awaitly 2.0.0 → 3.0.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 (88) hide show
  1. package/dist/di-Biw_plBn.d.cts +15 -0
  2. package/dist/di-DxyH2N3i.d.ts +15 -0
  3. package/dist/durable.cjs +4670 -0
  4. package/dist/durable.cjs.map +1 -0
  5. package/dist/durable.d.cts +9 -0
  6. package/dist/durable.d.ts +9 -0
  7. package/dist/durable.js +4610 -0
  8. package/dist/durable.js.map +1 -0
  9. package/dist/{di-BbFFfO8y.d.ts → duration-BjVn3QpB.d.cts} +1 -15
  10. package/dist/{di-BDlT7InM.d.cts → duration-BjVn3QpB.d.ts} +1 -15
  11. package/dist/engine.cjs +4501 -0
  12. package/dist/engine.cjs.map +1 -0
  13. package/dist/engine.d.cts +113 -0
  14. package/dist/engine.d.ts +113 -0
  15. package/dist/engine.js +4474 -0
  16. package/dist/engine.js.map +1 -0
  17. package/dist/{errors-DtXvrCiO.d.cts → errors-sDSeaZBO.d.cts} +1 -1
  18. package/dist/{errors-DtXvrCiO.d.ts → errors-sDSeaZBO.d.ts} +1 -1
  19. package/dist/guards-CwQZro1F.d.ts +72 -0
  20. package/dist/guards-DhhOJZda.d.cts +72 -0
  21. package/dist/hitl-BnnnLzh2.d.cts +468 -0
  22. package/dist/hitl-pYfkQMv_.d.ts +468 -0
  23. package/dist/hitl.cjs +646 -0
  24. package/dist/hitl.cjs.map +1 -0
  25. package/dist/hitl.d.cts +440 -0
  26. package/dist/hitl.d.ts +440 -0
  27. package/dist/hitl.js +605 -0
  28. package/dist/hitl.js.map +1 -0
  29. package/dist/index-Bew12SZ8.d.ts +417 -0
  30. package/dist/index-Bwt-iz50.d.cts +417 -0
  31. package/dist/{types-B8NfNRGX.d.ts → index-Cv4K_3sZ.d.ts} +2 -1162
  32. package/dist/{types-BZ2f4MRR.d.cts → index-ICmfQi08.d.cts} +2 -1162
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +11 -1527
  35. package/dist/index.d.ts +11 -1527
  36. package/dist/persistence.cjs +552 -0
  37. package/dist/persistence.cjs.map +1 -0
  38. package/dist/persistence.d.cts +254 -0
  39. package/dist/persistence.d.ts +254 -0
  40. package/dist/persistence.js +499 -0
  41. package/dist/persistence.js.map +1 -0
  42. package/dist/reliability.cjs +1651 -0
  43. package/dist/reliability.cjs.map +1 -0
  44. package/dist/reliability.d.cts +1442 -0
  45. package/dist/reliability.d.ts +1442 -0
  46. package/dist/reliability.js +1589 -0
  47. package/dist/reliability.js.map +1 -0
  48. package/dist/result.d.cts +1 -1
  49. package/dist/result.d.ts +1 -1
  50. package/dist/run.cjs +2283 -0
  51. package/dist/run.cjs.map +1 -0
  52. package/dist/run.d.cts +90 -0
  53. package/dist/run.d.ts +90 -0
  54. package/dist/run.js +2247 -0
  55. package/dist/run.js.map +1 -0
  56. package/dist/saga.cjs +3699 -0
  57. package/dist/saga.cjs.map +1 -0
  58. package/dist/saga.d.cts +162 -0
  59. package/dist/saga.d.ts +162 -0
  60. package/dist/saga.js +3670 -0
  61. package/dist/saga.js.map +1 -0
  62. package/dist/store-contract-BI98VYmX.d.ts +66 -0
  63. package/dist/store-contract-C2HyR_o6.d.cts +66 -0
  64. package/dist/streaming.cjs +895 -0
  65. package/dist/streaming.cjs.map +1 -0
  66. package/dist/streaming.d.cts +594 -0
  67. package/dist/streaming.d.ts +594 -0
  68. package/dist/streaming.js +832 -0
  69. package/dist/streaming.js.map +1 -0
  70. package/dist/testing.d.cts +4 -2
  71. package/dist/testing.d.ts +4 -2
  72. package/dist/types-BDTxgKKc.d.ts +845 -0
  73. package/dist/types-C9Y71dua.d.cts +845 -0
  74. package/dist/types-d8q8iQlk.d.cts +323 -0
  75. package/dist/types-sObbY4mX.d.ts +323 -0
  76. package/dist/webhook.cjs +461 -0
  77. package/dist/webhook.cjs.map +1 -0
  78. package/dist/webhook.d.cts +497 -0
  79. package/dist/webhook.d.ts +497 -0
  80. package/dist/webhook.js +422 -0
  81. package/dist/webhook.js.map +1 -0
  82. package/dist/workflow.cjs +2 -2614
  83. package/dist/workflow.cjs.map +1 -1
  84. package/dist/workflow.d.cts +12 -3023
  85. package/dist/workflow.d.ts +12 -3023
  86. package/dist/workflow.js +2 -2535
  87. package/dist/workflow.js.map +1 -1
  88. package/package.json +46 -1
