@reventlessdev/reventless-core 3.0.0-alpha.262 → 3.0.0-alpha.264

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 (34) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/package.json +9 -9
  3. package/src/admin/Platform_Admin_Structure.res.mjs +1 -1
  4. package/src/components/Aggregate/Aggregate_Builder.res.mjs +1 -1
  5. package/src/components/CommandGenerator/CommandGenerator.res +4 -4
  6. package/src/components/CommandGenerator/CommandGenerator_Callback.res +13 -20
  7. package/src/components/CommandGenerator/CommandGenerator_Callback.res.mjs +3 -24
  8. package/src/components/Dcb/Dcb_Builder.res +45 -49
  9. package/src/components/Dcb/Dcb_Builder.res.mjs +31 -40
  10. package/src/components/StateChangeSlice/StateChangeSlice.res +2 -0
  11. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +6 -0
  12. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res.mjs +4 -4
  13. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +51 -22
  14. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +47 -25
  15. package/src/plugin/component/Plugin_Structure.res +101 -4
  16. package/src/plugin/component/Plugin_Structure.res.mjs +82 -9
  17. package/tests/adapter/RuntimeExtensionHookReachTest.res.mjs +1 -1
  18. package/tests/commandgenerator/CommandGeneratorCallbackTest.res +1 -1
  19. package/tests/commandgenerator/CommandGeneratorCallbackTest.res.mjs +1 -1
  20. package/tests/commandgenerator/CommandGeneratorFixtures.res +2 -0
  21. package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +17 -3
  22. package/tests/commandgenerator/OwnerStampingTest.res.mjs +2 -2
  23. package/tests/commandtopic/CommandOutcomeHookTest.res.mjs +1 -1
  24. package/tests/dcb/DcbFixtures.res +18 -1
  25. package/tests/dcb/DcbFixtures.res.mjs +14 -0
  26. package/tests/dcb/DcbScopeInferenceTest.res +234 -0
  27. package/tests/dcb/DcbScopeInferenceTest.res.mjs +425 -13
  28. package/tests/dcb/DcbStateChangeSliceTest.res.mjs +22 -22
  29. package/tests/dcb/DcbTagTest.res +81 -68
  30. package/tests/dcb/DcbTagTest.res.mjs +88 -89
  31. package/tests/plugin/PluginStructureAccessTest.res +1 -0
  32. package/tests/plugin/PluginStructureAccessTest.res.mjs +1 -1
  33. package/tests/plugin/PluginStructureTest.res +47 -0
  34. package/tests/plugin/PluginStructureTest.res.mjs +50 -10
@@ -32,6 +32,7 @@ module PsPlaceOrderSlice: ReventlessInfra.StateChangeSlice.T = {
32
32
  ~publishJsons as _,
33
33
  ~tagKeysByEventType as _=?,
34
34
  ~crossPartitionTagKeys as _=?,
35
+ ~partitionTag as _=?,
35
36
  ~runtime as _=?,
36
37
  ~opts as _=?,
37
38
  ): component => Obj.magic(0)
@@ -52,6 +53,7 @@ module PsShipOrderSlice: ReventlessInfra.StateChangeSlice.T = {
52
53
  ~publishJsons as _,
53
54
  ~tagKeysByEventType as _=?,
54
55
  ~crossPartitionTagKeys as _=?,
56
+ ~partitionTag as _=?,
55
57
  ~runtime as _=?,
56
58
  ~opts as _=?,
57
59
  ): component => Obj.magic(0)
@@ -118,6 +120,7 @@ module PsAttachInvoiceSlice: ReventlessInfra.StateChangeSlice.T = {
118
120
  ~publishJsons as _,
119
121
  ~tagKeysByEventType as _=?,
120
122
  ~crossPartitionTagKeys as _=?,
123
+ ~partitionTag as _=?,
121
124
  ~runtime as _=?,
122
125
  ~opts as _=?,
123
126
  ): component => Obj.magic(0)
