prostgles-server 4.2.646 → 4.2.648

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 (113) hide show
  1. package/.github/workflows/main.yml +1 -1
  2. package/debug/after-commit-fix-build.log +4 -0
  3. package/debug/after-commit-fix-client-build.log +0 -0
  4. package/debug/after-commit-fix-client.log +674 -0
  5. package/debug/after-commit-fix-lint.log +4 -0
  6. package/debug/after-commit-fix-server.log +542 -0
  7. package/debug/after-commit-fix-test-build.log +0 -0
  8. package/debug/after-commit-fix-typecheck.log +8 -0
  9. package/debug/after-commit-review-build.log +4 -0
  10. package/debug/after-commit-review-regressions.log +604 -0
  11. package/debug/after-commit-review-reproductions.patch +62 -0
  12. package/debug/after-commit-review-restored-build.log +0 -0
  13. package/debug/after-commit-review-server.log +3249 -0
  14. package/debug/after-commit-review-test-build.log +0 -0
  15. package/debug/after-commit-review-typecheck.log +8 -0
  16. package/debug/after-commit-review-withUserRLS.original.ts +554 -0
  17. package/debug/after-commit-shared-query-build.log +4 -0
  18. package/debug/after-commit-shared-query-lint.log +4 -0
  19. package/debug/after-commit-shared-query-server.log +3253 -0
  20. package/debug/inspect-ui-sync.cjs +24 -0
  21. package/debug/subscription-cleanup-repro.log +662 -0
  22. package/debug/subscription-cleanup-trace.log +7230 -0
  23. package/debug/sync-bigint-DBGeneratedSchema.backup +489 -0
  24. package/debug/sync-bigint-build.log +4 -0
  25. package/debug/sync-bigint-client-build.log +0 -0
  26. package/debug/sync-bigint-lint.log +4 -0
  27. package/debug/sync-bigint-server-build.log +0 -0
  28. package/debug/sync-comment-DBGeneratedSchema.backup +489 -0
  29. package/debug/sync-delay-gate-DBGeneratedSchema.backup +489 -0
  30. package/debug/sync-delay-gate-build.log +0 -0
  31. package/debug/sync-diff-review-test.log +132 -0
  32. package/debug/sync-followup-build.log +4 -0
  33. package/debug/sync-notification-before.log +121 -0
  34. package/debug/sync-trigger-cleanup-before.log +134 -0
  35. package/debug/sync-trigger-fix-e2e.log +1758 -0
  36. package/debug/sync-trigger-fix-npm-test.log +1815 -0
  37. package/debug/sync-trigger-lint.log +4 -0
  38. package/debug/trace-subscription-cleanup.cjs +19 -0
  39. package/debug/ui-sync-database-snapshot.log +8 -0
  40. package/debug/ui-sync-investigation.md +30 -0
  41. package/debug/ui-sync-server-tests.log +553 -0
  42. package/dist/DboBuilder/TableHandler/TableHandler.d.ts +13 -0
  43. package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
  44. package/dist/DboBuilder/TableHandler/TableHandler.js +13 -0
  45. package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
  46. package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.d.ts.map +1 -1
  47. package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js +12 -0
  48. package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js.map +1 -1
  49. package/dist/DboBuilder/TableHandler/isApplicableHook.js +1 -1
  50. package/dist/DboBuilder/TableHandler/isApplicableHook.js.map +1 -1
  51. package/dist/DboBuilder/TableHandler/updateBatch.d.ts.map +1 -1
  52. package/dist/DboBuilder/TableHandler/updateBatch.js +18 -0
  53. package/dist/DboBuilder/TableHandler/updateBatch.js.map +1 -1
  54. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts +1 -0
  55. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts.map +1 -1
  56. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js +6 -4
  57. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js.map +1 -1
  58. package/dist/Prostgles.d.ts +2 -0
  59. package/dist/Prostgles.d.ts.map +1 -1
  60. package/dist/Prostgles.js +2 -0
  61. package/dist/Prostgles.js.map +1 -1
  62. package/dist/PubSubManager/PubSubManager.d.ts +8 -25
  63. package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
  64. package/dist/PubSubManager/PubSubManager.js +27 -23
  65. package/dist/PubSubManager/PubSubManager.js.map +1 -1
  66. package/dist/PubSubManager/deleteOrphanedTriggers.d.ts.map +1 -1
  67. package/dist/PubSubManager/deleteOrphanedTriggers.js +5 -3
  68. package/dist/PubSubManager/deleteOrphanedTriggers.js.map +1 -1
  69. package/dist/PubSubManager/init/getDataWatchFunctionQuery.d.ts.map +1 -1
  70. package/dist/PubSubManager/init/getDataWatchFunctionQuery.js +1 -2
  71. package/dist/PubSubManager/init/getDataWatchFunctionQuery.js.map +1 -1
  72. package/dist/PubSubManager/init/getPubSubManagerInitQuery.d.ts.map +1 -1
  73. package/dist/PubSubManager/init/getPubSubManagerInitQuery.js +3 -2
  74. package/dist/PubSubManager/init/getPubSubManagerInitQuery.js.map +1 -1
  75. package/dist/PubSubManager/notifListener.js +2 -2
  76. package/dist/PubSubManager/notifListener.js.map +1 -1
  77. package/dist/PubSubManager/refreshTriggers.d.ts.map +1 -1
  78. package/dist/PubSubManager/refreshTriggers.js +5 -3
  79. package/dist/PubSubManager/refreshTriggers.js.map +1 -1
  80. package/dist/PublishParser/publishTypesAndUtils.d.ts +15 -1
  81. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  82. package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
  83. package/dist/TableHooks/TableHooks.d.ts +12 -4
  84. package/dist/TableHooks/TableHooks.d.ts.map +1 -1
  85. package/dist/WebsocketAPI/getClientHandlers.d.ts +9 -0
  86. package/dist/WebsocketAPI/getClientHandlers.d.ts.map +1 -1
  87. package/dist/WebsocketAPI/getClientHandlers.js +12 -1
  88. package/dist/WebsocketAPI/getClientHandlers.js.map +1 -1
  89. package/dist/index.d.ts +2 -1
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/initProstgles.d.ts +3 -11
  93. package/dist/initProstgles.d.ts.map +1 -1
  94. package/dist/initProstgles.js +1 -11
  95. package/dist/initProstgles.js.map +1 -1
  96. package/lib/DboBuilder/TableHandler/TableHandler.ts +13 -0
  97. package/lib/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.ts +13 -0
  98. package/lib/DboBuilder/TableHandler/isApplicableHook.ts +1 -1
  99. package/lib/DboBuilder/TableHandler/updateBatch.ts +28 -1
  100. package/lib/DboBuilder/ViewHandler/getReturnTypeQuery.ts +8 -3
  101. package/lib/Prostgles.ts +7 -0
  102. package/lib/PubSubManager/PubSubManager.ts +31 -28
  103. package/lib/PubSubManager/deleteOrphanedTriggers.ts +5 -3
  104. package/lib/PubSubManager/init/getDataWatchFunctionQuery.ts +1 -2
  105. package/lib/PubSubManager/init/getPubSubManagerInitQuery.ts +3 -2
  106. package/lib/PubSubManager/notifListener.ts +2 -2
  107. package/lib/PubSubManager/refreshTriggers.ts +7 -5
  108. package/lib/PublishParser/publishTypesAndUtils.ts +16 -1
  109. package/lib/TableHooks/TableHooks.ts +14 -2
  110. package/lib/WebsocketAPI/getClientHandlers.ts +37 -0
  111. package/lib/index.ts +5 -0
  112. package/lib/initProstgles.ts +7 -30
  113. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"initProstgles.js","sourceRoot":"","sources":["../lib/initProstgles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"initProstgles.js","sourceRoot":"","sources":["../lib/initProstgles.ts"],"names":[],"mappings":"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"}
@@ -176,6 +176,18 @@ export class TableHandler extends ViewHandler {
176
176
  } as const;
177
177
  })
