mol_vary 0.0.5 → 0.0.6

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/node.mjs CHANGED
@@ -38,60 +38,6 @@ var $;
38
38
  $.$mol_fail = $mol_fail;
39
39
  })($ || ($ = {}));
40
40
 
41
- ;
42
- "use strict";
43
- var $;
44
- (function ($) {
45
- function $mol_hash_numbers(buff, seed = 0) {
46
- let h1 = 0xdeadbeef ^ seed;
47
- let h2 = 0x41c6ce57 ^ seed;
48
- for (let i = 0; i < buff.length; ++i) {
49
- const item = buff[i];
50
- h1 = Math.imul(h1 ^ item, 2654435761);
51
- h2 = Math.imul(h2 ^ item, 1597334677);
52
- }
53
- h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
54
- h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
55
- return 4294967296 * (((1 << 16) - 1) & h2) + (h1 >>> 0);
56
- }
57
- $.$mol_hash_numbers = $mol_hash_numbers;
58
- })($ || ($ = {}));
59
-
60
- ;
61
- "use strict";
62
- var $;
63
- (function ($) {
64
- function $mol_bigint_encode(num) {
65
- const minus = num < 0n ? 255 : 0;
66
- num = minus ? -num - 1n : num;
67
- const bytes = [];
68
- do {
69
- let byte = minus ^ Number(num % 256n);
70
- bytes.push(byte);
71
- if (num >>= 8n)
72
- continue;
73
- if ((minus & 128) !== (byte & 128))
74
- bytes.push(minus);
75
- break;
76
- } while (num);
77
- return new Uint8Array(bytes);
78
- }
79
- $.$mol_bigint_encode = $mol_bigint_encode;
80
- })($ || ($ = {}));
81
-
82
- ;
83
- "use strict";
84
- var $;
85
- (function ($) {
86
- function $mol_hash_string(str, seed = 0) {
87
- let nums = new Array(str.length);
88
- for (let i = 0; i < str.length; ++i)
89
- nums[i] = str.charCodeAt(i);
90
- return $mol_hash_numbers(nums);
91
- }
92
- $.$mol_hash_string = $mol_hash_string;
93
- })($ || ($ = {}));
94
-
95
41
  ;
96
42
  "use strict";
97
43
  var $;
@@ -166,6 +112,59 @@ var $;
166
112
  $.$mol_charset_decode = $mol_charset_decode;
167
113
  })($ || ($ = {}));
168
114
 
115
+ ;
116
+ "use strict";
117
+ var $;
118
+ (function ($) {
119
+ function $mol_charset_decode_from(buffer, from, count) {
120
+ let res = '';
121
+ let pos = from;
122
+ while (pos < buffer.length && res.length < count) {
123
+ const byte1 = buffer[pos++];
124
+ if (byte1 <= 0x7F) {
125
+ res += String.fromCharCode(byte1);
126
+ }
127
+ else if ((byte1 & 0xE0) === 0xC0) {
128
+ if (pos >= buffer.length)
129
+ break;
130
+ const byte2 = buffer[pos++];
131
+ let code = ((byte1 & 0x1F) << 6) | (byte2 & 0x3F);
132
+ res += String.fromCharCode(code);
133
+ }
134
+ else if ((byte1 & 0xF0) === 0xE0) {
135
+ if (pos + 1 >= buffer.length)
136
+ break;
137
+ const byte2 = buffer[pos++];
138
+ const byte3 = buffer[pos++];
139
+ let code = ((byte1 & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F);
140
+ res += String.fromCharCode(code);
141
+ }
142
+ else if ((byte1 & 0xF8) === 0xF0) {
143
+ if (pos + 2 >= buffer.length)
144
+ break;
145
+ const byte2 = buffer[pos++];
146
+ const byte3 = buffer[pos++];
147
+ const byte4 = buffer[pos++];
148
+ let code = ((byte1 & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F);
149
+ if (code > 0xFFFF) {
150
+ code -= 0x10000;
151
+ const hi = 0xD800 + (code >> 10);
152
+ const lo = 0xDC00 + (code & 0x3FF);
153
+ res += String.fromCharCode(hi, lo);
154
+ }
155
+ else {
156
+ res += String.fromCharCode(code);
157
+ }
158
+ }
159
+ else {
160
+ res += '�';
161
+ }
162
+ }
163
+ return [res, pos - from];
164
+ }
165
+ $.$mol_charset_decode_from = $mol_charset_decode_from;
166
+ })($ || ($ = {}));
167
+
169
168
  ;
170
169
  "use strict";
171
170
  var $;
@@ -197,319 +196,286 @@ var $;
197
196
  $mol_vary_spec[$mol_vary_spec["fp32"] = 94] = "fp32";
198
197
  $mol_vary_spec[$mol_vary_spec["fp64"] = 95] = "fp64";
199
198
  })($mol_vary_spec = $.$mol_vary_spec || ($.$mol_vary_spec = {}));
