@reventlessdev/reventless-core 3.0.0-alpha.237 → 3.0.0-alpha.239
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 +24 -0
- package/package.json +8 -8
- package/src/Message.res +1 -1
- package/src/adapter/Monitoring/Monitoring.res +1 -1
- package/src/admin/Platform_Admin_Structure.res +1 -0
- package/src/admin/Platform_Admin_Structure.res.mjs +1 -0
- package/src/admin/Platform_ComponentDefinitionsApi.res +2 -1
- package/src/admin/Platform_ComponentDefinitionsApi.res.mjs +5 -1
- package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res +1 -1
- package/src/components/Aggregate/Aggregate_Callback.res +2 -2
- package/src/components/Api/ApiAllowedStatesHelpers.res +2 -3
- package/src/components/Api/ApiTargetStateHelpers.res +4 -3
- package/src/components/Api/GraphQL_FragmentGenerator.res +122 -12
- package/src/components/Api/GraphQL_FragmentGenerator.res.mjs +41 -8
- package/src/components/Api/SuryToJsonSchema.res +8 -0
- package/src/components/Api/SuryToJsonSchema.res.mjs +8 -4
- package/src/components/Dcb/Dcb_Builder.res +79 -16
- package/src/components/Dcb/Dcb_Builder.res.mjs +41 -5
- package/src/components/EventLog/EventLog.res +1 -1
- package/src/plugin/component/Plugin_Builder.res +7 -0
- package/src/plugin/component/Plugin_Builder.res.mjs +3 -1
- package/src/plugin/component/Plugin_Structure.res +376 -27
- package/src/plugin/component/Plugin_Structure.res.mjs +175 -8
- package/src/plugin/connect/PluginExtensionPoint_UiFragment.res +1 -1
- package/tests/admin/Platform_BakedManifestTest.res +1 -0
- package/tests/admin/Platform_BakedManifestTest.res.mjs +1 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +3 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +6 -0
- package/tests/admin/Platform_PluginStructuresApiTest.res +1 -0
- package/tests/admin/Platform_PluginStructuresApiTest.res.mjs +2 -0
- package/tests/aggregate/AggregateCacheTest.res +1 -1
- package/tests/aggregate/AggregateSnapshotTest.res +1 -1
- package/tests/api/GraphQL_FragmentGeneratorTest.res +171 -0
- package/tests/api/GraphQL_FragmentGeneratorTest.res.mjs +108 -0
- package/tests/api/SuryToJsonSchemaTest.res +30 -3
- package/tests/api/SuryToJsonSchemaTest.res.mjs +49 -4
- package/tests/commandgenerator/OwnerStampingTest.res +57 -0
- package/tests/commandgenerator/OwnerStampingTest.res.mjs +19 -0
- package/tests/message/MessageTest.res +1 -1
- package/tests/plugin/HeartbeatDisconnectGraceTest.res +1 -1
- package/tests/plugin/PluginStructureTest.res +268 -4
- package/tests/plugin/PluginStructureTest.res.mjs +284 -3
- package/tests/plugin/StateChangeSlice/PsDispatchShipment.res +31 -0
- package/tests/plugin/StateChangeSlice/PsDispatchShipment.res.mjs +73 -0
- package/tests/plugin/StateChangeSlice/PsShipOrder.res +16 -1
- package/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs +7 -2
- package/tests/plugin/StateViewSlice/PsShipmentsView.res +26 -0
- package/tests/plugin/StateViewSlice/PsShipmentsView.res.mjs +101 -0
- package/tests/util/CsvStreamTest.res +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Test fixture spec for the @transition cross-check — the failing case.
|
|
2
|
+
//
|
|
3
|
+
// `Dispatchd` is a deliberate typo. It compiles: the PPX strips the attribute
|
|
4
|
+
// before the typechecker sees it, so a misspelled state is a well-formed string
|
|
5
|
+
// all the way down. That is exactly the hole the structure-side check closes,
|
|
6
|
+
// and a fixture that could not compile would not demonstrate it.
|
|
7
|
+
|
|
8
|
+
@@reventless.spec("DispatchShipment")
|
|
9
|
+
|
|
10
|
+
type shipmentStatus =
|
|
11
|
+
| Booked
|
|
12
|
+
| Dispatched
|
|
13
|
+
|
|
14
|
+
@schema
|
|
15
|
+
type consumedEvent = ShipmentBooked({shipmentId: string})
|
|
16
|
+
|
|
17
|
+
let evolve = (_state, _event) => true
|
|
18
|
+
|
|
19
|
+
type state = bool
|
|
20
|
+
let initialState = false
|
|
21
|
+
|
|
22
|
+
@schema
|
|
23
|
+
type command = @transition(([Booked]) => Dispatchd) DispatchShipment({shipmentId: string})
|
|
24
|
+
|
|
25
|
+
@schema
|
|
26
|
+
type error = ShipmentNotFound
|
|
27
|
+
|
|
28
|
+
@schema
|
|
29
|
+
type event = ShipmentDispatched({shipmentId: string})
|
|
30
|
+
|
|
31
|
+
let decide = (_state, _command): result<array<event>, error> => Ok([])
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
5
|
+
import * as Api$ReventlessInfra from "@reventlessdev/reventless-infra/src/components/Api.res.mjs";
|
|
6
|
+
|
|
7
|
+
let consumedEventSchema = S.schema(s => ({
|
|
8
|
+
TAG: "ShipmentBooked",
|
|
9
|
+
shipmentId: s.m(DcbTag$Reventless.string)
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
function evolve(_state, _event) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let commandSchema = S.schema(s => ({
|
|
17
|
+
TAG: "DispatchShipment",
|
|
18
|
+
shipmentId: s.m(DcbTag$Reventless.string)
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
let errorSchema = S.literal("ShipmentNotFound");
|
|
22
|
+
|
|
23
|
+
let eventSchema = S.schema(s => ({
|
|
24
|
+
TAG: "ShipmentDispatched",
|
|
25
|
+
shipmentId: s.m(DcbTag$Reventless.string)
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
function decide(_state, _command) {
|
|
29
|
+
return {
|
|
30
|
+
TAG: "Ok",
|
|
31
|
+
_0: []
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let commandSchema$1 = Api$ReventlessInfra.markAllowedStates(commandSchema, [[
|
|
36
|
+
"DispatchShipment",
|
|
37
|
+
["Booked"]
|
|
38
|
+
]]);
|
|
39
|
+
|
|
40
|
+
let commandSchema$2 = Api$ReventlessInfra.markTargetState(commandSchema$1, [[
|
|
41
|
+
"DispatchShipment",
|
|
42
|
+
"Dispatchd"
|
|
43
|
+
]]);
|
|
44
|
+
|
|
45
|
+
function commandAuthorization(param) {
|
|
46
|
+
return "AllowAuthenticated";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let name = "DispatchShipment";
|
|
50
|
+
|
|
51
|
+
let Id;
|
|
52
|
+
|
|
53
|
+
let initialState = false;
|
|
54
|
+
|
|
55
|
+
let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsDispatchShipment.res.mjs";
|
|
56
|
+
|
|
57
|
+
let readConsistency = "EscalateOnRetry";
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
name,
|
|
61
|
+
Id,
|
|
62
|
+
consumedEventSchema,
|
|
63
|
+
evolve,
|
|
64
|
+
initialState,
|
|
65
|
+
errorSchema,
|
|
66
|
+
eventSchema,
|
|
67
|
+
decide,
|
|
68
|
+
commandSchema$2 as commandSchema,
|
|
69
|
+
moduleUrl,
|
|
70
|
+
commandAuthorization,
|
|
71
|
+
readConsistency,
|
|
72
|
+
}
|
|
73
|
+
/* consumedEventSchema Not a pure module */
|
|
@@ -18,8 +18,23 @@ let evolve = (_state, _event) => true
|
|
|
18
18
|
// It is also `@noApi` (internal/admin only): a two-variant slice with exactly
|
|
19
19
|
// one API-exposed command, which is the case that used to leak the exposed
|
|
20
20
|
// command's slice mutation field onto the non-exposed variant.
|
|
21
|
+
// The lifecycle this slice's commands move a shipment through. The PPX strips
|
|
22
|
+
// @transition before the typechecker sees it, so this enum is not what makes the
|
|
23
|
+
// reference below valid — the structure-side check against the linked view is.
|
|
24
|
+
// It is here because a state is a constructor, and naming one in a string is a
|
|
25
|
+
// reference nothing can check at any layer.
|
|
26
|
+
type shipmentStatus = Placed | Shipped | Cancelled
|
|
27
|
+
|
|
28
|
+
// CancelShipment is payload-less — it compiles to a bare string literal, so it
|
|
29
|
+
// exercises toCommandDef's payload-less branch (still surfaced in `commands`).
|
|
30
|
+
// It is also `@noApi` (internal/admin only): a two-variant slice with exactly
|
|
31
|
+
// one API-exposed command, which is the case that used to leak the exposed
|
|
32
|
+
// command's slice mutation field onto the non-exposed variant. It carries no
|
|
33
|
+
// @transition, which is the un-annotated case the resolver still guesses for.
|
|
21
34
|
@schema
|
|
22
|
-
type command =
|
|
35
|
+
type command =
|
|
36
|
+
| @transition(([Placed]) => Shipped) ShipOrder({orderId: string})
|
|
37
|
+
| @noApi CancelShipment
|
|
23
38
|
|
|
24
39
|
// Two variants, one payload-less and one carrying a field — the same two branches
|
|
25
40
|
// `events` exercises, so the structure's `errors` list is pinned on both.
|
|
@@ -47,7 +47,12 @@ function decide(_state, _command) {
|
|
|
47
47
|
|
|
48
48
|
let commandSchema$1 = Api$ReventlessInfra.markNoApiVariants(commandSchema, ["CancelShipment"]);
|
|
49
49
|
|
|
50
|
-
let commandSchema$2 = Api$ReventlessInfra.
|
|
50
|
+
let commandSchema$2 = Api$ReventlessInfra.markAllowedStates(commandSchema$1, [[
|
|
51
|
+
"ShipOrder",
|
|
52
|
+
["Placed"]
|
|
53
|
+
]]);
|
|
54
|
+
|
|
55
|
+
let commandSchema$3 = Api$ReventlessInfra.markTargetState(commandSchema$2, [[
|
|
51
56
|
"ShipOrder",
|
|
52
57
|
"Shipped"
|
|
53
58
|
]]);
|
|
@@ -75,7 +80,7 @@ export {
|
|
|
75
80
|
errorSchema,
|
|
76
81
|
eventSchema,
|
|
77
82
|
decide,
|
|
78
|
-
commandSchema$
|
|
83
|
+
commandSchema$3 as commandSchema,
|
|
79
84
|
moduleUrl,
|
|
80
85
|
commandAuthorization,
|
|
81
86
|
readConsistency,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Test fixture spec for the @transition cross-check.
|
|
2
|
+
// A view that declares a lifecycle, so a command's declared states have
|
|
3
|
+
// something to be checked against. `PsOrdersView` deliberately declares none —
|
|
4
|
+
// the two together cover both the checked and the unvalidated path.
|
|
5
|
+
|
|
6
|
+
@@reventless.spec("Shipments")
|
|
7
|
+
|
|
8
|
+
@schema
|
|
9
|
+
type consumedEvent =
|
|
10
|
+
| ShipmentBooked({shipmentId: string})
|
|
11
|
+
| ShipmentDispatched({shipmentId: string})
|
|
12
|
+
|
|
13
|
+
@schema
|
|
14
|
+
type shipmentStatus =
|
|
15
|
+
| Booked
|
|
16
|
+
| Dispatched
|
|
17
|
+
|
|
18
|
+
@schema
|
|
19
|
+
type state = {shipmentId: string, @lifecycle shipmentStatus: shipmentStatus}
|
|
20
|
+
|
|
21
|
+
let project = ({event}: Reventless.StateViewSlice.consumed<consumedEvent>) =>
|
|
22
|
+
switch event {
|
|
23
|
+
| ShipmentBooked({shipmentId}) => [Set(shipmentId, {shipmentId, shipmentStatus: Booked})]
|
|
24
|
+
| ShipmentDispatched({shipmentId}) =>
|
|
25
|
+
[Update(shipmentId, s => {...s, shipmentStatus: Dispatched})]
|
|
26
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
5
|
+
import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
|
|
6
|
+
import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
|
|
7
|
+
|
|
8
|
+
let consumedEventSchema = S.union([
|
|
9
|
+
S.schema(s => ({
|
|
10
|
+
TAG: "ShipmentBooked",
|
|
11
|
+
shipmentId: s.m(DcbTag$Reventless.string)
|
|
12
|
+
})),
|
|
13
|
+
S.schema(s => ({
|
|
14
|
+
TAG: "ShipmentDispatched",
|
|
15
|
+
shipmentId: s.m(DcbTag$Reventless.string)
|
|
16
|
+
}))
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
let shipmentStatusSchema = S.union([
|
|
20
|
+
S.literal("Booked"),
|
|
21
|
+
S.literal("Dispatched")
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
let stateSchema = S.schema(s => ({
|
|
25
|
+
shipmentId: s.m(S.string),
|
|
26
|
+
shipmentStatus: s.m(shipmentStatusSchema)
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
function project(param) {
|
|
30
|
+
let event = param.event;
|
|
31
|
+
if (event.TAG !== "ShipmentBooked") {
|
|
32
|
+
return [{
|
|
33
|
+
TAG: "Update",
|
|
34
|
+
_0: event.shipmentId,
|
|
35
|
+
_1: s => ({
|
|
36
|
+
shipmentId: s.shipmentId,
|
|
37
|
+
shipmentStatus: "Dispatched"
|
|
38
|
+
})
|
|
39
|
+
}];
|
|
40
|
+
}
|
|
41
|
+
let shipmentId = event.shipmentId;
|
|
42
|
+
return [{
|
|
43
|
+
TAG: "Set",
|
|
44
|
+
_0: shipmentId,
|
|
45
|
+
_1: {
|
|
46
|
+
shipmentId: shipmentId,
|
|
47
|
+
shipmentStatus: "Booked"
|
|
48
|
+
}
|
|
49
|
+
}];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let config = ReadModel$Reventless.config(undefined, undefined, undefined);
|
|
53
|
+
|
|
54
|
+
let stateSchema$1 = S.Metadata.set(stateSchema, StateAnnotations$Reventless.stateAnnotationsId, {
|
|
55
|
+
ids: [],
|
|
56
|
+
compositeIds: [],
|
|
57
|
+
subIds: [],
|
|
58
|
+
compositeSubIds: [],
|
|
59
|
+
indexes: [],
|
|
60
|
+
hidden: [],
|
|
61
|
+
summary: [],
|
|
62
|
+
drillTargets: [],
|
|
63
|
+
drillTargetKeys: [],
|
|
64
|
+
collapsed: [],
|
|
65
|
+
scan: [],
|
|
66
|
+
scanSort: [],
|
|
67
|
+
semantic: [],
|
|
68
|
+
metric: [],
|
|
69
|
+
lifecycle: "shipmentStatus",
|
|
70
|
+
groupBy: undefined,
|
|
71
|
+
visibility: undefined,
|
|
72
|
+
live: undefined,
|
|
73
|
+
retired: undefined
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
let name = "Shipments";
|
|
77
|
+
|
|
78
|
+
let Id;
|
|
79
|
+
|
|
80
|
+
let subIdConfig;
|
|
81
|
+
|
|
82
|
+
let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsShipmentsView.res.mjs";
|
|
83
|
+
|
|
84
|
+
let authorization = "AllowAuthenticated";
|
|
85
|
+
|
|
86
|
+
let visibility = "Public";
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
name,
|
|
90
|
+
Id,
|
|
91
|
+
consumedEventSchema,
|
|
92
|
+
shipmentStatusSchema,
|
|
93
|
+
project,
|
|
94
|
+
config,
|
|
95
|
+
subIdConfig,
|
|
96
|
+
stateSchema$1 as stateSchema,
|
|
97
|
+
moduleUrl,
|
|
98
|
+
authorization,
|
|
99
|
+
visibility,
|
|
100
|
+
}
|
|
101
|
+
/* consumedEventSchema Not a pure module */
|