@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.
Files changed (159) hide show
  1. package/build/cjs/index.js +3614 -2634
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +3324 -2445
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +3614 -2634
  6. package/lib/Decoder.d.ts +16 -0
  7. package/lib/Decoder.js +182 -0
  8. package/lib/Decoder.js.map +1 -0
  9. package/lib/Encoder.d.ts +13 -0
  10. package/lib/Encoder.js +79 -0
  11. package/lib/Encoder.js.map +1 -0
  12. package/lib/Metadata.d.ts +36 -0
  13. package/lib/Metadata.js +91 -0
  14. package/lib/Metadata.js.map +1 -0
  15. package/lib/Reflection.d.ts +7 -5
  16. package/lib/Reflection.js +62 -58
  17. package/lib/Reflection.js.map +1 -1
  18. package/lib/Schema.d.ts +39 -51
  19. package/lib/Schema.js +189 -731
  20. package/lib/Schema.js.map +1 -1
  21. package/lib/annotations.d.ts +26 -45
  22. package/lib/annotations.js +363 -194
  23. package/lib/annotations.js.map +1 -1
  24. package/lib/changes/ChangeSet.d.ts +12 -0
  25. package/lib/changes/ChangeSet.js +35 -0
  26. package/lib/changes/ChangeSet.js.map +1 -0
  27. package/lib/changes/DecodeOperation.d.ts +15 -0
  28. package/lib/changes/DecodeOperation.js +186 -0
  29. package/lib/changes/DecodeOperation.js.map +1 -0
  30. package/lib/changes/EncodeOperation.d.ts +18 -0
  31. package/lib/changes/EncodeOperation.js +130 -0
  32. package/lib/changes/EncodeOperation.js.map +1 -0
  33. package/lib/changes/consts.d.ts +14 -0
  34. package/lib/changes/consts.js +18 -0
  35. package/lib/changes/consts.js.map +1 -0
  36. package/lib/decoder/DecodeOperation.d.ts +24 -0
  37. package/lib/decoder/DecodeOperation.js +256 -0
  38. package/lib/decoder/DecodeOperation.js.map +1 -0
  39. package/lib/decoder/Decoder.d.ts +21 -0
  40. package/lib/decoder/Decoder.js +114 -0
  41. package/lib/decoder/Decoder.js.map +1 -0
  42. package/lib/decoder/ReferenceTracker.d.ts +26 -0
  43. package/lib/decoder/ReferenceTracker.js +131 -0
  44. package/lib/decoder/ReferenceTracker.js.map +1 -0
  45. package/lib/decoder/strategy/RawChanges.d.ts +3 -0
  46. package/lib/decoder/strategy/RawChanges.js +8 -0
  47. package/lib/decoder/strategy/RawChanges.js.map +1 -0
  48. package/lib/decoder/strategy/StateCallbacks.d.ts +20 -0
  49. package/lib/decoder/strategy/StateCallbacks.js +240 -0
  50. package/lib/decoder/strategy/StateCallbacks.js.map +1 -0
  51. package/lib/decoding/decode.d.ts +48 -0
  52. package/lib/decoding/decode.js +267 -0
  53. package/lib/decoding/decode.js.map +1 -0
  54. package/lib/ecs.d.ts +11 -0
  55. package/lib/ecs.js +160 -0
  56. package/lib/ecs.js.map +1 -0
  57. package/lib/encoder/ChangeTree.d.ts +72 -0
  58. package/lib/encoder/ChangeTree.js +384 -0
  59. package/lib/encoder/ChangeTree.js.map +1 -0
  60. package/lib/encoder/EncodeOperation.d.ts +25 -0
  61. package/lib/encoder/EncodeOperation.js +156 -0
  62. package/lib/encoder/EncodeOperation.js.map +1 -0
  63. package/lib/encoder/Encoder.d.ts +23 -0
  64. package/lib/encoder/Encoder.js +192 -0
  65. package/lib/encoder/Encoder.js.map +1 -0
  66. package/lib/encoder/StateView.d.ts +21 -0
  67. package/lib/encoder/StateView.js +196 -0
  68. package/lib/encoder/StateView.js.map +1 -0
  69. package/lib/encoding/assert.d.ts +9 -0
  70. package/lib/encoding/assert.js +47 -0
  71. package/lib/encoding/assert.js.map +1 -0
  72. package/lib/encoding/decode.js +1 -1
  73. package/lib/encoding/decode.js.map +1 -1
  74. package/lib/encoding/encode.d.ts +17 -16
  75. package/lib/encoding/encode.js +88 -81
  76. package/lib/encoding/encode.js.map +1 -1
  77. package/lib/encoding/spec.d.ts +25 -0
  78. package/lib/encoding/spec.js +30 -0
  79. package/lib/encoding/spec.js.map +1 -0
  80. package/lib/index.d.ts +18 -10
  81. package/lib/index.js +39 -17
  82. package/lib/index.js.map +1 -1
  83. package/lib/symbol.shim.d.ts +6 -0
  84. package/lib/symbol.shim.js +4 -0
  85. package/lib/symbol.shim.js.map +1 -0
  86. package/lib/types/ArraySchema.js +0 -7
  87. package/lib/types/ArraySchema.js.map +1 -1
  88. package/lib/types/HelperTypes.d.ts +10 -2
  89. package/lib/types/HelperTypes.js.map +1 -1
  90. package/lib/types/custom/ArraySchema.d.ts +245 -0
  91. package/lib/types/custom/ArraySchema.js +659 -0
  92. package/lib/types/custom/ArraySchema.js.map +1 -0
  93. package/lib/types/custom/CollectionSchema.d.ts +42 -0
  94. package/lib/types/custom/CollectionSchema.js +165 -0
  95. package/lib/types/custom/CollectionSchema.js.map +1 -0
  96. package/lib/types/custom/MapSchema.d.ts +43 -0
  97. package/lib/types/custom/MapSchema.js +200 -0
  98. package/lib/types/custom/MapSchema.js.map +1 -0
  99. package/lib/types/custom/SetSchema.d.ts +39 -0
  100. package/lib/types/custom/SetSchema.js +177 -0
  101. package/lib/types/custom/SetSchema.js.map +1 -0
  102. package/lib/types/registry.d.ts +6 -0
  103. package/lib/types/registry.js +19 -0
  104. package/lib/types/registry.js.map +1 -0
  105. package/lib/types/symbols.d.ts +29 -0
  106. package/lib/types/symbols.js +33 -0
  107. package/lib/types/symbols.js.map +1 -0
  108. package/lib/types/utils.d.ts +0 -8
  109. package/lib/types/utils.js +1 -33
  110. package/lib/types/utils.js.map +1 -1
  111. package/lib/usage.d.ts +1 -0
  112. package/lib/usage.js +22 -0
  113. package/lib/usage.js.map +1 -0
  114. package/lib/utils.d.ts +13 -2
  115. package/lib/utils.js +36 -15
  116. package/lib/utils.js.map +1 -1
  117. package/lib/v3.d.ts +1 -0
  118. package/lib/v3.js +427 -0
  119. package/lib/v3.js.map +1 -0
  120. package/lib/v3_bench.d.ts +1 -0
  121. package/lib/v3_bench.js +130 -0
  122. package/lib/v3_bench.js.map +1 -0
  123. package/lib/v3_experiment.d.ts +1 -0
  124. package/lib/v3_experiment.js +407 -0
  125. package/lib/v3_experiment.js.map +1 -0
  126. package/package.json +5 -5
  127. package/src/Metadata.ts +135 -0
  128. package/src/Reflection.ts +75 -66
  129. package/src/Schema.ts +213 -931
  130. package/src/annotations.ts +430 -243
  131. package/src/decoder/DecodeOperation.ts +372 -0
  132. package/src/decoder/Decoder.ts +155 -0
  133. package/src/decoder/ReferenceTracker.ts +151 -0
  134. package/src/decoder/strategy/RawChanges.ts +9 -0
  135. package/src/decoder/strategy/StateCallbacks.ts +326 -0
  136. package/src/encoder/ChangeTree.ts +492 -0
  137. package/src/encoder/EncodeOperation.ts +237 -0
  138. package/src/encoder/Encoder.ts +246 -0
  139. package/src/encoder/StateView.ts +229 -0
  140. package/src/encoding/assert.ts +58 -0
  141. package/src/encoding/decode.ts +1 -1
  142. package/src/encoding/encode.ts +88 -82
  143. package/src/encoding/spec.ts +29 -0
  144. package/src/index.ts +22 -19
  145. package/src/symbol.shim.ts +12 -0
  146. package/src/types/HelperTypes.ts +16 -2
  147. package/src/types/{ArraySchema.ts → custom/ArraySchema.ts} +345 -251
  148. package/src/types/{CollectionSchema.ts → custom/CollectionSchema.ts} +56 -46
  149. package/src/types/{MapSchema.ts → custom/MapSchema.ts} +88 -115
  150. package/src/types/{SetSchema.ts → custom/SetSchema.ts} +58 -47
  151. package/src/types/{typeRegistry.ts → registry.ts} +6 -6
  152. package/src/types/symbols.ts +36 -0
  153. package/src/types/utils.ts +0 -46
  154. package/src/utils.ts +50 -21
  155. package/src/v3_bench.ts +107 -0
  156. package/src/changes/ChangeTree.ts +0 -295
  157. package/src/changes/ReferenceTracker.ts +0 -91
  158. package/src/filters/index.ts +0 -23
  159. 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
