@gershy/clearing 0.0.30 → 0.0.32

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/readme.md CHANGED
@@ -15,7 +15,7 @@ The clearing module gives you all the features any sane person would want to see
15
15
  ## Basic bootstrapping
16
16
 
17
17
  Clearing uses an unorthodox (controversial??) technique to achieve a lot of convenience.
18
- Functionality is added by extending native classes and prototypes with _non-enumerable_, _Symbol_ properties like so:
18
+ Functionality is added by extending native classes and prototypes with _non-enumerable_, _Symbol_ properties comparable to the following:
19
19
 
20
20
  ```ts
21
21
  const coolNewHelper = Symbol();
@@ -28,22 +28,23 @@ console.log(obj[coolNewHelper]());
28
28
  ```
29
29
 
30
30
  Extending native classes and prototypes is kind of crazy, but only doing so with non-enumerable,
31
- Symbol properties maintains compatibility with the vast majority of npm modules. Oh there's one
32
- more thing - the symbols used to extend functionality are set in the global scope, so they are
33
- always globally available.
31
+ Symbol properties maintains compatibility with the vast majority of npm modules. All symbols are
32
+ accessible via the `clearing` (or `cl`) global object.
34
33
 
35
- ## Exported helpers
36
-
37
- In addition to prototype extensions, this module exports several utility helpers for direct import:
34
+ Simply import the clearing module to make all functionality globally available:
38
35
 
39
36
  ```ts
40
- import { isCls, inCls, getClsName, getCls, skip, then, safe } from '@gershy/clearing';
37
+ import '@gershy/clearing';
41
38
  ```
42
39
 
43
- ### `isCls(value, Constructor)`
40
+ ## Utility functions
41
+
42
+ ### `clearing.isCls(value, Constructor)`
44
43
  Type guard for strict class/constructor matching. Handles primitives, null, undefined, and NaN correctly.
45
44
 
46
45
  ```ts
46
+ const { isCls } = clearing;
47
+
47
48
  isCls(5, Number); // true
48
49
  isCls(5, NaN); // false
49
50
  isCls(5, String); // false
@@ -58,20 +59,24 @@ isCls([], Array); // true
58
59
  isCls(new Map(), Map); // true
59
60
  ```
60
61
 
61
- ### `inCls(value, Constructor)`
62
+ ### `clearing.inCls(value, Constructor)`
62
63
  Type guard for `instanceof` checks (including inheritance).
63
64
 
64
65
  ```ts
66
+ const { inCls } = clearing;
67
+
65
68
  inCls([], Array); // true
66
69
  inCls(new (class X extends Array {})(), Array); // true
67
70
  inCls({}, Object); // true
68
71
  inCls(5, Number); // false (primitives are not instanceof)
69
72
  ```
70
73
 
71
- ### `getClsName(value)`
74
+ ### `clearing.getClsName(value)`
72
75
  Returns the class/constructor name of a value, or special names for null/undefined/NaN.
73
76
 
74
77
  ```ts
78
+ const { getClsName } = clearing;
79
+
75
80
  getClsName(5); // 'Number'
76
81
  getClsName('abc'); // 'String'
77
82
  getClsName(null); // 'Null'
@@ -81,94 +86,138 @@ getClsName({}); // 'Object'
81
86
  getClsName(Object.create(null)); // 'Prototypeless'
82
87
  ```
83
88
 
84
- ### `getCls(value)`
89
+ ### `clearing.getCls(value)`
85
90
  Returns the constructor function of a value, or null if not available.
86
91
 
87
92
  ```ts
88
- getCls(5); // Number
89
- getCls('abc'); // String
90
- getCls(null); // null
91
- getCls(undefined); // null
92
- getCls({}); // Object
93
+ const { getCls } = clearing;
94
+
95
+ getCls(5); // Number
96
+ getCls('abc'); // String
97
+ getCls(null); // null
98
+ getCls(undefined); // null
99
+ getCls({}); // Object
93
100
  getCls(Object.create(null)); // null
94
101
  ```
95
102
 
96
- ### `skip`
97
- Special exported value (undefined) used to signal omission in mapping helpers.
103
+ ### `clearing.skip`
104
+ Special value (undefined) used to signal omission in mapping helpers.
98
105
 
99
106
  ```ts
100
- import { skip } from '@gershy/clearing';
107
+ const { skip } = clearing;
108
+
101
109
  [1, 2, 3].map(v => v > 1 ? v : skip); // [skip, 2, 3]
102
110
  ```
103
111
 
104
- ### `then(value, onFulfilled?, onRejected?)`
112
+ ### `clearing.then(value, onFulfilled?, onRejected?)`
105
113
  Unified handler for both Promise and non-Promise values. Applies `onFulfilled`/`onRejected` as appropriate.
106
114
 
107
115
  ```ts
116
+ const { then } = clearing;
117
+
108
118
  then(Promise.resolve(5), v => v * 2); // Promise resolving to 10
109
119
  then(5, v => v * 2); // 10
110
120
  then(Promise.reject('fail'), undefined, e => 'fallback'); // Promise resolving to 'fallback'
111
121
  ```
112
122
 
113
- ### `safe(fn, onRejected?)`
123
+ ### `clearing.safe(fn, onRejected?)`
114
124
  Runs a function (sync or async), catching errors and returning a Promise. Optionally handles errors with `onRejected`.
115
125
 
116
126
  ```ts
127
+ const { safe } = clearing;
128
+
117
129
  await safe(() => JSON.parse('{ bad }'), e => 'fallback'); // 'fallback'
118
130
  await safe(async () => await fetch('bad-url'), e => null); // null if fetch throws
119
131
  ```
120
132
 
