dotdo 0.0.1 → 0.1.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/LICENSE +1 -1
- package/README.md +446 -315
- package/cli/README.md +238 -0
- package/cli/agent.ts +72 -0
- package/cli/bin.js +44 -0
- package/cli/bin.ts +38 -0
- package/cli/build.ts +157 -0
- package/cli/commands/auth/login.ts +14 -0
- package/cli/commands/auth/logout.ts +6 -0
- package/cli/commands/auth/whoami.ts +16 -0
- package/cli/commands/deploy-multi.ts +245 -0
- package/cli/commands/dev/deploy.ts +100 -0
- package/cli/commands/dev/dev.ts +95 -0
- package/cli/commands/dev/logs.ts +91 -0
- package/cli/commands/dev-local.ts +88 -0
- package/cli/commands/do-ops.ts +314 -0
- package/cli/commands/index.ts +100 -0
- package/cli/commands/init.ts +247 -0
- package/cli/commands/introspect/emitter.ts +315 -0
- package/cli/commands/introspect/index.ts +193 -0
- package/cli/commands/link.ts +598 -0
- package/cli/commands/snippets.ts +415 -0
- package/cli/commands/tunnel.ts +239 -0
- package/cli/device-auth.ts +289 -0
- package/cli/fallback.ts +12 -0
- package/cli/index.ts +121 -0
- package/cli/main.ts +246 -0
- package/cli/mcp-stdio.ts +790 -0
- package/cli/package.json +62 -0
- package/cli/runtime/do-registry.ts +193 -0
- package/cli/runtime/embedded-db.ts +344 -0
- package/cli/runtime/index.ts +9 -0
- package/cli/runtime/miniflare-adapter.ts +162 -0
- package/cli/sandbox.ts +82 -0
- package/cli/src/args.ts +174 -0
- package/cli/src/auth.ts +55 -0
- package/cli/src/commands/call.ts +84 -0
- package/cli/src/commands/charge.ts +96 -0
- package/cli/src/commands/config.ts +115 -0
- package/cli/src/commands/email.ts +112 -0
- package/cli/src/commands/llm.ts +115 -0
- package/cli/src/commands/queue.ts +134 -0
- package/cli/src/commands/text.ts +86 -0
- package/cli/src/config.ts +185 -0
- package/cli/src/output.ts +246 -0
- package/cli/src/rpc.ts +192 -0
- package/cli/utils/config.ts +282 -0
- package/cli/utils/detect.ts +73 -0
- package/cli/utils/index.ts +15 -0
- package/cli/utils/logger.ts +232 -0
- 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/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +545 -0
- package/dist/api/middleware/auth.js.map +1 -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 +116 -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/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/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 +753 -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 +1006 -0
- package/dist/lib/mixins/git.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 +1190 -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/DOCache.js +153 -0
- package/dist/objects/DOCache.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 +650 -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 +691 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1508 -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 +1539 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +576 -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/sandbox/index.js +258 -0
- package/dist/sandbox/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 +1149 -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 +146 -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 +294 -46
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inngest Compat Layer - 100% API Compatible with inngest
|
|
3
|
+
*
|
|
4
|
+
* Drop-in replacement for Inngest that runs on dotdo's
|
|
5
|
+
* durable execution infrastructure.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Inngest } from '@dotdo/inngest'
|
|
10
|
+
*
|
|
11
|
+
* const inngest = new Inngest({ id: 'my-app' })
|
|
12
|
+
*
|
|
13
|
+
* export const processOrder = inngest.createFunction(
|
|
14
|
+
* { id: 'process-order' },
|
|
15
|
+
* { event: 'order/created' },
|
|
16
|
+
* async ({ event, step }) => {
|
|
17
|
+
* const user = await step.run('fetch-user', async () => {
|
|
18
|
+
* return await fetchUser(event.data.userId)
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* await step.sleep('wait-a-bit', '1h')
|
|
22
|
+
*
|
|
23
|
+
* await step.run('send-email', async () => {
|
|
24
|
+
* await sendEmail(user.email, 'Order confirmed!')
|
|
25
|
+
* })
|
|
26
|
+
* }
|
|
27
|
+
* )
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { WaitForEventManager, WaitTimeoutError } from '../../WaitForEventManager';
|
|
31
|
+
import { DurableWorkflowRuntime, InMemoryStepStorage } from '../../runtime';
|
|
32
|
+
import { parseDuration, ensureError } from '../utils';
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// ERROR TYPES - Match Inngest SDK exactly
|
|
35
|
+
// ============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Error that should not be retried
|
|
38
|
+
*/
|
|
39
|
+
export class NonRetriableError extends Error {
|
|
40
|
+
isNonRetriableError = true;
|
|
41
|
+
cause;
|
|
42
|
+
constructor(message, options) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = 'NonRetriableError';
|
|
45
|
+
this.cause = options?.cause;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Error that specifies when to retry
|
|
50
|
+
*/
|
|
51
|
+
export class RetryAfterError extends Error {
|
|
52
|
+
isRetryAfterError = true;
|
|
53
|
+
retryAfter;
|
|
54
|
+
cause;
|
|
55
|
+
constructor(message, retryAfter, options) {
|
|
56
|
+
super(message);
|
|
57
|
+
this.name = 'RetryAfterError';
|
|
58
|
+
this.retryAfter = retryAfter;
|
|
59
|
+
this.cause = options?.cause;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Error from a step execution
|
|
64
|
+
*/
|
|
65
|
+
export class StepError extends Error {
|
|
66
|
+
isStepError = true;
|
|
67
|
+
stepId;
|
|
68
|
+
cause;
|
|
69
|
+
constructor(message, stepId, options) {
|
|
70
|
+
super(message);
|
|
71
|
+
this.name = 'StepError';
|
|
72
|
+
this.stepId = stepId;
|
|
73
|
+
this.cause = options?.cause;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Error thrown when a function is cancelled
|
|
78
|
+
*/
|
|
79
|
+
export class CancellationError extends Error {
|
|
80
|
+
isCancellationError = true;
|
|
81
|
+
runId;
|
|
82
|
+
reason;
|
|
83
|
+
constructor(runId, reason) {
|
|
84
|
+
super(reason ? `Function run ${runId} was cancelled: ${reason}` : `Function run ${runId} was cancelled`);
|
|
85
|
+
this.name = 'CancellationError';
|
|
86
|
+
this.runId = runId;
|
|
87
|
+
this.reason = reason;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Error thrown when step.invoke times out
|
|
92
|
+
*/
|
|
93
|
+
export class InvokeTimeoutError extends Error {
|
|
94
|
+
isInvokeTimeoutError = true;
|
|
95
|
+
functionId;
|
|
96
|
+
timeout;
|
|
97
|
+
constructor(functionId, timeout) {
|
|
98
|
+
super(`Invoked function ${functionId} timed out after ${timeout}ms`);
|
|
99
|
+
this.name = 'InvokeTimeoutError';
|
|
100
|
+
this.functionId = functionId;
|
|
101
|
+
this.timeout = timeout;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// UTILITIES
|
|
106
|
+
// Note: parseDuration and ensureError are imported from '../utils'
|
|
107
|
+
// ============================================================================
|
|
108
|
+
function generateRunId() {
|
|
109
|
+
return `run_${crypto.randomUUID().replace(/-/g, '')}`;
|
|
110
|
+
}
|
|
111
|
+
function generateEventId() {
|
|
112
|
+
return `evt_${crypto.randomUUID().replace(/-/g, '')}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get value from object using dot notation path
|
|
116
|
+
*/
|
|
117
|
+
function getValueByPath(obj, path) {
|
|
118
|
+
const parts = path.split('.');
|
|
119
|
+
let current = obj;
|
|
120
|
+
for (const part of parts) {
|
|
121
|
+
if (current === null || current === undefined)
|
|
122
|
+
return undefined;
|
|
123
|
+
current = current[part];
|
|
124
|
+
}
|
|
125
|
+
return current;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Evaluate simple expression against event context
|
|
129
|
+
*/
|
|
130
|
+
function evaluateExpression(expression, context) {
|
|
131
|
+
// Simple expression evaluation for common patterns
|
|
132
|
+
// Format: "event.data.field == async.data.field"
|
|
133
|
+
const equalMatch = expression.match(/^(.+?)\s*==\s*(.+)$/);
|
|
134
|
+
if (equalMatch) {
|
|
135
|
+
const leftPath = equalMatch[1].trim();
|
|
136
|
+
const rightPath = equalMatch[2].trim();
|
|
137
|
+
const leftValue = getValueByPath(context, leftPath);
|
|
138
|
+
const rightValue = getValueByPath(context, rightPath);
|
|
139
|
+
return leftValue === rightValue;
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const defaultLogger = {
|
|
144
|
+
info: console.log.bind(console),
|
|
145
|
+
warn: console.warn.bind(console),
|
|
146
|
+
error: console.error.bind(console),
|
|
147
|
+
debug: console.debug.bind(console),
|
|
148
|
+
};
|
|
149
|
+
class ThrottleManager {
|
|
150
|
+
/** Map of throttle key -> array of timestamps */
|
|
151
|
+
buckets = new Map();
|
|
152
|
+
/** Queue of pending executions by throttle key */
|
|
153
|
+
queues = new Map();
|
|
154
|
+
/**
|
|
155
|
+
* Acquire a throttle slot
|
|
156
|
+
* @returns Promise that resolves when slot is available
|
|
157
|
+
*/
|
|
158
|
+
async acquire(key, count, periodMs) {
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
// Get or create bucket
|
|
161
|
+
let bucket = this.buckets.get(key) || [];
|
|
162
|
+
// Remove expired entries
|
|
163
|
+
bucket = bucket.filter((ts) => now - ts < periodMs);
|
|
164
|
+
// Check if we have capacity
|
|
165
|
+
if (bucket.length < count) {
|
|
166
|
+
bucket.push(now);
|
|
167
|
+
this.buckets.set(key, bucket);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Queue this request
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
const queue = this.queues.get(key) || [];
|
|
173
|
+
queue.push({ resolve, reject, count, periodMs, addedAt: now });
|
|
174
|
+
this.queues.set(key, queue);
|
|
175
|
+
// Schedule retry when oldest entry expires
|
|
176
|
+
const oldestTs = bucket[0];
|
|
177
|
+
const waitTime = periodMs - (now - oldestTs) + 1;
|
|
178
|
+
this.scheduleQueueProcess(key, waitTime);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
scheduleQueueProcess(key, waitTime) {
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
this.processQueue(key);
|
|
184
|
+
// If there are still items in queue, schedule again
|
|
185
|
+
const queue = this.queues.get(key);
|
|
186
|
+
if (queue && queue.length > 0) {
|
|
187
|
+
const item = queue[0];
|
|
188
|
+
// Calculate remaining time properly based on when item was added
|
|
189
|
+
const elapsed = Date.now() - item.addedAt;
|
|
190
|
+
const remaining = Math.max(0, item.periodMs - elapsed);
|
|
191
|
+
this.scheduleQueueProcess(key, remaining);
|
|
192
|
+
}
|
|
193
|
+
}, waitTime);
|
|
194
|
+
}
|
|
195
|
+
processQueue(key) {
|
|
196
|
+
const queue = this.queues.get(key);
|
|
197
|
+
if (!queue || queue.length === 0)
|
|
198
|
+
return;
|
|
199
|
+
const item = queue[0];
|
|
200
|
+
const { count, periodMs } = item;
|
|
201
|
+
const now = Date.now();
|
|
202
|
+
let bucket = this.buckets.get(key) || [];
|
|
203
|
+
bucket = bucket.filter((ts) => now - ts < periodMs);
|
|
204
|
+
if (bucket.length < count) {
|
|
205
|
+
queue.shift();
|
|
206
|
+
bucket.push(now);
|
|
207
|
+
this.buckets.set(key, bucket);
|
|
208
|
+
this.queues.set(key, queue);
|
|
209
|
+
item.resolve();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ============================================================================
|
|
214
|
+
// CONCURRENCY MANAGER
|
|
215
|
+
// ============================================================================
|
|
216
|
+
class ConcurrencyManager {
|
|
217
|
+
/** Map of concurrency key -> current count */
|
|
218
|
+
active = new Map();
|
|
219
|
+
/** Queue of pending executions by concurrency key */
|
|
220
|
+
queues = new Map();
|
|
221
|
+
/**
|
|
222
|
+
* Acquire a concurrency slot
|
|
223
|
+
* @returns Promise that resolves when slot is available
|
|
224
|
+
*/
|
|
225
|
+
async acquire(key, limit) {
|
|
226
|
+
const current = this.active.get(key) || 0;
|
|
227
|
+
if (current < limit) {
|
|
228
|
+
this.active.set(key, current + 1);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Queue this request
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
const queue = this.queues.get(key) || [];
|
|
234
|
+
queue.push({ resolve, reject });
|
|
235
|
+
this.queues.set(key, queue);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Release a concurrency slot
|
|
240
|
+
*/
|
|
241
|
+
release(key) {
|
|
242
|
+
const current = this.active.get(key) || 0;
|
|
243
|
+
if (current > 0) {
|
|
244
|
+
this.active.set(key, current - 1);
|
|
245
|
+
}
|
|
246
|
+
// Process queue
|
|
247
|
+
const queue = this.queues.get(key);
|
|
248
|
+
if (queue && queue.length > 0) {
|
|
249
|
+
const item = queue.shift();
|
|
250
|
+
if (item) {
|
|
251
|
+
this.active.set(key, (this.active.get(key) || 0) + 1);
|
|
252
|
+
this.queues.set(key, queue);
|
|
253
|
+
item.resolve();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Reject all queued items (for cancellation)
|
|
259
|
+
*/
|
|
260
|
+
rejectQueued(key, error) {
|
|
261
|
+
const queue = this.queues.get(key) || [];
|
|
262
|
+
for (const item of queue) {
|
|
263
|
+
item.reject(error);
|
|
264
|
+
}
|
|
265
|
+
this.queues.set(key, []);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
class BatchManager {
|
|
269
|
+
batches = new Map();
|
|
270
|
+
/**
|
|
271
|
+
* Add event to batch, returns promise that resolves with all batched events
|
|
272
|
+
*/
|
|
273
|
+
addEvent(key, event, config, onBatchReady) {
|
|
274
|
+
let batch = this.batches.get(key);
|
|
275
|
+
if (!batch) {
|
|
276
|
+
batch = {
|
|
277
|
+
events: [],
|
|
278
|
+
timeoutId: null,
|
|
279
|
+
resolve: null,
|
|
280
|
+
};
|
|
281
|
+
this.batches.set(key, batch);
|
|
282
|
+
}
|
|
283
|
+
batch.events.push(event);
|
|
284
|
+
// Check if batch is full
|
|
285
|
+
if (batch.events.length >= config.maxSize) {
|
|
286
|
+
this.flushBatch(key, onBatchReady);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
// Set/reset timeout if not already set
|
|
290
|
+
if (!batch.timeoutId) {
|
|
291
|
+
const timeoutMs = parseDuration(config.timeout);
|
|
292
|
+
batch.timeoutId = setTimeout(() => {
|
|
293
|
+
this.flushBatch(key, onBatchReady);
|
|
294
|
+
}, timeoutMs);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
flushBatch(key, onBatchReady) {
|
|
298
|
+
const batch = this.batches.get(key);
|
|
299
|
+
if (!batch || batch.events.length === 0)
|
|
300
|
+
return;
|
|
301
|
+
if (batch.timeoutId) {
|
|
302
|
+
clearTimeout(batch.timeoutId);
|
|
303
|
+
}
|
|
304
|
+
const events = batch.events;
|
|
305
|
+
this.batches.delete(key);
|
|
306
|
+
onBatchReady(events);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// ============================================================================
|
|
310
|
+
// INNGEST FUNCTION
|
|
311
|
+
// ============================================================================
|
|
312
|
+
export class InngestFunction {
|
|
313
|
+
id;
|
|
314
|
+
name;
|
|
315
|
+
config;
|
|
316
|
+
trigger;
|
|
317
|
+
handler;
|
|
318
|
+
inngest;
|
|
319
|
+
constructor(inngest, config, trigger, handler) {
|
|
320
|
+
this.inngest = inngest;
|
|
321
|
+
this.config = config;
|
|
322
|
+
this.trigger = trigger;
|
|
323
|
+
this.handler = handler;
|
|
324
|
+
this.id = config.id;
|
|
325
|
+
this.name = config.name ?? config.id;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Get the event name this function listens for
|
|
329
|
+
*/
|
|
330
|
+
get eventName() {
|
|
331
|
+
if (typeof this.trigger === 'string') {
|
|
332
|
+
return this.trigger;
|
|
333
|
+
}
|
|
334
|
+
if ('event' in this.trigger) {
|
|
335
|
+
return this.trigger.event;
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Get the cron expression if this is a scheduled function
|
|
341
|
+
*/
|
|
342
|
+
get cronExpression() {
|
|
343
|
+
if (typeof this.trigger === 'object' && 'cron' in this.trigger) {
|
|
344
|
+
return this.trigger.cron;
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Invoke this function with an event
|
|
350
|
+
*/
|
|
351
|
+
async invoke(event) {
|
|
352
|
+
return this.inngest.invokeFunction(this, event);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// ============================================================================
|
|
356
|
+
// INNGEST CLIENT
|
|
357
|
+
// ============================================================================
|
|
358
|
+
export class Inngest {
|
|
359
|
+
id;
|
|
360
|
+
config;
|
|
361
|
+
runtime;
|
|
362
|
+
waitManager;
|
|
363
|
+
stepResults = new Map();
|
|
364
|
+
functions = new Map();
|
|
365
|
+
eventHandlers = new Map();
|
|
366
|
+
middleware;
|
|
367
|
+
logger;
|
|
368
|
+
// Run tracking
|
|
369
|
+
activeRuns = new Map();
|
|
370
|
+
runCancellations = new Map();
|
|
371
|
+
// Background task tracking for promise race condition prevention
|
|
372
|
+
runningTasks = new Map();
|
|
373
|
+
failedRuns = new Map();
|
|
374
|
+
// Throttle manager
|
|
375
|
+
throttleManager = new ThrottleManager();
|
|
376
|
+
// Concurrency manager
|
|
377
|
+
concurrencyManager = new ConcurrencyManager();
|
|
378
|
+
// Batch manager
|
|
379
|
+
batchManager = new BatchManager();
|
|
380
|
+
// Cancel event subscriptions: eventName -> Set of { functionId, cancelConfig }
|
|
381
|
+
cancelSubscriptions = new Map();
|
|
382
|
+
constructor(config) {
|
|
383
|
+
this.id = config.id;
|
|
384
|
+
this.config = config;
|
|
385
|
+
this.logger = config.logger ?? defaultLogger;
|
|
386
|
+
this.middleware = config.middleware ?? [];
|
|
387
|
+
this.runtime = new DurableWorkflowRuntime({
|
|
388
|
+
storage: config.storage ?? new InMemoryStepStorage(),
|
|
389
|
+
});
|
|
390
|
+
// Create wait manager if DO state is provided
|
|
391
|
+
this.waitManager = config.state ? new WaitForEventManager(config.state) : null;
|
|
392
|
+
// Initialize middleware
|
|
393
|
+
for (const mw of this.middleware) {
|
|
394
|
+
mw.init?.();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Create a new function
|
|
399
|
+
*/
|
|
400
|
+
createFunction(config, trigger, handler) {
|
|
401
|
+
const fn = new InngestFunction(this, config, trigger, handler);
|
|
402
|
+
this.functions.set(fn.id, fn);
|
|
403
|
+
// Register event handler
|
|
404
|
+
const eventName = fn.eventName;
|
|
405
|
+
if (eventName) {
|
|
406
|
+
if (!this.eventHandlers.has(eventName)) {
|
|
407
|
+
this.eventHandlers.set(eventName, new Set());
|
|
408
|
+
}
|
|
409
|
+
this.eventHandlers.get(eventName).add(fn);
|
|
410
|
+
}
|
|
411
|
+
// Register cancel subscriptions
|
|
412
|
+
if (config.cancelOn) {
|
|
413
|
+
for (const cancelConfig of config.cancelOn) {
|
|
414
|
+
if (!this.cancelSubscriptions.has(cancelConfig.event)) {
|
|
415
|
+
this.cancelSubscriptions.set(cancelConfig.event, new Set());
|
|
416
|
+
}
|
|
417
|
+
this.cancelSubscriptions.get(cancelConfig.event).add({
|
|
418
|
+
functionId: fn.id,
|
|
419
|
+
config: cancelConfig,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return fn;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Send one or more events
|
|
427
|
+
*/
|
|
428
|
+
async send(events) {
|
|
429
|
+
const eventArray = Array.isArray(events) ? events : [events];
|
|
430
|
+
// Apply middleware
|
|
431
|
+
let processedEvents = eventArray;
|
|
432
|
+
for (const mw of this.middleware) {
|
|
433
|
+
if (mw.onSendEvent) {
|
|
434
|
+
processedEvents = await mw.onSendEvent(processedEvents);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const ids = [];
|
|
438
|
+
for (const payload of processedEvents) {
|
|
439
|
+
const eventId = payload.id ?? generateEventId();
|
|
440
|
+
ids.push(eventId);
|
|
441
|
+
const event = {
|
|
442
|
+
...payload,
|
|
443
|
+
id: eventId,
|
|
444
|
+
ts: payload.ts ?? Date.now(),
|
|
445
|
+
};
|
|
446
|
+
// Check for cancellation events
|
|
447
|
+
await this.processCancellationEvent(event);
|
|
448
|
+
// Trigger handlers for this event
|
|
449
|
+
const handlers = this.eventHandlers.get(event.name);
|
|
450
|
+
if (handlers) {
|
|
451
|
+
handlers.forEach((fn) => {
|
|
452
|
+
// Check if function uses batching
|
|
453
|
+
if (fn.config.batchEvents) {
|
|
454
|
+
this.handleBatchedEvent(fn, event);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
// Execute in background with proper error tracking
|
|
458
|
+
const runId = generateRunId();
|
|
459
|
+
const runPromise = this.invokeFunction(fn, event)
|
|
460
|
+
.catch((error) => {
|
|
461
|
+
this.logger.error(`Function ${fn.id} failed:`, error);
|
|
462
|
+
// Track failed run for debugging and observability
|
|
463
|
+
this.failedRuns.set(runId, { error: error, timestamp: Date.now() });
|
|
464
|
+
// Clean up old failed runs after 1 hour
|
|
465
|
+
setTimeout(() => this.failedRuns.delete(runId), 3600000);
|
|
466
|
+
throw error; // Re-throw so callers can handle if needed
|
|
467
|
+
})
|
|
468
|
+
.finally(() => {
|
|
469
|
+
// Clean up running task reference
|
|
470
|
+
this.runningTasks.delete(runId);
|
|
471
|
+
});
|
|
472
|
+
this.runningTasks.set(runId, runPromise);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
// Deliver to any waiting step.waitForEvent calls
|
|
477
|
+
if (this.waitManager) {
|
|
478
|
+
await this.waitManager.deliverEvent(null, event.name, event);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return { ids };
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Handle batched event
|
|
485
|
+
*/
|
|
486
|
+
handleBatchedEvent(fn, event) {
|
|
487
|
+
const config = fn.config.batchEvents;
|
|
488
|
+
const keyPath = config.key;
|
|
489
|
+
// Calculate batch key
|
|
490
|
+
let batchKey = fn.id;
|
|
491
|
+
if (keyPath) {
|
|
492
|
+
const keyValue = getValueByPath({ event }, keyPath);
|
|
493
|
+
batchKey = `${fn.id}:${String(keyValue)}`;
|
|
494
|
+
}
|
|
495
|
+
this.batchManager.addEvent(batchKey, event, config, (events) => {
|
|
496
|
+
// Invoke function with all batched events
|
|
497
|
+
this.invokeFunctionWithBatch(fn, events).catch((error) => {
|
|
498
|
+
this.logger.error(`Function ${fn.id} (batched) failed:`, error);
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Invoke function with a batch of events
|
|
504
|
+
*/
|
|
505
|
+
async invokeFunctionWithBatch(fn, events) {
|
|
506
|
+
const runId = generateRunId();
|
|
507
|
+
// Build context with all events
|
|
508
|
+
let ctx = {
|
|
509
|
+
event: events[0], // First event is the primary
|
|
510
|
+
events: events,
|
|
511
|
+
step: this.createStepTools(runId, fn),
|
|
512
|
+
runId,
|
|
513
|
+
attempt: 1,
|
|
514
|
+
logger: this.logger,
|
|
515
|
+
};
|
|
516
|
+
// Track the run
|
|
517
|
+
const run = {
|
|
518
|
+
runId,
|
|
519
|
+
functionId: fn.id,
|
|
520
|
+
status: 'running',
|
|
521
|
+
event: events[0],
|
|
522
|
+
startedAt: Date.now(),
|
|
523
|
+
};
|
|
524
|
+
this.activeRuns.set(runId, run);
|
|
525
|
+
try {
|
|
526
|
+
const result = await fn.handler(ctx);
|
|
527
|
+
run.status = 'completed';
|
|
528
|
+
run.completedAt = Date.now();
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
run.status = 'failed';
|
|
533
|
+
run.error = ensureError(error).message;
|
|
534
|
+
run.completedAt = Date.now();
|
|
535
|
+
throw error;
|
|
536
|
+
}
|
|
537
|
+
finally {
|
|
538
|
+
// Clear step results for this run (memory leak fix)
|
|
539
|
+
Array.from(this.stepResults.keys()).forEach((key) => {
|
|
540
|
+
if (key.startsWith(`${runId}:`)) {
|
|
541
|
+
this.stepResults.delete(key);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
// Cleanup after a delay
|
|
545
|
+
setTimeout(() => this.activeRuns.delete(runId), 60000);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Process cancellation events
|
|
550
|
+
*/
|
|
551
|
+
async processCancellationEvent(event) {
|
|
552
|
+
const subscriptions = this.cancelSubscriptions.get(event.name);
|
|
553
|
+
if (!subscriptions)
|
|
554
|
+
return;
|
|
555
|
+
subscriptions.forEach(async ({ functionId, config }) => {
|
|
556
|
+
// Find matching active runs
|
|
557
|
+
Array.from(this.activeRuns.entries()).forEach(async ([runId, run]) => {
|
|
558
|
+
if (run.functionId !== functionId || run.status !== 'running')
|
|
559
|
+
return;
|
|
560
|
+
// Check match condition
|
|
561
|
+
let shouldCancel = false;
|
|
562
|
+
if (config.match) {
|
|
563
|
+
// Match on field path
|
|
564
|
+
const triggerValue = getValueByPath(event, config.match);
|
|
565
|
+
const runValue = getValueByPath(run.event, config.match);
|
|
566
|
+
shouldCancel = triggerValue === runValue;
|
|
567
|
+
}
|
|
568
|
+
else if (config.if) {
|
|
569
|
+
// Evaluate expression
|
|
570
|
+
shouldCancel = evaluateExpression(config.if, { event, async: run.event });
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
// No condition, always cancel
|
|
574
|
+
shouldCancel = true;
|
|
575
|
+
}
|
|
576
|
+
if (shouldCancel) {
|
|
577
|
+
await this.cancel(runId, 'Cancelled by event: ' + event.name);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Get active runs for a function
|
|
584
|
+
*/
|
|
585
|
+
async getRuns(options) {
|
|
586
|
+
const runs = [];
|
|
587
|
+
this.activeRuns.forEach((run) => {
|
|
588
|
+
if (!options.functionId || run.functionId === options.functionId) {
|
|
589
|
+
runs.push(run);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
return runs;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Get state for a specific run
|
|
596
|
+
*/
|
|
597
|
+
async getRunState(runId) {
|
|
598
|
+
return this.activeRuns.get(runId) || null;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Cancel a running function
|
|
602
|
+
*/
|
|
603
|
+
async cancel(runId, reason) {
|
|
604
|
+
const run = this.activeRuns.get(runId);
|
|
605
|
+
if (!run)
|
|
606
|
+
return;
|
|
607
|
+
run.status = 'cancelled';
|
|
608
|
+
run.completedAt = Date.now();
|
|
609
|
+
// Reject any waiting promises
|
|
610
|
+
const cancellation = this.runCancellations.get(runId);
|
|
611
|
+
if (cancellation) {
|
|
612
|
+
cancellation.reject(new CancellationError(runId, reason));
|
|
613
|
+
this.runCancellations.delete(runId);
|
|
614
|
+
}
|
|
615
|
+
// Clear step results for this run
|
|
616
|
+
Array.from(this.stepResults.keys()).forEach((key) => {
|
|
617
|
+
if (key.startsWith(`${runId}:`)) {
|
|
618
|
+
this.stepResults.delete(key);
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
// Remove from active runs
|
|
622
|
+
this.activeRuns.delete(runId);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Create step tools for a function execution
|
|
626
|
+
*/
|
|
627
|
+
createStepTools(runId, fn) {
|
|
628
|
+
const self = this;
|
|
629
|
+
return {
|
|
630
|
+
async run(stepId, stepFn) {
|
|
631
|
+
// Check for cached result (memoization/replay)
|
|
632
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
633
|
+
if (self.stepResults.has(cacheKey)) {
|
|
634
|
+
return self.stepResults.get(cacheKey);
|
|
635
|
+
}
|
|
636
|
+
// Check if cancelled
|
|
637
|
+
const run = self.activeRuns.get(runId);
|
|
638
|
+
if (run?.status === 'cancelled') {
|
|
639
|
+
throw new CancellationError(runId);
|
|
640
|
+
}
|
|
641
|
+
// Apply throttling if configured
|
|
642
|
+
if (fn.config.throttle) {
|
|
643
|
+
const throttleConfig = fn.config.throttle;
|
|
644
|
+
const keyPath = throttleConfig.key;
|
|
645
|
+
let throttleKey = fn.id;
|
|
646
|
+
if (keyPath) {
|
|
647
|
+
const run = self.activeRuns.get(runId);
|
|
648
|
+
if (run) {
|
|
649
|
+
const keyValue = getValueByPath({ event: run.event }, keyPath);
|
|
650
|
+
throttleKey = `${fn.id}:${String(keyValue)}`;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
await self.throttleManager.acquire(throttleKey, throttleConfig.count, parseDuration(throttleConfig.period));
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
const result = await stepFn();
|
|
657
|
+
self.stepResults.set(cacheKey, result);
|
|
658
|
+
return result;
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
if (error instanceof NonRetriableError) {
|
|
662
|
+
throw error;
|
|
663
|
+
}
|
|
664
|
+
const err = ensureError(error);
|
|
665
|
+
throw new StepError(`Step "${stepId}" failed: ${err.message}`, stepId, { cause: err });
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
async sleep(stepId, duration) {
|
|
669
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
670
|
+
if (self.stepResults.has(cacheKey)) {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
// Check if cancelled
|
|
674
|
+
const run = self.activeRuns.get(runId);
|
|
675
|
+
if (run?.status === 'cancelled') {
|
|
676
|
+
throw new CancellationError(runId);
|
|
677
|
+
}
|
|
678
|
+
const ms = parseDuration(duration);
|
|
679
|
+
// Create cancellable sleep with proper cleanup
|
|
680
|
+
await new Promise((resolve, reject) => {
|
|
681
|
+
// Cleanup function to clear timeout and remove cancellation handler
|
|
682
|
+
const cleanup = () => {
|
|
683
|
+
clearTimeout(timeoutId);
|
|
684
|
+
self.runCancellations.delete(runId);
|
|
685
|
+
};
|
|
686
|
+
const timeoutId = setTimeout(() => {
|
|
687
|
+
cleanup();
|
|
688
|
+
resolve();
|
|
689
|
+
}, ms);
|
|
690
|
+
// Register for cancellation
|
|
691
|
+
self.runCancellations.set(runId, {
|
|
692
|
+
reject: (error) => {
|
|
693
|
+
cleanup();
|
|
694
|
+
reject(error);
|
|
695
|
+
},
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
self.stepResults.set(cacheKey, true);
|
|
699
|
+
},
|
|
700
|
+
async waitForEvent(stepId, options) {
|
|
701
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
702
|
+
if (self.stepResults.has(cacheKey)) {
|
|
703
|
+
return self.stepResults.get(cacheKey);
|
|
704
|
+
}
|
|
705
|
+
if (!self.waitManager) {
|
|
706
|
+
throw new Error('waitForEvent requires DO state to be provided');
|
|
707
|
+
}
|
|
708
|
+
try {
|
|
709
|
+
const result = await self.waitManager.waitForEvent(options.event, {
|
|
710
|
+
timeout: options.timeout,
|
|
711
|
+
correlationId: runId,
|
|
712
|
+
});
|
|
713
|
+
self.stepResults.set(cacheKey, result);
|
|
714
|
+
return result;
|
|
715
|
+
}
|
|
716
|
+
catch (error) {
|
|
717
|
+
if (error instanceof WaitTimeoutError) {
|
|
718
|
+
self.stepResults.set(cacheKey, null);
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
async sendEvent(stepId, event) {
|
|
725
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
726
|
+
if (self.stepResults.has(cacheKey)) {
|
|
727
|
+
return self.stepResults.get(cacheKey);
|
|
728
|
+
}
|
|
729
|
+
const result = await self.send(event);
|
|
730
|
+
self.stepResults.set(cacheKey, result);
|
|
731
|
+
return result;
|
|
732
|
+
},
|
|
733
|
+
async invoke(stepId, options) {
|
|
734
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
735
|
+
if (self.stepResults.has(cacheKey)) {
|
|
736
|
+
return self.stepResults.get(cacheKey);
|
|
737
|
+
}
|
|
738
|
+
const event = {
|
|
739
|
+
name: options.function.eventName || `invoke/${options.function.id}`,
|
|
740
|
+
data: options.data,
|
|
741
|
+
ts: Date.now(),
|
|
742
|
+
id: generateEventId(),
|
|
743
|
+
};
|
|
744
|
+
// Handle timeout
|
|
745
|
+
if (options.timeout) {
|
|
746
|
+
const timeoutMs = parseDuration(options.timeout);
|
|
747
|
+
const result = await Promise.race([
|
|
748
|
+
self.invokeFunction(options.function, event),
|
|
749
|
+
new Promise((_, reject) => {
|
|
750
|
+
setTimeout(() => {
|
|
751
|
+
reject(new InvokeTimeoutError(options.function.id, timeoutMs));
|
|
752
|
+
}, timeoutMs);
|
|
753
|
+
}),
|
|
754
|
+
]);
|
|
755
|
+
self.stepResults.set(cacheKey, result);
|
|
756
|
+
return result;
|
|
757
|
+
}
|
|
758
|
+
const result = await self.invokeFunction(options.function, event);
|
|
759
|
+
self.stepResults.set(cacheKey, result);
|
|
760
|
+
return result;
|
|
761
|
+
},
|
|
762
|
+
async parallel(stepId, steps) {
|
|
763
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
764
|
+
if (self.stepResults.has(cacheKey)) {
|
|
765
|
+
return self.stepResults.get(cacheKey);
|
|
766
|
+
}
|
|
767
|
+
const results = await Promise.all(steps.map((step) => step()));
|
|
768
|
+
self.stepResults.set(cacheKey, results);
|
|
769
|
+
return results;
|
|
770
|
+
},
|
|
771
|
+
ai: {
|
|
772
|
+
async infer(stepId, options) {
|
|
773
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
774
|
+
if (self.stepResults.has(cacheKey)) {
|
|
775
|
+
return self.stepResults.get(cacheKey);
|
|
776
|
+
}
|
|
777
|
+
// Stub - would integrate with AI providers
|
|
778
|
+
throw new Error('AI inference not yet implemented in compat layer');
|
|
779
|
+
},
|
|
780
|
+
async wrap(stepId, _model, _options) {
|
|
781
|
+
const cacheKey = `${runId}:${stepId}`;
|
|
782
|
+
if (self.stepResults.has(cacheKey)) {
|
|
783
|
+
return self.stepResults.get(cacheKey);
|
|
784
|
+
}
|
|
785
|
+
// Stub - would integrate with AI providers
|
|
786
|
+
throw new Error('AI wrap not yet implemented in compat layer');
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Invoke a function with an event (internal)
|
|
793
|
+
*/
|
|
794
|
+
async invokeFunction(fn, event) {
|
|
795
|
+
const runId = generateRunId();
|
|
796
|
+
// Track the run
|
|
797
|
+
const run = {
|
|
798
|
+
runId,
|
|
799
|
+
functionId: fn.id,
|
|
800
|
+
status: 'running',
|
|
801
|
+
event: event,
|
|
802
|
+
startedAt: Date.now(),
|
|
803
|
+
};
|
|
804
|
+
this.activeRuns.set(runId, run);
|
|
805
|
+
// Apply concurrency limits
|
|
806
|
+
if (fn.config.concurrency) {
|
|
807
|
+
const concurrencyConfig = typeof fn.config.concurrency === 'number'
|
|
808
|
+
? { limit: fn.config.concurrency }
|
|
809
|
+
: fn.config.concurrency;
|
|
810
|
+
let concurrencyKey = fn.id;
|
|
811
|
+
if (concurrencyConfig.key) {
|
|
812
|
+
const keyValue = getValueByPath({ event }, concurrencyConfig.key);
|
|
813
|
+
concurrencyKey = `${fn.id}:${String(keyValue)}`;
|
|
814
|
+
}
|
|
815
|
+
else if (concurrencyConfig.scope === 'env') {
|
|
816
|
+
concurrencyKey = `env:${this.id}`;
|
|
817
|
+
}
|
|
818
|
+
else if (concurrencyConfig.scope === 'account') {
|
|
819
|
+
concurrencyKey = 'account';
|
|
820
|
+
}
|
|
821
|
+
await this.concurrencyManager.acquire(concurrencyKey, concurrencyConfig.limit);
|
|
822
|
+
try {
|
|
823
|
+
return await this.executeFunction(fn, event, runId, run);
|
|
824
|
+
}
|
|
825
|
+
finally {
|
|
826
|
+
this.concurrencyManager.release(concurrencyKey);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
return this.executeFunction(fn, event, runId, run);
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Execute function (shared logic for invoke)
|
|
833
|
+
*/
|
|
834
|
+
async executeFunction(fn, event, runId, run) {
|
|
835
|
+
// Apply middleware
|
|
836
|
+
let middlewareLifecycles = [];
|
|
837
|
+
for (const mw of this.middleware) {
|
|
838
|
+
if (mw.onFunctionRun) {
|
|
839
|
+
const lifecycle = await mw.onFunctionRun({
|
|
840
|
+
event,
|
|
841
|
+
runId,
|
|
842
|
+
fn: fn,
|
|
843
|
+
});
|
|
844
|
+
middlewareLifecycles.push(lifecycle);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
// Build context
|
|
848
|
+
let ctx = {
|
|
849
|
+
event,
|
|
850
|
+
events: [event],
|
|
851
|
+
step: this.createStepTools(runId, fn),
|
|
852
|
+
runId,
|
|
853
|
+
attempt: 1,
|
|
854
|
+
logger: this.logger,
|
|
855
|
+
};
|
|
856
|
+
// Transform input via middleware
|
|
857
|
+
for (const lifecycle of middlewareLifecycles) {
|
|
858
|
+
if (lifecycle.transformInput) {
|
|
859
|
+
ctx = (await lifecycle.transformInput(ctx));
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
// Before execution hooks
|
|
863
|
+
for (const lifecycle of middlewareLifecycles) {
|
|
864
|
+
await lifecycle.beforeExecution?.();
|
|
865
|
+
}
|
|
866
|
+
try {
|
|
867
|
+
// Execute the function
|
|
868
|
+
let result = await fn.handler(ctx);
|
|
869
|
+
// Transform output via middleware
|
|
870
|
+
for (const lifecycle of middlewareLifecycles) {
|
|
871
|
+
if (lifecycle.transformOutput) {
|
|
872
|
+
result = (await lifecycle.transformOutput(result));
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
// After execution hooks
|
|
876
|
+
for (const lifecycle of middlewareLifecycles) {
|
|
877
|
+
await lifecycle.afterExecution?.();
|
|
878
|
+
}
|
|
879
|
+
run.status = 'completed';
|
|
880
|
+
run.completedAt = Date.now();
|
|
881
|
+
return result;
|
|
882
|
+
}
|
|
883
|
+
catch (error) {
|
|
884
|
+
const err = ensureError(error);
|
|
885
|
+
// Error hooks
|
|
886
|
+
for (const lifecycle of middlewareLifecycles) {
|
|
887
|
+
await lifecycle.onError?.(err);
|
|
888
|
+
}
|
|
889
|
+
run.status = 'failed';
|
|
890
|
+
run.error = err.message;
|
|
891
|
+
run.completedAt = Date.now();
|
|
892
|
+
throw error;
|
|
893
|
+
}
|
|
894
|
+
finally {
|
|
895
|
+
// Cleanup run cancellation handler
|
|
896
|
+
this.runCancellations.delete(runId);
|
|
897
|
+
// Clear step results for this run (memory leak fix)
|
|
898
|
+
// Step results are only needed during execution for memoization/replay
|
|
899
|
+
// Once execution completes (success or failure), they can be cleaned up
|
|
900
|
+
Array.from(this.stepResults.keys()).forEach((key) => {
|
|
901
|
+
if (key.startsWith(`${runId}:`)) {
|
|
902
|
+
this.stepResults.delete(key);
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
// Cleanup after a delay
|
|
906
|
+
setTimeout(() => this.activeRuns.delete(runId), 60000);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Get all registered functions
|
|
911
|
+
*/
|
|
912
|
+
getFunctions() {
|
|
913
|
+
return Array.from(this.functions.values());
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Get a function by ID
|
|
917
|
+
*/
|
|
918
|
+
getFunction(id) {
|
|
919
|
+
return this.functions.get(id);
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* Get failed runs for observability
|
|
923
|
+
*/
|
|
924
|
+
getFailedRuns() {
|
|
925
|
+
return new Map(this.failedRuns);
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Get count of currently running background tasks
|
|
929
|
+
*/
|
|
930
|
+
getRunningTaskCount() {
|
|
931
|
+
return this.runningTasks.size;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Wait for all running background tasks to complete
|
|
935
|
+
* Useful for graceful shutdown or testing
|
|
936
|
+
*/
|
|
937
|
+
async waitForAllTasks() {
|
|
938
|
+
const tasks = Array.from(this.runningTasks.values());
|
|
939
|
+
await Promise.allSettled(tasks);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Create a serve handler for HTTP frameworks
|
|
944
|
+
*/
|
|
945
|
+
export function serve(inngest, functions, config) {
|
|
946
|
+
// Register all functions
|
|
947
|
+
for (const fn of functions) {
|
|
948
|
+
inngest.createFunction(fn.config, fn.trigger, fn.handler);
|
|
949
|
+
}
|
|
950
|
+
// Return a fetch handler
|
|
951
|
+
return async (request) => {
|
|
952
|
+
const url = new URL(request.url);
|
|
953
|
+
const basePath = config?.path ?? '/api/inngest';
|
|
954
|
+
// Health check
|
|
955
|
+
if (request.method === 'GET' && url.pathname === basePath) {
|
|
956
|
+
return new Response(JSON.stringify({
|
|
957
|
+
appId: inngest.id,
|
|
958
|
+
functions: functions.map((f) => ({
|
|
959
|
+
id: f.id,
|
|
960
|
+
name: f.name,
|
|
961
|
+
trigger: f.trigger,
|
|
962
|
+
})),
|
|
963
|
+
}), { headers: { 'Content-Type': 'application/json' } });
|
|
964
|
+
}
|
|
965
|
+
// Event ingestion
|
|
966
|
+
if (request.method === 'POST' && url.pathname === basePath) {
|
|
967
|
+
try {
|
|
968
|
+
const body = await request.json();
|
|
969
|
+
const events = Array.isArray(body) ? body : [body];
|
|
970
|
+
const result = await inngest.send(events);
|
|
971
|
+
return new Response(JSON.stringify(result), {
|
|
972
|
+
headers: { 'Content-Type': 'application/json' },
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
catch (error) {
|
|
976
|
+
return new Response(JSON.stringify({ error: ensureError(error).message }), {
|
|
977
|
+
status: 400,
|
|
978
|
+
headers: { 'Content-Type': 'application/json' },
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return new Response('Not Found', { status: 404 });
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
// ============================================================================
|
|
986
|
+
// EXPORTS
|
|
987
|
+
// ============================================================================
|
|
988
|
+
export default Inngest;
|
|
989
|
+
//# sourceMappingURL=index.js.map
|