@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.
@@ -1,39 +1,40 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = __importDefault(require("express"));
7
- const driver_sqlite3_1 = __importDefault(require("@nymphjs/driver-sqlite3"));
8
- const nymph_1 = require("@nymphjs/nymph");
9
- const client_node_1 = require("@nymphjs/client-node");
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:5081/'],
15
+ entries: ['ws://localhost:5083/'],
20
16
  logger: () => { },
21
17
  };
22
- const nymphServer = new nymph_1.Nymph({}, new driver_sqlite3_1.default(sqliteConfig));
23
- const EmployeeModel = nymphServer.addEntityClass(testArtifacts_js_1.EmployeeModel);
24
- PubSub_1.default.initPublisher(pubSubConfig, nymphServer);
25
- const app = (0, express_1.default)();
26
- app.use((0, server_1.default)(nymphServer));
27
- const server = app.listen(5080);
28
- const pubsubServer = (0, index_1.default)(5081, pubSubConfig, nymphServer);
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:5080/',
31
- pubsubUrl: 'ws://localhost:5081/',
28
+ restUrl: 'http://localhost:5082/',
29
+ pubsubUrl: 'ws://localhost:5083/',
32
30
  noConsole: true,
31
+ WebSocket: ws.w3cwebsocket,
33
32
  };
34
- const nymph = new client_node_1.Nymph(nymphOptions);
35
- const pubsub = new client_node_1.PubSub(nymphOptions, nymph);
36
- const Employee = nymph.addEntityClass(testArtifacts_js_1.Employee);
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(true);
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(true);
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.class);
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.class);
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(true);
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(true);
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.class);
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.class);
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(true);
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(true);
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
- await new Promise((resolve) => {
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(true);
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
- await new Promise((resolve) => setTimeout(() => resolve(true), 10));
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(true);
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 = await createJane();
517
+ let jane;
415
518
  let entities = [];
416
- await new Promise((resolve) => setTimeout(() => resolve(true), 10));
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 (updated) {
429
- subscription.unsubscribe();
430
- resolve(true);
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 (Array.isArray(update)) {
433
- expect(update.length).toBeGreaterThan(0);
434
- updated = true;
435
- length = update.length;
436
- await jane.$delete();
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(entities.length).toEqual(length - 1);
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
- await new Promise((resolve) => setTimeout(() => resolve(true), 10));
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
- if ('removed' in update) {
457
- receivedRemove = true;
458
- }
459
- if ('added' in update) {
460
- receivedAdd = true;
461
- }
462
- if (receivedAdd && receivedRemove) {
463
- subscription.unsubscribe();
464
- resolve(true);
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(true);
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(true);
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 (resolve) => {
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
- resolve(true);
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(true);
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(true);
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(true);
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(true);
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(true);
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