@reventlessdev/reventless-core 3.0.0-alpha.193 → 3.0.0-alpha.194

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,14 @@
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.194 (2026-07-30)
7
+
8
+ ### Bug Fixes
9
+
10
+ * **spec,core:** record the storageRef annotation instead of inferring it ([06fb5d6](https://github.com/ReventlessDev/reventless-core/commit/06fb5d671db91fb536acefd0c2db69d98671da39))
11
+ * **spec:** read a semantic marker through an optional field's wrapper ([abebaa9](https://github.com/ReventlessDev/reventless-core/commit/abebaa9e6c73986765bb3de589ba0414eb0d85da))
12
+
13
+
6
14
  # 3.0.0-alpha.193 (2026-07-30)
7
15
 
8
16
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-core",
3
- "version": "3.0.0-alpha.193",
3
+ "version": "3.0.0-alpha.194",
4
4
  "description": "Core package for Reventless framework",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -28,17 +28,17 @@
28
28
  "dependencies": {
29
29
  "sury": "11.0.0-alpha.4",
30
30
  "uuid": "^13.0.0",
31
- "@reventlessdev/rescript-hash-object": "1.2.0-alpha.13",
32
31
  "@reventlessdev/rescript-effect": "0.1.0-alpha.31",
33
32
  "@reventlessdev/rescript-fast-csv": "1.2.0-alpha.14",
34
- "@reventlessdev/rescript-jest": "1.0.0-alpha.9",
33
+ "@reventlessdev/rescript-hash-object": "1.2.0-alpha.13",
35
34
  "@reventlessdev/rescript-node-streams": "1.1.0-alpha.13",
35
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.9",
36
36
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.17",
37
- "@reventlessdev/rescript-ssh2": "1.1.0-alpha.14",
38
37
  "@reventlessdev/rescript-uuid": "1.1.0-alpha.17",
39
- "@reventlessdev/reventless-infra": "3.0.0-alpha.111",
40
- "@reventlessdev/reventless-spec": "3.0.0-alpha.86",
41
- "@reventlessdev/reventless-interop": "3.0.0-alpha.29"
38
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.112",
39
+ "@reventlessdev/rescript-ssh2": "1.1.0-alpha.14",
40
+ "@reventlessdev/reventless-interop": "3.0.0-alpha.29",
41
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.87"
42
42
  },
43
43
  "devDependencies": {
44
44
  "rescript": "12.3.0",
@@ -498,6 +498,14 @@ let make = (
498
498
  Reventless.Plugin.store: target.plugin->Option.getOr(name) ++ "." ++ target.store,
499
499
  component,
500
500
  field,
501
+ // The annotation as its author wrote it. `target.plugin` is `None`
502
+ // exactly when the field left the store unqualified, so this is the
503
+ // source text rather than a guess at it — and this is the only place
504
+ // that distinction survives.
505
+ annotation: switch target.plugin {
506
+ | None => target.store
507
+ | Some(plugin) => plugin ++ "." ++ target.store
508
+ },
501
509
  })
502
510
  )
503
511
 
@@ -447,11 +447,15 @@ function make(name, aggregatesOpt, readModelsOpt, stateViewSlicesOpt, stateChang
447
447
  let properties = v.properties;
448
448
  return Stdlib_Array.filterMap(Object.entries(properties), param => {
449
449
  let field = param[0];
450
- return Stdlib_Option.map(StorageRef$Reventless.getStore(param[1]), target => ({
451
- store: Stdlib_Option.getOr(target.plugin, name) + "." + target.store,
452
- component: component,
453
- field: field
454
- }));
450
+ return Stdlib_Option.map(StorageRef$Reventless.getStore(param[1]), target => {
451
+ let plugin = target.plugin;
452
+ return {
453
+ store: Stdlib_Option.getOr(target.plugin, name) + "." + target.store,
454
+ component: component,
455
+ field: field,
456
+ annotation: plugin !== undefined ? plugin + "." + target.store : target.store
457
+ };
458
+ });
455
459
  });
456
460
  } else {
457
461
  return [];
@@ -606,6 +606,22 @@ describe("SuryToJsonSchema:", () => {
606
606
  )->toEqual(Some(JSON.Encode.string("string")))
607
607
  })
608
608
 
609
+ // An optional field's marker sits inside the wrapper sury-ppx builds around
610
+ // it, so this used to emit a plain nullable string: the field was a storage
611
+ // ref in the source and an untyped string on the wire. The semantic now
612
+ // survives, and it rides *beside* the nullable shape rather than replacing
613
+ // it — a reader still learns the value may be absent.
614
+ testSync("an optional storage-ref field keeps both its semantic and its nullability", () => {
615
+ let schema = S.schema(s =>
616
+ {"imageUrl": s.matches(S.option(Reventless.StorageRef.forStore(~store="productImages")))}
617
+ )->S.castToUnknown
618
+ let json = SuryToJsonSchema.deriveObjectSchema(schema)
619
+ expect(semanticOf(json, "imageUrl"))->toEqual(Some(JSON.Encode.string("storageRef")))
620
+ expect(
621
+ getPropertyOf(json, "imageUrl")->Option.flatMap(s => getProperty(s, "oneOf"))->Option.isSome,
622
+ )->toBe(true)
623
+ })
624
+
609
625
  testSync("a type-carried semantic beats an annotation naming the same field", () => {
610
626
  let withSpec = (schema, spec) =>
611
627
  schema->S.Metadata.set(~id=Reventless.StateAnnotations.stateAnnotationsId, spec)
@@ -909,6 +909,14 @@ globalThis.describe("SuryToJsonSchema:", () => {
909
909
  let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema);
910
910
  globalThis.expect(Stdlib_Option.flatMap(getPropertyOf(json, "imageUrl"), s => getProperty(s, "type"))).toEqual("string");
911
911
  });
912
+ globalThis.test("an optional storage-ref field keeps both its semantic and its nullability", () => {
913
+ let schema = S.schema(s => ({
914
+ imageUrl: s.m(S.option(StorageRef$Reventless.forStore(undefined, "productImages")))
915
+ }));
916
+ let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(schema);
917
+ globalThis.expect(semanticOf(json, "imageUrl")).toEqual("storageRef");
918
+ globalThis.expect(Stdlib_Option.isSome(Stdlib_Option.flatMap(getPropertyOf(json, "imageUrl"), s => getProperty(s, "oneOf")))).toBe(true);
919
+ });
912
920
  globalThis.test("a type-carried semantic beats an annotation naming the same field", () => {
913
921
  let withSpec = (schema, spec) => S.Metadata.set(schema, StateAnnotations$Reventless.stateAnnotationsId, spec);
914
922
  let schema = withSpec(S.schema(s => ({
@@ -93,6 +93,20 @@ module PsAttachInvoiceSlice: ReventlessInfra.StateChangeSlice.T = {
93
93
  let make = (~dcbEventLog as _, ~publishJsons as _, ~tagKeysByEventType as _=?, ~crossPartitionTagKeys as _=?, ~runtime as _=?, ~opts as _=?): component => Obj.magic(0)
94
94
  }
95
95
 
96
+ module PsUploadAvatarSlice: ReventlessInfra.StateChangeSlice.T = {
97
+ module Spec = PsUploadAvatar
98
+ module Behavior = {
99
+ type state = PsUploadAvatar.state
100
+ let initialState = PsUploadAvatar.initialState
101
+ let evolve = PsUploadAvatar.evolve
102
+ let decide = PsUploadAvatar.decide
103
+ let moduleUrl = PsUploadAvatar.moduleUrl
104
+ }
105
+ let isAsync = false
106
+ type component = scsComponent
107
+ let make = (~dcbEventLog as _, ~publishJsons as _, ~tagKeysByEventType as _=?, ~crossPartitionTagKeys as _=?, ~runtime as _=?, ~opts as _=?): component => Obj.magic(0)
108
+ }
109
+
96
110
  module PsChangePhotoSlice: ReventlessInfra.StateChangeSlice.T = {
97
111
  module Spec = PsChangePhoto
98
112
  module Behavior = {
@@ -694,9 +708,22 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
694
708
  // `documents` is declared on a command field AND an event field of the
695
709
  // same component under the same field name — one declaration site, so
696
710
  // the identical triples collapse to one entry.
711
+ // `annotation` is the source text, not the key: the own-plugin store is
712
+ // written bare and the foreign one qualified, which is exactly the
713
+ // distinction no downstream comparison can recover.
697
714
  let expected: array<Reventless.Plugin.requiredStoreDeclaration> = [
698
- {store: "TestPlugin.documents", component: "AttachInvoice", field: "documentUrl"},
699
- {store: "branding.logos", component: "AttachInvoice", field: "logoUrl"},
715
+ {
716
+ store: "TestPlugin.documents",
717
+ component: "AttachInvoice",
718
+ field: "documentUrl",
719
+ annotation: "documents",
720
+ },
721
+ {
722
+ store: "branding.logos",
723
+ component: "AttachInvoice",
724
+ field: "logoUrl",
725
+ annotation: "branding.logos",
726
+ },
700
727
  ]
701
728
  expect(withStores.requiredStoreDeclarations)->toEqual(Some(expected))
702
729
  })
@@ -718,7 +745,7 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
718
745
  let entry =
719
746
  manifest.capabilities->Array.find(c => c.key == "TestPlugin.documents")->Option.getOrThrow
720
747
  let expected: array<Reventless.CapabilityManifest.provenance> = [
721
- {component: "AttachInvoice", field: "documentUrl"},
748
+ {component: "AttachInvoice", field: "documentUrl", annotation: "documents"},
722
749
  ]
723
750
  expect(entry.declaredBy)->toEqual(expected)
724
751
  })
@@ -738,7 +765,8 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
738
765
  "declaredBy": [
739
766
  {
740
767
  "component": "AttachInvoice",
741
- "field": "documentUrl"
768
+ "field": "documentUrl",
769
+ "annotation": "documents"
742
770
  }
743
771
  ]
744
772
  },
@@ -748,7 +776,8 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
748
776
  "declaredBy": [
749
777
  {
750
778
  "component": "AttachInvoice",
751
- "field": "logoUrl"
779
+ "field": "logoUrl",
780
+ "annotation": "branding.logos"
752
781
  }
753
782
  ]
754
783
  }
@@ -760,6 +789,45 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
760
789
  })
761
790
  })
