@lostgradient/weft 0.23.0 → 0.24.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.
- package/README.md +72 -4
- package/dist/cli/codegen-emit-dedup.d.ts +81 -0
- package/dist/cli/codegen-emit-dedup.js +45 -0
- package/dist/cli/codegen-emit-registry.d.ts +90 -0
- package/dist/cli/codegen-emit-registry.js +50 -0
- package/dist/cli/codegen-emit.d.ts +26 -39
- package/dist/cli/codegen-emit.js +4 -27
- package/dist/cli/codegen-validate.d.ts +49 -0
- package/dist/cli/codegen-validate.js +186 -0
- package/dist/cli/codegen.js +6 -87
- package/dist/cli/generated/operation-catalog.snapshot.json +287 -3
- package/dist/cli/generated/operation-client.generated.d.ts +324 -10
- package/dist/cli/generated/operation-client.generated.js +12 -0
- package/dist/cli/output.js +1 -1
- package/dist/cli/storage-factory.js +2 -0
- package/dist/cli/workflow-commands.js +2 -0
- package/dist/cli-main.js +1 -1
- package/dist/core/application-payload-digest.d.ts +42 -0
- package/dist/core/application-payload-digest.js +76 -0
- package/dist/core/application-primitive-abort.d.ts +50 -0
- package/dist/core/application-primitive-abort.js +40 -0
- package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
- package/dist/core/application-primitive-attempt-registry.js +73 -0
- package/dist/core/application-primitive-codec.d.ts +36 -0
- package/dist/core/application-primitive-codec.js +56 -0
- package/dist/core/application-primitive-commit.d.ts +67 -0
- package/dist/core/application-primitive-commit.js +66 -0
- package/dist/core/application-primitive-guards.d.ts +62 -0
- package/dist/core/application-primitive-guards.js +89 -0
- package/dist/core/application-primitive-payload.d.ts +29 -0
- package/dist/core/application-primitive-payload.js +65 -0
- package/dist/core/application-primitive-timing.d.ts +18 -0
- package/dist/core/application-primitive-timing.js +22 -0
- package/dist/core/atomic-state.js +2 -0
- package/dist/core/catalog/codec.d.ts +40 -0
- package/dist/core/catalog/codec.js +45 -0
- package/dist/core/catalog/errors.d.ts +104 -0
- package/dist/core/catalog/errors.js +41 -0
- package/dist/core/catalog/index.d.ts +25 -0
- package/dist/core/catalog/index.js +15 -0
- package/dist/core/catalog/reference-counts.d.ts +105 -0
- package/dist/core/catalog/reference-counts.js +28 -0
- package/dist/core/catalog/removal.d.ts +52 -0
- package/dist/core/catalog/removal.js +14 -0
- package/dist/core/catalog/storage-io.d.ts +78 -0
- package/dist/core/catalog/storage-io.js +106 -0
- package/dist/core/catalog/types.d.ts +108 -0
- package/dist/core/catalog/types.js +0 -0
- package/dist/core/catalog/workflow-catalog.d.ts +165 -0
- package/dist/core/catalog/workflow-catalog.js +198 -0
- package/dist/core/compare-codepoint.d.ts +13 -0
- package/dist/core/compare-codepoint.js +7 -0
- package/dist/core/compression.js +2 -0
- package/dist/core/context/attributes.d.ts +1 -1
- package/dist/core/context/durable-operations.d.ts +2 -2
- package/dist/core/context/index.js +5 -3
- package/dist/core/context/state-namespace.d.ts +1 -1
- package/dist/core/contract/build.d.ts +64 -0
- package/dist/core/contract/build.js +99 -0
- package/dist/core/contract/compatibility.d.ts +187 -0
- package/dist/core/contract/compatibility.js +37 -0
- package/dist/core/contract/failure.d.ts +64 -0
- package/dist/core/contract/failure.js +4 -0
- package/dist/core/contract/hash.d.ts +92 -0
- package/dist/core/contract/hash.js +34 -0
- package/dist/core/contract/index.d.ts +21 -0
- package/dist/core/contract/index.js +22 -0
- package/dist/core/contract/limits.d.ts +74 -0
- package/dist/core/contract/limits.js +1 -0
- package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
- package/dist/core/contract/manifest-parse-schema.js +106 -0
- package/dist/core/contract/manifest-parse.d.ts +76 -0
- package/dist/core/contract/manifest-parse.js +189 -0
- package/dist/core/contract/manifest.d.ts +56 -0
- package/dist/core/contract/manifest.js +31 -0
- package/dist/core/contract/normalize.d.ts +97 -0
- package/dist/core/contract/normalize.js +127 -0
- package/dist/core/contract/revision.d.ts +29 -0
- package/dist/core/contract/revision.js +5 -0
- package/dist/core/contract/types.d.ts +274 -0
- package/dist/core/contract/types.js +1 -0
- package/dist/core/engine/catalog-activation.d.ts +40 -0
- package/dist/core/engine/catalog-activation.js +17 -0
- package/dist/core/engine/catalog-events.d.ts +36 -0
- package/dist/core/engine/catalog-events.js +15 -0
- package/dist/core/engine/catalog-readiness.d.ts +49 -0
- package/dist/core/engine/catalog-readiness.js +59 -0
- package/dist/core/engine/catalog-removal.d.ts +132 -0
- package/dist/core/engine/catalog-removal.js +70 -0
- package/dist/core/engine/construction.d.ts +1 -1
- package/dist/core/engine/construction.js +4 -2
- package/dist/core/engine/disposal.js +9 -0
- package/dist/core/engine/engine-workflows-namespace.d.ts +130 -0
- package/dist/core/engine/engine-workflows-namespace.js +49 -0
- package/dist/core/engine/finalizer-metadata.d.ts +22 -0
- package/dist/core/engine/finalizer-metadata.js +12 -0
- package/dist/core/engine/handle-result.js +2 -0
- package/dist/core/engine/index.d.ts +83 -0
- package/dist/core/engine/index.js +61 -0
- package/dist/core/engine/internals.d.ts +44 -1
- package/dist/core/engine/internals.js +6 -0
- package/dist/core/engine/lifecycle/start.js +3 -0
- package/dist/core/engine/registration.d.ts +76 -0
- package/dist/core/engine/registration.js +12 -6
- package/dist/core/engine/source-registration.d.ts +42 -0
- package/dist/core/engine/source-registration.js +36 -0
- package/dist/core/engine/source-resolution.d.ts +85 -0
- package/dist/core/engine/source-resolution.js +119 -0
- package/dist/core/engine/validation.js +2 -2
- package/dist/core/events/catalog-events.d.ts +117 -0
- package/dist/core/events/catalog-events.js +62 -0
- package/dist/core/events/event-map.d.ts +6 -0
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -0
- package/dist/core/mailbox-admission.d.ts +26 -0
- package/dist/core/mailbox-admission.js +130 -0
- package/dist/core/mailbox-claims.d.ts +251 -0
- package/dist/core/mailbox-claims.js +0 -0
- package/dist/core/mailbox-codec.d.ts +32 -0
- package/dist/core/mailbox-codec.js +221 -0
- package/dist/core/mailbox-contract.d.ts +290 -0
- package/dist/core/mailbox-contract.js +0 -0
- package/dist/core/mailbox-delivery.d.ts +37 -0
- package/dist/core/mailbox-delivery.js +193 -0
- package/dist/core/mailbox-guards.d.ts +78 -0
- package/dist/core/mailbox-guards.js +58 -0
- package/dist/core/mailbox-index-codec.d.ts +41 -0
- package/dist/core/mailbox-index-codec.js +71 -0
- package/dist/core/mailbox-internals.d.ts +156 -0
- package/dist/core/mailbox-internals.js +154 -0
- package/dist/core/mailbox-maintenance.d.ts +29 -0
- package/dist/core/mailbox-maintenance.js +196 -0
- package/dist/core/mailbox-settlement.d.ts +69 -0
- package/dist/core/mailbox-settlement.js +206 -0
- package/dist/core/mailbox-storage.d.ts +117 -0
- package/dist/core/mailbox-storage.js +115 -0
- package/dist/core/mailbox-transition-helpers.d.ts +70 -0
- package/dist/core/mailbox-transition-helpers.js +43 -0
- package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
- package/dist/core/mailbox-transitions-recovery.js +64 -0
- package/dist/core/mailbox-transitions.d.ts +138 -0
- package/dist/core/mailbox-transitions.js +180 -0
- package/dist/core/mailbox-types.d.ts +406 -0
- package/dist/core/mailbox-types.js +16 -0
- package/dist/core/mailbox-validation.d.ts +65 -0
- package/dist/core/mailbox-validation.js +73 -0
- package/dist/core/mailbox-waits.d.ts +50 -0
- package/dist/core/mailbox-waits.js +97 -0
- package/dist/core/mailbox.d.ts +163 -0
- package/dist/core/mailbox.js +211 -0
- package/dist/core/outbox-claims.d.ts +307 -0
- package/dist/core/outbox-claims.js +0 -0
- package/dist/core/outbox-codec.d.ts +24 -0
- package/dist/core/outbox-codec.js +257 -0
- package/dist/core/outbox-contract.d.ts +346 -0
- package/dist/core/outbox-contract.js +0 -0
- package/dist/core/outbox-delivery.d.ts +34 -0
- package/dist/core/outbox-delivery.js +149 -0
- package/dist/core/outbox-drain.d.ts +29 -0
- package/dist/core/outbox-drain.js +158 -0
- package/dist/core/outbox-enqueue.d.ts +24 -0
- package/dist/core/outbox-enqueue.js +115 -0
- package/dist/core/outbox-guards.d.ts +76 -0
- package/dist/core/outbox-guards.js +60 -0
- package/dist/core/outbox-index-codec.d.ts +33 -0
- package/dist/core/outbox-index-codec.js +71 -0
- package/dist/core/outbox-internals.d.ts +99 -0
- package/dist/core/outbox-internals.js +159 -0
- package/dist/core/outbox-listing.d.ts +12 -0
- package/dist/core/outbox-listing.js +38 -0
- package/dist/core/outbox-maintenance.d.ts +28 -0
- package/dist/core/outbox-maintenance.js +191 -0
- package/dist/core/outbox-operations.d.ts +18 -0
- package/dist/core/outbox-operations.js +46 -0
- package/dist/core/outbox-runner.d.ts +30 -0
- package/dist/core/outbox-runner.js +217 -0
- package/dist/core/outbox-settlement.d.ts +57 -0
- package/dist/core/outbox-settlement.js +183 -0
- package/dist/core/outbox-storage.d.ts +107 -0
- package/dist/core/outbox-storage.js +127 -0
- package/dist/core/outbox-transition-helpers.d.ts +83 -0
- package/dist/core/outbox-transition-helpers.js +63 -0
- package/dist/core/outbox-transitions-recovery.d.ts +30 -0
- package/dist/core/outbox-transitions-recovery.js +42 -0
- package/dist/core/outbox-transitions.d.ts +145 -0
- package/dist/core/outbox-transitions.js +236 -0
- package/dist/core/outbox-types.d.ts +400 -0
- package/dist/core/outbox-types.js +20 -0
- package/dist/core/outbox-validation.d.ts +101 -0
- package/dist/core/outbox-validation.js +127 -0
- package/dist/core/outbox-waits.d.ts +39 -0
- package/dist/core/outbox-waits.js +88 -0
- package/dist/core/outbox.d.ts +156 -0
- package/dist/core/outbox.js +234 -0
- package/dist/core/registry-limits.d.ts +49 -0
- package/dist/core/registry-limits.js +10 -0
- package/dist/core/registry-schema-conversion.d.ts +20 -0
- package/dist/core/registry-schema-conversion.js +22 -0
- package/dist/core/registry-snapshot.d.ts +91 -42
- package/dist/core/registry-snapshot.js +39 -77
- package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
- package/dist/core/registry-workflow-contract-draft.js +28 -0
- package/dist/core/registry-workflow-manifest.d.ts +122 -0
- package/dist/core/registry-workflow-manifest.js +92 -0
- package/dist/core/source/errors.d.ts +55 -0
- package/dist/core/source/errors.js +13 -0
- package/dist/core/source/index.d.ts +19 -0
- package/dist/core/source/index.js +4 -0
- package/dist/core/source/resolvers.d.ts +45 -0
- package/dist/core/source/resolvers.js +9 -0
- package/dist/core/source/types.d.ts +211 -0
- package/dist/core/source/types.js +0 -0
- package/dist/core/source/validate.d.ts +91 -0
- package/dist/core/source/validate.js +62 -0
- package/dist/core/source/workflow-source.d.ts +43 -0
- package/dist/core/source/workflow-source.js +16 -0
- package/dist/core/types/workflow-registries.d.ts +7 -0
- package/dist/core/types/workflow-registry.d.ts +12 -0
- package/dist/core/versioning.js +2 -0
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +9 -1
- package/dist/http.js +2 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +50 -0
- package/dist/indexeddb.js +1 -1
- package/dist/json-schema.js +3 -3
- package/dist/mcp/resources.js +2 -0
- package/dist/runtime/portable.d.ts +9 -1
- package/dist/server/fault-to-json-rpc.js +3 -1
- package/dist/server/handler/auth-context-principal.js +4 -0
- package/dist/server/json-rpc-http.js +2 -0
- package/dist/server/json-rpc-websocket.js +6 -4
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
- package/dist/server/operation-catalog/types.d.ts +17 -0
- package/dist/server/operation-fault.d.ts +3 -0
- package/dist/server/operation-fault.js +3 -1
- package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
- package/dist/server/operations/activate-workflow-revision.js +69 -0
- package/dist/server/operations/fleet-events-subscription.js +1 -1
- package/dist/server/operations/fork-workflow.js +1 -1
- package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
- package/dist/server/operations/get-active-workflow-revision.js +46 -0
- package/dist/server/operations/get-catalog-diagnostics.d.ts +85 -0
- package/dist/server/operations/get-catalog-diagnostics.js +57 -0
- package/dist/server/operations/get-registry.js +17 -4
- package/dist/server/operations/get-workflow-revision.d.ts +25 -0
- package/dist/server/operations/get-workflow-revision.js +50 -0
- package/dist/server/operations/install-workflow-revision.d.ts +27 -0
- package/dist/server/operations/install-workflow-revision.js +46 -0
- package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
- package/dist/server/operations/list-workflow-revisions.js +40 -0
- package/dist/server/operations/start-or-signal-workflow.js +1 -1
- package/dist/server/operations/start-workflow.js +1 -1
- package/dist/server/operations/static-registrations.js +36 -0
- package/dist/server/operations/storage.js +2 -2
- package/dist/server/operations/submit-review-decision.js +1 -1
- package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
- package/dist/server/operations/workflow-catalog-operation-helpers.js +135 -0
- package/dist/server/runtime/websocket-upgrade.js +2 -0
- package/dist/storage/bun-sql.js +49 -6
- package/dist/storage/catalog-keys.d.ts +45 -0
- package/dist/storage/catalog-keys.js +6 -0
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/derived-operations.js +1 -1
- package/dist/storage/index.d.ts +26 -1
- package/dist/storage/interface.d.ts +26 -1
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-encoding.d.ts +15 -0
- package/dist/storage/key-encoding.js +3 -0
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +15 -0
- package/dist/storage/lmdb.d.ts +26 -1
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/mailbox-keys.d.ts +80 -0
- package/dist/storage/mailbox-keys.js +14 -0
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon.js +2 -2
- package/dist/storage/node-sqlite-loader.d.ts +1 -1
- package/dist/storage/node-sqlite-loader.js +2 -2
- package/dist/storage/node-sqlite.js +51 -8
- package/dist/storage/outbox-keys.d.ts +77 -0
- package/dist/storage/outbox-keys.js +14 -0
- package/dist/storage/postgres.js +2 -2
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +6 -0
- package/dist/storage/testing.js +1 -1
- package/dist/storage/turso.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/web-extension.js +1 -1
- package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
- package/dist/worker/manifest/registry-contract-builder.js +40 -31
- package/package.json +1 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { AlertStateSnapshot } from '../../alerting/types.ts';
|
|
2
2
|
import { type Storage as WeftStorage } from '../../storage/interface.ts';
|
|
3
3
|
import { type ActivityMetadata, type ActivityRegistrationOptions, type RegisteredActivityFunction } from '../activity-registry.ts';
|
|
4
|
+
import type { WorkflowRevisionRecord } from '../catalog/index.ts';
|
|
4
5
|
import type { StoredStreamChunk } from '../context.ts';
|
|
5
6
|
import type { TypedEventTarget, WeftEventMap } from '../events.ts';
|
|
6
7
|
import type { Interceptor } from '../interceptor.ts';
|
|
7
8
|
import { type ReviewRequest } from '../review/index.ts';
|
|
8
9
|
import { Scheduler } from '../scheduler.ts';
|
|
10
|
+
import type { WorkflowSourceHandle } from '../source/index.ts';
|
|
9
11
|
import { type AnyActivityDefinition, type AnyWorkflowDefinition, type AttributeFilterKey, type BulkCancelResult, type BulkDeleteResult, type BulkOperationCommitOptions, type BulkOperationDryRunOptions, type BulkOperationDryRunResult, type BulkRetryFailedResult, type BulkSignalAllCommitOptions, type BulkSignalAllDryRunOptions, type BulkSignalResult, type BulkTagResult, type CheckpointState, type CheckpointSummary, type CoordinatedUpdateResult, type DefaultActivityTypes, type DefaultWorkflowRegistry, type ForkOptions, type InferActivityEntries, type InferActivityEntry, type InferWorkflowEntries, type InferWorkflowEntry, type ListFilter, type ListOptions, type PaginatedResult, type PendingAsyncActivityListOptions, type PendingAsyncActivityPage, type PurgeResult, type QueryDefinition, type RegisteredWorkflowDefinition, type RetentionOverview, type ReviewListEntry, type ReviewListFilter, type ScheduleDefinition, type ScheduleFilter, type ScheduleOptions, type ScheduleSpec, type ScheduleSummary, type ScheduleUpdateOptions, type SearchAttributeValue, type SignalDefinition, type SignalDeliveryOptions, type StartOrSignalOptions, type StartOrSignalSignal, type StartWorkflowOptions, type SubmitReviewOptions, type TypedListFilter, type UpdateDefinition, type WorkflowEvent, type WorkflowFinalizerStatus, type WorkflowInput, type WorkflowOutput, type WorkflowReplay, type WorkflowScheduleProvenance, type WorkflowServices, type WorkflowServicesUnion, type WorkflowState, type WorkflowSummary, type WorkflowTimelineEntry } from '../types.ts';
|
|
10
12
|
import type { TimerEntry } from '../types/checkpoint.ts';
|
|
11
13
|
import type { WorkflowAlreadyRegistered } from '../types/workflow-builder.ts';
|
|
@@ -14,29 +16,36 @@ import { type EmptyActivityDefinitions, type EmptyWorkflowDefinitions, type Know
|
|
|
14
16
|
import { type ActivityDefinitionName, type EngineCreateOptions, type EngineCreateWorkflowRegistry, type RegisteredActivityDefinitionExecute, type UnknownWorkflowNameWhenDefaultRegistryIsEmpty } from './engine-create-types.ts';
|
|
15
17
|
import type { EngineConstructorOptions } from './engine-internal-types.ts';
|
|
16
18
|
import type { EngineStateNamespace } from './engine-state-namespace.ts';
|
|
19
|
+
import { type EngineWorkflowsNamespace } from './engine-workflows-namespace.ts';
|
|
17
20
|
import { HANDLE_RESULT_PROMISE, WorkflowHandle } from './handles.ts';
|
|
18
21
|
import { ENGINE_LEASE_LOST_WARNING_NAME } from './lease-deposition.ts';
|
|
19
22
|
import type { EngineLeaseHealth } from './lease-health.ts';
|
|
20
23
|
import { type RecoverAllOptions, type StartOrSignalResult } from './lifecycle.ts';
|
|
21
24
|
import { assertCompatiblePersistedDataVersion } from './persisted-data-version.ts';
|
|
22
25
|
import { ScheduleHandle } from './schedule-handle.ts';
|
|
26
|
+
import { type ResolveWorkflowSourceOptions } from './source-resolution.ts';
|
|
23
27
|
import { type WorkflowFeedListener, type WorkflowFeedRecord, type WorkflowFeedSelector } from './workflow-feed.ts';
|
|
28
|
+
export type { WorkflowRevisionReferenceCounts } from '../catalog/index.ts';
|
|
24
29
|
export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, } from './activity-reconciliation.ts';
|
|
25
30
|
export { AsyncActivityTokenNotFoundError } from './async-activity-completion.ts';
|
|
26
31
|
export type { PendingAsyncActivity } from './async-activity-records.ts';
|
|
32
|
+
export { getWorkflowRevisionDiagnostics, removeWorkflowRevision, type WorkflowCatalogRemovalResult, type WorkflowRevisionDiagnostics, } from './catalog-removal.ts';
|
|
27
33
|
export type { PendingTimelineEntry, RegistrationEntry, ResolvedOptions, TrackedWaiterKeys, WorkflowResultWaiter, } from './engine-internal-types.ts';
|
|
28
34
|
export { ActivityResolutionError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, EngineCreateNameMismatchError, EngineDisposalError, EngineDisposedError, IdempotencyKeyPurgedError, PersistedDataCorruptError, PersistedDataIncompatibleError, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './errors.ts';
|
|
29
35
|
export { HANDLE_RESULT_PROMISE, WorkflowHandle } from './handles.ts';
|
|
36
|
+
export { getWorkflowCatalog } from './internals.ts';
|
|
30
37
|
export { WeftWorkflowClaimLostWarning, WeftWorkflowWakeDiscardedWarning, WORKFLOW_CLAIM_LOST_WARNING_NAME, WORKFLOW_WAKE_DISCARDED_WARNING_NAME, } from './lease-deposition.ts';
|
|
31
38
|
export type { WorkflowWakeKind } from './lease-deposition.ts';
|
|
32
39
|
export { EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, OwnershipModeMismatchError, WorkflowClaimUnavailableError, } from './lease-errors.ts';
|
|
33
40
|
export type { EngineLeaseHealth, LeaseLostReason } from './lease-health.ts';
|
|
34
41
|
export type { RecoverAllOptions, RecoveredWorkflowInfo } from './lifecycle.ts';
|
|
35
42
|
export { ScheduleHandle } from './schedule-handle.ts';
|
|
43
|
+
export type { ResolveWorkflowSourceOptions } from './source-resolution.ts';
|
|
36
44
|
export type { WorkflowFeedListener, WorkflowFeedRecord, WorkflowFeedSelector, } from './workflow-feed.ts';
|
|
37
45
|
export type { EngineCreateOptions } from './engine-create-types.ts';
|
|
38
46
|
export { clearEngineLeakWarningTokenForTesting, getEngineLeakCollectionCountForTesting, hasEngineLeakWarningTokenForTesting, setEngineLeakWarningOverrideForTesting, setNextEngineLeakWarningTokenForTesting, shouldEmitEngineLeakWarningForTesting, } from './engine-leak-warnings.ts';
|
|
39
47
|
export type { EngineStateNamespace } from './engine-state-namespace.ts';
|
|
48
|
+
export type { ActivateWorkflowRevisionOptions, EngineWorkflowsNamespace, } from './engine-workflows-namespace.ts';
|
|
40
49
|
export { assertCompatiblePersistedDataVersion };
|
|
41
50
|
export declare const ENGINE_PARKED_WORKFLOW_COUNT_FOR_TESTING: unique symbol;
|
|
42
51
|
export declare const ENGINE_SIGNAL_WAITER_COUNT_FOR_TESTING: unique symbol;
|
|
@@ -172,6 +181,7 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
|
|
|
172
181
|
removeEventListener<K extends Extract<keyof WeftEventMap, string>>(type: K, listener: (event: WeftEventMap[K]) => void, options?: boolean | EventListenerOptions): void;
|
|
173
182
|
removeEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | EventListenerOptions): void;
|
|
174
183
|
get state(): EngineStateNamespace;
|
|
184
|
+
get workflows(): EngineWorkflowsNamespace;
|
|
175
185
|
/** Return detached snapshots of the alert rules that are currently firing. */
|
|
176
186
|
getActiveAlerts(): readonly AlertStateSnapshot[];
|
|
177
187
|
/**
|
|
@@ -212,6 +222,50 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
|
|
|
212
222
|
readonly execute: RegisteredActivityDefinitionExecute<TActivities, TName>;
|
|
213
223
|
}): Engine<TWorkflows, TActivities & InferActivityEntry<TDefinition>>;
|
|
214
224
|
register<TDefinition extends AnyActivityDefinition>(definition: ActivityDefinitionName<TDefinition> extends Extract<keyof TActivities, string> ? never : TDefinition): Engine<TWorkflows, TActivities & InferActivityEntry<TDefinition>>;
|
|
225
|
+
/**
|
|
226
|
+
* Record `source` as a lazily-resolvable dynamic workflow source
|
|
227
|
+
* (WFT-13/14): synchronous, and it never invokes `source.load` — it only
|
|
228
|
+
* records a catalog candidate keyed `(source.descriptor.name,
|
|
229
|
+
* source.descriptor.revision)`. Call `resolveWorkflowSource()` to
|
|
230
|
+
* actually load, validate, and install it. A workflow name may not be
|
|
231
|
+
* both eagerly registered (`engine.register()`) and a dynamic source;
|
|
232
|
+
* registering the identical `source` reference twice for the same
|
|
233
|
+
* `(name, revision)` is idempotent.
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* import { Engine, workflowSource } from '@lostgradient/weft';
|
|
238
|
+
*
|
|
239
|
+
* declare const loadCheckout: () => Promise<{
|
|
240
|
+
* checkout: import('@lostgradient/weft').WorkflowDefinition<unknown, unknown, 'checkout'>;
|
|
241
|
+
* }>;
|
|
242
|
+
* const engine = new Engine();
|
|
243
|
+
* engine.registerSource(
|
|
244
|
+
* workflowSource(
|
|
245
|
+
* { name: 'checkout', location: './checkout.ts', exportName: 'checkout', revision: 'r1' },
|
|
246
|
+
* loadCheckout,
|
|
247
|
+
* ),
|
|
248
|
+
* );
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
registerSource(source: WorkflowSourceHandle): void;
|
|
252
|
+
/**
|
|
253
|
+
* Load, validate, and install one dynamic workflow source revision
|
|
254
|
+
* previously recorded via {@link Engine.registerSource}. Single-flight
|
|
255
|
+
* per `(name, revision)`: concurrent callers for the same key share one
|
|
256
|
+
* loader invocation. Does not wire `engine.start()` or recovery to await
|
|
257
|
+
* resolution — that is a later batch's job (WFT-15).
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* import { Engine } from '@lostgradient/weft';
|
|
262
|
+
*
|
|
263
|
+
* declare const engine: Engine;
|
|
264
|
+
* const record = await engine.resolveWorkflowSource('checkout', 'r1');
|
|
265
|
+
* console.log(record.manifest.revision);
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
resolveWorkflowSource(name: string, revision: string, options?: ResolveWorkflowSourceOptions): Promise<WorkflowRevisionRecord>;
|
|
215
269
|
/**
|
|
216
270
|
* Register every workflow from an object map at once and return a typed
|
|
217
271
|
* engine view that exposes the newly added workflow names.
|
|
@@ -244,6 +298,35 @@ export declare class Engine<TWorkflows extends object = DefaultWorkflowRegistry,
|
|
|
244
298
|
listWorkflowDefinitions(): RegisteredWorkflowDefinition[];
|
|
245
299
|
getActivityDefinition(name: string): ActivityMetadata | undefined;
|
|
246
300
|
listActivityDefinitions(): ActivityMetadata[];
|
|
301
|
+
/**
|
|
302
|
+
* Resolve one activity's catalog metadata the same way dispatch resolves
|
|
303
|
+
* it for a running workflow of this type: the workflow's per-workflow
|
|
304
|
+
* `.activities({...})` registry first, falling back to the global registry
|
|
305
|
+
* — see `activity-resolution.ts`'s `resolveActivityViaRegistries`. Build
|
|
306
|
+
* tooling (`buildWorkerManifestFromRegistry`) uses this so a workflow-scoped
|
|
307
|
+
* activity's schema, not a same-named global activity's, feeds its
|
|
308
|
+
* `contractHash` when both are registered.
|
|
309
|
+
*/
|
|
310
|
+
getWorkflowActivityDefinition(workflowType: string, activityName: string): ActivityMetadata | undefined;
|
|
311
|
+
/**
|
|
312
|
+
* List every activity definition registered on this workflow's own
|
|
313
|
+
* per-workflow `.activities({...})` registry — name, schema, description,
|
|
314
|
+
* tags, retry/timeout metadata, never a handler function. Returns an
|
|
315
|
+
* empty array for a workflow with no `.activities({...})` step (including
|
|
316
|
+
* an unknown `workflowType`), never `undefined`, so a caller can fold the
|
|
317
|
+
* result straight into a contract without an existence check first.
|
|
318
|
+
*
|
|
319
|
+
* Companion to {@link getWorkflowActivityDefinition}: that resolves one
|
|
320
|
+
* activity by name with the per-workflow-first, global-fallback dispatch
|
|
321
|
+
* order; this enumerates only the names the per-workflow registry itself
|
|
322
|
+
* declares — activities a workflow reaches solely through the global
|
|
323
|
+
* registry are deliberately excluded, since those are not part of what
|
|
324
|
+
* `.activities({...})` scoped to this workflow. Build tooling that needs a
|
|
325
|
+
* workflow's full scoped-activity contract set (`buildRegistrySnapshot`,
|
|
326
|
+
* `worker/manifest/registry-contract-builder.ts`) uses this instead of
|
|
327
|
+
* reaching into engine internals directly.
|
|
328
|
+
*/
|
|
329
|
+
listWorkflowActivityDefinitions(workflowType: string): ActivityMetadata[];
|
|
247
330
|
start<TName extends KnownWorkflowNames<TWorkflows>>(type: TName, input: WorkflowInput<TWorkflows, TName>, options?: StartWorkflowOptions<WorkflowServices<TWorkflows, TName>>): Promise<WorkflowHandle<WorkflowOutput<TWorkflows, TName>>>;
|
|
248
331
|
start<TName extends string>(type: UnknownWorkflowNameWhenDefaultRegistryIsEmpty<TWorkflows, TName>, input: unknown, options?: StartWorkflowOptions): Promise<WorkflowHandle>;
|
|
249
332
|
/**
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
createUpdateCallbacks as createUpdateCallbacksForEngine
|
|
48
48
|
} from "./callback-creators.js";
|
|
49
49
|
import { registerCancelHandler } from "./cancel-handlers.js";
|
|
50
|
+
import { ensureWorkflowCatalogReady, isWorkflowCatalogReady } from "./catalog-readiness.js";
|
|
50
51
|
import {
|
|
51
52
|
getCheckpointAt as getCheckpointStateAt,
|
|
52
53
|
getEvents as getWorkflowEvents,
|
|
@@ -78,6 +79,9 @@ import {
|
|
|
78
79
|
shouldStartEngineScheduler,
|
|
79
80
|
validateEngineCreateBackgroundTaskOptions
|
|
80
81
|
} from "./engine-runtime-helpers.js";
|
|
82
|
+
import {
|
|
83
|
+
createEngineWorkflowsNamespace
|
|
84
|
+
} from "./engine-workflows-namespace.js";
|
|
81
85
|
import {
|
|
82
86
|
EngineCreateNameMismatchError,
|
|
83
87
|
EngineDisposalError,
|
|
@@ -167,6 +171,10 @@ import {
|
|
|
167
171
|
releaseSignalWaiter,
|
|
168
172
|
signal as signalWorkflow
|
|
169
173
|
} from "./signals.js";
|
|
174
|
+
import { registerSource as registerWorkflowSource } from "./source-registration.js";
|
|
175
|
+
import {
|
|
176
|
+
resolveWorkflowSource as resolveWorkflowSourceImpl
|
|
177
|
+
} from "./source-resolution.js";
|
|
170
178
|
import {
|
|
171
179
|
loadScheduleState,
|
|
172
180
|
loadWorkflowState,
|
|
@@ -204,6 +212,10 @@ export {
|
|
|
204
212
|
ActivityReconciliationIndeterminateError
|
|
205
213
|
} from "./activity-reconciliation.js";
|
|
206
214
|
export { AsyncActivityTokenNotFoundError } from "./async-activity-completion.js";
|
|
215
|
+
export {
|
|
216
|
+
getWorkflowRevisionDiagnostics,
|
|
217
|
+
removeWorkflowRevision
|
|
218
|
+
} from "./catalog-removal.js";
|
|
207
219
|
export {
|
|
208
220
|
ActivityResolutionError,
|
|
209
221
|
BulkDeleteRequiresTerminalWorkflowsError,
|
|
@@ -224,6 +236,7 @@ export {
|
|
|
224
236
|
WorkflowTypeNotRegisteredForRecoveryError
|
|
225
237
|
} from "./errors.js";
|
|
226
238
|
export { HANDLE_RESULT_PROMISE, WorkflowHandle } from "./handles.js";
|
|
239
|
+
export { getWorkflowCatalog } from "./internals.js";
|
|
227
240
|
export {
|
|
228
241
|
WeftWorkflowClaimLostWarning,
|
|
229
242
|
WeftWorkflowWakeDiscardedWarning,
|
|
@@ -282,6 +295,8 @@ export class Engine extends EventTarget {
|
|
|
282
295
|
}
|
|
283
296
|
await engine.#bootstrapOwnershipIfConfigured();
|
|
284
297
|
await engine.#acquireLeaseIfConfigured();
|
|
298
|
+
if (!isWorkflowCatalogReady(engine))
|
|
299
|
+
await ensureWorkflowCatalogReady(engine);
|
|
285
300
|
if (options.recover !== !1)
|
|
286
301
|
await engine.recoverAll(options.acknowledgeUnknownWorkflowTypes !== void 0 ? { acknowledgeUnknownWorkflowTypes: options.acknowledgeUnknownWorkflowTypes } : {});
|
|
287
302
|
if (shouldStartEngineScheduler(options, getInternals(engine).options.backgroundTaskMode))
|
|
@@ -424,6 +439,16 @@ export class Engine extends EventTarget {
|
|
|
424
439
|
getInternals(this).activityWorkerDispatcher = createActivityWorkerDispatcher(options?.activityExecution);
|
|
425
440
|
getInternals(this).strategy.onMessage(this.#handleStrategyMessage.bind(this));
|
|
426
441
|
getInternals(this).alertManager = options?.alerts ? new AlertManager(this, options.alerts, getNow, resolvedOptions.backgroundTaskMode === "automatic") : null;
|
|
442
|
+
getInternals(this).workflowCatalog = null;
|
|
443
|
+
getInternals(this).pendingCatalogInstalls = [];
|
|
444
|
+
getInternals(this).catalogRestored = !1;
|
|
445
|
+
getInternals(this).catalogDrainPromise = null;
|
|
446
|
+
getInternals(this).registeredCatalogRevisions = new Map;
|
|
447
|
+
getInternals(this).inFlightStartsByRevision = new Map;
|
|
448
|
+
getInternals(this).workflowSourcesByName = new Map;
|
|
449
|
+
getInternals(this).sourceResolutionsInFlight = new Map;
|
|
450
|
+
getInternals(this).sourceResolutionWaiterControllers = new Set;
|
|
451
|
+
getInternals(this).resolvedWorkflowSources = new Map;
|
|
427
452
|
this.#ensureRetentionSweepInterval();
|
|
428
453
|
this.#startSecondInstanceDetection();
|
|
429
454
|
}
|
|
@@ -675,6 +700,9 @@ export class Engine extends EventTarget {
|
|
|
675
700
|
workflow: (workflowType, key, options) => new AtomicState(storage, KEYS.stateWorkflow(workflowType, key), options)
|
|
676
701
|
};
|
|
677
702
|
}
|
|
703
|
+
get workflows() {
|
|
704
|
+
return createEngineWorkflowsNamespace(this);
|
|
705
|
+
}
|
|
678
706
|
getActiveAlerts() {
|
|
679
707
|
return getInternals(this).alertManager?.activeStates ?? [];
|
|
680
708
|
}
|
|
@@ -692,6 +720,12 @@ export class Engine extends EventTarget {
|
|
|
692
720
|
registerWorkflow(getInternals(this), definition, this.#createRegistrationCallbacks());
|
|
693
721
|
return typedEngineView(this);
|
|
694
722
|
}
|
|
723
|
+
registerSource(source) {
|
|
724
|
+
registerWorkflowSource(getInternals(this), source);
|
|
725
|
+
}
|
|
726
|
+
async resolveWorkflowSource(name, revision, options) {
|
|
727
|
+
return resolveWorkflowSourceImpl(this, name, revision, options);
|
|
728
|
+
}
|
|
695
729
|
registerWorkflows(workflows) {
|
|
696
730
|
for (const [name, definition] of Object.entries(workflows)) {
|
|
697
731
|
if (name !== definition.name)
|
|
@@ -730,14 +764,25 @@ export class Engine extends EventTarget {
|
|
|
730
764
|
listActivityDefinitions() {
|
|
731
765
|
return getInternals(this).activityRegistry.listDefinitions();
|
|
732
766
|
}
|
|
767
|
+
getWorkflowActivityDefinition(workflowType, activityName) {
|
|
768
|
+
const internals = getInternals(this);
|
|
769
|
+
return internals.activityRegistriesByWorkflow.get(workflowType)?.getDefinition(activityName) ?? internals.activityRegistry.getDefinition(activityName);
|
|
770
|
+
}
|
|
771
|
+
listWorkflowActivityDefinitions(workflowType) {
|
|
772
|
+
return getInternals(this).activityRegistriesByWorkflow.get(workflowType)?.listDefinitions() ?? [];
|
|
773
|
+
}
|
|
733
774
|
async start(type, input, options) {
|
|
734
775
|
assertLeaseHeldForEngineWork(getInternals(this));
|
|
776
|
+
if (!isWorkflowCatalogReady(this))
|
|
777
|
+
await ensureWorkflowCatalogReady(this);
|
|
735
778
|
if (options?.idempotencyKey !== void 0)
|
|
736
779
|
return startWithIdempotencyFromLifecycle(getInternals(this), type, input, options, this.#createLifecycleCallbacks());
|
|
737
780
|
return startWorkflowFromLifecycle(getInternals(this), type, input, options, void 0, this.#createLifecycleCallbacks());
|
|
738
781
|
}
|
|
739
782
|
async startOrSignal(type, input, signal, options) {
|
|
740
783
|
assertLeaseHeldForEngineWork(getInternals(this));
|
|
784
|
+
if (!isWorkflowCatalogReady(this))
|
|
785
|
+
await ensureWorkflowCatalogReady(this);
|
|
741
786
|
return startOrSignalFromLifecycle(getInternals(this), type, input, signal, options, this.#createStartOrSignalCallbacks());
|
|
742
787
|
}
|
|
743
788
|
#createStartOrSignalCallbacks() {
|
|
@@ -810,6 +855,8 @@ export class Engine extends EventTarget {
|
|
|
810
855
|
async schedule(typeOrDefinition, input, spec, options) {
|
|
811
856
|
const internals = getInternals(this);
|
|
812
857
|
assertLeaseHeldForEngineWork(internals);
|
|
858
|
+
if (!isWorkflowCatalogReady(this))
|
|
859
|
+
await ensureWorkflowCatalogReady(this);
|
|
813
860
|
if (typeof typeOrDefinition === "object")
|
|
814
861
|
return scheduleDefinitionFromInternals(internals, typeOrDefinition);
|
|
815
862
|
if (spec === void 0)
|
|
@@ -826,21 +873,29 @@ export class Engine extends EventTarget {
|
|
|
826
873
|
async pauseSchedule(scheduleId) {
|
|
827
874
|
const internals = getInternals(this);
|
|
828
875
|
assertLeaseHeldForEngineWork(internals);
|
|
876
|
+
if (!isWorkflowCatalogReady(this))
|
|
877
|
+
await ensureWorkflowCatalogReady(this);
|
|
829
878
|
return pauseScheduleFromInternals(internals, scheduleId);
|
|
830
879
|
}
|
|
831
880
|
async resumeSchedule(scheduleId) {
|
|
832
881
|
const internals = getInternals(this);
|
|
833
882
|
assertLeaseHeldForEngineWork(internals);
|
|
883
|
+
if (!isWorkflowCatalogReady(this))
|
|
884
|
+
await ensureWorkflowCatalogReady(this);
|
|
834
885
|
return resumeScheduleFromInternals(internals, scheduleId);
|
|
835
886
|
}
|
|
836
887
|
async cancelSchedule(scheduleId) {
|
|
837
888
|
const internals = getInternals(this);
|
|
838
889
|
assertLeaseHeldForEngineWork(internals);
|
|
890
|
+
if (!isWorkflowCatalogReady(this))
|
|
891
|
+
await ensureWorkflowCatalogReady(this);
|
|
839
892
|
return cancelScheduleFromInternals(internals, scheduleId);
|
|
840
893
|
}
|
|
841
894
|
async updateSchedule(scheduleId, newSpec, options) {
|
|
842
895
|
const internals = getInternals(this);
|
|
843
896
|
assertLeaseHeldForEngineWork(internals);
|
|
897
|
+
if (!isWorkflowCatalogReady(this))
|
|
898
|
+
await ensureWorkflowCatalogReady(this);
|
|
844
899
|
return updateScheduleFromInternals(internals, scheduleId, newSpec, options);
|
|
845
900
|
}
|
|
846
901
|
[HANDLE_RESULT_PROMISE](workflowId) {
|
|
@@ -906,10 +961,14 @@ export class Engine extends EventTarget {
|
|
|
906
961
|
}
|
|
907
962
|
async fork(sourceWorkflowId, options) {
|
|
908
963
|
assertLeaseHeldForEngineWork(getInternals(this));
|
|
964
|
+
if (!isWorkflowCatalogReady(this))
|
|
965
|
+
await ensureWorkflowCatalogReady(this);
|
|
909
966
|
return forkFromLifecycle(getInternals(this), sourceWorkflowId, options, this.#createLifecycleCallbacks());
|
|
910
967
|
}
|
|
911
968
|
async resume(workflowId) {
|
|
912
969
|
assertLeaseHeldForEngineWork(getInternals(this));
|
|
970
|
+
if (!isWorkflowCatalogReady(this))
|
|
971
|
+
await ensureWorkflowCatalogReady(this);
|
|
913
972
|
return resumeFromLifecycle(getInternals(this), workflowId, this.#createLifecycleCallbacks());
|
|
914
973
|
}
|
|
915
974
|
async recoverAll(options) {
|
|
@@ -917,6 +976,8 @@ export class Engine extends EventTarget {
|
|
|
917
976
|
await this.#acquireLeaseIfConfigured();
|
|
918
977
|
if (getInternals(this).disposed)
|
|
919
978
|
throw new EngineDisposedError;
|
|
979
|
+
if (!isWorkflowCatalogReady(this))
|
|
980
|
+
await ensureWorkflowCatalogReady(this);
|
|
920
981
|
await recoverPendingAsyncActivities(getInternals(this));
|
|
921
982
|
await recoverOrphanedScheduleTimers(getInternals(this));
|
|
922
983
|
getInternals(this).onRecoveredWorkflowHook = options?.onRecoveredWorkflow;
|
|
@@ -29,7 +29,7 @@ import type { InlineExecutionStrategy } from '../inline-execution-strategy.ts';
|
|
|
29
29
|
import type { ComposedActivityInterceptor, ComposedWorkflowInterceptor, Interceptor } from '../interceptor.ts';
|
|
30
30
|
import type { HumanReviewResult, ReviewCoordinator } from '../review/index.ts';
|
|
31
31
|
import type { Scheduler } from '../scheduler.ts';
|
|
32
|
-
import type { Checkpoint, StartWorkflowOptions } from '../types.ts';
|
|
32
|
+
import type { Checkpoint, StartWorkflowOptions, WorkflowDefinition } from '../types.ts';
|
|
33
33
|
import type { UpdateCoordinator } from '../updates.ts';
|
|
34
34
|
import type { WorkflowVersionTuple } from '../workflow-version-tuple.ts';
|
|
35
35
|
import type { RecoveredWorkflowInfo } from './lifecycle/shared.ts';
|
|
@@ -58,6 +58,12 @@ export type DurableInlineOperation = {
|
|
|
58
58
|
type EngineRuntime = WorkflowHandleEngine & ScheduleHandleEngine & {
|
|
59
59
|
start(type: string, input: unknown, options?: StartWorkflowOptions): Promise<WorkflowHandle>;
|
|
60
60
|
};
|
|
61
|
+
type SourceHandle = import('../source/index.ts').WorkflowSourceHandle;
|
|
62
|
+
type CatalogRevisionRecord = import('../catalog/index.ts').WorkflowRevisionRecord;
|
|
63
|
+
type ResolvedSource = {
|
|
64
|
+
definition: WorkflowDefinition;
|
|
65
|
+
activityRegistry: ActivityRegistry;
|
|
66
|
+
};
|
|
61
67
|
export interface EngineInternals {
|
|
62
68
|
engine: EngineRuntime;
|
|
63
69
|
storage: WeftStorage;
|
|
@@ -386,6 +392,31 @@ export interface EngineInternals {
|
|
|
386
392
|
workflowVisibilityWatermarkExpiresAt: number | undefined;
|
|
387
393
|
pendingTimelineEntries: Map<string, PendingTimelineEntry>;
|
|
388
394
|
pendingAtomicWorkflowCommitSideEffects: Map<string, import('./checkpoint-side-effects.ts').AtomicWorkflowCommitSideEffects>;
|
|
395
|
+
/**
|
|
396
|
+
* The durable workflow catalog (WFT-9/WFT-10), `null` until
|
|
397
|
+
* {@link import('./catalog-readiness.ts').ensureWorkflowCatalogReady} first
|
|
398
|
+
* restores it from storage. Read via {@link getWorkflowCatalog}, never
|
|
399
|
+
* directly.
|
|
400
|
+
*/
|
|
401
|
+
workflowCatalog: import('../catalog/index.ts').WorkflowCatalog | null;
|
|
402
|
+
/** Workflow names `commitWorkflowDefinition` (`registration.ts`) has queued for catalog install+activate since the last drain — `engine.register()` stays synchronous (it cannot itself build a manifest) and defers to the next `ensureWorkflowCatalogReady` call. */
|
|
403
|
+
pendingCatalogInstalls: string[];
|
|
404
|
+
/** Whether {@link workflowCatalog} has been restored from storage at least once. */
|
|
405
|
+
catalogRestored: boolean;
|
|
406
|
+
/** The in-flight catalog restore-and-drain, or `null` when none is running; concurrent `ensureWorkflowCatalogReady` callers await this same promise rather than racing a second restore/drain. */
|
|
407
|
+
catalogDrainPromise: Promise<void> | null;
|
|
408
|
+
/** Name -> revision this process's own register()-drain most recently activated (WFT-12, `catalog-readiness.ts`). Process-local, never persisted. */
|
|
409
|
+
registeredCatalogRevisions: Map<string, string>;
|
|
410
|
+
/** Name -> revision -> in-flight `startWorkflow` count (WFT-12, `lifecycle/start.ts`). Process-local, never persisted. */
|
|
411
|
+
inFlightStartsByRevision: Map<string, Map<string, number>>;
|
|
412
|
+
/** Dynamic workflow sources (WFT-13/14): `registerSource()` candidates, keyed name then revision. Registering never invokes the loader. Process-local, never persisted. */
|
|
413
|
+
workflowSourcesByName: Map<string, Map<string, SourceHandle>>;
|
|
414
|
+
/** In-flight `resolveWorkflowSource` single-flight load per `(name, revision)`. Self-removes on settle via a `catalogDrainPromise`-style identity guard. */
|
|
415
|
+
sourceResolutionsInFlight: Map<string, Map<string, Promise<CatalogRevisionRecord>>>;
|
|
416
|
+
/** Per-caller `AbortController`s from in-flight `resolveWorkflowSource()` calls; disposal aborts every waiter without touching the shared load (mirrors `pendingWebhooks`). */
|
|
417
|
+
sourceResolutionWaiterControllers: Set<AbortController>;
|
|
418
|
+
/** A successful `resolveWorkflowSource()`'s live definition, keyed name then revision. Unread this batch — WFT-15's job. */
|
|
419
|
+
resolvedWorkflowSources: Map<string, Map<string, ResolvedSource>>;
|
|
389
420
|
}
|
|
390
421
|
/**
|
|
391
422
|
* Set up an empty `EngineInternals` skeleton in the WeakMap. The Engine
|
|
@@ -406,4 +437,16 @@ export declare function initializeInternals(engine: EngineRuntime): void;
|
|
|
406
437
|
* internals existing.
|
|
407
438
|
*/
|
|
408
439
|
export declare function getInternals(engine: object): EngineInternals;
|
|
440
|
+
/**
|
|
441
|
+
* Read an engine's durable workflow catalog. Throws when it has not been
|
|
442
|
+
* restored yet — every public entry point that can observe catalog state
|
|
443
|
+
* (`start`, `startOrSignal`, `schedule`/`pauseSchedule`/`resumeSchedule`/
|
|
444
|
+
* `cancelSchedule`/`updateSchedule`, `fork`, `resume`, `recoverAll`,
|
|
445
|
+
* `Engine.create`, and `buildRegistrySnapshot`) awaits
|
|
446
|
+
* `ensureWorkflowCatalogReady(engine)` first, which restores it. Calling
|
|
447
|
+
* this before that await boundary — for example from a pathological
|
|
448
|
+
* direct-internals test — is a programming error, not a recoverable runtime
|
|
449
|
+
* condition, so it fails loud rather than returning a placeholder catalog.
|
|
450
|
+
*/
|
|
451
|
+
export declare function getWorkflowCatalog(engine: object): import('../catalog/index.ts').WorkflowCatalog;
|
|
409
452
|
export {};
|
|
@@ -9,3 +9,9 @@ export function getInternals(engine) {
|
|
|
9
9
|
throw Error("Engine internals not initialized \u2014 initializeInternals(this) was not called in the Engine constructor");
|
|
10
10
|
return internals;
|
|
11
11
|
}
|
|
12
|
+
export function getWorkflowCatalog(engine) {
|
|
13
|
+
const internals = getInternals(engine);
|
|
14
|
+
if (internals.workflowCatalog === null)
|
|
15
|
+
throw Error("Workflow catalog not restored \u2014 ensureWorkflowCatalogReady(engine) was not awaited before " + "getWorkflowCatalog(engine) was called.");
|
|
16
|
+
return internals.workflowCatalog;
|
|
17
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
coerceStartWorkflowTimestamp,
|
|
10
10
|
parseStartWorkflowDuration
|
|
11
11
|
} from "../../start-workflow-validation.js";
|
|
12
|
+
import { releaseInFlightStart, reserveInFlightStart } from "../catalog-removal.js";
|
|
12
13
|
import { forgetCommittedCheckpointBytes } from "../checkpoint-commit-snapshots.js";
|
|
13
14
|
import { WorkflowAlreadyExistsError, WorkflowNotRegisteredError } from "../errors.js";
|
|
14
15
|
import { createDelayedStartTimerEntry } from "../operations-time.js";
|
|
@@ -90,6 +91,7 @@ export async function startWorkflow(internals, type, input, options, additionalS
|
|
|
90
91
|
throw new WorkflowAlreadyExistsError(workflowId);
|
|
91
92
|
internals.pendingStarts.add(workflowId);
|
|
92
93
|
let startSucceeded = !1;
|
|
94
|
+
const inFlightRevision = reserveInFlightStart(internals, type);
|
|
93
95
|
try {
|
|
94
96
|
const terminalRunToPurge = callerProvidedId ? await resolveTerminalConflictForRestart(internals, workflowId, options) : null;
|
|
95
97
|
assertPayloadWithinLimit(input, internals.options.payloadSizePolicy.maxBytes, "workflow input");
|
|
@@ -133,6 +135,7 @@ export async function startWorkflow(internals, type, input, options, additionalS
|
|
|
133
135
|
return handle;
|
|
134
136
|
} finally {
|
|
135
137
|
internals.pendingStarts.delete(workflowId);
|
|
138
|
+
releaseInFlightStart(internals, type, inFlightRevision);
|
|
136
139
|
if (!startSucceeded)
|
|
137
140
|
rollbackTransientStartState(internals, workflowId);
|
|
138
141
|
}
|
|
@@ -1,7 +1,83 @@
|
|
|
1
|
+
import { ActivityRegistry } from '../activity-registry.ts';
|
|
2
|
+
import { type ActivityDefinition, type QueryDefinition, type SignalDefinition, type UpdateDefinition, type WorkflowDefinition } from '../types.ts';
|
|
3
|
+
import type { RegistrationEntry } from './engine-internal-types.ts';
|
|
1
4
|
import type { EngineInternals } from './internals.ts';
|
|
2
5
|
export type RegistrationCallbacks = {
|
|
3
6
|
ensureRetentionSweepInterval: () => void;
|
|
4
7
|
dispatchEvent: (event: Event) => void;
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Build the `RegistrationEntry` `engine.register()` would store for
|
|
11
|
+
* `registration`, without committing anything — pure normalization
|
|
12
|
+
* (base fields, optional fields, and, for a builder-produced definition,
|
|
13
|
+
* signal/update/query name-collision checks). Exported so the dynamic
|
|
14
|
+
* workflow-source validation pipeline (`core/source/validate.ts`, WFT-13/14)
|
|
15
|
+
* can normalize a loaded module's exported definition through the identical
|
|
16
|
+
* path `engine.register()` uses, rather than re-deriving a
|
|
17
|
+
* `RegistrationEntry` independently and risking the two producers drifting
|
|
18
|
+
* apart.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { workflow } from '@lostgradient/weft';
|
|
23
|
+
*
|
|
24
|
+
* const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
|
|
25
|
+
* return `hello ${input}`;
|
|
26
|
+
* });
|
|
27
|
+
* console.log(greet.name);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildRegistrationEntry(name: string, registration: WorkflowDefinition): RegistrationEntry;
|
|
31
|
+
/**
|
|
32
|
+
* Structural predicate for `BuiltWorkflowDefinition` — the runtime shape
|
|
33
|
+
* `workflow({ name }).execute(...)` returns. Exported so the dynamic
|
|
34
|
+
* workflow-source validation pipeline (`core/source/validate.ts`, WFT-13/14)
|
|
35
|
+
* can reject a loaded export that is a hand-rolled `{ name, handler }`
|
|
36
|
+
* literal rather than a builder-produced definition — the same "removed
|
|
37
|
+
* bare-handler shape" rejection `engine.register()` itself applies via
|
|
38
|
+
* {@link buildRegistrationEntry}.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { workflow } from '@lostgradient/weft';
|
|
43
|
+
*
|
|
44
|
+
* const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
|
|
45
|
+
* return `hello ${input}`;
|
|
46
|
+
* });
|
|
47
|
+
* console.log(typeof greet.activities === 'object');
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function isBuilderWorkflowDefinition(value: unknown): value is WorkflowDefinition & {
|
|
51
|
+
readonly activities: Readonly<Record<string, Readonly<ActivityDefinition>>>;
|
|
52
|
+
readonly signals: Readonly<Record<string, Readonly<SignalDefinition<unknown>>>>;
|
|
53
|
+
readonly updates: Readonly<Record<string, Readonly<UpdateDefinition<unknown>>>>;
|
|
54
|
+
readonly queries: Readonly<Record<string, Readonly<QueryDefinition<unknown>>>>;
|
|
55
|
+
readonly searchAttributes: Readonly<Record<string, unknown>>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Build a fresh per-workflow {@link ActivityRegistry} from a builder workflow's
|
|
59
|
+
* activities map. Each entry is defensively deep-cloned and then turned into a
|
|
60
|
+
* fresh `ActivityCallable` via {@link activity}, so the engine's registry holds
|
|
61
|
+
* its own callable references and the user's `BuiltWorkflowDefinition` cannot
|
|
62
|
+
* influence dispatch by post-registration mutation.
|
|
63
|
+
*
|
|
64
|
+
* Exported so the dynamic workflow-source validation pipeline
|
|
65
|
+
* (`core/source/validate.ts`, WFT-13/14) can build the same
|
|
66
|
+
* uncommitted-but-canonical per-workflow registry for a loaded module's
|
|
67
|
+
* export that `engine.register()` builds for an eagerly registered one —
|
|
68
|
+
* required so {@link import('../registry-workflow-manifest.ts').buildWorkflowManifestFromDefinition}
|
|
69
|
+
* produces byte-identical manifests for the two paths.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { workflow } from '@lostgradient/weft';
|
|
74
|
+
*
|
|
75
|
+
* const greet = workflow({ name: 'greet' }).execute(async function* (_ctx, input: string) {
|
|
76
|
+
* return `hello ${input}`;
|
|
77
|
+
* });
|
|
78
|
+
* console.log(Object.keys(greet.activities).length);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildPerWorkflowActivityRegistry(activities: Readonly<Record<string, Readonly<ActivityDefinition>>>): ActivityRegistry;
|
|
6
82
|
export declare function register(internals: EngineInternals, definition: unknown, callbacks: RegistrationCallbacks): void;
|
|
7
83
|
export declare function resolveWorkflowTypeTarget(internals: EngineInternals, target: string | Function, _callbacks: RegistrationCallbacks): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRecord } from "../../worker/manifest/is-record.js";
|
|
1
2
|
import { ActivityRegistry } from "../activity-registry.js";
|
|
2
3
|
import { WorkflowDefinitionRegisteredEvent } from "../events.js";
|
|
3
4
|
import {
|
|
@@ -6,12 +7,13 @@ import {
|
|
|
6
7
|
} from "../types.js";
|
|
7
8
|
import { clonePlain } from "../types/clone-plain.js";
|
|
8
9
|
import { validateWorkflowOrActivityName } from "../types/name-grammar.js";
|
|
10
|
+
import { DEFAULT_WORKFLOW_VERSION } from "../versioning.js";
|
|
9
11
|
import { normalizeRetentionPolicy } from "./validation.js";
|
|
10
12
|
function copiedTags(tags) {
|
|
11
13
|
return tags === void 0 ? void 0 : [...tags];
|
|
12
14
|
}
|
|
13
15
|
function isWorkflowDefinition(value) {
|
|
14
|
-
return typeof value === "object" && value !== null && "name" in value && "handler" in value;
|
|
16
|
+
return typeof value === "object" && value !== null && "name" in value && "handler" in value && typeof value.handler === "function";
|
|
15
17
|
}
|
|
16
18
|
function assertConstraintsSupported(internals, name, registration) {
|
|
17
19
|
if (!registration.constraints || registration.constraints.length === 0)
|
|
@@ -23,7 +25,7 @@ function buildBaseRegistrationEntry(name, registration) {
|
|
|
23
25
|
const tags = copiedTags(registration.tags), normalizedRetention = normalizeRetentionPolicy(registration.retention, `registration("${name}").retention`);
|
|
24
26
|
return {
|
|
25
27
|
handler: registration.handler,
|
|
26
|
-
version: registration.version ??
|
|
28
|
+
version: registration.version ?? DEFAULT_WORKFLOW_VERSION,
|
|
27
29
|
...registration.description === void 0 ? {} : { description: registration.description },
|
|
28
30
|
...tags === void 0 ? {} : { tags },
|
|
29
31
|
...registration.inputSchema === void 0 ? {} : {
|
|
@@ -56,7 +58,7 @@ function applyOptionalRegistrationFields(entry, registration) {
|
|
|
56
58
|
if (registration.finalizer !== void 0)
|
|
57
59
|
entry.finalizer = registration.finalizer;
|
|
58
60
|
}
|
|
59
|
-
function buildRegistrationEntry(name, registration) {
|
|
61
|
+
export function buildRegistrationEntry(name, registration) {
|
|
60
62
|
const entry = buildBaseRegistrationEntry(name, registration);
|
|
61
63
|
applyOptionalRegistrationFields(entry, registration);
|
|
62
64
|
if (isBuilderWorkflowDefinition(registration)) {
|
|
@@ -78,25 +80,29 @@ function normalizeMessageDefinitions(workflowType, messageKind, definitions) {
|
|
|
78
80
|
function commitWorkflowDefinition(internals, definition, callbacks) {
|
|
79
81
|
const name = definition.name;
|
|
80
82
|
validateWorkflowOrActivityName(name, "workflow");
|
|
83
|
+
if (internals.workflowSourcesByName.has(name))
|
|
84
|
+
throw Error(`Cannot register("${name}"): "${name}" is already registered as a dynamic workflow source via engine.registerSource(). A workflow name may not be both eagerly registered and a dynamic source.`);
|
|
81
85
|
assertConstraintsSupported(internals, name, definition);
|
|
82
86
|
const entry = buildRegistrationEntry(name, definition);
|
|
83
87
|
internals.registrations.set(name, entry);
|
|
84
88
|
callbacks.ensureRetentionSweepInterval();
|
|
85
89
|
internals.workflowTypesByHandler.set(definition.handler, name);
|
|
90
|
+
if (!internals.pendingCatalogInstalls.includes(name))
|
|
91
|
+
internals.pendingCatalogInstalls.push(name);
|
|
86
92
|
callbacks.dispatchEvent(new WorkflowDefinitionRegisteredEvent(name));
|
|
87
93
|
}
|
|
88
94
|
function hasNonNullObjectField(value, key) {
|
|
89
95
|
if (!(key in value))
|
|
90
96
|
return !1;
|
|
91
97
|
const fieldValue = value[key];
|
|
92
|
-
return
|
|
98
|
+
return isRecord(fieldValue);
|
|
93
99
|
}
|
|
94
|
-
function isBuilderWorkflowDefinition(value) {
|
|
100
|
+
export function isBuilderWorkflowDefinition(value) {
|
|
95
101
|
if (!isWorkflowDefinition(value))
|
|
96
102
|
return !1;
|
|
97
103
|
return hasNonNullObjectField(value, "activities") && hasNonNullObjectField(value, "signals") && hasNonNullObjectField(value, "updates") && hasNonNullObjectField(value, "queries") && hasNonNullObjectField(value, "searchAttributes");
|
|
98
104
|
}
|
|
99
|
-
function buildPerWorkflowActivityRegistry(activities) {
|
|
105
|
+
export function buildPerWorkflowActivityRegistry(activities) {
|
|
100
106
|
const registry = new ActivityRegistry;
|
|
101
107
|
for (const definition of Object.values(activities)) {
|
|
102
108
|
const clonedDefinition = clonePlain(definition), callable = activity(clonedDefinition);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `registerSource()` — the synchronous entry point for a dynamic workflow
|
|
3
|
+
* source (WFT-13/14). Mirrors `engine.register()`'s own "stays synchronous,
|
|
4
|
+
* defers the real work" contract: this records a catalog candidate keyed
|
|
5
|
+
* `(name, revision)` and returns — it never invokes the source's loader and
|
|
6
|
+
* never touches storage. The loader runs only inside a later, explicit
|
|
7
|
+
* `resolveWorkflowSource()` call (`source-resolution.ts`).
|
|
8
|
+
*
|
|
9
|
+
* @module core/engine/source-registration
|
|
10
|
+
*/
|
|
11
|
+
import type { WorkflowSourceHandle } from '../source/index.ts';
|
|
12
|
+
import type { EngineInternals } from './internals.ts';
|
|
13
|
+
/**
|
|
14
|
+
* Record `source` as a lazily-resolvable candidate for
|
|
15
|
+
* `(source.descriptor.name, source.descriptor.revision)`. Synchronous and
|
|
16
|
+
* side-effect-free beyond the in-memory record: never invokes
|
|
17
|
+
* `source.load`, never reads or writes storage.
|
|
18
|
+
*
|
|
19
|
+
* Collision rules, checked in both directions against `engine.register()`'s
|
|
20
|
+
* own state so a workflow name can never be simultaneously eager and lazy:
|
|
21
|
+
*
|
|
22
|
+
* - A name already eagerly registered (`internals.registrations` — set by
|
|
23
|
+
* BOTH branches of `engine.register()`, unlike `workflowDefinitionsByName`,
|
|
24
|
+
* which only the builder-produced branch populates; checking that narrower
|
|
25
|
+
* map here would let a plain `{ name, handler }` `WorkflowDefinition`
|
|
26
|
+
* registered via `engine.register()` collide silently with a same-named
|
|
27
|
+
* `registerSource()` call) cannot also be registered as a source — throws.
|
|
28
|
+
* - Re-registering the identical `source` object reference for the same
|
|
29
|
+
* `(name, revision)` is idempotent (a no-op), mirroring `engine.register()`'s
|
|
30
|
+
* own same-reference-is-idempotent rule for eager definitions.
|
|
31
|
+
* - Registering a *different* handle under the same `(name, revision)` key
|
|
32
|
+
* throws — a revision identity, once claimed, names exactly one source.
|
|
33
|
+
* - Multiple *different* revisions of the same lazy name may coexist
|
|
34
|
+
* unregistered — this is the direct lazy analog of the catalog already
|
|
35
|
+
* supporting multiple installed revisions per name (WFT-9/10); nothing in
|
|
36
|
+
* this batch's acceptance criteria forbids it.
|
|
37
|
+
*
|
|
38
|
+
* The symmetric check — an eager `engine.register()` call for a name
|
|
39
|
+
* already claimed by a source — lives in `registration.ts`'s
|
|
40
|
+
* `commitWorkflowDefinition`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function registerSource(internals: EngineInternals, source: WorkflowSourceHandle): void;
|