@@ -139,6 +142,7 @@ module PsUploadAvatarSlice: ReventlessInfra.StateChangeSlice.T = {
139
142
  ~publishJsons as _,
140
143
  ~tagKeysByEventType as _=?,
141
144
  ~crossPartitionTagKeys as _=?,
145
+ ~partitionTag as _=?,
142
146
  ~runtime as _=?,
143
147
  ~opts as _=?,
144
148
  ): component => Obj.magic(0)
@@ -160,6 +164,7 @@ module PsUploadImagesSlice: ReventlessInfra.StateChangeSlice.T = {
160
164
  ~publishJsons as _,
161
165
  ~tagKeysByEventType as _=?,
162
166
  ~crossPartitionTagKeys as _=?,
167
+ ~partitionTag as _=?,
163
168
  ~runtime as _=?,
164
169
  ~opts as _=?,
165
170
  ): component => Obj.magic(0)
@@ -181,6 +186,7 @@ module PsTypoStoreSlice: ReventlessInfra.StateChangeSlice.T = {
181
186
  ~publishJsons as _,
182
187
  ~tagKeysByEventType as _=?,
183
188
  ~crossPartitionTagKeys as _=?,
189
+ ~partitionTag as _=?,
184
190
  ~runtime as _=?,
185
191
  ~opts as _=?,
186
192
  ): component => Obj.magic(0)
@@ -202,6 +208,7 @@ module PsChangePhotoSlice: ReventlessInfra.StateChangeSlice.T = {
202
208
  ~publishJsons as _,
203
209
  ~tagKeysByEventType as _=?,
204
210
  ~crossPartitionTagKeys as _=?,
211
+ ~partitionTag as _=?,
205
212
  ~runtime as _=?,
206
213
  ~opts as _=?,
207
214
  ): component => Obj.magic(0)
@@ -223,6 +230,7 @@ module PsReserveStockSlice: ReventlessInfra.StateChangeSlice.T = {
223
230
  ~publishJsons as _,
224
231
  ~tagKeysByEventType as _=?,
225
232
  ~crossPartitionTagKeys as _=?,
233
+ ~partitionTag as _=?,
226
234
  ~runtime as _=?,
227
235
  ~opts as _=?,
228
236
  ): component => Obj.magic(0)
@@ -244,6 +252,7 @@ module PsDispatchShipmentSlice: ReventlessInfra.StateChangeSlice.T = {
244
252
  ~publishJsons as _,
245
253
  ~tagKeysByEventType as _=?,
246
254
  ~crossPartitionTagKeys as _=?,
255
+ ~partitionTag as _=?,
247
256
  ~runtime as _=?,
248
257
  ~opts as _=?,
249
258
  ): component => Obj.magic(0)
@@ -264,6 +273,7 @@ module PsTransitionSwitchSlice: ReventlessInfra.StateChangeSlice.T = {
264
273
  ~publishJsons as _,
265
274
  ~tagKeysByEventType as _=?,
266
275
  ~crossPartitionTagKeys as _=?,
276
+ ~partitionTag as _=?,
267
277
  ~runtime as _=?,
268
278
  ~opts as _=?,
269
279
  ): component => Obj.magic(0)
@@ -2694,6 +2704,43 @@ describe("the subscriber's half of the table", () => {
2694
2704
  )
2695
2705
  })
2696
2706
 
