@tanstack/vue-db
Version:
Vue integration for @tanstack/db
1 lines • 12.2 kB
Source Map (JSON)
{"version":3,"file":"useLiveInfiniteQuery.cjs","sources":["../../src/useLiveInfiniteQuery.ts"],"sourcesContent":["import { computed, shallowRef, toValue, watchEffect } from 'vue'\nimport {\n assertLiveQueryWindowManyResult,\n compareLiveQueryWindowDependencies,\n createLiveQueryCollection,\n createLiveQueryWindowController,\n fetchNextLiveQueryWindowPage,\n getLiveQueryWindowCollectionWarning,\n normalizeLiveQueryWindowPageSize,\n resolveLiveQueryWindowInput,\n shouldPreserveLiveQueryWindowPageCount,\n} from '@tanstack/db'\nimport type {\n Collection,\n CollectionStatus,\n Context,\n GetResult,\n InferResultType,\n InitialQueryBuilder,\n NonSingleResult,\n QueryBuilder,\n UtilsRecord,\n} from '@tanstack/db'\nimport type { ComputedRef, MaybeRefOrGetter } from 'vue'\n\nconst DEFAULT_GC_TIME_MS = 1\n\ntype InternalCollection = Collection<object, string | number, UtilsRecord>\n\ntype PreviousController = {\n getSnapshot: () => { pages: ReadonlyArray<ReadonlyArray<unknown>> }\n}\n\ntype InfiniteQueryOptions = {\n pageSize?: number\n initialPageParam?: number\n}\n\nexport type LiveInfiniteQueryConfig<TRow> = InfiniteQueryOptions & {\n /**\n * @deprecated Pagination uses the shared controller's peek-ahead strategy.\n * This remains for compatibility with TanStack Query conventions.\n */\n getNextPageParam?: (\n lastPage: Array<TRow>,\n allPages: Array<Array<TRow>>,\n lastPageParam: number,\n allPageParams: Array<number>,\n ) => number | undefined\n}\n\nexport type UseLiveInfiniteQueryConfig<\n TContext extends Context & NonSingleResult,\n> = LiveInfiniteQueryConfig<InferResultType<TContext>[number]>\n\nexport interface UseLiveInfiniteQueryReturn<\n TContext extends Context & NonSingleResult,\n> {\n state: ComputedRef<Map<string | number, GetResult<TContext>>>\n data: ComputedRef<InferResultType<TContext>>\n collection: ComputedRef<\n Collection<GetResult<TContext>, string | number, UtilsRecord>\n >\n status: ComputedRef<CollectionStatus>\n isLoading: ComputedRef<boolean>\n isReady: ComputedRef<boolean>\n isIdle: ComputedRef<boolean>\n isError: ComputedRef<boolean>\n isCleanedUp: ComputedRef<boolean>\n pages: ComputedRef<Array<Array<InferResultType<TContext>[number]>>>\n pageParams: ComputedRef<Array<number>>\n fetchNextPage: () => Promise<void>\n hasNextPage: ComputedRef<boolean>\n isFetchingNextPage: ComputedRef<boolean>\n error: ComputedRef<unknown>\n}\n\nexport interface UseLiveInfiniteQueryReturnWithCollection<\n TResult extends object,\n TKey extends string | number,\n TUtils extends UtilsRecord,\n> {\n state: ComputedRef<Map<TKey, TResult>>\n data: ComputedRef<Array<TResult>>\n collection: ComputedRef<Collection<TResult, TKey, TUtils>>\n status: ComputedRef<CollectionStatus>\n isLoading: ComputedRef<boolean>\n isReady: ComputedRef<boolean>\n isIdle: ComputedRef<boolean>\n isError: ComputedRef<boolean>\n isCleanedUp: ComputedRef<boolean>\n pages: ComputedRef<Array<Array<TResult>>>\n pageParams: ComputedRef<Array<number>>\n fetchNextPage: () => Promise<void>\n hasNextPage: ComputedRef<boolean>\n isFetchingNextPage: ComputedRef<boolean>\n error: ComputedRef<unknown>\n}\n\n/**\n * Create a Vue-native reactive view over the shared live-query window\n * controller. The query must include an `orderBy` clause.\n */\nexport function useLiveInfiniteQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends UtilsRecord,\n>(\n liveQueryCollection: MaybeRefOrGetter<\n Collection<TResult, TKey, TUtils> & NonSingleResult\n >,\n config: LiveInfiniteQueryConfig<TResult>,\n): UseLiveInfiniteQueryReturnWithCollection<TResult, TKey, TUtils>\n\nexport function useLiveInfiniteQuery<\n TContext extends Context & NonSingleResult,\n>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n config: UseLiveInfiniteQueryConfig<TContext>,\n deps?: Array<MaybeRefOrGetter<unknown>>,\n): UseLiveInfiniteQueryReturn<TContext>\n\nexport function useLiveInfiniteQuery<\n TContext extends Context & NonSingleResult,\n>(\n queryFnOrCollection: unknown,\n config: InfiniteQueryOptions,\n deps: Array<MaybeRefOrGetter<unknown>> = [],\n): UseLiveInfiniteQueryReturn<TContext> {\n let validatedCollection: InternalCollection | null = null\n let previousController: PreviousController | null = null\n let previousInput: ReturnType<\n typeof resolveLiveQueryWindowInput<TContext>\n > | null = null\n let previousDependencies: Array<unknown> | null = null\n let previousPageSize: number | null = null\n let previousInitialPageParam: number | null = null\n\n const controller = computed(() => {\n const dependencies = deps.map((dependency) => toValue(dependency))\n\n const pageSize = normalizeLiveQueryWindowPageSize(config.pageSize)\n const initialPageParam = config.initialPageParam ?? 0\n const unwrappedInput =\n typeof queryFnOrCollection === `function`\n ? queryFnOrCollection\n : toValue(queryFnOrCollection)\n const input = resolveLiveQueryWindowInput<TContext>(unwrappedInput)\n const dependencyComparison = compareLiveQueryWindowDependencies(\n previousDependencies,\n dependencies,\n )\n const dependenciesChanged = dependencyComparison.changed\n const dependenciesStructurallyEqual = dependencyComparison.structurallyEqual\n const pageShapeChanged =\n previousPageSize !== pageSize ||\n previousInitialPageParam !== initialPageParam\n const sameCollection =\n input.kind === `collection` &&\n previousInput?.kind === `collection` &&\n previousInput.collection === input.collection\n const canPreservePageCount = shouldPreserveLiveQueryWindowPageCount({\n hasPreviousController: previousController !== null,\n previousInputKind: previousInput?.kind,\n inputKind: input.kind,\n sameCollection,\n dependenciesChanged,\n dependenciesStructurallyEqual,\n pageShapeChanged,\n })\n const previousPageCount = previousController\n ? Math.max(1, previousController.getSnapshot().pages.length)\n : 1\n const initialPageCount = canPreservePageCount ? previousPageCount : 1\n\n previousInput = input\n previousDependencies = [...dependencies]\n previousPageSize = pageSize\n previousInitialPageParam = initialPageParam\n\n if (input.kind === `collection`) {\n const collection = input.collection\n const warning = getLiveQueryWindowCollectionWarning(\n collection,\n pageSize + 1,\n )\n\n if (validatedCollection !== collection) {\n validatedCollection = collection\n if (warning) console.warn(warning)\n }\n\n const currentController = createLiveQueryWindowController(collection, {\n pageSize,\n initialPageParam,\n initialPageCount,\n })\n previousController = currentController\n return currentController\n }\n\n const collection = createLiveQueryCollection({\n query: input.query.limit(pageSize + 1).offset(0),\n startSync: false,\n gcTime: DEFAULT_GC_TIME_MS,\n })\n assertLiveQueryWindowManyResult(collection)\n const currentController = createLiveQueryWindowController(collection, {\n pageSize,\n initialPageParam,\n initialPageCount,\n })\n previousController = currentController\n return currentController\n })\n\n const snapshot = shallowRef(controller.value.getSnapshot())\n\n watchEffect(\n (onInvalidate) => {\n const currentController = controller.value\n const updateSnapshot = () => {\n snapshot.value = currentController.getSnapshot()\n }\n\n updateSnapshot()\n const unsubscribe = currentController.subscribe(updateSnapshot)\n updateSnapshot()\n\n onInvalidate(() => {\n unsubscribe()\n currentController.dispose()\n })\n },\n { flush: `sync` },\n )\n\n return {\n state: computed(\n () => snapshot.value.state as Map<string | number, GetResult<TContext>>,\n ),\n data: computed(() => snapshot.value.data as InferResultType<TContext>),\n collection: computed(\n () =>\n snapshot.value.collection as Collection<\n GetResult<TContext>,\n string | number,\n UtilsRecord\n >,\n ),\n status: computed(() => snapshot.value.status as CollectionStatus),\n isLoading: computed(() => snapshot.value.isLoading),\n isReady: computed(() => snapshot.value.isReady),\n isIdle: computed(() => snapshot.value.isIdle),\n isError: computed(() => snapshot.value.isError),\n isCleanedUp: computed(() => snapshot.value.isCleanedUp),\n pages: computed(\n () =>\n snapshot.value.pages as Array<Array<InferResultType<TContext>[number]>>,\n ),\n pageParams: computed(() => snapshot.value.pageParams as Array<number>),\n fetchNextPage: () => fetchNextLiveQueryWindowPage(controller.value),\n hasNextPage: computed(() => snapshot.value.hasNextPage),\n isFetchingNextPage: computed(() => snapshot.value.isFetchingNextPage),\n error: computed(() => snapshot.value.error),\n }\n}\n"],"names":["computed","toValue","normalizeLiveQueryWindowPageSize","resolveLiveQueryWindowInput","compareLiveQueryWindowDependencies","shouldPreserveLiveQueryWindowPageCount","collection","getLiveQueryWindowCollectionWarning","currentController","createLiveQueryWindowController","createLiveQueryCollection","assertLiveQueryWindowManyResult","shallowRef","watchEffect","fetchNextLiveQueryWindowPage"],"mappings":"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"}