@reventlessdev/reventless-aws 3.0.0-alpha.167

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 (394) hide show
  1. package/CHANGELOG.md +1564 -0
  2. package/README.md +62 -0
  3. package/__mocks__/emptyModule.js +1 -0
  4. package/all-licenses.csv +565 -0
  5. package/docker-compose.dynamodb-local.yml +12 -0
  6. package/jest.setup.cjs +5 -0
  7. package/licenses-analysis.ods +0 -0
  8. package/package.json +73 -0
  9. package/rescript.json +39 -0
  10. package/reventless-licenses-analysis.xls +0 -0
  11. package/scripts/run-integration-tests.sh +43 -0
  12. package/src/Platform.res +1940 -0
  13. package/src/Platform.res.mjs +2281 -0
  14. package/src/Platform_Casts.res +106 -0
  15. package/src/Platform_Casts.res.mjs +13 -0
  16. package/src/Platform_Stack.res +153 -0
  17. package/src/Platform_Stack.res.mjs +121 -0
  18. package/src/Types.res +39 -0
  19. package/src/Types.res.mjs +21 -0
  20. package/src/adapter/AWS.res +96 -0
  21. package/src/adapter/AWS.res.mjs +186 -0
  22. package/src/adapter/AWS_Tags.res +16 -0
  23. package/src/adapter/AWS_Tags.res.mjs +48 -0
  24. package/src/adapter/Adapter_Helpers.res +19 -0
  25. package/src/adapter/Adapter_Helpers.res.mjs +37 -0
  26. package/src/adapter/Api/AppSync_EventsApi.res +172 -0
  27. package/src/adapter/Api/AppSync_EventsApi.res.mjs +96 -0
  28. package/src/adapter/Api/AppSync_Resolver_Native.res +93 -0
  29. package/src/adapter/Api/AppSync_Resolver_Native.res.mjs +67 -0
  30. package/src/adapter/Api/AppSync_Resolver_Retrying.res +653 -0
  31. package/src/adapter/Api/AppSync_Resolver_Retrying.res.mjs +462 -0
  32. package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res +29 -0
  33. package/src/adapter/Api/CommandSubscriptionResolvers_AppSync.res.mjs +15 -0
  34. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +238 -0
  35. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +179 -0
  36. package/src/adapter/Api/Platform_UIFragments_Lambda.res +229 -0
  37. package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +245 -0
  38. package/src/adapter/Auth/Auth_Cognito.res +209 -0
  39. package/src/adapter/Auth/Auth_Cognito.res.mjs +135 -0
  40. package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res +2 -0
  41. package/src/adapter/CommandGenerator/CommandGeneratorResolvers.res.mjs +12 -0
  42. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +251 -0
  43. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs +126 -0
  44. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res +20 -0
  45. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_NoOp.res.mjs +23 -0
  46. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res +1 -0
  47. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync_Runtime.res.mjs +11 -0
  48. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +95 -0
  49. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs +50 -0
  50. package/src/adapter/CommandTopic/CommandTopicChannel.res +6 -0
  51. package/src/adapter/CommandTopic/CommandTopicChannel.res.mjs +21 -0
  52. package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res +196 -0
  53. package/src/adapter/CommandTopic/CommandTopicChannel_Helpers.res.mjs +145 -0
  54. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +91 -0
  55. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +74 -0
  56. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +69 -0
  57. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +62 -0
  58. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +60 -0
  59. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +56 -0
  60. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res +73 -0
  61. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs +65 -0
  62. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +88 -0
  63. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +76 -0
  64. package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res +1 -0
  65. package/src/adapter/CommandTopic/CommandTopicRemoteChannel.res.mjs +9 -0
  66. package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res +7 -0
  67. package/src/adapter/CommandTopic/CommandTopicRemoteChannel_SQS.res.mjs +17 -0
  68. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +103 -0
  69. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +68 -0
  70. package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res +107 -0
  71. package/src/adapter/Counter/CounterHandler_DynamoDbStream_Runtime.res.mjs +145 -0
  72. package/src/adapter/DcbEventLog/DcbEventLogStorage.res +1 -0
  73. package/src/adapter/DcbEventLog/DcbEventLogStorage.res.mjs +9 -0
  74. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +84 -0
  75. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res.mjs +52 -0
  76. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res +1436 -0
  77. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb_Runtime.res.mjs +1143 -0
  78. package/src/adapter/EventCollector/EventCollectorChannel.res +6 -0
  79. package/src/adapter/EventCollector/EventCollectorChannel.res.mjs +21 -0
  80. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +63 -0
  81. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +56 -0
  82. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res +20 -0
  83. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res.mjs +32 -0
  84. package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res +266 -0
  85. package/src/adapter/EventCollector/EventCollectorChannel_Helpers.res.mjs +166 -0
  86. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +81 -0
  87. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res.mjs +54 -0
  88. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +59 -0
  89. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res.mjs +45 -0
  90. package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res +91 -0
  91. package/src/adapter/EventCollector/EventCollectorChannel_SQS_Runtime.res.mjs +89 -0
  92. package/src/adapter/EventLog/EventLogStorage.res +3 -0
  93. package/src/adapter/EventLog/EventLogStorage.res.mjs +15 -0
  94. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res +25 -0
  95. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res.mjs +34 -0
  96. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +26 -0
  97. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs +35 -0
  98. package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res +121 -0
  99. package/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res.mjs +137 -0
  100. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +265 -0
  101. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +185 -0
  102. package/src/adapter/EventTopic/EventTopicPublisher.res +6 -0
  103. package/src/adapter/EventTopic/EventTopicPublisher.res.mjs +21 -0
  104. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +25 -0
  105. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs +28 -0
  106. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +40 -0
  107. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res.mjs +39 -0
  108. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +39 -0
  109. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res.mjs +38 -0
  110. package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res +5 -0
  111. package/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res.mjs +18 -0
  112. package/src/adapter/Mcp/MCP_Lambda.res +502 -0
  113. package/src/adapter/Mcp/MCP_Lambda.res.mjs +289 -0
  114. package/src/adapter/QueryDb/NodeResolver_AppSync.res +71 -0
  115. package/src/adapter/QueryDb/NodeResolver_AppSync.res.mjs +44 -0
  116. package/src/adapter/QueryDb/QueryDbResolvers.res +2 -0
  117. package/src/adapter/QueryDb/QueryDbResolvers.res.mjs +12 -0
  118. package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res +434 -0
  119. package/src/adapter/QueryDb/QueryDbResolvers_AppSync.res.mjs +243 -0
  120. package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res +21 -0
  121. package/src/adapter/QueryDb/QueryDbResolvers_AppSync_NoOp.res.mjs +14 -0
  122. package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res +21 -0
  123. package/src/adapter/QueryDb/QueryDbResolvers_NoOp.res.mjs +14 -0
  124. package/src/adapter/QueryDb/QueryDbStorage.res +5 -0
  125. package/src/adapter/QueryDb/QueryDbStorage.res.mjs +18 -0
  126. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +115 -0
  127. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res.mjs +100 -0
  128. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +52 -0
  129. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs +38 -0
  130. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res +271 -0
  131. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb_Runtime.res.mjs +306 -0
  132. package/src/adapter/QueryDb/QueryInterceptor_Lambda.res +20 -0
  133. package/src/adapter/QueryDb/QueryInterceptor_Lambda.res.mjs +22 -0
  134. package/src/adapter/QueryEngine/QueryEngine.res +3 -0
  135. package/src/adapter/QueryEngine/QueryEngine.res.mjs +12 -0
  136. package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +184 -0
  137. package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res.mjs +221 -0
  138. package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +879 -0
  139. package/src/adapter/Runtime/AggregateEntryPoint.mjs +313 -0
  140. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +327 -0
  141. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +239 -0
  142. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +331 -0
  143. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +240 -0
  144. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +247 -0
  145. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +185 -0
  146. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +244 -0
  147. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +185 -0
  148. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +347 -0
  149. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +244 -0
  150. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +285 -0
  151. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +212 -0
  152. package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +124 -0
  153. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +187 -0
  154. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +147 -0
  155. package/src/adapter/Runtime/CounterEntryPoint.mjs +91 -0
  156. package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +265 -0
  157. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +122 -0
  158. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +89 -0
  159. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +193 -0
  160. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +137 -0
  161. package/src/adapter/Runtime/EventMapperEntryPoint.mjs +97 -0
  162. package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +101 -0
  163. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +83 -0
  164. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +59 -0
  165. package/src/adapter/Runtime/HandlerFactoryHelpers.mjs +142 -0
  166. package/src/adapter/Runtime/HeartbeatEntryPoint.mjs +38 -0
  167. package/src/adapter/Runtime/PluginExtensionPointEntryPoint.mjs +137 -0
  168. package/src/adapter/Runtime/ReadModelEntryPoint.mjs +143 -0
  169. package/src/adapter/Runtime/RuntimeEnvironment.res +1 -0
  170. package/src/adapter/Runtime/RuntimeEnvironment.res.mjs +9 -0
  171. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +254 -0
  172. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +169 -0
  173. package/src/adapter/Runtime/SideEffectEntryPoint.mjs +81 -0
  174. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +178 -0
  175. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +129 -0
  176. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +166 -0
  177. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +87 -0
  178. package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +136 -0
  179. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +344 -0
  180. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +242 -0
  181. package/src/adapter/Runtime/TaskBucketEntryPoint.mjs +150 -0
  182. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +123 -0
  183. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +74 -0
  184. package/src/adapter/ScheduledPublisher/ScheduledPublisher.res +2 -0
  185. package/src/adapter/ScheduledPublisher/ScheduledPublisher.res.mjs +12 -0
  186. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +54 -0
  187. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +41 -0
  188. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res +97 -0
  189. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents_Runtime.res.mjs +85 -0
  190. package/src/adapter/StateTopic/StateTopic_AppSync.res +418 -0
  191. package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +295 -0
  192. package/src/adapter/Task/TaskBucket.res +1 -0
  193. package/src/adapter/Task/TaskBucket.res.mjs +9 -0
  194. package/src/adapter/Task/TaskBucket_S3.res +157 -0
  195. package/src/adapter/Task/TaskBucket_S3.res.mjs +108 -0
  196. package/src/adapter/Task/TaskBucket_S3_Runtime.res +11 -0
  197. package/src/adapter/Task/TaskBucket_S3_Runtime.res.mjs +15 -0
  198. package/src/components/Aggregate_Builder.res +1 -0
  199. package/src/components/Aggregate_Builder.res.mjs +25 -0
  200. package/src/components/Aggregate_Builder_Micro.res +63 -0
  201. package/src/components/Aggregate_Builder_Micro.res.mjs +80 -0
  202. package/src/components/Aggregate_Builder_NoResolver.res +61 -0
  203. package/src/components/Aggregate_Builder_NoResolver.res.mjs +80 -0
  204. package/src/components/Aggregate_Builder_PerAggregate.res +57 -0
  205. package/src/components/Aggregate_Builder_PerAggregate.res.mjs +80 -0
  206. package/src/components/Aggregate_Builder_Single.res +59 -0
  207. package/src/components/Aggregate_Builder_Single.res.mjs +80 -0
  208. package/src/components/Aggregate_Builder_Single_Async.res +59 -0
  209. package/src/components/Aggregate_Builder_Single_Async.res.mjs +80 -0
  210. package/src/components/Api/AppSync_Adapter.res +500 -0
  211. package/src/components/Api/AppSync_Adapter.res.mjs +396 -0
  212. package/src/components/AutomationSlice_Builder.res +52 -0
  213. package/src/components/AutomationSlice_Builder.res.mjs +72 -0
  214. package/src/components/AutomationSlice_Builder_Bundled.res.mjs +70 -0
  215. package/src/components/Counter_Builder.res +10 -0
  216. package/src/components/Counter_Builder.res.mjs +16 -0
  217. package/src/components/DataCleaner.res +170 -0
  218. package/src/components/DataCleaner.res.mjs +2 -0
  219. package/src/components/DcbEventLog_Builder.res +8 -0
  220. package/src/components/DcbEventLog_Builder.res.mjs +14 -0
  221. package/src/components/ExtensionPoint_Builder.res +16 -0
  222. package/src/components/ExtensionPoint_Builder.res.mjs +37 -0
  223. package/src/components/ForeignReadModel_Builder.res +19 -0
  224. package/src/components/ForeignReadModel_Builder.res.mjs +48 -0
  225. package/src/components/InboundTranslationSlice_Builder.res +25 -0
  226. package/src/components/InboundTranslationSlice_Builder.res.mjs +31 -0
  227. package/src/components/OutboundTranslationSlice_Builder.res +60 -0
  228. package/src/components/OutboundTranslationSlice_Builder.res.mjs +76 -0
  229. package/src/components/OutboundTranslationSlice_Builder_Bundled.res.mjs +75 -0
  230. package/src/components/Plugin.res +29 -0
  231. package/src/components/Plugin.res.mjs +63 -0
  232. package/src/components/ReadModel_Builder.res +1 -0
  233. package/src/components/ReadModel_Builder.res.mjs +19 -0
  234. package/src/components/ReadModel_Builder_NoResolver.res +55 -0
  235. package/src/components/ReadModel_Builder_NoResolver.res.mjs +64 -0
  236. package/src/components/ReadModel_Builder_NoResolver_Stream.res +60 -0
  237. package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +64 -0
  238. package/src/components/ReadModel_Builder_PerReadModel.res +53 -0
  239. package/src/components/ReadModel_Builder_PerReadModel.res.mjs +66 -0
  240. package/src/components/ReadModel_Builder_Single.res +52 -0
  241. package/src/components/ReadModel_Builder_Single.res.mjs +66 -0
  242. package/src/components/ReadModel_Builder_Single_Stream.res +60 -0
  243. package/src/components/ReadModel_Builder_Single_Stream.res.mjs +66 -0
  244. package/src/components/Scheduler.res +1 -0
  245. package/src/components/Scheduler.res.mjs +13 -0
  246. package/src/components/SideEffectHandler.res +1 -0
  247. package/src/components/SideEffectHandler.res.mjs +19 -0
  248. package/src/components/SideEffectHandler_PerSideEffectHandler.res +13 -0
  249. package/src/components/SideEffectHandler_PerSideEffectHandler.res.mjs +52 -0
  250. package/src/components/SideEffectHandler_Single.res +54 -0
  251. package/src/components/SideEffectHandler_Single.res.mjs +60 -0
  252. package/src/components/StateChangeSlice_Builder.res +17 -0
  253. package/src/components/StateChangeSlice_Builder.res.mjs +23 -0
  254. package/src/components/StateViewSlice_Builder.res +46 -0
  255. package/src/components/StateViewSlice_Builder.res.mjs +68 -0
  256. package/src/components/StateViewSlice_Builder_Bundled.res.mjs +69 -0
  257. package/src/components/StateViewSlice_Builder_Stream.res +50 -0
  258. package/src/components/StateViewSlice_Builder_Stream.res.mjs +68 -0
  259. package/src/components/Task_Builder.res +1 -0
  260. package/src/components/Task_Builder.res.mjs +28 -0
  261. package/src/components/Task_Builder_PerBucket.res +22 -0
  262. package/src/components/Task_Builder_PerBucket.res.mjs +63 -0
  263. package/src/components/Vpc.res +214 -0
  264. package/src/components/Vpc.res.mjs +117 -0
  265. package/src/components/Vpc.resi +22 -0
  266. package/src/errors/AppSync_Error.res +36 -0
  267. package/src/errors/AppSync_Error.res.mjs +38 -0
  268. package/src/errors/Cognito_Error.res +36 -0
  269. package/src/errors/Cognito_Error.res.mjs +38 -0
  270. package/src/errors/DynamoDb_Error.res +75 -0
  271. package/src/errors/DynamoDb_Error.res.mjs +86 -0
  272. package/src/errors/Kinesis_Error.res +36 -0
  273. package/src/errors/Kinesis_Error.res.mjs +38 -0
  274. package/src/errors/SNS_Error.res +34 -0
  275. package/src/errors/SNS_Error.res.mjs +38 -0
  276. package/src/errors/SQS_Error.res +40 -0
  277. package/src/errors/SQS_Error.res.mjs +41 -0
  278. package/src/plugin/cloner/ClonerRunner.res +1 -0
  279. package/src/plugin/cloner/ClonerRunner.res.mjs +9 -0
  280. package/src/plugin/cloner/ClonerRunner_Fargate.res +362 -0
  281. package/src/plugin/cloner/ClonerRunner_Fargate.res.mjs +246 -0
  282. package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res +42 -0
  283. package/src/plugin/cloner/ClonerRunner_Fargate_Runtime.res.mjs +45 -0
  284. package/src/plugin/heartbeat/HeartbeatRunner.res +1 -0
  285. package/src/plugin/heartbeat/HeartbeatRunner.res.mjs +9 -0
  286. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +96 -0
  287. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res.mjs +69 -0
  288. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +115 -0
  289. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +88 -0
  290. package/src/plugin/runtime/PluginRuntimeOperations.res +5 -0
  291. package/src/plugin/runtime/PluginRuntimeOperations.res.mjs +14 -0
  292. package/src/plugin/runtime/PluginRuntime_Builder.res +769 -0
  293. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +464 -0
  294. package/src/plugin/runtime/Util_PluginMessage_Runtime.res +13 -0
  295. package/src/plugin/runtime/Util_PluginMessage_Runtime.res.mjs +19 -0
  296. package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res +28 -0
  297. package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs +67 -0
  298. package/src/plugin/stack/Plugin_Stack.res +439 -0
  299. package/src/plugin/stack/Plugin_Stack.res.mjs +263 -0
  300. package/src/util/Util.res +29 -0
  301. package/src/util/Util.res.mjs +93 -0
  302. package/src/util/Util_AppSync.res +36 -0
  303. package/src/util/Util_AppSync.res.mjs +35 -0
  304. package/src/util/Util_AppSync_Caller.res +213 -0
  305. package/src/util/Util_AppSync_Caller.res.mjs +170 -0
  306. package/src/util/Util_Bundle.res +255 -0
  307. package/src/util/Util_Bundle.res.mjs +179 -0
  308. package/src/util/Util_Cloudwatch.res +14 -0
  309. package/src/util/Util_Cloudwatch.res.mjs +19 -0
  310. package/src/util/Util_CognitoGroupUser.res +39 -0
  311. package/src/util/Util_CognitoGroupUser.res.mjs +32 -0
  312. package/src/util/Util_CognitoGroupUser_Runtime.res +65 -0
  313. package/src/util/Util_CognitoGroupUser_Runtime.res.mjs +50 -0
  314. package/src/util/Util_Cognito_Runtime.res +52 -0
  315. package/src/util/Util_Cognito_Runtime.res.mjs +35 -0
  316. package/src/util/Util_DeadLetterQueue.res +154 -0
  317. package/src/util/Util_DeadLetterQueue.res.mjs +158 -0
  318. package/src/util/Util_DynamoDb.res +210 -0
  319. package/src/util/Util_DynamoDb.res.mjs +218 -0
  320. package/src/util/Util_DynamoDbStream.res +138 -0
  321. package/src/util/Util_DynamoDbStream.res.mjs +134 -0
  322. package/src/util/Util_DynamoDbStream_Runtime.res +94 -0
  323. package/src/util/Util_DynamoDbStream_Runtime.res.mjs +131 -0
  324. package/src/util/Util_DynamoDb_Runtime.res +216 -0
  325. package/src/util/Util_DynamoDb_Runtime.res.mjs +257 -0
  326. package/src/util/Util_DynamoDb_TableManager.res +23 -0
  327. package/src/util/Util_DynamoDb_TableManager.res.mjs +35 -0
  328. package/src/util/Util_DynamoDb_TableManager.resi +3 -0
  329. package/src/util/Util_Env.res +5 -0
  330. package/src/util/Util_Env.res.mjs +2 -0
  331. package/src/util/Util_EventSourceMapping.res +49 -0
  332. package/src/util/Util_EventSourceMapping.res.mjs +32 -0
  333. package/src/util/Util_HostUiDomain.res +28 -0
  334. package/src/util/Util_HostUiDomain.res.mjs +26 -0
  335. package/src/util/Util_IAM_Role.res +14 -0
  336. package/src/util/Util_IAM_Role.res.mjs +28 -0
  337. package/src/util/Util_Kinesis_Runtime.res +20 -0
  338. package/src/util/Util_Kinesis_Runtime.res.mjs +24 -0
  339. package/src/util/Util_Lambda.res +39 -0
  340. package/src/util/Util_Lambda.res.mjs +45 -0
  341. package/src/util/Util_LocalConfig.res +119 -0
  342. package/src/util/Util_LocalConfig.res.mjs +112 -0
  343. package/src/util/Util_ResourceNaming.res +15 -0
  344. package/src/util/Util_ResourceNaming.res.mjs +26 -0
  345. package/src/util/Util_S3.res +17 -0
  346. package/src/util/Util_S3.res.mjs +30 -0
  347. package/src/util/Util_S3_Runtime.res +11 -0
  348. package/src/util/Util_S3_Runtime.res.mjs +15 -0
  349. package/src/util/Util_SNS.res +33 -0
  350. package/src/util/Util_SNS.res.mjs +50 -0
  351. package/src/util/Util_SNS_FIFO.res +21 -0
  352. package/src/util/Util_SNS_FIFO.res.mjs +27 -0
  353. package/src/util/Util_SNS_Runtime.res +33 -0
  354. package/src/util/Util_SNS_Runtime.res.mjs +27 -0
  355. package/src/util/Util_SQS.res +70 -0
  356. package/src/util/Util_SQS.res.mjs +83 -0
  357. package/src/util/Util_SQS_FIFO.res +16 -0
  358. package/src/util/Util_SQS_FIFO.res.mjs +28 -0
  359. package/src/util/Util_SQS_Runtime.res +169 -0
  360. package/src/util/Util_SQS_Runtime.res.mjs +150 -0
  361. package/src/util/Util_SesPolicy_Runtime.res +54 -0
  362. package/src/util/Util_SesPolicy_Runtime.res.mjs +55 -0
  363. package/src/util/Util_StaticBundle.res +124 -0
  364. package/src/util/Util_StaticBundle.res.mjs +132 -0
  365. package/src/util/Util_Vpc.res +22 -0
  366. package/src/util/Util_Vpc.res.mjs +27 -0
  367. package/tests/AppSync_AdapterTest.res +396 -0
  368. package/tests/AppSync_AdapterTest.res.mjs +326 -0
  369. package/tests/AppSync_Resolver_RetryingTest.res +59 -0
  370. package/tests/AppSync_Resolver_RetryingTest.res.mjs +66 -0
  371. package/tests/Auth_CognitoTest.res +203 -0
  372. package/tests/Auth_CognitoTest.res.mjs +248 -0
  373. package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res +602 -0
  374. package/tests/DcbEventLogStorage_DynamoDb_RuntimeTest.res.mjs +742 -0
  375. package/tests/EventLogStorage_DynamoDb_RuntimeTest.res +57 -0
  376. package/tests/EventLogStorage_DynamoDb_RuntimeTest.res.mjs +68 -0
  377. package/tests/MCP_LambdaTest.res +101 -0
  378. package/tests/MCP_LambdaTest.res.mjs +56 -0
  379. package/tests/Util_HostUiDomainTest.res +90 -0
  380. package/tests/Util_HostUiDomainTest.res.mjs +50 -0
  381. package/tests/Util_SQS_RuntimeTest.res +46 -0
  382. package/tests/Util_SQS_RuntimeTest.res.mjs +45 -0
  383. package/tests/Util_StaticBundleTest.res +136 -0
  384. package/tests/Util_StaticBundleTest.res.mjs +149 -0
  385. package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res +101 -0
  386. package/tests/integration/DcbCommandTopicEntryPoint_IntegrationTest.res.mjs +91 -0
  387. package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res +315 -0
  388. package/tests/integration/DcbEventLogStorage_DynamoDb_IntegrationTest.res.mjs +435 -0
  389. package/tests/integration/DcbIntegrationHarness.res +102 -0
  390. package/tests/integration/DcbIntegrationHarness.res.mjs +163 -0
  391. package/tests/integration/EpTestSlice.res +28 -0
  392. package/tests/integration/EpTestSlice.res.mjs +43 -0
  393. package/tests/integration/EpTestSliceBehavior.res +18 -0
  394. package/tests/integration/EpTestSliceBehavior.res.mjs +35 -0
