@crvouga/atlas 0.8.0 → 0.9.0

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
@@ -1,5 +1,11 @@
1
1
  # Changelog: @crvouga/atlas
2
2
 
3
+ ## 0.9.0 (2026-10-15)
4
+
5
+ ### Features
6
+
7
+ - accept transition metadata ([6668573](https://github.com/crvouga/atlas/commit/666857395a702b7fc3319d7a31e90caaa060e8e9))
8
+
3
9
  ## 0.8.0 (2026-10-15)
4
10
 
5
11
  ### Features
@@ -2,6 +2,7 @@ import { ChartGraph } from './graph.js';
2
2
  import { composeCharts } from './spec/compose.js';
3
3
  import { invokesOf, walkStates } from './spec/types.js';
4
4
  const STATE_KEYS = new Set(['id', 'initial', 'type', 'meta', 'states', 'on', 'invoke', 'description']);
5
+ const TRANSITION_KEYS = new Set(['target', 'meta']);
5
6
  const INVOKE_KEYS = new Set(['src', 'id', 'onDone']);
6
7
  const REQUIRED_META = ['description'];
7
8
  const FORBIDDEN = ['entry', 'exit', 'actions', 'assign', 'after', 'always', 'context', 'guard', 'cond', 'delay', 'output', 'onError'];
@@ -26,7 +27,7 @@ function checkShape(node, name, requiredMeta, out) {
26
27
  continue;
27
28
  }
28
29
  for (const key of Object.keys(t)) {
29
- if (key !== 'target')
30
+ if (!TRANSITION_KEYS.has(key))
30
31
  out.push({ rule: 'pure', message: `${name} --${event}-->: "${key}" is not allowed (no guards, no actions)` });
31
32
  }
32
33
  }
@@ -47,7 +48,10 @@ function sanitized(bundle) {
47
48
  if (STATE_KEYS.has(key))
48
49
  out[key] = value;
49
50
  if (node.on) {
50
- out['on'] = Object.fromEntries(Object.entries(node.on).map(([event, t]) => [event, typeof t === 'string' ? t : { target: t.target }]));
51
+ out['on'] = Object.fromEntries(Object.entries(node.on).map(([event, t]) => [
52
+ event,
53
+ typeof t === 'string' ? t : { target: t.target, ...('meta' in t ? { meta: t.meta } : {}) }
54
+ ]));
51
55
  }
52
56
  if (node.states)
53
57
  out['states'] = Object.fromEntries(Object.entries(node.states).map(([k, v]) => [k, clean(v)]));
@@ -18,7 +18,10 @@
18
18
  */
19
19
  /** The object form of a transition. `target` is a state name, optionally prefixed with `#` (a reference by name across the composed product). */
20
20
  export type TransitionConfig = {
21
+ /** The destination state, optionally prefixed with `#`. */
21
22
  target: string;
23
+ /** Declarative provenance or business metadata; ignored while executing the chart. */
24
+ meta?: Record<string, unknown>;
22
25
  };
23
26
  /** An `invoke` that runs another chart inside a state. It is never executed: `composeCharts` inlines the child chart statically. */
24
27
  export type InvokeConfig = {
@@ -84,7 +87,7 @@ export type StateConfig = {
84
87
  type?: 'parallel' | 'final';
85
88
  meta?: StateMeta;
86
89
  states?: Record<string, StateConfig>;
87
- /** Event name (exact business wording) to its transition: a target string or `{ target }`. */
90
+ /** Event name (exact business wording) to its transition: a target string or `{ target, meta? }`. */
88
91
  on?: Record<string, TransitionConfig | string>;
89
92
  /** Child chart(s) that run inside this state. */
90
93
  invoke?: InvokeConfig | InvokeConfig[];
@@ -144,9 +144,10 @@ export declare const StateMetaSchema: z.ZodObject<{
144
144
  }, z.core.$strip>;
145
145
  /** A parsed `StateMetaSchema` value. */
146
146
  export type StateMeta = z.infer<typeof StateMetaSchema>;
147
- /** The target of an event transition: a state name (or `#id`) written as a string, or an object with `target`. */
147
+ /** The target of an event transition: a state name (or `#id`) written as a string, or an object with `target` and optional declarative `meta`. */
148
148
  export declare const TransitionTargetSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
149
149
  target: z.ZodString;
150
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
150
151
  }, z.core.$strip>]>;
151
152
  /** Kinds of state in the composed map: `atomic`, `compound`, `parallel`, `final`. */
152
153
  export declare const STATE_TYPES: readonly ["atomic", "compound", "parallel", "final"];
@@ -73,10 +73,13 @@ export const StateMetaShape = {
73
73
  };
74
74
  /** `StateMetaShape` with every field optional: the `meta` of a state or of a whole chart. */
75
75
  export const StateMetaSchema = z.object(StateMetaShape).partial();
76
- /** The target of an event transition: a state name (or `#id`) written as a string, or an object with `target`. */
76
+ /** The target of an event transition: a state name (or `#id`) written as a string, or an object with `target` and optional declarative `meta`. */
77
77
  export const TransitionTargetSchema = z.union([
78
78
  z.string().min(1),
79
- z.object({ target: z.string().min(1) })
79
+ z.object({
80
+ target: z.string().min(1),
81
+ meta: z.record(z.string(), z.unknown()).optional()
82
+ })
80
83
  ]);
81
84
  /** Kinds of state in the composed map: `atomic`, `compound`, `parallel`, `final`. */
82
85
  export const STATE_TYPES = ['atomic', 'compound', 'parallel', 'final'];
@@ -2241,7 +2241,12 @@ See docs/statecharts.md
2241
2241
  #### `TransitionConfig`
2242
2242
 
2243
2243
  ```ts
2244
- export type TransitionConfig = { target: string };
2244
+ export type TransitionConfig = {
2245
+ /** The destination state, optionally prefixed with `#`. */
2246
+ target: string;
2247
+ /** Declarative provenance or business metadata; ignored while executing the chart. */
2248
+ meta?: Record<string, unknown>;
2249
+ };
2245
2250
  ```
2246
2251
 
2247
2252
  The object form of a transition. `target` is a state name, optionally prefixed with `#` (a reference by name across the composed product).
@@ -2308,7 +2313,7 @@ export type StateConfig = {
2308
2313
  type?: 'parallel' | 'final';
2309
2314
  meta?: StateMeta;
2310
2315
  states?: Record<string, StateConfig>;
2311
- /** Event name (exact business wording) to its transition: a target string or `{ target }`. */
2316
+ /** Event name (exact business wording) to its transition: a target string or `{ target, meta? }`. */
2312
2317
  on?: Record<string, TransitionConfig | string>;
2313
2318
  /** Child chart(s) that run inside this state. */
2314
2319
  invoke?: InvokeConfig | InvokeConfig[];
@@ -1613,7 +1613,7 @@ A parsed `StateMetaSchema` value.
1613
1613
  export const TransitionTargetSchema = …
1614
1614
  ```
1615
1615
 
1616
- The target of an event transition: a state name (or `#id`) written as a string, or an object with `target`.
1616
+ The target of an event transition: a state name (or `#id`) written as a string, or an object with `target` and optional declarative `meta`.
1617
1617
 
1618
1618
  #### `STATE_TYPES`
1619
1619
 
@@ -119,7 +119,8 @@ Atlas walks charts without running any code, so it executes only the parts of a
119
119
  are pure structure:
120
120
 
121
121
  - states, nesting (`initial`), `parallel` regions and `final` states;
122
- - event transitions, written as a target (`Opens: Open` or `{ target: '#Open' }`);
122
+ - event transitions, written as a target (`Opens: Open` or `{ target: '#Open' }`), with
123
+ optional declarative metadata (`{ target: '#Open', meta: { source: ['specs/door.feature'] } }`);
123
124
  - `invoke` that names another chart (`src`, `id`, `onDone`), composed statically;
124
125
  - `meta`.
125
126
 
package/llms-full.txt CHANGED
@@ -2727,7 +2727,8 @@ Atlas walks charts without running any code, so it executes only the parts of a
2727
2727
  are pure structure:
2728
2728
 
2729
2729
  - states, nesting (`initial`), `parallel` regions and `final` states;
2730
- - event transitions, written as a target (`Opens: Open` or `{ target: '#Open' }`);
2730
+ - event transitions, written as a target (`Opens: Open` or `{ target: '#Open' }`), with
2731
+ optional declarative metadata (`{ target: '#Open', meta: { source: ['specs/door.feature'] } }`);
2731
2732
  - `invoke` that names another chart (`src`, `id`, `onDone`), composed statically;
2732
2733
  - `meta`.
2733
2734
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crvouga/atlas",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Atlas: specs of any kind, reported as layered evidence. Publish checks from any runner (JUnit, CTRF, a script), combine them across nodes, branches, environments and backends, gate CI on the result, and run statecharts against the real app.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -225,6 +225,13 @@
225
225
  "target": {
226
226
  "type": "string",
227
227
  "minLength": 1
228
+ },
229
+ "meta": {
230
+ "type": "object",
231
+ "propertyNames": {
232
+ "type": "string"
233
+ },
234
+ "additionalProperties": {}
228
235
  }
229
236
  },
230
237
  "required": [