@sanoma-ai/workflows 0.11.11 → 0.11.13
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/CLOUD-IDENTITY.md +12 -4
- package/KMS-SECRETS.md +3 -1
- package/README.md +6 -2
- package/dist/bundled.d.ts +2 -2
- package/dist/chats.d.ts +3 -3
- package/dist/chats.js +34 -20
- package/dist/chats.js.map +1 -1
- package/dist/client.d.ts +17 -4
- package/dist/client.js +74 -63
- package/dist/client.js.map +1 -1
- package/dist/cloud-identity.js +14 -12
- package/dist/cloud-identity.js.map +1 -1
- package/dist/collection.d.ts +2 -2
- package/dist/collection.js +53 -42
- package/dist/collection.js.map +1 -1
- package/dist/config.d.ts +11 -6
- package/dist/config.js +15 -13
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +2 -0
- package/dist/connection.js +112 -40
- package/dist/connection.js.map +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/credentials.js +33 -29
- package/dist/credentials.js.map +1 -1
- package/dist/database.js +4 -1
- package/dist/database.js.map +1 -1
- package/dist/db/company.d.ts +1152 -0
- package/dist/db/company.js +118 -0
- package/dist/db/company.js.map +1 -0
- package/dist/db/dbos.d.ts +111 -0
- package/dist/db/dbos.js +15 -0
- package/dist/db/dbos.js.map +1 -0
- package/dist/db/identity.d.ts +367 -0
- package/dist/db/identity.js +48 -0
- package/dist/db/identity.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.js +10 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/kms.d.ts +224 -0
- package/dist/db/kms.js +29 -0
- package/dist/db/kms.js.map +1 -0
- package/dist/db/migrate.d.ts +63 -0
- package/dist/db/migrate.js +41 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/wakeup.d.ts +271 -0
- package/dist/db/wakeup.js +34 -0
- package/dist/db/wakeup.js.map +1 -0
- package/dist/db.d.ts +42 -39
- package/dist/db.js +129 -169
- package/dist/db.js.map +1 -1
- package/dist/deadlines.js +8 -4
- package/dist/deadlines.js.map +1 -1
- package/dist/deployment-key.d.ts +4 -1
- package/dist/deployment-key.js +10 -3
- package/dist/deployment-key.js.map +1 -1
- package/dist/host-derive.d.ts +12 -3
- package/dist/host-derive.js +21 -8
- package/dist/host-derive.js.map +1 -1
- package/dist/identity-provisioning.d.ts +2 -2
- package/dist/identity-provisioning.js +75 -42
- package/dist/identity-provisioning.js.map +1 -1
- package/dist/identity-service.js +18 -15
- package/dist/identity-service.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/kms-secrets.d.ts +9 -0
- package/dist/kms-secrets.js +59 -27
- package/dist/kms-secrets.js.map +1 -1
- package/dist/ledger.d.ts +1 -1
- package/dist/ledger.js +22 -14
- package/dist/ledger.js.map +1 -1
- package/dist/op.d.ts +27 -6
- package/dist/op.js.map +1 -1
- package/dist/run-status.js +7 -3
- package/dist/run-status.js.map +1 -1
- package/dist/schedules.d.ts +1 -1
- package/dist/schedules.js +5 -7
- package/dist/schedules.js.map +1 -1
- package/dist/schema.d.ts +6 -5
- package/dist/schema.js +11 -7
- package/dist/schema.js.map +1 -1
- package/dist/shared.d.ts +6 -23
- package/dist/shared.js +6 -5
- package/dist/shared.js.map +1 -1
- package/dist/storage-provisioning.d.ts +2 -0
- package/dist/storage-provisioning.js +51 -50
- package/dist/storage-provisioning.js.map +1 -1
- package/dist/tokens.d.ts +2 -2
- package/dist/tokens.js +31 -20
- package/dist/tokens.js.map +1 -1
- package/dist/version.d.ts +4 -4
- package/dist/version.js +5 -5
- package/dist/version.js.map +1 -1
- package/dist/wakeup-service.d.ts +0 -4
- package/dist/wakeup-service.js +102 -93
- package/dist/wakeup-service.js.map +1 -1
- package/dist/worker.d.ts +7 -0
- package/dist/worker.js +26 -21
- package/dist/worker.js.map +1 -1
- package/drizzle/company/0000_tables.sql +104 -0
- package/drizzle/company/0001_wakeup_row.sql +2 -0
- package/drizzle/company/meta/0000_snapshot.json +652 -0
- package/drizzle/company/meta/0001_snapshot.json +652 -0
- package/drizzle/company/meta/_journal.json +20 -0
- package/drizzle/wakeup/0000_tables.sql +26 -0
- package/drizzle/wakeup/meta/0000_snapshot.json +200 -0
- package/drizzle/wakeup/meta/_journal.json +13 -0
- package/oxlint.json +2 -1
- package/package.json +11 -2
- package/src/bundled.ts +2 -2
- package/src/chats.ts +41 -42
- package/src/client.ts +81 -64
- package/src/cloud-identity.ts +23 -24
- package/src/collection.ts +58 -50
- package/src/config.ts +29 -19
- package/src/connection.ts +132 -102
- package/src/credentials.ts +37 -33
- package/src/database.ts +4 -2
- package/src/db/company.ts +173 -0
- package/src/db/dbos.ts +17 -0
- package/src/db/identity.ts +61 -0
- package/src/db/index.ts +10 -0
- package/src/db/kms.ts +41 -0
- package/src/db/migrate.ts +70 -0
- package/src/db/wakeup.ts +41 -0
- package/src/db.ts +151 -182
- package/src/deadlines.ts +10 -4
- package/src/deployment-key.ts +11 -3
- package/src/host-derive.ts +26 -9
- package/src/identity-provisioning.ts +85 -57
- package/src/identity-service.ts +19 -19
- package/src/index.ts +3 -0
- package/src/kms-secrets.ts +64 -56
- package/src/ledger.ts +23 -18
- package/src/op.ts +28 -6
- package/src/run-status.ts +7 -6
- package/src/schedules.ts +6 -8
- package/src/schema.ts +11 -8
- package/src/shared.ts +6 -17
- package/src/storage-provisioning.ts +47 -52
- package/src/tokens.ts +43 -33
- package/src/version.ts +5 -5
- package/src/wakeup-service.ts +117 -131
- package/src/worker.ts +38 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-provisioning.js","sourceRoot":"","sources":["../src/storage-provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"storage-provisioning.js","sourceRoot":"","sources":["../src/storage-provisioning.ts"],"names":[],"mappings":"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"}
|
package/dist/tokens.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Db } from "./db.ts";
|
|
2
2
|
import type { Principal } from "./define.ts";
|
|
3
3
|
/** Register only a generated bearer retained by trusted provisioning, never a workflow value. */
|
|
4
4
|
export interface TokenRegistration {
|
|
@@ -40,6 +40,6 @@ export interface Tokens {
|
|
|
40
40
|
/** The subject the token `id` acts for (a workflow's `ctx.startedBy.subject`); undefined for one revoked or missing. */
|
|
41
41
|
subjectOf(id: string): Promise<string | undefined>;
|
|
42
42
|
}
|
|
43
|
-
export declare function tokenStore(db: () => Promise<
|
|
43
|
+
export declare function tokenStore(db: () => Promise<Db>): Tokens;
|
|
44
44
|
/** The api tokens in memory, for a sandbox run's `sanoma.token.*`: the same contract, nothing kept past the process. */
|
|
45
45
|
export declare function memoryTokens(): Tokens;
|
package/dist/tokens.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { and, eq, isNull, sql } from "drizzle-orm";
|
|
3
|
+
import { pgCode } from "./db.js";
|
|
4
|
+
import { apiTokens } from "./db/company.js";
|
|
3
5
|
import { generateSecret, tokenHash as hashOf } from "./secret.js";
|
|
4
6
|
// The api tokens, in the config's database beside the runtime's other tables: a caller of a
|
|
5
7
|
// public site's api (`callFn`) with `Authorization: Bearer sca_…` is the principal `token:<id>`,
|
|
@@ -13,52 +15,61 @@ const registrationOf = (input) => {
|
|
|
13
15
|
throw new Error("Invalid token registration");
|
|
14
16
|
return { ...input, hash: hashOf(input.token), groups: groupsOf(input.groups) };
|
|
15
17
|
};
|
|
18
|
+
const active = (where) => and(where, isNull(apiTokens.revokedAt));
|
|
16
19
|
export function tokenStore(db) {
|
|
17
20
|
return {
|
|
18
21
|
async mint({ id = randomUUID(), subject, groups }) {
|
|
19
22
|
const token = newApiToken();
|
|
20
|
-
await (await db()).
|
|
21
|
-
id,
|
|
22
|
-
hashOf(token),
|
|
23
|
-
subject,
|
|
24
|
-
JSON.stringify(groups),
|
|
25
|
-
]);
|
|
23
|
+
await (await db()).insert(apiTokens).values({ id, hash: hashOf(token), subject, groups: [...groups] });
|
|
26
24
|
return { id, token };
|
|
27
25
|
},
|
|
28
26
|
async register(input) {
|
|
29
27
|
const { id, hash, subject, groups } = registrationOf(input);
|
|
30
28
|
try {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
// A duplicate id changes nothing unless it is this same active registration (the no-op
|
|
30
|
+
// update makes the row come back).
|
|
31
|
+
const registered = await (await db())
|
|
32
|
+
.insert(apiTokens)
|
|
33
|
+
.values({ id, hash, subject, groups })
|
|
34
|
+
.onConflictDoUpdate({
|
|
35
|
+
target: apiTokens.id,
|
|
36
|
+
set: { id },
|
|
37
|
+
setWhere: and(eq(apiTokens.hash, hash), eq(apiTokens.subject, subject), sql `${apiTokens.groups} @> ${sql.param(groups, apiTokens.groups)} AND ${apiTokens.groups} <@ ${sql.param(groups, apiTokens.groups)}`, isNull(apiTokens.revokedAt)),
|
|
38
|
+
})
|
|
39
|
+
.returning({ id: apiTokens.id });
|
|
40
|
+
return registered.length === 1;
|
|
38
41
|
}
|
|
39
42
|
catch (error) {
|
|
40
43
|
// A bearer already registered under another ID cannot acquire a second identity.
|
|
41
|
-
if (error
|
|
44
|
+
if (pgCode(error) === "23505")
|
|
42
45
|
return false;
|
|
43
46
|
throw error;
|
|
44
47
|
}
|
|
45
48
|
},
|
|
46
49
|
async revoke({ id }) {
|
|
47
|
-
await (await db())
|
|
50
|
+
await (await db())
|
|
51
|
+
.update(apiTokens)
|
|
52
|
+
.set({ revokedAt: sql `now()` })
|
|
53
|
+
.where(active(eq(apiTokens.id, id)));
|
|
48
54
|
},
|
|
49
55
|
async resolve(token) {
|
|
50
56
|
if (!token.startsWith(PREFIX))
|
|
51
57
|
return undefined;
|
|
52
58
|
// Looked up by its hash: the token itself is never stored, so there is nothing to compare it to.
|
|
53
|
-
const
|
|
54
|
-
|
|
59
|
+
const [row] = await (await db())
|
|
60
|
+
.select({ id: apiTokens.id, subject: apiTokens.subject, groups: apiTokens.groups })
|
|
61
|
+
.from(apiTokens)
|
|
62
|
+
.where(active(eq(apiTokens.hash, hashOf(token))));
|
|
55
63
|
if (!row)
|
|
56
64
|
return undefined;
|
|
57
65
|
return { principal: { id: `token:${row.id}`, groups: row.groups }, subject: row.subject };
|
|
58
66
|
},
|
|
59
67
|
async subjectOf(id) {
|
|
60
|
-
const
|
|
61
|
-
|
|
68
|
+
const [row] = await (await db())
|
|
69
|
+
.select({ subject: apiTokens.subject })
|
|
70
|
+
.from(apiTokens)
|
|
71
|
+
.where(active(eq(apiTokens.id, id)));
|
|
72
|
+
return row?.subject;
|
|
62
73
|
},
|
|
63
74
|
};
|
|
64
75
|
}
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -32,10 +32,10 @@ export declare function computeVersion({ appName, workflows: definitions, }: {
|
|
|
32
32
|
workflows: readonly WorkflowDefinition<any, any>[];
|
|
33
33
|
}): string;
|
|
34
34
|
/**
|
|
35
|
-
* A hash of
|
|
36
|
-
* `
|
|
37
|
-
* (`
|
|
35
|
+
* A hash of a built-in workflow's own code (`apply`'s, `change`'s, …), which each of its runs
|
|
36
|
+
* carries (its `builtInCode` attribute) so a worker on another version of the app may take it
|
|
37
|
+
* over (`carryBuiltInRuns` in worker.ts): what `computeVersion` hashes of that one workflow, with
|
|
38
38
|
* `RUNTIME_VERSION`, `STEP_LAYOUT` and the installed DBOS version. Never the company's workflows
|
|
39
39
|
* nor `DBOS__APPVERSION`, so a merge that changes only the company's code leaves it as it is.
|
|
40
40
|
*/
|
|
41
|
-
export declare function
|
|
41
|
+
export declare function builtInCodeOf(builtIn: WorkflowDefinition<any, any>): string;
|
package/dist/version.js
CHANGED
|
@@ -58,14 +58,14 @@ export function computeVersion({ appName, workflows: definitions, }) {
|
|
|
58
58
|
return `${appName}@${sha256([appName, RUNTIME_VERSION, STEP_LAYOUT, installedDbosVersion(), ...workflows])}`;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* A hash of
|
|
62
|
-
* `
|
|
63
|
-
* (`
|
|
61
|
+
* A hash of a built-in workflow's own code (`apply`'s, `change`'s, …), which each of its runs
|
|
62
|
+
* carries (its `builtInCode` attribute) so a worker on another version of the app may take it
|
|
63
|
+
* over (`carryBuiltInRuns` in worker.ts): what `computeVersion` hashes of that one workflow, with
|
|
64
64
|
* `RUNTIME_VERSION`, `STEP_LAYOUT` and the installed DBOS version. Never the company's workflows
|
|
65
65
|
* nor `DBOS__APPVERSION`, so a merge that changes only the company's code leaves it as it is.
|
|
66
66
|
*/
|
|
67
|
-
export function
|
|
68
|
-
return sha256([RUNTIME_VERSION, STEP_LAYOUT, installedDbosVersion(), codeOf(
|
|
67
|
+
export function builtInCodeOf(builtIn) {
|
|
68
|
+
return sha256([RUNTIME_VERSION, STEP_LAYOUT, installedDbosVersion(), codeOf(builtIn)]);
|
|
69
69
|
}
|
|
70
70
|
const sha256 = (parts) => createHash("sha256").update(JSON.stringify(parts)).digest("hex");
|
|
71
71
|
/** What the hashes read of a workflow: its name, the source of its `run`, its operations and its input schema. */
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,OAAO,EAA2B,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,eAAe,GAC1B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAC7E,CAAC,OAAO,CAAC;AAEV;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,IAAI,WAA+B,CAAC;AAEpC,qGAAqG;AACrG,SAAS,oBAAoB;IAC3B,WAAW,KAAK,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;QACpG,IAAI,GAAwC,CAAC;QAC7C,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAe,CAAC;QAClF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACvE,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxF,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,EAC7B,OAAO,EACP,SAAS,EAAE,WAAW,GAKvB;IACC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,KAAK;QAAE,OAAO,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,OAAO,GAAG,OAAO,IAAI,MAAM,CAAC,CAAC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,oBAAoB,EAAE,EAAE,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC;AAC/G,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"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"}
|
package/dist/wakeup-service.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/** Where the accounts live: one per party that registers instances, its token's hash alone. */
|
|
2
|
-
export declare const WAKEUP_ACCOUNTS_TABLE = "sanoma_wakeup_accounts";
|
|
3
|
-
/** Where the instances live: each one's URL, its token's hash and its registered wake. */
|
|
4
|
-
export declare const WAKEUP_INSTANCES_TABLE = "sanoma_wakeup_instances";
|
|
5
1
|
/** The shape of `@sanoma-ai/app`'s `IngressRoute`, which `startApp`'s `ingress` takes. */
|
|
6
2
|
export interface WakeupRoute {
|
|
7
3
|
method?: "GET" | "POST" | "PUT" | "DELETE";
|
package/dist/wakeup-service.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { and, eq, inArray, isNotNull, isNull, lt, lte, or, sql } from "drizzle-orm";
|
|
3
|
+
import { databaseOn, openPool, underPreparationLock } from "./db.js";
|
|
4
|
+
import { applyMigrations, WAKEUP_MIGRATIONS } from "./db/migrate.js";
|
|
5
|
+
import { wakeupAccounts, wakeupInstances } from "./db/wakeup.js";
|
|
3
6
|
import { info, warn } from "./log.js";
|
|
4
7
|
import { generateSecret, tokenHash as hashOf } from "./secret.js";
|
|
5
8
|
import { errorMessage } from "./shared.js";
|
|
@@ -10,36 +13,8 @@ import { errorMessage } from "./shared.js";
|
|
|
10
13
|
* before it stops, `PUT`s with that token when it wants waking, replacing what it asked before;
|
|
11
14
|
* the service then calls `GET {url}/wake`, retrying until an answer is a 2xx. It makes its two
|
|
12
15
|
* tables itself, in the database it is given (sanoma-ops's own, when it hosts it): never among
|
|
13
|
-
* `db.ts`'s, which every company's database gets.
|
|
16
|
+
* `db/company.ts`'s, which every company's database gets.
|
|
14
17
|
*/
|
|
15
|
-
/** Where the accounts live: one per party that registers instances, its token's hash alone. */
|
|
16
|
-
export const WAKEUP_ACCOUNTS_TABLE = "sanoma_wakeup_accounts";
|
|
17
|
-
/** Where the instances live: each one's URL, its token's hash and its registered wake. */
|
|
18
|
-
export const WAKEUP_INSTANCES_TABLE = "sanoma_wakeup_instances";
|
|
19
|
-
const TABLES = [
|
|
20
|
-
[
|
|
21
|
-
"wakeup accounts",
|
|
22
|
-
`CREATE TABLE IF NOT EXISTS ${WAKEUP_ACCOUNTS_TABLE} (id uuid PRIMARY KEY, token_hash text UNIQUE NOT NULL, ` +
|
|
23
|
-
"label text NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), revoked_at timestamptz)",
|
|
24
|
-
],
|
|
25
|
-
[
|
|
26
|
-
"wakeup instances",
|
|
27
|
-
`CREATE TABLE IF NOT EXISTS ${WAKEUP_INSTANCES_TABLE} (id uuid PRIMARY KEY, ` +
|
|
28
|
-
`account_id uuid NOT NULL REFERENCES ${WAKEUP_ACCOUNTS_TABLE} (id), url text NOT NULL, ` +
|
|
29
|
-
"token_hash text UNIQUE NOT NULL, at timestamptz, " +
|
|
30
|
-
"called_at timestamptz, attempts integer NOT NULL DEFAULT 0, next_attempt_at timestamptz, " +
|
|
31
|
-
"last_error text, created_at timestamptz NOT NULL DEFAULT now())",
|
|
32
|
-
],
|
|
33
|
-
// Each on its own, so one another process made first does not skip the next.
|
|
34
|
-
[
|
|
35
|
-
"wakeup instances",
|
|
36
|
-
`CREATE INDEX IF NOT EXISTS ${WAKEUP_INSTANCES_TABLE}_at ON ${WAKEUP_INSTANCES_TABLE} (at) WHERE at IS NOT NULL`,
|
|
37
|
-
],
|
|
38
|
-
[
|
|
39
|
-
"wakeup instances",
|
|
40
|
-
`CREATE INDEX IF NOT EXISTS ${WAKEUP_INSTANCES_TABLE}_account ON ${WAKEUP_INSTANCES_TABLE} (account_id)`,
|
|
41
|
-
],
|
|
42
|
-
];
|
|
43
18
|
/** How long a call to an instance's `/wake` may take. */
|
|
44
19
|
const CALL_TIMEOUT_MS = 10_000;
|
|
45
20
|
/** The longest the loop sleeps without looking again, whatever is due. */
|
|
@@ -134,39 +109,33 @@ const shownInstance = (row) => ({
|
|
|
134
109
|
id: row.id,
|
|
135
110
|
url: row.url,
|
|
136
111
|
at: row.at?.toISOString() ?? null,
|
|
137
|
-
calledAt: row.
|
|
112
|
+
calledAt: row.calledAt?.toISOString() ?? null,
|
|
138
113
|
attempts: row.attempts,
|
|
139
|
-
lastError: row.
|
|
114
|
+
lastError: row.lastError,
|
|
140
115
|
});
|
|
141
116
|
/** A row waiting for its call: registered, not called since its `at`. */
|
|
142
|
-
const
|
|
143
|
-
/**
|
|
144
|
-
const
|
|
117
|
+
const waiting = and(isNotNull(wakeupInstances.at), or(isNull(wakeupInstances.calledAt), lt(wakeupInstances.calledAt, wakeupInstances.at)));
|
|
118
|
+
/** The join to an account not revoked. */
|
|
119
|
+
const live = and(eq(wakeupAccounts.id, wakeupInstances.accountId), isNull(wakeupAccounts.revokedAt));
|
|
145
120
|
/**
|
|
146
|
-
* Runs `use` on a connection to `databaseUrl`
|
|
147
|
-
*
|
|
121
|
+
* Runs `use` on a connection to `databaseUrl` holding the preparation's lock, the database and the
|
|
122
|
+
* service's two tables made when missing: the service's own migrations folder, with its own journal
|
|
123
|
+
* table, since the database may be a company's too.
|
|
148
124
|
*/
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
finally {
|
|
157
|
-
await conn.end().catch(() => undefined);
|
|
158
|
-
}
|
|
125
|
+
function withTables(databaseUrl, use) {
|
|
126
|
+
return underPreparationLock(databaseUrl, async (db) => {
|
|
127
|
+
await applyMigrations(db, WAKEUP_MIGRATIONS).catch((err) => {
|
|
128
|
+
throw new Error(`could not prepare the wakeup service tables: ${errorMessage(err)}`, { cause: err });
|
|
129
|
+
});
|
|
130
|
+
return use(db);
|
|
131
|
+
});
|
|
159
132
|
}
|
|
160
133
|
async function insertAccount(db, label) {
|
|
161
134
|
if (!label.trim())
|
|
162
135
|
throw new Error("An account's label must not be empty");
|
|
163
136
|
const id = randomUUID();
|
|
164
137
|
const token = newToken("swa_");
|
|
165
|
-
await db.
|
|
166
|
-
id,
|
|
167
|
-
hashOf(token),
|
|
168
|
-
label,
|
|
169
|
-
]);
|
|
138
|
+
await db.insert(wakeupAccounts).values({ id, tokenHash: hashOf(token), label });
|
|
170
139
|
return { id, token };
|
|
171
140
|
}
|
|
172
141
|
/**
|
|
@@ -196,24 +165,27 @@ export async function mintWakeupAccount(databaseUrl, label) {
|
|
|
196
165
|
export async function startWakeupService({ databaseUrl, now = () => new Date(), fetch = globalThis.fetch, log = { info, warn }, }) {
|
|
197
166
|
await withTables(databaseUrl, async () => { });
|
|
198
167
|
const pool = openPool(databaseUrl, "wakeup service");
|
|
199
|
-
const
|
|
168
|
+
const db = databaseOn(pool);
|
|
169
|
+
const loop = startLoop({ db, now, fetch, log });
|
|
200
170
|
/** The live account the request's token is, or a 401. */
|
|
201
171
|
async function account(request) {
|
|
202
172
|
const token = bearer(request);
|
|
203
173
|
if (!token?.startsWith("swa_"))
|
|
204
174
|
return problem(401, "an account's token is needed");
|
|
205
|
-
const
|
|
206
|
-
|
|
175
|
+
const [row] = await db
|
|
176
|
+
.select({ id: wakeupAccounts.id })
|
|
177
|
+
.from(wakeupAccounts)
|
|
178
|
+
.where(and(eq(wakeupAccounts.tokenHash, hashOf(token)), isNull(wakeupAccounts.revokedAt)));
|
|
179
|
+
return row?.id ?? problem(401, "the token is no account's");
|
|
207
180
|
}
|
|
208
181
|
/** The account's instance `id`, or a 404, or a 403 when it is another account's. */
|
|
209
182
|
async function owned(accountId, id) {
|
|
210
183
|
if (!UUID.test(id))
|
|
211
184
|
return problem(404, "no such instance");
|
|
212
|
-
const
|
|
213
|
-
const row = rows[0];
|
|
185
|
+
const [row] = await db.select().from(wakeupInstances).where(eq(wakeupInstances.id, id));
|
|
214
186
|
if (!row)
|
|
215
187
|
return problem(404, "no such instance");
|
|
216
|
-
return row.
|
|
188
|
+
return row.accountId === accountId ? row : problem(403, "the instance is another account's");
|
|
217
189
|
}
|
|
218
190
|
async function register(request) {
|
|
219
191
|
const accountId = await account(request);
|
|
@@ -230,26 +202,39 @@ export async function startWakeupService({ databaseUrl, now = () => new Date(),
|
|
|
230
202
|
return problem(400, "token must be an instance's token: swi_, then 43 or more base64url characters");
|
|
231
203
|
// The token names the instance: a new one is a new row, one of this account's is moved to the
|
|
232
204
|
// URL given, and another account's is refused (no row returned).
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
205
|
+
const id = randomUUID();
|
|
206
|
+
const sameUrl = eq(wakeupInstances.url, checked.url);
|
|
207
|
+
const [row] = await db
|
|
208
|
+
.insert(wakeupInstances)
|
|
209
|
+
.values({ id, accountId, url: checked.url, tokenHash: hashOf(token) })
|
|
210
|
+
.onConflictDoUpdate({
|
|
211
|
+
target: wakeupInstances.tokenHash,
|
|
212
|
+
set: {
|
|
213
|
+
url: checked.url,
|
|
214
|
+
at: sql `CASE WHEN ${sameUrl} THEN ${wakeupInstances.at} END`,
|
|
215
|
+
calledAt: sql `CASE WHEN ${sameUrl} THEN ${wakeupInstances.calledAt} END`,
|
|
216
|
+
attempts: sql `CASE WHEN ${sameUrl} THEN ${wakeupInstances.attempts} ELSE 0 END`,
|
|
217
|
+
nextAttemptAt: sql `CASE WHEN ${sameUrl} THEN ${wakeupInstances.nextAttemptAt} END`,
|
|
218
|
+
lastError: sql `CASE WHEN ${sameUrl} THEN ${wakeupInstances.lastError} END`,
|
|
219
|
+
},
|
|
220
|
+
setWhere: eq(wakeupInstances.accountId, accountId),
|
|
221
|
+
})
|
|
222
|
+
.returning({ id: wakeupInstances.id });
|
|
242
223
|
if (!row) {
|
|
243
224
|
return problem(409, "the token is another account's instance's");
|
|
244
225
|
}
|
|
245
|
-
return json(row.
|
|
226
|
+
return json(row.id === id ? 201 : 200, { id: row.id });
|
|
246
227
|
}
|
|
247
228
|
async function wake(request) {
|
|
248
229
|
const token = bearer(request);
|
|
249
230
|
if (!token?.startsWith("swi_"))
|
|
250
231
|
return problem(401, "an instance's token is needed");
|
|
251
|
-
const
|
|
252
|
-
|
|
232
|
+
const [found] = await db
|
|
233
|
+
.select({ id: wakeupInstances.id })
|
|
234
|
+
.from(wakeupInstances)
|
|
235
|
+
.innerJoin(wakeupAccounts, live)
|
|
236
|
+
.where(eq(wakeupInstances.tokenHash, hashOf(token)));
|
|
237
|
+
const id = found?.id;
|
|
253
238
|
if (!id)
|
|
254
239
|
return problem(401, "the token is no instance's");
|
|
255
240
|
const given = await jsonBody(request);
|
|
@@ -259,8 +244,10 @@ export async function startWakeupService({ databaseUrl, now = () => new Date(),
|
|
|
259
244
|
if (typeof at !== "string" || !ISO_DATE_TIME.test(at) || Number.isNaN(Date.parse(at)))
|
|
260
245
|
return problem(400, "at must be an ISO 8601 date-time");
|
|
261
246
|
// Whatever it had is replaced: a wake that arrives for an older one starts a worker with nothing to do.
|
|
262
|
-
await
|
|
263
|
-
|
|
247
|
+
await db
|
|
248
|
+
.update(wakeupInstances)
|
|
249
|
+
.set({ at: new Date(at), calledAt: null, attempts: 0, nextAttemptAt: null, lastError: null })
|
|
250
|
+
.where(eq(wakeupInstances.id, id));
|
|
264
251
|
loop.poke();
|
|
265
252
|
return noContent();
|
|
266
253
|
}
|
|
@@ -287,19 +274,19 @@ export async function startWakeupService({ databaseUrl, now = () => new Date(),
|
|
|
287
274
|
return row;
|
|
288
275
|
if (method === "GET")
|
|
289
276
|
return json(200, shownInstance(row));
|
|
290
|
-
await
|
|
277
|
+
await db.delete(wakeupInstances).where(eq(wakeupInstances.id, id));
|
|
291
278
|
return noContent();
|
|
292
279
|
}
|
|
293
280
|
return {
|
|
294
281
|
routes: [{ path: "/wakeup", prefix: true, handle }],
|
|
295
|
-
mintAccount: (label) => insertAccount(
|
|
282
|
+
mintAccount: (label) => insertAccount(db, label),
|
|
296
283
|
async revokeAccount(id) {
|
|
297
284
|
if (!UUID.test(id))
|
|
298
285
|
return;
|
|
299
|
-
await
|
|
300
|
-
|
|
301
|
-
now()
|
|
302
|
-
|
|
286
|
+
await db
|
|
287
|
+
.update(wakeupAccounts)
|
|
288
|
+
.set({ revokedAt: now() })
|
|
289
|
+
.where(and(eq(wakeupAccounts.id, id), isNull(wakeupAccounts.revokedAt)));
|
|
303
290
|
},
|
|
304
291
|
async stop() {
|
|
305
292
|
await loop.stop();
|
|
@@ -312,7 +299,7 @@ export async function startWakeupService({ databaseUrl, now = () => new Date(),
|
|
|
312
299
|
* next is (at most `MAX_SLEEP_MS`) or until `poke`. A failed call is tried again after
|
|
313
300
|
* `min(2^attempts s, MAX_BACKOFF_S)`, for as long as it takes: no row is ever dropped.
|
|
314
301
|
*/
|
|
315
|
-
function startLoop({
|
|
302
|
+
function startLoop({ db, now, fetch, log, }) {
|
|
316
303
|
const stopping = new AbortController();
|
|
317
304
|
let poked = false;
|
|
318
305
|
let wakeUp;
|
|
@@ -336,36 +323,58 @@ function startLoop({ pool, now, fetch, log, }) {
|
|
|
336
323
|
return;
|
|
337
324
|
// Recorded only on the registration called: one replaced (another `at`), or moved to another
|
|
338
325
|
// URL, is called again.
|
|
339
|
-
const same =
|
|
326
|
+
const same = and(eq(wakeupInstances.id, row.id), eq(wakeupInstances.at, row.at), eq(wakeupInstances.url, row.url));
|
|
340
327
|
if (error === undefined) {
|
|
341
|
-
await
|
|
342
|
-
|
|
328
|
+
await db
|
|
329
|
+
.update(wakeupInstances)
|
|
330
|
+
.set({ calledAt: now(), attempts: 0, nextAttemptAt: null, lastError: null })
|
|
331
|
+
.where(same);
|
|
343
332
|
log.info(`wakeup: called ${target}`);
|
|
344
333
|
}
|
|
345
334
|
else {
|
|
346
|
-
await
|
|
347
|
-
|
|
348
|
-
|
|
335
|
+
await db
|
|
336
|
+
.update(wakeupInstances)
|
|
337
|
+
.set({
|
|
338
|
+
attempts: sql `${wakeupInstances.attempts} + 1`,
|
|
339
|
+
lastError: error,
|
|
340
|
+
nextAttemptAt: sql `${now().toISOString()}::timestamptz + least(power(2, ${wakeupInstances.attempts}), ${sql.raw(String(MAX_BACKOFF_S))}) * interval '1 second'`,
|
|
341
|
+
})
|
|
342
|
+
.where(same);
|
|
349
343
|
log.warn(`wakeup: calling ${target} failed (${error}); it is tried again`);
|
|
350
344
|
}
|
|
351
345
|
}
|
|
352
346
|
/** Calls every due row; returns when the next one is due, or undefined with none waiting. */
|
|
353
347
|
async function round() {
|
|
354
348
|
// Taken for `CLAIM_S`, rows another service holds skipped: each due row is called by one service.
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
349
|
+
const at = now();
|
|
350
|
+
const due = db
|
|
351
|
+
.select({ id: wakeupInstances.id })
|
|
352
|
+
.from(wakeupInstances)
|
|
353
|
+
.innerJoin(wakeupAccounts, live)
|
|
354
|
+
.where(and(waiting, lte(wakeupInstances.at, at), or(isNull(wakeupInstances.nextAttemptAt), lte(wakeupInstances.nextAttemptAt, at))))
|
|
355
|
+
.orderBy(wakeupInstances.at)
|
|
356
|
+
.limit(ROUND_ROWS)
|
|
357
|
+
.for("update", { of: wakeupInstances, skipLocked: true });
|
|
358
|
+
const rows = await db
|
|
359
|
+
.update(wakeupInstances)
|
|
360
|
+
.set({ nextAttemptAt: new Date(at.getTime() + CLAIM_S * 1000) })
|
|
361
|
+
.where(inArray(wakeupInstances.id, due))
|
|
362
|
+
.returning({ id: wakeupInstances.id, url: wakeupInstances.url, at: wakeupInstances.at });
|
|
363
|
+
const queue = rows.flatMap((r) => (r.at ? [{ ...r, at: r.at }] : []));
|
|
360
364
|
const worker = async () => {
|
|
361
365
|
for (let row = queue.shift(); row && !stopping.signal.aborted; row = queue.shift()) {
|
|
362
366
|
await call(row).catch((err) => log.warn(`wakeup: could not record a call: ${errorMessage(err)}`));
|
|
363
367
|
}
|
|
364
368
|
};
|
|
365
369
|
await Promise.all(Array.from({ length: Math.min(CONCURRENCY, queue.length) }, worker));
|
|
366
|
-
const next = await
|
|
367
|
-
|
|
368
|
-
|
|
370
|
+
const [next] = await db
|
|
371
|
+
.select({
|
|
372
|
+
next: sql `min(greatest(${wakeupInstances.at}, coalesce(${wakeupInstances.nextAttemptAt}, ${wakeupInstances.at})))`.mapWith(wakeupInstances.at),
|
|
373
|
+
})
|
|
374
|
+
.from(wakeupInstances)
|
|
375
|
+
.innerJoin(wakeupAccounts, live)
|
|
376
|
+
.where(waiting);
|
|
377
|
+
return next?.next ?? undefined;
|
|
369
378
|
}
|
|
370
379
|
const sleep = (ms) => new Promise((resolve) => {
|
|
371
380
|
const timer = setTimeout(resolve, ms);
|