yummies 7.12.0 → 7.14.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 (127) hide show
  1. package/README.md +5 -87
  2. package/assert.cjs +146 -0
  3. package/assert.cjs.map +1 -0
  4. package/assert.d.ts +134 -0
  5. package/assert.js +140 -0
  6. package/assert.js.map +1 -0
  7. package/async.cjs +17 -0
  8. package/async.cjs.map +1 -1
  9. package/async.d.ts +17 -0
  10. package/async.js +17 -0
  11. package/async.js.map +1 -1
  12. package/common.cjs.map +1 -1
  13. package/common.d.ts +18 -0
  14. package/common.js.map +1 -1
  15. package/complex.cjs.map +1 -1
  16. package/complex.d.ts +66 -0
  17. package/complex.js.map +1 -1
  18. package/cookie.cjs.map +1 -1
  19. package/cookie.d.ts +18 -0
  20. package/cookie.js.map +1 -1
  21. package/css.cjs +16 -0
  22. package/css.cjs.map +1 -1
  23. package/css.d.ts +17 -0
  24. package/css.js +16 -0
  25. package/css.js.map +1 -1
  26. package/data.cjs.map +1 -1
  27. package/data.d.ts +18 -0
  28. package/data.js.map +1 -1
  29. package/date-time.cjs +16 -0
  30. package/date-time.cjs.map +1 -1
  31. package/date-time.d.ts +17 -0
  32. package/date-time.js +16 -0
  33. package/date-time.js.map +1 -1
  34. package/device.cjs +17 -0
  35. package/device.cjs.map +1 -1
  36. package/device.d.ts +17 -0
  37. package/device.js +17 -0
  38. package/device.js.map +1 -1
  39. package/encodings.cjs.map +1 -1
  40. package/encodings.d.ts +17 -0
  41. package/encodings.js.map +1 -1
  42. package/errors.cjs +16 -0
  43. package/errors.cjs.map +1 -1
  44. package/errors.d.ts +17 -0
  45. package/errors.js +16 -0
  46. package/errors.js.map +1 -1
  47. package/file.cjs +16 -0
  48. package/file.cjs.map +1 -1
  49. package/file.d.ts +16 -0
  50. package/file.js +16 -0
  51. package/file.js.map +1 -1
  52. package/format.cjs.map +1 -1
  53. package/format.d.ts +18 -0
  54. package/format.js.map +1 -1
  55. package/html.cjs +16 -0
  56. package/html.cjs.map +1 -1
  57. package/html.d.ts +17 -0
  58. package/html.js +16 -0
  59. package/html.js.map +1 -1
  60. package/id.cjs +16 -0
  61. package/id.cjs.map +1 -1
  62. package/id.d.ts +16 -0
  63. package/id.js +16 -0
  64. package/id.js.map +1 -1
  65. package/imports.cjs +16 -0
  66. package/imports.cjs.map +1 -1
  67. package/imports.d.ts +16 -0
  68. package/imports.js +16 -0
  69. package/imports.js.map +1 -1
  70. package/math.cjs.map +1 -1
  71. package/math.d.ts +17 -0
  72. package/math.js.map +1 -1
  73. package/media.cjs +16 -0
  74. package/media.cjs.map +1 -1
  75. package/media.d.ts +16 -0
  76. package/media.js +16 -0
  77. package/media.js.map +1 -1
  78. package/mobx.cjs +96 -0
  79. package/mobx.cjs.map +1 -1
  80. package/mobx.d.ts +101 -0
  81. package/mobx.js +96 -0
  82. package/mobx.js.map +1 -1
  83. package/ms.cjs +16 -0
  84. package/ms.cjs.map +1 -1
  85. package/ms.d.ts +16 -0
  86. package/ms.js +16 -0
  87. package/ms.js.map +1 -1
  88. package/number.cjs +16 -0
  89. package/number.cjs.map +1 -1
  90. package/number.d.ts +16 -0
  91. package/number.js +16 -0
  92. package/number.js.map +1 -1
  93. package/package.json +8 -2
  94. package/parser.cjs.map +1 -1
  95. package/parser.d.ts +17 -0
  96. package/parser.js.map +1 -1
  97. package/price.cjs.map +1 -1
  98. package/price.d.ts +16 -0
  99. package/price.js.map +1 -1
  100. package/random.cjs +16 -0
  101. package/random.cjs.map +1 -1
  102. package/random.d.ts +16 -0
  103. package/random.js +16 -0
  104. package/random.js.map +1 -1
  105. package/sound.cjs +16 -0
  106. package/sound.cjs.map +1 -1
  107. package/sound.d.ts +16 -0
  108. package/sound.js +16 -0
  109. package/sound.js.map +1 -1
  110. package/storage.cjs.map +1 -1
  111. package/storage.d.ts +16 -0
  112. package/storage.js.map +1 -1
  113. package/text.cjs +16 -0
  114. package/text.cjs.map +1 -1
  115. package/text.d.ts +16 -0
  116. package/text.js +16 -0
  117. package/text.js.map +1 -1
  118. package/type-guard.cjs.map +1 -1
  119. package/type-guard.d.ts +18 -0
  120. package/type-guard.js.map +1 -1
  121. package/types.d.ts +41 -0
  122. package/types.global.d.ts +41 -0
  123. package/vibrate.cjs +16 -0
  124. package/vibrate.cjs.map +1 -1
  125. package/vibrate.d.ts +16 -0
  126. package/vibrate.js +16 -0
  127. package/vibrate.js.map +1 -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/assert.cjs ADDED
