@reventlessdev/reventless-gwt 1.0.0-alpha.242 → 1.0.0-alpha.244

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.
@@ -0,0 +1,113 @@
1
+ // A deadline tested at a fixed time: an order not shipped within three days of
2
+ // being placed is cancelled. `collect` counts the due time from the event's
3
+ // recorded time; `process` compares it with `~now`. `atTime` and `~recordedAt`
4
+ // say when the events happened, `~now` when the sweep runs.
5
+
6
+ module CancelUnshipped = {
7
+ let name = "CancelUnshipped"
8
+ let moduleUrl = ""
9
+
10
+ @schema
11
+ type todoItem = {orderId: string, dueAt: float}
12
+
13
+ @schema
14
+ type command = CancelOrder({orderId: string})
15
+
16
+ let maxRetries = 3
17
+ let heartbeatInterval = 60
18
+ let targetName = "Order"
19
+ let schedule = None
20
+ }
21
+
22
+ let day = 24. *. 60. *. 60. *. 1000.
23
+ let day0 = Date.fromString("2026-10-01T09:00:00Z")->Date.getTime
24
+
25
+ module CancelUnshipped_Automation = {
26
+ module M = Reventless.AutomationSlice.Mappings.Make(CancelUnshipped)
27
+ module type Mapping = M.Mapping
28
+ let moduleUrl = ""
29
+
30
+ module Orders = {
31
+ module Id = Reventless.Id.String
32
+ let name = "Orders"
33
+ @schema
34
+ type event =
35
+ | OrderPlaced({orderId: string})
36
+ | OrderShipped({orderId: string})
37
+ }
38
+
39
+ module FromOrders = Reventless.AutomationSlice.Mapping.Make(
40
+ Orders,
41
+ CancelUnshipped,
42
+ {
43
+ let collect = (event, ~sourceId as _, ctx: Reventless.AutomationSlice.context) =>
44
+ switch (event, ctx.recordedAt) {
45
+ | (Orders.OrderPlaced({orderId}), Some(placedAt)) => [
46
+ (orderId, ({orderId, dueAt: placedAt +. 3. *. day}: CancelUnshipped.todoItem)),
47
+ ]
48
+ | _ => []
49
+ }
50
+ let resolve = event =>
51
+ switch event {
52
+ | Orders.OrderShipped({orderId}) => Some(orderId)
53
+ | OrderPlaced(_) => None
54
+ }
55
+ let reschedule = _ => []
56
+ },
57
+ )
58
+
59
+ let mappings: array<module(Mapping)> = [module(FromOrders)]
60
+
61
+ let process = (id, item: CancelUnshipped.todoItem, ~now) =>
62
+ now >= item.dueAt ? Some((id, CancelUnshipped.CancelOrder({orderId: item.orderId}))) : None
63
+ let onExhausted = (_id, _item: CancelUnshipped.todoItem) => None
64
+ }
65
+
66
+ open CancelUnshipped
67
+ open CancelUnshipped_Automation
68
+ include Automation_GWT.FromSlice(CancelUnshipped, CancelUnshipped_Automation)
69
+ module O = Mapping(FromOrders)
70
+
71
+ describe("a deadline at a fixed time", () => {
72
+ test("collect counts the due time from the event's recorded time", () =>
73
+ O.givenEvent(OrderPlaced({orderId: "o1"}))
74
+ ->O.whenCollect(~recordedAt=day0)
75
+ ->thenTodos([("o1", {orderId: "o1", dueAt: day0 +. 3. *. day})])
76
+ )
77
+
78
+ test("not yet due on day 2: no command", () =>
79
+ givenEvents([O.event(OrderPlaced({orderId: "o1"}))])
80
+ ->atTime(day0)
81
+ ->whenSweep(~now=day0 +. 2. *. day)
82
+ ->thenCommands([])
83
+ )
84
+
85
+ test("due on day 3: CancelOrder", () =>
86
+ givenEvents([O.event(OrderPlaced({orderId: "o1"}))])
87
+ ->atTime(day0)
88
+ ->whenSweep(~now=day0 +. 3. *. day)
89
+ ->thenCommands([("o1", CancelOrder({orderId: "o1"}))])
90
+ )
91
+
92
+ test("shipped on day 2: nothing on day 3", () =>
93
+ givenEvents([
94
+ O.event(OrderPlaced({orderId: "o1"}), ~recordedAt=day0),
95
+ O.event(OrderShipped({orderId: "o1"}), ~recordedAt=day0 +. 2. *. day),
96
+ ])
97
+ ->whenSweep(~now=day0 +. 3. *. day)
98
+ ->thenCommands([])
99
+ )
100
+
101
+ test("a sweep given no time runs when the events happened", () =>
102
+ givenEvents([O.event(OrderPlaced({orderId: "o1"}))])
103
+ ->atTime(day0)
104
+ ->whenSweep
105
+ ->thenCommands([])
106
+ )
107
+
108
+ test("process is given the time a scenario fixes", () =>
109
+ givenTodo("o1", {orderId: "o1", dueAt: day0})
110
+ ->whenProcess(~now=day0)
111
+ ->thenCommand("o1", CancelOrder({orderId: "o1"}))
112
+ )
113
+ })
@@ -0,0 +1,291 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Sury from "sury";
4
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
5
+ import * as AutomationSlice$Reventless from "@reventlessdev/reventless-spec/src/components/AutomationSlice.res.mjs";
6
+ import * as Automation_GWT$ReventlessGwt from "../src/Automation_GWT.res.mjs";
7
+
8
+ let todoItemSchema = Sury.$schema(s => ({
9
+ orderId: s.m(Sury.string),
10
+ dueAt: s.m(Sury.number)
11
+ }));
12
+
13
+ let commandSchema = Sury.$schema(s => ({
14
+ TAG: "CancelOrder",
15
+ orderId: s.m(Sury.string)
16
+ }));
17
+
18
+ function authorizationOf(param) {
19
+ return "AllowAuthenticated";
20
+ }
21
+
22
+ function commandTransition(param) {
23
+ return "Undeclared";
24
+ }
25
+
26
+ let traits = [];
27
+
28
+ let CancelUnshipped = {
29
+ name: "CancelUnshipped",
30
+ moduleUrl: "",
31
+ todoItemSchema: todoItemSchema,
32
+ commandSchema: commandSchema,
33
+ maxRetries: 3,
34
+ heartbeatInterval: 60,
35
+ targetName: "Order",
36
+ schedule: undefined,
37
+ authorizationOf: authorizationOf,
38
+ commandTransition: commandTransition,
39
+ traits: traits
40
+ };
41
+
42
+ let day = 24 * 60 * 60 * 1000;
43
+
44
+ let day0 = new Date("2026-10-01T09:00:00Z").getTime();
45
+
46
+ let M = AutomationSlice$Reventless.Mappings.Make(CancelUnshipped);
47
+
48
+ let moduleUrl = "";
49
+
50
+ let name = "Orders";
51
+
52
+ let eventSchema = Sury.union([
53
+ Sury.$schema(s => ({
54
+ TAG: "OrderPlaced",
55
+ orderId: s.m(Sury.string)
56
+ })),
57
+ Sury.$schema(s => ({
58
+ TAG: "OrderShipped",
59
+ orderId: s.m(Sury.string)
60
+ }))
61
+ ]);
62
+
63
+ let Orders = {
64
+ Id: undefined,
65
+ name: name,
66
+ eventSchema: eventSchema
67
+ };
68
+
69
+ function collect(event, param, ctx) {
70
+ let match = ctx.recordedAt;
71
+ if (event.TAG !== "OrderPlaced") {
72
+ return [];
73
+ }
74
+ if (match === undefined) {
75
+ return [];
76
+ }
77
+ let orderId = event.orderId;
78
+ return [[
79
+ orderId,
80
+ {
81
+ orderId: orderId,
82
+ dueAt: match + 3 * day
83
+ }
84
+ ]];
85
+ }
86
+
87
+ function resolve(event) {
88
+ if (event.TAG === "OrderPlaced") {
89
+ return;
90
+ } else {
91
+ return event.orderId;
92
+ }
93
+ }
94
+
95
+ function reschedule(param) {
96
+ return [];
97
+ }
98
+
99
+ let FromOrders = AutomationSlice$Reventless.Mapping.Make({
100
+ Id: Id$Reventless.$$String,
101
+ name: name,
102
+ eventSchema: eventSchema
103
+ })(CancelUnshipped)({
104
+ collect: collect,
105
+ resolve: resolve,
106
+ reschedule: reschedule
107
+ });
108
+
109
+ let mappings = [FromOrders];
110
+
111
+ function process(id, item, now) {
112
+ if (now >= item.dueAt) {
113
+ return [
114
+ id,
115
+ {
116
+ TAG: "CancelOrder",
117
+ orderId: item.orderId
118
+ }
119
+ ];
120
+ }
121
+ }
122
+
123
+ function onExhausted(_id, _item) {
124
+
125
+ }
126
+
127
+ let CancelUnshipped_Automation = {
128
+ M: M,
129
+ moduleUrl: moduleUrl,
130
+ Orders: Orders,
131
+ FromOrders: FromOrders,
132
+ mappings: mappings,
133
+ process: process,
134
+ onExhausted: onExhausted
135
+ };
136
+
137
+ let include = Automation_GWT$ReventlessGwt.FromSlice(CancelUnshipped)({
138
+ process: process,
139
+ onExhausted: onExhausted,
140
+ moduleUrl: moduleUrl,
141
+ mappings: mappings
142
+ });
143
+
144
+ let describe = include.describe;
145
+
146
+ let test = include.test;
147
+
148
+ let thenTodos = include.thenTodos;
149
+
150
+ let Mapping = include.Mapping;
151
+
152
+ let givenTodo = include.givenTodo;
153
+
154
+ let whenProcess = include.whenProcess;
155
+
156
+ let thenCommand = include.thenCommand;
157
+
158
+ let givenEvents = include.givenEvents;
159
+
160
+ let atTime = include.atTime;
161
+
162
+ let whenSweep = include.whenSweep;
163
+
164
+ let thenCommands = include.thenCommands;
165
+
166
+ let O = Mapping(FromOrders);
167
+
168
+ describe("a deadline at a fixed time", () => {
169
+ test("collect counts the due time from the event's recorded time", () => thenTodos(O.whenCollect(O.givenEvent({
170
+ TAG: "OrderPlaced",
171
+ orderId: "o1"
172
+ }), undefined, undefined, day0), [[
173
+ "o1",
174
+ {
175
+ orderId: "o1",
176
+ dueAt: day0 + 3 * day
177
+ }
178
+ ]]));
179
+ test("not yet due on day 2: no command", () => thenCommands(whenSweep(atTime(givenEvents([O.event({
180
+ TAG: "OrderPlaced",
181
+ orderId: "o1"
182
+ }, undefined, undefined)]), day0), undefined, day0 + 2 * day), []));
183
+ test("due on day 3: CancelOrder", () => thenCommands(whenSweep(atTime(givenEvents([O.event({
184
+ TAG: "OrderPlaced",
185
+ orderId: "o1"
186
+ }, undefined, undefined)]), day0), undefined, day0 + 3 * day), [[
187
+ "o1",
188
+ {
189
+ TAG: "CancelOrder",
190
+ orderId: "o1"
191
+ }
192
+ ]]));
193
+ test("shipped on day 2: nothing on day 3", () => thenCommands(whenSweep(givenEvents([
194
+ O.event({
195
+ TAG: "OrderPlaced",
196
+ orderId: "o1"
197
+ }, undefined, day0),
198
+ O.event({
199
+ TAG: "OrderShipped",
200
+ orderId: "o1"
201
+ }, undefined, day0 + 2 * day)
202
+ ]), undefined, day0 + 3 * day), []));
203
+ test("a sweep given no time runs when the events happened", () => thenCommands(whenSweep(atTime(givenEvents([O.event({
204
+ TAG: "OrderPlaced",
205
+ orderId: "o1"
206
+ }, undefined, undefined)]), day0), undefined, undefined), []));
207
+ test("process is given the time a scenario fixes", () => thenCommand(whenProcess(givenTodo("o1", {
208
+ orderId: "o1",
209
+ dueAt: day0
210
+ }), day0), "o1", {
211
+ TAG: "CancelOrder",
212
+ orderId: "o1"
213
+ }));
214
+ });
215
+
216
+ let Route = include.Route;
217
+
218
+ let testContext = include.testContext;
219
+
220
+ let withRecordedAt = include.withRecordedAt;
221
+
222
+ let encTodos = include.encTodos;
223
+
224
+ let encPair = include.encPair;
225
+
226
+ let thenResolved = include.thenResolved;
227
+
228
+ let whenExhausted = include.whenExhausted;
229
+
230
+ let thenNoCommand = include.thenNoCommand;
231
+
232
+ let latestRecorded = include.latestRecorded;
233
+
234
+ let routeEach = include.routeEach;
235
+
236
+ let routeAll = include.routeAll;
237
+
238
+ let foldSchedules = include.foldSchedules;
239
+
240
+ let declaredRows = include.declaredRows;
241
+
242
+ let sweep = include.sweep;
243
+
244
+ let tick = include.tick;
245
+
246
+ let whenTick = include.whenTick;
247
+
248
+ let andThenEvents = include.andThenEvents;
249
+
250
+ let thenSchedules = include.thenSchedules;
251
+
252
+ let thenScenarioTodos = include.thenScenarioTodos;
253
+
254
+ export {
255
+ CancelUnshipped,
256
+ day,
257
+ day0,
258
+ CancelUnshipped_Automation,
259
+ Route,
260
+ describe,
261
+ test,
262
+ testContext,
263
+ withRecordedAt,
264
+ encTodos,
265
+ encPair,
266
+ thenTodos,
267
+ thenResolved,
268
+ Mapping,
269
+ givenTodo,
270
+ whenProcess,
271
+ whenExhausted,
272
+ thenCommand,
273
+ thenNoCommand,
274
+ givenEvents,
275
+ atTime,
276
+ latestRecorded,
277
+ routeEach,
278
+ routeAll,
279
+ foldSchedules,
280
+ declaredRows,
281
+ sweep,
282
+ whenSweep,
283
+ tick,
284
+ whenTick,
285
+ thenCommands,
286
+ andThenEvents,
287
+ thenSchedules,
288
+ thenScenarioTodos,
289
+ O,
290
+ }
291
+ /* todoItemSchema Not a pure module */
@@ -18,6 +18,7 @@ module ShipPaid = {
18
18
  let maxRetries = 3
19
19
  let heartbeatInterval = 60
20
20
  let targetName = "Order"
21
+ let schedule = None
21
22
  }
