@jackens/nnn 2026.4.12 → 2026.4.14

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 (4) hide show
  1. package/nnn.d.ts +213 -104
  2. package/nnn.js +59 -63
  3. package/package.json +1 -1
  4. package/readme.md +522 -236
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # nnn
2
2
 
3
- A collection of Jackens’ JavaScript helper utilities (version: `2026.4.12`).
3
+ A collection of Jackens’ JavaScript helper utilities (version: `2026.4.14`).
4
4
 
5
5
  ## Installation
6
6
 
@@ -19,62 +19,118 @@ npm i @jackens/nnn
19
19
  ```js
20
20
  import {
21
21
  c,
22
- csvParse,
23
- fixPlTypography,
24
- h,
25
- hasOwn,
26
- isArray,
27
- isFiniteNumber,
28
- isInteger,
29
- isNumber,
30
- isRecord,
31
- isString,
32
- jsOnParse,
33
- monokai,
34
- nanolightTs,
35
- newEscape,
36
- newNounForm,
37
- newTokenizer,
38
- omit,
39
- pick,
40
- rwd,
41
- s,
42
- svgUse,
43
- uuidV1,
44
- vivify
22
+ csvParse,
23
+ fixPlTypography,
24
+ h,
25
+ hasOwn,
26
+ isArray,
27
+ isFiniteNumber,
28
+ isInteger,
29
+ isNumber,
30
+ isRecord,
31
+ isString,
32
+ jsOnParse,
33
+ monokai,
34
+ nanolightTs,
35
+ newEscape,
36
+ newNounForm,
37
+ newTokenizer,
38
+ omit,
39
+ pick,
40
+ rwd,
41
+ s,
42
+ svgUse,
43
+ uuidV1,
44
+ vivify,
45
+
45
46
  } from '@jackens/nnn' // or './node_modules/@jackens/nnn/nnn.js'
46
47
  ```
47
48
 
48
49
  ## Exports
49
50
 
