UNPKG

@pinia/colada-plugin-auto-refetch

Version:

Automatically refetch queries when they become stale in Pinia Colada

1 lines 5.42 kB
{"version":3,"file":"index.mjs","names":[],"sources":["../src/auto-refetch.ts"],"sourcesContent":["/**\n * Pinia Colada Auto Refetch plugin.\n *\n * Automatically refreshes queries when they become stale.\n *\n * @module @pinia/colada-plugin-auto-refetch\n */\n\nimport {\n _toValueWithArgs,\n type PiniaColadaPlugin,\n type UseQueryEntry,\n type UseQueryOptions,\n type DataState,\n type UseQueryOptionsWithDefaults,\n} from '@pinia/colada'\nimport { toValue } from 'vue'\n\n/**\n * Options for the auto-refetch plugin.\n */\nexport interface PiniaColadaAutoRefetchOptions<\n TData = unknown,\n TError = unknown,\n // TODO: should be undefined?\n TDataInitial = unknown,\n> {\n /**\n * Whether to enable auto refresh by default.\n * @default false\n */\n autoRefetch?:\n | boolean\n | number\n // FIXME: implement without the extended type Param\n | (<T extends DataState<TData, TError, TDataInitial>>(state: T) => boolean | number)\n // | ((state: DataState<TData, TError, TDataInitial>) => boolean | number)\n}\n\n/**\n * To store timeouts in the entry extensions.\n *\n * @internal\n */\nconst REFETCH_TIMEOUT_KEY = Symbol()\nexport { REFETCH_TIMEOUT_KEY as _REFETCH_TIMEOUT_KEY }\n\n/**\n * Plugin that automatically refreshes queries when they become stale\n */\nexport function PiniaColadaAutoRefetch(\n options: PiniaColadaAutoRefetchOptions = {},\n): PiniaColadaPlugin {\n const { autoRefetch = false } = options\n\n return ({ queryCache }) => {\n // Skip setting auto-refetch on the server\n if (typeof document === 'undefined') return\n\n function scheduleRefetch(\n // TODO: should be undefined\n entry: UseQueryEntry<unknown, unknown, unknown>,\n delayMs: number,\n ) {\n if (!entry.active) return\n\n // Always clear existing timeout first\n clearTimeout(entry.ext[REFETCH_TIMEOUT_KEY])\n\n // Schedule next refetch\n const timeout = setTimeout(() => {\n if (entry?.active && entry.options && toValue(entry.options.enabled)) {\n queryCache.fetch(entry).catch(console.error)\n }\n }, delayMs)\n\n entry.ext[REFETCH_TIMEOUT_KEY] = timeout\n }\n\n queryCache.$onAction(({ name, args, after }) => {\n /**\n * Whether to schedule a refetch for the given entry and determine the interval\n * Returns { shouldSchedule: boolean, interval?: number }\n */\n function shouldScheduleRefetch({\n state,\n options,\n }: UseQueryEntry<unknown, unknown, unknown>): number | false {\n const autoRefetchValue =\n !!options && _toValueWithArgs(options.autoRefetch ?? autoRefetch, state.value)\n return (\n !!options &&\n toValue(options.enabled) &&\n (autoRefetchValue === true ? options.staleTime! : autoRefetchValue)\n )\n }\n\n // Trigger a fetch on creation to enable auto-refetch on initial load\n if (name === 'ensure') {\n after((entry) => {\n // after ensure, options are always defined\n const interval = shouldScheduleRefetch(entry)\n if (interval) {\n scheduleRefetch(entry, interval)\n }\n })\n }\n\n // Set up auto-refetch on every fetch\n if (name === 'fetch') {\n const [entry] = args\n\n // Clear any existing timeout before scheduling a new one\n clearTimeout(entry.ext[REFETCH_TIMEOUT_KEY])\n\n after(async () => {\n if (!entry.options) return\n const interval = shouldScheduleRefetch(entry)\n if (interval) {\n scheduleRefetch(entry, interval)\n }\n })\n }\n\n // Clean up timeouts when entry is removed\n if (name === 'remove') {\n const [entry] = args\n clearTimeout(entry.ext[REFETCH_TIMEOUT_KEY])\n }\n })\n }\n}\n\n// Add types for the new option\ndeclare module '@pinia/colada' {\n interface UseQueryOptions<TData, TError, TDataInitial> extends PiniaColadaAutoRefetchOptions<\n TData,\n TError,\n TDataInitial\n > {}\n\n interface UseQueryOptionsGlobal extends PiniaColadaAutoRefetchOptions {}\n\n // eslint-disable-next-line unused-imports/no-unused-vars\n interface UseQueryEntryExtensions<TData, TError, TDataInitial> {\n /**\n * Used to store the timeout for the auto-refetch plugin.\n * @internal\n */\n [REFETCH_TIMEOUT_KEY]?: ReturnType<typeof setTimeout>\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AA4CA,MAAM,sBAAsB,QAAQ;;;;AAMpC,SAAgB,uBACd,UAAyC,EAAE,EACxB;CACnB,MAAM,EAAE,cAAc,UAAU;AAEhC,SAAQ,EAAE,iBAAiB;AAEzB,MAAI,OAAO,aAAa,YAAa;EAErC,SAAS,gBAEP,OACA,SACA;AACA,OAAI,CAAC,MAAM,OAAQ;AAGnB,gBAAa,MAAM,IAAI,qBAAqB;GAG5C,MAAM,UAAU,iBAAiB;AAC/B,QAAI,OAAO,UAAU,MAAM,WAAW,QAAQ,MAAM,QAAQ,QAAQ,CAClE,YAAW,MAAM,MAAM,CAAC,MAAM,QAAQ,MAAM;MAE7C,QAAQ;AAEX,SAAM,IAAI,uBAAuB;;AAGnC,aAAW,WAAW,EAAE,MAAM,MAAM,YAAY;;;;;GAK9C,SAAS,sBAAsB,EAC7B,OACA,WAC2D;IAC3D,MAAM,mBACJ,CAAC,CAAC,WAAW,iBAAiB,QAAQ,eAAe,aAAa,MAAM,MAAM;AAChF,WACE,CAAC,CAAC,WACF,QAAQ,QAAQ,QAAQ,KACvB,qBAAqB,OAAO,QAAQ,YAAa;;AAKtD,OAAI,SAAS,SACX,QAAO,UAAU;IAEf,MAAM,WAAW,sBAAsB,MAAM;AAC7C,QAAI,SACF,iBAAgB,OAAO,SAAS;KAElC;AAIJ,OAAI,SAAS,SAAS;IACpB,MAAM,CAAC,SAAS;AAGhB,iBAAa,MAAM,IAAI,qBAAqB;AAE5C,UAAM,YAAY;AAChB,SAAI,CAAC,MAAM,QAAS;KACpB,MAAM,WAAW,sBAAsB,MAAM;AAC7C,SAAI,SACF,iBAAgB,OAAO,SAAS;MAElC;;AAIJ,OAAI,SAAS,UAAU;IACrB,MAAM,CAAC,SAAS;AAChB,iBAAa,MAAM,IAAI,qBAAqB;;IAE9C"}