@gershy/clearing 0.0.24 → 0.0.27

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/cmp/cjs/main.d.ts CHANGED
@@ -3,7 +3,7 @@ type ClsCheck = {
3
3
  (i: unknown, num: BooleanConstructor): i is boolean;
4
4
  (i: unknown, num: NumberConstructor): i is number;
5
5
  (i: unknown, str: StringConstructor): i is string;
6
- (i: unknown, buff: BufferConstructor): i is Buffer;
6
+ (i: unknown, buff: Buffer): i is Buffer;
7
7
  (i: unknown, arr: ArrayConstructor): i is any[];
8
8
  (i: unknown, obj: ObjectConstructor): i is Obj<unknown>;
9
9
  (i: unknown, fn: FunctionConstructor): i is Fn;
package/cmp/cjs/main.js CHANGED
@@ -59,6 +59,7 @@ const applyClearing = (() => {
59
59
  if (global[memSym])
60
60
  return;
61
61
  global[memSym] = true;
62
+ const [enc, dec] = [new TextEncoder(), new TextDecoder()];
62
63
  const symNames = [
63
64
  // <SYMBOLS> :: definitions :: /[']([a-zA-Z0-9]+)[']/
64
65
  'add',
@@ -73,7 +74,6 @@ const applyClearing = (() => {
73
74
  'base64Url',
74
75
  'baseline',
75
76
  'bind',
76
- 'bits',
77
77
  'char',
78
78
  'charset',
79
79
  'code',
@@ -105,6 +105,7 @@ const applyClearing = (() => {
105
105
  'slice',
106
106
  'suppress',
107
107
  'toArr',
108
+ 'toBin',
108
109
  'toNum',
109
110
  'toObj',
110
111
  'toStr',
@@ -113,29 +114,19 @@ const applyClearing = (() => {
113
114
  ];
114
115
  const syms = Object.fromEntries(symNames.map(term => [term, Symbol(`${pfx}:${term}`)]));
115
116
  Object.assign(global, { ...syms });
116
- const protoDefs = (Cls, def) => {
117
- let protoVals = [];
118
- let classVals = [];
117
+ const assignSyms = (Cls, def) => {
118
+ const protoVals = [];
119
119
  for (const key of Reflect.ownKeys(def)) {
120
- if (key !== '$' && !(0, exports.isCls)(key, Symbol))
120
+ if (!(0, exports.isCls)(key, Symbol))
121
121
  throw Object.assign(Error('invalid proto key'), { Cls, keyClsName: (0, exports.getClsName)(key), key });
122
- if (key !== '$') {
123
- protoVals.push([key, def[key]]);
124
- }
125
- else {
126
- for (const k of Reflect.ownKeys(def[key])) {
127
- if (!(0, exports.isCls)(k, Symbol))
128
- throw Object.assign(Error('invalid class key'), { Cls, keyClsName: (0, exports.getClsName)(k), key: k });
129
- classVals.push([k, def[key][k]]);
130
- }
131
- }
122
+ protoVals.push([key, def[key]]);
132
123
  }
133
124
  // Assign class properties
134
- for (const [target, props] of [[Cls, classVals], [Cls.prototype, protoVals]])
135
- for (const [sym, value] of props)
136
- Object.defineProperty(target, sym, { enumerable: false, value });
125
+ for (const [sym, value] of protoVals)
126
+ Object.defineProperty(Cls, sym, { enumerable: false, value });
137
127
  };
138
- protoDefs(Object, {
128
+ assignSyms(Object, {});
129
+ assignSyms(Object.prototype, {
139
130
  [at](cmps, def = exports.skip) {
140
131
  let ptr = this;
141
132
  if (!(0, exports.isCls)(cmps, Array))
@@ -234,7 +225,8 @@ const applyClearing = (() => {
234
225
  *[Symbol.iterator]() { for (const k in this)
235
226
  yield [k, this[k]]; }
236
227
  });
237
- protoDefs(Array, {
228
+ assignSyms(Array, {});
229
+ assignSyms(Array.prototype, {
238
230
  [add](...args) { this.push(...args); return args[0]; },
239
231
  [count]() { return this.length; },
240
232
  [empty]() { return !this.length; },
@@ -287,43 +279,43 @@ const applyClearing = (() => {
287
279
  return Object.fromEntries(ret);
288
280
  }
289
281
  });
290
- protoDefs(String, {
291
- $: {
292
- [baseline]: (str, seq = '| ') => {
293
- return str.split('\n')[map](ln => {
294
- const ind = ln.indexOf(seq);
295
- if (ind === -1)
296
- return exports.skip;
297
- return ln.slice(ind + seq.length);
298
- }).join('\n');
299
- },
300
- [base32]: '0123456789abcdefghijklmnopqrstuv',
301
- [base36]: '0123456789abcdefghijklmnopqrstuvwxyz',
302
- [base62]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
303
- [base64Url]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
304
- [base64Std]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/',
305
- [charset]: str => {
306
- const cache = new Map();
307
- return {
308
- str,
309
- size: BigInt(str.length),
310
- charVal: (c) => {
311
- if (!cache.has(c)) {
312
- const ind = str.indexOf(c);
313
- if (ind < 0)
314
- throw Error('char outside charset')[mod]({ char: c });
315
- cache.set(c, BigInt(ind));
316
- }
317
- return cache.get(c);
318
- },
319
- valChar: (n) => {
320
- if (n < 0 || n >= str.length)
321
- throw Error('val outside charset');
322
- return str[n];
323
- }
324
- };
325
- },
282
+ assignSyms(String, {
283
+ [baseline]: (str, seq = '| ') => {
284
+ return str.split('\n')[map](ln => {
285
+ const ind = ln.indexOf(seq);
286
+ if (ind === -1)
287
+ return exports.skip;
288
+ return ln.slice(ind + seq.length);
289
+ }).join('\n');
326
290
  },
291
+ [base32]: '0123456789abcdefghijklmnopqrstuv',
292
+ [base36]: '0123456789abcdefghijklmnopqrstuvwxyz',
293
+ [base62]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
294
+ [base64Url]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
295
+ [base64Std]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/',
296
+ [charset]: str => {
297
+ const cache = new Map();
298
+ return {
299
+ str,
300
+ size: BigInt(str.length),
301
+ charVal: (c) => {
302
+ if (!cache.has(c)) {
303
+ const ind = str.indexOf(c);
304
+ if (ind < 0)
305
+ throw Error('char outside charset')[mod]({ char: c });
306
+ cache.set(c, BigInt(ind));
307
+ }
308
+ return cache.get(c);
309
+ },
310
+ valChar: (n) => {
311
+ if (n < 0 || n >= str.length)
312
+ throw Error('val outside charset');
313
+ return str[n];
314
+ }
315
+ };
316
+ }
317
+ });
318
+ assignSyms(String.prototype, {
327
319
  [code](ind = 0) { return this.charCodeAt(ind); },
328
320
  [count]() { return this.length; },
329
321
  [cut](delim, cuts = 1) {
@@ -356,6 +348,7 @@ const applyClearing = (() => {
356
348
  [lower]: String.prototype.toLowerCase,
357
349
  [padHead]: String.prototype.padStart,
358
350
  [padTail]: String.prototype.padEnd,
351
+ [toBin]() { return enc.encode(this); },
359
352
  [toNum](cs = String[base62]) {
360
353
  if ((0, exports.isCls)(cs, String))
361
354
  cs = String[charset](cs);
@@ -365,18 +358,17 @@ const applyClearing = (() => {
365
358
  let sum = 0n;
366
359
  const n = this.length;
367
360
  for (let ind = 0; ind < n; ind++)
368
- // Earlier values of `i` represent higher places same as with written numbers further left
361
+ // Earlier values of `i` are more valuable; same as how with written numbers leftmost
369
362
  // digits are more significant
370
- // The value of the place `i` is `ind - 1`
371
363
  sum += (base ** BigInt(n - ind - 1)) * cs.charVal(this[ind]);
372
364
  return sum;
373
365
  },
374
366
  [upper]: String.prototype.toUpperCase,
375
367
  });
376
- protoDefs(Number, {
377
- $: { [int32]: 2 ** 32, [int64]: 2 ** 64 },
368
+ assignSyms(Number, { [int32]: 2 ** 32, [int64]: 2 ** 64 });
369
+ assignSyms(Number.prototype, {
378
370
  [char]() { return String.fromCharCode(this); },
379
- [isInt]() { return this === Math.round(this); }, // No bitwise shortcut - it disrupts Infinity
371
+ [isInt]() { return this === Math.round(this); }, // No bitwise shortcut - it fails with +/- Infinity
380
372
  [toArr](fn) { const arr = new Array(this || 0); for (let i = 0; i < this; i++)
381
373
  arr[i] = fn(i); return arr; },
382
374
  [toObj](fn) {
@@ -394,13 +386,13 @@ const applyClearing = (() => {
394
386
  // | (n).encodeStr(singleChr)
395
387
  // is always equivalent to
396
388
  // | singleChr.repeat(n - 1)
389
+ if (this !== this)
390
+ throw Error('nan');
397
391
  if ((0, exports.isCls)(cs, String))
398
392
  cs = String[charset](cs);
399
393
  const base = cs.size;
400
394
  if (base === 1n && padLen)
401
395
  throw Error(`pad with base-1 encoding`);
402
- if (this !== this)
403
- return (base === 1n) ? '' : cs[0].repeat(Math.max(padLen, 1));
404
396
  let num = this.constructor === BigInt ? this : BigInt(Math.floor(this));
405
397
  const digits = [];
406
398
  while (num) {
@@ -409,28 +401,53 @@ const applyClearing = (() => {
409
401
  }
410
402
  return digits.reverse().join('')[padHead](padLen, cs.str[0]);
411
403
  },
404
+ [toBin]() {
405
+ if (this !== this)
406
+ throw Error('nan');
407
+ const base = 256n;
408
+ let num = this.constructor === BigInt ? this : BigInt(Math.floor(this));
409
+ const digits = [];
410
+ while (num) {
411
+ digits.push(Number(num % base));
412
+ num /= base;
413
+ }
414
+ return new Uint8Array(digits.reverse());
415
+ },
412
416
  *[Symbol.iterator]() { for (let i = 0; i < this; i++)
413
417
  yield i; },
414
- *[bits]() { let n = this >= 0 ? this : -this; while (n) {
415
- yield n & 1;
416
- n = n >> 1;
417
- } }
418
418
  });
419
- protoDefs(BigInt, { [toStr]: Number.prototype[toStr] });
420
- protoDefs(Function, {
421
- [bind](...args) { return this.bind(null, ...args); }
419
+ assignSyms(BigInt, {});
420
+ assignSyms(BigInt.prototype, { [toStr]: Number.prototype[toStr], [toBin]: Number.prototype[toBin] });
421
+ assignSyms(ArrayBuffer, {});
422
+ assignSyms(ArrayBuffer.prototype, {
423
+ [toStr]() { return dec.decode(this); },
424
+ [toNum]() { return (new Uint8Array(this))[toNum](); }
422
425
  });
423
- protoDefs(Error, {
424
- $: {
425
- [assert]: (args, fn) => {
426
- if (fn(args))
427
- return;
428
- throw Error('assert failed')[mod]({
429
- fn: `false === (${fn.toString().replace(/[\s]+/, ' ')})(args)`,
430
- args
431
- });
432
- },
433
- },
426
+ assignSyms(Uint8Array, {});
427
+ assignSyms(Uint8Array.prototype, {
428
+ [toStr]() { return dec.decode(this); },
429
+ [toNum]() {
430
+ const base = 256n;
431
+ let sum = 0n;
432
+ const n = this.length;
433
+ for (let ind = 0; ind < n; ind++)
434
+ // Earlier values of `i` are more valuable; same as how with written numbers leftmost
435
+ // digits are more significant
436
+ sum += (base ** BigInt(n - ind - 1)) * BigInt(this[ind]);
437
+ return sum;
438
+ }
439
+ });
440
+ assignSyms(Error, {
441
+ [assert]: (args, fn) => {
442
+ if (fn(args))
443
+ return;
444
+ throw Error('assert failed')[mod]({
445
+ fn: `false === (${fn.toString().replace(/[\s]+/, ' ')})(args)`,
446
+ args
447
+ });
448
+ }
449
+ });
450
+ assignSyms(Error.prototype, {
434
451
  [fire](props /* { cause, msg, message, ...more } */) { throw this[mod](props); },
435
452
  [limn](seen = new Map()) {
436
453
  if (seen.has(this))
@@ -468,27 +485,27 @@ const applyClearing = (() => {
468
485
  return this;
469
486
  }
470
487
  });
471
- protoDefs(Promise, {
472
- $: {
473
- [allArr]: arr => Promise.all(arr).then(arr => arr.filter(v => v !== exports.skip)),
474
- [allObj]: obj => {
475
- // Need to get `keys` immediately, in case `obj` mutates before resolution
476
- const keys = Object.keys(obj);
477
- return Promise.all(Object.values(obj)).then(vals => {
478
- const ret = {};
479
- for (const [i, k] of keys.entries())
480
- if (vals[i] !== exports.skip)
481
- ret[k] = vals[i];
482
- return ret;
483
- });
484
- },
485
- [later]: (resolve, reject) => {
486
- const p = new Promise((...a) => [resolve, reject] = a);
487
- return Object.assign(p, { resolve, reject });
488
- }
488
+ assignSyms(Promise, {
489
+ [allArr]: arr => Promise.all(arr).then(arr => arr.filter(v => v !== exports.skip)),
490
+ [allObj]: obj => {
491
+ // Need to get `keys` immediately, in case `obj` mutates before resolution
492
+ const keys = Object.keys(obj);
493
+ return Promise.all(Object.values(obj)).then(vals => {
494
+ const ret = {};
495
+ for (const [i, k] of keys.entries())
496
+ if (vals[i] !== exports.skip)
497
+ ret[k] = vals[i];
498
+ return ret;
499
+ });
500
+ },
501
+ [later]: (resolve, reject) => {
502
+ const p = new Promise((...a) => [resolve, reject] = a);
503
+ return Object.assign(p, { resolve, reject });
489
504
  }
490
505
  });
491
- protoDefs(Set, {
506
+ assignSyms(Promise.prototype, {});
507
+ assignSyms(Set, {});
508
+ assignSyms(Set.prototype, {
492
509
  [count]() { return this.size; },
493
510
  [empty]() { return !this.size; },
494
511
  [find](fn) {
@@ -528,7 +545,8 @@ const applyClearing = (() => {
528
545
  return Object.fromEntries(ret);
529
546
  }
530
547
  });
531
- protoDefs(Map, {
548
+ assignSyms(Map, {});
549
+ assignSyms(Map.prototype, {
532
550
  [add]: Map.prototype.set,
533
551
  [count]() { return this.size; },
534
552
  [empty]() { return !this.size; },
package/cmp/mjs/main.d.ts CHANGED
@@ -3,7 +3,7 @@ type ClsCheck = {
3
3
  (i: unknown, num: BooleanConstructor): i is boolean;
4
4
  (i: unknown, num: NumberConstructor): i is number;
5
5
  (i: unknown, str: StringConstructor): i is string;
6
- (i: unknown, buff: BufferConstructor): i is Buffer;
6
+ (i: unknown, buff: Buffer): i is Buffer;
7
7
  (i: unknown, arr: ArrayConstructor): i is any[];
8
8
  (i: unknown, obj: ObjectConstructor): i is Obj<unknown>;
9
9
  (i: unknown, fn: FunctionConstructor): i is Fn;
package/cmp/mjs/main.js CHANGED
@@ -50,6 +50,7 @@ const applyClearing = (() => {
50
50
  if (global[memSym])
51
51
  return;
52
52
  global[memSym] = true;
53
+ const [enc, dec] = [new TextEncoder(), new TextDecoder()];
53
54
  const symNames = [
54
55
  // <SYMBOLS> :: definitions :: /[']([a-zA-Z0-9]+)[']/
55
56
  'add',
@@ -64,7 +65,6 @@ const applyClearing = (() => {
64
65
  'base64Url',
65
66
  'baseline',
66
67
  'bind',
67
- 'bits',
68
68
  'char',
69
69
  'charset',
70
70
  'code',
@@ -96,6 +96,7 @@ const applyClearing = (() => {
96
96
  'slice',
97
97
  'suppress',
98
98
  'toArr',
99
+ 'toBin',
99
100
  'toNum',
100
101
  'toObj',
101
102
  'toStr',
@@ -104,29 +105,19 @@ const applyClearing = (() => {
104
105
  ];
105
106
  const syms = Object.fromEntries(symNames.map(term => [term, Symbol(`${pfx}:${term}`)]));
106
107
  Object.assign(global, { ...syms });
107
- const protoDefs = (Cls, def) => {
108
- let protoVals = [];
109
- let classVals = [];
108
+ const assignSyms = (Cls, def) => {
109
+ const protoVals = [];
110
110
  for (const key of Reflect.ownKeys(def)) {
111
- if (key !== '$' && !isCls(key, Symbol))
111
+ if (!isCls(key, Symbol))
112
112
  throw Object.assign(Error('invalid proto key'), { Cls, keyClsName: getClsName(key), key });
113
- if (key !== '$') {
114
- protoVals.push([key, def[key]]);
115
- }
116
- else {
117
- for (const k of Reflect.ownKeys(def[key])) {
118
- if (!isCls(k, Symbol))
119
- throw Object.assign(Error('invalid class key'), { Cls, keyClsName: getClsName(k), key: k });
120
- classVals.push([k, def[key][k]]);
121
- }
122
- }
113
+ protoVals.push([key, def[key]]);
123
114
  }
124
115
  // Assign class properties
125
- for (const [target, props] of [[Cls, classVals], [Cls.prototype, protoVals]])
126
- for (const [sym, value] of props)
127
- Object.defineProperty(target, sym, { enumerable: false, value });
116
+ for (const [sym, value] of protoVals)
117
+ Object.defineProperty(Cls, sym, { enumerable: false, value });
128
118
  };
129
- protoDefs(Object, {
119
+ assignSyms(Object, {});
120
+ assignSyms(Object.prototype, {
130
121
  [at](cmps, def = skip) {
131
122
  let ptr = this;
132
123
  if (!isCls(cmps, Array))
@@ -225,7 +216,8 @@ const applyClearing = (() => {
225
216
  *[Symbol.iterator]() { for (const k in this)
226
217
  yield [k, this[k]]; }
227
218
  });
228
- protoDefs(Array, {
219
+ assignSyms(Array, {});
220
+ assignSyms(Array.prototype, {
229
221
  [add](...args) { this.push(...args); return args[0]; },
230
222
  [count]() { return this.length; },
231
223
  [empty]() { return !this.length; },
@@ -278,43 +270,43 @@ const applyClearing = (() => {
278
270
  return Object.fromEntries(ret);
279
271
  }
280
272
  });
281
- protoDefs(String, {
282
- $: {
283
- [baseline]: (str, seq = '| ') => {
284
- return str.split('\n')[map](ln => {
285
- const ind = ln.indexOf(seq);
286
- if (ind === -1)
287
- return skip;
288
- return ln.slice(ind + seq.length);
289
- }).join('\n');
290
- },
291
- [base32]: '0123456789abcdefghijklmnopqrstuv',
292
- [base36]: '0123456789abcdefghijklmnopqrstuvwxyz',
293
- [base62]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
294
- [base64Url]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
295
- [base64Std]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/',
296
- [charset]: str => {
297
- const cache = new Map();
298
- return {
299
- str,
300
- size: BigInt(str.length),
301
- charVal: (c) => {
302
- if (!cache.has(c)) {
303
- const ind = str.indexOf(c);
304
- if (ind < 0)
305
- throw Error('char outside charset')[mod]({ char: c });
306
- cache.set(c, BigInt(ind));
307
- }
308
- return cache.get(c);
309
- },
310
- valChar: (n) => {
311
- if (n < 0 || n >= str.length)
312
- throw Error('val outside charset');
313
- return str[n];
314
- }
315
- };
316
- },
273
+ assignSyms(String, {
274
+ [baseline]: (str, seq = '| ') => {
275
+ return str.split('\n')[map](ln => {
276
+ const ind = ln.indexOf(seq);
277
+ if (ind === -1)
278
+ return skip;
279
+ return ln.slice(ind + seq.length);
280
+ }).join('\n');
317
281
  },
282
+ [base32]: '0123456789abcdefghijklmnopqrstuv',
283
+ [base36]: '0123456789abcdefghijklmnopqrstuvwxyz',
284
+ [base62]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
285
+ [base64Url]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
286
+ [base64Std]: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/',
287
+ [charset]: str => {
288
+ const cache = new Map();
289
+ return {
290
+ str,
291
+ size: BigInt(str.length),
292
+ charVal: (c) => {
293
+ if (!cache.has(c)) {
294
+ const ind = str.indexOf(c);
295
+ if (ind < 0)
296
+ throw Error('char outside charset')[mod]({ char: c });
297
+ cache.set(c, BigInt(ind));
298
+ }
299
+ return cache.get(c);
300
+ },
301
+ valChar: (n) => {
302
+ if (n < 0 || n >= str.length)
303
+ throw Error('val outside charset');
304
+ return str[n];
305
+ }
306
+ };
307
+ }
308
+ });
309
+ assignSyms(String.prototype, {
318
310
  [code](ind = 0) { return this.charCodeAt(ind); },
319
311
  [count]() { return this.length; },
320
312
  [cut](delim, cuts = 1) {
@@ -347,6 +339,7 @@ const applyClearing = (() => {
347
339
  [lower]: String.prototype.toLowerCase,
348
340
  [padHead]: String.prototype.padStart,
349
341
  [padTail]: String.prototype.padEnd,
342
+ [toBin]() { return enc.encode(this); },
350
343
  [toNum](cs = String[base62]) {
351
344
  if (isCls(cs, String))
352
345
  cs = String[charset](cs);
@@ -356,18 +349,17 @@ const applyClearing = (() => {
356
349
  let sum = 0n;
357
350
  const n = this.length;
358
351
  for (let ind = 0; ind < n; ind++)
359
- // Earlier values of `i` represent higher places same as with written numbers further left
352
+ // Earlier values of `i` are more valuable; same as how with written numbers leftmost
360
353
  // digits are more significant
361
- // The value of the place `i` is `ind - 1`
362
354
  sum += (base ** BigInt(n - ind - 1)) * cs.charVal(this[ind]);
363
355
  return sum;
364
356
  },
365
357
  [upper]: String.prototype.toUpperCase,
366
358
  });
367
- protoDefs(Number, {
368
- $: { [int32]: 2 ** 32, [int64]: 2 ** 64 },
359
+ assignSyms(Number, { [int32]: 2 ** 32, [int64]: 2 ** 64 });
360
+ assignSyms(Number.prototype, {
369
361
  [char]() { return String.fromCharCode(this); },
370
- [isInt]() { return this === Math.round(this); }, // No bitwise shortcut - it disrupts Infinity
362
+ [isInt]() { return this === Math.round(this); }, // No bitwise shortcut - it fails with +/- Infinity
371
363
  [toArr](fn) { const arr = new Array(this || 0); for (let i = 0; i < this; i++)
372
364
  arr[i] = fn(i); return arr; },
373
365
  [toObj](fn) {
@@ -385,13 +377,13 @@ const applyClearing = (() => {
385
377
  // | (n).encodeStr(singleChr)
386
378
  // is always equivalent to
387
379
  // | singleChr.repeat(n - 1)
380
+ if (this !== this)
381
+ throw Error('nan');
388
382
  if (isCls(cs, String))
389
383
  cs = String[charset](cs);
390
384
  const base = cs.size;
391
385
  if (base === 1n && padLen)
392
386
  throw Error(`pad with base-1 encoding`);
393
- if (this !== this)
394
- return (base === 1n) ? '' : cs[0].repeat(Math.max(padLen, 1));
395
387
  let num = this.constructor === BigInt ? this : BigInt(Math.floor(this));
396
388
  const digits = [];
397
389
  while (num) {
@@ -400,28 +392,53 @@ const applyClearing = (() => {
400
392
  }
401
393
  return digits.reverse().join('')[padHead](padLen, cs.str[0]);
402
394
  },
395
+ [toBin]() {
396
+ if (this !== this)
397
+ throw Error('nan');
398
+ const base = 256n;
399
+ let num = this.constructor === BigInt ? this : BigInt(Math.floor(this));
400
+ const digits = [];
401
+ while (num) {
402
+ digits.push(Number(num % base));
403
+ num /= base;
404
+ }
405
+ return new Uint8Array(digits.reverse());
406
+ },
403
407
  *[Symbol.iterator]() { for (let i = 0; i < this; i++)
404
408
  yield i; },
405
- *[bits]() { let n = this >= 0 ? this : -this; while (n) {
406
- yield n & 1;
407
- n = n >> 1;
408
- } }
409
409
  });
410
- protoDefs(BigInt, { [toStr]: Number.prototype[toStr] });
411
- protoDefs(Function, {
412
- [bind](...args) { return this.bind(null, ...args); }
410
+ assignSyms(BigInt, {});
411
+ assignSyms(BigInt.prototype, { [toStr]: Number.prototype[toStr], [toBin]: Number.prototype[toBin] });
412
+ assignSyms(ArrayBuffer, {});
413
+ assignSyms(ArrayBuffer.prototype, {
414
+ [toStr]() { return dec.decode(this); },
415
+ [toNum]() { return (new Uint8Array(this))[toNum](); }
413
416
  });
414
- protoDefs(Error, {
415
- $: {
416
- [assert]: (args, fn) => {
417
- if (fn(args))
418
- return;
419
- throw Error('assert failed')[mod]({
420
- fn: `false === (${fn.toString().replace(/[\s]+/, ' ')})(args)`,
421
- args
422
- });
423
- },
424
- },
417
+ assignSyms(Uint8Array, {});
418
+ assignSyms(Uint8Array.prototype, {
419
+ [toStr]() { return dec.decode(this); },
420
+ [toNum]() {
421
+ const base = 256n;
422
+ let sum = 0n;
423
+ const n = this.length;
424
+ for (let ind = 0; ind < n; ind++)
425
+ // Earlier values of `i` are more valuable; same as how with written numbers leftmost
426
+ // digits are more significant
427
+ sum += (base ** BigInt(n - ind - 1)) * BigInt(this[ind]);
428
+ return sum;
429
+ }
430
+ });
431
+ assignSyms(Error, {
432
+ [assert]: (args, fn) => {
433
+ if (fn(args))
434
+ return;
435
+ throw Error('assert failed')[mod]({
436
+ fn: `false === (${fn.toString().replace(/[\s]+/, ' ')})(args)`,
437
+ args
438
+ });
439
+ }
440
+ });
441
+ assignSyms(Error.prototype, {
425
442
  [fire](props /* { cause, msg, message, ...more } */) { throw this[mod](props); },
426
443
  [limn](seen = new Map()) {
427
444
  if (seen.has(this))
@@ -459,27 +476,27 @@ const applyClearing = (() => {
459
476
  return this;
460
477
  }
461
478
  });
462
- protoDefs(Promise, {
463
- $: {
464
- [allArr]: arr => Promise.all(arr).then(arr => arr.filter(v => v !== skip)),
465
- [allObj]: obj => {
466
- // Need to get `keys` immediately, in case `obj` mutates before resolution
467
- const keys = Object.keys(obj);
468
- return Promise.all(Object.values(obj)).then(vals => {
469
- const ret = {};
470
- for (const [i, k] of keys.entries())
471
- if (vals[i] !== skip)
472
- ret[k] = vals[i];
473
- return ret;
474
- });
475
- },
476
- [later]: (resolve, reject) => {
477
- const p = new Promise((...a) => [resolve, reject] = a);
478
- return Object.assign(p, { resolve, reject });
479
- }
479
+ assignSyms(Promise, {
480
+ [allArr]: arr => Promise.all(arr).then(arr => arr.filter(v => v !== skip)),
481
+ [allObj]: obj => {
482
+ // Need to get `keys` immediately, in case `obj` mutates before resolution
483
+ const keys = Object.keys(obj);
484
+ return Promise.all(Object.values(obj)).then(vals => {
485
+ const ret = {};
486
+ for (const [i, k] of keys.entries())
487
+ if (vals[i] !== skip)
488
+ ret[k] = vals[i];
489
+ return ret;
490
+ });
491
+ },
492
+ [later]: (resolve, reject) => {
493
+ const p = new Promise((...a) => [resolve, reject] = a);
494
+ return Object.assign(p, { resolve, reject });
480
495
  }
481
496
  });
482
- protoDefs(Set, {
497
+ assignSyms(Promise.prototype, {});
498
+ assignSyms(Set, {});
499
+ assignSyms(Set.prototype, {
483
500
  [count]() { return this.size; },
484
501
  [empty]() { return !this.size; },
485
502
  [find](fn) {
@@ -519,7 +536,8 @@ const applyClearing = (() => {
519
536
  return Object.fromEntries(ret);
520
537
  }
521
538
  });
522
- protoDefs(Map, {
539
+ assignSyms(Map, {});
540
+ assignSyms(Map.prototype, {
523
541
  [add]: Map.prototype.set,
524
542
  [count]() { return this.size; },
525
543
  [empty]() { return !this.size; },
@@ -9,6 +9,7 @@ declare global {
9
9
  type ObjMode<O extends { [K: string]: any }> = O extends { [K in infer KK]: any } ? (string extends KK ? 'map' : 'rec') : never;
10
10
  type ObjKeys<O extends Obj> = Extract<keyof O, string> | `${Extract<keyof O, number>}`; // Convert numbers to strings; ignores symbols
11
11
  type ObjVals<O extends Obj> = O[Extract<keyof O, string>];
12
+ type ObjIterator<O extends Obj> = Iterable<[ string, O[keyof O] ]>;
12
13
 
13
14
  type Json = null | boolean | number | string | Json[] | { [K: string]: Json };
14
15
  type Skip = undefined;
@@ -41,7 +42,6 @@ declare global {
41
42
  const base64Url: unique symbol;
42
43
  const baseline: unique symbol;
43
44
  const bind: unique symbol;
44
- const bits: unique symbol;
45
45
  const char: unique symbol;
46
46
  const charset: unique symbol;
47
47
  const code: unique symbol;
@@ -73,6 +73,7 @@ declare global {
73
73
  const slice: unique symbol;
74
74
  const suppress: unique symbol;
75
75
  const toArr: unique symbol;
76
+ const toBin: unique symbol;
76
77
  const toNum: unique symbol;
77
78
  const toObj: unique symbol;
78
79
  const toStr: unique symbol;
@@ -96,7 +97,6 @@ declare global {
96
97
  [base64Url]: undefined,
97
98
  [baseline]: undefined,
98
99
  [bind]: undefined,
99
- [bits]: undefined,
100
100
  [char]: undefined,
101
101
  [charset]: undefined,
102
102
  [code]: undefined,
@@ -128,6 +128,7 @@ declare global {
128
128
  [slice]: undefined,
129
129
  [suppress]: undefined,
130
130
  [toArr]: undefined,
131
+ [toBin]: undefined,
131
132
  [toNum]: undefined,
132
133
  [toObj]: undefined,
133
134
  [toStr]: undefined,
@@ -163,11 +164,6 @@ declare global {
163
164
  [group]: <G extends string>(fn: (v: T) => Skip | G) => { [K in G]?: T[] }
164
165
  }
165
166
 
166
- interface FunctionConstructor {}
167
- interface Function extends SymbolsProto {
168
- [bind]: <Fn extends (...args: any[]) => any, To>(this: Fn, to: To) => ((...args: Parameters<Fn> extends [ infer A0, ...infer AM ] ? AM : never) => ReturnType<Fn>)
169
- }
170
-
171
167
  interface NumberConstructor {
172
168
  [int32]: number,
173
169
  [int64]: number
@@ -178,13 +174,14 @@ declare global {
178
174
  [toStr]: (str: string | CharSet, len?: number) => string,
179
175
  [toArr]: <T>(fn: (n: number) => T) => T[],
180
176
  [toObj]: <R extends readonly [string, any]>(fn: (n: number) => Skip | R) => { [K: string]: any },
181
- [bits]: () => Generator<number>,
177
+ [toBin]: () => Uint8Array,
182
178
  [Symbol.iterator]: () => Generator<number>
183
179
  }
184
180
 
185
181
  interface BigIntConstructor {}
186
182
  interface BigInt extends SymbolsProto {
187
- [toStr]: (str: string | CharSet, len?: number) => string
183
+ [toStr]: (str: string | CharSet, len?: number) => string,
184
+ [toBin]: () => Uint8Array
188
185
  }
189
186
 
190
187
  interface ObjectConstructor {}
@@ -203,6 +200,18 @@ declare global {
203
200
  [Symbol.iterator]: <O extends Obj>(this: O) => Iterator<[ ObjKeys<O>, ObjVals<O> ]>
204
201
  }
205
202
 
203
+ interface ArrayBufferConstructor {}
204
+ interface ArrayBuffer {
205
+ [toStr]: () => string,
206
+ [toNum]: () => bigint
207
+ }
208
+
209
+ interface Uint8ArrayConstructor {}
210
+ interface Uint8Array {
211
+ [toStr]: () => string,
212
+ [toNum]: () => bigint
213
+ }
214
+
206
215
  interface PromiseConstructor {
207
216
  [allArr]: <V extends Promise<any>>(arr: Arr<V>) => Promise<Arr<Exclude<Awaited<V>, Skip>>>,
208
217
  [allObj]: <V extends Promise<any>>(obj: Obj<V>) => Promise<Obj<Exclude<Awaited<V>, Skip>>>,
@@ -254,6 +263,7 @@ declare global {
254
263
  [padHead]: (n: number, s?: string) => string,
255
264
  [padTail]: (n: number, s?: string) => string,
256
265
  [toNum]: (chrs: string | CharSet) => bigint,
266
+ [toBin]: () => Uint8Array,
257
267
  [hasHead]: <H extends string>(this: string, head: H) => this is `${H}${string}`,
258
268
  [hasTail]: <T extends string>(this: string, tail: T) => this is `${string}${T}`,
259
269
  [upper]: <S extends string>(this: S) => Uppercase<S>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gershy/clearing",
3
- "version": "0.0.24",
3
+ "version": "0.0.27",
4
4
  "description": "Adds the features you always wish javascript had!",
5
5
  "keywords": [
6
6
  "clearing",
package/readme.md CHANGED
@@ -621,19 +621,6 @@ Same as `Number.prototype[toStr]`, but for BigInt values.
621
621
  ```ts
622
622
  console.log((1000000000000n)[toStr](String[base62])); // 'bLY38W'
623
623
  ```
624
-
625
- ## `Function.prototype` extensions
626
-
627
- ### `Function.prototype[bind]`
628
-
629
- Partially applies arguments to a function (like `bind`, but without a `this` context).
630
-
631
- ```ts
632
- const add = (a, b, c) => a + b + c;
633
- const add10 = add[bind](10);
634
- console.log(add10(5, 3)); // 18
635
- ```
636
-
637
624
  ## `Error` extensions
638
625
 
639
626
  ### `Error[assert]`