@reventlessdev/reventless-local 3.0.0-alpha.129 → 3.0.0-alpha.131

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,20 @@
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.131 (2026-07-08)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **reventless-core:** composite DCB slices can read back their own events ([4604a91](https://github.com/ReventlessDev/reventless-core/commit/4604a9159fb8bf59b2191ad69fee6613c7f75cd9))
11
+
12
+
13
+ # 3.0.0-alpha.130 (2026-07-08)
14
+
15
+ ### Features
16
+
17
+ * **reventless-core:** classify plugins by kind in the lifecycle read model ([64e3f22](https://github.com/ReventlessDev/reventless-core/commit/64e3f22b8114a771886b7c8ec023e95971413c0b))
18
+
19
+
6
20
  # 3.0.0-alpha.129 (2026-07-08)
7
21
 
8
22
  **Note:** Version bump only for package @reventlessdev/reventless-local
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-local",
3
- "version": "3.0.0-alpha.129",
3
+ "version": "3.0.0-alpha.131",
4
4
  "description": "Local platform for Reventless (in-memory or SQLite backend, for development and testing without AWS)",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -32,15 +32,15 @@
32
32
  "sury": "11.0.0-alpha.4",
33
33
  "ws": "^8.18.0",
34
34
  "@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.18",
35
- "@reventlessdev/rescript-effect": "0.1.0-alpha.25",
36
35
  "@reventlessdev/rescript-jest": "1.0.0-alpha.6",
37
- "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
36
+ "@reventlessdev/rescript-effect": "0.1.0-alpha.25",
38
37
  "@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.17",
39
- "@reventlessdev/reventless-core": "3.0.0-alpha.145",
40
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.90",
41
- "@reventlessdev/reventless-postgres": "3.0.0-alpha.9",
42
- "@reventlessdev/reventless-spec": "3.0.0-alpha.68",
43
- "@reventlessdev/reventless-infra": "3.0.0-alpha.90"
38
+ "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
39
+ "@reventlessdev/reventless-core": "3.0.0-alpha.147",
40
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.92",
41
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.91",
42
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.69",
43
+ "@reventlessdev/reventless-postgres": "3.0.0-alpha.11"
44
44
  },
45
45
  "devDependencies": {
46
46
  "rescript": "^12.3.0",
package/src/Platform.res CHANGED
@@ -1018,6 +1018,7 @@ module MakeWithConfig = (
1018
1018
  uiFragments,
1019
1019
  structure: pluginStructure,
1020
1020
  dcbEventLog: None,
1021
+ kind: Domain,
1021
1022
  }
1022
1023
  // Dispatch Connect(def) to the Plugin aggregate (id = plugin NAME).
1023
1024
  let _ = dispatchPluginCommand(
@@ -879,7 +879,8 @@ function MakeWithConfig(Config) {
879
879
  apiTarget: undefined,
880
880
  uiFragments: param[6],
881
881
  structure: param[7],
882
- dcbEventLog: undefined
882
+ dcbEventLog: undefined,
883
+ kind: "Domain"
883
884
  };
884
885
  dispatchPluginCommand(pluginName, {
885
886
  TAG: "Connect",
@@ -2505,7 +2506,8 @@ function Make($star) {
2505
2506
  apiTarget: undefined,
2506
2507
  uiFragments: param[6],
2507
2508
  structure: param[7],
2508
- dcbEventLog: undefined
2509
+ dcbEventLog: undefined,
2510
+ kind: "Domain"
2509
2511
  };
2510
2512
  dispatchPluginCommand(pluginName, {
2511
2513
  TAG: "Connect",
@@ -54,7 +54,7 @@ let bridgeSourceA = (
54
54
  let ps = getPubSub()
55
55
  let yogaTopic = sourceATopic(displayName)
56
56
  // Push the raw event JSON directly — it already contains the event data.
57
- // In-memory events don't carry a separate position/originatorSlice envelope.
57
+ // In-memory events don't carry a separate position envelope.
58
58
  subscribeToEvents(busTopicName, async (_service, _meta, json) => {
59
59
  ps->YG.pubSubPublish(yogaTopic, json)
60
60
  })
@@ -761,3 +761,26 @@ describe("GraphQL_SchemaInspector", () => {
761
761
  })
762
762
  })
763
763
  })
764
+
765
+ // ── Plugin admin fragment: kind enum + connection filter (A1) ────────────────
766
+ // Regression guard for the plugin-kind segregation surface: the Plugin lifecycle
767
+ // read model carries `kind: pluginKind`, so the generated admin fragment must
768
+ // expose it as a real GraphQL enum on Platform_Plugin, and the `@scan` opt-in on
769
+ // the field must fold a `kindEq` equality filter into Platform_PluginFilter so the
770
+ // admin console can page the main list vs the System/Infrastructure panel
771
+ // server-side.
772
+ describe("Plugin admin fragment — kind enum + kindEq filter", () => {
773
+ testPromise("Platform_Plugin exposes a PluginKind enum and Platform_Plugins gains kindEq", async () => {
774
+ let fragment = ReventlessCore.GraphQL_FragmentGenerator.generate(
775
+ ~mutationEntries=[],
776
+ ~queryEntries=ReventlessCore.PluginBaseFragment.queryEntries,
777
+ )
778
+ let sdl = ReventlessCore.GraphQL_SchemaInspector.inspectFragment(fragment).sdlPreview
779
+ // kind is a real enum on the Plugin type (auto-derived from the payload-less variant)
780
+ expect(sdl->String.includes("enum Platform_PluginKind"))->toBe(true)
781
+ expect(sdl->String.includes("PlatformInfrastructure"))->toBe(true)
782
+ expect(sdl->String.includes("kind: Platform_PluginKind!"))->toBe(true)
783
+ // @scan folds a server-side equality filter for the panel split
784
+ expect(sdl->String.includes("kindEq: String"))->toBe(true)
785
+ })
786
+ })
@@ -7,6 +7,7 @@ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
7
7
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
8
8
  import * as GraphQL_Server$ReventlessLocal from "../../src/adapter/GraphQL_Server.res.mjs";
9
9
  import * as GraphQL_Stitcher$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_Stitcher.res.mjs";
10
+ import * as PluginBaseFragment$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/api/PluginBaseFragment.res.mjs";
10
11
  import * as GraphQL_SchemaInspector$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_SchemaInspector.res.mjs";
11
12
  import * as GraphQL_FragmentGenerator$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_FragmentGenerator.res.mjs";
12
13
 
@@ -550,6 +551,17 @@ globalThis.describe("GraphQL_SchemaInspector", () => {
550
551
  });
551
552
  });
552
553
 
554
+ globalThis.describe("Plugin admin fragment — kind enum + kindEq filter", () => {
555
+ globalThis.test("Platform_Plugin exposes a PluginKind enum and Platform_Plugins gains kindEq", async () => {
556
+ let fragment = GraphQL_FragmentGenerator$ReventlessCore.generate([], PluginBaseFragment$ReventlessCore.queryEntries);
557
+ let sdl = GraphQL_SchemaInspector$ReventlessCore.inspectFragment(fragment).sdlPreview;
558
+ globalThis.expect(sdl.includes("enum Platform_PluginKind")).toBe(true);
559
+ globalThis.expect(sdl.includes("PlatformInfrastructure")).toBe(true);
560
+ globalThis.expect(sdl.includes("kind: Platform_PluginKind!")).toBe(true);
561
+ globalThis.expect(sdl.includes("kindEq: String")).toBe(true);
562
+ });
563
+ });
564
+
553
565
  let stringSchema = S.string;
554
566
 
555
567
  let taggedSchema = DcbTag$Reventless.string;
@@ -15,11 +15,16 @@ let pluginDefinition: Reventless.Plugin.pluginDefinition = {
15
15
  uiFragments: None,
16
16
  structure: None,
17
17
  dcbEventLog: None,
18
+ kind: Domain,
18
19
  }
19
20
 
20
21
  // A higher version of the SAME plugin name — for supersession / rollback tests.
21
22
  let pluginDefinitionV2 = {...pluginDefinition, id: "name@2", version: "2"}
22
23
 
24
+ // Infrastructure-kind definition (e.g. the platform inspector) — verifies the
25
+ // business `kind` rides the handshake into the projected lifecycle row.
26
+ let pluginDefinitionInfra = {...pluginDefinition, kind: PlatformInfrastructure}
27
+
23
28
  // Expected current-view row for a def + status + the OTHER currently-connected
24
29
  // versions (own version excluded). Reuses the projection's own builder so
25
30
  // assertions match the projection output exactly.
@@ -58,4 +63,5 @@ let pluginDefinition2 = {
58
63
  uiFragments: None,
59
64
  structure: None,
60
65
  dcbEventLog: None,
66
+ kind: Domain,
61
67
  }
@@ -19,7 +19,8 @@ let pluginDefinition = {
19
19
  apiTarget: undefined,
20
20
  uiFragments: undefined,
21
21
  structure: undefined,
22
- dcbEventLog: undefined
22
+ dcbEventLog: undefined,
23
+ kind: "Domain"
23
24
  };
24
25
 
25
26
  let pluginDefinitionV2 = {
@@ -34,7 +35,24 @@ let pluginDefinitionV2 = {
34
35
  apiTarget: pluginDefinition.apiTarget,
35
36
  uiFragments: pluginDefinition.uiFragments,
36
37
  structure: pluginDefinition.structure,
37
- dcbEventLog: pluginDefinition.dcbEventLog
38
+ dcbEventLog: pluginDefinition.dcbEventLog,
39
+ kind: pluginDefinition.kind
40
+ };
41
+
42
+ let pluginDefinitionInfra = {
43
+ id: pluginDefinition.id,
44
+ name: pluginDefinition.name,
45
+ version: pluginDefinition.version,
46
+ extensionPoints: pluginDefinition.extensionPoints,
47
+ extensions: pluginDefinition.extensions,
48
+ eventCollector: pluginDefinition.eventCollector,
49
+ extensionProtocols: pluginDefinition.extensionProtocols,
50
+ apiSchemaFragment: pluginDefinition.apiSchemaFragment,
51
+ apiTarget: pluginDefinition.apiTarget,
52
+ uiFragments: pluginDefinition.uiFragments,
53
+ structure: pluginDefinition.structure,
54
+ dcbEventLog: pluginDefinition.dcbEventLog,
55
+ kind: "PlatformInfrastructure"
38
56
  };
39
57
 
40
58
  function display(def, status, otherConnectedVersions) {
@@ -65,7 +83,8 @@ let pluginDefinitionWithUI = {
65
83
  apiTarget: pluginDefinition.apiTarget,
66
84
  uiFragments: uiManifest,
67
85
  structure: pluginDefinition.structure,
68
- dcbEventLog: pluginDefinition.dcbEventLog
86
+ dcbEventLog: pluginDefinition.dcbEventLog,
87
+ kind: pluginDefinition.kind
69
88
  };
70
89
 
71
90
  let extensionPointNames2 = ["Test.Test"];
@@ -86,7 +105,8 @@ let pluginDefinition2 = {
86
105
  apiTarget: undefined,
87
106
  uiFragments: undefined,
88
107
  structure: undefined,
89
- dcbEventLog: undefined
108
+ dcbEventLog: undefined,
109
+ kind: "Domain"
90
110
  };
91
111
 
92
112
  let sc = TestFixtures$ReventlessGwt.statusChange;
@@ -95,6 +115,7 @@ export {
95
115
  sc,
96
116
  pluginDefinition,
97
117
  pluginDefinitionV2,
118
+ pluginDefinitionInfra,
98
119
  display,
99
120
  state,
100
121
  uiManifest,
@@ -27,6 +27,12 @@ describe("PluginsProjection:", () => {
27
27
  ->thenState(state)
28
28
  )
29
29
 
30
+ test("VersionConnected carries the plugin kind into the current row", () =>
31
+ givenEvents([])
32
+ ->whenEvent(VersionConnected(pluginDefinitionInfra))
33
+ ->thenState(display(pluginDefinitionInfra, Connected, []))
34
+ )
35
+
30
36
  test("A higher VersionConnected becomes the current row (supersession)", () =>
31
37
  givenEvents([VersionConnected(pluginDefinition)])
32
38
  ->whenEvent(VersionConnected(pluginDefinitionV2))
@@ -25,6 +25,10 @@ PluginsProjectionTest.describe("PluginsProjection:", () => {
25
25
  TAG: "VersionConnected",
26
26
  _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
27
27
  }), Plugin_Fixtures$ReventlessLocal.state));
28
+ PluginsProjectionTest.test("VersionConnected carries the plugin kind into the current row", undefined, () => PluginsProjectionTest.thenState(PluginsProjectionTest.whenEvent(PluginsProjectionTest.givenEvents([]), {
29
+ TAG: "VersionConnected",
30
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra
31
+ }), Plugin_Fixtures$ReventlessLocal.display(Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra, "Connected", [])));
28
32
  PluginsProjectionTest.test("A higher VersionConnected becomes the current row (supersession)", undefined, () => PluginsProjectionTest.thenState(PluginsProjectionTest.whenEvent(PluginsProjectionTest.givenEvents([{
29
33
  TAG: "VersionConnected",
30
34
  _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition