@reventlessdev/reventless-aws 3.0.0-alpha.174 → 3.0.0-alpha.176
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/package.json +10 -10
- package/src/Platform.res +115 -31
- package/src/Platform.res.mjs +217 -44
- package/src/adapter/DcbEventLog/DcbBackend.res +2 -2
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res +4 -1
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream.res.mjs +1 -1
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res +14 -4
- package/src/adapter/EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res.mjs +19 -14
- package/src/adapter/EventLog/EventLogBackend.res +82 -0
- package/src/adapter/EventLog/EventLogBackend.res.mjs +53 -0
- package/src/adapter/EventLog/EventLogStorage.res +15 -0
- package/src/adapter/EventLog/EventLogStorage.res.mjs +20 -1
- package/src/adapter/EventLog/EventLogStorage_Postgres.res +37 -0
- package/src/adapter/EventLog/EventLogStorage_Postgres.res.mjs +21 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +26 -11
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs +15 -6
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res +78 -7
- package/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res.mjs +30 -2
- package/src/adapter/Postgres/PgProjectionFeed.res +100 -0
- package/src/adapter/Postgres/PgProjectionFeed.res.mjs +54 -0
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res +192 -0
- package/src/adapter/QueryDb/PgQueryResolver_Lambda.res.mjs +141 -0
- package/src/adapter/QueryDb/QueryDbBackend.res +52 -0
- package/src/adapter/QueryDb/QueryDbBackend.res.mjs +44 -0
- package/src/adapter/QueryDb/QueryDbResolvers.res +48 -0
- package/src/adapter/QueryDb/QueryDbResolvers.res.mjs +17 -1
- package/src/adapter/QueryDb/QueryDbStorage.res +44 -0
- package/src/adapter/QueryDb/QueryDbStorage.res.mjs +34 -1
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res +43 -0
- package/src/adapter/QueryDb/QueryDbStorage_Postgres.res.mjs +21 -0
- package/src/adapter/QueryDb/QueryDbStorage_Postgres_Runtime.res +19 -0
- package/src/adapter/QueryDb/QueryDbStorage_Postgres_Runtime.res.mjs +15 -0
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res +12 -1
- package/src/adapter/QueryEngine/QueryEngine_DynamoDb.res.mjs +2 -1
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res +83 -3
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single.res.mjs +46 -3
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res +83 -3
- package/src/adapter/Runtime/AggregateRuntime_Builder_Single_Async.res.mjs +48 -3
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res +130 -5
- package/src/adapter/Runtime/EventCollectorRuntime_Builder_Single.res.mjs +66 -6
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.mjs +15 -10
- package/src/adapter/Runtime/ReadModelEntryPoint.mjs +32 -15
- package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +26 -12
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res +138 -8
- package/src/adapter/Runtime/StateViewSliceRuntime_Builder_Single.res.mjs +76 -11
- package/src/components/Aggregate_Builder_Single.res +12 -5
- package/src/components/Aggregate_Builder_Single.res.mjs +12 -6
- package/src/components/Aggregate_Builder_Single_Async.res +12 -5
- package/src/components/Aggregate_Builder_Single_Async.res.mjs +12 -6
- package/src/components/ReadModel_Builder_NoResolver.res.mjs +1 -1
- package/src/components/ReadModel_Builder_NoResolver_Stream.res +13 -4
- package/src/components/ReadModel_Builder_NoResolver_Stream.res.mjs +14 -9
- package/src/components/ReadModel_Builder_Single.res +14 -5
- package/src/components/ReadModel_Builder_Single.res.mjs +15 -12
- package/src/components/ReadModel_Builder_Single_Stream.res +14 -5
- package/src/components/ReadModel_Builder_Single_Stream.res.mjs +15 -12
- package/src/components/StateViewSlice_Builder.res +10 -4
- package/src/components/StateViewSlice_Builder.res.mjs +8 -10
- package/src/components/StateViewSlice_Builder_Stream.res +10 -4
- package/src/components/StateViewSlice_Builder_Stream.res.mjs +8 -10
- package/src/plugin/runtime/PluginRuntime_Builder.res +12 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +4 -0
- package/tests/EventCollectorChannelStreamRuntimeTest.res +55 -0
- package/tests/EventCollectorChannelStreamRuntimeTest.res.mjs +78 -0
- package/tests/PgChangeFeedRelay_IntegrationTest.res +259 -0
- package/tests/PgChangeFeedRelay_IntegrationTest.res.mjs +238 -0
- package/tests/PgPipeline_IntegrationTest.res +208 -0
- package/tests/PgPipeline_IntegrationTest.res.mjs +260 -0
- package/tests/PgQueryResolver_LambdaTest.res +206 -0
- package/tests/PgQueryResolver_LambdaTest.res.mjs +259 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.176 (2026-07-06)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **reventless-aws:** QueryEngine deploy crash on resource-less Postgres QueryDbs (B3.1b) ([a11b5d6](https://github.com/ReventlessDev/reventless-core/commit/a11b5d6f0797f1c9324f2a4ff3ba4197c20e721b))
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **reventless-aws:** classic EventLog Postgres deploy-time wiring + relay (B1 vertical) ([8235ba4](https://github.com/ReventlessDev/reventless-core/commit/8235ba44e506f7094d17251405c6a05c39789805))
|
|
14
|
+
* **reventless-aws:** PgQueryResolver Lambda dispatcher for Postgres GraphQL reads (B3.2a-2) ([140d2bd](https://github.com/ReventlessDev/reventless-core/commit/140d2bd44c2443a03de16e21fd29d5a66b5db9be))
|
|
15
|
+
* **reventless-aws:** Postgres projection delivery via relay feed queues (B3.0) ([80a0ffb](https://github.com/ReventlessDev/reventless-core/commit/80a0ffb1696902a1df99acca1f7915dd65e5c016))
|
|
16
|
+
* **reventless-aws:** Postgres QueryDb storage vertical (B3.1) ([51a7993](https://github.com/ReventlessDev/reventless-core/commit/51a79934c1d9f59bb6f61233a90651d5eadf9f4e))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# 3.0.0-alpha.175 (2026-07-05)
|
|
20
|
+
|
|
21
|
+
**Note:** Version bump only for package @reventlessdev/reventless-aws
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
6
27
|
# 3.0.0-alpha.174 (2026-07-05)
|
|
7
28
|
|
|
8
29
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.176",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
"sury": "11.0.0-alpha.4",
|
|
10
10
|
"uuid": "^13.0.0",
|
|
11
11
|
"@reventlessdev/rescript-aws-sdk": "2.2.0-alpha.20",
|
|
12
|
-
"@reventlessdev/rescript-effect": "0.1.0-alpha.
|
|
13
|
-
"@reventlessdev/rescript-jest": "1.0.0-alpha.
|
|
12
|
+
"@reventlessdev/rescript-effect": "0.1.0-alpha.25",
|
|
13
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.6",
|
|
14
14
|
"@reventlessdev/rescript-pulumi-aws": "2.4.0-alpha.45",
|
|
15
15
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
|
|
16
|
-
"@reventlessdev/rescript-uuid": "1.1.0-alpha.
|
|
17
|
-
"@reventlessdev/reventless-
|
|
18
|
-
"@reventlessdev/reventless-
|
|
19
|
-
"@reventlessdev/reventless-
|
|
20
|
-
"@reventlessdev/reventless-
|
|
21
|
-
"@reventlessdev/reventless-
|
|
16
|
+
"@reventlessdev/rescript-uuid": "1.1.0-alpha.14",
|
|
17
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.24",
|
|
18
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.89",
|
|
19
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.5",
|
|
20
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.67",
|
|
21
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.143"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"rescript": "^12.3.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"build": "rescript build",
|
|
62
62
|
"start": "rescript watch",
|
|
63
63
|
"clean": "rescript clean",
|
|
64
|
-
"rebuild": "pnpm run clean && pnpm run build
|
|
64
|
+
"rebuild": "pnpm run clean && pnpm run build",
|
|
65
65
|
"deploy": "./scripts/deploy.sh",
|
|
66
66
|
"test": "NODE_OPTIONS='--experimental-vm-modules' npx jest",
|
|
67
67
|
"coverage": "nyc report --temp-directory=coverage --reporter=text-lcov | coveralls",
|
package/src/Platform.res
CHANGED
|
@@ -81,17 +81,35 @@ module MakeWithConfig = (
|
|
|
81
81
|
Config.commandHandlerConfig.stateChanges->Option.forEach(({?sync, ?async}) =>
|
|
82
82
|
PluginRuntime_Builder.setStateChangesConfig(~sync?, ~async?, ())
|
|
83
83
|
)
|
|
84
|
-
// B2.3c: when a PgConnection is supplied, route ALL DCB EventLogs
|
|
85
|
-
//
|
|
86
|
-
// record the
|
|
87
|
-
// Set BEFORE the Admin/plugin functors run so
|
|
88
|
-
|
|
84
|
+
// B2.3c: when a PgConnection is supplied, route ALL DCB EventLogs (DcbBackend)
|
|
85
|
+
// AND all classic aggregate EventLogs (EventLogBackend, Single strategies) to
|
|
86
|
+
// Postgres, and record the selections for the change-feed relay wiring in
|
|
87
|
+
// makePlatform below. Set BEFORE the Admin/plugin functors run so the storage
|
|
88
|
+
// Selectables see it.
|
|
89
|
+
Config.pgConnection->Option.forEach((pg: PgConnection.t) => {
|
|
89
90
|
DcbBackend.set({
|
|
90
91
|
connectionConfig: pg.connectionConfig,
|
|
91
92
|
securityGroupId: pg.securityGroupId,
|
|
92
93
|
subnetIds: pg.subnetIds,
|
|
93
94
|
})
|
|
94
|
-
|
|
95
|
+
EventLogBackend.set({
|
|
96
|
+
connectionConfig: pg.connectionConfig,
|
|
97
|
+
securityGroupId: pg.securityGroupId,
|
|
98
|
+
subnetIds: pg.subnetIds,
|
|
99
|
+
})
|
|
100
|
+
// B3.1: app read models / state view slices store to Postgres too. Admin
|
|
101
|
+
// read models are exempt — deploy-time consumers (schema-clobber guard's
|
|
102
|
+
// Plugin-RM scan, PLUGIN_RM_TABLE_NAME gates, retire hooks) query them
|
|
103
|
+
// during `pulumi up` from outside the VPC, and the platform lifecycle
|
|
104
|
+
// depends on them.
|
|
105
|
+
QueryDbBackend.set({
|
|
106
|
+
connectionConfig: pg.connectionConfig,
|
|
107
|
+
securityGroupId: pg.securityGroupId,
|
|
108
|
+
subnetIds: pg.subnetIds,
|
|
109
|
+
})
|
|
110
|
+
QueryDbBackend.exempt(ReventlessCore.PluginsReadModelSpec.name)
|
|
111
|
+
QueryDbBackend.exempt(ReventlessCore.UIFragmentRegistryReadModelSpec.name)
|
|
112
|
+
})
|
|
95
113
|
type api = Types.AppSync.api
|
|
96
114
|
type role = Types.AppSync.role
|
|
97
115
|
type apiTarget = Domain | Platform
|
|
@@ -1230,36 +1248,101 @@ module MakeWithConfig = (
|
|
|
1230
1248
|
type mcpSupported = | @as(true) McpSupported | @as(false) McpNotSupported
|
|
1231
1249
|
let mcpSupported = McpNotSupported
|
|
1232
1250
|
|
|
1233
|
-
// B2.3d: provision the Postgres change-feed relay when
|
|
1234
|
-
// Called after plugins are built (makePlatform monolithic, or deployPlugin
|
|
1235
|
-
// stack). Each Postgres
|
|
1236
|
-
//
|
|
1237
|
-
// queue was attached in forPluginEventCollector — so the
|
|
1238
|
-
// One shared relay Lambda drains all logs
|
|
1239
|
-
//
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1251
|
+
// B2.3d: provision the Postgres change-feed relay when a Postgres backend is
|
|
1252
|
+
// active. Called after plugins are built (makePlatform monolithic, or deployPlugin
|
|
1253
|
+
// per stack). Each Postgres log registered itself during its plugin build
|
|
1254
|
+
// (DcbEventLogStorage_Postgres.make / EventLogStorage_Postgres.make), and its
|
|
1255
|
+
// plugin's EventCollector queue was attached in forPluginEventCollector — so the
|
|
1256
|
+
// registries are complete here. One shared relay Lambda drains all logs (DCB and
|
|
1257
|
+
// classic) and feeds each plugin's collector queue. The checkpoint tables key by
|
|
1258
|
+
// subscriber alone, so the subscriber embeds the log name — a shared subscriber
|
|
1259
|
+
// string across logs would clobber checkpoints and skip events.
|
|
1260
|
+
let provisionPgChangeFeedRelay = () => {
|
|
1261
|
+
// B3.0: besides each plugin's EventCollector queue, every log also fans out
|
|
1262
|
+
// to the registered projection feed queues (the AllReadModels /
|
|
1263
|
+
// AllStateViewSlices Lambdas) — Postgres logs have no DynamoDB stream, so
|
|
1264
|
+
// this is how RM/SVS projections are fed. One subscriber per (feed, log)
|
|
1265
|
+
// keeps checkpoints isolated.
|
|
1266
|
+
let feedTargets = (~connectionConfig, ~logName, ~feed, ~isClassic) =>
|
|
1267
|
+
PgProjectionFeed.getFeedQueues()->Array.filterMap(fq =>
|
|
1268
|
+
(isClassic ? fq.includeClassic : fq.includeDcb)
|
|
1269
|
+
? Some({
|
|
1270
|
+
PgChangeFeedRelay_Builder.connectionConfig,
|
|
1271
|
+
logName,
|
|
1272
|
+
subscriber: `${fq.scope}:${logName}`,
|
|
1273
|
+
feed,
|
|
1274
|
+
targetQueueUrl: fq.url,
|
|
1275
|
+
targetQueueArn: fq.arn,
|
|
1276
|
+
})
|
|
1277
|
+
: None
|
|
1278
|
+
)
|
|
1279
|
+
let dcbLogs = switch DcbBackend.get() {
|
|
1280
|
+
| Some({connectionConfig}) =>
|
|
1281
|
+
DcbBackend.getRelayLogs()->Array.flatMap(entry => {
|
|
1282
|
+
let feed = PgChangeFeedRelay_Builder.Dcb({partitionTag: entry.partitionTag})
|
|
1283
|
+
let ecTarget = switch (entry.collectorQueueUrl, entry.collectorQueueArn) {
|
|
1284
|
+
| (Some(targetQueueUrl), Some(targetQueueArn)) => [
|
|
1285
|
+
{
|
|
1248
1286
|
PgChangeFeedRelay_Builder.connectionConfig,
|
|
1249
1287
|
logName: entry.logName,
|
|
1250
|
-
subscriber:
|
|
1251
|
-
|
|
1288
|
+
subscriber: `aws-eventcollector-relay:${entry.logName}`,
|
|
1289
|
+
feed,
|
|
1252
1290
|
targetQueueUrl,
|
|
1253
1291
|
targetQueueArn,
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1292
|
+
},
|
|
1293
|
+
]
|
|
1294
|
+
| _ =>
|
|
1295
|
+
log.warn(
|
|
1296
|
+
~comp="Platform",
|
|
1297
|
+
`PgChangeFeedRelay: DCB log ${entry.logName} has no EventCollector queue — EP/extension fan-out skipped for it`,
|
|
1298
|
+
)
|
|
1299
|
+
[]
|
|
1300
|
+
}
|
|
1301
|
+
ecTarget->Array.concat(
|
|
1302
|
+
feedTargets(~connectionConfig, ~logName=entry.logName, ~feed, ~isClassic=false),
|
|
1303
|
+
)
|
|
1304
|
+
})
|
|
1305
|
+
| None => []
|
|
1306
|
+
}
|
|
1307
|
+
let classicLogs = switch EventLogBackend.get() {
|
|
1308
|
+
| Some({connectionConfig}) =>
|
|
1309
|
+
EventLogBackend.getRelayLogs()->Array.flatMap(entry => {
|
|
1310
|
+
let feed = PgChangeFeedRelay_Builder.Classic
|
|
1311
|
+
let ecTarget = switch (entry.collectorQueueUrl, entry.collectorQueueArn) {
|
|
1312
|
+
| (Some(targetQueueUrl), Some(targetQueueArn)) => [
|
|
1313
|
+
{
|
|
1314
|
+
PgChangeFeedRelay_Builder.connectionConfig,
|
|
1315
|
+
logName: entry.logName,
|
|
1316
|
+
subscriber: `aws-eventcollector-relay:${entry.logName}`,
|
|
1317
|
+
feed,
|
|
1318
|
+
targetQueueUrl,
|
|
1319
|
+
targetQueueArn,
|
|
1320
|
+
},
|
|
1321
|
+
]
|
|
1322
|
+
| _ =>
|
|
1323
|
+
log.warn(
|
|
1324
|
+
~comp="Platform",
|
|
1325
|
+
`PgChangeFeedRelay: classic log ${entry.logName} has no EventCollector queue — EP/extension fan-out skipped for it`,
|
|
1326
|
+
)
|
|
1327
|
+
[]
|
|
1328
|
+
}
|
|
1329
|
+
ecTarget->Array.concat(
|
|
1330
|
+
feedTargets(~connectionConfig, ~logName=entry.logName, ~feed, ~isClassic=true),
|
|
1262
1331
|
)
|
|
1332
|
+
})
|
|
1333
|
+
| None => []
|
|
1334
|
+
}
|
|
1335
|
+
let relayLogs = dcbLogs->Array.concat(classicLogs)
|
|
1336
|
+
let relayVpc = switch DcbBackend.get() {
|
|
1337
|
+
| Some(sel) => Some((sel.securityGroupId, sel.subnetIds))
|
|
1338
|
+
| None =>
|
|
1339
|
+
switch EventLogBackend.get() {
|
|
1340
|
+
| Some(sel) => Some((sel.securityGroupId, sel.subnetIds))
|
|
1341
|
+
| None => None
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
switch relayVpc {
|
|
1345
|
+
| Some((securityGroupId, subnetIds)) =>
|
|
1263
1346
|
if relayLogs->Array.length > 0 {
|
|
1264
1347
|
let _ = PgChangeFeedRelay_Builder.make(
|
|
1265
1348
|
~name="PgChangeFeedRelay",
|
|
@@ -1270,6 +1353,7 @@ module MakeWithConfig = (
|
|
|
1270
1353
|
}
|
|
1271
1354
|
| None => ()
|
|
1272
1355
|
}
|
|
1356
|
+
}
|
|
1273
1357
|
|
|
1274
1358
|
// In split mode, create a dedicated core AppSync API and push the core schema.
|
|
1275
1359
|
// In unified mode, makePlatform is a no-op (schema stitching handled by events).
|
package/src/Platform.res.mjs
CHANGED
|
@@ -31,12 +31,15 @@ import * as Util_Pulumi$ReventlessCore from "@reventlessdev/reventless-core/src/
|
|
|
31
31
|
import * as Util_DynamoDb$ReventlessAws from "./util/Util_DynamoDb.res.mjs";
|
|
32
32
|
import * as Platform_Casts$ReventlessAws from "./Platform_Casts.res.mjs";
|
|
33
33
|
import * as Platform_Stack$ReventlessAws from "./Platform_Stack.res.mjs";
|
|
34
|
+
import * as QueryDbBackend$ReventlessAws from "./adapter/QueryDb/QueryDbBackend.res.mjs";
|
|
34
35
|
import * as AppSync_Adapter$ReventlessAws from "./components/Api/AppSync_Adapter.res.mjs";
|
|
35
36
|
import * as Counter_Builder$ReventlessAws from "./components/Counter_Builder.res.mjs";
|
|
37
|
+
import * as EventLogBackend$ReventlessAws from "./adapter/EventLog/EventLogBackend.res.mjs";
|
|
36
38
|
import * as Platform_Admin$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_Admin.res.mjs";
|
|
37
39
|
import * as PluginBehavior$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/lifecycle/PluginBehavior.res.mjs";
|
|
38
40
|
import * as Plugin_Helpers$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_Helpers.res.mjs";
|
|
39
41
|
import * as DynamoDb_DocumentClient$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/DynamoDb_DocumentClient.res.mjs";
|
|
42
|
+
import * as PgProjectionFeed$ReventlessAws from "./adapter/Postgres/PgProjectionFeed.res.mjs";
|
|
40
43
|
import * as Util_LocalConfig$ReventlessAws from "./util/Util_LocalConfig.res.mjs";
|
|
41
44
|
import * as IndexJs from "@pulumi/pulumi/runtime/index.js";
|
|
42
45
|
import * as AppSync_EventsApi$ReventlessAws from "./adapter/Api/AppSync_EventsApi.res.mjs";
|
|
@@ -120,11 +123,25 @@ function MakeWithConfig(Config) {
|
|
|
120
123
|
Stdlib_Option.forEach(param.async, AggregateRuntime_Builder_Single_Async$ReventlessAws.setConfig);
|
|
121
124
|
});
|
|
122
125
|
Stdlib_Option.forEach(Config.commandHandlerConfig.stateChanges, param => PluginRuntime_Builder$ReventlessAws.setStateChangesConfig(param.sync, param.async, undefined));
|
|
123
|
-
Stdlib_Option.forEach(Config.pgConnection, pg =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
Stdlib_Option.forEach(Config.pgConnection, pg => {
|
|
127
|
+
DcbBackend$ReventlessAws.set({
|
|
128
|
+
connectionConfig: pg.connectionConfig,
|
|
129
|
+
securityGroupId: pg.securityGroupId,
|
|
130
|
+
subnetIds: pg.subnetIds
|
|
131
|
+
});
|
|
132
|
+
EventLogBackend$ReventlessAws.set({
|
|
133
|
+
connectionConfig: pg.connectionConfig,
|
|
134
|
+
securityGroupId: pg.securityGroupId,
|
|
135
|
+
subnetIds: pg.subnetIds
|
|
136
|
+
});
|
|
137
|
+
QueryDbBackend$ReventlessAws.set({
|
|
138
|
+
connectionConfig: pg.connectionConfig,
|
|
139
|
+
securityGroupId: pg.securityGroupId,
|
|
140
|
+
subnetIds: pg.subnetIds
|
|
141
|
+
});
|
|
142
|
+
QueryDbBackend$ReventlessAws.exempt(PluginsReadModelSpec$ReventlessCore.name);
|
|
143
|
+
QueryDbBackend$ReventlessAws.exempt(UIFragmentRegistryReadModelSpec$ReventlessCore.name);
|
|
144
|
+
});
|
|
128
145
|
let currentDeployTarget = {
|
|
129
146
|
contents: "Domain"
|
|
130
147
|
};
|
|
@@ -816,28 +833,99 @@ function MakeWithConfig(Config) {
|
|
|
816
833
|
return Component$ReventlessCore.operations(component);
|
|
817
834
|
};
|
|
818
835
|
let provisionPgChangeFeedRelay = () => {
|
|
819
|
-
let
|
|
820
|
-
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
let connectionConfig = match.connectionConfig;
|
|
824
|
-
let relayLogs = Stdlib_Array.filterMap(DcbBackend$ReventlessAws.getRelayLogs(), entry => {
|
|
825
|
-
let match = entry.collectorQueueUrl;
|
|
826
|
-
let match$1 = entry.collectorQueueArn;
|
|
827
|
-
if (match !== undefined && match$1 !== undefined) {
|
|
836
|
+
let feedTargets = (connectionConfig, logName, feed, isClassic) => Stdlib_Array.filterMap(PgProjectionFeed$ReventlessAws.getFeedQueues(), fq => {
|
|
837
|
+
if (isClassic ? fq.includeClassic : fq.includeDcb) {
|
|
828
838
|
return {
|
|
829
839
|
connectionConfig: connectionConfig,
|
|
830
|
-
logName:
|
|
831
|
-
subscriber:
|
|
832
|
-
|
|
833
|
-
targetQueueUrl:
|
|
834
|
-
targetQueueArn:
|
|
840
|
+
logName: logName,
|
|
841
|
+
subscriber: fq.scope + `:` + logName,
|
|
842
|
+
feed: feed,
|
|
843
|
+
targetQueueUrl: fq.url,
|
|
844
|
+
targetQueueArn: fq.arn
|
|
835
845
|
};
|
|
836
846
|
}
|
|
837
|
-
log.warn("Platform", undefined, `PgChangeFeedRelay: DCB log ` + entry.logName + ` has no EventCollector queue — skipping (its events will not propagate)`);
|
|
838
847
|
});
|
|
839
|
-
|
|
840
|
-
|
|
848
|
+
let match = DcbBackend$ReventlessAws.get();
|
|
849
|
+
let dcbLogs;
|
|
850
|
+
if (match !== undefined) {
|
|
851
|
+
let connectionConfig = match.connectionConfig;
|
|
852
|
+
dcbLogs = DcbBackend$ReventlessAws.getRelayLogs().flatMap(entry => {
|
|
853
|
+
let feed = {
|
|
854
|
+
TAG: "Dcb",
|
|
855
|
+
partitionTag: entry.partitionTag
|
|
856
|
+
};
|
|
857
|
+
let match = entry.collectorQueueUrl;
|
|
858
|
+
let match$1 = entry.collectorQueueArn;
|
|
859
|
+
let ecTarget;
|
|
860
|
+
let exit = 0;
|
|
861
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
862
|
+
ecTarget = [{
|
|
863
|
+
connectionConfig: connectionConfig,
|
|
864
|
+
logName: entry.logName,
|
|
865
|
+
subscriber: `aws-eventcollector-relay:` + entry.logName,
|
|
866
|
+
feed: feed,
|
|
867
|
+
targetQueueUrl: match,
|
|
868
|
+
targetQueueArn: match$1
|
|
869
|
+
}];
|
|
870
|
+
} else {
|
|
871
|
+
exit = 1;
|
|
872
|
+
}
|
|
873
|
+
if (exit === 1) {
|
|
874
|
+
log.warn("Platform", undefined, `PgChangeFeedRelay: DCB log ` + entry.logName + ` has no EventCollector queue — EP/extension fan-out skipped for it`);
|
|
875
|
+
ecTarget = [];
|
|
876
|
+
}
|
|
877
|
+
return ecTarget.concat(feedTargets(connectionConfig, entry.logName, feed, false));
|
|
878
|
+
});
|
|
879
|
+
} else {
|
|
880
|
+
dcbLogs = [];
|
|
881
|
+
}
|
|
882
|
+
let match$1 = EventLogBackend$ReventlessAws.get();
|
|
883
|
+
let classicLogs;
|
|
884
|
+
if (match$1 !== undefined) {
|
|
885
|
+
let connectionConfig$1 = match$1.connectionConfig;
|
|
886
|
+
classicLogs = EventLogBackend$ReventlessAws.getRelayLogs().flatMap(entry => {
|
|
887
|
+
let match = entry.collectorQueueUrl;
|
|
888
|
+
let match$1 = entry.collectorQueueArn;
|
|
889
|
+
let ecTarget;
|
|
890
|
+
let exit = 0;
|
|
891
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
892
|
+
ecTarget = [{
|
|
893
|
+
connectionConfig: connectionConfig$1,
|
|
894
|
+
logName: entry.logName,
|
|
895
|
+
subscriber: `aws-eventcollector-relay:` + entry.logName,
|
|
896
|
+
feed: "Classic",
|
|
897
|
+
targetQueueUrl: match,
|
|
898
|
+
targetQueueArn: match$1
|
|
899
|
+
}];
|
|
900
|
+
} else {
|
|
901
|
+
exit = 1;
|
|
902
|
+
}
|
|
903
|
+
if (exit === 1) {
|
|
904
|
+
log.warn("Platform", undefined, `PgChangeFeedRelay: classic log ` + entry.logName + ` has no EventCollector queue — EP/extension fan-out skipped for it`);
|
|
905
|
+
ecTarget = [];
|
|
906
|
+
}
|
|
907
|
+
return ecTarget.concat(feedTargets(connectionConfig$1, entry.logName, "Classic", true));
|
|
908
|
+
});
|
|
909
|
+
} else {
|
|
910
|
+
classicLogs = [];
|
|
911
|
+
}
|
|
912
|
+
let relayLogs = dcbLogs.concat(classicLogs);
|
|
913
|
+
let sel = DcbBackend$ReventlessAws.get();
|
|
914
|
+
let relayVpc;
|
|
915
|
+
if (sel !== undefined) {
|
|
916
|
+
relayVpc = [
|
|
917
|
+
sel.securityGroupId,
|
|
918
|
+
sel.subnetIds
|
|
919
|
+
];
|
|
920
|
+
} else {
|
|
921
|
+
let sel$1 = EventLogBackend$ReventlessAws.get();
|
|
922
|
+
relayVpc = sel$1 !== undefined ? [
|
|
923
|
+
sel$1.securityGroupId,
|
|
924
|
+
sel$1.subnetIds
|
|
925
|
+
] : undefined;
|
|
926
|
+
}
|
|
927
|
+
if (relayVpc !== undefined && relayLogs.length !== 0) {
|
|
928
|
+
PgChangeFeedRelay_Builder$ReventlessAws.make("PgChangeFeedRelay", relayLogs, relayVpc[0], relayVpc[1], undefined, undefined);
|
|
841
929
|
return;
|
|
842
930
|
}
|
|
843
931
|
};
|
|
@@ -1245,11 +1333,25 @@ function Make($star) {
|
|
|
1245
1333
|
Stdlib_Option.forEach(param.async, AggregateRuntime_Builder_Single_Async$ReventlessAws.setConfig);
|
|
1246
1334
|
});
|
|
1247
1335
|
Stdlib_Option.forEach(commandHandlerConfig.stateChanges, param => PluginRuntime_Builder$ReventlessAws.setStateChangesConfig(param.sync, param.async, undefined));
|
|
1248
|
-
Stdlib_Option.forEach(undefined, pg =>
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1336
|
+
Stdlib_Option.forEach(undefined, pg => {
|
|
1337
|
+
DcbBackend$ReventlessAws.set({
|
|
1338
|
+
connectionConfig: pg.connectionConfig,
|
|
1339
|
+
securityGroupId: pg.securityGroupId,
|
|
1340
|
+
subnetIds: pg.subnetIds
|
|
1341
|
+
});
|
|
1342
|
+
EventLogBackend$ReventlessAws.set({
|
|
1343
|
+
connectionConfig: pg.connectionConfig,
|
|
1344
|
+
securityGroupId: pg.securityGroupId,
|
|
1345
|
+
subnetIds: pg.subnetIds
|
|
1346
|
+
});
|
|
1347
|
+
QueryDbBackend$ReventlessAws.set({
|
|
1348
|
+
connectionConfig: pg.connectionConfig,
|
|
1349
|
+
securityGroupId: pg.securityGroupId,
|
|
1350
|
+
subnetIds: pg.subnetIds
|
|
1351
|
+
});
|
|
1352
|
+
QueryDbBackend$ReventlessAws.exempt(PluginsReadModelSpec$ReventlessCore.name);
|
|
1353
|
+
QueryDbBackend$ReventlessAws.exempt(UIFragmentRegistryReadModelSpec$ReventlessCore.name);
|
|
1354
|
+
});
|
|
1253
1355
|
let currentDeployTarget = {
|
|
1254
1356
|
contents: "Domain"
|
|
1255
1357
|
};
|
|
@@ -1940,28 +2042,99 @@ function Make($star) {
|
|
|
1940
2042
|
return Component$ReventlessCore.operations(component);
|
|
1941
2043
|
};
|
|
1942
2044
|
let provisionPgChangeFeedRelay = () => {
|
|
1943
|
-
let
|
|
1944
|
-
|
|
1945
|
-
return;
|
|
1946
|
-
}
|
|
1947
|
-
let connectionConfig = match.connectionConfig;
|
|
1948
|
-
let relayLogs = Stdlib_Array.filterMap(DcbBackend$ReventlessAws.getRelayLogs(), entry => {
|
|
1949
|
-
let match = entry.collectorQueueUrl;
|
|
1950
|
-
let match$1 = entry.collectorQueueArn;
|
|
1951
|
-
if (match !== undefined && match$1 !== undefined) {
|
|
2045
|
+
let feedTargets = (connectionConfig, logName, feed, isClassic) => Stdlib_Array.filterMap(PgProjectionFeed$ReventlessAws.getFeedQueues(), fq => {
|
|
2046
|
+
if (isClassic ? fq.includeClassic : fq.includeDcb) {
|
|
1952
2047
|
return {
|
|
1953
2048
|
connectionConfig: connectionConfig,
|
|
1954
|
-
logName:
|
|
1955
|
-
subscriber:
|
|
1956
|
-
|
|
1957
|
-
targetQueueUrl:
|
|
1958
|
-
targetQueueArn:
|
|
2049
|
+
logName: logName,
|
|
2050
|
+
subscriber: fq.scope + `:` + logName,
|
|
2051
|
+
feed: feed,
|
|
2052
|
+
targetQueueUrl: fq.url,
|
|
2053
|
+
targetQueueArn: fq.arn
|
|
1959
2054
|
};
|
|
1960
2055
|
}
|
|
1961
|
-
log.warn("Platform", undefined, `PgChangeFeedRelay: DCB log ` + entry.logName + ` has no EventCollector queue — skipping (its events will not propagate)`);
|
|
1962
2056
|
});
|
|
1963
|
-
|
|
1964
|
-
|
|
2057
|
+
let match = DcbBackend$ReventlessAws.get();
|
|
2058
|
+
let dcbLogs;
|
|
2059
|
+
if (match !== undefined) {
|
|
2060
|
+
let connectionConfig = match.connectionConfig;
|
|
2061
|
+
dcbLogs = DcbBackend$ReventlessAws.getRelayLogs().flatMap(entry => {
|
|
2062
|
+
let feed = {
|
|
2063
|
+
TAG: "Dcb",
|
|
2064
|
+
partitionTag: entry.partitionTag
|
|
2065
|
+
};
|
|
2066
|
+
let match = entry.collectorQueueUrl;
|
|
2067
|
+
let match$1 = entry.collectorQueueArn;
|
|
2068
|
+
let ecTarget;
|
|
2069
|
+
let exit = 0;
|
|
2070
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
2071
|
+
ecTarget = [{
|
|
2072
|
+
connectionConfig: connectionConfig,
|
|
2073
|
+
logName: entry.logName,
|
|
2074
|
+
subscriber: `aws-eventcollector-relay:` + entry.logName,
|
|
2075
|
+
feed: feed,
|
|
2076
|
+
targetQueueUrl: match,
|
|
2077
|
+
targetQueueArn: match$1
|
|
2078
|
+
}];
|
|
2079
|
+
} else {
|
|
2080
|
+
exit = 1;
|
|
2081
|
+
}
|
|
2082
|
+
if (exit === 1) {
|
|
2083
|
+
log.warn("Platform", undefined, `PgChangeFeedRelay: DCB log ` + entry.logName + ` has no EventCollector queue — EP/extension fan-out skipped for it`);
|
|
2084
|
+
ecTarget = [];
|
|
2085
|
+
}
|
|
2086
|
+
return ecTarget.concat(feedTargets(connectionConfig, entry.logName, feed, false));
|
|
2087
|
+
});
|
|
2088
|
+
} else {
|
|
2089
|
+
dcbLogs = [];
|
|
2090
|
+
}
|
|
2091
|
+
let match$1 = EventLogBackend$ReventlessAws.get();
|
|
2092
|
+
let classicLogs;
|
|
2093
|
+
if (match$1 !== undefined) {
|
|
2094
|
+
let connectionConfig$1 = match$1.connectionConfig;
|
|
2095
|
+
classicLogs = EventLogBackend$ReventlessAws.getRelayLogs().flatMap(entry => {
|
|
2096
|
+
let match = entry.collectorQueueUrl;
|
|
2097
|
+
let match$1 = entry.collectorQueueArn;
|
|
2098
|
+
let ecTarget;
|
|
2099
|
+
let exit = 0;
|
|
2100
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
2101
|
+
ecTarget = [{
|
|
2102
|
+
connectionConfig: connectionConfig$1,
|
|
2103
|
+
logName: entry.logName,
|
|
2104
|
+
subscriber: `aws-eventcollector-relay:` + entry.logName,
|
|
2105
|
+
feed: "Classic",
|
|
2106
|
+
targetQueueUrl: match,
|
|
2107
|
+
targetQueueArn: match$1
|
|
2108
|
+
}];
|
|
2109
|
+
} else {
|
|
2110
|
+
exit = 1;
|
|
2111
|
+
}
|
|
2112
|
+
if (exit === 1) {
|
|
2113
|
+
log.warn("Platform", undefined, `PgChangeFeedRelay: classic log ` + entry.logName + ` has no EventCollector queue — EP/extension fan-out skipped for it`);
|
|
2114
|
+
ecTarget = [];
|
|
2115
|
+
}
|
|
2116
|
+
return ecTarget.concat(feedTargets(connectionConfig$1, entry.logName, "Classic", true));
|
|
2117
|
+
});
|
|
2118
|
+
} else {
|
|
2119
|
+
classicLogs = [];
|
|
2120
|
+
}
|
|
2121
|
+
let relayLogs = dcbLogs.concat(classicLogs);
|
|
2122
|
+
let sel = DcbBackend$ReventlessAws.get();
|
|
2123
|
+
let relayVpc;
|
|
2124
|
+
if (sel !== undefined) {
|
|
2125
|
+
relayVpc = [
|
|
2126
|
+
sel.securityGroupId,
|
|
2127
|
+
sel.subnetIds
|
|
2128
|
+
];
|
|
2129
|
+
} else {
|
|
2130
|
+
let sel$1 = EventLogBackend$ReventlessAws.get();
|
|
2131
|
+
relayVpc = sel$1 !== undefined ? [
|
|
2132
|
+
sel$1.securityGroupId,
|
|
2133
|
+
sel$1.subnetIds
|
|
2134
|
+
] : undefined;
|
|
2135
|
+
}
|
|
2136
|
+
if (relayVpc !== undefined && relayLogs.length !== 0) {
|
|
2137
|
+
PgChangeFeedRelay_Builder$ReventlessAws.make("PgChangeFeedRelay", relayLogs, relayVpc[0], relayVpc[1], undefined, undefined);
|
|
1965
2138
|
return;
|
|
1966
2139
|
}
|
|
1967
2140
|
};
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
// EventCollector SQS queue.
|
|
11
11
|
//
|
|
12
12
|
// All DCB logs in the platform share one selection (the confirmed B2.3c toggle);
|
|
13
|
-
// aggregate EventLogs
|
|
14
|
-
// `
|
|
13
|
+
// classic aggregate EventLogs follow the same platform toggle via the sibling
|
|
14
|
+
// `EventLogBackend` registry. See docs/plans/done/aws-postgres-change-feed-bridge.md.
|
|
15
15
|
|
|
16
16
|
type selection = {
|
|
17
17
|
connectionConfig: Pulumi.Output.t<PgConnection.connectionConfig>,
|
|
@@ -32,10 +32,13 @@ let make: ReventlessCore.EventCollector_Adapter.channelMaker<callbackEvent, 'con
|
|
|
32
32
|
~eventTopics,
|
|
33
33
|
~opts as _,
|
|
34
34
|
) => {
|
|
35
|
+
// Postgres-backed event logs have NO storage resources (no table, no stream) —
|
|
36
|
+
// skip them instead of producing undefined entries; their events arrive via the
|
|
37
|
+
// PgProjectionFeed SQS queue (B3.0), not a stream ESM.
|
|
35
38
|
let eventTopicResources =
|
|
36
39
|
eventTopics
|
|
37
40
|
->Dict.valuesToArray
|
|
38
|
-
->Array.
|
|
41
|
+
->Array.filterMap(outputs => outputs.resources->Array.get(0))
|
|
39
42
|
|
|
40
43
|
let enqueueEventNotSupported = (delay, id, messageBody) => {
|
|
41
44
|
// TODO: can we check this at deploy time ?
|
|
@@ -21,7 +21,7 @@ function connect(name, channelSpecs, runtime, opts) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function make(param, eventTopics, param$1) {
|
|
24
|
-
let eventTopicResources = Object.values(eventTopics)
|
|
24
|
+
let eventTopicResources = Stdlib_Array.filterMap(Object.values(eventTopics), outputs => outputs.resources[0]);
|
|
25
25
|
let enqueueEventNotSupported = (delay, id, messageBody) => {
|
|
26
26
|
log.debug("EventCollectorChannel_DynamoDbStream", Object.fromEntries([
|
|
27
27
|
[
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
// Shared record decoder for the ReadModel / StateViewSlice entry points.
|
|
2
|
+
//
|
|
3
|
+
// DynamoDB path: the Lambda is invoked by DynamoDB-stream ESMs — decode each
|
|
4
|
+
// NEW_IMAGE. Postgres path (B3.0): the Lambda is invoked by its SQS feed queue,
|
|
5
|
+
// fed by the PgChangeFeedRelay with ready-made `{id, meta, event}` bodies —
|
|
6
|
+
// parse each body straight back to JSON. Both record kinds can appear in one
|
|
7
|
+
// deployment (mixed backends), so the branch is per record, not per event.
|
|
1
8
|
let handleStreamEvent: (
|
|
2
9
|
ReventlessCore.EventCollector.jsonEventsHandler,
|
|
3
|
-
PulumiAws.
|
|
10
|
+
PulumiAws.Lambda.CallbackFunction.event,
|
|
4
11
|
_,
|
|
5
|
-
) => Effect.t<unit, string, unit> = (handleEvents,
|
|
6
|
-
let jsons =
|
|
12
|
+
) => Effect.t<unit, string, unit> = (handleEvents, event, _) => {
|
|
13
|
+
let jsons = event.records->Array.filterMap(record =>
|
|
7
14
|
switch record.eventSource {
|
|
15
|
+
| "aws:sqs" => record->PulumiAws.SQS.Queue.asRecord->Util.SQS_Runtime.parseSqsRecord
|
|
8
16
|
| "aws:dynamodb" =>
|
|
9
|
-
switch record
|
|
17
|
+
switch record
|
|
18
|
+
->PulumiAws.DynamoDb.Stream.asRecord
|
|
19
|
+
->Util.DynamoDbStream_Runtime.parseDynamoDbStreamRecordEvent {
|
|
10
20
|
| NewImage(_, newImage)
|
|
11
21
|
| NewAndOldImage(_, newImage, _) =>
|
|
12
22
|
Some(newImage)
|