yummies 7.11.0 → 7.13.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 (159) hide show
  1. package/README.md +5 -87
  2. package/async.cjs +179 -48
  3. package/async.cjs.map +1 -1
  4. package/async.d.ts +125 -7
  5. package/async.js +180 -54
  6. package/async.js.map +1 -1
  7. package/chunk-CVq3Gv4J.cjs +50 -0
  8. package/chunk-YKewjYmz.js +37 -0
  9. package/common.cjs +48 -8
  10. package/common.cjs.map +1 -1
  11. package/common.d.ts +53 -2
  12. package/common.js +49 -11
  13. package/common.js.map +1 -1
  14. package/complex.cjs +275 -128
  15. package/complex.cjs.map +1 -1
  16. package/complex.d.ts +66 -0
  17. package/complex.js +275 -133
  18. package/complex.js.map +1 -1
  19. package/cookie.cjs +17 -7
  20. package/cookie.cjs.map +1 -1
  21. package/cookie.d.ts +26 -0
  22. package/cookie.js +18 -9
  23. package/cookie.js.map +1 -1
  24. package/css.cjs +163 -39
  25. package/css.cjs.map +1 -1
  26. package/css.d.ts +115 -6
  27. package/css.js +159 -41
  28. package/css.js.map +1 -1
  29. package/data.cjs +90 -55
  30. package/data.cjs.map +1 -1
  31. package/data.d.ts +50 -0
  32. package/data.js +91 -61
  33. package/data.js.map +1 -1
  34. package/date-time.cjs +594 -412
  35. package/date-time.cjs.map +1 -1
  36. package/date-time.d.ts +105 -0
  37. package/date-time.js +591 -421
  38. package/date-time.js.map +1 -1
  39. package/device.cjs +65 -23
  40. package/device.cjs.map +1 -1
  41. package/device.d.ts +49 -0
  42. package/device.js +66 -31
  43. package/device.js.map +1 -1
  44. package/encodings.cjs +275 -266
  45. package/encodings.cjs.map +1 -1
  46. package/encodings.d.ts +25 -0
  47. package/encodings.js +276 -268
  48. package/encodings.js.map +1 -1
  49. package/errors.cjs +36 -18
  50. package/errors.cjs.map +1 -1
  51. package/errors.d.ts +17 -0
  52. package/errors.js +35 -19
  53. package/errors.js.map +1 -1
  54. package/file.cjs +58 -24
  55. package/file.cjs.map +1 -1
  56. package/file.d.ts +32 -0
  57. package/file.js +59 -27
  58. package/file.js.map +1 -1
  59. package/format.cjs +125 -83
  60. package/format.cjs.map +1 -1
  61. package/format.d.ts +18 -0
  62. package/format.js +118 -82
  63. package/format.js.map +1 -1
  64. package/html.cjs +242 -137
  65. package/html.cjs.map +1 -1
  66. package/html.d.ts +81 -0
  67. package/html.js +239 -150
  68. package/html.js.map +1 -1
  69. package/id.cjs +90 -17
  70. package/id.cjs.map +1 -1
  71. package/id.d.ts +16 -0
  72. package/id.js +89 -24
  73. package/id.js.map +1 -1
  74. package/imports.cjs +57 -29
  75. package/imports.cjs.map +1 -1
  76. package/imports.d.ts +24 -0
  77. package/imports.js +56 -31
  78. package/imports.js.map +1 -1
  79. package/math.cjs +32 -6
  80. package/math.cjs.map +1 -1
  81. package/math.d.ts +33 -0
  82. package/math.js +33 -10
  83. package/math.js.map +1 -1
  84. package/media.cjs +291 -84
  85. package/media.cjs.map +1 -1
  86. package/media.d.ts +204 -2
  87. package/media.js +290 -93
  88. package/media.js.map +1 -1
  89. package/mobx.cjs +449 -193
  90. package/mobx.cjs.map +1 -1
  91. package/mobx.d.ts +108 -0
  92. package/mobx.js +447 -200
  93. package/mobx.js.map +1 -1
  94. package/ms.cjs +37 -10
  95. package/ms.cjs.map +1 -1
  96. package/ms.d.ts +16 -0
  97. package/ms.js +38 -13
  98. package/ms.js.map +1 -1
  99. package/number.cjs +29 -7
  100. package/number.cjs.map +1 -1
  101. package/number.d.ts +16 -0
  102. package/number.js +30 -9
  103. package/number.js.map +1 -1
  104. package/package.json +11 -3
  105. package/parser.cjs +117 -64
  106. package/parser.cjs.map +1 -1
  107. package/parser.d.ts +17 -0
  108. package/parser.js +111 -64
  109. package/parser.js.map +1 -1
  110. package/price.cjs +24 -18
  111. package/price.cjs.map +1 -1
  112. package/price.d.ts +24 -0
  113. package/price.js +25 -20
  114. package/price.js.map +1 -1
  115. package/random.cjs +95 -13
  116. package/random.cjs.map +1 -1
  117. package/random.d.ts +80 -0
  118. package/random.js +96 -22
  119. package/random.js.map +1 -1
  120. package/react.cjs +673 -214
  121. package/react.cjs.map +1 -1
  122. package/react.d.ts +21 -0
  123. package/react.js +674 -239
  124. package/react.js.map +1 -1
  125. package/sound.cjs +30 -9
  126. package/sound.cjs.map +1 -1
  127. package/sound.d.ts +16 -0
  128. package/sound.js +31 -11
  129. package/sound.js.map +1 -1
  130. package/storage.cjs +49 -50
  131. package/storage.cjs.map +1 -1
  132. package/storage.d.ts +24 -0
  133. package/storage.js +50 -53
  134. package/storage.js.map +1 -1
  135. package/text.cjs +67 -34
  136. package/text.cjs.map +1 -1
  137. package/text.d.ts +16 -0
  138. package/text.js +68 -37
  139. package/text.js.map +1 -1
  140. package/type-guard.cjs +292 -72
  141. package/type-guard.cjs.map +1 -1
  142. package/type-guard.d.ts +18 -0
  143. package/type-guard.js +288 -73
  144. package/type-guard.js.map +1 -1
  145. package/types.cjs +0 -2
  146. package/types.d.ts +41 -0
  147. package/types.global.cjs +0 -2
  148. package/types.global.d.ts +41 -0
  149. package/types.global.js +0 -2
  150. package/types.js +0 -2
  151. package/vibrate.cjs +47 -6
  152. package/vibrate.cjs.map +1 -1
  153. package/vibrate.d.ts +39 -1
  154. package/vibrate.js +48 -8
  155. package/vibrate.js.map +1 -1
  156. package/types.cjs.map +0 -1
  157. package/types.global.cjs.map +0 -1
  158. package/types.global.js.map +0 -1
  159. package/types.js.map +0 -1
