@reventlessdev/online-shop-aggregates-catalog 3.0.0-alpha.101

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 (330) hide show
  1. package/CHANGELOG.md +854 -0
  2. package/LICENSE +202 -0
  3. package/__mocks__/emptyModule.js +1 -0
  4. package/lib/bs/.compiler.log +2 -0
  5. package/lib/bs/CatalogPlugin.cmi +0 -0
  6. package/lib/bs/CatalogPlugin.cmj +0 -0
  7. package/lib/bs/CatalogPlugin.cmt +0 -0
  8. package/lib/bs/CatalogPlugin.mlmap +25 -0
  9. package/lib/bs/build.ninja +0 -0
  10. package/lib/bs/compiler-info.json +8 -0
  11. package/lib/bs/src/Category/Aggregate/Category-CatalogPlugin.cmi +0 -0
  12. package/lib/bs/src/Category/Aggregate/Category-CatalogPlugin.cmj +0 -0
  13. package/lib/bs/src/Category/Aggregate/Category-CatalogPlugin.cmt +0 -0
  14. package/lib/bs/src/Category/Aggregate/Category.ast +0 -0
  15. package/lib/bs/src/Category/Aggregate/Category.res +22 -0
  16. package/lib/bs/src/Category/Aggregate/Category.res.mjs +61 -0
  17. package/lib/bs/src/Category/Aggregate/Category_Behavior-CatalogPlugin.cmi +0 -0
  18. package/lib/bs/src/Category/Aggregate/Category_Behavior-CatalogPlugin.cmj +0 -0
  19. package/lib/bs/src/Category/Aggregate/Category_Behavior-CatalogPlugin.cmt +0 -0
  20. package/lib/bs/src/Category/Aggregate/Category_Behavior.ast +0 -0
  21. package/lib/bs/src/Category/Aggregate/Category_Behavior.res +36 -0
  22. package/lib/bs/src/Category/Aggregate/Category_Behavior.res.mjs +106 -0
  23. package/lib/bs/src/Category/ReadModel/Categories-CatalogPlugin.cmi +0 -0
  24. package/lib/bs/src/Category/ReadModel/Categories-CatalogPlugin.cmj +0 -0
  25. package/lib/bs/src/Category/ReadModel/Categories-CatalogPlugin.cmt +0 -0
  26. package/lib/bs/src/Category/ReadModel/Categories.ast +0 -0
  27. package/lib/bs/src/Category/ReadModel/Categories.res +11 -0
  28. package/lib/bs/src/Category/ReadModel/Categories.res.mjs +35 -0
  29. package/lib/bs/src/Category/ReadModel/Categories_Projections-CatalogPlugin.cmi +0 -0
  30. package/lib/bs/src/Category/ReadModel/Categories_Projections-CatalogPlugin.cmj +0 -0
  31. package/lib/bs/src/Category/ReadModel/Categories_Projections-CatalogPlugin.cmt +0 -0
  32. package/lib/bs/src/Category/ReadModel/Categories_Projections.ast +0 -0
  33. package/lib/bs/src/Category/ReadModel/Categories_Projections.res +19 -0
  34. package/lib/bs/src/Category/ReadModel/Categories_Projections.res.mjs +75 -0
  35. package/lib/bs/src/Extension/Orders_Extension-CatalogPlugin.cmi +0 -0
  36. package/lib/bs/src/Extension/Orders_Extension-CatalogPlugin.cmj +0 -0
  37. package/lib/bs/src/Extension/Orders_Extension-CatalogPlugin.cmt +0 -0
  38. package/lib/bs/src/Extension/Orders_Extension.ast +0 -0
  39. package/lib/bs/src/Extension/Orders_Extension.res +23 -0
  40. package/lib/bs/src/Extension/Orders_Extension.res.mjs +42 -0
  41. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping-CatalogPlugin.cmi +0 -0
  42. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping-CatalogPlugin.cmj +0 -0
  43. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping-CatalogPlugin.cmt +0 -0
  44. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping.ast +0 -0
  45. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping.res +19 -0
  46. package/lib/bs/src/ExtensionPoint/Products_ExtensionPointMapping.res.mjs +56 -0
  47. package/lib/bs/src/Plugin-CatalogPlugin.cmi +0 -0
  48. package/lib/bs/src/Plugin-CatalogPlugin.cmj +0 -0
  49. package/lib/bs/src/Plugin-CatalogPlugin.cmt +0 -0
  50. package/lib/bs/src/Plugin.ast +0 -0
  51. package/lib/bs/src/Plugin.res +65 -0
  52. package/lib/bs/src/Plugin.res.mjs +222 -0
  53. package/lib/bs/src/Product/Aggregate/Product-CatalogPlugin.cmi +0 -0
  54. package/lib/bs/src/Product/Aggregate/Product-CatalogPlugin.cmj +0 -0
  55. package/lib/bs/src/Product/Aggregate/Product-CatalogPlugin.cmt +0 -0
  56. package/lib/bs/src/Product/Aggregate/Product.ast +0 -0
  57. package/lib/bs/src/Product/Aggregate/Product.res +23 -0
  58. package/lib/bs/src/Product/Aggregate/Product.res.mjs +71 -0
  59. package/lib/bs/src/Product/Aggregate/Product_Behavior-CatalogPlugin.cmi +0 -0
  60. package/lib/bs/src/Product/Aggregate/Product_Behavior-CatalogPlugin.cmj +0 -0
  61. package/lib/bs/src/Product/Aggregate/Product_Behavior-CatalogPlugin.cmt +0 -0
  62. package/lib/bs/src/Product/Aggregate/Product_Behavior.ast +0 -0
  63. package/lib/bs/src/Product/Aggregate/Product_Behavior.res +38 -0
  64. package/lib/bs/src/Product/Aggregate/Product_Behavior.res.mjs +150 -0
  65. package/lib/bs/src/Product/ReadModel/Products-CatalogPlugin.cmi +0 -0
  66. package/lib/bs/src/Product/ReadModel/Products-CatalogPlugin.cmj +0 -0
  67. package/lib/bs/src/Product/ReadModel/Products-CatalogPlugin.cmt +0 -0
  68. package/lib/bs/src/Product/ReadModel/Products.ast +0 -0
  69. package/lib/bs/src/Product/ReadModel/Products.res +12 -0
  70. package/lib/bs/src/Product/ReadModel/Products.res.mjs +36 -0
  71. package/lib/bs/src/Product/ReadModel/Products_Projections-CatalogPlugin.cmi +0 -0
  72. package/lib/bs/src/Product/ReadModel/Products_Projections-CatalogPlugin.cmj +0 -0
  73. package/lib/bs/src/Product/ReadModel/Products_Projections-CatalogPlugin.cmt +0 -0
  74. package/lib/bs/src/Product/ReadModel/Products_Projections.ast +0 -0
  75. package/lib/bs/src/Product/ReadModel/Products_Projections.res +22 -0
  76. package/lib/bs/src/Product/ReadModel/Products_Projections.res.mjs +91 -0
  77. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand-CatalogPlugin.cmi +0 -0
  78. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand-CatalogPlugin.cmj +0 -0
  79. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand-CatalogPlugin.cmt +0 -0
  80. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand.ast +0 -0
  81. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand.res +20 -0
  82. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand.res.mjs +51 -0
  83. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior-CatalogPlugin.cmi +0 -0
  84. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior-CatalogPlugin.cmj +0 -0
  85. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior-CatalogPlugin.cmt +0 -0
  86. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior.ast +0 -0
  87. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior.res +39 -0
  88. package/lib/bs/src/ProductDemand/Aggregate/ProductDemand_Behavior.res.mjs +102 -0
  89. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands-CatalogPlugin.cmi +0 -0
  90. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands-CatalogPlugin.cmj +0 -0
  91. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands-CatalogPlugin.cmt +0 -0
  92. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands.ast +0 -0
  93. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands.res +8 -0
  94. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands.res.mjs +35 -0
  95. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections-CatalogPlugin.cmi +0 -0
  96. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections-CatalogPlugin.cmj +0 -0
  97. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections-CatalogPlugin.cmt +0 -0
  98. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections.ast +0 -0
  99. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections.res +36 -0
  100. package/lib/bs/src/ProductDemand/ReadModel/ProductDemands_Projections.res.mjs +99 -0
  101. package/lib/bs/src/Task/ImportProducts-CatalogPlugin.cmi +0 -0
  102. package/lib/bs/src/Task/ImportProducts-CatalogPlugin.cmj +0 -0
  103. package/lib/bs/src/Task/ImportProducts-CatalogPlugin.cmt +0 -0
  104. package/lib/bs/src/Task/ImportProducts.ast +0 -0
  105. package/lib/bs/src/Task/ImportProducts.res +48 -0
  106. package/lib/bs/src/Task/ImportProducts.res.mjs +58 -0
  107. package/lib/bs/tests/Category/Aggregate/Category_GWT-CatalogPlugin.cmi +0 -0
  108. package/lib/bs/tests/Category/Aggregate/Category_GWT-CatalogPlugin.cmj +0 -0
  109. package/lib/bs/tests/Category/Aggregate/Category_GWT-CatalogPlugin.cmt +0 -0
  110. package/lib/bs/tests/Category/Aggregate/Category_GWT.ast +0 -0
  111. package/lib/bs/tests/Category/Aggregate/Category_GWT.res +51 -0
  112. package/lib/bs/tests/Category/Aggregate/Category_GWT.res.mjs +125 -0
  113. package/lib/bs/tests/Category/ReadModel/Categories_GWT-CatalogPlugin.cmi +0 -0
  114. package/lib/bs/tests/Category/ReadModel/Categories_GWT-CatalogPlugin.cmj +0 -0
  115. package/lib/bs/tests/Category/ReadModel/Categories_GWT-CatalogPlugin.cmt +0 -0
  116. package/lib/bs/tests/Category/ReadModel/Categories_GWT.ast +0 -0
  117. package/lib/bs/tests/Category/ReadModel/Categories_GWT.res +21 -0
  118. package/lib/bs/tests/Category/ReadModel/Categories_GWT.res.mjs +88 -0
  119. package/lib/bs/tests/Extension/Orders_Extension_GWT-CatalogPlugin.cmi +0 -0
  120. package/lib/bs/tests/Extension/Orders_Extension_GWT-CatalogPlugin.cmj +0 -0
  121. package/lib/bs/tests/Extension/Orders_Extension_GWT-CatalogPlugin.cmt +0 -0
  122. package/lib/bs/tests/Extension/Orders_Extension_GWT.ast +0 -0
  123. package/lib/bs/tests/Extension/Orders_Extension_GWT.res +21 -0
  124. package/lib/bs/tests/Extension/Orders_Extension_GWT.res.mjs +105 -0
  125. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmi +0 -0
  126. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmj +0 -0
  127. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmt +0 -0
  128. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT.ast +0 -0
  129. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT.res +31 -0
  130. package/lib/bs/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT.res.mjs +114 -0
  131. package/lib/bs/tests/Product/Aggregate/Product_GWT-CatalogPlugin.cmi +0 -0
  132. package/lib/bs/tests/Product/Aggregate/Product_GWT-CatalogPlugin.cmj +0 -0
  133. package/lib/bs/tests/Product/Aggregate/Product_GWT-CatalogPlugin.cmt +0 -0
  134. package/lib/bs/tests/Product/Aggregate/Product_GWT.ast +0 -0
  135. package/lib/bs/tests/Product/Aggregate/Product_GWT.res +69 -0
  136. package/lib/bs/tests/Product/Aggregate/Product_GWT.res.mjs +166 -0
  137. package/lib/bs/tests/Product/ReadModel/Products_GWT-CatalogPlugin.cmi +0 -0
  138. package/lib/bs/tests/Product/ReadModel/Products_GWT-CatalogPlugin.cmj +0 -0
  139. package/lib/bs/tests/Product/ReadModel/Products_GWT-CatalogPlugin.cmt +0 -0
  140. package/lib/bs/tests/Product/ReadModel/Products_GWT.ast +0 -0
  141. package/lib/bs/tests/Product/ReadModel/Products_GWT.res +27 -0
  142. package/lib/bs/tests/Product/ReadModel/Products_GWT.res.mjs +113 -0
  143. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT-CatalogPlugin.cmi +0 -0
  144. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT-CatalogPlugin.cmj +0 -0
  145. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT-CatalogPlugin.cmt +0 -0
  146. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT.ast +0 -0
  147. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT.res +39 -0
  148. package/lib/bs/tests/ProductDemand/Aggregate/ProductDemand_GWT.res.mjs +114 -0
  149. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT-CatalogPlugin.cmi +0 -0
  150. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT-CatalogPlugin.cmj +0 -0
  151. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT-CatalogPlugin.cmt +0 -0
  152. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT.ast +0 -0
  153. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT.res +56 -0
  154. package/lib/bs/tests/ProductDemand/ReadModel/ProductDemands_GWT.res.mjs +73 -0
  155. package/lib/ocaml/.compiler.log +2 -0
  156. package/lib/ocaml/CatalogPlugin.cmi +0 -0
  157. package/lib/ocaml/CatalogPlugin.cmj +0 -0
  158. package/lib/ocaml/CatalogPlugin.cmt +0 -0
  159. package/lib/ocaml/CatalogPlugin.mlmap +25 -0
  160. package/lib/ocaml/Categories-CatalogPlugin.cmi +0 -0
  161. package/lib/ocaml/Categories-CatalogPlugin.cmj +0 -0
  162. package/lib/ocaml/Categories-CatalogPlugin.cmt +0 -0
  163. package/lib/ocaml/Categories.ast +0 -0
  164. package/lib/ocaml/Categories.res +11 -0
  165. package/lib/ocaml/Categories_GWT-CatalogPlugin.cmi +0 -0
  166. package/lib/ocaml/Categories_GWT-CatalogPlugin.cmj +0 -0
  167. package/lib/ocaml/Categories_GWT-CatalogPlugin.cmt +0 -0
  168. package/lib/ocaml/Categories_GWT.ast +0 -0
  169. package/lib/ocaml/Categories_GWT.res +21 -0
  170. package/lib/ocaml/Categories_Projections-CatalogPlugin.cmi +0 -0
  171. package/lib/ocaml/Categories_Projections-CatalogPlugin.cmj +0 -0
  172. package/lib/ocaml/Categories_Projections-CatalogPlugin.cmt +0 -0
  173. package/lib/ocaml/Categories_Projections.ast +0 -0
  174. package/lib/ocaml/Categories_Projections.res +19 -0
  175. package/lib/ocaml/Category-CatalogPlugin.cmi +0 -0
  176. package/lib/ocaml/Category-CatalogPlugin.cmj +0 -0
  177. package/lib/ocaml/Category-CatalogPlugin.cmt +0 -0
  178. package/lib/ocaml/Category.ast +0 -0
  179. package/lib/ocaml/Category.res +22 -0
  180. package/lib/ocaml/Category_Behavior-CatalogPlugin.cmi +0 -0
  181. package/lib/ocaml/Category_Behavior-CatalogPlugin.cmj +0 -0
  182. package/lib/ocaml/Category_Behavior-CatalogPlugin.cmt +0 -0
  183. package/lib/ocaml/Category_Behavior.ast +0 -0
  184. package/lib/ocaml/Category_Behavior.res +36 -0
  185. package/lib/ocaml/Category_GWT-CatalogPlugin.cmi +0 -0
  186. package/lib/ocaml/Category_GWT-CatalogPlugin.cmj +0 -0
  187. package/lib/ocaml/Category_GWT-CatalogPlugin.cmt +0 -0
  188. package/lib/ocaml/Category_GWT.ast +0 -0
  189. package/lib/ocaml/Category_GWT.res +51 -0
  190. package/lib/ocaml/ImportProducts-CatalogPlugin.cmi +0 -0
  191. package/lib/ocaml/ImportProducts-CatalogPlugin.cmj +0 -0
  192. package/lib/ocaml/ImportProducts-CatalogPlugin.cmt +0 -0
  193. package/lib/ocaml/ImportProducts.ast +0 -0
  194. package/lib/ocaml/ImportProducts.res +48 -0
  195. package/lib/ocaml/Orders_Extension-CatalogPlugin.cmi +0 -0
  196. package/lib/ocaml/Orders_Extension-CatalogPlugin.cmj +0 -0
  197. package/lib/ocaml/Orders_Extension-CatalogPlugin.cmt +0 -0
  198. package/lib/ocaml/Orders_Extension.ast +0 -0
  199. package/lib/ocaml/Orders_Extension.res +23 -0
  200. package/lib/ocaml/Orders_Extension_GWT-CatalogPlugin.cmi +0 -0
  201. package/lib/ocaml/Orders_Extension_GWT-CatalogPlugin.cmj +0 -0
  202. package/lib/ocaml/Orders_Extension_GWT-CatalogPlugin.cmt +0 -0
  203. package/lib/ocaml/Orders_Extension_GWT.ast +0 -0
  204. package/lib/ocaml/Orders_Extension_GWT.res +21 -0
  205. package/lib/ocaml/Plugin-CatalogPlugin.cmi +0 -0
  206. package/lib/ocaml/Plugin-CatalogPlugin.cmj +0 -0
  207. package/lib/ocaml/Plugin-CatalogPlugin.cmt +0 -0
  208. package/lib/ocaml/Plugin.ast +0 -0
  209. package/lib/ocaml/Plugin.res +65 -0
  210. package/lib/ocaml/Product-CatalogPlugin.cmi +0 -0
  211. package/lib/ocaml/Product-CatalogPlugin.cmj +0 -0
  212. package/lib/ocaml/Product-CatalogPlugin.cmt +0 -0
  213. package/lib/ocaml/Product.ast +0 -0
  214. package/lib/ocaml/Product.res +23 -0
  215. package/lib/ocaml/ProductDemand-CatalogPlugin.cmi +0 -0
  216. package/lib/ocaml/ProductDemand-CatalogPlugin.cmj +0 -0
  217. package/lib/ocaml/ProductDemand-CatalogPlugin.cmt +0 -0
  218. package/lib/ocaml/ProductDemand.ast +0 -0
  219. package/lib/ocaml/ProductDemand.res +20 -0
  220. package/lib/ocaml/ProductDemand_Behavior-CatalogPlugin.cmi +0 -0
  221. package/lib/ocaml/ProductDemand_Behavior-CatalogPlugin.cmj +0 -0
  222. package/lib/ocaml/ProductDemand_Behavior-CatalogPlugin.cmt +0 -0
  223. package/lib/ocaml/ProductDemand_Behavior.ast +0 -0
  224. package/lib/ocaml/ProductDemand_Behavior.res +39 -0
  225. package/lib/ocaml/ProductDemand_GWT-CatalogPlugin.cmi +0 -0
  226. package/lib/ocaml/ProductDemand_GWT-CatalogPlugin.cmj +0 -0
  227. package/lib/ocaml/ProductDemand_GWT-CatalogPlugin.cmt +0 -0
  228. package/lib/ocaml/ProductDemand_GWT.ast +0 -0
  229. package/lib/ocaml/ProductDemand_GWT.res +39 -0
  230. package/lib/ocaml/ProductDemands-CatalogPlugin.cmi +0 -0
  231. package/lib/ocaml/ProductDemands-CatalogPlugin.cmj +0 -0
  232. package/lib/ocaml/ProductDemands-CatalogPlugin.cmt +0 -0
  233. package/lib/ocaml/ProductDemands.ast +0 -0
  234. package/lib/ocaml/ProductDemands.res +8 -0
  235. package/lib/ocaml/ProductDemands_GWT-CatalogPlugin.cmi +0 -0
  236. package/lib/ocaml/ProductDemands_GWT-CatalogPlugin.cmj +0 -0
  237. package/lib/ocaml/ProductDemands_GWT-CatalogPlugin.cmt +0 -0
  238. package/lib/ocaml/ProductDemands_GWT.ast +0 -0
  239. package/lib/ocaml/ProductDemands_GWT.res +56 -0
  240. package/lib/ocaml/ProductDemands_Projections-CatalogPlugin.cmi +0 -0
  241. package/lib/ocaml/ProductDemands_Projections-CatalogPlugin.cmj +0 -0
  242. package/lib/ocaml/ProductDemands_Projections-CatalogPlugin.cmt +0 -0
  243. package/lib/ocaml/ProductDemands_Projections.ast +0 -0
  244. package/lib/ocaml/ProductDemands_Projections.res +36 -0
  245. package/lib/ocaml/Product_Behavior-CatalogPlugin.cmi +0 -0
  246. package/lib/ocaml/Product_Behavior-CatalogPlugin.cmj +0 -0
  247. package/lib/ocaml/Product_Behavior-CatalogPlugin.cmt +0 -0
  248. package/lib/ocaml/Product_Behavior.ast +0 -0
  249. package/lib/ocaml/Product_Behavior.res +38 -0
  250. package/lib/ocaml/Product_GWT-CatalogPlugin.cmi +0 -0
  251. package/lib/ocaml/Product_GWT-CatalogPlugin.cmj +0 -0
  252. package/lib/ocaml/Product_GWT-CatalogPlugin.cmt +0 -0
  253. package/lib/ocaml/Product_GWT.ast +0 -0
  254. package/lib/ocaml/Product_GWT.res +69 -0
  255. package/lib/ocaml/Products-CatalogPlugin.cmi +0 -0
  256. package/lib/ocaml/Products-CatalogPlugin.cmj +0 -0
  257. package/lib/ocaml/Products-CatalogPlugin.cmt +0 -0
  258. package/lib/ocaml/Products.ast +0 -0
  259. package/lib/ocaml/Products.res +12 -0
  260. package/lib/ocaml/Products_ExtensionPointMapping-CatalogPlugin.cmi +0 -0
  261. package/lib/ocaml/Products_ExtensionPointMapping-CatalogPlugin.cmj +0 -0
  262. package/lib/ocaml/Products_ExtensionPointMapping-CatalogPlugin.cmt +0 -0
  263. package/lib/ocaml/Products_ExtensionPointMapping.ast +0 -0
  264. package/lib/ocaml/Products_ExtensionPointMapping.res +19 -0
  265. package/lib/ocaml/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmi +0 -0
  266. package/lib/ocaml/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmj +0 -0
  267. package/lib/ocaml/Products_ExtensionPointMapping_GWT-CatalogPlugin.cmt +0 -0
  268. package/lib/ocaml/Products_ExtensionPointMapping_GWT.ast +0 -0
  269. package/lib/ocaml/Products_ExtensionPointMapping_GWT.res +31 -0
  270. package/lib/ocaml/Products_GWT-CatalogPlugin.cmi +0 -0
  271. package/lib/ocaml/Products_GWT-CatalogPlugin.cmj +0 -0
  272. package/lib/ocaml/Products_GWT-CatalogPlugin.cmt +0 -0
  273. package/lib/ocaml/Products_GWT.ast +0 -0
  274. package/lib/ocaml/Products_GWT.res +27 -0
  275. package/lib/ocaml/Products_Projections-CatalogPlugin.cmi +0 -0
  276. package/lib/ocaml/Products_Projections-CatalogPlugin.cmj +0 -0
  277. package/lib/ocaml/Products_Projections-CatalogPlugin.cmt +0 -0
  278. package/lib/ocaml/Products_Projections.ast +0 -0
  279. package/lib/ocaml/Products_Projections.res +22 -0
  280. package/package.json +52 -0
  281. package/rescript.json +39 -0
  282. package/src/Category/Aggregate/Category.res +22 -0
  283. package/src/Category/Aggregate/Category.res.mjs +61 -0
  284. package/src/Category/Aggregate/Category_Behavior.res +36 -0
  285. package/src/Category/Aggregate/Category_Behavior.res.mjs +106 -0
  286. package/src/Category/ReadModel/Categories.res +11 -0
  287. package/src/Category/ReadModel/Categories.res.mjs +35 -0
  288. package/src/Category/ReadModel/Categories_Projections.res +19 -0
  289. package/src/Category/ReadModel/Categories_Projections.res.mjs +75 -0
  290. package/src/Extension/Orders_Extension.res +23 -0
  291. package/src/Extension/Orders_Extension.res.mjs +42 -0
  292. package/src/ExtensionPoint/Products_ExtensionPointMapping.res +19 -0
  293. package/src/ExtensionPoint/Products_ExtensionPointMapping.res.mjs +56 -0
  294. package/src/Plugin.res +65 -0
  295. package/src/Plugin.res.mjs +222 -0
  296. package/src/Product/Aggregate/Product.res +23 -0
  297. package/src/Product/Aggregate/Product.res.mjs +71 -0
  298. package/src/Product/Aggregate/Product_Behavior.res +38 -0
  299. package/src/Product/Aggregate/Product_Behavior.res.mjs +150 -0
  300. package/src/Product/ReadModel/Products.res +12 -0
  301. package/src/Product/ReadModel/Products.res.mjs +36 -0
  302. package/src/Product/ReadModel/Products_Projections.res +22 -0
  303. package/src/Product/ReadModel/Products_Projections.res.mjs +91 -0
  304. package/src/ProductDemand/Aggregate/ProductDemand.res +20 -0
  305. package/src/ProductDemand/Aggregate/ProductDemand.res.mjs +51 -0
  306. package/src/ProductDemand/Aggregate/ProductDemand_Behavior.res +39 -0
  307. package/src/ProductDemand/Aggregate/ProductDemand_Behavior.res.mjs +102 -0
  308. package/src/ProductDemand/ReadModel/ProductDemands.res +8 -0
  309. package/src/ProductDemand/ReadModel/ProductDemands.res.mjs +35 -0
  310. package/src/ProductDemand/ReadModel/ProductDemands_Projections.res +36 -0
  311. package/src/ProductDemand/ReadModel/ProductDemands_Projections.res.mjs +99 -0
  312. package/src/Task/ImportProducts.res +48 -0
  313. package/src/Task/ImportProducts.res.mjs +58 -0
  314. package/src/plugin.json +1 -0
  315. package/tests/Category/Aggregate/Category_GWT.res +51 -0
  316. package/tests/Category/Aggregate/Category_GWT.res.mjs +125 -0
  317. package/tests/Category/ReadModel/Categories_GWT.res +21 -0
  318. package/tests/Category/ReadModel/Categories_GWT.res.mjs +88 -0
  319. package/tests/Extension/Orders_Extension_GWT.res +21 -0
  320. package/tests/Extension/Orders_Extension_GWT.res.mjs +105 -0
  321. package/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT.res +31 -0
  322. package/tests/ExtensionPoint/Products_ExtensionPointMapping_GWT.res.mjs +114 -0
  323. package/tests/Product/Aggregate/Product_GWT.res +69 -0
  324. package/tests/Product/Aggregate/Product_GWT.res.mjs +166 -0
  325. package/tests/Product/ReadModel/Products_GWT.res +27 -0
  326. package/tests/Product/ReadModel/Products_GWT.res.mjs +113 -0
  327. package/tests/ProductDemand/Aggregate/ProductDemand_GWT.res +39 -0
  328. package/tests/ProductDemand/Aggregate/ProductDemand_GWT.res.mjs +114 -0
  329. package/tests/ProductDemand/ReadModel/ProductDemands_GWT.res +56 -0
  330. package/tests/ProductDemand/ReadModel/ProductDemands_GWT.res.mjs +73 -0
