@reventlessdev/reventless-aws 3.0.0-alpha.263 → 3.0.0-alpha.265
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.
- package/CHANGELOG.md +17 -0
- package/package.json +7 -7
- package/src/Platform.res +37 -6
- package/src/Platform.res.mjs +21 -6
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +6 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +4 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +5 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +3 -0
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +6 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +4 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +6 -1
- package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +4 -1
- package/src/adapter/CommandTopic/CommandTopicRegistry.res +50 -0
- package/src/adapter/CommandTopic/CommandTopicRegistry.res.mjs +26 -0
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +21 -3
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +230 -29
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +124 -9
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +188 -3
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +107 -6
- package/src/components/AutomationSlice_Builder.res.mjs +1 -1
- package/src/components/OutboundTranslationSlice_Builder.res +20 -0
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +12 -2
- package/src/plugin/runtime/PluginRuntime_Builder.res +26 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +26 -0
- package/tests/AutomationSliceEntryPoint_OpsTest.res +44 -3
- package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +65 -1
|
@@ -112,6 +112,7 @@ describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandler", () =>
|
|
|
112
112
|
~callback,
|
|
113
113
|
~publishJsons=noopPublish,
|
|
114
114
|
~syncTodoItems=async () => steps->Array.push("sync"),
|
|
115
|
+
~loadTodoItems=async () => steps->Array.push("restore"),
|
|
115
116
|
)
|
|
116
117
|
let envelope = obj([("meta", obj([("service", str("Order"))])), ("event", str("Placed"))])
|
|
117
118
|
await Stream.fromIterable([envelope, str("bare")])->handler->Effect.runPromise
|
|
@@ -120,7 +121,43 @@ describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandler", () =>
|
|
|
120
121
|
expect(receivedCtx.contents->Option.map(c => c.Reventless.AutomationSlice.sliceName))->toEqual(
|
|
121
122
|
Some("S"),
|
|
122
123
|
)
|
|
123
|
-
|
|
124
|
+
// `restore` first: rehydrating the TODO list after phase 1 would let a stored
|
|
125
|
+
// row overwrite one this batch just collected, and after phase 2 would leave
|
|
126
|
+
// the reloaded backlog unprocessed until another invocation.
|
|
127
|
+
expect(steps)->toEqual(["restore", "phase1", "sync", "phase2", "sync"])
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
132
|
+
let dummyRegistered: StreamRoutedEntryPoint_Ops.registeredHandler = {
|
|
133
|
+
handler: (_event, _context) => Effect.succeed(),
|
|
134
|
+
}
|
|
135
|
+
let sliceThat = (~comp, ~run): AutomationSliceEntryPoint_Ops.builtSlice => {
|
|
136
|
+
registered: dummyRegistered,
|
|
137
|
+
sweep: run,
|
|
138
|
+
comp,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
test("sweeps every slice", async () => {
|
|
142
|
+
let swept = []
|
|
143
|
+
await AutomationSliceEntryPoint_Ops.runSweeps([
|
|
144
|
+
sliceThat(~comp="A", ~run=async () => swept->Array.push("a")),
|
|
145
|
+
sliceThat(~comp="B", ~run=async () => swept->Array.push("b")),
|
|
146
|
+
])
|
|
147
|
+
expect(swept)->toEqual(["a", "b"])
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// A sweep exists to recover from a failing external call, so one slice whose
|
|
151
|
+
// geocoder is still down must not cost every other slice on the Lambda its
|
|
152
|
+
// turn — that would be a worse version of the problem being fixed.
|
|
153
|
+
test("a throwing slice does not stop the others", async () => {
|
|
154
|
+
let swept = []
|
|
155
|
+
await AutomationSliceEntryPoint_Ops.runSweeps([
|
|
156
|
+
sliceThat(~comp="A", ~run=async () => swept->Array.push("a")),
|
|
157
|
+
sliceThat(~comp="Boom", ~run=async () => JsError.throwWithMessage("gateway down")),
|
|
158
|
+
sliceThat(~comp="C", ~run=async () => swept->Array.push("c")),
|
|
159
|
+
])
|
|
160
|
+
expect(swept)->toEqual(["a", "c"])
|
|
124
161
|
})
|
|
125
162
|
})
|
|
126
163
|
|
|
@@ -142,13 +179,14 @@ describe("AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler", () => {
|
|
|
142
179
|
received := events
|
|
143
180
|
steps->Array.push("phase1")
|
|
144
181
|
},
|
|
145
|
-
phase2: async _publish => steps->Array.push("phase2"),
|
|
182
|
+
phase2: async (_publish, ~capabilities as _) => steps->Array.push("phase2"),
|
|
146
183
|
}
|
|
147
184
|
let handler = AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler(
|
|
148
185
|
~consumedEventSchema=outboundEventSchema,
|
|
149
186
|
~callback,
|
|
150
187
|
~publishJsons=noopPublish,
|
|
151
188
|
~syncTodoItems=async () => steps->Array.push("sync"),
|
|
189
|
+
~loadTodoItems=async () => steps->Array.push("restore"),
|
|
152
190
|
)
|
|
153
191
|
// `id` is the envelope's subject — the entity the event was published for.
|
|
154
192
|
// An Aggregate's event payload does not repeat it, so this is the only place
|
|
@@ -170,6 +208,9 @@ describe("AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler", () => {
|
|
|
170
208
|
("ord-1", OrderPlaced({orderId: "ord-1"})),
|
|
171
209
|
("", OrderArchived),
|
|
172
210
|
])
|
|
173
|
-
|
|
211
|
+
// `restore` first: rehydrating the TODO list after phase 1 would let a stored
|
|
212
|
+
// row overwrite one this batch just collected, and after phase 2 would leave
|
|
213
|
+
// the reloaded backlog unprocessed until another invocation.
|
|
214
|
+
expect(steps)->toEqual(["restore", "phase1", "sync", "phase2", "sync"])
|
|
174
215
|
})
|
|
175
216
|
})
|
|
@@ -153,6 +153,8 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
153
153
|
sliceName: "S"
|
|
154
154
|
}, callback, noopPublish, async () => {
|
|
155
155
|
steps.push("sync");
|
|
156
|
+
}, async () => {
|
|
157
|
+
steps.push("restore");
|
|
156
158
|
});
|
|
157
159
|
let envelope = Object.fromEntries([
|
|
158
160
|
[
|
|
@@ -177,6 +179,7 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
177
179
|
]);
|
|
178
180
|
globalThis.expect(Stdlib_Option.map(receivedCtx.contents, c => c.sliceName)).toEqual("S");
|
|
179
181
|
globalThis.expect(steps).toEqual([
|
|
182
|
+
"restore",
|
|
180
183
|
"phase1",
|
|
181
184
|
"sync",
|
|
182
185
|
"phase2",
|
|
@@ -185,6 +188,64 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
185
188
|
});
|
|
186
189
|
});
|
|
187
190
|
|
|
191
|
+
globalThis.describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
192
|
+
let dummyRegistered_handler = (_event, _context) => Effect.succeed();
|
|
193
|
+
let dummyRegistered = {
|
|
194
|
+
handler: dummyRegistered_handler
|
|
195
|
+
};
|
|
196
|
+
globalThis.test("sweeps every slice", async () => {
|
|
197
|
+
let swept = [];
|
|
198
|
+
await AutomationSliceEntryPoint_Ops$ReventlessAws.runSweeps([
|
|
199
|
+
{
|
|
200
|
+
registered: dummyRegistered,
|
|
201
|
+
sweep: async () => {
|
|
202
|
+
swept.push("a");
|
|
203
|
+
},
|
|
204
|
+
comp: "A"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
registered: dummyRegistered,
|
|
208
|
+
sweep: async () => {
|
|
209
|
+
swept.push("b");
|
|
210
|
+
},
|
|
211
|
+
comp: "B"
|
|
212
|
+
}
|
|
213
|
+
]);
|
|
214
|
+
globalThis.expect(swept).toEqual([
|
|
215
|
+
"a",
|
|
216
|
+
"b"
|
|
217
|
+
]);
|
|
218
|
+
});
|
|
219
|
+
globalThis.test("a throwing slice does not stop the others", async () => {
|
|
220
|
+
let swept = [];
|
|
221
|
+
await AutomationSliceEntryPoint_Ops$ReventlessAws.runSweeps([
|
|
222
|
+
{
|
|
223
|
+
registered: dummyRegistered,
|
|
224
|
+
sweep: async () => {
|
|
225
|
+
swept.push("a");
|
|
226
|
+
},
|
|
227
|
+
comp: "A"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
registered: dummyRegistered,
|
|
231
|
+
sweep: async () => Stdlib_JsError.throwWithMessage("gateway down"),
|
|
232
|
+
comp: "Boom"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
registered: dummyRegistered,
|
|
236
|
+
sweep: async () => {
|
|
237
|
+
swept.push("c");
|
|
238
|
+
},
|
|
239
|
+
comp: "C"
|
|
240
|
+
}
|
|
241
|
+
]);
|
|
242
|
+
globalThis.expect(swept).toEqual([
|
|
243
|
+
"a",
|
|
244
|
+
"c"
|
|
245
|
+
]);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
188
249
|
let outboundEventSchema = S.union([
|
|
189
250
|
S.schema(s => ({
|
|
190
251
|
TAG: "OrderPlaced",
|
|
@@ -204,7 +265,7 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler
|
|
|
204
265
|
received.contents = events;
|
|
205
266
|
steps.push("phase1");
|
|
206
267
|
};
|
|
207
|
-
let callback_phase2 = async _publish => {
|
|
268
|
+
let callback_phase2 = async (_publish, param) => {
|
|
208
269
|
steps.push("phase2");
|
|
209
270
|
};
|
|
210
271
|
let callback = {
|
|
@@ -214,6 +275,8 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler
|
|
|
214
275
|
};
|
|
215
276
|
let handler = AutomationSliceEntryPoint_Ops$ReventlessAws.makeOutboundJsonEventsHandler(outboundEventSchema, callback, noopPublish, async () => {
|
|
216
277
|
steps.push("sync");
|
|
278
|
+
}, async () => {
|
|
279
|
+
steps.push("restore");
|
|
217
280
|
});
|
|
218
281
|
let placed = Object.fromEntries([
|
|
219
282
|
[
|
|
@@ -273,6 +336,7 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeOutboundJsonEventsHandler
|
|
|
273
336
|
]
|
|
274
337
|
]);
|
|
275
338
|
globalThis.expect(steps).toEqual([
|
|
339
|
+
"restore",
|
|
276
340
|
"phase1",
|
|
277
341
|
"sync",
|
|
278
342
|
"phase2",
|