178
178
  .filter(isDefined);
179
+ const afterCommitHooks = this.hooks?.afterCommit
180
+ ?.map((hook) => {
181
+ const { commands } = hook;
182
+ if (!commands[command.name]) {
183
+ return;
184
+ }
185
+ return {
186
+ type: "afterCommit",
187
+ ...hook,
188
+ } as const;
189
+ })
190
+ .filter(isDefined);
179
191
  return [
180
192
  ...(afterEachHooks ?? []),
181
193
  ...(postValidate ?
@@ -185,6 +197,7 @@ export class TableHandler extends ViewHandler {
185
197
  [{ type: "checkFilter", checkFilter, changedFields: undefined } as const]
186
198
  : []),
187
199
  ...(afterAllHooks ?? []),
200
+ ...(afterCommitHooks ?? []),
188
201
  ];
189
202
  };
190
203
  shouldWrapInTx = (
@@ -125,6 +125,19 @@ export const executeAfterHooksCheckAndPostValidation = async ({
125
125
  localParams,
126
126
  context: tableHandler.dboBuilder.prostgles.context,
127
127
  });
128
+ } else if (hook.type === "afterCommit" && applicableRows.length) {
129
+ const context = tableHandler.dboBuilder.prostgles.context;
130
+ txParams.onCommit(({ db, dbo }) =>
131
+ hook.run({
132
+ rows: applicableRows,
133
+ command,
134
+ context,
135
+ db,
136
+ dbo,
137
+ getClientDBHandlers: tableHandler.dboBuilder.prostgles.getClientDBHandlers,
138
+ localParams,
139
+ }),
140
+ );
128
141
  }
