@cynodia/axiom-runtime 0.6.1-alpha.1 → 0.6.2-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.
@@ -6,14 +6,52 @@
6
6
  * stripped from that bundle. Keeping these local also means the gateway pulls in nothing
7
7
  * else at all.
8
8
  */
9
+ /**
10
+ * Structurally identical to `NodeId` in `@cynodia/axiom-core`, and it must stay that way:
11
+ * the brand exists only at compile time, so declaring the same shape here makes the two the
12
+ * same type without an import the browser bundle cannot carry.
13
+ * `packages/runtime/test/host.test.ts` fails if the two declarations drift apart.
14
+ */
9
15
  export type NodeId = string & {
10
- readonly __brand?: 'NodeId';
16
+ readonly __brand: 'NodeId';
11
17
  };
12
18
  export interface RuntimeDiagnostic {
19
+ /**
20
+ * A code from `RUNTIME_DIAGNOSTIC_CODES` or `SERVER_DIAGNOSTIC_CODES`, but typed as a
21
+ * string here on purpose: a diagnostic arriving over the wire is untrusted input, and a
22
+ * gateway cannot promise it is one of ours. Match on it; do not switch exhaustively.
23
+ */
13
24
  code: string;
14
25
  message: string;
15
26
  severity: 'error' | 'warning';
16
27
  details?: Record<string, unknown>;
17
- [key: string]: unknown;
28
+ nodeId?: NodeId;
29
+ actionId?: NodeId;
30
+ constraintId?: NodeId;
31
+ stateId?: NodeId;
32
+ transactionId?: string;
33
+ }
34
+ /**
35
+ * How a client runtime reaches an authority.
36
+ *
37
+ * It lives here, beside the browser-safe gateway, rather than in `runtime.ts`, so that the
38
+ * gateway a page is given and the gateway the runtime accepts are the **same type**. When
39
+ * they were declared separately, `createHttpRemoteGateway()` did not typecheck as one and
40
+ * every consumer needed a cast — for a value the framework hands them itself.
41
+ */
42
+ export interface RemoteGateway {
43
+ invoke(request: {
44
+ actionId: NodeId;
45
+ arguments: Record<string, unknown>;
46
+ requestId: string;
47
+ }): Promise<{
48
+ ok: boolean;
49
+ diagnostics: RuntimeDiagnostic[];
50
+ changes: Record<NodeId, unknown>;
51
+ }>;
52
+ /** The authoritative values of every observable state. */
53
+ snapshot?(): Promise<{
54
+ states: Record<NodeId, unknown>;
55
+ }>;
18
56
  }
19
57
  //# sourceMappingURL=runtime-types.d.ts.map
package/dist/runtime.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { RemoteGateway } from './runtime-types.js';
1
2
  import type { ApplicationIR, CompiledRoute, Expression, FieldId, Location, NodeId } from '@cynodia/axiom-core';
2
3
  import type { DomElement, HostEnvironment } from './dom.js';
3
4
  import type { MutationLogEntry } from './mutation/mutation-engine.js';
@@ -72,21 +73,7 @@ export interface ActionResult {
72
73
  * is dispatched and answered later, so `invokeAction` returns `pending` and the outcome
73
74
  * arrives through the same diagnostic lifecycle a local refusal uses.
74
75
  */
75
- export interface RemoteGateway {
76
- invoke(request: {
77
- actionId: NodeId;
78
- arguments: Record<string, unknown>;
79
- requestId: string;
80
- }): Promise<{
81
- ok: boolean;
82
- diagnostics: RuntimeDiagnostic[];
83
- changes: Record<NodeId, unknown>;
84
- }>;
85
- /** The authoritative values of every observable state. */
86
- snapshot?(): Promise<{
87
- states: Record<NodeId, unknown>;
88
- }>;
89
- }
76
+ export type { RemoteGateway } from './runtime-types.js';
90
77
  /**
91
78
  * The outcome of an action's most recent invocation.
92
79
  *
package/dist/runtime.js CHANGED
@@ -1045,10 +1045,14 @@ export function createAxiomRuntime(options) {
1045
1045
  .invoke({ actionId: action.id, arguments: args, requestId })
1046
1046
  .then((answer) => {
1047
1047
  applyAuthoritative(answer.changes ?? {});
1048
- answer.diagnostics.forEach(report);
1049
- recordOutcome(action.id, answer.ok ? 'ok' : 'failed', answer.ok ? [] : answer.diagnostics);
1048
+ // A diagnostic from an authority is untrusted input: its `code` is a string until it
1049
+ // matches something we know. It is carried through unchanged, because a client that
1050
+ // rewrote a refusal would be inventing one.
1051
+ const reported = answer.diagnostics;
1052
+ reported.forEach(report);
1053
+ recordOutcome(action.id, answer.ok ? 'ok' : 'failed', answer.ok ? [] : reported);
1050
1054
  renderApplication();
1051
- return { ok: answer.ok, diagnostics: answer.diagnostics };
1055
+ return { ok: answer.ok, diagnostics: reported };
1052
1056
  })
1053
1057
  .catch((error) => {
1054
1058
  // A transport failure becomes a structured diagnostic, not an escaping exception.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom-runtime",
3
- "version": "0.6.1-alpha.1",
3
+ "version": "0.6.2-alpha.1",
4
4
  "description": "Domain-independent runtime that executes an Axiom application graph.",
5
5
  "license": "MIT",
6
6
  "author": "AskTech AS",
@@ -31,7 +31,7 @@
31
31
  }
32
32
  },
33
33
  "dependencies": {
34
- "@cynodia/axiom-core": "0.6.1-alpha.1"
34
+ "@cynodia/axiom-core": "0.6.2-alpha.1"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -b tsconfig.json tsconfig.test.json",