@shware/workflow 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -2
  3. package/dist/_virtual/_rolldown/runtime.cjs +23 -0
  4. package/dist/apns-relay.cjs +105 -0
  5. package/dist/apns-relay.cjs.map +1 -0
  6. package/dist/apns-relay.d.cts +28 -0
  7. package/dist/apns-relay.d.cts.map +1 -0
  8. package/dist/apns-relay.d.mts +28 -0
  9. package/dist/apns-relay.d.mts.map +1 -0
  10. package/dist/apns-relay.mjs +104 -0
  11. package/dist/apns-relay.mjs.map +1 -0
  12. package/dist/apns.cjs +121 -0
  13. package/dist/apns.cjs.map +1 -0
  14. package/dist/apns.d.cts +63 -0
  15. package/dist/apns.d.cts.map +1 -0
  16. package/dist/apns.d.mts +63 -0
  17. package/dist/apns.d.mts.map +1 -0
  18. package/dist/apns.mjs +116 -0
  19. package/dist/apns.mjs.map +1 -0
  20. package/dist/client.cjs +125 -0
  21. package/dist/client.cjs.map +1 -0
  22. package/dist/client.d.cts +108 -0
  23. package/dist/client.d.cts.map +1 -0
  24. package/dist/client.d.mts +108 -0
  25. package/dist/client.d.mts.map +1 -0
  26. package/dist/client.mjs +122 -0
  27. package/dist/client.mjs.map +1 -0
  28. package/dist/cloudflare/bindings.cjs +28 -0
  29. package/dist/cloudflare/bindings.cjs.map +1 -0
  30. package/dist/cloudflare/bindings.d.cts +144 -0
  31. package/dist/cloudflare/bindings.d.cts.map +1 -0
  32. package/dist/cloudflare/bindings.d.mts +144 -0
  33. package/dist/cloudflare/bindings.d.mts.map +1 -0
  34. package/dist/cloudflare/bindings.mjs +25 -0
  35. package/dist/cloudflare/bindings.mjs.map +1 -0
  36. package/dist/cloudflare/channels.cjs +164 -0
  37. package/dist/cloudflare/channels.cjs.map +1 -0
  38. package/dist/cloudflare/channels.d.cts +29 -0
  39. package/dist/cloudflare/channels.d.cts.map +1 -0
  40. package/dist/cloudflare/channels.d.mts +29 -0
  41. package/dist/cloudflare/channels.d.mts.map +1 -0
  42. package/dist/cloudflare/channels.mjs +161 -0
  43. package/dist/cloudflare/channels.mjs.map +1 -0
  44. package/dist/cloudflare/d1-env.cjs +17 -0
  45. package/dist/cloudflare/d1-env.cjs.map +1 -0
  46. package/dist/cloudflare/d1-env.d.cts +12 -0
  47. package/dist/cloudflare/d1-env.d.cts.map +1 -0
  48. package/dist/cloudflare/d1-env.d.mts +12 -0
  49. package/dist/cloudflare/d1-env.d.mts.map +1 -0
  50. package/dist/cloudflare/d1-env.mjs +16 -0
  51. package/dist/cloudflare/d1-env.mjs.map +1 -0
  52. package/dist/cloudflare/index.cjs +54 -0
  53. package/dist/cloudflare/index.d.cts +19 -0
  54. package/dist/cloudflare/index.d.mts +19 -0
  55. package/dist/cloudflare/index.mjs +16 -0
  56. package/dist/cloudflare/router.cjs +516 -0
  57. package/dist/cloudflare/router.cjs.map +1 -0
  58. package/dist/cloudflare/router.d.cts +157 -0
  59. package/dist/cloudflare/router.d.cts.map +1 -0
  60. package/dist/cloudflare/router.d.mts +157 -0
  61. package/dist/cloudflare/router.d.mts.map +1 -0
  62. package/dist/cloudflare/router.mjs +503 -0
  63. package/dist/cloudflare/router.mjs.map +1 -0
  64. package/dist/cloudflare/runner.cjs +225 -0
  65. package/dist/cloudflare/runner.cjs.map +1 -0
  66. package/dist/cloudflare/runner.d.cts +73 -0
  67. package/dist/cloudflare/runner.d.cts.map +1 -0
  68. package/dist/cloudflare/runner.d.mts +73 -0
  69. package/dist/cloudflare/runner.d.mts.map +1 -0
  70. package/dist/cloudflare/runner.mjs +224 -0
  71. package/dist/cloudflare/runner.mjs.map +1 -0
  72. package/dist/cloudflare/schema.sql +127 -0
  73. package/dist/cloudflare/senders.cjs +114 -0
  74. package/dist/cloudflare/senders.cjs.map +1 -0
  75. package/dist/cloudflare/senders.d.cts +68 -0
  76. package/dist/cloudflare/senders.d.cts.map +1 -0
  77. package/dist/cloudflare/senders.d.mts +68 -0
  78. package/dist/cloudflare/senders.d.mts.map +1 -0
  79. package/dist/cloudflare/senders.mjs +108 -0
  80. package/dist/cloudflare/senders.mjs.map +1 -0
  81. package/dist/cloudflare/worker.cjs +228 -0
  82. package/dist/cloudflare/worker.cjs.map +1 -0
  83. package/dist/cloudflare/worker.d.cts +92 -0
  84. package/dist/cloudflare/worker.d.cts.map +1 -0
  85. package/dist/cloudflare/worker.d.mts +92 -0
  86. package/dist/cloudflare/worker.d.mts.map +1 -0
  87. package/dist/cloudflare/worker.mjs +224 -0
  88. package/dist/cloudflare/worker.mjs.map +1 -0
  89. package/dist/cloudflare/workers.d.cjs +0 -0
  90. package/dist/cloudflare/workers.d.cts +44 -0
  91. package/dist/cloudflare/workers.d.cts.map +1 -0
  92. package/dist/cloudflare/workers.d.mts +44 -0
  93. package/dist/cloudflare/workers.d.mts.map +1 -0
  94. package/dist/config.cjs +151 -0
  95. package/dist/config.cjs.map +1 -0
  96. package/dist/config.d.cts +149 -0
  97. package/dist/config.d.cts.map +1 -0
  98. package/dist/config.d.mts +149 -0
  99. package/dist/config.d.mts.map +1 -0
  100. package/dist/config.mjs +143 -0
  101. package/dist/config.mjs.map +1 -0
  102. package/dist/contract.cjs +212 -0
  103. package/dist/contract.cjs.map +1 -0
  104. package/dist/contract.d.cts +90 -0
  105. package/dist/contract.d.cts.map +1 -0
  106. package/dist/contract.d.mts +90 -0
  107. package/dist/contract.d.mts.map +1 -0
  108. package/dist/contract.mjs +206 -0
  109. package/dist/contract.mjs.map +1 -0
  110. package/dist/dsl/action.cjs +29 -0
  111. package/dist/dsl/action.cjs.map +1 -0
  112. package/dist/dsl/action.d.cts +64 -0
  113. package/dist/dsl/action.d.cts.map +1 -0
  114. package/dist/dsl/action.d.mts +64 -0
  115. package/dist/dsl/action.d.mts.map +1 -0
  116. package/dist/dsl/action.mjs +28 -0
  117. package/dist/dsl/action.mjs.map +1 -0
  118. package/dist/dsl/base.cjs +34 -0
  119. package/dist/dsl/base.cjs.map +1 -0
  120. package/dist/dsl/base.d.cts +45 -0
  121. package/dist/dsl/base.d.cts.map +1 -0
  122. package/dist/dsl/base.d.mts +45 -0
  123. package/dist/dsl/base.d.mts.map +1 -0
  124. package/dist/dsl/base.mjs +30 -0
  125. package/dist/dsl/base.mjs.map +1 -0
  126. package/dist/dsl/bundle.cjs +207 -0
  127. package/dist/dsl/bundle.cjs.map +1 -0
  128. package/dist/dsl/bundle.d.cts +19 -0
  129. package/dist/dsl/bundle.d.cts.map +1 -0
  130. package/dist/dsl/bundle.d.mts +19 -0
  131. package/dist/dsl/bundle.d.mts.map +1 -0
  132. package/dist/dsl/bundle.mjs +206 -0
  133. package/dist/dsl/bundle.mjs.map +1 -0
  134. package/dist/dsl/condition.cjs +177 -0
  135. package/dist/dsl/condition.cjs.map +1 -0
  136. package/dist/dsl/condition.d.cts +140 -0
  137. package/dist/dsl/condition.d.cts.map +1 -0
  138. package/dist/dsl/condition.d.mts +140 -0
  139. package/dist/dsl/condition.d.mts.map +1 -0
  140. package/dist/dsl/condition.mjs +156 -0
  141. package/dist/dsl/condition.mjs.map +1 -0
  142. package/dist/dsl/flow.cjs +228 -0
  143. package/dist/dsl/flow.cjs.map +1 -0
  144. package/dist/dsl/flow.d.cts +223 -0
  145. package/dist/dsl/flow.d.cts.map +1 -0
  146. package/dist/dsl/flow.d.mts +223 -0
  147. package/dist/dsl/flow.d.mts.map +1 -0
  148. package/dist/dsl/flow.mjs +226 -0
  149. package/dist/dsl/flow.mjs.map +1 -0
  150. package/dist/dsl/index.cjs +38 -0
  151. package/dist/dsl/index.d.cts +10 -0
  152. package/dist/dsl/index.d.mts +10 -0
  153. package/dist/dsl/index.mjs +9 -0
  154. package/dist/dsl/refs.cjs +59 -0
  155. package/dist/dsl/refs.cjs.map +1 -0
  156. package/dist/dsl/refs.d.cts +88 -0
  157. package/dist/dsl/refs.d.cts.map +1 -0
  158. package/dist/dsl/refs.d.mts +88 -0
  159. package/dist/dsl/refs.d.mts.map +1 -0
  160. package/dist/dsl/refs.mjs +55 -0
  161. package/dist/dsl/refs.mjs.map +1 -0
  162. package/dist/dsl/template.cjs +65 -0
  163. package/dist/dsl/template.cjs.map +1 -0
  164. package/dist/dsl/template.d.cts +75 -0
  165. package/dist/dsl/template.d.cts.map +1 -0
  166. package/dist/dsl/template.d.mts +75 -0
  167. package/dist/dsl/template.d.mts.map +1 -0
  168. package/dist/dsl/template.mjs +63 -0
  169. package/dist/dsl/template.mjs.map +1 -0
  170. package/dist/dsl/trigger.cjs +40 -0
  171. package/dist/dsl/trigger.cjs.map +1 -0
  172. package/dist/dsl/trigger.d.cts +65 -0
  173. package/dist/dsl/trigger.d.cts.map +1 -0
  174. package/dist/dsl/trigger.d.mts +65 -0
  175. package/dist/dsl/trigger.d.mts.map +1 -0
  176. package/dist/dsl/trigger.mjs +39 -0
  177. package/dist/dsl/trigger.mjs.map +1 -0
  178. package/dist/dsl/workflow.cjs +121 -0
  179. package/dist/dsl/workflow.cjs.map +1 -0
  180. package/dist/dsl/workflow.d.cts +59 -0
  181. package/dist/dsl/workflow.d.cts.map +1 -0
  182. package/dist/dsl/workflow.d.mts +59 -0
  183. package/dist/dsl/workflow.d.mts.map +1 -0
  184. package/dist/dsl/workflow.mjs +120 -0
  185. package/dist/dsl/workflow.mjs.map +1 -0
  186. package/dist/engine/actions.cjs +27 -0
  187. package/dist/engine/actions.cjs.map +1 -0
  188. package/dist/engine/actions.d.cts +40 -0
  189. package/dist/engine/actions.d.cts.map +1 -0
  190. package/dist/engine/actions.d.mts +40 -0
  191. package/dist/engine/actions.d.mts.map +1 -0
  192. package/dist/engine/actions.mjs +26 -0
  193. package/dist/engine/actions.mjs.map +1 -0
  194. package/dist/engine/bucket.cjs +72 -0
  195. package/dist/engine/bucket.cjs.map +1 -0
  196. package/dist/engine/bucket.d.cts +32 -0
  197. package/dist/engine/bucket.d.cts.map +1 -0
  198. package/dist/engine/bucket.d.mts +32 -0
  199. package/dist/engine/bucket.d.mts.map +1 -0
  200. package/dist/engine/bucket.mjs +69 -0
  201. package/dist/engine/bucket.mjs.map +1 -0
  202. package/dist/engine/condition.cjs +166 -0
  203. package/dist/engine/condition.cjs.map +1 -0
  204. package/dist/engine/condition.d.cts +52 -0
  205. package/dist/engine/condition.d.cts.map +1 -0
  206. package/dist/engine/condition.d.mts +52 -0
  207. package/dist/engine/condition.d.mts.map +1 -0
  208. package/dist/engine/condition.mjs +161 -0
  209. package/dist/engine/condition.mjs.map +1 -0
  210. package/dist/engine/index.cjs +20 -0
  211. package/dist/engine/index.d.cts +8 -0
  212. package/dist/engine/index.d.mts +8 -0
  213. package/dist/engine/index.mjs +7 -0
  214. package/dist/engine/interpreter.cjs +428 -0
  215. package/dist/engine/interpreter.cjs.map +1 -0
  216. package/dist/engine/interpreter.d.cts +6 -0
  217. package/dist/engine/interpreter.d.cts.map +1 -0
  218. package/dist/engine/interpreter.d.mts +6 -0
  219. package/dist/engine/interpreter.d.mts.map +1 -0
  220. package/dist/engine/interpreter.mjs +427 -0
  221. package/dist/engine/interpreter.mjs.map +1 -0
  222. package/dist/engine/ports.cjs +0 -0
  223. package/dist/engine/ports.d.cts +252 -0
  224. package/dist/engine/ports.d.cts.map +1 -0
  225. package/dist/engine/ports.d.mts +252 -0
  226. package/dist/engine/ports.d.mts.map +1 -0
  227. package/dist/engine/ports.mjs +1 -0
  228. package/dist/engine/recipient.cjs +23 -0
  229. package/dist/engine/recipient.cjs.map +1 -0
  230. package/dist/engine/recipient.d.cts +13 -0
  231. package/dist/engine/recipient.d.cts.map +1 -0
  232. package/dist/engine/recipient.d.mts +13 -0
  233. package/dist/engine/recipient.d.mts.map +1 -0
  234. package/dist/engine/recipient.mjs +22 -0
  235. package/dist/engine/recipient.mjs.map +1 -0
  236. package/dist/engine/time-scale.cjs +54 -0
  237. package/dist/engine/time-scale.cjs.map +1 -0
  238. package/dist/engine/time-scale.d.cts +31 -0
  239. package/dist/engine/time-scale.d.cts.map +1 -0
  240. package/dist/engine/time-scale.d.mts +31 -0
  241. package/dist/engine/time-scale.d.mts.map +1 -0
  242. package/dist/engine/time-scale.mjs +52 -0
  243. package/dist/engine/time-scale.mjs.map +1 -0
  244. package/dist/engine/time-window.cjs +149 -0
  245. package/dist/engine/time-window.cjs.map +1 -0
  246. package/dist/engine/time-window.d.cts +22 -0
  247. package/dist/engine/time-window.d.cts.map +1 -0
  248. package/dist/engine/time-window.d.mts +22 -0
  249. package/dist/engine/time-window.d.mts.map +1 -0
  250. package/dist/engine/time-window.mjs +147 -0
  251. package/dist/engine/time-window.mjs.map +1 -0
  252. package/dist/fcm.cjs +125 -0
  253. package/dist/fcm.cjs.map +1 -0
  254. package/dist/fcm.d.cts +48 -0
  255. package/dist/fcm.d.cts.map +1 -0
  256. package/dist/fcm.d.mts +48 -0
  257. package/dist/fcm.d.mts.map +1 -0
  258. package/dist/fcm.mjs +121 -0
  259. package/dist/fcm.mjs.map +1 -0
  260. package/dist/hash.cjs +245 -0
  261. package/dist/hash.cjs.map +1 -0
  262. package/dist/hash.d.cts +30 -0
  263. package/dist/hash.d.cts.map +1 -0
  264. package/dist/hash.d.mts +30 -0
  265. package/dist/hash.d.mts.map +1 -0
  266. package/dist/hash.mjs +239 -0
  267. package/dist/hash.mjs.map +1 -0
  268. package/dist/index.cjs +100 -0
  269. package/dist/index.d.cts +18 -0
  270. package/dist/index.d.mts +18 -0
  271. package/dist/index.mjs +17 -0
  272. package/dist/ir.cjs +366 -0
  273. package/dist/ir.cjs.map +1 -0
  274. package/dist/ir.d.cts +486 -0
  275. package/dist/ir.d.cts.map +1 -0
  276. package/dist/ir.d.mts +486 -0
  277. package/dist/ir.d.mts.map +1 -0
  278. package/dist/ir.mjs +344 -0
  279. package/dist/ir.mjs.map +1 -0
  280. package/dist/jwt.cjs +22 -0
  281. package/dist/jwt.cjs.map +1 -0
  282. package/dist/jwt.d.cts +9 -0
  283. package/dist/jwt.d.cts.map +1 -0
  284. package/dist/jwt.d.mts +9 -0
  285. package/dist/jwt.d.mts.map +1 -0
  286. package/dist/jwt.mjs +20 -0
  287. package/dist/jwt.mjs.map +1 -0
  288. package/dist/plan.cjs +223 -0
  289. package/dist/plan.cjs.map +1 -0
  290. package/dist/plan.d.cts +68 -0
  291. package/dist/plan.d.cts.map +1 -0
  292. package/dist/plan.d.mts +68 -0
  293. package/dist/plan.d.mts.map +1 -0
  294. package/dist/plan.mjs +221 -0
  295. package/dist/plan.mjs.map +1 -0
  296. package/dist/postgres-js.cjs +42 -0
  297. package/dist/postgres-js.cjs.map +1 -0
  298. package/dist/postgres-js.d.cts +28 -0
  299. package/dist/postgres-js.d.cts.map +1 -0
  300. package/dist/postgres-js.d.mts +28 -0
  301. package/dist/postgres-js.d.mts.map +1 -0
  302. package/dist/postgres-js.mjs +38 -0
  303. package/dist/postgres-js.mjs.map +1 -0
  304. package/dist/provenance.cjs +67 -0
  305. package/dist/provenance.cjs.map +1 -0
  306. package/dist/provenance.d.cts +41 -0
  307. package/dist/provenance.d.cts.map +1 -0
  308. package/dist/provenance.d.mts +41 -0
  309. package/dist/provenance.d.mts.map +1 -0
  310. package/dist/provenance.mjs +65 -0
  311. package/dist/provenance.mjs.map +1 -0
  312. package/dist/push.cjs +14 -0
  313. package/dist/push.cjs.map +1 -0
  314. package/dist/push.d.cts +16 -0
  315. package/dist/push.d.cts.map +1 -0
  316. package/dist/push.d.mts +16 -0
  317. package/dist/push.d.mts.map +1 -0
  318. package/dist/push.mjs +13 -0
  319. package/dist/push.mjs.map +1 -0
  320. package/dist/react-email.cjs +48 -0
  321. package/dist/react-email.cjs.map +1 -0
  322. package/dist/react-email.d.cts +7 -0
  323. package/dist/react-email.d.cts.map +1 -0
  324. package/dist/react-email.d.mts +7 -0
  325. package/dist/react-email.d.mts.map +1 -0
  326. package/dist/react-email.mjs +47 -0
  327. package/dist/react-email.mjs.map +1 -0
  328. package/dist/reporting/classify.cjs +42 -0
  329. package/dist/reporting/classify.cjs.map +1 -0
  330. package/dist/reporting/classify.d.cts +60 -0
  331. package/dist/reporting/classify.d.cts.map +1 -0
  332. package/dist/reporting/classify.d.mts +60 -0
  333. package/dist/reporting/classify.d.mts.map +1 -0
  334. package/dist/reporting/classify.mjs +38 -0
  335. package/dist/reporting/classify.mjs.map +1 -0
  336. package/dist/reporting/observer.cjs +63 -0
  337. package/dist/reporting/observer.cjs.map +1 -0
  338. package/dist/reporting/observer.d.cts +18 -0
  339. package/dist/reporting/observer.d.cts.map +1 -0
  340. package/dist/reporting/observer.d.mts +18 -0
  341. package/dist/reporting/observer.d.mts.map +1 -0
  342. package/dist/reporting/observer.mjs +62 -0
  343. package/dist/reporting/observer.mjs.map +1 -0
  344. package/dist/reporting/tracking.cjs +153 -0
  345. package/dist/reporting/tracking.cjs.map +1 -0
  346. package/dist/reporting/tracking.d.cts +43 -0
  347. package/dist/reporting/tracking.d.cts.map +1 -0
  348. package/dist/reporting/tracking.d.mts +43 -0
  349. package/dist/reporting/tracking.d.mts.map +1 -0
  350. package/dist/reporting/tracking.mjs +151 -0
  351. package/dist/reporting/tracking.mjs.map +1 -0
  352. package/dist/runtime.cjs +19 -0
  353. package/dist/runtime.cjs.map +1 -0
  354. package/dist/runtime.d.cts +30 -0
  355. package/dist/runtime.d.cts.map +1 -0
  356. package/dist/runtime.d.mts +30 -0
  357. package/dist/runtime.d.mts.map +1 -0
  358. package/dist/runtime.mjs +18 -0
  359. package/dist/runtime.mjs.map +1 -0
  360. package/dist/store/d1.cjs +185 -0
  361. package/dist/store/d1.cjs.map +1 -0
  362. package/dist/store/d1.d.cts +55 -0
  363. package/dist/store/d1.d.cts.map +1 -0
  364. package/dist/store/d1.d.mts +55 -0
  365. package/dist/store/d1.d.mts.map +1 -0
  366. package/dist/store/d1.mjs +184 -0
  367. package/dist/store/d1.mjs.map +1 -0
  368. package/dist/store/facts.cjs +60 -0
  369. package/dist/store/facts.cjs.map +1 -0
  370. package/dist/store/facts.d.cts +38 -0
  371. package/dist/store/facts.d.cts.map +1 -0
  372. package/dist/store/facts.d.mts +38 -0
  373. package/dist/store/facts.d.mts.map +1 -0
  374. package/dist/store/facts.mjs +58 -0
  375. package/dist/store/facts.mjs.map +1 -0
  376. package/dist/store/index.cjs +31 -0
  377. package/dist/store/index.cjs.map +1 -0
  378. package/dist/store/index.d.cts +291 -0
  379. package/dist/store/index.d.cts.map +1 -0
  380. package/dist/store/index.d.mts +291 -0
  381. package/dist/store/index.d.mts.map +1 -0
  382. package/dist/store/index.mjs +22 -0
  383. package/dist/store/index.mjs.map +1 -0
  384. package/dist/store/postgres-reporting.cjs +213 -0
  385. package/dist/store/postgres-reporting.cjs.map +1 -0
  386. package/dist/store/postgres-reporting.d.cts +63 -0
  387. package/dist/store/postgres-reporting.d.cts.map +1 -0
  388. package/dist/store/postgres-reporting.d.mts +63 -0
  389. package/dist/store/postgres-reporting.d.mts.map +1 -0
  390. package/dist/store/postgres-reporting.mjs +212 -0
  391. package/dist/store/postgres-reporting.mjs.map +1 -0
  392. package/dist/store/postgres.cjs +309 -0
  393. package/dist/store/postgres.cjs.map +1 -0
  394. package/dist/store/postgres.d.cts +77 -0
  395. package/dist/store/postgres.d.cts.map +1 -0
  396. package/dist/store/postgres.d.mts +77 -0
  397. package/dist/store/postgres.d.mts.map +1 -0
  398. package/dist/store/postgres.mjs +306 -0
  399. package/dist/store/postgres.mjs.map +1 -0
  400. package/dist/store/sql.cjs +24 -0
  401. package/dist/store/sql.cjs.map +1 -0
  402. package/dist/store/sql.d.cts +25 -0
  403. package/dist/store/sql.d.cts.map +1 -0
  404. package/dist/store/sql.d.mts +25 -0
  405. package/dist/store/sql.d.mts.map +1 -0
  406. package/dist/store/sql.mjs +23 -0
  407. package/dist/store/sql.mjs.map +1 -0
  408. package/dist/store/tables.cjs +404 -0
  409. package/dist/store/tables.cjs.map +1 -0
  410. package/dist/store/tables.d.cts +81 -0
  411. package/dist/store/tables.d.cts.map +1 -0
  412. package/dist/store/tables.d.mts +81 -0
  413. package/dist/store/tables.d.mts.map +1 -0
  414. package/dist/store/tables.mjs +399 -0
  415. package/dist/store/tables.mjs.map +1 -0
  416. package/dist/templates.cjs +247 -0
  417. package/dist/templates.cjs.map +1 -0
  418. package/dist/templates.d.cts +187 -0
  419. package/dist/templates.d.cts.map +1 -0
  420. package/dist/templates.d.mts +187 -0
  421. package/dist/templates.d.mts.map +1 -0
  422. package/dist/templates.mjs +230 -0
  423. package/dist/templates.mjs.map +1 -0
  424. package/dist/webhooks.cjs +96 -0
  425. package/dist/webhooks.cjs.map +1 -0
  426. package/dist/webhooks.d.cts +25 -0
  427. package/dist/webhooks.d.cts.map +1 -0
  428. package/dist/webhooks.d.mts +25 -0
  429. package/dist/webhooks.d.mts.map +1 -0
  430. package/dist/webhooks.mjs +94 -0
  431. package/dist/webhooks.mjs.map +1 -0
  432. package/dist/webpush.cjs +180 -0
  433. package/dist/webpush.cjs.map +1 -0
  434. package/dist/webpush.d.cts +53 -0
  435. package/dist/webpush.d.cts.map +1 -0
  436. package/dist/webpush.d.mts +53 -0
  437. package/dist/webpush.d.mts.map +1 -0
  438. package/dist/webpush.mjs +175 -0
  439. package/dist/webpush.mjs.map +1 -0
  440. package/package.json +189 -3
  441. package/src/cloudflare/schema.sql +127 -0
  442. package/src/cloudflare/workers.d.ts +44 -0
