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,1215 @@
1
+ /**
2
+ * Stream Processing API ($.stream)
3
+ *
4
+ * Provides real-time stream processing capabilities:
5
+ * - Stream sources from domain events, tracked events, and measurements
6
+ * - Transformations: filter(), map(), enrich(), flatMap()
7
+ * - Keyed streams via keyBy()
8
+ * - Windowing: tumbling, sliding, session windows
9
+ * - Aggregations within windows
10
+ * - Stream joins with temporal constraints
11
+ * - Sinks to track, measure, and view
12
+ *
13
+ * @module workflows/data/stream
14
+ */
15
+ import { toMillis } from '../../../db/primitives/utils/duration';
16
+ // ============================================================================
17
+ // Implementation
18
+ // ============================================================================
19
+ class StreamImpl {
20
+ type = 'stream';
21
+ source;
22
+ sink;
23
+ bufferCapacity;
24
+ bufferStrategy;
25
+ subscribers = [];
26
+ errorHandlers = [];
27
+ deadLetterHandlers = [];
28
+ forEachHandler;
29
+ running = false; // Streams don't run until explicitly started
30
+ streamName;
31
+ maxRetries = 0;
32
+ _bufferCapacity = Infinity;
33
+ _bufferStrategy = 'dropOldest';
34
+ _buffer = []; // Renamed to avoid conflict with buffer() method
35
+ throttleMs = 0;
36
+ lastEmitTime = 0;
37
+ throttleQueue = [];
38
+ throttleTimer = null;
39
+ ctx;
40
+ pipeline = [];
41
+ keyedSubscribers = [];
42
+ started = false; // Track if start() was called
43
+ isRoot = true; // Whether this is a root stream (receives from emit directly)
44
+ parentStream; // Parent stream for child streams
45
+ pendingOperations = []; // Track pending async operations
46
+ constructor(source, ctx, parent) {
47
+ this.source = Object.freeze({ ...source });
48
+ this.ctx = ctx;
49
+ if (parent) {
50
+ this.isRoot = false;
51
+ this.parentStream = parent;
52
+ }
53
+ }
54
+ isRootStream() {
55
+ return this.isRoot;
56
+ }
57
+ filter(predicate) {
58
+ const newStream = new StreamImpl(this.source, this.ctx, this);
59
+ newStream.pipeline.push(async (item) => {
60
+ const result = await predicate(item);
61
+ if (!result)
62
+ return Symbol.for('skip');
63
+ return item;
64
+ });
65
+ // Subscribe to parent to receive items, tracking async operations
66
+ this.subscribe((item) => {
67
+ const op = newStream.processItem(item);
68
+ newStream.pendingOperations.push(op);
69
+ });
70
+ this.ctx.registerStream(newStream);
71
+ return newStream;
72
+ }
73
+ map(fn) {
74
+ const newStream = new StreamImpl(this.source, this.ctx, this);
75
+ newStream.pipeline.push(async (item) => {
76
+ return await fn(item);
77
+ });
78
+ // Subscribe to parent to receive items, tracking async operations
79
+ this.subscribe((item) => {
80
+ const op = newStream.processItem(item);
81
+ newStream.pendingOperations.push(op);
82
+ });
83
+ this.ctx.registerStream(newStream);
84
+ return newStream;
85
+ }
86
+ flatMap(fn) {
87
+ const newStream = new StreamImpl(this.source, this.ctx, this);
88
+ newStream.pipeline.push(async (item) => {
89
+ const result = await fn(item);
90
+ return { __flatMap: result };
91
+ });
92
+ // Subscribe to parent to receive items, tracking async operations
93
+ this.subscribe((item) => {
94
+ const op = newStream.processItem(item);
95
+ newStream.pendingOperations.push(op);
96
+ });
97
+ this.ctx.registerStream(newStream);
98
+ return newStream;
99
+ }
100
+ enrich(fn) {
101
+ const newStream = new StreamImpl(this.source, this.ctx, this);
102
+ newStream.pipeline.push(async (item) => {
103
+ return await fn(item, this.ctx);
104
+ });
105
+ // Subscribe to parent to receive items, tracking async operations
106
+ this.subscribe((item) => {
107
+ const op = newStream.processItem(item);
108
+ newStream.pendingOperations.push(op);
109
+ });
110
+ this.ctx.registerStream(newStream);
111
+ return newStream;
112
+ }
113
+ keyBy(keyOrFn) {
114
+ return new KeyedStreamImpl(this, keyOrFn, this.ctx);
115
+ }
116
+ // These methods exist to provide helpful error messages
117
+ join() {
118
+ throw new Error('join() requires a keyed stream. Call keyBy() first.');
119
+ }
120
+ leftJoin() {
121
+ throw new Error('leftJoin() requires a keyed stream. Call keyBy() first.');
122
+ }
123
+ coGroup() {
124
+ throw new Error('coGroup() requires a keyed stream. Call keyBy() first.');
125
+ }
126
+ get window() {
127
+ // For non-keyed streams, use global key
128
+ const globalKeyedStream = new KeyedStreamImpl(this, () => '__global__', this.ctx);
129
+ return {
130
+ tumbling: (size) => {
131
+ const ws = globalKeyedStream.window.tumbling(size);
132
+ ws.key = '__global__';
133
+ return ws;
134
+ },
135
+ sliding: (size, slide) => globalKeyedStream.window.sliding(size, slide),
136
+ session: (gap) => globalKeyedStream.window.session(gap),
137
+ };
138
+ }
139
+ subscribe(fn) {
140
+ this.subscribers.push(fn);
141
+ // Auto-start when subscribed (implicit running) unless explicitly stopped
142
+ if (!this.started) {
143
+ this.running = true;
144
+ }
145
+ return () => {
146
+ const idx = this.subscribers.indexOf(fn);
147
+ if (idx !== -1)
148
+ this.subscribers.splice(idx, 1);
149
+ };
150
+ }
151
+ forEach(fn) {
152
+ this.forEachHandler = fn;
153
+ // Auto-start when forEach is called
154
+ if (!this.started) {
155
+ this.running = true;
156
+ }
157
+ return this;
158
+ }
159
+ async flush() {
160
+ // First, flush parent stream if we have one (to ensure upstream items flow through)
161
+ if (this.parentStream) {
162
+ await this.parentStream.flush();
163
+ }
164
+ // Wait for all pending async operations on THIS stream
165
+ // Keep flushing until no more pending operations (items may chain through)
166
+ while (this.pendingOperations.length > 0) {
167
+ const ops = this.pendingOperations;
168
+ this.pendingOperations = [];
169
+ await Promise.all(ops);
170
+ }
171
+ // Advance time to trigger window closes
172
+ this.ctx.advanceTime(Date.now());
173
+ // Process any throttled items
174
+ if (this.throttleTimer) {
175
+ clearTimeout(this.throttleTimer);
176
+ this.throttleTimer = null;
177
+ }
178
+ for (const item of this.throttleQueue) {
179
+ await this.deliverItem(item, true); // Skip throttle when flushing
180
+ }
181
+ this.throttleQueue = [];
182
+ // Deliver buffered items
183
+ if (this._buffer.length > 0) {
184
+ const items = [...this._buffer];
185
+ this._buffer = [];
186
+ for (const item of items) {
187
+ for (const subscriber of this.subscribers) {
188
+ subscriber(item);
189
+ }
190
+ if (this.forEachHandler) {
191
+ await this.forEachHandler(item);
192
+ }
193
+ // Also deliver to sinks
194
+ if (this.sink) {
195
+ if (this.sink.type === 'track' && this.sink.event) {
196
+ const handlers = this.ctx.getTrackHandlers(this.sink.event);
197
+ for (const handler of handlers) {
198
+ handler(item);
199
+ }
200
+ }
201
+ else if (this.sink.type === 'measure' && this.sink.metric) {
202
+ const handlers = this.ctx.getMeasureHandlers(this.sink.metric);
203
+ for (const handler of handlers) {
204
+ const value = typeof item === 'number' ? item : item?.value ?? 0;
205
+ const labels = item?.labels ?? {};
206
+ handler(value, labels);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ }
213
+ async start() {
214
+ this.started = true;
215
+ this.running = true;
216
+ }
217
+ async stop() {
218
+ this.running = false;
219
+ }
220
+ isRunning() {
221
+ return this.started && this.running;
222
+ }
223
+ name(n) {
224
+ this.streamName = n;
225
+ this.ctx.namedStreams.set(n, this);
226
+ return this;
227
+ }
228
+ getName() {
229
+ return this.streamName;
230
+ }
231
+ onError(handler) {
232
+ this.errorHandlers.push(handler);
233
+ return this;
234
+ }
235
+ deadLetter(handler) {
236
+ this.deadLetterHandlers.push(handler);
237
+ return this;
238
+ }
239
+ retry(maxRetries) {
240
+ this.maxRetries = maxRetries;
241
+ return this;
242
+ }
243
+ buffer(capacity, options) {
244
+ this._bufferCapacity = capacity;
245
+ this.bufferCapacity = capacity;
246
+ this._bufferStrategy = options?.strategy ?? 'dropOldest';
247
+ this.bufferStrategy = this._bufferStrategy;
248
+ return this;
249
+ }
250
+ throttle(interval) {
251
+ this.throttleMs = toMillis(interval);
252
+ return this;
253
+ }
254
+ get to() {
255
+ const self = this;
256
+ return {
257
+ track: new Proxy({}, {
258
+ get(_, event) {
259
+ self.sink = { type: 'track', event };
260
+ self.ctx.registerSinkStream(self, 'track', event);
261
+ return self;
262
+ },
263
+ }),
264
+ measure: new Proxy({}, {
265
+ get(_, metric) {
266
+ self.sink = { type: 'measure', metric };
267
+ self.ctx.registerSinkStream(self, 'measure', metric);
268
+ return self;
269
+ },
270
+ }),
271
+ view: new Proxy({}, {
272
+ get(_, view) {
273
+ self.sink = { type: 'view', view };
274
+ self.ctx.registerSinkStream(self, 'view', view);
275
+ return self;
276
+ },
277
+ }),
278
+ };
279
+ }
280
+ async processItem(item) {
281
+ // If explicitly stopped (started = true but running = false), don't process
282
+ if (this.started && !this.running) {
283
+ return;
284
+ }
285
+ // Otherwise, process if:
286
+ // - root stream (always processes unless explicitly stopped)
287
+ // - has subscribers
288
+ // - has forEachHandler
289
+ // - has pipeline (predicates/transforms to run for side effects like spying)
290
+ if (!this.isRoot && this.subscribers.length === 0 && !this.forEachHandler && this.pipeline.length === 0) {
291
+ return;
292
+ }
293
+ let current = item;
294
+ let attempts = 0;
295
+ const maxAttempts = this.maxRetries + 1;
296
+ while (attempts < maxAttempts) {
297
+ try {
298
+ // Process through pipeline
299
+ for (const step of this.pipeline) {
300
+ current = await step(current);
301
+ if (current === Symbol.for('skip'))
302
+ return;
303
+ if (current && typeof current === 'object' && '__flatMap' in current) {
304
+ const items = current.__flatMap;
305
+ for (const flatItem of items) {
306
+ await this.deliverItem(flatItem);
307
+ }
308
+ return;
309
+ }
310
+ }
311
+ await this.deliverItem(current);
312
+ return;
313
+ }
314
+ catch (error) {
315
+ attempts++;
316
+ if (attempts >= maxAttempts) {
317
+ for (const handler of this.errorHandlers) {
318
+ handler(error);
319
+ }
320
+ for (const handler of this.deadLetterHandlers) {
321
+ handler(item, error);
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+ async deliverItem(item, skipThrottle = false) {
328
+ // Handle throttling (skipped when flushing throttled items)
329
+ if (this.throttleMs > 0 && !skipThrottle) {
330
+ const now = Date.now();
331
+ if (now - this.lastEmitTime < this.throttleMs) {
332
+ this.throttleQueue.push(item);
333
+ if (!this.throttleTimer) {
334
+ this.throttleTimer = setTimeout(() => {
335
+ const next = this.throttleQueue.shift();
336
+ if (next)
337
+ this.deliverItem(next, true);
338
+ this.throttleTimer = null;
339
+ }, this.throttleMs - (now - this.lastEmitTime));
340
+ }
341
+ return;
342
+ }
343
+ this.lastEmitTime = now;
344
+ }
345
+ // Handle buffering - buffer items and deliver on flush
346
+ if (this._bufferCapacity < Infinity) {
347
+ this._buffer.push(item);
348
+ if (this._buffer.length > this._bufferCapacity) {
349
+ if (this._bufferStrategy === 'dropOldest') {
350
+ this._buffer.shift();
351
+ }
352
+ else {
353
+ this._buffer.pop(); // Remove the item we just pushed (newest)
354
+ }
355
+ }
356
+ // When buffering, don't deliver immediately - wait for flush
357
+ return;
358
+ }
359
+ for (const subscriber of this.subscribers) {
360
+ subscriber(item);
361
+ }
362
+ if (this.forEachHandler) {
363
+ await this.forEachHandler(item);
364
+ }
365
+ // Deliver to sink if configured
366
+ if (this.sink) {
367
+ if (this.sink.type === 'track' && this.sink.event) {
368
+ const handlers = this.ctx.getTrackHandlers(this.sink.event);
369
+ for (const handler of handlers) {
370
+ handler(item);
371
+ }
372
+ }
373
+ else if (this.sink.type === 'measure' && this.sink.metric) {
374
+ const handlers = this.ctx.getMeasureHandlers(this.sink.metric);
375
+ for (const handler of handlers) {
376
+ // For measure sinks, extract value and labels from the item
377
+ const value = typeof item === 'number' ? item : item?.value ?? 0;
378
+ const labels = item?.labels ?? {};
379
+ handler(value, labels);
380
+ }
381
+ }
382
+ else if (this.sink.type === 'view' && this.sink.view) {
383
+ const handlers = this.ctx.getViewHandlers(this.sink.view);
384
+ for (const handler of handlers) {
385
+ handler(item);
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+ class KeyedStreamImpl {
392
+ type = 'keyed-stream';
393
+ keySelector;
394
+ parentStream;
395
+ ctx;
396
+ subscribers = [];
397
+ timestampSubscribers = [];
398
+ constructor(parent, keySelector, ctx) {
399
+ this.parentStream = parent;
400
+ this.keySelector = keySelector;
401
+ this.ctx = ctx;
402
+ // Subscribe to parent stream to get transformed items
403
+ this.parentStream.subscribe((item) => {
404
+ // Get timestamp from item if available, otherwise use current time
405
+ const timestamp = item?.timestamp ?? Date.now();
406
+ this.processItem(item, timestamp);
407
+ });
408
+ this.ctx.registerKeyedStream(this);
409
+ }
410
+ getKey(item) {
411
+ if (typeof this.keySelector === 'string') {
412
+ return item[this.keySelector];
413
+ }
414
+ return this.keySelector(item);
415
+ }
416
+ get window() {
417
+ return {
418
+ tumbling: (size) => {
419
+ const sizeMs = toMillis(size);
420
+ return new WindowedStreamImpl(this, { type: 'tumbling', size: sizeMs }, this.ctx);
421
+ },
422
+ sliding: (size, slide) => {
423
+ const sizeMs = toMillis(size);
424
+ const slideMs = toMillis(slide);
425
+ if (slideMs > sizeMs) {
426
+ throw new Error('Slide cannot be larger than size');
427
+ }
428
+ return new WindowedStreamImpl(this, { type: 'sliding', size: sizeMs, slide: slideMs }, this.ctx);
429
+ },
430
+ session: (gap) => {
431
+ const gapMs = toMillis(gap);
432
+ return new WindowedStreamImpl(this, { type: 'session', gap: gapMs }, this.ctx);
433
+ },
434
+ };
435
+ }
436
+ join(other) {
437
+ return new JoinBuilderImpl(this, other, 'inner', this.ctx);
438
+ }
439
+ leftJoin(other) {
440
+ return new JoinBuilderImpl(this, other, 'left', this.ctx);
441
+ }
442
+ coGroup(other) {
443
+ return new CoGroupBuilderImpl(this, other, this.ctx);
444
+ }
445
+ subscribe(fn) {
446
+ this.subscribers.push(fn);
447
+ return () => {
448
+ const idx = this.subscribers.indexOf(fn);
449
+ if (idx !== -1)
450
+ this.subscribers.splice(idx, 1);
451
+ };
452
+ }
453
+ subscribeWithTimestamp(fn) {
454
+ this.timestampSubscribers.push(fn);
455
+ return () => {
456
+ const idx = this.timestampSubscribers.indexOf(fn);
457
+ if (idx !== -1)
458
+ this.timestampSubscribers.splice(idx, 1);
459
+ };
460
+ }
461
+ async flush() {
462
+ await this.parentStream.flush();
463
+ }
464
+ processItem(item, timestamp) {
465
+ const key = this.getKey(item);
466
+ const ts = timestamp ?? item?.timestamp ?? Date.now();
467
+ for (const subscriber of this.subscribers) {
468
+ subscriber(item, key);
469
+ }
470
+ for (const subscriber of this.timestampSubscribers) {
471
+ subscriber(item, key, ts);
472
+ }
473
+ }
474
+ }
475
+ class WindowedStreamImpl {
476
+ type = 'windowed-stream';
477
+ window;
478
+ key;
479
+ keyedStream;
480
+ ctx;
481
+ windowCloseHandlers = [];
482
+ windowState = new Map();
483
+ subscribers = [];
484
+ aggregateSpec;
485
+ reduceSpec;
486
+ constructor(keyedStream, windowSpec, ctx) {
487
+ this.keyedStream = keyedStream;
488
+ this.window = windowSpec;
489
+ this.ctx = ctx;
490
+ // Subscribe to keyed stream to receive items
491
+ this.keyedStream.subscribeWithTimestamp((item, key, timestamp) => {
492
+ this.processItem(item, timestamp);
493
+ });
494
+ this.ctx.registerWindowedStream(this);
495
+ }
496
+ aggregate(spec) {
497
+ this.aggregateSpec = spec;
498
+ return new AggregatedStreamImpl(this, this.ctx);
499
+ }
500
+ reduce(reducer, initial) {
501
+ this.reduceSpec = { reducer: reducer, initial };
502
+ return new AggregatedStreamImpl(this, this.ctx);
503
+ }
504
+ onWindowClose(handler) {
505
+ this.windowCloseHandlers.push(handler);
506
+ }
507
+ subscribe(fn) {
508
+ this.subscribers.push(fn);
509
+ return () => {
510
+ const idx = this.subscribers.indexOf(fn);
511
+ if (idx !== -1)
512
+ this.subscribers.splice(idx, 1);
513
+ };
514
+ }
515
+ async flush() {
516
+ // Trigger window close for all pending windows
517
+ for (const [windowKey, state] of this.windowState.entries()) {
518
+ const [key] = windowKey.split('|');
519
+ const windowInfo = this.computeWindowInfo(state.lastTimestamp);
520
+ for (const handler of this.windowCloseHandlers) {
521
+ handler(key, state.elements, windowInfo);
522
+ }
523
+ }
524
+ this.windowState.clear();
525
+ }
526
+ computeWindowInfo(timestamp) {
527
+ if (this.window.type === 'tumbling') {
528
+ const size = this.window.size;
529
+ const start = Math.floor(timestamp / size) * size;
530
+ return { start, end: start + size };
531
+ }
532
+ else if (this.window.type === 'sliding') {
533
+ const size = this.window.size;
534
+ const slide = this.window.slide;
535
+ const start = Math.floor(timestamp / slide) * slide;
536
+ return { start, end: start + size };
537
+ }
538
+ else {
539
+ // Session - approximate based on elements
540
+ return { start: timestamp, end: timestamp + (this.window.gap || 0) };
541
+ }
542
+ }
543
+ processItem(item, timestamp) {
544
+ const key = this.keyedStream.getKey(item);
545
+ const windowKeys = this.getWindowKeys(key, timestamp);
546
+ for (const windowKey of windowKeys) {
547
+ let state = this.windowState.get(windowKey);
548
+ if (!state) {
549
+ state = { elements: [], lastTimestamp: timestamp };
550
+ this.windowState.set(windowKey, state);
551
+ }
552
+ state.elements.push(item);
553
+ state.lastTimestamp = Math.max(state.lastTimestamp, timestamp);
554
+ }
555
+ for (const subscriber of this.subscribers) {
556
+ subscriber(item, key);
557
+ }
558
+ }
559
+ getWindowKeys(key, timestamp) {
560
+ if (this.window.type === 'tumbling') {
561
+ const size = this.window.size;
562
+ const windowStart = Math.floor(timestamp / size) * size;
563
+ return [`${key}|${windowStart}`];
564
+ }
565
+ else if (this.window.type === 'session') {
566
+ // For session windows, check if we should start a new session
567
+ const gap = this.window.gap;
568
+ // Find the current session for this key (if any)
569
+ let currentSession = null;
570
+ let currentLastTimestamp = -Infinity;
571
+ for (const [windowKey, state] of this.windowState.entries()) {
572
+ if (windowKey.startsWith(`${key}|session_`)) {
573
+ if (state.lastTimestamp > currentLastTimestamp) {
574
+ currentSession = windowKey;
575
+ currentLastTimestamp = state.lastTimestamp;
576
+ }
577
+ }
578
+ }
579
+ // If there's no current session, or the gap is too large, start a new session
580
+ if (currentSession === null || timestamp - currentLastTimestamp > gap) {
581
+ return [`${key}|session_${timestamp}`];
582
+ }
583
+ // Otherwise, add to the current session
584
+ return [currentSession];
585
+ }
586
+ else {
587
+ // Sliding window: item belongs to all windows where windowStart <= timestamp < windowStart + size
588
+ const size = this.window.size;
589
+ const slide = this.window.slide;
590
+ const keys = [];
591
+ // Find the earliest window that could contain this timestamp
592
+ // Window starts at multiples of slide
593
+ const earliestWindowStart = Math.floor((timestamp - size + 1) / slide) * slide;
594
+ const latestWindowStart = Math.floor(timestamp / slide) * slide;
595
+ for (let windowStart = Math.max(0, earliestWindowStart); windowStart <= latestWindowStart; windowStart += slide) {
596
+ if (timestamp >= windowStart && timestamp < windowStart + size) {
597
+ keys.push(`${key}|${windowStart}`);
598
+ }
599
+ }
600
+ return keys;
601
+ }
602
+ }
603
+ triggerWindowClose(currentTime) {
604
+ const windowsToClose = [];
605
+ for (const [windowKey, state] of this.windowState.entries()) {
606
+ const [key, windowId] = windowKey.split('|');
607
+ let shouldClose = false;
608
+ let windowInfo;
609
+ if (this.window.type === 'tumbling') {
610
+ const size = this.window.size;
611
+ const windowStart = parseInt(windowId);
612
+ const windowEnd = windowStart + size;
613
+ windowInfo = { start: windowStart, end: windowEnd };
614
+ shouldClose = currentTime >= windowEnd;
615
+ }
616
+ else if (this.window.type === 'sliding') {
617
+ const size = this.window.size;
618
+ const slide = this.window.slide;
619
+ const windowStart = parseInt(windowId);
620
+ const windowEnd = windowStart + size;
621
+ windowInfo = { start: windowStart, end: windowEnd };
622
+ shouldClose = currentTime >= windowEnd;
623
+ }
624
+ else {
625
+ // Session
626
+ const gap = this.window.gap;
627
+ windowInfo = { start: state.lastTimestamp - gap, end: state.lastTimestamp + gap };
628
+ shouldClose = currentTime >= state.lastTimestamp + gap;
629
+ }
630
+ if (shouldClose) {
631
+ windowsToClose.push({ key, windowKey, state });
632
+ }
633
+ }
634
+ for (const { key, windowKey, state } of windowsToClose) {
635
+ const windowInfo = this.computeWindowInfo(state.lastTimestamp);
636
+ for (const handler of this.windowCloseHandlers) {
637
+ handler(key, state.elements, windowInfo);
638
+ }
639
+ this.windowState.delete(windowKey);
640
+ }
641
+ }
642
+ getAggregateSpec() {
643
+ return this.aggregateSpec;
644
+ }
645
+ getReduceSpec() {
646
+ return this.reduceSpec;
647
+ }
648
+ getWindowState() {
649
+ return this.windowState;
650
+ }
651
+ getKeyedStream() {
652
+ return this.keyedStream;
653
+ }
654
+ }
655
+ class AggregatedStreamImpl {
656
+ type = 'stream';
657
+ sink;
658
+ windowedStream;
659
+ ctx;
660
+ subscribers = [];
661
+ mapFn;
662
+ constructor(windowedStream, ctx) {
663
+ this.windowedStream = windowedStream;
664
+ this.ctx = ctx;
665
+ this.ctx.registerAggregatedStream(this);
666
+ }
667
+ map(fn) {
668
+ const newStream = new AggregatedStreamImpl(this.windowedStream, this.ctx);
669
+ const prevMapFn = this.mapFn;
670
+ newStream.mapFn = (item) => {
671
+ const prev = prevMapFn ? prevMapFn(item) : item;
672
+ return fn(prev);
673
+ };
674
+ return newStream;
675
+ }
676
+ subscribe(fn) {
677
+ this.subscribers.push(fn);
678
+ return () => {
679
+ const idx = this.subscribers.indexOf(fn);
680
+ if (idx !== -1)
681
+ this.subscribers.splice(idx, 1);
682
+ };
683
+ }
684
+ async flush() {
685
+ // Advance time to trigger window closes
686
+ this.ctx.advanceTime(Date.now());
687
+ await this.windowedStream.flush();
688
+ }
689
+ get to() {
690
+ const self = this;
691
+ return {
692
+ track: new Proxy({}, {
693
+ get(_, event) {
694
+ self.sink = { type: 'track', event };
695
+ return self;
696
+ },
697
+ }),
698
+ measure: new Proxy({}, {
699
+ get(_, metric) {
700
+ self.sink = { type: 'measure', metric };
701
+ self.ctx.registerAggregatedSink(self, 'measure', metric);
702
+ return self;
703
+ },
704
+ }),
705
+ view: new Proxy({}, {
706
+ get(_, view) {
707
+ self.sink = { type: 'view', view };
708
+ self.ctx.registerAggregatedSink(self, 'view', view);
709
+ return self;
710
+ },
711
+ }),
712
+ };
713
+ }
714
+ emitResult(result, key, info) {
715
+ let finalResult = result;
716
+ if (this.mapFn) {
717
+ finalResult = this.mapFn(result);
718
+ }
719
+ for (const subscriber of this.subscribers) {
720
+ subscriber(finalResult, key, info);
721
+ }
722
+ }
723
+ getWindowedStream() {
724
+ return this.windowedStream;
725
+ }
726
+ }
727
+ class JoinBuilderImpl {
728
+ type = 'joined-stream';
729
+ window;
730
+ leftStream;
731
+ rightStream;
732
+ joinType;
733
+ ctx;
734
+ constructor(left, right, joinType, ctx) {
735
+ this.leftStream = left;
736
+ this.rightStream = right;
737
+ this.joinType = joinType;
738
+ this.ctx = ctx;
739
+ }
740
+ within(duration) {
741
+ this.window = toMillis(duration);
742
+ return this;
743
+ }
744
+ on(fn) {
745
+ const newStream = new StreamImpl({ type: 'domain' }, this.ctx);
746
+ this.ctx.registerJoin(this.leftStream, this.rightStream, this.window ?? Infinity, this.joinType, fn, newStream);
747
+ return newStream;
748
+ }
749
+ }
750
+ class CoGroupBuilderImpl {
751
+ type = 'joined-stream';
752
+ window;
753
+ leftStream;
754
+ rightStream;
755
+ ctx;
756
+ constructor(left, right, ctx) {
757
+ this.leftStream = left;
758
+ this.rightStream = right;
759
+ this.ctx = ctx;
760
+ }
761
+ within(duration) {
762
+ this.window = toMillis(duration);
763
+ return this;
764
+ }
765
+ apply(fn) {
766
+ const newStream = new StreamImpl({ type: 'domain' }, this.ctx);
767
+ this.ctx.registerCoGroup(this.leftStream, this.rightStream, this.window ?? Infinity, fn, newStream);
768
+ return newStream;
769
+ }
770
+ }
771
+ // ============================================================================
772
+ // Stream Context Implementation
773
+ // ============================================================================
774
+ class StreamContextImpl {
775
+ _storage = {
776
+ customers: new Map(),
777
+ };
778
+ trackHandlers = new Map();
779
+ measureHandlers = new Map();
780
+ entityActionHandlers = new Map();
781
+ streams = [];
782
+ keyedStreams = [];
783
+ windowedStreams = [];
784
+ aggregatedStreams = [];
785
+ namedStreams = new Map();
786
+ eventBuffer = new Map();
787
+ trackEventBuffer = new Map();
788
+ // Sink streams
789
+ sinkStreams = new Map();
790
+ aggregatedSinks = new Map();
791
+ // Joins
792
+ joins = [];
793
+ coGroups = [];
794
+ // Views storage
795
+ viewData = new Map();
796
+ _hooks = {
797
+ onTrack: (event, handler) => {
798
+ if (!this.trackHandlers.has(event))
799
+ this.trackHandlers.set(event, []);
800
+ this.trackHandlers.get(event).push(handler);
801
+ },
802
+ onMeasure: (metric, handler) => {
803
+ if (!this.measureHandlers.has(metric))
804
+ this.measureHandlers.set(metric, []);
805
+ this.measureHandlers.get(metric).push(handler);
806
+ },
807
+ onEntityAction: (entity, action, handler) => {
808
+ const key = `${entity}.${action}`;
809
+ if (!this.entityActionHandlers.has(key))
810
+ this.entityActionHandlers.set(key, []);
811
+ this.entityActionHandlers.get(key).push(handler);
812
+ },
813
+ };
814
+ // Handler getters for sink delivery
815
+ getTrackHandlers(event) {
816
+ return this.trackHandlers.get(event) ?? [];
817
+ }
818
+ getMeasureHandlers(metric) {
819
+ return this.measureHandlers.get(metric) ?? [];
820
+ }
821
+ getViewHandlers(view) {
822
+ // View handlers not currently implemented, return empty array
823
+ return [];
824
+ }
825
+ stream = {
826
+ from: new Proxy({}, {
827
+ get: (_, entity) => {
828
+ if (entity === 'track') {
829
+ return new Proxy({}, {
830
+ get: (_, event) => {
831
+ const stream = new StreamImpl({ type: 'track', event }, this);
832
+ this.registerStream(stream);
833
+ return stream;
834
+ },
835
+ });
836
+ }
837
+ if (entity === 'measure') {
838
+ return new Proxy({}, {
839
+ get: (_, metric) => {
840
+ const stream = new StreamImpl({ type: 'measure', metric }, this);
841
+ this.registerStream(stream);
842
+ return stream;
843
+ },
844
+ });
845
+ }
846
+ return new Proxy({}, {
847
+ get: (_, event) => {
848
+ const stream = new StreamImpl({ type: 'domain', entity, event }, this);
849
+ this.registerStream(stream);
850
+ return stream;
851
+ },
852
+ });
853
+ },
854
+ }),
855
+ emit: async (entity, event, data) => {
856
+ const timestamp = data?.timestamp ?? Date.now();
857
+ if (entity === 'track') {
858
+ const eventKey = event;
859
+ if (!this.trackEventBuffer.has(eventKey)) {
860
+ this.trackEventBuffer.set(eventKey, []);
861
+ }
862
+ this.trackEventBuffer.get(eventKey).push({ data, timestamp });
863
+ // Process through streams
864
+ for (const stream of this.streams) {
865
+ if (stream.source.type === 'track' && stream.source.event === event) {
866
+ await stream.processItem(data);
867
+ }
868
+ }
869
+ // Don't return - continue to process joins and coGroups below
870
+ }
871
+ else {
872
+ // Domain events
873
+ const eventKey = `${entity}.${event}`;
874
+ if (!this.eventBuffer.has(eventKey)) {
875
+ this.eventBuffer.set(eventKey, []);
876
+ }
877
+ this.eventBuffer.get(eventKey).push({ data, timestamp });
878
+ // Process through ROOT streams only (child streams get data via parent subscription)
879
+ for (const stream of this.streams) {
880
+ // Check if this stream matches the emit
881
+ const isMatchingSource =
882
+ // Domain events: $.stream.from.Order.created
883
+ ((stream.source.entity === entity || stream.source.entity === '*') &&
884
+ (stream.source.event === event || stream.source.event === '*'));
885
+ if (stream.isRootStream() && isMatchingSource) {
886
+ await stream.processItem(data);
887
+ }
888
+ }
889
+ }
890
+ // NOTE: keyed streams and windowed streams receive data through parent subscriptions
891
+ // They don't need direct processing here anymore
892
+ // Process joins
893
+ for (const join of this.joins) {
894
+ const leftKey = join.left.getKey(data);
895
+ const rightKey = join.right.getKey?.(data);
896
+ // Check if this event matches left stream
897
+ const leftSource = join.left.parentStream?.source;
898
+ const leftSourceMatches = (leftSource?.entity === entity && leftSource?.event === event) ||
899
+ (leftSource?.type === 'track' && entity === 'track' && leftSource?.event === event);
900
+ if (leftSourceMatches) {
901
+ join.leftBuffer.set(leftKey, join.leftBuffer.get(leftKey) ?? []);
902
+ join.leftBuffer.get(leftKey).push({ data, timestamp });
903
+ // Try to match with right buffer
904
+ const rightMatches = join.rightBuffer.get(leftKey) ?? [];
905
+ for (const rightItem of rightMatches) {
906
+ if (Math.abs(timestamp - rightItem.timestamp) <= join.window) {
907
+ const result = join.mapper(data, rightItem.data);
908
+ await join.output.processItem(result);
909
+ }
910
+ }
911
+ }
912
+ // Check if this event matches right stream
913
+ const rightSource = join.right.parentStream?.source;
914
+ const rightSourceMatches = (rightSource?.entity === entity && rightSource?.event === event) ||
915
+ (rightSource?.type === 'track' && entity === 'track' && rightSource?.event === event);
916
+ if (rightSourceMatches) {
917
+ if (rightKey) {
918
+ join.rightBuffer.set(rightKey, join.rightBuffer.get(rightKey) ?? []);
919
+ join.rightBuffer.get(rightKey).push({ data, timestamp });
920
+ // Try to match with left buffer
921
+ const leftMatches = join.leftBuffer.get(rightKey) ?? [];
922
+ for (const leftItem of leftMatches) {
923
+ if (Math.abs(timestamp - leftItem.timestamp) <= join.window) {
924
+ const result = join.mapper(leftItem.data, data);
925
+ await join.output.processItem(result);
926
+ }
927
+ }
928
+ }
929
+ }
930
+ }
931
+ // Process coGroups
932
+ for (const coGroup of this.coGroups) {
933
+ const leftKey = coGroup.left.getKey(data);
934
+ const rightKey = coGroup.right.getKey?.(data);
935
+ const leftSource = coGroup.left.parentStream?.source;
936
+ const leftSourceMatches = (leftSource?.entity === entity && leftSource?.event === event) ||
937
+ (leftSource?.type === 'track' && entity === 'track' && leftSource?.event === event);
938
+ if (leftSourceMatches) {
939
+ coGroup.leftBuffer.set(leftKey, coGroup.leftBuffer.get(leftKey) ?? []);
940
+ coGroup.leftBuffer.get(leftKey).push({ data, timestamp });
941
+ }
942
+ const rightSource = coGroup.right.parentStream?.source;
943
+ const rightSourceMatches = (rightSource?.entity === entity && rightSource?.event === event) ||
944
+ (rightSource?.type === 'track' && entity === 'track' && rightSource?.event === event);
945
+ if (rightSourceMatches) {
946
+ if (rightKey) {
947
+ coGroup.rightBuffer.set(rightKey, coGroup.rightBuffer.get(rightKey) ?? []);
948
+ coGroup.rightBuffer.get(rightKey).push({ data, timestamp });
949
+ }
950
+ }
951
+ }
952
+ },
953
+ get: (name) => this.namedStreams.get(name),
954
+ };
955
+ registerStream(stream) {
956
+ this.streams.push(stream);
957
+ }
958
+ registerKeyedStream(stream) {
959
+ this.keyedStreams.push(stream);
960
+ }
961
+ registerWindowedStream(stream) {
962
+ this.windowedStreams.push(stream);
963
+ }
964
+ registerAggregatedStream(stream) {
965
+ this.aggregatedStreams.push(stream);
966
+ }
967
+ registerSinkStream(stream, type, name) {
968
+ const key = `${type}.${name}`;
969
+ if (!this.sinkStreams.has(key))
970
+ this.sinkStreams.set(key, []);
971
+ this.sinkStreams.get(key).push(stream);
972
+ }
973
+ registerAggregatedSink(stream, type, name) {
974
+ const key = `${type}.${name}`;
975
+ if (!this.aggregatedSinks.has(key))
976
+ this.aggregatedSinks.set(key, []);
977
+ this.aggregatedSinks.get(key).push(stream);
978
+ }
979
+ registerJoin(left, right, window, joinType, mapper, output) {
980
+ this.joins.push({
981
+ left,
982
+ right,
983
+ window,
984
+ joinType,
985
+ mapper,
986
+ output,
987
+ leftBuffer: new Map(),
988
+ rightBuffer: new Map(),
989
+ });
990
+ }
991
+ registerCoGroup(left, right, window, mapper, output) {
992
+ this.coGroups.push({
993
+ left,
994
+ right,
995
+ window,
996
+ mapper,
997
+ output,
998
+ leftBuffer: new Map(),
999
+ rightBuffer: new Map(),
1000
+ });
1001
+ }
1002
+ // Aggregation helpers
1003
+ count() {
1004
+ return { type: 'count' };
1005
+ }
1006
+ sum(field) {
1007
+ return { type: 'sum', field };
1008
+ }
1009
+ avg(field) {
1010
+ return { type: 'avg', field };
1011
+ }
1012
+ min(field) {
1013
+ return { type: 'min', field };
1014
+ }
1015
+ max(field) {
1016
+ return { type: 'max', field };
1017
+ }
1018
+ first() {
1019
+ return { type: 'first' };
1020
+ }
1021
+ last() {
1022
+ return { type: 'last' };
1023
+ }
1024
+ collect() {
1025
+ return { type: 'collect' };
1026
+ }
1027
+ distinct(field) {
1028
+ return { type: 'distinct', field };
1029
+ }
1030
+ // Entity proxies
1031
+ Customer = this.createEntityProxy('Customer');
1032
+ Order = this.createEntityProxy('Order');
1033
+ Payment = this.createEntityProxy('Payment');
1034
+ createEntityProxy(entityName) {
1035
+ return (id) => ({
1036
+ get: async () => {
1037
+ const storage = this._storage[entityName.toLowerCase() + 's'] ?? this._storage.customers;
1038
+ return storage.get(id);
1039
+ },
1040
+ notify: async (payload) => {
1041
+ const handlers = this.entityActionHandlers.get(`${entityName}.notify`) ?? [];
1042
+ for (const handler of handlers) {
1043
+ handler(id, payload);
1044
+ }
1045
+ },
1046
+ });
1047
+ }
1048
+ // View namespace
1049
+ view = new Proxy({}, {
1050
+ get: (_, viewName) => {
1051
+ if (!this.viewData.has(viewName)) {
1052
+ this.viewData.set(viewName, new Map());
1053
+ }
1054
+ const viewStore = this.viewData.get(viewName);
1055
+ return {
1056
+ get: async (key) => viewStore.get(key),
1057
+ set: async (key, value) => viewStore.set(key, value),
1058
+ };
1059
+ },
1060
+ });
1061
+ // Trigger window processing (called when time advances)
1062
+ advanceTime(currentTime) {
1063
+ for (const windowedStream of this.windowedStreams) {
1064
+ // Process aggregations BEFORE triggering window close (which deletes the state)
1065
+ const aggregateSpec = windowedStream.getAggregateSpec();
1066
+ const reduceSpec = windowedStream.getReduceSpec();
1067
+ const windowState = windowedStream.getWindowState();
1068
+ if (aggregateSpec || reduceSpec) {
1069
+ for (const [windowKey, state] of windowState.entries()) {
1070
+ const [key, windowId] = windowKey.split('|');
1071
+ let shouldClose = false;
1072
+ let windowInfo;
1073
+ if (windowedStream.window.type === 'tumbling') {
1074
+ const size = windowedStream.window.size;
1075
+ const windowStart = parseInt(windowId);
1076
+ const windowEnd = windowStart + size;
1077
+ windowInfo = { start: windowStart, end: windowEnd };
1078
+ shouldClose = currentTime >= windowEnd;
1079
+ }
1080
+ else if (windowedStream.window.type === 'sliding') {
1081
+ const size = windowedStream.window.size;
1082
+ const slide = windowedStream.window.slide;
1083
+ const windowStart = parseInt(windowId);
1084
+ const windowEnd = windowStart + size;
1085
+ windowInfo = { start: windowStart, end: windowEnd };
1086
+ shouldClose = currentTime >= windowEnd;
1087
+ }
1088
+ else {
1089
+ const gap = windowedStream.window.gap;
1090
+ windowInfo = { start: state.lastTimestamp - gap, end: state.lastTimestamp + gap };
1091
+ shouldClose = currentTime >= state.lastTimestamp + gap;
1092
+ }
1093
+ if (shouldClose) {
1094
+ let result;
1095
+ if (aggregateSpec) {
1096
+ result = this.computeAggregation(aggregateSpec, state.elements, key);
1097
+ }
1098
+ else if (reduceSpec) {
1099
+ result = state.elements.reduce((acc, item) => reduceSpec.reducer(acc, item), reduceSpec.initial);
1100
+ }
1101
+ // Emit to aggregated streams
1102
+ for (const aggStream of this.aggregatedStreams) {
1103
+ if (aggStream.getWindowedStream() === windowedStream) {
1104
+ aggStream.emitResult(result, key, windowInfo);
1105
+ // Handle sinks
1106
+ if (aggStream.sink?.type === 'measure') {
1107
+ const handlers = this.measureHandlers.get(aggStream.sink.metric) ?? [];
1108
+ const value = typeof result === 'object' ? result.revenue ?? result.count ?? 0 : 0;
1109
+ for (const handler of handlers) {
1110
+ handler(value, { region: key });
1111
+ }
1112
+ }
1113
+ if (aggStream.sink?.type === 'view') {
1114
+ const viewName = aggStream.sink.view;
1115
+ if (!this.viewData.has(viewName)) {
1116
+ this.viewData.set(viewName, new Map());
1117
+ }
1118
+ this.viewData.get(viewName).set(key, result);
1119
+ }
1120
+ }
1121
+ }
1122
+ }
1123
+ }
1124
+ }
1125
+ // Trigger window close AFTER processing aggregations (this clears the state)
1126
+ windowedStream.triggerWindowClose(currentTime);
1127
+ }
1128
+ // Process left joins (emit unmatched left elements after window expires)
1129
+ for (const join of this.joins) {
1130
+ if (join.joinType === 'left') {
1131
+ for (const [key, leftItems] of join.leftBuffer.entries()) {
1132
+ const rightItems = join.rightBuffer.get(key) ?? [];
1133
+ for (const leftItem of leftItems) {
1134
+ if (currentTime - leftItem.timestamp > join.window) {
1135
+ // Check if there was a match
1136
+ const hasMatch = rightItems.some((r) => Math.abs(leftItem.timestamp - r.timestamp) <= join.window);
1137
+ if (!hasMatch) {
1138
+ const result = join.mapper(leftItem.data, null);
1139
+ join.output.processItem(result);
1140
+ }
1141
+ }
1142
+ }
1143
+ }
1144
+ }
1145
+ }
1146
+ // Process coGroups
1147
+ for (const coGroup of this.coGroups) {
1148
+ const allKeys = new Set([
1149
+ ...coGroup.leftBuffer.keys(),
1150
+ ...coGroup.rightBuffer.keys(),
1151
+ ]);
1152
+ for (const key of allKeys) {
1153
+ const leftItems = coGroup.leftBuffer.get(key) ?? [];
1154
+ const rightItems = coGroup.rightBuffer.get(key) ?? [];
1155
+ // Check if any items are past the window
1156
+ const expiredLeft = leftItems.filter((i) => currentTime - i.timestamp > coGroup.window);
1157
+ const expiredRight = rightItems.filter((i) => currentTime - i.timestamp > coGroup.window);
1158
+ if (expiredLeft.length > 0 || expiredRight.length > 0) {
1159
+ const result = coGroup.mapper(leftItems.map((i) => i.data), rightItems.map((i) => i.data));
1160
+ coGroup.output.processItem(result);
1161
+ // Clear processed items
1162
+ coGroup.leftBuffer.delete(key);
1163
+ coGroup.rightBuffer.delete(key);
1164
+ }
1165
+ }
1166
+ }
1167
+ }
1168
+ computeAggregation(spec, elements, key) {
1169
+ const result = { key };
1170
+ for (const [name, aggSpec] of Object.entries(spec)) {
1171
+ switch (aggSpec.type) {
1172
+ case 'count':
1173
+ result[name] = elements.length;
1174
+ break;
1175
+ case 'sum':
1176
+ result[name] = elements.reduce((sum, el) => sum + (el[aggSpec.field] ?? 0), 0);
1177
+ break;
1178
+ case 'avg':
1179
+ result[name] =
1180
+ elements.length > 0
1181
+ ? elements.reduce((sum, el) => sum + (el[aggSpec.field] ?? 0), 0) /
1182
+ elements.length
1183
+ : 0;
1184
+ break;
1185
+ case 'min':
1186
+ result[name] = Math.min(...elements.map((el) => el[aggSpec.field] ?? Infinity));
1187
+ break;
1188
+ case 'max':
1189
+ result[name] = Math.max(...elements.map((el) => el[aggSpec.field] ?? -Infinity));
1190
+ break;
1191
+ case 'first':
1192
+ result[name] = elements[0];
1193
+ break;
1194
+ case 'last':
1195
+ result[name] = elements[elements.length - 1];
1196
+ break;
1197
+ case 'collect':
1198
+ result[name] = [...elements];
1199
+ break;
1200
+ case 'distinct':
1201
+ result[name] = new Set(elements.map((el) => el[aggSpec.field])).size;
1202
+ break;
1203
+ }
1204
+ }
1205
+ return result;
1206
+ }
1207
+ }
1208
+ // ============================================================================
1209
+ // Factory
1210
+ // ============================================================================
1211
+ export function createStreamContext() {
1212
+ const ctx = new StreamContextImpl();
1213
+ return ctx;
1214
+ }
1215
+ //# sourceMappingURL=index.js.map