@reventlessdev/reventless-spec 3.0.0-alpha.100

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 (139) hide show
  1. package/CHANGELOG.md +931 -0
  2. package/LICENSE +202 -0
  3. package/README.md +109 -0
  4. package/package.json +49 -0
  5. package/rescript.json +32 -0
  6. package/run-generator.mjs +2 -0
  7. package/run-platform-generator.mjs +2 -0
  8. package/scripts/generate-currency.mjs +215 -0
  9. package/scripts/iso-4217-list-one.xml +1956 -0
  10. package/src/AnsiStyle.res +40 -0
  11. package/src/AnsiStyle.res.mjs +54 -0
  12. package/src/LogPrefix.res +192 -0
  13. package/src/LogPrefix.res.mjs +159 -0
  14. package/src/PackageVersion.res +67 -0
  15. package/src/PackageVersion.res.mjs +81 -0
  16. package/src/components/Aggregate.res +64 -0
  17. package/src/components/Aggregate.res.mjs +2 -0
  18. package/src/components/AutomationSlice.res +279 -0
  19. package/src/components/AutomationSlice.res.mjs +30 -0
  20. package/src/components/CapabilityManifest.res +74 -0
  21. package/src/components/CapabilityManifest.res.mjs +61 -0
  22. package/src/components/ComponentKind.res +99 -0
  23. package/src/components/ComponentKind.res.mjs +125 -0
  24. package/src/components/Counter.res +24 -0
  25. package/src/components/Counter.res.mjs +2 -0
  26. package/src/components/DcbDecode.res +118 -0
  27. package/src/components/DcbDecode.res.mjs +100 -0
  28. package/src/components/DcbScopeInference.res +244 -0
  29. package/src/components/DcbScopeInference.res.mjs +177 -0
  30. package/src/components/DcbTag.res +1335 -0
  31. package/src/components/DcbTag.res.mjs +898 -0
  32. package/src/components/DcbValidation.res +427 -0
  33. package/src/components/DcbValidation.res.mjs +423 -0
  34. package/src/components/DisplayName.res +40 -0
  35. package/src/components/DisplayName.res.mjs +26 -0
  36. package/src/components/ExtensionPoint.res +27 -0
  37. package/src/components/ExtensionPoint.res.mjs +2 -0
  38. package/src/components/InboundTranslationSlice.res +85 -0
  39. package/src/components/InboundTranslationSlice.res.mjs +2 -0
  40. package/src/components/OutboundTranslationSlice.res +153 -0
  41. package/src/components/OutboundTranslationSlice.res.mjs +2 -0
  42. package/src/components/Plugin.res +538 -0
  43. package/src/components/Plugin.res.mjs +264 -0
  44. package/src/components/PluginName.res +39 -0
  45. package/src/components/PluginName.res.mjs +45 -0
  46. package/src/components/ReadModel.res +199 -0
  47. package/src/components/ReadModel.res.mjs +18 -0
  48. package/src/components/Reference.res +55 -0
  49. package/src/components/Reference.res.mjs +50 -0
  50. package/src/components/Snapshot.res +26 -0
  51. package/src/components/Snapshot.res.mjs +2 -0
  52. package/src/components/StateAnnotations.res +97 -0
  53. package/src/components/StateAnnotations.res.mjs +15 -0
  54. package/src/components/StateChangeSlice.res +131 -0
  55. package/src/components/StateChangeSlice.res.mjs +2 -0
  56. package/src/components/StateViewSlice.res +123 -0
  57. package/src/components/StateViewSlice.res.mjs +2 -0
  58. package/src/components/Task.res +62 -0
  59. package/src/components/Task.res.mjs +2 -0
  60. package/src/generator/Codegen.res +842 -0
  61. package/src/generator/Codegen.res.mjs +565 -0
  62. package/src/generator/Config.res +106 -0
  63. package/src/generator/Config.res.mjs +69 -0
  64. package/src/generator/Discovery.res +230 -0
  65. package/src/generator/Discovery.res.mjs +198 -0
  66. package/src/generator/Generator_Node.res +14 -0
  67. package/src/generator/Generator_Node.res.mjs +18 -0
  68. package/src/generator/Pairing.res +460 -0
  69. package/src/generator/Pairing.res.mjs +415 -0
  70. package/src/generator/PlatformCodegen.res +207 -0
  71. package/src/generator/PlatformCodegen.res.mjs +154 -0
  72. package/src/generator/PlatformGenerator.res +126 -0
  73. package/src/generator/PlatformGenerator.res.mjs +114 -0
  74. package/src/generator/PlatformManifests.res +203 -0
  75. package/src/generator/PlatformManifests.res.mjs +212 -0
  76. package/src/generator/PluginGenerator.res +57 -0
  77. package/src/generator/PluginGenerator.res.mjs +73 -0
  78. package/src/semantic/Bytes.res +54 -0
  79. package/src/semantic/Bytes.res.mjs +38 -0
  80. package/src/semantic/Capabilities.res +43 -0
  81. package/src/semantic/Capabilities.res.mjs +17 -0
  82. package/src/semantic/Color.res +51 -0
  83. package/src/semantic/Color.res.mjs +29 -0
  84. package/src/semantic/Currency.res +598 -0
  85. package/src/semantic/Currency.res.mjs +743 -0
  86. package/src/semantic/DateRange.res +148 -0
  87. package/src/semantic/DateRange.res.mjs +74 -0
  88. package/src/semantic/Duration.res +53 -0
  89. package/src/semantic/Duration.res.mjs +26 -0
  90. package/src/semantic/Email.res +51 -0
  91. package/src/semantic/Email.res.mjs +31 -0
  92. package/src/semantic/GeoPoint.res +226 -0
  93. package/src/semantic/GeoPoint.res.mjs +190 -0
  94. package/src/semantic/Geocoding.res +127 -0
  95. package/src/semantic/Geocoding.res.mjs +36 -0
  96. package/src/semantic/Money.res +196 -0
  97. package/src/semantic/Money.res.mjs +138 -0
  98. package/src/semantic/Offload.res +294 -0
  99. package/src/semantic/Offload.res.mjs +191 -0
  100. package/src/semantic/Percent.res +53 -0
  101. package/src/semantic/Percent.res.mjs +33 -0
  102. package/src/semantic/Phone.res +55 -0
  103. package/src/semantic/Phone.res.mjs +29 -0
  104. package/src/semantic/Semantic.res +162 -0
  105. package/src/semantic/Semantic.res.mjs +95 -0
  106. package/src/semantic/StorageRef.res +164 -0
  107. package/src/semantic/StorageRef.res.mjs +111 -0
  108. package/src/semantic/Url.res +66 -0
  109. package/src/semantic/Url.res.mjs +48 -0
  110. package/src/types/Authorization.res +23 -0
  111. package/src/types/Authorization.res.mjs +33 -0
  112. package/src/types/Behavior.res +86 -0
  113. package/src/types/Behavior.res.mjs +2 -0
  114. package/src/types/DateTime.res +29 -0
  115. package/src/types/DateTime.res.mjs +16 -0
  116. package/src/types/EventMapping.res +100 -0
  117. package/src/types/EventMapping.res.mjs +15 -0
  118. package/src/types/Handler.res +30 -0
  119. package/src/types/Handler.res.mjs +2 -0
  120. package/src/types/Id.res +75 -0
  121. package/src/types/Id.res.mjs +37 -0
  122. package/src/types/Identity.res +46 -0
  123. package/src/types/Identity.res.mjs +51 -0
  124. package/src/types/Message.res +326 -0
  125. package/src/types/Message.res.mjs +186 -0
  126. package/src/types/Projection.res +220 -0
  127. package/src/types/Projection.res.mjs +44 -0
  128. package/src/types/QueryEngine.res +123 -0
  129. package/src/types/QueryEngine.res.mjs +12 -0
  130. package/src/types/ReadConsistency.res +38 -0
  131. package/src/types/ReadConsistency.res.mjs +29 -0
  132. package/src/types/Schedule.res +65 -0
  133. package/src/types/Schedule.res.mjs +68 -0
  134. package/src/types/SideEffect.res +45 -0
  135. package/src/types/SideEffect.res.mjs +2 -0
  136. package/src/types/StoredEvent.res +46 -0
  137. package/src/types/StoredEvent.res.mjs +32 -0
  138. package/src/types/Visibility.res +24 -0
  139. package/src/types/Visibility.res.mjs +25 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ Module types for a DCB outbound translation slice.
