UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

132 lines (131 loc) • 5.92 kB
import { devBuild, codedMessage } from "./error-message.js"; import { UnhashableQueryIRError } from "./errors.js"; import { getLiveQueryHash } from "./live-query-options.js"; import { isFailedStatus } from "./live-query-primitives.js"; import { createLiveQueryCollection } from "./query/live-query-collection.js"; import { resolveLiveQueryWindowInput, getLiveQueryWindowInputKind, shouldPreserveLiveQueryWindowPageCount, liveQueryWindowMatches, createLiveQueryWindowController, normalizeLiveQueryWindowPageSize, compareLiveQueryWindowDependencies, getLiveQueryWindowCollectionWarning, assertLiveQueryWindowManyResult } from "./live-query-window-controller.js"; const WINDOW_COLLECTION_GC_TIME_MS = 1; function readLiveQueryWindowPageShape(config) { if (`getNextPageParam` in config) { throw new Error( devBuild() && process.env.NODE_ENV !== `production` ? `getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.` : codedMessage(246) ); } return { pageSize: normalizeLiveQueryWindowPageSize(config.pageSize), initialPageParam: config.initialPageParam ?? 0 }; } function bindLiveQueryWindow(previous, update, uncommitted) { const resolved = update.recompile === `always` ? resolveLiveQueryWindowInput(update.input) : void 0; const supplied = resolved === void 0 ? getLiveQueryWindowInputKind(update.input) === `collection` ? update.input : void 0 : resolved.kind === `collection` ? resolved.collection : void 0; const inputKind = supplied ? `collection` : `query`; const previousKind = previous ? previous.supplied ? `collection` : `query` : void 0; const dependencies = supplied ? void 0 : [...update.dependencies ?? []]; const change = compareUpdate(previous, update, dependencies); const needsNewCollection = previous === null || previousKind !== inputKind || (supplied ? previous.supplied !== supplied : change.recompile); const pageShapeChanged = previous === null || previous.pageSize !== update.pageSize || previous.initialPageParam !== update.initialPageParam; if (!needsNewCollection && !pageShapeChanged) return previous; const initialPageCount = shouldPreserveLiveQueryWindowPageCount({ hasPreviousController: previous !== null, previousInputKind: previousKind, inputKind, sameCollection: supplied !== void 0 && previous?.supplied === supplied, dependenciesChanged: change.dependenciesChanged, dependenciesStructurallyEqual: change.dependenciesStructurallyEqual, pageShapeChanged }) ? Math.max(1, previous.controller.getSnapshot().pages.length) : 1; const requiredLimit = initialPageCount * update.pageSize + 1; let collection = previous?.collection; let queryHash = previous?.queryHash; let ownsCollection = previous?.ownsCollection ?? false; let warning; if (needsNewCollection) { if (!supplied && uncommitted?.ownsCollection && !compareUpdate(uncommitted, update, dependencies).recompile && uncommitted.collection.status !== `cleaned-up` && !isFailedStatus(uncommitted.collection.status) && liveQueryWindowMatches(uncommitted.collection, requiredLimit)) { collection = uncommitted.collection; queryHash = uncommitted.queryHash; ownsCollection = true; } else { const window = openWindowCollection( resolved ?? resolveLiveQueryWindowInput(update.input), requiredLimit, update ); collection = window.collection; queryHash = window.queryHash; ownsCollection = window.ownsCollection; warning = window.warning; } } return { supplied, dependencies, scope: update.scope, pageSize: update.pageSize, initialPageParam: update.initialPageParam, collection, queryHash, ownsCollection, controller: createLiveQueryWindowController(collection, { pageSize: update.pageSize, initialPageParam: update.initialPageParam, initialPageCount, client: update.client, queryHash }), warning }; } function compareUpdate(binding, update, dependencies) { const comparison = compareLiveQueryWindowDependencies( binding?.dependencies, dependencies ?? [] ); const scopeChanged = binding?.scope !== update.scope; const dependenciesChanged = scopeChanged || (update.recompile === `identity` ? !comparison.structurallyEqual : comparison.changed); return { recompile: update.recompile === `always` || dependenciesChanged, dependenciesChanged, // An identity that changed differs by structure by definition. dependenciesStructurallyEqual: !scopeChanged && update.recompile !== `identity` && comparison.structurallyEqual }; } function openWindowCollection(input, requiredLimit, update) { const prepared = input.kind === `collection` ? input.collection : { query: input.query.limit(requiredLimit).offset(0) }; let queryHash; if (update.client) { try { queryHash = getLiveQueryHash(prepared, update.queryKey); } catch (error) { if (!(error instanceof UnhashableQueryIRError) || update.queryKey?.length) throw error; } } if (input.kind === `collection`) { const warning = getLiveQueryWindowCollectionWarning( input.collection, update.pageSize + 1 ); if (liveQueryWindowMatches(input.collection, requiredLimit)) { input.collection.startSyncImmediate(); } return { collection: input.collection, queryHash, ownsCollection: false, warning }; } const collection = createLiveQueryCollection({ query: prepared.query, gcTime: WINDOW_COLLECTION_GC_TIME_MS }); assertLiveQueryWindowManyResult(collection); collection.startSyncImmediate(); return { collection, queryHash, ownsCollection: true, warning: void 0 }; } export { bindLiveQueryWindow, readLiveQueryWindowPageShape }; //# sourceMappingURL=live-query-window-binding.js.map