openworkflow 0.5.0 → 0.6.1

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 (115) hide show
  1. package/README.md +41 -346
  2. package/dist/backend.js +0 -1
  3. package/dist/bin/openworkflow.js +0 -1
  4. package/dist/client.js +0 -1
  5. package/dist/core/duration.js +0 -1
  6. package/dist/core/error.js +0 -1
  7. package/dist/core/json.js +0 -1
  8. package/dist/core/result.js +0 -1
  9. package/dist/core/retry.js +0 -1
  10. package/dist/core/schema.js +0 -1
  11. package/dist/core/step.js +0 -1
  12. package/dist/core/workflow.js +0 -1
  13. package/dist/execution.js +0 -1
  14. package/dist/index.js +0 -1
  15. package/dist/internal.d.ts +3 -5
  16. package/dist/internal.d.ts.map +1 -1
  17. package/dist/internal.js +0 -4
  18. package/dist/{pg → postgres}/backend.d.ts +3 -1
  19. package/dist/postgres/backend.d.ts.map +1 -0
  20. package/dist/{pg → postgres}/backend.js +5 -5
  21. package/dist/postgres/postgres.d.ts.map +1 -0
  22. package/dist/{backend-postgres → postgres}/postgres.js +0 -1
  23. package/dist/postgres/scripts/db-migrate.d.ts.map +1 -0
  24. package/dist/{pg → postgres}/scripts/db-migrate.js +0 -1
  25. package/dist/postgres/scripts/db-reset.d.ts.map +1 -0
  26. package/dist/{pg → postgres}/scripts/db-reset.js +0 -1
  27. package/dist/{pg → postgres}/scripts/squawk.d.ts.map +1 -1
  28. package/dist/{pg → postgres}/scripts/squawk.js +0 -1
  29. package/dist/postgres.d.ts +2 -0
  30. package/dist/postgres.d.ts.map +1 -0
  31. package/dist/postgres.js +1 -0
  32. package/dist/registry.js +0 -1
  33. package/dist/sqlite/backend.d.ts +3 -1
  34. package/dist/sqlite/backend.d.ts.map +1 -1
  35. package/dist/sqlite/backend.js +5 -5
  36. package/dist/sqlite/sqlite.js +0 -1
  37. package/dist/sqlite.d.ts +2 -0
  38. package/dist/sqlite.d.ts.map +1 -0
  39. package/dist/sqlite.js +1 -0
  40. package/dist/worker.js +0 -1
  41. package/dist/workflow.js +0 -1
  42. package/package.json +24 -6
  43. package/dist/backend-postgres/index.d.ts +0 -44
  44. package/dist/backend-postgres/index.d.ts.map +0 -1
  45. package/dist/backend-postgres/index.js +0 -535
  46. package/dist/backend-postgres/index.js.map +0 -1
  47. package/dist/backend-postgres/postgres.d.ts.map +0 -1
  48. package/dist/backend-postgres/postgres.js.map +0 -1
  49. package/dist/backend-sqlite/index.d.ts +0 -42
  50. package/dist/backend-sqlite/index.d.ts.map +0 -1
  51. package/dist/backend-sqlite/index.js +0 -655
  52. package/dist/backend-sqlite/index.js.map +0 -1
  53. package/dist/backend-sqlite/sqlite.d.ts +0 -61
  54. package/dist/backend-sqlite/sqlite.d.ts.map +0 -1
  55. package/dist/backend-sqlite/sqlite.js +0 -247
  56. package/dist/backend-sqlite/sqlite.js.map +0 -1
  57. package/dist/backend.js.map +0 -1
  58. package/dist/bin/openworkflow.js.map +0 -1
  59. package/dist/client.js.map +0 -1
  60. package/dist/config.d.ts +0 -34
  61. package/dist/config.d.ts.map +0 -1
  62. package/dist/config.js +0 -49
  63. package/dist/config.js.map +0 -1
  64. package/dist/core/duration.js.map +0 -1
  65. package/dist/core/error.js.map +0 -1
  66. package/dist/core/json.js.map +0 -1
  67. package/dist/core/result.js.map +0 -1
  68. package/dist/core/retry.js.map +0 -1
  69. package/dist/core/schema.js.map +0 -1
  70. package/dist/core/step.js.map +0 -1
  71. package/dist/core/workflow.js.map +0 -1
  72. package/dist/execution.js.map +0 -1
  73. package/dist/index.js.map +0 -1
  74. package/dist/internal.js.map +0 -1
  75. package/dist/pg/backend.d.ts.map +0 -1
  76. package/dist/pg/backend.js.map +0 -1
  77. package/dist/pg/index.d.ts +0 -3
  78. package/dist/pg/index.d.ts.map +0 -1
  79. package/dist/pg/index.js +0 -3
  80. package/dist/pg/index.js.map +0 -1
  81. package/dist/pg/postgres.d.ts +0 -42
  82. package/dist/pg/postgres.d.ts.map +0 -1
  83. package/dist/pg/postgres.js +0 -234
  84. package/dist/pg/postgres.js.map +0 -1
  85. package/dist/pg/scripts/db-migrate.d.ts.map +0 -1
  86. package/dist/pg/scripts/db-migrate.js.map +0 -1
  87. package/dist/pg/scripts/db-reset.d.ts.map +0 -1
  88. package/dist/pg/scripts/db-reset.js.map +0 -1
  89. package/dist/pg/scripts/squawk.js.map +0 -1
  90. package/dist/pg/vitest.global-setup.d.ts +0 -3
  91. package/dist/pg/vitest.global-setup.d.ts.map +0 -1
  92. package/dist/pg/vitest.global-setup.js +0 -8
  93. package/dist/pg/vitest.global-setup.js.map +0 -1
  94. package/dist/registry.js.map +0 -1
  95. package/dist/sqlite/backend.js.map +0 -1
  96. package/dist/sqlite/index.d.ts +0 -3
  97. package/dist/sqlite/index.d.ts.map +0 -1
  98. package/dist/sqlite/index.js +0 -3
  99. package/dist/sqlite/index.js.map +0 -1
  100. package/dist/sqlite/sqlite.js.map +0 -1
  101. package/dist/testing/backend.testsuite.d.ts +0 -20
  102. package/dist/testing/backend.testsuite.d.ts.map +0 -1
  103. package/dist/testing/backend.testsuite.js +0 -1091
  104. package/dist/testing/backend.testsuite.js.map +0 -1
  105. package/dist/testing/index.d.ts +0 -2
  106. package/dist/testing/index.d.ts.map +0 -1
  107. package/dist/testing/index.js +0 -2
  108. package/dist/testing/index.js.map +0 -1
  109. package/dist/tsconfig.tsbuildinfo +0 -1
  110. package/dist/worker.js.map +0 -1
  111. package/dist/workflow.js.map +0 -1
  112. /package/dist/{backend-postgres → postgres}/postgres.d.ts +0 -0
  113. /package/dist/{pg → postgres}/scripts/db-migrate.d.ts +0 -0
  114. /package/dist/{pg → postgres}/scripts/db-reset.d.ts +0 -0
  115. /package/dist/{pg → postgres}/scripts/squawk.d.ts +0 -0
