prostgles-server 4.2.60 → 4.2.61

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.
Files changed (35) hide show
  1. package/dist/AuthHandler.d.ts +4 -0
  2. package/dist/AuthHandler.d.ts.map +1 -1
  3. package/dist/AuthHandler.js +13 -0
  4. package/dist/AuthHandler.js.map +1 -1
  5. package/dist/DboBuilder/DboBuilderTypes.d.ts +2 -0
  6. package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
  7. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  8. package/dist/DboBuilder/ViewHandler/ViewHandler.js +8 -1
  9. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  10. package/dist/Logging.d.ts +24 -18
  11. package/dist/Logging.d.ts.map +1 -1
  12. package/dist/Prostgles.d.ts.map +1 -1
  13. package/dist/Prostgles.js +75 -58
  14. package/dist/Prostgles.js.map +1 -1
  15. package/dist/PubSubManager/PubSubManager.d.ts +3 -0
  16. package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
  17. package/dist/PubSubManager/PubSubManager.js +2 -0
  18. package/dist/PubSubManager/PubSubManager.js.map +1 -1
  19. package/dist/PubSubManager/addSync.d.ts +1 -2
  20. package/dist/PubSubManager/addSync.d.ts.map +1 -1
  21. package/dist/PubSubManager/addSync.js +6 -13
  22. package/dist/PubSubManager/addSync.js.map +1 -1
  23. package/dist/SyncReplication.d.ts.map +1 -1
  24. package/dist/SyncReplication.js +30 -19
  25. package/dist/SyncReplication.js.map +1 -1
  26. package/lib/AuthHandler.ts +12 -0
  27. package/lib/DboBuilder/DboBuilderTypes.ts +2 -1
  28. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +8 -1
  29. package/lib/Logging.ts +27 -17
  30. package/lib/Prostgles.ts +81 -60
  31. package/lib/PubSubManager/PubSubManager.ts +3 -0
  32. package/lib/PubSubManager/addSync.ts +7 -17
  33. package/lib/SyncReplication.ts +38 -24
  34. package/package.json +2 -2
  35. package/tests/server/package-lock.json +3 -3
package/lib/Prostgles.ts CHANGED
@@ -384,9 +384,9 @@ export class Prostgles {
384
384
  type: "debug",
385
385
  command: "refreshDBO.start",
386
386
  duration: -1,
387
- data: { work_mem: await this.db?.oneOrNone(`show work_mem;`) }
387
+ data: { }
388
388
  });
389
- const now = Date.now();
389
+ const start = Date.now();
390
390
  if (this._dboBuilder) {
391
391
  await this._dboBuilder.build();
392
392
  } else {
@@ -394,7 +394,7 @@ export class Prostgles {
394
394
  }
395
395
  if (!this.dboBuilder) throw "this.dboBuilder";
396
396
  this.dbo = this.dboBuilder.dbo;
397
- await this.opts.onLog?.({ type: "debug", command: "refreshDBO.end", duration: Date.now() - now })
397
+ await this.opts.onLog?.({ type: "debug", command: "refreshDBO.end", duration: Date.now() - start })
398
398
  return this.dbo;
399
399
  }
400
400
 
@@ -429,7 +429,7 @@ export class Prostgles {
429
429
  }
430
430
  });
431
431
  await this.opts.onLog?.({ type: "debug", command: "initTableConfig", ...res });
432
- if(res.error !== undefined) throw res.error;
432
+ if(res.hasError) throw res.error;
433
433
  return res.data;
434
434
  }
435
435
 
@@ -619,70 +619,91 @@ export class Prostgles {
619
619
  }
620
620
 