22
23
 
23
24
  module ShipPaid_Automation = {
@@ -57,6 +58,7 @@ module ShipPaid_Automation = {
57
58
  | Orders.OrderCancelled({orderId}) => Some(orderId)
58
59
  | OrderPlaced(_) => None
59
60
  }
61
+ let reschedule = _ => []
60
62
  },
61
63
  )
62
64
 
@@ -74,12 +76,16 @@ module ShipPaid_Automation = {
74
76
  | Payments.Refunded(_) => None
75
77
  | Captured(_) => None
76
78
  }
79
+ let reschedule = _ => []
77
80
  },
78
81
  )
79
82
 
80
83
  let mappings: array<module(Mapping)> = [module(FromOrders), module(FromPayments)]
81
84
 
82
- let process = (id, _item: ShipPaid.todoItem) => Some((id, ShipPaid.Ship({orderId: id})))
85
+ let process = (id, _item: ShipPaid.todoItem, ~now as _) => Some((
86
+ id,
87
+ ShipPaid.Ship({orderId: id}),
88
+ ))
83
89
  let onExhausted = (id, _item: ShipPaid.todoItem) => Some((id, ShipPaid.GiveUp({orderId: id})))
84
90
  }
85
91
 
@@ -38,6 +38,7 @@ let ShipPaid = {
38
38
  maxRetries: 3,
39
39
  heartbeatInterval: 60,
40
40
  targetName: "Order",
41
+ schedule: undefined,
41
42
  authorizationOf: authorizationOf,
42
43
  commandTransition: commandTransition,
43
44
  traits: traits
@@ -106,13 +107,18 @@ function resolve(event) {
106
107
  }
107
108
  }
