@lostgradient/weft 0.16.0 → 0.17.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 (107) hide show
  1. package/README.md +1 -1
  2. package/dist/alerting/alert-manager.d.ts +5 -5
  3. package/dist/alerting/alert-manager.js +24 -6
  4. package/dist/alerting/index.d.ts +1 -1
  5. package/dist/alerting/types.d.ts +17 -13
  6. package/dist/alerting/types.js +5 -0
  7. package/dist/core/engine/disposal.js +7 -0
  8. package/dist/core/engine/engine-runtime-helpers.d.ts +3 -1
  9. package/dist/core/engine/engine-runtime-helpers.js +2 -2
  10. package/dist/core/engine/errors.d.ts +20 -0
  11. package/dist/core/engine/errors.js +8 -0
  12. package/dist/core/engine/index.d.ts +39 -17
  13. package/dist/core/engine/index.js +81 -9
  14. package/dist/core/engine/inline-launch-queue.d.ts +6 -2
  15. package/dist/core/engine/inline-launch-queue.js +41 -6
  16. package/dist/core/engine/internals.d.ts +2 -0
  17. package/dist/core/engine/lease-manager.d.ts +3 -2
  18. package/dist/core/engine/lease-manager.js +7 -3
  19. package/dist/core/engine/operations-time.js +6 -0
  20. package/dist/core/execution-strategy.d.ts +8 -0
  21. package/dist/core/inline-execution-strategy.d.ts +1 -0
  22. package/dist/core/inline-execution-strategy.js +33 -20
  23. package/dist/core/weft-error.d.ts +1 -1
  24. package/dist/core/weft-error.js +1 -0
  25. package/dist/core/worker-execution-strategy.d.ts +2 -0
  26. package/dist/core/worker-execution-strategy.js +7 -2
  27. package/dist/core/worker-turn-watchdog.d.ts +4 -1
  28. package/dist/core/worker-turn-watchdog.js +9 -4
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +1 -0
  31. package/dist/indexeddb.js +1 -1
  32. package/dist/json-schema.js +1 -1
  33. package/dist/mcp/tools.js +1 -3
  34. package/dist/server/dashboard-assets.d.ts +12 -1
  35. package/dist/server/dashboard-assets.js +145 -31
  36. package/dist/server/operations/aggregate-workflows.js +0 -7
  37. package/dist/server/operations/async-activity.js +5 -24
  38. package/dist/server/operations/bulk-cancel-workflows.js +3 -8
  39. package/dist/server/operations/bulk-delete-workflows.js +3 -8
  40. package/dist/server/operations/bulk-mutate-workflow-tags.js +3 -8
  41. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -10
  42. package/dist/server/operations/bulk-operation-helpers.js +0 -6
  43. package/dist/server/operations/bulk-retry-failed-workflows.js +3 -8
  44. package/dist/server/operations/bulk-signal-workflows.js +3 -8
  45. package/dist/server/operations/cancel-schedule.js +1 -3
  46. package/dist/server/operations/cancel-workflow.js +1 -3
  47. package/dist/server/operations/create-schedule.js +2 -3
  48. package/dist/server/operations/fork-workflow.js +2 -3
  49. package/dist/server/operations/get-checkpoint-at.js +1 -6
  50. package/dist/server/operations/get-registry.js +1 -7
  51. package/dist/server/operations/get-retention-overview.js +2 -15
  52. package/dist/server/operations/get-review.js +2 -15
  53. package/dist/server/operations/get-schedule.js +2 -8
  54. package/dist/server/operations/get-stream-chunks.js +2 -6
  55. package/dist/server/operations/get-system-lease.js +1 -7
  56. package/dist/server/operations/get-system-metrics.js +0 -4
  57. package/dist/server/operations/get-task-diagnostics.js +2 -13
  58. package/dist/server/operations/get-update-result.js +1 -6
  59. package/dist/server/operations/get-workflow-attributes.js +2 -15
  60. package/dist/server/operations/get-workflow-events.js +2 -15
  61. package/dist/server/operations/get-workflow-observability.js +2 -5
  62. package/dist/server/operations/get-workflow-result.js +0 -7
  63. package/dist/server/operations/get-workflow-timeline.js +1 -6
  64. package/dist/server/operations/get-workflow.d.ts +3 -6
  65. package/dist/server/operations/get-workflow.js +2 -12
  66. package/dist/server/operations/list-alerts.d.ts +5 -2
  67. package/dist/server/operations/list-alerts.js +2 -9
  68. package/dist/server/operations/list-checkpoints.js +1 -6
  69. package/dist/server/operations/list-reviews.js +0 -7
  70. package/dist/server/operations/list-schedules.js +3 -8
  71. package/dist/server/operations/list-task-queues.js +0 -4
  72. package/dist/server/operations/list-workers.js +0 -4
  73. package/dist/server/operations/list-workflows.js +0 -7
  74. package/dist/server/operations/pause-schedule.js +1 -3
  75. package/dist/server/operations/purge-workflows.js +2 -5
  76. package/dist/server/operations/query-workflow.js +4 -15
  77. package/dist/server/operations/replay-workflow.js +2 -6
  78. package/dist/server/operations/resume-schedule.js +1 -3
  79. package/dist/server/operations/resume-workflow.js +1 -3
  80. package/dist/server/operations/set-workflow-attributes.js +3 -15
  81. package/dist/server/operations/signal-workflow.js +3 -12
  82. package/dist/server/operations/single-workflow-tag-mutation.js +0 -7
  83. package/dist/server/operations/start-or-signal-workflow.js +2 -3
  84. package/dist/server/operations/start-workflow.js +2 -3
  85. package/dist/server/operations/storage-capabilities.js +1 -3
  86. package/dist/server/operations/storage.js +7 -13
  87. package/dist/server/operations/submit-review-decision.js +3 -12
  88. package/dist/server/operations/suspend-workflow.js +1 -3
  89. package/dist/server/operations/timeout-workflow.js +1 -3
  90. package/dist/server/operations/update-schedule.js +1 -3
  91. package/dist/server/operations/update-workflow.js +2 -3
  92. package/dist/server/operations/worker-drain.js +0 -8
  93. package/dist/server/rest-binding.d.ts +3 -2
  94. package/dist/server/route-model.d.ts +2 -0
  95. package/dist/server/route-model.js +1 -1
  96. package/dist/server/runtime/task-reconciliation.d.ts +10 -1
  97. package/dist/server/runtime/task-reconciliation.js +26 -2
  98. package/dist/server/serve-internals.js +12 -6
  99. package/dist/storage/indexeddb.js +28 -48
  100. package/dist/storage/testing.d.ts +6 -3
  101. package/dist/storage/testing.js +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/dist/worker/protocol-schemas.d.ts +2 -2
  105. package/dist/worker/protocol-schemas.js +2 -2
  106. package/dist/worker/protocol.js +1 -1
  107. package/package.json +1 -1
