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/html.js CHANGED
@@ -1,168 +1,257 @@
1
1
  import DOMPurify from "dompurify";
2
2
  import { blobToUrl } from "yummies/media";
3
- const getComputedColor = (color) => {
4
- if (!color) return null;
5
- const d = document.createElement("div");
6
- d.style.color = color;
7
- document.body.append(d);
8
- const rgbcolor = globalThis.getComputedStyle(d).color;
9
- const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor);
10
- d.remove();
11
- if (!match) return null;
12
- return `${match[1]}, ${match[2]}, ${match[3]}`;
3
+ //#region src/html.ts
4
+ /**
5
+ * ---header-docs-section---
6
+ * # yummies/html
7
+ *
8
+ * ## Description
9
+ *
10
+ * DOM-centric utilities: sanitizing HTML with **DOMPurify**, computed style probes, downloads via
11
+ * temporary anchors, and small string helpers for safe markup. Prefer these over `innerHTML` with
12
+ * raw user input; keep CSP and server-side validation as the real security boundary.
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ```ts
17
+ * import { getComputedColor } from "yummies/html";
18
+ * ```
19
+ */
20
+ /**
21
+ * Extracts an RGB value from any valid CSS color.
22
+ *
23
+ * Not recommended for frequent use because it triggers a reflow.
24
+ */
25
+ var getComputedColor = (color) => {
26
+ if (!color) return null;
27
+ const d = document.createElement("div");
28
+ d.style.color = color;
29
+ document.body.append(d);
30
+ const rgbcolor = globalThis.getComputedStyle(d).color;
31
+ const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor);
32
+ d.remove();
33
+ if (!match) return null;
34
+ return `${match[1]}, ${match[2]}, ${match[3]}`;
13
35
  };
14
- const downloadUsingAnchor = (urlOrBlob, fileName) => {
15
- const url = blobToUrl(urlOrBlob);
16
- const a = document.createElement("a");
17
- a.href = url;
18
- a.download = fileName ?? "file";
19
- a.target = "_blank";
20
- document.body.append(a);
21
- a.click();
22
- a.remove();
36
+ /**
37
+ * Triggers a file download by creating and clicking a temporary anchor element.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * downloadUsingAnchor('/report.pdf', 'report.pdf');
42
+ * ```
43
+ */
44
+ var downloadUsingAnchor = (urlOrBlob, fileName) => {
45
+ const url = blobToUrl(urlOrBlob);
46
+ const a = document.createElement("a");
47
+ a.href = url;
48
+ a.download = fileName ?? "file";
49
+ a.target = "_blank";
50
+ document.body.append(a);
51
+ a.click();
52
+ a.remove();
23
53
  };
54
+ /**
55
+ * Surrounds string in an anchor tag
56
+ */
24
57
  function wrapTextToTagLink(link) {
25
- const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, "www.");
26
- if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
27
- return `<a href=${link} target="_blank">${descr}</a>`;
58
+ const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, "www.");
59
+ if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
60
+ return `<a href=${link} target="_blank">${descr}</a>`;
28
61
  }
