@reventlessdev/reventless-core 3.0.0-alpha.169 → 3.0.0-alpha.170

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 (44) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/package.json +14 -14
  3. package/src/admin/Platform_Admin.res +5 -2
  4. package/src/admin/Platform_Admin.res.mjs +4 -4
  5. package/src/components/Aggregate/Aggregate.res +5 -1
  6. package/src/components/Aggregate/Aggregate_Builder.res +21 -6
  7. package/src/components/Aggregate/Aggregate_Builder.res.mjs +10 -7
  8. package/src/components/AutomationSlice/AutomationSlice.res +1 -0
  9. package/src/components/AutomationSlice/AutomationSlice_Builder.res +13 -2
  10. package/src/components/AutomationSlice/AutomationSlice_Builder.res.mjs +5 -2
  11. package/src/components/Builder_Helpers.res +16 -2
  12. package/src/components/Builder_Helpers.res.mjs +6 -6
  13. package/src/components/Dcb/Dcb_Builder.res +46 -4
  14. package/src/components/Dcb/Dcb_Builder.res.mjs +13 -9
  15. package/src/components/ExtensionPoint/ExtensionPoint.res +2 -0
  16. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +7 -0
  17. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res.mjs +4 -2
  18. package/src/components/InboundTranslationSlice/InboundTranslationSlice.res +1 -0
  19. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +8 -1
  20. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res.mjs +1 -1
  21. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res +1 -0
  22. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +12 -3
  23. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res.mjs +5 -2
  24. package/src/components/ReadModel/ReadModel.res +1 -0
  25. package/src/components/ReadModel/ReadModel_Builder.res +9 -1
  26. package/src/components/ReadModel/ReadModel_Builder.res.mjs +5 -2
  27. package/src/components/StateChangeSlice/StateChangeSlice.res +1 -0
  28. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +6 -0
  29. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res.mjs +1 -1
  30. package/src/components/StateViewSlice/StateViewSlice.res +1 -0
  31. package/src/components/StateViewSlice/StateViewSlice_Builder.res +11 -3
  32. package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +5 -2
  33. package/src/components/Task/Task.res +1 -0
  34. package/src/components/Task/Task_Builder.res +9 -2
  35. package/src/components/Task/Task_Builder.res.mjs +5 -2
  36. package/src/plugin/component/Plugin.res +5 -0
  37. package/src/plugin/component/Plugin_Builder.res +10 -2
  38. package/src/plugin/component/Plugin_Builder.res.mjs +7 -6
  39. package/src/plugin/component/Plugin_Helpers.res +2 -0
  40. package/src/plugin/component/Plugin_Helpers.res.mjs +2 -2
  41. package/tests/plugin/ManifestVisibilityTest.res +2 -2
  42. package/tests/plugin/ManifestVisibilityTest.res.mjs +2 -2
  43. package/tests/plugin/PluginStructureTest.res +6 -6
  44. package/tests/plugin/PluginStructureTest.res.mjs +6 -6
@@ -16,6 +16,7 @@ import * as Component$ReventlessCore from "../Component.res.mjs";
16
16
  import * as DcbValidation$Reventless from "@reventlessdev/reventless-spec/src/components/DcbValidation.res.mjs";
17
17
  import * as Api_Naming$ReventlessCore from "../Api/Api_Naming.res.mjs";
18
18
  import * as DcbScopeInference$Reventless from "@reventlessdev/reventless-spec/src/components/DcbScopeInference.res.mjs";
19
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
19
20
  import * as Plugin_Helpers$ReventlessCore from "../../plugin/component/Plugin_Helpers.res.mjs";
20
21
  import * as ApiNoApiHelpers$ReventlessCore from "../Api/ApiNoApiHelpers.res.mjs";
21
22
  import * as Plugin_Structure$ReventlessCore from "../../plugin/component/Plugin_Structure.res.mjs";
