@nymphjs/client 1.0.0-beta.2 → 1.0.0-beta.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nymphjs/client",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.21",
4
4
  "description": "NymphJS - Client",
5
5
  "browser": "dist/index.js",
6
6
  "main": "lib/index.js",
@@ -36,16 +36,16 @@
36
36
  },
37
37
  "license": "Apache-2.0",
38
38
  "devDependencies": {
39
- "@tsconfig/recommended": "^1.0.1",
40
- "@types/jest": "^29.2.3",
41
- "@types/lodash": "^4.14.189",
42
- "jest": "^29.3.1",
39
+ "@tsconfig/recommended": "^1.0.2",
40
+ "@types/jest": "^29.5.1",
41
+ "@types/lodash": "^4.14.194",
42
+ "jest": "^29.5.0",
43
43
  "lodash": "^4.17.21",
44
- "ts-jest": "^29.0.3",
45
- "ts-loader": "^9.4.1",
46
- "typescript": "^4.9.3",
47
- "webpack": "^5.75.0",
48
- "webpack-cli": "^4.10.0"
44
+ "ts-jest": "^29.1.0",
45
+ "ts-loader": "^9.4.2",
46
+ "typescript": "^5.0.4",
47
+ "webpack": "^5.80.0",
48
+ "webpack-cli": "^5.0.2"
49
49
  },
50
- "gitHead": "431d1aaa620a4f1d4ef0227aaad717665dfd6a6d"
50
+ "gitHead": "a1149a055d645ce8191845978d5cbdeaa1afddaa"
51
51
  }
package/src/Entity.ts CHANGED
@@ -419,9 +419,6 @@ export default class Entity<T extends EntityData = EntityData>
419
419
  return false;
420
420
  }
421
421
  }
422
- if (object.constructor !== this.constructor) {
423
- return false;
424
- }
425
422
  if (object.cdate !== this.cdate) {
426
423
  return false;
427
424
  }
@@ -524,7 +521,7 @@ export default class Entity<T extends EntityData = EntityData>
524
521
  const mdate = this.mdate;
525
522
 
526
523
  await this.$nymph.patchEntity(this);
527
- return mdate === this.mdate;
524
+ return mdate !== this.mdate;
528
525
  }
529
526
 
