@reventlessdev/reventless-core 3.0.0-alpha.258 → 3.0.0-alpha.260

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/package.json +9 -9
  3. package/src/Projection.res +158 -40
  4. package/src/Projection.res.mjs +107 -28
  5. package/src/admin/UiFragmentRegistry/{StateChangeSlice → StateChange}/UiFragmentRegistry.res.mjs +1 -1
  6. package/src/admin/UiFragmentRegistry/{StateChangeSlice → StateChange}/UiFragmentRegistry_Behavior.res.mjs +1 -1
  7. package/src/admin/UiFragmentRegistry/{StateViewSlice → StateView}/UiFragments.res.mjs +1 -1
  8. package/src/admin/UiFragmentRegistry/{StateViewSlice → StateView}/UiFragments_Projection.res.mjs +1 -1
  9. package/src/components/Api/GraphQL_FragmentGenerator.res +16 -2
  10. package/src/components/Api/GraphQL_FragmentGenerator.res.mjs +13 -5
  11. package/src/components/Api/SchemaType.res +81 -1
  12. package/src/components/Api/SchemaType.res.mjs +82 -3
  13. package/src/components/Api/SuryToJsonSchema.res +10 -0
  14. package/src/components/Api/SuryToJsonSchema.res.mjs +135 -110
  15. package/src/components/ReadModel/ReadModel_Callback.res +5 -2
  16. package/src/components/ReadModel/ReadModel_Callback.res.mjs +2 -5
  17. package/src/components/StateViewSlice/StateViewSlice_Builder.res +7 -6
  18. package/src/components/StateViewSlice/StateViewSlice_Builder.res.mjs +2 -5
  19. package/src/components/StateViewSlice/StateViewSlice_Callback.res +3 -1
  20. package/src/components/StateViewSlice/StateViewSlice_Callback.res.mjs +1 -1
  21. package/src/plugin/component/Plugin_Structure.res +9 -46
  22. package/src/plugin/component/Plugin_Structure.res.mjs +8 -40
  23. package/src/plugin/connect/PluginExtensionPoint_UiFragment.res.mjs +1 -1
  24. package/tests/admin/AdminApiSchemaDriftTest.res.mjs +1 -1
  25. package/tests/api/BrandedMarkerCompositionTest.res +74 -0
  26. package/tests/api/BrandedMarkerCompositionTest.res.mjs +74 -0
  27. package/tests/api/PsBrandedMarkersReadModel.res +24 -0
  28. package/tests/api/PsBrandedMarkersReadModel.res.mjs +87 -0
  29. package/tests/api/SuryToJsonSchemaTest.res +91 -3
  30. package/tests/api/SuryToJsonSchemaTest.res.mjs +66 -4
  31. package/tests/plugin/PluginStructureAccessTest.res.mjs +3 -3
  32. package/tests/plugin/PluginStructureTest.res +24 -5
  33. package/tests/plugin/PluginStructureTest.res.mjs +32 -26
  34. package/tests/plugin/{StateChangeSlice → StateChange}/PsAttachInvoice.res.mjs +1 -1
  35. package/tests/plugin/{StateChangeSlice → StateChange}/PsChangePhoto.res.mjs +1 -1
  36. package/tests/plugin/{StateChangeSlice → StateChange}/PsDispatchShipment.res.mjs +1 -1
  37. package/tests/plugin/{StateChangeSlice → StateChange}/PsGatedCommands.res.mjs +1 -1
  38. package/tests/plugin/{StateChangeSlice → StateChange}/PsPlaceOrder.res.mjs +1 -1
  39. package/tests/plugin/{StateChangeSlice → StateChange}/PsReserveStock.res.mjs +1 -1
  40. package/tests/plugin/{StateChangeSlice → StateChange}/PsShipOrder.res.mjs +1 -1
  41. package/tests/plugin/{StateChangeSlice → StateChange}/PsTransitionSwitch.res.mjs +1 -1
  42. package/tests/plugin/{StateChangeSlice → StateChange}/PsTypoStore.res.mjs +1 -1
  43. package/tests/plugin/{StateChangeSlice → StateChange}/PsUploadAvatar.res.mjs +1 -1
  44. package/tests/plugin/{StateChangeSlice → StateChange}/PsUploadImages.res.mjs +1 -1
  45. package/tests/plugin/{StateViewSlice → StateView}/PsAnnotatedView.res +4 -2
  46. package/tests/plugin/{StateViewSlice → StateView}/PsAnnotatedView.res.mjs +8 -4
  47. package/tests/plugin/{StateViewSlice → StateView}/PsAvailableProductsView.res.mjs +1 -1
  48. package/tests/plugin/{StateViewSlice → StateView}/PsCategoriesView.res.mjs +1 -1
  49. package/tests/plugin/{StateViewSlice → StateView}/PsCustomersView.res.mjs +1 -1
  50. package/tests/plugin/{StateViewSlice → StateView}/PsGatedView.res.mjs +1 -1
  51. package/tests/plugin/{StateViewSlice → StateView}/PsOrdersView.res.mjs +1 -1
  52. package/tests/plugin/{StateViewSlice → StateView}/PsShipmentsView.res.mjs +1 -1
  53. package/tests/projection/LifecycleTrailTest.res +139 -0
  54. package/tests/projection/LifecycleTrailTest.res.mjs +280 -0
  55. /package/src/admin/UiFragmentRegistry/{StateChangeSlice → StateChange}/UiFragmentRegistry.res +0 -0
  56. /package/src/admin/UiFragmentRegistry/{StateChangeSlice → StateChange}/UiFragmentRegistry_Behavior.res +0 -0
  57. /package/src/admin/UiFragmentRegistry/{StateViewSlice → StateView}/UiFragments.res +0 -0
  58. /package/src/admin/UiFragmentRegistry/{StateViewSlice → StateView}/UiFragments_Projection.res +0 -0
  59. /package/tests/plugin/{StateChangeSlice → StateChange}/PsAttachInvoice.res +0 -0
  60. /package/tests/plugin/{StateChangeSlice → StateChange}/PsChangePhoto.res +0 -0
  61. /package/tests/plugin/{StateChangeSlice → StateChange}/PsDispatchShipment.res +0 -0
  62. /package/tests/plugin/{StateChangeSlice → StateChange}/PsGatedCommands.res +0 -0
  63. /package/tests/plugin/{StateChangeSlice → StateChange}/PsPlaceOrder.res +0 -0
  64. /package/tests/plugin/{StateChangeSlice → StateChange}/PsReserveStock.res +0 -0
  65. /package/tests/plugin/{StateChangeSlice → StateChange}/PsShipOrder.res +0 -0
  66. /package/tests/plugin/{StateChangeSlice → StateChange}/PsTransitionSwitch.res +0 -0
  67. /package/tests/plugin/{StateChangeSlice → StateChange}/PsTypoStore.res +0 -0
  68. /package/tests/plugin/{StateChangeSlice → StateChange}/PsUploadAvatar.res +0 -0
  69. /package/tests/plugin/{StateChangeSlice → StateChange}/PsUploadImages.res +0 -0
  70. /package/tests/plugin/{StateViewSlice → StateView}/PsAvailableProductsView.res +0 -0
  71. /package/tests/plugin/{StateViewSlice → StateView}/PsCategoriesView.res +0 -0
  72. /package/tests/plugin/{StateViewSlice → StateView}/PsCustomersView.res +0 -0
  73. /package/tests/plugin/{StateViewSlice → StateView}/PsGatedView.res +0 -0
  74. /package/tests/plugin/{StateViewSlice → StateView}/PsOrdersView.res +0 -0
  75. /package/tests/plugin/{StateViewSlice → StateView}/PsShipmentsView.res +0 -0