133
+ ## Prototype extensions
134
+
135
+ Along with utility functions, `@gershy/clearing` adds functionality to native prototypes, keyed by symbols, and exposes those symbols via the `clearing` (or `cl`) globals. These symbols are `unique symbols`, in typescript terms. Note that `unique symbol` is widened only to `symbol` on assignment-to-property-reference:
136
+
137
+ ```ts
138
+ clearing.map; // Typescript knows this is `unique symbol`
139
+
140
+ const symbol = clearing.map;
141
+ symbol; // Typescript thinks this is a regular `symbol`! Ouch.
142
+ ```
143
+
144
+ In order to gain the sophisticated typing provided by clearing, you must preserve the `unique symbol` typing of all `@gershy/clearing` symbols. My greatest apology to `@gershy/clearing` users it the lack of a succinct way to reference a bunch of symbols at once, while retaining strong typing. For example, the most intuitive way to reference a batch of symbols - via destructuring - is *the easiest way to lose your typing*:
145
+
146
+ ```ts
147
+ const { map, toArr, toObj } = clearing; // Typescript thinks these are regular `symbol`s
148
+ { a: 1, b: 2 }[map](v => v * 3); // Typescript thinks this is `any` - very sad!
149
+ ```
150
+
151
+ To preserve your typing you can:
152
+
153
+ 1. Reference directly from the clearing global:
154
+
155
+ ```ts
156
+ { a: 1, b: 2 }[cl.map](v => v * 3); // Typescript gets `{ a: number, b: number }`!
157
+ ```
158
+
159
+ 2. Use explicit typing:
160
+
161
+ ```ts
162
+ const map: typeof clearing.map = clearing.map; // `map` is now a `unique symbol`!
163
+ { a: 1, b: 2 }[map](v => v * 3); // Typescript gets `{ a: number, b: number }`!
164
+ ```
165
+
166
+ 3. Riot against the typescript maintainers for making things work this way (just kidding just kidding, they have their reasonssssss. I mean, kinda. Don't riot. They're smart people.)
167
+
121
168
  ## `Object` extensions
122
169
 
123
170
  There are currently no extensions on the `Object` class.
124
171
 
125
172
  ## `Object.prototype` extensions
126
173
 
127
- ### `Object.prototype[at]`
174
+ ### `Object.prototype[cl.at]`
128
175
 
129
176
  References a potentially nested own property.
130
177
 
131
178
  ```ts
132
179
  const obj = { a: { b: { c: 'z' } } };
133
- console.log(obj[at]([ 'a', 'b', 'c' ])); // "z"
180
+ console.log(obj[cl.at]([ 'a', 'b', 'c' ])); // "z"
134
181
  ```
135
182
 
136
183
  A default value can be supplied if nested lookup finds nothing.
137
184
 
138
185
  ```ts
139
186
  const obj = { a: { b: { c: 'z' } } };
140
- console.log(obj[at]([ 'missing' ], 'default')); // "default"
141
- console.log(obj[at]([ 'a', 'lol', 'c' ], 'default')); // "default"
142
- console.log(obj[at]([ 'a', 'b', 'haha' ], 'default')); // "default"
187
+ console.log(obj[cl.at]([ 'missing' ], 'default')); // "default"
188
+ console.log(obj[cl.at]([ 'a', 'lol', 'c' ], 'default')); // "default"
189
+ console.log(obj[cl.at]([ 'a', 'b', 'haha' ], 'default')); // "default"
143
190
  ```
144
191
 
145
- ### `Object.prototype[count]`
192
+ ### `Object.prototype[cl.count]`
146
193
 
147
194
  Returns the number of own properties in an object.
148
195
 
149
196
  ```ts
150
- console.log({}[count]()); // 0
151
- console.log({ a: 1, b: 2 }[count]()); // 2
152
- console.log({ a: 1, b: 2, c: 3 }[count]()); // 3
197
+ const { count } = clearing;
198
+
199
+ console.log({ }[cl.count]()); // 0
200
+ console.log({ a: 1, b: 2 }[cl.count]()); // 2
201
+ console.log({ a: 1, b: 2, c: 3 }[cl.count]()); // 3
153
202
  ```
154
203
 
155
- ### `Object.prototype[empty]`
204
+ ### `Object.prototype[cl.empty]`
156
205
 
157
206
  Returns whether an object has any properties.
158
207
 
159
208
  ```ts
160
- console.log({}[empty]()); // true
161
- console.log({ a: 1 }[empty]()); // false
209
+ console.log({ }[cl.empty]()); // true
210
+ console.log({ a: 1 }[cl.empty]()); // false
162
211
  ```
163
212
 
164
- ### `Object.prototype[group]`
213
+ ### `Object.prototype[cl.group]`
165
214
 
166
215
  Splits an object into sub-object groups based on a function returning group names.
167
216
 
168
217
  ```ts
169
218
  const obj = { a: 1, b: 10, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 2 };
170
219
 
171
- console.log(obj[group](n => {
220
+ console.log(obj[cl.group](n => {
172
221
  if (n < 4) return 'small';
173
222
  if (n < 8) return 'medium';
174
223
  return 'big';
@@ -183,90 +232,89 @@ console.log(obj[group](n => {
183
232
  */
184
233
  ```
185
234
 
186
- ### `Object.prototype[has]`
235
+ ### `Object.prototype[cl.has]`
187
236
 
188
237
  Determines own property existence.
189
238
 
190
239
  ```ts
191
240
  const obj = { a: 1, b: 2 };
192
- console.log(obj[has]('a')); // true
193
- console.log(obj[has]('b')); // true
194
- console.log(obj[has]('z')); // false
241
+ console.log(obj[cl.has]('a')); // true
242
+ console.log(obj[cl.has]('b')); // true
243
+ console.log(obj[cl.has]('z')); // false
195
244
  ```
196
245
 
197
- ### `Object.prototype[map]`
246
+ ### `Object.prototype[cl.map]`
198
247
 
199
248
  Maps over object values, returning a new object. Return `skip` to omit a property.
200
249
 
