@reventlessdev/reventless-infra 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.
- package/CHANGELOG.md +853 -0
- package/LICENSE +202 -0
- package/README.md +92 -0
- package/package.json +46 -0
- package/rescript.json +34 -0
- package/src/adapter/Adapter.res +88 -0
- package/src/adapter/Adapter.res.mjs +29 -0
- package/src/components/Aggregate.res +73 -0
- package/src/components/Aggregate.res.mjs +2 -0
- package/src/components/Api.res +120 -0
- package/src/components/Api.res.mjs +31 -0
- package/src/components/Api_Adapter.res +29 -0
- package/src/components/Api_Adapter.res.mjs +2 -0
- package/src/components/AutomationSlice.res +48 -0
- package/src/components/AutomationSlice.res.mjs +2 -0
- package/src/components/CommandGenerator.res +8 -0
- package/src/components/CommandGenerator.res.mjs +2 -0
- package/src/components/CommandTopic.res +70 -0
- package/src/components/CommandTopic.res.mjs +2 -0
- package/src/components/Component.js +56 -0
- package/src/components/Component.mjs +10 -0
- package/src/components/Component.res +90 -0
- package/src/components/Component.res.mjs +57 -0
- package/src/components/Component.resi +21 -0
- package/src/components/Counter.res +81 -0
- package/src/components/Counter.res.mjs +2 -0
- package/src/components/DcbEventLog.res +130 -0
- package/src/components/DcbEventLog.res.mjs +2 -0
- package/src/components/DeployBootstrap.res +83 -0
- package/src/components/DeployBootstrap.res.mjs +69 -0
- package/src/components/EventCollector.res +19 -0
- package/src/components/EventCollector.res.mjs +2 -0
- package/src/components/EventLog.res +24 -0
- package/src/components/EventLog.res.mjs +2 -0
- package/src/components/EventMapper.res +37 -0
- package/src/components/EventMapper.res.mjs +2 -0
- package/src/components/EventTopic.res +51 -0
- package/src/components/EventTopic.res.mjs +2 -0
- package/src/components/Extension.res +64 -0
- package/src/components/Extension.res.mjs +2 -0
- package/src/components/ExtensionPoint.res +62 -0
- package/src/components/ExtensionPoint.res.mjs +2 -0
- package/src/components/Heartbeat.res +7 -0
- package/src/components/Heartbeat.res.mjs +2 -0
- package/src/components/InboundTranslationSlice.res +41 -0
- package/src/components/InboundTranslationSlice.res.mjs +2 -0
- package/src/components/OutboundTranslationSlice.res +44 -0
- package/src/components/OutboundTranslationSlice.res.mjs +2 -0
- package/src/components/Plugin.res +93 -0
- package/src/components/Plugin.res.mjs +2 -0
- package/src/components/QueryDb.res +48 -0
- package/src/components/QueryDb.res.mjs +33 -0
- package/src/components/ReadModel.res +56 -0
- package/src/components/ReadModel.res.mjs +2 -0
- package/src/components/Scheduler.res +32 -0
- package/src/components/Scheduler.res.mjs +2 -0
- package/src/components/StateChangeSlice.res +45 -0
- package/src/components/StateChangeSlice.res.mjs +2 -0
- package/src/components/StateViewSlice.res +38 -0
- package/src/components/StateViewSlice.res.mjs +2 -0
- package/src/components/Task.res +89 -0
- package/src/components/Task.res.mjs +2 -0
- package/src/types/ExtensionMapping.res +448 -0
- package/src/types/ExtensionMapping.res.mjs +252 -0
- package/src/types/ExtensionPointMapping.res +303 -0
- package/src/types/ExtensionPointMapping.res.mjs +116 -0
- package/src/types/Message.res +3 -0
- package/src/types/Message.res.mjs +2 -0
- package/src/types/NoEventMappings.res +25 -0
- package/src/types/NoEventMappings.res.mjs +17 -0
- package/src/types/Platform.res +269 -0
- package/src/types/Platform.res.mjs +2 -0
- package/src/types/PluginExtensionPointSpec.res +55 -0
- package/src/types/PluginExtensionPointSpec.res.mjs +209 -0
- package/src/types/ResourceNaming.res +12 -0
- package/src/types/ResourceNaming.res.mjs +2 -0
- package/tests/DeployBootstrapTest.res +72 -0
- package/tests/DeployBootstrapTest.res.mjs +100 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Deploy-time outputs produced by the `Plugin.T.make` function.
|
|
3
|
+
|
|
4
|
+
All fields are `Pulumi.Output.t`-wrapped because they reference resources
|
|
5
|
+
provisioned during the Pulumi stack update.
|
|
6
|
+
*/
|
|
7
|
+
type outputs = {
|
|
8
|
+
id: Pulumi.Output.t<string>,
|
|
9
|
+
version: Pulumi.Output.t<string>,
|
|
10
|
+
heartbeatInterval: Pulumi.Output.t<int>,
|
|
11
|
+
eventCollector: Pulumi.Output.t<EventCollector.outputs>,
|
|
12
|
+
extensionPoints: Pulumi.Output.t<dict<ExtensionPoint.outputs>>,
|
|
13
|
+
extensions: Pulumi.Output.t<dict<Extension.outputs>>,
|
|
14
|
+
aggregates: Pulumi.Output.t<dict<Aggregate.outputs>>,
|
|
15
|
+
readModels: Pulumi.Output.t<dict<ReadModel.outputs>>,
|
|
16
|
+
tasks: Pulumi.Output.t<dict<Task.outputs>>,
|
|
17
|
+
/** AppSync / GraphQL resolver resources. */
|
|
18
|
+
resolvers: Pulumi.Output.t<array<Adapter.resource>>,
|
|
19
|
+
heartbeat: Pulumi.Output.t<Heartbeat.outputs>,
|
|
20
|
+
apiSchemaFragment: Pulumi.Output.t<option<Reventless.Plugin.apiSchemaFragment>>,
|
|
21
|
+
/** UI fragment manifest for runtime micro-frontend registration (None for pure backend plugins). */
|
|
22
|
+
uiFragments: Pulumi.Output.t<option<Reventless.Plugin.uiFragmentManifest>>,
|
|
23
|
+
/** Plugin structure carrying queryable and writable component metadata (None for pure backend plugins). */
|
|
24
|
+
pluginStructure: Pulumi.Output.t<option<Reventless.Plugin.pluginStructure>>,
|
|
25
|
+
/** Present when the plugin uses a `DcbEventLog`. */
|
|
26
|
+
dcbEventLog: Pulumi.Output.t<option<DcbEventLog.outputs>>,
|
|
27
|
+
stateChangeSlices: Pulumi.Output.t<dict<StateChangeSlice.outputs>>,
|
|
28
|
+
stateViewSlices: Pulumi.Output.t<dict<StateViewSlice.outputs>>,
|
|
29
|
+
automationSlices: Pulumi.Output.t<dict<AutomationSlice.outputs>>,
|
|
30
|
+
outboundTranslationSlices: Pulumi.Output.t<dict<OutboundTranslationSlice.outputs>>,
|
|
31
|
+
inboundTranslationSlices: Pulumi.Output.t<dict<InboundTranslationSlice.outputs>>,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
Module type for the top-level plugin factory.
|
|
36
|
+
|
|
37
|
+
Call `Plugin.T.make` to provision all plugin components (aggregates, read models,
|
|
38
|
+
tasks, extension points, extensions, heartbeat, DCB log) in a single Pulumi stack update.
|
|
39
|
+
|
|
40
|
+
DCB slices are passed directly as optional labeled arrays. When any slice array
|
|
41
|
+
is non-empty, a shared DCB EventLog is provisioned automatically.
|
|
42
|
+
*/
|
|
43
|
+
module type T = {
|
|
44
|
+
type api
|
|
45
|
+
type role
|
|
46
|
+
type component
|
|
47
|
+
let make: (
|
|
48
|
+
~name: string,
|
|
49
|
+
/** How often (in seconds) the heartbeat Lambda fires. */
|
|
50
|
+
~heartbeatInterval: int,
|
|
51
|
+
~extensionPoints: array<module(ExtensionPoint.T)>=?,
|
|
52
|
+
~extensions: array<module(Extension.Blueprint)>=?,
|
|
53
|
+
~aggregates: array<module(Aggregate.T with type api = api)>=?,
|
|
54
|
+
~readModels: array<module(ReadModel.T with type api = api and type role = role)>=?,
|
|
55
|
+
~tasks: array<module(Task.T)>=?,
|
|
56
|
+
~stateChangeSlices: array<module(StateChangeSlice.T)>=?,
|
|
57
|
+
~stateViewSlices: array<module(StateViewSlice.T)>=?,
|
|
58
|
+
~automationSlices: array<module(AutomationSlice.T)>=?,
|
|
59
|
+
~outboundTranslationSlices: array<module(OutboundTranslationSlice.T)>=?,
|
|
60
|
+
~inboundTranslationSlices: array<module(InboundTranslationSlice.T)>=?,
|
|
61
|
+
/** Spec names of StateChangeSlices / StateViewSlices whose GraphQL fields a
|
|
62
|
+
deploy-time system caller (SigV4 / IAM) must invoke. Sets
|
|
63
|
+
`systemCallable: true` on the matching mutation / query schema entries so
|
|
64
|
+
the AWS provider emits the dual-auth
|
|
65
|
+
`@aws_cognito_user_pools(...) @aws_iam` directive form. Authored via
|
|
66
|
+
`@@reventless.systemCallable` on the spec file and threaded here by the
|
|
67
|
+
plugin generator; see `docs/guides/appsync-iam-system-caller.md`. */
|
|
68
|
+
~systemCallableComponents: array<string>=?,
|
|
69
|
+
~uiFragments: Reventless.Plugin.uiFragmentManifest=?,
|
|
70
|
+
~pluginStructure: Reventless.Plugin.pluginStructure=?,
|
|
71
|
+
~opts: Pulumi.ComponentResource.options=?,
|
|
72
|
+
) => component
|
|
73
|
+
let makeAutoUIManifest: (
|
|
74
|
+
~remoteEntryUrl: string,
|
|
75
|
+
~name: string,
|
|
76
|
+
~pluginStructure: Reventless.Plugin.pluginStructure,
|
|
77
|
+
~readModelPositions: array<string>=?,
|
|
78
|
+
~aggregatePositions: array<string>=?,
|
|
79
|
+
) => Reventless.Plugin.uiFragmentManifest
|
|
80
|
+
let makePluginDefinition: (
|
|
81
|
+
~name: string,
|
|
82
|
+
~aggregates: array<module(Aggregate.T with type api = api)>=?,
|
|
83
|
+
~readModels: array<module(ReadModel.T with type api = api and type role = role)>=?,
|
|
84
|
+
~stateViewSlices: array<module(StateViewSlice.T)>=?,
|
|
85
|
+
~stateChangeSlices: array<module(StateChangeSlice.T)>=?,
|
|
86
|
+
~automationSlices: array<module(AutomationSlice.T)>=?,
|
|
87
|
+
~outboundTranslationSlices: array<module(OutboundTranslationSlice.T)>=?,
|
|
88
|
+
~inboundTranslationSlices: array<module(InboundTranslationSlice.T)>=?,
|
|
89
|
+
~extensions: array<module(Extension.Blueprint)>=?,
|
|
90
|
+
~extensionPoints: array<module(ExtensionPointMapping.Mapping)>=?,
|
|
91
|
+
~componentChapters: dict<string>=?,
|
|
92
|
+
) => Reventless.Plugin.pluginStructure
|
|
93
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Errors that can occur during read model storage operations.
|
|
3
|
+
|
|
4
|
+
Returned as the error variant in `Result.t` by read model operations that
|
|
5
|
+
interact with the underlying query database (e.g. DynamoDB).
|
|
6
|
+
*/
|
|
7
|
+
@schema
|
|
8
|
+
type storageError =
|
|
9
|
+
/** A write operation failed to persist the state. */
|
|
10
|
+
| NotSavedToStorage(string)
|
|
11
|
+
/** A read operation failed to retrieve the state. */
|
|
12
|
+
| NotLoadedFromStorage(string)
|
|
13
|
+
/** A count operation failed. */
|
|
14
|
+
| NotCountedOnStorage(string)
|
|
15
|
+
/** A delete operation failed. */
|
|
16
|
+
| NotDeletedFromStorage(string)
|
|
17
|
+
/** A batch write did not fully succeed (some items may not have been written). */
|
|
18
|
+
| BatchNotFullyWrittenToStorage(string)
|
|
19
|
+
/** A conditional write failed because the state was modified concurrently. */
|
|
20
|
+
| StaleState
|
|
21
|
+
/** A composite-key (sub-ID) operation was attempted but no sub-ID config was provided. */
|
|
22
|
+
| MissingSubIdConfig
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
A function that derives the infrastructure resources needed to back GraphQL resolvers,
|
|
26
|
+
given the set of all query database outputs in the plugin.
|
|
27
|
+
*/
|
|
28
|
+
type rec resolversResourcesMaker = dict<outputs> => array<Adapter.resource>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
Deploy-time outputs produced when a `QueryDb` is provisioned.
|
|
32
|
+
|
|
33
|
+
- `resources` — the underlying database infrastructure resources
|
|
34
|
+
- `resolversMaker` — callback used by the plugin to assemble resolver resources
|
|
35
|
+
- `dataSourceName` — name of the AppSync DataSource that fronts this query DB.
|
|
36
|
+
Surfaced separately from `resources` so admin-side schema-push barriers can
|
|
37
|
+
wait for the DataSource to settle before invoking StartSchemaCreation —
|
|
38
|
+
AppSync rejects concurrent CreateDataSource / StartSchemaCreation calls
|
|
39
|
+
with `ConcurrentModificationException`.
|
|
40
|
+
*/
|
|
41
|
+
and outputs = {
|
|
42
|
+
resources: array<Adapter.resource>,
|
|
43
|
+
resolversMaker: resolversResourcesMaker,
|
|
44
|
+
dataSourceName: Pulumi.Output.t<string>,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A dictionary of query database outputs keyed by read model name. */
|
|
48
|
+
type allOutputs = dict<outputs>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
|
|
5
|
+
let storageErrorSchema = S.union([
|
|
6
|
+
S.schema(s => ({
|
|
7
|
+
TAG: "NotSavedToStorage",
|
|
8
|
+
_0: s.m(S.string)
|
|
9
|
+
})),
|
|
10
|
+
S.schema(s => ({
|
|
11
|
+
TAG: "NotLoadedFromStorage",
|
|
12
|
+
_0: s.m(S.string)
|
|
13
|
+
})),
|
|
14
|
+
S.schema(s => ({
|
|
15
|
+
TAG: "NotCountedOnStorage",
|
|
16
|
+
_0: s.m(S.string)
|
|
17
|
+
})),
|
|
18
|
+
S.schema(s => ({
|
|
19
|
+
TAG: "NotDeletedFromStorage",
|
|
20
|
+
_0: s.m(S.string)
|
|
21
|
+
})),
|
|
22
|
+
S.schema(s => ({
|
|
23
|
+
TAG: "BatchNotFullyWrittenToStorage",
|
|
24
|
+
_0: s.m(S.string)
|
|
25
|
+
})),
|
|
26
|
+
S.literal("StaleState"),
|
|
27
|
+
S.literal("MissingSubIdConfig")
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
storageErrorSchema,
|
|
32
|
+
}
|
|
33
|
+
/* storageErrorSchema Not a pure module */
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Deploy-time outputs produced when a `ReadModel` is provisioned.
|
|
3
|
+
|
|
4
|
+
- `name` — the read model's logical name
|
|
5
|
+
- `queryDb` — the underlying query database outputs (DynamoDB table)
|
|
6
|
+
- `eventCollector` — the inbound event queue
|
|
7
|
+
- `sourceNames` — names of all aggregates whose events feed this read model
|
|
8
|
+
*/
|
|
9
|
+
type outputs = {
|
|
10
|
+
name: string,
|
|
11
|
+
queryDb: QueryDb.outputs,
|
|
12
|
+
eventCollector: Pulumi.Output.t<EventCollector.outputs>,
|
|
13
|
+
sourceNames: array<string>,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
Runtime operations exposed by a `ReadModel` component.
|
|
18
|
+
Used by the aggregate runtime to push events into the read model's event queue.
|
|
19
|
+
*/
|
|
20
|
+
type operations = {enqueueEvent: EventCollector.enqueueEvent}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Module type produced by `Platform.ReadModel.Make(Spec, Mappings)`.
|
|
24
|
+
|
|
25
|
+
@example
|
|
26
|
+
```rescript
|
|
27
|
+
// CatalogPlugin.res
|
|
28
|
+
module CategoryReadModel = Platform.ReadModel.Make(CategoriesReadModel, CategoryMappings)
|
|
29
|
+
|
|
30
|
+
let rm = CategoryReadModel.make(~api, ~apiRole, ~allEventTopics, ~opts=?)
|
|
31
|
+
```
|
|
32
|
+
*/
|
|
33
|
+
module type T = {
|
|
34
|
+
module Spec: Reventless.ReadModel.Spec
|
|
35
|
+
type api
|
|
36
|
+
type role
|
|
37
|
+
type component
|
|
38
|
+
/** Names of aggregates whose events feed this read model (from Projection.Mapping.sourceName). */
|
|
39
|
+
let sourceNames: array<string>
|
|
40
|
+
/** Bare event-variant names this read model consumes, unioned across every projection
|
|
41
|
+
mapping's source event schema (Projection.Mapping.sourceEventSchema). Unlike
|
|
42
|
+
`sourceNames` (the source aggregate / DCB-log names) this names the actual events — so
|
|
43
|
+
a DCB-log-sourced mapping (e.g. consuming `OrderPlaced`) is captured, which sourceNames
|
|
44
|
+
cannot express. Plugin_Structure qualifies + exposes these as `queryableDef.consumedEventTypes`. */
|
|
45
|
+
let consumedEventNames: array<string>
|
|
46
|
+
let make: (
|
|
47
|
+
~api: api,
|
|
48
|
+
~apiRole: role,
|
|
49
|
+
~allEventTopics: EventTopic.allOutputs,
|
|
50
|
+
~opts: Pulumi.ComponentResource.options=?,
|
|
51
|
+
) => component
|
|
52
|
+
let outputs: component => outputs
|
|
53
|
+
let operations: component => Pulumi.Output.t<operations>
|
|
54
|
+
/** Signal that all sources have been registered; finalises the read model. */
|
|
55
|
+
let finish: unit => unit
|
|
56
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Deploy-time outputs produced when a `Scheduler` component is provisioned.
|
|
3
|
+
Contains the single infrastructure resource backing the scheduler (e.g. EventBridge Scheduler).
|
|
4
|
+
*/
|
|
5
|
+
type outputs = {resource: Adapter.resource}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
Creates a schedule in the underlying scheduling service (e.g. EventBridge Scheduler).
|
|
9
|
+
|
|
10
|
+
- `array<Adapter.resolvedResource>` — resolved scheduler resources (ARNs, etc.)
|
|
11
|
+
- `Reventless.Schedule.schedule` — the schedule definition to create
|
|
12
|
+
*/
|
|
13
|
+
type createSchedule = (array<Adapter.resolvedResource>, Reventless.Schedule.schedule) => promise<unit>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
Deletes a schedule by name from the underlying scheduling service.
|
|
17
|
+
|
|
18
|
+
- `array<Adapter.resolvedResource>` — resolved scheduler resources
|
|
19
|
+
- `string` — the name of the schedule to delete
|
|
20
|
+
*/
|
|
21
|
+
type deleteSchedule = (array<Adapter.resolvedResource>, string) => promise<unit>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
Runtime operations exposed by a `Scheduler` component.
|
|
25
|
+
|
|
26
|
+
Injected into extension points, tasks, and the plugin to create or delete
|
|
27
|
+
schedules dynamically at runtime.
|
|
28
|
+
*/
|
|
29
|
+
type operations = {
|
|
30
|
+
createSchedule: createSchedule,
|
|
31
|
+
deleteSchedule: deleteSchedule,
|
|
32
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Deploy-time outputs produced when a `StateChangeSlice` is provisioned.
|
|
3
|
+
Contains the underlying command queue infrastructure resources.
|
|
4
|
+
*/
|
|
5
|
+
type outputs = {
|
|
6
|
+
resources: array<Adapter.resource>,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
Runtime operations exposed by a `StateChangeSlice` component.
|
|
11
|
+
Used to publish commands to this slice's command topic.
|
|
12
|
+
*/
|
|
13
|
+
type operations = {publishJsons: CommandTopic.publishJsons}
|
|
14
|
+
|
|
15
|
+
type t
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
Module type produced by `Platform.StateChangeSlice.Make(Spec, Behavior)`.
|
|
19
|
+
|
|
20
|
+
@example
|
|
21
|
+
```rescript
|
|
22
|
+
// CatalogPlugin.res
|
|
23
|
+
module AddCategorySlice = Platform.StateChangeSlice.Make(AddCategory, AddCategory_Behavior)
|
|
24
|
+
let slice = AddCategorySlice.make(~dcbEventLog=log, ~publishJsons=publishJsonsOutput)
|
|
25
|
+
```
|
|
26
|
+
*/
|
|
27
|
+
module type T = {
|
|
28
|
+
module Spec: Reventless.StateChangeSlice.Spec
|
|
29
|
+
module Behavior: Reventless.StateChangeSlice.Behavior with module Spec := Spec
|
|
30
|
+
/** `true` when built with `Platform.StateChangeSlice.MakeAsync` — uses FIFO channel, returns `CommandPending`. */
|
|
31
|
+
let isAsync: bool
|
|
32
|
+
type component = Component.t<t, outputs, operations>
|
|
33
|
+
let make: (
|
|
34
|
+
~dcbEventLog: DcbEventLog.component,
|
|
35
|
+
~publishJsons: Pulumi.Output.t<CommandTopic.publishJsons>,
|
|
36
|
+
/** Produced event-log type→tag-key map, used to drop vacuous (type, tag)
|
|
37
|
+
clause combinations when building the decision-model query. */
|
|
38
|
+
~tagKeysByEventType: Dict.t<array<string>>=?,
|
|
39
|
+
/** Tag keys declared `@crossPartition` across the produced event schemas —
|
|
40
|
+
a cross-partition scalar command tag fans out into its own single-tag
|
|
41
|
+
decision-read clause. */
|
|
42
|
+
~crossPartitionTagKeys: array<string>=?,
|
|
43
|
+
~opts: Pulumi.ComponentResource.options=?,
|
|
44
|
+
) => component
|
|
45
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Deploy-time outputs produced when a `StateViewSlice` is provisioned.
|
|
3
|
+
|
|
4
|
+
- `resources` — the underlying infrastructure (e.g. SQS subscription)
|
|
5
|
+
- `queryDb` — the DynamoDB table for querying projected state
|
|
6
|
+
*/
|
|
7
|
+
type outputs = {
|
|
8
|
+
resources: array<Adapter.resource>,
|
|
9
|
+
queryDb: QueryDb.outputs,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
Runtime operations exposed by a `StateViewSlice` component.
|
|
14
|
+
Used to push events into the slice's projection queue.
|
|
15
|
+
*/
|
|
16
|
+
type operations = {enqueueEvent: EventCollector.enqueueEvent}
|
|
17
|
+
|
|
18
|
+
type t
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
Module type produced by `Platform.StateViewSlice.Make(Spec, Projection)`.
|
|
22
|
+
|
|
23
|
+
@example
|
|
24
|
+
```rescript
|
|
25
|
+
// CatalogPlugin.res
|
|
26
|
+
module CategoriesViewSlice = Platform.StateViewSlice.Make(CategoriesView, CategoriesView_Projection)
|
|
27
|
+
let slice = CategoriesViewSlice.make(~dcbEventLog=log)
|
|
28
|
+
```
|
|
29
|
+
*/
|
|
30
|
+
module type T = {
|
|
31
|
+
module Spec: Reventless.StateViewSlice.Spec
|
|
32
|
+
module Projection: Reventless.StateViewSlice.Projection with module Spec := Spec
|
|
33
|
+
type component = Component.t<t, outputs, operations>
|
|
34
|
+
let make: (
|
|
35
|
+
~dcbEventLog: DcbEventLog.component,
|
|
36
|
+
~opts: Pulumi.ComponentResource.options=?,
|
|
37
|
+
) => component
|
|
38
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
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
|
+
The `setup` function signature for a `Task.Spec`.
|
|
11
|
+
|
|
12
|
+
Called at deploy time to configure the task's infrastructure.
|
|
13
|
+
Receives the query engine, bucket name helper, and Pulumi options.
|
|
14
|
+
Returns the task's runtime `config`.
|
|
15
|
+
*/
|
|
16
|
+
type setup = (
|
|
17
|
+
Reventless.QueryEngine.operations,
|
|
18
|
+
queryBucketName,
|
|
19
|
+
Pulumi.ComponentResource.options,
|
|
20
|
+
) => Reventless.Task.config
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
Module type for a task's specification.
|
|
24
|
+
|
|
25
|
+
A `Task` is a serverless handler triggered by S3 events or schedules.
|
|
26
|
+
It can publish commands, manage schedules, and execute side effects.
|
|
27
|
+
|
|
28
|
+
@example
|
|
29
|
+
```rescript
|
|
30
|
+
module CatalogImportTask: Task.Spec = {
|
|
31
|
+
let name = "CatalogImport"
|
|
32
|
+
let setup = (_queryEngine, _queryBucketName, _opts) => {
|
|
33
|
+
buckets: [{bucketMode: Read}],
|
|
34
|
+
sideEffects: [],
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
*/
|
|
39
|
+
module type Spec = {
|
|
40
|
+
/** Logical task name (used as a Lambda function name prefix). */
|
|
41
|
+
let name: string
|
|
42
|
+
/** ESM specifier for this Spec module — populated by `@@reventless.task` PPX. */
|
|
43
|
+
let moduleUrl: string
|
|
44
|
+
let setup: setup
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
Deploy-time outputs produced when a `Task` is provisioned.
|
|
49
|
+
|
|
50
|
+
- `name` — the task's logical name
|
|
51
|
+
- `bucketNames` — resolved S3 bucket names keyed by bucket spec index
|
|
52
|
+
- `sideEffectSources` — names of aggregate event sources wired to side effects
|
|
53
|
+
*/
|
|
54
|
+
type outputs = {
|
|
55
|
+
name: string,
|
|
56
|
+
bucketNames?: dict<Pulumi.Output.t<string>>,
|
|
57
|
+
sideEffectSources?: array<string>,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
Runtime operations exposed by a `Task` component.
|
|
62
|
+
Allows the task handler to publish commands to aggregates by name.
|
|
63
|
+
*/
|
|
64
|
+
type operations = {
|
|
65
|
+
publishCommands: (string, array<Reventless.Message.commandJson>) => promise<unit>,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
Module type produced by `Platform.Task.Make(Spec)`.
|
|
70
|
+
*/
|
|
71
|
+
module type T = {
|
|
72
|
+
module Spec: Spec
|
|
73
|
+
type component
|
|
74
|
+
let make: (
|
|
75
|
+
~queryBucketName: queryBucketName,
|
|
76
|
+
~scheduler: Scheduler.operations,
|
|
77
|
+
/** URN identifying the principal/role the scheduler invokes targets as.
|
|
78
|
+
Bundled adapters thread this into the runtime config so the deployed
|
|
79
|
+
handler can call the underlying scheduler service. Adapters without
|
|
80
|
+
a real scheduler (e.g. in-memory) ignore it. */
|
|
81
|
+
~schedulerRoleUrn: Pulumi.Output.t<string>,
|
|
82
|
+
~publishToAggregates: dict<CommandTopic.publishJsons>,
|
|
83
|
+
~queryEngine: Reventless.QueryEngine.operations,
|
|
84
|
+
~resourceNaming: ResourceNaming.operations,
|
|
85
|
+
~allAggregates: dict<Aggregate.outputs>,
|
|
86
|
+
~opts: option<Pulumi.ComponentResource.options>,
|
|
87
|
+
) => component
|
|
88
|
+
let outputs: component => outputs
|
|
89
|
+
}
|