762
791
 
792
+ // Making a field optional says the value may be absent. It does not say the
793
+ // field stopped being a storage ref or a reference — but both walks read the
794
+ // marker through `Semantic.get`, and an optional field's marker sits on the
795
+ // schema inside the wrapper sury-ppx builds. Until that unwrap existed, adding
796
+ // a `?` to a field silently un-declared its store: nothing failed, an S3
797
+ // bucket just stopped being provisioned.
798
+ describe("optional carriers keep their declarations", () => {
799
+ let withOptional = Plugin_Structure.make(
800
+ ~name="TestPlugin",
801
+ ~stateChangeSlices=[module(PsUploadAvatarSlice)],
802
+ )
803
+
804
+ testSync("an optional storage ref still requires its store", () =>
805
+ expect(withOptional.requiredStores)->toEqual(Some(["TestPlugin.avatars"]))
806
+ )
807
+
808
+ // Declared on the command and on the event under one field name — the same
809
+ // collapse the required case makes, so optionality does not change arity.
810
+ testSync("and still carries one declaring site", () => {
811
+ let expected: array<Reventless.Plugin.requiredStoreDeclaration> = [
812
+ {
813
+ store: "TestPlugin.avatars",
814
+ component: "UploadAvatar",
815
+ field: "avatarUrl",
816
+ annotation: "avatars",
817
+ },
818
+ ]
819
+ expect(withOptional.requiredStoreDeclarations)->toEqual(Some(expected))
820
+ })
821
+
822
+ testSync("an optional reference is still collected", () => {
823
+ let cmd = (withOptional.stateChangeSlices->Array.getUnsafe(0)).commands->Array.getUnsafe(0)
824
+ let expected: array<Reventless.Plugin.fieldReference> = [
825
+ {fieldName: "referredBy", entity: "Customers", plugin: None},
826
+ ]
827
+ expect(cmd.references)->toEqual(expected)
828
+ })
829
+ })
830
+
763
831
  // Declarations are authoritative; the name heuristics are a lint. A
