@reventlessdev/reventless-core 3.0.0-alpha.301 → 3.0.0-alpha.302
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 +18 -0
- package/package.json +6 -6
- package/src/adapter/Runtime/AggregateRuntime_Builder.res +2 -2
- package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res +10 -5
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +2 -2
- package/src/adapter/Runtime/EventCollectorRuntime_Builder.res +1 -1
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +8 -3
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder.res +1 -1
- package/src/adapter/Runtime/PluginRuntime_Builder.res +3 -3
- package/src/adapter/Runtime/Runtime.res +10 -9
- package/src/adapter/Runtime/TaskRuntime_Builder.res +1 -1
- package/src/admin/Platform_Admin_Structure.res +3 -3
- package/src/admin/Platform_Admin_Structure.res.mjs +1 -1
- package/src/admin/Platform_BakedManifest.res +7 -7
- package/src/admin/Platform_BakedManifest.res.mjs +2 -2
- package/src/admin/Platform_ComponentDefinitionsApi.res +12 -12
- package/src/admin/Platform_ComponentDefinitionsApi.res.mjs +11 -11
- package/src/admin/Platform_PluginStructuresApi.res +6 -6
- package/src/admin/Platform_PluginStructuresApi.res.mjs +4 -4
- package/src/admin/UiFragmentRegistry/StateView/UiFragments.res.mjs +1 -4
- package/src/components/Api/SuryToJsonSchema.res +1 -1
- package/src/components/CommandGenerator/CommandGenerator.res +1 -1
- package/src/components/CommandGenerator/CommandGenerator_Adapter.res +6 -1
- package/src/components/CommandTopic/CommandTopic.res +2 -2
- package/src/components/CommandTopic/CommandTopic_Adapter.res +1 -1
- package/src/components/EventCollector/EventCollector.res +1 -1
- package/src/components/EventCollector/EventCollector_Adapter.res +1 -1
- package/src/components/Heartbeat/Heartbeat.res +1 -1
- package/src/components/ReadModel/ReadModel.res +1 -1
- package/src/components/StateViewSlice/StateViewSlice_Builder.res +2 -2
- package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +1 -1
- package/src/components/StateViewSlice/StateViewSlice_Callback.res +2 -2
- package/src/components/StateViewSlice/StateViewSlice_Callback.res.mjs +1 -1
- package/src/components/Task/Task_Adapter.res +1 -1
- package/src/components/Task/Task_Builder.res +1 -1
- package/src/plugin/component/Plugin_Builder.res +7 -7
- package/src/plugin/component/Plugin_Builder.res.mjs +3 -3
- package/src/plugin/component/Plugin_BuiltHook.res +1 -1
- package/src/plugin/component/Plugin_Structure.res +18 -18
- package/src/plugin/component/Plugin_Structure.res.mjs +8 -8
- package/tests/admin/AdminApiSchemaDriftTest.res +8 -8
- package/tests/admin/AdminApiSchemaDriftTest.res.mjs +54 -54
- package/tests/admin/Platform_Admin_StructureTest.res +10 -10
- package/tests/admin/Platform_Admin_StructureTest.res.mjs +5 -5
- package/tests/admin/Platform_BakedManifestTest.res +7 -7
- package/tests/admin/Platform_BakedManifestTest.res.mjs +9 -9
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +11 -11
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +5 -5
- package/tests/admin/Platform_PluginStructuresApiTest.res +3 -3
- package/tests/message/MessageTest.res +1 -1
- package/tests/plugin/ManifestVisibilityTest.res +2 -2
- package/tests/plugin/PluginStructureAccessTest.res.mjs +2 -2
- package/tests/plugin/PluginStructureTest.res +9 -9
- package/tests/plugin/PluginStructureTest.res.mjs +7 -7
- package/tests/plugin/StateView/PsAnnotatedView.res +1 -1
- package/tests/plugin/StateView/PsAnnotatedView.res.mjs +1 -4
- package/tests/plugin/StateView/PsAvailableProductsView.res.mjs +1 -4
- package/tests/plugin/StateView/PsCategoriesView.res.mjs +1 -4
- package/tests/plugin/StateView/PsCustomersView.res.mjs +1 -4
- package/tests/plugin/StateView/PsGatedView.res.mjs +1 -4
- package/tests/plugin/StateView/PsOrdersView.res.mjs +1 -4
- package/tests/plugin/StateView/PsShipmentsView.res.mjs +1 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
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.302 (2026-10-21)
|
|
7
|
+
|
|
8
|
+
* feat!: a state view's row key is module Id ([08c9726](https://github.com/ReventlessDev/reventless-core/commit/08c972659a3d689a39fd5e2f2026597155e92210))
|
|
9
|
+
* feat!: a plugin structure's component definitions are read-side and write-side defs ([ea2ab69](https://github.com/ReventlessDev/reventless-core/commit/ea2ab69e928ba16d7e640e4c66ab0e9ba034fe5c))
|
|
10
|
+
|
|
11
|
+
### BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* a state view spec declares its row key as module Id. A
|
|
14
|
+
hand-written module Key in a spec under StateView/ or StateViewStream/
|
|
15
|
+
fails the build with "A state view's row key is `module Id`, not
|
|
16
|
+
`module Key`".
|
|
17
|
+
* Plugin.queryableDef, Plugin.writableDef, their schemas,
|
|
18
|
+
isPublicQueryable and encodeQueryableDef no longer exist; a reader names
|
|
19
|
+
readSideDef, writeSideDef, isPublicReadSide and encodeReadSideDef. There
|
|
20
|
+
are no aliases, so the compiler lists every reader.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
6
24
|
# 3.0.0-alpha.301 (2026-10-21)
|
|
7
25
|
|
|
8
26
|
* feat!: the write-side logic module is called the decision, and a codemod moves an app over ([cb573ff](https://github.com/ReventlessDev/reventless-core/commit/cb573ff5b928c7d7f3e75988dfaa65066f8c95eb))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.302",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -28,22 +28,22 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"sury": "11.0.0",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
|
-
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.23",
|
|
32
31
|
"@reventlessdev/rescript-effect": "1.0.0-alpha.1",
|
|
32
|
+
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
|
|
33
|
+
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.23",
|
|
33
34
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.13",
|
|
34
35
|
"@reventlessdev/rescript-node": "2.0.0-alpha.23",
|
|
35
|
-
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
|
|
36
36
|
"@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
|
|
37
37
|
"@reventlessdev/rescript-ssh2": "2.0.0-alpha.24",
|
|
38
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.198",
|
|
39
38
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
39
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.199",
|
|
40
40
|
"@reventlessdev/reventless-interop": "3.0.0-alpha.42",
|
|
41
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
41
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.171"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "12.3.1",
|
|
45
45
|
"sury-ppx": "11.0.0",
|
|
46
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
46
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.104"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"rescript": "^12.3.1"
|
|
@@ -10,12 +10,12 @@ module type T = {
|
|
|
10
10
|
CommandGenerator.component,
|
|
11
11
|
>
|
|
12
12
|
let forCommandTopic: Runtime.forComponent<
|
|
13
|
-
Runtime.
|
|
13
|
+
Runtime.effectInvocationHandler<CommandTopicChannel.callbackEvent, context, unit, string>,
|
|
14
14
|
runtimeParts,
|
|
15
15
|
CommandTopic.component<'op>,
|
|
16
16
|
>
|
|
17
17
|
let forEventCollector: Runtime.forEventCollector<
|
|
18
|
-
Runtime.
|
|
18
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
19
19
|
EventCollector.component,
|
|
20
20
|
>
|
|
21
21
|
let finish: unit => unit
|
|
@@ -24,16 +24,21 @@ module Make = (
|
|
|
24
24
|
memorySize: int,
|
|
25
25
|
timeout: int,
|
|
26
26
|
}
|
|
27
|
-
type
|
|
27
|
+
type effectInvocationHandler = Runtime.effectInvocationHandler<
|
|
28
|
+
RuntimeEnvironment.event,
|
|
29
|
+
context,
|
|
30
|
+
unit,
|
|
31
|
+
string,
|
|
32
|
+
>
|
|
28
33
|
|
|
29
34
|
// Event collectors nested under this aggregate belong to their own element (a
|
|
30
35
|
// ReadModel, an EventMapper, …), so they carry the comp resolved at registration
|
|
31
36
|
// time rather than the hosting aggregate's.
|
|
32
|
-
type registeredHandler = {comp: string, handler:
|
|
37
|
+
type registeredHandler = {comp: string, handler: effectInvocationHandler}
|
|
33
38
|
|
|
34
39
|
let runtimeSpecs: dict<runtimeSpec> = Dict.make()
|
|
35
40
|
let commandGeneratorHandlers: dict<CommandGenerator.effectEventHandler<context>> = Dict.make()
|
|
36
|
-
let commandTopicHandlers: dict<
|
|
41
|
+
let commandTopicHandlers: dict<effectInvocationHandler> = Dict.make()
|
|
37
42
|
let eventCollectorHandlers: dict<array<registeredHandler>> = Dict.make()
|
|
38
43
|
|
|
39
44
|
let aggregateHandler = aggregateName =>
|
|
@@ -197,7 +202,7 @@ module Make = (
|
|
|
197
202
|
|
|
198
203
|
let forCommandTopic = (
|
|
199
204
|
~handler: Pulumi.Output.t<
|
|
200
|
-
Runtime.
|
|
205
|
+
Runtime.effectInvocationHandler<CommandTopicChannel.callbackEvent, context, unit, string>,
|
|
201
206
|
>,
|
|
202
207
|
~connect,
|
|
203
208
|
~memorySize=1024,
|
|
@@ -228,7 +233,7 @@ module Make = (
|
|
|
228
233
|
}
|
|
229
234
|
let forEventCollector = (
|
|
230
235
|
~handler: Pulumi.Output.t<
|
|
231
|
-
Runtime.
|
|
236
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
232
237
|
>,
|
|
233
238
|
~eventTopics: EventTopic.allOutputs,
|
|
234
239
|
~resources: array<ReventlessInfra.Adapter.resource>,
|
|
@@ -45,7 +45,7 @@ module Make = (
|
|
|
45
45
|
}
|
|
46
46
|
let forCommandTopic = (
|
|
47
47
|
~handler: Pulumi.Output.t<
|
|
48
|
-
Runtime.
|
|
48
|
+
Runtime.effectInvocationHandler<CommandTopicChannel.callbackEvent, context, unit, string>,
|
|
49
49
|
>,
|
|
50
50
|
~connect,
|
|
51
51
|
~memorySize=1024,
|
|
@@ -76,7 +76,7 @@ module Make = (
|
|
|
76
76
|
|
|
77
77
|
let forEventCollector = (
|
|
78
78
|
~handler: Pulumi.Output.t<
|
|
79
|
-
Runtime.
|
|
79
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
80
80
|
>,
|
|
81
81
|
~eventTopics: EventTopic.allOutputs,
|
|
82
82
|
~resources: array<ReventlessInfra.Adapter.resource>,
|
|
@@ -4,7 +4,7 @@ module type T = {
|
|
|
4
4
|
module EventCollectorChannel: EventCollector_Adapter.Channel
|
|
5
5
|
|
|
6
6
|
let forEventCollector: Runtime.forEventCollector<
|
|
7
|
-
Runtime.
|
|
7
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
8
8
|
EventCollector.component,
|
|
9
9
|
>
|
|
10
10
|
let finish: unit => unit
|
|
@@ -33,12 +33,17 @@ module Make = (
|
|
|
33
33
|
maxMemorySize: 0,
|
|
34
34
|
maxTimeout: 0,
|
|
35
35
|
})
|
|
36
|
-
type
|
|
36
|
+
type effectInvocationHandler = Runtime.effectInvocationHandler<
|
|
37
|
+
RuntimeEnvironment.event,
|
|
38
|
+
context,
|
|
39
|
+
unit,
|
|
40
|
+
string,
|
|
41
|
+
>
|
|
37
42
|
// `comp` is the *element's* log component, resolved where the handler is registered
|
|
38
43
|
// (the event collector's own resource is in hand there). Keeping it next to the
|
|
39
44
|
// handler is what makes every collector hosted in this one runtime separable by
|
|
40
45
|
// field — the runtime-group name would be identical for all of them.
|
|
41
|
-
type registeredHandler = {comp: string, handler:
|
|
46
|
+
type registeredHandler = {comp: string, handler: effectInvocationHandler}
|
|
42
47
|
let eventCollectorHandlers: dict<array<registeredHandler>> = Dict.make()
|
|
43
48
|
|
|
44
49
|
let eventCollectorHandler = parentName =>
|
|
@@ -142,7 +147,7 @@ module Make = (
|
|
|
142
147
|
|
|
143
148
|
let forEventCollector = (
|
|
144
149
|
~handler: Pulumi.Output.t<
|
|
145
|
-
Runtime.
|
|
150
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
146
151
|
>,
|
|
147
152
|
~eventTopics: EventTopic.allOutputs,
|
|
148
153
|
~resources: array<ReventlessInfra.Adapter.resource>,
|
|
@@ -5,7 +5,7 @@ module type T = {
|
|
|
5
5
|
|
|
6
6
|
let forCommandTopic: (
|
|
7
7
|
~handler: Pulumi.Output.t<
|
|
8
|
-
Runtime.
|
|
8
|
+
Runtime.effectInvocationHandler<CommandTopicChannel.callbackEvent, context, unit, string>,
|
|
9
9
|
>,
|
|
10
10
|
~connect: Runtime.connect<runtimeParts>,
|
|
11
11
|
~memorySize: int=?,
|
|
@@ -5,16 +5,16 @@ module type T = {
|
|
|
5
5
|
|
|
6
6
|
let registerPluginName: string => unit
|
|
7
7
|
let forPluginEventCollector: Runtime.forEventCollector<
|
|
8
|
-
Runtime.
|
|
8
|
+
Runtime.effectInvocationHandler<EventCollectorChannel.callbackEvent, context, unit, string>,
|
|
9
9
|
EventCollector.component,
|
|
10
10
|
>
|
|
11
11
|
let forPluginHeartbeat: Runtime.forComponent<
|
|
12
|
-
Runtime.
|
|
12
|
+
Runtime.invocationHandler<unit, context, unit>,
|
|
13
13
|
runtimeParts,
|
|
14
14
|
Heartbeat.component,
|
|
15
15
|
>
|
|
16
16
|
let forDcbCommandTopic: Runtime.forComponent<
|
|
17
|
-
Runtime.
|
|
17
|
+
Runtime.effectInvocationHandler<'callbackEvent, context, unit, string>,
|
|
18
18
|
runtimeParts,
|
|
19
19
|
CommandTopic.component<'op>,
|
|
20
20
|
>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
type
|
|
3
|
-
|
|
1
|
+
// Handlers of a platform invocation (a Lambda payload), not of domain events.
|
|
2
|
+
type invocationHandler<'payload, 'context, 'result> = ('payload, 'context) => promise<'result>
|
|
3
|
+
type effectInvocationHandler<'payload, 'context, 'result, 'error> = (
|
|
4
|
+
'payload,
|
|
4
5
|
'context,
|
|
5
6
|
) => Effect.t<'result, 'error, unit>
|
|
6
7
|
|
|
@@ -92,7 +93,7 @@ let runEffect = (
|
|
|
92
93
|
)
|
|
93
94
|
->Effect.runPromise
|
|
94
95
|
|
|
95
|
-
// Convert an
|
|
96
|
+
// Convert an effectInvocationHandler to an invocationHandler at build time, annotating the
|
|
96
97
|
// invocation on each call. Used by the single-component-per-Lambda strategies
|
|
97
98
|
// (Micro / PerAggregate / Plugin / PerEventCollector / PerExtensionPoint), which
|
|
98
99
|
// pass the Environment's `extractCorrelationId` / `extractCausationId` and the
|
|
@@ -105,8 +106,8 @@ let runEffectHandler = (
|
|
|
105
106
|
~extractRetryCount: option<'event => option<int>>=?,
|
|
106
107
|
~comp=?,
|
|
107
108
|
~pluginName=?,
|
|
108
|
-
handler:
|
|
109
|
-
):
|
|
109
|
+
handler: effectInvocationHandler<'event, 'context, 'result, 'error>,
|
|
110
|
+
): invocationHandler<'event, 'context, 'result> =>
|
|
110
111
|
(event, ctx) => {
|
|
111
112
|
let extract = (f, event) =>
|
|
112
113
|
switch f {
|
|
@@ -136,7 +137,7 @@ type environment<'parts> = {
|
|
|
136
137
|
|
|
137
138
|
type environmentMaker<'event, 'context, 'result, 'parts> = (
|
|
138
139
|
~name: string,
|
|
139
|
-
~handler: Pulumi.Output.t<
|
|
140
|
+
~handler: Pulumi.Output.t<invocationHandler<'event, 'context, 'result>>,
|
|
140
141
|
~memorySize: int=?,
|
|
141
142
|
~timeout: int=?,
|
|
142
143
|
~opts: Pulumi.ComponentResource.options=?,
|
|
@@ -154,8 +155,8 @@ module type Environment = {
|
|
|
154
155
|
// `None` where the transport carries no such notion (see each implementation).
|
|
155
156
|
let extractSentTimestamp: event => option<float>
|
|
156
157
|
let extractRetryCount: event => option<int>
|
|
157
|
-
let asEventHandler: 'a =>
|
|
158
|
-
let asEffectHandler: 'a =>
|
|
158
|
+
let asEventHandler: 'a => invocationHandler<event, context, 'result>
|
|
159
|
+
let asEffectHandler: 'a => effectInvocationHandler<event, context, 'result, 'error>
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
type connect<'parts> = (~runtime: environment<'parts>) => unit
|
|
@@ -18,7 +18,7 @@ module type T = {
|
|
|
18
18
|
type runtimeParts
|
|
19
19
|
|
|
20
20
|
let forBucketCallback: (
|
|
21
|
-
~handler: Pulumi.Output.t<Runtime.
|
|
21
|
+
~handler: Pulumi.Output.t<Runtime.invocationHandler<callbackEvent, context, unit>>,
|
|
22
22
|
~connect: Runtime.connect<runtimeParts>,
|
|
23
23
|
~memorySize: int=?,
|
|
24
24
|
~timeout: int=?,
|
|
@@ -42,7 +42,7 @@ let pluginCommands: array<commandDef> = Plugin_Structure.extractCommandDefs(
|
|
|
42
42
|
commandSchema,
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
let pluginAggregate:
|
|
45
|
+
let pluginAggregate: writeSideDef = {
|
|
46
46
|
name: "Plugin",
|
|
47
47
|
commands: pluginCommands,
|
|
48
48
|
producedEventTypes: [],
|
|
@@ -59,8 +59,8 @@ let pluginAggregate: writableDef = {
|
|
|
59
59
|
|
|
60
60
|
// Functions, not values: the view's access keys are the group the platform maps
|
|
61
61
|
// the administrator role to, and this module is evaluated before a root maps it.
|
|
62
|
-
let pluginReadModel = ():
|
|
63
|
-
Plugin_Structure.
|
|
62
|
+
let pluginReadModel = (): readSideDef =>
|
|
63
|
+
Plugin_Structure.readSideDefFromSpec(
|
|
64
64
|
~plugin=pluginId,
|
|
65
65
|
~name=PluginsReadModelSpec.name,
|
|
66
66
|
~stateSchema=PluginsReadModelSpec.stateSchema->S.castToUnknown,
|
|
@@ -33,7 +33,7 @@ let pluginAggregate = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
function pluginReadModel() {
|
|
36
|
-
return Plugin_Structure$ReventlessCore.
|
|
36
|
+
return Plugin_Structure$ReventlessCore.readSideDefFromSpec(pluginId, PluginsReadModelSpec$ReventlessCore.name, PluginsReadModelSpec$ReventlessCore.stateSchema, Authorization$Reventless.named(PluginsReadModelSpec$ReventlessCore.authorization), undefined, undefined, ["Plugin"], undefined);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function structure() {
|
|
@@ -65,12 +65,12 @@ type selection = {
|
|
|
65
65
|
derived: option<array<string>>,
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
let publicViews = (def: pluginStructure): array<
|
|
68
|
+
let publicViews = (def: pluginStructure): array<readSideDef> =>
|
|
69
69
|
Array.concat(def.readModels, def.stateViewSlices)->Array.filter(
|
|
70
|
-
Platform_ComponentDefinitionsApi.
|
|
70
|
+
Platform_ComponentDefinitionsApi.isPublicReadSide,
|
|
71
71
|
)
|
|
72
72
|
|
|
73
|
-
let writeSides = (def: pluginStructure): array<
|
|
73
|
+
let writeSides = (def: pluginStructure): array<writeSideDef> =>
|
|
74
74
|
Array.concat(def.stateChangeSlices, def.aggregates)
|
|
75
75
|
|
|
76
76
|
let commandNames = (def: pluginStructure): array<string> =>
|
|
@@ -116,7 +116,7 @@ let isSelected = (selected: option<array<string>>, name: string): bool =>
|
|
|
116
116
|
// breaks the picker permanently in the one deployment shape with no fallback.
|
|
117
117
|
// Naming it discloses nothing: the domain API already serves that view to the same
|
|
118
118
|
// caller (Internal is a menu hint, not a boundary).
|
|
119
|
-
let referencedEntities = (~pluginName: string, kept: array<
|
|
119
|
+
let referencedEntities = (~pluginName: string, kept: array<writeSideDef>): array<string> =>
|
|
120
120
|
kept
|
|
121
121
|
->Array.flatMap(w => w.commands)
|
|
122
122
|
->Array.flatMap(c => c.references)
|
|
@@ -133,7 +133,7 @@ let curateStructure = (~pluginId: string, ~def: pluginStructure, sel: selection)
|
|
|
133
133
|
> =>
|
|
134
134
|
validate(~def, sel)->Result.map(() => {
|
|
135
135
|
let pluginName = Plugin.name(pluginId)
|
|
136
|
-
let keepCommands = (ws: array<
|
|
136
|
+
let keepCommands = (ws: array<writeSideDef>) =>
|
|
137
137
|
ws
|
|
138
138
|
->Array.map(w => {
|
|
139
139
|
...w,
|
|
@@ -147,9 +147,9 @@ let curateStructure = (~pluginId: string, ~def: pluginStructure, sel: selection)
|
|
|
147
147
|
let stateChangeSlices = def.stateChangeSlices->keepCommands
|
|
148
148
|
let aggregates = def.aggregates->keepCommands
|
|
149
149
|
let referenced = referencedEntities(~pluginName, Array.concat(stateChangeSlices, aggregates))
|
|
150
|
-
let keepViews = (qs: array<
|
|
150
|
+
let keepViews = (qs: array<readSideDef>) =>
|
|
151
151
|
qs->Array.filter(q =>
|
|
152
|
-
if Platform_ComponentDefinitionsApi.
|
|
152
|
+
if Platform_ComponentDefinitionsApi.isPublicReadSide(q) {
|
|
153
153
|
sel.views->isSelected(q.name)
|
|
154
154
|
} else {
|
|
155
155
|
referenced->Array.includes(q.name)
|
|
@@ -27,7 +27,7 @@ function describe(e) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function publicViews(def) {
|
|
30
|
-
return def.readModels.concat(def.stateViewSlices).filter(Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
30
|
+
return def.readModels.concat(def.stateViewSlices).filter(Platform_ComponentDefinitionsApi$ReventlessCore.isPublicReadSide);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function writeSides(def) {
|
|
@@ -117,7 +117,7 @@ function curateStructure(pluginId, def, sel) {
|
|
|
117
117
|
let aggregates = keepCommands(def.aggregates);
|
|
118
118
|
let referenced = referencedEntities(pluginName, stateChangeSlices.concat(aggregates));
|
|
119
119
|
let keepViews = qs => qs.filter(q => {
|
|
120
|
-
if (Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
120
|
+
if (Platform_ComponentDefinitionsApi$ReventlessCore.isPublicReadSide(q)) {
|
|
121
121
|
return isSelected(sel.views, q.name);
|
|
122
122
|
} else {
|
|
123
123
|
return referenced.includes(q.name);
|
|
@@ -92,7 +92,7 @@ let encodeCommandDef = (c: commandDef): JSON.t =>
|
|
|
92
92
|
|
|
93
93
|
// Internal ReadModels / StateViewSlices are carried in pluginStructure for developer
|
|
94
94
|
// tooling but must stay out of the deployed AutoUI — the menu, drill-down pages and
|
|
95
|
-
//
|
|
95
|
+
// read-side defs are all derived from this response, so filter them here.
|
|
96
96
|
//
|
|
97
97
|
// Hidden from the menu is not the same question as denied as a reference target: a
|
|
98
98
|
// denormalised lookup view is precisely the thing an author wants referenceable but
|
|
@@ -100,9 +100,9 @@ let encodeCommandDef = (c: commandDef): JSON.t =>
|
|
|
100
100
|
// (below) answers the second. Neither is a security boundary — an Internal view
|
|
101
101
|
// keeps its resolver and stays queryable, so naming it here publishes a fact the
|
|
102
102
|
// caller is already entitled to.
|
|
103
|
-
let
|
|
103
|
+
let isPublicReadSide = (q: readSideDef): bool => q.visibility != Some("Internal")
|
|
104
104
|
|
|
105
|
-
let
|
|
105
|
+
let encodeReadSideDef = (r: readSideDef): JSON.t =>
|
|
106
106
|
Dict.fromArray([
|
|
107
107
|
("name", JSON.Encode.string(r.name)),
|
|
108
108
|
("queryField", JSON.Encode.string(r.queryField)),
|
|
@@ -143,7 +143,7 @@ let encodeErrorDef = (e: errorDef): JSON.t =>
|
|
|
143
143
|
("references", e.references->Array.map(encodeFieldReference)->JSON.Encode.array),
|
|
144
144
|
])->JSON.Encode.object
|
|
145
145
|
|
|
146
|
-
let
|
|
146
|
+
let encodeWriteSideDef = (w: writeSideDef): JSON.t =>
|
|
147
147
|
Dict.fromArray([
|
|
148
148
|
("name", JSON.Encode.string(w.name)),
|
|
149
149
|
("commands", w.commands->Array.map(encodeCommandDef)->JSON.Encode.array),
|
|
@@ -254,26 +254,26 @@ let encodePluginStructureEntry = (
|
|
|
254
254
|
(
|
|
255
255
|
"readModels",
|
|
256
256
|
def.readModels
|
|
257
|
-
->Array.filter(
|
|
258
|
-
->Array.map(
|
|
257
|
+
->Array.filter(isPublicReadSide)
|
|
258
|
+
->Array.map(encodeReadSideDef)
|
|
259
259
|
->JSON.Encode.array,
|
|
260
260
|
),
|
|
261
261
|
(
|
|
262
262
|
"stateViewSlices",
|
|
263
263
|
def.stateViewSlices
|
|
264
|
-
->Array.filter(
|
|
265
|
-
->Array.map(
|
|
264
|
+
->Array.filter(isPublicReadSide)
|
|
265
|
+
->Array.map(encodeReadSideDef)
|
|
266
266
|
->JSON.Encode.array,
|
|
267
267
|
),
|
|
268
268
|
(
|
|
269
269
|
"internalQueryables",
|
|
270
270
|
Array.concat(def.readModels, def.stateViewSlices)
|
|
271
|
-
->Array.filter(q => !
|
|
272
|
-
->Array.map(
|
|
271
|
+
->Array.filter(q => !isPublicReadSide(q))
|
|
272
|
+
->Array.map(encodeReadSideDef)
|
|
273
273
|
->JSON.Encode.array,
|
|
274
274
|
),
|
|
275
|
-
("stateChangeSlices", def.stateChangeSlices->Array.map(
|
|
276
|
-
("aggregates", def.aggregates->Array.map(
|
|
275
|
+
("stateChangeSlices", def.stateChangeSlices->Array.map(encodeWriteSideDef)->JSON.Encode.array),
|
|
276
|
+
("aggregates", def.aggregates->Array.map(encodeWriteSideDef)->JSON.Encode.array),
|
|
277
277
|
(
|
|
278
278
|
"automationSlices",
|
|
279
279
|
def.automationSlices->Array.map(encodeAutomationSliceDef)->JSON.Encode.array,
|
|
@@ -97,11 +97,11 @@ function encodeCommandDef(c) {
|
|
|
97
97
|
]);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
function
|
|
100
|
+
function isPublicReadSide(q) {
|
|
101
101
|
return Primitive_object.notequal(q.visibility, "Internal");
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
function
|
|
104
|
+
function encodeReadSideDef(r) {
|
|
105
105
|
return Object.fromEntries([
|
|
106
106
|
[
|
|
107
107
|
"name",
|
|
@@ -216,7 +216,7 @@ function encodeErrorDef(e) {
|
|
|
216
216
|
]);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
function
|
|
219
|
+
function encodeWriteSideDef(w) {
|
|
220
220
|
return Object.fromEntries([
|
|
221
221
|
[
|
|
222
222
|
"name",
|
|
@@ -399,23 +399,23 @@ function encodePluginStructureEntry(pluginId, derived, def) {
|
|
|
399
399
|
],
|
|
400
400
|
[
|
|
401
401
|
"readModels",
|
|
402
|
-
def.readModels.filter(
|
|
402
|
+
def.readModels.filter(isPublicReadSide).map(encodeReadSideDef)
|
|
403
403
|
],
|
|
404
404
|
[
|
|
405
405
|
"stateViewSlices",
|
|
406
|
-
def.stateViewSlices.filter(
|
|
406
|
+
def.stateViewSlices.filter(isPublicReadSide).map(encodeReadSideDef)
|
|
407
407
|
],
|
|
408
408
|
[
|
|
409
409
|
"internalQueryables",
|
|
410
|
-
def.readModels.concat(def.stateViewSlices).filter(q => !Primitive_object.notequal(q.visibility, "Internal")).map(
|
|
410
|
+
def.readModels.concat(def.stateViewSlices).filter(q => !Primitive_object.notequal(q.visibility, "Internal")).map(encodeReadSideDef)
|
|
411
411
|
],
|
|
412
412
|
[
|
|
413
413
|
"stateChangeSlices",
|
|
414
|
-
def.stateChangeSlices.map(
|
|
414
|
+
def.stateChangeSlices.map(encodeWriteSideDef)
|
|
415
415
|
],
|
|
416
416
|
[
|
|
417
417
|
"aggregates",
|
|
418
|
-
def.aggregates.map(
|
|
418
|
+
def.aggregates.map(encodeWriteSideDef)
|
|
419
419
|
],
|
|
420
420
|
[
|
|
421
421
|
"automationSlices",
|
|
@@ -448,11 +448,11 @@ export {
|
|
|
448
448
|
encodeStrings,
|
|
449
449
|
encodeFieldReference,
|
|
450
450
|
encodeCommandDef,
|
|
451
|
-
|
|
452
|
-
|
|
451
|
+
isPublicReadSide,
|
|
452
|
+
encodeReadSideDef,
|
|
453
453
|
encodeEventDef,
|
|
454
454
|
encodeErrorDef,
|
|
455
|
-
|
|
455
|
+
encodeWriteSideDef,
|
|
456
456
|
encodeAutomationSliceDef,
|
|
457
457
|
encodeOutboundTranslationSliceDef,
|
|
458
458
|
encodeInboundTranslationSliceDef,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// difference is not cosmetic.
|
|
7
7
|
//
|
|
8
8
|
// Platform_ComponentDefinitions the deployed AutoUI's menu, drill-down pages and
|
|
9
|
-
//
|
|
9
|
+
// read-side defs. Internal ReadModels /
|
|
10
10
|
// StateViewSlices are filtered OUT — showing them
|
|
11
11
|
// would put components in an end user's menu that
|
|
12
12
|
// the author marked as not-for-display.
|
|
@@ -119,7 +119,7 @@ let encodeRequiredCapabilityDeclaration = (d: requiredCapabilityDeclaration): JS
|
|
|
119
119
|
("component", JSON.Encode.string(d.component)),
|
|
120
120
|
])->JSON.Encode.object
|
|
121
121
|
|
|
122
|
-
// Deliberately NOT filtered by `
|
|
122
|
+
// Deliberately NOT filtered by `isPublicReadSide`: that filter is the AutoUI
|
|
123
123
|
// contract, and applying it here would silently drop Internal components from the
|
|
124
124
|
// graph a developer tool draws.
|
|
125
125
|
let encodePluginStructureEntry = (~pluginId: string, def: pluginStructure): JSON.t =>
|
|
@@ -128,25 +128,25 @@ let encodePluginStructureEntry = (~pluginId: string, def: pluginStructure): JSON
|
|
|
128
128
|
(
|
|
129
129
|
"readModels",
|
|
130
130
|
def.readModels
|
|
131
|
-
->Array.map(Platform_ComponentDefinitionsApi.
|
|
131
|
+
->Array.map(Platform_ComponentDefinitionsApi.encodeReadSideDef)
|
|
132
132
|
->JSON.Encode.array,
|
|
133
133
|
),
|
|
134
134
|
(
|
|
135
135
|
"stateViewSlices",
|
|
136
136
|
def.stateViewSlices
|
|
137
|
-
->Array.map(Platform_ComponentDefinitionsApi.
|
|
137
|
+
->Array.map(Platform_ComponentDefinitionsApi.encodeReadSideDef)
|
|
138
138
|
->JSON.Encode.array,
|
|
139
139
|
),
|
|
140
140
|
(
|
|
141
141
|
"stateChangeSlices",
|
|
142
142
|
def.stateChangeSlices
|
|
143
|
-
->Array.map(Platform_ComponentDefinitionsApi.
|
|
143
|
+
->Array.map(Platform_ComponentDefinitionsApi.encodeWriteSideDef)
|
|
144
144
|
->JSON.Encode.array,
|
|
145
145
|
),
|
|
146
146
|
(
|
|
147
147
|
"aggregates",
|
|
148
148
|
def.aggregates
|
|
149
|
-
->Array.map(Platform_ComponentDefinitionsApi.
|
|
149
|
+
->Array.map(Platform_ComponentDefinitionsApi.encodeWriteSideDef)
|
|
150
150
|
->JSON.Encode.array,
|
|
151
151
|
),
|
|
152
152
|
(
|
|
@@ -124,19 +124,19 @@ function encodePluginStructureEntry(pluginId, def) {
|
|
|
124
124
|
],
|
|
125
125
|
[
|
|
126
126
|
"readModels",
|
|
127
|
-
def.readModels.map(Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
127
|
+
def.readModels.map(Platform_ComponentDefinitionsApi$ReventlessCore.encodeReadSideDef)
|
|
128
128
|
],
|
|
129
129
|
[
|
|
130
130
|
"stateViewSlices",
|
|
131
|
-
def.stateViewSlices.map(Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
131
|
+
def.stateViewSlices.map(Platform_ComponentDefinitionsApi$ReventlessCore.encodeReadSideDef)
|
|
132
132
|
],
|
|
133
133
|
[
|
|
134
134
|
"stateChangeSlices",
|
|
135
|
-
def.stateChangeSlices.map(Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
135
|
+
def.stateChangeSlices.map(Platform_ComponentDefinitionsApi$ReventlessCore.encodeWriteSideDef)
|
|
136
136
|
],
|
|
137
137
|
[
|
|
138
138
|
"aggregates",
|
|
139
|
-
def.aggregates.map(Platform_ComponentDefinitionsApi$ReventlessCore.
|
|
139
|
+
def.aggregates.map(Platform_ComponentDefinitionsApi$ReventlessCore.encodeWriteSideDef)
|
|
140
140
|
],
|
|
141
141
|
[
|
|
142
142
|
"automationSlices",
|
|
@@ -40,8 +40,6 @@ let name = "UiFragments";
|
|
|
40
40
|
|
|
41
41
|
let Id;
|
|
42
42
|
|
|
43
|
-
let Key;
|
|
44
|
-
|
|
45
43
|
let subIdConfig;
|
|
46
44
|
|
|
47
45
|
let moduleUrl = "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateView/UiFragments.res.mjs";
|
|
@@ -52,11 +50,10 @@ let visibility = "Public";
|
|
|
52
50
|
|
|
53
51
|
export {
|
|
54
52
|
name,
|
|
55
|
-
Id,
|
|
56
53
|
stateSchema,
|
|
57
54
|
consumedEventSchema,
|
|
58
55
|
config,
|
|
59
|
-
|
|
56
|
+
Id,
|
|
60
57
|
subIdConfig,
|
|
61
58
|
moduleUrl,
|
|
62
59
|
authorization,
|
|
@@ -392,7 +392,7 @@ and objectRefToJsonSchema = (
|
|
|
392
392
|
// not declare — which is precisely the mismatch that made read-model queries
|
|
393
393
|
// reference fields the server rejects.
|
|
394
394
|
//
|
|
395
|
-
// This is the single point for every JSON-Schema consumer: `
|
|
395
|
+
// This is the single point for every JSON-Schema consumer: `readSideDef.schema`,
|
|
396
396
|
// the MCP generator and the manifest all derive through this walk.
|
|
397
397
|
let internal = annotations->Option.flatMap(spec => spec.internal)->Option.getOr([])
|
|
398
398
|
fields
|
|
@@ -27,7 +27,7 @@ external asEvent: 'a => event = "%identity"
|
|
|
27
27
|
let metaInfo = event => (event->asEvent).meta->Option.map(({info}) => info)
|
|
28
28
|
|
|
29
29
|
type commandGenerator = payload => Effect.t<CommandTopic.commandOutcome, unit, unit>
|
|
30
|
-
type effectEventHandler<'context> = Runtime.
|
|
30
|
+
type effectEventHandler<'context> = Runtime.effectInvocationHandler<
|
|
31
31
|
payload,
|
|
32
32
|
'context,
|
|
33
33
|
CommandTopic.commandOutcome,
|
|
@@ -15,7 +15,12 @@ module type Resolvers = {
|
|
|
15
15
|
type runtimeParts
|
|
16
16
|
|
|
17
17
|
let handleResolversEvent: CommandGenerator.commandGenerator => Pulumi.Output.t<
|
|
18
|
-
Runtime.
|
|
18
|
+
Runtime.effectInvocationHandler<
|
|
19
|
+
CommandGenerator.payload,
|
|
20
|
+
'context,
|
|
21
|
+
CommandTopic.commandOutcome,
|
|
22
|
+
unit,
|
|
23
|
+
>,
|
|
19
24
|
>
|
|
20
25
|
|
|
21
26
|
let make: resolversMaker<api, runtimeParts>
|
|
@@ -48,12 +48,12 @@ module type T = {
|
|
|
48
48
|
let makeHandler: (
|
|
49
49
|
~commandTopic: component,
|
|
50
50
|
~commandsHandler: commandsHandler,
|
|
51
|
-
) => Pulumi.Output.t<Runtime.
|
|
51
|
+
) => Pulumi.Output.t<Runtime.effectInvocationHandler<callbackEvent, 'context, unit, string>>
|
|
52
52
|
|
|
53
53
|
// Returns the filtering handler output for runtime connection
|
|
54
54
|
// Registers the handler with the channel's event routing
|
|
55
55
|
let makeFilteringHandler: component => Pulumi.Output.t<
|
|
56
|
-
Runtime.
|
|
56
|
+
Runtime.effectInvocationHandler<callbackEvent, 'context, unit, string>,
|
|
57
57
|
>
|
|
58
58
|
|
|
59
59
|
let make: (
|