yummies 7.19.4 → 7.20.1

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 (162) hide show
  1. package/assert.cjs +1 -1
  2. package/assert.cjs.map +1 -1
  3. package/assert.js +1 -1
  4. package/assert.js.map +1 -1
  5. package/async.cjs +147 -137
  6. package/async.cjs.map +1 -1
  7. package/async.d.ts +98 -131
  8. package/async.js +147 -137
  9. package/async.js.map +1 -1
  10. package/common.cjs +3 -1
  11. package/common.cjs.map +1 -1
  12. package/common.d.ts +18 -24
  13. package/common.js +3 -1
  14. package/common.js.map +1 -1
  15. package/complex.cjs +1 -0
  16. package/complex.cjs.map +1 -1
  17. package/complex.js +1 -0
  18. package/complex.js.map +1 -1
  19. package/cookie.cjs +1 -1
  20. package/cookie.cjs.map +1 -1
  21. package/cookie.d.ts +0 -18
  22. package/cookie.js +1 -1
  23. package/cookie.js.map +1 -1
  24. package/css-cx.cjs +78 -0
  25. package/css-cx.cjs.map +1 -0
  26. package/css-cx.d.ts +69 -0
  27. package/css-cx.js +74 -0
  28. package/css-cx.js.map +1 -0
  29. package/css.cjs +32 -111
  30. package/css.cjs.map +1 -1
  31. package/css.d.ts +32 -42
  32. package/css.js +30 -107
  33. package/css.js.map +1 -1
  34. package/data.cjs +60 -50
  35. package/data.cjs.map +1 -1
  36. package/data.d.ts +21 -34
  37. package/data.js +60 -50
  38. package/data.js.map +1 -1
  39. package/date-time.cjs +104 -98
  40. package/date-time.cjs.map +1 -1
  41. package/date-time.d.ts +51 -57
  42. package/date-time.js +104 -97
  43. package/date-time.js.map +1 -1
  44. package/device.cjs +14 -19
  45. package/device.cjs.map +1 -1
  46. package/device.d.ts +15 -26
  47. package/device.js +14 -19
  48. package/device.js.map +1 -1
  49. package/encodings.cjs +1 -1
  50. package/encodings.cjs.map +1 -1
  51. package/encodings.d.ts +0 -17
  52. package/encodings.js +1 -1
  53. package/encodings.js.map +1 -1
  54. package/errors.cjs +1 -18
  55. package/errors.cjs.map +1 -1
  56. package/errors.d.ts +0 -17
  57. package/errors.js +1 -17
  58. package/errors.js.map +1 -1
  59. package/file.cjs +3 -17
  60. package/file.cjs.map +1 -1
  61. package/file.d.ts +1 -16
  62. package/file.js +3 -17
  63. package/file.js.map +1 -1
  64. package/format.cjs +1 -1
  65. package/format.cjs.map +1 -1
  66. package/format.js +1 -1
  67. package/format.js.map +1 -1
  68. package/html.cjs +112 -175
  69. package/html.cjs.map +1 -1
  70. package/html.d.ts +58 -57
  71. package/html.js +111 -172
  72. package/html.js.map +1 -1
  73. package/id-nanoid.cjs +36 -0
  74. package/id-nanoid.cjs.map +1 -0
  75. package/id-nanoid.d.ts +26 -0
  76. package/id-nanoid.js +32 -0
  77. package/id-nanoid.js.map +1 -0
  78. package/id.cjs +10 -45
  79. package/id.cjs.map +1 -1
  80. package/id.d.ts +27 -36
  81. package/id.js +6 -40
  82. package/id.js.map +1 -1
  83. package/imports.cjs +3 -18
  84. package/imports.cjs.map +1 -1
  85. package/imports.d.ts +1 -16
  86. package/imports.js +3 -17
  87. package/imports.js.map +1 -1
  88. package/math.cjs +16 -12
  89. package/math.cjs.map +1 -1
  90. package/math.d.ts +9 -24
  91. package/math.js +16 -12
  92. package/math.js.map +1 -1
  93. package/media.cjs +88 -89
  94. package/media.cjs.map +1 -1
  95. package/media.d.ts +72 -80
  96. package/media.js +88 -88
  97. package/media.js.map +1 -1
  98. package/mobx.cjs +0 -1
  99. package/mobx.cjs.map +1 -1
  100. package/mobx.js.map +1 -1
  101. package/ms.cjs +3 -17
  102. package/ms.cjs.map +1 -1
  103. package/ms.d.ts +1 -16
  104. package/ms.js +3 -17
  105. package/ms.js.map +1 -1
  106. package/number.cjs +1 -17
  107. package/number.cjs.map +1 -1
  108. package/number.d.ts +0 -16
  109. package/number.js +1 -17
  110. package/number.js.map +1 -1
  111. package/package.json +6 -6
  112. package/parser.cjs +1 -1
  113. package/parser.cjs.map +1 -1
  114. package/parser.js +1 -1
  115. package/parser.js.map +1 -1
  116. package/price.cjs +1 -1
  117. package/price.cjs.map +1 -1
  118. package/price.d.ts +0 -16
  119. package/price.js +1 -1
  120. package/price.js.map +1 -1
  121. package/random.cjs +37 -39
  122. package/random.cjs.map +1 -1
  123. package/random.d.ts +31 -40
  124. package/random.js +37 -39
  125. package/random.js.map +1 -1
  126. package/react.cjs +0 -1
  127. package/react.cjs.map +1 -1
  128. package/react.js.map +1 -1
  129. package/sanitize-html.cjs +82 -0
  130. package/sanitize-html.cjs.map +1 -0
  131. package/sanitize-html.d.ts +28 -0
  132. package/sanitize-html.js +79 -0
  133. package/sanitize-html.js.map +1 -0
  134. package/sound.cjs +1 -17
  135. package/sound.cjs.map +1 -1
  136. package/sound.d.ts +0 -16
  137. package/sound.js +1 -17
  138. package/sound.js.map +1 -1
  139. package/storage.cjs +7 -5
  140. package/storage.cjs.map +1 -1
  141. package/storage.d.ts +3 -17
  142. package/storage.js +7 -5
  143. package/storage.js.map +1 -1
  144. package/text.cjs +3 -17
  145. package/text.cjs.map +1 -1
  146. package/text.d.ts +1 -16
  147. package/text.js +3 -17
  148. package/text.js.map +1 -1
  149. package/type-guard.cjs +38 -1
  150. package/type-guard.cjs.map +1 -1
  151. package/type-guard.d.ts +38 -0
  152. package/type-guard.js +38 -1
  153. package/type-guard.js.map +1 -1
  154. package/types.d.ts +20 -1
  155. package/types.global.d.ts +19 -0
  156. package/vibrate.cjs +1 -17
  157. package/vibrate.cjs.map +1 -1
  158. package/vibrate.d.ts +0 -16
  159. package/vibrate.js +1 -17
  160. package/vibrate.js.map +1 -1
  161. /package/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
  162. /package/{chunk-CZWwpsFl.cjs → chunk-DakpK96I.cjs} +0 -0
