@reventlessdev/reventless-core 3.0.0-alpha.260 → 3.0.0-alpha.262

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 (208) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/package.json +10 -10
  3. package/src/Behavior.res +1 -4
  4. package/src/Message.res +17 -14
  5. package/src/Projection.res +51 -25
  6. package/src/RequestContext.res +8 -9
  7. package/src/ResourceAttribution.res +28 -14
  8. package/src/adapter/Adapter.res +48 -4
  9. package/src/adapter/EventLogProvisioning/EventLogProvisioning.res +5 -5
  10. package/src/adapter/Messaging/Messaging_Log_Backend.res +10 -7
  11. package/src/adapter/Messaging/Messaging_Log_Backend.res.mjs +2 -4
  12. package/src/adapter/Monitoring/Monitoring.res +16 -17
  13. package/src/adapter/QueryInterception/QueryInterception.res +0 -1
  14. package/src/adapter/Runtime/AggregateRuntime_Builder_Common.res +12 -5
  15. package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +11 -7
  16. package/src/adapter/Runtime/PluginRuntime_Builder_Micro.res +1 -7
  17. package/src/adapter/Runtime/PluginRuntime_Builder_Single.res +1 -7
  18. package/src/adapter/RuntimeExtension/RuntimeExtension.res +0 -1
  19. package/src/adapter/Secrets/Secrets_Node_Backend.res +60 -0
  20. package/src/adapter/Secrets/Secrets_Node_Backend.res.mjs +69 -0
  21. package/src/admin/Platform_Admin.res +17 -6
  22. package/src/admin/Platform_AdminApi.res +14 -9
  23. package/src/admin/Platform_Admin_Callback.res +1 -1
  24. package/src/admin/Platform_BakedManifest.res +34 -34
  25. package/src/admin/Platform_ComponentDefinitionsApi.res +9 -21
  26. package/src/admin/Platform_PluginStructuresApi.res +15 -12
  27. package/src/admin/UiFragmentRegistry/StateChange/UiFragmentRegistry.res +1 -1
  28. package/src/components/Aggregate/Aggregate.res +13 -12
  29. package/src/components/Aggregate/Aggregate_Builder.res +22 -21
  30. package/src/components/Aggregate/Aggregate_Callback.res +91 -86
  31. package/src/components/Api/ApiNoApiHelpers.res +1 -3
  32. package/src/components/Api/Api_Ids.res +0 -1
  33. package/src/components/Api/Api_Naming.res +41 -18
  34. package/src/components/Api/GraphQL_FragmentGenerator.res +38 -51
  35. package/src/components/Api/GraphQL_SchemaInspector.res +5 -3
  36. package/src/components/Api/GraphQL_Stitcher.res +9 -10
  37. package/src/components/Api/MCP_SchemaGenerator.res +8 -12
  38. package/src/components/Api/OwnerScopeDiagnostics.res +1 -2
  39. package/src/components/Api/QueryDbListQuery.res +13 -6
  40. package/src/components/Api/SchemaType.res +28 -23
  41. package/src/components/Api/SuryToJsonSchema.res +9 -10
  42. package/src/components/AutomationSlice/AutomationSlice.res +4 -4
  43. package/src/components/AutomationSlice/AutomationSlice_Builder.res +15 -14
  44. package/src/components/AutomationSlice/AutomationSlice_Callback.res +3 -3
  45. package/src/components/Builder_Helpers.res +12 -23
  46. package/src/components/CommandGenerator/CommandGenerator.res +6 -1
  47. package/src/components/CommandGenerator/CommandGenerator_Builder.res +29 -21
  48. package/src/components/CommandGenerator/CommandGenerator_Callback.res +17 -21
  49. package/src/components/CommandTopic/CommandTopic.res +3 -3
  50. package/src/components/CommandTopic/CommandTopic_Builder.res +10 -10
  51. package/src/components/CommandTopic/CommandTopic_Callback.res +1 -4
  52. package/src/components/CommandTopic/CommandTopic_Helpers.res +1 -2
  53. package/src/components/Counter/Counter_Builder.res +1 -6
  54. package/src/components/Counter/Counter_Callback.res +3 -3
  55. package/src/components/Dcb/Dcb_Builder.res +970 -956
  56. package/src/components/DcbEventLog/DcbEventLog.res +4 -4
  57. package/src/components/DcbEventLog/DcbEventLog_Builder.res +0 -1
  58. package/src/components/DcbEventLog/DcbEventLog_Operations.res +17 -18
  59. package/src/components/EventCollector/EventCollector_Builder.res +2 -1
  60. package/src/components/EventLog/EventLog.res +5 -1
  61. package/src/components/EventLog/EventLog_Operations.res +12 -8
  62. package/src/components/EventMapper/EventMapper.res +8 -10
  63. package/src/components/EventMapper/EventMapper_Builder.res +4 -1
  64. package/src/components/EventMapper/EventMapper_Callback.res +46 -31
  65. package/src/components/EventTopic/EventTopic.res +3 -3
  66. package/src/components/EventTopic/EventTopic_Builder.res +1 -1
  67. package/src/components/Extension/Extension.res +4 -1
  68. package/src/components/Extension/Extension_Operations.res +11 -3
  69. package/src/components/ExtensionPoint/ExtensionPoint.res +3 -3
  70. package/src/components/ExtensionPoint/ExtensionPoint_Builder.res +9 -10
  71. package/src/components/ExtensionPoint/ExtensionPoint_Callback.res +2 -6
  72. package/src/components/ExtensionPoint/ExtensionPoint_Operations.res +13 -5
  73. package/src/components/Heartbeat/Heartbeat_Callback.res +3 -3
  74. package/src/components/InboundTranslationSlice/InboundTranslationSlice.res +4 -4
  75. package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +7 -10
  76. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice.res +4 -4
  77. package/src/components/OutboundTranslationSlice/OutboundTranslationSlice_Builder.res +15 -14
  78. package/src/components/QueryDb/QueryDb_Adapter.res +1 -3
  79. package/src/components/QueryDb/QueryDb_Operations.res +10 -10
  80. package/src/components/ReadModel/ReadModel.res +3 -3
  81. package/src/components/ReadModel/ReadModel_Builder.res +1 -2
  82. package/src/components/ReadModel/ReadModel_Callback.res +2 -1
  83. package/src/components/SideEffectHandler/SideEffectHandler_Callback.res +5 -2
  84. package/src/components/StateChangeSlice/StateChangeSlice.res +3 -3
  85. package/src/components/StateChangeSlice/StateChangeSlice_Builder.res +23 -4
  86. package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +22 -6
  87. package/src/components/StateTopic.res +1 -3
  88. package/src/components/StateViewSlice/StateViewSlice.res +4 -4
  89. package/src/components/StateViewSlice/StateViewSlice_Builder.res +79 -68
  90. package/src/components/StateViewSlice/StateViewSlice_Callback.res +3 -1
  91. package/src/components/Task/Task.res +3 -3
  92. package/src/components/Task/Task_Adapter.res +4 -1
  93. package/src/components/Task/Task_Builder.res +24 -21
  94. package/src/plugin/api/PluginBaseFragment.res +9 -3
  95. package/src/plugin/component/Capability_Inference.res +8 -10
  96. package/src/plugin/component/Plugin.res +6 -6
  97. package/src/plugin/component/Plugin_Builder.res +54 -50
  98. package/src/plugin/component/Plugin_Callback.res +10 -6
  99. package/src/plugin/component/Plugin_Helpers.res +264 -230
  100. package/src/plugin/component/Plugin_Structure.res +370 -324
  101. package/src/plugin/component/Plugin_SubscriptionSchema.res +8 -6
  102. package/src/plugin/component/SchemaWalker.res +11 -12
  103. package/src/plugin/connect/PluginConnectExtension_Mapping.res +45 -50
  104. package/src/plugin/lifecycle/PluginBehavior.res +3 -4
  105. package/src/plugin/lifecycle/PluginSpec.res +1 -2
  106. package/src/plugin/lifecycle/PluginsProjection.res +16 -5
  107. package/src/plugin/lifecycle/PluginsReadModelSpec.res +0 -2
  108. package/src/util/CommandPublisher.res +9 -2
  109. package/src/util/CsvStream.res +3 -3
  110. package/src/util/Interstack.res +7 -15
  111. package/src/util/Interstack.resi +3 -3
  112. package/src/util/LogFormat.res +5 -9
  113. package/src/util/Logger.res +1 -2
  114. package/src/util/Lru.res +2 -1
  115. package/src/util/Lru.resi +2 -3
  116. package/src/util/ScheduleOps.res +24 -27
  117. package/src/util/StorePrefixCollision.res +6 -9
  118. package/src/util/Util_Promise.res +4 -1
  119. package/src/util/Util_Promise.res.mjs +1 -1
  120. package/tests/IdentityTest.res +166 -113
  121. package/tests/ResourceAttributionTest.res +28 -25
  122. package/tests/Secrets_Node_BackendTest.res +141 -0
  123. package/tests/Secrets_Node_BackendTest.res.mjs +152 -0
  124. package/tests/StorePrefixCollisionTest.res +2 -1
  125. package/tests/TaskBucketNamingTest.res +3 -2
  126. package/tests/adapter/EventLogProvisioningTest.res +51 -48
  127. package/tests/adapter/MonitoringTest.res +81 -38
  128. package/tests/adapter/QueryInterceptionTest.res +2 -2
  129. package/tests/adapter/RefusalVocabularyTest.res +31 -23
  130. package/tests/adapter/RuntimeExtensionHookReachTest.res +9 -8
  131. package/tests/adapter/RuntimeExtensionTest.res +5 -3
  132. package/tests/admin/AdminApiSchemaDriftTest.res +22 -16
  133. package/tests/admin/Platform_Admin_StructureTest.res +22 -14
  134. package/tests/admin/Platform_Admin_StructureTest.res.mjs +4 -3
  135. package/tests/admin/Platform_BakedManifestTest.res +31 -35
  136. package/tests/admin/Platform_ComponentDefinitionsApiTest.res +18 -15
  137. package/tests/admin/Platform_PluginStructuresApiTest.res +5 -3
  138. package/tests/admin/Platform_UIFragmentsApiTest.res +6 -3
  139. package/tests/aggregate/AggregateCacheTest.res +10 -12
  140. package/tests/aggregate/AggregateCallbackTest.res +75 -46
  141. package/tests/aggregate/AggregateCausationTest.res +19 -20
  142. package/tests/aggregate/AggregateConflictTest.res +41 -19
  143. package/tests/aggregate/AggregateFixtures.res +15 -5
  144. package/tests/aggregate/AggregateRejectionTest.res +97 -80
  145. package/tests/aggregate/AggregateSnapshotTest.res +44 -16
  146. package/tests/api/Api_IdsTest.res +10 -4
  147. package/tests/api/BrandedMarkerCompositionTest.res +48 -36
  148. package/tests/api/GeolocationSemanticTest.res +3 -3
  149. package/tests/api/GraphQL_FragmentGeneratorTest.res +66 -54
  150. package/tests/api/OwnerScopeDiagnosticsTest.res +31 -27
  151. package/tests/api/StorageRefFieldsTest.res +30 -18
  152. package/tests/api/SuryToJsonSchemaTest.res +1315 -1014
  153. package/tests/api/TaggedUnionSchemaTest.res +17 -24
  154. package/tests/commandgenerator/CommandGeneratorCallbackTest.res +235 -179
  155. package/tests/commandgenerator/CommandGeneratorFixtures.res +8 -13
  156. package/tests/commandgenerator/OwnerStampingTest.res +91 -76
  157. package/tests/commandtopic/CommandOutcomeHookTest.res +198 -155
  158. package/tests/commandtopic/CommandTopicCallbackFixtures.res +5 -4
  159. package/tests/commandtopic/CommandTopicCallbackTest.res +61 -43
  160. package/tests/commandtopic/CommandTopicHelpersRejectionTest.res +70 -55
  161. package/tests/counter/CounterCallbackTest.res +40 -34
  162. package/tests/counter/CounterFixtures.res +4 -4
  163. package/tests/dcb/DcbDecodeTest.res +115 -84
  164. package/tests/dcb/DcbEventLogOperationsTest.res +194 -143
  165. package/tests/dcb/DcbEventLogSchemaTest.res +13 -13
  166. package/tests/dcb/DcbFixtures.res +4 -5
  167. package/tests/dcb/DcbScopeInferenceTest.res +173 -114
  168. package/tests/dcb/DcbStateChangeSliceTest.res +391 -262
  169. package/tests/dcb/DcbTagTest.res +22 -11
  170. package/tests/dcb/DcbValidationTest.res +288 -218
  171. package/tests/eventlog/EventLogFixtures.res +4 -4
  172. package/tests/eventlog/EventLogOperationsTest.res +102 -67
  173. package/tests/eventlog/EventLogRetryTest.res +104 -65
  174. package/tests/eventmapper/EventMapperCallbackTest.res +118 -83
  175. package/tests/eventmapper/EventMapperFixtures.res +15 -23
  176. package/tests/eventmapper/EventMapperTest.res +54 -38
  177. package/tests/eventtopic/EventTopicFixtures.res +3 -4
  178. package/tests/eventtopic/EventTopicOperationsTest.res +41 -29
  179. package/tests/extensionpoint/ExtensionPointCallbackTest.res +58 -45
  180. package/tests/extensionpoint/ExtensionPointFixtures.res +16 -20
  181. package/tests/extensionpoint/ExtensionPointOperationsTest.res +70 -49
  182. package/tests/extensionpoint/PluginDisconnectScheduleTest.res +2 -1
  183. package/tests/logger/LogFormatTest.res +104 -82
  184. package/tests/logger/LoggerLazyTest.res +21 -12
  185. package/tests/message/MessageTest.res +96 -93
  186. package/tests/message/MetaEnvelopeTest.res +26 -30
  187. package/tests/plugin/HeartbeatDisconnectGraceTest.res +31 -25
  188. package/tests/plugin/ManifestVisibilityTest.res +20 -12
  189. package/tests/plugin/PluginDefinitionScalars.res +1 -2
  190. package/tests/plugin/PluginLifecycleCorpusTest.res +15 -12
  191. package/tests/plugin/PluginSpecExperiment.res +0 -1
  192. package/tests/plugin/PluginStructureTest.res +1529 -1045
  193. package/tests/plugin/Plugin_EventQuerySchemaTest.res +21 -10
  194. package/tests/plugin/SchemaWalkerTest.res +116 -70
  195. package/tests/plugin/StateChange/PsReserveStock.res +4 -4
  196. package/tests/plugin/StateView/PsAnnotatedView.res +4 -4
  197. package/tests/plugin/StateView/PsCustomersView.res +4 -4
  198. package/tests/plugin/StateView/PsShipmentsView.res +3 -2
  199. package/tests/projection/LifecycleTrailTest.res +1 -4
  200. package/tests/projection/ProjectionOptimizeTest.res +13 -9
  201. package/tests/querydb/QueryDbFixtures.res +0 -1
  202. package/tests/querydb/QueryDbOperationsTest.res +99 -64
  203. package/tests/querydb/TaggedUnionStampTest.res +10 -8
  204. package/tests/sideeffecthandler/SideEffectHandlerCallbackTest.res +50 -35
  205. package/tests/sideeffecthandler/SideEffectHandlerFixtures.res +4 -10
  206. package/tests/util/CommandPublisherTest.res +0 -1
  207. package/tests/util/CsvStreamTest.res +3 -3
  208. package/tests/util/LruTest.res +84 -56