764
832
  // heuristic-only match warns and never reaches the manifest, so nothing is
765
833
  // provisioned from a guess — `imageUrl` is genuinely ambiguous between an
@@ -13,6 +13,7 @@ import * as PsOrdersView$ReventlessCore from "./StateViewSlice/PsOrdersView.res.
13
13
  import * as PsPlaceOrder$ReventlessCore from "./StateChangeSlice/PsPlaceOrder.res.mjs";
14
14
  import * as PsChangePhoto$ReventlessCore from "./StateChangeSlice/PsChangePhoto.res.mjs";
15
15
  import * as CapabilityManifest$Reventless from "@reventlessdev/reventless-spec/src/components/CapabilityManifest.res.mjs";
16
+ import * as PsUploadAvatar$ReventlessCore from "./StateChangeSlice/PsUploadAvatar.res.mjs";
16
17
  import * as PsAnnotatedView$ReventlessCore from "./StateViewSlice/PsAnnotatedView.res.mjs";
17
18
  import * as PsAttachInvoice$ReventlessCore from "./StateChangeSlice/PsAttachInvoice.res.mjs";
18
19
  import * as PsCustomersView$ReventlessCore from "./StateViewSlice/PsCustomersView.res.mjs";
@@ -215,13 +216,43 @@ let PsAttachInvoiceSlice = {
215
216
  };
