@reventlessdev/reventless-spec 3.0.0-alpha.74 → 3.0.0-alpha.75

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 CHANGED
@@ -3,6 +3,13 @@
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.75 (2026-07-11)
7
+
8
+ ### Features
9
+
10
+ * **infra:** add DeployBootstrap seam for generated deploy programs ([f0dc868](https://github.com/ReventlessDev/reventless-core/commit/f0dc8686396d21e7b39667eb0825b2e57fe4dabf))
11
+
12
+
6
13
  # 3.0.0-alpha.74 (2026-07-11)
7
14
 
8
15
  ### Bug Fixes
package/README.md CHANGED
@@ -1,114 +1,109 @@
1
- [![npm version](https://img.shields.io/npm/v/@reventlessdev/reventless-spec.svg?label=version)](https://www.npmjs.com/package/@reventlessdev/reventless-spec)
2
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
- [![Changelog](https://img.shields.io/badge/📋-Changelog-blue)](./CHANGELOG.md)
4
-
5
- # `reventless-spec`
6
-
7
- Specification types and interfaces for Reventless applications.
8
-
9
- ## Usage
10
-
11
- - Add `@reventlessdev/reventless-spec` to your dependencies in `package.json`.
12
- - Add `@reventlessdev/reventless-spec` to your dependencies in `rescript.json`.
13
- - For general information see this monorepo's [readme](../../README.md)
14
-
15
- ## Installation
1
+ [![npm](https://img.shields.io/npm/v/@reventlessdev/reventless-spec.svg?label=npm)](https://www.npmjs.com/package/@reventlessdev/reventless-spec)
2
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
3
+ [![Docs](https://img.shields.io/badge/docs-reventless.dev-blue)](https://docs.reventless.dev)
4
+
5
+ # @reventlessdev/reventless-spec
6
+
7
+ > ⚠️ **Alpha.** APIs and on-disk formats can change without notice between releases.
8
+ > Pin exact versions and expect breaking changes.
9
+
10
+ The **specification layer** of [Reventless](https://docs.reventless.dev) — a
11
+ spec-driven, event-sourced CQRS framework written in [ReScript](https://rescript-lang.org).
12
+ This package holds the type specifications and module-type interfaces that the rest of the
13
+ framework is built on: the contracts application domain code implements (commands, events,
14
+ behaviors, projections) and the component-kind vocabulary the whole framework shares. It
15
+ has **no** runtime, cloud, or storage dependency, so domain code can declare its shape
16
+ against `reventless-spec` without pulling in an implementation. Modules are exposed under
17
+ the `Reventless` namespace.
18
+
19
+ ## What it provides
20
+
21
+ ReScript modules, consumed by adding the package to your `rescript.json` `dependencies`.
22
+
23
+ **Domain contracts (`types/`)**
24
+
25
+ - **`Message`** — the envelope metadata carried by every event and command (`meta`,
26
+ `event'<>`, `command'<>`), used for audit, correlation, tracing, and routing.
27
+ - **`Behavior`** — the module type application code implements to define aggregate business
28
+ logic: `initialState`, `evolve(state, event)`, and `decide(command, state)`.
29
+ - **`Projection`** — `Source` / `Target` module types describing a read model projected
30
+ from an aggregate's events.
31
+ - **`Handler`** — function signatures for handling commands, events, and errors.
32
+ - **`SideEffect`** — module type for an imperative side effect triggered by aggregate events
33
+ (read-only access to the query engine; emits no events).
34
+ - **`StoredEvent`** — the logical envelope for an event as it lives in storage; single
35
+ source of truth for the on-disk event shape.
36
+ - **`Authorization`** / **`Identity`** — provider-agnostic permission rules evaluated against
37
+ a resolved identity.
38
+ - **`QueryEngine`** — typed filter values and operations for read-model queries.
39
+ - **`Id`**, **`EventMapping`**, **`ReadConsistency`**, **`Schedule`**, **`Visibility`** —
40
+ supporting spec types for identifiers, event translation, consistency, scheduling, and
41
+ exposure.
42
+
43
+ **Component vocabulary (`components/`)**
44
+
45
+ - **`ComponentKind`** — the single source of truth for the Reventless component-kind
46
+ vocabulary (aggregates, read models, tasks, extension points, DCB slices), including every
47
+ accepted folder spelling and body-file suffix.
48
+ - Per-kind spec modules: `Aggregate`, `ReadModel`, `Task`, `ExtensionPoint`, `Plugin`, and
49
+ the DCB slices (`StateChangeSlice`, `StateViewSlice`, `AutomationSlice`,
50
+ `InboundTranslationSlice`, `OutboundTranslationSlice`), plus DCB tagging/validation helpers.
51
+
52
+ **`generate-plugin` CLI**
53
+
54
+ `reventless-spec` ships a `generate-plugin` binary that auto-generates `src/Plugin.res` from
55
+ a plugin's folder structure, classifying `.res` files by their parent folder name — no
56
+ hand-authored composition root required.
16
57
 
17
58
  ```bash
18
- npm install @reventlessdev/reventless-spec
19
- ```
20
-
21
- Add to your `rescript.json`:
22
-
23
- ```json
24
- {
25
- "bs-dependencies": ["@reventlessdev/reventless-spec"]
26
- }
59
+ generate-plugin src/ # generate src/Plugin.res from the src/ folder
27
60
  ```
28
61
 
29
- ---
62
+ Wire it into your build via a `prebuild` script so it runs before `rescript build`. The
63
+ generated `Plugin.res` is committed to git, so CI compiles it directly.
30
64
 
31
- ## `generate-plugin` CLI
65
+ ## Where it fits
32
66
 
33
- `reventless-spec` ships a `generate-plugin` binary that auto-generates `src/Plugin.res` from a plugin's folder structure. This eliminates the need to maintain a hand-authored composition root.
67
+ `reventless-spec` is the foundation package in the Reventless framework:
34
68
 
35
- ### Setup
36
-
37
- Add to your plugin's `package.json`:
38
-
39
- ```json
40
- {
41
- "scripts": {
42
- "generate": "generate-plugin src/",
43
- "prebuild": "npm run generate",
44
- "build": "rescript build"
45
- }
46
- }
47
69
  ```
48
-
49
- ### Usage
50
-
51
- ```bash
52
- generate-plugin src/ # generate src/Plugin.res from the src/ folder
53
- npm run build # prebuild runs generate automatically, then compiles
70
+ reventless-spec (specifications) ← this package
71
+ ↓
72
+ reventless-core (provider-agnostic framework)
73
+ ↓
74
+ reventless-aws / reventless-postgres / reventless-local (storage & deployment adapters)
54
75
  ```
55
76
 
56
- ### Folder conventions
77
+ - [`@reventlessdev/reventless-core`](https://www.npmjs.com/package/@reventlessdev/reventless-core)
78
+ builds on these specs to provide the runtime building blocks.
79
+ - [`@reventlessdev/reventless-infra`](https://www.npmjs.com/package/@reventlessdev/reventless-infra)
80
+ layers deploy-time infrastructure types on top of the same specs.
57
81
 
58
- The generator classifies `.res` files by their parent folder name. Chapter folders (e.g. `Product/`, `Customer/`) are transparent — only the leaf folder name matters.
82
+ You normally obtain `reventless-spec` transitively by scaffolding an app rather than
83
+ installing it on its own.
59
84
 
60
- | Folder | Component |
61
- |---|---|
62
- | `Aggregate[s]` | Aggregate — must be paired with a `*Behavior.res` |
63
- | `ReadModel[s]` | Read model — must be paired with a `*Projections.res` |
64
- | `Task[s]` | Task |
65
- | `ExtensionPoint[s]` | Extension point mapping |
66
- | `Extension[s]` | Extension mapping |
67
- | `StateChange[s][Slice[s]]` | DCB StateChangeSlice |
68
- | `StateView[s][Slice[s]]` | DCB StateViewSlice |
69
- | `Automation[s][Slice[s]]` | DCB AutomationSlice |
70
- | `InboundTranslation[s][Slice[s]]` | DCB InboundTranslationSlice |
71
- | `OutboundTranslation[s][Slice[s]]` | DCB OutboundTranslationSlice |
85
+ ## Install
72
86
 
73
- Always excluded: `Plugin/`, `tests/`, `lib/`, `*Test.res`, `*Fixtures.res`.
74
-
75
- ### `plugin.json` (optional)
87
+ ```bash
88
+ pnpm add @reventlessdev/reventless-spec
89
+ ```
76
90
 
77
- Place `src/plugin.json` to override defaults:
91
+ Then register it as a ReScript dependency in `rescript.json`:
78
92
 
79
93
  ```json
80
94
  {
81
- "name": "Catalog",
82
- "heartbeatInterval": 60,
83
- "exclude": ["Product/StateChangeSlice/Experimental.res", "Analytics/**"]
95
+ "dependencies": ["@reventlessdev/reventless-spec"]
84
96
  }
85
97
  ```
86
98
 
87
- | Field | Default |
88
- |---|---|
89
- | `name` | Derived from `package.json` `"name"` — unscoped, hyphens/underscores → PascalCase |
90
- | `heartbeatInterval` | `60` |
91
- | `exclude` | `[]` — file paths or globs relative to `src/` |
92
-
93
- ### Extension file convention
94
-
95
- Each file in `Extension/` must expose its mapping as `module Mapping`:
96
-
97
- ```rescript
98
- // OrdersExtension.res
99
- open ReventlessInfra.ExtensionMapping
100
-
101
- module Mapping = {
102
- module ExtensionPoint = OrderingSpec.OrdersExtensionPoint
103
- module Delegate = ProductDemand
104
- // ...
105
- }
106
- ```
99
+ Requires ReScript `^12.3.0` (peer dependency).
107
100
 
108
- The generator references it as `OrdersExtension.Mapping`.
101
+ ## Links
109
102
 
110
- ### Namespace note
103
+ - 📚 Documentation — [docs.reventless.dev](https://docs.reventless.dev)
104
+ - 📦 Repository — [ReventlessDev/reventless-core](https://github.com/ReventlessDev/reventless-core)
105
+ - 📋 [Changelog](./CHANGELOG.md)
111
106
 
112
- Plugin packages should use a **suffixed namespace** (e.g. `CatalogPlugin`, `OrderingPlugin`). Never use a bare name like `Ordering` — it shadows OCaml's built-in `Ordering` type used by comparisons.
107
+ ## License
113
108
 
114
- The generated `Plugin.res` is **committed to git** — CI compiles it directly without re-running the generator.
109
+ [Apache-2.0](https://opensource.org/licenses/Apache-2.0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-spec",
3
- "version": "3.0.0-alpha.74",
3
+ "version": "3.0.0-alpha.75",
4
4
  "description": "Specifications for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "rescript": "^12.3.0",
25
- "@reventlessdev/rescript-jest": "1.0.0-alpha.6"
25
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.7"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "rescript": "^12.3.0"
@@ -458,6 +458,10 @@ let renderMain = (~config: Config.config): string => {
458
458
  "// AUTO-GENERATED — do not edit. Run `npm run generate` to update.",
459
459
  "// " ++ name ++ " plugin — AWS deployment.",
460
460
  "",
461
+ // Deploy-time bootstrap seam (no-op unless a package registers a
462
+ // contribution). PreDeploy runs before the platform/plugin graph builds.
463
+ "ReventlessInfra.DeployBootstrap.run(PreDeploy)",
464
+ "",
461
465
  "module Platform = ReventlessAws.Platform.Make()",
462
466
  "module " ++ name ++ " = Plugin.Make(Platform)",
463
467
  "",
@@ -465,6 +469,9 @@ let renderMain = (~config: Config.config): string => {
465
469
  " ~plugin=module(" ++ name ++ "),",
466
470
  ")",
467
471
  "",
472
+ // PostDeploy runs after the graph is registered (exports, cross-stack output).
473
+ "ReventlessInfra.DeployBootstrap.run(PostDeploy)",
474
+ "",
468
475
  ]->Array.join("\n")
469
476
  }
470
477
 
@@ -300,12 +300,16 @@ function renderMain(config) {
300
300
  "// AUTO-GENERATED — do not edit. Run `npm run generate` to update.",
301
301
  "// " + name + " plugin — AWS deployment.",
302
302
  "",
303
+ "ReventlessInfra.DeployBootstrap.run(PreDeploy)",
304
+ "",
303
305
  "module Platform = ReventlessAws.Platform.Make()",
304
306
  "module " + name + " = Plugin.Make(Platform)",
305
307
  "",
306
308
  "let default = Platform.deployPlugin(",
307
309
  " ~plugin=module(" + name + "),",
308
310
  ")",
311
+ "",
312
+ "ReventlessInfra.DeployBootstrap.run(PostDeploy)",
309
313
  ""
310
314
  ].join("\n");
311
315
  }