@nymphjs/client 1.0.0-beta.132 → 1.0.0-beta.134
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 +13 -0
- package/dist/Entity.d.ts +8 -8
- package/dist/Entity.js +60 -28
- package/dist/Entity.js.map +1 -1
- package/dist/Entity.types.d.ts +4 -6
- package/dist/EntityWeakCache.d.ts +1 -1
- package/dist/EntityWeakCache.js +1 -1
- package/dist/EntityWeakCache.js.map +1 -1
- package/dist/HttpRequester.d.ts +1 -1
- package/dist/HttpRequester.js +1 -1
- package/dist/HttpRequester.js.map +1 -1
- package/dist/Nymph.d.ts +11 -5
- package/dist/Nymph.js +92 -49
- package/dist/Nymph.js.map +1 -1
- package/dist/Nymph.types.d.ts +21 -2
- package/dist/Nymph.types.js.map +1 -1
- package/dist/PubSub.d.ts +2 -2
- package/dist/PubSub.js +10 -7
- package/dist/PubSub.js.map +1 -1
- package/dist/QueryWeakCache.d.ts +6 -0
- package/dist/QueryWeakCache.js +31 -0
- package/dist/QueryWeakCache.js.map +1 -0
- package/package.json +2 -2
- package/src/Entity.ts +88 -54
- package/src/Entity.types.ts +5 -6
- package/src/EntityWeakCache.ts +1 -1
- package/src/HttpRequester.ts +1 -1
- package/src/Nymph.ts +99 -49
- package/src/Nymph.types.ts +21 -2
- package/src/PubSub.ts +18 -12
- package/src/QueryWeakCache.ts +35 -0
package/src/Entity.ts
CHANGED
|
@@ -24,9 +24,7 @@ export type EntityDataType<T> =
|
|
|
24
24
|
export type EntityInstanceType<T extends EntityConstructor> =
|
|
25
25
|
T extends new () => infer E ? E & EntityDataType<E> : never;
|
|
26
26
|
|
|
27
|
-
export default class Entity<
|
|
28
|
-
T extends EntityData = EntityData,
|
|
29
|
-
> implements EntityInterface {
|
|
27
|
+
export default class Entity<T extends {} = {}> implements EntityInterface {
|
|
30
28
|
/**
|
|
31
29
|
* The instance of Nymph to use for queries.
|
|
32
30
|
*/
|
|
@@ -174,7 +172,7 @@ export default class Entity<
|
|
|
174
172
|
protected $proxy() {
|
|
175
173
|
if (this.$existingProxy == null) {
|
|
176
174
|
this.$existingProxy = new Proxy(this, {
|
|
177
|
-
has: (entity:
|
|
175
|
+
has: (entity: Record<string, any>, name: string) => {
|
|
178
176
|
if (
|
|
179
177
|
typeof name !== 'string' ||
|
|
180
178
|
name in entity ||
|
|
@@ -187,7 +185,7 @@ export default class Entity<
|
|
|
187
185
|
return name in entity.$data;
|
|
188
186
|
},
|
|
189
187
|
|
|
190
|
-
get: (entity:
|
|
188
|
+
get: (entity: Record<string, any>, name: string) => {
|
|
191
189
|
if (
|
|
192
190
|
typeof name !== 'string' ||
|
|
193
191
|
name in entity ||
|
|
@@ -206,7 +204,7 @@ export default class Entity<
|
|
|
206
204
|
return undefined;
|
|
207
205
|
},
|
|
208
206
|
|
|
209
|
-
set: (entity:
|
|
207
|
+
set: (entity: Record<string, any>, name: string, value: any) => {
|
|
210
208
|
if (
|
|
211
209
|
typeof name !== 'string' ||
|
|
212
210
|
name in entity ||
|
|
@@ -223,7 +221,7 @@ export default class Entity<
|
|
|
223
221
|
return true;
|
|
224
222
|
},
|
|
225
223
|
|
|
226
|
-
deleteProperty: (entity:
|
|
224
|
+
deleteProperty: (entity: Record<string, any>, name: string) => {
|
|
227
225
|
if (name in entity) {
|
|
228
226
|
return delete (entity as any)[name];
|
|
229
227
|
} else if (name in entity.$data) {
|
|
@@ -233,12 +231,12 @@ export default class Entity<
|
|
|
233
231
|
return true;
|
|
234
232
|
},
|
|
235
233
|
|
|
236
|
-
getPrototypeOf: (entity:
|
|
234
|
+
getPrototypeOf: (entity: Record<string, any>) => {
|
|
237
235
|
return entity.constructor.prototype;
|
|
238
236
|
},
|
|
239
237
|
|
|
240
238
|
defineProperty: (
|
|
241
|
-
entity:
|
|
239
|
+
entity: Record<string, any>,
|
|
242
240
|
name: string,
|
|
243
241
|
descriptor: PropertyDescriptor,
|
|
244
242
|
) => {
|
|
@@ -258,7 +256,10 @@ export default class Entity<
|
|
|
258
256
|
return true;
|
|
259
257
|
},
|
|
260
258
|
|
|
261
|
-
getOwnPropertyDescriptor: (
|
|
259
|
+
getOwnPropertyDescriptor: (
|
|
260
|
+
entity: Record<string, any>,
|
|
261
|
+
name: string,
|
|
262
|
+
) => {
|
|
262
263
|
if (
|
|
263
264
|
typeof name !== 'string' ||
|
|
264
265
|
name in entity ||
|
|
@@ -274,7 +275,7 @@ export default class Entity<
|
|
|
274
275
|
}
|
|
275
276
|
},
|
|
276
277
|
|
|
277
|
-
ownKeys: (entity:
|
|
278
|
+
ownKeys: (entity: Record<string, any>) => {
|
|
278
279
|
this.$check();
|
|
279
280
|
return Object.getOwnPropertyNames(entity).concat(
|
|
280
281
|
Object.getOwnPropertyNames(entity.$data),
|
|
@@ -297,7 +298,7 @@ export default class Entity<
|
|
|
297
298
|
new (): E;
|
|
298
299
|
},
|
|
299
300
|
guid?: string,
|
|
300
|
-
): Promise<E
|
|
301
|
+
): Promise<E> {
|
|
301
302
|
const cacheEntity = (
|
|
302
303
|
guid
|
|
303
304
|
? (this as unknown as EntityConstructor).nymph.getEntityFromCache(
|
|
@@ -307,7 +308,7 @@ export default class Entity<
|
|
|
307
308
|
: null
|
|
308
309
|
) as Entity | null;
|
|
309
310
|
if (cacheEntity) {
|
|
310
|
-
return cacheEntity as E
|
|
311
|
+
return cacheEntity as E;
|
|
311
312
|
}
|
|
312
313
|
const entity = new this();
|
|
313
314
|
if (guid != null) {
|
|
@@ -320,16 +321,14 @@ export default class Entity<
|
|
|
320
321
|
];
|
|
321
322
|
await entity.$wake();
|
|
322
323
|
}
|
|
323
|
-
return entity as E
|
|
324
|
+
return entity as E;
|
|
324
325
|
}
|
|
325
326
|
|
|
326
327
|
/**
|
|
327
328
|
* Create a new entity instance.
|
|
328
329
|
*/
|
|
329
|
-
public static factorySync<E extends Entity>(this: {
|
|
330
|
-
new ()
|
|
331
|
-
}): E & EntityDataType<E> {
|
|
332
|
-
return new this() as E & EntityDataType<E>;
|
|
330
|
+
public static factorySync<E extends Entity>(this: { new (): E }): E {
|
|
331
|
+
return new this() as E;
|
|
333
332
|
}
|
|
334
333
|
|
|
335
334
|
/**
|
|
@@ -346,7 +345,7 @@ export default class Entity<
|
|
|
346
345
|
new (): E;
|
|
347
346
|
},
|
|
348
347
|
reference: EntityReference,
|
|
349
|
-
): E
|
|
348
|
+
): E {
|
|
350
349
|
const cacheEntity = (
|
|
351
350
|
reference[1]
|
|
352
351
|
? (this as unknown as EntityConstructor).nymph.getEntityFromCache(
|
|
@@ -360,7 +359,7 @@ export default class Entity<
|
|
|
360
359
|
if (!cacheEntity) {
|
|
361
360
|
entity.$referenceSleep(reference);
|
|
362
361
|
}
|
|
363
|
-
return entity as E
|
|
362
|
+
return entity as E;
|
|
364
363
|
}
|
|
365
364
|
|
|
366
365
|
/**
|
|
@@ -402,7 +401,9 @@ export default class Entity<
|
|
|
402
401
|
}
|
|
403
402
|
|
|
404
403
|
public toJSON() {
|
|
405
|
-
this.$
|
|
404
|
+
if (this.$isASleepingReference && this.$sleepingReference) {
|
|
405
|
+
return this.$sleepingReference;
|
|
406
|
+
}
|
|
406
407
|
const obj: EntityJson = {
|
|
407
408
|
class: entityConstructorsToClassNames(this.constructor),
|
|
408
409
|
guid: this.guid,
|
|
@@ -419,9 +420,9 @@ export default class Entity<
|
|
|
419
420
|
return obj;
|
|
420
421
|
}
|
|
421
422
|
|
|
422
|
-
public $init(entityJson: EntityJson | null) {
|
|
423
|
+
public $init(entityJson: EntityJson | null, isFromSave: boolean) {
|
|
423
424
|
if (entityJson == null) {
|
|
424
|
-
return this
|
|
425
|
+
return this;
|
|
425
426
|
}
|
|
426
427
|
|
|
427
428
|
this.$isASleepingReference = false;
|
|
@@ -430,29 +431,54 @@ export default class Entity<
|
|
|
430
431
|
this.guid = entityJson.guid;
|
|
431
432
|
this.cdate = entityJson.cdate;
|
|
432
433
|
this.mdate = entityJson.mdate;
|
|
433
|
-
|
|
434
|
+
if (
|
|
435
|
+
// The instance is new.
|
|
436
|
+
!this.$originalTags.length ||
|
|
437
|
+
// The data is coming from a save.
|
|
438
|
+
isFromSave ||
|
|
439
|
+
// The tags haven't been modified.
|
|
440
|
+
JSON.stringify([...this.tags].sort()) ===
|
|
441
|
+
JSON.stringify([...this.$originalTags].sort())
|
|
442
|
+
) {
|
|
443
|
+
this.tags = entityJson.tags;
|
|
444
|
+
}
|
|
434
445
|
this.$originalTags = entityJson.tags.slice(0);
|
|
435
|
-
|
|
436
|
-
this.$
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
446
|
+
|
|
447
|
+
if (!this.$nymph.weakCache || !this.$nymph.weakCacheKeepDirtyData) {
|
|
448
|
+
// Clear dirty data tracker.
|
|
449
|
+
for (let name in this.$dirty) {
|
|
450
|
+
delete this.$dirty[name];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
for (let name in this.$dataStore) {
|
|
455
|
+
if (!this.$dirty[name]) {
|
|
456
|
+
if (name in entityJson.data) {
|
|
457
|
+
this.$dataStore[name] = classNamesToEntityConstructors(
|
|
442
458
|
this.$nymph,
|
|
443
|
-
referencesToEntities(
|
|
444
|
-
)
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
459
|
+
referencesToEntities(entityJson.data[name], this.$nymph),
|
|
460
|
+
);
|
|
461
|
+
this.$dirty[name] = false;
|
|
462
|
+
} else {
|
|
463
|
+
delete this.$dataStore[name];
|
|
464
|
+
delete this.$dirty[name];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
for (let name in entityJson.data as T) {
|
|
470
|
+
if (!(name in this.$dataStore)) {
|
|
471
|
+
this.$dataStore[name] = classNamesToEntityConstructors(
|
|
472
|
+
this.$nymph,
|
|
473
|
+
referencesToEntities(entityJson.data[name], this.$nymph),
|
|
474
|
+
);
|
|
475
|
+
this.$dirty[name] = false;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
452
478
|
|
|
453
479
|
this.$nymph.setEntityToCache(this.constructor as EntityConstructor, this);
|
|
454
480
|
|
|
455
|
-
return this
|
|
481
|
+
return this;
|
|
456
482
|
}
|
|
457
483
|
|
|
458
484
|
public $addTag(...tags: string[]) {
|
|
@@ -507,10 +533,14 @@ export default class Entity<
|
|
|
507
533
|
return false;
|
|
508
534
|
}
|
|
509
535
|
const obData = sortObj(object.toJSON());
|
|
510
|
-
obData
|
|
536
|
+
if ('tags' in obData) {
|
|
537
|
+
obData.tags?.sort();
|
|
538
|
+
}
|
|
511
539
|
// obData.data = sortObj(obData.data);
|
|
512
540
|
const myData = sortObj(this.toJSON());
|
|
513
|
-
myData
|
|
541
|
+
if ('tags' in myData) {
|
|
542
|
+
myData.tags?.sort();
|
|
543
|
+
}
|
|
514
544
|
// myData.data = sortObj(myData.data);
|
|
515
545
|
return isEqual(obData, myData);
|
|
516
546
|
}
|
|
@@ -540,7 +570,7 @@ export default class Entity<
|
|
|
540
570
|
if (dirty) {
|
|
541
571
|
if (key in this.$data) {
|
|
542
572
|
patch.set[key] = entityConstructorsToClassNames(
|
|
543
|
-
entitiesToReferences(this.$data[key]),
|
|
573
|
+
entitiesToReferences((this.$data as EntityData)[key]),
|
|
544
574
|
);
|
|
545
575
|
} else {
|
|
546
576
|
patch.unset.push(key);
|
|
@@ -585,10 +615,14 @@ export default class Entity<
|
|
|
585
615
|
return false;
|
|
586
616
|
} else {
|
|
587
617
|
const obData = sortObj(object.toJSON());
|
|
588
|
-
obData
|
|
618
|
+
if ('tags' in obData) {
|
|
619
|
+
obData.tags?.sort();
|
|
620
|
+
}
|
|
589
621
|
// obData.data = sortObj(obData.data);
|
|
590
622
|
const myData = sortObj(this.toJSON());
|
|
591
|
-
myData
|
|
623
|
+
if ('tags' in myData) {
|
|
624
|
+
myData.tags?.sort();
|
|
625
|
+
}
|
|
592
626
|
// myData.data = sortObj(myData.data);
|
|
593
627
|
return isEqual(obData, myData);
|
|
594
628
|
}
|
|
@@ -629,7 +663,7 @@ export default class Entity<
|
|
|
629
663
|
public $wake() {
|
|
630
664
|
if (!this.$asleep()) {
|
|
631
665
|
this.$wakePromise = null;
|
|
632
|
-
return Promise.resolve(this
|
|
666
|
+
return Promise.resolve(this);
|
|
633
667
|
}
|
|
634
668
|
if (this.$sleepingReference?.[1] == null) {
|
|
635
669
|
throw new InvalidStateError(
|
|
@@ -647,7 +681,7 @@ export default class Entity<
|
|
|
647
681
|
const errObj = { data, textStatus: 'No data returned.' };
|
|
648
682
|
return Promise.reject(errObj);
|
|
649
683
|
}
|
|
650
|
-
return this.$init(data);
|
|
684
|
+
return this.$init(data, false);
|
|
651
685
|
})
|
|
652
686
|
.finally(() => {
|
|
653
687
|
this.$wakePromise = null;
|
|
@@ -667,7 +701,7 @@ export default class Entity<
|
|
|
667
701
|
newLevel = level - 1;
|
|
668
702
|
}
|
|
669
703
|
if (newLevel !== undefined && newLevel < 0) {
|
|
670
|
-
resolve(this
|
|
704
|
+
resolve(this);
|
|
671
705
|
return;
|
|
672
706
|
}
|
|
673
707
|
const promises: Promise<any>[] = [];
|
|
@@ -701,11 +735,11 @@ export default class Entity<
|
|
|
701
735
|
walkData(this.$data);
|
|
702
736
|
if (promises.length) {
|
|
703
737
|
Promise.all(promises).then(
|
|
704
|
-
() => resolve(this
|
|
738
|
+
() => resolve(this),
|
|
705
739
|
(errObj) => reject(errObj),
|
|
706
740
|
);
|
|
707
741
|
} else {
|
|
708
|
-
resolve(this
|
|
742
|
+
resolve(this);
|
|
709
743
|
}
|
|
710
744
|
};
|
|
711
745
|
|
|
@@ -744,7 +778,7 @@ export default class Entity<
|
|
|
744
778
|
if (data == null) {
|
|
745
779
|
throw new Error("The entity's data could not be refreshed.");
|
|
746
780
|
}
|
|
747
|
-
this.$init(data);
|
|
781
|
+
this.$init(data, false);
|
|
748
782
|
return true;
|
|
749
783
|
}
|
|
750
784
|
|
|
@@ -779,7 +813,7 @@ export default class Entity<
|
|
|
779
813
|
stateless,
|
|
780
814
|
);
|
|
781
815
|
if (!stateless && data.entity) {
|
|
782
|
-
this.$init(data.entity);
|
|
816
|
+
this.$init(data.entity, false);
|
|
783
817
|
}
|
|
784
818
|
return data.return;
|
|
785
819
|
}
|
|
@@ -790,7 +824,7 @@ export default class Entity<
|
|
|
790
824
|
}
|
|
791
825
|
|
|
792
826
|
if (this.guid == null) {
|
|
793
|
-
return this
|
|
827
|
+
return this;
|
|
794
828
|
}
|
|
795
829
|
return [
|
|
796
830
|
'nymph_entity_reference',
|
package/src/Entity.types.ts
CHANGED
|
@@ -97,17 +97,13 @@ export interface DataObjectInterface {
|
|
|
97
97
|
* @returns False if the data has not been saved, true on success. An error is
|
|
98
98
|
* thrown on failure.
|
|
99
99
|
*/
|
|
100
|
-
$refresh(): Promise<boolean
|
|
100
|
+
$refresh(): Promise<boolean>;
|
|
101
101
|
/**
|
|
102
102
|
* Save the object to storage.
|
|
103
103
|
*
|
|
104
104
|
* An error is thrown on failure.
|
|
105
105
|
*/
|
|
106
106
|
$save(): Promise<void>;
|
|
107
|
-
/**
|
|
108
|
-
* The object's data.
|
|
109
|
-
*/
|
|
110
|
-
[k: string]: any;
|
|
111
107
|
}
|
|
112
108
|
|
|
113
109
|
/**
|
|
@@ -176,8 +172,9 @@ export interface EntityInterface extends DataObjectInterface {
|
|
|
176
172
|
* Initialize this entity from a JSON representation.
|
|
177
173
|
*
|
|
178
174
|
* @param entityJson The entity JSON.
|
|
175
|
+
* @param isFromSave True if the entity is being initialized with data just saved to the server.
|
|
179
176
|
*/
|
|
180
|
-
$init(entityJson: EntityJson | null): EntityInterface;
|
|
177
|
+
$init(entityJson: EntityJson | null, isFromSave: boolean): EntityInterface;
|
|
181
178
|
/**
|
|
182
179
|
* Retrieve this entity's data from the server.
|
|
183
180
|
*
|
|
@@ -223,6 +220,8 @@ export interface EntityInterface extends DataObjectInterface {
|
|
|
223
220
|
* @returns A Nymph Entity Reference array as an unsaved entity.
|
|
224
221
|
*/
|
|
225
222
|
$toReference(): EntityReference | EntityInterface;
|
|
223
|
+
|
|
224
|
+
toJSON(): EntityReference | EntityJson;
|
|
226
225
|
}
|
|
227
226
|
|
|
228
227
|
export type EntityConstructor<
|
package/src/EntityWeakCache.ts
CHANGED
package/src/HttpRequester.ts
CHANGED
|
@@ -32,7 +32,7 @@ export interface AbortableAsyncIterator<
|
|
|
32
32
|
abortController: AbortController;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export
|
|
35
|
+
export class HttpRequester {
|
|
36
36
|
private fetch: WindowOrWorkerGlobalScope['fetch'];
|
|
37
37
|
private requestCallbacks: HttpRequesterRequestCallback[] = [];
|
|
38
38
|
private responseCallbacks: HttpRequesterResponseCallback[] = [];
|
package/src/Nymph.ts
CHANGED
|
@@ -6,9 +6,10 @@ import type {
|
|
|
6
6
|
ServerCallResponse,
|
|
7
7
|
ServerCallStaticResponse,
|
|
8
8
|
} from './Entity.types.js';
|
|
9
|
-
import EntityWeakCache from './EntityWeakCache.js';
|
|
9
|
+
import { EntityWeakCache } from './EntityWeakCache.js';
|
|
10
|
+
import { QueryWeakCache } from './QueryWeakCache.js';
|
|
10
11
|
import type { AbortableAsyncIterator } from './HttpRequester.js';
|
|
11
|
-
import HttpRequester,
|
|
12
|
+
import { HttpRequester, ClientError } from './HttpRequester.js';
|
|
12
13
|
import type {
|
|
13
14
|
EventType,
|
|
14
15
|
NymphOptions,
|
|
@@ -45,7 +46,8 @@ export default class Nymph {
|
|
|
45
46
|
private requestCallbacks: RequestCallback[] = [];
|
|
46
47
|
private responseCallbacks: ResponseCallback[] = [];
|
|
47
48
|
private restUrl: string = '';
|
|
48
|
-
|
|
49
|
+
public weakCache = false;
|
|
50
|
+
public weakCacheKeepDirtyData = false;
|
|
49
51
|
/**
|
|
50
52
|
* Headers that will be sent with every request.
|
|
51
53
|
*
|
|
@@ -55,7 +57,11 @@ export default class Nymph {
|
|
|
55
57
|
/**
|
|
56
58
|
* The entity cache.
|
|
57
59
|
*/
|
|
58
|
-
public
|
|
60
|
+
public entityCache = new EntityWeakCache();
|
|
61
|
+
/**
|
|
62
|
+
* The query cache.
|
|
63
|
+
*/
|
|
64
|
+
public queryCache = new QueryWeakCache();
|
|
59
65
|
/**
|
|
60
66
|
* Return `null` or empty array instead of error when entity/ies not found.
|
|
61
67
|
*/
|
|
@@ -65,6 +71,7 @@ export default class Nymph {
|
|
|
65
71
|
this.restUrl = NymphOptions.restUrl;
|
|
66
72
|
// @ts-ignore TS doesn't know about WeakRef.
|
|
67
73
|
this.weakCache = !!NymphOptions.weakCache && typeof WeakRef !== 'undefined';
|
|
74
|
+
this.weakCacheKeepDirtyData = !!NymphOptions.weakCacheKeepDirtyData;
|
|
68
75
|
if (
|
|
69
76
|
'returnNullOnNotFound' in NymphOptions &&
|
|
70
77
|
NymphOptions.returnNullOnNotFound != null
|
|
@@ -156,12 +163,24 @@ export default class Nymph {
|
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
public async getUID(name: string) {
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
166
|
+
const query = { action: 'uid', data: name };
|
|
167
|
+
let promise: Promise<any> | null = null;
|
|
168
|
+
const queryJSON = JSON.stringify(query);
|
|
169
|
+
if (this.weakCache) {
|
|
170
|
+
promise = this.queryCache.get(queryJSON);
|
|
171
|
+
}
|
|
172
|
+
if (promise == null) {
|
|
173
|
+
promise = requester.GET({
|
|
174
|
+
url: this.restUrl,
|
|
175
|
+
headers: { ...this.headers },
|
|
176
|
+
dataType: 'text',
|
|
177
|
+
data: query,
|
|
178
|
+
});
|
|
179
|
+
if (this.weakCache) {
|
|
180
|
+
this.queryCache.set(queryJSON, promise);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const data = await promise;
|
|
165
184
|
return Number(data);
|
|
166
185
|
}
|
|
167
186
|
|
|
@@ -259,11 +278,11 @@ export default class Nymph {
|
|
|
259
278
|
response[i] &&
|
|
260
279
|
response[i].guid != null &&
|
|
261
280
|
(e.guid == null || e.guid === response[i].guid)
|
|
262
|
-
? e.$init(response[i])
|
|
281
|
+
? e.$init(response[i], method !== 'GET')
|
|
263
282
|
: e,
|
|
264
283
|
) as T[];
|
|
265
284
|
} else if (!Array.isArray(entity) && response.guid != null) {
|
|
266
|
-
return entity.$init(response) as T;
|
|
285
|
+
return entity.$init(response, method !== 'GET') as T;
|
|
267
286
|
}
|
|
268
287
|
throw new Error('Server error');
|
|
269
288
|
}
|
|
@@ -320,7 +339,7 @@ export default class Nymph {
|
|
|
320
339
|
if (options.return && options.return === 'guid') {
|
|
321
340
|
return data as string;
|
|
322
341
|
} else {
|
|
323
|
-
return this.initEntity(data as EntityJson<T
|
|
342
|
+
return this.initEntity(data as EntityJson<T>, false);
|
|
324
343
|
}
|
|
325
344
|
}
|
|
326
345
|
|
|
@@ -364,18 +383,31 @@ export default class Nymph {
|
|
|
364
383
|
if (typeof selectors[0] === 'string') {
|
|
365
384
|
selectors = [{ type: '&', guid: selectors[0] }];
|
|
366
385
|
}
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
386
|
+
const query = {
|
|
387
|
+
action: 'entity',
|
|
388
|
+
data: [
|
|
389
|
+
entityConstructorsToClassNames(options),
|
|
390
|
+
...entityConstructorsToClassNames(entitiesToReferences(selectors)),
|
|
391
|
+
],
|
|
392
|
+
};
|
|
393
|
+
let promise: Promise<any> | null = null;
|
|
394
|
+
const queryJSON = JSON.stringify(query);
|
|
395
|
+
if (this.weakCache) {
|
|
396
|
+
promise = this.queryCache.get(queryJSON);
|
|
397
|
+
}
|
|
398
|
+
if (promise == null) {
|
|
399
|
+
promise = requester.GET({
|
|
400
|
+
url: this.restUrl,
|
|
401
|
+
headers: { ...this.headers },
|
|
402
|
+
dataType: 'json',
|
|
403
|
+
data: query,
|
|
404
|
+
});
|
|
405
|
+
if (this.weakCache) {
|
|
406
|
+
this.queryCache.set(queryJSON, promise);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const data = await promise;
|
|
379
411
|
|
|
380
412
|
if (options.return === 'count' || typeof data.guid !== 'undefined') {
|
|
381
413
|
return data;
|
|
@@ -401,18 +433,30 @@ export default class Nymph {
|
|
|
401
433
|
): Promise<EntityInstanceType<T>[] | string[] | number> {
|
|
402
434
|
let data = null;
|
|
403
435
|
try {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
436
|
+
const query = {
|
|
437
|
+
action: 'entities',
|
|
438
|
+
data: [
|
|
439
|
+
entityConstructorsToClassNames(options),
|
|
440
|
+
...entityConstructorsToClassNames(entitiesToReferences(selectors)),
|
|
441
|
+
],
|
|
442
|
+
};
|
|
443
|
+
let promise: Promise<any> | null = null;
|
|
444
|
+
const queryJSON = JSON.stringify(query);
|
|
445
|
+
if (this.weakCache) {
|
|
446
|
+
promise = this.queryCache.get(queryJSON);
|
|
447
|
+
}
|
|
448
|
+
if (promise == null) {
|
|
449
|
+
promise = requester.GET({
|
|
450
|
+
url: this.restUrl,
|
|
451
|
+
headers: { ...this.headers },
|
|
452
|
+
dataType: 'json',
|
|
453
|
+
data: query,
|
|
454
|
+
});
|
|
455
|
+
if (this.weakCache) {
|
|
456
|
+
this.queryCache.set(queryJSON, promise);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
data = await promise;
|
|
416
460
|
} catch (e: any) {
|
|
417
461
|
if (
|
|
418
462
|
this.returnNullOnNotFound &&
|
|
@@ -434,11 +478,12 @@ export default class Nymph {
|
|
|
434
478
|
if (options.return && options.return === 'guid') {
|
|
435
479
|
return data;
|
|
436
480
|
}
|
|
437
|
-
return data.map((e: EntityJson<T>) => this.initEntity(e));
|
|
481
|
+
return data.map((e: EntityJson<T>) => this.initEntity(e, false));
|
|
438
482
|
}
|
|
439
483
|
|
|
440
484
|
public initEntity<T extends EntityConstructor = EntityConstructor>(
|
|
441
485
|
entityJSON: EntityJson<T>,
|
|
486
|
+
isFromSave: boolean,
|
|
442
487
|
): EntityInstanceType<T> {
|
|
443
488
|
const EntityClass = classNamesToEntityConstructors<T>(
|
|
444
489
|
this,
|
|
@@ -452,7 +497,7 @@ export default class Nymph {
|
|
|
452
497
|
let entity = EntityClass.factorySync();
|
|
453
498
|
if (this.weakCache) {
|
|
454
499
|
// Try to get it from cache.
|
|
455
|
-
const entityFromCache = this.
|
|
500
|
+
const entityFromCache = this.entityCache.get(
|
|
456
501
|
EntityClass,
|
|
457
502
|
entityJSON.guid || '',
|
|
458
503
|
);
|
|
@@ -460,7 +505,7 @@ export default class Nymph {
|
|
|
460
505
|
entity = entityFromCache as EntityInstanceType<T>;
|
|
461
506
|
}
|
|
462
507
|
}
|
|
463
|
-
return entity.$init(entityJSON) as EntityInstanceType<T>;
|
|
508
|
+
return entity.$init(entityJSON, isFromSave) as EntityInstanceType<T>;
|
|
464
509
|
}
|
|
465
510
|
|
|
466
511
|
public getEntityFromCache<T extends EntityConstructor = EntityConstructor>(
|
|
@@ -470,7 +515,10 @@ export default class Nymph {
|
|
|
470
515
|
if (!this.weakCache) {
|
|
471
516
|
return null;
|
|
472
517
|
}
|
|
473
|
-
return this.
|
|
518
|
+
return this.entityCache.get(
|
|
519
|
+
EntityClass,
|
|
520
|
+
guid,
|
|
521
|
+
) as EntityInstanceType<T> | null;
|
|
474
522
|
}
|
|
475
523
|
|
|
476
524
|
public setEntityToCache(
|
|
@@ -480,13 +528,15 @@ export default class Nymph {
|
|
|
480
528
|
if (!this.weakCache) {
|
|
481
529
|
return;
|
|
482
530
|
}
|
|
483
|
-
return this.
|
|
531
|
+
return this.entityCache.set(EntityClass, entity);
|
|
484
532
|
}
|
|
485
533
|
|
|
486
|
-
public initEntitiesFromData<T extends any>(item: T): T {
|
|
534
|
+
public initEntitiesFromData<T extends any>(item: T, isFromSave: boolean): T {
|
|
487
535
|
if (Array.isArray(item)) {
|
|
488
536
|
// Recurse into lower arrays.
|
|
489
|
-
return item.map((entry) =>
|
|
537
|
+
return item.map((entry) =>
|
|
538
|
+
this.initEntitiesFromData(entry, isFromSave),
|
|
539
|
+
) as T;
|
|
490
540
|
} else if (item instanceof Object && !(item instanceof Entity)) {
|
|
491
541
|
if (
|
|
492
542
|
item.hasOwnProperty('class') &&
|
|
@@ -500,11 +550,11 @@ export default class Nymph {
|
|
|
500
550
|
(item as any as EntityJson).class,
|
|
501
551
|
) != null
|
|
502
552
|
) {
|
|
503
|
-
return this.initEntity(item as any as EntityJson) as T;
|
|
553
|
+
return this.initEntity(item as any as EntityJson, isFromSave) as T;
|
|
504
554
|
} else {
|
|
505
555
|
for (let [key, value] of Object.entries(item)) {
|
|
506
556
|
// @ts-ignore: Key comes from the object. It's fine.
|
|
507
|
-
item[key] = this.initEntitiesFromData(value);
|
|
557
|
+
item[key] = this.initEntitiesFromData(value, isFromSave);
|
|
508
558
|
}
|
|
509
559
|
}
|
|
510
560
|
}
|
|
@@ -563,7 +613,7 @@ export default class Nymph {
|
|
|
563
613
|
|
|
564
614
|
return {
|
|
565
615
|
...data,
|
|
566
|
-
return: this.initEntitiesFromData(data.return),
|
|
616
|
+
return: this.initEntitiesFromData(data.return, false),
|
|
567
617
|
};
|
|
568
618
|
}
|
|
569
619
|
|
|
@@ -587,7 +637,7 @@ export default class Nymph {
|
|
|
587
637
|
},
|
|
588
638
|
});
|
|
589
639
|
|
|
590
|
-
return this.initEntitiesFromData(data);
|
|
640
|
+
return this.initEntitiesFromData(data, false);
|
|
591
641
|
}
|
|
592
642
|
|
|
593
643
|
public async serverCallStaticIterator(
|
|
@@ -619,7 +669,7 @@ export default class Nymph {
|
|
|
619
669
|
if (response instanceof Error) {
|
|
620
670
|
yield response;
|
|
621
671
|
} else {
|
|
622
|
-
yield that.initEntitiesFromData(response);
|
|
672
|
+
yield that.initEntitiesFromData(response, false);
|
|
623
673
|
}
|
|
624
674
|
}
|
|
625
675
|
},
|