@sanoma-ai/workflows 0.0.0-stage → 0.2.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.
Files changed (176) hide show
  1. package/LICENSE +105 -0
  2. package/README.md +544 -2
  3. package/dist/apply-steps.d.ts +6 -0
  4. package/dist/apply-steps.js +93 -0
  5. package/dist/apply-steps.js.map +1 -0
  6. package/dist/apply.d.ts +197 -0
  7. package/dist/apply.js +470 -0
  8. package/dist/apply.js.map +1 -0
  9. package/dist/approvals.d.ts +46 -0
  10. package/dist/approvals.js +111 -0
  11. package/dist/approvals.js.map +1 -0
  12. package/dist/ast.d.ts +57 -0
  13. package/dist/ast.js +81 -0
  14. package/dist/ast.js.map +1 -0
  15. package/dist/call.d.ts +37 -0
  16. package/dist/call.js +417 -0
  17. package/dist/call.js.map +1 -0
  18. package/dist/client.d.ts +203 -0
  19. package/dist/client.js +457 -0
  20. package/dist/client.js.map +1 -0
  21. package/dist/config.d.ts +126 -0
  22. package/dist/config.js +264 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/credentials.d.ts +55 -0
  25. package/dist/credentials.js +261 -0
  26. package/dist/credentials.js.map +1 -0
  27. package/dist/cucumber.d.ts +64 -0
  28. package/dist/cucumber.js +158 -0
  29. package/dist/cucumber.js.map +1 -0
  30. package/dist/datafile.d.ts +71 -0
  31. package/dist/datafile.js +380 -0
  32. package/dist/datafile.js.map +1 -0
  33. package/dist/db.d.ts +58 -0
  34. package/dist/db.js +179 -0
  35. package/dist/db.js.map +1 -0
  36. package/dist/define.d.ts +205 -0
  37. package/dist/define.js +103 -0
  38. package/dist/define.js.map +1 -0
  39. package/dist/describe.d.ts +141 -0
  40. package/dist/describe.js +135 -0
  41. package/dist/describe.js.map +1 -0
  42. package/dist/drift.d.ts +127 -0
  43. package/dist/drift.js +167 -0
  44. package/dist/drift.js.map +1 -0
  45. package/dist/env.d.ts +49 -0
  46. package/dist/env.js +83 -0
  47. package/dist/env.js.map +1 -0
  48. package/dist/errors.d.ts +88 -0
  49. package/dist/errors.js +148 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/expectations.d.ts +26 -0
  52. package/dist/expectations.js +162 -0
  53. package/dist/expectations.js.map +1 -0
  54. package/dist/fake.d.ts +55 -0
  55. package/dist/fake.js +87 -0
  56. package/dist/fake.js.map +1 -0
  57. package/dist/fill.d.ts +9 -0
  58. package/dist/fill.js +17 -0
  59. package/dist/fill.js.map +1 -0
  60. package/dist/host.d.ts +56 -0
  61. package/dist/host.js +45 -0
  62. package/dist/host.js.map +1 -0
  63. package/dist/index.d.ts +23 -0
  64. package/dist/index.js +29 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/ledger.d.ts +217 -0
  67. package/dist/ledger.js +251 -0
  68. package/dist/ledger.js.map +1 -0
  69. package/dist/lint.d.ts +32 -0
  70. package/dist/lint.js +168 -0
  71. package/dist/lint.js.map +1 -0
  72. package/dist/lockfile.d.ts +36 -0
  73. package/dist/lockfile.js +69 -0
  74. package/dist/lockfile.js.map +1 -0
  75. package/dist/log.d.ts +24 -0
  76. package/dist/log.js +83 -0
  77. package/dist/log.js.map +1 -0
  78. package/dist/op.d.ts +260 -0
  79. package/dist/op.js +188 -0
  80. package/dist/op.js.map +1 -0
  81. package/dist/outline.d.ts +179 -0
  82. package/dist/outline.js +506 -0
  83. package/dist/outline.js.map +1 -0
  84. package/dist/paths.d.ts +11 -0
  85. package/dist/paths.js +30 -0
  86. package/dist/paths.js.map +1 -0
  87. package/dist/plugin.d.ts +28 -0
  88. package/dist/plugin.js +25 -0
  89. package/dist/plugin.js.map +1 -0
  90. package/dist/policy.d.ts +114 -0
  91. package/dist/policy.js +60 -0
  92. package/dist/policy.js.map +1 -0
  93. package/dist/resource.d.ts +378 -0
  94. package/dist/resource.js +430 -0
  95. package/dist/resource.js.map +1 -0
  96. package/dist/resources.d.ts +77 -0
  97. package/dist/resources.js +244 -0
  98. package/dist/resources.js.map +1 -0
  99. package/dist/run.d.ts +101 -0
  100. package/dist/run.js +7 -0
  101. package/dist/run.js.map +1 -0
  102. package/dist/sandbox.d.ts +33 -0
  103. package/dist/sandbox.js +127 -0
  104. package/dist/sandbox.js.map +1 -0
  105. package/dist/scenario.d.ts +221 -0
  106. package/dist/scenario.js +1104 -0
  107. package/dist/scenario.js.map +1 -0
  108. package/dist/scenarios.d.ts +55 -0
  109. package/dist/scenarios.js +71 -0
  110. package/dist/scenarios.js.map +1 -0
  111. package/dist/secret.d.ts +42 -0
  112. package/dist/secret.js +58 -0
  113. package/dist/secret.js.map +1 -0
  114. package/dist/shared.d.ts +69 -0
  115. package/dist/shared.js +84 -0
  116. package/dist/shared.js.map +1 -0
  117. package/dist/source.d.ts +58 -0
  118. package/dist/source.js +54 -0
  119. package/dist/source.js.map +1 -0
  120. package/dist/steps.d.ts +76 -0
  121. package/dist/steps.js +23 -0
  122. package/dist/steps.js.map +1 -0
  123. package/dist/version.d.ts +29 -0
  124. package/dist/version.js +76 -0
  125. package/dist/version.js.map +1 -0
  126. package/dist/worker.d.ts +37 -0
  127. package/dist/worker.js +228 -0
  128. package/dist/worker.js.map +1 -0
  129. package/dist/writer.d.ts +35 -0
  130. package/dist/writer.js +201 -0
  131. package/dist/writer.js.map +1 -0
  132. package/oxlint.json +128 -0
  133. package/package.json +96 -3
  134. package/src/apply-steps.ts +110 -0
  135. package/src/apply.ts +626 -0
  136. package/src/approvals.ts +157 -0
  137. package/src/ast.ts +115 -0
  138. package/src/call.ts +483 -0
  139. package/src/client.ts +604 -0
  140. package/src/config.ts +404 -0
  141. package/src/credentials.ts +296 -0
  142. package/src/cucumber.ts +230 -0
  143. package/src/datafile.ts +481 -0
  144. package/src/db.ts +197 -0
  145. package/src/define.ts +285 -0
  146. package/src/describe.ts +282 -0
  147. package/src/drift.ts +259 -0
  148. package/src/env.ts +122 -0
  149. package/src/errors.ts +202 -0
  150. package/src/expectations.ts +191 -0
  151. package/src/fake.ts +156 -0
  152. package/src/fill.ts +24 -0
  153. package/src/host.ts +96 -0
  154. package/src/index.ts +143 -0
  155. package/src/ledger.ts +419 -0
  156. package/src/lint.ts +208 -0
  157. package/src/lockfile.ts +95 -0
  158. package/src/log.ts +82 -0
  159. package/src/op.ts +402 -0
  160. package/src/outline.ts +620 -0
  161. package/src/paths.ts +32 -0
  162. package/src/plugin.ts +37 -0
  163. package/src/policy.ts +139 -0
  164. package/src/resource.ts +670 -0
  165. package/src/resources.ts +311 -0
  166. package/src/run.ts +106 -0
  167. package/src/sandbox.ts +161 -0
  168. package/src/scenario.ts +1365 -0
  169. package/src/scenarios.ts +111 -0
  170. package/src/secret.ts +92 -0
  171. package/src/shared.ts +126 -0
  172. package/src/source.ts +82 -0
  173. package/src/steps.ts +90 -0
  174. package/src/version.ts +86 -0
  175. package/src/worker.ts +264 -0
  176. package/src/writer.ts +225 -0
