@reventlessdev/reventless-aws 3.0.0-alpha.335 → 3.0.0-alpha.337

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,51 @@
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.337 (2026-09-04)
7
+
8
+ * feat(spec)!: one optional encoding on the wire, with no annotation ([320f91d](https://github.com/ReventlessDev/reventless-core/commit/320f91daa8bd90812a6e82069e7a1cb473041930))
9
+
10
+ ### BREAKING CHANGES
11
+
12
+ * the two encodings cannot read each other. Stored
13
+ pluginDefinition / pluginStructure payloads and already-deployed plugins must
14
+ go — wipe the platform scope (SEED_RESET_SCOPE=platform), quiesce, and
15
+ redeploy the fleet from one commit. Domain plugin data is untouched.
16
+
17
+ Two guards had to learn the new shape, both of which defined "optional" as
18
+ has.null and so mistook an omitted key for something to invent:
19
+
20
+ - Message.fillMissingDefaults reached `return undefined` only below two arms
21
+ that fire first — an enum's first const, and an object member filled with
22
+ zeros. Absent option<record> therefore healed to a zero-filled record, not
23
+ None: on the real schema, dcbEventLog became Some({name: "", eventTopicArn:
24
+ ""}), which manageSubscriptions would have read as a peer to subscribe to.
25
+ One line, mirroring the has.null guard, above both arms.
26
+ - PluginDefinitionScalars' walker reported 16 optional fields as newly-added
27
+ bare required scalars. With both encodings understood, the golden list is
28
+ unchanged.
29
+
30
+ The frozen lifecycle corpus holds five real payloads in the old encoding.
31
+ Null-valued keys were stripped mechanically — the rewrite round-trips each
32
+ file unchanged before editing, and a key-by-key diff shows null removals and
33
+ nothing else. The README records it beside the account-id redaction and says
34
+ why it is not a regeneration: no fixture was rebuilt from ReScript types, so
35
+ every generation in its table is still pinned.
36
+
37
+ check:graphql is unchanged, as expected: SchemaType.fromSury collapses Null
38
+ and Undefined to the same Nullable, so the emitted schema never distinguished
39
+ them.
40
+
41
+
42
+
43
+ # 3.0.0-alpha.336 (2026-09-04)
44
+
45
+ **Note:** Version bump only for package @reventlessdev/reventless-aws
46
+
47
+
48
+
49
+
50
+
6
51
  # 3.0.0-alpha.335 (2026-09-02)
7
52
 
8
53
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-aws",
3
- "version": "3.0.0-alpha.335",
3
+ "version": "3.0.0-alpha.337",
4
4
  "description": "AWS adapters for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -15,18 +15,18 @@
15
15
  "@aws-sdk/s3-request-presigner": "3.970.0",
16
16
  "sury": "11.0.0-rc.2",
17
17
  "uuid": "^13.0.0",
18
- "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.14",
18
+ "@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.15",
19
+ "@reventlessdev/rescript-node": "2.0.0-alpha.9",
19
20
  "@reventlessdev/rescript-jest": "1.0.0-alpha.10",
20
- "@reventlessdev/rescript-node": "2.0.0-alpha.8",
21
- "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.7",
22
21
  "@reventlessdev/rescript-effect": "0.1.0-alpha.32",
22
+ "@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.8",
23
23
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
24
24
  "@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
25
- "@reventlessdev/reventless-core": "3.0.0-alpha.254",
26
- "@reventlessdev/reventless-infra": "3.0.0-alpha.155",
27
- "@reventlessdev/reventless-interop": "3.0.0-alpha.34",
28
- "@reventlessdev/reventless-postgres": "3.0.0-alpha.118",
29
- "@reventlessdev/reventless-spec": "3.0.0-alpha.127"
25
+ "@reventlessdev/reventless-core": "3.0.0-alpha.256",
26
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.157",
27
+ "@reventlessdev/reventless-interop": "3.0.0-alpha.35",
28
+ "@reventlessdev/reventless-postgres": "3.0.0-alpha.120",
29
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.129"
30
30
  },
31
31
  "devDependencies": {
32
32
  "rescript": "12.3.0",
@@ -62,11 +62,11 @@ external scanByTableName: (
62
62
  let exnMessage = (exn: exn): string =>
63
63
  exn->JsExn.fromException->Option.flatMap(JsExn.message)->Option.getOr("unknown error")
64
64
 
65
- // ── js_nullable normalization ───────────────────────────────────────────────
66
- // pluginDefinition option fields use @s.matches(js_nullable): when the record
67
- // comes from a plain JSON.parse (not a sury parse), None is represented as
68
- // `null` — which ReScript's option (undefined-based) would misread as Some.
69
- // Normalize through Nullable so pattern matches see a real option.
65
+ // ── Absent-field normalization ──────────────────────────────────────────────
66
+ // pluginDefinition's optionals omit the key, so a plain JSON.parse (not a sury
67
+ // parse) yields `undefined` and ReScript reads it as None unaided. Kept because
68
+ // the same records also arrive from stores and peers written when an absent
69
+ // field was `null`, which ReScript's option would misread as Some.
70
70
 
71
71
  external optionAsNullable: option<'a> => Nullable.t<'a> = "%identity"
72
72
  let jsOption = (v: option<'a>): option<'a> => v->optionAsNullable->Nullable.toOption
@@ -237,10 +237,9 @@ let parseHandlerConfig = (rawJson: string): handlerConfig => {
237
237
 
238
238
  // ── Plugin-RM row projection ────────────────────────────────────────────────
239
239
  // The subset of the Plugin read-model state the subscription manager needs.
240
- // Deliberately sidesteps sury: the state schema marks many fields
241
- // `@s.matches(js_nullable …)`, but DDB drops undefined attributes on write, so
242
- // the unmarshalled row arrives with those keys *missing* and sury's strict
243
- // parser rejects them. Field types reuse the spec's definition records — the
240
+ // Deliberately sidesteps sury: DDB drops undefined attributes on write, so the
241
+ // unmarshalled row can arrive with keys sury's strict parser still expects — the
242
+ // offload fields among them, whose codec keeps its `null` arm. Field types reuse the spec's definition records — the
244
243
  // projection is a strict subset of Reventless.Plugin.pluginDefinition.
245
244
 
246
245
  type pluginProjection = {
@@ -325,8 +324,8 @@ let projectPluginRow = (row: JSON.t): option<pluginProjection> =>
325
324
 
326
325
  // A pluginDefinition viewed as a projection (the manage logic reads only the
327
326
  // shared subset; `status` is never read for the acting plugin). Array/option
328
- // fields stay js_nullable-normalized: a definition arriving over the wire, rather
329
- // than from loadPluginDefinition's decode, still carries null for an absent field.
327
+ // fields stay normalized: a definition arriving over the wire, rather than from
328
+ // loadPluginDefinition's decode, may still carry null for an absent field.
330
329
  let projectionOfDefinition = (d: Reventless.Plugin.pluginDefinition): pluginProjection => {
331
330
  id: d.id,
332
331
  status: "",