@colyseus/schema 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/build/cjs/index.js +48 -48
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +130 -104
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +50 -50
- package/lib/Reflection.js +87 -119
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.js +195 -257
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +6 -6
- package/lib/annotations.js +64 -92
- package/lib/annotations.js.map +1 -1
- package/lib/changes/ChangeTree.d.ts +1 -1
- package/lib/changes/ChangeTree.js +63 -70
- package/lib/changes/ChangeTree.js.map +1 -1
- package/lib/changes/ReferenceTracker.js +24 -27
- package/lib/changes/ReferenceTracker.js.map +1 -1
- package/lib/codegen/api.js +9 -9
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/argv.d.ts +1 -1
- package/lib/codegen/argv.js +11 -11
- package/lib/codegen/argv.js.map +1 -1
- package/lib/codegen/cli.js +21 -10
- package/lib/codegen/cli.js.map +1 -1
- package/lib/codegen/languages/cpp.js +126 -77
- package/lib/codegen/languages/cpp.js.map +1 -1
- package/lib/codegen/languages/csharp.js +121 -62
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +34 -26
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/java.js +39 -27
- package/lib/codegen/languages/java.js.map +1 -1
- package/lib/codegen/languages/js.js +48 -32
- package/lib/codegen/languages/js.js.map +1 -1
- package/lib/codegen/languages/lua.js +35 -24
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/codegen/languages/ts.js +63 -68
- package/lib/codegen/languages/ts.js.map +1 -1
- package/lib/codegen/parser.d.ts +9 -1
- package/lib/codegen/parser.js +88 -46
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.d.ts +8 -0
- package/lib/codegen/types.js +64 -54
- package/lib/codegen/types.js.map +1 -1
- package/lib/encoding/decode.js +15 -15
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.js +14 -14
- package/lib/encoding/encode.js.map +1 -1
- package/lib/events/EventEmitter.d.ts +1 -1
- package/lib/events/EventEmitter.js +16 -47
- package/lib/events/EventEmitter.js.map +1 -1
- package/lib/filters/index.js +7 -8
- package/lib/filters/index.js.map +1 -1
- package/lib/index.js +11 -11
- package/lib/index.js.map +1 -1
- package/lib/types/ArraySchema.d.ts +1 -1
- package/lib/types/ArraySchema.js +161 -219
- package/lib/types/ArraySchema.js.map +1 -1
- package/lib/types/CollectionSchema.d.ts +1 -1
- package/lib/types/CollectionSchema.js +63 -71
- package/lib/types/CollectionSchema.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +9 -9
- package/lib/types/MapSchema.d.ts +16 -16
- package/lib/types/MapSchema.js +68 -78
- package/lib/types/MapSchema.js.map +1 -1
- package/lib/types/SetSchema.js +62 -71
- package/lib/types/SetSchema.js.map +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/index.js.map +1 -1
- package/lib/types/typeRegistry.js +1 -1
- package/lib/types/typeRegistry.js.map +1 -1
- package/lib/types/utils.js +9 -10
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +10 -13
- package/lib/utils.js.map +1 -1
- package/package.json +18 -15
- package/src/Reflection.ts +159 -0
- package/src/Schema.ts +1024 -0
- package/src/annotations.ts +400 -0
- package/src/changes/ChangeTree.ts +295 -0
- package/src/changes/ReferenceTracker.ts +81 -0
- package/src/codegen/api.ts +46 -0
- package/src/codegen/argv.ts +40 -0
- package/src/codegen/cli.ts +65 -0
- package/src/codegen/languages/cpp.ts +297 -0
- package/src/codegen/languages/csharp.ts +208 -0
- package/src/codegen/languages/haxe.ts +110 -0
- package/src/codegen/languages/java.ts +115 -0
- package/src/codegen/languages/js.ts +115 -0
- package/src/codegen/languages/lua.ts +125 -0
- package/src/codegen/languages/ts.ts +129 -0
- package/src/codegen/parser.ts +299 -0
- package/src/codegen/types.ts +177 -0
- package/src/encoding/decode.ts +278 -0
- package/src/encoding/encode.ts +283 -0
- package/src/filters/index.ts +23 -0
- package/src/index.ts +59 -0
- package/src/spec.ts +49 -0
- package/src/types/ArraySchema.ts +612 -0
- package/src/types/CollectionSchema.ts +199 -0
- package/src/types/HelperTypes.ts +34 -0
- package/src/types/MapSchema.ts +268 -0
- package/src/types/SetSchema.ts +208 -0
- package/src/types/typeRegistry.ts +19 -0
- package/src/types/utils.ts +62 -0
- package/src/utils.ts +28 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2018 Endel Dreyer
|
|
3
|
+
* Copyright (c) 2014 Ion Drive Software Ltd.
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { SWITCH_TO_STRUCTURE } from "../spec";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* msgpack implementation highly based on notepack.io
|
|
28
|
+
* https://github.com/darrachequesne/notepack
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export interface Iterator { offset: number; }
|
|
32
|
+
|
|
33
|
+
function utf8Read(bytes, offset, length) {
|
|
34
|
+
var string = '', chr = 0;
|
|
35
|
+
for (var i = offset, end = offset + length; i < end; i++) {
|
|
36
|
+
var byte = bytes[i];
|
|
37
|
+
if ((byte & 0x80) === 0x00) {
|
|
38
|
+
string += String.fromCharCode(byte);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if ((byte & 0xe0) === 0xc0) {
|
|
42
|
+
string += String.fromCharCode(
|
|
43
|
+
((byte & 0x1f) << 6) |
|
|
44
|
+
(bytes[++i] & 0x3f)
|
|
45
|
+
);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if ((byte & 0xf0) === 0xe0) {
|
|
49
|
+
string += String.fromCharCode(
|
|
50
|
+
((byte & 0x0f) << 12) |
|
|
51
|
+
((bytes[++i] & 0x3f) << 6) |
|
|
52
|
+
((bytes[++i] & 0x3f) << 0)
|
|
53
|
+
);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if ((byte & 0xf8) === 0xf0) {
|
|
57
|
+
chr = ((byte & 0x07) << 18) |
|
|
58
|
+
((bytes[++i] & 0x3f) << 12) |
|
|
59
|
+
((bytes[++i] & 0x3f) << 6) |
|
|
60
|
+
((bytes[++i] & 0x3f) << 0);
|
|
61
|
+
if (chr >= 0x010000) { // surrogate pair
|
|
62
|
+
chr -= 0x010000;
|
|
63
|
+
string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00);
|
|
64
|
+
} else {
|
|
65
|
+
string += String.fromCharCode(chr);
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.error('Invalid byte ' + byte.toString(16));
|
|
71
|
+
// (do not throw error to avoid server/client from crashing due to hack attemps)
|
|
72
|
+
// throw new Error('Invalid byte ' + byte.toString(16));
|
|
73
|
+
}
|
|
74
|
+
return string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function int8 (bytes: number[], it: Iterator) {
|
|
78
|
+
return uint8(bytes, it) << 24 >> 24;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export function uint8 (bytes: number[], it: Iterator) {
|
|
82
|
+
return bytes[it.offset++];
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export function int16 (bytes: number[], it: Iterator) {
|
|
86
|
+
return uint16(bytes, it) << 16 >> 16;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export function uint16 (bytes: number[], it: Iterator) {
|
|
90
|
+
return bytes[it.offset++] | bytes[it.offset++] << 8;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export function int32 (bytes: number[], it: Iterator) {
|
|
94
|
+
return bytes[it.offset++] | bytes[it.offset++] << 8 | bytes[it.offset++] << 16 | bytes[it.offset++] << 24;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export function uint32 (bytes: number[], it: Iterator) {
|
|
98
|
+
return int32(bytes, it) >>> 0;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export function float32(bytes: number[], it: Iterator) {
|
|
102
|
+
return readFloat32(bytes, it);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function float64(bytes: number[], it: Iterator) {
|
|
106
|
+
return readFloat64(bytes, it);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function int64(bytes: number[], it: Iterator) {
|
|
110
|
+
const low = uint32(bytes, it);
|
|
111
|
+
const high = int32(bytes, it) * Math.pow(2, 32);
|
|
112
|
+
return high + low;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export function uint64(bytes: number[], it: Iterator) {
|
|
116
|
+
const low = uint32(bytes, it);
|
|
117
|
+
const high = uint32(bytes, it) * Math.pow(2, 32);
|
|
118
|
+
return high + low;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// force little endian to facilitate decoding on multiple implementations
|
|
122
|
+
const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
123
|
+
const _int32 = new Int32Array(2);
|
|
124
|
+
const _float32 = new Float32Array(_int32.buffer);
|
|
125
|
+
const _float64 = new Float64Array(_int32.buffer);
|
|
126
|
+
|
|
127
|
+
export function readFloat32 (bytes: number[], it: Iterator) {
|
|
128
|
+
_int32[0] = int32(bytes, it);
|
|
129
|
+
return _float32[0];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export function readFloat64 (bytes: number[], it: Iterator) {
|
|
133
|
+
_int32[_isLittleEndian ? 0 : 1] = int32(bytes, it);
|
|
134
|
+
_int32[_isLittleEndian ? 1 : 0] = int32(bytes, it);
|
|
135
|
+
return _float64[0];
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export function boolean (bytes: number[], it: Iterator) {
|
|
139
|
+
return uint8(bytes, it) > 0;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export function string (bytes, it: Iterator) {
|
|
143
|
+
const prefix = bytes[it.offset++];
|
|
144
|
+
let length: number;
|
|
145
|
+
|
|
146
|
+
if (prefix < 0xc0) {
|
|
147
|
+
// fixstr
|
|
148
|
+
length = prefix & 0x1f;
|
|
149
|
+
|
|
150
|
+
} else if (prefix === 0xd9) {
|
|
151
|
+
length = uint8(bytes, it);
|
|
152
|
+
|
|
153
|
+
} else if (prefix === 0xda) {
|
|
154
|
+
length = uint16(bytes, it);
|
|
155
|
+
|
|
156
|
+
} else if (prefix === 0xdb) {
|
|
157
|
+
length = uint32(bytes, it);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const value = utf8Read(bytes, it.offset, length);
|
|
161
|
+
it.offset += length;
|
|
162
|
+
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function stringCheck(bytes, it: Iterator) {
|
|
167
|
+
const prefix = bytes[it.offset];
|
|
168
|
+
return (
|
|
169
|
+
// fixstr
|
|
170
|
+
(prefix < 0xc0 && prefix > 0xa0) ||
|
|
171
|
+
// str 8
|
|
172
|
+
prefix === 0xd9 ||
|
|
173
|
+
// str 16
|
|
174
|
+
prefix === 0xda ||
|
|
175
|
+
// str 32
|
|
176
|
+
prefix === 0xdb
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function number (bytes, it: Iterator) {
|
|
181
|
+
const prefix = bytes[it.offset++];
|
|
182
|
+
|
|
183
|
+
if (prefix < 0x80) {
|
|
184
|
+
// positive fixint
|
|
185
|
+
return prefix;
|
|
186
|
+
|
|
187
|
+
} else if (prefix === 0xca) {
|
|
188
|
+
// float 32
|
|
189
|
+
return readFloat32(bytes, it);
|
|
190
|
+
|
|
191
|
+
} else if (prefix === 0xcb) {
|
|
192
|
+
// float 64
|
|
193
|
+
return readFloat64(bytes, it);
|
|
194
|
+
|
|
195
|
+
} else if (prefix === 0xcc) {
|
|
196
|
+
// uint 8
|
|
197
|
+
return uint8(bytes, it);
|
|
198
|
+
|
|
199
|
+
} else if (prefix === 0xcd) {
|
|
200
|
+
// uint 16
|
|
201
|
+
return uint16(bytes, it);
|
|
202
|
+
|
|
203
|
+
} else if (prefix === 0xce) {
|
|
204
|
+
// uint 32
|
|
205
|
+
return uint32(bytes, it);
|
|
206
|
+
|
|
207
|
+
} else if (prefix === 0xcf) {
|
|
208
|
+
// uint 64
|
|
209
|
+
return uint64(bytes, it);
|
|
210
|
+
|
|
211
|
+
} else if (prefix === 0xd0) {
|
|
212
|
+
// int 8
|
|
213
|
+
return int8(bytes, it);
|
|
214
|
+
|
|
215
|
+
} else if (prefix === 0xd1) {
|
|
216
|
+
// int 16
|
|
217
|
+
return int16(bytes, it);
|
|
218
|
+
|
|
219
|
+
} else if (prefix === 0xd2) {
|
|
220
|
+
// int 32
|
|
221
|
+
return int32(bytes, it);
|
|
222
|
+
|
|
223
|
+
} else if (prefix === 0xd3) {
|
|
224
|
+
// int 64
|
|
225
|
+
return int64(bytes, it);
|
|
226
|
+
|
|
227
|
+
} else if (prefix > 0xdf) {
|
|
228
|
+
// negative fixint
|
|
229
|
+
return (0xff - prefix + 1) * -1
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export function numberCheck (bytes, it: Iterator) {
|
|
234
|
+
const prefix = bytes[it.offset];
|
|
235
|
+
// positive fixint - 0x00 - 0x7f
|
|
236
|
+
// float 32 - 0xca
|
|
237
|
+
// float 64 - 0xcb
|
|
238
|
+
// uint 8 - 0xcc
|
|
239
|
+
// uint 16 - 0xcd
|
|
240
|
+
// uint 32 - 0xce
|
|
241
|
+
// uint 64 - 0xcf
|
|
242
|
+
// int 8 - 0xd0
|
|
243
|
+
// int 16 - 0xd1
|
|
244
|
+
// int 32 - 0xd2
|
|
245
|
+
// int 64 - 0xd3
|
|
246
|
+
return (
|
|
247
|
+
prefix < 0x80 ||
|
|
248
|
+
(prefix >= 0xca && prefix <= 0xd3)
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function arrayCheck (bytes, it: Iterator) {
|
|
253
|
+
return bytes[it.offset] < 0xa0;
|
|
254
|
+
|
|
255
|
+
// const prefix = bytes[it.offset] ;
|
|
256
|
+
|
|
257
|
+
// if (prefix < 0xa0) {
|
|
258
|
+
// return prefix;
|
|
259
|
+
|
|
260
|
+
// // array
|
|
261
|
+
// } else if (prefix === 0xdc) {
|
|
262
|
+
// it.offset += 2;
|
|
263
|
+
|
|
264
|
+
// } else if (0xdd) {
|
|
265
|
+
// it.offset += 4;
|
|
266
|
+
// }
|
|
267
|
+
|
|
268
|
+
// return prefix;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function switchStructureCheck(bytes, it: Iterator) {
|
|
272
|
+
return (
|
|
273
|
+
// previous byte should be `SWITCH_TO_STRUCTURE`
|
|
274
|
+
bytes[it.offset - 1] === SWITCH_TO_STRUCTURE &&
|
|
275
|
+
// next byte should be a number
|
|
276
|
+
(bytes[it.offset] < 0x80 || (bytes[it.offset] >= 0xca && bytes[it.offset] <= 0xd3))
|
|
277
|
+
);
|
|
278
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2018 Endel Dreyer
|
|
3
|
+
* Copyright (c) 2014 Ion Drive Software Ltd.
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* msgpack implementation highly based on notepack.io
|
|
26
|
+
* https://github.com/darrachequesne/notepack
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
function utf8Length(str) {
|
|
31
|
+
var c = 0, length = 0;
|
|
32
|
+
for (var i = 0, l = str.length; i < l; i++) {
|
|
33
|
+
c = str.charCodeAt(i);
|
|
34
|
+
if (c < 0x80) {
|
|
35
|
+
length += 1;
|
|
36
|
+
}
|
|
37
|
+
else if (c < 0x800) {
|
|
38
|
+
length += 2;
|
|
39
|
+
}
|
|
40
|
+
else if (c < 0xd800 || c >= 0xe000) {
|
|
41
|
+
length += 3;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
i++;
|
|
45
|
+
length += 4;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return length;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function utf8Write(view, offset, str) {
|
|
52
|
+
var c = 0;
|
|
53
|
+
for (var i = 0, l = str.length; i < l; i++) {
|
|
54
|
+
c = str.charCodeAt(i);
|
|
55
|
+
if (c < 0x80) {
|
|
56
|
+
view[offset++] = c;
|
|
57
|
+
}
|
|
58
|
+
else if (c < 0x800) {
|
|
59
|
+
view[offset++] = 0xc0 | (c >> 6);
|
|
60
|
+
view[offset++] = 0x80 | (c & 0x3f);
|
|
61
|
+
}
|
|
62
|
+
else if (c < 0xd800 || c >= 0xe000) {
|
|
63
|
+
view[offset++] = 0xe0 | (c >> 12);
|
|
64
|
+
view[offset++] = 0x80 | (c >> 6 & 0x3f);
|
|
65
|
+
view[offset++] = 0x80 | (c & 0x3f);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
i++;
|
|
69
|
+
c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
|
|
70
|
+
view[offset++] = 0xf0 | (c >> 18);
|
|
71
|
+
view[offset++] = 0x80 | (c >> 12 & 0x3f);
|
|
72
|
+
view[offset++] = 0x80 | (c >> 6 & 0x3f);
|
|
73
|
+
view[offset++] = 0x80 | (c & 0x3f);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function int8(bytes, value) {
|
|
79
|
+
bytes.push(value & 255);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export function uint8(bytes, value) {
|
|
83
|
+
bytes.push(value & 255);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export function int16(bytes, value) {
|
|
87
|
+
bytes.push(value & 255);
|
|
88
|
+
bytes.push((value >> 8) & 255);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export function uint16(bytes, value) {
|
|
92
|
+
bytes.push(value & 255);
|
|
93
|
+
bytes.push((value >> 8) & 255);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export function int32(bytes, value) {
|
|
97
|
+
bytes.push(value & 255);
|
|
98
|
+
bytes.push((value >> 8) & 255);
|
|
99
|
+
bytes.push((value >> 16) & 255);
|
|
100
|
+
bytes.push((value >> 24) & 255);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export function uint32(bytes, value) {
|
|
104
|
+
const b4 = value >> 24;
|
|
105
|
+
const b3 = value >> 16;
|
|
106
|
+
const b2 = value >> 8;
|
|
107
|
+
const b1 = value;
|
|
108
|
+
bytes.push(b1 & 255);
|
|
109
|
+
bytes.push(b2 & 255);
|
|
110
|
+
bytes.push(b3 & 255);
|
|
111
|
+
bytes.push(b4 & 255);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export function int64(bytes, value) {
|
|
115
|
+
const high = Math.floor(value / Math.pow(2, 32));
|
|
116
|
+
const low = value >>> 0;
|
|
117
|
+
uint32(bytes, low);
|
|
118
|
+
uint32(bytes, high);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export function uint64(bytes, value) {
|
|
122
|
+
const high = (value / Math.pow(2, 32)) >> 0;
|
|
123
|
+
const low = value >>> 0;
|
|
124
|
+
uint32(bytes, low);
|
|
125
|
+
uint32(bytes, high);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export function float32(bytes, value) {
|
|
129
|
+
writeFloat32(bytes, value);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function float64(bytes, value) {
|
|
133
|
+
writeFloat64(bytes, value);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// force little endian to facilitate decoding on multiple implementations
|
|
137
|
+
const _isLittleEndian = true; // new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
138
|
+
const _int32 = new Int32Array(2);
|
|
139
|
+
const _float32 = new Float32Array(_int32.buffer);
|
|
140
|
+
const _float64 = new Float64Array(_int32.buffer);
|
|
141
|
+
|
|
142
|
+
export function writeFloat32(bytes, value) {
|
|
143
|
+
_float32[0] = value;
|
|
144
|
+
int32(bytes, _int32[0]);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export function writeFloat64(bytes, value) {
|
|
148
|
+
_float64[0] = value;
|
|
149
|
+
int32(bytes, _int32[_isLittleEndian ? 0 : 1]);
|
|
150
|
+
int32(bytes, _int32[_isLittleEndian ? 1 : 0]);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export function boolean(bytes, value) {
|
|
154
|
+
return uint8(bytes, value ? 1 : 0);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export function string(bytes, value) {
|
|
158
|
+
// encode `null` strings as empty.
|
|
159
|
+
if (!value) { value = ""; }
|
|
160
|
+
|
|
161
|
+
let length = utf8Length(value);
|
|
162
|
+
let size = 0;
|
|
163
|
+
|
|
164
|
+
// fixstr
|
|
165
|
+
if (length < 0x20) {
|
|
166
|
+
bytes.push(length | 0xa0);
|
|
167
|
+
size = 1;
|
|
168
|
+
}
|
|
169
|
+
// str 8
|
|
170
|
+
else if (length < 0x100) {
|
|
171
|
+
bytes.push(0xd9);
|
|
172
|
+
uint8(bytes, length);
|
|
173
|
+
size = 2;
|
|
174
|
+
}
|
|
175
|
+
// str 16
|
|
176
|
+
else if (length < 0x10000) {
|
|
177
|
+
bytes.push(0xda);
|
|
178
|
+
uint16(bytes, length);
|
|
179
|
+
size = 3;
|
|
180
|
+
}
|
|
181
|
+
// str 32
|
|
182
|
+
else if (length < 0x100000000) {
|
|
183
|
+
bytes.push(0xdb);
|
|
184
|
+
uint32(bytes, length);
|
|
185
|
+
size = 5;
|
|
186
|
+
} else {
|
|
187
|
+
throw new Error('String too long');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
utf8Write(bytes, bytes.length, value);
|
|
191
|
+
|
|
192
|
+
return size + length;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function number(bytes, value) {
|
|
196
|
+
if (isNaN(value)) {
|
|
197
|
+
return number(bytes, 0);
|
|
198
|
+
|
|
199
|
+
} else if (!isFinite(value)) {
|
|
200
|
+
return number(bytes, (value > 0) ? Number.MAX_SAFE_INTEGER : -Number.MAX_SAFE_INTEGER);
|
|
201
|
+
|
|
202
|
+
} else if (value !== (value|0)) {
|
|
203
|
+
bytes.push(0xcb);
|
|
204
|
+
writeFloat64(bytes, value);
|
|
205
|
+
return 9;
|
|
206
|
+
|
|
207
|
+
// TODO: encode float 32?
|
|
208
|
+
// is it possible to differentiate between float32 / float64 here?
|
|
209
|
+
|
|
210
|
+
// // float 32
|
|
211
|
+
// bytes.push(0xca);
|
|
212
|
+
// writeFloat32(bytes, value);
|
|
213
|
+
// return 5;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (value >= 0) {
|
|
217
|
+
// positive fixnum
|
|
218
|
+
if (value < 0x80) {
|
|
219
|
+
uint8(bytes, value);
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// uint 8
|
|
224
|
+
if (value < 0x100) {
|
|
225
|
+
bytes.push(0xcc);
|
|
226
|
+
uint8(bytes, value);
|
|
227
|
+
return 2;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// uint 16
|
|
231
|
+
if (value < 0x10000) {
|
|
232
|
+
bytes.push(0xcd);
|
|
233
|
+
uint16(bytes, value);
|
|
234
|
+
return 3;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// uint 32
|
|
238
|
+
if (value < 0x100000000) {
|
|
239
|
+
bytes.push(0xce);
|
|
240
|
+
uint32(bytes, value);
|
|
241
|
+
return 5;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// uint 64
|
|
245
|
+
bytes.push(0xcf);
|
|
246
|
+
uint64(bytes, value);
|
|
247
|
+
return 9;
|
|
248
|
+
|
|
249
|
+
} else {
|
|
250
|
+
|
|
251
|
+
// negative fixnum
|
|
252
|
+
if (value >= -0x20) {
|
|
253
|
+
bytes.push(0xe0 | (value + 0x20));
|
|
254
|
+
return 1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// int 8
|
|
258
|
+
if (value >= -0x80) {
|
|
259
|
+
bytes.push(0xd0);
|
|
260
|
+
int8(bytes, value);
|
|
261
|
+
return 2;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// int 16
|
|
265
|
+
if (value >= -0x8000) {
|
|
266
|
+
bytes.push(0xd1);
|
|
267
|
+
int16(bytes, value);
|
|
268
|
+
return 3;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// int 32
|
|
272
|
+
if (value >= -0x80000000) {
|
|
273
|
+
bytes.push(0xd2);
|
|
274
|
+
int32(bytes, value);
|
|
275
|
+
return 5;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// int 64
|
|
279
|
+
bytes.push(0xd3);
|
|
280
|
+
int64(bytes, value);
|
|
281
|
+
return 9;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ChangeTree } from "../changes/ChangeTree";
|
|
2
|
+
import { ClientWithSessionId } from "../annotations";
|
|
3
|
+
|
|
4
|
+
export class ClientState {
|
|
5
|
+
refIds = new WeakSet<ChangeTree>();
|
|
6
|
+
containerIndexes = new WeakMap<ChangeTree, Set<number>>();
|
|
7
|
+
// containerIndexes = new Map<ChangeTree, Set<number>>();
|
|
8
|
+
|
|
9
|
+
addRefId(changeTree: ChangeTree) {
|
|
10
|
+
if (!this.refIds.has(changeTree)) {
|
|
11
|
+
this.refIds.add(changeTree);
|
|
12
|
+
this.containerIndexes.set(changeTree, new Set());
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static get(client: ClientWithSessionId) {
|
|
17
|
+
if (client.$filterState === undefined) {
|
|
18
|
+
client.$filterState = new ClientState();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return client.$filterState as ClientState;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export { Schema, DataChange } from "./Schema";
|
|
2
|
+
|
|
3
|
+
import { MapSchema } from "./types/MapSchema"
|
|
4
|
+
export { MapSchema };
|
|
5
|
+
|
|
6
|
+
import { ArraySchema } from "./types/ArraySchema";
|
|
7
|
+
export { ArraySchema };
|
|
8
|
+
|
|
9
|
+
import { CollectionSchema } from "./types/CollectionSchema";
|
|
10
|
+
export { CollectionSchema };
|
|
11
|
+
|
|
12
|
+
import { SetSchema } from "./types/SetSchema";
|
|
13
|
+
export { SetSchema };
|
|
14
|
+
|
|
15
|
+
import { registerType } from "./types/typeRegistry";
|
|
16
|
+
export { registerType };
|
|
17
|
+
|
|
18
|
+
registerType("map", { constructor: MapSchema });
|
|
19
|
+
registerType("array", { constructor: ArraySchema });
|
|
20
|
+
registerType("set", { constructor: SetSchema });
|
|
21
|
+
registerType("collection", { constructor: CollectionSchema, });
|
|
22
|
+
|
|
23
|
+
// Utils
|
|
24
|
+
export { dumpChanges } from "./utils";
|
|
25
|
+
|
|
26
|
+
// Encoder / Decoder
|
|
27
|
+
export { Iterator } from "./encoding/decode";
|
|
28
|
+
import * as encode from "./encoding/encode";
|
|
29
|
+
import * as decode from "./encoding/decode";
|
|
30
|
+
export { encode, decode };
|
|
31
|
+
|
|
32
|
+
// Reflection
|
|
33
|
+
export {
|
|
34
|
+
Reflection,
|
|
35
|
+
ReflectionType,
|
|
36
|
+
ReflectionField,
|
|
37
|
+
} from "./Reflection";
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
// Annotations
|
|
41
|
+
type,
|
|
42
|
+
deprecated,
|
|
43
|
+
filter,
|
|
44
|
+
filterChildren,
|
|
45
|
+
defineTypes,
|
|
46
|
+
hasFilter,
|
|
47
|
+
|
|
48
|
+
// Internals
|
|
49
|
+
SchemaDefinition,
|
|
50
|
+
|
|
51
|
+
// Types
|
|
52
|
+
Context,
|
|
53
|
+
PrimitiveType,
|
|
54
|
+
Definition,
|
|
55
|
+
DefinitionType,
|
|
56
|
+
FilterCallback,
|
|
57
|
+
} from "./annotations";
|
|
58
|
+
|
|
59
|
+
export { OPERATION } from "./spec";
|
package/src/spec.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// export const SWITCH_TO_STRUCTURE = 193; (easily collides with DELETE_AND_ADD + fieldIndex = 2)
|
|
2
|
+
export const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
|
|
3
|
+
export const TYPE_ID = 213;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Encoding Schema field operations.
|
|
7
|
+
*/
|
|
8
|
+
export enum OPERATION {
|
|
9
|
+
// add new structure/primitive
|
|
10
|
+
ADD = 128,
|
|
11
|
+
|
|
12
|
+
// replace structure/primitive
|
|
13
|
+
REPLACE = 0,
|
|
14
|
+
|
|
15
|
+
// delete field
|
|
16
|
+
DELETE = 64,
|
|
17
|
+
|
|
18
|
+
// DELETE field, followed by an ADD
|
|
19
|
+
DELETE_AND_ADD = 192, // 11100000
|
|
20
|
+
|
|
21
|
+
// TOUCH is used to determine hierarchy of nested Schema structures during serialization.
|
|
22
|
+
// touches are NOT encoded.
|
|
23
|
+
TOUCH = 1, // 00000000
|
|
24
|
+
|
|
25
|
+
// MapSchema Operations
|
|
26
|
+
CLEAR = 10,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// export enum OPERATION {
|
|
30
|
+
// // add new structure/primitive
|
|
31
|
+
// // (128)
|
|
32
|
+
// ADD = 128, // 10000000,
|
|
33
|
+
|
|
34
|
+
// // replace structure/primitive
|
|
35
|
+
// REPLACE = 1,// 00000001
|
|
36
|
+
|
|
37
|
+
// // delete field
|
|
38
|
+
// DELETE = 192, // 11000000
|
|
39
|
+
|
|
40
|
+
// // DELETE field, followed by an ADD
|
|
41
|
+
// DELETE_AND_ADD = 224, // 11100000
|
|
42
|
+
|
|
43
|
+
// // TOUCH is used to determine hierarchy of nested Schema structures during serialization.
|
|
44
|
+
// // touches are NOT encoded.
|
|
45
|
+
// TOUCH = 0, // 00000000
|
|
46
|
+
|
|
47
|
+
// // MapSchema Operations
|
|
48
|
+
// CLEAR = 10,
|
|
49
|
+
// }
|