@colyseus/schema 2.0.32 → 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.d.ts +1 -1
- 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} +342 -248
- 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
|
@@ -1,42 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { OPERATION } from "../../encoding/spec";
|
|
2
|
+
import { registerType } from "../registry";
|
|
3
|
+
import { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex } from "../symbols";
|
|
4
|
+
import { Collection } from "../HelperTypes";
|
|
5
|
+
import { ChangeTree } from "../../encoder/ChangeTree";
|
|
6
|
+
import { encodeKeyValueOperation } from "../../encoder/EncodeOperation";
|
|
7
|
+
import { decodeKeyValueOperation } from "../../decoder/DecodeOperation";
|
|
8
|
+
import type { StateView } from "../../encoder/StateView";
|
|
6
9
|
|
|
7
|
-
export class SetSchema<V=any> implements
|
|
8
|
-
protected $changes: ChangeTree = new ChangeTree(this);
|
|
10
|
+
export class SetSchema<V=any> implements Collection<number, V> {
|
|
9
11
|
|
|
10
12
|
protected $items: Map<number, V> = new Map<number, V>();
|
|
11
13
|
protected $indexes: Map<number, number> = new Map<number, number>();
|
|
12
14
|
|
|
13
15
|
protected $refId: number = 0;
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
static [$encoder] = encodeKeyValueOperation;
|
|
18
|
+
static [$decoder] = decodeKeyValueOperation;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Determine if a property must be filtered.
|
|
22
|
+
* - If returns false, the property is NOT going to be encoded.
|
|
23
|
+
* - If returns true, the property is going to be encoded.
|
|
24
|
+
*
|
|
25
|
+
* Encoding with "filters" happens in two steps:
|
|
26
|
+
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
27
|
+
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
28
|
+
*/
|
|
29
|
+
static [$filter] (ref: SetSchema, index: number, view: StateView) {
|
|
30
|
+
return (
|
|
31
|
+
!view ||
|
|
32
|
+
typeof (ref[$childType]) === "string" ||
|
|
33
|
+
view.items.has(ref[$getByIndex](index)[$changes])
|
|
27
34
|
);
|
|
28
35
|
}
|
|
29
|
-
public onRemove(callback: (item: V, key: string) => void) { return addCallback(this.$callbacks || (this.$callbacks = []), OPERATION.DELETE, callback); }
|
|
30
|
-
public onChange(callback: (item: V, key: string) => void) { return addCallback(this.$callbacks || (this.$callbacks = []), OPERATION.REPLACE, callback); }
|
|
31
36
|
|
|
32
37
|
static is(type: any) {
|
|
33
38
|
return type['set'] !== undefined;
|
|
34
39
|
}
|
|
35
40
|
|
|
36
41
|
constructor (initialValues?: Array<V>) {
|
|
42
|
+
this[$changes] = new ChangeTree(this);
|
|
43
|
+
|
|
37
44
|
if (initialValues) {
|
|
38
45
|
initialValues.forEach((v) => this.add(v));
|
|
39
46
|
}
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(this, $childType, {
|
|
49
|
+
value: undefined,
|
|
50
|
+
enumerable: false,
|
|
51
|
+
writable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
});
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
add(value: V) {
|
|
@@ -46,18 +60,18 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
46
60
|
// set "index" for reference.
|
|
47
61
|
const index = this.$refId++;
|
|
48
62
|
|
|
49
|
-
if ((value[
|
|
50
|
-
|
|
63
|
+
if ((value[$changes]) !== undefined) {
|
|
64
|
+
value[$changes].setParent(this, this[$changes].root, index);
|
|
51
65
|
}
|
|
52
66
|
|
|
53
|
-
const operation = this
|
|
67
|
+
const operation = this[$changes].indexes[index]?.op ?? OPERATION.ADD;
|
|
54
68
|
|
|
55
|
-
this
|
|
69
|
+
this[$changes].indexes[index] = index;
|
|
56
70
|
|
|
57
71
|
this.$indexes.set(index, index);
|
|
58
72
|
this.$items.set(index, value);
|
|
59
73
|
|
|
60
|
-
this
|
|
74
|
+
this[$changes].change(index, operation);
|
|
61
75
|
return index;
|
|
62
76
|
}
|
|
63
77
|
|
|
@@ -83,36 +97,26 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
83
97
|
return false;
|
|
84
98
|
}
|
|
85
99
|
|
|
86
|
-
this
|
|
100
|
+
this[$changes].delete(index);
|
|
87
101
|
this.$indexes.delete(index);
|
|
88
102
|
|
|
89
103
|
return this.$items.delete(index);
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
clear(
|
|
106
|
+
clear() {
|
|
107
|
+
const changeTree = this[$changes];
|
|
108
|
+
|
|
93
109
|
// discard previous operations.
|
|
94
|
-
|
|
95
|
-
|
|
110
|
+
changeTree.discard(true);
|
|
111
|
+
changeTree.indexes = {};
|
|
96
112
|
|
|
97
113
|
// clear previous indexes
|
|
98
114
|
this.$indexes.clear();
|
|
99
115
|
|
|
100
|
-
//
|
|
101
|
-
// When decoding:
|
|
102
|
-
// - enqueue items for DELETE callback.
|
|
103
|
-
// - flag child items for garbage collection.
|
|
104
|
-
//
|
|
105
|
-
if (changes) {
|
|
106
|
-
removeChildRefs.call(this, changes);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
116
|
// clear items
|
|
110
117
|
this.$items.clear();
|
|
111
118
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// touch all structures until reach root
|
|
115
|
-
this.$changes.touchParents();
|
|
119
|
+
changeTree.operation(OPERATION.CLEAR);
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
has (value: V): boolean {
|
|
@@ -144,6 +148,11 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
144
148
|
return this.$items.size;
|
|
145
149
|
}
|
|
146
150
|
|
|
151
|
+
/** Iterator */
|
|
152
|
+
[Symbol.iterator](): IterableIterator<V> {
|
|
153
|
+
return this.$items.values();
|
|
154
|
+
}
|
|
155
|
+
|
|
147
156
|
protected setIndex(index: number, key: number) {
|
|
148
157
|
this.$indexes.set(index, key);
|
|
149
158
|
}
|
|
@@ -152,11 +161,11 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
152
161
|
return this.$indexes.get(index);
|
|
153
162
|
}
|
|
154
163
|
|
|
155
|
-
protected getByIndex(index: number) {
|
|
164
|
+
protected [$getByIndex](index: number) {
|
|
156
165
|
return this.$items.get(this.$indexes.get(index));
|
|
157
166
|
}
|
|
158
167
|
|
|
159
|
-
protected deleteByIndex(index: number) {
|
|
168
|
+
protected [$deleteByIndex](index: number) {
|
|
160
169
|
const key = this.$indexes.get(index);
|
|
161
170
|
this.$items.delete(key);
|
|
162
171
|
this.$indexes.delete(index);
|
|
@@ -194,7 +203,7 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
194
203
|
// server-side
|
|
195
204
|
cloned = new SetSchema();
|
|
196
205
|
this.forEach((value) => {
|
|
197
|
-
if (value[
|
|
206
|
+
if (value[$changes]) {
|
|
198
207
|
cloned.add(value['clone']());
|
|
199
208
|
} else {
|
|
200
209
|
cloned.add(value);
|
|
@@ -205,4 +214,6 @@ export class SetSchema<V=any> implements SchemaDecoderCallbacks {
|
|
|
205
214
|
return cloned;
|
|
206
215
|
}
|
|
207
216
|
|
|
208
|
-
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
registerType("set", { constructor: SetSchema });
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export interface TypeDefinition {
|
|
2
2
|
constructor: any,
|
|
3
|
-
|
|
4
|
-
// //
|
|
5
|
-
// // TODO: deprecate proxy on next version
|
|
6
|
-
// // the proxy is used for compatibility with versions <1.0.0 of @colyseus/schema
|
|
7
|
-
// //
|
|
8
|
-
// getProxy?: any,
|
|
9
3
|
}
|
|
10
4
|
|
|
11
5
|
const registeredTypes: {[identifier: string] : TypeDefinition} = {};
|
|
6
|
+
const identifiers = new Map<any, string>();
|
|
12
7
|
|
|
13
8
|
export function registerType(identifier: string, definition: TypeDefinition) {
|
|
9
|
+
identifiers.set(definition.constructor, identifier);
|
|
14
10
|
registeredTypes[identifier] = definition;
|
|
15
11
|
}
|
|
16
12
|
|
|
13
|
+
export function getIdentifier(klass: any): string {
|
|
14
|
+
return identifiers.get(klass);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
17
|
export function getType(identifier: string): TypeDefinition {
|
|
18
18
|
return registeredTypes[identifier];
|
|
19
19
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const $track = Symbol("$track");
|
|
2
|
+
export const $encoder = Symbol("$encoder");
|
|
3
|
+
export const $decoder = Symbol("$decoder");
|
|
4
|
+
|
|
5
|
+
export const $filter = Symbol("$filter");
|
|
6
|
+
|
|
7
|
+
export const $getByIndex = Symbol("$getByIndex");
|
|
8
|
+
export const $deleteByIndex = Symbol("$deleteByIndex");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Used to hold ChangeTree instances whitin the structures
|
|
12
|
+
*/
|
|
13
|
+
export const $changes = Symbol('$changes');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Used to keep track of the type of the child elements of a collection
|
|
17
|
+
* (MapSchema, ArraySchema, etc.)
|
|
18
|
+
*/
|
|
19
|
+
export const $childType = Symbol('$childType');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Special ChangeTree property to identify new instances
|
|
23
|
+
* (Once they're encoded, they're not new anymore)
|
|
24
|
+
*/
|
|
25
|
+
export const $isNew = Symbol("$isNew");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Optional "discard" method for custom types (ArraySchema)
|
|
29
|
+
* (Discards changes for next serialization)
|
|
30
|
+
*/
|
|
31
|
+
export const $onEncodeEnd = Symbol('$onEncodeEnd');
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* When decoding, this method is called after the instance is fully decoded
|
|
35
|
+
*/
|
|
36
|
+
export const $onDecodeEnd = Symbol("$onDecodeEnd");
|
package/src/types/utils.ts
CHANGED
|
@@ -1,49 +1,3 @@
|
|
|
1
|
-
import { CollectionSchema, DataChange } from "..";
|
|
2
|
-
import { OPERATION } from "../spec";
|
|
3
|
-
|
|
4
|
-
export function addCallback(
|
|
5
|
-
$callbacks: { [op: number]: Function[] },
|
|
6
|
-
op: OPERATION,
|
|
7
|
-
callback: (item: any, key: any) => void,
|
|
8
|
-
existing?: { forEach(callback: (item: any, key: any) => void): void; }
|
|
9
|
-
) {
|
|
10
|
-
// initialize list of callbacks
|
|
11
|
-
if (!$callbacks[op]) {
|
|
12
|
-
$callbacks[op] = [];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
$callbacks[op].push(callback);
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
// Trigger callback for existing elements
|
|
19
|
-
// - OPERATION.ADD
|
|
20
|
-
// - OPERATION.REPLACE
|
|
21
|
-
//
|
|
22
|
-
existing?.forEach((item, key) => callback(item, key));
|
|
23
|
-
|
|
24
|
-
return () => spliceOne($callbacks[op], $callbacks[op].indexOf(callback));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export function removeChildRefs(this: CollectionSchema, changes: DataChange[]) {
|
|
29
|
-
const needRemoveRef = (typeof (this.$changes.getType()) !== "string");
|
|
30
|
-
|
|
31
|
-
this.$items.forEach((item: any, key: any) => {
|
|
32
|
-
changes.push({
|
|
33
|
-
refId: this.$changes.refId,
|
|
34
|
-
op: OPERATION.DELETE,
|
|
35
|
-
field: key,
|
|
36
|
-
value: undefined,
|
|
37
|
-
previousValue: item
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (needRemoveRef) {
|
|
41
|
-
this.$changes.root.removeRef(item['$changes'].refId);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
1
|
export function spliceOne(arr: any[], index: number): boolean {
|
|
48
2
|
// manually splice an array
|
|
49
3
|
if (index === -1 || index >= arr.length) {
|
package/src/utils.ts
CHANGED
|
@@ -1,28 +1,57 @@
|
|
|
1
|
-
import { Schema } from "./Schema";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import type { Schema } from "./Schema";
|
|
2
|
+
import { OPERATION } from "./encoding/spec";
|
|
3
|
+
import { $changes } from "./types/symbols";
|
|
4
|
+
|
|
5
|
+
type ChangeItem = [string, number | string, any?];
|
|
6
|
+
|
|
7
|
+
interface ChangeDump {
|
|
8
|
+
ops: {
|
|
9
|
+
ADD?: number;
|
|
10
|
+
REMOVE?: number;
|
|
11
|
+
REPLACE?: number;
|
|
12
|
+
},
|
|
13
|
+
refs: string[],
|
|
14
|
+
}
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
export function getIndent(level: number) {
|
|
17
|
+
return (new Array(level).fill(0)).map((_, i) =>
|
|
18
|
+
(i === level - 1) ? `└─ ` : ` `
|
|
19
|
+
).join("");
|
|
20
|
+
}
|
|
13
21
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
export function dumpChanges(schema: Schema) {
|
|
23
|
+
const $root = schema[$changes].root;
|
|
24
|
+
|
|
25
|
+
const dump: ChangeDump = {
|
|
26
|
+
ops: {},
|
|
27
|
+
refs: []
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
$root.changes.forEach((operations, changeTree) => {
|
|
31
|
+
dump.refs.push(`refId#${changeTree.refId}`);
|
|
32
|
+
operations.forEach((op, index) => {
|
|
33
|
+
const opName = OPERATION[op];
|
|
34
|
+
if (!dump.ops[opName]) { dump.ops[opName] = 0; }
|
|
35
|
+
dump.ops[OPERATION[op]]++;
|
|
36
|
+
});
|
|
37
|
+
});
|
|
17
38
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
: ref['$indexes'].get(fieldIndex);
|
|
39
|
+
return dump;
|
|
40
|
+
}
|
|
21
41
|
|
|
22
|
-
|
|
23
|
-
|
|
42
|
+
export function getNextPowerOf2(number: number) {
|
|
43
|
+
// If number is already a power of 2, return it
|
|
44
|
+
if ((number & (number - 1)) === 0) {
|
|
45
|
+
return number;
|
|
46
|
+
}
|
|
24
47
|
|
|
48
|
+
// Find the position of the most significant bit
|
|
49
|
+
let msbPosition = 0;
|
|
50
|
+
while (number > 0) {
|
|
51
|
+
number >>= 1;
|
|
52
|
+
msbPosition++;
|
|
25
53
|
}
|
|
26
54
|
|
|
27
|
-
|
|
28
|
-
|
|
55
|
+
// Return the next power of 2
|
|
56
|
+
return 1 << msbPosition;
|
|
57
|
+
}
|
package/src/v3_bench.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Schema, type, MapSchema, ArraySchema, Reflection, Encoder, Decoder } from "./index";
|
|
2
|
+
|
|
3
|
+
// globalThis.interval = setInterval(() => {}, 1000);
|
|
4
|
+
|
|
5
|
+
// class Item extends Schema {
|
|
6
|
+
// @type("string") name: string;
|
|
7
|
+
// }
|
|
8
|
+
|
|
9
|
+
// class RootState extends Schema {
|
|
10
|
+
// @type([Item]) items = new ArraySchema<Item>();
|
|
11
|
+
// }
|
|
12
|
+
// const state = new RootState();
|
|
13
|
+
// state.items.push(new Item().assign({ name: "hello" }));
|
|
14
|
+
|
|
15
|
+
// console.log("Encoded:", state.encode());
|
|
16
|
+
|
|
17
|
+
class Vec3 extends Schema {
|
|
18
|
+
@type("number") x: number;
|
|
19
|
+
@type("number") y: number;
|
|
20
|
+
@type("number") z: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
class Base extends Schema {}
|
|
24
|
+
|
|
25
|
+
class Entity extends Schema {
|
|
26
|
+
@type(Vec3) position = new Vec3().assign({ x: 0, y: 0, z: 0 });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class Player extends Entity {
|
|
30
|
+
@type(Vec3) rotation = new Vec3().assign({ x: 0, y: 0, z: 0 });
|
|
31
|
+
@type("string") secret: string = "private info only for this player";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class State extends Schema {
|
|
35
|
+
// @type({ map: Base }) players = new MapSchema<Entity>();
|
|
36
|
+
@type("number") num: number = 0;
|
|
37
|
+
@type("string") str = "Hello world!";
|
|
38
|
+
// @type(Entity) entity = new Player().assign({
|
|
39
|
+
// position: new Vec3().assign({ x: 1, y: 2, z: 3 }),
|
|
40
|
+
// rotation: new Vec3().assign({ x: 4, y: 5, z: 6 }),
|
|
41
|
+
// });
|
|
42
|
+
@type({ map: Entity }) entities = new MapSchema();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const state = new State();
|
|
46
|
+
|
|
47
|
+
state.entities.set("one", new Player().assign({
|
|
48
|
+
position: new Vec3().assign({ x: 1, y: 2, z: 3 }),
|
|
49
|
+
rotation: new Vec3().assign({ x: 1, y: 2, z: 3 }),
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
state.entities.set("two", new Player().assign({
|
|
53
|
+
position: new Vec3().assign({ x: 4, y: 5, z: 6 }),
|
|
54
|
+
rotation: new Vec3().assign({ x: 7, y: 8, z: 9 }),
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
const encoder = new Encoder(state);
|
|
58
|
+
let encoded = encoder.encode();
|
|
59
|
+
console.log(`(${encoded.length})`, [...encoded]);
|
|
60
|
+
|
|
61
|
+
globalThis.perform = function() {
|
|
62
|
+
for (let i = 0; i < 500000; i++) {
|
|
63
|
+
encoder.encodeAll();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function logTime(label: string, callback: Function) {
|
|
68
|
+
const time = Date.now();
|
|
69
|
+
for (let i = 0; i < 500000; i++) {
|
|
70
|
+
callback();
|
|
71
|
+
}
|
|
72
|
+
console.log(`${label}:`, Date.now() - time);
|
|
73
|
+
}
|
|
74
|
+
logTime("encode time", () => encoder.encodeAll());
|
|
75
|
+
|
|
76
|
+
const decoder = new Decoder(new State());
|
|
77
|
+
logTime("decode time", () => decoder.decode(encoded));
|
|
78
|
+
|
|
79
|
+
// const time = Date.now();
|
|
80
|
+
// console.profile();
|
|
81
|
+
// for (let i = 0; i < 300000; i++) {
|
|
82
|
+
// state.encodeAll();
|
|
83
|
+
// }
|
|
84
|
+
// console.profileEnd();
|
|
85
|
+
// console.log("encode time:", Date.now() - time);
|
|
86
|
+
|
|
87
|
+
// const decoded = Reflection.decode(Reflection.encode(state));
|
|
88
|
+
// decoded.decode(encoded);
|
|
89
|
+
//
|
|
90
|
+
// console.log(decoded.toJSON());
|
|
91
|
+
//
|
|
92
|
+
// const rotation = state.entity.rotation;
|
|
93
|
+
// rotation.x = 100;
|
|
94
|
+
//
|
|
95
|
+
// encoded = state.encode();
|
|
96
|
+
// console.log({encoded});
|
|
97
|
+
//
|
|
98
|
+
// decoded.decode(encoded);
|
|
99
|
+
// console.log(decoded.toJSON());
|
|
100
|
+
|
|
101
|
+
// const time = Date.now();
|
|
102
|
+
// for (let i = 0; i < 300000; i++) {
|
|
103
|
+
// const state = new State();
|
|
104
|
+
// state.encode();
|
|
105
|
+
// }
|
|
106
|
+
// console.log("encode time:", Date.now() - time);
|
|
107
|
+
|