@@ -11,7 +11,7 @@ import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js
11
11
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
12
12
  import * as Percent$Reventless from "@reventlessdev/reventless-spec/src/semantic/Percent.res.mjs";
13
13
  import * as Currency$Reventless from "@reventlessdev/reventless-spec/src/semantic/Currency.res.mjs";
14
- import * as DateTime$Reventless from "@reventlessdev/reventless-spec/src/types/DateTime.res.mjs";
14
+ import * as DateTime$Reventless from "@reventlessdev/reventless-spec/src/semantic/DateTime.res.mjs";
15
15
  import * as GeoPoint$Reventless from "@reventlessdev/reventless-spec/src/semantic/GeoPoint.res.mjs";
16
16
  import * as Semantic$Reventless from "@reventlessdev/reventless-spec/src/semantic/Semantic.res.mjs";
17
17
  import * as DateRange$Reventless from "@reventlessdev/reventless-spec/src/semantic/DateRange.res.mjs";
@@ -19,6 +19,8 @@ import * as MemberRef$Reventless from "@reventlessdev/reventless-spec/src/semant
19
19
  import * as Reference$Reventless from "@reventlessdev/reventless-spec/src/components/Reference.res.mjs";
20
20
  import * as Sensitive$Reventless from "@reventlessdev/reventless-spec/src/components/Sensitive.res.mjs";
21
21
  import * as StorageRef$Reventless from "@reventlessdev/reventless-spec/src/semantic/StorageRef.res.mjs";
22
+ import * as CalendarDate$Reventless from "@reventlessdev/reventless-spec/src/semantic/CalendarDate.res.mjs";
23
+ import * as FieldDefault$Reventless from "@reventlessdev/reventless-spec/src/components/FieldDefault.res.mjs";
22
24
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
23
25
  import * as SuryToJsonSchema$ReventlessCore from "../../src/components/Api/SuryToJsonSchema.res.mjs";
24
26
 
@@ -103,13 +105,43 @@ globalThis.describe("SuryToJsonSchema:", () => {
103
105
  });