package/README.md CHANGED
@@ -15,94 +15,12 @@
15
15
  [bundlephobia-image]: https://badgen.net/bundlephobia/minzip/yummies
16
16
 
17
17
 
18
- Yummies - a set of various utilities for JavaScript projects with open source code, designed to simplify the execution of common tasks and increase performance. This project provides developers with powerful and easy-to-use functions that can be easily integrated into any JavaScript code.
19
-
20
- ## [yummies/async](src/async.ts)
21
- Utilities for working with asynchronous code
22
-
23
- ## [yummies/common](src/common.ts)
24
- All other utilities without groupping
25
-
26
- ## [yummies/cookie](src/cookie.ts)
27
- Utilities for working with cookies
28
-
29
- ## [yummies/css](src/css.ts)
30
- Utilities for working with CSS
31
-
32
- ## [yummies/date-time](src/date-time.ts)
33
- Utilities for working with dates and times (based on dayjs)
34
-
35
- ## [yummies/device](src/device.ts)
36
- Utilities for working with devices
37
-
38
- ## [yummies/html](src/html.ts)
39
- Utilities for working with HTML
40
-
41
- ## [yummies/id](src/id.ts)
42
- Utilities for working with identifiers
43
-
44
- ## [yummies/imports](src/imports.ts)
45
- Utilities for working with module imports
46
-
47
- ## [yummies/math](src/math.ts)
48
- Utilities for working with devices
49
-
50
- ## [yummies/media](src/media.ts)
51
- Utilities for working with media (image, canvas and blob)
52
-
53
- ## [yummies/ms](src/ms.ts)
54
- Utilities for working with milliseconds
55
-
56
- ## [yummies/price](src/price.ts)
57
- Utilities for working with monetary values (formatting)
58
-
59
- ## [yummies/sound](src/sound.ts)
60
- Utilities for working with sound
61
-
62
- ## [yummies/storage](src/storage.ts)
63
- Utilities for working with storage (localStorage, sessionStorage)
64
-
65
- ## [yummies/text](src/text.ts)
66
- Utilities for working with text
67
-
68
- ## [yummies/type-guard](src/type-guard.ts)
69
- Utility for type checks
70
-
71
- ## [yummies/vibrate](src/vibrate.ts)
72
- Utilities for working with vibrate api
73
-
74
- ## [yummies/types.global](src/types.ts)
75
- ## [yummies/types](src/types.ts)
76
- TypeScript utility types that simplify writing TypeScript code.
77
- They can be imported globally using the `d.ts` file, embedding it in the environment
78
- ```ts
79
- import 'yummies/types.global';
80
- ```
81
- Or specified in `tsconfig.json` in the `"types"` field
82
- ```json
83
- {
84
- "compilerOptions": {
85
- "types": [
86
- "yummies/types.global"
87
- ],
88
- "target": "...blabla",
89
- ...
90
- }
91
- ...
92
- }
93
- ```
94
- Alternatively, you can use the "library" approach, where you need exported types.
95
- For this, you can use the `yummies` or `yummies/types` import.
96
-
97
- ```ts
98
- import { AnyObject } from 'yummies';
99
- ```
100
-
101
-
102
- ## [yummies/complex](src/complex/index.ts)
103
-
104
- Additional set of complex utilities
18
+ `yummies` - a set of various utilities for JavaScript projects with open source code,
19
+ designed to simplify the execution of common tasks and increase performance.
20
+ This project provides developers with powerful and easy-to-use functions
21
+ that can be easily integrated into any JavaScript code.
105
22
 