@@ -81,13 +82,14 @@ let emptyResult = {
81
82
 
82
83
  function Make(DcbEventLogStorage) {
83
84
  return DcbEventTopicPublisher => (DcbCommandTopicChannel => (DcbCommandTopicChannelAsync => (RuntimeBuilder => (HooksConfig => {
84
- let construct = (name, childName, apiNamePrefixOpt, onAdminApiOpt, environmentOpt, platformNameOpt, aggregateEventTopicsOpt, stateChangeSlices, stateViewSlices, automationSlices, outboundTranslationSlices, inboundTranslationSlices, systemCallableComponentsOpt, pluginStructure, opts) => {
85
+ let construct = (name, childName, apiNamePrefixOpt, onAdminApiOpt, environmentOpt, platformNameOpt, aggregateEventTopicsOpt, stateChangeSlices, stateViewSlices, automationSlices, outboundTranslationSlices, inboundTranslationSlices, systemCallableComponentsOpt, componentRuntimeOpt, pluginStructure, opts) => {
85
86
  let apiNamePrefix = apiNamePrefixOpt !== undefined ? apiNamePrefixOpt : name;
86
87
  let onAdminApi = onAdminApiOpt !== undefined ? onAdminApiOpt : false;
87
88
  let environment = environmentOpt !== undefined ? environmentOpt : "";
88
89
  let platformName = platformNameOpt !== undefined ? platformNameOpt : "";
89
90
  let aggregateEventTopics = aggregateEventTopicsOpt !== undefined ? aggregateEventTopicsOpt : ({});
90
91
  let systemCallableComponents = systemCallableComponentsOpt !== undefined ? systemCallableComponentsOpt : [];
92
+ let componentRuntime = componentRuntimeOpt !== undefined ? componentRuntimeOpt : ({});
91
93
  let hasDcb = stateChangeSlices.length !== 0;
92
94
  if (!hasDcb) {
93
95
  return emptyResult;
@@ -206,7 +208,7 @@ function Make(DcbEventLogStorage) {
206
208
  asyncDcbCommandTopicOpt = undefined;
207
209
  }
208
210
  let stateChangeSlicesOutputs = Object.fromEntries(syncSlices.map(StateChangeSlice => {
209
- let ch = StateChangeSlice.make(dcbEventLog, publishJsons, effectiveTagKeysByEventType, effectiveCrossPartitionTagKeys, opts);
211
+ let ch = StateChangeSlice.make(dcbEventLog, publishJsons, effectiveTagKeysByEventType, effectiveCrossPartitionTagKeys, componentRuntime[StateChangeSlice.Spec.name], opts);
210
212
  return [
211
213
  StateChangeSlice.Spec.name,
212
214
  Component$ReventlessCore.outputs(ch)
@@ -216,7 +218,7 @@ function Make(DcbEventLogStorage) {
216
218
  if (asyncDcbCommandTopicOpt !== undefined) {
217
219
  let asyncPublishJsons = Component$ReventlessCore.operations(Primitive_option.valFromOption(asyncDcbCommandTopicOpt)).apply(ops => ops.publishJsons);
218
220
  asyncStateChangeSlicesOutputs = Object.fromEntries(asyncSlices.map(StateChangeSlice => {
219
- let ch = StateChangeSlice.make(dcbEventLog, asyncPublishJsons, effectiveTagKeysByEventType, effectiveCrossPartitionTagKeys, opts);
221
+ let ch = StateChangeSlice.make(dcbEventLog, asyncPublishJsons, effectiveTagKeysByEventType, effectiveCrossPartitionTagKeys, componentRuntime[StateChangeSlice.Spec.name], opts);
220
222
  return [
221
223
  StateChangeSlice.Spec.name,
222
224
  Component$ReventlessCore.outputs(ch)
@@ -297,7 +299,7 @@ function Make(DcbEventLogStorage) {
297
299
  Plugin_Helpers$ReventlessCore.queryFieldNamesRegistry[I.queryDbName] = qn;
298
300
  });
299
301
  let stateViewSlicesOutputs = Object.fromEntries(stateViewSlices.map(StateViewSlice => {
300
- let sv = StateViewSlice.make(dcbEventLog, opts);
302
+ let sv = StateViewSlice.make(dcbEventLog, componentRuntime[StateViewSlice.Spec.name], opts);
301
303
  return [
302
304
  StateViewSlice.Spec.name,
303
305
  Component$ReventlessCore.outputs(sv)
@@ -313,21 +315,21 @@ function Make(DcbEventLogStorage) {
313
315
  pluginName: name,
314
316
  sliceName: context_sliceName
315
317
  };
316
- let as_ = AutoSlice.make(allEventTopics, publishJsons, context, opts);
318
+ let as_ = AutoSlice.make(allEventTopics, publishJsons, context, componentRuntime[AutoSlice.Spec.name], opts);
317
319
  return [
318
320
  AutoSlice.Spec.name,
319
321
  Component$ReventlessCore.outputs(as_)
320
322
  ];
321
323
  }));
322
324
  let outboundTranslationSlicesOutputs = Object.fromEntries(outboundTranslationSlices.map(OTS => {
323
- let ots = OTS.make(dcbEventLog, publishJsons, opts);
325
+ let ots = OTS.make(dcbEventLog, publishJsons, componentRuntime[OTS.Spec.name], opts);
324
326
  return [
325
327
  OTS.Spec.name,
326
328
  Component$ReventlessCore.outputs(ots)
327
329
  ];
328
330
  }));
329
331
  let inboundTranslationSliceData = inboundTranslationSlices.map(ITS => {
330
- let its = ITS.make(publishJsons, opts);
332
+ let its = ITS.make(publishJsons, componentRuntime[ITS.Spec.name], opts);
331
333
  let fieldName = Api_Naming$ReventlessCore.sliceMutationField(name, ITS.Spec.name);
332
334
  let registerResolver = HooksConfig.hooks.inboundMutationResolverHook;
333
335
  if (registerResolver !== undefined) {
@@ -435,12 +437,14 @@ function Make(DcbEventLogStorage) {
435
437
  }
436
438
  };
437
439
  Stdlib_Option.forEach(HooksConfig.hooks.onDcbSlicesCreated, hook => hook(dcbEventLog));
440
+ let sliceMemoryFloor = slices => Stdlib_Array.reduce(slices, 0, (acc, M) => Math.max(acc, RuntimeHints$ReventlessInfra.resolveMemory(componentRuntime[M.Spec.name], 0)));
441
+ let sliceTimeoutFloor = slices => Stdlib_Array.reduce(slices, 0, (acc, M) => Math.max(acc, RuntimeHints$ReventlessInfra.resolveTimeout(componentRuntime[M.Spec.name], 0)));
438
442
  let dcbRuntimeSetup = () => {
439
- RuntimeBuilder.forDcbCommandTopic(dcbHandler, dcbConnectFn, undefined, undefined, dcbCommandTopic);
443
+ RuntimeBuilder.forDcbCommandTopic(dcbHandler, dcbConnectFn, sliceMemoryFloor(syncSlices), sliceTimeoutFloor(syncSlices), dcbCommandTopic);
440
444
  Stdlib_Option.forEach(asyncDcbCommandTopicOpt, asyncDcbCommandTopic => {
441
445
  let asyncDcbHandler = DcbAsyncCommandTopic.makeFilteringHandler(asyncDcbCommandTopic);
442
446
  let asyncDcbConnectFn = runtime => DcbAsyncCommandTopic.connect(runtime, asyncDcbResources, asyncDcbCommandTopic);
443
- RuntimeBuilder.forDcbCommandTopic(asyncDcbHandler, asyncDcbConnectFn, undefined, undefined, asyncDcbCommandTopic);
447
+ RuntimeBuilder.forDcbCommandTopic(asyncDcbHandler, asyncDcbConnectFn, sliceMemoryFloor(asyncSlices), sliceTimeoutFloor(asyncSlices), asyncDcbCommandTopic);
444
448
  });
445
449
  };
446
450
  let permissionForFirstConstructor = (commandSchema, commandAuthorization) => {
@@ -11,12 +11,14 @@ module type T = {
11
11
  type operations = operations
12
12
  type component = component<operations>
13
13
 
14
+ let name: string
14
15
  let make: (
15
16
  ~aggregateResources: dict<array<ReventlessInfra.Adapter.resource>>,
16
17
  ~publishToAggregates: dict<CommandTopic.publishJsons>,
17
18
  ~scheduler: Scheduler.operations,
18
19
  ~queryEngine: Reventless.QueryEngine.operations,
19
20
  ~resourceNaming: ReventlessInfra.ResourceNaming.operations,
21
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
20
22
  ~opts: option<Pulumi.ComponentResource.options>,
21
23
  ) => component
22
24
  let outputs: component => outputs
@@ -13,6 +13,8 @@ module Make = (
13
13
  type operations = ExtensionPoint.operations
14
14
  type component = ExtensionPoint.component<operations>
15
15
 
16
+ let name = Spec.name
17
+
16
18
  module SpecWithId: Reventless.ExtensionPoint.Spec
17
19
  with type command = Spec.command
18
20
  and type event = Spec.event
@@ -36,6 +38,7 @@ module Make = (
36
38
  ~scheduler: Scheduler.operations,
37
39
  ~queryEngine: Reventless.QueryEngine.operations,
38
40
  ~resourceNaming: ReventlessInfra.ResourceNaming.operations,
41
+ ~runtime: option<ReventlessInfra.RuntimeHints.t>,
39
42
  self,
40
43
  name,
41
44
  ) => {
@@ -89,6 +92,8 @@ module Make = (
89
92
  commandTopic->ExtensionPointRuntimeBuilder.forCommandTopic(
90
93
  ~handler,
91
94
  ~connect=SpecificCommandTopic.connect(commandTopic, ~resources, ...),
95
+ ~memorySize=runtime->ReventlessInfra.RuntimeHints.resolveMemory(~default=1024),
96
+ ~timeout=runtime->ReventlessInfra.RuntimeHints.resolveTimeout(~default=30),
92
97
  ~specModulePath=Spec.moduleUrl,
93
98
  ~mappingsModulePath=Mappings.moduleUrl,
94
99
  ~publishToAggregatesQueueUrls,
@@ -142,6 +147,7 @@ module Make = (
142
147
  ~scheduler,
143
148
  ~queryEngine,
144
149
  ~resourceNaming,
150
+ ~runtime=?,
145
151
  ~opts,
146
152
  ) =>
147
153
  Component.make(
@@ -153,6 +159,7 @@ module Make = (
153
159
  ~scheduler,
154
160
  ~queryEngine,
155
161
  ~resourceNaming,
162
+ ~runtime,
156
163
  ...
157
164
  ),
158
165
  ~opts,
@@ -9,6 +9,7 @@ import * as Pulumi from "@pulumi/pulumi";
9
9
  import * as Adapter$ReventlessCore from "../../adapter/Adapter.res.mjs";
10
10
  import * as Component$ReventlessCore from "../Component.res.mjs";
11
11
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
12
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
12
13
  import * as ExtensionPoint$ReventlessCore from "./ExtensionPoint.res.mjs";
13
14
  import * as EventTopic_Builder$ReventlessCore from "../EventTopic/EventTopic_Builder.res.mjs";
14
15
  import * as CommandTopic_Builder$ReventlessCore from "../CommandTopic/CommandTopic_Builder.res.mjs";
@@ -24,7 +25,7 @@ function Make(Spec) {
24
25
  let name = param[0];
25
26
  return aggregateNames.some(aggregateName => aggregateName === name);
26
27
  }).map(param => param[1]).flat();
27
- let make = (aggregateResources, publishToAggregates, scheduler, queryEngine, resourceNaming, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(ExtensionPoint$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
28
+ let make = (aggregateResources, publishToAggregates, scheduler, queryEngine, resourceNaming, runtime, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(ExtensionPoint$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
28
29
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
29
30
  let opts = {
30
31
  parent: opts_parent
@@ -58,7 +59,7 @@ function Make(Spec) {
58
59
  return Pulumi.output("");
59
60
  }
60
61
  });
61
- ExtensionPointRuntimeBuilder.forCommandTopic(handler, none => SpecificCommandTopic.connect(none, resources, commandTopic), undefined, undefined, Spec.moduleUrl, Mappings.moduleUrl, publishToAggregatesQueueUrls, commandTopic);
62
+ ExtensionPointRuntimeBuilder.forCommandTopic(handler, none => SpecificCommandTopic.connect(none, resources, commandTopic), RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024), RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30), Spec.moduleUrl, Mappings.moduleUrl, publishToAggregatesQueueUrls, commandTopic);
62
63
  let SpecificEventTopic = EventTopic_Builder$ReventlessCore.Make({
63
64
  Id: Id$Reventless.$$String,
64
65
  name: name,
@@ -100,6 +101,7 @@ function Make(Spec) {
100
101
  return Component$ReventlessCore.setOutputs(extra, epOutputs);
101
102
  }, opts);
102
103
  return {
104
+ name: Spec.name,
103
105
  make: make,
104
106
  outputs: Component$ReventlessCore.outputs,
105
107
  operations: Component$ReventlessCore.operations
@@ -29,6 +29,7 @@ module type T = {
29
29
 
30
30
  let make: (
31
31
  ~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
32
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
32
33
  ~opts: Pulumi.ComponentResource.options=?,
33
34
  ) => component
34
35
  }
@@ -87,7 +87,14 @@ module Make = (
87
87
  self->Component.setOutputs(outputs)
88
88
  }
89
89
 
90
- let make = (~publishJsons, ~opts=?): InboundTranslationSlice.component =>
90
+ // InboundTranslationSlice publishes commands + syncs its QueryDb inline; it
91
+ // provisions no per-slice runtime environment, so the runtime hint is accepted
92
+ // (for composition-surface parity) and discarded.
93
+ let make = (
94
+ ~publishJsons,
95
+ ~runtime as _=?,
96
+ ~opts=?,
97
+ ): InboundTranslationSlice.component =>
91
98
  Component.make(
92
99
  ~componentType=InboundTranslationSlice.componentType->ComponentType.toString,
93
100
  ~name=Spec.name,
@@ -34,7 +34,7 @@ function Make(QueryDbStorage) {
34
34
  await queryDbOps.save(Id$Reventless.$$String.makeFromString(param[0]), param[1], "Overwrite", undefined);
35
35
  });
36
36
  };
37
- let make = (publishJsons, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(InboundTranslationSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
37
+ let make = (publishJsons, param, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(InboundTranslationSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
38
38
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
39
39
  let opts = {
40
40
  parent: opts_parent
@@ -30,6 +30,7 @@ module type T = {
30
30
  let make: (
31
31
  ~dcbEventLog: DcbEventLog.component,
32
32
  ~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
33
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
33
34
  ~opts: Pulumi.ComponentResource.options=?,
34
35
  ) => component
35
36
  }
@@ -67,8 +67,10 @@ module Make = (
67
67
  })
68
68
  }
69
69
 
70
- let construct = (~dcbEventLog: DcbEventLog.component, ~publishJsons, self, _name) => {
70
+ let construct = (~dcbEventLog: DcbEventLog.component, ~publishJsons, ~runtime, self, _name) => {
71
71
  let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
72
+ let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=1024)
73
+ let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=30)
72
74
 
73
75
  let queryDb = SpecificQueryDb.make(~api=Api.api(), ~apiRole=Api.apiRole(), ~opts)
74
76
 
@@ -147,6 +149,8 @@ module Make = (
147
149
  ~handler,
148
150
  ~eventTopics=allEventTopics,
149
151
  ~resources,
152
+ ~memorySize,
153
+ ~timeout,
150
154
  )
151
155
  ec
152
156
  })
@@ -170,11 +174,16 @@ module Make = (
170
174
  self->Component.setOutputs(outputs)
171
175
  }
172
176
 
173
- let make = (~dcbEventLog, ~publishJsons, ~opts=?): OutboundTranslationSlice.component =>
177
+ let make = (
178
+ ~dcbEventLog,
179
+ ~publishJsons,
180
+ ~runtime=?,
181
+ ~opts=?,
182
+ ): OutboundTranslationSlice.component =>
174
183
  Component.make(
175
184
  ~componentType=OutboundTranslationSlice.componentType->ComponentType.toString,
176
185
  ~name=Spec.name,
177
- ~construct=construct(~dcbEventLog, ~publishJsons, ...),
186
+ ~construct=construct(~dcbEventLog, ~publishJsons, ~runtime, ...),
178
187
  ~opts,
179
188
  )
180
189
  }
@@ -18,6 +18,7 @@ import * as Message$ReventlessCore from "../../Message.res.mjs";
18
18
  import * as Component$ReventlessCore from "../Component.res.mjs";
19
19
  import * as EffectLogger$ReventlessCore from "../../util/EffectLogger.res.mjs";
20
20
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
21
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
21
22
  import * as QueryDb_Builder$ReventlessCore from "../QueryDb/QueryDb_Builder.res.mjs";
22
23
  import * as EventCollector_Builder$ReventlessCore from "../EventCollector/EventCollector_Builder.res.mjs";
23
24
  import * as OutboundTranslationSlice$ReventlessCore from "./OutboundTranslationSlice.res.mjs";
@@ -51,11 +52,13 @@ function Make(RuntimeEnvironment) {
51
52
  await queryDbOps.save(Id$Reventless.$$String.makeFromString(param[0]), param[1], "Overwrite", undefined);
52
53
  });
53
54
  };
54
- let make = (dcbEventLog, publishJsons, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(OutboundTranslationSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
55
+ let make = (dcbEventLog, publishJsons, runtime, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(OutboundTranslationSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
55
56
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
56
57
  let opts = {
57
58
  parent: opts_parent
58
59
  };
60
+ let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024);
61
+ let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30);
59
62
  let queryDb = SpecificQueryDb.make(Api.api(), Api.apiRole(), undefined, opts);
60
63
  let dcbEventTopicOutputs = Component$ReventlessCore.outputs(dcbEventLog).eventTopic;
61
64
  let allEventTopics = Object.fromEntries([[
@@ -95,7 +98,7 @@ function Make(RuntimeEnvironment) {
95
98
  }));
96
99
  let handler = SpecificEventCollector.makeHandler(ec, jsonEventsHandler);
97
100
  let resources = Component$ReventlessCore.outputs(queryDb).resources;
98
- EventCollectorRuntimeBuilder.forEventCollector(handler, allEventTopics, resources, undefined, undefined, ec);
101
+ EventCollectorRuntimeBuilder.forEventCollector(handler, allEventTopics, resources, memorySize, timeout, ec);
99
102
  return ec;
100
103
  });
101
104
  Component$ReventlessCore.setOperations(extra, Pulumi.all([
@@ -16,6 +16,7 @@ module type T = {
16
16
  ~api: api,
17
17
  ~apiRole: role,
18
18
  ~allEventTopics: EventTopic.allOutputs,
19
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
19
20
  ~opts: Pulumi.ComponentResource.options=?,
20
21
  ) => component
21
22
  let sourceNames: array<string>
@@ -46,11 +46,16 @@ module Make = (
46
46
  ~api: QueryDbStorage.api,
47
47
  ~apiRole: QueryDbStorage.role,
48
48
  ~allEventTopics,
49
+ ~runtime,
49
50
  self,
50
51
  name,
51
52
  ) => {
52
53
  let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
53
54
  let name = name->ComponentType.name(ReadModel.componentType)
55
+ // Per-component runtime hint raises the event-collector memory floor and
56
+ // overrides the timeout; absent hint keeps the builder defaults.
57
+ let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=1024)
58
+ let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=30)
54
59
 
55
60
  module SpecificQueryDb = QueryDb_Builder.Make(Spec, QueryDbStorage, QueryDbResolvers)
56
61
  let queryDb = SpecificQueryDb.make(~api, ~apiRole, ~opts)
@@ -129,6 +134,8 @@ module Make = (
129
134
  ~handler,
130
135
  ~eventTopics,
131
136
  ~resources,
137
+ ~memorySize,
138
+ ~timeout,
132
139
  )
133
140
 
134
141
  eventCollector
@@ -152,12 +159,13 @@ module Make = (
152
159
  ~api: QueryDbStorage.api,
153
160
  ~apiRole: QueryDbStorage.role,
154
161
  ~allEventTopics,
162
+ ~runtime=?,
155
163
  ~opts=?,
156
164
  ): ReadModel.component =>
157
165
  Component.make(
158
166
  ~componentType=ReadModel.componentType->ComponentType.toString,
159
167
  ~name=Spec.name,
160
- ~construct=construct(~api, ~apiRole, ~allEventTopics, ...),
168
+ ~construct=construct(~api, ~apiRole, ~allEventTopics, ~runtime, ...),
161
169
  ~opts,
162
170
  )
163
171
 
@@ -9,6 +9,7 @@ import * as Component$ReventlessCore from "../Component.res.mjs";
9
9
  import * as ReadModel$ReventlessCore from "./ReadModel.res.mjs";
10
10
  import * as EventTopic$ReventlessCore from "../EventTopic/EventTopic.res.mjs";
11
11
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
12
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
12
13
  import * as QueryDb_Builder$ReventlessCore from "../QueryDb/QueryDb_Builder.res.mjs";
13
14
  import * as ReadModel_Callback$ReventlessCore from "./ReadModel_Callback.res.mjs";
14
15
  import * as EventCollector_Builder$ReventlessCore from "../EventCollector/EventCollector_Builder.res.mjs";
@@ -17,12 +18,14 @@ function Make(Spec) {
17
18
  return Mappings => (RuntimeEnvironment => (QueryDbStorage => (QueryDbResolvers => (EventCollectorChannel => (EventCollectorRuntimeBuilder => {
18
19
  let sourceNames = Belt_SetString.toArray(Belt_SetString.fromArray(Mappings.mappings.map(Mapping => Mapping.sourceName)));
19
20
  let consumedEventNames = Belt_SetString.toArray(Belt_SetString.fromArray(Mappings.mappings.flatMap(Mapping => DcbTag$Reventless.extractVariantNames(Mapping.sourceEventSchema))));
20
- let make = (api, apiRole, allEventTopics, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(ReadModel$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
21
+ let make = (api, apiRole, allEventTopics, runtime, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(ReadModel$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
21
22
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
22
23
  let opts = {
23
24
  parent: opts_parent
24
25
  };
25
26
  let name = ComponentType$ReventlessCore.name(extra$1, ReadModel$ReventlessCore.componentType);
27
+ let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024);
28
+ let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30);
26
29
  let SpecificQueryDb = QueryDb_Builder$ReventlessCore.Make(Spec)(QueryDbStorage)(QueryDbResolvers);
27
30
  let queryDb = SpecificQueryDb.make(api, apiRole, undefined, opts);
28
31
  let toProjectionOperations = param => {
@@ -69,7 +72,7 @@ function Make(Spec) {
69
72
  });
70
73
  let handler = SpecificEventCollector.makeHandler(eventCollector, Callback.handleJsonEvents);
71
74
  let resources = Component$ReventlessCore.outputs(queryDb).resources;
72
- EventCollectorRuntimeBuilder.forEventCollector(handler, eventTopics, resources, undefined, undefined, eventCollector);
75
+ EventCollectorRuntimeBuilder.forEventCollector(handler, eventTopics, resources, memorySize, timeout, eventCollector);
73
76
  return eventCollector;
74
77
  });
75
78
  Component$ReventlessCore.setOperations(extra, Output$Pulumi.flatMap(eventCollector, Component$ReventlessCore.operations).apply(param => param.enqueueEvent));
@@ -33,6 +33,7 @@ module type T = {
33
33
  clause (instead of an AND-ed composite) so the decision read is a real
34
34
  secondary-tag read. */
35
35
  ~crossPartitionTagKeys: array<string>=?,
36
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
36
37
  ~opts: Pulumi.ComponentResource.options=?,
37
38
  ) => component
38
39
  }
@@ -75,11 +75,17 @@ module Make = (
75
75
  self->Component.setOutputs(outputs)
76
76
  }
77
77
 
78
+ // A StateChangeSlice registers its handler on the plugin's shared DCB command
79
+ // topic Lambda, so it has no per-slice runtime environment. The per-component
80
+ // hint is folded into that shared Lambda's size in the plugin/DCB runtime
81
+ // builder (keyed by `Spec.name` from `componentRuntime`), not here — so the
82
+ // slice builder accepts the hint for composition-surface parity and discards it.
78
83
  let make = (
79
84
  ~dcbEventLog,
80
85
  ~publishJsons,
81
86
  ~tagKeysByEventType=Dict.make(),
82
87
  ~crossPartitionTagKeys=[],
88
+ ~runtime as _=?,
83
89
  ~opts=?,
84
90
  ): StateChangeSlice.component =>
85
91
  Component.make(
@@ -46,7 +46,7 @@ function Make(Spec) {
46
46
  });
47
47
  return Callback.handleCommands(tagKeysByEventType, crossPartitionTagKeys, dcbEventLogOps, decodedStream);
48
48
  });
49
- let make = (dcbEventLog, publishJsons, tagKeysByEventTypeOpt, crossPartitionTagKeysOpt, opts) => {
49
+ let make = (dcbEventLog, publishJsons, tagKeysByEventTypeOpt, crossPartitionTagKeysOpt, param, opts) => {
50
50
  let tagKeysByEventType = tagKeysByEventTypeOpt !== undefined ? tagKeysByEventTypeOpt : ({});
51
51
  let crossPartitionTagKeys = crossPartitionTagKeysOpt !== undefined ? crossPartitionTagKeysOpt : [];
52
52
  return Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(StateChangeSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
@@ -28,6 +28,7 @@ module type T = {
28
28
 
29
29
  let make: (
30
30
  ~dcbEventLog: DcbEventLog.component,
31
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
31
32
  ~opts: Pulumi.ComponentResource.options=?,
32
33
  ) => component
33
34
  }
@@ -58,8 +58,10 @@ module Make = (
58
58
 
59
59
  let decoder = Reventless.DcbDecode.makeDecoder(Spec.consumedEventSchema)
60
60
 
61
- let construct = (~dcbEventLog: DcbEventLog.component, self, _name) => {
61
+ let construct = (~dcbEventLog: DcbEventLog.component, ~runtime, self, _name) => {
62
62
  let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
63
+ let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=1024)
64
+ let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=30)
63
65
 
64
66
  let queryDb = SpecificQueryDb.make(~api=Api.api(), ~apiRole=Api.apiRole(), ~opts)
65
67
 
@@ -145,6 +147,8 @@ module Make = (
145
147
  ~handler,
146
148
  ~eventTopics=allEventTopics,
147
149
  ~resources,
150
+ ~memorySize,
151
+ ~timeout,
148
152
  )
149
153
  ec
150
154
  })
@@ -165,11 +169,15 @@ module Make = (
165
169
  self->Component.setOutputs(outputs)
166
170
  }
167
171
 
168
- let make = (~dcbEventLog, ~opts=?): StateViewSlice.component =>
172
+ let make = (
173
+ ~dcbEventLog,
174
+ ~runtime=?,
175
+ ~opts=?,
176
+ ): StateViewSlice.component =>
169
177
  Component.make(
170
178
  ~componentType=StateViewSlice.componentType->ComponentType.toString,
171
179
  ~name=Spec.name,
172
- ~construct=construct(~dcbEventLog, ...),
180
+ ~construct=construct(~dcbEventLog, ~runtime, ...),
173
181
  ~opts,
174
182
  )
175
183
  }
@@ -17,6 +17,7 @@ import * as LogFormat$ReventlessCore from "../../util/LogFormat.res.mjs";
17
17
  import * as Projection$ReventlessCore from "../../Projection.res.mjs";
18
18
  import * as EffectLogger$ReventlessCore from "../../util/EffectLogger.res.mjs";
19
19
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
20
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
20
21
  import * as StateViewSlice$ReventlessCore from "./StateViewSlice.res.mjs";
21
22
  import * as QueryDb_Builder$ReventlessCore from "../QueryDb/QueryDb_Builder.res.mjs";
22
23
  import * as EventCollector_Builder$ReventlessCore from "../EventCollector/EventCollector_Builder.res.mjs";
@@ -53,11 +54,13 @@ function Make(RuntimeEnvironment) {
53
54
  ]))
54
55
  });
55
56
  let decoder = DcbDecode$Reventless.makeDecoder(Spec.consumedEventSchema);
56
- let make = (dcbEventLog, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(StateViewSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
57
+ let make = (dcbEventLog, runtime, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(StateViewSlice$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
57
58
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
58
59
  let opts = {
59
60
  parent: opts_parent
60
61
  };
62
+ let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 1024);
63
+ let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 30);
61
64
  let queryDb = SpecificQueryDb.make(Api.api(), Api.apiRole(), undefined, opts);
62
65
  let dcbEventTopicOutputs = Component$ReventlessCore.outputs(dcbEventLog).eventTopic;
63
66
  let allEventTopics = Object.fromEntries([[
@@ -98,7 +101,7 @@ function Make(RuntimeEnvironment) {
98
101
  });
99
102
  let handler = SpecificEventCollector.makeHandler(ec, jsonEventsHandler);
100
103
  let resources = Component$ReventlessCore.outputs(queryDb).resources;
101
- EventCollectorRuntimeBuilder.forEventCollector(handler, allEventTopics, resources, undefined, undefined, ec);
104
+ EventCollectorRuntimeBuilder.forEventCollector(handler, allEventTopics, resources, memorySize, timeout, ec);
102
105
  return ec;
103
106
  });
104
107
  Component$ReventlessCore.setOperations(extra, Output$Pulumi.flatMap(eventCollector, Component$ReventlessCore.operations).apply(param => ({
@@ -30,6 +30,7 @@ type maker = (
30
30
  ~queryEngine: Reventless.QueryEngine.operations,
31
31
  ~resourceNaming: ReventlessInfra.ResourceNaming.operations,
32
32
  ~allAggregates: dict<Aggregate.outputs>,
33
+ ~runtime: ReventlessInfra.RuntimeHints.t=?,
33
34
  ~opts: option<Pulumi.ComponentResource.options>,
34
35
  ) => component
35
36
 
@@ -45,10 +45,15 @@ module Make = (
45
45
  ~queryEngine,
46
46
  ~resourceNaming: ReventlessInfra.ResourceNaming.operations,
47
47
  ~allAggregates,
48
+ ~runtime,
48
49
  self,
49
50
  taskName,
50
51
  ) => {
51
52
  let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
53
+ // Task bucket callbacks default to a large envelope (bulk import/export work);
54
+ // a plugin.json `runtime` override raises memory above it and replaces timeout.
55
+ let memorySize = ReventlessInfra.RuntimeHints.resolveMemory(runtime, ~default=4096)
56
+ let timeout = ReventlessInfra.RuntimeHints.resolveTimeout(runtime, ~default=600)
52
57
  let allCommandTopics = allAggregates->Aggregate.allCommandTopics
53
58
 
54
59
  // Each adapter chooses what string the Task runtime should treat as the
@@ -171,8 +176,8 @@ module Make = (
171
176
  ~opts,
172
177
  ...
173
178
  ),
174
- ~memorySize=4096,
175
- ~timeout=600,
179
+ ~memorySize,
180
+ ~timeout,
176
181
  ~name=bucketStem,
177
182
  ~callbackModulePath=Spec.moduleUrl,
178
183
  ~publishToAggregatesQueueUrls,
@@ -201,6 +206,7 @@ module Make = (
201
206
  ~queryEngine,
202
207
  ~resourceNaming,
203
208
  ~allAggregates,
209
+ ~runtime=?,
204
210
  ~opts,
205
211
  ) =>
206
212
  Component.make(
@@ -214,6 +220,7 @@ module Make = (
214
220
  ~queryEngine,
215
221
  ~resourceNaming,
216
222
  ~allAggregates,
223
+ ~runtime,
217
224
  ...
218
225
  ),
219
226
  ~opts,
@@ -11,6 +11,7 @@ import * as Aggregate$ReventlessCore from "../Aggregate/Aggregate.res.mjs";
11
11
  import * as Component$ReventlessCore from "../Component.res.mjs";
12
12
  import * as Util_Promise$ReventlessCore from "../../util/Util_Promise.res.mjs";
13
13
  import * as ComponentType$ReventlessCore from "../../ComponentType.res.mjs";
14
+ import * as RuntimeHints$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/RuntimeHints.res.mjs";
14
15
 
15
16
  let log = Logger$ReventlessCore.fromEnv();
16
17
 
@@ -20,11 +21,13 @@ function pascalCase(s) {
20
21
 
21
22
  function Make(Spec) {
22
23
  return RuntimeEnvironment => (EventCollectorChannel => (EventCollectorRuntimeBuilder => (TaskRuntimeBuilder => (TaskBucket => (SpecificSideEffectHandler => {
23
- let make = (queryBucketName, scheduler, schedulerRoleUrn, publishToAggregates, queryEngine, resourceNaming, allAggregates, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(Task$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
24
+ let make = (queryBucketName, scheduler, schedulerRoleUrn, publishToAggregates, queryEngine, resourceNaming, allAggregates, runtime, opts) => Component$ReventlessCore.make(ComponentType$ReventlessCore.toString(Task$ReventlessCore.componentType), Spec.name, (extra, extra$1) => {
24
25
  let opts_parent = Component$ReventlessCore.toPulumiResource(extra);
25
26
  let opts = {
26
27
  parent: opts_parent
27
28
  };
29
+ let memorySize = RuntimeHints$ReventlessInfra.resolveMemory(runtime, 4096);
30
+ let timeout = RuntimeHints$ReventlessInfra.resolveTimeout(runtime, 600);
28
31
  let allCommandTopics = Aggregate$ReventlessCore.allCommandTopics(allAggregates);
29
32
  let publishToAggregatesQueueUrls = Stdlib_Dict.mapValues(allAggregates, agg => Output$Pulumi.flatMap(agg.commandTopic, ct => {
30
33
  let r = ct.resources[0];
@@ -86,7 +89,7 @@ function Make(Spec) {
86
89
  let opts$1 = {
87
90
  parent: opts_parent
88
91
  };
89
- Stdlib_Option.forEach(bucketSpec.callback, callback => TaskRuntimeBuilder.forBucketCallback(createHandler(sideEffectHandler, callback), none => TaskBucket.connect(name, bucket, bucketSpec.bucketMode, allCommandTopics, none, opts$1), 4096, 600, bucketStem, Spec.moduleUrl, publishToAggregatesQueueUrls, schedulerConfig, extra));
92
+ Stdlib_Option.forEach(bucketSpec.callback, callback => TaskRuntimeBuilder.forBucketCallback(createHandler(sideEffectHandler, callback), none => TaskBucket.connect(name, bucket, bucketSpec.bucketMode, allCommandTopics, none, opts$1), memorySize, timeout, bucketStem, Spec.moduleUrl, publishToAggregatesQueueUrls, schedulerConfig, extra));
90
93
  return [
91
94
  bucketName,
92
95
  bucket.resources[0].id
@@ -24,6 +24,11 @@ module type T = {
24
24
  ~outboundTranslationSlices: array<module(ReventlessInfra.OutboundTranslationSlice.T)>=?,
25
25
  ~inboundTranslationSlices: array<module(ReventlessInfra.InboundTranslationSlice.T)>=?,
26
26
  ~systemCallableComponents: array<string>=?,
27
+ /** Per-component runtime resource hints keyed by component name (plugin.json
28
+ `runtime` block). Looked up per component by `Spec.name` and forwarded into
29
+ the component's `make`. See
30
+ docs/plans/configurable-component-runtime-resources.md. */
31
+ ~componentRuntime: dict<ReventlessInfra.RuntimeHints.t>=?,
27
32
  ~uiFragments: Reventless.Plugin.uiFragmentManifest=?,
28
33
  ~pluginStructure: Reventless.Plugin.pluginStructure=?,
29
34
  ~opts: Pulumi.ComponentResource.options=?,