@reventlessdev/reventless-aws 3.0.0-alpha.405 → 3.0.0-alpha.407
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
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
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.407 (2026-10-29)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/reventless-aws
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0-alpha.406 (2026-10-29)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @reventlessdev/reventless-aws
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# 3.0.0-alpha.405 (2026-10-29)
|
|
7
23
|
|
|
8
24
|
### 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.407",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -24,17 +24,17 @@
|
|
|
24
24
|
"yaml": "^2.8.3",
|
|
25
25
|
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.37",
|
|
26
26
|
"@reventlessdev/rescript-effect": "1.0.0-alpha.1",
|
|
27
|
-
"@reventlessdev/rescript-node": "2.0.0-alpha.24",
|
|
28
|
-
"@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.36",
|
|
29
27
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.13",
|
|
30
|
-
"@reventlessdev/rescript-
|
|
28
|
+
"@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.36",
|
|
29
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.24",
|
|
31
30
|
"@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
|
|
31
|
+
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
32
32
|
"@reventlessdev/rescript-web": "1.0.0-alpha.8",
|
|
33
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.
|
|
34
|
-
"@reventlessdev/reventless-
|
|
35
|
-
"@reventlessdev/reventless-
|
|
36
|
-
"@reventlessdev/reventless-
|
|
37
|
-
"@reventlessdev/reventless-
|
|
33
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.317",
|
|
34
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.214",
|
|
35
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.42",
|
|
36
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.181",
|
|
37
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.185"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"rescript": "12.3.1",
|
|
@@ -71,11 +71,29 @@ type registeredHandler = {
|
|
|
71
71
|
plugin?: string,
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
// Each Lambda keeps its own key cache, so an event naming a key fetches it here,
|
|
75
|
+
// before the handler decodes it; an event naming none passes straight through.
|
|
76
|
+
let withPreparedKeys = (
|
|
77
|
+
handleJsonEvents: ReventlessCore.EventCollector.jsonEventsHandler,
|
|
78
|
+
): ReventlessCore.EventCollector.jsonEventsHandler =>
|
|
79
|
+
stream =>
|
|
80
|
+
stream
|
|
81
|
+
->Stream.mapEffect(json =>
|
|
82
|
+
Reventless.Pii.needsPrepare([json])
|
|
83
|
+
? Effect.promise(() => Reventless.Pii.prepareOrThrow([json]))->Effect.map(_ => json)
|
|
84
|
+
: Effect.succeed(json)
|
|
85
|
+
)
|
|
86
|
+
->handleJsonEvents
|
|
87
|
+
|
|
74
88
|
let toStreamHandler = (
|
|
75
89
|
handleJsonEvents: ReventlessCore.EventCollector.jsonEventsHandler,
|
|
76
90
|
): streamHandler =>
|
|
77
91
|
(event, context) =>
|
|
78
|
-
EventCollectorChannel_DynamoDbStream_Runtime.handleStreamEvent(
|
|
92
|
+
EventCollectorChannel_DynamoDbStream_Runtime.handleStreamEvent(
|
|
93
|
+
withPreparedKeys(handleJsonEvents),
|
|
94
|
+
event,
|
|
95
|
+
context,
|
|
96
|
+
)
|
|
79
97
|
|
|
80
98
|
// Multiple components can share one source stream — e.g. every admin read
|
|
81
99
|
// model (Plugins, PluginHistory, PlatformEventGraph, UIFragmentRegistry)
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
4
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Stream from "effect/Stream";
|
|
7
|
+
import * as Pii$Reventless from "@reventlessdev/reventless-spec/src/components/Pii.res.mjs";
|
|
5
8
|
import * as HandlerFactoryHelpersMjs from "./HandlerFactoryHelpers.mjs";
|
|
6
9
|
import * as EventCollectorChannel_DynamoDbStream_Runtime$ReventlessAws from "../EventCollector/EventCollectorChannel_DynamoDbStream_Runtime.res.mjs";
|
|
7
10
|
|
|
@@ -41,8 +44,18 @@ function exnMessage(exn) {
|
|
|
41
44
|
return Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_JsExn.fromException(exn), Stdlib_JsExn.message), "unknown error");
|
|
42
45
|
}
|
|
43
46
|
|
|
47
|
+
function withPreparedKeys(handleJsonEvents) {
|
|
48
|
+
return stream => handleJsonEvents(Stream.mapEffect(stream, json => {
|
|
49
|
+
if (Pii$Reventless.needsPrepare([json])) {
|
|
50
|
+
return Effect.map(Effect.promise(() => Pii$Reventless.prepareOrThrow([json])), () => json);
|
|
51
|
+
} else {
|
|
52
|
+
return Effect.succeed(json);
|
|
53
|
+
}
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
function toStreamHandler(handleJsonEvents) {
|
|
45
|
-
return (event, context) => EventCollectorChannel_DynamoDbStream_Runtime$ReventlessAws.handleStreamEvent(handleJsonEvents, event, context);
|
|
58
|
+
return (event, context) => EventCollectorChannel_DynamoDbStream_Runtime$ReventlessAws.handleStreamEvent(withPreparedKeys(handleJsonEvents), event, context);
|
|
46
59
|
}
|
|
47
60
|
|
|
48
61
|
function addToRegistry(registry, sourceUrn, handler) {
|
|
@@ -115,6 +128,7 @@ export {
|
|
|
115
128
|
logWarn,
|
|
116
129
|
logError,
|
|
117
130
|
exnMessage,
|
|
131
|
+
withPreparedKeys,
|
|
118
132
|
toStreamHandler,
|
|
119
133
|
addToRegistry,
|
|
120
134
|
groupBySource,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// A Lambda's stream handler fetches the keys an event's sealed fields name before
|
|
2
|
+
// the component decodes it, and asks for nothing when an event names none.
|
|
3
|
+
|
|
4
|
+
open JestGlobals
|
|
5
|
+
|
|
6
|
+
let asked: ref<array<array<string>>> = ref([])
|
|
7
|
+
let provider: Reventless.Pii.provider = {
|
|
8
|
+
...Reventless.Pii.plain,
|
|
9
|
+
name: "counting",
|
|
10
|
+
prefetch: async keyIds => {
|
|
11
|
+
asked := asked.contents->Array.concat([keyIds])
|
|
12
|
+
Ok()
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let sealed =
|
|
17
|
+
Dict.fromArray([
|
|
18
|
+
(
|
|
19
|
+
"event",
|
|
20
|
+
Dict.fromArray([
|
|
21
|
+
("TAG", JSON.Encode.string("MemberNamed")),
|
|
22
|
+
("name", Reventless.Pii.wrap("enc:v1:k-7:fake:AAAA")),
|
|
23
|
+
])->JSON.Encode.object,
|
|
24
|
+
),
|
|
25
|
+
])->JSON.Encode.object
|
|
26
|
+
|
|
27
|
+
describe("StreamRoutedEntryPoint_Ops.withPreparedKeys", () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
asked := []
|
|
30
|
+
Reventless.Pii.Provider.install(provider)
|
|
31
|
+
})
|
|
32
|
+
afterEach(() => Reventless.Pii.Provider.install(Reventless.Pii.plain))
|
|
33
|
+
|
|
34
|
+
testPromise("prefetches before the handler sees the event, and only what it names", async () => {
|
|
35
|
+
let seen = ref([])
|
|
36
|
+
let handler: ReventlessCore.EventCollector.jsonEventsHandler = stream =>
|
|
37
|
+
stream->Stream.runForEach(
|
|
38
|
+
json =>
|
|
39
|
+
Effect.sync(
|
|
40
|
+
() => seen := seen.contents->Array.concat([(json, asked.contents->Array.length)]),
|
|
41
|
+
),
|
|
42
|
+
)
|
|
43
|
+
let wrapped = StreamRoutedEntryPoint_Ops.withPreparedKeys(handler)
|
|
44
|
+
let _ = await wrapped(
|
|
45
|
+
Stream.fromIterable([sealed, JSON.Encode.string("plain")]),
|
|
46
|
+
)->Effect.runPromise
|
|
47
|
+
expect(asked.contents)->toEqual([["k-7"]])
|
|
48
|
+
// The sealed event arrived after its key was asked for.
|
|
49
|
+
expect(seen.contents->Array.map(((_, n)) => n))->toEqual([1, 1])
|
|
50
|
+
})
|
|
51
|
+
})
|