package/html.js CHANGED
@@ -1,64 +1,41 @@
1
- import DOMPurify from "dompurify";
1
+ import { sanitizeHtml } from "./sanitize-html.js";
2
2
  import { blobToUrl } from "yummies/media";
3
- //#region src/html.ts
3
+ //#region src/html/calc-scrollbar-width.ts
4
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.
5
+ * Calculates the scrollbar width.
24
6
  */
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]}`;
7
+ var calcScrollbarWidth = (elementToAppend = document.body) => {
8
+ const outer = document.createElement("div");
9
+ outer.style.visibility = "hidden";
10
+ outer.style.width = "100px";
11
+ outer.style.overflow = "scroll";
12
+ elementToAppend.append(outer);
13
+ const inner = document.createElement("div");
14
+ inner.style.width = "100%";
15
+ outer.append(inner);
16
+ const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
17
+ outer.parentNode?.removeChild(outer);
18
+ return scrollbarWidth;
35
19
  };
20
+ //#endregion
21
+ //#region src/html/check-element-has-parent.ts
36
22
  /**
37
- * Triggers a file download by creating and clicking a temporary anchor element.
23
+ * Checks whether the element is nested inside the provided parent element.
38
24
  *
39
25
  * @example
40
26
  * ```ts
41
- * downloadUsingAnchor('/report.pdf', 'report.pdf');
27
+ * checkElementHasParent(childElement, modalElement);
42
28
  * ```
43
29
  */
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();
30
+ var checkElementHasParent = (element, parent) => {
31
+ let node = element;
32
+ if (!parent) return false;
33
+ while (node != null) if (node === parent) return true;
34
+ else node = node.parentElement;
35
+ return false;
53
36
  };
54
- /**
55
- * Surrounds string in an anchor tag
56
- */
57
- function wrapTextToTagLink(link) {
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>`;
61
- }
37
+ //#endregion
38
+ //#region src/html/collect-offset-top.ts
62
39
  /**
63
40
  * Collects the cumulative `offsetTop` value through the element parent chain.
64
41
  *
@@ -76,19 +53,66 @@ var collectOffsetTop = (element) => {
76
53
  }
77
54
  return offsetTop;
78
55
  };
56
+ //#endregion
57
+ //#region src/html/download-using-anchor.ts
79
58
  /**
80
- * Prevents the default browser action and stops event propagation.
59
+ * Triggers a file download by creating and clicking a temporary anchor element.
81
60
  *
82
61
  * @example
83
62
  * ```ts
84
- * button.addEventListener('click', (event) => skipEvent(event));
63
+ * downloadUsingAnchor('/report.pdf', 'report.pdf');
85
64
  * ```
86
65
  */
