@tanstack/query-core
Version:
The framework agnostic core that powers TanStack Query
1 lines • 5.91 kB
Source Map (JSON)
{"version":3,"file":"notifyManager.cjs","names":["systemSetTimeoutZero"],"sources":["../../src/notifyManager.ts"],"sourcesContent":["// TYPES\n\nimport { systemSetTimeoutZero } from './timeoutManager'\n\ntype NotifyCallback = () => void\n\ntype NotifyFunction = (callback: () => void) => void\n\ntype BatchNotifyFunction = (callback: () => void) => void\n\ntype BatchCallsCallback<T extends Array<unknown>> = (...args: T) => void\n\ntype ScheduleFunction = (callback: () => void) => void\n\n/**\n * Default scheduling function used by the notify manager.\n * Schedules the callback with the system's `setTimeout(callback, 0)`.\n */\nexport const defaultScheduler: ScheduleFunction = systemSetTimeoutZero\n\n/**\n * Creates a notify manager, which schedules and batches notifications to subscribers. Query uses a\n * single instance of it, exported as {@link notifyManager}.\n * @returns A new notify manager.\n */\nexport function createNotifyManager() {\n let queue: Array<NotifyCallback> = []\n let transactions = 0\n let notifyFn: NotifyFunction = (callback) => {\n callback()\n }\n let batchNotifyFn: BatchNotifyFunction = (callback: () => void) => {\n callback()\n }\n let scheduleFn = defaultScheduler\n\n const schedule = (callback: NotifyCallback): void => {\n if (transactions) {\n queue.push(callback)\n } else {\n scheduleFn(() => {\n notifyFn(callback)\n })\n }\n }\n const flush = (): void => {\n const originalQueue = queue\n queue = []\n if (originalQueue.length) {\n scheduleFn(() => {\n batchNotifyFn(() => {\n originalQueue.forEach((callback) => {\n notifyFn(callback)\n })\n })\n })\n }\n }\n\n return {\n /**\n * Batches all updates scheduled inside the passed callback.\n * This is mainly used internally to optimize query client updating.\n * Batches can be nested; the queue is only flushed once the outermost `batch` call finishes.\n * The return value of `callback` is passed through.\n * @param callback - The function to run in the batch.\n * @returns The return value of `callback`.\n */\n batch: <T>(callback: () => T): T => {\n let result\n transactions++\n try {\n result = callback()\n } finally {\n transactions--\n if (!transactions) {\n flush()\n }\n }\n return result\n },\n /**\n * All calls to the wrapped function will be batched.\n * @param callback - The function to wrap.\n * @returns A function that schedules a call to `callback` with the given arguments.\n */\n batchCalls: <T extends Array<unknown>>(\n callback: BatchCallsCallback<T>,\n ): BatchCallsCallback<T> => {\n return (...args) => {\n schedule(() => {\n callback(...args)\n })\n }\n },\n /**\n * Schedules a function to be run on the next batch.\n * By default, the batch is run with a `setTimeout`, but this can be configured via `setScheduler`.\n */\n schedule,\n /**\n * Use this method to set a custom notify function.\n * This can be used to for example wrap notifications with `React.act` while running tests.\n * @param fn - Receives each notification callback and must call it.\n */\n setNotifyFunction: (fn: NotifyFunction) => {\n notifyFn = fn\n },\n /**\n * Use this method to set a custom function to batch notifications together into a single tick.\n * Framework adapters use this to plug in their own batching primitive, so that a single query\n * update only triggers one re-render instead of one per subscriber.\n * @param fn - Receives a function that runs a batch of notifications and must call it.\n * @example\n * ```ts\n * import { notifyManager } from '@tanstack/query-core'\n * import { batch } from 'solid-js'\n *\n * notifyManager.setBatchNotifyFunction(batch)\n * ```\n */\n setBatchNotifyFunction: (fn: BatchNotifyFunction) => {\n batchNotifyFn = fn\n },\n /**\n * Configures a custom callback that schedules when the next batch runs.\n * The default behavior is `setTimeout(callback, 0)`.\n * @param fn - Receives a callback that runs the next batch, and schedules it.\n * @example\n * ```ts\n * import { notifyManager } from '@tanstack/query-core'\n *\n * // Schedule batches in the next microtask\n * notifyManager.setScheduler(queueMicrotask)\n *\n * // Schedule batches before the next frame is rendered\n * notifyManager.setScheduler(requestAnimationFrame)\n *\n * // Schedule batches some time in the future\n * notifyManager.setScheduler((cb) => setTimeout(cb, 10))\n * ```\n */\n setScheduler: (fn: ScheduleFunction) => {\n scheduleFn = fn\n },\n } as const\n}\n\n// SINGLETON\n\n/**\n * Handles scheduling and batching callbacks in TanStack Query.\n */\nexport const notifyManager = createNotifyManager()\n"],"mappings":";;;;;;AAkBA,MAAa,iDAAqCA,CAAAA,CAAAA;;;;;;AAOlD,SAAgB,sBAAsB;CACpC,IAAI,QAA+B,CAAC;CACpC,IAAI,eAAe;CACnB,IAAI,YAA4B,aAAa;EAC3C,SAAS;CACX;CACA,IAAI,iBAAsC,aAAyB;EACjE,SAAS;CACX;CACA,IAAI,aAAa;CAEjB,MAAM,YAAY,aAAmC;EACnD,IAAI,cACF,MAAM,KAAK,QAAQ;OAEnB,iBAAiB;GACf,SAAS,QAAQ;EACnB,CAAC;CAEL;CACA,MAAM,cAAoB;EACxB,MAAM,gBAAgB;EACtB,QAAQ,CAAC;EACT,IAAI,cAAc,QAChB,iBAAiB;GACf,oBAAoB;IAClB,cAAc,SAAS,aAAa;KAClC,SAAS,QAAQ;IACnB,CAAC;GACH,CAAC;EACH,CAAC;CAEL;CAEA,OAAO;;;;;;;;;EASL,QAAW,aAAyB;GAClC,IAAI;GACJ;GACA,IAAI;IACF,SAAS,SAAS;GACpB,UAAU;IACR;IACA,IAAI,CAAC,cACH,MAAM;GAEV;GACA,OAAO;EACT;;;;;;EAMA,aACE,aAC0B;GAC1B,QAAQ,GAAG,SAAS;IAClB,eAAe;KACb,SAAS,GAAG,IAAI;IAClB,CAAC;GACH;EACF;;;;;EAKA;;;;;;EAMA,oBAAoB,OAAuB;GACzC,WAAW;EACb;;;;;;;;;;;;;;EAcA,yBAAyB,OAA4B;GACnD,gBAAgB;EAClB;;;;;;;;;;;;;;;;;;;EAmBA,eAAe,OAAyB;GACtC,aAAa;EACf;CACF;AACF;;;;AAOA,MAAa,gBAAgB,oBAAoB"}