104
106
  globalThis.test("emits format:\"date-time\" for a DateTime-marked string field", () => {
105
107
  let schema = Sury.$schema(s => ({
106
- placedAt: s.m(DateTime$Reventless.string),
108
+ placedAt: s.m(DateTime$Reventless.schema),
107
109
  name: s.m(Sury.string)
108
110
  }));
109
111
  let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, schema);
110
112
  globalThis.expect(Stdlib_Option.flatMap(Stdlib_Option.flatMap(getPropertyOf(json, "placedAt"), s => getProperty(s, "format")), Stdlib_JSON.Decode.string)).toBe("date-time");
111
113
  globalThis.expect(Stdlib_Option.flatMap(getPropertyOf(json, "name"), s => getProperty(s, "format"))).toBe(undefined);
112
114
  });
115
+ globalThis.test("a DateTime field emits format and no semantic key", () => {
116
+ let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, Sury.$schema(s => ({
117
+ placedAt: s.m(DateTime$Reventless.schema)
118
+ })));
119
+ let keyOf = key => Stdlib_Option.flatMap(getPropertyOf(json, "placedAt"), s => getProperty(s, key));
120
+ globalThis.expect([
121
+ keyOf("type"),
122
+ keyOf("format"),
123
+ keyOf("x-reventless-semantic")
124
+ ]).toEqual([
125
+ "string",
126
+ "date-time",
127
+ undefined
128
+ ]);
129
+ });
130
+ globalThis.test("a CalendarDate field emits format:\"date\" AND the semantic key", () => {
131
+ let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, Sury.$schema(s => ({
132
+ issuedOn: s.m(CalendarDate$Reventless.schema)
133
+ })));
134
+ let keyOf = key => Stdlib_Option.flatMap(getPropertyOf(json, "issuedOn"), s => getProperty(s, key));
135
+ globalThis.expect([
136
+ keyOf("type"),
137
+ keyOf("format"),
138
+ keyOf("x-reventless-semantic")
139
+ ]).toEqual([
140
+ "string",
141
+ "date",
142
+ "date"
143
+ ]);
144
+ });
113
145
  });