@@ -0,0 +1,146 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_chunk = require("./chunk-CVq3Gv4J.cjs");
3
+ let yummies_common = require("yummies/common");
4
+ //#region src/assert/_exports.ts
5
+ /**
6
+ * ---header-docs-section---
7
+ * # yummies/assert
8
+ *
9
+ * ## Description
10
+ *
11
+ * Runtime **assertions** for invariants, narrowing, and exhaustiveness. Helpers throw
12
+ * {@link AssertionError} with an optional message (`string` or {@link MaybeFn}) so failing fast stays
13
+ * explicit without a heavy assertion library. Use `assert.ok`, `assert.defined`, `assert.fail`, and
14
+ * the rest on the namespace export from the package entry.
15
+ *
16
+ * ## Usage
17
+ *
18
+ * ```ts
19
+ * import { assert } from "yummies/assert";
20
+ *
21
+ * assert.ok(user.id, "user id is required");
22
+ * assert.defined(maybeName);
23
+ * ```
24
+ */
25
+ var _exports_exports = /* @__PURE__ */ require_chunk.__exportAll({
26
+ AssertionError: () => AssertionError,
27
+ defined: () => defined,
28
+ fail: () => fail,
29
+ instanceOf: () => instanceOf,
30
+ invariant: () => invariant,
31
+ never: () => unreachable,
32
+ notNull: () => notNull,
33
+ notUndefined: () => notUndefined,
34
+ ok: () => ok,
35
+ unreachable: () => unreachable
36
+ });
37
+ /**
38
+ * Error thrown by assertion helpers in this module.
39
+ */
40
+ var AssertionError = class extends Error {
41
+ name = "AssertionError";
42
+ };
43
+ function resolveAssertMessage(message, fallback) {
44
+ if (message === void 0) return fallback;
45
+ return (0, yummies_common.callFunction)(message);
46
+ }
47
+ /**
48
+ * Throws when `condition` is falsy; narrows the type when it is truthy.
49
+ *
50
+ * @param condition Value treated as a boolean guard.
51
+ * @param message Optional message or lazy message factory.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * assert.ok(user.id, "user id is required");
56
+ * ```
57
+ */
58
+ function ok(condition, message) {
59
+ if (!condition) throw new AssertionError(resolveAssertMessage(message, "Assertion failed"));
60
+ }
61
+ /**
62
+ * Same as {@link ok}; common alias for internal invariants (e.g. after optional checks).
63
+ */
64
+ var invariant = ok;
65
+ /**
66
+ * Throws when the value is `null` or `undefined`; otherwise narrows away nullish.
67
+ *
68
+ * @param value Possibly nullish value.
69
+ * @param message Optional message or lazy message factory.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * assert.defined(maybeName, "name must be present");
74
+ * ```
75
+ */
76
+ function defined(value, message) {
77
+ if (value == null) throw new AssertionError(resolveAssertMessage(message, "Expected a defined value"));
78
+ }
79
+ /**
80
+ * Throws when the value is `null`; allows `undefined` unless combined with other checks.
81
+ *
82
+ * @param value Value that may be `null`.
83
+ * @param message Optional message or lazy message factory.
84
+ */
85
+ function notNull(value, message) {
86
+ if (value === null) throw new AssertionError(resolveAssertMessage(message, "Expected a non-null value"));
87
+ }
88
+ /**
89
+ * Throws when the value is `undefined`.
90
+ *
91
+ * @param value Value that may be `undefined`.
92
+ * @param message Optional message or lazy message factory.
93
+ */
94
+ function notUndefined(value, message) {
95
+ if (value === void 0) throw new AssertionError(resolveAssertMessage(message, "Expected a defined value"));
96
+ }
97
+ /**
98
+ * Always throws; use for branches that must be impossible or as a typed “abort”.
99
+ *
100
+ * @param message Optional message or lazy message factory.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * function parse(kind: "a" | "b") {
105
+ * if (kind === "a") return 1;
106
+ * if (kind === "b") return 2;
107
+ * assert.fail("unreachable");
108
+ * }
109
+ * ```
110
+ */
111
+ function fail(message) {
112
+ throw new AssertionError(resolveAssertMessage(message, "Unreachable"));
113
+ }
114
+ /**
115
+ * Exhaustiveness helper: call with a `never` value when all union cases are handled.
116
+ *
117
+ * @param value Should be `never` when the type checker is satisfied.
118
+ * @param message Optional message (this path always throws, so a lazy factory is unnecessary).
119
+ */
120
+ function unreachable(value, message) {
121
+ throw new AssertionError(resolveAssertMessage(message, `Unexpected value: ${String(value)}`));
122
+ }
123
+ /**
124
+ * Throws when `value` is not an instance of `ctor`.
125
+ *
126
+ * @param value Value to check.
127
+ * @param ctor Constructor used with `instanceof`.
128
+ * @param message Optional message or lazy message factory.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * assert.instanceOf(el, HTMLElement, "expected a DOM element");
133
+ * ```
134
+ */
135
+ function instanceOf(value, ctor, message) {
136
+ if (!(value instanceof ctor)) throw new AssertionError(resolveAssertMessage(message, `Expected instance of ${ctor.name}`));
137
+ }
138
+ //#endregion
139
+ Object.defineProperty(exports, "assert", {
140
+ enumerable: true,
141
+ get: function() {
142
+ return _exports_exports;
143
+ }
144
+ });
145
+
146
+ //# sourceMappingURL=assert.cjs.map
package/assert.cjs.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.cjs","names":[],"sources":["../src/assert/_exports.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/assert\n *\n * ## Description\n *\n * Runtime **assertions** for invariants, narrowing, and exhaustiveness. Helpers throw\n * {@link AssertionError} with an optional message (`string` or {@link MaybeFn}) so failing fast stays\n * explicit without a heavy assertion library. Use `assert.ok`, `assert.defined`, `assert.fail`, and\n * the rest on the namespace export from the package entry.\n *\n * ## Usage\n *\n * ```ts\n * import { assert } from \"yummies/assert\";\n *\n * assert.ok(user.id, \"user id is required\");\n * assert.defined(maybeName);\n * ```\n */\n\nimport { callFunction } from 'yummies/common';\nimport type { Maybe, MaybeFn } from 'yummies/types';\n\n/**\n * Error thrown by assertion helpers in this module.\n */\nexport class AssertionError extends Error {\n override name = 'AssertionError';\n}\n\nfunction resolveAssertMessage(\n message: MaybeFn<string> | undefined,\n fallback: string,\n): string {\n if (message === undefined) {\n return fallback;\n }\n return callFunction(message);\n}\n\n/**\n * Throws when `condition` is falsy; narrows the type when it is truthy.\n *\n * @param condition Value treated as a boolean guard.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.ok(user.id, \"user id is required\");\n * ```\n */\nexport function ok(\n condition: unknown,\n message?: MaybeFn<string>,\n): asserts condition {\n if (!condition) {\n throw new AssertionError(resolveAssertMessage(message, 'Assertion failed'));\n }\n}\n\n/**\n * Same as {@link ok}; common alias for internal invariants (e.g. after optional checks).\n */\nexport const invariant: typeof ok = ok;\n\n/**\n * Throws when the value is `null` or `undefined`; otherwise narrows away nullish.\n *\n * @param value Possibly nullish value.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.defined(maybeName, \"name must be present\");\n * ```\n */\nexport function defined<T>(\n value: Maybe<T>,\n message?: MaybeFn<string>,\n): asserts value is NonNullable<T> {\n if (value == null) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a defined value'),\n );\n }\n}\n\n/**\n * Throws when the value is `null`; allows `undefined` unless combined with other checks.\n *\n * @param value Value that may be `null`.\n * @param message Optional message or lazy message factory.\n */\nexport function notNull<T>(\n value: T | null,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (value === null) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a non-null value'),\n );\n }\n}\n\n/**\n * Throws when the value is `undefined`.\n *\n * @param value Value that may be `undefined`.\n * @param message Optional message or lazy message factory.\n */\nexport function notUndefined<T>(\n value: T | undefined,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (value === undefined) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a defined value'),\n );\n }\n}\n\n/**\n * Always throws; use for branches that must be impossible or as a typed “abort”.\n *\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * function parse(kind: \"a\" | \"b\") {\n * if (kind === \"a\") return 1;\n * if (kind === \"b\") return 2;\n * assert.fail(\"unreachable\");\n * }\n * ```\n */\nexport function fail(message?: MaybeFn<string>): never {\n throw new AssertionError(resolveAssertMessage(message, 'Unreachable'));\n}\n\n/**\n * Exhaustiveness helper: call with a `never` value when all union cases are handled.\n *\n * @param value Should be `never` when the type checker is satisfied.\n * @param message Optional message (this path always throws, so a lazy factory is unnecessary).\n */\nexport function unreachable(value: never, message?: string): never {\n throw new AssertionError(\n resolveAssertMessage(message, `Unexpected value: ${String(value)}`),\n );\n}\n\n/**\n * Alias for {@link unreachable} (common name in switch exhaustiveness snippets).\n */\nexport { unreachable as never };\n\n/**\n * Throws when `value` is not an instance of `ctor`.\n *\n * @param value Value to check.\n * @param ctor Constructor used with `instanceof`.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.instanceOf(el, HTMLElement, \"expected a DOM element\");\n * ```\n */\nexport function instanceOf<T>(\n value: unknown,\n ctor: abstract new (...args: never[]) => T,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (!(value instanceof ctor)) {\n throw new AssertionError(\n resolveAssertMessage(message, `Expected instance of ${ctor.name}`),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,iBAAb,cAAoC,MAAM;CACxC,OAAgB;;AAGlB,SAAS,qBACP,SACA,UACQ;AACR,KAAI,YAAY,KAAA,EACd,QAAO;AAET,SAAA,GAAA,eAAA,cAAoB,QAAQ;;;;;;;;;;;;;AAc9B,SAAgB,GACd,WACA,SACmB;AACnB,KAAI,CAAC,UACH,OAAM,IAAI,eAAe,qBAAqB,SAAS,mBAAmB,CAAC;;;;;AAO/E,IAAa,YAAuB;;;;;;;;;;;;AAapC,SAAgB,QACd,OACA,SACiC;AACjC,KAAI,SAAS,KACX,OAAM,IAAI,eACR,qBAAqB,SAAS,2BAA2B,CAC1D;;;;;;;;AAUL,SAAgB,QACd,OACA,SACoB;AACpB,KAAI,UAAU,KACZ,OAAM,IAAI,eACR,qBAAqB,SAAS,4BAA4B,CAC3D;;;;;;;;AAUL,SAAgB,aACd,OACA,SACoB;AACpB,KAAI,UAAU,KAAA,EACZ,OAAM,IAAI,eACR,qBAAqB,SAAS,2BAA2B,CAC1D;;;;;;;;;;;;;;;;AAkBL,SAAgB,KAAK,SAAkC;AACrD,OAAM,IAAI,eAAe,qBAAqB,SAAS,cAAc,CAAC;;;;;;;;AASxE,SAAgB,YAAY,OAAc,SAAyB;AACjE,OAAM,IAAI,eACR,qBAAqB,SAAS,qBAAqB,OAAO,MAAM,GAAG,CACpE;;;;;;;;;;;;;;AAoBH,SAAgB,WACd,OACA,MACA,SACoB;AACpB,KAAI,EAAE,iBAAiB,MACrB,OAAM,IAAI,eACR,qBAAqB,SAAS,wBAAwB,KAAK,OAAO,CACnE"}
package/assert.d.ts ADDED
@@ -0,0 +1,134 @@
1
+ import { Maybe, MaybeFn } from 'yummies/types';
2
+
3
+ /**
4
+ * ---header-docs-section---
5
+ * # yummies/assert
6
+ *
7
+ * ## Description
8
+ *
9
+ * Runtime **assertions** for invariants, narrowing, and exhaustiveness. Helpers throw
10
+ * {@link AssertionError} with an optional message (`string` or {@link MaybeFn}) so failing fast stays
11
+ * explicit without a heavy assertion library. Use `assert.ok`, `assert.defined`, `assert.fail`, and
12
+ * the rest on the namespace export from the package entry.
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ```ts
17
+ * import { assert } from "yummies/assert";
18
+ *
19
+ * assert.ok(user.id, "user id is required");
20
+ * assert.defined(maybeName);
21
+ * ```
22
+ */
23
+
24
+ /**
25
+ * Error thrown by assertion helpers in this module.
26
+ */
27
+ declare class AssertionError extends Error {
28
+ name: string;
29
+ }
30
+ /**
31
+ * Throws when `condition` is falsy; narrows the type when it is truthy.
32
+ *
33
+ * @param condition Value treated as a boolean guard.
34
+ * @param message Optional message or lazy message factory.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * assert.ok(user.id, "user id is required");
39
+ * ```
40
+ */
41
+ declare function ok(condition: unknown, message?: MaybeFn<string>): asserts condition;
42
+ /**
43
+ * Same as {@link ok}; common alias for internal invariants (e.g. after optional checks).
44
+ */
45
+ declare const invariant: typeof ok;
46
+ /**
47
+ * Throws when the value is `null` or `undefined`; otherwise narrows away nullish.
48
+ *
49
+ * @param value Possibly nullish value.
50
+ * @param message Optional message or lazy message factory.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * assert.defined(maybeName, "name must be present");
55
+ * ```
56
+ */
57
+ declare function defined<T>(value: Maybe<T>, message?: MaybeFn<string>): asserts value is NonNullable<T>;
58
+ /**
59
+ * Throws when the value is `null`; allows `undefined` unless combined with other checks.
60
+ *
61
+ * @param value Value that may be `null`.
62
+ * @param message Optional message or lazy message factory.
63
+ */
64
+ declare function notNull<T>(value: T | null, message?: MaybeFn<string>): asserts value is T;
65
+ /**
66
+ * Throws when the value is `undefined`.
67
+ *
68
+ * @param value Value that may be `undefined`.
69
+ * @param message Optional message or lazy message factory.
70
+ */
71
+ declare function notUndefined<T>(value: T | undefined, message?: MaybeFn<string>): asserts value is T;
72
+ /**
73
+ * Always throws; use for branches that must be impossible or as a typed “abort”.
74
+ *
75
+ * @param message Optional message or lazy message factory.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * function parse(kind: "a" | "b") {
80
+ * if (kind === "a") return 1;
81
+ * if (kind === "b") return 2;
82
+ * assert.fail("unreachable");
83
+ * }
84
+ * ```
85
+ */
86
+ declare function fail(message?: MaybeFn<string>): never;
87
+ /**
88
+ * Exhaustiveness helper: call with a `never` value when all union cases are handled.
89
+ *
90
+ * @param value Should be `never` when the type checker is satisfied.
91
+ * @param message Optional message (this path always throws, so a lazy factory is unnecessary).
92
+ */
93
+ declare function unreachable(value: never, message?: string): never;
94
+
95
+ /**
96
+ * Throws when `value` is not an instance of `ctor`.
97
+ *
98
+ * @param value Value to check.
99
+ * @param ctor Constructor used with `instanceof`.
100
+ * @param message Optional message or lazy message factory.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * assert.instanceOf(el, HTMLElement, "expected a DOM element");
105
+ * ```
106
+ */
107
+ declare function instanceOf<T>(value: unknown, ctor: abstract new (...args: never[]) => T, message?: MaybeFn<string>): asserts value is T;
108
+
109
+ type _exports_AssertionError = AssertionError;
110
+ declare const _exports_AssertionError: typeof AssertionError;
111
+ declare const _exports_defined: typeof defined;
112
+ declare const _exports_fail: typeof fail;
113
+ declare const _exports_instanceOf: typeof instanceOf;
114
+ declare const _exports_invariant: typeof invariant;
115
+ declare const _exports_notNull: typeof notNull;
116
+ declare const _exports_notUndefined: typeof notUndefined;
117
+ declare const _exports_ok: typeof ok;
118
+ declare const _exports_unreachable: typeof unreachable;
119
+ declare namespace _exports {
120
+ export {
121
+ _exports_AssertionError as AssertionError,
122
+ _exports_defined as defined,
123
+ _exports_fail as fail,
124
+ _exports_instanceOf as instanceOf,
125
+ _exports_invariant as invariant,
126
+ unreachable as never,
127
+ _exports_notNull as notNull,
128
+ _exports_notUndefined as notUndefined,
129
+ _exports_ok as ok,
130
+ _exports_unreachable as unreachable,
131
+ };
132
+ }
133
+
134
+ export { _exports as assert };
package/assert.js ADDED
@@ -0,0 +1,140 @@
1
+ import { n as __exportAll } from "./chunk-YKewjYmz.js";
2
+ import { callFunction } from "yummies/common";
3
+ //#region src/assert/_exports.ts
4
+ /**
5
+ * ---header-docs-section---
6
+ * # yummies/assert
7
+ *
8
+ * ## Description
9
+ *
10
+ * Runtime **assertions** for invariants, narrowing, and exhaustiveness. Helpers throw
11
+ * {@link AssertionError} with an optional message (`string` or {@link MaybeFn}) so failing fast stays
12
+ * explicit without a heavy assertion library. Use `assert.ok`, `assert.defined`, `assert.fail`, and
13
+ * the rest on the namespace export from the package entry.
14
+ *
15
+ * ## Usage
16
+ *
17
+ * ```ts
18
+ * import { assert } from "yummies/assert";
19
+ *
20
+ * assert.ok(user.id, "user id is required");
21
+ * assert.defined(maybeName);
22
+ * ```
23
+ */
24
+ var _exports_exports = /* @__PURE__ */ __exportAll({
25
+ AssertionError: () => AssertionError,
26
+ defined: () => defined,
27
+ fail: () => fail,
28
+ instanceOf: () => instanceOf,
29
+ invariant: () => invariant,
30
+ never: () => unreachable,
31
+ notNull: () => notNull,
32
+ notUndefined: () => notUndefined,
33
+ ok: () => ok,
34
+ unreachable: () => unreachable
35
+ });
36
+ /**
37
+ * Error thrown by assertion helpers in this module.
38
+ */
39
+ var AssertionError = class extends Error {
40
+ name = "AssertionError";
41
+ };
42
+ function resolveAssertMessage(message, fallback) {
43
+ if (message === void 0) return fallback;
44
+ return callFunction(message);
45
+ }
46
+ /**
47
+ * Throws when `condition` is falsy; narrows the type when it is truthy.
48
+ *
49
+ * @param condition Value treated as a boolean guard.
50
+ * @param message Optional message or lazy message factory.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * assert.ok(user.id, "user id is required");
55
+ * ```
56
+ */
57
+ function ok(condition, message) {
58
+ if (!condition) throw new AssertionError(resolveAssertMessage(message, "Assertion failed"));
59
+ }
60
+ /**
61
+ * Same as {@link ok}; common alias for internal invariants (e.g. after optional checks).
62
+ */
63
+ var invariant = ok;
64
+ /**
65
+ * Throws when the value is `null` or `undefined`; otherwise narrows away nullish.
66
+ *
67
+ * @param value Possibly nullish value.
68
+ * @param message Optional message or lazy message factory.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * assert.defined(maybeName, "name must be present");
73
+ * ```
74
+ */
75
+ function defined(value, message) {
76
+ if (value == null) throw new AssertionError(resolveAssertMessage(message, "Expected a defined value"));
77
+ }
78
+ /**
79
+ * Throws when the value is `null`; allows `undefined` unless combined with other checks.
80
+ *
81
+ * @param value Value that may be `null`.
82
+ * @param message Optional message or lazy message factory.
83
+ */
84
+ function notNull(value, message) {
85
+ if (value === null) throw new AssertionError(resolveAssertMessage(message, "Expected a non-null value"));
86
+ }
87
+ /**
88
+ * Throws when the value is `undefined`.
89
+ *
90
+ * @param value Value that may be `undefined`.
91
+ * @param message Optional message or lazy message factory.
92
+ */
93
+ function notUndefined(value, message) {
94
+ if (value === void 0) throw new AssertionError(resolveAssertMessage(message, "Expected a defined value"));
95
+ }
96
+ /**
97
+ * Always throws; use for branches that must be impossible or as a typed “abort”.
98
+ *
99
+ * @param message Optional message or lazy message factory.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * function parse(kind: "a" | "b") {
104
+ * if (kind === "a") return 1;
105
+ * if (kind === "b") return 2;
106
+ * assert.fail("unreachable");
107
+ * }
108
+ * ```
109
+ */
110
+ function fail(message) {
111
+ throw new AssertionError(resolveAssertMessage(message, "Unreachable"));
112
+ }
113
+ /**
114
+ * Exhaustiveness helper: call with a `never` value when all union cases are handled.
115
+ *
116
+ * @param value Should be `never` when the type checker is satisfied.
117
+ * @param message Optional message (this path always throws, so a lazy factory is unnecessary).
118
+ */
119
+ function unreachable(value, message) {
120
+ throw new AssertionError(resolveAssertMessage(message, `Unexpected value: ${String(value)}`));
121
+ }
122
+ /**
123
+ * Throws when `value` is not an instance of `ctor`.
124
+ *
125
+ * @param value Value to check.
126
+ * @param ctor Constructor used with `instanceof`.
127
+ * @param message Optional message or lazy message factory.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * assert.instanceOf(el, HTMLElement, "expected a DOM element");
132
+ * ```
133
+ */
134
+ function instanceOf(value, ctor, message) {
135
+ if (!(value instanceof ctor)) throw new AssertionError(resolveAssertMessage(message, `Expected instance of ${ctor.name}`));
136
+ }
137
+ //#endregion
138
+ export { _exports_exports as assert };
139
+
140
+ //# sourceMappingURL=assert.js.map
package/assert.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.js","names":[],"sources":["../src/assert/_exports.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/assert\n *\n * ## Description\n *\n * Runtime **assertions** for invariants, narrowing, and exhaustiveness. Helpers throw\n * {@link AssertionError} with an optional message (`string` or {@link MaybeFn}) so failing fast stays\n * explicit without a heavy assertion library. Use `assert.ok`, `assert.defined`, `assert.fail`, and\n * the rest on the namespace export from the package entry.\n *\n * ## Usage\n *\n * ```ts\n * import { assert } from \"yummies/assert\";\n *\n * assert.ok(user.id, \"user id is required\");\n * assert.defined(maybeName);\n * ```\n */\n\nimport { callFunction } from 'yummies/common';\nimport type { Maybe, MaybeFn } from 'yummies/types';\n\n/**\n * Error thrown by assertion helpers in this module.\n */\nexport class AssertionError extends Error {\n override name = 'AssertionError';\n}\n\nfunction resolveAssertMessage(\n message: MaybeFn<string> | undefined,\n fallback: string,\n): string {\n if (message === undefined) {\n return fallback;\n }\n return callFunction(message);\n}\n\n/**\n * Throws when `condition` is falsy; narrows the type when it is truthy.\n *\n * @param condition Value treated as a boolean guard.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.ok(user.id, \"user id is required\");\n * ```\n */\nexport function ok(\n condition: unknown,\n message?: MaybeFn<string>,\n): asserts condition {\n if (!condition) {\n throw new AssertionError(resolveAssertMessage(message, 'Assertion failed'));\n }\n}\n\n/**\n * Same as {@link ok}; common alias for internal invariants (e.g. after optional checks).\n */\nexport const invariant: typeof ok = ok;\n\n/**\n * Throws when the value is `null` or `undefined`; otherwise narrows away nullish.\n *\n * @param value Possibly nullish value.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.defined(maybeName, \"name must be present\");\n * ```\n */\nexport function defined<T>(\n value: Maybe<T>,\n message?: MaybeFn<string>,\n): asserts value is NonNullable<T> {\n if (value == null) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a defined value'),\n );\n }\n}\n\n/**\n * Throws when the value is `null`; allows `undefined` unless combined with other checks.\n *\n * @param value Value that may be `null`.\n * @param message Optional message or lazy message factory.\n */\nexport function notNull<T>(\n value: T | null,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (value === null) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a non-null value'),\n );\n }\n}\n\n/**\n * Throws when the value is `undefined`.\n *\n * @param value Value that may be `undefined`.\n * @param message Optional message or lazy message factory.\n */\nexport function notUndefined<T>(\n value: T | undefined,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (value === undefined) {\n throw new AssertionError(\n resolveAssertMessage(message, 'Expected a defined value'),\n );\n }\n}\n\n/**\n * Always throws; use for branches that must be impossible or as a typed “abort”.\n *\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * function parse(kind: \"a\" | \"b\") {\n * if (kind === \"a\") return 1;\n * if (kind === \"b\") return 2;\n * assert.fail(\"unreachable\");\n * }\n * ```\n */\nexport function fail(message?: MaybeFn<string>): never {\n throw new AssertionError(resolveAssertMessage(message, 'Unreachable'));\n}\n\n/**\n * Exhaustiveness helper: call with a `never` value when all union cases are handled.\n *\n * @param value Should be `never` when the type checker is satisfied.\n * @param message Optional message (this path always throws, so a lazy factory is unnecessary).\n */\nexport function unreachable(value: never, message?: string): never {\n throw new AssertionError(\n resolveAssertMessage(message, `Unexpected value: ${String(value)}`),\n );\n}\n\n/**\n * Alias for {@link unreachable} (common name in switch exhaustiveness snippets).\n */\nexport { unreachable as never };\n\n/**\n * Throws when `value` is not an instance of `ctor`.\n *\n * @param value Value to check.\n * @param ctor Constructor used with `instanceof`.\n * @param message Optional message or lazy message factory.\n *\n * @example\n * ```ts\n * assert.instanceOf(el, HTMLElement, \"expected a DOM element\");\n * ```\n */\nexport function instanceOf<T>(\n value: unknown,\n ctor: abstract new (...args: never[]) => T,\n message?: MaybeFn<string>,\n): asserts value is T {\n if (!(value instanceof ctor)) {\n throw new AssertionError(\n resolveAssertMessage(message, `Expected instance of ${ctor.name}`),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,iBAAb,cAAoC,MAAM;CACxC,OAAgB;;AAGlB,SAAS,qBACP,SACA,UACQ;AACR,KAAI,YAAY,KAAA,EACd,QAAO;AAET,QAAO,aAAa,QAAQ;;;;;;;;;;;;;AAc9B,SAAgB,GACd,WACA,SACmB;AACnB,KAAI,CAAC,UACH,OAAM,IAAI,eAAe,qBAAqB,SAAS,mBAAmB,CAAC;;;;;AAO/E,IAAa,YAAuB;;;;;;;;;;;;AAapC,SAAgB,QACd,OACA,SACiC;AACjC,KAAI,SAAS,KACX,OAAM,IAAI,eACR,qBAAqB,SAAS,2BAA2B,CAC1D;;;;;;;;AAUL,SAAgB,QACd,OACA,SACoB;AACpB,KAAI,UAAU,KACZ,OAAM,IAAI,eACR,qBAAqB,SAAS,4BAA4B,CAC3D;;;;;;;;AAUL,SAAgB,aACd,OACA,SACoB;AACpB,KAAI,UAAU,KAAA,EACZ,OAAM,IAAI,eACR,qBAAqB,SAAS,2BAA2B,CAC1D;;;;;;;;;;;;;;;;AAkBL,SAAgB,KAAK,SAAkC;AACrD,OAAM,IAAI,eAAe,qBAAqB,SAAS,cAAc,CAAC;;;;;;;;AASxE,SAAgB,YAAY,OAAc,SAAyB;AACjE,OAAM,IAAI,eACR,qBAAqB,SAAS,qBAAqB,OAAO,MAAM,GAAG,CACpE;;;;;;;;;;;;;;AAoBH,SAAgB,WACd,OACA,MACA,SACoB;AACpB,KAAI,EAAE,iBAAiB,MACrB,OAAM,IAAI,eACR,qBAAqB,SAAS,wBAAwB,KAAK,OAAO,CACnE"}
package/async.cjs CHANGED
@@ -1,6 +1,23 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/async.ts
3
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
+ /**
4
21
  * Returns a promise that resolves after `time` milliseconds.
5
22
  *
6
23
  * When `signal` is passed and becomes aborted before the delay elapses, the promise
package/async.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"async.cjs","names":[],"sources":["../src/async.ts"],"sourcesContent":["/**\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,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"}
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,3 +1,20 @@
1
+ /**
2
+ * ---header-docs-section---
3
+ * # yummies/async
4
+ *
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
+ */
1
18
  /**
2
19
  * Returns a promise that resolves after `time` milliseconds.
3
20
  *
package/async.js CHANGED
@@ -1,5 +1,22 @@
1
1
  //#region src/async.ts
2
2
  /**
3
+ * ---header-docs-section---
4
+ * # yummies/async
5
+ *
6
+ * ## Description
7
+ *
8
+ * Helpers for asynchronous control flow: delays, cancellable waits, scheduling on the next frame,
9
+ * and small utilities around `requestAnimationFrame` and `queueMicrotask`. They complement native
10
+ * `Promise`/`AbortSignal` patterns and keep timing logic easy to test and tree-shake per call site.
11
+ * Import only what you need from `yummies/async` so bundlers can drop unused helpers.
12
+ *
13
+ * ## Usage
14
+ *
15
+ * ```ts
16
+ * import { sleep } from "yummies/async";
17
+ * ```
18
+ */
19
+ /**
3
20
  * Returns a promise that resolves after `time` milliseconds.
4
21
  *
5
22
  * When `signal` is passed and becomes aborted before the delay elapses, the promise