@nymphjs/pubsub 1.0.0-beta.0 → 1.0.0-beta.2

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/dist/PubSub.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const nymph_1 = require("@nymphjs/nymph");
13
4
  const websocket_1 = require("websocket");
@@ -15,13 +6,13 @@ const lodash_1 = require("lodash");
15
6
  const conf_1 = require("./conf");
16
7
  class PubSub {
17
8
  static initPublisher(config, nymph) {
18
- const configWithDefaults = Object.assign(Object.assign({}, conf_1.ConfigDefaults), config);
19
- nymph.on('beforeSaveEntity', (nymph, entity) => {
9
+ const configWithDefaults = { ...conf_1.ConfigDefaults, ...config };
10
+ nymph.on('beforeSaveEntity', async (nymph, entity) => {
20
11
  const guid = entity.guid;
21
12
  const etype = entity.constructor.ETYPE;
22
- const off = nymph.on('afterSaveEntity', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
13
+ const off = nymph.on('afterSaveEntity', async (_nymph, result) => {
23
14
  off();
24
- if (!(yield result)) {
15
+ if (!(await result)) {
25
16
  return;
26
17
  }
27
18
  this.publish(JSON.stringify({
@@ -31,14 +22,14 @@ class PubSub {
31
22
  entity: entity.toJSON(),
32
23
  etype: etype,
33
24
  }), configWithDefaults);
34
- }));
25
+ });
35
26
  });
36
- nymph.on('beforeDeleteEntity', (nymph, entity) => {
27
+ nymph.on('beforeDeleteEntity', async (nymph, entity) => {
37
28
  const guid = entity.guid;
38
29
  const etype = entity.constructor.ETYPE;
39
- const off = nymph.on('afterDeleteEntity', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
30
+ const off = nymph.on('afterDeleteEntity', async (_nymph, result) => {
40
31
  off();
41
- if (!(yield result)) {
32
+ if (!(await result)) {
42
33
  return;
43
34
  }
44
35
  this.publish(JSON.stringify({
@@ -47,14 +38,14 @@ class PubSub {
47
38
  guid: guid,
48
39
  etype: etype,
49
40
  }), configWithDefaults);
50
- }));
41
+ });
51
42
  });
52
- nymph.on('beforeDeleteEntityByID', (nymph, guid, className) => {
43
+ nymph.on('beforeDeleteEntityByID', async (nymph, guid, className) => {
53
44
  try {
54
- const etype = nymph.getEntityClass(className !== null && className !== void 0 ? className : 'Entity').ETYPE;
55
- const off = nymph.on('afterDeleteEntityByID', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
45
+ const etype = nymph.getEntityClass(className ?? 'Entity').ETYPE;
46
+ const off = nymph.on('afterDeleteEntityByID', async (_nymph, result) => {
56
47
  off();
57
- if (!(yield result)) {
48
+ if (!(await result)) {
58
49
  return;
59
50
  }
60
51
  this.publish(JSON.stringify({
@@ -63,16 +54,16 @@ class PubSub {
63
54
  guid: guid,
64
55
  etype: etype,
65
56
  }), configWithDefaults);
66
- }));
57
+ });
67
58
  }
68
59
  catch (e) {
69
60
  return;
70
61
  }
71
62
  });
72
- nymph.on('beforeNewUID', (nymph, name) => {
73
- const off = nymph.on('afterNewUID', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
63
+ nymph.on('beforeNewUID', async (nymph, name) => {
64
+ const off = nymph.on('afterNewUID', async (_nymph, result) => {
74
65
  off();
75
- const value = yield result;
66
+ const value = await result;
76
67
  if (value == null) {
77
68
  return;
78
69
  }
@@ -82,12 +73,12 @@ class PubSub {
82
73
  name: name,
83
74
  value: value,
84
75
  }), configWithDefaults);
85
- }));
76
+ });
86
77
  });
87
- nymph.on('beforeSetUID', (nymph, name, value) => {
88
- const off = nymph.on('afterSetUID', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
78
+ nymph.on('beforeSetUID', async (nymph, name, value) => {
79
+ const off = nymph.on('afterSetUID', async (_nymph, result) => {
89
80
  off();
90
- if (!(yield result)) {
81
+ if (!(await result)) {
91
82
  return;
92
83
  }
93
84
  this.publish(JSON.stringify({
@@ -96,12 +87,12 @@ class PubSub {
96
87
  name: name,
97
88
  value: value,
98
89
  }), configWithDefaults);
99
- }));
90
+ });
100
91
  });
101
- nymph.on('beforeRenameUID', (nymph, oldName, newName) => {
102
- const off = nymph.on('afterRenameUID', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
92
+ nymph.on('beforeRenameUID', async (nymph, oldName, newName) => {
93
+ const off = nymph.on('afterRenameUID', async (_nymph, result) => {
103
94
  off();
104
- if (!(yield result)) {
95
+ if (!(await result)) {
105
96
  return;
106
97
  }
107
98
  this.publish(JSON.stringify({
@@ -110,12 +101,12 @@ class PubSub {
110
101
  oldName: oldName,
111
102
  newName: newName,
112
103
  }), configWithDefaults);
113
- }));
104
+ });
114
105
  });
115
- nymph.on('beforeDeleteUID', (nymph, name) => {
116
- const off = nymph.on('afterDeleteUID', (_nymph, result) => __awaiter(this, void 0, void 0, function* () {
106
+ nymph.on('beforeDeleteUID', async (nymph, name) => {
107
+ const off = nymph.on('afterDeleteUID', async (_nymph, result) => {
117
108
  off();
118
- if (!(yield result)) {
109
+ if (!(await result)) {
119
110
  return;
120
111
  }
121
112
  this.publish(JSON.stringify({
@@ -123,12 +114,11 @@ class PubSub {
123
114
  event: 'deleteUID',
124
115
  name: name,
125
116
  }), configWithDefaults);
126
- }));
117
+ });
127
118
  });
128
119
  }
129
120
  static publish(message, config) {
130
- var _a;
131
- for (let host of (_a = config.entries) !== null && _a !== void 0 ? _a : []) {
121
+ for (let host of config.entries ?? []) {
132
122
  const client = new websocket_1.client();
133
123
  client.on('connectFailed', (error) => {
134
124
  if (config.logger) {
@@ -154,7 +144,7 @@ class PubSub {
154
144
  this.querySubs = {};
155
145
  this.uidSubs = {};
156
146
  this.nymph = nymph;
157
- this.config = Object.assign(Object.assign({}, conf_1.ConfigDefaults), config);
147
+ this.config = { ...conf_1.ConfigDefaults, ...config };
158
148
  this.server = server;
159
149
  this.server.on('request', this.handleRequest.bind(this));
160
150
  }
@@ -179,29 +169,27 @@ class PubSub {
179
169
  this.onClose(connection, description);
180
170
  });
181
171
  }
182
- onMessage(from, msg) {
183
- return __awaiter(this, void 0, void 0, function* () {
184
- if (msg.type !== 'utf8') {
185
- throw new Error("This server doesn't accept binary messages.");
186
- }
187
- const data = JSON.parse(msg.utf8Data);
188
- if (!data.action ||
189
- ['authenticate', 'subscribe', 'unsubscribe', 'publish'].indexOf(data.action) === -1) {
190
- return;
191
- }
192
- switch (data.action) {
193
- case 'authenticate':
194
- this.handleAuthentication(from, data);
195
- break;
196
- case 'subscribe':
197
- case 'unsubscribe':
198
- yield this.handleSubscription(from, data);
199
- break;
200
- case 'publish':
201
- yield this.handlePublish(from, msg, data);
202
- break;
203
- }
204
- });
172
+ async onMessage(from, msg) {
173
+ if (msg.type !== 'utf8') {
174
+ throw new Error("This server doesn't accept binary messages.");
175
+ }
176
+ const data = JSON.parse(msg.utf8Data);
177
+ if (!data.action ||
178
+ ['authenticate', 'subscribe', 'unsubscribe', 'publish'].indexOf(data.action) === -1) {
179
+ return;
180
+ }
181
+ switch (data.action) {
182
+ case 'authenticate':
183
+ this.handleAuthentication(from, data);
184
+ break;
185
+ case 'subscribe':
186
+ case 'unsubscribe':
187
+ await this.handleSubscription(from, data);
188
+ break;
189
+ case 'publish':
190
+ await this.handlePublish(from, msg, data);
191
+ break;
192
+ }
205
193
  }
206
194
  onClose(conn, description) {
207
195
  this.config.logger('log', new Date().toISOString(), `Client skedaddled. (${description}, ${conn.remoteAddress})`);
@@ -280,410 +268,404 @@ class PubSub {
280
268
  this.sessions.delete(from);
281
269
  }
282
270
  }
283
- handleSubscription(from, data) {
284
- return __awaiter(this, void 0, void 0, function* () {
285
- if ('query' in data && data.query != null) {
286
- yield this.handleSubscriptionQuery(from, data);
271
+ async handleSubscription(from, data) {
272
+ if ('query' in data && data.query != null) {
273
+ await this.handleSubscriptionQuery(from, data);
274
+ }
275
+ else if ('uid' in data &&
276
+ data.uid != null &&
277
+ typeof data.uid == 'string') {
278
+ await this.handleSubscriptionUid(from, data);
279
+ }
280
+ }
281
+ async handleSubscriptionQuery(from, data, qrefParent) {
282
+ let args;
283
+ let EntityClass;
284
+ try {
285
+ args = JSON.parse(data.query);
286
+ EntityClass = this.nymph.getEntityClass(args[0].class);
287
+ }
288
+ catch (e) {
289
+ return;
290
+ }
291
+ const etype = EntityClass.ETYPE;
292
+ const serialArgs = JSON.stringify(args);
293
+ const [clientOptions, ...selectors] = args;
294
+ const options = {
295
+ ...clientOptions,
296
+ class: EntityClass,
297
+ return: 'guid',
298
+ source: 'client',
299
+ };
300
+ const qrefQueries = this.findQRefQueries(clientOptions, ...selectors);
301
+ if (data.action === 'subscribe') {
302
+ for (const qrefQuery of qrefQueries) {
303
+ await this.handleSubscriptionQuery(from, {
304
+ action: 'subscribe',
305
+ query: JSON.stringify(qrefQuery),
306
+ }, {
307
+ etype,
308
+ query: serialArgs,
309
+ });
287
310
  }
288
- else if ('uid' in data &&
289
- data.uid != null &&
290
- typeof data.uid == 'string') {
291
- yield this.handleSubscriptionUid(from, data);
311
+ if (!(etype in this.querySubs)) {
312
+ this.querySubs[etype] = {};
292
313
  }
293
- });
294
- }
295
- handleSubscriptionQuery(from, data, qrefParent) {
296
- return __awaiter(this, void 0, void 0, function* () {
297
- let args;
298
- let EntityClass;
299
- try {
300
- args = JSON.parse(data.query);
301
- EntityClass = this.nymph.getEntityClass(args[0].class);
314
+ if (!(serialArgs in this.querySubs[etype])) {
315
+ this.querySubs[etype][serialArgs] = new Map();
302
316
  }
303
- catch (e) {
304
- return;
317
+ let token = null;
318
+ if (this.sessions.has(from)) {
319
+ token = this.sessions.get(from);
305
320
  }
306
- const etype = EntityClass.ETYPE;
307
- const serialArgs = JSON.stringify(args);
308
- const [clientOptions, ...selectors] = args;
309
- const options = Object.assign(Object.assign({}, clientOptions), { class: EntityClass, return: 'guid', source: 'client' });
310
- const qrefQueries = this.findQRefQueries(clientOptions, ...selectors);
311
- if (data.action === 'subscribe') {
312
- for (const qrefQuery of qrefQueries) {
313
- yield this.handleSubscriptionQuery(from, {
314
- action: 'subscribe',
315
- query: JSON.stringify(qrefQuery),
316
- }, {
317
- etype,
318
- query: serialArgs,
319
- });
320
- }
321
- if (!(etype in this.querySubs)) {
322
- this.querySubs[etype] = {};
323
- }
324
- if (!(serialArgs in this.querySubs[etype])) {
325
- this.querySubs[etype][serialArgs] = new Map();
326
- }
327
- let token = null;
328
- if (this.sessions.has(from)) {
329
- token = this.sessions.get(from);
330
- }
331
- const nymph = this.nymph.clone();
332
- if (nymph.tilmeld != null && token != null) {
333
- const user = yield nymph.tilmeld.extractToken(token);
334
- if (user) {
335
- nymph.tilmeld.fillSession(user);
336
- }
337
- }
338
- const existingSub = this.querySubs[etype][serialArgs].get(from);
339
- if (existingSub) {
340
- if (qrefParent) {
341
- existingSub.qrefParents.push(qrefParent);
342
- }
343
- if (!qrefParent && !existingSub.direct) {
344
- existingSub.direct = true;
345
- }
346
- if (data.count && !existingSub.count) {
347
- existingSub.count = true;
348
- }
349
- }
350
- else {
351
- this.querySubs[etype][serialArgs].set(from, {
352
- current: yield nymph.getEntities(options, ...selectors),
353
- query: data.query,
354
- qrefParents: qrefParent ? [qrefParent] : [],
355
- direct: !qrefParent,
356
- count: !!data.count,
357
- });
358
- }
359
- if (nymph.tilmeld != null && token != null) {
360
- nymph.tilmeld.clearSession();
361
- }
362
- this.config.logger('log', new Date().toISOString(), `Client subscribed to a query! (${serialArgs}, ${from.remoteAddress})`);
363
- if (this.config.broadcastCounts) {
364
- const count = this.querySubs[etype][serialArgs].size;
365
- for (let key of this.querySubs[etype][serialArgs].keys()) {
366
- const curData = this.querySubs[etype][serialArgs].get(key);
367
- if (curData && curData.count) {
368
- key.sendUTF(JSON.stringify({
369
- query: curData.query,
370
- count,
371
- }));
372
- }
373
- }
321
+ const nymph = this.nymph.clone();
322
+ if (nymph.tilmeld != null && token != null) {
323
+ const user = await nymph.tilmeld.extractToken(token);
324
+ if (user) {
325
+ nymph.tilmeld.fillSession(user);
374
326
  }
375
327
  }
376
- if (data.action === 'unsubscribe') {
377
- for (const qrefQuery of qrefQueries) {
378
- yield this.handleSubscriptionQuery(from, {
379
- action: 'unsubscribe',
380
- query: JSON.stringify(qrefQuery),
381
- }, {
382
- etype,
383
- query: serialArgs,
384
- });
328
+ const existingSub = this.querySubs[etype][serialArgs].get(from);
329
+ if (existingSub) {
330
+ if (qrefParent) {
331
+ existingSub.qrefParents.push(qrefParent);
385
332
  }
386
- if (!(etype in this.querySubs)) {
387
- return;
333
+ if (!qrefParent && !existingSub.direct) {
334
+ existingSub.direct = true;
388
335
  }
389
- if (!(serialArgs in this.querySubs[etype])) {
390
- return;
336
+ if (data.count && !existingSub.count) {
337
+ existingSub.count = true;
391
338
  }
392
- if (!this.querySubs[etype][serialArgs].has(from)) {
393
- return;
394
- }
395
- const existingSub = this.querySubs[etype][serialArgs].get(from);
396
- if (existingSub) {
397
- if (qrefParent) {
398
- existingSub.qrefParents = existingSub.qrefParents.filter((parent) => !(qrefParent.etype === parent.etype &&
399
- qrefParent.query === parent.query));
400
- }
401
- if (!qrefParent) {
402
- existingSub.direct = false;
403
- }
404
- if (!existingSub.direct && !existingSub.qrefParents.length) {
405
- this.querySubs[etype][serialArgs].delete(from);
406
- }
407
- }
408
- this.config.logger('log', new Date().toISOString(), `Client unsubscribed from a query! (${serialArgs}, ${from.remoteAddress})`);
339
+ }
340
+ else {
341
+ this.querySubs[etype][serialArgs].set(from, {
342
+ current: await nymph.getEntities(options, ...selectors),
343
+ query: data.query,
344
+ qrefParents: qrefParent ? [qrefParent] : [],
345
+ direct: !qrefParent,
346
+ count: !!data.count,
347
+ });
348
+ }
349
+ if (nymph.tilmeld != null && token != null) {
350
+ nymph.tilmeld.clearSession();
351
+ }
352
+ this.config.logger('log', new Date().toISOString(), `Client subscribed to a query! (${serialArgs}, ${from.remoteAddress})`);
353
+ if (this.config.broadcastCounts) {
409
354
  const count = this.querySubs[etype][serialArgs].size;
410
- if (count === 0) {
411
- delete this.querySubs[etype][serialArgs];
412
- if (Object.keys(this.querySubs[etype]).length === 0) {
413
- delete this.querySubs[etype];
414
- }
415
- return;
416
- }
417
- if (this.config.broadcastCounts) {
418
- for (let key of this.querySubs[etype][serialArgs].keys()) {
419
- const curData = this.querySubs[etype][serialArgs].get(key);
420
- if (curData && curData.count) {
421
- key.sendUTF(JSON.stringify({
422
- query: curData.query,
423
- count,
424
- }));
425
- }
355
+ for (let key of this.querySubs[etype][serialArgs].keys()) {
356
+ const curData = this.querySubs[etype][serialArgs].get(key);
357
+ if (curData && curData.count) {
358
+ key.sendUTF(JSON.stringify({
359
+ query: curData.query,
360
+ count,
361
+ }));
426
362
  }
427
363
  }
428
364
  }
429
- });
430
- }
431
- handleSubscriptionUid(from, data) {
432
- return __awaiter(this, void 0, void 0, function* () {
433
- if (data.action === 'subscribe') {
434
- if (!(data.uid in this.uidSubs)) {
435
- this.uidSubs[data.uid] = new Map();
436
- }
437
- this.uidSubs[data['uid']].set(from, {
438
- count: !!data.count,
365
+ }
366
+ if (data.action === 'unsubscribe') {
367
+ for (const qrefQuery of qrefQueries) {
368
+ await this.handleSubscriptionQuery(from, {
369
+ action: 'unsubscribe',
370
+ query: JSON.stringify(qrefQuery),
371
+ }, {
372
+ etype,
373
+ query: serialArgs,
439
374
  });
440
- this.config.logger('log', new Date().toISOString(), `Client subscribed to a UID! (${data.uid}, ${from.remoteAddress})`);
441
- if (this.config.broadcastCounts) {
442
- const count = this.uidSubs[data.uid].size;
443
- for (let key of this.uidSubs[data.uid].keys()) {
444
- const curData = this.uidSubs[data.uid].get(key);
445
- if (curData && curData.count) {
446
- key.sendUTF(JSON.stringify({
447
- uid: data.uid,
448
- count,
449
- }));
450
- }
451
- }
375
+ }
376
+ if (!(etype in this.querySubs)) {
377
+ return;
378
+ }
379
+ if (!(serialArgs in this.querySubs[etype])) {
380
+ return;
381
+ }
382
+ if (!this.querySubs[etype][serialArgs].has(from)) {
383
+ return;
384
+ }
385
+ const existingSub = this.querySubs[etype][serialArgs].get(from);
386
+ if (existingSub) {
387
+ if (qrefParent) {
388
+ existingSub.qrefParents = existingSub.qrefParents.filter((parent) => !(qrefParent.etype === parent.etype &&
389
+ qrefParent.query === parent.query));
390
+ }
391
+ if (!qrefParent) {
392
+ existingSub.direct = false;
393
+ }
394
+ if (!existingSub.direct && !existingSub.qrefParents.length) {
395
+ this.querySubs[etype][serialArgs].delete(from);
452
396
  }
453
397
  }
454
- if (data.action === 'unsubscribe') {
455
- if (!(data.uid in this.uidSubs)) {
456
- return;
398
+ this.config.logger('log', new Date().toISOString(), `Client unsubscribed from a query! (${serialArgs}, ${from.remoteAddress})`);
399
+ const count = this.querySubs[etype][serialArgs].size;
400
+ if (count === 0) {
401
+ delete this.querySubs[etype][serialArgs];
402
+ if (Object.keys(this.querySubs[etype]).length === 0) {
403
+ delete this.querySubs[etype];
457
404
  }
458
- if (!this.uidSubs[data.uid].has(from)) {
459
- return;
405
+ return;
406
+ }
407
+ if (this.config.broadcastCounts) {
408
+ for (let key of this.querySubs[etype][serialArgs].keys()) {
409
+ const curData = this.querySubs[etype][serialArgs].get(key);
410
+ if (curData && curData.count) {
411
+ key.sendUTF(JSON.stringify({
412
+ query: curData.query,
413
+ count,
414
+ }));
415
+ }
460
416
  }
461
- this.uidSubs[data.uid].delete(from);
462
- this.config.logger('log', new Date().toISOString(), `Client unsubscribed from a UID! (${data.uid}, ${from.remoteAddress})`);
417
+ }
418
+ }
419
+ }
420
+ async handleSubscriptionUid(from, data) {
421
+ if (data.action === 'subscribe') {
422
+ if (!(data.uid in this.uidSubs)) {
423
+ this.uidSubs[data.uid] = new Map();
424
+ }
425
+ this.uidSubs[data['uid']].set(from, {
426
+ count: !!data.count,
427
+ });
428
+ this.config.logger('log', new Date().toISOString(), `Client subscribed to a UID! (${data.uid}, ${from.remoteAddress})`);
429
+ if (this.config.broadcastCounts) {
463
430
  const count = this.uidSubs[data.uid].size;
464
- if (count === 0) {
465
- delete this.uidSubs[data.uid];
466
- return;
431
+ for (let key of this.uidSubs[data.uid].keys()) {
432
+ const curData = this.uidSubs[data.uid].get(key);
433
+ if (curData && curData.count) {
434
+ key.sendUTF(JSON.stringify({
435
+ uid: data.uid,
436
+ count,
437
+ }));
438
+ }
467
439
  }
468
- if (this.config.broadcastCounts) {
469
- for (let key of this.uidSubs[data.uid].keys()) {
470
- const curData = this.uidSubs[data.uid].get(key);
471
- if (curData && curData.count) {
472
- key.sendUTF(JSON.stringify({
473
- uid: data.uid,
474
- count,
475
- }));
476
- }
440
+ }
441
+ }
442
+ if (data.action === 'unsubscribe') {
443
+ if (!(data.uid in this.uidSubs)) {
444
+ return;
445
+ }
446
+ if (!this.uidSubs[data.uid].has(from)) {
447
+ return;
448
+ }
449
+ this.uidSubs[data.uid].delete(from);
450
+ this.config.logger('log', new Date().toISOString(), `Client unsubscribed from a UID! (${data.uid}, ${from.remoteAddress})`);
451
+ const count = this.uidSubs[data.uid].size;
452
+ if (count === 0) {
453
+ delete this.uidSubs[data.uid];
454
+ return;
455
+ }
456
+ if (this.config.broadcastCounts) {
457
+ for (let key of this.uidSubs[data.uid].keys()) {
458
+ const curData = this.uidSubs[data.uid].get(key);
459
+ if (curData && curData.count) {
460
+ key.sendUTF(JSON.stringify({
461
+ uid: data.uid,
462
+ count,
463
+ }));
477
464
  }
478
465
  }
479
466
  }
480
- });
467
+ }
481
468
  }
482
- handlePublish(from, msg, data) {
483
- return __awaiter(this, void 0, void 0, function* () {
484
- if ('guid' in data &&
485
- typeof data.guid === 'string' &&
486
- data.guid.match(/^[0-9a-f]{24}$/) &&
487
- (data.event === 'delete' ||
488
- ((data.event === 'create' || data.event === 'update') &&
489
- 'entity' in data &&
490
- data.entity != null))) {
491
- yield this.handlePublishEntity(from, data);
492
- this.relay(msg);
493
- }
494
- if ((('name' in data && typeof data.name === 'string') ||
495
- ('oldName' in data &&
496
- typeof data.oldName === 'string' &&
497
- 'newName' in data &&
498
- typeof data.newName === 'string')) &&
499
- ['newUID', 'setUID', 'renameUID', 'deleteUID'].indexOf(data.event) !== -1) {
500
- yield this.handlePublishUid(from, data);
501
- this.relay(msg);
502
- }
503
- });
469
+ async handlePublish(from, msg, data) {
470
+ if ('guid' in data &&
471
+ typeof data.guid === 'string' &&
472
+ data.guid.match(/^[0-9a-f]{24}$/) &&
473
+ (data.event === 'delete' ||
474
+ ((data.event === 'create' || data.event === 'update') &&
475
+ 'entity' in data &&
476
+ data.entity != null))) {
477
+ await this.handlePublishEntity(from, data);
478
+ this.relay(msg);
479
+ }
480
+ if ((('name' in data && typeof data.name === 'string') ||
481
+ ('oldName' in data &&
482
+ typeof data.oldName === 'string' &&
483
+ 'newName' in data &&
484
+ typeof data.newName === 'string')) &&
485
+ ['newUID', 'setUID', 'renameUID', 'deleteUID'].indexOf(data.event) !== -1) {
486
+ await this.handlePublishUid(from, data);
487
+ this.relay(msg);
488
+ }
504
489
  }
505
- handlePublishEntity(from, data) {
506
- var _a, _b, _c, _d;
507
- return __awaiter(this, void 0, void 0, function* () {
508
- this.config.logger('log', new Date().toISOString(), `Received an entity publish! (${data.guid}, ${data.event}, ${from.remoteAddress})`);
509
- const etype = data.etype;
510
- if (!(etype in this.querySubs)) {
511
- return;
490
+ async handlePublishEntity(from, data) {
491
+ this.config.logger('log', new Date().toISOString(), `Received an entity publish! (${data.guid}, ${data.event}, ${from.remoteAddress})`);
492
+ const etype = data.etype;
493
+ if (!(etype in this.querySubs)) {
494
+ return;
495
+ }
496
+ for (let curQuery in this.querySubs[etype]) {
497
+ const curClients = this.querySubs[etype][curQuery];
498
+ const updatedClients = new Set();
499
+ if (data.event === 'delete' || data.event === 'update') {
500
+ try {
501
+ for (const curClient of curClients.keys()) {
502
+ const curData = curClients.get(curClient);
503
+ if (!curData) {
504
+ continue;
505
+ }
506
+ if (curData.current.indexOf(data.guid) !== -1) {
507
+ await this.updateClient(curClient, curData, data);
508
+ updatedClients.add(curClient);
509
+ }
510
+ }
511
+ }
512
+ catch (e) {
513
+ this.config.logger('error', new Date().toISOString(), `Error checking for client updates! (${e?.message})`);
514
+ }
512
515
  }
513
- for (let curQuery in this.querySubs[etype]) {
514
- const curClients = this.querySubs[etype][curQuery];
515
- const updatedClients = new Set();
516
- if (data.event === 'delete' || data.event === 'update') {
517
- try {
518
- for (const curClient of curClients.keys()) {
516
+ if ((data.event === 'create' || data.event === 'update') && data.entity) {
517
+ try {
518
+ const [clientOptions, ...selectors] = JSON.parse(curQuery);
519
+ const qrefQueries = this.findQRefQueries(clientOptions, ...selectors);
520
+ const EntityClass = this.nymph.getEntityClass(clientOptions.class);
521
+ const entityData = data.entity.data;
522
+ entityData.cdate = data.entity.cdate;
523
+ entityData.mdate = data.entity.mdate;
524
+ const entitySData = {};
525
+ if (typeof data.entity.class !== 'string') {
526
+ throw new Error(`Received entity data class is not valid: ${data.entity.class}`);
527
+ }
528
+ const DataEntityClass = this.nymph.getEntityClass(data.entity.class);
529
+ if (EntityClass.ETYPE === DataEntityClass.ETYPE &&
530
+ (qrefQueries.length ||
531
+ this.nymph.driver.checkData(entityData, entitySData, selectors, data.guid, data.entity?.tags ?? []))) {
532
+ for (let curClient of curClients.keys()) {
533
+ if (updatedClients.has(curClient)) {
534
+ continue;
535
+ }
519
536
  const curData = curClients.get(curClient);
520
537
  if (!curData) {
521
538
  continue;
522
539
  }
523
- if (curData.current.indexOf(data.guid) !== -1) {
524
- yield this.updateClient(curClient, curData, data);
525
- updatedClients.add(curClient);
526
- }
527
- }
528
- }
529
- catch (e) {
530
- this.config.logger('error', new Date().toISOString(), `Error checking for client updates! (${e === null || e === void 0 ? void 0 : e.message})`);
531
- }
532
- }
533
- if ((data.event === 'create' || data.event === 'update') && data.entity) {
534
- try {
535
- const [clientOptions, ...selectors] = JSON.parse(curQuery);
536
- const qrefQueries = this.findQRefQueries(clientOptions, ...selectors);
537
- const EntityClass = this.nymph.getEntityClass(clientOptions.class);
538
- const entityData = data.entity.data;
539
- entityData.cdate = data.entity.cdate;
540
- entityData.mdate = data.entity.mdate;
541
- const entitySData = {};
542
- if (typeof data.entity.class !== 'string') {
543
- throw new Error(`Received entity data class is not valid: ${data.entity.class}`);
544
- }
545
- const DataEntityClass = this.nymph.getEntityClass(data.entity.class);
546
- if (EntityClass.ETYPE === DataEntityClass.ETYPE &&
547
- (qrefQueries.length ||
548
- this.nymph.driver.checkData(entityData, entitySData, selectors, data.guid, (_b = (_a = data.entity) === null || _a === void 0 ? void 0 : _a.tags) !== null && _b !== void 0 ? _b : []))) {
549
- for (let curClient of curClients.keys()) {
550
- if (updatedClients.has(curClient)) {
551
- continue;
552
- }
553
- const curData = curClients.get(curClient);
554
- if (!curData) {
540
+ if (qrefQueries.length) {
541
+ const translatedSelectors = this.translateQRefSelectors(curClient, selectors);
542
+ if (!this.nymph.driver.checkData(entityData, entitySData, translatedSelectors, data.guid, data.entity?.tags ?? [])) {
555
543
  continue;
556
544
  }
557
- if (qrefQueries.length) {
558
- const translatedSelectors = this.translateQRefSelectors(curClient, selectors);
559
- if (!this.nymph.driver.checkData(entityData, entitySData, translatedSelectors, data.guid, (_d = (_c = data.entity) === null || _c === void 0 ? void 0 : _c.tags) !== null && _d !== void 0 ? _d : [])) {
560
- continue;
561
- }
562
- }
563
- yield this.updateClient(curClient, curData, data);
564
545
  }
546
+ await this.updateClient(curClient, curData, data);
565
547
  }
566
548
  }
567
- catch (e) {
568
- this.config.logger('error', new Date().toISOString(), `Error checking for client updates! (${e === null || e === void 0 ? void 0 : e.message})`);
569
- }
549
+ }
550
+ catch (e) {
551
+ this.config.logger('error', new Date().toISOString(), `Error checking for client updates! (${e?.message})`);
570
552
  }
571
553
  }
572
- });
554
+ }
573
555
  }
574
- updateClient(curClient, curData, data) {
575
- return __awaiter(this, void 0, void 0, function* () {
576
- let current;
577
- let token;
578
- const nymph = this.nymph.clone();
579
- try {
580
- const [clientOptions, ...clientSelectors] = JSON.parse(curData.query);
581
- const options = Object.assign(Object.assign({}, clientOptions), { class: nymph.getEntityClass(clientOptions.class), return: 'entity', source: 'client' });
582
- const selectors = (0, nymph_1.classNamesToEntityConstructors)(nymph, clientSelectors);
583
- if (this.sessions.has(curClient)) {
584
- token = this.sessions.get(curClient);
585
- }
586
- if (nymph.tilmeld != null && token != null) {
587
- const user = yield nymph.tilmeld.extractToken(token);
588
- if (user) {
589
- nymph.tilmeld.fillSession(user);
590
- }
556
+ async updateClient(curClient, curData, data) {
557
+ let current;
558
+ let token;
559
+ const nymph = this.nymph.clone();
560
+ try {
561
+ const [clientOptions, ...clientSelectors] = JSON.parse(curData.query);
562
+ const options = {
563
+ ...clientOptions,
564
+ class: nymph.getEntityClass(clientOptions.class),
565
+ return: 'entity',
566
+ source: 'client',
567
+ };
568
+ const selectors = (0, nymph_1.classNamesToEntityConstructors)(nymph, clientSelectors);
569
+ if (this.sessions.has(curClient)) {
570
+ token = this.sessions.get(curClient);
571
+ }
572
+ if (nymph.tilmeld != null && token != null) {
573
+ const user = await nymph.tilmeld.extractToken(token);
574
+ if (user) {
575
+ nymph.tilmeld.fillSession(user);
591
576
  }
592
- current = yield nymph.getEntities(options, ...selectors);
593
577
  }
594
- catch (e) {
595
- this.config.logger('error', new Date().toISOString(), `Error updating client! (${e === null || e === void 0 ? void 0 : e.message}, ${curClient.remoteAddress})`);
596
- return;
578
+ current = await nymph.getEntities(options, ...selectors);
579
+ }
580
+ catch (e) {
581
+ this.config.logger('error', new Date().toISOString(), `Error updating client! (${e?.message}, ${curClient.remoteAddress})`);
582
+ return;
583
+ }
584
+ const entityMap = Object.fromEntries(current.map((entity) => [entity.guid, entity]));
585
+ const currentGuids = current.map((entity) => entity.guid ?? '');
586
+ const removed = (0, lodash_1.difference)(curData.current, currentGuids);
587
+ const added = (0, lodash_1.difference)(currentGuids, curData.current);
588
+ if (curData.direct) {
589
+ for (let guid of removed) {
590
+ this.config.logger('log', new Date().toISOString(), `Notifying client of removal! (${curClient.remoteAddress})`);
591
+ curClient.sendUTF(JSON.stringify({
592
+ query: curData.query,
593
+ removed: guid,
594
+ }));
597
595
  }
598
- const entityMap = Object.fromEntries(current.map((entity) => [entity.guid, entity]));
599
- const currentGuids = current.map((entity) => { var _a; return (_a = entity.guid) !== null && _a !== void 0 ? _a : ''; });
600
- const removed = (0, lodash_1.difference)(curData.current, currentGuids);
601
- const added = (0, lodash_1.difference)(currentGuids, curData.current);
602
- if (curData.direct) {
603
- for (let guid of removed) {
604
- this.config.logger('log', new Date().toISOString(), `Notifying client of removal! (${curClient.remoteAddress})`);
605
- curClient.sendUTF(JSON.stringify({
606
- query: curData.query,
607
- removed: guid,
608
- }));
609
- }
610
- for (let guid of added) {
611
- const entity = entityMap[guid];
612
- this.config.logger('log', new Date().toISOString(), `Notifying client of new match! (${curClient.remoteAddress})`);
613
- if (typeof entity.updateDataProtection === 'function') {
614
- entity.updateDataProtection();
615
- }
616
- curClient.sendUTF(JSON.stringify({
617
- query: curData.query,
618
- added: guid,
619
- data: entity,
620
- }));
621
- }
622
- if (data.event === 'update' && data.guid in entityMap) {
623
- const entity = entityMap[data.guid];
624
- this.config.logger('log', new Date().toISOString(), `Notifying client of update! (${curClient.remoteAddress})`);
625
- if (typeof entity.updateDataProtection === 'function') {
626
- entity.updateDataProtection();
627
- }
628
- curClient.sendUTF(JSON.stringify({
629
- query: curData.query,
630
- updated: data.guid,
631
- data: entity,
632
- }));
633
- }
596
+ for (let guid of added) {
597
+ const entity = entityMap[guid];
598
+ this.config.logger('log', new Date().toISOString(), `Notifying client of new match! (${curClient.remoteAddress})`);
599
+ if (typeof entity.updateDataProtection === 'function') {
600
+ entity.updateDataProtection();
601
+ }
602
+ curClient.sendUTF(JSON.stringify({
603
+ query: curData.query,
604
+ added: guid,
605
+ data: entity,
606
+ }));
634
607
  }
635
- curData.current = currentGuids;
636
- if (nymph.tilmeld != null && token != null) {
637
- nymph.tilmeld.clearSession();
608
+ if (data.event === 'update' && data.guid in entityMap) {
609
+ const entity = entityMap[data.guid];
610
+ this.config.logger('log', new Date().toISOString(), `Notifying client of update! (${curClient.remoteAddress})`);
611
+ if (typeof entity.updateDataProtection === 'function') {
612
+ entity.updateDataProtection();
613
+ }
614
+ curClient.sendUTF(JSON.stringify({
615
+ query: curData.query,
616
+ updated: data.guid,
617
+ data: entity,
618
+ }));
638
619
  }
639
- if ((removed.length || added.length) && curData.qrefParents.length) {
640
- for (const qrefParent of curData.qrefParents) {
641
- const subData = this.querySubs[qrefParent.etype][qrefParent.query].get(curClient);
642
- if (subData) {
643
- this.updateClient(curClient, subData, data);
644
- }
620
+ }
621
+ curData.current = currentGuids;
622
+ if (nymph.tilmeld != null && token != null) {
623
+ nymph.tilmeld.clearSession();
624
+ }
625
+ if ((removed.length || added.length) && curData.qrefParents.length) {
626
+ for (const qrefParent of curData.qrefParents) {
627
+ const subData = this.querySubs[qrefParent.etype][qrefParent.query].get(curClient);
628
+ if (subData) {
629
+ this.updateClient(curClient, subData, data);
645
630
  }
646
631
  }
647
- });
632
+ }
648
633
  }
649
- handlePublishUid(from, data) {
650
- var _a;
651
- return __awaiter(this, void 0, void 0, function* () {
652
- this.config.logger('log', new Date().toISOString(), `Received a UID publish! (${'name' in data ? data.name : `${data.oldName} => ${data.newName}`}, ${data.event}, ${from.remoteAddress})`);
653
- const names = [data.name, data.oldName].filter((name) => name != null);
654
- let value = data.value;
655
- if (data.event === 'renameUID' && data.newName) {
656
- value = (_a = (yield this.nymph.getUID(data.newName))) !== null && _a !== void 0 ? _a : undefined;
657
- }
658
- for (let name of names) {
659
- if (!(name in this.uidSubs)) {
660
- continue;
661
- }
662
- for (let curClient of this.uidSubs[name].keys()) {
663
- this.config.logger('log', new Date().toISOString(), `Notifying client of ${data.event}! (${name}, ${curClient.remoteAddress})`);
664
- const payload = {
665
- uid: name,
666
- event: data.event,
667
- };
668
- if (data.value != null) {
669
- payload.value = data.value;
670
- }
671
- curClient.sendUTF(JSON.stringify(payload));
672
- }
634
+ async handlePublishUid(from, data) {
635
+ this.config.logger('log', new Date().toISOString(), `Received a UID publish! (${'name' in data ? data.name : `${data.oldName} => ${data.newName}`}, ${data.event}, ${from.remoteAddress})`);
636
+ const names = [data.name, data.oldName].filter((name) => name != null);
637
+ let value = data.value;
638
+ if (data.event === 'renameUID' && data.newName) {
639
+ value = (await this.nymph.getUID(data.newName)) ?? undefined;
640
+ }
641
+ for (let name of names) {
642
+ if (!(name in this.uidSubs)) {
643
+ continue;
673
644
  }
674
- if (data.event === 'renameUID' &&
675
- data.newName &&
676
- data.newName in this.uidSubs) {
677
- for (let curClient of this.uidSubs[data.newName].keys()) {
678
- this.config.logger('log', new Date().toISOString(), `Notifying client of new value after rename! (${data.newName}, ${curClient.remoteAddress})`);
679
- curClient.sendUTF(JSON.stringify({
680
- uid: data.newName,
681
- event: 'setUID',
682
- value,
683
- }));
684
- }
645
+ for (let curClient of this.uidSubs[name].keys()) {
646
+ this.config.logger('log', new Date().toISOString(), `Notifying client of ${data.event}! (${name}, ${curClient.remoteAddress})`);
647
+ const payload = {
648
+ uid: name,
649
+ event: data.event,
650
+ };
651
+ if (data.value != null) {
652
+ payload.value = data.value;
653
+ }
654
+ curClient.sendUTF(JSON.stringify(payload));
685
655
  }
686
- });
656
+ }
657
+ if (data.event === 'renameUID' &&
658
+ data.newName &&
659
+ data.newName in this.uidSubs) {
660
+ for (let curClient of this.uidSubs[data.newName].keys()) {
661
+ this.config.logger('log', new Date().toISOString(), `Notifying client of new value after rename! (${data.newName}, ${curClient.remoteAddress})`);
662
+ curClient.sendUTF(JSON.stringify({
663
+ uid: data.newName,
664
+ event: 'setUID',
665
+ value,
666
+ }));
667
+ }
668
+ }
687
669
  }
688
670
  relay(message) {
689
671
  if (message.type !== 'utf8') {
@@ -708,7 +690,6 @@ class PubSub {
708
690
  }
709
691
  }
710
692
  findQRefQueries(options, ...selectors) {
711
- var _a;
712
693
  const qrefQueries = [];
713
694
  for (const curSelector of selectors) {
714
695
  for (const k in curSelector) {
@@ -721,7 +702,7 @@ class PubSub {
721
702
  continue;
722
703
  }
723
704
  if (key === 'qref' || key === '!qref') {
724
- const tmpArr = (Array.isArray(((_a = value) !== null && _a !== void 0 ? _a : [])[0])
705
+ const tmpArr = (Array.isArray((value ?? [])[0])
725
706
  ? value
726
707
  : [value]);
727
708
  for (let i = 0; i < tmpArr.length; i++) {
@@ -737,7 +718,6 @@ class PubSub {
737
718
  return qrefQueries;
738
719
  }
739
720
  translateQRefSelectors(client, selectors) {
740
- var _a, _b, _c;
741
721
  const newSelectors = [];
742
722
  for (const curSelector of selectors) {
743
723
  const newSelector = { type: curSelector.type };
@@ -752,7 +732,7 @@ class PubSub {
752
732
  }
753
733
  if (key === 'qref' || key === '!qref') {
754
734
  const newKey = key === 'qref' ? 'ref' : '!ref';
755
- const tmpArr = (Array.isArray(((_a = value) !== null && _a !== void 0 ? _a : [])[0])
735
+ const tmpArr = (Array.isArray((value ?? [])[0])
756
736
  ? value
757
737
  : [value]);
758
738
  for (let i = 0; i < tmpArr.length; i++) {
@@ -761,7 +741,7 @@ class PubSub {
761
741
  const query = JSON.stringify(tmpArr[i][1]);
762
742
  const QrefEntityClass = typeof qrefOptions.class === 'string'
763
743
  ? this.nymph.getEntityClass(qrefOptions.class)
764
- : (_b = qrefOptions.class) !== null && _b !== void 0 ? _b : this.nymph.getEntityClass('Entity');
744
+ : qrefOptions.class ?? this.nymph.getEntityClass('Entity');
765
745
  const data = this.querySubs[QrefEntityClass.ETYPE][query].get(client);
766
746
  if (data) {
767
747
  const guids = data.current;
@@ -795,7 +775,7 @@ class PubSub {
795
775
  newSelector[key] = this.translateQRefSelectors(client, tmpArr);
796
776
  }
797
777
  else if (key === 'ref' || key === '!ref') {
798
- const tmpArr = (Array.isArray(((_c = value) !== null && _c !== void 0 ? _c : [])[0])
778
+ const tmpArr = (Array.isArray((value ?? [])[0])
799
779
  ? value
800
780
  : [value]);
801
781
  if (!newSelector[key]) {