@reventlessdev/reventless-aws 3.0.0-alpha.197 → 3.0.0-alpha.199

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 (28) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.json +7 -7
  3. package/src/Platform.res +294 -44
  4. package/src/Platform.res.mjs +420 -94
  5. package/src/adapter/Api/ApiFragmentDeregistration.res +137 -0
  6. package/src/adapter/Api/ApiFragmentDeregistration.res.mjs +108 -0
  7. package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res +4 -3
  8. package/src/adapter/Api/Platform_ApiFragments_Lambda.res +222 -0
  9. package/src/adapter/Api/Platform_ApiFragments_Lambda.res.mjs +202 -0
  10. package/src/adapter/Api/Platform_UIFragments_Lambda.res +27 -17
  11. package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +13 -13
  12. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +2 -1
  13. package/src/adapter/QueryDb/QueryDbBackend.res +1 -1
  14. package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +235 -9
  15. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +4 -0
  16. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +5 -0
  17. package/src/components/Api/AppSync_Adapter.res +36 -59
  18. package/src/components/Api/AppSync_Adapter.res.mjs +18 -74
  19. package/src/components/Api/AppSync_SdlDecorate.res +189 -0
  20. package/src/components/Api/AppSync_SdlDecorate.res.mjs +125 -0
  21. package/src/plugin/runtime/PluginRuntime_Builder.res +107 -2
  22. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +70 -7
  23. package/src/util/Util_AppSync_Caller.res +12 -4
  24. package/src/util/Util_AppSync_Caller.res.mjs +9 -3
  25. package/tests/AppSync_AdapterTest.res +6 -0
  26. package/tests/AppSync_AdapterTest.res.mjs +12 -6
  27. package/tests/AppSync_SdlDecorateTest.res +157 -0
  28. package/tests/AppSync_SdlDecorateTest.res.mjs +147 -0
@@ -12,7 +12,9 @@ import * as Output$Pulumi from "@reventlessdev/rescript-pulumi-pulumi/src/Output
12
12
  import * as Pulumi$Pulumi from "@reventlessdev/rescript-pulumi-pulumi/src/Pulumi.res.mjs";
13
13
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
14
14
  import * as Pulumi from "@pulumi/pulumi";
15
+ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
15
16
  import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
17
+ import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
16
18
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
17
19
  import * as Plugin$ReventlessAws from "./components/Plugin.res.mjs";
18
20
  import * as LibDynamodb from "@aws-sdk/lib-dynamodb";
@@ -27,7 +29,9 @@ import * as ReadModel$ReventlessCore from "@reventlessdev/reventless-core/src/co
27
29
  import * as PluginSpec$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/lifecycle/PluginSpec.res.mjs";
28
30
  import * as Api_Builder$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/Api_Builder.res.mjs";
29
31
  import * as Plugin_Stack$ReventlessAws from "./plugin/stack/Plugin_Stack.res.mjs";
32
+ import * as UiFragments$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments.res.mjs";
30
33
  import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/util/Util_Pulumi.res.mjs";
34
+ import * as ApiFragments$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments.res.mjs";
31
35
  import * as Util_DynamoDb$ReventlessAws from "./util/Util_DynamoDb.res.mjs";
32
36
  import * as Platform_Casts$ReventlessAws from "./Platform_Casts.res.mjs";
33
37
  import * as Platform_Stack$ReventlessAws from "./Platform_Stack.res.mjs";
@@ -50,7 +54,10 @@ import * as DcbEventLogStorage$ReventlessAws from "./adapter/DcbEventLog/DcbEven
50
54
  import * as ExtensionMapping$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/ExtensionMapping.res.mjs";
51
55
  import * as PluginsProjection$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/lifecycle/PluginsProjection.res.mjs";
52
56
  import * as StateTopic_AppSync$ReventlessAws from "./adapter/StateTopic/StateTopic_AppSync.res.mjs";
57
+ import * as UiFragmentRegistry$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry.res.mjs";
58
+ import * as Util_AppSync_Caller$ReventlessAws from "./util/Util_AppSync_Caller.res.mjs";
53
59
  import * as Util_ResourceNaming$ReventlessAws from "./util/Util_ResourceNaming.res.mjs";
60
+ import * as ApiFragmentRegistry$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry.res.mjs";
54
61
  import * as ClonerRunner_Fargate$ReventlessAws from "./plugin/cloner/ClonerRunner_Fargate.res.mjs";
55
62
  import * as QueryEngine_DynamoDb$ReventlessAws from "./adapter/QueryEngine/QueryEngine_DynamoDb.res.mjs";
56
63
  import * as PluginRuntime_Builder$ReventlessAws from "./plugin/runtime/PluginRuntime_Builder.res.mjs";
@@ -62,9 +69,12 @@ import * as AutomationSlice_Builder$ReventlessAws from "./components/AutomationS
62
69
  import * as EventTopicPublisher_SNS$ReventlessAws from "./adapter/EventTopic/EventTopicPublisher_SNS.res.mjs";
63
70
  import * as ExtensionPointMapping$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/ExtensionPointMapping.res.mjs";
64
71
  import * as PgQueryResolver_Builder$ReventlessAws from "./adapter/QueryDb/PgQueryResolver_Builder.res.mjs";
72
+ import * as UiFragments_Projection$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateViewSlice/UiFragments_Projection.res.mjs";
65
73
  import * as Aggregate_Builder_Single$ReventlessAws from "./components/Aggregate_Builder_Single.res.mjs";
74
+ import * as ApiFragments_Projection$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/StateViewSlice/ApiFragments_Projection.res.mjs";
66
75
  import * as ReadModel_Builder_Single$ReventlessAws from "./components/ReadModel_Builder_Single.res.mjs";
67
76
  import * as StateChangeSlice_Builder$ReventlessAws from "./components/StateChangeSlice_Builder.res.mjs";
77
+ import * as ApiFragmentDeregistration$ReventlessAws from "./adapter/Api/ApiFragmentDeregistration.res.mjs";
68
78
  import * as EventCollectorChannel_SQS$ReventlessAws from "./adapter/EventCollector/EventCollectorChannel_SQS.res.mjs";
69
79
  import * as PgChangeFeedRelay_Builder$ReventlessAws from "./adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs";
70
80
  import * as RuntimeEnvironment_Lambda$ReventlessAws from "./adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs";
@@ -72,23 +82,23 @@ import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/revent
72
82
  import * as Platform_UIFragments_Lambda$ReventlessAws from "./adapter/Api/Platform_UIFragments_Lambda.res.mjs";
73
83
  import * as CommandTopicChannel_SQS_Sync$ReventlessAws from "./adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs";
74
84
  import * as EventLogSubscription_AppSync$ReventlessAws from "./adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs";
85
+ import * as Platform_ApiFragments_Lambda$ReventlessAws from "./adapter/Api/Platform_ApiFragments_Lambda.res.mjs";
86
+ import * as UiFragmentRegistry_Behavior$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UiFragmentRegistry/StateChangeSlice/UiFragmentRegistry_Behavior.res.mjs";
87
+ import * as ApiFragmentRegistry_Behavior$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/StateChangeSlice/ApiFragmentRegistry_Behavior.res.mjs";
75
88
  import * as CommandTopicChannel_SQS_Async$ReventlessAws from "./adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs";
76
89
  import * as Plugin_ExtensionPoint_Builder$ReventlessAws from "./plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs";
77
90
  import * as QueryDbStorage_DynamoDbStream$ReventlessAws from "./adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs";
78
91
  import * as StateViewSlice_Builder_Stream$ReventlessAws from "./components/StateViewSlice_Builder_Stream.res.mjs";
79
- import * as UIFragmentRegistryProjection$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UIFragmentRegistryProjection.res.mjs";
80
92
  import * as Aggregate_Builder_Single_Async$ReventlessAws from "./components/Aggregate_Builder_Single_Async.res.mjs";