package/README.md CHANGED
@@ -8,16 +8,12 @@ OpenWorkflow is a TypeScript framework for building durable, resumable workflows
8
8
  that can pause for seconds or months, survive crashes and deploys, and resume
9
9
  exactly where they left off - all without extra servers to manage.
10
10
 
11
- Define a workflow in a few lines:
11
+ ![OpenWorkflow Dashboard](./packages/docs/assets/dashboard.png)
12
12
 
13
13
  ```ts
14
- import { BackendSqlite } from "@openworkflow/backend-sqlite";
15
- import { OpenWorkflow } from "openworkflow";
14
+ import { defineWorkflow } from "openworkflow";
16
15
 
17
- const backend = BackendSqlite.connect("openworkflow/backend.db");
18
- const ow = new OpenWorkflow({ backend });
19
-
20
- const sendWelcomeEmail = ow.defineWorkflow(
16
+ export const sendWelcomeEmail = defineWorkflow(
21
17
  { name: "send-welcome-email" },
22
18
  async ({ input, step }) => {
23
19
  const user = await step.run({ name: "fetch-user" }, async () => {
@@ -43,363 +39,62 @@ const sendWelcomeEmail = ow.defineWorkflow(
43
39
  );
44
40
  ```
45
41
 
46
- > OpenWorkflow is in active development and moving quickly. Check out the
47
- > [Roadmap](#roadmap) for what’s coming next.
48
-
49
42
  ## Quick Start
50
43
 
51
- Prerequisites:
52
-
53
- - Node.js
54
- - PostgreSQL (and/or SQLite)
55
-
56
- ### 1. Install
44
+ **Prerequisites:** Node.js & PostgreSQL (or SQLite)
57
45
 
58
- Install and set up OpenWorkflow with:
46
+ ### Install
59
47
 
60
48
  ```bash
61
49
  npx @openworkflow/cli init
62
50
  ```
63
51
 
64
- The CLI will prompt for your backend, installs dependencies, and generates:
65
- `openworkflow.config.ts`, `openworkflow/hello-world.ts`, `.env`, `.gitignore`,
66
- and a `worker` script.
67
-
68
- ### 2. Start a worker
69
-
70
- ```bash
71
- npm run worker
72
- # or
73
- npx @openworkflow/cli worker start
74
- ```
75
-
76
- This runs the worker using `openworkflow.config.ts` and auto-loads workflows
77
- from the configured directories (default: `openworkflow/`).
78
-
79
- ### 3. Run workflows from your app
80
-
81
- Edit the generated workflow file and run it from your application code using the
82
- OpenWorkflow client APIs (see examples below).
83
-
84
- That's it. Your workflow is now durable, resumable, and fault-tolerant.
85
-
86
- ## Core Concepts
87
-
88
- ### Workflows
89
-
90
- Workflows are durable functions. They can contain multiple steps, make external
91
- API calls, query databases, and perform complex logic. If a workflow is
92
- interrupted (crash, deploy, server restart), it resumes from its last completed
93
- step.
94
-
95
- ```ts
96
- const workflow = ow.defineWorkflow(
97
- { name: "my-workflow" },
98
- async ({ input, step }) => {
99
- // Your workflow logic here
100
- return result;
101
- },
102
- );
103
- ```
104
-
105
- ### Steps
106
-
107
- Steps are the building blocks of workflows. Each step is executed exactly once
108
- and its result is memoized. Steps let you break workflows into checkpoints.
109
-
110
- ```ts
111
- const result = await step.run({ name: "step-name" }, async () => {
112
- // This function runs once. If the workflow restarts,
113
- // this returns the cached result instead of re-running.
114
- return await someAsyncWork();
115
- });
116
- ```
117
-
118
- **Why steps matter**: Imagine a workflow that charges a credit card, then sends
119
- an email. Without steps, if your server crashes after charging the card, the
120
- workflow would retry from the beginning and charge the customer twice. With
121
- steps, the charge is memoized. The retry skips it and goes straight to sending
122
- the email.
123
-
124
- ### Workers
125
-
126
- Workers are long-running processes that poll your database for pending workflows
127
- and execute them. Run workers via the CLI so workflow discovery stays in sync
128
- with your `openworkflow.config.ts`:
129
-
130
- ```bash
131
- npm run worker
132
- # or
133
- npx @openworkflow/cli worker start
134
- ```
135
-
136
- Or, for more control, you can write your own workers:
137
-
138
- ```ts
139
- import { BackendSqlite } from "@openworkflow/backend-sqlite";
140
- import { OpenWorkflow } from "openworkflow";
141
-
142
- const backend = BackendSqlite.connect("openworkflow/backend.db");
143
- const ow = new OpenWorkflow({ backend });
144
-
145
- const worker = ow.newWorker({ concurrency: 20 });
146
- await worker.start();
147
-
148
- // & to shut down...
149
- await worker.stop(); // waits for in-flight workflows to complete
150
- ```
151
-
152
- Workers are stateless. They can be started, stopped, and deployed independently.
153
- Your database is the source of truth.
154
-
155
- ### How it Works
156
-
157
- 1. **Your app starts a workflow**: A row is inserted into the `workflow_runs`
158
- table with status `pending`.
159
- 2. **A worker picks it up**: The worker polls the database, claims the workflow,
160
- and sets its status to `running`.
161
- 3. **The worker executes steps**: Each step is recorded in the `step_attempts`
162
- table. If a step succeeds, its result is cached.
163
- 4. **The workflow completes**: The worker updates the `workflow_run` status to
164
- `completed` or `failed`.
165
- 5. **If the worker crashes**: The workflow becomes visible to other workers via
166
- a heartbeat timeout. Another worker picks it up, loads the cached step
167
- results, and resumes from the next step.
168
-
169
- ## Advanced Patterns
170
-
171
- ### Parallel Steps
172
-
173
- Run multiple steps concurrently using `Promise.all`:
174
-
175
- ```ts
176
- const [user, subscription, settings] = await Promise.all([
177
- step.run({ name: "fetch-user" }, async () => {
178
- await db.users.findOne({ id: input.userId });
179
- }),
180
- step.run({ name: "fetch-subscription" }, async () => {
181
- await stripe.subscriptions.retrieve(input.subId);
182
- }),
183
- step.run({ name: "fetch-settings" }, async () => {
184
- await db.settings.findOne({ userId: input.userId });
185
- }),
186
- ]);
187
- ```
188
-
189
- Each step is still memoized individually. If the workflow crashes mid-execution,
190
- completed steps return instantly on resume.
191
-
192
- ### Automatic Retries
193
-
194
- Steps can retry automatically with exponential backoff:
195
-
196
- ```ts
197
- const data = await step.run({ name: "fetch-external-api" }, async () => {
198
- // If this throws, the step retries automatically
199
- return await externalAPI.getData();
200
- });
201
- ```
202
-
203
- Configure retry behavior at the workflow or step level (coming soon) or handle
204
- errors explicitly in your step functions.
205
-
206
- ### Sleeping (Pausing) Workflows
207
-
208
- You can pause a workflow until a future time and, because sleeping releases the
209
- worker slot, you can pause thousands of workflows without tying up compute:
210
-
211
- ```ts
212
- // Pause for 1 hour (durable, non-blocking)
213
- await step.sleep("wait-one-hour", "1h");
214
- ```
215
-
216
- The sleep step is memoized after it completes. If the workflow is replayed again
217
- (e.g. due to a later retry) the completed sleep is not re-applied.
218
-
219
- #### Duration Formats
220
-
221
- Durations accept a number followed by a unit:
222
-
223
- | Unit | Aliases | Examples |
224
- | ------------ | --------------------- | ---------------- |
225
- | milliseconds | `ms`, `msec`, `msecs` | `100ms`, `1.5ms` |
226
- | seconds | `s`, `sec`, `secs` | `5s`, `0.25s` |
227
- | minutes | `m`, `min`, `mins` | `2m`, `1.5m` |
228
- | hours | `h`, `hr`, `hrs` | `1h`, `0.25h` |
229
- | days | `d`, `day(s)` | `1d`, `0.5d` |
230
- | weeks | `w`, `week(s)` | `1w`, `2w` |
231
- | months | `mo`, `month(s)` | `1mo`, `2mo` |
232
- | years | `y`, `yr`, `yrs` | `1y`, `2yr` |
233
-
234
- See more examples of accepted duration formats and aliases in the
235
- [tests](https://github.com/openworkflowdev/openworkflow/blob/main/packages/openworkflow/core/duration.test.ts).
236
-
237
- ### Type Safety
238
-
239
- Workflows are fully typed. Define input and output types for compile-time
240
- safety:
241
-
242
- ```ts
243
- interface ProcessOrderInput {
244
- orderId: string;
245
- userId: string;
246
- }
247
-
248
- interface ProcessOrderOutput {
249
- paymentId: string;
250
- shipmentId: string;
251
- }
252
-
253
- const processOrder = ow.defineWorkflow<ProcessOrderInput, ProcessOrderOutput>(
254
- { name: "process-order" },
255
- async ({ input, step }) => {
256
- // input is typed as ProcessOrderInput
257
- // return type must match ProcessOrderOutput
258
- return { paymentId: "...", shipmentId: "..." };
259
- },
260
- );
261
- ```
262
-
263
- ### Waiting for Results
264
-
265
- You can wait for a workflow to complete and get its result:
266
-
267
- ```ts
268
- const run = await myWorkflow.run({ data: "..." });
269
-
270
- // Wait for the workflow to finish (polls the database)
271
- const result = await run.result();
272
- ```
273
-
274
- ### Canceling Workflows
275
-
276
- You can cancel a workflow that is pending, running, or sleeping to prevent a
277
- workflow from continuing on to the next step:
278
-
279
- ```ts
280
- const handle = await myWorkflow.run({ data: "..." });
281
-
282
- // Cancel the workflow
283
- await handle.cancel();
284
- ```
285
-
286
- ### Workflow Versioning
287
-
288
- When you need to change workflow logic, use versioning for backwards
289
- compatibility.
290
-
291
- Define a workflow with an optional version:
292
-
293
- ```ts
294
- const workflow = ow.defineWorkflow(
295
- { name: "my-workflow", version: "v2" },
296
- async ({ input, step, version }) => {
297
- if (version === "v2") {
298
- // v2 runs go here
299
- await step.run({ name: "new-step" }, async () => {
300
- // legacy logic
301
- });
302
- } else {
303
- // v1 runs go here
304
- await step.run({ name: "old-step" }, async () => {
305
- // ...
306
- });
307
- }
308
- },
309
- );
310
- ```
311
-
312
- ### Validating Workflow Inputs
313
-
314
- You can require `.run()` callers to provide specific inputs by supplying a
315
- `schema` when defining the workflow. The schema is evaluated before the run is
316
- enqueued, so invalid requests fail immediately.
317
-
318
- ```ts
319
- import { z } from "zod";
320
-
321
- const summarizeDoc = ow.defineWorkflow(
322
- {
323
- name: "summarize",
324
- schema: z.object({
325
- docUrl: z.string().url(),
326
- }),
327
- },
328
- async ({ input, step }) => {
329
- // `input` has type { docUrl: string }
330
- },
331
- );
332
-
333
- // Throws before enqueueing the workflow because the input isn't a URL
334
- await summarizeDoc.run({ docUrl: "not-a-url" });
335
- ```
52
+ The CLI will guide you through setup and generate everything you need to get
53
+ started.
336
54
 
337
- Any validator function works as long as it throws on invalid data (great for
338
- custom logic or lightweight checks). Libraries such as Zod, ArkType, Valibot,
339
- and Yup.
55
+ For more details, check out our [docs](https://openworkflow.dev/docs).
340
56
 
341
- ## Production Checklist
57
+ ## Features
342
58
 
343
- - **Database**: Use a production-ready Postgres instance
344
- - **Workers**: Run at lease one worker process
345
- - **Concurrency**: Start with `concurrency: 10` per worker and tune based on
346
- your workload
347
- - **Monitoring**: Log worker activity and set up alerts for failed workflows
348
- - **Graceful Shutdown**: Handle `SIGTERM` to ensure clean deploys:
349
- ```ts
350
- process.on("SIGTERM", async () => {
351
- await worker.stop();
352
- process.exit(0);
353
- });
354
- ```
355
- - **Namespaces** (optional): Use `namespaceId` in your backend configuration to
356
- isolate workflows per environment:
357
- ```ts
358
- const backend = await BackendPostgres.connect(postgresUrl, {
359
- namespaceId: "production",
360
- });
361
- ```
59
+ - **Durable** - Workflows survive crashes and deploys
60
+ - **Resumable** - Pick up exactly where you left off
61
+ - **Type-safe** - Full TypeScript support
62
+ - ✅ **Step memoization** - Never repeat completed work
63
+ - **Automatic retries** - Built-in exponential backoff
64
+ - **Long pauses** - Sleep for seconds or months
65
+ - ✅ **Parallel execution** - Run steps concurrently
66
+ - **No extra servers** - Uses your existing database
67
+ - ✅ **Dashboard included** - Monitor and debug workflows
68
+ - ✅ **Production ready** - PostgreSQL and SQLite support
362
69
 
363
- ## What's Next
70
+ ## Documentation
364
71
 
365
- - Read [ARCHITECTURE.md](./ARCHITECTURE.md) for a deep dive into how
366
- OpenWorkflow works
367
- - Check [examples/](./examples) for working examples
368
- - Star the repo and follow development on
369
- [GitHub](https://github.com/openworkflowdev/openworkflow)
72
+ - [Documentation](https://openworkflow.dev/docs)
73
+ - [Quick Start Guide](https://openworkflow.dev/docs/quickstart)
74
+ - [Core Concepts](https://openworkflow.dev/docs/core-concepts)
75
+ - [Advanced Patterns](https://openworkflow.dev/docs/advanced-patterns)
76
+ - [Production Checklist](https://openworkflow.dev/docs/production)
370
77
 
371
- ## Roadmap
78
+ ## Architecture
372
79
 
373
- **Live in current `npm` release:**
80
+ Read
81
+ [ARCHITECTURE.md](https://github.com/openworkflowdev/openworkflow/blob/main/ARCHITECTURE.md)
82
+ for a deep dive into how OpenWorkflow works under the hood.
374
83
 
375
- - ✅ PostgreSQL and SQLite backends
376
- - ✅ CLI (`npx @openworkflow/cli`)
377
- - ✅ Worker with concurrency control
378
- - ✅ Step memoization & retries
379
- - ✅ Graceful shutdown
380
- - ✅ Parallel step execution
381
- - ✅ Sleeping (pausing) workflows
382
- - ✅ Workflow versioning
383
- - ✅ Workflow cancelation
84
+ ## Examples
384
85
 
385
- **Coming Soon:**
86
+ Check out
87
+ [examples/](https://github.com/openworkflowdev/openworkflow/tree/main/examples)
88
+ for working examples.
386
89
 
387
- > These releases don't yet include a dashboard UI. For now, you can inspect
388
- > workflow and step state directly in PostgreSQL or SQLite (workflow_runs and
389
- > step_attempts tables). A dashboard is planned for an upcoming release to make
390
- > debugging and monitoring much easier.
90
+ ## Contributing
391
91
 
392
- - Dashboard UI
393
- - Idempotency keys
394
- - Rollback / compensation functions
395
- - Configurable retry policies
396
- - Signals for external events
397
- - Native OpenTelemetry integration
398
- - Additional backends (Redis)
399
- - Additional languages (Go, Python)
92
+ We welcome contributions! Please read
93
+ [CONTRIBUTING.md](https://github.com/openworkflowdev/openworkflow/blob/main/CONTRIBUTING.md)
94
+ before submitting a pull request.
400
95
 
401
- ## Bugs & feature requests
96
+ ## Community
402
97
 
403
- Found a bug or have a feature request? Please open an issue on GitHub so we can
404
- track and prioritize it:
405
- https://github.com/openworkflowdev/openworkflow/issues/new
98
+ - [GitHub Issues](https://github.com/openworkflowdev/openworkflow/issues) -
99
+ Report bugs and request features
100
+ - [Roadmap](https://openworkflow.dev/docs/roadmap) - See what's coming next
package/dist/backend.js CHANGED
@@ -1,2 +1 @@
1
1
  export const DEFAULT_NAMESPACE_ID = "default";
2
- //# sourceMappingURL=backend.js.map
@@ -41,4 +41,3 @@ const result = spawnSync(
41
41
  });
42
42
  // exit with the same status code as the CLI
43
43
  process.exit(result.status ?? 0);
44
- //# sourceMappingURL=openworkflow.js.map
package/dist/client.js CHANGED
@@ -178,4 +178,3 @@ export class WorkflowRunHandle {
178
178
  });
179
179
  }
180
180
  }
181
- //# sourceMappingURL=client.js.map
@@ -61,4 +61,3 @@ export function parseDuration(str) {
61
61
  }
62
62
  return ok(numValue * multiplier);
63
63
  }
64
- //# sourceMappingURL=duration.js.map
@@ -15,4 +15,3 @@ export function serializeError(error) {
15
15
  message: String(error),
16
16
  };
17
17
  }
18
- //# sourceMappingURL=error.js.map
package/dist/core/json.js CHANGED
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=json.js.map
@@ -14,4 +14,3 @@ export function ok(value) {
14
14
  export function err(error) {
15
15
  return { ok: false, error };
16
16
  }
17
- //# sourceMappingURL=result.js.map
@@ -4,4 +4,3 @@ export const DEFAULT_RETRY_POLICY = {
4
4
  maximumIntervalMs: 100 * 1000, // 100s
5
5
  maximumAttempts: Infinity, // unlimited
6
6
  };
7
- //# sourceMappingURL=retry.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=schema.js.map
package/dist/core/step.js CHANGED
@@ -63,4 +63,3 @@ export function createSleepContext(resumeAt) {
63
63
  resumeAt: resumeAt.toISOString(),
64
64
  };
65
65
  }
66
- //# sourceMappingURL=step.js.map
@@ -32,4 +32,3 @@ export async function validateInput(schema, input) {
32
32
  value: resolved.value,
33
33
  };
34
34
  }
35
- //# sourceMappingURL=workflow.js.map
package/dist/execution.js CHANGED
@@ -185,4 +185,3 @@ export async function executeWorkflow(params) {
185
185
  });
186
186
  }
187
187
  }
188
- //# sourceMappingURL=execution.js.map
package/dist/index.js CHANGED
@@ -2,4 +2,3 @@ export { OpenWorkflow } from "./client.js";
2
2
  export { Worker } from "./worker.js";
3
3
  export { defineWorkflowSpec, defineWorkflow, declareWorkflow, // eslint-disable-line @typescript-eslint/no-deprecated
4
4
  } from "./workflow.js";
5
- //# sourceMappingURL=index.js.map
@@ -1,8 +1,6 @@
1
1
  export type { Workflow } from "./workflow.js";
2
2
  export { isWorkflow } from "./workflow.js";
3
- export * from "./backend.js";
4
- export type { JsonValue } from "./core/json.js";
5
- export type { WorkflowRun } from "./core/workflow.js";
6
- export type { StepAttempt } from "./core/step.js";
7
- export { DEFAULT_RETRY_POLICY } from "./core/retry.js";
3
+ export type { Backend, PaginationOptions, PaginatedResponse, } from "./backend.js";
4
+ export type { WorkflowRun, WorkflowRunStatus } from "./core/workflow.js";
5
+ export type { StepAttempt, StepAttemptStatus, StepKind } from "./core/step.js";
8
6
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../internal.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,cAAc,cAAc,CAAC;AAG7B,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../internal.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/internal.js CHANGED
@@ -1,5 +1 @@
1
1
  export { isWorkflow } from "./workflow.js";
2
- // backend
3
- export * from "./backend.js";
4
- export { DEFAULT_RETRY_POLICY } from "./core/retry.js";
5
- //# sourceMappingURL=internal.js.map
@@ -1,4 +1,6 @@
1
- import { Backend, CancelWorkflowRunParams, ClaimWorkflowRunParams, CreateStepAttemptParams, CreateWorkflowRunParams, GetStepAttemptParams, GetWorkflowRunParams, ExtendWorkflowRunLeaseParams, ListStepAttemptsParams, ListWorkflowRunsParams, PaginatedResponse, FailStepAttemptParams, CompleteStepAttemptParams, FailWorkflowRunParams, CompleteWorkflowRunParams, SleepWorkflowRunParams, StepAttempt, WorkflowRun } from "openworkflow/internal";
1
+ import { Backend, CancelWorkflowRunParams, ClaimWorkflowRunParams, CreateStepAttemptParams, CreateWorkflowRunParams, GetStepAttemptParams, GetWorkflowRunParams, ExtendWorkflowRunLeaseParams, ListStepAttemptsParams, ListWorkflowRunsParams, PaginatedResponse, FailStepAttemptParams, CompleteStepAttemptParams, FailWorkflowRunParams, CompleteWorkflowRunParams, SleepWorkflowRunParams } from "../backend.js";
2
+ import { StepAttempt } from "../core/step.js";
3
+ import { WorkflowRun } from "../core/workflow.js";
2
4
  interface BackendPostgresOptions {
3
5
  namespaceId?: string;
4
6
  runMigrations?: boolean;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../postgres/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAWlD,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,OAAO;IAC7C,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO;IAKP;;;;;;;OAOG;WACU,OAAO,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,eAAe,CAAC;IAiBrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IA0CjB,cAAc,CAClB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAYxB,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IA2B1C,OAAO,CAAC,0BAA0B;IA0B5B,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAmDxB,sBAAsB,CAC1B,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,WAAW,CAAC;IAkBjB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAwBtE,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IAuBjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IAgEpE,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IA2CjB,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAoCjB,cAAc,CAClB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWxB,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IA2B1C,OAAO,CAAC,0BAA0B;IA6BlC,OAAO,CAAC,wBAAwB;IAyC1B,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IA0BjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;CAyB3E"}
@@ -1,5 +1,6 @@
1
+ import { DEFAULT_NAMESPACE_ID, } from "../backend.js";
2
+ import { DEFAULT_RETRY_POLICY } from "../core/retry.js";
1
3
  import { newPostgres, newPostgresMaxOne, migrate, DEFAULT_SCHEMA, } from "./postgres.js";
2
- import { DEFAULT_NAMESPACE_ID, DEFAULT_RETRY_POLICY, } from "openworkflow/internal";
3
4
  const DEFAULT_PAGINATION_PAGE_SIZE = 100;
4
5
  /**
5
6
  * Manages a connection to a Postgres database for workflow operations.
@@ -98,8 +99,8 @@ export class BackendPostgres {
98
99
  }
99
100
  const whereClause = this.buildListWorkflowRunsWhere(params, cursor);
100
101
  const order = before
101
- ? this.pg `ORDER BY "created_at" DESC, "id" DESC`
102
- : this.pg `ORDER BY "created_at" ASC, "id" ASC`;
102
+ ? this.pg `ORDER BY "created_at" ASC, "id" ASC`
103
+ : this.pg `ORDER BY "created_at" DESC, "id" DESC`;
103
104
  const rows = await this.pg `
104
105
  SELECT *
105
106
  FROM "openworkflow"."workflow_runs"
@@ -113,7 +114,7 @@ export class BackendPostgres {
113
114
  const { after } = params;
114
115
  const conditions = [this.pg `"namespace_id" = ${this.namespaceId}`];
115
116
  if (cursor) {
116
- const op = after ? this.pg `>` : this.pg `<`;
117
+ const op = after ? this.pg `<` : this.pg `>`;
117
118
  conditions.push(this.pg `("created_at", "id") ${op} (${cursor.createdAt}, ${cursor.id})`);
118
119
  }
119
120
  let whereClause = conditions[0];
@@ -531,4 +532,3 @@ function decodeCursor(cursor) {
531
532
  id: parsed.id,
532
533
  };
533
534
  }
534
- //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../postgres/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,eAAO,MAAM,oBAAoB,2DACyB,CAAC;AAO3D,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAE7C,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,oBAEjE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,oBAEvE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA+JnD;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAQzD;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAE5D"}
@@ -231,4 +231,3 @@ async function getCurrentMigrationVersion(pg, schema) {
231
231
  const currentVersionRes = await pg.unsafe(`SELECT MAX("version") AS "version" FROM "${schema}"."openworkflow_migrations";`);
232
232
  return currentVersionRes[0]?.version ?? -1;
233
233
  }
234
- //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate.d.ts","sourceRoot":"","sources":["../../../postgres/scripts/db-migrate.ts"],"names":[],"mappings":""}
@@ -2,4 +2,3 @@ import { DEFAULT_POSTGRES_URL, DEFAULT_SCHEMA, newPostgresMaxOne, migrate, } fro
2
2
  const pg = newPostgresMaxOne(DEFAULT_POSTGRES_URL);
3
3
  await migrate(pg, DEFAULT_SCHEMA);
4
4
  await pg.end();
5
- //# sourceMappingURL=db-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-reset.d.ts","sourceRoot":"","sources":["../../../postgres/scripts/db-reset.ts"],"names":[],"mappings":""}
@@ -3,4 +3,3 @@ const pg = newPostgresMaxOne(DEFAULT_POSTGRES_URL);
3
3
  await dropSchema(pg, DEFAULT_SCHEMA);
4
4
  await migrate(pg, DEFAULT_SCHEMA);
5
5
  await pg.end();
6
- //# sourceMappingURL=db-reset.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"squawk.d.ts","sourceRoot":"","sources":["../../../pg/scripts/squawk.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"squawk.d.ts","sourceRoot":"","sources":["../../../postgres/scripts/squawk.ts"],"names":[],"mappings":""}
@@ -14,4 +14,3 @@ finally {
14
14
  unlinkSync("squawk.sql");
15
15
  console.log("");
16
16
  }
17
- //# sourceMappingURL=squawk.js.map
@@ -0,0 +1,2 @@
1
+ export { BackendPostgres } from "./postgres/backend.js";
2
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export { BackendPostgres } from "./postgres/backend.js";
package/dist/registry.js CHANGED
@@ -46,4 +46,3 @@ export class WorkflowRegistry {
46
46
  function registryKey(name, version) {
47
47
  return version ? `${name}@${version}` : name;
48
48
  }
49
- //# sourceMappingURL=registry.js.map
@@ -1,4 +1,6 @@
1
- import { Backend, CancelWorkflowRunParams, ClaimWorkflowRunParams, CreateStepAttemptParams, CreateWorkflowRunParams, GetStepAttemptParams, GetWorkflowRunParams, ExtendWorkflowRunLeaseParams, ListStepAttemptsParams, ListWorkflowRunsParams, PaginatedResponse, FailStepAttemptParams, CompleteStepAttemptParams, FailWorkflowRunParams, CompleteWorkflowRunParams, SleepWorkflowRunParams, StepAttempt, WorkflowRun } from "openworkflow/internal";
1
+ import { Backend, CancelWorkflowRunParams, ClaimWorkflowRunParams, CreateStepAttemptParams, CreateWorkflowRunParams, GetStepAttemptParams, GetWorkflowRunParams, ExtendWorkflowRunLeaseParams, ListStepAttemptsParams, ListWorkflowRunsParams, PaginatedResponse, FailStepAttemptParams, CompleteStepAttemptParams, FailWorkflowRunParams, CompleteWorkflowRunParams, SleepWorkflowRunParams } from "../backend.js";
2
+ import { StepAttempt } from "../core/step.js";
3
+ import { WorkflowRun } from "../core/workflow.js";
2
4
  interface BackendSqliteOptions {
3
5
  namespaceId?: string;
4
6
  runMigrations?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../sqlite/backend.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,OAAO,EACP,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,WAAW,EACX,WAAW,EAGZ,MAAM,uBAAuB,CAAC;AAI/B,UAAU,oBAAoB;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC3C,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO;IAKP;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa;IAiBrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAgDvB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAenE,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA0FxB,sBAAsB,CAC1B,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,WAAW,CAAC;IAmCjB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAoCtE,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IAyCjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IA+DpE,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAuDvB,gBAAgB,CACd,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAgE1C,gBAAgB,CACd,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAmE1C,OAAO,CAAC,wBAAwB;IAyC1B,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAwCvB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAenE,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IA0DjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;CAyD3E"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../sqlite/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,OAAO,EACP,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBlD,UAAU,oBAAoB;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC3C,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO;IAKP;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa;IAiBrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAgDvB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAenE,gBAAgB,CACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA0FxB,sBAAsB,CAC1B,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC,WAAW,CAAC;IAmCjB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAoCtE,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IAyCjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;IA+DpE,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAuDvB,gBAAgB,CACd,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAgE1C,gBAAgB,CACd,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAmE1C,OAAO,CAAC,wBAAwB;IAyC1B,iBAAiB,CACrB,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,WAAW,CAAC;IAwCvB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAenE,mBAAmB,CACvB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,WAAW,CAAC;IA0DjB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC;CAyD3E"}