@reventlessdev/reventless-core 3.0.0-alpha.134
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 +1355 -0
- package/LICENSE +202 -0
- package/README.md +173 -0
- package/__mocks__/emptyModule.js +2 -0
- package/jest.setup.cjs +5 -0
- package/package.json +73 -0
- package/rescript.json +41 -0
- package/scripts/deploy.sh +6 -0
- package/scripts/post-deploy.sh +5 -0
- package/scripts/pre-deploy.sh +18 -0
- package/scripts/pulumi-up.sh +30 -0
- package/src/Behavior.res +18 -0
- package/src/Behavior.res.mjs +2 -0
- package/src/ComponentType.res +125 -0
- package/src/ComponentType.res.mjs +199 -0
- package/src/Env.res +5 -0
- package/src/Env.res.mjs +2 -0
- package/src/Mapper.res +36 -0
- package/src/Mapper.res.mjs +18 -0
- package/src/Mapper1toN.res +107 -0
- package/src/Mapper1toN.res.mjs +2 -0
- package/src/MapperNto1.res +78 -0
- package/src/MapperNto1.res.mjs +35 -0
- package/src/Message.res +353 -0
- package/src/Message.res.mjs +418 -0
- package/src/PluginRuntimeOperations.res +15 -0
- package/src/PluginRuntimeOperations.res.mjs +2 -0
- package/src/Projection.res +447 -0
- package/src/Projection.res.mjs +712 -0
- package/src/ProjectionMapper.res +44 -0
- package/src/ProjectionMapper.res.mjs +51 -0
- package/src/RequestContext.res +42 -0
- package/src/RequestContext.res.mjs +39 -0
- package/src/adapter/Adapter.res +178 -0
- package/src/adapter/Adapter.res.mjs +201 -0
- package/src/adapter/AdapterDeploytime.res +56 -0
- package/src/adapter/AdapterDeploytime.res.mjs +42 -0
- package/src/adapter/Auth/Auth_Adapter.res +42 -0
- package/src/adapter/Auth/Auth_Adapter.res.mjs +2 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder.res +22 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder.res.mjs +2 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res +259 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res.mjs +190 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +92 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +59 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +52 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +49 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +64 -0
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +59 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder.res +11 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder.res.mjs +2 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +46 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +40 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +204 -0
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +150 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder.res +18 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder.res.mjs +2 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +36 -0
- package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +28 -0
- package/src/adapter/Runtime/PluginRuntime_Builder.res +23 -0
- package/src/adapter/Runtime/PluginRuntime_Builder.res.mjs +2 -0
- package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res +97 -0
- package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res.mjs +62 -0
- package/src/adapter/Runtime/PluginRuntime_Builder_Single.res +89 -0
- package/src/adapter/Runtime/PluginRuntime_Builder_Single.res.mjs +62 -0
- package/src/adapter/Runtime/Runtime.res +106 -0
- package/src/adapter/Runtime/Runtime.res.mjs +22 -0
- package/src/adapter/Runtime/TaskRuntime_Builder.res +32 -0
- package/src/adapter/Runtime/TaskRuntime_Builder.res.mjs +2 -0
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +42 -0
- package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +29 -0
- package/src/admin/AdminApi.res +88 -0
- package/src/admin/AdminApi.res.mjs +89 -0
- package/src/admin/Admin_Callback.res +27 -0
- package/src/admin/Admin_Callback.res.mjs +20 -0
- package/src/admin/Platform_Admin.res +402 -0
- package/src/admin/Platform_Admin.res.mjs +250 -0
- package/src/admin/Platform_Admin_Structure.res +125 -0
- package/src/admin/Platform_Admin_Structure.res.mjs +182 -0
- package/src/admin/Platform_ComponentDefinitionsApi.res +160 -0
- package/src/admin/Platform_ComponentDefinitionsApi.res.mjs +299 -0
- package/src/admin/Platform_UIFragmentsApi.res +55 -0
- package/src/admin/Platform_UIFragmentsApi.res.mjs +124 -0
- package/src/admin/UIFragmentRegistryProjection.res +43 -0
- package/src/admin/UIFragmentRegistryProjection.res.mjs +81 -0
- package/src/admin/UIFragmentRegistryReadModelSpec.res +13 -0
- package/src/admin/UIFragmentRegistryReadModelSpec.res.mjs +40 -0
- package/src/components/Aggregate/Aggregate.res +96 -0
- package/src/components/Aggregate/Aggregate.res.mjs +82 -0
- package/src/components/Aggregate/Aggregate_Builder.res +175 -0
- package/src/components/Aggregate/Aggregate_Builder.res.mjs +119 -0
- package/src/components/Aggregate/Aggregate_Callback.res +273 -0
- package/src/components/Aggregate/Aggregate_Callback.res.mjs +208 -0
- package/src/components/Api/ApiAllowedStatesHelpers.res +19 -0
- package/src/components/Api/ApiAllowedStatesHelpers.res.mjs +16 -0
- package/src/components/Api/ApiNoApiHelpers.res +13 -0
- package/src/components/Api/ApiNoApiHelpers.res.mjs +29 -0
- package/src/components/Api/Api_Builder.res +40 -0
- package/src/components/Api/Api_Builder.res.mjs +33 -0
- package/src/components/Api/Api_Naming.res +92 -0
- package/src/components/Api/Api_Naming.res.mjs +103 -0
- package/src/components/Api/Api_Operations.res +13 -0
- package/src/components/Api/Api_Operations.res.mjs +12 -0
- package/src/components/Api/GraphQL_FragmentGenerator.res +612 -0
- package/src/components/Api/GraphQL_FragmentGenerator.res.mjs +503 -0
- package/src/components/Api/GraphQL_SchemaInspector.res +156 -0
- package/src/components/Api/GraphQL_SchemaInspector.res.mjs +123 -0
- package/src/components/Api/GraphQL_Stitcher.res +271 -0
- package/src/components/Api/GraphQL_Stitcher.res.mjs +229 -0
- package/src/components/Api/MCP_SchemaGenerator.res +185 -0
- package/src/components/Api/MCP_SchemaGenerator.res.mjs +146 -0
- package/src/components/Api/SchemaType.res +126 -0
- package/src/components/Api/SchemaType.res.mjs +143 -0
- package/src/components/Api/SuryToJsonSchema.res +142 -0
- package/src/components/Api/SuryToJsonSchema.res.mjs +210 -0
- package/src/components/AutomationSlice/AutomationSlice.res +39 -0
- package/src/components/AutomationSlice/AutomationSlice.res.mjs +24 -0
- package/src/components/AutomationSlice/AutomationSlice_Builder.res +207 -0
- package/src/components/AutomationSlice/AutomationSlice_Builder.res.mjs +123 -0
- package/src/components/AutomationSlice/AutomationSlice_Callback.res +212 -0
- package/src/components/AutomationSlice/AutomationSlice_Callback.res.mjs +189 -0
- package/src/components/Builder_Helpers.res +196 -0
- package/src/components/Builder_Helpers.res.mjs +142 -0
- package/src/components/Cloner.res +84 -0
- package/src/components/Cloner.res.mjs +88 -0
- package/src/components/CommandGenerator/CommandGenerator.res +54 -0
- package/src/components/CommandGenerator/CommandGenerator.res.mjs +15 -0
- package/src/components/CommandGenerator/CommandGenerator_Adapter.res +22 -0
- package/src/components/CommandGenerator/CommandGenerator_Adapter.res.mjs +2 -0
- package/src/components/CommandGenerator/CommandGenerator_Builder.res +70 -0
- package/src/components/CommandGenerator/CommandGenerator_Builder.res.mjs +68 -0
- package/src/components/CommandGenerator/CommandGenerator_Callback.res +191 -0
- package/src/components/CommandGenerator/CommandGenerator_Callback.res.mjs +161 -0
- package/src/components/CommandTopic/CommandTopic.res +79 -0
- package/src/components/CommandTopic/CommandTopic.res.mjs +68 -0
- package/src/components/CommandTopic/CommandTopic_Adapter.res +53 -0
- package/src/components/CommandTopic/CommandTopic_Adapter.res.mjs +2 -0
- package/src/components/CommandTopic/CommandTopic_Builder.res +146 -0
- package/src/components/CommandTopic/CommandTopic_Builder.res.mjs +127 -0
- package/src/components/CommandTopic/CommandTopic_Callback.res +38 -0
- package/src/components/CommandTopic/CommandTopic_Callback.res.mjs +49 -0
- package/src/components/CommandTopic/CommandTopic_Helpers.res +176 -0
- package/src/components/CommandTopic/CommandTopic_Helpers.res.mjs +195 -0
- package/src/components/CommandTopic/CommandTopic_Operations.res +40 -0
- package/src/components/CommandTopic/CommandTopic_Operations.res.mjs +49 -0
- package/src/components/Component.res +1 -0
- package/src/components/Component.res.mjs +34 -0
- package/src/components/Component.resi +1 -0
- package/src/components/Counter/Counter.res +47 -0
- package/src/components/Counter/Counter.res.mjs +55 -0
- package/src/components/Counter/Counter_Adapter.res +18 -0
- package/src/components/Counter/Counter_Adapter.res.mjs +2 -0
- package/src/components/Counter/Counter_Builder.res +142 -0
- package/src/components/Counter/Counter_Builder.res.mjs +112 -0
- package/src/components/Counter/Counter_Callback.res +94 -0
- package/src/components/Counter/Counter_Callback.res.mjs +70 -0
- package/src/components/Counter/Counter_Operations.res +70 -0
- package/src/components/Counter/Counter_Operations.res.mjs +91 -0
- package/src/components/Dcb/Dcb_Builder.res +971 -0
- package/src/components/Dcb/Dcb_Builder.res.mjs +572 -0
- package/src/components/DcbEventLog/DcbEventLog.res +43 -0
- package/src/components/DcbEventLog/DcbEventLog.res.mjs +24 -0
- package/src/components/DcbEventLog/DcbEventLog_Adapter.res +57 -0
- package/src/components/DcbEventLog/DcbEventLog_Adapter.res.mjs +2 -0
- package/src/components/DcbEventLog/DcbEventLog_Builder.res +72 -0
- package/src/components/DcbEventLog/DcbEventLog_Builder.res.mjs +67 -0
- package/src/components/DcbEventLog/DcbEventLog_Operations.res +160 -0
- package/src/components/DcbEventLog/DcbEventLog_Operations.res.mjs +121 -0
- package/src/components/EventCollector/EventCollector.res +34 -0
- package/src/components/EventCollector/EventCollector.res.mjs +9 -0
- package/src/components/EventCollector/EventCollector_Adapter.res +45 -0
- package/src/components/EventCollector/EventCollector_Adapter.res.mjs +2 -0
- package/src/components/EventCollector/EventCollector_Builder.res +91 -0
- package/src/components/EventCollector/EventCollector_Builder.res.mjs +64 -0
- package/src/components/EventLog/EventLog.res +27 -0
- package/src/components/EventLog/EventLog.res.mjs +13 -0
- package/src/components/EventLog/EventLog_Adapter.res +15 -0
- package/src/components/EventLog/EventLog_Adapter.res.mjs +2 -0
- package/src/components/EventLog/EventLog_Builder.res +65 -0
- package/src/components/EventLog/EventLog_Builder.res.mjs +57 -0
- package/src/components/EventLog/EventLog_Operations.res +209 -0
- package/src/components/EventLog/EventLog_Operations.res.mjs +202 -0
- package/src/components/EventLog/EventPublish_Callback.res +29 -0
- package/src/components/EventLog/EventPublish_Callback.res.mjs +32 -0
- package/src/components/EventMapper/EventMapper.res +72 -0
- package/src/components/EventMapper/EventMapper.res.mjs +54 -0
- package/src/components/EventMapper/EventMapper_Builder.res +128 -0
- package/src/components/EventMapper/EventMapper_Builder.res.mjs +81 -0
- package/src/components/EventMapper/EventMapper_Callback.res +323 -0
- package/src/components/EventMapper/EventMapper_Callback.res.mjs +231 -0
- package/src/components/EventTopic/EventTopic.res +69 -0
- package/src/components/EventTopic/EventTopic.res.mjs +50 -0
- package/src/components/EventTopic/EventTopic_Adapter.res +15 -0
- package/src/components/EventTopic/EventTopic_Adapter.res.mjs +2 -0
- package/src/components/EventTopic/EventTopic_Builder.res +53 -0
- package/src/components/EventTopic/EventTopic_Builder.res.mjs +46 -0
- package/src/components/EventTopic/EventTopic_Operations.res +37 -0
- package/src/components/EventTopic/EventTopic_Operations.res.mjs +39 -0
- package/src/components/Extension/Extension.res +32 -0
- package/src/components/Extension/Extension.res.mjs +9 -0
- package/src/components/Extension/Extension_Builder.res +82 -0
- package/src/components/Extension/Extension_Builder.res.mjs +57 -0
- package/src/components/Extension/Extension_Operations.res +203 -0
- package/src/components/Extension/Extension_Operations.res.mjs +154 -0
- package/src/components/ExtensionPoint/ExtensionPoint.res +49 -0
- package/src/components/ExtensionPoint/ExtensionPoint.res.mjs +25 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +163 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Builder.res.mjs +113 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Callback.res +110 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Callback.res.mjs +76 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Operations.res +146 -0
- package/src/components/ExtensionPoint/ExtensionPoint_Operations.res.mjs +122 -0
- package/src/components/Heartbeat/Heartbeat.res +25 -0
- package/src/components/Heartbeat/Heartbeat.res.mjs +9 -0
- package/src/components/Heartbeat/Heartbeat_Adapter.res +14 -0
- package/src/components/Heartbeat/Heartbeat_Adapter.res.mjs +2 -0
- package/src/components/Heartbeat/Heartbeat_Builder.res +43 -0
- package/src/components/Heartbeat/Heartbeat_Builder.res.mjs +47 -0
- package/src/components/Heartbeat/Heartbeat_Callback.res +32 -0
- package/src/components/Heartbeat/Heartbeat_Callback.res.mjs +40 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice.res +34 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice.res.mjs +24 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +98 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res.mjs +87 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res +191 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res.mjs +175 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res +35 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res.mjs +24 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +181 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res.mjs +137 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Callback.res +173 -0
- package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Callback.res.mjs +173 -0
- package/src/components/QueryDb/QueryDb.res +74 -0
- package/src/components/QueryDb/QueryDb.res.mjs +37 -0
- package/src/components/QueryDb/QueryDb_Adapter.res +78 -0
- package/src/components/QueryDb/QueryDb_Adapter.res.mjs +17 -0
- package/src/components/QueryDb/QueryDb_Builder.res +76 -0
- package/src/components/QueryDb/QueryDb_Builder.res.mjs +53 -0
- package/src/components/QueryDb/QueryDb_Callback.res +18 -0
- package/src/components/QueryDb/QueryDb_Callback.res.mjs +21 -0
- package/src/components/QueryDb/QueryDb_Operations.res +116 -0
- package/src/components/QueryDb/QueryDb_Operations.res.mjs +165 -0
- package/src/components/ReadModel/ReadModel.res +42 -0
- package/src/components/ReadModel/ReadModel.res.mjs +27 -0
- package/src/components/ReadModel/ReadModel_Builder.res +155 -0
- package/src/components/ReadModel/ReadModel_Builder.res.mjs +101 -0
- package/src/components/ReadModel/ReadModel_Callback.res +48 -0
- package/src/components/ReadModel/ReadModel_Callback.res.mjs +48 -0
- package/src/components/Scheduler/Scheduler.res +13 -0
- package/src/components/Scheduler/Scheduler.res.mjs +9 -0
- package/src/components/Scheduler/Scheduler_Adapter.res +13 -0
- package/src/components/Scheduler/Scheduler_Adapter.res.mjs +2 -0
- package/src/components/Scheduler/Scheduler_Builder.res +19 -0
- package/src/components/Scheduler/Scheduler_Builder.res.mjs +29 -0
- package/src/components/SideEffectHandler/SideEffectHandler.res +30 -0
- package/src/components/SideEffectHandler/SideEffectHandler.res.mjs +12 -0
- package/src/components/SideEffectHandler/SideEffectHandler_Builder.res +117 -0
- package/src/components/SideEffectHandler/SideEffectHandler_Builder.res.mjs +64 -0
- package/src/components/SideEffectHandler/SideEffectHandler_Callback.res +116 -0
- package/src/components/SideEffectHandler/SideEffectHandler_Callback.res.mjs +95 -0
- package/src/components/StateChangeSlice/StateChangeSlice.res +38 -0
- package/src/components/StateChangeSlice/StateChangeSlice.res.mjs +17 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +91 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Builder.res.mjs +81 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +412 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +299 -0
- package/src/components/StateTopic.res +91 -0
- package/src/components/StateTopic.res.mjs +41 -0
- package/src/components/StateViewSlice/StateViewSlice.res +33 -0
- package/src/components/StateViewSlice/StateViewSlice.res.mjs +24 -0
- package/src/components/StateViewSlice/StateViewSlice_Builder.res +176 -0
- package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +134 -0
- package/src/components/StateViewSlice/StateViewSlice_Callback.res +64 -0
- package/src/components/StateViewSlice/StateViewSlice_Callback.res.mjs +56 -0
- package/src/components/Task/Task.res +81 -0
- package/src/components/Task/Task.res.mjs +51 -0
- package/src/components/Task/Task_Adapter.res +31 -0
- package/src/components/Task/Task_Adapter.res.mjs +2 -0
- package/src/components/Task/Task_Builder.res +223 -0
- package/src/components/Task/Task_Builder.res.mjs +115 -0
- package/src/plugin/api/PluginBaseFragment.res +104 -0
- package/src/plugin/api/PluginBaseFragment.res.mjs +64 -0
- package/src/plugin/component/Plugin.res +100 -0
- package/src/plugin/component/Plugin.res.mjs +61 -0
- package/src/plugin/component/Plugin_Builder.res +1017 -0
- package/src/plugin/component/Plugin_Builder.res.mjs +608 -0
- package/src/plugin/component/Plugin_BuiltHook.res +141 -0
- package/src/plugin/component/Plugin_BuiltHook.res.mjs +39 -0
- package/src/plugin/component/Plugin_Callback.res +98 -0
- package/src/plugin/component/Plugin_Callback.res.mjs +55 -0
- package/src/plugin/component/Plugin_Helpers.res +1730 -0
- package/src/plugin/component/Plugin_Helpers.res.mjs +1010 -0
- package/src/plugin/component/Plugin_ResolverError.res +27 -0
- package/src/plugin/component/Plugin_ResolverError.res.mjs +21 -0
- package/src/plugin/component/Plugin_Structure.res +570 -0
- package/src/plugin/component/Plugin_Structure.res.mjs +458 -0
- package/src/plugin/component/Plugin_SubscriptionSchema.res +103 -0
- package/src/plugin/component/Plugin_SubscriptionSchema.res.mjs +71 -0
- package/src/plugin/component/SchemaWalker.res +164 -0
- package/src/plugin/component/SchemaWalker.res.mjs +183 -0
- package/src/plugin/connect/PluginConnectExtension_Builder.res +14 -0
- package/src/plugin/connect/PluginConnectExtension_Builder.res.mjs +36 -0
- package/src/plugin/connect/PluginConnectExtension_Mapping.res +76 -0
- package/src/plugin/connect/PluginConnectExtension_Mapping.res.mjs +89 -0
- package/src/plugin/connect/PluginExtensionPoint_Builder.res +39 -0
- package/src/plugin/connect/PluginExtensionPoint_Builder.res.mjs +33 -0
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res +231 -0
- package/src/plugin/connect/PluginExtensionPoint_Plugin.res.mjs +353 -0
- package/src/plugin/lifecycle/PluginBehavior.res +250 -0
- package/src/plugin/lifecycle/PluginBehavior.res.mjs +391 -0
- package/src/plugin/lifecycle/PluginSpec.res +84 -0
- package/src/plugin/lifecycle/PluginSpec.res.mjs +148 -0
- package/src/plugin/lifecycle/PluginsProjection.res +154 -0
- package/src/plugin/lifecycle/PluginsProjection.res.mjs +230 -0
- package/src/plugin/lifecycle/PluginsReadModelSpec.res +66 -0
- package/src/plugin/lifecycle/PluginsReadModelSpec.res.mjs +58 -0
- package/src/util/AWS.res +7 -0
- package/src/util/AWS.res.mjs +20 -0
- package/src/util/CSV.res +27 -0
- package/src/util/CSV.res.mjs +56 -0
- package/src/util/CommandPublisher.res +133 -0
- package/src/util/CommandPublisher.res.mjs +161 -0
- package/src/util/CsvStream.res +39 -0
- package/src/util/CsvStream.res.mjs +42 -0
- package/src/util/EffectLogger.res +178 -0
- package/src/util/EffectLogger.res.mjs +171 -0
- package/src/util/FTP.res +69 -0
- package/src/util/FTP.res.mjs +101 -0
- package/src/util/FTPHandler.res +142 -0
- package/src/util/FTPHandler.res.mjs +136 -0
- package/src/util/Hash.res +1 -0
- package/src/util/Hash.res.mjs +10 -0
- package/src/util/Interstack.res +74 -0
- package/src/util/Interstack.res.mjs +126 -0
- package/src/util/Interstack.resi +25 -0
- package/src/util/LogFormat.res +222 -0
- package/src/util/LogFormat.res.mjs +257 -0
- package/src/util/Logger.res +196 -0
- package/src/util/Logger.res.mjs +238 -0
- package/src/util/Lru.res +51 -0
- package/src/util/Lru.res.mjs +59 -0
- package/src/util/Lru.resi +32 -0
- package/src/util/Metrics.res +32 -0
- package/src/util/Metrics.res.mjs +42 -0
- package/src/util/OutputFailsafeDeploytime.res +16 -0
- package/src/util/OutputFailsafeDeploytime.res.mjs +20 -0
- package/src/util/OutputFailsafeRuntime.res +6 -0
- package/src/util/OutputFailsafeRuntime.res.mjs +15 -0
- package/src/util/OutputLogger.res +9 -0
- package/src/util/OutputLogger.res.mjs +19 -0
- package/src/util/ResourceQuery.res +14 -0
- package/src/util/ResourceQuery.res.mjs +17 -0
- package/src/util/ResourceQueryRuntime.res +17 -0
- package/src/util/ResourceQueryRuntime.res.mjs +18 -0
- package/src/util/ScheduleOps.res +124 -0
- package/src/util/ScheduleOps.res.mjs +132 -0
- package/src/util/Util.res +12 -0
- package/src/util/Util.res.mjs +42 -0
- package/src/util/Util_Adapter.res +97 -0
- package/src/util/Util_Adapter.res.mjs +82 -0
- package/src/util/Util_AdapterRuntime.res +39 -0
- package/src/util/Util_AdapterRuntime.res.mjs +42 -0
- package/src/util/Util_Array.res +2 -0
- package/src/util/Util_Array.res.mjs +12 -0
- package/src/util/Util_Error.res +16 -0
- package/src/util/Util_Error.res.mjs +19 -0
- package/src/util/Util_Promise.res +67 -0
- package/src/util/Util_Promise.res.mjs +105 -0
- package/src/util/Util_Pulumi.res +35 -0
- package/src/util/Util_Pulumi.res.mjs +55 -0
- package/src/util/Util_Pulumi.resi +21 -0
- package/src/util/Util_QueryDb.res +14 -0
- package/src/util/Util_QueryDb.res.mjs +21 -0
- package/src/util/Util_QueryDbRuntime.res +11 -0
- package/src/util/Util_QueryDbRuntime.res.mjs +19 -0
- package/src/util/Util_ReadModel.res +2 -0
- package/src/util/Util_ReadModel.res.mjs +10 -0
- package/src/util/Util_StackRefs.res +24 -0
- package/src/util/Util_StackRefs.res.mjs +39 -0
- package/src/util/Validation.res +75 -0
- package/src/util/Validation.res.mjs +181 -0
- package/tests/.gitkeep +0 -0
- package/tests/IdentityTest.res +155 -0
- package/tests/IdentityTest.res.mjs +174 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res +237 -0
- package/tests/admin/Platform_ComponentDefinitionsApiTest.res.mjs +298 -0
- package/tests/admin/Platform_UIFragmentsApiTest.res +96 -0
- package/tests/admin/Platform_UIFragmentsApiTest.res.mjs +101 -0
- package/tests/aggregate/AggregateCallbackTest.res +81 -0
- package/tests/aggregate/AggregateCallbackTest.res.mjs +140 -0
- package/tests/aggregate/AggregateCausationTest.res +49 -0
- package/tests/aggregate/AggregateCausationTest.res.mjs +44 -0
- package/tests/aggregate/AggregateConflictTest.res +212 -0
- package/tests/aggregate/AggregateConflictTest.res.mjs +363 -0
- package/tests/aggregate/AggregateFixtures.res +177 -0
- package/tests/aggregate/AggregateFixtures.res.mjs +285 -0
- package/tests/aggregate/AggregateRejectionTest.res +139 -0
- package/tests/aggregate/AggregateRejectionTest.res.mjs +163 -0
- package/tests/api/ApiNoApiTest.res +62 -0
- package/tests/api/ApiNoApiTest.res.mjs +90 -0
- package/tests/api/GraphQL_StitcherTest.res +107 -0
- package/tests/api/GraphQL_StitcherTest.res.mjs +99 -0
- package/tests/api/SimpleTest.res +7 -0
- package/tests/api/SimpleTest.res.mjs +10 -0
- package/tests/api/SuryToJsonSchemaTest.res +405 -0
- package/tests/api/SuryToJsonSchemaTest.res.mjs +623 -0
- package/tests/commandgenerator/CommandGeneratorCallbackTest.res +128 -0
- package/tests/commandgenerator/CommandGeneratorCallbackTest.res.mjs +160 -0
- package/tests/commandgenerator/CommandGeneratorFixtures.res +139 -0
- package/tests/commandgenerator/CommandGeneratorFixtures.res.mjs +197 -0
- package/tests/commandtopic/CommandTopicCallbackFixtures.res +87 -0
- package/tests/commandtopic/CommandTopicCallbackFixtures.res.mjs +152 -0
- package/tests/commandtopic/CommandTopicCallbackTest.res +66 -0
- package/tests/commandtopic/CommandTopicCallbackTest.res.mjs +106 -0
- package/tests/commandtopic/CommandTopicHelpersRejectionTest.res +83 -0
- package/tests/commandtopic/CommandTopicHelpersRejectionTest.res.mjs +109 -0
- package/tests/counter/CounterCallbackTest.res +83 -0
- package/tests/counter/CounterCallbackTest.res.mjs +140 -0
- package/tests/counter/CounterFixtures.res +57 -0
- package/tests/counter/CounterFixtures.res.mjs +67 -0
- package/tests/dcb/DcbDecodeTest.res +122 -0
- package/tests/dcb/DcbDecodeTest.res.mjs +194 -0
- package/tests/dcb/DcbEventLogOperationsTest.res +195 -0
- package/tests/dcb/DcbEventLogOperationsTest.res.mjs +268 -0
- package/tests/dcb/DcbFixtures.res +422 -0
- package/tests/dcb/DcbFixtures.res.mjs +534 -0
- package/tests/dcb/DcbScopeInferenceTest.res +242 -0
- package/tests/dcb/DcbScopeInferenceTest.res.mjs +480 -0
- package/tests/dcb/DcbStateChangeSliceTest.res +362 -0
- package/tests/dcb/DcbStateChangeSliceTest.res.mjs +546 -0
- package/tests/dcb/DcbTagTest.res +978 -0
- package/tests/dcb/DcbTagTest.res.mjs +867 -0
- package/tests/dcb/DcbValidationTest.res +349 -0
- package/tests/dcb/DcbValidationTest.res.mjs +476 -0
- package/tests/eventlog/EventLogFixtures.res +113 -0
- package/tests/eventlog/EventLogFixtures.res.mjs +166 -0
- package/tests/eventlog/EventLogOperationsTest.res +96 -0
- package/tests/eventlog/EventLogOperationsTest.res.mjs +192 -0
- package/tests/eventlog/EventLogRetryTest.res +121 -0
- package/tests/eventlog/EventLogRetryTest.res.mjs +171 -0
- package/tests/eventmapper/EventMapperCallbackTest.res +134 -0
- package/tests/eventmapper/EventMapperCallbackTest.res.mjs +141 -0
- package/tests/eventmapper/EventMapperFixtures.res +255 -0
- package/tests/eventmapper/EventMapperFixtures.res.mjs +440 -0
- package/tests/eventmapper/EventMapperTest.res +53 -0
- package/tests/eventmapper/EventMapperTest.res.mjs +83 -0
- package/tests/eventtopic/EventTopicFixtures.res +36 -0
- package/tests/eventtopic/EventTopicFixtures.res.mjs +65 -0
- package/tests/eventtopic/EventTopicOperationsTest.res +48 -0
- package/tests/eventtopic/EventTopicOperationsTest.res.mjs +71 -0
- package/tests/extensionpoint/ExtensionPointCallbackTest.res +84 -0
- package/tests/extensionpoint/ExtensionPointCallbackTest.res.mjs +94 -0
- package/tests/extensionpoint/ExtensionPointFixtures.res +173 -0
- package/tests/extensionpoint/ExtensionPointFixtures.res.mjs +205 -0
- package/tests/extensionpoint/ExtensionPointOperationsTest.res +261 -0
- package/tests/extensionpoint/ExtensionPointOperationsTest.res.mjs +304 -0
- package/tests/ftp/FTPTest.res +64 -0
- package/tests/ftp/FTPTest.res.mjs +88 -0
- package/tests/logger/LogFormatTest.res +348 -0
- package/tests/logger/LogFormatTest.res.mjs +309 -0
- package/tests/message/MessageTest.res +95 -0
- package/tests/message/MessageTest.res.mjs +93 -0
- package/tests/message/MetaEnvelopeTest.res +200 -0
- package/tests/message/MetaEnvelopeTest.res.mjs +188 -0
- package/tests/plugin/ManifestVisibilityTest.res +137 -0
- package/tests/plugin/ManifestVisibilityTest.res.mjs +205 -0
- package/tests/plugin/PluginSpecExperiment.res +13 -0
- package/tests/plugin/PluginSpecExperiment.res.mjs +31 -0
- package/tests/plugin/PluginStructureTest.res +298 -0
- package/tests/plugin/PluginStructureTest.res.mjs +388 -0
- package/tests/plugin/PluginVersionTest.res +34 -0
- package/tests/plugin/PluginVersionTest.res.mjs +30 -0
- package/tests/plugin/SchemaWalkerTest.res +115 -0
- package/tests/plugin/SchemaWalkerTest.res.mjs +160 -0
- package/tests/plugin/StateChangeSlice/PsPlaceOrder.res +24 -0
- package/tests/plugin/StateChangeSlice/PsPlaceOrder.res.mjs +62 -0
- package/tests/plugin/StateChangeSlice/PsShipOrder.res +29 -0
- package/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs +69 -0
- package/tests/plugin/StateViewSlice/PsAnnotatedView.res +24 -0
- package/tests/plugin/StateViewSlice/PsAnnotatedView.res.mjs +94 -0
- package/tests/plugin/StateViewSlice/PsAvailableProductsView.res +18 -0
- package/tests/plugin/StateViewSlice/PsAvailableProductsView.res.mjs +69 -0
- package/tests/plugin/StateViewSlice/PsCustomersView.res +22 -0
- package/tests/plugin/StateViewSlice/PsCustomersView.res.mjs +69 -0
- package/tests/plugin/StateViewSlice/PsOrdersView.res +20 -0
- package/tests/plugin/StateViewSlice/PsOrdersView.res.mjs +81 -0
- package/tests/poc/StructuralSubtypingPoc.res +211 -0
- package/tests/poc/StructuralSubtypingPoc.res.mjs +61 -0
- package/tests/querydb/QueryDbFixtures.res +65 -0
- package/tests/querydb/QueryDbFixtures.res.mjs +135 -0
- package/tests/querydb/QueryDbOperationsTest.res +94 -0
- package/tests/querydb/QueryDbOperationsTest.res.mjs +168 -0
- package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res +56 -0
- package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res.mjs +77 -0
- package/tests/sideeffecthandler/SideEffectHandlerFixtures.res +96 -0
- package/tests/sideeffecthandler/SideEffectHandlerFixtures.res.mjs +139 -0
- package/tests/util/CsvStreamTest.res +54 -0
- package/tests/util/CsvStreamTest.res.mjs +51 -0
- package/tests/util/LruTest.res +73 -0
- package/tests/util/LruTest.res.mjs +105 -0
- package/tests/util/MetricsTest.res +36 -0
- package/tests/util/MetricsTest.res.mjs +53 -0
|
@@ -0,0 +1,1017 @@
|
|
|
1
|
+
open Plugin_Helpers
|
|
2
|
+
|
|
3
|
+
module PluginExtensionPointSpec = ReventlessInfra.PluginExtensionPointSpec
|
|
4
|
+
|
|
5
|
+
// (No type aliases needed — adminExtensionPoints is accessed as a ref field
|
|
6
|
+
// on Spec.hooks, so no optional-parameter parsing issues arise.)
|
|
7
|
+
|
|
8
|
+
module type Spec = {
|
|
9
|
+
let runtimeOps: PluginRuntimeOperations.operations
|
|
10
|
+
let resourceNaming: ReventlessInfra.ResourceNaming.operations
|
|
11
|
+
let environment: string
|
|
12
|
+
/** Deployment-level identity (Pulumi project name in AWS, "local" in
|
|
13
|
+
the local platform). Threaded into `AutomationSlice.context` so
|
|
14
|
+
mappings can populate partition tags from deployment metadata. */
|
|
15
|
+
let platformName: string
|
|
16
|
+
let hooks: Plugin_Helpers.platformHooks
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module Make = (
|
|
20
|
+
Spec: Spec,
|
|
21
|
+
ApiSpec: {
|
|
22
|
+
type api
|
|
23
|
+
type role
|
|
24
|
+
},
|
|
25
|
+
FragmentProvider: ReventlessInfra.Api_Adapter.Provider,
|
|
26
|
+
RuntimeEnvironment: Runtime.Environment,
|
|
27
|
+
EventCollectorChannel: EventCollector_Adapter.Channel
|
|
28
|
+
with type runtimeParts = RuntimeEnvironment.parts,
|
|
29
|
+
QueryEngineAdapter: QueryDb_Adapter.QueryEngineAdapter,
|
|
30
|
+
PluginExtensionPointRemoteChannel: CommandTopic_Adapter.RemoteChannel,
|
|
31
|
+
HeartbeatRunner: Heartbeat_Adapter.Runner with type runtimeParts = RuntimeEnvironment.parts,
|
|
32
|
+
PluginRuntimeBuilder: PluginRuntime_Builder.T
|
|
33
|
+
with module EventCollectorChannel = EventCollectorChannel
|
|
34
|
+
and type runtimeParts = RuntimeEnvironment.parts,
|
|
35
|
+
DcbEventLogStorage: DcbEventLog_Adapter.Storage,
|
|
36
|
+
DcbEventTopicPublisher: EventTopic_Adapter.Publisher,
|
|
37
|
+
DcbCommandTopicChannel: CommandTopic_Adapter.Channel,
|
|
38
|
+
DcbCommandTopicChannelAsync: CommandTopic_Adapter.Channel,
|
|
39
|
+
): (Plugin.T with type api = ApiSpec.api and type role = ApiSpec.role) => {
|
|
40
|
+
type api = ApiSpec.api
|
|
41
|
+
type role = ApiSpec.role
|
|
42
|
+
|
|
43
|
+
let construct = (
|
|
44
|
+
~version: string,
|
|
45
|
+
~heartbeatInterval: int,
|
|
46
|
+
~extensionPoints: array<module(ReventlessInfra.ExtensionPoint.T)>,
|
|
47
|
+
~extensions: array<module(ReventlessInfra.Extension.Blueprint)>,
|
|
48
|
+
~aggregates: array<module(ReventlessInfra.Aggregate.T with type api = api)>,
|
|
49
|
+
~readModels: array<
|
|
50
|
+
module(ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
51
|
+
>,
|
|
52
|
+
~tasks: array<module(ReventlessInfra.Task.T)>,
|
|
53
|
+
~stateChangeSlices: array<module(ReventlessInfra.StateChangeSlice.T)>,
|
|
54
|
+
~stateViewSlices: array<module(ReventlessInfra.StateViewSlice.T)>,
|
|
55
|
+
~automationSlices: array<module(ReventlessInfra.AutomationSlice.T)>,
|
|
56
|
+
~outboundTranslationSlices: array<module(ReventlessInfra.OutboundTranslationSlice.T)>,
|
|
57
|
+
~inboundTranslationSlices: array<module(ReventlessInfra.InboundTranslationSlice.T)>,
|
|
58
|
+
~uiFragments: option<Reventless.Plugin.uiFragmentManifest>,
|
|
59
|
+
~pluginStructure: option<Reventless.Plugin.pluginStructure>,
|
|
60
|
+
self,
|
|
61
|
+
name,
|
|
62
|
+
) => {
|
|
63
|
+
// Tag all logs emitted during this plugin's construction with `[name]`.
|
|
64
|
+
// Restored at the end of construct; nested constructs (none today) would stack.
|
|
65
|
+
let _prevPluginName = Logger.currentPluginName.contents
|
|
66
|
+
Logger.currentPluginName := Some(name)
|
|
67
|
+
|
|
68
|
+
// Register every component → plugin so runtime logs (fired after construct
|
|
69
|
+
// returns) can resolve a comp like `StateChangeSlice(AddProduct)` to its
|
|
70
|
+
// owning plugin via `Logger.componentPluginRegistry`. Also register the
|
|
71
|
+
// plugin's own name so dotted EP / Plugin / CommandTopic log comps resolve.
|
|
72
|
+
let registerComp = compName =>
|
|
73
|
+
Logger.registerComponentPlugin(~componentName=compName, ~pluginName=name)
|
|
74
|
+
registerComp(name)
|
|
75
|
+
aggregates->Array.forEach((module(M: ReventlessInfra.Aggregate.T with type api = api)) =>
|
|
76
|
+
registerComp(M.Spec.name)
|
|
77
|
+
)
|
|
78
|
+
readModels->Array.forEach((
|
|
79
|
+
module(R: ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
80
|
+
) => registerComp(R.Spec.name))
|
|
81
|
+
stateChangeSlices->Array.forEach((module(Sc: ReventlessInfra.StateChangeSlice.T)) =>
|
|
82
|
+
registerComp(Sc.Spec.name)
|
|
83
|
+
)
|
|
84
|
+
stateViewSlices->Array.forEach((module(Sv: ReventlessInfra.StateViewSlice.T)) =>
|
|
85
|
+
registerComp(Sv.Spec.name)
|
|
86
|
+
)
|
|
87
|
+
automationSlices->Array.forEach((module(As: ReventlessInfra.AutomationSlice.T)) =>
|
|
88
|
+
registerComp(As.Spec.name)
|
|
89
|
+
)
|
|
90
|
+
outboundTranslationSlices->Array.forEach((
|
|
91
|
+
module(Ots: ReventlessInfra.OutboundTranslationSlice.T),
|
|
92
|
+
) => registerComp(Ots.Spec.name))
|
|
93
|
+
inboundTranslationSlices->Array.forEach((
|
|
94
|
+
module(Its: ReventlessInfra.InboundTranslationSlice.T),
|
|
95
|
+
) => registerComp(Its.Spec.name))
|
|
96
|
+
tasks->Array.forEach((module(T: ReventlessInfra.Task.T)) => registerComp(T.Spec.name))
|
|
97
|
+
// Extensions deliberately not registered: their Spec.name is the filename stem
|
|
98
|
+
// (e.g. "Products") and would collide with same-named SVS/ReadModels in other
|
|
99
|
+
// plugins. Extension log comps already use the fully-qualified EP form
|
|
100
|
+
// `Extension(Catalog.Products.Ordering)`; the lastDot transformation resolves
|
|
101
|
+
// them to the consumer plugin via its self-registration.
|
|
102
|
+
|
|
103
|
+
// Read platform context from hooks refs (populated by makePlatform/deployPlugin).
|
|
104
|
+
let scheduler = switch Spec.hooks.scheduler.contents {
|
|
105
|
+
| Some(s) => s
|
|
106
|
+
| None =>
|
|
107
|
+
JsError.throwWithMessage(
|
|
108
|
+
"Plugin_Builder: scheduler not set — call makePlatform/deployPlugin first",
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
let schedulerRoleUrn = Spec.hooks.schedulerRoleUrn.contents
|
|
112
|
+
let api: api = switch Spec.hooks.api.contents {
|
|
113
|
+
| Some({val}) => Obj.magic(val)
|
|
114
|
+
| None =>
|
|
115
|
+
JsError.throwWithMessage(
|
|
116
|
+
"Plugin_Builder: api not set — call makePlatform/deployPlugin first",
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
let apiRole: role = switch Spec.hooks.apiRole.contents {
|
|
120
|
+
| Some({val}) => Obj.magic(val)
|
|
121
|
+
| None =>
|
|
122
|
+
JsError.throwWithMessage(
|
|
123
|
+
"Plugin_Builder: apiRole not set — call makePlatform/deployPlugin first",
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let id = Plugin.makeId(name, version)
|
|
128
|
+
let opts = {Pulumi.ComponentResource.parent: self->Component.toPulumiResource}
|
|
129
|
+
let childName = name->ComponentType.name(Plugin.componentType)
|
|
130
|
+
|
|
131
|
+
// Aggregates are constructed early so their EventTopics can feed multi-source
|
|
132
|
+
// AutomationSlices created inside DcbBuilder. The same `aggregateEventTopics`
|
|
133
|
+
// dict (after merging in the DCB EventLog topic) is reused later as
|
|
134
|
+
// `allEventTopics` for ReadModels.
|
|
135
|
+
let aggregatesWithoutEventMappers = aggregates->createAggregatesWithoutEventMappers(~api, opts)
|
|
136
|
+
let aggregateEventTopics = Aggregate.allEventTopics(aggregatesWithoutEventMappers)
|
|
137
|
+
|
|
138
|
+
// Construct DCB components and derive DCB-specific API schema entries
|
|
139
|
+
module DcbBuilder = Dcb_Builder.Make(
|
|
140
|
+
DcbEventLogStorage,
|
|
141
|
+
DcbEventTopicPublisher,
|
|
142
|
+
DcbCommandTopicChannel,
|
|
143
|
+
DcbCommandTopicChannelAsync,
|
|
144
|
+
PluginRuntimeBuilder,
|
|
145
|
+
Spec,
|
|
146
|
+
)
|
|
147
|
+
let dcbResult = DcbBuilder.construct(
|
|
148
|
+
~name,
|
|
149
|
+
~childName,
|
|
150
|
+
~environment=Spec.environment,
|
|
151
|
+
~platformName=Spec.platformName,
|
|
152
|
+
~aggregateEventTopics,
|
|
153
|
+
~stateChangeSlices,
|
|
154
|
+
~stateViewSlices,
|
|
155
|
+
~automationSlices,
|
|
156
|
+
~outboundTranslationSlices,
|
|
157
|
+
~inboundTranslationSlices,
|
|
158
|
+
~pluginStructure?,
|
|
159
|
+
~opts,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
// Derive GraphQL schema fragment for this plugin
|
|
163
|
+
let mutationEntriesFromAggregates =
|
|
164
|
+
aggregates->Array.flatMap((module(M: ReventlessInfra.Aggregate.T with type api = api)) => {
|
|
165
|
+
let commandSchema = M.Spec.commandSchema->S.castToUnknown
|
|
166
|
+
if ApiNoApiHelpers.isNoApi(commandSchema) {
|
|
167
|
+
[]
|
|
168
|
+
} else {
|
|
169
|
+
let constructorNames = Reventless.DcbTag.extractAllVariantNames(M.Spec.commandSchema)
|
|
170
|
+
let filteredConstructorNames = ApiNoApiHelpers.filterNoApiVariants(constructorNames, commandSchema)
|
|
171
|
+
let fieldNames =
|
|
172
|
+
filteredConstructorNames->Array.map(cname =>
|
|
173
|
+
Api_Naming.aggregateMutationField(~plugin=name, ~aggregate=M.Spec.name, ~command=cname)
|
|
174
|
+
)
|
|
175
|
+
// Register plugin-prefixed field names for CommandGenerator_Builder.
|
|
176
|
+
Plugin_Helpers.aggregateMutationFieldsRegistry->Dict.set(M.Spec.name, fieldNames)
|
|
177
|
+
if fieldNames->Array.length === 0 {
|
|
178
|
+
[]
|
|
179
|
+
} else {
|
|
180
|
+
// Register aggregate mutation SDL + resolver stubs synchronously via hook
|
|
181
|
+
// (before Output.apply chains fire).
|
|
182
|
+
Spec.hooks.mutationResolverHook->Option.forEach(registerResolver =>
|
|
183
|
+
registerResolver(
|
|
184
|
+
~kind=Aggregate,
|
|
185
|
+
~fields=fieldNames,
|
|
186
|
+
~commandSchema,
|
|
187
|
+
~commandAuthorization=M.Spec.commandAuthorization->Obj.magic,
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
let aggDef =
|
|
191
|
+
pluginStructure->Option.flatMap(s =>
|
|
192
|
+
s.aggregates->Array.find(d => d.name == M.Spec.name)
|
|
193
|
+
)
|
|
194
|
+
// Stage E2 (host-ui-login-core): derive per-field permissions by
|
|
195
|
+
// evaluating the PPX-generated `commandAuthorization` against a
|
|
196
|
+
// synthetic command value per constructor. Mirrors the resolver-time
|
|
197
|
+
// shape from `CommandGeneratorResolvers_GraphQL.syntheticCommand` —
|
|
198
|
+
// payload-bearing variants compile to `{TAG, ...}`, payload-less to
|
|
199
|
+
// bare strings.
|
|
200
|
+
let fieldPermissions = Dict.make()
|
|
201
|
+
filteredConstructorNames->Array.forEachWithIndex((cname, idx) => {
|
|
202
|
+
let fieldName = fieldNames->Array.getUnsafe(idx)
|
|
203
|
+
let hasPayload =
|
|
204
|
+
Reventless.DcbTag.isVariantPayloadBearing(M.Spec.commandSchema->Obj.magic, cname)
|
|
205
|
+
let syntheticCmd: unknown =
|
|
206
|
+
hasPayload ? {"TAG": cname}->Obj.magic : cname->Obj.magic
|
|
207
|
+
let rule = M.Spec.commandAuthorization(syntheticCmd->Obj.magic)
|
|
208
|
+
fieldPermissions->Dict.set(fieldName, rule)
|
|
209
|
+
})
|
|
210
|
+
[{
|
|
211
|
+
ReventlessInfra.Api.fieldNames,
|
|
212
|
+
commandSchema,
|
|
213
|
+
fieldPermissions,
|
|
214
|
+
linkedViews: ?aggDef->Option.map(d => d.linkedViews),
|
|
215
|
+
consistencyRead: ?aggDef->Option.flatMap(d => d.consistencyRead),
|
|
216
|
+
}]
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
let mutationEntries = Array.concat(mutationEntriesFromAggregates, dcbResult.mutationEntries)
|
|
222
|
+
|
|
223
|
+
let queryEntriesFromReadModels =
|
|
224
|
+
readModels->Array.map((
|
|
225
|
+
module(R: ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
226
|
+
) => {
|
|
227
|
+
let qn = Api_Naming.queryFieldNamesForReadModel(~plugin=name, ~name=R.Spec.name)
|
|
228
|
+
let subIdField = R.Spec.subIdConfig->Option.map(c => c.subIdField)
|
|
229
|
+
{
|
|
230
|
+
ReventlessInfra.Api.singleFieldName: qn.singleFieldName,
|
|
231
|
+
listFieldName: qn.listFieldName,
|
|
232
|
+
returnTypeName: qn.returnTypeName,
|
|
233
|
+
stateSchema: R.Spec.stateSchema->S.castToUnknown,
|
|
234
|
+
authorization: None,
|
|
235
|
+
permission: R.Spec.authorization,
|
|
236
|
+
connectionSpec: true,
|
|
237
|
+
subIdField: ?subIdField,
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
let queryEntries = Array.concat(queryEntriesFromReadModels, dcbResult.queryEntries)
|
|
242
|
+
|
|
243
|
+
let eventLogEntriesFromAggregates =
|
|
244
|
+
aggregates->Array.map((module(M: ReventlessInfra.Aggregate.T with type api = api)) => {
|
|
245
|
+
ReventlessInfra.Api.busKey: M.Spec.name ++ "Aggr" ++ "EventLog",
|
|
246
|
+
displayName: M.Spec.name,
|
|
247
|
+
eventSchema: M.Spec.eventSchema->S.castToUnknown,
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
let eventLogEntries = Array.concat(eventLogEntriesFromAggregates, dcbResult.eventLogEntries)
|
|
251
|
+
|
|
252
|
+
// Populate query field names registry so resolvers align with fragment SDL.
|
|
253
|
+
// Keyed by the Spec.name that each component uses for its QueryDb.
|
|
254
|
+
// (StateViewSlice registry is populated earlier, inside the DCB builder,
|
|
255
|
+
// before StateViewSlice.make calls — see above.)
|
|
256
|
+
readModels->Array.forEach((
|
|
257
|
+
module(R: ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
258
|
+
) => {
|
|
259
|
+
let qn = Api_Naming.queryFieldNamesForReadModel(~plugin=name, ~name=R.Spec.name)
|
|
260
|
+
let (labelField, _searchableFields) = Plugin_Structure.labelFieldsFromStateSchema(
|
|
261
|
+
~entityName=R.Spec.name,
|
|
262
|
+
R.Spec.stateSchema->S.castToUnknown,
|
|
263
|
+
)
|
|
264
|
+
let qn = {
|
|
265
|
+
...qn,
|
|
266
|
+
labelField,
|
|
267
|
+
connectionFilterTypeName: qn.returnTypeName ++ "Filter",
|
|
268
|
+
}
|
|
269
|
+
let qn = switch R.Spec.subIdConfig {
|
|
270
|
+
| Some(_) =>
|
|
271
|
+
{
|
|
272
|
+
...qn,
|
|
273
|
+
itemsFieldName: qn.singleFieldName ++ "Items",
|
|
274
|
+
itemsFilterTypeName: qn.returnTypeName ++ "ItemsFilter",
|
|
275
|
+
}
|
|
276
|
+
| None => qn
|
|
277
|
+
}
|
|
278
|
+
Plugin_Helpers.queryFieldNamesRegistry->Dict.set(R.Spec.name, qn)
|
|
279
|
+
Plugin_Helpers.stateSchemaRegistry->Dict.set(
|
|
280
|
+
R.Spec.name,
|
|
281
|
+
R.Spec.stateSchema->S.castToUnknown,
|
|
282
|
+
)
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
let apiSchemaFragment = {
|
|
286
|
+
let baseFragment = FragmentProvider.generateFragment(~mutationEntries, ~queryEntries)
|
|
287
|
+
let subResult = Plugin_SubscriptionSchema.generate(
|
|
288
|
+
~mutationEntries,
|
|
289
|
+
~eventLogEntries,
|
|
290
|
+
)
|
|
291
|
+
let parts = GraphQL_Stitcher.decode(baseFragment)
|
|
292
|
+
GraphQL_Stitcher.encode({
|
|
293
|
+
...parts,
|
|
294
|
+
types: Array.concat(parts.types, subResult.extraTypes),
|
|
295
|
+
subscriptions: subResult.subscriptionFields,
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Register type definitions via platform hook (e.g. GraphQL in-memory)
|
|
300
|
+
Spec.hooks.schemaTypeRegistrationHook->Option.forEach(registerTypes => {
|
|
301
|
+
let parts = GraphQL_Stitcher.decode(apiSchemaFragment)
|
|
302
|
+
registerTypes(parts.types)
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
// Register MCP tools and resources via platform hook (e.g. MCP in-memory)
|
|
306
|
+
Spec.hooks.mcpSchemaRegistrationHook->Option.forEach(registerMcp =>
|
|
307
|
+
registerMcp({
|
|
308
|
+
pluginName: name,
|
|
309
|
+
mutationEntries,
|
|
310
|
+
queryEntries,
|
|
311
|
+
eventLogEntries,
|
|
312
|
+
subscriptionFields: GraphQL_Stitcher.decode(apiSchemaFragment).subscriptions,
|
|
313
|
+
})
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
// Register DCB StateChangeSlice publish functions in publishToAggregates so that
|
|
317
|
+
// extensions whose Delegate is a DCB slice can dispatch commands to them.
|
|
318
|
+
// All slices in a plugin share the same DCB command topic (same publishJsons).
|
|
319
|
+
switch dcbResult.dcbPublishJsons {
|
|
320
|
+
| Some(slicePublishJsons) =>
|
|
321
|
+
stateChangeSlices->Array.forEach((module(Sc: StateChangeSlice.T)) =>
|
|
322
|
+
publishToAggregates->Dict.set(Sc.Spec.name, slicePublishJsons)
|
|
323
|
+
)
|
|
324
|
+
| None => ()
|
|
325
|
+
}
|
|
326
|
+
// Reuse the aggregateEventTopics dict computed before DcbBuilder.construct;
|
|
327
|
+
// merge in the DCB EventLog topic for ReadModels (already merged inside
|
|
328
|
+
// DcbBuilder for AutomationSlice subscription).
|
|
329
|
+
let allEventTopics = aggregateEventTopics
|
|
330
|
+
switch dcbResult.dcbEventLogOutputs {
|
|
331
|
+
| Some(dcbOutputs) => allEventTopics->Dict.set(name ++ "DcbEventLog", dcbOutputs.eventTopic)
|
|
332
|
+
| None => ()
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
let readModelsOutputs = readModels->createReadModels(~api, ~apiRole, allEventTopics, opts)
|
|
336
|
+
let allQueryDbs = readModelsOutputs->ReadModel.allQueryDbs
|
|
337
|
+
// Merge DCB StateViewSlice, InboundTranslation, AutomationSlice, and
|
|
338
|
+
// OutboundTranslation QueryDbs into allQueryDbs so createResolvers builds
|
|
339
|
+
// AppSync resolvers for them too.
|
|
340
|
+
//
|
|
341
|
+
// Key must match `name` passed to QueryDbResolvers_AppSync.make (the
|
|
342
|
+
// QueryDb's own queryDbName, used by storageResource lookups for ByIds
|
|
343
|
+
// and idResolver paths). Slice output dicts are keyed by Spec.name; the
|
|
344
|
+
// queryDb name appends a suffix per slice kind:
|
|
345
|
+
// StateViewSlice — no suffix
|
|
346
|
+
// AutomationSlice — "Todo"
|
|
347
|
+
// OutboundTranslationSlice — "Todo"
|
|
348
|
+
// InboundTranslationSlice — "Audit"
|
|
349
|
+
dcbResult.stateViewSlicesOutputs
|
|
350
|
+
->Dict.toArray
|
|
351
|
+
->Array.forEach(((k, v)) => allQueryDbs->Dict.set(k, v.queryDb))
|
|
352
|
+
dcbResult.inboundTranslationSlicesOutputs
|
|
353
|
+
->Dict.toArray
|
|
354
|
+
->Array.forEach(((k, v)) => allQueryDbs->Dict.set(k ++ "Audit", v.queryDb))
|
|
355
|
+
dcbResult.automationSlicesOutputs
|
|
356
|
+
->Dict.toArray
|
|
357
|
+
->Array.forEach(((k, v)) => allQueryDbs->Dict.set(k ++ "Todo", v.queryDb))
|
|
358
|
+
dcbResult.outboundTranslationSlicesOutputs
|
|
359
|
+
->Dict.toArray
|
|
360
|
+
->Array.forEach(((k, v)) => allQueryDbs->Dict.set(k ++ "Todo", v.queryDb))
|
|
361
|
+
let queryEngine = QueryEngineAdapter.make(allQueryDbs)
|
|
362
|
+
|
|
363
|
+
{
|
|
364
|
+
// Fire onPluginBuiltHook synchronously with a plain-data summary.
|
|
365
|
+
// ExtensionPoint/Extension names are not accessible from their T module type,
|
|
366
|
+
// so only aggregates, read models, and DCB slice names are included.
|
|
367
|
+
|
|
368
|
+
let extractTypes = schema => Reventless.DcbTag.extractAllVariantNames(schema)
|
|
369
|
+
// Build per-component schema data and register it for the deployed hook.
|
|
370
|
+
let aggregateComponents = aggregates->Array.map((
|
|
371
|
+
module(M: ReventlessInfra.Aggregate.T with type api = api),
|
|
372
|
+
) => {
|
|
373
|
+
let schema: Plugin_Helpers.pluginDeployedSchema = {
|
|
374
|
+
commandTypes: extractTypes(M.Spec.commandSchema),
|
|
375
|
+
eventTypes: extractTypes(M.Spec.eventSchema),
|
|
376
|
+
errorTypes: extractTypes(M.Spec.errorSchema),
|
|
377
|
+
commandSchemas: [
|
|
378
|
+
SchemaWalker.walk(M.Spec.name ++ ".command", M.Spec.commandSchema),
|
|
379
|
+
],
|
|
380
|
+
eventSchemas: [
|
|
381
|
+
SchemaWalker.walk(M.Spec.name ++ ".event", M.Spec.eventSchema),
|
|
382
|
+
],
|
|
383
|
+
}
|
|
384
|
+
Plugin_Helpers.componentSchemaRegistry->Dict.set(M.Spec.name, schema)
|
|
385
|
+
({name: M.Spec.name, kind: "Aggregate", schema}: Plugin_Helpers.pluginBuiltComponent)
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
let readModelComponents = readModels->Array.map((
|
|
389
|
+
module(R: ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
390
|
+
) => {
|
|
391
|
+
let qn = Api_Naming.queryFieldNamesForReadModel(~plugin=name, ~name=R.Spec.name)
|
|
392
|
+
let schema: Plugin_Helpers.pluginDeployedSchema = {
|
|
393
|
+
queryFields: [qn.singleFieldName, qn.listFieldName],
|
|
394
|
+
}
|
|
395
|
+
Plugin_Helpers.componentSchemaRegistry->Dict.set(R.Spec.name, schema)
|
|
396
|
+
({name: R.Spec.name, kind: "ReadModel", schema}: Plugin_Helpers.pluginBuiltComponent)
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
let mapNames = (d: dict<_>, kind: string) =>
|
|
400
|
+
d
|
|
401
|
+
->Dict.keysToArray
|
|
402
|
+
->Array.map(name => {
|
|
403
|
+
let schema: Plugin_Helpers.pluginDeployedSchema = {}
|
|
404
|
+
({Plugin_Helpers.name, kind, schema}: Plugin_Helpers.pluginBuiltComponent)
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
// Routing slices (automation / inbound + outbound translation) expose their
|
|
408
|
+
// command/event wiring and routing target on the hook surface, at parity
|
|
409
|
+
// with aggregates and read models — mirroring the metadata Plugin_Structure
|
|
410
|
+
// records on the static plugin def. Type strings stay unqualified to match
|
|
411
|
+
// the aggregate/read-model entries already on this same hook surface
|
|
412
|
+
// (Plugin_Structure additionally prefixes them with the plugin name).
|
|
413
|
+
let extractEventTypes = schema => Reventless.DcbTag.extractVariantNames(schema)
|
|
414
|
+
let routingSchemas: Dict.t<Plugin_Helpers.pluginDeployedSchema> = Dict.make()
|
|
415
|
+
automationSlices->Array.forEach((module(As: ReventlessInfra.AutomationSlice.T)) => {
|
|
416
|
+
// Union of source-event variants across every per-source mapping.
|
|
417
|
+
let consumedEventTypes =
|
|
418
|
+
As.Automation.mappings
|
|
419
|
+
->Array.flatMap((module(M: As.Automation.Mapping)) =>
|
|
420
|
+
extractEventTypes(M.sourceEventSchema->S.castToUnknown)
|
|
421
|
+
)
|
|
422
|
+
->Belt.Set.String.fromArray
|
|
423
|
+
->Belt.Set.String.toArray
|
|
424
|
+
routingSchemas->Dict.set(
|
|
425
|
+
As.Spec.name,
|
|
426
|
+
{
|
|
427
|
+
consumedEventTypes,
|
|
428
|
+
producedCommandTypes: extractTypes(As.Spec.commandSchema),
|
|
429
|
+
targetName: As.Spec.targetName,
|
|
430
|
+
},
|
|
431
|
+
)
|
|
432
|
+
})
|
|
433
|
+
outboundTranslationSlices->Array.forEach((
|
|
434
|
+
module(Ots: ReventlessInfra.OutboundTranslationSlice.T),
|
|
435
|
+
) =>
|
|
436
|
+
routingSchemas->Dict.set(
|
|
437
|
+
Ots.Spec.name,
|
|
438
|
+
{
|
|
439
|
+
consumedEventTypes: extractEventTypes(Ots.Spec.consumedEventSchema),
|
|
440
|
+
commandTypes: extractTypes(Ots.Spec.inboundCommandSchema),
|
|
441
|
+
// Outbound slices may have no target (option); pass it through.
|
|
442
|
+
targetName: ?Ots.Spec.targetName,
|
|
443
|
+
},
|
|
444
|
+
)
|
|
445
|
+
)
|
|
446
|
+
inboundTranslationSlices->Array.forEach((
|
|
447
|
+
module(Its: ReventlessInfra.InboundTranslationSlice.T),
|
|
448
|
+
) =>
|
|
449
|
+
routingSchemas->Dict.set(
|
|
450
|
+
Its.Spec.name,
|
|
451
|
+
{
|
|
452
|
+
commandTypes: extractTypes(Its.Spec.commandSchema),
|
|
453
|
+
targetName: Its.Spec.targetName,
|
|
454
|
+
},
|
|
455
|
+
)
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
// Component set still derives from the DCB outputs dict (unchanged
|
|
459
|
+
// membership); enrich + register the schema where a matching spec module
|
|
460
|
+
// was found above, so the deployed hook surfaces it too (the built-hook
|
|
461
|
+
// components carry it inline).
|
|
462
|
+
let routingComponents = (d: dict<_>, kind: string) =>
|
|
463
|
+
d
|
|
464
|
+
->Dict.keysToArray
|
|
465
|
+
->Array.map(name => {
|
|
466
|
+
let schema = routingSchemas->Dict.get(name)->Option.getOr({})
|
|
467
|
+
Plugin_Helpers.componentSchemaRegistry->Dict.set(name, schema)
|
|
468
|
+
({Plugin_Helpers.name, kind, schema}: Plugin_Helpers.pluginBuiltComponent)
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
let components = Array.flat([
|
|
472
|
+
aggregateComponents,
|
|
473
|
+
readModelComponents,
|
|
474
|
+
mapNames(dcbResult.stateChangeSlicesOutputs, "StateChangeSlice"),
|
|
475
|
+
mapNames(dcbResult.stateViewSlicesOutputs, "StateViewSlice"),
|
|
476
|
+
routingComponents(dcbResult.automationSlicesOutputs, "AutomationSlice"),
|
|
477
|
+
routingComponents(dcbResult.outboundTranslationSlicesOutputs, "OutboundTranslationSlice"),
|
|
478
|
+
routingComponents(dcbResult.inboundTranslationSlicesOutputs, "InboundTranslationSlice"),
|
|
479
|
+
])
|
|
480
|
+
|
|
481
|
+
switch Plugin_Helpers.onPluginBuiltHook.contents {
|
|
482
|
+
| Some(hook) =>
|
|
483
|
+
let meta = Plugin_Helpers.pluginMetadataRegistry.contents
|
|
484
|
+
hook({
|
|
485
|
+
name,
|
|
486
|
+
version,
|
|
487
|
+
kind: ?meta->Option.flatMap(m => m.kind),
|
|
488
|
+
displayName: ?meta->Option.flatMap(m => m.displayName),
|
|
489
|
+
vendor: ?meta->Option.flatMap(m => m.vendor),
|
|
490
|
+
architectureType: ?meta->Option.flatMap(m => m.architectureType),
|
|
491
|
+
components,
|
|
492
|
+
})
|
|
493
|
+
| None => ()
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
let builderOutputs = {
|
|
498
|
+
// Resolve admin extension point data — from Interstack (AWS cross-stack reference).
|
|
499
|
+
let interstackAdminExtensionPoints =
|
|
500
|
+
Interstack.coreStackReference->Option.mapOr(Pulumi.Output.make(None), coreStack =>
|
|
501
|
+
coreStack->Pulumi.StackReference.getOutput("extensionPoints")
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
// Derive local admin extension point resolved data (passed from makePlatform).
|
|
505
|
+
let localAdminResolvedEP =
|
|
506
|
+
Spec.hooks.adminExtensionPoints.contents->Pulumi.Output.flatMap(eps =>
|
|
507
|
+
switch eps->Dict.get(PluginExtensionPointSpec.name) {
|
|
508
|
+
| Some(ep) => ep->ExtensionPoint.toResolvedOutputs->Pulumi.Output.apply(r => Some(r))
|
|
509
|
+
| None => Pulumi.Output.make(None)
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
// Push schema fragment to the API before resolvers are created (AWS only).
|
|
514
|
+
// The returned Output chains into the dependency tuple so Pulumi waits
|
|
515
|
+
// for the schema update to complete before creating resolver resources.
|
|
516
|
+
let schemaPushed = switch Spec.hooks.preResolversSchemaHook {
|
|
517
|
+
| Some(pushSchema) => pushSchema(~name, ~version, apiSchemaFragment)
|
|
518
|
+
| None => Pulumi.Output.make()
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
(
|
|
522
|
+
(interstackAdminExtensionPoints, localAdminResolvedEP, schemaPushed)->Pulumi.Output.all3,
|
|
523
|
+
aggregateResources->Pulumi.Output.allDict,
|
|
524
|
+
publishToAggregates->Pulumi.Output.allDict,
|
|
525
|
+
publishToReadModels->Pulumi.Output.allDict,
|
|
526
|
+
scheduler,
|
|
527
|
+
queryEngine,
|
|
528
|
+
)
|
|
529
|
+
->Pulumi.Output.all6
|
|
530
|
+
->Pulumi.Output.apply(((
|
|
531
|
+
(interstackAdminExtensionPoints, localAdminResolvedEP, _),
|
|
532
|
+
aggregateResources,
|
|
533
|
+
publishToAggregates,
|
|
534
|
+
publishToReadModels,
|
|
535
|
+
scheduler,
|
|
536
|
+
queryEngine,
|
|
537
|
+
)) => {
|
|
538
|
+
let aggregatesOutputs = addEventMappers(allEventTopics, queryEngine)
|
|
539
|
+
|
|
540
|
+
let (extensionPointsOutputs, extensionPointsHandlers, extensionPointRegistryInfos) =
|
|
541
|
+
extensionPoints->createExtensionPoints(
|
|
542
|
+
~aggregateResources,
|
|
543
|
+
~publishToAggregates,
|
|
544
|
+
~scheduler,
|
|
545
|
+
~queryEngine,
|
|
546
|
+
~resourceNaming=Spec.resourceNaming,
|
|
547
|
+
~opts,
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
// Resolve admin connection — from Interstack (AWS), local admin (in-memory), or None
|
|
551
|
+
let coreSetup = switch interstackAdminExtensionPoints {
|
|
552
|
+
| Some(interstackAdminExtensionPoints) => {
|
|
553
|
+
let pluginExtensionPointUnwrapped: ReventlessInterop.ExtensionPoint.resolvedOutputs = (
|
|
554
|
+
interstackAdminExtensionPoints
|
|
555
|
+
->Pulumi.StackReference.get(PluginExtensionPointSpec.name)
|
|
556
|
+
->Obj.magic: JSON.t
|
|
557
|
+
)->S.parseOrThrow(ReventlessInterop.ExtensionPoint.resolvedOutputsSchema)
|
|
558
|
+
let pluginExtensionPointCommandTopicRemoteChannel = PluginExtensionPointRemoteChannel.make(
|
|
559
|
+
pluginExtensionPointUnwrapped.commandTopic.resources->Array.map(
|
|
560
|
+
Adapter.fromInteropResolved,
|
|
561
|
+
),
|
|
562
|
+
)
|
|
563
|
+
Some((pluginExtensionPointUnwrapped, pluginExtensionPointCommandTopicRemoteChannel))
|
|
564
|
+
}
|
|
565
|
+
| None =>
|
|
566
|
+
// Fallback: use local admin extension point data (e.g. in-memory platform)
|
|
567
|
+
switch localAdminResolvedEP {
|
|
568
|
+
| Some(resolvedEP) =>
|
|
569
|
+
let remoteChannel = PluginExtensionPointRemoteChannel.make(
|
|
570
|
+
resolvedEP.commandTopic.resources->Array.map(Adapter.fromInteropResolved),
|
|
571
|
+
)
|
|
572
|
+
Some((resolvedEP, remoteChannel))
|
|
573
|
+
| None => None
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
let publishToPluginExtensionPoint: ReventlessInfra.CommandTopic.publishJsons = switch coreSetup {
|
|
578
|
+
| Some((_, remoteChannel)) => remoteChannel.remotePublish
|
|
579
|
+
| None => async _ => ()
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
let (extensionsOutputs, extensionsHandlers, extensionRegistryInfos) =
|
|
583
|
+
extensions->createExtensions(
|
|
584
|
+
~pluginName=name,
|
|
585
|
+
~publishToPluginExtensionPoint,
|
|
586
|
+
~publishToAggregates,
|
|
587
|
+
~publishToReadModels,
|
|
588
|
+
~queryEngine,
|
|
589
|
+
~opts,
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
let extensionPointsDefinitions = extensionPointsOutputs->extractExtensionPointDefinitions
|
|
593
|
+
let extensionsDefinitions = extensionsOutputs->extractExtensionDefinitions
|
|
594
|
+
|
|
595
|
+
module Set = Belt.Set.String
|
|
596
|
+
|
|
597
|
+
let collectAggregateNames = ex =>
|
|
598
|
+
ex
|
|
599
|
+
->Set.fromArray
|
|
600
|
+
->Set.remove(ReventlessInfra.ExtensionMapping.NoDelegate.name)
|
|
601
|
+
|
|
602
|
+
let extensionPointAggregateNames =
|
|
603
|
+
extensionPointsOutputs
|
|
604
|
+
->Array.flatMap(ex => ex.aggregateNames)
|
|
605
|
+
->collectAggregateNames
|
|
606
|
+
|
|
607
|
+
let extensionAggregateNames =
|
|
608
|
+
extensionsOutputs
|
|
609
|
+
->Array.flatMap(ex => ex.aggregateNames)
|
|
610
|
+
->collectAggregateNames
|
|
611
|
+
|
|
612
|
+
let eventTopics =
|
|
613
|
+
aggregatesOutputs->Aggregate.filterEventTopics(
|
|
614
|
+
extensionPointAggregateNames->Set.union(extensionAggregateNames),
|
|
615
|
+
)
|
|
616
|
+
// Include DCB EventTopic so the EventCollector subscribes to DynamoDB Stream events
|
|
617
|
+
switch dcbResult.dcbEventLogOutputs {
|
|
618
|
+
| Some(dcbOutputs) => eventTopics->Dict.set(name ++ "DcbEventLog", dcbOutputs.eventTopic)
|
|
619
|
+
| None => ()
|
|
620
|
+
}
|
|
621
|
+
switch coreSetup {
|
|
622
|
+
| Some((pluginExtensionPointUnwrapped, _)) =>
|
|
623
|
+
eventTopics->Dict.set(
|
|
624
|
+
PluginExtensionPointSpec.name,
|
|
625
|
+
{
|
|
626
|
+
resources: pluginExtensionPointUnwrapped.eventTopic.resources->Array.map(
|
|
627
|
+
AdapterDeploytime.fromInteropResource,
|
|
628
|
+
),
|
|
629
|
+
},
|
|
630
|
+
)
|
|
631
|
+
| None => ()
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
let childName = name->ComponentType.name(Plugin.componentType)
|
|
635
|
+
|
|
636
|
+
module EventCollectorHelper = MakeEventCollectorHelper(
|
|
637
|
+
RuntimeEnvironment,
|
|
638
|
+
EventCollectorChannel,
|
|
639
|
+
PluginRuntimeBuilder,
|
|
640
|
+
)
|
|
641
|
+
let (eventCollector, eventCollectorOutputs, eventCollectorUrn) = EventCollectorHelper.make(
|
|
642
|
+
~name=childName,
|
|
643
|
+
~eventTopics,
|
|
644
|
+
~opts,
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
// Capture deployTarget synchronously before the Pulumi.Output.apply callback.
|
|
648
|
+
// deployPlugin resets hooks.deployTarget to "Domain" after P.make() returns,
|
|
649
|
+
// so reading it inside the async callback would always yield "Domain".
|
|
650
|
+
let capturedDeployTarget = Spec.hooks.deployTarget.contents
|
|
651
|
+
|
|
652
|
+
// DCB EventLog definition — Some when this plugin has a DcbEventLog
|
|
653
|
+
// component, None otherwise. Admin's manageSubscriptions reads this to
|
|
654
|
+
// provision cross-plugin SNS subscriptions from peer plugins' DCB
|
|
655
|
+
// topics → this plugin's EventCollector, and vice-versa. The eventTopic
|
|
656
|
+
// resource's `id` is the SNS topic ARN (same convention as
|
|
657
|
+
// extensionPointDefinition.eventTopic).
|
|
658
|
+
let dcbEventLogDef: Pulumi.Output.t<option<Reventless.Plugin.dcbEventLogDefinition>> =
|
|
659
|
+
switch dcbResult.dcbEventLogOutputs {
|
|
660
|
+
| None => Pulumi.Output.make(None)
|
|
661
|
+
| Some(dcbOutputs) =>
|
|
662
|
+
switch dcbOutputs.eventTopic.resources->Array.get(0) {
|
|
663
|
+
| Some(r) =>
|
|
664
|
+
r.id->Pulumi.Output.apply(arn => Some({
|
|
665
|
+
Reventless.Plugin.name: name ++ "DcbEventLog",
|
|
666
|
+
eventTopicArn: arn,
|
|
667
|
+
}))
|
|
668
|
+
| None => Pulumi.Output.make(None)
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let pluginDefinition =
|
|
673
|
+
(extensionPointsDefinitions, eventCollectorUrn, dcbEventLogDef)
|
|
674
|
+
->Pulumi.Output.all3
|
|
675
|
+
->Pulumi.Output.apply(((extensionPointsDefinitions, eventCollectorUrn, dcbEventLogDef)) => {
|
|
676
|
+
Reventless.Plugin.id,
|
|
677
|
+
name,
|
|
678
|
+
version,
|
|
679
|
+
extensionPoints: extensionPointsDefinitions,
|
|
680
|
+
extensions: extensionsDefinitions,
|
|
681
|
+
eventCollector: eventCollectorUrn,
|
|
682
|
+
extensionProtocols: [],
|
|
683
|
+
apiSchemaFragment: Some(apiSchemaFragment),
|
|
684
|
+
apiTarget: Some(capturedDeployTarget),
|
|
685
|
+
uiFragments,
|
|
686
|
+
structure: pluginStructure,
|
|
687
|
+
dcbEventLog: dcbEventLogDef,
|
|
688
|
+
})
|
|
689
|
+
|
|
690
|
+
// Bundled Plugin EventCollector reconstructs Extension_Operations at
|
|
691
|
+
// cold start from HANDLER_CONFIG, which needs concrete cmd-topic SQS
|
|
692
|
+
// URLs for every aggregate/slice a user extension may publish to.
|
|
693
|
+
let aggregateQueueUrls: dict<Pulumi.Output.t<string>> = Dict.make()
|
|
694
|
+
aggregateResources
|
|
695
|
+
->Dict.toArray
|
|
696
|
+
->Array.forEach(((aggName, resources)) =>
|
|
697
|
+
switch resources->Array.get(0) {
|
|
698
|
+
| Some(r) => aggregateQueueUrls->Dict.set(aggName, r.id)
|
|
699
|
+
| None => ()
|
|
700
|
+
}
|
|
701
|
+
)
|
|
702
|
+
// All DCB StateChangeSlices share the same dcb command topic — map
|
|
703
|
+
// every slice name to that single URL so PublishStateChangeSliceCommand
|
|
704
|
+
// routes correctly regardless of which slice the extension targets.
|
|
705
|
+
switch dcbResult.dcbCommandTopicQueueUrl {
|
|
706
|
+
| Some(url) =>
|
|
707
|
+
stateChangeSlices->Array.forEach((module(Sc: StateChangeSlice.T)) =>
|
|
708
|
+
aggregateQueueUrls->Dict.set(Sc.Spec.name, url)
|
|
709
|
+
)
|
|
710
|
+
| None => ()
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// Per-RM EventCollector SQS URL — populated only for plugins that
|
|
714
|
+
// expose RMs the bundled handler may enqueue events into directly.
|
|
715
|
+
let readModelQueueUrls: dict<Pulumi.Output.t<string>> = Dict.make()
|
|
716
|
+
readModelsOutputs
|
|
717
|
+
->Dict.toArray
|
|
718
|
+
->Array.forEach(((rmName, rmOut)) => {
|
|
719
|
+
let urlOutput =
|
|
720
|
+
rmOut.eventCollector->Pulumi.Output.flatMap(ecOutputs =>
|
|
721
|
+
switch ecOutputs.resources->Array.get(0) {
|
|
722
|
+
| Some(r) => r.id
|
|
723
|
+
| None => Pulumi.Output.make("")
|
|
724
|
+
}
|
|
725
|
+
)
|
|
726
|
+
readModelQueueUrls->Dict.set(rmName, urlOutput)
|
|
727
|
+
})
|
|
728
|
+
|
|
729
|
+
switch coreSetup {
|
|
730
|
+
| Some((pluginExtensionPointUnwrapped, _)) => {
|
|
731
|
+
let (
|
|
732
|
+
connectPluginExtensionOutputs,
|
|
733
|
+
connectPluginExtensionIncomingEventHandler,
|
|
734
|
+
) = createConnectPluginExtension(
|
|
735
|
+
~pluginDefinition,
|
|
736
|
+
~publishToPluginExtensionPoint,
|
|
737
|
+
~publishToAggregates,
|
|
738
|
+
~readModelNamesForSourceName,
|
|
739
|
+
~publishToReadModels,
|
|
740
|
+
~queryEngine,
|
|
741
|
+
~opts,
|
|
742
|
+
)
|
|
743
|
+
let _ = EventCollectorHelper.connect(
|
|
744
|
+
~eventCollector,
|
|
745
|
+
~eventTopics,
|
|
746
|
+
~extensionPointsOutputs,
|
|
747
|
+
~extensionsOutputs,
|
|
748
|
+
~pluginExtensionPointUnwrapped,
|
|
749
|
+
~pluginDefinition,
|
|
750
|
+
~connectPluginExtensionIncomingEventHandler,
|
|
751
|
+
~extensionsHandlers,
|
|
752
|
+
~extensionPointsHandlers,
|
|
753
|
+
~connectPluginExtensionOutputs,
|
|
754
|
+
~extensionRegistryInfos,
|
|
755
|
+
~extensionPointRegistryInfos,
|
|
756
|
+
~aggregateQueueUrls,
|
|
757
|
+
~readModelQueueUrls,
|
|
758
|
+
~readModelNamesForSourceName,
|
|
759
|
+
)
|
|
760
|
+
}
|
|
761
|
+
| None =>
|
|
762
|
+
// No admin connection — connect EventCollector without ConnectPluginExtension
|
|
763
|
+
let _ = EventCollectorHelper.connect(
|
|
764
|
+
~eventCollector,
|
|
765
|
+
~eventTopics,
|
|
766
|
+
~extensionPointsOutputs,
|
|
767
|
+
~extensionsOutputs,
|
|
768
|
+
~pluginDefinition,
|
|
769
|
+
~extensionsHandlers,
|
|
770
|
+
~extensionPointsHandlers,
|
|
771
|
+
~extensionRegistryInfos,
|
|
772
|
+
~aggregateQueueUrls,
|
|
773
|
+
~readModelQueueUrls,
|
|
774
|
+
~readModelNamesForSourceName,
|
|
775
|
+
)
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
let tasksOutputs = createTasks(
|
|
779
|
+
tasks,
|
|
780
|
+
~aggregatesOutputs,
|
|
781
|
+
~scheduler,
|
|
782
|
+
~schedulerRoleUrn,
|
|
783
|
+
~publishToAggregates,
|
|
784
|
+
~queryEngine,
|
|
785
|
+
~resourceNaming=Spec.resourceNaming,
|
|
786
|
+
~opts,
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
let resolvers = allQueryDbs->createResolvers
|
|
790
|
+
|
|
791
|
+
// Wire subscription infrastructure (StateTopic, EventLogSubscription) after resolvers.
|
|
792
|
+
// Gives the AWS platform access to allQueryDbs, allEventTopics, and eventLogEntries
|
|
793
|
+
// without coupling reventless-core to reventless-aws.
|
|
794
|
+
Spec.hooks.subscriptionInfraHook->Option.forEach(hook =>
|
|
795
|
+
hook({allQueryDbs, allEventTopics, eventLogEntries, opts})
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
module SpecificHeartbeat = Heartbeat_Builder.Make(HeartbeatRunner)
|
|
799
|
+
let heartbeat = SpecificHeartbeat.make(~name=childName, ~opts)
|
|
800
|
+
let handler = SpecificHeartbeat.makeHandler(
|
|
801
|
+
~id,
|
|
802
|
+
~timeout=heartbeatInterval,
|
|
803
|
+
~publishToPluginExtensionPoint,
|
|
804
|
+
)
|
|
805
|
+
switch coreSetup {
|
|
806
|
+
| Some((_, pluginExtensionPointCommandTopicRemoteChannel)) =>
|
|
807
|
+
// Notify platform hook that the EP channel is available (AWS extracts SQS URL for bundled heartbeat)
|
|
808
|
+
Spec.hooks.onHeartbeatEpChannelAvailable->Option.forEach(hook =>
|
|
809
|
+
hook(pluginExtensionPointCommandTopicRemoteChannel->Obj.magic, ~pluginId=id)
|
|
810
|
+
)
|
|
811
|
+
heartbeat->PluginRuntimeBuilder.forPluginHeartbeat(
|
|
812
|
+
~handler,
|
|
813
|
+
~connect=SpecificHeartbeat.connect(
|
|
814
|
+
heartbeat,
|
|
815
|
+
~remoteChannel=pluginExtensionPointCommandTopicRemoteChannel,
|
|
816
|
+
~timeout=heartbeatInterval,
|
|
817
|
+
...
|
|
818
|
+
),
|
|
819
|
+
)
|
|
820
|
+
| None =>
|
|
821
|
+
heartbeat->PluginRuntimeBuilder.forPluginHeartbeat(~handler, ~connect=(~runtime as _) =>
|
|
822
|
+
()
|
|
823
|
+
)
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// Connect DCB command topic to its Lambda runtime (if DCB is configured)
|
|
827
|
+
dcbResult.dcbRuntimeSetup->Option.forEach(dcbRuntimeSetup => dcbRuntimeSetup())
|
|
828
|
+
|
|
829
|
+
{
|
|
830
|
+
id,
|
|
831
|
+
version,
|
|
832
|
+
heartbeatInterval,
|
|
833
|
+
eventCollector: eventCollectorOutputs,
|
|
834
|
+
extensionPoints: extensionPointsOutputs->Array.map(el => (el.name, el))->Dict.fromArray,
|
|
835
|
+
extensions: extensionsOutputs->Array.map(el => (el.name, el))->Dict.fromArray,
|
|
836
|
+
aggregates: aggregatesOutputs,
|
|
837
|
+
stateChangeSlices: dcbResult.stateChangeSlicesOutputs,
|
|
838
|
+
stateViewSlices: dcbResult.stateViewSlicesOutputs,
|
|
839
|
+
automationSlices: dcbResult.automationSlicesOutputs,
|
|
840
|
+
outboundTranslationSlices: dcbResult.outboundTranslationSlicesOutputs,
|
|
841
|
+
inboundTranslationSlices: dcbResult.inboundTranslationSlicesOutputs,
|
|
842
|
+
readModels: readModelsOutputs,
|
|
843
|
+
tasks: tasksOutputs->Array.map(el => (el.name, el))->Dict.fromArray,
|
|
844
|
+
resolvers,
|
|
845
|
+
heartbeat: heartbeat->Component.outputs,
|
|
846
|
+
dcbEventLog: dcbResult.dcbEventLogOutputs,
|
|
847
|
+
uiFragments: (uiFragments: option<Reventless.Plugin.uiFragmentManifest>),
|
|
848
|
+
}
|
|
849
|
+
})
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
let pluginOutputs: Plugin.outputs = {
|
|
853
|
+
id: builderOutputs->Pulumi.Output.apply(outputs => outputs.id),
|
|
854
|
+
version: builderOutputs->Pulumi.Output.apply(outputs => outputs.version),
|
|
855
|
+
heartbeatInterval: builderOutputs->Pulumi.Output.apply(outputs => outputs.heartbeatInterval),
|
|
856
|
+
eventCollector: builderOutputs->Pulumi.Output.apply(outputs => outputs.eventCollector),
|
|
857
|
+
extensionPoints: builderOutputs->Pulumi.Output.apply(outputs => outputs.extensionPoints),
|
|
858
|
+
extensions: builderOutputs->Pulumi.Output.apply(outputs => outputs.extensions),
|
|
859
|
+
aggregates: builderOutputs->Pulumi.Output.apply(outputs => outputs.aggregates),
|
|
860
|
+
stateChangeSlices: builderOutputs->Pulumi.Output.apply(outputs => outputs.stateChangeSlices),
|
|
861
|
+
stateViewSlices: builderOutputs->Pulumi.Output.apply(outputs => outputs.stateViewSlices),
|
|
862
|
+
automationSlices: builderOutputs->Pulumi.Output.apply(outputs => outputs.automationSlices),
|
|
863
|
+
outboundTranslationSlices: builderOutputs->Pulumi.Output.apply(outputs =>
|
|
864
|
+
outputs.outboundTranslationSlices
|
|
865
|
+
),
|
|
866
|
+
inboundTranslationSlices: builderOutputs->Pulumi.Output.apply(outputs =>
|
|
867
|
+
outputs.inboundTranslationSlices
|
|
868
|
+
),
|
|
869
|
+
readModels: builderOutputs->Pulumi.Output.apply(outputs => outputs.readModels),
|
|
870
|
+
tasks: builderOutputs->Pulumi.Output.apply(outputs => outputs.tasks),
|
|
871
|
+
resolvers: builderOutputs->Pulumi.Output.apply(outputs => outputs.resolvers),
|
|
872
|
+
heartbeat: builderOutputs->Pulumi.Output.apply(outputs => outputs.heartbeat),
|
|
873
|
+
dcbEventLog: builderOutputs->Pulumi.Output.apply(outputs => outputs.dcbEventLog),
|
|
874
|
+
apiSchemaFragment: Pulumi.Output.make(Some(apiSchemaFragment)),
|
|
875
|
+
uiFragments: builderOutputs->Pulumi.Output.apply(outputs => outputs.uiFragments),
|
|
876
|
+
pluginStructure: Pulumi.Output.make(pluginStructure),
|
|
877
|
+
}
|
|
878
|
+
let _ = self->Component.setOutputs(pluginOutputs)
|
|
879
|
+
|
|
880
|
+
// Compute and store the _interopMeta stack export value. User entry-point
|
|
881
|
+
// code retrieves it via Plugin_Helpers.getInteropMeta() and exports it
|
|
882
|
+
// alongside "tasks", "plugin", and "eventMappers".
|
|
883
|
+
// Assign directly — do NOT wrap in Some(). Pulumi.Output.t is a JS Proxy;
|
|
884
|
+
// wrapping a Proxy in Caml_option.some() triggers the BS_PRIVATE sentinel bug.
|
|
885
|
+
interopMetaOutput :=
|
|
886
|
+
builderOutputs->Pulumi.Output.apply(outputs =>
|
|
887
|
+
outputs
|
|
888
|
+
->toInteropMeta
|
|
889
|
+
->S.reverseConvertToJsonOrThrow(ReventlessInterop.ExportMeta.schema)
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
Logger.currentPluginName := _prevPluginName
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
let makeAutoUIManifest = (
|
|
896
|
+
~remoteEntryUrl: string,
|
|
897
|
+
~name: string,
|
|
898
|
+
~pluginStructure: Reventless.Plugin.pluginStructure,
|
|
899
|
+
~readModelPositions: array<string>=[],
|
|
900
|
+
~aggregatePositions: array<string>=[],
|
|
901
|
+
): Reventless.Plugin.uiFragmentManifest => {
|
|
902
|
+
// Internal queryable components are hidden from the AutoUI manifest. They
|
|
903
|
+
// remain fully wired (resolvers, GraphQL schema, queryable defs,
|
|
904
|
+
// authorization) — visibility is a UX hint, not a security boundary. See
|
|
905
|
+
// docs/plans/done/component-visibility-annotations.md
|
|
906
|
+
let isVisibleQueryable = (q: Reventless.Plugin.queryableDef) =>
|
|
907
|
+
switch q.visibility {
|
|
908
|
+
| Some("Internal") => false
|
|
909
|
+
| _ => true
|
|
910
|
+
}
|
|
911
|
+
let visibleReadModels = pluginStructure.readModels->Array.filter(isVisibleQueryable)
|
|
912
|
+
let visibleStateViewSlices = pluginStructure.stateViewSlices->Array.filter(isVisibleQueryable)
|
|
913
|
+
let listPanel = (q: Reventless.Plugin.queryableDef): Reventless.Plugin.panelManifestEntry => {
|
|
914
|
+
fragmentId: name ++ "." ++ q.name ++ ".list",
|
|
915
|
+
title: q.name,
|
|
916
|
+
description: "",
|
|
917
|
+
positions: readModelPositions,
|
|
918
|
+
requiredAccess: None,
|
|
919
|
+
}
|
|
920
|
+
let detailPanel = (w: Reventless.Plugin.writableDef): Reventless.Plugin.panelManifestEntry => {
|
|
921
|
+
fragmentId: name ++ "." ++ w.name ++ ".detail",
|
|
922
|
+
title: w.name,
|
|
923
|
+
description: "",
|
|
924
|
+
positions: aggregatePositions,
|
|
925
|
+
requiredAccess: None,
|
|
926
|
+
}
|
|
927
|
+
let listPage = (q: Reventless.Plugin.queryableDef): Reventless.Plugin.pageManifestEntry => {
|
|
928
|
+
fragmentId: name ++ "." ++ q.name ++ ".list",
|
|
929
|
+
title: q.name,
|
|
930
|
+
menuEntry: {label: q.name, icon: None, group: None, sortOrder: 0},
|
|
931
|
+
requiredAccess: None,
|
|
932
|
+
}
|
|
933
|
+
let panels = Array.flat([
|
|
934
|
+
visibleReadModels->Array.map(listPanel),
|
|
935
|
+
visibleStateViewSlices->Array.map(listPanel),
|
|
936
|
+
pluginStructure.aggregates->Array.map(detailPanel),
|
|
937
|
+
pluginStructure.stateChangeSlices->Array.map(detailPanel),
|
|
938
|
+
])
|
|
939
|
+
let pages = Array.flat([
|
|
940
|
+
visibleReadModels->Array.map(listPage),
|
|
941
|
+
visibleStateViewSlices->Array.map(listPage),
|
|
942
|
+
])
|
|
943
|
+
{remoteEntryUrl, panels, pages}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
let makePluginDefinition = (
|
|
947
|
+
~name: string,
|
|
948
|
+
~aggregates: array<module(ReventlessInfra.Aggregate.T with type api = api)>=[],
|
|
949
|
+
~readModels: array<
|
|
950
|
+
module(ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
951
|
+
>=[],
|
|
952
|
+
~stateViewSlices: array<module(ReventlessInfra.StateViewSlice.T)>=[],
|
|
953
|
+
~stateChangeSlices: array<module(ReventlessInfra.StateChangeSlice.T)>=[],
|
|
954
|
+
~automationSlices: array<module(ReventlessInfra.AutomationSlice.T)>=[],
|
|
955
|
+
~outboundTranslationSlices: array<module(ReventlessInfra.OutboundTranslationSlice.T)>=[],
|
|
956
|
+
~inboundTranslationSlices: array<module(ReventlessInfra.InboundTranslationSlice.T)>=[],
|
|
957
|
+
~extensions: array<module(ReventlessInfra.Extension.Blueprint)>=[],
|
|
958
|
+
~extensionPoints: array<module(ReventlessInfra.ExtensionPointMapping.Mapping)>=[],
|
|
959
|
+
): Reventless.Plugin.pluginStructure =>
|
|
960
|
+
Plugin_Structure.make(
|
|
961
|
+
~name,
|
|
962
|
+
~aggregates,
|
|
963
|
+
~readModels,
|
|
964
|
+
~stateViewSlices,
|
|
965
|
+
~stateChangeSlices,
|
|
966
|
+
~automationSlices,
|
|
967
|
+
~outboundTranslationSlices,
|
|
968
|
+
~inboundTranslationSlices,
|
|
969
|
+
~extensions,
|
|
970
|
+
~extensionPoints,
|
|
971
|
+
)
|
|
972
|
+
|
|
973
|
+
let make = (
|
|
974
|
+
~name,
|
|
975
|
+
~heartbeatInterval,
|
|
976
|
+
~extensionPoints=[],
|
|
977
|
+
~extensions=[],
|
|
978
|
+
~aggregates: array<module(ReventlessInfra.Aggregate.T with type api = api)>=[],
|
|
979
|
+
~readModels: array<
|
|
980
|
+
module(ReventlessInfra.ReadModel.T with type api = api and type role = role),
|
|
981
|
+
>=[],
|
|
982
|
+
~tasks=[],
|
|
983
|
+
~stateChangeSlices=[],
|
|
984
|
+
~stateViewSlices=[],
|
|
985
|
+
~automationSlices=[],
|
|
986
|
+
~outboundTranslationSlices=[],
|
|
987
|
+
~inboundTranslationSlices=[],
|
|
988
|
+
~uiFragments: option<Reventless.Plugin.uiFragmentManifest>=?,
|
|
989
|
+
~pluginStructure: option<Reventless.Plugin.pluginStructure>=?,
|
|
990
|
+
~opts=?,
|
|
991
|
+
) => {
|
|
992
|
+
PluginRuntimeBuilder.registerPluginName(name)
|
|
993
|
+
let version = Reventless.PackageVersion.fromCaller()
|
|
994
|
+
Component.make(
|
|
995
|
+
~componentType=Plugin.componentType->ComponentType.toString,
|
|
996
|
+
~name,
|
|
997
|
+
~construct=construct(
|
|
998
|
+
~version,
|
|
999
|
+
~heartbeatInterval,
|
|
1000
|
+
~extensionPoints,
|
|
1001
|
+
~extensions,
|
|
1002
|
+
~aggregates,
|
|
1003
|
+
~readModels,
|
|
1004
|
+
~tasks,
|
|
1005
|
+
~stateChangeSlices,
|
|
1006
|
+
~stateViewSlices,
|
|
1007
|
+
~automationSlices,
|
|
1008
|
+
~outboundTranslationSlices,
|
|
1009
|
+
~inboundTranslationSlices,
|
|
1010
|
+
~uiFragments,
|
|
1011
|
+
~pluginStructure,
|
|
1012
|
+
...
|
|
1013
|
+
),
|
|
1014
|
+
~opts,
|
|
1015
|
+
)
|
|
1016
|
+
}
|
|
1017
|
+
}
|