114
146
  globalThis.describe("deriveObjectSchema with an owner field:", () => {
115
147
  let ownerOf = (json, name) => Stdlib_Option.flatMap(getPropertyOf(json, name), s => getProperty(s, "x-reventless-owner"));
@@ -847,7 +879,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
847
879
  globalThis.test("neither reference nor tag emits x-reventless-semantic on the wire", () => {
848
880
  let schema = Sury.$schema(s => ({
849
881
  customerId: s.m(Reference$Reventless.to_(undefined, undefined, "Customer")),
850
- placedAt: s.m(DateTime$Reventless.string)
882
+ placedAt: s.m(DateTime$Reventless.schema)
851
883
  }));
852
884
  let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, schema);
853
885
  let semanticOf = fieldName => Stdlib_Option.flatMap(getPropertyOf(json, fieldName), s => getProperty(s, "x-reventless-semantic"));
@@ -1042,7 +1074,7 @@ globalThis.describe("SuryToJsonSchema:", () => {
1042
1074
  globalThis.describe("DateRange is an object whose parts stay date-times:", () => {
1043
1075
  let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, Sury.$schema(s => ({
1044
1076
  deliveryWindow: s.m(DateRange$Reventless.schema),
1045
- orderedAt: s.m(DateTime$Reventless.string)
1077
+ orderedAt: s.m(DateTime$Reventless.schema)
1046
1078
  })));
1047
1079
  let keyOf = (name, key) => Stdlib_Option.flatMap(getPropertyOf(json, name), s => getProperty(s, key));
1048
1080
  globalThis.test("the field is an object, not a string", () => {
@@ -1132,6 +1164,36 @@ globalThis.describe("SuryToJsonSchema:", () => {
1132
1164
  globalThis.expect(nestedRequired.includes("street")).toBe(true);
1133
1165
  });
1134
1166
  });
1167
+ globalThis.describe("a field declaring a default:", () => {
1168
+ let defaultOf = (json, field) => Stdlib_Option.flatMap(getPropertyOf(json, field), s => getProperty(s, "default"));
1169
+ let json = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, Sury.$schema(s => ({
1170
+ quantity: s.m(FieldDefault$Reventless.int(Sury.int, 1)),
1171
+ shippingMethod: s.m(FieldDefault$Reventless.string(Sury.string, "Standard")),
1172
+ plain: s.m(Sury.int)
1173
+ })));
1174
+ globalThis.test("carries it as `default`", () => {
1175
+ globalThis.expect(defaultOf(json, "quantity")).toEqual(1);
1176
+ });
1177
+ globalThis.test("keeps the shape the value actually has", () => {
1178
+ globalThis.expect(Stdlib_Option.flatMap(getPropertyOf(json, "quantity"), s => getProperty(s, "type"))).toEqual("integer");
1179
+ });
1180
+ globalThis.test("carries a string default the same way", () => {
1181
+ globalThis.expect(defaultOf(json, "shippingMethod")).toEqual("Standard");
1182
+ });
1183
+ globalThis.test("while a field declaring none says nothing", () => {
1184
+ globalThis.expect(defaultOf(json, "plain")).toBe(undefined);
1185
+ });
1186
+ globalThis.test("and reaches a field of a nested record", () => {
1187
+ let lineItem = Sury.$schema(s => ({
1188
+ productId: s.m(Sury.string),
1189
+ quantity: s.m(FieldDefault$Reventless.int(Sury.int, 1))
1190
+ }));
1191
+ let nested = SuryToJsonSchema$ReventlessCore.deriveObjectSchema(undefined, undefined, Sury.$schema(s => ({
1192
+ lineItems: s.m(Sury.array(lineItem))
1193
+ })));
1194
+ globalThis.expect(Stdlib_Option.flatMap(Stdlib_Option.flatMap(getPropertyOf(nested, "lineItems"), a => getProperty(a, "items")), i => defaultOf(i, "quantity"))).toEqual(1);
1195
+ });
1196
+ });
1135
1197
  });
1136
1198
 
1137
1199
  export {
@@ -2,9 +2,9 @@
2
2
 
3
3
  import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
4
4
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
- import * as PsGatedView$ReventlessCore from "./StateViewSlice/PsGatedView.res.mjs";
6
- import * as PsOrdersView$ReventlessCore from "./StateViewSlice/PsOrdersView.res.mjs";
7
- import * as PsGatedCommands$ReventlessCore from "./StateChangeSlice/PsGatedCommands.res.mjs";
5
+ import * as PsGatedView$ReventlessCore from "./StateView/PsGatedView.res.mjs";
6
+ import * as PsOrdersView$ReventlessCore from "./StateView/PsOrdersView.res.mjs";
7
+ import * as PsGatedCommands$ReventlessCore from "./StateChange/PsGatedCommands.res.mjs";
8
8
  import * as Plugin_Structure$ReventlessCore from "../../src/plugin/component/Plugin_Structure.res.mjs";
9
9
  import * as Platform_ComponentDefinitionsApi$ReventlessCore from "../../src/admin/Platform_ComponentDefinitionsApi.res.mjs";
10
10
 
@@ -804,8 +804,8 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
804
804
  let schema = S.schema(s =>
805
805
  {
806
806
  "orderId": s.matches(Reventless.Reference.to_("Order")),
807
- "placedAt": s.matches(Reventless.DateTime.string),
808
- "shippedAt": s.matches(Reventless.DateTime.string),
807
+ "placedAt": s.matches(Reventless.DateTime.schema),
808
+ "shippedAt": s.matches(Reventless.DateTime.schema),
809
809
  }
810
810
  )
811
811
  expect(labelOf(schema))->toEqual(("id", []))
@@ -814,7 +814,7 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
814
814
  testSync("a DateTime is skipped, not fatal — a later plain string still wins", () => {
815
815
  let schema = S.schema(s =>
816
816
  {
817
- "placedAt": s.matches(Reventless.DateTime.string),
817
+ "placedAt": s.matches(Reventless.DateTime.schema),
818
818
  "reference": s.matches(S.string),
819
819
  }
820
820
  )
@@ -988,7 +988,7 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
988
988
  let schema = S.schema(s =>
989
989
  {
990
990
  "orderId": s.matches(Reventless.Reference.to_("Order")),
991
- "placedAt": s.matches(Reventless.DateTime.string),
991
+ "placedAt": s.matches(Reventless.DateTime.schema),
992
992
  }
993
993
  )
994
994
  expect(sourceOf(schema))->toEqual("fallback")
@@ -1086,7 +1086,7 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1086
1086
 
1087
1087
  describe("lifecycleField — the name rule and the shape rule", () => {
1088
1088
  let lifecycleOf = schema =>
1089
- Plugin_Structure.lifecycleFieldFromStateSchema(~entityName="Test", schema->S.castToUnknown)
1089
+ Plugin_Structure.lifecycleFieldFromStateSchema(schema->S.castToUnknown)
1090
1090
 
1091
1091
  let withLifecycle = (schema, ~field) =>
1092
1092
  schema->S.castToUnknown->S.Metadata.set(
@@ -1458,6 +1458,25 @@ describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1458
1458
  )->toEqual(["contact"])
1459
1459
  )
1460
1460
 
1461
+ // JSON Schema's own keyword rather than an `x-reventless-` one, so a client
1462
+ // that knows nothing about Reventless reads it.
1463
+ testSync("@default flows through the PPX to JSON Schema's `default`", () => {
1464
+ expect(
1465
+ annotatedSchema
1466
+ ->getPropertyOf("quantity")
1467
+ ->Option.flatMap(s => getProperty(s, "default")),
1468
+ )->toEqual(Some(JSON.Encode.int(1)))
1469
+ })
1470
+
1471
+ testSync("@default leaves the field's own shape alone", () => {
1472
+ expect(
1473
+ annotatedSchema
1474
+ ->getPropertyOf("quantity")
1475
+ ->Option.flatMap(s => getProperty(s, "type"))
1476
+ ->Option.flatMap(JSON.Decode.string),
1477
+ )->toBe(Some("integer"))
1478
+ })
1479
+
1461
1480
  testSync("@metric flows through the PPX to x-reventless-metric {aggregate,label}", () => {
1462
1481
  let metricObj =
1463
1482
  annotatedSchema
@@ -8,32 +8,32 @@ import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.
8
8
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
9
9
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
10
10
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
11
- import * as DateTime$Reventless from "@reventlessdev/reventless-spec/src/types/DateTime.res.mjs";
11
+ import * as DateTime$Reventless from "@reventlessdev/reventless-spec/src/semantic/DateTime.res.mjs";
12
12
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
13
13
  import * as Reference$Reventless from "@reventlessdev/reventless-spec/src/components/Reference.res.mjs";
14
14
  import * as Sensitive$Reventless from "@reventlessdev/reventless-spec/src/components/Sensitive.res.mjs";
15
15
  import * as StorageRef$Reventless from "@reventlessdev/reventless-spec/src/semantic/StorageRef.res.mjs";
16
16
  import * as Api_Naming$ReventlessCore from "../../src/components/Api/Api_Naming.res.mjs";
17
- import * as PsShipOrder$ReventlessCore from "./StateChangeSlice/PsShipOrder.res.mjs";
18
- import * as PsTypoStore$ReventlessCore from "./StateChangeSlice/PsTypoStore.res.mjs";
19
- import * as PsOrdersView$ReventlessCore from "./StateViewSlice/PsOrdersView.res.mjs";
20
- import * as PsPlaceOrder$ReventlessCore from "./StateChangeSlice/PsPlaceOrder.res.mjs";
17
+ import * as PsShipOrder$ReventlessCore from "./StateChange/PsShipOrder.res.mjs";
18
+ import * as PsTypoStore$ReventlessCore from "./StateChange/PsTypoStore.res.mjs";
19
+ import * as PsOrdersView$ReventlessCore from "./StateView/PsOrdersView.res.mjs";
20
+ import * as PsPlaceOrder$ReventlessCore from "./StateChange/PsPlaceOrder.res.mjs";
21
21
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
22
- import * as PsChangePhoto$ReventlessCore from "./StateChangeSlice/PsChangePhoto.res.mjs";
22
+ import * as PsChangePhoto$ReventlessCore from "./StateChange/PsChangePhoto.res.mjs";
23
23
  import * as CapabilityManifest$Reventless from "@reventlessdev/reventless-spec/src/components/CapabilityManifest.res.mjs";
24
- import * as PsReserveStock$ReventlessCore from "./StateChangeSlice/PsReserveStock.res.mjs";
25
- import * as PsUploadAvatar$ReventlessCore from "./StateChangeSlice/PsUploadAvatar.res.mjs";
26
- import * as PsUploadImages$ReventlessCore from "./StateChangeSlice/PsUploadImages.res.mjs";
27
- import * as PsAnnotatedView$ReventlessCore from "./StateViewSlice/PsAnnotatedView.res.mjs";
28
- import * as PsAttachInvoice$ReventlessCore from "./StateChangeSlice/PsAttachInvoice.res.mjs";
29
- import * as PsCustomersView$ReventlessCore from "./StateViewSlice/PsCustomersView.res.mjs";
30
- import * as PsShipmentsView$ReventlessCore from "./StateViewSlice/PsShipmentsView.res.mjs";
24
+ import * as PsReserveStock$ReventlessCore from "./StateChange/PsReserveStock.res.mjs";
25
+ import * as PsUploadAvatar$ReventlessCore from "./StateChange/PsUploadAvatar.res.mjs";
26
+ import * as PsUploadImages$ReventlessCore from "./StateChange/PsUploadImages.res.mjs";
27
+ import * as PsAnnotatedView$ReventlessCore from "./StateView/PsAnnotatedView.res.mjs";
28
+ import * as PsAttachInvoice$ReventlessCore from "./StateChange/PsAttachInvoice.res.mjs";
29
+ import * as PsCustomersView$ReventlessCore from "./StateView/PsCustomersView.res.mjs";
30
+ import * as PsShipmentsView$ReventlessCore from "./StateView/PsShipmentsView.res.mjs";
31
31
  import * as Plugin_Structure$ReventlessCore from "../../src/plugin/component/Plugin_Structure.res.mjs";
32
- import * as PsCategoriesView$ReventlessCore from "./StateViewSlice/PsCategoriesView.res.mjs";
33
- import * as PsDispatchShipment$ReventlessCore from "./StateChangeSlice/PsDispatchShipment.res.mjs";
34
- import * as PsTransitionSwitch$ReventlessCore from "./StateChangeSlice/PsTransitionSwitch.res.mjs";
32
+ import * as PsCategoriesView$ReventlessCore from "./StateView/PsCategoriesView.res.mjs";
33
+ import * as PsDispatchShipment$ReventlessCore from "./StateChange/PsDispatchShipment.res.mjs";
34
+ import * as PsTransitionSwitch$ReventlessCore from "./StateChange/PsTransitionSwitch.res.mjs";
35
35
  import * as Capability_Inference$ReventlessCore from "../../src/plugin/component/Capability_Inference.res.mjs";
36
- import * as PsAvailableProductsView$ReventlessCore from "./StateViewSlice/PsAvailableProductsView.res.mjs";
36
+ import * as PsAvailableProductsView$ReventlessCore from "./StateView/PsAvailableProductsView.res.mjs";
37
37
 
38
38
  let Behavior = {
39
39
  initialState: false,
@@ -1023,8 +1023,8 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1023
1023
  globalThis.test("a DateTime is not a name — a state whose only string is one falls to id", () => {
1024
1024
  let schema = Sury.$schema(s => ({
1025
1025
  orderId: s.m(Reference$Reventless.to_(undefined, undefined, "Order")),
1026
- placedAt: s.m(DateTime$Reventless.string),
1027
- shippedAt: s.m(DateTime$Reventless.string)
1026
+ placedAt: s.m(DateTime$Reventless.schema),
1027
+ shippedAt: s.m(DateTime$Reventless.schema)
1028
1028
  }));
1029
1029
  globalThis.expect(labelOf(undefined, schema)).toEqual([
1030
1030
  "id",
@@ -1033,7 +1033,7 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1033
1033
  });
1034
1034
  globalThis.test("a DateTime is skipped, not fatal — a later plain string still wins", () => {
1035
1035
  let schema = Sury.$schema(s => ({
1036
- placedAt: s.m(DateTime$Reventless.string),
1036
+ placedAt: s.m(DateTime$Reventless.schema),
1037
1037
  reference: s.m(Sury.string)
1038
1038
  }));
1039
1039
  globalThis.expect(labelOf(undefined, schema)).toEqual([
@@ -1188,7 +1188,7 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1188
1188
  globalThis.test("no candidate at all is the state saying it has no human field", () => {
1189
1189
  let schema = Sury.$schema(s => ({
1190
1190
  orderId: s.m(Reference$Reventless.to_(undefined, undefined, "Order")),
1191
- placedAt: s.m(DateTime$Reventless.string)
1191
+ placedAt: s.m(DateTime$Reventless.schema)
1192
1192
  }));
1193
1193
  globalThis.expect(sourceOf(schema)).toEqual("fallback");
1194
1194
  });
@@ -1274,7 +1274,7 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1274
1274
  Sury.literal("Shipped")
1275
1275
  ]))
1276
1276
  }));
1277
- globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema("Test", schema)).toEqual("lifecycle");
1277
+ globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema(schema)).toEqual("lifecycle");
1278
1278
  });
1279
1279
  globalThis.test("an optional one counts too", () => {
1280
1280
  let schema = Sury.$schema(s => ({
@@ -1283,13 +1283,13 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1283
1283
  Sury.literal("Shipped")
1284
1284
  ])))
1285
1285
  }));
1286
- globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema("Test", schema)).toEqual("lifecycle");
1286
+ globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema(schema)).toEqual("lifecycle");
1287
1287
  });