216
217
 
217
218
  let Behavior$3 = {
219
+ initialState: false,
220
+ evolve: PsUploadAvatar$ReventlessCore.evolve,
221
+ decide: PsUploadAvatar$ReventlessCore.decide,
222
+ moduleUrl: PsUploadAvatar$ReventlessCore.moduleUrl
223
+ };
224
+
225
+ function make$7(param, param$1, param$2, param$3, param$4, param$5) {
226
+ return 0;
227
+ }
228
+
229
+ let PsUploadAvatarSlice_Spec = {
230
+ name: PsUploadAvatar$ReventlessCore.name,
231
+ moduleUrl: PsUploadAvatar$ReventlessCore.moduleUrl,
232
+ Id: Id$Reventless.$$String,
233
+ consumedEventSchema: PsUploadAvatar$ReventlessCore.consumedEventSchema,
234
+ errorSchema: PsUploadAvatar$ReventlessCore.errorSchema,
235
+ eventSchema: PsUploadAvatar$ReventlessCore.eventSchema,
236
+ commandSchema: PsUploadAvatar$ReventlessCore.commandSchema,
237
+ commandAuthorization: PsUploadAvatar$ReventlessCore.commandAuthorization,
238
+ readConsistency: PsUploadAvatar$ReventlessCore.readConsistency
239
+ };
240
+
241
+ let PsUploadAvatarSlice = {
242
+ Spec: PsUploadAvatarSlice_Spec,
243
+ Behavior: Behavior$3,
244
+ isAsync: false,
245
+ make: make$7
246
+ };
247
+
248
+ let Behavior$4 = {
218
249
  initialState: false,
219
250
  evolve: PsChangePhoto$ReventlessCore.evolve,
220
251
  decide: PsChangePhoto$ReventlessCore.decide,
221
252
  moduleUrl: PsChangePhoto$ReventlessCore.moduleUrl
222
253
  };
223
254
 