@@ -0,0 +1,252 @@
1
+ import { ChannelIR, ConditionIR, ScalarIR } from "../ir.cjs";
2
+ //#region src/engine/ports.d.ts
3
+ /**
4
+ * Engine ports: the only shape of the outside world the interpreter depends on.
5
+ *
6
+ * Design constraints (AWS-proof, see the engine design notes):
7
+ * - A wake-up is only a hint — "**at least one wake-up, re-evaluate after
8
+ * waking**". No event buffering or de-duplication is promised (Cloudflare
9
+ * buffers, AWS callback tokens do not — the port takes the intersection).
10
+ * The truth of a condition is always re-read by the caller once awake.
11
+ * - subscribe / waitForWake / unsubscribe are split so the caller can register
12
+ * interest *before* its first condition check — an event landing between the
13
+ * check and the registration would otherwise be missed until the timeout.
14
+ * - Every source of non-determinism (randomness, current time, external IO)
15
+ * must happen inside step.do, so its result is persisted and replay lines up.
16
+ */
17
+ export interface EngineStep {
18
+ /** Durable step: fn's return value is checkpointed; on replay the result is reused without re-running. */
19
+ do<T>(name: string, fn: () => Promise<T>): Promise<T>;
20
+ /** Durable sleep: suspended time is not billed. */
21
+ sleep(name: string, ms: number): Promise<void>;
22
+ /** Sleep until an absolute instant (used by time_window). */
23
+ sleepUntil(name: string, timestampMs: number): Promise<void>;
24
+ /**
25
+ * Durable: register interest in the named events (Cloudflare: write the
26
+ * subscription table; AWS: create a callback and store its id). Must
27
+ * complete before the caller's condition check for that attempt.
28
+ *
29
+ * Contract: one subscribe arms **at least one** wake-up — adapters whose
30
+ * wake handle is one-shot (AWS durable-function callbacks are consumed on
31
+ * delivery) satisfy it with exactly one. Callers therefore re-subscribe on
32
+ * every wait attempt; adapters where registrations persist (Cloudflare rows)
33
+ * make the repeat call idempotent.
34
+ */
35
+ subscribe(name: string, events: readonly string[]): Promise<void>;
36
+ /** Durable: drop every registration this instance holds. */
37
+ unsubscribe(name: string): Promise<void>;
38
+ /**
39
+ * Wait for a wake-up or a timeout. A registration from `subscribe` must
40
+ * already exist — this call only parks the instance.
41
+ */
42
+ waitForWake(name: string, timeoutMs: number): Promise<'event' | 'timeout'>;
43
+ }
44
+ /** One device a push can go to: the provider token (APNs device token, FCM registration token) and the platform that picks the provider. */
45
+ export interface PushDevice {
46
+ token: string;
47
+ platform: string;
48
+ }
49
+ /** Facts from a single user's point of view: the read interface condition evaluation uses (D1 and in-memory share one evaluator). */
50
+ export interface FactSource {
51
+ /**
52
+ * How many times an event occurred. `sinceMs` bounds the window (within /
53
+ * anchoring); `where` is a payload-only condition tree — count only events
54
+ * whose payload matches (evaluate with matchesWhere from engine/condition).
55
+ */
56
+ countEvents(event: string, opts?: {
57
+ sinceMs?: number;
58
+ untilMs?: number;
59
+ where?: ConditionIR;
60
+ }): Promise<number>;
61
+ getProperty(path: string): Promise<ScalarIR | undefined>;
62
+ /** Resolve a segment definition by id (stored with the bundle at deploy time). */
63
+ getSegmentCondition(name: string): Promise<ConditionIR | undefined>;
64
+ /** The user's push devices, most recently registered first (empty when the user registered none). */
65
+ listDevices(): Promise<PushDevice[]>;
66
+ /** The user opted out of the channel (an email unsubscribe): nothing is sent there. */
67
+ isSuppressed?(channel: ChannelIR): Promise<boolean>;
68
+ }
69
+ export interface OutboundMessage {
70
+ /** Where the copy comes from: the workflow, its instance and the message node. */
71
+ workflow: string;
72
+ instanceId: string;
73
+ nodeId: string;
74
+ channel: ChannelIR;
75
+ template: string;
76
+ /** Already resolved: user_property references have been replaced by actual values. */
77
+ props: Record<string, ScalarIR | undefined>;
78
+ userId: string;
79
+ /**
80
+ * The channel's recipient address, resolved by the engine — so senders never
81
+ * read the database: a profile property for most channels, the device token
82
+ * for push (one message per device).
83
+ */
84
+ recipient?: string | undefined;
85
+ /** Push only: the device this copy goes to — its platform picks the provider. */
86
+ device?: PushDevice | undefined;
87
+ /**
88
+ * `${instanceId}:${nodeId}` (plus `:${token}` for a push copy) — one per copy. Senders
89
+ * de-duplicate on it, making replays and retries safe, and it is the copy's identity for
90
+ * tracking: a push carries it in its payload, so the app can report the tap against it.
91
+ */
92
+ idempotencyKey: string;
93
+ /** What the host's observer asked the sender to add for measuring this copy (see `MessageTracking`). */
94
+ tracking?: MessageTracking | undefined;
95
+ }
96
+ /**
97
+ * Measuring a copy, as the built-in senders apply it: an email's links are routed through
98
+ * `link` and `pixel` is appended as a 1×1 image; a push carries `data` in its payload.
99
+ * Each is optional, and a sender ignores what its channel has no use for.
100
+ */
101
+ export interface MessageTracking {
102
+ /** The original `http(s)` URL in, the URL that records the click and redirects out. */
103
+ link?: (url: string) => string;
104
+ /** Loaded when the email is opened. */
105
+ pixel?: string;
106
+ /** Extra string keys in the push payload. */
107
+ data?: Record<string, string>;
108
+ /**
109
+ * Called by the sender once the links are rewritten and before the transport takes the copy:
110
+ * what the tracking URLs resolve to is stored before anyone can click one. A throw stops the
111
+ * send, and the step retries it.
112
+ */
113
+ commit?: () => Promise<void>;
114
+ }
115
+ /**
116
+ * How a copy ended at the transport. A sender returns nothing when the transport accepted it;
117
+ * `{ delivered: false }` when it settled the copy without delivering — a dead push token, which
118
+ * is not retried. A transient failure throws instead, and the step retries.
119
+ */
120
+ export interface SendResult {
121
+ delivered: false;
122
+ reason: string;
123
+ }
124
+ export interface MessageSender {
125
+ send(message: OutboundMessage): Promise<void | SendResult>;
126
+ }
127
+ /**
128
+ * What the host learns about each journey as it runs, for reporting: where every instance
129
+ * stands, every copy it sends and how the transport took it, and how it ended. Storage is the
130
+ * host's — the engine only reports. Every method is optional and must be idempotent: a step
131
+ * that fails after its report ran is retried and reports again (keyed by the instance and node,
132
+ * or the copy's idempotency key).
133
+ */
134
+ export interface JourneyObserver {
135
+ /** The instance entered, before its entry guards: `at` is the trigger's time, the entry anchor. */
136
+ started?(event: {
137
+ workflow: string;
138
+ instanceId: string;
139
+ userId: string;
140
+ at: number;
141
+ }): Promise<void>;
142
+ /** The instance reached a node: it sits there until the next one (a delay, a wait), or passes through. */
143
+ nodeReached?(event: {
144
+ workflow: string;
145
+ instanceId: string;
146
+ userId: string;
147
+ nodeId: string;
148
+ at: number;
149
+ }): Promise<void>;
150
+ /** A copy is about to go out; the tracking returned travels with it to the sender. */
151
+ messagePrepared?(message: OutboundMessage): Promise<MessageTracking | undefined>;
152
+ /** The transport took the copy (`delivered: true`), or settled it undelivered; a thrown send is not reported. */
153
+ messageSent?(message: OutboundMessage, result: {
154
+ delivered: true;
155
+ } | SendResult): Promise<void>;
156
+ /** The instance ended: its outcome (`goal` is a conversion), or `failed` when an error ended it. */
157
+ finished?(event: {
158
+ workflow: string;
159
+ instanceId: string;
160
+ userId: string;
161
+ status: JourneyOutcome['status'] | 'failed';
162
+ at: number;
163
+ /** When it converted, if it did — set whatever the status (see JourneyOutcome). */
164
+ convertedAt?: number;
165
+ }): Promise<void>;
166
+ }
167
+ /**
168
+ * Message preparation: checks a message's resolved props against its template
169
+ * before any sender sees it (and, for a push, before the first device), and
170
+ * returns the props to send — the parsed value. Throwing stops the send; the
171
+ * interpreter adds the instance and node to the error. The Cloudflare host
172
+ * assembles one from the template registries (`registryValidator`).
173
+ */
174
+ export interface MessageValidator {
175
+ validate(message: {
176
+ channel: ChannelIR;
177
+ template: string;
178
+ props: Record<string, ScalarIR | undefined>;
179
+ }): Record<string, ScalarIR | undefined>;
180
+ }
181
+ /** send_event's outlet: feeds back into ingest (the event edge between workflows). */
182
+ export interface EventSink {
183
+ /**
184
+ * `id` identifies the occurrence, and sending the same one twice must record
185
+ * it once. The interpreter passes `${instanceId}:${nodeId}` — the same
186
+ * identity senders and actions de-duplicate on — because the emit is wrapped
187
+ * in a step, and a step body is retried after a failure that may have
188
+ * happened *after* the event was already written.
189
+ */
190
+ emit(event: string, payload: Record<string, ScalarIR | undefined>, id: string): Promise<void>;
191
+ }
192
+ /** One action node's resolved call, ready for the registry. */
193
+ export interface ActionInvocation {
194
+ /** Registry name; the code itself lives in the deployed bundle (dual-plane model, see dsl/action.ts). */
195
+ action: string;
196
+ /** Code-identity pin from the IR the journey is running; adapters compare it against the registered implementation. */
197
+ codeHash?: string | undefined;
198
+ /** Already resolved: user_property references have been replaced by actual values (same contract as message props). */
199
+ args: Record<string, ScalarIR | undefined>;
200
+ userId: string;
201
+ /** `${instanceId}:${nodeId}` — handlers with external side effects de-duplicate on it, like senders do. */
202
+ idempotencyKey: string;
203
+ }
204
+ /**
205
+ * Custom-action outlet. The interpreter already wraps the call in step.do, so
206
+ * an implementation may just look up and run the handler — a throw is retried
207
+ * by the runtime, a success is checkpointed.
208
+ */
209
+ export interface ActionInvoker {
210
+ invoke(invocation: ActionInvocation): Promise<void>;
211
+ }
212
+ export interface JourneyContext {
213
+ userId: string;
214
+ /** Instance identity: feeds the idempotency key and the logs. */
215
+ instanceId: string;
216
+ /**
217
+ * When the user entered the workflow (ms epoch) — the baseline for the
218
+ * goal's attribution window (`goal.within`). Must be replay-stable: the
219
+ * adapter derives it from the trigger event's timestamp, never from
220
+ * Date.now() at run time.
221
+ */
222
+ enteredAtMs: number;
223
+ step: EngineStep;
224
+ facts: FactSource;
225
+ messages: MessageSender;
226
+ events: EventSink;
227
+ /** Optional: only journeys whose IR contains action nodes need one; running such a node without it is a runtime error. */
228
+ actions?: ActionInvoker | undefined;
229
+ /** Template props validation before every send; without one, props go out as resolved. */
230
+ validator?: MessageValidator | undefined;
231
+ /** Reporting hooks (positions and copies); without one, nothing is reported. */
232
+ observer?: JourneyObserver | undefined;
233
+ }
234
+ /**
235
+ * How an instance ended, and — apart from that — whether and when it converted: `goal` ends it
236
+ * at the conversion, while with `exitOnMatch: false` a converted instance ends like any other
237
+ * and only `convertedAt` tells.
238
+ */
239
+ export type JourneyOutcome = ({
240
+ status: 'completed';
241
+ } | {
242
+ status: 'exited';
243
+ reason?: string;
244
+ } | {
245
+ status: 'goal';
246
+ } | {
247
+ status: 'exit_when';
248
+ }) & {
249
+ convertedAt?: number;
250
+ };
251
+ //#endregion
252
+ //# sourceMappingURL=ports.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.cts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW;;;;;;;iBAQI;;EAEf,QAAQ;;EAER;;EAEA,OAAO;;;;;;EAMP,eAAe;;;;;;;iBAQA;EACf;EACA;;iBAGe;EACf,KAAK,SAAS,kBAAkB,eAAe;;;;;;;;;iBAUhC;;EAEf,SAAS;IACP;IACA;IACA;IACA;MACE;;EAEJ,aAAa;IACX;IACA;IACA;IACA;IACA;MACE;;EAEJ,iBAAiB,SAAS,kBAAkB,QAAQ;;EAEpD,aAAa,SAAS,iBAAiB;IAAU;MAAoB,aAAa;;EAElF,UAAU;IACR;IACA;IACA;IACA,QAAQ;IACR;;IAEA;MACE;;;;;;;;;iBAUW;EACf,SAAS;IACP,SAAS;IACT;IACA,OAAO,eAAe;MACpB,eAAe;;;iBAIJ;;;;;;;;EAQf,KAAK,eAAe,SAAS,eAAe,uBAAuB,aAAa;;;iBAIjE;;EAEf;;EAEA;;EAEA,MAAM,eAAe;EACrB;;EAEA;;;;;;;iBAQe;EACf,OAAO,YAAY,mBAAmB;;iBAGvB;EACf;;EAEA;;;;;;;EAOA;EACA,MAAM;EACN,OAAO;EACP,UAAU;EACV,QAAQ;;EAER,UAAU;;EAEV,YAAY;;EAEZ,WAAW;;;;;;;YAQD;EACN;;EACA;EAAkB;;EAClB;;EACA;;EACA"}
@@ -0,0 +1,252 @@
1
+ import { ChannelIR, ConditionIR, ScalarIR } from "../ir.mjs";
2
+ //#region src/engine/ports.d.ts
3
+ /**
4
+ * Engine ports: the only shape of the outside world the interpreter depends on.
5
+ *
6
+ * Design constraints (AWS-proof, see the engine design notes):
7
+ * - A wake-up is only a hint — "**at least one wake-up, re-evaluate after
8
+ * waking**". No event buffering or de-duplication is promised (Cloudflare
9
+ * buffers, AWS callback tokens do not — the port takes the intersection).
10
+ * The truth of a condition is always re-read by the caller once awake.
11
+ * - subscribe / waitForWake / unsubscribe are split so the caller can register
12
+ * interest *before* its first condition check — an event landing between the
13
+ * check and the registration would otherwise be missed until the timeout.
14
+ * - Every source of non-determinism (randomness, current time, external IO)
15
+ * must happen inside step.do, so its result is persisted and replay lines up.
16
+ */
17
+ export interface EngineStep {
18
+ /** Durable step: fn's return value is checkpointed; on replay the result is reused without re-running. */
19
+ do<T>(name: string, fn: () => Promise<T>): Promise<T>;
20
+ /** Durable sleep: suspended time is not billed. */
21
+ sleep(name: string, ms: number): Promise<void>;
22
+ /** Sleep until an absolute instant (used by time_window). */
23
+ sleepUntil(name: string, timestampMs: number): Promise<void>;
24
+ /**
25
+ * Durable: register interest in the named events (Cloudflare: write the
26
+ * subscription table; AWS: create a callback and store its id). Must
27
+ * complete before the caller's condition check for that attempt.
28
+ *
29
+ * Contract: one subscribe arms **at least one** wake-up — adapters whose
30
+ * wake handle is one-shot (AWS durable-function callbacks are consumed on
31
+ * delivery) satisfy it with exactly one. Callers therefore re-subscribe on
32
+ * every wait attempt; adapters where registrations persist (Cloudflare rows)
33
+ * make the repeat call idempotent.
34
+ */
35
+ subscribe(name: string, events: readonly string[]): Promise<void>;
36
+ /** Durable: drop every registration this instance holds. */
37
+ unsubscribe(name: string): Promise<void>;
38
+ /**
39
+ * Wait for a wake-up or a timeout. A registration from `subscribe` must
40
+ * already exist — this call only parks the instance.
41
+ */
42
+ waitForWake(name: string, timeoutMs: number): Promise<'event' | 'timeout'>;
43
+ }
44
+ /** One device a push can go to: the provider token (APNs device token, FCM registration token) and the platform that picks the provider. */
45
+ export interface PushDevice {
46
+ token: string;
47
+ platform: string;
48
+ }
49
+ /** Facts from a single user's point of view: the read interface condition evaluation uses (D1 and in-memory share one evaluator). */
50
+ export interface FactSource {
51
+ /**
52
+ * How many times an event occurred. `sinceMs` bounds the window (within /
53
+ * anchoring); `where` is a payload-only condition tree — count only events
54
+ * whose payload matches (evaluate with matchesWhere from engine/condition).
55
+ */
56
+ countEvents(event: string, opts?: {
57
+ sinceMs?: number;
58
+ untilMs?: number;
59
+ where?: ConditionIR;
60
+ }): Promise<number>;
61
+ getProperty(path: string): Promise<ScalarIR | undefined>;
62
+ /** Resolve a segment definition by id (stored with the bundle at deploy time). */
63
+ getSegmentCondition(name: string): Promise<ConditionIR | undefined>;
64
+ /** The user's push devices, most recently registered first (empty when the user registered none). */
65
+ listDevices(): Promise<PushDevice[]>;
66
+ /** The user opted out of the channel (an email unsubscribe): nothing is sent there. */
67
+ isSuppressed?(channel: ChannelIR): Promise<boolean>;
68
+ }
69
+ export interface OutboundMessage {
70
+ /** Where the copy comes from: the workflow, its instance and the message node. */
71
+ workflow: string;
72
+ instanceId: string;
73
+ nodeId: string;
74
+ channel: ChannelIR;
75
+ template: string;
76
+ /** Already resolved: user_property references have been replaced by actual values. */
77
+ props: Record<string, ScalarIR | undefined>;
78
+ userId: string;
79
+ /**
80
+ * The channel's recipient address, resolved by the engine — so senders never
81
+ * read the database: a profile property for most channels, the device token
82
+ * for push (one message per device).
83
+ */
84
+ recipient?: string | undefined;
85
+ /** Push only: the device this copy goes to — its platform picks the provider. */
86
+ device?: PushDevice | undefined;
87
+ /**
88
+ * `${instanceId}:${nodeId}` (plus `:${token}` for a push copy) — one per copy. Senders
89
+ * de-duplicate on it, making replays and retries safe, and it is the copy's identity for
90
+ * tracking: a push carries it in its payload, so the app can report the tap against it.
91
+ */
92
+ idempotencyKey: string;
93
+ /** What the host's observer asked the sender to add for measuring this copy (see `MessageTracking`). */
94
+ tracking?: MessageTracking | undefined;
95
+ }
96
+ /**
97
+ * Measuring a copy, as the built-in senders apply it: an email's links are routed through
98
+ * `link` and `pixel` is appended as a 1×1 image; a push carries `data` in its payload.
99
+ * Each is optional, and a sender ignores what its channel has no use for.
100
+ */
101
+ export interface MessageTracking {
102
+ /** The original `http(s)` URL in, the URL that records the click and redirects out. */
103
+ link?: (url: string) => string;
104
+ /** Loaded when the email is opened. */
105
+ pixel?: string;
106
+ /** Extra string keys in the push payload. */
107
+ data?: Record<string, string>;
108
+ /**
109
+ * Called by the sender once the links are rewritten and before the transport takes the copy:
110
+ * what the tracking URLs resolve to is stored before anyone can click one. A throw stops the
111
+ * send, and the step retries it.
112
+ */
113
+ commit?: () => Promise<void>;
114
+ }
115
+ /**
116
+ * How a copy ended at the transport. A sender returns nothing when the transport accepted it;
117
+ * `{ delivered: false }` when it settled the copy without delivering — a dead push token, which
118
+ * is not retried. A transient failure throws instead, and the step retries.
119
+ */
120
+ export interface SendResult {
121
+ delivered: false;
122
+ reason: string;
123
+ }
124
+ export interface MessageSender {
125
+ send(message: OutboundMessage): Promise<void | SendResult>;
126
+ }
127
+ /**
128
+ * What the host learns about each journey as it runs, for reporting: where every instance
129
+ * stands, every copy it sends and how the transport took it, and how it ended. Storage is the
130
+ * host's — the engine only reports. Every method is optional and must be idempotent: a step
131
+ * that fails after its report ran is retried and reports again (keyed by the instance and node,
132
+ * or the copy's idempotency key).
133
+ */
134
+ export interface JourneyObserver {
135
+ /** The instance entered, before its entry guards: `at` is the trigger's time, the entry anchor. */
136
+ started?(event: {
137
+ workflow: string;
138
+ instanceId: string;
139
+ userId: string;
140
+ at: number;
141
+ }): Promise<void>;
142
+ /** The instance reached a node: it sits there until the next one (a delay, a wait), or passes through. */
143
+ nodeReached?(event: {
144
+ workflow: string;
145
+ instanceId: string;
146
+ userId: string;
147
+ nodeId: string;
148
+ at: number;
149
+ }): Promise<void>;
150
+ /** A copy is about to go out; the tracking returned travels with it to the sender. */
151
+ messagePrepared?(message: OutboundMessage): Promise<MessageTracking | undefined>;
152
+ /** The transport took the copy (`delivered: true`), or settled it undelivered; a thrown send is not reported. */
153
+ messageSent?(message: OutboundMessage, result: {
154
+ delivered: true;
155
+ } | SendResult): Promise<void>;
156
+ /** The instance ended: its outcome (`goal` is a conversion), or `failed` when an error ended it. */
157
+ finished?(event: {
158
+ workflow: string;
159
+ instanceId: string;
160
+ userId: string;
161
+ status: JourneyOutcome['status'] | 'failed';
162
+ at: number;
163
+ /** When it converted, if it did — set whatever the status (see JourneyOutcome). */
164
+ convertedAt?: number;
165
+ }): Promise<void>;
166
+ }
167
+ /**
168
+ * Message preparation: checks a message's resolved props against its template
169
+ * before any sender sees it (and, for a push, before the first device), and
170
+ * returns the props to send — the parsed value. Throwing stops the send; the
171
+ * interpreter adds the instance and node to the error. The Cloudflare host
172
+ * assembles one from the template registries (`registryValidator`).
173
+ */
174
+ export interface MessageValidator {
175
+ validate(message: {
176
+ channel: ChannelIR;
177
+ template: string;
178
+ props: Record<string, ScalarIR | undefined>;
179
+ }): Record<string, ScalarIR | undefined>;
180
+ }
181
+ /** send_event's outlet: feeds back into ingest (the event edge between workflows). */
182
+ export interface EventSink {
183
+ /**
184
+ * `id` identifies the occurrence, and sending the same one twice must record
185
+ * it once. The interpreter passes `${instanceId}:${nodeId}` — the same
186
+ * identity senders and actions de-duplicate on — because the emit is wrapped
187
+ * in a step, and a step body is retried after a failure that may have
188
+ * happened *after* the event was already written.
189
+ */
190
+ emit(event: string, payload: Record<string, ScalarIR | undefined>, id: string): Promise<void>;
191
+ }
192
+ /** One action node's resolved call, ready for the registry. */
193
+ export interface ActionInvocation {
194
+ /** Registry name; the code itself lives in the deployed bundle (dual-plane model, see dsl/action.ts). */
195
+ action: string;
196
+ /** Code-identity pin from the IR the journey is running; adapters compare it against the registered implementation. */
197
+ codeHash?: string | undefined;
198
+ /** Already resolved: user_property references have been replaced by actual values (same contract as message props). */
199
+ args: Record<string, ScalarIR | undefined>;
200
+ userId: string;
201
+ /** `${instanceId}:${nodeId}` — handlers with external side effects de-duplicate on it, like senders do. */
202
+ idempotencyKey: string;
203
+ }
204
+ /**
205
+ * Custom-action outlet. The interpreter already wraps the call in step.do, so
206
+ * an implementation may just look up and run the handler — a throw is retried
207
+ * by the runtime, a success is checkpointed.
208
+ */
209
+ export interface ActionInvoker {
210
+ invoke(invocation: ActionInvocation): Promise<void>;
211
+ }
212
+ export interface JourneyContext {
213
+ userId: string;
214
+ /** Instance identity: feeds the idempotency key and the logs. */
215
+ instanceId: string;
216
+ /**
217
+ * When the user entered the workflow (ms epoch) — the baseline for the
218
+ * goal's attribution window (`goal.within`). Must be replay-stable: the
219
+ * adapter derives it from the trigger event's timestamp, never from
220
+ * Date.now() at run time.
221
+ */
222
+ enteredAtMs: number;
223
+ step: EngineStep;
224
+ facts: FactSource;
225
+ messages: MessageSender;
226
+ events: EventSink;
227
+ /** Optional: only journeys whose IR contains action nodes need one; running such a node without it is a runtime error. */
228
+ actions?: ActionInvoker | undefined;
229
+ /** Template props validation before every send; without one, props go out as resolved. */
230
+ validator?: MessageValidator | undefined;
231
+ /** Reporting hooks (positions and copies); without one, nothing is reported. */
232
+ observer?: JourneyObserver | undefined;
233
+ }
234
+ /**
235
+ * How an instance ended, and — apart from that — whether and when it converted: `goal` ends it
236
+ * at the conversion, while with `exitOnMatch: false` a converted instance ends like any other
237
+ * and only `convertedAt` tells.
238
+ */
239
+ export type JourneyOutcome = ({
240
+ status: 'completed';
241
+ } | {
242
+ status: 'exited';
243
+ reason?: string;
244
+ } | {
245
+ status: 'goal';
246
+ } | {
247
+ status: 'exit_when';
248
+ }) & {
249
+ convertedAt?: number;
250
+ };
251
+ //#endregion
252
+ //# sourceMappingURL=ports.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.mts","names":[],"sources":["../../src/engine/ports.ts"],"mappings":";;;;;;;;;;;;;;;;iBAiBiB;;EAEf,GAAG,GAAG,cAAc,UAAU,QAAQ,KAAK,QAAQ;;EAGnD,MAAM,cAAc,aAAa;;EAGjC,WAAW,cAAc,sBAAsB;;;;;;;;;;;;EAa/C,UAAU,cAAc,4BAA4B;;EAGpD,YAAY,eAAe;;;;;EAM3B,YAAY,cAAc,oBAAoB;;;iBAI/B;EACf;EACA;;;iBAIe;;;;;;EAMf,YACE,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;EACH,YAAY,eAAe,QAAQ;;EAEnC,oBAAoB,eAAe,QAAQ;;EAE3C,eAAe,QAAQ;;EAEvB,cAAc,SAAS,YAAY;;iBAGpB;;EAEf;EACA;EACA;EACA,SAAS;EACT;;EAEA,OAAO,eAAe;EACtB;;;;;;EAMA;;EAEA,SAAS;;;;;;EAMT;;EAEA,WAAW;;;;;;;iBAQI;;EAEf,QAAQ;;EAER;;EAEA,OAAO;;;;;;EAMP,eAAe;;;;;;;iBAQA;EACf;EACA;;iBAGe;EACf,KAAK,SAAS,kBAAkB,eAAe;;;;;;;;;iBAUhC;;EAEf,SAAS;IACP;IACA;IACA;IACA;MACE;;EAEJ,aAAa;IACX;IACA;IACA;IACA;IACA;MACE;;EAEJ,iBAAiB,SAAS,kBAAkB,QAAQ;;EAEpD,aAAa,SAAS,iBAAiB;IAAU;MAAoB,aAAa;;EAElF,UAAU;IACR;IACA;IACA;IACA,QAAQ;IACR;;IAEA;MACE;;;;;;;;;iBAUW;EACf,SAAS;IACP,SAAS;IACT;IACA,OAAO,eAAe;MACpB,eAAe;;;iBAIJ;;;;;;;;EAQf,KAAK,eAAe,SAAS,eAAe,uBAAuB,aAAa;;;iBAIjE;;EAEf;;EAEA;;EAEA,MAAM,eAAe;EACrB;;EAEA;;;;;;;iBAQe;EACf,OAAO,YAAY,mBAAmB;;iBAGvB;EACf;;EAEA;;;;;;;EAOA;EACA,MAAM;EACN,OAAO;EACP,UAAU;EACV,QAAQ;;EAER,UAAU;;EAEV,YAAY;;EAEZ,WAAW;;;;;;;YAQD;EACN;;EACA;EAAkB;;EAClB;;EACA;;EACA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/engine/recipient.ts
3
+ /**
4
+ * Channel → the user property holding its recipient address. The engine
5
+ * resolves it before sending, which keeps senders stateless. Push is absent on
6
+ * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team
7
+ * channel through the template's webhook, so they have no per-user address either.
8
+ * TODO: let the app override this table (today it is a convention, with
9
+ * UserPropertyBase guaranteeing `email` exists).
10
+ */
11
+ const RECIPIENT_PROPERTY = {
12
+ email: "email",
13
+ sms: "phone",
14
+ push: void 0,
15
+ slack: void 0,
16
+ discord: void 0,
17
+ survey: "email",
18
+ in_app: void 0
19
+ };
20
+ //#endregion
21
+ exports.RECIPIENT_PROPERTY = RECIPIENT_PROPERTY;
22
+
23
+ //# sourceMappingURL=recipient.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipient.cjs","names":[],"sources":["../../src/engine/recipient.ts"],"sourcesContent":["import type { ChannelIR } from '../ir';\n\n/**\n * Channel → the user property holding its recipient address. The engine\n * resolves it before sending, which keeps senders stateless. Push is absent on\n * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team\n * channel through the template's webhook, so they have no per-user address either.\n * TODO: let the app override this table (today it is a convention, with\n * UserPropertyBase guaranteeing `email` exists).\n */\nexport const RECIPIENT_PROPERTY: Record<ChannelIR, string | undefined> = {\n email: 'email',\n sms: 'phone',\n push: undefined,\n slack: undefined,\n discord: undefined,\n survey: 'email',\n in_app: undefined,\n};\n"],"mappings":";;;;;;;;;;AAUA,MAAa,qBAA4D;CACvE,OAAO;CACP,KAAK;CACL,MAAM,KAAA;CACN,OAAO,KAAA;CACP,SAAS,KAAA;CACT,QAAQ;CACR,QAAQ,KAAA;AACV"}
@@ -0,0 +1,13 @@
1
+ import { ChannelIR } from "../ir.cjs";
2
+ //#region src/engine/recipient.d.ts
3
+ /**
4
+ * Channel → the user property holding its recipient address. The engine
5
+ * resolves it before sending, which keeps senders stateless. Push is absent on
6
+ * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team
7
+ * channel through the template's webhook, so they have no per-user address either.
8
+ * TODO: let the app override this table (today it is a convention, with
9
+ * UserPropertyBase guaranteeing `email` exists).
10
+ */
11
+ export declare const RECIPIENT_PROPERTY: Record<ChannelIR, string | undefined>;
12
+ //#endregion
13
+ //# sourceMappingURL=recipient.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipient.d.cts","names":[],"sources":["../../src/engine/recipient.ts"],"mappings":";;;;;;;;;;qBAUa,oBAAoB,OAAO"}
@@ -0,0 +1,13 @@
1
+ import { ChannelIR } from "../ir.mjs";
2
+ //#region src/engine/recipient.d.ts
3
+ /**
4
+ * Channel → the user property holding its recipient address. The engine
5
+ * resolves it before sending, which keeps senders stateless. Push is absent on
6
+ * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team
7
+ * channel through the template's webhook, so they have no per-user address either.
8
+ * TODO: let the app override this table (today it is a convention, with
9
+ * UserPropertyBase guaranteeing `email` exists).
10
+ */
11
+ export declare const RECIPIENT_PROPERTY: Record<ChannelIR, string | undefined>;
12
+ //#endregion
13
+ //# sourceMappingURL=recipient.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipient.d.mts","names":[],"sources":["../../src/engine/recipient.ts"],"mappings":";;;;;;;;;;qBAUa,oBAAoB,OAAO"}
@@ -0,0 +1,22 @@
1
+ //#region src/engine/recipient.ts
2
+ /**
3
+ * Channel → the user property holding its recipient address. The engine
4
+ * resolves it before sending, which keeps senders stateless. Push is absent on
5
+ * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team
6
+ * channel through the template's webhook, so they have no per-user address either.
7
+ * TODO: let the app override this table (today it is a convention, with
8
+ * UserPropertyBase guaranteeing `email` exists).
9
+ */
10
+ const RECIPIENT_PROPERTY = {
11
+ email: "email",
12
+ sms: "phone",
13
+ push: void 0,
14
+ slack: void 0,
15
+ discord: void 0,
16
+ survey: "email",
17
+ in_app: void 0
18
+ };
19
+ //#endregion
20
+ export { RECIPIENT_PROPERTY };
21
+
22
+ //# sourceMappingURL=recipient.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipient.mjs","names":[],"sources":["../../src/engine/recipient.ts"],"sourcesContent":["import type { ChannelIR } from '../ir';\n\n/**\n * Channel → the user property holding its recipient address. The engine\n * resolves it before sending, which keeps senders stateless. Push is absent on\n * purpose: its recipients are devices, kept in the store. Slack and Discord post to a team\n * channel through the template's webhook, so they have no per-user address either.\n * TODO: let the app override this table (today it is a convention, with\n * UserPropertyBase guaranteeing `email` exists).\n */\nexport const RECIPIENT_PROPERTY: Record<ChannelIR, string | undefined> = {\n email: 'email',\n sms: 'phone',\n push: undefined,\n slack: undefined,\n discord: undefined,\n survey: 'email',\n in_app: undefined,\n};\n"],"mappings":";;;;;;;;;AAUA,MAAa,qBAA4D;CACvE,OAAO;CACP,KAAK;CACL,MAAM,KAAA;CACN,OAAO,KAAA;CACP,SAAS,KAAA;CACT,QAAQ;CACR,QAAQ,KAAA;AACV"}
@@ -0,0 +1,54 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/engine/time-scale.ts
3
+ /**
4
+ * Debug time scale: divide every duration in a workflow's IR by a factor so a
5
+ * journey written in days plays out in seconds — with a factor of 3600, a
6
+ * `delay('2 days')` sleeps 48 s, a `waitUntil(..., { timeout: '3 days' })`
7
+ * gives up after 72 s, and a goal `within: '30 days'` closes after 12 min.
8
+ *
9
+ * Everything that is a Duration scales together (delays, random delays, wait
10
+ * timeouts, goal and `performed(... within)` windows inside the workflow), so
11
+ * the journey keeps its shape, just faster. What does not scale: wall-clock
12
+ * `timeWindow`s (they are times of day, not durations). Segment definitions
13
+ * live in the store rather than the workflow body; `scaleSegmentWindows`
14
+ * scales them as they are read, so a segment's `within` keeps pace too.
15
+ *
16
+ * Durations are recognised structurally — an object whose only keys are
17
+ * `value` (the source text) and `ms` — which is the DurationIR shape and
18
+ * nothing else in the IR. The text is kept so the studio still shows what was
19
+ * written.
20
+ */
21
+ function scaleDurations(ir, factor) {
22
+ if (!(factor > 0) || factor === 1) return ir;
23
+ return walk(ir, factor);
24
+ }
25
+ function walk(value, factor) {
26
+ if (Array.isArray(value)) return value.map((item) => walk(item, factor));
27
+ if (value === null || typeof value !== "object") return value;
28
+ const record = value;
29
+ const keys = Object.keys(record);
30
+ if (keys.length === 2 && typeof record.value === "string" && typeof record.ms === "number") return {
31
+ value: record.value,
32
+ ms: Math.max(0, Math.round(record.ms / factor))
33
+ };
34
+ return Object.fromEntries(keys.map((key) => [key, walk(record[key], factor)]));
35
+ }
36
+ /**
37
+ * A store whose segment definitions come back scaled by `factor` — what journeyWorker reads
38
+ * through in fast-forward, so a segment's windows (`performed(e.login, { within: '7 days' })`)
39
+ * shrink with the journeys that reference it, and with the segment triggers it routes. Every
40
+ * other method is the store's own.
41
+ */
42
+ function scaleSegmentWindows(store, factor) {
43
+ if (!(factor > 0) || factor === 1) return store;
44
+ return new Proxy(store, { get(target, property) {
45
+ if (property === "getSegmentCondition") return async (name) => scaleDurations(await target.getSegmentCondition(name), factor);
46
+ const value = Reflect.get(target, property, target);
47
+ return typeof value === "function" ? value.bind(target) : value;
48
+ } });
49
+ }
50
+ //#endregion
51
+ exports.scaleDurations = scaleDurations;
52
+ exports.scaleSegmentWindows = scaleSegmentWindows;
53
+
54
+ //# sourceMappingURL=time-scale.cjs.map