@reventlessdev/reventless-local 3.0.0-alpha.152 → 3.0.0-alpha.153
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 +7 -0
- package/package.json +10 -10
- package/src/Platform.res +40 -184
- package/src/Platform.res.mjs +54 -353
- package/src/adapter/Api/LocalGraphQL_Adapter.res +1 -11
- package/src/adapter/Api/LocalGraphQL_Adapter.res.mjs +0 -7
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +6 -6
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res.mjs +3 -5
- package/src/adapter/DomainGraphQL_Server.res +323 -131
- package/src/adapter/DomainGraphQL_Server.res.mjs +252 -123
- package/src/adapter/GraphQL_Server.res.mjs +41 -17
- package/tests/adapter/DomainGraphQL_ServerTest.res +161 -0
- package/tests/adapter/DomainGraphQL_ServerTest.res.mjs +192 -0
- package/tests/plugin/ApiFragmentRegistryBehavior_GWT.res +0 -131
- package/tests/plugin/ApiFragmentRegistryBehavior_GWT.res.mjs +0 -268
- package/tests/plugin/ApiFragmentsProjection_GWT.res +0 -108
- package/tests/plugin/ApiFragmentsProjection_GWT.res.mjs +0 -172
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
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.153 (2026-07-14)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **local:** plugin=subgraph composition — per-plugin subschemas merged at start (Phase 6, plan complete) ([40f44c5](https://github.com/ReventlessDev/reventless-core/commit/40f44c5c6aa32fbbd64f362841cf41ba4e2fc2e0))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# 3.0.0-alpha.152 (2026-07-14)
|
|
7
14
|
|
|
8
15
|
**Note:** Version bump only for package @reventlessdev/reventless-local
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-local",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.153",
|
|
4
4
|
"description": "Local platform for Reventless (in-memory or SQLite backend, for development and testing without AWS)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -31,17 +31,17 @@
|
|
|
31
31
|
"graphql-yoga": "^5.21.0",
|
|
32
32
|
"sury": "11.0.0-alpha.4",
|
|
33
33
|
"ws": "^8.18.0",
|
|
34
|
-
"@reventlessdev/rescript-jest": "1.0.0-alpha.7",
|
|
35
34
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.27",
|
|
36
|
-
"@reventlessdev/rescript-
|
|
35
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.7",
|
|
37
36
|
"@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.18",
|
|
38
|
-
"@reventlessdev/
|
|
39
|
-
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.
|
|
40
|
-
"@reventlessdev/reventless-
|
|
41
|
-
"@reventlessdev/reventless-
|
|
42
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.
|
|
43
|
-
"@reventlessdev/reventless-
|
|
44
|
-
"@reventlessdev/reventless-
|
|
37
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.15",
|
|
38
|
+
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.21",
|
|
39
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.167",
|
|
40
|
+
"@reventlessdev/reventless-graphql-server": "1.0.0-alpha.14",
|
|
41
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.99",
|
|
42
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.76",
|
|
43
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.31",
|
|
44
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.113"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"rescript": "^12.3.0",
|
package/src/Platform.res
CHANGED
|
@@ -61,23 +61,6 @@ let decodeUiFragmentRegistryEventEnvelope = (
|
|
|
61
61
|
| exception _ => None
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// Same {id, meta, event} envelope for the ApiFragmentRegistry singleton aggregate's
|
|
65
|
-
// events on its own aggregate event topic (the registry is an aggregate now, not a
|
|
66
|
-
// DCB slice — its events no longer ride the admin DcbEventLog). Top-level so the
|
|
67
|
-
// decode is unit-testable.
|
|
68
|
-
let decodeApiFragmentRegistryEventEnvelope = (
|
|
69
|
-
eventJson: JSON.t,
|
|
70
|
-
): option<ReventlessCore.ApiFragmentRegistrySpec.event> =>
|
|
71
|
-
switch eventJson
|
|
72
|
-
->JSON.Decode.object
|
|
73
|
-
->Option.flatMap(d => d->Dict.get("event"))
|
|
74
|
-
->Option.map(payload =>
|
|
75
|
-
payload->S.parseJsonOrThrow(ReventlessCore.ApiFragmentRegistrySpec.eventSchema)
|
|
76
|
-
) {
|
|
77
|
-
| result => result
|
|
78
|
-
| exception _ => None
|
|
79
|
-
}
|
|
80
|
-
|
|
81
64
|
// Configurable platform — set silent=true to suppress diagnostic warnings in tests,
|
|
82
65
|
// splitApi=true to serve core and plugin APIs on separate ports,
|
|
83
66
|
// backend=Backend.Sqlite({...}) to opt into file-backed SQLite persistence.
|
|
@@ -176,6 +159,30 @@ module MakeWithConfig = (
|
|
|
176
159
|
// Domain = plugin-facing (default); Platform = admin/core (split mode).
|
|
177
160
|
let currentDeployTarget: ref<apiTarget> = ref(Domain)
|
|
178
161
|
|
|
162
|
+
// Plugin=subgraph scoping (mirrors the AWS plugin=source-API model): each
|
|
163
|
+
// plugin's construction runs inside its own DomainGraphQL_Server scope so
|
|
164
|
+
// its GraphQL registrations form a standalone subgraph, validated in
|
|
165
|
+
// isolation and composed at start(). The plugin name is only known after
|
|
166
|
+
// construction (via the synchronous plugin-built hook), so the scope opens
|
|
167
|
+
// under a unique token and is relabeled to the plugin name afterwards.
|
|
168
|
+
let pluginScopeCounter = ref(0)
|
|
169
|
+
let buildPluginInScope = (
|
|
170
|
+
~makePlugin: unit => ReventlessCore.Plugin.component,
|
|
171
|
+
~builtInfos: ref<array<ReventlessCore.Plugin_Helpers.pluginBuiltInfo>>,
|
|
172
|
+
): ReventlessCore.Plugin.component => {
|
|
173
|
+
pluginScopeCounter.contents = pluginScopeCounter.contents + 1
|
|
174
|
+
let scopeToken = `plugin-${pluginScopeCounter.contents->Int.toString}`
|
|
175
|
+
DomainGraphQL_Server.setScope(scopeToken)
|
|
176
|
+
let countBefore = builtInfos.contents->Array.length
|
|
177
|
+
let component = makePlugin()
|
|
178
|
+
switch builtInfos.contents->Array.get(countBefore) {
|
|
179
|
+
| Some(info) => DomainGraphQL_Server.relabelScope(~from=scopeToken, ~to_=info.name)
|
|
180
|
+
| None => ()
|
|
181
|
+
}
|
|
182
|
+
DomainGraphQL_Server.resetScope()
|
|
183
|
+
component
|
|
184
|
+
}
|
|
185
|
+
|
|
179
186
|
// Track which GraphQL servers have had admin schema (Plugin queries/mutations) registered.
|
|
180
187
|
// Prevents double-registration when makePlatform and deployPlugin both target the same server.
|
|
181
188
|
let adminRegisteredServers: ref<array<ReventlessGraphqlServer.GraphQL_ServerInstance.t>> = ref([])
|
|
@@ -672,8 +679,7 @@ module MakeWithConfig = (
|
|
|
672
679
|
|
|
673
680
|
// Admin UI-fragment registry (docs/plans/event-sourced-fragment-registries.md): the
|
|
674
681
|
// platform UI-fragment registry hosted as an admin DCB slice on the admin DcbEventLog.
|
|
675
|
-
// Built once and passed into Admin.construct below.
|
|
676
|
-
// singleton aggregate — see LocalApiFragmentRegistryAggregate — not a slice.)
|
|
682
|
+
// Built once and passed into Admin.construct below.
|
|
677
683
|
module UiFragmentRegistrySlice = StateChangeSlice.Make(
|
|
678
684
|
ReventlessCore.UiFragmentRegistry,
|
|
679
685
|
ReventlessCore.UiFragmentRegistry_Behavior,
|
|
@@ -716,35 +722,6 @@ module MakeWithConfig = (
|
|
|
716
722
|
InboundTranslationSliceMaker.Make(Spec, Translation)
|
|
717
723
|
}
|
|
718
724
|
|
|
719
|
-
// Empty base fragment — no types, no mutations, no queries.
|
|
720
|
-
// Used by the plugin Api in split mode so plugin schema has no core fields.
|
|
721
|
-
let emptyBaseFragment = ReventlessCore.GraphQL_Stitcher.encode({
|
|
722
|
-
types: [],
|
|
723
|
-
mutations: [],
|
|
724
|
-
queries: [],
|
|
725
|
-
subscriptions: [],
|
|
726
|
-
subscriptionSources: [],
|
|
727
|
-
})
|
|
728
|
-
|
|
729
|
-
module Api = {
|
|
730
|
-
module Make = (
|
|
731
|
-
FragmentConfig: {
|
|
732
|
-
let baseFragment: ReventlessInfra.Api.schemaFragment
|
|
733
|
-
},
|
|
734
|
-
): ReventlessInfra.Api.T => {
|
|
735
|
-
module Builder = ReventlessCore.Api_Builder.Make(LocalGraphQL_Adapter)
|
|
736
|
-
// In split mode, the plugin API uses an empty base fragment so plugin schema
|
|
737
|
-
// has no core fields. In unified mode, use the provided base fragment as-is.
|
|
738
|
-
let effectiveBaseFragment = if Config.splitApi {
|
|
739
|
-
emptyBaseFragment
|
|
740
|
-
} else {
|
|
741
|
-
FragmentConfig.baseFragment
|
|
742
|
-
}
|
|
743
|
-
let make = (~name, ~opts=?) =>
|
|
744
|
-
Builder.make(~name, ~baseFragment=effectiveBaseFragment, ~opts?)
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
725
|
module PluginMaker = Plugin_Builder.Make(
|
|
749
726
|
Bus,
|
|
750
727
|
{
|
|
@@ -797,33 +774,6 @@ module MakeWithConfig = (
|
|
|
797
774
|
PluginsReadModelMappings,
|
|
798
775
|
)
|
|
799
776
|
|
|
800
|
-
// Admin-internal ApiFragmentRegistry singleton aggregate — the platform API-schema
|
|
801
|
-
// fragment registry (docs/plans/event-sourced-fragment-registries.md). Threaded into
|
|
802
|
-
// Admin.construct's ~aggregates so registerAdminAggregateMutations wires
|
|
803
|
-
// Platform_ApiFragmentRegistry_RegisterApiFragment / _DeregisterApiFragment through the
|
|
804
|
-
// standard CommandGenerator auto-flow. RecordApiFragmentPush carries `@noApi`.
|
|
805
|
-
module LocalApiFragmentRegistryAggregate: ReventlessInfra.Aggregate.T
|
|
806
|
-
with type api = unit = AggregateMaker.Make(
|
|
807
|
-
ReventlessCore.ApiFragmentRegistrySpec,
|
|
808
|
-
ReventlessCore.ApiFragmentRegistryBehavior,
|
|
809
|
-
ReventlessInfra.NoEventMappings.Make(ReventlessCore.ApiFragmentRegistrySpec),
|
|
810
|
-
)
|
|
811
|
-
|
|
812
|
-
// Admin ApiFragments read model — per-plugin status rows off the aggregate's event
|
|
813
|
-
// topic, backing the Platform_ApiFragments status query.
|
|
814
|
-
module ApiFragmentsReadModelMappings: Reventless.Projection.Mappings
|
|
815
|
-
with module Target := ReventlessCore.ApiFragmentsReadModelSpec = {
|
|
816
|
-
module M = ReventlessCore.ApiFragmentsProjection.Mappings
|
|
817
|
-
module type Mapping = M.Mapping
|
|
818
|
-
let moduleUrl: string = ReventlessCore.ApiFragmentsProjection.moduleUrl
|
|
819
|
-
let mappings: array<module(Mapping)> = ReventlessCore.ApiFragmentsProjection.mappings
|
|
820
|
-
}
|
|
821
|
-
module ApiFragmentsReadModel = ReadModelMaker.MakeNoResolver(
|
|
822
|
-
ReventlessCore.ApiFragmentsReadModelSpec,
|
|
823
|
-
ApiFragmentsReadModelMappings,
|
|
824
|
-
)
|
|
825
|
-
|
|
826
|
-
|
|
827
777
|
module Admin = ReventlessCore.Platform_Admin.Make(
|
|
828
778
|
LocalRuntimeEnvironment,
|
|
829
779
|
EventCollectorChannel,
|
|
@@ -954,57 +904,6 @@ module MakeWithConfig = (
|
|
|
954
904
|
Bus.dispatchCommand(adminDcbCmdTopicKey, ReventlessCore.CommandTopic.encodeCommandJson(cmdJson))
|
|
955
905
|
}
|
|
956
906
|
|
|
957
|
-
// The ApiFragmentRegistry is a SINGLETON aggregate now (not a DCB slice): the
|
|
958
|
-
// whole registry lives on one aggregate instance keyed by a fixed id, so a
|
|
959
|
-
// fragment change reads the whole registry from one consistency boundary. Its
|
|
960
|
-
// commands ride the aggregate command topic (name-derived, like the Plugin
|
|
961
|
-
// aggregate above) and its events its own aggregate event topic.
|
|
962
|
-
let apiFragmentRegistryId = "registry"
|
|
963
|
-
let apiFragmentRegistryCmdTopicKey =
|
|
964
|
-
ReventlessCore.ApiFragmentRegistrySpec.name ++ "Aggr" ++ "CmdTopic"
|
|
965
|
-
let apiFragmentRegistryEventTopicKey =
|
|
966
|
-
ReventlessCore.ApiFragmentRegistrySpec.name ++ "Aggr" ++ "EventTopic"
|
|
967
|
-
|
|
968
|
-
// Dispatch an ApiFragmentRegistry aggregate command in-process. On the real
|
|
969
|
-
// platform the deploy is the caller (SigV4 Platform_ApiFragmentRegistry_*
|
|
970
|
-
// mutation); locally we dispatch straight to the aggregate command topic. The
|
|
971
|
-
// aggregate id is the fixed singleton constant — `pluginId` is a payload field.
|
|
972
|
-
let dispatchApiFragmentCommand = (~command: ReventlessCore.ApiFragmentRegistrySpec.command) => {
|
|
973
|
-
let cmdJson: Reventless.Message.commandJson = {
|
|
974
|
-
id: apiFragmentRegistryId,
|
|
975
|
-
meta: ReventlessCore.Message.generateMeta(
|
|
976
|
-
~service=ReventlessCore.ApiFragmentRegistrySpec.name,
|
|
977
|
-
),
|
|
978
|
-
commandJson: command->S.reverseConvertToJsonOrThrow(
|
|
979
|
-
ReventlessCore.ApiFragmentRegistrySpec.commandSchema,
|
|
980
|
-
),
|
|
981
|
-
}
|
|
982
|
-
Bus.dispatchCommand(
|
|
983
|
-
apiFragmentRegistryCmdTopicKey,
|
|
984
|
-
ReventlessCore.CommandTopic.encodeCommandJson(cmdJson),
|
|
985
|
-
)
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
// Platform_ApiFragments status-query resolver — scans the ApiFragments read
|
|
989
|
-
// model (populated by the ApiFragmentRegistry aggregate's projection) and
|
|
990
|
-
// encodes via the shared Platform_ApiFragmentsApi encoder, so the deploy-facing
|
|
991
|
-
// status shape matches AWS. Keyed by bare plugin name (one row per plugin).
|
|
992
|
-
// Registered at each admin server site below.
|
|
993
|
-
let apiFragmentsQueryResolver = async (_root, _args, _ctx): JSON.t => {
|
|
994
|
-
let items = switch Bus.getQueryDbScan(ReventlessCore.ApiFragmentsReadModelSpec.name) {
|
|
995
|
-
| Some(scanAll) => scanAll()
|
|
996
|
-
| None => []
|
|
997
|
-
}
|
|
998
|
-
items
|
|
999
|
-
->Array.filterMap(item =>
|
|
1000
|
-
switch item->S.parseOrThrow(ReventlessCore.ApiFragmentsReadModelSpec.stateSchema) {
|
|
1001
|
-
| state => Some(ReventlessCore.Platform_ApiFragmentsApi.encodeApiFragmentEntry(state))
|
|
1002
|
-
| exception _ => None
|
|
1003
|
-
}
|
|
1004
|
-
)
|
|
1005
|
-
->JSON.Encode.array
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
907
|
// Subscription topics for the admin live-update channels.
|
|
1009
908
|
let pluginStatusSubTopic = "onPluginStatusChange"
|
|
1010
909
|
let uiFragmentSubTopic = "onUIFragmentChange"
|
|
@@ -1097,33 +996,6 @@ module MakeWithConfig = (
|
|
|
1097
996
|
}
|
|
1098
997
|
}
|
|
1099
998
|
)
|
|
1100
|
-
// Local single writer for the API-schema fragment registry — the analogue of
|
|
1101
|
-
// the AWS ApiSchemaPush SideEffect. Sourced from the ApiFragmentRegistry
|
|
1102
|
-
// aggregate's own event topic (the registry is an aggregate now). On AWS the
|
|
1103
|
-
// SideEffect stitches + pushes the schema then records the outcome; on local
|
|
1104
|
-
// the plugin's fields are already served by resolver registration, so the
|
|
1105
|
-
// "push" is a no-op and we simply record success — the honest status for an
|
|
1106
|
-
// in-process schema. Only Registered/Updated trigger a record (never
|
|
1107
|
-
// PushRecorded — no re-entrant loop; ApiSchemaComputed is the AWS push trigger
|
|
1108
|
-
// and is a no-op here).
|
|
1109
|
-
Bus.subscribeToEvents(apiFragmentRegistryEventTopicKey, async (_service, _meta, eventJson) =>
|
|
1110
|
-
switch decodeApiFragmentRegistryEventEnvelope(eventJson) {
|
|
1111
|
-
| Some(ApiFragmentRegistered({pluginId}))
|
|
1112
|
-
| Some(ApiFragmentUpdated({pluginId})) =>
|
|
1113
|
-
let _ = dispatchApiFragmentCommand(
|
|
1114
|
-
~command=ReventlessCore.ApiFragmentRegistrySpec.RecordApiFragmentPush({
|
|
1115
|
-
pluginId,
|
|
1116
|
-
ok: true,
|
|
1117
|
-
message: "",
|
|
1118
|
-
at: Date.make()->Date.toISOString,
|
|
1119
|
-
}),
|
|
1120
|
-
)
|
|
1121
|
-
| Some(ApiFragmentDeregistered(_))
|
|
1122
|
-
| Some(ApiFragmentPushRecorded(_))
|
|
1123
|
-
| Some(ApiSchemaComputed(_))
|
|
1124
|
-
| None => ()
|
|
1125
|
-
}
|
|
1126
|
-
)
|
|
1127
999
|
}
|
|
1128
1000
|
|
|
1129
1001
|
// Drive the admin Plugin read models the same way AWS does: build a
|
|
@@ -1217,24 +1089,6 @@ module MakeWithConfig = (
|
|
|
1217
1089
|
)
|
|
1218
1090
|
| None => ()
|
|
1219
1091
|
}
|
|
1220
|
-
// Register the API-schema fragment with the ApiFragmentRegistry aggregate.
|
|
1221
|
-
// On the real platform the deploy sends this as a SigV4 caller; locally
|
|
1222
|
-
// connect stands in. apiTarget is Domain (mirrors pluginDefinition.kind
|
|
1223
|
-
// = Domain / apiTarget = None above — the local platform has no
|
|
1224
|
-
// Platform-target plugins). The subscriber below records the push as ok,
|
|
1225
|
-
// since the fields are already served in-process by resolver registration.
|
|
1226
|
-
switch apiSchemaFragment {
|
|
1227
|
-
| Some(fragment) =>
|
|
1228
|
-
let _ = dispatchApiFragmentCommand(
|
|
1229
|
-
~command=ReventlessCore.ApiFragmentRegistrySpec.RegisterApiFragment({
|
|
1230
|
-
pluginId: pluginName,
|
|
1231
|
-
fragment,
|
|
1232
|
-
apiTarget: Domain,
|
|
1233
|
-
at: Date.make()->Date.toISOString,
|
|
1234
|
-
}),
|
|
1235
|
-
)
|
|
1236
|
-
| None => ()
|
|
1237
|
-
}
|
|
1238
1092
|
})
|
|
1239
1093
|
})
|
|
1240
1094
|
}
|
|
@@ -1500,8 +1354,8 @@ module MakeWithConfig = (
|
|
|
1500
1354
|
let admin = Admin.construct(
|
|
1501
1355
|
~version,
|
|
1502
1356
|
~extensionPoints=[],
|
|
1503
|
-
~aggregates=[module(LocalPluginAggregate)
|
|
1504
|
-
~readModels=[module(PluginsReadModel)
|
|
1357
|
+
~aggregates=[module(LocalPluginAggregate)],
|
|
1358
|
+
~readModels=[module(PluginsReadModel)],
|
|
1505
1359
|
~scheduler,
|
|
1506
1360
|
~resourceNaming=LocalPluginSpec.resourceNaming,
|
|
1507
1361
|
~api=(),
|
|
@@ -1531,10 +1385,12 @@ module MakeWithConfig = (
|
|
|
1531
1385
|
builtInfos.contents->Array.push(info)
|
|
1532
1386
|
})
|
|
1533
1387
|
|
|
1534
|
-
// Build each plugin
|
|
1388
|
+
// Build each plugin inside its own DomainGraphQL_Server scope so its
|
|
1389
|
+
// GraphQL registrations form a standalone subgraph (plugin=subgraph,
|
|
1390
|
+
// platform=merge — mirrors the AWS source-API model).
|
|
1535
1391
|
let plugins = plugins->Array.map(plugin => {
|
|
1536
1392
|
module P = unpack(plugin)
|
|
1537
|
-
P.make
|
|
1393
|
+
buildPluginInScope(~makePlugin=P.make, ~builtInfos)
|
|
1538
1394
|
})
|
|
1539
1395
|
|
|
1540
1396
|
// Restore original hook and fire deployed hooks synchronously.
|
|
@@ -1823,8 +1679,6 @@ module MakeWithConfig = (
|
|
|
1823
1679
|
->JSON.Encode.array
|
|
1824
1680
|
},
|
|
1825
1681
|
)
|
|
1826
|
-
queryResolvers->Dict.set("Platform_ApiFragments", apiFragmentsQueryResolver)
|
|
1827
|
-
|
|
1828
1682
|
// Composite-key / index admin query fields. Live loads from the seeded QueryDb stores.
|
|
1829
1683
|
registerAdminItemsAndIndexResolvers(~queryResolvers, ~live=true)
|
|
1830
1684
|
|
|
@@ -2066,8 +1920,8 @@ module MakeWithConfig = (
|
|
|
2066
1920
|
let _admin = Admin.construct(
|
|
2067
1921
|
~version,
|
|
2068
1922
|
~extensionPoints=[],
|
|
2069
|
-
~aggregates=[
|
|
2070
|
-
~readModels=[
|
|
1923
|
+
~aggregates=[],
|
|
1924
|
+
~readModels=[],
|
|
2071
1925
|
~scheduler,
|
|
2072
1926
|
~resourceNaming=LocalPluginSpec.resourceNaming,
|
|
2073
1927
|
~api=(),
|
|
@@ -2105,7 +1959,6 @@ module MakeWithConfig = (
|
|
|
2105
1959
|
"Platform_UIFragments",
|
|
2106
1960
|
async (_root, _args, _ctx): JSON.t => JSON.Encode.array([]),
|
|
2107
1961
|
)
|
|
2108
|
-
queryResolvers->Dict.set("Platform_ApiFragments", apiFragmentsQueryResolver)
|
|
2109
1962
|
// Composite-key / index admin query fields — empty stubs in the platform-only
|
|
2110
1963
|
// path (no plugins connected → no QueryDb seeded).
|
|
2111
1964
|
registerAdminItemsAndIndexResolvers(~queryResolvers, ~live=false)
|
|
@@ -2233,8 +2086,8 @@ module MakeWithConfig = (
|
|
|
2233
2086
|
let admin = Admin.construct(
|
|
2234
2087
|
~version="",
|
|
2235
2088
|
~extensionPoints=[],
|
|
2236
|
-
~aggregates=[module(LocalPluginAggregate)
|
|
2237
|
-
~readModels=[module(PluginsReadModel)
|
|
2089
|
+
~aggregates=[module(LocalPluginAggregate)],
|
|
2090
|
+
~readModels=[module(PluginsReadModel)],
|
|
2238
2091
|
~scheduler,
|
|
2239
2092
|
~resourceNaming=LocalPluginSpec.resourceNaming,
|
|
2240
2093
|
~api=(),
|
|
@@ -2258,8 +2111,12 @@ module MakeWithConfig = (
|
|
|
2258
2111
|
builtInfos.contents->Array.push(info)
|
|
2259
2112
|
})
|
|
2260
2113
|
|
|
2114
|
+
// Construct the plugin inside its own DomainGraphQL_Server scope
|
|
2115
|
+
// (plugin=subgraph — see buildPluginInScope). Registrations targeting the
|
|
2116
|
+
// platform server (apiTarget=Platform in split mode) are unaffected:
|
|
2117
|
+
// scopes only exist on DomainGraphQL_Server.
|
|
2261
2118
|
module P = unpack(plugin)
|
|
2262
|
-
let pluginComponent = P.make
|
|
2119
|
+
let pluginComponent = buildPluginInScope(~makePlugin=P.make, ~builtInfos)
|
|
2263
2120
|
|
|
2264
2121
|
ReventlessCore.Plugin_Helpers.onPluginBuiltHook.contents = existingBuiltHook
|
|
2265
2122
|
|
|
@@ -2301,7 +2158,6 @@ module MakeWithConfig = (
|
|
|
2301
2158
|
->JSON.Encode.array
|
|
2302
2159
|
},
|
|
2303
2160
|
)
|
|
2304
|
-
queryResolvers->Dict.set("Platform_ApiFragments", apiFragmentsQueryResolver)
|
|
2305
2161
|
// Platform_ComponentDefinitions resolver — SDL is already stitched into baseParts via
|
|
2306
2162
|
// AdminApi.baseFragment so we register only the resolver here. Uses the shared
|
|
2307
2163
|
// encoder so the dynamic-plugin admin server emits the same canonical shape as
|