@colyseus/schema 2.0.31 → 3.0.0-alpha.0
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/build/cjs/index.js +3614 -2634
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +3324 -2445
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +3614 -2634
- package/lib/Decoder.d.ts +16 -0
- package/lib/Decoder.js +182 -0
- package/lib/Decoder.js.map +1 -0
- package/lib/Encoder.d.ts +13 -0
- package/lib/Encoder.js +79 -0
- package/lib/Encoder.js.map +1 -0
- package/lib/Metadata.d.ts +36 -0
- package/lib/Metadata.js +91 -0
- package/lib/Metadata.js.map +1 -0
- package/lib/Reflection.d.ts +7 -5
- package/lib/Reflection.js +62 -58
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +39 -51
- package/lib/Schema.js +189 -731
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +26 -45
- package/lib/annotations.js +363 -194
- package/lib/annotations.js.map +1 -1
- package/lib/changes/ChangeSet.d.ts +12 -0
- package/lib/changes/ChangeSet.js +35 -0
- package/lib/changes/ChangeSet.js.map +1 -0
- package/lib/changes/DecodeOperation.d.ts +15 -0
- package/lib/changes/DecodeOperation.js +186 -0
- package/lib/changes/DecodeOperation.js.map +1 -0
- package/lib/changes/EncodeOperation.d.ts +18 -0
- package/lib/changes/EncodeOperation.js +130 -0
- package/lib/changes/EncodeOperation.js.map +1 -0
- package/lib/changes/consts.d.ts +14 -0
- package/lib/changes/consts.js +18 -0
- package/lib/changes/consts.js.map +1 -0
- package/lib/decoder/DecodeOperation.d.ts +24 -0
- package/lib/decoder/DecodeOperation.js +256 -0
- package/lib/decoder/DecodeOperation.js.map +1 -0
- package/lib/decoder/Decoder.d.ts +21 -0
- package/lib/decoder/Decoder.js +114 -0
- package/lib/decoder/Decoder.js.map +1 -0
- package/lib/decoder/ReferenceTracker.d.ts +26 -0
- package/lib/decoder/ReferenceTracker.js +131 -0
- package/lib/decoder/ReferenceTracker.js.map +1 -0
- package/lib/decoder/strategy/RawChanges.d.ts +3 -0
- package/lib/decoder/strategy/RawChanges.js +8 -0
- package/lib/decoder/strategy/RawChanges.js.map +1 -0
- package/lib/decoder/strategy/StateCallbacks.d.ts +20 -0
- package/lib/decoder/strategy/StateCallbacks.js +240 -0
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -0
- package/lib/decoding/decode.d.ts +48 -0
- package/lib/decoding/decode.js +267 -0
- package/lib/decoding/decode.js.map +1 -0
- package/lib/ecs.d.ts +11 -0
- package/lib/ecs.js +160 -0
- package/lib/ecs.js.map +1 -0
- package/lib/encoder/ChangeTree.d.ts +72 -0
- package/lib/encoder/ChangeTree.js +384 -0
- package/lib/encoder/ChangeTree.js.map +1 -0
- package/lib/encoder/EncodeOperation.d.ts +25 -0
- package/lib/encoder/EncodeOperation.js +156 -0
- package/lib/encoder/EncodeOperation.js.map +1 -0
- package/lib/encoder/Encoder.d.ts +23 -0
- package/lib/encoder/Encoder.js +192 -0
- package/lib/encoder/Encoder.js.map +1 -0
- package/lib/encoder/StateView.d.ts +21 -0
- package/lib/encoder/StateView.js +196 -0
- package/lib/encoder/StateView.js.map +1 -0
- package/lib/encoding/assert.d.ts +9 -0
- package/lib/encoding/assert.js +47 -0
- package/lib/encoding/assert.js.map +1 -0
- package/lib/encoding/decode.js +1 -1
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.d.ts +17 -16
- package/lib/encoding/encode.js +88 -81
- package/lib/encoding/encode.js.map +1 -1
- package/lib/encoding/spec.d.ts +25 -0
- package/lib/encoding/spec.js +30 -0
- package/lib/encoding/spec.js.map +1 -0
- package/lib/index.d.ts +18 -10
- package/lib/index.js +39 -17
- package/lib/index.js.map +1 -1
- package/lib/symbol.shim.d.ts +6 -0
- package/lib/symbol.shim.js +4 -0
- package/lib/symbol.shim.js.map +1 -0
- package/lib/types/ArraySchema.js +0 -7
- package/lib/types/ArraySchema.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +10 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/custom/ArraySchema.d.ts +245 -0
- package/lib/types/custom/ArraySchema.js +659 -0
- package/lib/types/custom/ArraySchema.js.map +1 -0
- package/lib/types/custom/CollectionSchema.d.ts +42 -0
- package/lib/types/custom/CollectionSchema.js +165 -0
- package/lib/types/custom/CollectionSchema.js.map +1 -0
- package/lib/types/custom/MapSchema.d.ts +43 -0
- package/lib/types/custom/MapSchema.js +200 -0
- package/lib/types/custom/MapSchema.js.map +1 -0
- package/lib/types/custom/SetSchema.d.ts +39 -0
- package/lib/types/custom/SetSchema.js +177 -0
- package/lib/types/custom/SetSchema.js.map +1 -0
- package/lib/types/registry.d.ts +6 -0
- package/lib/types/registry.js +19 -0
- package/lib/types/registry.js.map +1 -0
- package/lib/types/symbols.d.ts +29 -0
- package/lib/types/symbols.js +33 -0
- package/lib/types/symbols.js.map +1 -0
- package/lib/types/utils.d.ts +0 -8
- package/lib/types/utils.js +1 -33
- package/lib/types/utils.js.map +1 -1
- package/lib/usage.d.ts +1 -0
- package/lib/usage.js +22 -0
- package/lib/usage.js.map +1 -0
- package/lib/utils.d.ts +13 -2
- package/lib/utils.js +36 -15
- package/lib/utils.js.map +1 -1
- package/lib/v3.d.ts +1 -0
- package/lib/v3.js +427 -0
- package/lib/v3.js.map +1 -0
- package/lib/v3_bench.d.ts +1 -0
- package/lib/v3_bench.js +130 -0
- package/lib/v3_bench.js.map +1 -0
- package/lib/v3_experiment.d.ts +1 -0
- package/lib/v3_experiment.js +407 -0
- package/lib/v3_experiment.js.map +1 -0
- package/package.json +5 -5
- package/src/Metadata.ts +135 -0
- package/src/Reflection.ts +75 -66
- package/src/Schema.ts +213 -931
- package/src/annotations.ts +430 -243
- package/src/decoder/DecodeOperation.ts +372 -0
- package/src/decoder/Decoder.ts +155 -0
- package/src/decoder/ReferenceTracker.ts +151 -0
- package/src/decoder/strategy/RawChanges.ts +9 -0
- package/src/decoder/strategy/StateCallbacks.ts +326 -0
- package/src/encoder/ChangeTree.ts +492 -0
- package/src/encoder/EncodeOperation.ts +237 -0
- package/src/encoder/Encoder.ts +246 -0
- package/src/encoder/StateView.ts +229 -0
- package/src/encoding/assert.ts +58 -0
- package/src/encoding/decode.ts +1 -1
- package/src/encoding/encode.ts +88 -82
- package/src/encoding/spec.ts +29 -0
- package/src/index.ts +22 -19
- package/src/symbol.shim.ts +12 -0
- package/src/types/HelperTypes.ts +16 -2
- package/src/types/{ArraySchema.ts → custom/ArraySchema.ts} +345 -251
- package/src/types/{CollectionSchema.ts → custom/CollectionSchema.ts} +56 -46
- package/src/types/{MapSchema.ts → custom/MapSchema.ts} +88 -115
- package/src/types/{SetSchema.ts → custom/SetSchema.ts} +58 -47
- package/src/types/{typeRegistry.ts → registry.ts} +6 -6
- package/src/types/symbols.ts +36 -0
- package/src/types/utils.ts +0 -46
- package/src/utils.ts +50 -21
- package/src/v3_bench.ts +107 -0
- package/src/changes/ChangeTree.ts +0 -295
- package/src/changes/ReferenceTracker.ts +0 -91
- package/src/filters/index.ts +0 -23
- package/src/spec.ts +0 -49
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { ChangeTree, Ref } from "./ChangeTree";
|
|
2
|
+
import { $changes } from "../types/symbols";
|
|
3
|
+
import { DEFAULT_VIEW_TAG } from "../annotations";
|
|
4
|
+
import { OPERATION } from "../encoding/spec";
|
|
5
|
+
import { Metadata } from "../Metadata";
|
|
6
|
+
|
|
7
|
+
export class StateView {
|
|
8
|
+
/**
|
|
9
|
+
* List of ChangeTree's that are visible to this view
|
|
10
|
+
*/
|
|
11
|
+
items: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* List of ChangeTree's that are invisible to this view
|
|
15
|
+
*/
|
|
16
|
+
invisible: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();
|
|
17
|
+
|
|
18
|
+
tags?: WeakMap<ChangeTree, Set<number>>; // TODO: use bit manipulation instead of Set<number> ()
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Manual "ADD" operations for changes per ChangeTree, specific to this view.
|
|
22
|
+
* (This is used to force encoding a property, even if it was not changed)
|
|
23
|
+
*/
|
|
24
|
+
changes = new Map<ChangeTree, Map<number, OPERATION>>();
|
|
25
|
+
|
|
26
|
+
// TODO: allow to set multiple tags at once
|
|
27
|
+
add(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {
|
|
28
|
+
if (!obj[$changes]) {
|
|
29
|
+
console.warn("StateView#add(), invalid object:", obj);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let changeTree: ChangeTree = obj[$changes];
|
|
34
|
+
this.items.add(changeTree);
|
|
35
|
+
|
|
36
|
+
// Add children of this ChangeTree to this view
|
|
37
|
+
changeTree.forEachChild((change, _) =>
|
|
38
|
+
this.add(change.ref, tag));
|
|
39
|
+
|
|
40
|
+
// FIXME: ArraySchema/MapSchema does not have metadata
|
|
41
|
+
const metadata: Metadata = obj.constructor[Symbol.metadata];
|
|
42
|
+
|
|
43
|
+
// add parent ChangeTree's, if they are invisible to this view
|
|
44
|
+
// TODO: REFACTOR addParent()
|
|
45
|
+
this.addParent(changeTree, tag);
|
|
46
|
+
|
|
47
|
+
//
|
|
48
|
+
// TODO: when adding an item of a MapSchema, the changes may not
|
|
49
|
+
// be set (only the parent's changes are set)
|
|
50
|
+
//
|
|
51
|
+
let changes = this.changes.get(changeTree);
|
|
52
|
+
if (changes === undefined) {
|
|
53
|
+
changes = new Map<number, OPERATION>();
|
|
54
|
+
this.changes.set(changeTree, changes)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// set tag
|
|
58
|
+
if (tag !== DEFAULT_VIEW_TAG) {
|
|
59
|
+
if (!this.tags) {
|
|
60
|
+
this.tags = new WeakMap<ChangeTree, Set<number>>();
|
|
61
|
+
}
|
|
62
|
+
let tags: Set<number>;
|
|
63
|
+
if (!this.tags.has(changeTree)) {
|
|
64
|
+
tags = new Set<number>();
|
|
65
|
+
this.tags.set(changeTree, tags);
|
|
66
|
+
} else {
|
|
67
|
+
tags = this.tags.get(changeTree);
|
|
68
|
+
}
|
|
69
|
+
tags.add(tag);
|
|
70
|
+
|
|
71
|
+
// console.log("BY TAG:", tag);
|
|
72
|
+
|
|
73
|
+
// Ref: add tagged properties
|
|
74
|
+
metadata?.[-3]?.[tag]?.forEach((index) => {
|
|
75
|
+
if (changeTree.getChange(index) !== OPERATION.DELETE) {
|
|
76
|
+
changes.set(index, OPERATION.ADD)
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
} else {
|
|
81
|
+
|
|
82
|
+
// console.log("DEFAULT TAG", changeTree.allChanges);
|
|
83
|
+
|
|
84
|
+
// // add default tag properties
|
|
85
|
+
// metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {
|
|
86
|
+
// if (changeTree.getChange(index) !== OPERATION.DELETE) {
|
|
87
|
+
// changes.set(index, OPERATION.ADD);
|
|
88
|
+
// }
|
|
89
|
+
// });
|
|
90
|
+
|
|
91
|
+
const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
92
|
+
? changeTree.allFilteredChanges
|
|
93
|
+
: changeTree.allChanges;
|
|
94
|
+
const it = allChangesSet.keys();
|
|
95
|
+
const isInvisible = this.invisible.has(changeTree);
|
|
96
|
+
|
|
97
|
+
for (const index of it) {
|
|
98
|
+
if (
|
|
99
|
+
(isInvisible || metadata?.[metadata?.[index]].tag === tag) &&
|
|
100
|
+
changeTree.getChange(index) !== OPERATION.DELETE
|
|
101
|
+
) {
|
|
102
|
+
changes.set(index, OPERATION.ADD);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// TODO: avoid unnecessary iteration here
|
|
108
|
+
while (
|
|
109
|
+
changeTree.parent &&
|
|
110
|
+
(changeTree = changeTree.parent[$changes]) &&
|
|
111
|
+
(changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
112
|
+
) {
|
|
113
|
+
this.items.add(changeTree);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
protected addParent(changeTree: ChangeTree, tag: number) {
|
|
120
|
+
const parentRef = changeTree.parent;
|
|
121
|
+
if (!parentRef) { return; }
|
|
122
|
+
|
|
123
|
+
const parentChangeTree = parentRef[$changes];
|
|
124
|
+
const parentIndex = changeTree.parentIndex;
|
|
125
|
+
|
|
126
|
+
if (!this.invisible.has(parentChangeTree)) {
|
|
127
|
+
// parent is already available, no need to add it!
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
this.addParent(parentChangeTree, tag);
|
|
132
|
+
|
|
133
|
+
// add parent's tag properties
|
|
134
|
+
if (parentChangeTree.getChange(parentIndex) !== OPERATION.DELETE) {
|
|
135
|
+
|
|
136
|
+
let parentChanges = this.changes.get(parentChangeTree);
|
|
137
|
+
if (parentChanges === undefined) {
|
|
138
|
+
parentChanges = new Map<number, OPERATION>();
|
|
139
|
+
this.changes.set(parentChangeTree, parentChanges);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// console.log("add parent change", {
|
|
143
|
+
// parentIndex,
|
|
144
|
+
// parentChanges,
|
|
145
|
+
// parentChange: (
|
|
146
|
+
// parentChangeTree.getChange(parentIndex) &&
|
|
147
|
+
// OPERATION[parentChangeTree.getChange(parentIndex)]
|
|
148
|
+
// ),
|
|
149
|
+
// })
|
|
150
|
+
|
|
151
|
+
if (!this.tags) { this.tags = new WeakMap<ChangeTree, Set<number>>(); }
|
|
152
|
+
let tags: Set<number>;
|
|
153
|
+
if (!this.tags.has(parentChangeTree)) {
|
|
154
|
+
tags = new Set<number>();
|
|
155
|
+
this.tags.set(parentChangeTree, tags);
|
|
156
|
+
} else {
|
|
157
|
+
tags = this.tags.get(parentChangeTree);
|
|
158
|
+
}
|
|
159
|
+
tags.add(tag);
|
|
160
|
+
|
|
161
|
+
parentChanges.set(parentIndex, OPERATION.ADD);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
remove(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {
|
|
167
|
+
const changeTree = obj[$changes];
|
|
168
|
+
if (!changeTree) {
|
|
169
|
+
console.warn("StateView#remove(), invalid object:", obj);
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.items.delete(changeTree);
|
|
174
|
+
|
|
175
|
+
const ref = changeTree.ref;
|
|
176
|
+
const metadata: Metadata = ref.constructor[Symbol.metadata];
|
|
177
|
+
|
|
178
|
+
let changes = this.changes.get(changeTree);
|
|
179
|
+
if (changes === undefined) {
|
|
180
|
+
changes = new Map<number, OPERATION>();
|
|
181
|
+
this.changes.set(changeTree, changes)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (tag === DEFAULT_VIEW_TAG) {
|
|
185
|
+
// parent is collection (Map/Array)
|
|
186
|
+
const parent = changeTree.parent;
|
|
187
|
+
if (!Metadata.isValidInstance(parent)) {
|
|
188
|
+
const parentChangeTree = parent[$changes];
|
|
189
|
+
let changes = this.changes.get(parentChangeTree);
|
|
190
|
+
if (changes === undefined) {
|
|
191
|
+
changes = new Map<number, OPERATION>();
|
|
192
|
+
this.changes.set(parentChangeTree, changes)
|
|
193
|
+
}
|
|
194
|
+
// DELETE / DELETE BY REF ID
|
|
195
|
+
changes.set(changeTree.parentIndex, OPERATION.DELETE);
|
|
196
|
+
|
|
197
|
+
} else {
|
|
198
|
+
// delete all "tagged" properties.
|
|
199
|
+
metadata[-2].forEach((index) =>
|
|
200
|
+
changes.set(index, OPERATION.DELETE));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
} else {
|
|
205
|
+
// delete only tagged properties
|
|
206
|
+
metadata[-3][tag].forEach((index) =>
|
|
207
|
+
changes.set(index, OPERATION.DELETE));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// remove tag
|
|
211
|
+
if (this.tags && this.tags.has(changeTree)) {
|
|
212
|
+
const tags = this.tags.get(changeTree);
|
|
213
|
+
if (tag === undefined) {
|
|
214
|
+
// delete all tags
|
|
215
|
+
this.tags.delete(changeTree);
|
|
216
|
+
} else {
|
|
217
|
+
// delete specific tag
|
|
218
|
+
tags.delete(tag);
|
|
219
|
+
|
|
220
|
+
// if tag set is empty, delete it entirely
|
|
221
|
+
if (tags.size === 0) {
|
|
222
|
+
this.tags.delete(changeTree);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Schema } from "../Schema";
|
|
2
|
+
import { CollectionSchema } from "../types/custom/CollectionSchema";
|
|
3
|
+
import { MapSchema } from "../types/custom/MapSchema";
|
|
4
|
+
import { SetSchema } from "../types/custom/SetSchema";
|
|
5
|
+
import { ArraySchema } from "../types/custom/ArraySchema";
|
|
6
|
+
|
|
7
|
+
export class EncodeSchemaError extends Error {}
|
|
8
|
+
|
|
9
|
+
export function assertType(value: any, type: string, klass: Schema, field: string | number) {
|
|
10
|
+
let typeofTarget: string;
|
|
11
|
+
let allowNull: boolean = false;
|
|
12
|
+
|
|
13
|
+
switch (type) {
|
|
14
|
+
case "number":
|
|
15
|
+
case "int8":
|
|
16
|
+
case "uint8":
|
|
17
|
+
case "int16":
|
|
18
|
+
case "uint16":
|
|
19
|
+
case "int32":
|
|
20
|
+
case "uint32":
|
|
21
|
+
case "int64":
|
|
22
|
+
case "uint64":
|
|
23
|
+
case "float32":
|
|
24
|
+
case "float64":
|
|
25
|
+
typeofTarget = "number";
|
|
26
|
+
if (isNaN(value)) {
|
|
27
|
+
console.log(`trying to encode "NaN" in ${klass.constructor.name}#${field}`);
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
case "string":
|
|
31
|
+
typeofTarget = "string";
|
|
32
|
+
allowNull = true;
|
|
33
|
+
break;
|
|
34
|
+
case "boolean":
|
|
35
|
+
// boolean is always encoded as true/false based on truthiness
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (typeof (value) !== typeofTarget && (!allowNull || (allowNull && value !== null))) {
|
|
40
|
+
let foundValue = `'${JSON.stringify(value)}'${(value && value.constructor && ` (${value.constructor.name})`) || ''}`;
|
|
41
|
+
throw new EncodeSchemaError(`a '${typeofTarget}' was expected, but ${foundValue} was provided in ${klass.constructor.name}#${field}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function assertInstanceType(
|
|
46
|
+
value: Schema,
|
|
47
|
+
type: typeof Schema
|
|
48
|
+
| typeof ArraySchema
|
|
49
|
+
| typeof MapSchema
|
|
50
|
+
| typeof CollectionSchema
|
|
51
|
+
| typeof SetSchema,
|
|
52
|
+
klass: Schema,
|
|
53
|
+
field: string | number,
|
|
54
|
+
) {
|
|
55
|
+
if (!(value instanceof type)) {
|
|
56
|
+
throw new EncodeSchemaError(`a '${type.name}' was expected, but '${value && (value as any).constructor.name}' was provided in ${klass.constructor.name}#${field}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/encoding/decode.ts
CHANGED
package/src/encoding/encode.ts
CHANGED
|
@@ -21,11 +21,16 @@
|
|
|
21
21
|
* SOFTWARE
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import type { TextEncoder } from "util";
|
|
25
|
+
|
|
24
26
|
/**
|
|
25
27
|
* msgpack implementation highly based on notepack.io
|
|
26
28
|
* https://github.com/darrachequesne/notepack
|
|
27
29
|
*/
|
|
28
30
|
|
|
31
|
+
let textEncoder: TextEncoder;
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
try { textEncoder = new TextEncoder(); } catch (e) { }
|
|
29
34
|
|
|
30
35
|
function utf8Length(str) {
|
|
31
36
|
var c = 0, length = 0;
|
|
@@ -48,89 +53,89 @@ function utf8Length(str) {
|
|
|
48
53
|
return length;
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
export function utf8Write(view,
|
|
56
|
+
export function utf8Write(view, str, it) {
|
|
52
57
|
var c = 0;
|
|
53
58
|
for (var i = 0, l = str.length; i < l; i++) {
|
|
54
59
|
c = str.charCodeAt(i);
|
|
55
60
|
if (c < 0x80) {
|
|
56
|
-
view[offset++] = c;
|
|
61
|
+
view[it.offset++] = c;
|
|
57
62
|
}
|
|
58
63
|
else if (c < 0x800) {
|
|
59
|
-
view[offset++] = 0xc0 | (c >> 6);
|
|
60
|
-
view[offset++] = 0x80 | (c & 0x3f);
|
|
64
|
+
view[it.offset++] = 0xc0 | (c >> 6);
|
|
65
|
+
view[it.offset++] = 0x80 | (c & 0x3f);
|
|
61
66
|
}
|
|
62
67
|
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);
|
|
68
|
+
view[it.offset++] = 0xe0 | (c >> 12);
|
|
69
|
+
view[it.offset++] = 0x80 | (c >> 6 & 0x3f);
|
|
70
|
+
view[it.offset++] = 0x80 | (c & 0x3f);
|
|
66
71
|
}
|
|
67
72
|
else {
|
|
68
73
|
i++;
|
|
69
74
|
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);
|
|
75
|
+
view[it.offset++] = 0xf0 | (c >> 18);
|
|
76
|
+
view[it.offset++] = 0x80 | (c >> 12 & 0x3f);
|
|
77
|
+
view[it.offset++] = 0x80 | (c >> 6 & 0x3f);
|
|
78
|
+
view[it.offset++] = 0x80 | (c & 0x3f);
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
export function int8(bytes, value) {
|
|
79
|
-
|
|
83
|
+
export function int8(bytes, value, it) {
|
|
84
|
+
bytes[it.offset++] = value & 255;
|
|
80
85
|
};
|
|
81
86
|
|
|
82
|
-
export function uint8(bytes, value) {
|
|
83
|
-
|
|
87
|
+
export function uint8(bytes, value, it) {
|
|
88
|
+
bytes[it.offset++] = value & 255;
|
|
84
89
|
};
|
|
85
90
|
|
|
86
|
-
export function int16(bytes, value) {
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
export function int16(bytes, value, it) {
|
|
92
|
+
bytes[it.offset++] = value & 255;
|
|
93
|
+
bytes[it.offset++] = (value >> 8) & 255;
|
|
89
94
|
};
|
|
90
95
|
|
|
91
|
-
export function uint16(bytes, value) {
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
export function uint16(bytes, value, it) {
|
|
97
|
+
bytes[it.offset++] = value & 255;
|
|
98
|
+
bytes[it.offset++] = (value >> 8) & 255;
|
|
94
99
|
};
|
|
95
100
|
|
|
96
|
-
export function int32(bytes, value) {
|
|
97
|
-
bytes.
|
|
98
|
-
bytes.
|
|
99
|
-
bytes.
|
|
100
|
-
bytes.
|
|
101
|
+
export function int32(bytes, value, it) {
|
|
102
|
+
bytes[it.offset++] = value & 255;
|
|
103
|
+
bytes[it.offset++] = (value >> 8) & 255;
|
|
104
|
+
bytes[it.offset++] = (value >> 16) & 255;
|
|
105
|
+
bytes[it.offset++] = (value >> 24) & 255;
|
|
101
106
|
};
|
|
102
107
|
|
|
103
|
-
export function uint32(bytes, value) {
|
|
108
|
+
export function uint32(bytes, value, it) {
|
|
104
109
|
const b4 = value >> 24;
|
|
105
110
|
const b3 = value >> 16;
|
|
106
111
|
const b2 = value >> 8;
|
|
107
112
|
const b1 = value;
|
|
108
|
-
bytes.
|
|
109
|
-
bytes.
|
|
110
|
-
bytes.
|
|
111
|
-
bytes.
|
|
113
|
+
bytes[it.offset++] = b1 & 255;
|
|
114
|
+
bytes[it.offset++] = b2 & 255;
|
|
115
|
+
bytes[it.offset++] = b3 & 255;
|
|
116
|
+
bytes[it.offset++] = b4 & 255;
|
|
112
117
|
};
|
|
113
118
|
|
|
114
|
-
export function int64(bytes, value) {
|
|
119
|
+
export function int64(bytes, value, it) {
|
|
115
120
|
const high = Math.floor(value / Math.pow(2, 32));
|
|
116
121
|
const low = value >>> 0;
|
|
117
|
-
uint32(bytes, low);
|
|
118
|
-
uint32(bytes, high);
|
|
122
|
+
uint32(bytes, low, it);
|
|
123
|
+
uint32(bytes, high, it);
|
|
119
124
|
};
|
|
120
125
|
|
|
121
|
-
export function uint64(bytes, value) {
|
|
126
|
+
export function uint64(bytes, value, it) {
|
|
122
127
|
const high = (value / Math.pow(2, 32)) >> 0;
|
|
123
128
|
const low = value >>> 0;
|
|
124
|
-
uint32(bytes, low);
|
|
125
|
-
uint32(bytes, high);
|
|
129
|
+
uint32(bytes, low, it);
|
|
130
|
+
uint32(bytes, high, it);
|
|
126
131
|
};
|
|
127
132
|
|
|
128
|
-
export function float32(bytes, value) {
|
|
129
|
-
writeFloat32(bytes, value);
|
|
133
|
+
export function float32(bytes, value, it) {
|
|
134
|
+
writeFloat32(bytes, value, it);
|
|
130
135
|
}
|
|
131
136
|
|
|
132
|
-
export function float64(bytes, value) {
|
|
133
|
-
writeFloat64(bytes, value);
|
|
137
|
+
export function float64(bytes, value, it) {
|
|
138
|
+
writeFloat64(bytes, value, it);
|
|
134
139
|
}
|
|
135
140
|
|
|
136
141
|
// force little endian to facilitate decoding on multiple implementations
|
|
@@ -139,69 +144,70 @@ const _int32 = new Int32Array(2);
|
|
|
139
144
|
const _float32 = new Float32Array(_int32.buffer);
|
|
140
145
|
const _float64 = new Float64Array(_int32.buffer);
|
|
141
146
|
|
|
142
|
-
export function writeFloat32(bytes, value) {
|
|
147
|
+
export function writeFloat32(bytes, value, it) {
|
|
143
148
|
_float32[0] = value;
|
|
144
|
-
int32(bytes, _int32[0]);
|
|
149
|
+
int32(bytes, _int32[0], it);
|
|
145
150
|
};
|
|
146
151
|
|
|
147
|
-
export function writeFloat64(bytes, value) {
|
|
152
|
+
export function writeFloat64(bytes, value, it) {
|
|
148
153
|
_float64[0] = value;
|
|
149
|
-
int32(bytes, _int32[_isLittleEndian ? 0 : 1]);
|
|
150
|
-
int32(bytes, _int32[_isLittleEndian ? 1 : 0]);
|
|
154
|
+
int32(bytes, _int32[_isLittleEndian ? 0 : 1], it);
|
|
155
|
+
int32(bytes, _int32[_isLittleEndian ? 1 : 0], it);
|
|
151
156
|
};
|
|
152
157
|
|
|
153
|
-
export function boolean(bytes, value) {
|
|
154
|
-
|
|
158
|
+
export function boolean(bytes, value, it) {
|
|
159
|
+
bytes[it.offset++] = value ? 1 : 0; // uint8
|
|
155
160
|
};
|
|
156
161
|
|
|
157
|
-
export function string(bytes, value) {
|
|
162
|
+
export function string(bytes: Buffer, value, it) {
|
|
158
163
|
// encode `null` strings as empty.
|
|
159
164
|
if (!value) { value = ""; }
|
|
160
165
|
|
|
161
|
-
let length = utf8Length(value);
|
|
166
|
+
// let length = utf8Length(value);
|
|
167
|
+
let length = Buffer.byteLength(value, "utf8");
|
|
162
168
|
let size = 0;
|
|
163
169
|
|
|
164
170
|
// fixstr
|
|
165
171
|
if (length < 0x20) {
|
|
166
|
-
bytes.
|
|
172
|
+
bytes[it.offset++] = length | 0xa0;
|
|
167
173
|
size = 1;
|
|
168
174
|
}
|
|
169
175
|
// str 8
|
|
170
176
|
else if (length < 0x100) {
|
|
171
|
-
bytes.
|
|
172
|
-
|
|
177
|
+
bytes[it.offset++] = 0xd9;
|
|
178
|
+
bytes[it.offset++] = length % 255;
|
|
173
179
|
size = 2;
|
|
174
180
|
}
|
|
175
181
|
// str 16
|
|
176
182
|
else if (length < 0x10000) {
|
|
177
|
-
bytes.
|
|
178
|
-
uint16(bytes, length);
|
|
183
|
+
bytes[it.offset++] = 0xda;
|
|
184
|
+
uint16(bytes, length, it);
|
|
179
185
|
size = 3;
|
|
180
186
|
}
|
|
181
187
|
// str 32
|
|
182
188
|
else if (length < 0x100000000) {
|
|
183
|
-
bytes.
|
|
184
|
-
uint32(bytes, length);
|
|
189
|
+
bytes[it.offset++] = 0xdb;
|
|
190
|
+
uint32(bytes, length, it);
|
|
185
191
|
size = 5;
|
|
186
192
|
} else {
|
|
187
193
|
throw new Error('String too long');
|
|
188
194
|
}
|
|
189
195
|
|
|
190
|
-
utf8Write(bytes,
|
|
196
|
+
utf8Write(bytes, value, it);
|
|
191
197
|
|
|
192
198
|
return size + length;
|
|
193
199
|
}
|
|
194
200
|
|
|
195
|
-
export function number(bytes, value) {
|
|
201
|
+
export function number(bytes, value, it) {
|
|
196
202
|
if (isNaN(value)) {
|
|
197
|
-
return number(bytes, 0);
|
|
203
|
+
return number(bytes, 0, it);
|
|
198
204
|
|
|
199
205
|
} else if (!isFinite(value)) {
|
|
200
|
-
return number(bytes, (value > 0) ? Number.MAX_SAFE_INTEGER : -Number.MAX_SAFE_INTEGER);
|
|
206
|
+
return number(bytes, (value > 0) ? Number.MAX_SAFE_INTEGER : -Number.MAX_SAFE_INTEGER, it);
|
|
201
207
|
|
|
202
208
|
} else if (value !== (value|0)) {
|
|
203
|
-
bytes.
|
|
204
|
-
writeFloat64(bytes, value);
|
|
209
|
+
bytes[it.offset++] = 0xcb;
|
|
210
|
+
writeFloat64(bytes, value, it);
|
|
205
211
|
return 9;
|
|
206
212
|
|
|
207
213
|
// TODO: encode float 32?
|
|
@@ -216,68 +222,68 @@ export function number(bytes, value) {
|
|
|
216
222
|
if (value >= 0) {
|
|
217
223
|
// positive fixnum
|
|
218
224
|
if (value < 0x80) {
|
|
219
|
-
|
|
225
|
+
bytes[it.offset++] = value & 255; // uint8
|
|
220
226
|
return 1;
|
|
221
227
|
}
|
|
222
228
|
|
|
223
229
|
// uint 8
|
|
224
230
|
if (value < 0x100) {
|
|
225
|
-
bytes.
|
|
226
|
-
|
|
231
|
+
bytes[it.offset++] = 0xcc;
|
|
232
|
+
bytes[it.offset++] = value & 255; // uint8
|
|
227
233
|
return 2;
|
|
228
234
|
}
|
|
229
235
|
|
|
230
236
|
// uint 16
|
|
231
237
|
if (value < 0x10000) {
|
|
232
|
-
bytes.
|
|
233
|
-
uint16(bytes, value);
|
|
238
|
+
bytes[it.offset++] = 0xcd;
|
|
239
|
+
uint16(bytes, value, it);
|
|
234
240
|
return 3;
|
|
235
241
|
}
|
|
236
242
|
|
|
237
243
|
// uint 32
|
|
238
244
|
if (value < 0x100000000) {
|
|
239
|
-
bytes.
|
|
240
|
-
uint32(bytes, value);
|
|
245
|
+
bytes[it.offset++] = 0xce;
|
|
246
|
+
uint32(bytes, value, it);
|
|
241
247
|
return 5;
|
|
242
248
|
}
|
|
243
249
|
|
|
244
250
|
// uint 64
|
|
245
|
-
bytes.
|
|
246
|
-
uint64(bytes, value);
|
|
251
|
+
bytes[it.offset++] = 0xcf;
|
|
252
|
+
uint64(bytes, value, it);
|
|
247
253
|
return 9;
|
|
248
254
|
|
|
249
255
|
} else {
|
|
250
256
|
|
|
251
257
|
// negative fixnum
|
|
252
258
|
if (value >= -0x20) {
|
|
253
|
-
bytes.
|
|
259
|
+
bytes[it.offset++] = 0xe0 | (value + 0x20);
|
|
254
260
|
return 1;
|
|
255
261
|
}
|
|
256
262
|
|
|
257
263
|
// int 8
|
|
258
264
|
if (value >= -0x80) {
|
|
259
|
-
bytes.
|
|
260
|
-
int8(bytes, value);
|
|
265
|
+
bytes[it.offset++] = 0xd0;
|
|
266
|
+
int8(bytes, value, it);
|
|
261
267
|
return 2;
|
|
262
268
|
}
|
|
263
269
|
|
|
264
270
|
// int 16
|
|
265
271
|
if (value >= -0x8000) {
|
|
266
|
-
bytes.
|
|
267
|
-
int16(bytes, value);
|
|
272
|
+
bytes[it.offset++] = 0xd1;
|
|
273
|
+
int16(bytes, value, it);
|
|
268
274
|
return 3;
|
|
269
275
|
}
|
|
270
276
|
|
|
271
277
|
// int 32
|
|
272
278
|
if (value >= -0x80000000) {
|
|
273
|
-
bytes.
|
|
274
|
-
int32(bytes, value);
|
|
279
|
+
bytes[it.offset++] = 0xd2;
|
|
280
|
+
int32(bytes, value, it);
|
|
275
281
|
return 5;
|
|
276
282
|
}
|
|
277
283
|
|
|
278
284
|
// int 64
|
|
279
|
-
bytes.
|
|
280
|
-
int64(bytes, value);
|
|
285
|
+
bytes[it.offset++] = 0xd3;
|
|
286
|
+
int64(bytes, value, it);
|
|
281
287
|
return 9;
|
|
282
288
|
}
|
|
283
|
-
}
|
|
289
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
|
|
2
|
+
export const TYPE_ID = 213;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Encoding Schema field operations.
|
|
6
|
+
*/
|
|
7
|
+
export enum OPERATION {
|
|
8
|
+
ADD = 128, // (10000000) add new structure/primitive
|
|
9
|
+
REPLACE = 0, // (00000001) replace structure/primitive
|
|
10
|
+
DELETE = 64, // (01000000) delete field
|
|
11
|
+
DELETE_AND_MOVE = 96, // () add new structure/primitive
|
|
12
|
+
MOVE_AND_ADD = 160, // () add new structure/primitive
|
|
13
|
+
DELETE_AND_ADD = 192, // (11000000) DELETE field, followed by an ADD
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Collection operations
|
|
17
|
+
*/
|
|
18
|
+
CLEAR = 10,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* ArraySchema operations
|
|
22
|
+
*/
|
|
23
|
+
PUSH = 11,
|
|
24
|
+
UNSHIFT = 12,
|
|
25
|
+
REVERSE = 15,
|
|
26
|
+
MOVE = 32,
|
|
27
|
+
DELETE_BY_REFID = 33, // This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE
|
|
28
|
+
|
|
29
|
+
}
|