224
- function make$7(param, param$1, param$2, param$3, param$4, param$5) {
255
+ function make$8(param, param$1, param$2, param$3, param$4, param$5) {
225
256
  return 0;
226
257
  }
227
258
 
@@ -239,9 +270,9 @@ let PsChangePhotoSlice_Spec = {
239
270
 
240
271
  let PsChangePhotoSlice = {
241
272
  Spec: PsChangePhotoSlice_Spec,
242
- Behavior: Behavior$3,
273
+ Behavior: Behavior$4,
243
274
  isAsync: false,
244
- make: make$7
275
+ make: make$8
245
276
  };
246
277
 
247
278
  let structure = Plugin_Structure$ReventlessCore.make("TestPlugin", undefined, undefined, [
@@ -757,12 +788,14 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
757
788
  {
758
789
  store: "TestPlugin.documents",
759
790
  component: "AttachInvoice",
760
- field: "documentUrl"
791
+ field: "documentUrl",
792
+ annotation: "documents"
761
793
  },
762
794
  {
763
795
  store: "branding.logos",
764
796
  component: "AttachInvoice",
765
- field: "logoUrl"
797
+ field: "logoUrl",
798
+ annotation: "branding.logos"
766
799
  }
767
800
  ];
768
801
  globalThis.expect(withStores.requiredStoreDeclarations).toEqual(expected);
@@ -776,7 +809,8 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
776
809
  let entry = Stdlib_Option.getOrThrow(manifest.capabilities.find(c => c.key === "TestPlugin.documents"), undefined);
777
810
  let expected = [{
778
811
  component: "AttachInvoice",
779
- field: "documentUrl"
812
+ field: "documentUrl",
813
+ annotation: "documents"
780
814
  }];
781
815
  globalThis.expect(entry.declaredBy).toEqual(expected);
782
816
  });
@@ -793,7 +827,8 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
793
827
  "declaredBy": [
794
828
  {
795
829
  "component": "AttachInvoice",
796
- "field": "documentUrl"
830
+ "field": "documentUrl",
831
+ "annotation": "documents"
797
832
  }
798
833
  ]
799
834
  },
@@ -803,7 +838,8 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
803
838
  "declaredBy": [
804
839
  {
805
840
  "component": "AttachInvoice",
806
- "field": "logoUrl"
841
+ "field": "logoUrl",
842
+ "annotation": "branding.logos"
807
843
  }
808
844
  ]
809
845
  }
@@ -813,6 +849,30 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
813
849
  });
814
850
  });
815
851
  });
