@shware/workflow 0.0.0-stage → 0.0.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,177 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_dsl_refs = require("./refs.cjs");
3
+ const require_provenance = require("../provenance.cjs");
4
+ const require_dsl_base = require("./base.cjs");
5
+ //#region src/dsl/condition.ts
6
+ const cond = (ir, loc) => {
7
+ return {
8
+ __condition: true,
9
+ ir: loc === void 0 ? ir : {
10
+ ...ir,
11
+ meta: { loc }
12
+ }
13
+ };
14
+ };
15
+ /** @internal unwrap a condition to its IR — used by flow/trigger/workflow builders */
16
+ const condIR = (c) => {
17
+ const ir = c.ir;
18
+ if (ir === void 0) throw new Error("Condition was not created by this DSL — use the predicates (eq/gt/…), combinators (and/or/not) or segment()");
19
+ return ir;
20
+ };
21
+ /**
22
+ * A payload ref identifies itself by a symbol key, and a user-property ref by
23
+ * the absence of one. Nothing here reads a *string* key off the reference: a
24
+ * payload ref hands out sub-refs for every string key, so a field named `type`
25
+ * or `path` would otherwise answer in place of the ref itself.
26
+ */
27
+ const payloadPathOf = (ref) => ref[require_dsl_refs.PAYLOAD_PATH];
28
+ function prop(ref, op, value, values, loc) {
29
+ const payloadPath = payloadPathOf(ref);
30
+ return cond({
31
+ type: payloadPath !== void 0 ? "payload" : "property",
32
+ path: payloadPath ?? ref.path,
33
+ op,
34
+ ...value !== void 0 ? { value } : {},
35
+ ...values !== void 0 ? { values: [...values] } : {}
36
+ }, loc);
37
+ }
38
+ function eq(ref, value) {
39
+ return prop(ref, "eq", value, void 0, require_provenance.captureLoc(eq));
40
+ }
41
+ function ne(ref, value) {
42
+ return prop(ref, "ne", value, void 0, require_provenance.captureLoc(ne));
43
+ }
44
+ function gt(ref, value) {
45
+ return prop(ref, "gt", value, void 0, require_provenance.captureLoc(gt));
46
+ }
47
+ function gte(ref, value) {
48
+ return prop(ref, "gte", value, void 0, require_provenance.captureLoc(gte));
49
+ }
50
+ function lt(ref, value) {
51
+ return prop(ref, "lt", value, void 0, require_provenance.captureLoc(lt));
52
+ }
53
+ function lte(ref, value) {
54
+ return prop(ref, "lte", value, void 0, require_provenance.captureLoc(lte));
55
+ }
56
+ function between(ref, min, max) {
57
+ return prop(ref, "between", void 0, [min, max], require_provenance.captureLoc(between));
58
+ }
59
+ function notBetween(ref, min, max) {
60
+ return prop(ref, "not_between", void 0, [min, max], require_provenance.captureLoc(notBetween));
61
+ }
62
+ function inArray(ref, values) {
63
+ return prop(ref, "in_array", void 0, values, require_provenance.captureLoc(inArray));
64
+ }
65
+ function notInArray(ref, values) {
66
+ return prop(ref, "not_in_array", void 0, values, require_provenance.captureLoc(notInArray));
67
+ }
68
+ function exists(ref) {
69
+ return prop(ref, "exists", void 0, void 0, require_provenance.captureLoc(exists));
70
+ }
71
+ function notExists(ref) {
72
+ return prop(ref, "not_exists", void 0, void 0, require_provenance.captureLoc(notExists));
73
+ }
74
+ function contains(ref, value) {
75
+ return prop(ref, "contains", value, void 0, require_provenance.captureLoc(contains));
76
+ }
77
+ function notContains(ref, value) {
78
+ return prop(ref, "not_contains", value, void 0, require_provenance.captureLoc(notContains));
79
+ }
80
+ function performed(event, whereOrOpts, maybeOpts) {
81
+ const where = typeof whereOrOpts === "function" ? whereOrOpts : void 0;
82
+ const opts = typeof whereOrOpts === "function" ? maybeOpts : whereOrOpts;
83
+ return cond({
84
+ type: "performed",
85
+ event: event.name,
86
+ ...where !== void 0 ? { where: condIR(where(require_dsl_refs.payloadRefs())) } : {},
87
+ ...opts?.within !== void 0 ? { within: require_dsl_base.durationIR(opts.within) } : {},
88
+ ...opts?.count !== void 0 ? { count: opts.count } : {}
89
+ }, require_provenance.captureLoc(performed));
90
+ }
91
+ /**
92
+ * The user can be reached on a channel right now. For push it asks the host's
93
+ * device directory (at least one device listed) — the engine keeps no device
94
+ * state, so this is the way to branch on "has the app on a device that allowed
95
+ * notifications"; for the other channels it checks the recipient property
96
+ * (`email`, `phone`, …). Inside `waitUntil` it wakes on device changes
97
+ * (`POST /devices/changed`) or profile updates respectively.
98
+ *
99
+ * .branch([reachable('push'), (w) => w.push(tip)], (w) => w.email(tip))
100
+ */
101
+ function reachable(channel) {
102
+ return cond({
103
+ type: "reachable",
104
+ channel
105
+ }, require_provenance.captureLoc(reachable));
106
+ }
107
+ /** Condition combinators: nest freely. */
108
+ function and(...conditions) {
109
+ return cond({
110
+ type: "and",
111
+ conditions: conditions.map(condIR)
112
+ }, require_provenance.captureLoc(and));
113
+ }
114
+ function or(...conditions) {
115
+ return cond({
116
+ type: "or",
117
+ conditions: conditions.map(condIR)
118
+ }, require_provenance.captureLoc(or));
119
+ }
120
+ function not(condition) {
121
+ return cond({
122
+ type: "not",
123
+ condition: condIR(condition)
124
+ }, require_provenance.captureLoc(not));
125
+ }
126
+ /**
127
+ * Segment definition. `name` and `description` are optional labels: metadata,
128
+ * dropped before hashing, and what the studio shows.
129
+ *
130
+ * export const purchaser = segment({
131
+ * id: 'purchaser',
132
+ * name: 'Purchased (last 30d)',
133
+ * condition: performed(e.purchase, { within: '30 days' }),
134
+ * });
135
+ */
136
+ function segment({ id, condition, name, description }) {
137
+ const meta = {
138
+ ...name === void 0 ? {} : { name },
139
+ ...description === void 0 ? {} : { description }
140
+ };
141
+ return {
142
+ __condition: true,
143
+ __segment: true,
144
+ id,
145
+ ir: {
146
+ type: "segment",
147
+ segment: id
148
+ },
149
+ definition: condIR(condition),
150
+ loc: require_provenance.captureLoc(segment),
151
+ meta: Object.keys(meta).length === 0 ? void 0 : meta
152
+ };
153
+ }
154
+ //#endregion
155
+ exports.and = and;
156
+ exports.between = between;
157
+ exports.condIR = condIR;
158
+ exports.contains = contains;
159
+ exports.eq = eq;
160
+ exports.exists = exists;
161
+ exports.gt = gt;
162
+ exports.gte = gte;
163
+ exports.inArray = inArray;
164
+ exports.lt = lt;
165
+ exports.lte = lte;
166
+ exports.ne = ne;
167
+ exports.not = not;
168
+ exports.notBetween = notBetween;
169
+ exports.notContains = notContains;
170
+ exports.notExists = notExists;
171
+ exports.notInArray = notInArray;
172
+ exports.or = or;
173
+ exports.performed = performed;
174
+ exports.reachable = reachable;
175
+ exports.segment = segment;
176
+
177
+ //# sourceMappingURL=condition.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.cjs","names":["PAYLOAD_PATH","captureLoc","payloadRefs","durationIR"],"sources":["../../src/dsl/condition.ts"],"sourcesContent":["import type { ConditionIR, SourceLocIR } from '../ir';\nimport { captureLoc } from '../provenance';\nimport { type Duration, durationIR } from './base';\nimport {\n type EventRef,\n PAYLOAD_PATH,\n type PayloadRef,\n type PayloadRefs,\n type UserPropertyRef,\n payloadRefs,\n} from './refs';\nimport type { Channel } from './template';\n\n/**\n * Conditions — drizzle-style predicate expressions: free functions (eq/gt/…)\n * composed with and/or/not, plus `segment` for naming an expression as a\n * top-level asset. A condition is an opaque handle wrapping its ConditionIR.\n *\n * Type techniques:\n * - Types flow in from the reference's phantom type; operator applicability is\n * a signature constraint (gt only takes string|number refs, contains only\n * string ones), mirroring customer.io's condition panel.\n * - Value parameters are always NoInfer: types come from the reference only,\n * which stops eq(ref, 'typo') from widening T to include the bad value.\n *\n * TODO: JSON array 'where at least one'、JSON object 'has the property'。\n */\n\n/** Opaque condition handle — what predicates, combinators and segments all produce. */\nexport interface Condition {\n readonly __condition: true;\n}\n\ninterface ConditionInternal extends Condition {\n readonly ir: ConditionIR;\n}\n\nconst cond = (ir: ConditionIR, loc?: SourceLocIR): Condition => {\n const impl: ConditionInternal = {\n __condition: true,\n ir: loc === undefined ? ir : { ...ir, meta: { loc } },\n };\n return impl;\n};\n\n/** @internal unwrap a condition to its IR — used by flow/trigger/workflow builders */\nexport const condIR = (c: Condition): ConditionIR => {\n // Partial: the cast is unsound for hand-rolled objects — exactly what this checks\n const ir = (c as Partial<ConditionInternal>).ir;\n if (ir === undefined) {\n // A hand-rolled `{ __condition: true }` would otherwise surface as a\n // baffling zod error at toIR() time, far away from the actual mistake.\n throw new Error(\n 'Condition was not created by this DSL — use the predicates (eq/gt/…), combinators (and/or/not) or segment()'\n );\n }\n return ir;\n};\n\ntype Scalar = string | number | boolean;\n\n/**\n * Predicates accept either kind of reference: a user property (profile\n * condition) or an event payload field (only valid inside a `where` — the\n * bundle compiler enforces the placement, since both produce `Condition`).\n */\ntype CondRef<T> = UserPropertyRef<T> | PayloadRef<T>;\n\n/**\n * A payload ref identifies itself by a symbol key, and a user-property ref by\n * the absence of one. Nothing here reads a *string* key off the reference: a\n * payload ref hands out sub-refs for every string key, so a field named `type`\n * or `path` would otherwise answer in place of the ref itself.\n */\nconst payloadPathOf = (ref: CondRef<unknown>): string | undefined =>\n (ref as Partial<PayloadRef<unknown>>)[PAYLOAD_PATH];\n\nfunction prop(\n ref: CondRef<unknown>,\n op:\n | 'eq'\n | 'ne'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'between'\n | 'not_between'\n | 'in_array'\n | 'not_in_array'\n | 'exists'\n | 'not_exists'\n | 'contains'\n | 'not_contains',\n value?: Scalar,\n values?: readonly Scalar[],\n loc?: SourceLocIR\n): Condition {\n const payloadPath = payloadPathOf(ref);\n return cond(\n {\n type: payloadPath !== undefined ? 'payload' : 'property',\n path: payloadPath ?? (ref as UserPropertyRef<unknown>).path,\n op,\n ...(value !== undefined ? { value } : {}),\n ...(values !== undefined ? { values: [...values] } : {}),\n },\n loc\n );\n}\n\nexport function eq<T>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'eq', value as Scalar, undefined, captureLoc(eq));\n}\nexport function ne<T>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'ne', value as Scalar, undefined, captureLoc(ne));\n}\nexport function gt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'gt', value, undefined, captureLoc(gt));\n}\nexport function gte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'gte', value, undefined, captureLoc(gte));\n}\nexport function lt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'lt', value, undefined, captureLoc(lt));\n}\nexport function lte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition {\n return prop(ref, 'lte', value, undefined, captureLoc(lte));\n}\nexport function between<T extends string | number>(\n ref: CondRef<T>,\n min: NoInfer<T>,\n max: NoInfer<T>\n): Condition {\n return prop(ref, 'between', undefined, [min, max], captureLoc(between));\n}\nexport function notBetween<T extends string | number>(\n ref: CondRef<T>,\n min: NoInfer<T>,\n max: NoInfer<T>\n): Condition {\n return prop(ref, 'not_between', undefined, [min, max], captureLoc(notBetween));\n}\nexport function inArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition {\n return prop(ref, 'in_array', undefined, values as readonly Scalar[], captureLoc(inArray));\n}\nexport function notInArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition {\n return prop(ref, 'not_in_array', undefined, values as readonly Scalar[], captureLoc(notInArray));\n}\nexport function exists(ref: CondRef<unknown>): Condition {\n return prop(ref, 'exists', undefined, undefined, captureLoc(exists));\n}\nexport function notExists(ref: CondRef<unknown>): Condition {\n return prop(ref, 'not_exists', undefined, undefined, captureLoc(notExists));\n}\nexport function contains<T extends string>(ref: CondRef<T>, value: string): Condition {\n return prop(ref, 'contains', value, undefined, captureLoc(contains));\n}\nexport function notContains<T extends string>(ref: CondRef<T>, value: string): Condition {\n return prop(ref, 'not_contains', value, undefined, captureLoc(notContains));\n}\n\nexport interface PerformedOptions {\n within?: Duration;\n count?: number;\n}\n\n/** A payload where clause: an arrow taking the typed payload-ref table. Runs once at construction — the result is a serializable condition tree in IR, never a closure. */\nexport type PayloadWhere<P> = (p: PayloadRefs<P>) => Condition;\n\n/**\n * Event predicate: performed an event (optionally within a window / at least N\n * times). \"Did not perform\" is `not(performed(...))` — expressed by the\n * combinator, so there is no separate notPerformed.\n *\n * The optional second argument narrows which events count by their payload —\n * an arrow receiving a typed payload reference table, with the ordinary\n * predicates applying. It compiles to a `where` subtree in IR (data the UI\n * renders), not a runtime closure:\n *\n * performed(e.login)\n * performed(e.login, (p) => and(eq(p.platform, 'web'), eq(p.tags.utm_source, 'meta')))\n * performed(e.purchase, (p) => gt(p.value, 100), { within: '30 days', count: 2 })\n * performed(e.purchase, { within: '30 days' }) // options without a where\n *\n * Time anchoring: evaluated inside a `goal` the count starts at workflow\n * entry, inside `waitUntil` at the moment the wait began (the engine anchors\n * them — a conversion or a wake must not be satisfied by pre-existing\n * history). Everywhere else (branch/filter/exitWhen/segments) it looks over\n * full history, bounded only by `within`.\n */\nexport function performed<P>(event: EventRef<P>, opts?: PerformedOptions): Condition;\nexport function performed<P>(\n event: EventRef<P>,\n where: PayloadWhere<P>,\n opts?: PerformedOptions\n): Condition;\nexport function performed<P>(\n event: EventRef<P>,\n whereOrOpts?: PayloadWhere<P> | PerformedOptions,\n maybeOpts?: PerformedOptions\n): Condition {\n const where = typeof whereOrOpts === 'function' ? whereOrOpts : undefined;\n const opts = typeof whereOrOpts === 'function' ? maybeOpts : whereOrOpts;\n return cond(\n {\n type: 'performed',\n event: event.name,\n ...(where !== undefined ? { where: condIR(where(payloadRefs<P>())) } : {}),\n ...(opts?.within !== undefined ? { within: durationIR(opts.within) } : {}),\n ...(opts?.count !== undefined ? { count: opts.count } : {}),\n },\n captureLoc(performed)\n );\n}\n\n/**\n * The user can be reached on a channel right now. For push it asks the host's\n * device directory (at least one device listed) — the engine keeps no device\n * state, so this is the way to branch on \"has the app on a device that allowed\n * notifications\"; for the other channels it checks the recipient property\n * (`email`, `phone`, …). Inside `waitUntil` it wakes on device changes\n * (`POST /devices/changed`) or profile updates respectively.\n *\n * .branch([reachable('push'), (w) => w.push(tip)], (w) => w.email(tip))\n */\nexport function reachable(channel: Channel): Condition {\n return cond({ type: 'reachable', channel }, captureLoc(reachable));\n}\n\n/** Condition combinators: nest freely. */\nexport function and(...conditions: readonly Condition[]): Condition {\n return cond({ type: 'and', conditions: conditions.map(condIR) }, captureLoc(and));\n}\nexport function or(...conditions: readonly Condition[]): Condition {\n return cond({ type: 'or', conditions: conditions.map(condIR) }, captureLoc(or));\n}\nexport function not(condition: Condition): Condition {\n return cond({ type: 'not', condition: condIR(condition) }, captureLoc(not));\n}\n\n/**\n * Segment: a named condition expression and a top-level asset — it shows up in\n * the UI sidebar, is reusable across workflows, is referenced by id in IR,\n * and has a continuously materialized membership count (the prerequisite for\n * segment triggers). Anonymous reuse is just a const expression; a one-off\n * check is an inline expression at the use site.\n * TODO, to match customer.io's panel: form / page / device / screen /\n * opt-out / message data(email opened、sms clicked、webhook …)\n */\nexport interface SegmentRef extends Condition {\n readonly __segment: true;\n /** Wire identity: segment references and the membership store are keyed on it (`SegmentIR.id`). */\n readonly id: string;\n}\n\n/** @internal the compiled shape behind a SegmentRef — compileBundle reads definition/loc off it */\nexport interface SegmentInternal extends SegmentRef {\n readonly ir: ConditionIR;\n /** Human label / description; metadata, so never part of the hash. */\n readonly meta: SegmentMeta | undefined;\n /** The segment's own definition (SegmentIR.condition), as opposed to a reference by id. */\n readonly definition: ConditionIR;\n /** Callsite of the segment() call (provenance; lands in SegmentIR.meta.loc). */\n readonly loc: SourceLocIR | undefined;\n}\n\n/** Labels for a segment: what the studio shows instead of the wire key. */\nexport interface SegmentMeta {\n name?: string;\n description?: string;\n}\n\nexport interface SegmentDefinition extends SegmentMeta {\n /**\n * Wire identity — by-name references and the membership store are keyed on\n * it, so it is not something to rename for readability.\n */\n id: string;\n /** Who is in the segment; the predicates already checked its types. */\n condition: Condition;\n}\n\n/**\n * Segment definition. `name` and `description` are optional labels: metadata,\n * dropped before hashing, and what the studio shows.\n *\n * export const purchaser = segment({\n * id: 'purchaser',\n * name: 'Purchased (last 30d)',\n * condition: performed(e.purchase, { within: '30 days' }),\n * });\n */\nexport function segment({ id, condition, name, description }: SegmentDefinition): SegmentRef {\n const meta: SegmentMeta = {\n ...(name === undefined ? {} : { name }),\n ...(description === undefined ? {} : { description }),\n };\n const impl: SegmentInternal = {\n __condition: true,\n __segment: true,\n id,\n ir: { type: 'segment', segment: id },\n definition: condIR(condition),\n loc: captureLoc(segment),\n meta: Object.keys(meta).length === 0 ? undefined : meta,\n };\n return impl;\n}\n"],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ import { ConditionIR, SourceLocIR } from "../ir.cjs";
2
+ import { Duration } from "./base.cjs";
3
+ import { EventRef, PayloadRef, PayloadRefs, UserPropertyRef } from "./refs.cjs";
4
+ import { Channel } from "./template.cjs";
5
+ //#region src/dsl/condition.d.ts
6
+ /**
7
+ * Conditions — drizzle-style predicate expressions: free functions (eq/gt/…)
8
+ * composed with and/or/not, plus `segment` for naming an expression as a
9
+ * top-level asset. A condition is an opaque handle wrapping its ConditionIR.
10
+ *
11
+ * Type techniques:
12
+ * - Types flow in from the reference's phantom type; operator applicability is
13
+ * a signature constraint (gt only takes string|number refs, contains only
14
+ * string ones), mirroring customer.io's condition panel.
15
+ * - Value parameters are always NoInfer: types come from the reference only,
16
+ * which stops eq(ref, 'typo') from widening T to include the bad value.
17
+ *
18
+ * TODO: JSON array 'where at least one'、JSON object 'has the property'。
19
+ */
20
+ /** Opaque condition handle — what predicates, combinators and segments all produce. */
21
+ export interface Condition {
22
+ readonly __condition: true;
23
+ }
24
+ /** @internal unwrap a condition to its IR — used by flow/trigger/workflow builders */
25
+ export declare const condIR: (c: Condition) => ConditionIR;
26
+ /**
27
+ * Predicates accept either kind of reference: a user property (profile
28
+ * condition) or an event payload field (only valid inside a `where` — the
29
+ * bundle compiler enforces the placement, since both produce `Condition`).
30
+ */
31
+ type CondRef<T> = UserPropertyRef<T> | PayloadRef<T>;
32
+ export declare function eq<T>(ref: CondRef<T>, value: NoInfer<T>): Condition;
33
+ export declare function ne<T>(ref: CondRef<T>, value: NoInfer<T>): Condition;
34
+ export declare function gt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
35
+ export declare function gte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
36
+ export declare function lt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
37
+ export declare function lte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
38
+ export declare function between<T extends string | number>(ref: CondRef<T>, min: NoInfer<T>, max: NoInfer<T>): Condition;
39
+ export declare function notBetween<T extends string | number>(ref: CondRef<T>, min: NoInfer<T>, max: NoInfer<T>): Condition;
40
+ export declare function inArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition;
41
+ export declare function notInArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition;
42
+ export declare function exists(ref: CondRef<unknown>): Condition;
43
+ export declare function notExists(ref: CondRef<unknown>): Condition;
44
+ export declare function contains<T extends string>(ref: CondRef<T>, value: string): Condition;
45
+ export declare function notContains<T extends string>(ref: CondRef<T>, value: string): Condition;
46
+ export interface PerformedOptions {
47
+ within?: Duration;
48
+ count?: number;
49
+ }
50
+ /** A payload where clause: an arrow taking the typed payload-ref table. Runs once at construction — the result is a serializable condition tree in IR, never a closure. */
51
+ export type PayloadWhere<P> = (p: PayloadRefs<P>) => Condition;
52
+ /**
53
+ * Event predicate: performed an event (optionally within a window / at least N
54
+ * times). "Did not perform" is `not(performed(...))` — expressed by the
55
+ * combinator, so there is no separate notPerformed.
56
+ *
57
+ * The optional second argument narrows which events count by their payload —
58
+ * an arrow receiving a typed payload reference table, with the ordinary
59
+ * predicates applying. It compiles to a `where` subtree in IR (data the UI
60
+ * renders), not a runtime closure:
61
+ *
62
+ * performed(e.login)
63
+ * performed(e.login, (p) => and(eq(p.platform, 'web'), eq(p.tags.utm_source, 'meta')))
64
+ * performed(e.purchase, (p) => gt(p.value, 100), { within: '30 days', count: 2 })
65
+ * performed(e.purchase, { within: '30 days' }) // options without a where
66
+ *
67
+ * Time anchoring: evaluated inside a `goal` the count starts at workflow
68
+ * entry, inside `waitUntil` at the moment the wait began (the engine anchors
69
+ * them — a conversion or a wake must not be satisfied by pre-existing
70
+ * history). Everywhere else (branch/filter/exitWhen/segments) it looks over
71
+ * full history, bounded only by `within`.
72
+ */
73
+ export declare function performed<P>(event: EventRef<P>, opts?: PerformedOptions): Condition;
74
+ export declare function performed<P>(event: EventRef<P>, where: PayloadWhere<P>, opts?: PerformedOptions): Condition;
75
+ /**
76
+ * The user can be reached on a channel right now. For push it asks the host's
77
+ * device directory (at least one device listed) — the engine keeps no device
78
+ * state, so this is the way to branch on "has the app on a device that allowed
79
+ * notifications"; for the other channels it checks the recipient property
80
+ * (`email`, `phone`, …). Inside `waitUntil` it wakes on device changes
81
+ * (`POST /devices/changed`) or profile updates respectively.
82
+ *
83
+ * .branch([reachable('push'), (w) => w.push(tip)], (w) => w.email(tip))
84
+ */
85
+ export declare function reachable(channel: Channel): Condition;
86
+ /** Condition combinators: nest freely. */
87
+ export declare function and(...conditions: readonly Condition[]): Condition;
88
+ export declare function or(...conditions: readonly Condition[]): Condition;
89
+ export declare function not(condition: Condition): Condition;
90
+ /**
91
+ * Segment: a named condition expression and a top-level asset — it shows up in
92
+ * the UI sidebar, is reusable across workflows, is referenced by id in IR,
93
+ * and has a continuously materialized membership count (the prerequisite for
94
+ * segment triggers). Anonymous reuse is just a const expression; a one-off
95
+ * check is an inline expression at the use site.
96
+ * TODO, to match customer.io's panel: form / page / device / screen /
97
+ * opt-out / message data(email opened、sms clicked、webhook …)
98
+ */
99
+ export interface SegmentRef extends Condition {
100
+ readonly __segment: true;
101
+ /** Wire identity: segment references and the membership store are keyed on it (`SegmentIR.id`). */
102
+ readonly id: string;
103
+ }
104
+ /** @internal the compiled shape behind a SegmentRef — compileBundle reads definition/loc off it */
105
+ export interface SegmentInternal extends SegmentRef {
106
+ readonly ir: ConditionIR;
107
+ /** Human label / description; metadata, so never part of the hash. */
108
+ readonly meta: SegmentMeta | undefined;
109
+ /** The segment's own definition (SegmentIR.condition), as opposed to a reference by id. */
110
+ readonly definition: ConditionIR;
111
+ /** Callsite of the segment() call (provenance; lands in SegmentIR.meta.loc). */
112
+ readonly loc: SourceLocIR | undefined;
113
+ }
114
+ /** Labels for a segment: what the studio shows instead of the wire key. */
115
+ export interface SegmentMeta {
116
+ name?: string;
117
+ description?: string;
118
+ }
119
+ export interface SegmentDefinition extends SegmentMeta {
120
+ /**
121
+ * Wire identity — by-name references and the membership store are keyed on
122
+ * it, so it is not something to rename for readability.
123
+ */
124
+ id: string;
125
+ /** Who is in the segment; the predicates already checked its types. */
126
+ condition: Condition;
127
+ }
128
+ /**
129
+ * Segment definition. `name` and `description` are optional labels: metadata,
130
+ * dropped before hashing, and what the studio shows.
131
+ *
132
+ * export const purchaser = segment({
133
+ * id: 'purchaser',
134
+ * name: 'Purchased (last 30d)',
135
+ * condition: performed(e.purchase, { within: '30 days' }),
136
+ * });
137
+ */
138
+ export declare function segment({ id, condition, name, description }: SegmentDefinition): SegmentRef;
139
+ //#endregion
140
+ //# sourceMappingURL=condition.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.d.cts","names":[],"sources":["../../src/dsl/condition.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;iBA6BiB;WACN;;;qBAgBE,SAAM,GAAO,cAAY;;;;;;KAoBjC,QAAQ,KAAK,gBAAgB,KAAK,WAAW;wBA6ClC,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAG3C,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAG3C,GAAG,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGnE,IAAI,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGpE,GAAG,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGnE,IAAI,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGpE,QAAQ,2BACtB,KAAK,QAAQ,IACb,KAAK,QAAQ,IACb,KAAK,QAAQ,KACZ;wBAGa,WAAW,2BACzB,KAAK,QAAQ,IACb,KAAK,QAAQ,IACb,KAAK,QAAQ,KACZ;wBAGa,QAAQ,GAAG,KAAK,QAAQ,IAAI,iBAAiB,QAAQ,OAAO;wBAG5D,WAAW,GAAG,KAAK,QAAQ,IAAI,iBAAiB,QAAQ,OAAO;wBAG/D,OAAO,KAAK,mBAAmB;wBAG/B,UAAU,KAAK,mBAAmB;wBAGlC,SAAS,kBAAkB,KAAK,QAAQ,IAAI,gBAAgB;wBAG5D,YAAY,kBAAkB,KAAK,QAAQ,IAAI,gBAAgB;iBAI9D;EACf,SAAS;EACT;;;YAIU,aAAa,MAAM,GAAG,YAAY,OAAO;;;;;;;;;;;;;;;;;;;;;;wBAuBrC,UAAU,GAAG,OAAO,SAAS,IAAI,OAAO,mBAAmB;wBAC3D,UAAU,GACxB,OAAO,SAAS,IAChB,OAAO,aAAa,IACpB,OAAO,mBACN;;;;;;;;;;;wBA8Ba,UAAU,SAAS,UAAU;;wBAK7B,OAAO,qBAAqB,cAAc;wBAG1C,MAAM,qBAAqB,cAAc;wBAGzC,IAAI,WAAW,YAAY;;;;;;;;;;iBAa1B,mBAAmB;WACzB;;WAEA;;;iBAIM,wBAAwB;WAC9B,IAAI;;WAEJ,MAAM;;WAEN,YAAY;;WAEZ,KAAK;;;iBAIC;EACf;EACA;;iBAGe,0BAA0B;;;;;EAKzC;;EAEA,WAAW;;;;;;;;;;;;wBAaG,UAAU,IAAI,WAAW,MAAM,eAAe,oBAAoB"}
@@ -0,0 +1,140 @@
1
+ import { ConditionIR, SourceLocIR } from "../ir.mjs";
2
+ import { Duration } from "./base.mjs";
3
+ import { EventRef, PayloadRef, PayloadRefs, UserPropertyRef } from "./refs.mjs";
4
+ import { Channel } from "./template.mjs";
5
+ //#region src/dsl/condition.d.ts
6
+ /**
7
+ * Conditions — drizzle-style predicate expressions: free functions (eq/gt/…)
8
+ * composed with and/or/not, plus `segment` for naming an expression as a
9
+ * top-level asset. A condition is an opaque handle wrapping its ConditionIR.
10
+ *
11
+ * Type techniques:
12
+ * - Types flow in from the reference's phantom type; operator applicability is
13
+ * a signature constraint (gt only takes string|number refs, contains only
14
+ * string ones), mirroring customer.io's condition panel.
15
+ * - Value parameters are always NoInfer: types come from the reference only,
16
+ * which stops eq(ref, 'typo') from widening T to include the bad value.
17
+ *
18
+ * TODO: JSON array 'where at least one'、JSON object 'has the property'。
19
+ */
20
+ /** Opaque condition handle — what predicates, combinators and segments all produce. */
21
+ export interface Condition {
22
+ readonly __condition: true;
23
+ }
24
+ /** @internal unwrap a condition to its IR — used by flow/trigger/workflow builders */
25
+ export declare const condIR: (c: Condition) => ConditionIR;
26
+ /**
27
+ * Predicates accept either kind of reference: a user property (profile
28
+ * condition) or an event payload field (only valid inside a `where` — the
29
+ * bundle compiler enforces the placement, since both produce `Condition`).
30
+ */
31
+ type CondRef<T> = UserPropertyRef<T> | PayloadRef<T>;
32
+ export declare function eq<T>(ref: CondRef<T>, value: NoInfer<T>): Condition;
33
+ export declare function ne<T>(ref: CondRef<T>, value: NoInfer<T>): Condition;
34
+ export declare function gt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
35
+ export declare function gte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
36
+ export declare function lt<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
37
+ export declare function lte<T extends string | number>(ref: CondRef<T>, value: NoInfer<T>): Condition;
38
+ export declare function between<T extends string | number>(ref: CondRef<T>, min: NoInfer<T>, max: NoInfer<T>): Condition;
39
+ export declare function notBetween<T extends string | number>(ref: CondRef<T>, min: NoInfer<T>, max: NoInfer<T>): Condition;
40
+ export declare function inArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition;
41
+ export declare function notInArray<T>(ref: CondRef<T>, values: readonly NoInfer<T>[]): Condition;
42
+ export declare function exists(ref: CondRef<unknown>): Condition;
43
+ export declare function notExists(ref: CondRef<unknown>): Condition;
44
+ export declare function contains<T extends string>(ref: CondRef<T>, value: string): Condition;
45
+ export declare function notContains<T extends string>(ref: CondRef<T>, value: string): Condition;
46
+ export interface PerformedOptions {
47
+ within?: Duration;
48
+ count?: number;
49
+ }
50
+ /** A payload where clause: an arrow taking the typed payload-ref table. Runs once at construction — the result is a serializable condition tree in IR, never a closure. */
51
+ export type PayloadWhere<P> = (p: PayloadRefs<P>) => Condition;
52
+ /**
53
+ * Event predicate: performed an event (optionally within a window / at least N
54
+ * times). "Did not perform" is `not(performed(...))` — expressed by the
55
+ * combinator, so there is no separate notPerformed.
56
+ *
57
+ * The optional second argument narrows which events count by their payload —
58
+ * an arrow receiving a typed payload reference table, with the ordinary
59
+ * predicates applying. It compiles to a `where` subtree in IR (data the UI
60
+ * renders), not a runtime closure:
61
+ *
62
+ * performed(e.login)
63
+ * performed(e.login, (p) => and(eq(p.platform, 'web'), eq(p.tags.utm_source, 'meta')))
64
+ * performed(e.purchase, (p) => gt(p.value, 100), { within: '30 days', count: 2 })
65
+ * performed(e.purchase, { within: '30 days' }) // options without a where
66
+ *
67
+ * Time anchoring: evaluated inside a `goal` the count starts at workflow
68
+ * entry, inside `waitUntil` at the moment the wait began (the engine anchors
69
+ * them — a conversion or a wake must not be satisfied by pre-existing
70
+ * history). Everywhere else (branch/filter/exitWhen/segments) it looks over
71
+ * full history, bounded only by `within`.
72
+ */
73
+ export declare function performed<P>(event: EventRef<P>, opts?: PerformedOptions): Condition;
74
+ export declare function performed<P>(event: EventRef<P>, where: PayloadWhere<P>, opts?: PerformedOptions): Condition;
75
+ /**
76
+ * The user can be reached on a channel right now. For push it asks the host's
77
+ * device directory (at least one device listed) — the engine keeps no device
78
+ * state, so this is the way to branch on "has the app on a device that allowed
79
+ * notifications"; for the other channels it checks the recipient property
80
+ * (`email`, `phone`, …). Inside `waitUntil` it wakes on device changes
81
+ * (`POST /devices/changed`) or profile updates respectively.
82
+ *
83
+ * .branch([reachable('push'), (w) => w.push(tip)], (w) => w.email(tip))
84
+ */
85
+ export declare function reachable(channel: Channel): Condition;
86
+ /** Condition combinators: nest freely. */
87
+ export declare function and(...conditions: readonly Condition[]): Condition;
88
+ export declare function or(...conditions: readonly Condition[]): Condition;
89
+ export declare function not(condition: Condition): Condition;
90
+ /**
91
+ * Segment: a named condition expression and a top-level asset — it shows up in
92
+ * the UI sidebar, is reusable across workflows, is referenced by id in IR,
93
+ * and has a continuously materialized membership count (the prerequisite for
94
+ * segment triggers). Anonymous reuse is just a const expression; a one-off
95
+ * check is an inline expression at the use site.
96
+ * TODO, to match customer.io's panel: form / page / device / screen /
97
+ * opt-out / message data(email opened、sms clicked、webhook …)
98
+ */
99
+ export interface SegmentRef extends Condition {
100
+ readonly __segment: true;
101
+ /** Wire identity: segment references and the membership store are keyed on it (`SegmentIR.id`). */
102
+ readonly id: string;
103
+ }
104
+ /** @internal the compiled shape behind a SegmentRef — compileBundle reads definition/loc off it */
105
+ export interface SegmentInternal extends SegmentRef {
106
+ readonly ir: ConditionIR;
107
+ /** Human label / description; metadata, so never part of the hash. */
108
+ readonly meta: SegmentMeta | undefined;
109
+ /** The segment's own definition (SegmentIR.condition), as opposed to a reference by id. */
110
+ readonly definition: ConditionIR;
111
+ /** Callsite of the segment() call (provenance; lands in SegmentIR.meta.loc). */
112
+ readonly loc: SourceLocIR | undefined;
113
+ }
114
+ /** Labels for a segment: what the studio shows instead of the wire key. */
115
+ export interface SegmentMeta {
116
+ name?: string;
117
+ description?: string;
118
+ }
119
+ export interface SegmentDefinition extends SegmentMeta {
120
+ /**
121
+ * Wire identity — by-name references and the membership store are keyed on
122
+ * it, so it is not something to rename for readability.
123
+ */
124
+ id: string;
125
+ /** Who is in the segment; the predicates already checked its types. */
126
+ condition: Condition;
127
+ }
128
+ /**
129
+ * Segment definition. `name` and `description` are optional labels: metadata,
130
+ * dropped before hashing, and what the studio shows.
131
+ *
132
+ * export const purchaser = segment({
133
+ * id: 'purchaser',
134
+ * name: 'Purchased (last 30d)',
135
+ * condition: performed(e.purchase, { within: '30 days' }),
136
+ * });
137
+ */
138
+ export declare function segment({ id, condition, name, description }: SegmentDefinition): SegmentRef;
139
+ //#endregion
140
+ //# sourceMappingURL=condition.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"condition.d.mts","names":[],"sources":["../../src/dsl/condition.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;iBA6BiB;WACN;;;qBAgBE,SAAM,GAAO,cAAY;;;;;;KAoBjC,QAAQ,KAAK,gBAAgB,KAAK,WAAW;wBA6ClC,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAG3C,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAG3C,GAAG,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGnE,IAAI,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGpE,GAAG,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGnE,IAAI,2BAA2B,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK;wBAGpE,QAAQ,2BACtB,KAAK,QAAQ,IACb,KAAK,QAAQ,IACb,KAAK,QAAQ,KACZ;wBAGa,WAAW,2BACzB,KAAK,QAAQ,IACb,KAAK,QAAQ,IACb,KAAK,QAAQ,KACZ;wBAGa,QAAQ,GAAG,KAAK,QAAQ,IAAI,iBAAiB,QAAQ,OAAO;wBAG5D,WAAW,GAAG,KAAK,QAAQ,IAAI,iBAAiB,QAAQ,OAAO;wBAG/D,OAAO,KAAK,mBAAmB;wBAG/B,UAAU,KAAK,mBAAmB;wBAGlC,SAAS,kBAAkB,KAAK,QAAQ,IAAI,gBAAgB;wBAG5D,YAAY,kBAAkB,KAAK,QAAQ,IAAI,gBAAgB;iBAI9D;EACf,SAAS;EACT;;;YAIU,aAAa,MAAM,GAAG,YAAY,OAAO;;;;;;;;;;;;;;;;;;;;;;wBAuBrC,UAAU,GAAG,OAAO,SAAS,IAAI,OAAO,mBAAmB;wBAC3D,UAAU,GACxB,OAAO,SAAS,IAChB,OAAO,aAAa,IACpB,OAAO,mBACN;;;;;;;;;;;wBA8Ba,UAAU,SAAS,UAAU;;wBAK7B,OAAO,qBAAqB,cAAc;wBAG1C,MAAM,qBAAqB,cAAc;wBAGzC,IAAI,WAAW,YAAY;;;;;;;;;;iBAa1B,mBAAmB;WACzB;;WAEA;;;iBAIM,wBAAwB;WAC9B,IAAI;;WAEJ,MAAM;;WAEN,YAAY;;WAEZ,KAAK;;;iBAIC;EACf;EACA;;iBAGe,0BAA0B;;;;;EAKzC;;EAEA,WAAW;;;;;;;;;;;;wBAaG,UAAU,IAAI,WAAW,MAAM,eAAe,oBAAoB"}
@@ -0,0 +1,156 @@
1
+ import { PAYLOAD_PATH, payloadRefs } from "./refs.mjs";
2
+ import { captureLoc } from "../provenance.mjs";
3
+ import { durationIR } from "./base.mjs";
4
+ //#region src/dsl/condition.ts
5
+ const cond = (ir, loc) => {
6
+ return {
7
+ __condition: true,
8
+ ir: loc === void 0 ? ir : {
9
+ ...ir,
10
+ meta: { loc }
11
+ }
12
+ };
13
+ };
14
+ /** @internal unwrap a condition to its IR — used by flow/trigger/workflow builders */
15
+ const condIR = (c) => {
16
+ const ir = c.ir;
17
+ if (ir === void 0) throw new Error("Condition was not created by this DSL — use the predicates (eq/gt/…), combinators (and/or/not) or segment()");
18
+ return ir;
19
+ };
20
+ /**
21
+ * A payload ref identifies itself by a symbol key, and a user-property ref by
22
+ * the absence of one. Nothing here reads a *string* key off the reference: a
23
+ * payload ref hands out sub-refs for every string key, so a field named `type`
24
+ * or `path` would otherwise answer in place of the ref itself.
25
+ */
26
+ const payloadPathOf = (ref) => ref[PAYLOAD_PATH];
27
+ function prop(ref, op, value, values, loc) {
28
+ const payloadPath = payloadPathOf(ref);
29
+ return cond({
30
+ type: payloadPath !== void 0 ? "payload" : "property",
31
+ path: payloadPath ?? ref.path,
32
+ op,
33
+ ...value !== void 0 ? { value } : {},
34
+ ...values !== void 0 ? { values: [...values] } : {}
35
+ }, loc);
36
+ }
37
+ function eq(ref, value) {
38
+ return prop(ref, "eq", value, void 0, captureLoc(eq));
39
+ }
40
+ function ne(ref, value) {
41
+ return prop(ref, "ne", value, void 0, captureLoc(ne));
42
+ }
43
+ function gt(ref, value) {
44
+ return prop(ref, "gt", value, void 0, captureLoc(gt));
45
+ }
46
+ function gte(ref, value) {
47
+ return prop(ref, "gte", value, void 0, captureLoc(gte));
48
+ }
49
+ function lt(ref, value) {
50
+ return prop(ref, "lt", value, void 0, captureLoc(lt));
51
+ }
52
+ function lte(ref, value) {
53
+ return prop(ref, "lte", value, void 0, captureLoc(lte));
54
+ }
55
+ function between(ref, min, max) {
56
+ return prop(ref, "between", void 0, [min, max], captureLoc(between));
57
+ }
58
+ function notBetween(ref, min, max) {
59
+ return prop(ref, "not_between", void 0, [min, max], captureLoc(notBetween));
60
+ }
61
+ function inArray(ref, values) {
62
+ return prop(ref, "in_array", void 0, values, captureLoc(inArray));
63
+ }
64
+ function notInArray(ref, values) {
65
+ return prop(ref, "not_in_array", void 0, values, captureLoc(notInArray));
66
+ }
67
+ function exists(ref) {
68
+ return prop(ref, "exists", void 0, void 0, captureLoc(exists));
69
+ }
70
+ function notExists(ref) {
71
+ return prop(ref, "not_exists", void 0, void 0, captureLoc(notExists));
72
+ }
73
+ function contains(ref, value) {
74
+ return prop(ref, "contains", value, void 0, captureLoc(contains));
75
+ }
76
+ function notContains(ref, value) {
77
+ return prop(ref, "not_contains", value, void 0, captureLoc(notContains));
78
+ }
79
+ function performed(event, whereOrOpts, maybeOpts) {
80
+ const where = typeof whereOrOpts === "function" ? whereOrOpts : void 0;
81
+ const opts = typeof whereOrOpts === "function" ? maybeOpts : whereOrOpts;
82
+ return cond({
83
+ type: "performed",
84
+ event: event.name,
85
+ ...where !== void 0 ? { where: condIR(where(payloadRefs())) } : {},
86
+ ...opts?.within !== void 0 ? { within: durationIR(opts.within) } : {},
87
+ ...opts?.count !== void 0 ? { count: opts.count } : {}
88
+ }, captureLoc(performed));
89
+ }
90
+ /**
91
+ * The user can be reached on a channel right now. For push it asks the host's
92
+ * device directory (at least one device listed) — the engine keeps no device
93
+ * state, so this is the way to branch on "has the app on a device that allowed
94
+ * notifications"; for the other channels it checks the recipient property
95
+ * (`email`, `phone`, …). Inside `waitUntil` it wakes on device changes
96
+ * (`POST /devices/changed`) or profile updates respectively.
97
+ *
98
+ * .branch([reachable('push'), (w) => w.push(tip)], (w) => w.email(tip))
99
+ */
100
+ function reachable(channel) {
101
+ return cond({
102
+ type: "reachable",
103
+ channel
104
+ }, captureLoc(reachable));
105
+ }
106
+ /** Condition combinators: nest freely. */
107
+ function and(...conditions) {
108
+ return cond({
109
+ type: "and",
110
+ conditions: conditions.map(condIR)
111
+ }, captureLoc(and));
112
+ }
113
+ function or(...conditions) {
114
+ return cond({
115
+ type: "or",
116
+ conditions: conditions.map(condIR)
117
+ }, captureLoc(or));
118
+ }
119
+ function not(condition) {
120
+ return cond({
121
+ type: "not",
122
+ condition: condIR(condition)
123
+ }, captureLoc(not));
124
+ }
125
+ /**
126
+ * Segment definition. `name` and `description` are optional labels: metadata,
127
+ * dropped before hashing, and what the studio shows.
128
+ *
129
+ * export const purchaser = segment({
130
+ * id: 'purchaser',
131
+ * name: 'Purchased (last 30d)',
132
+ * condition: performed(e.purchase, { within: '30 days' }),
133
+ * });
134
+ */
135
+ function segment({ id, condition, name, description }) {
136
+ const meta = {
137
+ ...name === void 0 ? {} : { name },
138
+ ...description === void 0 ? {} : { description }
139
+ };
140
+ return {
141
+ __condition: true,
142
+ __segment: true,
143
+ id,
144
+ ir: {
145
+ type: "segment",
146
+ segment: id
147
+ },
148
+ definition: condIR(condition),
149
+ loc: captureLoc(segment),
150
+ meta: Object.keys(meta).length === 0 ? void 0 : meta
151
+ };
152
+ }
153
+ //#endregion
154
+ export { and, between, condIR, contains, eq, exists, gt, gte, inArray, lt, lte, ne, not, notBetween, notContains, notExists, notInArray, or, performed, reachable, segment };
155
+
156
+ //# sourceMappingURL=condition.mjs.map