@jackens/nnn 2026.9.3 → 2026.9.9
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 +0 -50
- package/nnn.js +1 -23
- package/package.json +13 -13
- package/readme.md +290 -379
package/nnn.d.ts
CHANGED
|
@@ -242,53 +242,3 @@ export declare const rwd: (root: CNode, selector: string, cellWidthPx: number, c
|
|
|
242
242
|
* `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`.
|
|
243
243
|
*/
|
|
244
244
|
export declare const uuidV1: (date?: Date, node?: string) => string;
|
|
245
|
-
/**
|
|
246
|
-
* A Proxy-based helper for auto-vivification of nested
|
|
247
|
-
* object structures.
|
|
248
|
-
*
|
|
249
|
-
* Accessing, assigning, or deleting any nested property on
|
|
250
|
-
* the returned proxy automatically creates intermediate
|
|
251
|
-
* objects (or arrays for numeric-string keys matching
|
|
252
|
-
* `^(0|[1-9]\d*)$`) as needed, allowing deep operations
|
|
253
|
-
* without explicit null checks.
|
|
254
|
-
*
|
|
255
|
-
* Intermediates of the last level in a get-only property
|
|
256
|
-
* chain are NOT auto-created. For example,
|
|
257
|
-
* `vivify(ref).one.two` will create `ref.one` as `{}`, but
|
|
258
|
-
* will NOT create `ref.one.two`. Only when a deeper access,
|
|
259
|
-
* assignment, or deletion occurs, e.g.
|
|
260
|
-
*
|
|
261
|
-
* ```ts
|
|
262
|
-
* delete vivify(ref).one.two.three
|
|
263
|
-
* ```
|
|
264
|
-
*
|
|
265
|
-
* or
|
|
266
|
-
*
|
|
267
|
-
* ```ts
|
|
268
|
-
* vivify(ref).one.two.three = 4
|
|
269
|
-
* ```
|
|
270
|
-
*
|
|
271
|
-
* Will `ref.one.two` be materialized.
|
|
272
|
-
*
|
|
273
|
-
* When traversal reaches a primitive value, no
|
|
274
|
-
* auto-creation happens; the primitive’s own property is
|
|
275
|
-
* returned instead (e.g. accessing `.toString.name` on a
|
|
276
|
-
* number yields `'toString'` without modifying the
|
|
277
|
-
* underlying structure).
|
|
278
|
-
*
|
|
279
|
-
* Deletion on a non-existing intermediate path will
|
|
280
|
-
* auto-create intermediates up to the parent of the deleted
|
|
281
|
-
* key, e.g.
|
|
282
|
-
*
|
|
283
|
-
* ```ts
|
|
284
|
-
* delete vivify(ref).one.two.three
|
|
285
|
-
* ```
|
|
286
|
-
*
|
|
287
|
-
* Will create `ref.one.two` as `{}` if it does not exist.
|
|
288
|
-
*
|
|
289
|
-
* @param ref The root object to wrap.
|
|
290
|
-
*
|
|
291
|
-
* @returns A proxy that auto-creates nested objects/arrays
|
|
292
|
-
* on property access.
|
|
293
|
-
*/
|
|
294
|
-
export declare const vivify: (ref: unknown) => any;
|
package/nnn.js
CHANGED
|
@@ -318,27 +318,6 @@ var uuidV1 = (date = new Date, node = Math.random().toString(16).slice(2)) => {
|
|
|
318
318
|
counter = counter + 1 & 16383;
|
|
319
319
|
return time.slice(-8).concat("-", time.slice(-12, -8), -1, time.slice(-15, -12), "-", (8 | counter >> 12).toString(16), (ZEROS + (counter & 4095).toString(16)).slice(-3), "-", (ZEROS + node).slice(-12));
|
|
320
320
|
};
|
|
321
|
-
// src/nnn/vivify.ts
|
|
322
|
-
var ARRAY_INDEX_REGEXP = /^(0|[1-9]\d*)$/;
|
|
323
|
-
var isObject = (ref) => typeof ref === "object";
|
|
324
|
-
var getTarget = (parent, parentKey, key) => parent[parentKey] ??= typeof key === "string" && ARRAY_INDEX_REGEXP.test(key) ? [] : {};
|
|
325
|
-
var _vivify = (parent, parentKey) => new Proxy(parent, {
|
|
326
|
-
get(_, key) {
|
|
327
|
-
const target = getTarget(parent, parentKey, key);
|
|
328
|
-
const value = target[key];
|
|
329
|
-
return typeof key === "string" && isObject(target) && (value == null || isObject(value)) ? _vivify(target, key) : value;
|
|
330
|
-
},
|
|
331
|
-
set(_, key, value) {
|
|
332
|
-
const target = getTarget(parent, parentKey, key);
|
|
333
|
-
target[key] = value;
|
|
334
|
-
return true;
|
|
335
|
-
},
|
|
336
|
-
deleteProperty(_, key) {
|
|
337
|
-
const target = getTarget(parent, parentKey, key);
|
|
338
|
-
return delete target[key];
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
var vivify = (ref) => _vivify({ _: ref }, "_");
|
|
342
321
|
export {
|
|
343
322
|
c,
|
|
344
323
|
createEscape,
|
|
@@ -351,6 +330,5 @@ export {
|
|
|
351
330
|
rwd,
|
|
352
331
|
s,
|
|
353
332
|
svgUse,
|
|
354
|
-
uuidV1
|
|
355
|
-
vivify
|
|
333
|
+
uuidV1
|
|
356
334
|
};
|
package/package.json
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"name": "@jackens/nnn",
|
|
3
|
+
"version": "2026.9.9",
|
|
3
4
|
"description": "Jackens’ JavaScript helpers.",
|
|
4
5
|
"keywords": [
|
|
5
|
-
"autovivify",
|
|
6
|
-
"c",
|
|
7
6
|
"CSS-in-JS",
|
|
8
7
|
"CSV parse",
|
|
9
8
|
"DOM",
|
|
10
|
-
"escape",
|
|
11
|
-
"h",
|
|
12
|
-
"highlight",
|
|
13
9
|
"HyperScript",
|
|
14
10
|
"JS-to-CSS",
|
|
15
11
|
"Monokai",
|
|
16
|
-
"nanolight",
|
|
17
|
-
"nnn",
|
|
18
|
-
"Responsive Web Design",
|
|
19
12
|
"RWD",
|
|
13
|
+
"Responsive Web Design",
|
|
20
14
|
"SVG",
|
|
15
|
+
"autovivify",
|
|
16
|
+
"c",
|
|
17
|
+
"escape",
|
|
18
|
+
"h",
|
|
19
|
+
"highlight",
|
|
20
|
+
"nanolight",
|
|
21
|
+
"nnn",
|
|
21
22
|
"tokenize",
|
|
22
23
|
"tokenizer",
|
|
23
24
|
"typography",
|
|
@@ -27,9 +28,8 @@
|
|
|
27
28
|
"vivify"
|
|
28
29
|
],
|
|
29
30
|
"license": "MIT",
|
|
30
|
-
"
|
|
31
|
-
"name": "@jackens/nnn",
|
|
31
|
+
"author": "Jackens",
|
|
32
32
|
"type": "module",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"main": "nnn.js",
|
|
34
|
+
"types": "nnn.d.ts"
|
|
35
35
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# nnn
|
|
2
2
|
|
|
3
|
-
A collection of Jackens’ JavaScript helper utilities (version: `2026.9.
|
|
3
|
+
A collection of Jackens’ JavaScript helper utilities (version: `2026.9.9`).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,6 +18,9 @@ npm i @jackens/nnn
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
import {
|
|
21
|
+
CNode,
|
|
22
|
+
HArgs,
|
|
23
|
+
HArgs1,
|
|
21
24
|
c,
|
|
22
25
|
createEscape,
|
|
23
26
|
createTokenizer,
|
|
@@ -30,7 +33,6 @@ import {
|
|
|
30
33
|
s,
|
|
31
34
|
svgUse,
|
|
32
35
|
uuidV1,
|
|
33
|
-
vivify,
|
|
34
36
|
} from '@jackens/nnn' // or './node_modules/@jackens/nnn/nnn.js'
|
|
35
37
|
```
|
|
36
38
|
|
|
@@ -80,9 +82,6 @@ import {
|
|
|
80
82
|
child referencing an icon by ID.
|
|
81
83
|
- [`uuidV1`](#uuidV1):
|
|
82
84
|
Generates a UUID v1 (time-based) identifier.
|
|
83
|
-
- [`vivify`](#vivify):
|
|
84
|
-
A Proxy-based helper for auto-vivification of nested
|
|
85
|
-
object structures.
|
|
86
85
|
|
|
87
86
|
### CNode
|
|
88
87
|
|
|
@@ -145,7 +144,7 @@ A CSS string representing the compiled rules.
|
|
|
145
144
|
#### Usage Examples
|
|
146
145
|
|
|
147
146
|
```ts
|
|
148
|
-
const
|
|
147
|
+
const actual = c({
|
|
149
148
|
a: {
|
|
150
149
|
color: 'red',
|
|
151
150
|
margin: 1,
|
|
@@ -154,22 +153,25 @@ const actual1 = c({
|
|
|
154
153
|
},
|
|
155
154
|
})
|
|
156
155
|
|
|
157
|
-
const
|
|
158
|
-
a{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
a.c{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
a{
|
|
167
|
-
|
|
168
|
-
}
|
|
156
|
+
const expected = `
|
|
157
|
+
a{
|
|
158
|
+
color:red;
|
|
159
|
+
margin:1
|
|
160
|
+
}
|
|
161
|
+
a.c{
|
|
162
|
+
margin:2;
|
|
163
|
+
padding:2
|
|
164
|
+
}
|
|
165
|
+
a{
|
|
166
|
+
padding:1
|
|
167
|
+
}
|
|
168
|
+
`.replace(/\n\s*/g, '')
|
|
169
169
|
|
|
170
|
-
expect(
|
|
170
|
+
expect(actual).toBe(expected)
|
|
171
|
+
```
|
|
171
172
|
|
|
172
|
-
|
|
173
|
+
```ts
|
|
174
|
+
const actual = c({
|
|
173
175
|
a: {
|
|
174
176
|
'.b': {
|
|
175
177
|
color: 'red',
|
|
@@ -180,22 +182,25 @@ const actual2 = c({
|
|
|
180
182
|
},
|
|
181
183
|
})
|
|
182
184
|
|
|
183
|
-
const
|
|
184
|
-
a.b{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
a.b.c{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
a.b{
|
|
193
|
-
|
|
194
|
-
}
|
|
185
|
+
const expected = `
|
|
186
|
+
a.b{
|
|
187
|
+
color:red;
|
|
188
|
+
margin:1
|
|
189
|
+
}
|
|
190
|
+
a.b.c{
|
|
191
|
+
margin:2;
|
|
192
|
+
padding:2
|
|
193
|
+
}
|
|
194
|
+
a.b{
|
|
195
|
+
padding:1
|
|
196
|
+
}
|
|
197
|
+
`.replace(/\n\s*/g, '')
|
|
195
198
|
|
|
196
|
-
expect(
|
|
199
|
+
expect(actual).toBe(expected)
|
|
200
|
+
```
|
|
197
201
|
|
|
198
|
-
|
|
202
|
+
```ts
|
|
203
|
+
const actual = c({
|
|
199
204
|
'@font-face$$1': {
|
|
200
205
|
'font-family': 'Jackens',
|
|
201
206
|
src$$1: 'url(otf/jackens.otf)',
|
|
@@ -225,51 +230,54 @@ const actual3 = c({
|
|
|
225
230
|
},
|
|
226
231
|
})
|
|
227
232
|
|
|
228
|
-
const
|
|
229
|
-
@font-face{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
@font-face{
|
|
237
|
-
font-family:C64;
|
|
238
|
-
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
239
|
-
}
|
|
240
|
-
@keyframes spin{
|
|
241
|
-
0%{
|
|
242
|
-
transform:rotate(0deg)
|
|
233
|
+
const expected = `
|
|
234
|
+
@font-face{
|
|
235
|
+
font-family:Jackens;
|
|
236
|
+
src:url(otf/jackens.otf);
|
|
237
|
+
src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
|
|
238
|
+
font-weight:normal;
|
|
239
|
+
font-style:normal
|
|
243
240
|
}
|
|
244
|
-
|
|
245
|
-
|
|
241
|
+
@font-face{
|
|
242
|
+
font-family:C64;
|
|
243
|
+
src:url(fonts/C64_Pro_Mono-STYLE.woff)
|
|
244
|
+
}
|
|
245
|
+
@keyframes spin{
|
|
246
|
+
0%{
|
|
247
|
+
transform:rotate(0deg)
|
|
248
|
+
}
|
|
249
|
+
100%{
|
|
250
|
+
transform:rotate(360deg)
|
|
251
|
+
}
|
|
246
252
|
}
|
|
247
|
-
}
|
|
248
|
-
div{
|
|
249
|
-
border:solid red 1px
|
|
250
|
-
}
|
|
251
|
-
div.c1{
|
|
252
|
-
background-color:#000
|
|
253
|
-
}
|
|
254
|
-
div .c1{
|
|
255
|
-
background-color:black
|
|
256
|
-
}
|
|
257
|
-
div.c2{
|
|
258
|
-
background-color:rgb(0,0,0)
|
|
259
|
-
}
|
|
260
|
-
@media(min-width:200px){
|
|
261
253
|
div{
|
|
262
|
-
|
|
263
|
-
|
|
254
|
+
border:solid red 1px
|
|
255
|
+
}
|
|
256
|
+
div.c1{
|
|
257
|
+
background-color:#000
|
|
264
258
|
}
|
|
265
|
-
|
|
266
|
-
color
|
|
259
|
+
div .c1{
|
|
260
|
+
background-color:black
|
|
267
261
|
}
|
|
268
|
-
|
|
262
|
+
div.c2{
|
|
263
|
+
background-color:rgb(0,0,0)
|
|
264
|
+
}
|
|
265
|
+
@media(min-width:200px){
|
|
266
|
+
div{
|
|
267
|
+
margin:0;
|
|
268
|
+
padding:0
|
|
269
|
+
}
|
|
270
|
+
span{
|
|
271
|
+
color:#000
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
`.replace(/\n\s*/g, '')
|
|
269
275
|
|
|
270
|
-
expect(
|
|
276
|
+
expect(actual).toBe(expected)
|
|
277
|
+
```
|
|
271
278
|
|
|
272
|
-
|
|
279
|
+
```ts
|
|
280
|
+
const actual = c({
|
|
273
281
|
a: {
|
|
274
282
|
'.b,.c': {
|
|
275
283
|
margin: 1,
|
|
@@ -280,17 +288,20 @@ const actual4 = c({
|
|
|
280
288
|
},
|
|
281
289
|
})
|
|
282
290
|
|
|
283
|
-
const
|
|
284
|
-
a.b,a.c{
|
|
285
|
-
|
|
286
|
-
}
|
|
287
|
-
a.b.d,a.c.d{
|
|
288
|
-
|
|
289
|
-
}
|
|
291
|
+
const expected = `
|
|
292
|
+
a.b,a.c{
|
|
293
|
+
margin:1
|
|
294
|
+
}
|
|
295
|
+
a.b.d,a.c.d{
|
|
296
|
+
margin:2
|
|
297
|
+
}
|
|
298
|
+
`.replace(/\n\s*/g, '')
|
|
290
299
|
|
|
291
|
-
expect(
|
|
300
|
+
expect(actual).toBe(expected)
|
|
301
|
+
```
|
|
292
302
|
|
|
293
|
-
|
|
303
|
+
```ts
|
|
304
|
+
const actual = c({
|
|
294
305
|
'.b,.c': {
|
|
295
306
|
margin: 1,
|
|
296
307
|
'.d': {
|
|
@@ -299,17 +310,20 @@ const actual5 = c({
|
|
|
299
310
|
},
|
|
300
311
|
})
|
|
301
312
|
|
|
302
|
-
const
|
|
303
|
-
.b,.c{
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
.b.d,.c.d{
|
|
307
|
-
|
|
308
|
-
}
|
|
313
|
+
const expected = `
|
|
314
|
+
.b,.c{
|
|
315
|
+
margin:1
|
|
316
|
+
}
|
|
317
|
+
.b.d,.c.d{
|
|
318
|
+
margin:2
|
|
319
|
+
}
|
|
320
|
+
`.replace(/\n\s*/g, '')
|
|
309
321
|
|
|
310
|
-
expect(
|
|
322
|
+
expect(actual).toBe(expected)
|
|
323
|
+
```
|
|
311
324
|
|
|
312
|
-
|
|
325
|
+
```ts
|
|
326
|
+
const actual = c({
|
|
313
327
|
'.a,.b': {
|
|
314
328
|
margin: 1,
|
|
315
329
|
'.c,.d': {
|
|
@@ -318,17 +332,20 @@ const actual6 = c({
|
|
|
318
332
|
},
|
|
319
333
|
})
|
|
320
334
|
|
|
321
|
-
const
|
|
322
|
-
.a,.b{
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
.a.c,.a.d,.b.c,.b.d{
|
|
326
|
-
|
|
327
|
-
}
|
|
335
|
+
const expected = `
|
|
336
|
+
.a,.b{
|
|
337
|
+
margin:1
|
|
338
|
+
}
|
|
339
|
+
.a.c,.a.d,.b.c,.b.d{
|
|
340
|
+
margin:2
|
|
341
|
+
}
|
|
342
|
+
`.replace(/\n\s*/g, '')
|
|
328
343
|
|
|
329
|
-
expect(
|
|
344
|
+
expect(actual).toBe(expected)
|
|
345
|
+
```
|
|
330
346
|
|
|
331
|
-
|
|
347
|
+
```ts
|
|
348
|
+
const actual = c({
|
|
332
349
|
':root$$monokai': {
|
|
333
350
|
'--': {
|
|
334
351
|
bg: '#faf4f2',
|
|
@@ -378,7 +395,7 @@ const actual7 = c({
|
|
|
378
395
|
},
|
|
379
396
|
})
|
|
380
397
|
|
|
381
|
-
const
|
|
398
|
+
const expected = `
|
|
382
399
|
:root{
|
|
383
400
|
--bg:#faf4f2;
|
|
384
401
|
--fg:#29242a;
|
|
@@ -412,9 +429,10 @@ const expected7 = `
|
|
|
412
429
|
--punctuation:#727072;
|
|
413
430
|
--string:#ffd866
|
|
414
431
|
}
|
|
415
|
-
}
|
|
432
|
+
}
|
|
433
|
+
`.replace(/\n\s*/g, '')
|
|
416
434
|
|
|
417
|
-
expect(
|
|
435
|
+
expect(actual).toBe(expected)
|
|
418
436
|
```
|
|
419
437
|
|
|
420
438
|
### createEscape
|
|
@@ -472,16 +490,18 @@ const actual = sql`
|
|
|
472
490
|
/42/,
|
|
473
491
|
new Date(323325000000),
|
|
474
492
|
]}
|
|
475
|
-
)
|
|
493
|
+
)
|
|
494
|
+
`
|
|
476
495
|
|
|
477
496
|
const expected = `
|
|
478
497
|
SELECT *
|
|
479
498
|
FROM table_name
|
|
480
499
|
WHERE column_name IN (
|
|
481
500
|
b'1', NULL, NULL, NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00'
|
|
482
|
-
)
|
|
501
|
+
)
|
|
502
|
+
`
|
|
483
503
|
|
|
484
|
-
expect(actual).
|
|
504
|
+
expect(actual).toBe(expected)
|
|
485
505
|
```
|
|
486
506
|
|
|
487
507
|
### createTokenizer
|
|
@@ -528,15 +548,15 @@ and returns an array of decorated tokens.
|
|
|
528
548
|
#### Usage Examples
|
|
529
549
|
|
|
530
550
|
```ts
|
|
531
|
-
const
|
|
551
|
+
const tokenizer = createTokenizer(
|
|
532
552
|
(chunk, metadata) => ({ chunk, metadata }),
|
|
533
553
|
['keyword', /\b(if|else|for)\b/],
|
|
534
554
|
['string', /"[^"]*"/]
|
|
535
555
|
)
|
|
536
556
|
|
|
537
|
-
const
|
|
557
|
+
const result = tokenizer('if "hello" else "world"')
|
|
538
558
|
|
|
539
|
-
expect(
|
|
559
|
+
expect(result).toEqual([
|
|
540
560
|
{ chunk: 'if', metadata: 'keyword' },
|
|
541
561
|
{ chunk: ' ', metadata: undefined },
|
|
542
562
|
{ chunk: '"hello"', metadata: 'string' },
|
|
@@ -545,92 +565,108 @@ expect(result1).to.deep.equal([
|
|
|
545
565
|
{ chunk: ' ', metadata: undefined },
|
|
546
566
|
{ chunk: '"world"', metadata: 'string' },
|
|
547
567
|
])
|
|
568
|
+
```
|
|
548
569
|
|
|
549
|
-
|
|
570
|
+
```ts
|
|
571
|
+
const tokenizer = createTokenizer(
|
|
550
572
|
(chunk, metadata) => `${metadata}:${chunk}`,
|
|
551
573
|
['tag', 'BEGIN'],
|
|
552
574
|
['end', 'END']
|
|
553
575
|
)
|
|
554
576
|
|
|
555
|
-
const
|
|
577
|
+
const result = tokenizer('aBEGINbENDc')
|
|
556
578
|
|
|
557
|
-
expect(
|
|
579
|
+
expect(result).toEqual([
|
|
558
580
|
'undefined:a',
|
|
559
581
|
'tag:BEGIN',
|
|
560
582
|
'undefined:b',
|
|
561
583
|
'end:END',
|
|
562
584
|
'undefined:c',
|
|
563
585
|
])
|
|
586
|
+
```
|
|
564
587
|
|
|
565
|
-
|
|
588
|
+
```ts
|
|
589
|
+
const tokenizer = createTokenizer(
|
|
566
590
|
chunk => chunk,
|
|
567
591
|
['test', /test/]
|
|
568
592
|
)
|
|
569
593
|
|
|
570
|
-
const
|
|
594
|
+
const result = tokenizer('')
|
|
571
595
|
|
|
572
|
-
expect(
|
|
596
|
+
expect(result).toEqual([])
|
|
597
|
+
```
|
|
573
598
|
|
|
574
|
-
|
|
599
|
+
```ts
|
|
600
|
+
const tokenizer = createTokenizer(
|
|
575
601
|
(chunk, metadata) => ({ chunk, metadata }),
|
|
576
602
|
['start', /^test/]
|
|
577
603
|
)
|
|
578
604
|
|
|
579
|
-
const
|
|
605
|
+
const result = tokenizer('test here')
|
|
580
606
|
|
|
581
|
-
expect(
|
|
607
|
+
expect(result).toEqual([
|
|
582
608
|
{ chunk: 'test', metadata: 'start' },
|
|
583
609
|
{ chunk: ' here', metadata: undefined },
|
|
584
610
|
])
|
|
611
|
+
```
|
|
585
612
|
|
|
586
|
-
|
|
613
|
+
```ts
|
|
614
|
+
const tokenizer = createTokenizer(
|
|
587
615
|
(chunk, metadata) => metadata,
|
|
588
616
|
['later', /x/],
|
|
589
617
|
['earlier', /y/]
|
|
590
618
|
)
|
|
591
619
|
|
|
592
|
-
const
|
|
620
|
+
const result = tokenizer('yx')
|
|
593
621
|
|
|
594
|
-
expect(
|
|
622
|
+
expect(result).toEqual(['earlier', 'later'])
|
|
623
|
+
```
|
|
595
624
|
|
|
596
|
-
|
|
625
|
+
```ts
|
|
626
|
+
const tokenizer = createTokenizer(
|
|
597
627
|
chunk => chunk,
|
|
598
628
|
['short', 'a'],
|
|
599
629
|
['long', 'abc']
|
|
600
630
|
)
|
|
601
631
|
|
|
602
|
-
const
|
|
632
|
+
const result = tokenizer('abc')
|
|
603
633
|
|
|
604
|
-
expect(
|
|
634
|
+
expect(result).toEqual(['abc'])
|
|
635
|
+
```
|
|
605
636
|
|
|
606
|
-
|
|
637
|
+
```ts
|
|
638
|
+
const tokenizer = createTokenizer(
|
|
607
639
|
chunk => chunk,
|
|
608
640
|
['empty', ''],
|
|
609
641
|
['word', /\w+/]
|
|
610
642
|
)
|
|
611
643
|
|
|
612
|
-
const
|
|
644
|
+
const result = tokenizer('hello')
|
|
613
645
|
|
|
614
|
-
expect(
|
|
646
|
+
expect(result).toEqual(['hello'])
|
|
647
|
+
```
|
|
615
648
|
|
|
616
|
-
|
|
649
|
+
```ts
|
|
650
|
+
const tokenizer = createTokenizer(
|
|
617
651
|
chunk => chunk,
|
|
618
652
|
['test', /xyz/]
|
|
619
653
|
)
|
|
620
654
|
|
|
621
|
-
const
|
|
655
|
+
const result = tokenizer('abc')
|
|
622
656
|
|
|
623
|
-
expect(
|
|
657
|
+
expect(result).toEqual(['abc'])
|
|
658
|
+
```
|
|
624
659
|
|
|
625
|
-
|
|
660
|
+
```ts
|
|
661
|
+
const tokenizer = createTokenizer(
|
|
626
662
|
(_chunk, metadata) => metadata,
|
|
627
663
|
['a', 'a'],
|
|
628
664
|
['b', 'b']
|
|
629
665
|
)
|
|
630
666
|
|
|
631
|
-
const
|
|
667
|
+
const result = tokenizer('aabb')
|
|
632
668
|
|
|
633
|
-
expect(
|
|
669
|
+
expect(result).toEqual(['a', 'a', 'b', 'b'])
|
|
634
670
|
```
|
|
635
671
|
|
|
636
672
|
### csvParse
|
|
@@ -670,7 +706,7 @@ yyy",zzz
|
|
|
670
706
|
|
|
671
707
|
`
|
|
672
708
|
|
|
673
|
-
expect(csvParse(text)).
|
|
709
|
+
expect(csvParse(text)).toEqual([
|
|
674
710
|
['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
|
|
675
711
|
['xxx,xxx', 'yyy\nyyy', 'zzz'],
|
|
676
712
|
[' 42 ', '42', ' 17'],
|
|
@@ -716,7 +752,7 @@ const p = h(
|
|
|
716
752
|
|
|
717
753
|
fixPlTypography(p)
|
|
718
754
|
|
|
719
|
-
expect(p.innerHTML).
|
|
755
|
+
expect(p.innerHTML).toEqual(
|
|
720
756
|
'Pchnąć ' +
|
|
721
757
|
'<span style="white-space:nowrap">w </span>' +
|
|
722
758
|
'tę łódź jeża lub ośm skrzyń fig ' +
|
|
@@ -775,61 +811,66 @@ The created or modified `HTMLElement`.
|
|
|
775
811
|
```ts
|
|
776
812
|
const b = h('b')
|
|
777
813
|
|
|
778
|
-
expect(b.outerHTML).
|
|
814
|
+
expect(b.outerHTML).toBe('<b></b>')
|
|
779
815
|
|
|
780
816
|
const i = h('i', 'text')
|
|
781
817
|
|
|
782
818
|
h(b, i)
|
|
783
819
|
|
|
784
|
-
expect(i.outerHTML).
|
|
820
|
+
expect(i.outerHTML).toBe('<i>text</i>')
|
|
785
821
|
|
|
786
|
-
expect(b.outerHTML).
|
|
822
|
+
expect(b.outerHTML).toBe('<b><i>text</i></b>')
|
|
787
823
|
|
|
788
824
|
h(i, { $className: 'some class' })
|
|
789
825
|
|
|
790
|
-
expect(i.outerHTML).
|
|
791
|
-
'<i class="some class">text</i>'
|
|
792
|
-
)
|
|
826
|
+
expect(i.outerHTML).toBe('<i class="some class">text</i>')
|
|
793
827
|
|
|
794
|
-
expect(b.outerHTML).
|
|
828
|
+
expect(b.outerHTML).toBe(
|
|
795
829
|
'<b><i class="some class">text</i></b>'
|
|
796
830
|
)
|
|
831
|
+
```
|
|
797
832
|
|
|
798
|
-
|
|
833
|
+
```ts
|
|
834
|
+
expect(h('span', 'text').outerHTML).toBe(
|
|
799
835
|
'<span>text</span>'
|
|
800
836
|
)
|
|
801
837
|
|
|
802
|
-
expect(
|
|
803
|
-
|
|
804
|
-
).to.equal('<span>text</span>')
|
|
805
|
-
|
|
806
|
-
expect(h('span', '42').outerHTML).to.equal(
|
|
807
|
-
'<span>42</span>'
|
|
838
|
+
expect(h('span', { $innerText: 'text' }).outerHTML).toBe(
|
|
839
|
+
'<span>text</span>'
|
|
808
840
|
)
|
|
809
841
|
|
|
810
|
-
expect(h('span', 42).outerHTML).
|
|
842
|
+
expect(h('span', '42').outerHTML).toBe('<span>42</span>')
|
|
811
843
|
|
|
844
|
+
expect(h('span', 42).outerHTML).toBe('<span>42</span>')
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
```ts
|
|
812
848
|
expect(
|
|
813
849
|
h('div', { style: 'margin:0;padding:0' }).outerHTML
|
|
814
|
-
).
|
|
850
|
+
).toBe('<div style="margin:0;padding:0"></div>')
|
|
815
851
|
|
|
816
852
|
expect(
|
|
817
853
|
h('div', { $style: 'margin:0;padding:0' }).outerHTML
|
|
818
|
-
).
|
|
854
|
+
).toBe('<div style="margin: 0px; padding: 0px;"></div>')
|
|
819
855
|
|
|
820
856
|
expect(
|
|
821
|
-
h('div', { $style: { margin: 0, padding: 0 } })
|
|
822
|
-
|
|
857
|
+
h('div', { $style: { margin: 0, padding: 0 } })
|
|
858
|
+
.outerHTML
|
|
859
|
+
).toBe('<div style="margin: 0px; padding: 0px;"></div>')
|
|
860
|
+
```
|
|
823
861
|
|
|
862
|
+
```ts
|
|
824
863
|
const input1 = h('input', { value: 42 })
|
|
825
864
|
const input2 = h('input', { $value: '42' })
|
|
826
865
|
|
|
827
|
-
expect(input1.value).
|
|
828
|
-
expect(input2.value).
|
|
866
|
+
expect(input1.value).toBe('42')
|
|
867
|
+
expect(input2.value).toBe('42')
|
|
829
868
|
|
|
830
|
-
expect(input1.outerHTML).
|
|
831
|
-
expect(input2.outerHTML).
|
|
869
|
+
expect(input1.outerHTML).toBe('<input value="42">')
|
|
870
|
+
expect(input2.outerHTML).toBe('<input>')
|
|
871
|
+
```
|
|
832
872
|
|
|
873
|
+
```ts
|
|
833
874
|
const checkbox1 = h('input', {
|
|
834
875
|
type: 'checkbox',
|
|
835
876
|
checked: true,
|
|
@@ -840,38 +881,42 @@ const checkbox2 = h('input', {
|
|
|
840
881
|
$checked: true,
|
|
841
882
|
})
|
|
842
883
|
|
|
843
|
-
expect(checkbox1.checked).
|
|
844
|
-
expect(checkbox2.checked).
|
|
884
|
+
expect(checkbox1.checked).toBe(true)
|
|
885
|
+
expect(checkbox2.checked).toBe(true)
|
|
845
886
|
|
|
846
|
-
expect(checkbox1.outerHTML).
|
|
887
|
+
expect(checkbox1.outerHTML).toBe(
|
|
847
888
|
'<input type="checkbox" checked="">'
|
|
848
889
|
)
|
|
849
890
|
|
|
850
|
-
expect(checkbox2.outerHTML).
|
|
891
|
+
expect(checkbox2.outerHTML).toBe(
|
|
851
892
|
'<input type="checkbox">'
|
|
852
893
|
)
|
|
894
|
+
```
|
|
853
895
|
|
|
896
|
+
```ts
|
|
854
897
|
const div = h('div')
|
|
855
898
|
|
|
856
|
-
expect(div.key).
|
|
899
|
+
expect(div.key).toBeUndefined()
|
|
857
900
|
|
|
858
901
|
h(div, { $key: { one: 1 } })
|
|
859
902
|
|
|
860
|
-
expect(div.key).
|
|
903
|
+
expect(div.key).toEqual({ one: 1 })
|
|
861
904
|
|
|
862
905
|
h(div, { $key: { two: 2 } })
|
|
863
906
|
|
|
864
|
-
expect(div.key).
|
|
907
|
+
expect(div.key).toEqual({ one: 1, two: 2 })
|
|
908
|
+
```
|
|
865
909
|
|
|
910
|
+
```ts
|
|
866
911
|
const elemWithClass = h('div', { class: 'test' })
|
|
867
912
|
|
|
868
|
-
expect(elemWithClass.getAttribute('class')).
|
|
913
|
+
expect(elemWithClass.getAttribute('class')).toBe('test')
|
|
869
914
|
|
|
870
915
|
const elemWithText = h('div', 'initial')
|
|
871
916
|
|
|
872
917
|
h(elemWithText, ' more')
|
|
873
918
|
|
|
874
|
-
expect(elemWithText.outerHTML).
|
|
919
|
+
expect(elemWithText.outerHTML).toBe(
|
|
875
920
|
'<div>initial more</div>'
|
|
876
921
|
)
|
|
877
922
|
|
|
@@ -881,7 +926,7 @@ const elemWithNested = h(
|
|
|
881
926
|
['b', 'world']
|
|
882
927
|
)
|
|
883
928
|
|
|
884
|
-
expect(elemWithNested.outerHTML).
|
|
929
|
+
expect(elemWithNested.outerHTML).toBe(
|
|
885
930
|
'<div><span>hello</span><b>world</b></div>'
|
|
886
931
|
)
|
|
887
932
|
```
|
|
@@ -920,7 +965,7 @@ const codeJs =
|
|
|
920
965
|
'const answerToLifeTheUniverseAndEverything = ' +
|
|
921
966
|
"{ 42: 42 }['42'] /* 42 */"
|
|
922
967
|
|
|
923
|
-
expect(nanolightTs(codeJs)).
|
|
968
|
+
expect(nanolightTs(codeJs)).toEqual([
|
|
924
969
|
['span', { class: 'keyword1' }, 'const'],
|
|
925
970
|
' ',
|
|
926
971
|
[
|
|
@@ -1002,7 +1047,7 @@ const style: CNode = {
|
|
|
1002
1047
|
|
|
1003
1048
|
rwd(style, '.r6', 200, 50, [6], [3], [1, 1, 2])
|
|
1004
1049
|
|
|
1005
|
-
expect(style).
|
|
1050
|
+
expect(style).toEqual({
|
|
1006
1051
|
body: {
|
|
1007
1052
|
margin: 0,
|
|
1008
1053
|
},
|
|
@@ -1077,29 +1122,49 @@ The created or modified `SVGElement`.
|
|
|
1077
1122
|
#### Usage Examples
|
|
1078
1123
|
|
|
1079
1124
|
```ts
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
const svg1 = s('svg', { 'xlink:href': true })
|
|
1125
|
+
const svg = s('svg', { 'xlink:href': true })
|
|
1083
1126
|
|
|
1084
|
-
expect(
|
|
1127
|
+
expect(
|
|
1128
|
+
svg.getAttributeNS(
|
|
1129
|
+
'http://www.w3.org/1999/xlink',
|
|
1130
|
+
'href'
|
|
1131
|
+
)
|
|
1132
|
+
).toBe('')
|
|
1133
|
+
```
|
|
1085
1134
|
|
|
1086
|
-
|
|
1135
|
+
```ts
|
|
1136
|
+
const svg = s('svg', { 'xlink:href': false })
|
|
1087
1137
|
|
|
1088
|
-
expect(
|
|
1138
|
+
expect(
|
|
1139
|
+
svg.getAttributeNS(
|
|
1140
|
+
'http://www.w3.org/1999/xlink',
|
|
1141
|
+
'href'
|
|
1142
|
+
)
|
|
1143
|
+
).toBeNull()
|
|
1144
|
+
```
|
|
1089
1145
|
|
|
1090
|
-
|
|
1146
|
+
```ts
|
|
1147
|
+
const svg = s('svg', {
|
|
1091
1148
|
'xlink:href': 'http://example.com',
|
|
1092
1149
|
})
|
|
1093
1150
|
|
|
1094
|
-
expect(
|
|
1095
|
-
|
|
1096
|
-
|
|
1151
|
+
expect(
|
|
1152
|
+
svg.getAttributeNS(
|
|
1153
|
+
'http://www.w3.org/1999/xlink',
|
|
1154
|
+
'href'
|
|
1155
|
+
)
|
|
1156
|
+
).toBe('http://example.com')
|
|
1157
|
+
```
|
|
1097
1158
|
|
|
1098
|
-
|
|
1159
|
+
```ts
|
|
1160
|
+
const svg = s('svg', { 'xlink:title': 42 })
|
|
1099
1161
|
|
|
1100
|
-
expect(
|
|
1101
|
-
|
|
1102
|
-
|
|
1162
|
+
expect(
|
|
1163
|
+
svg.getAttributeNS(
|
|
1164
|
+
'http://www.w3.org/1999/xlink',
|
|
1165
|
+
'title'
|
|
1166
|
+
)
|
|
1167
|
+
).toBe('42')
|
|
1103
1168
|
```
|
|
1104
1169
|
|
|
1105
1170
|
### svgUse
|
|
@@ -1138,47 +1203,54 @@ An `SVGSVGElement` containing a `<use>` element.
|
|
|
1138
1203
|
#### Usage Examples
|
|
1139
1204
|
|
|
1140
1205
|
```ts
|
|
1141
|
-
const XLINK_NS = 'http://www.w3.org/1999/xlink'
|
|
1142
|
-
|
|
1143
1206
|
const svg = svgUse('icon-home')
|
|
1144
1207
|
|
|
1145
|
-
expect(svg.children.length).
|
|
1208
|
+
expect(svg.children.length).toBe(1)
|
|
1146
1209
|
|
|
1147
1210
|
const useElement = svg.children[0]
|
|
1148
1211
|
|
|
1149
1212
|
expect(
|
|
1150
|
-
useElement.getAttributeNS(
|
|
1151
|
-
|
|
1213
|
+
useElement.getAttributeNS(
|
|
1214
|
+
'http://www.w3.org/1999/xlink',
|
|
1215
|
+
'href'
|
|
1216
|
+
)
|
|
1217
|
+
).toBe('#icon-home')
|
|
1152
1218
|
|
|
1153
1219
|
const svgWithViewBox = svgUse('icon-star', {
|
|
1154
1220
|
viewBox: '0 0 24 24',
|
|
1155
1221
|
})
|
|
1156
1222
|
|
|
1157
|
-
expect(svgWithViewBox.getAttribute('viewBox')).
|
|
1223
|
+
expect(svgWithViewBox.getAttribute('viewBox')).toBe(
|
|
1158
1224
|
'0 0 24 24'
|
|
1159
1225
|
)
|
|
1160
1226
|
|
|
1161
1227
|
const useViewBox = svgWithViewBox.children[0]
|
|
1162
1228
|
|
|
1163
1229
|
expect(
|
|
1164
|
-
useViewBox.getAttributeNS(
|
|
1165
|
-
|
|
1230
|
+
useViewBox.getAttributeNS(
|
|
1231
|
+
'http://www.w3.org/1999/xlink',
|
|
1232
|
+
'href'
|
|
1233
|
+
)
|
|
1234
|
+
).toBe('#icon-star')
|
|
1166
1235
|
|
|
1167
1236
|
const svgWithClass = svgUse('icon-menu', {
|
|
1168
1237
|
class: 'icon-btn',
|
|
1169
1238
|
})
|
|
1170
1239
|
|
|
1171
|
-
expect(svgWithClass.getAttribute('class')).
|
|
1240
|
+
expect(svgWithClass.getAttribute('class')).toBe(
|
|
1172
1241
|
'icon-btn'
|
|
1173
1242
|
)
|
|
1174
1243
|
|
|
1175
|
-
expect(svgWithClass.children.length).
|
|
1244
|
+
expect(svgWithClass.children.length).toBe(1)
|
|
1176
1245
|
|
|
1177
1246
|
const useClass = svgWithClass.children[0]
|
|
1178
1247
|
|
|
1179
|
-
expect(
|
|
1180
|
-
|
|
1181
|
-
|
|
1248
|
+
expect(
|
|
1249
|
+
useClass.getAttributeNS(
|
|
1250
|
+
'http://www.w3.org/1999/xlink',
|
|
1251
|
+
'href'
|
|
1252
|
+
)
|
|
1253
|
+
).toBe('#icon-menu')
|
|
1182
1254
|
|
|
1183
1255
|
const svgWithMultipleAttrs = svgUse('icon-settings', {
|
|
1184
1256
|
width: 24,
|
|
@@ -1186,23 +1258,26 @@ const svgWithMultipleAttrs = svgUse('icon-settings', {
|
|
|
1186
1258
|
class: 'icon',
|
|
1187
1259
|
})
|
|
1188
1260
|
|
|
1189
|
-
expect(svgWithMultipleAttrs.getAttribute('width')).
|
|
1261
|
+
expect(svgWithMultipleAttrs.getAttribute('width')).toBe(
|
|
1190
1262
|
'24'
|
|
1191
1263
|
)
|
|
1192
1264
|
|
|
1193
|
-
expect(
|
|
1194
|
-
|
|
1195
|
-
)
|
|
1265
|
+
expect(svgWithMultipleAttrs.getAttribute('height')).toBe(
|
|
1266
|
+
'24'
|
|
1267
|
+
)
|
|
1196
1268
|
|
|
1197
|
-
expect(svgWithMultipleAttrs.getAttribute('class')).
|
|
1269
|
+
expect(svgWithMultipleAttrs.getAttribute('class')).toBe(
|
|
1198
1270
|
'icon'
|
|
1199
1271
|
)
|
|
1200
1272
|
|
|
1201
1273
|
const useMultiple = svgWithMultipleAttrs.children[0]
|
|
1202
1274
|
|
|
1203
1275
|
expect(
|
|
1204
|
-
useMultiple.getAttributeNS(
|
|
1205
|
-
|
|
1276
|
+
useMultiple.getAttributeNS(
|
|
1277
|
+
'http://www.w3.org/1999/xlink',
|
|
1278
|
+
'href'
|
|
1279
|
+
)
|
|
1280
|
+
).toBe('#icon-settings')
|
|
1206
1281
|
```
|
|
1207
1282
|
|
|
1208
1283
|
### uuidV1
|
|
@@ -1237,213 +1312,49 @@ for (let i = 1; i <= 22136; ++i) {
|
|
|
1237
1312
|
const uuid = uuidV1()
|
|
1238
1313
|
|
|
1239
1314
|
if (i === 1) {
|
|
1240
|
-
expect(uuid.split('-')[3]).
|
|
1315
|
+
expect(uuid.split('-')[3]).toBe('8001')
|
|
1241
1316
|
}
|
|
1242
1317
|
|
|
1243
1318
|
if (i === 4095) {
|
|
1244
|
-
expect(uuid.split('-')[3]).
|
|
1319
|
+
expect(uuid.split('-')[3]).toBe('8fff')
|
|
1245
1320
|
}
|
|
1246
1321
|
|
|
1247
1322
|
if (i === 4096) {
|
|
1248
|
-
expect(uuid.split('-')[3]).
|
|
1323
|
+
expect(uuid.split('-')[3]).toBe('9000')
|
|
1249
1324
|
}
|
|
1250
1325
|
|
|
1251
1326
|
if (i === 9029) {
|
|
1252
|
-
expect(uuid.split('-')[3]).
|
|
1327
|
+
expect(uuid.split('-')[3]).toBe('a345')
|
|
1253
1328
|
}
|
|
1254
1329
|
|
|
1255
1330
|
if (i === 13398) {
|
|
1256
|
-
expect(uuid.split('-')[3]).
|
|
1331
|
+
expect(uuid.split('-')[3]).toBe('b456')
|
|
1257
1332
|
}
|
|
1258
1333
|
|
|
1259
1334
|
if (i === 16384) {
|
|
1260
|
-
expect(uuid.split('-')[3]).
|
|
1335
|
+
expect(uuid.split('-')[3]).toBe('8000')
|
|
1261
1336
|
}
|
|
1262
1337
|
|
|
1263
1338
|
if (i === 17767) {
|
|
1264
|
-
expect(uuid.split('-')[3]).
|
|
1339
|
+
expect(uuid.split('-')[3]).toBe('8567')
|
|
1265
1340
|
}
|
|
1266
1341
|
}
|
|
1342
|
+
```
|
|
1267
1343
|
|
|
1344
|
+
```ts
|
|
1268
1345
|
expect(
|
|
1269
1346
|
uuidV1(new Date(), '000123456789abc').split('-')[4]
|
|
1270
|
-
).
|
|
1347
|
+
).toBe('123456789abc')
|
|
1271
1348
|
|
|
1272
1349
|
expect(
|
|
1273
1350
|
uuidV1(new Date(), '123456789').split('-')[4]
|
|
1274
|
-
).
|
|
1351
|
+
).toBe('000123456789')
|
|
1275
1352
|
|
|
1276
1353
|
expect(
|
|
1277
1354
|
uuidV1(new Date(323325000000)).startsWith(
|
|
1278
1355
|
'c1399400-9a71-11bd'
|
|
1279
1356
|
)
|
|
1280
|
-
).
|
|
1281
|
-
```
|
|
1282
|
-
|
|
1283
|
-
### vivify
|
|
1284
|
-
|
|
1285
|
-
```ts
|
|
1286
|
-
const vivify: (ref: unknown) => any;
|
|
1287
|
-
```
|
|
1288
|
-
|
|
1289
|
-
A Proxy-based helper for auto-vivification of nested
|
|
1290
|
-
object structures.
|
|
1291
|
-
|
|
1292
|
-
Accessing, assigning, or deleting any nested property on
|
|
1293
|
-
the returned proxy automatically creates intermediate
|
|
1294
|
-
objects (or arrays for numeric-string keys matching
|
|
1295
|
-
`^(0|[1-9]\d*)$`) as needed, allowing deep operations
|
|
1296
|
-
without explicit null checks.
|
|
1297
|
-
|
|
1298
|
-
Intermediates of the last level in a get-only property
|
|
1299
|
-
chain are NOT auto-created. For example,
|
|
1300
|
-
`vivify(ref).one.two` will create `ref.one` as `{}`, but
|
|
1301
|
-
will NOT create `ref.one.two`. Only when a deeper access,
|
|
1302
|
-
assignment, or deletion occurs, e.g.
|
|
1303
|
-
|
|
1304
|
-
```ts
|
|
1305
|
-
delete vivify(ref).one.two.three
|
|
1306
|
-
```
|
|
1307
|
-
|
|
1308
|
-
or
|
|
1309
|
-
|
|
1310
|
-
```ts
|
|
1311
|
-
vivify(ref).one.two.three = 4
|
|
1312
|
-
```
|
|
1313
|
-
|
|
1314
|
-
Will `ref.one.two` be materialized.
|
|
1315
|
-
|
|
1316
|
-
When traversal reaches a primitive value, no
|
|
1317
|
-
auto-creation happens; the primitive’s own property is
|
|
1318
|
-
returned instead (e.g. accessing `.toString.name` on a
|
|
1319
|
-
number yields `'toString'` without modifying the
|
|
1320
|
-
underlying structure).
|
|
1321
|
-
|
|
1322
|
-
Deletion on a non-existing intermediate path will
|
|
1323
|
-
auto-create intermediates up to the parent of the deleted
|
|
1324
|
-
key, e.g.
|
|
1325
|
-
|
|
1326
|
-
```ts
|
|
1327
|
-
delete vivify(ref).one.two.three
|
|
1328
|
-
```
|
|
1329
|
-
|
|
1330
|
-
Will create `ref.one.two` as `{}` if it does not exist.
|
|
1331
|
-
|
|
1332
|
-
#### ref
|
|
1333
|
-
|
|
1334
|
-
The root object to wrap.
|
|
1335
|
-
|
|
1336
|
-
#### Returns
|
|
1337
|
-
|
|
1338
|
-
A proxy that auto-creates nested objects/arrays
|
|
1339
|
-
on property access.
|
|
1340
|
-
|
|
1341
|
-
#### Usage Examples
|
|
1342
|
-
|
|
1343
|
-
```ts
|
|
1344
|
-
const ref: any = {}
|
|
1345
|
-
|
|
1346
|
-
vivify(ref).one.two[3][4]
|
|
1347
|
-
|
|
1348
|
-
expect(ref).to.deep.equal({
|
|
1349
|
-
one: {
|
|
1350
|
-
two: [undefined, undefined, undefined, []],
|
|
1351
|
-
},
|
|
1352
|
-
})
|
|
1353
|
-
|
|
1354
|
-
vivify(ref).one.two[3][4] = 5
|
|
1355
|
-
|
|
1356
|
-
expect(ref).to.deep.equal({
|
|
1357
|
-
one: {
|
|
1358
|
-
two: [
|
|
1359
|
-
undefined,
|
|
1360
|
-
undefined,
|
|
1361
|
-
undefined,
|
|
1362
|
-
[undefined, undefined, undefined, undefined, 5],
|
|
1363
|
-
],
|
|
1364
|
-
},
|
|
1365
|
-
})
|
|
1366
|
-
|
|
1367
|
-
vivify(ref).one.two[3].length = 1
|
|
1368
|
-
|
|
1369
|
-
expect(ref).to.deep.equal({
|
|
1370
|
-
one: {
|
|
1371
|
-
two: [undefined, undefined, undefined, [undefined]],
|
|
1372
|
-
},
|
|
1373
|
-
})
|
|
1374
|
-
|
|
1375
|
-
vivify(ref).one.two[3] = 4
|
|
1376
|
-
|
|
1377
|
-
expect(ref).to.deep.equal({
|
|
1378
|
-
one: {
|
|
1379
|
-
two: [undefined, undefined, undefined, 4],
|
|
1380
|
-
},
|
|
1381
|
-
})
|
|
1382
|
-
|
|
1383
|
-
expect(vivify(ref).one.two.length).to.equal(4)
|
|
1384
|
-
|
|
1385
|
-
expect(ref).to.deep.equal({
|
|
1386
|
-
one: {
|
|
1387
|
-
two: [undefined, undefined, undefined, 4],
|
|
1388
|
-
},
|
|
1389
|
-
})
|
|
1390
|
-
|
|
1391
|
-
vivify(ref).one.two = 3
|
|
1392
|
-
|
|
1393
|
-
expect(ref).to.deep.equal({ one: { two: 3 } })
|
|
1394
|
-
|
|
1395
|
-
vivify(ref).one.two = undefined
|
|
1396
|
-
|
|
1397
|
-
expect(ref).to.deep.equal({ one: { two: undefined } })
|
|
1398
|
-
|
|
1399
|
-
delete vivify(ref).one.two
|
|
1400
|
-
|
|
1401
|
-
expect(ref).to.deep.equal({ one: {} })
|
|
1402
|
-
|
|
1403
|
-
expect(vivify(ref).one.toString instanceof Function).to.be
|
|
1404
|
-
.true
|
|
1405
|
-
|
|
1406
|
-
expect(vivify(ref).one.toString.name).to.equal('toString')
|
|
1407
|
-
|
|
1408
|
-
expect(ref).to.deep.equal({ one: {} })
|
|
1409
|
-
|
|
1410
|
-
delete vivify(ref).one.two.three
|
|
1411
|
-
|
|
1412
|
-
expect(ref).to.deep.equal({ one: { two: {} } })
|
|
1413
|
-
|
|
1414
|
-
vivify(ref).one.two.three.four
|
|
1415
|
-
|
|
1416
|
-
expect(ref).to.deep.equal({ one: { two: { three: {} } } })
|
|
1417
|
-
|
|
1418
|
-
vivify(ref).one.two[3]
|
|
1419
|
-
|
|
1420
|
-
expect(ref).to.deep.equal({ one: { two: { three: {} } } })
|
|
1421
|
-
|
|
1422
|
-
vivify(ref).one.two.three.four = 5
|
|
1423
|
-
|
|
1424
|
-
expect(ref).to.deep.equal({
|
|
1425
|
-
one: { two: { three: { four: 5 } } },
|
|
1426
|
-
})
|
|
1427
|
-
|
|
1428
|
-
expect(
|
|
1429
|
-
vivify(ref).one.two.three.four.toString.name
|
|
1430
|
-
).to.equal('toString')
|
|
1431
|
-
|
|
1432
|
-
expect(ref).to.deep.equal({
|
|
1433
|
-
one: { two: { three: { four: 5 } } },
|
|
1434
|
-
})
|
|
1435
|
-
|
|
1436
|
-
const u = undefined
|
|
1437
|
-
|
|
1438
|
-
vivify(u).one.two = 3
|
|
1439
|
-
|
|
1440
|
-
expect(u).to.be.undefined
|
|
1441
|
-
|
|
1442
|
-
const n = null
|
|
1443
|
-
|
|
1444
|
-
delete vivify(n).one.two.three
|
|
1445
|
-
|
|
1446
|
-
expect(n).to.be.null
|
|
1357
|
+
).toBe(true)
|
|
1447
1358
|
```
|
|
1448
1359
|
|
|
1449
1360
|
## License
|