201
250
  ```ts
202
- const { skip } = clearing;
203
251
  const obj = { a: 1, b: 2, c: 3 };
204
- console.log(obj[map](v => v * 2)); // { a: 2, b: 4, c: 6 }
205
- console.log(obj[map](v => v > 1 ? v : skip)); // { b: 2, c: 3 }
252
+ console.log(obj[cl.map](v => v * 2)); // { a: 2, b: 4, c: 6 }
253
+ console.log(obj[cl.map](v => v > 1 ? v : cl.skip)); // { b: 2, c: 3 }
206
254
  ```
207
255
 
208
- ### `Object.prototype[mapk]`
256
+ ### `Object.prototype[cl.mapk]`
209
257
 
210
258
  Maps over object entries returning `[key, value]` pairs to construct a new object; allows remapping
211
259
  keys.
212
260
 
213
261
  ```ts
214
262
  const obj = { a: 1, b: 2 };
215
- console.log(obj[mapk]((v, k) => [ k.toUpperCase(), v * 10 ])); // { A: 10, B: 20 }
263
+ console.log(obj[cl.mapk]((v, k) => [ k.toUpperCase(), v * 10 ])); // { A: 10, B: 20 }
216
264
  ```
217
265
 
218
- ### `Object.prototype[merge]`
266
+ ### `Object.prototype[cl.merge]`
219
267
 
220
- Deep merges another object into `this` (mutates in place). Use `skip` global for deletion.
268
+ Deep merges another object into `this` (mutates in place). Use `skip` for deletion.
221
269
 
222
270
  ```ts
223
-
224
271
  const obj = { a: 1, b: { c: 2, d: 3 } };
225
- obj[merge]({ b: { c: 100 }, e: 4 });
272
+ obj[cl.merge]({ b: { c: 100 }, e: 4 });
226
273
  console.log(obj); // { a: 1, b: { c: 100, d: 3 }, e: 4 }
227
274
 
228
275
  // Deleting properties
229
- const { skip } = clearing;
230
- obj[merge]({ a: skip });
276
+ obj[cl.merge]({ a: skip });
231
277
  console.log(obj); // { b: { c: 100, d: 3 }, e: 4 }
232
278
  ```
233
279
 
234
- ### `Object.prototype[slash]`
280
+ ### `Object.prototype[cl.slash]`
235
281
 
236
282
  Returns a copy of the object with specified keys removed/omitted.
237
283
 
238
284
  ```ts
239
285
  const obj = { a: 1, b: 2, c: 3, d: 4 };
240
- console.log(obj[slash]([ 'b', 'd' ])); // { a: 1, c: 3 }
286
+ console.log(obj[cl.slash]([ 'b', 'd' ])); // { a: 1, c: 3 }
241
287
  ```
242
288
 
243
- ### `Object.prototype[slice]`
289
+ ### `Object.prototype[cl.slice]`
244
290
 
245
291
  Returns a copy of the object containing only the specified keys.
246
292
 
247
293
  ```ts
248
294
  const obj = { a: 1, b: 2, c: 3, d: 4 };
249
- console.log(obj[slice]([ 'b', 'd' ])); // { b: 2, d: 4 }
295
+ console.log(obj[cl.slice]([ 'b', 'd' ])); // { b: 2, d: 4 }
250
296
  ```
251
297
 
252
- ### `Object.prototype[toArr]`
298
+ ### `Object.prototype[cl.toArr]`
253
299
 
254
300
  Converts an object to an array by mapping over its entries.
255
301
 
256
302
  ```ts
257
303
  const obj = { a: 1, b: 2, c: 3 };
258
- console.log(obj[toArr]((v, k) => `${k}=${v}`)); // [ 'a=1', 'b=2', 'c=3' ]
304
+ console.log(obj[cl.toArr]((v, k) => `${k}=${v}`)); // [ 'a=1', 'b=2', 'c=3' ]
259
305
  ```
260
306
 
261
- ### `Object.prototype[Symbol.iterator]`
307
+ ### `Object.prototype[cl.walk]`
262
308
 
263
309
  Makes objects iterable, yielding `[key, value]` pairs.
264
310
 
265
311
  ```ts
266
312
  const obj = { a: 1, b: 2 };
267
- for (const [ k, v ] of obj) console.log(k, v);
268
- // "a" 1
269
- // "b" 2
313
+ for (const [ k, v ] of obj[cl.walk]())
314
+ // Logs twice:
315
+ // 1. a 1
316
+ // 2. b 2
317
+ console.log(k, v);
270
318
  ```
271
319
 
272
320
  ## `Array` extensions
@@ -275,57 +323,57 @@ There are currently no extensions on the `Array` class.
275
323
 
276
324
  ## `Array.prototype` extensions
277
325
 
278
- ### `Array.prototype[add]`
326
+ ### `Array.prototype[cl.add]`
279
327
 
280
328
  Pushes an item onto the array and returns that item.
281
329
 
282
330
  ```ts
283
331
  const arr = [ 1, 2, 3 ];
284
- const added = arr[add](4);
332
+ const added = arr[cl.add](4);
285
333
  console.log(added); // 4
286
334
  console.log(arr); // [ 1, 2, 3, 4 ]
287
335
  ```
288
336
 
289
- ### `Array.prototype[count]`
337
+ ### `Array.prototype[cl.count]`
290
338
 
291
339
  Returns the length of the array.
292
340
 
293
341
  ```ts
294
- console.log([ 1, 2, 3 ][count]()); // 3
295
- console.log([][count]()); // 0
342
+ console.log([ 1, 2, 3 ][cl.count]()); // 3
343
+ console.log([][cl.count]()); // 0
296
344
  ```
297
345
 
298
- ### `Array.prototype[empty]`
346
+ ### `Array.prototype[cl.empty]`
299
347
 
300
348
  Returns whether the array has no elements.
301
349
 
302
350
  ```ts
303
- console.log([][empty]()); // true
304
- console.log([ 1, 2, 3 ][empty]()); // false
351
+ console.log([][cl.empty]()); // true
352
+ console.log([ 1, 2, 3 ][cl.empty]()); // false
305
353
  ```
306
354
 
307
- ### `Array.prototype[find]`
355
+ ### `Array.prototype[cl.find]`
308
356
 
