Server Side Grouping
Module Extensions
Section titled “Module Extensions”ServerSideGroupingLoadRowsRequest
Section titled “ServerSideGroupingLoadRowsRequest”interface ServerSideGroupingLoadRowsRequest { /** * Group route being loaded. The root route is an empty array. */ route: ServerSideGroupRoute; /** * Route depth. Root is level 0, first-level groups are level 1. */ level: number; /** * Active grouping columns in server request order. */ groupBy: ColumnProp[]; /** * Offset inside this route, aligned to the configured block size. */ start: number; /** * Maximum number of direct route children requested. */ limit: number; /** * Active remote sort model. */ sort?: ServerSideGroupingSort; /** * Active remote column filter model. */ filter?: ServerSideGroupingFilter; /** * Optional global quick-filter payload forwarded to the server. */ quickFilter?: ServerSideGroupingQuickFilter; levelParams?: unknown; parent?: ServerSideGroupRow}ServerSideGroupingLoadExpandedGroupsRequest
Section titled “ServerSideGroupingLoadExpandedGroupsRequest”interface ServerSideGroupingLoadExpandedGroupsRequest { /** * Active grouping columns in server request order. */ groupBy: ColumnProp[]; /** * Active remote sort model. */ sort?: ServerSideGroupingSort; /** * Active remote column filter model. */ filter?: ServerSideGroupingFilter; /** * Optional global quick-filter payload forwarded to the server. */ quickFilter?: ServerSideGroupingQuickFilter}ServerSideGroupingConfig
Section titled “ServerSideGroupingConfig”interface ServerSideGroupingConfig { /** * Column props used as grouping levels. The server decides returned groups for each level. */ groupBy: ColumnProp[]; /** * Loads one block of groups or rows for a route. The AbortSignal is cancelled on refresh/config changes. */ loadRows: ServerSideGroupingLoadRows<T>; /** * Optional one-shot datasource used by `expandAllGroups`. * * Return every group row that should be expanded with its full `route`. This * avoids recursive route loading for backends that can compute the group tree * in one request. */ loadExpandedGroups?: ServerSideGroupingLoadExpandedGroups; /** * Number of direct route children requested per block. */ blockSize?: number; /** * Purge child route cache when a group is collapsed. */ purgeClosedGroups?: boolean; /** * @deprecated Use `purgeClosedGroups`. */ purgeOnCollapse?: boolean; /** * Expands routes unless the user explicitly collapses them. A predicate can target selected routes. */ openGroupsByDefault?: boolean | ((route: ServerSideGroupRoute) => boolean); /** * Initial externally controlled expanded routes. */ expandedRoutes?: ServerSideGroupRoute[] | Set<string>; /** * Limits simultaneous remote block loads. */ maxConcurrentRequests?: number; /** * Debounces block load execution. Useful when virtualization emits several scroll updates quickly. */ blockLoadDebounceMs?: number; /** * Optional global quick-filter payload included in every request. */ quickFilter?: ServerSideGroupingQuickFilter; /** * Enables plugin debug helpers. */ debug?: boolean | ServerSideGroupingDebugConfig; getLevelParams?: ( route: ServerSideGroupRoute, level: number, parent?: ServerSideGroupRow, ) => unknown; formatAggregate?: ( key: string, value: unknown, group: ServerSideGroupRow, ) => string; formatGroupRow?: ( group: ServerSideGroupRow, context: { route: ServerSideGroupRoute; level: number; expanded: boolean; groupBy: ColumnProp[]; }, ) => string; groupRowRenderer?: GroupLabelTemplateFunc; /** * Receives the imperative API while the plugin is active and `null` on cleanup. */ api?: (api: ServerSideGroupingApi | null) => void}HTMLRevoGridElement (Extended from global)
Section titled “HTMLRevoGridElement (Extended from global)”interface HTMLRevoGridElement { serverSideGrouping?: Partial<ServerSideGroupingConfig>; 'server-side-grouping'?: Partial<ServerSideGroupingConfig>}AdditionalData (Extended from @revolist/revogrid)
Section titled “AdditionalData (Extended from @revolist/revogrid)”interface AdditionalData { /** * @deprecated Use `grid.serverSideGrouping` instead. */ serverSideGrouping?: Partial<ServerSideGroupingConfig>}Plugin API
Section titled “Plugin API”ServerSideGroupingPlugin
Section titled “ServerSideGroupingPlugin”Dependencies
Section titled “Dependencies”- Event integration
groupexpandclick,viewportscroll: Uses core grouping row rendering and viewport events to load grouped server-side blocks. - Event integration
beforefilterapply,beforesortingapply: Forwards sorting and filtering metadata to server-side grouping requests.
class ServerSideGroupingPlugin { destroy();}normalizeServerSideGroupingConfig
Section titled “normalizeServerSideGroupingConfig”Resolves user config into a complete internal config object.
This is the single place for defaults and deprecated alias handling, including
purgeOnCollapse -> purgeClosedGroups.
export function normalizeServerSideGroupingConfig<T extends DataType>( config: Partial<ResolvedServerSideGroupingConfig<T>> =;normalizeServerSideGroupingFilter
Section titled “normalizeServerSideGroupingFilter”Builds the server request filter model from the RevoGrid filter event.
The advanced filterItems model is preferred because the legacy collection
only contains the first filter per column. Values are cloned into a stable,
serializable shape so request logs, cache keys, and REST bodies can represent
Set-backed selection filters and nested slider ranges consistently.
export function normalizeServerSideGroupingFilter( detail?: ServerSideGroupingFilterEventDetail,): ServerSideGroupingFilter | undefined;ServerSideGroupingModel
Section titled “ServerSideGroupingModel”class ServerSideGroupingModel { configure(config: ResolvedServerSideGroupingConfig<T>, preserveExpanded = true);
setSort(sort?: ServerSideGroupingSort);
setFilter(filter?: ServerSideGroupingFilter);
setQuickFilter(quickFilter?: ServerSideGroupingQuickFilter);
reset(preserveExpanded = true);
async loadRoot();
async expand(routeOrId: ServerSideGroupId);
async expandAllGroups();
collapse(routeOrId: ServerSideGroupId);
collapseAllLoadedGroups();
async refreshServerSide();
async refreshRoute(routeOrId: ServerSideGroupId);
purgeRoute(routeOrId: ServerSideGroupId = ROOT_ROUTE);
destroy();
async retryRoute(routeOrId: ServerSideGroupId);
async loadRouteBlock(routeOrId: ServerSideGroupId, start = 0, force = false): Promise<boolean>;
getMissingBlockRequests(rows: DataType[]);
materialize(displayProp?: ColumnProp): DataType[];
getCacheState(): ServerSideGroupingCacheState;
getRouteKey(route: ServerSideGroupRoute);}createServerSideGroupRouteKey
Section titled “createServerSideGroupRouteKey”Builds a stable cache key for a route. Route keys are intentionally JSON strings so they round-trip through the public API and can distinguish nested values safely.
export function createServerSideGroupRouteKey(route: ServerSideGroupRoute): string;parseServerSideGroupId
Section titled “parseServerSideGroupId”Converts a public group id into a route array. Accepts real route arrays,
serialized route keys returned by createServerSideGroupRouteKey, or a single key.
export function parseServerSideGroupId(id: ServerSideGroupId): ServerSideGroupRoute;ServerSideGroupKey
Section titled “ServerSideGroupKey”export type ServerSideGroupKey = string | number | boolean | null;ServerSideGroupRoute
Section titled “ServerSideGroupRoute”export type ServerSideGroupRoute = ServerSideGroupKey[];ServerSideGroupId
Section titled “ServerSideGroupId”export type ServerSideGroupId = string | ServerSideGroupRoute;ServerSideGroupKind
Section titled “ServerSideGroupKind”export type ServerSideGroupKind = 'group' | 'row' | 'loading' | 'skeleton' | 'error';ServerSideGroupingStatus
Section titled “ServerSideGroupingStatus”export type ServerSideGroupingStatus = 'idle' | 'loading' | 'loaded' | 'error';ServerSideGroupingSort
Section titled “ServerSideGroupingSort”export type ServerSideGroupingSort = Record<ColumnProp, Exclude<Order, undefined>>;ServerSideGroupingFilterItem
Section titled “ServerSideGroupingFilterItem”Serializable server-side filter item forwarded to loadRows.
It intentionally mirrors RevoGrid filter metadata while replacing runtime-only
values such as Set with JSON-friendly arrays. Pro filters such as selection
and slider can therefore be sent directly to REST/SQL backends.
/** * Serializable server-side filter item forwarded to `loadRows`. * * It intentionally mirrors RevoGrid filter metadata while replacing runtime-only * values such as `Set` with JSON-friendly arrays. Pro filters such as selection * and slider can therefore be sent directly to REST/SQL backends. */export type ServerSideGroupingFilterItem = | FilterCollectionItem | Pick<FilterData, 'id' | 'type' | 'value' | 'relation' | 'hidden'>;ServerSideGroupingFilter
Section titled “ServerSideGroupingFilter”Server filter model keyed by column prop. A prop can contain one item for the legacy filter collection path or multiple items for the advanced filter panel.
/** * Server filter model keyed by column prop. A prop can contain one item for the * legacy filter collection path or multiple items for the advanced filter panel. */export type ServerSideGroupingFilter = Record< ColumnProp, ServerSideGroupingFilterItem | ServerSideGroupingFilterItem[]>;ServerSideGroupingTotals
Section titled “ServerSideGroupingTotals”export type ServerSideGroupingTotals = Record<string, unknown>;ServerSideGroupingQuickFilter
Section titled “ServerSideGroupingQuickFilter”export type ServerSideGroupingQuickFilter = string | Record<string, unknown>;ServerSideGroupingDebugConfig
Section titled “ServerSideGroupingDebugConfig”interface ServerSideGroupingDebugConfig { /** * Renders a lightweight cache summary below the grid while grouping is active. */ cacheView?: boolean}ServerSideGroupRow
Section titled “ServerSideGroupRow”interface ServerSideGroupRow { key: ServerSideGroupKey; /** * Optional display label. Falls back to `key`. */ label?: string; /** * Count displayed on the group row. Usually total descendant leaf rows. */ count?: number; /** * Known number of direct children for this group route. At the final grouping * level this is usually the number of leaf rows. */ childCount?: number; /** * Whether this group can be expanded. Defaults to true while there are * more grouping columns, and false at leaf level unless explicitly set. */ hasChildren?: boolean; /** * Totals or aggregates associated with this group row. */ aggregates?: ServerSideGroupingTotals; totals?: ServerSideGroupingTotals; /** * Server-provided params forwarded when this group route is loaded. */ levelParams?: unknown}ServerSideExpandedGroupRow (Extended from index.ts)
Section titled “ServerSideExpandedGroupRow (Extended from index.ts)”interface ServerSideExpandedGroupRow { /** * Full route for this group row. For example `['Germany', 'Swimming']`. */ route: ServerSideGroupRoute}ServerSideGroupingLoadExpandedGroupsResult
Section titled “ServerSideGroupingLoadExpandedGroupsResult”interface ServerSideGroupingLoadExpandedGroupsResult { /** * Flattened list of all group rows that should be expanded. * * Parent routes are inferred from each route. The plugin rebuilds route * blocks from this list and keeps leaf-row blocks unloaded. */ groups: ServerSideExpandedGroupRow[]; grandTotals?: ServerSideGroupingTotals}ServerSideGroupingLoadRowsResult
Section titled “ServerSideGroupingLoadRowsResult”interface ServerSideGroupingLoadRowsResult { groups?: ServerSideGroupRow[]; rows?: T[]; /** * Known direct child count for this route. For grouped routes this is the * number of direct child groups. For leaf routes this is the number of rows. */ rowCount?: number; /** * Alias for `rowCount` for server APIs that return `total`. */ total?: number; /** * Whether more direct children can be requested after this block. */ hasMore?: boolean; totals?: ServerSideGroupingTotals; grandTotals?: ServerSideGroupingTotals}ServerSideGroupingLoadRows
Section titled “ServerSideGroupingLoadRows”export type ServerSideGroupingLoadRows<T extends DataType = DataType> = ( request: ServerSideGroupingLoadRowsRequest, signal?: AbortSignal,) => Promise<ServerSideGroupingLoadRowsResult<T> | T[] | ServerSideGroupRow[]>;ServerSideGroupingLoadExpandedGroups
Section titled “ServerSideGroupingLoadExpandedGroups”export type ServerSideGroupingLoadExpandedGroups = ( request: ServerSideGroupingLoadExpandedGroupsRequest, signal?: AbortSignal,) => Promise<ServerSideGroupingLoadExpandedGroupsResult | ServerSideExpandedGroupRow[]>;ServerSideGroupingCacheRouteState
Section titled “ServerSideGroupingCacheRouteState”interface ServerSideGroupingCacheRouteState { route: ServerSideGroupRoute; status: ServerSideGroupingStatus; rowCount?: number; hasMore?: boolean; loadingBlocks: number[]; loadedBlocks: number[]; error?: unknown}ServerSideGroupingCacheState
Section titled “ServerSideGroupingCacheState”interface ServerSideGroupingCacheState { groupBy: ColumnProp[]; expandedRoutes: ServerSideGroupRoute[]; routeCount: number; routes: ServerSideGroupingCacheRouteState[]; grandTotals?: ServerSideGroupingTotals; activeRequests: number; queuedRequests: number}ServerSideGroupingApi
Section titled “ServerSideGroupingApi”interface ServerSideGroupingApi { /** * Expands a group route and lazily loads the first child block when needed. */ expandGroup(id: ServerSideGroupId): Promise<void>; /** * Expands all server group routes. * * If `loadExpandedGroups` is configured this uses one backend request to * hydrate all group routes. Otherwise it recursively loads group blocks. * Leaf-row routes are opened but not fully loaded; normal viewport loading * fetches visible row blocks. */ expandAllGroups(): Promise<void>; /** * Collapses a group route. Cache retention is controlled by `purgeClosedGroups`. */ collapseGroup(id: ServerSideGroupId): void; /** * Collapses all group routes currently known by the cache. */ collapseAllGroups(): void; /** * Clears the server-side grouping cache and reloads the root route. */ refreshServerSide(): Promise<void>; /** * Clears and reloads one route branch without resetting the whole grid. */ refreshRoute(route: ServerSideGroupId): Promise<void>; /** * Purges all cached blocks or the requested route branch. */ purgeServerSideCache(route?: ServerSideGroupId): void; /** * Returns a serializable snapshot of routes, loaded blocks, and queue state. */ getServerSideCacheState(): ServerSideGroupingCacheState}ResolvedServerSideGroupingConfig (Extended from index.ts)
Section titled “ResolvedServerSideGroupingConfig (Extended from index.ts)”interface ResolvedServerSideGroupingConfig { blockSize: number; purgeClosedGroups: boolean; purgeOnCollapse: boolean; openGroupsByDefault: boolean | ((route: ServerSideGroupRoute) => boolean); expandedRoutes?: ServerSideGroupRoute[] | Set<string>; maxConcurrentRequests: number; blockLoadDebounceMs: number}ServerSideGroupingSyntheticRow (Extended from index.ts)
Section titled “ServerSideGroupingSyntheticRow (Extended from index.ts)”interface ServerSideGroupingSyntheticRow { __serverSideGrouping?: true; __serverSideGroupingKind: ServerSideGroupKind; __serverSideGroupingRoute: ServerSideGroupRoute; __serverSideGroupingRouteKey: string; __serverSideGroupingIndex?: number; __serverSideGroupingBlockStart?: number; __serverSideGroupingError?: unknown}createServerSideGroupingApi
Section titled “createServerSideGroupingApi”Creates the public imperative API from plugin-local handlers.
export function createServerSideGroupingApi( handlers: ServerSideGroupingApiHandlers,): ServerSideGroupingApi;ServerSideGroupingApiHandlers
Section titled “ServerSideGroupingApiHandlers”Plugin methods used to construct the public server-side grouping API.
interface ServerSideGroupingApiHandlers { /** Expands and loads a route when needed. */ expandGroup(id: ServerSideGroupId): Promise<void>; /** Expands every server group route, loading group blocks recursively. */ expandAllGroups(): Promise<void>; /** Collapses a route and optionally purges child cache based on config. */ collapseGroup(id: ServerSideGroupId): void; /** Collapses every loaded group route. */ collapseAllGroups(): void; /** Clears all route blocks and reloads the root route. */ refreshServerSide(): Promise<void>; /** Clears one route branch and reloads it when visible/expanded. */ refreshRoute(route: ServerSideGroupId): Promise<void>; /** Purges all cache or one route branch without forcing an immediate load. */ purgeServerSideCache(route?: ServerSideGroupId): void; /** Returns a serializable cache snapshot for diagnostics. */ getServerSideCacheState(): ServerSideGroupingCacheState}markServerSideGroupingColumn
Section titled “markServerSideGroupingColumn”Marks the first visible column as grouping-capable so RevoGrid’s core grouping row renderer can draw server-side synthetic group rows.
export function markServerSideGroupingColumn( columnsByType: Record<string, ColumnRegular[]> | undefined, refreshByType: (type: ColumnType) => void,);syncServerSideGroupingDebugCacheView
Section titled “syncServerSideGroupingDebugCacheView”Adds or removes the debug cache view from RevoGrid’s extra vnode registry.
export function syncServerSideGroupingDebugCacheView(;removeServerSideGroupingDebugCacheView
Section titled “removeServerSideGroupingDebugCacheView”Removes the plugin-owned debug vnode and returns the remaining vnode list.
export function removeServerSideGroupingDebugCacheView(revogrid: HTMLRevoGridElement);ServerSideGroupingDebugViewOptions
Section titled “ServerSideGroupingDebugViewOptions”Inputs used to register the optional cache diagnostics vnode.
interface ServerSideGroupingDebugViewOptions { /** Grid element that owns the extra vnode registry. */ revogrid: HTMLRevoGridElement; /** RevoGrid hyperscript renderer passed to plugin extra vnodes. */ h: HyperFunc<VNode>; /** Whether the diagnostics vnode should be present. */ enabled: boolean; /** Reads current cache state without coupling this helper to the model. */ getCacheState(): ServerSideGroupingCacheState}addServerSideGroupingExcelExportTransformer
Section titled “addServerSideGroupingExcelExportTransformer”Prepends the grouping export transformer to a one-off export config.
export function addServerSideGroupingExcelExportTransformer<T extends;transformServerSideGroupingExcelExport
Section titled “transformServerSideGroupingExcelExport”Normalizes server-side grouping rows before Excel providers receive them.
Group rows are exportable, but loading/skeleton/error placeholders are UI state and should not become workbook rows. Group labels are copied into the first visible export column so exports match what users see in the grid.
transformServerSideGroupingExcelExport: ExcelExportContextTransformer;ServerSideGroupingFilterEventDetail
Section titled “ServerSideGroupingFilterEventDetail”Full filter payload emitted by RevoGrid before local filter trimming.
collection is the backward-compatible single-filter model. filterItems
is the complete advanced model used by Pro filters, including selection,
quick-search, slider, and multi-filter relations.
interface ServerSideGroupingFilterEventDetail { collection?: Record<ColumnProp, FilterCollectionItem>; filterItems?: MultiFilterItem}applyServerSideGroupingLoadResult
Section titled “applyServerSideGroupingLoadResult”Applies a loaded block to a route and returns optional grand totals.
This function owns response normalization, group-vs-leaf child shaping,
known/unknown count inference, and hasMore calculation.
export function applyServerSideGroupingLoadResult<T extends DataType>(;ApplyLoadResultOptions
Section titled “ApplyLoadResultOptions”Inputs required to merge one datasource response into a route block.
interface ApplyLoadResultOptions { /** Route state receiving the loaded block. */ state: RouteState<T>; /** Route-local block start offset. */ blockStart: number; /** Raw datasource response, including legacy array-only forms. */ response: ServerSideGroupingLoadRowsResult<T> | T[] | ServerSideGroupRow[]; /** Resolved plugin config used to infer grouping level and block size. */ config: ResolvedServerSideGroupingConfig<T>; /** Route creator callback used when returned group rows introduce child routes. */ ensureRoute(route: ServerSideGroupRoute, parent?: ServerSideGroupRow): RouteState<T>}materializeServerSideGroupingRoute
Section titled “materializeServerSideGroupingRoute”Converts one route plus any expanded descendants into RevoGrid source rows.
The output includes synthetic core grouping rows, loading rows, skeleton rows, error rows, and final leaf rows. It does not perform network loading.
export function materializeServerSideGroupingRoute<T extends DataType>( state: RouteState<T>, displayProp: ColumnProp, includeGroupRows: boolean, context: ServerSideGroupingMaterializeContext<T>,): DataType[];ServerSideGroupingMaterializeContext
Section titled “ServerSideGroupingMaterializeContext”Callbacks and config required to convert route state into grid rows.
interface ServerSideGroupingMaterializeContext { /** Resolved grouping config used for row labels, block size, and grouping depth. */ config: ResolvedServerSideGroupingConfig<T>; /** Ensures nested routes exist when expanded group rows are materialized. */ ensureRoute(route: ServerSideGroupRoute, parent?: ServerSideGroupRow): RouteState<T>; /** Returns the current expansion state for a serialized route key. */ isRouteExpanded(routeKey: string): boolean}getMissingServerSideGroupingBlockRequests
Section titled “getMissingServerSideGroupingBlockRequests”Scans currently visible materialized rows and returns unloaded route blocks.
The plugin uses this after scroll/render events to lazily load only blocks represented by visible loading or skeleton rows.
export function getMissingServerSideGroupingBlockRequests( rows: DataType[], routes: Map<string, RouteState>,);SERVER_SIDE_GROUPING_PLUGIN
Section titled “SERVER_SIDE_GROUPING_PLUGIN”SERVER_SIDE_GROUPING_PLUGIN: string;isAbortError
Section titled “isAbortError”Normalizes AbortError detection across browser DOMException and plain error objects.
export function isAbortError(error: unknown);ServerSideGroupingRequestQueue
Section titled “ServerSideGroupingRequestQueue”Coordinates block request concurrency, debounce, and cancellation for a model instance.
The queue is intentionally independent from route state. It answers only: “when may a request run?” and “which currently running requests should be aborted?”
class ServerSideGroupingRequestQueue { /** * Aborts all active requests and releases queued waiters so stale model work * can exit through generation checks. */ cancelPendingRequests();
/** * Creates and tracks an AbortController for one datasource call. */ createAbortController();
/** * Stops tracking a controller after its datasource call settles. */ releaseAbortController(controller: AbortController);
/** * Waits until a concurrency slot is available and returns an idempotent release function. */ async acquireRequestSlot();
/** * Applies configured debounce before a block request reaches the datasource. */ async waitForBlockLoadDebounce();}isDescendantRouteKey
Section titled “isDescendantRouteKey”Checks whether a serialized route belongs to a route branch. Used by partial refresh and purge so those operations can target one group without clearing siblings.
export function isDescendantRouteKey(routeKey: string, parentRoute: ServerSideGroupRoute);toServerSideGroupingBlockStart
Section titled “toServerSideGroupingBlockStart”Aligns any child index to the start offset for its server block.
export function toServerSideGroupingBlockStart(index: number, blockSize: number);ROOT_ROUTE
Section titled “ROOT_ROUTE”Canonical route for top-level group rows. All server-side grouping loads start here.
ROOT_ROUTE: ServerSideGroupRoute;MESSAGE_PROP
Section titled “MESSAGE_PROP”Internal fallback cell property used when the grid has no visible grouping column.
MESSAGE_PROP: string;createRouteState
Section titled “createRouteState”Creates empty route state and seeds known child counts from parent metadata.
export function createRouteState<T extends DataType>( route: ServerSideGroupRoute, config: ResolvedServerSideGroupingConfig<T>, parent?: ServerSideGroupRow,): RouteState<T>;clearRouteState
Section titled “clearRouteState”Clears loaded data and error/loading metadata while keeping the route object and parent metadata alive for partial refreshes.
export function clearRouteState(state: RouteState);getMaterializedChildCount
Section titled “getMaterializedChildCount”Returns the number of child slots to materialize for a route.
Known-count routes render exactly rowCount; unknown-count routes render up
to the largest loaded block and may add a tail loader separately.
export function getMaterializedChildCount(state: RouteState);getChildAt
Section titled “getChildAt”Resolves a child at an absolute route-local index from the block cache.
export function getChildAt<T extends DataType>( state: RouteState<T>, index: number, blockSize: number,);toCacheRouteState
Section titled “toCacheRouteState”Converts mutable internal route state into the public serializable cache view.
export function toCacheRouteState(route: RouteState): ServerSideGroupingCacheRouteState;MaterializedChild
Section titled “MaterializedChild”A direct child materialized for a route block. Group children point to their child route, while row children are final leaf records from the backend.
/** * A direct child materialized for a route block. Group children point to their * child route, while row children are final leaf records from the backend. */export type MaterializedChild<T extends DataType = DataType> = | { kind: 'group'; group: ServerSideGroupRow; route: ServerSideGroupRoute } | { kind: 'row'; row: T };RouteState
Section titled “RouteState”Mutable cache state for one route.
A route is the unit of loading, expansion, retry, purge, and refresh. Blocks are keyed by their start offset and contain only direct children for this route.
interface RouteState { /** Route represented by this state. Root is an empty array. */ route: ServerSideGroupRoute; /** Stable serialized route key used in maps and synthetic row metadata. */ routeKey: string; /** Parent group row returned by the backend, if this is not root. */ parent?: ServerSideGroupRow; /** Server-provided params forwarded when this route is loaded. */ levelParams?: unknown; /** Loaded blocks of direct child groups or leaf rows keyed by block start. */ blocks: Map<number, MaterializedChild<T>[]>; /** Block starts that currently have in-flight load requests. */ loadingBlocks: Set<number>; /** Per-block request versions used to ignore stale responses. */ blockVersions: Map<number, number>; /** Monotonic route request version. Incrementing invalidates previous block loads. */ requestVersion: number; /** Current route loading state used by materialization. */ status: 'idle' | 'loading' | 'loaded' | 'error'; /** Known direct child count. Undefined means unknown count. */ rowCount?: number; /** Unknown-count continuation flag from the backend. */ hasMore?: boolean; /** Route-level totals returned by the backend. */ totals?: ServerSideGroupingTotals; /** Last route/block load error. */ error?: unknown; /** Failed block start. Retry targets this block only. */ errorBlockStart?: number}