@reventlessdev/reventless-local 3.0.0-alpha.133 → 3.0.0-alpha.135

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.135 (2026-07-10)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **plugin-lifecycle:** backfill plugin kind onto existing rows via deploy-time RedetectPlugin ([502dbd6](https://github.com/ReventlessDev/reventless-core/commit/502dbd65d1fdd5b8beae8a7b96df06dcfa32fe3e))
11
+
12
+
13
+ # 3.0.0-alpha.134 (2026-07-10)
14
+
15
+ ### Features
16
+
17
+ * **reventless-ppx:** add [@group](https://github.com/group)By state-field annotation → x-reventless-group-by ([9e7a7b2](https://github.com/ReventlessDev/reventless-core/commit/9e7a7b29e54fb4eda1c6a145c0e7b6dcf26940ee))
18
+
19
+
6
20
  # 3.0.0-alpha.133 (2026-07-09)
7
21
 
8
22
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-local",
3
- "version": "3.0.0-alpha.133",
3
+ "version": "3.0.0-alpha.135",
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": {
@@ -33,19 +33,19 @@
33
33
  "ws": "^8.18.0",
34
34
  "@reventlessdev/rescript-effect": "0.1.0-alpha.25",
35
35
  "@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.18",
36
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.6",
36
37
  "@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.17",
37
38
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
38
- "@reventlessdev/rescript-jest": "1.0.0-alpha.6",
39
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.94",
40
- "@reventlessdev/reventless-infra": "3.0.0-alpha.91",
41
- "@reventlessdev/reventless-spec": "3.0.0-alpha.69",
42
- "@reventlessdev/reventless-postgres": "3.0.0-alpha.13",
43
- "@reventlessdev/reventless-core": "3.0.0-alpha.149"
39
+ "@reventlessdev/reventless-core": "3.0.0-alpha.151",
40
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.96",
41
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.93",
42
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.71",
43
+ "@reventlessdev/reventless-postgres": "3.0.0-alpha.15"
44
44
  },
45
45
  "devDependencies": {
46
46
  "rescript": "^12.3.0",
47
47
  "sury-ppx": "11.0.0-alpha.2",
48
- "@reventlessdev/reventless-ppx": "1.0.0-alpha.51"
48
+ "@reventlessdev/reventless-ppx": "1.0.0-alpha.52"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "rescript": "^12.3.0"
@@ -85,6 +85,7 @@ let indexedStateSchemaWithAnnotations = indexedStateSchema->S.Metadata.set(
85
85
  scan: [],
86
86
  scanSort: [],
87
87
  status: None,
88
+ groupBy: None,
88
89
  visibility: None,
89
90
  },
90
91
  )
@@ -111,6 +112,7 @@ let orderedStateSchemaWithAnnotations = orderedStateSchema->S.Metadata.set(
111
112
  scan: [],
112
113
  scanSort: [],
113
114
  status: None,
115
+ groupBy: None,
114
116
  visibility: None,
115
117
  },
116
118
  )
@@ -138,6 +140,7 @@ let scanStateSchemaWithAnnotations = scanStateSchema->S.Metadata.set(
138
140
  scan: ["status"],
139
141
  scanSort: ["name"],
140
142
  status: None,
143
+ groupBy: None,
141
144
  visibility: None,
142
145
  },
143
146
  )
@@ -96,6 +96,7 @@ let indexedStateSchemaWithAnnotations = S.Metadata.set(indexedStateSchema, State
96
96
  scan: [],
97
97
  scanSort: [],
98
98
  status: undefined,
99
+ groupBy: undefined,
99
100
  visibility: undefined
100
101
  });
101
102
 
@@ -119,6 +120,7 @@ let orderedStateSchemaWithAnnotations = S.Metadata.set(orderedStateSchema, State
119
120
  scan: [],
120
121
  scanSort: [],
121
122
  status: undefined,
123
+ groupBy: undefined,
122
124
  visibility: undefined
123
125
  });
124
126
 
