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.
Files changed (727) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +446 -315
  3. package/dist/ai/index.js +19 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/template-literals.js +852 -0
  6. package/dist/ai/template-literals.js.map +1 -0
  7. package/dist/api/analytics/router.js +601 -0
  8. package/dist/api/analytics/router.js.map +1 -0
  9. package/dist/api/index.js +158 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/middleware/auth-federation.js +573 -0
  12. package/dist/api/middleware/auth-federation.js.map +1 -0
  13. package/dist/api/middleware/auth.js +544 -0
  14. package/dist/api/middleware/auth.js.map +1 -0
  15. package/dist/api/middleware/error-handling.js +176 -0
  16. package/dist/api/middleware/error-handling.js.map +1 -0
  17. package/dist/api/middleware/request-id.js +21 -0
  18. package/dist/api/middleware/request-id.js.map +1 -0
  19. package/dist/api/pages.js +1180 -0
  20. package/dist/api/pages.js.map +1 -0
  21. package/dist/api/routes/api.js +612 -0
  22. package/dist/api/routes/api.js.map +1 -0
  23. package/dist/api/routes/browsers.js +471 -0
  24. package/dist/api/routes/browsers.js.map +1 -0
  25. package/dist/api/routes/do.js +188 -0
  26. package/dist/api/routes/do.js.map +1 -0
  27. package/dist/api/routes/mcp.js +459 -0
  28. package/dist/api/routes/mcp.js.map +1 -0
  29. package/dist/api/routes/obs.js +445 -0
  30. package/dist/api/routes/obs.js.map +1 -0
  31. package/dist/api/routes/openapi.js +794 -0
  32. package/dist/api/routes/openapi.js.map +1 -0
  33. package/dist/api/routes/rpc.js +1103 -0
  34. package/dist/api/routes/rpc.js.map +1 -0
  35. package/dist/api/routes/sandboxes.js +389 -0
  36. package/dist/api/routes/sandboxes.js.map +1 -0
  37. package/dist/api/test-do.js +38 -0
  38. package/dist/api/test-do.js.map +1 -0
  39. package/dist/api/types.js +11 -0
  40. package/dist/api/types.js.map +1 -0
  41. package/dist/cli/bin.js +2 -0
  42. package/dist/cli/main.js +52342 -0
  43. package/dist/db/actions.js +212 -0
  44. package/dist/db/actions.js.map +1 -0
  45. package/dist/db/auth.js +506 -0
  46. package/dist/db/auth.js.map +1 -0
  47. package/dist/db/branches.js +65 -0
  48. package/dist/db/branches.js.map +1 -0
  49. package/dist/db/clickhouse.js +1074 -0
  50. package/dist/db/clickhouse.js.map +1 -0
  51. package/dist/db/dlq.js +39 -0
  52. package/dist/db/dlq.js.map +1 -0
  53. package/dist/db/events.js +28 -0
  54. package/dist/db/events.js.map +1 -0
  55. package/dist/db/exec.js +64 -0
  56. package/dist/db/exec.js.map +1 -0
  57. package/dist/db/files.js +85 -0
  58. package/dist/db/files.js.map +1 -0
  59. package/dist/db/flags.js +24 -0
  60. package/dist/db/flags.js.map +1 -0
  61. package/dist/db/git.js +116 -0
  62. package/dist/db/git.js.map +1 -0
  63. package/dist/db/iceberg/inverted-index.js +862 -0
  64. package/dist/db/iceberg/inverted-index.js.map +1 -0
  65. package/dist/db/iceberg/puffin.js +878 -0
  66. package/dist/db/iceberg/puffin.js.map +1 -0
  67. package/dist/db/iceberg/search-manifest.js +422 -0
  68. package/dist/db/iceberg/search-manifest.js.map +1 -0
  69. package/dist/db/iceberg/types.js +8 -0
  70. package/dist/db/iceberg/types.js.map +1 -0
  71. package/dist/db/index.js +121 -0
  72. package/dist/db/index.js.map +1 -0
  73. package/dist/db/integrations.js +368 -0
  74. package/dist/db/integrations.js.map +1 -0
  75. package/dist/db/json-indexes.js +332 -0
  76. package/dist/db/json-indexes.js.map +1 -0
  77. package/dist/db/linked-accounts.js +287 -0
  78. package/dist/db/linked-accounts.js.map +1 -0
  79. package/dist/db/nouns.js +183 -0
  80. package/dist/db/nouns.js.map +1 -0
  81. package/dist/db/objects.js +170 -0
  82. package/dist/db/objects.js.map +1 -0
  83. package/dist/db/primitives/dag-scheduler/index.js +869 -0
  84. package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
  85. package/dist/db/primitives/exactly-once-context.js +237 -0
  86. package/dist/db/primitives/exactly-once-context.js.map +1 -0
  87. package/dist/db/primitives/index.js +62 -0
  88. package/dist/db/primitives/index.js.map +1 -0
  89. package/dist/db/primitives/keyed-router.js +145 -0
  90. package/dist/db/primitives/keyed-router.js.map +1 -0
  91. package/dist/db/primitives/observability.js +162 -0
  92. package/dist/db/primitives/observability.js.map +1 -0
  93. package/dist/db/primitives/schema-evolution.js +643 -0
  94. package/dist/db/primitives/schema-evolution.js.map +1 -0
  95. package/dist/db/primitives/stateful-operator/index.js +770 -0
  96. package/dist/db/primitives/stateful-operator/index.js.map +1 -0
  97. package/dist/db/primitives/temporal-store.js +306 -0
  98. package/dist/db/primitives/temporal-store.js.map +1 -0
  99. package/dist/db/primitives/typed-column-store.js +1229 -0
  100. package/dist/db/primitives/typed-column-store.js.map +1 -0
  101. package/dist/db/primitives/utils/duration.js +162 -0
  102. package/dist/db/primitives/utils/duration.js.map +1 -0
  103. package/dist/db/primitives/utils/murmur3.js +118 -0
  104. package/dist/db/primitives/utils/murmur3.js.map +1 -0
  105. package/dist/db/primitives/watermark-service.js +136 -0
  106. package/dist/db/primitives/watermark-service.js.map +1 -0
  107. package/dist/db/primitives/window-manager.js +764 -0
  108. package/dist/db/primitives/window-manager.js.map +1 -0
  109. package/dist/db/relationships.js +66 -0
  110. package/dist/db/relationships.js.map +1 -0
  111. package/dist/db/schema-minimal.js +61 -0
  112. package/dist/db/schema-minimal.js.map +1 -0
  113. package/dist/db/search.js +28 -0
  114. package/dist/db/search.js.map +1 -0
  115. package/dist/db/stores.js +1665 -0
  116. package/dist/db/stores.js.map +1 -0
  117. package/dist/db/things.js +297 -0
  118. package/dist/db/things.js.map +1 -0
  119. package/dist/db/vault.js +171 -0
  120. package/dist/db/vault.js.map +1 -0
  121. package/dist/db/verbs.js +102 -0
  122. package/dist/db/verbs.js.map +1 -0
  123. package/dist/do/base.js +48 -0
  124. package/dist/do/base.js.map +1 -0
  125. package/dist/do/bash.js +35 -0
  126. package/dist/do/bash.js.map +1 -0
  127. package/dist/do/fs.js +25 -0
  128. package/dist/do/fs.js.map +1 -0
  129. package/dist/do/full.js +61 -0
  130. package/dist/do/full.js.map +1 -0
  131. package/dist/do/git.js +28 -0
  132. package/dist/do/git.js.map +1 -0
  133. package/dist/do/index.js +52 -0
  134. package/dist/do/index.js.map +1 -0
  135. package/dist/do/tiny.js +31 -0
  136. package/dist/do/tiny.js.map +1 -0
  137. package/dist/lib/DOAuth.js +261 -0
  138. package/dist/lib/DOAuth.js.map +1 -0
  139. package/dist/lib/DODispatcher.js +72 -0
  140. package/dist/lib/DODispatcher.js.map +1 -0
  141. package/dist/lib/Modifier.js +189 -0
  142. package/dist/lib/Modifier.js.map +1 -0
  143. package/dist/lib/StateStorage.js +403 -0
  144. package/dist/lib/StateStorage.js.map +1 -0
  145. package/dist/lib/TypeRegistry.js +122 -0
  146. package/dist/lib/TypeRegistry.js.map +1 -0
  147. package/dist/lib/agent/tools/bash.js +336 -0
  148. package/dist/lib/agent/tools/bash.js.map +1 -0
  149. package/dist/lib/agent/tools/edit.js +157 -0
  150. package/dist/lib/agent/tools/edit.js.map +1 -0
  151. package/dist/lib/agent/tools/glob.js +137 -0
  152. package/dist/lib/agent/tools/glob.js.map +1 -0
  153. package/dist/lib/agent/tools/grep.js +315 -0
  154. package/dist/lib/agent/tools/grep.js.map +1 -0
  155. package/dist/lib/agent/tools/index.js +71 -0
  156. package/dist/lib/agent/tools/index.js.map +1 -0
  157. package/dist/lib/agent/tools/read.js +212 -0
  158. package/dist/lib/agent/tools/read.js.map +1 -0
  159. package/dist/lib/agent/tools/types.js +197 -0
  160. package/dist/lib/agent/tools/types.js.map +1 -0
  161. package/dist/lib/agent/tools/write.js +159 -0
  162. package/dist/lib/agent/tools/write.js.map +1 -0
  163. package/dist/lib/ai/gateway.js +247 -0
  164. package/dist/lib/ai/gateway.js.map +1 -0
  165. package/dist/lib/ai/tool-loop-agent.js +591 -0
  166. package/dist/lib/ai/tool-loop-agent.js.map +1 -0
  167. package/dist/lib/auto-wiring.js +439 -0
  168. package/dist/lib/auto-wiring.js.map +1 -0
  169. package/dist/lib/browse/browserbase.js +163 -0
  170. package/dist/lib/browse/browserbase.js.map +1 -0
  171. package/dist/lib/browse/cloudflare.js +144 -0
  172. package/dist/lib/browse/cloudflare.js.map +1 -0
  173. package/dist/lib/browse/index.js +62 -0
  174. package/dist/lib/browse/index.js.map +1 -0
  175. package/dist/lib/browse/types.js +13 -0
  176. package/dist/lib/browse/types.js.map +1 -0
  177. package/dist/lib/cache/index.js +37 -0
  178. package/dist/lib/cache/index.js.map +1 -0
  179. package/dist/lib/cache/visibility.js +638 -0
  180. package/dist/lib/cache/visibility.js.map +1 -0
  181. package/dist/lib/capabilities.js +268 -0
  182. package/dist/lib/capabilities.js.map +1 -0
  183. package/dist/lib/channels/base.js +106 -0
  184. package/dist/lib/channels/base.js.map +1 -0
  185. package/dist/lib/channels/discord.js +94 -0
  186. package/dist/lib/channels/discord.js.map +1 -0
  187. package/dist/lib/channels/email.js +204 -0
  188. package/dist/lib/channels/email.js.map +1 -0
  189. package/dist/lib/channels/index.js +90 -0
  190. package/dist/lib/channels/index.js.map +1 -0
  191. package/dist/lib/channels/mdxui-chat.js +95 -0
  192. package/dist/lib/channels/mdxui-chat.js.map +1 -0
  193. package/dist/lib/channels/slack-blockkit.js +121 -0
  194. package/dist/lib/channels/slack-blockkit.js.map +1 -0
  195. package/dist/lib/channels/types.js +7 -0
  196. package/dist/lib/channels/types.js.map +1 -0
  197. package/dist/lib/cloudflare/ai.js +654 -0
  198. package/dist/lib/cloudflare/ai.js.map +1 -0
  199. package/dist/lib/cloudflare/index.js +88 -0
  200. package/dist/lib/cloudflare/index.js.map +1 -0
  201. package/dist/lib/cloudflare/kv.js +342 -0
  202. package/dist/lib/cloudflare/kv.js.map +1 -0
  203. package/dist/lib/cloudflare/queues.js +434 -0
  204. package/dist/lib/cloudflare/queues.js.map +1 -0
  205. package/dist/lib/cloudflare/r2.js +604 -0
  206. package/dist/lib/cloudflare/r2.js.map +1 -0
  207. package/dist/lib/cloudflare/vectorize.js +494 -0
  208. package/dist/lib/cloudflare/vectorize.js.map +1 -0
  209. package/dist/lib/cloudflare/workflows.js +569 -0
  210. package/dist/lib/cloudflare/workflows.js.map +1 -0
  211. package/dist/lib/colo/caching.js +196 -0
  212. package/dist/lib/colo/caching.js.map +1 -0
  213. package/dist/lib/colo/detection.js +194 -0
  214. package/dist/lib/colo/detection.js.map +1 -0
  215. package/dist/lib/colo/external-data.js +219 -0
  216. package/dist/lib/colo/external-data.js.map +1 -0
  217. package/dist/lib/colo/globe-data.js +179 -0
  218. package/dist/lib/colo/globe-data.js.map +1 -0
  219. package/dist/lib/colo/index.js +16 -0
  220. package/dist/lib/colo/index.js.map +1 -0
  221. package/dist/lib/decorators.js +37 -0
  222. package/dist/lib/decorators.js.map +1 -0
  223. package/dist/lib/discovery.js +81 -0
  224. package/dist/lib/discovery.js.map +1 -0
  225. package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
  226. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
  227. package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
  228. package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
  229. package/dist/lib/executors/CascadeExecutor.js +418 -0
  230. package/dist/lib/executors/CascadeExecutor.js.map +1 -0
  231. package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
  232. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
  233. package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
  234. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
  235. package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
  236. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
  237. package/dist/lib/executors/ParallelStepExecutor.js +308 -0
  238. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
  239. package/dist/lib/executors/types.js +12 -0
  240. package/dist/lib/executors/types.js.map +1 -0
  241. package/dist/lib/experiments.js +89 -0
  242. package/dist/lib/experiments.js.map +1 -0
  243. package/dist/lib/flags/store.js +262 -0
  244. package/dist/lib/flags/store.js.map +1 -0
  245. package/dist/lib/functions/FunctionComposition.js +467 -0
  246. package/dist/lib/functions/FunctionComposition.js.map +1 -0
  247. package/dist/lib/functions/FunctionMiddleware.js +457 -0
  248. package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
  249. package/dist/lib/functions/FunctionRegistry.js +426 -0
  250. package/dist/lib/functions/FunctionRegistry.js.map +1 -0
  251. package/dist/lib/functions/createFunction.js +1048 -0
  252. package/dist/lib/functions/createFunction.js.map +1 -0
  253. package/dist/lib/humans/index.js +68 -0
  254. package/dist/lib/humans/index.js.map +1 -0
  255. package/dist/lib/humans/templates.js +117 -0
  256. package/dist/lib/humans/templates.js.map +1 -0
  257. package/dist/lib/identity.js +98 -0
  258. package/dist/lib/identity.js.map +1 -0
  259. package/dist/lib/index.js +9 -0
  260. package/dist/lib/index.js.map +1 -0
  261. package/dist/lib/logging/error-logger.js +163 -0
  262. package/dist/lib/logging/error-logger.js.map +1 -0
  263. package/dist/lib/logging/index.js +160 -0
  264. package/dist/lib/logging/index.js.map +1 -0
  265. package/dist/lib/mixins/bash.js +825 -0
  266. package/dist/lib/mixins/bash.js.map +1 -0
  267. package/dist/lib/mixins/fs.js +648 -0
  268. package/dist/lib/mixins/fs.js.map +1 -0
  269. package/dist/lib/mixins/git.js +1011 -0
  270. package/dist/lib/mixins/git.js.map +1 -0
  271. package/dist/lib/mixins/index.js +29 -0
  272. package/dist/lib/mixins/index.js.map +1 -0
  273. package/dist/lib/mixins/npm.js +662 -0
  274. package/dist/lib/mixins/npm.js.map +1 -0
  275. package/dist/lib/noun-id.js +278 -0
  276. package/dist/lib/noun-id.js.map +1 -0
  277. package/dist/lib/rate-limit/sliding-window.js +148 -0
  278. package/dist/lib/rate-limit/sliding-window.js.map +1 -0
  279. package/dist/lib/rate-limit.js +110 -0
  280. package/dist/lib/rate-limit.js.map +1 -0
  281. package/dist/lib/rpc/bindings.js +548 -0
  282. package/dist/lib/rpc/bindings.js.map +1 -0
  283. package/dist/lib/rpc/index.js +64 -0
  284. package/dist/lib/rpc/index.js.map +1 -0
  285. package/dist/lib/safe-stringify.js +223 -0
  286. package/dist/lib/safe-stringify.js.map +1 -0
  287. package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
  288. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
  289. package/dist/lib/sqids.js +110 -0
  290. package/dist/lib/sqids.js.map +1 -0
  291. package/dist/lib/sql/adapters/index.js +10 -0
  292. package/dist/lib/sql/adapters/index.js.map +1 -0
  293. package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
  294. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
  295. package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
  296. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
  297. package/dist/lib/sql/index.js +277 -0
  298. package/dist/lib/sql/index.js.map +1 -0
  299. package/dist/lib/sql/types.js +56 -0
  300. package/dist/lib/sql/types.js.map +1 -0
  301. package/dist/lib/type-classifier.js +126 -0
  302. package/dist/lib/type-classifier.js.map +1 -0
  303. package/dist/lib/utils/html.js +47 -0
  304. package/dist/lib/utils/html.js.map +1 -0
  305. package/dist/lib/validation.js +48 -0
  306. package/dist/lib/validation.js.map +1 -0
  307. package/dist/lib/vault/store.js +411 -0
  308. package/dist/lib/vault/store.js.map +1 -0
  309. package/dist/metrics/hunch.js +739 -0
  310. package/dist/metrics/hunch.js.map +1 -0
  311. package/dist/objects/API.js +302 -0
  312. package/dist/objects/API.js.map +1 -0
  313. package/dist/objects/Agent.js +179 -0
  314. package/dist/objects/Agent.js.map +1 -0
  315. package/dist/objects/AgenticFunctionExecutor.js +8 -0
  316. package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
  317. package/dist/objects/App.js +83 -0
  318. package/dist/objects/App.js.map +1 -0
  319. package/dist/objects/Browser.js +884 -0
  320. package/dist/objects/Browser.js.map +1 -0
  321. package/dist/objects/Business.js +107 -0
  322. package/dist/objects/Business.js.map +1 -0
  323. package/dist/objects/CLI.js +221 -0
  324. package/dist/objects/CLI.js.map +1 -0
  325. package/dist/objects/CodeFunctionExecutor.js +8 -0
  326. package/dist/objects/CodeFunctionExecutor.js.map +1 -0
  327. package/dist/objects/Collection.js +161 -0
  328. package/dist/objects/Collection.js.map +1 -0
  329. package/dist/objects/DO.js +41 -0
  330. package/dist/objects/DO.js.map +1 -0
  331. package/dist/objects/DOBase.js +2309 -0
  332. package/dist/objects/DOBase.js.map +1 -0
  333. package/dist/objects/DOFull.js +1676 -0
  334. package/dist/objects/DOFull.js.map +1 -0
  335. package/dist/objects/DOTiny.js +207 -0
  336. package/dist/objects/DOTiny.js.map +1 -0
  337. package/dist/objects/Directory.js +199 -0
  338. package/dist/objects/Directory.js.map +1 -0
  339. package/dist/objects/Entity.js +413 -0
  340. package/dist/objects/Entity.js.map +1 -0
  341. package/dist/objects/Function.js +116 -0
  342. package/dist/objects/Function.js.map +1 -0
  343. package/dist/objects/Human.js +231 -0
  344. package/dist/objects/Human.js.map +1 -0
  345. package/dist/objects/HumanFunctionExecutor.js +8 -0
  346. package/dist/objects/HumanFunctionExecutor.js.map +1 -0
  347. package/dist/objects/IcebergMetadataDO.js +938 -0
  348. package/dist/objects/IcebergMetadataDO.js.map +1 -0
  349. package/dist/objects/IntegrationsDO.js +1174 -0
  350. package/dist/objects/IntegrationsDO.js.map +1 -0
  351. package/dist/objects/ObservabilityBroadcaster.js +149 -0
  352. package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
  353. package/dist/objects/Package.js +154 -0
  354. package/dist/objects/Package.js.map +1 -0
  355. package/dist/objects/Product.js +193 -0
  356. package/dist/objects/Product.js.map +1 -0
  357. package/dist/objects/SDK.js +152 -0
  358. package/dist/objects/SDK.js.map +1 -0
  359. package/dist/objects/SaaS.js +235 -0
  360. package/dist/objects/SaaS.js.map +1 -0
  361. package/dist/objects/SandboxDO.js +759 -0
  362. package/dist/objects/SandboxDO.js.map +1 -0
  363. package/dist/objects/Service.js +337 -0
  364. package/dist/objects/Service.js.map +1 -0
  365. package/dist/objects/Site.js +80 -0
  366. package/dist/objects/Site.js.map +1 -0
  367. package/dist/objects/Startup.js +479 -0
  368. package/dist/objects/Startup.js.map +1 -0
  369. package/dist/objects/ThingsDO.js +170 -0
  370. package/dist/objects/ThingsDO.js.map +1 -0
  371. package/dist/objects/VectorShardDO.js +648 -0
  372. package/dist/objects/VectorShardDO.js.map +1 -0
  373. package/dist/objects/Worker.js +144 -0
  374. package/dist/objects/Worker.js.map +1 -0
  375. package/dist/objects/Workflow.js +196 -0
  376. package/dist/objects/Workflow.js.map +1 -0
  377. package/dist/objects/WorkflowFactory.js +313 -0
  378. package/dist/objects/WorkflowFactory.js.map +1 -0
  379. package/dist/objects/WorkflowRuntime.js +863 -0
  380. package/dist/objects/WorkflowRuntime.js.map +1 -0
  381. package/dist/objects/circuit-breaker-bulkhead.js +178 -0
  382. package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
  383. package/dist/objects/createFunction.js +934 -0
  384. package/dist/objects/createFunction.js.map +1 -0
  385. package/dist/objects/index.js +80 -0
  386. package/dist/objects/index.js.map +1 -0
  387. package/dist/objects/lifecycle/Branch.js +275 -0
  388. package/dist/objects/lifecycle/Branch.js.map +1 -0
  389. package/dist/objects/lifecycle/Clone.js +1499 -0
  390. package/dist/objects/lifecycle/Clone.js.map +1 -0
  391. package/dist/objects/lifecycle/Compact.js +237 -0
  392. package/dist/objects/lifecycle/Compact.js.map +1 -0
  393. package/dist/objects/lifecycle/Promote.js +476 -0
  394. package/dist/objects/lifecycle/Promote.js.map +1 -0
  395. package/dist/objects/lifecycle/Shard.js +560 -0
  396. package/dist/objects/lifecycle/Shard.js.map +1 -0
  397. package/dist/objects/lifecycle/index.js +15 -0
  398. package/dist/objects/lifecycle/index.js.map +1 -0
  399. package/dist/objects/lifecycle/types.js +33 -0
  400. package/dist/objects/lifecycle/types.js.map +1 -0
  401. package/dist/objects/mixins/infrastructure.js +171 -0
  402. package/dist/objects/mixins/infrastructure.js.map +1 -0
  403. package/dist/objects/modules/StoresModule.js +153 -0
  404. package/dist/objects/modules/StoresModule.js.map +1 -0
  405. package/dist/objects/persistence/checkpoint-manager.js +606 -0
  406. package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
  407. package/dist/objects/persistence/index.js +72 -0
  408. package/dist/objects/persistence/index.js.map +1 -0
  409. package/dist/objects/persistence/migration-runner.js +562 -0
  410. package/dist/objects/persistence/migration-runner.js.map +1 -0
  411. package/dist/objects/persistence/replication-manager.js +501 -0
  412. package/dist/objects/persistence/replication-manager.js.map +1 -0
  413. package/dist/objects/persistence/tiered-storage-manager.js +595 -0
  414. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
  415. package/dist/objects/persistence/types.js +14 -0
  416. package/dist/objects/persistence/types.js.map +1 -0
  417. package/dist/objects/persistence/wal-manager.js +653 -0
  418. package/dist/objects/persistence/wal-manager.js.map +1 -0
  419. package/dist/objects/presets/index.js +20 -0
  420. package/dist/objects/presets/index.js.map +1 -0
  421. package/dist/objects/presets/primitives.js +188 -0
  422. package/dist/objects/presets/primitives.js.map +1 -0
  423. package/dist/objects/primitives/alarm-adapter.js +141 -0
  424. package/dist/objects/primitives/alarm-adapter.js.map +1 -0
  425. package/dist/objects/primitives/index.js +337 -0
  426. package/dist/objects/primitives/index.js.map +1 -0
  427. package/dist/objects/primitives/storage-adapter.js +182 -0
  428. package/dist/objects/primitives/storage-adapter.js.map +1 -0
  429. package/dist/objects/primitives/with-primitives.js +102 -0
  430. package/dist/objects/primitives/with-primitives.js.map +1 -0
  431. package/dist/objects/services/StoreManager.js +227 -0
  432. package/dist/objects/services/StoreManager.js.map +1 -0
  433. package/dist/objects/services/index.js +13 -0
  434. package/dist/objects/services/index.js.map +1 -0
  435. package/dist/objects/transport/auth-layer.js +1451 -0
  436. package/dist/objects/transport/auth-layer.js.map +1 -0
  437. package/dist/objects/transport/capnweb-target.js +355 -0
  438. package/dist/objects/transport/capnweb-target.js.map +1 -0
  439. package/dist/objects/transport/chain.js +441 -0
  440. package/dist/objects/transport/chain.js.map +1 -0
  441. package/dist/objects/transport/handler.js +58 -0
  442. package/dist/objects/transport/handler.js.map +1 -0
  443. package/dist/objects/transport/index.js +53 -0
  444. package/dist/objects/transport/index.js.map +1 -0
  445. package/dist/objects/transport/mcp-server.js +690 -0
  446. package/dist/objects/transport/mcp-server.js.map +1 -0
  447. package/dist/objects/transport/rest-autowire.js +1507 -0
  448. package/dist/objects/transport/rest-autowire.js.map +1 -0
  449. package/dist/objects/transport/rest-router.js +440 -0
  450. package/dist/objects/transport/rest-router.js.map +1 -0
  451. package/dist/objects/transport/rpc-server.js +1536 -0
  452. package/dist/objects/transport/rpc-server.js.map +1 -0
  453. package/dist/objects/transport/shared.js +575 -0
  454. package/dist/objects/transport/shared.js.map +1 -0
  455. package/dist/objects/transport/sync-engine.js +291 -0
  456. package/dist/objects/transport/sync-engine.js.map +1 -0
  457. package/dist/objects/transport/types.js +8 -0
  458. package/dist/objects/transport/types.js.map +1 -0
  459. package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
  460. package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
  461. package/dist/primitives/bashx/src/ast/parser.js +1488 -0
  462. package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
  463. package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
  464. package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
  465. package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
  466. package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
  467. package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
  468. package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
  469. package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
  470. package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
  471. package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
  472. package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
  473. package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
  474. package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
  475. package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
  476. package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
  477. package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
  478. package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
  479. package/dist/primitives/bashx/src/do/container-executor.js +429 -0
  480. package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
  481. package/dist/primitives/bashx/src/do/index.js +668 -0
  482. package/dist/primitives/bashx/src/do/index.js.map +1 -0
  483. package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
  484. package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
  485. package/dist/primitives/bashx/src/do/worker.js +352 -0
  486. package/dist/primitives/bashx/src/do/worker.js.map +1 -0
  487. package/dist/primitives/bashx/src/types.js +10 -0
  488. package/dist/primitives/bashx/src/types.js.map +1 -0
  489. package/dist/primitives/fsx/core/backend.js +480 -0
  490. package/dist/primitives/fsx/core/backend.js.map +1 -0
  491. package/dist/primitives/fsx/core/constants.js +140 -0
  492. package/dist/primitives/fsx/core/constants.js.map +1 -0
  493. package/dist/primitives/fsx/core/fsx.js +1184 -0
  494. package/dist/primitives/fsx/core/fsx.js.map +1 -0
  495. package/dist/primitives/fsx/core/glob/glob.js +438 -0
  496. package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
  497. package/dist/primitives/fsx/core/glob/index.js +8 -0
  498. package/dist/primitives/fsx/core/glob/index.js.map +1 -0
  499. package/dist/primitives/fsx/core/glob/match.js +392 -0
  500. package/dist/primitives/fsx/core/glob/match.js.map +1 -0
  501. package/dist/primitives/fsx/core/types.js +307 -0
  502. package/dist/primitives/fsx/core/types.js.map +1 -0
  503. package/dist/sandbox/index.js +258 -0
  504. package/dist/sandbox/index.js.map +1 -0
  505. package/dist/sdk/capnweb-compat.js +42 -0
  506. package/dist/sdk/capnweb-compat.js.map +1 -0
  507. package/dist/sdk/client.js +20 -0
  508. package/dist/sdk/client.js.map +1 -0
  509. package/dist/sdk/index.js +17 -0
  510. package/dist/sdk/index.js.map +1 -0
  511. package/dist/snippets/artifacts-config.js +241 -0
  512. package/dist/snippets/artifacts-config.js.map +1 -0
  513. package/dist/snippets/artifacts-ingest.js +832 -0
  514. package/dist/snippets/artifacts-ingest.js.map +1 -0
  515. package/dist/snippets/artifacts-serve.js +1035 -0
  516. package/dist/snippets/artifacts-serve.js.map +1 -0
  517. package/dist/snippets/artifacts-types.js +161 -0
  518. package/dist/snippets/artifacts-types.js.map +1 -0
  519. package/dist/snippets/cache-probe.js +376 -0
  520. package/dist/snippets/cache-probe.js.map +1 -0
  521. package/dist/snippets/cache.js +10 -0
  522. package/dist/snippets/cache.js.map +1 -0
  523. package/dist/snippets/events.js +469 -0
  524. package/dist/snippets/events.js.map +1 -0
  525. package/dist/snippets/index.js +7 -0
  526. package/dist/snippets/index.js.map +1 -0
  527. package/dist/snippets/proxy.js +495 -0
  528. package/dist/snippets/proxy.js.map +1 -0
  529. package/dist/snippets/search.js +1759 -0
  530. package/dist/snippets/search.js.map +1 -0
  531. package/dist/streams/index.js +30 -0
  532. package/dist/streams/index.js.map +1 -0
  533. package/dist/streams/observability.js +68 -0
  534. package/dist/streams/observability.js.map +1 -0
  535. package/dist/types/AI.js +92 -0
  536. package/dist/types/AI.js.map +1 -0
  537. package/dist/types/AIFunction.js +171 -0
  538. package/dist/types/AIFunction.js.map +1 -0
  539. package/dist/types/BrowseVerb.js +89 -0
  540. package/dist/types/BrowseVerb.js.map +1 -0
  541. package/dist/types/Browser.js +31 -0
  542. package/dist/types/Browser.js.map +1 -0
  543. package/dist/types/Chaos.js +15 -0
  544. package/dist/types/Chaos.js.map +1 -0
  545. package/dist/types/CloudflareBindings.js +109 -0
  546. package/dist/types/CloudflareBindings.js.map +1 -0
  547. package/dist/types/Collection.js +50 -0
  548. package/dist/types/Collection.js.map +1 -0
  549. package/dist/types/DO.js +2 -0
  550. package/dist/types/DO.js.map +1 -0
  551. package/dist/types/DOLocation.js +63 -0
  552. package/dist/types/DOLocation.js.map +1 -0
  553. package/dist/types/EventHandler.js +57 -0
  554. package/dist/types/EventHandler.js.map +1 -0
  555. package/dist/types/Experiment.js +33 -0
  556. package/dist/types/Experiment.js.map +1 -0
  557. package/dist/types/Flag.js +57 -0
  558. package/dist/types/Flag.js.map +1 -0
  559. package/dist/types/Lifecycle.js +13 -0
  560. package/dist/types/Lifecycle.js.map +1 -0
  561. package/dist/types/Location.js +169 -0
  562. package/dist/types/Location.js.map +1 -0
  563. package/dist/types/Noun.js +66 -0
  564. package/dist/types/Noun.js.map +1 -0
  565. package/dist/types/SessionEvent.js +194 -0
  566. package/dist/types/SessionEvent.js.map +1 -0
  567. package/dist/types/Thing.js +55 -0
  568. package/dist/types/Thing.js.map +1 -0
  569. package/dist/types/ThingDO.js +153 -0
  570. package/dist/types/ThingDO.js.map +1 -0
  571. package/dist/types/Things.js +2 -0
  572. package/dist/types/Things.js.map +1 -0
  573. package/dist/types/Verb.js +119 -0
  574. package/dist/types/Verb.js.map +1 -0
  575. package/dist/types/WorkflowContext.js +70 -0
  576. package/dist/types/WorkflowContext.js.map +1 -0
  577. package/dist/types/analytics-api.js +13 -0
  578. package/dist/types/analytics-api.js.map +1 -0
  579. package/dist/types/capabilities.js +135 -0
  580. package/dist/types/capabilities.js.map +1 -0
  581. package/dist/types/drizzle.js +12 -0
  582. package/dist/types/drizzle.js.map +1 -0
  583. package/dist/types/event.js +201 -0
  584. package/dist/types/event.js.map +1 -0
  585. package/dist/types/fn.js +12 -0
  586. package/dist/types/fn.js.map +1 -0
  587. package/dist/types/iceberg.js +48 -0
  588. package/dist/types/iceberg.js.map +1 -0
  589. package/dist/types/ids.js +170 -0
  590. package/dist/types/ids.js.map +1 -0
  591. package/dist/types/index.js +41 -0
  592. package/dist/types/index.js.map +1 -0
  593. package/dist/types/introspect.js +54 -0
  594. package/dist/types/introspect.js.map +1 -0
  595. package/dist/types/observability.js +124 -0
  596. package/dist/types/observability.js.map +1 -0
  597. package/dist/types/sync-protocol.js +175 -0
  598. package/dist/types/sync-protocol.js.map +1 -0
  599. package/dist/types/vector.js +13 -0
  600. package/dist/types/vector.js.map +1 -0
  601. package/dist/workflows/ScheduleManager.js +473 -0
  602. package/dist/workflows/ScheduleManager.js.map +1 -0
  603. package/dist/workflows/StepDOBridge.js +149 -0
  604. package/dist/workflows/StepDOBridge.js.map +1 -0
  605. package/dist/workflows/StepResultStorage.js +232 -0
  606. package/dist/workflows/StepResultStorage.js.map +1 -0
  607. package/dist/workflows/WaitForEventManager.js +461 -0
  608. package/dist/workflows/WaitForEventManager.js.map +1 -0
  609. package/dist/workflows/analyzer.js +332 -0
  610. package/dist/workflows/analyzer.js.map +1 -0
  611. package/dist/workflows/compat/activity-router.js +484 -0
  612. package/dist/workflows/compat/activity-router.js.map +1 -0
  613. package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
  614. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
  615. package/dist/workflows/compat/backends/index.js +14 -0
  616. package/dist/workflows/compat/backends/index.js.map +1 -0
  617. package/dist/workflows/compat/errors/index.js +375 -0
  618. package/dist/workflows/compat/errors/index.js.map +1 -0
  619. package/dist/workflows/compat/index.js +79 -0
  620. package/dist/workflows/compat/index.js.map +1 -0
  621. package/dist/workflows/compat/inngest/index.js +989 -0
  622. package/dist/workflows/compat/inngest/index.js.map +1 -0
  623. package/dist/workflows/compat/qstash/index.js +1263 -0
  624. package/dist/workflows/compat/qstash/index.js.map +1 -0
  625. package/dist/workflows/compat/temporal/activities.js +739 -0
  626. package/dist/workflows/compat/temporal/activities.js.map +1 -0
  627. package/dist/workflows/compat/temporal/child-workflows.js +154 -0
  628. package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
  629. package/dist/workflows/compat/temporal/client.js +381 -0
  630. package/dist/workflows/compat/temporal/client.js.map +1 -0
  631. package/dist/workflows/compat/temporal/context.js +309 -0
  632. package/dist/workflows/compat/temporal/context.js.map +1 -0
  633. package/dist/workflows/compat/temporal/determinism.js +216 -0
  634. package/dist/workflows/compat/temporal/determinism.js.map +1 -0
  635. package/dist/workflows/compat/temporal/errors.js +128 -0
  636. package/dist/workflows/compat/temporal/errors.js.map +1 -0
  637. package/dist/workflows/compat/temporal/index.js +2464 -0
  638. package/dist/workflows/compat/temporal/index.js.map +1 -0
  639. package/dist/workflows/compat/temporal/saga.js +504 -0
  640. package/dist/workflows/compat/temporal/saga.js.map +1 -0
  641. package/dist/workflows/compat/temporal/signals.js +364 -0
  642. package/dist/workflows/compat/temporal/signals.js.map +1 -0
  643. package/dist/workflows/compat/temporal/storage.js +271 -0
  644. package/dist/workflows/compat/temporal/storage.js.map +1 -0
  645. package/dist/workflows/compat/temporal/timers.js +347 -0
  646. package/dist/workflows/compat/temporal/timers.js.map +1 -0
  647. package/dist/workflows/compat/temporal/types.js +7 -0
  648. package/dist/workflows/compat/temporal/types.js.map +1 -0
  649. package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
  650. package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
  651. package/dist/workflows/compat/trigger/index.js +468 -0
  652. package/dist/workflows/compat/trigger/index.js.map +1 -0
  653. package/dist/workflows/compat/utils/index.js +69 -0
  654. package/dist/workflows/compat/utils/index.js.map +1 -0
  655. package/dist/workflows/context/correlation-capability.js +266 -0
  656. package/dist/workflows/context/correlation-capability.js.map +1 -0
  657. package/dist/workflows/context/correlation.js +484 -0
  658. package/dist/workflows/context/correlation.js.map +1 -0
  659. package/dist/workflows/context/experiment.js +289 -0
  660. package/dist/workflows/context/experiment.js.map +1 -0
  661. package/dist/workflows/context/flag.js +244 -0
  662. package/dist/workflows/context/flag.js.map +1 -0
  663. package/dist/workflows/context/foundation.js +648 -0
  664. package/dist/workflows/context/foundation.js.map +1 -0
  665. package/dist/workflows/context/human-base.js +106 -0
  666. package/dist/workflows/context/human-base.js.map +1 -0
  667. package/dist/workflows/context/human.js +368 -0
  668. package/dist/workflows/context/human.js.map +1 -0
  669. package/dist/workflows/context/measure.js +354 -0
  670. package/dist/workflows/context/measure.js.map +1 -0
  671. package/dist/workflows/context/rate-limit.js +358 -0
  672. package/dist/workflows/context/rate-limit.js.map +1 -0
  673. package/dist/workflows/context/user.js +117 -0
  674. package/dist/workflows/context/user.js.map +1 -0
  675. package/dist/workflows/context/vault.js +360 -0
  676. package/dist/workflows/context/vault.js.map +1 -0
  677. package/dist/workflows/data/entity-events/entity-events.js +489 -0
  678. package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
  679. package/dist/workflows/data/experiment/index.js +599 -0
  680. package/dist/workflows/data/experiment/index.js.map +1 -0
  681. package/dist/workflows/data/goal/context.js +558 -0
  682. package/dist/workflows/data/goal/context.js.map +1 -0
  683. package/dist/workflows/data/goal/index.js +32 -0
  684. package/dist/workflows/data/goal/index.js.map +1 -0
  685. package/dist/workflows/data/measure/index.js +840 -0
  686. package/dist/workflows/data/measure/index.js.map +1 -0
  687. package/dist/workflows/data/stream/index.js +1215 -0
  688. package/dist/workflows/data/stream/index.js.map +1 -0
  689. package/dist/workflows/data/track/context.js +883 -0
  690. package/dist/workflows/data/track/context.js.map +1 -0
  691. package/dist/workflows/data/track/index.js +15 -0
  692. package/dist/workflows/data/track/index.js.map +1 -0
  693. package/dist/workflows/data/view/context.js +864 -0
  694. package/dist/workflows/data/view/context.js.map +1 -0
  695. package/dist/workflows/domain.js +93 -0
  696. package/dist/workflows/domain.js.map +1 -0
  697. package/dist/workflows/flag.js +176 -0
  698. package/dist/workflows/flag.js.map +1 -0
  699. package/dist/workflows/flags.js +217 -0
  700. package/dist/workflows/flags.js.map +1 -0
  701. package/dist/workflows/hash.js +209 -0
  702. package/dist/workflows/hash.js.map +1 -0
  703. package/dist/workflows/index.js +50 -0
  704. package/dist/workflows/index.js.map +1 -0
  705. package/dist/workflows/on.js +378 -0
  706. package/dist/workflows/on.js.map +1 -0
  707. package/dist/workflows/pipeline-promise.js +481 -0
  708. package/dist/workflows/pipeline-promise.js.map +1 -0
  709. package/dist/workflows/pipeline-types.js +20 -0
  710. package/dist/workflows/pipeline-types.js.map +1 -0
  711. package/dist/workflows/proxy.js +76 -0
  712. package/dist/workflows/proxy.js.map +1 -0
  713. package/dist/workflows/runtime.js +310 -0
  714. package/dist/workflows/runtime.js.map +1 -0
  715. package/dist/workflows/schedule-builder.js +327 -0
  716. package/dist/workflows/schedule-builder.js.map +1 -0
  717. package/dist/workflows/visibility/index.js +148 -0
  718. package/dist/workflows/visibility/index.js.map +1 -0
  719. package/dist/workflows/visibility/query-parser.js +150 -0
  720. package/dist/workflows/visibility/query-parser.js.map +1 -0
  721. package/dist/workflows/visibility/store.js +223 -0
  722. package/dist/workflows/visibility/store.js.map +1 -0
  723. package/dist/workflows/visibility/types.js +30 -0
  724. package/dist/workflows/visibility/types.js.map +1 -0
  725. package/dist/workflows/workflow.js +53 -0
  726. package/dist/workflows/workflow.js.map +1 -0
  727. 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