@reventlessdev/reventless-aws 3.0.0-alpha.220 → 3.0.0-alpha.221

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 (160) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +8 -8
  3. package/src/Platform.res.mjs +4 -0
  4. package/src/Platform_Stack.res +6 -0
  5. package/src/Platform_Stack.res.mjs +3 -1
  6. package/src/adapter/AWS_Tags.res +127 -12
  7. package/src/adapter/AWS_Tags.res.mjs +58 -17
  8. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +13 -1
  9. package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +3 -4
  10. package/src/adapter/Api/Platform_UIFragments_Lambda.res +13 -1
  11. package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +3 -4
  12. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res +12 -0
  13. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_AppSync.res.mjs +4 -2
  14. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res +6 -0
  15. package/src/adapter/CommandGenerator/InboundTranslationResolvers_AppSync.res.mjs +2 -1
  16. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res +2 -2
  17. package/src/adapter/CommandTopic/CommandTopicChannel_SQS.res.mjs +2 -2
  18. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res +2 -2
  19. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Async.res.mjs +2 -2
  20. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res +2 -2
  21. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_FIFO.res.mjs +2 -2
  22. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res +2 -2
  23. package/src/adapter/CommandTopic/CommandTopicChannel_SQS_Sync.res.mjs +2 -2
  24. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res +1 -0
  25. package/src/adapter/Counter/CounterHandler_DynamoDbStream.res.mjs +1 -1
  26. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res +1 -1
  27. package/src/adapter/DcbEventLog/DcbEventLogStorage_DynamoDb.res.mjs +1 -2
  28. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +1 -1
  29. package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +1 -1
  30. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res +2 -2
  31. package/src/adapter/EventCollector/EventCollectorChannel_SQS.res.mjs +2 -2
  32. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res +2 -2
  33. package/src/adapter/EventCollector/EventCollectorChannel_SQS_FIFO.res.mjs +2 -2
  34. package/src/adapter/EventLog/EventLogStorage.res +3 -3
  35. package/src/adapter/EventLog/EventLogStorage.res.mjs +3 -3
  36. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res +2 -2
  37. package/src/adapter/EventLog/EventLogStorage_DynamoDb.res.mjs +2 -2
  38. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res +2 -2
  39. package/src/adapter/EventLog/EventLogStorage_DynamoDbStream.res.mjs +2 -2
  40. package/src/adapter/EventLog/EventLogStorage_Postgres.res +1 -1
  41. package/src/adapter/EventLog/EventLogStorage_Postgres.res.mjs +1 -1
  42. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +7 -1
  43. package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +2 -2
  44. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res +1 -1
  45. package/src/adapter/EventTopic/EventTopicPublisher_DynamoDbStream.res.mjs +1 -1
  46. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res +2 -2
  47. package/src/adapter/EventTopic/EventTopicPublisher_SNS.res.mjs +2 -2
  48. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res +2 -2
  49. package/src/adapter/EventTopic/EventTopicPublisher_SNS_FIFO.res.mjs +2 -2
  50. package/src/adapter/Mcp/MCP_Lambda.res.mjs +1 -1
  51. package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +7 -0
  52. package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs +4 -2
  53. package/src/adapter/Postgres/PgMigration_Builder.res +1 -0
  54. package/src/adapter/Postgres/PgMigration_Builder.res.mjs +1 -1
  55. package/src/adapter/QueryDb/PgQueryResolver_Builder.res +7 -0
  56. package/src/adapter/QueryDb/PgQueryResolver_Builder.res.mjs +4 -2
  57. package/src/adapter/QueryDb/QueryDbStorage.res +6 -6
  58. package/src/adapter/QueryDb/QueryDbStorage.res.mjs +6 -6
  59. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res +2 -2
  60. package/src/adapter/QueryDb/QueryDbStorage_DynamoDb.res.mjs +2 -2
  61. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res +2 -2
  62. package/src/adapter/QueryDb/QueryDbStorage_DynamoDbStream.res.mjs +2 -2
  63. package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +1 -1
  64. package/src/adapter/QueryDb/QueryDbStorage_Postgres.res.mjs +1 -1
  65. package/src/adapter/Runtime/AdminEventCollectorEntryPoint.mjs +24 -41
  66. package/src/adapter/Runtime/AggregateEntryPoint.mjs +52 -45
  67. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res +19 -2
  68. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro.res.mjs +8 -5
  69. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res +19 -2
  70. package/src/adapter/Runtime/AggregateRuntime_Builder_Micro_Async.res.mjs +8 -5
  71. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res +9 -1
  72. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate.res.mjs +4 -2
  73. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res +9 -1
  74. package/src/adapter/Runtime/AggregateRuntime_Builder_PerAggregate_Async.res.mjs +4 -2
  75. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +9 -1
  76. package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +4 -2
  77. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +9 -1
  78. package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +4 -2
  79. package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +36 -22
  80. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +1 -0
  81. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +1 -1
  82. package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +39 -42
  83. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res +7 -1
  84. package/src/adapter/Runtime/EventCollectorRuntime_Builder_PerEventCollector.res.mjs +4 -2
  85. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +19 -1
  86. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +5 -2
  87. package/src/adapter/Runtime/EventMapperEntryPoint.mjs +25 -23
  88. package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +25 -41
  89. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res +1 -0
  90. package/src/adapter/Runtime/ExtensionPointRuntime_Builder_PerExtensionPoint.res.mjs +1 -1
  91. package/src/adapter/Runtime/HandlerFactoryHelpers.mjs +126 -0
  92. package/src/adapter/Runtime/PluginExtensionPointEntryPoint.mjs +24 -41
  93. package/src/adapter/Runtime/ReadModelEntryPoint.mjs +33 -24
  94. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +52 -2
  95. package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +25 -7
  96. package/src/adapter/Runtime/SideEffectEntryPoint.mjs +25 -24
  97. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res +9 -1
  98. package/src/adapter/Runtime/SideEffectHandlerRuntime_Builder_Single.res.mjs +4 -2
  99. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +1 -0
  100. package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +1 -1
  101. package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +26 -21
  102. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +2 -1
  103. package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +2 -2
  104. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res +1 -0
  105. package/src/adapter/Runtime/TaskRuntime_Builder_PerBucket.res.mjs +1 -1
  106. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res +12 -0
  107. package/src/adapter/ScheduledPublisher/ScheduledPublisher_CloudWatchEvents.res.mjs +4 -2
  108. package/src/adapter/StateTopic/StateTopic_AppSync.res +7 -1
  109. package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +2 -2
  110. package/src/adapter/Task/TaskBucket_S3.res +1 -0
  111. package/src/adapter/Task/TaskBucket_S3.res.mjs +7 -1
  112. package/src/components/Aggregate_Builder_Micro.res.mjs +2 -0
  113. package/src/components/Aggregate_Builder_NoResolver.res.mjs +2 -0
  114. package/src/components/Aggregate_Builder_PerAggregate.res.mjs +2 -0
  115. package/src/components/Aggregate_Builder_Single.res.mjs +2 -0
  116. package/src/components/Aggregate_Builder_Single_Async.res.mjs +2 -0
  117. package/src/components/Api/AppSync_Adapter.res +12 -0
  118. package/src/components/Api/AppSync_Adapter.res.mjs +6 -2
  119. package/src/components/Api/AppSync_MergedApi.res +12 -0
  120. package/src/components/Api/AppSync_MergedApi.res.mjs +5 -2
  121. package/src/components/AutomationSlice_Builder.res.mjs +2 -0
  122. package/src/components/ExtensionPoint_Builder.res.mjs +2 -0
  123. package/src/components/ForeignReadModel_Builder.res.mjs +4 -0
  124. package/src/components/OutboundTranslationSlice_Builder.res.mjs +2 -0
  125. package/src/components/Plugin.res.mjs +2 -0
  126. package/src/components/ReadModel_Builder_NoResolver.res.mjs +2 -0
  127. package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +2 -0
  128. package/src/components/ReadModel_Builder_PerReadModel.res.mjs +2 -0
  129. package/src/components/ReadModel_Builder_Single.res.mjs +2 -0
  130. package/src/components/ReadModel_Builder_Single_Stream.res.mjs +2 -0
  131. package/src/components/SideEffectHandler_PerSideEffectHandler.res.mjs +6 -0
  132. package/src/components/SideEffectHandler_Single.res.mjs +4 -0
  133. package/src/components/StateViewSlice_Builder.res.mjs +2 -0
  134. package/src/components/StateViewSlice_Builder_Stream.res.mjs +2 -0
  135. package/src/components/Task_Builder_PerBucket.res.mjs +4 -0
  136. package/src/components/Vpc.res +10 -1
  137. package/src/components/Vpc.res.mjs +3 -1
  138. package/src/plugin/cloner/ClonerRunner_Fargate.res +26 -1
  139. package/src/plugin/cloner/ClonerRunner_Fargate.res.mjs +9 -6
  140. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res +6 -0
  141. package/src/plugin/heartbeat/HeartbeatRunner_CloudWatchEvents.res.mjs +4 -1
  142. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res +1 -0
  143. package/src/plugin/runtime/PluginExtensionPointRuntime_Builder.res.mjs +1 -1
  144. package/src/plugin/runtime/PluginRuntime_Builder.res +2 -0
  145. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +2 -2
  146. package/src/plugin/stack/Plugin_ExtensionPoint_Builder.res.mjs +4 -0
  147. package/src/plugin/stack/Plugin_Stack.res +26 -1
  148. package/src/plugin/stack/Plugin_Stack.res.mjs +8 -3
  149. package/src/util/Util_CognitoGroupUser.res +6 -0
  150. package/src/util/Util_CognitoGroupUser.res.mjs +3 -1
  151. package/src/util/Util_DeadLetterQueue.res +8 -2
  152. package/src/util/Util_DeadLetterQueue.res.mjs +3 -4
  153. package/src/util/Util_LogAttribution.res +31 -0
  154. package/src/util/Util_LogAttribution.res.mjs +27 -0
  155. package/tests/AWS_TagsTest.res +236 -0
  156. package/tests/AWS_TagsTest.res.mjs +153 -0
  157. package/tests/HandlerFactoryDispatchTest.res +190 -0
  158. package/tests/HandlerFactoryDispatchTest.res.mjs +135 -0
  159. package/tests/integration/AggregateEntryPoint_IntegrationTest.res +5 -3
  160. package/tests/integration/AggregateEntryPoint_IntegrationTest.res.mjs +5 -3
