UNPKG

@tanstack/solid-db

Version:

Solid integration for @tanstack/db

178 lines (177 loc) 4.52 kB
import { createMemo, createSignal, createResource, batch, createEffect, onCleanup } from "solid-js"; import { ReactiveMap } from "@solid-primitives/map"; import { BaseQueryBuilder, createLiveQueryCollection, CollectionImpl } from "@tanstack/db"; import { createStore, reconcile } from "solid-js/store"; function useLiveQuery(configOrQueryOrCollection) { const collection = createMemo( () => { if (configOrQueryOrCollection.length === 1) { const queryBuilder = new BaseQueryBuilder(); const result = configOrQueryOrCollection(queryBuilder); if (result === void 0 || result === null) { return null; } return createLiveQueryCollection({ query: configOrQueryOrCollection, startSync: true }); } const innerCollection = configOrQueryOrCollection(); if (innerCollection === void 0 || innerCollection === null) { return null; } if (innerCollection instanceof CollectionImpl) { innerCollection.startSyncImmediate(); return innerCollection; } return createLiveQueryCollection({ ...innerCollection, startSync: true }); }, void 0, { name: `TanstackDBCollectionMemo` } ); const state = new ReactiveMap(); const [data, setData] = createStore([], { name: `TanstackDBData` }); const [status, setStatus] = createSignal( collection() ? collection().status : `disabled`, { name: `TanstackDBStatus` } ); const syncDataFromCollection = (currentCollection) => { setData( (prev) => reconcile(Array.from(currentCollection.values()))(prev).filter(Boolean) ); }; const [getDataResource] = createResource( () => ({ currentCollection: collection() }), async ({ currentCollection }) => { if (!currentCollection) { return []; } setStatus(currentCollection.status); try { await currentCollection.toArrayWhenReady(); } catch (error) { setStatus(`error`); throw error; } batch(() => { state.clear(); for (const [key, value] of currentCollection.entries()) { state.set(key, value); } syncDataFromCollection(currentCollection); setStatus(currentCollection.status); }); return data; }, { name: `TanstackDBData`, deferStream: false, initialValue: data } ); createEffect(() => { const currentCollection = collection(); if (!currentCollection) { setStatus(`disabled`); state.clear(); setData([]); return; } const subscription = currentCollection.subscribeChanges( (changes) => { batch(() => { for (const change of changes) { switch (change.type) { case `insert`: case `update`: state.set(change.key, change.value); break; case `delete`: state.delete(change.key); break; } } syncDataFromCollection(currentCollection); setStatus(currentCollection.status); }); }, { // Include initial state to ensure immediate population for pre-created collections includeInitialState: true } ); onCleanup(() => { subscription.unsubscribe(); }); }); function getData() { const currentCollection = collection(); if (currentCollection) { const config = currentCollection.config; if (config.singleResult) { getDataResource(); return data[0]; } } return getDataResource(); } Object.defineProperties(getData, { data: { get() { return getData(); } }, status: { get() { return status(); } }, collection: { get() { return collection(); } }, state: { get() { return state; } }, isLoading: { get() { return status() === `loading`; } }, isReady: { get() { return status() === `ready` || status() === `disabled`; } }, isIdle: { get() { return status() === `idle`; } }, isError: { get() { return status() === `error`; } }, isCleanedUp: { get() { return status() === `cleaned-up`; } } }); return getData; } export { useLiveQuery }; //# sourceMappingURL=useLiveQuery.js.map