29
- const collectOffsetTop = (element) => {
30
- let offsetTop = 0;
31
- let node = element;
32
- while (node != null) {
33
- offsetTop += node.offsetTop;
34
- node = node.parentElement;
35
- }
36
- return offsetTop;
62
+ /**
63
+ * Collects the cumulative `offsetTop` value through the element parent chain.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * const offsetTop = collectOffsetTop(document.getElementById('section'));
68
+ * ```
69
+ */
70
+ var collectOffsetTop = (element) => {
71
+ let offsetTop = 0;
72
+ let node = element;
73
+ while (node != null) {
74
+ offsetTop += node.offsetTop;
75
+ node = node.parentElement;
76
+ }
77
+ return offsetTop;
37
78
  };
38
- const skipEvent = (e) => {
39
- e.preventDefault();
40
- e.stopPropagation();
41
- return false;
79
+ /**
80
+ * Prevents the default browser action and stops event propagation.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * button.addEventListener('click', (event) => skipEvent(event));
85
+ * ```
86
+ */
87
+ var skipEvent = (e) => {
88
+ e.preventDefault();
89
+ e.stopPropagation();
90
+ return false;
42
91
  };
43
- const globalScrollIntoViewForY = (node) => {
44
- const scrollContainer = document.body;
45
- const pageHeight = window.innerHeight;
46
- const nodeBounding = node.getBoundingClientRect();
47
- const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;
48
- const scrollPageNumber = Math.min(
49
- Math.max(nodeBounding.top / pageHeight, 1),
50
- scrollPagesCount
51
- );
52
- window.scroll({
53
- top: scrollPageNumber * pageHeight,
54
- behavior: "smooth"
55
- });
92
+ /**
93
+ * Scrolls the page vertically to the viewport section containing the target element.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * globalScrollIntoViewForY(document.getElementById('footer')!);
98
+ * ```
99
+ */
100
+ var globalScrollIntoViewForY = (node) => {
101
+ const scrollContainer = document.body;
102
+ const pageHeight = window.innerHeight;
103
+ const nodeBounding = node.getBoundingClientRect();
104
+ const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;
105
+ const scrollPageNumber = Math.min(Math.max(nodeBounding.top / pageHeight, 1), scrollPagesCount);
106
+ window.scroll({
107
+ top: scrollPageNumber * pageHeight,
108
+ behavior: "smooth"
109
+ });
56
110
  };
57
- const sanitizeDefaults = {
58
- ALLOWED_TAGS: [
59
- "a",
60
- "article",
61
- "b",
62
- "blockquote",
63
- "br",
64
- "caption",
65
- "code",
66
- "del",
67
- "details",
68
- "div",
69
- "em",
70
- "h1",
71
- "h2",
72
- "h3",
73
- "h4",
74
- "h5",
75
- "h6",
76
- "hr",
77
- "i",
78
- "img",
79
- "ins",
80
- "kbd",
81
- "li",
82
- "main",
83
- "ol",
84
- "p",
85
- "pre",
86
- "section",
87
- "span",
88
- "strong",
89
- "sub",
90
- "summary",
91
- "sup",
92
- "table",
93
- "tbody",
94
- "td",
95
- "th",
96
- "thead",
97
- "tr",
98
- "u",
99
- "ul"
100
- ],
101
- ALLOWED_ATTR: ["href", "target", "name", "src", "class"]
111
+ var sanitizeDefaults = {
112
+ ALLOWED_TAGS: [
113
+ "a",
114
+ "article",
115
+ "b",
116
+ "blockquote",
117
+ "br",
118
+ "caption",
119
+ "code",
120
+ "del",
121
+ "details",
122
+ "div",
123
+ "em",
124
+ "h1",
125
+ "h2",
126
+ "h3",
127
+ "h4",
128
+ "h5",
129
+ "h6",
130
+ "hr",
131
+ "i",
132
+ "img",
133
+ "ins",
134
+ "kbd",
135
+ "li",
136
+ "main",
137
+ "ol",
138
+ "p",
139
+ "pre",
140
+ "section",
141
+ "span",
142
+ "strong",
143
+ "sub",
144
+ "summary",
145
+ "sup",
146
+ "table",
147
+ "tbody",
148
+ "td",
149
+ "th",
150
+ "thead",
151
+ "tr",
152
+ "u",
153
+ "ul"
154
+ ],
155
+ ALLOWED_ATTR: [
156
+ "href",
157
+ "target",
158
+ "name",
159
+ "src",
160
+ "class"
161
+ ]
102
162
  };
103
- const sanitizeHtml = (html, config) => {
104
- return DOMPurify.sanitize(html || "", {
105
- ...sanitizeDefaults,
106
- ...config
107
- });
163
+ /**
164
+ * Sanitizes HTML using the default allowlist merged with custom DOMPurify config.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * sanitizeHtml('<img src=x onerror=alert(1) />');
169
+ * ```
170
+ */
171
+ var sanitizeHtml = (html, config) => {
172
+ return DOMPurify.sanitize(html || "", {
173
+ ...sanitizeDefaults,
174
+ ...config
175
+ });
108
176
  };
109
- const checkElementHasParent = (element, parent) => {
110
- let node = element;
111
- if (!parent) return false;
112
- while (node != null) {
113
- if (node === parent) {
114
- return true;
115
- } else {
116
- node = node.parentElement;
117
- }
118
- }
119
- return false;
177
+ /**
178
+ * Checks whether the element is nested inside the provided parent element.
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * checkElementHasParent(childElement, modalElement);
183
+ * ```
184
+ */
185
+ var checkElementHasParent = (element, parent) => {
186
+ let node = element;
187
+ if (!parent) return false;
188
+ while (node != null) if (node === parent) return true;
189
+ else node = node.parentElement;
190
+ return false;
120
191
  };
121
- const startViewTransitionSafety = (fn, params) => {
122
- if (typeof document !== "undefined" && document.startViewTransition && !params?.disabled) {
123
- return document.startViewTransition(fn);
124
- }
125
- fn();
192
+ /**
193
+ * Executes a function within a view transition if supported by the browser.
194
+ *
195
+ * @param {VoidFunction} fn - The function to be executed.
196
+ * @returns {ViewTransition} - The result of the executed function.
197
+ *
198
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}
199
+ */
200
+ var startViewTransitionSafety = (fn, params) => {
201
+ if (typeof document !== "undefined" && document.startViewTransition && !params?.disabled) return document.startViewTransition(fn);
202
+ fn();
126
203
  };
127
- const calcScrollbarWidth = (elementToAppend = document.body) => {
128
- const outer = document.createElement("div");
129
- outer.style.visibility = "hidden";
130
- outer.style.width = "100px";
131
- outer.style.overflow = "scroll";
132
- elementToAppend.append(outer);
133
- const inner = document.createElement("div");
134
- inner.style.width = "100%";
135
- outer.append(inner);
136
- const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
137
- outer.parentNode?.removeChild(outer);
138
- return scrollbarWidth;
204
+ /**
205
+ * Calculates the scrollbar width.
206
+ */
207
+ var calcScrollbarWidth = (elementToAppend = document.body) => {
208
+ const outer = document.createElement("div");
209
+ outer.style.visibility = "hidden";
210
+ outer.style.width = "100px";
211
+ outer.style.overflow = "scroll";
212
+ elementToAppend.append(outer);
213
+ const inner = document.createElement("div");
214
+ inner.style.width = "100%";
215
+ outer.append(inner);
216
+ const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
217
+ outer.parentNode?.removeChild(outer);
218
+ return scrollbarWidth;
139
219
  };
220
+ /**
221
+ * Calculates the inner height of an HTML element, accounting for padding.
222
+ */
140
223
  function getElementInnerHeight(element) {
141
- const { clientHeight } = element;
142
- const { paddingTop, paddingBottom } = getComputedStyle(element);
143
- return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
224
+ const { clientHeight } = element;
225
+ const { paddingTop, paddingBottom } = getComputedStyle(element);
226
+ return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
144
227
  }
228
+ /**
229
+ * Calculates the inner width of an HTML element, accounting for padding.
230
+ */
145
231
  function getElementInnerWidth(el) {
146
- const { clientWidth } = el;
147
- const { paddingLeft, paddingRight } = getComputedStyle(el);
148
- return clientWidth - Number.parseFloat(paddingLeft) - Number.parseFloat(paddingRight);
232
+ const { clientWidth } = el;
233
+ const { paddingLeft, paddingRight } = getComputedStyle(el);
234
+ return clientWidth - Number.parseFloat(paddingLeft) - Number.parseFloat(paddingRight);
149
235
  }
150
- const isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
151
- const isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
152
- export {
153
- calcScrollbarWidth,
154
- checkElementHasParent,
155
- collectOffsetTop,
156
- downloadUsingAnchor,
157
- getComputedColor,
158
- getElementInnerHeight,
159
- getElementInnerWidth,
160
- globalScrollIntoViewForY,
161
- isPrefersDarkTheme,
162
- isPrefersLightTheme,
163
- sanitizeHtml,
164
- skipEvent,
165
- startViewTransitionSafety,
166
- wrapTextToTagLink
167
- };
168
- //# sourceMappingURL=html.js.map
236
+ /**
237
+ * Checks whether the user prefers a dark color scheme.
238
+ *
239
+ * @example
240
+ * ```ts
241
+ * const prefersDark = isPrefersDarkTheme();
242
+ * ```
243
+ */
244
+ var isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
245
+ /**
246
+ * Checks whether the user prefers a light color scheme.
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const prefersLight = isPrefersLightTheme();
251
+ * ```
252
+ */
253
+ var isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
254
+ //#endregion
255
+ export { calcScrollbarWidth, checkElementHasParent, collectOffsetTop, downloadUsingAnchor, getComputedColor, getElementInnerHeight, getElementInnerWidth, globalScrollIntoViewForY, isPrefersDarkTheme, isPrefersLightTheme, sanitizeHtml, skipEvent, startViewTransitionSafety, wrapTextToTagLink };
256
+
257
+ //# sourceMappingURL=html.js.map
package/html.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"html.js","sources":["../src/html.ts"],"sourcesContent":["import DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';\nimport { blobToUrl } from 'yummies/media';\nimport type { Maybe } from 'yummies/types';\n\n/**\n * Extracts an RGB value from any valid CSS color.\n *\n * Not recommended for frequent use because it triggers a reflow.\n */\nexport const getComputedColor = (color?: string): string | null => {\n if (!color) return null;\n\n const d = document.createElement('div');\n d.style.color = color;\n document.body.append(d);\n const rgbcolor = globalThis.getComputedStyle(d).color;\n const match =\n /rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*\\d+[.d+]*)*\\)/g.exec(rgbcolor);\n\n d.remove();\n\n if (!match) return null;\n\n return `${match[1]}, ${match[2]}, ${match[3]}`;\n};\n\nexport const downloadUsingAnchor = (\n urlOrBlob: string | Blob,\n fileName?: string,\n) => {\n const url = blobToUrl(urlOrBlob);\n\n const a = document.createElement('a');\n a.href = url;\n\n a.download = fileName ?? 'file';\n\n a.target = '_blank';\n\n document.body.append(a);\n\n a.click();\n\n a.remove();\n};\n\n/**\n * Surrounds string in an anchor tag\n */\nexport function wrapTextToTagLink(link: string) {\n const descr = String(link).replace(/^(https?:\\/{0,2})?(w{3}\\.)?/, 'www.');\n if (!/^https?:\\/{2}/.test(link)) link = `http://${link}`;\n return `<a href=${link} target=\"_blank\">${descr}</a>`;\n}\n\nexport const collectOffsetTop = (element: HTMLElement | null) => {\n let offsetTop = 0;\n let node = element;\n\n while (node != null) {\n offsetTop += node.offsetTop;\n node = node.parentElement;\n }\n\n return offsetTop;\n};\n\nexport const skipEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n\n return false;\n};\n\nexport const globalScrollIntoViewForY = (node: HTMLElement) => {\n const scrollContainer = document.body;\n const pageHeight = window.innerHeight;\n const nodeBounding = node.getBoundingClientRect();\n const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;\n\n const scrollPageNumber = Math.min(\n Math.max(nodeBounding.top / pageHeight, 1),\n scrollPagesCount,\n );\n\n window.scroll({\n top: scrollPageNumber * pageHeight,\n behavior: 'smooth',\n });\n};\n\nconst sanitizeDefaults: DOMPurifyConfig = {\n ALLOWED_TAGS: [\n 'a',\n 'article',\n 'b',\n 'blockquote',\n 'br',\n 'caption',\n 'code',\n 'del',\n 'details',\n 'div',\n 'em',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'i',\n 'img',\n 'ins',\n 'kbd',\n 'li',\n 'main',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n ],\n ALLOWED_ATTR: ['href', 'target', 'name', 'src', 'class'],\n};\n\nexport const sanitizeHtml = (html: Maybe<string>, config?: DOMPurifyConfig) => {\n return DOMPurify.sanitize(html || '', {\n ...sanitizeDefaults,\n ...config,\n });\n};\n\nexport const checkElementHasParent = (\n element: HTMLElement | null,\n parent: Maybe<HTMLElement>,\n) => {\n let node = element;\n\n if (!parent) return false;\n\n while (node != null) {\n if (node === parent) {\n return true;\n } else {\n node = node.parentElement;\n }\n }\n\n return false;\n};\n\n/**\n * Executes a function within a view transition if supported by the browser.\n *\n * @param {VoidFunction} fn - The function to be executed.\n * @returns {ViewTransition} - The result of the executed function.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}\n */\nexport const startViewTransitionSafety = (\n fn: VoidFunction,\n params?: { disabled?: boolean },\n) => {\n if (\n typeof document !== 'undefined' &&\n document.startViewTransition &&\n !params?.disabled\n ) {\n return document.startViewTransition(fn);\n }\n fn();\n};\n\n/**\n * Calculates the scrollbar width.\n */\nexport const calcScrollbarWidth = (elementToAppend = document.body) => {\n const outer = document.createElement('div');\n\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.overflow = 'scroll';\n\n elementToAppend.append(outer);\n\n const inner = document.createElement('div');\n inner.style.width = '100%';\n\n outer.append(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n};\n\n/**\n * Calculates the inner height of an HTML element, accounting for padding.\n */\nexport function getElementInnerHeight(element: HTMLElement) {\n const { clientHeight } = element;\n const { paddingTop, paddingBottom } = getComputedStyle(element);\n return (\n clientHeight -\n Number.parseFloat(paddingTop) -\n Number.parseFloat(paddingBottom)\n );\n}\n\n/**\n * Calculates the inner width of an HTML element, accounting for padding.\n */\nexport function getElementInnerWidth(el: HTMLElement) {\n const { clientWidth } = el;\n const { paddingLeft, paddingRight } = getComputedStyle(el);\n return (\n clientWidth -\n Number.parseFloat(paddingLeft) -\n Number.parseFloat(paddingRight)\n );\n}\n\nexport const isPrefersDarkTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;\n\nexport const isPrefersLightTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"html.js","names":[],"sources":["../src/html.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/html\n *\n * ## Description\n *\n * DOM-centric utilities: sanitizing HTML with **DOMPurify**, computed style probes, downloads via\n * temporary anchors, and small string helpers for safe markup. Prefer these over `innerHTML` with\n * raw user input; keep CSP and server-side validation as the real security boundary.\n *\n * ## Usage\n *\n * ```ts\n * import { getComputedColor } from \"yummies/html\";\n * ```\n */\n\nimport DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';\nimport { blobToUrl } from 'yummies/media';\nimport type { Maybe } from 'yummies/types';\n\n/**\n * Extracts an RGB value from any valid CSS color.\n *\n * Not recommended for frequent use because it triggers a reflow.\n */\nexport const getComputedColor = (color?: string): string | null => {\n if (!color) return null;\n\n const d = document.createElement('div');\n d.style.color = color;\n document.body.append(d);\n const rgbcolor = globalThis.getComputedStyle(d).color;\n const match =\n /rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*\\d+[.d+]*)*\\)/g.exec(rgbcolor);\n\n d.remove();\n\n if (!match) return null;\n\n return `${match[1]}, ${match[2]}, ${match[3]}`;\n};\n\n/**\n * Triggers a file download by creating and clicking a temporary anchor element.\n *\n * @example\n * ```ts\n * downloadUsingAnchor('/report.pdf', 'report.pdf');\n * ```\n */\nexport const downloadUsingAnchor = (\n urlOrBlob: string | Blob,\n fileName?: string,\n) => {\n const url = blobToUrl(urlOrBlob);\n\n const a = document.createElement('a');\n a.href = url;\n\n a.download = fileName ?? 'file';\n\n a.target = '_blank';\n\n document.body.append(a);\n\n a.click();\n\n a.remove();\n};\n\n/**\n * Surrounds string in an anchor tag\n */\nexport function wrapTextToTagLink(link: string) {\n const descr = String(link).replace(/^(https?:\\/{0,2})?(w{3}\\.)?/, 'www.');\n if (!/^https?:\\/{2}/.test(link)) link = `http://${link}`;\n return `<a href=${link} target=\"_blank\">${descr}</a>`;\n}\n\n/**\n * Collects the cumulative `offsetTop` value through the element parent chain.\n *\n * @example\n * ```ts\n * const offsetTop = collectOffsetTop(document.getElementById('section'));\n * ```\n */\nexport const collectOffsetTop = (element: HTMLElement | null) => {\n let offsetTop = 0;\n let node = element;\n\n while (node != null) {\n offsetTop += node.offsetTop;\n node = node.parentElement;\n }\n\n return offsetTop;\n};\n\n/**\n * Prevents the default browser action and stops event propagation.\n *\n * @example\n * ```ts\n * button.addEventListener('click', (event) => skipEvent(event));\n * ```\n */\nexport const skipEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n\n return false;\n};\n\n/**\n * Scrolls the page vertically to the viewport section containing the target element.\n *\n * @example\n * ```ts\n * globalScrollIntoViewForY(document.getElementById('footer')!);\n * ```\n */\nexport const globalScrollIntoViewForY = (node: HTMLElement) => {\n const scrollContainer = document.body;\n const pageHeight = window.innerHeight;\n const nodeBounding = node.getBoundingClientRect();\n const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;\n\n const scrollPageNumber = Math.min(\n Math.max(nodeBounding.top / pageHeight, 1),\n scrollPagesCount,\n );\n\n window.scroll({\n top: scrollPageNumber * pageHeight,\n behavior: 'smooth',\n });\n};\n\nconst sanitizeDefaults: DOMPurifyConfig = {\n ALLOWED_TAGS: [\n 'a',\n 'article',\n 'b',\n 'blockquote',\n 'br',\n 'caption',\n 'code',\n 'del',\n 'details',\n 'div',\n 'em',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'i',\n 'img',\n 'ins',\n 'kbd',\n 'li',\n 'main',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n ],\n ALLOWED_ATTR: ['href', 'target', 'name', 'src', 'class'],\n};\n\n/**\n * Sanitizes HTML using the default allowlist merged with custom DOMPurify config.\n *\n * @example\n * ```ts\n * sanitizeHtml('<img src=x onerror=alert(1) />');\n * ```\n */\nexport const sanitizeHtml = (html: Maybe<string>, config?: DOMPurifyConfig) => {\n return DOMPurify.sanitize(html || '', {\n ...sanitizeDefaults,\n ...config,\n });\n};\n\n/**\n * Checks whether the element is nested inside the provided parent element.\n *\n * @example\n * ```ts\n * checkElementHasParent(childElement, modalElement);\n * ```\n */\nexport const checkElementHasParent = (\n element: HTMLElement | null,\n parent: Maybe<HTMLElement>,\n) => {\n let node = element;\n\n if (!parent) return false;\n\n while (node != null) {\n if (node === parent) {\n return true;\n } else {\n node = node.parentElement;\n }\n }\n\n return false;\n};\n\n/**\n * Executes a function within a view transition if supported by the browser.\n *\n * @param {VoidFunction} fn - The function to be executed.\n * @returns {ViewTransition} - The result of the executed function.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}\n */\nexport const startViewTransitionSafety = (\n fn: VoidFunction,\n params?: { disabled?: boolean },\n) => {\n if (\n typeof document !== 'undefined' &&\n document.startViewTransition &&\n !params?.disabled\n ) {\n return document.startViewTransition(fn);\n }\n fn();\n};\n\n/**\n * Calculates the scrollbar width.\n */\nexport const calcScrollbarWidth = (elementToAppend = document.body) => {\n const outer = document.createElement('div');\n\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.overflow = 'scroll';\n\n elementToAppend.append(outer);\n\n const inner = document.createElement('div');\n inner.style.width = '100%';\n\n outer.append(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n};\n\n/**\n * Calculates the inner height of an HTML element, accounting for padding.\n */\nexport function getElementInnerHeight(element: HTMLElement) {\n const { clientHeight } = element;\n const { paddingTop, paddingBottom } = getComputedStyle(element);\n return (\n clientHeight -\n Number.parseFloat(paddingTop) -\n Number.parseFloat(paddingBottom)\n );\n}\n\n/**\n * Calculates the inner width of an HTML element, accounting for padding.\n */\nexport function getElementInnerWidth(el: HTMLElement) {\n const { clientWidth } = el;\n const { paddingLeft, paddingRight } = getComputedStyle(el);\n return (\n clientWidth -\n Number.parseFloat(paddingLeft) -\n Number.parseFloat(paddingRight)\n );\n}\n\n/**\n * Checks whether the user prefers a dark color scheme.\n *\n * @example\n * ```ts\n * const prefersDark = isPrefersDarkTheme();\n * ```\n */\nexport const isPrefersDarkTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;\n\n/**\n * Checks whether the user prefers a light color scheme.\n *\n * @example\n * ```ts\n * const prefersLight = isPrefersLightTheme();\n * ```\n */\nexport const isPrefersLightTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;\n"],"mappings":"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"}
package/id.cjs CHANGED
@@ -1,21 +1,93 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const nanoid = require("nanoid");
4
- const DIGITS = "0123456789";
5
- const LATIN_CHARS = "abcdefghijklmnopqrstuvwxyz";
6
- const ALPHABET = `${LATIN_CHARS}${DIGITS}`;
7
- const generateId = nanoid.customAlphabet(ALPHABET, 6);
8
- const generateShortId = nanoid.customAlphabet(ALPHABET, 4);
9
- const generateNumericId = nanoid.customAlphabet(DIGITS, 6);
10
- const generateNumericShortId = nanoid.customAlphabet(DIGITS, 4);
11
- const createLinearNumericIdGenerator = (size = 9) => {
12
- let lastCount = 0;
13
- return () => {
14
- return (lastCount++).toString().padStart(size, "0");
15
- };
2
+ require("./chunk-CVq3Gv4J.cjs");
3
+ let nanoid = require("nanoid");
4
+ //#region src/id.ts
5
+ /**
6
+ * ---header-docs-section---
7
+ * # yummies/id
8
+ *
9
+ * ## Description
10
+ *
11
+ * Fast, URL-friendly identifiers based on **nanoid** with curated alphabets and lengths. Use for
12
+ * client-generated keys, trace ids, or UI instance ids where UUID size is unnecessary. Collisions are
13
+ * unlikely at these lengths but still assume server-side uniqueness for persisted entities.
14
+ *
15
+ * ## Usage
16
+ *
17
+ * ```ts
18
+ * import { generateId } from "yummies/id";
19
+ * ```
20
+ */
21
+ var DIGITS = "0123456789";
22
+ var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
23
+ /**
24
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
25
+ * Length: 6.
26
+ */
27
+ var generateId = (0, nanoid.customAlphabet)(ALPHABET, 6);
28
+ /**
29
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
30
+ * Length: 4.
31
+ */
32
+ var generateShortId = (0, nanoid.customAlphabet)(ALPHABET, 4);
33
+ /**
34
+ * Uses the alphabet `0123456789`.
35
+ * Length: 6.
36
+ */
37
+ var generateNumericId = (0, nanoid.customAlphabet)(DIGITS, 6);
38
+ /**
39
+ * Uses the alphabet `0123456789`.
40
+ * Length: 4.
41
+ */
42
+ var generateNumericShortId = (0, nanoid.customAlphabet)(DIGITS, 4);
43
+ /**
44
+ * Creates a function that generates unique strings based on call order.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * generateLinearNumericId = createLinearNumericIdGenerator(6);
49
+ * generateLinearNumericId() // '000000'
50
+ * generateLinearNumericId() // '000001'
51
+ * ...
52
+ * generateLinearNumericId() // '999999'
53
+ * generateLinearNumericId() // '1000000'
54
+ * ...
55
+ * generateLinearNumericId() // '9999999'
56
+ * generateLinearNumericId() // '10000000'
57
+ * ```
58
+ *
59
+ * @param size Minimum string length.
60
+ * @returns {()=>string}
61
+ */
62
+ var createLinearNumericIdGenerator = (size = 9) => {
63
+ let lastCount = 0;
64
+ return () => {
65
+ return (lastCount++).toString().padStart(size, "0");
66
+ };
16
67
  };
17
- const generateLinearNumericId = createLinearNumericIdGenerator();
18
- const generateStackBasedId = () => new Error().stack.split("\n").slice(1, 4).join("");
68
+ /**
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * generateLinearNumericId() // '000000000'
73
+ * generateLinearNumericId() // '000000001'
74
+ * ...
75
+ * generateLinearNumericId() // '999999999'
76
+ * generateLinearNumericId() // '1000000000'
77
+ * ...
78
+ * generateLinearNumericId() // '9999999999'
79
+ * generateLinearNumericId() // '10000000000'
80
+ * ```
81
+ *
82
+ */
83
+ var generateLinearNumericId = createLinearNumericIdGenerator();
84
+ /**
85
+ * Is not recommended to use.
86
+ *
87
+ * Generates execution stack based pseudo-id (just sliced string from error stack)
88
+ */
89
+ var generateStackBasedId = () => (/* @__PURE__ */ new Error()).stack.split("\n").slice(1, 4).join("");
90
+ //#endregion
19
91
  exports.createLinearNumericIdGenerator = createLinearNumericIdGenerator;
20
92
  exports.generateId = generateId;
21
93
  exports.generateLinearNumericId = generateLinearNumericId;
@@ -23,4 +95,5 @@ exports.generateNumericId = generateNumericId;
23
95
  exports.generateNumericShortId = generateNumericShortId;
24
96
  exports.generateShortId = generateShortId;
25
97
  exports.generateStackBasedId = generateStackBasedId;
26
- //# sourceMappingURL=id.cjs.map
98
+
99
+ //# sourceMappingURL=id.cjs.map
package/id.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"id.cjs","sources":["../src/id.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n\n/**\n * Creates a function that generates unique strings based on call order.\n *\n * @example\n * ```ts\n * generateLinearNumericId = createLinearNumericIdGenerator(6);\n * generateLinearNumericId() // '000000'\n * generateLinearNumericId() // '000001'\n * ...\n * generateLinearNumericId() // '999999'\n * generateLinearNumericId() // '1000000'\n * ...\n * generateLinearNumericId() // '9999999'\n * generateLinearNumericId() // '10000000'\n * ```\n *\n * @param size Minimum string length.\n * @returns {()=>string}\n */\nexport const createLinearNumericIdGenerator = (size: number = 9) => {\n let lastCount = 0;\n return () => {\n return (lastCount++).toString().padStart(size, '0');\n };\n};\n\n/**\n *\n * @example\n * ```ts\n * generateLinearNumericId() // '000000000'\n * generateLinearNumericId() // '000000001'\n * ...\n * generateLinearNumericId() // '999999999'\n * generateLinearNumericId() // '1000000000'\n * ...\n * generateLinearNumericId() // '9999999999'\n * generateLinearNumericId() // '10000000000'\n * ```\n *\n */\nexport const generateLinearNumericId = createLinearNumericIdGenerator();\n\n/**\n * Is not recommended to use.\n *\n * Generates execution stack based pseudo-id (just sliced string from error stack)\n */\nexport const generateStackBasedId = () =>\n new Error().stack!.split('\\n').slice(1, 4).join('');\n"],"names":["customAlphabet"],"mappings":";;;AAEA,MAAM,SAAS;AACf,MAAM,cAAc;AAEpB,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM;AAMjC,MAAM,aAAaA,OAAAA,eAAe,UAAU,CAAC;AAM7C,MAAM,kBAAkBA,OAAAA,eAAe,UAAU,CAAC;AAMlD,MAAM,oBAAoBA,OAAAA,eAAe,QAAQ,CAAC;AAMlD,MAAM,yBAAyBA,OAAAA,eAAe,QAAQ,CAAC;AAqBvD,MAAM,iCAAiC,CAAC,OAAe,MAAM;AAClE,MAAI,YAAY;AAChB,SAAO,MAAM;AACX,YAAQ,aAAa,SAAA,EAAW,SAAS,MAAM,GAAG;AAAA,EACpD;AACF;AAiBO,MAAM,0BAA0B,+BAAA;AAOhC,MAAM,uBAAuB,MAClC,IAAI,MAAA,EAAQ,MAAO,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE;;;;;;;;"}
1
+ {"version":3,"file":"id.cjs","names":[],"sources":["../src/id.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/id\n *\n * ## Description\n *\n * Fast, URL-friendly identifiers based on **nanoid** with curated alphabets and lengths. Use for\n * client-generated keys, trace ids, or UI instance ids where UUID size is unnecessary. Collisions are\n * unlikely at these lengths but still assume server-side uniqueness for persisted entities.\n *\n * ## Usage\n *\n * ```ts\n * import { generateId } from \"yummies/id\";\n * ```\n */\n\nimport { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n\n/**\n * Creates a function that generates unique strings based on call order.\n *\n * @example\n * ```ts\n * generateLinearNumericId = createLinearNumericIdGenerator(6);\n * generateLinearNumericId() // '000000'\n * generateLinearNumericId() // '000001'\n * ...\n * generateLinearNumericId() // '999999'\n * generateLinearNumericId() // '1000000'\n * ...\n * generateLinearNumericId() // '9999999'\n * generateLinearNumericId() // '10000000'\n * ```\n *\n * @param size Minimum string length.\n * @returns {()=>string}\n */\nexport const createLinearNumericIdGenerator = (size: number = 9) => {\n let lastCount = 0;\n return () => {\n return (lastCount++).toString().padStart(size, '0');\n };\n};\n\n/**\n *\n * @example\n * ```ts\n * generateLinearNumericId() // '000000000'\n * generateLinearNumericId() // '000000001'\n * ...\n * generateLinearNumericId() // '999999999'\n * generateLinearNumericId() // '1000000000'\n * ...\n * generateLinearNumericId() // '9999999999'\n * generateLinearNumericId() // '10000000000'\n * ```\n *\n */\nexport const generateLinearNumericId = createLinearNumericIdGenerator();\n\n/**\n * Is not recommended to use.\n *\n * Generates execution stack based pseudo-id (just sliced string from error stack)\n */\nexport const generateStackBasedId = () =>\n new Error().stack!.split('\\n').slice(1, 4).join('');\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmBA,IAAM,SAAS;AAGf,IAAM,WAAW,6BAAiB;;;;;AAMlC,IAAa,cAAA,GAAA,OAAA,gBAA4B,UAAU,EAAE;;;;;AAMrD,IAAa,mBAAA,GAAA,OAAA,gBAAiC,UAAU,EAAE;;;;;AAM1D,IAAa,qBAAA,GAAA,OAAA,gBAAmC,QAAQ,EAAE;;;;;AAM1D,IAAa,0BAAA,GAAA,OAAA,gBAAwC,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;AAqB/D,IAAa,kCAAkC,OAAe,MAAM;CAClE,IAAI,YAAY;AAChB,cAAa;AACX,UAAQ,aAAa,UAAU,CAAC,SAAS,MAAM,IAAI;;;;;;;;;;;;;;;;;;AAmBvD,IAAa,0BAA0B,gCAAgC;;;;;;AAOvE,IAAa,8CACX,IAAI,OAAO,EAAC,MAAO,MAAM,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,GAAG"}
package/id.d.ts CHANGED
@@ -1,3 +1,19 @@
1
+ /**
2
+ * ---header-docs-section---
3
+ * # yummies/id
4
+ *
5
+ * ## Description
6
+ *
7
+ * Fast, URL-friendly identifiers based on **nanoid** with curated alphabets and lengths. Use for
8
+ * client-generated keys, trace ids, or UI instance ids where UUID size is unnecessary. Collisions are
9
+ * unlikely at these lengths but still assume server-side uniqueness for persisted entities.
10
+ *
11
+ * ## Usage
12
+ *
13
+ * ```ts
14
+ * import { generateId } from "yummies/id";
15
+ * ```
16
+ */
1
17
  /**
2
18
  * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
3
19
  * Length: 6.