Row Data Source

Server Row Data Source

Modern applications often work with datasets too large to load entirely in the browser. To preserve performance, LyteNyte Grid uses server-side (on-demand) data loading, transferring only the data currently required by the user interface.

The server row data source integrates with your backend to request data in blocks. Responses must adhere to the interfaces defined in the LyteNyte Grid server data source specification.


Creating a Server Row Data Source

Use the useServerDataSource hook to create a server-backed data source. At a minimum, you must provide a dataFetcher function that retrieves rows from your server.


The Data Fetcher

The dataFetcher function is the core of your implementation. It receives a DataFetcherParams object, which includes:

  • model: the current request model (sorts, filters, groups, aggregations, etc.)
  • requests: an array of DataRequest objects, one for each block of rows the grid requires.

Data Request Model

export interface DataRequestModel<T> {
  readonly sorts: SortModelItem<T>[];
  readonly filters: Record<string, FilterModelItem<T>>;
  readonly filtersIn: Record<string, FilterIn>;
  readonly quickSearch: string | null;
  readonly group: RowGroupModelItem<T>[];
  readonly groupExpansions: Record<string, boolean | undefined>;
  readonly aggregations: Record<string, { fn: AggModelFn<T> }>;
  readonly pivotGroupExpansions: Record<string, boolean | undefined>;
  readonly pivotMode: boolean;
  readonly pivotModel: ColumnPivotModel<T>;
}

This model mirrors the current grid configuration. For example, if the grid has a sort applied, model.sorts will contain the relevant sort configuration.

Data Requests

Each request describes the specific rows the grid needs:

export interface DataRequest {
  readonly id: string;
  readonly path: (string | null)[];
  readonly start: number;
  readonly end: number;
  readonly rowStartIndex: number;
  readonly rowEndIndex: number;
}
  • id uniquely identifies the request (useful for caching).
  • path describes grouping context (empty for root).
  • start/end define the requested range relative to the path.

Data Responses

Your server must return one or more responses per request. These can be optimistic (i.e., include more rows than requested). The return type is:

Promise<(DataResponse | DataResponsePinned)[]>;

Standard Response

export interface DataResponse {
  readonly kind: "center";
  readonly data: (DataResponseLeafItem | DataResponseBranchItem)[];
  readonly size: number;
  readonly asOfTime: number;
  readonly path: (string | null)[];
  readonly start: number;
  readonly end: number;
}

The data array may include leaf rows or branch rows, depending on grouping.

Pinned Response

export interface DataResponsePinned {
  readonly kind: "top" | "bottom";
  readonly data: DataResponseLeafItem[];
  readonly asOfTime: number;
}

Pinned rows (top or bottom) are never explicitly requested by the grid. If needed, include them alongside your standard responses.


Examples

Server Data Source

Row Grouping

Grouping increases the number of blocks the server must manage. Each group level requires responses for its subset of rows.

Row Group Server

Block Size

The useServerDataSource hook accepts a blockSize option that determines how many rows are requested per block:

  • Default: 100 rows
  • Recommended: 1000 rows for faster performance on stable connections

Adjust this value based on expected dataset size and user bandwidth.


Column Pivoting

Enable pivoting by providing dataColumnPivotFetcher to useServerDataSource. This async callback fetches pivot column definitions for the current configuration. The grid automatically calls it when pivot mode is enabled.


Server-Side Considerations

The server row data source is the most flexible, but also the most complex option. The server is responsible for applying:

  • Sort models
  • Filter models
  • Aggregation models

Limitations

  • Row selection: Supported, but "Select All Rows" is not possible (grid does not know all rows).
  • Cell selection: Supported, but "Select All Cells" is not possible for the same reason.
  • Export: Only exports rows currently loaded. For full exports, implement server-side APIs.