openworkflow 0.4.0 → 0.5.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 (143) hide show
  1. package/README.md +57 -46
  2. package/dist/backend-postgres/index.d.ts +44 -0
  3. package/dist/backend-postgres/index.d.ts.map +1 -0
  4. package/dist/backend-postgres/index.js +535 -0
  5. package/dist/backend-postgres/index.js.map +1 -0
  6. package/dist/backend-postgres/postgres.d.ts +42 -0
  7. package/dist/backend-postgres/postgres.d.ts.map +1 -0
  8. package/dist/backend-postgres/postgres.js +234 -0
  9. package/dist/backend-postgres/postgres.js.map +1 -0
  10. package/dist/backend-sqlite/index.d.ts +42 -0
  11. package/dist/backend-sqlite/index.d.ts.map +1 -0
  12. package/dist/backend-sqlite/index.js +655 -0
  13. package/dist/backend-sqlite/index.js.map +1 -0
  14. package/dist/backend-sqlite/sqlite.d.ts +61 -0
  15. package/dist/backend-sqlite/sqlite.d.ts.map +1 -0
  16. package/dist/backend-sqlite/sqlite.js +247 -0
  17. package/dist/backend-sqlite/sqlite.js.map +1 -0
  18. package/dist/backend.d.ts +21 -89
  19. package/dist/backend.d.ts.map +1 -1
  20. package/dist/backend.js +0 -21
  21. package/dist/backend.js.map +1 -1
  22. package/dist/bin/openworkflow.d.ts +3 -0
  23. package/dist/bin/openworkflow.d.ts.map +1 -0
  24. package/dist/bin/openworkflow.js +44 -0
  25. package/dist/bin/openworkflow.js.map +1 -0
  26. package/dist/client.d.ts +68 -80
  27. package/dist/client.d.ts.map +1 -1
  28. package/dist/client.js +83 -53
  29. package/dist/client.js.map +1 -1
  30. package/dist/config.d.ts +34 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +49 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/{duration.d.ts → core/duration.d.ts} +5 -2
  35. package/dist/core/duration.d.ts.map +1 -0
  36. package/dist/{duration.js → core/duration.js} +9 -6
  37. package/dist/core/duration.js.map +1 -0
  38. package/dist/core/error.d.ts +14 -0
  39. package/dist/core/error.d.ts.map +1 -0
  40. package/dist/core/error.js +18 -0
  41. package/dist/core/error.js.map +1 -0
  42. package/dist/core/json.d.ts +5 -0
  43. package/dist/core/json.d.ts.map +1 -0
  44. package/dist/core/json.js +2 -0
  45. package/dist/core/json.js.map +1 -0
  46. package/dist/core/result.d.ts +22 -0
  47. package/dist/core/result.d.ts.map +1 -0
  48. package/dist/core/result.js +17 -0
  49. package/dist/core/result.js.map +1 -0
  50. package/dist/core/retry.d.ts +7 -0
  51. package/dist/core/retry.d.ts.map +1 -0
  52. package/dist/core/retry.js +7 -0
  53. package/dist/core/retry.js.map +1 -0
  54. package/dist/core/schema.d.ts.map +1 -0
  55. package/dist/core/schema.js.map +1 -0
  56. package/dist/core/step.d.ts +89 -0
  57. package/dist/core/step.d.ts.map +1 -0
  58. package/dist/core/step.js +66 -0
  59. package/dist/core/step.js.map +1 -0
  60. package/dist/core/workflow.d.ts +63 -0
  61. package/dist/core/workflow.d.ts.map +1 -0
  62. package/dist/core/workflow.js +35 -0
  63. package/dist/core/workflow.js.map +1 -0
  64. package/dist/execution.d.ts +69 -0
  65. package/dist/execution.d.ts.map +1 -0
  66. package/dist/execution.js +188 -0
  67. package/dist/execution.js.map +1 -0
  68. package/dist/index.d.ts +2 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +2 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/internal.d.ts +8 -0
  73. package/dist/internal.d.ts.map +1 -0
  74. package/dist/internal.js +5 -0
  75. package/dist/internal.js.map +1 -0
  76. package/dist/pg/backend.d.ts +42 -0
  77. package/dist/pg/backend.d.ts.map +1 -0
  78. package/dist/pg/backend.js +534 -0
  79. package/dist/pg/backend.js.map +1 -0
  80. package/dist/pg/index.d.ts +3 -0
  81. package/dist/pg/index.d.ts.map +1 -0
  82. package/dist/pg/index.js +3 -0
  83. package/dist/pg/index.js.map +1 -0
  84. package/dist/pg/postgres.d.ts +42 -0
  85. package/dist/pg/postgres.d.ts.map +1 -0
  86. package/dist/pg/postgres.js +234 -0
  87. package/dist/pg/postgres.js.map +1 -0
  88. package/dist/pg/scripts/db-migrate.d.ts +2 -0
  89. package/dist/pg/scripts/db-migrate.d.ts.map +1 -0
  90. package/dist/pg/scripts/db-migrate.js +5 -0
  91. package/dist/pg/scripts/db-migrate.js.map +1 -0
  92. package/dist/pg/scripts/db-reset.d.ts +2 -0
  93. package/dist/pg/scripts/db-reset.d.ts.map +1 -0
  94. package/dist/pg/scripts/db-reset.js +6 -0
  95. package/dist/pg/scripts/db-reset.js.map +1 -0
  96. package/dist/pg/scripts/squawk.d.ts +2 -0
  97. package/dist/pg/scripts/squawk.d.ts.map +1 -0
  98. package/dist/pg/scripts/squawk.js +17 -0
  99. package/dist/pg/scripts/squawk.js.map +1 -0
  100. package/dist/pg/vitest.global-setup.d.ts +3 -0
  101. package/dist/pg/vitest.global-setup.d.ts.map +1 -0
  102. package/dist/pg/vitest.global-setup.js +8 -0
  103. package/dist/pg/vitest.global-setup.js.map +1 -0
  104. package/dist/registry.d.ts +27 -0
  105. package/dist/registry.d.ts.map +1 -0
  106. package/dist/registry.js +49 -0
  107. package/dist/registry.js.map +1 -0
  108. package/dist/sqlite/backend.d.ts +40 -0
  109. package/dist/sqlite/backend.d.ts.map +1 -0
  110. package/dist/sqlite/backend.js +654 -0
  111. package/dist/sqlite/backend.js.map +1 -0
  112. package/dist/sqlite/index.d.ts +3 -0
  113. package/dist/sqlite/index.d.ts.map +1 -0
  114. package/dist/sqlite/index.js +3 -0
  115. package/dist/sqlite/index.js.map +1 -0
  116. package/dist/sqlite/sqlite.d.ts +61 -0
  117. package/dist/sqlite/sqlite.d.ts.map +1 -0
  118. package/dist/sqlite/sqlite.js +247 -0
  119. package/dist/sqlite/sqlite.js.map +1 -0
  120. package/dist/testing/backend.testsuite.d.ts +20 -0
  121. package/dist/testing/backend.testsuite.d.ts.map +1 -0
  122. package/dist/testing/backend.testsuite.js +1091 -0
  123. package/dist/testing/backend.testsuite.js.map +1 -0
  124. package/dist/testing/index.d.ts +2 -0
  125. package/dist/testing/index.d.ts.map +1 -0
  126. package/dist/testing/index.js +2 -0
  127. package/dist/testing/index.js.map +1 -0
  128. package/dist/tsconfig.tsbuildinfo +1 -1
  129. package/dist/worker.d.ts +10 -3
  130. package/dist/worker.d.ts.map +1 -1
  131. package/dist/worker.js +29 -195
  132. package/dist/worker.js.map +1 -1
  133. package/dist/workflow.d.ts +60 -0
  134. package/dist/workflow.d.ts.map +1 -0
  135. package/dist/workflow.js +49 -0
  136. package/dist/workflow.js.map +1 -0
  137. package/package.json +16 -6
  138. package/dist/duration.d.ts.map +0 -1
  139. package/dist/duration.js.map +0 -1
  140. package/dist/schema.d.ts.map +0 -1
  141. package/dist/schema.js.map +0 -1
  142. /package/dist/{schema.d.ts → core/schema.d.ts} +0 -0
  143. /package/dist/{schema.js → core/schema.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../pg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,oBAAoB,EACpB,cAAc,EAGd,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,UAAU,GACX,MAAM,eAAe,CAAC"}
@@ -0,0 +1,42 @@
1
+ import postgres from "postgres";
2
+ export declare const DEFAULT_POSTGRES_URL = "postgresql://postgres:postgres@localhost:5432/postgres";
3
+ export declare const DEFAULT_SCHEMA = "openworkflow";
4
+ export type Postgres = ReturnType<typeof postgres>;
5
+ export type PostgresOptions = Parameters<typeof postgres>[1];
6
+ /**
7
+ * newPostgres creates a new Postgres client.
8
+ * @param url - Database connection URL
9
+ * @param options - Postgres client options
10
+ * @returns A Postgres client
11
+ */
12
+ export declare function newPostgres(url: string, options?: PostgresOptions): postgres.Sql<{}>;
13
+ /**
14
+ * newPostgresMaxOne creates a new Postgres client with a maximum pool size of
15
+ * one, which is useful for migrations.
16
+ * @param url - Database connection URL
17
+ * @param options - Postgres client options
18
+ * @returns A Postgres client
19
+ */
20
+ export declare function newPostgresMaxOne(url: string, options?: PostgresOptions): postgres.Sql<{}>;
21
+ /**
22
+ * migrations returns the list of migration SQL statements.
23
+ * @param schema - Schema name
24
+ * @returns Migration SQL statements
25
+ */
26
+ export declare function migrations(schema: string): string[];
27
+ /**
28
+ * migrate applies pending migrations to the database. Does nothing if the
29
+ * database is already up to date.
30
+ * @param pg - Postgres client
31
+ * @param schema - Schema name
32
+ * @returns Promise resolved when migrations complete
33
+ */
34
+ export declare function migrate(pg: Postgres, schema: string): Promise<void>;
35
+ /**
36
+ * dropSchema drops the specified schema from the database.
37
+ * @param pg - Postgres client
38
+ * @param schema - Schema name
39
+ * @returns Promise resolved when the schema is dropped
40
+ */
41
+ export declare function dropSchema(pg: Postgres, schema: string): Promise<void>;
42
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../pg/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"}
@@ -0,0 +1,234 @@
1
+ import postgres from "postgres";
2
+ export const DEFAULT_POSTGRES_URL = "postgresql://postgres:postgres@localhost:5432/postgres";
3
+ // The default schema to use for OpenWorkflow data. This type is more for
4
+ // documentation than for practical use. The only time we allow schema
5
+ // customization is during testing, specifically for testing migrations.
6
+ // Everywhere else uses the "openworkflow" schema directly for prepared
7
+ // statements.
8
+ export const DEFAULT_SCHEMA = "openworkflow";
9
+ /**
10
+ * newPostgres creates a new Postgres client.
11
+ * @param url - Database connection URL
12
+ * @param options - Postgres client options
13
+ * @returns A Postgres client
14
+ */
15
+ export function newPostgres(url, options) {
16
+ return postgres(url, { ...options, transform: postgres.toCamel });
17
+ }
18
+ /**
19
+ * newPostgresMaxOne creates a new Postgres client with a maximum pool size of
20
+ * one, which is useful for migrations.
21
+ * @param url - Database connection URL
22
+ * @param options - Postgres client options
23
+ * @returns A Postgres client
24
+ */
25
+ export function newPostgresMaxOne(url, options) {
26
+ return newPostgres(url, { ...options, max: 1 });
27
+ }
28
+ /**
29
+ * migrations returns the list of migration SQL statements.
30
+ * @param schema - Schema name
31
+ * @returns Migration SQL statements
32
+ */
33
+ export function migrations(schema) {
34
+ return [
35
+ // 0 - init
36
+ `BEGIN;
37
+
38
+ CREATE SCHEMA IF NOT EXISTS ${schema};
39
+
40
+ CREATE TABLE IF NOT EXISTS "${schema}"."openworkflow_migrations" (
41
+ "version" BIGINT NOT NULL PRIMARY KEY
42
+ );
43
+
44
+ INSERT INTO "${schema}"."openworkflow_migrations" ("version")
45
+ VALUES (0)
46
+ ON CONFLICT DO NOTHING;
47
+
48
+ COMMIT;`,
49
+ // 1 - add workflow_runs and step_attempts tables
50
+ `BEGIN;
51
+
52
+ CREATE TABLE IF NOT EXISTS "${schema}"."workflow_runs" (
53
+ "namespace_id" TEXT NOT NULL,
54
+ "id" TEXT NOT NULL,
55
+ --
56
+ "workflow_name" TEXT NOT NULL,
57
+ "version" TEXT,
58
+ "status" TEXT NOT NULL,
59
+ "idempotency_key" TEXT,
60
+ "config" JSONB NOT NULL,
61
+ "context" JSONB,
62
+ "input" JSONB,
63
+ "output" JSONB,
64
+ "error" JSONB,
65
+ "attempts" INTEGER NOT NULL,
66
+ "parent_step_attempt_namespace_id" TEXT,
67
+ "parent_step_attempt_id" TEXT,
68
+ "worker_id" TEXT,
69
+ "available_at" TIMESTAMPTZ,
70
+ "deadline_at" TIMESTAMPTZ,
71
+ "started_at" TIMESTAMPTZ,
72
+ "finished_at" TIMESTAMPTZ,
73
+ "created_at" TIMESTAMPTZ NOT NULL,
74
+ "updated_at" TIMESTAMPTZ NOT NULL,
75
+ PRIMARY KEY ("namespace_id", "id")
76
+ );
77
+
78
+ CREATE TABLE IF NOT EXISTS "${schema}"."step_attempts" (
79
+ "namespace_id" TEXT NOT NULL,
80
+ "id" TEXT NOT NULL,
81
+ --
82
+ "workflow_run_id" TEXT NOT NULL,
83
+ "step_name" TEXT NOT NULL,
84
+ "kind" TEXT NOT NULL,
85
+ "status" TEXT NOT NULL,
86
+ "config" JSONB NOT NULL,
87
+ "context" JSONB,
88
+ "output" JSONB,
89
+ "error" JSONB,
90
+ "child_workflow_run_namespace_id" TEXT,
91
+ "child_workflow_run_id" TEXT,
92
+ "started_at" TIMESTAMPTZ,
93
+ "finished_at" TIMESTAMPTZ,
94
+ "created_at" TIMESTAMPTZ NOT NULL,
95
+ "updated_at" TIMESTAMPTZ NOT NULL,
96
+ PRIMARY KEY ("namespace_id", "id")
97
+ );
98
+
99
+ INSERT INTO "${schema}"."openworkflow_migrations" ("version")
100
+ VALUES (1)
101
+ ON CONFLICT DO NOTHING;
102
+
103
+ COMMIT;`,
104
+ // 2 - foreign keys
105
+ `BEGIN;
106
+
107
+ ALTER TABLE "${schema}"."step_attempts"
108
+ ADD CONSTRAINT "step_attempts_workflow_run_fk"
109
+ FOREIGN KEY ("namespace_id", "workflow_run_id")
110
+ REFERENCES "${schema}"."workflow_runs" ("namespace_id", "id")
111
+ ON DELETE CASCADE
112
+ NOT VALID;
113
+
114
+ ALTER TABLE "${schema}"."workflow_runs"
115
+ ADD CONSTRAINT "workflow_runs_parent_step_attempt_fk"
116
+ FOREIGN KEY ("parent_step_attempt_namespace_id", "parent_step_attempt_id")
117
+ REFERENCES "${schema}"."step_attempts" ("namespace_id", "id")
118
+ ON DELETE SET NULL
119
+ NOT VALID;
120
+
121
+ ALTER TABLE "${schema}"."step_attempts"
122
+ ADD CONSTRAINT "step_attempts_child_workflow_run_fk"
123
+ FOREIGN KEY ("child_workflow_run_namespace_id", "child_workflow_run_id")
124
+ REFERENCES "${schema}"."workflow_runs" ("namespace_id", "id")
125
+ ON DELETE SET NULL
126
+ NOT VALID;
127
+
128
+ INSERT INTO "${schema}"."openworkflow_migrations" ("version")
129
+ VALUES (2)
130
+ ON CONFLICT DO NOTHING;
131
+
132
+ COMMIT;`,
133
+ // 3 - validate foreign keys
134
+ `BEGIN;
135
+
136
+ ALTER TABLE "${schema}"."step_attempts"
137
+ VALIDATE CONSTRAINT "step_attempts_workflow_run_fk";
138
+
139
+ ALTER TABLE "${schema}"."workflow_runs" VALIDATE CONSTRAINT
140
+ "workflow_runs_parent_step_attempt_fk";
141
+
142
+ ALTER TABLE "${schema}"."step_attempts"
143
+ VALIDATE CONSTRAINT "step_attempts_child_workflow_run_fk";
144
+
145
+ INSERT INTO "${schema}"."openworkflow_migrations" ("version")
146
+ VALUES (3)
147
+ ON CONFLICT DO NOTHING;
148
+
149
+ COMMIT;`,
150
+ // 4 - indexes
151
+ `BEGIN;
152
+
153
+ CREATE INDEX IF NOT EXISTS "workflow_runs_status_available_at_created_at_idx"
154
+ ON "${schema}"."workflow_runs" ("namespace_id", "status", "available_at", "created_at");
155
+
156
+ CREATE INDEX IF NOT EXISTS "workflow_runs_workflow_name_idempotency_key_created_at_idx"
157
+ ON "${schema}"."workflow_runs" ("namespace_id", "workflow_name", "idempotency_key", "created_at");
158
+
159
+ CREATE INDEX IF NOT EXISTS "workflow_runs_parent_step_idx"
160
+ ON "${schema}"."workflow_runs" ("parent_step_attempt_namespace_id", "parent_step_attempt_id")
161
+ WHERE parent_step_attempt_namespace_id IS NOT NULL AND parent_step_attempt_id IS NOT NULL;
162
+
163
+ CREATE INDEX IF NOT EXISTS "workflow_runs_created_at_desc_idx"
164
+ ON "${schema}"."workflow_runs" ("namespace_id", "created_at" DESC);
165
+
166
+ CREATE INDEX IF NOT EXISTS "workflow_runs_status_created_at_desc_idx"
167
+ ON "${schema}"."workflow_runs" ("namespace_id", "status", "created_at" DESC);
168
+
169
+ CREATE INDEX IF NOT EXISTS "workflow_runs_workflow_name_status_created_at_desc_idx"
170
+ ON "${schema}"."workflow_runs" ("namespace_id", "workflow_name", "status", "created_at" DESC);
171
+
172
+ CREATE INDEX IF NOT EXISTS "step_attempts_workflow_run_created_at_idx"
173
+ ON "${schema}"."step_attempts" ("namespace_id", "workflow_run_id", "created_at");
174
+
175
+ CREATE INDEX IF NOT EXISTS "step_attempts_workflow_run_step_name_created_at_idx"
176
+ ON "${schema}"."step_attempts" ("namespace_id", "workflow_run_id", "step_name", "created_at");
177
+
178
+ CREATE INDEX IF NOT EXISTS "step_attempts_child_workflow_run_idx"
179
+ ON "${schema}"."step_attempts" ("child_workflow_run_namespace_id", "child_workflow_run_id")
180
+ WHERE child_workflow_run_namespace_id IS NOT NULL AND child_workflow_run_id IS NOT NULL;
181
+
182
+ INSERT INTO "${schema}"."openworkflow_migrations"("version")
183
+ VALUES (4)
184
+ ON CONFLICT DO NOTHING;
185
+
186
+ COMMIT;`,
187
+ ];
188
+ }
189
+ /**
190
+ * migrate applies pending migrations to the database. Does nothing if the
191
+ * database is already up to date.
192
+ * @param pg - Postgres client
193
+ * @param schema - Schema name
194
+ * @returns Promise resolved when migrations complete
195
+ */
196
+ export async function migrate(pg, schema) {
197
+ const currentMigrationVersion = await getCurrentMigrationVersion(pg, schema);
198
+ for (const [i, migrationSql] of migrations(schema).entries()) {
199
+ if (i <= currentMigrationVersion)
200
+ continue; // already applied
201
+ await pg.unsafe(migrationSql);
202
+ }
203
+ }
204
+ /**
205
+ * dropSchema drops the specified schema from the database.
206
+ * @param pg - Postgres client
207
+ * @param schema - Schema name
208
+ * @returns Promise resolved when the schema is dropped
209
+ */
210
+ export async function dropSchema(pg, schema) {
211
+ await pg.unsafe(`DROP SCHEMA IF EXISTS ${schema} CASCADE;`);
212
+ }
213
+ /**
214
+ * getCurrentVersion returns the current migration version of the database.
215
+ * @param pg - Postgres client
216
+ * @param schema - Schema name
217
+ * @returns Current migration version
218
+ */
219
+ async function getCurrentMigrationVersion(pg, schema) {
220
+ // check if migrations table exists
221
+ const existsRes = await pg.unsafe(`
222
+ SELECT EXISTS (
223
+ SELECT 1
224
+ FROM information_schema.tables
225
+ WHERE table_schema = '${schema}'
226
+ AND table_name = 'openworkflow_migrations'
227
+ )`);
228
+ if (!existsRes[0]?.exists)
229
+ return -1;
230
+ // get current version
231
+ const currentVersionRes = await pg.unsafe(`SELECT MAX("version") AS "version" FROM "${schema}"."openworkflow_migrations";`);
232
+ return currentVersionRes[0]?.version ?? -1;
233
+ }
234
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../pg/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,MAAM,oBAAoB,GAC/B,wDAAwD,CAAC;AAE3D,yEAAyE;AACzE,sEAAsE;AACtE,wEAAwE;AACxE,uEAAuE;AACvE,cAAc;AACd,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAK7C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,OAAyB;IAChE,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,OAAyB;IACtE,OAAO,WAAW,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO;QACL,WAAW;QACX;;kCAE8B,MAAM;;kCAEN,MAAM;;;;mBAIrB,MAAM;;;;YAIb;QAER,iDAAiD;QACjD;;kCAE8B,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;kCA0BN,MAAM;;;;;;;;;;;;;;;;;;;;;mBAqBrB,MAAM;;;;YAIb;QAER,mBAAmB;QACnB;;mBAEe,MAAM;;;kBAGP,MAAM;;;;mBAIL,MAAM;;;kBAGP,MAAM;;;;mBAIL,MAAM;;;kBAGP,MAAM;;;;mBAIL,MAAM;;;;YAIb;QAER,4BAA4B;QAC5B;;mBAEe,MAAM;;;mBAGN,MAAM;;;mBAGN,MAAM;;;mBAGN,MAAM;;;;YAIb;QAER,cAAc;QACd;;;UAGM,MAAM;;;UAGN,MAAM;;;UAGN,MAAM;;;;UAIN,MAAM;;;UAGN,MAAM;;;UAGN,MAAM;;;UAGN,MAAM;;;UAGN,MAAM;;;UAGN,MAAM;;;mBAGG,MAAM;;;;YAIb;KACT,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAY,EAAE,MAAc;IACxD,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAE7E,KAAK,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7D,IAAI,CAAC,IAAI,uBAAuB;YAAE,SAAS,CAAC,kBAAkB;QAE9D,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,EAAY,EAAE,MAAc;IAC3D,MAAM,EAAE,CAAC,MAAM,CAAC,yBAAyB,MAAM,WAAW,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,0BAA0B,CACvC,EAAY,EACZ,MAAc;IAEd,mCAAmC;IACnC,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,MAAM,CAAwB;;;;8BAI7B,MAAM;;MAE9B,CAAC,CAAC;IACN,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM;QAAE,OAAO,CAAC,CAAC,CAAC;IAErC,sBAAsB;IACtB,MAAM,iBAAiB,GAAG,MAAM,EAAE,CAAC,MAAM,CACvC,4CAA4C,MAAM,8BAA8B,CACjF,CAAC;IACF,OAAO,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=db-migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate.d.ts","sourceRoot":"","sources":["../../../pg/scripts/db-migrate.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { DEFAULT_POSTGRES_URL, DEFAULT_SCHEMA, newPostgresMaxOne, migrate, } from "../postgres.js";
2
+ const pg = newPostgresMaxOne(DEFAULT_POSTGRES_URL);
3
+ await migrate(pg, DEFAULT_SCHEMA);
4
+ await pg.end();
5
+ //# sourceMappingURL=db-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate.js","sourceRoot":"","sources":["../../../pg/scripts/db-migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,OAAO,GACR,MAAM,gBAAgB,CAAC;AAExB,MAAM,EAAE,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;AACnD,MAAM,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;AAClC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=db-reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-reset.d.ts","sourceRoot":"","sources":["../../../pg/scripts/db-reset.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { DEFAULT_POSTGRES_URL, DEFAULT_SCHEMA, newPostgresMaxOne, dropSchema, migrate, } from "../postgres.js";
2
+ const pg = newPostgresMaxOne(DEFAULT_POSTGRES_URL);
3
+ await dropSchema(pg, DEFAULT_SCHEMA);
4
+ await migrate(pg, DEFAULT_SCHEMA);
5
+ await pg.end();
6
+ //# sourceMappingURL=db-reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-reset.js","sourceRoot":"","sources":["../../../pg/scripts/db-reset.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,OAAO,GACR,MAAM,gBAAgB,CAAC;AAExB,MAAM,EAAE,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;AACnD,MAAM,UAAU,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;AACrC,MAAM,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;AAClC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=squawk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"squawk.d.ts","sourceRoot":"","sources":["../../../pg/scripts/squawk.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { DEFAULT_SCHEMA, migrations } from "../postgres.js";
2
+ import { execSync } from "node:child_process";
3
+ import { unlinkSync, writeFileSync } from "node:fs";
4
+ const sql = migrations(DEFAULT_SCHEMA).join("\n\n");
5
+ writeFileSync("squawk.sql", sql);
6
+ try {
7
+ // eslint-disable-next-line sonarjs/no-os-command-from-path
8
+ execSync("npx squawk squawk.sql", { stdio: "inherit" });
9
+ }
10
+ catch {
11
+ // ignore - squawk will produce its own error output
12
+ }
13
+ finally {
14
+ unlinkSync("squawk.sql");
15
+ console.log("");
16
+ }
17
+ //# sourceMappingURL=squawk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"squawk.js","sourceRoot":"","sources":["../../../pg/scripts/squawk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,GAAG,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACpD,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAEjC,IAAI,CAAC;IACH,2DAA2D;IAC3D,QAAQ,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAC1D,CAAC;AAAC,MAAM,CAAC;IACP,oDAAoD;AACtD,CAAC;QAAS,CAAC;IACT,UAAU,CAAC,YAAY,CAAC,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Run database migrations once before Postgres backend tests. */
2
+ export declare function setup(): Promise<void>;
3
+ //# sourceMappingURL=vitest.global-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.global-setup.d.ts","sourceRoot":"","sources":["../../pg/vitest.global-setup.ts"],"names":[],"mappings":"AAOA,kEAAkE;AAClE,wBAAsB,KAAK,kBAI1B"}
@@ -0,0 +1,8 @@
1
+ import { migrate, newPostgresMaxOne, DEFAULT_SCHEMA, DEFAULT_POSTGRES_URL, } from "./postgres.js";
2
+ /** Run database migrations once before Postgres backend tests. */
3
+ export async function setup() {
4
+ const pg = newPostgresMaxOne(DEFAULT_POSTGRES_URL);
5
+ await migrate(pg, DEFAULT_SCHEMA);
6
+ await pg.end();
7
+ }
8
+ //# sourceMappingURL=vitest.global-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.global-setup.js","sourceRoot":"","sources":["../../pg/vitest.global-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,cAAc,EACd,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,EAAE,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;IACnD,MAAM,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;IAClC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;AACjB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Workflow } from "./workflow.js";
2
+ /**
3
+ * A registry for storing and retrieving workflows by name and version.
4
+ * Provides a centralized way to manage workflow registrations.
5
+ */
6
+ export declare class WorkflowRegistry {
7
+ private readonly workflows;
8
+ /**
9
+ * Register a workflow in the registry.
10
+ * @param workflow - The workflow to register
11
+ * @throws {Error} If a workflow with the same name and version is already registered
12
+ */
13
+ register(workflow: Workflow<unknown, unknown, unknown>): void;
14
+ /**
15
+ * Get a workflow from the registry by name and version.
16
+ * @param name - The workflow name
17
+ * @param version - The workflow version (null for unversioned)
18
+ * @returns The workflow if found, undefined otherwise
19
+ */
20
+ get(name: string, version: string | null): Workflow<unknown, unknown, unknown> | undefined;
21
+ /**
22
+ * Get all registered workflows.
23
+ * @returns Array of all registered workflows
24
+ */
25
+ getAll(): Workflow<unknown, unknown, unknown>[];
26
+ }
27
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGtB;IAEJ;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI;IAW7D;;;;;OAKG;IACH,GAAG,CACD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS;IAKlD;;;OAGG;IACH,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;CAGhD"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * A registry for storing and retrieving workflows by name and version.
3
+ * Provides a centralized way to manage workflow registrations.
4
+ */
5
+ export class WorkflowRegistry {
6
+ workflows = new Map();
7
+ /**
8
+ * Register a workflow in the registry.
9
+ * @param workflow - The workflow to register
10
+ * @throws {Error} If a workflow with the same name and version is already registered
11
+ */
12
+ register(workflow) {
13
+ const name = workflow.spec.name;
14
+ const version = workflow.spec.version ?? null;
15
+ const key = registryKey(name, version);
16
+ if (this.workflows.has(key)) {
17
+ const versionStr = version ? ` (version: ${version})` : "";
18
+ throw new Error(`Workflow "${name}"${versionStr} is already registered`);
19
+ }
20
+ this.workflows.set(key, workflow);
21
+ }
22
+ /**
23
+ * Get a workflow from the registry by name and version.
24
+ * @param name - The workflow name
25
+ * @param version - The workflow version (null for unversioned)
26
+ * @returns The workflow if found, undefined otherwise
27
+ */
28
+ get(name, version) {
29
+ const key = registryKey(name, version);
30
+ return this.workflows.get(key);
31
+ }
32
+ /**
33
+ * Get all registered workflows.
34
+ * @returns Array of all registered workflows
35
+ */
36
+ getAll() {
37
+ return [...this.workflows.values()];
38
+ }
39
+ }
40
+ /**
41
+ * Build a registry key from name and version.
42
+ * @param name - Workflow name
43
+ * @param version - Workflow version (or null)
44
+ * @returns Registry key
45
+ */
46
+ function registryKey(name, version) {
47
+ return version ? `${name}@${version}` : name;
48
+ }
49
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../registry.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACV,SAAS,GAAG,IAAI,GAAG,EAGjC,CAAC;IAEJ;;;;OAIG;IACH,QAAQ,CAAC,QAA6C;QACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QAC9C,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI,UAAU,wBAAwB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,GAAG,CACD,IAAY,EACZ,OAAsB;QAEtB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,CAAC;CACF;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,IAAY,EAAE,OAAsB;IACvD,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Backend, CancelWorkflowRunParams, ClaimWorkflowRunParams, CreateStepAttemptParams, CreateWorkflowRunParams, GetStepAttemptParams, GetWorkflowRunParams, ExtendWorkflowRunLeaseParams, ListStepAttemptsParams, ListWorkflowRunsParams, PaginatedResponse, FailStepAttemptParams, CompleteStepAttemptParams, FailWorkflowRunParams, CompleteWorkflowRunParams, SleepWorkflowRunParams, StepAttempt, WorkflowRun } from "openworkflow/internal";
2
+ interface BackendSqliteOptions {
3
+ namespaceId?: string;
4
+ runMigrations?: boolean;
5
+ }
6
+ /**
7
+ * Manages a connection to a SQLite database for workflow operations.
8
+ */
9
+ export declare class BackendSqlite implements Backend {
10
+ private db;
11
+ private namespaceId;
12
+ private constructor();
13
+ /**
14
+ * Create and initialize a new BackendSqlite instance. This will
15
+ * automatically run migrations on startup unless `runMigrations` is set to
16
+ * false.
17
+ * @param path - Database path
18
+ * @param options - Backend options
19
+ * @returns A connected backend instance
20
+ */
21
+ static connect(path: string, options?: BackendSqliteOptions): BackendSqlite;
22
+ stop(): Promise<void>;
23
+ createWorkflowRun(params: CreateWorkflowRunParams): Promise<WorkflowRun>;
24
+ getWorkflowRun(params: GetWorkflowRunParams): Promise<WorkflowRun | null>;
25
+ claimWorkflowRun(params: ClaimWorkflowRunParams): Promise<WorkflowRun | null>;
26
+ extendWorkflowRunLease(params: ExtendWorkflowRunLeaseParams): Promise<WorkflowRun>;
27
+ sleepWorkflowRun(params: SleepWorkflowRunParams): Promise<WorkflowRun>;
28
+ completeWorkflowRun(params: CompleteWorkflowRunParams): Promise<WorkflowRun>;
29
+ failWorkflowRun(params: FailWorkflowRunParams): Promise<WorkflowRun>;
30
+ cancelWorkflowRun(params: CancelWorkflowRunParams): Promise<WorkflowRun>;
31
+ listWorkflowRuns(params: ListWorkflowRunsParams): Promise<PaginatedResponse<WorkflowRun>>;
32
+ listStepAttempts(params: ListStepAttemptsParams): Promise<PaginatedResponse<StepAttempt>>;
33
+ private processPaginationResults;
34
+ createStepAttempt(params: CreateStepAttemptParams): Promise<StepAttempt>;
35
+ getStepAttempt(params: GetStepAttemptParams): Promise<StepAttempt | null>;
36
+ completeStepAttempt(params: CompleteStepAttemptParams): Promise<StepAttempt>;
37
+ failStepAttempt(params: FailStepAttemptParams): Promise<StepAttempt>;
38
+ }
39
+ export {};
40
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +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"}