@cynodia/axiom-core 0.3.1-alpha.1 → 0.4.1-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.
@@ -1,18 +1,22 @@
1
1
  import type { Expression } from './expressions.js';
2
2
  import type { NodeId } from './ids.js';
3
3
  import type { GraphEdge } from './nodes.js';
4
+ import type { AnyNode } from './types.js';
4
5
  import type { ApplicationGraph } from './graph.js';
5
6
  /** Ids a `ref` expression mentions anywhere in the tree. */
6
7
  export declare function referencedIds(expression: Expression): NodeId[];
7
8
  /**
8
- * Recomputes the structural edges implied by node definitions. Edges index semantics
9
- * that already exist in the nodes, so they are derived rather than hand maintained:
10
- * any transformation that changes a node can simply re-run this pass.
9
+ * Recomputes the structural edges implied by node definitions. Edges index semantics that
10
+ * already exist in the nodes, so they are derived rather than hand maintained — see
11
+ * `ApplicationGraph.semanticEdges()`, which keeps them current automatically.
11
12
  *
12
- * Write edges carry the fields they touch, so an agent can distinguish an action that
13
- * writes one field of a record from one that replaces the record.
14
- *
15
- * Edges added by hand (without the `derived` marker) are preserved.
13
+ * Write edges carry the fields they touch, so writing one field of a record is
14
+ * distinguishable from writing another.
15
+ */
16
+ export declare function deriveEdges(nodes: readonly AnyNode[]): GraphEdge[];
17
+ /**
18
+ * Writes the derived edges into the graph. Queries derive them on demand, so this is only
19
+ * needed to materialize edges into serialized graph data.
16
20
  */
17
21
  export declare function synchronizeEdges(graph: ApplicationGraph): GraphEdge[];
18
22
  //# sourceMappingURL=derive-edges.d.ts.map
@@ -1,4 +1,4 @@
1
- import { expressionFieldIds, walkExpression } from './expressions.js';
1
+ import { constructedFieldIds, expressionFieldIds, walkExpression } from './expressions.js';
2
2
  import { locationExpressions, locationFieldIds, locationRootStateId, locationSelectorFieldIds, } from './location.js';
3
3
  import { isUINode } from './ui.js';
4
4
  /** Ids a `ref` expression mentions anywhere in the tree. */
@@ -24,184 +24,300 @@ function entityIdsIn(type) {
24
24
  }
25
25
  }
26
26
  /**
27
- * Recomputes the structural edges implied by node definitions. Edges index semantics
28
- * that already exist in the nodes, so they are derived rather than hand maintained:
29
- * any transformation that changes a node can simply re-run this pass.
27
+ * Recomputes the structural edges implied by node definitions. Edges index semantics that
28
+ * already exist in the nodes, so they are derived rather than hand maintained — see
29
+ * `ApplicationGraph.semanticEdges()`, which keeps them current automatically.
30
30
  *
31
- * Write edges carry the fields they touch, so an agent can distinguish an action that
32
- * writes one field of a record from one that replaces the record.
33
- *
34
- * Edges added by hand (without the `derived` marker) are preserved.
31
+ * Write edges carry the fields they touch, so writing one field of a record is
32
+ * distinguishable from writing another.
35
33
  */