81
93
  import * as AggregateRuntime_Builder_Single$ReventlessAws from "./adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs";
82
94
  import * as CommandTopicChannel_SQS_Runtime$ReventlessAws from "./adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
83
95
  import * as InboundTranslationSlice_Builder$ReventlessAws from "./components/InboundTranslationSlice_Builder.res.mjs";
84
96
  import * as ReadModel_Builder_Single_Stream$ReventlessAws from "./components/ReadModel_Builder_Single_Stream.res.mjs";
85
97
  import * as OutboundTranslationSlice_Builder$ReventlessAws from "./components/OutboundTranslationSlice_Builder.res.mjs";
86
- import * as UIFragmentRegistryReadModelSpec$ReventlessCore from "@reventlessdev/reventless-core/src/admin/UIFragmentRegistryReadModelSpec.res.mjs";
87
98
  import * as CommandGeneratorResolvers_AppSync$ReventlessAws from "./adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs";
88
99
  import * as EventTopicPublisher_DynamoDbStream$ReventlessAws from "./adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs";
89
100
  import * as InboundTranslationResolvers_AppSync$ReventlessAws from "./adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs";
90
101
  import * as PluginExtensionPointRuntime_Builder$ReventlessAws from "./plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs";
91
- import * as ReadModel_Builder_NoResolver_Stream$ReventlessAws from "./components/ReadModel_Builder_NoResolver_Stream.res.mjs";
92
102
  import * as EventCollectorRuntime_Builder_Single$ReventlessAws from "./adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs";
93
103
  import * as Platform_ComponentDefinitions_Lambda$ReventlessAws from "./adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs";
94
104
  import * as StateViewSliceRuntime_Builder_Single$ReventlessAws from "./adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs";
@@ -143,7 +153,8 @@ function MakeWithConfig(Config) {
143
153
  subnetIds: pg.subnetIds
144
154
  });
145
155
  QueryDbBackend$ReventlessAws.exempt(PluginsReadModelSpec$ReventlessCore.name);
146
- QueryDbBackend$ReventlessAws.exempt(UIFragmentRegistryReadModelSpec$ReventlessCore.name);
156
+ QueryDbBackend$ReventlessAws.exempt(UiFragments$ReventlessCore.name);
157
+ QueryDbBackend$ReventlessAws.exempt(ApiFragments$ReventlessCore.name);
147
158
  });
148
159
  let currentDeployTarget = {
149
160
  contents: "Domain"
@@ -413,17 +424,79 @@ function MakeWithConfig(Config) {
413
424
  MakeAsync: MakeAsync$1
414
425
  };
415
426
  let include = StateViewSlice_Builder$ReventlessAws.Make(ApiConfig);
427
+ let Make$7 = include.Make;
416
428
  let include$1 = StateViewSlice_Builder_Stream$ReventlessAws.Make(ApiConfig);
417
429
  let include$2 = AutomationSlice_Builder$ReventlessAws.Make(ApiConfig);
418
430
  let include$3 = OutboundTranslationSlice_Builder$ReventlessAws.Make(ApiConfig);
419
431
  let InboundTranslationSlice = InboundTranslationSlice_Builder$ReventlessAws.Make(ApiConfig);
432
+ let Spec = {
433
+ name: UiFragmentRegistry$ReventlessCore.name,
434
+ moduleUrl: UiFragmentRegistry$ReventlessCore.moduleUrl,
435
+ Id: Id$Reventless.$$String,
436
+ consumedEventSchema: UiFragmentRegistry$ReventlessCore.consumedEventSchema,
437
+ errorSchema: UiFragmentRegistry$ReventlessCore.errorSchema,
438
+ eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
439
+ commandSchema: UiFragmentRegistry$ReventlessCore.commandSchema,
440
+ commandAuthorization: UiFragmentRegistry$ReventlessCore.commandAuthorization,
441
+ readConsistency: UiFragmentRegistry$ReventlessCore.readConsistency
442
+ };
443
+ let UiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec)({
444
+ initialState: undefined,
445
+ evolve: UiFragmentRegistry_Behavior$ReventlessCore.evolve,
446
+ decide: UiFragmentRegistry_Behavior$ReventlessCore.decide,
447
+ moduleUrl: UiFragmentRegistry_Behavior$ReventlessCore.moduleUrl
448
+ });
449
+ let UiFragmentsViewSlice = Make$7({
450
+ name: UiFragments$ReventlessCore.name,
451
+ moduleUrl: UiFragments$ReventlessCore.moduleUrl,
452
+ stateSchema: UiFragments$ReventlessCore.stateSchema,
453
+ consumedEventSchema: UiFragments$ReventlessCore.consumedEventSchema,
454
+ config: UiFragments$ReventlessCore.config,
455
+ subIdConfig: undefined,
456
+ authorization: UiFragments$ReventlessCore.authorization,
457
+ visibility: UiFragments$ReventlessCore.visibility
458
+ })({
459
+ project: UiFragments_Projection$ReventlessCore.project,
460
+ moduleUrl: UiFragments_Projection$ReventlessCore.moduleUrl
461
+ });
462
+ let Spec$1 = {
463
+ name: ApiFragmentRegistry$ReventlessCore.name,
464
+ moduleUrl: ApiFragmentRegistry$ReventlessCore.moduleUrl,
465
+ Id: Id$Reventless.$$String,
466
+ consumedEventSchema: ApiFragmentRegistry$ReventlessCore.consumedEventSchema,
467
+ errorSchema: ApiFragmentRegistry$ReventlessCore.errorSchema,
468
+ eventSchema: ApiFragmentRegistry$ReventlessCore.eventSchema,
469
+ commandSchema: ApiFragmentRegistry$ReventlessCore.commandSchema,
470
+ commandAuthorization: ApiFragmentRegistry$ReventlessCore.commandAuthorization,
471
+ readConsistency: ApiFragmentRegistry$ReventlessCore.readConsistency
472
+ };
473
+ let ApiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec$1)({
474
+ initialState: undefined,
475
+ evolve: ApiFragmentRegistry_Behavior$ReventlessCore.evolve,
476
+ decide: ApiFragmentRegistry_Behavior$ReventlessCore.decide,
477
+ moduleUrl: ApiFragmentRegistry_Behavior$ReventlessCore.moduleUrl
478
+ });
479
+ let ApiFragmentsViewSlice = Make$7({
480
+ name: ApiFragments$ReventlessCore.name,
481
+ moduleUrl: ApiFragments$ReventlessCore.moduleUrl,
482
+ stateSchema: ApiFragments$ReventlessCore.stateSchema,
483
+ consumedEventSchema: ApiFragments$ReventlessCore.consumedEventSchema,
484
+ config: ApiFragments$ReventlessCore.config,
485
+ subIdConfig: undefined,
486
+ authorization: ApiFragments$ReventlessCore.authorization,
487
+ visibility: ApiFragments$ReventlessCore.visibility
488
+ })({
489
+ project: ApiFragments_Projection$ReventlessCore.project,
490
+ moduleUrl: ApiFragments_Projection$ReventlessCore.moduleUrl
491
+ });
420
492
  let emptyBaseFragment = GraphQL_Stitcher$ReventlessCore.encode({
421
493
  types: [],
422
494
  mutations: [],
423
495
  queries: [],
424
- subscriptions: []
496
+ subscriptions: [],
497
+ subscriptionSources: []
425
498
  });
