@reventlessdev/reventless-infra 3.0.0-alpha.163 → 3.0.0-alpha.165
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,29 @@
|
|
|
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.165 (2026-09-20)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/reventless-infra
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 3.0.0-alpha.164 (2026-09-16)
|
|
15
|
+
|
|
16
|
+
* feat(spec)!: infer the DCB partition key per slice, and drop @partitionTag where inference agrees ([6c10161](https://github.com/ReventlessDev/reventless-core/commit/6c101611d438beea4bc9175ae8ea0ea1f6f7493b))
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **core:** fail the build when an extension cannot find its slice's partition key ([cf2b093](https://github.com/ReventlessDev/reventless-core/commit/cf2b093dd5dc7cf9425cdac919cd3910fc4aeefd))
|
|
20
|
+
* **spec:** let a slice's chapter break a partition-key tie ([2b9ae77](https://github.com/ReventlessDev/reventless-core/commit/2b9ae77e98eb42177d2bdd4977bc62bb7c7911aa))
|
|
21
|
+
|
|
22
|
+
### BREAKING CHANGES
|
|
23
|
+
|
|
24
|
+
* DcbTag.derivePartitionTag is removed; a boundary whose
|
|
25
|
+
partition cannot be inferred no longer deploys.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
6
29
|
# 3.0.0-alpha.163 (2026-09-11)
|
|
7
30
|
|
|
8
31
|
* feat(spec)!: making a principal is a capability, so the provider is replaceable ([3e59b9b](https://github.com/ReventlessDev/reventless-core/commit/3e59b9b665cc7e4b6b6f156b63b1b6bd0c6181ca))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-infra",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.165",
|
|
4
4
|
"description": "Infrastructure types for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"sury-ppx": "11.0.0-rc.2",
|
|
18
18
|
"uuid": "^13.0.0",
|
|
19
19
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.33",
|
|
20
|
-
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.
|
|
20
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.21",
|
|
21
21
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
|
|
22
|
-
"@reventlessdev/reventless-spec": "3.0.0-alpha.
|
|
22
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.137"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"rescript": "12.3.0",
|
|
@@ -40,6 +40,8 @@ module type T = {
|
|
|
40
40
|
a cross-partition scalar command tag fans out into its own single-tag
|
|
41
41
|
decision-read clause. */
|
|
42
42
|
~crossPartitionTagKeys: array<string>=?,
|
|
43
|
+
/** This slice's partition, as `Dcb_Builder` derives it for the whole boundary. */
|
|
44
|
+
~partitionTag: Reventless.DcbTag.derivedPartitionTag=?,
|
|
43
45
|
~runtime: RuntimeHints.t=?,
|
|
44
46
|
~opts: Pulumi.ComponentResource.options=?,
|
|
45
47
|
) => component
|
|
@@ -10,7 +10,7 @@ type id = string
|
|
|
10
10
|
|
|
11
11
|
/** What `mapIncomingEvent` can do with a published event: command the wrapped
|
|
12
12
|
aggregate or slice, command the extension point, forward, or run a directive.
|
|
13
|
-
The slice forms take no id — the FIFO group
|
|
13
|
+
The slice forms take no id — the FIFO group is the slice's partition key. */
|
|
14
14
|
type incomingCommandAction<'aggregateCommand, 'extensionPointCommand, 'directive> =
|
|
15
15
|
| PublishAggregateCommand(id, 'aggregateCommand)
|
|
16
16
|
| PublishAggregateCommandAsync(promise<(id, 'aggregateCommand)>)
|
|
@@ -182,6 +182,11 @@ module type T = {
|
|
|
182
182
|
let delegateCommandNames: array<string>
|
|
183
183
|
let delegateEventNames: array<string>
|
|
184
184
|
|
|
185
|
+
/** The partition key slice commands to the Delegate are grouped by, inferred
|
|
186
|
+
from the Delegate alone — or why it cannot tell. Checked at assembly against
|
|
187
|
+
the plugin's own derivation, which sees what the slice reads. */
|
|
188
|
+
let delegatePartition: unit => result<Reventless.DcbTag.derivedPartitionTag, string>
|
|
189
|
+
|
|
185
190
|
let mapIncomingEvent: (
|
|
186
191
|
Reventless.Message.event'<string, ExtensionPoint.event>,
|
|
187
192
|
pluginDefinition,
|
|
@@ -216,28 +221,35 @@ module Make = (MappingImpl: Mapping): (
|
|
|
216
221
|
let acceptedTags = Reventless.DcbTag.extractAllVariantNames(Delegate.eventSchema)
|
|
217
222
|
let delegateEventNames = acceptedTags
|
|
218
223
|
|
|
219
|
-
// Partition
|
|
220
|
-
//
|
|
224
|
+
// Partition for `PublishStateChangeSliceCommand*`, which becomes the command's
|
|
225
|
+
// FIFO group. Inferred from the Delegate alone: its consumed arms are not in
|
|
226
|
+
// view, so a slice whose key only they decide needs `@partitionTag`. Throws
|
|
227
|
+
// when unresolved — an Aggregate, where `PublishAggregateCommand` is right.
|
|
221
228
|
let derivedPartitionTagLazy = ref(None)
|
|
222
229
|
let getDerivedPartitionTag = () =>
|
|
223
230
|
switch derivedPartitionTagLazy.contents {
|
|
224
231
|
| Some(d) => d
|
|
225
232
|
| None =>
|
|
226
|
-
let d = Reventless.DcbTag.
|
|
227
|
-
|
|
228
|
-
|
|
233
|
+
let d = Reventless.DcbTag.deriveSlicePartition({
|
|
234
|
+
name: Delegate.name,
|
|
235
|
+
commandSchema: Delegate.commandSchema->S.castToUnknown,
|
|
236
|
+
consumedEventSchema: S.unknown,
|
|
237
|
+
eventSchema: Delegate.eventSchema->S.castToUnknown,
|
|
238
|
+
moduleUrl: Delegate.moduleUrl,
|
|
239
|
+
})
|
|
229
240
|
derivedPartitionTagLazy := Some(d)
|
|
230
241
|
d
|
|
231
242
|
}
|
|
232
|
-
let
|
|
243
|
+
let delegatePartition = () =>
|
|
233
244
|
switch getDerivedPartitionTag() {
|
|
234
|
-
|
|
|
235
|
-
|
|
236
|
-
Reventless.DcbTag.getPartitionTagValue([{tags: tags}], pt)->Option.getOr("")
|
|
237
|
-
| Composite(spec) =>
|
|
238
|
-
let tags = Reventless.DcbTag.extractTags(Delegate.commandSchema, targetCmd)
|
|
239
|
-
Reventless.DcbTag.getCompositePartitionKeyValue(tags, spec)
|
|
245
|
+
| tag => Ok(tag)
|
|
246
|
+
| exception JsExn(err) => Error(err->JsExn.message->Option.getOr("no partition key"))
|
|
240
247
|
}
|
|
248
|
+
let derivePartitionId = (targetCmd: Delegate.command): string =>
|
|
249
|
+
Reventless.DcbTag.extractTags(
|
|
250
|
+
Delegate.commandSchema,
|
|
251
|
+
targetCmd,
|
|
252
|
+
)->Reventless.DcbTag.partitionValueOfTags(getDerivedPartitionTag())
|
|
241
253
|
|
|
242
254
|
// `comp` as an Effect log annotation; EffectLogger.install lifts it to the
|
|
243
255
|
// top-level JSON field.
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
4
|
import * as Uuid from "uuid";
|
|
5
5
|
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
6
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
6
7
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
8
|
import * as Effect from "effect/Effect";
|
|
8
9
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
9
10
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
10
11
|
import * as Message$Reventless from "@reventlessdev/reventless-spec/src/types/Message.res.mjs";
|
|
11
12
|
import * as AnsiStyle$Reventless from "@reventlessdev/reventless-spec/src/AnsiStyle.res.mjs";
|
|
13
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
12
14
|
import * as PluginExtensionPointSpec$ReventlessInfra from "./PluginExtensionPointSpec.res.mjs";
|
|
13
15
|
|
|
14
16
|
let schema = Sury.string;
|
|
@@ -65,25 +67,36 @@ function Make(MappingImpl) {
|
|
|
65
67
|
if (d !== undefined) {
|
|
66
68
|
return d;
|
|
67
69
|
}
|
|
68
|
-
let d$1 = DcbTag$Reventless.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
let d$1 = DcbTag$Reventless.deriveSlicePartition({
|
|
71
|
+
name: Delegate.name,
|
|
72
|
+
commandSchema: Delegate.commandSchema,
|
|
73
|
+
consumedEventSchema: Sury.unknown,
|
|
74
|
+
eventSchema: Delegate.eventSchema,
|
|
75
|
+
moduleUrl: Delegate.moduleUrl
|
|
76
|
+
});
|
|
73
77
|
derivedPartitionTagLazy.contents = d$1;
|
|
74
78
|
return d$1;
|
|
75
79
|
};
|
|
76
|
-
let
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
let delegatePartition = () => {
|
|
81
|
+
let tag;
|
|
82
|
+
try {
|
|
83
|
+
tag = getDerivedPartitionTag();
|
|
84
|
+
} catch (raw_err) {
|
|
85
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
86
|
+
if (err.RE_EXN_ID === "JsExn") {
|
|
87
|
+
return {
|
|
88
|
+
TAG: "Error",
|
|
89
|
+
_0: Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "no partition key")
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
throw err;
|
|
83
93
|
}
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
return {
|
|
95
|
+
TAG: "Ok",
|
|
96
|
+
_0: tag
|
|
97
|
+
};
|
|
86
98
|
};
|
|
99
|
+
let derivePartitionId = targetCmd => DcbTag$Reventless.partitionValueOfTags(DcbTag$Reventless.extractTags(Delegate.commandSchema, targetCmd), getDerivedPartitionTag());
|
|
87
100
|
let compLog = (comp, msg) => Effect.runSync(Effect.annotateLogs(Effect.logInfo(msg), "comp", comp));
|
|
88
101
|
let encodeMeta = (meta, service) => {
|
|
89
102
|
let newrecord = {...meta};
|
|
@@ -261,6 +274,7 @@ function Make(MappingImpl) {
|
|
|
261
274
|
issuedCommands: MappingImpl.issuedCommands,
|
|
262
275
|
delegateCommandNames: delegateCommandNames,
|
|
263
276
|
delegateEventNames: acceptedTags,
|
|
277
|
+
delegatePartition: delegatePartition,
|
|
264
278
|
mapIncomingEvent: mapIncomingEvent,
|
|
265
279
|
mapOutgoingEvent: mapOutgoingEvent
|
|
266
280
|
};
|