108
109
 
110
+ function reschedule(param) {
111
+ return [];
112
+ }
113
+
109
114
  let FromOrders = AutomationSlice$Reventless.Mapping.Make({
110
115
  Id: Id$Reventless.$$String,
111
116
  name: name,
112
117
  eventSchema: eventSchema
113
118
  })(ShipPaid)({
114
119
  collect: collect,
115
- resolve: resolve
120
+ resolve: resolve,
121
+ reschedule: reschedule
116
122
  });
117
123
 
118
124
  function collect$1(event, sourceId, _ctx) {
@@ -132,13 +138,18 @@ function resolve$1(event) {
132
138
 
133
139
  }
134
140
 
141
+ function reschedule$1(param) {
142
+ return [];
143
+ }
144
+
135
145
  let FromPayments = AutomationSlice$Reventless.Mapping.Make({
136
146
  Id: Id$Reventless.$$String,
137
147
  name: name$1,
138
148
  eventSchema: eventSchema$1
139
149
  })(ShipPaid)({
140
150
  collect: collect$1,
141
- resolve: resolve$1
151
+ resolve: resolve$1,
152
+ reschedule: reschedule$1
142
153
  });
143
154
 
144
155
  let mappings = [
@@ -146,7 +157,7 @@ let mappings = [
146
157
  FromPayments
147
158
  ];
148
159
 
149
- function process(id, _item) {
160
+ function process(id, _item, param) {
150
161
  return [
151
162
  id,
152
163
  {
@@ -221,7 +232,7 @@ describe("Automation_GWT.FromSlice", () => {
221
232
  test("collect through one mapping", () => thenTodos(O.whenCollect(O.givenEvent({
222
233
  TAG: "OrderPlaced",
223
234
  orderId: "o1"
224
- }), undefined, undefined), [[
235
+ }), undefined, undefined, undefined), [[
225
236
  "o1",
226
237
  {
227
238
  orderId: "o1"
@@ -230,7 +241,7 @@ describe("Automation_GWT.FromSlice", () => {
230
241
  test("collect keys by the source id where the event does not name it", () => thenTodos(P.whenCollect(P.givenEvent({
231
242
  TAG: "Captured",
232
243
  amount: 5
233
- }), "o2", undefined), [[
244
+ }), "o2", undefined, undefined), [[
234
245
  "o2",
235
246
  {
236
247
  orderId: "o2"
@@ -242,7 +253,7 @@ describe("Automation_GWT.FromSlice", () => {
242
253
  })), "o1"));
243
254
  test("process", () => thenCommand(whenProcess(givenTodo("o1", {
244
255
  orderId: "o1"
245
- })), "o1", {
256
+ }), undefined), "o1", {
246
257
  TAG: "Ship",
247
258
  orderId: "o1"
248
259
  }));
@@ -256,12 +267,12 @@ describe("Automation_GWT.FromSlice", () => {
256
267
  P.event({
257
268
  TAG: "Captured",
258
269
  amount: 5
259
- }, "o2"),
270
+ }, "o2", undefined),
260
271
  O.event({
261
272
  TAG: "OrderPlaced",
262
273
  orderId: "o1"
263
- }, undefined)
264
- ]), undefined), [
274
+ }, undefined, undefined)
275
+ ]), undefined, undefined), [
265
276
  [
266
277
  "o2",
267
278
  {
@@ -281,20 +292,20 @@ describe("Automation_GWT.FromSlice", () => {
281
292
  O.event({
282
293
  TAG: "OrderCancelled",
283
294
  orderId: "o1"
284
- }, undefined),
295
+ }, undefined, undefined),
285
296
  O.event({
286
297
  TAG: "OrderPlaced",
287
298
  orderId: "o1"
288
- }, undefined),
299
+ }, undefined, undefined),
289
300
  O.event({
290
301
  TAG: "OrderPlaced",
291
302
  orderId: "o3"
292
- }, undefined),
303
+ }, undefined, undefined),
293
304
  O.event({
294
305
  TAG: "OrderCancelled",
295
306
  orderId: "o3"
296
- }, undefined)
297
- ]), undefined), [[
307
+ }, undefined, undefined)
308
+ ]), undefined, undefined), [[
298
309
  "o1",
299
310
  {
300
311
  orderId: "o1"
@@ -303,26 +314,44 @@ describe("Automation_GWT.FromSlice", () => {
303
314
  test("andThenEvents drains what later events resolve", () => thenScenarioTodos(andThenEvents(whenSweep(givenEvents([O.event({
304
315
  TAG: "OrderPlaced",
305
316
  orderId: "o1"
306
- }, undefined)]), undefined), [O.event({
317
+ }, undefined, undefined)]), undefined, undefined), [O.event({
307
318
  TAG: "OrderCancelled",
308
319
  orderId: "o1"
309
- }, undefined)], undefined), []));
320
+ }, undefined, undefined)], undefined), []));
310
321
  });
