UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

125 lines (113 loc) 3.51 kB
import { BaseQueryBuilder } from './query/builder/index.js' import { isCollection } from './live-query-adapter.js' import { getStableQueryBuilderHash, getStableValueHash, } from './query/ir-stable-identity.js' import type { CollectionImpl } from './collection/index.js' import type { CollectionOptionsIdentity } from './collection-options.js' import type { CollectionOptions, DbClient } from './client.js' import type { InitialQueryBuilder, LiveQueryCollectionConfig, } from './query/index.js' export type LiveQueryKey = ReadonlyArray<unknown> export type LiveQueryOptions = LiveQueryCollectionConfig<any> & { queryKey?: LiveQueryKey } export type DeferredLiveQueryCollections = Set< CollectionImpl<any, string | number, any, any, any> > function createInitialQueryBuilder( dbClient: DbClient | undefined, deferredCollections: DeferredLiveQueryCollections, ): InitialQueryBuilder { return new BaseQueryBuilder( {}, dbClient ? ( options: CollectionOptionsIdentity< any, string | number, any, any, any >, ) => { const collection = dbClient._materializeCollectionForRender( options as CollectionOptions<any, string | number, any, any>, ) as CollectionImpl<any, string | number, any, any, any> if (collection._deferSyncStart()) deferredCollections.add(collection) return collection } : undefined, ) as InitialQueryBuilder } export function prepareLiveQueryValue( value: unknown, dbClient: DbClient | undefined, deferredCollections: DeferredLiveQueryCollections, ): unknown { if (typeof value === `function`) { return prepareLiveQueryValue( value(createInitialQueryBuilder(dbClient, deferredCollections)), dbClient, deferredCollections, ) } if ( value && typeof value === `object` && !isCollection(value) && !(value instanceof BaseQueryBuilder) && `query` in value ) { const { query, queryKey: _queryKey, client: _client, ...config } = value as LiveQueryCollectionConfig<any> & { queryKey?: LiveQueryKey client?: DbClient } return { ...config, query: typeof query === `function` ? query(createInitialQueryBuilder(dbClient, deferredCollections)) : query, } } return value } export function getPreparedLiveQueryIdentity(value: unknown): unknown { if (isCollection(value)) return [`collection`, value.id] if (value instanceof BaseQueryBuilder) { return [`query`, getStableQueryBuilderHash(value)] } if (value && typeof value === `object` && `query` in value) { const config = value as LiveQueryCollectionConfig<any> return [ `config`, getPreparedLiveQueryIdentity(config.query), [`getKey`, config.getKey], [`schema`, config.schema], [`singleResult`, config.singleResult === true], [`defaultStringCollation`, config.defaultStringCollation], ] } if (value === undefined || value === null) return [`disabled`] return [`value`, value] } export function getLiveQueryHash( preparedValue: unknown, queryKey?: LiveQueryKey, ): string { const identity = queryKey?.length ? [`queryKey`, queryKey] : isCollection(preparedValue) ? [`collection`, preparedValue.id] : [`derived`, getPreparedLiveQueryIdentity(preparedValue)] return getStableValueHash(identity, `queryKey`) }