sayiir 0.1.0-alpha.3
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 +291 -0
- package/dist/duration.d.ts +15 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/duration.js +33 -0
- package/dist/duration.js.map +1 -0
- package/dist/executor.d.ts +52 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +125 -0
- package/dist/executor.js.map +1 -0
- package/dist/flow.d.ts +120 -0
- package/dist/flow.d.ts.map +1 -0
- package/dist/flow.js +208 -0
- package/dist/flow.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/native.d.ts +63 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +49 -0
- package/dist/native.js.map +1 -0
- package/dist/task.d.ts +29 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +83 -0
- package/dist/task.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +66 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +74 -0
- package/dist/worker.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Sayiir
|
|
2
|
+
|
|
3
|
+
**Durable workflows for Node.js and TypeScript, powered by a Rust runtime.**
|
|
4
|
+
|
|
5
|
+
[](https://github.com/sayiir/sayiir/blob/main/LICENSE)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](https://discord.gg/MWSzsHeg)
|
|
8
|
+
|
|
9
|
+
Write plain TypeScript functions. Sayiir makes them durable — automatic checkpointing, crash recovery, and parallel execution with zero infrastructure.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { task, flow, runWorkflow } from "sayiir";
|
|
13
|
+
|
|
14
|
+
const fetchUser = task("fetch-user", async (id: number) => {
|
|
15
|
+
return { id, name: "Alice" };
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const sendEmail = task("send-email", (user: { id: number; name: string }) => {
|
|
19
|
+
return `Sent welcome to ${user.name}`;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const workflow = flow<number>("welcome")
|
|
23
|
+
.then(fetchUser)
|
|
24
|
+
.then(sendEmail)
|
|
25
|
+
.build();
|
|
26
|
+
|
|
27
|
+
const result = runWorkflow(workflow, 42);
|
|
28
|
+
// "Sent welcome to Alice"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
No DSL. No YAML. No determinism constraints. No infrastructure to deploy.
|
|
32
|
+
|
|
33
|
+
## Why Sayiir?
|
|
34
|
+
|
|
35
|
+
- **No replay, no determinism rules** — Unlike Temporal, Restate, and other replay-based engines, Sayiir checkpoints after each task and resumes from the last checkpoint. Your tasks can call any API, use any library, read the clock, generate random values. No restrictions.
|
|
36
|
+
- **A library, not a platform** — `pnpm add sayiir` and write workflows. No server cluster, no separate services. Optional PostgreSQL for production persistence.
|
|
37
|
+
- **Rust core** — All orchestration, checkpointing, and execution runs in Rust via NAPI-RS. You write TypeScript; Rust handles the hard parts.
|
|
38
|
+
- **Type-safe** — Generic `Flow<TInput, TLast>` builder tracks types through the chain. Full inference, no manual annotations.
|
|
39
|
+
- **Zod integration** — Optional input/output validation with Zod schemas as a peer dependency.
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm add sayiir
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Requires Node.js 18 or higher.
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
### Inline lambdas — zero boilerplate
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { flow, runWorkflow } from "sayiir";
|
|
55
|
+
|
|
56
|
+
const workflow = flow<number>("pipeline")
|
|
57
|
+
.then("double", (x) => x * 2)
|
|
58
|
+
.then("add-one", (x) => x + 1)
|
|
59
|
+
.then("stringify", (x) => String(x))
|
|
60
|
+
.build();
|
|
61
|
+
|
|
62
|
+
const result = runWorkflow(workflow, 5);
|
|
63
|
+
// "11" (5 * 2 = 10, 10 + 1 = 11, String(11))
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
No decorators, no registration — just pass any function. Use `task()` when you need metadata (retries, timeouts, tags) or reusable task definitions.
|
|
67
|
+
|
|
68
|
+
### Sequential workflow
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { task, flow, runWorkflow } from "sayiir";
|
|
72
|
+
|
|
73
|
+
const double = task("double", (x: number) => x * 2);
|
|
74
|
+
const addTen = task("add-ten", (x: number) => x + 10);
|
|
75
|
+
|
|
76
|
+
const workflow = flow<number>("math")
|
|
77
|
+
.then(double)
|
|
78
|
+
.then(addTen)
|
|
79
|
+
.build();
|
|
80
|
+
|
|
81
|
+
const result = runWorkflow(workflow, 5);
|
|
82
|
+
// 20 (5 * 2 = 10, 10 + 10 = 20)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Durable workflow (survives crashes)
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { task, flow, runDurableWorkflow, InMemoryBackend } from "sayiir";
|
|
89
|
+
|
|
90
|
+
const processOrder = task("process-order", (orderId: number) => {
|
|
91
|
+
return { orderId, status: "processed" };
|
|
92
|
+
}, { timeout: "30s" });
|
|
93
|
+
|
|
94
|
+
const sendConfirmation = task("send-confirmation", (order: { orderId: number }) => {
|
|
95
|
+
return `Confirmed order ${order.orderId}`;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const workflow = flow<number>("order")
|
|
99
|
+
.then(processOrder)
|
|
100
|
+
.then(sendConfirmation)
|
|
101
|
+
.build();
|
|
102
|
+
|
|
103
|
+
const backend = new InMemoryBackend();
|
|
104
|
+
|
|
105
|
+
// Checkpoints after each task — resumes from last checkpoint on crash
|
|
106
|
+
const status = runDurableWorkflow(workflow, "order-123", 42, backend);
|
|
107
|
+
|
|
108
|
+
if (status.status === "completed") {
|
|
109
|
+
console.log(status.output); // "Confirmed order 42"
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### PostgreSQL persistence
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { PostgresBackend, runDurableWorkflow } from "sayiir";
|
|
117
|
+
|
|
118
|
+
// Auto-runs migrations on first connect
|
|
119
|
+
const backend = PostgresBackend.connect("postgresql://localhost/sayiir");
|
|
120
|
+
const status = runDurableWorkflow(workflow, "run-001", 21, backend);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Retry policy
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { task } from "sayiir";
|
|
127
|
+
|
|
128
|
+
const flakyCall = task("flaky-call", async (url: string) => {
|
|
129
|
+
const res = await fetch(url);
|
|
130
|
+
return res.json();
|
|
131
|
+
}, {
|
|
132
|
+
retry: { maxAttempts: 3, initialDelay: "500ms", backoffMultiplier: 2.0 },
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Parallel execution (fork/join)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { task, flow, branch, runWorkflow } from "sayiir";
|
|
140
|
+
|
|
141
|
+
const validatePayment = task("validate-payment", (order: { id: number }) => {
|
|
142
|
+
return { payment: "valid" };
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const checkInventory = task("check-inventory", (order: { id: number }) => {
|
|
146
|
+
return { stock: "available" };
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const workflow = flow<{ id: number }>("checkout")
|
|
150
|
+
.fork([
|
|
151
|
+
branch("payment", validatePayment),
|
|
152
|
+
branch("inventory", checkInventory),
|
|
153
|
+
])
|
|
154
|
+
.join("finalize", ([payment, inventory]) => {
|
|
155
|
+
return { ...payment, ...inventory };
|
|
156
|
+
})
|
|
157
|
+
.build();
|
|
158
|
+
|
|
159
|
+
const result = runWorkflow(workflow, { id: 1 });
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Delays and signals
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { flow, runDurableWorkflow, sendSignal, resumeWorkflow } from "sayiir";
|
|
166
|
+
|
|
167
|
+
const workflow = flow<number>("approval")
|
|
168
|
+
.then("submit", (id) => ({ requestId: id }))
|
|
169
|
+
.waitForSignal("approval", "manager_approval", { timeout: "48h" })
|
|
170
|
+
.then("process", (signal) => `Approved: ${signal}`)
|
|
171
|
+
.build();
|
|
172
|
+
|
|
173
|
+
// First run — parks at the signal
|
|
174
|
+
const status = runDurableWorkflow(workflow, "req-1", 42, backend);
|
|
175
|
+
// status.status === "awaiting_signal"
|
|
176
|
+
|
|
177
|
+
// Later, when the approval arrives:
|
|
178
|
+
sendSignal("req-1", "manager_approval", { approved: true }, backend);
|
|
179
|
+
const final = resumeWorkflow(workflow, "req-1", backend);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Zod validation
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { z } from "zod";
|
|
186
|
+
import { task, flow, runWorkflow } from "sayiir";
|
|
187
|
+
|
|
188
|
+
const OrderSchema = z.object({
|
|
189
|
+
id: z.string(),
|
|
190
|
+
amount: z.number().positive(),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const processOrder = task("process-order", (order) => {
|
|
194
|
+
return { status: "charged", amount: order.amount };
|
|
195
|
+
}, {
|
|
196
|
+
input: OrderSchema,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const workflow = flow("checkout").then(processOrder).build();
|
|
200
|
+
const result = runWorkflow(workflow, { id: "abc", amount: 99.99 });
|
|
201
|
+
// Zod validates input before the task runs
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Task metadata
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const processPayment = task("process-payment", async (order) => {
|
|
208
|
+
// ...
|
|
209
|
+
}, {
|
|
210
|
+
timeout: "60s",
|
|
211
|
+
retries: 3,
|
|
212
|
+
tags: ["payments", "critical"],
|
|
213
|
+
description: "Charges the customer's payment method",
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## API Reference
|
|
218
|
+
|
|
219
|
+
### Task Definition
|
|
220
|
+
|
|
221
|
+
- **`task(id, fn, opts?)`** — Create a named task. Optional: `timeout`, `retries`, `retry`, `tags`, `description`, `input`/`output` (Zod schemas).
|
|
222
|
+
|
|
223
|
+
### Flow Builder
|
|
224
|
+
|
|
225
|
+
- **`flow<TInput>(name)`** — Create a new type-safe flow builder.
|
|
226
|
+
- **`.then(fn)`** / **`.then(id, fn, opts?)`** — Append a task step. Accepts `task()` functions, plain functions, or lambdas.
|
|
227
|
+
- **`.fork(branches)`** — Start parallel branches. Takes an array of `branch()` definitions.
|
|
228
|
+
- **`.join(id, fn)`** — Merge branches with a combining function.
|
|
229
|
+
- **`.delay(id, duration)`** — Durable delay (`"30s"`, `"5m"`, `"1h"`, or milliseconds).
|
|
230
|
+
- **`.waitForSignal(id, signalName, opts?)`** — Wait for an external signal.
|
|
231
|
+
- **`.build()`** — Compile and return a `Workflow<TIn, TOut>`.
|
|
232
|
+
|
|
233
|
+
### Execution
|
|
234
|
+
|
|
235
|
+
- **`runWorkflow(workflow, input)`** — Execute in-memory. Returns the final output.
|
|
236
|
+
- **`runDurableWorkflow(workflow, instanceId, input, backend)`** — Execute with checkpointing. Returns `WorkflowStatus<TOut>`.
|
|
237
|
+
- **`resumeWorkflow(workflow, instanceId, backend)`** — Resume from last checkpoint.
|
|
238
|
+
- **`cancelWorkflow(instanceId, backend, opts?)`** — Cancel a running workflow.
|
|
239
|
+
- **`pauseWorkflow(instanceId, backend, opts?)`** — Pause a running workflow.
|
|
240
|
+
- **`unpauseWorkflow(instanceId, backend)`** — Unpause a paused workflow.
|
|
241
|
+
- **`sendSignal(instanceId, signalName, payload, backend)`** — Send an external signal.
|
|
242
|
+
|
|
243
|
+
### WorkflowStatus\<TOut\>
|
|
244
|
+
|
|
245
|
+
Discriminated union — use `status.status` with TypeScript narrowing:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
if (status.status === "completed") {
|
|
249
|
+
console.log(status.output); // TOut
|
|
250
|
+
} else if (status.status === "failed") {
|
|
251
|
+
console.log(status.error); // string
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Variants: `completed`, `in_progress`, `failed`, `cancelled`, `paused`, `waiting`, `awaiting_signal`.
|
|
256
|
+
|
|
257
|
+
### Backends
|
|
258
|
+
|
|
259
|
+
- **`new InMemoryBackend()`** — In-memory storage for development and testing.
|
|
260
|
+
- **`PostgresBackend.connect(url)`** — PostgreSQL persistence. Auto-runs migrations.
|
|
261
|
+
|
|
262
|
+
## Architecture
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
Your TypeScript code Sayiir (Rust) Storage
|
|
266
|
+
┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐
|
|
267
|
+
│ task() │───>│ Orchestration │───>│ Checkpoint │
|
|
268
|
+
│ functions │ │ Checkpointing │ │ after each │
|
|
269
|
+
│ │<───│ Crash recovery │<───│ task │
|
|
270
|
+
└──────────────┘ │ Fork/join │ └──────────────┘
|
|
271
|
+
│ Serialization │
|
|
272
|
+
└─────────────────────┘
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
TypeScript provides task implementations. Rust handles everything else: building the execution graph, running tasks in order, checkpointing results, recovering from crashes, and managing parallel branches.
|
|
276
|
+
|
|
277
|
+
## Requirements
|
|
278
|
+
|
|
279
|
+
- Node.js 18+
|
|
280
|
+
- Optional: `zod` for input/output validation
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
MIT
|
|
285
|
+
|
|
286
|
+
## Links
|
|
287
|
+
|
|
288
|
+
- [Documentation](https://docs.sayiir.dev/getting-started/nodejs/)
|
|
289
|
+
- [GitHub](https://github.com/sayiir/sayiir)
|
|
290
|
+
- [Discord](https://discord.gg/MWSzsHeg)
|
|
291
|
+
- [Roadmap](https://github.com/sayiir/sayiir/blob/main/ROADMAP.md)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duration parsing utility.
|
|
3
|
+
*
|
|
4
|
+
* Converts human-readable duration strings (via `ms` library) or numeric
|
|
5
|
+
* milliseconds to milliseconds.
|
|
6
|
+
*/
|
|
7
|
+
import type { Duration } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Parse a Duration value to milliseconds.
|
|
10
|
+
*
|
|
11
|
+
* - Numbers are returned as-is (assumed to be ms).
|
|
12
|
+
* - Strings are parsed via the `ms` library (e.g. "30s", "5m", "1h").
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseDuration(d: Duration): number;
|
|
15
|
+
//# sourceMappingURL=duration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAY3C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAOjD"}
|
package/dist/duration.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Duration parsing utility.
|
|
4
|
+
*
|
|
5
|
+
* Converts human-readable duration strings (via `ms` library) or numeric
|
|
6
|
+
* milliseconds to milliseconds.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.parseDuration = parseDuration;
|
|
10
|
+
let _ms;
|
|
11
|
+
function getMs() {
|
|
12
|
+
if (!_ms) {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
14
|
+
_ms = require("ms");
|
|
15
|
+
}
|
|
16
|
+
return _ms;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a Duration value to milliseconds.
|
|
20
|
+
*
|
|
21
|
+
* - Numbers are returned as-is (assumed to be ms).
|
|
22
|
+
* - Strings are parsed via the `ms` library (e.g. "30s", "5m", "1h").
|
|
23
|
+
*/
|
|
24
|
+
function parseDuration(d) {
|
|
25
|
+
if (typeof d === "number")
|
|
26
|
+
return d;
|
|
27
|
+
const result = getMs()(d);
|
|
28
|
+
if (result == null) {
|
|
29
|
+
throw new Error(`Invalid duration: "${d}"`);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=duration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.js","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAoBH,sCAOC;AAvBD,IAAI,GAAsD,CAAC;AAE3D,SAAS,KAAK;IACZ,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,iEAAiE;QACjE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAwC,CAAC;IAC7D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,CAAW;IACvC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow execution utilities.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrappers around the native addon, mirroring the Python executor.
|
|
5
|
+
*/
|
|
6
|
+
import type { Workflow } from "./flow.js";
|
|
7
|
+
import type { WorkflowStatus } from "./types.js";
|
|
8
|
+
import type { NapiInMemoryBackend, NapiPostgresBackend } from "./native.js";
|
|
9
|
+
/** Backend type union. */
|
|
10
|
+
export type Backend = InMemoryBackend | PostgresBackend;
|
|
11
|
+
/** In-memory persistence backend for testing and development. */
|
|
12
|
+
export declare class InMemoryBackend {
|
|
13
|
+
/** @internal */
|
|
14
|
+
readonly _inner: NapiInMemoryBackend;
|
|
15
|
+
constructor();
|
|
16
|
+
}
|
|
17
|
+
/** PostgreSQL persistence backend for durable production workflows. */
|
|
18
|
+
export declare class PostgresBackend {
|
|
19
|
+
/** @internal */
|
|
20
|
+
readonly _inner: NapiPostgresBackend;
|
|
21
|
+
private constructor();
|
|
22
|
+
static connect(url: string): PostgresBackend;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run a workflow to completion (no persistence).
|
|
26
|
+
*
|
|
27
|
+
* Returns the workflow output directly.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runWorkflow<TIn, TOut>(workflow: Workflow<TIn, TOut>, input: TIn): TOut;
|
|
30
|
+
/**
|
|
31
|
+
* Run a workflow with checkpointing and durability.
|
|
32
|
+
*
|
|
33
|
+
* Returns a WorkflowStatus indicating the outcome.
|
|
34
|
+
*/
|
|
35
|
+
export declare function runDurableWorkflow<TIn, TOut>(workflow: Workflow<TIn, TOut>, instanceId: string, input: TIn, backend: Backend): WorkflowStatus<TOut>;
|
|
36
|
+
/** Resume a workflow from a saved checkpoint. */
|
|
37
|
+
export declare function resumeWorkflow<TIn, TOut>(workflow: Workflow<TIn, TOut>, instanceId: string, backend: Backend): WorkflowStatus<TOut>;
|
|
38
|
+
/** Request cancellation of a running workflow. */
|
|
39
|
+
export declare function cancelWorkflow(instanceId: string, backend: Backend, opts?: {
|
|
40
|
+
reason?: string;
|
|
41
|
+
cancelledBy?: string;
|
|
42
|
+
}): void;
|
|
43
|
+
/** Request pausing of a running workflow. */
|
|
44
|
+
export declare function pauseWorkflow(instanceId: string, backend: Backend, opts?: {
|
|
45
|
+
reason?: string;
|
|
46
|
+
pausedBy?: string;
|
|
47
|
+
}): void;
|
|
48
|
+
/** Unpause a paused workflow so it can be resumed. */
|
|
49
|
+
export declare function unpauseWorkflow(instanceId: string, backend: Backend): void;
|
|
50
|
+
/** Send an external signal to a workflow instance. */
|
|
51
|
+
export declare function sendSignal(instanceId: string, signalName: string, payload: unknown, backend: Backend): void;
|
|
52
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAwB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvE,OAAO,KAAK,EAEV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAGrB,0BAA0B;AAC1B,MAAM,MAAM,OAAO,GAAG,eAAe,GAAG,eAAe,CAAC;AAExD,iEAAiE;AACjE,qBAAa,eAAe;IAC1B,gBAAgB;IAChB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;;CAKtC;AAED,uEAAuE;AACvE,qBAAa,eAAe;IAC1B,gBAAgB;IAChB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAErC,OAAO;IAIP,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;CAI7C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,EACnC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,EAC7B,KAAK,EAAE,GAAG,GACT,IAAI,CAON;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAC1C,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,EAC7B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,GAAG,EACV,OAAO,EAAE,OAAO,GACf,cAAc,CAAC,IAAI,CAAC,CAStB;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,IAAI,EACtC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf,cAAc,CAAC,IAAI,CAAC,CAQtB;AAED,kDAAkD;AAClD,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,IAAI,CAGN;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,IAAI,CAGN;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf,IAAI,CAGN;AAED,sDAAsD;AACtD,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACf,IAAI,CAGN"}
|
package/dist/executor.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Workflow execution utilities.
|
|
4
|
+
*
|
|
5
|
+
* Thin wrappers around the native addon, mirroring the Python executor.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.PostgresBackend = exports.InMemoryBackend = void 0;
|
|
9
|
+
exports.runWorkflow = runWorkflow;
|
|
10
|
+
exports.runDurableWorkflow = runDurableWorkflow;
|
|
11
|
+
exports.resumeWorkflow = resumeWorkflow;
|
|
12
|
+
exports.cancelWorkflow = cancelWorkflow;
|
|
13
|
+
exports.pauseWorkflow = pauseWorkflow;
|
|
14
|
+
exports.unpauseWorkflow = unpauseWorkflow;
|
|
15
|
+
exports.sendSignal = sendSignal;
|
|
16
|
+
const types_js_1 = require("./types.js");
|
|
17
|
+
const native_js_1 = require("./native.js");
|
|
18
|
+
/** In-memory persistence backend for testing and development. */
|
|
19
|
+
class InMemoryBackend {
|
|
20
|
+
/** @internal */
|
|
21
|
+
_inner;
|
|
22
|
+
constructor() {
|
|
23
|
+
this._inner = new ((0, native_js_1.getNative)().NapiInMemoryBackend)();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.InMemoryBackend = InMemoryBackend;
|
|
27
|
+
/** PostgreSQL persistence backend for durable production workflows. */
|
|
28
|
+
class PostgresBackend {
|
|
29
|
+
/** @internal */
|
|
30
|
+
_inner;
|
|
31
|
+
constructor(inner) {
|
|
32
|
+
this._inner = inner;
|
|
33
|
+
}
|
|
34
|
+
static connect(url) {
|
|
35
|
+
const inner = (0, native_js_1.getNative)().NapiPostgresBackend.connect(url);
|
|
36
|
+
return new PostgresBackend(inner);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.PostgresBackend = PostgresBackend;
|
|
40
|
+
/**
|
|
41
|
+
* Run a workflow to completion (no persistence).
|
|
42
|
+
*
|
|
43
|
+
* Returns the workflow output directly.
|
|
44
|
+
*/
|
|
45
|
+
function runWorkflow(workflow, input) {
|
|
46
|
+
const engine = new ((0, native_js_1.getNative)().NapiWorkflowEngine)();
|
|
47
|
+
return engine.run(workflow._inner, input, workflow._taskRegistry);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Run a workflow with checkpointing and durability.
|
|
51
|
+
*
|
|
52
|
+
* Returns a WorkflowStatus indicating the outcome.
|
|
53
|
+
*/
|
|
54
|
+
function runDurableWorkflow(workflow, instanceId, input, backend) {
|
|
55
|
+
const engine = createDurableEngine(backend);
|
|
56
|
+
const raw = engine.run(workflow._inner, instanceId, input, workflow._taskRegistry);
|
|
57
|
+
return parseWorkflowStatus(raw);
|
|
58
|
+
}
|
|
59
|
+
/** Resume a workflow from a saved checkpoint. */
|
|
60
|
+
function resumeWorkflow(workflow, instanceId, backend) {
|
|
61
|
+
const engine = createDurableEngine(backend);
|
|
62
|
+
const raw = engine.resume(workflow._inner, instanceId, workflow._taskRegistry);
|
|
63
|
+
return parseWorkflowStatus(raw);
|
|
64
|
+
}
|
|
65
|
+
/** Request cancellation of a running workflow. */
|
|
66
|
+
function cancelWorkflow(instanceId, backend, opts) {
|
|
67
|
+
const engine = createDurableEngine(backend);
|
|
68
|
+
engine.cancel(instanceId, opts?.reason, opts?.cancelledBy);
|
|
69
|
+
}
|
|
70
|
+
/** Request pausing of a running workflow. */
|
|
71
|
+
function pauseWorkflow(instanceId, backend, opts) {
|
|
72
|
+
const engine = createDurableEngine(backend);
|
|
73
|
+
engine.pause(instanceId, opts?.reason, opts?.pausedBy);
|
|
74
|
+
}
|
|
75
|
+
/** Unpause a paused workflow so it can be resumed. */
|
|
76
|
+
function unpauseWorkflow(instanceId, backend) {
|
|
77
|
+
const engine = createDurableEngine(backend);
|
|
78
|
+
engine.unpause(instanceId);
|
|
79
|
+
}
|
|
80
|
+
/** Send an external signal to a workflow instance. */
|
|
81
|
+
function sendSignal(instanceId, signalName, payload, backend) {
|
|
82
|
+
const engine = createDurableEngine(backend);
|
|
83
|
+
engine.sendSignal(instanceId, signalName, payload);
|
|
84
|
+
}
|
|
85
|
+
// ---- Internal helpers ----
|
|
86
|
+
function createDurableEngine(backend) {
|
|
87
|
+
const native = (0, native_js_1.getNative)();
|
|
88
|
+
if (backend instanceof InMemoryBackend) {
|
|
89
|
+
return native.NapiDurableEngine.withInMemory(backend._inner);
|
|
90
|
+
}
|
|
91
|
+
if (backend instanceof PostgresBackend) {
|
|
92
|
+
return native.NapiDurableEngine.withPostgres(backend._inner);
|
|
93
|
+
}
|
|
94
|
+
throw new types_js_1.WorkflowError("backend must be InMemoryBackend or PostgresBackend");
|
|
95
|
+
}
|
|
96
|
+
function parseWorkflowStatus(raw) {
|
|
97
|
+
switch (raw.status) {
|
|
98
|
+
case "completed":
|
|
99
|
+
return {
|
|
100
|
+
status: "completed",
|
|
101
|
+
output: (raw.outputJson != null
|
|
102
|
+
? JSON.parse(raw.outputJson)
|
|
103
|
+
: undefined),
|
|
104
|
+
};
|
|
105
|
+
case "in_progress":
|
|
106
|
+
return { status: "in_progress" };
|
|
107
|
+
case "failed":
|
|
108
|
+
return { status: "failed", error: raw.error ?? "unknown error" };
|
|
109
|
+
case "cancelled":
|
|
110
|
+
return {
|
|
111
|
+
status: "cancelled",
|
|
112
|
+
reason: raw.reason,
|
|
113
|
+
cancelledBy: raw.cancelledBy,
|
|
114
|
+
};
|
|
115
|
+
case "paused":
|
|
116
|
+
return {
|
|
117
|
+
status: "paused",
|
|
118
|
+
reason: raw.reason,
|
|
119
|
+
pausedBy: raw.cancelledBy,
|
|
120
|
+
};
|
|
121
|
+
default:
|
|
122
|
+
return { status: raw.status };
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/flow.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-safe flow builder for constructing workflows.
|
|
3
|
+
*
|
|
4
|
+
* The builder tracks input/output types through the chain using generics,
|
|
5
|
+
* providing full type inference without manual annotations.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const wf = flow<number>("welcome")
|
|
9
|
+
* .then("fetch", (id) => getUser(id)) // id: number -> User
|
|
10
|
+
* .then("greet", (user) => `Hi ${user.name}`) // user: User -> string
|
|
11
|
+
* .build(); // Workflow<number, string>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import type { Duration, StepOptions, ZodLike } from "./types.js";
|
|
15
|
+
import type { TaskFn } from "./task.js";
|
|
16
|
+
import type { NapiFlowBuilder, NapiTaskMetadata, NapiWorkflow } from "./native.js";
|
|
17
|
+
/** A compiled workflow ready for execution. */
|
|
18
|
+
export declare class Workflow<TIn, TOut> {
|
|
19
|
+
/** @internal */
|
|
20
|
+
readonly _inner: NapiWorkflow;
|
|
21
|
+
/** @internal */
|
|
22
|
+
readonly _taskRegistry: Record<string, Function>;
|
|
23
|
+
constructor(inner: NapiWorkflow, taskRegistry: Record<string, Function>);
|
|
24
|
+
get workflowId(): string;
|
|
25
|
+
get definitionHash(): string;
|
|
26
|
+
}
|
|
27
|
+
/** A branch definition for fork/join. */
|
|
28
|
+
export interface BranchDef<TIn, TOut> {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly steps: readonly BranchStep[];
|
|
31
|
+
/** @internal — phantom type marker */
|
|
32
|
+
readonly _in?: TIn;
|
|
33
|
+
readonly _out?: TOut;
|
|
34
|
+
}
|
|
35
|
+
interface BranchStep {
|
|
36
|
+
taskId: string;
|
|
37
|
+
fn: Function;
|
|
38
|
+
metadata?: NapiTaskMetadata;
|
|
39
|
+
}
|
|
40
|
+
/** Infer the output types from a tuple of branch definitions. */
|
|
41
|
+
export type InferBranchOutputs<T extends readonly BranchDef<any, any>[]> = {
|
|
42
|
+
[K in keyof T]: T[K] extends BranchDef<any, infer O> ? O : never;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Create a branch for use with `.fork()`.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* flow<Order>("process")
|
|
49
|
+
* .then(chargePayment)
|
|
50
|
+
* .fork([
|
|
51
|
+
* branch("email", sendConfirmation),
|
|
52
|
+
* branch("ship", shipOrder),
|
|
53
|
+
* ])
|
|
54
|
+
* .join("finalize", ([email, ship]) => ({ email, ship }))
|
|
55
|
+
* .build();
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function branch<TIn, TOut>(name: string, fn: TaskFn<TIn, TOut> | ((input: TIn) => TOut | Promise<TOut>)): BranchDef<TIn, Awaited<TOut>>;
|
|
59
|
+
/** Type-safe workflow builder. */
|
|
60
|
+
export declare class Flow<TInput, TLast = TInput> {
|
|
61
|
+
/** @internal */
|
|
62
|
+
readonly _builder: NapiFlowBuilder;
|
|
63
|
+
/** @internal */
|
|
64
|
+
readonly _taskRegistry: Record<string, Function>;
|
|
65
|
+
/** @internal */
|
|
66
|
+
_lambdaCounter: number;
|
|
67
|
+
constructor(name: string);
|
|
68
|
+
/**
|
|
69
|
+
* Add a sequential task step.
|
|
70
|
+
*
|
|
71
|
+
* Accepts either a `TaskFn` (created by `task()`) or an inline function with an id.
|
|
72
|
+
*/
|
|
73
|
+
then<TOut>(fn: TaskFn<TLast, TOut>): Flow<TInput, Awaited<TOut>>;
|
|
74
|
+
then<TOut>(id: string, fn: ((input: TLast) => TOut | Promise<TOut>) | TaskFn<TLast, TOut>, opts?: StepOptions): Flow<TInput, Awaited<TOut>>;
|
|
75
|
+
/**
|
|
76
|
+
* Start a fork for parallel execution.
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* .fork([
|
|
80
|
+
* branch("email", sendEmail),
|
|
81
|
+
* branch("sms", sendSms),
|
|
82
|
+
* ])
|
|
83
|
+
* .join("merge", ([email, sms]) => ({ email, sms }))
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
fork<TBranches extends readonly BranchDef<TLast, any>[]>(branches: [...TBranches]): ForkBuilder<TInput, TLast, TBranches>;
|
|
87
|
+
/**
|
|
88
|
+
* Add a durable delay. No workers are held during the delay.
|
|
89
|
+
*
|
|
90
|
+
* Duration can be a number (ms) or a string like "30s", "5m", "1h".
|
|
91
|
+
*/
|
|
92
|
+
delay(id: string, duration: Duration): Flow<TInput, TLast>;
|
|
93
|
+
/**
|
|
94
|
+
* Wait for an external signal before continuing.
|
|
95
|
+
*
|
|
96
|
+
* The workflow parks and releases the worker until the signal arrives.
|
|
97
|
+
*/
|
|
98
|
+
waitForSignal<TSignal = unknown>(id: string, signalName: string, opts?: {
|
|
99
|
+
timeout?: Duration;
|
|
100
|
+
schema?: ZodLike<TSignal>;
|
|
101
|
+
}): Flow<TInput, TSignal>;
|
|
102
|
+
/** Build the workflow definition. */
|
|
103
|
+
build(): Workflow<TInput, TLast>;
|
|
104
|
+
}
|
|
105
|
+
/** Builder for fork/join parallel branches. */
|
|
106
|
+
export declare class ForkBuilder<TInput, TLast, TBranches extends readonly BranchDef<TLast, any>[]> {
|
|
107
|
+
private readonly flow;
|
|
108
|
+
private readonly branches;
|
|
109
|
+
constructor(flow: Flow<TInput, TLast>, branches: TBranches);
|
|
110
|
+
/**
|
|
111
|
+
* Join branches with a combining function.
|
|
112
|
+
*
|
|
113
|
+
* The join function receives a tuple of branch outputs.
|
|
114
|
+
*/
|
|
115
|
+
join<TOut>(id: string, fn: (branches: InferBranchOutputs<TBranches>) => TOut | Promise<TOut>): Flow<TInput, Awaited<TOut>>;
|
|
116
|
+
}
|
|
117
|
+
/** Factory function to create a new flow. */
|
|
118
|
+
export declare function flow<TInput>(name: string): Flow<TInput>;
|
|
119
|
+
export {};
|
|
120
|
+
//# sourceMappingURL=flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../src/flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAEV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACb,MAAM,aAAa,CAAC;AAGrB,+CAA+C;AAC/C,qBAAa,QAAQ,CAAC,GAAG,EAAE,IAAI;IAC7B,gBAAgB;IAChB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,gBAAgB;IAChB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAErC,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC;IAKvE,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;CACF;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS,CAAC,GAAG,EAAE,IAAI;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,sCAAsC;IACtC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;CACtB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,QAAQ,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAED,iEAAiE;AACjE,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI;KACxE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CACjE,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,IAAI,EAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAC7D,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAQ/B;AAED,kCAAkC;AAClC,qBAAa,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM;IACtC,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,gBAAgB;IAChB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAM;IACtD,gBAAgB;IAChB,cAAc,SAAK;gBAEP,IAAI,EAAE,MAAM;IAIxB;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI,EACP,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,EAClE,IAAI,CAAC,EAAE,WAAW,GACjB,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IA6C9B;;;;;;;;;;OAUG;IACH,IAAI,CAAC,SAAS,SAAS,SAAS,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EACrD,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,GACvB,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;IAIxC;;;;OAIG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;IAM1D;;;;OAIG;IACH,aAAa,CAAC,OAAO,GAAG,OAAO,EAC7B,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,GACvD,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAOxB,qCAAqC;IACrC,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;CAIjC;AAED,+CAA+C;AAC/C,qBAAa,WAAW,CACtB,MAAM,EACN,KAAK,EACL,SAAS,SAAS,SAAS,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;IAElD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAY;gBAEzB,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS;IAK1D;;;;OAIG;IACH,IAAI,CAAC,IAAI,EACP,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CACF,QAAQ,EAAE,kBAAkB,CAAC,SAAS,CAAC,KACpC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACxB,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAsB/B;AAED,6CAA6C;AAC7C,wBAAgB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAEvD"}
|