36
- export function synchronizeEdges(graph) {
37
- for (const edge of graph.listEdges()) {
38
- if (edge.metadata?.derived === true) {
39
- graph.removeEdge(edge.id);
40
- }
41
- }
42
- const nodes = graph.listNodes();
34
+ export function deriveEdges(nodes) {
43
35
  const known = new Set(nodes.map((node) => node.id));
44
36
  const states = new Set(nodes.filter((node) => node.kind === 'state').map((node) => node.id));
45
37
  const pending = new Map();
46
- // An iteration scope stands for an item of whatever collection its repeat reads, so a
47
- // template that shows a field of the item still reads that field of the state.
48
- const scopeStates = new Map();
38
+ // A repeat's template refers to the current item by the repeat node's own id.
39
+ const rootScope = new Map();
49
40
  for (const node of nodes) {
50
41
  if (node.kind === 'repeat') {
51
- scopeStates.set(node.id, referencedIds(node.source).filter((id) => states.has(id)));
42
+ rootScope.set(node.id, statesOf(node.source, new Map(), states));
43
+ }
44
+ }
45
+ // Which states can hold instances of an entity, including nested ones. An entity-scoped
46
+ // constraint reads its fields wherever those instances actually live.
47
+ const entities = new Map(nodes.filter((node) => node.kind === 'entity').map((node) => [node.id, node]));
48
+ const statesByEntity = new Map();
49
+ for (const node of nodes) {
50
+ if (node.kind !== 'state' || node.draft || node.derivation) {
51
+ continue;
52
+ }
53
+ for (const entityId of reachableEntities(node.valueType, entities)) {
54
+ statesByEntity.set(entityId, [...(statesByEntity.get(entityId) ?? []), node.id]);
52
55
  }
53
56
  }
54
- const resolveStates = (id) => {
55
- if (states.has(id)) {
56
- return [id];
57
+ const entityScope = (entityId) => new Map([...rootScope, [entityId, statesByEntity.get(entityId) ?? []]]);
58
+ const link = (from, to, kind, fieldIds = []) => {
59
+ if (from === to || !known.has(from) || !known.has(to)) {
60
+ return;
57
61
  }
58
- return scopeStates.get(id) ?? [];
62
+ const key = `${from}|${to}|${kind}`;
63
+ const entry = pending.get(key) ?? { from, to, kind, fieldIds: new Set() };
64
+ for (const fieldId of fieldIds) {
65
+ entry.fieldIds.add(fieldId);
66
+ }
67
+ pending.set(key, entry);
59
68
  };
60
- const linker = {
61
- statesFor: resolveStates,
62
- link(from, to, kind, fieldIds = []) {
63
- if (from === to || !known.has(from) || !known.has(to)) {
64
- return;
65
- }
66
- const key = `${from}|${to}|${kind}`;
67
- const entry = pending.get(key) ?? { from, to, kind, fieldIds: new Set() };
68
- for (const fieldId of fieldIds) {
69
- entry.fieldIds.add(fieldId);
70
- }
71
- pending.set(key, entry);
72
- },
73
- reads(from, expression, kind = 'reads') {
74
- // Attribute a field to a state only where the expression actually reads that
75
- // state's field, so "reads X.name" never over-reports.
76
- const perState = new Map();
77
- const referenced = new Set();
78
- walkExpression(expression, (node) => {
79
- if (node.kind === 'ref') {
80
- for (const stateId of resolveStates(node.targetId)) {
81
- referenced.add(stateId);
82
- }
83
- }
84
- if (node.kind === 'field' && node.source.kind === 'ref') {
85
- for (const stateId of resolveStates(node.source.targetId)) {
86
- const existing = perState.get(stateId) ?? new Set();
87
- existing.add(node.fieldId);
88
- perState.set(stateId, existing);
89
- }
90
- }
91
- });
92
- for (const id of referenced) {
93
- linker.link(from, id, kind, [...(perState.get(id) ?? [])]);
94
- }
95
- },
96
- writes(from, location, kind = 'writes', extraFields = []) {
97
- linker.link(from, locationRootStateId(location), kind, [
98
- ...locationFieldIds(location),
99
- ...extraFields,
100
- ]);
101
- // Addressing the location is itself a read of whatever the selectors consult.
102
- for (const expression of locationExpressions(location)) {
103
- linker.reads(from, expression);
104
- }
105
- const selectorFields = locationSelectorFieldIds(location);
106
- if (selectorFields.length > 0) {
107
- linker.link(from, locationRootStateId(location), 'reads', selectorFields);
108
- }
109
- },
69
+ const reads = (from, expression, scope, kind = 'reads') => {
70
+ for (const [stateId, fieldIds] of collectReads(expression, scope, states)) {
71
+ link(from, stateId, kind, [...fieldIds]);
72
+ }
73
+ };
74
+ const writes = (from, location, scope, kind = 'writes', extraFields = []) => {
75
+ link(from, locationRootStateId(location), kind, [...locationFieldIds(location), ...extraFields]);
76
+ // Addressing the location is itself a read of whatever the selectors consult.
77
+ for (const expression of locationExpressions(location)) {
78
+ reads(from, expression, scope);
79
+ }
80
+ const selectorFields = locationSelectorFieldIds(location);
81
+ if (selectorFields.length > 0) {
82
+ link(from, locationRootStateId(location), 'reads', selectorFields);
83
+ }
110
84
  };
111
85
  for (const node of nodes) {
112
86
  if (isUINode(node)) {
113
- linkUiNode(node, linker);
87
+ linkUiNode(node, { link, reads, writes, scope: rootScope, states });
114
88
  continue;
115
89
  }
116
90
  switch (node.kind) {
117
91
  case 'entity':
118
- linkEntity(node, linker);
92
+ for (const field of node.fields) {
93
+ for (const target of entityIdsIn(field.valueType)) {
94
+ link(node.id, target, 'references', [field.id]);
95
+ }
96
+ }
119
97
  break;
120
98
  case 'state':
121
- linkState(node, linker);
99
+ linkState(node, link, reads, rootScope);
122
100
  break;
123
101
  case 'action':
124
- linkAction(node, linker);
102
+ linkAction(node, { link, reads, writes, scope: rootScope, states });
125
103
  break;
126
104
  case 'constraint':
127
- linkConstraint(node, linker);
105
+ if (node.entityId) {
106
+ link(node.id, node.entityId, 'constrains', expressionFieldIds(node.expression));
107
+ }
108
+ reads(node.id, node.expression, node.entityId ? entityScope(node.entityId) : rootScope);
128
109
  break;
110
+ case 'transition-constraint': {
111
+ link(node.id, node.entityId, 'constrains', expressionFieldIds(node.expression));
112
+ const holders = statesByEntity.get(node.entityId) ?? [];
113
+ reads(node.id, node.expression, new Map([...rootScope, [node.previousScopeId, holders], [node.proposedScopeId, holders]]));
114
+ break;
115
+ }
129
116
  case 'route':
130
- linker.link(node.id, node.viewId, 'routes-to');
117
+ link(node.id, node.viewId, 'routes-to');
131
118
  break;
132
119
  default:
133
120
  }
134
121
  }
135
- for (const entry of pending.values()) {
136
- graph.addEdge(entry.from, entry.to, entry.kind, {
137
- metadata: {
138
- derived: true,
139
- ...(entry.fieldIds.size > 0 ? { fieldIds: [...entry.fieldIds] } : {}),
140
- },
141
- });
122
+ return [...pending.values()].map((entry) => ({
123
+ id: `${entry.from}:${entry.kind}:${entry.to}`,
124
+ from: entry.from,
125
+ to: entry.to,
126
+ kind: entry.kind,
127
+ metadata: {
128
+ derived: true,
129
+ ...(entry.fieldIds.size > 0 ? { fieldIds: [...entry.fieldIds] } : {}),
130
+ },
131
+ }));
132
+ }
133
+ /**
134
+ * The states an expression ultimately draws its members from. Following `field` and calls
135
+ * matters: a collection reached as `coalesce(field(ref(state), lines), [])` still comes
136
+ * from that state, and its members' fields are still reads of it.
137
+ */
138
+ function statesOf(expression, scope, states) {
139
+ switch (expression.kind) {
140
+ case 'ref': {
141
+ const bound = scope.get(expression.targetId);
142
+ if (bound) {
143
+ return [...bound];
144
+ }
145
+ return states.has(expression.targetId) ? [expression.targetId] : [];
146
+ }
147
+ case 'filter':
148
+ case 'find':
149
+ case 'sort':
150
+ case 'map':
151
+ case 'flatten':
152
+ return statesOf(expression.source, scope, states);
153
+ case 'conditional':
154
+ return [
155
+ ...new Set([
156
+ ...statesOf(expression.whenTrue, scope, states),
157
+ ...statesOf(expression.whenFalse, scope, states),
158
+ ]),
159
+ ];
160
+ case 'field':
161
+ return statesOf(expression.source, scope, states);
162
+ case 'call':
163
+ return [...new Set(expression.arguments.flatMap((argument) => statesOf(argument, scope, states)))];
164
+ default:
165
+ return [];
142
166
  }
143
- return graph.listEdges();
144
167
  }
145
- function linkEntity(entity, linker) {
146
- for (const field of entity.fields) {
147
- for (const target of entityIdsIn(field.valueType)) {
148
- linker.link(entity.id, target, 'references', [field.id]);
168
+ /** Entities reachable from a type, following entity fields as well as collections. */
169
+ function reachableEntities(type, entities, seen = new Set()) {
170
+ const found = [];
171
+ for (const entityId of entityIdsIn(type)) {
172
+ if (seen.has(entityId)) {
173
+ continue;
174
+ }
175
+ seen.add(entityId);
176
+ found.push(entityId);
177
+ for (const field of entities.get(entityId)?.fields ?? []) {
178
+ found.push(...reachableEntities(field.valueType, entities, seen));
149
179
  }
150
180
  }
181
+ return found;
182
+ }
183
+ function bind(scope, id, targets) {
184
+ const next = new Map(scope);
185
+ next.set(id, targets);
186
+ return next;
151
187
  }
152
- function linkState(state, linker) {
188
+ /**
189
+ * Reads an expression performs, as state id → fields. Iteration scopes are followed, so
190
+ * projecting a field of each member is recorded as a read of that field of the state the
191
+ * members came from.
192
+ */
193
+ function collectReads(expression, scope, states, found = new Map()) {
194
+ const record = (stateId, fieldId) => {
195
+ const entry = found.get(stateId) ?? new Set();
196
+ if (fieldId) {
197
+ entry.add(fieldId);
198
+ }
199
+ found.set(stateId, entry);
200
+ };
201
+ switch (expression.kind) {
202
+ case 'ref':
203
+ for (const stateId of statesOf(expression, scope, states)) {
204
+ record(stateId);
205
+ }
206
+ return found;
207
+ case 'field':
208
+ for (const stateId of statesOf(expression.source, scope, states)) {
209
+ record(stateId, expression.fieldId);
210
+ }
211
+ collectReads(expression.source, scope, states, found);
212
+ return found;
213
+ case 'object':
214
+ for (const entry of expression.entries) {
215
+ collectReads(entry.value, scope, states, found);
216
+ }
217
+ return found;
218
+ case 'binary':
219
+ collectReads(expression.left, scope, states, found);
220
+ collectReads(expression.right, scope, states, found);
221
+ return found;
222
+ case 'unary':
223
+ collectReads(expression.operand, scope, states, found);
224
+ return found;
225
+ case 'call':
226
+ for (const argument of expression.arguments) {
227
+ collectReads(argument, scope, states, found);
228
+ }
229
+ return found;
230
+ case 'filter':
231
+ case 'find':
232
+ case 'map':
233
+ case 'sort':
234
+ case 'every':
235
+ case 'some': {
236
+ collectReads(expression.source, scope, states, found);
237
+ const inner = bind(scope, expression.scopeId, statesOf(expression.source, scope, states));
238
+ const body = expression.kind === 'map'
239
+ ? expression.projection
240
+ : expression.kind === 'sort'
241
+ ? expression.by
242
+ : expression.predicate;
243
+ collectReads(body, inner, states, found);
244
+ return found;
245
+ }
246
+ case 'flatten':
247
+ collectReads(expression.source, scope, states, found);
248
+ return found;
249
+ case 'conditional':
250
+ collectReads(expression.condition, scope, states, found);
251
+ collectReads(expression.whenTrue, scope, states, found);
252
+ collectReads(expression.whenFalse, scope, states, found);
253
+ return found;
254
+ default:
255
+ return found;
256
+ }
257
+ }
258
+ function linkState(state, link, reads, scope) {
153
259
  for (const target of entityIdsIn(state.valueType)) {
154
- linker.link(state.id, target, 'references');
260
+ link(state.id, target, 'references');
155
261
  }
156
262
  if (state.derivation) {
157
- linker.reads(state.id, state.derivation, 'derives-from');
263
+ reads(state.id, state.derivation, scope, 'derives-from');
158
264
  }
159
265
  }
160
266
  function linkAction(action, linker) {
161
267
  for (const expression of [...(action.preconditions ?? []), ...(action.postconditions ?? [])]) {
162
- linker.reads(action.id, expression);
268
+ linker.reads(action.id, expression, linker.scope);
163
269
  }
164
- for (const operation of action.operations ?? []) {
270
+ linkOperations(action.id, action.operations ?? [], linker, linker.scope);
271
+ }
272
+ function linkOperations(actionId, operations, linker, scope) {
273
+ for (const operation of operations) {
165
274
  switch (operation.kind) {
166
275
  case 'set':
167
- linker.writes(action.id, operation.target);
168
- linker.reads(action.id, operation.value);
276
+ linker.writes(actionId, operation.target, scope);
277
+ linker.reads(actionId, operation.value, scope);
169
278
  break;
170
279
  case 'insert':
171
- // Inserting a constructed record writes every field the record declares.
172
- linker.writes(action.id, operation.target, 'writes', expressionFieldIds(operation.value));
173
- linker.reads(action.id, operation.value);
280
+ // A constructed record writes the fields it declares. Fields consulted while
281
+ // computing those values are reads, and must not be reported as writes.
282
+ linker.writes(actionId, operation.target, scope, 'writes', constructedFieldIds(operation.value));
283
+ linker.reads(actionId, operation.value, scope);
174
284
  break;
175
285
  case 'remove':
176
- linker.writes(action.id, operation.target);
286
+ linker.writes(actionId, operation.target, scope);
287
+ break;
288
+ case 'for-each': {
289
+ linker.reads(actionId, operation.collection, scope);
290
+ const inner = bind(scope, operation.scopeId, statesOf(operation.collection, scope, linker.states));
291
+ linkOperations(actionId, operation.operations, linker, inner);
177
292
  break;
293
+ }
178
294
  case 'invoke':
179
- linker.link(action.id, operation.actionId, 'depends-on');
295
+ linker.link(actionId, operation.actionId, 'depends-on');
180
296
  for (const argument of Object.values(operation.arguments ?? {})) {
181
- linker.reads(action.id, argument);
297
+ linker.reads(actionId, argument, scope);
182
298
  }
183
299
  break;
184
300
  case 'navigate':
185
301
  if (operation.routeId) {
186
- linker.link(action.id, operation.routeId, 'depends-on');
302
+ linker.link(actionId, operation.routeId, 'depends-on');
187
303
  }
188
304
  for (const argument of Object.values(operation.parameters ?? {})) {
189
- linker.reads(action.id, argument);
305
+ linker.reads(actionId, argument, scope);
190
306
  }
191
307
  break;
192
308
  case 'native':
193
309
  for (const input of Object.values(operation.inputs ?? {})) {
194
- linker.reads(action.id, input);
310
+ linker.reads(actionId, input, scope);
195
311
  }
196
312
  if (operation.resultTarget) {
197
- linker.writes(action.id, operation.resultTarget);
313
+ linker.writes(actionId, operation.resultTarget, scope);
198
314
  }
199
315
  for (const effect of operation.declaredEffects ?? []) {
200
316
  if (effect.kind === 'reads-state') {
201
- linker.link(action.id, effect.stateId, 'reads');
317
+ linker.link(actionId, effect.stateId, 'reads');
202
318
  }
203
319
  if (effect.kind === 'writes-state') {
204
- linker.link(action.id, effect.stateId, 'writes');
320
+ linker.link(actionId, effect.stateId, 'writes');
205
321
  }
206
322
  }
207
323
  break;
@@ -209,74 +325,85 @@ function linkAction(action, linker) {
209
325
  }
210
326
  }
211
327
  }
212
- function linkConstraint(constraint, linker) {
213
- if (constraint.entityId) {
214
- linker.link(constraint.id, constraint.entityId, 'constrains', expressionFieldIds(constraint.expression));
215
- }
216
- linker.reads(constraint.id, constraint.expression);
217
- }
218
328
  function linkUiNode(node, linker) {
329
+ const { link, reads, writes, scope } = linker;
219
330
  if (node.visibleWhen) {
220
- linker.reads(node.id, node.visibleWhen);
331
+ reads(node.id, node.visibleWhen, scope);
221
332
  }
222
333
  switch (node.kind) {
223
334
  case 'view':
224
335
  case 'container':
225
336
  for (const childId of node.children) {
226
- linker.link(node.id, childId, 'contains');
337
+ link(node.id, childId, 'contains');
227
338
  }
228
339
  return;
229
340
  case 'form':
230
341
  for (const childId of node.children) {
231
- linker.link(node.id, childId, 'contains');
342
+ link(node.id, childId, 'contains');
232
343
  }
233
- linker.reads(node.id, node.target);
344
+ reads(node.id, node.target, scope);
234
345
  if (node.submitActionId) {
235
- linker.link(node.id, node.submitActionId, 'invokes');
346
+ link(node.id, node.submitActionId, 'invokes');
236
347
  }
237
348
  return;
238
349
  case 'conditional':
239
350
  for (const childId of [...node.whenTrue, ...(node.whenFalse ?? [])]) {
240
- linker.link(node.id, childId, 'contains');
351
+ link(node.id, childId, 'contains');
241
352
  }
242
- linker.reads(node.id, node.condition);
353
+ reads(node.id, node.condition, scope);
243
354
  return;
244
355
  case 'repeat':
245
- linker.link(node.id, node.templateId, 'renders');
356
+ link(node.id, node.templateId, 'renders');
246
357
  if (node.emptyTemplateId) {
247
- linker.link(node.id, node.emptyTemplateId, 'renders');
358
+ link(node.id, node.emptyTemplateId, 'renders');
248
359
  }
249
- linker.reads(node.id, node.source);
360
+ reads(node.id, node.source, scope);
250
361
  return;
251
362
  case 'text':
252
363
  if (typeof node.value !== 'string') {
253
- linker.reads(node.id, node.value);
364
+ reads(node.id, node.value, scope);
254
365
  }
255
366
  return;
256
367
  case 'field-display':
257
- for (const id of referencedIds(node.source).flatMap((target) => linker.statesFor(target))) {
258
- linker.link(node.id, id, 'reads', [node.fieldId]);
368
+ for (const stateId of statesOf(node.source, scope, linker.states)) {
369
+ link(node.id, stateId, 'reads', [node.fieldId]);
259
370
  }
371
+ reads(node.id, node.source, scope);
260
372
  return;
261
373
  case 'input':
262
374
  // An input both reads and writes the location it is bound to.
263
375
  if (node.binding?.location) {
264
- linker.writes(node.id, node.binding.location, 'binds');
265
- linker.writes(node.id, node.binding.location, 'writes');
376
+ writes(node.id, node.binding.location, scope, 'binds');
377
+ writes(node.id, node.binding.location, scope, 'writes');
266
378
  }
267
379
  if (node.options) {
268
- linker.reads(node.id, node.options.source);
380
+ reads(node.id, node.options.source, scope);
269
381
  }
270
382
  return;
271
383
  case 'button':
272
- linker.link(node.id, node.actionId, 'invokes');
384
+ link(node.id, node.actionId, 'invokes');
273
385
  if (typeof node.label !== 'string') {
274
- linker.reads(node.id, node.label);
386
+ reads(node.id, node.label, scope);
275
387
  }
276
388
  for (const argument of Object.values(node.arguments ?? {})) {
277
- linker.reads(node.id, argument);
389
+ reads(node.id, argument, scope);
278
390
  }
279
391
  return;
280
392
  default:
281
393
  }
282
394
  }
395
+ /**
396
+ * Writes the derived edges into the graph. Queries derive them on demand, so this is only
397
+ * needed to materialize edges into serialized graph data.
398
+ */
399
+ export function synchronizeEdges(graph) {
400
+ for (const edge of graph.listEdges()) {
401
+ if (edge.metadata?.derived === true) {
402
+ graph.removeEdge(edge.id);
403
+ }
404
+ }
405
+ for (const edge of deriveEdges(graph.listNodes())) {
406
+ graph.addEdge(edge.from, edge.to, edge.kind, { id: edge.id, metadata: edge.metadata });
407
+ }
408
+ return graph.listEdges();
409
+ }
@@ -5,6 +5,10 @@ export interface ValidationIssue {
5
5
  nodeId?: NodeId;
6
6
  fieldId?: FieldId;
7
7
  edgeId?: EdgeId;
8
+ /** Where inside a value the problem is, such as `state_orders[2].field_lines[1]`. */
9
+ path?: string;
10
+ /** Structured context an agent can act on without parsing the message. */
11
+ details?: Record<string, unknown>;
8
12
  }
9
13
  export interface ValidationResult {
10
14
  valid: boolean;
@@ -35,5 +39,16 @@ export declare const VALIDATION_CODES: {
35
39
  readonly identityFieldMismatch: "IDENTITY_FIELD_MISMATCH";
36
40
  readonly assignmentTypeMismatch: "ASSIGNMENT_TYPE_MISMATCH";
37
41
  readonly invalidSelectorType: "INVALID_SELECTOR_TYPE";
42
+ readonly unsupportedExpression: "UNSUPPORTED_EXPRESSION";
43
+ readonly unsupportedOperation: "UNSUPPORTED_OPERATION";
44
+ readonly unsupportedConstraintScope: "UNSUPPORTED_CONSTRAINT_SCOPE";
45
+ readonly invalidAggregation: "INVALID_AGGREGATION";
46
+ readonly notACollection: "NOT_A_COLLECTION";
47
+ readonly initialValueTypeMismatch: "INITIAL_VALUE_TYPE_MISMATCH";
48
+ readonly initialValueUnknownField: "INITIAL_VALUE_UNKNOWN_FIELD";
49
+ readonly initialValueMissingRequiredField: "INITIAL_VALUE_MISSING_REQUIRED_FIELD";
50
+ readonly initialValueInvalidEntity: "INITIAL_VALUE_INVALID_ENTITY";
51
+ readonly scopeShadowing: "SCOPE_SHADOWING";
52
+ readonly scopeCollidesWithNode: "SCOPE_COLLIDES_WITH_NODE";
38
53
  };
39
54
  //# sourceMappingURL=diagnostics.d.ts.map
@@ -22,4 +22,15 @@ export const VALIDATION_CODES = {
22
22
  identityFieldMismatch: 'IDENTITY_FIELD_MISMATCH',
23
23
  assignmentTypeMismatch: 'ASSIGNMENT_TYPE_MISMATCH',
24
24
  invalidSelectorType: 'INVALID_SELECTOR_TYPE',
25
+ unsupportedExpression: 'UNSUPPORTED_EXPRESSION',
26
+ unsupportedOperation: 'UNSUPPORTED_OPERATION',
27
+ unsupportedConstraintScope: 'UNSUPPORTED_CONSTRAINT_SCOPE',
28
+ invalidAggregation: 'INVALID_AGGREGATION',
29
+ notACollection: 'NOT_A_COLLECTION',
30
+ initialValueTypeMismatch: 'INITIAL_VALUE_TYPE_MISMATCH',
31
+ initialValueUnknownField: 'INITIAL_VALUE_UNKNOWN_FIELD',
32
+ initialValueMissingRequiredField: 'INITIAL_VALUE_MISSING_REQUIRED_FIELD',
33
+ initialValueInvalidEntity: 'INITIAL_VALUE_INVALID_ENTITY',
34
+ scopeShadowing: 'SCOPE_SHADOWING',
35
+ scopeCollidesWithNode: 'SCOPE_COLLIDES_WITH_NODE',
25
36
  };