87
- var skipEvent = (e) => {
88
- e.preventDefault();
89
- e.stopPropagation();
90
- return false;
66
+ var downloadUsingAnchor = (urlOrBlob, fileName) => {
67
+ const url = blobToUrl(urlOrBlob);
68
+ const a = document.createElement("a");
69
+ a.href = url;
70
+ a.download = fileName ?? "file";
71
+ a.target = "_blank";
72
+ document.body.append(a);
73
+ a.click();
74
+ a.remove();
91
75
  };
76
+ //#endregion
77
+ //#region src/html/get-computed-color.ts
78
+ /**
79
+ * Extracts an RGB value from any valid CSS color.
80
+ *
81
+ * Not recommended for frequent use because it triggers a reflow.
82
+ */
83
+ var getComputedColor = (color) => {
84
+ if (!color) return null;
85
+ const d = document.createElement("div");
86
+ d.style.color = color;
87
+ document.body.append(d);
88
+ const rgbcolor = globalThis.getComputedStyle(d).color;
89
+ const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor);
90
+ d.remove();
91
+ if (!match) return null;
92
+ return `${match[1]}, ${match[2]}, ${match[3]}`;
93
+ };
94
+ //#endregion
95
+ //#region src/html/get-element-inner-height.ts
96
+ /**
97
+ * Calculates the inner height of an HTML element, accounting for padding.
98
+ */
99
+ function getElementInnerHeight(element) {
100
+ const { clientHeight } = element;
101
+ const { paddingTop, paddingBottom } = getComputedStyle(element);
102
+ return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
103
+ }
104
+ //#endregion
105
+ //#region src/html/get-element-inner-width.ts
106
+ /**
107
+ * Calculates the inner width of an HTML element, accounting for padding.
108
+ */
109
+ function getElementInnerWidth(el) {
110
+ const { clientWidth } = el;
111
+ const { paddingLeft, paddingRight } = getComputedStyle(el);
112
+ return clientWidth - Number.parseFloat(paddingLeft) - Number.parseFloat(paddingRight);
113
+ }
114
+ //#endregion
115
+ //#region src/html/global-scroll-into-view-for-y.ts
92
116
  /**
93
117
  * Scrolls the page vertically to the viewport section containing the target element.
94
118
  *
@@ -108,90 +132,45 @@ var globalScrollIntoViewForY = (node) => {
108
132
  behavior: "smooth"
109
133
  });
110
134
  };
135
+ //#endregion
136
+ //#region src/html/is-prefers-dark-theme.ts
111
137
  /**
112
- * Sanitizes HTML using the default allowlist merged with custom DOMPurify config.
138
+ * Checks whether the user prefers a dark color scheme.
113
139
  *
114
- * Default DOMPurify settings are exposed on `sanitizeHtml.defaults` and can be
115
- * overridden per call via `config`.
140
+ * @example
141
+ * ```ts
142
+ * const prefersDark = isPrefersDarkTheme();
143
+ * ```
144
+ */
145
+ var isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
146
+ //#endregion
147
+ //#region src/html/is-prefers-light-theme.ts
148
+ /**
149
+ * Checks whether the user prefers a light color scheme.
116
150
  *
117
151
  * @example
118
152
  * ```ts
119
- * sanitizeHtml('<img src=x onerror=alert(1) />');
153
+ * const prefersLight = isPrefersLightTheme();
120
154
  * ```
121
155
  */