@@ -95,7 +95,8 @@ export type LeaseManagerOptions = {
95
95
  * - `currentEpochBytes()` returns the held epoch as bytes for Step-2 fencing
96
96
  * conditions; `null` before a successful acquire. Synchronous and stable across
97
97
  * renewals.
98
- * - `release()` best-effort relinquishes the lease (holder key only) on dispose.
98
+ * - `release()` best-effort relinquishes the lease (holder key only) on dispose
99
+ * and resolves to whether the holder delete committed.
99
100
  */
100
101
  export type LeaseManager = {
101
102
  acquire(): Promise<void>;
@@ -104,7 +105,7 @@ export type LeaseManager = {
104
105
  currentEpochBytes(): Uint8Array | null;
105
106
  /** Return a defensive, synchronous view of this process's last-known lease state. */
106
107
  health(): LeaseManagerHealth;
107
- release(): Promise<void>;
108
+ release(): Promise<boolean>;
108
109
  stop(): void;
109
110
  };
110
111
  /**
@@ -149,11 +149,15 @@ export function createLeaseManager(options) {
149
149
  if (inFlightRenewal !== null)
150
150
  await inFlightRenewal;
151
151
  if (lastHolderBytes === null)
152
- return;
152
+ return !0;
153
153
  try {
154
- if (await storageConditionalBatch(storage, [{ key: KEYS.leaseHolder(), expectedValue: lastHolderBytes }], [{ type: "delete", key: KEYS.leaseHolder() }]))
154
+ const deleted = await storageConditionalBatch(storage, [{ key: KEYS.leaseHolder(), expectedValue: lastHolderBytes }], [{ type: "delete", key: KEYS.leaseHolder() }]);
155
+ if (deleted)
155
156
  lastHolderBytes = null;
156
- } catch {}
157
+ return deleted;
158
+ } catch {
159
+ return !1;
160
+ }
157
161
  }
158
162
  function stop() {
159
163
  stopped = !0;
@@ -71,6 +71,12 @@ export function registerSleepResolver(internals, workflowId, operationId, resolv
71
71
  internals.sleepResolversByWorkflow.set(workflowId, workflowOperations);
72
72
  }
73
73
  workflowOperations.add(operationId);
74
+ const readinessWaiters = internals.sleepResolverReadyWaitersForTesting?.get(workflowId);
75
+ if (readinessWaiters !== void 0) {
76
+ internals.sleepResolverReadyWaitersForTesting?.delete(workflowId);
77
+ for (const notifyReady of readinessWaiters)
78
+ notifyReady();
79
+ }
74
80
  }
75
81
  export async function startDelayedWorkflow(internals, entry, callbacks) {
76
82
  const state = await callbacks.loadWorkflowState(entry.workflowId);
@@ -71,6 +71,14 @@
71
71
  */
72
72
  import type { OperationOutcome, WorkerOutboundMessage } from './types.ts';
73
73
  export interface ExecutionStrategy extends Disposable, AsyncDisposable {
74
+ /**
75
+ * Internal test seam for selecting a load-tolerant timeout around one
76
+ * intentionally wedged Worker turn. Production construction never sets it.
77
+ */
78
+ setWorkflowTurnTimeoutResolverForTesting?: (resolver: (turn: {
79
+ workflowId: string;
80
+ kind: 'run' | 'resume';
81
+ }) => number) => void;
74
82
  /**
75
83
  * Start a new workflow execution from the beginning.
76
84
  */
@@ -53,6 +53,7 @@ export declare class InlineExecutionStrategy implements ExecutionStrategy {
53
53
  clearParkedContext(workflowId: string): void;
54
54
  getAbortController(workflowId: string): AbortController | undefined;
55
55
  waitForWorkflowTurn(workflowId: string): Promise<void> | undefined;
56
+ abortWorkflowAdvanceForShutdown(workflowId: string): void;
56
57
  waitForWorkflowAdvance(workflowId: string): Promise<void> | undefined;
57
58
  hasGenerator(workflowId: string): boolean;
58
59
  /**
@@ -13,6 +13,7 @@ export class InlineExecutionStrategy {
13
13
  #parkedContexts;
14
14
  #workflowAdvances;
15
15
  #workflowTurns;
16
+ #shutdownAbortedWorkflowIds;
16
17
  #messageHandler;
17
18
  constructor(dependencies) {
18
19
  this.#dependencies = dependencies;
@@ -22,6 +23,7 @@ export class InlineExecutionStrategy {
22
23
  this.#parkedContexts = new Map;
23
24
  this.#workflowAdvances = new Map;
24
25
  this.#workflowTurns = new Map;
26
+ this.#shutdownAbortedWorkflowIds = new Set;
25
27
  this.#messageHandler = null;
26
28
  }
27
29
  onMessage(handler) {
@@ -91,6 +93,10 @@ export class InlineExecutionStrategy {
91
93
  waitForWorkflowTurn(workflowId) {
92
94
  return this.#workflowTurns.get(workflowId);
93
95
  }
96
+ abortWorkflowAdvanceForShutdown(workflowId) {
97
+ this.#shutdownAbortedWorkflowIds.add(workflowId);
98
+ this.#abortControllers.get(workflowId)?.abort();
99
+ }
94
100
  waitForWorkflowAdvance(workflowId) {
95
101
  return this.#workflowAdvances.get(workflowId);
96
102
  }
@@ -122,6 +128,7 @@ export class InlineExecutionStrategy {
122
128
  this.#parkedContexts.clear();
123
129
  this.#workflowAdvances.clear();
124
130
  this.#workflowTurns.clear();
131
+ this.#shutdownAbortedWorkflowIds.clear();
125
132
  this.#messageHandler = null;
126
133
  }
127
134
  async[Symbol.asyncDispose]() {
@@ -138,26 +145,7 @@ export class InlineExecutionStrategy {
138
145
  try {
139
146
  if (this.#abortControllers.get(workflowId)?.signal.aborted)
140
147
  return;
141
- const iterationResult = await advance();
142
- if (iterationResult.done) {
143
- this.#cleanup(workflowId, {
144
- preserveTrackedAdvance: !0,
145
- preserveTrackedTurn: !0
146
- });
147
- this.#emit({
148
- type: "completed",
149
- workflowId,
150
- result: iterationResult.value
151
- });
152
- return;
153
- }
154
- const operation = iterationResult.value;
155
- this.#emit({
156
- type: "checkpoint",
157
- workflowId,
158
- checkpoint: new ArrayBuffer(0),
159
- operationRequest: operation
160
- });
148
+ this.#handleIterationResult(workflowId, await advance());
161
149
  } catch (error) {
162
150
  this.#cleanup(workflowId, {
163
151
  preserveTrackedAdvance: !0,
@@ -177,6 +165,30 @@ export class InlineExecutionStrategy {
177
165
  }
178
166
  })());
179
167
  }
168
+ #handleIterationResult(workflowId, iterationResult) {
169
+ const shutdownAborted = this.#shutdownAbortedWorkflowIds.delete(workflowId);
170
+ if (!iterationResult.done && shutdownAborted)
171
+ return;
172
+ if (iterationResult.done) {
173
+ this.#cleanup(workflowId, {
174
+ preserveTrackedAdvance: !0,
175
+ preserveTrackedTurn: !0
176
+ });
177
+ this.#emit({
178
+ type: "completed",
179
+ workflowId,
180
+ result: iterationResult.value
181
+ });
182
+ return;
183
+ }
184
+ const operation = iterationResult.value;
185
+ this.#emit({
186
+ type: "checkpoint",
187
+ workflowId,
188
+ checkpoint: new ArrayBuffer(0),
189
+ operationRequest: operation
190
+ });
191
+ }
180
192
  #trackWorkflowAdvance(workflowId, pendingAdvance) {
181
193
  const trackedAdvance = pendingAdvance.finally(() => {
182
194
  if (this.#workflowAdvances.get(workflowId) === trackedAdvance)
@@ -212,5 +224,6 @@ export class InlineExecutionStrategy {
212
224
  this.#workflowAdvances.delete(workflowId);
213
225
  if (!options?.preserveTrackedTurn)
214
226
  this.#workflowTurns.delete(workflowId);
227
+ this.#shutdownAbortedWorkflowIds.delete(workflowId);
215
228
  }
216
229
  }
@@ -25,7 +25,7 @@
25
25
  * }
26
26
  * ```
27
27
  */
28
- export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
28
+ export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'EngineDisposalError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
29
29
  /**
30
30
  * Generic abstract base for all Weft library errors. The `TCode` parameter
31
31
  * makes each subclass's `code` its own literal type; the exported base surface
@@ -13,6 +13,7 @@ const publicWeftErrorCodeMap = {
13
13
  WorkflowTypeNotRegisteredForRecoveryError: !0,
14
14
  EngineCreateNameMismatchError: !0,
15
15
  EngineDisposedError: !0,
16
+ EngineDisposalError: !0,
16
17
  WorkflowNotFoundError: !0,
17
18
  WorkflowNotRegisteredError: !0,
18
19
  WorkflowConcurrencyLimitExceededError: !0,
@@ -2,10 +2,12 @@ import type { WorkerPool } from '../workers/pool.ts';
2
2
  import type { ExecutionStrategy } from './execution-strategy.ts';
3
3
  import type { OperationOutcome, WorkerOutboundMessage } from './types.ts';
4
4
  import type { WorkerExecutionStrategyOptions } from './worker-execution-strategy-options.ts';
5
+ import { type WorkerTurnTimeoutResolverForTesting } from './worker-turn-watchdog.ts';
5
6
  export declare class WorkerExecutionStrategy implements ExecutionStrategy {
6
7
  #private;
7
8
  constructor(pool: WorkerPool, options?: WorkerExecutionStrategyOptions);
8
9
  onMessage(handler: (message: WorkerOutboundMessage) => void | Promise<void>): void;
10
+ setWorkflowTurnTimeoutResolverForTesting(resolver: WorkerTurnTimeoutResolverForTesting): void;
9
11
  startWorkflow(parameters: {
10
12
  workflowId: string;
11
13
  workflowExecutionToken?: string;
@@ -16,7 +16,9 @@ import {
16
16
  import { WorkerProtocolGuard } from "./worker-protocol-guard.js";
17
17
  import { isWorkerLogMessage } from "./worker-protocol-log.js";
18
18
  import { WORKER_PROTOCOL_VERSION } from "./worker-protocol.js";
19
- import { WorkerTurnWatchdog } from "./worker-turn-watchdog.js";
19
+ import {
20
+ WorkerTurnWatchdog
21
+ } from "./worker-turn-watchdog.js";
20
22
 
21
23
  export class WorkerExecutionStrategy {
22
24
  #pool;
@@ -99,6 +101,9 @@ export class WorkerExecutionStrategy {
99
101
  onMessage(handler) {
100
102
  this.#messageHandler = handler;
101
103
  }
104
+ setWorkflowTurnTimeoutResolverForTesting(resolver) {
105
+ this.#turnWatchdog.setTimeoutResolverForTesting(resolver);
106
+ }
102
107
  startWorkflow(parameters) {
103
108
  this.#ownership.resetWorkflow(parameters.workflowId);
104
109
  this.#checkpointResumeState.resetWorkflow(parameters.workflowId);
@@ -315,7 +320,7 @@ export class WorkerExecutionStrategy {
315
320
  this.#discardWorkerAndFailWorkflows(turn.worker, {
316
321
  targetWorkflowId: turn.workflowId,
317
322
  targetCategory: "timeout",
318
- targetError: `Worker workflow turn timed out after ${this.#workflowTurnTimeoutMs}ms`,
323
+ targetError: `Worker workflow turn timed out after ${turn.timeoutMs}ms`,
319
324
  otherCategory: "timeout",
320
325
  otherError: `Worker discarded after workflow turn timed out: ${turn.workflowId}`
321
326
  });
@@ -3,11 +3,14 @@ export interface WorkerTurnState {
3
3
  workflowId: string;
4
4
  turnId: number;
5
5
  kind: 'run' | 'resume';
6
+ timeoutMs: number | undefined;
6
7
  }
8
+ export type WorkerTurnTimeoutResolverForTesting = (turn: Pick<WorkerTurnState, 'workflowId' | 'kind'>) => number;
7
9
  export declare class WorkerTurnWatchdog {
8
10
  #private;
9
11
  constructor(timeoutMs: number | undefined, onTimeout: (turn: WorkerTurnState) => void);
10
- begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind']): void;
12
+ begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind'], timeoutMs?: number | undefined): void;
13
+ setTimeoutResolverForTesting(resolver: WorkerTurnTimeoutResolverForTesting): void;
11
14
  clear(worker: Worker): void;
12
15
  clearAll(): void;
13
16
  get(worker: Worker): WorkerTurnState | undefined;
@@ -2,26 +2,31 @@ export class WorkerTurnWatchdog {
2
2
  #turnsByWorker = new Map;
3
3
  #timeoutMs;
4
4
  #onTimeout;
5
+ #timeoutResolverForTesting = null;
5
6
  constructor(timeoutMs, onTimeout) {
6
7
  this.#timeoutMs = timeoutMs;
7
8
  this.#onTimeout = onTimeout;
8
9
  }
9
- begin(worker, workflowId, turnId, kind) {
10
+ begin(worker, workflowId, turnId, kind, timeoutMs = this.#timeoutMs) {
10
11
  this.clear(worker);
11
- const turn = {
12
+ const resolvedTimeoutMs = this.#timeoutResolverForTesting?.({ workflowId, kind }) ?? timeoutMs, turn = {
12
13
  worker,
13
14
  workflowId,
14
15
  turnId,
15
16
  kind,
17
+ timeoutMs: resolvedTimeoutMs,
16
18
  timeout: null
17
19
  };
18
- if (this.#timeoutMs !== void 0)
20
+ if (resolvedTimeoutMs !== void 0)
19
21
  turn.timeout = setTimeout(() => {
20
22
  if (this.#turnsByWorker.get(worker) === turn)
21
23
  this.#onTimeout(turn);
22
- }, this.#timeoutMs);
24
+ }, resolvedTimeoutMs);
23
25
  this.#turnsByWorker.set(worker, turn);
24
26
  }
27
+ setTimeoutResolverForTesting(resolver) {
28
+ this.#timeoutResolverForTesting = resolver;
29
+ }
25
30
  clear(worker) {
26
31
  const turn = this.#turnsByWorker.get(worker);
27
32
  if (!turn)
package/dist/index.d.ts CHANGED
@@ -21,12 +21,12 @@ export type { WeftErrorCode } from './core/weft-error.ts';
21
21
  export { FAULT_CODE_TO_FAILURE_CATEGORY, failureCategoryForFaultCode, isFaultCode, } from './core/fault-code.ts';
22
22
  export type { FaultCode } from './core/fault-code.ts';
23
23
  export { DurableActivityScopeError, DurableActivityUnsupportedError, durableActivity, } from './core/context/durable-activity.ts';
24
- export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
24
+ export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposalError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
25
25
  export type { EngineCreateOptions, EngineLeaseHealth, EngineStateNamespace, LeaseLostReason, RecoverAllOptions, RecoveredWorkflowInfo, } from './core/engine';
26
26
  export { DEFAULT_CHECKPOINT_SIZE_WARNING_THRESHOLD, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_POLL_INTERVAL_MS, DEFAULT_RETRY_POLICY, DEFAULT_VISIBILITY_TIMEOUT_MS, HISTORY_CIRCUIT_BREAKER_REASON, WorkflowBuilderError, query, schedule, signal, update, workflow, } from './core/types';
27
27
  export type { ActivityArgsFor, ActivityCallOptions, ActivityCallable, ActivityContext, ActivityDefinition, ActivityEntryInput, ActivityFunction, ActivityMap, ActivityMapInput, ActivityObjectInput, ActivityResultFor, ActivityVerificationContext, ActivityVerificationPhase, ActivityVerificationResult, AnyActivityDefinition, AnyWorkflowDefinition, ArchiveAdapter, BuilderState, BuiltWorkflowDefinition, BulkCancelResult, BulkDeleteResult, BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationFilterSummary, BulkOperationOptions, BulkOperationPrincipal, BulkOperationScopeSummary, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, LaunchMetadata, ListFilter, ListOptions, MarkBuilderState, NormalizeActivities, NormalizedActivityEntry, NormalizedRetentionPolicy, PaginatedResult, PayloadSizePolicy, PendingAsyncActivityInfo, PendingAsyncActivityListOptions, PendingAsyncActivityPage, PendingReviewEntry, PurgeResult, QueryDefinition, QueryMap, QueryShape, RegisteredWorkflowDefinition, RestartLineage, RetentionOverview, RetentionPolicy, RetryPolicy, ReviewDecision, ReviewListEntry, ReviewListFilter, ReviewStatus, ScheduleDefinition, ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleQueuedRun, ScheduleSpec, ScheduleState, ScheduleStatus, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeDefinition, SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, Serializer, SignalDefinition, SignalDeliveryOptions, SignalMap, SignalPayload, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowConcurrencyOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFinalizerStatus, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowKeyedRaceResult, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowScheduleProvenance, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineOperationDetail, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
28
28
  export { AlertManager } from './alerting/index';
29
- export type { AlertAction, AlertMetric, AlertRule, AlertState, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
29
+ export type { AlertAction, AlertMetric, AlertRule, AlertStateSnapshot, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
30
30
  export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, ScheduleFiredEvent, ScheduleMissedFireEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, TaskResultDeadLetteredEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowDefinitionRegisteredEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTeardownEvent, WorkflowTimedOutEvent, } from './core/events';
31
31
  export type { TypedEventTarget, WeftEventMap, WorkflowRecoverySkippedReason, WorkflowTeardownStatus, } from './core/events';
32
32
  export { detectRuntime, hashBytes, hashString, sleep } from './runtime/portable';
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ export {
28
28
  ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME,
29
29
  Engine,
30
30
  EngineCreateNameMismatchError,
31
+ EngineDisposalError,
31
32
  EngineDisposedError,
32
33
  EngineLeaseAcquisitionTimeoutError,
33
34
  EngineLeaseCorruptedError,
package/dist/indexeddb.js CHANGED
@@ -1 +1 @@
1
- async function q(G,J){return await G.get(J)!==null}async function*N(G,J,Q){for await(let[X]of G.scan(J,Q))yield X}async function O(G,J){let Q=0;for await(let X of N(G,J))Q++;return Q}async function R(G,J){let Q=[];for await(let X of N(G,J))Q.push({type:"delete",key:X});if(Q.length===0)return 0;return await G.batch(Q),Q.length}async function h(G,J,Q){let X=[];for await(let Y of N(G,J,Q))X.push({type:"delete",key:Y});if(X.length===0)return 0;return await G.batch(X),X.length}function v(G,J,Q){if(!G.capabilities()[J])throw Error(`Feature "${Q}" requires storage capability "${J}", but this storage backend does not provide it.`)}var A=1e4;class E extends Error{code="StorageBatchOperationLimitExceededError";cap=A;count;target;constructor(G,J){super(`${G} count ${J} exceeds MAX_BATCH_OPERATIONS (${A}).`);this.name="StorageBatchOperationLimitExceededError",this.target=G,this.count=J}}function K(G,J){if(J>A)throw new E(G,J)}function M(G){return G.length>0?G.slice(0,-1)+String.fromCharCode(G.charCodeAt(G.length-1)+1):"ÿ"}function S(G,J={}){if(J.gt!==void 0&&G<=J.gt)return!1;if(J.gte!==void 0&&G<J.gte)return!1;if(J.lt!==void 0&&G>=J.lt)return!1;if(J.lte!==void 0&&G>J.lte)return!1;return!0}function b(G,J){if(G===null||J===null)return G===J;if(G.byteLength!==J.byteLength)return!1;for(let Q=0;Q<G.byteLength;Q++)if(G[Q]!==J[Q])return!1;return!0}async function m(G,J){if(G.has)return G.has(J);return q(G,J)}function x(G,J,Q){if(G.keys)return G.keys(J,Q);return N(G,J,Q)}async function y(G,J){if(G.count)return G.count(J);return O(G,J)}async function I(G,J){if(G.deletePrefix)return G.deletePrefix(J);return R(G,J)}async function g(G,J,Q){if(K("conditionalBatch conditions",J.length),K("conditionalBatch operations",Q.length),v(G,"conditionalBatch","storageConditionalBatch"),!G.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return G.conditionalBatch(J,Q)}function l(G){if(G===void 0)return;if(typeof G!=="number"||!Number.isInteger(G)||G<0)throw Error("deleteRange limit must be a finite non-negative integer");return G===0?0:G}function T(G){let J={},Q=!1;for(let Y of["gt","gte","lt","lte"]){let $=G[Y];if($===void 0)continue;if(typeof $!=="string")throw Error("deleteRange bounds must be strings");J[Y]=$,Q=!0}if(!Q)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let X=l(G.limit);if(X!==void 0)J.limit=X;return J}async function k(G,J,Q){let X=T(Q);if(G.deleteRange)return G.deleteRange(J,X);return h(G,J,X)}function p(G,J){let Q={key:G,open:!1};if(J.gte!==void 0&&J.gte>Q.key)Q.key=J.gte,Q.open=!1;if(J.gt!==void 0&&J.gt>=Q.key)Q.key=J.gt,Q.open=!0;return Q}function d(G,J){let Q={key:M(G),open:!0};if(J.lt!==void 0&&J.lt<=Q.key)Q.key=J.lt,Q.open=!0;if(J.lte!==void 0&&J.lte<Q.key)Q.key=J.lte,Q.open=!1;return Q}function c(G,J){let Q=p(G,J),X=d(G,J);if(Q.key>X.key||Q.key===X.key&&(Q.open||X.open))return null;return{lower:Q,upper:X}}function P(G){return G.replaceAll(/:+$/g,"")}function a(G,J){let Q=P(G),X=P(J);if(Q.length===0)return X;if(X.length===0)return Q;return`${Q}:${X}`}class C{#J;#Q;constructor(G,J){this.#J=G,this.#Q=P(J)}#G(G){if(this.#Q.length===0)return G;return G.length===0?`${this.#Q}:`:`${this.#Q}:${G}`}#X(G){return G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#G(J.key),value:J.value};return{type:"delete",key:this.#G(J.key)}})}#Y(G){if(this.#Q.length===0)return G;return G.slice(this.#Q.length+1)}#Z(G){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}#$(G={}){let J=this.#Z(G);if(G.reverse!==void 0)J.reverse=G.reverse;return J}#U(G){return this.#Z(G)}capabilities(){return this.#J.capabilities()}scoped(G){return new C(this.#J,a(this.#Q,G))}async get(G){return this.#J.get(this.#G(G))}async put(G,J){await this.#J.put(this.#G(G),J)}async delete(G){await this.#J.delete(this.#G(G))}async*scan(G,J){for await(let[Q,X]of this.#J.scan(this.#G(G),this.#$(J)))yield[this.#Y(Q),X]}async batch(G){K("batch operations",G.length),await this.#J.batch(this.#X(G))}async conditionalBatch(G,J){return g(this.#J,G.map((Q)=>({key:this.#G(Q.key),expectedValue:Q.expectedValue})),this.#X(J))}async has(G){return m(this.#J,this.#G(G))}async deletePrefix(G){return I(this.#J,this.#G(G))}async deleteRange(G,J){let Q=this.#U(T(J));return k(this.#J,this.#G(G),Q)}async*keys(G,J){for await(let Q of x(this.#J,this.#G(G),this.#$(J)))yield this.#Y(Q)}async count(G){return y(this.#J,this.#G(G))}[Symbol.dispose](){this.#J[Symbol.dispose]()}}function u(G,J){return new C(G,J)}var U="kv";function s(G=globalThis){let{indexedDB:J,IDBKeyRange:Q}=G;if(J===void 0||Q===void 0)throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");return{indexedDB:J,IDBKeyRange:Q}}function j(G){return new Promise((J,Q)=>{G.onsuccess=()=>J(G.result),G.onerror=()=>Q(G.error)})}function w(G,J){let Q=null,X=null,Y=null,$=(Z,V)=>{let H=Z??Error(V);if(X){let B=X;Q=null,X=null,B(H);return}Y=H};return G.onsuccess=()=>{if(!Q)return;let Z=Q;Q=null,X=null,Z(G.result)},G.onerror=()=>{$(G.error,"IndexedDB cursor request failed.")},J.onerror=()=>{$(J.error,"IndexedDB transaction failed.")},J.onabort=()=>{$(J.error,"IndexedDB transaction aborted.")},()=>{return new Promise((Z,V)=>{if(Y){let H=Y;Y=null,V(H);return}if(Q=Z,X=V,G.readyState==="done"){let H=Q;Q=null,X=null,H?.(G.result)}})}}class n{#J;#Q=null;#G;#X;constructor(G="weft",J=s()){this.#J=G,this.#X=J,this.#G=this.#Y()}capabilities(){return{persistence:"local",readAfterWrite:"linearizable",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}#Y(){let G=this.#X.indexedDB.open(this.#J,1);return G.onupgradeneeded=()=>{let J=G.result;if(!J.objectStoreNames.contains(U))J.createObjectStore(U)},j(G).then((J)=>{return this.#Q=J,J})}async get(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U),Y=await j(X.get(G));return Y===void 0?null:new Uint8Array(Y)}async put(G,J){let Y=(await this.#G).transaction(U,"readwrite").objectStore(U);await j(Y.put(J,G))}async delete(G){let X=(await this.#G).transaction(U,"readwrite").objectStore(U);await j(X.delete(G))}async has(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U);return await j(X.count(G))>0}async deletePrefix(G){let J=await this.#G,Q=M(G),X=this.#X.IDBKeyRange.bound(G,Q,!1,!0);return new Promise((Y,$)=>{let Z=J.transaction(U,"readwrite"),V=Z.objectStore(U),H=0,B=V.count(X);B.onsuccess=()=>{H=B.result,V.delete(X)},Z.oncomplete=()=>Y(H),Z.onerror=()=>$(Z.error)})}async deleteRange(G,J){let Q=T(J),X=c(G,Q);if(X===null)return 0;let Y=this.#X.IDBKeyRange.bound(X.lower.key,X.upper.key,X.lower.open,X.upper.open),$=await this.#G,{limit:Z}=Q;return new Promise((V,H)=>{let B=$.transaction(U,"readwrite"),z=B.objectStore(U),D=0;if(Z===void 0){let F=z.count(Y);F.onsuccess=()=>{D=F.result,z.delete(Y)}}else{let F=z.openCursor(Y,"next");F.onsuccess=()=>{let W=F.result;if(W===null||D>=Z)return;if(W.delete(),D++,D<Z)W.continue()}}B.oncomplete=()=>V(D),B.onerror=()=>H(B.error)})}async*scan(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=M(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openCursor(Z,V),D=0,F=w(z,H),W=!1;try{let L=await F();while(L){if(Q!==void 0&&D>=Q)break;let _=L.key;if(S(_,J))yield[_,new Uint8Array(L.value)],D++;L.continue(),L=await F()}W=!0}finally{if(!W)try{H.abort()}catch{}}}async batch(G){if(K("batch operations",G.length),G.length===0)return;let J=await this.#G;return new Promise((Q,X)=>{let Y=J.transaction(U,"readwrite"),$=Y.objectStore(U);for(let Z of G)if(Z.type==="put")$.put(Z.value,Z.key);else $.delete(Z.key);Y.oncomplete=()=>Q(),Y.onerror=()=>X(Y.error)})}async conditionalBatch(G,J){K("conditionalBatch conditions",G.length),K("conditionalBatch operations",J.length);let Q=await this.#G;return new Promise((X,Y)=>{let $=Q.transaction(U,"readwrite"),Z=$.objectStore(U),V=!1,H=!1,B=(F,W)=>{if(V)return;V=!0,Y(F??Error(W))};$.oncomplete=()=>{if(V)return;V=!0,X(!0)},$.onerror=()=>{B($.error,"IndexedDB conditionalBatch transaction failed.")},$.onabort=()=>{if(V)return;if(V=!0,H){X(!1);return}Y($.error??Error("IndexedDB conditionalBatch transaction aborted."))};let z=()=>{for(let F of J)if(F.type==="put")Z.put(F.value,F.key);else Z.delete(F.key)},D=(F)=>{if(F>=G.length){z();return}let W=G[F],L=Z.get(W.key);L.onsuccess=()=>{let _=L.result,f=_===void 0?null:new Uint8Array(_);if(!b(f,W.expectedValue)){H=!0,$.abort();return}D(F+1)},L.onerror=()=>{B(L.error,"IndexedDB conditionalBatch condition check failed.")}};D(0)})}async*keys(G,J={}){let{limit:Q,reverse:X}=J,Y=await this.#G,$=M(G),Z=this.#X.IDBKeyRange.bound(G,$,!1,!0),V=X?"prev":"next",H=Y.transaction(U,"readonly"),z=H.objectStore(U).openKeyCursor(Z,V),D=0,F=w(z,H),W=!1;try{let L=await F();while(L){if(Q!==void 0&&D>=Q)break;let _=L.key;if(S(_,J))yield _,D++;L.continue(),L=await F()}W=!0}finally{if(!W)try{H.abort()}catch{}}}async count(G){let J=await this.#G,Q=M(G),Y=J.transaction(U,"readonly").objectStore(U);return j(Y.count(this.#X.IDBKeyRange.bound(G,Q,!1,!0)))}scoped(G){return u(this,G)}[Symbol.dispose](){if(this.#Q)this.#Q.close(),this.#Q=null}}export{n as IndexedDBStorage};
1
+ async function O(G,J){return await G.get(J)!==null}async function*T(G,J,Q){for await(let[X]of G.scan(J,Q))yield X}async function R(G,J){let Q=0;for await(let X of T(G,J))Q++;return Q}async function h(G,J){let Q=[];for await(let X of T(G,J))Q.push({type:"delete",key:X});if(Q.length===0)return 0;return await G.batch(Q),Q.length}async function v(G,J,Q){let X=[];for await(let Y of T(G,J,Q))X.push({type:"delete",key:Y});if(X.length===0)return 0;return await G.batch(X),X.length}function E(G,J,Q){if(!G.capabilities()[J])throw Error(`Feature "${Q}" requires storage capability "${J}", but this storage backend does not provide it.`)}var P=1e4;class b extends Error{code="StorageBatchOperationLimitExceededError";cap=P;count;target;constructor(G,J){super(`${G} count ${J} exceeds MAX_BATCH_OPERATIONS (${P}).`);this.name="StorageBatchOperationLimitExceededError",this.target=G,this.count=J}}function W(G,J){if(J>P)throw new b(G,J)}function M(G){return G.length>0?G.slice(0,-1)+String.fromCharCode(G.charCodeAt(G.length-1)+1):"ÿ"}function m(G,J={}){if(J.gt!==void 0&&G<=J.gt)return!1;if(J.gte!==void 0&&G<J.gte)return!1;if(J.lt!==void 0&&G>=J.lt)return!1;if(J.lte!==void 0&&G>J.lte)return!1;return!0}function x(G,J){if(G===null||J===null)return G===J;if(G.byteLength!==J.byteLength)return!1;for(let Q=0;Q<G.byteLength;Q++)if(G[Q]!==J[Q])return!1;return!0}async function y(G,J){if(G.has)return G.has(J);return O(G,J)}function I(G,J,Q){if(G.keys)return G.keys(J,Q);return T(G,J,Q)}async function g(G,J){if(G.count)return G.count(J);return R(G,J)}async function k(G,J){if(G.deletePrefix)return G.deletePrefix(J);return h(G,J)}async function c(G,J,Q){if(W("conditionalBatch conditions",J.length),W("conditionalBatch operations",Q.length),E(G,"conditionalBatch","storageConditionalBatch"),!G.conditionalBatch)throw Error("This storage backend reports conditionalBatch capability but does not implement the conditionalBatch() method.");return G.conditionalBatch(J,Q)}function d(G){if(G===void 0)return;if(typeof G!=="number"||!Number.isInteger(G)||G<0)throw Error("deleteRange limit must be a finite non-negative integer");return G===0?0:G}function A(G){let J={},Q=!1;for(let Y of["gt","gte","lt","lte"]){let Z=G[Y];if(Z===void 0)continue;if(typeof Z!=="string")throw Error("deleteRange bounds must be strings");J[Y]=Z,Q=!0}if(!Q)throw Error("deleteRange requires at least one of gt/gte/lt/lte; use deletePrefix to delete a whole prefix");let X=d(G.limit);if(X!==void 0)J.limit=X;return J}async function u(G,J,Q){let X=A(Q);if(G.deleteRange)return G.deleteRange(J,X);return v(G,J,X)}function a(G,J){let Q={key:G,open:!1};if(J.gte!==void 0&&J.gte>Q.key)Q.key=J.gte,Q.open=!1;if(J.gt!==void 0&&J.gt>=Q.key)Q.key=J.gt,Q.open=!0;return Q}function s(G,J){let Q={key:M(G),open:!0};if(J.lt!==void 0&&J.lt<=Q.key)Q.key=J.lt,Q.open=!0;if(J.lte!==void 0&&J.lte<Q.key)Q.key=J.lte,Q.open=!1;return Q}function w(G,J){let Q=a(G,J),X=s(G,J);if(Q.key>X.key||Q.key===X.key&&(Q.open||X.open))return null;return{lower:Q,upper:X}}function q(G){return G.replaceAll(/:+$/g,"")}function n(G,J){let Q=q(G),X=q(J);if(Q.length===0)return X;if(X.length===0)return Q;return`${Q}:${X}`}class C{#J;#Q;constructor(G,J){this.#J=G,this.#Q=q(J)}#G(G){if(this.#Q.length===0)return G;return G.length===0?`${this.#Q}:`:`${this.#Q}:${G}`}#X(G){return G.map((J)=>{if(J.type==="put")return{type:"put",key:this.#G(J.key),value:J.value};return{type:"delete",key:this.#G(J.key)}})}#Y(G){if(this.#Q.length===0)return G;return G.slice(this.#Q.length+1)}#Z(G){let J={};if(G.limit!==void 0)J.limit=G.limit;if(G.gt!==void 0)J.gt=this.#G(G.gt);if(G.gte!==void 0)J.gte=this.#G(G.gte);if(G.lt!==void 0)J.lt=this.#G(G.lt);if(G.lte!==void 0)J.lte=this.#G(G.lte);return J}#$(G={}){let J=this.#Z(G);if(G.reverse!==void 0)J.reverse=G.reverse;return J}#U(G){return this.#Z(G)}capabilities(){return this.#J.capabilities()}scoped(G){return new C(this.#J,n(this.#Q,G))}async get(G){return this.#J.get(this.#G(G))}async put(G,J){await this.#J.put(this.#G(G),J)}async delete(G){await this.#J.delete(this.#G(G))}async*scan(G,J){for await(let[Q,X]of this.#J.scan(this.#G(G),this.#$(J)))yield[this.#Y(Q),X]}async batch(G){W("batch operations",G.length),await this.#J.batch(this.#X(G))}async conditionalBatch(G,J){return c(this.#J,G.map((Q)=>({key:this.#G(Q.key),expectedValue:Q.expectedValue})),this.#X(J))}async has(G){return y(this.#J,this.#G(G))}async deletePrefix(G){return k(this.#J,this.#G(G))}async deleteRange(G,J){let Q=this.#U(A(J));return u(this.#J,this.#G(G),Q)}async*keys(G,J){for await(let Q of I(this.#J,this.#G(G),this.#$(J)))yield this.#Y(Q)}async count(G){return g(this.#J,this.#G(G))}[Symbol.dispose](){this.#J[Symbol.dispose]()}}function f(G,J){return new C(G,J)}var U="kv";function i(G=globalThis){let{indexedDB:J,IDBKeyRange:Q}=G;if(J===void 0||Q===void 0)throw Error("IndexedDBStorage requires both indexedDB and IDBKeyRange runtime globals.");return{indexedDB:J,IDBKeyRange:Q}}function K(G){return new Promise((J,Q)=>{G.onsuccess=()=>J(G.result),G.onerror=()=>Q(G.error)})}function t(G,J){let Q=null,X=null,Y=null,Z=($,H)=>{let F=$??Error(H);if(X){let L=X;Q=null,X=null,L(F);return}Y=F};return G.onsuccess=()=>{if(!Q)return;let $=Q;Q=null,X=null,$(G.result)},G.onerror=()=>{Z(G.error,"IndexedDB cursor request failed.")},J.onerror=()=>{Z(J.error,"IndexedDB transaction failed.")},J.onabort=()=>{Z(J.error,"IndexedDB transaction aborted.")},()=>{return new Promise(($,H)=>{if(Y){let F=Y;Y=null,H(F);return}if(Q=$,X=H,G.readyState==="done"){let F=Q;Q=null,X=null,F?.(G.result)}})}}async function*l(G,J,Q,X,Y,Z){let{limit:$,reverse:H}=X,F=M(Q),L=J.bound(Q,F,!1,!0),z=H?"prev":"next",B=G.transaction(U,"readonly"),V=B.objectStore(U),D=Y(V,L,z),_=t(D,B),j=0,S=!1;try{let N=await _();while(N){if($!==void 0&&j>=$)break;let p=N.key;if(m(p,X))yield Z(N),j++;N.continue(),N=await _()}S=!0}finally{if(!S)try{B.abort()}catch{}}}class r{#J;#Q=null;#G;#X;constructor(G="weft",J=i()){this.#J=G,this.#X=J,this.#G=this.#Y()}capabilities(){return{persistence:"local",readAfterWrite:"linearizable",scanConsistency:"best-effort",atomicBatch:!0,conditionalBatch:!0,boundedRangeDelete:!0}}#Y(){let G=this.#X.indexedDB.open(this.#J,1);return G.onupgradeneeded=()=>{let J=G.result;if(!J.objectStoreNames.contains(U))J.createObjectStore(U)},K(G).then((J)=>{return this.#Q=J,J})}async get(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U),Y=await K(X.get(G));return Y===void 0?null:new Uint8Array(Y)}async put(G,J){let Y=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(Y.put(J,G))}async delete(G){let X=(await this.#G).transaction(U,"readwrite").objectStore(U);await K(X.delete(G))}async has(G){let X=(await this.#G).transaction(U,"readonly").objectStore(U);return await K(X.count(G))>0}async deletePrefix(G){let J=await this.#G,Q=M(G),X=this.#X.IDBKeyRange.bound(G,Q,!1,!0);return new Promise((Y,Z)=>{let $=J.transaction(U,"readwrite"),H=$.objectStore(U),F=0,L=H.count(X);L.onsuccess=()=>{F=L.result,H.delete(X)},$.oncomplete=()=>Y(F),$.onerror=()=>Z($.error)})}async deleteRange(G,J){let Q=A(J),X=w(G,Q);if(X===null)return 0;let Y=this.#X.IDBKeyRange.bound(X.lower.key,X.upper.key,X.lower.open,X.upper.open),Z=await this.#G,{limit:$}=Q;return new Promise((H,F)=>{let L=Z.transaction(U,"readwrite"),z=L.objectStore(U),B=0;if($===void 0){let V=z.count(Y);V.onsuccess=()=>{B=V.result,z.delete(Y)}}else{let V=z.openCursor(Y,"next");V.onsuccess=()=>{let D=V.result;if(D===null||B>=$)return;if(D.delete(),B++,B<$)D.continue()}}L.oncomplete=()=>H(B),L.onerror=()=>F(L.error)})}async*scan(G,J={}){let Q=await this.#G;yield*l(Q,this.#X.IDBKeyRange,G,J,(X,Y,Z)=>X.openCursor(Y,Z),(X)=>[X.key,new Uint8Array(X.value)])}async batch(G){if(W("batch operations",G.length),G.length===0)return;let J=await this.#G;return new Promise((Q,X)=>{let Y=J.transaction(U,"readwrite"),Z=Y.objectStore(U);for(let $ of G)if($.type==="put")Z.put($.value,$.key);else Z.delete($.key);Y.oncomplete=()=>Q(),Y.onerror=()=>X(Y.error)})}async conditionalBatch(G,J){W("conditionalBatch conditions",G.length),W("conditionalBatch operations",J.length);let Q=await this.#G;return new Promise((X,Y)=>{let Z=Q.transaction(U,"readwrite"),$=Z.objectStore(U),H=!1,F=!1,L=(V,D)=>{if(H)return;H=!0,Y(V??Error(D))};Z.oncomplete=()=>{if(H)return;H=!0,X(!0)},Z.onerror=()=>{L(Z.error,"IndexedDB conditionalBatch transaction failed.")},Z.onabort=()=>{if(H)return;if(H=!0,F){X(!1);return}Y(Z.error??Error("IndexedDB conditionalBatch transaction aborted."))};let z=()=>{for(let V of J)if(V.type==="put")$.put(V.value,V.key);else $.delete(V.key)},B=(V)=>{if(V>=G.length){z();return}let D=G[V],_=$.get(D.key);_.onsuccess=()=>{let j=_.result,S=j===void 0?null:new Uint8Array(j);if(!x(S,D.expectedValue)){F=!0,Z.abort();return}B(V+1)},_.onerror=()=>{L(_.error,"IndexedDB conditionalBatch condition check failed.")}};B(0)})}async*keys(G,J={}){let Q=await this.#G;yield*l(Q,this.#X.IDBKeyRange,G,J,(X,Y,Z)=>X.openKeyCursor(Y,Z),(X)=>X.key)}async count(G){let J=await this.#G,Q=M(G),Y=J.transaction(U,"readonly").objectStore(U);return K(Y.count(this.#X.IDBKeyRange.bound(G,Q,!1,!0)))}scoped(G){return f(this,G)}[Symbol.dispose](){if(this.#Q)this.#Q.close(),this.#Q=null}}export{r as IndexedDBStorage};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- var O=import.meta.require,T=(j,q,z)=>{if(q!=null){if(typeof q!=="object"&&typeof q!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let A;if(z)A=q[Symbol.asyncDispose];if(A===void 0)A=q[Symbol.dispose];if(typeof A!=="function")throw TypeError("Object not disposable");j.push([z,A,q])}else if(z)j.push([z]);return q},y=(j,q,z)=>{let A=(G)=>q=z?new SuppressedError(G,q,"An error was suppressed during disposal"):(z=!0,G),H=(G)=>{while(G=j.pop())try{var $=G[1]&&G[1].call(G[2]);if(G[0])return Promise.resolve($).then(H,(Q)=>(A(Q),H()))}catch(Q){A(Q)}if(z)throw q};return H()};class X extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}}var B={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,WorkflowConcurrencyLimitExceededError:!0,WorkflowSuspendNotSupportedError:!0,ActivityResolutionError:!0,BranchTopologyChangedError:!0,PersistedDataIncompatibleError:!0,WorkflowTimeoutError:!0,HttpClientError:!0,WorkerProtocolIncompatibleError:!0,UpdateTimeoutError:!0,UpdateValidationError:!0,WorkflowTerminalError:!0,WorkflowBuilderError:!0,VersionMismatchError:!0,EffectReplayConflictError:!0,ReviewTimeoutError:!0,AtomicStateConflictError:!0,StandardSchemaValidationError:!0,ActivityReconciliationCapabilityError:!0,ActivityReconciliationConflictError:!0,ActivityReconciliationIndeterminateError:!0,DurableActivityScopeError:!0,DurableActivityUnsupportedError:!0,AsyncActivityTokenNotFoundError:!0,ActivityScheduleToCloseTimeoutError:!0,ActivityPerAttemptTimeoutError:!0,PayloadSizeExceededError:!0,StartOrSignalConflictError:!0,WorkflowTeardownPendingError:!0,IdempotencyKeyPurgedError:!0},R=new Set(Object.keys(B));class K extends X{fieldName;operation;issues;constructor(j){super("StandardSchemaValidationError",M(j.fieldName,j.operation,j.issues));this.fieldName=j.fieldName,this.operation=j.operation,this.issues=j.issues}}async function Z(j,q,z){let A=j["~standard"];if(!D(A))throw TypeError(`Schema for ${z.fieldName} does not provide runtime validation. Attach a Standard Schema validator (Zod, Valibot, or another vendor) or supply a runtime-validating schema at this boundary.`);let H=await A.validate(q);if(H.issues===void 0)return H.value;throw new K({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(U)})}function Y(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
2
+ var O=import.meta.require,T=(j,q,z)=>{if(q!=null){if(typeof q!=="object"&&typeof q!=="function")throw TypeError('Object expected to be assigned to "using" declaration');let A;if(z)A=q[Symbol.asyncDispose];if(A===void 0)A=q[Symbol.dispose];if(typeof A!=="function")throw TypeError("Object not disposable");j.push([z,A,q])}else if(z)j.push([z]);return q},y=(j,q,z)=>{let A=(G)=>q=z?new SuppressedError(G,q,"An error was suppressed during disposal"):(z=!0,G),H=(G)=>{while(G=j.pop())try{var $=G[1]&&G[1].call(G[2]);if(G[0])return Promise.resolve($).then(H,(Q)=>(A(Q),H()))}catch(Q){A(Q)}if(z)throw q};return H()};class X extends Error{code;constructor(j,q,z){super(q,z);this.code=j,this.name=j}}var B={WorkflowAlreadyExistsError:!0,BulkDeleteRequiresTerminalWorkflowsError:!0,BulkOperationConfirmationError:!0,WorkflowTypeNotRegisteredForRecoveryError:!0,EngineCreateNameMismatchError:!0,EngineDisposedError:!0,EngineDisposalError:!0,WorkflowNotFoundError:!0,WorkflowNotRegisteredError:!0,WorkflowConcurrencyLimitExceededError:!0,WorkflowSuspendNotSupportedError:!0,ActivityResolutionError:!0,BranchTopologyChangedError:!0,PersistedDataIncompatibleError:!0,WorkflowTimeoutError:!0,HttpClientError:!0,WorkerProtocolIncompatibleError:!0,UpdateTimeoutError:!0,UpdateValidationError:!0,WorkflowTerminalError:!0,WorkflowBuilderError:!0,VersionMismatchError:!0,EffectReplayConflictError:!0,ReviewTimeoutError:!0,AtomicStateConflictError:!0,StandardSchemaValidationError:!0,ActivityReconciliationCapabilityError:!0,ActivityReconciliationConflictError:!0,ActivityReconciliationIndeterminateError:!0,DurableActivityScopeError:!0,DurableActivityUnsupportedError:!0,AsyncActivityTokenNotFoundError:!0,ActivityScheduleToCloseTimeoutError:!0,ActivityPerAttemptTimeoutError:!0,PayloadSizeExceededError:!0,StartOrSignalConflictError:!0,WorkflowTeardownPendingError:!0,IdempotencyKeyPurgedError:!0},R=new Set(Object.keys(B));class K extends X{fieldName;operation;issues;constructor(j){super("StandardSchemaValidationError",M(j.fieldName,j.operation,j.issues));this.fieldName=j.fieldName,this.operation=j.operation,this.issues=j.issues}}async function Z(j,q,z){let A=j["~standard"];if(!D(A))throw TypeError(`Schema for ${z.fieldName} does not provide runtime validation. Attach a Standard Schema validator (Zod, Valibot, or another vendor) or supply a runtime-validating schema at this boundary.`);let H=await A.validate(q);if(H.issues===void 0)return H.value;throw new K({fieldName:z.fieldName,operation:z.operation,issues:H.issues.map(U)})}function Y(j){return j.map((q)=>q.path===""?q.message:`${q.path}: ${q.message}`).join(`
3
3
  `)}function D(j){return typeof j.validate==="function"}function U(j){return{message:j.message,path:b(j.path)}}function b(j){if(j===void 0||j.length===0)return"";let q="";for(let z of j)q+="/",q+=w(z);return q}function w(j){let q=F(j)?j.key:j;return J(String(q))}function F(j){return j!==null&&typeof j==="object"&&"key"in j}function J(j){return j.replace(/~/g,"~0").replace(/\//g,"~1")}function M(j,q,z){return`Validation failed for ${q===void 0?j:`${q} ${j}`}:
4
4
  ${Y(z)}`}var V=Y,k=K,P=Z;export{P as validateStandardSchema,V as formatStandardSchemaIssues,k as StandardSchemaValidationError};
package/dist/mcp/tools.js CHANGED
@@ -113,9 +113,7 @@ function withWorkflowToolTimeoutParameter(schema) {
113
113
  };
114
114
  }
115
115
  function parseWorkflowToolArguments(argumentsValue) {
116
- if (argumentsValue === null || typeof argumentsValue !== "object" || Array.isArray(argumentsValue))
117
- return { input: argumentsValue, timeoutMs: DEFAULT_WORKFLOW_TOOL_TIMEOUT_MS };
118
- const record = argumentsValue, timeoutMs = parseWorkflowToolTimeoutMs(record.timeoutMs);
116
+ const record = requireObject(argumentsValue), timeoutMs = parseWorkflowToolTimeoutMs(record.timeoutMs);
119
117
  return { input: record.input, timeoutMs };
120
118
  }
121
119
  function parseWorkflowToolTimeoutMs(value) {
@@ -1,3 +1,13 @@
1
+ import * as fileSystem from 'node:fs';
2
+ type DashboardAssetFileSystem = {
3
+ constants: Pick<typeof fileSystem.constants, 'O_RDONLY' | 'O_NOFOLLOW' | 'O_NONBLOCK'>;
4
+ realpathSync: (path: string) => string;
5
+ statSync: (path: string) => fileSystem.Stats;
6
+ openSync: (path: string, flags: Parameters<typeof fileSystem.openSync>[1], mode?: Parameters<typeof fileSystem.openSync>[2]) => number;
7
+ fstatSync: (descriptor: number) => fileSystem.Stats;
8
+ read: (descriptor: number, buffer: NodeJS.ArrayBufferView, offset: number, length: number, position: number | null) => Promise<number>;
9
+ closeSync: (descriptor: number) => void;
10
+ };
1
11
  /**
2
12
  * Static files belonging to an externally supplied dashboard.
3
13
  *
@@ -23,4 +33,5 @@ export interface ResolvedDashboardAssets {
23
33
  directory: string;
24
34
  }
25
35
  export declare function resolveDashboardAssets(value: unknown, pageRoutes: readonly string[]): ResolvedDashboardAssets;
26
- export declare function createDashboardAssetRoute(assets: ResolvedDashboardAssets): Partial<Record<'GET' | 'HEAD', (request: Request) => Response>>;
36
+ export declare function createDashboardAssetRoute(assets: ResolvedDashboardAssets, assetFileSystem?: DashboardAssetFileSystem): Partial<Record<'GET' | 'HEAD', (request: Request) => Response>>;
37
+ export {};