@reventlessdev/reventless-spec 3.0.0-alpha.61
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 +625 -0
- package/LICENSE +202 -0
- package/README.md +114 -0
- package/package.json +34 -0
- package/rescript.json +25 -0
- package/run-generator.mjs +2 -0
- package/src/AnsiStyle.res +40 -0
- package/src/AnsiStyle.res.mjs +54 -0
- package/src/LogPrefix.res +168 -0
- package/src/LogPrefix.res.mjs +148 -0
- package/src/PackageVersion.res +73 -0
- package/src/PackageVersion.res.mjs +81 -0
- package/src/components/Aggregate.res +64 -0
- package/src/components/Aggregate.res.mjs +2 -0
- package/src/components/AutomationSlice.res +279 -0
- package/src/components/AutomationSlice.res.mjs +30 -0
- package/src/components/Counter.res +24 -0
- package/src/components/Counter.res.mjs +2 -0
- package/src/components/DcbDecode.res +128 -0
- package/src/components/DcbDecode.res.mjs +117 -0
- package/src/components/DcbTag.res +1256 -0
- package/src/components/DcbTag.res.mjs +869 -0
- package/src/components/DcbValidation.res +362 -0
- package/src/components/DcbValidation.res.mjs +360 -0
- package/src/components/DisplayName.res +40 -0
- package/src/components/DisplayName.res.mjs +26 -0
- package/src/components/ExtensionPoint.res +27 -0
- package/src/components/ExtensionPoint.res.mjs +2 -0
- package/src/components/InboundTranslationSlice.res +79 -0
- package/src/components/InboundTranslationSlice.res.mjs +2 -0
- package/src/components/OutboundTranslationSlice.res +108 -0
- package/src/components/OutboundTranslationSlice.res.mjs +2 -0
- package/src/components/Plugin.res +373 -0
- package/src/components/Plugin.res.mjs +249 -0
- package/src/components/ReadModel.res +199 -0
- package/src/components/ReadModel.res.mjs +18 -0
- package/src/components/Reference.res +51 -0
- package/src/components/Reference.res.mjs +37 -0
- package/src/components/StateAnnotations.res +65 -0
- package/src/components/StateAnnotations.res.mjs +15 -0
- package/src/components/StateChangeSlice.res +131 -0
- package/src/components/StateChangeSlice.res.mjs +2 -0
- package/src/components/StateViewSlice.res +99 -0
- package/src/components/StateViewSlice.res.mjs +2 -0
- package/src/components/Task.res +62 -0
- package/src/components/Task.res.mjs +2 -0
- package/src/generator/Codegen.res +703 -0
- package/src/generator/Codegen.res.mjs +485 -0
- package/src/generator/Config.res +85 -0
- package/src/generator/Config.res.mjs +78 -0
- package/src/generator/Discovery.res +204 -0
- package/src/generator/Discovery.res.mjs +213 -0
- package/src/generator/Generator_Node.res +49 -0
- package/src/generator/Generator_Node.res.mjs +18 -0
- package/src/generator/Pairing.res +386 -0
- package/src/generator/Pairing.res.mjs +353 -0
- package/src/generator/PluginGenerator.res +53 -0
- package/src/generator/PluginGenerator.res.mjs +70 -0
- package/src/types/Authorization.res +23 -0
- package/src/types/Authorization.res.mjs +33 -0
- package/src/types/Behavior.res +78 -0
- package/src/types/Behavior.res.mjs +2 -0
- package/src/types/EventMapping.res +100 -0
- package/src/types/EventMapping.res.mjs +15 -0
- package/src/types/Handler.res +30 -0
- package/src/types/Handler.res.mjs +2 -0
- package/src/types/Id.res +75 -0
- package/src/types/Id.res.mjs +37 -0
- package/src/types/Identity.res +46 -0
- package/src/types/Identity.res.mjs +51 -0
- package/src/types/Message.res +197 -0
- package/src/types/Message.res.mjs +108 -0
- package/src/types/Projection.res +220 -0
- package/src/types/Projection.res.mjs +44 -0
- package/src/types/QueryEngine.res +123 -0
- package/src/types/QueryEngine.res.mjs +12 -0
- package/src/types/ReadConsistency.res +38 -0
- package/src/types/ReadConsistency.res.mjs +29 -0
- package/src/types/Schedule.res +65 -0
- package/src/types/Schedule.res.mjs +68 -0
- package/src/types/SideEffect.res +45 -0
- package/src/types/SideEffect.res.mjs +2 -0
- package/src/types/StoredEvent.res +46 -0
- package/src/types/StoredEvent.res.mjs +32 -0
- package/src/types/Visibility.res +24 -0
- package/src/types/Visibility.res.mjs +25 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Decodes raw stored events against a consumed event schema.
|
|
2
|
+
// Supports the full spectrum of consumed events:
|
|
3
|
+
// - Payload-less variants (match by TAG only, bypass sury)
|
|
4
|
+
// - Partial projections (sury parse with field subset)
|
|
5
|
+
// - Full shape (sury parse as-is)
|
|
6
|
+
|
|
7
|
+
// Build a lookup of TAG name -> variant kind (payloadLess or withFields)
|
|
8
|
+
// from a consumed event schema. Cached per schema for performance.
|
|
9
|
+
|
|
10
|
+
type variantKind =
|
|
11
|
+
| PayloadLess
|
|
12
|
+
| WithFields
|
|
13
|
+
|
|
14
|
+
let buildVariantLookup = (schema: S.t<unknown>): dict<variantKind> => {
|
|
15
|
+
let lookup = Dict.make()
|
|
16
|
+
switch schema {
|
|
17
|
+
| Union({anyOf}) =>
|
|
18
|
+
anyOf->Array.forEach(variantSchema =>
|
|
19
|
+
switch variantSchema {
|
|
20
|
+
| Object({items, properties}) =>
|
|
21
|
+
let tagName =
|
|
22
|
+
items
|
|
23
|
+
->Array.find(item => item.location == "TAG")
|
|
24
|
+
->Option.flatMap(item =>
|
|
25
|
+
switch item.schema {
|
|
26
|
+
| String({const}) => Some(const)
|
|
27
|
+
| _ => None
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
switch tagName {
|
|
31
|
+
| Some(name) =>
|
|
32
|
+
let kind = if properties->Dict.keysToArray->Array.length == 0 {
|
|
33
|
+
PayloadLess
|
|
34
|
+
} else {
|
|
35
|
+
WithFields
|
|
36
|
+
}
|
|
37
|
+
lookup->Dict.set(name, kind)
|
|
38
|
+
| None => ()
|
|
39
|
+
}
|
|
40
|
+
| String({const: ?Some(name)}) =>
|
|
41
|
+
// sury represents payload-less variants in some cases as bare String({const})
|
|
42
|
+
lookup->Dict.set(name, PayloadLess)
|
|
43
|
+
| _ => ()
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
| Object({items}) =>
|
|
47
|
+
// Single-variant schema with fields
|
|
48
|
+
let tagName =
|
|
49
|
+
items
|
|
50
|
+
->Array.find(item => item.location == "TAG")
|
|
51
|
+
->Option.flatMap(item =>
|
|
52
|
+
switch item.schema {
|
|
53
|
+
| String({const}) => Some(const)
|
|
54
|
+
| _ => None
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
switch tagName {
|
|
58
|
+
| Some(name) => lookup->Dict.set(name, WithFields)
|
|
59
|
+
| None => ()
|
|
60
|
+
}
|
|
61
|
+
| String({const: ?Some(name)}) =>
|
|
62
|
+
// Single payload-less variant — sury compiles `type t = Foo` to String({const: "Foo"})
|
|
63
|
+
lookup->Dict.set(name, PayloadLess)
|
|
64
|
+
| _ => ()
|
|
65
|
+
}
|
|
66
|
+
lookup
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type decoder<'event> = {
|
|
70
|
+
lookup: dict<variantKind>,
|
|
71
|
+
schema: S.t<'event>,
|
|
72
|
+
constructors: dict<'event>,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
external unsafeCast: 'a => 'b = "%identity"
|
|
76
|
+
|
|
77
|
+
// Build a map of TAG name -> constructed payload-less variant value
|
|
78
|
+
// by encoding each payload-less variant through sury and storing the result.
|
|
79
|
+
// This is done once per schema, not per event.
|
|
80
|
+
let buildPayloadLessConstructors = (schema: S.t<'event>, lookup: dict<variantKind>): dict<'event> => {
|
|
81
|
+
let constructors = Dict.make()
|
|
82
|
+
// For payload-less variants, we need to figure out what ReScript value
|
|
83
|
+
// corresponds to each TAG name. sury's schema for a union with payload-less
|
|
84
|
+
// variants encodes them as bare strings. So `| ItemCreated` serializes to
|
|
85
|
+
// JSON string "ItemCreated". We can use S.parseJsonOrThrow with the string.
|
|
86
|
+
lookup->Dict.toArray->Array.forEach(((tagName, kind)) =>
|
|
87
|
+
switch kind {
|
|
88
|
+
| PayloadLess =>
|
|
89
|
+
try {
|
|
90
|
+
let value = JSON.String(tagName)->S.parseJsonOrThrow(schema)
|
|
91
|
+
constructors->Dict.set(tagName, value)
|
|
92
|
+
} catch {
|
|
93
|
+
| _ => ()
|
|
94
|
+
}
|
|
95
|
+
| WithFields => ()
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
constructors
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
type makeDecoderResult<'event> = {
|
|
102
|
+
decode: (~eventType: string, ~data: dict<JSON.t>) => option<'event>,
|
|
103
|
+
eventTypes: array<string>,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let makeDecoder = (schema: S.t<'event>): makeDecoderResult<'event> => {
|
|
107
|
+
let unknownSchema: S.t<unknown> = unsafeCast(schema)
|
|
108
|
+
let lookup = buildVariantLookup(unknownSchema)
|
|
109
|
+
let constructors = buildPayloadLessConstructors(schema, lookup)
|
|
110
|
+
let eventTypes = lookup->Dict.keysToArray
|
|
111
|
+
|
|
112
|
+
let decode = (~eventType: string, ~data: dict<JSON.t>): option<'event> =>
|
|
113
|
+
switch lookup->Dict.get(eventType) {
|
|
114
|
+
| None => None
|
|
115
|
+
| Some(PayloadLess) => constructors->Dict.get(eventType)
|
|
116
|
+
| Some(WithFields) =>
|
|
117
|
+
// Reconstruct the JSON with TAG for sury parsing
|
|
118
|
+
let jsonDict = data->Dict.copy
|
|
119
|
+
jsonDict->Dict.set("TAG", JSON.String(eventType))
|
|
120
|
+
try {
|
|
121
|
+
Some(JSON.Object(jsonDict)->S.parseJsonOrThrow(schema))
|
|
122
|
+
} catch {
|
|
123
|
+
| _ => None
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
{decode, eventTypes}
|
|
128
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
|
+
|
|
7
|
+
function buildVariantLookup(schema) {
|
|
8
|
+
let lookup = {};
|
|
9
|
+
switch (schema.type) {
|
|
10
|
+
case "string" :
|
|
11
|
+
let name = schema.const;
|
|
12
|
+
if (name !== undefined) {
|
|
13
|
+
lookup[name] = "PayloadLess";
|
|
14
|
+
}
|
|
15
|
+
break;
|
|
16
|
+
case "object" :
|
|
17
|
+
let tagName = Stdlib_Option.flatMap(schema.items.find(item => item.location === "TAG"), item => {
|
|
18
|
+
let match = item.schema;
|
|
19
|
+
if (match.type !== "string") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
let $$const = match.const;
|
|
23
|
+
if ($$const !== undefined) {
|
|
24
|
+
return $$const;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
if (tagName !== undefined) {
|
|
28
|
+
lookup[tagName] = "WithFields";
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
case "union" :
|
|
32
|
+
schema.anyOf.forEach(variantSchema => {
|
|
33
|
+
switch (variantSchema.type) {
|
|
34
|
+
case "string" :
|
|
35
|
+
let name = variantSchema.const;
|
|
36
|
+
if (name !== undefined) {
|
|
37
|
+
lookup[name] = "PayloadLess";
|
|
38
|
+
return;
|
|
39
|
+
} else {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
case "object" :
|
|
43
|
+
let tagName = Stdlib_Option.flatMap(variantSchema.items.find(item => item.location === "TAG"), item => {
|
|
44
|
+
let match = item.schema;
|
|
45
|
+
if (match.type !== "string") {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
let $$const = match.const;
|
|
49
|
+
if ($$const !== undefined) {
|
|
50
|
+
return $$const;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (tagName === undefined) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let kind = Object.keys(variantSchema.properties).length === 0 ? "PayloadLess" : "WithFields";
|
|
57
|
+
lookup[tagName] = kind;
|
|
58
|
+
return;
|
|
59
|
+
default:
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
return lookup;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildPayloadLessConstructors(schema, lookup) {
|
|
69
|
+
let constructors = {};
|
|
70
|
+
Object.entries(lookup).forEach(param => {
|
|
71
|
+
let tagName = param[0];
|
|
72
|
+
if (param[1] !== "PayloadLess") {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
let value = S.parseJsonOrThrow(tagName, schema);
|
|
77
|
+
constructors[tagName] = value;
|
|
78
|
+
return;
|
|
79
|
+
} catch (exn) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return constructors;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function makeDecoder(schema) {
|
|
87
|
+
let lookup = buildVariantLookup(schema);
|
|
88
|
+
let constructors = buildPayloadLessConstructors(schema, lookup);
|
|
89
|
+
let eventTypes = Object.keys(lookup);
|
|
90
|
+
let decode = (eventType, data) => {
|
|
91
|
+
let match = lookup[eventType];
|
|
92
|
+
if (match === undefined) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (match === "PayloadLess") {
|
|
96
|
+
return constructors[eventType];
|
|
97
|
+
}
|
|
98
|
+
let jsonDict = Object.assign({}, data);
|
|
99
|
+
jsonDict["TAG"] = eventType;
|
|
100
|
+
try {
|
|
101
|
+
return Primitive_option.some(S.parseJsonOrThrow(jsonDict, schema));
|
|
102
|
+
} catch (exn) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
decode: decode,
|
|
108
|
+
eventTypes: eventTypes
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
buildVariantLookup,
|
|
114
|
+
buildPayloadLessConstructors,
|
|
115
|
+
makeDecoder,
|
|
116
|
+
}
|
|
117
|
+
/* S Not a pure module */
|