@@ -0,0 +1,313 @@
1
+ // Aggregate Lambda entry point.
2
+ // At cold start: reads HANDLER_CONFIG, dynamically imports Spec+Behavior modules,
3
+ // wires EventLog_Operations, Aggregate_Callback, CommandTopic_Callback.
4
+ // Handles both SQS CommandTopic events (Route 2) and AppSync direct invocation (Route 1).
5
+
6
+ import * as Effect from "effect/Effect";
7
+ import { patchSpecId, makeQueueRef, log, pluginName } from "./HandlerFactoryHelpers.mjs";
8
+ import { tag as requestContextTag } from "@reventlessdev/reventless-core/src/RequestContext.res.mjs";
9
+ import { Make as eventLogOperationsMake } from "@reventlessdev/reventless-core/src/components/EventLog/EventLog_Operations.res.mjs";
10
+ import { Make as aggregateCallbackMake } from "@reventlessdev/reventless-core/src/components/Aggregate/Aggregate_Callback.res.mjs";
11
+ import { Make as commandTopicCallbackMake } from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Callback.res.mjs";
12
+ import { makeGenerateCommand } from "@reventlessdev/reventless-core/src/components/CommandGenerator/CommandGenerator_Callback.res.mjs";
13
+ import { commandOutcomeToJson, runInlineAndCollect } from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Helpers.res.mjs";
14
+ import { append, replay, replayStream, appendStream } from "@reventlessdev/reventless-aws/src/adapter/EventLog/EventLogStorage_DynamoDb_Runtime.res.mjs";
15
+ import { handleQueueEvent, publishJsons as sqsPublishJsons } from "@reventlessdev/reventless-aws/src/adapter/CommandTopic/CommandTopicChannel_SQS_Runtime.res.mjs";
16
+ import { DynamoDBClient, ScanCommand } from "@aws-sdk/client-dynamodb";
17
+ import { unmarshall } from "@aws-sdk/util-dynamodb";
18
+
19
+ const dynamicImport = (specifier) => import('/var/task/node_modules/' + specifier);
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Plugin status gate — mirrors CommandGeneratorResolvers_GraphQL.checkPluginStatus.
23
+ // Rejects mutations on plugins whose Plugin RM `status` is not `Connected`,
24
+ // returning the split error codes from docs/analysis/plugin-lifecycle-tiers.md:
25
+ // Disconnected → PluginUnavailable (tier 1, retryable)
26
+ // Inactive → PluginInactive (tier 2, admin-controlled)
27
+ // Retired → PluginRetired (tier 2, admin-archived version)
28
+ // Platform_* admin mutations bypass the gate. Disabled silently if
29
+ // PLUGIN_RM_TABLE_NAME env var is not set.
30
+ // ---------------------------------------------------------------------------
31
+
32
+ const PLUGIN_RM_TABLE_NAME = process.env["PLUGIN_RM_TABLE_NAME"];
33
+ const PLUGIN_RM_CACHE_TTL_MS = parseInt(process.env["PLUGIN_RM_CACHE_TTL_MS"] || "5000", 10);
34
+ const ddbClient = PLUGIN_RM_TABLE_NAME ? new DynamoDBClient({}) : null;
35
+
36
+ let pluginStatusCache = null;
37
+ let pluginStatusCacheExpiresAt = 0;
38
+
39
+ async function loadPluginStatuses() {
40
+ const now = Date.now();
41
+ if (pluginStatusCache !== null && now < pluginStatusCacheExpiresAt) {
42
+ return pluginStatusCache;
43
+ }
44
+ const dict = {};
45
+ let exclusiveStartKey = undefined;
46
+ do {
47
+ const res = await ddbClient.send(new ScanCommand({
48
+ TableName: PLUGIN_RM_TABLE_NAME,
49
+ Limit: 1000,
50
+ ExclusiveStartKey: exclusiveStartKey,
51
+ }));
52
+ for (const raw of res.Items || []) {
53
+ try {
54
+ const item = unmarshall(raw);
55
+ if (typeof item.name === "string" && typeof item.status === "string") {
56
+ dict[item.name] = item.status;
57
+ }
58
+ } catch (_) {}
59
+ }
60
+ exclusiveStartKey = res.LastEvaluatedKey;
61
+ } while (exclusiveStartKey);
62
+ pluginStatusCache = dict;
63
+ pluginStatusCacheExpiresAt = now + PLUGIN_RM_CACHE_TTL_MS;
64
+ return dict;
65
+ }
66
+
67
+ function extractFieldName(event) {
68
+ // AppSync resolver template populates `event.meta.info` with
69
+ // `${parentTypeName}.${fieldName}` (see AppSync_Resolver_Functions.invokeCommandGenerator).
70
+ const info = event?.meta?.info;
71
+ if (typeof info !== "string") return null;
72
+ const dot = info.indexOf(".");
73
+ return dot >= 0 ? info.slice(dot + 1) : info;
74
+ }
75
+
76
+ function pluginRejection(msgId, errorCode, detail) {
77
+ return {
78
+ __typename: "CommandRejected",
79
+ msgId,
80
+ errorCode,
81
+ errorDetail: detail,
82
+ };
83
+ }
84
+
85
+ async function checkPluginStatus(event) {
86
+ if (ddbClient === null) return null;
87
+ const fieldName = extractFieldName(event);
88
+ if (fieldName === null) return null;
89
+ const underscore = fieldName.indexOf("_");
90
+ const pluginPrefix = underscore >= 0 ? fieldName.slice(0, underscore) : fieldName;
91
+ if (pluginPrefix === "Platform") return null;
92
+ let statuses;
93
+ try {
94
+ statuses = await loadPluginStatuses();
95
+ } catch (err) {
96
+ log.warn("checkPluginStatus: failed to load Plugin RM statuses", { comp: "AggregateEntryPoint", detail: err?.message ?? String(err) });
97
+ return null;
98
+ }
99
+ const status = statuses[pluginPrefix];
100
+ const msgId = "00000000-0000-0000-0000-000000000000";
101
+ const detailPrefix = `Mutation.${fieldName}`;
102
+ switch (status) {
103
+ case undefined:
104
+ case "Connected":
105
+ return null;
106
+ case "Disconnected":
107
+ return pluginRejection(msgId, "PluginUnavailable", `${detailPrefix}: plugin is disconnected`);
108
+ case "Inactive":
109
+ return pluginRejection(msgId, "PluginInactive", `${detailPrefix}: plugin is inactive`);
110
+ case "Retired":
111
+ return pluginRejection(msgId, "PluginRetired", `${detailPrefix}: plugin version has been retired`);
112
+ default:
113
+ return null;
114
+ }
115
+ }
116
+
117
+ // Build the per-aggregate parts shared by Route 1 (AppSync direct invoke) and
118
+ // Route 2 (SQS event source): the in-process command handler (used both as the
119
+ // inline dispatch target and as the SQS message handler) plus the resolved
120
+ // queue ref for the fire-and-forget async path.
121
+ function buildAggregateParts(specModule, behaviorModule, eventLogTableName, queueUrl) {
122
+ const patchedSpec = patchSpecId(specModule);
123
+ const resolvedTable = { name: eventLogTableName };
124
+ const rawStorageOps = {
125
+ append: append(resolvedTable),
126
+ replay: replay(resolvedTable),
127
+ replayStream: replayStream(resolvedTable),
128
+ appendStream: appendStream(resolvedTable),
129
+ };
130
+ const eventLogOps = eventLogOperationsMake(patchedSpec)({
131
+ Spec: patchedSpec,
132
+ EventTopic: { Spec: patchedSpec },
133
+ eventTopic: { publish: async () => {} },
134
+ storage: rawStorageOps,
135
+ });
136
+ const aggregateCallback = aggregateCallbackMake(patchedSpec)(behaviorModule)({
137
+ Spec: patchedSpec,
138
+ EventLog: { Spec: patchedSpec },
139
+ eventLog: eventLogOps,
140
+ });
141
+ const commandTopicCallback = commandTopicCallbackMake(patchedSpec)({
142
+ Spec: patchedSpec,
143
+ commandsHandler: aggregateCallback.handleCommands,
144
+ });
145
+ const resolvedQueue = makeQueueRef(queueUrl);
146
+ return {
147
+ patchedSpec,
148
+ handleJsonCommands: commandTopicCallback.handleJsonCommands,
149
+ sqsHandler: handleQueueEvent(resolvedQueue, commandTopicCallback.handleJsonCommands),
150
+ resolvedQueue,
151
+ };
152
+ }
153
+
154
+ function buildCommandGeneratorHandler(parts, dispatchMode) {
155
+ const { patchedSpec, handleJsonCommands, resolvedQueue } = parts;
156
+ const publishJsons = sqsPublishJsons(resolvedQueue, "SQS_FIFO");
157
+ // Sync (default): dispatch inline so the AppSync resolver gets a typed
158
+ // Accepted/Rejected outcome. Async: fire-and-forget to SQS, return Pending —
159
+ // the SQS event source (Route 2) processes the command later.
160
+ const publishJsonsAndWait = dispatchMode === "async"
161
+ ? undefined
162
+ : (jsons) => runInlineAndCollect(jsons, handleJsonCommands);
163
+ // Positional args after ReScript compiles labeled params:
164
+ // (publishJsons, publishJsonsAndWait, serviceName, commandSchema, componentKind, stripIdFromParams)
165
+ // The `undefined` for `stripIdFromParams` must be passed explicitly here —
166
+ // omitting it shifts everything left, sending the schema object through the
167
+ // serviceName slot (string-concat then throws "Cannot convert object to
168
+ // primitive value" once the log line tries to print "CommandGenerator(<schema>)").
169
+ const generateCommand = makeGenerateCommand(publishJsons, publishJsonsAndWait, patchedSpec.name, patchedSpec.commandSchema, "Aggregate", undefined);
170
+ return (event, _context) => {
171
+ // Add identity fallback: use payload.identity if present, otherwise construct from meta.user.
172
+ const identity = (event.identity != null && typeof event.identity === 'object')
173
+ ? event.identity
174
+ : {
175
+ userId: event.meta?.user ?? "anonymous",
176
+ username: event.meta?.user ?? "anonymous",
177
+ groups: [],
178
+ provider: { TAG: "Custom", _0: "aws" },
179
+ };
180
+ // CommandGenerator.meta declares ip as array<string> (X-Forwarded-For chain).
181
+ // The AppSync resolver template sends a single string (or null) from
182
+ // identity.sourceIp — normalize to array so generateCommand's
183
+ // `payload.meta.ip->Array.shift` doesn't crash on null/non-array values.
184
+ const rawIp = event.meta?.ip;
185
+ const ip = rawIp == null ? [] : Array.isArray(rawIp) ? rawIp : [rawIp];
186
+ const meta = { ...event.meta, ip };
187
+ return generateCommand({ ...event, meta, identity });
188
+ };
189
+ }
190
+
191
+ // Set at handler entry; read by runEffect to tag logs with the Lambda request id.
192
+ let _currentRequestId = "unknown";
193
+
194
+ function runEffect(correlationId, effect) {
195
+ let e = effect
196
+ // Promote correlationId/requestId/plugin to top-level JSON log fields —
197
+ // decoded by EffectLogger.install() from Effect log annotations. Harmless
198
+ // no-op if the unified logger isn't installed.
199
+ .pipe(Effect.annotateLogs("correlationId", correlationId || "unknown"))
200
+ .pipe(Effect.annotateLogs("requestId", _currentRequestId));
201
+ if (pluginName) e = e.pipe(Effect.annotateLogs("plugin", pluginName));
202
+ return e
203
+ .pipe(Effect.provideService(requestContextTag, { correlationId: correlationId || "unknown" }))
204
+ .pipe(Effect.runPromise);
205
+ }
206
+
207
+ function groupBySource(records) {
208
+ const dict = {};
209
+ records.forEach(record => {
210
+ const arn = record.eventSourceARN;
211
+ const existing = dict[arn] || [];
212
+ dict[arn] = existing.concat([record]);
213
+ });
214
+ return dict;
215
+ }
216
+
217
+ function extractCorrelationId(records) {
218
+ const first = records[0];
219
+ if (!first) return undefined;
220
+ const body = first.body;
221
+ if (body == null) return undefined;
222
+ try {
223
+ const parsed = JSON.parse(body);
224
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
225
+ const meta = parsed.meta;
226
+ if (meta && typeof meta === "object" && !Array.isArray(meta)) {
227
+ const cid = meta.correlationId;
228
+ if (typeof cid === "string") return cid;
229
+ }
230
+ }
231
+ } catch (_) {}
232
+ return undefined;
233
+ }
234
+
235
+ // DISPATCH_MODE controls whether AppSync direct-invoke commands are run inline
236
+ // (sync, default) or pushed to SQS for asynchronous processing (async).
237
+ // Aggregate_Builder_Single bundles this entry point with sync; the async
238
+ // variant (Aggregate_Builder_Single_Async) sets DISPATCH_MODE=async.
239
+ const DISPATCH_MODE = process.env["DISPATCH_MODE"] === "async" ? "async" : "sync";
240
+
241
+ async function buildAllHandlers() {
242
+ const configStr = process.env["HANDLER_CONFIG"] || '{"handlers":[]}';
243
+ const config = JSON.parse(configStr);
244
+ const cmdTopicHandlers = {};
245
+ const cmdGenHandlers = {};
246
+ await Promise.all(config.handlers.map(async h => {
247
+ const specModule = await dynamicImport(h.specModule);
248
+ const behaviorModule = await dynamicImport(h.behaviorModule);
249
+ const parts = buildAggregateParts(specModule, behaviorModule, h.eventLogTable, h.queueUrl);
250
+ cmdTopicHandlers[h.queueArn] = parts.sqsHandler;
251
+ cmdGenHandlers[specModule.name] = buildCommandGeneratorHandler(parts, DISPATCH_MODE);
252
+ }));
253
+ return [cmdTopicHandlers, cmdGenHandlers];
254
+ }
255
+
256
+ const initPromise = buildAllHandlers();
257
+
258
+ export async function handler(event, context) {
259
+ _currentRequestId = context?.awsRequestId || "unknown";
260
+ const [cmdTopicHandlers, cmdGenHandlers] = await initPromise;
261
+
262
+ // Route 1: AppSync direct invocation
263
+ if (event.command != null && event.arguments != null) {
264
+ // Plugin status gate (Part 2.3) — checked before dispatching to the
265
+ // per-aggregate handler so a deactivated plugin's mutations are rejected
266
+ // without touching the EventLog or CommandTopic.
267
+ const rejection = await checkPluginStatus(event);
268
+ if (rejection !== null) {
269
+ log.warn("plugin status gate rejected: " + rejection.errorCode, { comp: "CommandGenerator" });
270
+ return rejection;
271
+ }
272
+ const entries = Object.entries(cmdGenHandlers);
273
+ const len = entries.length;
274
+ let i = 0;
275
+ let result = null;
276
+ let found = false;
277
+ while (i < len && !found) {
278
+ const [name, cmdGenHandler] = entries[i];
279
+ try {
280
+ const r = await runEffect(undefined, cmdGenHandler(event, context));
281
+ log.debug("processed command via " + name, { comp: "CommandGenerator" });
282
+ result = r;
283
+ found = true;
284
+ } catch (e) {
285
+ log.debug("handler '" + name + "' threw, trying next", { comp: "CommandGenerator", detail: e && e.message ? e.message : String(e) });
286
+ i = i + 1;
287
+ }
288
+ }
289
+ if (!found) {
290
+ log.warn("no handler matched command", { comp: "CommandGenerator" });
291
+ return null;
292
+ }
293
+ // generateCommand returns a ReScript commandOutcome variant
294
+ // (Accepted/Rejected/Pending) compiled to a `{TAG, ...}` JS object. AppSync
295
+ // resolves the CommandResult union by `__typename` — convert to that shape.
296
+ return commandOutcomeToJson(result);
297
+ }
298
+
299
+ // Route 2: SQS CommandTopic events
300
+ const records = event.Records || [];
301
+ const correlationId = extractCorrelationId(records);
302
+ const grouped = groupBySource(records);
303
+ await Promise.all(Object.entries(grouped).map(async ([arn, subRecords]) => {
304
+ const cmdHandler = cmdTopicHandlers[arn];
305
+ if (cmdHandler !== undefined) {
306
+ log.debug("found handler for CommandTopic " + arn, { comp: "AggregateRuntime" });
307
+ await runEffect(correlationId, cmdHandler({ Records: subRecords }, context));
308
+ } else {
309
+ log.warn("no handler found: " + arn, { comp: "AggregateRuntime" });
310
+ }
311
+ }));
312
+ return "";
313
+ }
@@ -0,0 +1,327 @@
1
+ module CommandTopicChannel = CommandTopicChannel.SQS_Sync
2
+ module EventCollectorChannel = EventCollectorChannel.DynamoDbStream
3
+ module RuntimeEnvironment = RuntimeEnvironment.Lambda
4
+
5
+ let log = ReventlessCore.Logger.fromEnv()
6
+
7
+ type context = PulumiAws.Lambda.context
8
+ type runtimeParts = Util.Lambda.runtimeParts
9
+
10
+ type aggregateInfo = {
11
+ specModulePath: string,
12
+ behaviorModulePath: string,
13
+ eventLogTableName: Pulumi.Output.t<string>,
14
+ mappingsModulePath: option<string>,
15
+ }
16
+
17
+ let aggregateInfos: dict<aggregateInfo> = Dict.make()
18
+
19
+ let registerAggregate = (
20
+ ~aggregateName,
21
+ ~specModulePath,
22
+ ~behaviorModulePath,
23
+ ~eventLogTableName,
24
+ ~mappingsModulePath=?,
25
+ ) =>
26
+ aggregateInfos->Dict.set(
27
+ aggregateName,
28
+ {specModulePath, behaviorModulePath, eventLogTableName, mappingsModulePath},
29
+ )
30
+
31
+ type storedSpec = {
32
+ aggregateName: string,
33
+ aggregateResource: Pulumi.Resource.t,
34
+ queueUrl: Pulumi.Output.t<string>,
35
+ queueArn: Pulumi.Output.t<string>,
36
+ commandTopicConnects: array<ReventlessCore.Runtime.connect<runtimeParts>>,
37
+ commandGeneratorConnects: array<ReventlessCore.Runtime.connect<runtimeParts>>,
38
+ eventCollectorChannelSpec: option<
39
+ ReventlessCore.EventCollector_Adapter.channelSpec<
40
+ EventCollectorChannel.callbackEvent,
41
+ context,
42
+ EventCollectorChannel.channelParts,
43
+ >,
44
+ >,
45
+ commandTopicMemorySize: int,
46
+ commandTopicTimeout: int,
47
+ commandGeneratorMemorySize: int,
48
+ commandGeneratorTimeout: int,
49
+ eventCollectorMemorySize: int,
50
+ eventCollectorTimeout: int,
51
+ }
52
+
53
+ let storedSpecs: dict<storedSpec> = Dict.make()
54
+
55
+ let getStoredSpec = (aggregateName, aggregateResource) =>
56
+ storedSpecs
57
+ ->Dict.get(aggregateName)
58
+ ->Option.getOr({
59
+ aggregateName,
60
+ aggregateResource,
61
+ queueUrl: ""->Pulumi.Output.make,
62
+ queueArn: ""->Pulumi.Output.make,
63
+ commandTopicConnects: [],
64
+ commandGeneratorConnects: [],
65
+ eventCollectorChannelSpec: None,
66
+ commandTopicMemorySize: 0,
67
+ commandTopicTimeout: 0,
68
+ commandGeneratorMemorySize: 0,
69
+ commandGeneratorTimeout: 0,
70
+ eventCollectorMemorySize: 0,
71
+ eventCollectorTimeout: 0,
72
+ })
73
+
74
+ let forCommandGenerator: ReventlessCore.Runtime.forComponent<
75
+ ReventlessCore.CommandGenerator.effectEventHandler<context>,
76
+ runtimeParts,
77
+ ReventlessCore.CommandGenerator.component,
78
+ > = (
79
+ ~handler as _,
80
+ ~connect,
81
+ ~memorySize=1024,
82
+ ~timeout=30,
83
+ commandGenerator,
84
+ ) => {
85
+ let resource = commandGenerator->ReventlessCore.Component.toPulumiResource
86
+ switch resource.parent {
87
+ | Some(aggregateResource) =>
88
+ let aggregateName = aggregateResource.name->Option.getOr("Unnamed")
89
+ let spec = getStoredSpec(aggregateName, aggregateResource)
90
+ storedSpecs->Dict.set(aggregateName, {
91
+ ...spec,
92
+ commandGeneratorConnects: spec.commandGeneratorConnects->Array.concat([connect]),
93
+ commandGeneratorMemorySize: Math.Int.max(spec.commandGeneratorMemorySize, memorySize),
94
+ commandGeneratorTimeout: Math.Int.max(spec.commandGeneratorTimeout, timeout),
95
+ })
96
+ | None => ()
97
+ }
98
+ }
99
+
100
+ let forCommandTopic: ReventlessCore.Runtime.forComponent<
101
+ ReventlessCore.Runtime.effectHandler<
102
+ CommandTopicChannel.callbackEvent,
103
+ context,
104
+ unit,
105
+ string,
106
+ >,
107
+ runtimeParts,
108
+ ReventlessCore.CommandTopic.component<'op>,
109
+ > = (
110
+ ~handler as _,
111
+ ~connect,
112
+ ~memorySize=1024,
113
+ ~timeout=30,
114
+ commandTopic,
115
+ ) => {
116
+ let commandTopicResource = commandTopic->ReventlessCore.Component.toPulumiResource
117
+ switch commandTopicResource.parent {
118
+ | Some(aggregateResource) =>
119
+ let aggregateName = aggregateResource.name->Option.getOr("Unnamed")
120
+ let channel = commandTopic->ReventlessCore.CommandTopic_Adapter.channel
121
+ let channelParts: Util.SQS.channelParts = Obj.magic(channel.parts)
122
+ let queue = channelParts.queue
123
+
124
+ let spec = getStoredSpec(aggregateName, aggregateResource)
125
+ storedSpecs->Dict.set(aggregateName, {
126
+ ...spec,
127
+ queueUrl: queue.id,
128
+ queueArn: queue.arn,
129
+ commandTopicConnects: spec.commandTopicConnects->Array.concat([connect]),
130
+ commandTopicMemorySize: Math.Int.max(spec.commandTopicMemorySize, memorySize),
131
+ commandTopicTimeout: Math.Int.max(spec.commandTopicTimeout, timeout),
132
+ })
133
+ | None =>
134
+ let name = commandTopicResource.name->Option.getOr("Unnamed")
135
+ JsError.throwWithMessage(
136
+ `forCommandTopic(micro): commandTopic ${name} has no Aggregate parent`,
137
+ )
138
+ }
139
+ }
140
+
141
+ let forEventCollector: ReventlessCore.Runtime.forEventCollector<
142
+ ReventlessCore.Runtime.effectHandler<
143
+ EventCollectorChannel.callbackEvent,
144
+ context,
145
+ unit,
146
+ string,
147
+ >,
148
+ ReventlessCore.EventCollector.component,
149
+ > = (
150
+ ~handler as _,
151
+ ~eventTopics,
152
+ ~resources,
153
+ ~memorySize=2048,
154
+ ~timeout=180,
155
+ eventCollector,
156
+ ) => {
157
+ let eventCollectorResource = eventCollector->ReventlessCore.Component.toPulumiResource
158
+ let channel = eventCollector->ReventlessCore.EventCollector_Adapter.channel
159
+ switch eventCollectorResource.parent->Option.flatMap(parent => parent.parent) {
160
+ | Some(aggregateResource) =>
161
+ let aggregateName = aggregateResource.name->Option.getOr("Unnamed")
162
+ let spec = getStoredSpec(aggregateName, aggregateResource)
163
+ storedSpecs->Dict.set(aggregateName, {
164
+ ...spec,
165
+ eventCollectorChannelSpec: Some({channel, eventTopics, resources}),
166
+ eventCollectorMemorySize: Math.Int.max(spec.eventCollectorMemorySize, memorySize),
167
+ eventCollectorTimeout: Math.Int.max(spec.eventCollectorTimeout, timeout),
168
+ })
169
+ | None =>
170
+ let name = eventCollectorResource.name->Option.getOr("Unnamed")
171
+ JsError.throwWithMessage(
172
+ `forEventCollector(micro): eventCollector ${name} has no Aggregate parent`,
173
+ )
174
+ }
175
+ }
176
+
177
+ let finished = ref(false)
178
+
179
+ let finish = () =>
180
+ if !finished.contents {
181
+ let specs = storedSpecs->Dict.valuesToArray
182
+ if specs->Array.length > 0 {
183
+ specs->Array.forEach(spec => {
184
+ switch aggregateInfos->Dict.get(spec.aggregateName) {
185
+ | Some(info) =>
186
+ let aggregateOpts = {
187
+ Pulumi.ComponentResource.parent: spec.aggregateResource,
188
+ }
189
+ let baseName =
190
+ spec.aggregateName->ReventlessCore.ComponentType.name(
191
+ ReventlessCore.Aggregate.componentType,
192
+ )
193
+
194
+ // Collect user packages (shared by CmdTopic and CmdGen)
195
+ let packageDirs: dict<string> = Dict.make()
196
+ let specPkg = Util_Bundle.extractPackageName(info.specModulePath)
197
+ let behaviorPkg = Util_Bundle.extractPackageName(info.behaviorModulePath)
198
+ packageDirs->Dict.set(specPkg, Util_Bundle.resolvePackageRoot(specPkg))
199
+ packageDirs->Dict.set(behaviorPkg, Util_Bundle.resolvePackageRoot(behaviorPkg))
200
+
201
+ let specModule =
202
+ info.specModulePath->JSON.stringifyAny->Option.getOr(`""`)
203
+ let behaviorModule =
204
+ info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
205
+
206
+ // --- CommandTopic Lambda ---
207
+ let cmdTopicHandlerConfigOutput =
208
+ Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
209
+ ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
210
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
211
+ )
212
+
213
+ let cmdTopicEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
214
+ cmdTopicEnvVars->Dict.set("HANDLER_CONFIG", cmdTopicHandlerConfigOutput->Pulumi.Output.asInput)
215
+
216
+ let {code: cmdTopicCode, sourceCodeHash: cmdTopicSourceCodeHash} = Util_Bundle.buildCodeArchive(
217
+ ~entryPointModule="@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs",
218
+ ~packageDirs,
219
+ )
220
+
221
+ let cmdTopicName = baseName ++ "CmdHandler"
222
+ let cmdTopicRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
223
+ ~name=cmdTopicName,
224
+ ~code=cmdTopicCode,
225
+ ~sourceCodeHash=cmdTopicSourceCodeHash,
226
+ ~envVars=cmdTopicEnvVars,
227
+ ~memorySize=Math.Int.max(spec.commandTopicMemorySize, 1024),
228
+ ~timeout=Math.Int.max(spec.commandTopicTimeout, 30),
229
+ ~opts=aggregateOpts,
230
+ )
231
+
232
+ spec.commandTopicConnects->Array.forEach(connect => connect(~runtime=cmdTopicRuntime))
233
+
234
+ // --- CommandGenerator Lambda ---
235
+ if spec.commandGeneratorConnects->Array.length > 0 {
236
+ let cmdGenHandlerConfigOutput =
237
+ Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
238
+ ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
239
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
240
+ )
241
+
242
+ let cmdGenEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
243
+ cmdGenEnvVars->Dict.set("HANDLER_CONFIG", cmdGenHandlerConfigOutput->Pulumi.Output.asInput)
244
+
245
+ let {code: cmdGenCode, sourceCodeHash: cmdGenSourceCodeHash} = Util_Bundle.buildCodeArchive(
246
+ ~entryPointModule="@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs",
247
+ ~packageDirs,
248
+ )
249
+
250
+ let cmdGenName = baseName ++ "CmdGen"
251
+ let cmdGenRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
252
+ ~name=cmdGenName,
253
+ ~code=cmdGenCode,
254
+ ~sourceCodeHash=cmdGenSourceCodeHash,
255
+ ~envVars=cmdGenEnvVars,
256
+ ~memorySize=Math.Int.max(spec.commandGeneratorMemorySize, 1024),
257
+ ~timeout=Math.Int.max(spec.commandGeneratorTimeout, 30),
258
+ ~opts=aggregateOpts,
259
+ )
260
+
261
+ spec.commandGeneratorConnects->Array.forEach(connect =>
262
+ connect(~runtime=cmdGenRuntime)
263
+ )
264
+ }
265
+
266
+ // --- EventMapper Lambda ---
267
+ switch (spec.eventCollectorChannelSpec, info.mappingsModulePath) {
268
+ | (Some(channelSpec), Some(mappingsModulePath)) =>
269
+ let evtMapperEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
270
+
271
+ let targetSpecModule =
272
+ info.specModulePath->JSON.stringifyAny->Option.getOr(`""`)
273
+ let mappingsModuleJson =
274
+ mappingsModulePath->JSON.stringifyAny->Option.getOr(`""`)
275
+
276
+ let handlerConfigJson =
277
+ spec.queueUrl
278
+ ->Pulumi.Output.apply(queueUrl =>
279
+ `{"targetSpecModule":${targetSpecModule},"mappingsModule":${mappingsModuleJson},"queueUrl":"${queueUrl}"}`
280
+ )
281
+ evtMapperEnvVars->Dict.set("HANDLER_CONFIG", handlerConfigJson->Pulumi.Output.asInput)
282
+
283
+ let evtMapperPackageDirs: dict<string> = Dict.make()
284
+ let specPkg = Util_Bundle.extractPackageName(info.specModulePath)
285
+ let mappingsPkg = Util_Bundle.extractPackageName(mappingsModulePath)
286
+ evtMapperPackageDirs->Dict.set(specPkg, Util_Bundle.resolvePackageRoot(specPkg))
287
+ evtMapperPackageDirs->Dict.set(mappingsPkg, Util_Bundle.resolvePackageRoot(mappingsPkg))
288
+
289
+ let {code: evtMapperCode, sourceCodeHash: evtMapperSourceCodeHash} = Util_Bundle.buildCodeArchive(
290
+ ~entryPointModule="@reventlessdev/reventless-aws/src/adapter/Runtime/EventMapperEntryPoint.mjs",
291
+ ~packageDirs=evtMapperPackageDirs,
292
+ )
293
+
294
+ let evtMapperName = baseName ++ "EventMapper"
295
+ let evtMapperRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
296
+ ~name=evtMapperName,
297
+ ~code=evtMapperCode,
298
+ ~sourceCodeHash=evtMapperSourceCodeHash,
299
+ ~envVars=evtMapperEnvVars,
300
+ ~memorySize=Math.Int.max(spec.eventCollectorMemorySize, 2048),
301
+ ~timeout=Math.Int.max(spec.eventCollectorTimeout, 180),
302
+ ~opts=aggregateOpts,
303
+ )
304
+
305
+ let _connectResources = EventCollectorChannel.connect(
306
+ ~name=evtMapperName,
307
+ ~channelSpecs=[channelSpec],
308
+ ~runtime=evtMapperRuntime,
309
+ ~opts=aggregateOpts,
310
+ )
311
+ | (Some(_), None) =>
312
+ log.warn(
313
+ ~comp="AggregateRuntime_Builder_Micro",
314
+ `eventCollector registered for ${spec.aggregateName} but no mappingsModulePath — skipping EventMapper Lambda`,
315
+ )
316
+ | _ => ()
317
+ }
318
+ | None =>
319
+ log.warn(
320
+ ~comp="AggregateRuntime_Builder_Micro",
321
+ `no handler registered for ${spec.aggregateName}`,
322
+ )
323
+ }
324
+ })
325
+ }
326
+ finished := true
327
+ }