@tanstack/pacer-lite 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/cjs/index.cjs +18 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/cjs/index.d.cts +5 -0
  6. package/dist/cjs/lite-batcher.cjs +92 -0
  7. package/dist/cjs/lite-batcher.cjs.map +1 -0
  8. package/dist/cjs/lite-batcher.d.cts +180 -0
  9. package/dist/cjs/lite-debouncer.cjs +59 -0
  10. package/dist/cjs/lite-debouncer.cjs.map +1 -0
  11. package/dist/cjs/lite-debouncer.d.cts +121 -0
  12. package/dist/cjs/lite-queuer.cjs +171 -0
  13. package/dist/cjs/lite-queuer.cjs.map +1 -0
  14. package/dist/cjs/lite-queuer.d.cts +239 -0
  15. package/dist/cjs/lite-rate-limiter.cjs +95 -0
  16. package/dist/cjs/lite-rate-limiter.cjs.map +1 -0
  17. package/dist/cjs/lite-rate-limiter.d.cts +143 -0
  18. package/dist/cjs/lite-throttler.cjs +63 -0
  19. package/dist/cjs/lite-throttler.cjs.map +1 -0
  20. package/dist/cjs/lite-throttler.d.cts +128 -0
  21. package/dist/esm/index.d.ts +5 -0
  22. package/dist/esm/index.js +18 -0
  23. package/dist/esm/index.js.map +1 -0
  24. package/dist/esm/lite-batcher.d.ts +180 -0
  25. package/dist/esm/lite-batcher.js +92 -0
  26. package/dist/esm/lite-batcher.js.map +1 -0
  27. package/dist/esm/lite-debouncer.d.ts +121 -0
  28. package/dist/esm/lite-debouncer.js +59 -0
  29. package/dist/esm/lite-debouncer.js.map +1 -0
  30. package/dist/esm/lite-queuer.d.ts +239 -0
  31. package/dist/esm/lite-queuer.js +171 -0
  32. package/dist/esm/lite-queuer.js.map +1 -0
  33. package/dist/esm/lite-rate-limiter.d.ts +143 -0
  34. package/dist/esm/lite-rate-limiter.js +95 -0
  35. package/dist/esm/lite-rate-limiter.js.map +1 -0
  36. package/dist/esm/lite-throttler.d.ts +128 -0
  37. package/dist/esm/lite-throttler.js +63 -0
  38. package/dist/esm/lite-throttler.js.map +1 -0
  39. package/package.json +113 -0
  40. package/src/index.ts +5 -0
  41. package/src/lite-batcher.ts +267 -0
  42. package/src/lite-debouncer.ts +184 -0
  43. package/src/lite-queuer.ts +434 -0
  44. package/src/lite-rate-limiter.ts +246 -0
  45. package/src/lite-throttler.ts +195 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lite-rate-limiter.cjs","sources":["../../src/lite-rate-limiter.ts"],"sourcesContent":["import type { AnyFunction } from '@tanstack/pacer/types'\n\n/**\n * Options for configuring a lite rate-limited function\n */\nexport interface LiteRateLimiterOptions<TFn extends AnyFunction = AnyFunction> {\n /**\n * Maximum number of executions allowed within the time window.\n */\n limit: number\n /**\n * Callback function that is called after the function is executed\n */\n onExecute?: (args: Parameters<TFn>, rateLimiter: LiteRateLimiter<TFn>) => void\n /**\n * Optional callback function that is called when an execution is rejected due to rate limiting\n */\n onReject?: (rateLimiter: LiteRateLimiter<TFn>) => void\n /**\n * Time window in milliseconds within which the limit applies.\n */\n window: number\n /**\n * Type of window to use for rate limiting\n * - 'fixed': Uses a fixed window that resets after the window period\n * - 'sliding': Uses a sliding window that allows executions as old ones expire\n * Defaults to 'fixed'\n */\n windowType?: 'fixed' | 'sliding'\n}\n\n/**\n * A lightweight class that creates a rate-limited function.\n *\n * This is an alternative to the RateLimiter in the core @tanstack/pacer package, but is more\n * suitable for libraries and npm packages that need minimal overhead. Unlike the core RateLimiter,\n * this version does not use TanStack Store for state management, has no devtools integration,\n * and provides only essential rate limiting functionality.\n *\n * Rate limiting allows a function to execute up to a limit within a time window,\n * then blocks all subsequent calls until the window passes. This can lead to \"bursty\" behavior where\n * all executions happen immediately, followed by a complete block.\n *\n * The rate limiter supports two types of windows:\n * - 'fixed': A strict window that resets after the window period. All executions within the window count\n * towards the limit, and the window resets completely after the period.\n * - 'sliding': A rolling window that allows executions as old ones expire. This provides a more\n * consistent rate of execution over time.\n *\n * Features:\n * - Zero dependencies - no external libraries required\n * - Minimal API surface - only essential methods (maybeExecute, getRemainingInWindow, getMsUntilNextWindow, reset)\n * - Simple state management - uses basic private properties instead of reactive stores\n * - Lightweight - designed for use in npm packages where bundle size matters\n *\n * @example\n * ```ts\n * const rateLimiter = new LiteRateLimiter((id: string) => {\n * api.getData(id);\n * }, { limit: 5, window: 1000 });\n *\n * // First 5 calls will execute, then block until window resets\n * if (rateLimiter.maybeExecute('123')) {\n * console.log('API call made');\n * } else {\n * console.log('Rate limited - try again in', rateLimiter.getMsUntilNextWindow(), 'ms');\n * }\n * ```\n */\nexport class LiteRateLimiter<TFn extends AnyFunction> {\n private executionTimes: Array<number> = []\n private timeoutIds: Set<NodeJS.Timeout> = new Set()\n\n constructor(\n public fn: TFn,\n public options: LiteRateLimiterOptions<TFn>,\n ) {\n // Default windowType to 'fixed' if not specified\n if (this.options.windowType === undefined) {\n this.options.windowType = 'fixed'\n }\n }\n\n /**\n * Attempts to execute the rate-limited function if within the configured limits.\n * Returns true if executed, false if rejected due to rate limiting.\n *\n * @example\n * ```ts\n * const rateLimiter = new LiteRateLimiter(fn, { limit: 5, window: 1000 });\n *\n * // First 5 calls return true\n * rateLimiter.maybeExecute('arg1', 'arg2'); // true\n *\n * // Additional calls within the window return false\n * rateLimiter.maybeExecute('arg1', 'arg2'); // false\n * ```\n */\n maybeExecute = (...args: Parameters<TFn>): boolean => {\n this.cleanupOldExecutions()\n\n const relevantExecutionTimes = this.getExecutionTimesInWindow()\n\n if (relevantExecutionTimes.length < this.options.limit) {\n this.execute(...args)\n return true\n }\n\n this.options.onReject?.(this)\n return false\n }\n\n private execute = (...args: Parameters<TFn>): void => {\n const now = Date.now()\n this.fn(...args)\n this.options.onExecute?.(args, this)\n this.executionTimes.push(now)\n this.setCleanupTimeout(now)\n }\n\n private getExecutionTimesInWindow = (): Array<number> => {\n if (this.options.windowType === 'sliding') {\n // For sliding window, return all executions within the current window\n return this.executionTimes.filter(\n (time) => time > Date.now() - this.options.window,\n )\n } else {\n // For fixed window, return all executions in the current window\n if (this.executionTimes.length === 0) {\n return []\n }\n const oldestExecution = Math.min(...this.executionTimes)\n const windowStart = oldestExecution\n const windowEnd = windowStart + this.options.window\n const now = Date.now()\n\n // If the window has expired, return empty array\n if (now > windowEnd) {\n return []\n }\n\n // Otherwise, return all executions in the current window\n return this.executionTimes.filter(\n (time) => time >= windowStart && time <= windowEnd,\n )\n }\n }\n\n private setCleanupTimeout = (executionTime: number): void => {\n if (\n this.options.windowType === 'sliding' ||\n this.timeoutIds.size === 0 // new fixed window\n ) {\n const now = Date.now()\n const timeUntilExpiration = executionTime - now + this.options.window + 1\n const timeoutId = setTimeout(() => {\n this.cleanupOldExecutions()\n this.clearTimeout(timeoutId)\n }, timeUntilExpiration)\n this.timeoutIds.add(timeoutId)\n }\n }\n\n private clearTimeout = (timeoutId: NodeJS.Timeout): void => {\n clearTimeout(timeoutId)\n this.timeoutIds.delete(timeoutId)\n }\n\n private clearTimeouts = (): void => {\n this.timeoutIds.forEach((timeoutId) => clearTimeout(timeoutId))\n this.timeoutIds.clear()\n }\n\n private cleanupOldExecutions = (): void => {\n this.executionTimes = this.getExecutionTimesInWindow()\n }\n\n /**\n * Returns the number of remaining executions allowed in the current window.\n */\n getRemainingInWindow = (): number => {\n const relevantExecutionTimes = this.getExecutionTimesInWindow()\n return Math.max(0, this.options.limit - relevantExecutionTimes.length)\n }\n\n /**\n * Returns the number of milliseconds until the next execution will be possible.\n * Returns 0 if executions are currently allowed.\n */\n getMsUntilNextWindow = (): number => {\n if (this.getRemainingInWindow() > 0) {\n return 0\n }\n const oldestExecution = this.executionTimes[0] ?? Infinity\n return oldestExecution + this.options.window - Date.now()\n }\n\n /**\n * Resets the rate limiter state, clearing all execution history.\n */\n reset = (): void => {\n this.executionTimes = []\n this.clearTimeouts()\n }\n}\n\n/**\n * Creates a lightweight rate-limited function that will execute the provided function up to a maximum number of times within a time window.\n *\n * This is an alternative to the rateLimit function in the core @tanstack/pacer package, but is more\n * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,\n * this function creates a rate limiter with no external dependencies, devtools integration, or reactive state.\n *\n * Rate limiting allows all executions until the limit is reached, then blocks all subsequent calls until the window resets.\n * This differs from throttling (which ensures even spacing) and debouncing (which waits for pauses).\n *\n * @example\n * ```ts\n * const rateLimitedApi = liteRateLimit(makeApiCall, {\n * limit: 5,\n * window: 60000, // 1 minute\n * windowType: 'sliding'\n * });\n *\n * // First 5 calls execute immediately\n * // Additional calls are rejected until window allows\n * rateLimitedApi();\n * ```\n *\n * @example\n * ```ts\n * // Fixed window - all 10 calls happen in first second, then 10 second wait\n * const rateLimitedFixed = liteRateLimit(logEvent, {\n * limit: 10,\n * window: 10000,\n * windowType: 'fixed'\n * });\n * ```\n */\nexport function liteRateLimit<TFn extends AnyFunction>(\n fn: TFn,\n options: LiteRateLimiterOptions<TFn>,\n): (...args: Parameters<TFn>) => boolean {\n const rateLimiter = new LiteRateLimiter(fn, options)\n return rateLimiter.maybeExecute\n}\n"],"names":[],"mappings":";;AAqEO,MAAM,gBAAyC;AAAA,EAIpD,YACS,IACA,SACP;AAFO,SAAA,KAAA;AACA,SAAA,UAAA;AALT,SAAQ,iBAAgC,CAAA;AACxC,SAAQ,iCAAsC,IAAA;AA2B9C,SAAA,eAAe,IAAI,SAAmC;AACpD,WAAK,qBAAA;AAEL,YAAM,yBAAyB,KAAK,0BAAA;AAEpC,UAAI,uBAAuB,SAAS,KAAK,QAAQ,OAAO;AACtD,aAAK,QAAQ,GAAG,IAAI;AACpB,eAAO;AAAA,MACT;AAEA,WAAK,QAAQ,WAAW,IAAI;AAC5B,aAAO;AAAA,IACT;AAEA,SAAQ,UAAU,IAAI,SAAgC;AACpD,YAAM,MAAM,KAAK,IAAA;AACjB,WAAK,GAAG,GAAG,IAAI;AACf,WAAK,QAAQ,YAAY,MAAM,IAAI;AACnC,WAAK,eAAe,KAAK,GAAG;AAC5B,WAAK,kBAAkB,GAAG;AAAA,IAC5B;AAEA,SAAQ,4BAA4B,MAAqB;AACvD,UAAI,KAAK,QAAQ,eAAe,WAAW;AAEzC,eAAO,KAAK,eAAe;AAAA,UACzB,CAAC,SAAS,OAAO,KAAK,IAAA,IAAQ,KAAK,QAAQ;AAAA,QAAA;AAAA,MAE/C,OAAO;AAEL,YAAI,KAAK,eAAe,WAAW,GAAG;AACpC,iBAAO,CAAA;AAAA,QACT;AACA,cAAM,kBAAkB,KAAK,IAAI,GAAG,KAAK,cAAc;AACvD,cAAM,cAAc;AACpB,cAAM,YAAY,cAAc,KAAK,QAAQ;AAC7C,cAAM,MAAM,KAAK,IAAA;AAGjB,YAAI,MAAM,WAAW;AACnB,iBAAO,CAAA;AAAA,QACT;AAGA,eAAO,KAAK,eAAe;AAAA,UACzB,CAAC,SAAS,QAAQ,eAAe,QAAQ;AAAA,QAAA;AAAA,MAE7C;AAAA,IACF;AAEA,SAAQ,oBAAoB,CAAC,kBAAgC;AAC3D,UACE,KAAK,QAAQ,eAAe,aAC5B,KAAK,WAAW,SAAS,GACzB;AACA,cAAM,MAAM,KAAK,IAAA;AACjB,cAAM,sBAAsB,gBAAgB,MAAM,KAAK,QAAQ,SAAS;AACxE,cAAM,YAAY,WAAW,MAAM;AACjC,eAAK,qBAAA;AACL,eAAK,aAAa,SAAS;AAAA,QAC7B,GAAG,mBAAmB;AACtB,aAAK,WAAW,IAAI,SAAS;AAAA,MAC/B;AAAA,IACF;AAEA,SAAQ,eAAe,CAAC,cAAoC;AAC1D,mBAAa,SAAS;AACtB,WAAK,WAAW,OAAO,SAAS;AAAA,IAClC;AAEA,SAAQ,gBAAgB,MAAY;AAClC,WAAK,WAAW,QAAQ,CAAC,cAAc,aAAa,SAAS,CAAC;AAC9D,WAAK,WAAW,MAAA;AAAA,IAClB;AAEA,SAAQ,uBAAuB,MAAY;AACzC,WAAK,iBAAiB,KAAK,0BAAA;AAAA,IAC7B;AAKA,SAAA,uBAAuB,MAAc;AACnC,YAAM,yBAAyB,KAAK,0BAAA;AACpC,aAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,QAAQ,uBAAuB,MAAM;AAAA,IACvE;AAMA,SAAA,uBAAuB,MAAc;AACnC,UAAI,KAAK,qBAAA,IAAyB,GAAG;AACnC,eAAO;AAAA,MACT;AACA,YAAM,kBAAkB,KAAK,eAAe,CAAC,KAAK;AAClD,aAAO,kBAAkB,KAAK,QAAQ,SAAS,KAAK,IAAA;AAAA,IACtD;AAKA,SAAA,QAAQ,MAAY;AAClB,WAAK,iBAAiB,CAAA;AACtB,WAAK,cAAA;AAAA,IACP;AA7HE,QAAI,KAAK,QAAQ,eAAe,QAAW;AACzC,WAAK,QAAQ,aAAa;AAAA,IAC5B;AAAA,EACF;AA2HF;AAmCO,SAAS,cACd,IACA,SACuC;AACvC,QAAM,cAAc,IAAI,gBAAgB,IAAI,OAAO;AACnD,SAAO,YAAY;AACrB;;;"}
@@ -0,0 +1,143 @@
1
+ import { AnyFunction } from '@tanstack/pacer/types';
2
+ /**
3
+ * Options for configuring a lite rate-limited function
4
+ */
5
+ export interface LiteRateLimiterOptions<TFn extends AnyFunction = AnyFunction> {
6
+ /**
7
+ * Maximum number of executions allowed within the time window.
8
+ */
9
+ limit: number;
10
+ /**
11
+ * Callback function that is called after the function is executed
12
+ */
13
+ onExecute?: (args: Parameters<TFn>, rateLimiter: LiteRateLimiter<TFn>) => void;
14
+ /**
15
+ * Optional callback function that is called when an execution is rejected due to rate limiting
16
+ */
17
+ onReject?: (rateLimiter: LiteRateLimiter<TFn>) => void;
18
+ /**
19
+ * Time window in milliseconds within which the limit applies.
20
+ */
21
+ window: number;
22
+ /**
23
+ * Type of window to use for rate limiting
24
+ * - 'fixed': Uses a fixed window that resets after the window period
25
+ * - 'sliding': Uses a sliding window that allows executions as old ones expire
26
+ * Defaults to 'fixed'
27
+ */
28
+ windowType?: 'fixed' | 'sliding';
29
+ }
30
+ /**
31
+ * A lightweight class that creates a rate-limited function.
32
+ *
33
+ * This is an alternative to the RateLimiter in the core @tanstack/pacer package, but is more
34
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core RateLimiter,
35
+ * this version does not use TanStack Store for state management, has no devtools integration,
36
+ * and provides only essential rate limiting functionality.
37
+ *
38
+ * Rate limiting allows a function to execute up to a limit within a time window,
39
+ * then blocks all subsequent calls until the window passes. This can lead to "bursty" behavior where
40
+ * all executions happen immediately, followed by a complete block.
41
+ *
42
+ * The rate limiter supports two types of windows:
43
+ * - 'fixed': A strict window that resets after the window period. All executions within the window count
44
+ * towards the limit, and the window resets completely after the period.
45
+ * - 'sliding': A rolling window that allows executions as old ones expire. This provides a more
46
+ * consistent rate of execution over time.
47
+ *
48
+ * Features:
49
+ * - Zero dependencies - no external libraries required
50
+ * - Minimal API surface - only essential methods (maybeExecute, getRemainingInWindow, getMsUntilNextWindow, reset)
51
+ * - Simple state management - uses basic private properties instead of reactive stores
52
+ * - Lightweight - designed for use in npm packages where bundle size matters
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const rateLimiter = new LiteRateLimiter((id: string) => {
57
+ * api.getData(id);
58
+ * }, { limit: 5, window: 1000 });
59
+ *
60
+ * // First 5 calls will execute, then block until window resets
61
+ * if (rateLimiter.maybeExecute('123')) {
62
+ * console.log('API call made');
63
+ * } else {
64
+ * console.log('Rate limited - try again in', rateLimiter.getMsUntilNextWindow(), 'ms');
65
+ * }
66
+ * ```
67
+ */
68
+ export declare class LiteRateLimiter<TFn extends AnyFunction> {
69
+ fn: TFn;
70
+ options: LiteRateLimiterOptions<TFn>;
71
+ private executionTimes;
72
+ private timeoutIds;
73
+ constructor(fn: TFn, options: LiteRateLimiterOptions<TFn>);
74
+ /**
75
+ * Attempts to execute the rate-limited function if within the configured limits.
76
+ * Returns true if executed, false if rejected due to rate limiting.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * const rateLimiter = new LiteRateLimiter(fn, { limit: 5, window: 1000 });
81
+ *
82
+ * // First 5 calls return true
83
+ * rateLimiter.maybeExecute('arg1', 'arg2'); // true
84
+ *
85
+ * // Additional calls within the window return false
86
+ * rateLimiter.maybeExecute('arg1', 'arg2'); // false
87
+ * ```
88
+ */
89
+ maybeExecute: (...args: Parameters<TFn>) => boolean;
90
+ private execute;
91
+ private getExecutionTimesInWindow;
92
+ private setCleanupTimeout;
93
+ private clearTimeout;
94
+ private clearTimeouts;
95
+ private cleanupOldExecutions;
96
+ /**
97
+ * Returns the number of remaining executions allowed in the current window.
98
+ */
99
+ getRemainingInWindow: () => number;
100
+ /**
101
+ * Returns the number of milliseconds until the next execution will be possible.
102
+ * Returns 0 if executions are currently allowed.
103
+ */
104
+ getMsUntilNextWindow: () => number;
105
+ /**
106
+ * Resets the rate limiter state, clearing all execution history.
107
+ */
108
+ reset: () => void;
109
+ }
110
+ /**
111
+ * Creates a lightweight rate-limited function that will execute the provided function up to a maximum number of times within a time window.
112
+ *
113
+ * This is an alternative to the rateLimit function in the core @tanstack/pacer package, but is more
114
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,
115
+ * this function creates a rate limiter with no external dependencies, devtools integration, or reactive state.
116
+ *
117
+ * Rate limiting allows all executions until the limit is reached, then blocks all subsequent calls until the window resets.
118
+ * This differs from throttling (which ensures even spacing) and debouncing (which waits for pauses).
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const rateLimitedApi = liteRateLimit(makeApiCall, {
123
+ * limit: 5,
124
+ * window: 60000, // 1 minute
125
+ * windowType: 'sliding'
126
+ * });
127
+ *
128
+ * // First 5 calls execute immediately
129
+ * // Additional calls are rejected until window allows
130
+ * rateLimitedApi();
131
+ * ```
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * // Fixed window - all 10 calls happen in first second, then 10 second wait
136
+ * const rateLimitedFixed = liteRateLimit(logEvent, {
137
+ * limit: 10,
138
+ * window: 10000,
139
+ * windowType: 'fixed'
140
+ * });
141
+ * ```
142
+ */
143
+ export declare function liteRateLimit<TFn extends AnyFunction>(fn: TFn, options: LiteRateLimiterOptions<TFn>): (...args: Parameters<TFn>) => boolean;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ class LiteThrottler {
4
+ constructor(fn, options) {
5
+ this.fn = fn;
6
+ this.options = options;
7
+ this.lastExecutionTime = 0;
8
+ this.isPending = false;
9
+ this.maybeExecute = (...args) => {
10
+ const now = Date.now();
11
+ const timeSinceLastExecution = now - this.lastExecutionTime;
12
+ if (this.options.leading && timeSinceLastExecution >= this.options.wait) {
13
+ this.execute(...args);
14
+ } else {
15
+ this.lastArgs = args;
16
+ if (!this.timeoutId && this.options.trailing) {
17
+ const timeoutDuration = this.options.wait - timeSinceLastExecution;
18
+ this.isPending = true;
19
+ this.timeoutId = setTimeout(() => {
20
+ if (this.lastArgs !== void 0) {
21
+ this.execute(...this.lastArgs);
22
+ }
23
+ }, timeoutDuration);
24
+ }
25
+ }
26
+ };
27
+ this.execute = (...args) => {
28
+ this.fn(...args);
29
+ this.options.onExecute?.(args, this);
30
+ this.lastExecutionTime = Date.now();
31
+ this.clearTimeout();
32
+ this.lastArgs = void 0;
33
+ this.isPending = false;
34
+ };
35
+ this.flush = () => {
36
+ if (this.isPending && this.lastArgs) {
37
+ this.execute(...this.lastArgs);
38
+ }
39
+ };
40
+ this.cancel = () => {
41
+ this.clearTimeout();
42
+ this.lastArgs = void 0;
43
+ this.isPending = false;
44
+ };
45
+ this.clearTimeout = () => {
46
+ if (this.timeoutId) {
47
+ clearTimeout(this.timeoutId);
48
+ this.timeoutId = void 0;
49
+ }
50
+ };
51
+ if (this.options.leading === void 0 && this.options.trailing === void 0) {
52
+ this.options.leading = true;
53
+ this.options.trailing = true;
54
+ }
55
+ }
56
+ }
57
+ function liteThrottle(fn, options) {
58
+ const throttler = new LiteThrottler(fn, options);
59
+ return throttler.maybeExecute;
60
+ }
61
+ exports.LiteThrottler = LiteThrottler;
62
+ exports.liteThrottle = liteThrottle;
63
+ //# sourceMappingURL=lite-throttler.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lite-throttler.cjs","sources":["../../src/lite-throttler.ts"],"sourcesContent":["import type { AnyFunction } from '@tanstack/pacer/types'\n\n/**\n * Options for configuring a lite throttled function\n */\nexport interface LiteThrottlerOptions<TFn extends AnyFunction = AnyFunction> {\n /**\n * Whether to execute on the leading edge of the timeout.\n * Defaults to true.\n */\n leading?: boolean\n /**\n * Callback function that is called after the function is executed\n */\n onExecute?: (args: Parameters<TFn>, throttler: LiteThrottler<TFn>) => void\n /**\n * Whether to execute on the trailing edge of the timeout.\n * Defaults to true.\n */\n trailing?: boolean\n /**\n * Time window in milliseconds during which the function can only be executed once.\n */\n wait: number\n}\n\n/**\n * A lightweight class that creates a throttled function.\n *\n * This is an alternative to the Throttler in the core @tanstack/pacer package, but is more\n * suitable for libraries and npm packages that need minimal overhead. Unlike the core Throttler,\n * this version does not use TanStack Store for state management, has no devtools integration,\n * and provides only essential throttling functionality.\n *\n * Throttling ensures a function is called at most once within a specified time window.\n * Unlike debouncing which waits for a pause in calls, throttling guarantees consistent\n * execution timing regardless of call frequency.\n *\n * Supports both leading and trailing edge execution:\n * - Leading: Execute immediately on first call (default: true)\n * - Trailing: Execute after wait period if called during throttle (default: true)\n *\n * Features:\n * - Zero dependencies - no external libraries required\n * - Minimal API surface - only essential methods (maybeExecute, flush, cancel)\n * - Simple state management - uses basic private properties instead of reactive stores\n * - Callback support for monitoring execution events\n * - Lightweight - designed for use in npm packages where bundle size matters\n *\n * @example\n * ```ts\n * const throttler = new LiteThrottler((scrollY: number) => {\n * updateScrollPosition(scrollY);\n * }, {\n * wait: 100,\n * onExecute: (args, throttler) => {\n * console.log('Updated scroll position:', args[0]);\n * }\n * });\n *\n * // Will execute at most once per 100ms\n * window.addEventListener('scroll', () => {\n * throttler.maybeExecute(window.scrollY);\n * });\n * ```\n */\nexport class LiteThrottler<TFn extends AnyFunction> {\n private timeoutId: NodeJS.Timeout | undefined\n private lastArgs: Parameters<TFn> | undefined\n private lastExecutionTime = 0\n private isPending = false\n\n constructor(\n public fn: TFn,\n public options: LiteThrottlerOptions<TFn>,\n ) {\n // Default both leading and trailing to true if neither is specified\n if (\n this.options.leading === undefined &&\n this.options.trailing === undefined\n ) {\n this.options.leading = true\n this.options.trailing = true\n }\n }\n\n /**\n * Attempts to execute the throttled function. The execution behavior depends on the throttler options:\n *\n * - If enough time has passed since the last execution (>= wait period):\n * - With leading=true: Executes immediately\n * - With leading=false: Waits for the next trailing execution\n *\n * - If within the wait period:\n * - With trailing=true: Schedules execution for end of wait period\n * - With trailing=false: Drops the execution\n */\n maybeExecute = (...args: Parameters<TFn>): void => {\n const now = Date.now()\n const timeSinceLastExecution = now - this.lastExecutionTime\n\n // Handle leading execution\n if (this.options.leading && timeSinceLastExecution >= this.options.wait) {\n this.execute(...args)\n } else {\n // Store the most recent arguments for potential trailing execution\n this.lastArgs = args\n\n // Set up trailing execution if not already scheduled\n if (!this.timeoutId && this.options.trailing) {\n const timeoutDuration = this.options.wait - timeSinceLastExecution\n this.isPending = true\n this.timeoutId = setTimeout(() => {\n if (this.lastArgs !== undefined) {\n this.execute(...this.lastArgs)\n }\n }, timeoutDuration)\n }\n }\n }\n\n private execute = (...args: Parameters<TFn>): void => {\n this.fn(...args)\n this.options.onExecute?.(args, this)\n this.lastExecutionTime = Date.now()\n this.clearTimeout()\n this.lastArgs = undefined\n this.isPending = false\n }\n\n /**\n * Processes the current pending execution immediately.\n * If there's a pending execution, it will be executed right away\n * and the timeout will be cleared.\n */\n flush = (): void => {\n if (this.isPending && this.lastArgs) {\n this.execute(...this.lastArgs)\n }\n }\n\n /**\n * Cancels any pending trailing execution and clears internal state.\n * If a trailing execution is scheduled, this will prevent that execution from occurring.\n */\n cancel = (): void => {\n this.clearTimeout()\n this.lastArgs = undefined\n this.isPending = false\n }\n\n private clearTimeout = (): void => {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId)\n this.timeoutId = undefined\n }\n }\n}\n\n/**\n * Creates a lightweight throttled function that limits how often the provided function can execute.\n *\n * This is an alternative to the throttle function in the core @tanstack/pacer package, but is more\n * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,\n * this function creates a throttler with no external dependencies, devtools integration, or reactive state.\n *\n * Throttling ensures a function executes at most once within a specified time window,\n * regardless of how many times it is called. This is useful for rate-limiting\n * expensive operations or UI updates.\n *\n * @example\n * ```ts\n * const throttledScroll = liteThrottle(() => {\n * updateScrollIndicator();\n * }, { wait: 100 });\n *\n * // Will execute at most once per 100ms\n * window.addEventListener('scroll', throttledScroll);\n * ```\n *\n * @example\n * ```ts\n * // Leading edge execution - fires immediately then throttles\n * const throttledResize = liteThrottle(() => {\n * recalculateLayout();\n * }, { wait: 250, leading: true, trailing: false });\n * ```\n */\nexport function liteThrottle<TFn extends AnyFunction>(\n fn: TFn,\n options: LiteThrottlerOptions<TFn>,\n): (...args: Parameters<TFn>) => void {\n const throttler = new LiteThrottler(fn, options)\n return throttler.maybeExecute\n}\n"],"names":[],"mappings":";;AAkEO,MAAM,cAAuC;AAAA,EAMlD,YACS,IACA,SACP;AAFO,SAAA,KAAA;AACA,SAAA,UAAA;AALT,SAAQ,oBAAoB;AAC5B,SAAQ,YAAY;AA2BpB,SAAA,eAAe,IAAI,SAAgC;AACjD,YAAM,MAAM,KAAK,IAAA;AACjB,YAAM,yBAAyB,MAAM,KAAK;AAG1C,UAAI,KAAK,QAAQ,WAAW,0BAA0B,KAAK,QAAQ,MAAM;AACvE,aAAK,QAAQ,GAAG,IAAI;AAAA,MACtB,OAAO;AAEL,aAAK,WAAW;AAGhB,YAAI,CAAC,KAAK,aAAa,KAAK,QAAQ,UAAU;AAC5C,gBAAM,kBAAkB,KAAK,QAAQ,OAAO;AAC5C,eAAK,YAAY;AACjB,eAAK,YAAY,WAAW,MAAM;AAChC,gBAAI,KAAK,aAAa,QAAW;AAC/B,mBAAK,QAAQ,GAAG,KAAK,QAAQ;AAAA,YAC/B;AAAA,UACF,GAAG,eAAe;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,SAAQ,UAAU,IAAI,SAAgC;AACpD,WAAK,GAAG,GAAG,IAAI;AACf,WAAK,QAAQ,YAAY,MAAM,IAAI;AACnC,WAAK,oBAAoB,KAAK,IAAA;AAC9B,WAAK,aAAA;AACL,WAAK,WAAW;AAChB,WAAK,YAAY;AAAA,IACnB;AAOA,SAAA,QAAQ,MAAY;AAClB,UAAI,KAAK,aAAa,KAAK,UAAU;AACnC,aAAK,QAAQ,GAAG,KAAK,QAAQ;AAAA,MAC/B;AAAA,IACF;AAMA,SAAA,SAAS,MAAY;AACnB,WAAK,aAAA;AACL,WAAK,WAAW;AAChB,WAAK,YAAY;AAAA,IACnB;AAEA,SAAQ,eAAe,MAAY;AACjC,UAAI,KAAK,WAAW;AAClB,qBAAa,KAAK,SAAS;AAC3B,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AA/EE,QACE,KAAK,QAAQ,YAAY,UACzB,KAAK,QAAQ,aAAa,QAC1B;AACA,WAAK,QAAQ,UAAU;AACvB,WAAK,QAAQ,WAAW;AAAA,IAC1B;AAAA,EACF;AAyEF;AA+BO,SAAS,aACd,IACA,SACoC;AACpC,QAAM,YAAY,IAAI,cAAc,IAAI,OAAO;AAC/C,SAAO,UAAU;AACnB;;;"}
@@ -0,0 +1,128 @@
1
+ import { AnyFunction } from '@tanstack/pacer/types';
2
+ /**
3
+ * Options for configuring a lite throttled function
4
+ */
5
+ export interface LiteThrottlerOptions<TFn extends AnyFunction = AnyFunction> {
6
+ /**
7
+ * Whether to execute on the leading edge of the timeout.
8
+ * Defaults to true.
9
+ */
10
+ leading?: boolean;
11
+ /**
12
+ * Callback function that is called after the function is executed
13
+ */
14
+ onExecute?: (args: Parameters<TFn>, throttler: LiteThrottler<TFn>) => void;
15
+ /**
16
+ * Whether to execute on the trailing edge of the timeout.
17
+ * Defaults to true.
18
+ */
19
+ trailing?: boolean;
20
+ /**
21
+ * Time window in milliseconds during which the function can only be executed once.
22
+ */
23
+ wait: number;
24
+ }
25
+ /**
26
+ * A lightweight class that creates a throttled function.
27
+ *
28
+ * This is an alternative to the Throttler in the core @tanstack/pacer package, but is more
29
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core Throttler,
30
+ * this version does not use TanStack Store for state management, has no devtools integration,
31
+ * and provides only essential throttling functionality.
32
+ *
33
+ * Throttling ensures a function is called at most once within a specified time window.
34
+ * Unlike debouncing which waits for a pause in calls, throttling guarantees consistent
35
+ * execution timing regardless of call frequency.
36
+ *
37
+ * Supports both leading and trailing edge execution:
38
+ * - Leading: Execute immediately on first call (default: true)
39
+ * - Trailing: Execute after wait period if called during throttle (default: true)
40
+ *
41
+ * Features:
42
+ * - Zero dependencies - no external libraries required
43
+ * - Minimal API surface - only essential methods (maybeExecute, flush, cancel)
44
+ * - Simple state management - uses basic private properties instead of reactive stores
45
+ * - Callback support for monitoring execution events
46
+ * - Lightweight - designed for use in npm packages where bundle size matters
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const throttler = new LiteThrottler((scrollY: number) => {
51
+ * updateScrollPosition(scrollY);
52
+ * }, {
53
+ * wait: 100,
54
+ * onExecute: (args, throttler) => {
55
+ * console.log('Updated scroll position:', args[0]);
56
+ * }
57
+ * });
58
+ *
59
+ * // Will execute at most once per 100ms
60
+ * window.addEventListener('scroll', () => {
61
+ * throttler.maybeExecute(window.scrollY);
62
+ * });
63
+ * ```
64
+ */
65
+ export declare class LiteThrottler<TFn extends AnyFunction> {
66
+ fn: TFn;
67
+ options: LiteThrottlerOptions<TFn>;
68
+ private timeoutId;
69
+ private lastArgs;
70
+ private lastExecutionTime;
71
+ private isPending;
72
+ constructor(fn: TFn, options: LiteThrottlerOptions<TFn>);
73
+ /**
74
+ * Attempts to execute the throttled function. The execution behavior depends on the throttler options:
75
+ *
76
+ * - If enough time has passed since the last execution (>= wait period):
77
+ * - With leading=true: Executes immediately
78
+ * - With leading=false: Waits for the next trailing execution
79
+ *
80
+ * - If within the wait period:
81
+ * - With trailing=true: Schedules execution for end of wait period
82
+ * - With trailing=false: Drops the execution
83
+ */
84
+ maybeExecute: (...args: Parameters<TFn>) => void;
85
+ private execute;
86
+ /**
87
+ * Processes the current pending execution immediately.
88
+ * If there's a pending execution, it will be executed right away
89
+ * and the timeout will be cleared.
90
+ */
91
+ flush: () => void;
92
+ /**
93
+ * Cancels any pending trailing execution and clears internal state.
94
+ * If a trailing execution is scheduled, this will prevent that execution from occurring.
95
+ */
96
+ cancel: () => void;
97
+ private clearTimeout;
98
+ }
99
+ /**
100
+ * Creates a lightweight throttled function that limits how often the provided function can execute.
101
+ *
102
+ * This is an alternative to the throttle function in the core @tanstack/pacer package, but is more
103
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,
104
+ * this function creates a throttler with no external dependencies, devtools integration, or reactive state.
105
+ *
106
+ * Throttling ensures a function executes at most once within a specified time window,
107
+ * regardless of how many times it is called. This is useful for rate-limiting
108
+ * expensive operations or UI updates.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * const throttledScroll = liteThrottle(() => {
113
+ * updateScrollIndicator();
114
+ * }, { wait: 100 });
115
+ *
116
+ * // Will execute at most once per 100ms
117
+ * window.addEventListener('scroll', throttledScroll);
118
+ * ```
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * // Leading edge execution - fires immediately then throttles
123
+ * const throttledResize = liteThrottle(() => {
124
+ * recalculateLayout();
125
+ * }, { wait: 250, leading: true, trailing: false });
126
+ * ```
127
+ */
128
+ export declare function liteThrottle<TFn extends AnyFunction>(fn: TFn, options: LiteThrottlerOptions<TFn>): (...args: Parameters<TFn>) => void;
@@ -0,0 +1,5 @@
1
+ export * from './lite-debouncer.js';
2
+ export * from './lite-throttler.js';
3
+ export * from './lite-rate-limiter.js';
4
+ export * from './lite-queuer.js';
5
+ export * from './lite-batcher.js';
@@ -0,0 +1,18 @@
1
+ import { LiteDebouncer, liteDebounce } from "./lite-debouncer.js";
2
+ import { LiteThrottler, liteThrottle } from "./lite-throttler.js";
3
+ import { LiteRateLimiter, liteRateLimit } from "./lite-rate-limiter.js";
4
+ import { LiteQueuer, liteQueue } from "./lite-queuer.js";
5
+ import { LiteBatcher, liteBatch } from "./lite-batcher.js";
6
+ export {
7
+ LiteBatcher,
8
+ LiteDebouncer,
9
+ LiteQueuer,
10
+ LiteRateLimiter,
11
+ LiteThrottler,
12
+ liteBatch,
13
+ liteDebounce,
14
+ liteQueue,
15
+ liteRateLimit,
16
+ liteThrottle
17
+ };
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Options for configuring a lite batcher instance
3
+ */
4
+ export interface LiteBatcherOptions<TValue> {
5
+ /**
6
+ * Custom function to determine if a batch should be processed
7
+ * Return true to process the batch immediately
8
+ */
9
+ getShouldExecute?: (items: Array<TValue>, batcher: LiteBatcher<TValue>) => boolean;
10
+ /**
11
+ * Maximum number of items in a batch
12
+ * @default Infinity
13
+ */
14
+ maxSize?: number;
15
+ /**
16
+ * Callback fired after a batch is processed
17
+ */
18
+ onExecute?: (batch: Array<TValue>, batcher: LiteBatcher<TValue>) => void;
19
+ /**
20
+ * Callback fired after items are added to the batcher
21
+ */
22
+ onItemsChange?: (batcher: LiteBatcher<TValue>) => void;
23
+ /**
24
+ * Whether the batcher should start processing immediately
25
+ * @default true
26
+ */
27
+ started?: boolean;
28
+ /**
29
+ * Maximum time in milliseconds to wait before processing a batch.
30
+ * If the wait duration has elapsed, the batch will be processed.
31
+ * If not provided, the batch will not be triggered by a timeout.
32
+ * @default Infinity
33
+ */
34
+ wait?: number | ((batcher: LiteBatcher<TValue>) => number);
35
+ }
36
+ /**
37
+ * A lightweight class that collects items and processes them in batches.
38
+ *
39
+ * This is an alternative to the Batcher in the core @tanstack/pacer package, but is more
40
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core Batcher,
41
+ * this version does not use TanStack Store for state management, has no devtools integration,
42
+ * no callbacks, and provides only essential batching functionality.
43
+ *
44
+ * Batching is a technique for grouping multiple operations together to be processed as a single unit.
45
+ * This synchronous version is lighter weight and often all you need.
46
+ *
47
+ * The Batcher provides a flexible way to implement batching with configurable:
48
+ * - Maximum batch size (number of items per batch)
49
+ * - Time-based batching (process after X milliseconds)
50
+ * - Custom batch processing logic via getShouldExecute
51
+ *
52
+ * Features included:
53
+ * - Core batching functionality (addItem, flush, clear, cancel)
54
+ * - Size-based batching (maxSize)
55
+ * - Time-based batching (wait timeout)
56
+ * - Custom condition batching (getShouldExecute)
57
+ * - Manual processing controls
58
+ * - Public mutable options
59
+ * - Callback support for monitoring batch execution and state changes
60
+ *
61
+ * Features NOT included (compared to core Batcher):
62
+ * - No TanStack Store state management
63
+ * - No devtools integration
64
+ * - No complex state tracking (execution counts, etc.)
65
+ * - No reactive state management
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * // Basic batching
70
+ * const batcher = new LiteBatcher<number>(
71
+ * (items) => console.log('Processing batch:', items),
72
+ * {
73
+ * maxSize: 5,
74
+ * wait: 2000,
75
+ * onExecute: (batch, batcher) => {
76
+ * console.log('Batch executed with', batch.length, 'items');
77
+ * },
78
+ * onItemsChange: (batcher) => {
79
+ * console.log('Batch size changed to:', batcher.size);
80
+ * }
81
+ * }
82
+ * );
83
+ *
84
+ * batcher.addItem(1);
85
+ * batcher.addItem(2);
86
+ * // After 2 seconds or when 5 items are added, whichever comes first,
87
+ * // the batch will be processed
88
+ * ```
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * // Custom condition batching
93
+ * const batcher = new LiteBatcher<Task>(
94
+ * (items) => processTasks(items),
95
+ * {
96
+ * getShouldExecute: (items) => items.some(task => task.urgent),
97
+ * maxSize: 10,
98
+ * }
99
+ * );
100
+ *
101
+ * batcher.addItem({ name: 'normal', urgent: false });
102
+ * batcher.addItem({ name: 'urgent', urgent: true }); // Triggers immediate processing
103
+ * ```
104
+ */
105
+ export declare class LiteBatcher<TValue> {
106
+ fn: (items: Array<TValue>) => void;
107
+ options: LiteBatcherOptions<TValue>;
108
+ private items;
109
+ private timeoutId;
110
+ private _isPending;
111
+ constructor(fn: (items: Array<TValue>) => void, options?: LiteBatcherOptions<TValue>);
112
+ /**
113
+ * Number of items currently in the batch
114
+ */
115
+ get size(): number;
116
+ /**
117
+ * Whether the batch has no items to process (items array is empty)
118
+ */
119
+ get isEmpty(): boolean;
120
+ /**
121
+ * Whether the batcher is waiting for the timeout to trigger batch processing
122
+ */
123
+ get isPending(): boolean;
124
+ private getWait;
125
+ /**
126
+ * Adds an item to the batcher
127
+ * If the batch size is reached, timeout occurs, or getShouldExecute returns true, the batch will be processed
128
+ */
129
+ addItem: (item: TValue) => void;
130
+ /**
131
+ * Processes the current batch of items.
132
+ * This method will automatically be triggered if the batcher is running and any of these conditions are met:
133
+ * - The number of items reaches maxSize
134
+ * - The wait duration has elapsed
135
+ * - The getShouldExecute function returns true upon adding an item
136
+ *
137
+ * You can also call this method manually to process the current batch at any time.
138
+ */
139
+ private execute;
140
+ /**
141
+ * Processes the current batch of items immediately
142
+ */
143
+ flush: () => void;
144
+ /**
145
+ * Returns a copy of all items in the batcher
146
+ */
147
+ peekAllItems: () => Array<TValue>;
148
+ private clearTimeout;
149
+ /**
150
+ * Removes all items from the batcher
151
+ */
152
+ clear: () => void;
153
+ /**
154
+ * Cancels any pending execution that was scheduled.
155
+ * Does NOT clear out the items.
156
+ */
157
+ cancel: () => void;
158
+ }
159
+ /**
160
+ * Creates a batcher that processes items in batches.
161
+ *
162
+ * This is an alternative to the batch function in the core @tanstack/pacer package, but is more
163
+ * suitable for libraries and npm packages that need minimal overhead. Unlike the core version,
164
+ * this function creates a batcher with no external dependencies, devtools integration, or reactive state.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const batchItems = liteBatch<number>(
169
+ * (items) => console.log('Processing:', items),
170
+ * {
171
+ * maxSize: 3,
172
+ * }
173
+ * );
174
+ *
175
+ * batchItems(1);
176
+ * batchItems(2);
177
+ * batchItems(3); // Triggers batch processing
178
+ * ```
179
+ */
180
+ export declare function liteBatch<TValue>(fn: (items: Array<TValue>) => void, options?: LiteBatcherOptions<TValue>): (item: TValue) => void;
@@ -0,0 +1,92 @@
1
+ class LiteBatcher {
2
+ constructor(fn, options = {}) {
3
+ this.fn = fn;
4
+ this.options = options;
5
+ this.items = [];
6
+ this.timeoutId = null;
7
+ this._isPending = false;
8
+ this.addItem = (item) => {
9
+ this.items.push(item);
10
+ this._isPending = this.options.wait !== Infinity;
11
+ this.options.onItemsChange?.(this);
12
+ const shouldProcess = this.items.length >= this.options.maxSize || this.options.getShouldExecute(this.items, this);
13
+ if (shouldProcess) {
14
+ this.execute();
15
+ } else if (this.options.wait !== Infinity) {
16
+ this.clearTimeout();
17
+ this.timeoutId = setTimeout(() => this.execute(), this.getWait());
18
+ }
19
+ };
20
+ this.execute = () => {
21
+ if (this.items.length === 0) {
22
+ return;
23
+ }
24
+ const batch = this.peekAllItems();
25
+ this.clear();
26
+ this.fn(batch);
27
+ this.options.onExecute?.(batch, this);
28
+ };
29
+ this.flush = () => {
30
+ this.clearTimeout();
31
+ this.execute();
32
+ };
33
+ this.peekAllItems = () => {
34
+ return [...this.items];
35
+ };
36
+ this.clearTimeout = () => {
37
+ if (this.timeoutId) {
38
+ clearTimeout(this.timeoutId);
39
+ this.timeoutId = null;
40
+ }
41
+ };
42
+ this.clear = () => {
43
+ const hadItems = this.items.length > 0;
44
+ this.items = [];
45
+ this._isPending = false;
46
+ if (hadItems) {
47
+ this.options.onItemsChange?.(this);
48
+ }
49
+ };
50
+ this.cancel = () => {
51
+ this.clearTimeout();
52
+ this._isPending = false;
53
+ };
54
+ this.options.maxSize = this.options.maxSize ?? Infinity;
55
+ this.options.started = this.options.started ?? true;
56
+ this.options.wait = this.options.wait ?? Infinity;
57
+ this.options.getShouldExecute = this.options.getShouldExecute ?? (() => false);
58
+ }
59
+ /**
60
+ * Number of items currently in the batch
61
+ */
62
+ get size() {
63
+ return this.items.length;
64
+ }
65
+ /**
66
+ * Whether the batch has no items to process (items array is empty)
67
+ */
68
+ get isEmpty() {
69
+ return this.items.length === 0;
70
+ }
71
+ /**
72
+ * Whether the batcher is waiting for the timeout to trigger batch processing
73
+ */
74
+ get isPending() {
75
+ return this._isPending;
76
+ }
77
+ getWait() {
78
+ if (typeof this.options.wait === "function") {
79
+ return this.options.wait(this);
80
+ }
81
+ return this.options.wait;
82
+ }
83
+ }
84
+ function liteBatch(fn, options = {}) {
85
+ const batcher = new LiteBatcher(fn, options);
86
+ return batcher.addItem;
87
+ }
88
+ export {
89
+ LiteBatcher,
90
+ liteBatch
91
+ };
92
+ //# sourceMappingURL=lite-batcher.js.map