309
357
  Finds an element matching a predicate, returning `{ found, val, ind }`.
310
358
 
311
359
  ```ts
312
360
  const arr = [ 10, 20, 30, 40 ];
313
361
 
314
- const result = arr[find](v => v > 25);
362
+ const result = arr[cl.find](v => v > 25);
315
363
  console.log(result); // { found: true, val: 30, ind: 2 }
316
364
 
317
- const missing = arr[find](v => v > 100);
365
+ const missing = arr[cl.find](v => v > 100);
318
366
  console.log(missing); // { found: false, val: null, ind: null }
319
367
  ```
320
368
 
321
- ### `Array.prototype[group]`
369
+ ### `Array.prototype[cl.group]`
322
370
 
323
371
  Splits an array into sub-arrays based on a function returning group names.
324
372
 
325
373
  ```ts
326
374
  const arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
327
375
 
328
- console.log(arr[group](n => {
376
+ console.log(arr[cl.group](n => {
329
377
  if (n < 4) return 'small';
330
378
  if (n < 8) return 'medium';
331
379
  return 'big';
@@ -340,49 +388,47 @@ console.log(arr[group](n => {
340
388
  */
341
389
  ```
342
390
 
343
- ### `Array.prototype[has]`
391
+ ### `Array.prototype[cl.has]`
344
392
 
345
393
  Checks if an array includes a value.
346
394
 
347
395
  ```ts
348
- console.log([ 1, 2, 3 ][has](2)); // true
349
- console.log([ 1, 2, 3 ][has](5)); // false
396
+ console.log([ 1, 2, 3 ][cl.has](2)); // true
397
+ console.log([ 1, 2, 3 ][cl.has](5)); // false
350
398
  ```
351
399
 
352
400
  ### `Array.prototype[map]`
353
401
 
354
- Maps over array values. Return `clearing.skip` to omit an element (filter + map in one).
402
+ Maps over array values. Return `cl.skip` to omit an element; it's filter + map in one.
355
403
 
356
404
  ```ts
357
405
  const arr = [ 1, 2, 3, 4, 5 ];
358
- console.log(arr[map](v => v * 2)); // [ 2, 4, 6, 8, 10 ]
359
-
360
- const { skip } = clearing;
361
- console.log(arr[map](v => v > 2 ? v * 10 : skip)); // [ 30, 40, 50 ]
406
+ console.log(arr[cl.map](v => v * 2)); // [ 2, 4, 6, 8, 10 ]
407
+ console.log(arr[cl.map](v => v > 2 ? v * 10 : cl.skip)); // [ 30, 40, 50 ]
362
408
  ```
363
409
 
364
- ### `Array.prototype[rem]`
410
+ ### `Array.prototype[cl.rem]`
365
411
 
366
412
  Removes the first occurrence of a value from the array (mutates in place).
367
413
 
368
414
  ```ts
369
415
  const arr = [ 1, 2, 3, 2, 4 ];
370
- arr[rem](2);
416
+ arr[cl.rem](2);
371
417
  console.log(arr); // [ 1, 3, 2, 4 ]
372
418
  ```
373
419
 
374
- ### `Array.prototype[toObj]`
420
+ ### `Array.prototype[cl.toObj]`
375
421
 
376
422
  Converts an array to an object by mapping each element to a `[key, value]` pair.
377
423
 
378
424
  ```ts
379
425
  const arr = [ 'a', 'b', 'c' ];
380
- console.log(arr[toObj]((v, i) => [ v, i ])); // { a: 0, b: 1, c: 2 }
426
+ console.log(arr[cl.toObj]((v, i) => [ v, i ])); // { a: 0, b: 1, c: 2 }
381
427
  ```
382
428
 
383
429
  ## `String` extensions
384
430
 
385
- ### `String[baseline]`
431
+ ### `String[cl.baseline]`
386
432
 
387
433
  Allows writing coherent multiline strings with predictable indentation.
388
434
 
