prostgles-server 3.0.154 → 4.0.1
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/AuthHandler.d.ts.map +1 -1
- package/dist/AuthHandler.js +6 -3
- package/dist/AuthHandler.js.map +1 -1
- package/dist/DBEventsManager.d.ts.map +1 -1
- package/dist/DBEventsManager.js +5 -4
- package/dist/DBEventsManager.js.map +1 -1
- package/dist/DBSchemaBuilder.js +14 -14
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions.js +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/makeSelectQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler.js +1 -2
- package/dist/DboBuilder/TableHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler.js +10 -8
- package/dist/DboBuilder/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/getCondition.js +1 -1
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/insert.js +1 -1
- package/dist/DboBuilder/insert.js.map +1 -1
- package/dist/DboBuilder/insertDataParse.js +4 -3
- package/dist/DboBuilder/insertDataParse.js.map +1 -1
- package/dist/DboBuilder/subscribe.d.ts +2 -2
- package/dist/DboBuilder/subscribe.d.ts.map +1 -1
- package/dist/DboBuilder/subscribe.js +3 -4
- package/dist/DboBuilder/subscribe.js.map +1 -1
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +5 -4
- package/dist/DboBuilder.js.map +1 -1
- package/dist/FileManager.js +1 -1
- package/dist/FileManager.js.map +1 -1
- package/dist/Filtering.js.map +1 -1
- package/dist/JSONBValidation/validation.js.map +1 -1
- package/dist/Prostgles.js +1 -1
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +28 -26
- package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.js +53 -433
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/addSub.d.ts +8 -0
- package/dist/PubSubManager/addSub.d.ts.map +1 -0
- package/dist/PubSubManager/addSub.js +163 -0
- package/dist/PubSubManager/addSub.js.map +1 -0
- package/dist/PubSubManager/addSync.d.ts +8 -0
- package/dist/PubSubManager/addSync.d.ts.map +1 -0
- package/dist/PubSubManager/addSync.js +110 -0
- package/dist/PubSubManager/addSync.js.map +1 -0
- package/dist/PubSubManager/notifListener.d.ts +5 -0
- package/dist/PubSubManager/notifListener.d.ts.map +1 -0
- package/dist/PubSubManager/notifListener.js +99 -0
- package/dist/PubSubManager/notifListener.js.map +1 -0
- package/dist/PubSubManager/pushSubData.d.ts +3 -0
- package/dist/PubSubManager/pushSubData.d.ts.map +1 -0
- package/dist/PubSubManager/pushSubData.js +48 -0
- package/dist/PubSubManager/pushSubData.js.map +1 -0
- package/dist/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser.js +4 -3
- package/dist/PublishParser.js.map +1 -1
- package/dist/TableConfig/TableConfig.js.map +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.js.map +1 -1
- package/dist/TableConfig/getTableColumnQueries.js.map +1 -1
- package/lib/AuthHandler.d.ts.map +1 -1
- package/lib/AuthHandler.js +6 -3
- package/lib/AuthHandler.ts +12 -7
- package/lib/DBEventsManager.d.ts.map +1 -1
- package/lib/DBEventsManager.js +5 -4
- package/lib/DBEventsManager.ts +10 -9
- package/lib/DBSchemaBuilder.js +14 -14
- package/lib/DBSchemaBuilder.ts +14 -14
- package/lib/DboBuilder/QueryBuilder/Functions.js +1 -1
- package/lib/DboBuilder/QueryBuilder/Functions.ts +2 -2
- package/lib/DboBuilder/QueryBuilder/makeSelectQuery.ts +1 -1
- package/lib/DboBuilder/TableHandler.d.ts +1 -5
- package/lib/DboBuilder/TableHandler.d.ts.map +1 -1
- package/lib/DboBuilder/TableHandler.js +1 -2
- package/lib/DboBuilder/TableHandler.ts +3 -3
- package/lib/DboBuilder/ViewHandler.d.ts.map +1 -1
- package/lib/DboBuilder/ViewHandler.js +10 -8
- package/lib/DboBuilder/ViewHandler.ts +22 -20
- package/lib/DboBuilder/getCondition.js +1 -1
- package/lib/DboBuilder/getCondition.ts +2 -2
- package/lib/DboBuilder/insert.js +1 -1
- package/lib/DboBuilder/insert.ts +1 -1
- package/lib/DboBuilder/insertDataParse.js +4 -3
- package/lib/DboBuilder/insertDataParse.ts +15 -13
- package/lib/DboBuilder/subscribe.d.ts +2 -2
- package/lib/DboBuilder/subscribe.d.ts.map +1 -1
- package/lib/DboBuilder/subscribe.js +3 -4
- package/lib/DboBuilder/subscribe.ts +8 -9
- package/lib/DboBuilder.d.ts.map +1 -1
- package/lib/DboBuilder.js +5 -4
- package/lib/DboBuilder.ts +15 -21
- package/lib/FileManager.js +1 -1
- package/lib/FileManager.ts +5 -5
- package/lib/Filtering.ts +1 -1
- package/lib/JSONBValidation/validation.ts +3 -3
- package/lib/Prostgles.js +1 -1
- package/lib/Prostgles.ts +3 -3
- package/lib/PubSubManager/PubSubManager.d.ts +27 -29
- package/lib/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/lib/PubSubManager/PubSubManager.js +54 -437
- package/lib/PubSubManager/PubSubManager.ts +93 -546
- package/lib/PubSubManager/addSub.d.ts +8 -0
- package/lib/PubSubManager/addSub.d.ts.map +1 -0
- package/lib/PubSubManager/addSub.js +162 -0
- package/lib/PubSubManager/addSub.ts +186 -0
- package/lib/PubSubManager/addSync.d.ts +8 -0
- package/lib/PubSubManager/addSync.d.ts.map +1 -0
- package/lib/PubSubManager/addSync.js +109 -0
- package/lib/PubSubManager/addSync.ts +127 -0
- package/lib/PubSubManager/notifListener.d.ts +5 -0
- package/lib/PubSubManager/notifListener.d.ts.map +1 -0
- package/lib/PubSubManager/notifListener.js +98 -0
- package/lib/PubSubManager/notifListener.ts +124 -0
- package/lib/PubSubManager/pushSubData.d.ts +3 -0
- package/lib/PubSubManager/pushSubData.d.ts.map +1 -0
- package/lib/PubSubManager/pushSubData.js +47 -0
- package/lib/PubSubManager/pushSubData.ts +47 -0
- package/lib/PublishParser.d.ts.map +1 -1
- package/lib/PublishParser.js +4 -3
- package/lib/PublishParser.ts +4 -3
- package/lib/TableConfig/TableConfig.ts +7 -7
- package/lib/TableConfig/getConstraintDefinitionQueries.ts +1 -1
- package/lib/TableConfig/getTableColumnQueries.ts +2 -2
- package/package.json +2 -2
- package/tests/client/PID.txt +1 -1
- package/tests/client/package-lock.json +15 -15
- package/tests/client/package.json +1 -1
- package/tests/client/tsconfig.json +2 -1
- package/tests/client_only_queries.js +1 -1
- package/tests/client_only_queries.ts +1 -1
- package/tests/isomorphic_queries.ts +1 -1
- package/tests/server/DBoGenerated.d.ts +2 -2
- package/tests/server/package-lock.json +3 -3
- package/tests/server/tsconfig.json +2 -1
- package/tsconfig.json +1 -1
|
@@ -27,8 +27,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
27
27
|
return result;
|
|
28
28
|
};
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.omitKeys = exports.pickKeys = exports.PubSubManager = exports.log = exports.DEFAULT_SYNC_BATCH_SIZE = exports.asValue = void 0;
|
|
31
|
-
const
|
|
30
|
+
exports.omitKeys = exports.pickKeys = exports.parseCondition = exports.PubSubManager = exports.log = exports.DEFAULT_SYNC_BATCH_SIZE = exports.asValue = void 0;
|
|
31
|
+
const addSync_1 = require("./addSync");
|
|
32
32
|
const DboBuilder_1 = require("../DboBuilder");
|
|
33
33
|
const Prostgles_1 = require("../Prostgles");
|
|
34
34
|
const initPubSubManager_1 = require("./initPubSubManager");
|
|
@@ -38,6 +38,9 @@ const prostgles_types_1 = require("prostgles-types");
|
|
|
38
38
|
const SyncReplication_1 = require("../SyncReplication");
|
|
39
39
|
const util_1 = require("prostgles-types/dist/util");
|
|
40
40
|
const getInitQuery_1 = require("./getInitQuery");
|
|
41
|
+
const addSub_1 = require("./addSub");
|
|
42
|
+
const notifListener_1 = require("./notifListener");
|
|
43
|
+
const pushSubData_1 = require("./pushSubData");
|
|
41
44
|
const pgp = pgPromise({
|
|
42
45
|
promiseLib: Bluebird
|
|
43
46
|
});
|
|
@@ -60,9 +63,10 @@ class PubSubManager {
|
|
|
60
63
|
return this.dboBuilder.dbo;
|
|
61
64
|
}
|
|
62
65
|
_triggers;
|
|
63
|
-
sockets;
|
|
64
|
-
subs;
|
|
65
|
-
|
|
66
|
+
sockets = {};
|
|
67
|
+
// subs: { [ke: string]: { [ke: string]: { subs: SubscriptionParams[] } } };
|
|
68
|
+
subs = [];
|
|
69
|
+
syncs = [];
|
|
66
70
|
socketChannelPreffix;
|
|
67
71
|
onSchemaChange = undefined;
|
|
68
72
|
postgresNotifListenManager;
|
|
@@ -73,9 +77,6 @@ class PubSubManager {
|
|
|
73
77
|
}
|
|
74
78
|
this.onSchemaChange = onSchemaChange;
|
|
75
79
|
this.dboBuilder = dboBuilder;
|
|
76
|
-
this.sockets = {};
|
|
77
|
-
this.subs = {};
|
|
78
|
-
this.syncs = [];
|
|
79
80
|
this.socketChannelPreffix = wsChannelNamePrefix || "_psqlWS_";
|
|
80
81
|
(0, exports.log)("Created PubSubManager");
|
|
81
82
|
}
|
|
@@ -126,7 +127,8 @@ class PubSubManager {
|
|
|
126
127
|
if (this.appCheck) {
|
|
127
128
|
clearInterval(this.appCheck);
|
|
128
129
|
}
|
|
129
|
-
this.
|
|
130
|
+
this.subs = [];
|
|
131
|
+
this.syncs = [];
|
|
130
132
|
if (!this.postgresNotifListenManager) {
|
|
131
133
|
throw "this.postgresNotifListenManager missing";
|
|
132
134
|
}
|
|
@@ -267,399 +269,63 @@ class PubSubManager {
|
|
|
267
269
|
throw "this.postgresNotifListenManager missing";
|
|
268
270
|
return this.postgresNotifListenManager.isListening();
|
|
269
271
|
}
|
|
270
|
-
getSubs(table_name, condition) {
|
|
271
|
-
const subs = this.subs
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return subs
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return parentSubs ?? s;
|
|
290
|
-
}
|
|
291
|
-
return s;
|
|
292
|
-
});
|
|
272
|
+
getSubs(table_name, condition, client) {
|
|
273
|
+
const subs = this.subs.filter(s => (0, util_1.find)(s.triggers, { table_name, condition }));
|
|
274
|
+
if (client) {
|
|
275
|
+
return subs.filter(s => client.func && s.func === client.func || client.socket_id && s.socket_id === client.socket_id);
|
|
276
|
+
}
|
|
277
|
+
return subs;
|
|
278
|
+
}
|
|
279
|
+
removeLocalSub(tableName, conditionRaw, func) {
|
|
280
|
+
const condition = (0, exports.parseCondition)(conditionRaw);
|
|
281
|
+
if (this.getSubs(tableName, condition, { func }).length) {
|
|
282
|
+
this.subs = this.subs.filter(s => s.func !== func && !(0, util_1.find)(s.triggers, { tableName, condition }));
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
console.error("Could not unsubscribe. Subscription might not have initialised yet", { tableName, condition });
|
|
286
|
+
}
|
|
293
287
|
}
|
|
294
288
|
getSyncs(table_name, condition) {
|
|
295
289
|
return (this.syncs || [])
|
|
296
290
|
.filter((s) => s.table_name === table_name && s.condition === condition);
|
|
297
291
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
292
|
+
notifListener = notifListener_1.notifListener.bind(this);
|
|
293
|
+
getSubData = async (sub) => {
|
|
294
|
+
const { table_info, filter, params, table_rules } = sub; //, subOne = false
|
|
295
|
+
const { name: table_name } = table_info;
|
|
296
|
+
if (!this.dbo?.[table_name]?.find) {
|
|
297
|
+
throw new Error(`1107 this.dbo.${table_name}.find`);
|
|
304
298
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (this.onSchemaChange) {
|
|
309
|
-
const command = dataArr[1], event_type = dataArr[2], query = dataArr[3];
|
|
310
|
-
if (query) {
|
|
311
|
-
this.onSchemaChange({ command, query });
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
if (notifType !== this.NOTIF_TYPE.data) {
|
|
317
|
-
console.error("Unexpected notif type: ", notifType);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
if (dataArr.length < 3) {
|
|
321
|
-
throw "dataArr length < 3";
|
|
322
|
-
}
|
|
323
|
-
const table_name = dataArr[1], op_name = dataArr[2], condition_ids_str = dataArr[3];
|
|
324
|
-
// const triggers = await this.db.any("SELECT * FROM prostgles.triggers WHERE table_name = $1 AND id IN ($2:csv)", [table_name, condition_ids_str.split(",").map(v => +v)]);
|
|
325
|
-
// const conditions: string[] = triggers.map(t => t.condition);
|
|
326
|
-
/**
|
|
327
|
-
* Trigger error
|
|
328
|
-
*/
|
|
329
|
-
(0, exports.log)("PG Trigger ->", dataArr.join("__"));
|
|
330
|
-
if (condition_ids_str && condition_ids_str.startsWith("error") &&
|
|
331
|
-
this._triggers &&
|
|
332
|
-
this._triggers[table_name]?.length) {
|
|
333
|
-
const pref = "INTERNAL ERROR";
|
|
334
|
-
console.error(`${pref}: condition_ids_str: ${condition_ids_str}`);
|
|
335
|
-
this._triggers[table_name].map(c => {
|
|
336
|
-
const subs = this.getSubs(table_name, c);
|
|
337
|
-
subs.map(s => {
|
|
338
|
-
this.pushSubData(s, pref + ". Check server logs. Schema might have changed");
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
/**
|
|
342
|
-
* Trigger ok
|
|
343
|
-
*/
|
|
344
|
-
}
|
|
345
|
-
else if (condition_ids_str?.split(",").length &&
|
|
346
|
-
condition_ids_str?.split(",").every((c) => Number.isInteger(+c)) &&
|
|
347
|
-
this._triggers?.[table_name]?.length) {
|
|
348
|
-
const idxs = condition_ids_str.split(",").map(v => +v);
|
|
349
|
-
const conditions = this._triggers[table_name].filter((c, i) => idxs.includes(i));
|
|
350
|
-
(0, exports.log)("PG Trigger -> ", { table_name, op_name, condition_ids_str, conditions }, this._triggers[table_name]);
|
|
351
|
-
conditions.map(condition => {
|
|
352
|
-
const subs = this.getSubs(table_name, condition);
|
|
353
|
-
const syncs = this.getSyncs(table_name, condition);
|
|
354
|
-
syncs.map((s) => {
|
|
355
|
-
this.syncData(s, undefined, "trigger");
|
|
356
|
-
});
|
|
357
|
-
if (!subs) {
|
|
358
|
-
// console.error(`sub missing for ${table_name} ${condition}`, this.triggers);
|
|
359
|
-
// console.log(this.subs)
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
/* Throttle the subscriptions */
|
|
363
|
-
for (let i = 0; i < subs.length; i++) {
|
|
364
|
-
const sub = subs[i];
|
|
365
|
-
if (this.dbo[sub.table_name] &&
|
|
366
|
-
sub.is_ready &&
|
|
367
|
-
(sub.socket_id && this.sockets[sub.socket_id]) || sub.func) {
|
|
368
|
-
const throttle = sub.throttle || 0;
|
|
369
|
-
if (sub.last_throttled <= Date.now() - throttle) {
|
|
370
|
-
/* It is assumed the policy was checked before this point */
|
|
371
|
-
this.pushSubData(sub);
|
|
372
|
-
// sub.last_throttled = Date.now();
|
|
373
|
-
}
|
|
374
|
-
else if (!sub.is_throttling) {
|
|
375
|
-
(0, exports.log)("throttling sub");
|
|
376
|
-
sub.is_throttling = setTimeout(() => {
|
|
377
|
-
(0, exports.log)("throttling finished. pushSubData...");
|
|
378
|
-
sub.is_throttling = null;
|
|
379
|
-
this.pushSubData(sub);
|
|
380
|
-
}, throttle); // sub.throttle);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
});
|
|
299
|
+
try {
|
|
300
|
+
const data = await this.dbo?.[table_name].find(filter, params, undefined, table_rules);
|
|
301
|
+
return { data };
|
|
385
302
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
// console.warn(190, "Trigger sub not found. DROPPING TRIGGER", table_name, condition_ids_str, this._triggers);
|
|
389
|
-
// this.dropTrigger(table_name);
|
|
390
|
-
// } else {
|
|
391
|
-
// }
|
|
392
|
-
console.warn(190, "Trigger sub issue: ", table_name, condition_ids_str, this._triggers);
|
|
303
|
+
catch (err) {
|
|
304
|
+
return { err };
|
|
393
305
|
}
|
|
394
306
|
};
|
|
395
|
-
pushSubData(
|
|
396
|
-
if (!sub)
|
|
397
|
-
throw "pushSubData: invalid sub";
|
|
398
|
-
const { table_name, filter, params, table_rules, socket_id, channel_name, func } = sub; //, subOne = false
|
|
399
|
-
sub.last_throttled = Date.now();
|
|
400
|
-
if (err) {
|
|
401
|
-
if (socket_id) {
|
|
402
|
-
this.sockets[socket_id].emit(channel_name, { err });
|
|
403
|
-
}
|
|
404
|
-
return true;
|
|
405
|
-
}
|
|
406
|
-
return new Promise(async (resolve, reject) => {
|
|
407
|
-
/* TODO: Retire subOne -> it's redundant */
|
|
408
|
-
// this.dbo[table_name][subOne? "findOne" : "find"](filter, params, null, table_rules)
|
|
409
|
-
if (!this.dbo?.[table_name]?.find) {
|
|
410
|
-
throw new Error(`1107 this.dbo.${table_name}.find`);
|
|
411
|
-
}
|
|
412
|
-
this.dbo?.[table_name]?.find?.(filter, params, undefined, table_rules)
|
|
413
|
-
.then(data => {
|
|
414
|
-
if (socket_id && this.sockets[socket_id]) {
|
|
415
|
-
(0, exports.log)("Pushed " + data.length + " records to sub");
|
|
416
|
-
this.sockets[socket_id].emit(channel_name, { data }, () => {
|
|
417
|
-
resolve(data);
|
|
418
|
-
});
|
|
419
|
-
/* TO DO: confirm receiving data or server will unsubscribe
|
|
420
|
-
{ data }, (cb)=> { console.log(cb) });
|
|
421
|
-
*/
|
|
422
|
-
}
|
|
423
|
-
else if (func) {
|
|
424
|
-
func(data);
|
|
425
|
-
resolve(data);
|
|
426
|
-
}
|
|
427
|
-
sub.last_throttled = Date.now();
|
|
428
|
-
}).catch(err => {
|
|
429
|
-
const errObj = { _err_msg: err.toString(), err };
|
|
430
|
-
if (socket_id && this.sockets[socket_id]) {
|
|
431
|
-
this.sockets[socket_id].emit(channel_name, { err: errObj });
|
|
432
|
-
}
|
|
433
|
-
else if (func) {
|
|
434
|
-
func({ err: errObj });
|
|
435
|
-
}
|
|
436
|
-
reject(errObj);
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
}
|
|
307
|
+
pushSubData = pushSubData_1.pushSubData.bind(this);
|
|
440
308
|
upsertSocket(socket) {
|
|
441
309
|
if (socket && !this.sockets[socket.id]) {
|
|
442
310
|
this.sockets[socket.id] = socket;
|
|
443
|
-
socket.on("disconnect", () =>
|
|
311
|
+
socket.on("disconnect", () => {
|
|
312
|
+
this.subs = this.subs.filter(s => {
|
|
313
|
+
return !(s.socket && s.socket.id === socket.id);
|
|
314
|
+
});
|
|
315
|
+
this.syncs = this.syncs.filter(s => {
|
|
316
|
+
return !(s.socket_id && s.socket_id === socket.id);
|
|
317
|
+
});
|
|
318
|
+
delete this.sockets[socket.id];
|
|
319
|
+
return "ok";
|
|
320
|
+
});
|
|
444
321
|
}
|
|
445
322
|
}
|
|
446
323
|
syncTimeout;
|
|
447
324
|
async syncData(sync, clientData, source) {
|
|
448
325
|
return await (0, SyncReplication_1.syncData)(this, sync, clientData, source);
|
|
449
326
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
* A sync channel is unique per socket for each filter
|
|
453
|
-
*/
|
|
454
|
-
async addSync(syncParams) {
|
|
455
|
-
const { socket = null, table_info = null, table_rules, synced_field = null, allow_delete = false, id_fields = [], filter = {}, params, condition = "", throttle = 0 } = syncParams || {};
|
|
456
|
-
const conditionParsed = parseCondition(condition);
|
|
457
|
-
if (!socket || !table_info)
|
|
458
|
-
throw "socket or table_info missing";
|
|
459
|
-
const { name: table_name } = table_info, channel_name = `${this.socketChannelPreffix}.${table_name}.${JSON.stringify(filter)}.sync`;
|
|
460
|
-
if (!synced_field)
|
|
461
|
-
throw "synced_field missing from table_rules";
|
|
462
|
-
this.upsertSocket(socket);
|
|
463
|
-
const upsertSync = () => {
|
|
464
|
-
const newSync = {
|
|
465
|
-
channel_name,
|
|
466
|
-
table_name,
|
|
467
|
-
filter,
|
|
468
|
-
condition: conditionParsed,
|
|
469
|
-
synced_field,
|
|
470
|
-
id_fields,
|
|
471
|
-
allow_delete,
|
|
472
|
-
table_rules,
|
|
473
|
-
throttle: Math.max(throttle || 0, table_rules?.sync?.throttle || 0),
|
|
474
|
-
batch_size: (0, utils_1.get)(table_rules, "sync.batch_size") || exports.DEFAULT_SYNC_BATCH_SIZE,
|
|
475
|
-
last_throttled: 0,
|
|
476
|
-
socket_id: socket.id,
|
|
477
|
-
is_sync: true,
|
|
478
|
-
last_synced: 0,
|
|
479
|
-
lr: undefined,
|
|
480
|
-
table_info,
|
|
481
|
-
is_syncing: false,
|
|
482
|
-
wal: undefined,
|
|
483
|
-
socket,
|
|
484
|
-
params
|
|
485
|
-
};
|
|
486
|
-
/* Only a sync per socket per table per condition allowed */
|
|
487
|
-
this.syncs = this.syncs || [];
|
|
488
|
-
const existing = (0, util_1.find)(this.syncs, { socket_id: socket.id, channel_name });
|
|
489
|
-
if (!existing) {
|
|
490
|
-
this.syncs.push(newSync);
|
|
491
|
-
// console.log("Added SYNC");
|
|
492
|
-
socket.removeAllListeners(channel_name + "unsync");
|
|
493
|
-
socket.once(channel_name + "unsync", (_data, cb) => {
|
|
494
|
-
this.onSocketDisconnected(socket, channel_name);
|
|
495
|
-
cb(null, { res: "ok" });
|
|
496
|
-
});
|
|
497
|
-
socket.removeAllListeners(channel_name);
|
|
498
|
-
socket.on(channel_name, (data, cb) => {
|
|
499
|
-
if (!data) {
|
|
500
|
-
cb({ err: "Unexpected request. Need data or onSyncRequest" });
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
/*
|
|
504
|
-
*/
|
|
505
|
-
/* Server will:
|
|
506
|
-
1. Ask for last_synced emit(onSyncRequest)
|
|
507
|
-
2. Ask for data >= server_synced emit(onPullRequest)
|
|
508
|
-
-> Upsert that data
|
|
509
|
-
2. Push data >= last_synced emit(data.data)
|
|
510
|
-
|
|
511
|
-
Client will:
|
|
512
|
-
1. Send last_synced on(onSyncRequest)
|
|
513
|
-
2. Send data >= server_synced on(onPullRequest)
|
|
514
|
-
3. Send data on CRUD emit(data.data | data.deleted)
|
|
515
|
-
4. Upsert data.data | deleted on(data.data | data.deleted)
|
|
516
|
-
*/
|
|
517
|
-
// if(data.data){
|
|
518
|
-
// console.error("THIS SHOUKD NEVER FIRE !! NEW DATA FROM SYNC");
|
|
519
|
-
// this.upsertClientData(newSync, data.data);
|
|
520
|
-
// } else
|
|
521
|
-
if (data.onSyncRequest) {
|
|
522
|
-
// console.log("syncData from socket")
|
|
523
|
-
this.syncData(newSync, data.onSyncRequest, "client");
|
|
524
|
-
// console.log("onSyncRequest ", socket._user)
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
console.error("Unexpected sync request data from client: ", data);
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
// socket.emit(channel_name, { onSyncRequest: true }, (response) => {
|
|
531
|
-
// console.log(response)
|
|
532
|
-
// });
|
|
533
|
-
}
|
|
534
|
-
else {
|
|
535
|
-
console.warn("UNCLOSED DUPLICATE SYNC FOUND", existing.channel_name);
|
|
536
|
-
}
|
|
537
|
-
return newSync;
|
|
538
|
-
};
|
|
539
|
-
// const { min_id, max_id, count, max_synced } = params;
|
|
540
|
-
const _sync = upsertSync();
|
|
541
|
-
await this.addTrigger({ table_name, condition: conditionParsed });
|
|
542
|
-
return channel_name;
|
|
543
|
-
}
|
|
544
|
-
/* Must return a channel for socket */
|
|
545
|
-
/* The distinct list of channel names must have a corresponding trigger in the database */
|
|
546
|
-
async addSub(subscriptionParams) {
|
|
547
|
-
const { socket, func = null, table_info = null, table_rules, filter = {}, params = {}, condition = "", throttle = 0, //subOne = false,
|
|
548
|
-
viewOptions } = subscriptionParams || {};
|
|
549
|
-
let validated_throttle = subscriptionParams.throttle || 10;
|
|
550
|
-
if ((!socket && !func) || !table_info)
|
|
551
|
-
throw "socket/func or table_info missing";
|
|
552
|
-
const pubThrottle = (0, utils_1.get)(table_rules, ["subscribe", "throttle"]) || 0;
|
|
553
|
-
if (pubThrottle && Number.isInteger(pubThrottle) && pubThrottle > 0) {
|
|
554
|
-
validated_throttle = pubThrottle;
|
|
555
|
-
}
|
|
556
|
-
if (throttle && Number.isInteger(throttle) && throttle >= pubThrottle) {
|
|
557
|
-
validated_throttle = throttle;
|
|
558
|
-
}
|
|
559
|
-
const channel_name = `${this.socketChannelPreffix}.${table_info.name}.${JSON.stringify(filter)}.${JSON.stringify(params)}.${"m"}.sub`;
|
|
560
|
-
this.upsertSocket(socket);
|
|
561
|
-
const upsertSub = (newSubData, isReadyOverride) => {
|
|
562
|
-
const { table_name, condition: _cond, is_ready = false, parentSubParams } = newSubData, condition = parseCondition(_cond), newSub = {
|
|
563
|
-
socket,
|
|
564
|
-
table_name: table_info.name,
|
|
565
|
-
table_info,
|
|
566
|
-
filter,
|
|
567
|
-
params,
|
|
568
|
-
table_rules,
|
|
569
|
-
channel_name,
|
|
570
|
-
parentSubParams,
|
|
571
|
-
func: func ?? undefined,
|
|
572
|
-
socket_id: socket?.id,
|
|
573
|
-
throttle: validated_throttle,
|
|
574
|
-
is_throttling: null,
|
|
575
|
-
last_throttled: 0,
|
|
576
|
-
is_ready,
|
|
577
|
-
};
|
|
578
|
-
this.subs[table_name] = this.subs[table_name] ?? {};
|
|
579
|
-
this.subs[table_name][condition] = this.subs[table_name][condition] ?? { subs: [] };
|
|
580
|
-
this.subs[table_name][condition].subs = this.subs[table_name][condition].subs ?? [];
|
|
581
|
-
// console.log("1034 upsertSub", this.subs)
|
|
582
|
-
const sub_idx = this.subs[table_name][condition].subs.findIndex(s => s.channel_name === channel_name &&
|
|
583
|
-
(socket && s.socket_id === socket.id ||
|
|
584
|
-
func && s.func === func));
|
|
585
|
-
if (sub_idx < 0) {
|
|
586
|
-
this.subs[table_name][condition].subs.push(newSub);
|
|
587
|
-
if (socket) {
|
|
588
|
-
const chnUnsub = channel_name + "unsubscribe";
|
|
589
|
-
socket.removeAllListeners(chnUnsub);
|
|
590
|
-
socket.once(chnUnsub, (_data, cb) => {
|
|
591
|
-
const res = this.onSocketDisconnected(socket, channel_name);
|
|
592
|
-
cb(null, { res });
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
else {
|
|
597
|
-
this.subs[table_name][condition].subs[sub_idx] = newSub;
|
|
598
|
-
}
|
|
599
|
-
if (isReadyOverride ?? is_ready) {
|
|
600
|
-
this.pushSubData(newSub);
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
viewOptions?.relatedTables.map(async (relatedTable, relatedTableIdx) => {
|
|
604
|
-
const params = {
|
|
605
|
-
table_name: relatedTable.tableName,
|
|
606
|
-
condition: relatedTable.condition,
|
|
607
|
-
parentSubParams: {
|
|
608
|
-
...subscriptionParams,
|
|
609
|
-
channel_name
|
|
610
|
-
},
|
|
611
|
-
};
|
|
612
|
-
upsertSub({
|
|
613
|
-
...params,
|
|
614
|
-
is_ready: false,
|
|
615
|
-
}, false);
|
|
616
|
-
await this.addTrigger(params, viewOptions);
|
|
617
|
-
/** Trigger pushSubData only on last related table (if it's a view) to prevent duplicate firings */
|
|
618
|
-
const isLast = relatedTableIdx === viewOptions.relatedTables.length - 1;
|
|
619
|
-
upsertSub({
|
|
620
|
-
...params,
|
|
621
|
-
is_ready: true
|
|
622
|
-
}, isLast && !table_info.is_view);
|
|
623
|
-
});
|
|
624
|
-
if (table_info.is_view) {
|
|
625
|
-
if (!viewOptions?.relatedTables.length) {
|
|
626
|
-
throw "PubSubManager: view parent_tables missing";
|
|
627
|
-
}
|
|
628
|
-
return channel_name;
|
|
629
|
-
}
|
|
630
|
-
/* Just a table, add table + condition trigger */
|
|
631
|
-
// console.log(table_info, 202);
|
|
632
|
-
upsertSub({
|
|
633
|
-
table_name: table_info.name,
|
|
634
|
-
condition: parseCondition(condition),
|
|
635
|
-
parentSubParams: undefined,
|
|
636
|
-
is_ready: false
|
|
637
|
-
}, undefined);
|
|
638
|
-
await this.addTrigger({
|
|
639
|
-
table_name: table_info.name,
|
|
640
|
-
condition: parseCondition(condition),
|
|
641
|
-
});
|
|
642
|
-
upsertSub({
|
|
643
|
-
table_name: table_info.name,
|
|
644
|
-
condition: parseCondition(condition),
|
|
645
|
-
parentSubParams: undefined,
|
|
646
|
-
is_ready: true
|
|
647
|
-
}, undefined);
|
|
648
|
-
return channel_name;
|
|
649
|
-
}
|
|
650
|
-
removeLocalSub(table_name, condition, func) {
|
|
651
|
-
const cond = parseCondition(condition);
|
|
652
|
-
if ((0, utils_1.get)(this.subs, [table_name, cond, "subs"])) {
|
|
653
|
-
this.subs[table_name][cond].subs.map((sub, i) => {
|
|
654
|
-
if (sub.func && sub.func === func) {
|
|
655
|
-
this.subs[table_name][cond].subs.splice(i, 1);
|
|
656
|
-
}
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
else {
|
|
660
|
-
console.error("Could not unsubscribe. Subscription might not have initialised yet");
|
|
661
|
-
}
|
|
662
|
-
}
|
|
327
|
+
addSync = addSync_1.addSync.bind(this);
|
|
328
|
+
addSub = addSub_1.addSub.bind(this);
|
|
663
329
|
getActiveListeners = () => {
|
|
664
330
|
const result = [];
|
|
665
331
|
const upsert = (t, c) => {
|
|
@@ -670,63 +336,13 @@ class PubSubManager {
|
|
|
670
336
|
(this.syncs || []).map(s => {
|
|
671
337
|
upsert(s.table_name, s.condition);
|
|
672
338
|
});
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
upsert(table_name, condition);
|
|
677
|
-
}
|
|
339
|
+
this.subs.forEach(s => {
|
|
340
|
+
s.triggers.forEach(trg => {
|
|
341
|
+
upsert(trg.table_name, trg.condition);
|
|
678
342
|
});
|
|
679
343
|
});
|
|
680
344
|
return result;
|
|
681
345
|
};
|
|
682
|
-
onSocketDisconnected(socket, channel_name) {
|
|
683
|
-
// process.on('warning', e => {
|
|
684
|
-
// console.warn(e.stack)
|
|
685
|
-
// });
|
|
686
|
-
// console.log("onSocketDisconnected", channel_name, this.syncs)
|
|
687
|
-
if (this.subs) {
|
|
688
|
-
Object.keys(this.subs).map(table_name => {
|
|
689
|
-
Object.keys(this.subs[table_name]).map(condition => {
|
|
690
|
-
this.subs[table_name][condition].subs.map((sub, i) => {
|
|
691
|
-
/**
|
|
692
|
-
* If a channel name is specified then delete triggers
|
|
693
|
-
*/
|
|
694
|
-
if ((socket && sub.socket_id === socket.id) &&
|
|
695
|
-
(!channel_name || sub.channel_name === channel_name)) {
|
|
696
|
-
this.subs[table_name][condition].subs.splice(i, 1);
|
|
697
|
-
if (!this.subs[table_name][condition].subs.length) {
|
|
698
|
-
delete this.subs[table_name][condition];
|
|
699
|
-
if ((0, prostgles_types_1.isEmpty)(this.subs[table_name])) {
|
|
700
|
-
delete this.subs[table_name];
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
});
|
|
705
|
-
});
|
|
706
|
-
});
|
|
707
|
-
}
|
|
708
|
-
if (this.syncs) {
|
|
709
|
-
this.syncs = this.syncs.filter(s => {
|
|
710
|
-
const matchesSocket = Boolean(socket && s.socket_id !== socket.id);
|
|
711
|
-
if (channel_name) {
|
|
712
|
-
return matchesSocket || s.channel_name !== channel_name;
|
|
713
|
-
}
|
|
714
|
-
return matchesSocket;
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
if (!socket) {
|
|
718
|
-
// Do nothing
|
|
719
|
-
}
|
|
720
|
-
else if (!channel_name) {
|
|
721
|
-
delete this.sockets[socket.id];
|
|
722
|
-
}
|
|
723
|
-
else {
|
|
724
|
-
socket.removeAllListeners(channel_name);
|
|
725
|
-
socket.removeAllListeners(channel_name + "unsync");
|
|
726
|
-
socket.removeAllListeners(channel_name + "unsubscribe");
|
|
727
|
-
}
|
|
728
|
-
return "ok";
|
|
729
|
-
}
|
|
730
346
|
checkIfTimescaleBug = async (table_name) => {
|
|
731
347
|
const schema = "_timescaledb_catalog", res = await this.db.oneOrNone("SELECT EXISTS( \
|
|
732
348
|
SELECT * \
|
|
@@ -810,6 +426,7 @@ class PubSubManager {
|
|
|
810
426
|
}
|
|
811
427
|
exports.PubSubManager = PubSubManager;
|
|
812
428
|
const parseCondition = (condition) => condition && condition.trim().length ? condition : "TRUE";
|
|
429
|
+
exports.parseCondition = parseCondition;
|
|
813
430
|
var prostgles_types_2 = require("prostgles-types");
|
|
814
431
|
Object.defineProperty(exports, "pickKeys", { enumerable: true, get: function () { return prostgles_types_2.pickKeys; } });
|
|
815
432
|
Object.defineProperty(exports, "omitKeys", { enumerable: true, get: function () { return prostgles_types_2.omitKeys; } });
|