UNPKG

@tanstack/vue-db

Version:

Vue integration for @tanstack/db

162 lines (159 loc) 5.37 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const vue = require("vue"); const db = require("@tanstack/db"); function useLiveQuery(configOrQueryOrCollection, deps = []) { const collection = vue.computed(() => { let unwrappedParam = configOrQueryOrCollection; if (typeof configOrQueryOrCollection !== `function`) { try { const potentiallyUnwrapped = vue.toValue(configOrQueryOrCollection); if (potentiallyUnwrapped !== configOrQueryOrCollection) { unwrappedParam = potentiallyUnwrapped; } } catch { unwrappedParam = configOrQueryOrCollection; } } const isCollection = unwrappedParam && typeof unwrappedParam === `object` && typeof unwrappedParam.subscribeChanges === `function` && typeof unwrappedParam.startSyncImmediate === `function` && typeof unwrappedParam.id === `string`; if (isCollection) { const syncMode = unwrappedParam.config?.syncMode; if (syncMode === `on-demand`) { console.warn( `[useLiveQuery] Warning: Passing a collection with syncMode "on-demand" directly to useLiveQuery will not load any data. In on-demand mode, data is only loaded when queries with predicates request it. Instead, use a query builder function: const { data } = useLiveQuery((q) => q.from({ c: myCollection }).select(({ c }) => c)) Or switch to syncMode "eager" if you want all data to sync automatically.` ); } if (unwrappedParam.status === `idle`) { unwrappedParam.startSyncImmediate(); } return unwrappedParam; } deps.forEach((dep) => vue.toValue(dep)); if (typeof unwrappedParam === `function`) { const wrappedQuery = (q) => { const result = unwrappedParam(q); if (result === void 0 || result === null) { throw new Error(`__DISABLED_QUERY__`); } return result; }; try { return db.createLiveQueryCollection({ query: wrappedQuery, startSync: true }); } catch (error) { if (error instanceof Error && error.message === `__DISABLED_QUERY__`) { return null; } throw error; } } else { return db.createLiveQueryCollection({ ...unwrappedParam, startSync: true }); } }); const state = vue.reactive(/* @__PURE__ */ new Map()); const internalData = vue.reactive([]); const data = vue.computed(() => { const currentCollection = collection.value; if (!currentCollection) { return internalData; } const config = currentCollection.config; return config.singleResult ? internalData[0] : internalData; }); const status = vue.ref( collection.value ? collection.value.status : `disabled` ); const syncDataFromCollection = (currentCollection) => { internalData.length = 0; internalData.push(...Array.from(currentCollection.values())); }; let currentUnsubscribe = null; vue.watchEffect((onInvalidate) => { const currentCollection = collection.value; if (!currentCollection) { status.value = `disabled`; state.clear(); internalData.length = 0; if (currentUnsubscribe) { currentUnsubscribe(); currentUnsubscribe = null; } return; } status.value = currentCollection.status; if (currentUnsubscribe) { currentUnsubscribe(); } state.clear(); for (const [key, value] of currentCollection.entries()) { state.set(key, value); } syncDataFromCollection(currentCollection); currentCollection.onFirstReady(() => { vue.nextTick(() => { status.value = currentCollection.status; }); }); const subscription = currentCollection.subscribeChanges( (changes) => { 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); status.value = currentCollection.status; }, { includeInitialState: true } ); currentUnsubscribe = subscription.unsubscribe.bind(subscription); if (currentCollection.status === `idle`) { currentCollection.preload().catch(console.error); } onInvalidate(() => { if (currentUnsubscribe) { currentUnsubscribe(); currentUnsubscribe = null; } }); }); const instance = vue.getCurrentInstance(); if (instance) { vue.onUnmounted(() => { if (currentUnsubscribe) { currentUnsubscribe(); } }); } return { state: vue.computed(() => state), data, collection: vue.computed(() => collection.value), status: vue.computed(() => status.value), isLoading: vue.computed(() => status.value === `loading`), isReady: vue.computed( () => status.value === `ready` || status.value === `disabled` ), isIdle: vue.computed(() => status.value === `idle`), isError: vue.computed(() => status.value === `error`), isCleanedUp: vue.computed(() => status.value === `cleaned-up`) }; } exports.useLiveQuery = useLiveQuery; //# sourceMappingURL=useLiveQuery.cjs.map