1288
1288
  globalThis.test("free text named `lifecycle` is not a lifecycle", () => {
1289
1289
  let schema = Sury.$schema(s => ({
1290
1290
  lifecycle: s.m(Sury.string)
1291
1291
  }));
1292
- globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema("Test", schema)).toEqual(undefined);
1292
+ globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema(schema)).toEqual(undefined);
1293
1293
  });
1294
1294
  globalThis.test("an unannotated field named `status` resolves to None", () => {
1295
1295
  let schema = Sury.$schema(s => ({
@@ -1298,7 +1298,7 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1298
1298
  Sury.literal("Shipped")
1299
1299
  ]))
1300
1300
  }));
1301
- globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema("Test", schema)).toEqual(undefined);
1301
+ globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema(schema)).toEqual(undefined);
1302
1302
  });
1303
1303
  globalThis.test("the annotation names a field the convention would never reach", () => {
1304
1304
  let schema = Sury.$schema(s => ({
@@ -1307,7 +1307,7 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1307
1307
  Sury.literal("Located")
1308
1308
  ]))
1309
1309
  }));
1310
- globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema("Test", withLifecycle(schema, "locationStatus"))).toEqual("locationStatus");
1310
+ globalThis.expect(Plugin_Structure$ReventlessCore.lifecycleFieldFromStateSchema(withLifecycle(schema, "locationStatus"))).toEqual("locationStatus");
1311
1311
  });
