@reventlessdev/reventless-local 3.0.0-alpha.256 → 3.0.0-alpha.257
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 +16 -0
- package/package.json +8 -8
- package/src/Platform.res.mjs +16 -2
- package/tests/components/aggregate/AggregateSelfMappingFixtures.res +88 -0
- package/tests/components/aggregate/AggregateSelfMappingFixtures.res.mjs +204 -0
- package/tests/components/aggregate/AggregateSelfMappingTest.res +43 -0
- package/tests/components/aggregate/AggregateSelfMappingTest.res.mjs +33 -0
- package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res.mjs +0 -2
- package/tests/components/dcb/DcbCrossPartitionFixtures.res.mjs +0 -2
- package/tests/components/dcb/DcbFixtures.res.mjs +0 -2
- package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res.mjs +0 -2
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res +7 -2
- package/tests/components/readmodel/DcbReadModelE2EFixtures.res.mjs +1 -2
- package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res +3 -2
- package/tests/components/readmodel/DcbReadModelTypoFailFastTest.res.mjs +1 -1
- package/tests/components/readmodel/MixedSourceReadModelFixtures.res +2 -2
- package/tests/components/readmodel/ReadModelFixtures.res +1 -1
- package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res +1 -0
- package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res.mjs +9 -0
- package/tests/components/stateviewslice/StateViewSliceFixtures.res +1 -0
- package/tests/components/stateviewslice/StateViewSliceFixtures.res.mjs +9 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +1 -0
- package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res.mjs +9 -0
- package/tests/plugin/UiFragments_GWT.res.mjs +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
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.257 (2026-09-21)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **core:** an event mapping that commands its own source no longer hangs ([d30ce6b](https://github.com/ReventlessDev/reventless-core/commit/d30ce6b360707d933732fa2c90aba49c03dda006))
|
|
11
|
+
* feat(spec)!: typed projection keys ([fc6a018](https://github.com/ReventlessDev/reventless-core/commit/fc6a01811ba788f3289e84a435a09f77fa627e1a))
|
|
12
|
+
|
|
13
|
+
### BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* a projection that keys a row by a payload `string`, or uses
|
|
16
|
+
the envelope id as a `string`, converts explicitly with
|
|
17
|
+
`Target.Id.makeFromString` / `Source.Id.toString`. `StateChangeSlice.Spec` no
|
|
18
|
+
longer requires `module Id`.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# 3.0.0-alpha.256 (2026-09-21)
|
|
7
23
|
|
|
8
24
|
**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.
|
|
3
|
+
"version": "3.0.0-alpha.257",
|
|
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
|
"bin": {
|
|
@@ -39,19 +39,19 @@
|
|
|
39
39
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
40
40
|
"@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.22",
|
|
41
41
|
"@reventlessdev/rescript-node": "2.0.0-alpha.12",
|
|
42
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.266",
|
|
43
42
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.21",
|
|
44
|
-
"@reventlessdev/reventless-
|
|
45
|
-
"@reventlessdev/reventless-
|
|
46
|
-
"@reventlessdev/reventless-
|
|
43
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.267",
|
|
44
|
+
"@reventlessdev/reventless-graphql-server": "1.0.0-alpha.115",
|
|
45
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.214",
|
|
47
46
|
"@reventlessdev/reventless-seed": "1.0.0-alpha.23",
|
|
48
|
-
"@reventlessdev/reventless-
|
|
49
|
-
"@reventlessdev/reventless-
|
|
47
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.168",
|
|
48
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.131",
|
|
49
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.140"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"rescript": "12.3.0",
|
|
53
53
|
"sury-ppx": "11.0.0-rc.2",
|
|
54
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
54
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.81"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"rescript": "12.3.0"
|
package/src/Platform.res.mjs
CHANGED
|
@@ -642,7 +642,6 @@ function MakeWithConfig(Config) {
|
|
|
642
642
|
let Spec = {
|
|
643
643
|
name: UiFragmentRegistry$ReventlessCore.name,
|
|
644
644
|
moduleUrl: UiFragmentRegistry$ReventlessCore.moduleUrl,
|
|
645
|
-
Id: Id$Reventless.$$String,
|
|
646
645
|
consumedEventSchema: UiFragmentRegistry$ReventlessCore.consumedEventSchema,
|
|
647
646
|
errorSchema: UiFragmentRegistry$ReventlessCore.errorSchema,
|
|
648
647
|
eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
|
|
@@ -669,10 +668,18 @@ function MakeWithConfig(Config) {
|
|
|
669
668
|
isAsync: UiFragmentRegistrySlice_isAsync,
|
|
670
669
|
make: UiFragmentRegistrySlice_make
|
|
671
670
|
};
|
|
671
|
+
let Spec_Key = {
|
|
672
|
+
schema: Id$Reventless.StringPure.schema,
|
|
673
|
+
make: prim => prim,
|
|
674
|
+
makeFromString: prim => prim,
|
|
675
|
+
toString: prim => prim,
|
|
676
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
677
|
+
};
|
|
672
678
|
let Spec$1 = {
|
|
673
679
|
name: UiFragments$ReventlessCore.name,
|
|
674
680
|
moduleUrl: UiFragments$ReventlessCore.moduleUrl,
|
|
675
681
|
stateSchema: UiFragments$ReventlessCore.stateSchema,
|
|
682
|
+
Key: Spec_Key,
|
|
676
683
|
consumedEventSchema: UiFragments$ReventlessCore.consumedEventSchema,
|
|
677
684
|
config: UiFragments$ReventlessCore.config,
|
|
678
685
|
subIdConfig: undefined,
|
|
@@ -2388,7 +2395,6 @@ function Make($star) {
|
|
|
2388
2395
|
let Spec = {
|
|
2389
2396
|
name: UiFragmentRegistry$ReventlessCore.name,
|
|
2390
2397
|
moduleUrl: UiFragmentRegistry$ReventlessCore.moduleUrl,
|
|
2391
|
-
Id: Id$Reventless.$$String,
|
|
2392
2398
|
consumedEventSchema: UiFragmentRegistry$ReventlessCore.consumedEventSchema,
|
|
2393
2399
|
errorSchema: UiFragmentRegistry$ReventlessCore.errorSchema,
|
|
2394
2400
|
eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
|
|
@@ -2415,10 +2421,18 @@ function Make($star) {
|
|
|
2415
2421
|
isAsync: UiFragmentRegistrySlice_isAsync,
|
|
2416
2422
|
make: UiFragmentRegistrySlice_make
|
|
2417
2423
|
};
|
|
2424
|
+
let Spec_Key = {
|
|
2425
|
+
schema: Id$Reventless.StringPure.schema,
|
|
2426
|
+
make: prim => prim,
|
|
2427
|
+
makeFromString: prim => prim,
|
|
2428
|
+
toString: prim => prim,
|
|
2429
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
2430
|
+
};
|
|
2418
2431
|
let Spec$1 = {
|
|
2419
2432
|
name: UiFragments$ReventlessCore.name,
|
|
2420
2433
|
moduleUrl: UiFragments$ReventlessCore.moduleUrl,
|
|
2421
2434
|
stateSchema: UiFragments$ReventlessCore.stateSchema,
|
|
2435
|
+
Key: Spec_Key,
|
|
2422
2436
|
consumedEventSchema: UiFragments$ReventlessCore.consumedEventSchema,
|
|
2423
2437
|
config: UiFragments$ReventlessCore.config,
|
|
2424
2438
|
subIdConfig: undefined,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Regression fixtures for the event-mapping self-deadlock.
|
|
2
|
+
//
|
|
3
|
+
// An aggregate whose event mapping commands the aggregate that emitted the event:
|
|
4
|
+
// Placed → Ship, as the aggregates example's order auto-ships. Awaited inside the
|
|
5
|
+
// mapper's subscriber, the Ship command appends Shipped, which the bus cannot
|
|
6
|
+
// finish publishing until that same subscriber dequeues it — so the original
|
|
7
|
+
// Place never returned, and neither did the GraphQL request behind it.
|
|
8
|
+
|
|
9
|
+
module ShipmentSpec = {
|
|
10
|
+
module Id = Reventless.Id.String
|
|
11
|
+
let name = "TestShipment"
|
|
12
|
+
|
|
13
|
+
@schema
|
|
14
|
+
type command = Place | Ship
|
|
15
|
+
|
|
16
|
+
@schema
|
|
17
|
+
type event = Placed | Shipped
|
|
18
|
+
|
|
19
|
+
@schema
|
|
20
|
+
type error = unit
|
|
21
|
+
|
|
22
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module ShipmentBehavior: ReventlessCore.Behavior.T with module Spec := ShipmentSpec = {
|
|
26
|
+
type state = int // events seen
|
|
27
|
+
|
|
28
|
+
let initialState = 0
|
|
29
|
+
let snapshot = None
|
|
30
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
31
|
+
|
|
32
|
+
let evolve = (state, _event: ShipmentSpec.event) => state + 1
|
|
33
|
+
|
|
34
|
+
let decide = (state, command: ShipmentSpec.command) =>
|
|
35
|
+
switch (state, command) {
|
|
36
|
+
| (0, Place) => Ok([ShipmentSpec.Placed])
|
|
37
|
+
| (1, Ship) => Ok([ShipmentSpec.Shipped])
|
|
38
|
+
| _ => Ok([])
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module ShipmentMappings = {
|
|
43
|
+
module M = Reventless.EventMapping.Mappings.Make(ShipmentSpec)
|
|
44
|
+
module type Mapping = M.Mapping
|
|
45
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
46
|
+
|
|
47
|
+
module AutoShip = {
|
|
48
|
+
module Source = ShipmentSpec
|
|
49
|
+
let map = (id, event, _queryEngine) =>
|
|
50
|
+
switch event {
|
|
51
|
+
| ShipmentSpec.Placed => [Reventless.EventMapping.Publish(id, ShipmentSpec.Ship)]
|
|
52
|
+
| Shipped => []
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let mappings: array<module(Mapping)> = [module(AutoShip)]
|
|
57
|
+
let counter = None
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module Bus = LocalBus.Make()
|
|
61
|
+
|
|
62
|
+
// Topic name = Spec.name ++ "Aggr" ++ "EventTopic"
|
|
63
|
+
let publishedEvents: ref<int> = ref(0)
|
|
64
|
+
let _ = Bus.subscribeToEvents("TestShipmentAggrEventTopic", async (_, _, _) => {
|
|
65
|
+
publishedEvents := publishedEvents.contents + 1
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
let _ = TestRunner.setup()
|
|
69
|
+
|
|
70
|
+
module ShipmentAggregateMaker = Aggregate_Builder.Make(Bus)
|
|
71
|
+
module ShipmentAgg = ShipmentAggregateMaker.Make(ShipmentSpec, ShipmentBehavior, ShipmentMappings)
|
|
72
|
+
|
|
73
|
+
let agg = ShipmentAgg.make(~api=())
|
|
74
|
+
|
|
75
|
+
// A plugin attaches an aggregate's event mapper once every topic exists; with one
|
|
76
|
+
// aggregate, its own topic is all there is.
|
|
77
|
+
let aggOutputs = agg->ReventlessCore.Component.outputs
|
|
78
|
+
let _ = aggOutputs.addEventMapper(
|
|
79
|
+
Dict.fromArray([(ShipmentSpec.name, aggOutputs.eventLog.eventTopic)]),
|
|
80
|
+
TestFixtures.mockQueryEngine,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
let withTimeout = async (p: promise<'a>, ~ms: int): result<'a, string> => {
|
|
84
|
+
let timeout = Promise.make((resolve, _) => {
|
|
85
|
+
let _ = setTimeout(() => resolve(Error("timed out")), ms)
|
|
86
|
+
})
|
|
87
|
+
await Promise.race([p->Promise.thenResolve(v => Ok(v)), timeout])
|
|
88
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Sury from "sury";
|
|
4
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
5
|
+
import * as EventMapping$Reventless from "@reventlessdev/reventless-spec/src/types/EventMapping.res.mjs";
|
|
6
|
+
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
7
|
+
import * as LocalBus$ReventlessLocal from "../../../src/adapter/LocalBus.res.mjs";
|
|
8
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
9
|
+
import * as TestFixtures$ReventlessLocal from "../../TestFixtures.res.mjs";
|
|
10
|
+
import * as Aggregate_Builder$ReventlessLocal from "../../../src/components/Aggregate_Builder.res.mjs";
|
|
11
|
+
|
|
12
|
+
let name = "TestShipment";
|
|
13
|
+
|
|
14
|
+
let commandSchema = Sury.union([
|
|
15
|
+
Sury.literal("Place"),
|
|
16
|
+
Sury.literal("Ship")
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
let eventSchema = Sury.union([
|
|
20
|
+
Sury.literal("Placed"),
|
|
21
|
+
Sury.literal("Shipped")
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
let errorSchema = Sury.$unit;
|
|
25
|
+
|
|
26
|
+
let moduleUrl = import.meta.url;
|
|
27
|
+
|
|
28
|
+
function commandAuthorization(param) {
|
|
29
|
+
return "AllowAuthenticated";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function commandTransition(param) {
|
|
33
|
+
return "Undeclared";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let traits = [];
|
|
37
|
+
|
|
38
|
+
let ShipmentSpec = {
|
|
39
|
+
Id: undefined,
|
|
40
|
+
name: name,
|
|
41
|
+
commandSchema: commandSchema,
|
|
42
|
+
eventSchema: eventSchema,
|
|
43
|
+
errorSchema: errorSchema,
|
|
44
|
+
moduleUrl: moduleUrl,
|
|
45
|
+
commandAuthorization: commandAuthorization,
|
|
46
|
+
commandTransition: commandTransition,
|
|
47
|
+
traits: traits
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
let moduleUrl$1 = import.meta.url;
|
|
51
|
+
|
|
52
|
+
function evolve(state, _event) {
|
|
53
|
+
return state + 1 | 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function decide(state, command) {
|
|
57
|
+
if (state !== 0) {
|
|
58
|
+
if (state !== 1) {
|
|
59
|
+
return {
|
|
60
|
+
TAG: "Ok",
|
|
61
|
+
_0: []
|
|
62
|
+
};
|
|
63
|
+
} else if (command === "Place") {
|
|
64
|
+
return {
|
|
65
|
+
TAG: "Ok",
|
|
66
|
+
_0: []
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
return {
|
|
70
|
+
TAG: "Ok",
|
|
71
|
+
_0: ["Shipped"]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
} else if (command === "Place") {
|
|
75
|
+
return {
|
|
76
|
+
TAG: "Ok",
|
|
77
|
+
_0: ["Placed"]
|
|
78
|
+
};
|
|
79
|
+
} else {
|
|
80
|
+
return {
|
|
81
|
+
TAG: "Ok",
|
|
82
|
+
_0: []
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let ShipmentBehavior = {
|
|
88
|
+
initialState: 0,
|
|
89
|
+
evolve: evolve,
|
|
90
|
+
decide: decide,
|
|
91
|
+
snapshot: undefined,
|
|
92
|
+
moduleUrl: moduleUrl$1
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
let M = EventMapping$Reventless.Mappings.Make({
|
|
96
|
+
name: name,
|
|
97
|
+
Id: Id$Reventless.$$String,
|
|
98
|
+
commandSchema: commandSchema
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
let moduleUrl$2 = import.meta.url;
|
|
102
|
+
|
|
103
|
+
function map(id, event, _queryEngine) {
|
|
104
|
+
if (event === "Placed") {
|
|
105
|
+
return [{
|
|
106
|
+
TAG: "Publish",
|
|
107
|
+
_0: id,
|
|
108
|
+
_1: "Ship"
|
|
109
|
+
}];
|
|
110
|
+
} else {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let AutoShip = {
|
|
116
|
+
Source: undefined,
|
|
117
|
+
map: map
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
let mappings = [{
|
|
121
|
+
Source: {
|
|
122
|
+
name: name,
|
|
123
|
+
Id: Id$Reventless.$$String,
|
|
124
|
+
eventSchema: eventSchema
|
|
125
|
+
},
|
|
126
|
+
map: map
|
|
127
|
+
}];
|
|
128
|
+
|
|
129
|
+
let ShipmentMappings = {
|
|
130
|
+
M: M,
|
|
131
|
+
moduleUrl: moduleUrl$2,
|
|
132
|
+
AutoShip: AutoShip,
|
|
133
|
+
mappings: mappings,
|
|
134
|
+
counter: undefined
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
let Bus = LocalBus$ReventlessLocal.Make({});
|
|
138
|
+
|
|
139
|
+
let publishedEvents = {
|
|
140
|
+
contents: 0
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
Bus.subscribeToEvents("TestShipmentAggrEventTopic", async (param, param$1, param$2) => {
|
|
144
|
+
publishedEvents.contents = publishedEvents.contents + 1 | 0;
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
TestRunner$ReventlessLocal.setup();
|
|
148
|
+
|
|
149
|
+
let ShipmentAggregateMaker = Aggregate_Builder$ReventlessLocal.Make(Bus);
|
|
150
|
+
|
|
151
|
+
let ShipmentAgg = ShipmentAggregateMaker.Make({
|
|
152
|
+
Id: Id$Reventless.$$String,
|
|
153
|
+
name: name,
|
|
154
|
+
eventSchema: eventSchema,
|
|
155
|
+
errorSchema: errorSchema,
|
|
156
|
+
commandSchema: commandSchema,
|
|
157
|
+
moduleUrl: moduleUrl,
|
|
158
|
+
commandAuthorization: commandAuthorization,
|
|
159
|
+
commandTransition: commandTransition,
|
|
160
|
+
traits: traits
|
|
161
|
+
})(ShipmentBehavior)({
|
|
162
|
+
moduleUrl: moduleUrl$2,
|
|
163
|
+
mappings: mappings,
|
|
164
|
+
counter: undefined
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
let agg = ShipmentAgg.make(undefined, undefined, undefined);
|
|
168
|
+
|
|
169
|
+
let aggOutputs = Component$ReventlessCore.outputs(agg);
|
|
170
|
+
|
|
171
|
+
aggOutputs.addEventMapper(Object.fromEntries([[
|
|
172
|
+
name,
|
|
173
|
+
aggOutputs.eventLog.eventTopic
|
|
174
|
+
]]), TestFixtures$ReventlessLocal.mockQueryEngine);
|
|
175
|
+
|
|
176
|
+
async function withTimeout(p, ms) {
|
|
177
|
+
let timeout = new Promise((resolve, param) => {
|
|
178
|
+
setTimeout(() => resolve({
|
|
179
|
+
TAG: "Error",
|
|
180
|
+
_0: "timed out"
|
|
181
|
+
}), ms);
|
|
182
|
+
});
|
|
183
|
+
return await Promise.race([
|
|
184
|
+
p.then(v => ({
|
|
185
|
+
TAG: "Ok",
|
|
186
|
+
_0: v
|
|
187
|
+
})),
|
|
188
|
+
timeout
|
|
189
|
+
]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export {
|
|
193
|
+
ShipmentSpec,
|
|
194
|
+
ShipmentBehavior,
|
|
195
|
+
ShipmentMappings,
|
|
196
|
+
Bus,
|
|
197
|
+
publishedEvents,
|
|
198
|
+
ShipmentAggregateMaker,
|
|
199
|
+
ShipmentAgg,
|
|
200
|
+
agg,
|
|
201
|
+
aggOutputs,
|
|
202
|
+
withTimeout,
|
|
203
|
+
}
|
|
204
|
+
/* commandSchema Not a pure module */
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Regression test for the event-mapping self-deadlock.
|
|
2
|
+
// See AggregateSelfMappingFixtures.res for the shape.
|
|
3
|
+
//
|
|
4
|
+
// Without the fix, publishing Place never returns: the mapper awaits the Ship
|
|
5
|
+
// it issues, and Ship's event waits for the mapper to dequeue it.
|
|
6
|
+
|
|
7
|
+
open TestFixtures
|
|
8
|
+
open JestGlobals
|
|
9
|
+
open AggregateSelfMappingFixtures
|
|
10
|
+
|
|
11
|
+
describe("Event mapping that commands its own source:", () => {
|
|
12
|
+
let _ = beforeAllAsync(async () => {
|
|
13
|
+
let _ = await agg->ShipmentAgg.operations->TestRunner.resolve
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
testPromise("Place returns, and the mapped Ship still runs", async () => {
|
|
17
|
+
let ops = await agg->ShipmentAgg.operations->TestRunner.resolve
|
|
18
|
+
let place = {
|
|
19
|
+
Reventless.Message.id: "shipment-1",
|
|
20
|
+
// The mapper finds its mappings by the event's service, as a real command's is.
|
|
21
|
+
meta: {...testMeta, service: ShipmentSpec.name},
|
|
22
|
+
commandJson: ShipmentSpec.Place->ReventlessCore.Message.encode(ShipmentSpec.commandSchema),
|
|
23
|
+
}
|
|
24
|
+
let outcome = await withTimeout(ops.publishJsons([place]), ~ms=1500)
|
|
25
|
+
expect(
|
|
26
|
+
switch outcome {
|
|
27
|
+
| Ok(_) => "ok"
|
|
28
|
+
| Error(msg) => msg
|
|
29
|
+
},
|
|
30
|
+
)->toBe("ok")
|
|
31
|
+
|
|
32
|
+
// The Ship command is detached; let it run.
|
|
33
|
+
let _ = await withTimeout(
|
|
34
|
+
Promise.make(
|
|
35
|
+
(resolve, _) => {
|
|
36
|
+
let _ = setTimeout(() => resolve(), 100)
|
|
37
|
+
},
|
|
38
|
+
),
|
|
39
|
+
~ms=1000,
|
|
40
|
+
)
|
|
41
|
+
expect(publishedEvents.contents)->toBe(2)
|
|
42
|
+
})
|
|
43
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
|
|
4
|
+
import * as TestRunner$ReventlessLocal from "../../../src/test/TestRunner.res.mjs";
|
|
5
|
+
import * as TestFixtures$ReventlessLocal from "../../TestFixtures.res.mjs";
|
|
6
|
+
import * as AggregateSelfMappingFixtures$ReventlessLocal from "./AggregateSelfMappingFixtures.res.mjs";
|
|
7
|
+
|
|
8
|
+
globalThis.describe("Event mapping that commands its own source:", () => {
|
|
9
|
+
globalThis.beforeAll(async () => {
|
|
10
|
+
await TestRunner$ReventlessLocal.resolve(AggregateSelfMappingFixtures$ReventlessLocal.ShipmentAgg.operations(AggregateSelfMappingFixtures$ReventlessLocal.agg));
|
|
11
|
+
});
|
|
12
|
+
globalThis.test("Place returns, and the mapped Ship still runs", async () => {
|
|
13
|
+
let ops = await TestRunner$ReventlessLocal.resolve(AggregateSelfMappingFixtures$ReventlessLocal.ShipmentAgg.operations(AggregateSelfMappingFixtures$ReventlessLocal.agg));
|
|
14
|
+
let newrecord = {...TestFixtures$ReventlessLocal.testMeta};
|
|
15
|
+
let place_meta = (newrecord.service = AggregateSelfMappingFixtures$ReventlessLocal.ShipmentSpec.name, newrecord);
|
|
16
|
+
let place_commandJson = Message$ReventlessCore.encode("Place", AggregateSelfMappingFixtures$ReventlessLocal.ShipmentSpec.commandSchema);
|
|
17
|
+
let place = {
|
|
18
|
+
id: "shipment-1",
|
|
19
|
+
meta: place_meta,
|
|
20
|
+
commandJson: place_commandJson
|
|
21
|
+
};
|
|
22
|
+
let outcome = await AggregateSelfMappingFixtures$ReventlessLocal.withTimeout(ops.publishJsons([place]), 1500);
|
|
23
|
+
let tmp;
|
|
24
|
+
tmp = outcome.TAG === "Ok" ? "ok" : outcome._0;
|
|
25
|
+
globalThis.expect(tmp).toBe("ok");
|
|
26
|
+
await AggregateSelfMappingFixtures$ReventlessLocal.withTimeout(new Promise((resolve, param) => {
|
|
27
|
+
setTimeout(() => resolve(), 100);
|
|
28
|
+
}), 1000);
|
|
29
|
+
globalThis.expect(AggregateSelfMappingFixtures$ReventlessLocal.publishedEvents.contents).toBe(2);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/* Not a pure module */
|
|
@@ -358,7 +358,6 @@ let publishJsonsOutput = Pulumi.output(publishJsons);
|
|
|
358
358
|
let PlaceMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
359
359
|
name: name,
|
|
360
360
|
moduleUrl: moduleUrl,
|
|
361
|
-
Id: Id$Reventless.$$String,
|
|
362
361
|
consumedEventSchema: consumedEventSchema,
|
|
363
362
|
errorSchema: errorSchema,
|
|
364
363
|
eventSchema: eventSchema,
|
|
@@ -379,7 +378,6 @@ let _placeSlice = PlaceMaker.make(dcbEventLog, publishJsonsOutput, undefined, un
|
|
|
379
378
|
let ShipMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
380
379
|
name: name$1,
|
|
381
380
|
moduleUrl: moduleUrl$2,
|
|
382
|
-
Id: Id$Reventless.$$String,
|
|
383
381
|
consumedEventSchema: consumedEventSchema$1,
|
|
384
382
|
errorSchema: errorSchema$1,
|
|
385
383
|
eventSchema: eventSchema$1,
|
|
@@ -1,7 +1,6 @@
|
|
|
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";
|
|
5
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
5
|
import * as Effect from "effect/Effect";
|
|
7
6
|
import * as Stream from "effect/Stream";
|
|
@@ -174,7 +173,6 @@ let eventLog = CatalogLogMaker.make("CatalogLog", ["tag_categoryId"], {
|
|
|
174
173
|
let AddProductMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
175
174
|
name: name,
|
|
176
175
|
moduleUrl: moduleUrl,
|
|
177
|
-
Id: Id$Reventless.$$String,
|
|
178
176
|
consumedEventSchema: consumedEventSchema,
|
|
179
177
|
errorSchema: errorSchema,
|
|
180
178
|
eventSchema: eventSchema$1,
|
|
@@ -1,7 +1,6 @@
|
|
|
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";
|
|
5
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
5
|
import * as Effect from "effect/Effect";
|
|
7
6
|
import * as Stream from "effect/Stream";
|
|
@@ -126,7 +125,6 @@ let eventLog = ItemEventLogMaker.make("ItemEventLog", undefined, {
|
|
|
126
125
|
let AddItemMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
127
126
|
name: name,
|
|
128
127
|
moduleUrl: moduleUrl,
|
|
129
|
-
Id: Id$Reventless.$$String,
|
|
130
128
|
consumedEventSchema: consumedEventSchema,
|
|
131
129
|
errorSchema: errorSchema,
|
|
132
130
|
eventSchema: eventSchema$1,
|
package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
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";
|
|
5
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
5
|
import * as Effect from "effect/Effect";
|
|
7
6
|
import * as Stream from "effect/Stream";
|
|
@@ -219,7 +218,6 @@ let publishJsonsOutput = Pulumi.output(publishJsons);
|
|
|
219
218
|
let PlaceMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
220
219
|
name: name,
|
|
221
220
|
moduleUrl: moduleUrl,
|
|
222
|
-
Id: Id$Reventless.$$String,
|
|
223
221
|
consumedEventSchema: consumedEventSchema,
|
|
224
222
|
errorSchema: errorSchema,
|
|
225
223
|
eventSchema: eventSchema,
|
|
@@ -93,10 +93,15 @@ module ProductsFromDcb = Mapping.Make(
|
|
|
93
93
|
ProductCatalogDcbSource,
|
|
94
94
|
ProductsReadModelSpec,
|
|
95
95
|
{
|
|
96
|
-
let project = (
|
|
96
|
+
let project = (
|
|
97
|
+
msg: Message.event'<ProductCatalogDcbSource.Id.t, ProductCatalogDcbSource.event>,
|
|
98
|
+
) =>
|
|
97
99
|
switch msg.event {
|
|
98
100
|
| ProductAdded({productId, name}) =>
|
|
99
|
-
Set(
|
|
101
|
+
Set(
|
|
102
|
+
ProductsReadModelSpec.Id.makeFromString(productId),
|
|
103
|
+
({productId, name}: ProductsReadModelSpec.state),
|
|
104
|
+
)
|
|
100
105
|
}
|
|
101
106
|
},
|
|
102
107
|
)
|
|
@@ -138,7 +138,7 @@ function project(msg) {
|
|
|
138
138
|
let productId = match.productId;
|
|
139
139
|
return {
|
|
140
140
|
TAG: "Set",
|
|
141
|
-
_0: productId,
|
|
141
|
+
_0: Id$Reventless.$$String.makeFromString(productId),
|
|
142
142
|
_1: {
|
|
143
143
|
productId: productId,
|
|
144
144
|
name: match.name
|
|
@@ -191,7 +191,6 @@ let dcbEventLog = DcbLogMaker.make("ProductCatalog", undefined, {
|
|
|
191
191
|
let AddProductMaker = StateChangeSlice_Builder$ReventlessLocal.Make({
|
|
192
192
|
name: name,
|
|
193
193
|
moduleUrl: moduleUrl,
|
|
194
|
-
Id: Id$Reventless.$$String,
|
|
195
194
|
consumedEventSchema: consumedEventSchema,
|
|
196
195
|
errorSchema: errorSchema,
|
|
197
196
|
eventSchema: eventSchema,
|
|
@@ -42,9 +42,10 @@ module TypoMapping = Mapping.Make(
|
|
|
42
42
|
TypoSource,
|
|
43
43
|
RmSpec,
|
|
44
44
|
{
|
|
45
|
-
let project = (msg: Message.event'<
|
|
45
|
+
let project = (msg: Message.event'<TypoSource.Id.t, TypoSource.event>) =>
|
|
46
46
|
switch msg.event {
|
|
47
|
-
| ProductAdded({productId, name}) =>
|
|
47
|
+
| ProductAdded({productId, name}) =>
|
|
48
|
+
Set(RmSpec.Id.makeFromString(productId), ({productId, name}: RmSpec.state))
|
|
48
49
|
}
|
|
49
50
|
},
|
|
50
51
|
)
|
|
@@ -61,7 +61,7 @@ module AggregateMapping = Mapping.Make(
|
|
|
61
61
|
AggregateSource,
|
|
62
62
|
MixedReadModelSpec,
|
|
63
63
|
{
|
|
64
|
-
let project = (msg: Message.event'<
|
|
64
|
+
let project = (msg: Message.event'<AggregateSource.Id.t, AggregateSource.event>) =>
|
|
65
65
|
switch msg.event {
|
|
66
66
|
| AggregateItemCreated({name}) =>
|
|
67
67
|
Create(msg.id, ({name, source: "aggregate"}: MixedReadModelSpec.state))
|
|
@@ -78,7 +78,7 @@ module DcbMapping = Mapping.Make(
|
|
|
78
78
|
DcbSource,
|
|
79
79
|
MixedReadModelSpec,
|
|
80
80
|
{
|
|
81
|
-
let project = (msg: Message.event'<
|
|
81
|
+
let project = (msg: Message.event'<DcbSource.Id.t, DcbSource.event>) =>
|
|
82
82
|
switch msg.event {
|
|
83
83
|
| DcbItemAdded({name}) => Create(msg.id, ({name, source: "dcb"}: MixedReadModelSpec.state))
|
|
84
84
|
| DcbItemNameChanged({name}) => Update(msg.id, state => {...state, name})
|
|
@@ -43,7 +43,7 @@ module ItemMapping = Mapping.Make(
|
|
|
43
43
|
ItemEventSource,
|
|
44
44
|
ItemReadModelSpec,
|
|
45
45
|
{
|
|
46
|
-
let project = (msg: Message.event'<
|
|
46
|
+
let project = (msg: Message.event'<ItemEventSource.Id.t, ItemEventSource.event>) =>
|
|
47
47
|
switch msg.event {
|
|
48
48
|
| ItemCreated({name}) => Create(msg.id, ({name: name}: ItemReadModelSpec.state))
|
|
49
49
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
4
|
import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
|
|
5
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
7
8
|
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
@@ -63,6 +64,7 @@ let stateSchema$1 = Sury.$Metadata_set(stateSchema, DisplayName$Reventless.displ
|
|
|
63
64
|
let config = ReadModel$Reventless.config(undefined, undefined, undefined);
|
|
64
65
|
|
|
65
66
|
let OrdersViewSpec = {
|
|
67
|
+
Key: undefined,
|
|
66
68
|
name: name,
|
|
67
69
|
moduleUrl: moduleUrl,
|
|
68
70
|
consumedEventSchema: consumedEventSchema,
|
|
@@ -128,6 +130,13 @@ let OrdersViewMaker = SVMaker.Make({
|
|
|
128
130
|
name: name,
|
|
129
131
|
moduleUrl: moduleUrl,
|
|
130
132
|
stateSchema: stateSchema$1,
|
|
133
|
+
Key: {
|
|
134
|
+
schema: Id$Reventless.StringPure.schema,
|
|
135
|
+
make: prim => prim,
|
|
136
|
+
makeFromString: prim => prim,
|
|
137
|
+
toString: prim => prim,
|
|
138
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
139
|
+
},
|
|
131
140
|
consumedEventSchema: consumedEventSchema,
|
|
132
141
|
config: config,
|
|
133
142
|
subIdConfig: undefined,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
4
|
import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
|
|
5
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
7
8
|
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
@@ -63,6 +64,7 @@ let stateSchema = Sury.$schema(s => ({
|
|
|
63
64
|
let config = ReadModel$Reventless.config(undefined, undefined, undefined);
|
|
64
65
|
|
|
65
66
|
let ItemsViewSpec = {
|
|
67
|
+
Key: undefined,
|
|
66
68
|
name: name,
|
|
67
69
|
moduleUrl: moduleUrl,
|
|
68
70
|
consumedEventSchema: consumedEventSchema,
|
|
@@ -131,6 +133,13 @@ let ItemsViewMaker = SVMaker.Make({
|
|
|
131
133
|
name: name,
|
|
132
134
|
moduleUrl: moduleUrl,
|
|
133
135
|
stateSchema: stateSchema,
|
|
136
|
+
Key: {
|
|
137
|
+
schema: Id$Reventless.StringPure.schema,
|
|
138
|
+
make: prim => prim,
|
|
139
|
+
makeFromString: prim => prim,
|
|
140
|
+
toString: prim => prim,
|
|
141
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
142
|
+
},
|
|
134
143
|
consumedEventSchema: consumedEventSchema,
|
|
135
144
|
config: config,
|
|
136
145
|
subIdConfig: undefined,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
4
|
import * as Stream from "@reventlessdev/rescript-effect/src/Stream.res.mjs";
|
|
5
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
7
8
|
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
@@ -68,6 +69,7 @@ let subIdConfig = {
|
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
let ScoresViewSpec = {
|
|
72
|
+
Key: undefined,
|
|
71
73
|
name: name,
|
|
72
74
|
moduleUrl: moduleUrl,
|
|
73
75
|
consumedEventSchema: consumedEventSchema,
|
|
@@ -126,6 +128,13 @@ let ScoresViewMaker = SVMaker.Make({
|
|
|
126
128
|
name: name,
|
|
127
129
|
moduleUrl: moduleUrl,
|
|
128
130
|
stateSchema: stateSchema,
|
|
131
|
+
Key: {
|
|
132
|
+
schema: Id$Reventless.StringPure.schema,
|
|
133
|
+
make: prim => prim,
|
|
134
|
+
makeFromString: prim => prim,
|
|
135
|
+
toString: prim => prim,
|
|
136
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
137
|
+
},
|
|
129
138
|
consumedEventSchema: consumedEventSchema,
|
|
130
139
|
config: config,
|
|
131
140
|
subIdConfig: subIdConfig,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
3
4
|
import * as UiFragments$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateView/UiFragments.res.mjs";
|
|
4
5
|
import * as Projection_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Projection_GWT.res.mjs";
|
|
5
6
|
import * as Plugin_Fixtures$ReventlessLocal from "./Plugin_Fixtures.res.mjs";
|
|
@@ -8,6 +9,13 @@ import * as UiFragments_Projection$ReventlessCore from "@reventlessdev/reventles
|
|
|
8
9
|
let Test = Projection_GWT$ReventlessGwt.Make({
|
|
9
10
|
name: UiFragments$ReventlessCore.name,
|
|
10
11
|
stateSchema: UiFragments$ReventlessCore.stateSchema,
|
|
12
|
+
Key: {
|
|
13
|
+
schema: Id$Reventless.StringPure.schema,
|
|
14
|
+
make: prim => prim,
|
|
15
|
+
makeFromString: prim => prim,
|
|
16
|
+
toString: prim => prim,
|
|
17
|
+
cmp: Id$Reventless.StringPure.cmp
|
|
18
|
+
},
|
|
11
19
|
consumedEventSchema: UiFragments$ReventlessCore.consumedEventSchema,
|
|
12
20
|
subIdConfig: undefined
|
|
13
21
|
})({
|