@reventlessdev/reventless-core 3.0.0-alpha.156 → 3.0.0-alpha.157

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +6 -6
  3. package/src/admin/AdminApi.res +80 -10
  4. package/src/admin/AdminApi.res.mjs +45 -7
  5. package/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry.res +65 -0
  6. package/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry.res.mjs +87 -0
  7. package/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry_Behavior.res +58 -0
  8. package/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry_Behavior.res.mjs +135 -0
  9. package/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments.res +44 -0
  10. package/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments.res.mjs +74 -0
  11. package/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments_Projection.res +50 -0
  12. package/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments_Projection.res.mjs +80 -0
  13. package/src/admin/Platform_Admin.res +37 -1
  14. package/src/admin/Platform_Admin.res.mjs +18 -5
  15. package/src/admin/Platform_ApiFragmentsApi.res +32 -0
  16. package/src/admin/Platform_ApiFragmentsApi.res.mjs +52 -0
  17. package/src/admin/Platform_UIFragmentsApi.res +1 -1
  18. package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res +50 -0
  19. package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res.mjs +70 -0
  20. package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry_Behavior.res +33 -0
  21. package/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry_Behavior.res.mjs +80 -0
  22. package/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments.res +33 -0
  23. package/src/admin/{UIFragmentRegistryReadModelSpec.res.mjs → UiFragmentRegistry/StateViewSlice/UiFragments.res.mjs} +24 -2
  24. package/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments_Projection.res +34 -0
  25. package/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments_Projection.res.mjs +54 -0
  26. package/src/components/Api/Api_Naming.res +1 -1
  27. package/src/components/Api/GraphQL_FragmentGenerator.res +7 -11
  28. package/src/components/Api/GraphQL_FragmentGenerator.res.mjs +8 -22
  29. package/src/components/Api/GraphQL_PushPlanner.res +65 -0
  30. package/src/components/Api/GraphQL_PushPlanner.res.mjs +46 -0
  31. package/src/components/Api/GraphQL_Stitcher.res +72 -1
  32. package/src/components/Api/GraphQL_Stitcher.res.mjs +53 -2
  33. package/src/components/Dcb/Dcb_Builder.res +16 -6
  34. package/src/components/Dcb/Dcb_Builder.res.mjs +10 -7
  35. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +6 -1
  36. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +1 -1
  37. package/src/plugin/api/PluginBaseFragment.res +5 -6
  38. package/src/plugin/api/PluginBaseFragment.res.mjs +0 -1
  39. package/src/plugin/component/Plugin_Builder.res +4 -1
  40. package/src/plugin/component/Plugin_Builder.res.mjs +7 -6
  41. package/src/plugin/component/Plugin_Helpers.res +30 -0
  42. package/src/plugin/component/Plugin_Helpers.res.mjs +13 -3
  43. package/src/plugin/component/Plugin_SubscriptionSchema.res +19 -9
  44. package/src/plugin/component/Plugin_SubscriptionSchema.res.mjs +23 -14
  45. package/src/plugin/connect/PluginConnectExtension_Mapping.res +28 -6
  46. package/src/plugin/connect/PluginConnectExtension_Mapping.res.mjs +34 -14
  47. package/src/plugin/connect/PluginExtensionPoint_Builder.res +7 -1
  48. package/src/plugin/connect/PluginExtensionPoint_Builder.res.mjs +5 -1
  49. package/src/plugin/connect/PluginExtensionPoint_Plugin.res +3 -1
  50. package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +4 -2
  51. package/src/plugin/connect/PluginExtensionPoint_UiFragment.res +52 -0
  52. package/src/plugin/connect/PluginExtensionPoint_UiFragment.res.mjs +74 -0
  53. package/src/plugin/lifecycle/PluginBehavior.res +9 -51
  54. package/src/plugin/lifecycle/PluginBehavior.res.mjs +39 -68
  55. package/src/plugin/lifecycle/PluginSpec.res +0 -18
  56. package/src/plugin/lifecycle/PluginSpec.res.mjs +0 -30
  57. package/src/plugin/lifecycle/PluginsProjection.res +2 -6
  58. package/src/plugin/lifecycle/PluginsProjection.res.mjs +0 -2
  59. package/src/plugin/lifecycle/PluginsReadModelSpec.res +0 -2
  60. package/src/plugin/lifecycle/PluginsReadModelSpec.res.mjs +0 -1
  61. package/tests/admin/Platform_ApiFragmentsApiTest.res +66 -0
  62. package/tests/admin/Platform_ApiFragmentsApiTest.res.mjs +68 -0
  63. package/tests/admin/Platform_UIFragmentsApiTest.res +1 -1
  64. package/tests/api/GraphQL_PushPlannerTest.res +62 -0
  65. package/tests/api/GraphQL_PushPlannerTest.res.mjs +80 -0
  66. package/tests/api/GraphQL_StitcherTest.res +63 -0
  67. package/tests/api/GraphQL_StitcherTest.res.mjs +75 -0
  68. package/tests/logger/LogFormatTest.res +1 -2
  69. package/tests/logger/LogFormatTest.res.mjs +1 -2
  70. package/tests/message/MessageTest.res +0 -3
  71. package/tests/message/MessageTest.res.mjs +0 -3
  72. package/src/admin/UIFragmentRegistryProjection.res +0 -43
  73. package/src/admin/UIFragmentRegistryProjection.res.mjs +0 -81
  74. package/src/admin/UIFragmentRegistryReadModelSpec.res +0 -13
