@cynodia/axiom-compiler 0.9.0-alpha.2 → 0.11.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.
package/dist/normalize.js CHANGED
@@ -162,11 +162,16 @@ export function compileToIR(graph, options = {}) {
162
162
  case 'event':
163
163
  case 'subscription':
164
164
  case 'storage':
165
+ case 'query':
166
+ case 'relationship':
167
+ case 'read-policy':
168
+ case 'migration':
165
169
  // Server-only vocabulary: no client concern ever needs to know an integration, its
166
- // operations, the events it can raise (spec §80), the live sources it subscribes to
167
- // or the object stores it reaches. A subscription in particular has no client half
168
- // at all — the browser maintains no long-lived external source — so it is absent
169
- // here rather than present and inert (spec 0.9 §62-64).
170
+ // operations, the events it can raise (spec §80), the live sources it subscribes to,
171
+ // the object stores it reaches, or — new in 0.10 — the registered queries,
172
+ // entity relationships and row-level read policies the authority executes. A client
173
+ // invokes a query by id and receives a typed page; it never sees a clause or a
174
+ // policy predicate (spec 0.10 §6, §46-49).
170
175
  delete nodes[node.id];
171
176
  break;
172
177
  case 'trigger': {
package/dist/server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { actionAuthority, actionGuards, authorityContext, expressionDefsIn, isObservable, maxContract, requiredServerContract, serverIRExpressions, serverStateClosure, stateAuthority, usesExternalIOVocabulary, usesIntegrationVocabulary, usesInvocationVocabulary, usesV4Semantics, validateGraph, } from '@cynodia/axiom-core';
1
+ import { actionAuthority, actionGuards, authorityContext, expressionDefsIn, isObservable, maxContract, requiredServerContract, schemaFingerprint, stripAuthoringMetadata, serverIRExpressions, serverStateClosure, stateAuthority, usesExternalIOVocabulary, usesIntegrationVocabulary, usesInvocationVocabulary, usesMigrationVocabulary, usesQueryVocabulary, usesV4Semantics, validateGraph, } from '@cynodia/axiom-core';
2
2
  import { GraphValidationError } from './normalize.js';
3
3
  /**
4
4
  * Compiles the authoritative half of a graph.
@@ -30,6 +30,10 @@ export function compileToServerIR(graph, options = {}) {
30
30
  const events = [];
31
31
  const subscriptions = [];
32
32
  const storages = [];
33
+ const queries = [];
34
+ const relationships = [];
35
+ const readPolicies = [];
36
+ const migrations = [];
33
37
  for (const node of nodes) {
34
38
  if (node.kind === 'entity') {
35
39
  entities.push(node);
@@ -61,6 +65,30 @@ export function compileToServerIR(graph, options = {}) {
61
65
  else if (node.kind === 'storage') {
62
66
  storages.push(node);
63
67
  }
68
+ else if (node.kind === 'query') {
69
+ // A query reads authoritative data, so it is executed on the authority and nowhere
70
+ // else. The client invokes it by id (spec 0.10 §6); it never receives the clauses.
71
+ queries.push(node);
72
+ }
73
+ else if (node.kind === 'relationship') {
74
+ relationships.push(node);
75
+ }
76
+ else if (node.kind === 'read-policy') {
77
+ readPolicies.push(node);
78
+ }
79
+ else if (node.kind === 'migration') {
80
+ // A migration is authority-side by construction: only the authoritative runtime
81
+ // executes a schema evolution, and only against persisted canonical data (spec11
82
+ // §73). It never reaches a client. Authoring markers on the migration or its
83
+ // operations are stripped like any other trust-boundary payload.
84
+ migrations.push({
85
+ ...stripAuthoringMetadata(node),
86
+ operations: node.operations.map((operation) => stripAuthoringMetadata(operation)),
87
+ ...(node.reverseOperations
88
+ ? { reverseOperations: node.reverseOperations.map((operation) => stripAuthoringMetadata(operation)) }
89
+ : {}),
90
+ });
91
+ }
64
92
  }
65
93
  const states = [];
66
94
  const observableStateIds = [];
@@ -104,10 +132,25 @@ export function compileToServerIR(graph, options = {}) {
104
132
  for (const entry of graph.listFields()) {
105
133
  fields[entry.field.id] = entry;
106
134
  }
135
+ // Schema-evolution vocabulary is emitted only when the document actually uses it — a
136
+ // migration node, or a schemaVersion past the default 1. A plain graph compiles to the
137
+ // byte-identical pre-v7 document it always did, so the frozen v1–v6 contracts and their
138
+ // conformance fixtures are untouched (spec11 §87).
139
+ const emitSchemaEvolution = usesMigrationVocabulary({
140
+ migrations,
141
+ schemaVersion: graph.schemaVersion,
142
+ });
107
143
  const rules = {
108
144
  id: graph.id,
109
145
  name: graph.name,
110
146
  version: graph.version,
147
+ ...(emitSchemaEvolution
148
+ ? {
149
+ schemaVersion: graph.schemaVersion,
150
+ schemaFingerprint: schemaFingerprint(graph),
151
+ ...(migrations.length > 0 ? { migrations } : {}),
152
+ }
153
+ : {}),
111
154
  entities,
112
155
  fields,
113
156
  states,
@@ -122,6 +165,9 @@ export function compileToServerIR(graph, options = {}) {
122
165
  ...(triggers.length > 0 ? { triggers } : {}),
123
166
  ...(subscriptions.length > 0 ? { subscriptions } : {}),
124
167
  ...(storages.length > 0 ? { storages } : {}),
168
+ ...(queries.length > 0 ? { queries } : {}),
169
+ ...(relationships.length > 0 ? { relationships } : {}),
170
+ ...(readPolicies.length > 0 ? { readPolicies } : {}),
125
171
  };
126
172
  // Only the definitions the authority's own rules reach. A calculation used by the client
127
173
  // alone decides nothing here, and the Server IR carries nothing that decides nothing.
@@ -151,6 +197,8 @@ export function compileToServerIR(graph, options = {}) {
151
197
  usesIntegrationVocabulary(document) ? 'axiom.server.v3' : 'axiom.server.v1',
152
198
  usesV4Semantics(document) ? 'axiom.server.v4' : 'axiom.server.v1',
153
199
  usesExternalIOVocabulary(document) ? 'axiom.server.v5' : 'axiom.server.v1',
200
+ usesQueryVocabulary(document) ? 'axiom.server.v6' : 'axiom.server.v1',
201
+ usesMigrationVocabulary(document) ? 'axiom.server.v7' : 'axiom.server.v1',
154
202
  ];
155
203
  const contract = contractCandidates.reduce(maxContract);
156
204
  return { contract, ...document };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom-compiler",
3
- "version": "0.9.0-alpha.2",
3
+ "version": "0.11.0-alpha.1",
4
4
  "description": "Normalizes an Axiom application graph and emits a self-contained page.",
5
5
  "license": "MIT",
6
6
  "author": "AskTech AS",
@@ -31,8 +31,8 @@
31
31
  }
32
32
  },
33
33
  "dependencies": {
34
- "@cynodia/axiom-core": "0.9.0-alpha.2",
35
- "@cynodia/axiom-runtime": "0.9.0-alpha.2"
34
+ "@cynodia/axiom-core": "0.11.0-alpha.1",
35
+ "@cynodia/axiom-runtime": "0.11.0-alpha.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc -b tsconfig.json tsconfig.test.json",