426
- let Make$7 = FragmentConfig => {
499
+ let Make$8 = FragmentConfig => {
427
500
  let Builder = Api_Builder$ReventlessCore.Make({
428
501
  makeApiResource: AppSync_Adapter$ReventlessAws.makeApiResource,
429
502
  generateFragment: AppSync_Adapter$ReventlessAws.generateFragment,
@@ -436,7 +509,7 @@ function MakeWithConfig(Config) {
436
509
  };
437
510
  };
438
511
  let Api = {
439
- Make: Make$7
512
+ Make: Make$8
440
513
  };
441
514
  let deploySchemaHashPrefix = "deploy-schema-hash:";
442
515
  let readSchemaHash = async (tableName, apiId) => {
@@ -476,6 +549,9 @@ function MakeWithConfig(Config) {
476
549
  let hooksApiRoleRef = {
477
550
  contents: undefined
478
551
  };
552
+ let hooksAdminApiRef = {
553
+ contents: undefined
554
+ };
479
555
  let resolveHookedApi = () => {
480
556
  let match = hooksApiRef.contents;
481
557
  if (match !== undefined) {
@@ -484,6 +560,42 @@ function MakeWithConfig(Config) {
484
560
  return resolveTargetApi();
485
561
  }
486
562
  };
563
+ let resolveAdminHookedApi = () => {
564
+ let match = hooksAdminApiRef.contents;
565
+ if (match !== undefined) {
566
+ return match.val;
567
+ } else {
568
+ return resolveHookedApi();
569
+ }
570
+ };
571
+ let deployWaiterDelay = ms => new Promise((resolve, param) => {
572
+ setTimeout(() => resolve(), ms);
573
+ });
574
+ let waitForApiFragmentPush = async (endpoint, region, pluginId, sinceAt) => {
575
+ let loop = async attempt => {
576
+ if (attempt >= 90) {
577
+ return Stdlib_JsError.throwWithMessage(`Timed out (>3min) waiting for the platform to push ` + pluginId + `'s API fragment — check the AdminEventCollector Lambda logs.`);
578
+ }
579
+ let data = await Util_AppSync_Caller$ReventlessAws.sendQuery(endpoint, region, "query { Platform_ApiFragments { pluginId pushStatus pushMessage pushedAt } }");
580
+ let row = Stdlib_Option.flatMap(Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(data, Stdlib_JSON.Decode.object), d => d["Platform_ApiFragments"]), Stdlib_JSON.Decode.array), []).find(entry => Primitive_object.equal(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(entry), e => e["pluginId"]), Stdlib_JSON.Decode.string), pluginId)), Stdlib_JSON.Decode.object);
581
+ if (row !== undefined) {
582
+ let field = k => Stdlib_Option.getOr(Stdlib_Option.flatMap(row[k], Stdlib_JSON.Decode.string), "");
583
+ let status = field("pushStatus");
584
+ let fresh = field("pushedAt") >= sinceAt;
585
+ if (fresh && status === "ok") {
586
+ return log.info("registerFragmentViaApi", undefined, pluginId + ` schema push confirmed ACTIVE`);
587
+ } else if (fresh && status === "error") {
588
+ return Stdlib_JsError.throwWithMessage(`Schema push failed for ` + pluginId + `: ` + field("pushMessage"));
589
+ } else {
590
+ await deployWaiterDelay(2000);
591
+ return await loop(attempt + 1 | 0);
592
+ }
593
+ }
594
+ await deployWaiterDelay(2000);
595
+ return await loop(attempt + 1 | 0);
596
+ };
597
+ return await loop(0);
598
+ };
487
599
  let hooks_subscriptionInfraHook = Stdlib_Option.map(domainEventsApiOpt, eventsApi => (params => {
488
600
  let allEventTopics = params.allEventTopics;
489
601
  let allQueryDbs = params.allQueryDbs;
@@ -505,22 +617,68 @@ function MakeWithConfig(Config) {
505
617
  let hooks_preResolversSchemaHook = (name, version, pluginFragment) => {
506
618
  log.info("preResolversSchemaHook", undefined, `Pushing schema for plugin ` + name + `@` + version + ` to AppSync`);
507
619
  let capturedDeployTarget = currentDeployTarget.contents;
508
- let match;
620
+ if (platformStackRef !== undefined) {
621
+ let apiTargetName;
622
+ apiTargetName = capturedDeployTarget === "Domain" ? "Domain" : "Platform";
623
+ let match = apiConfigRef.contents;
624
+ let platformApi = match !== undefined ? match.platformApi : domainApi;
625
+ let region = Stdlib_Option.getOr(new Pulumi.Config("aws").get("region"), "unknown");
626
+ let endpointOutput = Output$Pulumi.flatMap(platformApi, api => api.uris).apply(uris => uris.GRAPHQL);
627
+ ApiFragmentDeregistration$ReventlessAws.make(name + `ApiFragmentRegistration`, name, endpointOutput, region, undefined);
628
+ return Output$Pulumi.flatMap(endpointOutput, endpoint => {
629
+ let run = async () => {
630
+ let at = new Date().toISOString();
631
+ let variables = {
632
+ id: name,
633
+ pluginId: name,
634
+ fragment: {
635
+ encoded: pluginFragment.encoded,
636
+ protocol: pluginFragment.protocol
637
+ },
638
+ apiTarget: Util_AppSync_Caller$ReventlessAws.graphqlEnum(apiTargetName),
639
+ at: at
640
+ };
641
+ log.info("registerFragmentViaApi", undefined, `Registering API fragment for ` + name + ` (` + apiTargetName + `) via ` + endpoint);
642
+ let result = await Util_AppSync_Caller$ReventlessAws.sendMutation(endpoint, region, "Platform_RegisterApiFragment", "{ __typename ... on CommandAccepted { eventCount } ... on CommandRejected { errorCode errorDetail } }", variables);
643
+ let outcome = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(result, Stdlib_JSON.Decode.object), d => d["Platform_RegisterApiFragment"]), Stdlib_JSON.Decode.object);
644
+ if (outcome === undefined) {
645
+ return await waitForApiFragmentPush(endpoint, region, name, at);
646
+ }
647
+ let typename = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["__typename"], Stdlib_JSON.Decode.string), "");
648
+ switch (typename) {
649
+ case "CommandAccepted" :
650
+ let eventCount = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["eventCount"], Stdlib_JSON.Decode.float), 0.0);
651
+ if (eventCount > 0.0) {
652
+ return await waitForApiFragmentPush(endpoint, region, name, at);
653
+ } else {
654
+ return log.info("registerFragmentViaApi", undefined, name + ` fragment unchanged — no push needed`);
655
+ }
656
+ case "CommandRejected" :
657
+ let code = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["errorCode"], Stdlib_JSON.Decode.string), "unknown");
658
+ return Stdlib_JsError.throwWithMessage(`RegisterApiFragment rejected for ` + name + `: ` + code);
659
+ default:
660
+ return await waitForApiFragmentPush(endpoint, region, name, at);
661
+ }
662
+ };
663
+ return run();
664
+ });
665
+ }
666
+ let match$1;
509
667
  if (capturedDeployTarget === "Domain") {
510
- match = [
668
+ match$1 = [
511
669
  "deploy-schema:",
512
670
  domainApi
513
671
  ];
514
672
  } else {
515
- let match$1 = apiConfigRef.contents;
516
- let api = match$1 !== undefined ? match$1.platformApi : domainApi;
517
- match = [
673
+ let match$2 = apiConfigRef.contents;
674
+ let api = match$2 !== undefined ? match$2.platformApi : domainApi;
675
+ match$1 = [
518
676
  "deploy-schema-platform:",
519
677
  api
520
678
  ];
521
679
  }
522
- let targetApi = match[1];
523
- let schemaPrefix = match[0];
680
+ let targetApi = match$1[1];
681
+ let schemaPrefix = match$1[0];
524
682
  let readStackRefString = (stackRef, key) => {
525
683
  let direct = stackRef.getOutput(key);
526
684
  let defaultOutput = stackRef.getOutput("default");
@@ -638,8 +796,10 @@ function MakeWithConfig(Config) {
638
796
  return Output$Pulumi.flatMap(targetApi, api => Output$Pulumi.flatMap(api.id, apiId => {
639
797
  let runSchemaPush = () => writeAndScanFragments().then(async allPluginFragments => {
640
798
  let baseFragment;
641
- baseFragment = capturedDeployTarget === "Domain" && Config.splitApi ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", undefined);
642
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(baseFragment, allPluginFragments));
799
+ baseFragment = capturedDeployTarget === "Domain" ? (
800
+ Config.splitApi ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", undefined)
801
+ ) : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", AdminApi$ReventlessCore.systemCallerFieldNames);
802
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(baseFragment, allPluginFragments);
643
803
  let currentHash = AppSync_Adapter$ReventlessAws.sha256Hex(sdl);
644
804
  let storedHash = tableNameOpt !== undefined ? await readSchemaHash(tableNameOpt, apiId) : undefined;
645
805
  let client = AppSync_Adapter$ReventlessAws.getClient();
@@ -685,8 +845,8 @@ function MakeWithConfig(Config) {
685
845
  Config.splitApi ? undefined : domainApi
686
846
  );
687
847
  if (targetApiOpt !== undefined) {
688
- let adminBaseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", undefined);
689
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(adminBaseFragment, []));
848
+ let adminBaseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", AdminApi$ReventlessCore.systemCallerFieldNames);
849
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(adminBaseFragment, []);
690
850
  return Output$Pulumi.flatMap(Pulumi.all([
691
851
  targetApiOpt,
692
852
  adminBarrier
@@ -707,7 +867,7 @@ function MakeWithConfig(Config) {
707
867
  return adminBarrier;
708
868
  };
709
869
  let hooks_inboundAppSyncResolverHook = param => InboundTranslationResolvers_AppSync$ReventlessAws.make(resolveHookedApi(), param.runtime, param.fieldNames, param.opts);
710
- let hooks_dcbAppSyncResolverHook = param => CommandGeneratorResolvers_AppSync$ReventlessAws.makeDcb(resolveHookedApi(), param.runtime, param.fieldNames, param.tags, param.opts);
870
+ let hooks_dcbAppSyncResolverHook = param => CommandGeneratorResolvers_AppSync$ReventlessAws.makeDcb(param.onAdminApi ? resolveAdminHookedApi() : resolveHookedApi(), param.runtime, param.fieldNames, param.tags, param.opts);
711
871
  let hooks_onDcbEventLogCreated = dcbEventLogUnknown => {
712
872
  if (DcbBackend$ReventlessAws.isPostgres()) {
713
873
  return;
@@ -760,6 +920,7 @@ function MakeWithConfig(Config) {
760
920
  schedulerRoleUrn: hooks_schedulerRoleUrn,
761
921
  api: hooksApiRef,
762
922
  apiRole: hooksApiRoleRef,
923
+ adminApi: hooksAdminApiRef,
763
924
  deployTarget: hooks_deployTarget
764
925
  };
765
926
  let PluginBuilderImpl = Plugin$ReventlessAws.Make({
@@ -823,20 +984,6 @@ function MakeWithConfig(Config) {
823
984
  authorization: PluginsReadModelSpec$ReventlessCore.authorization,
824
985
  visibility: PluginsReadModelSpec$ReventlessCore.visibility
825
986
  })(PluginReadModelMappings);
826
- let UIFragmentRegistryReadModelMappings = {
827
- moduleUrl: UIFragmentRegistryProjection$ReventlessCore.moduleUrl,
828
- mappings: UIFragmentRegistryProjection$ReventlessCore.mappings
829
- };
830
- let UIFragmentRegistryReadModel = ReadModel_Builder_NoResolver_Stream$ReventlessAws.Make({
831
- Id: Id$Reventless.$$String,
832
- name: UIFragmentRegistryReadModelSpec$ReventlessCore.name,
833
- moduleUrl: UIFragmentRegistryReadModelSpec$ReventlessCore.moduleUrl,
834
- stateSchema: UIFragmentRegistryReadModelSpec$ReventlessCore.stateSchema,
835
- config: UIFragmentRegistryReadModelSpec$ReventlessCore.config,
836
- subIdConfig: undefined,
837
- authorization: UIFragmentRegistryReadModelSpec$ReventlessCore.authorization,
838
- visibility: UIFragmentRegistryReadModelSpec$ReventlessCore.visibility
839
- })(UIFragmentRegistryReadModelMappings);
840
987
  let makeScheduler = () => {
841
988
  let component = Scheduler$ReventlessAws.make(undefined);
842
989
  let outputs = Component$ReventlessCore.outputs(component);
@@ -952,6 +1099,7 @@ function MakeWithConfig(Config) {
952
1099
  ];
953
1100
  let platformApiRole = match[1];
954
1101
  let platformApi = match[0];
1102
+ hooksAdminApiRef.contents = Platform_Casts$ReventlessAws.wrapHookedValue(platformApi);
955
1103
  if (Config.splitApi) {
956
1104
  splitApiOutputsRef.contents = {
957
1105
  platformApi: platformApi,
@@ -967,10 +1115,13 @@ function MakeWithConfig(Config) {
967
1115
  };
968
1116
  }
969
1117
  }
970
- let admin = Admin.construct(version, [], [PluginAggregate], [
971
- PluginReadModel,
972
- UIFragmentRegistryReadModel
973
- ], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [], [], [], [], []);
1118
+ let admin = Admin.construct(version, [], [PluginAggregate], [PluginReadModel], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [
1119
+ UiFragmentRegistrySlice,
1120
+ ApiFragmentRegistrySlice
1121
+ ], [
1122
+ UiFragmentsViewSlice,
1123
+ ApiFragmentsViewSlice
1124
+ ], [], [], []);
974
1125
  let pluginRm = admin.readModelsOutputs["Plugins"];
975
1126
  if (pluginRm !== undefined) {
976
1127
  let r = pluginRm.queryDb.resources[0];
@@ -979,11 +1130,18 @@ function MakeWithConfig(Config) {
979
1130
  AggregateRuntime_Builder_Single$ReventlessAws.setPluginReadModelTable(r.name);
980
1131
  }
981
1132
  }
982
- let rm = admin.readModelsOutputs["UIFragmentRegistry"];
1133
+ let rm = admin.stateViewSlicesOutputs["UiFragments"];
983
1134
  if (rm !== undefined) {
984
1135
  let r$1 = rm.queryDb.resources[0];
985
1136
  if (r$1 !== undefined) {
986
- Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, {});
1137
+ Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, admin.adminSchemaPushed, {});
1138
+ }
1139
+ }
1140
+ let rm$1 = admin.stateViewSlicesOutputs["ApiFragments"];
1141
+ if (rm$1 !== undefined) {
1142
+ let r$2 = rm$1.queryDb.resources[0];
1143
+ if (r$2 !== undefined) {
1144
+ Platform_ApiFragments_Lambda$ReventlessAws.make(platformApi, r$2.name, admin.adminSchemaPushed, {});
987
1145
  }
988
1146
  }
989
1147
  let pluginComponents = plugins.map(plugin => plugin.make());
@@ -1021,6 +1179,7 @@ function MakeWithConfig(Config) {
1021
1179
  ];
1022
1180
  let platformApiRole = match[1];
1023
1181
  let platformApi = match[0];
1182
+ hooksAdminApiRef.contents = Platform_Casts$ReventlessAws.wrapHookedValue(platformApi);
1024
1183
  if (Config.splitApi) {
1025
1184
  splitApiOutputsRef.contents = {
1026
1185
  platformApi: platformApi,
@@ -1060,8 +1219,8 @@ function MakeWithConfig(Config) {
1060
1219
  return;
1061
1220
  }
1062
1221
  });
1063
- let baseFragment = Config.splitApi ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", undefined);
1064
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(baseFragment, fragments));
1222
+ let baseFragment = Config.splitApi ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(Config.cloner), "Admin", AdminApi$ReventlessCore.systemCallerFieldNames);
1223
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(baseFragment, fragments);
1065
1224
  return await AppSync_Adapter$ReventlessAws.startSchemaCreationRetrying(AppSync_Adapter$ReventlessAws.getClient(), {
1066
1225
  apiId: apiId,
1067
1226
  definition: sdl
@@ -1071,10 +1230,13 @@ function MakeWithConfig(Config) {
1071
1230
  updateApiSchema: updateApiSchema,
1072
1231
  manageSubscriptions: undefined
1073
1232
  });
1074
- let admin = Admin.construct(version, [PluginExtensionPoint], [PluginAggregate], [
1075
- PluginReadModel,
1076
- UIFragmentRegistryReadModel
1077
- ], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [], [], [], [], []);
1233
+ let admin = Admin.construct(version, [PluginExtensionPoint], [PluginAggregate], [PluginReadModel], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [
1234
+ UiFragmentRegistrySlice,
1235
+ ApiFragmentRegistrySlice
1236
+ ], [
1237
+ UiFragmentsViewSlice,
1238
+ ApiFragmentsViewSlice
1239
+ ], [], [], []);
1078
1240
  let pluginRm = admin.readModelsOutputs["Plugins"];
1079
1241
  let pluginReadModelTableName;
1080
1242
  if (pluginRm !== undefined) {
@@ -1103,16 +1265,23 @@ function MakeWithConfig(Config) {
1103
1265
  return Pulumi.output("NOT_AVAILABLE");
1104
1266
  }
1105
1267
  });
1106
- PluginRuntime_Builder$ReventlessAws.registerConfig(pluginEpEventTopicArn, pluginReadModelTableName, pluginSchemaPersistenceTable.name, hooks_schedulerRoleUrn.contents, undefined, undefined, domainApiId, Config.cloner, undefined);
1268
+ PluginRuntime_Builder$ReventlessAws.registerConfig(pluginEpEventTopicArn, pluginReadModelTableName, pluginSchemaPersistenceTable.name, hooks_schedulerRoleUrn.contents, undefined, undefined, domainApiId, Config.cloner, Output$Pulumi.flatMap(platformApi, api => api.id), Stdlib_Option.map(Stdlib_Option.flatMap(admin.stateViewSlicesOutputs["ApiFragments"], rm => rm.queryDb.resources[0]), r => r.name), AutomationSliceRuntime_Builder_Single$ReventlessAws.getDcbQueueUrl(), Config.splitApi, undefined);
1107
1269
  if (pluginReadModelTableName !== undefined) {
1108
1270
  AggregateRuntime_Builder_Single$ReventlessAws.setPluginReadModelTable(pluginReadModelTableName);
1109
1271
  Platform_ComponentDefinitions_Lambda$ReventlessAws.make(platformApi, pluginReadModelTableName, {});
1110
1272
  }
1111
- let rm = admin.readModelsOutputs["UIFragmentRegistry"];
1273
+ let rm = admin.stateViewSlicesOutputs["UiFragments"];
1112
1274
  if (rm !== undefined) {
1113
1275
  let r$1 = rm.queryDb.resources[0];
1114
1276
  if (r$1 !== undefined) {
1115
- Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, {});
1277
+ Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, admin.adminSchemaPushed, {});
1278
+ }
1279
+ }
1280
+ let rm$1 = admin.stateViewSlicesOutputs["ApiFragments"];
1281
+ if (rm$1 !== undefined) {
1282
+ let r$2 = rm$1.queryDb.resources[0];
1283
+ if (r$2 !== undefined) {
1284
+ Platform_ApiFragments_Lambda$ReventlessAws.make(platformApi, r$2.name, admin.adminSchemaPushed, {});
1116
1285
  }
1117
1286
  }
1118
1287
  if (Config.splitApi) {
@@ -1321,7 +1490,7 @@ function MakeWithConfig(Config) {
1321
1490
  Counter: Counter,
1322
1491
  StateChangeSlice: StateChangeSlice,
1323
1492
  StateViewSlice: {
1324
- Make: include.Make
1493
+ Make: Make$7
1325
1494
  },
1326
1495
  StateViewSliceStream: {
1327
1496
  Make: include$1.Make
@@ -1370,7 +1539,8 @@ function Make($star) {
1370
1539
  subnetIds: pg.subnetIds
1371
1540
  });
1372
1541
  QueryDbBackend$ReventlessAws.exempt(PluginsReadModelSpec$ReventlessCore.name);
1373
- QueryDbBackend$ReventlessAws.exempt(UIFragmentRegistryReadModelSpec$ReventlessCore.name);
1542
+ QueryDbBackend$ReventlessAws.exempt(UiFragments$ReventlessCore.name);
1543
+ QueryDbBackend$ReventlessAws.exempt(ApiFragments$ReventlessCore.name);
1374
1544
  });
1375
1545
  let currentDeployTarget = {
1376
1546
  contents: "Domain"
@@ -1640,17 +1810,79 @@ function Make($star) {
1640
1810
  MakeAsync: MakeAsync$1
1641
1811
  };
1642
1812
  let include = StateViewSlice_Builder$ReventlessAws.Make(ApiConfig);
1813
+ let Make$8 = include.Make;
1643
1814
  let include$1 = StateViewSlice_Builder_Stream$ReventlessAws.Make(ApiConfig);
1644
1815
  let include$2 = AutomationSlice_Builder$ReventlessAws.Make(ApiConfig);
1645
1816
  let include$3 = OutboundTranslationSlice_Builder$ReventlessAws.Make(ApiConfig);
1646
1817
  let InboundTranslationSlice = InboundTranslationSlice_Builder$ReventlessAws.Make(ApiConfig);
1818
+ let Spec = {
1819
+ name: UiFragmentRegistry$ReventlessCore.name,
1820
+ moduleUrl: UiFragmentRegistry$ReventlessCore.moduleUrl,
1821
+ Id: Id$Reventless.$$String,
1822
+ consumedEventSchema: UiFragmentRegistry$ReventlessCore.consumedEventSchema,
1823
+ errorSchema: UiFragmentRegistry$ReventlessCore.errorSchema,
1824
+ eventSchema: UiFragmentRegistry$ReventlessCore.eventSchema,
1825
+ commandSchema: UiFragmentRegistry$ReventlessCore.commandSchema,
1826
+ commandAuthorization: UiFragmentRegistry$ReventlessCore.commandAuthorization,
1827
+ readConsistency: UiFragmentRegistry$ReventlessCore.readConsistency
1828
+ };
1829
+ let UiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec)({
1830
+ initialState: undefined,
1831
+ evolve: UiFragmentRegistry_Behavior$ReventlessCore.evolve,
1832
+ decide: UiFragmentRegistry_Behavior$ReventlessCore.decide,
1833
+ moduleUrl: UiFragmentRegistry_Behavior$ReventlessCore.moduleUrl
1834
+ });
1835
+ let UiFragmentsViewSlice = Make$8({
1836
+ name: UiFragments$ReventlessCore.name,
1837
+ moduleUrl: UiFragments$ReventlessCore.moduleUrl,
1838
+ stateSchema: UiFragments$ReventlessCore.stateSchema,
1839
+ consumedEventSchema: UiFragments$ReventlessCore.consumedEventSchema,
1840
+ config: UiFragments$ReventlessCore.config,
1841
+ subIdConfig: undefined,
1842
+ authorization: UiFragments$ReventlessCore.authorization,
1843
+ visibility: UiFragments$ReventlessCore.visibility
1844
+ })({
1845
+ project: UiFragments_Projection$ReventlessCore.project,
1846
+ moduleUrl: UiFragments_Projection$ReventlessCore.moduleUrl
1847
+ });
1848
+ let Spec$1 = {
1849
+ name: ApiFragmentRegistry$ReventlessCore.name,
1850
+ moduleUrl: ApiFragmentRegistry$ReventlessCore.moduleUrl,
1851
+ Id: Id$Reventless.$$String,
1852
+ consumedEventSchema: ApiFragmentRegistry$ReventlessCore.consumedEventSchema,
1853
+ errorSchema: ApiFragmentRegistry$ReventlessCore.errorSchema,
1854
+ eventSchema: ApiFragmentRegistry$ReventlessCore.eventSchema,
1855
+ commandSchema: ApiFragmentRegistry$ReventlessCore.commandSchema,
1856
+ commandAuthorization: ApiFragmentRegistry$ReventlessCore.commandAuthorization,
1857
+ readConsistency: ApiFragmentRegistry$ReventlessCore.readConsistency
1858
+ };
1859
+ let ApiFragmentRegistrySlice = StateChangeSlice_Builder$ReventlessAws.Make(Spec$1)({
1860
+ initialState: undefined,
1861
+ evolve: ApiFragmentRegistry_Behavior$ReventlessCore.evolve,
1862
+ decide: ApiFragmentRegistry_Behavior$ReventlessCore.decide,
1863
+ moduleUrl: ApiFragmentRegistry_Behavior$ReventlessCore.moduleUrl
1864
+ });
1865
+ let ApiFragmentsViewSlice = Make$8({
1866
+ name: ApiFragments$ReventlessCore.name,
1867
+ moduleUrl: ApiFragments$ReventlessCore.moduleUrl,
1868
+ stateSchema: ApiFragments$ReventlessCore.stateSchema,
1869
+ consumedEventSchema: ApiFragments$ReventlessCore.consumedEventSchema,
1870
+ config: ApiFragments$ReventlessCore.config,
1871
+ subIdConfig: undefined,
1872
+ authorization: ApiFragments$ReventlessCore.authorization,
1873
+ visibility: ApiFragments$ReventlessCore.visibility
1874
+ })({
1875
+ project: ApiFragments_Projection$ReventlessCore.project,
1876
+ moduleUrl: ApiFragments_Projection$ReventlessCore.moduleUrl
1877
+ });
1647
1878
  let emptyBaseFragment = GraphQL_Stitcher$ReventlessCore.encode({
1648
1879
  types: [],
1649
1880
  mutations: [],
1650
1881
  queries: [],
1651
- subscriptions: []
1882
+ subscriptions: [],
1883
+ subscriptionSources: []
1652
1884
  });
1653
- let Make$8 = FragmentConfig => {
1885
+ let Make$9 = FragmentConfig => {
1654
1886
  let Builder = Api_Builder$ReventlessCore.Make({
1655
1887
  makeApiResource: AppSync_Adapter$ReventlessAws.makeApiResource,
1656
1888
  generateFragment: AppSync_Adapter$ReventlessAws.generateFragment,
@@ -1662,7 +1894,7 @@ function Make($star) {
1662
1894
  };
1663
1895
  };
1664
1896
  let Api = {
1665
- Make: Make$8
1897
+ Make: Make$9
1666
1898
  };
1667
1899
  let deploySchemaHashPrefix = "deploy-schema-hash:";
1668
1900
  let readSchemaHash = async (tableName, apiId) => {
@@ -1702,6 +1934,9 @@ function Make($star) {
1702
1934
  let hooksApiRoleRef = {
1703
1935
  contents: undefined
1704
1936
  };
1937
+ let hooksAdminApiRef = {
1938
+ contents: undefined
1939
+ };
1705
1940
  let resolveHookedApi = () => {
1706
1941
  let match = hooksApiRef.contents;
1707
1942
  if (match !== undefined) {
@@ -1710,6 +1945,42 @@ function Make($star) {
1710
1945
  return resolveTargetApi();
1711
1946
  }
1712
1947
  };
1948
+ let resolveAdminHookedApi = () => {
1949
+ let match = hooksAdminApiRef.contents;
1950
+ if (match !== undefined) {
1951
+ return match.val;
1952
+ } else {
1953
+ return resolveHookedApi();
1954
+ }
1955
+ };
1956
+ let deployWaiterDelay = ms => new Promise((resolve, param) => {
1957
+ setTimeout(() => resolve(), ms);
1958
+ });
1959
+ let waitForApiFragmentPush = async (endpoint, region, pluginId, sinceAt) => {
1960
+ let loop = async attempt => {
1961
+ if (attempt >= 90) {
1962
+ return Stdlib_JsError.throwWithMessage(`Timed out (>3min) waiting for the platform to push ` + pluginId + `'s API fragment — check the AdminEventCollector Lambda logs.`);
1963
+ }
1964
+ let data = await Util_AppSync_Caller$ReventlessAws.sendQuery(endpoint, region, "query { Platform_ApiFragments { pluginId pushStatus pushMessage pushedAt } }");
1965
+ let row = Stdlib_Option.flatMap(Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(data, Stdlib_JSON.Decode.object), d => d["Platform_ApiFragments"]), Stdlib_JSON.Decode.array), []).find(entry => Primitive_object.equal(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(entry), e => e["pluginId"]), Stdlib_JSON.Decode.string), pluginId)), Stdlib_JSON.Decode.object);
1966
+ if (row !== undefined) {
1967
+ let field = k => Stdlib_Option.getOr(Stdlib_Option.flatMap(row[k], Stdlib_JSON.Decode.string), "");
1968
+ let status = field("pushStatus");
1969
+ let fresh = field("pushedAt") >= sinceAt;
1970
+ if (fresh && status === "ok") {
1971
+ return log.info("registerFragmentViaApi", undefined, pluginId + ` schema push confirmed ACTIVE`);
1972
+ } else if (fresh && status === "error") {
1973
+ return Stdlib_JsError.throwWithMessage(`Schema push failed for ` + pluginId + `: ` + field("pushMessage"));
1974
+ } else {
1975
+ await deployWaiterDelay(2000);
1976
+ return await loop(attempt + 1 | 0);
1977
+ }
1978
+ }
1979
+ await deployWaiterDelay(2000);
1980
+ return await loop(attempt + 1 | 0);
1981
+ };
1982
+ return await loop(0);
1983
+ };
1713
1984
  let hooks_subscriptionInfraHook = Stdlib_Option.map(domainEventsApiOpt, eventsApi => (params => {
1714
1985
  let allEventTopics = params.allEventTopics;
1715
1986
  let allQueryDbs = params.allQueryDbs;
@@ -1731,22 +2002,68 @@ function Make($star) {
1731
2002
  let hooks_preResolversSchemaHook = (name, version, pluginFragment) => {
1732
2003
  log.info("preResolversSchemaHook", undefined, `Pushing schema for plugin ` + name + `@` + version + ` to AppSync`);
1733
2004
  let capturedDeployTarget = currentDeployTarget.contents;
1734
- let match;
2005
+ if (platformStackRef !== undefined) {
2006
+ let apiTargetName;
2007
+ apiTargetName = capturedDeployTarget === "Domain" ? "Domain" : "Platform";
2008
+ let match = apiConfigRef.contents;
2009
+ let platformApi = match !== undefined ? match.platformApi : domainApi;
2010
+ let region = Stdlib_Option.getOr(new Pulumi.Config("aws").get("region"), "unknown");
2011
+ let endpointOutput = Output$Pulumi.flatMap(platformApi, api => api.uris).apply(uris => uris.GRAPHQL);
2012
+ ApiFragmentDeregistration$ReventlessAws.make(name + `ApiFragmentRegistration`, name, endpointOutput, region, undefined);
2013
+ return Output$Pulumi.flatMap(endpointOutput, endpoint => {
2014
+ let run = async () => {
2015
+ let at = new Date().toISOString();
2016
+ let variables = {
2017
+ id: name,
2018
+ pluginId: name,
2019
+ fragment: {
2020
+ encoded: pluginFragment.encoded,
2021
+ protocol: pluginFragment.protocol
2022
+ },
2023
+ apiTarget: Util_AppSync_Caller$ReventlessAws.graphqlEnum(apiTargetName),
2024
+ at: at
2025
+ };
2026
+ log.info("registerFragmentViaApi", undefined, `Registering API fragment for ` + name + ` (` + apiTargetName + `) via ` + endpoint);
2027
+ let result = await Util_AppSync_Caller$ReventlessAws.sendMutation(endpoint, region, "Platform_RegisterApiFragment", "{ __typename ... on CommandAccepted { eventCount } ... on CommandRejected { errorCode errorDetail } }", variables);
2028
+ let outcome = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_Option.flatMap(result, Stdlib_JSON.Decode.object), d => d["Platform_RegisterApiFragment"]), Stdlib_JSON.Decode.object);
2029
+ if (outcome === undefined) {
2030
+ return await waitForApiFragmentPush(endpoint, region, name, at);
2031
+ }
2032
+ let typename = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["__typename"], Stdlib_JSON.Decode.string), "");
2033
+ switch (typename) {
2034
+ case "CommandAccepted" :
2035
+ let eventCount = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["eventCount"], Stdlib_JSON.Decode.float), 0.0);
2036
+ if (eventCount > 0.0) {
2037
+ return await waitForApiFragmentPush(endpoint, region, name, at);
2038
+ } else {
2039
+ return log.info("registerFragmentViaApi", undefined, name + ` fragment unchanged — no push needed`);
2040
+ }
2041
+ case "CommandRejected" :
2042
+ let code = Stdlib_Option.getOr(Stdlib_Option.flatMap(outcome["errorCode"], Stdlib_JSON.Decode.string), "unknown");
2043
+ return Stdlib_JsError.throwWithMessage(`RegisterApiFragment rejected for ` + name + `: ` + code);
2044
+ default:
2045
+ return await waitForApiFragmentPush(endpoint, region, name, at);
2046
+ }
2047
+ };
2048
+ return run();
2049
+ });
2050
+ }
2051
+ let match$1;
1735
2052
  if (capturedDeployTarget === "Domain") {
1736
- match = [
2053
+ match$1 = [
1737
2054
  "deploy-schema:",
1738
2055
  domainApi
1739
2056
  ];
1740
2057
  } else {
1741
- let match$1 = apiConfigRef.contents;
1742
- let api = match$1 !== undefined ? match$1.platformApi : domainApi;
1743
- match = [
2058
+ let match$2 = apiConfigRef.contents;
2059
+ let api = match$2 !== undefined ? match$2.platformApi : domainApi;
2060
+ match$1 = [
1744
2061
  "deploy-schema-platform:",
1745
2062
  api
1746
2063
  ];
1747
2064
  }
1748
- let targetApi = match[1];
1749
- let schemaPrefix = match[0];
2065
+ let targetApi = match$1[1];
2066
+ let schemaPrefix = match$1[0];
1750
2067
  let readStackRefString = (stackRef, key) => {
1751
2068
  let direct = stackRef.getOutput(key);
1752
2069
  let defaultOutput = stackRef.getOutput("default");
@@ -1864,8 +2181,8 @@ function Make($star) {
1864
2181
  return Output$Pulumi.flatMap(targetApi, api => Output$Pulumi.flatMap(api.id, apiId => {
1865
2182
  let runSchemaPush = () => writeAndScanFragments().then(async allPluginFragments => {
1866
2183
  let baseFragment;
1867
- baseFragment = capturedDeployTarget === "Domain" ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(false), "Admin", undefined);
1868
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(baseFragment, allPluginFragments));
2184
+ baseFragment = capturedDeployTarget === "Domain" ? emptyBaseFragment : AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(false), "Admin", AdminApi$ReventlessCore.systemCallerFieldNames);
2185
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(baseFragment, allPluginFragments);
1869
2186
  let currentHash = AppSync_Adapter$ReventlessAws.sha256Hex(sdl);
1870
2187
  let storedHash = tableNameOpt !== undefined ? await readSchemaHash(tableNameOpt, apiId) : undefined;
1871
2188
  let client = AppSync_Adapter$ReventlessAws.getClient();
@@ -1909,8 +2226,8 @@ function Make($star) {
1909
2226
  let match = splitApiOutputsRef.contents;
1910
2227
  let targetApiOpt = match !== undefined ? match.platformApi : undefined;
1911
2228
  if (targetApiOpt !== undefined) {
1912
- let adminBaseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(false), "Admin", undefined);
1913
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(adminBaseFragment, []));
2229
+ let adminBaseFragment = AppSync_Adapter$ReventlessAws.injectAwsAuthAll(AdminApi$ReventlessCore.baseFragment(false), "Admin", AdminApi$ReventlessCore.systemCallerFieldNames);
2230
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(adminBaseFragment, []);
1914
2231
  return Output$Pulumi.flatMap(Pulumi.all([
1915
2232
  targetApiOpt,
1916
2233
  adminBarrier
@@ -1931,7 +2248,7 @@ function Make($star) {
1931
2248
  return adminBarrier;
1932
2249
  };
1933
2250
  let hooks_inboundAppSyncResolverHook = param => InboundTranslationResolvers_AppSync$ReventlessAws.make(resolveHookedApi(), param.runtime, param.fieldNames, param.opts);
1934
- let hooks_dcbAppSyncResolverHook = param => CommandGeneratorResolvers_AppSync$ReventlessAws.makeDcb(resolveHookedApi(), param.runtime, param.fieldNames, param.tags, param.opts);
2251
+ let hooks_dcbAppSyncResolverHook = param => CommandGeneratorResolvers_AppSync$ReventlessAws.makeDcb(param.onAdminApi ? resolveAdminHookedApi() : resolveHookedApi(), param.runtime, param.fieldNames, param.tags, param.opts);
1935
2252
  let hooks_onDcbEventLogCreated = dcbEventLogUnknown => {
1936
2253
  if (DcbBackend$ReventlessAws.isPostgres()) {
1937
2254
  return;
@@ -1984,6 +2301,7 @@ function Make($star) {
1984
2301
  schedulerRoleUrn: hooks_schedulerRoleUrn,
1985
2302
  api: hooksApiRef,
1986
2303
  apiRole: hooksApiRoleRef,
2304
+ adminApi: hooksAdminApiRef,
1987
2305
  deployTarget: hooks_deployTarget
1988
2306
  };
1989
2307
  let PluginBuilderImpl = Plugin$ReventlessAws.Make({
@@ -2047,20 +2365,6 @@ function Make($star) {
2047
2365
  authorization: PluginsReadModelSpec$ReventlessCore.authorization,
2048
2366
  visibility: PluginsReadModelSpec$ReventlessCore.visibility
2049
2367
  })(PluginReadModelMappings);
2050
- let UIFragmentRegistryReadModelMappings = {
2051
- moduleUrl: UIFragmentRegistryProjection$ReventlessCore.moduleUrl,
2052
- mappings: UIFragmentRegistryProjection$ReventlessCore.mappings
2053
- };
2054
- let UIFragmentRegistryReadModel = ReadModel_Builder_NoResolver_Stream$ReventlessAws.Make({
2055
- Id: Id$Reventless.$$String,
2056
- name: UIFragmentRegistryReadModelSpec$ReventlessCore.name,
2057
- moduleUrl: UIFragmentRegistryReadModelSpec$ReventlessCore.moduleUrl,
2058
- stateSchema: UIFragmentRegistryReadModelSpec$ReventlessCore.stateSchema,
2059
- config: UIFragmentRegistryReadModelSpec$ReventlessCore.config,
2060
- subIdConfig: undefined,
2061
- authorization: UIFragmentRegistryReadModelSpec$ReventlessCore.authorization,
2062
- visibility: UIFragmentRegistryReadModelSpec$ReventlessCore.visibility
2063
- })(UIFragmentRegistryReadModelMappings);
2064
2368
  let makeScheduler = () => {
2065
2369
  let component = Scheduler$ReventlessAws.make(undefined);
2066
2370
  let outputs = Component$ReventlessCore.outputs(component);
@@ -2173,6 +2477,7 @@ function Make($star) {
2173
2477
  let match = AppSync_Adapter$ReventlessAws.makeApiResource("PlatformApi", {});
2174
2478
  let platformApiRole = match[1];
2175
2479
  let platformApi = match[0];
2480
+ hooksAdminApiRef.contents = Platform_Casts$ReventlessAws.wrapHookedValue(platformApi);
2176
2481
  splitApiOutputsRef.contents = {
2177
2482
  platformApi: platformApi,
2178
2483
  platformApiRole: platformApiRole
@@ -2186,10 +2491,13 @@ function Make($star) {
2186
2491
  platformApiRole: platformApiRole
2187
2492
  };
2188
2493
  }
2189
- let admin = Admin.construct(version, [], [PluginAggregate], [
2190
- PluginReadModel,
2191
- UIFragmentRegistryReadModel
2192
- ], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [], [], [], [], []);
2494
+ let admin = Admin.construct(version, [], [PluginAggregate], [PluginReadModel], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [
2495
+ UiFragmentRegistrySlice,
2496
+ ApiFragmentRegistrySlice
2497
+ ], [
2498
+ UiFragmentsViewSlice,
2499
+ ApiFragmentsViewSlice
2500
+ ], [], [], []);
2193
2501
  let pluginRm = admin.readModelsOutputs["Plugins"];
2194
2502
  if (pluginRm !== undefined) {
2195
2503
  let r = pluginRm.queryDb.resources[0];
@@ -2198,11 +2506,18 @@ function Make($star) {
2198
2506
  AggregateRuntime_Builder_Single$ReventlessAws.setPluginReadModelTable(r.name);
2199
2507
  }
2200
2508
  }
2201
- let rm = admin.readModelsOutputs["UIFragmentRegistry"];
2509
+ let rm = admin.stateViewSlicesOutputs["UiFragments"];
2202
2510
  if (rm !== undefined) {
2203
2511
  let r$1 = rm.queryDb.resources[0];
2204
2512
  if (r$1 !== undefined) {
2205
- Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, {});
2513
+ Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, admin.adminSchemaPushed, {});
2514
+ }
2515
+ }
2516
+ let rm$1 = admin.stateViewSlicesOutputs["ApiFragments"];
2517
+ if (rm$1 !== undefined) {
2518
+ let r$2 = rm$1.queryDb.resources[0];
2519
+ if (r$2 !== undefined) {
2520
+ Platform_ApiFragments_Lambda$ReventlessAws.make(platformApi, r$2.name, admin.adminSchemaPushed, {});
2206
2521
  }
2207
2522
  }
2208
2523
  let pluginComponents = plugins.map(plugin => plugin.make());
@@ -2231,6 +2546,7 @@ function Make($star) {
2231
2546
  let match = AppSync_Adapter$ReventlessAws.makeApiResource("PlatformApi", {});
2232
2547
  let platformApiRole = match[1];
2233
2548
  let platformApi = match[0];
2549
+ hooksAdminApiRef.contents = Platform_Casts$ReventlessAws.wrapHookedValue(platformApi);
2234
2550
  splitApiOutputsRef.contents = {
2235
2551
  platformApi: platformApi,
2236
2552
  platformApiRole: platformApiRole
@@ -2268,7 +2584,7 @@ function Make($star) {
2268
2584
  return;
2269
2585
  }
2270
2586
  });
2271
- let sdl = AppSync_Adapter$ReventlessAws.stampSharedIamTypes(GraphQL_Stitcher$ReventlessCore.stitch(emptyBaseFragment, fragments));
2587
+ let sdl = AppSync_Adapter$ReventlessAws.stitchWithAwsDirectives(emptyBaseFragment, fragments);
2272
2588
  return await AppSync_Adapter$ReventlessAws.startSchemaCreationRetrying(AppSync_Adapter$ReventlessAws.getClient(), {
2273
2589
  apiId: apiId,
2274
2590
  definition: sdl
@@ -2278,10 +2594,13 @@ function Make($star) {
2278
2594
  updateApiSchema: updateApiSchema,
2279
2595
  manageSubscriptions: undefined
2280
2596
  });
2281
- let admin = Admin.construct(version, [PluginExtensionPoint], [PluginAggregate], [
2282
- PluginReadModel,
2283
- UIFragmentRegistryReadModel
2284
- ], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [], [], [], [], []);
2597
+ let admin = Admin.construct(version, [PluginExtensionPoint], [PluginAggregate], [PluginReadModel], scheduler, Util_ResourceNaming$ReventlessAws.operations, platformApi, platformApiRole, [
2598
+ UiFragmentRegistrySlice,
2599
+ ApiFragmentRegistrySlice
2600
+ ], [
2601
+ UiFragmentsViewSlice,
2602
+ ApiFragmentsViewSlice
2603
+ ], [], [], []);
2285
2604
  let pluginRm = admin.readModelsOutputs["Plugins"];
2286
2605
  let pluginReadModelTableName;
2287
2606
  if (pluginRm !== undefined) {
@@ -2310,16 +2629,23 @@ function Make($star) {
2310
2629
  return Pulumi.output("NOT_AVAILABLE");
2311
2630
  }
2312
2631
  });
2313
- PluginRuntime_Builder$ReventlessAws.registerConfig(pluginEpEventTopicArn, pluginReadModelTableName, pluginSchemaPersistenceTable.name, hooks_schedulerRoleUrn.contents, undefined, undefined, domainApiId, false, undefined);
2632
+ PluginRuntime_Builder$ReventlessAws.registerConfig(pluginEpEventTopicArn, pluginReadModelTableName, pluginSchemaPersistenceTable.name, hooks_schedulerRoleUrn.contents, undefined, undefined, domainApiId, false, Output$Pulumi.flatMap(platformApi, api => api.id), Stdlib_Option.map(Stdlib_Option.flatMap(admin.stateViewSlicesOutputs["ApiFragments"], rm => rm.queryDb.resources[0]), r => r.name), AutomationSliceRuntime_Builder_Single$ReventlessAws.getDcbQueueUrl(), true, undefined);
2314
2633
  if (pluginReadModelTableName !== undefined) {
2315
2634
  AggregateRuntime_Builder_Single$ReventlessAws.setPluginReadModelTable(pluginReadModelTableName);
2316
2635
  Platform_ComponentDefinitions_Lambda$ReventlessAws.make(platformApi, pluginReadModelTableName, {});
2317
2636
  }
2318
- let rm = admin.readModelsOutputs["UIFragmentRegistry"];
2637
+ let rm = admin.stateViewSlicesOutputs["UiFragments"];
2319
2638
  if (rm !== undefined) {
2320
2639
  let r$1 = rm.queryDb.resources[0];
2321
2640
  if (r$1 !== undefined) {
2322
- Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, {});
2641
+ Platform_UIFragments_Lambda$ReventlessAws.make(platformApi, r$1.name, admin.adminSchemaPushed, {});
2642
+ }
2643
+ }
2644
+ let rm$1 = admin.stateViewSlicesOutputs["ApiFragments"];
2645
+ if (rm$1 !== undefined) {
2646
+ let r$2 = rm$1.queryDb.resources[0];
2647
+ if (r$2 !== undefined) {
2648
+ Platform_ApiFragments_Lambda$ReventlessAws.make(platformApi, r$2.name, admin.adminSchemaPushed, {});
2323
2649
  }
2324
2650
  }
2325
2651
  Pulumi$Pulumi.$$export("platformApiId", Output$Pulumi.flatMap(platformApi, api => api.id));
@@ -2511,7 +2837,7 @@ function Make($star) {
2511
2837
  return Pulumi$Pulumi.getOutputs();
2512
2838
  };
2513
2839
  let StateViewSlice = {
2514
- Make: include.Make
2840
+ Make: Make$8
2515
2841
  };
2516
2842
  let StateViewSliceStream = {
2517
2843
  Make: include$1.Make