200
- function num_len(num) {
201
- if (typeof num === 'number' && !Number.isInteger(num))
202
- return 8;
203
- if (num < 0) {
204
- if (num >= -28)
205
- return 0;
206
- if (num >= -(2 ** 7))
207
- return 1;
208
- if (num >= -(2 ** 15))
209
- return 2;
210
- if (num >= -(2 ** 31))
211
- return 4;
212
- if (num >= -(2n ** 63n))
213
- return 8;
214
- $mol_fail(new Error(`Too low numb ${num}`));
215
- }
216
- else {
217
- if (num < 28)
218
- return 0;
219
- if (num < 2 ** 8)
220
- return 1;
221
- if (num < 2 ** 16)
222
- return 2;
223
- if (num < 2 ** 32)
224
- return 4;
225
- if (num < 2n ** 64n)
226
- return 8;
227
- $mol_fail(new Error(`Too high numb ${num}`));
228
- }
229
- }
199
+ let offsets = new Map();
200
+ let sizes = new Map();
230
201
  class $mol_vary extends DataView {
231
- static buffer = new Uint8Array(4096);
232
- static buffer_view = new this(this.buffer.buffer);
233
- static allocate(size) {
234
- if (this.buffer.byteLength > size)
235
- return;
236
- this.buffer = new Uint8Array(Math.ceil(size / 4096) * 4096);
237
- this.buffer_view = new this(this.buffer.buffer);
238
- }
239
202
  static pack(data) {
240
- const leaned = new WeakMap();
241
- const lean = (val) => {
242
- let tupl = leaned.get(val);
243
- if (tupl)
244
- return tupl;
245
- leaned.set(val, tupl = this.lean(val));
246
- return tupl;
203
+ let pos = 0;
204
+ let capacity = 0;
205
+ const acquire = (size) => {
206
+ capacity += size;
207
+ if (buffer.byteLength >= capacity)
208
+ return;
209
+ const buffer2 = new Uint8Array(Math.ceil(capacity / 4096) * 4096);
210
+ buffer2.set(buffer);
211
+ buffer = buffer2;
212
+ pack = new DataView(buffer.buffer);
247
213
  };
248
- const hashes = new Map();
249
- const hash = (val) => {
250
- switch (typeof val) {
251
- case 'undefined':
252
- return 0;
253
- case 'number':
254
- case 'boolean':
255
- return Number(val);
256
- case 'number':
257
- return val;
258
- case 'bigint':
259
- return $mol_hash_numbers($mol_bigint_encode(val), $mol_vary_tip.sint);
260
- case 'string': {
261
- let res = hashes.get(val);
262
- if (res != null)
263
- return res;
264
- res = $mol_hash_string(val, $mol_vary_tip.text);
265
- hashes.set(val, res);
266
- return res;
267
- }
268
- case 'object': {
269
- if (!val)
270
- return $mol_vary_spec.none;
271
- let res = hashes.get(val);
272
- if (res != null)
273
- return res;
274
- if (ArrayBuffer.isView(val))
275
- res = $mol_hash_numbers(new Uint8Array(val.buffer, val.byteOffset, val.byteLength), $mol_vary_tip.blob);
276
- else if (Array.isArray(val))
277
- res = $mol_hash_numbers(val.map(hash), $mol_vary_tip.list);
278
- else {
279
- const [keys, vals] = lean(val);
280
- res = $mol_hash_numbers(vals.map(hash), hash(keys));
281
- }
282
- hashes.set(val, res);
283
- return res;
284
- }
214
+ const release = (size) => {
215
+ capacity -= size;
216
+ };
217
+ const dump_snum = (tip, val) => {
218
+ if (val >= -28) {
219
+ pack.setInt8(pos++, tip | Number(val));
220
+ release(9);
221
+ }
222
+ else if (val >= -(2 ** 7)) {
223
+ pack.setInt8(pos++, tip | (-1 - $.$mol_vary_len[1]));
224
+ pack.setInt8(pos, Number(val));
225
+ pos += 1;
226
+ release(8);
227
+ }
228
+ else if (val >= -(2 ** 15)) {
229
+ pack.setInt8(pos++, tip | (-1 - $.$mol_vary_len[2]));
230
+ pack.setInt16(pos, Number(val), true);
231
+ pos += 2;
232
+ release(7);
233
+ }
234
+ else if (val >= -(2 ** 31)) {
235
+ pack.setInt8(pos++, tip | (-1 - $.$mol_vary_len[4]));
236
+ pack.setInt32(pos, Number(val), true);
237
+ pos += 4;
238
+ release(5);
239
+ }
240
+ else if (val >= -(2n ** 63n)) {
241
+ pack.setInt8(pos++, tip | (-1 - $.$mol_vary_len[8]));
242
+ pack.setBigInt64(pos, BigInt(val), true);
243
+ pos += 8;
244
+ release(1);
245
+ }
246
+ else {
247
+ $mol_fail(new Error('Number too low', { cause: val }));
285
248
  }
286
- $mol_fail(new Error(`Unsupported type`));
287
249
  };
288
- let size = 0;
289
- const offsets = new Map();
290
- const sizes = new Map();
291
- const stream = [];
292
- const dedup = (val, len) => {
293
- const key = hash(val);
294
- let offset = offsets.get(key);
295
- if (offset === undefined) {
296
- offsets.set(key, offset = stream.length);
297
- stream.push(val);
298
- size += len;
299
- return true;
250
+ const dump_unum = (tip, val) => {
251
+ if (val < 28) {
252
+ pack.setUint8(pos++, tip | Number(val));
253
+ release(9);
254
+ }
255
+ else if (val < 2 ** 8) {
256
+ pack.setUint8(pos++, tip | $.$mol_vary_len[1]);
257
+ pack.setUint8(pos, Number(val));
258
+ pos += 1;
259
+ release(8);
260
+ }
261
+ else if (val < 2 ** 16) {
262
+ pack.setUint8(pos++, tip | $.$mol_vary_len[2]);
263
+ pack.setUint16(pos, Number(val), true);
264
+ pos += 2;
265
+ release(7);
266
+ }
267
+ else if (val < 2 ** 32) {
268
+ pack.setUint8(pos++, tip | $.$mol_vary_len[4]);
269
+ pack.setUint32(pos, Number(val), true);
270
+ pos += 4;
271
+ release(5);
272
+ }
273
+ else if (val < 2n ** 64n) {
274
+ pack.setUint8(pos++, tip | $.$mol_vary_len[8]);
275
+ pack.setBigUint64(pos, BigInt(val), true);
276
+ pos += 8;
277
+ release(1);
300
278
  }
301
279
  else {
302
- size += 1 + num_len(offset);
303
- return false;
280
+ $mol_fail(new Error('Number too high', { cause: val }));
304
281
  }
305
282
  };
306
- const calc = (val) => {
307
- if (val == null) {
308
- size += 1;
309
- return true;
283
+ const dump_string = (val) => {
284
+ if (val.length) {
285
+ const offset = offsets.get(val);
286
+ if (offset !== undefined)
287
+ return dump_unum($mol_vary_tip.link, offset);
310
288
  }
311
- switch (typeof val) {
312
- case 'boolean':
313
- size += 1;
314
- return true;
315
- case 'number':
316
- case 'bigint':
317
- size += 1 + num_len(val);
318
- return true;
319
- case 'string': {
320
- let len = sizes.get(val);
321
- if (len == null)
322
- sizes.set(val, len = $mol_charset_encode_size(val));
323
- if (!len) {
324
- size += 1;
325
- return true;
326
- }
327
- return dedup(val, 1 + num_len(len) + len);
328
- }
329
- case 'object': {
330
- if (ArrayBuffer.isView(val)) {
331
- if (!val.byteLength) {
332
- size += 2;
333
- return true;
334
- }
335
- return dedup(val, 2 + num_len(val.byteLength) + val.byteLength);
336
- }
337
- if (Array.isArray(val)) {
338
- if (!val.length) {
339
- size += 1;
340
- return true;
341
- }
342
- const key = hash(val);
343
- let offset = offsets.get(key);
344
- if (offset === undefined) {
345
- for (const item of val)
346
- calc(item);
347
- }
348
- return dedup(val, 1 + num_len(val.length));
349
- }
350
- const [keys, vals] = lean(val);
351
- if (!vals.length) {
352
- size += 2;
353
- return true;
354
- }
355
- const key = hash(val);
356
- let offset = offsets.get(key);
357
- if (offset === undefined) {
358
- calc(keys);
359
- for (const item of vals)
360
- calc(item);
361
- }
362
- return dedup(val, 1 + num_len(vals.length));
363
- }
289
+ dump_unum($mol_vary_tip.text, val.length);
290
+ acquire(val.length * 3);
291
+ const len = $mol_charset_encode_to(val, buffer, pos);
292
+ pos += len;
293
+ release(val.length * 3 - len - 1);
294
+ if (val.length)
295
+ offsets.set(val, offsets.size);
296
+ return;
297
+ };
298
+ const dump_buffer = (val) => {
299
+ if (val.byteLength) {
300
+ const offset = offsets.get(val);
301
+ if (offset !== undefined)
302
+ return dump_unum($mol_vary_tip.link, offset);
364
303
  }
365
- $mol_fail(new Error(`Unsupported type`));
304
+ dump_unum($mol_vary_tip.blob, val.byteLength);
305
+ if (val instanceof Uint8Array)
306
+ pack.setUint8(pos++, $mol_vary_tip.uint | $.$mol_vary_len[1]);
307
+ else if (val instanceof Uint16Array)
308
+ pack.setUint8(pos++, $mol_vary_tip.uint | $.$mol_vary_len[2]);
309
+ else if (val instanceof Uint32Array)
310
+ pack.setUint8(pos++, $mol_vary_tip.uint | $.$mol_vary_len[4]);
311
+ else if (val instanceof BigUint64Array)
312
+ pack.setUint8(pos++, $mol_vary_tip.uint | $.$mol_vary_len[8]);
313
+ else if (val instanceof Int8Array)
314
+ pack.setUint8(pos++, $mol_vary_tip.sint | ~$.$mol_vary_len[1]);
315
+ else if (val instanceof Int16Array)
316
+ pack.setUint8(pos++, $mol_vary_tip.sint | ~$.$mol_vary_len[2]);
317
+ else if (val instanceof Int32Array)
318
+ pack.setUint8(pos++, $mol_vary_tip.sint | ~$.$mol_vary_len[4]);
319
+ else if (val instanceof BigInt64Array)
320
+ pack.setUint8(pos++, $mol_vary_tip.sint | ~$.$mol_vary_len[8]);
321
+ else if (val instanceof Float32Array)
322
+ pack.setUint8(pos++, $mol_vary_spec.fp32);
323
+ else if (val instanceof Float64Array)
324
+ pack.setUint8(pos++, $mol_vary_spec.fp64);
325
+ else
326
+ $mol_fail(new Error(`Unsupported type`));
327
+ const src = (val instanceof Uint8Array) ? val : new Uint8Array(val.buffer, val.byteOffset, val.byteLength);
328
+ acquire(val.byteLength);
329
+ buffer.set(src, pos);
330
+ pos += val.byteLength;
331
+ if (val.byteLength)
332
+ offsets.set(val, offsets.size);
333
+ };
334
+ const dump_list = (val) => {
335
+ if (val.length) {
336
+ const offset = offsets.get(val);
337
+ if (offset !== undefined)
338
+ return dump_unum($mol_vary_tip.link, offset);
339
+ }
340
+ dump_unum($mol_vary_tip.list, val.length);
341
+ acquire(val.length * 10);
342
+ for (const item of val)
343
+ dump(item);
344
+ if (val.length)
345
+ offsets.set(val, offsets.size);
346
+ };
347
+ const dump_object = (val) => {
348
+ const offset = offsets.get(val);
349
+ if (offset !== undefined)
350
+ return dump_unum($mol_vary_tip.link, offset);
351
+ const proto = Reflect.getPrototypeOf(val);
352
+ const lean = this.leanes.get(proto);
353
+ const keys = lean ? this.keys.get(proto) : Object.keys(val);
354
+ const vals = lean ? lean(val) : Object.values(val);
355
+ dump_unum($mol_vary_tip.tupl, vals.length);
356
+ acquire(vals.length * 2 * 10);
357
+ for (const item of keys)
358
+ dump(item);
359
+ for (const item of vals)
360
+ dump(item);
361
+ if (vals.length)
362
+ offsets.set(val, offsets.size);
366
363
  };
367
- calc(data);
368
- this.allocate(size);
369
- const buf = this.buffer;
370
- const pack = this.buffer_view;
371
- const embedded = new Set();
372
- let pos = 0;
373
364
  const dump = (val) => {
374
- if (pos >= size)
375
- $mol_fail(new Error('Wrong buffer length', { cause: buf }));
376
365
  switch (typeof val) {
377
366
  case 'undefined': {
378
- pack.tlen(pos, 'spec', $mol_vary_spec.both);
379
- pos += 1;
367
+ pack.setUint8(pos++, $mol_vary_spec.both);
368
+ release(9);
380
369
  return;
381
370
  }
382
371
  case 'boolean': {
383
- pack.tlen(pos, 'spec', val ? $mol_vary_spec.true : $mol_vary_spec.fake);
384
- pos += 1;
372
+ pack.setUint8(pos++, val ? $mol_vary_spec.true : $mol_vary_spec.fake);
373
+ release(9);
385
374
  return;
386
375
  }
387
376
  case 'number': {
388
377
  if (!Number.isInteger(val)) {
389
- pos += pack.tfp(pos, 'spec', val);
390
- }
391
- else if (val < 0) {
392
- pos += pack.tint(pos, 'sint', val);
393
- }
394
- else {
395
- pos += pack.tnat(pos, 'uint', val);
378
+ pack.setUint8(pos++, $mol_vary_spec.fp64);
379
+ pack.setFloat64(pos, val, true);
380
+ pos += 8;
381
+ release(1);
382
+ return;
396
383
  }
397
- return;
398
384
  }
399
385
  case 'bigint': {
400
386
  if (val < 0) {
401
- pos += pack.tint(pos, 'sint', val);
387
+ dump_snum($mol_vary_tip.sint, val);
402
388
  }
403
389
  else {
404
- pos += pack.tnat(pos, 'uint', val);
405
- }
406
- return;
407
- }
408
- case 'string': {
409
- const key = hash(val);
410
- if (embedded.has(key)) {
411
- pos += pack.tnat(pos, 'link', offsets.get(key));
412
- return;
390
+ dump_unum($mol_vary_tip.uint, val);
413
391
  }
414
- pos += pack.tnat(pos, 'text', sizes.get(val));
415
- pos += $mol_charset_encode_to(val, buf, pos);
416
- if (val.length)
417
- embedded.add(key);
418
392
  return;
419
393
  }
394
+ case 'string': return dump_string(val);
420
395
  case 'object': {
421
396
  if (!val) {
422
- pack.tlen(pos, 'spec', $mol_vary_spec.none);
423
- pos += 1;
424
- return;
397
+ release(9);
398
+ return pack.setUint8(pos++, $mol_vary_spec.none);
425
399
  }
426
- if (ArrayBuffer.isView(val)) {
427
- const key = hash(val);
428
- if (embedded.has(key)) {
429
- pos += pack.tnat(pos, 'link', offsets.get(key));
430
- return;
431
- }
432
- pos += pack.tnat(pos, 'blob', val.byteLength);
433
- if (val instanceof Uint8Array)
434
- pos += pack.tlen(pos, 'uint', $.$mol_vary_len[1]);
435
- else if (val instanceof Uint16Array)
436
- pos += pack.tlen(pos, 'uint', $.$mol_vary_len[2]);
437
- else if (val instanceof Uint32Array)
438
- pos += pack.tlen(pos, 'uint', $.$mol_vary_len[4]);
439
- else if (val instanceof BigUint64Array)
440
- pos += pack.tlen(pos, 'uint', $.$mol_vary_len[8]);
441
- else if (val instanceof Int8Array)
442
- pos += pack.tlen(pos, 'sint', ~$.$mol_vary_len[1]);
443
- else if (val instanceof Int16Array)
444
- pos += pack.tlen(pos, 'sint', ~$.$mol_vary_len[2]);
445
- else if (val instanceof Int32Array)
446
- pos += pack.tlen(pos, 'sint', ~$.$mol_vary_len[4]);
447
- else if (val instanceof BigInt64Array)
448
- pos += pack.tlen(pos, 'sint', ~$.$mol_vary_len[8]);
449
- else if (val instanceof Float32Array)
450
- pos += pack.tlen(pos, 'spec', $mol_vary_spec.fp32);
451
- else if (val instanceof Float64Array)
452
- pos += pack.tlen(pos, 'spec', $mol_vary_spec.fp64);
453
- else
454
- $mol_fail(new Error(`Unsupported type`));
455
- buf.set(new Uint8Array(val.buffer, val.byteOffset, val.byteLength), pos);
456
- pos += val.byteLength;
457
- if (val.byteLength)
458
- embedded.add(key);
459
- return;
460
- }
461
- if (Array.isArray(val)) {
462
- const key = hash(val);
463
- if (embedded.has(key)) {
464
- pos += pack.tnat(pos, 'link', offsets.get(key));
465
- return;
466
- }
467
- pos += pack.tnat(pos, 'list', val.length);
468
- for (const item of val)
469
- dump(item);
470
- if (val.length)
471
- embedded.add(key);
472
- return;
473
- }
474
- const key = hash(val);
475
- if (embedded.has(key)) {
476
- pos += pack.tnat(pos, 'link', offsets.get(key));
477
- return;
478
- }
479
- const [keys, vals] = lean(val);
480
- pos += pack.tnat(pos, 'tupl', vals.length);
481
- dump(keys);
482
- for (const item of vals)
483
- dump(item);
484
- if (vals.length)
485
- embedded.add(key);
486
- return;
400
+ if (ArrayBuffer.isView(val))
401
+ return dump_buffer(val);
402
+ if (Array.isArray(val))
403
+ return dump_list(val);
404
+ return dump_object(val);
487
405
  }
488
406
  }
489
407
  $mol_fail(new Error(`Unsupported type`));
490
408
  };
491
409
  dump(data);
492
- return buf.slice(0, size);
410
+ offsets = new Map;
411
+ sizes = new Map;
412
+ return buffer.slice(0, pos);
493
413
  }
494
414
  static take(buf) {
495
415
  const pack = new $mol_vary(buf.buffer, buf.byteOffset, buf.byteLength);
496
416
  const stream = [];
497
417
  let pos = 0;
498
- const read_unum = () => {
499
- const num = pack.unum(pos);
500
- pos += 1 + pack.ulen(pos);
501
- return num;
418
+ const read_unum = (kind) => {
419
+ ++pos;
420
+ const num = kind & 0b11111;
421
+ if (num < 28)
422
+ return num;
423
+ let res = 0;
424
+ if (num === 28) {
425
+ res = pack.getUint8(pos);
426
+ pos += 1;
427
+ }
428
+ else if (num === 29) {
429
+ res = pack.getUint16(pos, true);
430
+ pos += 2;
431
+ }
432
+ else if (num === 30) {
433
+ res = pack.getUint32(pos, true);
434
+ pos += 4;
435
+ }
436
+ else if (num === 31) {
437
+ res = pack.getBigUint64(pos, true);
438
+ if (res <= Number.MAX_SAFE_INTEGER)
439
+ res = Number(res);
440
+ pos += 8;
441
+ }
442
+ else {
443
+ $mol_fail(new Error('Unsupported unum', { cause: { num } }));
444
+ }
445
+ return res;
502
446
  };
503
- const read_snum = () => {
504
- const num = pack.snum(pos);
505
- pos += 1 + pack.slen(pos);
506
- return num;
447
+ const read_snum = (kind) => {
448
+ const num = pack.getInt8(pos++);
449
+ if (num >= -28)
450
+ return num;
451
+ let res = 0;
452
+ if (num === -29) {
453
+ res = pack.getInt8(pos);
454
+ pos += 1;
455
+ }
456
+ else if (num === -30) {
457
+ res = pack.getInt16(pos, true);
458
+ pos += 2;
459
+ }
460
+ else if (num === -31) {
461
+ res = pack.getInt32(pos, true);
462
+ pos += 4;
463
+ }
464
+ else if (num === -32) {
465
+ res = pack.getBigInt64(pos, true);
466
+ if (res >= Number.MIN_SAFE_INTEGER && res <= Number.MAX_SAFE_INTEGER)
467
+ res = Number(res);
468
+ pos += 8;
469
+ }
470
+ else {
471
+ $mol_fail(new Error('Unsupported snum', { cause: { num } }));
472
+ }
473
+ return res;
507
474
  };
508
- const read_text = () => {
509
- const len = read_unum();
510
- const bin = new Uint8Array(buf.buffer, pack.byteOffset + pos, len);
511
- pos += len;
512
- const text = $mol_charset_decode(bin);
475
+ const read_text = (kind) => {
476
+ const len = read_unum(kind);
477
+ const [text, bytes] = $mol_charset_decode_from(buf, pack.byteOffset + pos, len);
478
+ pos += bytes;
513
479
  if (text.length)
514
480
  stream.push(text);
515
481
  return text;
@@ -521,79 +487,90 @@ var $;
521
487
  stream.push(bin);
522
488
  return bin;
523
489
  };
524
- const read_blob = () => {
525
- const len = read_unum();
526
- const kind = pack.getUint8(pos++);
527
- switch (kind) {
528
- case $mol_vary_tip.uint | $.$mol_vary_len[1]: return read_buffer(len, Uint8Array);
529
- case $mol_vary_tip.uint | $.$mol_vary_len[2]: return read_buffer(len, Uint16Array);
530
- case $mol_vary_tip.uint | $.$mol_vary_len[4]: return read_buffer(len, Uint32Array);
531
- case $mol_vary_tip.uint | $.$mol_vary_len[8]: return read_buffer(len, BigUint64Array);
532
- case $mol_vary_tip.sint | ~$.$mol_vary_len[1] + 256: return read_buffer(len, Int8Array);
533
- case $mol_vary_tip.sint | ~$.$mol_vary_len[2] + 256: return read_buffer(len, Int16Array);
534
- case $mol_vary_tip.sint | ~$.$mol_vary_len[4] + 256: return read_buffer(len, Int32Array);
535
- case $mol_vary_tip.sint | ~$.$mol_vary_len[8] + 256: return read_buffer(len, BigInt64Array);
490
+ const read_blob = (kind) => {
491
+ const len = read_unum(kind);
492
+ const kind_item = pack.getUint8(pos++);
493
+ switch (kind_item) {
494
+ case $.$mol_vary_len[1]: return read_buffer(len, Uint8Array);
495
+ case $.$mol_vary_len[2]: return read_buffer(len, Uint16Array);
496
+ case $.$mol_vary_len[4]: return read_buffer(len, Uint32Array);
497
+ case $.$mol_vary_len[8]: return read_buffer(len, BigUint64Array);
498
+ case ~$.$mol_vary_len[1] + 256: return read_buffer(len, Int8Array);
499
+ case ~$.$mol_vary_len[2] + 256: return read_buffer(len, Int16Array);
500
+ case ~$.$mol_vary_len[4] + 256: return read_buffer(len, Int32Array);
501
+ case ~$.$mol_vary_len[8] + 256: return read_buffer(len, BigInt64Array);
502
+ case $mol_vary_tip.spec | $mol_vary_spec.fp16: return read_buffer(len, Float16Array);
536
503
  case $mol_vary_tip.spec | $mol_vary_spec.fp32: return read_buffer(len, Float32Array);
537
504
  case $mol_vary_tip.spec | $mol_vary_spec.fp64: return read_buffer(len, Float64Array);
538
505
  default:
539
- $mol_fail(new Error('Unsupported blob kind', { cause: { kind } }));
506
+ $mol_fail(new Error('Unsupported blob item kind', { cause: { kind_item } }));
540
507
  }
541
508
  };
542
- const read_list = () => {
543
- const len = read_unum();
544
- const list = [];
509
+ const read_list = (kind) => {
510
+ const len = read_unum(kind);
511
+ const list = new Array(len);
545
512
  for (let i = 0; i < len; ++i)
546
- list.push(read_vary());
513
+ list[i] = read_vary();
547
514
  if (len)
548
515
  stream.push(list);
549
516
  return list;
550
517
  };
551
- const read_link = () => {
552
- const index = read_unum();
518
+ const read_link = (kind) => {
519
+ const index = read_unum(kind);
553
520
  if (index >= stream.length)
554
521
  $mol_fail(new Error('Too large index', { cause: { index, exists: stream.length } }));
555
522
  return stream[index];
556
523
  };
557
- const read_tupl = () => {
558
- const len = read_unum();
559
- const keys = pack.tip(pos) === 'link' ? read_link() : read_list();
560
- if (!Array.isArray(keys))
561
- $mol_fail(new Error('Wrong tupl shape type', { cause: { type: typeof keys } }));
562
- const vals = Array.from({ length: len }, () => read_vary());
563
- const obj = this.rich(keys, vals);
524
+ const read_tupl = (kind) => {
525
+ const len = read_unum(kind);
526
+ const keys = new Array(len);
527
+ const vals = new Array(len);
528
+ for (let i = 0; i < len; ++i)
529
+ keys[i] = read_vary();
530
+ for (let i = 0; i < len; ++i)
531
+ vals[i] = read_vary();
532
+ const shape = JSON.stringify([keys, vals.map(v => typeof v)]);
533
+ let obj;
534
+ const rich = this.riches.get(shape);
535
+ if (rich) {
536
+ obj = rich(...vals);
537
+ }
538
+ else {
539
+ obj = {};
540
+ for (let i = 0; i < len; ++i)
541
+ obj[keys[i]] = vals[i];
542
+ }
564
543
  if (vals.length)
565
544
  stream.push(obj);
566
545
  return obj;
567
546
  };
568
- const read_spec = () => {
569
- const kind = pack.getUint8(pos);
570
- const spec = $mol_vary_spec[kind];
571
- switch (spec) {
572
- case 'none':
547
+ const read_spec = (kind) => {
548
+ switch (kind) {
549
+ case $mol_vary_spec.none:
573
550
  ++pos;
574
551
  return null;
575
- case 'fake':
552
+ case $mol_vary_spec.fake:
576
553
  ++pos;
577
554
  return false;
578
- case 'true':
555
+ case $mol_vary_spec.true:
579
556
  ++pos;
580
557
  return true;
581
- case 'both':
558
+ case $mol_vary_spec.both:
582
559
  ++pos;
583
560
  return undefined;
584
- case 'fp16': {
585
- const val = pack.getFloat16(pos + 1, true);
586
- pos += 3;
561
+ case $mol_vary_spec.fp64: {
562
+ const val = pack.getFloat64(++pos, true);
563
+ pos += 8;
587
564
  return val;
588
565
  }
589
- case 'fp32': {
590
- const val = pack.getFloat32(pos + 1, true);
591
- pos += 5;
566
+ case $mol_vary_spec.fp32: {
567
+ const val = pack.getFloat32(++pos, true);
568
+ pos += 4;
592
569
  return val;
593
570
  }
594
- case 'fp64': {
595
- const val = pack.getFloat64(pos + 1, true);
596
- pos += 9;
571
+ case $mol_vary_spec.fp16: {
572
+ const val = pack.getFloat16(++pos, true);
573
+ pos += 2;
597
574
  return val;
598
575
  }
599
576
  default:
@@ -601,181 +578,41 @@ var $;
601
578
  }
602
579
  };
603
580
  const read_vary = () => {
604
- const tip = pack.tip(pos);
581
+ const kind = pack.getUint8(pos);
582
+ const tip = kind & 0b111_00000;
605
583
  switch (tip) {
606
- case 'uint': return read_unum();
607
- case 'sint': return read_snum();
608
- case 'link': return read_link();
609
- case 'text': return read_text();
610
- case 'list': return read_list();
611
- case 'blob': return read_blob();
612
- case 'tupl': return read_tupl();
613
- case 'spec': return read_spec();
584
+ case $mol_vary_tip.uint: return read_unum(kind);
585
+ case $mol_vary_tip.sint: return read_snum(kind);
586
+ case $mol_vary_tip.link: return read_link(kind);
587
+ case $mol_vary_tip.text: return read_text(kind);
588
+ case $mol_vary_tip.list: return read_list(kind);
589
+ case $mol_vary_tip.blob: return read_blob(kind);
590
+ case $mol_vary_tip.tupl: return read_tupl(kind);
591
+ case $mol_vary_tip.spec: return read_spec(kind);
614
592
  default: $mol_fail(new Error('Unsupported tip', { cause: { tip } }));
615
593
  }
616
594
  };
617
595
  return read_vary();
618
596
  }
619
- tlen(pos, tip, len) {
620
- this.setUint8(pos, $mol_vary_tip[tip] | len);
621
- return 1;
622
- }
623
- tnat(pos, tip, num) {
624
- const len = num_len(num);
625
- this.tlen(pos, tip, len ? $.$mol_vary_len[len] : Number(num));
626
- switch (len) {
627
- case 0: break;
628
- case 1:
629
- this.setUint8(pos + 1, Number(num));
630
- break;
631
- case 2:
632
- this.setUint16(pos + 1, Number(num), true);
633
- break;
634
- case 4:
635
- this.setUint32(pos + 1, Number(num), true);
636
- break;
637
- case 8:
638
- this.setBigUint64(pos + 1, BigInt(num), true);
639
- break;
640
- default: $mol_fail(new Error('Unsupported uint len', { cause: { len } }));
641
- }
642
- return 1 + len;
643
- }
644
- tint(pos, tip, num) {
645
- const len = num_len(num);
646
- this.tlen(pos, tip, len ? -$.$mol_vary_len[len] - 1 : Number(num));
647
- switch (len) {
648
- case 0: break;
649
- case 1:
650
- this.setInt8(pos + 1, Number(num));
651
- break;
652
- case 2:
653
- this.setInt16(pos + 1, Number(num), true);
654
- break;
655
- case 4:
656
- this.setInt32(pos + 1, Number(num), true);
657
- break;
658
- case 8:
659
- this.setBigInt64(pos + 1, BigInt(num), true);
660
- break;
661
- default: $mol_fail(new Error('Unsupported sint len', { cause: { len } }));
662
- }
663
- return 1 + len;
664
- }
665
- tfp(pos, tip, num) {
666
- const len = num_len(num);
667
- this.tlen(pos, tip, len ? $.$mol_vary_len[len] : Number(num));
668
- switch (len) {
669
- case 2:
670
- this.setFloat16(pos + 1, num, true);
671
- break;
672
- case 4:
673
- this.setFloat32(pos + 1, num, true);
674
- break;
675
- case 8:
676
- this.setFloat64(pos + 1, num, true);
677
- break;
678
- default: $mol_fail(new Error('Unsupported fp len', { cause: { len } }));
679
- }
680
- return 1 + len;
681
- }
682
- tip(pos) {
683
- return $mol_vary_tip[this.getUint8(pos) & 0b111_00000];
684
- }
685
- ulen(pos) {
686
- const num = this.getUint8(pos) & 0b11111;
687
- if (num < 28)
688
- return 0;
689
- switch (num) {
690
- case 28: return 1;
691
- case 29: return 2;
692
- case 30: return 4;
693
- case 31: return 8;
694
- default: $mol_fail(new Error('Impossible!'));
695
- }
696
- }
697
- slen(pos) {
698
- const num = this.getInt8(pos);
699
- if (num > -29)
700
- return 0;
701
- switch (num) {
702
- case -29: return 1;
703
- case -30: return 2;
704
- case -31: return 4;
705
- case -32: return 8;
706
- default: $mol_fail(new Error('Impossible!'));
707
- }
708
- }
709
- unum(pos) {
710
- const num = this.getUint8(pos) & 0b11111;
711
- if (num < 28)
712
- return num;
713
- switch (num) {
714
- case 28: return this.getUint8(pos + 1);
715
- case 29: return this.getUint16(pos + 1, true);
716
- case 30: return this.getUint32(pos + 1, true);
717
- case 31:
718
- const val = this.getBigUint64(pos + 1, true);
719
- if (val > Number.MAX_SAFE_INTEGER)
720
- return val;
721
- return Number(val);
722
- default: $mol_fail(new Error('Unsupported len', { cause: { num } }));
723
- }
724
- }
725
- snum(pos) {
726
- const num = this.getInt8(pos);
727
- if (num > -29)
728
- return num;
729
- switch (num) {
730
- case -29: return this.getInt8(pos + 1);
731
- case -30: return this.getInt16(pos + 1, true);
732
- case -31: return this.getInt32(pos + 1, true);
733
- case -32:
734
- const val = this.getBigInt64(pos + 1, true);
735
- if (val > Number.MAX_SAFE_INTEGER)
736
- return val;
737
- if (val < Number.MIN_SAFE_INTEGER)
738
- return val;
739
- return Number(val);
740
- default: $mol_fail(new Error('Unsupported len', { cause: { num } }));
741
- }
742
- }
743
- static rich(keys, vals) {
744
- const shape = JSON.stringify([keys, vals.map(v => typeof v)]);
745
- const rich = this.riches.get(shape);
746
- if (rich)
747
- return rich(...vals);
748
- const pairs = keys.map((key, index) => [key, vals[index]]);
749
- const obj = Object.fromEntries(pairs);
750
- return obj;
751
- }
752
- static lean(val) {
753
- const proto = Reflect.getPrototypeOf(val);
754
- const lean = this.leanes.get(proto);
755
- if (lean)
756
- return lean(val);
757
- return [Object.keys(val), Object.values(val)];
758
- }
759
597
  static leanes = new Map();
598
+ static keys = new Map();
760
599
  static riches = new Map();
761
- static type(rich, lean) {
600
+ static type(keys, rich, lean) {
762
601
  const obj = rich();
763
602
  const proto = Reflect.getPrototypeOf(obj);
764
- const [keys, vals] = lean(obj);
603
+ const vals = lean(obj);
765
604
  const shape = JSON.stringify([keys, vals.map(v => typeof v)]);
766
605
  this.leanes.set(proto, lean);
606
+ this.keys.set(proto, keys);
767
607
  this.riches.set(shape, rich);
768
608
  }
769
609
  }
770
610
  $.$mol_vary = $mol_vary;
771
- $mol_vary.type((keys = [], vals = []) => new Map(keys.map((k, i) => [k, vals[i]])), obj => [
772
- ['keys', 'vals'],
773
- [[...obj.keys()], [...obj.values()]],
774
- ]);
775
- $mol_vary.type((vals = []) => new Set(vals), obj => [
776
- ['vals'],
777
- [[...obj.values()]],
778
- ]);
611
+ let buffer = new Uint8Array(128);
612
+ let pack = new DataView(buffer.buffer);
613
+ $mol_vary.type(['keys', 'vals'], (keys = [], vals = []) => new Map(keys.map((k, i) => [k, vals[i]])), obj => [[...obj.keys()], [...obj.values()]]);
614
+ $mol_vary.type(['vals'], (vals = []) => new Set(vals), obj => [[...obj.values()]]);
615
+ $mol_vary.type(['unix_time'], (ts = 0) => new Date(ts * 1000), obj => [obj.valueOf() / 1000]);
779
616
  })($ || ($ = {}));
780
617
 
781
618