@nymphjs/pubsub 1.0.0-beta.13 → 1.0.0-beta.130
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 +534 -0
- package/README.md +12 -10
- package/dist/PubSub.d.ts +77 -14
- package/dist/PubSub.js +548 -213
- package/dist/PubSub.js.map +1 -1
- package/dist/PubSub.test.js +265 -81
- package/dist/PubSub.test.js.map +1 -1
- package/dist/PubSub.types.d.ts +11 -2
- package/dist/PubSub.types.js +1 -2
- package/dist/conf/defaults.d.ts +1 -1
- package/dist/conf/defaults.js +4 -4
- package/dist/conf/defaults.js.map +1 -1
- package/dist/conf/index.d.ts +31 -2
- package/dist/conf/index.js +2 -8
- package/dist/conf/index.js.map +1 -1
- package/dist/createServer.d.ts +2 -2
- package/dist/createServer.js +14 -15
- package/dist/createServer.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +7 -27
- package/dist/index.js.map +1 -1
- package/jest.config.js +31 -5
- package/package.json +37 -28
- package/src/PubSub.test.ts +343 -137
- package/src/PubSub.ts +796 -481
- package/src/PubSub.types.ts +11 -6
- package/src/conf/defaults.ts +2 -2
- package/src/conf/index.ts +31 -2
- package/src/createServer.ts +8 -8
- package/src/index.ts +4 -4
- package/tsconfig.json +6 -3
- package/typedoc.json +4 -0
- package/dist/conf/d.d.ts +0 -7
- package/dist/conf/d.js +0 -3
- package/dist/conf/d.js.map +0 -1
- package/src/conf/d.ts +0 -30
package/dist/PubSub.test.js
CHANGED
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const server_1 = __importDefault(require("@nymphjs/server"));
|
|
11
|
-
const testArtifacts_js_1 = require("@nymphjs/server/dist/testArtifacts.js");
|
|
12
|
-
const index_1 = __importDefault(require("./index"));
|
|
13
|
-
const PubSub_1 = __importDefault(require("./PubSub"));
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import ws from 'websocket';
|
|
3
|
+
import SQLite3Driver from '@nymphjs/driver-sqlite3';
|
|
4
|
+
import { Nymph as NymphServer } from '@nymphjs/nymph';
|
|
5
|
+
import { Nymph, PubSub } from '@nymphjs/client';
|
|
6
|
+
import createRestServer from '@nymphjs/server';
|
|
7
|
+
import { EmployeeModel as EmployeeModelClass, Employee as EmployeeClass, RestrictedModel as RestrictedModelClass, Restricted as RestrictedClass, PubSubDisabledModel as PubSubDisabledModelClass, PubSubDisabled as PubSubDisabledClass, } from '@nymphjs/server/dist/testArtifacts.js';
|
|
8
|
+
import createServer from './index.js';
|
|
9
|
+
import PubSubServer from './PubSub.js';
|
|
14
10
|
const sqliteConfig = {
|
|
15
11
|
filename: ':memory:',
|
|
16
12
|
};
|
|
17
13
|
const pubSubConfig = {
|
|
18
14
|
originIsAllowed: () => true,
|
|
19
|
-
entries: ['ws://localhost:
|
|
15
|
+
entries: ['ws://localhost:5083/'],
|
|
20
16
|
logger: () => { },
|
|
21
17
|
};
|
|
22
|
-
const nymphServer = new
|
|
23
|
-
const EmployeeModel = nymphServer.addEntityClass(
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
18
|
+
const nymphServer = new NymphServer({}, new SQLite3Driver(sqliteConfig));
|
|
19
|
+
const EmployeeModel = nymphServer.addEntityClass(EmployeeModelClass);
|
|
20
|
+
const RestrictedModel = nymphServer.addEntityClass(RestrictedModelClass);
|
|
21
|
+
const PubSubDisabledModel = nymphServer.addEntityClass(PubSubDisabledModelClass);
|
|
22
|
+
const removePublisher = PubSubServer.initPublisher(pubSubConfig, nymphServer);
|
|
23
|
+
const app = express();
|
|
24
|
+
app.use(createRestServer(nymphServer));
|
|
25
|
+
const server = app.listen(5082);
|
|
26
|
+
const pubsubServer = createServer(5083, pubSubConfig, nymphServer);
|
|
29
27
|
const nymphOptions = {
|
|
30
|
-
restUrl: 'http://localhost:
|
|
31
|
-
pubsubUrl: 'ws://localhost:
|
|
28
|
+
restUrl: 'http://localhost:5082/',
|
|
29
|
+
pubsubUrl: 'ws://localhost:5083/',
|
|
32
30
|
noConsole: true,
|
|
31
|
+
WebSocket: ws.w3cwebsocket,
|
|
33
32
|
};
|
|
34
|
-
const nymph = new
|
|
35
|
-
const pubsub = new
|
|
36
|
-
const Employee = nymph.addEntityClass(
|
|
33
|
+
const nymph = new Nymph(nymphOptions);
|
|
34
|
+
const pubsub = new PubSub(nymphOptions, nymph);
|
|
35
|
+
const Employee = nymph.addEntityClass(EmployeeClass);
|
|
36
|
+
const Restricted = nymph.addEntityClass(RestrictedClass);
|
|
37
|
+
const PubSubDisabled = nymph.addEntityClass(PubSubDisabledClass);
|
|
37
38
|
describe('Nymph REST Server and Client', () => {
|
|
38
39
|
async function createJane() {
|
|
39
40
|
const jane = await Employee.factory();
|
|
@@ -95,7 +96,7 @@ describe('Nymph REST Server and Client', () => {
|
|
|
95
96
|
expect('added' in update && update.added).toEqual((await jane).guid);
|
|
96
97
|
expect('data' in update && update.data.guid).toEqual((await jane).guid);
|
|
97
98
|
subscription.unsubscribe();
|
|
98
|
-
resolve(
|
|
99
|
+
resolve();
|
|
99
100
|
}
|
|
100
101
|
else {
|
|
101
102
|
expect(update).toEqual([]);
|
|
@@ -123,13 +124,13 @@ describe('Nymph REST Server and Client', () => {
|
|
|
123
124
|
throw new Error('Update arrived before transaction committed.');
|
|
124
125
|
}
|
|
125
126
|
subscription.unsubscribe();
|
|
126
|
-
resolve(
|
|
127
|
+
resolve();
|
|
127
128
|
}
|
|
128
129
|
else {
|
|
129
130
|
expect(update).toEqual([]);
|
|
130
131
|
updated = true;
|
|
131
132
|
const tnymph = await nymphServer.startTransaction('steve');
|
|
132
|
-
const Employee = tnymph.getEntityClass(EmployeeModel
|
|
133
|
+
const Employee = tnymph.getEntityClass(EmployeeModel);
|
|
133
134
|
const steve = await Employee.factory();
|
|
134
135
|
steve.name = 'Steve Transaction';
|
|
135
136
|
steve.current = true;
|
|
@@ -170,7 +171,7 @@ describe('Nymph REST Server and Client', () => {
|
|
|
170
171
|
expect(update).toEqual([]);
|
|
171
172
|
updated = true;
|
|
172
173
|
const tnymph = await nymphServer.startTransaction('steve');
|
|
173
|
-
const Employee = tnymph.getEntityClass(EmployeeModel
|
|
174
|
+
const Employee = tnymph.getEntityClass(EmployeeModel);
|
|
174
175
|
const steve = await Employee.factory();
|
|
175
176
|
steve.name = 'Steve Rollback';
|
|
176
177
|
steve.current = true;
|
|
@@ -185,7 +186,7 @@ describe('Nymph REST Server and Client', () => {
|
|
|
185
186
|
await tnymph.rollback('steve');
|
|
186
187
|
await new Promise((res) => setTimeout(res, 600));
|
|
187
188
|
subscription.unsubscribe();
|
|
188
|
-
resolve(
|
|
189
|
+
resolve();
|
|
189
190
|
}
|
|
190
191
|
catch (e) {
|
|
191
192
|
console.error('Error creating entity: ', e);
|
|
@@ -213,14 +214,15 @@ describe('Nymph REST Server and Client', () => {
|
|
|
213
214
|
throw new Error('Update arrived before transaction committed.');
|
|
214
215
|
}
|
|
215
216
|
subscription.unsubscribe();
|
|
216
|
-
resolve(
|
|
217
|
+
resolve();
|
|
217
218
|
}
|
|
218
219
|
else {
|
|
219
220
|
expect(update).toEqual([]);
|
|
220
221
|
updated = true;
|
|
221
222
|
const tnymphTop = await nymphServer.startTransaction('steve-top');
|
|
223
|
+
// Start a transaction that ultimately gets rolled back.
|
|
222
224
|
const tnymphB = await tnymphTop.startTransaction('steve-b');
|
|
223
|
-
const EmployeeB = tnymphB.getEntityClass(EmployeeModel
|
|
225
|
+
const EmployeeB = tnymphB.getEntityClass(EmployeeModel);
|
|
224
226
|
const badSteve = await EmployeeB.factory();
|
|
225
227
|
badSteve.name = 'Steve Complex';
|
|
226
228
|
badSteve.current = true;
|
|
@@ -238,8 +240,9 @@ describe('Nymph REST Server and Client', () => {
|
|
|
238
240
|
console.error('Error creating entity: ', e);
|
|
239
241
|
throw e;
|
|
240
242
|
}
|
|
243
|
+
// Start a transaction that ultimately gets committed.
|
|
241
244
|
const tnymphA = await tnymphTop.startTransaction('steve-a');
|
|
242
|
-
const EmployeeA = tnymphA.getEntityClass(EmployeeModel
|
|
245
|
+
const EmployeeA = tnymphA.getEntityClass(EmployeeModel);
|
|
243
246
|
const goodSteve = await EmployeeA.factory();
|
|
244
247
|
goodSteve.name = 'Steve Complex';
|
|
245
248
|
goodSteve.current = true;
|
|
@@ -279,11 +282,12 @@ describe('Nymph REST Server and Client', () => {
|
|
|
279
282
|
pubsub.updateArray(entities, update);
|
|
280
283
|
if (mdate > 0 && (entities[0]?.mdate ?? -1) === mdate) {
|
|
281
284
|
subscription.unsubscribe();
|
|
282
|
-
resolve(
|
|
285
|
+
resolve();
|
|
283
286
|
}
|
|
284
287
|
else if (Array.isArray(update)) {
|
|
285
288
|
expect(update.length).toEqual(1);
|
|
286
289
|
expect(entities[0].salary).toEqual(8000000);
|
|
290
|
+
// Time for a raise!
|
|
287
291
|
jane.salary = (jane.salary ?? 0) + 1000000;
|
|
288
292
|
await jane.$save();
|
|
289
293
|
mdate = jane.mdate ?? 0;
|
|
@@ -310,11 +314,12 @@ describe('Nymph REST Server and Client', () => {
|
|
|
310
314
|
pubsub.updateArray(entities, update);
|
|
311
315
|
if (mdate > 0 && (entities[0]?.mdate ?? -1) === mdate) {
|
|
312
316
|
subscription.unsubscribe();
|
|
313
|
-
resolve(
|
|
317
|
+
resolve();
|
|
314
318
|
}
|
|
315
319
|
else if (Array.isArray(update)) {
|
|
316
320
|
expect(update.length).toEqual(1);
|
|
317
321
|
expect(entities[0].salary).toEqual(8000000);
|
|
322
|
+
// Time for a raise!
|
|
318
323
|
jane.salary = (jane.salary ?? 0) + 1000000;
|
|
319
324
|
await jane.$save();
|
|
320
325
|
mdate = jane.mdate ?? 0;
|
|
@@ -326,7 +331,14 @@ describe('Nymph REST Server and Client', () => {
|
|
|
326
331
|
it('notified of new match for qref query', async () => {
|
|
327
332
|
let [jane, john] = await createBossJane();
|
|
328
333
|
let entities = [];
|
|
329
|
-
|
|
334
|
+
// Create employees that matches qref to test when multiple things match.
|
|
335
|
+
let oldEmployee = await createJane();
|
|
336
|
+
oldEmployee.current = false;
|
|
337
|
+
await oldEmployee.$save();
|
|
338
|
+
let oldEmployee2 = await createJane();
|
|
339
|
+
oldEmployee2.current = false;
|
|
340
|
+
await oldEmployee2.$save();
|
|
341
|
+
expect(await new Promise((resolve) => {
|
|
330
342
|
if (jane.guid == null || john.guid == null) {
|
|
331
343
|
throw new Error('Entity is null.');
|
|
332
344
|
}
|
|
@@ -345,13 +357,100 @@ describe('Nymph REST Server and Client', () => {
|
|
|
345
357
|
}
|
|
346
358
|
else if (Array.isArray(update)) {
|
|
347
359
|
expect(update.length).toEqual(0);
|
|
360
|
+
// John gets fired.
|
|
348
361
|
john.current = false;
|
|
349
362
|
await john.$save();
|
|
350
363
|
}
|
|
351
364
|
});
|
|
352
|
-
});
|
|
365
|
+
})).toEqual(true);
|
|
353
366
|
expect(entities.length).toEqual(1);
|
|
354
367
|
});
|
|
368
|
+
it('notified of new match for qref query in transaction', async () => {
|
|
369
|
+
let entities = [];
|
|
370
|
+
const john = await EmployeeModel.factory();
|
|
371
|
+
john.name = 'John Der';
|
|
372
|
+
john.current = true;
|
|
373
|
+
john.salary = 8000000;
|
|
374
|
+
john.startDate = Date.now();
|
|
375
|
+
john.subordinates = [];
|
|
376
|
+
john.title = 'Junior Person';
|
|
377
|
+
try {
|
|
378
|
+
await john.$save();
|
|
379
|
+
}
|
|
380
|
+
catch (e) {
|
|
381
|
+
console.error('Error creating entity: ', e);
|
|
382
|
+
throw e;
|
|
383
|
+
}
|
|
384
|
+
const jane = await EmployeeModel.factory();
|
|
385
|
+
jane.name = 'Jane Doe';
|
|
386
|
+
jane.current = true;
|
|
387
|
+
jane.salary = 8000000;
|
|
388
|
+
jane.startDate = Date.now();
|
|
389
|
+
jane.subordinates = [john];
|
|
390
|
+
jane.title = 'Seniorer Person';
|
|
391
|
+
try {
|
|
392
|
+
await jane.$save();
|
|
393
|
+
}
|
|
394
|
+
catch (e) {
|
|
395
|
+
console.error('Error creating entity: ', e);
|
|
396
|
+
throw e;
|
|
397
|
+
}
|
|
398
|
+
async function createNewBoss() {
|
|
399
|
+
// Create employee that matches qref.
|
|
400
|
+
const tnymph = await nymphServer.startTransaction('qref-test');
|
|
401
|
+
const tnymphDeep = await tnymph.startTransaction('qref-deep-test');
|
|
402
|
+
const TEmployeeModel = tnymph.getEntityClass(EmployeeModel);
|
|
403
|
+
const newBoss = await TEmployeeModel.factory();
|
|
404
|
+
newBoss.name = 'Jill Doe';
|
|
405
|
+
newBoss.current = false;
|
|
406
|
+
newBoss.salary = 8000000;
|
|
407
|
+
newBoss.startDate = Date.now();
|
|
408
|
+
newBoss.subordinates = [john];
|
|
409
|
+
newBoss.title = 'Seniorer Person';
|
|
410
|
+
try {
|
|
411
|
+
await newBoss.$save();
|
|
412
|
+
}
|
|
413
|
+
catch (e) {
|
|
414
|
+
console.error('Error creating entity: ', e);
|
|
415
|
+
throw e;
|
|
416
|
+
}
|
|
417
|
+
newBoss.current = true;
|
|
418
|
+
try {
|
|
419
|
+
await newBoss.$save();
|
|
420
|
+
}
|
|
421
|
+
catch (e) {
|
|
422
|
+
console.error('Error creating entity: ', e);
|
|
423
|
+
throw e;
|
|
424
|
+
}
|
|
425
|
+
await tnymphDeep.commit('qref-deep-test');
|
|
426
|
+
await tnymph.commit('qref-test');
|
|
427
|
+
}
|
|
428
|
+
expect(await new Promise((resolve) => {
|
|
429
|
+
if (jane.guid == null || john.guid == null) {
|
|
430
|
+
throw new Error('Entity is null.');
|
|
431
|
+
}
|
|
432
|
+
const subscription = pubsub.subscribeEntities({ class: Employee }, {
|
|
433
|
+
type: '&',
|
|
434
|
+
truthy: 'current',
|
|
435
|
+
qref: [
|
|
436
|
+
'subordinates',
|
|
437
|
+
[{ class: Employee }, { type: '&', guid: john.guid }],
|
|
438
|
+
],
|
|
439
|
+
})(async (update) => {
|
|
440
|
+
pubsub.updateArray(entities, update);
|
|
441
|
+
if (Array.isArray(update)) {
|
|
442
|
+
expect(entities.length).toEqual(1);
|
|
443
|
+
await createNewBoss();
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
expect(entities.length).toEqual(2);
|
|
447
|
+
subscription.unsubscribe();
|
|
448
|
+
resolve(true);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
})).toEqual(true);
|
|
452
|
+
expect(entities.length).toEqual(2);
|
|
453
|
+
});
|
|
355
454
|
it('notified of removed match for qref query', async () => {
|
|
356
455
|
let [jane, john] = await createBossJane();
|
|
357
456
|
let entities = [];
|
|
@@ -370,10 +469,11 @@ describe('Nymph REST Server and Client', () => {
|
|
|
370
469
|
pubsub.updateArray(entities, update);
|
|
371
470
|
if (!entities.length) {
|
|
372
471
|
subscription.unsubscribe();
|
|
373
|
-
resolve(
|
|
472
|
+
resolve();
|
|
374
473
|
}
|
|
375
474
|
else if (Array.isArray(update)) {
|
|
376
475
|
expect(update.length).toEqual(1);
|
|
476
|
+
// John gets fired.
|
|
377
477
|
john.current = false;
|
|
378
478
|
await john.$save();
|
|
379
479
|
}
|
|
@@ -384,8 +484,10 @@ describe('Nymph REST Server and Client', () => {
|
|
|
384
484
|
it('receives correct number of updates', async () => {
|
|
385
485
|
let jane = await createJane();
|
|
386
486
|
let entities = [];
|
|
387
|
-
|
|
487
|
+
// Wait for change to propagate. (Only needed since we're not going across network.)
|
|
488
|
+
await new Promise((resolve) => setTimeout(() => resolve(), 10));
|
|
388
489
|
await new Promise((resolve) => {
|
|
490
|
+
// Should only receive 1 update, since we waited.
|
|
389
491
|
let updated = false;
|
|
390
492
|
if (jane.guid == null) {
|
|
391
493
|
throw new Error('Entity is null.');
|
|
@@ -397,12 +499,13 @@ describe('Nymph REST Server and Client', () => {
|
|
|
397
499
|
pubsub.updateArray(entities, update);
|
|
398
500
|
if (updated) {
|
|
399
501
|
subscription.unsubscribe();
|
|
400
|
-
resolve(
|
|
502
|
+
resolve();
|
|
401
503
|
}
|
|
402
504
|
else if (Array.isArray(update)) {
|
|
403
505
|
expect(update.length).toEqual(1);
|
|
404
506
|
expect(entities[0].salary).toEqual(8000000);
|
|
405
507
|
updated = true;
|
|
508
|
+
// Time for a raise!
|
|
406
509
|
jane.salary = (jane.salary ?? 0) + 1000000;
|
|
407
510
|
await jane.$save();
|
|
408
511
|
}
|
|
@@ -411,39 +514,39 @@ describe('Nymph REST Server and Client', () => {
|
|
|
411
514
|
expect(entities[0].salary).toEqual(9000000);
|
|
412
515
|
});
|
|
413
516
|
it('notified of entity delete', async () => {
|
|
414
|
-
let jane
|
|
517
|
+
let jane;
|
|
415
518
|
let entities = [];
|
|
416
|
-
|
|
417
|
-
let length = -1;
|
|
519
|
+
let removed = false;
|
|
418
520
|
await new Promise((resolve) => {
|
|
419
|
-
let updated = false;
|
|
420
|
-
if (jane.guid == null) {
|
|
421
|
-
throw new Error('Entity is null.');
|
|
422
|
-
}
|
|
423
521
|
const subscription = pubsub.subscribeEntities({ class: Employee }, {
|
|
424
522
|
type: '&',
|
|
425
523
|
equal: ['name', 'Jane Doe'],
|
|
426
524
|
})(async (update) => {
|
|
427
525
|
pubsub.updateArray(entities, update);
|
|
428
|
-
if (
|
|
429
|
-
|
|
430
|
-
|
|
526
|
+
if (Array.isArray(update)) {
|
|
527
|
+
jane = await createJane();
|
|
528
|
+
if (jane.guid == null) {
|
|
529
|
+
throw new Error('Entity is null.');
|
|
530
|
+
}
|
|
431
531
|
}
|
|
432
|
-
else if (
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
532
|
+
else if ('added' in update) {
|
|
533
|
+
await entities.find((e) => e.guid === update.added)?.$delete();
|
|
534
|
+
}
|
|
535
|
+
else if ('removed' in update && update.removed === jane.guid) {
|
|
536
|
+
subscription.unsubscribe();
|
|
537
|
+
removed = true;
|
|
538
|
+
resolve();
|
|
437
539
|
}
|
|
438
540
|
});
|
|
439
541
|
});
|
|
440
|
-
expect(
|
|
542
|
+
expect(removed).toBeTruthy();
|
|
441
543
|
});
|
|
442
544
|
it('entire match is updated', async () => {
|
|
443
545
|
let jane;
|
|
444
546
|
let entities = [];
|
|
445
547
|
await createJane();
|
|
446
|
-
|
|
548
|
+
// Wait for change to propagate. (Only needed since we're not going across network.)
|
|
549
|
+
await new Promise((resolve) => setTimeout(() => resolve(), 10));
|
|
447
550
|
await new Promise((resolve) => {
|
|
448
551
|
let receivedRemove = false;
|
|
449
552
|
let receivedAdd = false;
|
|
@@ -453,15 +556,20 @@ describe('Nymph REST Server and Client', () => {
|
|
|
453
556
|
})(async (update) => {
|
|
454
557
|
pubsub.updateArray(entities, update);
|
|
455
558
|
if (jane) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
559
|
+
const updates = 'multiple' in update && update.multiple
|
|
560
|
+
? update.messages
|
|
561
|
+
: [update];
|
|
562
|
+
for (let curUpdate of updates) {
|
|
563
|
+
if ('removed' in curUpdate) {
|
|
564
|
+
receivedRemove = true;
|
|
565
|
+
}
|
|
566
|
+
if ('added' in curUpdate) {
|
|
567
|
+
receivedAdd = true;
|
|
568
|
+
}
|
|
569
|
+
if (receivedAdd && receivedRemove) {
|
|
570
|
+
subscription.unsubscribe();
|
|
571
|
+
resolve();
|
|
572
|
+
}
|
|
465
573
|
}
|
|
466
574
|
}
|
|
467
575
|
else if (Array.isArray(update)) {
|
|
@@ -478,9 +586,10 @@ describe('Nymph REST Server and Client', () => {
|
|
|
478
586
|
await new Promise(async (resolve) => {
|
|
479
587
|
let mdate = 0;
|
|
480
588
|
const subscription = pubsub.subscribeWith(jane, async () => {
|
|
589
|
+
expect(jane.guid).not.toBeNull();
|
|
481
590
|
if (mdate > 0 && (jane.mdate ?? -1) === mdate) {
|
|
482
591
|
subscription.unsubscribe();
|
|
483
|
-
resolve(
|
|
592
|
+
resolve();
|
|
484
593
|
}
|
|
485
594
|
});
|
|
486
595
|
if (jane.guid == null) {
|
|
@@ -489,18 +598,75 @@ describe('Nymph REST Server and Client', () => {
|
|
|
489
598
|
expect(jane.salary).toEqual(8000000);
|
|
490
599
|
const janeDupe = await Employee.factory(jane.guid);
|
|
491
600
|
expect(janeDupe.salary).toEqual(8000000);
|
|
601
|
+
// Time for a raise!
|
|
492
602
|
janeDupe.salary = (janeDupe.salary ?? 0) + 1000000;
|
|
493
603
|
await janeDupe.$save();
|
|
494
604
|
mdate = janeDupe.mdate ?? 0;
|
|
495
605
|
});
|
|
496
606
|
expect(jane.salary).toEqual(9000000);
|
|
497
607
|
});
|
|
608
|
+
it("doesn't allow subscription of a restricted entity class", async () => {
|
|
609
|
+
let receivedBadUpdate = false;
|
|
610
|
+
let error = null;
|
|
611
|
+
await new Promise((resolve) => {
|
|
612
|
+
pubsub.subscribeEntities({ class: Restricted }, {
|
|
613
|
+
type: '&',
|
|
614
|
+
equal: ['name', 'Jane Doe'],
|
|
615
|
+
})(async () => {
|
|
616
|
+
receivedBadUpdate = true;
|
|
617
|
+
resolve();
|
|
618
|
+
}, (e) => {
|
|
619
|
+
error = e;
|
|
620
|
+
resolve();
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
expect(receivedBadUpdate).toEqual(false);
|
|
624
|
+
expect(error).toEqual('Not accessible.');
|
|
625
|
+
});
|
|
626
|
+
it("doesn't notify of new pubsub disabled entity class", async () => {
|
|
627
|
+
let receivedBadUpdate = false;
|
|
628
|
+
await new Promise(async (resolve) => {
|
|
629
|
+
const subscription = await new Promise(async (resolve) => {
|
|
630
|
+
let updated = false;
|
|
631
|
+
const subscription = pubsub.subscribeEntities({
|
|
632
|
+
class: PubSubDisabled,
|
|
633
|
+
})(async (update) => {
|
|
634
|
+
if (updated) {
|
|
635
|
+
receivedBadUpdate = true;
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
expect(update).toEqual([]);
|
|
639
|
+
updated = true;
|
|
640
|
+
try {
|
|
641
|
+
const entity = await PubSubDisabled.factory();
|
|
642
|
+
entity.name = 'Someone';
|
|
643
|
+
try {
|
|
644
|
+
await entity.$save();
|
|
645
|
+
}
|
|
646
|
+
catch (e) {
|
|
647
|
+
throw new Error("Couldn't save.");
|
|
648
|
+
}
|
|
649
|
+
resolve(subscription);
|
|
650
|
+
}
|
|
651
|
+
catch (e) {
|
|
652
|
+
console.error('Error creating entity: ', e);
|
|
653
|
+
throw e;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
});
|
|
658
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
659
|
+
subscription.unsubscribe();
|
|
660
|
+
resolve();
|
|
661
|
+
});
|
|
662
|
+
expect(receivedBadUpdate).toEqual(false);
|
|
663
|
+
});
|
|
498
664
|
it('new uid', async () => {
|
|
499
665
|
await new Promise(async (resolve) => {
|
|
500
666
|
const subscription = pubsub.subscribeUID('testNewUID')(async (value) => {
|
|
501
667
|
expect(value).toEqual(directValue);
|
|
502
668
|
subscription.unsubscribe();
|
|
503
|
-
resolve(
|
|
669
|
+
resolve();
|
|
504
670
|
}, (err) => {
|
|
505
671
|
expect(err.status).toEqual(404);
|
|
506
672
|
});
|
|
@@ -508,20 +674,24 @@ describe('Nymph REST Server and Client', () => {
|
|
|
508
674
|
});
|
|
509
675
|
});
|
|
510
676
|
it('increasing uids', async () => {
|
|
511
|
-
await new Promise(async (
|
|
677
|
+
await new Promise(async (finalResolve) => {
|
|
512
678
|
let receivedFirst = false;
|
|
513
679
|
let lastUpdate = 0;
|
|
680
|
+
// Don't go too fast.
|
|
681
|
+
let { promise, resolve } = Promise.withResolvers();
|
|
514
682
|
const subscription = pubsub.subscribeUID('testIncUID')(async (value) => {
|
|
515
683
|
if (!receivedFirst) {
|
|
516
684
|
receivedFirst = true;
|
|
517
685
|
expect(value).toBeNull();
|
|
686
|
+
resolve();
|
|
518
687
|
return;
|
|
519
688
|
}
|
|
520
689
|
expect(value).toEqual(lastUpdate + 1);
|
|
521
690
|
lastUpdate = value;
|
|
691
|
+
resolve();
|
|
522
692
|
if (value == 100) {
|
|
523
693
|
subscription.unsubscribe();
|
|
524
|
-
|
|
694
|
+
finalResolve();
|
|
525
695
|
}
|
|
526
696
|
}, (err) => {
|
|
527
697
|
expect(err.status).toEqual(404);
|
|
@@ -529,6 +699,8 @@ describe('Nymph REST Server and Client', () => {
|
|
|
529
699
|
await nymph.deleteUID('testIncUID');
|
|
530
700
|
let directValue = -1;
|
|
531
701
|
while (directValue < 100) {
|
|
702
|
+
await promise;
|
|
703
|
+
({ promise, resolve } = Promise.withResolvers());
|
|
532
704
|
directValue = await nymph.newUID('testIncUID');
|
|
533
705
|
}
|
|
534
706
|
});
|
|
@@ -538,7 +710,7 @@ describe('Nymph REST Server and Client', () => {
|
|
|
538
710
|
const subscription = pubsub.subscribeUID('testSetUID')(async (value) => {
|
|
539
711
|
expect(value).toEqual(123);
|
|
540
712
|
subscription.unsubscribe();
|
|
541
|
-
resolve(
|
|
713
|
+
resolve();
|
|
542
714
|
}, (err) => {
|
|
543
715
|
expect(err.status).toEqual(404);
|
|
544
716
|
});
|
|
@@ -553,9 +725,9 @@ describe('Nymph REST Server and Client', () => {
|
|
|
553
725
|
expect(event).toEqual('renameUID');
|
|
554
726
|
expect(value).toEqual(null);
|
|
555
727
|
subscription.unsubscribe();
|
|
556
|
-
resolve(
|
|
728
|
+
resolve();
|
|
557
729
|
}
|
|
558
|
-
else {
|
|
730
|
+
else if (event === 'setUID') {
|
|
559
731
|
expect(value).toEqual(456);
|
|
560
732
|
updated = true;
|
|
561
733
|
}
|
|
@@ -572,7 +744,7 @@ describe('Nymph REST Server and Client', () => {
|
|
|
572
744
|
expect(event).toEqual('setUID');
|
|
573
745
|
expect(value).toEqual(456);
|
|
574
746
|
subscription.unsubscribe();
|
|
575
|
-
resolve(
|
|
747
|
+
resolve();
|
|
576
748
|
}, (err) => {
|
|
577
749
|
expect(err.status).toEqual(404);
|
|
578
750
|
});
|
|
@@ -588,28 +760,40 @@ describe('Nymph REST Server and Client', () => {
|
|
|
588
760
|
if (updated && event === 'deleteUID') {
|
|
589
761
|
expect(value).toEqual(null);
|
|
590
762
|
subscription.unsubscribe();
|
|
591
|
-
resolve(
|
|
763
|
+
resolve();
|
|
592
764
|
}
|
|
593
765
|
else {
|
|
594
766
|
expect(value).toEqual(789);
|
|
595
767
|
updated = true;
|
|
768
|
+
await nymph.deleteUID('testDeleteUID');
|
|
596
769
|
}
|
|
597
770
|
}, (err) => {
|
|
598
771
|
expect(err.status).toEqual(404);
|
|
599
772
|
});
|
|
600
|
-
await nymph.deleteUID('testDeleteUID');
|
|
601
773
|
});
|
|
602
774
|
});
|
|
775
|
+
beforeEach(async () => {
|
|
776
|
+
pubsub.connect();
|
|
777
|
+
while (!pubsub.isConnectionOpen()) {
|
|
778
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
779
|
+
}
|
|
780
|
+
});
|
|
603
781
|
afterAll(async () => {
|
|
782
|
+
// Don't publish anything after the tests.
|
|
783
|
+
removePublisher();
|
|
784
|
+
// Avoid jest open handle errors.
|
|
604
785
|
const closed = new Promise((resolve) => {
|
|
605
786
|
pubsub.on('disconnect', () => {
|
|
606
|
-
resolve(
|
|
787
|
+
resolve();
|
|
607
788
|
});
|
|
608
789
|
});
|
|
609
|
-
pubsub.close();
|
|
790
|
+
pubsub.close(); // close PubSub client.
|
|
610
791
|
await closed;
|
|
611
|
-
pubsubServer.close();
|
|
612
|
-
server.close();
|
|
792
|
+
pubsubServer.close(); // close PubSub server.
|
|
793
|
+
server.close(); // close REST server.
|
|
794
|
+
// Wait for the next event loop to prevent websocket importing something
|
|
795
|
+
// after jest teardown.
|
|
796
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
613
797
|
});
|
|
614
798
|
});
|
|
615
799
|
//# sourceMappingURL=PubSub.test.js.map
|