@@ -143,6 +145,7 @@ let scanStateSchemaWithAnnotations = S.Metadata.set(scanStateSchema, StateAnnota
143
145
  scan: ["status"],
144
146
  scanSort: ["name"],
145
147
  status: undefined,
148
+ groupBy: undefined,
146
149
  visibility: undefined
147
150
  });
148
151
 
@@ -36,6 +36,7 @@ let rowStateSchemaWithAnnotations =
36
36
  scan: ["status"],
37
37
  scanSort: ["name"],
38
38
  status: None,
39
+ groupBy: None,
39
40
  visibility: None,
40
41
  },
41
42
  )
@@ -44,6 +44,7 @@ let rowStateSchemaWithAnnotations = S.Metadata.set(rowStateSchema, StateAnnotati
44
44
  scan: ["status"],
45
45
  scanSort: ["name"],
46
46
  status: undefined,
47
+ groupBy: undefined,
47
48
  visibility: undefined
48
49
  });
49
50
 
@@ -43,6 +43,41 @@ describe("PluginBehavior:", () => {
43
43
  givenEvents([VersionConnected(pluginDefinition)])->whenCmd(Heartbeat("1"))->thenNoEvent
44
44
  )
45
45
 
46
+ // ── Deploy-time re-detect + definition refresh ─────────────────────────────
47
+ // Redetect (fired once per deploy) forces the handshake to run again — even for
48
+ // a connected version — so the plugin re-answers with its current definition and
49
+ // Connect refreshes the stored def (e.g. backfilling a newly added `kind`).
50
+ test("Redetect re-runs detection for an already-connected version", () =>
51
+ givenEvents([VersionConnected(pluginDefinition)])
52
+ ->whenCmd(Redetect("1"))
53
+ ->thenEvents([VersionDetected("1")])
54
+ )
55
+
56
+ test("Redetect for an unknown version detects like a heartbeat", () =>
57
+ givenEvents([])->whenCmd(Redetect("1"))->thenEvents([VersionDetected("1")])
58
+ )
59
+
60
+ test("Redetect re-detects a disconnected version (drives a full reconnect handshake)", () =>
61
+ givenEvents([VersionConnected(pluginDefinition), VersionDisconnected(pluginDefinition)])
62
+ ->whenCmd(Redetect("1"))
63
+ ->thenEvents([VersionDetected("1")])
64
+ )
65
+
66
+ test("Redetect does NOT revive a retired version (admin only)", () =>
67
+ givenEvents([VersionConnected(pluginDefinition), VersionRetired(pluginDefinition)])
68
+ ->whenCmd(Redetect("1"))
69
+ ->thenNoEvent
70
+ )
71
+
72
+ test("Connect refreshes the stored definition when it changed (kind backfill)", () =>
73
+ // Same version, but the redeployed def now carries kind PlatformInfrastructure
74
+ // where the stored one predated `kind` (Domain). Re-emit VersionConnected so the
75
+ // projected row picks up the new kind; no supersede (the version is still current).
76
+ givenEvents([VersionConnected(pluginDefinition)])
77
+ ->whenCmd(Connect(pluginDefinitionInfra))
78
+ ->thenEvents([VersionConnected(pluginDefinitionInfra)])
79
+ )
80
+
46
81
  // ── Disconnect / reconnect ─────────────────────────────────────────────────
47
82
  test("Disconnect of the current version", () =>
48
83
  givenEvents([VersionConnected(pluginDefinition)])
@@ -76,6 +76,62 @@ PluginTest.describe("PluginBehavior:", () => {
76
76
  TAG: "Heartbeat",
77
77
  _0: "1"
78
78
  })));
