grafast
Version:
Cutting edge GraphQL planning and execution engine
148 lines • 8 kB
TypeScript
import type { ExecutionDetails, GrafastResultsList, Maybe, UnbatchedExecutionExtra } from "../interfaces.js";
import type { Step } from "../step.js";
import { UnbatchedStep } from "../step.js";
import { ConstantStep } from "./constant.js";
type ParametersExceptFirst<F> = F extends (arg0: any, ...rest: infer R) => any ? R : never[];
/**
* Describes what a plan needs to implement in order to be suitable for
* supplying what the `PageInfo` type requires.
*/
export interface PageInfoCapableStep extends Step {
hasNextPage(): Step<boolean>;
hasPreviousPage(): Step<boolean>;
startCursor(): Step<string | null>;
endCursor(): Step<string | null>;
}
export declare function assertPageInfoCapableStep($step: Step | PageInfoCapableStep): asserts $step is PageInfoCapableStep;
/**
* Describes what a plan needs to implement in order to be suitable for
* supplying what a ConnectionStep requires.
*/
export interface ConnectionCapableStep<TItemStep extends Step, TCursorStep extends Step> extends Step {
/**
* Clone the plan; it's recommended that you add `$connection` as a
* dependency so that you can abort execution early in the case of errors
* (e.g. if the cursors cannot be parsed).
*/
connectionClone($connection: ConnectionStep<TItemStep, TCursorStep, any, any>, ...args: any[]): ConnectionCapableStep<TItemStep, TCursorStep>;
pageInfo($connection: ConnectionStep<TItemStep, TCursorStep, ConnectionCapableStep<TItemStep, TCursorStep>, any>): PageInfoCapableStep;
setFirst($first: Step<Maybe<number>>): void;
setLast($last: Step<Maybe<number>>): void;
setOffset($offset: Step<Maybe<number>>): void;
parseCursor($cursor: Step<Maybe<string>>): TCursorStep;
setBefore($before: TCursorStep): void;
setAfter($after: TCursorStep): void;
items(): Step<ReadonlyArray<TItemStep extends Step<infer U> ? U : any>>;
}
/**
* Handles GraphQL cursor pagination in a standard and consistent way
* indepdenent of data source.
*/
export declare class ConnectionStep<TItemStep extends Step, TCursorStep extends Step, TStep extends ConnectionCapableStep<TItemStep, TCursorStep>, TEdgeDataStep extends Step = TItemStep, TNodeStep extends Step = Step> extends UnbatchedStep<unknown> {
static $$export: {
moduleName: string;
exportName: string;
};
isSyncAndSafe: boolean;
private subplanId;
private _firstDepId;
private _lastDepId;
private _offsetDepId;
private _beforeDepId;
private _afterDepId;
/** Plan for data to associate with the edge */
readonly edgeDataPlan?: ($item: TItemStep) => TEdgeDataStep;
/** The node plan */
readonly itemPlan?: ($item: TItemStep) => TNodeStep;
readonly cursorPlan?: ($item: TItemStep) => Step<string | null> | undefined;
constructor(subplan: TStep, config?: ConnectionConfig<TItemStep, TEdgeDataStep, TNodeStep>);
toStringMeta(): string;
getFirst(): Step<number | null | undefined> | null;
setFirst(first: Step<number | null | undefined> | number): void;
getLast(): Step<number | null | undefined> | null;
setLast(last: Step<number | null | undefined> | number): void;
getOffset(): Step<number | null | undefined> | null;
setOffset(offset: Step<number | null | undefined> | number): void;
getBefore(): TCursorStep | null;
setBefore($beforePlan: Step<string | null | undefined>): void;
getAfter(): TCursorStep | null;
setAfter($afterPlan: Step<string | null | undefined>): void;
/**
* This should not be called after the arguments have been finalized.
*/
getSubplan(): TStep;
/**
* This represents the entire collection with conditions and ordering
* applied, but without any pagination constraints (before, after, first,
* last, offset) applied. It's useful for the following:
*
* - performing aggregates e.g. totalCount across the entire collection
* - determining fields for pageInfo, e.g. is there a next/previous page
*
* This cannot be called before the arguments have been finalized.
*/
cloneSubplanWithoutPagination(...args: ParametersExceptFirst<TStep["connectionClone"]>): TStep;
/**
* This represents a single page from the collection - not only have
* conditions and ordering been applied but we've also applied the pagination
* constraints (before, after, first, last, offset). It's useful for
* returning the actual edges and nodes of the connection.
*
* This cannot be called before the arguments have been finalized.
*/
cloneSubplanWithPagination(...args: ParametersExceptFirst<TStep["connectionClone"]> | []): TStep;
/**
* Subplans may call this from their `setBefore`/`setAfter`/etc plans in order
* to add a dependency to us, which is typically useful for adding validation
* functions so that they are thrown "earlier", avoiding error bubbling.
*/
addValidation(callback: () => Step): void;
get(fieldName: string): Step<any>;
edges(): Step;
nodes(): import("./listTransform.js").__ListTransformStep<any, any, any, any> | TStep;
wrapEdge($edge: TItemStep): EdgeStep<TItemStep, TCursorStep, TStep, TEdgeDataStep, TNodeStep>;
pageInfo(): PageInfoCapableStep;
execute({ count, }: ExecutionDetails): GrafastResultsList<Record<string, never>>;
unbatchedExecute(): any;
}
export interface EdgeCapableStep<TNodeStep extends Step> extends Step {
node(): TNodeStep;
cursor(): Step<string | null>;
}
export declare function assertEdgeCapableStep<TNodeStep extends Step>($step: Step | EdgeCapableStep<TNodeStep>): asserts $step is EdgeCapableStep<TNodeStep>;
export declare class EdgeStep<TItemStep extends Step, TCursorStep extends Step, TStep extends ConnectionCapableStep<TItemStep, TCursorStep>, TEdgeDataStep extends Step = TItemStep, TNodeStep extends Step = Step> extends UnbatchedStep implements EdgeCapableStep<TNodeStep> {
private skipCursor;
static $$export: {
moduleName: string;
exportName: string;
};
isSyncAndSafe: boolean;
private connectionDepId;
private readonly cursorDepId;
private needCursor;
constructor($connection: ConnectionStep<TItemStep, TCursorStep, TStep, TEdgeDataStep, TNodeStep>, $item: TItemStep, skipCursor?: boolean);
get(fieldName: string): ConstantStep<undefined> | Step<string | null> | TNodeStep;
private getConnectionStep;
private getItemStep;
data(): TEdgeDataStep;
node(): TNodeStep;
cursor(): Step<string | null>;
optimize(): EdgeStep<TItemStep, TCursorStep, TStep, TNodeStep, Step<any>>;
deduplicate(_peers: EdgeStep<any, any, any, any>[]): EdgeStep<TItemStep, TCursorStep, TStep, TNodeStep>[];
deduplicatedWith(replacement: EdgeStep<any, any, any, any>): void;
unbatchedExecute(_extra: UnbatchedExecutionExtra, record: any, cursor: any): any;
}
interface ConnectionConfig<TItemStep extends Step, TEdgeDataStep extends Step = TItemStep, TNodeStep extends Step = Step> {
nodePlan?: ($item: TItemStep) => TNodeStep;
edgeDataPlan?: ($item: TItemStep) => TEdgeDataStep;
cursorPlan?: ($item: TItemStep) => Step<string | null>;
}
/**
* Wraps a collection fetch to provide the utilities for working with GraphQL
* cursor connections.
*/
export declare function connection<TItemStep extends Step, TCursorStep extends Step, TStep extends ConnectionCapableStep<TItemStep, TCursorStep>, TEdgeDataStep extends Step = TItemStep, TNodeStep extends Step = Step>(step: TStep, config?: ConnectionConfig<TItemStep, TEdgeDataStep, TNodeStep>): ConnectionStep<TItemStep, TCursorStep, TStep, TEdgeDataStep, TNodeStep>;
export type ItemsStep<T extends Step<readonly any[]> | ConnectionCapableStep<any, any>> = T extends ConnectionCapableStep<any, any> ? ReturnType<T["items"]> : T;
export declare function itemsOrStep<T extends Step<readonly any[]> | ConnectionCapableStep<any, any>>($step: T): Step<readonly any[]>;
export {};
//# sourceMappingURL=connection.d.ts.map