@bikky/replication 1.0.1
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/Constants/Errors.d.ts +27 -0
- package/Constants/Errors.js +75 -0
- package/Constants/Logging.d.ts +17 -0
- package/Constants/Logging.js +97 -0
- package/Constants/ReplicableRegistry.d.ts +37 -0
- package/Constants/ReplicableRegistry.js +234 -0
- package/Constants/SerialisationTypes.d.ts +82 -0
- package/Constants/SerialisationTypes.js +160 -0
- package/Constants/SourceMaps.d.ts +10 -0
- package/Constants/SourceMaps.js +12 -0
- package/Constants/TraversalStep.d.ts +5 -0
- package/Constants/TraversalStep.js +2 -0
- package/Constants/Versions.d.ts +15 -0
- package/Constants/Versions.js +63 -0
- package/Expressions/Compiler/BuiltinGrammar.d.ts +234 -0
- package/Expressions/Compiler/BuiltinGrammar.js +446 -0
- package/Expressions/Compiler/ExpressionGrammar.d.ts +89 -0
- package/Expressions/Compiler/ExpressionGrammar.js +70 -0
- package/Expressions/Compiler/Parser.d.ts +56 -0
- package/Expressions/Compiler/Parser.js +314 -0
- package/Expressions/Compiler/Tokenizer.d.ts +52 -0
- package/Expressions/Compiler/Tokenizer.js +222 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.d.ts +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.js +516 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.d.ts +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.js +68 -0
- package/Expressions/CreateEvaluator.d.ts +4 -0
- package/Expressions/CreateEvaluator.js +85 -0
- package/Expressions/EvaluatorChain.d.ts +19 -0
- package/Expressions/EvaluatorChain.js +137 -0
- package/Expressions/EvaluatorSteps.d.ts +19 -0
- package/Expressions/EvaluatorSteps.js +12 -0
- package/Expressions/EvaluatorString.d.ts +21 -0
- package/Expressions/EvaluatorString.js +26 -0
- package/Expressions/Expression.d.ts +36 -0
- package/Expressions/Expression.js +147 -0
- package/Expressions/Traverser.d.ts +28 -0
- package/Expressions/Traverser.js +348 -0
- package/Expressions/TypeRegistry/Accessors.d.ts +26 -0
- package/Expressions/TypeRegistry/Accessors.js +58 -0
- package/Expressions/TypeRegistry/ChainCollections.d.ts +51 -0
- package/Expressions/TypeRegistry/ChainCollections.js +134 -0
- package/Expressions/TypeRegistry/ChainTypes.d.ts +23 -0
- package/Expressions/TypeRegistry/ChainTypes.js +46 -0
- package/Expressions/TypeRegistry/CustomAPI.d.ts +36 -0
- package/Expressions/TypeRegistry/CustomAPI.js +181 -0
- package/Expressions/TypeRegistry/Primitive.d.ts +19 -0
- package/Expressions/TypeRegistry/Primitive.js +47 -0
- package/Expressions/TypeRegistry/Registry.d.ts +27 -0
- package/Expressions/TypeRegistry/Registry.js +270 -0
- package/Expressions/TypeRegistry/ReplAPI.d.ts +41 -0
- package/Expressions/TypeRegistry/ReplAPI.js +220 -0
- package/Expressions/TypeRegistry/Scope.d.ts +24 -0
- package/Expressions/TypeRegistry/Scope.js +44 -0
- package/Expressions/TypeRegistry/Types.d.ts +23 -0
- package/Expressions/TypeRegistry/Types.js +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.d.ts +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.js +31 -0
- package/Expressions/__tests__/ExpressionExamples.d.ts +28 -0
- package/Expressions/__tests__/ExpressionExamples.js +50 -0
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.d.ts +1 -0
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.js +166 -0
- package/IDPool.d.ts +18 -0
- package/IDPool.data.d.ts +17 -0
- package/IDPool.js +139 -0
- package/License.txt +1 -0
- package/Main.d.ts +13 -0
- package/Main.js +13 -0
- package/Networking.d.ts +60 -0
- package/Networking.js +626 -0
- package/Replicatable.d.ts +66 -0
- package/Replicatable.js +123 -0
- package/Tracking/Buffable.d.ts +68 -0
- package/Tracking/Buffable.js +194 -0
- package/Tracking/Class.d.ts +97 -0
- package/Tracking/Class.js +221 -0
- package/Tracking/Functions.d.ts +14 -0
- package/Tracking/Functions.js +27 -0
- package/Tracking/GlobalGroup.d.ts +5 -0
- package/Tracking/GlobalGroup.js +39 -0
- package/Tracking/Property.d.ts +95 -0
- package/Tracking/Property.js +125 -0
- package/Tracking/Types.d.ts +33 -0
- package/Tracking/Types.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.js +151 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.js +253 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.js +135 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.js +66 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.js +67 -0
- package/Transformers/Configurer.d.ts +39 -0
- package/Transformers/Configurer.js +415 -0
- package/Transformers/Constructor.d.ts +12 -0
- package/Transformers/Constructor.js +44 -0
- package/Transformers/Definitions.d.ts +102 -0
- package/Transformers/Definitions.js +626 -0
- package/Transformers/Loader.d.ts +45 -0
- package/Transformers/Loader.js +350 -0
- package/Transformers/Progress.d.ts +32 -0
- package/Transformers/Progress.js +429 -0
- package/Transformers/Reference.d.ts +37 -0
- package/Transformers/Reference.js +212 -0
- package/Transformers/SchemaGenerator.d.ts +102 -0
- package/Transformers/SchemaGenerator.js +564 -0
- package/Transformers/Serialiser.d.ts +31 -0
- package/Transformers/Serialiser.js +366 -0
- package/Transformers/Utils.d.ts +33 -0
- package/Transformers/Utils.js +287 -0
- package/Transformers/__tests__/Examples.d.ts +168 -0
- package/Transformers/__tests__/Examples.js +263 -0
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.js +457 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.js +339 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.js +256 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.js +167 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.js +400 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.js +441 -0
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.js +320 -0
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.js +534 -0
- package/__tests__/Replicable.Expressions.test.d.ts +1 -0
- package/__tests__/Replicable.Expressions.test.js +166 -0
- package/__tests__/Replicable.IDPool.test.d.ts +1 -0
- package/__tests__/Replicable.IDPool.test.js +11 -0
- package/__tests__/Replicable.ReplicableRegistry.test.d.ts +1 -0
- package/__tests__/Replicable.ReplicableRegistry.test.js +154 -0
- package/__tests__/Replicable.Serialisation.test.d.ts +1 -0
- package/__tests__/Replicable.Serialisation.test.js +283 -0
- package/package.json +14 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { ArrayMap, InstantOpenPromise, InstantPromise, SmartArray } from "@bikky/smart-collections";
|
|
2
|
+
import { describeObject, isPrimitiveType } from "../Constants/SerialisationTypes.js";
|
|
3
|
+
const DoneCallbackList = [];
|
|
4
|
+
const ReplCallbackList = [];
|
|
5
|
+
const PrimCallbackList = [];
|
|
6
|
+
const AliasCallbackList = [];
|
|
7
|
+
let finished = false;
|
|
8
|
+
class PendingProperty {
|
|
9
|
+
constructor(params, config) {
|
|
10
|
+
this.types = [];
|
|
11
|
+
this.loaded = false;
|
|
12
|
+
this.parameters = config;
|
|
13
|
+
this.ready = new InstantOpenPromise();
|
|
14
|
+
//If it's entirely primitive types, we can just complete it immediately.
|
|
15
|
+
if (params.every((e) => isPrimitiveType(e))) {
|
|
16
|
+
this.loaded = true;
|
|
17
|
+
this.ready.complete(this.parameters);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
for (let param of params) {
|
|
21
|
+
if (isPrimitiveType(param)) {
|
|
22
|
+
let promise = new InstantOpenPromise();
|
|
23
|
+
promise.complete([param]);
|
|
24
|
+
this.types.push(promise);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.types.push(Progress.ReadyForParameters(param));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
InstantPromise.all(this.types).then((types) => {
|
|
31
|
+
this.loaded = true;
|
|
32
|
+
this.ready.complete(types.flat());
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Keeps information for a class that hasn't loaded yet.
|
|
39
|
+
*/
|
|
40
|
+
class PendingClass {
|
|
41
|
+
constructor(name) {
|
|
42
|
+
this.addedProperties = [];
|
|
43
|
+
this.removedProperties = [];
|
|
44
|
+
this.addedFunctions = [];
|
|
45
|
+
this.loadingComplete = false;
|
|
46
|
+
this.name = name;
|
|
47
|
+
this.replReadyToSetupProperties = new InstantOpenPromise();
|
|
48
|
+
this.replReadyToSetupProperties.then(this.setRepl.bind(this));
|
|
49
|
+
this.replComplete = new InstantOpenPromise();
|
|
50
|
+
}
|
|
51
|
+
addProperty(config) {
|
|
52
|
+
if (this.loadingComplete) {
|
|
53
|
+
console.warn(`Property ${config[0]} is being added after the class has already loaded.`
|
|
54
|
+
+ ` If immediate this will be fine, but if this happens significantly delayed then some types`
|
|
55
|
+
+ ` or expressions may have loaded with incorrect information.`);
|
|
56
|
+
}
|
|
57
|
+
if (typeof config[2] === "undefined") {
|
|
58
|
+
throw new Error(`Property ${config[0]} is missing a type.`);
|
|
59
|
+
}
|
|
60
|
+
let params = [...config[2].type.flatMap((e) => e.type)];
|
|
61
|
+
if (config[2].customDataType) {
|
|
62
|
+
params.push(...config[2].customDataType.flatMap((e) => e.type));
|
|
63
|
+
}
|
|
64
|
+
let property = new PendingProperty(params, config);
|
|
65
|
+
property.ready.then(async () => {
|
|
66
|
+
if (finished && this.repl) {
|
|
67
|
+
this.repl.addProperty(...property.parameters);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.addedProperties.push(property);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
removeProperty(config) {
|
|
75
|
+
if (this.loadingComplete) {
|
|
76
|
+
console.warn(`Property ${config[0]} is being removed after the class has already loaded.`
|
|
77
|
+
+ ` If immediate this will be fine, but if this happens significantly delayed then some types`
|
|
78
|
+
+ ` or expressions may have loaded with incorrect information.`);
|
|
79
|
+
}
|
|
80
|
+
let params = [...config[2].type.map((e) => e.type)];
|
|
81
|
+
if (config[2].customDataType) {
|
|
82
|
+
params.push(...config[2].customDataType.map((e) => e.type));
|
|
83
|
+
}
|
|
84
|
+
let property = new PendingProperty(params, config);
|
|
85
|
+
property.ready.then(async () => {
|
|
86
|
+
if (this.repl) {
|
|
87
|
+
this.repl.removeProperty(...property.parameters);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.removedProperties.push(property);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
addFunction(config) {
|
|
95
|
+
if (this.loadingComplete) {
|
|
96
|
+
console.warn(`Property ${config[0]} is being added after the class has already loaded.`
|
|
97
|
+
+ ` If immediate this will be fine, but if this happens significantly delayed then some types`
|
|
98
|
+
+ ` or expressions may have loaded with incorrect information.`);
|
|
99
|
+
}
|
|
100
|
+
let params = [...config[2].flatMap((e) => e.type), ...config[3].flatMap((c) => c.flatMap((e) => e.type))];
|
|
101
|
+
let func = new PendingProperty(params, config);
|
|
102
|
+
func.ready.then(async () => {
|
|
103
|
+
if (this.repl) {
|
|
104
|
+
this.repl.addFunction(...func.parameters);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
this.addedFunctions.push(func);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
setRepl(repl) {
|
|
112
|
+
this.repl = repl;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export var Progress;
|
|
116
|
+
(function (Progress) {
|
|
117
|
+
/**
|
|
118
|
+
* The classes that are currently being constructed.
|
|
119
|
+
*/
|
|
120
|
+
const ConstructingClasses = new Map();
|
|
121
|
+
const FinishedClasses = new Map();
|
|
122
|
+
const PrimitiveTypes = new Map();
|
|
123
|
+
/**
|
|
124
|
+
* The classes that are currently being requested externally. May include aliases.
|
|
125
|
+
*/
|
|
126
|
+
const PendingTypes = new Map();
|
|
127
|
+
/**
|
|
128
|
+
* The types and their mapped values.
|
|
129
|
+
*/
|
|
130
|
+
const ValueMappings = new ArrayMap();
|
|
131
|
+
function SetupPrimitives() {
|
|
132
|
+
PrimitiveTypes.set(Number, Number);
|
|
133
|
+
PrimitiveTypes.set("number", Number);
|
|
134
|
+
PrimitiveTypes.set("Number", Number);
|
|
135
|
+
PrimitiveTypes.set(String, String);
|
|
136
|
+
PrimitiveTypes.set("string", String);
|
|
137
|
+
PrimitiveTypes.set("String", String);
|
|
138
|
+
PrimitiveTypes.set(Boolean, Boolean);
|
|
139
|
+
PrimitiveTypes.set("boolean", Boolean);
|
|
140
|
+
PrimitiveTypes.set("Boolean", Boolean);
|
|
141
|
+
PrimitiveTypes.set(null, null);
|
|
142
|
+
PrimitiveTypes.set("null", null);
|
|
143
|
+
PrimitiveTypes.set("Null", null);
|
|
144
|
+
PrimitiveTypes.set(undefined, undefined);
|
|
145
|
+
PrimitiveTypes.set("undefined", undefined);
|
|
146
|
+
PrimitiveTypes.set("Undefined", undefined);
|
|
147
|
+
}
|
|
148
|
+
SetupPrimitives();
|
|
149
|
+
/**
|
|
150
|
+
* The types being requested internally (by functions or properties) and the promises that are waiting for them.
|
|
151
|
+
*/
|
|
152
|
+
const AwaitedMappings = new ArrayMap();
|
|
153
|
+
const Aliases = new Set();
|
|
154
|
+
const DelayedClasses = new Map();
|
|
155
|
+
const StandinClasses = new Map();
|
|
156
|
+
OnBikDelayCompleted(function MapProgressClasses(old, upd) {
|
|
157
|
+
DelayedClasses.set(old, upd);
|
|
158
|
+
StandinClasses.set(upd, old);
|
|
159
|
+
});
|
|
160
|
+
const ReplInitialisationFunctions = [];
|
|
161
|
+
function RegisterReplInitialisationFunction(callback) {
|
|
162
|
+
ReplInitialisationFunctions.push(callback);
|
|
163
|
+
}
|
|
164
|
+
Progress.RegisterReplInitialisationFunction = RegisterReplInitialisationFunction;
|
|
165
|
+
/**
|
|
166
|
+
* This function is designed to be called after every file in the game has finished loading.
|
|
167
|
+
* It completes the setup of each class, it's properties and functions, since often their types
|
|
168
|
+
* reference other classes.
|
|
169
|
+
* It's done in stages so circular references are treated fine.
|
|
170
|
+
*/
|
|
171
|
+
function FinishedAllLoading() {
|
|
172
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
173
|
+
// First give all the available classes to ReplicableRegistry, as it'll need to be queried as everything
|
|
174
|
+
// instantiates itself.
|
|
175
|
+
for (let [alias, prim] of PrimitiveTypes.entries()) {
|
|
176
|
+
ValueMappings.push(alias, prim);
|
|
177
|
+
for (let callback of PrimCallbackList) {
|
|
178
|
+
callback(alias, prim);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (let pending of ConstructingClasses.values()) {
|
|
182
|
+
if (!pending.repl) {
|
|
183
|
+
console.warn(`Class ${pending instanceof PendingClass ? pending.name : describeObject(pending)} was never completed.`);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
let originalPending = StandinClasses.get(pending.repl.classConstructor);
|
|
187
|
+
for (let callback of ReplCallbackList) {
|
|
188
|
+
callback(pending.repl, originalPending);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Second mark all aliases as completed along with giving them the classes that they alias to.
|
|
192
|
+
for (let alias of Aliases) {
|
|
193
|
+
alias = (_a = DelayedClasses.get(alias)) !== null && _a !== void 0 ? _a : alias;
|
|
194
|
+
let types = ValueMappings.get(alias);
|
|
195
|
+
if (!types) {
|
|
196
|
+
console.warn(`Alias ${describeObject(alias)} was never completed.`);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
types = types.flatMap((e) => {
|
|
200
|
+
let delayed = DelayedClasses.get(e);
|
|
201
|
+
if (delayed) {
|
|
202
|
+
e = delayed;
|
|
203
|
+
}
|
|
204
|
+
if (isPrimitiveType(e)) {
|
|
205
|
+
return e;
|
|
206
|
+
}
|
|
207
|
+
//TODO: This check is probably unsafe, but it was done this way to avoid a circular import.
|
|
208
|
+
else if (typeof e == "object" && e.constructor.name == "ReplicableClass") {
|
|
209
|
+
return e;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
let repl = FinishedClasses.get(e);
|
|
213
|
+
if (!repl) {
|
|
214
|
+
console.error(`Unable to find class ${describeObject(e)} for alias ${describeObject(alias)}. Did you forget a @Struct or @Class decorator?`);
|
|
215
|
+
}
|
|
216
|
+
return repl;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
ValueMappings.set(alias, types);
|
|
220
|
+
let originalAlias = (_b = StandinClasses.get(alias)) !== null && _b !== void 0 ? _b : alias;
|
|
221
|
+
(_c = AwaitedMappings.get(alias)) === null || _c === void 0 ? void 0 : _c.forEach((e) => e.complete(types));
|
|
222
|
+
(_d = AwaitedMappings.get(originalAlias)) === null || _d === void 0 ? void 0 : _d.forEach((e) => e.complete(types));
|
|
223
|
+
for (let callback of AliasCallbackList) {
|
|
224
|
+
callback(alias, [...types]);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Third mark all classes that properties and functions are waiting for as "done" so the properties
|
|
228
|
+
// and functions instantiate correctly.
|
|
229
|
+
let values = new ArrayMap(ValueMappings);
|
|
230
|
+
for (let [id, value] of values.entries()) {
|
|
231
|
+
let updatedId = (_e = DelayedClasses.get(id)) !== null && _e !== void 0 ? _e : id;
|
|
232
|
+
let originalId = (_f = StandinClasses.get(id)) !== null && _f !== void 0 ? _f : id;
|
|
233
|
+
let updatedValue = new SmartArray(...value.flatMap((e) => { var _a; return (_a = DelayedClasses.get(e)) !== null && _a !== void 0 ? _a : e; }));
|
|
234
|
+
ValueMappings.set(updatedId, updatedValue);
|
|
235
|
+
ValueMappings.set(originalId, updatedValue);
|
|
236
|
+
if (!Aliases.has(updatedId)) {
|
|
237
|
+
for (let promise of (_g = AwaitedMappings.get(updatedId)) !== null && _g !== void 0 ? _g : []) {
|
|
238
|
+
promise.complete(updatedValue);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (!Aliases.has(originalId) && id != originalId) {
|
|
242
|
+
for (let promise of (_h = AwaitedMappings.get(originalId)) !== null && _h !== void 0 ? _h : []) {
|
|
243
|
+
promise.complete(updatedValue);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Fourth complete all properties and functions are waiting for as "done" so the properties
|
|
248
|
+
// and functions instantiate correctly.
|
|
249
|
+
// Properties depend on classes and aliases being done, so those are finished first.
|
|
250
|
+
for (let pending of ConstructingClasses.values()) {
|
|
251
|
+
if (!pending.repl) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
pending.repl.classConstructor = (_j = DelayedClasses.get(pending.repl.classConstructor)) !== null && _j !== void 0 ? _j : pending.repl.classConstructor;
|
|
255
|
+
for (let property of pending.addedProperties) {
|
|
256
|
+
if (!property.loaded) {
|
|
257
|
+
console.warn(`Property ${pending.repl.opts.dataTypeName}.${property.parameters[0]}'s requirements never loaded.`);
|
|
258
|
+
}
|
|
259
|
+
pending.repl.addProperty(...property.parameters);
|
|
260
|
+
}
|
|
261
|
+
for (let removed of pending.removedProperties) {
|
|
262
|
+
if (!removed.loaded) {
|
|
263
|
+
console.warn(`Property ${pending.repl.opts.dataTypeName}.${removed.parameters[0]}'s requirements never loaded.`);
|
|
264
|
+
}
|
|
265
|
+
pending.repl.removeProperty(...removed.parameters);
|
|
266
|
+
}
|
|
267
|
+
for (let func of pending.addedFunctions) {
|
|
268
|
+
if (!func.loaded) {
|
|
269
|
+
console.warn(`Function ${pending.repl.opts.dataTypeName}.${func.parameters[0]}'s requirements never loaded.`);
|
|
270
|
+
}
|
|
271
|
+
pending.repl.addFunction(...func.parameters);
|
|
272
|
+
}
|
|
273
|
+
pending.addedProperties.length = 0;
|
|
274
|
+
pending.removedProperties.length = 0;
|
|
275
|
+
pending.addedFunctions.length = 0;
|
|
276
|
+
pending.loadingComplete = true;
|
|
277
|
+
for (let callback of ReplInitialisationFunctions) {
|
|
278
|
+
callback(pending.repl);
|
|
279
|
+
}
|
|
280
|
+
pending.replComplete.complete(pending.repl);
|
|
281
|
+
}
|
|
282
|
+
// Fifth instantiate all the aliases now that the types that they alias to have finished loading.
|
|
283
|
+
// for (let id of Aliases) {
|
|
284
|
+
// let value = ValueMappings.get(id) ?? [];
|
|
285
|
+
// for (let promise of AwaitedMappings.get(id) ?? []) {
|
|
286
|
+
// promise.complete(value);
|
|
287
|
+
// }
|
|
288
|
+
// }
|
|
289
|
+
// Finally let anything that was waiting on class creation know that the class is ready.
|
|
290
|
+
for (let [id, value] of PendingTypes.entries()) {
|
|
291
|
+
let val = (_k = ValueMappings.get(id)) !== null && _k !== void 0 ? _k : [];
|
|
292
|
+
if (val.length === 0 && DelayedClasses.has(id)) {
|
|
293
|
+
val = (_l = ValueMappings.get(DelayedClasses.get(id))) !== null && _l !== void 0 ? _l : [];
|
|
294
|
+
}
|
|
295
|
+
if (val.length === 0) {
|
|
296
|
+
console.warn(`Type ${describeObject(id)} was requested but never registered.`);
|
|
297
|
+
}
|
|
298
|
+
value.complete(val);
|
|
299
|
+
}
|
|
300
|
+
finished = true;
|
|
301
|
+
for (let callback of DoneCallbackList) {
|
|
302
|
+
callback();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
Progress.FinishedAllLoading = FinishedAllLoading;
|
|
306
|
+
function ReadyForParameters(key) {
|
|
307
|
+
let promise = new InstantOpenPromise();
|
|
308
|
+
AwaitedMappings.push(key, promise);
|
|
309
|
+
return promise;
|
|
310
|
+
}
|
|
311
|
+
Progress.ReadyForParameters = ReadyForParameters;
|
|
312
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
313
|
+
function AwaitReplicableFor(type) {
|
|
314
|
+
let promise = PendingTypes.get(type);
|
|
315
|
+
if (!promise) {
|
|
316
|
+
PendingTypes.set(type, promise = new InstantOpenPromise);
|
|
317
|
+
}
|
|
318
|
+
return new InstantPromise((res) => promise.then(res));
|
|
319
|
+
}
|
|
320
|
+
Progress.AwaitReplicableFor = AwaitReplicableFor;
|
|
321
|
+
function FinishReplicableType(type) {
|
|
322
|
+
let pending = ConstructingClasses.get(type.classConstructor);
|
|
323
|
+
if (!pending) {
|
|
324
|
+
ConstructingClasses.set(type.classConstructor, pending = new PendingClass(type.opts.typescriptTypeName));
|
|
325
|
+
}
|
|
326
|
+
pending.replReadyToSetupProperties.complete(type);
|
|
327
|
+
ValueMappings.push(type.opts.typescriptTypeName, type);
|
|
328
|
+
ValueMappings.push(type.opts.dataTypeName, type);
|
|
329
|
+
ValueMappings.push(type.classConstructor, type);
|
|
330
|
+
FinishedClasses.set(type.classConstructor, type);
|
|
331
|
+
FinishedClasses.set(type.opts.typescriptTypeName, type);
|
|
332
|
+
FinishedClasses.set(type.opts.dataTypeName, type);
|
|
333
|
+
let oldID = StandinClasses.get(type.classConstructor);
|
|
334
|
+
if (oldID) {
|
|
335
|
+
ValueMappings.push(oldID, type);
|
|
336
|
+
FinishedClasses.set(oldID, type);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
Progress.FinishReplicableType = FinishReplicableType;
|
|
340
|
+
/**
|
|
341
|
+
* A type collection is an object or string whose value is only used to look up other values.
|
|
342
|
+
*/
|
|
343
|
+
function RegisterAlias(type, value) {
|
|
344
|
+
if (finished) {
|
|
345
|
+
console.warn(`Alias ${describeObject(type)} is being added after the game`
|
|
346
|
+
+ ` has already finished loading, this could cause significant issues.`);
|
|
347
|
+
}
|
|
348
|
+
Aliases.add(type);
|
|
349
|
+
if (typeof type === "object" && "name" in type) {
|
|
350
|
+
Aliases.add(type.name);
|
|
351
|
+
}
|
|
352
|
+
ValueMappings.push(type, value);
|
|
353
|
+
if (typeof type === "object" && "name" in type) {
|
|
354
|
+
ValueMappings.push(type.name, value);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
Progress.RegisterAlias = RegisterAlias;
|
|
358
|
+
function RegisterPropertyLoad(classConstructor, property) {
|
|
359
|
+
if (finished) {
|
|
360
|
+
console.warn(`Property ${describeObject(classConstructor)}.${property[0]} is being added after the game`
|
|
361
|
+
+ ` has already finished loading, this could cause significant issues.`);
|
|
362
|
+
}
|
|
363
|
+
let pending = ConstructingClasses.get(classConstructor);
|
|
364
|
+
if (!pending) {
|
|
365
|
+
ConstructingClasses.set(classConstructor, pending = new PendingClass(describeObject(classConstructor)));
|
|
366
|
+
}
|
|
367
|
+
pending.addProperty(property);
|
|
368
|
+
}
|
|
369
|
+
Progress.RegisterPropertyLoad = RegisterPropertyLoad;
|
|
370
|
+
function RegisterPropertyRemove(classConstructor, property) {
|
|
371
|
+
if (finished) {
|
|
372
|
+
console.warn(`Property ${describeObject(classConstructor)}.${property[0]} is being removed after the game`
|
|
373
|
+
+ ` has already finished loading, this could cause significant issues.`);
|
|
374
|
+
}
|
|
375
|
+
let pending = ConstructingClasses.get(classConstructor);
|
|
376
|
+
if (!pending) {
|
|
377
|
+
ConstructingClasses.set(classConstructor, pending = new PendingClass(describeObject(classConstructor)));
|
|
378
|
+
}
|
|
379
|
+
pending.removeProperty(property);
|
|
380
|
+
}
|
|
381
|
+
Progress.RegisterPropertyRemove = RegisterPropertyRemove;
|
|
382
|
+
function RegisterFunctionAdd(classConstructor, property) {
|
|
383
|
+
if (finished) {
|
|
384
|
+
console.warn(`Function ${describeObject(classConstructor)}.${property[0]} is being added after the game`
|
|
385
|
+
+ ` has already finished loading, this could cause significant issues.`);
|
|
386
|
+
}
|
|
387
|
+
let pending = ConstructingClasses.get(classConstructor);
|
|
388
|
+
if (!pending) {
|
|
389
|
+
ConstructingClasses.set(classConstructor, pending = new PendingClass(describeObject(classConstructor)));
|
|
390
|
+
}
|
|
391
|
+
pending.addFunction(property);
|
|
392
|
+
}
|
|
393
|
+
Progress.RegisterFunctionAdd = RegisterFunctionAdd;
|
|
394
|
+
function OnLoadFinished(callback) {
|
|
395
|
+
if (finished) {
|
|
396
|
+
callback();
|
|
397
|
+
}
|
|
398
|
+
DoneCallbackList.push(callback);
|
|
399
|
+
}
|
|
400
|
+
Progress.OnLoadFinished = OnLoadFinished;
|
|
401
|
+
function OnAnyReplicableReady(callback) {
|
|
402
|
+
ReplCallbackList.push(callback);
|
|
403
|
+
}
|
|
404
|
+
Progress.OnAnyReplicableReady = OnAnyReplicableReady;
|
|
405
|
+
function OnAnyPrimitiveReady(callback) {
|
|
406
|
+
PrimCallbackList.push(callback);
|
|
407
|
+
}
|
|
408
|
+
Progress.OnAnyPrimitiveReady = OnAnyPrimitiveReady;
|
|
409
|
+
function OnAnyAliasReady(callback) {
|
|
410
|
+
AliasCallbackList.push(callback);
|
|
411
|
+
}
|
|
412
|
+
Progress.OnAnyAliasReady = OnAnyAliasReady;
|
|
413
|
+
/**
|
|
414
|
+
* This function is only for testing!
|
|
415
|
+
*/
|
|
416
|
+
function ClearCaches() {
|
|
417
|
+
if (typeof TestingMode === "boolean" && TestingMode) {
|
|
418
|
+
finished = false;
|
|
419
|
+
Aliases.clear();
|
|
420
|
+
ConstructingClasses.clear();
|
|
421
|
+
PendingTypes.clear();
|
|
422
|
+
ValueMappings.clear();
|
|
423
|
+
AwaitedMappings.clear();
|
|
424
|
+
FinishedClasses.clear();
|
|
425
|
+
SetupPrimitives();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
Progress.ClearCaches = ClearCaches;
|
|
429
|
+
})(Progress || (Progress = {}));
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Primitive } from "../Constants/SerialisationTypes.js";
|
|
2
|
+
import type { Replicable } from "../Replicatable.js";
|
|
3
|
+
import type { ReplicableClass } from "../Tracking/Class.js";
|
|
4
|
+
declare const ptr: unique symbol;
|
|
5
|
+
declare const registry: unique symbol;
|
|
6
|
+
declare const alive: unique symbol;
|
|
7
|
+
declare const ref: unique symbol;
|
|
8
|
+
export declare class Pointer<T extends object> {
|
|
9
|
+
[ptr]: WeakRef<T> | undefined;
|
|
10
|
+
[alive]: boolean;
|
|
11
|
+
[registry]: FinalizationRegistry<T>;
|
|
12
|
+
[ref]: Replicable.Reference | null;
|
|
13
|
+
constructor(item?: T | null);
|
|
14
|
+
get val(): T;
|
|
15
|
+
get valOrNull(): T | null;
|
|
16
|
+
set val(value: T | null);
|
|
17
|
+
get ref(): Replicable.Reference | null;
|
|
18
|
+
set ref(refa: Replicable.Reference | null);
|
|
19
|
+
}
|
|
20
|
+
export declare namespace Referencer {
|
|
21
|
+
type Reference<R extends any[] = any[]> = [type: string, ...vals: R];
|
|
22
|
+
function SetDataNameLookupFunction(lookupFunc: (dataName: string) => ReplicableClass | undefined): void;
|
|
23
|
+
function SetAliasLookupFunction(lookupFunc: (dataName: string) => (ReplicableClass | Primitive)[] | undefined): void;
|
|
24
|
+
function UnregisterReference(type: ReplicableClass, pointer: Pointer<any>): void;
|
|
25
|
+
function RegisterReference(type: ReplicableClass, pointer: Pointer<any>): void;
|
|
26
|
+
/**
|
|
27
|
+
* Update all references of an object of this type to a new reference. This is good if the server and the client
|
|
28
|
+
* spawn entities with different IDs, this function helps to map the IDs sent from the client to the actual
|
|
29
|
+
* legitimate entity on the server.
|
|
30
|
+
*/
|
|
31
|
+
function UpdateReferences(from: Replicable.Reference, to: Replicable.Reference): void;
|
|
32
|
+
function CanReference<T extends object>(item: T): boolean;
|
|
33
|
+
function IsReference(ref: any): ref is Referencer.Reference;
|
|
34
|
+
function Reference<T extends object>(data: T, type?: ReplicableClass): Referencer.Reference;
|
|
35
|
+
function Dereference<T extends object>(ref: Referencer.Reference, overrideType?: ReplicableClass): T;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
var _a, _b;
|
|
2
|
+
import { isPrimitiveType, isPrimitiveValue, TypeSymbol } from "../Constants/SerialisationTypes.js";
|
|
3
|
+
import { WeakArray } from "@bikky/smart-collections";
|
|
4
|
+
const ptr = Symbol("Pointer");
|
|
5
|
+
const registry = Symbol("Registry");
|
|
6
|
+
const alive = Symbol("Alive");
|
|
7
|
+
const ref = Symbol("Reference");
|
|
8
|
+
let getReplicableClassByName = null;
|
|
9
|
+
let getReplicableClassByAlias = null;
|
|
10
|
+
export class Pointer {
|
|
11
|
+
constructor(item) {
|
|
12
|
+
this[_a] = undefined;
|
|
13
|
+
this[_b] = false;
|
|
14
|
+
this[registry] = new FinalizationRegistry(() => {
|
|
15
|
+
this[alive] = false;
|
|
16
|
+
});
|
|
17
|
+
if (typeof item !== "undefined" && item !== null) {
|
|
18
|
+
//Use the setter so it sets the ref, value, and registry correctly.
|
|
19
|
+
this.val = item;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this[ref] = null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// isValid() {
|
|
26
|
+
// return !!this.#ref;
|
|
27
|
+
// }
|
|
28
|
+
get val() {
|
|
29
|
+
if (!this[alive]) {
|
|
30
|
+
if (!this[ref])
|
|
31
|
+
throw new Error("Cannot get value before value is set!");
|
|
32
|
+
let val = Referencer.Dereference(this[ref]);
|
|
33
|
+
if (val) {
|
|
34
|
+
this.val = val;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
throw new Error(`Attempt to access invalid value.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return this[ptr].deref() || null;
|
|
41
|
+
}
|
|
42
|
+
get valOrNull() {
|
|
43
|
+
if (!this[alive]) {
|
|
44
|
+
if (!this[ref])
|
|
45
|
+
return null;
|
|
46
|
+
let val = Referencer.Dereference(this[ref]);
|
|
47
|
+
if (typeof val !== "undefined" && val !== null) {
|
|
48
|
+
this.val = val;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return this[ptr].deref() || null;
|
|
55
|
+
}
|
|
56
|
+
set val(value) {
|
|
57
|
+
if (this[alive]) {
|
|
58
|
+
let existing = this[ptr].deref();
|
|
59
|
+
Referencer.UnregisterReference(existing[TypeSymbol], this);
|
|
60
|
+
this[registry].unregister(existing);
|
|
61
|
+
}
|
|
62
|
+
if (value === null) {
|
|
63
|
+
this[ptr] = undefined;
|
|
64
|
+
this[alive] = false;
|
|
65
|
+
this[ref] = null;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this[ptr] = new WeakRef(value);
|
|
69
|
+
this[alive] = true;
|
|
70
|
+
this[registry].register(this[ptr], value);
|
|
71
|
+
this[ref] = Referencer.Reference(value);
|
|
72
|
+
Referencer.RegisterReference(value[TypeSymbol], this);
|
|
73
|
+
}
|
|
74
|
+
get ref() {
|
|
75
|
+
if (this[ref] === null)
|
|
76
|
+
return null;
|
|
77
|
+
if (!this[ref])
|
|
78
|
+
throw new Error("Cannot get reference before reference is set!");
|
|
79
|
+
return this[ref];
|
|
80
|
+
}
|
|
81
|
+
set ref(refa) {
|
|
82
|
+
if (this[alive]) {
|
|
83
|
+
let existing = this[ptr].deref();
|
|
84
|
+
Referencer.UnregisterReference(existing[TypeSymbol], this);
|
|
85
|
+
this[registry].unregister(existing);
|
|
86
|
+
this[alive] = false;
|
|
87
|
+
}
|
|
88
|
+
if (refa === null) {
|
|
89
|
+
this[ptr] = undefined;
|
|
90
|
+
this[alive] = false;
|
|
91
|
+
this[ref] = null;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this[ref] = refa;
|
|
95
|
+
if (!getReplicableClassByName) {
|
|
96
|
+
throw new Error("Cannot set reference without a lookup function.");
|
|
97
|
+
}
|
|
98
|
+
Referencer.RegisterReference(getReplicableClassByName(refa[0]), this);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
_a = ptr, _b = alive;
|
|
102
|
+
export var Referencer;
|
|
103
|
+
(function (Referencer) {
|
|
104
|
+
var refs = new Map();
|
|
105
|
+
function SetDataNameLookupFunction(lookupFunc) {
|
|
106
|
+
getReplicableClassByName = lookupFunc;
|
|
107
|
+
}
|
|
108
|
+
Referencer.SetDataNameLookupFunction = SetDataNameLookupFunction;
|
|
109
|
+
function SetAliasLookupFunction(lookupFunc) {
|
|
110
|
+
getReplicableClassByAlias = lookupFunc;
|
|
111
|
+
}
|
|
112
|
+
Referencer.SetAliasLookupFunction = SetAliasLookupFunction;
|
|
113
|
+
function UnregisterReference(type, pointer) {
|
|
114
|
+
let set = refs.get(type);
|
|
115
|
+
if (!set)
|
|
116
|
+
refs.set(type, set = new WeakArray());
|
|
117
|
+
set.removeAll(pointer);
|
|
118
|
+
}
|
|
119
|
+
Referencer.UnregisterReference = UnregisterReference;
|
|
120
|
+
function RegisterReference(type, pointer) {
|
|
121
|
+
let set = refs.get(type);
|
|
122
|
+
if (!set)
|
|
123
|
+
refs.set(type, set = new WeakArray());
|
|
124
|
+
if (!set.includes(pointer))
|
|
125
|
+
set.push(pointer);
|
|
126
|
+
}
|
|
127
|
+
Referencer.RegisterReference = RegisterReference;
|
|
128
|
+
/**
|
|
129
|
+
* Update all references of an object of this type to a new reference. This is good if the server and the client
|
|
130
|
+
* spawn entities with different IDs, this function helps to map the IDs sent from the client to the actual
|
|
131
|
+
* legitimate entity on the server.
|
|
132
|
+
*/
|
|
133
|
+
function UpdateReferences(from, to) {
|
|
134
|
+
if (!getReplicableClassByName) {
|
|
135
|
+
throw new Error("Cannot update references without a lookup function.");
|
|
136
|
+
}
|
|
137
|
+
let type = getReplicableClassByName(from[0]);
|
|
138
|
+
if (!type)
|
|
139
|
+
throw new Error(`Cannot find type ${from[0]}.`);
|
|
140
|
+
let fromStr = JSON.stringify(from);
|
|
141
|
+
let allPtrs = refs.get(type);
|
|
142
|
+
if (!allPtrs)
|
|
143
|
+
throw new Error(`Cannot find pointers for type ${from[0]}.`);
|
|
144
|
+
for (let ptr of allPtrs) {
|
|
145
|
+
if (JSON.stringify(ptr.ref) == fromStr) {
|
|
146
|
+
ptr.ref = to;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
Referencer.UpdateReferences = UpdateReferences;
|
|
151
|
+
function CanReference(item) {
|
|
152
|
+
if (isPrimitiveType(item))
|
|
153
|
+
return true;
|
|
154
|
+
let type = item[TypeSymbol];
|
|
155
|
+
if (!type)
|
|
156
|
+
return false;
|
|
157
|
+
return "Reference" in type.classConstructor && "Dereference" in type.classConstructor;
|
|
158
|
+
}
|
|
159
|
+
Referencer.CanReference = CanReference;
|
|
160
|
+
function IsReference(ref) {
|
|
161
|
+
if (!getReplicableClassByName) {
|
|
162
|
+
throw new Error("Cannot update references without a lookup function.");
|
|
163
|
+
}
|
|
164
|
+
if (!Array.isArray(ref))
|
|
165
|
+
return false;
|
|
166
|
+
let type = getReplicableClassByName(ref[0]);
|
|
167
|
+
if (!type)
|
|
168
|
+
return false;
|
|
169
|
+
return !!type && "Reference" in type.classConstructor && "Dereference" in type.classConstructor;
|
|
170
|
+
}
|
|
171
|
+
Referencer.IsReference = IsReference;
|
|
172
|
+
function Reference(data, type) {
|
|
173
|
+
if (type && "Reference" in type.classConstructor)
|
|
174
|
+
return [type.opts.typescriptTypeName, ...type.classConstructor.Reference(data)];
|
|
175
|
+
if (isPrimitiveValue(data))
|
|
176
|
+
return ["Primitive", data];
|
|
177
|
+
let typeDef = data[TypeSymbol];
|
|
178
|
+
if (!typeDef)
|
|
179
|
+
throw new Error(`Cannot find type for ${data}.`);
|
|
180
|
+
let classConstructor = typeDef.classConstructor;
|
|
181
|
+
if (!("Reference" in classConstructor)) {
|
|
182
|
+
throw new Error(`Tried to create a reference for a ${typeDef.opts.typescriptTypeName} which doesn't support references.`);
|
|
183
|
+
}
|
|
184
|
+
return [typeDef.opts.dataTypeName, ...classConstructor.Reference(data)];
|
|
185
|
+
}
|
|
186
|
+
Referencer.Reference = Reference;
|
|
187
|
+
function Dereference(ref, overrideType) {
|
|
188
|
+
if (!Array.isArray(ref)) {
|
|
189
|
+
return ref;
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
if (!getReplicableClassByAlias) {
|
|
193
|
+
throw new Error("Cannot update references without a lookup function.");
|
|
194
|
+
}
|
|
195
|
+
if (ref[0] === "Primitive")
|
|
196
|
+
return ref[1];
|
|
197
|
+
if (ref[0] === "JSON")
|
|
198
|
+
return JSON.parse(ref[1]);
|
|
199
|
+
let types = overrideType ? [overrideType] : getReplicableClassByAlias(ref[0]);
|
|
200
|
+
let type = types === null || types === void 0 ? void 0 : types[0];
|
|
201
|
+
if (!type) {
|
|
202
|
+
throw new Error(`Tried to dereference ${ref[0]} which is an unregistered/non-replicable type.`);
|
|
203
|
+
}
|
|
204
|
+
let classConstructor = type.classConstructor;
|
|
205
|
+
if (!("Dereference" in classConstructor)) {
|
|
206
|
+
throw new Error(`Tried to dereference a ${type.opts.typescriptTypeName} which doesn't support dereferencing.`);
|
|
207
|
+
}
|
|
208
|
+
return classConstructor.Dereference(ref.slice(1));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
Referencer.Dereference = Dereference;
|
|
212
|
+
})(Referencer || (Referencer = {}));
|