@reventlessdev/reventless-aws 3.0.0-alpha.387 → 3.0.0-alpha.389
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 +32 -0
- package/README.md +1 -1
- package/package.json +12 -12
- package/scripts/ProvisionIdentity.res +1 -1
- package/src/Platform.res +14 -14
- package/src/Platform.res.mjs +30 -30
- package/src/Platform_Stack.res +3 -3
- package/src/adapter/AWS_Tags.res +1 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +1 -1
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +7 -7
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res.mjs +5 -5
- package/src/adapter/Auth/Auth_ActiveRolePoolAttachment.res +1 -1
- package/src/adapter/Auth/Auth_ActiveRoleStore_Ops.res +2 -2
- package/src/adapter/Auth/Auth_ActiveRoleStore_Schema.res +1 -1
- package/src/adapter/Auth/Auth_Cognito.res +1 -1
- package/src/adapter/Auth/Auth_LoginIdentifier.res +1 -1
- package/src/adapter/Auth/Auth_SignUpMode.res +1 -1
- package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +2 -2
- package/src/adapter/EventLog/EventLogBackend.res +1 -1
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +2 -2
- package/src/adapter/Runtime/AggregateEntryPoint.mjs +6 -6
- package/src/adapter/Runtime/AggregateEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +20 -10
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +20 -10
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +7 -7
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +19 -9
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +6 -6
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +1 -1
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +8 -3
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +7 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +7 -7
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res.mjs +2 -2
- package/src/adapter/Runtime/EventCollectorEntryPoint.mjs +1 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +6 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +6 -1
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +4 -4
- package/src/adapter/Runtime/RuntimeExtensionEntryPoint_Ops.res +2 -2
- package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +6 -1
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +10 -10
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +3 -3
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +6 -1
- package/src/adapter/StateTopic/StateTopic_AppSync.res +2 -2
- package/src/capability/Capability_Messaging.res +2 -2
- package/src/components/Aggregate_Builder_Micro.res +3 -3
- package/src/components/Aggregate_Builder_Micro.res.mjs +3 -3
- package/src/components/Aggregate_Builder_NoResolver.res +3 -3
- package/src/components/Aggregate_Builder_NoResolver.res.mjs +3 -3
- package/src/components/Aggregate_Builder_PerAggregate.res +3 -3
- package/src/components/Aggregate_Builder_PerAggregate.res.mjs +3 -3
- package/src/components/Aggregate_Builder_Single.res +3 -3
- package/src/components/Aggregate_Builder_Single.res.mjs +3 -3
- package/src/components/Aggregate_Builder_Single_Async.res +3 -3
- package/src/components/Aggregate_Builder_Single_Async.res.mjs +3 -3
- package/src/components/Api/AppSync_Adapter.res +3 -3
- package/src/components/Api/AppSync_SdlDecorate.res +3 -3
- package/src/components/SideEffectHandler_PerSideEffectHandler.res +1 -1
- package/src/components/StateChangeSlice_Builder.res +4 -4
- package/src/components/StateChangeSlice_Builder.res.mjs +4 -4
- package/src/plugin/runtime/PluginRuntime_Builder.res +7 -7
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +3 -3
- package/src/plugin/stack/Plugin_Stack.res +1 -1
- package/src/util/Util_Bundle.res +1 -1
- package/tests/AppSync_AdapterTest.res +1 -1
- package/tests/AppSync_RetirementNarrowingTest.res +1 -1
- package/tests/AppSync_SdlDecorateTest.res +1 -1
- package/tests/Auth_LoginIdentifierTest.res +1 -1
- package/tests/Auth_SignUpModeTest.res +1 -1
- package/tests/BakeConvergenceTest.res +11 -11
- package/tests/BakeConvergenceTest.res.mjs +13 -13
- package/tests/QueryDbResolvers_AppSyncTest.res +1 -1
- package/tests/Upload_ClaimTest.res +1 -1
- package/tests/Util_AwsErrorTest.res +1 -1
- package/tests/Util_StoreLayoutTest.res +1 -1
- package/tests/dcbColdStartPartition.mjs +3 -3
- package/tests/integration/{AggTestAggregateBehavior.res → AggTestAggregateDecision.res} +2 -2
- package/tests/integration/{AggTestAggregateBehavior.res.mjs → AggTestAggregateDecision.res.mjs} +1 -1
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res +3 -3
- package/tests/integration/AggregateEntryPoint_IntegrationTest.res.mjs +2 -2
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +5 -5
- package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res.mjs +4 -4
- package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +1 -1
- package/tests/integration/{EpCompositeSliceBehavior.res → EpCompositeSliceDecision.res} +2 -2
- package/tests/integration/{EpCompositeSliceBehavior.res.mjs → EpCompositeSliceDecision.res.mjs} +1 -1
- package/tests/integration/{EpTestSliceBehavior.res → EpTestSliceDecision.res} +2 -2
- package/tests/integration/{EpTestSliceBehavior.res.mjs → EpTestSliceDecision.res.mjs} +1 -1
|
@@ -13,7 +13,7 @@ type runtimeParts = Util.Lambda.runtimeParts
|
|
|
13
13
|
|
|
14
14
|
type aggregateInfo = {
|
|
15
15
|
specModulePath: string,
|
|
16
|
-
|
|
16
|
+
decisionModulePath: string,
|
|
17
17
|
eventLogTableName: Pulumi.Output.t<string>,
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -29,10 +29,10 @@ let setConfig = (c: ReventlessCore.Runtime.commandHandlerConfig) => configRef :=
|
|
|
29
29
|
let registerAggregate = (
|
|
30
30
|
~aggregateName,
|
|
31
31
|
~specModulePath,
|
|
32
|
-
~
|
|
32
|
+
~decisionModulePath,
|
|
33
33
|
~eventLogTableName,
|
|
34
34
|
) =>
|
|
35
|
-
aggregateInfos->Dict.set(aggregateName, {specModulePath,
|
|
35
|
+
aggregateInfos->Dict.set(aggregateName, {specModulePath, decisionModulePath, eventLogTableName})
|
|
36
36
|
|
|
37
37
|
type storedSpec = {
|
|
38
38
|
aggregateName: string,
|
|
@@ -91,7 +91,12 @@ let forCommandGenerator: ReventlessCore.Runtime.forComponent<
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
let forCommandTopic: ReventlessCore.Runtime.forComponent<
|
|
94
|
-
ReventlessCore.Runtime.
|
|
94
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
95
|
+
CommandTopicChannel.callbackEvent,
|
|
96
|
+
context,
|
|
97
|
+
unit,
|
|
98
|
+
string,
|
|
99
|
+
>,
|
|
95
100
|
runtimeParts,
|
|
96
101
|
ReventlessCore.CommandTopic.component<'op>,
|
|
97
102
|
> = (~handler as _, ~connect, ~memorySize=1024, ~timeout=30, commandTopic) => {
|
|
@@ -125,7 +130,12 @@ let forCommandTopic: ReventlessCore.Runtime.forComponent<
|
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
128
|
-
ReventlessCore.Runtime.
|
|
133
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
134
|
+
EventCollectorChannel.callbackEvent,
|
|
135
|
+
context,
|
|
136
|
+
unit,
|
|
137
|
+
string,
|
|
138
|
+
>,
|
|
129
139
|
ReventlessCore.EventCollector.component,
|
|
130
140
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
131
141
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -200,12 +210,12 @@ let finish = () =>
|
|
|
200
210
|
switch aggregateInfos->Dict.get(spec.aggregateName) {
|
|
201
211
|
| Some(info) =>
|
|
202
212
|
let specPkg = Util_Bundle.extractPackageName(info.specModulePath)
|
|
203
|
-
let
|
|
213
|
+
let decisionPkg = Util_Bundle.extractPackageName(info.decisionModulePath)
|
|
204
214
|
packageDirs->Dict.set(specPkg, Util_Bundle.resolvePackageRoot(specPkg))
|
|
205
|
-
packageDirs->Dict.set(
|
|
215
|
+
packageDirs->Dict.set(decisionPkg, Util_Bundle.resolvePackageRoot(decisionPkg))
|
|
206
216
|
|
|
207
217
|
let specModule = info.specModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
208
|
-
let
|
|
218
|
+
let decisionModule = info.decisionModulePath->JSON.stringifyAny->Option.getOr(`""`)
|
|
209
219
|
|
|
210
220
|
// `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
|
|
211
221
|
// deploy-time structure, and the Lambda-name fallback yields nothing for a
|
|
@@ -221,7 +231,7 @@ let finish = () =>
|
|
|
221
231
|
spec.queueArn,
|
|
222
232
|
pgConnectionFragment,
|
|
223
233
|
))->Pulumi.Output.apply(((table, queueUrl, queueArn, pgFragment)) =>
|
|
224
|
-
`{"specModule":${specModule},"
|
|
234
|
+
`{"specModule":${specModule},"decisionModule":${decisionModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}${pgFragment}}`
|
|
225
235
|
)
|
|
226
236
|
let _ = handlerOutputs->Array.push(handlerJson)
|
|
227
237
|
| None =>
|
|
@@ -30,10 +30,10 @@ function setConfig(c) {
|
|
|
30
30
|
configRef.contents = c;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
function registerAggregate(aggregateName, specModulePath,
|
|
33
|
+
function registerAggregate(aggregateName, specModulePath, decisionModulePath, eventLogTableName) {
|
|
34
34
|
aggregateInfos[aggregateName] = {
|
|
35
35
|
specModulePath: specModulePath,
|
|
36
|
-
|
|
36
|
+
decisionModulePath: decisionModulePath,
|
|
37
37
|
eventLogTableName: eventLogTableName
|
|
38
38
|
};
|
|
39
39
|
}
|
|
@@ -162,18 +162,18 @@ function finish() {
|
|
|
162
162
|
return log.warn("AggregateRuntime_Builder_Single_Async", undefined, `no handler registered for ` + spec.aggregateName);
|
|
163
163
|
}
|
|
164
164
|
let specPkg = Util_Bundle$ReventlessAws.extractPackageName(info.specModulePath);
|
|
165
|
-
let
|
|
165
|
+
let decisionPkg = Util_Bundle$ReventlessAws.extractPackageName(info.decisionModulePath);
|
|
166
166
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, specPkg);
|
|
167
|
-
packageDirs[
|
|
167
|
+
packageDirs[decisionPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, decisionPkg);
|
|
168
168
|
let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
|
|
169
|
-
let
|
|
169
|
+
let decisionModule = Stdlib_Option.getOr(JSON.stringify(info.decisionModulePath), `""`);
|
|
170
170
|
let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
|
|
171
171
|
let handlerJson = Pulumi.all([
|
|
172
172
|
info.eventLogTableName,
|
|
173
173
|
spec.queueUrl,
|
|
174
174
|
spec.queueArn,
|
|
175
175
|
pgConnectionFragment
|
|
176
|
-
]).apply(param => `{"specModule":` + specModule + `,"
|
|
176
|
+
]).apply(param => `{"specModule":` + specModule + `,"decisionModule":` + decisionModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + param[3] + `}`);
|
|
177
177
|
handlerOutputs.push(handlerJson);
|
|
178
178
|
});
|
|
179
179
|
let handlerConfigOutput = Pulumi.all(handlerOutputs).apply(handlers => `{"handlers":[` + handlers.join(",") + `]}`);
|
|
@@ -399,7 +399,7 @@ channel it cannot send on.
|
|
|
399
399
|
/** The email transport this deployment chose.
|
|
400
400
|
|
|
401
401
|
Read per call like the sender beside it, and defaulting to SES on anything it
|
|
402
|
-
does not
|
|
402
|
+
does not recognize — including the empty string a platform that named nothing
|
|
403
403
|
exports. The deploy already refuses an unknown value (`Capability_Messaging`
|
|
404
404
|
parses it there, where a human is watching); defaulting again here is for the
|
|
405
405
|
case that cannot be refused, a Lambda whose variable was edited by hand. SES
|
|
@@ -138,7 +138,12 @@ let storedSpecs: array<storedSpec> = []
|
|
|
138
138
|
let grandParent = ref(None)
|
|
139
139
|
|
|
140
140
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
141
|
-
ReventlessCore.Runtime.
|
|
141
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
142
|
+
EventCollectorChannel.callbackEvent,
|
|
143
|
+
context,
|
|
144
|
+
unit,
|
|
145
|
+
string,
|
|
146
|
+
>,
|
|
142
147
|
ReventlessCore.EventCollector.component,
|
|
143
148
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
144
149
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -533,7 +538,7 @@ let finish = () =>
|
|
|
533
538
|
// HANDLER_CONFIG: this is one shared Lambda and every slice on it reaches
|
|
534
539
|
// the same capability. A capability the platform did not provision arrives
|
|
535
540
|
// as "", which its client reads as "not configured" and reports as a
|
|
536
|
-
// retryable `Unavailable` — a
|
|
541
|
+
// retryable `Unavailable` — a modeled outcome rather than a missing
|
|
537
542
|
// variable that fails as a crash.
|
|
538
543
|
PluginRuntime_Builder.capabilityEnv()->Array.forEach(((name, value)) =>
|
|
539
544
|
envVars->Dict.set(name, value->Pulumi.Output.asInput)
|
|
@@ -782,7 +787,7 @@ let finishWithDcbEventLog = (
|
|
|
782
787
|
// HANDLER_CONFIG: this is one shared Lambda and every slice on it reaches
|
|
783
788
|
// the same capability. A capability the platform did not provision arrives
|
|
784
789
|
// as "", which its client reads as "not configured" and reports as a
|
|
785
|
-
// retryable `Unavailable` — a
|
|
790
|
+
// retryable `Unavailable` — a modeled outcome rather than a missing
|
|
786
791
|
// variable that fails as a crash.
|
|
787
792
|
PluginRuntime_Builder.capabilityEnv()->Array.forEach(((name, value)) =>
|
|
788
793
|
envVars->Dict.set(name, value->Pulumi.Output.asInput)
|
|
@@ -64,19 +64,19 @@ const dcbComp = (plugin) => `DcbCommandTopicRuntime(${plugin})`;
|
|
|
64
64
|
// already-parsed `HANDLER_CONFIG` shape, with an injectable module loader.
|
|
65
65
|
// In production, `buildHandler` below wraps this with the env-config + the
|
|
66
66
|
// Lambda's `/var/task/node_modules` dynamic-import; integration tests inject
|
|
67
|
-
// their own loader that returns pre-imported spec/
|
|
67
|
+
// their own loader that returns pre-imported spec/decision modules so the test
|
|
68
68
|
// can drive the real `cmdGenHandler` end-to-end against DynamoDB Local.
|
|
69
69
|
export async function buildHandlersForConfig(config, opts = {}) {
|
|
70
70
|
const loadModule = opts.loadModule ?? dynamicImport;
|
|
71
71
|
|
|
72
|
-
// Untyped boundary: dynamically import + id-patch the user Spec/
|
|
72
|
+
// Untyped boundary: dynamically import + id-patch the user Spec/Decision
|
|
73
73
|
// modules. Their types are unknowable here — this is the one seam the typed
|
|
74
74
|
// core (below) cannot own, so it stays in the shell.
|
|
75
75
|
const loadedSlices = await Promise.all(
|
|
76
|
-
config.stateChangeSliceModules.map(async ({ spec,
|
|
76
|
+
config.stateChangeSliceModules.map(async ({ spec, decision }) => {
|
|
77
77
|
const specModule = await loadModule(spec);
|
|
78
|
-
const
|
|
79
|
-
return { patchedSpec: patchSpecId(specModule),
|
|
78
|
+
const decisionModule = await loadModule(decision);
|
|
79
|
+
return { patchedSpec: patchSpecId(specModule), decisionModule };
|
|
80
80
|
})
|
|
81
81
|
);
|
|
82
82
|
|
|
@@ -108,14 +108,14 @@ export async function buildHandlersForConfig(config, opts = {}) {
|
|
|
108
108
|
publishJson: async (_name, _meta, _json) => {},
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
loadedSlices.forEach(({ patchedSpec,
|
|
111
|
+
loadedSlices.forEach(({ patchedSpec, decisionModule }) => {
|
|
112
112
|
// Typed core: builds the slice callback (functor), the JSON→command decode,
|
|
113
113
|
// and the handleCommands invocation — all compiler-checked (was the fragile
|
|
114
114
|
// positional call this file's line-146 comment warned about; see the
|
|
115
115
|
// 2026-06-21 arity-drift incident referenced in the _Ops header).
|
|
116
116
|
const jsonHandler = buildSliceHandler(
|
|
117
117
|
patchedSpec,
|
|
118
|
-
|
|
118
|
+
decisionModule,
|
|
119
119
|
scope,
|
|
120
120
|
sharedDcbEventLogOps,
|
|
121
121
|
);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// The "typed core, thin shell" split (docs/plans/done/minimize-lambda-entrypoint-mjs-shell.md).
|
|
4
4
|
// The `.mjs` shell owns the one boundary that is inherently untyped: reading
|
|
5
|
-
// `HANDLER_CONFIG` and dynamically `import()`-ing user Spec/
|
|
5
|
+
// `HANDLER_CONFIG` and dynamically `import()`-ing user Spec/Decision modules at
|
|
6
6
|
// cold start, whose types are unknowable here. Everything below is compiler-
|
|
7
7
|
// checked against the *real* framework signatures, so the invariants that used
|
|
8
8
|
// to live only in `.mjs` comments are now enforced by the build:
|
|
@@ -165,18 +165,18 @@ let makeStorageOps = (
|
|
|
165
165
|
// (a labelled arg added before the positional ones shifts `stream` to
|
|
166
166
|
// undefined, crashing inside `Stream.mapEffect`). Moving the functor call, the
|
|
167
167
|
// JSON→command decode, and the `handleCommands` invocation here makes all three
|
|
168
|
-
// compiler-checked. The loaded Spec/
|
|
168
|
+
// compiler-checked. The loaded Spec/Decision modules enter opaque (a clean
|
|
169
169
|
// pass-through to the functor — not poked at); `dcbEventLog` enters as a
|
|
170
170
|
// boundary-typed parameter (the shell still builds it).
|
|
171
171
|
|
|
172
172
|
// The loaded slice's `command` type — opaque; flows from the decode straight
|
|
173
173
|
// into `handleCommands`, so decode and consume share one abstract type.
|
|
174
174
|
type command
|
|
175
|
-
type
|
|
175
|
+
type decisionModule
|
|
176
176
|
|
|
177
177
|
@get external specCommandSchemaTyped: specModule => S.t<command> = "commandSchema"
|
|
178
178
|
|
|
179
|
-
// `StateChangeSlice_Callback.Make(Spec)(
|
|
179
|
+
// `StateChangeSlice_Callback.Make(Spec)(Decision)` — curried in compiled form.
|
|
180
180
|
type sliceCallback = {
|
|
181
181
|
handleCommands: (
|
|
182
182
|
~tagKeysByEventType: dict<array<string>>=?,
|
|
@@ -195,7 +195,7 @@ type sliceCallback = {
|
|
|
195
195
|
@module(
|
|
196
196
|
"@reventlessdev/reventless-core/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs"
|
|
197
197
|
)
|
|
198
|
-
external makeSliceCallback: specModule =>
|
|
198
|
+
external makeSliceCallback: specModule => decisionModule => sliceCallback = "Make"
|
|
199
199
|
|
|
200
200
|
// Builds the per-slice JSON-command handler: decode each topic item's JSON
|
|
201
201
|
// command against the slice's schema (dropping undecodable ones), then dispatch
|
|
@@ -203,11 +203,11 @@ external makeSliceCallback: specModule => behaviorModule => sliceCallback = "Mak
|
|
|
203
203
|
// `Stream.t<topicItem<JSON>> => Effect` the shell's routing map keys on.
|
|
204
204
|
let buildSliceHandler = (
|
|
205
205
|
spec: specModule,
|
|
206
|
-
|
|
206
|
+
decision: decisionModule,
|
|
207
207
|
scope: derivedScope,
|
|
208
208
|
dcbEventLog: ReventlessInfra.DcbEventLog.operations,
|
|
209
209
|
) => {
|
|
210
|
-
let callback = makeSliceCallback(spec)(
|
|
210
|
+
let callback = makeSliceCallback(spec)(decision)
|
|
211
211
|
let commandSchema = spec->specCommandSchemaTyped
|
|
212
212
|
(jsonStream: Stream.t<ReventlessInfra.CommandTopic.topicItem<JSON.t>, string, unit>): Effect.t<
|
|
213
213
|
array<result<string, string>>,
|
|
@@ -94,8 +94,8 @@ function makeStorageOps(tableName, pgConnection, scope) {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
function buildSliceHandler(spec,
|
|
98
|
-
let callback = StateChangeSlice_CallbackResMjs.Make(spec)(
|
|
97
|
+
function buildSliceHandler(spec, decision, scope, dcbEventLog) {
|
|
98
|
+
let callback = StateChangeSlice_CallbackResMjs.Make(spec)(decision);
|
|
99
99
|
let commandSchema = spec.commandSchema;
|
|
100
100
|
return jsonStream => {
|
|
101
101
|
let decodedStream = Stream.flatMap(Stream.mapEffect(jsonStream, topicItem => Effect.sync(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Plugin EventCollector Lambda entry point — shared between the platform and every
|
|
2
|
-
// per-plugin EventCollector Lambda. This module is plugin-agnostic:
|
|
2
|
+
// per-plugin EventCollector Lambda. This module is plugin-agnostic: behavior is
|
|
3
3
|
// driven entirely by HANDLER_CONFIG.
|
|
4
4
|
//
|
|
5
5
|
// Thin untyped shell ("typed core, thin shell" —
|
|
@@ -18,7 +18,12 @@ let registerReadModel = (~readModelName, ~specModulePath, ~mappingsModulePath, ~
|
|
|
18
18
|
readModelInfos->Dict.set(readModelName, {specModulePath, mappingsModulePath, queryDbTableName})
|
|
19
19
|
|
|
20
20
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
21
|
-
ReventlessCore.Runtime.
|
|
21
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
22
|
+
EventCollectorChannel.callbackEvent,
|
|
23
|
+
context,
|
|
24
|
+
unit,
|
|
25
|
+
string,
|
|
26
|
+
>,
|
|
22
27
|
ReventlessCore.EventCollector.component,
|
|
23
28
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
24
29
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -66,7 +66,12 @@ let storedSpecs: array<storedSpec> = []
|
|
|
66
66
|
let grandParent = ref(None)
|
|
67
67
|
|
|
68
68
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
69
|
-
ReventlessCore.Runtime.
|
|
69
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
70
|
+
EventCollectorChannel.callbackEvent,
|
|
71
|
+
context,
|
|
72
|
+
unit,
|
|
73
|
+
string,
|
|
74
|
+
>,
|
|
70
75
|
ReventlessCore.EventCollector.component,
|
|
71
76
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
72
77
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -105,7 +105,7 @@ let makeFromCodeAsset: (
|
|
|
105
105
|
kind; `makeFromCodeAsset` announces the provisioned Lambda to the
|
|
106
106
|
`Monitoring` registry (no-op unless an extension registered a backend). */
|
|
107
107
|
~unitKind: ReventlessCore.Monitoring.unitKind,
|
|
108
|
-
/** The
|
|
108
|
+
/** The modeling kind of the component this Lambda runs, for resource
|
|
109
109
|
attribution (`reventless:kind`). Distinct from `~unitKind`, which grades
|
|
110
110
|
the unit by what its failure means — `CommandHandler` covers aggregates,
|
|
111
111
|
state-change slices and extension points alike, so it cannot identify the
|
|
@@ -251,7 +251,7 @@ let makeFromCodeAsset: (
|
|
|
251
251
|
// ESM self-containment (Option C): every code archive built by
|
|
252
252
|
// Util_Bundle.buildCodeArchive ships register-hook.mjs + layer-resolver.mjs at
|
|
253
253
|
// /var/task. --import registers the resolve hook so the ESM entry point (and the
|
|
254
|
-
// user spec/
|
|
254
|
+
// user spec/decision modules it dynamically imports) can resolve bare specifiers
|
|
255
255
|
// — @reventlessdev/*, effect, sury from the layer, @aws-sdk/* from the runtime —
|
|
256
256
|
// that ESM `import` would otherwise not find outside /var/task. Framework
|
|
257
257
|
// invariant: set last so it wins over any caller-supplied value.
|
|
@@ -447,9 +447,9 @@ let extractRetryCount = (event: event) =>
|
|
|
447
447
|
->Option.flatMap(attrs => attrs.approximateReceiveCount)
|
|
448
448
|
->Option.flatMap(Int.fromString(_))
|
|
449
449
|
|
|
450
|
-
external asEventHandler: 'a => ReventlessCore.Runtime.
|
|
450
|
+
external asEventHandler: 'a => ReventlessCore.Runtime.invocationHandler<event, context, 'result> =
|
|
451
451
|
"%identity"
|
|
452
|
-
external asEffectHandler: 'a => ReventlessCore.Runtime.
|
|
452
|
+
external asEffectHandler: 'a => ReventlessCore.Runtime.effectInvocationHandler<
|
|
453
453
|
event,
|
|
454
454
|
context,
|
|
455
455
|
'result,
|
|
@@ -21,7 +21,7 @@ let log = ReventlessCore.Logger.fromEnv()
|
|
|
21
21
|
extension is registered, which is the only reason a runtime skips the seam.
|
|
22
22
|
|
|
23
23
|
`modules` are npm specifiers resolvable under `/var/task/node_modules` — the
|
|
24
|
-
extension packages ride in the code archive alongside the spec and
|
|
24
|
+
extension packages ride in the code archive alongside the spec and decision
|
|
25
25
|
packages. The remaining fields are this runtime's identity, resolved at
|
|
26
26
|
provisioning time from the ambient `ResourceAttribution` context.
|
|
27
27
|
*/
|
|
@@ -88,7 +88,7 @@ Fire every loaded extension's `onColdStart`, in the order the deploy program
|
|
|
88
88
|
registered them, each isolated from the others (see
|
|
89
89
|
`ReventlessCore.RuntimeExtension`).
|
|
90
90
|
|
|
91
|
-
An
|
|
91
|
+
An unrecognized `runtimeKind` means the layer's `ComponentType` and the
|
|
92
92
|
deploy-time one disagree — a framework version skew, not anything an extension
|
|
93
93
|
can fix. Logged at ERROR and skipped rather than fired under a guessed kind: an
|
|
94
94
|
extension that routes on kind would otherwise attach to the wrong runtime
|
|
@@ -41,7 +41,12 @@ let storedSpecs: array<storedSpec> = []
|
|
|
41
41
|
let grandParent = ref(None)
|
|
42
42
|
|
|
43
43
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
44
|
-
ReventlessCore.Runtime.
|
|
44
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
45
|
+
EventCollectorChannel.callbackEvent,
|
|
46
|
+
context,
|
|
47
|
+
unit,
|
|
48
|
+
string,
|
|
49
|
+
>,
|
|
45
50
|
ReventlessCore.EventCollector.component,
|
|
46
51
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
47
52
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -27,7 +27,7 @@ type inboundSlicePaths = {
|
|
|
27
27
|
auditTableName: Pulumi.Output.t<string>,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// `slicePaths`: `(specPath,
|
|
30
|
+
// `slicePaths`: `(specPath, decisionPath)` per StateChangeSlice (already merged
|
|
31
31
|
// from auto- and manually-registered sources by the caller).
|
|
32
32
|
let forDcbCommandTopic = (
|
|
33
33
|
~slicePaths: array<(string, string)>,
|
|
@@ -124,9 +124,9 @@ let forDcbCommandTopic = (
|
|
|
124
124
|
envVars->Dict.set("LOG_LEVEL", level->Pulumi.Output.make->Pulumi.Output.asInput)
|
|
125
125
|
)
|
|
126
126
|
|
|
127
|
-
// The slice registry: an array of {spec,
|
|
127
|
+
// The slice registry: an array of {spec, decision} objects so the entry point
|
|
128
128
|
// can dynamically import both modules and apply the curried StateChangeSlice_Callback.Make
|
|
129
|
-
// functor (Make(Spec)(
|
|
129
|
+
// functor (Make(Spec)(Decision)).
|
|
130
130
|
//
|
|
131
131
|
// Shipped as a `sliceModules.json` asset rather than inline in HANDLER_CONFIG.
|
|
132
132
|
// Two absolute module specifiers per slice is the one term here that grows
|
|
@@ -136,10 +136,10 @@ let forDcbCommandTopic = (
|
|
|
136
136
|
// and it fails at deploy with the registry already committed to the stack.
|
|
137
137
|
let sliceModulesJson =
|
|
138
138
|
slicePaths
|
|
139
|
-
->Array.map(((specPath,
|
|
139
|
+
->Array.map(((specPath, decisionPath)) => {
|
|
140
140
|
let s = specPath->JSON.stringifyAny->Option.getOr(`""`)
|
|
141
|
-
let b =
|
|
142
|
-
`{"spec":${s},"
|
|
141
|
+
let b = decisionPath->JSON.stringifyAny->Option.getOr(`""`)
|
|
142
|
+
`{"spec":${s},"decision":${b}}`
|
|
143
143
|
})
|
|
144
144
|
->Array.join(",")
|
|
145
145
|
|
|
@@ -163,7 +163,7 @@ let forDcbCommandTopic = (
|
|
|
163
163
|
// InboundTranslationSlice modules — spec + translation paths and the resolved
|
|
164
164
|
// audit table name (Pulumi-generated, so it must be resolved here). Emitted as
|
|
165
165
|
// a `,"inboundTranslationSliceModules":[…]` fragment merged into HANDLER_CONFIG
|
|
166
|
-
// (absent → the entry point has no Route 0 registry, unchanged
|
|
166
|
+
// (absent → the entry point has no Route 0 registry, unchanged behavior).
|
|
167
167
|
let inboundFragment = switch inboundSlices {
|
|
168
168
|
| [] => Pulumi.Output.make("")
|
|
169
169
|
| slices =>
|
|
@@ -201,11 +201,11 @@ let forDcbCommandTopic = (
|
|
|
201
201
|
|
|
202
202
|
// Build code asset
|
|
203
203
|
let packageDirs: dict<string> = Dict.make()
|
|
204
|
-
slicePaths->Array.forEach(((specPath,
|
|
204
|
+
slicePaths->Array.forEach(((specPath, decisionPath)) => {
|
|
205
205
|
let specPkg = Util_Bundle.extractPackageName(specPath)
|
|
206
206
|
packageDirs->Dict.set(specPkg, Util_Bundle.resolvePackageRoot(specPkg))
|
|
207
|
-
let
|
|
208
|
-
packageDirs->Dict.set(
|
|
207
|
+
let decisionPkg = Util_Bundle.extractPackageName(decisionPath)
|
|
208
|
+
packageDirs->Dict.set(decisionPkg, Util_Bundle.resolvePackageRoot(decisionPkg))
|
|
209
209
|
})
|
|
210
210
|
// Inbound slice spec + translation packages the entry point imports for Route 0.
|
|
211
211
|
inboundSlices->Array.forEach(s => {
|
|
@@ -67,7 +67,7 @@ function forDcbCommandTopic(slicePaths, inboundSlicesOpt, dcbTableName, pluginNa
|
|
|
67
67
|
let sliceModulesJson = slicePaths.map(param => {
|
|
68
68
|
let s = Stdlib_Option.getOr(JSON.stringify(param[0]), `""`);
|
|
69
69
|
let b = Stdlib_Option.getOr(JSON.stringify(param[1]), `""`);
|
|
70
|
-
return `{"spec":` + s + `,"
|
|
70
|
+
return `{"spec":` + s + `,"decision":` + b + `}`;
|
|
71
71
|
}).join(",");
|
|
72
72
|
let pgConnectionFragment = pgSelection !== undefined ? pgSelection.connectionConfig.apply(cc => `,"pgConnection":` + JSON.stringify(PgConnection$ReventlessAws.connectionConfigToJson(pgSelection.lockStrategy, cc))) : Pulumi.output("");
|
|
73
73
|
let inboundFragment = inboundSlices.length !== 0 ? Pulumi.all(inboundSlices.map(s => s.auditTableName)).apply(tableNames => {
|
|
@@ -96,8 +96,8 @@ function forDcbCommandTopic(slicePaths, inboundSlicesOpt, dcbTableName, pluginNa
|
|
|
96
96
|
slicePaths.forEach(param => {
|
|
97
97
|
let specPkg = Util_Bundle$ReventlessAws.extractPackageName(param[0]);
|
|
98
98
|
packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, specPkg);
|
|
99
|
-
let
|
|
100
|
-
packageDirs[
|
|
99
|
+
let decisionPkg = Util_Bundle$ReventlessAws.extractPackageName(param[1]);
|
|
100
|
+
packageDirs[decisionPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(undefined, decisionPkg);
|
|
101
101
|
});
|
|
102
102
|
inboundSlices.forEach(s => {
|
|
103
103
|
let specPkg = Util_Bundle$ReventlessAws.extractPackageName(s.specPath);
|
|
@@ -93,7 +93,12 @@ let storedSpecs: array<storedSpec> = []
|
|
|
93
93
|
let grandParent = ref(None)
|
|
94
94
|
|
|
95
95
|
let forEventCollector: ReventlessCore.Runtime.forEventCollector<
|
|
96
|
-
ReventlessCore.Runtime.
|
|
96
|
+
ReventlessCore.Runtime.effectInvocationHandler<
|
|
97
|
+
EventCollectorChannel.callbackEvent,
|
|
98
|
+
context,
|
|
99
|
+
unit,
|
|
100
|
+
string,
|
|
101
|
+
>,
|
|
97
102
|
ReventlessCore.EventCollector.component,
|
|
98
103
|
> = (~handler as _, ~eventTopics, ~resources, ~memorySize=1024, ~timeout=30, eventCollector) => {
|
|
99
104
|
let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
//
|
|
11
11
|
// Channel layout: /default/{topicName}/{pathSegment(entityKey)}
|
|
12
12
|
// topicName = plugin-prefixed query LIST field name (e.g. "Catalog-Products").
|
|
13
|
-
// MUST match the AutoUI manifest's
|
|
13
|
+
// MUST match the AutoUI manifest's readSideDef.queryField,
|
|
14
14
|
// which the host-shell's AutoLive subscribes on. Using the
|
|
15
15
|
// singular return type here would orphan the channel.
|
|
16
16
|
// entityKey = the table's primary-key value(s) extracted from record.Keys.
|
|
@@ -388,7 +388,7 @@ let finish = (~eventsApi: AppSync_EventsApi.t, ~opts: Pulumi.CustomResourceOptio
|
|
|
388
388
|
// One EventSourceMapping per stream, all targeting the shared Lambda.
|
|
389
389
|
// Retry posture: the handler throws on 5xx / network errors and logs-and-
|
|
390
390
|
// continues on 4xx. `maximumRetryAttempts: 3` bounds the per-record
|
|
391
|
-
// retries so a permanently broken record (default DDB stream
|
|
391
|
+
// retries so a permanently broken record (default DDB stream behavior is
|
|
392
392
|
// -1 → forever, which would wedge the shard); `bisectBatchOnFunctionError`
|
|
393
393
|
// isolates the bad record across those retries instead of redelivering
|
|
394
394
|
// the whole batch each time.
|
|
@@ -36,7 +36,7 @@ let smsSenderKey = "messagingSmsSender"
|
|
|
36
36
|
Blank matters because the ways to write "nothing" must not differ: a stray
|
|
37
37
|
`REVENTLESS_MESSAGING_EMAIL_SENDER=` in CI, a blank line in
|
|
38
38
|
`Pulumi.local.yaml`, and a key left with a space after the colon all mean the
|
|
39
|
-
stack named no sender.
|
|
39
|
+
stack named no sender. Honoring any of them would ask SES for an identity
|
|
40
40
|
with a blank address — a deploy failure whose cause is whitespace, and one
|
|
41
41
|
that reaches AWS before anything here explains it.
|
|
42
42
|
|
|
@@ -69,7 +69,7 @@ Which transport this stack asked for. SES is the default, so a deployment that
|
|
|
69
69
|
says nothing gets the real one — the safe direction is that mail works, and a
|
|
70
70
|
stack opting out of sending says so explicitly.
|
|
71
71
|
|
|
72
|
-
An
|
|
72
|
+
An unrecognized value is refused rather than defaulted. Falling back to SES on a
|
|
73
73
|
typo would provision a real identity for a stack that asked to only log, which
|
|
74
74
|
is the one mistake this key exists to prevent.
|
|
75
75
|
*/
|
|
@@ -11,7 +11,7 @@ module type MappingsConfig = {
|
|
|
11
11
|
|
|
12
12
|
module Make = (
|
|
13
13
|
Spec: Reventless.Aggregate.Spec,
|
|
14
|
-
|
|
14
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
15
15
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
16
16
|
MappingsConfig: MappingsConfig,
|
|
17
17
|
): (
|
|
@@ -21,7 +21,7 @@ module Make = (
|
|
|
21
21
|
) => {
|
|
22
22
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
23
23
|
Spec,
|
|
24
|
-
|
|
24
|
+
Decision,
|
|
25
25
|
EventMappings,
|
|
26
26
|
RuntimeEnvironment,
|
|
27
27
|
CommandGeneratorResolvers,
|
|
@@ -49,7 +49,7 @@ module Make = (
|
|
|
49
49
|
AggregateRuntimeBuilder.registerAggregate(
|
|
50
50
|
~aggregateName=Spec.name,
|
|
51
51
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
52
|
-
~
|
|
52
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
53
53
|
~eventLogTableName,
|
|
54
54
|
~mappingsModulePath=?MappingsConfig.mappingsModulePath,
|
|
55
55
|
)
|
|
@@ -12,8 +12,8 @@ import * as EventTopicPublisher_DynamoDbStream$ReventlessAws from "../adapter/Ev
|
|
|
12
12
|
import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
|
|
13
13
|
|
|
14
14
|
function Make(Spec) {
|
|
15
|
-
return
|
|
16
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
15
|
+
return Decision => (EventMappings => (MappingsConfig => {
|
|
16
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
17
17
|
mappings: EventMappings.mappings,
|
|
18
18
|
counter: EventMappings.counter
|
|
19
19
|
})({
|
|
@@ -48,7 +48,7 @@ function Make(Spec) {
|
|
|
48
48
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
49
49
|
let tableResource = eventLogOutputs.resources[0];
|
|
50
50
|
let eventLogTableName = tableResource.name;
|
|
51
|
-
AggregateRuntime_Builder_Micro$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
51
|
+
AggregateRuntime_Builder_Micro$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName, MappingsConfig.mappingsModulePath);
|
|
52
52
|
return aggregate;
|
|
53
53
|
};
|
|
54
54
|
let finish = () => AggregateRuntime_Builder_Micro$ReventlessAws.finish();
|
|
@@ -11,7 +11,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_Single
|
|
|
11
11
|
|
|
12
12
|
module Make = (
|
|
13
13
|
Spec: Reventless.Aggregate.Spec,
|
|
14
|
-
|
|
14
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
15
15
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
16
16
|
): (
|
|
17
17
|
ReventlessInfra.Aggregate.T
|
|
@@ -20,7 +20,7 @@ module Make = (
|
|
|
20
20
|
) => {
|
|
21
21
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
22
22
|
Spec,
|
|
23
|
-
|
|
23
|
+
Decision,
|
|
24
24
|
EventMappings,
|
|
25
25
|
RuntimeEnvironment,
|
|
26
26
|
CommandGeneratorResolvers,
|
|
@@ -48,7 +48,7 @@ module Make = (
|
|
|
48
48
|
AggregateRuntimeBuilder.registerAggregate(
|
|
49
49
|
~aggregateName=Spec.name,
|
|
50
50
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
51
|
-
~
|
|
51
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
52
52
|
~eventLogTableName,
|
|
53
53
|
)
|
|
54
54
|
|
|
@@ -12,8 +12,8 @@ import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../adapter/
|
|
|
12
12
|
import * as CommandGeneratorResolvers_AppSync_NoOp$ReventlessAws from "../adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res.mjs";
|
|
13
13
|
|
|
14
14
|
function Make(Spec) {
|
|
15
|
-
return
|
|
16
|
-
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(
|
|
15
|
+
return Decision => (EventMappings => {
|
|
16
|
+
let Inner = Aggregate_Builder$ReventlessCore.Make(Spec)(Decision)({
|
|
17
17
|
mappings: EventMappings.mappings,
|
|
18
18
|
counter: EventMappings.counter
|
|
19
19
|
})({
|
|
@@ -48,7 +48,7 @@ function Make(Spec) {
|
|
|
48
48
|
let eventLogOutputs = Inner.outputs(aggregate).eventLog;
|
|
49
49
|
let tableResource = eventLogOutputs.resources[0];
|
|
50
50
|
let eventLogTableName = tableResource.name;
|
|
51
|
-
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(
|
|
51
|
+
AggregateRuntime_Builder_Single$ReventlessAws.registerAggregate(Spec.name, Util_Bundle$ReventlessAws.getModuleSpecifier(Spec.moduleUrl), Util_Bundle$ReventlessAws.getModuleSpecifier(Decision.moduleUrl), eventLogTableName);
|
|
52
52
|
return aggregate;
|
|
53
53
|
};
|
|
54
54
|
let finish = () => AggregateRuntime_Builder_Single$ReventlessAws.finish();
|
|
@@ -7,7 +7,7 @@ module AggregateRuntimeBuilder = AggregateRuntime_Builder_PerAggregate
|
|
|
7
7
|
|
|
8
8
|
module Make = (
|
|
9
9
|
Spec: Reventless.Aggregate.Spec,
|
|
10
|
-
|
|
10
|
+
Decision: Reventless.Decision.T with module Spec := Spec,
|
|
11
11
|
EventMappings: ReventlessInfra.EventMapper.Mappings with module Target := Spec,
|
|
12
12
|
): (
|
|
13
13
|
ReventlessInfra.Aggregate.T
|
|
@@ -16,7 +16,7 @@ module Make = (
|
|
|
16
16
|
) => {
|
|
17
17
|
module Inner = ReventlessCore.Aggregate_Builder.Make(
|
|
18
18
|
Spec,
|
|
19
|
-
|
|
19
|
+
Decision,
|
|
20
20
|
EventMappings,
|
|
21
21
|
RuntimeEnvironment,
|
|
22
22
|
CommandGeneratorResolvers,
|
|
@@ -44,7 +44,7 @@ module Make = (
|
|
|
44
44
|
AggregateRuntimeBuilder.registerAggregate(
|
|
45
45
|
~aggregateName=Spec.name,
|
|
46
46
|
~specModulePath=Util_Bundle.getModuleSpecifier(Spec.moduleUrl),
|
|
47
|
-
~
|
|
47
|
+
~decisionModulePath=Util_Bundle.getModuleSpecifier(Decision.moduleUrl),
|
|
48
48
|
~eventLogTableName,
|
|
49
49
|
)
|
|
50
50
|
|