+ }
@@ -21,7 +21,7 @@
21
21
  * SOFTWARE
22
22
  */
23
23
 
24
- import { SWITCH_TO_STRUCTURE } from "../spec";
24
+ import { SWITCH_TO_STRUCTURE } from "./spec";
25
25
 
26
26
  /**
27
27
  * msgpack implementation highly based on notepack.io
@@ -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, offset, str) {
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
- bytes.push(value & 255);
83
+ export function int8(bytes, value, it) {
84
+ bytes[it.offset++] = value & 255;
80
85
  };
81
86
 
82
- export function uint8(bytes, value) {
83
- bytes.push(value & 255);
87
+ export function uint8(bytes, value, it) {
88
+ bytes[it.offset++] = value & 255;
84
89
  };
85
90
 
86
- export function int16(bytes, value) {
87
- bytes.push(value & 255);
88
- bytes.push((value >> 8) & 255);
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
- bytes.push(value & 255);
93
- bytes.push((value >> 8) & 255);
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.push(value & 255);
98
- bytes.push((value >> 8) & 255);
99
- bytes.push((value >> 16) & 255);
100
- bytes.push((value >> 24) & 255);
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.push(b1 & 255);
109
- bytes.push(b2 & 255);
110
- bytes.push(b3 & 255);
111
- bytes.push(b4 & 255);
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
- return uint8(bytes, value ? 1 : 0);
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.push(length | 0xa0);
172
+ bytes[it.offset++] = length | 0xa0;
167
173
  size = 1;
168
174
  }
169
175
  // str 8
170
176
  else if (length < 0x100) {
171
- bytes.push(0xd9);
172
- uint8(bytes, length);
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.push(0xda);
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.push(0xdb);
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, bytes.length, value);
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.push(0xcb);
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
- uint8(bytes, value);
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.push(0xcc);
226
- uint8(bytes, value);
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.push(0xcd);
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.push(0xce);
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.push(0xcf);
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.push(0xe0 | (value + 0x20));
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.push(0xd0);
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.push(0xd1);
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.push(0xd2);
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.push(0xd3);
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
+ }