79
+ PluginTest.test("Redetect re-runs detection for an already-connected version", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([{
80
+ TAG: "VersionConnected",
81
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
82
+ }]), {
83
+ TAG: "Redetect",
84
+ _0: "1"
85
+ }), [{
86
+ TAG: "VersionDetected",
87
+ _0: "1"
88
+ }]));
89
+ PluginTest.test("Redetect for an unknown version detects like a heartbeat", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([]), {
90
+ TAG: "Redetect",
91
+ _0: "1"
92
+ }), [{
93
+ TAG: "VersionDetected",
94
+ _0: "1"
95
+ }]));
96
+ PluginTest.test("Redetect re-detects a disconnected version (drives a full reconnect handshake)", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([
97
+ {
98
+ TAG: "VersionConnected",
99
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
100
+ },
101
+ {
102
+ TAG: "VersionDisconnected",
103
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
104
+ }
105
+ ]), {
106
+ TAG: "Redetect",
107
+ _0: "1"
108
+ }), [{
109
+ TAG: "VersionDetected",
110
+ _0: "1"
111
+ }]));
112
+ PluginTest.test("Redetect does NOT revive a retired version (admin only)", () => PluginTest.thenNoEvent(PluginTest.whenCmd(PluginTest.givenEvents([
113
+ {
114
+ TAG: "VersionConnected",
115
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
116
+ },
117
+ {
118
+ TAG: "VersionRetired",
119
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
120
+ }
121
+ ]), {
122
+ TAG: "Redetect",
123
+ _0: "1"
124
+ })));
125
+ PluginTest.test("Connect refreshes the stored definition when it changed (kind backfill)", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([{
126
+ TAG: "VersionConnected",
127
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
128
+ }]), {
129
+ TAG: "Connect",
130
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra
131
+ }), [{
132
+ TAG: "VersionConnected",
133
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra
134
+ }]));
79
135
  PluginTest.test("Disconnect of the current version", () => PluginTest.thenEvents(PluginTest.whenCmd(PluginTest.givenEvents([{
80
136
  TAG: "VersionConnected",
81
137
  _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
@@ -33,6 +33,15 @@ describe("PluginsProjection:", () => {
33
33
  ->thenState(display(pluginDefinitionInfra, Connected, []))
34
34
  )
35
35
 
36
+ test("A re-emitted VersionConnected refreshes kind on an existing row (deploy backfill)", () =>
37
+ // The deploy re-detect drives Connect with the current def; for a version already
38
+ // Connected with a kind-less (Domain) def, the refreshed VersionConnected overwrites
39
+ // the row's kind in place — same version, no new/other-connected version.
40
+ givenEvents([VersionConnected(pluginDefinition)])
41
+ ->whenEvent(VersionConnected(pluginDefinitionInfra))
42
+ ->thenState(display(pluginDefinitionInfra, Connected, []))
43
+ )
44
+
36
45
  test("A higher VersionConnected becomes the current row (supersession)", () =>
37
46
  givenEvents([VersionConnected(pluginDefinition)])
38
47
  ->whenEvent(VersionConnected(pluginDefinitionV2))
@@ -29,6 +29,13 @@ PluginsProjectionTest.describe("PluginsProjection:", () => {
29
29
  TAG: "VersionConnected",
30
30
  _0: Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra
31
31
  }), Plugin_Fixtures$ReventlessLocal.display(Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra, "Connected", [])));
32
+ PluginsProjectionTest.test("A re-emitted VersionConnected refreshes kind on an existing row (deploy backfill)", undefined, () => PluginsProjectionTest.thenState(PluginsProjectionTest.whenEvent(PluginsProjectionTest.givenEvents([{
33
+ TAG: "VersionConnected",
34
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition
35
+ }]), {
36
+ TAG: "VersionConnected",
37
+ _0: Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra
38
+ }), Plugin_Fixtures$ReventlessLocal.display(Plugin_Fixtures$ReventlessLocal.pluginDefinitionInfra, "Connected", [])));
32
39
  PluginsProjectionTest.test("A higher VersionConnected becomes the current row (supersession)", undefined, () => PluginsProjectionTest.thenState(PluginsProjectionTest.whenEvent(PluginsProjectionTest.givenEvents([{
33
40
  TAG: "VersionConnected",
34
41
  _0: Plugin_Fixtures$ReventlessLocal.pluginDefinition