@reventlessdev/reventless-aws 3.0.0-alpha.232 → 3.0.0-alpha.234
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 +23 -0
- package/package.json +7 -7
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res +137 -0
- package/src/adapter/Api/AppSyncEventsSigner_Ops.res.mjs +121 -0
- package/src/adapter/Api/Platform_AdminScan_Ops.res +136 -0
- package/src/adapter/Api/Platform_AdminScan_Ops.res.mjs +98 -0
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res +12 -90
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda.res.mjs +11 -84
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res +86 -0
- package/src/adapter/Api/Platform_ComponentDefinitions_Lambda_Ops.res.mjs +79 -0
- package/src/adapter/Api/Platform_UIFragments_Lambda.res +9 -79
- package/src/adapter/Api/Platform_UIFragments_Lambda.res.mjs +7 -143
- package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res +48 -0
- package/src/adapter/Api/Platform_UIFragments_Lambda_Ops.res.mjs +63 -0
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res +21 -80
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync.res.mjs +23 -68
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res +70 -0
- package/src/adapter/EventLogSubscription/EventLogSubscription_AppSync_Ops.res.mjs +68 -0
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res +1 -1
- package/src/adapter/Postgres/PgChangeFeedRelay_Builder.res.mjs +1 -1
- package/src/adapter/Postgres/PgMigration_Builder.res +1 -1
- package/src/adapter/Postgres/PgMigration_Builder.res.mjs +1 -1
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +42 -126
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +246 -0
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +145 -0
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +27 -2
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +10 -3
- package/src/adapter/Runtime/CounterEntryPoint.mjs +19 -73
- package/src/adapter/Runtime/CounterEntryPoint_Ops.res +145 -0
- package/src/adapter/Runtime/CounterEntryPoint_Ops.res.mjs +129 -0
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint.mjs +14 -1
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res +22 -2
- package/src/adapter/Runtime/DcbCommandTopicEntryPoint_Ops.res.mjs +15 -4
- package/src/adapter/Runtime/EventCollectorEntryPoint.mjs +52 -510
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +816 -0
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res.mjs +651 -0
- package/src/adapter/Runtime/EventMapperEntryPoint.mjs +23 -67
- package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res +126 -0
- package/src/adapter/Runtime/EventMapperEntryPoint_Ops.res.mjs +83 -0
- package/src/adapter/Runtime/ExtensionPointEntryPoint.mjs +16 -63
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res +150 -0
- package/src/adapter/Runtime/ExtensionPointEntryPoint_Ops.res.mjs +111 -0
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res +96 -0
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.res.mjs +70 -0
- package/src/adapter/Runtime/PgMigrationEntryPoint.res +54 -0
- package/src/adapter/Runtime/PgMigrationEntryPoint.res.mjs +37 -0
- package/src/adapter/Runtime/PgQueryResolverEntryPoint.mjs +20 -55
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res +155 -0
- package/src/adapter/Runtime/PgQueryResolverEntryPoint_Ops.res.mjs +94 -0
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res +80 -0
- package/src/adapter/Runtime/ProjectionEntryPoint_Ops.res.mjs +39 -0
- package/src/adapter/Runtime/QueryDbEntryPoint_Ops.res +4 -4
- package/src/adapter/Runtime/ReadModelEntryPoint.mjs +34 -153
- package/src/adapter/Runtime/ReadModelEntryPoint_Ops.res +114 -0
- package/src/adapter/Runtime/ReadModelEntryPoint_Ops.res.mjs +83 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +26 -6
- package/src/adapter/Runtime/SideEffectEntryPoint.mjs +23 -64
- package/src/adapter/Runtime/SideEffectEntryPoint_Ops.res +71 -0
- package/src/adapter/Runtime/SideEffectEntryPoint_Ops.res.mjs +57 -0
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res +5 -2
- package/src/adapter/Runtime/StateChangeSliceRuntime_Builder_Single.res.mjs +1 -1
- package/src/adapter/Runtime/StateViewSliceEntryPoint.mjs +34 -165
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res +206 -0
- package/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res.mjs +105 -0
- package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res +156 -0
- package/src/adapter/Runtime/StreamRoutedEntryPoint_Ops.res.mjs +123 -0
- package/src/adapter/Runtime/TaskBucketEntryPoint.mjs +18 -138
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res +198 -0
- package/src/adapter/Runtime/TaskBucketEntryPoint_Ops.res.mjs +155 -0
- package/src/adapter/StateTopic/StateTopic_AppSync.res +12 -170
- package/src/adapter/StateTopic/StateTopic_AppSync.res.mjs +7 -167
- package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res +208 -0
- package/src/adapter/StateTopic/StateTopic_AppSync_Ops.res.mjs +183 -0
- package/src/components/AutomationSlice_Builder.res +2 -0
- package/src/components/AutomationSlice_Builder.res.mjs +1 -1
- package/src/components/OutboundTranslationSlice_Builder.res +1 -0
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +1 -1
- package/src/plugin/runtime/PluginRuntime_Builder.res +13 -4
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +1 -1
- package/tests/AppSyncEventsSigner_OpsTest.res +75 -0
- package/tests/AppSyncEventsSigner_OpsTest.res.mjs +44 -0
- package/tests/AppSyncEventsSigner_ParityFixture.mjs +36 -0
- package/tests/AutomationSliceEntryPoint_OpsTest.res +165 -0
- package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +280 -0
- package/tests/CounterEntryPoint_OpsTest.res +115 -0
- package/tests/CounterEntryPoint_OpsTest.res.mjs +150 -0
- package/tests/EventCollectorEntryPoint_OpsTest.res +216 -0
- package/tests/EventCollectorEntryPoint_OpsTest.res.mjs +339 -0
- package/tests/EventMapperEntryPoint_OpsTest.res +103 -0
- package/tests/EventMapperEntryPoint_OpsTest.res.mjs +120 -0
- package/tests/ExtensionPointEntryPoint_OpsTest.res +57 -0
- package/tests/ExtensionPointEntryPoint_OpsTest.res.mjs +54 -0
- package/tests/PgMigrationEntryPoint_IntegrationTest.res +22 -31
- package/tests/PgMigrationEntryPoint_IntegrationTest.res.mjs +20 -23
- package/tests/PgQueryResolverEntryPoint_OpsTest.res +38 -0
- package/tests/PgQueryResolverEntryPoint_OpsTest.res.mjs +31 -0
- package/tests/Platform_AdminScan_OpsTest.res +80 -0
- package/tests/Platform_AdminScan_OpsTest.res.mjs +127 -0
- package/tests/ReadModelEntryPoint_OpsTest.res +141 -0
- package/tests/ReadModelEntryPoint_OpsTest.res.mjs +267 -0
- package/tests/SideEffectEntryPoint_OpsTest.res +79 -0
- package/tests/SideEffectEntryPoint_OpsTest.res.mjs +105 -0
- package/tests/StateViewSliceEntryPoint_OpsTest.res +167 -0
- package/tests/StateViewSliceEntryPoint_OpsTest.res.mjs +296 -0
- package/tests/TaskBucketEntryPoint_OpsTest.res +117 -0
- package/tests/TaskBucketEntryPoint_OpsTest.res.mjs +165 -0
- package/tests/integration/StateViewSliceEntryPoint_IntegrationTest.res +42 -13
- package/tests/integration/StateViewSliceEntryPoint_IntegrationTest.res.mjs +29 -6
- package/src/adapter/Runtime/PgChangeFeedRelayEntryPoint.mjs +0 -57
- package/src/adapter/Runtime/PgMigrationEntryPoint.mjs +0 -40
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
|
+
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
5
|
+
import * as TaskBucketEntryPoint_Ops$ReventlessAws from "../src/adapter/Runtime/TaskBucketEntryPoint_Ops.res.mjs";
|
|
6
|
+
|
|
7
|
+
function str(prim) {
|
|
8
|
+
return prim;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function obj(pairs) {
|
|
12
|
+
return Object.fromEntries(pairs);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
globalThis.describe("TaskBucketEntryPoint_Ops.parseHandlerConfig", () => {
|
|
16
|
+
globalThis.test("empty raw config decodes to empty defaults", () => {
|
|
17
|
+
let c = TaskBucketEntryPoint_Ops$ReventlessAws.parseHandlerConfig("");
|
|
18
|
+
globalThis.expect(c.callbackModule).toBe("");
|
|
19
|
+
globalThis.expect(Object.entries(c.publishToAggregates).length).toBe(0);
|
|
20
|
+
globalThis.expect(Stdlib_Option.isNone(c.scheduler)).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
globalThis.test("decodes callbackModule, publishToAggregates, and scheduler env names", () => {
|
|
23
|
+
let config = JSON.stringify(Object.fromEntries([
|
|
24
|
+
[
|
|
25
|
+
"callbackModule",
|
|
26
|
+
"@x/plugin/src/Task/ImportCatalog.res.mjs"
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
"publishToAggregates",
|
|
30
|
+
Object.fromEntries([[
|
|
31
|
+
"Product",
|
|
32
|
+
"PTA_Product_QUEUE_URL"
|
|
33
|
+
]])
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"scheduler",
|
|
37
|
+
Object.fromEntries([
|
|
38
|
+
[
|
|
39
|
+
"roleArnEnv",
|
|
40
|
+
"SCHEDULER_ROLE_ARN"
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
"targetArnEnv",
|
|
44
|
+
"SCHEDULER_TARGET_ARN"
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
"targetNameEnv",
|
|
48
|
+
"SCHEDULER_TARGET_NAME"
|
|
49
|
+
]
|
|
50
|
+
])
|
|
51
|
+
]
|
|
52
|
+
]));
|
|
53
|
+
let c = TaskBucketEntryPoint_Ops$ReventlessAws.parseHandlerConfig(config);
|
|
54
|
+
globalThis.expect(c.callbackModule).toBe("@x/plugin/src/Task/ImportCatalog.res.mjs");
|
|
55
|
+
globalThis.expect(c.publishToAggregates["Product"]).toEqual("PTA_Product_QUEUE_URL");
|
|
56
|
+
let s = c.scheduler;
|
|
57
|
+
if (s !== undefined) {
|
|
58
|
+
globalThis.expect(s.roleArnEnv).toBe("SCHEDULER_ROLE_ARN");
|
|
59
|
+
return;
|
|
60
|
+
} else {
|
|
61
|
+
return Stdlib_JsError.throwWithMessage("expected Some(scheduler)");
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
globalThis.describe("TaskBucketEntryPoint_Ops.buildPublishCommands", () => {
|
|
67
|
+
globalThis.test("resolves queue URLs via env vars, skipping unset or empty ones", () => {
|
|
68
|
+
process.env["TB_TEST_QUEUE_A"] = "https://sqs/a.fifo";
|
|
69
|
+
process.env["TB_TEST_QUEUE_EMPTY"] = "";
|
|
70
|
+
let map = Object.fromEntries([
|
|
71
|
+
[
|
|
72
|
+
"AggA",
|
|
73
|
+
"TB_TEST_QUEUE_A"
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
"AggEmpty",
|
|
77
|
+
"TB_TEST_QUEUE_EMPTY"
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
"AggUnset",
|
|
81
|
+
"TB_TEST_QUEUE_UNSET"
|
|
82
|
+
]
|
|
83
|
+
]);
|
|
84
|
+
let publish = TaskBucketEntryPoint_Ops$ReventlessAws.buildPublishCommands(map);
|
|
85
|
+
globalThis.expect(Stdlib_Option.isSome(publish["AggA"])).toBe(true);
|
|
86
|
+
globalThis.expect(Stdlib_Option.isNone(publish["AggEmpty"])).toBe(true);
|
|
87
|
+
globalThis.expect(Stdlib_Option.isNone(publish["AggUnset"])).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
globalThis.describe("TaskBucketEntryPoint_Ops.dispatchTaskActions", () => {
|
|
92
|
+
let schedule = {
|
|
93
|
+
name: "sweep",
|
|
94
|
+
rate: {
|
|
95
|
+
TAG: "Minutes",
|
|
96
|
+
_0: 5
|
|
97
|
+
},
|
|
98
|
+
payload: "{}"
|
|
99
|
+
};
|
|
100
|
+
globalThis.test("routes PublishCommands to the aggregate's publish fn", async () => {
|
|
101
|
+
let published = [];
|
|
102
|
+
let publishCommands = Object.fromEntries([[
|
|
103
|
+
"Product",
|
|
104
|
+
async cmds => {
|
|
105
|
+
published.push(cmds);
|
|
106
|
+
}
|
|
107
|
+
]]);
|
|
108
|
+
await TaskBucketEntryPoint_Ops$ReventlessAws.dispatchTaskActions([
|
|
109
|
+
{
|
|
110
|
+
TAG: "PublishCommands",
|
|
111
|
+
_0: "Product",
|
|
112
|
+
_1: []
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
TAG: "PublishCommands",
|
|
116
|
+
_0: "Nope",
|
|
117
|
+
_1: []
|
|
118
|
+
}
|
|
119
|
+
], publishCommands, () => {});
|
|
120
|
+
globalThis.expect(published.length).toBe(1);
|
|
121
|
+
});
|
|
122
|
+
globalThis.test("routes schedule actions to the scheduler ops; skips when unconfigured", async () => {
|
|
123
|
+
let created = [];
|
|
124
|
+
let deleted = [];
|
|
125
|
+
let ops_createSchedule = async s => {
|
|
126
|
+
created.push(s.name);
|
|
127
|
+
};
|
|
128
|
+
let ops_deleteSchedule = async name => {
|
|
129
|
+
deleted.push(name);
|
|
130
|
+
};
|
|
131
|
+
let ops = {
|
|
132
|
+
createSchedule: ops_createSchedule,
|
|
133
|
+
deleteSchedule: ops_deleteSchedule
|
|
134
|
+
};
|
|
135
|
+
await TaskBucketEntryPoint_Ops$ReventlessAws.dispatchTaskActions([
|
|
136
|
+
{
|
|
137
|
+
TAG: "CreateSchedule",
|
|
138
|
+
_0: schedule
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
TAG: "DeleteSchedule",
|
|
142
|
+
_0: "sweep"
|
|
143
|
+
}
|
|
144
|
+
], {}, () => ops);
|
|
145
|
+
globalThis.expect(created).toEqual(["sweep"]);
|
|
146
|
+
globalThis.expect(deleted).toEqual(["sweep"]);
|
|
147
|
+
await TaskBucketEntryPoint_Ops$ReventlessAws.dispatchTaskActions([
|
|
148
|
+
{
|
|
149
|
+
TAG: "CreateSchedule",
|
|
150
|
+
_0: schedule
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
TAG: "DeleteSchedule",
|
|
154
|
+
_0: "sweep"
|
|
155
|
+
}
|
|
156
|
+
], {}, () => {});
|
|
157
|
+
globalThis.expect(created.length).toBe(1);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
export {
|
|
162
|
+
str,
|
|
163
|
+
obj,
|
|
164
|
+
}
|
|
165
|
+
/* Not a pure module */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Integration regression guard for the StateViewSlice projection Lambda entry
|
|
2
|
-
// point (`StateViewSliceEntryPoint.mjs`
|
|
2
|
+
// point (`StateViewSliceEntryPoint.mjs` + `StateViewSliceEntryPoint_Ops.res`),
|
|
3
|
+
// run against DynamoDB Local.
|
|
3
4
|
//
|
|
4
5
|
// Covers the 2026-07-09 incident: the deployed runtime built its projection
|
|
5
6
|
// loop with `handleAction(action, queryDbOps, undefined)` — hardcoding
|
|
@@ -8,8 +9,10 @@
|
|
|
8
9
|
// then hit the `MissingSubIdConfig` guard and silently wrote nothing, while the
|
|
9
10
|
// in-memory GWT/callback path (which threads `subIdConfig`) stayed green. This
|
|
10
11
|
// is a deployed-runtime vs test-harness parity gap: a unit test on the callback
|
|
11
|
-
// path cannot catch it, so this test drives the
|
|
12
|
-
// production uses
|
|
12
|
+
// path cannot catch it, so this test drives the real entry-point wiring the
|
|
13
|
+
// production shell uses — `makeRegisteredHandler` with the modules record read
|
|
14
|
+
// off the dynamically imported spec/projection modules, invoked with an
|
|
15
|
+
// SQS-shaped Lambda record so the full decode path runs.
|
|
13
16
|
//
|
|
14
17
|
// The fixture `SvsTestSlice` is an `@subId productId` view slice whose only
|
|
15
18
|
// projection path is `UpdateMultiState`. Before the fix both appends no-op and
|
|
@@ -48,26 +51,52 @@ let createViewTable = async (tableName): Util_DynamoDb_Runtime.resolvedTable =>
|
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
// Drives the real entry
|
|
52
|
-
//
|
|
53
|
-
// undefined)
|
|
54
|
-
//
|
|
54
|
+
// Drives the real entry-point wiring: mirrors the shell's untyped seam line for
|
|
55
|
+
// line — a HANDLER_CONFIG-shaped entry (DynamoDB path — `pgConnection`/
|
|
56
|
+
// `stateTopicName` undefined) plus the modules record read off the dynamically
|
|
57
|
+
// imported spec/projection modules — then feeds one SQS-shaped Lambda record
|
|
58
|
+
// through the registered stream handler, so the same decode path the deployed
|
|
59
|
+
// Lambda runs (handleStreamEvent → envelope decode → schema parse → project →
|
|
60
|
+
// handleAction) is exercised end to end.
|
|
55
61
|
let runOneEvent: (string, JSON.t) => promise<unit> = %raw(`
|
|
56
62
|
async (tableName, eventJson) => {
|
|
57
|
-
const
|
|
58
|
-
"@reventlessdev/reventless-aws/src/adapter/Runtime/
|
|
63
|
+
const Ops = await import(
|
|
64
|
+
"@reventlessdev/reventless-aws/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res.mjs"
|
|
59
65
|
);
|
|
60
66
|
const specModule = await import("./SvsTestSlice.res.mjs");
|
|
61
67
|
const projectionModule = await import("./SvsTestSlice_Projection.res.mjs");
|
|
62
68
|
const Effect = await import("effect/Effect");
|
|
63
|
-
const Stream = await import("effect/Stream");
|
|
64
69
|
const { tag: requestContextTag } = await import(
|
|
65
70
|
"@reventlessdev/reventless-core/src/RequestContext.res.mjs"
|
|
66
71
|
);
|
|
67
72
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
const registered = Ops.makeRegisteredHandler(
|
|
74
|
+
{
|
|
75
|
+
specModule: "",
|
|
76
|
+
projectionModule: "",
|
|
77
|
+
queryDbTableName: tableName,
|
|
78
|
+
sourceUrn: "svs-test-urn",
|
|
79
|
+
stateTopicName: undefined,
|
|
80
|
+
pgConnection: undefined,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: specModule.name,
|
|
84
|
+
consumedEventSchema: specModule.consumedEventSchema,
|
|
85
|
+
project: projectionModule.project,
|
|
86
|
+
config: specModule.config,
|
|
87
|
+
subIdConfig: specModule.subIdConfig,
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
const event = {
|
|
91
|
+
Records: [
|
|
92
|
+
{
|
|
93
|
+
eventSource: "aws:sqs",
|
|
94
|
+
eventSourceARN: "svs-test-urn",
|
|
95
|
+
body: JSON.stringify(eventJson),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
const effect = registered.handler(event, {})
|
|
71
100
|
.pipe(Effect.provideService(requestContextTag, { correlationId: "svs-test" }));
|
|
72
101
|
await Effect.runPromise(effect);
|
|
73
102
|
}
|
|
@@ -69,20 +69,43 @@ async function createViewTable(tableName) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
let runOneEvent = (async (tableName, eventJson) => {
|
|
72
|
-
const
|
|
73
|
-
"@reventlessdev/reventless-aws/src/adapter/Runtime/
|
|
72
|
+
const Ops = await import(
|
|
73
|
+
"@reventlessdev/reventless-aws/src/adapter/Runtime/StateViewSliceEntryPoint_Ops.res.mjs"
|
|
74
74
|
);
|
|
75
75
|
const specModule = await import("./SvsTestSlice.res.mjs");
|
|
76
76
|
const projectionModule = await import("./SvsTestSlice_Projection.res.mjs");
|
|
77
77
|
const Effect = await import("effect/Effect");
|
|
78
|
-
const Stream = await import("effect/Stream");
|
|
79
78
|
const { tag: requestContextTag } = await import(
|
|
80
79
|
"@reventlessdev/reventless-core/src/RequestContext.res.mjs"
|
|
81
80
|
);
|
|
82
81
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
const registered = Ops.makeRegisteredHandler(
|
|
83
|
+
{
|
|
84
|
+
specModule: "",
|
|
85
|
+
projectionModule: "",
|
|
86
|
+
queryDbTableName: tableName,
|
|
87
|
+
sourceUrn: "svs-test-urn",
|
|
88
|
+
stateTopicName: undefined,
|
|
89
|
+
pgConnection: undefined,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: specModule.name,
|
|
93
|
+
consumedEventSchema: specModule.consumedEventSchema,
|
|
94
|
+
project: projectionModule.project,
|
|
95
|
+
config: specModule.config,
|
|
96
|
+
subIdConfig: specModule.subIdConfig,
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
const event = {
|
|
100
|
+
Records: [
|
|
101
|
+
{
|
|
102
|
+
eventSource: "aws:sqs",
|
|
103
|
+
eventSourceARN: "svs-test-urn",
|
|
104
|
+
body: JSON.stringify(eventJson),
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
const effect = registered.handler(event, {})
|
|
86
109
|
.pipe(Effect.provideService(requestContextTag, { correlationId: "svs-test" }));
|
|
87
110
|
await Effect.runPromise(effect);
|
|
88
111
|
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// PgChangeFeedRelay Lambda entry point (scheduled poll — B2.3).
|
|
2
|
-
//
|
|
3
|
-
// Triggered on a schedule (EventBridge rate rule). Each invocation drains every
|
|
4
|
-
// Postgres log listed in HANDLER_CONFIG from its checkpoint — DCB (`dcb_event`)
|
|
5
|
-
// and classic aggregate (`event_log`) logs alike — and relays the events,
|
|
6
|
-
// transformed into the {id, meta, event} shape, onto the plugin EventCollector
|
|
7
|
-
// SQS queue — which then fans out to projections, aggregate command topics, and
|
|
8
|
-
// the cross-plugin SNS EventTopic.
|
|
9
|
-
// See docs/plans/done/aws-postgres-change-feed-bridge.md.
|
|
10
|
-
//
|
|
11
|
-
// HANDLER_CONFIG shape:
|
|
12
|
-
// { "logs": [ { "pgConnection": {host,port,database,username,secretArn},
|
|
13
|
-
// "logName": string, // dcb_event/event_log log_name
|
|
14
|
-
// "subscriber": string, // per-log checkpoint key
|
|
15
|
-
// "targetQueueUrl": string, // plugin EventCollector SQS URL
|
|
16
|
-
// "kind"?: "classic", // absent → DCB
|
|
17
|
-
// "partitionTag"?: <derivedPartitionTag> } ] } // DCB only
|
|
18
|
-
|
|
19
|
-
import { relay, relayClassic } from "@reventlessdev/reventless-aws/src/adapter/Postgres/PgChangeFeedRelay_Runtime.res.mjs";
|
|
20
|
-
import { sendMessage } from "@reventlessdev/reventless-aws/src/util/Util_SQS_Runtime.res.mjs";
|
|
21
|
-
import { makeQueueRef, log } from "./HandlerFactoryHelpers.mjs";
|
|
22
|
-
|
|
23
|
-
// Standard (non-FIFO) EventCollector queue — no message group id needed. The
|
|
24
|
-
// SQS handler parses each body straight back to JSON (Util_SQS_Runtime.parseSqsRecord).
|
|
25
|
-
function makeSendBatch(targetQueueUrl) {
|
|
26
|
-
const queue = makeQueueRef(targetQueueUrl);
|
|
27
|
-
return (jsons) =>
|
|
28
|
-
Promise.all(jsons.map((json) => sendMessage(queue, undefined, JSON.stringify(json)))).then(
|
|
29
|
-
() => {}
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function handler(_event, _context) {
|
|
34
|
-
const configStr = process.env["HANDLER_CONFIG"] || '{"logs":[]}';
|
|
35
|
-
const config = JSON.parse(configStr);
|
|
36
|
-
const logs = config.logs || [];
|
|
37
|
-
|
|
38
|
-
await Promise.all(
|
|
39
|
-
logs.map(async (l) => {
|
|
40
|
-
const sendBatch = makeSendBatch(l.targetQueueUrl);
|
|
41
|
-
try {
|
|
42
|
-
const count =
|
|
43
|
-
l.kind === "classic"
|
|
44
|
-
? await relayClassic(l.pgConnection, l.logName, l.subscriber, sendBatch)
|
|
45
|
-
: await relay(l.pgConnection, l.logName, l.subscriber, l.partitionTag, sendBatch);
|
|
46
|
-
log.debug("relayed " + count + " event(s) for " + l.logName, { comp: "PgChangeFeedRelay" });
|
|
47
|
-
} catch (err) {
|
|
48
|
-
// Log and continue — a failed log this tick is retried next tick from its
|
|
49
|
-
// unchanged checkpoint (at-least-once; projections are idempotent).
|
|
50
|
-
log.warn("relay failed for " + l.logName + ": " + (err?.message ?? String(err)), {
|
|
51
|
-
comp: "PgChangeFeedRelay",
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
);
|
|
56
|
-
return "";
|
|
57
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
// One-shot Postgres schema-migration Lambda entry point (A3).
|
|
2
|
-
//
|
|
3
|
-
// Invoked once during `pulumi up` by an `aws.lambda.Invocation` resource, from
|
|
4
|
-
// INSIDE the DB's VPC, so the deploy runner needs no network path to a private
|
|
5
|
-
// RDS instance. Runs the exact idempotent `PgSchema.ensureSchema` the local
|
|
6
|
-
// backend runs at startup (reventless-local's `postgres` smart constructor), so
|
|
7
|
-
// the AWS schema is byte-identical to local — zero drift. Every statement is
|
|
8
|
-
// `IF NOT EXISTS`, so re-invocation (e.g. after a schema-DDL change bumps the
|
|
9
|
-
// Lambda layer) is safe.
|
|
10
|
-
//
|
|
11
|
-
// HANDLER_CONFIG shape:
|
|
12
|
-
// { "pgConnection": { host, port, database, username, secretArn } }
|
|
13
|
-
|
|
14
|
-
import { poolFor } from "@reventlessdev/reventless-aws/src/adapter/Postgres/PgRuntime.res.mjs";
|
|
15
|
-
import { ensureSchema } from "@reventlessdev/reventless-postgres/src/PgSchema.res.mjs";
|
|
16
|
-
import { log } from "./HandlerFactoryHelpers.mjs";
|
|
17
|
-
|
|
18
|
-
// Config parse → pool → ensureSchema, with the pool source injectable so the
|
|
19
|
-
// orchestration is integration-testable against a real Postgres without the
|
|
20
|
-
// Secrets Manager round-trip (mirrors PgChangeFeedRelay_Runtime's
|
|
21
|
-
// relayWithPool/relay split). `opts.makePool` defaults to the production `poolFor`.
|
|
22
|
-
export async function runMigration(config, opts = {}) {
|
|
23
|
-
if (!config.pgConnection) {
|
|
24
|
-
throw new Error("PgMigrationEntryPoint: HANDLER_CONFIG has no pgConnection");
|
|
25
|
-
}
|
|
26
|
-
// `poolFor` memoises one pool per secret ARN per container and resolves the
|
|
27
|
-
// RDS-managed password from Secrets Manager via a cached provider.
|
|
28
|
-
const makePool = opts.makePool ?? poolFor;
|
|
29
|
-
const pool = makePool(config.pgConnection);
|
|
30
|
-
await ensureSchema(pool);
|
|
31
|
-
log.info("ensureSchema completed for " + config.pgConnection.database, {
|
|
32
|
-
comp: "PgMigration",
|
|
33
|
-
});
|
|
34
|
-
return "ok";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function handler(_event, _context) {
|
|
38
|
-
const config = JSON.parse(process.env["HANDLER_CONFIG"] || "{}");
|
|
39
|
-
return runMigration(config);
|
|
40
|
-
}
|