2707
+ // An extension infers its target slice's partition from the slice alone. Where
2708
+ // the plugin needed the slice's reads or chapter, the two can part — caught here,
2709
+ // at assembly, rather than when the first event arrives.
2710
+ describe("an extension's partition against the plugin's", () => {
2711
+ let failure = (~expected, ~actual) =>
2712
+ Plugin_Structure.extensionPartitionFailure(
2713
+ ~label="Ordering.Orders → PlaceOrder",
2714
+ ~delegate="PlaceOrder",
2715
+ ~expected,
2716
+ ~actual,
2717
+ )
2718
+ let orderId = Reventless.DcbTag.Simple({key: "orderId"})
2719
+
2720
+ testSync("says nothing when both derive the same key", () =>
2721
+ expect(failure(~expected=Some(orderId), ~actual=Ok(orderId)))->toEqual(None)
2722
+ )
2723
+
2724
+ testSync("fails when the extension alone cannot tell, naming the key to annotate", () => {
2725
+ let message =
2726
+ failure(
2727
+ ~expected=Some(orderId),
2728
+ ~actual=Error("multiple candidate partition keys"),
2729
+ )->Option.getOr("")
2730
+ expect(message->String.includes("add @partitionTag orderId to PlaceOrder's event"))->toBe(true)
2731
+ })
2732
+
2733
+ testSync("fails when the extension derives a different key", () =>
2734
+ expect(
2735
+ failure(~expected=Some(orderId), ~actual=Ok(Simple({key: "customerId"})))->Option.isSome,
2736
+ )->toBe(true)
2737
+ )
2738
+
2739
+ testSync("leaves a plugin that cannot derive a partition to the builder", () =>
2740
+ expect(failure(~expected=None, ~actual=Error("no partition key")))->toEqual(None)
2741
+ )
2742
+ })
2743
+
2697
2744
  // ── One command name, one handler ────────────────────────────────────────────
2698
2745
  //
2699
2746
  // A DCB plugin routes a command by its bare type name, so two slices declaring
@@ -42,7 +42,7 @@ let Behavior = {
42
42
  moduleUrl: PsPlaceOrder$ReventlessCore.moduleUrl
43
43
  };
44
44
 