@@ -0,0 +1,499 @@
1
+ // src/core/index.ts
2
+ function ok(value) {
3
+ return { ok: true, value };
4
+ }
5
+ function err(error, options) {
6
+ const cause = options?.cause;
7
+ return { ok: false, error, ...cause !== void 0 ? { cause } : {} };
8
+ }
9
+
10
+ // src/workflow/guards.ts
11
+ function isResumeState(x) {
12
+ return typeof x === "object" && x !== null && "steps" in x && x.steps instanceof Map;
13
+ }
14
+
15
+ // src/persistence.ts
16
+ var SnapshotFormatError = class extends Error {
17
+ constructor(message, errors = []) {
18
+ super(message);
19
+ this.errors = errors;
20
+ this.name = "SnapshotFormatError";
21
+ }
22
+ errors;
23
+ };
24
+ var SnapshotMismatchError = class extends Error {
25
+ constructor(message, mismatchType, details) {
26
+ super(message);
27
+ this.mismatchType = mismatchType;
28
+ this.details = details;
29
+ this.name = "SnapshotMismatchError";
30
+ }
31
+ mismatchType;
32
+ details;
33
+ };
34
+ var SnapshotDecodeError = class extends Error {
35
+ constructor(message, stepId, originalError) {
36
+ super(message);
37
+ this.stepId = stepId;
38
+ this.originalError = originalError;
39
+ this.name = "SnapshotDecodeError";
40
+ }
41
+ stepId;
42
+ originalError;
43
+ };
44
+ function looksLikeWorkflowSnapshot(obj) {
45
+ return typeof obj === "object" && obj !== null && "formatVersion" in obj && obj.formatVersion === 1 && "steps" in obj && typeof obj.steps === "object" && obj.steps !== null && "execution" in obj && typeof obj.execution === "object";
46
+ }
47
+ var isWorkflowSnapshot = looksLikeWorkflowSnapshot;
48
+ function validateSnapshot(obj) {
49
+ const errors = [];
50
+ if (typeof obj !== "object" || obj === null) {
51
+ return { valid: false, errors: ["Snapshot must be an object"] };
52
+ }
53
+ const snapshot = obj;
54
+ if (!("formatVersion" in snapshot)) {
55
+ errors.push("Missing required field: formatVersion");
56
+ } else if (snapshot.formatVersion !== 1) {
57
+ errors.push(`Invalid formatVersion: expected 1, got ${snapshot.formatVersion}`);
58
+ }
59
+ if (!("steps" in snapshot)) {
60
+ errors.push("Missing required field: steps");
61
+ } else if (typeof snapshot.steps !== "object" || snapshot.steps === null) {
62
+ errors.push("steps must be an object");
63
+ } else {
64
+ const steps = snapshot.steps;
65
+ for (const [stepId, stepResult] of Object.entries(steps)) {
66
+ if (typeof stepResult !== "object" || stepResult === null) {
67
+ errors.push(`steps["${stepId}"] must be an object`);
68
+ continue;
69
+ }
70
+ const step = stepResult;
71
+ if (!("ok" in step)) {
72
+ errors.push(`steps["${stepId}"] missing required field: ok`);
73
+ } else if (typeof step.ok !== "boolean") {
74
+ errors.push(`steps["${stepId}"].ok must be a boolean`);
75
+ } else if (step.ok === false) {
76
+ if (!("error" in step)) {
77
+ errors.push(`steps["${stepId}"] is error result but missing error field`);
78
+ }
79
+ if (!("cause" in step)) {
80
+ errors.push(`steps["${stepId}"] is error result but missing cause field`);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ if (!("execution" in snapshot)) {
86
+ errors.push("Missing required field: execution");
87
+ } else if (typeof snapshot.execution !== "object" || snapshot.execution === null) {
88
+ errors.push("execution must be an object");
89
+ } else {
90
+ const execution = snapshot.execution;
91
+ if (!("status" in execution)) {
92
+ errors.push("execution missing required field: status");
93
+ } else if (!["running", "completed", "failed"].includes(execution.status)) {
94
+ errors.push(`execution.status must be one of: running, completed, failed`);
95
+ }
96
+ if (!("lastUpdated" in execution)) {
97
+ errors.push("execution missing required field: lastUpdated");
98
+ } else if (typeof execution.lastUpdated !== "string") {
99
+ errors.push("execution.lastUpdated must be a string (ISO timestamp)");
100
+ }
101
+ }
102
+ if (errors.length > 0) {
103
+ return { valid: false, errors };
104
+ }
105
+ return { valid: true, snapshot: obj };
106
+ }
107
+ function assertValidSnapshot(obj) {
108
+ const result = validateSnapshot(obj);
109
+ if (!result.valid) {
110
+ throw new SnapshotFormatError(`Invalid snapshot format: ${result.errors[0]}`, result.errors);
111
+ }
112
+ return result.snapshot;
113
+ }
114
+ function mergeSnapshots(base, delta) {
115
+ const mergedSteps = /* @__PURE__ */ Object.create(null);
116
+ for (const [key, value] of Object.entries(base.steps)) {
117
+ if (Object.prototype.hasOwnProperty.call(base.steps, key)) {
118
+ mergedSteps[key] = value;
119
+ }
120
+ }
121
+ for (const [key, value] of Object.entries(delta.steps)) {
122
+ if (Object.prototype.hasOwnProperty.call(delta.steps, key)) {
123
+ mergedSteps[key] = value;
124
+ }
125
+ }
126
+ const mergedMetadata = base.metadata || delta.metadata ? { ...base.metadata, ...delta.metadata } : void 0;
127
+ const baseWarnings = (base.warnings || []).filter(
128
+ (w) => !Object.prototype.hasOwnProperty.call(delta.steps, w.stepId)
129
+ );
130
+ const mergedWarnings = [...baseWarnings, ...delta.warnings || []];
131
+ return {
132
+ formatVersion: 1,
133
+ steps: mergedSteps,
134
+ execution: { ...delta.execution },
135
+ metadata: mergedMetadata,
136
+ warnings: mergedWarnings.length > 0 ? mergedWarnings : void 0
137
+ };
138
+ }
139
+ var MAX_STRING_REPRESENTATION_LENGTH = 1e3;
140
+ function serializeError(error) {
141
+ const serialized = {
142
+ type: "error",
143
+ name: error.name,
144
+ message: error.message
145
+ };
146
+ if (error.stack) {
147
+ serialized.stack = error.stack;
148
+ }
149
+ const errorWithCause = error;
150
+ if (errorWithCause.cause !== void 0) {
151
+ if (errorWithCause.cause instanceof Error) {
152
+ serialized.cause = serializeError(errorWithCause.cause);
153
+ } else {
154
+ serialized.cause = serializeThrown(errorWithCause.cause);
155
+ }
156
+ }
157
+ return serialized;
158
+ }
159
+ function serializeThrown(value) {
160
+ let stringRepresentation;
161
+ let truncated = false;
162
+ try {
163
+ stringRepresentation = String(value);
164
+ if (stringRepresentation.length > MAX_STRING_REPRESENTATION_LENGTH) {
165
+ stringRepresentation = stringRepresentation.slice(0, MAX_STRING_REPRESENTATION_LENGTH);
166
+ truncated = true;
167
+ }
168
+ } catch {
169
+ stringRepresentation = "[unable to convert to string]";
170
+ }
171
+ const originalType = value === null ? "null" : typeof value === "object" ? value.constructor?.name ?? "Object" : typeof value;
172
+ let jsonValue;
173
+ try {
174
+ const serialized = JSON.stringify(value);
175
+ if (serialized !== void 0) {
176
+ jsonValue = JSON.parse(serialized);
177
+ }
178
+ } catch {
179
+ }
180
+ const result = {
181
+ type: "thrown",
182
+ originalType,
183
+ stringRepresentation
184
+ };
185
+ if (jsonValue !== void 0) {
186
+ result.value = jsonValue;
187
+ }
188
+ if (truncated) {
189
+ result.truncated = true;
190
+ }
191
+ return result;
192
+ }
193
+ function deserializeCauseNew(serialized) {
194
+ if (serialized.type === "error") {
195
+ const error = new Error(serialized.message);
196
+ error.name = serialized.name;
197
+ if (serialized.stack) {
198
+ error.stack = serialized.stack;
199
+ }
200
+ if (serialized.cause) {
201
+ error.cause = deserializeCauseNew(serialized.cause);
202
+ }
203
+ return error;
204
+ }
205
+ return serialized.value !== void 0 ? serialized.value : serialized.stringRepresentation;
206
+ }
207
+ function createMemoryCache(options = {}) {
208
+ const { maxSize, ttl } = options;
209
+ const cache = /* @__PURE__ */ new Map();
210
+ const isExpired = (entry) => {
211
+ const effectiveTtl = entry.entryTtl ?? ttl;
212
+ if (!effectiveTtl) return false;
213
+ return Date.now() - entry.timestamp > effectiveTtl;
214
+ };
215
+ const evictExpired = () => {
216
+ for (const [key, entry] of cache) {
217
+ if (isExpired(entry)) {
218
+ cache.delete(key);
219
+ }
220
+ }
221
+ };
222
+ const evictOldest = () => {
223
+ if (!maxSize || cache.size < maxSize) return;
224
+ let oldestKey;
225
+ let oldestTime = Infinity;
226
+ for (const [key, entry] of cache) {
227
+ if (entry.timestamp < oldestTime) {
228
+ oldestTime = entry.timestamp;
229
+ oldestKey = key;
230
+ }
231
+ }
232
+ if (oldestKey) {
233
+ cache.delete(oldestKey);
234
+ }
235
+ };
236
+ return {
237
+ get(key) {
238
+ evictExpired();
239
+ const entry = cache.get(key);
240
+ if (!entry) return void 0;
241
+ if (isExpired(entry)) {
242
+ cache.delete(key);
243
+ return void 0;
244
+ }
245
+ return entry.result;
246
+ },
247
+ set(key, result, options2) {
248
+ evictExpired();
249
+ evictOldest();
250
+ cache.set(key, { result, timestamp: Date.now(), entryTtl: options2?.ttl });
251
+ },
252
+ has(key) {
253
+ evictExpired();
254
+ const entry = cache.get(key);
255
+ if (!entry) return false;
256
+ if (isExpired(entry)) {
257
+ cache.delete(key);
258
+ return false;
259
+ }
260
+ return true;
261
+ },
262
+ delete(key) {
263
+ return cache.delete(key);
264
+ },
265
+ clear() {
266
+ cache.clear();
267
+ }
268
+ };
269
+ }
270
+
271
+ // src/workflow/cache-encoding.ts
272
+ function isCachedErrorCause(cause) {
273
+ return typeof cause === "object" && cause !== null && cause.__cachedMeta === true;
274
+ }
275
+ function encodeCachedError(error, meta, originalCause) {
276
+ return err(error, {
277
+ cause: { __cachedMeta: true, originalCause, meta }
278
+ });
279
+ }
280
+
281
+ // src/workflow/serialize-resume-state.ts
282
+ function serializeResumeState(state) {
283
+ const steps = [];
284
+ for (const [key, entry] of state.steps) {
285
+ const stepResult = entryToStepResult(entry);
286
+ steps.push([key, stepResult]);
287
+ }
288
+ return { kind: "ResumeState", steps };
289
+ }
290
+ function isSerializedResumeState(x) {
291
+ return typeof x === "object" && x !== null && x.kind === "ResumeState" && Array.isArray(x.steps);
292
+ }
293
+ function deserializeResumeState(raw) {
294
+ const steps = /* @__PURE__ */ new Map();
295
+ for (const [key, stepResult] of raw.steps) {
296
+ steps.set(key, stepResultToEntry(stepResult));
297
+ }
298
+ return { steps };
299
+ }
300
+ function entryToStepResult(entry) {
301
+ const { result, meta } = entry;
302
+ if (result.ok) {
303
+ return { ok: true, value: result.value };
304
+ }
305
+ const causeToSerialize = isCachedErrorCause(result.cause) ? result.cause.originalCause : result.cause;
306
+ const serializedCause = causeToSerialize instanceof Error ? serializeError(causeToSerialize) : serializeThrown(causeToSerialize);
307
+ const origin = meta?.origin === "throw" ? "throw" : "result";
308
+ return {
309
+ ok: false,
310
+ error: result.error,
311
+ cause: serializedCause,
312
+ meta: { origin }
313
+ };
314
+ }
315
+ function stepResultToEntry(sr) {
316
+ if (sr.ok) {
317
+ return { result: ok(sr.value) };
318
+ }
319
+ const deserializedCause = deserializeCauseNew(sr.cause);
320
+ const meta = sr.meta?.origin === "throw" ? { origin: "throw", thrown: deserializedCause } : { origin: "result", resultCause: deserializedCause };
321
+ const errorResult = encodeCachedError(sr.error, meta, deserializedCause);
322
+ return { result: errorResult, meta };
323
+ }
324
+
325
+ // src/workflow/store-contract.ts
326
+ function toResumeState(loaded) {
327
+ if (loaded === null) return void 0;
328
+ if (isResumeState(loaded)) return loaded;
329
+ return void 0;
330
+ }
331
+
332
+ // src/versioning.ts
333
+ function isMigrationError(error) {
334
+ return typeof error === "object" && error !== null && error.type === "MIGRATION_ERROR";
335
+ }
336
+ function isVersionIncompatibleError(error) {
337
+ return typeof error === "object" && error !== null && error.type === "VERSION_INCOMPATIBLE";
338
+ }
339
+ async function migrateState(state, targetVersion, migrations) {
340
+ let currentState = state.state;
341
+ let currentVersion = state.version;
342
+ if (currentVersion > targetVersion) {
343
+ return err({
344
+ type: "VERSION_INCOMPATIBLE",
345
+ stateVersion: currentVersion,
346
+ currentVersion: targetVersion,
347
+ reason: "State version is higher than current workflow version. Cannot downgrade."
348
+ });
349
+ }
350
+ if (currentVersion === targetVersion) {
351
+ return ok({ version: currentVersion, state: currentState });
352
+ }
353
+ while (currentVersion < targetVersion) {
354
+ const migration = migrations[currentVersion];
355
+ if (!migration) {
356
+ return err({
357
+ type: "VERSION_INCOMPATIBLE",
358
+ stateVersion: state.version,
359
+ currentVersion: targetVersion,
360
+ reason: `No migration found for version ${currentVersion} to ${currentVersion + 1}`
361
+ });
362
+ }
363
+ try {
364
+ currentState = await migration(currentState);
365
+ currentVersion++;
366
+ } catch (cause) {
367
+ return err({
368
+ type: "MIGRATION_ERROR",
369
+ fromVersion: currentVersion,
370
+ toVersion: currentVersion + 1,
371
+ cause
372
+ });
373
+ }
374
+ }
375
+ return ok({ version: currentVersion, state: currentState });
376
+ }
377
+ function createVersionedStateLoader(config) {
378
+ const { version, migrations = {}, strictVersioning = true } = config;
379
+ return async (versionedState) => {
380
+ if (!versionedState) {
381
+ return ok(void 0);
382
+ }
383
+ if (strictVersioning && versionedState.version > version) {
384
+ return err({
385
+ type: "VERSION_INCOMPATIBLE",
386
+ stateVersion: versionedState.version,
387
+ currentVersion: version,
388
+ reason: "Saved state is from a newer workflow version"
389
+ });
390
+ }
391
+ if (versionedState.version === version) {
392
+ return ok(versionedState.state);
393
+ }
394
+ const result = await migrateState(versionedState, version, migrations);
395
+ if (!result.ok) {
396
+ return result;
397
+ }
398
+ return ok(result.value.state);
399
+ };
400
+ }
401
+ function createVersionedState(state, version) {
402
+ return { version, state };
403
+ }
404
+ function parseVersionedState(json) {
405
+ if (!json) return null;
406
+ try {
407
+ const parsed = typeof json === "string" ? JSON.parse(json) : json;
408
+ if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || typeof parsed.version !== "number" || !("state" in parsed) || !parsed.state || !Array.isArray(parsed.state.steps)) {
409
+ return null;
410
+ }
411
+ const typedParsed = parsed;
412
+ const steps = new Map(typedParsed.state.steps);
413
+ return {
414
+ version: typedParsed.version,
415
+ state: { steps }
416
+ };
417
+ } catch {
418
+ return null;
419
+ }
420
+ }
421
+ function stringifyVersionedState(state) {
422
+ return JSON.stringify({
423
+ version: state.version,
424
+ state: {
425
+ steps: Array.from(state.state.steps.entries())
426
+ }
427
+ });
428
+ }
429
+ function createKeyRenameMigration(renames) {
430
+ return (state) => {
431
+ const newSteps = /* @__PURE__ */ new Map();
432
+ for (const [key, entry] of state.steps) {
433
+ const newKey = renames[key] ?? key;
434
+ newSteps.set(newKey, entry);
435
+ }
436
+ return { steps: newSteps };
437
+ };
438
+ }
439
+ function createKeyRemoveMigration(keysToRemove) {
440
+ const keysSet = new Set(keysToRemove);
441
+ return (state) => {
442
+ const newSteps = /* @__PURE__ */ new Map();
443
+ for (const [key, entry] of state.steps) {
444
+ if (!keysSet.has(key)) {
445
+ newSteps.set(key, entry);
446
+ }
447
+ }
448
+ return { steps: newSteps };
449
+ };
450
+ }
451
+ function createValueTransformMigration(transforms) {
452
+ return (state) => {
453
+ const newSteps = /* @__PURE__ */ new Map();
454
+ for (const [key, entry] of state.steps) {
455
+ const transform = transforms[key];
456
+ newSteps.set(key, transform ? transform(entry) : entry);
457
+ }
458
+ return { steps: newSteps };
459
+ };
460
+ }
461
+ function composeMigrations(migrations) {
462
+ return async (state) => {
463
+ let currentState = state;
464
+ for (const migration of migrations) {
465
+ currentState = await migration(currentState);
466
+ }
467
+ return currentState;
468
+ };
469
+ }
470
+ export {
471
+ SnapshotDecodeError,
472
+ SnapshotFormatError,
473
+ SnapshotMismatchError,
474
+ assertValidSnapshot,
475
+ composeMigrations,
476
+ createKeyRemoveMigration,
477
+ createKeyRenameMigration,
478
+ createMemoryCache,
479
+ createValueTransformMigration,
480
+ createVersionedState,
481
+ createVersionedStateLoader,
482
+ deserializeCauseNew,
483
+ deserializeResumeState,
484
+ isMigrationError,
485
+ isResumeState,
486
+ isSerializedResumeState,
487
+ isVersionIncompatibleError,
488
+ isWorkflowSnapshot,
489
+ looksLikeWorkflowSnapshot,
490
+ mergeSnapshots,
491
+ parseVersionedState,
492
+ serializeError,
493
+ serializeResumeState,
494
+ serializeThrown,
495
+ stringifyVersionedState,
496
+ toResumeState,
497
+ validateSnapshot
498
+ };
499
+ //# sourceMappingURL=persistence.js.map