@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/CHANGELOG.md +92 -0
- package/README.md +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/lib/Entity.d.ts +2 -2
- package/lib/Entity.js +2 -5
- package/lib/Entity.js.map +1 -1
- package/lib/Entity.types.d.ts +1 -1
- package/lib/EntityWeakCache.js +3 -2
- package/lib/EntityWeakCache.js.map +1 -1
- package/lib/HttpRequester.d.ts +26 -4
- package/lib/HttpRequester.js +42 -12
- package/lib/HttpRequester.js.map +1 -1
- package/lib/Nymph.d.ts +4 -4
- package/lib/Nymph.js +12 -12
- package/lib/Nymph.js.map +1 -1
- package/lib/Nymph.types.d.ts +2 -1
- package/lib/PubSub.d.ts +3 -1
- package/lib/PubSub.js +12 -7
- package/lib/PubSub.js.map +1 -1
- package/package.json +11 -11
- package/src/Entity.ts +1 -4
- package/src/Entity.types.ts +1 -1
- package/src/EntityWeakCache.ts +7 -5
- package/src/HttpRequester.ts +48 -11
- package/src/Nymph.ts +28 -16
- package/src/Nymph.types.ts +5 -1
- package/src/PubSub.ts +15 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nymphjs/client",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
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.
|
|
40
|
-
"@types/jest": "^29.
|
|
41
|
-
"@types/lodash": "^4.14.
|
|
42
|
-
"jest": "^29.
|
|
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
|
|
45
|
-
"ts-loader": "^9.4.
|
|
46
|
-
"typescript": "^
|
|
47
|
-
"webpack": "^5.
|
|
48
|
-
"webpack-cli": "^
|
|
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": "
|
|
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
|
|
524
|
+
return mdate !== this.mdate;
|
|
528
525
|
}
|
|
529
526
|
|
|
530
527
|
public $ready() {
|
package/src/Entity.types.ts
CHANGED
|
@@ -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
|
*/
|
package/src/EntityWeakCache.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { EntityConstructor, EntityInterface } from './Entity.types';
|
|
2
2
|
|
|
3
3
|
export default class EntityWeakCache {
|
|
4
|
-
private references: WeakMap<
|
|
5
|
-
|
|
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
|
-
|
|
12
|
-
|
|
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) || {};
|
package/src/HttpRequester.ts
CHANGED
|
@@ -167,9 +167,15 @@ export default class HttpRequester {
|
|
|
167
167
|
};
|
|
168
168
|
}
|
|
169
169
|
errObj.status = response.status;
|
|
170
|
-
throw response.status <
|
|
171
|
-
? new
|
|
172
|
-
:
|
|
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
|
|
206
|
-
|
|
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 =
|
|
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
|
|
214
|
-
constructor(errObj: { textStatus: string }) {
|
|
215
|
-
super(errObj
|
|
216
|
-
|
|
217
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
81
|
-
|
|
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
|
package/src/Nymph.types.ts
CHANGED
|
@@ -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 (
|
|
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(
|
|
720
|
-
authToken =
|
|
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
|
-
|
|
728
|
+
authToken: this.authToken,
|
|
729
|
+
switchToken: this.switchToken,
|
|
725
730
|
});
|
|
726
731
|
}
|
|
727
732
|
}
|