@reventlessdev/reventless-gwt 1.0.0-alpha.212 → 1.0.0-alpha.214

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,27 @@
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
+ # 1.0.0-alpha.214 (2026-09-21)
7
+
8
+ * feat(spec)!: typed projection keys ([fc6a018](https://github.com/ReventlessDev/reventless-core/commit/fc6a01811ba788f3289e84a435a09f77fa627e1a))
9
+
10
+ ### BREAKING CHANGES
11
+
12
+ * a projection that keys a row by a payload `string`, or uses
13
+ the envelope id as a `string`, converts explicitly with
14
+ `Target.Id.makeFromString` / `Source.Id.toString`. `StateChangeSlice.Spec` no
15
+ longer requires `module Id`.
16
+
17
+
18
+
19
+ # 1.0.0-alpha.213 (2026-09-21)
20
+
21
+ **Note:** Version bump only for package @reventlessdev/reventless-gwt
22
+
23
+
24
+
25
+
26
+
6
27
  # 1.0.0-alpha.212 (2026-09-20)
7
28
 
8
29
  **Note:** Version bump only for package @reventlessdev/reventless-gwt
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-gwt",
3
- "version": "1.0.0-alpha.212",
3
+ "version": "1.0.0-alpha.214",
4
4
  "description": "Given-When-Then DSLs and test harness for Reventless slice testing",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -17,14 +17,14 @@
17
17
  "@reventlessdev/rescript-effect": "0.1.0-alpha.33",
18
18
  "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
19
19
  "@reventlessdev/rescript-node": "2.0.0-alpha.12",
20
- "@reventlessdev/reventless-core": "3.0.0-alpha.265",
21
- "@reventlessdev/reventless-infra": "3.0.0-alpha.166",
22
- "@reventlessdev/reventless-spec": "3.0.0-alpha.138"
20
+ "@reventlessdev/reventless-core": "3.0.0-alpha.267",
21
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.168",
22
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.140"
23
23
  },
24
24
  "devDependencies": {
25
25
  "rescript": "12.3.0",
26
26
  "sury-ppx": "11.0.0-rc.2",
27
- "@reventlessdev/reventless-ppx": "1.0.0-alpha.80"
27
+ "@reventlessdev/reventless-ppx": "1.0.0-alpha.81"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "rescript": "12.3.0"
@@ -33,6 +33,8 @@ module Make = (Projection: Reventless.Projection.Mapping): (
33
33
  T with type sourceEvent := Projection.sourceEvent and type targetState := Projection.targetState
34
34
  ) => {
35
35
  let testId = ref(TestFixtures.id)
36
+ // The envelope carries the source's id type; the store is keyed by strings.
37
+ let sourceId = () => Projection.SourceId.makeFromString(testId.contents)
36
38
  let meta = ref(TestFixtures.meta)
37
39
 
38
40
  let describe = JestBind.describe
@@ -129,6 +131,10 @@ module Make = (Projection: Reventless.Projection.Mapping): (
129
131
  ->Array.map(event' =>
130
132
  event'
131
133
  ->Projection.project
134
+ ->Reventless.Projection.mapActionId(
135
+ ~to_=Projection.targetIdToString,
136
+ ~from=Projection.targetIdFromString,
137
+ )
132
138
  ->ReventlessCore.Projection.rewriteTrail(~at=event'.meta.time, Projection.targetStateSchema)
133
139
  )
134
140
  ->handleActions({
@@ -146,13 +152,13 @@ module Make = (Projection: Reventless.Projection.Mapping): (
146
152
 
147
153
  let givenEvents = events =>
148
154
  Dict.make()->update(
149
- events->Array.map(event => {Message.id: testId.contents, meta: meta.contents, event}),
155
+ events->Array.map(event => {Message.id: sourceId(), meta: meta.contents, event}),
150
156
  )
151
157
 
152
158
  let givenEventsWithTime = events =>
153
159
  Dict.make()->update(
154
160
  events->Array.map(((time, event)) => {
155
- Message.id: testId.contents,
161
+ Message.id: sourceId(),
156
162
  meta: {...meta.contents, time},
157
163
  event,
158
164
  }),
@@ -162,14 +168,14 @@ module Make = (Projection: Reventless.Projection.Mapping): (
162
168
  () =>
163
169
  (
164
170
  async () =>
165
- await (await store)->update([{Message.id: testId.contents, meta: meta.contents, event}])
171
+ await (await store)->update([{Message.id: sourceId(), meta: meta.contents, event}])
166
172
  )()
167
173
  let whenEvents = (store, events): storeThunk =>
168
174
  () =>
169
175
  (
170
176
  async () =>
171
177
  await (await store)->update(
172
- events->Array.map(event => {Message.id: testId.contents, meta: meta.contents, event}),
178
+ events->Array.map(event => {Message.id: sourceId(), meta: meta.contents, event}),
173
179
  )
174
180
  )()
175
181
  let whenEventWithTime = (store, time, event): storeThunk =>
@@ -177,7 +183,7 @@ module Make = (Projection: Reventless.Projection.Mapping): (
177
183
  (
178
184
  async () =>
179
185
  await (await store)->update([
180
- {Message.id: testId.contents, meta: {...meta.contents, time}, event},
186
+ {Message.id: sourceId(), meta: {...meta.contents, time}, event},
181
187
  ])
182
188
  )()
183
189
  let whenEventsWithTime = (store, events): storeThunk =>
@@ -186,7 +192,7 @@ module Make = (Projection: Reventless.Projection.Mapping): (
186
192
  async () =>
187
193
  await (await store)->update(
188
194
  events->Array.map(((time, event)) => {
189
- Message.id: testId.contents,
195
+ Message.id: sourceId(),
190
196
  meta: {...meta.contents, time},
191
197
  event,
192
198
  }),
@@ -7,6 +7,7 @@ import * as Stream from "effect/Stream";
7
7
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
8
8
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
9
9
  import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
10
+ import * as Projection$Reventless from "@reventlessdev/reventless-spec/src/types/Projection.res.mjs";
10
11
  import * as JestBind$ReventlessGwt from "./JestBind.res.mjs";
11
12
  import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
12
13
  import * as Projection$ReventlessCore from "@reventlessdev/reventless-core/src/Projection.res.mjs";
@@ -45,7 +46,7 @@ function Make(Projection) {
45
46
  };
46
47
  let handleActions = (actions, operations) => Projection$ReventlessCore.handleActions(undefined, actions, operations, Projection.subIdConfig);
47
48
  let update = async (store, events$p) => {
48
- await handleActions(events$p.map(event$p => Projection$ReventlessCore.rewriteTrail(Projection.project(event$p), event$p.meta.time, Projection.targetStateSchema)), {
49
+ await handleActions(events$p.map(event$p => Projection$ReventlessCore.rewriteTrail(Projection$Reventless.mapActionId(Projection.project(event$p), Projection.targetIdToString, Projection.targetIdFromString), event$p.meta.time, Projection.targetStateSchema)), {
49
50
  load: extra => Promise.resolve({
50
51
  TAG: "Ok",
51
52
  _0: states(store, extra)
@@ -169,32 +170,32 @@ function Make(Projection) {
169
170
  }
170
171
  };
171
172
  let givenEvents = events => update({}, events.map(event => ({
172
- id: testId.contents,
173
+ id: Projection.SourceId.makeFromString(testId.contents),
173
174
  meta: meta.contents,
174
175
  event: event
175
176
  })));
176
177
  let givenEventsWithTime = events => update({}, events.map(param => {
177
178
  let newrecord = {...meta.contents};
178
179
  return {
179
- id: testId.contents,
180
+ id: Projection.SourceId.makeFromString(testId.contents),
180
181
  meta: (newrecord.time = param[0], newrecord),
181
182
  event: param[1]
182
183
  };
183
184
  }));
184
185
  let whenEvent = (store, event) => (() => (async () => await update(await store, [{
185
- id: testId.contents,
186
+ id: Projection.SourceId.makeFromString(testId.contents),
186
187
  meta: meta.contents,
187
188
  event: event
188
189
  }]))());
189
190
  let whenEvents = (store, events) => (() => (async () => await update(await store, events.map(event => ({
190
- id: testId.contents,
191
+ id: Projection.SourceId.makeFromString(testId.contents),
191
192
  meta: meta.contents,
192
193
  event: event
193
194
  }))))());
194
195
  let whenEventWithTime = (store, time, event) => (() => (async () => {
195
196
  let newrecord = {...meta.contents};
196
197
  return await update(await store, [{
197
- id: testId.contents,
198
+ id: Projection.SourceId.makeFromString(testId.contents),
198
199
  meta: (newrecord.time = time, newrecord),
199
200
  event: event
200
201
  }]);
@@ -202,7 +203,7 @@ function Make(Projection) {
202
203
  let whenEventsWithTime = (store, events) => (() => (async () => await update(await store, events.map(param => {
203
204
  let newrecord = {...meta.contents};
204
205
  return {
205
- id: testId.contents,
206
+ id: Projection.SourceId.makeFromString(testId.contents),
206
207
  meta: (newrecord.time = param[0], newrecord),
207
208
  event: param[1]
208
209
  };
@@ -20,6 +20,8 @@ module type Spec = {
20
20
 
21
21
  let stateSchema: S.t<state>
22
22
 
23
+ module Key: Reventless.Id.T
24
+
23
25
  @schema
24
26
  type consumedEvent
25
27
 
@@ -31,7 +33,7 @@ module type Projection = {
31
33
  module Spec: Spec
32
34
 
33
35
  let project: Reventless.StateViewSlice.consumed<Spec.consumedEvent> => array<
34
- Reventless.Projection.action<string, Spec.state>,
36
+ Reventless.Projection.action<Spec.Key.t, Spec.state>,
35
37
  >
36
38
  }
37
39
 
@@ -176,8 +178,10 @@ module Make = (Spec: Spec, Projection: Projection with module Spec := Spec): (
176
178
  recordedAt: TestFixtures.recordedAt,
177
179
  }
178
180
  ->Projection.project
179
- ->Array.map(
180
- ReventlessCore.Projection.rewriteTrail(_, ~at=TestFixtures.meta.time, Spec.stateSchema),
181
+ ->Array.map(action =>
182
+ action
183
+ ->Reventless.Projection.mapActionId(~to_=Spec.Key.toString, ~from=Spec.Key.makeFromString)
184
+ ->ReventlessCore.Projection.rewriteTrail(~at=TestFixtures.meta.time, Spec.stateSchema)
181
185
  )
182
186
  )
183
187
  ->Array.flat
@@ -7,6 +7,7 @@ import * as Stream from "effect/Stream";
7
7
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
8
8
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
9
9
  import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
10
+ import * as Projection$Reventless from "@reventlessdev/reventless-spec/src/types/Projection.res.mjs";
10
11
  import * as JestBind$ReventlessGwt from "./JestBind.res.mjs";
11
12
  import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
12
13
  import * as Projection$ReventlessCore from "@reventlessdev/reventless-core/src/Projection.res.mjs";
@@ -63,7 +64,7 @@ function Make(Spec) {
63
64
  event: ev,
64
65
  meta: TestFixtures$ReventlessGwt.meta,
65
66
  recordedAt: TestFixtures$ReventlessGwt.recordedAt
66
- }).map(__x => Projection$ReventlessCore.rewriteTrail(__x, TestFixtures$ReventlessGwt.meta.time, Spec.stateSchema))).flat();
67
+ }).map(action => Projection$ReventlessCore.rewriteTrail(Projection$Reventless.mapActionId(action, Spec.Key.toString, Spec.Key.makeFromString), TestFixtures$ReventlessGwt.meta.time, Spec.stateSchema))).flat();
67
68
  await runActions(actions, {
68
69
  load: extra => Promise.resolve({
69
70
  TAG: "Ok",
@@ -120,6 +120,7 @@ module ShipOrderBehavior = {
120
120
  }
121
121
 
122
122
  module OrdersViewSlice = {
123
+ module Key = Reventless.Id.StringPure
123
124
  let name = "OrdersView"
124
125
 
125
126
  @schema
@@ -1,6 +1,7 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Sury from "sury";
4
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
5
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
6
  import * as Flow_GWT$ReventlessGwt from "../src/Flow_GWT.res.mjs";
6
7
 
@@ -254,6 +255,8 @@ let ShipOrderBehavior = {
254
255
  decide: decide$1
255
256
  };
256
257
 
258
+ let name = "OrdersView";
259
+
257
260
  let stateSchema = Sury.$schema(s => ({
258
261
  orderId: s.m(Sury.string),
259
262
  item: s.m(Sury.string),
@@ -273,7 +276,8 @@ let consumedEventSchema$3 = Sury.union([
273
276
  ]);
274
277
 
275
278
  let OrdersViewSlice = {
276
- name: "OrdersView",
279
+ Key: undefined,
280
+ name: name,
277
281
  stateSchema: stateSchema,
278
282
  consumedEventSchema: consumedEventSchema$3,
279
283
  subIdConfig: undefined,
@@ -355,7 +359,19 @@ let Ship = Flow_GWT$ReventlessGwt.CommandStep(ShipOrderSlice)({
355
359
  decide: decide$1
356
360
  });
357
361
 
358
- let View = Flow_GWT$ReventlessGwt.ViewStep(OrdersViewSlice)({
362
+ let View = Flow_GWT$ReventlessGwt.ViewStep({
363
+ name: name,
364
+ stateSchema: stateSchema,
365
+ Key: {
366
+ schema: Id$Reventless.StringPure.schema,
367
+ make: prim => prim,
368
+ makeFromString: prim => prim,
369
+ toString: prim => prim,
370
+ cmp: Id$Reventless.StringPure.cmp
371
+ },
372
+ consumedEventSchema: consumedEventSchema$3,
373
+ subIdConfig: undefined
374
+ })({
359
375
  project: project
360
376
  });
361
377
 
@@ -115,6 +115,7 @@ CategoriesQuery.describe("Categories ReadModel queries", () => {
115
115
  module OrdersView = {
116
116
  let name = "OrdersView"
117
117
  let moduleUrl = ""
118
+ module Key = Reventless.Id.StringPure
118
119
 
119
120
  @schema
120
121
  type state = {orderId: string, customerId: string, total: int}
@@ -242,6 +242,7 @@ let subIdConfig = {
242
242
  let OrdersView = {
243
243
  name: name$1,
244
244
  moduleUrl: moduleUrl$1,
245
+ Key: undefined,
245
246
  stateSchema: stateSchema$1,
246
247
  consumedEventSchema: consumedEventSchema,
247
248
  project: project,
@@ -255,6 +256,13 @@ let OrdersQuery = Query_GWT$ReventlessGwt.Make(Query_GWT$ReventlessGwt.FromState
255
256
  name: name$1,
256
257
  moduleUrl: moduleUrl$1,
257
258
  stateSchema: stateSchema$1,
259
+ Key: {
260
+ schema: Id$Reventless.StringPure.schema,
261
+ make: prim => prim,
262
+ makeFromString: prim => prim,
263
+ toString: prim => prim,
264
+ cmp: Id$Reventless.StringPure.cmp
265
+ },
258
266
  consumedEventSchema: consumedEventSchema,
259
267
  config: config$1,
260
268
  subIdConfig: subIdConfig,
@@ -11,6 +11,7 @@
11
11
  open Reventless.Projection
12
12
 
13
13
  module CategoriesView = {
14
+ module Key = Reventless.Id.StringPure
14
15
  let name = "CategoriesView"
15
16
 
16
17
  @schema
@@ -1,8 +1,11 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as Sury from "sury";
4
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
5
  import * as Projection_GWT$ReventlessGwt from "../src/Projection_GWT.res.mjs";
5
6
 
7
+ let name = "CategoriesView";
8
+
6
9
  let stateSchema = Sury.$schema(s => ({
7
10
  categoryId: s.m(Sury.string),
8
11
  name: s.m(Sury.string),
@@ -27,7 +30,8 @@ let consumedEventSchema = Sury.union([
27
30
  ]);
28
31
 
29
32
  let CategoriesView = {
30
- name: "CategoriesView",
33
+ Key: undefined,
34
+ name: name,
31
35
  stateSchema: stateSchema,
32
36
  consumedEventSchema: consumedEventSchema,
33
37
  subIdConfig: undefined,
@@ -78,7 +82,19 @@ let CategoriesViewProjection = {
78
82
  project: project
79
83
  };
80
84
 
81
- let include = Projection_GWT$ReventlessGwt.Make(CategoriesView)({
85
+ let include = Projection_GWT$ReventlessGwt.Make({
86
+ name: name,
87
+ stateSchema: stateSchema,
88
+ Key: {
89
+ schema: Id$Reventless.StringPure.schema,
90
+ make: prim => prim,
91
+ makeFromString: prim => prim,
92
+ toString: prim => prim,
93
+ cmp: Id$Reventless.StringPure.cmp
94
+ },
95
+ consumedEventSchema: consumedEventSchema,
96
+ subIdConfig: undefined
97
+ })({
82
98
  project: project
83
99
  });
84
100