@@ -393,7 +439,7 @@ const text = (() => {
393
439
 
394
440
  return (() => {
395
441
 
396
- return String[baseline](`
442
+ return String[cl.baseline](`
397
443
  | Even though this text is in an indented scope, it will have predictable indentation.
398
444
  |
399
445
  | This is achieved by using the pipe ("|") character plus a space as a delimiter for
@@ -411,184 +457,184 @@ const text = (() => {
411
457
  })();
412
458
  ```
413
459
 
414
- ### `String[base32]`, `String[base36]`, `String[base62]`, `String[base64Url]`, `String[base64Std]`
460
+ ### `String[cl.base32]`, `String[cl.base36]`, `String[cl.base62]`, `String[cl.base64Url]`, `String[cl.base64Std]`
415
461
 
416
462
  Character sets for encoding/decoding numbers to strings.
417
463
 
418
464
  ```ts
419
- console.log(String[base32]); // '0123456789abcdefghijklmnopqrstuv'
420
- console.log(String[base36]); // '0123456789abcdefghijklmnopqrstuvwxyz'
421
- console.log(String[base62]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
422
- console.log(String[base64Url]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'
423
- console.log(String[base64Std]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'
465
+ console.log(String[cl.base32]); // '0123456789abcdefghijklmnopqrstuv'
466
+ console.log(String[cl.base36]); // '0123456789abcdefghijklmnopqrstuvwxyz'
467
+ console.log(String[cl.base62]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
468
+ console.log(String[cl.base64Url]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'
469
+ console.log(String[cl.base64Std]); // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/'
424
470
  ```
425
471
 
426
472
  ## `String.prototype` extensions
427
473
 
428
- ### `String.prototype[code]`
474
+ ### `String.prototype[cl.code]`
429
475
 
430
476
  Returns the character code at a given index (default 0).
431
477
 
432
478
  ```ts
433
- console.log('A'[code]()); // 65
434
- console.log('AB'[code](1)); // 66
479
+ console.log('A'[cl.code]()); // 65
480
+ console.log('AB'[cl.code](1)); // 66
435
481
  ```
436
482
 
437
- ### `String.prototype[count]`
483
+ ### `String.prototype[cl.count]`
438
484
 
439
485
  Returns the length of the string.
440
486
 
441
487
  ```ts
442
- console.log('hello'[count]()); // 5
443
- console.log(''[count]()); // 0
488
+ console.log('hello'[cl.count]()); // 5
489
+ console.log(''[cl.count]()); // 0
444
490
  ```
445
491
 
446
- ### `String.prototype[cut]`
492
+ ### `String.prototype[cl.cut]`
447
493
 
448
494
  Splits a string by a delimiter with a maximum number of cuts.
449
495
 
450
496
  ```ts
451
- console.log('a:b:c:d:e'[cut](':')); // [ 'a', 'b:c:d:e' ]
452
- console.log('a:b:c:d:e'[cut](':', 2)); // [ 'a', 'b', 'c:d:e' ]
453
- console.log('a:b:c:d:e'[cut](':', Infinity)); // [ 'a', 'b', 'c', 'd', 'e' ]
497
+ console.log('a:b:c:d:e'[cl.cut](':')); // [ 'a', 'b:c:d:e' ]
498
+ console.log('a:b:c:d:e'[cl.cut](':', 2)); // [ 'a', 'b', 'c:d:e' ]
499
+ console.log('a:b:c:d:e'[cl.cut](':', Infinity)); // [ 'a', 'b', 'c', 'd', 'e' ]
454
500
  ```
455
501
 
456
- ### `String.prototype[has]`
502
+ ### `String.prototype[cl.has]`
457
503
 
458
504
  Checks if a string contains a substring.
459
505
 
460
506
  ```ts
461
- console.log('hello world'[has]('world')); // true
462
- console.log('hello world'[has]('xyz')); // false
507
+ console.log('hello world'[cl.has]('world')); // true
508
+ console.log('hello world'[cl.has]('xyz')); // false
463
509
  ```
464
510
 
465
- ### `String.prototype[hasHead]`
511
+ ### `String.prototype[cl.hasHead]`
466
512
 
467
513
  Checks if a string starts with a given prefix.
468
514
 
469
515
  ```ts
470
- console.log('hello world'[hasHead]('hello')); // true
471
- console.log('hello world'[hasHead]('world')); // false
516
+ console.log('hello world'[cl.hasHead]('hello')); // true
517
+ console.log('hello world'[cl.hasHead]('world')); // false
472
518
  ```
473
519
 
474
- ### `String.prototype[hasTail]`
520
+ ### `String.prototype[cl.hasTail]`
475
521
 
476
522
  Checks if a string ends with a given suffix.
477
523
 
478
524
  ```ts
479
- console.log('hello world'[hasTail]('world')); // true
480
- console.log('hello world'[hasTail]('hello')); // false
525
+ console.log('hello world'[cl.hasTail]('world')); // true
526
+ console.log('hello world'[cl.hasTail]('hello')); // false
481
527
  ```
482
528
 
483
- ### `String.prototype[indent]`
529
+ ### `String.prototype[cl.indent]`
484
530
 
485
531
  Indents each line of a string.
486
532
 
487
533
  ```ts
488
534
  const text = 'line1\nline2\nline3';
489
535
 
490
- console.log(text[indent]()); // 2 spaces (default)
491
- console.log(text[indent](4)); // 4 spaces
492
- console.log(text[indent](2, '-')); // '--' prefix
493
- console.log(text[indent]('>>> ')); // custom prefix
536
+ console.log(text[cl.indent]()); // 2 spaces (default)
537
+ console.log(text[cl.indent](4)); // 4 spaces
538
+ console.log(text[cl.indent](2, '-')); // '--' prefix
539
+ console.log(text[cl.indent]('>>> ')); // custom prefix
494
540
  ```
495
541
 
496
- ### `String.prototype[lower]`
542
+ ### `String.prototype[cl.lower]`
497
543
 
498
544
  Converts the string to lowercase.
499
545
 
500
546
  ```ts
501
- console.log('HELLO'[lower]()); // 'hello'
547
+ console.log('HELLO'[cl.lower]()); // 'hello'
502
548
  ```
503
549
 
504
- ### `String.prototype[upper]`
550
+ ### `String.prototype[cl.upper]`
505
551
 
506
552
  Converts the string to uppercase.
507
553
 
508
554
  ```ts
509
- console.log('hello'[upper]()); // 'HELLO'
555
+ console.log('hello'[cl.upper]()); // 'HELLO'
510
556
  ```
511
557
 
512
- ### `String.prototype[padHead]`
558
+ ### `String.prototype[cl.padHead]`
513
559
 
514
560
  Pads the start of the string to a given length.
515
561
 
516
562
  ```ts
517
- console.log('5'[padHead](3, '0')); // '005'
563
+ console.log('5'[cl.padHead](3, '0')); // '005'
518
564
  ```
519
565
 
520
- ### `String.prototype[padTail]`
566
+ ### `String.prototype[cl.padTail]`
521
567
 
522
568
  Pads the end of the string to a given length.
523
569
 
524
570
  ```ts
525
- console.log('5'[padTail](3, '0')); // '500'
571
+ console.log('5'[cl.padTail](3, '0')); // '500'
526
572
  ```
527
573
 
528
- ### `String.prototype[toNum]`
574
+ ### `String.prototype[cl.toNum]`
529
575
 
530
576
  Decodes a string to a BigInt using a given charset.
531
577
 
532
578
  ```ts
533
- console.log('ff'[toNum](String[charset]('0123456789abcdef'))); // 255n
534
- console.log('10'[toNum](String[base62])); // 62n
579
+ console.log('ff'[cl.toNum](String[cl.charset]('0123456789abcdef'))); // 255n
580
+ console.log('10'[cl.toNum](String[cl.base62])); // 62n
535
581
  ```
536
582
 
537
583
  ## `Number` extensions
538
584
 
539
- ### `Number[int32]`, `Number[int64]`
585
+ ### `Number[cl.int32]`, `Number[cl.int64]`
540
586
 
541
587
  Constants for 32-bit and 64-bit integer ranges.
542
588
 
543
589
  ```ts
544
- console.log(Number[int32]); // 4294967296 (2^32)
545
- console.log(Number[int64]); // 18446744073709551616 (2^64)
590
+ console.log(Number[cl.int32]); // 4294967296 (2^32)
591
+ console.log(Number[cl.int64]); // 18446744073709551616 (2^64)
546
592
  ```
547
593
 
548
594
  ## `Number.prototype` extensions
549
595
 
550
- ### `Number.prototype[char]`
596
+ ### `Number.prototype[cl.char]`
551
597
 
552
598
  Converts a character code to its character.
553
599
 
554
600
  ```ts
555
- console.log((65)[char]()); // 'A'
556
- console.log((97)[char]()); // 'a'
601
+ console.log((65)[cl.char]()); // 'A'
602
+ console.log((97)[cl.char]()); // 'a'
557
603
  ```
558
604
 
559
- ### `Number.prototype[isInt]`
605
+ ### `Number.prototype[cl.isInt]`
560
606
 
561
607
  Returns whether a number is an integer.
562
608
 
563
609
  ```ts
564
- console.log((5)[isInt]()); // true
565
- console.log((5.1)[isInt]()); // false
610
+ console.log((5)[cl.isInt]()); // true
611
+ console.log((5.1)[cl.isInt]()); // false
566
612
  ```
567
613
 
568
- ### `Number.prototype[toArr]`
614
+ ### `Number.prototype[cl.toArr]`
569
615
 
570
616
  Creates an array of length `n` by mapping over indices.
571
617
 
572
618
  ```ts
573
- console.log((5)[toArr](i => i * 2)); // [ 0, 2, 4, 6, 8 ]
619
+ console.log((5)[cl.toArr](i => i * 2)); // [ 0, 2, 4, 6, 8 ]
574
620
  ```
575
621
 
576
- ### `Number.prototype[toObj]`
622
+ ### `Number.prototype[cl.toObj]`
577
623
 
578
624
  Creates an object by mapping over indices, returning `[key, value]` pairs.
579
625
 
580
626
  ```ts
581
- console.log((3)[toObj](i => [ `key${i}`, i * 10 ])); // { key0: 0, key1: 10, key2: 20 }
627
+ console.log((3)[cl.toObj](i => [ `key${i}`, i * 10 ])); // { key0: 0, key1: 10, key2: 20 }
582
628
  ```
583
629
 
584
- ### `Number.prototype[toStr]`
630
+ ### `Number.prototype[cl.toStr]`
585
631
 
586
632
  Encodes a number to a string using a given charset.
587
633
 
588
634
  ```ts
589
- console.log((255)[toStr](String[charset]('0123456789abcdef'))); // 'ff'
590
- console.log((62)[toStr](String[base62])); // '10'
591
- console.log((5)[toStr](String[base62], 4)); // '0005' (padded)
635
+ console.log((255)[cl.toStr](String[cl.charset]('0123456789abcdef'))); // 'ff'
636
+ console.log((62)[cl.toStr](String[cl.base62])); // '10'
637
+ console.log((5)[cl.toStr](String[cl.base62], 4)); // '0005' (padded)
592
638
  ```
593
639
 
594
640
  ### `Number.prototype[Symbol.iterator]`
@@ -604,72 +650,72 @@ for (const i of 3) console.log(i);
604
650
  console.log([ ...5 ]); // [ 0, 1, 2, 3, 4 ]
605
651
  ```
606
652
 
607
- ### `Number.prototype[bits]`
653
+ ### `Number.prototype[cl.bits]`
608
654
 
609
655
  Yields the bits of a number (least significant first).
610
656
 
611
657
  ```ts
612
- console.log([ ...(13)[bits]() ]); // [ 1, 0, 1, 1 ] (13 is 1101 in binary)
658
+ console.log([ ...(13)[cl.bits]() ]); // [ 1, 0, 1, 1 ] (13 is 1101 in binary)
613
659
  ```
614
660
 
615
661
  ## `BigInt.prototype` extensions
616
662
 
617
- ### `BigInt.prototype[toStr]`
663
+ ### `BigInt.prototype[cl.toStr]`
618
664
 
619
- Same as `Number.prototype[toStr]`, but for BigInt values.
665
+ Same as `Number.prototype[cl.toStr]`, but for BigInt values.
620
666
 
621
667
  ```ts
622
- console.log((1000000000000n)[toStr](String[base62])); // 'bLY38W'
668
+ console.log((1000000000000n)[cl.toStr](String[cl.base62])); // 'bLY38W'
623
669
  ```
624
670
  ## `Error` extensions
625
671
 
626
- ### `Error[assert]`
672
+ ### `Error[cl.assert]`
627
673
 
628
674
  Throws an error if the assertion function returns false.
629
675
 
630
676
  ```ts
631
- Error[assert]({ x: 5, y: 10 }, ({ x, y }) => x < y); // passes
632
- Error[assert]({ x: 10, y: 5 }, ({ x, y }) => x < y); // throws!
677
+ Error[cl.assert]({ x: 5, y: 10 }, ({ x, y }) => x < y); // passes
678
+ Error[cl.assert]({ x: 10, y: 5 }, ({ x, y }) => x < y); // throws!
633
679
  ```
634
680
 
635
681
  ## `Error.prototype` extensions
636
682
 
637
- ### `Error.prototype[mod]`
683
+ ### `Error.prototype[cl.mod]`
638
684
 
639
685
  Modifies an error's message and adds properties. Returns the error for chaining.
640
686
 
641
687
  ```ts
642
688
  // Add context to errors:
643
- throw Error('oops')[mod]({ code: 'err99', context: { userId: 123 } });
689
+ throw Error('oops')[cl.mod]({ code: 'err99', context: { userId: 123 } });
644
690
 
645
691
  // Overwrite the error message by passing a string, or supplying "message" or "msg" properties:
646
- throw Error('oops')[mod]('new message');
647
- throw Error('oops')[mod]({ msg: 'new message', extra: 'data' });
648
- throw Error('oops')[mod]({ message: 'new message', extra: 'data' });
692
+ throw Error('oops')[cl.mod]('new message');
693
+ throw Error('oops')[cl.mod]({ msg: 'new message', extra: 'data' });
694
+ throw Error('oops')[cl.mod]({ message: 'new message', extra: 'data' });
649
695
 
650
696
  // Pass a callback to succinctly reference the original message:
651
- throw Error('oops')[mod](msg => `Modified message! Original: ${msg}`);
652
- throw Error('oops')[mod](msg => ({
697
+ throw Error('oops')[cl.mod](msg => `Modified message! Original: ${msg}`);
698
+ throw Error('oops')[cl.mod](msg => ({
653
699
  msg: `Modified message! Original: ${msg}`,
654
700
  extra: 'data'
655
701
  }));
656
702
  ```
657
703
 
658
- ### `Error.prototype[fire]`
704
+ ### `Error.prototype[cl.fire]`
659
705
 
660
- Shorthand for `throw error[mod](props)`.
706
+ Shorthand for `throw error[cl.mod](props)`.
661
707
 
662
708
  ```ts
663
- Error('something failed')[fire]({ code: 'err99' });
709
+ Error('something failed')[cl.fire]({ code: 'err99' });
664
710
  ```
665
711
 
666
- ### `Error.prototype[limn]`
712
+ ### `Error.prototype[cl.limn]`
667
713
 
668
714
  Converts an error (and its cause chain) to a plain, json-serializable object.
669
715
 
670
716
  ```ts
671
- const err = Error('outer')[mod]({ cause: Error('inner') });
672
- console.log(err[limn]());
717
+ const err = Error('outer')[cl.mod]({ cause: Error('inner') });
718
+ console.log(err[cl.limn]());
673
719
  /*
674
720
  {
675
721
  form: 'Error',
@@ -680,13 +726,13 @@ console.log(err[limn]());
680
726
  */
681
727
  ```
682
728
 
683
- ### `Error.prototype[suppress]`
729
+ ### `Error.prototype[cl.suppress]`
684
730
 
685
731
  Marks an error (and its causes) as suppressed for custom error handling.
686
732
 
687
733
  ```ts
688
734
  const err = Error('handled gracefully');
689
- err[suppress]();
735
+ err[cl.suppress]();
690
736
  console.log(err[Symbol.for('clearing.err.suppressed')]); // true
691
737
  ```
692
738
 
@@ -705,20 +751,20 @@ process.on('unhandledException', err => {
705
751
 
706
752
  ## `Promise` extensions
707
753
 
708
- ### `Promise[allArr]`
754
+ ### `Promise[cl.allArr]`
709
755
 
710
756
  Alias for `Promise.all`.
711
757
 
712
758
  ```ts
713
- const results = await Promise[allArr]([ fetch('/a'), fetch('/b'), fetch('/c') ]);
759
+ const results = await Promise[cl.allArr]([ fetch('/a'), fetch('/b'), fetch('/c') ]);
714
760
  ```
715
761
 
716
- ### `Promise[allObj]`
762
+ ### `Promise[cl.allObj]`
717
763
 
718
764
  Like `Promise.all`, but for an object of promises, returning an object of results.
719
765
 
720
766
  ```ts
721
- const results = await Promise[allObj]({
767
+ const results = await Promise[cl.allObj]({
722
768
  user: fetchUser(),
723
769
  posts: fetchPosts(),
724
770
  comments: fetchComments()
@@ -726,12 +772,12 @@ const results = await Promise[allObj]({
726
772
  console.log(results.user, results.posts, results.comments);
727
773
  ```
728
774
 
729
- ### `Promise[later]`
775
+ ### `Promise[cl.later]`
730
776
 
731
777
  Creates a promise with externally accessible `resolve` and `reject` functions.
732
778
 
733
779
  ```ts
734
- const p = Promise[later]();
780
+ const p = Promise[cl.later]();
735
781
 
736
782
  setTimeout(() => p.resolve('done!'), 1000);
737
783
 
@@ -740,140 +786,140 @@ console.log(await p); // 'done!'
740
786
 
741
787
  ## `Set.prototype` extensions
742
788
 
743
- ### `Set.prototype[count]`
789
+ ### `Set.prototype[cl.count]`
744
790
 
745
791
  Returns the size of the set.
746
792
 
747
793
  ```ts
748
- console.log(new Set([ 1, 2, 3 ])[count]()); // 3
794
+ console.log(new Set([ 1, 2, 3 ])[cl.count]()); // 3
749
795
  ```
750
796
 
751
- ### `Set.prototype[empty]`
797
+ ### `Set.prototype[cl.empty]`
752
798
 
753
799
  Returns whether the set is empty.
754
800
 
755
801
  ```ts
756
- console.log(new Set()[empty]()); // true
757
- console.log(new Set([ 1 ])[empty]()); // false
802
+ console.log(new Set()[cl.empty]()); // true
803
+ console.log(new Set([ 1 ])[cl.empty]()); // false
758
804
  ```
759
805
 
760
- ### `Set.prototype[find]`
806
+ ### `Set.prototype[cl.find]`
761
807
 
762
808
  Finds an element matching a predicate, returning `{ found, val }`.
763
809
 
764
810
  ```ts
765
811
  const s = new Set([ 10, 20, 30 ]);
766
- console.log(s[find](v => v > 15)); // { found: true, val: 20 }
812
+ console.log(s[cl.find](v => v > 15)); // { found: true, val: 20 }
767
813
  ```
768
814
 
769
- ### `Set.prototype[map]`
815
+ ### `Set.prototype[cl.map]`
770
816
 
771
817
  Maps over set values to produce an array.
772
818
 
773
819
  ```ts
774
820
  const s = new Set([ 1, 2, 3 ]);
775
- console.log(s[map](v => v * 2)); // [ 2, 4, 6 ]
821
+ console.log(s[cl.map](v => v * 2)); // [ 2, 4, 6 ]
776
822
  ```
777
823
 
778
- ### `Set.prototype[rem]`
824
+ ### `Set.prototype[cl.rem]`
779
825
 
780
826
  Removes a value from the set.
781
827
 
782
828
  ```ts
783
829
  const s = new Set([ 1, 2, 3 ]);
784
- s[rem](2);
830
+ s[cl.rem](2);
785
831
  console.log([ ...s ]); // [ 1, 3 ]
786
832
  ```
787
833
 
788
- ### `Set.prototype[toArr]`
834
+ ### `Set.prototype[cl.toArr]`
789
835
 
790
836
  Converts a set to an array by mapping over its values.
791
837
 
792
838
  ```ts
793
839
  const s = new Set([ 1, 2, 3 ]);
794
- console.log(s[toArr](v => v * 10)); // [ 10, 20, 30 ]
840
+ console.log(s[cl.toArr](v => v * 10)); // [ 10, 20, 30 ]
795
841
  ```
796
842
 
797
- ### `Set.prototype[toObj]`
843
+ ### `Set.prototype[cl.toObj]`
798
844
 
799
845
  Converts a set to an object by mapping each value to a `[key, value]` pair.
800
846
 
801
847
  ```ts
802
848
  const s = new Set([ 'a', 'b', 'c' ]);
803
- console.log(s[toObj](v => [ v, v.toUpperCase() ])); // { a: 'A', b: 'B', c: 'C' }
849
+ console.log(s[cl.toObj](v => [ v, v.toUpperCase() ])); // { a: 'A', b: 'B', c: 'C' }
804
850
  ```
805
851
 
806
852
  ## `Map.prototype` extensions
807
853
 
808
- ### `Map.prototype[add]`
854
+ ### `Map.prototype[cl.add]`
809
855
 
810
856
  Alias for `Map.prototype.set` (for consistency with Set).
811
857
 
812
858
  ```ts
813
859
  const m = new Map();
814
- m[add]('key', 'value');
860
+ m[cl.add]('key', 'value');
815
861
  ```
816
862
 
817
- ### `Map.prototype[count]`
863
+ ### `Map.prototype[cl.count]`
818
864
 
819
865
  Returns the size of the map.
820
866
 
821
867
  ```ts
822
868
  const m = new Map([ [ 'a', 1 ], [ 'b', 2 ] ]);
823
- console.log(m[count]()); // 2
869
+ console.log(m[cl.count]()); // 2
824
870
  ```
825
871
 
826
- ### `Map.prototype[empty]`
872
+ ### `Map.prototype[cl.empty]`
827
873
 
828
874
  Returns whether the map is empty.
829
875
 
830
876
  ```ts
831
- console.log(new Map()[empty]()); // true
832
- console.log(new Map([ [ 'a', 1 ] ])[empty]()); // false
877
+ console.log(new Map()[cl.empty]()); // true
878
+ console.log(new Map([ [ 'a', 1 ] ])[cl.empty]()); // false
833
879
  ```
834
880
 
835
- ### `Map.prototype[find]`
881
+ ### `Map.prototype[cl.find]`
836
882
 
837
883
  Finds an entry matching a predicate, returning `{ found, val, key }`.
838
884
 
839
885
  ```ts
840
886
  const m = new Map([ [ 'a', 10 ], [ 'b', 20 ], [ 'c', 30 ] ]);
841
- console.log(m[find](v => v > 15)); // { found: true, val: 20, key: 'b' }
887
+ console.log(m[cl.find](v => v > 15)); // { found: true, val: 20, key: 'b' }
842
888
  ```
843
889
 
844
- ### `Map.prototype[map]`
890
+ ### `Map.prototype[cl.map]`
845
891
 
846
892
  Maps entries to produce an object; iterator receives `(val, key)` and returns `[key, val]`.
847
893
 
848
894
  ```ts
849
895
  const m = new Map([ [ 'a', 1 ], [ 'b', 2 ] ]);
850
- console.log(m[map]((v, k) => [ k.toUpperCase(), v * 10 ])); // { A: 10, B: 20 }
896
+ console.log(m[cl.map]((v, k) => [ k.toUpperCase(), v * 10 ])); // { A: 10, B: 20 }
851
897
  ```
852
898
 
853
- ### `Map.prototype[rem]`
899
+ ### `Map.prototype[cl.rem]`
854
900
 
855
901
  Removes an entry from the map by key.
856
902
 
857
903
  ```ts
858
904
  const m = new Map([ [ 'a', 1 ], [ 'b', 2 ] ]);
859
- m[rem]('a');
860
- console.log(m[count]()); // 1
905
+ m[cl.rem]('a');
906
+ console.log(m[cl.count]()); // 1
861
907
  ```
862
908
 
863
- ### `Map.prototype[toArr]`
909
+ ### `Map.prototype[cl.toArr]`
864
910
 
865
911
  Converts a map to an array by mapping over its entries.
866
912
 
867
913
  ```ts
868
914
  const m = new Map([ [ 'a', 1 ], [ 'b', 2 ] ]);
869
- console.log(m[toArr]((v, k) => `${k}=${v}`)); // [ 'a=1', 'b=2' ]
915
+ console.log(m[cl.toArr]((v, k) => `${k}=${v}`)); // [ 'a=1', 'b=2' ]
870
916
  ```
871
917
 
872
- ### `Map.prototype[toObj]`
918
+ ### `Map.prototype[cl.toObj]`
873
919
 
874
920
  Converts a map to an object by mapping over its entries.
875
921
 
876
922
  ```ts
877
923
  const m = new Map([ [ 'a', 1 ], [ 'b', 2 ] ]);
878
- console.log(m[toObj]((v, k) => [ k, v * 100 ])); // { a: 100, b: 200 }
924
+ console.log(m[cl.toObj]((v, k) => [ k, v * 100 ])); // { a: 100, b: 200 }
879
925
  ```