3
+
4
+ An `OutboundTranslationSlice` listens to the shared `DcbEventLog` event topic,
5
+ collects outbound items (TODO list), and calls an external service for each one.
6
+ The translate function may optionally return a command to publish back into the
7
+ system, closing the loop.
8
+
9
+ Replaces fire-and-forget `SideEffectHandler` with tracked, retryable external calls.
10
+
11
+ ```
12
+ Event(s) -> TODO List (read model) -> Translator -> External Service
13
+ -> Command (optional)
14
+ ```
15
+
16
+ Plan 02 splits the merged spec into two module types:
17
+
18
+ - `Spec` — types, identity, schemas, sweep config. Per D2, `outboundItem`
19
+ lives here (persisted TODO state with schema).
20
+ - `Translation` — `collect` (sync, observable in tests) and `translate`
21
+ (async, mocked in tests via `whenTranslateMocked`).
22
+
23
+ @example
24
+ ```rescript
25
+ // SendTrackingEmail.res
26
+ let name = "SendTrackingEmail"
27
+
28
+ @schema type outboundItem = {orderId: string, email: string}
29
+ @schema type inboundCommand = unit
30
+
31
+ let collect = event => switch event {
32
+ | OrderShipped({orderId, email}) => [(orderId, {orderId, email})]
33
+ | _ => []
34
+ }
35
+
36
+ // `~capabilities` is ignored here: this slice calls a service the framework
37
+ // does not broker. A geocoding slice would use `capabilities.geocode`.
38
+ let translate = async (_id, item, ~capabilities as _) => {
39
+ await EmailService.send(item.email, ~orderId=item.orderId)
40
+ Ok(None) // fire-and-forget: no command back
41
+ }
42
+
43
+ let maxRetries = 3
44
+ let heartbeatInterval = 60
45
+ ```
46
+ */
47
+
48
+ /**
49
+ The lean Spec for an OutboundTranslationSlice — types, identity, schemas, sweep config.
50
+ */
51
+ module type Spec = {
52
+ /** Logical name of this outbound translation slice (used as a component prefix). */
53
+ let name: string
54
+ let moduleUrl: string
55
+
56
+ /**
57
+ Events this outbound translation slice consumes for collect.
58
+ Only needs the fields required — no tag annotations needed.
59
+ Must carry `@schema`.
60
+ */
61
+ @schema
62
+ type consumedEvent
63
+
64
+ /** The outbound item state — what data is accumulated for each pending external call. Must carry `@schema`. */
65
+ @schema
66
+ type outboundItem
67
+
68
+ /** The command type optionally produced after a successful translate call. Must carry `@schema`. */
69
+ @schema
70
+ type inboundCommand
71
+
72
+ /** Maximum number of retries for a failed translate attempt. */
73
+ let maxRetries: int
74
+
75
+ /** Heartbeat interval in seconds for sweeping pending/failed items. */
76
+ let heartbeatInterval: int
77
+
78
+ /** Name of the aggregate or StateChangeSlice that receives the inbound command, or None for fire-and-forget. */
79
+ let targetName: option<string>
80
+
81
+ /**
82
+ Event sources this slice subscribes to, by topic key.
83
+
84
+ `[]` — the default and the historical behaviour — means this plugin's own DCB
85
+ event log. Naming sources explicitly subscribes to them instead: an Aggregate's
86
+ `Spec.name`, or a DCB source name (conventionally `"<pluginName>DcbEventLog"`),
87
+ matching the keys `AutomationSlice` mappings already use.
88
+
89
+ This exists because an outbound slice is the framework's one component for
90
+ *calling an external service and feeding the answer back*, and that job is not
91
+ specific to DCB-modelled entities. An Aggregate whose events should trigger an
92
+ outbound call had no route to one while this list was hard-wired.
93
+
94
+ Unlike `AutomationSlice`, the sources are a flat list rather than per-source
95
+ `Mapping` modules. An automation needs a `resolve` per source (a different
96
+ event completes the item depending on where it came from); an outbound item is
97
+ resolved by its own `translate` succeeding, so the only thing that varies per
98
+ source is the decode — and the one `consumedEvent` union already covers that.
99
+ The cost of the flat form is that two sources sharing an event-type name are
100
+ indistinguishable; declare only the sources whose events you mean.
101
+ */
102
+ let sourceNames: array<string>
103
+
104
+ /** Optional display name of the foreign system this anti-corruption slice publishes
105
+ to (e.g. `"EmailService"`). Drives the **external box** drawn outside the plugin
106
+ in the Event Graph / Context Map (see docs/plans/translation-external-boxes.md).
107
+ Auto-injected by `@@reventless.spec` defaulting to `None` — set it to name the box. */
108
+ let externalSystem: option<string>
109
+ }
110
+
111
+ /**
112
+ The Translation — `collect` and async `translate`. Both functions are
113
+ distinguished from the Inbound shape (which has only a sync `translate`).
114
+ */
115
+ module type Translation = {
116
+ module Spec: Spec
117
+
118
+ /**
119
+ Collect: map an incoming event to zero or more new outbound items.
120
+ Each item has an `id` (deduplication key) and the `outboundItem` payload.
121
+ Returns empty array if this event is not relevant.
122
+
123
+ `~sourceId` is the id of the entity the event was published for — the envelope's
124
+ `id`, not part of the event payload. A DCB event usually names its own subject
125
+ in the payload (`OrderPlaced({orderId, …})`) and can ignore this; an Aggregate's
126
+ event generally does not, because the aggregate id is what addressed it in the
127
+ first place. Without this the outbound item for `Registered({email, address})`
128
+ would have no way to say *which customer* it is for.
129
+ */
130
+ let collect: (Spec.consumedEvent, ~sourceId: string) => array<(string, Spec.outboundItem)>
131
+
132
+ /**
133
+ Translate: call the external service for a single outbound item.
134
+ Returns:
135
+ - `Ok(Some((targetId, cmd)))` to publish a command back into the system
136
+ - `Ok(None)` for fire-and-forget (no command back)
137
+ - `Error(msg)` on failure (item will be retried up to maxRetries)
138
+
139
+ `~capabilities` carries what the platform provisioned — a geocoder today. It is
140
+ how a provider-agnostic plugin reaches a provider-specific service without
141
+ naming one: the deployment decides what is behind `capabilities.geocode`, and
142
+ the call site does not change when that answer does. A slice calling a service
143
+ the framework knows nothing about still reaches it directly and simply ignores
144
+ this argument.
145
+ */
146
+ let translate: (string, Spec.outboundItem, ~capabilities: Capabilities.t) => promise<
147
+ result<option<(string, Spec.inboundCommand)>, string>,
148
+ >
149
+
150
+ /** File URL of this Translation module (`import.meta.url`). */
151
+ let moduleUrl: string
152
+ }
153
+
@@ -0,0 +1,2 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */