@andrew_l/tl-pack 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -31
- package/dist/BinaryReader.d.ts +9 -3
- package/dist/BinaryReader.js +64 -28
- package/dist/BinaryWriter.d.ts +5 -4
- package/dist/BinaryWriter.js +25 -22
- package/dist/constants.d.ts +14 -13
- package/dist/constants.js +14 -13
- package/dist/extension.js +3 -0
- package/dist/helpers.d.ts +3 -3
- package/dist/helpers.js +22 -65
- package/dist/stream.d.ts +0 -1
- package/dist/stream.js +8 -3
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# TLPack for JavaScript/NodeJs
|
|
1
|
+
# TLPack for JavaScript/NodeJs <!-- omit in toc -->
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+
  
|
|
4
4
|
|
|
5
5
|
This library is another implementation of binary serialization like **MessagePack** inspired by TL (Type Language) developed by old VK team.
|
|
6
6
|
|
|
@@ -20,23 +20,39 @@ const writer = new BinaryWriter();
|
|
|
20
20
|
// use to compress this part of data
|
|
21
21
|
// writer.writeObjectGzip
|
|
22
22
|
writer.writeObject({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
null: null,
|
|
24
|
+
uint8: 255,
|
|
25
|
+
uint16: 256,
|
|
26
|
+
uint32: 65536,
|
|
27
|
+
int8: -128,
|
|
28
|
+
int16: -32768,
|
|
29
|
+
int32: -2147483648,
|
|
30
|
+
double: 3.14,
|
|
31
|
+
string: 'Hello world',
|
|
32
|
+
vector: [1, 2, 3, 4, 5, { text: 'hi' }],
|
|
33
|
+
map: { foo: 'bar' },
|
|
34
|
+
date: new Date(),
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
const reader = new BinaryReader(writer.getBuffer());
|
|
38
38
|
|
|
39
39
|
console.log(reader.readObject());
|
|
40
|
+
/**
|
|
41
|
+
{
|
|
42
|
+
null: null,
|
|
43
|
+
uint8: 255,
|
|
44
|
+
uint16: 256,
|
|
45
|
+
uint32: 65536,
|
|
46
|
+
int8: -128,
|
|
47
|
+
int16: -32768,
|
|
48
|
+
int32: -2147483648,
|
|
49
|
+
double: 3.14,
|
|
50
|
+
string: 'Hello world',
|
|
51
|
+
vector: [ 1, 2, 3, 4, 5, { text: 'hi' } ],
|
|
52
|
+
map: { foo: 'bar' },
|
|
53
|
+
date: 2023-07-03T12:22:26.000Z
|
|
54
|
+
}
|
|
55
|
+
*/
|
|
40
56
|
```
|
|
41
57
|
|
|
42
58
|
## Supported Types
|
|
@@ -73,9 +89,9 @@ const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
|
73
89
|
const dataStream = new Readable({ objectMode: true });
|
|
74
90
|
|
|
75
91
|
dataStream._read = () => {
|
|
76
|
-
|
|
92
|
+
const chunk = values.shift();
|
|
77
93
|
|
|
78
|
-
|
|
94
|
+
dataStream.push(chunk || null);
|
|
79
95
|
};
|
|
80
96
|
|
|
81
97
|
const encode = new TLEncode();
|
|
@@ -96,31 +112,38 @@ import { BinaryWriter, BinaryReader, createExtension } from '@andrew_l/tl-pack';
|
|
|
96
112
|
const ObjectId = mongoose.Types.ObjectId;
|
|
97
113
|
|
|
98
114
|
const extensions = [
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
// Reserving token - 100 for ObjectId types
|
|
116
|
+
createExtension(100, {
|
|
117
|
+
encode(value) {
|
|
118
|
+
if (value?._bsontype === 'ObjectID') {
|
|
119
|
+
return value.toJSON(); // (string)
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
// on client side, you possibly need a decoding as a plain string.
|
|
123
|
+
decode(value) {
|
|
124
|
+
return new ObjectId(value);
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
111
127
|
];
|
|
112
128
|
|
|
113
129
|
const writer = new BinaryWriter({ extensions });
|
|
114
130
|
|
|
115
131
|
writer.writeObject({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
132
|
+
_id: new Object(),
|
|
133
|
+
firstName: 'Andrew',
|
|
134
|
+
lastName: 'L.',
|
|
119
135
|
});
|
|
120
136
|
|
|
121
137
|
const reader = new BinaryReader(writer.getBuffer(), { extensions });
|
|
122
138
|
|
|
123
139
|
console.log(reader.readObject());
|
|
140
|
+
/**
|
|
141
|
+
{
|
|
142
|
+
_id: 64a2be105e19f67e19a71a1d,
|
|
143
|
+
firstName: 'Andrew',
|
|
144
|
+
lastName: 'L.'
|
|
145
|
+
}
|
|
146
|
+
*/
|
|
124
147
|
```
|
|
125
148
|
|
|
126
149
|
## Dictionary
|
package/dist/BinaryReader.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { CORE_TYPES } from './constants.js';
|
|
2
3
|
import { Dictionary } from './dictionary.js';
|
|
3
4
|
import { TLExtension } from './extension.js';
|
|
4
5
|
export interface BinaryReaderOptions {
|
|
@@ -7,7 +8,6 @@ export interface BinaryReaderOptions {
|
|
|
7
8
|
}
|
|
8
9
|
export declare class BinaryReader {
|
|
9
10
|
private target;
|
|
10
|
-
private targetView;
|
|
11
11
|
private _last?;
|
|
12
12
|
private dictionary?;
|
|
13
13
|
private dictionaryExtended;
|
|
@@ -38,18 +38,19 @@ export declare class BinaryReader {
|
|
|
38
38
|
* @param length {number}
|
|
39
39
|
*/
|
|
40
40
|
assertRead(length: number): void;
|
|
41
|
+
assertConstructor(constructorId: CORE_TYPES): void;
|
|
41
42
|
/**
|
|
42
43
|
* Gets the byte array representing the current buffer as a whole.
|
|
43
44
|
* @returns {Buffer}
|
|
44
45
|
*/
|
|
45
|
-
getBuffer():
|
|
46
|
+
getBuffer(): Buffer | Uint8Array;
|
|
46
47
|
readNull(): null;
|
|
47
48
|
readLength(): number;
|
|
48
49
|
readAll(): any[];
|
|
49
50
|
/**
|
|
50
51
|
* @returns {Uint8Array | Buffer}
|
|
51
52
|
*/
|
|
52
|
-
readBytes():
|
|
53
|
+
readBytes(): Buffer | Uint8Array;
|
|
53
54
|
/**
|
|
54
55
|
* Reads encoded string.
|
|
55
56
|
* @returns {string}
|
|
@@ -82,6 +83,11 @@ export declare class BinaryReader {
|
|
|
82
83
|
* @returns {any[]}
|
|
83
84
|
*/
|
|
84
85
|
readVector(checkConstructor?: boolean): any[];
|
|
86
|
+
/**
|
|
87
|
+
* Reads a vector (a list) of objects.
|
|
88
|
+
* @returns {any[]}
|
|
89
|
+
*/
|
|
90
|
+
readVectorDynamic(checkConstructor?: boolean): any[];
|
|
85
91
|
/**
|
|
86
92
|
* Tells the current position on the stream.
|
|
87
93
|
* @returns {number}
|
package/dist/BinaryReader.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import pako from 'pako';
|
|
2
2
|
import { CORE_TYPES } from './constants.js';
|
|
3
3
|
import { Dictionary } from './dictionary.js';
|
|
4
|
-
import { bytesToUtf8 } from './helpers.js';
|
|
4
|
+
import { bytesToUtf8, float32, float64, int32 } from './helpers.js';
|
|
5
5
|
export class BinaryReader {
|
|
6
6
|
target;
|
|
7
|
-
targetView;
|
|
8
7
|
_last;
|
|
9
8
|
dictionary;
|
|
10
9
|
dictionaryExtended;
|
|
@@ -17,7 +16,6 @@ export class BinaryReader {
|
|
|
17
16
|
*/
|
|
18
17
|
constructor(data, options) {
|
|
19
18
|
this.target = data;
|
|
20
|
-
this.targetView = new DataView(data.buffer, 0, data.length);
|
|
21
19
|
this._last = undefined;
|
|
22
20
|
this.offset = 0;
|
|
23
21
|
this.length = data.length;
|
|
@@ -48,35 +46,30 @@ export class BinaryReader {
|
|
|
48
46
|
}
|
|
49
47
|
readInt32(signed = true) {
|
|
50
48
|
this.assertRead(4);
|
|
51
|
-
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
this._last =
|
|
50
|
+
this.target[this.offset++] |
|
|
51
|
+
(this.target[this.offset++] << 8) |
|
|
52
|
+
(this.target[this.offset++] << 16) |
|
|
53
|
+
(this.target[this.offset++] << 24);
|
|
54
|
+
if (!signed) {
|
|
55
|
+
this._last = this._last >>> 0;
|
|
56
56
|
}
|
|
57
|
-
this.offset += 4;
|
|
58
57
|
return this._last;
|
|
59
58
|
}
|
|
60
59
|
readInt16(signed = true) {
|
|
61
60
|
this.assertRead(2);
|
|
61
|
+
this._last = this.target[this.offset++] | (this.target[this.offset++] << 8);
|
|
62
62
|
if (signed) {
|
|
63
|
-
this._last =
|
|
63
|
+
this._last = (this._last << 16) >> 16;
|
|
64
64
|
}
|
|
65
|
-
else {
|
|
66
|
-
this._last = this.targetView.getUint16(this.offset, true);
|
|
67
|
-
}
|
|
68
|
-
this.offset += 2;
|
|
69
65
|
return this._last;
|
|
70
66
|
}
|
|
71
67
|
readInt8(signed = true) {
|
|
72
68
|
this.assertRead(1);
|
|
69
|
+
this._last = this.target[this.offset++];
|
|
73
70
|
if (signed) {
|
|
74
|
-
this._last =
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
this._last = this.targetView.getUint8(this.offset);
|
|
71
|
+
this._last = (this._last << 24) >> 24;
|
|
78
72
|
}
|
|
79
|
-
this.offset += 1;
|
|
80
73
|
return this._last;
|
|
81
74
|
}
|
|
82
75
|
/**
|
|
@@ -85,8 +78,8 @@ export class BinaryReader {
|
|
|
85
78
|
*/
|
|
86
79
|
readFloat() {
|
|
87
80
|
this.assertRead(4);
|
|
88
|
-
|
|
89
|
-
this.
|
|
81
|
+
int32[0] = this.readInt32();
|
|
82
|
+
this._last = float32[0];
|
|
90
83
|
return this._last;
|
|
91
84
|
}
|
|
92
85
|
/**
|
|
@@ -95,8 +88,9 @@ export class BinaryReader {
|
|
|
95
88
|
*/
|
|
96
89
|
readDouble() {
|
|
97
90
|
this.assertRead(8);
|
|
98
|
-
|
|
99
|
-
this.
|
|
91
|
+
int32[0] = this.readInt32();
|
|
92
|
+
int32[1] = this.readInt32();
|
|
93
|
+
this._last = float64[0];
|
|
100
94
|
return this._last;
|
|
101
95
|
}
|
|
102
96
|
/**
|
|
@@ -113,6 +107,12 @@ export class BinaryReader {
|
|
|
113
107
|
throw err;
|
|
114
108
|
}
|
|
115
109
|
}
|
|
110
|
+
assertConstructor(constructorId) {
|
|
111
|
+
const byte = this.readByte();
|
|
112
|
+
if (byte !== constructorId) {
|
|
113
|
+
throw new Error(`Invalid constructor code, expected = ${CORE_TYPES[constructorId]}, got = ${CORE_TYPES[byte] || byte}, offset = ${this.offset - 1}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
116
|
/**
|
|
117
117
|
* Gets the byte array representing the current buffer as a whole.
|
|
118
118
|
* @returns {Buffer}
|
|
@@ -227,6 +227,8 @@ export class BinaryReader {
|
|
|
227
227
|
return false;
|
|
228
228
|
case CORE_TYPES.Vector:
|
|
229
229
|
return this.readVector(false);
|
|
230
|
+
case CORE_TYPES.VectorDynamic:
|
|
231
|
+
return this.readVectorDynamic(false);
|
|
230
232
|
case CORE_TYPES.Null:
|
|
231
233
|
return null;
|
|
232
234
|
case CORE_TYPES.Binary:
|
|
@@ -291,8 +293,8 @@ export class BinaryReader {
|
|
|
291
293
|
return key;
|
|
292
294
|
}
|
|
293
295
|
readMap(checkConstructor = true) {
|
|
294
|
-
if (checkConstructor
|
|
295
|
-
|
|
296
|
+
if (checkConstructor) {
|
|
297
|
+
this.assertConstructor(CORE_TYPES.Map);
|
|
296
298
|
}
|
|
297
299
|
const temp = {};
|
|
298
300
|
let key = this.readDictionary();
|
|
@@ -304,7 +306,6 @@ export class BinaryReader {
|
|
|
304
306
|
}
|
|
305
307
|
decode(value) {
|
|
306
308
|
this.target = value;
|
|
307
|
-
this.targetView = new DataView(value.buffer, 0, value.length);
|
|
308
309
|
this._last = undefined;
|
|
309
310
|
this.offset = 0;
|
|
310
311
|
this.length = value.length;
|
|
@@ -315,8 +316,8 @@ export class BinaryReader {
|
|
|
315
316
|
* @returns {any[]}
|
|
316
317
|
*/
|
|
317
318
|
readVector(checkConstructor = true) {
|
|
318
|
-
if (checkConstructor
|
|
319
|
-
|
|
319
|
+
if (checkConstructor) {
|
|
320
|
+
this.assertConstructor(CORE_TYPES.Vector);
|
|
320
321
|
}
|
|
321
322
|
const count = this.readLength();
|
|
322
323
|
const temp = [];
|
|
@@ -325,6 +326,41 @@ export class BinaryReader {
|
|
|
325
326
|
}
|
|
326
327
|
return temp;
|
|
327
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Reads a vector (a list) of objects.
|
|
331
|
+
* @returns {any[]}
|
|
332
|
+
*/
|
|
333
|
+
readVectorDynamic(checkConstructor = true) {
|
|
334
|
+
if (checkConstructor) {
|
|
335
|
+
this.assertConstructor(CORE_TYPES.VectorDynamic);
|
|
336
|
+
}
|
|
337
|
+
const temp = [];
|
|
338
|
+
let complete = false;
|
|
339
|
+
while (this.length > this.offset) {
|
|
340
|
+
const constructorId = this.readByte();
|
|
341
|
+
if (constructorId === CORE_TYPES.None) {
|
|
342
|
+
complete = true;
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
const ext = this.extensions.get(constructorId);
|
|
346
|
+
let value;
|
|
347
|
+
if (ext) {
|
|
348
|
+
value = this.readObject();
|
|
349
|
+
value = ext.decode(value);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
value = this.readCore(constructorId);
|
|
353
|
+
}
|
|
354
|
+
temp.push(value);
|
|
355
|
+
}
|
|
356
|
+
if (!complete) {
|
|
357
|
+
const err = new Error(`DynamicVector incomplete.`);
|
|
358
|
+
err.incomplete = true;
|
|
359
|
+
Error.captureStackTrace(err, this.readDictionary);
|
|
360
|
+
throw err;
|
|
361
|
+
}
|
|
362
|
+
return temp;
|
|
363
|
+
}
|
|
328
364
|
/**
|
|
329
365
|
* Tells the current position on the stream.
|
|
330
366
|
* @returns {number}
|
package/dist/BinaryWriter.d.ts
CHANGED
|
@@ -9,16 +9,15 @@ export interface BinaryWriterOptions {
|
|
|
9
9
|
export declare class BinaryWriter {
|
|
10
10
|
private withGzip;
|
|
11
11
|
private target;
|
|
12
|
-
private targetView;
|
|
13
12
|
private dictionary?;
|
|
14
13
|
private dictionaryExtended;
|
|
15
14
|
private extensions;
|
|
16
15
|
offset: number;
|
|
17
16
|
constructor(options?: BinaryWriterOptions);
|
|
18
17
|
allocate(size: number): void;
|
|
19
|
-
makeRoom
|
|
18
|
+
private makeRoom;
|
|
20
19
|
get safeEnd(): number;
|
|
21
|
-
getBuffer():
|
|
20
|
+
getBuffer(): Buffer | Uint8Array;
|
|
22
21
|
writeByte(value: number): void;
|
|
23
22
|
writeBool(value: boolean): void;
|
|
24
23
|
writeNull(): void;
|
|
@@ -35,7 +34,9 @@ export declare class BinaryWriter {
|
|
|
35
34
|
writeMap(object: Record<string, any>): void;
|
|
36
35
|
wireDictionary(value: string): void;
|
|
37
36
|
writeGzip(value: any): void;
|
|
38
|
-
encode(value: any):
|
|
37
|
+
encode(value: any): Buffer | Uint8Array;
|
|
38
|
+
startDynamicVector(): void;
|
|
39
|
+
endDynamicVector(): void;
|
|
39
40
|
private _writeCustom;
|
|
40
41
|
writeObject(value: any): void;
|
|
41
42
|
writeObjectGzip(value: any): void;
|
package/dist/BinaryWriter.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pako from 'pako';
|
|
2
2
|
import { CORE_TYPES } from './constants.js';
|
|
3
3
|
import { Dictionary } from './dictionary.js';
|
|
4
|
-
import { coreType } from './helpers.js';
|
|
4
|
+
import { coreType, float32, float64, int32 } from './helpers.js';
|
|
5
5
|
const hasNodeBuffer = typeof Buffer !== 'undefined';
|
|
6
6
|
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
|
|
7
7
|
const textEncoder = new TextEncoder();
|
|
@@ -24,7 +24,6 @@ const SUPPORT_COMPRESSION = new Set([CORE_TYPES.String]);
|
|
|
24
24
|
export class BinaryWriter {
|
|
25
25
|
withGzip;
|
|
26
26
|
target;
|
|
27
|
-
targetView;
|
|
28
27
|
dictionary;
|
|
29
28
|
dictionaryExtended;
|
|
30
29
|
extensions;
|
|
@@ -34,7 +33,6 @@ export class BinaryWriter {
|
|
|
34
33
|
this.extensions = new Map();
|
|
35
34
|
this.withGzip = !!options && !!options.gzip;
|
|
36
35
|
this.target = byteArrayAllocate(8192);
|
|
37
|
-
this.targetView = new DataView(this.target.buffer, 0, this.target.length);
|
|
38
36
|
if (options && options.extensions) {
|
|
39
37
|
options.extensions.forEach((ext) => {
|
|
40
38
|
this.extensions.set(ext.token, ext);
|
|
@@ -85,7 +83,6 @@ export class BinaryWriter {
|
|
|
85
83
|
newBuffer.set(target.slice(start, end));
|
|
86
84
|
}
|
|
87
85
|
this.target = newBuffer;
|
|
88
|
-
this.targetView = newView;
|
|
89
86
|
}
|
|
90
87
|
get safeEnd() {
|
|
91
88
|
return this.target.length - 10;
|
|
@@ -111,41 +108,43 @@ export class BinaryWriter {
|
|
|
111
108
|
writeInt32(value, signed = true) {
|
|
112
109
|
this.allocate(4);
|
|
113
110
|
if (signed) {
|
|
114
|
-
this.
|
|
111
|
+
this.target[this.offset++] = value;
|
|
112
|
+
this.target[this.offset++] = value >> 8;
|
|
113
|
+
this.target[this.offset++] = value >> 16;
|
|
114
|
+
this.target[this.offset++] = value >> 24;
|
|
115
115
|
}
|
|
116
116
|
else {
|
|
117
|
-
this.
|
|
117
|
+
this.target[this.offset++] = value;
|
|
118
|
+
this.target[this.offset++] = value >> 8;
|
|
119
|
+
this.target[this.offset++] = value >> 16;
|
|
120
|
+
this.target[this.offset++] = value >> 24;
|
|
118
121
|
}
|
|
119
|
-
this.offset += 4;
|
|
120
122
|
}
|
|
121
123
|
writeInt16(value, signed = true) {
|
|
122
124
|
this.allocate(2);
|
|
123
125
|
if (signed) {
|
|
124
|
-
this.
|
|
126
|
+
this.target[this.offset++] = value;
|
|
127
|
+
this.target[this.offset++] = value >> 8;
|
|
125
128
|
}
|
|
126
129
|
else {
|
|
127
|
-
this.
|
|
130
|
+
this.target[this.offset++] = value;
|
|
131
|
+
this.target[this.offset++] = value >> 8;
|
|
128
132
|
}
|
|
129
|
-
this.offset += 2;
|
|
130
133
|
}
|
|
131
134
|
writeInt8(value, signed = true) {
|
|
132
135
|
this.allocate(1);
|
|
133
|
-
|
|
134
|
-
this.target[this.offset++] = value;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
this.targetView.setUint8(this.offset++, value);
|
|
138
|
-
}
|
|
136
|
+
this.target[this.offset++] = value;
|
|
139
137
|
}
|
|
140
138
|
writeFloat(value) {
|
|
141
139
|
this.allocate(4);
|
|
142
|
-
|
|
143
|
-
this.
|
|
140
|
+
float32[0] = value;
|
|
141
|
+
this.writeInt32(int32[0]);
|
|
144
142
|
}
|
|
145
143
|
writeDouble(value) {
|
|
146
144
|
this.allocate(8);
|
|
147
|
-
|
|
148
|
-
this.
|
|
145
|
+
float64[0] = value;
|
|
146
|
+
this.writeInt32(int32[0], false);
|
|
147
|
+
this.writeInt32(int32[1], false);
|
|
149
148
|
}
|
|
150
149
|
writeDate(value) {
|
|
151
150
|
let timestamp = 0;
|
|
@@ -247,10 +246,15 @@ export class BinaryWriter {
|
|
|
247
246
|
encode(value) {
|
|
248
247
|
this.offset = 0;
|
|
249
248
|
this.target = byteArrayAllocate(256);
|
|
250
|
-
this.targetView = new DataView(this.target.buffer, 0, this.target.length);
|
|
251
249
|
this.writeObject(value);
|
|
252
250
|
return this.getBuffer();
|
|
253
251
|
}
|
|
252
|
+
startDynamicVector() {
|
|
253
|
+
this.writeByte(CORE_TYPES.VectorDynamic);
|
|
254
|
+
}
|
|
255
|
+
endDynamicVector() {
|
|
256
|
+
this.writeByte(CORE_TYPES.None);
|
|
257
|
+
}
|
|
254
258
|
_writeCustom(value) {
|
|
255
259
|
for (const ext of this.extensions.values()) {
|
|
256
260
|
const result = ext.encode(value);
|
|
@@ -294,7 +298,6 @@ export class BinaryWriter {
|
|
|
294
298
|
this.writeCore(CORE_TYPES.GZIP, writer.getBuffer());
|
|
295
299
|
}
|
|
296
300
|
writeCore(constructorId, value) {
|
|
297
|
-
// console.log('write', { constructorId: CORE_TYPES[constructorId] || constructorId, value });
|
|
298
301
|
if (this.withGzip && SUPPORT_COMPRESSION.has(constructorId)) {
|
|
299
302
|
this.writeObjectGzip(value);
|
|
300
303
|
return;
|
package/dist/constants.d.ts
CHANGED
|
@@ -6,17 +6,18 @@ export declare enum CORE_TYPES {
|
|
|
6
6
|
Null = 4,
|
|
7
7
|
Date = 5,
|
|
8
8
|
Vector = 6,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
VectorDynamic = 7,
|
|
10
|
+
Int32 = 8,
|
|
11
|
+
Int16 = 9,
|
|
12
|
+
Int8 = 10,
|
|
13
|
+
UInt32 = 11,
|
|
14
|
+
UInt16 = 12,
|
|
15
|
+
UInt8 = 13,
|
|
16
|
+
Float = 14,
|
|
17
|
+
Double = 15,
|
|
18
|
+
Map = 16,
|
|
19
|
+
DictValue = 17,
|
|
20
|
+
DictIndex = 18,
|
|
21
|
+
String = 19,
|
|
22
|
+
GZIP = 25
|
|
22
23
|
}
|
package/dist/constants.js
CHANGED
|
@@ -7,17 +7,18 @@ export var CORE_TYPES;
|
|
|
7
7
|
CORE_TYPES[CORE_TYPES["Null"] = 4] = "Null";
|
|
8
8
|
CORE_TYPES[CORE_TYPES["Date"] = 5] = "Date";
|
|
9
9
|
CORE_TYPES[CORE_TYPES["Vector"] = 6] = "Vector";
|
|
10
|
-
CORE_TYPES[CORE_TYPES["
|
|
11
|
-
CORE_TYPES[CORE_TYPES["
|
|
12
|
-
CORE_TYPES[CORE_TYPES["
|
|
13
|
-
CORE_TYPES[CORE_TYPES["
|
|
14
|
-
CORE_TYPES[CORE_TYPES["
|
|
15
|
-
CORE_TYPES[CORE_TYPES["
|
|
16
|
-
CORE_TYPES[CORE_TYPES["
|
|
17
|
-
CORE_TYPES[CORE_TYPES["
|
|
18
|
-
CORE_TYPES[CORE_TYPES["
|
|
19
|
-
CORE_TYPES[CORE_TYPES["
|
|
20
|
-
CORE_TYPES[CORE_TYPES["
|
|
21
|
-
CORE_TYPES[CORE_TYPES["
|
|
22
|
-
CORE_TYPES[CORE_TYPES["
|
|
10
|
+
CORE_TYPES[CORE_TYPES["VectorDynamic"] = 7] = "VectorDynamic";
|
|
11
|
+
CORE_TYPES[CORE_TYPES["Int32"] = 8] = "Int32";
|
|
12
|
+
CORE_TYPES[CORE_TYPES["Int16"] = 9] = "Int16";
|
|
13
|
+
CORE_TYPES[CORE_TYPES["Int8"] = 10] = "Int8";
|
|
14
|
+
CORE_TYPES[CORE_TYPES["UInt32"] = 11] = "UInt32";
|
|
15
|
+
CORE_TYPES[CORE_TYPES["UInt16"] = 12] = "UInt16";
|
|
16
|
+
CORE_TYPES[CORE_TYPES["UInt8"] = 13] = "UInt8";
|
|
17
|
+
CORE_TYPES[CORE_TYPES["Float"] = 14] = "Float";
|
|
18
|
+
CORE_TYPES[CORE_TYPES["Double"] = 15] = "Double";
|
|
19
|
+
CORE_TYPES[CORE_TYPES["Map"] = 16] = "Map";
|
|
20
|
+
CORE_TYPES[CORE_TYPES["DictValue"] = 17] = "DictValue";
|
|
21
|
+
CORE_TYPES[CORE_TYPES["DictIndex"] = 18] = "DictIndex";
|
|
22
|
+
CORE_TYPES[CORE_TYPES["String"] = 19] = "String";
|
|
23
|
+
CORE_TYPES[CORE_TYPES["GZIP"] = 25] = "GZIP";
|
|
23
24
|
})(CORE_TYPES || (CORE_TYPES = {}));
|
package/dist/extension.js
CHANGED
|
@@ -2,6 +2,9 @@ export function createExtension(token, { encode, decode }) {
|
|
|
2
2
|
if (token !== -1 && (token > 254 || token < 0 || token << 0 !== token)) {
|
|
3
3
|
throw new TypeError('Token must be a 8 bit number');
|
|
4
4
|
}
|
|
5
|
+
if (token < 35) {
|
|
6
|
+
throw new TypeError('Tokens reserved from 0 to 34');
|
|
7
|
+
}
|
|
5
8
|
return {
|
|
6
9
|
token,
|
|
7
10
|
encode,
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { CORE_TYPES } from './constants.js';
|
|
3
|
-
export declare
|
|
3
|
+
export declare const int32: Int32Array;
|
|
4
|
+
export declare const float32: Float32Array;
|
|
5
|
+
export declare const float64: Float64Array;
|
|
4
6
|
export declare function bytesToUtf8(bytes: Buffer | Uint8Array): string;
|
|
5
7
|
export declare function utf8ToBytes(string: string): Uint8Array;
|
|
6
|
-
export declare function serializeBytes(value: Buffer | Uint8Array | string | any): Uint8Array;
|
|
7
|
-
export declare function serializeLength(value: number): Buffer;
|
|
8
8
|
export declare function coreType(value: any): CORE_TYPES;
|
package/dist/helpers.js
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { CORE_TYPES } from './constants.js';
|
|
2
2
|
const textEncoder = new TextEncoder();
|
|
3
3
|
const textDecoder = new TextDecoder();
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
totalLength += array.length;
|
|
8
|
-
}
|
|
9
|
-
const result = new Uint8Array(totalLength);
|
|
10
|
-
let offset = 0;
|
|
11
|
-
for (const array of arrays) {
|
|
12
|
-
result.set(array, offset);
|
|
13
|
-
offset += array.length;
|
|
14
|
-
}
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
4
|
+
export const int32 = new Int32Array(2);
|
|
5
|
+
export const float32 = new Float32Array(int32.buffer);
|
|
6
|
+
export const float64 = new Float64Array(int32.buffer);
|
|
17
7
|
export function bytesToUtf8(bytes) {
|
|
18
8
|
return textDecoder.decode(bytes);
|
|
19
9
|
}
|
|
@@ -22,41 +12,6 @@ export function utf8ToBytes(string) {
|
|
|
22
12
|
const length = textEncoder.encodeInto(string, buff).written;
|
|
23
13
|
return buff.subarray(0, length);
|
|
24
14
|
}
|
|
25
|
-
export function serializeBytes(value) {
|
|
26
|
-
let data;
|
|
27
|
-
if (typeof value === 'string') {
|
|
28
|
-
data = utf8ToBytes(value);
|
|
29
|
-
}
|
|
30
|
-
else if (value instanceof Buffer) {
|
|
31
|
-
data = value;
|
|
32
|
-
}
|
|
33
|
-
else if (value instanceof Uint8Array) {
|
|
34
|
-
data = value;
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
throw Error(`Bytes or str expected, not ${value.constructor.name}`);
|
|
38
|
-
}
|
|
39
|
-
let length = data.length;
|
|
40
|
-
let header;
|
|
41
|
-
if (length < 254) {
|
|
42
|
-
header = new Uint8Array(1);
|
|
43
|
-
header[0] = length;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
header = new Uint8Array(4);
|
|
47
|
-
header[0] = 254;
|
|
48
|
-
header[1] = length % 256;
|
|
49
|
-
header[2] = (length >> 8) % 256;
|
|
50
|
-
header[3] = (length >> 16) % 256;
|
|
51
|
-
}
|
|
52
|
-
return concatUint8Arrays([header, data]);
|
|
53
|
-
}
|
|
54
|
-
export function serializeLength(value) {
|
|
55
|
-
if (value < 254) {
|
|
56
|
-
return Buffer.from([value]);
|
|
57
|
-
}
|
|
58
|
-
return Buffer.from([254, value % 256, (value >> 8) % 256, (value >> 16) % 256]);
|
|
59
|
-
}
|
|
60
15
|
export function coreType(value) {
|
|
61
16
|
switch (typeof value) {
|
|
62
17
|
case 'string': {
|
|
@@ -66,23 +21,25 @@ export function coreType(value) {
|
|
|
66
21
|
return value ? CORE_TYPES.BoolTrue : CORE_TYPES.BoolFalse;
|
|
67
22
|
}
|
|
68
23
|
case 'number': {
|
|
69
|
-
if (value
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
24
|
+
if (value >> 0 === value) {
|
|
25
|
+
if (value >= 0 && value <= 0xff) {
|
|
26
|
+
return CORE_TYPES.UInt8;
|
|
27
|
+
}
|
|
28
|
+
else if (value >= 0 && value <= 0xffff) {
|
|
29
|
+
return CORE_TYPES.UInt16;
|
|
30
|
+
}
|
|
31
|
+
else if (value >= 0 && value <= 0xffffffff) {
|
|
32
|
+
return CORE_TYPES.UInt32;
|
|
33
|
+
}
|
|
34
|
+
else if (value >= -0x80 && value <= 0x7f) {
|
|
35
|
+
return CORE_TYPES.Int8;
|
|
36
|
+
}
|
|
37
|
+
else if (value >= -0x8000 && value <= 0x7fff) {
|
|
38
|
+
return CORE_TYPES.Int16;
|
|
39
|
+
}
|
|
40
|
+
else if (value >= -0x80000000 && value <= 0x7fffffff) {
|
|
41
|
+
return CORE_TYPES.Int32;
|
|
42
|
+
}
|
|
86
43
|
}
|
|
87
44
|
return CORE_TYPES.Double;
|
|
88
45
|
}
|
package/dist/stream.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { BinaryWriter, BinaryWriterOptions } from './BinaryWriter.js';
|
|
|
5
5
|
import { BinaryReader } from './BinaryReader.js';
|
|
6
6
|
export interface TLEncodeOptions extends BinaryWriterOptions {
|
|
7
7
|
streamOptions?: TransformOptions;
|
|
8
|
-
writeVectorWhenEmpty?: boolean;
|
|
9
8
|
}
|
|
10
9
|
export declare class TLEncode extends Transform {
|
|
11
10
|
writer: BinaryWriter;
|
package/dist/stream.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Transform } from 'stream';
|
|
2
2
|
import { BinaryWriter } from './BinaryWriter.js';
|
|
3
3
|
import { BinaryReader } from './BinaryReader.js';
|
|
4
|
+
import { CORE_TYPES } from './constants.js';
|
|
4
5
|
export class TLEncode extends Transform {
|
|
5
6
|
writer;
|
|
6
7
|
count;
|
|
@@ -10,10 +11,14 @@ export class TLEncode extends Transform {
|
|
|
10
11
|
super(opts.streamOptions);
|
|
11
12
|
const writer = new BinaryWriter(options);
|
|
12
13
|
const customFlush = opts.streamOptions.flush;
|
|
14
|
+
const VECTOR_TYPES = new Uint8Array(2);
|
|
15
|
+
VECTOR_TYPES[0] = CORE_TYPES.VectorDynamic;
|
|
16
|
+
VECTOR_TYPES[1] = CORE_TYPES.None;
|
|
17
|
+
// push a byte about dynamic vector starting
|
|
18
|
+
this.push(VECTOR_TYPES.subarray(0, 1));
|
|
13
19
|
this._flush = (callback) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
20
|
+
// push a byte about dynamic vector ending
|
|
21
|
+
this.push(VECTOR_TYPES.subarray(1, 2));
|
|
17
22
|
if (customFlush) {
|
|
18
23
|
customFlush.call(this, callback);
|
|
19
24
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andrew_l/tl-pack",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nodemon src/playground.ts",
|
|
8
8
|
"build": "rm -rf dist && npx tsc"
|
|
9
9
|
},
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"tl",
|
|
12
|
+
"pack",
|
|
13
|
+
"binary",
|
|
14
|
+
"buffer",
|
|
15
|
+
"serialization",
|
|
16
|
+
"deserialization"
|
|
17
|
+
],
|
|
11
18
|
"author": "Andrew L.",
|
|
12
19
|
"license": "ISC",
|
|
13
20
|
"files": [
|