@reventlessdev/reventless-infra 3.0.0-alpha.100 → 3.0.0-alpha.101

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 CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 3.0.0-alpha.101 (2026-07-16)
7
+
8
+ ### Features
9
+
10
+ * **aws:** consume per-component runtime hints; fold into shared command Lambdas ([7ba2485](https://github.com/ReventlessDev/reventless-core/commit/7ba248579f2472f2fc847b26033927199353f3e6))
11
+ * **core:** honor per-component runtime hints for ExtensionPoints ([72d0218](https://github.com/ReventlessDev/reventless-core/commit/72d0218ec4f73d6a59230640c9ee4a538e6b8688))
12
+ * **core:** thread per-component runtime hints from plugin.json (spec/infra/core/local) ([a94f419](https://github.com/ReventlessDev/reventless-core/commit/a94f4199c4ac7eeeb24dd0a71d58fb73c1e514e6))
13
+
14
+
6
15
  # 3.0.0-alpha.100 (2026-07-15)
7
16
 
8
17
  **Note:** Version bump only for package @reventlessdev/reventless-infra
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-infra",
3
- "version": "3.0.0-alpha.100",
3
+ "version": "3.0.0-alpha.101",
4
4
  "description": "Infrastructure types for Reventless framework",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -16,17 +16,17 @@
16
16
  "sury": "11.0.0-alpha.4",
17
17
  "sury-ppx": "11.0.0-alpha.2",
18
18
  "uuid": "^13.0.0",
19
- "@reventlessdev/rescript-effect": "0.1.0-alpha.27",
20
- "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.15",
21
- "@reventlessdev/rescript-uuid": "1.1.0-alpha.15",
22
- "@reventlessdev/reventless-spec": "3.0.0-alpha.77"
19
+ "@reventlessdev/rescript-uuid": "1.1.0-alpha.16",
20
+ "@reventlessdev/rescript-effect": "0.1.0-alpha.28",
21
+ "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.16",
22
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.78"
23
23
  },
24
24
  "devDependencies": {
25
- "rescript": "^12.3.0",
26
- "@reventlessdev/rescript-jest": "1.0.0-alpha.7"
25
+ "rescript": "12.3.0",
26
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.8"
27
27
  },
28
28
  "peerDependencies": {
29
- "rescript": "^12.3.0"
29
+ "rescript": "12.3.0"
30
30
  },
31
31
  "publishConfig": {
32
32
  "registry": "https://registry.npmjs.org"
@@ -65,7 +65,11 @@ module type T = {
65
65
  module Spec: Reventless.Aggregate.Spec
66
66
  type api
67
67
  type component
68
- let make: (~api: api, ~opts: Pulumi.ComponentResource.options=?) => component
68
+ let make: (
69
+ ~api: api,
70
+ ~runtime: RuntimeHints.t=?,
71
+ ~opts: Pulumi.ComponentResource.options=?,
72
+ ) => component
69
73
  let outputs: component => outputs
70
74
  let operations: component => Pulumi.Output.t<operations>
71
75
  /** Signal that all event mappers have been attached; finalises the aggregate. */
@@ -43,6 +43,7 @@ module type T = {
43
43
  ~allEventTopics: EventTopic.allOutputs,
44
44
  ~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
45
45
  ~context: Reventless.AutomationSlice.context,
46
+ ~runtime: RuntimeHints.t=?,
46
47
  ~opts: Pulumi.ComponentResource.options=?,
47
48
  ) => component
48
49
  }
@@ -49,12 +49,17 @@ the `reventless` package.
49
49
  module type T = {
50
50
  type operations
51
51
  type component
52
+ /** The extension point's logical name — the key its `plugin.json` runtime
53
+ hint is looked up by at the `Builder_Helpers.createExtensionPoints` site,
54
+ before `make` is called. */
55
+ let name: string
52
56
  let make: (
53
57
  ~aggregateResources: dict<array<Adapter.resource>>,
54
58
  ~publishToAggregates: dict<CommandTopic.publishJsons>,
55
59
  ~scheduler: Scheduler.operations,
56
60
  ~queryEngine: Reventless.QueryEngine.operations,
57
61
  ~resourceNaming: ResourceNaming.operations,
62
+ ~runtime: RuntimeHints.t=?,
58
63
  ~opts: option<Pulumi.ComponentResource.options>,
59
64
  ) => component
60
65
  let outputs: component => outputs
@@ -36,6 +36,7 @@ module type T = {
36
36
  let queryDbName: string
37
37
  let make: (
38
38
  ~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
39
+ ~runtime: RuntimeHints.t=?,
39
40
  ~opts: Pulumi.ComponentResource.options=?,
40
41
  ) => component
41
42
  }
@@ -39,6 +39,7 @@ module type T = {
39
39
  let make: (
40
40
  ~dcbEventLog: DcbEventLog.component,
41
41
  ~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
42
+ ~runtime: RuntimeHints.t=?,
42
43
  ~opts: Pulumi.ComponentResource.options=?,
43
44
  ) => component
44
45
  }
@@ -66,6 +66,12 @@ module type T = {
66
66
  `@@reventless.systemCallable` on the spec file and threaded here by the
67
67
  plugin generator; see `docs/guides/appsync-iam-system-caller.md`. */
68
68
  ~systemCallableComponents: array<string>=?,
69
+ /** Per-component runtime resource hints keyed by component name, authored in
70
+ the plugin's `plugin.json` `runtime` block and emitted by the plugin
71
+ generator. The deploy loop looks up each component's hint by `Spec.name`
72
+ and forwards it into that component's `make`. See
73
+ docs/plans/configurable-component-runtime-resources.md. */
74
+ ~componentRuntime: dict<RuntimeHints.t>=?,
69
75
  ~uiFragments: Reventless.Plugin.uiFragmentManifest=?,
70
76
  ~pluginStructure: Reventless.Plugin.pluginStructure=?,
71
77
  ~opts: Pulumi.ComponentResource.options=?,
@@ -47,6 +47,7 @@ module type T = {
47
47
  ~api: api,
48
48
  ~apiRole: role,
49
49
  ~allEventTopics: EventTopic.allOutputs,
50
+ ~runtime: RuntimeHints.t=?,
50
51
  ~opts: Pulumi.ComponentResource.options=?,
51
52
  ) => component
52
53
  let outputs: component => outputs
@@ -40,6 +40,7 @@ module type T = {
40
40
  a cross-partition scalar command tag fans out into its own single-tag
41
41
  decision-read clause. */
42
42
  ~crossPartitionTagKeys: array<string>=?,
43
+ ~runtime: RuntimeHints.t=?,
43
44
  ~opts: Pulumi.ComponentResource.options=?,
44
45
  ) => component
45
46
  }
@@ -33,6 +33,7 @@ module type T = {
33
33
  type component = Component.t<t, outputs, operations>
34
34
  let make: (
35
35
  ~dcbEventLog: DcbEventLog.component,
36
+ ~runtime: RuntimeHints.t=?,
36
37
  ~opts: Pulumi.ComponentResource.options=?,
37
38
  ) => component
38
39
  }
@@ -83,6 +83,7 @@ module type T = {
83
83
  ~queryEngine: Reventless.QueryEngine.operations,
84
84
  ~resourceNaming: ResourceNaming.operations,
85
85
  ~allAggregates: dict<Aggregate.outputs>,
86
+ ~runtime: RuntimeHints.t=?,
86
87
  ~opts: option<Pulumi.ComponentResource.options>,
87
88
  ) => component
88
89
  let outputs: component => outputs
@@ -0,0 +1,41 @@
1
+ /**
2
+ Per-component runtime resource hints, declared once (portably) on the plugin's
3
+ composition surface (`plugin.json` `runtime` block) and threaded into each
4
+ component's `make` by the plugin deploy loop.
5
+
6
+ Both fields are optional; an omitted field falls through to the per-kind builder
7
+ default. The value is a *logical envelope* (working-set memory / wall-clock),
8
+ not a literal cap — each platform adapter maps it to its own resource model
9
+ (AWS Lambda `memorySize`/`timeout`, k8s pod `requests`/`limits`, local ignores).
10
+
11
+ See docs/plans/configurable-component-runtime-resources.md.
12
+ */
13
+ type t = {
14
+ memorySize: option<int>,
15
+ timeout: option<int>,
16
+ }
17
+
18
+ /** No hints — every field falls through to the per-kind builder default. */
19
+ let empty: t = {memorySize: None, timeout: None}
20
+
21
+ /**
22
+ Resolve a component's memory floor: the per-component override raises the
23
+ per-kind default, never lowers it (`Math.Int.max`). An absent override yields
24
+ the default unchanged.
25
+ */
26
+ let resolveMemory = (hints: option<t>, ~default: int): int =>
27
+ switch hints {
28
+ | Some({memorySize: Some(m)}) => Math.Int.max(default, m)
29
+ | _ => default
30
+ }
31
+
32
+ /**
33
+ Resolve a component's timeout: an explicit per-component timeout replaces the
34
+ default (no `max` — a longer default is not inherently safer). An absent
35
+ override yields the default unchanged.
36
+ */
37
+ let resolveTimeout = (hints: option<t>, ~default: int): int =>
38
+ switch hints {
39
+ | Some({timeout: Some(t)}) => t
40
+ | _ => default
41
+ }
@@ -0,0 +1,38 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+
4
+ function resolveMemory(hints, $$default) {
5
+ if (hints === undefined) {
6
+ return $$default;
7
+ }
8
+ let m = hints.memorySize;
9
+ if (m !== undefined) {
10
+ return Math.max($$default, m);
11
+ } else {
12
+ return $$default;
13
+ }
14
+ }
15
+
16
+ function resolveTimeout(hints, $$default) {
17
+ if (hints === undefined) {
18
+ return $$default;
19
+ }
20
+ let t = hints.timeout;
21
+ if (t !== undefined) {
22
+ return t;
23
+ } else {
24
+ return $$default;
25
+ }
26
+ }
27
+
28
+ let empty = {
29
+ memorySize: undefined,
30
+ timeout: undefined
31
+ };
32
+
33
+ export {
34
+ empty,
35
+ resolveMemory,
36
+ resolveTimeout,
37
+ }
38
+ /* No side effect */
@@ -0,0 +1,32 @@
1
+ open JestGlobals
2
+
3
+ module RH = RuntimeHints
4
+
5
+ // Precedence for per-component runtime hints (see
6
+ // docs/plans/configurable-component-runtime-resources.md): memory is a floor
7
+ // (override raises the per-kind default via Math.Int.max, never lowers it),
8
+ // timeout is a replace (an explicit value wins outright).
9
+
10
+ describe("RuntimeHints.resolveMemory", () => {
11
+ testSync("no hint falls through to the per-kind default", () => {
12
+ expect(RH.resolveMemory(None, ~default=1024))->toBe(1024)
13
+ })
14
+ testSync("an override above the default wins", () => {
15
+ expect(RH.resolveMemory(Some({memorySize: Some(2048), timeout: None}), ~default=1024))->toBe(2048)
16
+ })
17
+ testSync("an override below the default is clamped up to the floor", () => {
18
+ expect(RH.resolveMemory(Some({memorySize: Some(256), timeout: None}), ~default=1024))->toBe(1024)
19
+ })
20
+ testSync("an absent memorySize field falls through to the default", () => {
21
+ expect(RH.resolveMemory(Some({memorySize: None, timeout: Some(60)}), ~default=1024))->toBe(1024)
22
+ })
23
+ })
24
+
25
+ describe("RuntimeHints.resolveTimeout", () => {
26
+ testSync("an explicit timeout replaces the default (no max)", () => {
27
+ expect(RH.resolveTimeout(Some({memorySize: None, timeout: Some(15)}), ~default=30))->toBe(15)
28
+ })
29
+ testSync("no hint falls through to the default", () => {
30
+ expect(RH.resolveTimeout(None, ~default=30))->toBe(30)
31
+ })
32
+ })
@@ -0,0 +1,46 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as RuntimeHints$ReventlessInfra from "../src/types/RuntimeHints.res.mjs";
4
+
5
+ globalThis.describe("RuntimeHints.resolveMemory", () => {
6
+ globalThis.test("no hint falls through to the per-kind default", () => {
7
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveMemory(undefined, 1024)).toBe(1024);
8
+ });
9
+ globalThis.test("an override above the default wins", () => {
10
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveMemory({
11
+ memorySize: 2048,
12
+ timeout: undefined
13
+ }, 1024)).toBe(2048);
14
+ });
15
+ globalThis.test("an override below the default is clamped up to the floor", () => {
16
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveMemory({
17
+ memorySize: 256,
18
+ timeout: undefined
19
+ }, 1024)).toBe(1024);
20
+ });
21
+ globalThis.test("an absent memorySize field falls through to the default", () => {
22
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveMemory({
23
+ memorySize: undefined,
24
+ timeout: 60
25
+ }, 1024)).toBe(1024);
26
+ });
27
+ });
28
+
29
+ globalThis.describe("RuntimeHints.resolveTimeout", () => {
30
+ globalThis.test("an explicit timeout replaces the default (no max)", () => {
31
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveTimeout({
32
+ memorySize: undefined,
33
+ timeout: 15
34
+ }, 30)).toBe(15);
35
+ });
36
+ globalThis.test("no hint falls through to the default", () => {
37
+ globalThis.expect(RuntimeHints$ReventlessInfra.resolveTimeout(undefined, 30)).toBe(30);
38
+ });
39
+ });
40
+
41
+ let RH;
42
+
43
+ export {
44
+ RH,
45
+ }
46
+ /* Not a pure module */