311
322
 
312
323
  let Route = include.Route;
313
324
 
314
325
  let testContext = include.testContext;
315
326
 
327
+ let withRecordedAt = include.withRecordedAt;
328
+
316
329
  let encTodos = include.encTodos;
317
330
 
318
331
  let encPair = include.encPair;
319
332
 
320
333
  let thenNoCommand = include.thenNoCommand;
321
334
 
335
+ let atTime = include.atTime;
336
+
337
+ let latestRecorded = include.latestRecorded;
338
+
339
+ let routeEach = include.routeEach;
340
+
322
341
  let routeAll = include.routeAll;
323
342
 
343
+ let foldSchedules = include.foldSchedules;
344
+
345
+ let declaredRows = include.declaredRows;
346
+
324
347
  let sweep = include.sweep;
325
348
 
349
+ let tick = include.tick;
350
+
351
+ let whenTick = include.whenTick;
352
+
353
+ let thenSchedules = include.thenSchedules;
354
+
326
355
  export {
327
356
  ShipPaid,
328
357
  ShipPaid_Automation,
@@ -330,6 +359,7 @@ export {
330
359
  describe,
331
360
  test,
332
361
  testContext,
362
+ withRecordedAt,
333
363
  encTodos,
334
364
  encPair,
335
365
  thenTodos,
@@ -341,11 +371,19 @@ export {
341
371
  thenCommand,
342
372
  thenNoCommand,
343
373
  givenEvents,
374
+ atTime,
375
+ latestRecorded,
376
+ routeEach,
344
377
  routeAll,
378
+ foldSchedules,
379
+ declaredRows,
345
380
  sweep,
346
381
  whenSweep,
382
+ tick,
383
+ whenTick,
347
384
  thenCommands,
348
385
  andThenEvents,
386
+ thenSchedules,
349
387
  thenScenarioTodos,
350
388
  O,
351
389
  P,
@@ -31,7 +31,7 @@ module ShipOrderSlice = {
31
31
  | _ => None
32
32
  }
33
33
 
34
- let process = (_id, item) => Some((
34
+ let process = (_id, item, ~now as _) => Some((
35
35
  item.orderId,
36
36
  CreateShipment({orderId: item.orderId, address: item.shippingAddress}),
37
37
  ))
@@ -49,7 +49,7 @@ function resolve(event) {
49
49
  }
50
50
  }
51
51
 
52
- function process(_id, item) {
52
+ function process(_id, item, param) {
53
53
  return [
54
54
  item.orderId,
55
55
  {
@@ -139,7 +139,7 @@ describe("ShipOrder AutomationSlice", () => {
139
139
  test("process: pending TODO emits CreateShipment", () => thenCommand(whenProcess(givenTodo("o1", {
140
140
  orderId: "o1",
141
141
  shippingAddress: "1 Main St"
142
- })), "o1", {
142
+ }), undefined), "o1", {
143
143
  TAG: "CreateShipment",
144
144
  orderId: "o1",
145
145
  address: "1 Main St"
@@ -149,7 +149,7 @@ describe("ShipOrder AutomationSlice", () => {
149
149
  TAG: "OrderPlaced",
150
150
  orderId: "o1",
151
151
  shippingAddress: "1 Main St"
152
- }]));
152
+ }]), undefined);
153
153
  let commandsOk = thenCommands(s, [[
154
154
  "o1",
155
155
  {