@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,97 @@
1
+ /**
2
+ Spec describing the structural annotations declared on the fields of an
3
+ `@schema type state` record. The ppx attaches one of these to the generated
4
+ `stateSchema` whenever a field carries a structural annotation (`@id`,
5
+ `@compositeId`, `@subId`, `@compositeSubId`, `@index`), a visibility
6
+ annotation (`@hidden`, `@summary`), a hierarchical-rendering annotation
7
+ (`@drillTarget`, `@collapsed`), a server-query opt-in annotation
8
+ (`@scan`, `@scanSort`), or a UI-list annotation (`@status`, `@groupBy`).
9
+ Downstream consumers (UI, MCP, codegen) read the
10
+ spec to surface field roles in JSON Schema as `x-reventless-*` extension
11
+ properties.
12
+
13
+ Each list contains the source field names; `indexes` carries `(fieldName,
14
+ indexName)` pairs where `indexName` is `""` for unnamed `@index` annotations.
15
+ `hidden` lists fields the UI should suppress from summary/list views;
16
+ `summary` lists fields the UI should always include in summary/list views.
17
+ `drillTargets` carries `(fieldName, sliceName)` pairs naming the slice/view
18
+ the UI should navigate to instead of expanding the field inline;
19
+ `drillTargetKeys` carries `(fieldName, keyPath)` pairs for fields whose
20
+ drill-down target is keyed by a sub-path within the array element;
21
+ `collapsed` lists object-typed fields the UI should render as an inline
22
+ summary rather than expanding. `scan` lists fields the type author opted
23
+ into server-side equality filtering on (without a backing index); `scanSort`
24
+ lists fields the type author opted into server-side sorting on. The cost is
25
+ free on the in-memory adapter but is `O(n)` Scan + FilterExpression on
26
+ DynamoDB-backed adapters — the annotation is the explicit signal that the
27
+ read model is small enough or the cost is acceptable.
28
+ */
29
+ /**
30
+ Declared aggregation for a `@metric`-annotated numeric field. `aggregate` is one
31
+ of `"count"`, `"sum"`, `"avg"` (the UI's dashboard vocabulary); `label` is the
32
+ KPI label, or `""` to let the UI derive one from the field name.
33
+ */
34
+ type metricSpec = {aggregate: string, label: string}
35
+
36
+ type stateAnnotationSpec = {
37
+ ids: array<string>,
38
+ compositeIds: array<string>,
39
+ subIds: array<string>,
40
+ compositeSubIds: array<string>,
41
+ indexes: array<(string, string)>,
42
+ hidden: array<string>,
43
+ summary: array<string>,
44
+ drillTargets: array<(string, string)>,
45
+ drillTargetKeys: array<(string, string)>,
46
+ collapsed: array<string>,
47
+ scan: array<string>,
48
+ scanSort: array<string>,
49
+ /**
50
+ Fields annotated `@semantic("<id>")` — `(fieldName, semanticId)` pairs. The
51
+ semantic id is the UI's `AutoSemantics` vocabulary (e.g. `"currency"`,
52
+ `"geo-lat"`); the PPX can't validate it (the UI owns that vocabulary).
53
+ `SuryToJsonSchema` emits `x-reventless-semantic` on the named field, which
54
+ AutoUI reads at `#Annotation` provenance — above its heuristic, below a
55
+ `ui-hints.json` `fields:` override.
56
+ */
57
+ semantic: array<(string, string)>,
58
+ /**
59
+ Fields annotated `@metric(...)` — `(fieldName, metricSpec)` pairs.
60
+ `SuryToJsonSchema` emits `x-reventless-metric: {aggregate, label}` on the named
61
+ field, which AutoUI folds into the dashboard metric list it already builds from
62
+ hints — so a plugin gets a Dashboard page from its schema alone.
63
+ */
64
+ metric: array<(string, metricSpec)>,
65
+ /**
66
+ Field annotated `@status` on the state record (PPX-emitted). `Some(name)`
67
+ when one such annotation exists; the PPX errors on duplicate `@status`
68
+ annotations within the same record. Codegen consumes this to populate
69
+ `queryableDef.statusField` (with a fallback to a field literally named
70
+ `"status"` when this annotation is absent).
71
+ */
72
+ status: option<string>,
73
+ /**
74
+ Field annotated `@groupBy` on the state record (PPX-emitted). `Some(name)`
75
+ when one such annotation exists; the PPX errors on duplicate `@groupBy`
76
+ annotations within the same record. `SuryToJsonSchema.deriveObjectSchema`
77
+ emits `x-reventless-group-by: true` on the named field, which the UI's
78
+ list view reads to render rows in sections keyed on that field.
79
+ */
80
+ groupBy: option<string>,
81
+ /**
82
+ Component-level visibility hint from `@@reventless.visibility(...)`.
83
+ `Some("Internal")` when the file-level attribute is `Internal`; `None`
84
+ (omitted) for the default `Public`. `SuryToJsonSchema.deriveObjectSchema`
85
+ emits `x-reventless-visibility: "Internal"` on the schema when present —
86
+ the default case is omitted to keep schemas compact.
87
+ */
88
+ visibility: option<string>,
89
+ }
90
+
91
+ /** Sury metadata ID used to attach a `stateAnnotationSpec` to a state schema. */
92
+ let stateAnnotationsId: S.Metadata.Id.t<stateAnnotationSpec> =
93
+ S.Metadata.Id.make(~namespace="reventless", ~name="stateAnnotations")
94
+
95
+ /** Returns the spec attached to a state schema, if any. */
96
+ let getSpec = (schema: S.t<unknown>): option<stateAnnotationSpec> =>
97
+ S.Metadata.get(schema, ~id=stateAnnotationsId)
@@ -0,0 +1,15 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as S from "sury/src/S.res.mjs";
4
+
5
+ let stateAnnotationsId = S.Metadata.Id.make("reventless", "stateAnnotations");
6
+
7
+ function getSpec(schema) {
8
+ return S.Metadata.get(schema, stateAnnotationsId);
9
+ }
10
+
11
+ export {
12
+ stateAnnotationsId,
13
+ getSpec,
14
+ }
15
+ /* stateAnnotationsId Not a pure module */
@@ -0,0 +1,131 @@
1
+ /**
2
+ Module types for a DCB write-side state change slice.
3
+
4
+ A `StateChangeSlice` is the DCB equivalent of an aggregate: it processes
5
+ commands by reading the relevant events from a shared `DcbEventLog`, building
6
+ a `state` (ephemeral read model), and appending new events conditioned
7
+ on no concurrent changes to the same entities.
8
+
9
+ Plan 02 splits the merged spec into two module types:
10
+
11
+ - `Spec` — types, identity, schemas. The structural contract.
12
+ - `Behavior` — `state`, `initialState`, `evolve`, `decide`. The state machine.
13
+
14
+ @example
15
+ ```rescript
16
+ // AddCategory.res
17
+ let name = "AddCategory"
18
+
19
+ type state = {exists: bool, archived: bool}
20
+ let initialState = {exists: false, archived: false}
21
+
22
+ @schema type consumedEvent =
23
+ | CategoryAdded
24
+ | CategoryArchived
25
+
26
+ let evolve = (state, event) => switch event {
27
+ | CategoryAdded => {exists: true, archived: false}
28
+ | CategoryArchived => {...state, archived: true}
29
+ }
30
+
31
+ @schema type command = AddCategory({categoryId: @s.matches(DcbTag.string) string, name: string})
32
+ @schema type error = CategoryAlreadyExists
33
+
34
+ @schema type event =
35
+ | CategoryAdded({categoryId: @s.matches(DcbTag.string) string, name: string})
36
+
37
+ let decide = (state, command) => switch command {
38
+ | AddCategory({categoryId, name}) =>
39
+ if state.exists { Error(CategoryAlreadyExists) }
40
+ else { Ok([CategoryAdded({categoryId, name})]) }
41
+ }
42
+ ```
43
+ */
44
+
45
+ /**
46
+ The lean Spec for a StateChangeSlice — types, identity, schemas. State and
47
+ state-evolution functions live in the sibling `Behavior` module type.
48
+ */
49
+ module type Spec = {
50
+ /** Logical name of this slice (used as a command topic prefix). */
51
+ let name: string
52
+ let moduleUrl: string
53
+
54
+ /** Identity type — always `Id.String` for DCB slices. */
55
+ module Id: Id.T
56
+
57
+ /**
58
+ Events this slice reads to build its decision model (in `evolve`).
59
+ Only needs the fields required for the decision — no tag annotations needed.
60
+ May be payload-less for events where only existence matters.
61
+ Must carry `@schema`.
62
+ */
63
+ @schema
64
+ type consumedEvent
65
+
66
+ /** Commands this slice handles. Must carry `@schema`. */
67
+ @schema
68
+ type command
69
+
70
+ /** Business rule violation errors. Must carry `@schema`. */
71
+ @schema
72
+ type error
73
+
74
+ /** Events this slice emits (from `decide`). Must carry `@schema` and include tag annotations. */
75
+ @schema
76
+ type event
77
+
78
+ /** Schema for the command type — used to extract DCB tags for the conditional read. */
79
+ let commandSchema: S.t<command>
80
+
81
+ /** Authorization rule evaluated at the GraphQL resolver entry before any
82
+ command is dispatched. Auto-injected by `@@reventless.spec` and on
83
+ structurally-detected inline spec modules — defaults to
84
+ `AllowAuthenticated`; override at the file/module level with
85
+ `@@reventless.authorize(<rule>)`. */
86
+ let commandAuthorization: command => Authorization.permission
87
+
88
+ /** Decision-read consistency mode for this slice's optimistic-concurrency
89
+ retry loop. Auto-injected by `@@reventless.spec` and on
90
+ structurally-detected inline spec modules — defaults to
91
+ `EscalateOnRetry` (eventual first, strong on retry); override at the
92
+ file/module level with `@@reventless.consistency(AlwaysStrong)` (or
93
+ `AlwaysEventual`). Affects RCU/latency only, never correctness — the
94
+ conditional append's fence is always evaluated strongly. */
95
+ let readConsistency: ReadConsistency.t
96
+ }
97
+
98
+ /**
99
+ The Behavior — pure state machine that decides commands and folds events.
100
+
101
+ `module Spec: Spec` shares the lean Spec's types so `evolve` references
102
+ `Spec.consumedEvent`, `decide` references `Spec.command`/`Spec.event`/`Spec.error`.
103
+ */
104
+ module type Behavior = {
105
+ module Spec: Spec
106
+
107
+ /**
108
+ The ephemeral state built by replaying relevant events.
109
+ Not persisted — reconstructed for each command by reading from the DCB log.
110
+ */
111
+ type state
112
+
113
+ /** The initial (empty) state before any events have been applied. */
114
+ let initialState: state
115
+
116
+ /**
117
+ Folds one consumed event into the state during the read phase.
118
+ Must be a pure function — no side effects.
119
+ */
120
+ let evolve: (state, Spec.consumedEvent) => state
121
+
122
+ /**
123
+ Decides what events to append given the current state and the command.
124
+ Return `Ok(events)` to append, or `Error(error)` to reject the command.
125
+ */
126
+ let decide: (state, Spec.command) => result<array<Spec.event>, Spec.error>
127
+
128
+ /** File URL of this Behavior module (`import.meta.url`). */
129
+ let moduleUrl: string
130
+ }
131
+
@@ -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. */
@@ -0,0 +1,123 @@
1
+ /**
2
+ Module types for a DCB read-side state view slice.
3
+
4
+ A `StateViewSlice` is the DCB equivalent of a `ReadModel`: it listens to the
5
+ shared `DcbEventLog` event topic and projects events into a queryable state table
6
+ using the `Projection.action` algebra.
7
+
8
+ Plan 02 splits the merged spec into two module types:
9
+
10
+ - `Spec` — types, identity, schemas, infrastructure config. The persisted
11
+ state contract (matches the ReadModel convention where `state` is in Spec).
12
+ - `Projection` — the single `project` function (and any future projection
13
+ helpers).
14
+
15
+ @example
16
+ ```rescript
17
+ // CategoriesView.res
18
+ let name = "CategoriesView"
19
+
20
+ @schema type state = {categoryId: string, name: string, archived: bool}
21
+
22
+ @schema type consumedEvent =
23
+ | CategoryAdded({categoryId: string, name: string})
24
+ | CategoryRenamed({categoryId: string, name: string})
25
+ | CategoryArchived({categoryId: string})
26
+
27
+ let project = ({event}) => switch event {
28
+ | CategoryAdded({categoryId, name}) =>
29
+ [Set(categoryId, {categoryId, name, archived: false})]
30
+ | CategoryRenamed({categoryId, name}) =>
31
+ [Update(categoryId, state => {...state, name})]
32
+ | CategoryArchived({categoryId}) =>
33
+ [Update(categoryId, state => {...state, archived: true})]
34
+ }
35
+ ```
36
+ */
37
+
38
+ /**
39
+ The lean Spec for a StateViewSlice — types, identity, schemas, infra config.
40
+ Per D2, `state` lives here (not in `Projection`) because the projected state
41
+ is the externally-observable contract — schema queried by GraphQL resolvers.
42
+ */
43
+ module type Spec = {
44
+ /** Logical name of this view slice (used as a DynamoDB table prefix). */
45
+ let name: string
46
+ let moduleUrl: string
47
+
48
+ /** The projected state type stored in the view table. Must carry `@schema`. */
49
+ @schema
50
+ type state
51
+
52
+ /** Sury schema for the state type — generated automatically by `@schema`. */
53
+ let stateSchema: S.t<state>
54
+
55
+ /**
56
+ Events this view slice projects. Only needs the fields required for the projection —
57
+ no tag annotations needed. May be payload-less where only existence matters.
58
+ Must carry `@schema`.
59
+ */
60
+ @schema
61
+ type consumedEvent
62
+
63
+ /** Infrastructure configuration (indexes, resolvers). */
64
+ let config: ReadModel.config
65
+
66
+ /** Optional composite-key configuration. `None` for single-key tables. */
67
+ let subIdConfig: option<ReadModel.subIdConfig<state>>
68
+
69
+ /** Authorization rule evaluated at the GraphQL resolver entry before any
70
+ query is resolved. Auto-injected by `@@reventless.spec` and on
71
+ structurally-detected inline spec modules — defaults to
72
+ `AllowAuthenticated`. */
73
+ let authorization: Authorization.permission
74
+
75
+ /** AutoUI visibility hint. Auto-injected by `@@reventless.spec` and on
76
+ structurally-detected inline spec modules — defaults to
77
+ `Visibility.Public`; override at the file/module level with
78
+ `@@reventless.visibility(Internal)` to hide from the AutoUI manifest.
79
+ Does not affect GraphQL exposure, authorization, or resolver
80
+ provisioning. */
81
+ let visibility: Visibility.t
82
+ }
83
+
84
+ /**
85
+ The envelope a projection receives for each consumed event.
86
+
87
+ Carries the decoded event alongside the metadata the storage layer already
88
+ holds, so a projection can persist producer time or the acting user without the
89
+ command author having to duplicate that framework state into the event payload.
90
+
91
+ `meta.time` and `recordedAt` are **different clocks** — pick deliberately:
92
+
93
+ - `meta.time` — *producer* time, stamped when the command handler created the
94
+ event. This is the domain-meaningful timestamp (when the order was placed,
95
+ when it shipped); it is identical across every path.
96
+ - `recordedAt` — *storage* time, when the event was appended to the DCB log. On
97
+ the AWS (DynamoDB-stream) path this is the authoritative stored column; on the
98
+ local (topic) path it is stamped at publish, so it may sit a few milliseconds
99
+ after the stored value. Use it for storage-lag diagnostics, not domain dates.
100
+ */
101
+ type consumed<'e> = {
102
+ event: 'e,
103
+ meta: Message.meta,
104
+ recordedAt: string,
105
+ }
106
+
107
+ /**
108
+ The Projection — the pure projection function from consumed events to actions.
109
+ */
110
+ module type Projection = {
111
+ module Spec: Spec
112
+
113
+ /**
114
+ Projects one consumed event into read model actions.
115
+ Receives the event wrapped in a `consumed` envelope (event + `meta` +
116
+ `recordedAt`); only events declared in `Spec.consumedEvent` — no wildcard needed.
117
+ */
118
+ let project: consumed<Spec.consumedEvent> => array<Projection.action<string, Spec.state>>
119
+
120
+ /** File URL of this Projection module (`import.meta.url`). */
121
+ let moduleUrl: string
122
+ }
123
+
@@ -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. */
@@ -0,0 +1,62 @@
1
+ /**
2
+ Derives the name used to query a task's S3 bucket.
3
+
4
+ - `~taskName` — the task's logical name
5
+ - `~bucketName` — optional override; defaults to the task's configured bucket name
6
+ */
7
+ type queryBucketName = (~taskName: string, ~bucketName: string=?) => string
8
+
9
+ /**
10
+ An action that a task handler can return after processing a trigger.
11
+
12
+ - `PublishCommands(aggregateName, commands)` — publish commands to an aggregate
13
+ - `CreateSchedule(schedule)` — create a new recurring or one-time schedule
14
+ - `DeleteSchedule(name)` — delete a schedule by name
15
+ */
16
+ type taskAction =
17
+ | PublishCommands(string, array<Message.commandJson>)
18
+ | CreateSchedule(Schedule.schedule)
19
+ | DeleteSchedule(string)
20
+
21
+ /**
22
+ A callback invoked when an S3 object event occurs on a task bucket.
23
+
24
+ - `~eventName` — the S3 event type (e.g. `"ObjectCreated:Put"`)
25
+ - `~key` — the S3 object key that triggered the event
26
+
27
+ Returns an array of `taskAction` values to execute after the callback completes.
28
+ */
29
+ type bucketCallback = (~eventName: string, ~key: string) => promise<array<taskAction>>
30
+
31
+ /**
32
+ The access mode a task needs for one of its S3 buckets.
33
+
34
+ - `Read` — task reads from the bucket (e.g. to import catalog data)
35
+ - `Write` — task writes to the bucket (e.g. to export a report)
36
+ - `ReadWrite` — task reads and writes
37
+ */
38
+ type bucketMode = Read | Write | ReadWrite
39
+
40
+ /**
41
+ Configuration for one S3 bucket used by a task.
42
+
43
+ - `bucketName` — optional override; if absent, the framework derives a name
44
+ - `bucketMode` — the required access level
45
+ - `callback` — optional handler triggered by S3 object events
46
+ */
47
+ type bucketSpec = {bucketName?: string, bucketMode: bucketMode, callback?: bucketCallback}
48
+
49
+ /** An array of `SideEffect.T` modules executed when this task fires. */
50
+ type sideEffects = array<module(SideEffect.T)>
51
+
52
+ /**
53
+ The runtime configuration returned by a task's `setup` function.
54
+
55
+ - `buckets` — optional list of S3 bucket specifications
56
+ - `sideEffects` — optional list of side effect modules to execute
57
+ */
58
+ type config = {
59
+ buckets?: array<bucketSpec>,
60
+ sideEffects?: sideEffects,
61
+ }
62
+
@@ -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. */