nytra 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Nytra.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  import { Reader } from "./Reader.ts";
2
2
  import { Writer } from "./Writer.ts";
3
+ type TypedArrayRegisterFieldOptions = {
4
+ typedArrayTargetTypeId?: number | Function;
5
+ };
3
6
  export type RegisterFieldOptions = {
4
7
  nullable?: boolean;
5
- };
8
+ } & TypedArrayRegisterFieldOptions;
6
9
  export declare class Nytra {
7
10
  #private;
8
11
  static registerField(position: number, targetTypeId?: number | Function, options?: RegisterFieldOptions): (v: undefined, ctx: ClassFieldDecoratorContext) => void;
@@ -12,3 +15,4 @@ export declare class Nytra {
12
15
  static encode(data: unknown, type?: number | null, withType?: boolean, writer?: Writer | null): Uint8Array;
13
16
  static decode(data: Uint8Array | Reader, type?: number | null): unknown;
14
17
  }
18
+ export {};
package/dist/Nytra.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Reader } from "./Reader.js";
2
2
  import { Registry } from "./Registry.js";
3
3
  import { Writer } from "./Writer.js";
4
- import { TYPE_ARRAY, TYPE_BIGINT, TYPE_BOOLEAN, TYPE_EXTENSION, TYPE_FLOAT32, TYPE_FLOAT64, TYPE_INT16, TYPE_INT32, TYPE_INT64, TYPE_INT8, TYPE_JSON, TYPE_NULL, TYPE_OBJECT, TYPE_STRING, TYPE_STRING_16_INTERNAL, TYPE_STRING_32_INTERNAL, TYPE_UINT16, TYPE_UINT32, TYPE_UINT64, TYPE_UINT8 } from "./Types.js";
4
+ import { TYPE_ARRAY, TYPE_BIGINT, TYPE_BOOLEAN, TYPE_FLOAT32, TYPE_FLOAT64, TYPE_INT16, TYPE_INT32, TYPE_INT64, TYPE_INT8, TYPE_JSON, TYPE_NULL, TYPE_OBJECT, TYPE_STRING, TYPE_STRING_16_INTERNAL, TYPE_STRING_32_INTERNAL, TYPE_TYPED_ARRAY, TYPE_UINT16, TYPE_UINT32, TYPE_UINT64, TYPE_UINT8 } from "./Types.js";
5
5
  const MAX_UINT_32 = 2 ** 32;
6
6
  const MAX_UINT_16 = 2 ** 16;
7
7
  const MAX_UINT_8 = 2 ** 8;
@@ -34,6 +34,17 @@ function createDecoder(cls) {
34
34
  meta.targetTypeId = found ? found.typeId : TYPE_JSON;
35
35
  }
36
36
  let type = meta.targetTypeId;
37
+ if (type === TYPE_TYPED_ARRAY) {
38
+ const targetType = typeof meta.options.typedArrayTargetTypeId === 'function' ? classMetaStore.get(meta.options.typedArrayTargetTypeId)?.typeId : meta.options.typedArrayTargetTypeId;
39
+ const size = reader.readUINT32();
40
+ const end = reader.offset + size;
41
+ let data = [];
42
+ while (reader.offset < end) {
43
+ data.push(Nytra.decode(reader, targetType === TYPE_STRING ? null : targetType));
44
+ }
45
+ obj[name] = data;
46
+ continue;
47
+ }
37
48
  if (type === TYPE_STRING) {
38
49
  type = reader.readType();
39
50
  }
@@ -43,6 +54,35 @@ function createDecoder(cls) {
43
54
  return obj;
44
55
  };
45
56
  }
