@sanoma-ai/workflows 0.6.0 → 0.7.0
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/README.md +48 -14
- package/dist/apply.d.ts +2 -1
- package/dist/apply.js +29 -7
- package/dist/apply.js.map +1 -1
- package/dist/approvals.d.ts +27 -2
- package/dist/approvals.js +73 -9
- package/dist/approvals.js.map +1 -1
- package/dist/call.d.ts +3 -2
- package/dist/call.js +38 -30
- package/dist/call.js.map +1 -1
- package/dist/cedar.js +24 -9
- package/dist/cedar.js.map +1 -1
- package/dist/change.d.ts +219 -0
- package/dist/change.js +150 -0
- package/dist/change.js.map +1 -0
- package/dist/chats.d.ts +43 -0
- package/dist/chats.js +48 -0
- package/dist/chats.js.map +1 -0
- package/dist/client.d.ts +52 -6
- package/dist/client.js +88 -47
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +47 -5
- package/dist/config.js +71 -7
- package/dist/config.js.map +1 -1
- package/dist/database.d.ts +83 -0
- package/dist/database.js +92 -0
- package/dist/database.js.map +1 -0
- package/dist/db.d.ts +31 -1
- package/dist/db.js +89 -7
- package/dist/db.js.map +1 -1
- package/dist/deadlines.d.ts +88 -0
- package/dist/deadlines.js +171 -0
- package/dist/deadlines.js.map +1 -0
- package/dist/define.d.ts +25 -4
- package/dist/define.js +40 -0
- package/dist/define.js.map +1 -1
- package/dist/demo.d.ts +28 -0
- package/dist/demo.js +72 -0
- package/dist/demo.js.map +1 -0
- package/dist/describe.d.ts +5 -2
- package/dist/describe.js +10 -6
- package/dist/describe.js.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -1
- package/dist/fake.d.ts +8 -0
- package/dist/fake.js +11 -1
- package/dist/fake.js.map +1 -1
- package/dist/grid.d.ts +34 -0
- package/dist/grid.js +62 -0
- package/dist/grid.js.map +1 -0
- package/dist/host.d.ts +13 -2
- package/dist/host.js +2 -2
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +16 -8
- package/dist/index.js +12 -5
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +11 -2
- package/dist/ledger.js.map +1 -1
- package/dist/lint.js +1 -1
- package/dist/lint.js.map +1 -1
- package/dist/op.d.ts +14 -2
- package/dist/op.js.map +1 -1
- package/dist/policy.d.ts +7 -1
- package/dist/policy.js +2 -1
- package/dist/policy.js.map +1 -1
- package/dist/resource.d.ts +13 -1
- package/dist/resource.js +9 -1
- package/dist/resource.js.map +1 -1
- package/dist/resources.d.ts +2 -0
- package/dist/resources.js +10 -1
- package/dist/resources.js.map +1 -1
- package/dist/run.d.ts +5 -0
- package/dist/run.js.map +1 -1
- package/dist/sandbox.d.ts +38 -10
- package/dist/sandbox.js +66 -35
- package/dist/sandbox.js.map +1 -1
- package/dist/scenario.d.ts +18 -1
- package/dist/scenario.js +77 -27
- package/dist/scenario.js.map +1 -1
- package/dist/scenarios.d.ts +10 -1
- package/dist/scenarios.js +19 -4
- package/dist/scenarios.js.map +1 -1
- package/dist/schedules.d.ts +66 -0
- package/dist/schedules.js +158 -0
- package/dist/schedules.js.map +1 -0
- package/dist/schema.d.ts +6 -0
- package/dist/schema.js +13 -3
- package/dist/schema.js.map +1 -1
- package/dist/shared.d.ts +30 -2
- package/dist/shared.js +42 -4
- package/dist/shared.js.map +1 -1
- package/dist/source.d.ts +61 -2
- package/dist/source.js.map +1 -1
- package/dist/supervisor.d.ts +38 -0
- package/dist/supervisor.js +77 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/version.d.ts +3 -1
- package/dist/version.js +3 -1
- package/dist/version.js.map +1 -1
- package/dist/wakeup-service.d.ts +83 -0
- package/dist/wakeup-service.js +421 -0
- package/dist/wakeup-service.js.map +1 -0
- package/dist/wakeup.d.ts +84 -0
- package/dist/wakeup.js +87 -0
- package/dist/wakeup.js.map +1 -0
- package/dist/worker.d.ts +39 -1
- package/dist/worker.js +130 -39
- package/dist/worker.js.map +1 -1
- package/oxlint.json +2 -1
- package/package.json +8 -2
- package/src/apply.ts +25 -6
- package/src/approvals.ts +89 -16
- package/src/call.ts +40 -29
- package/src/cedar.ts +24 -6
- package/src/change.ts +222 -0
- package/src/chats.ts +114 -0
- package/src/client.ts +145 -55
- package/src/config.ts +110 -13
- package/src/database.ts +152 -0
- package/src/db.ts +108 -9
- package/src/deadlines.ts +234 -0
- package/src/define.ts +71 -4
- package/src/demo.ts +87 -0
- package/src/describe.ts +18 -6
- package/src/errors.ts +14 -0
- package/src/fake.ts +12 -0
- package/src/grid.ts +100 -0
- package/src/host.ts +13 -4
- package/src/index.ts +61 -3
- package/src/ledger.ts +15 -3
- package/src/lint.ts +1 -1
- package/src/op.ts +15 -2
- package/src/policy.ts +7 -1
- package/src/resource.ts +22 -3
- package/src/resources.ts +12 -1
- package/src/run.ts +5 -0
- package/src/sandbox.ts +97 -37
- package/src/scenario.ts +97 -28
- package/src/scenarios.ts +21 -5
- package/src/schedules.ts +206 -0
- package/src/schema.ts +16 -3
- package/src/shared.ts +51 -4
- package/src/source.ts +58 -3
- package/src/supervisor.ts +107 -0
- package/src/version.ts +3 -1
- package/src/wakeup-service.ts +511 -0
- package/src/wakeup.ts +150 -0
- package/src/worker.ts +181 -44
package/dist/source.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { PermissionsGrid } from "./grid.ts";
|
|
2
3
|
/** A company's repository, as the runtime writes to it. */
|
|
3
4
|
export interface Source {
|
|
4
5
|
/** The repository's root directory. */
|
|
@@ -16,14 +17,72 @@ export interface Source {
|
|
|
16
17
|
} | undefined | Promise<{
|
|
17
18
|
revision: string;
|
|
18
19
|
} | undefined>;
|
|
19
|
-
/** The revision `ref` names, the checked-out one by default. */
|
|
20
|
+
/** The revision `ref` names, the checked-out one by default (a draft's by its `branch`). */
|
|
20
21
|
head(ref?: string): string | Promise<string>;
|
|
21
|
-
/** Pushes `ref` to the repository at `url`, signed in with `token
|
|
22
|
+
/** Pushes `ref` to the repository at `url`, signed in with `token` (a draft by its `branch`). */
|
|
22
23
|
push?(target: {
|
|
23
24
|
url: string;
|
|
24
25
|
token: string;
|
|
25
26
|
ref: string;
|
|
26
27
|
}): void | Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* The draft `id` (letters, digits, `_` and `-`), opened: made from the checked-out revision the
|
|
30
|
+
* first time, then the same one, edits and all, until its branch is deleted.
|
|
31
|
+
*/
|
|
32
|
+
draft?(id: string): Promise<Draft>;
|
|
33
|
+
/** The open drafts' ids, sorted. */
|
|
34
|
+
drafts?(): Promise<string[]>;
|
|
35
|
+
/** What the draft `id` has committed since its branch left the checked-out one (read from the branch alone). */
|
|
36
|
+
diff?(id: string): Promise<DraftDiff>;
|
|
37
|
+
/** Closes the draft `id`: its checkout removed and its branch deleted, whatever it held; nothing when it is gone. */
|
|
38
|
+
closeDraft?(id: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* `sanoma check` on the draft `id`, as a child in its checkout, one at a time in the process. A
|
|
41
|
+
* check that gives no result (a config that does not load, no install, a timeout) is a result
|
|
42
|
+
* of one problem saying why.
|
|
43
|
+
*/
|
|
44
|
+
check?(id: string): Promise<CheckResult>;
|
|
45
|
+
/** The URL of the repository this one was cloned from (`origin`); undefined when it has none. */
|
|
46
|
+
remoteUrl?(): Promise<string | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Fast-forwards the checked-out branch to `ref` in the repository at `url`, signed in with
|
|
49
|
+
* `token`, as `push` is: only when `ref` is checked out, nothing is uncommitted and the remote's
|
|
50
|
+
* `ref` contains it; otherwise `skipped`, saying why. The checked-out revision after.
|
|
51
|
+
*/
|
|
52
|
+
follow?(target: {
|
|
53
|
+
url: string;
|
|
54
|
+
token: string;
|
|
55
|
+
ref: string;
|
|
56
|
+
}): Promise<{
|
|
57
|
+
revision: string;
|
|
58
|
+
} | {
|
|
59
|
+
skipped: string;
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A draft: a checkout of its own, at `root`, on `branch`, which `commit` records in as
|
|
64
|
+
* `Source.commit` does in its root. Its `node_modules` may be the root's own install, linked in:
|
|
65
|
+
* a writer never writes under it.
|
|
66
|
+
*/
|
|
67
|
+
export interface Draft {
|
|
68
|
+
branch: string;
|
|
69
|
+
root: string;
|
|
70
|
+
commit: Source["commit"];
|
|
71
|
+
}
|
|
72
|
+
/** A draft's change: the files it touches, relative to the root, and git's `--stat` of it. */
|
|
73
|
+
export interface DraftDiff {
|
|
74
|
+
files: string[];
|
|
75
|
+
summary: string;
|
|
76
|
+
}
|
|
77
|
+
/** What `sanoma check` finds in a repo (a draft's too). */
|
|
78
|
+
export interface CheckResult {
|
|
79
|
+
ok: boolean;
|
|
80
|
+
/** One printable line each: `<file>:<line>:<col>: <message>`, or `<scenario> › <step>: <message>`. */
|
|
81
|
+
problems: string[];
|
|
82
|
+
/** What is worth fixing but not wrong, one line each, `<file>:<line>:<col>: warning: <message>`: the sites' `warnings`. */
|
|
83
|
+
warnings: string[];
|
|
84
|
+
/** The repo's Permissions grid (`permissionsGrid`), when its config loaded and its policies hold: what a change is reviewed by. */
|
|
85
|
+
grid?: PermissionsGrid;
|
|
27
86
|
}
|
|
28
87
|
/**
|
|
29
88
|
* The built-in operation `sanoma.source.resolve`: the commit `ref` names in the repository at
|
package/dist/source.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type SanomaConfig } from "./config.ts";
|
|
2
|
+
import type { SelfStop } from "./deadlines.ts";
|
|
3
|
+
import { type WorkerOptions } from "./worker.ts";
|
|
4
|
+
/** A worker under a supervisor (`superviseWorker`). */
|
|
5
|
+
export interface Supervisor {
|
|
6
|
+
/** True from the moment the worker stopped itself until a fresh one starts. */
|
|
7
|
+
readonly stopped: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Starts a fresh worker when the last one stopped itself, for a write that needs one (a run's
|
|
10
|
+
* start, an approval's decision); while one starts or runs, it is heard (below). Resolves once it runs, or
|
|
11
|
+
* once its failure to start is logged: the next call tries again. Never rejects.
|
|
12
|
+
*/
|
|
13
|
+
resume(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* A wakeup's `GET /wake?generation=N`: `resume` when the worker stopped with `generation`
|
|
16
|
+
* registered (`shouldWake`); a no-op for any other, and while one starts or runs.
|
|
17
|
+
*/
|
|
18
|
+
wake(generation: number): Promise<void>;
|
|
19
|
+
/** Stops the worker running or starting, and starts none again. */
|
|
20
|
+
stop(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export interface SupervisorOptions extends Omit<WorkerOptions, "onStopped"> {
|
|
23
|
+
/**
|
|
24
|
+
* False: the worker never stops itself, as on an app on this machine alone, whose wakeup
|
|
25
|
+
* would wake the instance the host runs. Default true.
|
|
26
|
+
*/
|
|
27
|
+
selfStop?: boolean;
|
|
28
|
+
/** Told each time the worker stops itself, once a fresh one is starting for a write it heard, or `stopped` is true. */
|
|
29
|
+
onStopped?: (stopped: SelfStop) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Starts a worker on `config` that stops itself when idle with a wakeup declared (`onStopped`
|
|
33
|
+
* in `WorkerOptions`), and a fresh one each time `resume` or `wake` asks after it did. Throws
|
|
34
|
+
* when the first does not start. A write heard while a worker starts or runs may land after its last check
|
|
35
|
+
* for being idle, so a worker that stops itself after one is started again at once: it stops
|
|
36
|
+
* again on its own when nothing came of it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function superviseWorker(config: SanomaConfig, options?: SupervisorOptions): Promise<Supervisor>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { resolveConfig } from "./config.js";
|
|
2
|
+
import { shouldWake } from "./db.js";
|
|
3
|
+
import { warn } from "./log.js";
|
|
4
|
+
import { errorMessage } from "./shared.js";
|
|
5
|
+
import { startWorker } from "./worker.js";
|
|
6
|
+
/**
|
|
7
|
+
* Starts a worker on `config` that stops itself when idle with a wakeup declared (`onStopped`
|
|
8
|
+
* in `WorkerOptions`), and a fresh one each time `resume` or `wake` asks after it did. Throws
|
|
9
|
+
* when the first does not start. A write heard while a worker starts or runs may land after its last check
|
|
10
|
+
* for being idle, so a worker that stops itself after one is started again at once: it stops
|
|
11
|
+
* again on its own when nothing came of it.
|
|
12
|
+
*/
|
|
13
|
+
export async function superviseWorker(config, options = {}) {
|
|
14
|
+
const { onStopped, selfStop = true, ...workerOptions } = options;
|
|
15
|
+
let worker;
|
|
16
|
+
let starting;
|
|
17
|
+
let closed = false;
|
|
18
|
+
// A write while the worker starts or runs, since it began starting.
|
|
19
|
+
let heard = false;
|
|
20
|
+
let databaseUrl;
|
|
21
|
+
const launch = async () => {
|
|
22
|
+
heard = false;
|
|
23
|
+
const started = await startWorker(config, { ...workerOptions, ...(selfStop && { onStopped: selfStopped }) });
|
|
24
|
+
if (closed)
|
|
25
|
+
await started.stop();
|
|
26
|
+
else
|
|
27
|
+
worker = started;
|
|
28
|
+
};
|
|
29
|
+
const selfStopped = (stopped) => {
|
|
30
|
+
worker = undefined;
|
|
31
|
+
if (closed)
|
|
32
|
+
return;
|
|
33
|
+
// Resumed first, so `stopped` is false when `onStopped` (the exit rule) looks.
|
|
34
|
+
if (heard)
|
|
35
|
+
void supervisor.resume();
|
|
36
|
+
onStopped?.(stopped);
|
|
37
|
+
};
|
|
38
|
+
const supervisor = {
|
|
39
|
+
get stopped() {
|
|
40
|
+
return !closed && !worker && !starting;
|
|
41
|
+
},
|
|
42
|
+
resume() {
|
|
43
|
+
if (closed)
|
|
44
|
+
return Promise.resolve();
|
|
45
|
+
if (worker) {
|
|
46
|
+
heard = true;
|
|
47
|
+
return Promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
if (starting) {
|
|
50
|
+
heard = true;
|
|
51
|
+
return starting;
|
|
52
|
+
}
|
|
53
|
+
return (starting = launch()
|
|
54
|
+
.catch((err) => warn(`the worker could not start again: ${errorMessage(err)}`))
|
|
55
|
+
.finally(() => {
|
|
56
|
+
starting = undefined;
|
|
57
|
+
}));
|
|
58
|
+
},
|
|
59
|
+
async wake(generation) {
|
|
60
|
+
if (!supervisor.stopped)
|
|
61
|
+
return;
|
|
62
|
+
databaseUrl ??= resolveConfig(config).databaseUrl;
|
|
63
|
+
if (await shouldWake(databaseUrl, generation))
|
|
64
|
+
await supervisor.resume();
|
|
65
|
+
},
|
|
66
|
+
async stop() {
|
|
67
|
+
closed = true;
|
|
68
|
+
await starting;
|
|
69
|
+
const running = worker;
|
|
70
|
+
worker = undefined;
|
|
71
|
+
await running?.stop();
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
await launch();
|
|
75
|
+
return supervisor;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=supervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAqB,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAmC,MAAM,aAAa,CAAC;AAoC3E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAoB,EAAE,OAAO,GAAsB,EAAE;IACzF,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACjE,IAAI,MAA0B,CAAC;IAC/B,IAAI,QAAmC,CAAC;IACxC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,oEAAoE;IACpE,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,WAA+B,CAAC;IAEpC,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,KAAK,GAAG,KAAK,CAAC;QACd,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7G,IAAI,MAAM;YAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;;YAC5B,MAAM,GAAG,OAAO,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,OAAiB,EAAE,EAAE;QACxC,MAAM,GAAG,SAAS,CAAC;QACnB,IAAI,MAAM;YAAE,OAAO;QACnB,+EAA+E;QAC/E,IAAI,KAAK;YAAE,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QACpC,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,MAAM,UAAU,GAAe;QAC7B,IAAI,OAAO;YACT,OAAO,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC;QACzC,CAAC;QACD,MAAM;YACJ,IAAI,MAAM;gBAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,MAAM,EAAE,CAAC;gBACX,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3B,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,MAAM,EAAE;iBACxB,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,IAAI,CAAC,qCAAqC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;iBACvF,OAAO,CAAC,GAAG,EAAE;gBACZ,QAAQ,GAAG,SAAS,CAAC;YACvB,CAAC,CAAC,CAAC,CAAC;QACR,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,CAAC,UAAU,CAAC,OAAO;gBAAE,OAAO;YAChC,WAAW,KAAK,aAAa,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC;YAClD,IAAI,MAAM,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC;gBAAE,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC;QAC3E,CAAC;QACD,KAAK,CAAC,IAAI;YACR,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,QAAQ,CAAC;YACf,MAAM,OAAO,GAAG,MAAM,CAAC;YACvB,MAAM,GAAG,SAAS,CAAC;YACnB,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;IACF,MAAM,MAAM,EAAE,CAAC;IACf,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -7,8 +7,10 @@ export declare const RUNTIME_VERSION: string;
|
|
|
7
7
|
* package release, so a run in flight on the old layout is not replayed against the new one.
|
|
8
8
|
* 2: calls run in program order; a decision event per approval (2026-10-07).
|
|
9
9
|
* 3: a start the policy holds waits on its approval before the body (2026-10-21).
|
|
10
|
+
* 4: a sleep for a duration reads DBOS's clock for its start (2026-10-25).
|
|
11
|
+
* 5: a scheduled run admits its starter and asks the policy in two steps before the body (2026-10-25).
|
|
10
12
|
*/
|
|
11
|
-
export declare const STEP_LAYOUT =
|
|
13
|
+
export declare const STEP_LAYOUT = 5;
|
|
12
14
|
/**
|
|
13
15
|
* The application version DBOS stamps on every run, always `<appName>@…`: DBOS version names
|
|
14
16
|
* are unique per system database across apps. A worker recovers and dequeues only runs of its
|
package/dist/version.js
CHANGED
|
@@ -12,8 +12,10 @@ export const RUNTIME_VERSION = JSON.parse(readFileSync(new URL("../package.json"
|
|
|
12
12
|
* package release, so a run in flight on the old layout is not replayed against the new one.
|
|
13
13
|
* 2: calls run in program order; a decision event per approval (2026-10-07).
|
|
14
14
|
* 3: a start the policy holds waits on its approval before the body (2026-10-21).
|
|
15
|
+
* 4: a sleep for a duration reads DBOS's clock for its start (2026-10-25).
|
|
16
|
+
* 5: a scheduled run admits its starter and asks the policy in two steps before the body (2026-10-25).
|
|
15
17
|
*/
|
|
16
|
-
export const STEP_LAYOUT =
|
|
18
|
+
export const STEP_LAYOUT = 5;
|
|
17
19
|
let dbosVersion;
|
|
18
20
|
/** The installed DBOS SDK's version, read from its package.json (which its exports don't expose). */
|
|
19
21
|
function installedDbosVersion() {
|
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
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
/** The shape of `@sanoma-ai/app`'s `IngressRoute`, which `startApp`'s `ingress` takes. */
|
|
6
|
+
export interface WakeupRoute {
|
|
7
|
+
method?: "GET" | "POST" | "PUT" | "DELETE";
|
|
8
|
+
/** `/wakeup`, with every path under it (`prefix`). */
|
|
9
|
+
path: string;
|
|
10
|
+
prefix: true;
|
|
11
|
+
handle(request: Request): Promise<Response>;
|
|
12
|
+
}
|
|
13
|
+
export interface WakeupServiceOptions {
|
|
14
|
+
/** The service's own Postgres: its tables are made there when missing (the database too). */
|
|
15
|
+
databaseUrl: string;
|
|
16
|
+
/** The clock: what is due, and what `called_at` and `next_attempt_at` are set from. */
|
|
17
|
+
now?: () => Date;
|
|
18
|
+
/** How the instances are called. */
|
|
19
|
+
fetch?: typeof globalThis.fetch;
|
|
20
|
+
/** One `info` line per call, a `warn` per failure; the runtime's logger by default. */
|
|
21
|
+
log?: {
|
|
22
|
+
info(line: string): void;
|
|
23
|
+
warn(line: string): void;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface WakeupService {
|
|
27
|
+
/** One route answering everything under `/wakeup`, for `startApp`'s `ingress` or a server of its own. */
|
|
28
|
+
routes: WakeupRoute[];
|
|
29
|
+
/** An account that may register instances: its id, and its token, shown this once. */
|
|
30
|
+
mintAccount(label: string): Promise<{
|
|
31
|
+
id: string;
|
|
32
|
+
token: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Refuses the account's token and its instances' from now on, and wakes its instances no more. */
|
|
35
|
+
revokeAccount(id: string): Promise<void>;
|
|
36
|
+
/** Ends the loop, abandoning the calls in flight (called again once their claim lapses), and closes the pool. */
|
|
37
|
+
stop(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A new instance token (`swi_…`), which the company mints and stores as `SANOMA_WAKEUP_TOKEN`
|
|
41
|
+
* before anything is applied, so its host is given it from the first apply; the wakeup's create
|
|
42
|
+
* then registers it with the service. The service never mints one.
|
|
43
|
+
*/
|
|
44
|
+
export declare const mintInstanceToken: () => string;
|
|
45
|
+
/** The secret a company keeps its instance token in: what its host's `secrets` name and its wakeup's driver reads. */
|
|
46
|
+
export declare const WAKEUP_TOKEN = "SANOMA_WAKEUP_TOKEN";
|
|
47
|
+
/** An instance token the service takes: `swi_`, then at least as many base64url characters as a minted one has. */
|
|
48
|
+
export declare const INSTANCE_TOKEN: RegExp;
|
|
49
|
+
/**
|
|
50
|
+
* An instance's URL as it is stored, without a trailing slash, or why it is refused: `http(s)`, no
|
|
51
|
+
* user or password, no query, no fragment (`/wake?generation=N` is added to it).
|
|
52
|
+
*/
|
|
53
|
+
export declare function instanceUrl(value: unknown): {
|
|
54
|
+
url: string;
|
|
55
|
+
} | {
|
|
56
|
+
error: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* An account of the wakeup service on `databaseUrl`, minted without starting the service (its
|
|
60
|
+
* tables made when missing): what `sanoma wakeup account <label>` prints.
|
|
61
|
+
*/
|
|
62
|
+
export declare function mintWakeupAccount(databaseUrl: string, label: string): Promise<{
|
|
63
|
+
id: string;
|
|
64
|
+
token: string;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* Starts the wakeup service on its own database: its two tables made when missing, its one loop
|
|
68
|
+
* running, and `routes` for whoever serves it (`sanoma wakeup`, or `sanoma serve` with
|
|
69
|
+
* `wakeup: true`). Routes, each JSON and `no-store`:
|
|
70
|
+
*
|
|
71
|
+
* - `POST /wakeup/instances { url, token }`, an account's token → 201 `{ id }` for a new instance
|
|
72
|
+
* token, 200 `{ id }` for one the account registered already, its URL now the given one (a lost
|
|
73
|
+
* reply, or a host that moved; its registered wake kept only when the URL is the same), 409 for
|
|
74
|
+
* another account's
|
|
75
|
+
* - `GET /wakeup/instances/{id}`, its account's token → `{ id, url, at, generation, calledAt, attempts, lastError }`
|
|
76
|
+
* - `DELETE /wakeup/instances/{id}`, its account's token → 204
|
|
77
|
+
* - `PUT /wakeup/wake { at, generation }`, an instance's own token, which names the instance → 204,
|
|
78
|
+
* applied only when `generation` is newer than the one it has, and waking the loop
|
|
79
|
+
*
|
|
80
|
+
* 401 without a token or with an unknown one, 403 for another account's instance, 400 for a bad
|
|
81
|
+
* body, 404 for an unknown id or path.
|
|
82
|
+
*/
|
|
83
|
+
export declare function startWakeupService({ databaseUrl, now, fetch, log, }: WakeupServiceOptions): Promise<WakeupService>;
|