45
- function make(param, param$1, param$2, param$3, param$4, param$5) {
45
+ function make(param, param$1, param$2, param$3, param$4, param$5, param$6) {
46
46
  return 0;
47
47
  }
48
48
 
@@ -74,7 +74,7 @@ let Behavior$1 = {
74
74
  moduleUrl: PsShipOrder$ReventlessCore.moduleUrl
75
75
  };
76
76
 
77
- function make$1(param, param$1, param$2, param$3, param$4, param$5) {
77
+ function make$1(param, param$1, param$2, param$3, param$4, param$5, param$6) {
78
78
  return 0;
79
79
  }
80
80
 
@@ -236,7 +236,7 @@ let Behavior$2 = {
236
236
  moduleUrl: PsAttachInvoice$ReventlessCore.moduleUrl
237
237
  };
238
238
 
239
- function make$7(param, param$1, param$2, param$3, param$4, param$5) {
239
+ function make$7(param, param$1, param$2, param$3, param$4, param$5, param$6) {
240
240
  return 0;
241
241
  }
242
242
 
@@ -268,7 +268,7 @@ let Behavior$3 = {
268
268
  moduleUrl: PsUploadAvatar$ReventlessCore.moduleUrl
269
269
  };
270
270
 
271
- function make$8(param, param$1, param$2, param$3, param$4, param$5) {
271
+ function make$8(param, param$1, param$2, param$3, param$4, param$5, param$6) {
272
272
  return 0;
273
273
  }
274
274
 
@@ -300,7 +300,7 @@ let Behavior$4 = {
300
300
  moduleUrl: PsUploadImages$ReventlessCore.moduleUrl
301
301
  };
302
302
 
303
- function make$9(param, param$1, param$2, param$3, param$4, param$5) {
303
+ function make$9(param, param$1, param$2, param$3, param$4, param$5, param$6) {
304
304
  return 0;
305
305
  }
306
306
 
@@ -332,7 +332,7 @@ let Behavior$5 = {
332
332
  moduleUrl: PsTypoStore$ReventlessCore.moduleUrl
333
333
  };
334
334
 
335
- function make$10(param, param$1, param$2, param$3, param$4, param$5) {
335
+ function make$10(param, param$1, param$2, param$3, param$4, param$5, param$6) {
336
336
  return 0;
337
337
  }
338
338
 
@@ -364,7 +364,7 @@ let Behavior$6 = {
364
364
  moduleUrl: PsChangePhoto$ReventlessCore.moduleUrl
365
365
  };
366
366
 
367
- function make$11(param, param$1, param$2, param$3, param$4, param$5) {
367
+ function make$11(param, param$1, param$2, param$3, param$4, param$5, param$6) {
368
368
  return 0;
369
369
  }
370
370
 
@@ -396,7 +396,7 @@ let Behavior$7 = {
396
396
  moduleUrl: PsReserveStock$ReventlessCore.moduleUrl
397
397
  };
398
398
 
399
- function make$12(param, param$1, param$2, param$3, param$4, param$5) {
399
+ function make$12(param, param$1, param$2, param$3, param$4, param$5, param$6) {
400
400
  return 0;
401
401
  }
402
402
 
@@ -428,7 +428,7 @@ let Behavior$8 = {
428
428
  moduleUrl: PsDispatchShipment$ReventlessCore.moduleUrl
429
429
  };
430
430
 
431
- function make$13(param, param$1, param$2, param$3, param$4, param$5) {
431
+ function make$13(param, param$1, param$2, param$3, param$4, param$5, param$6) {
432
432
  return 0;
433
433
  }
434
434
 
@@ -460,7 +460,7 @@ let Behavior$9 = {
460
460
  moduleUrl: PsTransitionSwitch$ReventlessCore.moduleUrl
461
461
  };
462
462
 
463
- function make$14(param, param$1, param$2, param$3, param$4, param$5) {
463
+ function make$14(param, param$1, param$2, param$3, param$4, param$5, param$6) {
464
464
  return 0;
465
465
  }
466
466
 
@@ -2182,6 +2182,46 @@ globalThis.describe("the subscriber's half of the table", () => {
2182
2182
  });
2183
2183
  });
2184
2184
 
2185
+ globalThis.describe("an extension's partition against the plugin's", () => {
2186
+ let failure = (expected, actual) => Plugin_Structure$ReventlessCore.extensionPartitionFailure("Ordering.Orders → PlaceOrder", "PlaceOrder", expected, actual);
2187
+ let orderId = {
2188
+ TAG: "Simple",
2189
+ _0: {
2190
+ key: "orderId"
2191
+ }
2192
+ };
2193
+ globalThis.test("says nothing when both derive the same key", () => {
2194
+ globalThis.expect(failure(orderId, {
2195
+ TAG: "Ok",
2196
+ _0: orderId
2197
+ })).toEqual(undefined);
2198
+ });
2199
+ globalThis.test("fails when the extension alone cannot tell, naming the key to annotate", () => {
2200
+ let message = Stdlib_Option.getOr(failure(orderId, {
2201
+ TAG: "Error",
2202
+ _0: "multiple candidate partition keys"
2203
+ }), "");
2204
+ globalThis.expect(message.includes("add @partitionTag orderId to PlaceOrder's event")).toBe(true);
2205
+ });
2206
+ globalThis.test("fails when the extension derives a different key", () => {
2207
+ globalThis.expect(Stdlib_Option.isSome(failure(orderId, {
2208
+ TAG: "Ok",
2209
+ _0: {
2210
+ TAG: "Simple",
2211
+ _0: {
2212
+ key: "customerId"
2213
+ }
2214
+ }
2215
+ }))).toBe(true);
2216
+ });
2217
+ globalThis.test("leaves a plugin that cannot derive a partition to the builder", () => {
2218
+ globalThis.expect(failure(undefined, {
2219
+ TAG: "Error",
2220
+ _0: "no partition key"
2221
+ })).toEqual(undefined);
2222
+ });
2223
+ });
2224
+
2185
2225
  globalThis.describe("duplicate DCB command names", () => {
2186
2226
  globalThis.test("two slices declaring one command are refused", () => {
2187
2227
  let tmp;