50
- - [`CNode`](#CNode): Represents a CSS rule node for the [`c`](#c) helper. Keys are CSS properties or nested selectors.
51
- - [`CRoot`](#CRoot): Represents the root CSS object for the [`c`](#c) helper. Keys are top-level selectors or at-rules.
52
- - [`HArgs`](#HArgs): Tuple argument type for the [`h`](#h) and [`s`](#s) helpers.
53
- - [`HArgs1`](#HArgs1): Single argument type for the [`h`](#h) and [`s`](#s) helpers.
54
- - [`c`](#c): A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
55
- - [`csvParse`](#csvParse): Parses a CSV string into a two-dimensional array of strings.
56
- - [`fixPlTypography`](#fixPlTypography): Applies Polish-specific typographic corrections to a DOM subtree.
57
- - [`h`](#h): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also [`s`](#s)).
58
- - [`hasOwn`](#hasOwn): Checks whether an object has the specified key as its own property.
59
- - [`isArray`](#isArray): Checks whether the argument is an array.
60
- - [`isFiniteNumber`](#isFiniteNumber): Checks whether the argument is a finite number (excludes `±Infinity` and `NaN`).
61
- - [`isInteger`](#isInteger): Checks whether the argument is an integer number.
62
- - [`isNumber`](#isNumber): Checks whether the argument is of type `number` (includes `NaN` and `±Infinity`).
63
- - [`isRecord`](#isRecord): Checks whether the argument is a plain object (not `null` and not an array).
64
- - [`isString`](#isString): Checks whether the argument is a string.
65
- - [`jsOnParse`](#jsOnParse): Parses JSON with support for handler-based value transformation (“JavaScript ON”).
66
- - [`monokai`](#monokai): A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolightTs`](#nanolightTs) tokenizer.
67
- - [`nanolightTs`](#nanolightTs): A TypeScript/JavaScript syntax highlighting tokenizer built using [`newTokenizer`](#newTokenizer).
68
- - [`newEscape`](#newEscape): Creates a tag function for escaping interpolated values in template literals.
69
- - [`newNounForm`](#newNounForm): Creates a function that returns the appropriate noun form based on a numeric value using `Intl.PluralRules`.
70
- - [`newTokenizer`](#newTokenizer): A helper for building simple tokenizers (see also [`nanolightTs`](#nanolightTs)).
71
- - [`omit`](#omit): Creates a new object excluding the specified keys from the source object.
72
- - [`pick`](#pick): Creates a new object containing only the specified keys from the source object.
73
- - [`rwd`](#rwd): A responsive web design helper that generates CSS rules for a grid-like layout.
74
- - [`s`](#s): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also [`h`](#h)).
75
- - [`svgUse`](#svgUse): Shorthand for creating an SVG element with a `<use>` child referencing an icon by ID.
76
- - [`uuidV1`](#uuidV1): Generates a UUID v1 (time-based) identifier.
77
- - [`vivify`](#vivify): A Proxy-based helper for auto-vivification of nested object structures.
51
+ - [`CNode`](#CNode):
52
+ Represents a CSS rule node for the [`c`](#c) helper.
53
+ - [`CRoot`](#CRoot):
54
+ Represents the root CSS object for the [`c`](#c) helper.
55
+ - [`HArgs`](#HArgs):
56
+ Tuple argument type for the [`h`](#h) and [`s`](#s)
57
+ helpers.
58
+ - [`HArgs1`](#HArgs1):
59
+ Single argument type for the [`h`](#h) and [`s`](#s)
60
+ helpers.
61
+ - [`c`](#c):
62
+ A minimal CSS-in-JS helper
63
+ that converts a JavaScript object hierarchy
64
+ into a CSS string.
65
+ - [`csvParse`](#csvParse):
66
+ Parses a CSV string
67
+ into a two-dimensional array of strings.
68
+ - [`fixPlTypography`](#fixPlTypography):
69
+ Applies Polish-specific typographic corrections
70
+ to a DOM subtree.
71
+ - [`h`](#h):
72
+ A lightweight *HyperScript*-style helper
73
+ for creating and modifying `HTMLElement`s
74
+ (see also [`s`](#s)).
75
+ - [`hasOwn`](#hasOwn):
76
+ Checks whether an object has the specified key
77
+ as its own property.
78
+ - [`isArray`](#isArray):
79
+ Checks whether the argument is an array.
80
+ - [`isFiniteNumber`](#isFiniteNumber):
81
+ Checks whether the argument is a finite number
82
+ (excludes `±Infinity` and `NaN`).
83
+ - [`isInteger`](#isInteger):
84
+ Checks whether the argument is an integer number.
85
+ - [`isNumber`](#isNumber):
86
+ Checks whether the argument is of type `number`
87
+ (includes `NaN` and `±Infinity`).
88
+ - [`isRecord`](#isRecord):
89
+ Checks whether the argument is a plain object
90
+ (not `null` and not an array).
91
+ - [`isString`](#isString):
92
+ Checks whether the argument is a string.
93
+ - [`jsOnParse`](#jsOnParse):
94
+ Parses JSON with support for
95
+ handler-based value transformation (“JavaScript ON”).
96
+ - [`monokai`](#monokai):
97
+ A Monokai-inspired color scheme
98
+ for use with the [`c`](#c) helper
99
+ and [`nanolightTs`](#nanolightTs) tokenizer.
100
+ - [`nanolightTs`](#nanolightTs):
101
+ A TypeScript/JavaScript syntax highlighting tokenizer
102
+ built using [`newTokenizer`](#newTokenizer).
103
+ - [`newEscape`](#newEscape):
104
+ Creates a tag function
105
+ for escaping interpolated values in template literals.
106
+ - [`newNounForm`](#newNounForm):
107
+ Creates a function that
108
+ returns the appropriate noun form
109
+ based on a numeric value using `Intl.PluralRules`.
110
+ - [`newTokenizer`](#newTokenizer):
111
+ A helper for building simple tokenizers
112
+ (see also [`nanolightTs`](#nanolightTs)).
113
+ - [`omit`](#omit):
114
+ Creates a new object excluding the specified keys
115
+ from the source object.
116
+ - [`pick`](#pick):
117
+ Creates a new object containing only the specified keys
118
+ from the source object.
119
+ - [`rwd`](#rwd):
120
+ A responsive web design helper
121
+ that generates CSS rules for a grid-like layout.
122
+ - [`s`](#s):
123
+ A lightweight *HyperScript*-style helper
124
+ for creating and modifying `SVGElement`s
125
+ (see also [`h`](#h)).
126
+ - [`svgUse`](#svgUse):
127
+ Shorthand for creating an SVG element
128
+ with a `<use>` child referencing an icon by ID.
129
+ - [`uuidV1`](#uuidV1):
130
+ Generates a UUID v1 (time-based) identifier.
131
+ - [`vivify`](#vivify):
132
+ A Proxy-based helper for auto-vivification
133
+ of nested object structures.
78
134
 
79
135
  ### CNode
80
136
 
@@ -84,7 +140,8 @@ type CNode = {
84
140
  };
85
141
  ```
86
142
 
87
- Represents a CSS rule node for the [`c`](#c) helper. Keys are CSS properties or nested selectors.
143
+ Represents a CSS rule node for the [`c`](#c) helper.
144
+ Keys are CSS properties or nested selectors.
88
145
 
89
146
  ### CRoot
90
147
 
@@ -92,7 +149,8 @@ Represents a CSS rule node for the [`c`](#c) helper. Keys are CSS properties or
92
149
  type CRoot = Record<PropertyKey, CNode>;
93
150
  ```
94
151
 
95
- Represents the root CSS object for the [`c`](#c) helper. Keys are top-level selectors or at-rules.
152
+ Represents the root CSS object for the [`c`](#c) helper.
153
+ Keys are top-level selectors or at-rules.
96
154
 
97
155
  ### HArgs
98
156
 
@@ -100,7 +158,8 @@ Represents the root CSS object for the [`c`](#c) helper. Keys are top-level sele
100
158
  type HArgs = [string | Node, ...HArgs1[]];
101
159
  ```
102
160
 
103
- Tuple argument type for the [`h`](#h) and [`s`](#s) helpers.
161
+ Tuple argument type for the [`h`](#h) and [`s`](#s)
162
+ helpers.
104
163
 
105
164
  ### HArgs1
106
165
 
@@ -108,7 +167,8 @@ Tuple argument type for the [`h`](#h) and [`s`](#s) helpers.
108
167
  type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs;
109
168
  ```
110
169
 
111
- Single argument type for the [`h`](#h) and [`s`](#s) helpers.
170
+ Single argument type for the [`h`](#h) and [`s`](#s)
171
+ helpers.
112
172
 
113
173
  ### c
114
174
 
@@ -116,17 +176,22 @@ Single argument type for the [`h`](#h) and [`s`](#s) helpers.
116
176
  const c: (root: CRoot, splitter?: string) => string;
117
177
  ```
118
178
 
119
- A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
179
+ A minimal CSS-in-JS helper
180
+ that converts a JavaScript object hierarchy
181
+ into a CSS string.
120
182
 
121
183
  #### root
122
184
 
123
185
  An object describing CSS rules.
124
- Keys are selectors or at-rules; values are either CSS property values or nested rule objects.
186
+ Keys are selectors or at-rules;
187
+ values are either CSS property values
188
+ or nested rule objects.
125
189
 
126
190
  #### splitter
127
191
 
128
192
  A delimiter used to create unique keys (default: `'$$'`).
129
- The substring from `splitter` to the end of a key is ignored (e.g., `src$$1` → `src`).
193
+ The substring from `splitter` to the end of a key
194
+ is ignored (e.g., `src$$1` → `src`).
130
195
 
131
196
  #### Returns
132
197
 
@@ -134,12 +199,19 @@ A CSS string representing the compiled rules.
134
199
 
135
200
  #### Remarks
136
201
 
137
- - Keys whose values are primitives (`string` | `number`) are treated as CSS properties.
138
- - In property keys, uppercase letters become lowercase with a `-` prefix (e.g., `fontFamily` → `font-family`);
139
- underscores become hyphens (e.g., `font_family` → `font-family`).
140
- - Comma-separated selector keys expand into multiple selectors
141
- (e.g., `{ div: { '.a,.b': { margin: 1 } } }` → `div.a,div.b{margin:1}`).
142
- - Top-level keys starting with `@` (at-rules) are not concatenated with child selectors.
202
+ - Keys whose values are primitives (`string` | `number`)
203
+ are treated as CSS properties.
204
+ - In property keys, uppercase letters
205
+ become lowercase with a `-` prefix
206
+ (e.g., `fontFamily` → `font-family`);
207
+ underscores become hyphens
208
+ (e.g., `font_family` → `font-family`).
209
+ - Comma-separated selector keys
210
+ expand into multiple selectors
211
+ (e.g., `{ div: { '.a,.b': { margin: 1 } } }` →
212
+ `div.a,div.b{margin:1}`).
213
+ - Top-level keys starting with `@` (at-rules)
214
+ are not concatenated with child selectors.
143
215
 
144
216
  #### Usage Examples
145
217
 
@@ -333,9 +405,11 @@ expect(actual6).to.equal(expected6)
333
405
  const csvParse: (csv: string, separator?: string) => string[][];
334
406
  ```
335
407
 
336
- Parses a CSV string into a two-dimensional array of strings.
408
+ Parses a CSV string
409
+ into a two-dimensional array of strings.
337
410
 
338
- Supports quoted fields with escaped double quotes (`""`). Carriage returns are normalized.
411
+ Supports quoted fields with escaped double quotes (`""`).
412
+ Carriage returns are normalized.
339
413
 
340
414
  #### csv
341
415
 
@@ -347,7 +421,8 @@ The field delimiter (default: `','`).
347
421
 
348
422
  #### Returns
349
423
 
350
- A 2D array where each inner array represents a row of fields.
424
+ A 2D array where each inner array
425
+ represents a row of fields.
351
426
 
352
427
  #### Usage Examples
353
428
 
@@ -374,22 +449,30 @@ expect(csvParse(text)).to.deep.equal([
374
449
  const fixPlTypography: (node: Node) => void;
375
450
  ```
376
451
 
377
- Applies Polish-specific typographic corrections to a DOM subtree.
452
+ Applies Polish-specific typographic corrections
453
+ to a DOM subtree.
378
454
 
379
- This function prevents orphaned conjunctions (single-letter words like “a”, “i”, “o”, “u”, “w”, “z”)
380
- from appearing at the end of a line by wrapping them with the following word in a non-breaking span.
381
- It also inserts zero-width spaces after slashes and dots to allow line breaks.
455
+ This function prevents orphaned conjunctions
456
+ (single-letter words like a”, “i”, “o”, “u”, “w”, “z”)
457
+ from appearing at the end of a line
458
+ by wrapping them with the following word
459
+ in a non-breaking span.
460
+ It also inserts zero-width spaces
461
+ after slashes and dots to allow line breaks.
382
462
 
383
463
  #### node
384
464
 
385
- The root DOM node to process. All descendant text nodes are corrected recursively,
386
- except those inside `IFRAME`, `NOSCRIPT`, `PRE`, `SCRIPT`, `STYLE`, or `TEXTAREA` elements.
465
+ The root DOM node to process.
466
+ All descendant text nodes are corrected recursively,
467
+ except those inside `IFRAME`, `NOSCRIPT`, `PRE`,
468
+ `SCRIPT`, `STYLE`, or `TEXTAREA` elements.
387
469
 
388
470
  #### Usage Examples
389
471
 
390
472
  ```ts
391
473
  const p = h('p',
392
- 'Pchnąć w tę łódź jeża lub ośm skrzyń fig (zob. https://pl.wikipedia.org/wiki/Pangram).',
474
+ 'Pchnąć w tę łódź jeża lub ośm skrzyń fig ' +
475
+ '(zob. https://pl.wikipedia.org/wiki/Pangram).',
393
476
  ['br'],
394
477
  ['b', 'Zażółć gęślą jaźń.'],
395
478
  )
@@ -397,9 +480,13 @@ const p = h('p',
397
480
  fixPlTypography(p)
398
481
 
399
482
  expect(p.innerHTML).to.deep.equal(
400
- 'Pchnąć <span style="white-space:nowrap">w </span>tę łódź jeża lub ośm skrzyń fig ' +
401
- '(zob. https://\u200Bpl.\u200Bwikipedia.\u200Borg/\u200Bwiki/\u200BPangram).' +
402
- '<br><b>Zażółć gęślą jaźń.</b>')
483
+ 'Pchnąć ' +
484
+ '<span style="white-space:nowrap">w </span>' +
485
+ ' łódź jeża lub ośm skrzyń fig ' +
486
+ '(zob. https://\u200Bpl.\u200Bwikipedia.\u200Borg/' +
487
+ '\u200Bwiki/\u200BPangram).' +
488
+ '<br>' +
489
+ '<b>Zażółć gęślą jaźń.</b>')
403
490
  ```
404
491
 
405
492
  ### h
@@ -412,21 +499,28 @@ const h: {
412
499
  };
413
500
  ```
414
501
 
415
- A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also [`s`](#s)).
502
+ A lightweight *HyperScript*-style helper
503
+ for creating and modifying `HTMLElement`s
504
+ (see also [`s`](#s)).
416
505
 
417
506
  #### tagOrNode
418
507
 
419
- If a `string`, it is treated as the tag name for a new element.
508
+ If a `string`, it is treated as the tag name
509
+ for a new element.
420
510
  If a `Node`, that node is modified in place.
421
511
 
422
512
  #### args
423
513
 
424
514
  Additional arguments processed as follows:
425
- - `Object`: maps attributes/properties. Keys starting with `$` set element properties (without the `$` prefix);
426
- other keys set attributes via `setAttribute`. A value of `false` removes the attribute.
515
+ - `Object`: maps attributes/properties.
516
+ Keys starting with `$` set element properties
517
+ (without the `$` prefix);
518
+ other keys set attributes via `setAttribute`.
519
+ A value of `false` removes the attribute.
427
520
  - `null`/`undefined`: ignored.
428
521
  - `Node`: appended as a child.
429
- - `string`/`number`: converted to a `Text` node and appended.
522
+ - `string`/`number`: converted to a `Text` node
523
+ and appended.
430
524
  - [`HArgs`](#HArgs) array: processed recursively.
431
525
 
432
526
  #### Returns
@@ -449,21 +543,32 @@ expect(b.outerHTML).to.equal('<b><i>text</i></b>')
449
543
 
450
544
  h(i, { $className: 'some class' })
451
545
 
452
- expect(i.outerHTML).to.equal('<i class="some class">text</i>')
453
- expect(b.outerHTML).to.equal('<b><i class="some class">text</i></b>')
546
+ expect(i.outerHTML)
547
+ .to.equal('<i class="some class">text</i>')
548
+ expect(b.outerHTML)
549
+ .to.equal('<b><i class="some class">text</i></b>')
454
550
 
455
- expect(h('span', 'text').outerHTML).to.equal('<span>text</span>')
456
- expect(h('span', { $innerText: 'text' }).outerHTML).to.equal('<span>text</span>')
551
+ expect(h('span', 'text').outerHTML)
552
+ .to.equal('<span>text</span>')
553
+ expect(h('span', { $innerText: 'text' }).outerHTML)
554
+ .to.equal('<span>text</span>')
457
555
 
458
- expect(h('span', '42').outerHTML).to.equal('<span>42</span>')
556
+ expect(h('span', '42').outerHTML)
557
+ .to.equal('<span>42</span>')
459
558
  expect(h('span', 42).outerHTML).to.equal('<span>42</span>')
460
559
 
461
560
  expect(h('div', { style: 'margin:0;padding:0' }).outerHTML)
462
561
  .to.equal('<div style="margin:0;padding:0"></div>')
463
562
  expect(h('div', { $style: 'margin:0;padding:0' }).outerHTML)
464
- .to.equal('<div style="margin: 0px; padding: 0px;"></div>')
465
- expect(h('div', { $style: { margin: 0, padding: 0 } }).outerHTML)
466
- .to.equal('<div style="margin: 0px; padding: 0px;"></div>')
563
+ .to.equal(
564
+ '<div style="margin: 0px; padding: 0px;"></div>',
565
+ )
566
+ expect(
567
+ h(
568
+ 'div',
569
+ { $style: { margin: 0, padding: 0 } },
570
+ ).outerHTML,
571
+ ).to.equal('<div style="margin: 0px; padding: 0px;"></div>')
467
572
 
468
573
  const input1 = h('input', { value: 42 })
469
574
  const input2 = h('input', { $value: '42' })
@@ -474,14 +579,22 @@ expect(input2.value).to.equal('42')
474
579
  expect(input1.outerHTML).to.equal('<input value="42">')
475
580
  expect(input2.outerHTML).to.equal('<input>')
476
581
 
477
- const checkbox1 = h('input', { type: 'checkbox', checked: true })
478
- const checkbox2 = h('input', { type: 'checkbox', $checked: true })
582
+ const checkbox1 = h(
583
+ 'input',
584
+ { type: 'checkbox', checked: true },
585
+ )
586
+ const checkbox2 = h(
587
+ 'input',
588
+ { type: 'checkbox', $checked: true },
589
+ )
479
590
 
480
591
  expect(checkbox1.checked).to.be.true
481
592
  expect(checkbox2.checked).to.be.true
482
593
 
483
- expect(checkbox1.outerHTML).to.equal('<input type="checkbox" checked="">')
484
- expect(checkbox2.outerHTML).to.equal('<input type="checkbox">')
594
+ expect(checkbox1.outerHTML)
595
+ .to.equal('<input type="checkbox" checked="">')
596
+ expect(checkbox2.outerHTML)
597
+ .to.equal('<input type="checkbox">')
485
598
 
486
599
  const div = h('div')
487
600
 
@@ -502,11 +615,15 @@ expect(elemWithClass.getAttribute('class')).to.equal('test')
502
615
  const elemWithText = h('div', 'initial')
503
616
 
504
617
  h(elemWithText, ' more')
505
- expect(elemWithText.outerHTML).to.equal('<div>initial more</div>')
618
+ expect(elemWithText.outerHTML)
619
+ .to.equal('<div>initial more</div>')
506
620
 
507
- const elemWithNested = h('div', ['span', 'hello'], ['b', 'world'])
621
+ const elemWithNested = h('div',
622
+ ['span', 'hello'],
623
+ ['b', 'world'])
508
624
 
509
- expect(elemWithNested.outerHTML).to.equal('<div><span>hello</span><b>world</b></div>')
625
+ expect(elemWithNested.outerHTML)
626
+ .to.equal('<div><span>hello</span><b>world</b></div>')
510
627
  ```
511
628
 
512
629
  ### hasOwn
@@ -515,7 +632,8 @@ expect(elemWithNested.outerHTML).to.equal('<div><span>hello</span><b>world</b></
515
632
  const hasOwn: (ref: unknown, key: unknown) => boolean;
516
633
  ```
517
634
 
518
- Checks whether an object has the specified key as its own property.
635
+ Checks whether an object has the specified key
636
+ as its own property.
519
637
 
520
638
  A null-safe wrapper around `Object.hasOwn`.
521
639
 
@@ -529,7 +647,8 @@ The property key to look for.
529
647
 
530
648
  #### Returns
531
649
 
532
- `true` if `ref` is not nullish and has `key` as an own property, `false` otherwise.
650
+ `true` if `ref` is not nullish
651
+ and has `key` as an own property, `false` otherwise.
533
652
 
534
653
  #### Usage Examples
535
654
 
@@ -584,8 +703,15 @@ The value to check.
584
703
 
585
704
  ```ts
586
705
  expect(isArray([])).to.be.true
587
- expect(isArray(Object.create({ constructor: Array }))).to.be.false
588
- expect(isArray(Object.create({ [Symbol.toStringTag]: Array.name }))).to.be.false
706
+
707
+ const fakeArray1 = Object.create({ constructor: Array })
708
+
709
+ expect(isArray(fakeArray1)).to.be.false
710
+
711
+ const fakeArray2 =
712
+ Object.create({ [Symbol.toStringTag]: Array.name })
713
+
714
+ expect(isArray(fakeArray2)).to.be.false
589
715
  ```
590
716
 
591
717
  ### isFiniteNumber
@@ -594,7 +720,8 @@ expect(isArray(Object.create({ [Symbol.toStringTag]: Array.name }))).to.be.false
594
720
  const isFiniteNumber: (arg: unknown) => arg is number;
595
721
  ```
596
722
 
597
- Checks whether the argument is a finite number (excludes `±Infinity` and `NaN`).
723
+ Checks whether the argument is a finite number
724
+ (excludes `±Infinity` and `NaN`).
598
725
 
599
726
  #### arg
600
727
 
@@ -635,7 +762,8 @@ The value to check.
635
762
  ```ts
636
763
  expect(isInteger(42)).to.be.true
637
764
  expect(isInteger(42.00000000000001)).to.be.false
638
- expect(isInteger(42.000000000000001)).to.be.true // because of loss of precision
765
+ expect(isInteger(42.000000000000001)).to.be.true
766
+ // ^because of loss of precision
639
767
  expect(isInteger(Number(42))).to.be.true
640
768
  expect(isInteger(new Number(42))).to.be.false
641
769
  expect(isInteger(NaN)).to.be.false
@@ -648,7 +776,8 @@ expect(isInteger(Infinity)).to.be.false
648
776
  const isNumber: (arg: unknown) => arg is number;
649
777
  ```
650
778
 
651
- Checks whether the argument is of type `number` (includes `NaN` and `±Infinity`).
779
+ Checks whether the argument is of type `number`
780
+ (includes `NaN` and `±Infinity`).
652
781
 
653
782
  #### arg
654
783
 
@@ -674,7 +803,8 @@ expect(isNumber(Infinity)).to.be.true
674
803
  const isRecord: (arg: unknown) => arg is Record<PropertyKey, unknown>;
675
804
  ```
676
805
 
677
- Checks whether the argument is a plain object (not `null` and not an array).
806
+ Checks whether the argument is a plain object
807
+ (not `null` and not an array).
678
808
 
679
809
  #### arg
680
810
 
@@ -690,8 +820,16 @@ The value to check.
690
820
  expect(isRecord({})).to.be.true
691
821
  expect(isRecord([])).to.be.false
692
822
  expect(isRecord(Object.create(null))).to.be.true
693
- expect(isRecord(Object.create({ constructor: Number }))).to.be.true
694
- expect(isRecord(Object.create({ [Symbol.toStringTag]: Number.name }))).to.be.true
823
+
824
+ const fakeNumber1 = Object.create({ constructor: Number })
825
+
826
+ expect(isRecord(fakeNumber1)).to.be.true
827
+
828
+ const fakeNumber2 =
829
+ Object.create({ [Symbol.toStringTag]: Number.name })
830
+
831
+ expect(isRecord(fakeNumber2)).to.be.true
832
+
695
833
  expect(isRecord(new Number(42))).to.be.true
696
834
  expect(isRecord(new String('42'))).to.be.true
697
835
 
@@ -730,10 +868,14 @@ expect(isString(new String('42'))).to.be.false
730
868
  const jsOnParse: (handlers: Record<PropertyKey, Function>, text: string) => any;
731
869
  ```
732
870
 
733
- Parses JSON with support for handler-based value transformation (“JavaScript ON”).
871
+ Parses JSON with support for
872
+ handler-based value transformation (“JavaScript ON”).
734
873
 
735
- Objects with exactly one property whose key exists in `handlers` and whose value is an array
736
- are replaced by invoking the corresponding handler with the array elements as arguments.
874
+ Objects with exactly one property
875
+ whose key exists in `handlers`
876
+ and whose value is an array
877
+ are replaced by invoking the corresponding handler
878
+ with the array elements as arguments.
737
879
 
738
880
  #### handlers
739
881
 
@@ -790,23 +932,37 @@ expect(actual1).to.deep.equal([
790
932
  },
791
933
  'bar',
792
934
  {
793
- $foo: ['The parent object does not have exactly one property!'],
935
+ $foo: [
936
+ 'The parent object does not have ' +
937
+ 'exactly one property!',
938
+ ],
794
939
  one: 1,
795
940
  two: 2,
796
941
  },
797
942
  ])
798
943
 
799
- const actual2 = jsOnParse({ $notFunc: 'handler not being a function' } as any, '{"$notFunc": [1, 2]}')
944
+ const actual2 = jsOnParse(
945
+ { $notFunc: 'handler not being a function' } as any,
946
+ '{"$notFunc": [1, 2]}',
947
+ )
800
948
 
801
949
  expect(actual2).to.deep.equal({ $notFunc: [1, 2] })
802
950
 
803
- const actual3 = jsOnParse(handlers, '{"$unknown_handler_key": [1, 2]}')
951
+ const actual3 = jsOnParse(
952
+ handlers,
953
+ '{"$unknown_handler_key": [1, 2]}',
954
+ )
804
955
 
805
- expect(actual3).to.deep.equal({ $unknown_handler_key: [1, 2] })
956
+ expect(actual3)
957
+ .to.deep.equal({ $unknown_handler_key: [1, 2] })
806
958
 
807
- const actual4 = jsOnParse(handlers, '{"$add": {"not": "array"}}')
959
+ const actual4 = jsOnParse(
960
+ handlers,
961
+ '{"$add": {"not": "array"}}',
962
+ )
808
963
 
809
- expect(actual4).to.deep.equal({ $add: { not: 'array' } })
964
+ expect(actual4)
965
+ .to.deep.equal({ $add: { not: 'array' } })
810
966
  ```
811
967
 
812
968
  ### monokai
@@ -815,7 +971,9 @@ expect(actual4).to.deep.equal({ $add: { not: 'array' } })
815
971
  const monokai: CRoot;
816
972
  ```
817
973
 
818
- A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolightTs`](#nanolightTs) tokenizer.
974
+ A Monokai-inspired color scheme
975
+ for use with the [`c`](#c) helper
976
+ and [`nanolightTs`](#nanolightTs) tokenizer.
819
977
 
820
978
  ### nanolightTs
821
979
 
@@ -823,7 +981,8 @@ A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanoligh
823
981
  const nanolightTs: (code: string) => HArgs1[];
824
982
  ```
825
983
 
826
- A TypeScript/JavaScript syntax highlighting tokenizer built using [`newTokenizer`](#newTokenizer).
984
+ A TypeScript/JavaScript syntax highlighting tokenizer
985
+ built using [`newTokenizer`](#newTokenizer).
827
986
 
828
987
  #### code
829
988
 
@@ -831,17 +990,23 @@ The source code string to tokenize.
831
990
 
832
991
  #### Returns
833
992
 
834
- An array of [`HArgs1`](#HArgs1) elements suitable for rendering with [`h`](#h).
993
+ An array of [`HArgs1`](#HArgs1) elements
994
+ suitable for rendering with [`h`](#h).
835
995
 
836
996
  #### Usage Examples
837
997
 
838
998
  ```ts
839
- const codeJs = "const answerToLifeTheUniverseAndEverything = { 42: 42 }['42'] /* 42 */"
999
+ const codeJs =
1000
+ 'const answerToLifeTheUniverseAndEverything = ' +
1001
+ "{ 42: 42 }['42'] /* 42 */"
840
1002
 
841
1003
  expect(nanolightTs(codeJs)).to.deep.equal([
842
1004
  ['span', { class: 'keyword-1' }, 'const'],
843
1005
  ' ',
844
- ['span', { class: 'identifier-4' }, 'answerToLifeTheUniverseAndEverything'],
1006
+ ['span',
1007
+ { class: 'identifier-4' },
1008
+ 'answerToLifeTheUniverseAndEverything',
1009
+ ],
845
1010
  ' ',
846
1011
  ['span', { class: 'operator' }, '='],
847
1012
  ' ',
@@ -867,15 +1032,18 @@ expect(nanolightTs(codeJs)).to.deep.equal([
867
1032
  const newEscape: (escapeFn: (value: any) => string) => (template: TemplateStringsArray, ...values: unknown[]) => string;
868
1033
  ```
869
1034
 
870
- Creates a tag function for escaping interpolated values in template literals.
1035
+ Creates a tag function
1036
+ for escaping interpolated values in template literals.
871
1037
 
872
1038
  #### escapeFn
873
1039
 
874
- A function that takes a value and returns its escaped string representation.
1040
+ A function that takes a value
1041
+ and returns its escaped string representation.
875
1042
 
876
1043
  #### Returns
877
1044
 
878
- A tag function that escapes interpolated values using the provided escape map.
1045
+ A tag function that escapes interpolated values
1046
+ using the provided escape map.
879
1047
 
880
1048
  #### Usage Examples
881
1049
 
@@ -898,7 +1066,18 @@ const sql = newEscape(escapeFn)
898
1066
  const actual = sql`
899
1067
  SELECT *
900
1068
  FROM table_name
901
- WHERE column_name IN (${[true, null, undefined, NaN, Infinity, 42, '42', "4'2", /42/, new Date(323325000000)]})`
1069
+ WHERE column_name IN (${[
1070
+ true,
1071
+ null,
1072
+ undefined,
1073
+ NaN,
1074
+ Infinity,
1075
+ 42,
1076
+ '42',
1077
+ "4'2",
1078
+ /42/,
1079
+ new Date(323325000000),
1080
+ ]})`
902
1081
 
903
1082
  const expected = `
904
1083
  SELECT *
@@ -914,14 +1093,20 @@ expect(actual).to.equal(expected)
914
1093
  const newNounForm: (locale: string, forms: Partial<Record<Intl.LDMLPluralRule, string>>) => (value: number) => string;
915
1094
  ```
916
1095
 
917
- Creates a function that returns the appropriate noun form based on a numeric value using `Intl.PluralRules`.
1096
+ Creates a function that
1097
+ returns the appropriate noun form
1098
+ based on a numeric value using `Intl.PluralRules`.
918
1099
 
919
- Different languages have different plural rules. The `Intl.PluralRules` API provides locale-aware plural category selection.
1100
+ Different languages have different plural rules.
1101
+ The `Intl.PluralRules` API provides locale-aware
1102
+ plural category selection.
920
1103
  Possible categories are:
921
1104
 
922
- - `zero`: for zero items (used in some languages like Arabic, Latvian)
1105
+ - `zero`: for zero items
1106
+ (used in some languages like Arabic, Latvian)
923
1107
  - `one`: for singular (e.g., 1 item)
924
- - `two`: for dual (used in some languages like Arabic, Hebrew)
1108
+ - `two`: for dual
1109
+ (used in some languages like Arabic, Hebrew)
925
1110
  - `few`: for small plurals (e.g., 2-4 in Polish)
926
1111
  - `many`: for larger plurals (e.g., 5-21 in Polish)
927
1112
  - `other`: fallback category (used by all languages)
@@ -932,17 +1117,24 @@ A BCP 47 language tag (e.g., `pl`, `en`).
932
1117
 
933
1118
  #### forms
934
1119
 
935
- An object mapping plural categories to noun forms. Not all categories need to be provided;
936
- if a category is missing, the function falls back to `other`, then to an empty string.
1120
+ An object mapping plural categories to noun forms.
1121
+ Not all categories need to be provided;
1122
+ if a category is missing,
1123
+ the function falls back to `other`,
1124
+ then to an empty string.
937
1125
 
938
1126
  #### Returns
939
1127
 
940
- A function that takes a numeric value and returns the appropriate noun form.
1128
+ A function that takes a numeric value
1129
+ and returns the appropriate noun form.
941
1130
 
942
1131
  #### Usage Examples
943
1132
 
944
1133
  ```ts
945
- const auto = newNounForm('pl', { one: 'auto', few: 'auta', other: 'aut' })
1134
+ const auto = newNounForm(
1135
+ 'pl',
1136
+ { one: 'auto', few: 'auta', other: 'aut' },
1137
+ )
946
1138
 
947
1139
  expect(auto(0)).to.equal('aut')
948
1140
  expect(auto(1)).to.equal('auto')
@@ -970,29 +1162,39 @@ expect(empty(42)).to.equal('')
970
1162
  const newTokenizer: <M, T>(decorator: (chunk: string, metadata?: M) => T, ...specs: [M, string | RegExp][]) => (code: string) => T[];
971
1163
  ```
972
1164
 
973
- A helper for building simple tokenizers (see also [`nanolightTs`](#nanolightTs)).
1165
+ A helper for building simple tokenizers
1166
+ (see also [`nanolightTs`](#nanolightTs)).
974
1167
 
975
1168
  #### decorator
976
1169
 
977
- A function that wraps each matched chunk. It receives the matched text (`chunk`)
978
- and optionally the `metadata` associated with the pattern that produced the match.
979
- For unmatched text between patterns, `metadata` is `undefined`.
1170
+ A function that wraps each matched chunk.
1171
+ It receives the matched text (`chunk`)
1172
+ and optionally the `metadata`
1173
+ associated with the pattern that produced the match.
1174
+ For unmatched text between patterns,
1175
+ `metadata` is `undefined`.
980
1176
 
981
1177
  #### specs
982
1178
 
983
1179
  An array of tuples `[metadata, pattern]` where:
984
- - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
985
- - `pattern`: a `string` or `RegExp` to match against the input.
1180
+ - `metadata`: arbitrary data (e.g., a CSS class name)
1181
+ passed to `decorator` when the pattern matches.
1182
+ - `pattern`: a `string` or `RegExp`
1183
+ to match against the input.
986
1184
 
987
1185
  #### Returns
988
1186
 
989
- A tokenizer function that accepts a code string and returns an array of decorated tokens.
1187
+ A tokenizer function that accepts a code string
1188
+ and returns an array of decorated tokens.
990
1189
 
991
1190
  #### Remarks
992
1191
 
993
- 1. Matches starting at an earlier position take precedence.
994
- 2. Among matches at the same position, the longer one wins.
995
- 3. Among matches of the same position and length, the one defined earlier wins.
1192
+ 1. Matches starting at an earlier position
1193
+ take precedence.
1194
+ 2. Among matches at the same position,
1195
+ the longer one wins.
1196
+ 3. Among matches of the same position and length,
1197
+ the one defined earlier wins.
996
1198
 
997
1199
  #### Usage Examples
998
1200
 
@@ -1021,7 +1223,13 @@ const tokenizer2 = newTokenizer(
1021
1223
  )
1022
1224
  const result2 = tokenizer2('aBEGINbENDc')
1023
1225
 
1024
- expect(result2).to.deep.equal(['undefined:a', 'tag:BEGIN', 'undefined:b', 'end:END', 'undefined:c'])
1226
+ expect(result2).to.deep.equal([
1227
+ 'undefined:a',
1228
+ 'tag:BEGIN',
1229
+ 'undefined:b',
1230
+ 'end:END',
1231
+ 'undefined:c',
1232
+ ])
1025
1233
 
1026
1234
  const tokenizer3 = newTokenizer(
1027
1235
  (chunk) => chunk,
@@ -1078,7 +1286,7 @@ const result8 = tokenizer8('abc')
1078
1286
  expect(result8).to.deep.equal(['abc'])
1079
1287
 
1080
1288
  const tokenizer9 = newTokenizer(
1081
- (chunk, metadata) => metadata,
1289
+ (_chunk, metadata) => metadata,
1082
1290
  ['a', 'a'],
1083
1291
  ['b', 'b'],
1084
1292
  )
@@ -1093,9 +1301,12 @@ expect(result9).to.deep.equal(['a', 'a', 'b', 'b'])
1093
1301
  const omit: <T, K extends keyof T>(ref: T, keys: unknown[]) => Omit<T, K>;
1094
1302
  ```
1095
1303
 
1096
- Creates a new object excluding the specified keys from the source object.
1304
+ Creates a new object excluding the specified keys
1305
+ from the source object.
1097
1306
 
1098
- A runtime equivalent of TypeScript’s `Omit<T, K>` utility type. See also [`pick`](#pick).
1307
+ A runtime equivalent
1308
+ of TypeScript’s `Omit<T, K>` utility type.
1309
+ See also [`pick`](#pick).
1099
1310
 
1100
1311
  #### ref
1101
1312
 
@@ -1120,12 +1331,15 @@ expect(omit(ref, ['c'])).to.deep.equal({ a: 42, b: '42' })
1120
1331
  ### pick
1121
1332
 
1122
1333
  ```ts
1123
- const pick: <T, K extends keyof T>(ref: T, keys: K[]) => Pick<T, K>;
1334
+ const pick: <T, K extends keyof T>(ref: T, keys: unknown[]) => Pick<T, K>;
1124
1335
  ```
1125
1336
 
1126
- Creates a new object containing only the specified keys from the source object.
1337
+ Creates a new object containing only the specified keys
1338
+ from the source object.
1127
1339
 
1128
- A runtime equivalent of TypeScript’s `Pick<T, K>` utility type. See also [`omit`](#omit).
1340
+ A runtime equivalent
1341
+ of TypeScript’s `Pick<T, K>` utility type.
1342
+ See also [`omit`](#omit).
1129
1343
 
1130
1344
  #### ref
1131
1345
 
@@ -1144,7 +1358,9 @@ A new object with only the specified keys.
1144
1358
  ```ts
1145
1359
  const ref = { a: 42, b: '42', c: 17 }
1146
1360
 
1147
- expect(pick(ref, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
1361
+ expect(pick(ref, ['a', 'b'])).to.deep.equal(
1362
+ { a: 42, b: '42' },
1363
+ )
1148
1364
  ```
1149
1365
 
1150
1366
  ### rwd
@@ -1153,7 +1369,8 @@ expect(pick(ref, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
1153
1369
  const rwd: (root: CRoot, selector: string, cellWidthPx: number, cellHeightPx: number, ...specs: [number, number?, number?][]) => void;
1154
1370
  ```
1155
1371
 
1156
- A responsive web design helper that generates CSS rules for a grid-like layout.
1372
+ A responsive web design helper
1373
+ that generates CSS rules for a grid-like layout.
1157
1374
 
1158
1375
  #### root
1159
1376
 
@@ -1174,9 +1391,12 @@ The base cell height in pixels.
1174
1391
  #### specs
1175
1392
 
1176
1393
  An array of breakpoint specifications, each a tuple of:
1177
- - `maxWidth`: maximum number of cells per row (defines the viewport breakpoint).
1178
- - `width` (optional, default `1`): number of horizontal cells the element spans.
1179
- - `height` (optional, default `1`): number of vertical cells the element spans.
1394
+ - `maxWidth`: maximum number of cells per row
1395
+ (defines the viewport breakpoint).
1396
+ - `width` (optional, default `1`):
1397
+ number of horizontal cells the element spans.
1398
+ - `height` (optional, default `1`):
1399
+ number of vertical cells the element spans.
1180
1400
 
1181
1401
  #### Usage Examples
1182
1402
 
@@ -1195,34 +1415,36 @@ const style: CRoot = {
1195
1415
 
1196
1416
  rwd(style, '.r6', 200, 50, [6], [3], [1, 1, 2])
1197
1417
 
1198
- expect(style).to.deep.equal({
1199
- body: {
1200
- margin: 0,
1201
- },
1202
- '.r6': {
1203
- border: 'solid red 1px',
1204
- '.no-border': {
1205
- border: 'none',
1418
+ expect(style).to.deep.equal(
1419
+ {
1420
+ body: {
1421
+ margin: 0,
1206
1422
  },
1207
- boxSizing: 'border-box',
1208
- display: 'block',
1209
- float: 'left',
1210
- width: '100%',
1211
- height: '100px',
1212
- },
1213
- '@media(min-width:600px)': {
1214
1423
  '.r6': {
1215
- width: 'calc(100% / 3)',
1216
- height: '50px',
1424
+ border: 'solid red 1px',
1425
+ '.no-border': {
1426
+ border: 'none',
1427
+ },
1428
+ boxSizing: 'border-box',
1429
+ display: 'block',
1430
+ float: 'left',
1431
+ width: '100%',
1432
+ height: '100px',
1217
1433
  },
1218
- },
1219
- '@media(min-width:1200px)': {
1220
- '.r6': {
1221
- width: 'calc(50% / 3)',
1222
- height: '50px',
1434
+ '@media(min-width:600px)': {
1435
+ '.r6': {
1436
+ width: 'calc(100% / 3)',
1437
+ height: '50px',
1438
+ },
1439
+ },
1440
+ '@media(min-width:1200px)': {
1441
+ '.r6': {
1442
+ width: 'calc(50% / 3)',
1443
+ height: '50px',
1444
+ },
1223
1445
  },
1224
1446
  },
1225
- })
1447
+ )
1226
1448
  ```
1227
1449
 
1228
1450
  ### s
@@ -1235,21 +1457,28 @@ const s: {
1235
1457
  };
1236
1458
  ```
1237
1459
 
1238
- A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also [`h`](#h)).
1460
+ A lightweight *HyperScript*-style helper
1461
+ for creating and modifying `SVGElement`s
1462
+ (see also [`h`](#h)).
1239
1463
 
1240
1464
  #### tagOrNode
1241
1465
 
1242
- If a `string`, it is treated as the tag name for a new element.
1466
+ If a `string`, it is treated as the tag name
1467
+ for a new element.
1243
1468
  If a `Node`, that node is modified in place.
1244
1469
 
1245
1470
  #### args
1246
1471
 
1247
1472
  Additional arguments processed as follows:
1248
- - `Object`: maps attributes/properties. Keys starting with `$` set element properties (without the `$` prefix);
1249
- other keys set attributes via `setAttributeNS`. A value of `false` removes the attribute.
1473
+ - `Object`: maps attributes/properties.
1474
+ Keys starting with `$` set element properties
1475
+ (without the `$` prefix);
1476
+ other keys set attributes via `setAttributeNS`.
1477
+ A value of `false` removes the attribute.
1250
1478
  - `null`/`undefined`: ignored.
1251
1479
  - `Node`: appended as a child.
1252
- - `string`/`number`: converted to a `Text` node and appended.
1480
+ - `string`/`number`: converted to a `Text` node
1481
+ and appended.
1253
1482
  - [`HArgs`](#HArgs) array: processed recursively.
1254
1483
 
1255
1484
  #### Returns
@@ -1259,25 +1488,28 @@ The created or modified `SVGElement`.
1259
1488
  #### Usage Examples
1260
1489
 
1261
1490
  ```ts
1262
- const svg = s('svg')
1491
+ const XLINK_NS = 'http://www.w3.org/1999/xlink'
1263
1492
 
1264
- s(svg, { 'xlink:href': true })
1265
- expect(svg.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).to.equal('')
1493
+ const svg1 = s('svg', { 'xlink:href': true })
1266
1494
 
1267
- const svg2 = s('svg')
1495
+ expect(svg1.getAttributeNS(XLINK_NS, 'href')).to.equal('')
1268
1496
 
1269
- s(svg2, { 'xlink:href': false })
1270
- expect(svg2.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).to.be.null
1497
+ const svg2 = s('svg', { 'xlink:href': false })
1271
1498
 
1272
- const svg3 = s('svg')
1499
+ expect(svg2.getAttributeNS(XLINK_NS, 'href')).to.be.null
1273
1500
 
1274
- s(svg3, { 'xlink:href': 'http://example.com' })
1275
- expect(svg3.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).to.equal('http://example.com')
1501
+ const svg3 = s(
1502
+ 'svg',
1503
+ { 'xlink:href': 'http://example.com' },
1504
+ )
1505
+
1506
+ expect(svg3.getAttributeNS(XLINK_NS, 'href'))
1507
+ .to.equal('http://example.com')
1276
1508
 
1277
- const svg4 = s('svg')
1509
+ const svg4 = s('svg', { 'xlink:title': 42 })
1278
1510
 
1279
- s(svg4, { 'xlink:title': 42 })
1280
- expect(svg4.getAttributeNS('http://www.w3.org/1999/xlink', 'title')).to.equal('42')
1511
+ expect(svg4.getAttributeNS(XLINK_NS, 'title'))
1512
+ .to.equal('42')
1281
1513
  ```
1282
1514
 
1283
1515
  ### svgUse
@@ -1286,13 +1518,16 @@ expect(svg4.getAttributeNS('http://www.w3.org/1999/xlink', 'title')).to.equal('4
1286
1518
  const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
1287
1519
  ```
1288
1520
 
1289
- Shorthand for creating an SVG element with a `<use>` child referencing an icon by ID.
1521
+ Shorthand for creating an SVG element
1522
+ with a `<use>` child referencing an icon by ID.
1290
1523
 
1291
- Equivalent to: `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
1524
+ Equivalent to:
1525
+ `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
1292
1526
 
1293
1527
  #### id
1294
1528
 
1295
- The ID of the symbol to reference (without the `#` prefix).
1529
+ The ID of the symbol to reference
1530
+ (without the `#` prefix).
1296
1531
 
1297
1532
  #### args
1298
1533
 
@@ -1309,40 +1544,55 @@ const XLINK_NS = 'http://www.w3.org/1999/xlink'
1309
1544
 
1310
1545
  const svg = svgUse('icon-home')
1311
1546
 
1312
- expect(svg.tagName).to.equal('SVG')
1313
1547
  expect(svg.children.length).to.equal(1)
1314
1548
 
1315
1549
  const useElement = svg.children[0]
1316
1550
 
1317
- expect(useElement.tagName).to.equal('USE')
1318
- expect(useElement.getAttributeNS(XLINK_NS, 'href')).to.equal('#icon-home')
1551
+ expect(useElement.getAttributeNS(XLINK_NS, 'href'))
1552
+ .to.equal('#icon-home')
1319
1553
 
1320
- const svgWithViewBox = svgUse('icon-star', { viewBox: '0 0 24 24' })
1554
+ const svgWithViewBox =
1555
+ svgUse('icon-star', { viewBox: '0 0 24 24' })
1321
1556
 
1322
- expect(svgWithViewBox.getAttribute('viewBox')).to.equal('0 0 24 24')
1557
+ expect(svgWithViewBox.getAttribute('viewBox'))
1558
+ .to.equal('0 0 24 24')
1323
1559
 
1324
1560
  const useViewBox = svgWithViewBox.children[0]
1325
1561
 
1326
- expect(useViewBox.getAttributeNS(XLINK_NS, 'href')).to.equal('#icon-star')
1562
+ expect(useViewBox.getAttributeNS(XLINK_NS, 'href'))
1563
+ .to.equal('#icon-star')
1564
+
1565
+ const svgWithClass =
1566
+ svgUse('icon-menu', { class: 'icon-btn' })
1327
1567
 
1328
- const svgWithClass = svgUse('icon-menu', { class: 'icon-btn' })
1568
+ expect(svgWithClass.getAttribute('class'))
1569
+ .to.equal('icon-btn')
1329
1570
 
1330
- expect(svgWithClass.getAttribute('class')).to.equal('icon-btn')
1331
1571
  expect(svgWithClass.children.length).to.equal(1)
1332
1572
 
1333
1573
  const useClass = svgWithClass.children[0]
1334
1574
 
1335
- expect(useClass.getAttributeNS(XLINK_NS, 'href')).to.equal('#icon-menu')
1575
+ expect(useClass.getAttributeNS(XLINK_NS, 'href'))
1576
+ .to.equal('#icon-menu')
1336
1577
 
1337
- const svgWithMultipleAttrs = svgUse('icon-settings', { width: 24, height: 24, class: 'icon' })
1578
+ const svgWithMultipleAttrs = svgUse(
1579
+ 'icon-settings',
1580
+ { width: 24, height: 24, class: 'icon' },
1581
+ )
1582
+
1583
+ expect(svgWithMultipleAttrs.getAttribute('width'))
1584
+ .to.equal('24')
1585
+
1586
+ expect(svgWithMultipleAttrs.getAttribute('height'))
1587
+ .to.equal('24')
1338
1588
 
1339
- expect(svgWithMultipleAttrs.getAttribute('width')).to.equal('24')
1340
- expect(svgWithMultipleAttrs.getAttribute('height')).to.equal('24')
1341
- expect(svgWithMultipleAttrs.getAttribute('class')).to.equal('icon')
1589
+ expect(svgWithMultipleAttrs.getAttribute('class'))
1590
+ .to.equal('icon')
1342
1591
 
1343
1592
  const useMultiple = svgWithMultipleAttrs.children[0]
1344
1593
 
1345
- expect(useMultiple.getAttributeNS(XLINK_NS, 'href')).to.equal('#icon-settings')
1594
+ expect(useMultiple.getAttributeNS(XLINK_NS, 'href'))
1595
+ .to.equal('#icon-settings')
1346
1596
  ```
1347
1597
 
1348
1598
  ### uuidV1
@@ -1355,16 +1605,21 @@ Generates a UUID v1 (time-based) identifier.
1355
1605
 
1356
1606
  #### date
1357
1607
 
1358
- The date to use for the timestamp portion (default: current date/time).
1608
+ The date to use for the timestamp portion
1609
+ (default: current date/time).
1359
1610
 
1360
1611
  #### node
1361
1612
 
1362
- A hexadecimal `string` for the node portion (default: random).
1363
- Must match `/^[0-9a-f]*$/`; it is trimmed to the last 12 characters and left-padded with zeros if shorter.
1613
+ A hexadecimal `string` for the node portion
1614
+ (default: random).
1615
+ Must match `/^[0-9a-f]*$/`;
1616
+ it is trimmed to the last 12 characters
1617
+ and left-padded with zeros if shorter.
1364
1618
 
1365
1619
  #### Returns
1366
1620
 
1367
- A UUID v1 `string` in the standard format `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`.
1621
+ A UUID v1 `string` in the standard format
1622
+ `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`.
1368
1623
 
1369
1624
  #### Usage Examples
1370
1625
 
@@ -1401,10 +1656,17 @@ for (let i = 1; i <= 22136; ++i) {
1401
1656
  }
1402
1657
  }
1403
1658
 
1404
- expect(uuidV1(new Date(), '000123456789abc').split('-')[4]).to.equal('123456789abc')
1405
- expect(uuidV1(new Date(), '123456789').split('-')[4]).to.equal('000123456789')
1659
+ expect(uuidV1(new Date(), '000123456789abc').split('-')[4])
1660
+ .to.equal('123456789abc')
1406
1661
 
1407
- expect(uuidV1(new Date(323325000000)).startsWith('c1399400-9a71-11bd')).to.be.true
1662
+ expect(uuidV1(new Date(), '123456789').split('-')[4])
1663
+ .to.equal('000123456789')
1664
+
1665
+ expect(
1666
+ uuidV1(new Date(323325000000))
1667
+ .startsWith('c1399400-9a71-11bd'),
1668
+ )
1669
+ .to.be.true
1408
1670
  ```
1409
1671
 
1410
1672
  ### vivify
@@ -1413,22 +1675,36 @@ expect(uuidV1(new Date(323325000000)).startsWith('c1399400-9a71-11bd')).to.be.tr
1413
1675
  const vivify: (ref: unknown) => any;
1414
1676
  ```
1415
1677
 
1416
- A Proxy-based helper for auto-vivification of nested object structures.
1678
+ A Proxy-based helper for auto-vivification
1679
+ of nested object structures.
1417
1680
 
1418
- Accessing, assigning, or deleting any nested property on the returned proxy automatically creates intermediate objects
1419
- (or arrays for numeric-string keys matching `^(0|[1-9]\d*)$`) as needed, allowing deep operations without explicit null checks.
1681
+ Accessing, assigning, or deleting any nested property
1682
+ on the returned proxy
1683
+ automatically creates intermediate objects
1684
+ (or arrays for numeric-string keys matching
1685
+ `^(0|[1-9]\d*)$`) as needed,
1686
+ allowing deep operations without explicit null checks.
1420
1687
 
1421
- Intermediates of the last level in a get-only property chain are NOT auto-created.
1422
- For example, `vivify(ref).one.two` will create `ref.one` as `{}`, but will NOT create `ref.one.two`.
1688
+ Intermediates of the last level
1689
+ in a get-only property chain are NOT auto-created.
1690
+ For example, `vivify(ref).one.two` will create
1691
+ `ref.one` as `{}`, but will NOT create `ref.one.two`.
1423
1692
  Only when a deeper access, assignment, or deletion occurs
1424
- (e.g. `delete vivify(ref).one.two.three` or `vivify(ref).one.two.three = 4`) will `ref.one.two` be materialized.
1693
+ (e.g. `delete vivify(ref).one.two.three`
1694
+ or `vivify(ref).one.two.three = 4`)
1695
+ will `ref.one.two` be materialized.
1425
1696
 
1426
- When traversal reaches a primitive value, no auto-creation happens;
1697
+ When traversal reaches a primitive value,
1698
+ no auto-creation happens;
1427
1699
  the primitive’s own property is returned instead
1428
- (e.g. accessing `.toString.name` on a number yields `'toString'` without modifying the underlying structure).
1700
+ (e.g. accessing `.toString.name` on a number yields
1701
+ `'toString'` without modifying the underlying structure).
1429
1702
 
1430
- Deletion on a non-existing intermediate path will auto-create intermediates up to the parent of the deleted key
1431
- (e.g. `delete vivify(ref).one.two.three` will create `ref.one.two` as `{}` if it does not exist).
1703
+ Deletion on a non-existing intermediate path
1704
+ will auto-create intermediates up to the parent
1705
+ of the deleted key
1706
+ (e.g. `delete vivify(ref).one.two.three`
1707
+ will create `ref.one.two` as `{}` if it does not exist).
1432
1708
 
1433
1709
  #### ref
1434
1710
 
@@ -1436,7 +1712,8 @@ The root object to wrap.
1436
1712
 
1437
1713
  #### Returns
1438
1714
 
1439
- A proxy that auto-creates nested objects/arrays on property access.
1715
+ A proxy that auto-creates nested objects/arrays
1716
+ on property access.
1440
1717
 
1441
1718
  #### Usage Examples
1442
1719
 
@@ -1455,7 +1732,12 @@ vivify(ref).one.two[3][4] = 5
1455
1732
 
1456
1733
  expect(ref).to.deep.equal({
1457
1734
  one: {
1458
- two: [undefined, undefined, undefined, [undefined, undefined, undefined, undefined, 5]],
1735
+ two: [
1736
+ undefined,
1737
+ undefined,
1738
+ undefined,
1739
+ [undefined, undefined, undefined, undefined, 5],
1740
+ ],
1459
1741
  },
1460
1742
  })
1461
1743
 
@@ -1495,7 +1777,8 @@ delete vivify(ref).one.two
1495
1777
 
1496
1778
  expect(ref).to.deep.equal({ one: {} })
1497
1779
 
1498
- expect(vivify(ref).one.toString instanceof Function).to.be.true
1780
+ expect(vivify(ref).one.toString instanceof Function)
1781
+ .to.be.true
1499
1782
 
1500
1783
  expect(vivify(ref).one.toString.name).to.equal('toString')
1501
1784
 
@@ -1515,11 +1798,14 @@ expect(ref).to.deep.equal({ one: { two: { three: {} } } })
1515
1798
 
1516
1799
  vivify(ref).one.two.three.four = 5
1517
1800
 
1518
- expect(ref).to.deep.equal({ one: { two: { three: { four: 5 } } } })
1801
+ expect(ref)
1802
+ .to.deep.equal({ one: { two: { three: { four: 5 } } } })
1519
1803
 
1520
- expect(vivify(ref).one.two.three.four.toString.name).to.equal('toString')
1804
+ expect(vivify(ref).one.two.three.four.toString.name)
1805
+ .to.equal('toString')
1521
1806
 
1522
- expect(ref).to.deep.equal({ one: { two: { three: { four: 5 } } } })
1807
+ expect(ref)
1808
+ .to.deep.equal({ one: { two: { three: { four: 5 } } } })
1523
1809
 
1524
1810
  const u = undefined
1525
1811