@cynodia/axiom 0.3.1-alpha.1 → 0.4.0-alpha.1

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 (2) hide show
  1. package/README.md +72 -0
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -90,6 +90,78 @@ console.log(app.getState(COUNT)); // 1
90
90
  const page = compileToHtml(graph);
91
91
  ```
92
92
 
93
+ ## Actions are transactions
94
+
95
+ This is the guarantee the framework is built around:
96
+
97
+ > An Axiom action executes as a semantic transaction. Its mutations are applied
98
+ > provisionally, the relevant constraints are evaluated against the resulting **proposed
99
+ > state**, and either the complete action commits or every one of its state mutations is
100
+ > rolled back.
101
+
102
+ That includes iteration. If an action reduces stock for twenty order lines and the
103
+ seventeenth breaks an invariant, the first sixteen do not survive — you never write
104
+ rollback logic yourself, and `runtime.getMutationLog()` shows every attempted write with
105
+ its `outcome` of `committed` or `rolled-back`.
106
+
107
+ ## Collections
108
+
109
+ Values are described by expressions, writable positions by **locations**. Collections add
110
+ projection, aggregation and ordering to the first, and iteration to the second.
111
+
112
+ ```ts
113
+ import { binary, field, filter, forEach, map, ref, sum } from '@cynodia/axiom';
114
+
115
+ // An order total: project each line to its amount, then sum the projection.
116
+ const orderTotal = sum(
117
+ map(ref(LINES), LINE, binary('multiply', field(ref(LINE), QUANTITY), field(ref(LINE), PRICE))),
118
+ );
119
+
120
+ // How much of one product this order asks for, across every line that mentions it.
121
+ const requested = sum(
122
+ map(
123
+ filter(ref(LINES), LINE, binary('eq', field(ref(LINE), PRODUCT), field(ref(P), PRODUCT_ID))),
124
+ LINE,
125
+ field(ref(LINE), QUANTITY),
126
+ ),
127
+ );
128
+
129
+ // Reduce the stock of every product the order mentions — one mutation per line, one
130
+ // transaction for the action.
131
+ const confirm = forEach(ref(LINES), LINE, [
132
+ {
133
+ kind: 'set',
134
+ target: fieldLocation(
135
+ itemLocation(stateLocation(PRODUCTS), identitySelector(PRODUCT_ID, field(ref(LINE), PRODUCT))),
136
+ STOCK,
137
+ ),
138
+ value: binary('subtract', currentStock, field(ref(LINE), QUANTITY)),
139
+ },
140
+ ]);
141
+ ```
142
+
143
+ None of this is a callback. `map`, `sort`, `filter`, `find` and `for-each` are data: they
144
+ serialize, they validate, and an agent can ask what they read and write.
145
+
146
+ ## Diagnostics
147
+
148
+ Failures are structured. Match on `code` rather than reading the message:
149
+
150
+ ```ts
151
+ import { RUNTIME_DIAGNOSTIC_CODES } from '@cynodia/axiom';
152
+
153
+ const result = app.invokeAction(CONFIRM_ORDER);
154
+ if (!result.ok) {
155
+ const stock = result.diagnostics.find(
156
+ (diagnostic) => diagnostic.code === RUNTIME_DIAGNOSTIC_CODES.PRECONDITION_FAILED,
157
+ );
158
+ console.log(stock?.details); // { preconditionIndex: 2, failureMode: 'insufficient-stock' }
159
+ }
160
+ ```
161
+
162
+ `result.diagnostics` belongs to that invocation. `app.diagnostics()` keeps the history and
163
+ `app.clearDiagnostics()` empties it.
164
+
93
165
  ## What is in the box
94
166
 
95
167
  `@cynodia/axiom` re-exports the framework packages, which can also be installed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom",
3
- "version": "0.3.1-alpha.1",
3
+ "version": "0.4.0-alpha.1",
4
4
  "description": "AI-native semantic web application framework.",
5
5
  "license": "MIT",
6
6
  "author": "AskTech AS",
@@ -31,10 +31,10 @@
31
31
  }
32
32
  },
33
33
  "dependencies": {
34
- "@cynodia/axiom-core": "0.3.1-alpha.1",
35
- "@cynodia/axiom-runtime": "0.3.1-alpha.1",
36
- "@cynodia/axiom-compiler": "0.3.1-alpha.1",
37
- "@cynodia/axiom-agent-api": "0.3.1-alpha.1"
34
+ "@cynodia/axiom-core": "0.4.0-alpha.1",
35
+ "@cynodia/axiom-runtime": "0.4.0-alpha.1",
36
+ "@cynodia/axiom-compiler": "0.4.0-alpha.1",
37
+ "@cynodia/axiom-agent-api": "0.4.0-alpha.1"
38
38
  },
39
39
  "scripts": {
40
40
  "build": "tsc -b tsconfig.json"