@nymphjs/client 1.0.0-beta.7 → 1.0.0-beta.71
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/CHANGELOG.md +304 -0
- package/README.md +4 -4
- package/asyncitertest.js +53 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/lib/Entity.d.ts +112 -8
- package/lib/Entity.js +158 -76
- package/lib/Entity.js.map +1 -1
- package/lib/Entity.types.d.ts +144 -9
- package/lib/EntityWeakCache.js +3 -2
- package/lib/EntityWeakCache.js.map +1 -1
- package/lib/HttpRequester.d.ts +44 -8
- package/lib/HttpRequester.js +236 -21
- package/lib/HttpRequester.js.map +1 -1
- package/lib/Nymph.d.ts +43 -11
- package/lib/Nymph.js +102 -19
- package/lib/Nymph.js.map +1 -1
- package/lib/Nymph.types.d.ts +48 -1
- package/lib/PubSub.d.ts +15 -9
- package/lib/PubSub.js +148 -87
- package/lib/PubSub.js.map +1 -1
- package/lib/PubSub.types.d.ts +6 -1
- package/lib/entityRefresh.js +16 -0
- package/lib/entityRefresh.js.map +1 -1
- package/lib/utils.js +11 -0
- package/lib/utils.js.map +1 -1
- package/package.json +17 -14
- package/src/Entity.ts +163 -103
- package/src/Entity.types.ts +10 -46
- package/src/EntityWeakCache.ts +7 -5
- package/src/HttpRequester.ts +302 -29
- package/src/Nymph.ts +140 -67
- package/src/Nymph.types.ts +15 -1
- package/src/PubSub.ts +205 -132
- package/src/PubSub.types.ts +8 -3
- package/src/entityRefresh.ts +5 -5
- package/tsconfig.json +1 -1
- package/typedoc.json +4 -0
package/lib/utils.js
CHANGED
|
@@ -17,9 +17,11 @@ function entityConstructorsToClassNames(item) {
|
|
|
17
17
|
if (typeof item === 'function' &&
|
|
18
18
|
item.prototype instanceof Entity_1.default &&
|
|
19
19
|
typeof item.class === 'string') {
|
|
20
|
+
// Convert entity classes to strings.
|
|
20
21
|
return item.class;
|
|
21
22
|
}
|
|
22
23
|
else if (Array.isArray(item)) {
|
|
24
|
+
// Recurse into lower arrays.
|
|
23
25
|
return item.map((entry) => entityConstructorsToClassNames(entry));
|
|
24
26
|
}
|
|
25
27
|
else if (item instanceof Object) {
|
|
@@ -29,14 +31,17 @@ function entityConstructorsToClassNames(item) {
|
|
|
29
31
|
}
|
|
30
32
|
return newObj;
|
|
31
33
|
}
|
|
34
|
+
// Not an entity or array, just return it.
|
|
32
35
|
return item;
|
|
33
36
|
}
|
|
34
37
|
exports.entityConstructorsToClassNames = entityConstructorsToClassNames;
|
|
35
38
|
function entitiesToReferences(item) {
|
|
36
39
|
if (item instanceof Entity_1.default && typeof item.$toReference === 'function') {
|
|
40
|
+
// Convert entities to references.
|
|
37
41
|
return item.$toReference();
|
|
38
42
|
}
|
|
39
43
|
else if (Array.isArray(item)) {
|
|
44
|
+
// Recurse into lower arrays.
|
|
40
45
|
return item.map((entry) => entitiesToReferences(entry));
|
|
41
46
|
}
|
|
42
47
|
else if (item instanceof Object) {
|
|
@@ -46,11 +51,13 @@ function entitiesToReferences(item) {
|
|
|
46
51
|
}
|
|
47
52
|
return newObj;
|
|
48
53
|
}
|
|
54
|
+
// Not an entity or array, just return it.
|
|
49
55
|
return item;
|
|
50
56
|
}
|
|
51
57
|
exports.entitiesToReferences = entitiesToReferences;
|
|
52
58
|
function referencesToEntities(item, nymph) {
|
|
53
59
|
if (Array.isArray(item)) {
|
|
60
|
+
// Check if it's a reference.
|
|
54
61
|
if (item[0] === 'nymph_entity_reference') {
|
|
55
62
|
try {
|
|
56
63
|
const EntityClass = nymph.getEntityClass(item[2]);
|
|
@@ -61,6 +68,7 @@ function referencesToEntities(item, nymph) {
|
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
else {
|
|
71
|
+
// Recurse into lower arrays.
|
|
64
72
|
return item.map((item) => referencesToEntities(item, nymph));
|
|
65
73
|
}
|
|
66
74
|
}
|
|
@@ -69,10 +77,13 @@ function referencesToEntities(item, nymph) {
|
|
|
69
77
|
item[key] = referencesToEntities(value, nymph);
|
|
70
78
|
}
|
|
71
79
|
}
|
|
80
|
+
// Not an array, just return it.
|
|
72
81
|
return item;
|
|
73
82
|
}
|
|
74
83
|
exports.referencesToEntities = referencesToEntities;
|
|
75
84
|
function sortObj(obj) {
|
|
85
|
+
// adapted from
|
|
86
|
+
// http://am.aurlien.net/post/1221493460/sorting-javascript-objects
|
|
76
87
|
const tempArray = Object.keys(obj);
|
|
77
88
|
tempArray.sort();
|
|
78
89
|
for (let i = 0; i < tempArray.length; i++) {
|
package/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;AAEA,sDAA8B;AAE9B,SAAgB,aAAa,CAAC,KAAe;IAC3C,MAAM,GAAG,GAA0B,EAAE,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nymphjs/client",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0-beta.71",
|
|
4
|
+
"description": "Nymph.js - Client",
|
|
5
5
|
"browser": "dist/index.js",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"build:js": "webpack",
|
|
20
20
|
"watch:ts": "tsc --watch",
|
|
21
21
|
"watch:js": "webpack --watch",
|
|
22
|
-
"
|
|
22
|
+
"prepublish": "npm run clean && npm run build",
|
|
23
23
|
"test": "jest --detectOpenHandles",
|
|
24
24
|
"test:watch": "jest --watch"
|
|
25
25
|
},
|
|
@@ -36,16 +36,19 @@
|
|
|
36
36
|
},
|
|
37
37
|
"license": "Apache-2.0",
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@tsconfig/recommended": "^1.0.
|
|
40
|
-
"@types/jest": "^29.
|
|
41
|
-
"@types/lodash": "^4.14.
|
|
42
|
-
"jest": "^29.
|
|
43
|
-
"
|
|
44
|
-
"ts-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"webpack": "^5.
|
|
48
|
-
"webpack-cli": "^5.0.1"
|
|
39
|
+
"@tsconfig/recommended": "^1.0.3",
|
|
40
|
+
"@types/jest": "^29.5.12",
|
|
41
|
+
"@types/lodash": "^4.14.202",
|
|
42
|
+
"jest": "^29.7.0",
|
|
43
|
+
"ts-jest": "^29.1.2",
|
|
44
|
+
"ts-loader": "^9.5.1",
|
|
45
|
+
"typescript": "^5.3.3",
|
|
46
|
+
"webpack": "^5.90.3",
|
|
47
|
+
"webpack-cli": "^5.1.4"
|
|
49
48
|
},
|
|
50
|
-
"
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"fetch-event-source-hperrin": "^3.0.0",
|
|
51
|
+
"lodash": "^4.17.21"
|
|
52
|
+
},
|
|
53
|
+
"gitHead": "c6e7c987c990dfcdb9f2a176954b69bf5bbbefc7"
|
|
51
54
|
}
|
package/src/Entity.ts
CHANGED
|
@@ -16,9 +16,12 @@ import {
|
|
|
16
16
|
sortObj,
|
|
17
17
|
} from './utils';
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
export type EntityDataType<T> = T extends Entity<infer DataType>
|
|
20
|
+
? DataType
|
|
21
|
+
: never;
|
|
22
|
+
|
|
23
|
+
export type EntityInstanceType<T extends EntityConstructor> =
|
|
24
|
+
T extends new () => infer E ? E & EntityDataType<E> : never;
|
|
22
25
|
|
|
23
26
|
export default class Entity<T extends EntityData = EntityData>
|
|
24
27
|
implements EntityInterface
|
|
@@ -84,15 +87,14 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
84
87
|
*/
|
|
85
88
|
protected $sleepingReference: EntityReference | null = null;
|
|
86
89
|
/**
|
|
87
|
-
* A promise that resolved when the entity's data is
|
|
90
|
+
* A promise that resolved when the entity's data is wake.
|
|
88
91
|
*/
|
|
89
|
-
protected $
|
|
92
|
+
protected $wakePromise: Promise<Entity<T>> | null = null;
|
|
90
93
|
|
|
91
94
|
/**
|
|
92
|
-
*
|
|
93
|
-
* @param guid The ID of the entity to load, undefined for a new entity.
|
|
95
|
+
* Initialize an entity.
|
|
94
96
|
*/
|
|
95
|
-
public constructor(
|
|
97
|
+
public constructor(..._rest: any[]) {
|
|
96
98
|
this.$nymph = (this.constructor as EntityConstructor).nymph;
|
|
97
99
|
this.$dataHandler = {
|
|
98
100
|
has: (data: EntityData, name: string) => {
|
|
@@ -129,7 +131,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
129
131
|
deleteProperty: (data: EntityData, name: string) => {
|
|
130
132
|
if (typeof name !== 'symbol' && this.$isASleepingReference) {
|
|
131
133
|
console.error(
|
|
132
|
-
`Tried to delete data on a sleeping reference: ${name}
|
|
134
|
+
`Tried to delete data on a sleeping reference: ${name}`,
|
|
133
135
|
);
|
|
134
136
|
return false;
|
|
135
137
|
}
|
|
@@ -143,11 +145,11 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
143
145
|
defineProperty: (
|
|
144
146
|
data: EntityData,
|
|
145
147
|
name: string,
|
|
146
|
-
descriptor: PropertyDescriptor
|
|
148
|
+
descriptor: PropertyDescriptor,
|
|
147
149
|
) => {
|
|
148
150
|
if (typeof name !== 'symbol' && this.$isASleepingReference) {
|
|
149
151
|
console.error(
|
|
150
|
-
`Tried to define data on a sleeping reference: ${name}
|
|
152
|
+
`Tried to define data on a sleeping reference: ${name}`,
|
|
151
153
|
);
|
|
152
154
|
return false;
|
|
153
155
|
}
|
|
@@ -161,7 +163,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
161
163
|
getOwnPropertyDescriptor: (data: EntityData, name: string) => {
|
|
162
164
|
if (typeof name !== 'symbol' && this.$isASleepingReference) {
|
|
163
165
|
console.error(
|
|
164
|
-
`Tried to get property descriptor on a sleeping reference: ${name}
|
|
166
|
+
`Tried to get property descriptor on a sleeping reference: ${name}`,
|
|
165
167
|
);
|
|
166
168
|
return undefined;
|
|
167
169
|
}
|
|
@@ -179,17 +181,6 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
179
181
|
this.$dataStore = {} as T;
|
|
180
182
|
this.$data = new Proxy(this.$dataStore, this.$dataHandler);
|
|
181
183
|
|
|
182
|
-
if (guid != null) {
|
|
183
|
-
this.guid = guid;
|
|
184
|
-
this.$isASleepingReference = true;
|
|
185
|
-
this.$sleepingReference = [
|
|
186
|
-
'nymph_entity_reference',
|
|
187
|
-
this.guid,
|
|
188
|
-
(this.constructor as EntityConstructor).class,
|
|
189
|
-
];
|
|
190
|
-
this.$ready();
|
|
191
|
-
}
|
|
192
|
-
|
|
193
184
|
return new Proxy(this, {
|
|
194
185
|
has(entity: Entity, name: string) {
|
|
195
186
|
if (
|
|
@@ -245,7 +236,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
245
236
|
defineProperty(
|
|
246
237
|
entity: Entity,
|
|
247
238
|
name: string,
|
|
248
|
-
descriptor: PropertyDescriptor
|
|
239
|
+
descriptor: PropertyDescriptor,
|
|
249
240
|
) {
|
|
250
241
|
if (
|
|
251
242
|
typeof name !== 'string' ||
|
|
@@ -273,57 +264,130 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
273
264
|
|
|
274
265
|
ownKeys(entity: Entity) {
|
|
275
266
|
return Object.getOwnPropertyNames(entity).concat(
|
|
276
|
-
Object.getOwnPropertyNames(entity.$data)
|
|
267
|
+
Object.getOwnPropertyNames(entity.$data),
|
|
277
268
|
);
|
|
278
269
|
},
|
|
279
270
|
}) as Entity<T>;
|
|
280
271
|
}
|
|
281
272
|
|
|
282
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Create or retrieve a new entity instance.
|
|
275
|
+
*
|
|
276
|
+
* Note that this will always return an entity, even if the GUID is not found.
|
|
277
|
+
*
|
|
278
|
+
* @param guid An optional GUID to retrieve.
|
|
279
|
+
*/
|
|
280
|
+
public static async factory<E extends Entity>(
|
|
281
|
+
this: {
|
|
282
|
+
new (): E;
|
|
283
|
+
},
|
|
284
|
+
guid?: string,
|
|
285
|
+
): Promise<E & EntityDataType<E>> {
|
|
283
286
|
const cacheEntity = (
|
|
284
|
-
guid
|
|
287
|
+
guid
|
|
288
|
+
? (this as unknown as EntityConstructor).nymph.getEntityFromCache(
|
|
289
|
+
this as unknown as EntityConstructor,
|
|
290
|
+
guid,
|
|
291
|
+
)
|
|
292
|
+
: null
|
|
285
293
|
) as Entity | null;
|
|
286
|
-
|
|
294
|
+
if (cacheEntity) {
|
|
295
|
+
return cacheEntity as E & EntityDataType<E>;
|
|
296
|
+
}
|
|
297
|
+
const entity = new this();
|
|
287
298
|
if (guid != null) {
|
|
288
|
-
|
|
299
|
+
entity.guid = guid;
|
|
300
|
+
entity.$isASleepingReference = true;
|
|
301
|
+
entity.$sleepingReference = [
|
|
302
|
+
'nymph_entity_reference',
|
|
303
|
+
guid,
|
|
304
|
+
(this as unknown as EntityConstructor).class,
|
|
305
|
+
];
|
|
306
|
+
await entity.$wake();
|
|
289
307
|
}
|
|
290
|
-
return entity
|
|
308
|
+
return entity as E & EntityDataType<E>;
|
|
291
309
|
}
|
|
292
310
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Create a new entity instance.
|
|
313
|
+
*/
|
|
314
|
+
public static factorySync<E extends Entity>(this: {
|
|
315
|
+
new (): E;
|
|
316
|
+
}): E & EntityDataType<E> {
|
|
317
|
+
return new this() as E & EntityDataType<E>;
|
|
298
318
|
}
|
|
299
319
|
|
|
300
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Create a new sleeping reference instance.
|
|
322
|
+
*
|
|
323
|
+
* Sleeping references won't retrieve their data from the server until they
|
|
324
|
+
* are readied with `$wake()` or a parent's `$wakeAll()`.
|
|
325
|
+
*
|
|
326
|
+
* @param reference The Nymph Entity Reference to use to wake.
|
|
327
|
+
* @returns The new instance.
|
|
328
|
+
*/
|
|
329
|
+
public static factoryReference<E extends Entity>(
|
|
330
|
+
this: {
|
|
331
|
+
new (): E;
|
|
332
|
+
},
|
|
333
|
+
reference: EntityReference,
|
|
334
|
+
): E & EntityDataType<E> {
|
|
301
335
|
const cacheEntity = (
|
|
302
|
-
reference[1]
|
|
336
|
+
reference[1]
|
|
337
|
+
? (this as unknown as EntityConstructor).nymph.getEntityFromCache(
|
|
338
|
+
this as unknown as EntityConstructor,
|
|
339
|
+
reference[1],
|
|
340
|
+
)
|
|
341
|
+
: null
|
|
303
342
|
) as Entity | null;
|
|
304
343
|
|
|
305
344
|
const entity = cacheEntity || new this();
|
|
306
345
|
if (!cacheEntity) {
|
|
307
346
|
entity.$referenceSleep(reference);
|
|
308
347
|
}
|
|
309
|
-
return entity
|
|
348
|
+
return entity as E & EntityDataType<E>;
|
|
310
349
|
}
|
|
311
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Call a static method on the server version of this entity.
|
|
353
|
+
*
|
|
354
|
+
* @param method The name of the method.
|
|
355
|
+
* @param params The parameters to call the method with.
|
|
356
|
+
* @returns The value that the method on the server returned.
|
|
357
|
+
*/
|
|
312
358
|
public static async serverCallStatic(method: string, params: Iterable<any>) {
|
|
313
359
|
const data = await this.nymph.serverCallStatic(
|
|
314
360
|
this.class,
|
|
315
361
|
method,
|
|
316
362
|
// Turn the params into a real array, in case an arguments object was
|
|
317
363
|
// passed.
|
|
318
|
-
Array.prototype.slice.call(params)
|
|
364
|
+
Array.prototype.slice.call(params),
|
|
319
365
|
);
|
|
320
366
|
return data.return;
|
|
321
367
|
}
|
|
322
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Call a static iterator method on the server version of this entity.
|
|
371
|
+
*
|
|
372
|
+
* @param method The name of the method.
|
|
373
|
+
* @param params The parameters to call the method with.
|
|
374
|
+
* @returns An iterator that iterates over values that the method on the server yields.
|
|
375
|
+
*/
|
|
376
|
+
public static async serverCallStaticIterator(
|
|
377
|
+
method: string,
|
|
378
|
+
params: Iterable<any>,
|
|
379
|
+
) {
|
|
380
|
+
return await this.nymph.serverCallStaticIterator(
|
|
381
|
+
this.class,
|
|
382
|
+
method,
|
|
383
|
+
// Turn the params into a real array, in case an arguments object was
|
|
384
|
+
// passed.
|
|
385
|
+
Array.prototype.slice.call(params),
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
323
389
|
public toJSON() {
|
|
324
|
-
|
|
325
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
326
|
-
}
|
|
390
|
+
this.$check();
|
|
327
391
|
const obj: EntityJson = {
|
|
328
392
|
class: (this.constructor as any).class as string,
|
|
329
393
|
guid: this.guid,
|
|
@@ -359,7 +423,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
359
423
|
})
|
|
360
424
|
.reduce(
|
|
361
425
|
(obj, { key, value }) => Object.assign(obj, { [key]: value }),
|
|
362
|
-
{}
|
|
426
|
+
{},
|
|
363
427
|
) as T;
|
|
364
428
|
this.$data = new Proxy(this.$dataStore, this.$dataHandler);
|
|
365
429
|
|
|
@@ -369,9 +433,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
369
433
|
}
|
|
370
434
|
|
|
371
435
|
public $addTag(...tags: string[]) {
|
|
372
|
-
|
|
373
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
374
|
-
}
|
|
436
|
+
this.$check();
|
|
375
437
|
|
|
376
438
|
if (tags.length < 1) {
|
|
377
439
|
return;
|
|
@@ -380,9 +442,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
380
442
|
}
|
|
381
443
|
|
|
382
444
|
public $arraySearch(array: any[], strict = false) {
|
|
383
|
-
|
|
384
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
385
|
-
}
|
|
445
|
+
this.$check();
|
|
386
446
|
|
|
387
447
|
if (!Array.isArray(array)) {
|
|
388
448
|
return -1;
|
|
@@ -397,9 +457,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
397
457
|
}
|
|
398
458
|
|
|
399
459
|
public async $delete(): Promise<boolean> {
|
|
400
|
-
|
|
401
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
402
|
-
}
|
|
460
|
+
this.$check();
|
|
403
461
|
|
|
404
462
|
const guid = this.guid;
|
|
405
463
|
|
|
@@ -407,9 +465,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
407
465
|
}
|
|
408
466
|
|
|
409
467
|
public $equals(object: any) {
|
|
410
|
-
|
|
411
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
412
|
-
}
|
|
468
|
+
this.$check();
|
|
413
469
|
|
|
414
470
|
if (!(object instanceof Entity)) {
|
|
415
471
|
return false;
|
|
@@ -419,9 +475,6 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
419
475
|
return false;
|
|
420
476
|
}
|
|
421
477
|
}
|
|
422
|
-
if (object.constructor !== this.constructor) {
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
478
|
if (object.cdate !== this.cdate) {
|
|
426
479
|
return false;
|
|
427
480
|
}
|
|
@@ -438,12 +491,10 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
438
491
|
}
|
|
439
492
|
|
|
440
493
|
public $getPatch(): EntityPatch {
|
|
441
|
-
|
|
442
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
443
|
-
}
|
|
494
|
+
this.$check();
|
|
444
495
|
if (this.guid == null) {
|
|
445
496
|
throw new InvalidStateError(
|
|
446
|
-
"You can't make a patch from an unsaved entity."
|
|
497
|
+
"You can't make a patch from an unsaved entity.",
|
|
447
498
|
);
|
|
448
499
|
}
|
|
449
500
|
const patch: EntityPatch = {
|
|
@@ -451,10 +502,10 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
451
502
|
mdate: this.mdate,
|
|
452
503
|
class: (this.constructor as EntityConstructor).class,
|
|
453
504
|
addTags: this.tags.filter(
|
|
454
|
-
(tag) => this.$originalTags.indexOf(tag) === -1
|
|
505
|
+
(tag) => this.$originalTags.indexOf(tag) === -1,
|
|
455
506
|
),
|
|
456
507
|
removeTags: this.$originalTags.filter(
|
|
457
|
-
(tag) => this.tags.indexOf(tag) === -1
|
|
508
|
+
(tag) => this.tags.indexOf(tag) === -1,
|
|
458
509
|
),
|
|
459
510
|
unset: [],
|
|
460
511
|
set: {},
|
|
@@ -474,9 +525,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
474
525
|
}
|
|
475
526
|
|
|
476
527
|
public $hasTag(...tags: string[]) {
|
|
477
|
-
|
|
478
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
479
|
-
}
|
|
528
|
+
this.$check();
|
|
480
529
|
|
|
481
530
|
if (!tags.length) {
|
|
482
531
|
return false;
|
|
@@ -494,9 +543,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
494
543
|
}
|
|
495
544
|
|
|
496
545
|
public $is(object: any) {
|
|
497
|
-
|
|
498
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
499
|
-
}
|
|
546
|
+
this.$check();
|
|
500
547
|
|
|
501
548
|
if (!(object instanceof Entity)) {
|
|
502
549
|
return false;
|
|
@@ -517,9 +564,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
517
564
|
}
|
|
518
565
|
|
|
519
566
|
public async $patch() {
|
|
520
|
-
|
|
521
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
522
|
-
}
|
|
567
|
+
this.$check();
|
|
523
568
|
|
|
524
569
|
const mdate = this.mdate;
|
|
525
570
|
|
|
@@ -527,21 +572,42 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
527
572
|
return mdate !== this.mdate;
|
|
528
573
|
}
|
|
529
574
|
|
|
530
|
-
|
|
575
|
+
/**
|
|
576
|
+
* Check if this is a sleeping reference and throw an error if so.
|
|
577
|
+
*/
|
|
578
|
+
protected $check() {
|
|
579
|
+
if (this.$isASleepingReference || this.$sleepingReference != null) {
|
|
580
|
+
throw new EntityIsSleepingReferenceError(
|
|
581
|
+
'This entity is in a sleeping reference state. You must use .$wake() to wake it.',
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Check if this is a sleeping reference.
|
|
588
|
+
*/
|
|
589
|
+
public $asleep() {
|
|
590
|
+
return this.$isASleepingReference || this.$sleepingReference != null;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Wake from a sleeping reference.
|
|
595
|
+
*/
|
|
596
|
+
public $wake() {
|
|
531
597
|
if (!this.$isASleepingReference) {
|
|
532
|
-
this.$
|
|
598
|
+
this.$wakePromise = null;
|
|
533
599
|
return Promise.resolve(this);
|
|
534
600
|
}
|
|
535
601
|
if (this.$sleepingReference?.[1] == null) {
|
|
536
602
|
throw new InvalidStateError(
|
|
537
|
-
'Tried to
|
|
603
|
+
'Tried to wake a sleeping reference with no GUID.',
|
|
538
604
|
);
|
|
539
605
|
}
|
|
540
|
-
if (!this.$
|
|
541
|
-
this.$
|
|
606
|
+
if (!this.$wakePromise) {
|
|
607
|
+
this.$wakePromise = this.$nymph
|
|
542
608
|
.getEntityData(
|
|
543
609
|
{ class: this.constructor as EntityConstructor },
|
|
544
|
-
{ type: '&', guid: this.$sleepingReference[1] }
|
|
610
|
+
{ type: '&', guid: this.$sleepingReference[1] },
|
|
545
611
|
)
|
|
546
612
|
.then((data) => {
|
|
547
613
|
if (data == null) {
|
|
@@ -551,16 +617,16 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
551
617
|
return this.$init(data);
|
|
552
618
|
})
|
|
553
619
|
.finally(() => {
|
|
554
|
-
this.$
|
|
620
|
+
this.$wakePromise = null;
|
|
555
621
|
});
|
|
556
622
|
}
|
|
557
|
-
return this.$
|
|
623
|
+
return this.$wakePromise;
|
|
558
624
|
}
|
|
559
625
|
|
|
560
|
-
public $
|
|
626
|
+
public $wakeAll(level?: number) {
|
|
561
627
|
return new Promise((resolve, reject) => {
|
|
562
|
-
// Run this once this entity is
|
|
563
|
-
const
|
|
628
|
+
// Run this once this entity is awake.
|
|
629
|
+
const wakeProps = () => {
|
|
564
630
|
let newLevel;
|
|
565
631
|
// If level is undefined, keep going forever, otherwise, stop once we've
|
|
566
632
|
// gone deep enough.
|
|
@@ -572,17 +638,17 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
572
638
|
return;
|
|
573
639
|
}
|
|
574
640
|
const promises = [];
|
|
575
|
-
// Go through data looking for entities to
|
|
641
|
+
// Go through data looking for entities to wake.
|
|
576
642
|
for (let [key, value] of Object.entries(this.$data)) {
|
|
577
643
|
if (value instanceof Entity && value.$isASleepingReference) {
|
|
578
|
-
promises.push(value.$
|
|
644
|
+
promises.push(value.$wakeAll(newLevel));
|
|
579
645
|
} else if (Array.isArray(value)) {
|
|
580
646
|
for (let i = 0; i < value.length; i++) {
|
|
581
647
|
if (
|
|
582
648
|
value[i] instanceof Entity &&
|
|
583
649
|
value[i].$isASleepingReference
|
|
584
650
|
) {
|
|
585
|
-
promises.push(value[i].$
|
|
651
|
+
promises.push(value[i].$wakeAll(newLevel));
|
|
586
652
|
}
|
|
587
653
|
}
|
|
588
654
|
}
|
|
@@ -590,7 +656,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
590
656
|
if (promises.length) {
|
|
591
657
|
Promise.all(promises).then(
|
|
592
658
|
() => resolve(this),
|
|
593
|
-
(errObj) => reject(errObj)
|
|
659
|
+
(errObj) => reject(errObj),
|
|
594
660
|
);
|
|
595
661
|
} else {
|
|
596
662
|
resolve(this);
|
|
@@ -598,9 +664,9 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
598
664
|
};
|
|
599
665
|
|
|
600
666
|
if (this.$isASleepingReference) {
|
|
601
|
-
this.$
|
|
667
|
+
this.$wake().then(wakeProps, (errObj) => reject(errObj));
|
|
602
668
|
} else {
|
|
603
|
-
|
|
669
|
+
wakeProps();
|
|
604
670
|
}
|
|
605
671
|
}) as Promise<Entity<T>>;
|
|
606
672
|
}
|
|
@@ -613,7 +679,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
613
679
|
|
|
614
680
|
public async $refresh() {
|
|
615
681
|
if (this.$isASleepingReference) {
|
|
616
|
-
await this.$
|
|
682
|
+
await this.$wake();
|
|
617
683
|
return true;
|
|
618
684
|
}
|
|
619
685
|
|
|
@@ -627,24 +693,20 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
627
693
|
{
|
|
628
694
|
type: '&',
|
|
629
695
|
guid: this.guid,
|
|
630
|
-
}
|
|
696
|
+
},
|
|
631
697
|
);
|
|
632
698
|
this.$init(data);
|
|
633
699
|
return this.guid == null ? 0 : true;
|
|
634
700
|
}
|
|
635
701
|
|
|
636
702
|
public $removeTag(...tags: string[]) {
|
|
637
|
-
|
|
638
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
639
|
-
}
|
|
703
|
+
this.$check();
|
|
640
704
|
|
|
641
705
|
this.tags = difference(this.tags, tags);
|
|
642
706
|
}
|
|
643
707
|
|
|
644
708
|
public async $save() {
|
|
645
|
-
|
|
646
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
647
|
-
}
|
|
709
|
+
this.$check();
|
|
648
710
|
|
|
649
711
|
await this.$nymph.saveEntity(this);
|
|
650
712
|
return !!this.guid;
|
|
@@ -653,11 +715,9 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
653
715
|
public async $serverCall(
|
|
654
716
|
method: string,
|
|
655
717
|
params: Iterable<any>,
|
|
656
|
-
stateless = false
|
|
718
|
+
stateless = false,
|
|
657
719
|
) {
|
|
658
|
-
|
|
659
|
-
throw new EntityIsSleepingReferenceError(sleepErr);
|
|
660
|
-
}
|
|
720
|
+
this.$check();
|
|
661
721
|
// Turn the params into a real array, in case an arguments object was
|
|
662
722
|
// passed.
|
|
663
723
|
const paramArray = Array.prototype.slice.call(params);
|
|
@@ -665,7 +725,7 @@ export default class Entity<T extends EntityData = EntityData>
|
|
|
665
725
|
this,
|
|
666
726
|
method,
|
|
667
727
|
paramArray,
|
|
668
|
-
stateless
|
|
728
|
+
stateless,
|
|
669
729
|
);
|
|
670
730
|
if (!stateless && data.entity) {
|
|
671
731
|
this.$init(data.entity);
|