@nymphjs/client 1.0.0-beta.12 → 1.0.0-beta.120
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 +496 -0
- package/README.md +6 -6
- package/asyncitertest.js +53 -0
- package/dist/Entity.d.ts +156 -0
- package/{lib → dist}/Entity.js +202 -104
- package/dist/Entity.js.map +1 -0
- package/dist/Entity.types.d.ts +218 -0
- package/dist/Entity.types.js +2 -0
- package/{lib → dist}/EntityWeakCache.d.ts +1 -1
- package/{lib → dist}/EntityWeakCache.js +5 -9
- package/dist/EntityWeakCache.js.map +1 -0
- package/{lib → dist}/HttpRequester.d.ts +18 -4
- package/dist/HttpRequester.js +365 -0
- package/dist/HttpRequester.js.map +1 -0
- package/{lib → dist}/Nymph.d.ts +48 -11
- package/{lib → dist}/Nymph.js +167 -51
- package/dist/Nymph.js.map +1 -0
- package/dist/Nymph.types.d.ts +227 -0
- package/dist/Nymph.types.js +45 -0
- package/dist/Nymph.types.js.map +1 -0
- package/{lib → dist}/PubSub.d.ts +16 -10
- package/{lib → dist}/PubSub.js +208 -135
- package/dist/PubSub.js.map +1 -0
- package/{lib → dist}/PubSub.types.d.ts +19 -6
- package/dist/PubSub.types.js +2 -0
- package/{lib → dist}/entityRefresh.d.ts +1 -1
- package/{lib → dist}/entityRefresh.js +21 -13
- package/dist/entityRefresh.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/{lib → dist}/utils.d.ts +1 -1
- package/{lib → dist}/utils.js +28 -21
- package/dist/utils.js.map +1 -0
- package/jest.config.js +31 -5
- package/package.json +31 -30
- package/src/Entity.ts +174 -108
- package/src/Entity.types.ts +29 -47
- package/src/EntityWeakCache.ts +8 -6
- package/src/HttpRequester.ts +268 -31
- package/src/Nymph.ts +188 -88
- package/src/Nymph.types.ts +102 -2
- package/src/PubSub.ts +262 -179
- package/src/PubSub.types.ts +33 -19
- package/src/entityRefresh.ts +6 -6
- package/src/index.ts +10 -10
- package/src/utils.ts +12 -5
- package/tsconfig.json +7 -4
- package/typedoc.json +4 -0
- package/dist/index.js.LICENSE.txt +0 -8
- package/lib/Entity.d.ts +0 -51
- package/lib/Entity.js.map +0 -1
- package/lib/Entity.types.d.ts +0 -65
- package/lib/Entity.types.js +0 -3
- package/lib/EntityWeakCache.js.map +0 -1
- package/lib/HttpRequester.js +0 -190
- package/lib/HttpRequester.js.map +0 -1
- package/lib/Nymph.js.map +0 -1
- package/lib/Nymph.types.d.ts +0 -97
- package/lib/Nymph.types.js +0 -3
- package/lib/Nymph.types.js.map +0 -1
- package/lib/PubSub.js.map +0 -1
- package/lib/PubSub.types.js +0 -3
- package/lib/entityRefresh.js.map +0 -1
- package/lib/index.d.ts +0 -13
- package/lib/index.js +0 -34
- package/lib/index.js.map +0 -1
- package/lib/utils.js.map +0 -1
- package/webpack.config.js +0 -28
- /package/{lib → dist}/Entity.types.js.map +0 -0
- /package/{lib → dist}/PubSub.types.js.map +0 -0
package/src/Nymph.ts
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import Entity from './Entity';
|
|
2
|
-
import {
|
|
1
|
+
import Entity, { type EntityInstanceType } from './Entity.js';
|
|
2
|
+
import type {
|
|
3
3
|
EntityConstructor,
|
|
4
|
-
EntityData,
|
|
5
4
|
EntityInterface,
|
|
6
5
|
EntityJson,
|
|
7
6
|
ServerCallResponse,
|
|
8
7
|
ServerCallStaticResponse,
|
|
9
|
-
} from './Entity.types';
|
|
10
|
-
import EntityWeakCache from './EntityWeakCache';
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
8
|
+
} from './Entity.types.js';
|
|
9
|
+
import EntityWeakCache from './EntityWeakCache.js';
|
|
10
|
+
import type { AbortableAsyncIterator } from './HttpRequester.js';
|
|
11
|
+
import HttpRequester, { ClientError } from './HttpRequester.js';
|
|
12
|
+
import type {
|
|
13
13
|
EventType,
|
|
14
14
|
NymphOptions,
|
|
15
15
|
Options,
|
|
16
16
|
RequestCallback,
|
|
17
17
|
ResponseCallback,
|
|
18
18
|
Selector,
|
|
19
|
-
} from './Nymph.types';
|
|
20
|
-
import PubSub from './PubSub';
|
|
21
|
-
import {
|
|
19
|
+
} from './Nymph.types.js';
|
|
20
|
+
import type PubSub from './PubSub.js';
|
|
21
|
+
import {
|
|
22
|
+
entitiesToReferences,
|
|
23
|
+
entityConstructorsToClassNames,
|
|
24
|
+
} from './utils.js';
|
|
22
25
|
|
|
23
26
|
let requester: HttpRequester;
|
|
24
27
|
|
|
@@ -42,19 +45,42 @@ export default class Nymph {
|
|
|
42
45
|
private responseCallbacks: ResponseCallback[] = [];
|
|
43
46
|
private restUrl: string = '';
|
|
44
47
|
private weakCache = false;
|
|
48
|
+
/**
|
|
49
|
+
* Headers that will be sent with every request.
|
|
50
|
+
*
|
|
51
|
+
* These are used by Tilmeld for authentication.
|
|
52
|
+
*/
|
|
53
|
+
public headers: { [k: string]: string } = {};
|
|
54
|
+
/**
|
|
55
|
+
* The entity cache.
|
|
56
|
+
*/
|
|
45
57
|
public cache = new EntityWeakCache();
|
|
58
|
+
/**
|
|
59
|
+
* Return `null` or empty array instead of error when entity/ies not found.
|
|
60
|
+
*/
|
|
61
|
+
public returnNullOnNotFound = false;
|
|
46
62
|
|
|
47
63
|
public constructor(NymphOptions: NymphOptions) {
|
|
48
64
|
this.restUrl = NymphOptions.restUrl;
|
|
49
65
|
// @ts-ignore TS doesn't know about WeakRef.
|
|
50
66
|
this.weakCache = !!NymphOptions.weakCache && typeof WeakRef !== 'undefined';
|
|
67
|
+
if (
|
|
68
|
+
'returnNullOnNotFound' in NymphOptions &&
|
|
69
|
+
NymphOptions.returnNullOnNotFound != null
|
|
70
|
+
) {
|
|
71
|
+
this.returnNullOnNotFound = NymphOptions.returnNullOnNotFound;
|
|
72
|
+
}
|
|
51
73
|
|
|
52
74
|
this.Entity = this.addEntityClass(Entity);
|
|
53
75
|
|
|
54
76
|
requester = new HttpRequester(
|
|
55
|
-
'fetch' in NymphOptions ? NymphOptions.fetch : undefined
|
|
77
|
+
'fetch' in NymphOptions ? NymphOptions.fetch : undefined,
|
|
56
78
|
);
|
|
57
79
|
|
|
80
|
+
if ('renewTokens' in NymphOptions && !NymphOptions.renewTokens) {
|
|
81
|
+
this.headers['X-Tilmeld-Token-Renewal'] = 'off';
|
|
82
|
+
}
|
|
83
|
+
|
|
58
84
|
requester.on('request', (_requester, url, options) => {
|
|
59
85
|
for (let i = 0; i < this.requestCallbacks.length; i++) {
|
|
60
86
|
this.requestCallbacks[i] && this.requestCallbacks[i](url, options);
|
|
@@ -75,8 +101,9 @@ export default class Nymph {
|
|
|
75
101
|
* Nymph and return it. You can then use this class's constructor and methods,
|
|
76
102
|
* which will use this instance of Nymph.
|
|
77
103
|
*
|
|
78
|
-
* Because this creates a subclass, don't use the class
|
|
79
|
-
*
|
|
104
|
+
* Because this creates a subclass, don't use the class returned from
|
|
105
|
+
* `getEntityClass` to check with `instanceof`. Instead, use the base class
|
|
106
|
+
* that you passed into this method.
|
|
80
107
|
*/
|
|
81
108
|
public addEntityClass<T extends EntityConstructor>(entityClass: T): T {
|
|
82
109
|
const nymph = this;
|
|
@@ -91,18 +118,27 @@ export default class Nymph {
|
|
|
91
118
|
return NymphEntity;
|
|
92
119
|
}
|
|
93
120
|
|
|
94
|
-
public getEntityClass(className:
|
|
95
|
-
|
|
96
|
-
|
|
121
|
+
public getEntityClass<T extends EntityConstructor>(className: T): T;
|
|
122
|
+
public getEntityClass(className: string): EntityConstructor;
|
|
123
|
+
public getEntityClass<T extends EntityConstructor = EntityConstructor>(
|
|
124
|
+
className: T | string,
|
|
125
|
+
): T | EntityConstructor {
|
|
126
|
+
let key: string | null = null;
|
|
127
|
+
if (typeof className === 'string') {
|
|
128
|
+
key = className;
|
|
129
|
+
} else {
|
|
130
|
+
key = className.class;
|
|
97
131
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
132
|
+
if (key in this.entityClasses) {
|
|
133
|
+
return this.entityClasses[key];
|
|
134
|
+
}
|
|
135
|
+
throw new ClassNotAvailableError('Tried to use class: ' + key);
|
|
101
136
|
}
|
|
102
137
|
|
|
103
138
|
public async newUID(name: string) {
|
|
104
139
|
const data = await requester.POST({
|
|
105
140
|
url: this.restUrl,
|
|
141
|
+
headers: { ...this.headers },
|
|
106
142
|
dataType: 'text',
|
|
107
143
|
data: { action: 'uid', data: name },
|
|
108
144
|
});
|
|
@@ -112,6 +148,7 @@ export default class Nymph {
|
|
|
112
148
|
public async setUID(name: string, value: number) {
|
|
113
149
|
return await requester.PUT({
|
|
114
150
|
url: this.restUrl,
|
|
151
|
+
headers: { ...this.headers },
|
|
115
152
|
dataType: 'json',
|
|
116
153
|
data: { action: 'uid', data: { name, value } },
|
|
117
154
|
});
|
|
@@ -120,6 +157,7 @@ export default class Nymph {
|
|
|
120
157
|
public async getUID(name: string) {
|
|
121
158
|
const data = await requester.GET({
|
|
122
159
|
url: this.restUrl,
|
|
160
|
+
headers: { ...this.headers },
|
|
123
161
|
dataType: 'text',
|
|
124
162
|
data: { action: 'uid', data: name },
|
|
125
163
|
});
|
|
@@ -129,6 +167,7 @@ export default class Nymph {
|
|
|
129
167
|
public async deleteUID(name: string) {
|
|
130
168
|
return await requester.DELETE({
|
|
131
169
|
url: this.restUrl,
|
|
170
|
+
headers: { ...this.headers },
|
|
132
171
|
dataType: 'text',
|
|
133
172
|
data: { action: 'uid', data: name },
|
|
134
173
|
});
|
|
@@ -152,7 +191,7 @@ export default class Nymph {
|
|
|
152
191
|
) {
|
|
153
192
|
throw new InvalidRequestError(
|
|
154
193
|
'Due to REST restriction, you can only create new entities or ' +
|
|
155
|
-
'update existing entities, not both at the same time.'
|
|
194
|
+
'update existing entities, not both at the same time.',
|
|
156
195
|
);
|
|
157
196
|
}
|
|
158
197
|
});
|
|
@@ -162,7 +201,7 @@ export default class Nymph {
|
|
|
162
201
|
public async patchEntity(entity: EntityInterface) {
|
|
163
202
|
if (entity.guid == null) {
|
|
164
203
|
throw new InvalidRequestError(
|
|
165
|
-
"You can't patch an entity that hasn't yet been saved."
|
|
204
|
+
"You can't patch an entity that hasn't yet been saved.",
|
|
166
205
|
);
|
|
167
206
|
}
|
|
168
207
|
|
|
@@ -179,7 +218,7 @@ export default class Nymph {
|
|
|
179
218
|
if (cur.guid == null) {
|
|
180
219
|
throw new InvalidRequestError(
|
|
181
220
|
'Due to REST restriction, you can only create new entities or ' +
|
|
182
|
-
'update existing entities, not both at the same time.'
|
|
221
|
+
'update existing entities, not both at the same time.',
|
|
183
222
|
);
|
|
184
223
|
}
|
|
185
224
|
});
|
|
@@ -191,22 +230,23 @@ export default class Nymph {
|
|
|
191
230
|
entity: T,
|
|
192
231
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
|
|
193
232
|
data: { [k: string]: any },
|
|
194
|
-
plural: false
|
|
233
|
+
plural: false,
|
|
195
234
|
): Promise<T>;
|
|
196
235
|
private async requestWithMethod<T extends EntityInterface>(
|
|
197
236
|
entity: T[],
|
|
198
237
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
|
|
199
238
|
data: { [k: string]: any },
|
|
200
|
-
plural: true
|
|
239
|
+
plural: true,
|
|
201
240
|
): Promise<T[]>;
|
|
202
241
|
private async requestWithMethod<T extends EntityInterface>(
|
|
203
242
|
entity: T | T[],
|
|
204
243
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
|
|
205
244
|
data: { [k: string]: any },
|
|
206
|
-
plural: boolean
|
|
245
|
+
plural: boolean,
|
|
207
246
|
): Promise<T | T[]> {
|
|
208
247
|
const response = await requester[method]({
|
|
209
248
|
url: this.restUrl,
|
|
249
|
+
headers: { ...this.headers },
|
|
210
250
|
dataType: 'json',
|
|
211
251
|
data: {
|
|
212
252
|
action: plural ? 'entities' : 'entity',
|
|
@@ -219,7 +259,7 @@ export default class Nymph {
|
|
|
219
259
|
typeof response[i].guid !== 'undefined' &&
|
|
220
260
|
(e.guid == null || e.guid === response[i].guid)
|
|
221
261
|
? e.$init(response[i])
|
|
222
|
-
: e
|
|
262
|
+
: e,
|
|
223
263
|
) as T[];
|
|
224
264
|
} else if (!Array.isArray(entity) && typeof response.guid !== 'undefined') {
|
|
225
265
|
return entity.$init(response) as T;
|
|
@@ -238,29 +278,39 @@ export default class Nymph {
|
|
|
238
278
|
public async getEntity<T extends EntityConstructor = EntityConstructor>(
|
|
239
279
|
options: Options<T>,
|
|
240
280
|
...selectors: Selector[]
|
|
241
|
-
): Promise<
|
|
281
|
+
): Promise<EntityInstanceType<T> | null>;
|
|
242
282
|
public async getEntity<T extends EntityConstructor = EntityConstructor>(
|
|
243
283
|
options: Options<T> & { return: 'count' },
|
|
244
|
-
guid: string
|
|
284
|
+
guid: string,
|
|
245
285
|
): Promise<number>;
|
|
246
286
|
public async getEntity<T extends EntityConstructor = EntityConstructor>(
|
|
247
287
|
options: Options<T> & { return: 'guid' },
|
|
248
|
-
guid: string
|
|
288
|
+
guid: string,
|
|
249
289
|
): Promise<string | null>;
|
|
250
290
|
public async getEntity<T extends EntityConstructor = EntityConstructor>(
|
|
251
291
|
options: Options<T>,
|
|
252
|
-
guid: string
|
|
253
|
-
): Promise<
|
|
292
|
+
guid: string,
|
|
293
|
+
): Promise<EntityInstanceType<T> | null>;
|
|
254
294
|
public async getEntity<T extends EntityConstructor = EntityConstructor>(
|
|
255
295
|
options: Options<T>,
|
|
256
296
|
...selectors: Selector[] | string[]
|
|
257
|
-
): Promise<
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
297
|
+
): Promise<EntityInstanceType<T> | string | number | null> {
|
|
298
|
+
let data: any = null;
|
|
299
|
+
try {
|
|
300
|
+
// @ts-ignore: Implementation signatures of overloads are not externally visible.
|
|
301
|
+
data = (await this.getEntityData(options, ...selectors)) as
|
|
302
|
+
EntityJson<T> | string | number | null;
|
|
303
|
+
} catch (e: any) {
|
|
304
|
+
if (
|
|
305
|
+
this.returnNullOnNotFound &&
|
|
306
|
+
e instanceof ClientError &&
|
|
307
|
+
e.status === 404
|
|
308
|
+
) {
|
|
309
|
+
data = null;
|
|
310
|
+
} else {
|
|
311
|
+
throw e;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
264
314
|
|
|
265
315
|
if (options.return && options.return === 'count') {
|
|
266
316
|
return Number(data ?? 0) as number;
|
|
@@ -290,23 +340,23 @@ export default class Nymph {
|
|
|
290
340
|
): Promise<EntityJson<T> | null>;
|
|
291
341
|
public async getEntityData<T extends EntityConstructor = EntityConstructor>(
|
|
292
342
|
options: Options<T> & { return: 'count' },
|
|
293
|
-
guid: string
|
|
343
|
+
guid: string,
|
|
294
344
|
): Promise<number>;
|
|
295
345
|
public async getEntityData<T extends EntityConstructor = EntityConstructor>(
|
|
296
346
|
options: Options<T> & { return: 'guid' },
|
|
297
|
-
guid: string
|
|
347
|
+
guid: string,
|
|
298
348
|
): Promise<string | null>;
|
|
299
349
|
public async getEntityData<T extends EntityConstructor = EntityConstructor>(
|
|
300
350
|
options: Options<T>,
|
|
301
|
-
guid: string
|
|
351
|
+
guid: string,
|
|
302
352
|
): Promise<EntityJson<T> | null>;
|
|
303
353
|
public async getEntityData<T extends EntityConstructor = EntityConstructor>(
|
|
304
354
|
options: Options<T>,
|
|
305
355
|
...selectors: Selector[] | string[]
|
|
306
356
|
): Promise<EntityJson<T> | string | number | null> {
|
|
307
|
-
if (options.class
|
|
357
|
+
if (options.class instanceof Entity) {
|
|
308
358
|
throw new InvalidRequestError(
|
|
309
|
-
"You can't make REST requests with the base Entity class."
|
|
359
|
+
"You can't make REST requests with the base Entity class.",
|
|
310
360
|
);
|
|
311
361
|
}
|
|
312
362
|
// Set up options and selectors.
|
|
@@ -315,6 +365,7 @@ export default class Nymph {
|
|
|
315
365
|
}
|
|
316
366
|
const data = await requester.GET({
|
|
317
367
|
url: this.restUrl,
|
|
368
|
+
headers: { ...this.headers },
|
|
318
369
|
dataType: 'json',
|
|
319
370
|
data: {
|
|
320
371
|
action: 'entity',
|
|
@@ -342,25 +393,42 @@ export default class Nymph {
|
|
|
342
393
|
public async getEntities<T extends EntityConstructor = EntityConstructor>(
|
|
343
394
|
options: Options<T>,
|
|
344
395
|
...selectors: Selector[]
|
|
345
|
-
): Promise<
|
|
396
|
+
): Promise<EntityInstanceType<T>[]>;
|
|
346
397
|
public async getEntities<T extends EntityConstructor = EntityConstructor>(
|
|
347
398
|
options: Options<T>,
|
|
348
399
|
...selectors: Selector[]
|
|
349
|
-
): Promise<
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
400
|
+
): Promise<EntityInstanceType<T>[] | string[] | number> {
|
|
401
|
+
let data = null;
|
|
402
|
+
try {
|
|
403
|
+
data = await requester.GET({
|
|
404
|
+
url: this.restUrl,
|
|
405
|
+
headers: { ...this.headers },
|
|
406
|
+
dataType: 'json',
|
|
407
|
+
data: {
|
|
408
|
+
action: 'entities',
|
|
409
|
+
data: [
|
|
410
|
+
{ ...options, class: options.class.class },
|
|
411
|
+
...entityConstructorsToClassNames(selectors),
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
} catch (e: any) {
|
|
416
|
+
if (
|
|
417
|
+
this.returnNullOnNotFound &&
|
|
418
|
+
e instanceof ClientError &&
|
|
419
|
+
e.status === 404
|
|
420
|
+
) {
|
|
421
|
+
data = null;
|
|
422
|
+
} else {
|
|
423
|
+
throw e;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
361
426
|
|
|
362
427
|
if (options.return && options.return === 'count') {
|
|
363
|
-
return Number(data);
|
|
428
|
+
return Number(data ?? 0) as number;
|
|
429
|
+
}
|
|
430
|
+
if (data == null) {
|
|
431
|
+
return [];
|
|
364
432
|
}
|
|
365
433
|
if (options.return && options.return === 'guid') {
|
|
366
434
|
return data;
|
|
@@ -369,12 +437,12 @@ export default class Nymph {
|
|
|
369
437
|
}
|
|
370
438
|
|
|
371
439
|
public initEntity<T extends EntityConstructor = EntityConstructor>(
|
|
372
|
-
entityJSON: EntityJson<T
|
|
373
|
-
):
|
|
440
|
+
entityJSON: EntityJson<T>,
|
|
441
|
+
): EntityInstanceType<T> {
|
|
374
442
|
const EntityClass = this.getEntityClass(entityJSON.class);
|
|
375
443
|
if (!EntityClass) {
|
|
376
444
|
throw new ClassNotAvailableError(
|
|
377
|
-
entityJSON.class + ' class cannot be found.'
|
|
445
|
+
entityJSON.class + ' class cannot be found.',
|
|
378
446
|
);
|
|
379
447
|
}
|
|
380
448
|
let entity = EntityClass.factorySync();
|
|
@@ -382,30 +450,28 @@ export default class Nymph {
|
|
|
382
450
|
// Try to get it from cache.
|
|
383
451
|
const entityFromCache = this.cache.get(
|
|
384
452
|
EntityClass,
|
|
385
|
-
entityJSON.guid || ''
|
|
453
|
+
entityJSON.guid || '',
|
|
386
454
|
);
|
|
387
455
|
if (entityFromCache != null) {
|
|
388
|
-
entity = entityFromCache
|
|
456
|
+
entity = entityFromCache as EntityInstanceType<T>;
|
|
389
457
|
}
|
|
390
458
|
}
|
|
391
|
-
return entity.$init(entityJSON) as
|
|
459
|
+
return entity.$init(entityJSON) as EntityInstanceType<T>;
|
|
392
460
|
}
|
|
393
461
|
|
|
394
462
|
public getEntityFromCache<T extends EntityConstructor = EntityConstructor>(
|
|
395
463
|
EntityClass: EntityConstructor,
|
|
396
|
-
guid: string
|
|
397
|
-
):
|
|
464
|
+
guid: string,
|
|
465
|
+
): EntityInstanceType<T> | null {
|
|
398
466
|
if (!this.weakCache) {
|
|
399
467
|
return null;
|
|
400
468
|
}
|
|
401
|
-
return this.cache.get(EntityClass, guid) as
|
|
402
|
-
T['factorySync']
|
|
403
|
-
> | null;
|
|
469
|
+
return this.cache.get(EntityClass, guid) as EntityInstanceType<T> | null;
|
|
404
470
|
}
|
|
405
471
|
|
|
406
472
|
public setEntityToCache(
|
|
407
473
|
EntityClass: EntityConstructor,
|
|
408
|
-
entity: EntityInterface
|
|
474
|
+
entity: EntityInterface,
|
|
409
475
|
) {
|
|
410
476
|
if (!this.weakCache) {
|
|
411
477
|
return;
|
|
@@ -417,10 +483,7 @@ export default class Nymph {
|
|
|
417
483
|
if (Array.isArray(item)) {
|
|
418
484
|
// Recurse into lower arrays.
|
|
419
485
|
return item.map((entry) => this.initEntitiesFromData(entry)) as T;
|
|
420
|
-
} else if (
|
|
421
|
-
item instanceof Object &&
|
|
422
|
-
!(item instanceof this.getEntityClass('Entity'))
|
|
423
|
-
) {
|
|
486
|
+
} else if (item instanceof Object && !(item instanceof Entity)) {
|
|
424
487
|
if (
|
|
425
488
|
item.hasOwnProperty('class') &&
|
|
426
489
|
item.hasOwnProperty('guid') &&
|
|
@@ -444,10 +507,11 @@ export default class Nymph {
|
|
|
444
507
|
|
|
445
508
|
public async deleteEntity(
|
|
446
509
|
entity: EntityInterface | EntityInterface[],
|
|
447
|
-
_plural = false
|
|
510
|
+
_plural = false,
|
|
448
511
|
) {
|
|
449
512
|
return await requester.DELETE({
|
|
450
513
|
url: this.restUrl,
|
|
514
|
+
headers: { ...this.headers },
|
|
451
515
|
dataType: 'json',
|
|
452
516
|
data: {
|
|
453
517
|
action: _plural ? 'entities' : 'entity',
|
|
@@ -473,10 +537,11 @@ export default class Nymph {
|
|
|
473
537
|
entity: EntityInterface,
|
|
474
538
|
method: string,
|
|
475
539
|
params: any[],
|
|
476
|
-
stateless = false
|
|
540
|
+
stateless = false,
|
|
477
541
|
): Promise<ServerCallResponse> {
|
|
478
542
|
const data = await requester.POST({
|
|
479
543
|
url: this.restUrl,
|
|
544
|
+
headers: { ...this.headers },
|
|
480
545
|
dataType: 'json',
|
|
481
546
|
data: {
|
|
482
547
|
action: 'method',
|
|
@@ -498,10 +563,11 @@ export default class Nymph {
|
|
|
498
563
|
public async serverCallStatic(
|
|
499
564
|
className: string,
|
|
500
565
|
method: string,
|
|
501
|
-
params: any[]
|
|
566
|
+
params: any[],
|
|
502
567
|
): Promise<ServerCallStaticResponse> {
|
|
503
568
|
const data = await requester.POST({
|
|
504
569
|
url: this.restUrl,
|
|
570
|
+
headers: { ...this.headers },
|
|
505
571
|
dataType: 'json',
|
|
506
572
|
data: {
|
|
507
573
|
action: 'method',
|
|
@@ -517,19 +583,57 @@ export default class Nymph {
|
|
|
517
583
|
return this.initEntitiesFromData(data);
|
|
518
584
|
}
|
|
519
585
|
|
|
586
|
+
public async serverCallStaticIterator(
|
|
587
|
+
className: string,
|
|
588
|
+
method: string,
|
|
589
|
+
params: any[],
|
|
590
|
+
): Promise<AbortableAsyncIterator<ServerCallStaticResponse>> {
|
|
591
|
+
const iterable = await requester.POST_ITERATOR({
|
|
592
|
+
url: this.restUrl,
|
|
593
|
+
headers: { ...this.headers },
|
|
594
|
+
dataType: 'json',
|
|
595
|
+
data: {
|
|
596
|
+
action: 'method',
|
|
597
|
+
data: {
|
|
598
|
+
class: className,
|
|
599
|
+
static: true,
|
|
600
|
+
method: method,
|
|
601
|
+
iterator: true,
|
|
602
|
+
params: entitiesToReferences(entityConstructorsToClassNames(params)),
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
const that = this;
|
|
608
|
+
const iterator: AbortableAsyncIterator = {
|
|
609
|
+
abortController: iterable.abortController,
|
|
610
|
+
async *[Symbol.asyncIterator]() {
|
|
611
|
+
for await (let response of iterable) {
|
|
612
|
+
if (response instanceof Error) {
|
|
613
|
+
yield response;
|
|
614
|
+
} else {
|
|
615
|
+
yield that.initEntitiesFromData(response);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
return iterator;
|
|
622
|
+
}
|
|
623
|
+
|
|
520
624
|
public on<T extends EventType>(
|
|
521
625
|
event: T,
|
|
522
626
|
callback: T extends 'request'
|
|
523
627
|
? RequestCallback
|
|
524
628
|
: T extends 'response'
|
|
525
|
-
|
|
526
|
-
|
|
629
|
+
? ResponseCallback
|
|
630
|
+
: never,
|
|
527
631
|
) {
|
|
528
632
|
const prop = (event + 'Callbacks') as T extends 'request'
|
|
529
633
|
? 'requestCallbacks'
|
|
530
634
|
: T extends 'request'
|
|
531
|
-
|
|
532
|
-
|
|
635
|
+
? 'responseCallbacks'
|
|
636
|
+
: never;
|
|
533
637
|
if (!(prop in this)) {
|
|
534
638
|
throw new Error('Invalid event type.');
|
|
535
639
|
}
|
|
@@ -543,14 +647,14 @@ export default class Nymph {
|
|
|
543
647
|
callback: T extends 'request'
|
|
544
648
|
? RequestCallback
|
|
545
649
|
: T extends 'response'
|
|
546
|
-
|
|
547
|
-
|
|
650
|
+
? ResponseCallback
|
|
651
|
+
: never,
|
|
548
652
|
) {
|
|
549
653
|
const prop = (event + 'Callbacks') as T extends 'request'
|
|
550
654
|
? 'requestCallbacks'
|
|
551
655
|
: T extends 'request'
|
|
552
|
-
|
|
553
|
-
|
|
656
|
+
? 'responseCallbacks'
|
|
657
|
+
: never;
|
|
554
658
|
if (!(prop in this)) {
|
|
555
659
|
return false;
|
|
556
660
|
}
|
|
@@ -562,10 +666,6 @@ export default class Nymph {
|
|
|
562
666
|
}
|
|
563
667
|
return true;
|
|
564
668
|
}
|
|
565
|
-
|
|
566
|
-
public setXsrfToken(token: string | null) {
|
|
567
|
-
requester.setXsrfToken(token);
|
|
568
|
-
}
|
|
569
669
|
}
|
|
570
670
|
|
|
571
671
|
export class ClassNotAvailableError extends Error {
|