@@ -16,7 +16,9 @@ module Make = (
16
16
  and module EventCollectorChannel = EventCollectorChannel
17
17
  and type runtimeParts = RuntimeEnvironment.parts,
18
18
  HooksConfig: Plugin_Helpers.HooksConfig,
19
- ): (Aggregate.T with type api = CommandGeneratorResolvers.api and type component = Aggregate.component) => {
19
+ ): (
20
+ Aggregate.T with type api = CommandGeneratorResolvers.api and type component = Aggregate.component
21
+ ) => {
20
22
  module Spec = Spec
21
23
  module AggregateRuntimeBuilder = AggregateRuntimeBuilder
22
24
 
@@ -25,10 +27,7 @@ module Make = (
25
27
 
26
28
  module SpecificEventLog = EventLog_Builder.Make(Spec, EventLogStorage, EventTopicPublisher)
27
29
  module SpecificCommandTopic = CommandTopic_Builder.Make(Spec, CommandTopicChannel)
28
- module SpecificCommandGenerator = CommandGenerator_Builder.Make(
29
- Spec,
30
- CommandGeneratorResolvers,
31
- )
30
+ module SpecificCommandGenerator = CommandGenerator_Builder.Make(Spec, CommandGeneratorResolvers)
32
31
  module SpecificEventCollector = EventCollector_Builder.Make(
33
32
  RuntimeEnvironment,
34
33
  EventCollectorChannel,
@@ -57,16 +56,22 @@ module Make = (
57
56
  )
58
57
  {
59
58
  ...aggregate->Component.outputs,
60
- eventMapper: eventMapper->Pulumi.Output.apply(eventMapper =>
61
- Some(eventMapper->Component.outputs)
62
- ),
59
+ eventMapper: eventMapper->Pulumi.Output.apply(eventMapper => Some(
60
+ eventMapper->Component.outputs,
61
+ )),
63
62
  }
64
63
  } else {
65
64
  aggregate->Component.outputs
66
65
  }
67
66
  }
68
67
 
69
- let createCommandTopic = (eventLog: SpecificEventLog.component, name, opts, ~memorySize, ~timeout) => {
68
+ let createCommandTopic = (
69
+ eventLog: SpecificEventLog.component,
70
+ name,
71
+ opts,
72
+ ~memorySize,
73
+ ~timeout,
74
+ ) => {
70
75
  // Created outside the apply below, so the topic — and with it the channel's
71
76
  // queue — exists while plugin construction is still synchronous. An outbound
72
77
  // slice targeting this aggregate resolves its publish queue in a finalizer
@@ -122,14 +127,13 @@ module Make = (
122
127
  | Some(bindHandler) =>
123
128
  // In-memory: bind generateCommand to resolver stubs directly,
124
129
  // skipping the adapter-driven forCommandGenerator path.
125
- let fields =
126
- switch Plugin_Helpers.aggregateMutationFieldsRegistry->Dict.get(Spec.name) {
127
- | Some(registeredFields) if registeredFields->Array.length > 0 => registeredFields
128
- | _ => []
129
- }
130
+ let fields = switch Plugin_Helpers.aggregateMutationFieldsRegistry->Dict.get(Spec.name) {
131
+ | Some(registeredFields) if registeredFields->Array.length > 0 => registeredFields
132
+ | _ => []
133
+ }
130
134
  let generateCommand = CommandGenerator_Callback.makeGenerateCommand(
131
135
  ~publishJsons,
132
- ~publishJsonsAndWait=?publishJsonsAndWait,
136
+ ~publishJsonsAndWait?,
133
137
  ~serviceName=Spec.name,
134
138
  ~commandSchema=Spec.commandSchema->S.castToUnknown,
135
139
  ~componentKind=CommandGenerator_Callback.Aggregate,
@@ -164,7 +168,8 @@ module Make = (
164
168
  ~opts,
165
169
  )
166
170
  let commandTopic = eventLog->createCommandTopic(name, opts, ~memorySize, ~timeout)
167
- let commandGenerator = commandTopic->createCommandGenerator(~api, name, opts, ~memorySize, ~timeout)
171
+ let commandGenerator =
172
+ commandTopic->createCommandGenerator(~api, name, opts, ~memorySize, ~timeout)
168
173
 
169
174
  self->Component.setOperations(
170
175
  commandTopic->Pulumi.Output.flatMap(commandTopic =>
@@ -189,11 +194,7 @@ module Make = (
189
194
  self->Component.setOutputs(aggOutputs)
190
195
  }
191
196
 
192
- let make = (
193
- ~api: CommandGeneratorResolvers.api,
194
- ~runtime=?,
195
- ~opts=?,
196
- ): Aggregate.component =>
197
+ let make = (~api: CommandGeneratorResolvers.api, ~runtime=?, ~opts=?): Aggregate.component =>
197
198
  Component.make(
198
199
  ~componentType=Aggregate.componentType->ComponentType.toString,
199
200
  ~name=Spec.name,
@@ -69,43 +69,47 @@ module Make = (
69
69
  //
70
70
  // `~seq` is the replayed sequence number the batch decides from, carried in so
71
71
  // the line below can name the state rather than serialise it.
72
- let processCommand = (~seq: int) => (
73
- (state, outcomes): (Behavior.state, array<(string, cmdOutcome, Message.meta)>),
74
- topicItem: CommandTopic.topicItem<Message.command'<Spec.Id.t, Spec.command>>,
75
- ) => {
76
- let {reference, command: command'} = topicItem
77
- let meta = command'->updateMeta
78
- let id = command'.id->Spec.Id.toString
79
- // Identity, not content: the folded state grows with the entity's whole
80
- // history, so serialising it here makes the line's size a function of how
81
- // long the system has been in use. The state at decision time is a
82
- // debugger's subject, not a log's.
83
- let cmdName =
84
- command'.command->Message.encode(Spec.commandSchema)->Message.variantNameOfJson->LogFormat.bold
85
- EffectLogger.logDebug(
86
- ~comp,
87
- `deciding: id=${id} seq=${seq->Int.toString} cmd=${cmdName}`,
88
- )->Effect.runSync
89
- switch Behavior.decide(state, command'.command) {
90
- | Ok(generatedEvents) =>
91
- let newState = generatedEvents->Array.reduce(state, Behavior.evolve)
92
- (newState, Array.concat(outcomes, [(reference, CmdOk(generatedEvents), meta)]))
93
- | Error(error) =>
94
- let errorJson = error->Message.encode(Spec.errorSchema)
95
- let errorCode = errorJson->Message.variantNameOfJson
96
- // Strip the TAG so detail carries only the rejection payload (empty for unit errors).
97
- let (_, payloadDict) = errorJson->Message.splitMessage
98
- let errorDetail =
99
- payloadDict->Dict.toArray->Array.length == 0
100
- ? ""
101
- : payloadDict->JSON.Encode.object->JSON.stringify
102
- EffectLogger.logError(
72
+ let processCommand = (~seq: int) =>
73
+ (
74
+ (state, outcomes): (Behavior.state, array<(string, cmdOutcome, Message.meta)>),
75
+ topicItem: CommandTopic.topicItem<Message.command'<Spec.Id.t, Spec.command>>,
76
+ ) => {
77
+ let {reference, command: command'} = topicItem
78
+ let meta = command'->updateMeta
79
+ let id = command'.id->Spec.Id.toString
80
+ // Identity, not content: the folded state grows with the entity's whole
81
+ // history, so serialising it here makes the line's size a function of how
82
+ // long the system has been in use. The state at decision time is a
83
+ // debugger's subject, not a log's.
84
+ let cmdName =
85
+ command'.command
86
+ ->Message.encode(Spec.commandSchema)
87
+ ->Message.variantNameOfJson
88
+ ->LogFormat.bold
89
+ EffectLogger.logDebug(
103
90
  ~comp,
104
- `decide rejected: ${errorCode} ${errorDetail} id=${id}`,
91
+ `deciding: id=${id} seq=${seq->Int.toString} cmd=${cmdName}`,
105
92
  )->Effect.runSync
106
- (state, Array.concat(outcomes, [(reference, CmdRejected({errorCode, errorDetail}), meta)]))
93
+ switch Behavior.decide(state, command'.command) {
94
+ | Ok(generatedEvents) =>
95
+ let newState = generatedEvents->Array.reduce(state, Behavior.evolve)
96
+ (newState, Array.concat(outcomes, [(reference, CmdOk(generatedEvents), meta)]))
97
+ | Error(error) =>
98
+ let errorJson = error->Message.encode(Spec.errorSchema)
99
+ let errorCode = errorJson->Message.variantNameOfJson
100
+ // Strip the TAG so detail carries only the rejection payload (empty for unit errors).
101
+ let (_, payloadDict) = errorJson->Message.splitMessage
102
+ let errorDetail =
103
+ payloadDict->Dict.toArray->Array.length == 0
104
+ ? ""
105
+ : payloadDict->JSON.Encode.object->JSON.stringify
106
+ EffectLogger.logError(
107
+ ~comp,
108
+ `decide rejected: ${errorCode} ${errorDetail} id=${id}`,
109
+ )->Effect.runSync
110
+ (state, Array.concat(outcomes, [(reference, CmdRejected({errorCode, errorDetail}), meta)]))
111
+ }
107
112
  }
108
- }
109
113
 
110
114
  let maxConflictRetries = 3
111
115
 
@@ -125,9 +129,7 @@ module Make = (
125
129
  // the fixed capacity (a per-aggregate knob is a future refinement — see
126
130
  // docs/plans/done/aggregate-snapshotting.md).
127
131
  let replayCacheCapacity = 100
128
- let replayCache: Lru.t<string, (Behavior.state, int)> = Lru.make(
129
- ~capacity=replayCacheCapacity,
130
- )
132
+ let replayCache: Lru.t<string, (Behavior.state, int)> = Lru.make(~capacity=replayCacheCapacity)
131
133
 
132
134
  let resetCache = () => replayCache->Lru.clear
133
135
 
@@ -188,8 +190,7 @@ module Make = (
188
190
  let seedEffect = switch snapshotConfig {
189
191
  | None => Effect.succeed((Behavior.initialState, 0))
190
192
  | Some(_) =>
191
- Effect.promise(() => Ops.eventLog.latestSnapshot(id))
192
- ->Effect.map(snapResult =>
193
+ Effect.promise(() => Ops.eventLog.latestSnapshot(id))->Effect.map(snapResult =>
193
194
  switch snapResult {
194
195
  | Ok(Some(snap)) if snap.EventLog.schemaHash == stateSchemaHash =>
195
196
  switch decodeState(snap.state) {
@@ -269,7 +270,11 @@ module Make = (
269
270
  | Some({interval}) if interval > 0 && newSeq / interval > oldSeq / interval =>
270
271
  switch encodeState(state) {
271
272
  | Some(stateJson) =>
272
- fireSnapshotWrite(id, idStr, {EventLog.seqNr: newSeq, state: stateJson, schemaHash: stateSchemaHash})
273
+ fireSnapshotWrite(
274
+ id,
275
+ idStr,
276
+ {EventLog.seqNr: newSeq, state: stateJson, schemaHash: stateSchemaHash},
277
+ )
273
278
  | None =>
274
279
  EffectLogger.logWarn(
275
280
  ~comp,
@@ -342,8 +347,7 @@ module Make = (
342
347
  | None => coldReadState(id)
343
348
  }
344
349
 
345
- readState
346
- ->Effect.flatMap(((initialState, sequenceNr)) => {
350
+ readState->Effect.flatMap(((initialState, sequenceNr)) => {
347
351
  let (finalState, outcomes) =
348
352
  topicItemsForId->Array.reduce((initialState, []), processCommand(~seq=sequenceNr))
349
353
 
@@ -379,51 +383,52 @@ module Make = (
379
383
  ~detail=eventJsons,
380
384
  `produced ${eventCount} event(s): [${eventDetails}]`,
381
385
  )
382
- ->Effect.flatMap(
383
- _ => Effect.promise(() => Ops.eventLog.append(sequenceNr, id, generatedEvents')),
386
+ ->Effect.flatMap(_ =>
387
+ Effect.promise(() => Ops.eventLog.append(sequenceNr, id, generatedEvents'))
384
388
  )
385
- ->Effect.flatMap(
386
- appendResult =>
387
- switch appendResult {
388
- | Ok(_) =>
389
- // The post-decide fold state IS the post-append replay result;
390
- // cache it so the next command for this id skips the replay.
391
- let newSeq = sequenceNr + generatedEvents'->Array.length
392
- replayCache->Lru.put(idStr, (finalState, newSeq))
393
- // Persist a snapshot if this append crossed an interval boundary
394
- // (fire-and-forget — never blocks or fails the command).
395
- maybeWriteSnapshot(id, idStr, ~oldSeq=sequenceNr, ~newSeq, finalState)
396
- let perRef = reportFinalOutcomes(
397
- outcomes,
398
- ~entityId=idStr,
399
- ~appendSucceeded=true,
400
- ~appendedEventCount=generatedEvents'->Array.length,
401
- )
402
- EffectLogger.logInfo(~comp, `append: id=${idStr}`)->Effect.map(_ => Ok(perRef))
403
- | Error(EventLog.Conflict) =>
404
- // Another writer advanced the stream past our (possibly cached)
405
- // sequenceNr — drop the entry so the retry replays cold.
406
- replayCache->Lru.invalidate(idStr)
407
- // Signal the outer replay+re-decide retry loop (which matches
408
- // Error(_)); the string is an internal marker, no longer a
409
- // cross-component substring sentinel.
410
- EffectLogger.logWarn(~comp, `conflict: id=${idStr}, will retry`)->Effect.map(
411
- _ => Error("conflict"),
412
- )
413
- | Error(EventLog.StorageFailure(msg)) =>
414
- // Appends are atomic, so the read snapshot is likely still valid —
415
- // but a storage error means we can't be sure what committed;
416
- // drop the entry so the next attempt reads authoritative state.
417
- replayCache->Lru.invalidate(idStr)
418
- let perRef = reportFinalOutcomes(
419
- outcomes,
420
- ~entityId=idStr,
421
- ~appendSucceeded=false,
422
- ~appendedEventCount=0,
423
- ~appendErrorDetail=msg,
424
- )
425
- EffectLogger.logError(~comp, `append failed: id=${idStr}: ${msg}`)->Effect.map(_ => Ok(perRef))
426
- },
389
+ ->Effect.flatMap(appendResult =>
390
+ switch appendResult {
391
+ | Ok(_) =>
392
+ // The post-decide fold state IS the post-append replay result;
393
+ // cache it so the next command for this id skips the replay.
394
+ let newSeq = sequenceNr + generatedEvents'->Array.length
395
+ replayCache->Lru.put(idStr, (finalState, newSeq))
396
+ // Persist a snapshot if this append crossed an interval boundary
397
+ // (fire-and-forget — never blocks or fails the command).
398
+ maybeWriteSnapshot(id, idStr, ~oldSeq=sequenceNr, ~newSeq, finalState)
399
+ let perRef = reportFinalOutcomes(
400
+ outcomes,
401
+ ~entityId=idStr,
402
+ ~appendSucceeded=true,
403
+ ~appendedEventCount=generatedEvents'->Array.length,
404
+ )
405
+ EffectLogger.logInfo(~comp, `append: id=${idStr}`)->Effect.map(_ => Ok(perRef))
406
+ | Error(EventLog.Conflict) =>
407
+ // Another writer advanced the stream past our (possibly cached)
408
+ // sequenceNr — drop the entry so the retry replays cold.
409
+ replayCache->Lru.invalidate(idStr)
410
+ // Signal the outer replay+re-decide retry loop (which matches
411
+ // Error(_)); the string is an internal marker, no longer a
412
+ // cross-component substring sentinel.
413
+ EffectLogger.logWarn(~comp, `conflict: id=${idStr}, will retry`)->Effect.map(
414
+ _ => Error("conflict"),
415
+ )
416
+ | Error(EventLog.StorageFailure(msg)) =>
417
+ // Appends are atomic, so the read snapshot is likely still valid —
418
+ // but a storage error means we can't be sure what committed;
419
+ // drop the entry so the next attempt reads authoritative state.
420
+ replayCache->Lru.invalidate(idStr)
421
+ let perRef = reportFinalOutcomes(
422
+ outcomes,
423
+ ~entityId=idStr,
424
+ ~appendSucceeded=false,
425
+ ~appendedEventCount=0,
426
+ ~appendErrorDetail=msg,
427
+ )
428
+ EffectLogger.logError(~comp, `append failed: id=${idStr}: ${msg}`)->Effect.map(
429
+ _ => Ok(perRef),
430
+ )
431
+ }
427
432
  )
428
433
  }
429
434
  })
@@ -10,9 +10,7 @@ let excludedByMembers = (commandSchema: S.t<unknown>): array<string> =>
10
10
  switch commandSchema {
11
11
  | AnyOf({anyOf}) =>
12
12
  anyOf->Array.filterMap(member =>
13
- member->S.Metadata.get(~id=noApiVariantId)->Option.getOr(false)
14
- ? variantNameOf(member)
15
- : None
13
+ member->S.Metadata.get(~id=noApiVariantId)->Option.getOr(false) ? variantNameOf(member) : None
16
14
  )
17
15
  | _ => []
18
16
  }
@@ -12,7 +12,6 @@ door applies it, and so provider adapters share one definition rather than three
12
12
  Provider-neutral on purpose: the contract belongs to neither the local platform
13
13
  nor AWS.
14
14
  */
15
-
16
15
  @val external btoa: string => string = "btoa"
17
16
  @val external atob: string => string = "atob"
18
17
 
@@ -12,9 +12,15 @@ type queryNames = {
12
12
  }
13
13
 
14
14
  let pluralize = (n: string) =>
15
- if RegExp.test(%re("/[^aeiou]y$/i"), n) {
15
+ if RegExp.test(/[^aeiou]y$/i, n) {
16
16
  n->String.slice(~start=0, ~end=String.length(n) - 1) ++ "ies"
17
- } else if n->String.endsWith("s") || n->String.endsWith("x") || n->String.endsWith("z") || n->String.endsWith("ch") || n->String.endsWith("sh") {
17
+ } else if (
18
+ n->String.endsWith("s") ||
19
+ n->String.endsWith("x") ||
20
+ n->String.endsWith("z") ||
21
+ n->String.endsWith("ch") ||
22
+ n->String.endsWith("sh")
23
+ ) {
18
24
  n ++ "es"
19
25
  } else {
20
26
  n ++ "s"
@@ -23,7 +29,13 @@ let pluralize = (n: string) =>
23
29
  let singularize = (n: string) =>
24
30
  if n->String.endsWith("ies") {
25
31
  n->String.slice(~start=0, ~end=n->String.length - 3) ++ "y"
26
- } else if n->String.endsWith("ses") || n->String.endsWith("xes") || n->String.endsWith("zes") || n->String.endsWith("ches") || n->String.endsWith("shes") {
32
+ } else if (
33
+ n->String.endsWith("ses") ||
34
+ n->String.endsWith("xes") ||
35
+ n->String.endsWith("zes") ||
36
+ n->String.endsWith("ches") ||
37
+ n->String.endsWith("shes")
38
+ ) {
27
39
  n->String.slice(~start=0, ~end=n->String.length - 2)
28
40
  } else if n->String.endsWith("s") {
29
41
  n->String.slice(~start=0, ~end=n->String.length - 1)
@@ -76,16 +88,17 @@ let assertSubscriptionNameFits = (~fieldName: string) => {
76
88
  // expect that shape (not aggregate-style `${plugin}_${slice}_${command}`). @noApi
77
89
  // variants are filtered out. Every emitted name is guarded against the 50-char AppSync
78
90
  // subscription cap at build time. Returns [(fieldName, constructorName)] in declaration order.
79
- let sliceMutationFields = (
80
- ~plugin: string,
81
- ~slice: string,
82
- ~commandSchema: S.t<unknown>,
83
- ): array<(string, string)> => {
91
+ let sliceMutationFields = (~plugin: string, ~slice: string, ~commandSchema: S.t<unknown>): array<(
92
+ string,
93
+ string,
94
+ )> => {
84
95
  let allNames = Reventless.DcbTag.extractAllVariantNames(commandSchema->Obj.magic)
85
96
  let filtered = ApiNoApiHelpers.filterNoApiVariants(allNames, commandSchema)
86
97
  switch filtered {
87
98
  | [] => []
88
- | [single] => [(assertSubscriptionNameFits(~fieldName=sliceMutationField(~plugin, ~slice)), single)]
99
+ | [single] => [
100
+ (assertSubscriptionNameFits(~fieldName=sliceMutationField(~plugin, ~slice)), single),
101
+ ]
89
102
  | _ =>
90
103
  filtered->Array.map(ctor => (
91
104
  assertSubscriptionNameFits(~fieldName=dcbCommandMutationField(~plugin, ~command=ctor)),
@@ -115,7 +128,11 @@ let sliceMutationFieldFor = (
115
128
  // "ProductDemand" the singularize is a no-op and pluralize behaves as usual.
116
129
  let canonicalPlural = (n: string) => pluralize(singularize(n))
117
130
 
118
- let queryFieldNamesForReadModel = (~plugin: string, ~name: string, ~connectionSpec: bool=true): queryNames => {
131
+ let queryFieldNamesForReadModel = (
132
+ ~plugin: string,
133
+ ~name: string,
134
+ ~connectionSpec: bool=true,
135
+ ): queryNames => {
119
136
  let singular = singularize(name)
120
137
  let plural = canonicalPlural(name)
121
138
  {
@@ -144,18 +161,16 @@ returning a type the plugin does not define fails the merge — and on AWS the
144
161
  target table's `dynamodb:*` grant is attached to the *declaring* plugin's API
145
162
  role, so even a schema that merged would be refused at read time.
146
163
  */
147
- let resolvedFieldsOfConfig = (
148
- ~plugin: string,
149
- config: Reventless.ReadModel.config,
150
- ): array<ReventlessInfra.Api.resolvedFieldEntry> => {
164
+ let resolvedFieldsOfConfig = (~plugin: string, config: Reventless.ReadModel.config): array<
165
+ ReventlessInfra.Api.resolvedFieldEntry,
166
+ > => {
151
167
  let assertSamePlugin = (~pluginName: option<string>, ~tableName: string, ~fieldName: string) =>
152
168
  switch pluginName {
153
169
  | Some(p) if p != plugin =>
154
170
  JsError.throwWithMessage(
155
171
  `Field \`${fieldName}\` resolves to "${tableName}" in plugin "${p}", but cross-plugin ` ++
156
172
  `resolvers are not supported: a plugin's GraphQL document must be valid standalone, and ` ++
157
- `"${p}"'s table is not readable by "${plugin}"'s API role. Query the other view directly, ` ++
158
- `or project the fields you need into this one.`,
173
+ `"${p}"'s table is not readable by "${plugin}"'s API role. Query the other view directly, ` ++ `or project the fields you need into this one.`,
159
174
  )
160
175
  | _ => ()
161
176
  }
@@ -186,7 +201,11 @@ let resolvedFieldsOfConfig = (
186
201
  Array.concat(single, many)
187
202
  }
188
203
 
189
- let queryFieldNamesForStateView = (~plugin: string, ~viewName: string, ~connectionSpec: bool=true): queryNames => {
204
+ let queryFieldNamesForStateView = (
205
+ ~plugin: string,
206
+ ~viewName: string,
207
+ ~connectionSpec: bool=true,
208
+ ): queryNames => {
190
209
  let entity = stripViewSuffix(viewName)
191
210
  let singular = singularize(entity)
192
211
  let plural = canonicalPlural(entity)
@@ -206,7 +225,11 @@ let queryFieldNamesForStateView = (~plugin: string, ~viewName: string, ~connecti
206
225
  // the resolver path (`GetItem` instead of `Scan`), and the `*ByIds` batch
207
226
  // resolver all line up. StateViewSlice uses `queryFieldNamesForStateView`
208
227
  // instead and keeps its own (id-free) shape.
209
- let queryFieldNamesForSliceQueryDb = (~plugin: string, ~queryDbName: string, ~connectionSpec: bool=true): queryNames => {
228
+ let queryFieldNamesForSliceQueryDb = (
229
+ ~plugin: string,
230
+ ~queryDbName: string,
231
+ ~connectionSpec: bool=true,
232
+ ): queryNames => {
210
233
  {
211
234
  singleFieldName: `${plugin}_${queryDbName}`,
212
235
  listFieldName: `${plugin}_${canonicalPlural(queryDbName)}`,
@@ -237,7 +237,9 @@ let deriveObjectTypeWithNested = (
237
237
  // — for every plugin in the merge, not just this one. Refuse at build time,
238
238
  // naming both halves.
239
239
  resolvedFields->Array.forEach(({fieldName}) =>
240
- if filteredFields->Dict.get(fieldName)->Option.isSome || (includeIdParam && fieldName == "id") {
240
+ if (
241
+ filteredFields->Dict.get(fieldName)->Option.isSome || (includeIdParam && fieldName == "id")
242
+ ) {
241
243
  JsError.throwWithMessage(
242
244
  `${typeName}.${fieldName} is declared by @resolves/@resolvesMany and is already a field of the state record. Name the resolved field something the state does not use.`,
243
245
  )
@@ -303,16 +305,15 @@ let rec scalarOfSchemaType = (st: SchemaType.schemaType): string =>
303
305
  // `SchemaType.isIdFieldName`, which lowercases before testing the suffix and so
304
306
  // accepts `paid` and `valid` — harmless where it is used, but here it would
305
307
  // nominate an ordinary word as a row's key.
306
- let isKeyFieldName = (name: string): bool =>
307
- name->String.length > 2 && name->String.endsWith("Id")
308
+ let isKeyFieldName = (name: string): bool => name->String.length > 2 && name->String.endsWith("Id")
308
309
 
309
310
  /** What the ladder below concluded. The two ways to have no key are opposite
310
311
  mistakes, so they are kept apart rather than collapsed into `None`. */
311
312
  type keyFieldResolution =
312
313
  | Resolved({field: string, rung: string})
313
- | /** Several `*Id` fields and none matching the name — usually a field
314
+ /** Several `*Id` fields and none matching the name — usually a field
314
315
  somebody added to a view that used to have exactly one. */
315
- Ambiguous({candidates: array<string>, conventional: string})
316
+ | Ambiguous({candidates: array<string>, conventional: string})
316
317
  | NoCandidate
317
318
 
318
319
  /**
@@ -384,8 +385,7 @@ let keyFieldGapMessage = (resolution: keyFieldResolution): option<string> =>
384
385
  `has no row key: it declares no @id and its \`*Id\` fields ` ++
385
386
  `(${candidates->Array.join(", ")}) include no "${conventional}" for the name to ` ++
386
387
  `pick. Adding a second \`*Id\` field to a view that had one is what lands here, ` ++
387
- `and it costs the view its filter and its whole orderBy in the schema. Declare ` ++
388
- `@id on the field that identifies a row.`,
388
+ `and it costs the view its filter and its whole orderBy in the schema. Declare ` ++ `@id on the field that identifies a row.`,
389
389
  )
390
390
  }
391
391
 
@@ -497,15 +497,14 @@ let deriveConnectionFilterType = (
497
497
  ~capability: serverCapability=emptyCapability,
498
498
  ): string => {
499
499
  let baseFields = ["search: String", "searchPrefix: String", "ids: [ID!]"]
500
- let perFieldFilters =
501
- capability.filterFields->Array.flatMap(f => {
502
- let eq = `${f.name}Eq: ${f.gqlType}`
503
- if f.range {
504
- [eq, `${f.name}From: ${f.gqlType}`, `${f.name}To: ${f.gqlType}`]
505
- } else {
506
- [eq]
507
- }
508
- })
500
+ let perFieldFilters = capability.filterFields->Array.flatMap(f => {
501
+ let eq = `${f.name}Eq: ${f.gqlType}`
502
+ if f.range {
503
+ [eq, `${f.name}From: ${f.gqlType}`, `${f.name}To: ${f.gqlType}`]
504
+ } else {
505
+ [eq]
506
+ }
507
+ })
509
508
  let allFields = Array.concat(baseFields, perFieldFilters)
510
509
  let body = allFields->Array.map(f => ` ${f}`)->Array.join("\n")
511
510
  `input ${filterTypeName} {\n${body}\n}`
@@ -514,10 +513,9 @@ let deriveConnectionFilterType = (
514
513
  // Emits an `enum <Type>OrderField` and `input <Type>OrderBy` pair when the
515
514
  // capability has any sort fields. Returns [] when no field is sortable so
516
515
  // the connection field doesn't reference a non-existent OrderBy type.
517
- let deriveConnectionOrderByType = (
518
- ~singularTypeName: string,
519
- ~capability: serverCapability,
520
- ): array<string> =>
516
+ let deriveConnectionOrderByType = (~singularTypeName: string, ~capability: serverCapability): array<
517
+ string,
518
+ > =>
521
519
  if capability.sortFields->Array.length == 0 {
522
520
  []
523
521
  } else {
@@ -561,10 +559,7 @@ let deriveObjectQueryField = (
561
559
  ` ${singleFieldName}: ${typeName}`
562
560
  }
563
561
 
564
- let deriveListQueryField = (
565
- ~listFieldName: string,
566
- ~pluralTypeName: string,
567
- ): string =>
562
+ let deriveListQueryField = (~listFieldName: string, ~pluralTypeName: string): string =>
568
563
  ` ${listFieldName}(nextToken: String, limit: Int): ${pluralTypeName}!`
569
564
 
570
565
  // Batched-by-ids query: fetches multiple entities in a single BatchGetItem.
@@ -572,10 +567,7 @@ let deriveListQueryField = (
572
567
  // caller correlates by `id` on each returned item. Single-key tables only —
573
568
  // composite-key BatchGetItem requires both pk + sk per key entry, which is
574
569
  // out of scope for this field.
575
- let deriveByIdsQueryField = (
576
- ~listFieldName: string,
577
- ~returnTypeName: string,
578
- ): string =>
570
+ let deriveByIdsQueryField = (~listFieldName: string, ~returnTypeName: string): string =>
579
571
  ` ${listFieldName}ByIds(ids: [String!]!, includeRetired: Boolean): [${returnTypeName}!]!`
580
572
 
581
573
  // ── The reference door ─────────────────────────────────────────────────────
@@ -614,10 +606,8 @@ let deriveRefTypeSdl = (~returnTypeName: string): string =>
614
606
  // `retiredState` is null in two cases that do not need telling apart by a
615
607
  // consumer: a live row, and a boolean-form retirement, where the field is the
616
608
  // state and `retired: true` has already said everything there is to say.
617
- let deriveRefsQueryField = (
618
- ~listFieldName: string,
619
- ~returnTypeName: string,
620
- ): string => ` ${listFieldName}Refs(ids: [ID!]!): [${returnTypeName}Ref!]!`
609
+ let deriveRefsQueryField = (~listFieldName: string, ~returnTypeName: string): string =>
610
+ ` ${listFieldName}Refs(ids: [ID!]!): [${returnTypeName}Ref!]!`
621
611
 
622
612
  // `includeRetired` sits beside the paging arguments rather than inside `filter`,
623
613
  // and that placement is the point. `filter` is the caller's description of the
@@ -751,10 +741,7 @@ let mutationArgTypes = (~fieldName: string, variantSchema: S.t<unknown>): option
751
741
  fields
752
742
  ->Dict.toArray
753
743
  ->Array.forEach(((argName, argType)) =>
754
- out->Dict.set(
755
- argName,
756
- fromSchemaType(~required=true, ~asInput=true, argType, [], Set.make()),
757
- )
744
+ out->Dict.set(argName, fromSchemaType(~required=true, ~asInput=true, argType, [], Set.make()))
758
745
  )
759
746
  out
760
747
  })
@@ -774,8 +761,10 @@ let generate = (
774
761
  // `Plugin_Activate` / `Platform_Plugin_Activate` — always the last
775
762
  // underscore-separated segment (e.g. `Activate`).
776
763
  let constructorNameOf = (fieldName: string): string =>
777
- fieldName->String.split("_")->Array.get(fieldName->String.split("_")->Array.length - 1)
778
- ->Option.getOr(fieldName)
764
+ fieldName
765
+ ->String.split("_")
766
+ ->Array.get(fieldName->String.split("_")->Array.length - 1)
767
+ ->Option.getOr(fieldName)
779
768
 
780
769
  mutationEntries->Array.forEach(entry => {
781
770
  let schema = entry.commandSchema
@@ -803,9 +792,8 @@ let generate = (
803
792
  entry.fieldNames->Array.forEach(fieldName => {
804
793
  let cname = constructorNameOf(fieldName)
805
794
  let variantIndex = variantNames->Array.indexOf(cname)
806
- let variantSchema = variantIndex >= 0
807
- ? anyOf->Array.get(variantIndex)->Option.getOr(schema)
808
- : schema
795
+ let variantSchema =
796
+ variantIndex >= 0 ? anyOf->Array.get(variantIndex)->Option.getOr(schema) : schema
809
797
  switch deriveMutationFieldFromObject(
810
798
  ~fieldName,
811
799
  ~collectedTypes=types,
@@ -838,8 +826,7 @@ let generate = (
838
826
  ~collectedTypes=types,
839
827
  ~seenTypes,
840
828
  schema,
841
- )
842
- ->Option.forEach(field => mutations->Array.push(field))
829
+ )->Option.forEach(field => mutations->Array.push(field))
843
830
  }
844
831
  | _ => ()
845
832
  }
@@ -984,8 +971,9 @@ let generate = (
984
971
  let edgeName = entry.returnTypeName ++ "Edge"
985
972
  seenTypes->Set.add(edgeName)
986
973
  seenTypes->Set.add(connectionTypeName)
987
- deriveConnectionTypes(~singularTypeName=entry.returnTypeName)
988
- ->Array.forEach(t => types->Array.push(t))
974
+ deriveConnectionTypes(~singularTypeName=entry.returnTypeName)->Array.forEach(t =>
975
+ types->Array.push(t)
976
+ )
989
977
  }
990
978
  let capability = deriveServerCapability(~entityName=entityNameOf(entry), entry.stateSchema)
991
979
  let connectionFilterTypeName = entry.returnTypeName ++ "Filter"
@@ -995,8 +983,10 @@ let generate = (
995
983
  deriveConnectionFilterType(~filterTypeName=connectionFilterTypeName, ~capability),
996
984
  )
997
985
  }
998
- let orderByTypes =
999
- deriveConnectionOrderByType(~singularTypeName=entry.returnTypeName, ~capability)
986
+ let orderByTypes = deriveConnectionOrderByType(
987
+ ~singularTypeName=entry.returnTypeName,
988
+ ~capability,
989
+ )
1000
990
  let hasOrderBy = orderByTypes->Array.length > 0
1001
991
  if hasOrderBy {
1002
992
  let orderFieldEnumName = entry.returnTypeName ++ "OrderField"
@@ -1024,10 +1014,7 @@ let generate = (
1024
1014
  )
1025
1015
  types->Array.push(pluralType)
1026
1016
  }
1027
- let listField = deriveListQueryField(
1028
- ~listFieldName,
1029
- ~pluralTypeName=listFieldName,
1030
- )
1017
+ let listField = deriveListQueryField(~listFieldName, ~pluralTypeName=listFieldName)
1031
1018
  queries->Array.push(listField)
1032
1019
  }
1033
1020
  })