Skip to content

Query documents

class

class QueryDocument<T> implements ClientQueryDocument<QueryDocumentSnapshot<T>>

QueryDocument or its snapshots are the way you are interacting with injections.

See useInjection() and useDocumentWatch()

type: string;

The name of the row type

config: QueryConfig;

Current config

rows: T[];

The current result rows.

rowCount: number;

Total number of available rows.

error: Error | null;

Why the last update() failed, null once one succeeds again.

constructor(type: string, config: QueryConfig, rows: T[], rowCount: number);

Creates a new QueryDocument from raw data.

Parameters

type row type name
config current config
rows current result rows
rowCount total number of rows available
update: (newConfig: QueryConfigDelta) => Promise<QueryDocumentSnapshot<T>>;

Re-executes the query this document came from with its config changed as given and updates the document in place. A document made by localDocument() applies the config to the rows it holds instead.

An arrow property, not a method: it is handed out on every snapshot, where it is called detached from the document and needs to keep both its “this” and its identity.

Parameters

newConfig config fields to change

Returns the snapshot the update produced

interface

interface QueryDocumentSnapshot<T> extends ClientQueryDocument<QueryDocumentSnapshot<T>>

Immutable snapshot of a QueryDocument

The document itself is a store that gets mutated in place – it has to be, or the subscription a view holds would point at a stale object after every update. What comes out of getSnapshot() is the opposite: a fresh object every time the document changes and the same object as long as it does not. That is what makes an update visible to React.memo, to effect dependencies and to useSyncExternalStore’s own change detection.

type: string;

The name of the row type

config: QueryConfig;

Current config

rows: T[];

The current result rows.

rowCount: number;

Total number of available rows.

interface

interface ClientQueryDocument<D>

What a query document is on the client on top of the data the server sent: the way to run the query again, and how the last attempt went.

Every document the server sends becomes a QueryDocument instance, so the generated result type of a query selecting one mixes this in: these members are part of the type the same way they are part of the value.

update(newConfig: QueryConfigDelta): Promise<D>;

Re-executes the query this document snapshot came from with its config changed as given and updates the document in place.

Calling this from a snapshot will update the mutable QueryDocument it came up which in turn will trigger a rerendering of that document, so the returned snapshot is mostly there in case anybody else might need it before that.

Parameters

newConfig config fields to change

Returns the snapshot the update produced

error: Error | null;

Why the last update() failed, null once one succeeds again. The rows and config are the ones from before the failure.

The update() promise rejects with the same error, but a pager, a sort header or a filter row doesn’t wait for it: this is where a view sees their failures, and what it shows for one is its own choice. Only the latest update() counts, so a slow one failing after a later one succeeded sets nothing.

interface

interface QueryConfig

The configuration part of a QueryDocument.

condition: FilterExpression | null;

FilterDSL condition or null for “Not filtered”.

offset: number;

Current offset in rows.

pageSize: number;

Current pagination size

sortFields: FieldExpression[];

Array of sort field expression which are either column names with optional ! prefix to describe descending sort or a complex field expression like the sum of two fields.

interface

interface QueryConfigDelta

Describes the relative changes to a pre-existing QueryConfig.

condition?: FilterExpression | null;

FilterDSL condition or null for “Not filtered”.

offset?: number;

Current offset in rows.

pageSize?: number;

Current pagination size

sortFields?: FieldExpression[];

Array of sort field expression which are either column names with optional ! prefix to describe descending sort or a complex field expression like the sum of two fields.

function

declare function unawaited(promise: Promise<unknown>): void;

Lets go of the promise of an update() nobody waits for, a click handler’s or a timer’s. A query document keeps the failure as its error, where the view sees it, so catching here hides nothing and leaves no unhandled rejection behind.

Parameters

promise the update() or what a hook made of it

function

declare function localDocument<T extends object>(type: string, rows: T[], config?: Partial<QueryConfig>): QueryDocument<T>;

A query document over rows the browser holds rather than a query: its update() filters, sorts and pages them.

const doc = localDocument("Foo", rows, {pageSize: 10, sortFields: ["name"]});

Everything that takes a query document takes this one – a DataGrid, its filters, sort headers and pager – and can’t tell the difference. The condition is evaluated as conditionPredicate() has it, the order is sortComparator()’s. The rows are of a type of the schema, which is what field paths are checked against; they are held as given, so rows added to the array show with the next update().

In a view, useLocalDocument() is this with the subscription that makes an update() show.

Parameters

type GraphQL type name of the rows
rows all the rows, not a page of them
config initial config. By default no condition, no order and all rows on one page.

Returns query document

function

declare function useLocalDocument<T extends object>(type: string, rows: T[], config?: Partial<QueryConfig>): QueryDocumentSnapshot<T>;

A query document over rows the view holds, see localDocument(), and the current snapshot of it.

const foos = useLocalDocument("Foo", rows, {pageSize: 10});
<DataGrid doc={ foos } columns={ ["name", "num"] }/>

The config is the initial one; after that it is the document’s, changed through update() like any other. New rows – an array that isn’t the one before – are filtered, sorted and paged under the config the document has.

Rules of hooks apply.

Parameters

type GraphQL type name of the rows
rows all the rows, not a page of them
config initial config. By default no condition, no order and all rows on one page.

Returns snapshot of the document