@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,140 @@
1
+ // A declared schedule: the demand report every morning at 06:00. The slice maps the
2
+ // framework's Clock source; each tick makes the day's item, `process` requests the
3
+ // report, and the event that request records completes the item. The catalog team
4
+ // can move the report or stop it with an event, which replaces the declared time.
5
+
6
+ module DemandReport = {
7
+ let name = "DemandReport"
8
+ let moduleUrl = ""
9
+
10
+ @schema
11
+ type todoItem = {day: float}
12
+
13
+ @schema
14
+ type command = RequestDemandReport({day: float})
15
+
16
+ let maxRetries = 3
17
+ let heartbeatInterval = 60
18
+ let targetName = "ReportSettings"
19
+ let schedule = Some(Reventless.Schedule.Calendar({calendar: Daily({hour: 6, minute: 0})}))
20
+ }
21
+
22
+ module DemandReport_Automation = {
23
+ module M = Reventless.AutomationSlice.Mappings.Make(DemandReport)
24
+ module type Mapping = M.Mapping
25
+ let moduleUrl = ""
26
+
27
+ module CatalogDcbSource = {
28
+ module Id = Reventless.Id.String
29
+ let name = "CatalogDcbEventLog"
30
+ @schema
31
+ type event =
32
+ | DemandReportRequested({day: float})
33
+ | DemandReportTimeChanged({time: Reventless.Schedule.time})
34
+ | DemandReportStopped
35
+ }
36
+
37
+ module FromClock = Reventless.AutomationSlice.Mapping.Make(
38
+ Reventless.Clock,
39
+ DemandReport,
40
+ {
41
+ open Reventless.Clock
42
+ let collect = (Tick({key, at}), ~sourceId as _, _ctx) => [
43
+ (itemId(key, at), ({day: at}: DemandReport.todoItem)),
44
+ ]
45
+ let resolve = _ => None
46
+ let reschedule = _ => []
47
+ },
48
+ )
49
+
50
+ module FromCatalogDcb = Reventless.AutomationSlice.Mapping.Make(
51
+ CatalogDcbSource,
52
+ DemandReport,
53
+ {
54
+ let collect = (_, ~sourceId as _, _ctx) => []
55
+ let resolve = event =>
56
+ switch event {
57
+ | CatalogDcbSource.DemandReportRequested({day}) =>
58
+ Some(Reventless.Clock.itemId(Reventless.Clock.defaultKey, day))
59
+ | _ => None
60
+ }
61
+ let reschedule = event =>
62
+ switch event {
63
+ | CatalogDcbSource.DemandReportTimeChanged({time}) => [
64
+ Reventless.AutomationSlice.Set({key: Reventless.Clock.defaultKey, time}),
65
+ ]
66
+ | DemandReportStopped => [Clear({key: Reventless.Clock.defaultKey})]
67
+ | DemandReportRequested(_) => []
68
+ }
69
+ },
70
+ )
71
+
72
+ let mappings: array<module(Mapping)> = [module(FromClock), module(FromCatalogDcb)]
73
+
74
+ let process = (id, item: DemandReport.todoItem, ~now as _) => Some((
75
+ id,
76
+ DemandReport.RequestDemandReport({day: item.day}),
77
+ ))
78
+ let onExhausted = (_id, _item: DemandReport.todoItem) => None
79
+ }
80
+
81
+ open DemandReport
82
+ open DemandReport_Automation
83
+ include Automation_GWT.FromSlice(DemandReport, DemandReport_Automation)
84
+ module Catalog = Mapping(FromCatalogDcb)
85
+
86
+ let morning = Date.fromString("2026-10-16T06:00:00Z")->Date.getTime
87
+ let dayItem = "default@2026-10-16T06:00Z"
88
+
89
+ describe("a declared schedule", () => {
90
+ test("the tick makes the day's item, and process requests the report", () =>
91
+ givenEvents([])
92
+ ->whenTick(~at=morning)
93
+ ->thenCommands([(dayItem, RequestDemandReport({day: morning}))])
94
+ )
95
+
96
+ test("the same tick delivered twice makes one item", () =>
97
+ givenEvents([tick(morning)])
98
+ ->whenTick(~at=morning)
99
+ ->thenScenarioTodos([(dayItem, {day: morning})])
100
+ )
101
+
102
+ test("the report's own event completes the day's item", () =>
103
+ givenEvents([])
104
+ ->whenTick(~at=morning)
105
+ ->andThenEvents([Catalog.event(DemandReportRequested({day: morning}))])
106
+ ->thenScenarioTodos([])
107
+ )
108
+
109
+ test("the item id is the key and the scheduled minute, in UTC", () =>
110
+ givenEvents([])
111
+ ->whenTick(~key="r1", ~at=Date.fromString("2026-10-16T18:00:42Z")->Date.getTime)
112
+ ->thenScenarioTodos([
113
+ ("r1@2026-10-16T18:00Z", {day: Date.fromString("2026-10-16T18:00:42Z")->Date.getTime}),
114
+ ])
115
+ )
116
+ })
117
+
118
+ let daily6 = Reventless.Schedule.Calendar({calendar: Daily({hour: 6, minute: 0})})
119
+ let weekdays730 = Reventless.Schedule.Calendar({
120
+ calendar: Weekly({days: [Mon, Tue, Wed, Thu, Fri], hour: 7, minute: 30}),
121
+ })
122
+
123
+ describe("the same schedule, moved by an event", () => {
124
+ test("with no event, the schedule is the declared one", () =>
125
+ givenEvents([])->whenSweep(~now=morning)->thenSchedules([("default", daily6)])
126
+ )
127
+
128
+ test("an event replaces the declared time", () =>
129
+ givenEvents([Catalog.event(DemandReportTimeChanged({time: weekdays730}))])
130
+ ->whenSweep(~now=morning)
131
+ ->thenSchedules([("default", weekdays730)])
132
+ )
133
+
134
+ test("an event that stops the report leaves no schedule", () =>
135
+ givenEvents([Catalog.event(DemandReportTimeChanged({time: weekdays730}))])
136
+ ->whenSweep(~now=morning)
137
+ ->andThenEvents([Catalog.event(DemandReportStopped)])
138
+ ->thenSchedules([])
139
+ )
140
+ })
@@ -0,0 +1,356 @@
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 Clock$Reventless from "@reventlessdev/reventless-spec/src/components/Clock.res.mjs";
6
+ import * as Schedule$Reventless from "@reventlessdev/reventless-spec/src/types/Schedule.res.mjs";
7
+ import * as AutomationSlice$Reventless from "@reventlessdev/reventless-spec/src/components/AutomationSlice.res.mjs";
8
+ import * as Automation_GWT$ReventlessGwt from "../src/Automation_GWT.res.mjs";
9
+
10
+ let todoItemSchema = Sury.$schema(s => ({
11
+ day: s.m(Sury.number)
12
+ }));
13
+
14
+ let commandSchema = Sury.$schema(s => ({
15
+ TAG: "RequestDemandReport",
16
+ day: s.m(Sury.number)
17
+ }));
18
+
19
+ function authorizationOf(param) {
20
+ return "AllowAuthenticated";
21
+ }
22
+
23
+ function commandTransition(param) {
24
+ return "Undeclared";
25
+ }
26
+
27
+ let traits = [];
28
+
29
+ let DemandReport_schedule = {
30
+ TAG: "Calendar",
31
+ calendar: {
32
+ TAG: "Daily",
33
+ hour: 6,
34
+ minute: 0
35
+ }
36
+ };
37
+
38
+ let DemandReport = {
39
+ name: "DemandReport",
40
+ moduleUrl: "",
41
+ todoItemSchema: todoItemSchema,
42
+ commandSchema: commandSchema,
43
+ maxRetries: 3,
44
+ heartbeatInterval: 60,
45
+ targetName: "ReportSettings",
46
+ schedule: DemandReport_schedule,
47
+ authorizationOf: authorizationOf,
48
+ commandTransition: commandTransition,
49
+ traits: traits
50
+ };
51
+
52
+ let M = AutomationSlice$Reventless.Mappings.Make(DemandReport);
53
+
54
+ let moduleUrl = "";
55
+
56
+ let name = "CatalogDcbEventLog";
57
+
58
+ let eventSchema = Sury.union([
59
+ Sury.$schema(s => ({
60
+ TAG: "DemandReportRequested",
61
+ day: s.m(Sury.number)
62
+ })),
63
+ Sury.$schema(s => ({
64
+ TAG: "DemandReportTimeChanged",
65
+ time: s.m(Schedule$Reventless.timeSchema)
66
+ })),
67
+ Sury.literal("DemandReportStopped")
68
+ ]);
69
+
70
+ let CatalogDcbSource = {
71
+ Id: undefined,
72
+ name: name,
73
+ eventSchema: eventSchema
74
+ };
75
+
76
+ function collect(param, param$1, _ctx) {
77
+ let at = param.at;
78
+ return [[
79
+ Clock$Reventless.itemId(param.key, at),
80
+ {
81
+ day: at
82
+ }
83
+ ]];
84
+ }
85
+
86
+ function resolve(param) {
87
+
88
+ }
89
+
90
+ function reschedule(param) {
91
+ return [];
92
+ }
93
+
94
+ let FromClock = AutomationSlice$Reventless.Mapping.Make({
95
+ Id: Id$Reventless.$$String,
96
+ name: Clock$Reventless.name,
97
+ eventSchema: Clock$Reventless.eventSchema
98
+ })(DemandReport)({
99
+ collect: collect,
100
+ resolve: resolve,
101
+ reschedule: reschedule
102
+ });
103
+
104
+ function collect$1(param, param$1, _ctx) {
105
+ return [];
106
+ }
107
+
108
+ function resolve$1(event) {
109
+ if (typeof event !== "object" || event.TAG !== "DemandReportRequested") {
110
+ return;
111
+ } else {
112
+ return Clock$Reventless.itemId(Clock$Reventless.defaultKey, event.day);
113
+ }
114
+ }
115
+
116
+ function reschedule$1(event) {
117
+ if (typeof event !== "object") {
118
+ return [{
119
+ TAG: "Clear",
120
+ key: Clock$Reventless.defaultKey
121
+ }];
122
+ } else if (event.TAG === "DemandReportRequested") {
123
+ return [];
124
+ } else {
125
+ return [{
126
+ TAG: "Set",
127
+ key: Clock$Reventless.defaultKey,
128
+ time: event.time
129
+ }];
130
+ }
131
+ }
132
+
133
+ let FromCatalogDcb = AutomationSlice$Reventless.Mapping.Make({
134
+ Id: Id$Reventless.$$String,
135
+ name: name,
136
+ eventSchema: eventSchema
137
+ })(DemandReport)({
138
+ collect: collect$1,
139
+ resolve: resolve$1,
140
+ reschedule: reschedule$1
141
+ });
142
+
143
+ let mappings = [
144
+ FromClock,
145
+ FromCatalogDcb
146
+ ];
147
+
148
+ function process(id, item, param) {
149
+ return [
150
+ id,
151
+ {
152
+ TAG: "RequestDemandReport",
153
+ day: item.day
154
+ }
155
+ ];
156
+ }
157
+
158
+ function onExhausted(_id, _item) {
159
+
160
+ }
161
+
162
+ let DemandReport_Automation = {
163
+ M: M,
164
+ moduleUrl: moduleUrl,
165
+ CatalogDcbSource: CatalogDcbSource,
166
+ FromClock: FromClock,
167
+ FromCatalogDcb: FromCatalogDcb,
168
+ mappings: mappings,
169
+ process: process,
170
+ onExhausted: onExhausted
171
+ };
172
+
173
+ let include = Automation_GWT$ReventlessGwt.FromSlice(DemandReport)({
174
+ process: process,
175
+ onExhausted: onExhausted,
176
+ moduleUrl: moduleUrl,
177
+ mappings: mappings
178
+ });
179
+
180
+ let describe = include.describe;
181
+
182
+ let test = include.test;
183
+
184
+ let Mapping = include.Mapping;
185
+
186
+ let givenEvents = include.givenEvents;
187
+
188
+ let whenSweep = include.whenSweep;
189
+
190
+ let tick = include.tick;
191
+
192
+ let whenTick = include.whenTick;
193
+
194
+ let thenCommands = include.thenCommands;
195
+
196
+ let andThenEvents = include.andThenEvents;
197
+
198
+ let thenSchedules = include.thenSchedules;
199
+
200
+ let thenScenarioTodos = include.thenScenarioTodos;
201
+
202
+ let Catalog = Mapping(FromCatalogDcb);
203
+
204
+ let morning = new Date("2026-10-16T06:00:00Z").getTime();
205
+
206
+ let dayItem = "default@2026-10-16T06:00Z";
207
+
208
+ describe("a declared schedule", () => {
209
+ test("the tick makes the day's item, and process requests the report", () => thenCommands(whenTick(givenEvents([]), undefined, morning, undefined), [[
210
+ dayItem,
211
+ {
212
+ TAG: "RequestDemandReport",
213
+ day: morning
214
+ }
215
+ ]]));
216
+ test("the same tick delivered twice makes one item", () => thenScenarioTodos(whenTick(givenEvents([tick(undefined, morning)]), undefined, morning, undefined), [[
217
+ dayItem,
218
+ {
219
+ day: morning
220
+ }
221
+ ]]));
222
+ test("the report's own event completes the day's item", () => thenScenarioTodos(andThenEvents(whenTick(givenEvents([]), undefined, morning, undefined), [Catalog.event({
223
+ TAG: "DemandReportRequested",
224
+ day: morning
225
+ }, undefined, undefined)], undefined), []));
226
+ test("the item id is the key and the scheduled minute, in UTC", () => thenScenarioTodos(whenTick(givenEvents([]), "r1", new Date("2026-10-16T18:00:42Z").getTime(), undefined), [[
227
+ "r1@2026-10-16T18:00Z",
228
+ {
229
+ day: new Date("2026-10-16T18:00:42Z").getTime()
230
+ }
231
+ ]]));
232
+ });
233
+
234
+ let daily6 = {
235
+ TAG: "Calendar",
236
+ calendar: {
237
+ TAG: "Daily",
238
+ hour: 6,
239
+ minute: 0
240
+ }
241
+ };
242
+
243
+ let weekdays730_0 = {
244
+ TAG: "Weekly",
245
+ days: [
246
+ "Mon",
247
+ "Tue",
248
+ "Wed",
249
+ "Thu",
250
+ "Fri"
251
+ ],
252
+ hour: 7,
253
+ minute: 30
254
+ };
255
+
256
+ let weekdays730 = {
257
+ TAG: "Calendar",
258
+ calendar: weekdays730_0
259
+ };
260
+
261
+ describe("the same schedule, moved by an event", () => {
262
+ test("with no event, the schedule is the declared one", () => thenSchedules(whenSweep(givenEvents([]), undefined, morning), [[
263
+ "default",
264
+ daily6
265
+ ]]));
266
+ test("an event replaces the declared time", () => thenSchedules(whenSweep(givenEvents([Catalog.event({
267
+ TAG: "DemandReportTimeChanged",
268
+ time: weekdays730
269
+ }, undefined, undefined)]), undefined, morning), [[
270
+ "default",
271
+ weekdays730
272
+ ]]));
273
+ test("an event that stops the report leaves no schedule", () => thenSchedules(andThenEvents(whenSweep(givenEvents([Catalog.event({
274
+ TAG: "DemandReportTimeChanged",
275
+ time: weekdays730
276
+ }, undefined, undefined)]), undefined, morning), [Catalog.event("DemandReportStopped", undefined, undefined)], undefined), []));
277
+ });
278
+
279
+ let Route = include.Route;
280
+
281
+ let testContext = include.testContext;
282
+
283
+ let withRecordedAt = include.withRecordedAt;
284
+
285
+ let encTodos = include.encTodos;
286
+
287
+ let encPair = include.encPair;
288
+
289
+ let thenTodos = include.thenTodos;
290
+
291
+ let thenResolved = include.thenResolved;
292
+
293
+ let givenTodo = include.givenTodo;
294
+
295
+ let whenProcess = include.whenProcess;
296
+
297
+ let whenExhausted = include.whenExhausted;
298
+
299
+ let thenCommand = include.thenCommand;
300
+
301
+ let thenNoCommand = include.thenNoCommand;
302
+
303
+ let atTime = include.atTime;
304
+
305
+ let latestRecorded = include.latestRecorded;
306
+
307
+ let routeEach = include.routeEach;
308
+
309
+ let routeAll = include.routeAll;
310
+
311
+ let foldSchedules = include.foldSchedules;
312
+
313
+ let declaredRows = include.declaredRows;
314
+
315
+ let sweep = include.sweep;
316
+
317
+ export {
318
+ DemandReport,
319
+ DemandReport_Automation,
320
+ Route,
321
+ describe,
322
+ test,
323
+ testContext,
324
+ withRecordedAt,
325
+ encTodos,
326
+ encPair,
327
+ thenTodos,
328
+ thenResolved,
329
+ Mapping,
330
+ givenTodo,
331
+ whenProcess,
332
+ whenExhausted,
333
+ thenCommand,
334
+ thenNoCommand,
335
+ givenEvents,
336
+ atTime,
337
+ latestRecorded,
338
+ routeEach,
339
+ routeAll,
340
+ foldSchedules,
341
+ declaredRows,
342
+ sweep,
343
+ whenSweep,
344
+ tick,
345
+ whenTick,
346
+ thenCommands,
347
+ andThenEvents,
348
+ thenSchedules,
349
+ thenScenarioTodos,
350
+ Catalog,
351
+ morning,
352
+ dayItem,
353
+ daily6,
354
+ weekdays730,
355
+ }
356
+ /* todoItemSchema Not a pure module */
@@ -73,7 +73,7 @@ module AutoShipSlice = {
73
73
  | OrderPlaced(_) => None
74
74
  }
75
75
 
76
- let process = (id, _todo) => Some((id, ShipOrder({orderId: id})))
76
+ let process = (id, _todo, ~now as _) => Some((id, ShipOrder({orderId: id})))
77
77
  let onExhausted = (_id, _todo) => None
78
78
  }
79
79
 
@@ -122,7 +122,7 @@ function resolve(event) {
122
122
  }
123
123
  }
124
124
 
125
- function process(id, _todo) {
125
+ function process(id, _todo, param) {
126
126
  return [
127
127
  id,
128
128
  {