122
- var sanitizeHtml = ((html, config) => {
123
- return DOMPurify.sanitize(html || "", {
124
- ...sanitizeHtml.defaults,
125
- ...config
126
- });
127
- });
128
- sanitizeHtml.defaults = {
129
- ALLOWED_TAGS: [
130
- "a",
131
- "article",
132
- "b",
133
- "blockquote",
134
- "br",
135
- "caption",
136
- "code",
137
- "del",
138
- "details",
139
- "div",
140
- "em",
141
- "h1",
142
- "h2",
143
- "h3",
144
- "h4",
145
- "h5",
146
- "h6",
147
- "hr",
148
- "i",
149
- "img",
150
- "ins",
151
- "kbd",
152
- "li",
153
- "main",
154
- "ol",
155
- "p",
156
- "pre",
157
- "section",
158
- "span",
159
- "strong",
160
- "sub",
161
- "summary",
162
- "sup",
163
- "table",
164
- "tbody",
165
- "td",
166
- "th",
167
- "thead",
168
- "tr",
169
- "u",
170
- "ul"
171
- ],
172
- ALLOWED_ATTR: [
173
- "href",
174
- "target",
175
- "name",
176
- "src",
177
- "class"
178
- ]
179
- };
156
+ var isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
157
+ //#endregion
158
+ //#region src/html/skip-event.ts
180
159
  /**
181
- * Checks whether the element is nested inside the provided parent element.
160
+ * Prevents the default browser action and stops event propagation.
182
161
  *
183
162
  * @example
184
163
  * ```ts
185
- * checkElementHasParent(childElement, modalElement);
164
+ * button.addEventListener('click', (event) => skipEvent(event));
186
165
  * ```
187
166
  */