129
142
  }
130
143
  } finally {
@@ -12,7 +12,7 @@ export const isApplicableHook = (
12
12
  const getChangedFieldsSet = () => {
13
13
  changedFieldsSet ??= new Set(
14
14
  tableHandler.column_names.filter((col) =>
15
- rows.some((row) => row[col] !== undefined && row[col] !== null),
15
+ rows.some((row) => row[col] !== undefined),
16
16
  ),
17
17
  );
18
18
  return changedFieldsSet;
@@ -8,7 +8,7 @@ import {
8
8
  withUserRLS,
9
9
  } from "../DboBuilder";
10
10
  import type { TableHandler } from "./TableHandler";
11
- import { getReturnTypeQuery } from "../ViewHandler/getReturnTypeQuery";
11
+ import { getReturnTypeQuery, isReturningQuery } from "../ViewHandler/getReturnTypeQuery";
12
12
 
13
13
  export async function updateBatch(
14
14
  this: TableHandler,
@@ -24,6 +24,33 @@ export async function updateBatch(
24
24
  if (checkFilter || postValidate) {
25
25
  throw `updateBatch not allowed for tables with checkFilter or postValidate rules`;
26
26
  }
27
+ const hasHooks =
28
+ this.getAfterHooksAndChecks({ name: "update", rule: tableRules?.update }, localParams).length ||
29
+ this.hooks?.beforeEach?.some(({ commands }) => commands.update);
30
+ if (hasHooks && !isReturningQuery(params?.returnType, localParams)) {
31
+ if (!this.getTransaction(localParams)) {
32
+ return this.dboBuilder.getTX((dbx) =>
33
+ dbx[this.name]!.updateBatch(updates, params, undefined, tableRules, localParams),
34
+ );
35
+ }
36
+ // Run the full update pipeline so hooks share the batch transaction.
37
+ for (const [filter, data] of updates) {
38
+ await this.update(
39
+ filter,
40
+ data,
41
+ { ...(params ?? {}), returning: undefined },
42
+ tableRules,
43
+ localParams,
44
+ );
45
+ }
46
+ await this._log({
47
+ command: "updateBatch",
48
+ localParams,
49
+ data: { data: updates, params },
50
+ duration: Date.now() - start,
51
+ });
52
+ return null;
53
+ }
27
54
  const updateQueries: string[] = await Promise.all(
28
55
  updates.map(async ([filter, data]) => {
29
56
  const query = (await this.update(
@@ -26,6 +26,9 @@ export const getReturnTypeQuery = async ({
26
26
  if (localParams?.returnNewQuery) {
27
27
  return newQuery;
28
28
  }
29
+ if (!isReturningQuery(returnType, localParams)) {
30
+ return;
31
+ }
29
32
 
30
33
  if (returnType === "statement-where" || localParams?.returnQuery === "where-condition") {
31
34
  if (!newQuery) {
@@ -37,9 +40,6 @@ export const getReturnTypeQuery = async ({
37
40
  return localParams.returnQuery === "noRLS" ? queryWithoutRLS : queryWithRLS;
38
41
  }
39
42
 
40
- if (!sqlTypes.some((v) => v === returnType)) {
41
- return;
42
- }
43
43
  if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams?.clientReq))) {
44
44
  throw `Not allowed: { returnType: ${JSON.stringify(returnType)} } requires execute sql privileges `;
45
45
  }
@@ -48,3 +48,8 @@ export const getReturnTypeQuery = async ({
48
48
  }
49
49
  return queryWithRLS as unknown as unknown[];
50
50
  };
51
+
52
+ export const isReturningQuery = (
53
+ returnType: SelectParams["returnType"],
54
+ localParams: LocalParams | undefined,
55
+ ) => Boolean(localParams?.returnQuery || sqlTypes.some((type) => type === returnType));
package/lib/Prostgles.ts CHANGED
@@ -6,6 +6,10 @@ import type { ContextCleanup, OnInitReason } from "./initProstgles";
6
6
  import { initProstgles } from "./initProstgles";
7
7
  import type { SchemaWatch } from "./SchemaWatch/SchemaWatch";
8
8
  import { getClientSchema } from "./WebsocketAPI/getClientSchema";
9
+ import {
10
+ getClientDBHandlers,
11
+ type GetClientDBHandlers,
12
+ } from "./WebsocketAPI/getClientHandlers";
9
13
  import { onSocketConnected } from "./WebsocketAPI/onSocketConnected";
10
14
  import pg = require("pg-promise/typescript/pg-subset");
11
15
 
@@ -107,6 +111,9 @@ export class Prostgles {
107
111
  }
108
112
  publishParser?: PublishParser;
109
113
 
114
+ getClientDBHandlers: GetClientDBHandlers = (clientReq, scope) =>
115
+ getClientDBHandlers(this, clientReq, scope);
116
+
110
117
  authHandler = new AuthHandler(this);
111
118
 
112
119
  schemaWatch?: SchemaWatch;
@@ -278,16 +278,11 @@ export class PubSubManager {
278
278
  );
279
279
  const matchingSub = this.subs[matchingSubIdx];
280
280
  if (matchingSub) {
281
- /** Ensure we check and refresh related table/view triggers as well */
282
- const oldActiveTriggers = this.getAllActiveTriggers();
283
281
  this.subs.splice(matchingSubIdx, 1);
284
- const newActiveTriggers = this.getAllActiveTriggers();
285
- const tableNames = new Set(
286
- [...oldActiveTriggers, ...newActiveTriggers].map((t) => t.tableName),
282
+ // These are tables to recheck, not a snapshot of which triggers can be deleted.
283
+ this.deleteOrphanedTriggers(
284
+ new Set(matchingSub.triggers.map((trigger) => trigger.table_name)),
287
285
  );
288
- if (newActiveTriggers.length < oldActiveTriggers.length) {
289
- this.deleteOrphanedTriggers(tableNames);
290
- }
291
286
  } else {
292
287
  console.error("Could not unsubscribe. Subscription might not have initialised yet", {
293
288
  channelName,
@@ -314,22 +309,6 @@ export class PubSubManager {
314
309
  }));
315
310
  return tableTriggerConditions;
316
311
  };
317
- getActiveTriggers = (tableName: string) => {
318
- const activeTriggers = (this.getTriggerInfo(tableName) ?? []).filter(
319
- (c) => c.subs.length || c.syncs.length,
320
- );
321
- return activeTriggers;
322
- };
323
-
324
- getAllActiveTriggers = () => {
325
- return Array.from(this._triggers.keys()).flatMap((tableName) => {
326
- return this.getActiveTriggers(tableName).map((triggerInfo) => ({
327
- ...triggerInfo,
328
- tableName,
329
- }));
330
- });
331
- };
332
-
333
312
  getSubData = async (sub: Subscription) => {
334
313
  const {
335
314
  table_info,
@@ -418,9 +397,11 @@ export class PubSubManager {
418
397
  syncTimeout?: ReturnType<typeof setTimeout>;
419
398
  syncData = syncData.bind(this);
420
399
 
421
- addSync = addSync.bind(this);
400
+ addSync = (...args: Parameters<typeof addSync>) =>
401
+ this.registerTriggers(() => addSync.apply(this, args));
422
402
 
423
- addSub = addSub.bind(this);
403
+ addSub = (...args: Parameters<typeof addSub>) =>
404
+ this.registerTriggers(() => addSub.apply(this, args));
424
405
 
425
406
  getActiveListeners = (): { table_name: string; condition: string }[] => {
426
407
  const activeListeners: { table_name: string; condition: string }[] = [];
@@ -445,9 +426,17 @@ export class PubSubManager {
445
426
  /**
446
427
  * Sync triggers with database
447
428
  * */
448
- refreshTriggers = refreshTriggers.bind(this);
429
+ private triggerRefresh: Promise<void> = Promise.resolve();
430
+ refreshTriggers = () => {
431
+ // Apply database snapshots in order, including after a previous refresh failed.
432
+ const refresh = () => refreshTriggers.call(this);
433
+ this.triggerRefresh = this.triggerRefresh.then(refresh, refresh);
434
+ return this.triggerRefresh;
435
+ };
449
436
 
450
437
  /** Throttle trigger deletes */
438
+ private triggerCleanup: Promise<void> = Promise.resolve();
439
+ private pendingTriggerRegistrations = new Set<Promise<unknown>>();
451
440
  deletingOrphanedTriggers:
452
441
  | {
453
442
  tableNames: Set<string>;
@@ -460,7 +449,11 @@ export class PubSubManager {
460
449
  timeout: setTimeout(() => {
461
450
  const tableNames = this.deletingOrphanedTriggers!.tableNames;
462
451
  this.deletingOrphanedTriggers = undefined;
463
- void deleteOrphanedTriggers.bind(this)(Array.from(tableNames));
452
+ // Finish existing registrations before cleanup; new ones wait for this cleanup.
453
+ this.triggerCleanup = Promise.allSettled([
454
+ this.triggerCleanup,
455
+ ...this.pendingTriggerRegistrations,
456
+ ]).then(() => deleteOrphanedTriggers.call(this, Array.from(tableNames)));
464
457
  }, 1000),
465
458
  };
466
459
 
@@ -469,6 +462,16 @@ export class PubSubManager {
469
462
  });
470
463
  };
471
464
 
465
+ private registerTriggers = <T>(register: () => Promise<T>): Promise<T> => {
466
+ const result = this.triggerCleanup.then(register);
467
+ this.pendingTriggerRegistrations.add(result);
468
+ const settled = () => {
469
+ this.pendingTriggerRegistrations.delete(result);
470
+ };
471
+ void result.then(settled, settled);
472
+ return result;
473
+ };
474
+
472
475
  addingTrigger: any;
473
476
  addTriggerPool?: Record<string, string[]> = undefined;
474
477
  addTrigger = addTrigger.bind(this);
@@ -2,10 +2,12 @@ import type { PubSubManager } from "./PubSubManager";
2
2
  import { asValue, EXCLUDE_QUERY_FROM_SCHEMA_WATCH_ID } from "./PubSubManagerUtils";
3
3
 
4
4
  export function deleteOrphanedTriggers(this: PubSubManager, tableNames: string[]) {
5
+ const activeListeners = this.getActiveListeners();
5
6
  const conditions = tableNames.map((tableName) => {
6
- const activeTriggers = this.getActiveTriggers(tableName);
7
- const activeConditionHashes = activeTriggers.map((c) => c.hash);
8
- return `(at.table_name = ${asValue(tableName)} ${activeConditionHashes.length ? `AND at.condition_hash NOT IN (${asValue(activeConditionHashes, ":csv")})` : ""})`;
7
+ const activeConditions = activeListeners
8
+ .filter((listener) => listener.table_name === tableName)
9
+ .map((listener) => listener.condition);
10
+ return `(at.table_name = ${asValue(tableName)} ${activeConditions.length ? `AND at.condition NOT IN (${asValue(activeConditions, ":csv")})` : ""})`;
9
11
  });
10
12
 
11
13
  // log("deleteOrphanedTriggers", { appId: this.appId, conditions });
@@ -13,8 +13,7 @@ export const getDataWatchFunctionQuery = (debugMode: boolean | undefined) => {
13
13
  CREATE OR REPLACE FUNCTION ${DB_OBJ_NAMES.data_watch_func}() RETURNS TRIGGER
14
14
  AS $$
15
15
 
16
- DECLARE c_ids INTEGER[];
17
- DECLARE err_c_ids INTEGER[];
16
+ DECLARE c_ids BIGINT[];
18
17
  DECLARE condition_checks_union_query TEXT := '';
19
18
  DECLARE query TEXT := '';
20
19
  DECLARE v_trigger RECORD;
@@ -195,6 +195,8 @@ BEGIN
195
195
  COMMENT ON TABLE prostgles.apps IS 'Keep track of prostgles server apps connected to db to combine common triggers. Heartbeat used due to no logout triggers in postgres';
196
196
 
197
197
  CREATE TABLE IF NOT EXISTS prostgles.app_triggers (
198
+ /* Stable notification IDs, capped at JavaScript's maximum safe integer. */
199
+ table_condition_id BIGINT GENERATED BY DEFAULT AS IDENTITY (MAXVALUE 9007199254740991) UNIQUE,
198
200
  app_id TEXT NOT NULL,
199
201
  table_name TEXT NOT NULL,
200
202
  condition TEXT NOT NULL,
@@ -219,9 +221,8 @@ BEGIN
219
221
  CREATE OR REPLACE VIEW prostgles.v_triggers AS
220
222
  SELECT *
221
223
  , (ROW_NUMBER() OVER( ORDER BY table_name, condition ))::text AS id
222
- , ROW_NUMBER() OVER(PARTITION BY app_id, table_name ORDER BY table_name, condition ) - 1 AS table_condition_id
223
224
  FROM prostgles.app_triggers;
224
- COMMENT ON VIEW prostgles.v_triggers IS 'Augment trigger table with natural IDs and per app IDs';
225
+ COMMENT ON VIEW prostgles.v_triggers IS 'Augment trigger table with natural IDs';
225
226
 
226
227
  ${getDataWatchFunctionQuery(debugMode)}
227
228
 
@@ -102,11 +102,11 @@ export async function notifListener(this: PubSubManager, data: { payload: string
102
102
  conditionIds.includes(table_condition_id),
103
103
  );
104
104
  const orphanedTableConditions = conditionIds.filter((condId) => {
105
- const tc = tableTriggerConditions.at(condId);
105
+ const tc = tableTriggerConditions.find((trigger) => trigger.table_condition_id === condId);
106
106
  return !tc || (tc.subs.length === 0 && tc.syncs.length === 0);
107
107
  });
108
108
  if (orphanedTableConditions.length) {
109
- void this.deleteOrphanedTriggers(new Set(table_name));
109
+ void this.deleteOrphanedTriggers(new Set([table_name]));
110
110
  }
111
111
 
112
112
  const triggeredSubs = new Set<Subscription>();
@@ -1,4 +1,4 @@
1
- import type { PubSubManager, TableTriggerInfo } from "./PubSubManager";
1
+ import type { PubSubManager, PubSubManagerTriggers, TableTriggerInfo } from "./PubSubManager";
2
2
 
3
3
  export async function refreshTriggers(this: PubSubManager) {
4
4
  const start = Date.now();
@@ -18,14 +18,15 @@ export async function refreshTriggers(this: PubSubManager) {
18
18
  [this.dboBuilder.prostgles.appId],
19
19
  );
20
20
 
21
- const oldTriggers = new Map(this._triggers);
21
+ const oldTriggers = this._triggers;
22
+ const newTriggers: PubSubManagerTriggers = new Map();
22
23
 
23
24
  triggers.forEach((t) => {
24
- this._triggers.set(
25
+ newTriggers.set(
25
26
  t.table_name,
26
- this._triggers.get(t.table_name) ?? new Map<number, TableTriggerInfo>(),
27
+ newTriggers.get(t.table_name) ?? new Map<number, TableTriggerInfo>(),
27
28
  );
28
- const tableTriggers = this._triggers.get(t.table_name)!;
29
+ const tableTriggers = newTriggers.get(t.table_name)!;
29
30
  const table_condition_id = Number(t.table_condition_id);
30
31
  tableTriggers.set(table_condition_id, {
31
32
  condition: t.condition,
@@ -34,6 +35,7 @@ export async function refreshTriggers(this: PubSubManager) {
34
35
  table_condition_id,
35
36
  });
36
37
  });
38
+ this._triggers = newTriggers;
37
39
 
38
40
  await this._log({
39
41
  type: "syncOrSub",
@@ -26,7 +26,7 @@ import type {
26
26
  } from "prostgles-types";
27
27
  import type { AuthClientRequest, LoginClientInfo, SessionUser } from "../Auth/AuthTypes";
28
28
  import type { TableSchemaColumn } from "../DboBuilder/DboBuilderTypes";
29
- import type { ClientHandlers } from "../WebsocketAPI/getClientHandlers";
29
+ import type { ClientHandlers, GetClientDBHandlers } from "../WebsocketAPI/getClientHandlers";
30
30
  import { isArray } from "../utils/utils";
31
31
 
32
32
  export type InsertRequestData = {
@@ -173,6 +173,21 @@ export type AfterAllTsTrigger<R, DBX, Context = undefined> = {
173
173
  ) => Promise<void>;
174
174
  };
175
175
 
176
+ export type AfterCommitTsTrigger<R, DBO, Context = undefined, ClientSchema = void> = {
177
+ commands: Partial<Record<"insert" | "update" | "delete", 1>>;
178
+ changedFields?: (keyof R)[];
179
+ run: (params: {
180
+ /** Committed rows, or the deleted rows' pre-delete state. */
181
+ rows: R[];
182
+ command: "insert" | "update" | "delete";
183
+ context: Context;
184
+ db: DB;
185
+ dbo: DBO;
186
+ getClientDBHandlers: GetClientDBHandlers<ClientSchema>;
187
+ localParams: undefined | LocalParams;
188
+ }) => MaybePromise<unknown>;
189
+ };
190
+
176
191
  export type ValidateRowArgs<R = AnyObject, DBX = DBHandlerServer> = ValidateRowArgsCommon<
177
192
  R,
178
193
  DBX
@@ -9,6 +9,7 @@ import type { DbTxTableHandlers } from "../DboBuilder/DboBuilderTypes";
9
9
  import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
10
10
  import type {
11
11
  AfterAllTsTrigger,
12
+ AfterCommitTsTrigger,
12
13
  AfterEachTsTrigger,
13
14
  BeforeEachTsTrigger,
14
15
  TransactionCallbacks,
@@ -20,7 +21,8 @@ export type TableHooks<S = void, Context = undefined> = S extends DBSchema
20
21
  Required<S[tableName]["columns"]>,
21
22
  DBOFullyTyped<S>,
22
23
  Context,
23
- InsertDataWithNested<S[tableName]["columns"], S, tableName>
24
+ InsertDataWithNested<S[tableName]["columns"], S, tableName>,
25
+ S
24
26
  >;
25
27
  }>
26
28
  : Record<string, TableHooksDefinition<AnyObject, DbTxTableHandlers, Context>>;
@@ -30,6 +32,7 @@ export type TableHooksDefinition<
30
32
  DBX = DbTxTableHandlers,
31
33
  Context = undefined,
32
34
  InputDataType = RowDataType,
35
+ ClientSchema = void,
33
36
  > = {
34
37
  /**
35
38
  * Runs sequentially before data validation and mutation SQL for each insert row,
@@ -63,9 +66,18 @@ export type TableHooksDefinition<
63
66
  */
64
67
  afterAll?: AfterAllTsTrigger<RowDataType, DBX, Context>[];
65
68
 
69
+ /**
70
+ * Runs once after the outer transaction commits successfully with at least one affected row.
71
+ * Receives committed rows and non-transactional handlers; it cannot roll back the mutation.
72
+ * It is awaited before the mutation promise resolves. Errors are logged and do not change the
73
+ * mutation result.
74
+ */
75
+ afterCommit?: AfterCommitTsTrigger<RowDataType, DBX, Context, ClientSchema>[];
76
+
66
77
  /**
67
78
  * Replaces the generated DELETE. Must perform the mutation and shape its return value using
68
- * the prepared filter and returning arguments. Delete `afterEach`/`afterAll` hooks do not run.
79
+ * the prepared filter and returning arguments. Delete `afterEach`/`afterAll`/`afterCommit`
80
+ * hooks do not run.
69
81
  * Use `onCommit`/`onRollback` for external side effects after the outer transaction finishes.
70
82
  */
71
83
  onInsteadOfDelete?: (
@@ -8,6 +8,7 @@ import {
8
8
  type TableHandler,
9
9
  } from "prostgles-types";
10
10
  import type { AuthClientRequest } from "../Auth/AuthTypes";
11
+ import { createServerSideRequest } from "../Auth/utils/serverSideRequest";
11
12
  import type { DBOFullyTypedClient } from "../DBSchemaBuilder/DBSchemaBuilder";
12
13
  import type { DbTxTableHandlers } from "../DboBuilder/DboBuilderTypes";
13
14
  import type { Prostgles } from "../Prostgles";
@@ -27,6 +28,42 @@ export type ClientHandlers<S = void> = {
27
28
  clientMethods: Record<string, ServerFunctionDefinition>;
28
29
  clientSchema: ClientSchema;
29
30
  };
31
+
32
+ export type ClientDBHandlerRequest =
33
+ | AuthClientRequest
34
+ | {
35
+ /** Trusted server-only identity, resolved through auth.findUser on every operation. */
36
+ userId: string;
37
+ socket?: never;
38
+ httpReq?: never;
39
+ res?: never;
40
+ };
41
+
42
+ export type GetClientDBHandlers<ClientSchema = void> = <
43
+ NarrowedClientSchema = ClientSchema,
44
+ >(
45
+ clientReq: ClientDBHandlerRequest,
46
+ scope: PermissionScope | undefined,
47
+ ) => Promise<ClientHandlers<NarrowedClientSchema>>;
48
+
49
+ export const getClientDBHandlers = async <ClientSchema = void>(
50
+ prostgles: Prostgles,
51
+ clientReq: ClientDBHandlerRequest,
52
+ scope: PermissionScope | undefined,
53
+ ) => {
54
+ if ("userId" in clientReq) {
55
+ if ("socket" in clientReq || "httpReq" in clientReq || "res" in clientReq) {
56
+ throw new Error("userId cannot be combined with a client request");
57
+ }
58
+ return getClientHandlers<ClientSchema>(
59
+ prostgles,
60
+ createServerSideRequest(prostgles, clientReq.userId),
61
+ scope,
62
+ );
63
+ }
64
+ return getClientHandlers<ClientSchema>(prostgles, clientReq, scope);
65
+ };
66
+
30
67
  export const getClientHandlers = async <S = void>(
31
68
  prostgles: Prostgles,
32
69
  clientReq: AuthClientRequest,
package/lib/index.ts CHANGED
@@ -37,10 +37,15 @@ export type {
37
37
  PublishedResult,
38
38
  BeforeEachTsTrigger,
39
39
  AfterAllTsTrigger,
40
+ AfterCommitTsTrigger,
40
41
  AfterEachTsTrigger,
41
42
  PublishProfile,
42
43
  PublishParams,
43
44
  } from "./PublishParser/publishTypesAndUtils";
45
+ export type {
46
+ ClientDBHandlerRequest,
47
+ GetClientDBHandlers,
48
+ } from "./WebsocketAPI/getClientHandlers";
44
49
  export type { DBOFullyTyped, DBOFullyTypedClient } from "./DBSchemaBuilder/DBSchemaBuilder";
45
50
  export type { DBHandlerServer } from "./Prostgles";
46
51
  export type { StorageClient as CloudClient } from "./StorageClient/StorageClientTypes";
@@ -3,7 +3,7 @@ import { deferDbQueries } from "./deferDbQueries";
3
3
  import type pgPromise from "pg-promise";
4
4
  import type pg from "pg-promise/typescript/pg-subset";
5
5
  import type { MaybePromise, SQLHandler, TableSchema } from "prostgles-types";
6
- import type { AuthClientRequest, SessionUser } from "./Auth/AuthTypes";
6
+ import type { SessionUser } from "./Auth/AuthTypes";
7
7
  import { removeExpressRoutesTest } from "./Auth/utils/removeExpressRoute";
8
8
  import { DBEventsManager } from "./DBEventsManager";
9
9
  import type { DboBuilder } from "./DboBuilder/DboBuilder";
@@ -17,19 +17,11 @@ import { SchemaWatch } from "./SchemaWatch/SchemaWatch";
17
17
  import { runSQLFile } from "./TableConfig/runSQLFile";
18
18
  import { updateConfiguration, type clientOnlyUpdateKeys } from "./updateConfiguration";
19
19
  import { sleep } from "./utils/utils";
20
- import { getClientHandlers } from "./WebsocketAPI/getClientHandlers";
21
20
  import { getAdminClient } from "./DboBuilder/runSql/getAdminClient";
22
- import { createServerSideRequest } from "./Auth/utils/serverSideRequest";
23
-
24
- type ClientDBHandlerRequest =
25
- | AuthClientRequest
26
- | {
27
- /** Trusted server-only identity, resolved through auth.findUser on every operation. */
28
- userId: string;
29
- socket?: never;
30
- httpReq?: never;
31
- res?: never;
32
- };
21
+ import type {
22
+ ClientDBHandlerRequest,
23
+ GetClientDBHandlers,
24
+ } from "./WebsocketAPI/getClientHandlers";
33
25
 
34
26
  /**
35
27
  * Database connection details
@@ -140,10 +132,7 @@ export type InitResult<
140
132
  * Uses the configured client schema by default and accepts a publish-profile schema override.
141
133
  * Only pass userId from trusted server code; never forward client-supplied input here.
142
134
  */
143
- getClientDBHandlers: <NarrowedClientSchema = ClientSchema>(
144
- clientReq: ClientDBHandlerRequest,
145
- scope: PermissionScope | undefined,
146
- ) => ReturnType<typeof getClientHandlers<NarrowedClientSchema>>;
135
+ getClientDBHandlers: GetClientDBHandlers<ClientSchema>;
147
136
 
148
137
  getFieldsWithTypes: typeof DboBuilder.prototype.getDetailedFieldInfo;
149
138
  };
@@ -350,19 +339,7 @@ export const initProstgles = async function (
350
339
  getClientDBHandlers: async <ClientSchema = void>(
351
340
  clientReq: ClientDBHandlerRequest,
352
341
  scope: PermissionScope | undefined,
353
- ) => {
354
- if ("userId" in clientReq) {
355
- if ("socket" in clientReq || "httpReq" in clientReq || "res" in clientReq) {
356
- throw new Error("userId cannot be combined with a client request");
357
- }
358
- return getClientHandlers<ClientSchema>(
359
- this,
360
- createServerSideRequest(this, clientReq.userId),
361
- scope,
362
- );
363
- }
364
- return getClientHandlers<ClientSchema>(this, clientReq, scope);
365
- },
342
+ ) => this.getClientDBHandlers<ClientSchema>(clientReq, scope),
366
343
  };
367
344
 
368
345
  return initResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "4.2.646",
3
+ "version": "4.2.648",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",