prostgles-server 4.2.647 → 4.2.649
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/.github/workflows/main.yml +1 -1
- package/debug/als-build.log +4 -0
- package/debug/als-e2e.log +1747 -0
- package/debug/als-lint.log +4 -0
- package/debug/als-npm-test.log +712 -0
- package/debug/als-row-parts-e2e.log +1759 -0
- package/debug/als-row-parts-npm-test.log +716 -0
- package/debug/als-typecheck.log +8 -0
- package/debug/als-unified-build.log +4 -0
- package/debug/als-unified-lint.log +4 -0
- package/debug/als-unified-test-build.log +11 -0
- package/debug/als-unified-test-server.log +3444 -0
- package/debug/inspect-ui-sync.cjs +24 -0
- package/debug/subscription-cleanup-repro.log +662 -0
- package/debug/subscription-cleanup-trace.log +7230 -0
- package/debug/sync-bigint-DBGeneratedSchema.backup +489 -0
- package/debug/sync-bigint-build.log +4 -0
- package/debug/sync-bigint-client-build.log +0 -0
- package/debug/sync-bigint-lint.log +4 -0
- package/debug/sync-bigint-server-build.log +0 -0
- package/debug/sync-comment-DBGeneratedSchema.backup +489 -0
- package/debug/sync-delay-gate-DBGeneratedSchema.backup +489 -0
- package/debug/sync-delay-gate-build.log +0 -0
- package/debug/sync-diff-review-test.log +132 -0
- package/debug/sync-followup-build.log +4 -0
- package/debug/sync-notification-before.log +121 -0
- package/debug/sync-trigger-cleanup-before.log +134 -0
- package/debug/sync-trigger-fix-e2e.log +1758 -0
- package/debug/sync-trigger-fix-npm-test.log +1815 -0
- package/debug/sync-trigger-lint.log +4 -0
- package/debug/trace-subscription-cleanup.cjs +19 -0
- package/debug/ui-sync-database-snapshot.log +8 -0
- package/debug/ui-sync-investigation.md +30 -0
- package/debug/ui-sync-server-tests.log +553 -0
- package/dist/Audit/AuditTable.d.ts +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +4 -2
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilder.spec.js +3 -1
- package/dist/DboBuilder/DboBuilder.spec.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +3 -2
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js +4 -3
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js +7 -6
- package/dist/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts +2 -2
- package/dist/ExecutionContext.d.ts +32 -0
- package/dist/ExecutionContext.d.ts.map +1 -0
- package/dist/ExecutionContext.js +25 -0
- package/dist/ExecutionContext.js.map +1 -0
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.d.ts +1 -1
- package/dist/Prostgles.d.ts +5 -0
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +5 -0
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +9 -26
- package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.js +27 -23
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/deleteOrphanedTriggers.d.ts.map +1 -1
- package/dist/PubSubManager/deleteOrphanedTriggers.js +5 -3
- package/dist/PubSubManager/deleteOrphanedTriggers.js.map +1 -1
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.d.ts.map +1 -1
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.js +1 -2
- package/dist/PubSubManager/init/getDataWatchFunctionQuery.js.map +1 -1
- package/dist/PubSubManager/init/getPubSubManagerInitQuery.d.ts.map +1 -1
- package/dist/PubSubManager/init/getPubSubManagerInitQuery.js +3 -2
- package/dist/PubSubManager/init/getPubSubManagerInitQuery.js.map +1 -1
- package/dist/PubSubManager/notifListener.js +2 -2
- package/dist/PubSubManager/notifListener.js.map +1 -1
- package/dist/PubSubManager/refreshTriggers.d.ts.map +1 -1
- package/dist/PubSubManager/refreshTriggers.js +5 -3
- package/dist/PubSubManager/refreshTriggers.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +14 -1
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getFunctionRelatedRecords.d.ts +5 -0
- package/dist/PublishParser/getFunctionRelatedRecords.d.ts.map +1 -0
- package/dist/PublishParser/getFunctionRelatedRecords.js +26 -0
- package/dist/PublishParser/getFunctionRelatedRecords.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/initProstgles.d.ts +3 -0
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +1 -0
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +6 -1
- package/dist/runClientRequest.js.map +1 -1
- package/lib/DboBuilder/DboBuilder.spec.ts +3 -7
- package/lib/DboBuilder/DboBuilder.ts +4 -2
- package/lib/DboBuilder/TableHandler/TableHandler.ts +14 -11
- package/lib/DboBuilder/TableHandler/delete.ts +14 -11
- package/lib/DboBuilder/TableHandler/executeAfterHooksCheckAndPostValidation.ts +28 -21
- package/lib/ExecutionContext.ts +60 -0
- package/lib/Prostgles.ts +8 -4
- package/lib/PubSubManager/PubSubManager.ts +31 -28
- package/lib/PubSubManager/deleteOrphanedTriggers.ts +5 -3
- package/lib/PubSubManager/init/getDataWatchFunctionQuery.ts +1 -2
- package/lib/PubSubManager/init/getPubSubManagerInitQuery.ts +3 -2
- package/lib/PubSubManager/notifListener.ts +2 -2
- package/lib/PubSubManager/refreshTriggers.ts +7 -5
- package/lib/PublishParser/PublishParser.ts +17 -1
- package/lib/PublishParser/getFunctionRelatedRecords.ts +25 -0
- package/lib/index.ts +2 -4
- package/lib/initProstgles.ts +5 -4
- package/lib/runClientRequest.ts +16 -8
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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.
|
|
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 =
|
|
21
|
+
const oldTriggers = this._triggers;
|
|
22
|
+
const newTriggers: PubSubManagerTriggers = new Map();
|
|
22
23
|
|
|
23
24
|
triggers.forEach((t) => {
|
|
24
|
-
|
|
25
|
+
newTriggers.set(
|
|
25
26
|
t.table_name,
|
|
26
|
-
|
|
27
|
+
newTriggers.get(t.table_name) ?? new Map<number, TableTriggerInfo>(),
|
|
27
28
|
);
|
|
28
|
-
const tableTriggers =
|
|
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",
|
|
@@ -36,6 +36,9 @@ import {
|
|
|
36
36
|
type PublishObject,
|
|
37
37
|
} from "./publishTypesAndUtils";
|
|
38
38
|
import { validatePublishProfiles } from "./validatePublishProfiles";
|
|
39
|
+
import { randomUUID } from "node:crypto";
|
|
40
|
+
import { createExecutionContext } from "../ExecutionContext";
|
|
41
|
+
import { getFunctionRelatedRecords } from "./getFunctionRelatedRecords";
|
|
39
42
|
|
|
40
43
|
export class PublishParser {
|
|
41
44
|
parsedPublish: ReturnType<typeof getParsedPublish>;
|
|
@@ -144,7 +147,20 @@ export class PublishParser {
|
|
|
144
147
|
})();
|
|
145
148
|
|
|
146
149
|
this.prostgles.checkNotDestroyed();
|
|
147
|
-
|
|
150
|
+
const parent = createExecutionContext(this.prostgles.getExecution());
|
|
151
|
+
const relatedRecords = getFunctionRelatedRecords(method.input, args);
|
|
152
|
+
return this.prostgles.runWithExecution(
|
|
153
|
+
{
|
|
154
|
+
...parent,
|
|
155
|
+
user,
|
|
156
|
+
clientReq,
|
|
157
|
+
invocations: [
|
|
158
|
+
...parent.invocations,
|
|
159
|
+
{ type: "function", id: randomUUID(), functionName: name, relatedRecords },
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
() => method.run(args, ctx),
|
|
163
|
+
);
|
|
148
164
|
};
|
|
149
165
|
allowedFunctionsMap.set(name, { ...method, run: runWithContext });
|
|
150
166
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FunctionInvocation } from "../ExecutionContext";
|
|
2
|
+
import type { ServerFunctionDefinition } from "./defineServerFunction";
|
|
3
|
+
|
|
4
|
+
/** Capture top-level RowLookup/ValueLookup inputs without querying the database. */
|
|
5
|
+
export const getFunctionRelatedRecords = (
|
|
6
|
+
input: ServerFunctionDefinition["input"],
|
|
7
|
+
args: Record<string, unknown> | undefined,
|
|
8
|
+
): FunctionInvocation["relatedRecords"] => {
|
|
9
|
+
const records: FunctionInvocation["relatedRecords"] = [];
|
|
10
|
+
for (const [argName, schema] of Object.entries(input ?? {})) {
|
|
11
|
+
if (typeof schema !== "object" || !("table" in schema)) continue;
|
|
12
|
+
const isRow = schema.type === "RowLookup" || schema.type === "RowLookup[]";
|
|
13
|
+
const isValue = schema.type === "ValueLookup" || schema.type === "ValueLookup[]";
|
|
14
|
+
if (!isRow && !isValue) continue;
|
|
15
|
+
const value = args?.[argName];
|
|
16
|
+
if (value === undefined || value === null) continue;
|
|
17
|
+
const values: unknown[] = schema.type.endsWith("[]") ? (value as unknown[]) : [value];
|
|
18
|
+
for (const item of values) {
|
|
19
|
+
const rowPart =
|
|
20
|
+
"column" in schema ? { [schema.column]: item } : (item as Record<string, unknown>);
|
|
21
|
+
records.push({ argName, tableName: schema.table, rowPart });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return records;
|
|
25
|
+
};
|
package/lib/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ export const createProstgles = <
|
|
|
28
28
|
};
|
|
29
29
|
export * from "./PublishParser/defineServerFunction";
|
|
30
30
|
export * from "./Auth/AuthTypes";
|
|
31
|
+
export type { ExecutionContext, FunctionInvocation, TriggerInvocation } from "./ExecutionContext";
|
|
31
32
|
|
|
32
33
|
export type {
|
|
33
34
|
PublishContextValue,
|
|
@@ -42,10 +43,7 @@ export type {
|
|
|
42
43
|
PublishProfile,
|
|
43
44
|
PublishParams,
|
|
44
45
|
} from "./PublishParser/publishTypesAndUtils";
|
|
45
|
-
export type {
|
|
46
|
-
ClientDBHandlerRequest,
|
|
47
|
-
GetClientDBHandlers,
|
|
48
|
-
} from "./WebsocketAPI/getClientHandlers";
|
|
46
|
+
export type { ClientDBHandlerRequest, GetClientDBHandlers } from "./WebsocketAPI/getClientHandlers";
|
|
49
47
|
export type { DBOFullyTyped, DBOFullyTypedClient } from "./DBSchemaBuilder/DBSchemaBuilder";
|
|
50
48
|
export type { DBHandlerServer } from "./Prostgles";
|
|
51
49
|
export type { StorageClient as CloudClient } from "./StorageClient/StorageClientTypes";
|
package/lib/initProstgles.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { syncTableTriggers } from "./TableConfig/syncTableTriggers";
|
|
2
|
+
import type { ExecutionContext } from "./ExecutionContext";
|
|
2
3
|
import { deferDbQueries } from "./deferDbQueries";
|
|
3
4
|
import type pgPromise from "pg-promise";
|
|
4
5
|
import type pg from "pg-promise/typescript/pg-subset";
|
|
@@ -18,10 +19,7 @@ import { runSQLFile } from "./TableConfig/runSQLFile";
|
|
|
18
19
|
import { updateConfiguration, type clientOnlyUpdateKeys } from "./updateConfiguration";
|
|
19
20
|
import { sleep } from "./utils/utils";
|
|
20
21
|
import { getAdminClient } from "./DboBuilder/runSql/getAdminClient";
|
|
21
|
-
import type {
|
|
22
|
-
ClientDBHandlerRequest,
|
|
23
|
-
GetClientDBHandlers,
|
|
24
|
-
} from "./WebsocketAPI/getClientHandlers";
|
|
22
|
+
import type { ClientDBHandlerRequest, GetClientDBHandlers } from "./WebsocketAPI/getClientHandlers";
|
|
25
23
|
|
|
26
24
|
/**
|
|
27
25
|
* Database connection details
|
|
@@ -93,6 +91,8 @@ export type OnReadyParams<S, Context = undefined> = OnReadyParamsCommon & {
|
|
|
93
91
|
export type ContextCleanup = () => MaybePromise<void>;
|
|
94
92
|
export type CreateContextParams<S> = OnReadyParamsCommon & {
|
|
95
93
|
dbo: DBOFullyTyped<S>;
|
|
94
|
+
/** Read at call time; undefined outside a function, client operation, or table hook. */
|
|
95
|
+
getExecution: () => ExecutionContext | undefined;
|
|
96
96
|
onCleanup: (cleanup: ContextCleanup) => void;
|
|
97
97
|
};
|
|
98
98
|
export type CreateContext<S, Context> = (params: CreateContextParams<S>) => MaybePromise<Context>;
|
|
@@ -324,6 +324,7 @@ export const initProstgles = async function (
|
|
|
324
324
|
}
|
|
325
325
|
this.restApi?.destroy();
|
|
326
326
|
await this.cleanupContext();
|
|
327
|
+
this.executionStorage.disable();
|
|
327
328
|
await this.dboBuilder.destroy();
|
|
328
329
|
this.authHandler.destroy();
|
|
329
330
|
await this.tableConfigurator?.destroy();
|
package/lib/runClientRequest.ts
CHANGED
|
@@ -12,10 +12,10 @@ import type { LocalParams } from "./DboBuilder/DboBuilder";
|
|
|
12
12
|
import type { DbTxTableHandlers } from "./DboBuilder/DboBuilderTypes";
|
|
13
13
|
import type { TableHandler as TableHandlerServer } from "./DboBuilder/TableHandler/TableHandler";
|
|
14
14
|
import { canRunSQL } from "./DboBuilder/runSql/runSQL";
|
|
15
|
+
import { createExecutionContext } from "./ExecutionContext";
|
|
15
16
|
import type { Prostgles } from "./Prostgles";
|
|
16
17
|
import type { ParsedTableRule } from "./PublishParser/publishTypesAndUtils";
|
|
17
18
|
import { type PermissionScope } from "./PublishParser/publishTypesAndUtils";
|
|
18
|
-
import { getAbortSignalKeys } from "./DboBuilder/ViewHandler/getDbHandlerWithAbort";
|
|
19
19
|
|
|
20
20
|
const TABLE_METHODS = {
|
|
21
21
|
find: 1,
|
|
@@ -184,13 +184,21 @@ export const runClientRequest = async function (
|
|
|
184
184
|
undefined | TableMethodFunctionWithRulesAndLocalParams;
|
|
185
185
|
|
|
186
186
|
this.checkNotDestroyed();
|
|
187
|
-
return (
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
return this.runWithExecution(
|
|
188
|
+
{
|
|
189
|
+
...createExecutionContext(this.getExecution()),
|
|
190
|
+
user: clientInfo.user,
|
|
191
|
+
clientReq,
|
|
192
|
+
},
|
|
193
|
+
() =>
|
|
194
|
+
(tableHandler[command] as TableMethodFunctionWithRulesAndLocalParams)(
|
|
195
|
+
param1,
|
|
196
|
+
param2,
|
|
197
|
+
param3,
|
|
198
|
+
parsedTableRule,
|
|
199
|
+
localParams,
|
|
200
|
+
) as AnyObject | undefined,
|
|
201
|
+
);
|
|
194
202
|
};
|
|
195
203
|
|
|
196
204
|
export const clientCanRunSqlRequest = async function (
|