188
- var checkElementHasParent = (element, parent) => {
189
- let node = element;
190
- if (!parent) return false;
191
- while (node != null) if (node === parent) return true;
192
- else node = node.parentElement;
167
+ var skipEvent = (e) => {
168
+ e.preventDefault();
169
+ e.stopPropagation();
193
170
  return false;
194
171
  };
172
+ //#endregion
173
+ //#region src/html/start-view-transition-safety.ts
195
174
  /**
196
175
  * Executes a function within a view transition if supported by the browser.
197
176
  *
@@ -204,56 +183,16 @@ var startViewTransitionSafety = (fn, params) => {
204
183
  if (typeof document !== "undefined" && document.startViewTransition && !params?.disabled) return document.startViewTransition(fn);
205
184
  fn();
206
185
  };
186
+ //#endregion
187
+ //#region src/html/wrap-text-to-tag-link.ts
207
188
  /**
208
- * Calculates the scrollbar width.
209
- */
210
- var calcScrollbarWidth = (elementToAppend = document.body) => {
211
- const outer = document.createElement("div");
212
- outer.style.visibility = "hidden";
213
- outer.style.width = "100px";
214
- outer.style.overflow = "scroll";
215
- elementToAppend.append(outer);
216
- const inner = document.createElement("div");
217
- inner.style.width = "100%";
218
- outer.append(inner);
219
- const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
220
- outer.parentNode?.removeChild(outer);
221
- return scrollbarWidth;
222
- };
223
- /**
224
- * Calculates the inner height of an HTML element, accounting for padding.
225
- */
226
- function getElementInnerHeight(element) {
227
- const { clientHeight } = element;
228
- const { paddingTop, paddingBottom } = getComputedStyle(element);
229
- return clientHeight - Number.parseFloat(paddingTop) - Number.parseFloat(paddingBottom);
230
- }
231
- /**
232
- * Calculates the inner width of an HTML element, accounting for padding.
189
+ * Surrounds string in an anchor tag
233
190
  */
234
- function getElementInnerWidth(el) {
235
- const { clientWidth } = el;
236
- const { paddingLeft, paddingRight } = getComputedStyle(el);
237
- return clientWidth - Number.parseFloat(paddingLeft) - Number.parseFloat(paddingRight);
191
+ function wrapTextToTagLink(link) {
192
+ const descr = String(link).replace(/^(https?:\/{0,2})?(w{3}\.)?/, "www.");
193
+ if (!/^https?:\/{2}/.test(link)) link = `http://${link}`;
194
+ return `<a href=${link} target="_blank">${descr}</a>`;
238
195
  }
239
- /**
240
- * Checks whether the user prefers a dark color scheme.
241
- *
242
- * @example
243
- * ```ts
244
- * const prefersDark = isPrefersDarkTheme();
245
- * ```
246
- */
247
- var isPrefersDarkTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: dark)")?.matches;
248
- /**
249
- * Checks whether the user prefers a light color scheme.
250
- *
251
- * @example
252
- * ```ts
253
- * const prefersLight = isPrefersLightTheme();
254
- * ```
255
- */
256
- var isPrefersLightTheme = () => !!globalThis.matchMedia?.("(prefers-color-scheme: light)")?.matches;
257
196
  //#endregion
258
197
  export { calcScrollbarWidth, checkElementHasParent, collectOffsetTop, downloadUsingAnchor, getComputedColor, getElementInnerHeight, getElementInnerWidth, globalScrollIntoViewForY, isPrefersDarkTheme, isPrefersLightTheme, sanitizeHtml, skipEvent, startViewTransitionSafety, wrapTextToTagLink };
259
198
 
package/html.js.map CHANGED
@@ -1 +1 @@
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\ntype SanitizeHtmlFn = ((\n html: Maybe<string>,\n config?: DOMPurifyConfig,\n) => string) & {\n /**\n * Default DOMPurify settings\n */\n defaults: DOMPurifyConfig;\n};\n/**\n * Sanitizes HTML using the default allowlist merged with custom DOMPurify config.\n *\n * Default DOMPurify settings are exposed on `sanitizeHtml.defaults` and can be\n * overridden per call via `config`.\n *\n * @example\n * ```ts\n * sanitizeHtml('<img src=x onerror=alert(1) />');\n * ```\n */\nexport const sanitizeHtml = ((\n html: Maybe<string>,\n config?: DOMPurifyConfig,\n) => {\n return DOMPurify.sanitize(html || '', {\n ...sanitizeHtml.defaults,\n ...config,\n });\n}) as SanitizeHtmlFn;\n\nsanitizeHtml.defaults = {\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 * 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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"}
1
+ {"version":3,"file":"html.js","names":[],"sources":["../src/html/calc-scrollbar-width.ts","../src/html/check-element-has-parent.ts","../src/html/collect-offset-top.ts","../src/html/download-using-anchor.ts","../src/html/get-computed-color.ts","../src/html/get-element-inner-height.ts","../src/html/get-element-inner-width.ts","../src/html/global-scroll-into-view-for-y.ts","../src/html/is-prefers-dark-theme.ts","../src/html/is-prefers-light-theme.ts","../src/html/skip-event.ts","../src/html/start-view-transition-safety.ts","../src/html/wrap-text-to-tag-link.ts"],"sourcesContent":["/**\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","import type { Maybe } from 'yummies/types';\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 * 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","import { blobToUrl } from 'yummies/media';\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 * 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 * 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 * 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 * 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","/**\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 * 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","/**\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 * 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 * 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"],"mappings":";;;;;;AAGA,IAAa,sBAAsB,kBAAkB,SAAS,SAAS;CACrE,MAAM,QAAQ,SAAS,cAAc,KAAK;CAE1C,MAAM,MAAM,aAAa;CACzB,MAAM,MAAM,QAAQ;CACpB,MAAM,MAAM,WAAW;CAEvB,gBAAgB,OAAO,KAAK;CAE5B,MAAM,QAAQ,SAAS,cAAc,KAAK;CAC1C,MAAM,MAAM,QAAQ;CAEpB,MAAM,OAAO,KAAK;CAElB,MAAM,iBAAiB,MAAM,cAAc,MAAM;CAEjD,MAAM,YAAY,YAAY,KAAK;CAEnC,OAAO;AACT;;;;;;;;;;;ACZA,IAAa,yBACX,SACA,WACG;CACH,IAAI,OAAO;CAEX,IAAI,CAAC,QAAQ,OAAO;CAEpB,OAAO,QAAQ,MACb,IAAI,SAAS,QACX,OAAO;MAEP,OAAO,KAAK;CAIhB,OAAO;AACT;;;;;;;;;;;ACnBA,IAAa,oBAAoB,YAAgC;CAC/D,IAAI,YAAY;CAChB,IAAI,OAAO;CAEX,OAAO,QAAQ,MAAM;EACnB,aAAa,KAAK;EAClB,OAAO,KAAK;CACd;CAEA,OAAO;AACT;;;;;;;;;;;ACRA,IAAa,uBACX,WACA,aACG;CACH,MAAM,MAAM,UAAU,SAAS;CAE/B,MAAM,IAAI,SAAS,cAAc,GAAG;CACpC,EAAE,OAAO;CAET,EAAE,WAAW,YAAY;CAEzB,EAAE,SAAS;CAEX,SAAS,KAAK,OAAO,CAAC;CAEtB,EAAE,MAAM;CAER,EAAE,OAAO;AACX;;;;;;;;ACvBA,IAAa,oBAAoB,UAAkC;CACjE,IAAI,CAAC,OAAO,OAAO;CAEnB,MAAM,IAAI,SAAS,cAAc,KAAK;CACtC,EAAE,MAAM,QAAQ;CAChB,SAAS,KAAK,OAAO,CAAC;CACtB,MAAM,WAAW,WAAW,iBAAiB,CAAC,EAAE;CAChD,MAAM,QACJ,6DAA6D,KAAK,QAAQ;CAE5E,EAAE,OAAO;CAET,IAAI,CAAC,OAAO,OAAO;CAEnB,OAAO,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG,IAAI,MAAM;AAC5C;;;;;;ACjBA,SAAgB,sBAAsB,SAAsB;CAC1D,MAAM,EAAE,iBAAiB;CACzB,MAAM,EAAE,YAAY,kBAAkB,iBAAiB,OAAO;CAC9D,OACE,eACA,OAAO,WAAW,UAAU,IAC5B,OAAO,WAAW,aAAa;AAEnC;;;;;;ACRA,SAAgB,qBAAqB,IAAiB;CACpD,MAAM,EAAE,gBAAgB;CACxB,MAAM,EAAE,aAAa,iBAAiB,iBAAiB,EAAE;CACzD,OACE,cACA,OAAO,WAAW,WAAW,IAC7B,OAAO,WAAW,YAAY;AAElC;;;;;;;;;;;ACHA,IAAa,4BAA4B,SAAsB;CAC7D,MAAM,kBAAkB,SAAS;CACjC,MAAM,aAAa,OAAO;CAC1B,MAAM,eAAe,KAAK,sBAAsB;CAChD,MAAM,mBAAmB,gBAAgB,eAAe;CAExD,MAAM,mBAAmB,KAAK,IAC5B,KAAK,IAAI,aAAa,MAAM,YAAY,CAAC,GACzC,gBACF;CAEA,OAAO,OAAO;EACZ,KAAK,mBAAmB;EACxB,UAAU;CACZ,CAAC;AACH;;;;;;;;;;;ACfA,IAAa,2BACX,CAAC,CAAC,WAAW,aAAa,8BAA8B,GAAG;;;;;;;;;;;ACD7D,IAAa,4BACX,CAAC,CAAC,WAAW,aAAa,+BAA+B,GAAG;;;;;;;;;;;ACD9D,IAAa,aAAa,MAAa;CACrC,EAAE,eAAe;CACjB,EAAE,gBAAgB;CAElB,OAAO;AACT;;;;;;;;;;;ACLA,IAAa,6BACX,IACA,WACG;CACH,IACE,OAAO,aAAa,eACpB,SAAS,uBACT,CAAC,QAAQ,UAET,OAAO,SAAS,oBAAoB,EAAE;CAExC,GAAG;AACL;;;;;;ACjBA,SAAgB,kBAAkB,MAAc;CAC9C,MAAM,QAAQ,OAAO,IAAI,EAAE,QAAQ,+BAA+B,MAAM;CACxE,IAAI,CAAC,gBAAgB,KAAK,IAAI,GAAG,OAAO,UAAU;CAClD,OAAO,WAAW,KAAK,mBAAmB,MAAM;AAClD"}
package/id-nanoid.cjs ADDED
@@ -0,0 +1,36 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let nanoid = require("nanoid");
3
+ //#region src/id/id-nanoid.ts
4
+ /**
5
+ * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
6
+ * are not used. Consumers import from `yummies/id` — this module is not a public entry point.
7
+ */
8
+ var DIGITS = "0123456789";
9
+ var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
10
+ /**
11
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
12
+ * Length: 6.
13
+ */
14
+ var generateId = (0, nanoid.customAlphabet)(ALPHABET, 6);
15
+ /**
16
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
17
+ * Length: 4.
18
+ */
19
+ var generateShortId = (0, nanoid.customAlphabet)(ALPHABET, 4);
20
+ /**
21
+ * Uses the alphabet `0123456789`.
22
+ * Length: 6.
23
+ */
24
+ var generateNumericId = (0, nanoid.customAlphabet)(DIGITS, 6);
25
+ /**
26
+ * Uses the alphabet `0123456789`.
27
+ * Length: 4.
28
+ */
29
+ var generateNumericShortId = (0, nanoid.customAlphabet)(DIGITS, 4);
30
+ //#endregion
31
+ exports.generateId = generateId;
32
+ exports.generateNumericId = generateNumericId;
33
+ exports.generateNumericShortId = generateNumericShortId;
34
+ exports.generateShortId = generateShortId;
35
+
36
+ //# sourceMappingURL=id-nanoid.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-nanoid.cjs","names":[],"sources":["../src/id/id-nanoid.ts"],"sourcesContent":["/**\n * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.\n * are not used. Consumers import from `yummies/id` — this module is not a public entry point.\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"],"mappings":";;;;;;;AAOA,IAAM,SAAS;AAGf,IAAM,WAAW,6BAAiB;;;;;AAMlC,IAAa,cAAA,GAAA,OAAA,gBAA4B,UAAU,CAAC;;;;;AAMpD,IAAa,mBAAA,GAAA,OAAA,gBAAiC,UAAU,CAAC;;;;;AAMzD,IAAa,qBAAA,GAAA,OAAA,gBAAmC,QAAQ,CAAC;;;;;AAMzD,IAAa,0BAAA,GAAA,OAAA,gBAAwC,QAAQ,CAAC"}
package/id-nanoid.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
3
+ * are not used. Consumers import from `yummies/id` — this module is not a public entry point.
4
+ */
5
+ /**
6
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
7
+ * Length: 6.
8
+ */
9
+ declare const generateId: (size?: number) => string;
10
+ /**
11
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
12
+ * Length: 4.
13
+ */
14
+ declare const generateShortId: (size?: number) => string;
15
+ /**
16
+ * Uses the alphabet `0123456789`.
17
+ * Length: 6.
18
+ */
19
+ declare const generateNumericId: (size?: number) => string;
20
+ /**
21
+ * Uses the alphabet `0123456789`.
22
+ * Length: 4.
23
+ */
24
+ declare const generateNumericShortId: (size?: number) => string;
25
+
26
+ export { generateId, generateNumericId, generateNumericShortId, generateShortId };
package/id-nanoid.js ADDED
@@ -0,0 +1,32 @@
1
+ import { customAlphabet } from "nanoid";
2
+ //#region src/id/id-nanoid.ts
3
+ /**
4
+ * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.
5
+ * are not used. Consumers import from `yummies/id` — this module is not a public entry point.
6
+ */
7
+ var DIGITS = "0123456789";
8
+ var ALPHABET = `abcdefghijklmnopqrstuvwxyz${DIGITS}`;
9
+ /**
10
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
11
+ * Length: 6.
12
+ */
13
+ var generateId = customAlphabet(ALPHABET, 6);
14
+ /**
15
+ * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
16
+ * Length: 4.
17
+ */
18
+ var generateShortId = customAlphabet(ALPHABET, 4);
19
+ /**
20
+ * Uses the alphabet `0123456789`.
21
+ * Length: 6.
22
+ */
23
+ var generateNumericId = customAlphabet(DIGITS, 6);
24
+ /**
25
+ * Uses the alphabet `0123456789`.
26
+ * Length: 4.
27
+ */
28
+ var generateNumericShortId = customAlphabet(DIGITS, 4);
29
+ //#endregion
30
+ export { generateId, generateNumericId, generateNumericShortId, generateShortId };
31
+
32
+ //# sourceMappingURL=id-nanoid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-nanoid.js","names":[],"sources":["../src/id/id-nanoid.ts"],"sourcesContent":["/**\n * @internal Separate chunk so nanoid is tree-shaken away when generateId/generateShortId/etc.\n * are not used. Consumers import from `yummies/id` — this module is not a public entry point.\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"],"mappings":";;;;;;AAOA,IAAM,SAAS;AAGf,IAAM,WAAW,6BAAiB;;;;;AAMlC,IAAa,aAAa,eAAe,UAAU,CAAC;;;;;AAMpD,IAAa,kBAAkB,eAAe,UAAU,CAAC;;;;;AAMzD,IAAa,oBAAoB,eAAe,QAAQ,CAAC;;;;;AAMzD,IAAa,yBAAyB,eAAe,QAAQ,CAAC"}
package/id.cjs CHANGED
@@ -1,45 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("./chunk-CZWwpsFl.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);
2
+ const require_id_nanoid = require("./id-nanoid.cjs");
3
+ //#region src/id/create-linear-numeric-id-generator.ts
43
4
  /**
44
5
  * Creates a function that generates unique strings based on call order.
45
6
  *
@@ -65,6 +26,8 @@ var createLinearNumericIdGenerator = (size = 9) => {
65
26
  return (lastCount++).toString().padStart(size, "0");
66
27
  };
67
28
  };
29
+ //#endregion
30
+ //#region src/id/generate-linear-numeric-id.ts
68
31
  /**
69
32
  *
70
33
  * @example
@@ -81,6 +44,8 @@ var createLinearNumericIdGenerator = (size = 9) => {
81
44
  *
82
45
  */
83
46
  var generateLinearNumericId = createLinearNumericIdGenerator();
47
+ //#endregion
48
+ //#region src/id/generate-stack-based-id.ts
84
49
  /**
85
50
  * Is not recommended to use.
86
51
  *
@@ -89,11 +54,11 @@ var generateLinearNumericId = createLinearNumericIdGenerator();
89
54
  var generateStackBasedId = () => (/* @__PURE__ */ new Error()).stack.split("\n").slice(1, 4).join("");
90
55
  //#endregion
91
56
  exports.createLinearNumericIdGenerator = createLinearNumericIdGenerator;
92
- exports.generateId = generateId;
57
+ exports.generateId = require_id_nanoid.generateId;
93
58
  exports.generateLinearNumericId = generateLinearNumericId;
94
- exports.generateNumericId = generateNumericId;
95
- exports.generateNumericShortId = generateNumericShortId;
96
- exports.generateShortId = generateShortId;
59
+ exports.generateNumericId = require_id_nanoid.generateNumericId;
60
+ exports.generateNumericShortId = require_id_nanoid.generateNumericShortId;
61
+ exports.generateShortId = require_id_nanoid.generateShortId;
97
62
  exports.generateStackBasedId = generateStackBasedId;
98
63
 
99
64
  //# sourceMappingURL=id.cjs.map
package/id.cjs.map CHANGED
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"id.cjs","names":[],"sources":["../src/id/create-linear-numeric-id-generator.ts","../src/id/generate-linear-numeric-id.ts","../src/id/generate-stack-based-id.ts"],"sourcesContent":["/**\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","import { createLinearNumericIdGenerator } from './create-linear-numeric-id-generator.js';\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 * 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,IAAa,kCAAkC,OAAe,MAAM;CAClE,IAAI,YAAY;CAChB,aAAa;EACX,QAAQ,aAAa,SAAS,EAAE,SAAS,MAAM,GAAG;CACpD;AACF;;;;;;;;;;;;;;;;;;ACPA,IAAa,0BAA0B,+BAA+B;;;;;;;;ACZtE,IAAa,8CACX,IAAI,MAAM,GAAE,MAAO,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE"}