@reventlessdev/reventless-local 3.0.0-alpha.131 → 3.0.0-alpha.133
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 +14 -0
- package/package.json +6 -6
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +11 -3
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res.mjs +4 -3
- package/tests/adapter/GraphQL_SchemaInspectorTest.res +117 -0
- package/tests/adapter/GraphQL_SchemaInspectorTest.res.mjs +76 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
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.133 (2026-07-09)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **reventless-core:** DCB StateChangeSlice mutations use ${plugin}_${command}, not ${plugin}_${slice}_${command} ([c5874d2](https://github.com/ReventlessDev/reventless-core/commit/c5874d27ad63e6af5c639c8b6c6f8596fd7f682b))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.132 (2026-07-09)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **reventless-core:** DCB StateChangeSlices expose one mutation per command constructor ([136fe93](https://github.com/ReventlessDev/reventless-core/commit/136fe93c56c2e5115eb60d792e9d5e9c07eecc2b))
|
|
18
|
+
|
|
19
|
+
|
|
6
20
|
# 3.0.0-alpha.131 (2026-07-08)
|
|
7
21
|
|
|
8
22
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-local",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.133",
|
|
4
4
|
"description": "Local platform for Reventless (in-memory or SQLite backend, for development and testing without AWS)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -31,16 +31,16 @@
|
|
|
31
31
|
"graphql-yoga": "^5.21.0",
|
|
32
32
|
"sury": "11.0.0-alpha.4",
|
|
33
33
|
"ws": "^8.18.0",
|
|
34
|
-
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.18",
|
|
35
|
-
"@reventlessdev/rescript-jest": "1.0.0-alpha.6",
|
|
36
34
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.25",
|
|
35
|
+
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.18",
|
|
37
36
|
"@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.17",
|
|
38
37
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.14",
|
|
39
|
-
"@reventlessdev/
|
|
40
|
-
"@reventlessdev/reventless-gwt": "1.0.0-alpha.
|
|
38
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.6",
|
|
39
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.94",
|
|
41
40
|
"@reventlessdev/reventless-infra": "3.0.0-alpha.91",
|
|
42
41
|
"@reventlessdev/reventless-spec": "3.0.0-alpha.69",
|
|
43
|
-
"@reventlessdev/reventless-postgres": "3.0.0-alpha.
|
|
42
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.13",
|
|
43
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.149"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"rescript": "^12.3.0",
|
|
@@ -237,12 +237,20 @@ let registerDcb = (
|
|
|
237
237
|
~server: GraphQL_ServerInstance.t,
|
|
238
238
|
) => {
|
|
239
239
|
ensureCommandResultTypes(server)
|
|
240
|
-
|
|
240
|
+
// Derive the constructor from the field name's trailing `_` segment (mirrors the
|
|
241
|
+
// aggregate resolver). A single-command slice's `Plugin_Slice` resolves to its sole
|
|
242
|
+
// constructor (slice name == constructor); a multi-command slice's `Plugin_Ctor`
|
|
243
|
+
// resolves to `Ctor`. Position 0 was previously hardcoded, which dropped every
|
|
244
|
+
// non-first constructor of a multi-command slice.
|
|
245
|
+
let constructorNames = Reventless.DcbTag.extractAllVariantNames(commandSchema->Obj.magic)
|
|
246
|
+
let variantIndex = variantIndexForField(commandSchema, ~field=fieldName)
|
|
247
|
+
let variantSchema = extractVariantSchema(commandSchema, ~index=variantIndex >= 0 ? variantIndex : 0)
|
|
241
248
|
let sdlFields = [deriveSdlField(~fieldName, variantSchema)]
|
|
242
249
|
|
|
243
250
|
// Extract TAG (variant constructor name) for routing
|
|
244
|
-
let
|
|
245
|
-
|
|
251
|
+
let tag =
|
|
252
|
+
(variantIndex >= 0 ? constructorNames->Array.get(variantIndex) : constructorNames->Array.get(0))
|
|
253
|
+
->Option.getOr(fieldName)
|
|
246
254
|
let hasPayload = Reventless.DcbTag.isVariantPayloadBearing(commandSchema->Obj.magic, tag)
|
|
247
255
|
|
|
248
256
|
let handlerRef = ref(None)
|
|
@@ -198,10 +198,11 @@ function register(fields, commandSchema, commandAuthorization, server) {
|
|
|
198
198
|
|
|
199
199
|
function registerDcb(fieldName, commandSchema, commandAuthorization, server) {
|
|
200
200
|
ensureCommandResultTypes(server);
|
|
201
|
-
let variantSchema = extractVariantSchema(commandSchema, undefined);
|
|
202
|
-
let sdlFields = [deriveSdlField(fieldName, variantSchema)];
|
|
203
201
|
let constructorNames = DcbTag$Reventless.extractAllVariantNames(commandSchema);
|
|
204
|
-
let
|
|
202
|
+
let variantIndex = variantIndexForField(commandSchema, fieldName);
|
|
203
|
+
let variantSchema = extractVariantSchema(commandSchema, variantIndex >= 0 ? variantIndex : 0);
|
|
204
|
+
let sdlFields = [deriveSdlField(fieldName, variantSchema)];
|
|
205
|
+
let tag = Stdlib_Option.getOr(variantIndex >= 0 ? constructorNames[variantIndex] : constructorNames[0], fieldName);
|
|
205
206
|
let hasPayload = DcbTag$Reventless.isVariantPayloadBearing(commandSchema, tag);
|
|
206
207
|
let handlerRef = {
|
|
207
208
|
contents: undefined
|
|
@@ -38,6 +38,23 @@ type unionCommand =
|
|
|
38
38
|
| Create({itemId: @s.matches(Reventless.DcbTag.string) string, name: string})
|
|
39
39
|
| Rename({itemId: @s.matches(Reventless.DcbTag.string) string, newName: string})
|
|
40
40
|
|
|
41
|
+
// DCB StateChangeSlice command shapes for the per-constructor mutation fan-out.
|
|
42
|
+
// A single-variant union models a single-command slice (must keep the byte-identical
|
|
43
|
+
// `Plugin_Slice` field); a multi-variant union models a multi-command slice (must
|
|
44
|
+
// expose one `Plugin_Command` field per constructor).
|
|
45
|
+
@schema
|
|
46
|
+
type dcbSingleCommand =
|
|
47
|
+
| AddCategory({categoryId: @s.matches(Reventless.DcbTag.string) string, name: string})
|
|
48
|
+
|
|
49
|
+
@schema
|
|
50
|
+
type dcbMultiCommand =
|
|
51
|
+
| SyncNewProduct({
|
|
52
|
+
productId: @s.matches(Reventless.DcbTag.string) string,
|
|
53
|
+
name: string,
|
|
54
|
+
price: float,
|
|
55
|
+
})
|
|
56
|
+
| ChangeSyncedPrice({productId: @s.matches(Reventless.DcbTag.string) string, price: float})
|
|
57
|
+
|
|
41
58
|
// State schemas exercising structural annotations (Phase 1 server capability)
|
|
42
59
|
@schema
|
|
43
60
|
type plainState = {
|
|
@@ -769,6 +786,106 @@ describe("GraphQL_SchemaInspector", () => {
|
|
|
769
786
|
// the field must fold a `kindEq` equality filter into Platform_PluginFilter so the
|
|
770
787
|
// admin console can page the main list vs the System/Infrastructure panel
|
|
771
788
|
// server-side.
|
|
789
|
+
// ── DCB StateChangeSlice: one mutation per command constructor ───────────────
|
|
790
|
+
// A multi-command DCB slice must expose one GraphQL mutation per command
|
|
791
|
+
// constructor (mirroring aggregates), each carrying its own argument shape and its
|
|
792
|
+
// own subscription — not a single slice-named mutation that drops the extra
|
|
793
|
+
// constructors. Single-command slices must stay byte-identical (no schema churn).
|
|
794
|
+
describe("DCB StateChangeSlice — one mutation per command constructor", () => {
|
|
795
|
+
testPromise("single-command slice keeps the byte-identical Plugin_Slice field", async () => {
|
|
796
|
+
let fieldNames =
|
|
797
|
+
ReventlessCore.Api_Naming.sliceMutationFields(
|
|
798
|
+
~plugin="Catalog",
|
|
799
|
+
~slice="AddCategory",
|
|
800
|
+
~commandSchema=dcbSingleCommandSchema->S.castToUnknown,
|
|
801
|
+
)->Array.map(((f, _)) => f)
|
|
802
|
+
expect(fieldNames)->toEqual(["Catalog_AddCategory"])
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
testPromise("multi-command slice emits one `${plugin}_${command}` field per constructor", async () => {
|
|
806
|
+
// The command constructor already names the operation; callers/plans expect
|
|
807
|
+
// `${plugin}_${command}` (e.g. Platform_SyncComponent / Platform_RemoveComponent),
|
|
808
|
+
// NOT the aggregate-style `${plugin}_${slice}_${command}` doubling — which both
|
|
809
|
+
// renamed the primary command and overflowed AppSync's subscription cap.
|
|
810
|
+
let fieldNames =
|
|
811
|
+
ReventlessCore.Api_Naming.sliceMutationFields(
|
|
812
|
+
~plugin="Ordering",
|
|
813
|
+
~slice="SyncCatalogProduct",
|
|
814
|
+
~commandSchema=dcbMultiCommandSchema->S.castToUnknown,
|
|
815
|
+
)->Array.map(((f, _)) => f)
|
|
816
|
+
expect(fieldNames)->toEqual(["Ordering_SyncNewProduct", "Ordering_ChangeSyncedPrice"])
|
|
817
|
+
})
|
|
818
|
+
|
|
819
|
+
testPromise(
|
|
820
|
+
"multi-command slice: both mutations carry their own args, plus both subscriptions (each ≤ 50 chars)",
|
|
821
|
+
async () => {
|
|
822
|
+
let fieldNames =
|
|
823
|
+
ReventlessCore.Api_Naming.sliceMutationFields(
|
|
824
|
+
~plugin="Ordering",
|
|
825
|
+
~slice="SyncCatalogProduct",
|
|
826
|
+
~commandSchema=dcbMultiCommandSchema->S.castToUnknown,
|
|
827
|
+
)->Array.map(((f, _)) => f)
|
|
828
|
+
let commandSchema = dcbMultiCommandSchema->S.castToUnknown
|
|
829
|
+
|
|
830
|
+
let fragment = ReventlessCore.GraphQL_FragmentGenerator.generate(
|
|
831
|
+
~mutationEntries=[{fieldNames, commandSchema}],
|
|
832
|
+
~queryEntries=[],
|
|
833
|
+
)
|
|
834
|
+
let sdl = ReventlessCore.GraphQL_SchemaInspector.inspectFragment(fragment).sdlPreview
|
|
835
|
+
// Each constructor's mutation carries that constructor's own argument shape.
|
|
836
|
+
expect(
|
|
837
|
+
sdl->String.includes(
|
|
838
|
+
"Ordering_SyncNewProduct(id: ID!, productId: ID!, name: String!, price: Float!)",
|
|
839
|
+
),
|
|
840
|
+
)->toBe(true)
|
|
841
|
+
expect(
|
|
842
|
+
sdl->String.includes(
|
|
843
|
+
"Ordering_ChangeSyncedPrice(id: ID!, productId: ID!, price: Float!)",
|
|
844
|
+
),
|
|
845
|
+
)->toBe(true)
|
|
846
|
+
|
|
847
|
+
// Subscriptions fan out one-per-field over the same entry.
|
|
848
|
+
let subs = ReventlessCore.Plugin_SubscriptionSchema.generate(
|
|
849
|
+
~mutationEntries=[{fieldNames, commandSchema}],
|
|
850
|
+
~eventLogEntries=[],
|
|
851
|
+
)
|
|
852
|
+
let subSdl = subs.subscriptionFields->Array.join("\n")
|
|
853
|
+
expect(subSdl->String.includes("onOrdering_SyncNewProduct"))->toBe(true)
|
|
854
|
+
expect(subSdl->String.includes("onOrdering_ChangeSyncedPrice"))->toBe(true)
|
|
855
|
+
|
|
856
|
+
// Every emitted subscription field name stays within AppSync's 50-char cap.
|
|
857
|
+
subs.subscriptionFields->Array.forEach(sub => {
|
|
858
|
+
// `sub` is the full SDL line ` on<Field>(id: ID): CommandResult\n ...`;
|
|
859
|
+
// extract the leading `on<Field>` token to length-check the field name itself.
|
|
860
|
+
let name =
|
|
861
|
+
sub->String.trim->String.split("(")->Array.getUnsafe(0)
|
|
862
|
+
expect(name->String.length <= 50)->toBe(true)
|
|
863
|
+
})
|
|
864
|
+
},
|
|
865
|
+
)
|
|
866
|
+
|
|
867
|
+
testPromise(
|
|
868
|
+
"regression: a slice whose plugin+command overflow the 50-char cap fails at build, not at AppSync",
|
|
869
|
+
async () => {
|
|
870
|
+
// `on` + `Platform_SyncExtensionWiring_RemoveExtensionWiring` (the old doubled
|
|
871
|
+
// shape) was 52 chars → AppSync rejected the schema push with an opaque 500.
|
|
872
|
+
// A field long enough to overflow must now throw an actionable build-time error.
|
|
873
|
+
let longPlugin = "PlatformIntegrationOrchestration"
|
|
874
|
+
let field = ReventlessCore.Api_Naming.dcbCommandMutationField(
|
|
875
|
+
~plugin=longPlugin,
|
|
876
|
+
~command="RemoveExtensionWiring",
|
|
877
|
+
)
|
|
878
|
+
let raised = try {
|
|
879
|
+
let _ = ReventlessCore.Api_Naming.assertSubscriptionNameFits(~fieldName=field)
|
|
880
|
+
false
|
|
881
|
+
} catch {
|
|
882
|
+
| JsExn(_) => true
|
|
883
|
+
}
|
|
884
|
+
expect(raised)->toBe(true)
|
|
885
|
+
},
|
|
886
|
+
)
|
|
887
|
+
})
|
|
888
|
+
|
|
772
889
|
describe("Plugin admin fragment — kind enum + kindEq filter", () => {
|
|
773
890
|
testPromise("Platform_Plugin exposes a PluginKind enum and Platform_Plugins gains kindEq", async () => {
|
|
774
891
|
let fragment = ReventlessCore.GraphQL_FragmentGenerator.generate(
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import * as S from "sury/src/S.res.mjs";
|
|
4
4
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
5
|
import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
|
|
6
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
7
|
+
import * as Api_Naming$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/Api_Naming.res.mjs";
|
|
6
8
|
import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
|
|
7
9
|
import * as StateAnnotations$Reventless from "@reventlessdev/reventless-spec/src/components/StateAnnotations.res.mjs";
|
|
8
10
|
import * as GraphQL_Server$ReventlessLocal from "../../src/adapter/GraphQL_Server.res.mjs";
|
|
@@ -10,6 +12,7 @@ import * as GraphQL_Stitcher$ReventlessCore from "@reventlessdev/reventless-core
|
|
|
10
12
|
import * as PluginBaseFragment$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/api/PluginBaseFragment.res.mjs";
|
|
11
13
|
import * as GraphQL_SchemaInspector$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_SchemaInspector.res.mjs";
|
|
12
14
|
import * as GraphQL_FragmentGenerator$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_FragmentGenerator.res.mjs";
|
|
15
|
+
import * as Plugin_SubscriptionSchema$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_SubscriptionSchema.res.mjs";
|
|
13
16
|
|
|
14
17
|
TestRunner$ReventlessLocal.setup();
|
|
15
18
|
|
|
@@ -44,6 +47,26 @@ let unionCommandSchema = S.union([
|
|
|
44
47
|
}))
|
|
45
48
|
]);
|
|
46
49
|
|
|
50
|
+
let dcbSingleCommandSchema = S.schema(s => ({
|
|
51
|
+
TAG: "AddCategory",
|
|
52
|
+
categoryId: s.m(DcbTag$Reventless.string),
|
|
53
|
+
name: s.m(S.string)
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
let dcbMultiCommandSchema = S.union([
|
|
57
|
+
S.schema(s => ({
|
|
58
|
+
TAG: "SyncNewProduct",
|
|
59
|
+
productId: s.m(DcbTag$Reventless.string),
|
|
60
|
+
name: s.m(S.string),
|
|
61
|
+
price: s.m(S.float)
|
|
62
|
+
})),
|
|
63
|
+
S.schema(s => ({
|
|
64
|
+
TAG: "ChangeSyncedPrice",
|
|
65
|
+
productId: s.m(DcbTag$Reventless.string),
|
|
66
|
+
price: s.m(S.float)
|
|
67
|
+
}))
|
|
68
|
+
]);
|
|
69
|
+
|
|
47
70
|
let plainStateSchema = S.schema(s => ({
|
|
48
71
|
productId: s.m(DcbTag$Reventless.string),
|
|
49
72
|
name: s.m(S.string)
|
|
@@ -551,6 +574,57 @@ globalThis.describe("GraphQL_SchemaInspector", () => {
|
|
|
551
574
|
});
|
|
552
575
|
});
|
|
553
576
|
|
|
577
|
+
globalThis.describe("DCB StateChangeSlice — one mutation per command constructor", () => {
|
|
578
|
+
globalThis.test("single-command slice keeps the byte-identical Plugin_Slice field", async () => {
|
|
579
|
+
let fieldNames = Api_Naming$ReventlessCore.sliceMutationFields("Catalog", "AddCategory", dcbSingleCommandSchema).map(param => param[0]);
|
|
580
|
+
globalThis.expect(fieldNames).toEqual(["Catalog_AddCategory"]);
|
|
581
|
+
});
|
|
582
|
+
globalThis.test("multi-command slice emits one `${plugin}_${command}` field per constructor", async () => {
|
|
583
|
+
let fieldNames = Api_Naming$ReventlessCore.sliceMutationFields("Ordering", "SyncCatalogProduct", dcbMultiCommandSchema).map(param => param[0]);
|
|
584
|
+
globalThis.expect(fieldNames).toEqual([
|
|
585
|
+
"Ordering_SyncNewProduct",
|
|
586
|
+
"Ordering_ChangeSyncedPrice"
|
|
587
|
+
]);
|
|
588
|
+
});
|
|
589
|
+
globalThis.test("multi-command slice: both mutations carry their own args, plus both subscriptions (each ≤ 50 chars)", async () => {
|
|
590
|
+
let fieldNames = Api_Naming$ReventlessCore.sliceMutationFields("Ordering", "SyncCatalogProduct", dcbMultiCommandSchema).map(param => param[0]);
|
|
591
|
+
let fragment = GraphQL_FragmentGenerator$ReventlessCore.generate([{
|
|
592
|
+
fieldNames: fieldNames,
|
|
593
|
+
commandSchema: dcbMultiCommandSchema
|
|
594
|
+
}], []);
|
|
595
|
+
let sdl = GraphQL_SchemaInspector$ReventlessCore.inspectFragment(fragment).sdlPreview;
|
|
596
|
+
globalThis.expect(sdl.includes("Ordering_SyncNewProduct(id: ID!, productId: ID!, name: String!, price: Float!)")).toBe(true);
|
|
597
|
+
globalThis.expect(sdl.includes("Ordering_ChangeSyncedPrice(id: ID!, productId: ID!, price: Float!)")).toBe(true);
|
|
598
|
+
let subs = Plugin_SubscriptionSchema$ReventlessCore.generate([{
|
|
599
|
+
fieldNames: fieldNames,
|
|
600
|
+
commandSchema: dcbMultiCommandSchema
|
|
601
|
+
}], []);
|
|
602
|
+
let subSdl = subs.subscriptionFields.join("\n");
|
|
603
|
+
globalThis.expect(subSdl.includes("onOrdering_SyncNewProduct")).toBe(true);
|
|
604
|
+
globalThis.expect(subSdl.includes("onOrdering_ChangeSyncedPrice")).toBe(true);
|
|
605
|
+
subs.subscriptionFields.forEach(sub => {
|
|
606
|
+
let name = sub.trim().split("(")[0];
|
|
607
|
+
globalThis.expect(name.length <= 50).toBe(true);
|
|
608
|
+
});
|
|
609
|
+
});
|
|
610
|
+
globalThis.test("regression: a slice whose plugin+command overflow the 50-char cap fails at build, not at AppSync", async () => {
|
|
611
|
+
let field = Api_Naming$ReventlessCore.dcbCommandMutationField("PlatformIntegrationOrchestration", "RemoveExtensionWiring");
|
|
612
|
+
let raised;
|
|
613
|
+
try {
|
|
614
|
+
Api_Naming$ReventlessCore.assertSubscriptionNameFits(field);
|
|
615
|
+
raised = false;
|
|
616
|
+
} catch (raw_exn) {
|
|
617
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
618
|
+
if (exn.RE_EXN_ID === "JsExn") {
|
|
619
|
+
raised = true;
|
|
620
|
+
} else {
|
|
621
|
+
throw exn;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
globalThis.expect(raised).toBe(true);
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
|
|
554
628
|
globalThis.describe("Plugin admin fragment — kind enum + kindEq filter", () => {
|
|
555
629
|
globalThis.test("Platform_Plugin exposes a PluginKind enum and Platform_Plugins gains kindEq", async () => {
|
|
556
630
|
let fragment = GraphQL_FragmentGenerator$ReventlessCore.generate([], PluginBaseFragment$ReventlessCore.queryEntries);
|
|
@@ -579,6 +653,8 @@ export {
|
|
|
579
653
|
svStateSchema,
|
|
580
654
|
addCommandSchema,
|
|
581
655
|
unionCommandSchema,
|
|
656
|
+
dcbSingleCommandSchema,
|
|
657
|
+
dcbMultiCommandSchema,
|
|
582
658
|
plainStateSchema,
|
|
583
659
|
indexedStateSchema,
|
|
584
660
|
indexedStateSchemaWithAnnotations,
|