@reventlessdev/reventless-local 3.0.0-alpha.248 → 3.0.0-alpha.250

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 (170) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +14 -14
  3. package/src/BakedManifest.res +5 -6
  4. package/src/EmitCapabilities.res +3 -1
  5. package/src/LocalPlatformRegistry.res +3 -1
  6. package/src/LocalPlatformStart.res +7 -6
  7. package/src/LocalSeedTarget.res +3 -1
  8. package/src/Platform.res +291 -215
  9. package/src/ShellConfig.res +10 -17
  10. package/src/UiHints.res +8 -14
  11. package/src/UiSlots.res +10 -17
  12. package/src/adapter/Api/LocalEvents_Server.res +5 -3
  13. package/src/adapter/Api/LocalGraphQL_Adapter.res +4 -4
  14. package/src/adapter/Auth/LocalAuth.res +11 -15
  15. package/src/adapter/Auth/UserStore.res +5 -7
  16. package/src/adapter/Backend.res +1 -2
  17. package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +42 -26
  18. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +13 -3
  19. package/src/adapter/CommandTopic/LocalCommandTopicChannel.res +15 -17
  20. package/src/adapter/CommandTopic/LocalCommandTopicRemoteChannel.res +18 -22
  21. package/src/adapter/Counter/LocalCounterHandler.res +1 -1
  22. package/src/adapter/DcbEventLog/DcbEventLogStorage_InMemory.res +33 -22
  23. package/src/adapter/DcbEventLog/DcbEventLogStorage_Sqlite.res +57 -57
  24. package/src/adapter/DomainGraphQL_Server.res +35 -34
  25. package/src/adapter/DomainMCP_Server.res +45 -41
  26. package/src/adapter/EventCollector/LocalEventCollectorChannel.res +47 -36
  27. package/src/adapter/EventHistory/EventHistoryResolvers_GraphQL.res +15 -12
  28. package/src/adapter/EventLog/EventLogStorage_InMemory.res +9 -4
  29. package/src/adapter/EventLog/EventLogStorage_Sqlite.res +36 -24
  30. package/src/adapter/EventTopic/LocalEventTopicPublisher.res +9 -3
  31. package/src/adapter/Heartbeat/LocalHeartbeatRunner.res +9 -14
  32. package/src/adapter/LocalBus.res +12 -12
  33. package/src/adapter/LocalCapabilities.res.mjs +1 -1
  34. package/src/adapter/LocalGeocodeResolvers.res +1 -4
  35. package/src/adapter/LocalSideEffectHandler.res +1 -1
  36. package/src/adapter/LocalStateChangeDescriptor.res +2 -1
  37. package/src/adapter/MCP_ServerInstance.res +51 -39
  38. package/src/adapter/ObjectStore/LocalObjectStore.res +5 -2
  39. package/src/adapter/ObjectStore/ObjectStoreStorage_FileSystem.res +1 -2
  40. package/src/adapter/PlatformGraphQL_Server.res +9 -5
  41. package/src/adapter/ProjectionCheckpoint.res +8 -1
  42. package/src/adapter/ProjectionPending.res +1 -3
  43. package/src/adapter/QueryDb/LocalQueryDbStorage.res +2 -1
  44. package/src/adapter/QueryDb/QueryDbResolvers_GraphQL.res +367 -269
  45. package/src/adapter/QueryDb/QueryDbStorage_InMemory.res +5 -3
  46. package/src/adapter/QueryDb/QueryDbStorage_Sqlite.res +63 -40
  47. package/src/adapter/QueryDb/SortKey_Filter.res +14 -6
  48. package/src/adapter/Runtime/LocalAggregateRuntime_Builder.res +12 -10
  49. package/src/adapter/Runtime/LocalEventCollectorRuntime_Builder.res +8 -2
  50. package/src/adapter/Runtime/LocalPluginRuntime_Builder.res +1 -4
  51. package/src/adapter/Scheduler/LocalScheduledPublisher.res +12 -12
  52. package/src/adapter/SqliteDriver.res +16 -4
  53. package/src/adapter/Task/TaskBucket_Sqlite.res +5 -6
  54. package/src/components/Aggregate_Builder.res +6 -1
  55. package/src/components/Counter_Builder.res +1 -5
  56. package/src/components/DcbEventLog_Builder.res +5 -3
  57. package/src/components/ExtensionPoint_Builder.res +13 -15
  58. package/src/components/InboundTranslationSlice_Builder.res +3 -2
  59. package/src/components/OutboundTranslationSlice_Builder.res +3 -2
  60. package/src/components/ReadModel_Builder.res +18 -20
  61. package/src/components/StateViewSlice_Builder.res +3 -2
  62. package/src/components/Task_Builder.res +12 -13
  63. package/src/reset/LocalSeedReset.res +2 -5
  64. package/src/test/Mocks/MockDcbEventLogStorage.res +5 -1
  65. package/src/test/Mocks/MockEventLogStorage.res +8 -3
  66. package/src/test/Mocks/MockQueryDbStorage.res +3 -2
  67. package/src/test/TestRunner.res +1 -1
  68. package/tests/BakedManifestFilesTest.res +7 -10
  69. package/tests/LocalEventTapTest.res +26 -21
  70. package/tests/LocalPlatformStartTest.res +33 -28
  71. package/tests/PluginEventDecodeTest.res +3 -3
  72. package/tests/ShellConfigTest.res +30 -21
  73. package/tests/SplitApiFixtures.res +34 -10
  74. package/tests/SplitApiTest.res +92 -62
  75. package/tests/adapter/BackendParityTest.res +180 -130
  76. package/tests/adapter/CollectNEventsTest.res +6 -4
  77. package/tests/adapter/CommandAuthorizationTest.res +47 -41
  78. package/tests/adapter/CommandTopicChannelTest.res +163 -139
  79. package/tests/adapter/CounterHandlerTest.res +95 -77
  80. package/tests/adapter/DcbEventLogStorageSqliteTest.res +171 -168
  81. package/tests/adapter/DcbEventLogStorageTest.res +264 -207
  82. package/tests/adapter/DomainGraphQL_ServerTest.res +53 -43
  83. package/tests/adapter/EventCollectorChannelTest.res +153 -124
  84. package/tests/adapter/EventHistoryResolverTest.res +46 -18
  85. package/tests/adapter/EventLogSnapshotParityTest.res +57 -45
  86. package/tests/adapter/EventLogStorageSqliteTest.res +9 -10
  87. package/tests/adapter/EventTapTest.res +37 -20
  88. package/tests/adapter/EventTopicPublisherTest.res +74 -50
  89. package/tests/adapter/GraphQLSubscriptionBridgeTest.res +4 -3
  90. package/tests/adapter/GraphQL_SchemaInspectorTest.res +666 -568
  91. package/tests/adapter/GraphQL_SubscriptionResolversTest.res +105 -96
  92. package/tests/adapter/HeartbeatRunnerTest.res +99 -81
  93. package/tests/adapter/InboundTranslationMutationTest.res +4 -1
  94. package/tests/adapter/LocalAuthHttpTest.res +79 -85
  95. package/tests/adapter/LocalAuthLoginTest.res +42 -50
  96. package/tests/adapter/LocalAuthTest.res +8 -16
  97. package/tests/adapter/LocalAuthUserStoreTest.res +2 -7
  98. package/tests/adapter/LocalBusBoundedTest.res +187 -117
  99. package/tests/adapter/LocalBusPubSubTest.res +118 -76
  100. package/tests/adapter/LocalDispatchContextTest.res +1 -2
  101. package/tests/adapter/LocalEvents_ServerTest.res +242 -187
  102. package/tests/adapter/PgProjectionCatchupTest.res +44 -10
  103. package/tests/adapter/ProjectionCheckpointTest.res +261 -206
  104. package/tests/adapter/QueryDbGsiTtlTest.res +123 -83
  105. package/tests/adapter/QueryDbListPushdownParityTest.res +107 -67
  106. package/tests/adapter/QueryDbListResolverTest.res +225 -208
  107. package/tests/adapter/QueryDbResolvedFieldsTest.res +17 -14
  108. package/tests/adapter/QueryDbStorageSqliteTest.res +33 -49
  109. package/tests/adapter/QueryDbStorageTest.res +163 -117
  110. package/tests/adapter/QueryDbUnionRoundTripTest.res +8 -10
  111. package/tests/adapter/QueryEngineTest.res +179 -126
  112. package/tests/adapter/ScheduledPublisherTest.res +171 -135
  113. package/tests/adapter/ServedBucketHttpTest.res +65 -59
  114. package/tests/adapter/SortKey_FilterTest.res +19 -3
  115. package/tests/adapter/SqliteDriverTest.res +13 -10
  116. package/tests/adapter/TaskBucketTest.res +94 -80
  117. package/tests/components/aggregate/AggregateTest.res +31 -18
  118. package/tests/components/automationslice/AutomationSliceCallbackTest.res +259 -222
  119. package/tests/components/automationslice/AutomationSliceFixtures.res +4 -2
  120. package/tests/components/automationslice/AutomationSliceSelfDeadlockFixtures.res +38 -38
  121. package/tests/components/automationslice/MixedSourceAutomationSliceFixtures.res +12 -14
  122. package/tests/components/automationslice/MixedSourceAutomationSliceTest.res +8 -32
  123. package/tests/components/commandgenerator/CommandGeneratorFixtures.res +7 -5
  124. package/tests/components/commandgenerator/CommandGeneratorTest.res +40 -31
  125. package/tests/components/commandtopic/CommandTopicFixtures.res +3 -4
  126. package/tests/components/commandtopic/CommandTopicStreamFixtures.res +7 -5
  127. package/tests/components/commandtopic/CommandTopicTest.res +24 -15
  128. package/tests/components/counter/CounterFixtures.res +6 -8
  129. package/tests/components/dcb/DcbCrossPartitionFixtures.res +8 -2
  130. package/tests/components/dcb/DcbCrossPartitionReadTest.res +20 -13
  131. package/tests/components/dcb/DcbEventLogAppendStreamTest.res +12 -8
  132. package/tests/components/dcb/DcbEventLogStreamTest.res +88 -61
  133. package/tests/components/dcb/DcbFixtures.res +4 -1
  134. package/tests/components/dcb/DcbTest.res +9 -6
  135. package/tests/components/eventcollector/EventCollectorFixtures.res +0 -1
  136. package/tests/components/eventcollector/EventCollectorTest.res +6 -3
  137. package/tests/components/eventlog/EventLogAppendStreamTest.res +88 -68
  138. package/tests/components/eventlog/EventLogConflictTest.res +8 -4
  139. package/tests/components/eventlog/EventLogFixtures.res +3 -3
  140. package/tests/components/eventlog/EventLogProvisioningSeamTest.res +26 -13
  141. package/tests/components/eventlog/EventLogStreamTest.res +119 -56
  142. package/tests/components/eventlog/EventLogTest.res +20 -4
  143. package/tests/components/eventtopic/EventTopicFixtures.res +3 -3
  144. package/tests/components/eventtopic/EventTopicStreamFixtures.res +1 -2
  145. package/tests/components/eventtopic/EventTopicStreamTest.res +7 -1
  146. package/tests/components/extensionpoint/ExtensionPointFixtures.res +14 -9
  147. package/tests/components/extensionpoint/ExtensionPointTest.res +3 -2
  148. package/tests/components/heartbeat/HeartbeatFixtures.res +5 -6
  149. package/tests/components/heartbeat/HeartbeatTest.res +56 -47
  150. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +271 -249
  151. package/tests/components/inboundtranslationslice/InboundTranslationSliceFixtures.res +3 -2
  152. package/tests/components/outboundtranslationslice/OutboundTranslationSliceCallbackTest.res +361 -276
  153. package/tests/components/outboundtranslationslice/OutboundTranslationSliceFixtures.res +8 -10
  154. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +37 -43
  155. package/tests/components/querydb/QueryDbFixtures.res +1 -5
  156. package/tests/components/querydb/QueryDbTest.res +2 -4
  157. package/tests/components/readmodel/DcbReadModelE2EFixtures.res +15 -18
  158. package/tests/components/readmodel/MixedSourceReadModelFixtures.res +5 -7
  159. package/tests/components/readmodel/ReadModelFixtures.res +8 -8
  160. package/tests/components/scheduler/SchedulerTest.res +76 -58
  161. package/tests/components/sideeffecthandler/SideEffectHandlerFixtures.res +4 -4
  162. package/tests/components/stateviewslice/StateViewSliceDisplayNameFixtures.res +5 -7
  163. package/tests/components/stateviewslice/StateViewSliceFixtures.res +8 -6
  164. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +17 -11
  165. package/tests/components/stateviewslice/StateViewSliceSubIdTest.res +12 -2
  166. package/tests/components/task/TaskFixtures.res +5 -5
  167. package/tests/components/task/TaskTest.res +95 -80
  168. package/tests/plugin/PluginsProjection_GWT.res +3 -1
  169. package/tests/plugin/UiFragments_GWT.res +6 -1
  170. package/tests/reset/LocalSeedResetTest.res +1 -0