@@ -0,0 +1,65 @@
1
+ // AUTO-GENERATED — do not edit. Run `npm run generate` to update.
2
+
3
+ @val external uiBundleUrl: option<string> = "process.env.CATALOG_UI_BUNDLE_URL"
4
+
5
+ module Make = (Platform: ReventlessInfra.Platform.T) => {
6
+ // Aggregates
7
+ module CategoryAggregate = Platform.Aggregate.Make(
8
+ Category,
9
+ Category_Behavior,
10
+ ReventlessInfra.NoEventMappings.Make(Category),
11
+ )
12
+ module ProductAggregate = Platform.Aggregate.Make(
13
+ Product,
14
+ Product_Behavior,
15
+ ReventlessInfra.NoEventMappings.Make(Product),
16
+ )
17
+ module ProductDemandAggregate = Platform.Aggregate.Make(
18
+ ProductDemand,
19
+ ProductDemand_Behavior,
20
+ ReventlessInfra.NoEventMappings.Make(ProductDemand),
21
+ )
22
+
23
+ // ReadModels
24
+ module CategoriesReadModel = Platform.ReadModel.Make(Categories, Categories_Projections)
25
+ module ProductDemandsReadModel = Platform.ReadModel.Make(ProductDemands, ProductDemands_Projections)
26
+ module ProductsReadModel = Platform.ReadModel.Make(Products, Products_Projections)
27
+
28
+ // Tasks
29
+ module ImportProductsTask = Platform.Task.Make(ImportProducts)
30
+
31
+ // ExtensionPoints
32
+ module Products_ExtensionPoint = Platform.ExtensionPoint.Make(Products_ExtensionPointMapping)
33
+
34
+ // Extensions
35
+ module Orders_Extension = Platform.Extension.Make(Orders_Extension.Mapping)
36
+
37
+ let pluginStructure = Platform.Plugin.makePluginDefinition(
38
+ ~name="Catalog",
39
+ ~aggregates=[module(CategoryAggregate), module(ProductAggregate), module(ProductDemandAggregate)],
40
+ ~readModels=[module(CategoriesReadModel), module(ProductDemandsReadModel), module(ProductsReadModel)],
41
+ ~extensions=[module(Orders_Extension)],
42
+ ~extensionPoints=[module(Products_ExtensionPointMapping)],
43
+ )
44
+
45
+ let make = () =>
46
+ Platform.Plugin.make(
47
+ ~name="Catalog",
48
+ ~heartbeatInterval=5,
49
+ ~extensionPoints=[module(Products_ExtensionPoint)],
50
+ ~extensions=[module(Orders_Extension)],
51
+ ~aggregates=[module(CategoryAggregate), module(ProductAggregate), module(ProductDemandAggregate)],
52
+ ~readModels=[module(CategoriesReadModel), module(ProductDemandsReadModel), module(ProductsReadModel)],
53
+ ~tasks=[module(ImportProductsTask)],
54
+ ~pluginStructure=pluginStructure,
55
+ ~uiFragments=?uiBundleUrl->Option.map(url =>
56
+ Platform.Plugin.makeAutoUIManifest(
57
+ ~remoteEntryUrl=url,
58
+ ~name="Catalog",
59
+ ~pluginStructure,
60
+ ~readModelPositions=["platform-summary"],
61
+ ~aggregatePositions=["resource-detail"],
62
+ )
63
+ ),
64
+ )
65
+ }
Binary file
@@ -0,0 +1,23 @@
1
+ // Product aggregate specification.
2
+ // A product listing with name, description, and price.
3
+
4
+ @@reventless.spec
5
+
6
+ @schema
7
+ type command =
8
+ | Add({name: string, description: string, price: float})
9
+ | UpdateName({name: string})
10
+ | UpdateDescription({description: string})
11
+ | UpdatePrice({price: float})
12
+
13
+ @schema
14
+ type event =
15
+ | Added({name: string, description: string, price: float})
16
+ | NameUpdated({name: string})
17
+ | DescriptionUpdated({description: string})
18
+ | PriceUpdated({price: float})
19
+
20
+ @schema
21
+ type error =
22
+ | ProductAlreadyExists
23
+ | ProductNotFound
Binary file
@@ -0,0 +1,20 @@
1
+ // ProductDemand aggregate specification.
2
+ // Records per-product order demand, driven by Ordering's OrdersExtensionPoint.
3
+
4
+ @@reventless.spec
5
+
6
+ // Not a UI/API command — driven only by Ordering's OrdersExtensionPoint.
7
+ // @noApi removes it from the GraphQL/MCP/AutoUI surface, so the cross-plugin
8
+ // `orderId` is never rendered as a picker and needs no @ref.
9
+ @schema @noApi
10
+ type command =
11
+ | Record({orderId: string})
12
+ | Revoke({orderId: string})
13
+
14
+ @schema
15
+ type event =
16
+ | Recorded({orderId: string})
17
+ | Revoked({orderId: string})
18
+
19
+ @schema
20
+ type error = unit
@@ -0,0 +1,39 @@
1
+ // ProductDemand aggregate behavior.
2
+ // Idempotently records and revokes order demand per product.
3
+
4
+ @@reventless.behavior
5
+
6
+ @schema
7
+ type state =
8
+ | NotCreated
9
+ | Created({recordedOrderIds: array<string>})
10
+
11
+ let initialState = NotCreated
12
+
13
+ let evolve = (state, event) =>
14
+ switch (state, event) {
15
+ | (NotCreated, Recorded({orderId})) => Created({recordedOrderIds: [orderId]})
16
+ | (Created(s), Recorded({orderId})) =>
17
+ Created({recordedOrderIds: Array.concat(s.recordedOrderIds, [orderId])})
18
+ | (Created(s), Revoked({orderId})) =>
19
+ Created({recordedOrderIds: s.recordedOrderIds->Array.filter(id => id !== orderId)})
20
+ | (NotCreated, Revoked(_)) => state
21
+ }
22
+
23
+ let decide = (state, command) =>
24
+ switch (state, command) {
25
+ | (NotCreated, Record({orderId})) => Ok([Recorded({orderId: orderId})])
26
+ | (NotCreated, Revoke(_)) => Ok([]) // nothing recorded yet — idempotent
27
+ | (Created(s), Record({orderId})) =>
28
+ if s.recordedOrderIds->Array.includes(orderId) {
29
+ Ok([]) // idempotent
30
+ } else {
31
+ Ok([Recorded({orderId: orderId})])
32
+ }
33
+ | (Created(s), Revoke({orderId})) =>
34
+ if !(s.recordedOrderIds->Array.includes(orderId)) {
35
+ Ok([]) // idempotent
36
+ } else {
37
+ Ok([Revoked({orderId: orderId})])
38
+ }
39
+ }
Binary file
@@ -0,0 +1,39 @@
1
+ @@reventless.gwt
2
+
3
+ describe("ProductDemand Behavior", () => {
4
+ test("Record on new aggregate produces Recorded", () =>
5
+ givenEvents([])
6
+ ->whenCmd(Record({orderId: "order-1"}))
7
+ ->thenEvent(Recorded({orderId: "order-1"}))
8
+ )
9
+
10
+ test("Record with new orderId on existing aggregate produces Recorded", () =>
11
+ givenEvents([Recorded({orderId: "order-1"})])
12
+ ->whenCmd(Record({orderId: "order-2"}))
13
+ ->thenEvent(Recorded({orderId: "order-2"}))
14
+ )
15
+
16
+ test("Record with already-recorded orderId produces no events (idempotent)", () =>
17
+ givenEvents([Recorded({orderId: "order-1"})])
18
+ ->whenCmd(Record({orderId: "order-1"}))
19
+ ->thenNoEvent
20
+ )
21
+
22
+ test("Revoke on never-recorded aggregate produces no events (idempotent)", () =>
23
+ givenEvents([])
24
+ ->whenCmd(Revoke({orderId: "order-1"}))
25
+ ->thenNoEvent
26
+ )
27
+
28
+ test("Revoke of unrecorded orderId on existing aggregate produces no events (idempotent)", () =>
29
+ givenEvents([Recorded({orderId: "order-1"})])
30
+ ->whenCmd(Revoke({orderId: "order-2"}))
31
+ ->thenNoEvent
32
+ )
33
+
34
+ test("Revoke of recorded orderId produces Revoked", () =>
35
+ givenEvents([Recorded({orderId: "order-1"})])
36
+ ->whenCmd(Revoke({orderId: "order-1"}))
37
+ ->thenEvent(Revoked({orderId: "order-1"}))
38
+ )
39
+ })
Binary file
@@ -0,0 +1,8 @@
1
+ // ProductDemand read model specification.
2
+ // Tracks per-product order demand counts, combining data from Product and ProductDemand aggregates.
3
+
4
+ @@reventless.spec
5
+
6
+ @schema
7
+ type state = {name: string, orderCount: int}
8
+
Binary file
@@ -0,0 +1,56 @@
1
+ // Multi-source ReadModel: separate `_GWT` instances per source mapping.
2
+ // `MultiSourceProjection_GWT.Make` is single-source; spec-stem uniqueness keeps
3
+ // the file name singular while we instantiate one functor per mapping.
4
+
5
+ module ProductGwt = ReventlessGwt.MultiSourceProjection_GWT.Make(
6
+ ProductDemands_Projections.ProductMapping,
7
+ )
8
+ module ProductDemandGwt = ReventlessGwt.MultiSourceProjection_GWT.Make(
9
+ ProductDemands_Projections.ProductDemandMapping,
10
+ )
11
+
12
+ ProductGwt.describe("ProductDemands ReadModel ← Product", () => {
13
+ ProductGwt.test("Added initialises the entry with orderCount = 0", () =>
14
+ ProductGwt.givenEvents([])
15
+ ->ProductGwt.whenEvent(Product.Added({name: "Laptop", description: "x", price: 1.0}))
16
+ ->ProductGwt.thenState({ProductDemands.name: "Laptop", orderCount: 0})
17
+ )
18
+
19
+ ProductGwt.test("NameUpdated is ignored (handled by Products read model)", () =>
20
+ ProductGwt.givenEvents([Product.Added({name: "Laptop", description: "x", price: 1.0})])
21
+ ->ProductGwt.whenEvent(Product.NameUpdated({name: "Gaming Laptop"}))
22
+ ->ProductGwt.thenState({ProductDemands.name: "Laptop", orderCount: 0})
23
+ )
24
+
25
+ ProductGwt.test("DescriptionUpdated is ignored", () =>
26
+ ProductGwt.givenEvents([Product.Added({name: "Laptop", description: "x", price: 1.0})])
27
+ ->ProductGwt.whenEvent(Product.DescriptionUpdated({description: "y"}))
28
+ ->ProductGwt.thenState({ProductDemands.name: "Laptop", orderCount: 0})
29
+ )
30
+
31
+ ProductGwt.test("PriceUpdated is ignored", () =>
32
+ ProductGwt.givenEvents([Product.Added({name: "Laptop", description: "x", price: 1.0})])
33
+ ->ProductGwt.whenEvent(Product.PriceUpdated({price: 2.0}))
34
+ ->ProductGwt.thenState({ProductDemands.name: "Laptop", orderCount: 0})
35
+ )
36
+ })
37
+
38
+ // `MultiSourceProjection_GWT` is single-source: the ProductDemand mapping
39
+ // emits `Update(...)` that needs initial state seeded by the Product
40
+ // mapping's `Set(...)`. Tested in isolation, both Update branches surface
41
+ // a `StaleState` error. We assert the throw to lock in that the mapping
42
+ // never tries to initialise its own row — the integration relies on
43
+ // Product.Added arriving first.
44
+ ProductDemandGwt.describe("ProductDemands ReadModel ← ProductDemand", () => {
45
+ ProductDemandGwt.test("Recorded without prior Product.Added throws StaleState", () =>
46
+ ProductDemandGwt.givenEvents([])
47
+ ->ProductDemandGwt.whenEvent(ProductDemand.Recorded({orderId: "order-1"}))
48
+ ->ProductDemandGwt.thenThrow
49
+ )
50
+
51
+ ProductDemandGwt.test("Revoked without prior Product.Added throws StaleState", () =>
52
+ ProductDemandGwt.givenEvents([])
53
+ ->ProductDemandGwt.whenEvent(ProductDemand.Revoked({orderId: "order-1"}))
54
+ ->ProductDemandGwt.thenThrow
55
+ )
56
+ })
@@ -0,0 +1,36 @@
1
+ // ProductDemands projection mappings.
2
+ // Multi-source read model: combines events from two aggregates.
3
+ // Source 1: Product — initialises the entry on Added.
4
+ // Source 2: ProductDemand — increments / decrements the order count.
5
+ @@reventless.mappings
6
+
7
+ module ProductMapping = Mapping.Make(
8
+ Product,
9
+ ProductDemands,
10
+ {
11
+ open Product
12
+ let project = ({event, id, _}) =>
13
+ switch event {
14
+ | Added({name}) =>
15
+ Set(id, {ProductDemands.name: name, orderCount: 0})
16
+ | _ => Ignore
17
+ }
18
+ },
19
+ )
20
+
21
+ module ProductDemandMapping = Mapping.Make(
22
+ ProductDemand,
23
+ ProductDemands,
24
+ {
25
+ open ProductDemand
26
+ let project = ({event, id, _}) =>
27
+ switch event {
28
+ | Recorded(_) =>
29
+ Update(id, (state: ProductDemands.state) => {...state, orderCount: state.orderCount + 1})
30
+ | Revoked(_) =>
31
+ Update(id, (state: ProductDemands.state) => {...state, orderCount: max(0, state.orderCount - 1)})
32
+ }
33
+ },
34
+ )
35
+
36
+ let mappings: array<module(Mapping)> = [module(ProductMapping), module(ProductDemandMapping)]
Binary file
@@ -0,0 +1,38 @@
1
+ // Product aggregate behavior.
2
+ // Implements the state machine for adding and updating products.
3
+
4
+ @@reventless.behavior
5
+
6
+ @schema
7
+ type state =
8
+ | NotCreated
9
+ | Created({name: string, description: string, price: float})
10
+
11
+ let initialState = NotCreated
12
+
13
+ let evolve = (state, event) =>
14
+ switch (state, event) {
15
+ | (NotCreated, Added({name, description, price})) => Created({name, description, price})
16
+ | (Created(_), Added({name, description, price})) => Created({name, description, price})
17
+ | (Created(s), NameUpdated({name})) => Created({...s, name})
18
+ | (Created(s), DescriptionUpdated({description})) => Created({...s, description})
19
+ | (Created(s), PriceUpdated({price})) => Created({...s, price})
20
+ | (NotCreated, _) => state
21
+ }
22
+
23
+ let decide = (state, command) =>
24
+ switch (state, command) {
25
+ | (NotCreated, Add({name, description, price})) =>
26
+ Ok([Added({name, description, price})])
27
+ | (NotCreated, UpdateName(_)) => Error(ProductNotFound)
28
+ | (NotCreated, UpdateDescription(_)) => Error(ProductNotFound)
29
+ | (NotCreated, UpdatePrice(_)) => Error(ProductNotFound)
30
+ | (Created(_), Add(_)) => Error(ProductAlreadyExists)
31
+ | (Created(s), UpdateName({name})) if name == s.name => Ok([])
32
+ | (Created(_), UpdateName({name})) => Ok([NameUpdated({name: name})])
33
+ | (Created(s), UpdateDescription({description})) if description == s.description => Ok([])
34
+ | (Created(_), UpdateDescription({description})) =>
35
+ Ok([DescriptionUpdated({description: description})])
36
+ | (Created(s), UpdatePrice({price})) if price == s.price => Ok([])
37
+ | (Created(_), UpdatePrice({price})) => Ok([PriceUpdated({price: price})])
38
+ }
Binary file
@@ -0,0 +1,69 @@
1
+ @@reventless.gwt
2
+
3
+ describe("Product Behavior", () => {
4
+ test("Add on new aggregate produces Added", () =>
5
+ givenEvents([])
6
+ ->whenCmd(Add({name: "Laptop", description: "A laptop", price: 999.99}))
7
+ ->thenEvent(Added({name: "Laptop", description: "A laptop", price: 999.99}))
8
+ )
9
+
10
+ test("Add on existing aggregate returns ProductAlreadyExists", () =>
11
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
12
+ ->whenCmd(Add({name: "Laptop 2", description: "Another", price: 1.0}))
13
+ ->thenError(ProductAlreadyExists)
14
+ )
15
+
16
+ test("UpdateName on non-existent aggregate returns ProductNotFound", () =>
17
+ givenEvents([])
18
+ ->whenCmd(UpdateName({name: "New Name"}))
19
+ ->thenError(ProductNotFound)
20
+ )
21
+
22
+ test("UpdateName on existing product produces NameUpdated", () =>
23
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
24
+ ->whenCmd(UpdateName({name: "Gaming Laptop"}))
25
+ ->thenEvent(NameUpdated({name: "Gaming Laptop"}))
26
+ )
27
+
28
+ test("UpdateName to same name produces no events (idempotent)", () =>
29
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
30
+ ->whenCmd(UpdateName({name: "Laptop"}))
31
+ ->thenNoEvent
32
+ )
33
+
34
+ test("UpdateDescription on non-existent aggregate returns ProductNotFound", () =>
35
+ givenEvents([])
36
+ ->whenCmd(UpdateDescription({description: "x"}))
37
+ ->thenError(ProductNotFound)
38
+ )
39
+
40
+ test("UpdateDescription on existing product produces DescriptionUpdated", () =>
41
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
42
+ ->whenCmd(UpdateDescription({description: "A high-end laptop"}))
43
+ ->thenEvent(DescriptionUpdated({description: "A high-end laptop"}))
44
+ )
45
+
46
+ test("UpdateDescription to same description produces no events (idempotent)", () =>
47
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
48
+ ->whenCmd(UpdateDescription({description: "A laptop"}))
49
+ ->thenNoEvent
50
+ )
51
+
52
+ test("UpdatePrice on non-existent aggregate returns ProductNotFound", () =>
53
+ givenEvents([])
54
+ ->whenCmd(UpdatePrice({price: 1.0}))
55
+ ->thenError(ProductNotFound)
56
+ )
57
+
58
+ test("UpdatePrice on existing product produces PriceUpdated", () =>
59
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
60
+ ->whenCmd(UpdatePrice({price: 899.99}))
61
+ ->thenEvent(PriceUpdated({price: 899.99}))
62
+ )
63
+
64
+ test("UpdatePrice to same price produces no events (idempotent)", () =>
65
+ givenEvents([Added({name: "Laptop", description: "A laptop", price: 999.99})])
66
+ ->whenCmd(UpdatePrice({price: 999.99}))
67
+ ->thenNoEvent
68
+ )
69
+ })
Binary file
@@ -0,0 +1,12 @@
1
+ // Products read model specification.
2
+ // Query-side state for product listings.
3
+
4
+ @@reventless.spec
5
+
6
+ @schema
7
+ type state = {
8
+ name: string,
9
+ description: string,
10
+ price: float,
11
+ }
12
+
@@ -0,0 +1,19 @@
1
+ // Maps internal Product aggregate events to the stable ProductsExtensionPoint public API.
2
+ @@reventless.spec
3
+
4
+ module ExtensionPoint = CatalogSpec.Products_ExtensionPoint
5
+ module Delegate = Product
6
+
7
+ let mapIncomingCommand = (_id, _command, _meta) => []
8
+
9
+ let mapOutgoingEvent = Some((id, event, _meta, _queryEngine) =>
10
+ switch event {
11
+ | Product.Added({name, price}) => [
12
+ PublishEvent(id, CatalogSpec.Products_ExtensionPoint.ProductBecameAvailable({productId: id, name, price})),
13
+ ]
14
+ | Product.PriceUpdated({price}) => [
15
+ PublishEvent(id, CatalogSpec.Products_ExtensionPoint.ProductPriceChanged({productId: id, price})),
16
+ ]
17
+ | _ => []
18
+ }
19
+ )
@@ -0,0 +1,31 @@
1
+ // Boundary GWT for the Products extension point: internal Product aggregate
2
+ // events become the stable public events Ordering subscribes to.
3
+ @@reventless.gwt
4
+
5
+ describe("Products ExtensionPoint mapping", () => {
6
+ test("Added publishes ProductBecameAvailable", () =>
7
+ whenDelegateEvent(
8
+ Delegate.Added({name: "Book", description: "A good book", price: 9.99}),
9
+ )->thenPublishesEvent(
10
+ "gwt-id",
11
+ ExtensionPoint.ProductBecameAvailable({productId: "gwt-id", name: "Book", price: 9.99}),
12
+ )
13
+ )
14
+
15
+ test("PriceUpdated publishes ProductPriceChanged", () =>
16
+ whenDelegateEvent(Delegate.PriceUpdated({price: 7.5}))->thenPublishesEvent(
17
+ "gwt-id",
18
+ ExtensionPoint.ProductPriceChanged({productId: "gwt-id", price: 7.5}),
19
+ )
20
+ )
21
+
22
+ test("NameUpdated publishes nothing", () =>
23
+ whenDelegateEvent(Delegate.NameUpdated({name: "Better Book"}))->thenPublishesNothing
24
+ )
25
+
26
+ test("DescriptionUpdated publishes nothing", () =>
27
+ whenDelegateEvent(
28
+ Delegate.DescriptionUpdated({description: "A really good book"}),
29
+ )->thenPublishesNothing
30
+ )
31
+ })
Binary file
@@ -0,0 +1,27 @@
1
+ @@reventless.gwt(Products_Projections.ProductMapping)
2
+
3
+ describe("Products ReadModel ← Product", () => {
4
+ test("Added sets initial read model state", () =>
5
+ givenEvents([])
6
+ ->whenEvent(Product.Added({name: "Laptop", description: "A laptop", price: 999.99}))
7
+ ->thenState({Products.name: "Laptop", description: "A laptop", price: 999.99})
8
+ )
9
+
10
+ test("NameUpdated updates the name", () =>
11
+ givenEvents([Product.Added({name: "Laptop", description: "A laptop", price: 999.99})])
12
+ ->whenEvent(Product.NameUpdated({name: "Gaming Laptop"}))
13
+ ->thenState({Products.name: "Gaming Laptop", description: "A laptop", price: 999.99})
14
+ )
15
+
16
+ test("DescriptionUpdated updates the description", () =>
17
+ givenEvents([Product.Added({name: "Laptop", description: "A laptop", price: 999.99})])
18
+ ->whenEvent(Product.DescriptionUpdated({description: "A high-end laptop"}))
19
+ ->thenState({Products.name: "Laptop", description: "A high-end laptop", price: 999.99})
20
+ )
21
+
22
+ test("PriceUpdated updates the price", () =>
23
+ givenEvents([Product.Added({name: "Laptop", description: "A laptop", price: 999.99})])
24
+ ->whenEvent(Product.PriceUpdated({price: 899.99}))
25
+ ->thenState({Products.name: "Laptop", description: "A laptop", price: 899.99})
26
+ )
27
+ })