@colyseus/schema 3.0.0-alpha.4 → 3.0.0-alpha.41
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 +148 -62
- package/bin/schema-debug +94 -0
- package/build/cjs/index.js +2201 -1507
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +2198 -1506
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +2208 -1514
- package/lib/Metadata.d.ts +21 -9
- package/lib/Metadata.js +169 -32
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +19 -4
- package/lib/Reflection.js +66 -32
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +4 -4
- package/lib/Schema.js +44 -50
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +31 -34
- package/lib/annotations.js +110 -160
- package/lib/annotations.js.map +1 -1
- package/lib/bench_encode.d.ts +1 -0
- package/lib/bench_encode.js +130 -0
- package/lib/bench_encode.js.map +1 -0
- package/lib/codegen/api.js +1 -2
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/languages/cpp.js +1 -2
- package/lib/codegen/languages/cpp.js.map +1 -1
- package/lib/codegen/languages/csharp.js +2 -46
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +1 -2
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/java.js +1 -2
- package/lib/codegen/languages/java.js.map +1 -1
- package/lib/codegen/languages/js.js +1 -2
- package/lib/codegen/languages/js.js.map +1 -1
- package/lib/codegen/languages/lua.js +1 -2
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/codegen/languages/ts.js +1 -2
- package/lib/codegen/languages/ts.js.map +1 -1
- package/lib/codegen/parser.js +85 -3
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +6 -3
- package/lib/codegen/types.js.map +1 -1
- package/lib/debug.d.ts +1 -0
- package/lib/debug.js +51 -0
- package/lib/debug.js.map +1 -0
- package/lib/decoder/DecodeOperation.d.ts +3 -4
- package/lib/decoder/DecodeOperation.js +37 -19
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +6 -7
- package/lib/decoder/Decoder.js +14 -14
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/ReferenceTracker.js +3 -2
- package/lib/decoder/ReferenceTracker.js.map +1 -1
- package/lib/decoder/strategy/RawChanges.js +1 -2
- package/lib/decoder/strategy/RawChanges.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
- package/lib/decoder/strategy/StateCallbacks.js +75 -65
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +27 -21
- package/lib/encoder/ChangeTree.js +246 -186
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.d.ts +3 -6
- package/lib/encoder/EncodeOperation.js +51 -65
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +9 -8
- package/lib/encoder/Encoder.js +168 -91
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +22 -0
- package/lib/encoder/Root.js +81 -0
- package/lib/encoder/Root.js.map +1 -0
- package/lib/encoder/StateView.d.ts +7 -7
- package/lib/encoder/StateView.js +70 -74
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/assert.d.ts +7 -6
- package/lib/encoding/assert.js +13 -5
- package/lib/encoding/assert.js.map +1 -1
- package/lib/encoding/decode.d.ts +35 -20
- package/lib/encoding/decode.js +43 -87
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +36 -17
- package/lib/encoding/encode.js +82 -68
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +4 -5
- package/lib/encoding/spec.js +1 -2
- package/lib/encoding/spec.js.map +1 -1
- package/lib/index.d.ts +10 -9
- package/lib/index.js +24 -17
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.d.ts +23 -0
- package/lib/types/TypeContext.js +111 -0
- package/lib/types/TypeContext.js.map +1 -0
- package/lib/types/custom/ArraySchema.d.ts +2 -2
- package/lib/types/custom/ArraySchema.js +33 -22
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/CollectionSchema.js +1 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -1
- package/lib/types/custom/MapSchema.d.ts +3 -1
- package/lib/types/custom/MapSchema.js +12 -4
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/custom/SetSchema.js +1 -0
- package/lib/types/custom/SetSchema.js.map +1 -1
- package/lib/types/registry.d.ts +8 -1
- package/lib/types/registry.js +23 -6
- package/lib/types/registry.js.map +1 -1
- package/lib/types/symbols.d.ts +8 -5
- package/lib/types/symbols.js +9 -6
- package/lib/types/symbols.js.map +1 -1
- package/lib/types/utils.js +1 -2
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +9 -7
- package/lib/utils.js.map +1 -1
- package/package.json +7 -6
- package/src/Metadata.ts +190 -42
- package/src/Reflection.ts +77 -39
- package/src/Schema.ts +59 -64
- package/src/annotations.ts +156 -202
- package/src/bench_encode.ts +108 -0
- package/src/codegen/languages/csharp.ts +1 -47
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/debug.ts +55 -0
- package/src/decoder/DecodeOperation.ts +46 -18
- package/src/decoder/Decoder.ts +17 -15
- package/src/decoder/ReferenceTracker.ts +3 -2
- package/src/decoder/strategy/StateCallbacks.ts +153 -82
- package/src/encoder/ChangeTree.ts +286 -202
- package/src/encoder/EncodeOperation.ts +78 -78
- package/src/encoder/Encoder.ts +202 -97
- package/src/encoder/Root.ts +93 -0
- package/src/encoder/StateView.ts +76 -88
- package/src/encoding/assert.ts +17 -8
- package/src/encoding/decode.ts +62 -97
- package/src/encoding/encode.ts +99 -65
- package/src/encoding/spec.ts +3 -5
- package/src/index.ts +12 -20
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +133 -0
- package/src/types/custom/ArraySchema.ts +49 -19
- package/src/types/custom/CollectionSchema.ts +1 -0
- package/src/types/custom/MapSchema.ts +18 -5
- package/src/types/custom/SetSchema.ts +1 -0
- package/src/types/registry.ts +22 -3
- package/src/types/symbols.ts +10 -7
- package/src/utils.ts +7 -3
package/src/encoding/encode.ts
CHANGED
|
@@ -35,28 +35,40 @@ let textEncoder: TextEncoder;
|
|
|
35
35
|
// @ts-ignore
|
|
36
36
|
try { textEncoder = new TextEncoder(); } catch (e) { }
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
// force little endian to facilitate decoding on multiple implementations
|
|
39
|
+
const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
40
|
+
const _convoBuffer = new ArrayBuffer(8);
|
|
41
|
+
const _int32 = new Int32Array(_convoBuffer);
|
|
42
|
+
const _float32 = new Float32Array(_convoBuffer);
|
|
43
|
+
const _float64 = new Float64Array(_convoBuffer);
|
|
44
|
+
const _int64 = new BigInt64Array(_convoBuffer);
|
|
45
|
+
|
|
46
|
+
const hasBufferByteLength = (typeof Buffer !== 'undefined' && Buffer.byteLength);
|
|
47
|
+
|
|
48
|
+
const utf8Length: (str: string, _?: any) => number = (hasBufferByteLength)
|
|
49
|
+
? Buffer.byteLength // node
|
|
50
|
+
: function (str: string, _?: any) {
|
|
51
|
+
var c = 0, length = 0;
|
|
52
|
+
for (var i = 0, l = str.length; i < l; i++) {
|
|
53
|
+
c = str.charCodeAt(i);
|
|
54
|
+
if (c < 0x80) {
|
|
55
|
+
length += 1;
|
|
56
|
+
}
|
|
57
|
+
else if (c < 0x800) {
|
|
58
|
+
length += 2;
|
|
59
|
+
}
|
|
60
|
+
else if (c < 0xd800 || c >= 0xe000) {
|
|
61
|
+
length += 3;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
i++;
|
|
65
|
+
length += 4;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return length;
|
|
54
69
|
}
|
|
55
|
-
}
|
|
56
|
-
return length;
|
|
57
|
-
}
|
|
58
70
|
|
|
59
|
-
|
|
71
|
+
function utf8Write(view: BufferLike, str: string, it: Iterator) {
|
|
60
72
|
var c = 0;
|
|
61
73
|
for (var i = 0, l = str.length; i < l; i++) {
|
|
62
74
|
c = str.charCodeAt(i);
|
|
@@ -64,51 +76,54 @@ export function utf8Write(view, str, it) {
|
|
|
64
76
|
view[it.offset++] = c;
|
|
65
77
|
}
|
|
66
78
|
else if (c < 0x800) {
|
|
67
|
-
view[it.offset
|
|
68
|
-
view[it.offset
|
|
79
|
+
view[it.offset] = 0xc0 | (c >> 6);
|
|
80
|
+
view[it.offset + 1] = 0x80 | (c & 0x3f);
|
|
81
|
+
it.offset += 2;
|
|
69
82
|
}
|
|
70
83
|
else if (c < 0xd800 || c >= 0xe000) {
|
|
71
|
-
view[it.offset
|
|
72
|
-
view[it.offset
|
|
73
|
-
view[it.offset
|
|
84
|
+
view[it.offset] = 0xe0 | (c >> 12);
|
|
85
|
+
view[it.offset+1] = 0x80 | (c >> 6 & 0x3f);
|
|
86
|
+
view[it.offset+2] = 0x80 | (c & 0x3f);
|
|
87
|
+
it.offset += 3;
|
|
74
88
|
}
|
|
75
89
|
else {
|
|
76
90
|
i++;
|
|
77
91
|
c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
|
|
78
|
-
view[it.offset
|
|
79
|
-
view[it.offset
|
|
80
|
-
view[it.offset
|
|
81
|
-
view[it.offset
|
|
92
|
+
view[it.offset] = 0xf0 | (c >> 18);
|
|
93
|
+
view[it.offset+1] = 0x80 | (c >> 12 & 0x3f);
|
|
94
|
+
view[it.offset+2] = 0x80 | (c >> 6 & 0x3f);
|
|
95
|
+
view[it.offset+3] = 0x80 | (c & 0x3f);
|
|
96
|
+
it.offset += 4;
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
99
|
}
|
|
85
100
|
|
|
86
|
-
|
|
101
|
+
function int8(bytes: BufferLike, value: number, it: Iterator) {
|
|
87
102
|
bytes[it.offset++] = value & 255;
|
|
88
103
|
};
|
|
89
104
|
|
|
90
|
-
|
|
105
|
+
function uint8(bytes: BufferLike, value: number, it: Iterator) {
|
|
91
106
|
bytes[it.offset++] = value & 255;
|
|
92
107
|
};
|
|
93
108
|
|
|
94
|
-
|
|
109
|
+
function int16(bytes: BufferLike, value: number, it: Iterator) {
|
|
95
110
|
bytes[it.offset++] = value & 255;
|
|
96
111
|
bytes[it.offset++] = (value >> 8) & 255;
|
|
97
112
|
};
|
|
98
113
|
|
|
99
|
-
|
|
114
|
+
function uint16(bytes: BufferLike, value: number, it: Iterator) {
|
|
100
115
|
bytes[it.offset++] = value & 255;
|
|
101
116
|
bytes[it.offset++] = (value >> 8) & 255;
|
|
102
117
|
};
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
function int32(bytes: BufferLike, value: number, it: Iterator) {
|
|
105
120
|
bytes[it.offset++] = value & 255;
|
|
106
121
|
bytes[it.offset++] = (value >> 8) & 255;
|
|
107
122
|
bytes[it.offset++] = (value >> 16) & 255;
|
|
108
123
|
bytes[it.offset++] = (value >> 24) & 255;
|
|
109
124
|
};
|
|
110
125
|
|
|
111
|
-
|
|
126
|
+
function uint32(bytes: BufferLike, value: number, it: Iterator) {
|
|
112
127
|
const b4 = value >> 24;
|
|
113
128
|
const b3 = value >> 16;
|
|
114
129
|
const b2 = value >> 8;
|
|
@@ -119,55 +134,52 @@ export function uint32(bytes: BufferLike, value: number, it: Iterator) {
|
|
|
119
134
|
bytes[it.offset++] = b4 & 255;
|
|
120
135
|
};
|
|
121
136
|
|
|
122
|
-
|
|
137
|
+
function int64(bytes: BufferLike, value: number, it: Iterator) {
|
|
123
138
|
const high = Math.floor(value / Math.pow(2, 32));
|
|
124
139
|
const low = value >>> 0;
|
|
125
140
|
uint32(bytes, low, it);
|
|
126
141
|
uint32(bytes, high, it);
|
|
127
142
|
};
|
|
128
143
|
|
|
129
|
-
|
|
144
|
+
function uint64(bytes: BufferLike, value: number, it: Iterator) {
|
|
130
145
|
const high = (value / Math.pow(2, 32)) >> 0;
|
|
131
146
|
const low = value >>> 0;
|
|
132
147
|
uint32(bytes, low, it);
|
|
133
148
|
uint32(bytes, high, it);
|
|
134
149
|
};
|
|
135
150
|
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
function bigint64(bytes: BufferLike, value: bigint, it: Iterator) {
|
|
152
|
+
_int64[0] = BigInt.asIntN(64, value);
|
|
153
|
+
int32(bytes, _int32[0], it);
|
|
154
|
+
int32(bytes, _int32[1], it);
|
|
138
155
|
}
|
|
139
156
|
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
function biguint64(bytes: BufferLike, value: bigint, it: Iterator) {
|
|
158
|
+
_int64[0] = BigInt.asIntN(64, value);
|
|
159
|
+
int32(bytes, _int32[0], it);
|
|
160
|
+
int32(bytes, _int32[1], it);
|
|
142
161
|
}
|
|
143
162
|
|
|
144
|
-
|
|
145
|
-
const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
146
|
-
const _int32 = new Int32Array(2);
|
|
147
|
-
const _float32 = new Float32Array(_int32.buffer);
|
|
148
|
-
const _float64 = new Float64Array(_int32.buffer);
|
|
149
|
-
|
|
150
|
-
export function writeFloat32(bytes: BufferLike, value: number, it: Iterator) {
|
|
163
|
+
function float32(bytes: BufferLike, value: number, it: Iterator) {
|
|
151
164
|
_float32[0] = value;
|
|
152
165
|
int32(bytes, _int32[0], it);
|
|
153
|
-
}
|
|
166
|
+
}
|
|
154
167
|
|
|
155
|
-
|
|
168
|
+
function float64(bytes: BufferLike, value: number, it: Iterator) {
|
|
156
169
|
_float64[0] = value;
|
|
157
170
|
int32(bytes, _int32[_isLittleEndian ? 0 : 1], it);
|
|
158
171
|
int32(bytes, _int32[_isLittleEndian ? 1 : 0], it);
|
|
159
|
-
}
|
|
172
|
+
}
|
|
160
173
|
|
|
161
|
-
|
|
174
|
+
function boolean(bytes: BufferLike, value: number, it: Iterator) {
|
|
162
175
|
bytes[it.offset++] = value ? 1 : 0; // uint8
|
|
163
176
|
};
|
|
164
177
|
|
|
165
|
-
|
|
178
|
+
function string(bytes: BufferLike, value: string, it: Iterator) {
|
|
166
179
|
// encode `null` strings as empty.
|
|
167
180
|
if (!value) { value = ""; }
|
|
168
181
|
|
|
169
|
-
|
|
170
|
-
let length = Buffer.byteLength(value, "utf8");
|
|
182
|
+
let length = utf8Length(value, "utf8");
|
|
171
183
|
let size = 0;
|
|
172
184
|
|
|
173
185
|
// fixstr
|
|
@@ -201,7 +213,7 @@ export function string(bytes: BufferLike, value: string, it: Iterator) {
|
|
|
201
213
|
return size + length;
|
|
202
214
|
}
|
|
203
215
|
|
|
204
|
-
|
|
216
|
+
function number(bytes: BufferLike, value: number, it: Iterator) {
|
|
205
217
|
if (isNaN(value)) {
|
|
206
218
|
return number(bytes, 0, it);
|
|
207
219
|
|
|
@@ -209,17 +221,19 @@ export function number(bytes: BufferLike, value: number, it: Iterator) {
|
|
|
209
221
|
return number(bytes, (value > 0) ? Number.MAX_SAFE_INTEGER : -Number.MAX_SAFE_INTEGER, it);
|
|
210
222
|
|
|
211
223
|
} else if (value !== (value|0)) {
|
|
224
|
+
if (Math.abs(value) <= 3.4028235e+38) { // range check
|
|
225
|
+
_float32[0] = value;
|
|
226
|
+
if (Math.abs(Math.abs(_float32[0]) - Math.abs(value)) < 1e-4) { // precision check; adjust 1e-n (n = precision) to in-/decrease acceptable precision loss
|
|
227
|
+
// now we know value is in range for f32 and has acceptable precision for f32
|
|
228
|
+
bytes[it.offset++] = 0xca;
|
|
229
|
+
float32(bytes, value, it);
|
|
230
|
+
return 5;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
212
234
|
bytes[it.offset++] = 0xcb;
|
|
213
|
-
|
|
235
|
+
float64(bytes, value, it);
|
|
214
236
|
return 9;
|
|
215
|
-
|
|
216
|
-
// TODO: encode float 32?
|
|
217
|
-
// is it possible to differentiate between float32 / float64 here?
|
|
218
|
-
|
|
219
|
-
// // float 32
|
|
220
|
-
// bytes.push(0xca);
|
|
221
|
-
// writeFloat32(bytes, value);
|
|
222
|
-
// return 5;
|
|
223
237
|
}
|
|
224
238
|
|
|
225
239
|
if (value >= 0) {
|
|
@@ -290,3 +304,23 @@ export function number(bytes: BufferLike, value: number, it: Iterator) {
|
|
|
290
304
|
return 9;
|
|
291
305
|
}
|
|
292
306
|
}
|
|
307
|
+
|
|
308
|
+
export const encode = {
|
|
309
|
+
int8,
|
|
310
|
+
uint8,
|
|
311
|
+
int16,
|
|
312
|
+
uint16,
|
|
313
|
+
int32,
|
|
314
|
+
uint32,
|
|
315
|
+
int64,
|
|
316
|
+
uint64,
|
|
317
|
+
bigint64,
|
|
318
|
+
biguint64,
|
|
319
|
+
float32,
|
|
320
|
+
float64,
|
|
321
|
+
boolean,
|
|
322
|
+
string,
|
|
323
|
+
number,
|
|
324
|
+
utf8Write,
|
|
325
|
+
utf8Length,
|
|
326
|
+
}
|
package/src/encoding/spec.ts
CHANGED
|
@@ -8,8 +8,8 @@ export enum OPERATION {
|
|
|
8
8
|
ADD = 128, // (10000000) add new structure/primitive
|
|
9
9
|
REPLACE = 0, // (00000001) replace structure/primitive
|
|
10
10
|
DELETE = 64, // (01000000) delete field
|
|
11
|
-
DELETE_AND_MOVE = 96, // ()
|
|
12
|
-
MOVE_AND_ADD = 160, // ()
|
|
11
|
+
DELETE_AND_MOVE = 96, // () ArraySchema only
|
|
12
|
+
MOVE_AND_ADD = 160, // () ArraySchema only
|
|
13
13
|
DELETE_AND_ADD = 192, // (11000000) DELETE field, followed by an ADD
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -20,10 +20,8 @@ export enum OPERATION {
|
|
|
20
20
|
/**
|
|
21
21
|
* ArraySchema operations
|
|
22
22
|
*/
|
|
23
|
-
PUSH = 11,
|
|
24
|
-
UNSHIFT = 12,
|
|
25
23
|
REVERSE = 15,
|
|
26
24
|
MOVE = 32,
|
|
27
25
|
DELETE_BY_REFID = 33, // This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE
|
|
28
|
-
|
|
26
|
+
ADD_BY_REFID = 129,
|
|
29
27
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export { Schema } from "./Schema";
|
|
2
2
|
export type { DataChange } from "./decoder/DecodeOperation";
|
|
3
|
-
|
|
4
|
-
import { $track, $encoder, $decoder, $filter, $getByIndex, $deleteByIndex, $changes, $childType } from "./types/symbols";
|
|
5
|
-
export { $track, $encoder, $decoder, $filter, $getByIndex, $deleteByIndex, $changes, $childType };
|
|
3
|
+
export type { ToJSON } from "./types/HelperTypes";
|
|
6
4
|
|
|
7
5
|
import { MapSchema } from "./types/custom/MapSchema"
|
|
8
6
|
export { MapSchema };
|
|
@@ -16,8 +14,8 @@ export { CollectionSchema };
|
|
|
16
14
|
import { SetSchema } from "./types/custom/SetSchema";
|
|
17
15
|
export { SetSchema };
|
|
18
16
|
|
|
19
|
-
import { registerType } from "./types/registry";
|
|
20
|
-
export { registerType };
|
|
17
|
+
import { registerType, defineCustomTypes } from "./types/registry";
|
|
18
|
+
export { registerType, defineCustomTypes };
|
|
21
19
|
|
|
22
20
|
registerType("map", { constructor: MapSchema });
|
|
23
21
|
registerType("array", { constructor: ArraySchema });
|
|
@@ -28,10 +26,9 @@ registerType("collection", { constructor: CollectionSchema, });
|
|
|
28
26
|
export { dumpChanges } from "./utils";
|
|
29
27
|
|
|
30
28
|
// Encoder / Decoder
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export { encode, decode };
|
|
29
|
+
export { $track, $encoder, $decoder, $filter, $getByIndex, $deleteByIndex, $changes, $childType } from "./types/symbols";
|
|
30
|
+
export { encode } from "./encoding/encode";
|
|
31
|
+
export { decode, type Iterator } from "./encoding/decode";
|
|
35
32
|
|
|
36
33
|
// Reflection
|
|
37
34
|
export {
|
|
@@ -40,22 +37,17 @@ export {
|
|
|
40
37
|
ReflectionField,
|
|
41
38
|
} from "./Reflection";
|
|
42
39
|
|
|
40
|
+
// Annotations, Metadata and TypeContext
|
|
43
41
|
export { Metadata } from "./Metadata";
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
// Annotations
|
|
47
|
-
type,
|
|
48
|
-
deprecated,
|
|
49
|
-
defineTypes,
|
|
50
|
-
view,
|
|
51
|
-
|
|
52
|
-
// Internals
|
|
53
|
-
TypeContext,
|
|
54
|
-
} from "./annotations";
|
|
42
|
+
export { type, deprecated, defineTypes, view, schema, type SchemaWithExtends, } from "./annotations";
|
|
43
|
+
export { TypeContext } from "./types/TypeContext";
|
|
55
44
|
|
|
56
45
|
// Annotation types
|
|
57
46
|
export type { DefinitionType, PrimitiveType, Definition, } from "./annotations";
|
|
58
47
|
|
|
48
|
+
export { getDecoderStateCallbacks, CallbackProxy, GetCallbackProxy } from "./decoder/strategy/StateCallbacks";
|
|
49
|
+
export { getRawChangesCallback } from "./decoder/strategy/RawChanges";
|
|
50
|
+
|
|
59
51
|
export { Encoder } from "./encoder/Encoder";
|
|
60
52
|
export { encodeSchemaOperation, encodeArray as encodeKeyValueOperation } from "./encoder/EncodeOperation";
|
|
61
53
|
export { ChangeTree, Ref } from "./encoder/ChangeTree";
|
package/src/types/HelperTypes.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from "../annotations";
|
|
2
|
+
import type { Schema } from "../Schema";
|
|
3
|
+
import type { ArraySchema } from "./custom/ArraySchema";
|
|
4
|
+
import type { CollectionSchema } from "./custom/CollectionSchema";
|
|
5
|
+
import type { MapSchema } from "./custom/MapSchema";
|
|
6
|
+
import type { SetSchema } from "./custom/SetSchema";
|
|
7
|
+
|
|
8
|
+
export type Constructor<T = {}> = new (...args: any[]) => T;
|
|
3
9
|
|
|
4
10
|
export interface Collection<K = any, V = any, IT = V> {
|
|
5
11
|
[Symbol.iterator](): IterableIterator<IT>;
|
|
@@ -7,6 +13,52 @@ export interface Collection<K = any, V = any, IT = V> {
|
|
|
7
13
|
entries(): IterableIterator<[K, V]>;
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
export type InferValueType<T extends DefinitionType> =
|
|
17
|
+
T extends "string" ? string
|
|
18
|
+
: T extends "number" ? number
|
|
19
|
+
: T extends "int8" ? number
|
|
20
|
+
: T extends "uint8" ? number
|
|
21
|
+
: T extends "int16" ? number
|
|
22
|
+
: T extends "uint16" ? number
|
|
23
|
+
: T extends "int32" ? number
|
|
24
|
+
: T extends "uint32" ? number
|
|
25
|
+
: T extends "int64" ? number
|
|
26
|
+
: T extends "uint64" ? number
|
|
27
|
+
: T extends "float32" ? number
|
|
28
|
+
: T extends "float64" ? number
|
|
29
|
+
: T extends "boolean" ? boolean
|
|
30
|
+
|
|
31
|
+
: T extends { type: infer ChildType extends Constructor } ? InstanceType<ChildType>
|
|
32
|
+
: T extends { type: infer ChildType extends PrimitiveType } ? ChildType
|
|
33
|
+
|
|
34
|
+
: T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[]
|
|
35
|
+
: T extends Array<infer ChildType extends RawPrimitiveType> ? ChildType[]
|
|
36
|
+
|
|
37
|
+
: T extends { array: infer ChildType extends Constructor } ? InstanceType<ChildType>[]
|
|
38
|
+
: T extends { array: infer ChildType extends PrimitiveType } ? ChildType[]
|
|
39
|
+
|
|
40
|
+
: T extends { map: infer ChildType extends Constructor } ? MapSchema<InstanceType<ChildType>>
|
|
41
|
+
: T extends { map: infer ChildType extends PrimitiveType } ? MapSchema<ChildType>
|
|
42
|
+
|
|
43
|
+
: T extends { set: infer ChildType extends Constructor } ? SetSchema<InstanceType<ChildType>>
|
|
44
|
+
: T extends { set: infer ChildType extends PrimitiveType } ? SetSchema<ChildType>
|
|
45
|
+
|
|
46
|
+
: T extends { collection: infer ChildType extends Constructor } ? CollectionSchema<InstanceType<ChildType>>
|
|
47
|
+
: T extends { collection: infer ChildType extends PrimitiveType } ? CollectionSchema<ChildType>
|
|
48
|
+
|
|
49
|
+
: T extends Constructor ? InstanceType<T>
|
|
50
|
+
: T extends PrimitiveType ? T
|
|
51
|
+
|
|
52
|
+
: never;
|
|
53
|
+
|
|
54
|
+
export type InferSchemaInstanceType<T extends Definition> = {
|
|
55
|
+
[K in keyof T]: InferValueType<T[K]>
|
|
56
|
+
} & Schema;
|
|
57
|
+
|
|
58
|
+
export type DefinedSchemaType<T extends Definition, P extends typeof Schema> = {
|
|
59
|
+
new (): InferSchemaInstanceType<T> & InstanceType<P>;
|
|
60
|
+
} & typeof Schema;
|
|
61
|
+
|
|
10
62
|
export type NonFunctionProps<T> = Omit<T, {
|
|
11
63
|
[K in keyof T]: T[K] extends Function ? K : never;
|
|
12
64
|
}[keyof T]>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Metadata } from "../Metadata";
|
|
2
|
+
import { Schema } from "../Schema";
|
|
3
|
+
import { $viewFieldIndexes } from "./symbols";
|
|
4
|
+
|
|
5
|
+
export class TypeContext {
|
|
6
|
+
types: { [id: number]: typeof Schema; } = {};
|
|
7
|
+
schemas = new Map<typeof Schema, number>();
|
|
8
|
+
|
|
9
|
+
hasFilters: boolean = false;
|
|
10
|
+
parentFiltered: {[typeIdAndParentIndex: string]: boolean} = {};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* For inheritance support
|
|
14
|
+
* Keeps track of which classes extends which. (parent -> children)
|
|
15
|
+
*/
|
|
16
|
+
static inheritedTypes = new Map<typeof Schema, Set<typeof Schema>>();
|
|
17
|
+
|
|
18
|
+
static register(target: typeof Schema) {
|
|
19
|
+
const parent = Object.getPrototypeOf(target);
|
|
20
|
+
if (parent !== Schema) {
|
|
21
|
+
let inherits = TypeContext.inheritedTypes.get(parent);
|
|
22
|
+
if (!inherits) {
|
|
23
|
+
inherits = new Set<typeof Schema>();
|
|
24
|
+
TypeContext.inheritedTypes.set(parent, inherits);
|
|
25
|
+
}
|
|
26
|
+
inherits.add(target);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constructor(rootClass?: typeof Schema) {
|
|
31
|
+
if (rootClass) {
|
|
32
|
+
this.discoverTypes(rootClass);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
has(schema: typeof Schema) {
|
|
37
|
+
return this.schemas.has(schema);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get(typeid: number) {
|
|
41
|
+
return this.types[typeid];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
add(schema: typeof Schema, typeid: number = this.schemas.size) {
|
|
45
|
+
// skip if already registered
|
|
46
|
+
if (this.schemas.has(schema)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.types[typeid] = schema;
|
|
51
|
+
|
|
52
|
+
//
|
|
53
|
+
// Workaround to allow using an empty Schema (with no `@type()` fields)
|
|
54
|
+
//
|
|
55
|
+
if (schema[Symbol.metadata] === undefined) {
|
|
56
|
+
Metadata.initialize(schema);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.schemas.set(schema, typeid);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getTypeId(klass: typeof Schema) {
|
|
64
|
+
return this.schemas.get(klass);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private discoverTypes(klass: typeof Schema, parentIndex?: number, parentFieldViewTag?: number) {
|
|
68
|
+
if (!this.add(klass)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// add classes inherited from this base class
|
|
73
|
+
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
74
|
+
this.discoverTypes(child, parentIndex, parentFieldViewTag);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// add parent classes
|
|
78
|
+
let parent: any = klass;
|
|
79
|
+
while (
|
|
80
|
+
(parent = Object.getPrototypeOf(parent)) &&
|
|
81
|
+
parent !== Schema && // stop at root (Schema)
|
|
82
|
+
parent !== Function.prototype // stop at root (non-Schema)
|
|
83
|
+
) {
|
|
84
|
+
this.discoverTypes(parent);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const metadata: Metadata = (klass[Symbol.metadata] ??= {});
|
|
88
|
+
|
|
89
|
+
// if any schema/field has filters, mark "context" as having filters.
|
|
90
|
+
if (metadata[$viewFieldIndexes]) {
|
|
91
|
+
this.hasFilters = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (parentFieldViewTag !== undefined) {
|
|
95
|
+
this.parentFiltered[`${this.schemas.get(klass)}-${parentIndex}`] = true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const fieldIndex in metadata) {
|
|
99
|
+
const index = fieldIndex as any as number;
|
|
100
|
+
|
|
101
|
+
const fieldType = metadata[index].type;
|
|
102
|
+
const viewTag = metadata[index].tag;
|
|
103
|
+
|
|
104
|
+
if (typeof (fieldType) === "string") {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (Array.isArray(fieldType)) {
|
|
109
|
+
const type = fieldType[0];
|
|
110
|
+
|
|
111
|
+
// skip primitive types
|
|
112
|
+
if (type === "string") {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.discoverTypes(type as typeof Schema, index, viewTag);
|
|
117
|
+
|
|
118
|
+
} else if (typeof (fieldType) === "function") {
|
|
119
|
+
this.discoverTypes(fieldType as typeof Schema, viewTag);
|
|
120
|
+
|
|
121
|
+
} else {
|
|
122
|
+
const type = Object.values(fieldType)[0];
|
|
123
|
+
|
|
124
|
+
// skip primitive types
|
|
125
|
+
if (typeof (type) === "string") {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.discoverTypes(type as typeof Schema, index, viewTag);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|