@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 +21 -0
- package/package.json +5 -5
- package/src/MultiSourceProjection_GWT.res +12 -6
- package/src/MultiSourceProjection_GWT.res.mjs +8 -7
- package/src/Projection_GWT.res +7 -3
- package/src/Projection_GWT.res.mjs +2 -1
- package/tests/FlowGwtTest.res +1 -0
- package/tests/FlowGwtTest.res.mjs +18 -2
- package/tests/QueryGwtTest.res +1 -0
- package/tests/QueryGwtTest.res.mjs +8 -0
- package/tests/StateViewSliceGwtTest.res +1 -0
- package/tests/StateViewSliceGwtTest.res.mjs +18 -2
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.
|
|
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.
|
|
21
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.
|
|
22
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
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.
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
};
|
package/src/Projection_GWT.res
CHANGED
|
@@ -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<
|
|
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
|
-
|
|
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(
|
|
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",
|
package/tests/FlowGwtTest.res
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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
|
|
package/tests/QueryGwtTest.res
CHANGED
|
@@ -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,
|
|
@@ -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
|
-
|
|
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(
|
|
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
|
|