@@ -73,7 +73,8 @@ module Make = (Bus: LocalBus.T) => {
73
73
  ~ttl as _=?,
74
74
  ~api as _,
75
75
  ~apiRole as _,
76
- ~owner as _, ~opts as _,
76
+ ~owner as _,
77
+ ~opts as _,
77
78
  ) => {
78
79
  let store: ref<dict<dict<JSON.t>>> = ref(Dict.make())
79
80
  // Lazy flattened snapshot for the registered scan/stream closures. The old
@@ -199,7 +200,9 @@ module Make = (Bus: LocalBus.T) => {
199
200
  ~state=Some(state),
200
201
  ~seq=LocalStateChangeDescriptor.nextSequence(),
201
202
  ~retiredField=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.map(r => r.field),
202
- ~retiredValues=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.flatMap(r => r.values),
203
+ ~retiredValues=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.flatMap(r =>
204
+ r.values
205
+ ),
203
206
  )
204
207
  Bus.publishStateChange(~name, ~descriptor)
205
208
  }
@@ -367,5 +370,4 @@ module Make = (Bus: LocalBus.T) => {
367
370
  operations: Pulumi.Output.make(ops),
368
371
  }
369
372
  }
370
-
371
373
  }
@@ -31,8 +31,8 @@ let sanitizeIdent = (s: string): string =>
31
31
  let code = ch->String.codePointAt(0)->Option.getOr(0)