23
+ ## [Read the docs →](https://js2me.github.io/yummies/)
106
24
 
107
25
  ## Migration from 5.x to 6.x
108
26
 
package/async.cjs CHANGED
@@ -1,60 +1,191 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const sleep = (time = 0, signal) => new Promise((resolve, reject) => {
4
- if (signal) {
5
- const abortListener = () => {
6
- clearTimeout(timerId);
7
- reject(signal?.reason);
8
- };
9
- const timerId = setTimeout(() => {
10
- signal.removeEventListener("abort", abortListener);
11
- resolve();
12
- }, time);
13
- signal.addEventListener("abort", abortListener, { once: true });
14
- } else {
15
- setTimeout(resolve, time);
16
- }
2
+ //#region src/async.ts
3
+ /**
4
+ * ---header-docs-section---
5
+ * # yummies/async
6
+ *
7
+ * ## Description
8
+ *
9
+ * Helpers for asynchronous control flow: delays, cancellable waits, scheduling on the next frame,
10
+ * and small utilities around `requestAnimationFrame` and `queueMicrotask`. They complement native
11
+ * `Promise`/`AbortSignal` patterns and keep timing logic easy to test and tree-shake per call site.
12
+ * Import only what you need from `yummies/async` so bundlers can drop unused helpers.
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ```ts
17
+ * import { sleep } from "yummies/async";
18
+ * ```
19
+ */
20
+ /**
21
+ * Returns a promise that resolves after `time` milliseconds.
22
+ *
23
+ * When `signal` is passed and becomes aborted before the delay elapses, the promise
24
+ * rejects with `signal.reason` (same as native `fetch` / `AbortController` usage).
25
+ * The timeout is cleared on abort so no resolve happens after cancellation.
26
+ *
27
+ * @param time - Delay in milliseconds. Defaults to `0` (next macrotask tick, same idea as `setTimeout(0)`).
28
+ * @param signal - Optional `AbortSignal` to cancel the wait early.
29
+ * @returns A promise that resolves with `void` when the delay completes, or rejects if aborted.
30
+ *
31
+ * @example
32
+ * Basic pause in an async function:
33
+ * ```ts
34
+ * await sleep(250);
35
+ * console.log('after 250ms');
36
+ * ```
37
+ *
38
+ * @example
39
+ * Cancellable delay tied to component unmount or user action:
40
+ * ```ts
41
+ * const ac = new AbortController();
42
+ * try {
43
+ * await sleep(5000, ac.signal);
44
+ * } catch (e) {
45
+ * // aborted — e is signal.reason
46
+ * }
47
+ * ac.abort('user cancelled');
48
+ * ```
49
+ */
50
+ var sleep = (time = 0, signal) => new Promise((resolve, reject) => {
51
+ if (signal) {
52
+ const abortListener = () => {
53
+ clearTimeout(timerId);
54
+ reject(signal?.reason);
55
+ };
56
+ const timerId = setTimeout(() => {
57
+ signal.removeEventListener("abort", abortListener);
58
+ resolve();
59
+ }, time);
60
+ signal.addEventListener("abort", abortListener, { once: true });
61
+ } else setTimeout(resolve, time);
17
62
  });
18
- const waitAsync = async (ms = 1e3) => new Promise((resolve) => setTimeout(resolve, ms));
19
- const endlessRAF = (quitFunction, asMicrotask) => {
20
- if (quitFunction()) return;
21
- const raf = () => requestAnimationFrame(() => endlessRAF(quitFunction, asMicrotask));
22
- if (asMicrotask) {
23
- queueMicrotask(raf);
24
- } else {
25
- raf();
26
- }
63
+ /**
64
+ * Creates a promise that resolves after the specified number of milliseconds.
65
+ *
66
+ * @deprecated Use `sleep` instead.
67
+ * @param ms Delay in milliseconds.
68
+ * @returns Promise
69
+ */
70
+ var waitAsync = async (ms = 1e3) => new Promise((resolve) => setTimeout(resolve, ms));
71
+ /**
72
+ * Runs a loop driven by `requestAnimationFrame`: on each frame, `quitFunction` is called first.
73
+ * If it returns a truthy value, the loop stops and no further frames are scheduled.
74
+ * If it returns falsy or nothing, the next frame is scheduled recursively.
75
+ *
76
+ * Use this for per-frame work (animations, layout reads after paint) without managing
77
+ * `cancelAnimationFrame` manually — returning `true` from `quitFunction` is the exit condition.
78
+ *
79
+ * When `asMicrotask` is `true`, scheduling the next RAF is deferred with `queueMicrotask`
80
+ * so other microtasks can run before the frame is requested (useful when you need to
81
+ * batch DOM updates or let reactive frameworks flush first).
82
+ *
83
+ * @param quitFunction - Invoked each animation frame. Return `true` to stop the loop.
84
+ * @param asMicrotask - If `true`, wrap the `requestAnimationFrame` call in `queueMicrotask`.
85
+ *
86
+ * @example
87
+ * Stop after 60 frames (~1s at 60Hz):
88
+ * ```ts
89
+ * let frames = 0;
90
+ * endlessRAF(() => {
91
+ * frames++;
92
+ * updateSomething(frames);
93
+ * return frames >= 60;
94
+ * });
95
+ * ```
96
+ *
97
+ * @example
98
+ * Run until an element is removed or a flag is set:
99
+ * ```ts
100
+ * let running = true;
101
+ * endlessRAF(() => {
102
+ * if (!running || !document.body.contains(el)) return true;
103
+ * draw(el);
104
+ * }, true);
105
+ * ```
106
+ */
107
+ var endlessRAF = (quitFunction, asMicrotask) => {
108
+ if (quitFunction()) return;
109
+ const raf = () => requestAnimationFrame(() => endlessRAF(quitFunction, asMicrotask));
110
+ if (asMicrotask) queueMicrotask(raf);
111
+ else raf();
27
112
  };
113
+ /**
114
+ * Like `setTimeout`, but if `signal` aborts before the delay fires, the timer is cleared
115
+ * and `callback` is never run. If the callback runs normally, the abort listener is removed.
116
+ *
117
+ * Does nothing special if `signal` is omitted — behaves like a plain timeout.
118
+ *
119
+ * @param callback - Function to run once after `delayInMs` (same as `setTimeout` callback).
120
+ * @param delayInMs - Milliseconds to wait. Passed through to `setTimeout` (browser/Node semantics apply).
121
+ * @param signal - When aborted, clears the pending timeout so `callback` is not invoked.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * const controller = new AbortController();
126
+ * setAbortableTimeout(() => console.log('done'), 500, controller.signal);
127
+ * // later: controller.abort(); // timeout cancelled, log never runs
128
+ * ```
129
+ *
130
+ * @example
131
+ * Zero-delay scheduling that can still be cancelled before the macrotask runs:
132
+ * ```ts
133
+ * const ac = new AbortController();
134
+ * setAbortableTimeout(() => startIntro(), 0, ac.signal);
135
+ * // e.g. on teardown: ac.abort();
136
+ * ```
137
+ */
28
138
  function setAbortableTimeout(callback, delayInMs, signal) {
29
- let internalTimer = null;
30
- const handleAbort = () => {
31
- if (internalTimer == null) {
32
- return;
33
- }
34
- clearTimeout(internalTimer);
35
- internalTimer = null;
36
- };
37
- signal?.addEventListener("abort", handleAbort, { once: true });
38
- internalTimer = setTimeout(() => {
39
- signal?.removeEventListener("abort", handleAbort);
40
- callback();
41
- }, delayInMs);
139
+ let internalTimer = null;
140
+ const handleAbort = () => {
141
+ if (internalTimer == null) return;
142
+ clearTimeout(internalTimer);
143
+ internalTimer = null;
144
+ };
145
+ signal?.addEventListener("abort", handleAbort, { once: true });
146
+ internalTimer = setTimeout(() => {
147
+ signal?.removeEventListener("abort", handleAbort);
148
+ callback();
149
+ }, delayInMs);
42
150
  }
151
+ /**
152
+ * Like `setInterval`, but when `signal` aborts, the interval is cleared with `clearInterval`
153
+ * and `callback` stops being called. If `signal` is omitted, behaves like a normal interval
154
+ * (you must clear it yourself).
155
+ *
156
+ * @param callback - Invoked every `delayInMs` milliseconds until aborted or cleared.
157
+ * @param delayInMs - Interval period in milliseconds (same as `setInterval`).
158
+ * @param signal - Aborting stops the interval and removes the abort listener path from keeping work alive.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * const controller = new AbortController();
163
+ * setAbortableInterval(() => console.log('tick'), 1000, controller.signal);
164
+ * // stop: controller.abort();
165
+ * ```
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const ac = new AbortController();
170
+ * setAbortableInterval(syncStatus, 30_000, ac.signal);
171
+ * window.addEventListener('beforeunload', () => ac.abort());
172
+ * ```
173
+ */
43
174
  function setAbortableInterval(callback, delayInMs, signal) {
44
- let timer = null;
45
- const handleAbort = () => {
46
- if (timer == null) {
47
- return;
48
- }
49
- clearInterval(timer);
50
- timer = null;
51
- };
52
- signal?.addEventListener("abort", handleAbort, { once: true });
53
- timer = setInterval(callback, delayInMs);
175
+ let timer = null;
176
+ const handleAbort = () => {
177
+ if (timer == null) return;
178
+ clearInterval(timer);
179
+ timer = null;
180
+ };
181
+ signal?.addEventListener("abort", handleAbort, { once: true });
182
+ timer = setInterval(callback, delayInMs);
54
183
  }
184
+ //#endregion
55
185
  exports.endlessRAF = endlessRAF;
56
186
  exports.setAbortableInterval = setAbortableInterval;
57
187
  exports.setAbortableTimeout = setAbortableTimeout;
58
188
  exports.sleep = sleep;
59
189
  exports.waitAsync = waitAsync;
60
- //# sourceMappingURL=async.cjs.map
190
+
191
+ //# sourceMappingURL=async.cjs.map
package/async.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"async.cjs","sources":["../src/async.ts"],"sourcesContent":["/**\n * Creates a promise that resolves after the specified number of milliseconds.\n *\n * @param time Delay in milliseconds.\n * @returns Promise\n */\nexport const sleep = (time: number = 0, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal) {\n const abortListener = () => {\n clearTimeout(timerId);\n reject(signal?.reason);\n };\n const timerId = setTimeout(() => {\n signal.removeEventListener('abort', abortListener);\n resolve();\n }, time);\n signal.addEventListener('abort', abortListener, { once: true });\n } else {\n setTimeout(resolve, time);\n }\n });\n\n/**\n * Creates a promise that resolves after the specified number of milliseconds.\n *\n * @deprecated Use `sleep` instead.\n * @param ms Delay in milliseconds.\n * @returns Promise\n */\nexport const waitAsync = async (ms = 1000) =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Repeatedly schedules `requestAnimationFrame` until `quitFunction` returns `true`.\n *\n * @param quitFunction Function executed on each animation frame.\n * @param asMicrotask Additionally wraps the RAF scheduling in `queueMicrotask`.\n * @returns void\n */\nexport const endlessRAF = (\n quitFunction: () => boolean | void,\n asMicrotask?: boolean,\n) => {\n if (quitFunction()) return;\n\n const raf = () =>\n requestAnimationFrame(() => endlessRAF(quitFunction, asMicrotask));\n\n if (asMicrotask) {\n queueMicrotask(raf);\n } else {\n raf();\n }\n};\n\nexport function setAbortableTimeout(\n callback: VoidFunction,\n delayInMs?: number,\n signal?: AbortSignal,\n) {\n let internalTimer: number | null = null;\n\n const handleAbort = () => {\n if (internalTimer == null) {\n return;\n }\n clearTimeout(internalTimer);\n internalTimer = null;\n };\n\n signal?.addEventListener('abort', handleAbort, { once: true });\n\n internalTimer = setTimeout(() => {\n signal?.removeEventListener('abort', handleAbort);\n callback();\n }, delayInMs);\n}\n\nexport function setAbortableInterval(\n callback: VoidFunction,\n delayInMs?: number,\n signal?: AbortSignal,\n) {\n let timer: number | null = null;\n\n const handleAbort = () => {\n if (timer == null) {\n return;\n }\n clearInterval(timer);\n timer = null;\n };\n\n signal?.addEventListener('abort', handleAbort, { once: true });\n\n timer = setInterval(callback, delayInMs);\n}\n"],"names":[],"mappings":";;AAMO,MAAM,QAAQ,CAAC,OAAe,GAAG,WACtC,IAAI,QAAc,CAAC,SAAS,WAAW;AACrC,MAAI,QAAQ;AACV,UAAM,gBAAgB,MAAM;AAC1B,mBAAa,OAAO;AACpB,aAAO,QAAQ,MAAM;AAAA,IACvB;AACA,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,oBAAoB,SAAS,aAAa;AACjD,cAAA;AAAA,IACF,GAAG,IAAI;AACP,WAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,MAAM;AAAA,EAChE,OAAO;AACL,eAAW,SAAS,IAAI;AAAA,EAC1B;AACF,CAAC;AASI,MAAM,YAAY,OAAO,KAAK,QACnC,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAS3C,MAAM,aAAa,CACxB,cACA,gBACG;AACH,MAAI,eAAgB;AAEpB,QAAM,MAAM,MACV,sBAAsB,MAAM,WAAW,cAAc,WAAW,CAAC;AAEnE,MAAI,aAAa;AACf,mBAAe,GAAG;AAAA,EACpB,OAAO;AACL,QAAA;AAAA,EACF;AACF;AAEO,SAAS,oBACd,UACA,WACA,QACA;AACA,MAAI,gBAA+B;AAEnC,QAAM,cAAc,MAAM;AACxB,QAAI,iBAAiB,MAAM;AACzB;AAAA,IACF;AACA,iBAAa,aAAa;AAC1B,oBAAgB;AAAA,EAClB;AAEA,UAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,MAAM;AAE7D,kBAAgB,WAAW,MAAM;AAC/B,YAAQ,oBAAoB,SAAS,WAAW;AAChD,aAAA;AAAA,EACF,GAAG,SAAS;AACd;AAEO,SAAS,qBACd,UACA,WACA,QACA;AACA,MAAI,QAAuB;AAE3B,QAAM,cAAc,MAAM;AACxB,QAAI,SAAS,MAAM;AACjB;AAAA,IACF;AACA,kBAAc,KAAK;AACnB,YAAQ;AAAA,EACV;AAEA,UAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,MAAM;AAE7D,UAAQ,YAAY,UAAU,SAAS;AACzC;;;;;;"}
1
+ {"version":3,"file":"async.cjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/async\n *\n * ## Description\n *\n * Helpers for asynchronous control flow: delays, cancellable waits, scheduling on the next frame,\n * and small utilities around `requestAnimationFrame` and `queueMicrotask`. They complement native\n * `Promise`/`AbortSignal` patterns and keep timing logic easy to test and tree-shake per call site.\n * Import only what you need from `yummies/async` so bundlers can drop unused helpers.\n *\n * ## Usage\n *\n * ```ts\n * import { sleep } from \"yummies/async\";\n * ```\n */\n\n/**\n * Returns a promise that resolves after `time` milliseconds.\n *\n * When `signal` is passed and becomes aborted before the delay elapses, the promise\n * rejects with `signal.reason` (same as native `fetch` / `AbortController` usage).\n * The timeout is cleared on abort so no resolve happens after cancellation.\n *\n * @param time - Delay in milliseconds. Defaults to `0` (next macrotask tick, same idea as `setTimeout(0)`).\n * @param signal - Optional `AbortSignal` to cancel the wait early.\n * @returns A promise that resolves with `void` when the delay completes, or rejects if aborted.\n *\n * @example\n * Basic pause in an async function:\n * ```ts\n * await sleep(250);\n * console.log('after 250ms');\n * ```\n *\n * @example\n * Cancellable delay tied to component unmount or user action:\n * ```ts\n * const ac = new AbortController();\n * try {\n * await sleep(5000, ac.signal);\n * } catch (e) {\n * // aborted — e is signal.reason\n * }\n * ac.abort('user cancelled');\n * ```\n */\nexport const sleep = (time: number = 0, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal) {\n const abortListener = () => {\n clearTimeout(timerId);\n reject(signal?.reason);\n };\n const timerId = setTimeout(() => {\n signal.removeEventListener('abort', abortListener);\n resolve();\n }, time);\n signal.addEventListener('abort', abortListener, { once: true });\n } else {\n setTimeout(resolve, time);\n }\n });\n\n/**\n * Creates a promise that resolves after the specified number of milliseconds.\n *\n * @deprecated Use `sleep` instead.\n * @param ms Delay in milliseconds.\n * @returns Promise\n */\nexport const waitAsync = async (ms = 1000) =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Runs a loop driven by `requestAnimationFrame`: on each frame, `quitFunction` is called first.\n * If it returns a truthy value, the loop stops and no further frames are scheduled.\n * If it returns falsy or nothing, the next frame is scheduled recursively.\n *\n * Use this for per-frame work (animations, layout reads after paint) without managing\n * `cancelAnimationFrame` manually — returning `true` from `quitFunction` is the exit condition.\n *\n * When `asMicrotask` is `true`, scheduling the next RAF is deferred with `queueMicrotask`\n * so other microtasks can run before the frame is requested (useful when you need to\n * batch DOM updates or let reactive frameworks flush first).\n *\n * @param quitFunction - Invoked each animation frame. Return `true` to stop the loop.\n * @param asMicrotask - If `true`, wrap the `requestAnimationFrame` call in `queueMicrotask`.\n *\n * @example\n * Stop after 60 frames (~1s at 60Hz):\n * ```ts\n * let frames = 0;\n * endlessRAF(() => {\n * frames++;\n * updateSomething(frames);\n * return frames >= 60;\n * });\n * ```\n *\n * @example\n * Run until an element is removed or a flag is set:\n * ```ts\n * let running = true;\n * endlessRAF(() => {\n * if (!running || !document.body.contains(el)) return true;\n * draw(el);\n * }, true);\n * ```\n */\nexport const endlessRAF = (\n quitFunction: () => boolean | void,\n asMicrotask?: boolean,\n) => {\n if (quitFunction()) return;\n\n const raf = () =>\n requestAnimationFrame(() => endlessRAF(quitFunction, asMicrotask));\n\n if (asMicrotask) {\n queueMicrotask(raf);\n } else {\n raf();\n }\n};\n\n/**\n * Like `setTimeout`, but if `signal` aborts before the delay fires, the timer is cleared\n * and `callback` is never run. If the callback runs normally, the abort listener is removed.\n *\n * Does nothing special if `signal` is omitted — behaves like a plain timeout.\n *\n * @param callback - Function to run once after `delayInMs` (same as `setTimeout` callback).\n * @param delayInMs - Milliseconds to wait. Passed through to `setTimeout` (browser/Node semantics apply).\n * @param signal - When aborted, clears the pending timeout so `callback` is not invoked.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * setAbortableTimeout(() => console.log('done'), 500, controller.signal);\n * // later: controller.abort(); // timeout cancelled, log never runs\n * ```\n *\n * @example\n * Zero-delay scheduling that can still be cancelled before the macrotask runs:\n * ```ts\n * const ac = new AbortController();\n * setAbortableTimeout(() => startIntro(), 0, ac.signal);\n * // e.g. on teardown: ac.abort();\n * ```\n */\nexport function setAbortableTimeout(\n callback: VoidFunction,\n delayInMs?: number,\n signal?: AbortSignal,\n) {\n let internalTimer: number | null = null;\n\n const handleAbort = () => {\n if (internalTimer == null) {\n return;\n }\n clearTimeout(internalTimer);\n internalTimer = null;\n };\n\n signal?.addEventListener('abort', handleAbort, { once: true });\n\n internalTimer = setTimeout(() => {\n signal?.removeEventListener('abort', handleAbort);\n callback();\n }, delayInMs);\n}\n\n/**\n * Like `setInterval`, but when `signal` aborts, the interval is cleared with `clearInterval`\n * and `callback` stops being called. If `signal` is omitted, behaves like a normal interval\n * (you must clear it yourself).\n *\n * @param callback - Invoked every `delayInMs` milliseconds until aborted or cleared.\n * @param delayInMs - Interval period in milliseconds (same as `setInterval`).\n * @param signal - Aborting stops the interval and removes the abort listener path from keeping work alive.\n *\n * @example\n * ```ts\n * const controller = new AbortController();\n * setAbortableInterval(() => console.log('tick'), 1000, controller.signal);\n * // stop: controller.abort();\n * ```\n *\n * @example\n * ```ts\n * const ac = new AbortController();\n * setAbortableInterval(syncStatus, 30_000, ac.signal);\n * window.addEventListener('beforeunload', () => ac.abort());\n * ```\n */\nexport function setAbortableInterval(\n callback: VoidFunction,\n delayInMs?: number,\n signal?: AbortSignal,\n) {\n let timer: number | null = null;\n\n const handleAbort = () => {\n if (timer == null) {\n return;\n }\n clearInterval(timer);\n timer = null;\n };\n\n signal?.addEventListener('abort', handleAbort, { once: true });\n\n timer = setInterval(callback, delayInMs);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,IAAa,SAAS,OAAe,GAAG,WACtC,IAAI,SAAe,SAAS,WAAW;AACrC,KAAI,QAAQ;EACV,MAAM,sBAAsB;AAC1B,gBAAa,QAAQ;AACrB,UAAO,QAAQ,OAAO;;EAExB,MAAM,UAAU,iBAAiB;AAC/B,UAAO,oBAAoB,SAAS,cAAc;AAClD,YAAS;KACR,KAAK;AACR,SAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,MAAM,CAAC;OAE/D,YAAW,SAAS,KAAK;EAE3B;;;;;;;;AASJ,IAAa,YAAY,OAAO,KAAK,QACnC,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCnD,IAAa,cACX,cACA,gBACG;AACH,KAAI,cAAc,CAAE;CAEpB,MAAM,YACJ,4BAA4B,WAAW,cAAc,YAAY,CAAC;AAEpE,KAAI,YACF,gBAAe,IAAI;KAEnB,MAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BT,SAAgB,oBACd,UACA,WACA,QACA;CACA,IAAI,gBAA+B;CAEnC,MAAM,oBAAoB;AACxB,MAAI,iBAAiB,KACnB;AAEF,eAAa,cAAc;AAC3B,kBAAgB;;AAGlB,SAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,MAAM,CAAC;AAE9D,iBAAgB,iBAAiB;AAC/B,UAAQ,oBAAoB,SAAS,YAAY;AACjD,YAAU;IACT,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;AA0Bf,SAAgB,qBACd,UACA,WACA,QACA;CACA,IAAI,QAAuB;CAE3B,MAAM,oBAAoB;AACxB,MAAI,SAAS,KACX;AAEF,gBAAc,MAAM;AACpB,UAAQ;;AAGV,SAAQ,iBAAiB,SAAS,aAAa,EAAE,MAAM,MAAM,CAAC;AAE9D,SAAQ,YAAY,UAAU,UAAU"}
package/async.d.ts CHANGED
@@ -1,8 +1,49 @@
1
1
  /**
2
- * Creates a promise that resolves after the specified number of milliseconds.
2
+ * ---header-docs-section---
3
+ * # yummies/async
3
4
  *
4
- * @param time Delay in milliseconds.
5
- * @returns Promise
5
+ * ## Description
6
+ *
7
+ * Helpers for asynchronous control flow: delays, cancellable waits, scheduling on the next frame,
8
+ * and small utilities around `requestAnimationFrame` and `queueMicrotask`. They complement native
9
+ * `Promise`/`AbortSignal` patterns and keep timing logic easy to test and tree-shake per call site.
10
+ * Import only what you need from `yummies/async` so bundlers can drop unused helpers.
11
+ *
12
+ * ## Usage
13
+ *
14
+ * ```ts
15
+ * import { sleep } from "yummies/async";
16
+ * ```
17
+ */
18
+ /**
19
+ * Returns a promise that resolves after `time` milliseconds.
20
+ *
21
+ * When `signal` is passed and becomes aborted before the delay elapses, the promise
22
+ * rejects with `signal.reason` (same as native `fetch` / `AbortController` usage).
23
+ * The timeout is cleared on abort so no resolve happens after cancellation.
24
+ *
25
+ * @param time - Delay in milliseconds. Defaults to `0` (next macrotask tick, same idea as `setTimeout(0)`).
26
+ * @param signal - Optional `AbortSignal` to cancel the wait early.
27
+ * @returns A promise that resolves with `void` when the delay completes, or rejects if aborted.
28
+ *
29
+ * @example
30
+ * Basic pause in an async function:
31
+ * ```ts
32
+ * await sleep(250);
33
+ * console.log('after 250ms');
34
+ * ```
35
+ *
36
+ * @example
37
+ * Cancellable delay tied to component unmount or user action:
38
+ * ```ts
39
+ * const ac = new AbortController();
40
+ * try {
41
+ * await sleep(5000, ac.signal);
42
+ * } catch (e) {
43
+ * // aborted — e is signal.reason
44
+ * }
45
+ * ac.abort('user cancelled');
46
+ * ```
6
47
  */
7
48
  declare const sleep: (time?: number, signal?: AbortSignal) => Promise<void>;
8
49
  /**
@@ -14,14 +55,91 @@ declare const sleep: (time?: number, signal?: AbortSignal) => Promise<void>;
14
55
  */
15
56
  declare const waitAsync: (ms?: number) => Promise<unknown>;
16
57
  /**
17
- * Repeatedly schedules `requestAnimationFrame` until `quitFunction` returns `true`.
58
+ * Runs a loop driven by `requestAnimationFrame`: on each frame, `quitFunction` is called first.
59
+ * If it returns a truthy value, the loop stops and no further frames are scheduled.
60
+ * If it returns falsy or nothing, the next frame is scheduled recursively.
61
+ *
62
+ * Use this for per-frame work (animations, layout reads after paint) without managing
63
+ * `cancelAnimationFrame` manually — returning `true` from `quitFunction` is the exit condition.
64
+ *
65
+ * When `asMicrotask` is `true`, scheduling the next RAF is deferred with `queueMicrotask`
66
+ * so other microtasks can run before the frame is requested (useful when you need to
67
+ * batch DOM updates or let reactive frameworks flush first).
18
68
  *
19
- * @param quitFunction Function executed on each animation frame.
20
- * @param asMicrotask Additionally wraps the RAF scheduling in `queueMicrotask`.
21
- * @returns void
69
+ * @param quitFunction - Invoked each animation frame. Return `true` to stop the loop.
70
+ * @param asMicrotask - If `true`, wrap the `requestAnimationFrame` call in `queueMicrotask`.
71
+ *
72
+ * @example
73
+ * Stop after 60 frames (~1s at 60Hz):
74
+ * ```ts
75
+ * let frames = 0;
76
+ * endlessRAF(() => {
77
+ * frames++;
78
+ * updateSomething(frames);
79
+ * return frames >= 60;
80
+ * });
81
+ * ```
82
+ *
83
+ * @example
84
+ * Run until an element is removed or a flag is set:
85
+ * ```ts
86
+ * let running = true;
87
+ * endlessRAF(() => {
88
+ * if (!running || !document.body.contains(el)) return true;
89
+ * draw(el);
90
+ * }, true);
91
+ * ```
22
92
  */
23
93
  declare const endlessRAF: (quitFunction: () => boolean | void, asMicrotask?: boolean) => void;
94
+ /**
95
+ * Like `setTimeout`, but if `signal` aborts before the delay fires, the timer is cleared
96
+ * and `callback` is never run. If the callback runs normally, the abort listener is removed.
97
+ *
98
+ * Does nothing special if `signal` is omitted — behaves like a plain timeout.
99
+ *
100
+ * @param callback - Function to run once after `delayInMs` (same as `setTimeout` callback).
101
+ * @param delayInMs - Milliseconds to wait. Passed through to `setTimeout` (browser/Node semantics apply).
102
+ * @param signal - When aborted, clears the pending timeout so `callback` is not invoked.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * const controller = new AbortController();
107
+ * setAbortableTimeout(() => console.log('done'), 500, controller.signal);
108
+ * // later: controller.abort(); // timeout cancelled, log never runs
109
+ * ```
110
+ *
111
+ * @example
112
+ * Zero-delay scheduling that can still be cancelled before the macrotask runs:
113
+ * ```ts
114
+ * const ac = new AbortController();
115
+ * setAbortableTimeout(() => startIntro(), 0, ac.signal);
116
+ * // e.g. on teardown: ac.abort();
117
+ * ```
118
+ */
24
119
  declare function setAbortableTimeout(callback: VoidFunction, delayInMs?: number, signal?: AbortSignal): void;
120
+ /**
121
+ * Like `setInterval`, but when `signal` aborts, the interval is cleared with `clearInterval`
122
+ * and `callback` stops being called. If `signal` is omitted, behaves like a normal interval
123
+ * (you must clear it yourself).
124
+ *
125
+ * @param callback - Invoked every `delayInMs` milliseconds until aborted or cleared.
126
+ * @param delayInMs - Interval period in milliseconds (same as `setInterval`).
127
+ * @param signal - Aborting stops the interval and removes the abort listener path from keeping work alive.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * const controller = new AbortController();
132
+ * setAbortableInterval(() => console.log('tick'), 1000, controller.signal);
133
+ * // stop: controller.abort();
134
+ * ```
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * const ac = new AbortController();
139
+ * setAbortableInterval(syncStatus, 30_000, ac.signal);
140
+ * window.addEventListener('beforeunload', () => ac.abort());
141
+ * ```
142
+ */
25
143
  declare function setAbortableInterval(callback: VoidFunction, delayInMs?: number, signal?: AbortSignal): void;
26
144
 
27
145
  export { endlessRAF, setAbortableInterval, setAbortableTimeout, sleep, waitAsync };