621
621
  getClientSchema = async (clientReq: Pick<LocalParams, "socket" | "httpReq">) => {
622
- const clientInfo = clientReq.socket? { type: "socket" as const, socket: clientReq.socket } : clientReq.httpReq? { type: "http" as const, httpReq: clientReq.httpReq } : undefined;
623
- if(!clientInfo) throw "Invalid client";
624
- if(!this.authHandler) throw "this.authHandler missing";
625
- const userData = await this.authHandler.getClientInfo(clientInfo);
626
- const { publishParser } = this;
627
- let fullSchema: {
628
- schema: TableSchemaForClient;
629
- tables: DBSchemaTable[];
630
- } | undefined;
631
- let publishValidationError;
632
622
 
633
- try {
634
- if (!publishParser) throw "publishParser undefined";
635
- fullSchema = await publishParser.getSchemaFromPublish({ ...clientInfo, userData });
636
- } catch (e) {
637
- publishValidationError = "Server Error: PUBLISH VALIDATION ERROR";
638
- console.error(`\nProstgles PUBLISH VALIDATION ERROR (after socket connected):\n ->`, e);
639
- }
640
- let rawSQL = false;
641
- if (this.opts.publishRawSQL && typeof this.opts.publishRawSQL === "function") {
642
- const { allowed } = await clientCanRunSqlRequest.bind(this)(clientInfo);
643
- rawSQL = allowed;
644
- }
623
+ const result = await tryCatch(async () => {
645
624
 
646
- const { schema, tables } = fullSchema ?? { schema: {}, tables: [] };
647
- const joinTables2: string[][] = [];
648
- if (this.opts.joins) {
649
- const _joinTables2 = this.dboBuilder.getAllJoinPaths()
650
- .filter(jp =>
651
- ![jp.t1, jp.t2].find(t => !schema[t] || !schema[t]?.findOne)
652
- ).map(jp => [jp.t1, jp.t2].sort());
653
- _joinTables2.map(jt => {
654
- if (!joinTables2.find(_jt => _jt.join() === jt.join())) {
655
- joinTables2.push(jt);
656
- }
657
- });
658
- }
625
+ const clientInfo = clientReq.socket? { type: "socket" as const, socket: clientReq.socket } : clientReq.httpReq? { type: "http" as const, httpReq: clientReq.httpReq } : undefined;
626
+ if(!clientInfo) throw "Invalid client";
627
+ if(!this.authHandler) throw "this.authHandler missing";
628
+ const userData = await this.authHandler.getClientInfo(clientInfo);
659
629
 
660
- const methods = await publishParser?.getAllowedMethods(clientInfo, userData);
630
+ const { publishParser } = this;
631
+ let fullSchema: {
632
+ schema: TableSchemaForClient;
633
+ tables: DBSchemaTable[];
634
+ } | undefined;
635
+ let publishValidationError;
661
636
 
662
- const methodSchema: ClientSchema["methods"] = !methods? [] : getKeys(methods).map(methodName => {
663
- const method = methods[methodName];
637
+ try {
638
+ if (!publishParser) throw "publishParser undefined";
639
+ fullSchema = await publishParser.getSchemaFromPublish({ ...clientInfo, userData });
640
+ } catch (e) {
641
+ publishValidationError = e;
642
+ console.error(`\nProstgles Publish validation failed (after socket connected):\n ->`, e);
643
+ }
644
+ let rawSQL = false;
645
+ if (this.opts.publishRawSQL && typeof this.opts.publishRawSQL === "function") {
646
+ const { allowed } = await clientCanRunSqlRequest.bind(this)(clientInfo);
647
+ rawSQL = allowed;
648
+ }
664
649
 
665
- if(isObject(method) && "run" in method){
666
- return {
667
- name: methodName,
668
- ...omitKeys(method, ["run"]),
650
+ const { schema, tables } = fullSchema ?? { schema: {}, tables: [] };
651
+ const joinTables2: string[][] = [];
652
+ if (this.opts.joins) {
653
+ const _joinTables2 = this.dboBuilder.getAllJoinPaths()
654
+ .filter(jp =>
655
+ ![jp.t1, jp.t2].find(t => !schema[t] || !schema[t]?.findOne)
656
+ ).map(jp => [jp.t1, jp.t2].sort());
657
+ _joinTables2.map(jt => {
658
+ if (!joinTables2.find(_jt => _jt.join() === jt.join())) {
659
+ joinTables2.push(jt);
660
+ }
661
+ });
662
+ }
663
+
664
+ const methods = await publishParser?.getAllowedMethods(clientInfo, userData);
665
+
666
+ const methodSchema: ClientSchema["methods"] = !methods? [] : getKeys(methods).map(methodName => {
667
+ const method = methods[methodName];
668
+
669
+ if(isObject(method) && "run" in method){
670
+ return {
671
+ name: methodName,
672
+ ...omitKeys(method, ["run"]),
673
+ }
669
674
  }
675
+ return methodName;
676
+ });
677
+
678
+ const { auth } = clientReq.socket? await this.authHandler.makeSocketAuth(clientReq.socket) : { auth: {} };
679
+
680
+ const clientSchema: ClientSchema = {
681
+ schema,
682
+ methods: methodSchema,
683
+ tableSchema: tables,
684
+ rawSQL,
685
+ joinTables: joinTables2,
686
+ auth,
687
+ version,
688
+ err: publishValidationError? "Server Error: User publish validation failed." : undefined
689
+ };
690
+
691
+ return {
692
+ publishValidationError,
693
+ clientSchema,
694
+ userData
670
695
  }
671
- return methodName;
672
696
  });
673
-
674
- const { auth } = clientReq.socket? await this.authHandler.makeSocketAuth(clientReq.socket) : { auth: {} };
675
- const clientSchema: ClientSchema = {
676
- schema,
677
- methods: methodSchema,
678
- tableSchema: tables,
679
- rawSQL,
680
- joinTables: joinTables2,
681
- auth,
682
- version,
683
- err: publishValidationError
684
- }
685
- return clientSchema;
697
+ const sid = result.userData?.sid ?? this.authHandler?.getSIDNoError(clientReq);
698
+ await this.opts.onLog?.({
699
+ type: "connect.getClientSchema",
700
+ duration: result.duration,
701
+ sid,
702
+ socketId: clientReq.socket?.id,
703
+ error: result.error || result.publishValidationError,
704
+ });
705
+ if(result.hasError) throw result.error;
706
+ return result.clientSchema;
686
707
  }
687
708
 
688
709
  pushSocketSchema = async (socket: PRGLIOSocket) => {
@@ -43,6 +43,7 @@ export type BasicCallback = (err?: any, res?: any) => void
43
43
 
44
44
  export type SyncParams = {
45
45
  socket_id: string;
46
+ sid: string | undefined;
46
47
  channel_name: string;
47
48
  table_name: string;
48
49
  table_rules?: TableRule;
@@ -375,6 +376,7 @@ export class PubSubManager {
375
376
  command: "upsertSocket.disconnect",
376
377
  tableName: "",
377
378
  duration: 0,
379
+ sid: this.dboBuilder.prostgles.authHandler?.getSIDNoError({ socket }),
378
380
  socketId: socket.id,
379
381
  connectedSocketIds: this.connectedSocketIds,
380
382
  remainingSubs: JSON.stringify(this.subs.map(s => ({ tableName: s.table_info.name, triggers: s.triggers }))),
@@ -498,6 +500,7 @@ export class PubSubManager {
498
500
  socketId: socket?.id,
499
501
  state: !addedTrigger.tbl? "fail" : "ok",
500
502
  error: addedTrigger.error,
503
+ sid: this.dboBuilder.prostgles.authHandler?.getSIDNoError({ socket }),
501
504
  tableName: addedTrigger.tbl ?? params.table_name,
502
505
  connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map(s => s.id),
503
506
  localParams: { socket }
@@ -1,6 +1,5 @@
1
1
  import { find, tryCatch } from "prostgles-types/dist/util";
2
- import { BasicCallback, parseCondition, PubSubManager } from "./PubSubManager";
3
- import { AddSyncParams, DEFAULT_SYNC_BATCH_SIZE } from "./PubSubManager";
2
+ import { AddSyncParams, BasicCallback, DEFAULT_SYNC_BATCH_SIZE, PubSubManager, parseCondition } from "./PubSubManager";
4
3
 
5
4
  /**
6
5
  * Returns a sync channel
@@ -8,6 +7,7 @@ import { AddSyncParams, DEFAULT_SYNC_BATCH_SIZE } from "./PubSubManager";
8
7
  */
9
8
  export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
10
9
 
10
+ const sid = this.dboBuilder.prostgles.authHandler?.getSIDNoError({ socket: syncParams.socket });
11
11
  const res = await tryCatch(async () => {
12
12
 
13
13
  const {
@@ -18,7 +18,6 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
18
18
  const conditionParsed = parseCondition(condition);
19
19
  if (!socket || !table_info) throw "socket or table_info missing";
20
20
 
21
-
22
21
  const { name: table_name } = table_info;
23
22
  const channel_name = `${this.socketChannelPreffix}.${table_name}.${JSON.stringify(filter)}.sync`;
24
23
 
@@ -33,12 +32,12 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
33
32
  filter,
34
33
  condition: conditionParsed,
35
34
  synced_field,
35
+ sid,
36
36
  id_fields,
37
37
  allow_delete,
38
38
  table_rules,
39
39
  throttle: Math.max(throttle || 0, table_rules?.sync?.throttle || 0),
40
40
  batch_size: table_rules?.sync?.batch_size || DEFAULT_SYNC_BATCH_SIZE,
41
- // last_throttled: 0,
42
41
  socket_id: socket.id,
43
42
  is_sync: true,
44
43
  last_synced: 0,
@@ -65,7 +64,9 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
65
64
  socketId: socket.id,
66
65
  tableName: table_name,
67
66
  condition,
68
- connectedSocketIds: this.connectedSocketIds,
67
+ sid,
68
+ connectedSocketIds: this.connectedSocketIds,
69
+ duration: -1,
69
70
  });
70
71
  socket.removeAllListeners(channel_name);
71
72
  socket.removeAllListeners(unsyncChn);
@@ -100,23 +101,14 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
100
101
  4. Upsert data.data | deleted on(data.data | data.deleted)
101
102
  */
102
103
 
103
- // if(data.data){
104
- // console.error("THIS SHOUKD NEVER FIRE !! NEW DATA FROM SYNC");
105
- // this.upsertClientData(newSync, data.data);
106
- // } else
107
104
  if (data.onSyncRequest) {
108
- // console.log("syncData from socket")
109
105
  this.syncData(newSync, data.onSyncRequest, "client");
110
106
 
111
- // console.log("onSyncRequest ", socket._user)
112
107
  } else {
113
108
  console.error("Unexpected sync request data from client: ", data)
114
109
  }
115
110
  });
116
111
 
117
- // socket.emit(channel_name, { onSyncRequest: true }, (response) => {
118
- // console.log(response)
119
- // });
120
112
  } else {
121
113
  console.warn("UNCLOSED DUPLICATE SYNC FOUND", existing.channel_name);
122
114
  }
@@ -124,9 +116,6 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
124
116
  return newSync;
125
117
  };
126
118
 
127
-
128
- // const { min_id, max_id, count, max_synced } = params;
129
-
130
119
  upsertSync();
131
120
 
132
121
  await this.addTrigger({ table_name, condition: conditionParsed }, undefined, socket);
@@ -143,6 +132,7 @@ export async function addSync(this: PubSubManager, syncParams: AddSyncParams) {
143
132
  connectedSocketIds: this.connectedSocketIds,
144
133
  duration: res.duration,
145
134
  error: res.error,
135
+ sid,
146
136
  });
147
137
 
148
138
  if(res.error !== undefined) throw res.error;
@@ -50,11 +50,14 @@ export async function syncData (this: PubSubManager, sync: SyncParams, clientDat
50
50
  type: "sync",
51
51
  command: "syncData",
52
52
  tableName: sync.table_name,
53
+ sid: sync.sid,
53
54
  source,
54
55
  ...pickKeys(sync, ["socket_id", "condition", "last_synced", "is_syncing"]),
55
56
  lr: JSON.stringify(sync.lr),
56
57
  connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map(s => s.id),
57
- localParams: undefined
58
+ localParams: undefined,
59
+ duration: -1,
60
+ socketId: sync.socket_id
58
61
  });
59
62
 
60
63
  const {
@@ -193,16 +196,8 @@ export async function syncData (this: PubSubManager, sync: SyncParams, clientDat
193
196
  */
194
197
  upsertData = async (data: AnyObject[]) => {
195
198
 
196
- await this._log({
197
- type: "sync",
198
- command: "upsertData",
199
- tableName: sync.table_name,
200
- rows: data.length,
201
- socketId: socket_id,
202
- connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map(s => s.id)
203
- });
204
-
205
- return this.dboBuilder.getTX(async (dbTX) => {
199
+ const start = Date.now();
200
+ const result = await this.dboBuilder.getTX(async (dbTX) => {
206
201
  const tbl = dbTX[table_name] as TableHandler;
207
202
  const existingData = await tbl.find(
208
203
  { $or: data.map(d => pickKeys(d, id_fields)) },
@@ -247,26 +242,32 @@ export async function syncData (this: PubSubManager, sync: SyncParams, clientDat
247
242
  log(`upsertData: inserted( ${inserts.length} ) updated( ${updates.length} ) total( ${data.length} ) \n last insert ${JSON.stringify(inserts.at(-1))} \n last update ${JSON.stringify(updates.at(-1))}`);
248
243
  return { inserted: inserts.length, updated: updates.length, total: data.length };
249
244
  })
250
- .catch(err => {
251
- console.trace("Something went wrong with syncing to server: \n ->", err, data.length, id_fields);
252
- return Promise.reject("Something went wrong with syncing to server: ")
253
- });
254
- },
245
+ .catch(err => {
246
+ console.trace("Something went wrong with syncing to server: \n ->", err, data.length, id_fields);
247
+ return Promise.reject("Something went wrong with syncing to server: ")
248
+ });
255
249
 
256
- /**
257
- * Pushes the given data to client
258
- * @param isSynced = true if
259
- */
260
- pushData = async (data?: AnyObject[], isSynced = false, err: any = null) => {
261
250
  await this._log({
262
251
  type: "sync",
263
- command: "pushData",
252
+ command: "upsertData",
264
253
  tableName: sync.table_name,
265
- rows: data?.length ?? 0,
254
+ rows: data.length,
266
255
  socketId: socket_id,
256
+ sid: sync.sid,
257
+ duration: Date.now() - start,
267
258
  connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map(s => s.id)
268
259
  });
269
- return new Promise((resolve, reject) => {
260
+
261
+ return result;
262
+ },
263
+
264
+ /**
265
+ * Pushes the given data to client
266
+ * @param isSynced = true if
267
+ */
268
+ pushData = async (data?: AnyObject[], isSynced = false, err: any = null) => {
269
+ const start = Date.now();
270
+ const result = await new Promise((resolve, reject) => {
270
271
  socket.emit(channel_name, { data, isSynced }, (resp?: { ok: boolean }) => {
271
272
 
272
273
  if (resp && resp.ok) {
@@ -278,6 +279,19 @@ export async function syncData (this: PubSubManager, sync: SyncParams, clientDat
278
279
  }
279
280
  });
280
281
  });
282
+
283
+ await this._log({
284
+ type: "sync",
285
+ command: "pushData",
286
+ tableName: sync.table_name,
287
+ rows: data?.length ?? 0,
288
+ socketId: socket_id,
289
+ duration: Date.now() - start,
290
+ sid: sync.sid,
291
+ connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map(s => s.id)
292
+ });
293
+
294
+ return result;
281
295
  },
282
296
 
283
297
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "4.2.60",
3
+ "version": "4.2.61",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,7 +43,7 @@
43
43
  "pg-cursor": "^2.10.5",
44
44
  "pg-promise": "^11.6.0",
45
45
  "prostgles-client": "^4.0.53",
46
- "prostgles-types": "^4.0.85"
46
+ "prostgles-types": "^4.0.86"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/bluebird": "^3.5.36",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "../..": {
23
23
  "name": "prostgles-server",
24
- "version": "4.2.59",
24
+ "version": "4.2.60",
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
27
  "bluebird": "^3.7.2",
@@ -32,7 +32,7 @@
32
32
  "pg-cursor": "^2.10.5",
33
33
  "pg-promise": "^11.6.0",
34
34
  "prostgles-client": "^4.0.53",
35
- "prostgles-types": "^4.0.85"
35
+ "prostgles-types": "^4.0.86"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/bluebird": "^3.5.36",
@@ -1548,7 +1548,7 @@
1548
1548
  "pg-cursor": "^2.10.5",
1549
1549
  "pg-promise": "^11.6.0",
1550
1550
  "prostgles-client": "^4.0.53",
1551
- "prostgles-types": "^4.0.85",
1551
+ "prostgles-types": "^4.0.86",
1552
1552
  "typescript": "^5.3.3"
1553
1553
  }
1554
1554
  },