57
+ function createTypedArrayEncoder(targetType) {
58
+ if (typeof targetType === 'function') {
59
+ const meta = classMetaStore.get(targetType);
60
+ if (!meta) {
61
+ throw new Error(`Cannot convert object type ${targetType}`);
62
+ }
63
+ targetType = meta ? meta.typeId : TYPE_JSON;
64
+ meta.typeId;
65
+ }
66
+ return function (data, writer) {
67
+ if (!Array.isArray(data)) {
68
+ throw new Error('Data must be an array');
69
+ }
70
+ if (writer === null) {
71
+ writer = new Writer();
72
+ }
73
+ const arr = data;
74
+ const startIndex = writer.offset;
75
+ writer.setOffset(startIndex + 4); // reserve space for length
76
+ for (let value of arr) {
77
+ Nytra.encode(value, targetType, false, writer);
78
+ }
79
+ const endIndex = writer.offset;
80
+ writer.setOffset(startIndex);
81
+ writer.writeUINT32(endIndex - startIndex - 4);
82
+ writer.setOffset(endIndex);
83
+ return writer.toUint8Array();
84
+ };
85
+ }
46
86
  function createEncoder(cls) {
47
87
  const meta = classMetaStore.get(cls);
48
88
  const cachedEncoders = [];
@@ -69,7 +109,14 @@ function createEncoder(cls) {
69
109
  }
70
110
  // Encoder-Funktion vorgebunden
71
111
  let encodeFn;
72
- if (typeId < 255) {
112
+ if (typeId === TYPE_TYPED_ARRAY) {
113
+ if (typeof fieldMeta.options.typedArrayTargetTypeId === 'function') {
114
+ const typeId = classMetaStore.get(fieldMeta.options.typedArrayTargetTypeId)?.typeId;
115
+ fieldMeta.options.typedArrayTargetTypeId = typeId;
116
+ }
117
+ encodeFn = createTypedArrayEncoder(fieldMeta.options.typedArrayTargetTypeId);
118
+ }
119
+ else if (typeId < 255) {
73
120
  encodeFn = (value, writer) => Nytra.encode(value, typeId, false, writer);
74
121
  }
75
122
  else {
@@ -107,11 +154,15 @@ const classMetaStore = new WeakMap();
107
154
  const SYMBOL_FIELDS = Symbol('Nytra:fields');
108
155
  const CustomRegistry = new Registry();
109
156
  export class Nytra {
110
- static registerField(position, targetTypeId, options = {}) {
157
+ static registerField(position, targetTypeId, options) {
111
158
  const defaultOpts = {
112
- nullable: false
159
+ nullable: false,
160
+ typedArrayTargetTypeId: -1,
113
161
  };
114
162
  Object.assign(defaultOpts, options);
163
+ if (targetTypeId === TYPE_TYPED_ARRAY && defaultOpts.typedArrayTargetTypeId === -1) {
164
+ throw new Error('You must provide options.typedArrayTargetTypeId if you want to register a typed array field');
165
+ }
115
166
  return function (v, ctx) {
116
167
  if (ctx.private) {
117
168
  throw new Error('Only public fields can be registered');
@@ -223,8 +274,7 @@ export class Nytra {
223
274
  throw new Error('Unknown type:' + type);
224
275
  }
225
276
  if (withType) {
226
- writer.writeUint8(TYPE_EXTENSION);
227
- writer.writeUint16(type);
277
+ writer.writeType(type);
228
278
  }
229
279
  encodeFunction(data, writer);
230
280
  return writer.toUint8Array();
@@ -234,24 +284,24 @@ export class Nytra {
234
284
  const bytes = this.#TEXT_ENCODER.encode(str);
235
285
  const len = bytes.length;
236
286
  if (len <= 127) {
237
- writer.writeUint8(128 + len);
287
+ writer.writeUINT8(128 + len);
238
288
  writer.writeBytes(bytes);
239
289
  return writer.toUint8Array();
240
290
  }
241
291
  if (len <= 65535) {
242
- writer.writeUint8(TYPE_STRING_16_INTERNAL);
243
- writer.writeUint16(len);
292
+ writer.writeUINT8(TYPE_STRING_16_INTERNAL);
293
+ writer.writeUINT16(len);
244
294
  writer.writeBytes(bytes);
245
295
  return writer.toUint8Array();
246
296
  }
247
- writer.writeUint8(TYPE_STRING_32_INTERNAL);
248
- writer.writeUint32(len);
297
+ writer.writeUINT8(TYPE_STRING_32_INTERNAL);
298
+ writer.writeUINT32(len);
249
299
  writer.writeBytes(bytes);
250
300
  return writer.toUint8Array();
251
301
  }
252
302
  switch (type) {
253
303
  case TYPE_NULL:
254
- writer.writeUint8(TYPE_NULL);
304
+ writer.writeUINT8(TYPE_NULL);
255
305
  return writer.toUint8Array();
256
306
  case TYPE_ARRAY: {
257
307
  if (!Array.isArray(data)) {
@@ -259,7 +309,7 @@ export class Nytra {
259
309
  }
260
310
  const arr = data;
261
311
  if (withType)
262
- writer.writeUint8(TYPE_ARRAY);
312
+ writer.writeType(TYPE_ARRAY);
263
313
  const startIndex = writer.offset;
264
314
  writer.setOffset(startIndex + 4); // reserve space for length
265
315
  for (let value of arr) {
@@ -267,7 +317,7 @@ export class Nytra {
267
317
  }
268
318
  const endIndex = writer.offset;
269
319
  writer.setOffset(startIndex);
270
- writer.writeUint32(endIndex - startIndex - 4);
320
+ writer.writeUINT32(endIndex - startIndex - 4);
271
321
  writer.setOffset(endIndex);
272
322
  return writer.toUint8Array();
273
323
  }
@@ -277,7 +327,7 @@ export class Nytra {
277
327
  }
278
328
  const obj = data;
279
329
  if (withType)
280
- writer.writeUint8(TYPE_OBJECT);
330
+ writer.writeType(TYPE_OBJECT);
281
331
  const startIndex = writer.offset;
282
332
  writer.setOffset(startIndex + 4);
283
333
  let keys = Object.keys(obj);
@@ -287,62 +337,62 @@ export class Nytra {
287
337
  }
288
338
  const endIndex = writer.offset;
289
339
  writer.setOffset(startIndex);
290
- writer.writeUint32(endIndex - startIndex - 4);
340
+ writer.writeUINT32(endIndex - startIndex - 4);
291
341
  writer.setOffset(endIndex);
292
342
  return writer.toUint8Array();
293
343
  }
294
344
  case TYPE_UINT8: {
295
345
  if (withType)
296
- writer.writeUint8(TYPE_UINT8);
297
- writer.writeUint8(data);
346
+ writer.writeType(TYPE_UINT8);
347
+ writer.writeUINT8(data);
298
348
  return writer.toUint8Array();
299
349
  }
300
350
  case TYPE_UINT16: {
301
351
  if (withType)
302
- writer.writeUint8(TYPE_UINT16);
303
- writer.writeUint16(data);
352
+ writer.writeType(TYPE_UINT16);
353
+ writer.writeUINT16(data);
304
354
  return writer.toUint8Array();
305
355
  }
306
356
  case TYPE_UINT32: {
307
357
  if (withType)
308
- writer.writeUint8(TYPE_UINT32);
309
- writer.writeUint32(data);
358
+ writer.writeType(TYPE_UINT32);
359
+ writer.writeUINT32(data);
310
360
  return writer.toUint8Array();
311
361
  }
312
362
  case TYPE_UINT64: {
313
363
  if (withType)
314
- writer.writeUint8(TYPE_UINT64);
315
- writer.writeUint64(BigInt(data));
364
+ writer.writeType(TYPE_UINT64);
365
+ writer.writeUINT64(BigInt(data));
316
366
  return writer.toUint8Array();
317
367
  }
318
368
  case TYPE_INT8: {
319
369
  if (withType)
320
- writer.writeUint8(TYPE_INT8);
321
- writer.writeInt8(data);
370
+ writer.writeType(TYPE_INT8);
371
+ writer.writeINT8(data);
322
372
  return writer.toUint8Array();
323
373
  }
324
374
  case TYPE_INT16: {
325
375
  if (withType)
326
- writer.writeUint8(TYPE_INT16);
327
- writer.writeInt16(data);
376
+ writer.writeType(TYPE_INT16);
377
+ writer.writeINT16(data);
328
378
  return writer.toUint8Array();
329
379
  }
330
380
  case TYPE_INT32: {
331
381
  if (withType)
332
- writer.writeUint8(TYPE_INT32);
333
- writer.writeInt32(data);
382
+ writer.writeType(TYPE_INT32);
383
+ writer.writeINT32(data);
334
384
  return writer.toUint8Array();
335
385
  }
336
386
  case TYPE_INT64: {
337
387
  if (withType)
338
- writer.writeUint8(TYPE_INT64);
339
- writer.writeInt64(BigInt(data));
388
+ writer.writeType(TYPE_INT64);
389
+ writer.writeINT64(BigInt(data));
340
390
  return writer.toUint8Array();
341
391
  }
342
392
  case TYPE_BOOLEAN: {
343
393
  if (withType)
344
- writer.writeUint8(TYPE_BOOLEAN);
345
- writer.writeUint8(data ? 1 : 0);
394
+ writer.writeType(TYPE_BOOLEAN);
395
+ writer.writeUINT8(data ? 1 : 0);
346
396
  return writer.toUint8Array();
347
397
  }
348
398
  case TYPE_JSON: {
@@ -350,19 +400,19 @@ export class Nytra {
350
400
  }
351
401
  case TYPE_FLOAT32: {
352
402
  if (withType)
353
- writer.writeUint8(TYPE_FLOAT32);
354
- writer.writeFloat32(data);
403
+ writer.writeType(TYPE_FLOAT32);
404
+ writer.writeFLOAT32(data);
355
405
  return writer.toUint8Array();
356
406
  }
357
407
  case TYPE_FLOAT64: {
358
408
  if (withType)
359
- writer.writeUint8(TYPE_FLOAT64);
360
- writer.writeFloat64(data);
409
+ writer.writeType(TYPE_FLOAT64);
410
+ writer.writeFLOAT64(data);
361
411
  return writer.toUint8Array();
362
412
  }
363
413
  case TYPE_BIGINT: {
364
414
  if (withType)
365
- writer.writeUint8(TYPE_BIGINT);
415
+ writer.writeType(TYPE_BIGINT);
366
416
  writer.writeBigInt(BigInt(data));
367
417
  return writer.toUint8Array();
368
418
  }
@@ -425,10 +475,10 @@ export class Nytra {
425
475
  return bigintToSafeNumber(reader.readINT64());
426
476
  }
427
477
  case TYPE_FLOAT64: {
428
- return reader.readFloat64();
478
+ return reader.readFLOAT64();
429
479
  }
430
480
  case TYPE_FLOAT32: {
431
- return reader.readFloat32();
481
+ return reader.readFLOAT32();
432
482
  }
433
483
  case TYPE_ARRAY: {
434
484
  const len = reader.readUINT32();
package/dist/Reader.d.ts CHANGED
@@ -18,8 +18,8 @@ export declare class Reader {
18
18
  readINT16(): number;
19
19
  readINT32(): number;
20
20
  readINT64(): bigint;
21
- readFloat32(): number;
22
- readFloat64(): number;
21
+ readFLOAT32(): number;
22
+ readFLOAT64(): number;
23
23
  readString(length: number): string;
24
24
  readBigInt(): bigint;
25
25
  readType(): number;
package/dist/Reader.js CHANGED
@@ -65,12 +65,12 @@ export class Reader {
65
65
  this.#ind += 8;
66
66
  return this.#dataView.getBigInt64(offset, LITTLE_ENDIAN);
67
67
  }
68
- readFloat32() {
68
+ readFLOAT32() {
69
69
  const offset = this.#ind;
70
70
  this.#ind += 4;
71
71
  return this.#dataView.getFloat32(offset, LITTLE_ENDIAN);
72
72
  }
73
- readFloat64() {
73
+ readFLOAT64() {
74
74
  const offset = this.#ind;
75
75
  this.#ind += 8;
76
76
  return this.#dataView.getFloat64(offset, LITTLE_ENDIAN);
package/dist/Registry.js CHANGED
@@ -1,8 +1,4 @@
1
1
  export class Registry {
2
- /**
3
- *
4
- * @type {Map<number, TypeHandler>}
5
- */
6
2
  #registry = new Map();
7
3
  register(type, handler) {
8
4
  if (this.#registry.has(type)) {
package/dist/Types.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const TYPE_NULL = 0, TYPE_BOOLEAN = 1, TYPE_ARRAY = 2, TYPE_OBJECT = 3, TYPE_STRING_16_INTERNAL = 4, TYPE_STRING_32_INTERNAL = 5, TYPE_JSON = 9, TYPE_UINT8 = 11, TYPE_UINT16 = 12, TYPE_UINT32 = 13, TYPE_UINT64 = 14, TYPE_INT8 = 21, TYPE_INT16 = 22, TYPE_INT32 = 23, TYPE_INT64 = 24, TYPE_FLOAT32 = 30, TYPE_FLOAT64 = 31, TYPE_BIGINT = 40, TYPE_EXTENSION = 127, TYPE_STRING = 128;
1
+ export declare const TYPE_NULL = 0, TYPE_BOOLEAN = 1, TYPE_ARRAY = 2, TYPE_OBJECT = 3, TYPE_STRING_16_INTERNAL = 4, TYPE_STRING_32_INTERNAL = 5, TYPE_JSON = 9, TYPE_UINT8 = 11, TYPE_UINT16 = 12, TYPE_UINT32 = 13, TYPE_UINT64 = 14, TYPE_INT8 = 21, TYPE_INT16 = 22, TYPE_INT32 = 23, TYPE_INT64 = 24, TYPE_FLOAT32 = 30, TYPE_FLOAT64 = 31, TYPE_BIGINT = 40, TYPE_TYPED_ARRAY = 50, TYPE_EXTENSION = 127, TYPE_STRING = 128;
package/dist/Types.js CHANGED
@@ -1,3 +1,3 @@
1
- export const TYPE_NULL = 0, TYPE_BOOLEAN = 1, TYPE_ARRAY = 2, TYPE_OBJECT = 3, TYPE_STRING_16_INTERNAL = 4, TYPE_STRING_32_INTERNAL = 5, TYPE_JSON = 9, TYPE_UINT8 = 11, TYPE_UINT16 = 12, TYPE_UINT32 = 13, TYPE_UINT64 = 14, TYPE_INT8 = 21, TYPE_INT16 = 22, TYPE_INT32 = 23, TYPE_INT64 = 24, TYPE_FLOAT32 = 30, TYPE_FLOAT64 = 31, TYPE_BIGINT = 40, TYPE_EXTENSION = 127,
1
+ export const TYPE_NULL = 0, TYPE_BOOLEAN = 1, TYPE_ARRAY = 2, TYPE_OBJECT = 3, TYPE_STRING_16_INTERNAL = 4, TYPE_STRING_32_INTERNAL = 5, TYPE_JSON = 9, TYPE_UINT8 = 11, TYPE_UINT16 = 12, TYPE_UINT32 = 13, TYPE_UINT64 = 14, TYPE_INT8 = 21, TYPE_INT16 = 22, TYPE_INT32 = 23, TYPE_INT64 = 24, TYPE_FLOAT32 = 30, TYPE_FLOAT64 = 31, TYPE_BIGINT = 40, TYPE_TYPED_ARRAY = 50, TYPE_EXTENSION = 127,
2
2
  //128-255 -> String use 7 bits for length (max 127)
3
3
  TYPE_STRING = 128;
package/dist/Writer.d.ts CHANGED
@@ -5,16 +5,17 @@ export declare class Writer {
5
5
  get offset(): number;
6
6
  constructor(initialSize?: number);
7
7
  private ensureCapacity;
8
- writeInt8(value: number): this;
9
- writeInt16(value: number): this;
10
- writeInt32(value: number): this;
11
- writeInt64(value: bigint): this;
12
- writeUint8(value: number): this;
13
- writeUint16(value: number): this;
14
- writeUint32(value: number): this;
15
- writeUint64(value: bigint): this;
16
- writeFloat32(value: number): this;
17
- writeFloat64(value: number): this;
8
+ writeType(type: number): this;
9
+ writeINT8(value: number): this;
10
+ writeINT16(value: number): this;
11
+ writeINT32(value: number): this;
12
+ writeINT64(value: bigint): this;
13
+ writeUINT8(value: number): this;
14
+ writeUINT16(value: number): this;
15
+ writeUINT32(value: number): this;
16
+ writeUINT64(value: bigint): this;
17
+ writeFLOAT32(value: number): this;
18
+ writeFLOAT64(value: number): this;
18
19
  writeBytes(bytes: Uint8Array): this;
19
20
  writeBigInt(value: bigint): this;
20
21
  toUint8Array(): Uint8Array;
package/dist/Writer.js CHANGED
@@ -1,7 +1,7 @@
1
+ import { TYPE_EXTENSION } from "./Types.js";
1
2
  const LITTLE_ENDIAN = true;
2
3
  export class Writer {
3
4
  static DEFAULT_SIZE = 1024;
4
- static #encoder = new TextEncoder();
5
5
  #buffer;
6
6
  #view;
7
7
  #offset = 0;
@@ -38,61 +38,68 @@ export class Writer {
38
38
  this.#buffer = newBuffer;
39
39
  this.#view = new DataView(newBuffer);
40
40
  }
41
- writeInt8(value) {
41
+ writeType(type) {
42
+ if (type <= 255) {
43
+ return this.writeUINT8(type);
44
+ }
45
+ this.writeUINT8(TYPE_EXTENSION);
46
+ return this.writeUINT16(type);
47
+ }
48
+ writeINT8(value) {
42
49
  this.ensureCapacity(1);
43
50
  this.#view.setInt8(this.#offset, value);
44
51
  this.#offset += 1;
45
52
  return this;
46
53
  }
47
- writeInt16(value) {
54
+ writeINT16(value) {
48
55
  this.ensureCapacity(2);
49
56
  this.#view.setInt16(this.#offset, value, LITTLE_ENDIAN);
50
57
  this.#offset += 2;
51
58
  return this;
52
59
  }
53
- writeInt32(value) {
60
+ writeINT32(value) {
54
61
  this.ensureCapacity(4);
55
62
  this.#view.setInt32(this.#offset, value, LITTLE_ENDIAN);
56
63
  this.#offset += 4;
57
64
  return this;
58
65
  }
59
- writeInt64(value) {
66
+ writeINT64(value) {
60
67
  this.ensureCapacity(8);
61
68
  this.#view.setBigInt64(this.#offset, value, LITTLE_ENDIAN);
62
69
  this.#offset += 8;
63
70
  return this;
64
71
  }
65
- writeUint8(value) {
72
+ writeUINT8(value) {
66
73
  this.ensureCapacity(1);
67
74
  this.#view.setUint8(this.#offset, value);
68
75
  this.#offset += 1;
69
76
  return this;
70
77
  }
71
- writeUint16(value) {
78
+ writeUINT16(value) {
72
79
  this.ensureCapacity(2);
73
80
  this.#view.setUint16(this.#offset, value, LITTLE_ENDIAN);
74
81
  this.#offset += 2;
75
82
  return this;
76
83
  }
77
- writeUint32(value) {
84
+ writeUINT32(value) {
78
85
  this.ensureCapacity(4);
79
86
  this.#view.setUint32(this.#offset, value, LITTLE_ENDIAN);
80
87
  this.#offset += 4;
81
88
  return this;
82
89
  }
83
- writeUint64(value) {
90
+ writeUINT64(value) {
84
91
  this.ensureCapacity(8);
85
92
  this.#view.setBigUint64(this.#offset, value, LITTLE_ENDIAN);
86
93
  this.#offset += 8;
87
94
  return this;
88
95
  }
89
- writeFloat32(value) {
96
+ writeFLOAT32(value) {
90
97
  this.ensureCapacity(4);
91
98
  this.#view.setFloat32(this.#offset, value, LITTLE_ENDIAN);
92
99
  this.#offset += 4;
93
100
  return this;
94
101
  }
95
- writeFloat64(value) {
102
+ writeFLOAT64(value) {
96
103
  this.ensureCapacity(8);
97
104
  this.#view.setFloat64(this.#offset, value, LITTLE_ENDIAN);
98
105
  this.#offset += 8;
@@ -105,8 +112,8 @@ export class Writer {
105
112
  return this;
106
113
  }
107
114
  writeBigInt(value) {
108
- let bytes = bigintToUint8ArrayLE(value);
109
- this.writeUint16(bytes.length);
115
+ const bytes = bigintToUint8ArrayLE(value);
116
+ this.writeUINT16(bytes.length);
110
117
  this.writeBytes(bytes);
111
118
  return this;
112
119
  }
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "private": false,
3
- "name": "nytra",
4
- "version": "0.0.5",
5
- "description": "A javascript ES6 Decorator driven library to encode/decode javascript objects to/from binary optimized buffers to reduce payload on network",
6
- "license": "MIT",
7
- "author": {
8
- "name": "Kapsonfire",
9
- "email": "kapsonfire@googlemail.com"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/nytra-lib/nytra-js.git"
14
- },
15
- "homepage": "https://github.com/nytra-lib/nytra-js#readme",
16
- "bugs": {
17
- "url": "https://github.com/nytra-lib/nytra-js/issues"
18
- },
19
- "type": "module",
20
- "main": "index.js",
21
- "scripts": {
22
- "test": "echo \"Error: no test specified\" && exit 1",
23
- "build": "tsc",
24
- "prepublishOnly": "npm run build"
25
- },
26
- "files": [
27
- "dist",
28
- "README.md"
29
- ],
30
- "devDependencies": {
31
- "@msgpack/msgpack": "^3.1.3",
32
- "@types/bun": "^1.3.13",
33
- "typescript": "^6.0.3"
34
- },
35
- "exports": {
36
- ".": {
37
- "import": "./dist/index.js",
38
- "types": "./dist/index.d.ts"
39
- }
40
- }
41
- }
1
+ {
2
+ "private": false,
3
+ "name": "nytra",
4
+ "version": "0.0.7",
5
+ "description": "A javascript ES6 Decorator driven library to encode/decode javascript objects to/from binary optimized buffers to reduce payload on network",
6
+ "license": "MIT",
7
+ "author": {
8
+ "name": "Kapsonfire",
9
+ "email": "kapsonfire@googlemail.com"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/nytra-lib/nytra-js.git"
14
+ },
15
+ "homepage": "https://github.com/nytra-lib/nytra-js#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/nytra-lib/nytra-js/issues"
18
+ },
19
+ "type": "module",
20
+ "main": "index.js",
21
+ "scripts": {
22
+ "test": "echo \"Error: no test specified\" && exit 1",
23
+ "build": "tsc",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "README.md"
29
+ ],
30
+ "devDependencies": {
31
+ "@msgpack/msgpack": "^3.1.3",
32
+ "@types/bun": "^1.3.13",
33
+ "typescript": "^6.0.3"
34
+ },
35
+ "exports": {
36
+ ".": {
37
+ "import": "./dist/index.js",
38
+ "types": "./dist/index.d.ts"
39
+ }
40
+ }
41
+ }
package/dist/Binson.d.ts DELETED
@@ -1,14 +0,0 @@
1
- import { Reader } from "./Reader.ts";
2
- import { Writer } from "./Writer.ts";
3
- export type RegisterFieldOptions = {
4
- nullable?: boolean;
5
- };
6
- export declare class Binson {
7
- #private;
8
- static registerField(position: number, targetTypeId?: number | Function, options?: RegisterFieldOptions): (v: undefined, ctx: ClassFieldDecoratorContext) => void;
9
- static registerClass(typeId: number): <T extends Function>(decoratedClass: T, ctx: ClassDecoratorContext) => void;
10
- static autoguessType(data: unknown): number;
11
- static getTypeIdForClass(ctor: Function): number;
12
- static encode(data: unknown, type?: number | null, withType?: boolean, writer?: Writer | null): Uint8Array;
13
- static decode(data: Uint8Array | Reader, type?: number | null): unknown;
14
- }
package/dist/Binson.js DELETED
@@ -1,468 +0,0 @@
1
- import { Reader } from "./Reader.js";
2
- import { Registry } from "./Registry.js";
3
- import { Writer } from "./Writer.js";
4
- import { TYPE_ARRAY, TYPE_BIGINT, TYPE_BOOLEAN, TYPE_EXTENSION, TYPE_FLOAT32, TYPE_FLOAT64, TYPE_INT16, TYPE_INT32, TYPE_INT64, TYPE_INT8, TYPE_JSON, TYPE_NULL, TYPE_OBJECT, TYPE_STRING, TYPE_STRING_16_INTERNAL, TYPE_STRING_32_INTERNAL, TYPE_UINT16, TYPE_UINT32, TYPE_UINT64, TYPE_UINT8 } from "./Types.js";
5
- const MAX_UINT_32 = 2 ** 32;
6
- const MAX_UINT_16 = 2 ** 16;
7
- const MAX_UINT_8 = 2 ** 8;
8
- const MIN_INT_32 = -(2 ** 31);
9
- const MIN_INT_16 = -(2 ** 15);
10
- const MIN_INT_8 = -(2 ** 8);
11
- function createDecoder(cls) {
12
- const meta = classMetaStore.get(cls);
13
- const fields = meta?.fields;
14
- return function (reader) {
15
- let obj = {};
16
- const nullableFields = fields.filter(([_name, meta]) => meta.options.nullable).map(([name, _meta]) => name);
17
- const nullableBytes = Math.ceil(nullableFields.length / 8);
18
- const nullableBitfield = nullableBytes > 0 ? reader.readBytes(nullableBytes) : [];
19
- const isFieldNull = (index) => {
20
- const byteIndex = Math.floor(index / 8);
21
- const bitOffset = index % 8;
22
- return (nullableBitfield[byteIndex] & (1 << bitOffset)) !== 0;
23
- };
24
- for (let [name, meta] of fields) {
25
- if (nullableBytes > 0 && meta.options.nullable) {
26
- const nullIndex = nullableFields.indexOf(name);
27
- if (nullIndex !== -1 && isFieldNull(nullIndex)) {
28
- obj[name] = null;
29
- continue;
30
- }
31
- }
32
- if (typeof meta.targetTypeId === "function") {
33
- const found = classMetaStore.get(meta.targetTypeId);
34
- meta.targetTypeId = found ? found.typeId : TYPE_JSON;
35
- }
36
- let type = meta.targetTypeId;
37
- if (type === TYPE_STRING) {
38
- type = reader.readType();
39
- }
40
- obj[name] = Binson.decode(reader, type);
41
- }
42
- Object.setPrototypeOf(obj, cls.prototype);
43
- return obj;
44
- };
45
- }
46
- function createEncoder(cls) {
47
- const meta = classMetaStore.get(cls);
48
- const cachedEncoders = [];
49
- const nullableFields = [];
50
- let nullableBytes = 0;
51
- return function (data, writer) {
52
- if (writer === null) {
53
- writer = new Writer();
54
- }
55
- if (cachedEncoders.length == 0) {
56
- meta.fields.forEach(([name, fieldMeta]) => {
57
- if (fieldMeta.options.nullable) {
58
- nullableFields.push(name);
59
- }
60
- let typeId = fieldMeta.targetTypeId;
61
- if (!typeId) {
62
- cachedEncoders.push({ name: name, encode: null, options: fieldMeta.options });
63
- return;
64
- }
65
- // Resolve Function → typeId hier, nicht im Loop!
66
- if (typeof typeId === 'function') {
67
- const found = classMetaStore.get(typeId);
68
- typeId = found ? found.typeId : TYPE_JSON;
69
- }
70
- // Encoder-Funktion vorgebunden
71
- let encodeFn;
72
- if (typeId < 255) {
73
- encodeFn = (value, writer) => Binson.encode(value, typeId, false, writer);
74
- }
75
- else {
76
- encodeFn = CustomRegistry.getEncoder(typeId);
77
- }
78
- cachedEncoders.push({ name: name, encode: encodeFn, options: fieldMeta.options });
79
- });
80
- nullableBytes = Math.ceil(nullableFields.length / 8);
81
- }
82
- if (nullableBytes > 0) {
83
- const nullableBitfield = new Uint8Array(nullableBytes);
84
- for (let i = 0; i < nullableFields.length; i++) {
85
- const field = nullableFields[i];
86
- if (data[field] === null) {
87
- const byteIndex = Math.floor(i / 8);
88
- const bitOffset = i % 8;
89
- nullableBitfield[byteIndex] |= (1 << bitOffset);
90
- }
91
- }
92
- writer.writeBytes(nullableBitfield);
93
- }
94
- for (const encodeInfo of cachedEncoders) {
95
- const value = data[encodeInfo.name];
96
- if (value === null && encodeInfo.options.nullable) {
97
- continue;
98
- }
99
- encodeInfo.encode ?
100
- encodeInfo.encode(data[encodeInfo.name], writer) :
101
- Binson.encode(data[encodeInfo.name], null, true, writer);
102
- }
103
- return writer.toUint8Array();
104
- };
105
- }
106
- const classMetaStore = new WeakMap();
107
- const SYMBOL_FIELDS = Symbol('binson:fields');
108
- const CustomRegistry = new Registry();
109
- export class Binson {
110
- static registerField(position, targetTypeId, options = {}) {
111
- const defaultOpts = {
112
- nullable: false
113
- };
114
- Object.assign(defaultOpts, options);
115
- return function (v, ctx) {
116
- if (ctx.private) {
117
- throw new Error('Only public fields can be registered');
118
- }
119
- const metadata = ctx.metadata;
120
- if (typeof metadata[SYMBOL_FIELDS] === 'undefined') {
121
- metadata[SYMBOL_FIELDS] = new Map();
122
- }
123
- const fieldMeta = {
124
- position,
125
- targetTypeId,
126
- options: defaultOpts
127
- };
128
- metadata[SYMBOL_FIELDS].set(ctx.name, fieldMeta);
129
- };
130
- }
131
- static registerClass(typeId) {
132
- if (typeId < 256 || typeId > 65535) {
133
- throw new Error('typeId must be in range of 256 and 65535');
134
- }
135
- return function (decoratedClass, ctx) {
136
- const metadata = ctx.metadata;
137
- const fields = metadata[SYMBOL_FIELDS] ?
138
- [...metadata[SYMBOL_FIELDS].entries()].sort(([_aName, aMeta], [_bName, bMeta]) => aMeta.position - bMeta.position)
139
- : [];
140
- classMetaStore.set(decoratedClass, { typeId, fields });
141
- CustomRegistry.register(typeId, {
142
- encoder: createEncoder(decoratedClass),
143
- decoder: createDecoder(decoratedClass)
144
- });
145
- };
146
- }
147
- static autoguessType(data) {
148
- if (data === null) {
149
- return TYPE_NULL;
150
- }
151
- if (typeof data === 'object') {
152
- const ctor = data.constructor;
153
- const found = classMetaStore.get(ctor);
154
- if (found) {
155
- return found.typeId;
156
- }
157
- }
158
- if (Array.isArray(data)) {
159
- return TYPE_ARRAY;
160
- }
161
- if (typeof data === 'object') {
162
- return TYPE_OBJECT;
163
- }
164
- if (typeof data === 'string') {
165
- return TYPE_STRING;
166
- }
167
- if (typeof data === 'boolean') {
168
- return TYPE_BOOLEAN;
169
- }
170
- if (typeof data === 'number') {
171
- if (Number.isInteger(data)) {
172
- if (data >= 0) {
173
- //unsigned possible
174
- if (data <= MAX_UINT_8) {
175
- return TYPE_UINT8;
176
- }
177
- if (data <= MAX_UINT_16) {
178
- return TYPE_UINT16;
179
- }
180
- if (data <= MAX_UINT_32) {
181
- return TYPE_UINT32;
182
- }
183
- return TYPE_UINT64;
184
- }
185
- else {
186
- if (data >= MIN_INT_8) {
187
- return TYPE_INT8;
188
- }
189
- if (data >= MIN_INT_16) {
190
- return TYPE_INT16;
191
- }
192
- if (data >= MIN_INT_32) {
193
- return TYPE_INT32;
194
- }
195
- return TYPE_INT64;
196
- }
197
- }
198
- if (Math.fround(data) === data) {
199
- return TYPE_FLOAT32;
200
- }
201
- return TYPE_FLOAT64;
202
- }
203
- if (typeof data === 'bigint') {
204
- return TYPE_BIGINT;
205
- }
206
- return TYPE_JSON;
207
- }
208
- static getTypeIdForClass(ctor) {
209
- const found = classMetaStore.get(ctor);
210
- return found ? found.typeId : TYPE_JSON;
211
- }
212
- static #TEXT_ENCODER = new TextEncoder();
213
- static encode(data, type = null, withType = true, writer = null) {
214
- if (writer === null) {
215
- writer = new Writer();
216
- }
217
- if (type === null) {
218
- type = this.autoguessType(data);
219
- }
220
- if (type >= 256) {
221
- const encodeFunction = CustomRegistry.getEncoder(type);
222
- if (typeof encodeFunction !== 'function') {
223
- throw new Error('Unknown type:' + type);
224
- }
225
- if (withType) {
226
- writer.writeUint8(TYPE_EXTENSION);
227
- writer.writeUint16(type);
228
- }
229
- encodeFunction(data, writer);
230
- return writer.toUint8Array();
231
- }
232
- if (type >= TYPE_STRING) { //automatically
233
- const str = data;
234
- const bytes = this.#TEXT_ENCODER.encode(str);
235
- const len = bytes.length;
236
- if (len <= 127) {
237
- writer.writeUint8(128 + len);
238
- writer.writeBytes(bytes);
239
- return writer.toUint8Array();
240
- }
241
- if (len <= 65535) {
242
- writer.writeUint8(TYPE_STRING_16_INTERNAL);
243
- writer.writeUint16(len);
244
- writer.writeBytes(bytes);
245
- return writer.toUint8Array();
246
- }
247
- writer.writeUint8(TYPE_STRING_32_INTERNAL);
248
- writer.writeUint32(len);
249
- writer.writeBytes(bytes);
250
- return writer.toUint8Array();
251
- }
252
- switch (type) {
253
- case TYPE_NULL:
254
- writer.writeUint8(TYPE_NULL);
255
- return writer.toUint8Array();
256
- case TYPE_ARRAY: {
257
- if (!Array.isArray(data)) {
258
- throw new Error('Data must be an array');
259
- }
260
- const arr = data;
261
- if (withType)
262
- writer.writeUint8(TYPE_ARRAY);
263
- const startIndex = writer.offset;
264
- writer.setOffset(startIndex + 4); // reserve space for length
265
- for (let value of arr) {
266
- this.encode(value, null, true, writer);
267
- }
268
- const endIndex = writer.offset;
269
- writer.setOffset(startIndex);
270
- writer.writeUint32(endIndex - startIndex - 4);
271
- writer.setOffset(endIndex);
272
- return writer.toUint8Array();
273
- }
274
- case TYPE_OBJECT: {
275
- if (typeof data !== 'object') {
276
- throw new Error('Data must be an array');
277
- }
278
- const obj = data;
279
- if (withType)
280
- writer.writeUint8(TYPE_OBJECT);
281
- const startIndex = writer.offset;
282
- writer.setOffset(startIndex + 4);
283
- let keys = Object.keys(obj);
284
- for (let key of keys) {
285
- this.encode(key, TYPE_STRING, true, writer);
286
- this.encode(obj[key], null, true, writer);
287
- }
288
- const endIndex = writer.offset;
289
- writer.setOffset(startIndex);
290
- writer.writeUint32(endIndex - startIndex - 4);
291
- writer.setOffset(endIndex);
292
- return writer.toUint8Array();
293
- }
294
- case TYPE_UINT8: {
295
- if (withType)
296
- writer.writeUint8(TYPE_UINT8);
297
- writer.writeUint8(data);
298
- return writer.toUint8Array();
299
- }
300
- case TYPE_UINT16: {
301
- if (withType)
302
- writer.writeUint8(TYPE_UINT16);
303
- writer.writeUint16(data);
304
- return writer.toUint8Array();
305
- }
306
- case TYPE_UINT32: {
307
- if (withType)
308
- writer.writeUint8(TYPE_UINT32);
309
- writer.writeUint32(data);
310
- return writer.toUint8Array();
311
- }
312
- case TYPE_UINT64: {
313
- if (withType)
314
- writer.writeUint8(TYPE_UINT64);
315
- writer.writeUint64(BigInt(data));
316
- return writer.toUint8Array();
317
- }
318
- case TYPE_INT8: {
319
- if (withType)
320
- writer.writeUint8(TYPE_INT8);
321
- writer.writeInt8(data);
322
- return writer.toUint8Array();
323
- }
324
- case TYPE_INT16: {
325
- if (withType)
326
- writer.writeUint8(TYPE_INT16);
327
- writer.writeInt16(data);
328
- return writer.toUint8Array();
329
- }
330
- case TYPE_INT32: {
331
- if (withType)
332
- writer.writeUint8(TYPE_INT32);
333
- writer.writeInt32(data);
334
- return writer.toUint8Array();
335
- }
336
- case TYPE_INT64: {
337
- if (withType)
338
- writer.writeUint8(TYPE_INT64);
339
- writer.writeInt64(BigInt(data));
340
- return writer.toUint8Array();
341
- }
342
- case TYPE_BOOLEAN: {
343
- if (withType)
344
- writer.writeUint8(TYPE_BOOLEAN);
345
- writer.writeUint8(data ? 1 : 0);
346
- return writer.toUint8Array();
347
- }
348
- case TYPE_JSON: {
349
- return this.encode(JSON.stringify(data), TYPE_STRING, withType, writer);
350
- }
351
- case TYPE_FLOAT32: {
352
- if (withType)
353
- writer.writeUint8(TYPE_FLOAT32);
354
- writer.writeFloat32(data);
355
- return writer.toUint8Array();
356
- }
357
- case TYPE_FLOAT64: {
358
- if (withType)
359
- writer.writeUint8(TYPE_FLOAT64);
360
- writer.writeFloat64(data);
361
- return writer.toUint8Array();
362
- }
363
- case TYPE_BIGINT: {
364
- if (withType)
365
- writer.writeUint8(TYPE_BIGINT);
366
- writer.writeBigInt(BigInt(data));
367
- return writer.toUint8Array();
368
- }
369
- }
370
- throw new Error('Type unknown: ' + type);
371
- }
372
- static decode(data, type = null) {
373
- let reader = data instanceof Reader ? data : new Reader(data);
374
- if (type === null)
375
- type = reader.readType();
376
- if (type > 255) {
377
- const decodeFunction = CustomRegistry.getDecoder(type);
378
- if (typeof decodeFunction !== 'function') {
379
- throw new Error('Unknown type:' + type);
380
- }
381
- return decodeFunction(reader);
382
- }
383
- if (type >= TYPE_STRING) {
384
- let length = type & 0b01111111;
385
- return reader.readString(length);
386
- }
387
- switch (type) {
388
- case TYPE_STRING_16_INTERNAL: {
389
- const length = reader.readUINT16();
390
- return reader.readString(length);
391
- }
392
- case TYPE_STRING_32_INTERNAL: {
393
- const length = reader.readUINT32();
394
- return reader.readString(length);
395
- }
396
- case TYPE_BOOLEAN: {
397
- return reader.readUINT8() !== 0;
398
- }
399
- case TYPE_JSON: {
400
- const json = this.decode(reader);
401
- return JSON.parse(json);
402
- }
403
- case TYPE_UINT8: {
404
- return reader.readUINT8();
405
- }
406
- case TYPE_UINT16: {
407
- return reader.readUINT16();
408
- }
409
- case TYPE_UINT32: {
410
- return reader.readUINT32();
411
- }
412
- case TYPE_UINT64: {
413
- return bigintToSafeNumber(reader.readUINT64());
414
- }
415
- case TYPE_INT8: {
416
- return reader.readINT8();
417
- }
418
- case TYPE_INT16: {
419
- return reader.readINT16();
420
- }
421
- case TYPE_INT32: {
422
- return reader.readINT32();
423
- }
424
- case TYPE_INT64: {
425
- return bigintToSafeNumber(reader.readINT64());
426
- }
427
- case TYPE_FLOAT64: {
428
- return reader.readFloat64();
429
- }
430
- case TYPE_FLOAT32: {
431
- return reader.readFloat32();
432
- }
433
- case TYPE_ARRAY: {
434
- const len = reader.readUINT32();
435
- const end = reader.offset + len;
436
- const targetArray = [];
437
- while (reader.offset < end) {
438
- targetArray.push(this.decode(reader));
439
- }
440
- return targetArray;
441
- }
442
- case TYPE_OBJECT: {
443
- const len = reader.readUINT32();
444
- const end = reader.offset + len;
445
- const targetObj = {};
446
- while (reader.offset < end) {
447
- const key = this.decode(reader);
448
- targetObj[key] = this.decode(reader);
449
- }
450
- return targetObj;
451
- }
452
- case TYPE_BIGINT: {
453
- return reader.readBigInt();
454
- }
455
- case TYPE_NULL: {
456
- return null;
457
- }
458
- }
459
- throw new Error('Unknown type:' + type);
460
- }
461
- }
462
- function bigintToSafeNumber(value) {
463
- if (value > BigInt(Number.MAX_SAFE_INTEGER) ||
464
- value < BigInt(Number.MIN_SAFE_INTEGER)) {
465
- return value;
466
- }
467
- return Number(value);
468
- }
@@ -1,25 +0,0 @@
1
- import { Reader } from "./Reader.ts";
2
- export declare const NativeHandlers: {
3
- readonly [x: number]: {
4
- encoder: (data: null) => Uint8Array<ArrayBuffer>;
5
- decoder: (reader: Reader) => null;
6
- } | {
7
- encoder: (data: number) => Uint8Array<ArrayBufferLike>;
8
- decoder: (reader: Reader) => number;
9
- } | {
10
- encoder: (data: bigint) => Uint8Array<ArrayBufferLike>;
11
- decoder: (reader: Reader) => bigint;
12
- } | {
13
- encoder: (data: boolean) => Uint8Array<ArrayBuffer>;
14
- decoder: (reader: Reader) => boolean;
15
- } | {
16
- decoder(reader: Reader): object;
17
- encoder(data: object): Uint8Array;
18
- } | {
19
- encoder: (json: unknown) => Uint8Array<ArrayBufferLike>;
20
- decoder: (reader: Reader) => any;
21
- } | {
22
- encoder: (data: string) => Uint8Array<ArrayBufferLike>;
23
- decoder: (reader: Reader) => string;
24
- };
25
- };
@@ -1,137 +0,0 @@
1
- import { Writer } from "./Writer.js";
2
- import { Binson } from "./Binson.js";
3
- import { Reader } from "./Reader.js";
4
- const TRUE = new Uint8Array([1]);
5
- const FALSE = new Uint8Array([0]);
6
- export const NativeHandlers = {
7
- [Types.NULL]: {
8
- encoder: (data) => new Uint8Array(0),
9
- decoder: (reader) => null
10
- },
11
- [Types.UINT8]: {
12
- encoder: (data) => new Writer(1).writeUint8(data).toUint8Array(),
13
- decoder: (reader) => reader.readUINT8()
14
- },
15
- [Types.UINT16]: {
16
- encoder: (data) => new Writer(2).writeUint16(data).toUint8Array(),
17
- decoder: (reader) => reader.readUINT16()
18
- },
19
- [Types.UINT32]: {
20
- encoder: (data) => new Writer(4).writeUint32(data).toUint8Array(),
21
- decoder: (reader) => reader.readUINT32()
22
- },
23
- [Types.UINT64]: {
24
- encoder: (data) => new Writer(8).writeUint64(BigInt(data)).toUint8Array(),
25
- decoder: (reader) => Number(reader.readUINT64())
26
- },
27
- [Types.INT8]: {
28
- encoder: (data) => new Writer(1).writeUint8(data).toUint8Array(),
29
- decoder: (reader) => reader.readINT8()
30
- },
31
- [Types.INT16]: {
32
- encoder: (data) => new Writer(2).writeInt16(data).toUint8Array(),
33
- decoder: (reader) => reader.readINT16()
34
- },
35
- [Types.INT32]: {
36
- encoder: (data) => new Writer(4).writeInt32(data).toUint8Array(),
37
- decoder: (reader) => reader.readINT32()
38
- },
39
- [Types.INT64]: {
40
- encoder: (data) => new Writer(8).writeInt64(BigInt(data)).toUint8Array(),
41
- decoder: (reader) => Number(reader.readINT64())
42
- },
43
- [Types.FLOAT32]: {
44
- encoder: (data) => new Writer(4).writeFloat32(data).toUint8Array(),
45
- decoder: (reader) => reader.readFloat32()
46
- },
47
- [Types.FLOAT64]: {
48
- encoder: (data) => new Writer(4).writeFloat32(data).toUint8Array(),
49
- decoder: (reader) => reader.readFloat32()
50
- },
51
- [Types.BIGINT]: {
52
- encoder: (data) => new Writer(10).writeBigInt(data).toUint8Array(),
53
- decoder: (reader) => reader.readBigInt()
54
- },
55
- [Types.BOOLEAN]: {
56
- encoder: (data) => data ? TRUE : FALSE,
57
- decoder: (reader) => reader.readUINT8() > 0
58
- },
59
- [Types.ARRAY]: {
60
- decoder(reader) {
61
- let fullData = [];
62
- let length = reader.readUINT32();
63
- let buffer = reader.readBytes(length);
64
- let bufferReader = new Reader(buffer);
65
- while (bufferReader.remaining > 0) {
66
- fullData.push(Binson.decode(bufferReader));
67
- }
68
- return fullData;
69
- }, encoder(data) {
70
- const buffer = flattenUint8Array(data.map(d => Binson.encode(d, null)));
71
- const length = new Uint8Array(4);
72
- new DataView(length.buffer).setUint32(0, buffer.length, true);
73
- const out = new Uint8Array(4 + buffer.length);
74
- out.set(length, 0);
75
- out.set(buffer, 4);
76
- return out;
77
- }
78
- },
79
- [Types.OBJECT]: {
80
- decoder(reader) {
81
- let fullData = {};
82
- let length = reader.readUINT32();
83
- let buffer = reader.readBytes(length);
84
- let bufferReader = new Reader(buffer);
85
- while (bufferReader.remaining > 0) {
86
- let key = bufferReader.readString();
87
- fullData[key] = Binson.decode(bufferReader);
88
- }
89
- return fullData;
90
- }, encoder(data) {
91
- let keys = Object.keys(data);
92
- let dataArray = new Array(keys.length * 2);
93
- for (let i = 0; i < keys.length; i++) {
94
- let key = keys[i];
95
- dataArray[i * 2] = Binson.encodeValue(key, Types.STRING);
96
- dataArray[i * 2 + 1] = Binson.encode(data[key], null);
97
- }
98
- let buffer = flattenUint8Array(dataArray);
99
- const length = new Uint8Array(4);
100
- new DataView(length.buffer).setUint32(0, buffer.length, true);
101
- const out = new Uint8Array(4 + buffer.length);
102
- out.set(length, 0);
103
- out.set(buffer, 4);
104
- return out;
105
- }
106
- },
107
- [Types.JSON]: {
108
- encoder: (json) => {
109
- let data = JSON.stringify(json);
110
- const bytes = new TextEncoder().encode(data);
111
- return new Writer(2 + bytes.length)
112
- .writeString(data)
113
- .toUint8Array();
114
- },
115
- decoder: (reader) => JSON.parse(reader.readString())
116
- },
117
- [Types.STRING]: {
118
- encoder: (data) => {
119
- const bytes = new TextEncoder().encode(data);
120
- return new Writer(2 + bytes.length)
121
- .writeString(data)
122
- .toUint8Array();
123
- },
124
- decoder: (reader) => reader.readString()
125
- },
126
- };
127
- function flattenUint8Array(chunks) {
128
- const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
129
- const result = new Uint8Array(totalLength);
130
- let offset = 0;
131
- for (let i = 0; i < chunks.length; i++) {
132
- const chunk = chunks[i];
133
- result.set(chunk, offset);
134
- offset += chunk.length;
135
- }
136
- return result;
137
- }