@tanstack/db
Version:
A reactive client store for building super fast apps on sync
145 lines (144 loc) • 8.78 kB
text/typescript
import { StandardSchemaV1 } from '@standard-schema/spec';
import { Collection } from './collection/index.js';
import { CollectionOptionsIdentity } from './collection-options.js';
import { CollectionConfig, InferSchemaInput, InferSchemaOutput, NonSingleResult, SingleResult, TransactionConfig, UtilsRecord } from './types.js';
import { LiveQueryOptions } from './live-query-options.js';
declare const collectionConfigFactory: unique symbol;
type AnyCollectionConfig = CollectionConfig<any, any, any, any>;
export type CollectionOptions<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TSchema extends StandardSchemaV1 = never, TUtils extends UtilsRecord = UtilsRecord> = CollectionOptionsIdentity<T, TKey, TSchema, TUtils, DbClient>;
type DescriptorFromConfig<TConfig extends AnyCollectionConfig> = TConfig extends {
getKey: (item: infer T) => infer TKey;
} ? CollectionOptions<Extract<T, object>, Extract<TKey, string | number>, TConfig extends {
schema: infer TSchema extends StandardSchemaV1;
} ? TSchema : never, TConfig extends {
utils: infer TUtils extends UtilsRecord;
} ? TUtils : UtilsRecord> & (TConfig extends SingleResult ? SingleResult : NonSingleResult) : never;
type CollectionConfigWithFactory<TConfig extends AnyCollectionConfig> = TConfig & {
readonly [collectionConfigFactory]: (client: DbClient) => TConfig;
};
/**
* Adds a fresh-config materializer to an adapter options object.
*
* Adapter option creators should use this so a module-scoped descriptor can be
* materialized safely by more than one DbClient.
*/
export declare function withCollectionConfigFactory<TConfig extends AnyCollectionConfig>(config: TConfig, factory: (client: DbClient) => TConfig): CollectionConfigWithFactory<TConfig>;
export type CollectionMaterializeOptions<T extends object> = {
initialData?: Array<T>;
};
export type DehydratedCollectionRow<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = {
key: TKey;
value: T;
metadata?: unknown;
};
export type DehydratedCollectionChunk<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = {
collectionId: string;
rows: Array<DehydratedCollectionRow<T, TKey>>;
syncMeta?: unknown;
};
export type DehydratedLiveQuery = {
queryHash: string;
dehydratedAt: number;
snapshot?: DehydratedLiveQueryResult;
promise?: Promise<DehydratedLiveQueryResult>;
};
export type DehydratedLiveQueryResult<T extends object = object, TKey extends string | number = string | number> = {
rows: Array<DehydratedCollectionRow<T, TKey>>;
};
export type DehydratedDbState = {
collections: Array<DehydratedCollectionChunk>;
liveQueries?: Array<DehydratedLiveQuery>;
};
export type DbClientLiveQueryState = `pending` | `success` | `error`;
export type DbClientLiveQuery = {
readonly queryHash: string;
readonly dehydratedAt: number;
readonly status: DbClientLiveQueryState;
readonly promise: Promise<void>;
readonly snapshot?: DehydratedLiveQueryResult;
readonly error?: unknown;
};
export type DbClientEvent = {
type: `liveQueryAdded` | `liveQueryUpdated`;
query: DbClientLiveQuery;
} | {
type: `liveQueryStreamError`;
error: unknown;
};
export type DehydrateDbClientOptions = {
shouldDehydrateCollection?: (collection: Collection) => boolean;
shouldDehydrateLiveQuery?: (query: DbClientLiveQuery) => boolean;
};
export type DbClientOptions = Record<string, unknown>;
export declare function collectionOptions<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionConfig<InferSchemaOutput<T>, TKey, T, TUtils> & {
schema: T;
} & NonSingleResult): CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & NonSingleResult;
export declare function collectionOptions<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionConfig<InferSchemaOutput<T>, TKey, T, TUtils> & {
schema: T;
} & SingleResult): CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & SingleResult;
export declare function collectionOptions<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionConfig<T, TKey, never, TUtils> & {
schema?: never;
} & NonSingleResult): CollectionOptions<T, TKey, never, TUtils> & NonSingleResult;
export declare function collectionOptions<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionConfig<T, TKey, never, TUtils> & {
schema?: never;
} & SingleResult): CollectionOptions<T, TKey, never, TUtils> & SingleResult;
export declare function collectionOptions<TConfig extends AnyCollectionConfig>(id: string, factory: (client: DbClient) => TConfig): DescriptorFromConfig<TConfig>;
export declare function isCollectionOptions(value: unknown): value is CollectionOptions<any, string | number, any, UtilsRecord>;
export declare class DbClient {
private readonly options;
private collectionsByOptions;
private collectionsById;
private pendingHydration;
private liveQueries;
private preloadedLiveQueries;
private liveQueryResources;
private listeners;
private ssrStreamingEnabled;
private ssrServerCleanupEnabled;
private lastLiveQueryTimestamp;
private readonly transactionScope;
constructor(options?: DbClientOptions);
getDependency<T>(key: string): T | undefined;
requireDependency<T>(key: string): T;
get activeTransaction(): import('./transactions.js').Transaction<Record<string, unknown>> | undefined;
createTransaction<T extends object = Record<string, unknown>>(config: TransactionConfig<T>): import('./transactions.js').Transaction<T>;
preloadLiveQuery(options: LiveQueryOptions): Promise<void>;
collection<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & NonSingleResult, materializeOptions?: CollectionMaterializeOptions<InferSchemaInput<T>>): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & NonSingleResult;
collection<T extends StandardSchemaV1, TKey extends string | number, TUtils extends UtilsRecord>(options: CollectionOptions<InferSchemaOutput<T>, TKey, T, TUtils> & SingleResult, materializeOptions?: CollectionMaterializeOptions<InferSchemaInput<T>>): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>> & SingleResult;
collection<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionOptions<T, TKey, never, TUtils> & NonSingleResult, materializeOptions?: CollectionMaterializeOptions<T>): Collection<T, TKey, TUtils, never, T> & NonSingleResult;
collection<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = UtilsRecord>(options: CollectionOptions<T, TKey, never, TUtils> & SingleResult, materializeOptions?: CollectionMaterializeOptions<T>): Collection<T, TKey, TUtils, never, T> & SingleResult;
/** @internal */
_materializeCollectionForRender<T extends object, TKey extends string | number, TSchema extends StandardSchemaV1, TUtils extends UtilsRecord>(options: CollectionOptions<T, TKey, TSchema, TUtils>): Collection<T, TKey, TUtils, TSchema, [
TSchema
] extends [never] ? T : InferSchemaInput<TSchema>>;
private materializeCollection;
dehydrate(options?: DehydrateDbClientOptions): DehydratedDbState;
hydrate(state: DehydratedDbState): void;
applyCollectionChunk(chunk: DehydratedCollectionChunk): void;
subscribe(listener: (event: DbClientEvent) => void): () => void;
/** @internal */
_setSsrStreamingEnabled(enabled: boolean): void;
/** @internal */
_isSsrStreamingEnabled(): boolean;
/** @internal */
_setSsrServerCleanupEnabled(enabled: boolean): void;
/** @internal */
_isSsrServerCleanupEnabled(): boolean;
/** @internal */
_getLiveQuery(queryHash: string): DbClientLiveQuery | undefined;
/** @internal */
_consumeLiveQueryResult(queryHash: string, dehydratedAt: number): void;
/** @internal */
_registerLiveQuery(queryHash: string, promise: Promise<DehydratedLiveQueryResult>): Promise<void>;
/** @internal */
_registerLiveQueryResource(owner: object, cleanup: () => Promise<void>): () => void;
/** @internal */
_failPendingLiveQueries(error: unknown): void;
cleanup(): Promise<void>;
private hydrateLiveQuery;
private nextLiveQueryTimestamp;
private createLiveQueryRecord;
private emit;
private applyRows;
}
export {};