@jackens/nnn 2024.4.15 → 2024.7.10

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.d.ts +2 -2
  2. package/package.json +1 -4
  3. package/readme.md +126 -149
package/nnn.d.ts CHANGED
@@ -167,12 +167,12 @@ export declare const nanolightJs: (code: string) => HArgs1[];
167
167
  /**
168
168
  * A helper that implements TypeScript’s `Pick` utility type.
169
169
  */
170
- export declare const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
170
+ export declare const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
171
171
 
172
172
  /**
173
173
  * A helper that implements TypeScript’s `Omit` utility type.
174
174
  */
175
- export declare const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
175
+ export declare const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
176
176
 
177
177
  /**
178
178
  * A helper for choosing the correct singular and plural.
package/package.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
2
  "author": "Jackens",
3
3
  "description": "Jackens’ JavaScript helpers.",
4
- "homepage": "https://jackens.github.io/nnn/doc/",
5
4
  "keywords": [
6
5
  "CSS-in-JS",
7
6
  "CSV",
8
7
  "csvParse",
9
8
  "DOM",
10
9
  "escape",
11
- "Gantt",
12
10
  "h",
13
11
  "has",
14
12
  "highlight",
@@ -25,7 +23,6 @@
25
23
  "nnn",
26
24
  "omit",
27
25
  "pick",
28
- "RWD",
29
26
  "SVG",
30
27
  "translation",
31
28
  "typography",
@@ -38,5 +35,5 @@
38
35
  "types": "nnn.d.ts",
39
36
  "name": "@jackens/nnn",
40
37
  "type": "module",
41
- "version": "2024.4.15"
38
+ "version": "2024.7.10"
42
39
  }
package/readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Jackens’ JavaScript helpers.
4
4
 
5
- <sub>Version: <code class="version">2024.4.15</code></sub>
5
+ <sub>Version: <code class="version">2024.7.10</code></sub>
6
6
 
7
7
  ## Installation
8
8
 
@@ -18,18 +18,22 @@ npm i @jackens/nnn
18
18
 
19
19
  ## Usage
20
20
 
21
- Bun (or Node.js):
22
-
23
21
  ```js
24
22
  import { «something» } from '@jackens/nnn'
25
23
  ```
26
24
 
27
- The browser (or Bun or Node.js):
25
+ or:
28
26
 
29
27
  ```js
30
28
  import { «something» } from './node_modules/@jackens/nnn/nnn.js'
31
29
  ```
32
30
 
31
+ or:
32
+
33
+ ```js
34
+ import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.7.10/nnn.js'
35
+ ```
36
+
33
37
  ## Exports
34
38
 
35
39
  - `EscapeMap`: The type of arguments of the `escapeValues` and `escape` helpers.
@@ -80,8 +84,6 @@ The type of arguments of the `h` and `s` helpers.
80
84
  type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined | Node | string | number | HArgs;
81
85
  ```
82
86
 
83
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Record>` instead of `Record`.
84
-
85
87
  The type of arguments of the `h` and `s` helpers.
86
88
 
87
89
  ### JcNode
@@ -100,8 +102,6 @@ The type of arguments of the `jc` helper.
100
102
  type JcRoot = Partial<Record<PropertyKey, JcNode>>;
101
103
  ```
102
104
 
103
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Record>` instead of `Record`.
104
-
105
105
  The type of arguments of the `jc` helper.
106
106
 
107
107
  ### csvParse
@@ -113,8 +113,6 @@ const csvParse: (text: string, { header, separator }?: {
113
113
  }) => Partial<Array<Partial<Record<PropertyKey, string>>>> | Partial<Array<Partial<Array<string>>>>;
114
114
  ```
115
115
 
116
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>`/`Partial<Record>` instead of `Array`/`Record`.
117
-
118
116
  A tiny helper for CSV parsing.
119
117
 
120
118
  Options:
@@ -132,13 +130,13 @@ yyy",zzz
132
130
  42 , "42" , 17
133
131
 
134
132
  `
135
- expect(csvParse(text, { header: false })).toStrictEqual([
133
+ expect(csvParse(text, { header: false })).to.deep.equal([
136
134
  ['aaa\n"aaa"\naaa', 'bbb', 'ccc,ccc'],
137
135
  ['xxx,xxx', 'yyy\nyyy', 'zzz'],
138
136
  [' 42 ', '42', ' 17']
139
137
  ])
140
138
 
141
- expect(csvParse(text)).toStrictEqual([{
139
+ expect(csvParse(text)).to.deep.equal([{
142
140
  'aaa\n"aaa"\naaa': 'xxx,xxx',
143
141
  bbb: 'yyy\nyyy',
144
142
  'ccc,ccc': 'zzz'
@@ -155,20 +153,18 @@ expect(csvParse(text)).toStrictEqual([{
155
153
  const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<unknown>>) => string;
156
154
  ```
157
155
 
158
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
159
-
160
156
  A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
161
157
 
162
158
  #### Usage Examples
163
159
 
164
160
  ```js
165
- const escapeMap: EscapeMap = new Map([
161
+ const /** @type {import('../dist/nnn.js').EscapeMap} */ escapeMap = new Map([
166
162
  [undefined, () => 'NULL'],
167
- [Array, (values: Partial<Array<unknown>>) => escapeValues(escapeMap, values).join(', ')],
168
- [Boolean, (value: boolean) => `b'${+value}'`],
169
- [Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
170
- [Number, (value: number) => `${value}`],
171
- [String, (value: string) => `'${value.replace(/'/g, "''")}'`]
163
+ [Array, (/** @type {Partial<Array<unknown>>} */ values) => escapeValues(escapeMap, values).join(', ')],
164
+ [Boolean, (/** @type {boolean} */ value) => `b'${+value}'`],
165
+ [Date, (/** @type {Date} */ value) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
166
+ [Number, (/** @type {number} */ value) => `${value}`],
167
+ [String, (/** @type {string} */ value) => `'${value.replace(/'/g, "''")}'`]
172
168
  ])
173
169
 
174
170
  const sql = escape.bind(null, escapeMap)
@@ -183,7 +179,7 @@ const expected = `
183
179
  FROM table_name
184
180
  WHERE column_name IN (b'1', NULL, NULL, 42, '42', '4''2', NULL, '1980-03-31 04:30:00')`
185
181
 
186
- expect(actual).toStrictEqual(expected)
182
+ expect(actual).to.deep.equal(expected)
187
183
  ```
188
184
 
189
185
  ### escapeValues
@@ -192,8 +188,6 @@ expect(actual).toStrictEqual(expected)
192
188
  const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<unknown>>) => Partial<Array<string>>;
193
189
  ```
194
190
 
195
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
196
-
197
191
  A generic helper for escaping `values` by given `escapeMap`.
198
192
 
199
193
  ### fixTypography
@@ -211,7 +205,7 @@ const p = h('p', 'Pchnąć w tę łódź jeża lub ośm skrzyń fig (zob. https:
211
205
 
212
206
  fixTypography(p)
213
207
 
214
- expect(p.innerHTML).toStrictEqual(
208
+ expect(p.innerHTML).to.deep.equal(
215
209
  'Pchnąć <span style="white-space:nowrap">w </span>tę łódź jeża lub ośm skrzyń fig ' +
216
210
  '(zob. https://\u200Bpl.\u200Bwikipedia.\u200Borg/\u200Bwiki/\u200BPangram).')
217
211
  ```
@@ -226,8 +220,6 @@ const h: {
226
220
  };
227
221
  ```
228
222
 
229
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
230
-
231
223
  A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
232
224
 
233
225
  - The first argument of type `string` specifies the tag of the element to be created.
@@ -247,67 +239,67 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
247
239
  ```js
248
240
  const b = h('b')
249
241
 
250
- expect(b.outerHTML).toStrictEqual('<b></b>')
242
+ expect(b.outerHTML).to.deep.equal('<b></b>')
251
243
 
252
244
  const i = h('i', 'text')
253
245
 
254
246
  h(b, i)
255
247
 
256
- expect(i.outerHTML).toStrictEqual('<i>text</i>')
257
- expect(b.outerHTML).toStrictEqual('<b><i>text</i></b>')
248
+ expect(i.outerHTML).to.deep.equal('<i>text</i>')
249
+ expect(b.outerHTML).to.deep.equal('<b><i>text</i></b>')
258
250
 
259
251
  h(i, { $className: 'some class' })
260
252
 
261
- expect(i.outerHTML).toStrictEqual('<i class="some class">text</i>')
262
- expect(b.outerHTML).toStrictEqual('<b><i class="some class">text</i></b>')
253
+ expect(i.outerHTML).to.deep.equal('<i class="some class">text</i>')
254
+ expect(b.outerHTML).to.deep.equal('<b><i class="some class">text</i></b>')
263
255
  ```
264
256
 
265
257
  ```js
266
- expect(h('span', 'text').outerHTML).toStrictEqual('<span>text</span>')
267
- expect(h('span', { $innerText: 'text' }).outerHTML).toStrictEqual('<span>text</span>')
258
+ expect(h('span', 'text').outerHTML).to.deep.equal('<span>text</span>')
259
+ expect(h('span', { $innerText: 'text' }).outerHTML).to.deep.equal('<span>text</span>')
268
260
  ```
269
261
 
270
262
  ```js
271
263
  expect(h('div', { style: 'margin:0;padding:0' }).outerHTML)
272
- .toStrictEqual('<div style="margin:0;padding:0"></div>')
264
+ .to.deep.equal('<div style="margin:0;padding:0"></div>')
273
265
  expect(h('div', { $style: 'margin:0;padding:0' }).outerHTML)
274
- .toStrictEqual('<div style="margin: 0px; padding: 0px;"></div>')
266
+ .to.deep.equal('<div style="margin: 0px; padding: 0px;"></div>')
275
267
  expect(h('div', { $style: { margin: 0, padding: 0 } }).outerHTML)
276
- .toStrictEqual('<div style="margin: 0px; padding: 0px;"></div>')
268
+ .to.deep.equal('<div style="margin: 0px; padding: 0px;"></div>')
277
269
  ```
278
270
 
279
271
  ```js
280
272
  const input1 = h('input', { value: 42 })
281
273
  const input2 = h('input', { $value: '42' })
282
274
 
283
- expect(input1.value).toStrictEqual('42')
284
- expect(input2.value).toStrictEqual('42')
275
+ expect(input1.value).to.deep.equal('42')
276
+ expect(input2.value).to.deep.equal('42')
285
277
 
286
- expect(input1.outerHTML).toStrictEqual('<input value="42">')
287
- expect(input2.outerHTML).toStrictEqual('<input>')
278
+ expect(input1.outerHTML).to.deep.equal('<input value="42">')
279
+ expect(input2.outerHTML).to.deep.equal('<input>')
288
280
 
289
281
  const checkbox1 = h('input', { type: 'checkbox', checked: true })
290
282
  const checkbox2 = h('input', { type: 'checkbox', $checked: true })
291
283
 
292
- expect(checkbox1.checked).toBeTrue()
293
- expect(checkbox2.checked).toBeTrue()
284
+ expect(checkbox1.checked).to.be.true
285
+ expect(checkbox2.checked).to.be.true
294
286
 
295
- expect(checkbox1.outerHTML).toStrictEqual('<input type="checkbox" checked="">')
296
- expect(checkbox2.outerHTML).toStrictEqual('<input type="checkbox">')
287
+ expect(checkbox1.outerHTML).to.deep.equal('<input type="checkbox" checked="">')
288
+ expect(checkbox2.outerHTML).to.deep.equal('<input type="checkbox">')
297
289
  ```
298
290
 
299
291
  ```js
300
292
  const div = h('div')
301
293
 
302
- expect(div.key).toBeUndefined()
294
+ expect(div.key).to.be.undefined
303
295
 
304
296
  h(div, { $key: { one: 1 } })
305
297
 
306
- expect(div.key).toStrictEqual({ one: 1 })
298
+ expect(div.key).to.deep.equal({ one: 1 })
307
299
 
308
300
  h(div, { $key: { two: 2 } })
309
301
 
310
- expect(div.key).toStrictEqual({ one: 1, two: 2 })
302
+ expect(div.key).to.deep.equal({ one: 1, two: 2 })
311
303
  ```
312
304
 
313
305
  ### has
@@ -323,17 +315,17 @@ A replacement for the `in` operator (not to be confused with the `for-in` loop)
323
315
  ```js
324
316
  const obj = { key: 'K', null: 'N' }
325
317
 
326
- expect('key' in obj).toBeTrue()
327
- expect(has('key', obj)).toBeTrue()
318
+ expect('key' in obj).to.be.true
319
+ expect(has('key', obj)).to.be.true
328
320
 
329
- expect('null' in obj).toBeTrue()
330
- expect(has('null', obj)).toBeTrue()
321
+ expect('null' in obj).to.be.true
322
+ expect(has('null', obj)).to.be.true
331
323
 
332
- expect(null in obj).toBeTrue()
333
- expect(has(null, obj)).toBeFalse()
324
+ expect(null in obj).to.be.true
325
+ expect(has(null, obj)).to.be.false
334
326
 
335
- expect('toString' in obj).toBeTrue()
336
- expect(has('toString', obj)).toBeFalse()
327
+ expect('toString' in obj).to.be.true
328
+ expect(has('toString', obj)).to.be.false
337
329
  ```
338
330
 
339
331
  ```js
@@ -346,7 +338,7 @@ try {
346
338
  }
347
339
 
348
340
  expect(typeError instanceof TypeError) // Cannot use 'in' operator to search for 'key' in null
349
- expect(has('key', null)).toBeFalse()
341
+ expect(has('key', null)).to.be.false
350
342
  ```
351
343
 
352
344
  ### is
@@ -365,65 +357,66 @@ const is: {
365
357
  };
366
358
  ```
367
359
 
368
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>`/`Partial<Record>` instead of `Array`/`Record`.
369
-
370
360
  A helper that checks if the given argument is of a certain type.
371
361
 
372
362
  #### Usage Examples
373
363
 
374
364
  ```js
375
- expect(is(Number, 42)).toBeTrue()
376
- expect(is(Number, Number(42))).toBeTrue()
377
- expect(is(Number, new Number(42))).toBeTrue()
378
- expect(is(Number, NaN)).toBeTrue()
379
- expect(is(String, '42')).toBeTrue()
380
- expect(is(String, String('42'))).toBeTrue()
381
- expect(is(String, new String('42'))).toBeTrue()
382
- expect(is(Symbol, Symbol('42'))).toBeTrue()
383
- expect(is(Symbol, Object(Symbol('42')))).toBeTrue()
384
- expect(is(undefined, undefined)).toBeTrue()
385
- expect(is(undefined, null)).toBeTrue()
386
- expect(is(Object, {})).toBeTrue()
387
- expect(is(Array, [])).toBeTrue()
388
- expect(is(RegExp, /42/)).toBeTrue()
389
- expect(is(Date, new Date(42))).toBeTrue()
390
- expect(is(Set, new Set(['42', 42]))).toBeTrue()
391
- expect(is(Map, new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]))).toBeTrue()
365
+ expect(is(Number, 42)).to.be.true
366
+ expect(is(Number, Number(42))).to.be.true
367
+
368
+ expect(is(Number, new Number(42))).to.be.true
369
+ expect(is(Number, NaN)).to.be.true
370
+ expect(is(String, '42')).to.be.true
371
+ expect(is(String, String('42'))).to.be.true
372
+
373
+ expect(is(String, new String('42'))).to.be.true
374
+ expect(is(Symbol, Symbol('42'))).to.be.true
375
+ expect(is(Symbol, Object(Symbol('42')))).to.be.true
376
+ expect(is(undefined, undefined)).to.be.true
377
+ expect(is(undefined, null)).to.be.true
378
+ expect(is(Object, {})).to.be.true
379
+ expect(is(Array, [])).to.be.true
380
+ expect(is(RegExp, /42/)).to.be.true
381
+ expect(is(Date, new Date(42))).to.be.true
382
+ expect(is(Set, new Set(['42', 42]))).to.be.true
383
+ expect(is(Map, new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]))).to.be.true
392
384
  ```
393
385
 
394
386
  ```js
395
- const iz = (type: unknown, arg: unknown) => ({}).toString.call(arg).slice(8, -1) === type?.name
387
+ const iz = (/** @type {unknown} */ type, /** @type {unknown} */ arg) =>
388
+ ({}).toString.call(arg).slice(8, -1) === type?.name
396
389
 
397
390
  class FooBar { }
398
391
 
399
- expect(is(FooBar, new FooBar())).toBeTrue()
400
- expect(iz(FooBar, new FooBar())).toBeFalse()
392
+ expect(is(FooBar, new FooBar())).to.be.true
393
+ expect(iz(FooBar, new FooBar())).to.be.false
401
394
 
402
- expect(is(Object, new FooBar())).toBeFalse()
403
- expect(iz(Object, new FooBar())).toBeTrue()
395
+ expect(is(Object, new FooBar())).to.be.false
396
+ expect(iz(Object, new FooBar())).to.be.true
404
397
 
405
398
  const fakeFooBar = {}
406
399
 
407
400
  fakeFooBar[Symbol.toStringTag] = FooBar.name
408
401
 
409
- expect(is(FooBar, fakeFooBar)).toBeFalse()
410
- expect(iz(FooBar, fakeFooBar)).toBeTrue()
402
+ expect(is(FooBar, fakeFooBar)).to.be.false
403
+ expect(iz(FooBar, fakeFooBar)).to.be.true
411
404
 
412
- expect(is(Object, fakeFooBar)).toBeTrue()
413
- expect(iz(Object, fakeFooBar)).toBeFalse()
405
+ expect(is(Object, fakeFooBar)).to.be.true
406
+ expect(iz(Object, fakeFooBar)).to.be.false
414
407
  ```
415
408
 
416
409
  ```js
417
410
  const num = 42
418
411
  const str = '42'
419
412
 
420
- expect(is(Number, num)).toBeTrue()
413
+ expect(is(Number, num)).to.be.true
421
414
 
422
415
  try {
423
416
  num.constructor = str.constructor
424
417
  } catch { /* empty */ }
425
418
 
426
- expect(is(Number, num)).toBeTrue()
419
+ expect(is(Number, num)).to.be.true
427
420
  ```
428
421
 
429
422
  ### jc
@@ -467,7 +460,7 @@ a{
467
460
  padding:1
468
461
  }`.replace(/\n\s*/g, '')
469
462
 
470
- expect(actual).toStrictEqual(expected)
463
+ expect(actual).to.deep.equal(expected)
471
464
  ```
472
465
 
473
466
  ```js
@@ -495,7 +488,7 @@ a.b{
495
488
  padding:1
496
489
  }`.replace(/\n\s*/g, '')
497
490
 
498
- expect(actual).toStrictEqual(expected)
491
+ expect(actual).to.deep.equal(expected)
499
492
  ```
500
493
 
501
494
  ```js
@@ -570,7 +563,7 @@ div.c2{
570
563
  }
571
564
  }`.replace(/\n\s*/g, '')
572
565
 
573
- expect(actual).toStrictEqual(expected)
566
+ expect(actual).to.deep.equal(expected)
574
567
  ```
575
568
 
576
569
  ```js
@@ -593,7 +586,7 @@ a.b.d,a.c.d{
593
586
  margin:2
594
587
  }`.replace(/\n\s*/g, '')
595
588
 
596
- expect(actual).toStrictEqual(expected)
589
+ expect(actual).to.deep.equal(expected)
597
590
  ```
598
591
 
599
592
  ```js
@@ -614,7 +607,7 @@ const expected = `
614
607
  margin:2
615
608
  }`.replace(/\n\s*/g, '')
616
609
 
617
- expect(actual).toStrictEqual(expected)
610
+ expect(actual).to.deep.equal(expected)
618
611
  ```
619
612
 
620
613
  ```js
@@ -635,7 +628,7 @@ const expected = `
635
628
  margin:2
636
629
  }`.replace(/\n\s*/g, '')
637
630
 
638
- expect(actual).toStrictEqual(expected)
631
+ expect(actual).to.deep.equal(expected)
639
632
  ```
640
633
 
641
634
  ### jsOnParse
@@ -644,8 +637,6 @@ expect(actual).toStrictEqual(expected)
644
637
  const jsOnParse: (handlers: Partial<Record<PropertyKey, Function>>, text: string) => any;
645
638
  ```
646
639
 
647
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Record>` instead of `Record`.
648
-
649
640
  `JSON.parse` with “JavaScript turned on”.
650
641
 
651
642
  Objects having *exactly* one property which is present in the `handlers` map, i.e. objects of the form:
@@ -664,7 +655,7 @@ handlers['«handlerName»'](...«params»)
664
655
 
665
656
  ```js
666
657
  const handlers = {
667
- $hello: (name: string) => `Hello ${name}!`,
658
+ $hello: (/** @type {string} */ name) => `Hello ${name}!`,
668
659
  $foo: () => 'bar'
669
660
  }
670
661
 
@@ -704,7 +695,7 @@ const expected = [
704
695
  }
705
696
  ]
706
697
 
707
- expect(actual).toStrictEqual(expected)
698
+ expect(actual).to.deep.equal(expected)
708
699
  ```
709
700
 
710
701
  ### locale
@@ -713,8 +704,6 @@ expect(actual).toStrictEqual(expected)
713
704
  const locale: (map: Partial<Record<PropertyKey, Partial<Record<PropertyKey, string>>>>, defaultVersion: string) => (text: string, version?: string) => string;
714
705
  ```
715
706
 
716
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Record>` instead of `Record`.
717
-
718
707
  Language translations helper.
719
708
 
720
709
  #### Usage Examples
@@ -725,18 +714,18 @@ const _ = locale({
725
714
  button: { Login: 'Zaloguj' }
726
715
  }, 'default')
727
716
 
728
- expect(_('Login')).toStrictEqual('Login')
729
- expect(_('Password')).toStrictEqual('Hasło')
717
+ expect(_('Login')).to.deep.equal('Login')
718
+ expect(_('Password')).to.deep.equal('Hasło')
730
719
 
731
- expect(_('Undefined text')).toStrictEqual('Undefined text')
720
+ expect(_('Undefined text')).to.deep.equal('Undefined text')
732
721
 
733
- expect(_('Login', 'button')).toStrictEqual('Zaloguj')
722
+ expect(_('Login', 'button')).to.deep.equal('Zaloguj')
734
723
 
735
- expect(_('Password', 'undefined_version')).toStrictEqual('Hasło')
736
- expect(_('Undefined text', 'undefined_version')).toStrictEqual('Undefined text')
724
+ expect(_('Password', 'undefined_version')).to.deep.equal('Hasło')
725
+ expect(_('Undefined text', 'undefined_version')).to.deep.equal('Undefined text')
737
726
 
738
- expect(_('toString')).toStrictEqual('toString')
739
- expect(_('toString', 'undefined_version')).toStrictEqual('toString')
727
+ expect(_('toString')).to.deep.equal('toString')
728
+ expect(_('toString', 'undefined_version')).to.deep.equal('toString')
740
729
  ```
741
730
 
742
731
  ### nanolight
@@ -745,8 +734,6 @@ expect(_('toString', 'undefined_version')).toStrictEqual('toString')
745
734
  const nanolight: (pattern: RegExp, highlighters: Partial<Array<(chunk: string, index: number) => HArgs1>>, code: string) => HArgs1[];
746
735
  ```
747
736
 
748
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
749
-
750
737
  A generic helper for syntax highlighting (see also `nanolightJs`).
751
738
 
752
739
  ### nanolightJs
@@ -762,7 +749,7 @@ A helper for highlighting JavaScript.
762
749
  ```js
763
750
  const codeJs = 'const answerToLifeTheUniverseAndEverything = 42'
764
751
 
765
- expect(nanolightJs(codeJs)).toStrictEqual([
752
+ expect(nanolightJs(codeJs)).to.deep.equal([
766
753
  ['span', { class: 'keyword' }, 'const'],
767
754
  ' ',
768
755
  ['span', { class: 'literal' }, 'answerToLifeTheUniverseAndEverything'],
@@ -776,11 +763,9 @@ expect(nanolightJs(codeJs)).toStrictEqual([
776
763
  ### omit
777
764
 
778
765
  ```ts
779
- const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
766
+ const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
780
767
  ```
781
768
 
782
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>`/`Partial<Record>` instead of `Array`/`Record`.
783
-
784
769
  A helper that implements TypeScript’s `Omit` utility type.
785
770
 
786
771
  #### Usage Examples
@@ -788,17 +773,15 @@ A helper that implements TypeScript’s `Omit` utility type.
788
773
  ```js
789
774
  const obj = { a: 42, b: '42', c: 17 }
790
775
 
791
- expect(omit(obj, ['c'])).toStrictEqual({ a: 42, b: '42' })
776
+ expect(omit(obj, ['c'])).to.deep.equal({ a: 42, b: '42' })
792
777
  ```
793
778
 
794
779
  ### pick
795
780
 
796
781
  ```ts
797
- const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
782
+ const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
798
783
  ```
799
784
 
800
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>`/`Partial<Record>` instead of `Array`/`Record`.
801
-
802
785
  A helper that implements TypeScript’s `Pick` utility type.
803
786
 
804
787
  #### Usage Examples
@@ -806,7 +789,7 @@ A helper that implements TypeScript’s `Pick` utility type.
806
789
  ```js
807
790
  const obj = { a: 42, b: '42', c: 17 }
808
791
 
809
- expect(pick(obj, ['a', 'b'])).toStrictEqual({ a: 42, b: '42' })
792
+ expect(pick(obj, ['a', 'b'])).to.deep.equal({ a: 42, b: '42' })
810
793
  ```
811
794
 
812
795
  ### plUral
@@ -822,17 +805,17 @@ A helper for choosing the correct singular and plural.
822
805
  ```js
823
806
  const auto = plUral.bind(null, 'auto', 'auta', 'aut')
824
807
 
825
- expect(auto(0)).toStrictEqual('aut')
826
- expect(auto(1)).toStrictEqual('auto')
827
- expect(auto(17)).toStrictEqual('aut')
828
- expect(auto(42)).toStrictEqual('auta')
808
+ expect(auto(0)).to.deep.equal('aut')
809
+ expect(auto(1)).to.deep.equal('auto')
810
+ expect(auto(17)).to.deep.equal('aut')
811
+ expect(auto(42)).to.deep.equal('auta')
829
812
 
830
813
  const car = plUral.bind(null, 'car', 'cars', 'cars')
831
814
 
832
- expect(car(0)).toStrictEqual('cars')
833
- expect(car(1)).toStrictEqual('car')
834
- expect(car(17)).toStrictEqual('cars')
835
- expect(car(42)).toStrictEqual('cars')
815
+ expect(car(0)).to.deep.equal('cars')
816
+ expect(car(1)).to.deep.equal('car')
817
+ expect(car(17)).to.deep.equal('cars')
818
+ expect(car(42)).to.deep.equal('cars')
836
819
  ```
837
820
 
838
821
  ### pro
@@ -850,27 +833,27 @@ const ref = {}
850
833
 
851
834
  pro(ref).one.two[3][4] = 1234
852
835
 
853
- expect(ref).toStrictEqual({ one: { two: { 3: { 4: 1234 } } } })
836
+ expect(ref).to.deep.equal({ one: { two: { 3: { 4: 1234 } } } })
854
837
 
855
838
  pro(ref).one.two.tree = 123
856
839
 
857
- expect(ref).toStrictEqual({ one: { two: { 3: { 4: 1234 }, tree: 123 } } })
840
+ expect(ref).to.deep.equal({ one: { two: { 3: { 4: 1234 }, tree: 123 } } })
858
841
 
859
842
  pro(ref).one.two = undefined
860
843
 
861
- expect(ref).toStrictEqual({ one: { two: undefined } })
844
+ expect(ref).to.deep.equal({ one: { two: undefined } })
862
845
 
863
846
  delete pro(ref).one.two
864
847
 
865
- expect(ref).toStrictEqual({ one: {} })
848
+ expect(ref).to.deep.equal({ one: {} })
866
849
 
867
850
  pro(ref).one.two.three.four
868
851
 
869
- expect(ref).toStrictEqual({ one: { two: { three: { four: {} } } } })
852
+ expect(ref).to.deep.equal({ one: { two: { three: { four: {} } } } })
870
853
 
871
854
  pro(ref).one.two.three.four = 1234
872
855
 
873
- expect(ref).toStrictEqual({ one: { two: { three: { four: 1234 } } } })
856
+ expect(ref).to.deep.equal({ one: { two: { three: { four: 1234 } } } })
874
857
  ```
875
858
 
876
859
  ### refsInfo
@@ -879,8 +862,6 @@ expect(ref).toStrictEqual({ one: { two: { three: { four: 1234 } } } })
879
862
  const refsInfo: (...refs: Partial<Array<unknown>>) => Partial<Array<[string, string, Partial<Array<string>>]>>;
880
863
  ```
881
864
 
882
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
883
-
884
865
  A helper that provides information about the given `refs`.
885
866
 
886
867
  It returns an array of triples: `[«name», «prototype-name», «array-of-own-property-names»]`.
@@ -890,8 +871,8 @@ It returns an array of triples: `[«name», «prototype-name», «array-of-own-p
890
871
  ```js
891
872
  const info = refsInfo(Array, Function)
892
873
 
893
- expect(info.find(item => item?.[0] === 'Array')?.[2]?.includes('length')).toBeTrue()
894
- expect(info.find(item => item?.[0] === 'Function')?.[2]?.includes('length')).toBeTrue()
874
+ expect(info.find(item => item?.[0] === 'Array')?.[2]?.includes('length')).to.be.true
875
+ expect(info.find(item => item?.[0] === 'Function')?.[2]?.includes('length')).to.be.true
895
876
  ```
896
877
 
897
878
  ```js
@@ -928,8 +909,6 @@ const s: {
928
909
  };
929
910
  ```
930
911
 
931
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
932
-
933
912
  A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
934
913
 
935
914
  - The first argument of type `string` specifies the tag of the element to be created.
@@ -950,8 +929,6 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
950
929
  const svgUse: (id: string, ...args: Partial<Array<HArgs1>>) => SVGSVGElement;
951
930
  ```
952
931
 
953
- > See [here](https://jackens.github.io/nnn/doc/#Why-Partial-Array-and-Partial-Record) for an explanation of why `Partial<Array>` instead of `Array`.
954
-
955
932
  A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
956
933
 
957
934
  ### uuid1
@@ -974,23 +951,23 @@ A helper that generates a UUID v1 identifier (with a creation timestamp).
974
951
  for (let i = 1; i <= 22136; ++i) {
975
952
  const uuid = uuid1()
976
953
 
977
- i === 1 && expect(uuid.split('-')[3]).toStrictEqual('8001')
978
- i === 4095 && expect(uuid.split('-')[3]).toStrictEqual('8fff')
979
- i === 4096 && expect(uuid.split('-')[3]).toStrictEqual('9000')
980
- i === 9029 && expect(uuid.split('-')[3]).toStrictEqual('a345')
981
- i === 13398 && expect(uuid.split('-')[3]).toStrictEqual('b456')
982
- i === 16384 && expect(uuid.split('-')[3]).toStrictEqual('8000')
983
- i === 17767 && expect(uuid.split('-')[3]).toStrictEqual('8567')
954
+ i === 1 && expect(uuid.split('-')[3]).to.deep.equal('8001')
955
+ i === 4095 && expect(uuid.split('-')[3]).to.deep.equal('8fff')
956
+ i === 4096 && expect(uuid.split('-')[3]).to.deep.equal('9000')
957
+ i === 9029 && expect(uuid.split('-')[3]).to.deep.equal('a345')
958
+ i === 13398 && expect(uuid.split('-')[3]).to.deep.equal('b456')
959
+ i === 16384 && expect(uuid.split('-')[3]).to.deep.equal('8000')
960
+ i === 17767 && expect(uuid.split('-')[3]).to.deep.equal('8567')
984
961
  }
985
962
  ```
986
963
 
987
964
  ```js
988
- expect(uuid1({ node: '000123456789abc' }).split('-')[4]).toStrictEqual('123456789abc')
989
- expect(uuid1({ node: '123456789' }).split('-')[4]).toStrictEqual('000123456789')
965
+ expect(uuid1({ node: '000123456789abc' }).split('-')[4]).to.deep.equal('123456789abc')
966
+ expect(uuid1({ node: '123456789' }).split('-')[4]).to.deep.equal('000123456789')
990
967
  ```
991
968
 
992
969
  ```js
993
- expect(uuid1({ date: new Date(323325000000) }).startsWith('c1399400-9a71-11bd')).toBeTrue()
970
+ expect(uuid1({ date: new Date(323325000000) }).startsWith('c1399400-9a71-11bd')).to.be.true
994
971
  ```
995
972
 
996
973
  ## Why Partial\<Array\> and Partial\<Record\>