@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/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":"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"}
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.7",
4
- "description": "NymphJS - Client",
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
- "prepare": "npm run clean && npm run build",
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.1",
40
- "@types/jest": "^29.2.5",
41
- "@types/lodash": "^4.14.191",
42
- "jest": "^29.3.1",
43
- "lodash": "^4.17.21",
44
- "ts-jest": "^29.0.3",
45
- "ts-loader": "^9.4.2",
46
- "typescript": "^4.9.4",
47
- "webpack": "^5.75.0",
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
- "gitHead": "0f2e7433e16e40c704f505a3c8db5383d9e6b240"
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
- const sleepErr =
20
- 'This entity is in a sleeping reference state. ' +
21
- 'You must use .$ready() to wake it.';
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 ready.
90
+ * A promise that resolved when the entity's data is wake.
88
91
  */
89
- protected $readyPromise: Promise<Entity<T>> | null = null;
92
+ protected $wakePromise: Promise<Entity<T>> | null = null;
90
93
 
91
94
  /**
92
- * Load an entity.
93
- * @param guid The ID of the entity to load, undefined for a new entity.
95
+ * Initialize an entity.
94
96
  */
95
- public constructor(guid?: string) {
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
- public static async factory(guid?: string) {
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 ? this.nymph.getEntityFromCache(this, guid) : null
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
- const entity = cacheEntity || new this(guid);
294
+ if (cacheEntity) {
295
+ return cacheEntity as E & EntityDataType<E>;
296
+ }
297
+ const entity = new this();
287
298
  if (guid != null) {
288
- await entity.$ready();
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
- public static factorySync(guid?: string) {
294
- const cacheEntity = (
295
- guid ? this.nymph.getEntityFromCache(this, guid) : null
296
- ) as Entity | null;
297
- return cacheEntity || new this(guid);
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
- public static factoryReference(reference: EntityReference) {
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] ? this.nymph.getEntityFromCache(this, reference[1]) : null
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- public $ready() {
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.$readyPromise = null;
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 ready a sleeping reference with no GUID.'
603
+ 'Tried to wake a sleeping reference with no GUID.',
538
604
  );
539
605
  }
540
- if (!this.$readyPromise) {
541
- this.$readyPromise = this.$nymph
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.$readyPromise = null;
620
+ this.$wakePromise = null;
555
621
  });
556
622
  }
557
- return this.$readyPromise;
623
+ return this.$wakePromise;
558
624
  }
559
625
 
560
- public $readyAll(level?: number) {
626
+ public $wakeAll(level?: number) {
561
627
  return new Promise((resolve, reject) => {
562
- // Run this once this entity is ready.
563
- const readyProps = () => {
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 ready.
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.$readyAll(newLevel));
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].$readyAll(newLevel));
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.$ready().then(readyProps, (errObj) => reject(errObj));
667
+ this.$wake().then(wakeProps, (errObj) => reject(errObj));
602
668
  } else {
603
- readyProps();
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.$ready();
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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
- if (this.$isASleepingReference) {
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);