UNPKG

@tanstack/react-db

Version:

React integration for @tanstack/db

1 lines • 3.53 kB
{"version":3,"file":"useLiveQueryEffect.cjs","sources":["../../src/useLiveQueryEffect.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { createEffect, prepareLiveQueryValue } from '@tanstack/db'\nimport { useOptionalDbClient } from './DbProvider'\nimport { getPreparedSources } from './source-id-bindings'\nimport type { EffectConfig } from '@tanstack/db'\n\n/**\n * React hook for creating a reactive effect that fires handlers when rows\n * enter, exit, or update within a query result.\n *\n * The effect is created on mount and disposed on unmount. If `deps` change,\n * the previous effect is disposed and a new one is created.\n *\n * @example\n * ```tsx\n * function ChatComponent() {\n * useLiveQueryEffect(\n * {\n * query: (q) => q.from({ msg: messages }).where(({ msg }) => eq(msg.role, 'user')),\n * skipInitial: true,\n * onEnter: async (event) => {\n * await generateResponse(event.value)\n * },\n * },\n * []\n * )\n *\n * return <div>...</div>\n * }\n * ```\n */\nexport function useLiveQueryEffect<\n TRow extends object = Record<string, unknown>,\n TKey extends string | number = string | number,\n>(config: EffectConfig<TRow, TKey>, deps: React.DependencyList = []): void {\n const client = useOptionalDbClient()\n const configRef = useRef<EffectConfig<TRow, TKey>>(config)\n configRef.current = config\n\n useEffect(() => {\n const query = prepareLiveQueryValue(config.query, client)\n if (!client) getPreparedSources(query, client, `useLiveQueryEffect`)\n const effect = createEffect<TRow, TKey>({\n id: config.id,\n query: query as EffectConfig<TRow, TKey>[`query`],\n skipInitial: config.skipInitial,\n onEnter: (event, ctx) => configRef.current.onEnter?.(event, ctx),\n onUpdate: (event, ctx) => configRef.current.onUpdate?.(event, ctx),\n onExit: (event, ctx) => configRef.current.onExit?.(event, ctx),\n onBatch: (events, ctx) => configRef.current.onBatch?.(events, ctx),\n onError: config.onError\n ? (error, event) => configRef.current.onError?.(error, event)\n : undefined,\n onSourceError: config.onSourceError\n ? (error) => configRef.current.onSourceError?.(error)\n : undefined,\n })\n\n return () => {\n // React cannot await cleanup. Report a failed source release.\n void effect.dispose().catch((error) => {\n console.error(`[useLiveQueryEffect] failed to dispose effect:`, error)\n })\n }\n }, [...deps, client])\n}\n"],"names":["useOptionalDbClient","useRef","useEffect","prepareLiveQueryValue","getPreparedSources","createEffect"],"mappings":";;;;;;AA+BO,SAAS,mBAGd,QAAkC,OAA6B,IAAU;AACzE,QAAM,SAASA,WAAAA,oBAAA;AACf,QAAM,YAAYC,MAAAA,OAAiC,MAAM;AACzD,YAAU,UAAU;AAEpBC,QAAAA,UAAU,MAAM;AACd,UAAM,QAAQC,GAAAA,sBAAsB,OAAO,OAAO,MAAM;AACxD,QAAI,CAAC,OAAQC,kBAAAA,mBAAmB,OAAO,QAAQ,oBAAoB;AACnE,UAAM,SAASC,GAAAA,aAAyB;AAAA,MACtC,IAAI,OAAO;AAAA,MACX;AAAA,MACA,aAAa,OAAO;AAAA,MACpB,SAAS,CAAC,OAAO,QAAQ,UAAU,QAAQ,UAAU,OAAO,GAAG;AAAA,MAC/D,UAAU,CAAC,OAAO,QAAQ,UAAU,QAAQ,WAAW,OAAO,GAAG;AAAA,MACjE,QAAQ,CAAC,OAAO,QAAQ,UAAU,QAAQ,SAAS,OAAO,GAAG;AAAA,MAC7D,SAAS,CAAC,QAAQ,QAAQ,UAAU,QAAQ,UAAU,QAAQ,GAAG;AAAA,MACjE,SAAS,OAAO,UACZ,CAAC,OAAO,UAAU,UAAU,QAAQ,UAAU,OAAO,KAAK,IAC1D;AAAA,MACJ,eAAe,OAAO,gBAClB,CAAC,UAAU,UAAU,QAAQ,gBAAgB,KAAK,IAClD;AAAA,IAAA,CACL;AAED,WAAO,MAAM;AAEX,WAAK,OAAO,QAAA,EAAU,MAAM,CAAC,UAAU;AACrC,gBAAQ,MAAM,kDAAkD,KAAK;AAAA,MACvE,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,GAAG,MAAM,MAAM,CAAC;AACtB;;"}