@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,60 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_engine_condition = require("../engine/condition.cjs");
3
+ //#region src/store/facts.ts
4
+ /** The profile path that reads the user's own id (`u.userId`). */
5
+ const USER_ID_PROPERTY = "userId";
6
+ /** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */
7
+ var JourneyFactSource = class {
8
+ store;
9
+ userId;
10
+ constructor(store, userId) {
11
+ this.store = store;
12
+ this.userId = userId;
13
+ }
14
+ async countEvents(event, opts) {
15
+ const window = {
16
+ ...opts?.sinceMs === void 0 ? {} : { sinceMs: opts.sinceMs },
17
+ ...opts?.untilMs === void 0 ? {} : { untilMs: opts.untilMs }
18
+ };
19
+ if (opts?.where === void 0) return this.store.countEvents(this.userId, event, window);
20
+ const where = opts.where;
21
+ return (await this.store.listEventPayloads(this.userId, event, window)).filter((payload) => require_engine_condition.matchesWhere(payload, where)).length;
22
+ }
23
+ /**
24
+ * The scalar boundary. Everything downstream — comparisons, subject
25
+ * placeholders, resolved message props — is typed ScalarIR, but nothing so
26
+ * far has checked that the stored JSON is one: /identify validates only that
27
+ * `props` is a plain object, and the merge stores whatever nesting it is
28
+ * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true
29
+ * while `eq(score, 5)` is false, and `String(recipient)` on an object
30
+ * addresses an email to `[object Object]`.
31
+ *
32
+ * So a non-scalar value reads as absent, matching how matchesWhere treats a
33
+ * non-scalar payload leaf. The port cannot say "present but not a scalar",
34
+ * and guessing at a coercion is what produced the wrong branch in the first
35
+ * place.
36
+ */
37
+ async getProperty(path) {
38
+ if (path === "userId") return this.userId;
39
+ const props = await this.store.getProfile(this.userId);
40
+ if (props === void 0) return void 0;
41
+ if (!Object.hasOwn(props, path)) return void 0;
42
+ const value = props[path];
43
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
44
+ }
45
+ getSegmentCondition(name) {
46
+ return this.store.getSegmentCondition(name);
47
+ }
48
+ /** The user's registered devices; none, and push skips while `reachable('push')` is false. */
49
+ async isSuppressed(channel) {
50
+ return await this.store.isSuppressed?.(this.userId, channel) ?? false;
51
+ }
52
+ listDevices() {
53
+ return this.store.listDevices(this.userId);
54
+ }
55
+ };
56
+ //#endregion
57
+ exports.JourneyFactSource = JourneyFactSource;
58
+ exports.USER_ID_PROPERTY = USER_ID_PROPERTY;
59
+
60
+ //# sourceMappingURL=facts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.cjs","names":["matchesWhere"],"sources":["../../src/store/facts.ts"],"sourcesContent":["import { matchesWhere } from '../engine/condition';\nimport type { FactSource, PushDevice } from '../engine/ports';\nimport type { ConditionIR, ScalarIR } from '../ir';\nimport type { JourneyStore } from './index';\n\n/** The profile path that reads the user's own id (`u.userId`). */\nexport const USER_ID_PROPERTY = 'userId';\n\n/** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */\nexport class JourneyFactSource implements FactSource {\n constructor(\n private readonly store: JourneyStore,\n private readonly userId: string\n ) {}\n\n async countEvents(\n event: string,\n opts?: { sinceMs?: number; untilMs?: number; where?: ConditionIR }\n ): Promise<number> {\n const window = {\n ...(opts?.sinceMs === undefined ? {} : { sinceMs: opts.sinceMs }),\n ...(opts?.untilMs === undefined ? {} : { untilMs: opts.untilMs }),\n };\n if (opts?.where === undefined) return this.store.countEvents(this.userId, event, window);\n // Payload filtering happens in JS via the shared evaluator — one set of\n // where semantics with the in-memory FactSource; per-user row counts are small.\n const where = opts.where;\n const payloads = await this.store.listEventPayloads(this.userId, event, window);\n return payloads.filter((payload) => matchesWhere(payload, where)).length;\n }\n\n /**\n * The scalar boundary. Everything downstream — comparisons, subject\n * placeholders, resolved message props — is typed ScalarIR, but nothing so\n * far has checked that the stored JSON is one: /identify validates only that\n * `props` is a plain object, and the merge stores whatever nesting it is\n * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true\n * while `eq(score, 5)` is false, and `String(recipient)` on an object\n * addresses an email to `[object Object]`.\n *\n * So a non-scalar value reads as absent, matching how matchesWhere treats a\n * non-scalar payload leaf. The port cannot say \"present but not a scalar\",\n * and guessing at a coercion is what produced the wrong branch in the first\n * place.\n */\n async getProperty(path: string): Promise<ScalarIR | undefined> {\n // The system field: the request's identity, never stored in the profile (contract.user.userId)\n if (path === USER_ID_PROPERTY) return this.userId;\n const props: Record<string, unknown> | undefined = await this.store.getProfile(this.userId);\n if (props === undefined) return undefined;\n // Own keys only: `props[path]` would otherwise find Object.prototype, so\n // `exists(u.toString)` held for every user with a profile row and a subject\n // placeholder rendered native-code text into the email.\n if (!Object.hasOwn(props, path)) return undefined;\n const value = props[path];\n // An explicit null means \"unset\" and behaves as not_exists. /identify\n // itself clears a property by removing the key (the merge drops nulls), so\n // this covers profiles written by other means — a direct SQL fixup, a\n // migration, an import.\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n return undefined;\n }\n\n getSegmentCondition(name: string): Promise<ConditionIR | undefined> {\n return this.store.getSegmentCondition(name);\n }\n\n /** The user's registered devices; none, and push skips while `reachable('push')` is false. */\n async isSuppressed(channel: string): Promise<boolean> {\n return (await this.store.isSuppressed?.(this.userId, channel)) ?? false;\n }\n\n listDevices(): Promise<PushDevice[]> {\n return this.store.listDevices(this.userId);\n }\n}\n"],"mappings":";;;;AAMA,MAAa,mBAAmB;;AAGhC,IAAa,oBAAb,MAAqD;CAEhC;CACA;CAFnB,YACE,OACA,QACA;EAFiB,KAAA,QAAA;EACA,KAAA,SAAA;CAChB;CAEH,MAAM,YACJ,OACA,MACiB;EACjB,MAAM,SAAS;GACb,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;GAC/D,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;EACjE;EACA,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO,KAAK,MAAM,YAAY,KAAK,QAAQ,OAAO,MAAM;EAGvF,MAAM,QAAQ,KAAK;EAEnB,QAAO,MADgB,KAAK,MAAM,kBAAkB,KAAK,QAAQ,OAAO,MAAM,EAAA,CAC9D,QAAQ,YAAYA,yBAAAA,aAAa,SAAS,KAAK,CAAC,CAAC,CAAC;CACpE;;;;;;;;;;;;;;;CAgBA,MAAM,YAAY,MAA6C;EAE7D,IAAI,SAAA,UAA2B,OAAO,KAAK;EAC3C,MAAM,QAA6C,MAAM,KAAK,MAAM,WAAW,KAAK,MAAM;EAC1F,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAIhC,IAAI,CAAC,OAAO,OAAO,OAAO,IAAI,GAAG,OAAO,KAAA;EACxC,MAAM,QAAQ,MAAM;EAKpB,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,WAC7E,OAAO;CAGX;CAEA,oBAAoB,MAAgD;EAClE,OAAO,KAAK,MAAM,oBAAoB,IAAI;CAC5C;;CAGA,MAAM,aAAa,SAAmC;EACpD,OAAQ,MAAM,KAAK,MAAM,eAAe,KAAK,QAAQ,OAAO,KAAM;CACpE;CAEA,cAAqC;EACnC,OAAO,KAAK,MAAM,YAAY,KAAK,MAAM;CAC3C;AACF"}
@@ -0,0 +1,38 @@
1
+ import { ConditionIR, ScalarIR } from "../ir.cjs";
2
+ import { FactSource, PushDevice } from "../engine/ports.cjs";
3
+ import { JourneyStore } from "./index.cjs";
4
+ //#region src/store/facts.d.ts
5
+ /** The profile path that reads the user's own id (`u.userId`). */
6
+ export declare const USER_ID_PROPERTY = "userId";
7
+ /** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */
8
+ export declare class JourneyFactSource implements FactSource {
9
+ private readonly store;
10
+ private readonly userId;
11
+ constructor(store: JourneyStore, userId: string);
12
+ countEvents(event: string, opts?: {
13
+ sinceMs?: number;
14
+ untilMs?: number;
15
+ where?: ConditionIR;
16
+ }): Promise<number>;
17
+ /**
18
+ * The scalar boundary. Everything downstream — comparisons, subject
19
+ * placeholders, resolved message props — is typed ScalarIR, but nothing so
20
+ * far has checked that the stored JSON is one: /identify validates only that
21
+ * `props` is a plain object, and the merge stores whatever nesting it is
22
+ * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true
23
+ * while `eq(score, 5)` is false, and `String(recipient)` on an object
24
+ * addresses an email to `[object Object]`.
25
+ *
26
+ * So a non-scalar value reads as absent, matching how matchesWhere treats a
27
+ * non-scalar payload leaf. The port cannot say "present but not a scalar",
28
+ * and guessing at a coercion is what produced the wrong branch in the first
29
+ * place.
30
+ */
31
+ getProperty(path: string): Promise<ScalarIR | undefined>;
32
+ getSegmentCondition(name: string): Promise<ConditionIR | undefined>;
33
+ /** The user's registered devices; none, and push skips while `reachable('push')` is false. */
34
+ isSuppressed(channel: string): Promise<boolean>;
35
+ listDevices(): Promise<PushDevice[]>;
36
+ }
37
+ //#endregion
38
+ //# sourceMappingURL=facts.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.d.cts","names":[],"sources":["../../src/store/facts.ts"],"mappings":";;;;;qBAMa;;qBAGA,6BAA6B;mBAErB;mBACA;EAFnB,YACmB,OAAO,cACP;EAGb,YACJ,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;;;;;;;;;;;;;;;EA2BG,YAAY,eAAe,QAAQ;EAoBzC,oBAAoB,eAAe,QAAQ;;EAKrC,aAAa,kBAAkB;EAIrC,eAAe,QAAQ"}
@@ -0,0 +1,38 @@
1
+ import { ConditionIR, ScalarIR } from "../ir.mjs";
2
+ import { FactSource, PushDevice } from "../engine/ports.mjs";
3
+ import { JourneyStore } from "./index.mjs";
4
+ //#region src/store/facts.d.ts
5
+ /** The profile path that reads the user's own id (`u.userId`). */
6
+ export declare const USER_ID_PROPERTY = "userId";
7
+ /** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */
8
+ export declare class JourneyFactSource implements FactSource {
9
+ private readonly store;
10
+ private readonly userId;
11
+ constructor(store: JourneyStore, userId: string);
12
+ countEvents(event: string, opts?: {
13
+ sinceMs?: number;
14
+ untilMs?: number;
15
+ where?: ConditionIR;
16
+ }): Promise<number>;
17
+ /**
18
+ * The scalar boundary. Everything downstream — comparisons, subject
19
+ * placeholders, resolved message props — is typed ScalarIR, but nothing so
20
+ * far has checked that the stored JSON is one: /identify validates only that
21
+ * `props` is a plain object, and the merge stores whatever nesting it is
22
+ * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true
23
+ * while `eq(score, 5)` is false, and `String(recipient)` on an object
24
+ * addresses an email to `[object Object]`.
25
+ *
26
+ * So a non-scalar value reads as absent, matching how matchesWhere treats a
27
+ * non-scalar payload leaf. The port cannot say "present but not a scalar",
28
+ * and guessing at a coercion is what produced the wrong branch in the first
29
+ * place.
30
+ */
31
+ getProperty(path: string): Promise<ScalarIR | undefined>;
32
+ getSegmentCondition(name: string): Promise<ConditionIR | undefined>;
33
+ /** The user's registered devices; none, and push skips while `reachable('push')` is false. */
34
+ isSuppressed(channel: string): Promise<boolean>;
35
+ listDevices(): Promise<PushDevice[]>;
36
+ }
37
+ //#endregion
38
+ //# sourceMappingURL=facts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.d.mts","names":[],"sources":["../../src/store/facts.ts"],"mappings":";;;;;qBAMa;;qBAGA,6BAA6B;mBAErB;mBACA;EAFnB,YACmB,OAAO,cACP;EAGb,YACJ,eACA;IAAS;IAAkB;IAAkB,QAAQ;MACpD;;;;;;;;;;;;;;;EA2BG,YAAY,eAAe,QAAQ;EAoBzC,oBAAoB,eAAe,QAAQ;;EAKrC,aAAa,kBAAkB;EAIrC,eAAe,QAAQ"}
@@ -0,0 +1,58 @@
1
+ import { matchesWhere } from "../engine/condition.mjs";
2
+ //#region src/store/facts.ts
3
+ /** The profile path that reads the user's own id (`u.userId`). */
4
+ const USER_ID_PROPERTY = "userId";
5
+ /** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */
6
+ var JourneyFactSource = class {
7
+ store;
8
+ userId;
9
+ constructor(store, userId) {
10
+ this.store = store;
11
+ this.userId = userId;
12
+ }
13
+ async countEvents(event, opts) {
14
+ const window = {
15
+ ...opts?.sinceMs === void 0 ? {} : { sinceMs: opts.sinceMs },
16
+ ...opts?.untilMs === void 0 ? {} : { untilMs: opts.untilMs }
17
+ };
18
+ if (opts?.where === void 0) return this.store.countEvents(this.userId, event, window);
19
+ const where = opts.where;
20
+ return (await this.store.listEventPayloads(this.userId, event, window)).filter((payload) => matchesWhere(payload, where)).length;
21
+ }
22
+ /**
23
+ * The scalar boundary. Everything downstream — comparisons, subject
24
+ * placeholders, resolved message props — is typed ScalarIR, but nothing so
25
+ * far has checked that the stored JSON is one: /identify validates only that
26
+ * `props` is a plain object, and the merge stores whatever nesting it is
27
+ * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true
28
+ * while `eq(score, 5)` is false, and `String(recipient)` on an object
29
+ * addresses an email to `[object Object]`.
30
+ *
31
+ * So a non-scalar value reads as absent, matching how matchesWhere treats a
32
+ * non-scalar payload leaf. The port cannot say "present but not a scalar",
33
+ * and guessing at a coercion is what produced the wrong branch in the first
34
+ * place.
35
+ */
36
+ async getProperty(path) {
37
+ if (path === "userId") return this.userId;
38
+ const props = await this.store.getProfile(this.userId);
39
+ if (props === void 0) return void 0;
40
+ if (!Object.hasOwn(props, path)) return void 0;
41
+ const value = props[path];
42
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
43
+ }
44
+ getSegmentCondition(name) {
45
+ return this.store.getSegmentCondition(name);
46
+ }
47
+ /** The user's registered devices; none, and push skips while `reachable('push')` is false. */
48
+ async isSuppressed(channel) {
49
+ return await this.store.isSuppressed?.(this.userId, channel) ?? false;
50
+ }
51
+ listDevices() {
52
+ return this.store.listDevices(this.userId);
53
+ }
54
+ };
55
+ //#endregion
56
+ export { JourneyFactSource, USER_ID_PROPERTY };
57
+
58
+ //# sourceMappingURL=facts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.mjs","names":[],"sources":["../../src/store/facts.ts"],"sourcesContent":["import { matchesWhere } from '../engine/condition';\nimport type { FactSource, PushDevice } from '../engine/ports';\nimport type { ConditionIR, ScalarIR } from '../ir';\nimport type { JourneyStore } from './index';\n\n/** The profile path that reads the user's own id (`u.userId`). */\nexport const USER_ID_PROPERTY = 'userId';\n\n/** Single-user fact source over a JourneyStore: evaluation lives in engine/condition.ts, this only reads. */\nexport class JourneyFactSource implements FactSource {\n constructor(\n private readonly store: JourneyStore,\n private readonly userId: string\n ) {}\n\n async countEvents(\n event: string,\n opts?: { sinceMs?: number; untilMs?: number; where?: ConditionIR }\n ): Promise<number> {\n const window = {\n ...(opts?.sinceMs === undefined ? {} : { sinceMs: opts.sinceMs }),\n ...(opts?.untilMs === undefined ? {} : { untilMs: opts.untilMs }),\n };\n if (opts?.where === undefined) return this.store.countEvents(this.userId, event, window);\n // Payload filtering happens in JS via the shared evaluator — one set of\n // where semantics with the in-memory FactSource; per-user row counts are small.\n const where = opts.where;\n const payloads = await this.store.listEventPayloads(this.userId, event, window);\n return payloads.filter((payload) => matchesWhere(payload, where)).length;\n }\n\n /**\n * The scalar boundary. Everything downstream — comparisons, subject\n * placeholders, resolved message props — is typed ScalarIR, but nothing so\n * far has checked that the stored JSON is one: /identify validates only that\n * `props` is a plain object, and the merge stores whatever nesting it is\n * handed. Left unchecked, `gt(score, 3)` on `['5']` coerces its way to true\n * while `eq(score, 5)` is false, and `String(recipient)` on an object\n * addresses an email to `[object Object]`.\n *\n * So a non-scalar value reads as absent, matching how matchesWhere treats a\n * non-scalar payload leaf. The port cannot say \"present but not a scalar\",\n * and guessing at a coercion is what produced the wrong branch in the first\n * place.\n */\n async getProperty(path: string): Promise<ScalarIR | undefined> {\n // The system field: the request's identity, never stored in the profile (contract.user.userId)\n if (path === USER_ID_PROPERTY) return this.userId;\n const props: Record<string, unknown> | undefined = await this.store.getProfile(this.userId);\n if (props === undefined) return undefined;\n // Own keys only: `props[path]` would otherwise find Object.prototype, so\n // `exists(u.toString)` held for every user with a profile row and a subject\n // placeholder rendered native-code text into the email.\n if (!Object.hasOwn(props, path)) return undefined;\n const value = props[path];\n // An explicit null means \"unset\" and behaves as not_exists. /identify\n // itself clears a property by removing the key (the merge drops nulls), so\n // this covers profiles written by other means — a direct SQL fixup, a\n // migration, an import.\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n return undefined;\n }\n\n getSegmentCondition(name: string): Promise<ConditionIR | undefined> {\n return this.store.getSegmentCondition(name);\n }\n\n /** The user's registered devices; none, and push skips while `reachable('push')` is false. */\n async isSuppressed(channel: string): Promise<boolean> {\n return (await this.store.isSuppressed?.(this.userId, channel)) ?? false;\n }\n\n listDevices(): Promise<PushDevice[]> {\n return this.store.listDevices(this.userId);\n }\n}\n"],"mappings":";;;AAMA,MAAa,mBAAmB;;AAGhC,IAAa,oBAAb,MAAqD;CAEhC;CACA;CAFnB,YACE,OACA,QACA;EAFiB,KAAA,QAAA;EACA,KAAA,SAAA;CAChB;CAEH,MAAM,YACJ,OACA,MACiB;EACjB,MAAM,SAAS;GACb,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;GAC/D,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,KAAK,QAAQ;EACjE;EACA,IAAI,MAAM,UAAU,KAAA,GAAW,OAAO,KAAK,MAAM,YAAY,KAAK,QAAQ,OAAO,MAAM;EAGvF,MAAM,QAAQ,KAAK;EAEnB,QAAO,MADgB,KAAK,MAAM,kBAAkB,KAAK,QAAQ,OAAO,MAAM,EAAA,CAC9D,QAAQ,YAAY,aAAa,SAAS,KAAK,CAAC,CAAC,CAAC;CACpE;;;;;;;;;;;;;;;CAgBA,MAAM,YAAY,MAA6C;EAE7D,IAAI,SAAA,UAA2B,OAAO,KAAK;EAC3C,MAAM,QAA6C,MAAM,KAAK,MAAM,WAAW,KAAK,MAAM;EAC1F,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAIhC,IAAI,CAAC,OAAO,OAAO,OAAO,IAAI,GAAG,OAAO,KAAA;EACxC,MAAM,QAAQ,MAAM;EAKpB,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,WAC7E,OAAO;CAGX;CAEA,oBAAoB,MAAgD;EAClE,OAAO,KAAK,MAAM,oBAAoB,IAAI;CAC5C;;CAGA,MAAM,aAAa,SAAmC;EACpD,OAAQ,MAAM,KAAK,MAAM,eAAe,KAAK,QAAQ,OAAO,KAAM;CACpE;CAEA,cAAqC;EACnC,OAAO,KAAK,MAAM,YAAY,KAAK,MAAM;CAC3C;AACF"}
@@ -0,0 +1,31 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_store_postgres_reporting = require("./postgres-reporting.cjs");
3
+ const require_store_tables = require("./tables.cjs");
4
+ const require_store_postgres = require("./postgres.cjs");
5
+ const require_store_facts = require("./facts.cjs");
6
+ const require_store_d1 = require("./d1.cjs");
7
+ //#region src/store/index.ts
8
+ /**
9
+ * The live database lacks tables or columns the engine reads (an SDK upgrade added them, or the
10
+ * host never ran the migration). Raised before a deploy writes anything.
11
+ */
12
+ var SchemaMismatchError = class extends Error {
13
+ problems;
14
+ name = "SchemaMismatchError";
15
+ constructor(problems) {
16
+ super(`the database does not match @shware/workflow's tables — regenerate the drizzle schema (workflow-ui generate) and run your migrations:\n ${problems.join("\n ")}`);
17
+ this.problems = problems;
18
+ }
19
+ };
20
+ //#endregion
21
+ exports.D1JourneyStore = require_store_d1.D1JourneyStore;
22
+ exports.DEFAULT_SCHEMA = require_store_tables.DEFAULT_SCHEMA;
23
+ exports.JourneyFactSource = require_store_facts.JourneyFactSource;
24
+ exports.PostgresJourneyStore = require_store_postgres.PostgresJourneyStore;
25
+ exports.PostgresReporting = require_store_postgres_reporting.PostgresReporting;
26
+ exports.SchemaMismatchError = SchemaMismatchError;
27
+ exports.TABLES = require_store_tables.TABLES;
28
+ exports.renderDrizzleSchema = require_store_tables.renderDrizzleSchema;
29
+ exports.renderPostgresDdl = require_store_tables.renderPostgresDdl;
30
+
31
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/store/index.ts"],"sourcesContent":["import type { PushDevice } from '../engine/ports';\nimport type { BundleIR, ConditionIR, ScalarIR, WorkflowIR } from '../ir';\n\n/**\n * The journey engine's data plane as a port. Everything the ingest router, the\n * runner and the fact source persist or look up goes through this interface,\n * so the storage engine is a deployment choice: D1 + KV (`D1JourneyStore`,\n * the original), Postgres (`PostgresJourneyStore`), or anything else that can\n * satisfy the contract below. Execution (durable steps, sleeps, wake-ups) is\n * the workflow runtime's job and stays out of here.\n *\n * Timestamps are epoch milliseconds throughout; a store may persist them in\n * its native type as long as `sinceMs` comparisons behave.\n */\n\n/**\n * A profile patch or a stored profile. On the way in, `null` means \"remove\n * this property\" (RFC 7386 merge-patch, the only way the API has to unset\n * one); a stored profile never contains null.\n */\nexport type ProfileProps = Record<string, ScalarIR | null | undefined>;\n\nexport interface EventInput {\n /** The occurrence's identity, chosen by the sender; a second insert with the same id is a no-op. */\n id: string;\n userId: string;\n event: string;\n ts: number;\n payload: Record<string, unknown>;\n}\n\nexport interface TriggerRoute {\n workflow: string;\n hash: string;\n /** Payload gate (payload-only condition tree), or null when the trigger has none. */\n where: ConditionIR | null;\n /** Profile gate, or null. */\n filter: ConditionIR | null;\n}\n\nexport interface SegmentTriggerRoute {\n workflow: string;\n hash: string;\n segment: string;\n}\n\nexport interface EntryInput {\n workflow: string;\n userId: string;\n instanceId: string;\n hash: string;\n ts: number;\n}\n\n/**\n * How an entry attempt ended: a fresh row, a 'failed' row of a dead instance\n * taken over (the once policy does not bar a user over one outage), or\n * refused because the pair already entered and is still alive.\n */\nexport type EntryOutcome = 'entered' | 'reclaimed' | null;\n\n/** A device registered for pushes: its provider token belongs to the user who registered it last. */\nexport interface DeviceInput {\n userId: string;\n token: string;\n /** `ios` (APNs) or `android` (FCM): which provider the token belongs to. */\n platform: string;\n ts: number;\n}\n\n/** A store plus how to release what opening it acquired (a connection, say). */\nexport interface StoreLease {\n store: JourneyStore;\n close?: () => Promise<void>;\n}\n\n/**\n * The live database lacks tables or columns the engine reads (an SDK upgrade added them, or the\n * host never ran the migration). Raised before a deploy writes anything.\n */\nexport class SchemaMismatchError extends Error {\n override readonly name = 'SchemaMismatchError';\n\n constructor(readonly problems: readonly string[]) {\n super(\n `the database does not match @shware/workflow's tables — regenerate the drizzle schema (workflow-ui generate) and run your migrations:\\n ${problems.join('\\n ')}`\n );\n }\n}\n\n/** A message copy as reporting records it, before it goes out. */\nexport interface MessageRecord {\n idempotencyKey: string;\n workflow: string;\n instanceId: string;\n nodeId: string;\n template: string;\n /** Where the copy lands: `email`, `push_ios`, `push_android`. */\n channel: string;\n userId: string;\n sentAt: number;\n}\n\n/** What a click is judged by. */\nexport interface ClickContext {\n url: string;\n deliveredAt: number;\n linkCount: number;\n /** The copy's clicks in the window before this one. */\n recent: { position: number; at: number }[];\n}\n\n/** An open or a click, with the verdict on who made it and where it came from. */\nexport interface Engagement {\n at: number;\n machine: boolean;\n /** The rule that called it a machine; null for a person. */\n reason: string | null;\n userAgent: string | null;\n /** The network the request came from (Cloudflare's `cf.asn`, `cf.asOrganization`, `cf.country`), never the address. */\n asn: number | null;\n organization: string | null;\n country: string | null;\n}\n\n/**\n * Journey reporting: where each instance stands, every copy and how it was engaged with, segment\n * sizes. A store that keeps it (Postgres) exposes it as `reporting`; the Worker then records it\n * and serves email tracking. Every write is idempotent — a retried step reports again.\n */\n/** Bounds on when an event happened, both inclusive (epoch ms); an absent side is open. */\nexport interface EventWindow {\n sinceMs?: number;\n untilMs?: number;\n}\n\nexport interface JourneyReporting {\n /** The instance entered: its row exists from here, so one a guard ends at once still counts. */\n instanceStarted(input: {\n workflow: string;\n instanceId: string;\n userId: string;\n at: number;\n }): Promise<void>;\n nodeReached(input: {\n workflow: string;\n instanceId: string;\n userId: string;\n nodeId: string;\n at: number;\n }): Promise<void>;\n instanceFinished(input: {\n workflow: string;\n instanceId: string;\n userId: string;\n status: string;\n at: number;\n convertedAt?: number;\n }): Promise<void>;\n /** The copy's row id; the row a retry already wrote, when there is one. */\n recordMessage(message: MessageRecord): Promise<string>;\n settleMessage(\n idempotencyKey: string,\n result: { delivered: true } | { delivered: false; reason: string },\n at: number\n ): Promise<void>;\n /** An email's tracked links, in document order. */\n recordLinks(messageId: string, urls: readonly string[]): Promise<void>;\n /**\n * Record an open of the copy, judged by `judge` against the copy (its recipient and when it was\n * delivered — when it was sent, before the transport answered); `undefined` from the judge\n * records nothing. Read and written in one transaction. False for an unknown copy.\n */\n recordOpen(\n messageId: string,\n judge: (message: { userId: string; deliveredAt: number }) => Engagement | undefined\n ): Promise<boolean>;\n /**\n * Record a click on the copy's link at `position`, judged by `judge` against the link, how\n * many links the copy has and its clicks of the last `windowMs`. The copy is locked for the\n * transaction, so clicks arriving together (a scanner following every link at once) are\n * judged one after another, each seeing the ones before. When the judge asks to `backdate`,\n * the window's earlier clicks are reclassified with this one's verdict. A click implies an\n * open. Undefined for an unknown link.\n */\n recordClick(\n messageId: string,\n position: number,\n at: number,\n windowMs: number,\n judge: (link: ClickContext) => { engagement: Engagement; backdate: boolean }\n ): Promise<{ url: string; engagement: Engagement } | undefined>;\n /** The email copy's recipient opted out of email: recorded on the copy and as a suppression. False for an unknown copy. */\n recordUnsubscribe(messageId: string, at: number): Promise<boolean>;\n /** A push copy the device reported it received. False for an unknown copy. */\n recordDeviceDelivered(messageId: string, at: number): Promise<boolean>;\n /** Drop members of segments no longer deployed, then record every deployed segment's size. */\n snapshotSegments(at: number): Promise<{ segment: string; size: number }[]>;\n}\n\nexport interface JourneyStore {\n /** Reporting, when the store keeps it (Postgres); D1 stores none. */\n readonly reporting?: JourneyReporting;\n\n /**\n * Record that the user's data must go (a deleted account), before anything is erased: the\n * request outlives a failure to stop their instances, and the sweep retries it.\n */\n requestErasure(userId: string, at: number): Promise<void>;\n /** Users whose erasure was requested and not finished yet. */\n pendingErasures(): Promise<string[]>;\n /** The user's journey instances still running, by the entry ledger. */\n runningInstances(userId: string): Promise<string[]>;\n /**\n * Erase everything kept about the user — profile, devices, events, wake subscriptions, segment\n * memberships, suppressions, entries and reporting — and the erasure request last. Run only\n * once no instance of theirs runs any more, or one could write some of it back.\n */\n forgetUser(userId: string): Promise<void>;\n\n /** The user opted out of the channel (recorded by an unsubscribe); stores without reporting omit it. */\n isSuppressed?(userId: string, channel: string): Promise<boolean>;\n\n /**\n * What the live database lacks against the engine's tables (read-only); a deploy refuses to\n * run while it lists anything. Stores whose schema the engine owns (D1) omit it.\n */\n checkSchema?(): Promise<string[]>;\n\n /* ---------------------------------- events --------------------------------- */\n /** Append the occurrence; false when its id was already in the log (nothing written). */\n insertEvent(input: EventInput): Promise<boolean>;\n /** Occurrences of `event` for the user, optionally only those within the window. */\n countEvents(userId: string, event: string, window?: EventWindow): Promise<number>;\n /** The payloads of those occurrences — the caller filters them with the shared evaluator. */\n listEventPayloads(\n userId: string,\n event: string,\n window?: EventWindow\n ): Promise<Record<string, unknown>[]>;\n\n /* --------------------------------- profiles -------------------------------- */\n getProfile(userId: string): Promise<ProfileProps | undefined>;\n /**\n * Merge-patch `props` into the stored profile in one statement (a null\n * removes the property) and return the result. One statement, because a\n * read-modify-write loses one of two concurrent identifies.\n */\n mergeProfile(userId: string, props: ProfileProps): Promise<ProfileProps>;\n\n /** Every user the engine knows (a profile or an event): who the segment sweep evaluates. */\n listUserIds(): Promise<string[]>;\n\n /* ---------------------------------- devices --------------------------------- */\n /** The user's push devices, most recently registered first. */\n listDevices(userId: string): Promise<PushDevice[]>;\n /**\n * Register a device: one row per token, so a token registered again moves to the user who\n * registered it last (a phone signed into another account) and to the front of their list.\n */\n upsertDevice(device: DeviceInput): Promise<void>;\n /** Forget a token (reported dead by APNs / FCM); the user it belonged to, if any. */\n removeDevice(token: string): Promise<string | undefined>;\n /**\n * The user signed out on the device: the token is kept, bound to nobody, until the next sign-in\n * binds it again. The user it belonged to, if any.\n */\n unbindDevice(token: string): Promise<string | undefined>;\n\n /* ---------------------------- deployed definitions -------------------------- */\n getSegmentCondition(id: string): Promise<ConditionIR | undefined>;\n /** Every deployed segment with its definition: what the segment sweep evaluates. */\n listSegments(): Promise<{ id: string; condition: ConditionIR }[]>;\n findTriggers(event: string): Promise<TriggerRoute[]>;\n listSegmentTriggers(): Promise<SegmentTriggerRoute[]>;\n putWorkflowIR(workflow: WorkflowIR): Promise<void>;\n getWorkflowIR(contentHash: string): Promise<WorkflowIR | undefined>;\n /**\n * Swap the routing tables (segments, event triggers, segment triggers) for\n * the bundle's — atomically, so a concurrent ingest never sees them half\n * empty. Workflow bodies are stored separately (`putWorkflowIR`) because they\n * are content-addressed and outlive the routes that point at them.\n */\n replaceRoutes(bundle: BundleIR): Promise<void>;\n\n /* ----------------------------- segment membership --------------------------- */\n isSegmentMember(segment: string, userId: string): Promise<boolean>;\n /** Record the membership, with the workflows its entry has to start (see segment_start). */\n addSegmentMember(\n segment: string,\n userId: string,\n ts: number,\n workflows: readonly string[]\n ): Promise<void>;\n /** The workflows the member's entry has not started yet. */\n pendingSegmentStarts(segment: string, userId: string): Promise<string[]>;\n completeSegmentStart(segment: string, userId: string, workflow: string): Promise<void>;\n /** Drop the membership and any start it still owed. */\n removeSegmentMember(segment: string, userId: string): Promise<void>;\n\n /* ------------------------------- entry ledger ------------------------------- */\n /**\n * Record the entry (the once policy). Atomic under concurrent ingests: of\n * two racing attempts exactly one is 'entered' (or 'reclaimed', when the\n * pair's previous instance is recorded as 'failed') and the other null.\n */\n enterJourney(entry: EntryInput): Promise<EntryOutcome>;\n removeEntry(instanceId: string): Promise<void>;\n setEntryStatus(instanceId: string, status: string): Promise<void>;\n\n /* ------------------------------ wake subscriptions --------------------------- */\n /** Distinct wake handles registered for (user, event). */\n findWakeHandles(userId: string, event: string): Promise<string[]>;\n /** Register the handle for each event; repeated registrations are idempotent. */\n subscribe(handle: string, userId: string, events: readonly string[], ts: number): Promise<void>;\n /** Drop every registration the handle holds. */\n unsubscribe(handle: string): Promise<void>;\n}\n\nexport { D1JourneyStore } from './d1';\nexport { JourneyFactSource } from './facts';\nexport { PostgresJourneyStore } from './postgres';\nexport { PostgresReporting } from './postgres-reporting';\nexport {\n DEFAULT_SCHEMA,\n TABLES,\n renderDrizzleSchema,\n renderPostgresDdl,\n type TableSpec,\n} from './tables';\nexport type { PostgresJourneyStoreOptions, SqlClientLike } from './postgres';\n"],"mappings":";;;;;;;;;;;AAgFA,IAAa,sBAAb,cAAyC,MAAM;CAGxB;CAFrB,OAAyB;CAEzB,YAAY,UAAsC;EAChD,MACE,4IAA4I,SAAS,KAAK,MAAM,GAClK;EAHmB,KAAA,WAAA;CAIrB;AACF"}
@@ -0,0 +1,291 @@
1
+ import { BundleIR, ConditionIR, ScalarIR, WorkflowIR } from "../ir.cjs";
2
+ import { PushDevice } from "../engine/ports.cjs";
3
+ import { D1JourneyStore } from "./d1.cjs";
4
+ import { JourneyFactSource } from "./facts.cjs";
5
+ import { SqlClientLike } from "./sql.cjs";
6
+ import { DEFAULT_SCHEMA, TABLES, TableSpec, renderDrizzleSchema, renderPostgresDdl } from "./tables.cjs";
7
+ import { PostgresJourneyStore, PostgresJourneyStoreOptions } from "./postgres.cjs";
8
+ import { PostgresReporting } from "./postgres-reporting.cjs";
9
+ //#region src/store/index.d.ts
10
+ /**
11
+ * The journey engine's data plane as a port. Everything the ingest router, the
12
+ * runner and the fact source persist or look up goes through this interface,
13
+ * so the storage engine is a deployment choice: D1 + KV (`D1JourneyStore`,
14
+ * the original), Postgres (`PostgresJourneyStore`), or anything else that can
15
+ * satisfy the contract below. Execution (durable steps, sleeps, wake-ups) is
16
+ * the workflow runtime's job and stays out of here.
17
+ *
18
+ * Timestamps are epoch milliseconds throughout; a store may persist them in
19
+ * its native type as long as `sinceMs` comparisons behave.
20
+ */
21
+ /**
22
+ * A profile patch or a stored profile. On the way in, `null` means "remove
23
+ * this property" (RFC 7386 merge-patch, the only way the API has to unset
24
+ * one); a stored profile never contains null.
25
+ */
26
+ export type ProfileProps = Record<string, ScalarIR | null | undefined>;
27
+ export interface EventInput {
28
+ /** The occurrence's identity, chosen by the sender; a second insert with the same id is a no-op. */
29
+ id: string;
30
+ userId: string;
31
+ event: string;
32
+ ts: number;
33
+ payload: Record<string, unknown>;
34
+ }
35
+ export interface TriggerRoute {
36
+ workflow: string;
37
+ hash: string;
38
+ /** Payload gate (payload-only condition tree), or null when the trigger has none. */
39
+ where: ConditionIR | null;
40
+ /** Profile gate, or null. */
41
+ filter: ConditionIR | null;
42
+ }
43
+ export interface SegmentTriggerRoute {
44
+ workflow: string;
45
+ hash: string;
46
+ segment: string;
47
+ }
48
+ export interface EntryInput {
49
+ workflow: string;
50
+ userId: string;
51
+ instanceId: string;
52
+ hash: string;
53
+ ts: number;
54
+ }
55
+ /**
56
+ * How an entry attempt ended: a fresh row, a 'failed' row of a dead instance
57
+ * taken over (the once policy does not bar a user over one outage), or
58
+ * refused because the pair already entered and is still alive.
59
+ */
60
+ export type EntryOutcome = 'entered' | 'reclaimed' | null;
61
+ /** A device registered for pushes: its provider token belongs to the user who registered it last. */
62
+ export interface DeviceInput {
63
+ userId: string;
64
+ token: string;
65
+ /** `ios` (APNs) or `android` (FCM): which provider the token belongs to. */
66
+ platform: string;
67
+ ts: number;
68
+ }
69
+ /** A store plus how to release what opening it acquired (a connection, say). */
70
+ export interface StoreLease {
71
+ store: JourneyStore;
72
+ close?: () => Promise<void>;
73
+ }
74
+ /**
75
+ * The live database lacks tables or columns the engine reads (an SDK upgrade added them, or the
76
+ * host never ran the migration). Raised before a deploy writes anything.
77
+ */
78
+ export declare class SchemaMismatchError extends Error {
79
+ readonly problems: readonly string[];
80
+ readonly name = "SchemaMismatchError";
81
+ constructor(problems: readonly string[]);
82
+ }
83
+ /** A message copy as reporting records it, before it goes out. */
84
+ export interface MessageRecord {
85
+ idempotencyKey: string;
86
+ workflow: string;
87
+ instanceId: string;
88
+ nodeId: string;
89
+ template: string;
90
+ /** Where the copy lands: `email`, `push_ios`, `push_android`. */
91
+ channel: string;
92
+ userId: string;
93
+ sentAt: number;
94
+ }
95
+ /** What a click is judged by. */
96
+ export interface ClickContext {
97
+ url: string;
98
+ deliveredAt: number;
99
+ linkCount: number;
100
+ /** The copy's clicks in the window before this one. */
101
+ recent: {
102
+ position: number;
103
+ at: number;
104
+ }[];
105
+ }
106
+ /** An open or a click, with the verdict on who made it and where it came from. */
107
+ export interface Engagement {
108
+ at: number;
109
+ machine: boolean;
110
+ /** The rule that called it a machine; null for a person. */
111
+ reason: string | null;
112
+ userAgent: string | null;
113
+ /** The network the request came from (Cloudflare's `cf.asn`, `cf.asOrganization`, `cf.country`), never the address. */
114
+ asn: number | null;
115
+ organization: string | null;
116
+ country: string | null;
117
+ }
118
+ /**
119
+ * Journey reporting: where each instance stands, every copy and how it was engaged with, segment
120
+ * sizes. A store that keeps it (Postgres) exposes it as `reporting`; the Worker then records it
121
+ * and serves email tracking. Every write is idempotent — a retried step reports again.
122
+ */
123
+ /** Bounds on when an event happened, both inclusive (epoch ms); an absent side is open. */
124
+ export interface EventWindow {
125
+ sinceMs?: number;
126
+ untilMs?: number;
127
+ }
128
+ export interface JourneyReporting {
129
+ /** The instance entered: its row exists from here, so one a guard ends at once still counts. */
130
+ instanceStarted(input: {
131
+ workflow: string;
132
+ instanceId: string;
133
+ userId: string;
134
+ at: number;
135
+ }): Promise<void>;
136
+ nodeReached(input: {
137
+ workflow: string;
138
+ instanceId: string;
139
+ userId: string;
140
+ nodeId: string;
141
+ at: number;
142
+ }): Promise<void>;
143
+ instanceFinished(input: {
144
+ workflow: string;
145
+ instanceId: string;
146
+ userId: string;
147
+ status: string;
148
+ at: number;
149
+ convertedAt?: number;
150
+ }): Promise<void>;
151
+ /** The copy's row id; the row a retry already wrote, when there is one. */
152
+ recordMessage(message: MessageRecord): Promise<string>;
153
+ settleMessage(idempotencyKey: string, result: {
154
+ delivered: true;
155
+ } | {
156
+ delivered: false;
157
+ reason: string;
158
+ }, at: number): Promise<void>;
159
+ /** An email's tracked links, in document order. */
160
+ recordLinks(messageId: string, urls: readonly string[]): Promise<void>;
161
+ /**
162
+ * Record an open of the copy, judged by `judge` against the copy (its recipient and when it was
163
+ * delivered — when it was sent, before the transport answered); `undefined` from the judge
164
+ * records nothing. Read and written in one transaction. False for an unknown copy.
165
+ */
166
+ recordOpen(messageId: string, judge: (message: {
167
+ userId: string;
168
+ deliveredAt: number;
169
+ }) => Engagement | undefined): Promise<boolean>;
170
+ /**
171
+ * Record a click on the copy's link at `position`, judged by `judge` against the link, how
172
+ * many links the copy has and its clicks of the last `windowMs`. The copy is locked for the
173
+ * transaction, so clicks arriving together (a scanner following every link at once) are
174
+ * judged one after another, each seeing the ones before. When the judge asks to `backdate`,
175
+ * the window's earlier clicks are reclassified with this one's verdict. A click implies an
176
+ * open. Undefined for an unknown link.
177
+ */
178
+ recordClick(messageId: string, position: number, at: number, windowMs: number, judge: (link: ClickContext) => {
179
+ engagement: Engagement;
180
+ backdate: boolean;
181
+ }): Promise<{
182
+ url: string;
183
+ engagement: Engagement;
184
+ } | undefined>;
185
+ /** The email copy's recipient opted out of email: recorded on the copy and as a suppression. False for an unknown copy. */
186
+ recordUnsubscribe(messageId: string, at: number): Promise<boolean>;
187
+ /** A push copy the device reported it received. False for an unknown copy. */
188
+ recordDeviceDelivered(messageId: string, at: number): Promise<boolean>;
189
+ /** Drop members of segments no longer deployed, then record every deployed segment's size. */
190
+ snapshotSegments(at: number): Promise<{
191
+ segment: string;
192
+ size: number;
193
+ }[]>;
194
+ }
195
+ export interface JourneyStore {
196
+ /** Reporting, when the store keeps it (Postgres); D1 stores none. */
197
+ readonly reporting?: JourneyReporting;
198
+ /**
199
+ * Record that the user's data must go (a deleted account), before anything is erased: the
200
+ * request outlives a failure to stop their instances, and the sweep retries it.
201
+ */
202
+ requestErasure(userId: string, at: number): Promise<void>;
203
+ /** Users whose erasure was requested and not finished yet. */
204
+ pendingErasures(): Promise<string[]>;
205
+ /** The user's journey instances still running, by the entry ledger. */
206
+ runningInstances(userId: string): Promise<string[]>;
207
+ /**
208
+ * Erase everything kept about the user — profile, devices, events, wake subscriptions, segment
209
+ * memberships, suppressions, entries and reporting — and the erasure request last. Run only
210
+ * once no instance of theirs runs any more, or one could write some of it back.
211
+ */
212
+ forgetUser(userId: string): Promise<void>;
213
+ /** The user opted out of the channel (recorded by an unsubscribe); stores without reporting omit it. */
214
+ isSuppressed?(userId: string, channel: string): Promise<boolean>;
215
+ /**
216
+ * What the live database lacks against the engine's tables (read-only); a deploy refuses to
217
+ * run while it lists anything. Stores whose schema the engine owns (D1) omit it.
218
+ */
219
+ checkSchema?(): Promise<string[]>;
220
+ /** Append the occurrence; false when its id was already in the log (nothing written). */
221
+ insertEvent(input: EventInput): Promise<boolean>;
222
+ /** Occurrences of `event` for the user, optionally only those within the window. */
223
+ countEvents(userId: string, event: string, window?: EventWindow): Promise<number>;
224
+ /** The payloads of those occurrences — the caller filters them with the shared evaluator. */
225
+ listEventPayloads(userId: string, event: string, window?: EventWindow): Promise<Record<string, unknown>[]>;
226
+ getProfile(userId: string): Promise<ProfileProps | undefined>;
227
+ /**
228
+ * Merge-patch `props` into the stored profile in one statement (a null
229
+ * removes the property) and return the result. One statement, because a
230
+ * read-modify-write loses one of two concurrent identifies.
231
+ */
232
+ mergeProfile(userId: string, props: ProfileProps): Promise<ProfileProps>;
233
+ /** Every user the engine knows (a profile or an event): who the segment sweep evaluates. */
234
+ listUserIds(): Promise<string[]>;
235
+ /** The user's push devices, most recently registered first. */
236
+ listDevices(userId: string): Promise<PushDevice[]>;
237
+ /**
238
+ * Register a device: one row per token, so a token registered again moves to the user who
239
+ * registered it last (a phone signed into another account) and to the front of their list.
240
+ */
241
+ upsertDevice(device: DeviceInput): Promise<void>;
242
+ /** Forget a token (reported dead by APNs / FCM); the user it belonged to, if any. */
243
+ removeDevice(token: string): Promise<string | undefined>;
244
+ /**
245
+ * The user signed out on the device: the token is kept, bound to nobody, until the next sign-in
246
+ * binds it again. The user it belonged to, if any.
247
+ */
248
+ unbindDevice(token: string): Promise<string | undefined>;
249
+ getSegmentCondition(id: string): Promise<ConditionIR | undefined>;
250
+ /** Every deployed segment with its definition: what the segment sweep evaluates. */
251
+ listSegments(): Promise<{
252
+ id: string;
253
+ condition: ConditionIR;
254
+ }[]>;
255
+ findTriggers(event: string): Promise<TriggerRoute[]>;
256
+ listSegmentTriggers(): Promise<SegmentTriggerRoute[]>;
257
+ putWorkflowIR(workflow: WorkflowIR): Promise<void>;
258
+ getWorkflowIR(contentHash: string): Promise<WorkflowIR | undefined>;
259
+ /**
260
+ * Swap the routing tables (segments, event triggers, segment triggers) for
261
+ * the bundle's — atomically, so a concurrent ingest never sees them half
262
+ * empty. Workflow bodies are stored separately (`putWorkflowIR`) because they
263
+ * are content-addressed and outlive the routes that point at them.
264
+ */
265
+ replaceRoutes(bundle: BundleIR): Promise<void>;
266
+ isSegmentMember(segment: string, userId: string): Promise<boolean>;
267
+ /** Record the membership, with the workflows its entry has to start (see segment_start). */
268
+ addSegmentMember(segment: string, userId: string, ts: number, workflows: readonly string[]): Promise<void>;
269
+ /** The workflows the member's entry has not started yet. */
270
+ pendingSegmentStarts(segment: string, userId: string): Promise<string[]>;
271
+ completeSegmentStart(segment: string, userId: string, workflow: string): Promise<void>;
272
+ /** Drop the membership and any start it still owed. */
273
+ removeSegmentMember(segment: string, userId: string): Promise<void>;
274
+ /**
275
+ * Record the entry (the once policy). Atomic under concurrent ingests: of
276
+ * two racing attempts exactly one is 'entered' (or 'reclaimed', when the
277
+ * pair's previous instance is recorded as 'failed') and the other null.
278
+ */
279
+ enterJourney(entry: EntryInput): Promise<EntryOutcome>;
280
+ removeEntry(instanceId: string): Promise<void>;
281
+ setEntryStatus(instanceId: string, status: string): Promise<void>;
282
+ /** Distinct wake handles registered for (user, event). */
283
+ findWakeHandles(userId: string, event: string): Promise<string[]>;
284
+ /** Register the handle for each event; repeated registrations are idempotent. */
285
+ subscribe(handle: string, userId: string, events: readonly string[], ts: number): Promise<void>;
286
+ /** Drop every registration the handle holds. */
287
+ unsubscribe(handle: string): Promise<void>;
288
+ }
289
+ //#endregion
290
+ export { D1JourneyStore, DEFAULT_SCHEMA, JourneyFactSource, PostgresJourneyStore, type PostgresJourneyStoreOptions, PostgresReporting, type SqlClientLike, TABLES, type TableSpec, renderDrizzleSchema, renderPostgresDdl };
291
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/store/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;YAoBY,eAAe,eAAe;iBAEzB;;EAEf;EACA;EACA;EACA;EACA,SAAS;;iBAGM;EACf;EACA;;EAEA,OAAO;;EAEP,QAAQ;;iBAGO;EACf;EACA;EACA;;iBAGe;EACf;EACA;EACA;EACA;EACA;;;;;;;YAQU;;iBAGK;EACf;EACA;;EAEA;EACA;;;iBAIe;EACf,OAAO;EACP,cAAc;;;;;;qBAOH,4BAA4B;WAGlB;WAFH;EAElB,YAAqB;;;iBAQN;EACf;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;;iBAIe;EACf;EACA;EACA;;EAEA;IAAU;IAAkB;;;;iBAIb;EACf;EACA;;EAEA;EACA;;EAEA;EACA;EACA;;;;;;;;iBASe;EACf;EACA;;iBAGe;;EAEf,gBAAgB;IACd;IACA;IACA;IACA;MACE;EACJ,YAAY;IACV;IACA;IACA;IACA;IACA;MACE;EACJ,iBAAiB;IACf;IACA;IACA;IACA;IACA;IACA;MACE;;EAEJ,cAAc,SAAS,gBAAgB;EACvC,cACE,wBACA;IAAU;;IAAsB;IAAkB;KAClD,aACC;;EAEH,YAAY,mBAAmB,0BAA0B;;;;;;EAMzD,WACE,mBACA,QAAQ;IAAW;IAAgB;QAA0B,yBAC5D;;;;;;;;;EASH,YACE,mBACA,kBACA,YACA,kBACA,QAAQ,MAAM;IAAmB,YAAY;IAAY;MACxD;IAAU;IAAa,YAAY;;;EAEtC,kBAAkB,mBAAmB,aAAa;;EAElD,sBAAsB,mBAAmB,aAAa;;EAEtD,iBAAiB,aAAa;IAAU;IAAiB;;;iBAG1C;;WAEN,YAAY;;;;;EAMrB,eAAe,gBAAgB,aAAa;;EAE5C,mBAAmB;;EAEnB,iBAAiB,iBAAiB;;;;;;EAMlC,WAAW,iBAAiB;;EAG5B,cAAc,gBAAgB,kBAAkB;;;;;EAMhD,gBAAgB;;EAIhB,YAAY,OAAO,aAAa;;EAEhC,YAAY,gBAAgB,eAAe,SAAS,cAAc;;EAElE,kBACE,gBACA,eACA,SAAS,cACR,QAAQ;EAGX,WAAW,iBAAiB,QAAQ;;;;;;EAMpC,aAAa,gBAAgB,OAAO,eAAe,QAAQ;;EAG3D,eAAe;;EAIf,YAAY,iBAAiB,QAAQ;;;;;EAKrC,aAAa,QAAQ,cAAc;;EAEnC,aAAa,gBAAgB;;;;;EAK7B,aAAa,gBAAgB;EAG7B,oBAAoB,aAAa,QAAQ;;EAEzC,gBAAgB;IAAU;IAAY,WAAW;;EACjD,aAAa,gBAAgB,QAAQ;EACrC,uBAAuB,QAAQ;EAC/B,cAAc,UAAU,aAAa;EACrC,cAAc,sBAAsB,QAAQ;;;;;;;EAO5C,cAAc,QAAQ,WAAW;EAGjC,gBAAgB,iBAAiB,iBAAiB;;EAElD,iBACE,iBACA,gBACA,YACA,+BACC;;EAEH,qBAAqB,iBAAiB,iBAAiB;EACvD,qBAAqB,iBAAiB,gBAAgB,mBAAmB;;EAEzE,oBAAoB,iBAAiB,iBAAiB;;;;;;EAQtD,aAAa,OAAO,aAAa,QAAQ;EACzC,YAAY,qBAAqB;EACjC,eAAe,oBAAoB,iBAAiB;;EAIpD,gBAAgB,gBAAgB,gBAAgB;;EAEhD,UAAU,gBAAgB,gBAAgB,2BAA2B,aAAa;;EAElF,YAAY,iBAAiB"}