@reventlessdev/reventless-core 3.0.0-alpha.250 → 3.0.0-alpha.251
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 +25 -0
- package/package.json +8 -8
- package/src/admin/Platform_ComponentDefinitionsApi.res +31 -1
- package/src/admin/Platform_ComponentDefinitionsApi.res.mjs +29 -1
- package/src/admin/Platform_PluginStructuresApi.res +37 -1
- package/src/admin/Platform_PluginStructuresApi.res.mjs +29 -1
- package/src/plugin/component/Plugin_Structure.res +620 -370
- package/src/plugin/component/Plugin_Structure.res.mjs +341 -3
- package/src/plugin/connect/PluginConnectExtension_Mapping.res +3 -6
- package/src/plugin/connect/PluginConnectExtension_Mapping.res.mjs +11 -1
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res +0 -1
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +60 -2
- package/src/plugin/connect/PluginExtensionPoint_UiFragment.res.mjs +19 -2
- package/tests/admin/AdminApiSchemaDriftTest.res +460 -0
- package/tests/admin/AdminApiSchemaDriftTest.res.mjs +599 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +6 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +9 -1
- package/tests/admin/Platform_PluginStructuresApiTest.res +12 -1
- package/tests/admin/Platform_PluginStructuresApiTest.res.mjs +10 -2
- package/tests/plugin/PluginStructureTest.res +109 -0
- package/tests/plugin/PluginStructureTest.res.mjs +127 -0
- package/tests/plugin/pluginDefinitionRequiredScalars.txt +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
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.251 (2026-08-27)
|
|
7
|
+
|
|
8
|
+
* feat(spec)!: reflect the command direction across a port, both halves ([f2fe258](https://github.com/ReventlessDev/reventless-core/commit/f2fe258d195b74f4a61488edee305665341020ea))
|
|
9
|
+
* feat(spec)!: drop the plugin protocol's reconnect event, which nothing published ([7549db6](https://github.com/ReventlessDev/reventless-core/commit/7549db6aac6ad3f94dbb8d72dac4b4e783756ad1))
|
|
10
|
+
* feat(spec)!: read the port's translation table off the mapping's arms ([956348a](https://github.com/ReventlessDev/reventless-core/commit/956348a9fcb256cfff9db51809bdc27d73360e6c))
|
|
11
|
+
|
|
12
|
+
### BREAKING CHANGES
|
|
13
|
+
|
|
14
|
+
* `ExtensionPointMapping.Mapping` gains `acceptedCommands` and
|
|
15
|
+
`ExtensionMapping.Mapping` gains `issuedCommands`; both are derived, so a
|
|
16
|
+
mapping the ppx can read needs no source change, and one it cannot names itself
|
|
17
|
+
at compile time. Definitions persisted before the two new def fields must be
|
|
18
|
+
re-emitted before a consumer can read them as present — and until then they
|
|
19
|
+
decode as None, which means unknown, not "issues nothing".
|
|
20
|
+
* `PluginExtensionPointSpec.event` no longer declares
|
|
21
|
+
`PluginReconnected`. An extension matching on it was matching an event it could
|
|
22
|
+
never receive; drop the arm.
|
|
23
|
+
* `ExtensionPointMapping.Mapping` requires `publishedEvents` and
|
|
24
|
+
`ExtensionMapping.Mapping` requires `handledEvents`; the ppx injects both for
|
|
25
|
+
mappings it can read, so app code must build against the matching ppx. Plugin
|
|
26
|
+
definitions persisted before the new fields must be re-emitted before a consumer
|
|
27
|
+
reads them as present.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
6
31
|
# 3.0.0-alpha.250 (2026-08-23)
|
|
7
32
|
|
|
8
33
|
### Bug Fixes
|
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.251",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -29,21 +29,21 @@
|
|
|
29
29
|
"sury": "11.0.0-rc.2",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
31
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
32
|
-
"@reventlessdev/rescript-
|
|
32
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.8",
|
|
33
33
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
34
34
|
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.14",
|
|
35
|
-
"@reventlessdev/rescript-
|
|
36
|
-
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
|
|
35
|
+
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.8",
|
|
37
36
|
"@reventlessdev/rescript-ssh2": "2.0.0-alpha.8",
|
|
37
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
|
|
38
38
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
|
|
39
|
-
"@reventlessdev/reventless-
|
|
40
|
-
"@reventlessdev/reventless-
|
|
41
|
-
"@reventlessdev/reventless-
|
|
39
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.152",
|
|
40
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.34",
|
|
41
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.124"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "12.3.0",
|
|
45
45
|
"sury-ppx": "11.0.0-rc.2",
|
|
46
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
46
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.74"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"rescript": "12.3.0"
|
|
@@ -33,7 +33,11 @@ let sdlTypes: array<string> = [
|
|
|
33
33
|
`type Platform_AutomationSliceDef {\n name: String!\n consumedEventTypes: [String!]!\n producedCommandTypes: [String!]!\n targetName: String\n chapter: String\n}`,
|
|
34
34
|
`type Platform_OutboundTranslationSliceDef {\n name: String!\n consumedEventTypes: [String!]!\n inboundCommandTypes: [String!]!\n targetName: String\n externalSystem: String\n chapter: String\n}`,
|
|
35
35
|
`type Platform_InboundTranslationSliceDef {\n name: String!\n commandTypes: [String!]!\n targetName: String\n externalSystem: String\n chapter: String\n}`,
|
|
36
|
-
|
|
36
|
+
// The subscriber's half of the port's translation table — see `handledEventDef`.
|
|
37
|
+
`type Platform_HandledEventDef {\n name: String!\n toCommandTypes: [String!]!\n}`,
|
|
38
|
+
// Its command-direction mirror — see `issuedCommandDef`.
|
|
39
|
+
`type Platform_IssuedCommandDef {\n name: String!\n fromEventTypes: [String!]!\n}`,
|
|
40
|
+
`type Platform_ExtensionDef {\n name: String!\n delegateNames: [String!]!\n eventTypes: [String!]!\n commandTypes: [String!]!\n handledEvents: [Platform_HandledEventDef!]\n issuedCommands: [Platform_IssuedCommandDef!]\n}`,
|
|
37
41
|
// `internalQueryables` is the complement of the `readModels` / `stateViewSlices`
|
|
38
42
|
// filter, not an addition to either: it carries exactly the components the
|
|
39
43
|
// filter removed. A consumer enumerating surfaces reads the two filtered lists
|
|
@@ -208,6 +212,32 @@ let encodeExtensionDef = (e: extensionDef): JSON.t =>
|
|
|
208
212
|
("delegateNames", encodeStrings(e.delegateNames)),
|
|
209
213
|
("eventTypes", encodeStrings(e.eventTypes)),
|
|
210
214
|
("commandTypes", encodeStrings(e.commandTypes)),
|
|
215
|
+
(
|
|
216
|
+
"handledEvents",
|
|
217
|
+
e.handledEvents->Option.mapOr(JSON.Encode.null, handled =>
|
|
218
|
+
handled
|
|
219
|
+
->Array.map(h =>
|
|
220
|
+
Dict.fromArray([
|
|
221
|
+
("name", JSON.Encode.string(h.name)),
|
|
222
|
+
("toCommandTypes", encodeStrings(h.toCommandTypes)),
|
|
223
|
+
])->JSON.Encode.object
|
|
224
|
+
)
|
|
225
|
+
->JSON.Encode.array
|
|
226
|
+
),
|
|
227
|
+
),
|
|
228
|
+
(
|
|
229
|
+
"issuedCommands",
|
|
230
|
+
e.issuedCommands->Option.mapOr(JSON.Encode.null, issued =>
|
|
231
|
+
issued
|
|
232
|
+
->Array.map(i =>
|
|
233
|
+
Dict.fromArray([
|
|
234
|
+
("name", JSON.Encode.string(i.name)),
|
|
235
|
+
("fromEventTypes", encodeStrings(i.fromEventTypes)),
|
|
236
|
+
])->JSON.Encode.object
|
|
237
|
+
)
|
|
238
|
+
->JSON.Encode.array
|
|
239
|
+
),
|
|
240
|
+
),
|
|
211
241
|
])->JSON.Encode.object
|
|
212
242
|
|
|
213
243
|
// `derived` is curation, not structure: it says which of the pages a shell
|
|
@@ -14,7 +14,9 @@ let sdlTypes = [
|
|
|
14
14
|
`type Platform_AutomationSliceDef {\n name: String!\n consumedEventTypes: [String!]!\n producedCommandTypes: [String!]!\n targetName: String\n chapter: String\n}`,
|
|
15
15
|
`type Platform_OutboundTranslationSliceDef {\n name: String!\n consumedEventTypes: [String!]!\n inboundCommandTypes: [String!]!\n targetName: String\n externalSystem: String\n chapter: String\n}`,
|
|
16
16
|
`type Platform_InboundTranslationSliceDef {\n name: String!\n commandTypes: [String!]!\n targetName: String\n externalSystem: String\n chapter: String\n}`,
|
|
17
|
-
`type
|
|
17
|
+
`type Platform_HandledEventDef {\n name: String!\n toCommandTypes: [String!]!\n}`,
|
|
18
|
+
`type Platform_IssuedCommandDef {\n name: String!\n fromEventTypes: [String!]!\n}`,
|
|
19
|
+
`type Platform_ExtensionDef {\n name: String!\n delegateNames: [String!]!\n eventTypes: [String!]!\n commandTypes: [String!]!\n handledEvents: [Platform_HandledEventDef!]\n issuedCommands: [Platform_IssuedCommandDef!]\n}`,
|
|
18
20
|
`type Platform_ComponentDefinitionEntry {\n pluginId: String!\n readModels: [Platform_ReadSideDef!]!\n stateViewSlices: [Platform_ReadSideDef!]!\n internalQueryables: [Platform_ReadSideDef!]!\n stateChangeSlices: [Platform_WriteSideDef!]!\n aggregates: [Platform_WriteSideDef!]!\n automationSlices: [Platform_AutomationSliceDef!]!\n outboundTranslationSlices: [Platform_OutboundTranslationSliceDef!]!\n inboundTranslationSlices: [Platform_InboundTranslationSliceDef!]!\n extensions: [Platform_ExtensionDef!]!\n}`
|
|
19
21
|
];
|
|
20
22
|
|
|
@@ -347,6 +349,32 @@ function encodeExtensionDef(e) {
|
|
|
347
349
|
[
|
|
348
350
|
"commandTypes",
|
|
349
351
|
e.commandTypes.map(prim => prim)
|
|
352
|
+
],
|
|
353
|
+
[
|
|
354
|
+
"handledEvents",
|
|
355
|
+
Stdlib_Option.mapOr(e.handledEvents, null, handled => handled.map(h => Object.fromEntries([
|
|
356
|
+
[
|
|
357
|
+
"name",
|
|
358
|
+
h.name
|
|
359
|
+
],
|
|
360
|
+
[
|
|
361
|
+
"toCommandTypes",
|
|
362
|
+
h.toCommandTypes.map(prim => prim)
|
|
363
|
+
]
|
|
364
|
+
])))
|
|
365
|
+
],
|
|
366
|
+
[
|
|
367
|
+
"issuedCommands",
|
|
368
|
+
Stdlib_Option.mapOr(e.issuedCommands, null, issued => issued.map(i => Object.fromEntries([
|
|
369
|
+
[
|
|
370
|
+
"name",
|
|
371
|
+
i.name
|
|
372
|
+
],
|
|
373
|
+
[
|
|
374
|
+
"fromEventTypes",
|
|
375
|
+
i.fromEventTypes.map(prim => prim)
|
|
376
|
+
]
|
|
377
|
+
])))
|
|
350
378
|
]
|
|
351
379
|
]);
|
|
352
380
|
}
|
|
@@ -28,9 +28,13 @@
|
|
|
28
28
|
open Reventless.Plugin
|
|
29
29
|
|
|
30
30
|
let sdlTypes: array<string> = [
|
|
31
|
+
// The port's translation table — see `publishedEventDef`.
|
|
32
|
+
`type Platform_PublishedEventDef {\n name: String!\n fromEventTypes: [String!]!\n}`,
|
|
33
|
+
// Its command-direction mirror — see `acceptedCommandDef`.
|
|
34
|
+
`type Platform_AcceptedCommandDef {\n name: String!\n toCommandTypes: [String!]!\n}`,
|
|
31
35
|
// Producer side of an extension point. `commandTypes` is null for a
|
|
32
36
|
// notification-only (`command = unit`) extension point — see `extensionPointDef`.
|
|
33
|
-
`type Platform_ExtensionPointDef {\n name: String!\n delegateNames: [String!]!\n sourceEventTypes: [String!]!\n commandTypes: [String!]\n}`,
|
|
37
|
+
`type Platform_ExtensionPointDef {\n name: String!\n delegateNames: [String!]!\n sourceEventTypes: [String!]!\n commandTypes: [String!]\n publishedEvents: [Platform_PublishedEventDef!]\n acceptedCommands: [Platform_AcceptedCommandDef!]\n}`,
|
|
34
38
|
`type Platform_RequiredStoreDeclaration {\n store: String!\n component: String!\n field: String!\n annotation: String\n}`,
|
|
35
39
|
// `extensionPoints` / `requiredStores` / `requiredStoreDeclarations` are nullable
|
|
36
40
|
// lists, not `[T!]!`: all three are optional on `pluginStructure` so that plugin
|
|
@@ -52,6 +56,38 @@ let encodeExtensionPointDef = (e: extensionPointDef): JSON.t =>
|
|
|
52
56
|
"commandTypes",
|
|
53
57
|
e.commandTypes->Option.mapOr(JSON.Encode.null, Platform_ComponentDefinitionsApi.encodeStrings),
|
|
54
58
|
),
|
|
59
|
+
(
|
|
60
|
+
"publishedEvents",
|
|
61
|
+
e.publishedEvents->Option.mapOr(JSON.Encode.null, published =>
|
|
62
|
+
published
|
|
63
|
+
->Array.map(p =>
|
|
64
|
+
Dict.fromArray([
|
|
65
|
+
("name", JSON.Encode.string(p.name)),
|
|
66
|
+
(
|
|
67
|
+
"fromEventTypes",
|
|
68
|
+
Platform_ComponentDefinitionsApi.encodeStrings(p.fromEventTypes),
|
|
69
|
+
),
|
|
70
|
+
])->JSON.Encode.object
|
|
71
|
+
)
|
|
72
|
+
->JSON.Encode.array
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
(
|
|
76
|
+
"acceptedCommands",
|
|
77
|
+
e.acceptedCommands->Option.mapOr(JSON.Encode.null, accepted =>
|
|
78
|
+
accepted
|
|
79
|
+
->Array.map(a =>
|
|
80
|
+
Dict.fromArray([
|
|
81
|
+
("name", JSON.Encode.string(a.name)),
|
|
82
|
+
(
|
|
83
|
+
"toCommandTypes",
|
|
84
|
+
Platform_ComponentDefinitionsApi.encodeStrings(a.toCommandTypes),
|
|
85
|
+
),
|
|
86
|
+
])->JSON.Encode.object
|
|
87
|
+
)
|
|
88
|
+
->JSON.Encode.array
|
|
89
|
+
),
|
|
90
|
+
),
|
|
55
91
|
])->JSON.Encode.object
|
|
56
92
|
|
|
57
93
|
let encodeRequiredStoreDeclaration = (d: requiredStoreDeclaration): JSON.t =>
|
|
@@ -5,7 +5,9 @@ import * as Plugin$ReventlessCore from "../plugin/component/Plugin.res.mjs";
|
|
|
5
5
|
import * as Platform_ComponentDefinitionsApi$ReventlessCore from "./Platform_ComponentDefinitionsApi.res.mjs";
|
|
6
6
|
|
|
7
7
|
let sdlTypes = [
|
|
8
|
-
`type
|
|
8
|
+
`type Platform_PublishedEventDef {\n name: String!\n fromEventTypes: [String!]!\n}`,
|
|
9
|
+
`type Platform_AcceptedCommandDef {\n name: String!\n toCommandTypes: [String!]!\n}`,
|
|
10
|
+
`type Platform_ExtensionPointDef {\n name: String!\n delegateNames: [String!]!\n sourceEventTypes: [String!]!\n commandTypes: [String!]\n publishedEvents: [Platform_PublishedEventDef!]\n acceptedCommands: [Platform_AcceptedCommandDef!]\n}`,
|
|
9
11
|
`type Platform_RequiredStoreDeclaration {\n store: String!\n component: String!\n field: String!\n annotation: String\n}`,
|
|
10
12
|
`type Platform_PluginStructureEntry {\n pluginId: String!\n readModels: [Platform_ReadSideDef!]!\n stateViewSlices: [Platform_ReadSideDef!]!\n stateChangeSlices: [Platform_WriteSideDef!]!\n aggregates: [Platform_WriteSideDef!]!\n automationSlices: [Platform_AutomationSliceDef!]!\n outboundTranslationSlices: [Platform_OutboundTranslationSliceDef!]!\n inboundTranslationSlices: [Platform_InboundTranslationSliceDef!]!\n extensions: [Platform_ExtensionDef!]!\n extensionPoints: [Platform_ExtensionPointDef!]\n requiredStores: [String!]\n requiredStoreDeclarations: [Platform_RequiredStoreDeclaration!]\n}`
|
|
11
13
|
];
|
|
@@ -27,6 +29,32 @@ function encodeExtensionPointDef(e) {
|
|
|
27
29
|
[
|
|
28
30
|
"commandTypes",
|
|
29
31
|
Stdlib_Option.mapOr(e.commandTypes, null, Platform_ComponentDefinitionsApi$ReventlessCore.encodeStrings)
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"publishedEvents",
|
|
35
|
+
Stdlib_Option.mapOr(e.publishedEvents, null, published => published.map(p => Object.fromEntries([
|
|
36
|
+
[
|
|
37
|
+
"name",
|
|
38
|
+
p.name
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"fromEventTypes",
|
|
42
|
+
Platform_ComponentDefinitionsApi$ReventlessCore.encodeStrings(p.fromEventTypes)
|
|
43
|
+
]
|
|
44
|
+
])))
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
"acceptedCommands",
|
|
48
|
+
Stdlib_Option.mapOr(e.acceptedCommands, null, accepted => accepted.map(a => Object.fromEntries([
|
|
49
|
+
[
|
|
50
|
+
"name",
|
|
51
|
+
a.name
|
|
52
|
+
],
|
|
53
|
+
[
|
|
54
|
+
"toCommandTypes",
|
|
55
|
+
Platform_ComponentDefinitionsApi$ReventlessCore.encodeStrings(a.toCommandTypes)
|
|
56
|
+
]
|
|
57
|
+
])))
|
|
30
58
|
]
|
|
31
59
|
]);
|
|
32
60
|
}
|