1312
1312
  });
1313
1313
  globalThis.describe("retiredField — annotation and nothing else", () => {
@@ -1555,6 +1555,12 @@ globalThis.describe("Plugin_Structure.make — Phase 2 graph fields", () => {
1555
1555
  globalThis.test("@sensitive reaches an event variant's payload, not only state", () => {
1556
1556
  globalThis.expect(Sensitive$Reventless.variantFieldNames(PsAnnotatedView$ReventlessCore.consumedEventSchema, "ItemRecorded")).toEqual(["contact"]);
1557
1557
  });
1558
+ globalThis.test("@default flows through the PPX to JSON Schema's `default`", () => {
1559
+ globalThis.expect(Stdlib_Option.flatMap(getPropertyOf(annotatedSchema, "quantity"), s => getProperty(s, "default"))).toEqual(1);
1560
+ });
1561
+ globalThis.test("@default leaves the field's own shape alone", () => {
1562
+ globalThis.expect(Stdlib_Option.flatMap(Stdlib_Option.flatMap(getPropertyOf(annotatedSchema, "quantity"), s => getProperty(s, "type")), Stdlib_JSON.Decode.string)).toBe("integer");
1563
+ });
1558
1564
  globalThis.test("@metric flows through the PPX to x-reventless-metric {aggregate,label}", () => {
1559
1565
  let metricObj = Stdlib_Option.flatMap(getPropertyOf(annotatedSchema, "total"), s => getProperty(s, "x-reventless-metric"));
1560
1566
  globalThis.expect([
@@ -48,7 +48,7 @@ let Id;
48
48
 
49
49
  let initialState = false;
50
50
 
51
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsAttachInvoice.res.mjs";
51
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsAttachInvoice.res.mjs";
52
52
 
53
53
  let readConsistency = "EscalateOnRetry";
54
54
 
@@ -49,7 +49,7 @@ let Id;
49
49
 
50
50
  let initialState = false;
51
51
 
52
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsChangePhoto.res.mjs";
52
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsChangePhoto.res.mjs";
53
53
 
54
54
  let readConsistency = "EscalateOnRetry";
55
55
 
@@ -51,7 +51,7 @@ let Id;
51
51
 
52
52
  let initialState = false;
53
53
 
54
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsDispatchShipment.res.mjs";
54
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsDispatchShipment.res.mjs";
55
55
 
56
56
  let readConsistency = "EscalateOnRetry";
57
57
 
@@ -69,7 +69,7 @@ let Id;
69
69
 
70
70
  let initialState = false;
71
71
 
72
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsGatedCommands.res.mjs";
72
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsGatedCommands.res.mjs";
73
73
 
74
74
  let readConsistency = "EscalateOnRetry";
75
75
 
@@ -47,7 +47,7 @@ let Id;
47
47
 
48
48
  let initialState = false;
49
49
 
50
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsPlaceOrder.res.mjs";
50
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsPlaceOrder.res.mjs";
51
51
 
52
52
  let readConsistency = "EscalateOnRetry";
53
53
 
@@ -58,7 +58,7 @@ let Id;
58
58
 
59
59
  let initialState = false;
60
60
 
61
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsReserveStock.res.mjs";
61
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsReserveStock.res.mjs";
62
62
 
63
63
  let readConsistency = "EscalateOnRetry";
64
64
 
@@ -71,7 +71,7 @@ let Id;
71
71
 
72
72
  let initialState = false;
73
73
 
74
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsShipOrder.res.mjs";
74
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsShipOrder.res.mjs";
75
75
 
76
76
  let readConsistency = "EscalateOnRetry";
77
77
 
@@ -81,7 +81,7 @@ let Id;
81
81
 
82
82
  let initialState = false;
83
83
 
84
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsTransitionSwitch.res.mjs";
84
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsTransitionSwitch.res.mjs";
85
85
 
86
86
  let readConsistency = "EscalateOnRetry";
87
87
 
@@ -47,7 +47,7 @@ let Id;
47
47
 
48
48
  let initialState = false;
49
49
 
50
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsTypoStore.res.mjs";
50
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsTypoStore.res.mjs";
51
51
 
52
52
  let readConsistency = "EscalateOnRetry";
53
53
 
@@ -49,7 +49,7 @@ let Id;
49
49
 
50
50
  let initialState = false;
51
51
 
52
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsUploadAvatar.res.mjs";
52
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsUploadAvatar.res.mjs";
53
53
 
54
54
  let readConsistency = "EscalateOnRetry";
55
55
 
@@ -51,7 +51,7 @@ let Id;
51
51
 
52
52
  let initialState = false;
53
53
 
54
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChangeSlice/PsUploadImages.res.mjs";
54
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateChange/PsUploadImages.res.mjs";
55
55
 
56
56
  let readConsistency = "EscalateOnRetry";
57
57
 
@@ -16,6 +16,7 @@ type consumedEvent =
16
16
  // On the event, not just the state: a renderer composes from an event
17
17
  // payload, so this is the case the marker has to reach.
18
18
  @sensitive contact: string,
19
+ @default(1) quantity: int,
19
20
  })
20
21
 
21
22
  @live(false)
@@ -27,10 +28,11 @@ type state = {
27
28
  name: string,
28
29
  @semantic("currency") @metric({aggregate: "sum", label: "Revenue"}) total: float,
29
30
  @sensitive contact: string,
31
+ @default(1) quantity: int,
30
32
  }
31
33
 
32
34
  let project = ({event}: Reventless.StateViewSlice.consumed<consumedEvent>) =>
33
35
  switch event {
34
- | ItemRecorded({itemId, ownerId, version, name, total, contact}) =>
35
- [Set(itemId, {itemId, ownerId, version, name, total, contact})]
36
+ | ItemRecorded({itemId, ownerId, version, name, total, contact, quantity}) =>
37
+ [Set(itemId, {itemId, ownerId, version, name, total, contact, quantity})]
36
38
  }
@@ -4,6 +4,7 @@ import * as Sury from "sury";
4
4
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
5
5
  import * as ReadModel$Reventless from "@reventlessdev/reventless-spec/src/components/ReadModel.res.mjs";
6
6
  import * as Sensitive$Reventless from "@reventlessdev/reventless-spec/src/components/Sensitive.res.mjs";
7
+ import * as FieldDefault$Reventless from "@reventlessdev/reventless-spec/src/components/FieldDefault.res.mjs";
7
8
  import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
8
9
 
9
10
  let consumedEventSchema = Sury.$schema(s => ({
@@ -13,7 +14,8 @@ let consumedEventSchema = Sury.$schema(s => ({
13
14
  version: s.m(Sury.string),
14
15
  name: s.m(Sury.string),
15
16
  total: s.m(Sury.float),
16
- contact: s.m(Sensitive$Reventless.string)
17
+ contact: s.m(Sensitive$Reventless.string),
18
+ quantity: s.m(FieldDefault$Reventless.int(Sury.int, 1))
17
19
  }));
18
20
 
19
21
  let stateSchema = Sury.$schema(s => ({
@@ -22,7 +24,8 @@ let stateSchema = Sury.$schema(s => ({
22
24
  ownerId: s.m(Sury.string),
23
25
  name: s.m(Sury.string),
24
26
  total: s.m(Sury.float),
25
- contact: s.m(Sensitive$Reventless.string)
27
+ contact: s.m(Sensitive$Reventless.string),
28
+ quantity: s.m(FieldDefault$Reventless.int(Sury.int, 1))
26
29
  }));
27
30
 
28
31
  function project(param) {
@@ -37,7 +40,8 @@ function project(param) {
37
40
  ownerId: event.ownerId,
38
41
  name: event.name,
39
42
  total: event.total,
40
- contact: event.contact
43
+ contact: event.contact,
44
+ quantity: event.quantity
41
45
  }
42
46
  }];
43
47
  }
@@ -95,7 +99,7 @@ let name = "AnnotatedView";
95
99
 
96
100
  let Id;
97
101
 
98
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsAnnotatedView.res.mjs";
102
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsAnnotatedView.res.mjs";
99
103
 
100
104
  let authorization = "AllowAuthenticated";
101
105
 
@@ -49,7 +49,7 @@ let Id;
49
49
 
50
50
  let subIdConfig;
51
51
 
52
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsAvailableProductsView.res.mjs";
52
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsAvailableProductsView.res.mjs";
53
53
 
54
54
  let authorization = "AllowAuthenticated";
55
55
 
@@ -36,7 +36,7 @@ let Id;
36
36
 
37
37
  let subIdConfig;
38
38
 
39
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsCategoriesView.res.mjs";
39
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsCategoriesView.res.mjs";
40
40
 
41
41
  let authorization = "AllowAuthenticated";
42
42
 
@@ -49,7 +49,7 @@ let Id;
49
49
 
50
50
  let subIdConfig;
51
51
 
52
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsCustomersView.res.mjs";
52
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsCustomersView.res.mjs";
53
53
 
54
54
  let authorization = "AllowAuthenticated";
55
55
 
@@ -41,7 +41,7 @@ let Id;
41
41
 
42
42
  let subIdConfig;
43
43
 
44
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsGatedView.res.mjs";
44
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsGatedView.res.mjs";
45
45
 
46
46
  let visibility = "Public";
47
47
 
@@ -61,7 +61,7 @@ let Id;
61
61
 
62
62
  let subIdConfig;
63
63
 
64
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsOrdersView.res.mjs";
64
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsOrdersView.res.mjs";
65
65
 
66
66
  let authorization = "AllowAuthenticated";
67
67
 
@@ -80,7 +80,7 @@ let Id;
80
80
 
81
81
  let subIdConfig;
82
82
 
83
- let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateViewSlice/PsShipmentsView.res.mjs";
83
+ let moduleUrl = "@reventlessdev/reventless-core/tests/plugin/StateView/PsShipmentsView.res.mjs";
84
84
 
85
85
  let authorization = "AllowAuthenticated";
86
86