@@ -8,22 +8,42 @@ function Make(Spec) {
8
8
  let mapIncomingEvent = (pluginId, event, _meta, _pluginDef, _queryEngine) => {
9
9
  let pluginDefinition = Spec.pluginDefinition;
10
10
  let id = pluginDefinition.id;
11
- if (typeof event !== "object") {
12
- if (pluginId === id) {
13
- return [{
14
- TAG: "PublishExtensionPointCommand",
15
- _0: id,
16
- _1: {
17
- TAG: "ConnectPlugin",
18
- _0: pluginDefinition
19
- }
20
- }];
21
- } else {
22
- return [];
23
- }
24
- } else {
11
+ if (typeof event === "object") {
12
+ return [];
13
+ }
14
+ if (pluginId !== id) {
25
15
  return [];
26
16
  }
17
+ let manifest = Spec.uiFragments;
18
+ if (manifest !== undefined) {
19
+ return [
20
+ {
21
+ TAG: "PublishExtensionPointCommand",
22
+ _0: id,
23
+ _1: {
24
+ TAG: "ConnectPlugin",
25
+ _0: pluginDefinition
26
+ }
27
+ },
28
+ {
29
+ TAG: "PublishExtensionPointCommand",
30
+ _0: id,
31
+ _1: {
32
+ TAG: "RegisterUiFragment",
33
+ _0: manifest
34
+ }
35
+ }
36
+ ];
37
+ } else {
38
+ return [{
39
+ TAG: "PublishExtensionPointCommand",
40
+ _0: id,
41
+ _1: {
42
+ TAG: "ConnectPlugin",
43
+ _0: pluginDefinition
44
+ }
45
+ }];
46
+ }
27
47
  };
28
48
  let $$let = ExtensionMapping$ReventlessInfra.NoDelegate.Id;
29
49
  let ConnectPluginMapping = ExtensionMapping$ReventlessInfra.Make({
@@ -26,7 +26,13 @@ module Make = (
26
26
 
27
27
  let name = PluginMappingInstance.Mapping.delegateName
28
28
  let moduleUrl = PluginExtensionPointSpec.moduleUrl
29
- let mappings: array<module(Mapping)> = [module(PluginMappingInstance.Mapping)]
29
+ // The UI-fragment mapping routes RegisterUiFragment / (Disconnect →) DeregisterUiFragment to
30
+ // the admin UiFragmentRegistry slice; the Plugin mapping keeps the lifecycle. Both run per
31
+ // incoming command (ExtensionPoint_Callback fans commands through all mappings).
32
+ let mappings: array<module(Mapping)> = [
33
+ module(PluginMappingInstance.Mapping),
34
+ module(PluginExtensionPoint_UiFragment.Mapping),
35
+ ]
30
36
  }
31
37
  include ExtensionPoint_Builder.Make(
32
38
  PluginExtensionPointSpec,
@@ -3,12 +3,16 @@
3
3
  import * as ExtensionPoint_Builder$ReventlessCore from "../../components/ExtensionPoint/ExtensionPoint_Builder.res.mjs";
4
4
  import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/PluginExtensionPointSpec.res.mjs";
5
5
  import * as PluginExtensionPoint_Plugin$ReventlessCore from "./PluginExtensionPoint_Plugin.res.mjs";
6
+ import * as PluginExtensionPoint_UiFragment$ReventlessCore from "./PluginExtensionPoint_UiFragment.res.mjs";
6
7
 
7
8
  function Make(Spec) {
8
9
  return RuntimeEnvironment => (CommandTopicChannel => (EventTopicAdapter => (ExtensionPointRuntimeBuilder => {
9
10
  let PluginMappingInstance = PluginExtensionPoint_Plugin$ReventlessCore.Make(Spec);
10
11
  let name = PluginMappingInstance.Mapping.delegateName;
11
- let mappings = [PluginMappingInstance.Mapping];
12
+ let mappings = [
13
+ PluginMappingInstance.Mapping,
14
+ PluginExtensionPoint_UiFragment$ReventlessCore.Mapping
15
+ ];
12
16
  let Mappings = {
13
17
  name: name,
14
18
  moduleUrl: PluginExtensionPointSpec$ReventlessInfra.moduleUrl,
@@ -191,6 +191,9 @@ module Make = (Spec: Spec) => {
191
191
  HandleDirective(directiveHandler, DeleteDisconnectSchedule(id)),
192
192
  ]
193
193
  | ForwardCommand(forwardCommand) => [HandleDirective(directiveHandler, ForwardCommand(forwardCommand))]
194
+ // Routed to the UiFragmentRegistry slice by the sibling UI-fragment mapping, not the
195
+ // Plugin aggregate — a no-op here.
196
+ | RegisterUiFragment(_) => []
194
197
  }
195
198
 
196
199
  let mapOutgoingEvent = Some(
@@ -230,7 +233,6 @@ module Make = (Spec: Spec) => {
230
233
  | IncompatiblePluginDetected(pluginDefinition) => [
231
234
  PublishEvent(pluginDefinition.id, IncompatiblePlugin(pluginDefinition)),
232
235
  ]
233
- | UIFragmentRegistered(_) | UIFragmentUpdated(_) | UIFragmentDeregistered(_) => []
234
236
  },
235
237
  )
236
238
  }
@@ -183,6 +183,8 @@ function Make(Spec) {
183
183
  _0: cmd._0
184
184
  }
185
185
  }];
186
+ case "RegisterUiFragment" :
187
+ return [];
186
188
  case "RedetectPlugin" :
187
189
  return [
188
190
  {
@@ -213,6 +215,8 @@ function Make(Spec) {
213
215
  _0: Plugin$ReventlessCore.makeId(id, event._0),
214
216
  _1: "UnknownPluginDetected"
215
217
  }];
218
+ case "VersionSuperseded" :
219
+ return [];
216
220
  case "VersionConnected" :
217
221
  case "VersionPromoted" :
218
222
  break;
@@ -296,8 +300,6 @@ function Make(Spec) {
296
300
  _0: pluginDefinition$4
297
301
  }
298
302
  }];
299
- default:
300
- return [];
301
303
  }
302
304
  let pluginDefinition$5 = event._0;
303
305
  return [
@@ -0,0 +1,52 @@
1
+ // Second mapping on the admin PluginExtensionPoint, routing UI-fragment lifecycle to the
2
+ // admin UiFragmentRegistry StateChangeSlice (docs/plans/event-sourced-fragment-registries.md).
3
+ //
4
+ // The EP runtime fans every incoming command through ALL mappings and flattens the results
5
+ // (ExtensionPoint_Callback.mapIncomingCommands). This mapping's Delegate is the slice, so its
6
+ // PublishCommand encodes with the slice's commandSchema and routes to the slice's command
7
+ // topic via publishToAggregates["UiFragmentRegistry"] (registered by Platform_Admin's merge).
8
+ // The sibling PluginExtensionPoint_Plugin mapping keeps handling lifecycle for the Plugin
9
+ // aggregate; the two run side by side on the same EP.
10
+ //
11
+ // A StateChangeSlice Spec structurally satisfies Reventless.Aggregate.Spec (name, Id,
12
+ // command/event/error + schemas, commandSchema, commandAuthorization, moduleUrl), which is all
13
+ // ExtensionPointMapping.Make consumes from a Delegate.
14
+
15
+ open ReventlessInfra.ExtensionPointMapping
16
+
17
+ module PluginExtensionPointSpec = ReventlessInfra.PluginExtensionPointSpec
18
+
19
+ module UiFragmentMapping = {
20
+ module ExtensionPoint = PluginExtensionPointSpec
21
+ module Delegate = UiFragmentRegistry
22
+
23
+ let moduleUrl: string = %raw(`import.meta.url`)
24
+
25
+ // `id` is the EP transport id (`name@version`); the registry is keyed by bare plugin name,
26
+ // so route on `Plugin.name(id)`. `at` carries the incoming command's producer time (the
27
+ // StateViewSlice projection has no event meta).
28
+ let mapIncomingCommand = (id, cmd, meta: Reventless.Message.meta) =>
29
+ switch cmd {
30
+ | PluginExtensionPointSpec.RegisterUiFragment(manifest) => [
31
+ PublishCommand(
32
+ Plugin.name(id),
33
+ Delegate.RegisterUiFragment({
34
+ pluginId: Plugin.name(id),
35
+ manifest,
36
+ at: meta.time,
37
+ }),
38
+ ),
39
+ ]
40
+ // Deregistration rides DisconnectPlugin, which the admin disconnect schedule also sends on
41
+ // heartbeat timeout — so both graceful and timeout disconnects deregister the fragment.
42
+ | DisconnectPlugin => [
43
+ PublishCommand(Plugin.name(id), Delegate.DeregisterUiFragment({pluginId: Plugin.name(id)})),
44
+ ]
45
+ | Heartbeat(_) | ConnectPlugin(_) | RedetectPlugin(_) | ForwardCommand(_) => []
46
+ }
47
+
48
+ // This mapping never reflects slice events back through the EP.
49
+ let mapOutgoingEvent = None
50
+ }
51
+
52
+ module Mapping = ReventlessInfra.ExtensionPointMapping.Make(UiFragmentMapping)
@@ -0,0 +1,74 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
+ import * as Plugin$ReventlessCore from "../component/Plugin.res.mjs";
5
+ import * as UiFragmentRegistry$ReventlessCore from "../../admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res.mjs";
6
+ import * as ExtensionPointMapping$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/ExtensionPointMapping.res.mjs";
7
+ import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/PluginExtensionPointSpec.res.mjs";
8
+
9
+ let moduleUrl = import.meta.url;
10
+
11
+ function mapIncomingCommand(id, cmd, meta) {
12
+ if (typeof cmd !== "object") {
13
+ return [{
14
+ TAG: "PublishCommand",
15
+ _0: Plugin$ReventlessCore.name(id),
16
+ _1: {
17
+ TAG: "DeregisterUiFragment",
18
+ pluginId: Plugin$ReventlessCore.name(id)
19
+ }
20
+ }];
21
+ } else if (cmd.TAG === "RegisterUiFragment") {
22
+ return [{
23
+ TAG: "PublishCommand",
24
+ _0: Plugin$ReventlessCore.name(id),
25
+ _1: {
26
+ TAG: "RegisterUiFragment",
27
+ pluginId: Plugin$ReventlessCore.name(id),
28
+ manifest: cmd._0,
29
+ at: meta.time
30
+ }
31
+ }];
32
+ } else {
33
+ return [];
34
+ }
35
+ }
36
+
37
+ let UiFragmentMapping = {
38
+ ExtensionPoint: undefined,
39
+ Delegate: undefined,
40
+ moduleUrl: moduleUrl,
41
+ mapIncomingCommand: mapIncomingCommand,
42
+ mapOutgoingEvent: undefined
43
+ };
44
+
45
+ let Mapping = ExtensionPointMapping$ReventlessInfra.Make({
46
+ ExtensionPoint: {
47
+ name: PluginExtensionPointSpec$ReventlessInfra.name,
48
+ moduleUrl: PluginExtensionPointSpec$ReventlessInfra.moduleUrl,
49
+ commandSchema: PluginExtensionPointSpec$ReventlessInfra.commandSchema,
50
+ eventSchema: PluginExtensionPointSpec$ReventlessInfra.eventSchema,
51
+ directiveSchema: PluginExtensionPointSpec$ReventlessInfra.directiveSchema
52
+ },
53
+ Delegate: {
54
+ Id: Id$Reventless.$$String,
55
+ name: UiFragmentRegistry$ReventlessCore.name,
56
+ eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
57
+ errorSchema: UiFragmentRegistry$ReventlessCore.errorSchema,
58
+ commandSchema: UiFragmentRegistry$ReventlessCore.commandSchema,
59
+ moduleUrl: UiFragmentRegistry$ReventlessCore.moduleUrl,
60
+ commandAuthorization: UiFragmentRegistry$ReventlessCore.commandAuthorization
61
+ },
62
+ moduleUrl: moduleUrl,
63
+ mapIncomingCommand: mapIncomingCommand,
64
+ mapOutgoingEvent: undefined
65
+ });
66
+
67
+ let PluginExtensionPointSpec;
68
+
69
+ export {
70
+ PluginExtensionPointSpec,
71
+ UiFragmentMapping,
72
+ Mapping,
73
+ }
74
+ /* moduleUrl Not a pure module */
@@ -38,18 +38,6 @@ let snapshot = None
38
38
 
39
39
  let atomicCounter = None
40
40
 
41
- let uiRegisterEvents = (pluginId, manifest) =>
42
- switch manifest {
43
- | None => []
44
- | Some(manifest) => [(UIFragmentRegistered({pluginId, manifest}): event)]
45
- }
46
-
47
- let uiDeregisterEvents = (pluginId, manifest) =>
48
- switch manifest {
49
- | None => []
50
- | Some(_) => [(UIFragmentDeregistered({pluginId: pluginId}): event)]
51
- }
52
-
53
41
  // Highest version with status Connected, or None.
54
42
  let highestConnected = (known: dict<knownVersion>): option<version> =>
55
43
  known
@@ -93,11 +81,11 @@ let currentAfterConnect = (known, v) =>
93
81
  | Some(h) => Plugin.compareVersions(v, h) >= 0 ? v : h
94
82
  }
95
83
 
96
- // Events emitted when `v` (with `def`) becomes Connected: the VersionConnected +
97
- // UI register, plus a VersionSuperseded record when `v` takes over from a
84
+ // Events emitted when `v` (with `def`) becomes Connected: the VersionConnected,
85
+ // plus a VersionSuperseded record when `v` takes over from a
98
86
  // different current version.
99
87
  let connectEvents = (state: state, v: version, def: pluginDefinition): array<event> => {
100
- let base = Array.concat([VersionConnected(def)], uiRegisterEvents(def.id, def.uiFragments))
88
+ let base = [VersionConnected(def)]
101
89
  let supersede = if currentAfterConnect(state.known, v) == v {
102
90
  switch state.current {
103
91
  | Some(c) if c != v =>
@@ -159,7 +147,7 @@ let decide = (state, command) =>
159
147
  let v = def.version
160
148
  switch state.known->Dict.get(v) {
161
149
  // Idempotent when the definition is unchanged; when a redeploy carries a changed
162
- // definition (e.g. a newly added `kind`, updated uiFragments/protocols) re-emit
150
+ // definition (e.g. a newly added `kind`, updated protocols) re-emit
163
151
  // VersionConnected to overwrite the stored def and re-project the row. The version
164
152
  // is already current, so connectEvents' supersede stays empty — a bare refresh.
165
153
  | Some({status: Connected, definition}) => definition == def ? Ok([]) : Ok([VersionConnected(def)])
@@ -168,24 +156,13 @@ let decide = (state, command) =>
168
156
  | Disconnect(v) =>
169
157
  switch state.known->Dict.get(v) {
170
158
  | Some({status: Connected, definition}) =>
171
- Ok(
172
- Array.concat(
173
- Array.concat(
174
- [VersionDisconnected(definition)],
175
- uiDeregisterEvents(definition.id, definition.uiFragments),
176
- ),
177
- promoteEvents(state, v),
178
- ),
179
- )
159
+ Ok(Array.concat([VersionDisconnected(definition)], promoteEvents(state, v)))
180
160
  | _ => Ok([]) // not connected / unknown → tolerate stray disconnect
181
161
  }
182
162
  | Activate(v) =>
183
163
  switch state.known->Dict.get(v) {
184
164
  | Some({status: Inactive | Retired, definition}) =>
185
- let base = Array.concat(
186
- [VersionActivated(definition)],
187
- uiRegisterEvents(definition.id, definition.uiFragments),
188
- )
165
+ let base = [VersionActivated(definition)]
189
166
  let supersede = if currentAfterConnect(state.known, v) == v {
190
167
  switch state.current {
191
168
  | Some(c) if c != v =>
@@ -213,15 +190,7 @@ let decide = (state, command) =>
213
190
  | Deactivate(v) =>
214
191
  switch state.known->Dict.get(v) {
215
192
  | Some({status: Connected | Disconnected, definition}) =>
216
- Ok(
217
- Array.concat(
218
- Array.concat(
219
- [VersionDeactivated(definition)],
220
- uiDeregisterEvents(definition.id, definition.uiFragments),
221
- ),
222
- promoteEvents(state, v),
223
- ),
224
- )
193
+ Ok(Array.concat([VersionDeactivated(definition)], promoteEvents(state, v)))
225
194
  | Some({status: Inactive | Retired}) => Ok([]) // idempotent / archived no-op
226
195
  | None => Error(UnknownVersion)
227
196
  }
@@ -229,15 +198,7 @@ let decide = (state, command) =>
229
198
  switch state.known->Dict.get(v) {
230
199
  | Some({status: Retired}) => Ok([]) // idempotent
231
200
  | Some({definition}) =>
232
- Ok(
233
- Array.concat(
234
- Array.concat(
235
- [VersionRetired(definition)],
236
- uiDeregisterEvents(definition.id, definition.uiFragments),
237
- ),
238
- promoteEvents(state, v),
239
- ),
240
- )
201
+ Ok(Array.concat([VersionRetired(definition)], promoteEvents(state, v)))
241
202
  | None => Error(UnknownVersion)
242
203
  }
243
204
  | ReportIncompatibility(def) => Ok([IncompatiblePluginDetected(def)])
@@ -262,9 +223,6 @@ let evolve = (state: state, event) => {
262
223
  | VersionDetected(_)
263
224
  | VersionSuperseded(_)
264
225
  | VersionPromoted(_)
265
- | IncompatiblePluginDetected(_)
266
- | UIFragmentRegistered(_)
267
- | UIFragmentUpdated(_)
268
- | UIFragmentDeregistered(_) => state
226
+ | IncompatiblePluginDetected(_) => state
269
227
  }
270
228
  }
@@ -30,33 +30,6 @@ let initialState = {
30
30
  known: initialState_known
31
31
  };
32
32
 
33
- function uiRegisterEvents(pluginId, manifest) {
34
- if (manifest !== undefined) {
35
- return [{
36
- TAG: "UIFragmentRegistered",
37
- _0: {
38
- pluginId: pluginId,
39
- manifest: manifest
40
- }
41
- }];
42
- } else {
43
- return [];
44
- }
45
- }
46
-
47
- function uiDeregisterEvents(pluginId, manifest) {
48
- if (manifest !== undefined) {
49
- return [{
50
- TAG: "UIFragmentDeregistered",
51
- _0: {
52
- pluginId: pluginId
53
- }
54
- }];
55
- } else {
56
- return [];
57
- }
58
- }
59
-
60
33
  function highestConnected(known) {
61
34
  return Stdlib_Array.reduce(Object.entries(known), undefined, (acc, param) => {
62
35
  let v = param[0];
@@ -97,7 +70,7 @@ function connectEvents(state, v, def) {
97
70
  let base = [{
98
71
  TAG: "VersionConnected",
99
72
  _0: def
100
- }].concat(uiRegisterEvents(def.id, def.uiFragments));
73
+ }];
101
74
  let supersede;
102
75
  if (currentAfterConnect(state.known, v) === v) {
103
76
  let c = state.current;
@@ -229,26 +202,27 @@ function decide(state, command) {
229
202
  case "Disconnect" :
230
203
  let v$3 = command._0;
231
204
  let match$3 = state.known[v$3];
232
- if (match$3 === undefined) {
233
- return {
234
- TAG: "Ok",
235
- _0: []
236
- };
237
- }
238
- if (match$3.status !== "Connected") {
205
+ if (match$3 !== undefined) {
206
+ if (match$3.status === "Connected") {
207
+ return {
208
+ TAG: "Ok",
209
+ _0: [{
210
+ TAG: "VersionDisconnected",
211
+ _0: match$3.definition
212
+ }].concat(promoteEvents(state, v$3))
213
+ };
214
+ } else {
215
+ return {
216
+ TAG: "Ok",
217
+ _0: []
218
+ };
219
+ }
220
+ } else {
239
221
  return {
240
222
  TAG: "Ok",
241
223
  _0: []
242
224
  };
243
225
  }
244
- let definition = match$3.definition;
245
- return {
246
- TAG: "Ok",
247
- _0: [{
248
- TAG: "VersionDisconnected",
249
- _0: definition
250
- }].concat(uiDeregisterEvents(definition.id, definition.uiFragments)).concat(promoteEvents(state, v$3))
251
- };
252
226
  case "Activate" :
253
227
  let v$4 = command._0;
254
228
  let match$4 = state.known[v$4];
@@ -258,7 +232,7 @@ function decide(state, command) {
258
232
  _0: "UnknownVersion"
259
233
  };
260
234
  }
261
- let definition$1 = match$4.definition;
235
+ let definition = match$4.definition;
262
236
  switch (match$4.status) {
263
237
  case "Connected" :
264
238
  return {
@@ -276,8 +250,8 @@ function decide(state, command) {
276
250
  }
277
251
  let base = [{
278
252
  TAG: "VersionActivated",
279
- _0: definition$1
280
- }].concat(uiRegisterEvents(definition$1.id, definition$1.uiFragments));
253
+ _0: definition
254
+ }];
281
255
  let supersede;
282
256
  if (currentAfterConnect(state.known, v$4) === v$4) {
283
257
  let c = state.current;
@@ -290,7 +264,7 @@ function decide(state, command) {
290
264
  supersededVersion: c,
291
265
  supersededDefinition: match$5.definition,
292
266
  newVersion: v$4,
293
- newDefinition: definition$1
267
+ newDefinition: definition
294
268
  }
295
269
  }] : [];
296
270
  } else {
@@ -316,7 +290,6 @@ function decide(state, command) {
316
290
  _0: "UnknownVersion"
317
291
  };
318
292
  }
319
- let definition$2 = match$6.definition;
320
293
  switch (match$6.status) {
321
294
  case "Connected" :
322
295
  case "Disconnected" :
@@ -332,8 +305,8 @@ function decide(state, command) {
332
305
  TAG: "Ok",
333
306
  _0: [{
334
307
  TAG: "VersionDeactivated",
335
- _0: definition$2
336
- }].concat(uiDeregisterEvents(definition$2.id, definition$2.uiFragments)).concat(promoteEvents(state, v$5))
308
+ _0: match$6.definition
309
+ }].concat(promoteEvents(state, v$5))
337
310
  };
338
311
  break;
339
312
  case "ReportIncompatibility" :
@@ -347,27 +320,27 @@ function decide(state, command) {
347
320
  case "Retire" :
348
321
  let v$6 = command._0;
349
322
  let match$7 = state.known[v$6];
350
- if (match$7 === undefined) {
323
+ if (match$7 !== undefined) {
324
+ if (match$7.status === "Retired") {
325
+ return {
326
+ TAG: "Ok",
327
+ _0: []
328
+ };
329
+ } else {
330
+ return {
331
+ TAG: "Ok",
332
+ _0: [{
333
+ TAG: "VersionRetired",
334
+ _0: match$7.definition
335
+ }].concat(promoteEvents(state, v$6))
336
+ };
337
+ }
338
+ } else {
351
339
  return {
352
340
  TAG: "Error",
353
341
  _0: "UnknownVersion"
354
342
  };
355
343
  }
356
- let definition$3 = match$7.definition;
357
- if (match$7.status === "Retired") {
358
- return {
359
- TAG: "Ok",
360
- _0: []
361
- };
362
- } else {
363
- return {
364
- TAG: "Ok",
365
- _0: [{
366
- TAG: "VersionRetired",
367
- _0: definition$3
368
- }].concat(uiDeregisterEvents(definition$3.id, definition$3.uiFragments)).concat(promoteEvents(state, v$6))
369
- };
370
- }
371
344
  }
372
345
  }
373
346
 
@@ -419,8 +392,6 @@ export {
419
392
  initialState,
420
393
  snapshot,
421
394
  atomicCounter,
422
- uiRegisterEvents,
423
- uiDeregisterEvents,
424
395
  highestConnected,
425
396
  highestConnectedExcluding,
426
397
  currentAfterConnect,
@@ -26,19 +26,6 @@ type command =
26
26
  // automatic `Superseded` transition (which is decided, not commanded).
27
27
  | Retire(version)
28
28
 
29
- @schema
30
- type uiFragmentRegisteredData = {pluginId: string, manifest: uiFragmentManifest}
31
-
32
- @schema
33
- type uiFragmentUpdatedData = {
34
- pluginId: string,
35
- previousManifest: uiFragmentManifest,
36
- newManifest: uiFragmentManifest,
37
- }
38
-
39
- @schema
40
- type uiFragmentDeregisteredData = {pluginId: string}
41
-
42
29
  // Carries both the superseded and the superseding version's full definition —
43
30
  // a deterministic trigger for version-to-version schema/data migrations
44
31
  // (analysis §6.2.4).
@@ -72,11 +59,6 @@ type event =
72
59
  | VersionRetired(pluginDefinition)
73
60
  // Protocol incompatibility recorded at connect; connection still proceeds.
74
61
  | IncompatiblePluginDetected(pluginDefinition)
75
- // UI fragment lifecycle events — emitted alongside connect/disconnect/(de)activate
76
- // when the plugin's pluginDefinition.uiFragments is set.
77
- | UIFragmentRegistered(uiFragmentRegisteredData)
78
- | UIFragmentUpdated(uiFragmentUpdatedData)
79
- | UIFragmentDeregistered(uiFragmentDeregisteredData)
80
62
 
81
63
  @schema
82
64
  type error =
@@ -39,21 +39,6 @@ let commandSchema = S.union([
39
39
  }))
40
40
  ]);
41
41
 
42
- let uiFragmentRegisteredDataSchema = S.schema(s => ({
43
- pluginId: s.m(S.string),
44
- manifest: s.m(Plugin$Reventless.uiFragmentManifestSchema)
45
- }));
46
-
47
- let uiFragmentUpdatedDataSchema = S.schema(s => ({
48
- pluginId: s.m(S.string),
49
- previousManifest: s.m(Plugin$Reventless.uiFragmentManifestSchema),
50
- newManifest: s.m(Plugin$Reventless.uiFragmentManifestSchema)
51
- }));
52
-
53
- let uiFragmentDeregisteredDataSchema = S.schema(s => ({
54
- pluginId: s.m(S.string)
55
- }));
56
-
57
42
  let versionSupersededDataSchema = S.schema(s => ({
58
43
  supersededVersion: s.m(Plugin$Reventless.versionSchema),
59
44
  supersededDefinition: s.m(Plugin$Reventless.pluginDefinitionSchema),
@@ -97,18 +82,6 @@ let eventSchema = S.union([
97
82
  S.schema(s => ({
98
83
  TAG: "IncompatiblePluginDetected",
99
84
  _0: s.m(Plugin$Reventless.pluginDefinitionSchema)
100
- })),
101
- S.schema(s => ({
102
- TAG: "UIFragmentRegistered",
103
- _0: s.m(uiFragmentRegisteredDataSchema)
104
- })),
105
- S.schema(s => ({
106
- TAG: "UIFragmentUpdated",
107
- _0: s.m(uiFragmentUpdatedDataSchema)
108
- })),
109
- S.schema(s => ({
110
- TAG: "UIFragmentDeregistered",
111
- _0: s.m(uiFragmentDeregisteredDataSchema)
112
85
  }))
113
86
  ]);
114
87
 
@@ -140,9 +113,6 @@ let moduleUrl = "@reventlessdev/reventless-core/src/plugin/lifecycle/PluginSpec.
140
113
  export {
141
114
  name,
142
115
  Id,
143
- uiFragmentRegisteredDataSchema,
144
- uiFragmentUpdatedDataSchema,
145
- uiFragmentDeregisteredDataSchema,
146
116
  versionSupersededDataSchema,
147
117
  eventSchema,
148
118
  errorSchema,
@@ -55,7 +55,6 @@ let displayState = (
55
55
  status,
56
56
  statusChange,
57
57
  apiSchemaFragment: def.apiSchemaFragment,
58
- uiFragments: def.uiFragments,
59
58
  structure: def.structure,
60
59
  dcbEventLog: def.dcbEventLog,
61
60
  // A freshly projected row always knows its kind (the definition carries it as a
@@ -78,14 +77,11 @@ module PluginMapping = Reventless.Projection.Mapping.Make(
78
77
  let project = ({event, id, meta: {time, user: ?user}}) => {
79
78
  let statusChange = {at: time, by: user->Option.getOr("")}
80
79
  switch event {
81
- // Handshake trigger, supersession record, incompatibility and UI-fragment
80
+ // Handshake trigger, supersession record and incompatibility
82
81
  // events do not change which version is current.
83
82
  | PluginSpec.VersionDetected(_)
84
83
  | VersionSuperseded(_)
85
- | IncompatiblePluginDetected(_)
86
- | UIFragmentRegistered(_)
87
- | UIFragmentUpdated(_)
88
- | UIFragmentDeregistered(_) =>
84
+ | IncompatiblePluginDetected(_) =>
89
85
  Reventless.Projection.Ignore
90
86
 
91
87
  // A version became live. It becomes current iff it is the highest
@@ -71,7 +71,6 @@ function displayState(def, status, statusChange, otherConnectedVersions) {
71
71
  let base_extensionNames = def.extensions.map(extension => extension.extensionPointName);
72
72
  let base_extensions = def.extensions;
73
73
  let base_apiSchemaFragment = def.apiSchemaFragment;
74
- let base_uiFragments = def.uiFragments;
75
74
  let base_structure = def.structure;
76
75
  let base_dcbEventLog = def.dcbEventLog;
77
76
  let base_kind = def.kind;
@@ -87,7 +86,6 @@ function displayState(def, status, statusChange, otherConnectedVersions) {
87
86
  status: status,
88
87
  statusChange: statusChange,
89
88
  apiSchemaFragment: base_apiSchemaFragment,
90
- uiFragments: base_uiFragments,
91
89
  structure: base_structure,
92
90
  dcbEventLog: base_dcbEventLog,
93
91
  kind: base_kind,