@@ -14,10 +14,10 @@ let make: ReventlessCore.QueryDb_Adapter.storageMaker<api, role> = (
14
14
  ~ttl=?,
15
15
  ~api,
16
16
  ~apiRole,
17
- ~opts,
17
+ ~owner, ~opts,
18
18
  ) => {
19
19
  streamRegistry->Set.add(name)
20
- let tags = AWS.Tags.make(~name, ReventlessCore.QueryDb.componentType)
20
+ let tags = AWS.Tags.make(~name, ~kind=ReventlessCore.QueryDb.componentType, ~role=QueryDb, ~owner?)
21
21
  let table = Util_DynamoDbStream.makeTable(
22
22
  name,
23
23
  ~attributes=attributes(subIdField, indexes),
@@ -9,9 +9,9 @@ import * as QueryDbStorage_DynamoDb_Runtime$ReventlessAws from "./QueryDbStorage
9
9
 
10
10
  let streamRegistry = new Set();
11
11
 
12
- function make(name, indexes, subIdField, ttl, api, apiRole, opts) {
12
+ function make(name, indexes, subIdField, ttl, api, apiRole, owner, opts) {
13
13
  streamRegistry.add(name);
14
- let tags = AWS_Tags$ReventlessAws.make(name, QueryDb$ReventlessCore.componentType);
14
+ let tags = AWS_Tags$ReventlessAws.make(name, QueryDb$ReventlessCore.componentType, "QueryDb", undefined, undefined, owner, undefined, undefined);
15
15
  let table = Util_DynamoDbStream$ReventlessAws.makeTable(QueryDbStorage_DynamoDb$ReventlessAws.attributes(subIdField, indexes), QueryDbStorage_DynamoDb$ReventlessAws.globalSecondaryIndexes(indexes), ttl, subIdField, "NEW_AND_OLD_IMAGES", tags, opts, name);
16
16
  return {
17
17
  resources: [
@@ -24,7 +24,7 @@ let make: ReventlessCore.QueryDb_Adapter.storageMaker<api, role> = (
24
24
  ~ttl as _=?,
25
25
  ~api as _,
26
26
  ~apiRole as _,
27
- ~opts as _,
27
+ ~owner as _, ~opts as _,
28
28
  ) => {
29
29
  let operations = switch QueryDbBackend.get() {
30
30
  | Some({connectionConfig}) =>
@@ -5,7 +5,7 @@ import * as QueryDbBackend$ReventlessAws from "./QueryDbBackend.res.mjs";
5
5
  import * as PgQueryResolver_Builder$ReventlessAws from "./PgQueryResolver_Builder.res.mjs";
6
6
  import * as QueryDbStorage_Postgres_Runtime$ReventlessAws from "./QueryDbStorage_Postgres_Runtime.res.mjs";
7
7
 
8
- function make(name, indexes, subIdField, param, param$1, param$2, param$3) {
8
+ function make(name, indexes, subIdField, param, param$1, param$2, param$3, param$4) {
9
9
  let match = QueryDbBackend$ReventlessAws.get();
10
10
  let operations = match !== undefined ? match.connectionConfig.apply(config => QueryDbStorage_Postgres_Runtime$ReventlessAws.opsFor(config, name, indexes, subIdField)) : Stdlib_JsError.throwWithMessage("QueryDbStorage_Postgres.make called without a QueryDbBackend selection");
11
11
  return {
@@ -65,8 +65,17 @@
65
65
  import { readFileSync } from "node:fs";
66
66
  import { createRequire } from "node:module";
67
67
  import { pathToFileURL } from "node:url";
68
- import * as Effect from "effect/Effect";
69
- import { patchSpecId, makeQueueRef, scanByTableName, log, pluginName } from "./HandlerFactoryHelpers.mjs";
68
+ import {
69
+ patchSpecId,
70
+ makeQueueRef,
71
+ scanByTableName,
72
+ log,
73
+ runEffect,
74
+ setRequestId,
75
+ extractMetaField,
76
+ extractSentTimestamp,
77
+ extractRetryCount,
78
+ } from "./HandlerFactoryHelpers.mjs";
70
79
  import { subscribeQueueToTopic, unsubscribeQueueFromTopic } from "@reventlessdev/rescript-aws-sdk/src/SNS_Helpers.res.mjs";
71
80
  import { sendMessage } from "@reventlessdev/reventless-aws/src/plugin/runtime/Util_PluginMessage_Runtime.res.mjs";
72
81
  import { publish as snsPublish } from "@reventlessdev/reventless-aws/src/adapter/EventTopic/EventTopicPublisher_SNS_Runtime.res.mjs";
@@ -81,7 +90,6 @@ import { createSchedule as cwCreateSchedule, deleteSchedule as cwDeleteSchedule
81
90
  import {
82
91
  decode as decodeFragment,
83
92
  } from "@reventlessdev/reventless-core/src/components/Api/GraphQL_Stitcher.res.mjs";
84
- import { tag as requestContextTag } from "@reventlessdev/reventless-core/src/RequestContext.res.mjs";
85
93
 
86
94
  // The Plugin RM state schema uses `@s.matches(_jsNullable …)` for many
87
95
  // optional fields — top-level AND nested. DDB writes drop undefined
@@ -173,39 +181,6 @@ function parseHandlerConfig(rawJson) {
173
181
  return config;
174
182
  }
175
183
 
176
- // Set at handler entry; read by runEffect to tag logs with the Lambda request id.
177
- let _currentRequestId = "unknown";
178
-
179
- function runEffect(correlationId, effect) {
180
- let e = effect
181
- // Promote correlationId/requestId/plugin to top-level JSON log fields —
182
- // decoded by EffectLogger.install() from Effect log annotations. Harmless
183
- // no-op if the unified logger isn't installed.
184
- .pipe(Effect.annotateLogs("correlationId", correlationId || "unknown"))
185
- .pipe(Effect.annotateLogs("requestId", _currentRequestId));
186
- if (pluginName) e = e.pipe(Effect.annotateLogs("plugin", pluginName));
187
- return e
188
- .pipe(Effect.provideService(requestContextTag, { correlationId: correlationId || "unknown" }))
189
- .pipe(Effect.runPromise);
190
- }
191
-
192
- function extractCorrelationId(records) {
193
- const first = records && records[0];
194
- if (!first) return undefined;
195
- const body = first.body;
196
- if (!body) return undefined;
197
- try {
198
- const parsed = JSON.parse(body);
199
- if (parsed && typeof parsed === "object") {
200
- const meta = parsed.meta;
201
- if (meta && typeof meta === "object" && typeof meta.correlationId === "string") {
202
- return meta.correlationId;
203
- }
204
- }
205
- } catch (_) {}
206
- return undefined;
207
- }
208
-
209
184
  const invalidNameChars = /[^.\-_a-zA-Z0-9]/g;
210
185
  const resourceNaming = {
211
186
  validateName: (n) => n.replace(invalidNameChars, "_"),
@@ -714,17 +689,25 @@ async function buildHandler() {
714
689
  await reconcileSubscriptionsOnce(config.pluginReadModelTableName, manageSubscriptionsFn);
715
690
 
716
691
  const sqsHandler = handleDynamoDbOrSqsEvent(makeQueueRef(config.queueUrl), callback.handleJsonEvents);
717
- return { sqsHandler };
692
+ // This module backs both the admin and every per-plugin EventCollector
693
+ // Lambda, so the comp names the plugin whose events it drains — matching the
694
+ // `Plugin(<id>)` shape Plugin_Callback logs under.
695
+ return { sqsHandler, comp: `Plugin(${pluginDefinition.id})` };
718
696
  }
719
697
 
720
698
  const handlerBundlePromise = buildHandler();
721
699
 
722
700
  export async function handler(event, context) {
723
- _currentRequestId = context?.awsRequestId || "unknown";
701
+ setRequestId(context?.awsRequestId);
724
702
  const records = event.Records || [];
725
- const correlationId = extractCorrelationId(records);
726
703
  log.debug("processing " + records.length.toString() + " record(s)", { comp: "PluginEventCollectorRuntime" });
727
- const { sqsHandler } = await handlerBundlePromise;
728
- await runEffect(correlationId, sqsHandler(event, context));
704
+ const { sqsHandler, comp } = await handlerBundlePromise;
705
+ await runEffect(sqsHandler(event, context), {
706
+ correlationId: extractMetaField(records, "correlationId"),
707
+ causationId: extractMetaField(records, "causationId"),
708
+ comp,
709
+ timestamp: extractSentTimestamp(records),
710
+ retryCount: extractRetryCount(records),
711
+ });
729
712
  return "";
730
713
  }
@@ -3,9 +3,16 @@
3
3
  // wires EventLog_Operations, Aggregate_Callback, CommandTopic_Callback.
4
4
  // Handles both SQS CommandTopic events (Route 2) and AppSync direct invocation (Route 1).
5
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";
6
+ import {
7
+ patchSpecId,
8
+ makeQueueRef,
9
+ log,
10
+ runEffect,
11
+ setRequestId,
12
+ extractMetaField,
13
+ extractSentTimestamp,
14
+ extractRetryCount,
15
+ } from "./HandlerFactoryHelpers.mjs";
9
16
  import { Make as eventLogOperationsMake } from "@reventlessdev/reventless-core/src/components/EventLog/EventLog_Operations.res.mjs";
10
17
  import { Make as aggregateCallbackMake } from "@reventlessdev/reventless-core/src/components/Aggregate/Aggregate_Callback.res.mjs";
11
18
  import { Make as commandTopicCallbackMake } from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic_Callback.res.mjs";
@@ -192,21 +199,12 @@ function buildCommandGeneratorHandler(parts, dispatchMode) {
192
199
  };
193
200
  }
194
201
 
195
- // Set at handler entry; read by runEffect to tag logs with the Lambda request id.
196
- let _currentRequestId = "unknown";
197
-
198
- function runEffect(correlationId, effect) {
199
- let e = effect
200
- // Promote correlationId/requestId/plugin to top-level JSON log fields —
201
- // decoded by EffectLogger.install() from Effect log annotations. Harmless
202
- // no-op if the unified logger isn't installed.
203
- .pipe(Effect.annotateLogs("correlationId", correlationId || "unknown"))
204
- .pipe(Effect.annotateLogs("requestId", _currentRequestId));
205
- if (pluginName) e = e.pipe(Effect.annotateLogs("plugin", pluginName));
206
- return e
207
- .pipe(Effect.provideService(requestContextTag, { correlationId: correlationId || "unknown" }))
208
- .pipe(Effect.runPromise);
209
- }
202
+ // The dispatch `comp`, matching the ReScript boundary's
203
+ // `AggregateRuntime(<aggregateName>)` (AggregateRuntime_Builder_Common). Derived
204
+ // in-shell rather than baked into HANDLER_CONFIG because the aggregate name is
205
+ // already in hand here — unlike the event-collector resource name the read-model
206
+ // entry point has to be handed.
207
+ const aggregateComp = (aggregateName) => `AggregateRuntime(${aggregateName})`;
210
208
 
211
209
  function groupBySource(records) {
212
210
  const dict = {};
@@ -218,24 +216,6 @@ function groupBySource(records) {
218
216
  return dict;
219
217
  }
220
218
 
221
- function extractCorrelationId(records) {
222
- const first = records[0];
223
- if (!first) return undefined;
224
- const body = first.body;
225
- if (body == null) return undefined;
226
- try {
227
- const parsed = JSON.parse(body);
228
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
229
- const meta = parsed.meta;
230
- if (meta && typeof meta === "object" && !Array.isArray(meta)) {
231
- const cid = meta.correlationId;
232
- if (typeof cid === "string") return cid;
233
- }
234
- }
235
- } catch (_) {}
236
- return undefined;
237
- }
238
-
239
219
  // DISPATCH_MODE controls whether AppSync direct-invoke commands are run inline
240
220
  // (sync, default) or pushed to SQS for asynchronous processing (async).
241
221
  // Aggregate_Builder_Single bundles this entry point with sync; the async
@@ -257,8 +237,20 @@ export async function buildHandlersForConfig(config, opts = {}) {
257
237
  const specModule = await loadModule(h.specModule);
258
238
  const behaviorModule = await loadModule(h.behaviorModule);
259
239
  const parts = buildAggregateParts(specModule, behaviorModule, h.eventLogTable, h.queueUrl, h.pgConnection);
260
- cmdTopicHandlers[h.queueArn] = parts.sqsHandler;
261
- cmdGenHandlers[specModule.name] = buildCommandGeneratorHandler(parts, dispatchMode);
240
+ // Pair each handler with the comp of the aggregate it belongs to: this
241
+ // Lambda can host every aggregate in the platform, so the comp is what keeps
242
+ // their log lines separable.
243
+ const comp = aggregateComp(specModule.name);
244
+ // `plugin` is resolved at deploy time (Util_LogAttribution) — this Lambda can
245
+ // host aggregates from several plugins, so its own name carries no plugin
246
+ // identity to fall back on.
247
+ const plugin = h.plugin;
248
+ cmdTopicHandlers[h.queueArn] = { handler: parts.sqsHandler, comp, plugin };
249
+ cmdGenHandlers[specModule.name] = {
250
+ handler: buildCommandGeneratorHandler(parts, dispatchMode),
251
+ comp,
252
+ plugin,
253
+ };
262
254
  }));
263
255
  return [cmdTopicHandlers, cmdGenHandlers];
264
256
  }
@@ -271,7 +263,7 @@ async function buildAllHandlers() {
271
263
  const initPromise = buildAllHandlers();
272
264
 
273
265
  export async function handler(event, context) {
274
- _currentRequestId = context?.awsRequestId || "unknown";
266
+ setRequestId(context?.awsRequestId);
275
267
  const [cmdTopicHandlers, cmdGenHandlers] = await initPromise;
276
268
 
277
269
  // Route 1: AppSync direct invocation
@@ -290,9 +282,17 @@ export async function handler(event, context) {
290
282
  let result = null;
291
283
  let found = false;
292
284
  while (i < len && !found) {
293
- const [name, cmdGenHandler] = entries[i];
285
+ const [name, { handler: cmdGenHandler, comp, plugin }] = entries[i];
294
286
  try {
295
- const r = await runEffect(undefined, cmdGenHandler(event, context));
287
+ // Route 1 carries its envelope on `event.meta` (AppSync direct invoke),
288
+ // not in an SQS record — and there is no send time or receive count on
289
+ // this path, so latency/retry fields stay absent rather than faked.
290
+ const r = await runEffect(cmdGenHandler(event, context), {
291
+ correlationId: event.meta?.correlationId,
292
+ causationId: event.meta?.causationId,
293
+ comp,
294
+ plugin,
295
+ });
296
296
  log.debug("processed command via " + name, { comp: "CommandGenerator" });
297
297
  result = r;
298
298
  found = true;
@@ -313,13 +313,20 @@ export async function handler(event, context) {
313
313
 
314
314
  // Route 2: SQS CommandTopic events
315
315
  const records = event.Records || [];
316
- const correlationId = extractCorrelationId(records);
317
316
  const grouped = groupBySource(records);
318
317
  await Promise.all(Object.entries(grouped).map(async ([arn, subRecords]) => {
319
- const cmdHandler = cmdTopicHandlers[arn];
320
- if (cmdHandler !== undefined) {
318
+ const registered = cmdTopicHandlers[arn];
319
+ if (registered !== undefined) {
320
+ const { handler: cmdHandler, comp, plugin } = registered;
321
321
  log.debug("found handler for CommandTopic " + arn, { comp: "AggregateRuntime" });
322
- await runEffect(correlationId, cmdHandler({ Records: subRecords }, context));
322
+ await runEffect(cmdHandler({ Records: subRecords }, context), {
323
+ correlationId: extractMetaField(subRecords, "correlationId"),
324
+ causationId: extractMetaField(subRecords, "causationId"),
325
+ comp,
326
+ plugin,
327
+ timestamp: extractSentTimestamp(subRecords),
328
+ retryCount: extractRetryCount(subRecords),
329
+ });
323
330
  } else {
324
331
  log.warn("no handler found: " + arn, { comp: "AggregateRuntime" });
325
332
  }
@@ -204,10 +204,17 @@ let finish = () =>
204
204
  info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
205
205
 
206
206
  // --- CommandTopic Lambda ---
207
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
208
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
209
+ // shared or per-aggregate command handler. Resolve it here; the shell still
210
+ // derives `comp` itself from the spec name.
211
+ let pluginFragment = Util_LogAttribution.pluginFragment(
212
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
213
+ )
207
214
  let cmdTopicHandlerConfigOutput =
208
215
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
209
216
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
210
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
217
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
211
218
  )
212
219
 
213
220
  let cmdTopicEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -222,6 +229,7 @@ let finish = () =>
222
229
  let cmdTopicRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
223
230
  ~name=cmdTopicName,
224
231
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
232
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
225
233
  ~code=cmdTopicCode,
226
234
  ~sourceCodeHash=cmdTopicSourceCodeHash,
227
235
  ~envVars=cmdTopicEnvVars,
@@ -234,10 +242,17 @@ let finish = () =>
234
242
 
235
243
  // --- CommandGenerator Lambda ---
236
244
  if spec.commandGeneratorConnects->Array.length > 0 {
245
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
246
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
247
+ // shared or per-aggregate command handler. Resolve it here; the shell still
248
+ // derives `comp` itself from the spec name.
249
+ let pluginFragment = Util_LogAttribution.pluginFragment(
250
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
251
+ )
237
252
  let cmdGenHandlerConfigOutput =
238
253
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
239
254
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
240
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
255
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
241
256
  )
242
257
 
243
258
  let cmdGenEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -252,6 +267,7 @@ let finish = () =>
252
267
  let cmdGenRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
253
268
  ~name=cmdGenName,
254
269
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
270
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
255
271
  ~code=cmdGenCode,
256
272
  ~sourceCodeHash=cmdGenSourceCodeHash,
257
273
  ~envVars=cmdGenEnvVars,
@@ -297,6 +313,7 @@ let finish = () =>
297
313
  let evtMapperRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
298
314
  ~name=evtMapperName,
299
315
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
316
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
300
317
  ~code=evtMapperCode,
301
318
  ~sourceCodeHash=evtMapperSourceCodeHash,
302
319
  ~envVars=evtMapperEnvVars,
@@ -8,6 +8,7 @@ import * as Aggregate$ReventlessCore from "@reventlessdev/reventless-core/src/co
8
8
  import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
9
9
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
10
10
  import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
11
+ import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
11
12
  import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
12
13
  import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
13
14
 
@@ -164,28 +165,30 @@ function finish() {
164
165
  packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
165
166
  let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
166
167
  let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
168
+ let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
167
169
  let cmdTopicHandlerConfigOutput = Pulumi.all([
168
170
  info.eventLogTableName,
169
171
  spec.queueUrl,
170
172
  spec.queueArn
171
- ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
173
+ ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + `}]}`);
172
174
  let cmdTopicEnvVars = {};
173
175
  cmdTopicEnvVars["HANDLER_CONFIG"] = cmdTopicHandlerConfigOutput;
174
176
  let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
175
177
  let cmdTopicName = baseName + "CmdHandler";
176
- let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, "CommandHandler", match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
178
+ let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
177
179
  spec.commandTopicConnects.forEach(connect => connect(cmdTopicRuntime));
178
180
  if (spec.commandGeneratorConnects.length !== 0) {
181
+ let pluginFragment$1 = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
179
182
  let cmdGenHandlerConfigOutput = Pulumi.all([
180
183
  info.eventLogTableName,
181
184
  spec.queueUrl,
182
185
  spec.queueArn
183
- ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
186
+ ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment$1 + `}]}`);
184
187
  let cmdGenEnvVars = {};
185
188
  cmdGenEnvVars["HANDLER_CONFIG"] = cmdGenHandlerConfigOutput;
186
189
  let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
187
190
  let cmdGenName = baseName + "CmdGen";
188
- let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, "CommandHandler", match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
191
+ let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, "CommandHandler", "Aggregate", match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
189
192
  spec.commandGeneratorConnects.forEach(connect => connect(cmdGenRuntime));
190
193
  }
191
194
  let match$2 = spec.eventCollectorChannelSpec;
@@ -208,7 +211,7 @@ function finish() {
208
211
  evtMapperPackageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
209
212
  let match$4 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/EventMapperEntryPoint.mjs", evtMapperPackageDirs, undefined);
210
213
  let evtMapperName = baseName + "EventMapper";
211
- let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, "CommandHandler", match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
214
+ let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, "CommandHandler", "Aggregate", match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
212
215
  EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(evtMapperName, [match$2], evtMapperRuntime, aggregateOpts);
213
216
  });
214
217
  }
@@ -207,10 +207,17 @@ let finish = () =>
207
207
  info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
208
208
 
209
209
  // --- CommandTopic Lambda ---
210
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
211
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
212
+ // shared or per-aggregate command handler. Resolve it here; the shell still
213
+ // derives `comp` itself from the spec name.
214
+ let pluginFragment = Util_LogAttribution.pluginFragment(
215
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
216
+ )
210
217
  let cmdTopicHandlerConfigOutput =
211
218
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
212
219
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
213
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
220
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
214
221
  )
215
222
 
216
223
  let cmdTopicEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -225,6 +232,7 @@ let finish = () =>
225
232
  let cmdTopicRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
226
233
  ~name=cmdTopicName,
227
234
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
235
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
228
236
  ~code=cmdTopicCode,
229
237
  ~sourceCodeHash=cmdTopicSourceCodeHash,
230
238
  ~envVars=cmdTopicEnvVars,
@@ -237,10 +245,17 @@ let finish = () =>
237
245
 
238
246
  // --- CommandGenerator Lambda ---
239
247
  if spec.commandGeneratorConnects->Array.length > 0 {
248
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
249
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
250
+ // shared or per-aggregate command handler. Resolve it here; the shell still
251
+ // derives `comp` itself from the spec name.
252
+ let pluginFragment = Util_LogAttribution.pluginFragment(
253
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
254
+ )
240
255
  let cmdGenHandlerConfigOutput =
241
256
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
242
257
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
243
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
258
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
244
259
  )
245
260
 
246
261
  let cmdGenEnvVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -256,6 +271,7 @@ let finish = () =>
256
271
  let cmdGenRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
257
272
  ~name=cmdGenName,
258
273
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
274
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
259
275
  ~code=cmdGenCode,
260
276
  ~sourceCodeHash=cmdGenSourceCodeHash,
261
277
  ~envVars=cmdGenEnvVars,
@@ -301,6 +317,7 @@ let finish = () =>
301
317
  let evtMapperRuntime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
302
318
  ~name=evtMapperName,
303
319
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
320
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
304
321
  ~code=evtMapperCode,
305
322
  ~sourceCodeHash=evtMapperSourceCodeHash,
306
323
  ~envVars=evtMapperEnvVars,
@@ -8,6 +8,7 @@ import * as Aggregate$ReventlessCore from "@reventlessdev/reventless-core/src/co
8
8
  import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
9
9
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
10
10
  import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
11
+ import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
11
12
  import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
12
13
  import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
13
14
 
@@ -164,29 +165,31 @@ function finish() {
164
165
  packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
165
166
  let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
166
167
  let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
168
+ let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
167
169
  let cmdTopicHandlerConfigOutput = Pulumi.all([
168
170
  info.eventLogTableName,
169
171
  spec.queueUrl,
170
172
  spec.queueArn
171
- ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
173
+ ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + `}]}`);
172
174
  let cmdTopicEnvVars = {};
173
175
  cmdTopicEnvVars["HANDLER_CONFIG"] = cmdTopicHandlerConfigOutput;
174
176
  let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
175
177
  let cmdTopicName = baseName + "CmdHandler";
176
- let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, "CommandHandler", match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
178
+ let cmdTopicRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdTopicName, "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, cmdTopicEnvVars, Math.max(spec.commandTopicMemorySize, 1024), Math.max(spec.commandTopicTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
177
179
  spec.commandTopicConnects.forEach(connect => connect(cmdTopicRuntime));
178
180
  if (spec.commandGeneratorConnects.length !== 0) {
181
+ let pluginFragment$1 = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
179
182
  let cmdGenHandlerConfigOutput = Pulumi.all([
180
183
  info.eventLogTableName,
181
184
  spec.queueUrl,
182
185
  spec.queueArn
183
- ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
186
+ ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment$1 + `}]}`);
184
187
  let cmdGenEnvVars = {};
185
188
  cmdGenEnvVars["HANDLER_CONFIG"] = cmdGenHandlerConfigOutput;
186
189
  cmdGenEnvVars["DISPATCH_MODE"] = "async";
187
190
  let match$1 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
188
191
  let cmdGenName = baseName + "CmdGen";
189
- let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, "CommandHandler", match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
192
+ let cmdGenRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(cmdGenName, "CommandHandler", "Aggregate", match$1.code, match$1.sourceCodeHash, cmdGenEnvVars, Math.max(spec.commandGeneratorMemorySize, 1024), Math.max(spec.commandGeneratorTimeout, 30), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
190
193
  spec.commandGeneratorConnects.forEach(connect => connect(cmdGenRuntime));
191
194
  }
192
195
  let match$2 = spec.eventCollectorChannelSpec;
@@ -209,7 +212,7 @@ function finish() {
209
212
  evtMapperPackageDirs[mappingsPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(mappingsPkg);
210
213
  let match$4 = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/EventMapperEntryPoint.mjs", evtMapperPackageDirs, undefined);
211
214
  let evtMapperName = baseName + "EventMapper";
212
- let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, "CommandHandler", match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
215
+ let evtMapperRuntime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(evtMapperName, "CommandHandler", "Aggregate", match$4.code, match$4.sourceCodeHash, evtMapperEnvVars, Math.max(spec.eventCollectorMemorySize, 2048), Math.max(spec.eventCollectorTimeout, 180), undefined, undefined, undefined, undefined, undefined, aggregateOpts);
213
216
  EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(evtMapperName, [match$2], evtMapperRuntime, aggregateOpts);
214
217
  });
215
218
  }
@@ -193,10 +193,17 @@ let finish = () =>
193
193
  let behaviorModule =
194
194
  info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
195
195
 
196
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
197
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
198
+ // shared or per-aggregate command handler. Resolve it here; the shell still
199
+ // derives `comp` itself from the spec name.
200
+ let pluginFragment = Util_LogAttribution.pluginFragment(
201
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
202
+ )
196
203
  let handlerConfigOutput =
197
204
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
198
205
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
199
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
206
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
200
207
  )
201
208
 
202
209
  let envVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -218,6 +225,7 @@ let finish = () =>
218
225
  let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
219
226
  ~name=lambdaName,
220
227
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
228
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
221
229
  ~code,
222
230
  ~sourceCodeHash,
223
231
  ~envVars,
@@ -8,6 +8,7 @@ import * as Aggregate$ReventlessCore from "@reventlessdev/reventless-core/src/co
8
8
  import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
9
9
  import * as Util_Bundle$ReventlessAws from "../../util/Util_Bundle.res.mjs";
10
10
  import * as ComponentType$ReventlessCore from "@reventlessdev/reventless-core/src/ComponentType.res.mjs";
11
+ import * as Util_LogAttribution$ReventlessAws from "../../util/Util_LogAttribution.res.mjs";
11
12
  import * as RuntimeEnvironment_Lambda$ReventlessAws from "./RuntimeEnvironment_Lambda.res.mjs";
12
13
  import * as EventCollectorChannel_DynamoDbStream$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs";
13
14
 
@@ -139,11 +140,12 @@ function finish() {
139
140
  let lambdaName = name + "CmdHandler";
140
141
  let specModule = Stdlib_Option.getOr(JSON.stringify(info.specModulePath), `""`);
141
142
  let behaviorModule = Stdlib_Option.getOr(JSON.stringify(info.behaviorModulePath), `""`);
143
+ let pluginFragment = Util_LogAttribution$ReventlessAws.pluginFragment(`AggregateRuntime(` + spec.aggregateName + `)`);
142
144
  let handlerConfigOutput = Pulumi.all([
143
145
  info.eventLogTableName,
144
146
  spec.queueUrl,
145
147
  spec.queueArn
146
- ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"}]}`);
148
+ ]).apply(param => `{"handlers":[{"specModule":` + specModule + `,"behaviorModule":` + behaviorModule + `,"eventLogTable":"` + param[0] + `","queueUrl":"` + param[1] + `","queueArn":"` + param[2] + `"` + pluginFragment + `}]}`);
147
149
  let envVars = {};
148
150
  envVars["HANDLER_CONFIG"] = handlerConfigOutput;
149
151
  let packageDirs = {};
@@ -152,7 +154,7 @@ function finish() {
152
154
  packageDirs[specPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(specPkg);
153
155
  packageDirs[behaviorPkg] = Util_Bundle$ReventlessAws.resolvePackageRoot(behaviorPkg);
154
156
  let match = Util_Bundle$ReventlessAws.buildCodeArchive("@reventlessdev/reventless-aws/src/adapter/Runtime/AggregateEntryPoint.mjs", packageDirs, undefined);
155
- let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, "CommandHandler", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
157
+ let runtime = RuntimeEnvironment_Lambda$ReventlessAws.makeFromCodeAsset(lambdaName, "CommandHandler", "Aggregate", match.code, match.sourceCodeHash, envVars, spec.memorySize, spec.timeout, undefined, undefined, undefined, undefined, undefined, aggregateOpts);
156
158
  spec.connects.forEach(connect => connect(runtime));
157
159
  let channelSpecs = Stdlib_Option.mapOr(spec.eventCollectorChannelSpec, [], cs => [cs]);
158
160
  EventCollectorChannel_DynamoDbStream$ReventlessAws.connect(name, channelSpecs, runtime, aggregateOpts);
@@ -191,10 +191,17 @@ let finish = () =>
191
191
  let behaviorModule =
192
192
  info.behaviorModulePath->JSON.stringifyAny->Option.getOr(`""`)
193
193
 
194
+ // `plugin` cannot be resolved inside the Lambda — LogPrefix's registry is a
195
+ // deploy-time structure, and the Lambda-name fallback yields nothing for a
196
+ // shared or per-aggregate command handler. Resolve it here; the shell still
197
+ // derives `comp` itself from the spec name.
198
+ let pluginFragment = Util_LogAttribution.pluginFragment(
199
+ ~comp=`AggregateRuntime(${spec.aggregateName})`,
200
+ )
194
201
  let handlerConfigOutput =
195
202
  Pulumi.Output.all3((info.eventLogTableName, spec.queueUrl, spec.queueArn))
196
203
  ->Pulumi.Output.apply(((table, queueUrl, queueArn)) =>
197
- `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"}]}`
204
+ `{"handlers":[{"specModule":${specModule},"behaviorModule":${behaviorModule},"eventLogTable":"${table}","queueUrl":"${queueUrl}","queueArn":"${queueArn}"${pluginFragment}}]}`
198
205
  )
199
206
 
200
207
  let envVars: dict<Pulumi.Input.t<string>> = Dict.make()
@@ -215,6 +222,7 @@ let finish = () =>
215
222
  let runtime = RuntimeEnvironment_Lambda.makeFromCodeAsset(
216
223
  ~name,
217
224
  ~unitKind=ReventlessCore.Monitoring.CommandHandler,
225
+ ~componentKind=ReventlessCore.ComponentType.Aggregate,
218
226
  ~code,
219
227
  ~sourceCodeHash,
220
228
  ~envVars,