@tanstack/vue-db 0.1.10 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/useLiveInfiniteQuery.cjs +5 -0
- package/dist/cjs/useLiveInfiniteQuery.cjs.map +1 -1
- package/dist/cjs/useLiveInfiniteQuery.d.cts +2 -7
- package/dist/esm/useLiveInfiniteQuery.d.ts +2 -7
- package/dist/esm/useLiveInfiniteQuery.js +5 -0
- package/dist/esm/useLiveInfiniteQuery.js.map +1 -1
- package/package.json +2 -2
- package/src/useLiveInfiniteQuery.ts +8 -12
|
@@ -4,6 +4,11 @@ const vue = require("vue");
|
|
|
4
4
|
const db = require("@tanstack/db");
|
|
5
5
|
const DEFAULT_GC_TIME_MS = 1;
|
|
6
6
|
function useLiveInfiniteQuery(queryFnOrCollection, config, deps = []) {
|
|
7
|
+
if (`getNextPageParam` in config) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
7
12
|
let validatedCollection = null;
|
|
8
13
|
let previousController = null;
|
|
9
14
|
let previousInput = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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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"}
|
|
1
|
+
{"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 /** First result-page label, not a server cursor or remote offset. */\n initialPageParam?: number\n}\n\n// Keep the generic parameter for existing typed config wrappers.\nexport type LiveInfiniteQueryConfig<_TRow> = InfiniteQueryOptions\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 if (`getNextPageParam` in config) {\n throw new Error(\n `getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.`,\n )\n }\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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"}
|
|
@@ -2,15 +2,10 @@ import { Collection, CollectionStatus, Context, GetResult, InferResultType, Init
|
|
|
2
2
|
import { ComputedRef, MaybeRefOrGetter } from 'vue';
|
|
3
3
|
type InfiniteQueryOptions = {
|
|
4
4
|
pageSize?: number;
|
|
5
|
+
/** First result-page label, not a server cursor or remote offset. */
|
|
5
6
|
initialPageParam?: number;
|
|
6
7
|
};
|
|
7
|
-
export type LiveInfiniteQueryConfig<
|
|
8
|
-
/**
|
|
9
|
-
* @deprecated Pagination uses the shared controller's peek-ahead strategy.
|
|
10
|
-
* This remains for compatibility with TanStack Query conventions.
|
|
11
|
-
*/
|
|
12
|
-
getNextPageParam?: (lastPage: Array<TRow>, allPages: Array<Array<TRow>>, lastPageParam: number, allPageParams: Array<number>) => number | undefined;
|
|
13
|
-
};
|
|
8
|
+
export type LiveInfiniteQueryConfig<_TRow> = InfiniteQueryOptions;
|
|
14
9
|
export type UseLiveInfiniteQueryConfig<TContext extends Context & NonSingleResult> = LiveInfiniteQueryConfig<InferResultType<TContext>[number]>;
|
|
15
10
|
export interface UseLiveInfiniteQueryReturn<TContext extends Context & NonSingleResult> {
|
|
16
11
|
state: ComputedRef<Map<string | number, GetResult<TContext>>>;
|
|
@@ -2,15 +2,10 @@ import { Collection, CollectionStatus, Context, GetResult, InferResultType, Init
|
|
|
2
2
|
import { ComputedRef, MaybeRefOrGetter } from 'vue';
|
|
3
3
|
type InfiniteQueryOptions = {
|
|
4
4
|
pageSize?: number;
|
|
5
|
+
/** First result-page label, not a server cursor or remote offset. */
|
|
5
6
|
initialPageParam?: number;
|
|
6
7
|
};
|
|
7
|
-
export type LiveInfiniteQueryConfig<
|
|
8
|
-
/**
|
|
9
|
-
* @deprecated Pagination uses the shared controller's peek-ahead strategy.
|
|
10
|
-
* This remains for compatibility with TanStack Query conventions.
|
|
11
|
-
*/
|
|
12
|
-
getNextPageParam?: (lastPage: Array<TRow>, allPages: Array<Array<TRow>>, lastPageParam: number, allPageParams: Array<number>) => number | undefined;
|
|
13
|
-
};
|
|
8
|
+
export type LiveInfiniteQueryConfig<_TRow> = InfiniteQueryOptions;
|
|
14
9
|
export type UseLiveInfiniteQueryConfig<TContext extends Context & NonSingleResult> = LiveInfiniteQueryConfig<InferResultType<TContext>[number]>;
|
|
15
10
|
export interface UseLiveInfiniteQueryReturn<TContext extends Context & NonSingleResult> {
|
|
16
11
|
state: ComputedRef<Map<string | number, GetResult<TContext>>>;
|
|
@@ -2,6 +2,11 @@ import { computed, toValue, shallowRef, watchEffect } from "vue";
|
|
|
2
2
|
import { normalizeLiveQueryWindowPageSize, resolveLiveQueryWindowInput, compareLiveQueryWindowDependencies, shouldPreserveLiveQueryWindowPageCount, getLiveQueryWindowCollectionWarning, createLiveQueryWindowController, createLiveQueryCollection, assertLiveQueryWindowManyResult, fetchNextLiveQueryWindowPage } from "@tanstack/db";
|
|
3
3
|
const DEFAULT_GC_TIME_MS = 1;
|
|
4
4
|
function useLiveInfiniteQuery(queryFnOrCollection, config, deps = []) {
|
|
5
|
+
if (`getNextPageParam` in config) {
|
|
6
|
+
throw new Error(
|
|
7
|
+
`getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.`
|
|
8
|
+
);
|
|
9
|
+
}
|
|
5
10
|
let validatedCollection = null;
|
|
6
11
|
let previousController = null;
|
|
7
12
|
let previousInput = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLiveInfiniteQuery.js","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":["collection","currentController"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useLiveInfiniteQuery.js","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 /** First result-page label, not a server cursor or remote offset. */\n initialPageParam?: number\n}\n\n// Keep the generic parameter for existing typed config wrappers.\nexport type LiveInfiniteQueryConfig<_TRow> = InfiniteQueryOptions\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 if (`getNextPageParam` in config) {\n throw new Error(\n `getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.`,\n )\n }\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":["collection","currentController"],"mappings":";;AAyBA,MAAM,qBAAqB;AAwFpB,SAAS,qBAGd,qBACA,QACA,OAAyC,CAAA,GACH;AACtC,MAAI,sBAAsB,QAAQ;AAChC,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,MAAI,sBAAiD;AACrD,MAAI,qBAAgD;AACpD,MAAI,gBAEO;AACX,MAAI,uBAA8C;AAClD,MAAI,mBAAkC;AACtC,MAAI,2BAA0C;AAE9C,QAAM,aAAa,SAAS,MAAM;AAChC,UAAM,eAAe,KAAK,IAAI,CAAC,eAAe,QAAQ,UAAU,CAAC;AAEjE,UAAM,WAAW,iCAAiC,OAAO,QAAQ;AACjE,UAAM,mBAAmB,OAAO,oBAAoB;AACpD,UAAM,iBACJ,OAAO,wBAAwB,aAC3B,sBACA,QAAQ,mBAAmB;AACjC,UAAM,QAAQ,4BAAsC,cAAc;AAClE,UAAM,uBAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,sBAAsB,qBAAqB;AACjD,UAAM,gCAAgC,qBAAqB;AAC3D,UAAM,mBACJ,qBAAqB,YACrB,6BAA6B;AAC/B,UAAM,iBACJ,MAAM,SAAS,gBACf,eAAe,SAAS,gBACxB,cAAc,eAAe,MAAM;AACrC,UAAM,uBAAuB,uCAAuC;AAAA,MAClE,uBAAuB,uBAAuB;AAAA,MAC9C,mBAAmB,eAAe;AAAA,MAClC,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,UAAM,oBAAoB,qBACtB,KAAK,IAAI,GAAG,mBAAmB,YAAA,EAAc,MAAM,MAAM,IACzD;AACJ,UAAM,mBAAmB,uBAAuB,oBAAoB;AAEpE,oBAAgB;AAChB,2BAAuB,CAAC,GAAG,YAAY;AACvC,uBAAmB;AACnB,+BAA2B;AAE3B,QAAI,MAAM,SAAS,cAAc;AAC/B,YAAMA,cAAa,MAAM;AACzB,YAAM,UAAU;AAAA,QACdA;AAAAA,QACA,WAAW;AAAA,MAAA;AAGb,UAAI,wBAAwBA,aAAY;AACtC,8BAAsBA;AACtB,YAAI,QAAS,SAAQ,KAAK,OAAO;AAAA,MACnC;AAEA,YAAMC,qBAAoB,gCAAgCD,aAAY;AAAA,QACpE;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AACD,2BAAqBC;AACrB,aAAOA;AAAAA,IACT;AAEA,UAAM,aAAa,0BAA0B;AAAA,MAC3C,OAAO,MAAM,MAAM,MAAM,WAAW,CAAC,EAAE,OAAO,CAAC;AAAA,MAC/C,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,CACT;AACD,oCAAgC,UAAU;AAC1C,UAAM,oBAAoB,gCAAgC,YAAY;AAAA,MACpE;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,yBAAqB;AACrB,WAAO;AAAA,EACT,CAAC;AAED,QAAM,WAAW,WAAW,WAAW,MAAM,aAAa;AAE1D;AAAA,IACE,CAAC,iBAAiB;AAChB,YAAM,oBAAoB,WAAW;AACrC,YAAM,iBAAiB,MAAM;AAC3B,iBAAS,QAAQ,kBAAkB,YAAA;AAAA,MACrC;AAEA,qBAAA;AACA,YAAM,cAAc,kBAAkB,UAAU,cAAc;AAC9D,qBAAA;AAEA,mBAAa,MAAM;AACjB,oBAAA;AACA,0BAAkB,QAAA;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,IACA,EAAE,OAAO,OAAA;AAAA,EAAO;AAGlB,SAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM,SAAS,MAAM;AAAA,IAAA;AAAA,IAEvB,MAAM,SAAS,MAAM,SAAS,MAAM,IAAiC;AAAA,IACrE,YAAY;AAAA,MACV,MACE,SAAS,MAAM;AAAA,IAAA;AAAA,IAMnB,QAAQ,SAAS,MAAM,SAAS,MAAM,MAA0B;AAAA,IAChE,WAAW,SAAS,MAAM,SAAS,MAAM,SAAS;AAAA,IAClD,SAAS,SAAS,MAAM,SAAS,MAAM,OAAO;AAAA,IAC9C,QAAQ,SAAS,MAAM,SAAS,MAAM,MAAM;AAAA,IAC5C,SAAS,SAAS,MAAM,SAAS,MAAM,OAAO;AAAA,IAC9C,aAAa,SAAS,MAAM,SAAS,MAAM,WAAW;AAAA,IACtD,OAAO;AAAA,MACL,MACE,SAAS,MAAM;AAAA,IAAA;AAAA,IAEnB,YAAY,SAAS,MAAM,SAAS,MAAM,UAA2B;AAAA,IACrE,eAAe,MAAM,6BAA6B,WAAW,KAAK;AAAA,IAClE,aAAa,SAAS,MAAM,SAAS,MAAM,WAAW;AAAA,IACtD,oBAAoB,SAAS,MAAM,SAAS,MAAM,kBAAkB;AAAA,IACpE,OAAO,SAAS,MAAM,SAAS,MAAM,KAAK;AAAA,EAAA;AAE9C;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/vue-db",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Vue integration for @tanstack/db",
|
|
5
5
|
"author": "Kyle Mathews",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"skills"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@tanstack/db": "0.9.
|
|
43
|
+
"@tanstack/db": "0.9.2"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"vue": ">=3.3.0"
|
|
@@ -33,21 +33,12 @@ type PreviousController = {
|
|
|
33
33
|
|
|
34
34
|
type InfiniteQueryOptions = {
|
|
35
35
|
pageSize?: number
|
|
36
|
+
/** First result-page label, not a server cursor or remote offset. */
|
|
36
37
|
initialPageParam?: number
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
* @deprecated Pagination uses the shared controller's peek-ahead strategy.
|
|
42
|
-
* This remains for compatibility with TanStack Query conventions.
|
|
43
|
-
*/
|
|
44
|
-
getNextPageParam?: (
|
|
45
|
-
lastPage: Array<TRow>,
|
|
46
|
-
allPages: Array<Array<TRow>>,
|
|
47
|
-
lastPageParam: number,
|
|
48
|
-
allPageParams: Array<number>,
|
|
49
|
-
) => number | undefined
|
|
50
|
-
}
|
|
40
|
+
// Keep the generic parameter for existing typed config wrappers.
|
|
41
|
+
export type LiveInfiniteQueryConfig<_TRow> = InfiniteQueryOptions
|
|
51
42
|
|
|
52
43
|
export type UseLiveInfiniteQueryConfig<
|
|
53
44
|
TContext extends Context & NonSingleResult,
|
|
@@ -127,6 +118,11 @@ export function useLiveInfiniteQuery<
|
|
|
127
118
|
config: InfiniteQueryOptions,
|
|
128
119
|
deps: Array<MaybeRefOrGetter<unknown>> = [],
|
|
129
120
|
): UseLiveInfiniteQueryReturn<TContext> {
|
|
121
|
+
if (`getNextPageParam` in config) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.`,
|
|
124
|
+
)
|
|
125
|
+
}
|
|
130
126
|
let validatedCollection: InternalCollection | null = null
|
|
131
127
|
let previousController: PreviousController | null = null
|
|
132
128
|
let previousInput: ReturnType<
|