UNPKG

@tanstack/angular-db

Version:

Angular integration for @tanstack/db

109 lines (108 loc) 3.63 kB
import { assertInInjectionContext, inject, DestroyRef, computed, signal, effect } from "@angular/core"; import { isCollection, BaseQueryBuilder, createLiveQueryCollection, isSingleResultCollection, createLiveQueryObserver } from "@tanstack/db"; export * from "@tanstack/db"; function injectLiveQuery(opts) { assertInInjectionContext(injectLiveQuery); const destroyRef = inject(DestroyRef); const collection = computed(() => { if (isCollection(opts)) { return opts; } if (typeof opts === `function`) { const queryBuilder = new BaseQueryBuilder(); const result = opts(queryBuilder); if (result === void 0 || result === null) { return null; } return createLiveQueryCollection({ query: opts, startSync: true, gcTime: 0 }); } const isReactiveQueryOptions = opts && typeof opts === `object` && typeof opts.query === `function` && typeof opts.params === `function`; if (isReactiveQueryOptions) { const { params, query } = opts; const currentParams = params(); const queryBuilder = new BaseQueryBuilder(); const result = query({ params: currentParams, q: queryBuilder }); if (result === void 0 || result === null) { return null; } return createLiveQueryCollection({ query: () => result, startSync: true, gcTime: 0 }); } if (opts && typeof opts === `object` && typeof opts.query === `function`) { return createLiveQueryCollection({ startSync: true, gcTime: 0, ...opts }); } throw new Error(`Invalid options provided to injectLiveQuery`); }); const state = signal(/* @__PURE__ */ new Map()); const internalData = signal([]); const status = signal( collection() ? `idle` : `disabled` ); const data = computed(() => { const currentCollection = collection(); if (!currentCollection) { return internalData(); } return isSingleResultCollection(currentCollection) ? internalData()[0] : internalData(); }); const syncDataFromCollection = (currentCollection) => { const newState = new Map(currentCollection.entries()); const newData = Array.from(currentCollection.values()); state.set(newState); internalData.set(newData); status.set(currentCollection.status); }; let unsub = null; const cleanup = () => { unsub?.(); unsub = null; }; effect((onCleanup) => { const currentCollection = collection(); if (!currentCollection) { status.set(`disabled`); state.set(/* @__PURE__ */ new Map()); internalData.set([]); cleanup(); return; } cleanup(); const observer = createLiveQueryObserver(currentCollection, { mode: `wholesale` }); const unsubscribe = observer.subscribe(() => { syncDataFromCollection(currentCollection); }); syncDataFromCollection(currentCollection); unsub = () => { unsubscribe(); observer.dispose(); }; onCleanup(cleanup); }); destroyRef.onDestroy(cleanup); return { state, data, // Loosely typed so the impl return stays compatible with every overload // (the shared `isCollection` guard narrows the computed to `Collection | null`). collection, status, isLoading: computed(() => status() === `loading`), isReady: computed(() => status() === `ready` || status() === `disabled`), isIdle: computed(() => status() === `idle`), isError: computed(() => status() === `error`), isCleanedUp: computed(() => status() === `cleaned-up`) }; } export { injectLiveQuery }; //# sourceMappingURL=index.js.map