@tanstack/angular-db 0.2.1 → 0.2.3
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/index.cjs +6 -12
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +7 -13
- package/dist/esm/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +8 -12
package/dist/cjs/index.cjs
CHANGED
|
@@ -15,11 +15,7 @@ function injectLiveQuery(opts) {
|
|
|
15
15
|
if (result === void 0 || result === null) {
|
|
16
16
|
return null;
|
|
17
17
|
}
|
|
18
|
-
return db.
|
|
19
|
-
query: opts,
|
|
20
|
-
startSync: true,
|
|
21
|
-
gcTime: 0
|
|
22
|
-
});
|
|
18
|
+
return db.resolveLiveQueryValue(result, { gcTime: 0 });
|
|
23
19
|
}
|
|
24
20
|
const isReactiveQueryOptions = opts && typeof opts === `object` && typeof opts.query === `function` && typeof opts.params === `function`;
|
|
25
21
|
if (isReactiveQueryOptions) {
|
|
@@ -30,11 +26,7 @@ function injectLiveQuery(opts) {
|
|
|
30
26
|
if (result === void 0 || result === null) {
|
|
31
27
|
return null;
|
|
32
28
|
}
|
|
33
|
-
return db.
|
|
34
|
-
query: () => result,
|
|
35
|
-
startSync: true,
|
|
36
|
-
gcTime: 0
|
|
37
|
-
});
|
|
29
|
+
return db.resolveLiveQueryValue(result, { gcTime: 0 });
|
|
38
30
|
}
|
|
39
31
|
if (opts && typeof opts === `object` && typeof opts.query === `function`) {
|
|
40
32
|
return db.createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts });
|
|
@@ -59,7 +51,7 @@ function injectLiveQuery(opts) {
|
|
|
59
51
|
});
|
|
60
52
|
const syncDataFromCollection = (currentCollection, observer) => {
|
|
61
53
|
const newState = new Map(currentCollection.entries());
|
|
62
|
-
const newData = Array.from(
|
|
54
|
+
const newData = Array.from(newState.values());
|
|
63
55
|
state.set(newState);
|
|
64
56
|
internalData.set(newData);
|
|
65
57
|
const snapshot = observer.getSnapshot();
|
|
@@ -103,7 +95,9 @@ function injectLiveQuery(opts) {
|
|
|
103
95
|
data,
|
|
104
96
|
// Loosely typed so the impl return stays compatible with every overload
|
|
105
97
|
// (the shared `isCollection` guard narrows the computed to `Collection | null`).
|
|
106
|
-
collection
|
|
98
|
+
collection: core.computed(
|
|
99
|
+
() => db.getPublicCollection(collection())
|
|
100
|
+
),
|
|
107
101
|
status,
|
|
108
102
|
isLoading: core.computed(() => status() === `loading`),
|
|
109
103
|
isReady: core.computed(() => status() === `ready` || status() === `disabled`),
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import {\n DestroyRef,\n assertInInjectionContext,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core'\nimport {\n BaseQueryBuilder,\n createLiveQueryCollection,\n createLiveQueryObserver,\n isCollection,\n isSingleResultCollection,\n} from '@tanstack/db'\nimport type {\n Collection,\n CollectionStatus,\n Context,\n GetResult,\n InferResultType,\n InitialQueryBuilder,\n LiveQueryCollectionConfig,\n LiveQueryObserver,\n LiveQueryPersistedStatus,\n NonSingleResult,\n QueryBuilder,\n SingleResult,\n} from '@tanstack/db'\nimport type { Signal } from '@angular/core'\n\nexport * from '@tanstack/db'\n\n/**\n * The result of calling `injectLiveQuery`.\n * Contains reactive signals for the query state and data.\n */\nexport interface InjectLiveQueryResult<TContext extends Context> {\n /** A signal containing the complete state map of results keyed by their ID */\n state: Signal<Map<string | number, GetResult<TContext>>>\n /** A signal containing the results as an array, or single result for findOne queries */\n data: Signal<InferResultType<TContext>>\n /** A signal containing the underlying collection instance (null for disabled queries) */\n collection: Signal<Collection<\n GetResult<TContext>,\n string | number,\n {}\n > | null>\n /** A signal containing the current status of the collection */\n status: Signal<CollectionStatus | `disabled`>\n /** A signal indicating whether the collection is currently loading */\n isLoading: Signal<boolean>\n /** A signal indicating whether the collection is ready */\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n /** A signal indicating whether the collection is idle */\n isIdle: Signal<boolean>\n /** A signal indicating whether the collection has an error */\n isError: Signal<boolean>\n /** A signal indicating whether the collection has been cleaned up */\n isCleanedUp: Signal<boolean>\n}\n\ntype InferConditionalResultType<TContext extends Context> =\n TContext extends SingleResult\n ? InferResultType<TContext> | []\n : InferResultType<TContext>\n\nexport type InjectConditionalLiveQueryResult<TContext extends Context> = Omit<\n InjectLiveQueryResult<TContext>,\n `data`\n> & {\n data: Signal<InferConditionalResultType<TContext>>\n}\n\nexport interface InjectLiveQueryResultWithCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<Array<TResult>>\n collection: Signal<Collection<TResult, TKey, TUtils> | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport interface InjectLiveQueryResultWithSingleResultCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<TResult | undefined>\n collection: Signal<(Collection<TResult, TKey, TUtils> & SingleResult) | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext>\n}): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext> | undefined | null\n}): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (\n q: InitialQueryBuilder,\n ) => QueryBuilder<TContext> | undefined | null,\n): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n config: LiveQueryCollectionConfig<TContext>,\n): InjectLiveQueryResult<TContext>\n// Pre-created collection without singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & NonSingleResult,\n): InjectLiveQueryResultWithCollection<TResult, TKey, TUtils>\n// Pre-created collection with singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & SingleResult,\n): InjectLiveQueryResultWithSingleResultCollection<TResult, TKey, TUtils>\nexport function injectLiveQuery(opts: any) {\n assertInInjectionContext(injectLiveQuery)\n const destroyRef = inject(DestroyRef)\n\n const collection = computed(() => {\n // Check if it's an existing collection\n if (isCollection(opts)) {\n return opts\n }\n\n if (typeof opts === `function`) {\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = opts(queryBuilder)\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return createLiveQueryCollection({\n query: opts,\n startSync: true,\n gcTime: 0,\n })\n }\n\n // Check if it's reactive query options\n const isReactiveQueryOptions =\n opts &&\n typeof opts === `object` &&\n typeof opts.query === `function` &&\n typeof opts.params === `function`\n\n if (isReactiveQueryOptions) {\n const { params, query } = opts\n const currentParams = params()\n\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = query({ params: currentParams, q: queryBuilder })\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return createLiveQueryCollection({\n query: () => result,\n startSync: true,\n gcTime: 0,\n })\n }\n\n // Handle LiveQueryCollectionConfig objects. Default startSync/gcTime to\n // match the query-fn and reactive-options paths, but let an explicit value\n // in the config win — otherwise a bare `{ query }` never syncs.\n if (opts && typeof opts === `object` && typeof opts.query === `function`) {\n return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts })\n }\n\n throw new Error(`Invalid options provided to injectLiveQuery`)\n })\n\n const state = signal(new Map<string | number, any>())\n const internalData = signal<Array<any>>([])\n const statusValue = signal<CollectionStatus | `disabled`>(`idle`)\n const status = computed(() => {\n const value = statusValue()\n return value === `idle` && !collection() ? `disabled` : value\n })\n const persistedStatus = signal<LiveQueryPersistedStatus>(`unavailable`)\n const persistedError = signal<unknown>(undefined)\n\n // Returns single item for singleResult collections, array otherwise\n const data = computed(() => {\n const currentCollection = collection()\n if (!currentCollection) {\n return internalData()\n }\n return isSingleResultCollection(currentCollection)\n ? internalData()[0]\n : internalData()\n })\n\n const syncDataFromCollection = (\n currentCollection: Collection<any, any, any>,\n observer: LiveQueryObserver<any, any>,\n ) => {\n const newState = new Map(currentCollection.entries())\n const newData = Array.from(currentCollection.values())\n\n state.set(newState)\n internalData.set(newData)\n const snapshot = observer.getSnapshot()\n statusValue.set(snapshot.status)\n persistedStatus.set(snapshot.persistedStatus)\n persistedError.set(snapshot.persistedError)\n }\n\n let unsub: (() => void) | null = null\n const cleanup = () => {\n unsub?.()\n unsub = null\n }\n\n effect((onCleanup) => {\n const currentCollection = collection()\n\n // Handle null collection (disabled query)\n if (!currentCollection) {\n statusValue.set(`disabled` as const)\n persistedStatus.set(`unavailable`)\n persistedError.set(undefined)\n state.set(new Map())\n internalData.set([])\n cleanup()\n return\n }\n\n cleanup()\n\n // The shared observer owns sync start, subscription, the ready-race, and\n // status transitions; Angular re-reads the whole collection on each notify\n // (wholesale) into its signals.\n // Angular re-reads the collection on notify; wholesale mode preserves its\n // pre-observer loading policy (no initial-state snapshot request).\n const observer = createLiveQueryObserver(currentCollection, {\n mode: `wholesale`,\n })\n\n const unsubscribe = observer.subscribe(() => {\n syncDataFromCollection(currentCollection, observer)\n })\n // Wholesale attach suppresses listener calls raised by synchronous sync\n // startup. Read once after subscribe returns to capture that final state.\n syncDataFromCollection(currentCollection, observer)\n unsub = () => {\n unsubscribe()\n observer.dispose()\n }\n\n onCleanup(cleanup)\n })\n\n destroyRef.onDestroy(cleanup)\n\n return {\n state,\n data,\n // Loosely typed so the impl return stays compatible with every overload\n // (the shared `isCollection` guard narrows the computed to `Collection | null`).\n collection: collection as Signal<any>,\n status,\n isLoading: computed(() => status() === `loading`),\n isReady: computed(() => status() === `ready` || status() === `disabled`),\n persistedStatus,\n isPersistedReady: computed(() => persistedStatus() === `ready`),\n persistedError,\n isIdle: computed(() => status() === `idle`),\n isError: computed(() => status() === `error`),\n isCleanedUp: computed(() => status() === `cleaned-up`),\n }\n}\n"],"names":["assertInInjectionContext","inject","DestroyRef","computed","isCollection","BaseQueryBuilder","createLiveQueryCollection","signal","isSingleResultCollection","effect","createLiveQueryObserver"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import {\n DestroyRef,\n assertInInjectionContext,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core'\nimport {\n BaseQueryBuilder,\n createLiveQueryCollection,\n createLiveQueryObserver,\n getPublicCollection,\n isCollection,\n isSingleResultCollection,\n resolveLiveQueryValue,\n} from '@tanstack/db'\nimport type {\n Collection,\n CollectionStatus,\n Context,\n GetResult,\n InferResultType,\n InitialQueryBuilder,\n LiveQueryCollectionConfig,\n LiveQueryObserver,\n LiveQueryPersistedStatus,\n NonSingleResult,\n QueryBuilder,\n SingleResult,\n} from '@tanstack/db'\nimport type { Signal } from '@angular/core'\n\nexport * from '@tanstack/db'\n\n/**\n * The result of calling `injectLiveQuery`.\n * Contains reactive signals for the query state and data.\n */\nexport interface InjectLiveQueryResult<TContext extends Context> {\n /** A signal containing the complete state map of results keyed by their ID */\n state: Signal<Map<string | number, GetResult<TContext>>>\n /** A signal containing the results as an array, or single result for findOne queries */\n data: Signal<InferResultType<TContext>>\n /** A signal containing the underlying collection instance (null for disabled queries) */\n collection: Signal<Collection<\n GetResult<TContext>,\n string | number,\n {}\n > | null>\n /** A signal containing the current status of the collection */\n status: Signal<CollectionStatus | `disabled`>\n /** A signal indicating whether the collection is currently loading */\n isLoading: Signal<boolean>\n /** A signal indicating whether the collection is ready */\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n /** A signal indicating whether the collection is idle */\n isIdle: Signal<boolean>\n /** A signal indicating whether the collection has an error */\n isError: Signal<boolean>\n /** A signal indicating whether the collection has been cleaned up */\n isCleanedUp: Signal<boolean>\n}\n\ntype InferConditionalResultType<TContext extends Context> =\n TContext extends SingleResult\n ? InferResultType<TContext> | []\n : InferResultType<TContext>\n\nexport type InjectConditionalLiveQueryResult<TContext extends Context> = Omit<\n InjectLiveQueryResult<TContext>,\n `data`\n> & {\n data: Signal<InferConditionalResultType<TContext>>\n}\n\nexport interface InjectLiveQueryResultWithCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<Array<TResult>>\n collection: Signal<Collection<TResult, TKey, TUtils> | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport interface InjectLiveQueryResultWithSingleResultCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<TResult | undefined>\n collection: Signal<(Collection<TResult, TKey, TUtils> & SingleResult) | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext>\n}): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext> | undefined | null\n}): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (\n q: InitialQueryBuilder,\n ) => QueryBuilder<TContext> | undefined | null,\n): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n config: LiveQueryCollectionConfig<TContext>,\n): InjectLiveQueryResult<TContext>\n// Pre-created collection without singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & NonSingleResult,\n): InjectLiveQueryResultWithCollection<TResult, TKey, TUtils>\n// Pre-created collection with singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & SingleResult,\n): InjectLiveQueryResultWithSingleResultCollection<TResult, TKey, TUtils>\nexport function injectLiveQuery(opts: any) {\n assertInInjectionContext(injectLiveQuery)\n const destroyRef = inject(DestroyRef)\n\n const collection = computed(() => {\n // Check if it's an existing collection\n if (isCollection(opts)) {\n return opts\n }\n\n if (typeof opts === `function`) {\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = opts(queryBuilder)\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return resolveLiveQueryValue(result, { gcTime: 0 })\n }\n\n // Check if it's reactive query options\n const isReactiveQueryOptions =\n opts &&\n typeof opts === `object` &&\n typeof opts.query === `function` &&\n typeof opts.params === `function`\n\n if (isReactiveQueryOptions) {\n const { params, query } = opts\n const currentParams = params()\n\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = query({ params: currentParams, q: queryBuilder })\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return resolveLiveQueryValue(result, { gcTime: 0 })\n }\n\n // Handle LiveQueryCollectionConfig objects. Default startSync/gcTime to\n // match the query-fn and reactive-options paths, but let an explicit value\n // in the config win — otherwise a bare `{ query }` never syncs.\n if (opts && typeof opts === `object` && typeof opts.query === `function`) {\n return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts })\n }\n\n throw new Error(`Invalid options provided to injectLiveQuery`)\n })\n\n const state = signal(new Map<string | number, any>())\n const internalData = signal<Array<any>>([])\n const statusValue = signal<CollectionStatus | `disabled`>(`idle`)\n const status = computed(() => {\n const value = statusValue()\n return value === `idle` && !collection() ? `disabled` : value\n })\n const persistedStatus = signal<LiveQueryPersistedStatus>(`unavailable`)\n const persistedError = signal<unknown>(undefined)\n\n // Returns single item for singleResult collections, array otherwise\n const data = computed(() => {\n const currentCollection = collection()\n if (!currentCollection) {\n return internalData()\n }\n return isSingleResultCollection(currentCollection)\n ? internalData()[0]\n : internalData()\n })\n\n const syncDataFromCollection = (\n currentCollection: Collection<any, any, any>,\n observer: LiveQueryObserver<any, any>,\n ) => {\n const newState = new Map(currentCollection.entries())\n const newData = Array.from(newState.values())\n\n state.set(newState)\n internalData.set(newData)\n const snapshot = observer.getSnapshot()\n statusValue.set(snapshot.status)\n persistedStatus.set(snapshot.persistedStatus)\n persistedError.set(snapshot.persistedError)\n }\n\n let unsub: (() => void) | null = null\n const cleanup = () => {\n unsub?.()\n unsub = null\n }\n\n effect((onCleanup) => {\n const currentCollection = collection()\n\n // Handle null collection (disabled query)\n if (!currentCollection) {\n statusValue.set(`disabled` as const)\n persistedStatus.set(`unavailable`)\n persistedError.set(undefined)\n state.set(new Map())\n internalData.set([])\n cleanup()\n return\n }\n\n cleanup()\n\n // The shared observer owns sync start, subscription, the ready-race, and\n // status transitions; Angular re-reads the whole collection on each notify\n // (wholesale) into its signals.\n // Angular re-reads the collection on notify; wholesale mode preserves its\n // pre-observer loading policy (no initial-state snapshot request).\n const observer = createLiveQueryObserver(currentCollection, {\n mode: `wholesale`,\n })\n\n const unsubscribe = observer.subscribe(() => {\n syncDataFromCollection(currentCollection, observer)\n })\n // Wholesale attach suppresses listener calls raised by synchronous sync\n // startup. Read once after subscribe returns to capture that final state.\n syncDataFromCollection(currentCollection, observer)\n unsub = () => {\n unsubscribe()\n observer.dispose()\n }\n\n onCleanup(cleanup)\n })\n\n destroyRef.onDestroy(cleanup)\n\n return {\n state,\n data,\n // Loosely typed so the impl return stays compatible with every overload\n // (the shared `isCollection` guard narrows the computed to `Collection | null`).\n collection: computed(() =>\n getPublicCollection(collection()),\n ) as Signal<any>,\n status,\n isLoading: computed(() => status() === `loading`),\n isReady: computed(() => status() === `ready` || status() === `disabled`),\n persistedStatus,\n isPersistedReady: computed(() => persistedStatus() === `ready`),\n persistedError,\n isIdle: computed(() => status() === `idle`),\n isError: computed(() => status() === `error`),\n isCleanedUp: computed(() => status() === `cleaned-up`),\n }\n}\n"],"names":["assertInInjectionContext","inject","DestroyRef","computed","isCollection","BaseQueryBuilder","resolveLiveQueryValue","createLiveQueryCollection","signal","isSingleResultCollection","effect","createLiveQueryObserver","getPublicCollection"],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assertInInjectionContext, inject, DestroyRef, computed, signal, effect } from "@angular/core";
|
|
2
|
-
import { isCollection, BaseQueryBuilder, createLiveQueryCollection, isSingleResultCollection, createLiveQueryObserver } from "@tanstack/db";
|
|
2
|
+
import { isCollection, BaseQueryBuilder, resolveLiveQueryValue, createLiveQueryCollection, isSingleResultCollection, createLiveQueryObserver, getPublicCollection } from "@tanstack/db";
|
|
3
3
|
export * from "@tanstack/db";
|
|
4
4
|
function injectLiveQuery(opts) {
|
|
5
5
|
assertInInjectionContext(injectLiveQuery);
|
|
@@ -14,11 +14,7 @@ function injectLiveQuery(opts) {
|
|
|
14
14
|
if (result === void 0 || result === null) {
|
|
15
15
|
return null;
|
|
16
16
|
}
|
|
17
|
-
return
|
|
18
|
-
query: opts,
|
|
19
|
-
startSync: true,
|
|
20
|
-
gcTime: 0
|
|
21
|
-
});
|
|
17
|
+
return resolveLiveQueryValue(result, { gcTime: 0 });
|
|
22
18
|
}
|
|
23
19
|
const isReactiveQueryOptions = opts && typeof opts === `object` && typeof opts.query === `function` && typeof opts.params === `function`;
|
|
24
20
|
if (isReactiveQueryOptions) {
|
|
@@ -29,11 +25,7 @@ function injectLiveQuery(opts) {
|
|
|
29
25
|
if (result === void 0 || result === null) {
|
|
30
26
|
return null;
|
|
31
27
|
}
|
|
32
|
-
return
|
|
33
|
-
query: () => result,
|
|
34
|
-
startSync: true,
|
|
35
|
-
gcTime: 0
|
|
36
|
-
});
|
|
28
|
+
return resolveLiveQueryValue(result, { gcTime: 0 });
|
|
37
29
|
}
|
|
38
30
|
if (opts && typeof opts === `object` && typeof opts.query === `function`) {
|
|
39
31
|
return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts });
|
|
@@ -58,7 +50,7 @@ function injectLiveQuery(opts) {
|
|
|
58
50
|
});
|
|
59
51
|
const syncDataFromCollection = (currentCollection, observer) => {
|
|
60
52
|
const newState = new Map(currentCollection.entries());
|
|
61
|
-
const newData = Array.from(
|
|
53
|
+
const newData = Array.from(newState.values());
|
|
62
54
|
state.set(newState);
|
|
63
55
|
internalData.set(newData);
|
|
64
56
|
const snapshot = observer.getSnapshot();
|
|
@@ -102,7 +94,9 @@ function injectLiveQuery(opts) {
|
|
|
102
94
|
data,
|
|
103
95
|
// Loosely typed so the impl return stays compatible with every overload
|
|
104
96
|
// (the shared `isCollection` guard narrows the computed to `Collection | null`).
|
|
105
|
-
collection
|
|
97
|
+
collection: computed(
|
|
98
|
+
() => getPublicCollection(collection())
|
|
99
|
+
),
|
|
106
100
|
status,
|
|
107
101
|
isLoading: computed(() => status() === `loading`),
|
|
108
102
|
isReady: computed(() => status() === `ready` || status() === `disabled`),
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["import {\n DestroyRef,\n assertInInjectionContext,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core'\nimport {\n BaseQueryBuilder,\n createLiveQueryCollection,\n createLiveQueryObserver,\n isCollection,\n isSingleResultCollection,\n} from '@tanstack/db'\nimport type {\n Collection,\n CollectionStatus,\n Context,\n GetResult,\n InferResultType,\n InitialQueryBuilder,\n LiveQueryCollectionConfig,\n LiveQueryObserver,\n LiveQueryPersistedStatus,\n NonSingleResult,\n QueryBuilder,\n SingleResult,\n} from '@tanstack/db'\nimport type { Signal } from '@angular/core'\n\nexport * from '@tanstack/db'\n\n/**\n * The result of calling `injectLiveQuery`.\n * Contains reactive signals for the query state and data.\n */\nexport interface InjectLiveQueryResult<TContext extends Context> {\n /** A signal containing the complete state map of results keyed by their ID */\n state: Signal<Map<string | number, GetResult<TContext>>>\n /** A signal containing the results as an array, or single result for findOne queries */\n data: Signal<InferResultType<TContext>>\n /** A signal containing the underlying collection instance (null for disabled queries) */\n collection: Signal<Collection<\n GetResult<TContext>,\n string | number,\n {}\n > | null>\n /** A signal containing the current status of the collection */\n status: Signal<CollectionStatus | `disabled`>\n /** A signal indicating whether the collection is currently loading */\n isLoading: Signal<boolean>\n /** A signal indicating whether the collection is ready */\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n /** A signal indicating whether the collection is idle */\n isIdle: Signal<boolean>\n /** A signal indicating whether the collection has an error */\n isError: Signal<boolean>\n /** A signal indicating whether the collection has been cleaned up */\n isCleanedUp: Signal<boolean>\n}\n\ntype InferConditionalResultType<TContext extends Context> =\n TContext extends SingleResult\n ? InferResultType<TContext> | []\n : InferResultType<TContext>\n\nexport type InjectConditionalLiveQueryResult<TContext extends Context> = Omit<\n InjectLiveQueryResult<TContext>,\n `data`\n> & {\n data: Signal<InferConditionalResultType<TContext>>\n}\n\nexport interface InjectLiveQueryResultWithCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<Array<TResult>>\n collection: Signal<Collection<TResult, TKey, TUtils> | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport interface InjectLiveQueryResultWithSingleResultCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<TResult | undefined>\n collection: Signal<(Collection<TResult, TKey, TUtils> & SingleResult) | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext>\n}): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext> | undefined | null\n}): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (\n q: InitialQueryBuilder,\n ) => QueryBuilder<TContext> | undefined | null,\n): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n config: LiveQueryCollectionConfig<TContext>,\n): InjectLiveQueryResult<TContext>\n// Pre-created collection without singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & NonSingleResult,\n): InjectLiveQueryResultWithCollection<TResult, TKey, TUtils>\n// Pre-created collection with singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & SingleResult,\n): InjectLiveQueryResultWithSingleResultCollection<TResult, TKey, TUtils>\nexport function injectLiveQuery(opts: any) {\n assertInInjectionContext(injectLiveQuery)\n const destroyRef = inject(DestroyRef)\n\n const collection = computed(() => {\n // Check if it's an existing collection\n if (isCollection(opts)) {\n return opts\n }\n\n if (typeof opts === `function`) {\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = opts(queryBuilder)\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return createLiveQueryCollection({\n query: opts,\n startSync: true,\n gcTime: 0,\n })\n }\n\n // Check if it's reactive query options\n const isReactiveQueryOptions =\n opts &&\n typeof opts === `object` &&\n typeof opts.query === `function` &&\n typeof opts.params === `function`\n\n if (isReactiveQueryOptions) {\n const { params, query } = opts\n const currentParams = params()\n\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = query({ params: currentParams, q: queryBuilder })\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return createLiveQueryCollection({\n query: () => result,\n startSync: true,\n gcTime: 0,\n })\n }\n\n // Handle LiveQueryCollectionConfig objects. Default startSync/gcTime to\n // match the query-fn and reactive-options paths, but let an explicit value\n // in the config win — otherwise a bare `{ query }` never syncs.\n if (opts && typeof opts === `object` && typeof opts.query === `function`) {\n return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts })\n }\n\n throw new Error(`Invalid options provided to injectLiveQuery`)\n })\n\n const state = signal(new Map<string | number, any>())\n const internalData = signal<Array<any>>([])\n const statusValue = signal<CollectionStatus | `disabled`>(`idle`)\n const status = computed(() => {\n const value = statusValue()\n return value === `idle` && !collection() ? `disabled` : value\n })\n const persistedStatus = signal<LiveQueryPersistedStatus>(`unavailable`)\n const persistedError = signal<unknown>(undefined)\n\n // Returns single item for singleResult collections, array otherwise\n const data = computed(() => {\n const currentCollection = collection()\n if (!currentCollection) {\n return internalData()\n }\n return isSingleResultCollection(currentCollection)\n ? internalData()[0]\n : internalData()\n })\n\n const syncDataFromCollection = (\n currentCollection: Collection<any, any, any>,\n observer: LiveQueryObserver<any, any>,\n ) => {\n const newState = new Map(currentCollection.entries())\n const newData = Array.from(currentCollection.values())\n\n state.set(newState)\n internalData.set(newData)\n const snapshot = observer.getSnapshot()\n statusValue.set(snapshot.status)\n persistedStatus.set(snapshot.persistedStatus)\n persistedError.set(snapshot.persistedError)\n }\n\n let unsub: (() => void) | null = null\n const cleanup = () => {\n unsub?.()\n unsub = null\n }\n\n effect((onCleanup) => {\n const currentCollection = collection()\n\n // Handle null collection (disabled query)\n if (!currentCollection) {\n statusValue.set(`disabled` as const)\n persistedStatus.set(`unavailable`)\n persistedError.set(undefined)\n state.set(new Map())\n internalData.set([])\n cleanup()\n return\n }\n\n cleanup()\n\n // The shared observer owns sync start, subscription, the ready-race, and\n // status transitions; Angular re-reads the whole collection on each notify\n // (wholesale) into its signals.\n // Angular re-reads the collection on notify; wholesale mode preserves its\n // pre-observer loading policy (no initial-state snapshot request).\n const observer = createLiveQueryObserver(currentCollection, {\n mode: `wholesale`,\n })\n\n const unsubscribe = observer.subscribe(() => {\n syncDataFromCollection(currentCollection, observer)\n })\n // Wholesale attach suppresses listener calls raised by synchronous sync\n // startup. Read once after subscribe returns to capture that final state.\n syncDataFromCollection(currentCollection, observer)\n unsub = () => {\n unsubscribe()\n observer.dispose()\n }\n\n onCleanup(cleanup)\n })\n\n destroyRef.onDestroy(cleanup)\n\n return {\n state,\n data,\n // Loosely typed so the impl return stays compatible with every overload\n // (the shared `isCollection` guard narrows the computed to `Collection | null`).\n collection: collection as Signal<any>,\n status,\n isLoading: computed(() => status() === `loading`),\n isReady: computed(() => status() === `ready` || status() === `disabled`),\n persistedStatus,\n isPersistedReady: computed(() => persistedStatus() === `ready`),\n persistedError,\n isIdle: computed(() => status() === `idle`),\n isError: computed(() => status() === `error`),\n isCleanedUp: computed(() => status() === `cleaned-up`),\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["import {\n DestroyRef,\n assertInInjectionContext,\n computed,\n effect,\n inject,\n signal,\n} from '@angular/core'\nimport {\n BaseQueryBuilder,\n createLiveQueryCollection,\n createLiveQueryObserver,\n getPublicCollection,\n isCollection,\n isSingleResultCollection,\n resolveLiveQueryValue,\n} from '@tanstack/db'\nimport type {\n Collection,\n CollectionStatus,\n Context,\n GetResult,\n InferResultType,\n InitialQueryBuilder,\n LiveQueryCollectionConfig,\n LiveQueryObserver,\n LiveQueryPersistedStatus,\n NonSingleResult,\n QueryBuilder,\n SingleResult,\n} from '@tanstack/db'\nimport type { Signal } from '@angular/core'\n\nexport * from '@tanstack/db'\n\n/**\n * The result of calling `injectLiveQuery`.\n * Contains reactive signals for the query state and data.\n */\nexport interface InjectLiveQueryResult<TContext extends Context> {\n /** A signal containing the complete state map of results keyed by their ID */\n state: Signal<Map<string | number, GetResult<TContext>>>\n /** A signal containing the results as an array, or single result for findOne queries */\n data: Signal<InferResultType<TContext>>\n /** A signal containing the underlying collection instance (null for disabled queries) */\n collection: Signal<Collection<\n GetResult<TContext>,\n string | number,\n {}\n > | null>\n /** A signal containing the current status of the collection */\n status: Signal<CollectionStatus | `disabled`>\n /** A signal indicating whether the collection is currently loading */\n isLoading: Signal<boolean>\n /** A signal indicating whether the collection is ready */\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n /** A signal indicating whether the collection is idle */\n isIdle: Signal<boolean>\n /** A signal indicating whether the collection has an error */\n isError: Signal<boolean>\n /** A signal indicating whether the collection has been cleaned up */\n isCleanedUp: Signal<boolean>\n}\n\ntype InferConditionalResultType<TContext extends Context> =\n TContext extends SingleResult\n ? InferResultType<TContext> | []\n : InferResultType<TContext>\n\nexport type InjectConditionalLiveQueryResult<TContext extends Context> = Omit<\n InjectLiveQueryResult<TContext>,\n `data`\n> & {\n data: Signal<InferConditionalResultType<TContext>>\n}\n\nexport interface InjectLiveQueryResultWithCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<Array<TResult>>\n collection: Signal<Collection<TResult, TKey, TUtils> | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport interface InjectLiveQueryResultWithSingleResultCollection<\n TResult extends object = any,\n TKey extends string | number = string | number,\n TUtils extends Record<string, any> = {},\n> {\n state: Signal<Map<TKey, TResult>>\n data: Signal<TResult | undefined>\n collection: Signal<(Collection<TResult, TKey, TUtils> & SingleResult) | null>\n status: Signal<CollectionStatus | `disabled`>\n isLoading: Signal<boolean>\n isReady: Signal<boolean>\n persistedStatus: Signal<LiveQueryPersistedStatus>\n isPersistedReady: Signal<boolean>\n persistedError: Signal<unknown | undefined>\n isIdle: Signal<boolean>\n isError: Signal<boolean>\n isCleanedUp: Signal<boolean>\n}\n\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext>\n}): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<\n TContext extends Context,\n TParams extends any,\n>(options: {\n params: () => TParams\n query: (args: {\n params: TParams\n q: InitialQueryBuilder\n }) => QueryBuilder<TContext> | undefined | null\n}): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>,\n): InjectLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n queryFn: (\n q: InitialQueryBuilder,\n ) => QueryBuilder<TContext> | undefined | null,\n): InjectConditionalLiveQueryResult<TContext>\nexport function injectLiveQuery<TContext extends Context>(\n config: LiveQueryCollectionConfig<TContext>,\n): InjectLiveQueryResult<TContext>\n// Pre-created collection without singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & NonSingleResult,\n): InjectLiveQueryResultWithCollection<TResult, TKey, TUtils>\n// Pre-created collection with singleResult\nexport function injectLiveQuery<\n TResult extends object,\n TKey extends string | number,\n TUtils extends Record<string, any>,\n>(\n liveQueryCollection: Collection<TResult, TKey, TUtils> & SingleResult,\n): InjectLiveQueryResultWithSingleResultCollection<TResult, TKey, TUtils>\nexport function injectLiveQuery(opts: any) {\n assertInInjectionContext(injectLiveQuery)\n const destroyRef = inject(DestroyRef)\n\n const collection = computed(() => {\n // Check if it's an existing collection\n if (isCollection(opts)) {\n return opts\n }\n\n if (typeof opts === `function`) {\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = opts(queryBuilder)\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return resolveLiveQueryValue(result, { gcTime: 0 })\n }\n\n // Check if it's reactive query options\n const isReactiveQueryOptions =\n opts &&\n typeof opts === `object` &&\n typeof opts.query === `function` &&\n typeof opts.params === `function`\n\n if (isReactiveQueryOptions) {\n const { params, query } = opts\n const currentParams = params()\n\n // Check if query function returns null/undefined (disabled query)\n const queryBuilder = new BaseQueryBuilder() as InitialQueryBuilder\n const result = query({ params: currentParams, q: queryBuilder })\n\n if (result === undefined || result === null) {\n // Disabled query - return null\n return null\n }\n\n return resolveLiveQueryValue(result, { gcTime: 0 })\n }\n\n // Handle LiveQueryCollectionConfig objects. Default startSync/gcTime to\n // match the query-fn and reactive-options paths, but let an explicit value\n // in the config win — otherwise a bare `{ query }` never syncs.\n if (opts && typeof opts === `object` && typeof opts.query === `function`) {\n return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts })\n }\n\n throw new Error(`Invalid options provided to injectLiveQuery`)\n })\n\n const state = signal(new Map<string | number, any>())\n const internalData = signal<Array<any>>([])\n const statusValue = signal<CollectionStatus | `disabled`>(`idle`)\n const status = computed(() => {\n const value = statusValue()\n return value === `idle` && !collection() ? `disabled` : value\n })\n const persistedStatus = signal<LiveQueryPersistedStatus>(`unavailable`)\n const persistedError = signal<unknown>(undefined)\n\n // Returns single item for singleResult collections, array otherwise\n const data = computed(() => {\n const currentCollection = collection()\n if (!currentCollection) {\n return internalData()\n }\n return isSingleResultCollection(currentCollection)\n ? internalData()[0]\n : internalData()\n })\n\n const syncDataFromCollection = (\n currentCollection: Collection<any, any, any>,\n observer: LiveQueryObserver<any, any>,\n ) => {\n const newState = new Map(currentCollection.entries())\n const newData = Array.from(newState.values())\n\n state.set(newState)\n internalData.set(newData)\n const snapshot = observer.getSnapshot()\n statusValue.set(snapshot.status)\n persistedStatus.set(snapshot.persistedStatus)\n persistedError.set(snapshot.persistedError)\n }\n\n let unsub: (() => void) | null = null\n const cleanup = () => {\n unsub?.()\n unsub = null\n }\n\n effect((onCleanup) => {\n const currentCollection = collection()\n\n // Handle null collection (disabled query)\n if (!currentCollection) {\n statusValue.set(`disabled` as const)\n persistedStatus.set(`unavailable`)\n persistedError.set(undefined)\n state.set(new Map())\n internalData.set([])\n cleanup()\n return\n }\n\n cleanup()\n\n // The shared observer owns sync start, subscription, the ready-race, and\n // status transitions; Angular re-reads the whole collection on each notify\n // (wholesale) into its signals.\n // Angular re-reads the collection on notify; wholesale mode preserves its\n // pre-observer loading policy (no initial-state snapshot request).\n const observer = createLiveQueryObserver(currentCollection, {\n mode: `wholesale`,\n })\n\n const unsubscribe = observer.subscribe(() => {\n syncDataFromCollection(currentCollection, observer)\n })\n // Wholesale attach suppresses listener calls raised by synchronous sync\n // startup. Read once after subscribe returns to capture that final state.\n syncDataFromCollection(currentCollection, observer)\n unsub = () => {\n unsubscribe()\n observer.dispose()\n }\n\n onCleanup(cleanup)\n })\n\n destroyRef.onDestroy(cleanup)\n\n return {\n state,\n data,\n // Loosely typed so the impl return stays compatible with every overload\n // (the shared `isCollection` guard narrows the computed to `Collection | null`).\n collection: computed(() =>\n getPublicCollection(collection()),\n ) as Signal<any>,\n status,\n isLoading: computed(() => status() === `loading`),\n isReady: computed(() => status() === `ready` || status() === `disabled`),\n persistedStatus,\n isPersistedReady: computed(() => persistedStatus() === `ready`),\n persistedError,\n isIdle: computed(() => status() === `idle`),\n isError: computed(() => status() === `error`),\n isCleanedUp: computed(() => status() === `cleaned-up`),\n }\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/angular-db",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Angular integration for @tanstack/db",
|
|
5
5
|
"author": "Ethan McDaniel",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"skills"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@tanstack/db": "0.11.
|
|
43
|
+
"@tanstack/db": "0.11.3"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@angular/core": ">=16.0.0",
|
package/src/index.ts
CHANGED
|
@@ -10,8 +10,10 @@ import {
|
|
|
10
10
|
BaseQueryBuilder,
|
|
11
11
|
createLiveQueryCollection,
|
|
12
12
|
createLiveQueryObserver,
|
|
13
|
+
getPublicCollection,
|
|
13
14
|
isCollection,
|
|
14
15
|
isSingleResultCollection,
|
|
16
|
+
resolveLiveQueryValue,
|
|
15
17
|
} from '@tanstack/db'
|
|
16
18
|
import type {
|
|
17
19
|
Collection,
|
|
@@ -180,11 +182,7 @@ export function injectLiveQuery(opts: any) {
|
|
|
180
182
|
return null
|
|
181
183
|
}
|
|
182
184
|
|
|
183
|
-
return
|
|
184
|
-
query: opts,
|
|
185
|
-
startSync: true,
|
|
186
|
-
gcTime: 0,
|
|
187
|
-
})
|
|
185
|
+
return resolveLiveQueryValue(result, { gcTime: 0 })
|
|
188
186
|
}
|
|
189
187
|
|
|
190
188
|
// Check if it's reactive query options
|
|
@@ -207,11 +205,7 @@ export function injectLiveQuery(opts: any) {
|
|
|
207
205
|
return null
|
|
208
206
|
}
|
|
209
207
|
|
|
210
|
-
return
|
|
211
|
-
query: () => result,
|
|
212
|
-
startSync: true,
|
|
213
|
-
gcTime: 0,
|
|
214
|
-
})
|
|
208
|
+
return resolveLiveQueryValue(result, { gcTime: 0 })
|
|
215
209
|
}
|
|
216
210
|
|
|
217
211
|
// Handle LiveQueryCollectionConfig objects. Default startSync/gcTime to
|
|
@@ -250,7 +244,7 @@ export function injectLiveQuery(opts: any) {
|
|
|
250
244
|
observer: LiveQueryObserver<any, any>,
|
|
251
245
|
) => {
|
|
252
246
|
const newState = new Map(currentCollection.entries())
|
|
253
|
-
const newData = Array.from(
|
|
247
|
+
const newData = Array.from(newState.values())
|
|
254
248
|
|
|
255
249
|
state.set(newState)
|
|
256
250
|
internalData.set(newData)
|
|
@@ -312,7 +306,9 @@ export function injectLiveQuery(opts: any) {
|
|
|
312
306
|
data,
|
|
313
307
|
// Loosely typed so the impl return stays compatible with every overload
|
|
314
308
|
// (the shared `isCollection` guard narrows the computed to `Collection | null`).
|
|
315
|
-
collection:
|
|
309
|
+
collection: computed(() =>
|
|
310
|
+
getPublicCollection(collection()),
|
|
311
|
+
) as Signal<any>,
|
|
316
312
|
status,
|
|
317
313
|
isLoading: computed(() => status() === `loading`),
|
|
318
314
|
isReady: computed(() => status() === `ready` || status() === `disabled`),
|