@jackens/nnn 2026.2.20 → 2026.2.24
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.
- package/nnn.d.ts +31 -31
- package/nnn.js +130 -130
- package/package.json +9 -8
- package/readme.md +148 -148
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nnn
|
|
2
2
|
|
|
3
|
-
A collection of Jackens’ JavaScript helper utilities (version: `2026.2.
|
|
3
|
+
A collection of Jackens’ JavaScript helper utilities (version: `2026.2.24`).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -19,28 +19,28 @@ npm i @jackens/nnn
|
|
|
19
19
|
```js
|
|
20
20
|
import {
|
|
21
21
|
c,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
csvParse,
|
|
23
|
+
escapeValues,
|
|
24
|
+
fixPlTypography,
|
|
25
25
|
h,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
hasOwn,
|
|
27
|
+
isArray,
|
|
28
|
+
isFiniteNumber,
|
|
29
|
+
isNumber,
|
|
30
|
+
isRecord,
|
|
31
|
+
isString,
|
|
32
|
+
jsOnParse,
|
|
33
33
|
monokai,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
nanolightTs,
|
|
35
|
+
newEscape,
|
|
36
|
+
newNounForm,
|
|
37
|
+
newTokenizer,
|
|
38
38
|
omit,
|
|
39
39
|
pick,
|
|
40
40
|
rwd,
|
|
41
41
|
s,
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
svgUse,
|
|
43
|
+
uuidV1,
|
|
44
44
|
vivify
|
|
45
45
|
} from '@jackens/nnn' // or './node_modules/@jackens/nnn/nnn.js'
|
|
46
46
|
```
|
|
@@ -53,35 +53,35 @@ import {
|
|
|
53
53
|
- [`HArgs`](#HArgs): Tuple argument type for the [`h`](#h) and [`s`](#s) helpers.
|
|
54
54
|
- [`HArgs1`](#HArgs1): Single argument type for the [`h`](#h) and [`s`](#s) helpers.
|
|
55
55
|
- [`c`](#c): A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
|
|
56
|
-
- [`
|
|
57
|
-
- [`
|
|
58
|
-
- [`
|
|
56
|
+
- [`csvParse`](#csvParse): Parses a CSV string into a two-dimensional array of strings.
|
|
57
|
+
- [`escapeValues`](#escapeValues): Escapes an array of values using the provided escape map.
|
|
58
|
+
- [`fixPlTypography`](#fixPlTypography): Applies Polish-specific typographic corrections to a DOM subtree.
|
|
59
59
|
- [`h`](#h): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also [`s`](#s)).
|
|
60
|
-
- [`
|
|
61
|
-
- [`
|
|
62
|
-
- [`
|
|
63
|
-
- [`
|
|
64
|
-
- [`
|
|
65
|
-
- [`
|
|
66
|
-
- [`
|
|
67
|
-
- [`monokai`](#monokai): A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`
|
|
68
|
-
- [`
|
|
69
|
-
- [`
|
|
70
|
-
- [`
|
|
71
|
-
- [`
|
|
60
|
+
- [`hasOwn`](#hasOwn): Checks whether an object has the specified key as its own property.
|
|
61
|
+
- [`isArray`](#isArray): Checks whether the argument is an array.
|
|
62
|
+
- [`isFiniteNumber`](#isFiniteNumber): Checks whether the argument is a finite number (excludes `±Infinity` and `NaN`).
|
|
63
|
+
- [`isNumber`](#isNumber): Checks whether the argument is of type `number` (includes `NaN` and `±Infinity`).
|
|
64
|
+
- [`isRecord`](#isRecord): Checks whether the argument is a plain object (not `null` and not an array).
|
|
65
|
+
- [`isString`](#isString): Checks whether the argument is a string.
|
|
66
|
+
- [`jsOnParse`](#jsOnParse): Parses JSON with support for handler-based value transformation (“JavaScript ON”).
|
|
67
|
+
- [`monokai`](#monokai): A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolightTs`](#nanolightTs) tokenizer.
|
|
68
|
+
- [`nanolightTs`](#nanolightTs): A TypeScript/JavaScript syntax highlighting tokenizer built using [`newTokenizer`](#newTokenizer).
|
|
69
|
+
- [`newEscape`](#newEscape): Creates a tag function for escaping interpolated values in template literals.
|
|
70
|
+
- [`newNounForm`](#newNounForm): Creates a function that returns the appropriate noun form based on a numeric value using `Intl.PluralRules`.
|
|
71
|
+
- [`newTokenizer`](#newTokenizer): A helper for building simple tokenizers (see also [`nanolightTs`](#nanolightTs)).
|
|
72
72
|
- [`omit`](#omit): Creates a new object excluding the specified keys from the source object.
|
|
73
73
|
- [`pick`](#pick): Creates a new object containing only the specified keys from the source object.
|
|
74
74
|
- [`rwd`](#rwd): A responsive web design helper that generates CSS rules for a grid-like layout.
|
|
75
75
|
- [`s`](#s): A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also [`h`](#h)).
|
|
76
|
-
- [`
|
|
77
|
-
- [`
|
|
76
|
+
- [`svgUse`](#svgUse): Shorthand for creating an SVG element with a `<use>` child referencing an icon by ID.
|
|
77
|
+
- [`uuidV1`](#uuidV1): Generates a UUID v1 (time-based) identifier.
|
|
78
78
|
- [`vivify`](#vivify): A Proxy-based helper for auto-vivification of nested object structures.
|
|
79
79
|
|
|
80
80
|
### CNode
|
|
81
81
|
|
|
82
82
|
```ts
|
|
83
83
|
type CNode = {
|
|
84
|
-
[
|
|
84
|
+
[attributeOrSelector: string]: string | number | CNode | undefined;
|
|
85
85
|
};
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -103,7 +103,7 @@ type EscapeMap = Map<unknown, (value?: unknown) => string>;
|
|
|
103
103
|
|
|
104
104
|
A map from value constructors (or `null`/`undefined`) to escape functions.
|
|
105
105
|
|
|
106
|
-
Used by [`
|
|
106
|
+
Used by [`escapeValues`](#escapeValues) and [`newEscape`](#newEscape).
|
|
107
107
|
|
|
108
108
|
### HArgs
|
|
109
109
|
|
|
@@ -155,7 +155,7 @@ A CSS string representing the compiled rules.
|
|
|
155
155
|
#### Usage Examples
|
|
156
156
|
|
|
157
157
|
```ts
|
|
158
|
-
const
|
|
158
|
+
const actual1 = c({
|
|
159
159
|
a: {
|
|
160
160
|
color: 'red',
|
|
161
161
|
margin: 1,
|
|
@@ -164,7 +164,7 @@ const actual_1 = c({
|
|
|
164
164
|
}
|
|
165
165
|
})
|
|
166
166
|
|
|
167
|
-
const
|
|
167
|
+
const expected1 = `
|
|
168
168
|
a{
|
|
169
169
|
color:red;
|
|
170
170
|
margin:1
|
|
@@ -177,9 +177,9 @@ a{
|
|
|
177
177
|
padding:1
|
|
178
178
|
}`.replace(/\n\s*/g, '')
|
|
179
179
|
|
|
180
|
-
expect(
|
|
180
|
+
expect(actual1).to.equal(expected1)
|
|
181
181
|
|
|
182
|
-
const
|
|
182
|
+
const actual2 = c({
|
|
183
183
|
a: {
|
|
184
184
|
'.b': {
|
|
185
185
|
color: 'red',
|
|
@@ -190,7 +190,7 @@ const actual_2 = c({
|
|
|
190
190
|
}
|
|
191
191
|
})
|
|
192
192
|
|
|
193
|
-
const
|
|
193
|
+
const expected2 = `
|
|
194
194
|
a.b{
|
|
195
195
|
color:red;
|
|
196
196
|
margin:1
|
|
@@ -203,9 +203,9 @@ a.b{
|
|
|
203
203
|
padding:1
|
|
204
204
|
}`.replace(/\n\s*/g, '')
|
|
205
205
|
|
|
206
|
-
expect(
|
|
206
|
+
expect(actual2).to.equal(expected2)
|
|
207
207
|
|
|
208
|
-
const
|
|
208
|
+
const actual3 = c({
|
|
209
209
|
'@font-face$$1': {
|
|
210
210
|
fontFamily: 'Jackens',
|
|
211
211
|
src$$1: 'url(otf/jackens.otf)',
|
|
@@ -234,7 +234,7 @@ const actual_3 = c({
|
|
|
234
234
|
}
|
|
235
235
|
})
|
|
236
236
|
|
|
237
|
-
const
|
|
237
|
+
const expected3 = `
|
|
238
238
|
@font-face{
|
|
239
239
|
font-family:Jackens;
|
|
240
240
|
src:url(otf/jackens.otf);
|
|
@@ -276,9 +276,9 @@ div.c2{
|
|
|
276
276
|
}
|
|
277
277
|
}`.replace(/\n\s*/g, '')
|
|
278
278
|
|
|
279
|
-
expect(
|
|
279
|
+
expect(actual3).to.equal(expected3)
|
|
280
280
|
|
|
281
|
-
const
|
|
281
|
+
const actual4 = c({
|
|
282
282
|
a: {
|
|
283
283
|
'.b,.c': {
|
|
284
284
|
margin: 1,
|
|
@@ -289,7 +289,7 @@ const actual_4 = c({
|
|
|
289
289
|
}
|
|
290
290
|
})
|
|
291
291
|
|
|
292
|
-
const
|
|
292
|
+
const expected4 = `
|
|
293
293
|
a.b,a.c{
|
|
294
294
|
margin:1
|
|
295
295
|
}
|
|
@@ -297,9 +297,9 @@ a.b.d,a.c.d{
|
|
|
297
297
|
margin:2
|
|
298
298
|
}`.replace(/\n\s*/g, '')
|
|
299
299
|
|
|
300
|
-
expect(
|
|
300
|
+
expect(actual4).to.equal(expected4)
|
|
301
301
|
|
|
302
|
-
const
|
|
302
|
+
const actual5 = c({
|
|
303
303
|
'.b,.c': {
|
|
304
304
|
margin: 1,
|
|
305
305
|
'.d': {
|
|
@@ -308,7 +308,7 @@ const actual_5 = c({
|
|
|
308
308
|
}
|
|
309
309
|
})
|
|
310
310
|
|
|
311
|
-
const
|
|
311
|
+
const expected5 = `
|
|
312
312
|
.b,.c{
|
|
313
313
|
margin:1
|
|
314
314
|
}
|
|
@@ -316,9 +316,9 @@ const expected_5 = `
|
|
|
316
316
|
margin:2
|
|
317
317
|
}`.replace(/\n\s*/g, '')
|
|
318
318
|
|
|
319
|
-
expect(
|
|
319
|
+
expect(actual5).to.equal(expected5)
|
|
320
320
|
|
|
321
|
-
const
|
|
321
|
+
const actual6 = c({
|
|
322
322
|
'.a,.b': {
|
|
323
323
|
margin: 1,
|
|
324
324
|
'.c,.d': {
|
|
@@ -327,7 +327,7 @@ const actual_6 = c({
|
|
|
327
327
|
}
|
|
328
328
|
})
|
|
329
329
|
|
|
330
|
-
const
|
|
330
|
+
const expected6 = `
|
|
331
331
|
.a,.b{
|
|
332
332
|
margin:1
|
|
333
333
|
}
|
|
@@ -335,13 +335,13 @@ const expected_6 = `
|
|
|
335
335
|
margin:2
|
|
336
336
|
}`.replace(/\n\s*/g, '')
|
|
337
337
|
|
|
338
|
-
expect(
|
|
338
|
+
expect(actual6).to.equal(expected6)
|
|
339
339
|
```
|
|
340
340
|
|
|
341
|
-
###
|
|
341
|
+
### csvParse
|
|
342
342
|
|
|
343
343
|
```ts
|
|
344
|
-
const
|
|
344
|
+
const csvParse: (csv: string, separator?: string) => string[][];
|
|
345
345
|
```
|
|
346
346
|
|
|
347
347
|
Parses a CSV string into a two-dimensional array of strings.
|
|
@@ -372,22 +372,22 @@ yyy",zzz
|
|
|
372
372
|
|
|
373
373
|
`
|
|
374
374
|
|
|
375
|
-
expect(
|
|
375
|
+
expect(csvParse(text)).to.deep.equal([
|
|
376
376
|
['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
|
|
377
377
|
['xxx,xxx', 'yyy\nyyy', 'zzz'],
|
|
378
378
|
[' 42 ', '42', ' 17']
|
|
379
379
|
])
|
|
380
380
|
```
|
|
381
381
|
|
|
382
|
-
###
|
|
382
|
+
### escapeValues
|
|
383
383
|
|
|
384
384
|
```ts
|
|
385
|
-
const
|
|
385
|
+
const escapeValues: (escapeMap: EscapeMap, values: unknown[]) => string[];
|
|
386
386
|
```
|
|
387
387
|
|
|
388
388
|
Escapes an array of values using the provided escape map.
|
|
389
389
|
|
|
390
|
-
####
|
|
390
|
+
#### escapeMap
|
|
391
391
|
|
|
392
392
|
A map where keys are constructors (e.g., `String`, `Number`) and values are escape functions.
|
|
393
393
|
|
|
@@ -399,10 +399,10 @@ The array of values to escape.
|
|
|
399
399
|
|
|
400
400
|
An array of escaped strings.
|
|
401
401
|
|
|
402
|
-
###
|
|
402
|
+
### fixPlTypography
|
|
403
403
|
|
|
404
404
|
```ts
|
|
405
|
-
const
|
|
405
|
+
const fixPlTypography: (node: Node) => void;
|
|
406
406
|
```
|
|
407
407
|
|
|
408
408
|
Applies Polish-specific typographic corrections to a DOM subtree.
|
|
@@ -421,7 +421,7 @@ except those inside `IFRAME`, `NOSCRIPT`, `PRE`, `SCRIPT`, `STYLE`, or `TEXTAREA
|
|
|
421
421
|
```ts
|
|
422
422
|
const p = h('p', 'Pchnąć w tę łódź jeża lub ośm skrzyń fig (zob. https://pl.wikipedia.org/wiki/Pangram).')
|
|
423
423
|
|
|
424
|
-
|
|
424
|
+
fixPlTypography(p)
|
|
425
425
|
|
|
426
426
|
expect(p.innerHTML).to.deep.equal(
|
|
427
427
|
'Pchnąć <span style="white-space:nowrap">w </span>tę łódź jeża lub ośm skrzyń fig ' +
|
|
@@ -434,13 +434,13 @@ expect(p.innerHTML).to.deep.equal(
|
|
|
434
434
|
const h: {
|
|
435
435
|
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1[]): HTMLElementTagNameMap[T];
|
|
436
436
|
<N extends Node>(node: N, ...args1: HArgs1[]): N;
|
|
437
|
-
(
|
|
437
|
+
(tagOrNode: string | Node, ...args1: HArgs1[]): Node;
|
|
438
438
|
};
|
|
439
439
|
```
|
|
440
440
|
|
|
441
441
|
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also [`s`](#s)).
|
|
442
442
|
|
|
443
|
-
####
|
|
443
|
+
#### tagOrNode
|
|
444
444
|
|
|
445
445
|
If a `string`, it is treated as the tag name for a new element.
|
|
446
446
|
If a `Node`, that node is modified in place.
|
|
@@ -522,10 +522,10 @@ h(div, { $key: { two: 2 } })
|
|
|
522
522
|
expect(div.key).to.deep.equal({ one: 1, two: 2 })
|
|
523
523
|
```
|
|
524
524
|
|
|
525
|
-
###
|
|
525
|
+
### hasOwn
|
|
526
526
|
|
|
527
527
|
```ts
|
|
528
|
-
const
|
|
528
|
+
const hasOwn: (ref: unknown, key: unknown) => boolean;
|
|
529
529
|
```
|
|
530
530
|
|
|
531
531
|
Checks whether an object has the specified key as its own property.
|
|
@@ -550,37 +550,37 @@ The property key to look for.
|
|
|
550
550
|
const obj = { 42: null, null: 'k,e,y', 'k,e,y': 42 }
|
|
551
551
|
|
|
552
552
|
expect(42 in obj).to.be.true
|
|
553
|
-
expect(
|
|
553
|
+
expect(hasOwn(obj, 42)).to.be.true
|
|
554
554
|
|
|
555
555
|
expect('42' in obj).to.be.true
|
|
556
|
-
expect(
|
|
556
|
+
expect(hasOwn(obj, '42')).to.be.true
|
|
557
557
|
|
|
558
558
|
expect('null' in obj).to.be.true
|
|
559
|
-
expect(
|
|
559
|
+
expect(hasOwn(obj, 'null')).to.be.true
|
|
560
560
|
|
|
561
561
|
expect(null in obj).to.be.true
|
|
562
|
-
expect(
|
|
562
|
+
expect(hasOwn(obj, null)).to.be.true
|
|
563
563
|
|
|
564
564
|
expect('k,e,y' in obj).to.be.true
|
|
565
|
-
expect(
|
|
565
|
+
expect(hasOwn(obj, 'k,e,y')).to.be.true
|
|
566
566
|
|
|
567
567
|
expect(['k', 'e', 'y'] in obj).to.be.true
|
|
568
|
-
expect(
|
|
568
|
+
expect(hasOwn(obj, ['k', 'e', 'y'])).to.be.true
|
|
569
569
|
|
|
570
570
|
expect('toString' in obj).to.be.true
|
|
571
|
-
expect(
|
|
571
|
+
expect(hasOwn(obj, 'toString')).to.be.false
|
|
572
572
|
|
|
573
573
|
expect(() => 'key' in null).to.throw
|
|
574
|
-
expect(
|
|
574
|
+
expect(hasOwn(null, 'key')).to.be.false
|
|
575
575
|
|
|
576
576
|
expect(() => 'key' in undefined).to.throw
|
|
577
|
-
expect(
|
|
577
|
+
expect(hasOwn(undefined, 'key')).to.be.false
|
|
578
578
|
```
|
|
579
579
|
|
|
580
|
-
###
|
|
580
|
+
### isArray
|
|
581
581
|
|
|
582
582
|
```ts
|
|
583
|
-
const
|
|
583
|
+
const isArray: (arg: unknown) => arg is unknown[];
|
|
584
584
|
```
|
|
585
585
|
|
|
586
586
|
Checks whether the argument is an array.
|
|
@@ -596,15 +596,15 @@ The value to check.
|
|
|
596
596
|
#### Usage Examples
|
|
597
597
|
|
|
598
598
|
```ts
|
|
599
|
-
expect(
|
|
600
|
-
expect(
|
|
601
|
-
expect(
|
|
599
|
+
expect(isArray([])).to.be.true
|
|
600
|
+
expect(isArray(Object.create({ constructor: Array }))).to.be.false
|
|
601
|
+
expect(isArray(Object.create({ [Symbol.toStringTag]: Array.name }))).to.be.false
|
|
602
602
|
```
|
|
603
603
|
|
|
604
|
-
###
|
|
604
|
+
### isFiniteNumber
|
|
605
605
|
|
|
606
606
|
```ts
|
|
607
|
-
const
|
|
607
|
+
const isFiniteNumber: (arg: unknown) => arg is number;
|
|
608
608
|
```
|
|
609
609
|
|
|
610
610
|
Checks whether the argument is a finite number (excludes `±Infinity` and `NaN`).
|
|
@@ -620,17 +620,17 @@ The value to check.
|
|
|
620
620
|
#### Usage Examples
|
|
621
621
|
|
|
622
622
|
```ts
|
|
623
|
-
expect(
|
|
624
|
-
expect(
|
|
625
|
-
expect(
|
|
626
|
-
expect(
|
|
627
|
-
expect(
|
|
623
|
+
expect(isFiniteNumber(42)).to.be.true
|
|
624
|
+
expect(isFiniteNumber(Number(42))).to.be.true
|
|
625
|
+
expect(isFiniteNumber(new Number(42))).to.be.false
|
|
626
|
+
expect(isFiniteNumber(NaN)).to.be.false
|
|
627
|
+
expect(isFiniteNumber(Infinity)).to.be.false
|
|
628
628
|
```
|
|
629
629
|
|
|
630
|
-
###
|
|
630
|
+
### isNumber
|
|
631
631
|
|
|
632
632
|
```ts
|
|
633
|
-
const
|
|
633
|
+
const isNumber: (arg: unknown) => arg is number;
|
|
634
634
|
```
|
|
635
635
|
|
|
636
636
|
Checks whether the argument is of type `number` (includes `NaN` and `±Infinity`).
|
|
@@ -646,17 +646,17 @@ The value to check.
|
|
|
646
646
|
#### Usage Examples
|
|
647
647
|
|
|
648
648
|
```ts
|
|
649
|
-
expect(
|
|
650
|
-
expect(
|
|
651
|
-
expect(
|
|
652
|
-
expect(
|
|
653
|
-
expect(
|
|
649
|
+
expect(isNumber(42)).to.be.true
|
|
650
|
+
expect(isNumber(Number(42))).to.be.true
|
|
651
|
+
expect(isNumber(new Number(42))).to.be.false
|
|
652
|
+
expect(isNumber(NaN)).to.be.true
|
|
653
|
+
expect(isNumber(Infinity)).to.be.true
|
|
654
654
|
```
|
|
655
655
|
|
|
656
|
-
###
|
|
656
|
+
### isRecord
|
|
657
657
|
|
|
658
658
|
```ts
|
|
659
|
-
const
|
|
659
|
+
const isRecord: (arg: unknown) => arg is Record<PropertyKey, unknown>;
|
|
660
660
|
```
|
|
661
661
|
|
|
662
662
|
Checks whether the argument is a plain object (not `null` and not an array).
|
|
@@ -672,23 +672,23 @@ The value to check.
|
|
|
672
672
|
#### Usage Examples
|
|
673
673
|
|
|
674
674
|
```ts
|
|
675
|
-
expect(
|
|
676
|
-
expect(
|
|
677
|
-
expect(
|
|
678
|
-
expect(
|
|
679
|
-
expect(
|
|
680
|
-
expect(
|
|
681
|
-
expect(
|
|
675
|
+
expect(isRecord({})).to.be.true
|
|
676
|
+
expect(isRecord([])).to.be.false
|
|
677
|
+
expect(isRecord(Object.create(null))).to.be.true
|
|
678
|
+
expect(isRecord(Object.create({ constructor: Number }))).to.be.true
|
|
679
|
+
expect(isRecord(Object.create({ [Symbol.toStringTag]: Number.name }))).to.be.true
|
|
680
|
+
expect(isRecord(new Number(42))).to.be.true
|
|
681
|
+
expect(isRecord(new String('42'))).to.be.true
|
|
682
682
|
|
|
683
|
-
class
|
|
683
|
+
class FooBar { }
|
|
684
684
|
|
|
685
|
-
expect(
|
|
685
|
+
expect(isRecord(new FooBar())).to.be.true
|
|
686
686
|
```
|
|
687
687
|
|
|
688
|
-
###
|
|
688
|
+
### isString
|
|
689
689
|
|
|
690
690
|
```ts
|
|
691
|
-
const
|
|
691
|
+
const isString: (arg: unknown) => arg is string;
|
|
692
692
|
```
|
|
693
693
|
|
|
694
694
|
Checks whether the argument is a string.
|
|
@@ -704,15 +704,15 @@ The value to check.
|
|
|
704
704
|
#### Usage Examples
|
|
705
705
|
|
|
706
706
|
```ts
|
|
707
|
-
expect(
|
|
708
|
-
expect(
|
|
709
|
-
expect(
|
|
707
|
+
expect(isString('42')).to.be.true
|
|
708
|
+
expect(isString(String('42'))).to.be.true
|
|
709
|
+
expect(isString(new String('42'))).to.be.false
|
|
710
710
|
```
|
|
711
711
|
|
|
712
|
-
###
|
|
712
|
+
### jsOnParse
|
|
713
713
|
|
|
714
714
|
```ts
|
|
715
|
-
const
|
|
715
|
+
const jsOnParse: (handlers: Record<PropertyKey, Function>, text: string) => any;
|
|
716
716
|
```
|
|
717
717
|
|
|
718
718
|
Parses JSON with support for handler-based value transformation (“JavaScript ON”).
|
|
@@ -741,7 +741,7 @@ const handlers = {
|
|
|
741
741
|
$foo: () => 'bar'
|
|
742
742
|
}
|
|
743
743
|
|
|
744
|
-
const actual =
|
|
744
|
+
const actual = jsOnParse(handlers, `[
|
|
745
745
|
{
|
|
746
746
|
"$add": [1, 2]
|
|
747
747
|
},
|
|
@@ -790,15 +790,15 @@ expect(actual).to.deep.equal(expected)
|
|
|
790
790
|
const monokai: CRoot;
|
|
791
791
|
```
|
|
792
792
|
|
|
793
|
-
A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`
|
|
793
|
+
A Monokai-inspired color scheme for use with the [`c`](#c) helper and [`nanolightTs`](#nanolightTs) tokenizer.
|
|
794
794
|
|
|
795
|
-
###
|
|
795
|
+
### nanolightTs
|
|
796
796
|
|
|
797
797
|
```ts
|
|
798
|
-
const
|
|
798
|
+
const nanolightTs: (code: string) => HArgs1[];
|
|
799
799
|
```
|
|
800
800
|
|
|
801
|
-
A TypeScript/JavaScript syntax highlighting tokenizer built using [`
|
|
801
|
+
A TypeScript/JavaScript syntax highlighting tokenizer built using [`newTokenizer`](#newTokenizer).
|
|
802
802
|
|
|
803
803
|
#### code
|
|
804
804
|
|
|
@@ -811,12 +811,12 @@ An array of [`HArgs1`](#HArgs1) elements suitable for rendering with [`h`](#h).
|
|
|
811
811
|
#### Usage Examples
|
|
812
812
|
|
|
813
813
|
```ts
|
|
814
|
-
const
|
|
814
|
+
const codeJs = "const answerToLifeTheUniverseAndEverything = { 42: 42 }['42'] /* 42 */"
|
|
815
815
|
|
|
816
|
-
expect(
|
|
816
|
+
expect(nanolightTs(codeJs)).to.deep.equal([
|
|
817
817
|
['span', { class: 'keyword-1' }, 'const'],
|
|
818
818
|
' ',
|
|
819
|
-
['span', { class: 'identifier-4' }, '
|
|
819
|
+
['span', { class: 'identifier-4' }, 'answerToLifeTheUniverseAndEverything'],
|
|
820
820
|
' ',
|
|
821
821
|
['span', { class: 'operator' }, '='],
|
|
822
822
|
' ',
|
|
@@ -836,15 +836,15 @@ expect(nanolight_ts(code_js)).to.deep.equal([
|
|
|
836
836
|
])
|
|
837
837
|
```
|
|
838
838
|
|
|
839
|
-
###
|
|
839
|
+
### newEscape
|
|
840
840
|
|
|
841
841
|
```ts
|
|
842
|
-
const
|
|
842
|
+
const newEscape: (escapeMap: EscapeMap) => (template: TemplateStringsArray, ...values: unknown[]) => string;
|
|
843
843
|
```
|
|
844
844
|
|
|
845
845
|
Creates a tag function for escaping interpolated values in template literals.
|
|
846
846
|
|
|
847
|
-
####
|
|
847
|
+
#### escapeMap
|
|
848
848
|
|
|
849
849
|
A map where keys are constructors and values are escape functions.
|
|
850
850
|
|
|
@@ -855,17 +855,17 @@ A tag function that escapes interpolated values using the provided escape map.
|
|
|
855
855
|
#### Usage Examples
|
|
856
856
|
|
|
857
857
|
```ts
|
|
858
|
-
const
|
|
858
|
+
const escapeMap: EscapeMap = new Map([
|
|
859
859
|
[null, () => 'NULL'],
|
|
860
860
|
[undefined, () => 'NULL'],
|
|
861
|
-
[Array, (values: unknown[]) =>
|
|
861
|
+
[Array, (values: unknown[]) => escapeValues(escapeMap, values).join(', ')],
|
|
862
862
|
[Boolean, (value: boolean) => `b'${+value}'`],
|
|
863
863
|
[Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
|
|
864
864
|
[Number, (value: number) => `${value}`],
|
|
865
865
|
[String, (value: string) => `'${value.replace(/'/g, "''")}'`]
|
|
866
866
|
])
|
|
867
867
|
|
|
868
|
-
const sql =
|
|
868
|
+
const sql = newEscape(escapeMap)
|
|
869
869
|
|
|
870
870
|
const actual = sql`
|
|
871
871
|
SELECT *
|
|
@@ -880,10 +880,10 @@ const expected = `
|
|
|
880
880
|
expect(actual).to.equal(expected)
|
|
881
881
|
```
|
|
882
882
|
|
|
883
|
-
###
|
|
883
|
+
### newNounForm
|
|
884
884
|
|
|
885
885
|
```ts
|
|
886
|
-
const
|
|
886
|
+
const newNounForm: (locale: string, forms: Partial<Record<Intl.LDMLPluralRule, string>>) => (value: number) => string;
|
|
887
887
|
```
|
|
888
888
|
|
|
889
889
|
Creates a function that returns the appropriate noun form based on a numeric value using `Intl.PluralRules`.
|
|
@@ -914,14 +914,14 @@ A function that takes a numeric value and returns the appropriate noun form.
|
|
|
914
914
|
#### Usage Examples
|
|
915
915
|
|
|
916
916
|
```ts
|
|
917
|
-
const auto =
|
|
917
|
+
const auto = newNounForm('pl', { one: 'auto', few: 'auta', other: 'aut' })
|
|
918
918
|
|
|
919
919
|
expect(auto(0)).to.equal('aut')
|
|
920
920
|
expect(auto(1)).to.equal('auto')
|
|
921
921
|
expect(auto(17)).to.equal('aut')
|
|
922
922
|
expect(auto(42)).to.equal('auta')
|
|
923
923
|
|
|
924
|
-
const car =
|
|
924
|
+
const car = newNounForm('en', { one: 'car', other: 'cars' })
|
|
925
925
|
|
|
926
926
|
expect(car(0)).to.equal('cars')
|
|
927
927
|
expect(car(1)).to.equal('car')
|
|
@@ -929,13 +929,13 @@ expect(car(17)).to.equal('cars')
|
|
|
929
929
|
expect(car(42)).to.equal('cars')
|
|
930
930
|
```
|
|
931
931
|
|
|
932
|
-
###
|
|
932
|
+
### newTokenizer
|
|
933
933
|
|
|
934
934
|
```ts
|
|
935
|
-
const
|
|
935
|
+
const newTokenizer: <M, T>(decorator: (chunk: string, metadata?: M) => T, ...specs: [M, string | RegExp][]) => (code: string) => T[];
|
|
936
936
|
```
|
|
937
937
|
|
|
938
|
-
A helper for building simple tokenizers (see also [`
|
|
938
|
+
A helper for building simple tokenizers (see also [`nanolightTs`](#nanolightTs)).
|
|
939
939
|
|
|
940
940
|
#### decorator
|
|
941
941
|
|
|
@@ -1022,7 +1022,7 @@ expect(pick(ref, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
|
|
|
1022
1022
|
### rwd
|
|
1023
1023
|
|
|
1024
1024
|
```ts
|
|
1025
|
-
const rwd: (root: CRoot, selector: string,
|
|
1025
|
+
const rwd: (root: CRoot, selector: string, cellWidthPx: number, cellHeightPx: number, ...specs: [number, number?, number?][]) => void;
|
|
1026
1026
|
```
|
|
1027
1027
|
|
|
1028
1028
|
A responsive web design helper that generates CSS rules for a grid-like layout.
|
|
@@ -1035,18 +1035,18 @@ The CSS root object to populate (see [`c`](#c)).
|
|
|
1035
1035
|
|
|
1036
1036
|
The CSS selector for the grid item.
|
|
1037
1037
|
|
|
1038
|
-
####
|
|
1038
|
+
#### cellWidthPx
|
|
1039
1039
|
|
|
1040
1040
|
The base cell width in pixels.
|
|
1041
1041
|
|
|
1042
|
-
####
|
|
1042
|
+
#### cellHeightPx
|
|
1043
1043
|
|
|
1044
1044
|
The base cell height in pixels.
|
|
1045
1045
|
|
|
1046
1046
|
#### specs
|
|
1047
1047
|
|
|
1048
1048
|
An array of breakpoint specifications, each a tuple of:
|
|
1049
|
-
- `
|
|
1049
|
+
- `maxWidth`: maximum number of cells per row (defines the viewport breakpoint).
|
|
1050
1050
|
- `width` (optional, default `1`): number of horizontal cells the element spans.
|
|
1051
1051
|
- `height` (optional, default `1`): number of vertical cells the element spans.
|
|
1052
1052
|
|
|
@@ -1103,13 +1103,13 @@ expect(style).to.deep.equal({
|
|
|
1103
1103
|
const s: {
|
|
1104
1104
|
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1[]): SVGElementTagNameMap[T];
|
|
1105
1105
|
<N extends Node>(node: N, ...args1: HArgs1[]): N;
|
|
1106
|
-
(
|
|
1106
|
+
(tagOrNode: string | Node, ...args1: HArgs1[]): Node;
|
|
1107
1107
|
};
|
|
1108
1108
|
```
|
|
1109
1109
|
|
|
1110
1110
|
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also [`h`](#h)).
|
|
1111
1111
|
|
|
1112
|
-
####
|
|
1112
|
+
#### tagOrNode
|
|
1113
1113
|
|
|
1114
1114
|
If a `string`, it is treated as the tag name for a new element.
|
|
1115
1115
|
If a `Node`, that node is modified in place.
|
|
@@ -1128,10 +1128,10 @@ Additional arguments processed as follows:
|
|
|
1128
1128
|
|
|
1129
1129
|
The created or modified `SVGElement`.
|
|
1130
1130
|
|
|
1131
|
-
###
|
|
1131
|
+
### svgUse
|
|
1132
1132
|
|
|
1133
1133
|
```ts
|
|
1134
|
-
const
|
|
1134
|
+
const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
|
|
1135
1135
|
```
|
|
1136
1136
|
|
|
1137
1137
|
Shorthand for creating an SVG element with a `<use>` child referencing an icon by ID.
|
|
@@ -1150,10 +1150,10 @@ Additional arguments passed to the outer `<svg>` element.
|
|
|
1150
1150
|
|
|
1151
1151
|
An `SVGSVGElement` containing a `<use>` element.
|
|
1152
1152
|
|
|
1153
|
-
###
|
|
1153
|
+
### uuidV1
|
|
1154
1154
|
|
|
1155
1155
|
```ts
|
|
1156
|
-
const
|
|
1156
|
+
const uuidV1: (date?: Date, node?: string) => string;
|
|
1157
1157
|
```
|
|
1158
1158
|
|
|
1159
1159
|
Generates a UUID v1 (time-based) identifier.
|
|
@@ -1175,7 +1175,7 @@ A UUID v1 `string` in the standard format `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`
|
|
|
1175
1175
|
|
|
1176
1176
|
```ts
|
|
1177
1177
|
for (let i = 1; i <= 22136; ++i) {
|
|
1178
|
-
const uuid =
|
|
1178
|
+
const uuid = uuidV1()
|
|
1179
1179
|
|
|
1180
1180
|
if (i === 1) {
|
|
1181
1181
|
expect(uuid.split('-')[3]).to.equal('8001')
|
|
@@ -1206,10 +1206,10 @@ for (let i = 1; i <= 22136; ++i) {
|
|
|
1206
1206
|
}
|
|
1207
1207
|
}
|
|
1208
1208
|
|
|
1209
|
-
expect(
|
|
1210
|
-
expect(
|
|
1209
|
+
expect(uuidV1(new Date(), '000123456789abc').split('-')[4]).to.equal('123456789abc')
|
|
1210
|
+
expect(uuidV1(new Date(), '123456789').split('-')[4]).to.equal('000123456789')
|
|
1211
1211
|
|
|
1212
|
-
expect(
|
|
1212
|
+
expect(uuidV1(new Date(323325000000)).startsWith('c1399400-9a71-11bd')).to.be.true
|
|
1213
1213
|
```
|
|
1214
1214
|
|
|
1215
1215
|
### vivify
|