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,934 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createFunction Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates typed function instances for different execution modes:
|
|
5
|
+
* - CodeFunction: executes TypeScript/JavaScript code
|
|
6
|
+
* - GenerativeFunction: calls LLM for generation
|
|
7
|
+
* - AgenticFunction: orchestrates multi-step AI tasks
|
|
8
|
+
* - HumanFunction: queues tasks for human input
|
|
9
|
+
*/
|
|
10
|
+
// Use Cloudflare's DurableObjectState type from @cloudflare/workers-types
|
|
11
|
+
// No need to redeclare - it's provided by the ambient types
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// ERROR CLASSES
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export class ValidationError extends Error {
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'ValidationError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class RegistrationError extends Error {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = 'RegistrationError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class ExecutionError extends Error {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = 'ExecutionError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// VALIDATION
|
|
35
|
+
// ============================================================================
|
|
36
|
+
const VALID_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
37
|
+
const VALID_JSON_SCHEMA_TYPES = ['object', 'array', 'string', 'number', 'integer', 'boolean', 'null'];
|
|
38
|
+
const VALID_FORM_FIELD_TYPES = ['text', 'number', 'boolean', 'select', 'multiselect'];
|
|
39
|
+
function validateBase(def) {
|
|
40
|
+
if (!def.name) {
|
|
41
|
+
throw new ValidationError('Function name is required');
|
|
42
|
+
}
|
|
43
|
+
if (def.name === '') {
|
|
44
|
+
throw new ValidationError('Function name cannot be empty');
|
|
45
|
+
}
|
|
46
|
+
if (!VALID_NAME_PATTERN.test(def.name)) {
|
|
47
|
+
throw new ValidationError(`Invalid function name: ${def.name}. Names must start with a letter and contain only alphanumeric characters and underscores.`);
|
|
48
|
+
}
|
|
49
|
+
if (!def.type) {
|
|
50
|
+
throw new ValidationError('Function type is required');
|
|
51
|
+
}
|
|
52
|
+
if (!['code', 'generative', 'agentic', 'human'].includes(def.type)) {
|
|
53
|
+
throw new ValidationError(`Invalid function type: ${def.type}`);
|
|
54
|
+
}
|
|
55
|
+
if (def.timeout !== undefined && def.timeout < 0) {
|
|
56
|
+
throw new ValidationError('Timeout must be non-negative');
|
|
57
|
+
}
|
|
58
|
+
if (def.retries !== undefined && def.retries < 0) {
|
|
59
|
+
throw new ValidationError('Retries must be non-negative');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function validateCodeFunction(def) {
|
|
63
|
+
if (!def.handler) {
|
|
64
|
+
throw new ValidationError('CodeFunction requires a handler');
|
|
65
|
+
}
|
|
66
|
+
if (typeof def.handler !== 'function') {
|
|
67
|
+
throw new ValidationError('Handler must be a function');
|
|
68
|
+
}
|
|
69
|
+
if (def.runtime !== undefined && !['javascript', 'typescript'].includes(def.runtime)) {
|
|
70
|
+
throw new ValidationError(`Invalid runtime: ${def.runtime}. Must be 'javascript' or 'typescript'.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function validateGenerativeFunction(def) {
|
|
74
|
+
if (!def.model) {
|
|
75
|
+
throw new ValidationError('GenerativeFunction requires a model');
|
|
76
|
+
}
|
|
77
|
+
if (def.model === '') {
|
|
78
|
+
throw new ValidationError('Model cannot be empty');
|
|
79
|
+
}
|
|
80
|
+
if (def.prompt === undefined) {
|
|
81
|
+
throw new ValidationError('GenerativeFunction requires a prompt');
|
|
82
|
+
}
|
|
83
|
+
if (def.temperature !== undefined && (def.temperature < 0 || def.temperature > 2)) {
|
|
84
|
+
throw new ValidationError('Temperature must be between 0 and 2');
|
|
85
|
+
}
|
|
86
|
+
if (def.maxTokens !== undefined && def.maxTokens < 0) {
|
|
87
|
+
throw new ValidationError('maxTokens must be non-negative');
|
|
88
|
+
}
|
|
89
|
+
if (def.schema !== undefined) {
|
|
90
|
+
const schemaType = def.schema.type;
|
|
91
|
+
if (schemaType && !VALID_JSON_SCHEMA_TYPES.includes(schemaType)) {
|
|
92
|
+
throw new ValidationError(`Invalid JSON Schema type: ${schemaType}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function validateAgenticFunction(def) {
|
|
97
|
+
if (!def.agent) {
|
|
98
|
+
throw new ValidationError('AgenticFunction requires an agent');
|
|
99
|
+
}
|
|
100
|
+
if (def.agent === '') {
|
|
101
|
+
throw new ValidationError('Agent cannot be empty');
|
|
102
|
+
}
|
|
103
|
+
if (def.maxIterations !== undefined) {
|
|
104
|
+
if (def.maxIterations < 1) {
|
|
105
|
+
throw new ValidationError('maxIterations must be at least 1');
|
|
106
|
+
}
|
|
107
|
+
if (def.maxIterations > 1000) {
|
|
108
|
+
throw new ValidationError('maxIterations cannot exceed 1000');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (def.tools !== undefined) {
|
|
112
|
+
const uniqueTools = new Set(def.tools);
|
|
113
|
+
if (uniqueTools.size !== def.tools.length) {
|
|
114
|
+
throw new ValidationError('Tools array contains duplicates');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function validateHumanFunction(def) {
|
|
119
|
+
if (!def.channel) {
|
|
120
|
+
throw new ValidationError('HumanFunction requires a channel');
|
|
121
|
+
}
|
|
122
|
+
if (def.channel === '') {
|
|
123
|
+
throw new ValidationError('Channel cannot be empty');
|
|
124
|
+
}
|
|
125
|
+
if (def.timeout === undefined) {
|
|
126
|
+
throw new ValidationError('HumanFunction requires a timeout');
|
|
127
|
+
}
|
|
128
|
+
if (def.timeout <= 0) {
|
|
129
|
+
throw new ValidationError('Timeout must be positive');
|
|
130
|
+
}
|
|
131
|
+
if (def.escalation !== undefined && def.escalation.timeout > def.timeout) {
|
|
132
|
+
throw new ValidationError('Escalation timeout cannot exceed main timeout');
|
|
133
|
+
}
|
|
134
|
+
if (def.form !== undefined) {
|
|
135
|
+
for (const field of def.form.fields) {
|
|
136
|
+
if (!field.name) {
|
|
137
|
+
throw new ValidationError('Form field name is required');
|
|
138
|
+
}
|
|
139
|
+
if (!VALID_FORM_FIELD_TYPES.includes(field.type)) {
|
|
140
|
+
throw new ValidationError(`Invalid form field type: ${field.type}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function validate(def) {
|
|
146
|
+
validateBase(def);
|
|
147
|
+
switch (def.type) {
|
|
148
|
+
case 'code':
|
|
149
|
+
validateCodeFunction(def);
|
|
150
|
+
break;
|
|
151
|
+
case 'generative':
|
|
152
|
+
validateGenerativeFunction(def);
|
|
153
|
+
break;
|
|
154
|
+
case 'agentic':
|
|
155
|
+
validateAgenticFunction(def);
|
|
156
|
+
break;
|
|
157
|
+
case 'human':
|
|
158
|
+
validateHumanFunction(def);
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// TEMPLATE SUBSTITUTION
|
|
164
|
+
// ============================================================================
|
|
165
|
+
function substituteTemplate(template, data) {
|
|
166
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => {
|
|
167
|
+
return String(data[key] ?? '');
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// JSON SCHEMA VALIDATION
|
|
172
|
+
// ============================================================================
|
|
173
|
+
function validateAgainstSchema(data, schema) {
|
|
174
|
+
const schemaType = schema.type;
|
|
175
|
+
if (schemaType === 'object') {
|
|
176
|
+
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const required = schema.required || [];
|
|
180
|
+
for (const key of required) {
|
|
181
|
+
if (!(key in data)) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
// ============================================================================
|
|
189
|
+
// FORM VALIDATION
|
|
190
|
+
// ============================================================================
|
|
191
|
+
function validateFormResponse(response, form) {
|
|
192
|
+
if (typeof response !== 'object' || response === null) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const data = response;
|
|
196
|
+
for (const field of form.fields) {
|
|
197
|
+
const value = data[field.name];
|
|
198
|
+
if (field.required && value === undefined) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
if (value !== undefined) {
|
|
202
|
+
switch (field.type) {
|
|
203
|
+
case 'boolean':
|
|
204
|
+
if (typeof value !== 'boolean') {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
case 'number':
|
|
209
|
+
if (typeof value !== 'number') {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
case 'text':
|
|
214
|
+
if (typeof value !== 'string') {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// EXECUTION HELPERS
|
|
225
|
+
// ============================================================================
|
|
226
|
+
async function withTimeout(promise, ms) {
|
|
227
|
+
let timeoutId;
|
|
228
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
229
|
+
timeoutId = setTimeout(() => reject(new ExecutionError('Execution timeout exceeded')), ms);
|
|
230
|
+
});
|
|
231
|
+
try {
|
|
232
|
+
const result = await Promise.race([promise, timeoutPromise]);
|
|
233
|
+
clearTimeout(timeoutId);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
clearTimeout(timeoutId);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
async function withRetries(fn, retries) {
|
|
242
|
+
let lastError;
|
|
243
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
244
|
+
try {
|
|
245
|
+
return await fn();
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
lastError = error;
|
|
249
|
+
if (attempt === retries) {
|
|
250
|
+
throw new ExecutionError(`Execution failed after ${retries + 1} attempts: ${lastError.message}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
throw lastError;
|
|
255
|
+
}
|
|
256
|
+
// ============================================================================
|
|
257
|
+
// FUNCTION INSTANCE IMPLEMENTATION
|
|
258
|
+
// ============================================================================
|
|
259
|
+
function createFunctionInstance(def, options) {
|
|
260
|
+
const id = options.id || crypto.randomUUID();
|
|
261
|
+
const createdAt = new Date();
|
|
262
|
+
let invocationCount = 0;
|
|
263
|
+
const invocationHistory = [];
|
|
264
|
+
let registeredRegistry = undefined;
|
|
265
|
+
const createContext = (input) => {
|
|
266
|
+
return {
|
|
267
|
+
functionId: id,
|
|
268
|
+
invocationId: crypto.randomUUID(),
|
|
269
|
+
input,
|
|
270
|
+
env: options.env,
|
|
271
|
+
emit: async (event, data) => {
|
|
272
|
+
options.onEvent?.(event, data);
|
|
273
|
+
},
|
|
274
|
+
log: (message, data) => {
|
|
275
|
+
console.log(`[${id}] ${message}`, data);
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
const executeCode = async (input) => {
|
|
280
|
+
const codeDef = def;
|
|
281
|
+
const ctx = createContext(input);
|
|
282
|
+
return codeDef.handler(input, ctx);
|
|
283
|
+
};
|
|
284
|
+
const executeGenerative = async (input) => {
|
|
285
|
+
const genDef = def;
|
|
286
|
+
const inputObj = input;
|
|
287
|
+
let promptStr;
|
|
288
|
+
if (typeof genDef.prompt === 'function') {
|
|
289
|
+
promptStr = genDef.prompt(input);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
promptStr = substituteTemplate(genDef.prompt, inputObj);
|
|
293
|
+
}
|
|
294
|
+
if (genDef.stream) {
|
|
295
|
+
return options.env.AI.stream({
|
|
296
|
+
model: genDef.model,
|
|
297
|
+
prompt: promptStr,
|
|
298
|
+
temperature: genDef.temperature ?? 1,
|
|
299
|
+
maxTokens: genDef.maxTokens,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
const response = await options.env.AI.generate({
|
|
303
|
+
model: genDef.model,
|
|
304
|
+
prompt: promptStr,
|
|
305
|
+
temperature: genDef.temperature ?? 1,
|
|
306
|
+
maxTokens: genDef.maxTokens,
|
|
307
|
+
});
|
|
308
|
+
if (genDef.schema) {
|
|
309
|
+
try {
|
|
310
|
+
const parsed = JSON.parse(response.text);
|
|
311
|
+
if (!validateAgainstSchema(parsed, genDef.schema)) {
|
|
312
|
+
throw new ExecutionError('AI output does not match schema');
|
|
313
|
+
}
|
|
314
|
+
return parsed;
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (error instanceof ExecutionError)
|
|
318
|
+
throw error;
|
|
319
|
+
throw new ExecutionError('Failed to parse AI output as JSON');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return response;
|
|
323
|
+
};
|
|
324
|
+
const executeAgentic = async (input) => {
|
|
325
|
+
const agentDef = def;
|
|
326
|
+
try {
|
|
327
|
+
const result = await options.env.AGENT_RUNNER.run({
|
|
328
|
+
agent: agentDef.agent,
|
|
329
|
+
input,
|
|
330
|
+
tools: agentDef.tools || [],
|
|
331
|
+
maxIterations: agentDef.maxIterations ?? 10,
|
|
332
|
+
systemPrompt: agentDef.systemPrompt,
|
|
333
|
+
onStep: agentDef.onStep,
|
|
334
|
+
});
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
throw new ExecutionError(`Agent execution failed: ${error.message}`);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
const executeHuman = async (input) => {
|
|
342
|
+
const humanDef = def;
|
|
343
|
+
const inputObj = input;
|
|
344
|
+
let message;
|
|
345
|
+
if (typeof humanDef.prompt === 'function') {
|
|
346
|
+
message = humanDef.prompt(input);
|
|
347
|
+
}
|
|
348
|
+
else if (humanDef.prompt) {
|
|
349
|
+
message = substituteTemplate(humanDef.prompt, inputObj);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
message = JSON.stringify(input);
|
|
353
|
+
}
|
|
354
|
+
await options.env.NOTIFICATIONS.send({
|
|
355
|
+
channel: humanDef.channel,
|
|
356
|
+
message,
|
|
357
|
+
});
|
|
358
|
+
try {
|
|
359
|
+
const response = await options.env.NOTIFICATIONS.waitForResponse({
|
|
360
|
+
timeout: humanDef.timeout,
|
|
361
|
+
});
|
|
362
|
+
if (humanDef.form && !validateFormResponse(response, humanDef.form)) {
|
|
363
|
+
throw new ExecutionError('Human response does not match form schema');
|
|
364
|
+
}
|
|
365
|
+
return response;
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
if (humanDef.escalation) {
|
|
369
|
+
await options.env.NOTIFICATIONS.send({
|
|
370
|
+
channel: humanDef.escalation.to,
|
|
371
|
+
message,
|
|
372
|
+
});
|
|
373
|
+
return options.env.NOTIFICATIONS.waitForResponse({
|
|
374
|
+
timeout: humanDef.escalation.timeout,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
throw new ExecutionError(`Human task timeout: ${error.message}`);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
const execute = async (input) => {
|
|
381
|
+
const startTime = Date.now();
|
|
382
|
+
const ctx = createContext(input);
|
|
383
|
+
options.onEvent?.('function.invoked', {
|
|
384
|
+
functionId: id,
|
|
385
|
+
invocationId: ctx.invocationId,
|
|
386
|
+
input,
|
|
387
|
+
});
|
|
388
|
+
const doExecute = async () => {
|
|
389
|
+
switch (def.type) {
|
|
390
|
+
case 'code':
|
|
391
|
+
return executeCode(input);
|
|
392
|
+
case 'generative':
|
|
393
|
+
return executeGenerative(input);
|
|
394
|
+
case 'agentic':
|
|
395
|
+
return executeAgentic(input);
|
|
396
|
+
case 'human':
|
|
397
|
+
return executeHuman(input);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
try {
|
|
401
|
+
let result;
|
|
402
|
+
const retries = def.retries ?? 0;
|
|
403
|
+
const wrappedExecute = async () => {
|
|
404
|
+
const exec = doExecute();
|
|
405
|
+
if (def.timeout) {
|
|
406
|
+
return withTimeout(exec, def.timeout);
|
|
407
|
+
}
|
|
408
|
+
return exec;
|
|
409
|
+
};
|
|
410
|
+
if (retries > 0) {
|
|
411
|
+
result = await withRetries(wrappedExecute, retries);
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
result = await wrappedExecute();
|
|
415
|
+
}
|
|
416
|
+
const duration = Date.now() - startTime;
|
|
417
|
+
invocationCount++;
|
|
418
|
+
invocationHistory.push({
|
|
419
|
+
invocationId: ctx.invocationId,
|
|
420
|
+
functionId: id,
|
|
421
|
+
input,
|
|
422
|
+
output: result,
|
|
423
|
+
status: 'completed',
|
|
424
|
+
startedAt: new Date(startTime),
|
|
425
|
+
completedAt: new Date(),
|
|
426
|
+
duration,
|
|
427
|
+
});
|
|
428
|
+
if (options.state) {
|
|
429
|
+
await options.state.storage.put(`invocation:${ctx.invocationId}`, invocationHistory[invocationHistory.length - 1]);
|
|
430
|
+
}
|
|
431
|
+
options.onEvent?.('function.completed', {
|
|
432
|
+
functionId: id,
|
|
433
|
+
invocationId: ctx.invocationId,
|
|
434
|
+
result,
|
|
435
|
+
duration,
|
|
436
|
+
});
|
|
437
|
+
return result;
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
const duration = Date.now() - startTime;
|
|
441
|
+
const errorMessage = error.message;
|
|
442
|
+
invocationHistory.push({
|
|
443
|
+
invocationId: ctx.invocationId,
|
|
444
|
+
functionId: id,
|
|
445
|
+
input,
|
|
446
|
+
error: errorMessage,
|
|
447
|
+
status: 'failed',
|
|
448
|
+
startedAt: new Date(startTime),
|
|
449
|
+
completedAt: new Date(),
|
|
450
|
+
duration,
|
|
451
|
+
});
|
|
452
|
+
options.onEvent?.('function.failed', {
|
|
453
|
+
functionId: id,
|
|
454
|
+
invocationId: ctx.invocationId,
|
|
455
|
+
error: errorMessage,
|
|
456
|
+
duration,
|
|
457
|
+
});
|
|
458
|
+
if (error instanceof ExecutionError) {
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
461
|
+
throw new ExecutionError(errorMessage);
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
// Track registry reference (set during auto-register or manual register)
|
|
465
|
+
registeredRegistry = options.registry;
|
|
466
|
+
const register = async (registry) => {
|
|
467
|
+
registeredRegistry = registry;
|
|
468
|
+
await registry.register(instance);
|
|
469
|
+
};
|
|
470
|
+
const unregister = async () => {
|
|
471
|
+
if (registeredRegistry) {
|
|
472
|
+
await registeredRegistry.unregister(def.name);
|
|
473
|
+
}
|
|
474
|
+
if (options.state) {
|
|
475
|
+
await options.state.storage.delete(`function:${def.name}`);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
const toJSON = () => {
|
|
479
|
+
const json = {
|
|
480
|
+
id,
|
|
481
|
+
name: def.name,
|
|
482
|
+
type: def.type,
|
|
483
|
+
description: def.description,
|
|
484
|
+
createdAt: createdAt.toISOString(),
|
|
485
|
+
};
|
|
486
|
+
if (def.type === 'generative') {
|
|
487
|
+
const genDef = def;
|
|
488
|
+
json.model = genDef.model;
|
|
489
|
+
json.temperature = genDef.temperature;
|
|
490
|
+
json.maxTokens = genDef.maxTokens;
|
|
491
|
+
}
|
|
492
|
+
return json;
|
|
493
|
+
};
|
|
494
|
+
const getMetadata = () => ({
|
|
495
|
+
id,
|
|
496
|
+
name: def.name,
|
|
497
|
+
type: def.type,
|
|
498
|
+
createdAt,
|
|
499
|
+
invocationCount,
|
|
500
|
+
});
|
|
501
|
+
const getInvocationHistory = async () => {
|
|
502
|
+
return invocationHistory;
|
|
503
|
+
};
|
|
504
|
+
// Composition methods
|
|
505
|
+
const pipe = (next) => {
|
|
506
|
+
return createComposedFunction([instance, next], options);
|
|
507
|
+
};
|
|
508
|
+
const ifMethod = (predicate) => {
|
|
509
|
+
return createConditionalFunction(instance, predicate, options);
|
|
510
|
+
};
|
|
511
|
+
const map = (fn) => {
|
|
512
|
+
return createMappedFunction(instance, fn, options);
|
|
513
|
+
};
|
|
514
|
+
const contramap = (fn) => {
|
|
515
|
+
return createContramappedFunction(instance, fn, options);
|
|
516
|
+
};
|
|
517
|
+
const catchMethod = (handler) => {
|
|
518
|
+
return createCatchFunction(instance, handler, options);
|
|
519
|
+
};
|
|
520
|
+
const finallyMethod = (cleanup) => {
|
|
521
|
+
return createFinallyFunction(instance, cleanup, options);
|
|
522
|
+
};
|
|
523
|
+
const instance = {
|
|
524
|
+
id,
|
|
525
|
+
name: def.name,
|
|
526
|
+
type: def.type,
|
|
527
|
+
description: def.description,
|
|
528
|
+
createdAt,
|
|
529
|
+
timeout: def.timeout,
|
|
530
|
+
retries: def.retries,
|
|
531
|
+
requiredPermission: def.requiredPermission,
|
|
532
|
+
// Type-specific properties
|
|
533
|
+
...(def.type === 'code' && {
|
|
534
|
+
handler: def.handler,
|
|
535
|
+
runtime: def.runtime ?? 'javascript',
|
|
536
|
+
sandboxed: def.sandboxed,
|
|
537
|
+
}),
|
|
538
|
+
...(def.type === 'generative' && {
|
|
539
|
+
model: def.model,
|
|
540
|
+
prompt: def.prompt,
|
|
541
|
+
temperature: def.temperature ?? 1,
|
|
542
|
+
maxTokens: def.maxTokens,
|
|
543
|
+
stream: def.stream,
|
|
544
|
+
schema: def.schema,
|
|
545
|
+
}),
|
|
546
|
+
...(def.type === 'agentic' && {
|
|
547
|
+
agent: def.agent,
|
|
548
|
+
tools: def.tools,
|
|
549
|
+
maxIterations: def.maxIterations ?? 10,
|
|
550
|
+
systemPrompt: def.systemPrompt,
|
|
551
|
+
onStep: def.onStep,
|
|
552
|
+
}),
|
|
553
|
+
...(def.type === 'human' && {
|
|
554
|
+
channel: def.channel,
|
|
555
|
+
timeout: def.timeout,
|
|
556
|
+
prompt: def.prompt,
|
|
557
|
+
form: def.form,
|
|
558
|
+
escalation: def.escalation,
|
|
559
|
+
}),
|
|
560
|
+
execute,
|
|
561
|
+
register,
|
|
562
|
+
unregister,
|
|
563
|
+
toJSON,
|
|
564
|
+
getMetadata,
|
|
565
|
+
getInvocationHistory,
|
|
566
|
+
pipe,
|
|
567
|
+
if: ifMethod,
|
|
568
|
+
map,
|
|
569
|
+
contramap,
|
|
570
|
+
catch: catchMethod,
|
|
571
|
+
finally: finallyMethod,
|
|
572
|
+
};
|
|
573
|
+
return instance;
|
|
574
|
+
}
|
|
575
|
+
// ============================================================================
|
|
576
|
+
// COMPOSED FUNCTION
|
|
577
|
+
// ============================================================================
|
|
578
|
+
function createComposedFunction(functions, options) {
|
|
579
|
+
const name = functions.map(f => f.name).join(' -> ');
|
|
580
|
+
const id = crypto.randomUUID();
|
|
581
|
+
const createdAt = new Date();
|
|
582
|
+
let invocationCount = 0;
|
|
583
|
+
const execute = async (input) => {
|
|
584
|
+
let result = input;
|
|
585
|
+
for (const fn of functions) {
|
|
586
|
+
result = await fn.execute(result);
|
|
587
|
+
}
|
|
588
|
+
invocationCount++;
|
|
589
|
+
return result;
|
|
590
|
+
};
|
|
591
|
+
const describe = () => ({
|
|
592
|
+
type: 'pipeline',
|
|
593
|
+
steps: functions.map(f => ({ name: f.name, type: f.type })),
|
|
594
|
+
});
|
|
595
|
+
const pipe = (next) => {
|
|
596
|
+
return createComposedFunction([...functions, next], options);
|
|
597
|
+
};
|
|
598
|
+
const instance = {
|
|
599
|
+
id,
|
|
600
|
+
name,
|
|
601
|
+
type: 'code',
|
|
602
|
+
createdAt,
|
|
603
|
+
execute,
|
|
604
|
+
describe,
|
|
605
|
+
pipe,
|
|
606
|
+
if: (predicate) => createConditionalFunction(instance, predicate, options),
|
|
607
|
+
map: (fn) => createMappedFunction(instance, fn, options),
|
|
608
|
+
contramap: (fn) => createContramappedFunction(instance, fn, options),
|
|
609
|
+
catch: (handler) => createCatchFunction(instance, handler, options),
|
|
610
|
+
finally: (cleanup) => createFinallyFunction(instance, cleanup, options),
|
|
611
|
+
register: async () => { },
|
|
612
|
+
unregister: async () => { },
|
|
613
|
+
toJSON: () => ({ id, name, type: 'composed' }),
|
|
614
|
+
getMetadata: () => ({ id, name, type: 'composed', createdAt, invocationCount }),
|
|
615
|
+
getInvocationHistory: async () => [],
|
|
616
|
+
};
|
|
617
|
+
return instance;
|
|
618
|
+
}
|
|
619
|
+
// ============================================================================
|
|
620
|
+
// CONDITIONAL FUNCTION
|
|
621
|
+
// ============================================================================
|
|
622
|
+
function createConditionalFunction(fn, predicate, options) {
|
|
623
|
+
const id = crypto.randomUUID();
|
|
624
|
+
const createdAt = new Date();
|
|
625
|
+
let elseFn;
|
|
626
|
+
const execute = async (input) => {
|
|
627
|
+
if (predicate(input)) {
|
|
628
|
+
return fn.execute(input);
|
|
629
|
+
}
|
|
630
|
+
if (elseFn) {
|
|
631
|
+
return elseFn.execute(input);
|
|
632
|
+
}
|
|
633
|
+
return null;
|
|
634
|
+
};
|
|
635
|
+
const elseMethod = (alternative) => {
|
|
636
|
+
elseFn = alternative;
|
|
637
|
+
return instance;
|
|
638
|
+
};
|
|
639
|
+
const instance = {
|
|
640
|
+
id,
|
|
641
|
+
name: `${fn.name} (conditional)`,
|
|
642
|
+
type: fn.type,
|
|
643
|
+
createdAt,
|
|
644
|
+
execute,
|
|
645
|
+
else: elseMethod,
|
|
646
|
+
pipe: (next) => createComposedFunction([instance, next], options),
|
|
647
|
+
if: (pred) => createConditionalFunction(instance, pred, options),
|
|
648
|
+
map: (mapper) => createMappedFunction(instance, mapper, options),
|
|
649
|
+
contramap: (mapper) => createContramappedFunction(instance, mapper, options),
|
|
650
|
+
catch: (handler) => createCatchFunction(instance, handler, options),
|
|
651
|
+
finally: (cleanup) => createFinallyFunction(instance, cleanup, options),
|
|
652
|
+
register: async () => { },
|
|
653
|
+
unregister: async () => { },
|
|
654
|
+
toJSON: () => ({ id, name: instance.name, type: 'conditional' }),
|
|
655
|
+
getMetadata: () => ({ id, name: instance.name, type: 'conditional', createdAt, invocationCount: 0 }),
|
|
656
|
+
getInvocationHistory: async () => [],
|
|
657
|
+
};
|
|
658
|
+
return instance;
|
|
659
|
+
}
|
|
660
|
+
// ============================================================================
|
|
661
|
+
// MAPPED FUNCTION
|
|
662
|
+
// ============================================================================
|
|
663
|
+
function createMappedFunction(fn, mapper, options) {
|
|
664
|
+
const id = crypto.randomUUID();
|
|
665
|
+
const createdAt = new Date();
|
|
666
|
+
const execute = async (input) => {
|
|
667
|
+
const result = await fn.execute(input);
|
|
668
|
+
return mapper(result);
|
|
669
|
+
};
|
|
670
|
+
const instance = {
|
|
671
|
+
id,
|
|
672
|
+
name: `${fn.name} (mapped)`,
|
|
673
|
+
type: fn.type,
|
|
674
|
+
createdAt,
|
|
675
|
+
execute,
|
|
676
|
+
pipe: (next) => createComposedFunction([instance, next], options),
|
|
677
|
+
if: (pred) => createConditionalFunction(instance, pred, options),
|
|
678
|
+
map: (m) => createMappedFunction(instance, m, options),
|
|
679
|
+
contramap: (m) => createContramappedFunction(instance, m, options),
|
|
680
|
+
catch: (handler) => createCatchFunction(instance, handler, options),
|
|
681
|
+
finally: (cleanup) => createFinallyFunction(instance, cleanup, options),
|
|
682
|
+
register: async () => { },
|
|
683
|
+
unregister: async () => { },
|
|
684
|
+
toJSON: () => ({ id, name: instance.name, type: 'mapped' }),
|
|
685
|
+
getMetadata: () => ({ id, name: instance.name, type: 'mapped', createdAt, invocationCount: 0 }),
|
|
686
|
+
getInvocationHistory: async () => [],
|
|
687
|
+
};
|
|
688
|
+
return instance;
|
|
689
|
+
}
|
|
690
|
+
// ============================================================================
|
|
691
|
+
// CONTRAMAPPED FUNCTION
|
|
692
|
+
// ============================================================================
|
|
693
|
+
function createContramappedFunction(fn, mapper, options) {
|
|
694
|
+
const id = crypto.randomUUID();
|
|
695
|
+
const createdAt = new Date();
|
|
696
|
+
const execute = async (input) => {
|
|
697
|
+
const mappedInput = mapper(input);
|
|
698
|
+
return fn.execute(mappedInput);
|
|
699
|
+
};
|
|
700
|
+
const instance = {
|
|
701
|
+
id,
|
|
702
|
+
name: `${fn.name} (contramapped)`,
|
|
703
|
+
type: fn.type,
|
|
704
|
+
createdAt,
|
|
705
|
+
execute,
|
|
706
|
+
pipe: (next) => createComposedFunction([instance, next], options),
|
|
707
|
+
if: (pred) => createConditionalFunction(instance, pred, options),
|
|
708
|
+
map: (m) => createMappedFunction(instance, m, options),
|
|
709
|
+
contramap: (m) => createContramappedFunction(instance, m, options),
|
|
710
|
+
catch: (handler) => createCatchFunction(instance, handler, options),
|
|
711
|
+
finally: (cleanup) => createFinallyFunction(instance, cleanup, options),
|
|
712
|
+
register: async () => { },
|
|
713
|
+
unregister: async () => { },
|
|
714
|
+
toJSON: () => ({ id, name: instance.name, type: 'contramapped' }),
|
|
715
|
+
getMetadata: () => ({ id, name: instance.name, type: 'contramapped', createdAt, invocationCount: 0 }),
|
|
716
|
+
getInvocationHistory: async () => [],
|
|
717
|
+
};
|
|
718
|
+
return instance;
|
|
719
|
+
}
|
|
720
|
+
// ============================================================================
|
|
721
|
+
// CATCH FUNCTION
|
|
722
|
+
// ============================================================================
|
|
723
|
+
function createCatchFunction(fn, handler, options) {
|
|
724
|
+
const id = crypto.randomUUID();
|
|
725
|
+
const createdAt = new Date();
|
|
726
|
+
const execute = async (input) => {
|
|
727
|
+
try {
|
|
728
|
+
return await fn.execute(input);
|
|
729
|
+
}
|
|
730
|
+
catch (error) {
|
|
731
|
+
return handler(error);
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
const instance = {
|
|
735
|
+
id,
|
|
736
|
+
name: `${fn.name} (with catch)`,
|
|
737
|
+
type: fn.type,
|
|
738
|
+
createdAt,
|
|
739
|
+
execute,
|
|
740
|
+
pipe: (next) => createComposedFunction([instance, next], options),
|
|
741
|
+
if: (pred) => createConditionalFunction(instance, pred, options),
|
|
742
|
+
map: (m) => createMappedFunction(instance, m, options),
|
|
743
|
+
contramap: (m) => createContramappedFunction(instance, m, options),
|
|
744
|
+
catch: (h) => createCatchFunction(instance, h, options),
|
|
745
|
+
finally: (cleanup) => createFinallyFunction(instance, cleanup, options),
|
|
746
|
+
register: async () => { },
|
|
747
|
+
unregister: async () => { },
|
|
748
|
+
toJSON: () => ({ id, name: instance.name, type: 'catch' }),
|
|
749
|
+
getMetadata: () => ({ id, name: instance.name, type: 'catch', createdAt, invocationCount: 0 }),
|
|
750
|
+
getInvocationHistory: async () => [],
|
|
751
|
+
};
|
|
752
|
+
return instance;
|
|
753
|
+
}
|
|
754
|
+
// ============================================================================
|
|
755
|
+
// FINALLY FUNCTION
|
|
756
|
+
// ============================================================================
|
|
757
|
+
function createFinallyFunction(fn, cleanup, options) {
|
|
758
|
+
const id = crypto.randomUUID();
|
|
759
|
+
const createdAt = new Date();
|
|
760
|
+
const execute = async (input) => {
|
|
761
|
+
try {
|
|
762
|
+
return await fn.execute(input);
|
|
763
|
+
}
|
|
764
|
+
finally {
|
|
765
|
+
await cleanup();
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
const instance = {
|
|
769
|
+
id,
|
|
770
|
+
name: `${fn.name} (with finally)`,
|
|
771
|
+
type: fn.type,
|
|
772
|
+
createdAt,
|
|
773
|
+
execute,
|
|
774
|
+
pipe: (next) => createComposedFunction([instance, next], options),
|
|
775
|
+
if: (pred) => createConditionalFunction(instance, pred, options),
|
|
776
|
+
map: (m) => createMappedFunction(instance, m, options),
|
|
777
|
+
contramap: (m) => createContramappedFunction(instance, m, options),
|
|
778
|
+
catch: (h) => createCatchFunction(instance, h, options),
|
|
779
|
+
finally: (c) => createFinallyFunction(instance, c, options),
|
|
780
|
+
register: async () => { },
|
|
781
|
+
unregister: async () => { },
|
|
782
|
+
toJSON: () => ({ id, name: instance.name, type: 'finally' }),
|
|
783
|
+
getMetadata: () => ({ id, name: instance.name, type: 'finally', createdAt, invocationCount: 0 }),
|
|
784
|
+
getInvocationHistory: async () => [],
|
|
785
|
+
};
|
|
786
|
+
return instance;
|
|
787
|
+
}
|
|
788
|
+
// ============================================================================
|
|
789
|
+
// PARALLEL FUNCTIONS
|
|
790
|
+
// ============================================================================
|
|
791
|
+
function createParallelFunction(functions, mode) {
|
|
792
|
+
const id = crypto.randomUUID();
|
|
793
|
+
const createdAt = new Date();
|
|
794
|
+
const name = `parallel(${functions.map(f => f.name).join(', ')})`;
|
|
795
|
+
const execute = async (input) => {
|
|
796
|
+
const promises = functions.map(fn => fn.execute(input));
|
|
797
|
+
if (mode === 'all') {
|
|
798
|
+
return Promise.all(promises);
|
|
799
|
+
}
|
|
800
|
+
else {
|
|
801
|
+
const results = await Promise.allSettled(promises);
|
|
802
|
+
return results.map(r => r.status === 'fulfilled'
|
|
803
|
+
? { status: 'fulfilled', value: r.value }
|
|
804
|
+
: { status: 'rejected', reason: r.reason });
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
const instance = {
|
|
808
|
+
id,
|
|
809
|
+
name,
|
|
810
|
+
type: 'code',
|
|
811
|
+
createdAt,
|
|
812
|
+
execute,
|
|
813
|
+
pipe: (next) => createComposedFunction([instance, next], {}),
|
|
814
|
+
if: (pred) => createConditionalFunction(instance, pred, {}),
|
|
815
|
+
map: (m) => createMappedFunction(instance, m, {}),
|
|
816
|
+
contramap: (m) => createContramappedFunction(instance, m, {}),
|
|
817
|
+
catch: (h) => createCatchFunction(instance, h, {}),
|
|
818
|
+
finally: (c) => createFinallyFunction(instance, c, {}),
|
|
819
|
+
register: async () => { },
|
|
820
|
+
unregister: async () => { },
|
|
821
|
+
toJSON: () => ({ id, name, type: 'parallel' }),
|
|
822
|
+
getMetadata: () => ({ id, name, type: 'parallel', createdAt, invocationCount: 0 }),
|
|
823
|
+
getInvocationHistory: async () => [],
|
|
824
|
+
};
|
|
825
|
+
return instance;
|
|
826
|
+
}
|
|
827
|
+
// ============================================================================
|
|
828
|
+
// MAIN FACTORY FUNCTION
|
|
829
|
+
// ============================================================================
|
|
830
|
+
// We use a non-async wrapper function to avoid TypeScript's thenable detection issue
|
|
831
|
+
// FunctionInstance has a 'then' method for composition which conflicts with Promise.then
|
|
832
|
+
function createFunctionImpl(def, options) {
|
|
833
|
+
// Wrap everything to ensure validation errors become Promise rejections
|
|
834
|
+
try {
|
|
835
|
+
// Validate definition (sync)
|
|
836
|
+
validate(def);
|
|
837
|
+
}
|
|
838
|
+
catch (e) {
|
|
839
|
+
return Promise.reject(e);
|
|
840
|
+
}
|
|
841
|
+
// Create instance (sync)
|
|
842
|
+
const instance = createFunctionInstance(def, options);
|
|
843
|
+
// Register with DO if provided (sync)
|
|
844
|
+
if (options.durableObject) {
|
|
845
|
+
options.durableObject.registerFunction(instance);
|
|
846
|
+
}
|
|
847
|
+
// Build the promise chain for async operations
|
|
848
|
+
let promise = Promise.resolve();
|
|
849
|
+
// Check for duplicate names if registry provided
|
|
850
|
+
if (options.registry && options.autoRegister !== false) {
|
|
851
|
+
promise = promise.then(async () => {
|
|
852
|
+
const existing = await options.registry.has(def.name);
|
|
853
|
+
if (existing && !options.replace) {
|
|
854
|
+
throw new RegistrationError(`Function '${def.name}' already exists`);
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
// Store in state if provided
|
|
859
|
+
if (options.state) {
|
|
860
|
+
promise = promise.then(() => options.state.storage.put(`function:${def.name}`, {
|
|
861
|
+
name: def.name,
|
|
862
|
+
type: def.type,
|
|
863
|
+
description: def.description,
|
|
864
|
+
id: instance.id,
|
|
865
|
+
createdAt: instance.createdAt.toISOString(),
|
|
866
|
+
}));
|
|
867
|
+
}
|
|
868
|
+
// Auto-register with registry
|
|
869
|
+
if (options.registry && options.autoRegister !== false) {
|
|
870
|
+
promise = promise.then(async () => {
|
|
871
|
+
if (options.replace) {
|
|
872
|
+
await options.registry.unregister(def.name);
|
|
873
|
+
options.onEvent?.('function.replaced', { name: def.name, id: instance.id });
|
|
874
|
+
}
|
|
875
|
+
await options.registry.register(instance);
|
|
876
|
+
options.onEvent?.('function.registered', { name: def.name, type: def.type, id: instance.id });
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
// We need to explicitly resolve with the instance to avoid the thenable issue
|
|
880
|
+
// where JavaScript would try to call instance.then() since it exists
|
|
881
|
+
return new Promise((resolve, reject) => {
|
|
882
|
+
promise.then(() => resolve(instance)).catch(reject);
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
// Note: Using type assertion to avoid the thenable conflict with Promise<FunctionInstance>
|
|
886
|
+
// The FunctionInstance type has a 'then' method for composition which conflicts with Promise.then
|
|
887
|
+
export const createFunction = Object.assign((def, options) => createFunctionImpl(def, options), {
|
|
888
|
+
all: (functions) => {
|
|
889
|
+
return createParallelFunction(functions, 'all');
|
|
890
|
+
},
|
|
891
|
+
allSettled: (functions) => {
|
|
892
|
+
return createParallelFunction(functions, 'allSettled');
|
|
893
|
+
},
|
|
894
|
+
fromStorage: (name, options) => {
|
|
895
|
+
if (!options.state) {
|
|
896
|
+
return Promise.reject(new Error('State is required to restore from storage'));
|
|
897
|
+
}
|
|
898
|
+
return new Promise((resolve, reject) => {
|
|
899
|
+
options.state.storage.get(`function:${name}`).then((stored) => {
|
|
900
|
+
const storedData = stored;
|
|
901
|
+
if (!storedData) {
|
|
902
|
+
reject(new Error(`Function '${name}' not found in storage`));
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
// Create a minimal placeholder instance for restoration
|
|
906
|
+
// In real implementation, would need to store and restore full definition
|
|
907
|
+
const id = storedData.id;
|
|
908
|
+
const createdAt = new Date(storedData.createdAt);
|
|
909
|
+
const instance = {
|
|
910
|
+
id,
|
|
911
|
+
name: storedData.name,
|
|
912
|
+
type: storedData.type,
|
|
913
|
+
description: storedData.description,
|
|
914
|
+
createdAt,
|
|
915
|
+
execute: () => Promise.reject(new Error('Function restored from storage cannot be executed without handler')),
|
|
916
|
+
register: (registry) => registry.register(instance),
|
|
917
|
+
unregister: () => Promise.resolve(),
|
|
918
|
+
toJSON: () => ({ id, name: storedData.name, type: storedData.type }),
|
|
919
|
+
getMetadata: () => ({ id, name: storedData.name, type: storedData.type, createdAt, invocationCount: 0 }),
|
|
920
|
+
getInvocationHistory: () => Promise.resolve([]),
|
|
921
|
+
pipe: () => instance,
|
|
922
|
+
if: () => instance,
|
|
923
|
+
map: () => instance,
|
|
924
|
+
contramap: () => instance,
|
|
925
|
+
catch: () => instance,
|
|
926
|
+
finally: () => instance,
|
|
927
|
+
};
|
|
928
|
+
resolve(instance);
|
|
929
|
+
}).catch(reject);
|
|
930
|
+
});
|
|
931
|
+
},
|
|
932
|
+
});
|
|
933
|
+
export default createFunction;
|
|
934
|
+
//# sourceMappingURL=createFunction.js.map
|