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 +5 -1
- package/dist/Nytra.js +91 -41
- package/dist/Reader.d.ts +2 -2
- package/dist/Reader.js +2 -2
- package/dist/Registry.js +0 -4
- package/dist/Types.d.ts +1 -1
- package/dist/Types.js +1 -1
- package/dist/Writer.d.ts +11 -10
- package/dist/Writer.js +20 -13
- package/package.json +41 -41
- package/dist/Binson.d.ts +0 -14
- package/dist/Binson.js +0 -468
- package/dist/NativeHandlers.d.ts +0 -25
- package/dist/NativeHandlers.js +0 -137
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,
|
|
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
|
|
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.
|
|
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.
|
|
287
|
+
writer.writeUINT8(128 + len);
|
|
238
288
|
writer.writeBytes(bytes);
|
|
239
289
|
return writer.toUint8Array();
|
|
240
290
|
}
|
|
241
291
|
if (len <= 65535) {
|
|
242
|
-
writer.
|
|
243
|
-
writer.
|
|
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.
|
|
248
|
-
writer.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
297
|
-
writer.
|
|
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.
|
|
303
|
-
writer.
|
|
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.
|
|
309
|
-
writer.
|
|
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.
|
|
315
|
-
writer.
|
|
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.
|
|
321
|
-
writer.
|
|
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.
|
|
327
|
-
writer.
|
|
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.
|
|
333
|
-
writer.
|
|
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.
|
|
339
|
-
writer.
|
|
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.
|
|
345
|
-
writer.
|
|
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.
|
|
354
|
-
writer.
|
|
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.
|
|
360
|
-
writer.
|
|
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.
|
|
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.
|
|
478
|
+
return reader.readFLOAT64();
|
|
429
479
|
}
|
|
430
480
|
case TYPE_FLOAT32: {
|
|
431
|
-
return reader.
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
this.
|
|
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
|
-
"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
|
-
}
|
package/dist/NativeHandlers.d.ts
DELETED
|
@@ -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
|
-
};
|
package/dist/NativeHandlers.js
DELETED
|
@@ -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
|
-
}
|