@jackens/nnn 2026.9.2 → 2026.9.7

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 (3) hide show
  1. package/nnn.js +1 -1
  2. package/package.json +13 -23
  3. package/readme.md +333 -251
package/nnn.js CHANGED
@@ -108,7 +108,7 @@ var _h = (createElement, tagOrNode, ...args) => {
108
108
  child = _h(createElement, ...arg);
109
109
  } else if (typeof arg === "string" || typeof arg === "number") {
110
110
  child = document.createTextNode(arg);
111
- } else if (arg != null) {
111
+ } else if (typeof arg === "object" && arg != null) {
112
112
  for (const name in arg) {
113
113
  const value = arg[name];
114
114
  if (name[0] === "$") {
package/package.json CHANGED
@@ -1,33 +1,24 @@
1
1
  {
2
- "author": "Jackens",
2
+ "name": "@jackens/nnn",
3
+ "version": "2026.9.7",
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
- "has",
13
- "highlight",
14
9
  "HyperScript",
15
- "in",
16
- "is",
17
- "isArray",
18
- "isFiniteNumber",
19
- "isNumber",
20
- "isRecord",
21
- "isString",
22
10
  "JS-to-CSS",
23
11
  "Monokai",
24
- "nanolight",
25
- "nnn",
26
- "omit",
27
- "pick",
28
- "Responsive Web Design",
29
12
  "RWD",
13
+ "Responsive Web Design",
30
14
  "SVG",
15
+ "autovivify",
16
+ "c",
17
+ "escape",
18
+ "h",
19
+ "highlight",
20
+ "nanolight",
21
+ "nnn",
31
22
  "tokenize",
32
23
  "tokenizer",
33
24
  "typography",
@@ -37,9 +28,8 @@
37
28
  "vivify"
38
29
  ],
39
30
  "license": "MIT",
40
- "main": "nnn.js",
41
- "name": "@jackens/nnn",
31
+ "author": "Jackens",
42
32
  "type": "module",
43
- "types": "nnn.d.ts",
44
- "version": "2026.9.2"
33
+ "main": "nnn.js",
34
+ "types": "nnn.d.ts"
45
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.2`).
3
+ A collection of Jackens’ JavaScript helper utilities (version: `2026.9.7`).
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,
@@ -145,7 +148,7 @@ A CSS string representing the compiled rules.
145
148
  #### Usage Examples
146
149
 
147
150
  ```ts
148
- const actual1 = c({
151
+ const actual = c({
149
152
  a: {
150
153
  color: 'red',
151
154
  margin: 1,
@@ -154,22 +157,25 @@ const actual1 = c({
154
157
  },
155
158
  })
156
159
 
157
- const expected1 = `
158
- a{
159
- color:red;
160
- margin:1
161
- }
162
- a.c{
163
- margin:2;
164
- padding:2
165
- }
166
- a{
167
- padding:1
168
- }`.replace(/\n\s*/g, '')
160
+ const expected = `
161
+ a{
162
+ color:red;
163
+ margin:1
164
+ }
165
+ a.c{
166
+ margin:2;
167
+ padding:2
168
+ }
169
+ a{
170
+ padding:1
171
+ }
172
+ `.replace(/\n\s*/g, '')
169
173
 
170
- expect(actual1).to.equal(expected1)
174
+ expect(actual).toBe(expected)
175
+ ```
171
176
 
172
- const actual2 = c({
177
+ ```ts
178
+ const actual = c({
173
179
  a: {
174
180
  '.b': {
175
181
  color: 'red',
@@ -180,22 +186,25 @@ const actual2 = c({
180
186
  },
181
187
  })
182
188
 
183
- const expected2 = `
184
- a.b{
185
- color:red;
186
- margin:1
187
- }
188
- a.b.c{
189
- margin:2;
190
- padding:2
191
- }
192
- a.b{
193
- padding:1
194
- }`.replace(/\n\s*/g, '')
189
+ const expected = `
190
+ a.b{
191
+ color:red;
192
+ margin:1
193
+ }
194
+ a.b.c{
195
+ margin:2;
196
+ padding:2
197
+ }
198
+ a.b{
199
+ padding:1
200
+ }
201
+ `.replace(/\n\s*/g, '')
195
202
 
196
- expect(actual2).to.equal(expected2)
203
+ expect(actual).toBe(expected)
204
+ ```
197
205
 
198
- const actual3 = c({
206
+ ```ts
207
+ const actual = c({
199
208
  '@font-face$$1': {
200
209
  'font-family': 'Jackens',
201
210
  src$$1: 'url(otf/jackens.otf)',
@@ -225,51 +234,54 @@ const actual3 = c({
225
234
  },
226
235
  })
227
236
 
228
- const expected3 = `
229
- @font-face{
230
- font-family:Jackens;
231
- src:url(otf/jackens.otf);
232
- src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
233
- font-weight:normal;
234
- font-style:normal
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)
237
+ const expected = `
238
+ @font-face{
239
+ font-family:Jackens;
240
+ src:url(otf/jackens.otf);
241
+ src:url(otf/jackens.otf) format('opentype'),url(svg/jackens.svg) format('svg');
242
+ font-weight:normal;
243
+ font-style:normal
243
244
  }
244
- 100%{
245
- transform:rotate(360deg)
245
+ @font-face{
246
+ font-family:C64;
247
+ src:url(fonts/C64_Pro_Mono-STYLE.woff)
248
+ }
249
+ @keyframes spin{
250
+ 0%{
251
+ transform:rotate(0deg)
252
+ }
253
+ 100%{
254
+ transform:rotate(360deg)
255
+ }
246
256
  }
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
257
  div{
262
- margin:0;
263
- padding:0
258
+ border:solid red 1px
259
+ }
260
+ div.c1{
261
+ background-color:#000
264
262
  }
265
- span{
266
- color:#000
263
+ div .c1{
264
+ background-color:black
267
265
  }
268
- }`.replace(/\n\s*/g, '')
266
+ div.c2{
267
+ background-color:rgb(0,0,0)
268
+ }
269
+ @media(min-width:200px){
270
+ div{
271
+ margin:0;
272
+ padding:0
273
+ }
274
+ span{
275
+ color:#000
276
+ }
277
+ }
278
+ `.replace(/\n\s*/g, '')
269
279
 
270
- expect(actual3).to.equal(expected3)
280
+ expect(actual).toBe(expected)
281
+ ```
271
282
 
272
- const actual4 = c({
283
+ ```ts
284
+ const actual = c({
273
285
  a: {
274
286
  '.b,.c': {
275
287
  margin: 1,
@@ -280,17 +292,20 @@ const actual4 = c({
280
292
  },
281
293
  })
282
294
 
283
- const expected4 = `
284
- a.b,a.c{
285
- margin:1
286
- }
287
- a.b.d,a.c.d{
288
- margin:2
289
- }`.replace(/\n\s*/g, '')
295
+ const expected = `
296
+ a.b,a.c{
297
+ margin:1
298
+ }
299
+ a.b.d,a.c.d{
300
+ margin:2
301
+ }
302
+ `.replace(/\n\s*/g, '')
290
303
 
291
- expect(actual4).to.equal(expected4)
304
+ expect(actual).toBe(expected)
305
+ ```
292
306
 
293
- const actual5 = c({
307
+ ```ts
308
+ const actual = c({
294
309
  '.b,.c': {
295
310
  margin: 1,
296
311
  '.d': {
@@ -299,17 +314,20 @@ const actual5 = c({
299
314
  },
300
315
  })
301
316
 
302
- const expected5 = `
303
- .b,.c{
304
- margin:1
305
- }
306
- .b.d,.c.d{
307
- margin:2
308
- }`.replace(/\n\s*/g, '')
317
+ const expected = `
318
+ .b,.c{
319
+ margin:1
320
+ }
321
+ .b.d,.c.d{
322
+ margin:2
323
+ }
324
+ `.replace(/\n\s*/g, '')
309
325
 
310
- expect(actual5).to.equal(expected5)
326
+ expect(actual).toBe(expected)
327
+ ```
311
328
 
312
- const actual6 = c({
329
+ ```ts
330
+ const actual = c({
313
331
  '.a,.b': {
314
332
  margin: 1,
315
333
  '.c,.d': {
@@ -318,17 +336,20 @@ const actual6 = c({
318
336
  },
319
337
  })
320
338
 
321
- const expected6 = `
322
- .a,.b{
323
- margin:1
324
- }
325
- .a.c,.a.d,.b.c,.b.d{
326
- margin:2
327
- }`.replace(/\n\s*/g, '')
339
+ const expected = `
340
+ .a,.b{
341
+ margin:1
342
+ }
343
+ .a.c,.a.d,.b.c,.b.d{
344
+ margin:2
345
+ }
346
+ `.replace(/\n\s*/g, '')
328
347
 
329
- expect(actual6).to.equal(expected6)
348
+ expect(actual).toBe(expected)
349
+ ```
330
350
 
331
- const actual7 = c({
351
+ ```ts
352
+ const actual = c({
332
353
  ':root$$monokai': {
333
354
  '--': {
334
355
  bg: '#faf4f2',
@@ -378,7 +399,7 @@ const actual7 = c({
378
399
  },
379
400
  })
380
401
 
381
- const expected7 = `
402
+ const expected = `
382
403
  :root{
383
404
  --bg:#faf4f2;
384
405
  --fg:#29242a;
@@ -412,9 +433,10 @@ const expected7 = `
412
433
  --punctuation:#727072;
413
434
  --string:#ffd866
414
435
  }
415
- }`.replace(/\n\s*/g, '')
436
+ }
437
+ `.replace(/\n\s*/g, '')
416
438
 
417
- expect(actual7).to.equal(expected7)
439
+ expect(actual).toBe(expected)
418
440
  ```
419
441
 
420
442
  ### createEscape
@@ -457,31 +479,31 @@ const escapeFn = (value: any): string =>
457
479
  const sql = createEscape(escapeFn)
458
480
 
459
481
  const actual = sql`
460
- SELECT *
461
- FROM table_name
462
- WHERE column_name IN (
463
- ${[
464
- true,
465
- null,
466
- undefined,
467
- NaN,
468
- Infinity,
469
- 42,
470
- '42',
471
- "4'2",
472
- /42/,
473
- new Date(323325000000),
474
- ]}
475
- )`
482
+ SELECT *
483
+ FROM table_name
484
+ WHERE column_name IN (
485
+ ${[
486
+ true,
487
+ null,
488
+ undefined,
489
+ NaN,
490
+ Infinity,
491
+ 42,
492
+ '42',
493
+ "4'2",
494
+ /42/,
495
+ new Date(323325000000),
496
+ ]}
497
+ )`
476
498
 
477
499
  const expected = `
478
- SELECT *
479
- FROM table_name
480
- WHERE column_name IN (
481
- b'1', NULL, NULL, NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00'
482
- )`
500
+ SELECT *
501
+ FROM table_name
502
+ WHERE column_name IN (
503
+ b'1', NULL, NULL, NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00'
504
+ )`
483
505
 
484
- expect(actual).to.equal(expected)
506
+ expect(actual).toBe(expected)
485
507
  ```
486
508
 
487
509
  ### createTokenizer
@@ -528,15 +550,15 @@ and returns an array of decorated tokens.
528
550
  #### Usage Examples
529
551
 
530
552
  ```ts
531
- const tokenizer1 = createTokenizer(
553
+ const tokenizer = createTokenizer(
532
554
  (chunk, metadata) => ({ chunk, metadata }),
533
555
  ['keyword', /\b(if|else|for)\b/],
534
556
  ['string', /"[^"]*"/]
535
557
  )
536
558
 
537
- const result1 = tokenizer1('if "hello" else "world"')
559
+ const result = tokenizer('if "hello" else "world"')
538
560
 
539
- expect(result1).to.deep.equal([
561
+ expect(result).toEqual([
540
562
  { chunk: 'if', metadata: 'keyword' },
541
563
  { chunk: ' ', metadata: undefined },
542
564
  { chunk: '"hello"', metadata: 'string' },
@@ -545,92 +567,108 @@ expect(result1).to.deep.equal([
545
567
  { chunk: ' ', metadata: undefined },
546
568
  { chunk: '"world"', metadata: 'string' },
547
569
  ])
570
+ ```
548
571
 
549
- const tokenizer2 = createTokenizer(
572
+ ```ts
573
+ const tokenizer = createTokenizer(
550
574
  (chunk, metadata) => `${metadata}:${chunk}`,
551
575
  ['tag', 'BEGIN'],
552
576
  ['end', 'END']
553
577
  )
554
578
 
555
- const result2 = tokenizer2('aBEGINbENDc')
579
+ const result = tokenizer('aBEGINbENDc')
556
580
 
557
- expect(result2).to.deep.equal([
581
+ expect(result).toEqual([
558
582
  'undefined:a',
559
583
  'tag:BEGIN',
560
584
  'undefined:b',
561
585
  'end:END',
562
586
  'undefined:c',
563
587
  ])
588
+ ```
564
589
 
565
- const tokenizer3 = createTokenizer(
590
+ ```ts
591
+ const tokenizer = createTokenizer(
566
592
  chunk => chunk,
567
593
  ['test', /test/]
568
594
  )
569
595
 
570
- const result3 = tokenizer3('')
596
+ const result = tokenizer('')
571
597
 
572
- expect(result3).to.deep.equal([])
598
+ expect(result).toEqual([])
599
+ ```
573
600
 
574
- const tokenizer4 = createTokenizer(
601
+ ```ts
602
+ const tokenizer = createTokenizer(
575
603
  (chunk, metadata) => ({ chunk, metadata }),
576
604
  ['start', /^test/]
577
605
  )
578
606
 
579
- const result4 = tokenizer4('test here')
607
+ const result = tokenizer('test here')
580
608
 
581
- expect(result4).to.deep.equal([
609
+ expect(result).toEqual([
582
610
  { chunk: 'test', metadata: 'start' },
583
611
  { chunk: ' here', metadata: undefined },
584
612
  ])
613
+ ```
585
614
 
586
- const tokenizer5 = createTokenizer(
615
+ ```ts
616
+ const tokenizer = createTokenizer(
587
617
  (chunk, metadata) => metadata,
588
618
  ['later', /x/],
589
619
  ['earlier', /y/]
590
620
  )
591
621
 
592
- const result5 = tokenizer5('yx')
622
+ const result = tokenizer('yx')
593
623
 
594
- expect(result5).to.deep.equal(['earlier', 'later'])
624
+ expect(result).toEqual(['earlier', 'later'])
625
+ ```
595
626
 
596
- const tokenizer6 = createTokenizer(
627
+ ```ts
628
+ const tokenizer = createTokenizer(
597
629
  chunk => chunk,
598
630
  ['short', 'a'],
599
631
  ['long', 'abc']
600
632
  )
601
633
 
602
- const result6 = tokenizer6('abc')
634
+ const result = tokenizer('abc')
603
635
 
604
- expect(result6).to.deep.equal(['abc'])
636
+ expect(result).toEqual(['abc'])
637
+ ```
605
638
 
606
- const tokenizer7 = createTokenizer(
639
+ ```ts
640
+ const tokenizer = createTokenizer(
607
641
  chunk => chunk,
608
642
  ['empty', ''],
609
643
  ['word', /\w+/]
610
644
  )
611
645
 
612
- const result7 = tokenizer7('hello')
646
+ const result = tokenizer('hello')
613
647
 
614
- expect(result7).to.deep.equal(['hello'])
648
+ expect(result).toEqual(['hello'])
649
+ ```
615
650
 
616
- const tokenizer8 = createTokenizer(
651
+ ```ts
652
+ const tokenizer = createTokenizer(
617
653
  chunk => chunk,
618
654
  ['test', /xyz/]
619
655
  )
620
656
 
621
- const result8 = tokenizer8('abc')
657
+ const result = tokenizer('abc')
622
658
 
623
- expect(result8).to.deep.equal(['abc'])
659
+ expect(result).toEqual(['abc'])
660
+ ```
624
661
 
625
- const tokenizer9 = createTokenizer(
662
+ ```ts
663
+ const tokenizer = createTokenizer(
626
664
  (_chunk, metadata) => metadata,
627
665
  ['a', 'a'],
628
666
  ['b', 'b']
629
667
  )
630
668
 
631
- const result9 = tokenizer9('aabb')
669
+ const result = tokenizer('aabb')
632
670
 
633
- expect(result9).to.deep.equal(['a', 'a', 'b', 'b'])
671
+ expect(result).toEqual(['a', 'a', 'b', 'b'])
634
672
  ```
635
673
 
636
674
  ### csvParse
@@ -670,7 +708,7 @@ yyy",zzz
670
708
 
671
709
  `
672
710
 
673
- expect(csvParse(text)).to.deep.equal([
711
+ expect(csvParse(text)).toEqual([
674
712
  ['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
675
713
  ['xxx,xxx', 'yyy\nyyy', 'zzz'],
676
714
  [' 42 ', '42', ' 17'],
@@ -716,7 +754,7 @@ const p = h(
716
754
 
717
755
  fixPlTypography(p)
718
756
 
719
- expect(p.innerHTML).to.deep.equal(
757
+ expect(p.innerHTML).toEqual(
720
758
  'Pchnąć ' +
721
759
  '<span style="white-space:nowrap">w </span>' +
722
760
  'tę łódź jeża lub ośm skrzyń fig ' +
@@ -775,61 +813,66 @@ The created or modified `HTMLElement`.
775
813
  ```ts
776
814
  const b = h('b')
777
815
 
778
- expect(b.outerHTML).to.equal('<b></b>')
816
+ expect(b.outerHTML).toBe('<b></b>')
779
817
 
780
818
  const i = h('i', 'text')
781
819
 
782
820
  h(b, i)
783
821
 
784
- expect(i.outerHTML).to.equal('<i>text</i>')
822
+ expect(i.outerHTML).toBe('<i>text</i>')
785
823
 
786
- expect(b.outerHTML).to.equal('<b><i>text</i></b>')
824
+ expect(b.outerHTML).toBe('<b><i>text</i></b>')
787
825
 
788
826
  h(i, { $className: 'some class' })
789
827
 
790
- expect(i.outerHTML).to.equal(
791
- '<i class="some class">text</i>'
792
- )
828
+ expect(i.outerHTML).toBe('<i class="some class">text</i>')
793
829
 
794
- expect(b.outerHTML).to.equal(
830
+ expect(b.outerHTML).toBe(
795
831
  '<b><i class="some class">text</i></b>'
796
832
  )
833
+ ```
797
834
 
798
- expect(h('span', 'text').outerHTML).to.equal(
835
+ ```ts
836
+ expect(h('span', 'text').outerHTML).toBe(
799
837
  '<span>text</span>'
800
838
  )
801
839
 
802
- expect(
803
- h('span', { $innerText: 'text' }).outerHTML
804
- ).to.equal('<span>text</span>')
805
-
806
- expect(h('span', '42').outerHTML).to.equal(
807
- '<span>42</span>'
840
+ expect(h('span', { $innerText: 'text' }).outerHTML).toBe(
841
+ '<span>text</span>'
808
842
  )
809
843
 
810
- expect(h('span', 42).outerHTML).to.equal('<span>42</span>')
844
+ expect(h('span', '42').outerHTML).toBe('<span>42</span>')
811
845
 
846
+ expect(h('span', 42).outerHTML).toBe('<span>42</span>')
847
+ ```
848
+
849
+ ```ts
812
850
  expect(
813
851
  h('div', { style: 'margin:0;padding:0' }).outerHTML
814
- ).to.equal('<div style="margin:0;padding:0"></div>')
852
+ ).toBe('<div style="margin:0;padding:0"></div>')
815
853
 
816
854
  expect(
817
855
  h('div', { $style: 'margin:0;padding:0' }).outerHTML
818
- ).to.equal('<div style="margin: 0px; padding: 0px;"></div>')
856
+ ).toBe('<div style="margin: 0px; padding: 0px;"></div>')
819
857
 
820
858
  expect(
821
- h('div', { $style: { margin: 0, padding: 0 } }).outerHTML
822
- ).to.equal('<div style="margin: 0px; padding: 0px;"></div>')
859
+ h('div', { $style: { margin: 0, padding: 0 } })
860
+ .outerHTML
861
+ ).toBe('<div style="margin: 0px; padding: 0px;"></div>')
862
+ ```
823
863
 
864
+ ```ts
824
865
  const input1 = h('input', { value: 42 })
825
866
  const input2 = h('input', { $value: '42' })
826
867
 
827
- expect(input1.value).to.equal('42')
828
- expect(input2.value).to.equal('42')
868
+ expect(input1.value).toBe('42')
869
+ expect(input2.value).toBe('42')
829
870
 
830
- expect(input1.outerHTML).to.equal('<input value="42">')
831
- expect(input2.outerHTML).to.equal('<input>')
871
+ expect(input1.outerHTML).toBe('<input value="42">')
872
+ expect(input2.outerHTML).toBe('<input>')
873
+ ```
832
874
 
875
+ ```ts
833
876
  const checkbox1 = h('input', {
834
877
  type: 'checkbox',
835
878
  checked: true,
@@ -840,38 +883,42 @@ const checkbox2 = h('input', {
840
883
  $checked: true,
841
884
  })
842
885
 
843
- expect(checkbox1.checked).to.be.true
844
- expect(checkbox2.checked).to.be.true
886
+ expect(checkbox1.checked).toBe(true)
887
+ expect(checkbox2.checked).toBe(true)
845
888
 
846
- expect(checkbox1.outerHTML).to.equal(
889
+ expect(checkbox1.outerHTML).toBe(
847
890
  '<input type="checkbox" checked="">'
848
891
  )
849
892
 
850
- expect(checkbox2.outerHTML).to.equal(
893
+ expect(checkbox2.outerHTML).toBe(
851
894
  '<input type="checkbox">'
852
895
  )
896
+ ```
853
897
 
898
+ ```ts
854
899
  const div = h('div')
855
900
 
856
- expect(div.key).to.be.undefined
901
+ expect(div.key).toBeUndefined()
857
902
 
858
903
  h(div, { $key: { one: 1 } })
859
904
 
860
- expect(div.key).to.deep.equal({ one: 1 })
905
+ expect(div.key).toEqual({ one: 1 })
861
906
 
862
907
  h(div, { $key: { two: 2 } })
863
908
 
864
- expect(div.key).to.deep.equal({ one: 1, two: 2 })
909
+ expect(div.key).toEqual({ one: 1, two: 2 })
910
+ ```
865
911
 
912
+ ```ts
866
913
  const elemWithClass = h('div', { class: 'test' })
867
914
 
868
- expect(elemWithClass.getAttribute('class')).to.equal('test')
915
+ expect(elemWithClass.getAttribute('class')).toBe('test')
869
916
 
870
917
  const elemWithText = h('div', 'initial')
871
918
 
872
919
  h(elemWithText, ' more')
873
920
 
874
- expect(elemWithText.outerHTML).to.equal(
921
+ expect(elemWithText.outerHTML).toBe(
875
922
  '<div>initial more</div>'
876
923
  )
877
924
 
@@ -881,7 +928,7 @@ const elemWithNested = h(
881
928
  ['b', 'world']
882
929
  )
883
930
 
884
- expect(elemWithNested.outerHTML).to.equal(
931
+ expect(elemWithNested.outerHTML).toBe(
885
932
  '<div><span>hello</span><b>world</b></div>'
886
933
  )
887
934
  ```
@@ -920,7 +967,7 @@ const codeJs =
920
967
  'const answerToLifeTheUniverseAndEverything = ' +
921
968
  "{ 42: 42 }['42'] /* 42 */"
922
969
 
923
- expect(nanolightTs(codeJs)).to.deep.equal([
970
+ expect(nanolightTs(codeJs)).toEqual([
924
971
  ['span', { class: 'keyword1' }, 'const'],
925
972
  ' ',
926
973
  [
@@ -1002,7 +1049,7 @@ const style: CNode = {
1002
1049
 
1003
1050
  rwd(style, '.r6', 200, 50, [6], [3], [1, 1, 2])
1004
1051
 
1005
- expect(style).to.deep.equal({
1052
+ expect(style).toEqual({
1006
1053
  body: {
1007
1054
  margin: 0,
1008
1055
  },
@@ -1077,29 +1124,49 @@ The created or modified `SVGElement`.
1077
1124
  #### Usage Examples
1078
1125
 
1079
1126
  ```ts
1080
- const XLINK_NS = 'http://www.w3.org/1999/xlink'
1081
-
1082
- const svg1 = s('svg', { 'xlink:href': true })
1127
+ const svg = s('svg', { 'xlink:href': true })
1083
1128
 
1084
- expect(svg1.getAttributeNS(XLINK_NS, 'href')).to.equal('')
1129
+ expect(
1130
+ svg.getAttributeNS(
1131
+ 'http://www.w3.org/1999/xlink',
1132
+ 'href'
1133
+ )
1134
+ ).toBe('')
1135
+ ```
1085
1136
 
1086
- const svg2 = s('svg', { 'xlink:href': false })
1137
+ ```ts
1138
+ const svg = s('svg', { 'xlink:href': false })
1087
1139
 
1088
- expect(svg2.getAttributeNS(XLINK_NS, 'href')).to.be.null
1140
+ expect(
1141
+ svg.getAttributeNS(
1142
+ 'http://www.w3.org/1999/xlink',
1143
+ 'href'
1144
+ )
1145
+ ).toBeNull()
1146
+ ```
1089
1147
 
1090
- const svg3 = s('svg', {
1148
+ ```ts
1149
+ const svg = s('svg', {
1091
1150
  'xlink:href': 'http://example.com',
1092
1151
  })
1093
1152
 
1094
- expect(svg3.getAttributeNS(XLINK_NS, 'href')).to.equal(
1095
- 'http://example.com'
1096
- )
1153
+ expect(
1154
+ svg.getAttributeNS(
1155
+ 'http://www.w3.org/1999/xlink',
1156
+ 'href'
1157
+ )
1158
+ ).toBe('http://example.com')
1159
+ ```
1097
1160
 
1098
- const svg4 = s('svg', { 'xlink:title': 42 })
1161
+ ```ts
1162
+ const svg = s('svg', { 'xlink:title': 42 })
1099
1163
 
1100
- expect(svg4.getAttributeNS(XLINK_NS, 'title')).to.equal(
1101
- '42'
1102
- )
1164
+ expect(
1165
+ svg.getAttributeNS(
1166
+ 'http://www.w3.org/1999/xlink',
1167
+ 'title'
1168
+ )
1169
+ ).toBe('42')
1103
1170
  ```
1104
1171
 
1105
1172
  ### svgUse
@@ -1138,47 +1205,54 @@ An `SVGSVGElement` containing a `<use>` element.
1138
1205
  #### Usage Examples
1139
1206
 
1140
1207
  ```ts
1141
- const XLINK_NS = 'http://www.w3.org/1999/xlink'
1142
-
1143
1208
  const svg = svgUse('icon-home')
1144
1209
 
1145
- expect(svg.children.length).to.equal(1)
1210
+ expect(svg.children.length).toBe(1)
1146
1211
 
1147
1212
  const useElement = svg.children[0]
1148
1213
 
1149
1214
  expect(
1150
- useElement.getAttributeNS(XLINK_NS, 'href')
1151
- ).to.equal('#icon-home')
1215
+ useElement.getAttributeNS(
1216
+ 'http://www.w3.org/1999/xlink',
1217
+ 'href'
1218
+ )
1219
+ ).toBe('#icon-home')
1152
1220
 
1153
1221
  const svgWithViewBox = svgUse('icon-star', {
1154
1222
  viewBox: '0 0 24 24',
1155
1223
  })
1156
1224
 
1157
- expect(svgWithViewBox.getAttribute('viewBox')).to.equal(
1225
+ expect(svgWithViewBox.getAttribute('viewBox')).toBe(
1158
1226
  '0 0 24 24'
1159
1227
  )
1160
1228
 
1161
1229
  const useViewBox = svgWithViewBox.children[0]
1162
1230
 
1163
1231
  expect(
1164
- useViewBox.getAttributeNS(XLINK_NS, 'href')
1165
- ).to.equal('#icon-star')
1232
+ useViewBox.getAttributeNS(
1233
+ 'http://www.w3.org/1999/xlink',
1234
+ 'href'
1235
+ )
1236
+ ).toBe('#icon-star')
1166
1237
 
1167
1238
  const svgWithClass = svgUse('icon-menu', {
1168
1239
  class: 'icon-btn',
1169
1240
  })
1170
1241
 
1171
- expect(svgWithClass.getAttribute('class')).to.equal(
1242
+ expect(svgWithClass.getAttribute('class')).toBe(
1172
1243
  'icon-btn'
1173
1244
  )
1174
1245
 
1175
- expect(svgWithClass.children.length).to.equal(1)
1246
+ expect(svgWithClass.children.length).toBe(1)
1176
1247
 
1177
1248
  const useClass = svgWithClass.children[0]
1178
1249
 
1179
- expect(useClass.getAttributeNS(XLINK_NS, 'href')).to.equal(
1180
- '#icon-menu'
1181
- )
1250
+ expect(
1251
+ useClass.getAttributeNS(
1252
+ 'http://www.w3.org/1999/xlink',
1253
+ 'href'
1254
+ )
1255
+ ).toBe('#icon-menu')
1182
1256
 
1183
1257
  const svgWithMultipleAttrs = svgUse('icon-settings', {
1184
1258
  width: 24,
@@ -1186,23 +1260,26 @@ const svgWithMultipleAttrs = svgUse('icon-settings', {
1186
1260
  class: 'icon',
1187
1261
  })
1188
1262
 
1189
- expect(svgWithMultipleAttrs.getAttribute('width')).to.equal(
1263
+ expect(svgWithMultipleAttrs.getAttribute('width')).toBe(
1190
1264
  '24'
1191
1265
  )
1192
1266
 
1193
- expect(
1194
- svgWithMultipleAttrs.getAttribute('height')
1195
- ).to.equal('24')
1267
+ expect(svgWithMultipleAttrs.getAttribute('height')).toBe(
1268
+ '24'
1269
+ )
1196
1270
 
1197
- expect(svgWithMultipleAttrs.getAttribute('class')).to.equal(
1271
+ expect(svgWithMultipleAttrs.getAttribute('class')).toBe(
1198
1272
  'icon'
1199
1273
  )
1200
1274
 
1201
1275
  const useMultiple = svgWithMultipleAttrs.children[0]
1202
1276
 
1203
1277
  expect(
1204
- useMultiple.getAttributeNS(XLINK_NS, 'href')
1205
- ).to.equal('#icon-settings')
1278
+ useMultiple.getAttributeNS(
1279
+ 'http://www.w3.org/1999/xlink',
1280
+ 'href'
1281
+ )
1282
+ ).toBe('#icon-settings')
1206
1283
  ```
1207
1284
 
1208
1285
  ### uuidV1
@@ -1237,47 +1314,49 @@ for (let i = 1; i <= 22136; ++i) {
1237
1314
  const uuid = uuidV1()
1238
1315
 
1239
1316
  if (i === 1) {
1240
- expect(uuid.split('-')[3]).to.equal('8001')
1317
+ expect(uuid.split('-')[3]).toBe('8001')
1241
1318
  }
1242
1319
 
1243
1320
  if (i === 4095) {
1244
- expect(uuid.split('-')[3]).to.equal('8fff')
1321
+ expect(uuid.split('-')[3]).toBe('8fff')
1245
1322
  }
1246
1323
 
1247
1324
  if (i === 4096) {
1248
- expect(uuid.split('-')[3]).to.equal('9000')
1325
+ expect(uuid.split('-')[3]).toBe('9000')
1249
1326
  }
1250
1327
 
1251
1328
  if (i === 9029) {
1252
- expect(uuid.split('-')[3]).to.equal('a345')
1329
+ expect(uuid.split('-')[3]).toBe('a345')
1253
1330
  }
1254
1331
 
1255
1332
  if (i === 13398) {
1256
- expect(uuid.split('-')[3]).to.equal('b456')
1333
+ expect(uuid.split('-')[3]).toBe('b456')
1257
1334
  }
1258
1335
 
1259
1336
  if (i === 16384) {
1260
- expect(uuid.split('-')[3]).to.equal('8000')
1337
+ expect(uuid.split('-')[3]).toBe('8000')
1261
1338
  }
1262
1339
 
1263
1340
  if (i === 17767) {
1264
- expect(uuid.split('-')[3]).to.equal('8567')
1341
+ expect(uuid.split('-')[3]).toBe('8567')
1265
1342
  }
1266
1343
  }
1344
+ ```
1267
1345
 
1346
+ ```ts
1268
1347
  expect(
1269
1348
  uuidV1(new Date(), '000123456789abc').split('-')[4]
1270
- ).to.equal('123456789abc')
1349
+ ).toBe('123456789abc')
1271
1350
 
1272
1351
  expect(
1273
1352
  uuidV1(new Date(), '123456789').split('-')[4]
1274
- ).to.equal('000123456789')
1353
+ ).toBe('000123456789')
1275
1354
 
1276
1355
  expect(
1277
1356
  uuidV1(new Date(323325000000)).startsWith(
1278
1357
  'c1399400-9a71-11bd'
1279
1358
  )
1280
- ).to.be.true
1359
+ ).toBe(true)
1281
1360
  ```
1282
1361
 
1283
1362
  ### vivify
@@ -1345,7 +1424,7 @@ const ref: any = {}
1345
1424
 
1346
1425
  vivify(ref).one.two[3][4]
1347
1426
 
1348
- expect(ref).to.deep.equal({
1427
+ expect(ref).toEqual({
1349
1428
  one: {
1350
1429
  two: [undefined, undefined, undefined, []],
1351
1430
  },
@@ -1353,7 +1432,7 @@ expect(ref).to.deep.equal({
1353
1432
 
1354
1433
  vivify(ref).one.two[3][4] = 5
1355
1434
 
1356
- expect(ref).to.deep.equal({
1435
+ expect(ref).toEqual({
1357
1436
  one: {
1358
1437
  two: [
1359
1438
  undefined,
@@ -1366,7 +1445,7 @@ expect(ref).to.deep.equal({
1366
1445
 
1367
1446
  vivify(ref).one.two[3].length = 1
1368
1447
 
1369
- expect(ref).to.deep.equal({
1448
+ expect(ref).toEqual({
1370
1449
  one: {
1371
1450
  two: [undefined, undefined, undefined, [undefined]],
1372
1451
  },
@@ -1374,15 +1453,15 @@ expect(ref).to.deep.equal({
1374
1453
 
1375
1454
  vivify(ref).one.two[3] = 4
1376
1455
 
1377
- expect(ref).to.deep.equal({
1456
+ expect(ref).toEqual({
1378
1457
  one: {
1379
1458
  two: [undefined, undefined, undefined, 4],
1380
1459
  },
1381
1460
  })
1382
1461
 
1383
- expect(vivify(ref).one.two.length).to.equal(4)
1462
+ expect(vivify(ref).one.two.length).toBe(4)
1384
1463
 
1385
- expect(ref).to.deep.equal({
1464
+ expect(ref).toEqual({
1386
1465
  one: {
1387
1466
  two: [undefined, undefined, undefined, 4],
1388
1467
  },
@@ -1390,60 +1469,63 @@ expect(ref).to.deep.equal({
1390
1469
 
1391
1470
  vivify(ref).one.two = 3
1392
1471
 
1393
- expect(ref).to.deep.equal({ one: { two: 3 } })
1472
+ expect(ref).toEqual({ one: { two: 3 } })
1394
1473
 
1395
1474
  vivify(ref).one.two = undefined
1396
1475
 
1397
- expect(ref).to.deep.equal({ one: { two: undefined } })
1476
+ expect(ref).toEqual({ one: { two: undefined } })
1398
1477
 
1399
1478
  delete vivify(ref).one.two
1400
1479
 
1401
- expect(ref).to.deep.equal({ one: {} })
1480
+ expect(ref).toEqual({ one: {} })
1402
1481
 
1403
- expect(vivify(ref).one.toString instanceof Function).to.be
1404
- .true
1482
+ expect(vivify(ref).one.toString instanceof Function).toBe(
1483
+ true
1484
+ )
1405
1485
 
1406
- expect(vivify(ref).one.toString.name).to.equal('toString')
1486
+ expect(vivify(ref).one.toString.name).toBe('toString')
1407
1487
 
1408
- expect(ref).to.deep.equal({ one: {} })
1488
+ expect(ref).toEqual({ one: {} })
1409
1489
 
1410
1490
  delete vivify(ref).one.two.three
1411
1491
 
1412
- expect(ref).to.deep.equal({ one: { two: {} } })
1492
+ expect(ref).toEqual({ one: { two: {} } })
1413
1493
 
1414
1494
  vivify(ref).one.two.three.four
1415
1495
 
1416
- expect(ref).to.deep.equal({ one: { two: { three: {} } } })
1496
+ expect(ref).toEqual({ one: { two: { three: {} } } })
1417
1497
 
1418
1498
  vivify(ref).one.two[3]
1419
1499
 
1420
- expect(ref).to.deep.equal({ one: { two: { three: {} } } })
1500
+ expect(ref).toEqual({ one: { two: { three: {} } } })
1421
1501
 
1422
1502
  vivify(ref).one.two.three.four = 5
1423
1503
 
1424
- expect(ref).to.deep.equal({
1504
+ expect(ref).toEqual({
1425
1505
  one: { two: { three: { four: 5 } } },
1426
1506
  })
1427
1507
 
1428
- expect(
1429
- vivify(ref).one.two.three.four.toString.name
1430
- ).to.equal('toString')
1508
+ expect(vivify(ref).one.two.three.four.toString.name).toBe(
1509
+ 'toString'
1510
+ )
1431
1511
 
1432
- expect(ref).to.deep.equal({
1512
+ expect(ref).toEqual({
1433
1513
  one: { two: { three: { four: 5 } } },
1434
1514
  })
1515
+ ```
1435
1516
 
1517
+ ```ts
1436
1518
  const u = undefined
1437
1519
 
1438
1520
  vivify(u).one.two = 3
1439
1521
 
1440
- expect(u).to.be.undefined
1522
+ expect(u).toBeUndefined()
1441
1523
 
1442
1524
  const n = null
1443
1525
 
1444
1526
  delete vivify(n).one.two.three
1445
1527
 
1446
- expect(n).to.be.null
1528
+ expect(n).toBeNull()
1447
1529
  ```
1448
1530
 
1449
1531
  ## License