dotdo 0.0.1 → 0.0.2
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/LICENSE +1 -1
- package/README.md +446 -315
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/template-literals.js +852 -0
- package/dist/ai/template-literals.js.map +1 -0
- package/dist/api/analytics/router.js +601 -0
- package/dist/api/analytics/router.js.map +1 -0
- package/dist/api/index.js +158 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +544 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/api/middleware/error-handling.js +176 -0
- package/dist/api/middleware/error-handling.js.map +1 -0
- package/dist/api/middleware/request-id.js +21 -0
- package/dist/api/middleware/request-id.js.map +1 -0
- package/dist/api/pages.js +1180 -0
- package/dist/api/pages.js.map +1 -0
- package/dist/api/routes/api.js +612 -0
- package/dist/api/routes/api.js.map +1 -0
- package/dist/api/routes/browsers.js +471 -0
- package/dist/api/routes/browsers.js.map +1 -0
- package/dist/api/routes/do.js +188 -0
- package/dist/api/routes/do.js.map +1 -0
- package/dist/api/routes/mcp.js +459 -0
- package/dist/api/routes/mcp.js.map +1 -0
- package/dist/api/routes/obs.js +445 -0
- package/dist/api/routes/obs.js.map +1 -0
- package/dist/api/routes/openapi.js +794 -0
- package/dist/api/routes/openapi.js.map +1 -0
- package/dist/api/routes/rpc.js +1103 -0
- package/dist/api/routes/rpc.js.map +1 -0
- package/dist/api/routes/sandboxes.js +389 -0
- package/dist/api/routes/sandboxes.js.map +1 -0
- package/dist/api/test-do.js +38 -0
- package/dist/api/test-do.js.map +1 -0
- package/dist/api/types.js +11 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli/bin.js +2 -0
- package/dist/cli/main.js +52342 -0
- package/dist/db/actions.js +212 -0
- package/dist/db/actions.js.map +1 -0
- package/dist/db/auth.js +506 -0
- package/dist/db/auth.js.map +1 -0
- package/dist/db/branches.js +65 -0
- package/dist/db/branches.js.map +1 -0
- package/dist/db/clickhouse.js +1074 -0
- package/dist/db/clickhouse.js.map +1 -0
- package/dist/db/dlq.js +39 -0
- package/dist/db/dlq.js.map +1 -0
- package/dist/db/events.js +28 -0
- package/dist/db/events.js.map +1 -0
- package/dist/db/exec.js +64 -0
- package/dist/db/exec.js.map +1 -0
- package/dist/db/files.js +85 -0
- package/dist/db/files.js.map +1 -0
- package/dist/db/flags.js +24 -0
- package/dist/db/flags.js.map +1 -0
- package/dist/db/git.js +116 -0
- package/dist/db/git.js.map +1 -0
- package/dist/db/iceberg/inverted-index.js +862 -0
- package/dist/db/iceberg/inverted-index.js.map +1 -0
- package/dist/db/iceberg/puffin.js +878 -0
- package/dist/db/iceberg/puffin.js.map +1 -0
- package/dist/db/iceberg/search-manifest.js +422 -0
- package/dist/db/iceberg/search-manifest.js.map +1 -0
- package/dist/db/iceberg/types.js +8 -0
- package/dist/db/iceberg/types.js.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/integrations.js +368 -0
- package/dist/db/integrations.js.map +1 -0
- package/dist/db/json-indexes.js +332 -0
- package/dist/db/json-indexes.js.map +1 -0
- package/dist/db/linked-accounts.js +287 -0
- package/dist/db/linked-accounts.js.map +1 -0
- package/dist/db/nouns.js +183 -0
- package/dist/db/nouns.js.map +1 -0
- package/dist/db/objects.js +170 -0
- package/dist/db/objects.js.map +1 -0
- package/dist/db/primitives/dag-scheduler/index.js +869 -0
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
- package/dist/db/primitives/exactly-once-context.js +237 -0
- package/dist/db/primitives/exactly-once-context.js.map +1 -0
- package/dist/db/primitives/index.js +62 -0
- package/dist/db/primitives/index.js.map +1 -0
- package/dist/db/primitives/keyed-router.js +145 -0
- package/dist/db/primitives/keyed-router.js.map +1 -0
- package/dist/db/primitives/observability.js +162 -0
- package/dist/db/primitives/observability.js.map +1 -0
- package/dist/db/primitives/schema-evolution.js +643 -0
- package/dist/db/primitives/schema-evolution.js.map +1 -0
- package/dist/db/primitives/stateful-operator/index.js +770 -0
- package/dist/db/primitives/stateful-operator/index.js.map +1 -0
- package/dist/db/primitives/temporal-store.js +306 -0
- package/dist/db/primitives/temporal-store.js.map +1 -0
- package/dist/db/primitives/typed-column-store.js +1229 -0
- package/dist/db/primitives/typed-column-store.js.map +1 -0
- package/dist/db/primitives/utils/duration.js +162 -0
- package/dist/db/primitives/utils/duration.js.map +1 -0
- package/dist/db/primitives/utils/murmur3.js +118 -0
- package/dist/db/primitives/utils/murmur3.js.map +1 -0
- package/dist/db/primitives/watermark-service.js +136 -0
- package/dist/db/primitives/watermark-service.js.map +1 -0
- package/dist/db/primitives/window-manager.js +764 -0
- package/dist/db/primitives/window-manager.js.map +1 -0
- package/dist/db/relationships.js +66 -0
- package/dist/db/relationships.js.map +1 -0
- package/dist/db/schema-minimal.js +61 -0
- package/dist/db/schema-minimal.js.map +1 -0
- package/dist/db/search.js +28 -0
- package/dist/db/search.js.map +1 -0
- package/dist/db/stores.js +1665 -0
- package/dist/db/stores.js.map +1 -0
- package/dist/db/things.js +297 -0
- package/dist/db/things.js.map +1 -0
- package/dist/db/vault.js +171 -0
- package/dist/db/vault.js.map +1 -0
- package/dist/db/verbs.js +102 -0
- package/dist/db/verbs.js.map +1 -0
- package/dist/do/base.js +48 -0
- package/dist/do/base.js.map +1 -0
- package/dist/do/bash.js +35 -0
- package/dist/do/bash.js.map +1 -0
- package/dist/do/fs.js +25 -0
- package/dist/do/fs.js.map +1 -0
- package/dist/do/full.js +61 -0
- package/dist/do/full.js.map +1 -0
- package/dist/do/git.js +28 -0
- package/dist/do/git.js.map +1 -0
- package/dist/do/index.js +52 -0
- package/dist/do/index.js.map +1 -0
- package/dist/do/tiny.js +31 -0
- package/dist/do/tiny.js.map +1 -0
- package/dist/lib/DOAuth.js +261 -0
- package/dist/lib/DOAuth.js.map +1 -0
- package/dist/lib/DODispatcher.js +72 -0
- package/dist/lib/DODispatcher.js.map +1 -0
- package/dist/lib/Modifier.js +189 -0
- package/dist/lib/Modifier.js.map +1 -0
- package/dist/lib/StateStorage.js +403 -0
- package/dist/lib/StateStorage.js.map +1 -0
- package/dist/lib/TypeRegistry.js +122 -0
- package/dist/lib/TypeRegistry.js.map +1 -0
- package/dist/lib/agent/tools/bash.js +336 -0
- package/dist/lib/agent/tools/bash.js.map +1 -0
- package/dist/lib/agent/tools/edit.js +157 -0
- package/dist/lib/agent/tools/edit.js.map +1 -0
- package/dist/lib/agent/tools/glob.js +137 -0
- package/dist/lib/agent/tools/glob.js.map +1 -0
- package/dist/lib/agent/tools/grep.js +315 -0
- package/dist/lib/agent/tools/grep.js.map +1 -0
- package/dist/lib/agent/tools/index.js +71 -0
- package/dist/lib/agent/tools/index.js.map +1 -0
- package/dist/lib/agent/tools/read.js +212 -0
- package/dist/lib/agent/tools/read.js.map +1 -0
- package/dist/lib/agent/tools/types.js +197 -0
- package/dist/lib/agent/tools/types.js.map +1 -0
- package/dist/lib/agent/tools/write.js +159 -0
- package/dist/lib/agent/tools/write.js.map +1 -0
- package/dist/lib/ai/gateway.js +247 -0
- package/dist/lib/ai/gateway.js.map +1 -0
- package/dist/lib/ai/tool-loop-agent.js +591 -0
- package/dist/lib/ai/tool-loop-agent.js.map +1 -0
- package/dist/lib/auto-wiring.js +439 -0
- package/dist/lib/auto-wiring.js.map +1 -0
- package/dist/lib/browse/browserbase.js +163 -0
- package/dist/lib/browse/browserbase.js.map +1 -0
- package/dist/lib/browse/cloudflare.js +144 -0
- package/dist/lib/browse/cloudflare.js.map +1 -0
- package/dist/lib/browse/index.js +62 -0
- package/dist/lib/browse/index.js.map +1 -0
- package/dist/lib/browse/types.js +13 -0
- package/dist/lib/browse/types.js.map +1 -0
- package/dist/lib/cache/index.js +37 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/visibility.js +638 -0
- package/dist/lib/cache/visibility.js.map +1 -0
- package/dist/lib/capabilities.js +268 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/channels/base.js +106 -0
- package/dist/lib/channels/base.js.map +1 -0
- package/dist/lib/channels/discord.js +94 -0
- package/dist/lib/channels/discord.js.map +1 -0
- package/dist/lib/channels/email.js +204 -0
- package/dist/lib/channels/email.js.map +1 -0
- package/dist/lib/channels/index.js +90 -0
- package/dist/lib/channels/index.js.map +1 -0
- package/dist/lib/channels/mdxui-chat.js +95 -0
- package/dist/lib/channels/mdxui-chat.js.map +1 -0
- package/dist/lib/channels/slack-blockkit.js +121 -0
- package/dist/lib/channels/slack-blockkit.js.map +1 -0
- package/dist/lib/channels/types.js +7 -0
- package/dist/lib/channels/types.js.map +1 -0
- package/dist/lib/cloudflare/ai.js +654 -0
- package/dist/lib/cloudflare/ai.js.map +1 -0
- package/dist/lib/cloudflare/index.js +88 -0
- package/dist/lib/cloudflare/index.js.map +1 -0
- package/dist/lib/cloudflare/kv.js +342 -0
- package/dist/lib/cloudflare/kv.js.map +1 -0
- package/dist/lib/cloudflare/queues.js +434 -0
- package/dist/lib/cloudflare/queues.js.map +1 -0
- package/dist/lib/cloudflare/r2.js +604 -0
- package/dist/lib/cloudflare/r2.js.map +1 -0
- package/dist/lib/cloudflare/vectorize.js +494 -0
- package/dist/lib/cloudflare/vectorize.js.map +1 -0
- package/dist/lib/cloudflare/workflows.js +569 -0
- package/dist/lib/cloudflare/workflows.js.map +1 -0
- package/dist/lib/colo/caching.js +196 -0
- package/dist/lib/colo/caching.js.map +1 -0
- package/dist/lib/colo/detection.js +194 -0
- package/dist/lib/colo/detection.js.map +1 -0
- package/dist/lib/colo/external-data.js +219 -0
- package/dist/lib/colo/external-data.js.map +1 -0
- package/dist/lib/colo/globe-data.js +179 -0
- package/dist/lib/colo/globe-data.js.map +1 -0
- package/dist/lib/colo/index.js +16 -0
- package/dist/lib/colo/index.js.map +1 -0
- package/dist/lib/decorators.js +37 -0
- package/dist/lib/decorators.js.map +1 -0
- package/dist/lib/discovery.js +81 -0
- package/dist/lib/discovery.js.map +1 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
- package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/CascadeExecutor.js +418 -0
- package/dist/lib/executors/CascadeExecutor.js.map +1 -0
- package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/ParallelStepExecutor.js +308 -0
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
- package/dist/lib/executors/types.js +12 -0
- package/dist/lib/executors/types.js.map +1 -0
- package/dist/lib/experiments.js +89 -0
- package/dist/lib/experiments.js.map +1 -0
- package/dist/lib/flags/store.js +262 -0
- package/dist/lib/flags/store.js.map +1 -0
- package/dist/lib/functions/FunctionComposition.js +467 -0
- package/dist/lib/functions/FunctionComposition.js.map +1 -0
- package/dist/lib/functions/FunctionMiddleware.js +457 -0
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
- package/dist/lib/functions/FunctionRegistry.js +426 -0
- package/dist/lib/functions/FunctionRegistry.js.map +1 -0
- package/dist/lib/functions/createFunction.js +1048 -0
- package/dist/lib/functions/createFunction.js.map +1 -0
- package/dist/lib/humans/index.js +68 -0
- package/dist/lib/humans/index.js.map +1 -0
- package/dist/lib/humans/templates.js +117 -0
- package/dist/lib/humans/templates.js.map +1 -0
- package/dist/lib/identity.js +98 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logging/error-logger.js +163 -0
- package/dist/lib/logging/error-logger.js.map +1 -0
- package/dist/lib/logging/index.js +160 -0
- package/dist/lib/logging/index.js.map +1 -0
- package/dist/lib/mixins/bash.js +825 -0
- package/dist/lib/mixins/bash.js.map +1 -0
- package/dist/lib/mixins/fs.js +648 -0
- package/dist/lib/mixins/fs.js.map +1 -0
- package/dist/lib/mixins/git.js +1011 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/index.js +29 -0
- package/dist/lib/mixins/index.js.map +1 -0
- package/dist/lib/mixins/npm.js +662 -0
- package/dist/lib/mixins/npm.js.map +1 -0
- package/dist/lib/noun-id.js +278 -0
- package/dist/lib/noun-id.js.map +1 -0
- package/dist/lib/rate-limit/sliding-window.js +148 -0
- package/dist/lib/rate-limit/sliding-window.js.map +1 -0
- package/dist/lib/rate-limit.js +110 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/rpc/bindings.js +548 -0
- package/dist/lib/rpc/bindings.js.map +1 -0
- package/dist/lib/rpc/index.js +64 -0
- package/dist/lib/rpc/index.js.map +1 -0
- package/dist/lib/safe-stringify.js +223 -0
- package/dist/lib/safe-stringify.js.map +1 -0
- package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
- package/dist/lib/sqids.js +110 -0
- package/dist/lib/sqids.js.map +1 -0
- package/dist/lib/sql/adapters/index.js +10 -0
- package/dist/lib/sql/adapters/index.js.map +1 -0
- package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
- package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
- package/dist/lib/sql/index.js +277 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql/types.js +56 -0
- package/dist/lib/sql/types.js.map +1 -0
- package/dist/lib/type-classifier.js +126 -0
- package/dist/lib/type-classifier.js.map +1 -0
- package/dist/lib/utils/html.js +47 -0
- package/dist/lib/utils/html.js.map +1 -0
- package/dist/lib/validation.js +48 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/vault/store.js +411 -0
- package/dist/lib/vault/store.js.map +1 -0
- package/dist/metrics/hunch.js +739 -0
- package/dist/metrics/hunch.js.map +1 -0
- package/dist/objects/API.js +302 -0
- package/dist/objects/API.js.map +1 -0
- package/dist/objects/Agent.js +179 -0
- package/dist/objects/Agent.js.map +1 -0
- package/dist/objects/AgenticFunctionExecutor.js +8 -0
- package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
- package/dist/objects/App.js +83 -0
- package/dist/objects/App.js.map +1 -0
- package/dist/objects/Browser.js +884 -0
- package/dist/objects/Browser.js.map +1 -0
- package/dist/objects/Business.js +107 -0
- package/dist/objects/Business.js.map +1 -0
- package/dist/objects/CLI.js +221 -0
- package/dist/objects/CLI.js.map +1 -0
- package/dist/objects/CodeFunctionExecutor.js +8 -0
- package/dist/objects/CodeFunctionExecutor.js.map +1 -0
- package/dist/objects/Collection.js +161 -0
- package/dist/objects/Collection.js.map +1 -0
- package/dist/objects/DO.js +41 -0
- package/dist/objects/DO.js.map +1 -0
- package/dist/objects/DOBase.js +2309 -0
- package/dist/objects/DOBase.js.map +1 -0
- package/dist/objects/DOFull.js +1676 -0
- package/dist/objects/DOFull.js.map +1 -0
- package/dist/objects/DOTiny.js +207 -0
- package/dist/objects/DOTiny.js.map +1 -0
- package/dist/objects/Directory.js +199 -0
- package/dist/objects/Directory.js.map +1 -0
- package/dist/objects/Entity.js +413 -0
- package/dist/objects/Entity.js.map +1 -0
- package/dist/objects/Function.js +116 -0
- package/dist/objects/Function.js.map +1 -0
- package/dist/objects/Human.js +231 -0
- package/dist/objects/Human.js.map +1 -0
- package/dist/objects/HumanFunctionExecutor.js +8 -0
- package/dist/objects/HumanFunctionExecutor.js.map +1 -0
- package/dist/objects/IcebergMetadataDO.js +938 -0
- package/dist/objects/IcebergMetadataDO.js.map +1 -0
- package/dist/objects/IntegrationsDO.js +1174 -0
- package/dist/objects/IntegrationsDO.js.map +1 -0
- package/dist/objects/ObservabilityBroadcaster.js +149 -0
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
- package/dist/objects/Package.js +154 -0
- package/dist/objects/Package.js.map +1 -0
- package/dist/objects/Product.js +193 -0
- package/dist/objects/Product.js.map +1 -0
- package/dist/objects/SDK.js +152 -0
- package/dist/objects/SDK.js.map +1 -0
- package/dist/objects/SaaS.js +235 -0
- package/dist/objects/SaaS.js.map +1 -0
- package/dist/objects/SandboxDO.js +759 -0
- package/dist/objects/SandboxDO.js.map +1 -0
- package/dist/objects/Service.js +337 -0
- package/dist/objects/Service.js.map +1 -0
- package/dist/objects/Site.js +80 -0
- package/dist/objects/Site.js.map +1 -0
- package/dist/objects/Startup.js +479 -0
- package/dist/objects/Startup.js.map +1 -0
- package/dist/objects/ThingsDO.js +170 -0
- package/dist/objects/ThingsDO.js.map +1 -0
- package/dist/objects/VectorShardDO.js +648 -0
- package/dist/objects/VectorShardDO.js.map +1 -0
- package/dist/objects/Worker.js +144 -0
- package/dist/objects/Worker.js.map +1 -0
- package/dist/objects/Workflow.js +196 -0
- package/dist/objects/Workflow.js.map +1 -0
- package/dist/objects/WorkflowFactory.js +313 -0
- package/dist/objects/WorkflowFactory.js.map +1 -0
- package/dist/objects/WorkflowRuntime.js +863 -0
- package/dist/objects/WorkflowRuntime.js.map +1 -0
- package/dist/objects/circuit-breaker-bulkhead.js +178 -0
- package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
- package/dist/objects/createFunction.js +934 -0
- package/dist/objects/createFunction.js.map +1 -0
- package/dist/objects/index.js +80 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/objects/lifecycle/Branch.js +275 -0
- package/dist/objects/lifecycle/Branch.js.map +1 -0
- package/dist/objects/lifecycle/Clone.js +1499 -0
- package/dist/objects/lifecycle/Clone.js.map +1 -0
- package/dist/objects/lifecycle/Compact.js +237 -0
- package/dist/objects/lifecycle/Compact.js.map +1 -0
- package/dist/objects/lifecycle/Promote.js +476 -0
- package/dist/objects/lifecycle/Promote.js.map +1 -0
- package/dist/objects/lifecycle/Shard.js +560 -0
- package/dist/objects/lifecycle/Shard.js.map +1 -0
- package/dist/objects/lifecycle/index.js +15 -0
- package/dist/objects/lifecycle/index.js.map +1 -0
- package/dist/objects/lifecycle/types.js +33 -0
- package/dist/objects/lifecycle/types.js.map +1 -0
- package/dist/objects/mixins/infrastructure.js +171 -0
- package/dist/objects/mixins/infrastructure.js.map +1 -0
- package/dist/objects/modules/StoresModule.js +153 -0
- package/dist/objects/modules/StoresModule.js.map +1 -0
- package/dist/objects/persistence/checkpoint-manager.js +606 -0
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
- package/dist/objects/persistence/index.js +72 -0
- package/dist/objects/persistence/index.js.map +1 -0
- package/dist/objects/persistence/migration-runner.js +562 -0
- package/dist/objects/persistence/migration-runner.js.map +1 -0
- package/dist/objects/persistence/replication-manager.js +501 -0
- package/dist/objects/persistence/replication-manager.js.map +1 -0
- package/dist/objects/persistence/tiered-storage-manager.js +595 -0
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
- package/dist/objects/persistence/types.js +14 -0
- package/dist/objects/persistence/types.js.map +1 -0
- package/dist/objects/persistence/wal-manager.js +653 -0
- package/dist/objects/persistence/wal-manager.js.map +1 -0
- package/dist/objects/presets/index.js +20 -0
- package/dist/objects/presets/index.js.map +1 -0
- package/dist/objects/presets/primitives.js +188 -0
- package/dist/objects/presets/primitives.js.map +1 -0
- package/dist/objects/primitives/alarm-adapter.js +141 -0
- package/dist/objects/primitives/alarm-adapter.js.map +1 -0
- package/dist/objects/primitives/index.js +337 -0
- package/dist/objects/primitives/index.js.map +1 -0
- package/dist/objects/primitives/storage-adapter.js +182 -0
- package/dist/objects/primitives/storage-adapter.js.map +1 -0
- package/dist/objects/primitives/with-primitives.js +102 -0
- package/dist/objects/primitives/with-primitives.js.map +1 -0
- package/dist/objects/services/StoreManager.js +227 -0
- package/dist/objects/services/StoreManager.js.map +1 -0
- package/dist/objects/services/index.js +13 -0
- package/dist/objects/services/index.js.map +1 -0
- package/dist/objects/transport/auth-layer.js +1451 -0
- package/dist/objects/transport/auth-layer.js.map +1 -0
- package/dist/objects/transport/capnweb-target.js +355 -0
- package/dist/objects/transport/capnweb-target.js.map +1 -0
- package/dist/objects/transport/chain.js +441 -0
- package/dist/objects/transport/chain.js.map +1 -0
- package/dist/objects/transport/handler.js +58 -0
- package/dist/objects/transport/handler.js.map +1 -0
- package/dist/objects/transport/index.js +53 -0
- package/dist/objects/transport/index.js.map +1 -0
- package/dist/objects/transport/mcp-server.js +690 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1507 -0
- package/dist/objects/transport/rest-autowire.js.map +1 -0
- package/dist/objects/transport/rest-router.js +440 -0
- package/dist/objects/transport/rest-router.js.map +1 -0
- package/dist/objects/transport/rpc-server.js +1536 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +575 -0
- package/dist/objects/transport/shared.js.map +1 -0
- package/dist/objects/transport/sync-engine.js +291 -0
- package/dist/objects/transport/sync-engine.js.map +1 -0
- package/dist/objects/transport/types.js +8 -0
- package/dist/objects/transport/types.js.map +1 -0
- package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
- package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
- package/dist/primitives/bashx/src/ast/parser.js +1488 -0
- package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/container-executor.js +429 -0
- package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/index.js +668 -0
- package/dist/primitives/bashx/src/do/index.js.map +1 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/worker.js +352 -0
- package/dist/primitives/bashx/src/do/worker.js.map +1 -0
- package/dist/primitives/bashx/src/types.js +10 -0
- package/dist/primitives/bashx/src/types.js.map +1 -0
- package/dist/primitives/fsx/core/backend.js +480 -0
- package/dist/primitives/fsx/core/backend.js.map +1 -0
- package/dist/primitives/fsx/core/constants.js +140 -0
- package/dist/primitives/fsx/core/constants.js.map +1 -0
- package/dist/primitives/fsx/core/fsx.js +1184 -0
- package/dist/primitives/fsx/core/fsx.js.map +1 -0
- package/dist/primitives/fsx/core/glob/glob.js +438 -0
- package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
- package/dist/primitives/fsx/core/glob/index.js +8 -0
- package/dist/primitives/fsx/core/glob/index.js.map +1 -0
- package/dist/primitives/fsx/core/glob/match.js +392 -0
- package/dist/primitives/fsx/core/glob/match.js.map +1 -0
- package/dist/primitives/fsx/core/types.js +307 -0
- package/dist/primitives/fsx/core/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sdk/capnweb-compat.js +42 -0
- package/dist/sdk/capnweb-compat.js.map +1 -0
- package/dist/sdk/client.js +20 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/index.js +17 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/snippets/artifacts-config.js +241 -0
- package/dist/snippets/artifacts-config.js.map +1 -0
- package/dist/snippets/artifacts-ingest.js +832 -0
- package/dist/snippets/artifacts-ingest.js.map +1 -0
- package/dist/snippets/artifacts-serve.js +1035 -0
- package/dist/snippets/artifacts-serve.js.map +1 -0
- package/dist/snippets/artifacts-types.js +161 -0
- package/dist/snippets/artifacts-types.js.map +1 -0
- package/dist/snippets/cache-probe.js +376 -0
- package/dist/snippets/cache-probe.js.map +1 -0
- package/dist/snippets/cache.js +10 -0
- package/dist/snippets/cache.js.map +1 -0
- package/dist/snippets/events.js +469 -0
- package/dist/snippets/events.js.map +1 -0
- package/dist/snippets/index.js +7 -0
- package/dist/snippets/index.js.map +1 -0
- package/dist/snippets/proxy.js +495 -0
- package/dist/snippets/proxy.js.map +1 -0
- package/dist/snippets/search.js +1759 -0
- package/dist/snippets/search.js.map +1 -0
- package/dist/streams/index.js +30 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/observability.js +68 -0
- package/dist/streams/observability.js.map +1 -0
- package/dist/types/AI.js +92 -0
- package/dist/types/AI.js.map +1 -0
- package/dist/types/AIFunction.js +171 -0
- package/dist/types/AIFunction.js.map +1 -0
- package/dist/types/BrowseVerb.js +89 -0
- package/dist/types/BrowseVerb.js.map +1 -0
- package/dist/types/Browser.js +31 -0
- package/dist/types/Browser.js.map +1 -0
- package/dist/types/Chaos.js +15 -0
- package/dist/types/Chaos.js.map +1 -0
- package/dist/types/CloudflareBindings.js +109 -0
- package/dist/types/CloudflareBindings.js.map +1 -0
- package/dist/types/Collection.js +50 -0
- package/dist/types/Collection.js.map +1 -0
- package/dist/types/DO.js +2 -0
- package/dist/types/DO.js.map +1 -0
- package/dist/types/DOLocation.js +63 -0
- package/dist/types/DOLocation.js.map +1 -0
- package/dist/types/EventHandler.js +57 -0
- package/dist/types/EventHandler.js.map +1 -0
- package/dist/types/Experiment.js +33 -0
- package/dist/types/Experiment.js.map +1 -0
- package/dist/types/Flag.js +57 -0
- package/dist/types/Flag.js.map +1 -0
- package/dist/types/Lifecycle.js +13 -0
- package/dist/types/Lifecycle.js.map +1 -0
- package/dist/types/Location.js +169 -0
- package/dist/types/Location.js.map +1 -0
- package/dist/types/Noun.js +66 -0
- package/dist/types/Noun.js.map +1 -0
- package/dist/types/SessionEvent.js +194 -0
- package/dist/types/SessionEvent.js.map +1 -0
- package/dist/types/Thing.js +55 -0
- package/dist/types/Thing.js.map +1 -0
- package/dist/types/ThingDO.js +153 -0
- package/dist/types/ThingDO.js.map +1 -0
- package/dist/types/Things.js +2 -0
- package/dist/types/Things.js.map +1 -0
- package/dist/types/Verb.js +119 -0
- package/dist/types/Verb.js.map +1 -0
- package/dist/types/WorkflowContext.js +70 -0
- package/dist/types/WorkflowContext.js.map +1 -0
- package/dist/types/analytics-api.js +13 -0
- package/dist/types/analytics-api.js.map +1 -0
- package/dist/types/capabilities.js +135 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/drizzle.js +12 -0
- package/dist/types/drizzle.js.map +1 -0
- package/dist/types/event.js +201 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/fn.js +12 -0
- package/dist/types/fn.js.map +1 -0
- package/dist/types/iceberg.js +48 -0
- package/dist/types/iceberg.js.map +1 -0
- package/dist/types/ids.js +170 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/introspect.js +54 -0
- package/dist/types/introspect.js.map +1 -0
- package/dist/types/observability.js +124 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/sync-protocol.js +175 -0
- package/dist/types/sync-protocol.js.map +1 -0
- package/dist/types/vector.js +13 -0
- package/dist/types/vector.js.map +1 -0
- package/dist/workflows/ScheduleManager.js +473 -0
- package/dist/workflows/ScheduleManager.js.map +1 -0
- package/dist/workflows/StepDOBridge.js +149 -0
- package/dist/workflows/StepDOBridge.js.map +1 -0
- package/dist/workflows/StepResultStorage.js +232 -0
- package/dist/workflows/StepResultStorage.js.map +1 -0
- package/dist/workflows/WaitForEventManager.js +461 -0
- package/dist/workflows/WaitForEventManager.js.map +1 -0
- package/dist/workflows/analyzer.js +332 -0
- package/dist/workflows/analyzer.js.map +1 -0
- package/dist/workflows/compat/activity-router.js +484 -0
- package/dist/workflows/compat/activity-router.js.map +1 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
- package/dist/workflows/compat/backends/index.js +14 -0
- package/dist/workflows/compat/backends/index.js.map +1 -0
- package/dist/workflows/compat/errors/index.js +375 -0
- package/dist/workflows/compat/errors/index.js.map +1 -0
- package/dist/workflows/compat/index.js +79 -0
- package/dist/workflows/compat/index.js.map +1 -0
- package/dist/workflows/compat/inngest/index.js +989 -0
- package/dist/workflows/compat/inngest/index.js.map +1 -0
- package/dist/workflows/compat/qstash/index.js +1263 -0
- package/dist/workflows/compat/qstash/index.js.map +1 -0
- package/dist/workflows/compat/temporal/activities.js +739 -0
- package/dist/workflows/compat/temporal/activities.js.map +1 -0
- package/dist/workflows/compat/temporal/child-workflows.js +154 -0
- package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
- package/dist/workflows/compat/temporal/client.js +381 -0
- package/dist/workflows/compat/temporal/client.js.map +1 -0
- package/dist/workflows/compat/temporal/context.js +309 -0
- package/dist/workflows/compat/temporal/context.js.map +1 -0
- package/dist/workflows/compat/temporal/determinism.js +216 -0
- package/dist/workflows/compat/temporal/determinism.js.map +1 -0
- package/dist/workflows/compat/temporal/errors.js +128 -0
- package/dist/workflows/compat/temporal/errors.js.map +1 -0
- package/dist/workflows/compat/temporal/index.js +2464 -0
- package/dist/workflows/compat/temporal/index.js.map +1 -0
- package/dist/workflows/compat/temporal/saga.js +504 -0
- package/dist/workflows/compat/temporal/saga.js.map +1 -0
- package/dist/workflows/compat/temporal/signals.js +364 -0
- package/dist/workflows/compat/temporal/signals.js.map +1 -0
- package/dist/workflows/compat/temporal/storage.js +271 -0
- package/dist/workflows/compat/temporal/storage.js.map +1 -0
- package/dist/workflows/compat/temporal/timers.js +347 -0
- package/dist/workflows/compat/temporal/timers.js.map +1 -0
- package/dist/workflows/compat/temporal/types.js +7 -0
- package/dist/workflows/compat/temporal/types.js.map +1 -0
- package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
- package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
- package/dist/workflows/compat/trigger/index.js +468 -0
- package/dist/workflows/compat/trigger/index.js.map +1 -0
- package/dist/workflows/compat/utils/index.js +69 -0
- package/dist/workflows/compat/utils/index.js.map +1 -0
- package/dist/workflows/context/correlation-capability.js +266 -0
- package/dist/workflows/context/correlation-capability.js.map +1 -0
- package/dist/workflows/context/correlation.js +484 -0
- package/dist/workflows/context/correlation.js.map +1 -0
- package/dist/workflows/context/experiment.js +289 -0
- package/dist/workflows/context/experiment.js.map +1 -0
- package/dist/workflows/context/flag.js +244 -0
- package/dist/workflows/context/flag.js.map +1 -0
- package/dist/workflows/context/foundation.js +648 -0
- package/dist/workflows/context/foundation.js.map +1 -0
- package/dist/workflows/context/human-base.js +106 -0
- package/dist/workflows/context/human-base.js.map +1 -0
- package/dist/workflows/context/human.js +368 -0
- package/dist/workflows/context/human.js.map +1 -0
- package/dist/workflows/context/measure.js +354 -0
- package/dist/workflows/context/measure.js.map +1 -0
- package/dist/workflows/context/rate-limit.js +358 -0
- package/dist/workflows/context/rate-limit.js.map +1 -0
- package/dist/workflows/context/user.js +117 -0
- package/dist/workflows/context/user.js.map +1 -0
- package/dist/workflows/context/vault.js +360 -0
- package/dist/workflows/context/vault.js.map +1 -0
- package/dist/workflows/data/entity-events/entity-events.js +489 -0
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
- package/dist/workflows/data/experiment/index.js +599 -0
- package/dist/workflows/data/experiment/index.js.map +1 -0
- package/dist/workflows/data/goal/context.js +558 -0
- package/dist/workflows/data/goal/context.js.map +1 -0
- package/dist/workflows/data/goal/index.js +32 -0
- package/dist/workflows/data/goal/index.js.map +1 -0
- package/dist/workflows/data/measure/index.js +840 -0
- package/dist/workflows/data/measure/index.js.map +1 -0
- package/dist/workflows/data/stream/index.js +1215 -0
- package/dist/workflows/data/stream/index.js.map +1 -0
- package/dist/workflows/data/track/context.js +883 -0
- package/dist/workflows/data/track/context.js.map +1 -0
- package/dist/workflows/data/track/index.js +15 -0
- package/dist/workflows/data/track/index.js.map +1 -0
- package/dist/workflows/data/view/context.js +864 -0
- package/dist/workflows/data/view/context.js.map +1 -0
- package/dist/workflows/domain.js +93 -0
- package/dist/workflows/domain.js.map +1 -0
- package/dist/workflows/flag.js +176 -0
- package/dist/workflows/flag.js.map +1 -0
- package/dist/workflows/flags.js +217 -0
- package/dist/workflows/flags.js.map +1 -0
- package/dist/workflows/hash.js +209 -0
- package/dist/workflows/hash.js.map +1 -0
- package/dist/workflows/index.js +50 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/on.js +378 -0
- package/dist/workflows/on.js.map +1 -0
- package/dist/workflows/pipeline-promise.js +481 -0
- package/dist/workflows/pipeline-promise.js.map +1 -0
- package/dist/workflows/pipeline-types.js +20 -0
- package/dist/workflows/pipeline-types.js.map +1 -0
- package/dist/workflows/proxy.js +76 -0
- package/dist/workflows/proxy.js.map +1 -0
- package/dist/workflows/runtime.js +310 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/schedule-builder.js +327 -0
- package/dist/workflows/schedule-builder.js.map +1 -0
- package/dist/workflows/visibility/index.js +148 -0
- package/dist/workflows/visibility/index.js.map +1 -0
- package/dist/workflows/visibility/query-parser.js +150 -0
- package/dist/workflows/visibility/query-parser.js.map +1 -0
- package/dist/workflows/visibility/store.js +223 -0
- package/dist/workflows/visibility/store.js.map +1 -0
- package/dist/workflows/visibility/types.js +30 -0
- package/dist/workflows/visibility/types.js.map +1 -0
- package/dist/workflows/workflow.js +53 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/package.json +279 -46
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DAGScheduler - Workflow orchestration primitive
|
|
3
|
+
*
|
|
4
|
+
* Provides Directed Acyclic Graph scheduling with:
|
|
5
|
+
* - Task definitions with dependencies
|
|
6
|
+
* - Topological sort and cycle detection
|
|
7
|
+
* - Parallel execution with concurrency limits
|
|
8
|
+
* - Retry policies with exponential backoff
|
|
9
|
+
* - State persistence for recovery
|
|
10
|
+
* - Cron scheduling
|
|
11
|
+
* - Dynamic task generation
|
|
12
|
+
* - Cross-DAG dependencies
|
|
13
|
+
*
|
|
14
|
+
* @module db/primitives/dag-scheduler
|
|
15
|
+
*/
|
|
16
|
+
/** Create a dependency resolver */
|
|
17
|
+
export function createDependencyResolver() {
|
|
18
|
+
return {
|
|
19
|
+
getExecutionOrder(dag) {
|
|
20
|
+
const result = [];
|
|
21
|
+
const visited = new Set();
|
|
22
|
+
const inDegree = new Map();
|
|
23
|
+
// Calculate in-degrees
|
|
24
|
+
for (const [id, task] of dag.tasks) {
|
|
25
|
+
inDegree.set(id, task.dependencies.length);
|
|
26
|
+
}
|
|
27
|
+
// Kahn's algorithm
|
|
28
|
+
const queue = [];
|
|
29
|
+
for (const [id, degree] of inDegree) {
|
|
30
|
+
if (degree === 0)
|
|
31
|
+
queue.push(id);
|
|
32
|
+
}
|
|
33
|
+
while (queue.length > 0) {
|
|
34
|
+
const id = queue.shift();
|
|
35
|
+
visited.add(id);
|
|
36
|
+
result.push(dag.tasks.get(id));
|
|
37
|
+
// Find all tasks that depend on this one
|
|
38
|
+
for (const [depId, task] of dag.tasks) {
|
|
39
|
+
if (task.dependencies.includes(id)) {
|
|
40
|
+
const newDegree = inDegree.get(depId) - 1;
|
|
41
|
+
inDegree.set(depId, newDegree);
|
|
42
|
+
if (newDegree === 0 && !visited.has(depId)) {
|
|
43
|
+
queue.push(depId);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
},
|
|
50
|
+
detectCycles(dag) {
|
|
51
|
+
const visited = new Set();
|
|
52
|
+
const recursionStack = new Set();
|
|
53
|
+
const cycles = [];
|
|
54
|
+
function dfs(id, path) {
|
|
55
|
+
visited.add(id);
|
|
56
|
+
recursionStack.add(id);
|
|
57
|
+
path.push(id);
|
|
58
|
+
const task = dag.tasks.get(id);
|
|
59
|
+
if (task) {
|
|
60
|
+
for (const dep of task.dependencies) {
|
|
61
|
+
if (!visited.has(dep)) {
|
|
62
|
+
if (dfs(dep, [...path])) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (recursionStack.has(dep)) {
|
|
67
|
+
// Found cycle
|
|
68
|
+
const cycleStart = path.indexOf(dep);
|
|
69
|
+
cycles.push(path.slice(cycleStart));
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
recursionStack.delete(id);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
for (const id of dag.tasks.keys()) {
|
|
78
|
+
if (!visited.has(id)) {
|
|
79
|
+
dfs(id, []);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return cycles.length > 0 ? cycles : null;
|
|
83
|
+
},
|
|
84
|
+
getReadyTasks(dag, completed) {
|
|
85
|
+
const ready = [];
|
|
86
|
+
for (const [id, task] of dag.tasks) {
|
|
87
|
+
if (completed.has(id))
|
|
88
|
+
continue;
|
|
89
|
+
const allDepsComplete = task.dependencies.every((dep) => completed.has(dep));
|
|
90
|
+
if (allDepsComplete) {
|
|
91
|
+
ready.push(task);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return ready;
|
|
95
|
+
},
|
|
96
|
+
getDependents(dag, taskId, options) {
|
|
97
|
+
const directDependents = [];
|
|
98
|
+
for (const [_, task] of dag.tasks) {
|
|
99
|
+
if (task.dependencies.includes(taskId)) {
|
|
100
|
+
directDependents.push(task);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!options?.transitive) {
|
|
104
|
+
return directDependents;
|
|
105
|
+
}
|
|
106
|
+
// Get transitive dependents
|
|
107
|
+
const allDependents = new Set();
|
|
108
|
+
const queue = directDependents.map((t) => t.id);
|
|
109
|
+
while (queue.length > 0) {
|
|
110
|
+
const id = queue.shift();
|
|
111
|
+
if (allDependents.has(id))
|
|
112
|
+
continue;
|
|
113
|
+
allDependents.add(id);
|
|
114
|
+
for (const [_, task] of dag.tasks) {
|
|
115
|
+
if (task.dependencies.includes(id) && !allDependents.has(task.id)) {
|
|
116
|
+
queue.push(task.id);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return [...allDependents].map((id) => dag.tasks.get(id));
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// TASK NODE FACTORY
|
|
126
|
+
// ============================================================================
|
|
127
|
+
/** Create a task node */
|
|
128
|
+
export function createTaskNode(options) {
|
|
129
|
+
// Validation
|
|
130
|
+
if (!options.id || options.id.trim() === '') {
|
|
131
|
+
throw new Error('Task id cannot be empty');
|
|
132
|
+
}
|
|
133
|
+
if (options.dependencies.includes(options.id)) {
|
|
134
|
+
throw new Error('Task cannot depend on itself');
|
|
135
|
+
}
|
|
136
|
+
const uniqueDeps = new Set(options.dependencies);
|
|
137
|
+
if (uniqueDeps.size !== options.dependencies.length) {
|
|
138
|
+
throw new Error('Duplicate dependency detected');
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
id: options.id,
|
|
142
|
+
execute: options.execute,
|
|
143
|
+
dependencies: options.dependencies,
|
|
144
|
+
retryPolicy: options.retryPolicy,
|
|
145
|
+
timeout: options.timeout,
|
|
146
|
+
metadata: options.metadata,
|
|
147
|
+
dynamic: options.dynamic,
|
|
148
|
+
collectDynamic: options.collectDynamic,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// DAG FACTORY
|
|
153
|
+
// ============================================================================
|
|
154
|
+
/** Create a DAG */
|
|
155
|
+
export function createDAG(options) {
|
|
156
|
+
const tasks = new Map();
|
|
157
|
+
// Check for duplicate IDs
|
|
158
|
+
const ids = new Set();
|
|
159
|
+
for (const task of options.tasks) {
|
|
160
|
+
if (ids.has(task.id)) {
|
|
161
|
+
throw new Error(`Duplicate task id: ${task.id}`);
|
|
162
|
+
}
|
|
163
|
+
ids.add(task.id);
|
|
164
|
+
tasks.set(task.id, task);
|
|
165
|
+
}
|
|
166
|
+
// Validate dependencies exist
|
|
167
|
+
for (const task of options.tasks) {
|
|
168
|
+
for (const dep of task.dependencies) {
|
|
169
|
+
if (!ids.has(dep)) {
|
|
170
|
+
throw new Error(`Task '${task.id}' depends on unknown task '${dep}'`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Check for cycles
|
|
175
|
+
const resolver = createDependencyResolver();
|
|
176
|
+
const tempDag = {
|
|
177
|
+
id: options.id,
|
|
178
|
+
tasks,
|
|
179
|
+
run: async () => ({}),
|
|
180
|
+
};
|
|
181
|
+
const cycles = resolver.detectCycles(tempDag);
|
|
182
|
+
if (cycles) {
|
|
183
|
+
throw new Error(`Cycle detected in DAG: ${cycles[0].join(' -> ')}`);
|
|
184
|
+
}
|
|
185
|
+
const dag = {
|
|
186
|
+
id: options.id,
|
|
187
|
+
tasks,
|
|
188
|
+
schedule: options.schedule,
|
|
189
|
+
triggers: options.triggers,
|
|
190
|
+
run: async (execOptions) => {
|
|
191
|
+
const executor = createParallelExecutor(execOptions);
|
|
192
|
+
return executor.execute(dag, execOptions);
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
return dag;
|
|
196
|
+
}
|
|
197
|
+
/** Task decorator for fluent API */
|
|
198
|
+
export function task(id, execute, options) {
|
|
199
|
+
const dependencies = (options?.deps ?? []).map((d) => (typeof d === 'string' ? d : d.id));
|
|
200
|
+
return createTaskNode({ id, execute, dependencies });
|
|
201
|
+
}
|
|
202
|
+
/** Start building a DAG with fluent API */
|
|
203
|
+
export function dag(id, initialTasks) {
|
|
204
|
+
const tasks = initialTasks ? [...initialTasks] : [];
|
|
205
|
+
const builder = {
|
|
206
|
+
task(taskId, execute, options) {
|
|
207
|
+
const dependencies = (options?.deps ?? []).map((d) => (typeof d === 'string' ? d : d.id));
|
|
208
|
+
tasks.push(createTaskNode({
|
|
209
|
+
id: taskId,
|
|
210
|
+
execute,
|
|
211
|
+
dependencies,
|
|
212
|
+
timeout: options?.timeout,
|
|
213
|
+
retryPolicy: options?.retryPolicy,
|
|
214
|
+
}));
|
|
215
|
+
return builder;
|
|
216
|
+
},
|
|
217
|
+
build() {
|
|
218
|
+
return createDAG({ id, tasks });
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
return builder;
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// RETRY POLICY FACTORY
|
|
225
|
+
// ============================================================================
|
|
226
|
+
/** Create a retry policy with computed methods */
|
|
227
|
+
export function createRetryPolicy(config) {
|
|
228
|
+
const getDelay = (attempt) => {
|
|
229
|
+
const backoff = config.backoff;
|
|
230
|
+
switch (backoff.type) {
|
|
231
|
+
case 'fixed':
|
|
232
|
+
return backoff.delay;
|
|
233
|
+
case 'exponential': {
|
|
234
|
+
const delay = backoff.base * Math.pow(2, attempt - 1);
|
|
235
|
+
return Math.min(delay, backoff.max);
|
|
236
|
+
}
|
|
237
|
+
case 'exponential-jitter': {
|
|
238
|
+
const baseDelay = backoff.base * Math.pow(2, attempt - 1);
|
|
239
|
+
const cappedDelay = Math.min(baseDelay, backoff.max);
|
|
240
|
+
// Add jitter: random value between 0 and cappedDelay
|
|
241
|
+
return Math.random() * cappedDelay;
|
|
242
|
+
}
|
|
243
|
+
case 'custom':
|
|
244
|
+
return backoff.delays[attempt - 1] ?? backoff.delays[backoff.delays.length - 1];
|
|
245
|
+
default:
|
|
246
|
+
return 0;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
const shouldRetry = (attempt, error) => {
|
|
250
|
+
if (attempt >= config.maxAttempts)
|
|
251
|
+
return false;
|
|
252
|
+
if (config.retryableErrors && !config.retryableErrors(error))
|
|
253
|
+
return false;
|
|
254
|
+
return true;
|
|
255
|
+
};
|
|
256
|
+
return {
|
|
257
|
+
...config,
|
|
258
|
+
getDelay,
|
|
259
|
+
shouldRetry,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/** Create a parallel executor */
|
|
263
|
+
export function createParallelExecutor(defaultOptions) {
|
|
264
|
+
let cancelled = false;
|
|
265
|
+
let paused = false;
|
|
266
|
+
let pausePromise = null;
|
|
267
|
+
let resumePause = null;
|
|
268
|
+
const dagCompleteCallbacks = [];
|
|
269
|
+
const waitForResume = () => {
|
|
270
|
+
if (!paused)
|
|
271
|
+
return Promise.resolve();
|
|
272
|
+
if (!pausePromise) {
|
|
273
|
+
pausePromise = new Promise((resolve) => {
|
|
274
|
+
resumePause = resolve;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return pausePromise;
|
|
278
|
+
};
|
|
279
|
+
const executeWithTimeout = async (fn, timeout) => {
|
|
280
|
+
if (!timeout)
|
|
281
|
+
return fn();
|
|
282
|
+
return Promise.race([
|
|
283
|
+
fn(),
|
|
284
|
+
new Promise((_, reject) => {
|
|
285
|
+
setTimeout(() => reject(new Error('Task timeout exceeded')), timeout);
|
|
286
|
+
}),
|
|
287
|
+
]);
|
|
288
|
+
};
|
|
289
|
+
const executeTask = async (task, context, options) => {
|
|
290
|
+
const result = {
|
|
291
|
+
taskId: task.id,
|
|
292
|
+
status: 'running',
|
|
293
|
+
attempts: 0,
|
|
294
|
+
startedAt: new Date(),
|
|
295
|
+
};
|
|
296
|
+
const policy = task.retryPolicy ? createRetryPolicy(task.retryPolicy) : null;
|
|
297
|
+
const maxAttempts = policy?.maxAttempts ?? 1;
|
|
298
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
299
|
+
result.attempts = attempt;
|
|
300
|
+
try {
|
|
301
|
+
await waitForResume();
|
|
302
|
+
if (cancelled) {
|
|
303
|
+
result.status = 'skipped';
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
options?.onTaskStart?.(task);
|
|
307
|
+
const timeout = task.timeout ?? options?.taskTimeout;
|
|
308
|
+
const output = await executeWithTimeout(() => task.execute(context), timeout);
|
|
309
|
+
result.status = 'success';
|
|
310
|
+
result.output = output;
|
|
311
|
+
result.completedAt = new Date();
|
|
312
|
+
options?.onTaskComplete?.(task, result);
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
317
|
+
if (policy && policy.shouldRetry(attempt, err)) {
|
|
318
|
+
policy.onRetry?.(attempt, err);
|
|
319
|
+
await new Promise((resolve) => setTimeout(resolve, policy.getDelay(attempt)));
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
result.status = 'failed';
|
|
323
|
+
result.error = err;
|
|
324
|
+
result.completedAt = new Date();
|
|
325
|
+
options?.onTaskComplete?.(task, result);
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return result;
|
|
330
|
+
};
|
|
331
|
+
const executor = {
|
|
332
|
+
async execute(dag, options) {
|
|
333
|
+
const mergedOptions = { ...defaultOptions, ...options };
|
|
334
|
+
const maxConcurrency = mergedOptions?.maxConcurrency ?? Infinity;
|
|
335
|
+
const resolver = createDependencyResolver();
|
|
336
|
+
const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
337
|
+
const run = {
|
|
338
|
+
runId,
|
|
339
|
+
dagId: dag.id,
|
|
340
|
+
status: 'running',
|
|
341
|
+
taskResults: new Map(),
|
|
342
|
+
startedAt: new Date(),
|
|
343
|
+
};
|
|
344
|
+
// Initialize all tasks as pending
|
|
345
|
+
for (const [id] of dag.tasks) {
|
|
346
|
+
run.taskResults.set(id, { taskId: id, status: 'pending', attempts: 0 });
|
|
347
|
+
}
|
|
348
|
+
// Track expanded dynamic tasks
|
|
349
|
+
const dynamicTasks = new Map();
|
|
350
|
+
const dynamicResults = new Map();
|
|
351
|
+
const completed = new Set();
|
|
352
|
+
const failed = new Set();
|
|
353
|
+
const running = new Set();
|
|
354
|
+
const skipped = new Set();
|
|
355
|
+
// Get all tasks including dynamic
|
|
356
|
+
const getAllTasks = () => {
|
|
357
|
+
const all = new Map(dag.tasks);
|
|
358
|
+
for (const [id, task] of dynamicTasks) {
|
|
359
|
+
all.set(id, task);
|
|
360
|
+
}
|
|
361
|
+
return all;
|
|
362
|
+
};
|
|
363
|
+
// Mark downstream tasks as skipped
|
|
364
|
+
const skipDownstream = (taskId) => {
|
|
365
|
+
const allTasks = getAllTasks();
|
|
366
|
+
for (const [id, task] of allTasks) {
|
|
367
|
+
if (task.dependencies.includes(taskId) && !completed.has(id) && !failed.has(id)) {
|
|
368
|
+
skipped.add(id);
|
|
369
|
+
run.taskResults.set(id, { taskId: id, status: 'skipped', attempts: 0 });
|
|
370
|
+
skipDownstream(id);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
// Process tasks
|
|
375
|
+
while (true) {
|
|
376
|
+
await waitForResume();
|
|
377
|
+
if (cancelled) {
|
|
378
|
+
run.status = 'cancelled';
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
const allTasks = getAllTasks();
|
|
382
|
+
const pendingCount = allTasks.size - completed.size - failed.size - running.size - skipped.size;
|
|
383
|
+
if (pendingCount === 0 && running.size === 0) {
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
// Find ready tasks
|
|
387
|
+
const ready = [];
|
|
388
|
+
for (const [id, task] of allTasks) {
|
|
389
|
+
if (completed.has(id) || failed.has(id) || running.has(id) || skipped.has(id))
|
|
390
|
+
continue;
|
|
391
|
+
const allDepsComplete = task.dependencies.every((dep) => completed.has(dep) || dynamicResults.has(dep));
|
|
392
|
+
const anyDepFailed = task.dependencies.some((dep) => failed.has(dep) || skipped.has(dep));
|
|
393
|
+
if (anyDepFailed) {
|
|
394
|
+
skipped.add(id);
|
|
395
|
+
run.taskResults.set(id, { taskId: id, status: 'skipped', attempts: 0 });
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (allDepsComplete) {
|
|
399
|
+
ready.push(task);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (ready.length === 0 && running.size === 0) {
|
|
403
|
+
// No progress possible
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
// Start tasks up to concurrency limit
|
|
407
|
+
const toStart = ready.slice(0, maxConcurrency - running.size);
|
|
408
|
+
const taskPromises = toStart.map(async (task) => {
|
|
409
|
+
running.add(task.id);
|
|
410
|
+
// Build context with upstream results
|
|
411
|
+
const upstreamResults = {};
|
|
412
|
+
for (const dep of task.dependencies) {
|
|
413
|
+
const depResult = run.taskResults.get(dep);
|
|
414
|
+
if (depResult?.status === 'success') {
|
|
415
|
+
upstreamResults[dep] = depResult.output;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
// Add dynamic results if collecting
|
|
419
|
+
let dynResults;
|
|
420
|
+
if (task.collectDynamic) {
|
|
421
|
+
// Find the dynamic parent task
|
|
422
|
+
for (const dep of task.dependencies) {
|
|
423
|
+
if (dynamicResults.has(dep)) {
|
|
424
|
+
dynResults = dynamicResults.get(dep);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const context = {
|
|
429
|
+
runId,
|
|
430
|
+
dagId: dag.id,
|
|
431
|
+
upstreamResults,
|
|
432
|
+
triggerPayload: mergedOptions?.triggerPayload,
|
|
433
|
+
dynamicResults: dynResults,
|
|
434
|
+
};
|
|
435
|
+
const result = await executeTask(task, context, mergedOptions);
|
|
436
|
+
run.taskResults.set(task.id, result);
|
|
437
|
+
// Save to state store if available
|
|
438
|
+
if (mergedOptions?.stateStore) {
|
|
439
|
+
await mergedOptions.stateStore.updateTask(runId, task.id, result);
|
|
440
|
+
}
|
|
441
|
+
running.delete(task.id);
|
|
442
|
+
if (result.status === 'success') {
|
|
443
|
+
completed.add(task.id);
|
|
444
|
+
// Handle dynamic task expansion
|
|
445
|
+
if (task.dynamic) {
|
|
446
|
+
// Get the upstream result to expand from (first dependency's output)
|
|
447
|
+
const upstreamOutput = task.dependencies.length > 0
|
|
448
|
+
? upstreamResults[task.dependencies[0]]
|
|
449
|
+
: result.output;
|
|
450
|
+
let expandedTasks = task.dynamic.expand(upstreamOutput);
|
|
451
|
+
// Apply max expansion limit
|
|
452
|
+
if (task.dynamic.maxExpansion) {
|
|
453
|
+
expandedTasks = expandedTasks.slice(0, task.dynamic.maxExpansion);
|
|
454
|
+
}
|
|
455
|
+
const expandedResults = [];
|
|
456
|
+
for (const expandedTask of expandedTasks) {
|
|
457
|
+
dynamicTasks.set(expandedTask.id, expandedTask);
|
|
458
|
+
run.taskResults.set(expandedTask.id, {
|
|
459
|
+
taskId: expandedTask.id,
|
|
460
|
+
status: 'pending',
|
|
461
|
+
attempts: 0,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
// Store reference for fan-in collection
|
|
465
|
+
dynamicResults.set(task.id, expandedResults);
|
|
466
|
+
// Execute dynamic tasks and collect results
|
|
467
|
+
for (const expandedTask of expandedTasks) {
|
|
468
|
+
const dynResult = await executeTask(expandedTask, { runId, dagId: dag.id }, mergedOptions);
|
|
469
|
+
run.taskResults.set(expandedTask.id, dynResult);
|
|
470
|
+
if (dynResult.status === 'success') {
|
|
471
|
+
completed.add(expandedTask.id);
|
|
472
|
+
expandedResults.push(dynResult.output);
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
failed.add(expandedTask.id);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else if (result.status === 'failed') {
|
|
481
|
+
failed.add(task.id);
|
|
482
|
+
skipDownstream(task.id);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
// Wait for at least one task to complete
|
|
486
|
+
if (taskPromises.length > 0) {
|
|
487
|
+
await Promise.race(taskPromises);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
// Give other tasks a chance to complete
|
|
491
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
// Determine final status
|
|
495
|
+
if (run.status !== 'cancelled') {
|
|
496
|
+
run.status = failed.size > 0 ? 'failed' : 'completed';
|
|
497
|
+
}
|
|
498
|
+
run.completedAt = new Date();
|
|
499
|
+
// Save final state
|
|
500
|
+
if (mergedOptions?.stateStore) {
|
|
501
|
+
await mergedOptions.stateStore.saveRun(runId, {
|
|
502
|
+
runId,
|
|
503
|
+
dagId: dag.id,
|
|
504
|
+
status: run.status,
|
|
505
|
+
taskResults: run.taskResults,
|
|
506
|
+
startedAt: run.startedAt,
|
|
507
|
+
completedAt: run.completedAt,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
// Fire completion callbacks
|
|
511
|
+
for (const callback of dagCompleteCallbacks) {
|
|
512
|
+
try {
|
|
513
|
+
await callback(dag.id, run);
|
|
514
|
+
}
|
|
515
|
+
catch {
|
|
516
|
+
// Ignore callback errors
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return run;
|
|
520
|
+
},
|
|
521
|
+
async cancel() {
|
|
522
|
+
cancelled = true;
|
|
523
|
+
},
|
|
524
|
+
pause() {
|
|
525
|
+
paused = true;
|
|
526
|
+
pausePromise = null;
|
|
527
|
+
resumePause = null;
|
|
528
|
+
},
|
|
529
|
+
resume(runIdOrVoid, dag) {
|
|
530
|
+
// Handle overloaded signature
|
|
531
|
+
if (typeof runIdOrVoid === 'string' && dag) {
|
|
532
|
+
// Resume from checkpoint
|
|
533
|
+
return this.resumeFromCheckpoint(runIdOrVoid, dag);
|
|
534
|
+
}
|
|
535
|
+
// Regular resume from pause
|
|
536
|
+
paused = false;
|
|
537
|
+
if (resumePause) {
|
|
538
|
+
resumePause();
|
|
539
|
+
resumePause = null;
|
|
540
|
+
pausePromise = null;
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
async resumeFromCheckpoint(runId, dag) {
|
|
544
|
+
const mergedOptions = defaultOptions;
|
|
545
|
+
const store = mergedOptions?.stateStore;
|
|
546
|
+
if (!store) {
|
|
547
|
+
throw new Error('State store required for resume');
|
|
548
|
+
}
|
|
549
|
+
const savedState = await store.loadRun(runId);
|
|
550
|
+
if (!savedState) {
|
|
551
|
+
throw new Error(`Run ${runId} not found`);
|
|
552
|
+
}
|
|
553
|
+
// Create run from saved state
|
|
554
|
+
const run = {
|
|
555
|
+
runId: savedState.runId,
|
|
556
|
+
dagId: savedState.dagId,
|
|
557
|
+
status: 'running',
|
|
558
|
+
taskResults: new Map(savedState.taskResults),
|
|
559
|
+
startedAt: savedState.startedAt,
|
|
560
|
+
};
|
|
561
|
+
const resolver = createDependencyResolver();
|
|
562
|
+
const maxConcurrency = mergedOptions?.maxConcurrency ?? Infinity;
|
|
563
|
+
const completed = new Set();
|
|
564
|
+
const failed = new Set();
|
|
565
|
+
const running = new Set();
|
|
566
|
+
// Restore completed/failed from saved state
|
|
567
|
+
for (const [id, result] of run.taskResults) {
|
|
568
|
+
if (result.status === 'success') {
|
|
569
|
+
completed.add(id);
|
|
570
|
+
}
|
|
571
|
+
else if (result.status === 'failed') {
|
|
572
|
+
failed.add(id);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// Continue execution
|
|
576
|
+
while (true) {
|
|
577
|
+
const pendingCount = dag.tasks.size - completed.size - failed.size - running.size;
|
|
578
|
+
if (pendingCount === 0 && running.size === 0)
|
|
579
|
+
break;
|
|
580
|
+
const ready = resolver.getReadyTasks(dag, completed).filter((t) => !failed.has(t.id) && !running.has(t.id));
|
|
581
|
+
if (ready.length === 0 && running.size === 0)
|
|
582
|
+
break;
|
|
583
|
+
const toStart = ready.slice(0, maxConcurrency - running.size);
|
|
584
|
+
const taskPromises = toStart.map(async (task) => {
|
|
585
|
+
running.add(task.id);
|
|
586
|
+
const upstreamResults = {};
|
|
587
|
+
for (const dep of task.dependencies) {
|
|
588
|
+
const depResult = run.taskResults.get(dep);
|
|
589
|
+
if (depResult?.status === 'success') {
|
|
590
|
+
upstreamResults[dep] = depResult.output;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
const context = {
|
|
594
|
+
runId,
|
|
595
|
+
dagId: dag.id,
|
|
596
|
+
upstreamResults,
|
|
597
|
+
};
|
|
598
|
+
const result = await executeTask(task, context, mergedOptions);
|
|
599
|
+
run.taskResults.set(task.id, result);
|
|
600
|
+
await store.updateTask(runId, task.id, result);
|
|
601
|
+
running.delete(task.id);
|
|
602
|
+
if (result.status === 'success') {
|
|
603
|
+
completed.add(task.id);
|
|
604
|
+
}
|
|
605
|
+
else if (result.status === 'failed') {
|
|
606
|
+
failed.add(task.id);
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
if (taskPromises.length > 0) {
|
|
610
|
+
await Promise.race(taskPromises);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
run.status = failed.size > 0 ? 'failed' : 'completed';
|
|
617
|
+
run.completedAt = new Date();
|
|
618
|
+
await store.saveRun(runId, {
|
|
619
|
+
runId,
|
|
620
|
+
dagId: dag.id,
|
|
621
|
+
status: run.status,
|
|
622
|
+
taskResults: run.taskResults,
|
|
623
|
+
startedAt: run.startedAt,
|
|
624
|
+
completedAt: run.completedAt,
|
|
625
|
+
});
|
|
626
|
+
return run;
|
|
627
|
+
},
|
|
628
|
+
onDAGComplete(callback) {
|
|
629
|
+
dagCompleteCallbacks.push(callback);
|
|
630
|
+
},
|
|
631
|
+
};
|
|
632
|
+
return executor;
|
|
633
|
+
}
|
|
634
|
+
// ============================================================================
|
|
635
|
+
// STATE STORE FACTORY
|
|
636
|
+
// ============================================================================
|
|
637
|
+
/** Create an in-memory state store */
|
|
638
|
+
export function createInMemoryStateStore() {
|
|
639
|
+
const runs = new Map();
|
|
640
|
+
return {
|
|
641
|
+
async saveRun(runId, state) {
|
|
642
|
+
runs.set(runId, {
|
|
643
|
+
...state,
|
|
644
|
+
taskResults: new Map(state.taskResults),
|
|
645
|
+
});
|
|
646
|
+
},
|
|
647
|
+
async loadRun(runId) {
|
|
648
|
+
const state = runs.get(runId);
|
|
649
|
+
if (!state)
|
|
650
|
+
return null;
|
|
651
|
+
return {
|
|
652
|
+
...state,
|
|
653
|
+
taskResults: new Map(state.taskResults),
|
|
654
|
+
};
|
|
655
|
+
},
|
|
656
|
+
async updateTask(runId, taskId, result) {
|
|
657
|
+
const state = runs.get(runId);
|
|
658
|
+
if (state) {
|
|
659
|
+
state.taskResults.set(taskId, result);
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
async listRuns(dagId, options) {
|
|
663
|
+
const filtered = [...runs.values()].filter((r) => r.dagId === dagId);
|
|
664
|
+
if (options?.status) {
|
|
665
|
+
const statusFiltered = filtered.filter((r) => r.status === options.status);
|
|
666
|
+
return statusFiltered.slice(0, options?.limit);
|
|
667
|
+
}
|
|
668
|
+
return filtered.slice(0, options?.limit);
|
|
669
|
+
},
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
// ============================================================================
|
|
673
|
+
// CRON TRIGGER FACTORY
|
|
674
|
+
// ============================================================================
|
|
675
|
+
/** Day name to number mapping */
|
|
676
|
+
const DAY_NAMES = {
|
|
677
|
+
SUN: 0,
|
|
678
|
+
MON: 1,
|
|
679
|
+
TUE: 2,
|
|
680
|
+
WED: 3,
|
|
681
|
+
THU: 4,
|
|
682
|
+
FRI: 5,
|
|
683
|
+
SAT: 6,
|
|
684
|
+
};
|
|
685
|
+
/** Parse a cron expression */
|
|
686
|
+
export function parseCronExpression(expression) {
|
|
687
|
+
const parts = expression.trim().split(/\s+/);
|
|
688
|
+
if (parts.length !== 5) {
|
|
689
|
+
throw new Error('Invalid cron expression: must have 5 parts');
|
|
690
|
+
}
|
|
691
|
+
const parsePart = (part, min, max) => {
|
|
692
|
+
if (part === '*')
|
|
693
|
+
return '*';
|
|
694
|
+
// Step pattern: */n
|
|
695
|
+
if (part.startsWith('*/')) {
|
|
696
|
+
const step = parseInt(part.slice(2), 10);
|
|
697
|
+
if (isNaN(step) || step <= 0) {
|
|
698
|
+
throw new Error(`Invalid step value: ${part}`);
|
|
699
|
+
}
|
|
700
|
+
return { step };
|
|
701
|
+
}
|
|
702
|
+
// Range pattern: n-m
|
|
703
|
+
if (part.includes('-')) {
|
|
704
|
+
const [startStr, endStr] = part.split('-');
|
|
705
|
+
let start = parseInt(startStr, 10);
|
|
706
|
+
let end = parseInt(endStr, 10);
|
|
707
|
+
// Handle day names
|
|
708
|
+
if (isNaN(start) && DAY_NAMES[startStr.toUpperCase()] !== undefined) {
|
|
709
|
+
start = DAY_NAMES[startStr.toUpperCase()];
|
|
710
|
+
}
|
|
711
|
+
if (isNaN(end) && DAY_NAMES[endStr.toUpperCase()] !== undefined) {
|
|
712
|
+
end = DAY_NAMES[endStr.toUpperCase()];
|
|
713
|
+
}
|
|
714
|
+
if (isNaN(start) || isNaN(end) || start < min || end > max) {
|
|
715
|
+
throw new Error(`Invalid range: ${part}`);
|
|
716
|
+
}
|
|
717
|
+
return { start, end };
|
|
718
|
+
}
|
|
719
|
+
// Single value
|
|
720
|
+
let value = parseInt(part, 10);
|
|
721
|
+
if (isNaN(value) && DAY_NAMES[part.toUpperCase()] !== undefined) {
|
|
722
|
+
value = DAY_NAMES[part.toUpperCase()];
|
|
723
|
+
}
|
|
724
|
+
if (isNaN(value) || value < min || value > max) {
|
|
725
|
+
throw new Error(`Invalid value: ${part} (must be ${min}-${max})`);
|
|
726
|
+
}
|
|
727
|
+
return value;
|
|
728
|
+
};
|
|
729
|
+
return {
|
|
730
|
+
minute: parsePart(parts[0], 0, 59),
|
|
731
|
+
hour: parsePart(parts[1], 0, 23),
|
|
732
|
+
dayOfMonth: parsePart(parts[2], 1, 31),
|
|
733
|
+
month: parsePart(parts[3], 1, 12),
|
|
734
|
+
dayOfWeek: parsePart(parts[4], 0, 6),
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
/** Create a cron trigger */
|
|
738
|
+
export function createCronTrigger(expression, options) {
|
|
739
|
+
const parsed = parseCronExpression(expression);
|
|
740
|
+
const opts = options ?? {};
|
|
741
|
+
const getNextValue = (current, spec, min, max) => {
|
|
742
|
+
if (spec === '*') {
|
|
743
|
+
return { value: current, wrapped: false };
|
|
744
|
+
}
|
|
745
|
+
if (typeof spec === 'number') {
|
|
746
|
+
if (current <= spec) {
|
|
747
|
+
return { value: spec, wrapped: false };
|
|
748
|
+
}
|
|
749
|
+
return { value: spec, wrapped: true };
|
|
750
|
+
}
|
|
751
|
+
if ('step' in spec) {
|
|
752
|
+
const next = Math.ceil(current / spec.step) * spec.step;
|
|
753
|
+
if (next <= max) {
|
|
754
|
+
return { value: next, wrapped: false };
|
|
755
|
+
}
|
|
756
|
+
return { value: 0, wrapped: true };
|
|
757
|
+
}
|
|
758
|
+
if ('start' in spec && 'end' in spec) {
|
|
759
|
+
if (current >= spec.start && current <= spec.end) {
|
|
760
|
+
return { value: current, wrapped: false };
|
|
761
|
+
}
|
|
762
|
+
if (current < spec.start) {
|
|
763
|
+
return { value: spec.start, wrapped: false };
|
|
764
|
+
}
|
|
765
|
+
return { value: spec.start, wrapped: true };
|
|
766
|
+
}
|
|
767
|
+
return { value: current, wrapped: false };
|
|
768
|
+
};
|
|
769
|
+
return {
|
|
770
|
+
expression,
|
|
771
|
+
options: opts,
|
|
772
|
+
getNextRun(from) {
|
|
773
|
+
// Adjust for timezone
|
|
774
|
+
let date = new Date(from);
|
|
775
|
+
if (opts.timezone) {
|
|
776
|
+
// Simple timezone offset (for production, use a proper library)
|
|
777
|
+
const offset = getTimezoneOffset(opts.timezone, date);
|
|
778
|
+
date = new Date(date.getTime() + offset);
|
|
779
|
+
}
|
|
780
|
+
// Start from next minute
|
|
781
|
+
date = new Date(date);
|
|
782
|
+
date.setUTCSeconds(0);
|
|
783
|
+
date.setUTCMilliseconds(0);
|
|
784
|
+
date.setUTCMinutes(date.getUTCMinutes() + 1);
|
|
785
|
+
// Iterate to find next match (max 366 days)
|
|
786
|
+
for (let i = 0; i < 366 * 24 * 60; i++) {
|
|
787
|
+
const minute = date.getUTCMinutes();
|
|
788
|
+
const hour = date.getUTCHours();
|
|
789
|
+
const dayOfMonth = date.getUTCDate();
|
|
790
|
+
const month = date.getUTCMonth() + 1;
|
|
791
|
+
const dayOfWeek = date.getUTCDay();
|
|
792
|
+
// Check if current time matches
|
|
793
|
+
if (matchesCronPart(minute, parsed.minute) &&
|
|
794
|
+
matchesCronPart(hour, parsed.hour) &&
|
|
795
|
+
matchesCronPart(dayOfMonth, parsed.dayOfMonth) &&
|
|
796
|
+
matchesCronPart(month, parsed.month) &&
|
|
797
|
+
matchesCronPart(dayOfWeek, parsed.dayOfWeek)) {
|
|
798
|
+
// Convert back from timezone
|
|
799
|
+
if (opts.timezone) {
|
|
800
|
+
const offset = getTimezoneOffset(opts.timezone, date);
|
|
801
|
+
return new Date(date.getTime() - offset);
|
|
802
|
+
}
|
|
803
|
+
return date;
|
|
804
|
+
}
|
|
805
|
+
// Advance by one minute
|
|
806
|
+
date.setUTCMinutes(date.getUTCMinutes() + 1);
|
|
807
|
+
}
|
|
808
|
+
throw new Error('Could not find next run time');
|
|
809
|
+
},
|
|
810
|
+
getMissedRuns(lastRun, now) {
|
|
811
|
+
if (!opts.catchup)
|
|
812
|
+
return [];
|
|
813
|
+
const missed = [];
|
|
814
|
+
let current = new Date(lastRun);
|
|
815
|
+
while (true) {
|
|
816
|
+
const next = this.getNextRun(current);
|
|
817
|
+
if (next >= now)
|
|
818
|
+
break;
|
|
819
|
+
missed.push(next);
|
|
820
|
+
current = next;
|
|
821
|
+
}
|
|
822
|
+
return missed;
|
|
823
|
+
},
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
/** Check if a value matches a cron part spec */
|
|
827
|
+
function matchesCronPart(value, spec) {
|
|
828
|
+
if (spec === '*')
|
|
829
|
+
return true;
|
|
830
|
+
if (typeof spec === 'number')
|
|
831
|
+
return value === spec;
|
|
832
|
+
if ('step' in spec)
|
|
833
|
+
return value % spec.step === 0;
|
|
834
|
+
if ('start' in spec && 'end' in spec)
|
|
835
|
+
return value >= spec.start && value <= spec.end;
|
|
836
|
+
return false;
|
|
837
|
+
}
|
|
838
|
+
/** Get timezone offset in milliseconds */
|
|
839
|
+
function getTimezoneOffset(timezone, date) {
|
|
840
|
+
// Simple implementation for common timezones
|
|
841
|
+
// In production, use Intl.DateTimeFormat or a library like date-fns-tz
|
|
842
|
+
const offsets = {
|
|
843
|
+
'America/New_York': -5 * 60 * 60 * 1000, // EST (simplified, doesn't handle DST)
|
|
844
|
+
'America/Los_Angeles': -8 * 60 * 60 * 1000,
|
|
845
|
+
'Europe/London': 0,
|
|
846
|
+
UTC: 0,
|
|
847
|
+
};
|
|
848
|
+
return offsets[timezone] ?? 0;
|
|
849
|
+
}
|
|
850
|
+
// ============================================================================
|
|
851
|
+
// SENSOR FACTORY
|
|
852
|
+
// ============================================================================
|
|
853
|
+
/** Create a sensor */
|
|
854
|
+
export function createSensor(options) {
|
|
855
|
+
return {
|
|
856
|
+
id: options.id,
|
|
857
|
+
async wait() {
|
|
858
|
+
const startTime = Date.now();
|
|
859
|
+
while (Date.now() - startTime < options.timeout) {
|
|
860
|
+
const result = await options.poke();
|
|
861
|
+
if (result)
|
|
862
|
+
return true;
|
|
863
|
+
await new Promise((resolve) => setTimeout(resolve, options.interval));
|
|
864
|
+
}
|
|
865
|
+
throw new Error(`Sensor ${options.id} timeout after ${options.timeout}ms`);
|
|
866
|
+
},
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
//# sourceMappingURL=index.js.map
|