530
527
  public $ready() {
@@ -208,7 +208,7 @@ export interface EntityInterface extends DataObjectInterface {
208
208
  $toReference(): EntityReference | EntityInterface;
209
209
  }
210
210
 
211
- export type EntityConstructor = (new () => EntityInterface) & {
211
+ export type EntityConstructor = (new (...args: any[]) => EntityInterface) & {
212
212
  /**
213
213
  * The instance of Nymph to use for queries.
214
214
  */
@@ -1,15 +1,18 @@
1
1
  import { EntityConstructor, EntityInterface } from './Entity.types';
2
2
 
3
3
  export default class EntityWeakCache {
4
- private references: WeakMap<EntityConstructor, { [k: string]: any }> =
5
- new WeakMap();
4
+ private references: WeakMap<
5
+ EntityConstructor,
6
+ { [k: string]: WeakRef<EntityInterface> }
7
+ > = new WeakMap();
6
8
 
7
9
  get(EntityClass: EntityConstructor, guid: string): EntityInterface | null {
8
10
  const classMap = this.references.get(EntityClass);
9
11
  if (classMap && guid in classMap) {
10
12
  const weakRef = classMap[guid];
11
- if (weakRef && weakRef.deref() != null) {
12
- return weakRef.deref();
13
+ const deref = weakRef && weakRef.deref();
14
+ if (deref != null) {
15
+ return deref;
13
16
  } else {
14
17
  delete classMap[guid];
15
18
  }
@@ -22,7 +25,6 @@ export default class EntityWeakCache {
22
25
  return;
23
26
  }
24
27
 
25
- // @ts-ignore TS doesn't know about WeakRef.
26
28
  const weakRef = new WeakRef(entity);
27
29
 
28
30
  const classMap = this.references.get(EntityClass) || {};
@@ -167,9 +167,15 @@ export default class HttpRequester {
167
167
  };
168
168
  }
169
169
  errObj.status = response.status;
170
- throw response.status < 500
171
- ? new ClientError(errObj)
172
- : new ServerError(errObj);
170
+ throw response.status < 200
171
+ ? new InformationalError(response, errObj)
172
+ : response.status < 300
173
+ ? new SuccessError(response, errObj)
174
+ : response.status < 400
175
+ ? new RedirectError(response, errObj)
176
+ : response.status < 500
177
+ ? new ClientError(response, errObj)
178
+ : new ServerError(response, errObj);
173
179
  }
174
180
  for (let i = 0; i < this.responseCallbacks.length; i++) {
175
181
  this.responseCallbacks[i] &&
@@ -202,18 +208,49 @@ export class InvalidResponseError extends Error {
202
208
  }
203
209
  }
204
210
 
205
- export class ClientError extends Error {
206
- constructor(errObj: { textStatus: string }) {
211
+ export class HttpError extends Error {
212
+ status: number;
213
+ statusText: string;
214
+
215
+ constructor(
216
+ name: string,
217
+ response: Response,
218
+ errObj: { textStatus: string }
219
+ ) {
207
220
  super(errObj.textStatus);
208
- this.name = 'ClientError';
221
+ this.name = name;
222
+ this.status = response.status;
223
+ this.statusText = response.statusText;
209
224
  Object.assign(this, errObj);
210
225
  }
211
226
  }
212
227
 
213
- export class ServerError extends Error {
214
- constructor(errObj: { textStatus: string }) {
215
- super(errObj.textStatus);
216
- this.name = 'ServerError';
217
- Object.assign(this, errObj);
228
+ export class InformationalError extends HttpError {
229
+ constructor(response: Response, errObj: { textStatus: string }) {
230
+ super('InformationalError', response, errObj);
231
+ }
232
+ }
233
+
234
+ export class SuccessError extends HttpError {
235
+ constructor(response: Response, errObj: { textStatus: string }) {
236
+ super('SuccessError', response, errObj);
237
+ }
238
+ }
239
+
240
+ export class RedirectError extends HttpError {
241
+ constructor(response: Response, errObj: { textStatus: string }) {
242
+ super('RedirectError', response, errObj);
243
+ }
244
+ }
245
+
246
+ export class ClientError extends HttpError {
247
+ constructor(response: Response, errObj: { textStatus: string }) {
248
+ super('ClientError', response, errObj);
249
+ }
250
+ }
251
+
252
+ export class ServerError extends HttpError {
253
+ constructor(response: Response, errObj: { textStatus: string }) {
254
+ super('ServerError', response, errObj);
218
255
  }
219
256
  }
package/src/Nymph.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import Entity from './Entity';
2
- import {
2
+ import type {
3
3
  EntityConstructor,
4
- EntityData,
5
4
  EntityInterface,
6
5
  EntityJson,
7
6
  ServerCallResponse,
@@ -9,7 +8,7 @@ import {
9
8
  } from './Entity.types';
10
9
  import EntityWeakCache from './EntityWeakCache';
11
10
  import HttpRequester from './HttpRequester';
12
- import {
11
+ import type {
13
12
  EventType,
14
13
  NymphOptions,
15
14
  Options,
@@ -17,7 +16,7 @@ import {
17
16
  ResponseCallback,
18
17
  Selector,
19
18
  } from './Nymph.types';
20
- import PubSub from './PubSub';
19
+ import type PubSub from './PubSub';
21
20
  import { entitiesToReferences, entityConstructorsToClassNames } from './utils';
22
21
 
23
22
  let requester: HttpRequester;
@@ -36,7 +35,7 @@ export default class Nymph {
36
35
  /**
37
36
  * The entity class for this instance of Nymph.
38
37
  */
39
- public Entity: typeof Entity = Entity;
38
+ public Entity: typeof Entity;
40
39
 
41
40
  private requestCallbacks: RequestCallback[] = [];
42
41
  private responseCallbacks: ResponseCallback[] = [];
@@ -49,10 +48,7 @@ export default class Nymph {
49
48
  // @ts-ignore TS doesn't know about WeakRef.
50
49
  this.weakCache = !!NymphOptions.weakCache && typeof WeakRef !== 'undefined';
51
50
 
52
- class NymphEntity<T extends EntityData = EntityData> extends Entity<T> {}
53
- NymphEntity.nymph = this;
54
- this.Entity = NymphEntity;
55
- this.addEntityClass(NymphEntity);
51
+ this.Entity = this.addEntityClass(Entity);
56
52
 
57
53
  requester = new HttpRequester(
58
54
  'fetch' in NymphOptions ? NymphOptions.fetch : undefined
@@ -71,16 +67,32 @@ export default class Nymph {
71
67
  });
72
68
  }
73
69
 
74
- public addEntityClass(entityClass: EntityConstructor) {
75
- this.entityClasses[entityClass.class] = entityClass;
76
- entityClass.nymph = this;
70
+ /**
71
+ * Add your class to this instance.
72
+ *
73
+ * This will create a class that extends your class within this instance of
74
+ * Nymph and return it. You can then use this class's constructor and methods,
75
+ * which will use this instance of Nymph.
76
+ *
77
+ * Because this creates a subclass, don't use the class
78
+ * returned from `getEntityClass` to check with `instanceof`.
79
+ */
80
+ public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
81
+ const nymph = this;
82
+ class NymphEntity extends entityClass {
83
+ static nymph: Nymph = nymph;
84
+
85
+ constructor(...args: any[]) {
86
+ super(...args);
87
+ }
88
+ }
89
+ this.entityClasses[entityClass.class] = NymphEntity;
90
+ return NymphEntity;
77
91
  }
78
92
 
79
93
  public getEntityClass(className: string) {
80
- if (this.entityClasses.hasOwnProperty(className)) {
81
- const EntityClass = this.entityClasses[className];
82
- EntityClass.nymph = this;
83
- return EntityClass;
94
+ if (className in this.entityClasses) {
95
+ return this.entityClasses[className];
84
96
  }
85
97
  throw new ClassNotAvailableError(
86
98
  "Tried to get class that's not available: " + className
@@ -21,6 +21,10 @@ export type NymphOptions = {
21
21
  * Whether to not output status messages to the console.
22
22
  */
23
23
  noConsole?: boolean;
24
+ /**
25
+ * Don't automatically try to connect to PubSub server.
26
+ */
27
+ noAutoconnect?: boolean;
24
28
  /**
25
29
  * Use a WeakRef based cache of entities.
26
30
  *
@@ -53,7 +57,7 @@ export type Options<T extends EntityConstructor = EntityConstructor> = {
53
57
  limit?: number;
54
58
  offset?: number;
55
59
  reverse?: boolean;
56
- sort?: 'cdate' | 'mdate';
60
+ sort?: 'cdate' | 'mdate' | string;
57
61
  return?: 'entity' | 'guid' | 'count';
58
62
  skipCache?: boolean;
59
63
  };
package/src/PubSub.ts CHANGED
@@ -14,10 +14,10 @@ import {
14
14
  } from './PubSub.types';
15
15
  import { entityConstructorsToClassNames } from './utils';
16
16
 
17
- let authToken: string | null = null;
18
-
19
17
  export default class PubSub {
20
18
  private nymph: Nymph;
19
+ private authToken: string | null = null;
20
+ private switchToken: string | null = null;
21
21
  private connection: WebSocket | undefined;
22
22
  private waitForConnectionTimeout: NodeJS.Timeout | undefined;
23
23
  private pubsubUrl: string | undefined;
@@ -51,7 +51,10 @@ export default class PubSub {
51
51
  if (typeof addEventListener !== 'undefined') {
52
52
  addEventListener('online', () => this.connect());
53
53
  }
54
- if (typeof navigator === 'undefined' || navigator.onLine) {
54
+ if (
55
+ !nymphOptions.noAutoconnect &&
56
+ (typeof navigator === 'undefined' || navigator.onLine)
57
+ ) {
55
58
  this.connect();
56
59
  }
57
60
  }
@@ -289,10 +292,11 @@ export default class PubSub {
289
292
  }
290
293
  }
291
294
 
292
- if (authToken != null) {
295
+ if (this.authToken != null) {
293
296
  this._send({
294
297
  action: 'authenticate',
295
- token: authToken,
298
+ token: this.authToken,
299
+ switchToken: this.switchToken,
296
300
  });
297
301
  }
298
302
 
@@ -645,8 +649,7 @@ export default class PubSub {
645
649
  const query = JSON.parse(update.query);
646
650
  if (entity != null) {
647
651
  // Insert the entity in order.
648
- const sort =
649
- 'sort' in query[0] ? (query[0].sort as 'cdate' | 'mdate') : 'cdate';
652
+ const sort = 'sort' in query[0] ? (query[0].sort as string) : 'cdate';
650
653
  const reverse = query[0].hasOwnProperty('reverse')
651
654
  ? query[0].reverse
652
655
  : false;
@@ -716,12 +719,14 @@ export default class PubSub {
716
719
  return true;
717
720
  }
718
721
 
719
- public setToken(token: string | null) {
720
- authToken = token;
722
+ public setToken(authToken: string | null, switchToken: string | null = null) {
723
+ this.authToken = authToken;
724
+ this.switchToken = switchToken;
721
725
  if (this.isConnectionOpen()) {
722
726
  this._send({
723
727
  action: 'authenticate',
724
- token: authToken,
728
+ authToken: this.authToken,
729
+ switchToken: this.switchToken,
725
730
  });
726
731
  }
727
732
  }