@cynodia/axiom 0.6.3-alpha.1 → 0.7.0-alpha.2
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/README.md +27 -4
- package/docs/ACTIONS_TRANSACTIONS.md +1 -1
- package/docs/AGENT_API.md +1 -1
- package/docs/AGENT_REFERENCE.md +78 -5
- package/docs/ANTI_PATTERNS.md +1 -1
- package/docs/AUTHORITY.md +34 -4
- package/docs/CONSTRAINTS.md +1 -1
- package/docs/EXPRESSIONS.md +64 -2
- package/docs/GRAPH_MODEL.md +2 -2
- package/docs/LOCATIONS.md +1 -1
- package/docs/PRESENTATION.md +1 -1
- package/docs/RUNTIME.md +1 -1
- package/docs/SEMANTIC_CONTRACT.md +17 -2
- package/docs/STATE.md +1 -1
- package/docs/UI.md +93 -2
- package/docs/VALIDATION.md +17 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -6,13 +6,15 @@ Axiom represents application behavior, state, UI structure and presentation as s
|
|
|
6
6
|
semantic data executed by generic runtimes. An application is a typed graph, not source
|
|
7
7
|
files: the JavaScript and HTML that reach the browser are output, and are never edited.
|
|
8
8
|
|
|
9
|
-
**Status: experimental / alpha (0.
|
|
9
|
+
**Status: experimental / alpha (0.7.0-alpha.x).** The API may change between alpha
|
|
10
10
|
releases. The documentation in `docs/` describes this exact version.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install @cynodia/axiom
|
|
15
|
+
npm install @cynodia/axiom # the graph, compiler, runtime and agent API
|
|
16
|
+
npm install @cynodia/axiom-ui # semantic UI authoring patterns (build time only)
|
|
17
|
+
npm install @cynodia/axiom-server # only if the application has an authority
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
## Canonical mental model
|
|
@@ -26,15 +28,24 @@ npm install @cynodia/axiom
|
|
|
26
28
|
| `ActionDef` | A transactional semantic operation. |
|
|
27
29
|
| `ConstraintDef` | An invariant over proposed state. |
|
|
28
30
|
| `TransitionConstraintDef` | An invariant over previous committed state → proposed state. |
|
|
29
|
-
| UI nodes | Semantic interaction structure. |
|
|
31
|
+
| UI nodes | Semantic interaction structure (view, container, text, repeat, field-display, form, input, button, conditional, diagnostic, dialog). |
|
|
30
32
|
| `Presentation` | Semantic UX intent. Roles and tokens, never CSS. |
|
|
31
33
|
| `Theme` | Translation of presentation intent into visual design. |
|
|
32
34
|
| Renderer | Platform-specific materialization. Not part of the graph. |
|
|
35
|
+
| `StateDef.authority` | Who may commit a value: the client, or the server. The one declaration the split follows from. |
|
|
36
|
+
| `ServerIR` | The half an authority executes. Portable JSON, frozen as `axiom.server.v1`. |
|
|
37
|
+
| Semantic protocol | What a client may ask for: named actions with arguments, never mutation programs. |
|
|
38
|
+
| `PersistenceAdapter` | Where a decided value survives. Not part of the semantics. |
|
|
33
39
|
|
|
34
40
|
```text
|
|
35
|
-
ApplicationGraph → validateGraph → compileToIR
|
|
41
|
+
ApplicationGraph → validateGraph → compileToIR → runtime (+ theme → renderer) → page
|
|
42
|
+
→ compileToServerIR → authority (+ persistence)
|
|
36
43
|
```
|
|
37
44
|
|
|
45
|
+
Authority is **derived, never declared twice**: an action that writes server-owned state is a
|
|
46
|
+
server action, so where code runs cannot disagree with what it does. Full model:
|
|
47
|
+
`docs/AUTHORITY.md`.
|
|
48
|
+
|
|
38
49
|
## Load-bearing invariants
|
|
39
50
|
|
|
40
51
|
Know these before authoring an application. Each is stated in full in
|
|
@@ -53,6 +64,10 @@ Know these before authoring an application. Each is stated in full in
|
|
|
53
64
|
11. **`null` and `[]` are distinct.** `null` fails a collection operator; `[]` does not. A collection is truthy only when non-empty.
|
|
54
65
|
12. **`required(x)` asks only whether a value exists.** `required([])` is `true`.
|
|
55
66
|
13. **A theme changes presentation only.**
|
|
67
|
+
14. **A client cannot commit server-authoritative state**, by any path. An action that writes it executes on the authority.
|
|
68
|
+
15. **The client is untrusted.** Guards, authorization and argument types are checked again on the authority.
|
|
69
|
+
16. **A client requests semantic actions, never mutation programs.** The protocol carries no way to send operations.
|
|
70
|
+
17. **`axiom.server.v1` is frozen and language-independent.** Its semantics are defined by `docs/AUTHORITY.md`, the published JSON Schemas and the conformance fixtures — not by this implementation.
|
|
56
71
|
|
|
57
72
|
## Minimal application
|
|
58
73
|
|
|
@@ -126,6 +141,7 @@ The complete operational contract ships with this package, in `docs/`.
|
|
|
126
141
|
| Semantic UI nodes and bindings | `docs/UI.md` |
|
|
127
142
|
| Presentation, UX intent, themes, formatting | `docs/PRESENTATION.md` |
|
|
128
143
|
| Runtime API and diagnostic codes | `docs/RUNTIME.md` |
|
|
144
|
+
| Server authority, Server IR, the protocol and persistence | `docs/AUTHORITY.md` |
|
|
129
145
|
| Machine queries and graph transformations | `docs/AGENT_API.md` |
|
|
130
146
|
| Validation codes | `docs/VALIDATION.md` |
|
|
131
147
|
| Mistakes that compile but are wrong | `docs/ANTI_PATTERNS.md` |
|
|
@@ -144,6 +160,13 @@ This package re-exports four, which can also be installed individually:
|
|
|
144
160
|
| `@cynodia/axiom-runtime` | State store, evaluation, mutation engine, constraint checking, renderer, routing. |
|
|
145
161
|
| `@cynodia/axiom-agent-api` | Semantic and presentation queries, mutation impact, transactional transformations. |
|
|
146
162
|
|
|
163
|
+
Two published packages are deliberately **not** re-exported, and are installed separately:
|
|
164
|
+
|
|
165
|
+
| Package | Why it stands apart |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| `@cynodia/axiom-server` | The authoritative runtime: Server IR execution, persistence adapters, the semantic protocol and the Node host. It imports `node:http` and `node:sqlite`, and a browser bundle must not. |
|
|
168
|
+
| `@cynodia/axiom-ui` | Semantic UI authoring patterns, expanded into ordinary graph nodes at **build time**. Re-exporting it would make every application carry an authoring dependency forever, and would make "this application no longer needs the toolkit" impossible to state or to test. |
|
|
169
|
+
|
|
147
170
|
## License
|
|
148
171
|
|
|
149
172
|
MIT
|
package/docs/AGENT_API.md
CHANGED
package/docs/AGENT_REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent reference
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. Compressed operational contract. Read this plus the `.d.ts`
|
|
4
4
|
declarations before authoring or modifying an Axiom application.
|
|
5
5
|
|
|
6
6
|
Formal guarantees: [`SEMANTIC_CONTRACT.md`](SEMANTIC_CONTRACT.md). Mistakes that compile:
|
|
@@ -31,7 +31,7 @@ One canonical term per concept. These are not interchangeable.
|
|
|
31
31
|
## Graph construction
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
|
-
const graph = new ApplicationGraph(id, name); // version defaults to '0.
|
|
34
|
+
const graph = new ApplicationGraph(id, name); // version defaults to '0.7.0'
|
|
35
35
|
graph.addNode<StateDef>({ id, kind: 'state', ... }); // returns NodeId; throws if id exists
|
|
36
36
|
graph.getNode<StateDef>(id); // deep clone, or undefined
|
|
37
37
|
graph.updateNode(node); // write a modified node back
|
|
@@ -92,7 +92,7 @@ output, and anything read back with `getState`.
|
|
|
92
92
|
|
|
93
93
|
## Expressions
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
Every kind is in `EXPRESSION_KINDS`. Full semantics: [`EXPRESSIONS.md`](EXPRESSIONS.md).
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
98
|
literal(v) ref(id) field(src, fieldId) object(entries, entityId?)
|
|
@@ -100,8 +100,12 @@ binary(op, l, r) unary(op, operand) call(fn, ...args) conditional(c, t, f)
|
|
|
100
100
|
filter(src, scopeId, predicate) find(src, scopeId, predicate)
|
|
101
101
|
map(src, scopeId, projection) sort(src, scopeId, by, direction?)
|
|
102
102
|
every(src, scopeId, predicate) some(src, scopeId, predicate) flatten(src)
|
|
103
|
+
group(src, scopeId, by) expressionRef(expressionId, args?)
|
|
103
104
|
```
|
|
104
105
|
|
|
106
|
+
- `group` partitions a collection: `Collection<A>` → `Collection<Group<K, A>>`, read with `groupKey(g)` and `groupItems(g)`. Groups appear in **first-seen key order**, members keep source order, keys compare structurally. Nothing is sorted — use `sort` for that.
|
|
107
|
+
- `expressionRef` evaluates a named `ExpressionDef` node: the calculation exists **once** in the graph and every consumer references it. Arguments are evaluated in the calling scope; **the body is evaluated in an isolated scope** that sees its parameters and application state and nothing else, so a definition means the same thing everywhere and its scope ids can never collide with a caller's.
|
|
108
|
+
|
|
105
109
|
Builtins (14): `required` `is-empty` `non-empty` `length` `contains` `concat` `coalesce`
|
|
106
110
|
`one-of` `count` `sum` `lowercase` `to-string` `now` `uuid`.
|
|
107
111
|
|
|
@@ -316,13 +320,14 @@ boolean types (`TYPE_MISMATCH`).
|
|
|
316
320
|
|
|
317
321
|
## UI nodes
|
|
318
322
|
|
|
319
|
-
|
|
320
|
-
`conditional` `diagnostic`. Detail: [`UI.md`](UI.md).
|
|
323
|
+
Every kind is in `UI_NODE_KINDS`: `view` `container` `text` `repeat` `field-display` `form`
|
|
324
|
+
`input` `button` `conditional` `diagnostic` `dialog`. Detail: [`UI.md`](UI.md).
|
|
321
325
|
|
|
322
326
|
- `RepeatNode` binds the current item to **the repeat node's own id**; the template refers to it as `ref(repeatNodeId)`.
|
|
323
327
|
- `InputNode.binding` is `{ location }` — no expression, no field id. An input write goes through the same mutation engine and transaction as an action.
|
|
324
328
|
- `ButtonNode.arguments` is keyed by **action parameter id**.
|
|
325
329
|
- `FormNode` submits either a generated button (`submitActionId` + `submitLabel`) or a declared one (`submitButtonId`), which stays an ordinary queryable node.
|
|
330
|
+
- **`DialogNode` is how you ask for confirmation in a modal**, not `ActionDef.requiresConfirmation`. The two are different things: `requiresConfirmation` delegates to the host's own confirmation — `window.confirm` in a browser — which the application cannot label, focus, style or observe. A `dialog` declares the accessible name, the content, what closes it and where focus starts and returns; the runtime performs focus movement, containment, `Escape` and the ARIA relationships. Use `requiresConfirmation` for a coarse "are you sure" with no content of its own, and a `dialog` for anything a person needs to read.
|
|
326
331
|
- `DiagnosticNode` presents why an action refused. See [Action diagnostics](#action-diagnostics).
|
|
327
332
|
- `visibleWhen` and `ConditionalNode` are interaction behavior, **not authorization**.
|
|
328
333
|
|
|
@@ -343,6 +348,30 @@ identity field and falls back to a deterministic index; nested repeats compose.
|
|
|
343
348
|
|
|
344
349
|
The graph still holds one node. `AgentAPI` reasons about that node, never about instances.
|
|
345
350
|
|
|
351
|
+
## Authoring UI: pattern, primitive, or node
|
|
352
|
+
|
|
353
|
+
Nodes are the model. They are not the only authoring surface, and choosing between the three
|
|
354
|
+
is a decision an agent should make deliberately:
|
|
355
|
+
|
|
356
|
+
| The requirement is | Use | Where |
|
|
357
|
+
| --- | --- | --- |
|
|
358
|
+
| recurring application UX that expands deterministically into existing semantics | a **pattern** | `@cynodia/axiom-ui` |
|
|
359
|
+
| interaction behaviour the runtime must perform | a **canonical interaction primitive** | `dialog`, in core |
|
|
360
|
+
| custom but already expressible | **canonical nodes**, composed | this document |
|
|
361
|
+
| genuinely unsupported presentation | `rendererOverrides.web.className`, and nothing more | [`PRESENTATION.md`](PRESENTATION.md) |
|
|
362
|
+
|
|
363
|
+
The five patterns are `page`, `metric-grid`, `entity-list`, `entity-form` and `action-bar`.
|
|
364
|
+
Expansion happens **at authoring time**: afterwards the graph is ordinary canonical Axiom, and
|
|
365
|
+
nothing at run time knows a pattern existed. Ownership defaults to the **declaration**, so
|
|
366
|
+
editing a generated node is drift, reported per node and per property; `materializePattern`
|
|
367
|
+
hands ownership to the graph when an edit is what you actually want. A pattern never creates
|
|
368
|
+
state, an action, a constraint or an authority.
|
|
369
|
+
|
|
370
|
+
Interaction behaviour is never a pattern: a pattern can only emit nodes that already exist, so
|
|
371
|
+
focus movement, containment, `Escape`, typeahead and active descendant are unreachable from one
|
|
372
|
+
— see [interaction primitives](UI.md#interaction-primitives) for the classification, including
|
|
373
|
+
`combobox`, which is classified and not implemented.
|
|
374
|
+
|
|
346
375
|
## Action diagnostics
|
|
347
376
|
|
|
348
377
|
The runtime already knows why an action refused. A `DiagnosticNode` makes that available
|
|
@@ -574,6 +603,50 @@ Boundary diagnostics: `UNKNOWN_SERVER_ACTION` `ARGUMENT_TYPE_MISMATCH` `AUTHORIZ
|
|
|
574
603
|
`CONCURRENCY_CONFLICT` `MALFORMED_REQUEST` `AUTHORITY_UNREACHABLE`, plus `SERVER_STATE_WRITE`
|
|
575
604
|
and `REMOTE_ACTION_UNAVAILABLE` on the client.
|
|
576
605
|
|
|
606
|
+
## Metadata classes
|
|
607
|
+
|
|
608
|
+
```ts
|
|
609
|
+
metadata: { [AUTHORING_METADATA_KEY]: { … }, tracked: true }
|
|
610
|
+
// ↑ stripped from every compiled artifact ↑ kept
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
Authoring metadata describes how a node was authored, never how it executes. Stripped from
|
|
614
|
+
client IR, server IR and the generated page by default; `compileToIR(graph, {
|
|
615
|
+
includeAuthoringMetadata: true })` keeps it for a tool. Nothing may branch on it at run time.
|
|
616
|
+
|
|
617
|
+
## Renderability
|
|
618
|
+
|
|
619
|
+
```ts
|
|
620
|
+
validateGraph(graph, { renderer: BROWSER_RENDERER_CAPABILITIES }); // UNSUPPORTED_UI_NODE_KIND
|
|
621
|
+
compileToIR(graph); // applies it by default
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
A UI node kind is only in the contract if a renderer implements it. A renderer publishes
|
|
625
|
+
`{ target, supportedUiKinds }` and must implement everything it publishes.
|
|
626
|
+
|
|
627
|
+
Capabilities describe **node-kind** support, not partial support: a renderer cannot yet say
|
|
628
|
+
that it draws a kind but not one of its options. Nothing in the current vocabulary needs that,
|
|
629
|
+
and it is a deliberate future extension rather than an oversight.
|
|
630
|
+
|
|
631
|
+
## Named expressions
|
|
632
|
+
|
|
633
|
+
```ts
|
|
634
|
+
graph.addNode<ExpressionDef>({
|
|
635
|
+
id: X_LOW_STOCK,
|
|
636
|
+
kind: 'expression',
|
|
637
|
+
name: 'Low stock',
|
|
638
|
+
parameters: [{ id: P_SOURCE, valueType: collectionType(entityType(E_PRODUCT)) }],
|
|
639
|
+
expression: filter(ref(P_SOURCE), SC, binary('lte', field(ref(SC), F_STOCK), ref(S_THRESHOLD))),
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
expressionRef(X_LOW_STOCK, { [P_SOURCE]: ref(S_PRODUCTS) }) // in any number of consumers
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
- **MUST** supply every declared parameter; an unsupplied one is `MISSING_EXPRESSION_ARGUMENT`.
|
|
646
|
+
- **MUST NOT** reach the caller's scope from the body. It resolves parameters and state only.
|
|
647
|
+
- A definition that reaches itself is `EXPRESSION_DEF_CYCLE`.
|
|
648
|
+
- Dependencies are graph edges: `agent.getExpressionConsumers(id)`, `agent.getExpressionDependencies(id)`, and a consumer's read edges include everything the definition reads — so an answer does not change because a calculation was given a name.
|
|
649
|
+
|
|
577
650
|
## Serialization
|
|
578
651
|
|
|
579
652
|
The whole graph, theme included, is JSON. `graph.serialize()` /
|
package/docs/ANTI_PATTERNS.md
CHANGED
package/docs/AUTHORITY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Authority
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. How an application crosses the trust boundary.
|
|
4
4
|
|
|
5
5
|
Until 0.5.x an Axiom application executed locally. 0.6 adds an **authority**: a generic
|
|
6
6
|
runtime that owns state, decides mutations and persists them. The same semantic graph
|
|
@@ -95,8 +95,10 @@ which states a client may observe. It carries **no UI, no presentation, no theme
|
|
|
95
95
|
routes**, because none of that decides anything.
|
|
96
96
|
|
|
97
97
|
It is plain JSON — deterministic, closure-free, and specific to no language or host. It
|
|
98
|
-
declares `contract
|
|
99
|
-
|
|
98
|
+
declares a `contract`, and a runtime that does not recognize the value MUST refuse it rather
|
|
99
|
+
than interpret it partially. **The declared contract is the oldest one that can carry the
|
|
100
|
+
document**, computed from the document rather than asserted: see
|
|
101
|
+
[contract identifiers](#contract-identifiers).
|
|
100
102
|
|
|
101
103
|
Guards are normalized into aligned `preconditions` / `failureModes`, exactly as in the
|
|
102
104
|
client IR, so an authority that read one and not the other cannot silently skip a check.
|
|
@@ -515,6 +517,34 @@ them.
|
|
|
515
517
|
They describe **structure**. What a conforming runtime must *do* with a valid document is this
|
|
516
518
|
page plus the conformance fixtures.
|
|
517
519
|
|
|
520
|
+
## Contract identifiers
|
|
521
|
+
|
|
522
|
+
| Contract | Adds | Since |
|
|
523
|
+
| --- | --- | --- |
|
|
524
|
+
| `axiom.server.v1` | the frozen 0.6.1 contract, below | 0.6.1 |
|
|
525
|
+
| `axiom.server.v2` | the expression kinds `group` and `expression-ref`, and the `expressionDefs` they resolve against | 0.7.0 |
|
|
526
|
+
|
|
527
|
+
`SERVER_IR_CONTRACTS` enumerates both. The rules:
|
|
528
|
+
|
|
529
|
+
- **A document declares the oldest contract that can carry it.** `compileToServerIR` computes the label from the vocabulary the document actually uses, so an application that uses nothing from 0.7 produces a byte-identical `axiom.server.v1` document, and the committed v1 conformance fixtures are unchanged.
|
|
530
|
+
- **A runtime MUST refuse a contract it does not implement**, and MUST refuse a document whose vocabulary exceeds its declared contract. A v2 runtime executing a v1-labelled document that uses `group` would accept what a conforming v1 runtime elsewhere refuses, and the two would then disagree about the same file. `createAxiomServer` raises rather than executing one.
|
|
531
|
+
- **A frozen contract gains nothing.** `axiom.server.v1` does not contain `group`, `expression-ref` or `expressionDefs`, and `server-ir.v1.schema.json` is byte-frozen. Vocabulary arrives under a new identifier or not at all.
|
|
532
|
+
|
|
533
|
+
There is one JSON Schema per contract, each generated from the runtime's own vocabulary and
|
|
534
|
+
each shipped: `server-ir.v1.schema.json`, `server-ir.v2.schema.json`.
|
|
535
|
+
|
|
536
|
+
**`group`.** Partitions a collection: `Collection<A>` → `Collection<Group<K, A>>`. Groups appear
|
|
537
|
+
in the order their key was **first seen** in the source; members keep source order; two keys are
|
|
538
|
+
the same key when they are **structurally** equal; an empty source produces no groups; a `null`
|
|
539
|
+
source fails the evaluation as every collection operator does. Nothing is sorted. A group is a
|
|
540
|
+
record carrying the two reserved field ids `field_group_key` and `field_group_items`, and no
|
|
541
|
+
entity may declare either.
|
|
542
|
+
|
|
543
|
+
**`expression-ref`.** Evaluates a named `ExpressionDef` from `expressionDefs`. Arguments are
|
|
544
|
+
evaluated in the calling scope; the body is evaluated in an **isolated** scope binding the
|
|
545
|
+
definition's parameters and application state and nothing else. Every declared parameter MUST be
|
|
546
|
+
supplied. A definition that reaches itself is invalid and MUST be refused rather than executed.
|
|
547
|
+
|
|
518
548
|
## Server IR v1 is frozen
|
|
519
549
|
|
|
520
550
|
`axiom.server.v1` is a stable semantic contract as of 0.6.1. A runtime may depend on the
|
|
@@ -568,7 +598,7 @@ result is identical to some serial order. Across processes, correctness rests on
|
|
|
568
598
|
persistence adapter's revision check — the contract guarantees that a commit from a stale
|
|
569
599
|
snapshot is refused, not that two processes coordinate.
|
|
570
600
|
|
|
571
|
-
## Not in 0.
|
|
601
|
+
## Not in 0.7.0
|
|
572
602
|
|
|
573
603
|
Stated plainly rather than left to discovery:
|
|
574
604
|
|
package/docs/CONSTRAINTS.md
CHANGED
package/docs/EXPRESSIONS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Expressions
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. An expression describes **what value is computed**. It is a tree of
|
|
4
4
|
plain data, never source text and never a callback. Evaluation is pure: an expression MUST
|
|
5
5
|
NOT change state.
|
|
6
6
|
|
|
@@ -116,7 +116,7 @@ Both branches are expressions. Only the chosen branch is evaluated.
|
|
|
116
116
|
|
|
117
117
|
### Collection operators
|
|
118
118
|
|
|
119
|
-
All
|
|
119
|
+
All seven bind the current member to `scopeId` and are strict about their source: `null`
|
|
120
120
|
fails, `[]` behaves normally.
|
|
121
121
|
|
|
122
122
|
| Builder | Input | Output | On `[]` |
|
|
@@ -127,6 +127,7 @@ fails, `[]` behaves normally.
|
|
|
127
127
|
| `sort(src, scopeId, by, direction?)` | `Collection<A>` | `Collection<A>` | `[]` |
|
|
128
128
|
| `every(src, scopeId, predicate)` | `Collection<A>` | `boolean` | **`true`** |
|
|
129
129
|
| `some(src, scopeId, predicate)` | `Collection<A>` | `boolean` | **`false`** |
|
|
130
|
+
| `group(src, scopeId, by)` | `Collection<A>` | `Collection<Group<K, A>>` | `[]` |
|
|
130
131
|
| `flatten(src)` | `Collection<Collection<A>>` | `Collection<A>` | `[]` |
|
|
131
132
|
|
|
132
133
|
- `sort` orders by the projected key, ascending unless `direction: 'desc'`. Numbers compare numerically; anything else compares as text. The sort is stable.
|
|
@@ -146,6 +147,67 @@ sum(
|
|
|
146
147
|
)
|
|
147
148
|
```
|
|
148
149
|
|
|
150
|
+
### `group(source, scopeId, by)`
|
|
151
|
+
|
|
152
|
+
Builds `{ kind: 'group', source, scopeId, by }`. Partitions a collection by a key projected
|
|
153
|
+
from each member. `Collection<A>` becomes
|
|
154
|
+
`Collection<Group<K, A>>`, where `by` is evaluated with the member bound to `scopeId` — the
|
|
155
|
+
same iteration scope every other collection operator introduces.
|
|
156
|
+
|
|
157
|
+
A group is a **record keyed by two reserved field ids**, so it is read with the ordinary
|
|
158
|
+
`field` vocabulary rather than an accessor invented for the occasion:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
group(ref(LINES), LINE, field(ref(LINE), F_CATEGORY)) // Collection<Group<string, Line>>
|
|
162
|
+
|
|
163
|
+
groupKey(ref(GROUP)) // field(ref(GROUP), GROUP_KEY_FIELD) — the shared key
|
|
164
|
+
groupItems(ref(GROUP)) // field(ref(GROUP), GROUP_ITEMS_FIELD) — the members
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**The ordering contract is part of the semantics**, not an accident of implementation:
|
|
168
|
+
|
|
169
|
+
| | |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| Group order | the order each key was **first seen** in the source |
|
|
172
|
+
| Member order within a group | source order, preserved |
|
|
173
|
+
| Key identity | structural equality, so a key may be a nested record and not only a primitive |
|
|
174
|
+
| Empty source | no groups |
|
|
175
|
+
| `null` source | fails the evaluation, like every collection operator |
|
|
176
|
+
|
|
177
|
+
Nothing is sorted. A caller that wants groups in key order says so with `sort`, which is the
|
|
178
|
+
operator whose job that is.
|
|
179
|
+
|
|
180
|
+
`GROUP_KEY_FIELD` and `GROUP_ITEMS_FIELD` are **reserved**: an entity that declares either is
|
|
181
|
+
`RESERVED_FIELD_ID`, and reading either from something that is not a group — or reading
|
|
182
|
+
anything else *from* a group — is `INVALID_GROUP_FIELD`. A field id that meant one thing in
|
|
183
|
+
one place and another elsewhere would defeat the reason ids exist.
|
|
184
|
+
|
|
185
|
+
### `expressionRef(expressionId, arguments?)`
|
|
186
|
+
|
|
187
|
+
Builds `{ kind: 'expression-ref', expressionId, arguments? }`, which evaluates a named
|
|
188
|
+
`ExpressionDef` — the reuse mechanism. Without it, an expression used in
|
|
189
|
+
three places is written three times, each needing its own scope ids.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
graph.addNode<ExpressionDef>({
|
|
193
|
+
id: LINES_IN_CATEGORY,
|
|
194
|
+
kind: 'expression',
|
|
195
|
+
parameters: [{ id: P_CATEGORY, valueType: primitiveType('string') }],
|
|
196
|
+
expression: filter(ref(STATE_LINES), LINE, binary('eq', field(ref(LINE), F_CATEGORY), ref(P_CATEGORY))),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
expressionRef(LINES_IN_CATEGORY, { [P_CATEGORY]: literal('fasteners') })
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Arguments are evaluated in the calling scope; the body is evaluated in an isolated one.**
|
|
203
|
+
The body sees its parameters and application state, and nothing else. That isolation is the
|
|
204
|
+
point: a definition reused in three places cannot pick up an iteration scope from one of
|
|
205
|
+
them, and its internal scope ids can never collide with a caller's.
|
|
206
|
+
|
|
207
|
+
Validation: `UNKNOWN_EXPRESSION_DEF` for a reference to something that is not one;
|
|
208
|
+
`EXPRESSION_DEF_CYCLE` if a definition reaches itself; `MISSING_EXPRESSION_ARGUMENT` and
|
|
209
|
+
`UNKNOWN_EXPRESSION_ARGUMENT` for arguments that do not match the declared parameters.
|
|
210
|
+
|
|
149
211
|
## Built-in functions
|
|
150
212
|
|
|
151
213
|
14 names, enumerated by `BUILTIN_FUNCTIONS`. `AGGREGATE_FUNCTIONS` lists those that reduce
|
package/docs/GRAPH_MODEL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Graph model
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. The `ApplicationGraph` is the authoritative representation of an
|
|
4
4
|
application. Everything else — the IR, the page, the DOM — is derived from it and is never
|
|
5
5
|
edited.
|
|
6
6
|
|
|
@@ -25,7 +25,7 @@ edited.
|
|
|
25
25
|
## API
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
const graph = new ApplicationGraph(id, name, version?); // version defaults to '0.
|
|
28
|
+
const graph = new ApplicationGraph(id, name, version?); // version defaults to '0.7.0'
|
|
29
29
|
|
|
30
30
|
graph.addNode<T>(node): NodeId // generates an id if omitted; throws if it exists
|
|
31
31
|
graph.getNode<T>(id): T | undefined // deep clone
|
package/docs/LOCATIONS.md
CHANGED
package/docs/PRESENTATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Presentation
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. Presentation is **semantic UX intent**, expressed as data on a UI
|
|
4
4
|
node. It names roles, tokens and device classes. It never names a colour, a length, a media
|
|
5
5
|
query or a CSS property.
|
|
6
6
|
|
package/docs/RUNTIME.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Semantic contract
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. Runtime guarantees, stated formally. This file defines behavior; it
|
|
4
4
|
does not teach. Where this file and any specification in `../specs/` disagree, this file
|
|
5
5
|
describes the implementation and is authoritative.
|
|
6
6
|
|
|
@@ -205,7 +205,7 @@ Full model: [`AUTHORITY.md`](AUTHORITY.md).
|
|
|
205
205
|
- Server IR MUST be serializable, deterministic and free of closures, and MUST declare a contract version a runtime can refuse.
|
|
206
206
|
- `axiom.server.v1` is **frozen**. Its semantics — IEEE-754 binary64 arithmetic, Unicode code-point text ordering, the deterministic host model, and the JSON serialization constraints — are normative and language-independent. An incompatible semantic change requires a new contract identifier.
|
|
207
207
|
|
|
208
|
-
**Not guaranteed in 0.
|
|
208
|
+
**Not guaranteed in 0.7.0**, and stated so rather than implied: read authorization per caller
|
|
209
209
|
or per record, binding a value generated by one operation in a later one, external side
|
|
210
210
|
effects participating in a transaction, realtime synchronization, query semantics, and
|
|
211
211
|
multi-node execution.
|
|
@@ -222,6 +222,20 @@ multi-node execution.
|
|
|
222
222
|
- Action guards MUST be evaluated in declaration order, and the first that does not hold MUST stop evaluation and be the only failure reported. Guard failures MUST NOT be aggregated.
|
|
223
223
|
- An application MUST NOT need to duplicate an action's guards, read console output, copy an `ActionResult` into its own state, or install a renderer-specific handler in order to present a refusal.
|
|
224
224
|
|
|
225
|
+
## Metadata classes
|
|
226
|
+
|
|
227
|
+
- `metadata` is free-form and travels with a node. Anything under the reserved key `AUTHORING_METADATA_KEY` is **authoring metadata**: it describes how a node was authored, never how it executes.
|
|
228
|
+
- Authoring metadata MUST be stripped from every compiled artifact — client IR, server IR, generated page — unless `includeAuthoringMetadata` is passed. Semantic metadata beside it is untouched.
|
|
229
|
+
- Nothing may branch on authoring metadata at run time. Removing it MUST change validation, compilation, presentation resolution, rendering and runtime behaviour by exactly nothing.
|
|
230
|
+
- The mechanism is generic. A UI toolkit is the first thing that needs it, not the only one.
|
|
231
|
+
|
|
232
|
+
## Renderability
|
|
233
|
+
|
|
234
|
+
- A UI node kind is part of the contract only if a renderer implements it. `validateGraph(graph, { renderer })` rejects a kind the named target cannot draw, with `UNSUPPORTED_UI_NODE_KIND`.
|
|
235
|
+
- `compileToIR` applies the browser renderer's capabilities by default, so compiling a page rejects an unrenderable node at authoring time rather than producing one that reports `UNSUPPORTED_UI_NODE` on screen.
|
|
236
|
+
- With no renderer named, every kind is accepted: a graph is not rejected for a target nobody named.
|
|
237
|
+
- A renderer publishes what it implements, and MUST implement everything it publishes.
|
|
238
|
+
|
|
225
239
|
## Render identity
|
|
226
240
|
|
|
227
241
|
- A UI node inside a `repeat` is rendered once per member. `NodeId` MUST NOT be used alone to identify a rendered element.
|
|
@@ -271,6 +285,7 @@ These are current implementation limits, not design intentions.
|
|
|
271
285
|
- Type inference is deliberately partial: it rejects obvious mismatches and stays silent where a type depends on an iteration scope.
|
|
272
286
|
- Iteration scopes are ordinary `NodeId`s; misuse is caught by validation rather than by the type system.
|
|
273
287
|
- Remote persistence is declared but not executed.
|
|
288
|
+
- A `dialog` declares what is open, its accessible name, its content, what closes it and whether it is modal. The runtime performs focus movement, focus containment, `Escape` dismissal, focus return and the ARIA relationships. Dismissing a dialog invokes its close action and infers no other meaning: closing is not cancelling.
|
|
274
289
|
- Asynchronous action semantics extend no further than a remote invocation: the outcome is `pending` until the authority answers, and the control that started it is marked busy and refuses a second press. There is no general async workflow model, no progress reporting and no cancellation.
|
|
275
290
|
- An action cannot bind a value it generated earlier in the same transaction; `uuid()` in one operation is not addressable by a later one.
|
|
276
291
|
- Change sets are in memory and per `AgentAPI` instance. There is no semantic version control and no on-disk graph format.
|
package/docs/STATE.md
CHANGED
package/docs/UI.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# UI
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. Eleven semantic UI node kinds describe **what exists and what it does**.
|
|
4
4
|
How it looks is [presentation](PRESENTATION.md).
|
|
5
5
|
|
|
6
|
-
All
|
|
6
|
+
All eleven share `UIBase`:
|
|
7
7
|
|
|
8
8
|
```ts
|
|
9
9
|
{ id, kind, name?, visibleWhen?: Expression, presentation?: Presentation, metadata? }
|
|
@@ -229,6 +229,48 @@ Lifecycle — see [`RUNTIME.md`](RUNTIME.md#action-diagnostics) for the full con
|
|
|
229
229
|
- Messages come from the structured diagnostics — `failureMode.message` for a refused guard, `ConstraintDef.message` for a broken invariant. The renderer invents no wording.
|
|
230
230
|
- The region is a live region (`role="alert"` for errors, `role="status"` for warnings) and is rendered even when empty, so later content is announced. A control invoking the same action is related to it with `aria-describedby` while it has content.
|
|
231
231
|
|
|
232
|
+
### `dialog`
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
{
|
|
236
|
+
kind: 'dialog',
|
|
237
|
+
openWhen: Expression, // true while it is open
|
|
238
|
+
title: string | Expression, // the accessible name; required
|
|
239
|
+
description?: string | Expression,
|
|
240
|
+
children: NodeId[],
|
|
241
|
+
closeActionId: NodeId, // what dismissal invokes
|
|
242
|
+
modal?: boolean, // default true
|
|
243
|
+
initialFocusId?: NodeId, // a descendant
|
|
244
|
+
returnFocusId?: NodeId, // usually whatever opened it
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Content that interrupts, together with the interaction rules that make it a dialog rather
|
|
249
|
+
than a box that appears. It is the case where composing existing nodes stops being enough:
|
|
250
|
+
visibility is expressible with a `conditional`, but focus movement, focus containment,
|
|
251
|
+
`Escape`, focus return and the announcement to assistive technology are behaviour no node
|
|
252
|
+
describes.
|
|
253
|
+
|
|
254
|
+
**The graph says what; the runtime does how.**
|
|
255
|
+
|
|
256
|
+
| The graph declares | The runtime performs |
|
|
257
|
+
| --- | --- |
|
|
258
|
+
| what is open, and what closes it | moving focus in when it opens |
|
|
259
|
+
| the accessible name and description | containing focus while it is modal |
|
|
260
|
+
| the content | dismissing on `Escape` |
|
|
261
|
+
| whether it is modal | returning focus when it closes |
|
|
262
|
+
| where focus starts and returns to | `role="dialog"`, `aria-modal`, `aria-labelledby`, `aria-describedby` |
|
|
263
|
+
|
|
264
|
+
- **Openness is ordinary state.** `openWhen` is an expression over ordinary state — usually an `ephemeral` boolean — not hidden runtime state. Opening and closing therefore go through actions and the mutation log, and are as inspectable as anything else.
|
|
265
|
+
- **A closed dialog is absent, not hidden.** Nothing inside it renders, so nothing inside it is reachable by keyboard or by assistive technology.
|
|
266
|
+
- **Dismissal is not cancellation.** `Escape` invokes `closeActionId` and nothing else. Closing a dialog does not revert, cancel or roll anything back unless that action does — the runtime never infers that it should.
|
|
267
|
+
- **Focus moves in once**, when the dialog is first rendered open, not on every re-render. A full re-render must not take focus back from wherever the person moved it.
|
|
268
|
+
- `title` MUST NOT be empty: a dialog with no accessible name is `INVALID_DIALOG`. `initialFocusId` MUST be inside the dialog and `returnFocusId` MUST NOT be, since it has to exist after the dialog is gone.
|
|
269
|
+
- Nothing here names an element, a class, a position or a stacking order. A renderer that is not a browser implements the same semantics its own way.
|
|
270
|
+
- **Verified in a real browser.** Role, accessible name, `aria-modal`, focus entry, `Tab` and `Shift+Tab` containment, `Escape`, focus return to the correct render instance, a text field inside the dialog, and the absence of a closed dialog are all asserted against Chromium, not only against the in-memory host.
|
|
271
|
+
- **Keyboard containment, not pointer containment.** A modal contains focus and announces itself as modal. It does **not** currently make the rest of the document inert, so a pointer can still reach what is behind it. Declare the rule in a guard, never in the dialog — see [visibility is not authorization](#visibility-is-not-authorization).
|
|
272
|
+
- **Focus return prefers the exact render instance that opened it**, and falls back to another instance of the same control when the action removed that row. A destructive confirmation usually deletes the row its trigger was in; dropping focus to the top of the document instead would lose a keyboard user's place.
|
|
273
|
+
|
|
232
274
|
### `conditional`
|
|
233
275
|
|
|
234
276
|
```ts
|
|
@@ -238,6 +280,55 @@ Lifecycle — see [`RUNTIME.md`](RUNTIME.md#action-diagnostics) for the full con
|
|
|
238
280
|
Renders one branch. The condition uses the truthiness rules in
|
|
239
281
|
[`EXPRESSIONS.md`](EXPRESSIONS.md#conversions) — note that `[]` is falsy.
|
|
240
282
|
|
|
283
|
+
## Interaction primitives
|
|
284
|
+
|
|
285
|
+
`dialog` is the first of a class, and the rule that puts it here rather than in a pattern
|
|
286
|
+
library is worth stating once:
|
|
287
|
+
|
|
288
|
+
> Interaction semantics that **cannot be reduced to existing canonical nodes** belong in core.
|
|
289
|
+
|
|
290
|
+
An authoring pattern can only emit nodes that already exist. So anything whose defining
|
|
291
|
+
behaviour is not a node — focus movement, containment, `Escape`, typeahead, active descendant,
|
|
292
|
+
the ARIA relationships that go with them — is unreachable from a pattern at any level of
|
|
293
|
+
cleverness, and has to be canonical semantics with runtime support.
|
|
294
|
+
|
|
295
|
+
| Candidate | Class | State |
|
|
296
|
+
| --- | --- | --- |
|
|
297
|
+
| `dialog` | canonical-semantic | implemented, browser-verified |
|
|
298
|
+
| `combobox` | canonical-semantic | **classified, not implemented** |
|
|
299
|
+
| `menu`, `tabs`, `accordion`, `tooltip`, `popover` | canonical-semantic | unexamined; each needs its own contract |
|
|
300
|
+
| focus trap, keyboard scheme, live announcement | renderer-only | reached through canonical semantics, never declared |
|
|
301
|
+
| page, metric grid, entity list, entity form, action bar | pattern-expandable | `@cynodia/axiom-ui` |
|
|
302
|
+
|
|
303
|
+
**Combobox** was probed deliberately because it looks least like a dialog: no modality, no
|
|
304
|
+
interruption, a control inside a form. It divides at the identical seam. Expressible today,
|
|
305
|
+
with no new node kind: the bound value, the option source (`InputNode.options`), option
|
|
306
|
+
identity and label, filtering, and open state — all ordinary state and expressions. Not
|
|
307
|
+
expressible at all: arrow-key navigation, active descendant, typeahead, `aria-expanded` and the
|
|
308
|
+
listbox relationships. Two primitives that share no shape dividing the same way is what makes
|
|
309
|
+
the split a rule rather than an observation about dialogs.
|
|
310
|
+
|
|
311
|
+
## Semantic UI authoring
|
|
312
|
+
|
|
313
|
+
Nodes are the model, not the authoring surface an application has to use. `@cynodia/axiom-ui`
|
|
314
|
+
adds five patterns that expand — at build time — into exactly the nodes described on this page.
|
|
315
|
+
|
|
316
|
+
**Which to reach for:**
|
|
317
|
+
|
|
318
|
+
| The requirement is | Use |
|
|
319
|
+
| --- | --- |
|
|
320
|
+
| recurring application UX that expands deterministically into existing semantics | a **pattern** (`page`, `metric-grid`, `entity-list`, `entity-form`, `action-bar`) |
|
|
321
|
+
| interaction behaviour that needs the runtime to do something | a **canonical interaction primitive** (`dialog`) |
|
|
322
|
+
| custom, but already expressible | **ordinary canonical nodes**, composed |
|
|
323
|
+
| genuinely unsupported presentation | the renderer escape (`rendererOverrides.web.className`), and nothing more |
|
|
324
|
+
|
|
325
|
+
A pattern is an authoring abstraction and nothing else: after expansion the application is an
|
|
326
|
+
ordinary Axiom application, and `validateGraph`, `compileToIR`, `AgentAPI` and the runtime know
|
|
327
|
+
nothing about patterns. Ownership defaults to the **declaration**, so editing a generated node
|
|
328
|
+
is drift rather than an edit. The contract travels with the package rather than being restated here: install
|
|
329
|
+
`@cynodia/axiom-ui` and read its `README.md`, `docs/TOOLKIT_AGENT_REFERENCE.md` and
|
|
330
|
+
`docs/PATTERN_CATALOG.json` — the last is addressable as `@cynodia/axiom-ui/catalog`.
|
|
331
|
+
|
|
241
332
|
## Containment
|
|
242
333
|
|
|
243
334
|
`uiChildIds(node)` returns a node's children in render order, for every kind:
|
package/docs/VALIDATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Validation
|
|
2
2
|
|
|
3
|
-
Axiom 0.
|
|
3
|
+
Axiom 0.7.0-alpha.2. Validation is authoring-time structural checking. It is not the same
|
|
4
4
|
as runtime constraint evaluation — see [`CONSTRAINTS.md`](CONSTRAINTS.md) for the four
|
|
5
5
|
layers of correctness.
|
|
6
6
|
|
|
@@ -80,6 +80,14 @@ non-numeric collections, and obviously incompatible assignments.
|
|
|
80
80
|
| `EPHEMERAL_STATE_PERSISTED` | `ephemeral: true` together with `persistence`. |
|
|
81
81
|
| `CLIENT_WRITE_TO_SERVER_STATE` | An input bound into server-authoritative state. See [Authority](#authority). |
|
|
82
82
|
| `MISSING_ACTION_ARGUMENT` | A control invokes an action without supplying a required parameter. |
|
|
83
|
+
| `UNSUPPORTED_UI_NODE_KIND` | A UI node kind the intended renderer cannot draw. |
|
|
84
|
+
| `INVALID_DIALOG` | A `dialog` whose declaration cannot produce a usable dialog. |
|
|
85
|
+
| `RESERVED_FIELD_ID` | An entity declaring a field id reserved for group results. |
|
|
86
|
+
| `INVALID_GROUP_FIELD` | Reading a group field from a non-group, or a non-group field from a group. |
|
|
87
|
+
| `UNKNOWN_EXPRESSION_DEF` | An `expression-ref` naming something that is not an expression definition. |
|
|
88
|
+
| `EXPRESSION_DEF_CYCLE` | An expression definition that reaches itself. |
|
|
89
|
+
| `MISSING_EXPRESSION_ARGUMENT` | An `expression-ref` that omits a declared parameter. |
|
|
90
|
+
| `UNKNOWN_EXPRESSION_ARGUMENT` | An `expression-ref` supplying a parameter the definition does not declare. |
|
|
83
91
|
|
|
84
92
|
### Initial values
|
|
85
93
|
|
|
@@ -150,6 +158,14 @@ client commit authoritative state does not compile. Full model:
|
|
|
150
158
|
| `AUTHORIZATION_WITHOUT_PRINCIPAL` | An `authorization` expression with no principal entity declared. **Also raised as a warning** when an application has server state but no action declares authorization, so every caller may invoke everything. | error / warning |
|
|
151
159
|
| `PRINCIPAL_REFERENCE_ON_CLIENT` | `PRINCIPAL` is read where a client evaluates, or an `authorization` sits on an action no authority executes. | error |
|
|
152
160
|
| `MISSING_ACTION_ARGUMENT` | A `button`, or a `form` submitting without one, invokes an action with a required parameter it never supplies. The invocation would always be refused for a missing argument, so it is refused here instead. | error |
|
|
161
|
+
| `INVALID_DIALOG` | A `dialog` with an empty title (no accessible name), an initial focus target outside itself, or a return focus target inside itself. **Also a warning** when a non-modal dialog moves focus on open. | error / warning |
|
|
162
|
+
| `RESERVED_FIELD_ID` | An entity declares `field_group_key` or `field_group_items`. Both are reserved for the records a `group` expression returns; an id meaning one thing in one place and another elsewhere would defeat the reason ids exist. | error |
|
|
163
|
+
| `INVALID_GROUP_FIELD` | A `field` expression reads a group field from a source that is statically not a group, or reads anything other than the two group fields *from* a group. Read `groupItems` first, then the member's own fields. | error |
|
|
164
|
+
| `UNKNOWN_EXPRESSION_DEF` | An `expression-ref` names a node that is not an `ExpressionDef`. | error |
|
|
165
|
+
| `EXPRESSION_DEF_CYCLE` | An expression definition reaches itself, directly or through others. The message names the cycle. | error |
|
|
166
|
+
| `MISSING_EXPRESSION_ARGUMENT` | An `expression-ref` does not supply a parameter the definition declares. | error |
|
|
167
|
+
| `UNKNOWN_EXPRESSION_ARGUMENT` | An `expression-ref` supplies an argument the definition declares no parameter for. | error |
|
|
168
|
+
| `UNSUPPORTED_UI_NODE_KIND` | The graph contains a UI node kind the target renderer does not implement. Raised only when `validateGraph` is given a `renderer`; `compileToIR` supplies the browser renderer's capabilities by default. Without it a graph could validate and then render nothing — the failure would surface as a runtime `UNSUPPORTED_UI_NODE` diagnostic instead of an authoring error. | error |
|
|
153
169
|
| `INVALID_PRINCIPAL_ENTITY` | `principalEntityId` names something that is not an entity. | error |
|
|
154
170
|
|
|
155
171
|
### Accessibility
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cynodia/axiom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-alpha.2",
|
|
4
4
|
"description": "AI-native semantic web application framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "AskTech AS",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@cynodia/axiom-core": "0.
|
|
36
|
-
"@cynodia/axiom-runtime": "0.
|
|
37
|
-
"@cynodia/axiom-compiler": "0.
|
|
38
|
-
"@cynodia/axiom-agent-api": "0.
|
|
35
|
+
"@cynodia/axiom-core": "0.7.0-alpha.2",
|
|
36
|
+
"@cynodia/axiom-runtime": "0.7.0-alpha.2",
|
|
37
|
+
"@cynodia/axiom-compiler": "0.7.0-alpha.2",
|
|
38
|
+
"@cynodia/axiom-agent-api": "0.7.0-alpha.2"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc -b tsconfig.json"
|