852
+ globalThis.describe("optional carriers keep their declarations", () => {
853
+ let withOptional = Plugin_Structure$ReventlessCore.make("TestPlugin", undefined, undefined, undefined, [PsUploadAvatarSlice], undefined, undefined, undefined, undefined, undefined, undefined);
854
+ globalThis.test("an optional storage ref still requires its store", () => {
855
+ globalThis.expect(withOptional.requiredStores).toEqual(["TestPlugin.avatars"]);
856
+ });
857
+ globalThis.test("and still carries one declaring site", () => {
858
+ let expected = [{
859
+ store: "TestPlugin.avatars",
860
+ component: "UploadAvatar",
861
+ field: "avatarUrl",
862
+ annotation: "avatars"
863
+ }];
864
+ globalThis.expect(withOptional.requiredStoreDeclarations).toEqual(expected);
865
+ });
866
+ globalThis.test("an optional reference is still collected", () => {
867
+ let cmd = withOptional.stateChangeSlices[0].commands[0];
868
+ let expected = [{
869
+ fieldName: "referredBy",
870
+ entity: "Customers",
871
+ plugin: undefined
872
+ }];
873
+ globalThis.expect(cmd.references).toEqual(expected);
874
+ });
875
+ });
816
876
  globalThis.describe("capability inference", () => {
817
877
  let commandWarnings = Capability_Inference$ReventlessCore.scanSchema("ChangePhoto", PsChangePhoto$ReventlessCore.commandSchema);
818
878
  let eventWarnings = Capability_Inference$ReventlessCore.scanSchema("ChangePhoto", PsChangePhoto$ReventlessCore.eventSchema);
@@ -867,6 +927,7 @@ export {
867
927
  PsCustomersViewSlice,
868
928
  PsAnnotatedViewSlice,
869
929
  PsAttachInvoiceSlice,
930
+ PsUploadAvatarSlice,
870
931
  PsChangePhotoSlice,
871
932
  structure,
872
933
  }
@@ -0,0 +1,37 @@
1
+ // Test fixture spec where every semantic carrier is OPTIONAL.
2
+ //
3
+ // The marker of an optional field sits on the schema *inside* the
4
+ // undefined-union sury-ppx wraps it in, so a walk that reads only the outer
5
+ // schema finds nothing. That failure is silent in the worst way: the plugin
6
+ // compiles, deploys green, and provisions no object store — so `avatarUrl` is
7
+ // the only declarer of `avatars` here on purpose. If the unwrap regresses, the
8
+ // store requirement disappears entirely rather than merely losing a site.
9
+ //
10
+ // `referredBy` is the same trap for `@ref`: an optional reference that goes
11
+ // uncollected drops out of `commandDef.references`.
12
+
13
+ @@reventless.spec("UploadAvatar")
14
+
15
+ type state = bool
16
+ let initialState = false
17
+
18
+ @schema
19
+ type consumedEvent = OrderPlaced
20
+
21
+ let evolve = (_state, _event) => true
22
+
23
+ @schema
24
+ type command =
25
+ | UploadAvatar({
26
+ customerId: string,
27
+ @storageRef("avatars") avatarUrl?: string,
28
+ @ref("Customers") referredBy?: string,
29
+ })
30
+
31
+ @schema
32
+ type error = CustomerNotFound
33
+
34
+ @schema
35
+ type event = AvatarUploaded({customerId: string, @storageRef("avatars") avatarUrl?: string})
36
+
37
+ let decide = (_state, _command): result<array<event>, error> => Ok([])
@@ -0,0 +1,64 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+ import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
+ import * as Reference$Reventless from "@reventlessdev/reventless-spec/src/components/Reference.res.mjs";
6
+ import * as StorageRef$Reventless from "@reventlessdev/reventless-spec/src/semantic/StorageRef.res.mjs";
7
+
8
+ let consumedEventSchema = S.literal("OrderPlaced");
9
+
10
+ function evolve(_state, _event) {
11
+ return true;
12
+ }
13
+
14
+ let commandSchema = S.schema(s => ({
15
+ TAG: "UploadAvatar",
16
+ customerId: s.m(DcbTag$Reventless.string),
17
+ avatarUrl: s.m(S.option(StorageRef$Reventless.forStore(undefined, "avatars"))),
18
+ referredBy: s.m(S.option(Reference$Reventless.to_(undefined, undefined, "Customers")))
19
+ }));
20
+
21
+ let errorSchema = S.literal("CustomerNotFound");
22
+
23
+ let eventSchema = S.schema(s => ({
24
+ TAG: "AvatarUploaded",
25
+ customerId: s.m(DcbTag$Reventless.string),
26
+ avatarUrl: s.m(S.option(StorageRef$Reventless.forStore(undefined, "avatars")))
27
+ }));
28
+
29
+ function decide(_state, _command) {
30
+ return {
31
+ TAG: "Ok",
32
+ _0: []
33
+ };
34
+ }
35
+
36
+ function commandAuthorization(param) {
37
+ return "AllowAuthenticated";
38
+ }
39
+
40
+ let name = "UploadAvatar";
41
+
42
+ let Id;
43
+
44
+ let initialState = false;
45
+
46
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsUploadAvatar.res.mjs";
47
+
48
+ let readConsistency = "EscalateOnRetry";
49
+
50
+ export {
51
+ name,
52
+ Id,
53
+ initialState,
54
+ consumedEventSchema,
55
+ evolve,
56
+ commandSchema,
57
+ errorSchema,
58
+ eventSchema,
59
+ decide,
60
+ moduleUrl,
61
+ commandAuthorization,
62
+ readConsistency,
63
+ }
64
+ /* consumedEventSchema Not a pure module */