@reventlessdev/reventless-spec 3.0.0-alpha.109 → 3.0.0-alpha.110

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.110 (2026-08-12)
7
+
8
+ ### Features
9
+
10
+ * **ppx:** let a field say [@owner](https://github.com/owner) instead of spelling out its schema ([3bb0a4b](https://github.com/ReventlessDev/reventless-core/commit/3bb0a4bf3e5823fa929815fbe6f47203ba7958d7))
11
+
12
+
6
13
  # 3.0.0-alpha.109 (2026-08-12)
7
14
 
8
15
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-spec",
3
- "version": "3.0.0-alpha.109",
3
+ "version": "3.0.0-alpha.110",
4
4
  "description": "Specifications for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -20,25 +20,47 @@ the field goes unstamped and the view goes unscoped, silently. That is why
20
20
  why it exists at all rather than leaving each consumer to look the marker up
21
21
  itself.
22
22
 
23
- There is no `@owner` ppx shorthand yet — `@s.matches(Owner.string)` is the
24
- authoring form, not a workaround for one. The shorthand is sugar over exactly
25
- this, the way `@ref` is sugar over `Reference.to_`, so it can be added without
26
- changing what any reader here does; until it exists, prefer the explicit form
27
- over inventing an attribute the ppx will reject.
23
+ `@owner` is the authoring form and is sugar over the constructors below, the way
24
+ `@ref` is sugar over `Reference.to_`. Write `@s.matches(Owner.string)` by hand
25
+ only where the ppx shorthand cannot reach — a file with no `@@reventless.spec`
26
+ annotation, where the attribute would survive into the compiler as an unknown
27
+ one.
28
28
 
29
29
  @example
30
30
  ```rescript
31
31
  @schema type command =
32
32
  PlaceOrder({
33
33
  @partitionTag orderId: string,
34
- customerId: @s.matches(Owner.string) string,
34
+ @owner customerId: string,
35
35
  })
36
36
  ```
37
37
  */
38
38
  let ownerId: S.Metadata.Id.t<bool> = S.Metadata.Id.make(~namespace="reventless", ~name="owner")
39
39
 
40
+ /**
41
+ Layers the owner marker onto a schema that already says something else.
42
+
43
+ Owner-ness is independent of everything else a field declares: the same field
44
+ may be a DCB tag, a partition key, or a reference, and none of those implies or
45
+ is implied by owning. But a field carries at most one `@s.matches`, so the
46
+ shorthand composes by *wrapping* whatever schema the field already resolved to
47
+ rather than replacing it — replacing would silently drop the field's DCB tag,
48
+ and a dropped tag is a decision read that quietly misses events.
49
+ */
50
+ let mark = (schema: S.t<'a>): S.t<'a> => schema->S.Metadata.set(~id=ownerId, true)
51
+
40
52
  /** A string field declared as the record's owner. */
41
- let string: S.t<string> = S.string->S.Metadata.set(~id=ownerId, true)
53
+ let string: S.t<string> = S.string->mark
54
+
55
+ /**
56
+ An `option<string>` field declared as the record's owner.
57
+
58
+ Needed because `@s.matches` on an explicitly-`option`-typed field must supply
59
+ the whole field schema, wrapper included. The `f?: string` form needs nothing
60
+ extra: sury wraps the annotated inner schema itself, and `isFieldOwner` looks
61
+ through that wrapper either way.
62
+ */
63
+ let optionString: S.t<option<string>> = S.option(string)
42
64
 
43
65
  /** Whether this exact schema carries the marker. Does not look through wrappers. */
44
66
  let isOwner = (schema: S.t<unknown>): bool =>
@@ -7,7 +7,13 @@ import * as Semantic$Reventless from "../semantic/Semantic.res.mjs";
7
7
 
8
8
  let ownerId = S.Metadata.Id.make("reventless", "owner");
9
9
 
10
- let string = S.Metadata.set(S.string, ownerId, true);
10
+ function mark(schema) {
11
+ return S.Metadata.set(schema, ownerId, true);
12
+ }
13
+
14
+ let string = mark(S.string);
15
+
16
+ let optionString = S.option(string);
11
17
 
12
18
  function isOwner(schema) {
13
19
  return Stdlib_Option.getOr(S.Metadata.get(schema, ownerId), false);
@@ -86,7 +92,9 @@ function variantFieldNames(schema, variant) {
86
92
 
87
93
  export {
88
94
  ownerId,
95
+ mark,
89
96
  string,
97
+ optionString,
90
98
  isOwner,
91
99
  isFieldOwner,
92
100
  fieldNamesOfProperties,