package/dist/call.js ADDED
@@ -0,0 +1,417 @@
1
+ import { DBOS, DBOSWorkflowConflictError, Error as DBOSErrors } from "@dbos-inc/dbos-sdk";
2
+ import { awaitApproval } from "./approvals.js";
3
+ import { offsetOf } from "./ast.js";
4
+ import { AllMembers, ApprovalRequestSchema, SleepFor, SleepUntil, scriptPath, } from "./define.js";
5
+ import { causes, errorCode, errorInfo, isFinal, keepCode, parseOrThrow, PolicyDeniedError, SanomaError, } from "./errors.js";
6
+ import { currentGroup, entry, skipped, write, writeFailure } from "./ledger.js";
7
+ import { shown } from "./log.js";
8
+ import { isOp } from "./op.js";
9
+ import { callAt, callName } from "./outline.js";
10
+ import { DecisionSchema, policyOpOf } from "./policy.js";
11
+ import { isChangeOp } from "./resource.js";
12
+ import { APPLY_WORKFLOW, approverLabel, errorMessage, fitsOp } from "./shared.js";
13
+ /** DBOS took the run from this execution: it cancelled the run, or another process took it over. */
14
+ const takenByDbos = (err) => causes(err).some((e) => e instanceof DBOSErrors.DBOSWorkflowCancelledError || e instanceof DBOSWorkflowConflictError);
15
+ /**
16
+ * True for a failure that is not the run's outcome, so the ledger does not record it: DBOS
17
+ * cancelled the run or another process took it over, or the run's worker is stopping and the
18
+ * error has none of our codes. `stop()` marks the worker stopped before DBOS shuts down, so from
19
+ * then on whatever fails without a code (DBOS's "system database has been shut down", pg's
20
+ * closed pool) is the shutdown, and the run recovered on the next worker records how it ends.
21
+ * A coded failure then (a driver's final answer, a denial, a rejection) is still the outcome:
22
+ * DBOS records the run's error and never runs it again, so the ledger records it too. Narrower
23
+ * than `isRunControlError`: DBOS's other errors (a run that is not deterministic) end the run
24
+ * for good, and are recorded.
25
+ */
26
+ export function isInfrastructureError(err, state) {
27
+ return takenByDbos(err) || (state.stopped && errorCode(err) === undefined);
28
+ }
29
+ /** The value as the ledger records it: each of the operation's `opaque` fields as `"<name>"`. */
30
+ function recorded(op, value) {
31
+ if (!op.opaque?.length || typeof value !== "object" || value === null || Array.isArray(value))
32
+ return value;
33
+ const out = { ...value };
34
+ for (const name of op.opaque)
35
+ if (out[name] !== undefined)
36
+ out[name] = `<${name}>`;
37
+ return out;
38
+ }
39
+ /** How many times an idempotent operation is tried. */
40
+ const MAX_ATTEMPTS = 3;
41
+ // Matched by name too, since a workflow's schemas may come from another copy of zod.
42
+ const isSchemaError = (err) => err instanceof Error && err.name === "ZodError";
43
+ /**
44
+ * Whether DBOS should try an idempotent step again: not when the reply failed the output
45
+ * schema (it would fail again), and not when the driver said the vendor's answer is final
46
+ * (a `DriverError` with `retryable: false`, such as a 4xx). Read by code and property, never
47
+ * `instanceof`: the error may come from another copy of this package.
48
+ */
49
+ function shouldRetry(err) {
50
+ if (isSchemaError(err))
51
+ return false;
52
+ return !(errorCode(err) === "driver_failed" && isFinal(err));
53
+ }
54
+ /*
55
+ * A run's ctx calls run one at a time, in program order, even when the workflow starts several
56
+ * at once (Promise.all). Every DBOS call (a step, now, sleep, setEvent, recv) takes the run's
57
+ * next function id when it starts, and a replay matches each recorded result to a call by that
58
+ * id. Calls left to run concurrently would take ids in the order their earlier awaits happened
59
+ * to resolve, which differs between the first execution and a replay that reads results back
60
+ * from the database, and so would the ledger's `seq` and the approval ids. Queued, each call
61
+ * starts once the one before it has settled, so the order is the order the workflow made them.
62
+ */
63
+ function serial(run, call) {
64
+ // A failure rejects its caller; the calls queued after it still run, since the workflow may
65
+ // have caught it. Once the workflow body itself has ended, nothing queued may run. The body
66
+ // awaits only ctx calls, so one macrotask after the call before settles, the body has either
67
+ // caught the failure and gone on or ended; the rejection alone reaches it in the same
68
+ // microtask flush that would start this call.
69
+ const next = run.tail
70
+ .then(() => new Promise((r) => setImmediate(r)))
71
+ .then(() => {
72
+ refuseIfEnded(run);
73
+ return call();
74
+ });
75
+ // Settled either way, and holding nothing: the queue keeps neither the output nor the error.
76
+ run.tail = next.then(noop, noop);
77
+ return next;
78
+ }
79
+ const noop = () => { };
80
+ /** Throws once the workflow body has returned or thrown: a call left queued must not run then. */
81
+ function refuseIfEnded(run) {
82
+ if (run.ended) {
83
+ throw new SanomaError("run_ended", `run ${run.id} has ended; a call queued behind its failure was not made`, {
84
+ runId: run.id,
85
+ });
86
+ }
87
+ }
88
+ /** The step's name the outline gives a call's node: none for a computed op without one, or an approval's title that is no literal. */
89
+ const named = (node) => ("name" in node ? node.name : undefined);
90
+ /**
91
+ * The run's `ctx`: the operations and built-ins its workflow `uses`, and nothing else. Every
92
+ * member that writes a record is placed in the outline where the workflow calls it (`placeCall`)
93
+ * and goes through the run's queue (`serial`), its records carrying the node and the step's
94
+ * name; `ctx.now()` only reads the clock, queued, and `ctx.runId` is a value. `ctx.all` alone
95
+ * skips the queue: it makes no DBOS call or record itself, it only calls its members, whose ctx
96
+ * calls are queued. Queued, it would hold the queue until its members settled, and their calls,
97
+ * queued behind it, would never start.
98
+ */
99
+ export function buildCtx(wf, run) {
100
+ const uses = wf.uses;
101
+ /** A member placed where it is called, then `call`ed with its node. A refusal rejects, as a member's failure always has. */
102
+ const placed = (what, call) => async function member(...args) {
103
+ return call(placeCall(run, member, what), ...args);
104
+ };
105
+ const members = {};
106
+ for (const op of uses.filter(isOp)) {
107
+ const vendor = (members[op.vendor] ??= {});
108
+ const resource = (vendor[op.resource] ??= {});
109
+ resource[op.name] = placed(op.id, (node, input) => serial(run, () => callOp(run, op.id, input, { node: node.path, name: named(node) ?? op.id })));
110
+ }
111
+ members.runId = run.id;
112
+ members.now = () => serial(run, () => DBOS.now());
113
+ if (uses.includes("approval")) {
114
+ members.approval = placed("approval", (node, title, req) => serial(run, () => awaitApproval(run, title, checkApproval(title, req), { node: node.path, name: named(node) ?? title })));
115
+ }
116
+ if (uses.includes("sleep")) {
117
+ members.sleep = placed("sleep", (node, req) =>
118
+ // The outline names every sleep.
119
+ serial(run, () => sleep(run, req, { node: node.path, name: named(node) })));
120
+ }
121
+ if (uses.includes("all"))
122
+ members.all = placed("all", (node, list) => all(run, list, node.path));
123
+ return guarded(members, "ctx", wf.name);
124
+ }
125
+ /** `members`, each object in it included, refusing any member not in it (`strict`). */
126
+ function guarded(members, path, workflow) {
127
+ const out = {};
128
+ for (const [key, value] of Object.entries(members)) {
129
+ out[key] =
130
+ typeof value === "object" && value !== null
131
+ ? guarded(value, `${path}.${key}`, workflow)
132
+ : value;
133
+ }
134
+ return strict(out, path, workflow);
135
+ }
136
+ /**
137
+ * The frame above `fn`, the `ctx` member running, read from a stack trace rather than
138
+ * `util.getCallSites`: a test runner that transforms the source maps the trace back to it, and
139
+ * Node runs TypeScript stripped in place, so the position is the file's either way. One frame is
140
+ * captured: the rest would only be formatted and dropped.
141
+ */
142
+ function callSite(fn) {
143
+ const holder = {};
144
+ const limit = Error.stackTraceLimit;
145
+ Error.stackTraceLimit = 1;
146
+ try {
147
+ Error.captureStackTrace(holder, fn);
148
+ }
149
+ finally {
150
+ Error.stackTraceLimit = limit;
151
+ }
152
+ // `at run (/dir/file.ts:21:37)`, `at /dir/file.ts:21:37` or `at async run (file:///dir/file.ts:21:37)`.
153
+ const frame = holder.stack?.split("\n")[1]?.trim();
154
+ const m = frame === undefined ? null : /^at (?:.*?\()?(.+?):(\d+):(\d+)\)?$/.exec(frame);
155
+ const file = m && scriptPath(m[1]);
156
+ return file ? { file, line: Number(m[2]), column: Number(m[3]) } : undefined;
157
+ }
158
+ /**
159
+ * The outline node the workflow calls a `ctx` member at: the call whose code holds the position
160
+ * the workflow called from (`callSite`). `what` is the member's path on `ctx` (`ghost.post.create`,
161
+ * `approval`, `all`). The outline refuses most ways around it before a run (`outlineBody`'s
162
+ * problems); this is the run's own check, for what reaches a `ctx` member from code the outline
163
+ * has no node for: another file, a function defined inside `run` the outline does not read,
164
+ * `arguments`, or a node of another kind. The run fails with `call_not_in_outline`, and every
165
+ * record the call writes names the node, so a run's steps are the outline's calls and nothing else.
166
+ */
167
+ function placeCall(run, fn, what) {
168
+ const { outline, workflow } = run;
169
+ const site = callSite(fn);
170
+ if (!site)
171
+ throw notInOutline(run, what, site, "which the outline cannot place");
172
+ if (site.file !== outline.file)
173
+ throw notInOutline(run, what, site, `which is not in ${workflow}'s file ${outline.file}`);
174
+ const offset = offsetOf(outline.lineStarts, site.line, site.column);
175
+ const node = offset === undefined ? undefined : callAt(outline.calls, offset);
176
+ if (!node)
177
+ throw notInOutline(run, what, site, `which is no ctx call in ${workflow}'s outline`);
178
+ // The member called is the node's call: `ctx.all` at an `all` or `each`, an operation at its op.
179
+ if (!fitsOp(callName(node), what))
180
+ throw notInOutline(run, what, site, `where the outline has ctx.${callName(node)}`);
181
+ return node;
182
+ }
183
+ function notInOutline(run, what, site, why) {
184
+ const where = site ? `${site.file}:${site.line}:${site.column}` : "a place the stack does not show";
185
+ return new SanomaError("call_not_in_outline", `ctx.${what} was called from ${where}, ${why}: call ctx directly in run, not from a helper or a function ` +
186
+ "defined inside run (inline it), so the run's graph shows the call", { call: `ctx.${what}`, site: where, workflow: run.workflow });
187
+ }
188
+ /** Refuses anything not declared in `uses`, with a message that says so. */
189
+ function strict(obj, path, workflow) {
190
+ return new Proxy(obj, {
191
+ get(target, key, receiver) {
192
+ if (typeof key === "symbol" || key === "then" || key in target)
193
+ return Reflect.get(target, key, receiver);
194
+ throw new Error(`${path}.${key} is not available: add it to \`uses\` in workflow "${workflow}"`);
195
+ },
196
+ });
197
+ }
198
+ /** Checks a policy's answer, and copies it so nothing else the policy returned is recorded. */
199
+ function checkDecision(decision, opId) {
200
+ const parsed = DecisionSchema.safeParse(decision);
201
+ if (parsed.success)
202
+ return parsed.data;
203
+ const why = parsed.error.issues[0]?.message ?? "not a decision";
204
+ throw new Error(`The policy returned ${shown(decision)} for ${opId}: ${why}; use allow(), deny(reason) or approve(approver)`);
205
+ }
206
+ /** The resource instance the call acts on, from the operation's `target`, when it declares one. */
207
+ function targetOf(op, input) {
208
+ if (!op.target)
209
+ return {};
210
+ const target = op.target(input);
211
+ if (typeof target !== "string") {
212
+ throw new Error(`${op.id}: \`target\` returned ${typeof target}, not a string`);
213
+ }
214
+ return { target };
215
+ }
216
+ /** Asks the policy about one call, and checks its answer. Runs inside a step, so it must have no side effects of its own. */
217
+ export async function decide(run, op, input) {
218
+ const call = {
219
+ op: policyOpOf(op),
220
+ effect: op.effect,
221
+ ...targetOf(op, input),
222
+ input,
223
+ actor: run.actor,
224
+ run: { id: run.id, workflow: run.workflow, approvals: structuredClone(run.approvals) },
225
+ };
226
+ let answer;
227
+ try {
228
+ answer = await run.state.policy(call);
229
+ }
230
+ catch (err) {
231
+ // Named here, so the run's error and the ledger say which call the policy failed on, with
232
+ // the code the policy's error had.
233
+ if (isInfrastructureError(err, run.state))
234
+ throw err;
235
+ throw keepCode(new Error(`The policy failed deciding ${op.id}: ${errorMessage(err)}`, { cause: err }), err);
236
+ }
237
+ const decision = checkDecision(answer, op.id);
238
+ const policyVersion = run.state.policy.version;
239
+ return policyVersion === undefined ? decision : { ...decision, policyVersion };
240
+ }
241
+ async function callOp(run, id, input, place) {
242
+ // The worker's declaration, never the workflow's: its effect, schemas and retry setting.
243
+ const op = run.state.ops.get(id);
244
+ // A sandbox run calls its own fakes, never a vendor.
245
+ const fn = run.sandbox === undefined ? run.state.drivers.get(id) : run.fakeDrivers?.get(id);
246
+ if (!op || !fn) {
247
+ throw new Error(run.sandbox === undefined
248
+ ? `No connector or driver for ${id} in this worker`
249
+ : `No connector or fake for ${id} in this worker: no fake its connectors attach implements it`);
250
+ }
251
+ // Only apply changes a declared resource; `resolveConfig` refuses any other workflow that uses such an operation.
252
+ if (isChangeOp(op, run.state.types) && run.workflow !== APPLY_WORKFLOW) {
253
+ throw new SanomaError("invalid_input", `${op.id} changes a declared resource, which only ${APPLY_WORKFLOW} does`, {
254
+ op: op.id,
255
+ workflow: run.workflow,
256
+ });
257
+ }
258
+ const parsed = parseOrThrow(op.input, input, `The input to ${op.id} does not match its schema`, { op: op.id });
259
+ // The call's identity (its ledger seq and id, and the driver's idempotency key) is taken
260
+ // before the first await, so it depends only on the order the workflow made its calls. A
261
+ // replay skips the step bodies but counts the same way. A call held for an approval is
262
+ // numbered before the approval's records, so its op.called sorts ahead of them.
263
+ const seq = run.seq++;
264
+ // The decision is recorded as a step, so a replay reuses it instead of asking a policy
265
+ // that may have changed since. The policy must still be deterministic: a run that fails
266
+ // before the step is recorded asks again.
267
+ const decision = await DBOS.runStep(() => decide(run, op, parsed), { name: `policy:${op.id}` });
268
+ const logged = recorded(op, parsed);
269
+ const call = { type: "op.called", op: op.id, ...place, effect: op.effect, input: logged, decision };
270
+ if (decision.kind === "deny") {
271
+ const err = new PolicyDeniedError(op.id, decision.reason);
272
+ await writeFailure(run, entry(run, { ...call, error: errorInfo(err), durationMs: 0 }, { seq }), err);
273
+ throw err;
274
+ }
275
+ if (decision.kind === "approve") {
276
+ const title = decision.title ?? `${op.id} needs ${approverLabel(decision.approver)}`;
277
+ // A hold covers the call it held, and any other operations the policy named.
278
+ const covers = [...new Set([op.id, ...(decision.covers ?? [])])];
279
+ try {
280
+ await awaitApproval(run, title, { approver: decision.approver, covers }, place, {
281
+ op: op.id,
282
+ seq,
283
+ input: logged,
284
+ });
285
+ }
286
+ catch (err) {
287
+ if (errorCode(err) === "approval_rejected") {
288
+ const approval = err.data.approvalId;
289
+ const record = entry(run, { ...call, approval, error: errorInfo(err), durationMs: 0 }, { seq });
290
+ await writeFailure(run, record, err);
291
+ }
292
+ throw err;
293
+ }
294
+ }
295
+ const started = Date.now();
296
+ // The try DBOS is on, as it passes it to the step. The last try's error is not retried, so
297
+ // DBOS records and throws it as the vendor gave it, never wrapped with the others.
298
+ let attempt;
299
+ let result;
300
+ try {
301
+ result = await DBOS.runStep(async () => {
302
+ const at = Date.now();
303
+ attempt = DBOS.stepStatus?.currentAttempt ?? 1;
304
+ const secrets = run.sandbox === undefined ? run.state.secrets : run.fakeSecrets;
305
+ const context = {
306
+ idempotencyKey: `${run.id}:${seq}`,
307
+ runId: run.id,
308
+ opId: op.id,
309
+ attempt,
310
+ secrets,
311
+ };
312
+ // A live driver's `env` is checked here, inside the step, by the guard `indexDrivers` put
313
+ // on its function: the refusal is the call's failure, recorded and never retried.
314
+ const output = op.output.parse(await fn(parsed, context));
315
+ return { output, at, durationMs: Date.now() - at, attempt };
316
+ }, {
317
+ name: op.id,
318
+ retriesAllowed: op.idempotent,
319
+ maxAttempts: MAX_ATTEMPTS,
320
+ shouldRetry: (e) => shouldRetry(e) && (attempt ?? 1) < MAX_ATTEMPTS,
321
+ });
322
+ }
323
+ catch (err) {
324
+ // The step failed for good; on replay DBOS rethrows the recorded error, and this record
325
+ // gets the same id. A success record would too, so a call has one op.called at most.
326
+ const record = entry(run, { ...call, error: errorInfo(err), durationMs: Date.now() - started, ...(attempt ? { attempt } : {}) }, { seq, at: started });
327
+ if (isInfrastructureError(err, run.state))
328
+ skipped(record, `the call was interrupted (${errorMessage(err)})`);
329
+ else
330
+ await writeFailure(run, record, err);
331
+ throw err;
332
+ }
333
+ const { output, at, durationMs } = result;
334
+ try {
335
+ await write(run, entry(run, { ...call, output: recorded(op, output), durationMs, attempt: result.attempt }, { seq, at }));
336
+ }
337
+ catch (err) {
338
+ // The vendor acted, and nothing records it. A workflow that caught this and called again
339
+ // would repeat the side effect under a new key, so the run makes no further calls.
340
+ run.ended = true;
341
+ throw new Error(`${op.id} succeeded, but the ledger could not record it: ${errorMessage(err)}`, { cause: err });
342
+ }
343
+ return output;
344
+ }
345
+ /**
346
+ * Checks a `ctx.approval` request before any DBOS call, so a bad one fails the run with
347
+ * `invalid_input`: who may decide it, and the operations it covers, as ids (none unless named).
348
+ */
349
+ function checkApproval(title, req) {
350
+ const checked = parseOrThrow(ApprovalRequestSchema, req, `ctx.approval("${title}")`, { title });
351
+ return { ...checked, covers: checked.covers ?? [] };
352
+ }
353
+ /** Checks a sleep request before any DBOS call, so a bad one fails the run with `invalid_input`. */
354
+ function checkSleep(req) {
355
+ const timed = typeof req === "object" && req !== null && "until" in req;
356
+ return parseOrThrow(timed ? SleepUntil : SleepFor, req, `ctx.sleep(${shown(req)})`);
357
+ }
358
+ /**
359
+ * Calls the members one after another, each awaited before the next starts, each inside its
360
+ * group (`currentGroup`), so every record its calls write carries it. The first failure stops
361
+ * the group and is rethrown as it is. The id is the run's next `seq` when ctx.all begins, which
362
+ * depends only on the calls made before it, so a replay names the group the same.
363
+ */
364
+ async function all(run, list, node) {
365
+ const outer = currentGroup.getStore();
366
+ if (outer) {
367
+ throw new SanomaError("invalid_input", "ctx.all cannot be nested: a member of a ctx.all called ctx.all", {
368
+ group: outer.id,
369
+ });
370
+ }
371
+ // Two groups' calls would interleave on the run's queue, and neither would read as one fan-out.
372
+ if (run.inAll)
373
+ throw new SanomaError("invalid_input", "a ctx.all is already running: await it before the next");
374
+ const members = parseOrThrow(AllMembers, list, "ctx.all");
375
+ const id = `all:${run.seq}`;
376
+ const outputs = [];
377
+ run.inAll = true;
378
+ try {
379
+ for (const [index, member] of members.entries()) {
380
+ outputs.push(await currentGroup.run({ id, index, size: members.length, node }, member));
381
+ }
382
+ }
383
+ finally {
384
+ run.inAll = false;
385
+ }
386
+ return outputs;
387
+ }
388
+ /**
389
+ * Waits, durably, until the time or for the duration the request names, and records when it
390
+ * ends. For a duration that is the time the sleep started plus the duration, as the runtime saw
391
+ * it (`Date.now()`, which adds no DBOS call): a replay may compute another, but the store keeps
392
+ * the first record with the id, so the record says what the first execution waited for.
393
+ */
394
+ async function sleep(run, raw, at) {
395
+ const req = checkSleep(raw);
396
+ const seq = run.seq++;
397
+ let until;
398
+ let ms;
399
+ if ("until" in req) {
400
+ until = typeof req.until === "number" ? req.until : Date.parse(req.until);
401
+ ms = until - (await DBOS.now());
402
+ }
403
+ else {
404
+ ms =
405
+ (req.ms ?? 0) +
406
+ (req.seconds ?? 0) * 1_000 +
407
+ (req.minutes ?? 0) * 60_000 +
408
+ (req.hours ?? 0) * 3_600_000 +
409
+ (req.days ?? 0) * 86_400_000;
410
+ until = Date.now() + ms;
411
+ }
412
+ await write(run, entry(run, { type: "sleep.started", ...at, until }, { seq }));
413
+ // A time already past waits not at all, and adds no step. A sandbox run never waits.
414
+ if (ms > 0 && run.sandbox === undefined)
415
+ await DBOS.sleep(ms);
416
+ }
417
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../src/call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,203 @@
1
+ import { type WorkflowStatusString } from "@dbos-inc/dbos-sdk";
2
+ import { z } from "zod";
3
+ import { ApprovalMessage } from "./approvals.ts";
4
+ import { type SanomaConfig } from "./config.ts";
5
+ import { type CredentialStatus } from "./env.ts";
6
+ import { type ApprovalState, Principal, type WorkflowDefinition } from "./define.ts";
7
+ import { type ApplyInput, type ApplyReport } from "./apply.ts";
8
+ import { type DriftReport } from "./drift.ts";
9
+ import { type LedgerRecord } from "./ledger.ts";
10
+ import { type RunStatus } from "./shared.ts";
11
+ /** A run's status from DBOS's, and whether it has an approval pending. */
12
+ export declare function runStatus(dbosStatus: string, approvals: readonly ApprovalState[]): RunStatus;
13
+ /** The DBOS statuses the run statuses come from; `running` and `waiting` both come from PENDING. */
14
+ export declare const dbosStatusesOf: (...statuses: RunStatus[]) => WorkflowStatusString[];
15
+ /**
16
+ * The first `limit` items `keep` accepts, read a page of `pageSize` at a time from `list`, in
17
+ * its order, until there are enough or a page comes back short (the last one).
18
+ */
19
+ export declare function firstMatching<T>(list: (page: {
20
+ limit: number;
21
+ offset: number;
22
+ }) => Promise<T[]>, keep: (item: T) => boolean, limit: number, pageSize: number): Promise<T[]>;
23
+ /** Which runs `SanomaClient.runs` lists. */
24
+ export interface RunsFilter {
25
+ /** At most this many, newest first. Defaults to 20. */
26
+ limit?: number;
27
+ /** Only runs with this status. */
28
+ status?: RunStatus;
29
+ /** Only runs of the workflow of this name. */
30
+ workflow?: string;
31
+ }
32
+ export interface RunSummary {
33
+ runId: string;
34
+ workflow: string;
35
+ status: RunStatus;
36
+ /** Who started the run, as passed to `start`. */
37
+ startedBy?: Principal;
38
+ createdAt: number;
39
+ updatedAt?: number;
40
+ approvals: ApprovalState[];
41
+ error?: string;
42
+ /** For a sandbox run, the scenario it was seeded from. */
43
+ sandbox?: string;
44
+ }
45
+ export interface StartOptions {
46
+ /** Recorded as the run's actor in the ledger and passed to the policy. */
47
+ startedBy: Principal;
48
+ /**
49
+ * Use this run id instead of a new one, so a retried start makes one run. Starting an id
50
+ * that exists returns it, without starting another, when the workflow, the input (compared
51
+ * as JSON), `startedBy` and `sandbox` are the same, and throws `invalid_input` naming what differs
52
+ * when they are not. Of two starts racing with one new id, the first's run stands.
53
+ */
54
+ runId?: string;
55
+ /**
56
+ * Start a sandbox run, seeded from the config's scenario of this name: it calls its own fakes,
57
+ * made for it by its connectors' makers, instead of the drivers, and does not wait on sleeps.
58
+ * Sandbox runs go on the app's queue like any run, so several run at once.
59
+ */
60
+ sandbox?: string;
61
+ }
62
+ /** Talks to the runtime from another process (the app, a script), through the shared Postgres. */
63
+ export declare class SanomaClient {
64
+ private readonly dbos;
65
+ private readonly config;
66
+ private readonly drivers;
67
+ /** The config's own ledger store, or a Postgres one made for this client, which `close` then closes. */
68
+ private readonly audit;
69
+ /** On the config's database, for the credentials table: opened on first use. */
70
+ private readonly credentialsPool;
71
+ private constructor();
72
+ /**
73
+ * Connects to the runtime's Postgres for the config's app. Checks the config first and throws
74
+ * what the worker would refuse. Reads ledgers from the config's ledger store, or from the
75
+ * Postgres store on its database when it has none.
76
+ */
77
+ static connect(config: SanomaConfig): Promise<SanomaClient>;
78
+ /**
79
+ * Checks the input against the workflow's schema, then queues a run for the worker. The run
80
+ * gets the input as sent, not as the schema parsed it: the worker parses it once, so a schema
81
+ * with a `.transform` or a default sees the caller's value, and `run.started` records it.
82
+ * `workflow` is a definition, or the name of one in the config's `workflows`.
83
+ */
84
+ start<S extends z.ZodType>(workflow: WorkflowDefinition<any, S> | string, input: z.input<S>, options: StartOptions): Promise<string>;
85
+ /** The run's audit record, in order, from the ledger store. */
86
+ ledger(runId: string): Promise<LedgerRecord[]>;
87
+ /**
88
+ * The app's runs, newest first: the latest `limit`, or the latest `limit` with a `status`.
89
+ * Only the approvals tell `running` from `waiting`, so those read PENDING runs a page at a
90
+ * time until `limit` have that status.
91
+ */
92
+ runs({ limit, status, workflow }?: RunsFilter): Promise<RunSummary[]>;
93
+ run(runId: string): Promise<RunSummary | undefined>;
94
+ approvals(runId: string): Promise<ApprovalState[]>;
95
+ /**
96
+ * Sends a decision on the run's pending approval (or the one named), as `message.by`, and
97
+ * waits for the run to read it. Returns the approval as decided. Throws without sending when
98
+ * it is decided already (`already_decided`), when the run has finished, failed or been
99
+ * cancelled (`run_ended`), when there is nothing to decide (`no_pending_approval`,
100
+ * `run_not_found`), or when `by` may not decide it (`not_approver`); and throws
101
+ * `already_decided` too when another decision reached the run first, and `not_approver` when
102
+ * the run read this one and refused it.
103
+ *
104
+ * If the run does not read the decision within `timeoutSeconds` (30 by default; the worker
105
+ * may be down), returns the approval as it stands, still `pending`: the decision stays
106
+ * queued for the run, which reads it when it next runs.
107
+ */
108
+ decide(runId: string, message: ApprovalMessage, approvalId?: string, options?: {
109
+ timeoutSeconds?: number;
110
+ }): Promise<ApprovalState>;
111
+ /**
112
+ * The run's output once it ends, or its error. Throws `run_running` when it has not ended
113
+ * within `timeoutMs`; the run goes on.
114
+ */
115
+ result(runId: string, timeoutMs?: number): Promise<unknown>;
116
+ /**
117
+ * Starts the built-in drift workflow, which reads the config's data files itself: `start`
118
+ * with its input, `{}`. Returns the run id; `driftReport` waits for its report. Throws
119
+ * `invalid_input` when the config's connectors declare no resource types, so it has none.
120
+ */
121
+ drift(options: StartOptions): Promise<string>;
122
+ /** The report of a drift run once it ends: as `applyReport` for apply. */
123
+ driftReport(runId: string): Promise<DriftReport>;
124
+ /**
125
+ * Starts the built-in apply workflow, which reads the config's data files itself, with `input`
126
+ * (`only`, `bind`, `answers`; `{}` for all). Returns the run id; `applyReport` waits for its
127
+ * report. Throws `invalid_input` when the config's connectors declare no resource types.
128
+ */
129
+ apply(input: ApplyInput, options: StartOptions): Promise<string>;
130
+ /**
131
+ * The report of an apply run once it ends. Throws `run_not_found`, `invalid_input` for another
132
+ * workflow's run, the run's error when it failed, and `run_running` when it has not ended
133
+ * within 30 s.
134
+ */
135
+ applyReport(runId: string): Promise<ApplyReport>;
136
+ /** The built-in workflow `name`; `invalid_input` when the config has none, as its connectors declare no resource types. */
137
+ private builtIn;
138
+ /** The output of a run of the built-in `workflow` once it ends. */
139
+ private reportOf;
140
+ /**
141
+ * Stores a value for a variable a driver's `env` declares, as `by`, and tells the workers: each
142
+ * loads it into its environment, unless its environment sets the variable itself. Refuses
143
+ * (`invalid_input`) a name no driver declares, and a value the variable's schema refuses, with
144
+ * the schema's reason and never the value; an empty value too (`clearCredential` unsets one).
145
+ * Nothing records the value but its row, which records `by` and when.
146
+ */
147
+ setCredential(name: string, value: string, options: {
148
+ by: string;
149
+ }): Promise<void>;
150
+ /**
151
+ * Deletes the stored value of a declared variable, and tells the workers, which unset it unless
152
+ * their environment sets it. `by` is who asks; nothing records it once the row is gone.
153
+ * Refuses (`invalid_input`) a name no driver declares.
154
+ */
155
+ clearCredential(name: string, options: {
156
+ by: string;
157
+ }): Promise<void>;
158
+ /**
159
+ * Stores a secret as `by`, and tells the workers: a value under any variable's name, declared by
160
+ * a driver or not, such as a data file's `secret("NAME")` or the app's own (its GitHub App's
161
+ * keys). A name a driver declares is checked as `setCredential` checks it; any other name must
162
+ * look like a variable's, and the value must not be empty (`invalid_input`, never the value).
163
+ */
164
+ setSecret(name: string, value: string, options: {
165
+ by: string;
166
+ }): Promise<void>;
167
+ /**
168
+ * The values of these secrets, as a driver's `secrets.get` reads them: this process's
169
+ * environment, which wins, else the stored value, with who set it and when. A name with neither
170
+ * is left out. For server code: a page is told whether one is set, never its value.
171
+ */
172
+ secrets(names: readonly string[]): Promise<Map<string, StoredSecret>>;
173
+ /**
174
+ * Each vendor's declared variables and their statuses now: from this process's environment,
175
+ * which wins, else from the stored credentials, with `source` saying which (a value equal to
176
+ * the stored one, as a worker in this process loads it, is `stored`), and who set a stored one
177
+ * and when. Never a value.
178
+ */
179
+ credentials(): Promise<Map<string, CredentialStatus[]>>;
180
+ close(): Promise<void>;
181
+ /**
182
+ * The name's statuses with `lookup`'s value, one per vendor whose drivers declare it, or
183
+ * `invalid_input` when none does.
184
+ */
185
+ private declared;
186
+ /** The pool the credentials are read and written with, on the database once it is prepared. */
187
+ private credentialsDb;
188
+ /** Refuses a run id whose run, as stored, was started with another input, by someone else, or in another sandbox. */
189
+ private mustMatch;
190
+ /** The run's status row, read without its input (and its output, unless asked), or `run_not_found`. */
191
+ private mustExist;
192
+ /** The run's output once it ends, or its error, polled every 100 ms; `run_running` after `timeoutMs`. */
193
+ private awaitResult;
194
+ private summarize;
195
+ }
196
+ /** A secret's value as `SanomaClient.secrets` reads it, and where from. */
197
+ export interface StoredSecret {
198
+ value: string;
199
+ source: "environment" | "stored";
200
+ /** Who stored it (`setSecret`'s `by`), and when, as an ISO 8601 time. */
201
+ setBy?: string;
202
+ setAt?: string;
203
+ }