32
32
  let isAlphaNum =
33
33
  (code >= 48 && code <= 57) ||
34
- (code >= 65 && code <= 90) ||
35
- (code >= 97 && code <= 122) ||
34
+ code >= 65 && code <= 90 ||
35
+ code >= 97 && code <= 122 ||
36
36
  code == 95
37
37
  isAlphaNum ? ch : "_"
38
38
  })
@@ -64,8 +64,7 @@ let compositeExpr = (fields: array<string>, sep: string): string => {
64
64
  // Uses pkFields if present, else falls back to idField; same for sub key.
65
65
  let indexExpressions = (idx: indexConfig): (string, option<string>) => {
66
66
  let pkExpr = switch idx.pkFields {
67
- | Some(fields) if fields->Array.length > 0 =>
68
- compositeExpr(fields, idx.pkSep->Option.getOr("/"))
67
+ | Some(fields) if fields->Array.length > 0 => compositeExpr(fields, idx.pkSep->Option.getOr("/"))
69
68
  | _ =>
70
69
  switch idx.idField {
71
70
  | Some(field) => jsonField(field)
@@ -168,30 +167,32 @@ let makeStorage = (
168
167
  ensureExpiresColumn(~db, ~table)
169
168
  ensureIndexes(~db, ~table, ~indexes)
170
169
 
171
- let upsertStmt = db->SqliteDriver.prepare(
172
- `INSERT INTO ${table}(partition_key, sub_key, item, expires_at) VALUES(?,?,?,?) ON CONFLICT(partition_key, sub_key) DO UPDATE SET item = excluded.item, expires_at = excluded.expires_at`,
173
- )
174
- let selectByPartitionStmt = db->SqliteDriver.prepare(
175
- `SELECT partition_key, sub_key, item FROM ${table} WHERE partition_key = ? AND ${notExpiredClause} ORDER BY sub_key ASC`,
176
- )
177
- let deleteByPartitionStmt = db->SqliteDriver.prepare(
178
- `DELETE FROM ${table} WHERE partition_key = ?`,
179
- )
180
- let deleteBySubKeyStmt = db->SqliteDriver.prepare(
181
- `DELETE FROM ${table} WHERE partition_key = ? AND sub_key = ?`,
182
- )
183
- let scanAllStmt = db->SqliteDriver.prepare(
184
- `SELECT partition_key, sub_key, item FROM ${table} WHERE ${notExpiredClause} ORDER BY partition_key, sub_key`,
185
- )
170
+ let upsertStmt =
171
+ db->SqliteDriver.prepare(
172
+ `INSERT INTO ${table}(partition_key, sub_key, item, expires_at) VALUES(?,?,?,?) ON CONFLICT(partition_key, sub_key) DO UPDATE SET item = excluded.item, expires_at = excluded.expires_at`,
173
+ )
174
+ let selectByPartitionStmt =
175
+ db->SqliteDriver.prepare(
176
+ `SELECT partition_key, sub_key, item FROM ${table} WHERE partition_key = ? AND ${notExpiredClause} ORDER BY sub_key ASC`,
177
+ )
178
+ let deleteByPartitionStmt =
179
+ db->SqliteDriver.prepare(`DELETE FROM ${table} WHERE partition_key = ?`)
180
+ let deleteBySubKeyStmt =
181
+ db->SqliteDriver.prepare(`DELETE FROM ${table} WHERE partition_key = ? AND sub_key = ?`)
182
+ let scanAllStmt =
183
+ db->SqliteDriver.prepare(
184
+ `SELECT partition_key, sub_key, item FROM ${table} WHERE ${notExpiredClause} ORDER BY partition_key, sub_key`,
185
+ )
186
186
  // First-insert detection. DynamoDB streams hand the AWS StateTopic Lambda an
187
187
  // eventName that separates INSERT from MODIFY; an upsert reports neither, so
188
188
  // ask the table before writing. Carries `notExpiredClause` because that is what
189
189
  // a reader sees: a row aged past its TTL is invisible to them, so overwriting
190
190
  // it is an insert — the same descriptor pair (Removed, then Added) DynamoDB
191
191
  // emits when a TTL delete is followed by a fresh Put.
192
- let existsStmt = db->SqliteDriver.prepare(
193
- `SELECT 1 FROM ${table} WHERE partition_key = ? AND sub_key = ? AND ${notExpiredClause} LIMIT 1`,
194
- )
192
+ let existsStmt =
193
+ db->SqliteDriver.prepare(
194
+ `SELECT 1 FROM ${table} WHERE partition_key = ? AND sub_key = ? AND ${notExpiredClause} LIMIT 1`,
195
+ )
195
196
 
196
197
  let rowsFor = (id: string): array<JSON.t> =>
197
198
  selectByPartitionStmt
@@ -222,9 +223,10 @@ let makeStorage = (
222
223
  // Escape single quotes in the JSON path literal so an odd field name can't
223
224
  // break out of the string (bound `?` already covers the value).
224
225
  let escapedField = field->String.replaceAll("'", "''")
225
- let s = db->SqliteDriver.prepare(
226
- `SELECT partition_key, sub_key, item FROM ${table} WHERE json_extract(item, '$.${escapedField}') = ? AND ${notExpiredClause}`,
227
- )
226
+ let s =
227
+ db->SqliteDriver.prepare(
228
+ `SELECT partition_key, sub_key, item FROM ${table} WHERE json_extract(item, '$.${escapedField}') = ? AND ${notExpiredClause}`,
229
+ )
228
230
  indexLookupStmts->Dict.set(field, s)
229
231
  s
230
232
  }
@@ -265,7 +267,9 @@ let makeStorage = (
265
267
  ~state=Some(state),
266
268
  ~seq=LocalStateChangeDescriptor.nextSequence(),
267
269
  ~retiredField=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.map(r => r.field),
268
- ~retiredValues=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.flatMap(r => r.values),
270
+ ~retiredValues=?LocalStateChangeDescriptor.retiredSpecFor(name)->Option.flatMap(r =>
271
+ r.values
272
+ ),
269
273
  )
270
274
  bus.publishStateChange(~name, ~descriptor)
271
275
  }
@@ -358,10 +362,7 @@ let makeStorage = (
358
362
  switch subIdOpt {
359
363
  | None => deleteByPartitionStmt->SqliteDriver.run([JSON.Encode.string(id)])
360
364
  | Some((_, subValue)) =>
361
- deleteBySubKeyStmt->SqliteDriver.run([
362
- JSON.Encode.string(id),
363
- JSON.Encode.string(subValue),
364
- ])
365
+ deleteBySubKeyStmt->SqliteDriver.run([JSON.Encode.string(id), JSON.Encode.string(subValue)])
365
366
  }
366
367
 
367
368
  let delete: QueryDb.delete<string> = async (id, subIdOpt) => {
@@ -436,12 +437,24 @@ let makeStorage = (
436
437
  let filterDict =
437
438
  argsDict->Dict.get("filter")->Option.flatMap(JSON.Decode.object)->Option.getOr(Dict.make())
438
439
  let strNonEmpty = k =>
439
- filterDict->Dict.get(k)->Option.flatMap(JSON.Decode.string)->Option.mapOr(false, s => s->String.length > 0)
440
+ filterDict
441
+ ->Dict.get(k)
442
+ ->Option.flatMap(JSON.Decode.string)
443
+ ->Option.mapOr(false, s => s->String.length > 0)
440
444
  let hasIds =
441
- filterDict->Dict.get("ids")->Option.flatMap(JSON.Decode.array)->Option.mapOr(false, a => a->Array.length > 0)
445
+ filterDict
446
+ ->Dict.get("ids")
447
+ ->Option.flatMap(JSON.Decode.array)
448
+ ->Option.mapOr(false, a => a->Array.length > 0)
442
449
  let last = argsDict->Dict.get("last")->Option.flatMap(JSON.Decode.float)
443
450
  let before = argsDict->Dict.get("before")->Option.flatMap(JSON.Decode.string)
444
- if strNonEmpty("search") || strNonEmpty("searchPrefix") || hasIds || last->Option.isSome || before->Option.isSome {
451
+ if (
452
+ strNonEmpty("search") ||
453
+ strNonEmpty("searchPrefix") ||
454
+ hasIds ||
455
+ last->Option.isSome ||
456
+ before->Option.isSome
457
+ ) {
445
458
  None
446
459
  } else {
447
460
  let whereParts = [notExpiredClause]
@@ -495,20 +508,20 @@ let makeStorage = (
495
508
  }
496
509
  capability.filterFields->Array.forEach(f => {
497
510
  switch filterDict->Dict.get(f.name ++ "Eq") {
498
- | Some(v) when v != JSON.Encode.null =>
511
+ | Some(v) if v != JSON.Encode.null =>
499
512
  whereParts->Array.push(`${jsonText(f.name)} = ?`)
500
513
  params->Array.push(JSON.Encode.string(valString(v)->Option.getOr("")))
501
514
  | _ => ()
502
515
  }
503
516
  if f.range {
504
517
  switch filterDict->Dict.get(f.name ++ "From") {
505
- | Some(v) when v != JSON.Encode.null =>
518
+ | Some(v) if v != JSON.Encode.null =>
506
519
  whereParts->Array.push(`${jsonText(f.name)} >= ?`)
507
520
  params->Array.push(JSON.Encode.string(valString(v)->Option.getOr("")))
508
521
  | _ => ()
509
522
  }
510
523
  switch filterDict->Dict.get(f.name ++ "To") {
511
- | Some(v) when v != JSON.Encode.null =>
524
+ | Some(v) if v != JSON.Encode.null =>
512
525
  whereParts->Array.push(`${jsonText(f.name)} <= ?`)
513
526
  params->Array.push(JSON.Encode.string(valString(v)->Option.getOr("")))
514
527
  | _ => ()
@@ -551,7 +564,9 @@ let makeStorage = (
551
564
  ->Option.flatMap(JSON.Decode.float)
552
565
  ->Option.map(Float.toInt)
553
566
  ->Option.getOr(QueryDbListQuery.defaultListPageSize)
554
- let sql = `SELECT partition_key, item FROM ${table} WHERE ${whereParts->Array.join(" AND ")} ORDER BY ${orderClause} LIMIT ?`
567
+ let sql = `SELECT partition_key, item FROM ${table} WHERE ${whereParts->Array.join(
568
+ " AND ",
569
+ )} ORDER BY ${orderClause} LIMIT ?`
555
570
  let rows =
556
571
  preparedList(sql)
557
572
  ->SqliteDriver.all(params->Array.concat([JSON.Encode.int(pageSize + 1)]))
@@ -560,7 +575,9 @@ let makeStorage = (
560
575
  let pageItems = rows->Array.slice(~start=0, ~end=pageSize)
561
576
  let cursorField = orderByField->Option.getOr("id")
562
577
  let cursorValueOf = item =>
563
- QueryDbListQuery.getFieldString(item, cursorField)->Option.getOr(QueryDbListQuery.getId(item))
578
+ QueryDbListQuery.getFieldString(item, cursorField)->Option.getOr(
579
+ QueryDbListQuery.getId(item),
580
+ )
564
581
  Some(
565
582
  QueryDbListQuery.buildConnection(
566
583
  ~pageItems,
@@ -583,7 +600,12 @@ let makeStorage = (
583
600
  }
584
601
  }
585
602
 
586
- module Make = (Bus: LocalBus.T, DbProvider: {let db: SqliteDriver.t}) => {
603
+ module Make = (
604
+ Bus: LocalBus.T,
605
+ DbProvider: {
606
+ let db: SqliteDriver.t
607
+ },
608
+ ) => {
587
609
  type api = unit
588
610
  type role = unit
589
611
 
@@ -603,6 +625,7 @@ module Make = (Bus: LocalBus.T, DbProvider: {let db: SqliteDriver.t}) => {
603
625
  ~ttl as _=?,
604
626
  ~api as _,
605
627
  ~apiRole as _,
606
- ~owner as _, ~opts as _,
628
+ ~owner as _,
629
+ ~opts as _,
607
630
  ) => makeStorage(~db=DbProvider.db, ~bus=busCallbacks, ~name, ~indexes, ~subIdField)
608
631
  }
@@ -9,7 +9,11 @@ type result = {
9
9
 
10
10
  /** Extract the sort key string from a JSON item using the given field name. */
11
11
  let getSk = (item, skField) =>
12
- item->JSON.Decode.object->Option.flatMap(d => d->Dict.get(skField))->Option.flatMap(JSON.Decode.string)->Option.getOr("")
12
+ item
13
+ ->JSON.Decode.object
14
+ ->Option.flatMap(d => d->Dict.get(skField))
15
+ ->Option.flatMap(JSON.Decode.string)
16
+ ->Option.getOr("")
13
17
 
14
18
  /** Apply sort key conditions, ordering, and pagination to a list of JSON items.
15
19
  - `items` must already be sorted ascending by sort key.
@@ -28,12 +32,16 @@ let apply = (
28
32
  let filtered = items->Array.filter(item => {
29
33
  let sk = getSk(item, skField)
30
34
  let okPrefix = prefix->Option.map(p => sk->String.startsWith(p))->Option.getOr(true)
31
- let okFrom = from->Option.map(f => sk >= f)->Option.getOr(true)
32
- let okTo = to_->Option.map(t => sk <= t)->Option.getOr(true)
33
- let okEq = eq->Option.map(e => sk == e)->Option.getOr(true)
35
+ let okFrom = from->Option.map(f => sk >= f)->Option.getOr(true)
36
+ let okTo = to_->Option.map(t => sk <= t)->Option.getOr(true)
37
+ let okEq = eq->Option.map(e => sk == e)->Option.getOr(true)
34
38
  okPrefix && okFrom && okTo && okEq
35
39
  })
36
- let ordered = if reverse { filtered->Array.toReversed } else { filtered }
40
+ let ordered = if reverse {
41
+ filtered->Array.toReversed
42
+ } else {
43
+ filtered
44
+ }
37
45
  let sliced = ordered->Array.slice(~start=offset, ~end=ordered->Array.length)
38
46
  let (page, hasMore) = switch limit {
39
47
  | Some(n) => (sliced->Array.slice(~start=0, ~end=n), sliced->Array.length > n)
@@ -44,5 +52,5 @@ let apply = (
44
52
  } else {
45
53
  None
46
54
  }
47
- { items: page, nextToken }
55
+ {items: page, nextToken}
48
56
  }
@@ -32,7 +32,9 @@ module Make = (
32
32
  // runtime so the type is satisfied and future callers that need handlerRef will work.
33
33
  let resource = commandGenerator->ReventlessCore.Component.toPulumiResource
34
34
  let name =
35
- resource.name->ReventlessCore.ComponentType.nameOpt(ReventlessCore.CommandGenerator.componentType)
35
+ resource.name->ReventlessCore.ComponentType.nameOpt(
36
+ ReventlessCore.CommandGenerator.componentType,
37
+ )
36
38
  let runtime = LocalRuntimeEnvironment.make(
37
39
  ~name,
38
40
  ~handler=handler->Pulumi.Output.apply(h =>
@@ -50,13 +52,7 @@ module Make = (
50
52
  connect(~runtime)
51
53
  }
52
54
 
53
- let forCommandTopic = (
54
- ~handler,
55
- ~connect,
56
- ~memorySize as _=?,
57
- ~timeout as _=?,
58
- commandTopic,
59
- ) => {
55
+ let forCommandTopic = (~handler, ~connect, ~memorySize as _=?, ~timeout as _=?, commandTopic) => {
60
56
  let resource = commandTopic->ReventlessCore.Component.toPulumiResource
61
57
  let name =
62
58
  resource.name->ReventlessCore.ComponentType.nameOpt(ReventlessCore.CommandTopic.componentType)
@@ -87,7 +83,9 @@ module Make = (
87
83
  ) => {
88
84
  let resource = eventCollector->ReventlessCore.Component.toPulumiResource
89
85
  let name =
90
- resource.name->ReventlessCore.ComponentType.nameOpt(ReventlessCore.EventCollector.componentType)
86
+ resource.name->ReventlessCore.ComponentType.nameOpt(
87
+ ReventlessCore.EventCollector.componentType,
88
+ )
91
89
  // Same `comp` shape as the deployed dispatchers — see EventCollectorRuntime_Builder_Single.
92
90
  let comp = `EventCollector(${resource.name->Option.getOr("Unnamed")})`
93
91
  let opts = {Pulumi.ComponentResource.parent: resource}
@@ -108,7 +106,11 @@ module Make = (
108
106
  let _connectResources = EventCollectorChannel.connect(
109
107
  ~name,
110
108
  ~channelSpecs=[
111
- {channel: eventCollector->ReventlessCore.EventCollector_Adapter.channel, eventTopics, resources},
109
+ {
110
+ channel: eventCollector->ReventlessCore.EventCollector_Adapter.channel,
111
+ eventTopics,
112
+ resources,
113
+ },
112
114
  ],
113
115
  ~runtime,
114
116
  ~opts,
@@ -25,7 +25,9 @@ module Make = (
25
25
  ) => {
26
26
  let resource = eventCollector->ReventlessCore.Component.toPulumiResource
27
27
  let name =
28
- resource.name->ReventlessCore.ComponentType.nameOpt(ReventlessCore.EventCollector.componentType)
28
+ resource.name->ReventlessCore.ComponentType.nameOpt(
29
+ ReventlessCore.EventCollector.componentType,
30
+ )
29
31
  // Same `comp` shape as the deployed dispatchers — see EventCollectorRuntime_Builder_Single.
30
32
  let comp = `EventCollector(${resource.name->Option.getOr("Unnamed")})`
31
33
  let opts = {Pulumi.ComponentResource.parent: resource}
@@ -46,7 +48,11 @@ module Make = (
46
48
  let _connectResources = EventCollectorChannel.connect(
47
49
  ~name,
48
50
  ~channelSpecs=[
49
- {channel: eventCollector->ReventlessCore.EventCollector_Adapter.channel, eventTopics, resources},
51
+ {
52
+ channel: eventCollector->ReventlessCore.EventCollector_Adapter.channel,
53
+ eventTopics,
54
+ resources,
55
+ },
50
56
  ],
51
57
  ~runtime,
52
58
  ~opts,
@@ -4,8 +4,5 @@
4
4
  module Make = (Bus: LocalBus.T) => {
5
5
  module ECChannel = LocalEventCollectorChannel.Make(Bus)
6
6
 
7
- include ReventlessCore.PluginRuntime_Builder_Micro.Make(
8
- LocalRuntimeEnvironment,
9
- ECChannel,
10
- )
7
+ include ReventlessCore.PluginRuntime_Builder_Micro.Make(LocalRuntimeEnvironment, ECChannel)
11
8
  }
@@ -60,14 +60,12 @@ module Make = (Bus: LocalBus.T) => {
60
60
  | json => json
61
61
  | exception _ => schedule.payload->JSON.Encode.string
62
62
  }
63
- let fire = () =>
64
- Bus.publishEvent(topicName, "Scheduler", scheduleMeta, payloadJson)->ignore
65
- let handle =
66
- if schedule.rate->isSingleShot {
67
- setTimeoutJs(fire, 0)
68
- } else {
69
- setIntervalJs(fire, rateToMs(schedule.rate))
70
- }
63
+ let fire = () => Bus.publishEvent(topicName, "Scheduler", scheduleMeta, payloadJson)->ignore
64
+ let handle = if schedule.rate->isSingleShot {
65
+ setTimeoutJs(fire, 0)
66
+ } else {
67
+ setIntervalJs(fire, rateToMs(schedule.rate))
68
+ }
71
69
  activeTimers.contents->Dict.set(schedule.name, handle)
72
70
  }
73
71
 
@@ -87,10 +85,12 @@ module Make = (Bus: LocalBus.T) => {
87
85
  ~urn=""->Pulumi.Output.make,
88
86
  ~service="memory:InMemory"->Pulumi.Output.make,
89
87
  ),
90
- operations: ({
91
- createSchedule,
92
- deleteSchedule,
93
- }: ReventlessInfra.Scheduler.operations)->Pulumi.Output.make,
88
+ operations: (
89
+ {
90
+ createSchedule,
91
+ deleteSchedule,
92
+ }: ReventlessInfra.Scheduler.operations
93
+ )->Pulumi.Output.make,
94
94
  }
95
95
  }
96
96
 
@@ -14,10 +14,22 @@ external openDatabaseSync: string => t = "DatabaseSync"
14
14
  // node:sqlite accepts ...positional bound values. Use Function.prototype.apply
15
15
  // via a small inline helper so the array is splatted without ReScript's
16
16
  // `@send` syntax accidentally treating `run.apply` as a single property name.
17
- let _runApply: (statement, array<JSON.t>) => unit = %raw(`function(s, a) { return s.run.apply(s, a); }`)
18
- let _getApply: (statement, array<JSON.t>) => Nullable.t<dict<JSON.t>> = %raw(`function(s, a) { return s.get.apply(s, a); }`)
19
- let _allApply: (statement, array<JSON.t>) => array<dict<JSON.t>> = %raw(`function(s, a) { return s.all.apply(s, a); }`)
20
- let _iterateApply: (statement, array<JSON.t>) => Iterator.t<dict<JSON.t>> = %raw(`function(s, a) { return s.iterate.apply(s, a); }`)
17
+ let _runApply: (
18
+ statement,
19
+ array<JSON.t>,
20
+ ) => unit = %raw(`function(s, a) { return s.run.apply(s, a); }`)
21
+ let _getApply: (
22
+ statement,
23
+ array<JSON.t>,
24
+ ) => Nullable.t<dict<JSON.t>> = %raw(`function(s, a) { return s.get.apply(s, a); }`)
25
+ let _allApply: (
26
+ statement,
27
+ array<JSON.t>,
28
+ ) => array<dict<JSON.t>> = %raw(`function(s, a) { return s.all.apply(s, a); }`)
29
+ let _iterateApply: (
30
+ statement,
31
+ array<JSON.t>,
32
+ ) => Iterator.t<dict<JSON.t>> = %raw(`function(s, a) { return s.iterate.apply(s, a); }`)
21
33
 
22
34
  let openDb = (~path) => {
23
35
  if path !== ":memory:" {
@@ -21,9 +21,10 @@ let ensureSchema = (db: SqliteDriver.t) =>
21
21
 
22
22
  let put = (~db: SqliteDriver.t, ~bucket: string, ~key: string, ~body: string): unit => {
23
23
  ensureSchema(db)
24
- let stmt = db->SqliteDriver.prepare(
25
- "INSERT INTO task_object(bucket, key, body) VALUES(?, ?, ?) ON CONFLICT(bucket, key) DO UPDATE SET body = excluded.body",
26
- )
24
+ let stmt =
25
+ db->SqliteDriver.prepare(
26
+ "INSERT INTO task_object(bucket, key, body) VALUES(?, ?, ?) ON CONFLICT(bucket, key) DO UPDATE SET body = excluded.body",
27
+ )
27
28
  stmt->SqliteDriver.run([
28
29
  JSON.Encode.string(bucket),
29
30
  JSON.Encode.string(key),
@@ -33,9 +34,7 @@ let put = (~db: SqliteDriver.t, ~bucket: string, ~key: string, ~body: string): u
33
34
 
34
35
  let get = (~db: SqliteDriver.t, ~bucket: string, ~key: string): option<string> => {
35
36
  ensureSchema(db)
36
- let stmt = db->SqliteDriver.prepare(
37
- "SELECT body FROM task_object WHERE bucket = ? AND key = ?",
38
- )
37
+ let stmt = db->SqliteDriver.prepare("SELECT body FROM task_object WHERE bucket = ? AND key = ?")
39
38
  switch stmt->SqliteDriver.get([JSON.Encode.string(bucket), JSON.Encode.string(key)]) {
40
39
  | Some(row) =>
41
40
  switch row->Dict.get("body") {
@@ -52,5 +52,10 @@ module MakeWithHooks = (
52
52
 
53
53
  // Make — simple version for standalone tests and examples (no hook callbacks).
54
54
  module Make = (Bus: LocalBus.T) => {
55
- include MakeWithHooks(Bus, {let hooks = noHooks})
55
+ include MakeWithHooks(
56
+ Bus,
57
+ {
58
+ let hooks = noHooks
59
+ },
60
+ )
56
61
  }
@@ -6,9 +6,5 @@ module Make = (Bus: LocalBus.T) => {
6
6
  let api = () => ()
7
7
  let apiRole = () => ()
8
8
  }
9
- include ReventlessCore.Counter_Builder.Make(
10
- QueryDbStorage,
11
- Api,
12
- LocalCounterHandler,
13
- )
9
+ include ReventlessCore.Counter_Builder.Make(QueryDbStorage, Api, LocalCounterHandler)
14
10
  }
@@ -16,9 +16,11 @@ module Make = (Bus: LocalBus.T) => {
16
16
  ~indexes: array<string>=?,
17
17
  ~partitionTag: Reventless.DcbTag.derivedPartitionTag,
18
18
  ~opts: Pulumi.ComponentResource.options=?,
19
- ) => component = Inner.make->Obj.magic
19
+ ) => component =
20
+ Inner.make->Obj.magic
20
21
  // Expose `operations` so callers can resolve the Output chain
21
22
  // (e.g. in beforeAllAsync to register handlers).
22
- let operations: component => Pulumi.Output.t<ReventlessInfra.DcbEventLog.operations> =
23
- ReventlessInfra.Component.operations
23
+ let operations: component => Pulumi.Output.t<
24
+ ReventlessInfra.DcbEventLog.operations,
25
+ > = ReventlessInfra.Component.operations
24
26
  }
@@ -4,11 +4,10 @@ module Make = (Bus: LocalBus.T) => {
4
4
  module RuntimeEnvironment = LocalRuntimeEnvironment
5
5
  module CommandTopicChannel = LocalCommandTopicChannel.Make(Bus)
6
6
  module EventTopicPublisher = LocalEventTopicPublisher.Make(Bus)
7
- module ExtensionPointRuntimeBuilder =
8
- ReventlessCore.ExtensionPointRuntime_Builder_PerExtensionPoint.Make(
9
- RuntimeEnvironment,
10
- CommandTopicChannel,
11
- )
7
+ module ExtensionPointRuntimeBuilder = ReventlessCore.ExtensionPointRuntime_Builder_PerExtensionPoint.Make(
8
+ RuntimeEnvironment,
9
+ CommandTopicChannel,
10
+ )
12
11
 
13
12
  // The in-memory runtime ignores memorySize; timeout mirrors the AWS EP floor.
14
13
  module Defaults: ReventlessInfra.RuntimeDefaults.T = {
@@ -19,14 +18,13 @@ module Make = (Bus: LocalBus.T) => {
19
18
  module Make = (
20
19
  Spec: ReventlessInfra.ExtensionPointMapping.Spec,
21
20
  Mappings: ReventlessInfra.ExtensionPoint.Mappings with module Spec := Spec,
22
- ): ReventlessInfra.ExtensionPoint.T =>
23
- ReventlessCore.ExtensionPoint_Builder.Make(
24
- Spec,
25
- Mappings,
26
- RuntimeEnvironment,
27
- CommandTopicChannel,
28
- EventTopicPublisher,
29
- ExtensionPointRuntimeBuilder,
30
- Defaults,
31
- )
21
+ ): ReventlessInfra.ExtensionPoint.T => ReventlessCore.ExtensionPoint_Builder.Make(
22
+ Spec,
23
+ Mappings,
24
+ RuntimeEnvironment,
25
+ CommandTopicChannel,
26
+ EventTopicPublisher,
27
+ ExtensionPointRuntimeBuilder,
28
+ Defaults,
29
+ )
32
30
  }
@@ -28,7 +28,8 @@ module Make = (Bus: LocalBus.T) => {
28
28
  let queryDbName = Inner.queryDbName
29
29
  let make = Inner.make
30
30
  // Re-expose operations for test resolution
31
- let operations: component => Pulumi.Output.t<ReventlessCore.InboundTranslationSlice.operations> =
32
- ReventlessCore.Component.operations
31
+ let operations: component => Pulumi.Output.t<
32
+ ReventlessCore.InboundTranslationSlice.operations,
33
+ > = ReventlessCore.Component.operations
33
34
  }
34
35
  }
@@ -38,7 +38,8 @@ module Make = (Bus: LocalBus.T) => {
38
38
  let queryDbName = Inner.queryDbName
39
39
  let make = Inner.make
40
40
  // Re-expose operations for test resolution
41
- let operations: component => Pulumi.Output.t<ReventlessCore.OutboundTranslationSlice.operations> =
42
- ReventlessCore.Component.operations
41
+ let operations: component => Pulumi.Output.t<
42
+ ReventlessCore.OutboundTranslationSlice.operations,
43
+ > = ReventlessCore.Component.operations
43
44
  }
44
45
  }
@@ -15,16 +15,15 @@ module Make = (Bus: LocalBus.T) => {
15
15
  module Make = (
16
16
  Spec: Reventless.ReadModel.Spec,
17
17
  Mappings: Reventless.Projection.Mappings with module Target := Spec,
18
- ) =>
19
- ReventlessCore.ReadModel_Builder.Make(
20
- Spec,
21
- Mappings,
22
- RuntimeEnvironment,
23
- QueryDbStorage,
24
- QueryDbResolvers,
25
- EventCollectorChannel,
26
- EventCollectorRuntimeBuilder,
27
- )
18
+ ) => ReventlessCore.ReadModel_Builder.Make(
19
+ Spec,
20
+ Mappings,
21
+ RuntimeEnvironment,
22
+ QueryDbStorage,
23
+ QueryDbResolvers,
24
+ EventCollectorChannel,
25
+ EventCollectorRuntimeBuilder,
26
+ )
28
27
 
29
28
  // Resolver-free variant: registers the QueryDb store in the Bus and wires the
30
29
  // EventCollector subscription, but does NOT register GraphQL query resolvers.
@@ -36,14 +35,13 @@ module Make = (Bus: LocalBus.T) => {
36
35
  module MakeNoResolver = (
37
36
  Spec: Reventless.ReadModel.Spec,
38
37
  Mappings: Reventless.Projection.Mappings with module Target := Spec,
39
- ) =>
40
- ReventlessCore.ReadModel_Builder.Make(
41
- Spec,
42
- Mappings,
43
- RuntimeEnvironment,
44
- QueryDbStorage,
45
- NoResolvers,
46
- EventCollectorChannel,
47
- EventCollectorRuntimeBuilder,
48
- )
38
+ ) => ReventlessCore.ReadModel_Builder.Make(
39
+ Spec,
40
+ Mappings,
41
+ RuntimeEnvironment,
42
+ QueryDbStorage,
43
+ NoResolvers,
44
+ EventCollectorChannel,
45
+ EventCollectorRuntimeBuilder,
46
+ )
49
47
  }
@@ -39,7 +39,8 @@ module Make = (Bus: LocalBus.T) => {
39
39
  type component = Inner.component
40
40
  let make = Inner.make
41
41
  // Re-expose operations for test resolution
42
- let operations: component => Pulumi.Output.t<ReventlessCore.StateViewSlice.operations> =
43
- ReventlessCore.Component.operations
42
+ let operations: component => Pulumi.Output.t<
43
+ ReventlessCore.StateViewSlice.operations,
44
+ > = ReventlessCore.Component.operations
44
45
  }
45
46
  }
@@ -19,17 +19,16 @@ module Make = (Bus: LocalBus.T) => {
19
19
  let timeout = 600
20
20
  }
21
21
 
22
- module Make = (
23
- Spec: ReventlessCore.Task.Spec,
24
- ): (ReventlessCore.Task.T with module Spec = Spec) =>
25
- ReventlessCore.Task_Builder.Make(
26
- Spec,
27
- RuntimeEnvironment,
28
- EventCollectorChannel,
29
- EventCollectorRuntimeBuilder,
30
- TaskRuntimeBuilder,
31
- LocalTaskBucket,
32
- SideEffectHandler,
33
- Defaults,
34
- )
22
+ module Make = (Spec: ReventlessCore.Task.Spec): (
23
+ ReventlessCore.Task.T with module Spec = Spec
24
+ ) => ReventlessCore.Task_Builder.Make(
25
+ Spec,
26
+ RuntimeEnvironment,
27
+ EventCollectorChannel,
28
+ EventCollectorRuntimeBuilder,
29
+ TaskRuntimeBuilder,
30
+ LocalTaskBucket,
31
+ SideEffectHandler,
32
+ Defaults,
33
+ )
35
34
  }