dotdo 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +446 -315
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/template-literals.js +852 -0
- package/dist/ai/template-literals.js.map +1 -0
- package/dist/api/analytics/router.js +601 -0
- package/dist/api/analytics/router.js.map +1 -0
- package/dist/api/index.js +158 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +544 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/api/middleware/error-handling.js +176 -0
- package/dist/api/middleware/error-handling.js.map +1 -0
- package/dist/api/middleware/request-id.js +21 -0
- package/dist/api/middleware/request-id.js.map +1 -0
- package/dist/api/pages.js +1180 -0
- package/dist/api/pages.js.map +1 -0
- package/dist/api/routes/api.js +612 -0
- package/dist/api/routes/api.js.map +1 -0
- package/dist/api/routes/browsers.js +471 -0
- package/dist/api/routes/browsers.js.map +1 -0
- package/dist/api/routes/do.js +188 -0
- package/dist/api/routes/do.js.map +1 -0
- package/dist/api/routes/mcp.js +459 -0
- package/dist/api/routes/mcp.js.map +1 -0
- package/dist/api/routes/obs.js +445 -0
- package/dist/api/routes/obs.js.map +1 -0
- package/dist/api/routes/openapi.js +794 -0
- package/dist/api/routes/openapi.js.map +1 -0
- package/dist/api/routes/rpc.js +1103 -0
- package/dist/api/routes/rpc.js.map +1 -0
- package/dist/api/routes/sandboxes.js +389 -0
- package/dist/api/routes/sandboxes.js.map +1 -0
- package/dist/api/test-do.js +38 -0
- package/dist/api/test-do.js.map +1 -0
- package/dist/api/types.js +11 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli/bin.js +2 -0
- package/dist/cli/main.js +52342 -0
- package/dist/db/actions.js +212 -0
- package/dist/db/actions.js.map +1 -0
- package/dist/db/auth.js +506 -0
- package/dist/db/auth.js.map +1 -0
- package/dist/db/branches.js +65 -0
- package/dist/db/branches.js.map +1 -0
- package/dist/db/clickhouse.js +1074 -0
- package/dist/db/clickhouse.js.map +1 -0
- package/dist/db/dlq.js +39 -0
- package/dist/db/dlq.js.map +1 -0
- package/dist/db/events.js +28 -0
- package/dist/db/events.js.map +1 -0
- package/dist/db/exec.js +64 -0
- package/dist/db/exec.js.map +1 -0
- package/dist/db/files.js +85 -0
- package/dist/db/files.js.map +1 -0
- package/dist/db/flags.js +24 -0
- package/dist/db/flags.js.map +1 -0
- package/dist/db/git.js +116 -0
- package/dist/db/git.js.map +1 -0
- package/dist/db/iceberg/inverted-index.js +862 -0
- package/dist/db/iceberg/inverted-index.js.map +1 -0
- package/dist/db/iceberg/puffin.js +878 -0
- package/dist/db/iceberg/puffin.js.map +1 -0
- package/dist/db/iceberg/search-manifest.js +422 -0
- package/dist/db/iceberg/search-manifest.js.map +1 -0
- package/dist/db/iceberg/types.js +8 -0
- package/dist/db/iceberg/types.js.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/integrations.js +368 -0
- package/dist/db/integrations.js.map +1 -0
- package/dist/db/json-indexes.js +332 -0
- package/dist/db/json-indexes.js.map +1 -0
- package/dist/db/linked-accounts.js +287 -0
- package/dist/db/linked-accounts.js.map +1 -0
- package/dist/db/nouns.js +183 -0
- package/dist/db/nouns.js.map +1 -0
- package/dist/db/objects.js +170 -0
- package/dist/db/objects.js.map +1 -0
- package/dist/db/primitives/dag-scheduler/index.js +869 -0
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
- package/dist/db/primitives/exactly-once-context.js +237 -0
- package/dist/db/primitives/exactly-once-context.js.map +1 -0
- package/dist/db/primitives/index.js +62 -0
- package/dist/db/primitives/index.js.map +1 -0
- package/dist/db/primitives/keyed-router.js +145 -0
- package/dist/db/primitives/keyed-router.js.map +1 -0
- package/dist/db/primitives/observability.js +162 -0
- package/dist/db/primitives/observability.js.map +1 -0
- package/dist/db/primitives/schema-evolution.js +643 -0
- package/dist/db/primitives/schema-evolution.js.map +1 -0
- package/dist/db/primitives/stateful-operator/index.js +770 -0
- package/dist/db/primitives/stateful-operator/index.js.map +1 -0
- package/dist/db/primitives/temporal-store.js +306 -0
- package/dist/db/primitives/temporal-store.js.map +1 -0
- package/dist/db/primitives/typed-column-store.js +1229 -0
- package/dist/db/primitives/typed-column-store.js.map +1 -0
- package/dist/db/primitives/utils/duration.js +162 -0
- package/dist/db/primitives/utils/duration.js.map +1 -0
- package/dist/db/primitives/utils/murmur3.js +118 -0
- package/dist/db/primitives/utils/murmur3.js.map +1 -0
- package/dist/db/primitives/watermark-service.js +136 -0
- package/dist/db/primitives/watermark-service.js.map +1 -0
- package/dist/db/primitives/window-manager.js +764 -0
- package/dist/db/primitives/window-manager.js.map +1 -0
- package/dist/db/relationships.js +66 -0
- package/dist/db/relationships.js.map +1 -0
- package/dist/db/schema-minimal.js +61 -0
- package/dist/db/schema-minimal.js.map +1 -0
- package/dist/db/search.js +28 -0
- package/dist/db/search.js.map +1 -0
- package/dist/db/stores.js +1665 -0
- package/dist/db/stores.js.map +1 -0
- package/dist/db/things.js +297 -0
- package/dist/db/things.js.map +1 -0
- package/dist/db/vault.js +171 -0
- package/dist/db/vault.js.map +1 -0
- package/dist/db/verbs.js +102 -0
- package/dist/db/verbs.js.map +1 -0
- package/dist/do/base.js +48 -0
- package/dist/do/base.js.map +1 -0
- package/dist/do/bash.js +35 -0
- package/dist/do/bash.js.map +1 -0
- package/dist/do/fs.js +25 -0
- package/dist/do/fs.js.map +1 -0
- package/dist/do/full.js +61 -0
- package/dist/do/full.js.map +1 -0
- package/dist/do/git.js +28 -0
- package/dist/do/git.js.map +1 -0
- package/dist/do/index.js +52 -0
- package/dist/do/index.js.map +1 -0
- package/dist/do/tiny.js +31 -0
- package/dist/do/tiny.js.map +1 -0
- package/dist/lib/DOAuth.js +261 -0
- package/dist/lib/DOAuth.js.map +1 -0
- package/dist/lib/DODispatcher.js +72 -0
- package/dist/lib/DODispatcher.js.map +1 -0
- package/dist/lib/Modifier.js +189 -0
- package/dist/lib/Modifier.js.map +1 -0
- package/dist/lib/StateStorage.js +403 -0
- package/dist/lib/StateStorage.js.map +1 -0
- package/dist/lib/TypeRegistry.js +122 -0
- package/dist/lib/TypeRegistry.js.map +1 -0
- package/dist/lib/agent/tools/bash.js +336 -0
- package/dist/lib/agent/tools/bash.js.map +1 -0
- package/dist/lib/agent/tools/edit.js +157 -0
- package/dist/lib/agent/tools/edit.js.map +1 -0
- package/dist/lib/agent/tools/glob.js +137 -0
- package/dist/lib/agent/tools/glob.js.map +1 -0
- package/dist/lib/agent/tools/grep.js +315 -0
- package/dist/lib/agent/tools/grep.js.map +1 -0
- package/dist/lib/agent/tools/index.js +71 -0
- package/dist/lib/agent/tools/index.js.map +1 -0
- package/dist/lib/agent/tools/read.js +212 -0
- package/dist/lib/agent/tools/read.js.map +1 -0
- package/dist/lib/agent/tools/types.js +197 -0
- package/dist/lib/agent/tools/types.js.map +1 -0
- package/dist/lib/agent/tools/write.js +159 -0
- package/dist/lib/agent/tools/write.js.map +1 -0
- package/dist/lib/ai/gateway.js +247 -0
- package/dist/lib/ai/gateway.js.map +1 -0
- package/dist/lib/ai/tool-loop-agent.js +591 -0
- package/dist/lib/ai/tool-loop-agent.js.map +1 -0
- package/dist/lib/auto-wiring.js +439 -0
- package/dist/lib/auto-wiring.js.map +1 -0
- package/dist/lib/browse/browserbase.js +163 -0
- package/dist/lib/browse/browserbase.js.map +1 -0
- package/dist/lib/browse/cloudflare.js +144 -0
- package/dist/lib/browse/cloudflare.js.map +1 -0
- package/dist/lib/browse/index.js +62 -0
- package/dist/lib/browse/index.js.map +1 -0
- package/dist/lib/browse/types.js +13 -0
- package/dist/lib/browse/types.js.map +1 -0
- package/dist/lib/cache/index.js +37 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/visibility.js +638 -0
- package/dist/lib/cache/visibility.js.map +1 -0
- package/dist/lib/capabilities.js +268 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/channels/base.js +106 -0
- package/dist/lib/channels/base.js.map +1 -0
- package/dist/lib/channels/discord.js +94 -0
- package/dist/lib/channels/discord.js.map +1 -0
- package/dist/lib/channels/email.js +204 -0
- package/dist/lib/channels/email.js.map +1 -0
- package/dist/lib/channels/index.js +90 -0
- package/dist/lib/channels/index.js.map +1 -0
- package/dist/lib/channels/mdxui-chat.js +95 -0
- package/dist/lib/channels/mdxui-chat.js.map +1 -0
- package/dist/lib/channels/slack-blockkit.js +121 -0
- package/dist/lib/channels/slack-blockkit.js.map +1 -0
- package/dist/lib/channels/types.js +7 -0
- package/dist/lib/channels/types.js.map +1 -0
- package/dist/lib/cloudflare/ai.js +654 -0
- package/dist/lib/cloudflare/ai.js.map +1 -0
- package/dist/lib/cloudflare/index.js +88 -0
- package/dist/lib/cloudflare/index.js.map +1 -0
- package/dist/lib/cloudflare/kv.js +342 -0
- package/dist/lib/cloudflare/kv.js.map +1 -0
- package/dist/lib/cloudflare/queues.js +434 -0
- package/dist/lib/cloudflare/queues.js.map +1 -0
- package/dist/lib/cloudflare/r2.js +604 -0
- package/dist/lib/cloudflare/r2.js.map +1 -0
- package/dist/lib/cloudflare/vectorize.js +494 -0
- package/dist/lib/cloudflare/vectorize.js.map +1 -0
- package/dist/lib/cloudflare/workflows.js +569 -0
- package/dist/lib/cloudflare/workflows.js.map +1 -0
- package/dist/lib/colo/caching.js +196 -0
- package/dist/lib/colo/caching.js.map +1 -0
- package/dist/lib/colo/detection.js +194 -0
- package/dist/lib/colo/detection.js.map +1 -0
- package/dist/lib/colo/external-data.js +219 -0
- package/dist/lib/colo/external-data.js.map +1 -0
- package/dist/lib/colo/globe-data.js +179 -0
- package/dist/lib/colo/globe-data.js.map +1 -0
- package/dist/lib/colo/index.js +16 -0
- package/dist/lib/colo/index.js.map +1 -0
- package/dist/lib/decorators.js +37 -0
- package/dist/lib/decorators.js.map +1 -0
- package/dist/lib/discovery.js +81 -0
- package/dist/lib/discovery.js.map +1 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
- package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/CascadeExecutor.js +418 -0
- package/dist/lib/executors/CascadeExecutor.js.map +1 -0
- package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/ParallelStepExecutor.js +308 -0
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
- package/dist/lib/executors/types.js +12 -0
- package/dist/lib/executors/types.js.map +1 -0
- package/dist/lib/experiments.js +89 -0
- package/dist/lib/experiments.js.map +1 -0
- package/dist/lib/flags/store.js +262 -0
- package/dist/lib/flags/store.js.map +1 -0
- package/dist/lib/functions/FunctionComposition.js +467 -0
- package/dist/lib/functions/FunctionComposition.js.map +1 -0
- package/dist/lib/functions/FunctionMiddleware.js +457 -0
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
- package/dist/lib/functions/FunctionRegistry.js +426 -0
- package/dist/lib/functions/FunctionRegistry.js.map +1 -0
- package/dist/lib/functions/createFunction.js +1048 -0
- package/dist/lib/functions/createFunction.js.map +1 -0
- package/dist/lib/humans/index.js +68 -0
- package/dist/lib/humans/index.js.map +1 -0
- package/dist/lib/humans/templates.js +117 -0
- package/dist/lib/humans/templates.js.map +1 -0
- package/dist/lib/identity.js +98 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logging/error-logger.js +163 -0
- package/dist/lib/logging/error-logger.js.map +1 -0
- package/dist/lib/logging/index.js +160 -0
- package/dist/lib/logging/index.js.map +1 -0
- package/dist/lib/mixins/bash.js +825 -0
- package/dist/lib/mixins/bash.js.map +1 -0
- package/dist/lib/mixins/fs.js +648 -0
- package/dist/lib/mixins/fs.js.map +1 -0
- package/dist/lib/mixins/git.js +1011 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/index.js +29 -0
- package/dist/lib/mixins/index.js.map +1 -0
- package/dist/lib/mixins/npm.js +662 -0
- package/dist/lib/mixins/npm.js.map +1 -0
- package/dist/lib/noun-id.js +278 -0
- package/dist/lib/noun-id.js.map +1 -0
- package/dist/lib/rate-limit/sliding-window.js +148 -0
- package/dist/lib/rate-limit/sliding-window.js.map +1 -0
- package/dist/lib/rate-limit.js +110 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/rpc/bindings.js +548 -0
- package/dist/lib/rpc/bindings.js.map +1 -0
- package/dist/lib/rpc/index.js +64 -0
- package/dist/lib/rpc/index.js.map +1 -0
- package/dist/lib/safe-stringify.js +223 -0
- package/dist/lib/safe-stringify.js.map +1 -0
- package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
- package/dist/lib/sqids.js +110 -0
- package/dist/lib/sqids.js.map +1 -0
- package/dist/lib/sql/adapters/index.js +10 -0
- package/dist/lib/sql/adapters/index.js.map +1 -0
- package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
- package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
- package/dist/lib/sql/index.js +277 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql/types.js +56 -0
- package/dist/lib/sql/types.js.map +1 -0
- package/dist/lib/type-classifier.js +126 -0
- package/dist/lib/type-classifier.js.map +1 -0
- package/dist/lib/utils/html.js +47 -0
- package/dist/lib/utils/html.js.map +1 -0
- package/dist/lib/validation.js +48 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/vault/store.js +411 -0
- package/dist/lib/vault/store.js.map +1 -0
- package/dist/metrics/hunch.js +739 -0
- package/dist/metrics/hunch.js.map +1 -0
- package/dist/objects/API.js +302 -0
- package/dist/objects/API.js.map +1 -0
- package/dist/objects/Agent.js +179 -0
- package/dist/objects/Agent.js.map +1 -0
- package/dist/objects/AgenticFunctionExecutor.js +8 -0
- package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
- package/dist/objects/App.js +83 -0
- package/dist/objects/App.js.map +1 -0
- package/dist/objects/Browser.js +884 -0
- package/dist/objects/Browser.js.map +1 -0
- package/dist/objects/Business.js +107 -0
- package/dist/objects/Business.js.map +1 -0
- package/dist/objects/CLI.js +221 -0
- package/dist/objects/CLI.js.map +1 -0
- package/dist/objects/CodeFunctionExecutor.js +8 -0
- package/dist/objects/CodeFunctionExecutor.js.map +1 -0
- package/dist/objects/Collection.js +161 -0
- package/dist/objects/Collection.js.map +1 -0
- package/dist/objects/DO.js +41 -0
- package/dist/objects/DO.js.map +1 -0
- package/dist/objects/DOBase.js +2309 -0
- package/dist/objects/DOBase.js.map +1 -0
- package/dist/objects/DOFull.js +1676 -0
- package/dist/objects/DOFull.js.map +1 -0
- package/dist/objects/DOTiny.js +207 -0
- package/dist/objects/DOTiny.js.map +1 -0
- package/dist/objects/Directory.js +199 -0
- package/dist/objects/Directory.js.map +1 -0
- package/dist/objects/Entity.js +413 -0
- package/dist/objects/Entity.js.map +1 -0
- package/dist/objects/Function.js +116 -0
- package/dist/objects/Function.js.map +1 -0
- package/dist/objects/Human.js +231 -0
- package/dist/objects/Human.js.map +1 -0
- package/dist/objects/HumanFunctionExecutor.js +8 -0
- package/dist/objects/HumanFunctionExecutor.js.map +1 -0
- package/dist/objects/IcebergMetadataDO.js +938 -0
- package/dist/objects/IcebergMetadataDO.js.map +1 -0
- package/dist/objects/IntegrationsDO.js +1174 -0
- package/dist/objects/IntegrationsDO.js.map +1 -0
- package/dist/objects/ObservabilityBroadcaster.js +149 -0
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
- package/dist/objects/Package.js +154 -0
- package/dist/objects/Package.js.map +1 -0
- package/dist/objects/Product.js +193 -0
- package/dist/objects/Product.js.map +1 -0
- package/dist/objects/SDK.js +152 -0
- package/dist/objects/SDK.js.map +1 -0
- package/dist/objects/SaaS.js +235 -0
- package/dist/objects/SaaS.js.map +1 -0
- package/dist/objects/SandboxDO.js +759 -0
- package/dist/objects/SandboxDO.js.map +1 -0
- package/dist/objects/Service.js +337 -0
- package/dist/objects/Service.js.map +1 -0
- package/dist/objects/Site.js +80 -0
- package/dist/objects/Site.js.map +1 -0
- package/dist/objects/Startup.js +479 -0
- package/dist/objects/Startup.js.map +1 -0
- package/dist/objects/ThingsDO.js +170 -0
- package/dist/objects/ThingsDO.js.map +1 -0
- package/dist/objects/VectorShardDO.js +648 -0
- package/dist/objects/VectorShardDO.js.map +1 -0
- package/dist/objects/Worker.js +144 -0
- package/dist/objects/Worker.js.map +1 -0
- package/dist/objects/Workflow.js +196 -0
- package/dist/objects/Workflow.js.map +1 -0
- package/dist/objects/WorkflowFactory.js +313 -0
- package/dist/objects/WorkflowFactory.js.map +1 -0
- package/dist/objects/WorkflowRuntime.js +863 -0
- package/dist/objects/WorkflowRuntime.js.map +1 -0
- package/dist/objects/circuit-breaker-bulkhead.js +178 -0
- package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
- package/dist/objects/createFunction.js +934 -0
- package/dist/objects/createFunction.js.map +1 -0
- package/dist/objects/index.js +80 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/objects/lifecycle/Branch.js +275 -0
- package/dist/objects/lifecycle/Branch.js.map +1 -0
- package/dist/objects/lifecycle/Clone.js +1499 -0
- package/dist/objects/lifecycle/Clone.js.map +1 -0
- package/dist/objects/lifecycle/Compact.js +237 -0
- package/dist/objects/lifecycle/Compact.js.map +1 -0
- package/dist/objects/lifecycle/Promote.js +476 -0
- package/dist/objects/lifecycle/Promote.js.map +1 -0
- package/dist/objects/lifecycle/Shard.js +560 -0
- package/dist/objects/lifecycle/Shard.js.map +1 -0
- package/dist/objects/lifecycle/index.js +15 -0
- package/dist/objects/lifecycle/index.js.map +1 -0
- package/dist/objects/lifecycle/types.js +33 -0
- package/dist/objects/lifecycle/types.js.map +1 -0
- package/dist/objects/mixins/infrastructure.js +171 -0
- package/dist/objects/mixins/infrastructure.js.map +1 -0
- package/dist/objects/modules/StoresModule.js +153 -0
- package/dist/objects/modules/StoresModule.js.map +1 -0
- package/dist/objects/persistence/checkpoint-manager.js +606 -0
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
- package/dist/objects/persistence/index.js +72 -0
- package/dist/objects/persistence/index.js.map +1 -0
- package/dist/objects/persistence/migration-runner.js +562 -0
- package/dist/objects/persistence/migration-runner.js.map +1 -0
- package/dist/objects/persistence/replication-manager.js +501 -0
- package/dist/objects/persistence/replication-manager.js.map +1 -0
- package/dist/objects/persistence/tiered-storage-manager.js +595 -0
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
- package/dist/objects/persistence/types.js +14 -0
- package/dist/objects/persistence/types.js.map +1 -0
- package/dist/objects/persistence/wal-manager.js +653 -0
- package/dist/objects/persistence/wal-manager.js.map +1 -0
- package/dist/objects/presets/index.js +20 -0
- package/dist/objects/presets/index.js.map +1 -0
- package/dist/objects/presets/primitives.js +188 -0
- package/dist/objects/presets/primitives.js.map +1 -0
- package/dist/objects/primitives/alarm-adapter.js +141 -0
- package/dist/objects/primitives/alarm-adapter.js.map +1 -0
- package/dist/objects/primitives/index.js +337 -0
- package/dist/objects/primitives/index.js.map +1 -0
- package/dist/objects/primitives/storage-adapter.js +182 -0
- package/dist/objects/primitives/storage-adapter.js.map +1 -0
- package/dist/objects/primitives/with-primitives.js +102 -0
- package/dist/objects/primitives/with-primitives.js.map +1 -0
- package/dist/objects/services/StoreManager.js +227 -0
- package/dist/objects/services/StoreManager.js.map +1 -0
- package/dist/objects/services/index.js +13 -0
- package/dist/objects/services/index.js.map +1 -0
- package/dist/objects/transport/auth-layer.js +1451 -0
- package/dist/objects/transport/auth-layer.js.map +1 -0
- package/dist/objects/transport/capnweb-target.js +355 -0
- package/dist/objects/transport/capnweb-target.js.map +1 -0
- package/dist/objects/transport/chain.js +441 -0
- package/dist/objects/transport/chain.js.map +1 -0
- package/dist/objects/transport/handler.js +58 -0
- package/dist/objects/transport/handler.js.map +1 -0
- package/dist/objects/transport/index.js +53 -0
- package/dist/objects/transport/index.js.map +1 -0
- package/dist/objects/transport/mcp-server.js +690 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1507 -0
- package/dist/objects/transport/rest-autowire.js.map +1 -0
- package/dist/objects/transport/rest-router.js +440 -0
- package/dist/objects/transport/rest-router.js.map +1 -0
- package/dist/objects/transport/rpc-server.js +1536 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +575 -0
- package/dist/objects/transport/shared.js.map +1 -0
- package/dist/objects/transport/sync-engine.js +291 -0
- package/dist/objects/transport/sync-engine.js.map +1 -0
- package/dist/objects/transport/types.js +8 -0
- package/dist/objects/transport/types.js.map +1 -0
- package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
- package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
- package/dist/primitives/bashx/src/ast/parser.js +1488 -0
- package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
- package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
- package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
- package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
- package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
- package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
- package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
- package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
- package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
- package/dist/primitives/bashx/src/do/container-executor.js +429 -0
- package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/index.js +668 -0
- package/dist/primitives/bashx/src/do/index.js.map +1 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
- package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
- package/dist/primitives/bashx/src/do/worker.js +352 -0
- package/dist/primitives/bashx/src/do/worker.js.map +1 -0
- package/dist/primitives/bashx/src/types.js +10 -0
- package/dist/primitives/bashx/src/types.js.map +1 -0
- package/dist/primitives/fsx/core/backend.js +480 -0
- package/dist/primitives/fsx/core/backend.js.map +1 -0
- package/dist/primitives/fsx/core/constants.js +140 -0
- package/dist/primitives/fsx/core/constants.js.map +1 -0
- package/dist/primitives/fsx/core/fsx.js +1184 -0
- package/dist/primitives/fsx/core/fsx.js.map +1 -0
- package/dist/primitives/fsx/core/glob/glob.js +438 -0
- package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
- package/dist/primitives/fsx/core/glob/index.js +8 -0
- package/dist/primitives/fsx/core/glob/index.js.map +1 -0
- package/dist/primitives/fsx/core/glob/match.js +392 -0
- package/dist/primitives/fsx/core/glob/match.js.map +1 -0
- package/dist/primitives/fsx/core/types.js +307 -0
- package/dist/primitives/fsx/core/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sdk/capnweb-compat.js +42 -0
- package/dist/sdk/capnweb-compat.js.map +1 -0
- package/dist/sdk/client.js +20 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/index.js +17 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/snippets/artifacts-config.js +241 -0
- package/dist/snippets/artifacts-config.js.map +1 -0
- package/dist/snippets/artifacts-ingest.js +832 -0
- package/dist/snippets/artifacts-ingest.js.map +1 -0
- package/dist/snippets/artifacts-serve.js +1035 -0
- package/dist/snippets/artifacts-serve.js.map +1 -0
- package/dist/snippets/artifacts-types.js +161 -0
- package/dist/snippets/artifacts-types.js.map +1 -0
- package/dist/snippets/cache-probe.js +376 -0
- package/dist/snippets/cache-probe.js.map +1 -0
- package/dist/snippets/cache.js +10 -0
- package/dist/snippets/cache.js.map +1 -0
- package/dist/snippets/events.js +469 -0
- package/dist/snippets/events.js.map +1 -0
- package/dist/snippets/index.js +7 -0
- package/dist/snippets/index.js.map +1 -0
- package/dist/snippets/proxy.js +495 -0
- package/dist/snippets/proxy.js.map +1 -0
- package/dist/snippets/search.js +1759 -0
- package/dist/snippets/search.js.map +1 -0
- package/dist/streams/index.js +30 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/observability.js +68 -0
- package/dist/streams/observability.js.map +1 -0
- package/dist/types/AI.js +92 -0
- package/dist/types/AI.js.map +1 -0
- package/dist/types/AIFunction.js +171 -0
- package/dist/types/AIFunction.js.map +1 -0
- package/dist/types/BrowseVerb.js +89 -0
- package/dist/types/BrowseVerb.js.map +1 -0
- package/dist/types/Browser.js +31 -0
- package/dist/types/Browser.js.map +1 -0
- package/dist/types/Chaos.js +15 -0
- package/dist/types/Chaos.js.map +1 -0
- package/dist/types/CloudflareBindings.js +109 -0
- package/dist/types/CloudflareBindings.js.map +1 -0
- package/dist/types/Collection.js +50 -0
- package/dist/types/Collection.js.map +1 -0
- package/dist/types/DO.js +2 -0
- package/dist/types/DO.js.map +1 -0
- package/dist/types/DOLocation.js +63 -0
- package/dist/types/DOLocation.js.map +1 -0
- package/dist/types/EventHandler.js +57 -0
- package/dist/types/EventHandler.js.map +1 -0
- package/dist/types/Experiment.js +33 -0
- package/dist/types/Experiment.js.map +1 -0
- package/dist/types/Flag.js +57 -0
- package/dist/types/Flag.js.map +1 -0
- package/dist/types/Lifecycle.js +13 -0
- package/dist/types/Lifecycle.js.map +1 -0
- package/dist/types/Location.js +169 -0
- package/dist/types/Location.js.map +1 -0
- package/dist/types/Noun.js +66 -0
- package/dist/types/Noun.js.map +1 -0
- package/dist/types/SessionEvent.js +194 -0
- package/dist/types/SessionEvent.js.map +1 -0
- package/dist/types/Thing.js +55 -0
- package/dist/types/Thing.js.map +1 -0
- package/dist/types/ThingDO.js +153 -0
- package/dist/types/ThingDO.js.map +1 -0
- package/dist/types/Things.js +2 -0
- package/dist/types/Things.js.map +1 -0
- package/dist/types/Verb.js +119 -0
- package/dist/types/Verb.js.map +1 -0
- package/dist/types/WorkflowContext.js +70 -0
- package/dist/types/WorkflowContext.js.map +1 -0
- package/dist/types/analytics-api.js +13 -0
- package/dist/types/analytics-api.js.map +1 -0
- package/dist/types/capabilities.js +135 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/drizzle.js +12 -0
- package/dist/types/drizzle.js.map +1 -0
- package/dist/types/event.js +201 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/fn.js +12 -0
- package/dist/types/fn.js.map +1 -0
- package/dist/types/iceberg.js +48 -0
- package/dist/types/iceberg.js.map +1 -0
- package/dist/types/ids.js +170 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/introspect.js +54 -0
- package/dist/types/introspect.js.map +1 -0
- package/dist/types/observability.js +124 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/sync-protocol.js +175 -0
- package/dist/types/sync-protocol.js.map +1 -0
- package/dist/types/vector.js +13 -0
- package/dist/types/vector.js.map +1 -0
- package/dist/workflows/ScheduleManager.js +473 -0
- package/dist/workflows/ScheduleManager.js.map +1 -0
- package/dist/workflows/StepDOBridge.js +149 -0
- package/dist/workflows/StepDOBridge.js.map +1 -0
- package/dist/workflows/StepResultStorage.js +232 -0
- package/dist/workflows/StepResultStorage.js.map +1 -0
- package/dist/workflows/WaitForEventManager.js +461 -0
- package/dist/workflows/WaitForEventManager.js.map +1 -0
- package/dist/workflows/analyzer.js +332 -0
- package/dist/workflows/analyzer.js.map +1 -0
- package/dist/workflows/compat/activity-router.js +484 -0
- package/dist/workflows/compat/activity-router.js.map +1 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
- package/dist/workflows/compat/backends/index.js +14 -0
- package/dist/workflows/compat/backends/index.js.map +1 -0
- package/dist/workflows/compat/errors/index.js +375 -0
- package/dist/workflows/compat/errors/index.js.map +1 -0
- package/dist/workflows/compat/index.js +79 -0
- package/dist/workflows/compat/index.js.map +1 -0
- package/dist/workflows/compat/inngest/index.js +989 -0
- package/dist/workflows/compat/inngest/index.js.map +1 -0
- package/dist/workflows/compat/qstash/index.js +1263 -0
- package/dist/workflows/compat/qstash/index.js.map +1 -0
- package/dist/workflows/compat/temporal/activities.js +739 -0
- package/dist/workflows/compat/temporal/activities.js.map +1 -0
- package/dist/workflows/compat/temporal/child-workflows.js +154 -0
- package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
- package/dist/workflows/compat/temporal/client.js +381 -0
- package/dist/workflows/compat/temporal/client.js.map +1 -0
- package/dist/workflows/compat/temporal/context.js +309 -0
- package/dist/workflows/compat/temporal/context.js.map +1 -0
- package/dist/workflows/compat/temporal/determinism.js +216 -0
- package/dist/workflows/compat/temporal/determinism.js.map +1 -0
- package/dist/workflows/compat/temporal/errors.js +128 -0
- package/dist/workflows/compat/temporal/errors.js.map +1 -0
- package/dist/workflows/compat/temporal/index.js +2464 -0
- package/dist/workflows/compat/temporal/index.js.map +1 -0
- package/dist/workflows/compat/temporal/saga.js +504 -0
- package/dist/workflows/compat/temporal/saga.js.map +1 -0
- package/dist/workflows/compat/temporal/signals.js +364 -0
- package/dist/workflows/compat/temporal/signals.js.map +1 -0
- package/dist/workflows/compat/temporal/storage.js +271 -0
- package/dist/workflows/compat/temporal/storage.js.map +1 -0
- package/dist/workflows/compat/temporal/timers.js +347 -0
- package/dist/workflows/compat/temporal/timers.js.map +1 -0
- package/dist/workflows/compat/temporal/types.js +7 -0
- package/dist/workflows/compat/temporal/types.js.map +1 -0
- package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
- package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
- package/dist/workflows/compat/trigger/index.js +468 -0
- package/dist/workflows/compat/trigger/index.js.map +1 -0
- package/dist/workflows/compat/utils/index.js +69 -0
- package/dist/workflows/compat/utils/index.js.map +1 -0
- package/dist/workflows/context/correlation-capability.js +266 -0
- package/dist/workflows/context/correlation-capability.js.map +1 -0
- package/dist/workflows/context/correlation.js +484 -0
- package/dist/workflows/context/correlation.js.map +1 -0
- package/dist/workflows/context/experiment.js +289 -0
- package/dist/workflows/context/experiment.js.map +1 -0
- package/dist/workflows/context/flag.js +244 -0
- package/dist/workflows/context/flag.js.map +1 -0
- package/dist/workflows/context/foundation.js +648 -0
- package/dist/workflows/context/foundation.js.map +1 -0
- package/dist/workflows/context/human-base.js +106 -0
- package/dist/workflows/context/human-base.js.map +1 -0
- package/dist/workflows/context/human.js +368 -0
- package/dist/workflows/context/human.js.map +1 -0
- package/dist/workflows/context/measure.js +354 -0
- package/dist/workflows/context/measure.js.map +1 -0
- package/dist/workflows/context/rate-limit.js +358 -0
- package/dist/workflows/context/rate-limit.js.map +1 -0
- package/dist/workflows/context/user.js +117 -0
- package/dist/workflows/context/user.js.map +1 -0
- package/dist/workflows/context/vault.js +360 -0
- package/dist/workflows/context/vault.js.map +1 -0
- package/dist/workflows/data/entity-events/entity-events.js +489 -0
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
- package/dist/workflows/data/experiment/index.js +599 -0
- package/dist/workflows/data/experiment/index.js.map +1 -0
- package/dist/workflows/data/goal/context.js +558 -0
- package/dist/workflows/data/goal/context.js.map +1 -0
- package/dist/workflows/data/goal/index.js +32 -0
- package/dist/workflows/data/goal/index.js.map +1 -0
- package/dist/workflows/data/measure/index.js +840 -0
- package/dist/workflows/data/measure/index.js.map +1 -0
- package/dist/workflows/data/stream/index.js +1215 -0
- package/dist/workflows/data/stream/index.js.map +1 -0
- package/dist/workflows/data/track/context.js +883 -0
- package/dist/workflows/data/track/context.js.map +1 -0
- package/dist/workflows/data/track/index.js +15 -0
- package/dist/workflows/data/track/index.js.map +1 -0
- package/dist/workflows/data/view/context.js +864 -0
- package/dist/workflows/data/view/context.js.map +1 -0
- package/dist/workflows/domain.js +93 -0
- package/dist/workflows/domain.js.map +1 -0
- package/dist/workflows/flag.js +176 -0
- package/dist/workflows/flag.js.map +1 -0
- package/dist/workflows/flags.js +217 -0
- package/dist/workflows/flags.js.map +1 -0
- package/dist/workflows/hash.js +209 -0
- package/dist/workflows/hash.js.map +1 -0
- package/dist/workflows/index.js +50 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/on.js +378 -0
- package/dist/workflows/on.js.map +1 -0
- package/dist/workflows/pipeline-promise.js +481 -0
- package/dist/workflows/pipeline-promise.js.map +1 -0
- package/dist/workflows/pipeline-types.js +20 -0
- package/dist/workflows/pipeline-types.js.map +1 -0
- package/dist/workflows/proxy.js +76 -0
- package/dist/workflows/proxy.js.map +1 -0
- package/dist/workflows/runtime.js +310 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/schedule-builder.js +327 -0
- package/dist/workflows/schedule-builder.js.map +1 -0
- package/dist/workflows/visibility/index.js +148 -0
- package/dist/workflows/visibility/index.js.map +1 -0
- package/dist/workflows/visibility/query-parser.js +150 -0
- package/dist/workflows/visibility/query-parser.js.map +1 -0
- package/dist/workflows/visibility/store.js +223 -0
- package/dist/workflows/visibility/store.js.map +1 -0
- package/dist/workflows/visibility/types.js +30 -0
- package/dist/workflows/visibility/types.js.map +1 -0
- package/dist/workflows/workflow.js +53 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/package.json +279 -46
|
@@ -0,0 +1,1103 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { validateObsFilter, matchesFilter } from '../../types/observability';
|
|
3
|
+
// Standard JSON-RPC error codes
|
|
4
|
+
const JSON_RPC_ERRORS = {
|
|
5
|
+
PARSE_ERROR: { code: -32700, message: 'Parse error' },
|
|
6
|
+
INVALID_REQUEST: { code: -32600, message: 'Invalid Request' },
|
|
7
|
+
METHOD_NOT_FOUND: { code: -32601, message: 'Method not found' },
|
|
8
|
+
INVALID_PARAMS: { code: -32602, message: 'Invalid params' },
|
|
9
|
+
INTERNAL_ERROR: { code: -32603, message: 'Internal error' },
|
|
10
|
+
};
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Promise Store
|
|
13
|
+
// ============================================================================
|
|
14
|
+
class PromiseStore {
|
|
15
|
+
promises = new Map();
|
|
16
|
+
disposed = new Set();
|
|
17
|
+
set(id, value) {
|
|
18
|
+
this.promises.set(id, value);
|
|
19
|
+
}
|
|
20
|
+
get(id) {
|
|
21
|
+
if (this.disposed.has(id)) {
|
|
22
|
+
throw new Error(`Promise ${id} has been disposed`);
|
|
23
|
+
}
|
|
24
|
+
return this.promises.get(id);
|
|
25
|
+
}
|
|
26
|
+
has(id) {
|
|
27
|
+
return this.promises.has(id) && !this.disposed.has(id);
|
|
28
|
+
}
|
|
29
|
+
dispose(id) {
|
|
30
|
+
if (this.promises.has(id)) {
|
|
31
|
+
this.disposed.add(id);
|
|
32
|
+
this.promises.delete(id);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
isDisposed(id) {
|
|
38
|
+
return this.disposed.has(id);
|
|
39
|
+
}
|
|
40
|
+
clear() {
|
|
41
|
+
this.promises.clear();
|
|
42
|
+
this.disposed.clear();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class SubscriptionManager {
|
|
46
|
+
subscriptions = new Map();
|
|
47
|
+
eventSubscriptions = new Map();
|
|
48
|
+
subscribe(event, callback) {
|
|
49
|
+
const id = `sub_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
50
|
+
this.subscriptions.set(id, { id, event, callback });
|
|
51
|
+
if (!this.eventSubscriptions.has(event)) {
|
|
52
|
+
this.eventSubscriptions.set(event, new Set());
|
|
53
|
+
}
|
|
54
|
+
this.eventSubscriptions.get(event).add(id);
|
|
55
|
+
return id;
|
|
56
|
+
}
|
|
57
|
+
unsubscribe(subscriptionId) {
|
|
58
|
+
const sub = this.subscriptions.get(subscriptionId);
|
|
59
|
+
if (!sub)
|
|
60
|
+
return false;
|
|
61
|
+
this.subscriptions.delete(subscriptionId);
|
|
62
|
+
this.eventSubscriptions.get(sub.event)?.delete(subscriptionId);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
emit(event, data) {
|
|
66
|
+
const subIds = this.eventSubscriptions.get(event);
|
|
67
|
+
if (!subIds)
|
|
68
|
+
return;
|
|
69
|
+
for (const id of subIds) {
|
|
70
|
+
const sub = this.subscriptions.get(id);
|
|
71
|
+
if (sub) {
|
|
72
|
+
sub.callback(data);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
clear() {
|
|
77
|
+
this.subscriptions.clear();
|
|
78
|
+
this.eventSubscriptions.clear();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
class ObsSubscriptionManager {
|
|
82
|
+
subscriptions = new Map();
|
|
83
|
+
sendToClient;
|
|
84
|
+
constructor(sendToClient) {
|
|
85
|
+
this.sendToClient = sendToClient;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a new observability subscription
|
|
89
|
+
*/
|
|
90
|
+
subscribe(filter) {
|
|
91
|
+
const subscriptionId = `obs_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
92
|
+
this.subscriptions.set(subscriptionId, { id: subscriptionId, filter });
|
|
93
|
+
return { subscriptionId, filter };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Remove a subscription
|
|
97
|
+
*/
|
|
98
|
+
unsubscribe(subscriptionId) {
|
|
99
|
+
const sub = this.subscriptions.get(subscriptionId);
|
|
100
|
+
if (!sub)
|
|
101
|
+
return false;
|
|
102
|
+
// Close broadcaster WebSocket if exists
|
|
103
|
+
if (sub.broadcasterWs) {
|
|
104
|
+
try {
|
|
105
|
+
sub.broadcasterWs.close();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Ignore close errors
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
this.subscriptions.delete(subscriptionId);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Update filter for an existing subscription
|
|
116
|
+
*/
|
|
117
|
+
updateFilter(subscriptionId, newFilter) {
|
|
118
|
+
const sub = this.subscriptions.get(subscriptionId);
|
|
119
|
+
if (!sub)
|
|
120
|
+
return false;
|
|
121
|
+
sub.filter = newFilter;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a subscription by ID
|
|
126
|
+
*/
|
|
127
|
+
get(subscriptionId) {
|
|
128
|
+
return this.subscriptions.get(subscriptionId);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if a subscription exists
|
|
132
|
+
*/
|
|
133
|
+
has(subscriptionId) {
|
|
134
|
+
return this.subscriptions.has(subscriptionId);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Broadcast events to all subscriptions based on their filters
|
|
138
|
+
*/
|
|
139
|
+
broadcastEvents(events) {
|
|
140
|
+
for (const [_, sub] of this.subscriptions) {
|
|
141
|
+
const matchingEvents = events.filter(event => matchesFilter(event, sub.filter));
|
|
142
|
+
if (matchingEvents.length > 0) {
|
|
143
|
+
this.sendToClient({
|
|
144
|
+
type: 'events',
|
|
145
|
+
data: matchingEvents,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Clean up all subscriptions
|
|
152
|
+
*/
|
|
153
|
+
clear() {
|
|
154
|
+
for (const [_, sub] of this.subscriptions) {
|
|
155
|
+
if (sub.broadcasterWs) {
|
|
156
|
+
try {
|
|
157
|
+
sub.broadcasterWs.close();
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Ignore close errors
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
this.subscriptions.clear();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get all subscription IDs
|
|
168
|
+
*/
|
|
169
|
+
getAllIds() {
|
|
170
|
+
return Array.from(this.subscriptions.keys());
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// User object with methods for pipelining
|
|
174
|
+
class UserObject {
|
|
175
|
+
id;
|
|
176
|
+
name;
|
|
177
|
+
email;
|
|
178
|
+
constructor(id, name, email) {
|
|
179
|
+
this.id = id;
|
|
180
|
+
this.name = name;
|
|
181
|
+
this.email = email;
|
|
182
|
+
}
|
|
183
|
+
getPosts() {
|
|
184
|
+
return [
|
|
185
|
+
{ id: `${this.id}-post-1`, title: 'First Post', authorId: this.id },
|
|
186
|
+
{ id: `${this.id}-post-2`, title: 'Second Post', authorId: this.id },
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
getProfile() {
|
|
190
|
+
return { id: this.id, name: this.name, email: this.email, bio: `Bio for ${this.name}` };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Org object for deep pipelining
|
|
194
|
+
class OrgObject {
|
|
195
|
+
id;
|
|
196
|
+
constructor(id) {
|
|
197
|
+
this.id = id;
|
|
198
|
+
}
|
|
199
|
+
getTeam(teamId) {
|
|
200
|
+
return new TeamObject(`${this.id}-${teamId}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
class TeamObject {
|
|
204
|
+
id;
|
|
205
|
+
constructor(id) {
|
|
206
|
+
this.id = id;
|
|
207
|
+
}
|
|
208
|
+
getMembers() {
|
|
209
|
+
return [new UserObject(`${this.id}-member-1`, 'Member 1', 'member1@example.com.ai'), new UserObject(`${this.id}-member-2`, 'Member 2', 'member2@example.com.ai')];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Session object for createSession
|
|
213
|
+
class SessionObject {
|
|
214
|
+
id;
|
|
215
|
+
createdAt;
|
|
216
|
+
constructor() {
|
|
217
|
+
this.id = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
218
|
+
this.createdAt = Date.now();
|
|
219
|
+
}
|
|
220
|
+
getData() {
|
|
221
|
+
return { sessionId: this.id, createdAt: this.createdAt };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Create root object factory (with context for subscriptions)
|
|
225
|
+
function createRootObject(ctx) {
|
|
226
|
+
return {
|
|
227
|
+
// Basic methods
|
|
228
|
+
echo: (value) => value,
|
|
229
|
+
add: (a, b) => a + b,
|
|
230
|
+
multiply: (a, b) => a * b,
|
|
231
|
+
ping: () => ({ pong: true, timestamp: Date.now() }),
|
|
232
|
+
// Data methods
|
|
233
|
+
get: (id) => ({ id: id || 'default', data: `Data for ${id || 'default'}` }),
|
|
234
|
+
getUser: (id) => new UserObject(id || 'default', `User ${id}`, `${id}@example.com.ai`),
|
|
235
|
+
getPosts: () => [
|
|
236
|
+
{ id: '1', title: 'First Post', active: true },
|
|
237
|
+
{ id: '2', title: 'Second Post', active: false },
|
|
238
|
+
{ id: '3', title: 'Third Post', active: true },
|
|
239
|
+
],
|
|
240
|
+
getData: () => ({ foo: 'bar', count: 42 }),
|
|
241
|
+
getItems: () => [
|
|
242
|
+
{ id: '1', name: 'Item 1', active: true },
|
|
243
|
+
{ id: '2', name: 'Item 2', active: false },
|
|
244
|
+
{ id: '3', name: 'Item 3', active: true },
|
|
245
|
+
{ id: '4', name: 'Item 4', active: false },
|
|
246
|
+
],
|
|
247
|
+
getOrg: (id) => new OrgObject(id),
|
|
248
|
+
// Session management
|
|
249
|
+
createSession: () => new SessionObject(),
|
|
250
|
+
// Connection info - returns connection acknowledgment data
|
|
251
|
+
getConnectionInfo: () => ({ type: 'connected', sessionId: ctx.sessionId }),
|
|
252
|
+
// Notification/event methods
|
|
253
|
+
sendNotification: (user, message) => {
|
|
254
|
+
return { sent: true, userId: user.id, message };
|
|
255
|
+
},
|
|
256
|
+
// Subscription methods
|
|
257
|
+
subscribe: (params) => {
|
|
258
|
+
const subscriptionId = ctx.subscriptions.subscribe(params.event, (data) => {
|
|
259
|
+
ctx.sendNotification(params.event, data);
|
|
260
|
+
});
|
|
261
|
+
return { subscriptionId };
|
|
262
|
+
},
|
|
263
|
+
unsubscribe: (params) => {
|
|
264
|
+
const success = ctx.subscriptions.unsubscribe(params.subscriptionId);
|
|
265
|
+
return { success };
|
|
266
|
+
},
|
|
267
|
+
// Methods that trigger events
|
|
268
|
+
// Note: Events are emitted async to ensure response is sent first
|
|
269
|
+
updateUser: (params) => {
|
|
270
|
+
const result = { id: params.id, name: params.name, updated: true };
|
|
271
|
+
// Emit event for subscribers AFTER response is sent
|
|
272
|
+
setTimeout(() => {
|
|
273
|
+
ctx.subscriptions.emit('userUpdated', { userId: params.id, changes: { name: params.name } });
|
|
274
|
+
}, 0);
|
|
275
|
+
return result;
|
|
276
|
+
},
|
|
277
|
+
triggerEvent: (params) => {
|
|
278
|
+
// Emit event AFTER response is sent
|
|
279
|
+
setTimeout(() => {
|
|
280
|
+
ctx.subscriptions.emit(params.event, params.data);
|
|
281
|
+
}, 0);
|
|
282
|
+
return { triggered: true, event: params.event };
|
|
283
|
+
},
|
|
284
|
+
// Error methods for testing
|
|
285
|
+
throwError: () => {
|
|
286
|
+
throw { code: 'TEST_ERROR', message: 'Test error thrown' };
|
|
287
|
+
},
|
|
288
|
+
throwInternalError: () => {
|
|
289
|
+
throw new Error('Internal server error');
|
|
290
|
+
},
|
|
291
|
+
throwDetailedError: (params) => {
|
|
292
|
+
const error = {
|
|
293
|
+
code: 'DETAILED_ERROR',
|
|
294
|
+
message: 'Detailed error with data',
|
|
295
|
+
};
|
|
296
|
+
if (params?.includeStack) {
|
|
297
|
+
error.data = { stack: new Error().stack, timestamp: Date.now() };
|
|
298
|
+
}
|
|
299
|
+
throw error;
|
|
300
|
+
},
|
|
301
|
+
// Slow operation for timeout testing
|
|
302
|
+
slowOperation: async (params) => {
|
|
303
|
+
await new Promise((resolve) => setTimeout(resolve, params?.duration || 1000));
|
|
304
|
+
return { completed: true };
|
|
305
|
+
},
|
|
306
|
+
operationWithTimeout: async (params) => {
|
|
307
|
+
// Simulate operation that respects timeout
|
|
308
|
+
const duration = Math.min(params?.timeout || 1000, 500);
|
|
309
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
310
|
+
return { operation: params?.operation, completed: true };
|
|
311
|
+
},
|
|
312
|
+
// Binary data methods
|
|
313
|
+
uploadBinary: (params) => {
|
|
314
|
+
const size = params?.encoding === 'base64' ? Math.floor((params?.data?.length || 0) * 0.75) : params?.data?.length || 0;
|
|
315
|
+
return { received: true, size };
|
|
316
|
+
},
|
|
317
|
+
downloadBinary: (_params) => {
|
|
318
|
+
const content = 'binary file content here';
|
|
319
|
+
return { data: btoa(content), encoding: 'base64' };
|
|
320
|
+
},
|
|
321
|
+
// Log method (for notifications - no response)
|
|
322
|
+
log: (_params) => {
|
|
323
|
+
// Log doesn't return anything
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function resolveNestedTarget(target, ctx) {
|
|
328
|
+
switch (target.type) {
|
|
329
|
+
case 'root':
|
|
330
|
+
return ctx.rootObject;
|
|
331
|
+
case 'promise': {
|
|
332
|
+
if (ctx.promiseStore.isDisposed(target.promiseId)) {
|
|
333
|
+
throw { code: 'DISPOSED_REFERENCE', message: `Promise ${target.promiseId} has been disposed` };
|
|
334
|
+
}
|
|
335
|
+
const value = ctx.promiseStore.get(target.promiseId);
|
|
336
|
+
if (value === undefined && !ctx.promiseStore.has(target.promiseId)) {
|
|
337
|
+
throw { code: 'INVALID_PROMISE', message: `Promise ${target.promiseId} not found` };
|
|
338
|
+
}
|
|
339
|
+
// Check if the value is an error marker (propagate errors through pipeline)
|
|
340
|
+
if (value && typeof value === 'object' && '__error__' in value) {
|
|
341
|
+
throw value.__error__;
|
|
342
|
+
}
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
default:
|
|
346
|
+
throw { code: 'INVALID_TARGET', message: 'Unknown nested target type' };
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function resolveTarget(target, ctx) {
|
|
350
|
+
switch (target.type) {
|
|
351
|
+
case 'root':
|
|
352
|
+
return ctx.rootObject;
|
|
353
|
+
case 'promise': {
|
|
354
|
+
if (ctx.promiseStore.isDisposed(target.promiseId)) {
|
|
355
|
+
throw { code: 'DISPOSED_REFERENCE', message: `Promise ${target.promiseId} has been disposed` };
|
|
356
|
+
}
|
|
357
|
+
const value = ctx.promiseStore.get(target.promiseId);
|
|
358
|
+
if (value === undefined && !ctx.promiseStore.has(target.promiseId)) {
|
|
359
|
+
throw { code: 'INVALID_PROMISE', message: `Promise ${target.promiseId} not found` };
|
|
360
|
+
}
|
|
361
|
+
// Check if the value is an error marker (propagate errors through pipeline)
|
|
362
|
+
if (value && typeof value === 'object' && '__error__' in value) {
|
|
363
|
+
throw value.__error__;
|
|
364
|
+
}
|
|
365
|
+
return value;
|
|
366
|
+
}
|
|
367
|
+
case 'property': {
|
|
368
|
+
const base = resolveNestedTarget(target.base, ctx);
|
|
369
|
+
if (base === null || typeof base !== 'object') {
|
|
370
|
+
throw { code: 'INVALID_TARGET', message: 'Cannot access property of non-object' };
|
|
371
|
+
}
|
|
372
|
+
// Handle array index access
|
|
373
|
+
if (Array.isArray(base) && /^\d+$/.test(target.property)) {
|
|
374
|
+
return base[parseInt(target.property, 10)];
|
|
375
|
+
}
|
|
376
|
+
return base[target.property];
|
|
377
|
+
}
|
|
378
|
+
default:
|
|
379
|
+
throw { code: 'INVALID_TARGET', message: 'Unknown target type' };
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function resolveArg(arg, ctx) {
|
|
383
|
+
switch (arg.type) {
|
|
384
|
+
case 'value':
|
|
385
|
+
return arg.value;
|
|
386
|
+
case 'promise': {
|
|
387
|
+
if (ctx.promiseStore.isDisposed(arg.promiseId)) {
|
|
388
|
+
throw { code: 'DISPOSED_REFERENCE', message: `Promise ${arg.promiseId} has been disposed` };
|
|
389
|
+
}
|
|
390
|
+
return ctx.promiseStore.get(arg.promiseId);
|
|
391
|
+
}
|
|
392
|
+
case 'callback':
|
|
393
|
+
// Callbacks are not yet implemented
|
|
394
|
+
throw { code: 'NOT_IMPLEMENTED', message: 'Callbacks not yet supported' };
|
|
395
|
+
default:
|
|
396
|
+
throw { code: 'INVALID_ARG', message: 'Unknown argument type' };
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async function executeCall(call, ctx) {
|
|
400
|
+
try {
|
|
401
|
+
const target = resolveTarget(call.target, ctx);
|
|
402
|
+
const args = call.args.map((arg) => resolveArg(arg, ctx));
|
|
403
|
+
let result;
|
|
404
|
+
// Handle magic methods
|
|
405
|
+
if (call.method === '__get__') {
|
|
406
|
+
// Property getter - target is already the value from property access
|
|
407
|
+
result = target;
|
|
408
|
+
}
|
|
409
|
+
else if (call.method === '__map__' && Array.isArray(target)) {
|
|
410
|
+
// Magic map operation
|
|
411
|
+
const mapSpec = args[0];
|
|
412
|
+
if (mapSpec?.property) {
|
|
413
|
+
result = target.map((item) => item[mapSpec.property]);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
result = target;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else if (call.method === '__filter__' && Array.isArray(target)) {
|
|
420
|
+
// Magic filter operation
|
|
421
|
+
const filterSpec = args[0];
|
|
422
|
+
if (filterSpec?.property) {
|
|
423
|
+
result = target.filter((item) => item[filterSpec.property] === filterSpec.equals);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
result = target;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else if (typeof target === 'function') {
|
|
430
|
+
result = await target(...args);
|
|
431
|
+
}
|
|
432
|
+
else if (target && typeof target === 'object' && call.method in target) {
|
|
433
|
+
const method = target[call.method];
|
|
434
|
+
if (typeof method === 'function') {
|
|
435
|
+
result = await method.apply(target, args);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
result = method;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
else if (target && typeof target === 'object') {
|
|
442
|
+
// Property access
|
|
443
|
+
result = target[call.method];
|
|
444
|
+
if (result === undefined && !(call.method in target)) {
|
|
445
|
+
throw { code: 'METHOD_NOT_FOUND', message: `Method ${call.method} not found` };
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
throw { code: 'METHOD_NOT_FOUND', message: `Method ${call.method} not found` };
|
|
450
|
+
}
|
|
451
|
+
// Store result for pipelining
|
|
452
|
+
ctx.promiseStore.set(call.promiseId, result);
|
|
453
|
+
return {
|
|
454
|
+
promiseId: call.promiseId,
|
|
455
|
+
type: 'value',
|
|
456
|
+
value: result,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
const rpcError = error && typeof error === 'object' && 'code' in error ? error : { code: 'EXECUTION_ERROR', message: String(error) };
|
|
461
|
+
// Store error so dependent calls also fail
|
|
462
|
+
ctx.promiseStore.set(call.promiseId, { __error__: rpcError });
|
|
463
|
+
return {
|
|
464
|
+
promiseId: call.promiseId,
|
|
465
|
+
type: 'error',
|
|
466
|
+
error: rpcError,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
async function executeRequest(request, ctx) {
|
|
471
|
+
switch (request.type) {
|
|
472
|
+
case 'call':
|
|
473
|
+
case 'batch': {
|
|
474
|
+
if (!request.calls || request.calls.length === 0) {
|
|
475
|
+
return {
|
|
476
|
+
id: request.id,
|
|
477
|
+
type: 'error',
|
|
478
|
+
error: { code: 'INVALID_REQUEST', message: 'No calls provided' },
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
const results = [];
|
|
482
|
+
for (const call of request.calls) {
|
|
483
|
+
const result = await executeCall(call, ctx);
|
|
484
|
+
results.push(result);
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
id: request.id,
|
|
488
|
+
type: 'batch',
|
|
489
|
+
results,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
case 'resolve': {
|
|
493
|
+
if (!request.resolve?.promiseId) {
|
|
494
|
+
return {
|
|
495
|
+
id: request.id,
|
|
496
|
+
type: 'error',
|
|
497
|
+
error: { code: 'INVALID_REQUEST', message: 'No promiseId provided' },
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const promiseId = request.resolve.promiseId;
|
|
501
|
+
if (ctx.promiseStore.isDisposed(promiseId)) {
|
|
502
|
+
return {
|
|
503
|
+
id: request.id,
|
|
504
|
+
type: 'error',
|
|
505
|
+
error: { code: 'DISPOSED_REFERENCE', message: `Promise ${promiseId} has been disposed` },
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const value = ctx.promiseStore.get(promiseId);
|
|
509
|
+
return {
|
|
510
|
+
id: request.id,
|
|
511
|
+
type: 'result',
|
|
512
|
+
results: [
|
|
513
|
+
{
|
|
514
|
+
promiseId,
|
|
515
|
+
type: 'value',
|
|
516
|
+
value,
|
|
517
|
+
},
|
|
518
|
+
],
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
case 'dispose': {
|
|
522
|
+
if (!request.dispose?.promiseIds) {
|
|
523
|
+
return {
|
|
524
|
+
id: request.id,
|
|
525
|
+
type: 'error',
|
|
526
|
+
error: { code: 'INVALID_REQUEST', message: 'No promiseIds provided' },
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
for (const promiseId of request.dispose.promiseIds) {
|
|
530
|
+
ctx.promiseStore.dispose(promiseId);
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
id: request.id,
|
|
534
|
+
type: 'result',
|
|
535
|
+
results: [],
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
default:
|
|
539
|
+
return {
|
|
540
|
+
id: request.id,
|
|
541
|
+
type: 'error',
|
|
542
|
+
error: { code: 'INVALID_REQUEST', message: 'Unknown request type' },
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
// ============================================================================
|
|
547
|
+
// JSON-RPC 2.0 Handler
|
|
548
|
+
// ============================================================================
|
|
549
|
+
function isJSONRPCRequest(data) {
|
|
550
|
+
return data !== null && typeof data === 'object' && 'jsonrpc' in data && data.jsonrpc === '2.0';
|
|
551
|
+
}
|
|
552
|
+
function isJSONRPCBatch(data) {
|
|
553
|
+
return Array.isArray(data) && data.length > 0 && data.every((item) => isJSONRPCRequest(item));
|
|
554
|
+
}
|
|
555
|
+
function isCapnwebRequest(data) {
|
|
556
|
+
return data !== null && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
|
|
557
|
+
}
|
|
558
|
+
async function handleJSONRPCRequest(request, ctx) {
|
|
559
|
+
const { method, params, id } = request;
|
|
560
|
+
// Notifications (no id) don't get a response
|
|
561
|
+
const isNotification = id === undefined;
|
|
562
|
+
try {
|
|
563
|
+
const rootObject = ctx.rootObject;
|
|
564
|
+
const methodFn = rootObject[method];
|
|
565
|
+
if (methodFn === undefined) {
|
|
566
|
+
if (isNotification)
|
|
567
|
+
return null;
|
|
568
|
+
return {
|
|
569
|
+
jsonrpc: '2.0',
|
|
570
|
+
error: { ...JSON_RPC_ERRORS.METHOD_NOT_FOUND, message: `Method '${method}' not found` },
|
|
571
|
+
id: id ?? null,
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
// Validate params for getUser - requires specific param structure
|
|
575
|
+
if (method === 'getUser' && params && typeof params === 'object' && 'invalidParam' in params) {
|
|
576
|
+
if (isNotification)
|
|
577
|
+
return null;
|
|
578
|
+
return {
|
|
579
|
+
jsonrpc: '2.0',
|
|
580
|
+
error: JSON_RPC_ERRORS.INVALID_PARAMS,
|
|
581
|
+
id: id ?? null,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
let result;
|
|
585
|
+
if (typeof methodFn === 'function') {
|
|
586
|
+
// Call the method with params
|
|
587
|
+
if (params === undefined) {
|
|
588
|
+
result = await methodFn();
|
|
589
|
+
}
|
|
590
|
+
else if (Array.isArray(params)) {
|
|
591
|
+
result = await methodFn(...params);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
result = await methodFn(params);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
result = methodFn;
|
|
599
|
+
}
|
|
600
|
+
if (isNotification)
|
|
601
|
+
return null;
|
|
602
|
+
return {
|
|
603
|
+
jsonrpc: '2.0',
|
|
604
|
+
result,
|
|
605
|
+
id: id ?? null,
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
catch (error) {
|
|
609
|
+
if (isNotification)
|
|
610
|
+
return null;
|
|
611
|
+
// Check if it's a detailed error with data
|
|
612
|
+
if (error && typeof error === 'object' && 'data' in error) {
|
|
613
|
+
return {
|
|
614
|
+
jsonrpc: '2.0',
|
|
615
|
+
error: {
|
|
616
|
+
code: JSON_RPC_ERRORS.INTERNAL_ERROR.code,
|
|
617
|
+
message: error.message || 'Internal error',
|
|
618
|
+
data: error.data,
|
|
619
|
+
},
|
|
620
|
+
id: id ?? null,
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
return {
|
|
624
|
+
jsonrpc: '2.0',
|
|
625
|
+
error: JSON_RPC_ERRORS.INTERNAL_ERROR,
|
|
626
|
+
id: id ?? null,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
// ============================================================================
|
|
631
|
+
// HTTP Handler
|
|
632
|
+
// ============================================================================
|
|
633
|
+
export const rpcRoutes = new Hono();
|
|
634
|
+
// HTTP POST handler for batch mode
|
|
635
|
+
rpcRoutes.post('/', async (c) => {
|
|
636
|
+
const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
637
|
+
const promiseStore = new PromiseStore();
|
|
638
|
+
const subscriptions = new SubscriptionManager();
|
|
639
|
+
const ctx = {
|
|
640
|
+
promiseStore,
|
|
641
|
+
subscriptions,
|
|
642
|
+
rootObject: {},
|
|
643
|
+
sendNotification: () => { },
|
|
644
|
+
sessionId,
|
|
645
|
+
};
|
|
646
|
+
ctx.rootObject = createRootObject(ctx);
|
|
647
|
+
let request;
|
|
648
|
+
try {
|
|
649
|
+
request = await c.req.json();
|
|
650
|
+
}
|
|
651
|
+
catch {
|
|
652
|
+
return c.json({
|
|
653
|
+
id: '',
|
|
654
|
+
type: 'error',
|
|
655
|
+
error: { code: 'PARSE_ERROR', message: 'Invalid JSON' },
|
|
656
|
+
}, 400);
|
|
657
|
+
}
|
|
658
|
+
// Check if this is a JSON-RPC 2.0 request for obs methods (which require WebSocket)
|
|
659
|
+
if (request && typeof request === 'object' && 'jsonrpc' in request && request.jsonrpc === '2.0') {
|
|
660
|
+
const jsonRpcRequest = request;
|
|
661
|
+
if (jsonRpcRequest.method?.startsWith('obs.')) {
|
|
662
|
+
return c.json({
|
|
663
|
+
jsonrpc: '2.0',
|
|
664
|
+
error: {
|
|
665
|
+
code: -32600,
|
|
666
|
+
message: 'obs.subscribe requires WebSocket connection. Upgrade to WebSocket protocol.',
|
|
667
|
+
},
|
|
668
|
+
id: jsonRpcRequest.id ?? null,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
const rpcRequest = request;
|
|
673
|
+
if (!rpcRequest.id) {
|
|
674
|
+
return c.json({
|
|
675
|
+
id: '',
|
|
676
|
+
type: 'error',
|
|
677
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing request id' },
|
|
678
|
+
}, 400);
|
|
679
|
+
}
|
|
680
|
+
const response = await executeRequest(rpcRequest, ctx);
|
|
681
|
+
return c.json(response);
|
|
682
|
+
});
|
|
683
|
+
// ============================================================================
|
|
684
|
+
// Observability RPC Method Handlers
|
|
685
|
+
// ============================================================================
|
|
686
|
+
/**
|
|
687
|
+
* Handle obs.subscribe method - creates a new observability subscription
|
|
688
|
+
*/
|
|
689
|
+
async function handleObsSubscribe(params, obsManager, env, sendToClient) {
|
|
690
|
+
const filter = params?.filter || {};
|
|
691
|
+
// Validate filter
|
|
692
|
+
const validation = validateObsFilter(filter);
|
|
693
|
+
if (!validation.success) {
|
|
694
|
+
return {
|
|
695
|
+
jsonrpc: '2.0',
|
|
696
|
+
error: {
|
|
697
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
698
|
+
message: `Invalid filter: ${validation.errors.map(e => e.message).join(', ')}`,
|
|
699
|
+
data: validation.errors,
|
|
700
|
+
},
|
|
701
|
+
id: null,
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
// Create subscription in manager
|
|
705
|
+
const result = obsManager.subscribe(filter);
|
|
706
|
+
// Connect to ObservabilityBroadcaster DO if available
|
|
707
|
+
if (env.OBS_BROADCASTER) {
|
|
708
|
+
try {
|
|
709
|
+
const broadcasterStub = env.OBS_BROADCASTER.get(env.OBS_BROADCASTER.idFromName('global'));
|
|
710
|
+
// Build URL with filter params
|
|
711
|
+
const url = new URL('http://broadcaster/ws');
|
|
712
|
+
if (filter.level)
|
|
713
|
+
url.searchParams.set('level', filter.level);
|
|
714
|
+
if (filter.script)
|
|
715
|
+
url.searchParams.set('script', filter.script);
|
|
716
|
+
if (filter.type)
|
|
717
|
+
url.searchParams.set('type', filter.type);
|
|
718
|
+
if (filter.requestId)
|
|
719
|
+
url.searchParams.set('requestId', filter.requestId);
|
|
720
|
+
if (filter.doName)
|
|
721
|
+
url.searchParams.set('doName', filter.doName);
|
|
722
|
+
// Fetch with WebSocket upgrade to connect to broadcaster
|
|
723
|
+
const broadcasterResponse = await broadcasterStub.fetch(url.toString(), {
|
|
724
|
+
headers: { Upgrade: 'websocket' },
|
|
725
|
+
});
|
|
726
|
+
if (broadcasterResponse.webSocket) {
|
|
727
|
+
const broadcasterWs = broadcasterResponse.webSocket;
|
|
728
|
+
broadcasterWs.accept();
|
|
729
|
+
// Forward events from broadcaster to client
|
|
730
|
+
broadcasterWs.addEventListener('message', (event) => {
|
|
731
|
+
try {
|
|
732
|
+
const message = JSON.parse(event.data);
|
|
733
|
+
// Forward events messages to client
|
|
734
|
+
if (message.type === 'events') {
|
|
735
|
+
// Apply filter before forwarding (in case broadcaster filter changes)
|
|
736
|
+
const sub = obsManager.get(result.subscriptionId);
|
|
737
|
+
if (sub) {
|
|
738
|
+
const matchingEvents = message.data.filter((e) => matchesFilter(e, sub.filter));
|
|
739
|
+
if (matchingEvents.length > 0) {
|
|
740
|
+
sendToClient({
|
|
741
|
+
type: 'events',
|
|
742
|
+
data: matchingEvents,
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
catch {
|
|
749
|
+
// Ignore parse errors
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
// Store broadcaster WebSocket in subscription
|
|
753
|
+
const sub = obsManager.get(result.subscriptionId);
|
|
754
|
+
if (sub) {
|
|
755
|
+
sub.broadcasterWs = broadcasterWs;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
catch {
|
|
760
|
+
// Failed to connect to broadcaster - subscription still works but no events
|
|
761
|
+
// Log this in production but don't fail the subscription
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
return {
|
|
765
|
+
jsonrpc: '2.0',
|
|
766
|
+
result,
|
|
767
|
+
id: null,
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Handle obs.unsubscribe method - removes a subscription
|
|
772
|
+
*/
|
|
773
|
+
function handleObsUnsubscribe(params, obsManager) {
|
|
774
|
+
if (!params?.subscriptionId) {
|
|
775
|
+
return {
|
|
776
|
+
jsonrpc: '2.0',
|
|
777
|
+
error: {
|
|
778
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
779
|
+
message: 'Missing subscriptionId parameter',
|
|
780
|
+
},
|
|
781
|
+
id: null,
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
const success = obsManager.unsubscribe(params.subscriptionId);
|
|
785
|
+
if (!success) {
|
|
786
|
+
return {
|
|
787
|
+
jsonrpc: '2.0',
|
|
788
|
+
error: {
|
|
789
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
790
|
+
message: `Subscription ${params.subscriptionId} not found`,
|
|
791
|
+
},
|
|
792
|
+
id: null,
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
return {
|
|
796
|
+
jsonrpc: '2.0',
|
|
797
|
+
result: { success: true },
|
|
798
|
+
id: null,
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Handle obs.updateFilter method - updates filter for existing subscription
|
|
803
|
+
*/
|
|
804
|
+
function handleObsUpdateFilter(params, obsManager) {
|
|
805
|
+
if (!params?.subscriptionId) {
|
|
806
|
+
return {
|
|
807
|
+
jsonrpc: '2.0',
|
|
808
|
+
error: {
|
|
809
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
810
|
+
message: 'Missing subscriptionId parameter',
|
|
811
|
+
},
|
|
812
|
+
id: null,
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
if (!params.filter) {
|
|
816
|
+
return {
|
|
817
|
+
jsonrpc: '2.0',
|
|
818
|
+
error: {
|
|
819
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
820
|
+
message: 'Missing filter parameter',
|
|
821
|
+
},
|
|
822
|
+
id: null,
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
// Validate new filter
|
|
826
|
+
const validation = validateObsFilter(params.filter);
|
|
827
|
+
if (!validation.success) {
|
|
828
|
+
return {
|
|
829
|
+
jsonrpc: '2.0',
|
|
830
|
+
error: {
|
|
831
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
832
|
+
message: `Invalid filter: ${validation.errors.map(e => e.message).join(', ')}`,
|
|
833
|
+
data: validation.errors,
|
|
834
|
+
},
|
|
835
|
+
id: null,
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
const success = obsManager.updateFilter(params.subscriptionId, params.filter);
|
|
839
|
+
if (!success) {
|
|
840
|
+
return {
|
|
841
|
+
jsonrpc: '2.0',
|
|
842
|
+
error: {
|
|
843
|
+
code: JSON_RPC_ERRORS.INVALID_PARAMS.code,
|
|
844
|
+
message: `Subscription ${params.subscriptionId} not found`,
|
|
845
|
+
},
|
|
846
|
+
id: null,
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
return {
|
|
850
|
+
jsonrpc: '2.0',
|
|
851
|
+
result: { success: true, filter: params.filter },
|
|
852
|
+
id: null,
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
// ============================================================================
|
|
856
|
+
// WebSocket Handler
|
|
857
|
+
// ============================================================================
|
|
858
|
+
// Helper to create WebSocket handler with env access
|
|
859
|
+
function createWebSocketHandler(_path) {
|
|
860
|
+
return (c) => {
|
|
861
|
+
const upgradeHeader = c.req.header('upgrade');
|
|
862
|
+
// Check Connection header to determine if this is a full WebSocket upgrade
|
|
863
|
+
const connectionHeader = c.req.header('connection')?.toLowerCase() || '';
|
|
864
|
+
const hasConnectionUpgrade = connectionHeader.includes('upgrade');
|
|
865
|
+
// Only treat as WebSocket if BOTH Upgrade AND Connection headers are correct
|
|
866
|
+
// This prevents the Workers runtime from intercepting incomplete upgrades
|
|
867
|
+
if (upgradeHeader?.toLowerCase() !== 'websocket' || !hasConnectionUpgrade) {
|
|
868
|
+
// Return RPC info for GET requests without proper WebSocket upgrade headers
|
|
869
|
+
return new Response(JSON.stringify({
|
|
870
|
+
message: 'RPC endpoint - use POST for HTTP batch mode or WebSocket for streaming',
|
|
871
|
+
methods: Object.keys(createRootObject({})),
|
|
872
|
+
hint: 'Connect with WebSocket protocol for streaming RPC',
|
|
873
|
+
}), { status: 200, headers: { 'Content-Type': 'application/json' } });
|
|
874
|
+
}
|
|
875
|
+
// Check for required WebSocket headers - if missing, return 426 Upgrade Required
|
|
876
|
+
const secWebSocketKey = c.req.header('sec-websocket-key');
|
|
877
|
+
const secWebSocketVersion = c.req.header('sec-websocket-version');
|
|
878
|
+
if (!secWebSocketKey || !secWebSocketVersion) {
|
|
879
|
+
return new Response(JSON.stringify({
|
|
880
|
+
message: 'Incomplete WebSocket upgrade request',
|
|
881
|
+
hint: 'Missing required Sec-WebSocket-Key or Sec-WebSocket-Version headers',
|
|
882
|
+
}), {
|
|
883
|
+
status: 426,
|
|
884
|
+
headers: {
|
|
885
|
+
'Content-Type': 'application/json',
|
|
886
|
+
Upgrade: 'websocket',
|
|
887
|
+
Connection: 'Upgrade',
|
|
888
|
+
},
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
// Get environment bindings
|
|
892
|
+
const env = c.env;
|
|
893
|
+
// WebSocket upgrade
|
|
894
|
+
const pair = new WebSocketPair();
|
|
895
|
+
const [client, server] = Object.values(pair);
|
|
896
|
+
const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
897
|
+
const promiseStore = new PromiseStore();
|
|
898
|
+
const subscriptions = new SubscriptionManager();
|
|
899
|
+
// Helper to send messages to client
|
|
900
|
+
const sendToClient = (message) => {
|
|
901
|
+
try {
|
|
902
|
+
server.send(JSON.stringify(message));
|
|
903
|
+
}
|
|
904
|
+
catch {
|
|
905
|
+
// Ignore send errors on closed socket
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
// Create obs subscription manager
|
|
909
|
+
const obsManager = new ObsSubscriptionManager(sendToClient);
|
|
910
|
+
// Create context with send notification capability
|
|
911
|
+
const sendNotification = (method, params) => {
|
|
912
|
+
sendToClient({
|
|
913
|
+
jsonrpc: '2.0',
|
|
914
|
+
method,
|
|
915
|
+
params,
|
|
916
|
+
});
|
|
917
|
+
};
|
|
918
|
+
const ctx = {
|
|
919
|
+
promiseStore,
|
|
920
|
+
subscriptions,
|
|
921
|
+
rootObject: {},
|
|
922
|
+
sendNotification,
|
|
923
|
+
sessionId,
|
|
924
|
+
};
|
|
925
|
+
ctx.rootObject = createRootObject(ctx);
|
|
926
|
+
server.accept();
|
|
927
|
+
// Track if we've received any message or sent the ack
|
|
928
|
+
let receivedMessage = false;
|
|
929
|
+
let sentAck = false;
|
|
930
|
+
// Send connection acknowledgment after a short delay if no message received
|
|
931
|
+
// This allows tests that immediately send a request to get their response first
|
|
932
|
+
// while tests that wait for ack will receive it
|
|
933
|
+
const ackTimeout = setTimeout(() => {
|
|
934
|
+
if (!receivedMessage && !sentAck) {
|
|
935
|
+
sentAck = true;
|
|
936
|
+
server.send(JSON.stringify({
|
|
937
|
+
type: 'connected',
|
|
938
|
+
sessionId,
|
|
939
|
+
}));
|
|
940
|
+
}
|
|
941
|
+
}, 500); // 500ms delay - give tests time to send first message
|
|
942
|
+
server.addEventListener('message', async (event) => {
|
|
943
|
+
receivedMessage = true;
|
|
944
|
+
// Cancel pending ack if we receive a message
|
|
945
|
+
clearTimeout(ackTimeout);
|
|
946
|
+
const rawData = event.data;
|
|
947
|
+
// Handle binary data
|
|
948
|
+
if (rawData instanceof ArrayBuffer) {
|
|
949
|
+
server.send(JSON.stringify({
|
|
950
|
+
type: 'binary_received',
|
|
951
|
+
size: rawData.byteLength,
|
|
952
|
+
}));
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
// Check message size (limit to 1MB for safety)
|
|
956
|
+
const MAX_MESSAGE_SIZE = 1024 * 1024; // 1MB
|
|
957
|
+
const messageStr = rawData;
|
|
958
|
+
if (messageStr.length > MAX_MESSAGE_SIZE) {
|
|
959
|
+
server.send(JSON.stringify({
|
|
960
|
+
jsonrpc: '2.0',
|
|
961
|
+
error: { code: -32600, message: 'Message too large' },
|
|
962
|
+
id: null,
|
|
963
|
+
}));
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
// Parse the message
|
|
967
|
+
let data;
|
|
968
|
+
try {
|
|
969
|
+
data = JSON.parse(messageStr);
|
|
970
|
+
}
|
|
971
|
+
catch {
|
|
972
|
+
// Parse error
|
|
973
|
+
server.send(JSON.stringify({
|
|
974
|
+
jsonrpc: '2.0',
|
|
975
|
+
error: { code: -32700, message: 'Parse error' },
|
|
976
|
+
id: null,
|
|
977
|
+
}));
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
// Check for empty batch (array with length 0)
|
|
981
|
+
if (Array.isArray(data) && data.length === 0) {
|
|
982
|
+
server.send(JSON.stringify({
|
|
983
|
+
jsonrpc: '2.0',
|
|
984
|
+
error: { code: -32600, message: 'Invalid Request' },
|
|
985
|
+
id: null,
|
|
986
|
+
}));
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
// Handle JSON-RPC 2.0 batch
|
|
990
|
+
if (isJSONRPCBatch(data)) {
|
|
991
|
+
const responses = [];
|
|
992
|
+
for (const req of data) {
|
|
993
|
+
// Check for obs methods in batch
|
|
994
|
+
if (req.method?.startsWith('obs.')) {
|
|
995
|
+
const obsResponse = await handleObsMethod(req, obsManager, env, sendToClient);
|
|
996
|
+
if (obsResponse && req.id !== undefined) {
|
|
997
|
+
responses.push({ ...obsResponse, id: req.id });
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
else {
|
|
1001
|
+
const response = await handleJSONRPCRequest(req, ctx);
|
|
1002
|
+
if (response) {
|
|
1003
|
+
responses.push(response);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
if (responses.length > 0) {
|
|
1008
|
+
server.send(JSON.stringify(responses));
|
|
1009
|
+
}
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
// Handle single JSON-RPC 2.0 request
|
|
1013
|
+
if (isJSONRPCRequest(data)) {
|
|
1014
|
+
// Check for obs methods
|
|
1015
|
+
if (data.method?.startsWith('obs.')) {
|
|
1016
|
+
const response = await handleObsMethod(data, obsManager, env, sendToClient);
|
|
1017
|
+
if (response) {
|
|
1018
|
+
server.send(JSON.stringify({ ...response, id: data.id ?? null }));
|
|
1019
|
+
}
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
const response = await handleJSONRPCRequest(data, ctx);
|
|
1023
|
+
if (response) {
|
|
1024
|
+
server.send(JSON.stringify(response));
|
|
1025
|
+
}
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
// Handle Capnweb request
|
|
1029
|
+
if (isCapnwebRequest(data)) {
|
|
1030
|
+
const response = await executeRequest(data, ctx);
|
|
1031
|
+
server.send(JSON.stringify(response));
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
// Invalid request format
|
|
1035
|
+
server.send(JSON.stringify({
|
|
1036
|
+
jsonrpc: '2.0',
|
|
1037
|
+
error: { code: -32600, message: 'Invalid Request' },
|
|
1038
|
+
id: null,
|
|
1039
|
+
}));
|
|
1040
|
+
});
|
|
1041
|
+
server.addEventListener('close', () => {
|
|
1042
|
+
// Clean up resources
|
|
1043
|
+
promiseStore.clear();
|
|
1044
|
+
subscriptions.clear();
|
|
1045
|
+
obsManager.clear();
|
|
1046
|
+
});
|
|
1047
|
+
server.addEventListener('error', () => {
|
|
1048
|
+
server.close();
|
|
1049
|
+
});
|
|
1050
|
+
return new Response(null, {
|
|
1051
|
+
status: 101,
|
|
1052
|
+
webSocket: client,
|
|
1053
|
+
});
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Route obs.* methods to appropriate handlers
|
|
1058
|
+
*/
|
|
1059
|
+
async function handleObsMethod(request, obsManager, env, sendToClient) {
|
|
1060
|
+
const { method, params, id } = request;
|
|
1061
|
+
// Notifications (no id) don't get a response for subscribe but do for unsubscribe
|
|
1062
|
+
const isNotification = id === undefined;
|
|
1063
|
+
switch (method) {
|
|
1064
|
+
case 'obs.subscribe': {
|
|
1065
|
+
const response = await handleObsSubscribe(params, obsManager, env, sendToClient);
|
|
1066
|
+
if (isNotification)
|
|
1067
|
+
return null;
|
|
1068
|
+
return response;
|
|
1069
|
+
}
|
|
1070
|
+
case 'obs.unsubscribe': {
|
|
1071
|
+
const response = handleObsUnsubscribe(params, obsManager);
|
|
1072
|
+
if (isNotification)
|
|
1073
|
+
return null;
|
|
1074
|
+
return response;
|
|
1075
|
+
}
|
|
1076
|
+
case 'obs.updateFilter': {
|
|
1077
|
+
const response = handleObsUpdateFilter(params, obsManager);
|
|
1078
|
+
if (isNotification)
|
|
1079
|
+
return null;
|
|
1080
|
+
return response;
|
|
1081
|
+
}
|
|
1082
|
+
default:
|
|
1083
|
+
// Unknown obs method
|
|
1084
|
+
if (isNotification)
|
|
1085
|
+
return null;
|
|
1086
|
+
return {
|
|
1087
|
+
jsonrpc: '2.0',
|
|
1088
|
+
error: {
|
|
1089
|
+
code: JSON_RPC_ERRORS.METHOD_NOT_FOUND.code,
|
|
1090
|
+
message: `Method '${method}' not found`,
|
|
1091
|
+
},
|
|
1092
|
+
id: id ?? null,
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
// WebSocket upgrade handler for /rpc
|
|
1097
|
+
rpcRoutes.get('/', createWebSocketHandler('/'));
|
|
1098
|
+
// WebSocket upgrade handler for /rpc/:doName (e.g., /rpc/Users)
|
|
1099
|
+
rpcRoutes.get('/:doName', createWebSocketHandler('/:doName'));
|
|
1100
|
+
// WebSocket upgrade handler for /rpc/:doName/:id (e.g., /rpc/Users/user-123)
|
|
1101
|
+
rpcRoutes.get('/:doName/:id', createWebSocketHandler('/:doName/:id'));
|
|
1102
|
+
export default rpcRoutes;
|
|
1103
|
+
//# sourceMappingURL=rpc.js.map
|