@manifesto-ai/core 1.0.0 → 2.0.0
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 +42 -34
- package/dist/__tests__/apply.test.d.ts +2 -0
- package/dist/__tests__/apply.test.d.ts.map +1 -0
- package/dist/__tests__/apply.test.js +144 -0
- package/dist/__tests__/apply.test.js.map +1 -0
- package/dist/__tests__/jcs.test.d.ts +2 -0
- package/dist/__tests__/jcs.test.d.ts.map +1 -0
- package/dist/__tests__/jcs.test.js +45 -0
- package/dist/__tests__/jcs.test.js.map +1 -0
- package/dist/core/apply.d.ts +2 -1
- package/dist/core/apply.d.ts.map +1 -1
- package/dist/core/apply.js +96 -14
- package/dist/core/apply.js.map +1 -1
- package/dist/core/compute.d.ts +9 -9
- package/dist/core/compute.d.ts.map +1 -1
- package/dist/core/compute.js +117 -27
- package/dist/core/compute.js.map +1 -1
- package/dist/core/compute.test.js +317 -59
- package/dist/core/compute.test.js.map +1 -1
- package/dist/core/explain.d.ts.map +1 -1
- package/dist/core/explain.js +14 -10
- package/dist/core/explain.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/validate.d.ts +2 -1
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +219 -1
- package/dist/core/validate.js.map +1 -1
- package/dist/core/validate.test.js +196 -8
- package/dist/core/validate.test.js.map +1 -1
- package/dist/core/validation-utils.d.ts +20 -0
- package/dist/core/validation-utils.d.ts.map +1 -0
- package/dist/core/validation-utils.js +289 -0
- package/dist/core/validation-utils.js.map +1 -0
- package/dist/errors.d.ts +7 -7
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/evaluator/computed.d.ts.map +1 -1
- package/dist/evaluator/computed.js +7 -4
- package/dist/evaluator/computed.js.map +1 -1
- package/dist/evaluator/context.d.ts +14 -1
- package/dist/evaluator/context.d.ts.map +1 -1
- package/dist/evaluator/context.js +7 -1
- package/dist/evaluator/context.js.map +1 -1
- package/dist/evaluator/expr.d.ts.map +1 -1
- package/dist/evaluator/expr.js +155 -4
- package/dist/evaluator/expr.js.map +1 -1
- package/dist/evaluator/expr.test.js +27 -4
- package/dist/evaluator/expr.test.js.map +1 -1
- package/dist/evaluator/flow.d.ts +1 -0
- package/dist/evaluator/flow.d.ts.map +1 -1
- package/dist/evaluator/flow.js +189 -33
- package/dist/evaluator/flow.js.map +1 -1
- package/dist/evaluator/flow.test.js +59 -6
- package/dist/evaluator/flow.test.js.map +1 -1
- package/dist/factories.d.ts +4 -2
- package/dist/factories.d.ts.map +1 -1
- package/dist/factories.js +20 -19
- package/dist/factories.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +1 -0
- package/dist/index.test.js.map +1 -1
- package/dist/schema/domain.d.ts +4 -0
- package/dist/schema/domain.d.ts.map +1 -1
- package/dist/schema/domain.js +6 -0
- package/dist/schema/domain.js.map +1 -1
- package/dist/schema/expr.d.ts +64 -21
- package/dist/schema/expr.d.ts.map +1 -1
- package/dist/schema/expr.js +40 -4
- package/dist/schema/expr.js.map +1 -1
- package/dist/schema/flow.d.ts +1 -1
- package/dist/schema/host-context.d.ts +12 -0
- package/dist/schema/host-context.d.ts.map +1 -0
- package/dist/schema/host-context.js +23 -0
- package/dist/schema/host-context.js.map +1 -0
- package/dist/schema/index.d.ts +2 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/result.d.ts +12 -0
- package/dist/schema/result.d.ts.map +1 -1
- package/dist/schema/result.js +5 -1
- package/dist/schema/result.js.map +1 -1
- package/dist/schema/snapshot.d.ts +2 -0
- package/dist/schema/snapshot.d.ts.map +1 -1
- package/dist/schema/snapshot.js +4 -0
- package/dist/schema/snapshot.js.map +1 -1
- package/dist/schema/trace.d.ts +13 -2
- package/dist/schema/trace.d.ts.map +1 -1
- package/dist/schema/trace.js +14 -3
- package/dist/schema/trace.js.map +1 -1
- package/dist/schema/type-spec.d.ts +34 -0
- package/dist/schema/type-spec.d.ts.map +1 -0
- package/dist/schema/type-spec.js +40 -0
- package/dist/schema/type-spec.js.map +1 -0
- package/dist/utils/canonical.d.ts +8 -0
- package/dist/utils/canonical.d.ts.map +1 -1
- package/dist/utils/canonical.js +66 -0
- package/dist/utils/canonical.js.map +1 -1
- package/dist/utils/canonical.test.js +31 -1
- package/dist/utils/canonical.test.js.map +1 -1
- package/dist/utils/hash.d.ts +13 -1
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/utils/hash.js +124 -2
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/hash.test.js +55 -20
- package/dist/utils/hash.test.js.map +1 -1
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@ Core is responsible for evaluating domain semantics. Given a schema, snapshot, a
|
|
|
11
11
|
In the Manifesto architecture:
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
Host
|
|
15
|
-
|
|
14
|
+
Host -> CORE -> ComputeResult
|
|
15
|
+
|
|
|
16
16
|
Computes patches & effects
|
|
17
17
|
(pure, no IO, deterministic)
|
|
18
18
|
```
|
|
@@ -38,7 +38,7 @@ Host ──→ CORE ──→ ComputeResult
|
|
|
38
38
|
| Perform IO (network, filesystem) | Host |
|
|
39
39
|
| Persist snapshots | Host |
|
|
40
40
|
| Govern authority/proposals | World |
|
|
41
|
-
| Handle UI bindings |
|
|
41
|
+
| Handle UI/event bindings | App |
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -61,35 +61,55 @@ import type { DomainSchema } from "@manifesto-ai/core";
|
|
|
61
61
|
// Create core instance
|
|
62
62
|
const core = createCore();
|
|
63
63
|
|
|
64
|
-
// Define a simple schema (
|
|
64
|
+
// Define a simple schema (provided by App or authored manually)
|
|
65
65
|
const schema: DomainSchema = {
|
|
66
|
+
id: "example:counter",
|
|
66
67
|
version: "1.0.0",
|
|
68
|
+
hash: "example-hash",
|
|
69
|
+
types: {},
|
|
67
70
|
state: {
|
|
68
|
-
|
|
71
|
+
fields: {
|
|
72
|
+
count: { type: "number", required: true, default: 0 },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
computed: {
|
|
76
|
+
fields: {
|
|
77
|
+
"computed.count": {
|
|
78
|
+
deps: ["count"],
|
|
79
|
+
expr: { kind: "get", path: "count" },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
69
82
|
},
|
|
70
83
|
actions: {
|
|
71
84
|
increment: {
|
|
72
85
|
flow: {
|
|
73
86
|
kind: "patch",
|
|
74
87
|
op: "set",
|
|
75
|
-
path: "
|
|
76
|
-
value: {
|
|
88
|
+
path: "count",
|
|
89
|
+
value: {
|
|
90
|
+
kind: "add",
|
|
91
|
+
left: { kind: "get", path: "count" },
|
|
92
|
+
right: { kind: "lit", value: 1 },
|
|
93
|
+
},
|
|
77
94
|
},
|
|
78
95
|
},
|
|
79
96
|
},
|
|
80
97
|
};
|
|
81
98
|
|
|
99
|
+
// Create host context (deterministic inputs)
|
|
100
|
+
const context = { now: 0, randomSeed: "seed" };
|
|
101
|
+
|
|
82
102
|
// Create initial snapshot
|
|
83
|
-
const snapshot = createSnapshot(schema);
|
|
103
|
+
const snapshot = createSnapshot({ count: 0 }, schema.hash, context);
|
|
84
104
|
|
|
85
105
|
// Create intent
|
|
86
|
-
const intent = createIntent("increment");
|
|
106
|
+
const intent = createIntent("increment", "intent-1");
|
|
87
107
|
|
|
88
108
|
// Compute result (pure, deterministic)
|
|
89
|
-
const result = await core.compute(schema, snapshot, intent);
|
|
109
|
+
const result = await core.compute(schema, snapshot, intent, context);
|
|
90
110
|
|
|
91
|
-
console.log(result.status); //
|
|
92
|
-
console.log(result.snapshot.data.count); //
|
|
111
|
+
console.log(result.status); // -> "complete"
|
|
112
|
+
console.log(result.snapshot.data.count); // -> 1
|
|
93
113
|
```
|
|
94
114
|
|
|
95
115
|
> See [GUIDE.md](../../docs/packages/core/GUIDE.md) for the full tutorial.
|
|
@@ -106,18 +126,18 @@ function createCore(): ManifestoCore;
|
|
|
106
126
|
|
|
107
127
|
// Core interface
|
|
108
128
|
interface ManifestoCore {
|
|
109
|
-
compute(schema, snapshot, intent): Promise<ComputeResult>;
|
|
110
|
-
apply(schema, snapshot, patches): Snapshot;
|
|
129
|
+
compute(schema, snapshot, intent, context): Promise<ComputeResult>;
|
|
130
|
+
apply(schema, snapshot, patches, context): Snapshot;
|
|
111
131
|
validate(schema): ValidationResult;
|
|
112
132
|
explain(schema, snapshot, path): ExplainResult;
|
|
113
133
|
}
|
|
114
134
|
|
|
115
135
|
// Key types
|
|
116
|
-
type DomainSchema = { version, state, computed
|
|
136
|
+
type DomainSchema = { id, version, hash, types, state, computed, actions, meta? };
|
|
117
137
|
type Snapshot = { data, computed, system, input, meta };
|
|
118
138
|
type Intent = { type, input?, intentId };
|
|
119
139
|
type Patch = { op: "set" | "unset" | "merge", path, value? };
|
|
120
|
-
type ComputeResult = { status, snapshot,
|
|
140
|
+
type ComputeResult = { status, snapshot, requirements, trace };
|
|
121
141
|
```
|
|
122
142
|
|
|
123
143
|
> See [SPEC.md](../../docs/packages/core/SPEC.md) for complete API reference.
|
|
@@ -146,25 +166,13 @@ When an action needs IO (API call, timer, etc.), Core doesn't execute it. Instea
|
|
|
146
166
|
## Relationship with Other Packages
|
|
147
167
|
|
|
148
168
|
```
|
|
149
|
-
|
|
150
|
-
│ Host │ ← Uses Core to compute
|
|
151
|
-
└──────┬──────┘
|
|
152
|
-
│
|
|
153
|
-
▼
|
|
154
|
-
┌─────────────┐
|
|
155
|
-
│ CORE │
|
|
156
|
-
└─────────────┘
|
|
157
|
-
▲
|
|
158
|
-
│
|
|
159
|
-
┌─────────────┐
|
|
160
|
-
│ Builder │ ← Produces DomainSchema for Core
|
|
161
|
-
└─────────────┘
|
|
169
|
+
App/World -> Host -> Core
|
|
162
170
|
```
|
|
163
171
|
|
|
164
172
|
| Relationship | Package | How |
|
|
165
173
|
|--------------|---------|-----|
|
|
166
174
|
| Used by | `@manifesto-ai/host` | Host calls compute() and apply() |
|
|
167
|
-
| Schema from |
|
|
175
|
+
| Schema from | App | App supplies DomainSchema |
|
|
168
176
|
|
|
169
177
|
---
|
|
170
178
|
|
|
@@ -177,7 +185,7 @@ Use Core directly when:
|
|
|
177
185
|
- Testing domain logic in isolation
|
|
178
186
|
- Building developer tools (debuggers, visualizers)
|
|
179
187
|
|
|
180
|
-
For typical usage, see [`@manifesto-ai/
|
|
188
|
+
For typical usage, see [`@manifesto-ai/world`](../world/) or [`@manifesto-ai/host`](../host/).
|
|
181
189
|
|
|
182
190
|
---
|
|
183
191
|
|
|
@@ -185,9 +193,9 @@ For typical usage, see [`@manifesto-ai/react`](../react/) or [`@manifesto-ai/hos
|
|
|
185
193
|
|
|
186
194
|
| Document | Purpose |
|
|
187
195
|
|----------|---------|
|
|
188
|
-
| [GUIDE.md](
|
|
189
|
-
| [SPEC.md](
|
|
190
|
-
| [FDR.md](
|
|
196
|
+
| [GUIDE.md](docs/GUIDE.md) | Step-by-step usage guide |
|
|
197
|
+
| [SPEC-v2.0.0.md](docs/SPEC-v2.0.0.md) | Complete specification |
|
|
198
|
+
| [FDR-v2.0.0.md](docs/FDR-v2.0.0.md) | Design rationale |
|
|
191
199
|
|
|
192
200
|
---
|
|
193
201
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/apply.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { apply } from "../core/apply.js";
|
|
3
|
+
import { createSnapshot } from "../factories.js";
|
|
4
|
+
const HOST_CONTEXT = { now: 0, randomSeed: "seed" };
|
|
5
|
+
describe("apply", () => {
|
|
6
|
+
it("should surface computed evaluation errors as values", () => {
|
|
7
|
+
const schema = {
|
|
8
|
+
id: "manifesto:test",
|
|
9
|
+
version: "1.0.0",
|
|
10
|
+
hash: "test-hash",
|
|
11
|
+
types: {},
|
|
12
|
+
state: {
|
|
13
|
+
fields: {
|
|
14
|
+
dummy: { type: "string", required: true },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
computed: {
|
|
18
|
+
fields: {
|
|
19
|
+
"computed.a": {
|
|
20
|
+
expr: { kind: "get", path: "computed.b" },
|
|
21
|
+
deps: ["computed.b"],
|
|
22
|
+
},
|
|
23
|
+
"computed.b": {
|
|
24
|
+
expr: { kind: "get", path: "computed.a" },
|
|
25
|
+
deps: ["computed.a"],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
actions: {
|
|
30
|
+
noop: { flow: { kind: "halt", reason: "noop" } },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const snapshot = createSnapshot({ dummy: "initial" }, schema.hash, HOST_CONTEXT);
|
|
34
|
+
const result = apply(schema, snapshot, [{ op: "set", path: "dummy", value: "updated" }], HOST_CONTEXT);
|
|
35
|
+
expect(result.data).toEqual({ dummy: "updated" });
|
|
36
|
+
expect(result.system.status).toBe("error");
|
|
37
|
+
expect(result.system.lastError?.code).toBe("CYCLIC_DEPENDENCY");
|
|
38
|
+
expect(result.computed).toEqual({});
|
|
39
|
+
});
|
|
40
|
+
it("should record errors for unknown patch paths", () => {
|
|
41
|
+
const schema = {
|
|
42
|
+
id: "manifesto:test",
|
|
43
|
+
version: "1.0.0",
|
|
44
|
+
hash: "test-hash",
|
|
45
|
+
types: {},
|
|
46
|
+
state: {
|
|
47
|
+
fields: {
|
|
48
|
+
dummy: { type: "string", required: true },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
computed: { fields: {} },
|
|
52
|
+
actions: {
|
|
53
|
+
noop: { flow: { kind: "halt", reason: "noop" } },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const snapshot = createSnapshot({ dummy: "initial" }, schema.hash, HOST_CONTEXT);
|
|
57
|
+
const result = apply(schema, snapshot, [{ op: "set", path: "missing", value: "value" }], HOST_CONTEXT);
|
|
58
|
+
expect(result.data).toEqual({ dummy: "initial" });
|
|
59
|
+
expect(result.system.status).toBe("error");
|
|
60
|
+
expect(result.system.lastError?.code).toBe("PATH_NOT_FOUND");
|
|
61
|
+
});
|
|
62
|
+
it("should record errors for invalid patch value types", () => {
|
|
63
|
+
const schema = {
|
|
64
|
+
id: "manifesto:test",
|
|
65
|
+
version: "1.0.0",
|
|
66
|
+
hash: "test-hash",
|
|
67
|
+
types: {},
|
|
68
|
+
state: {
|
|
69
|
+
fields: {
|
|
70
|
+
dummy: { type: "string", required: true },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
computed: { fields: {} },
|
|
74
|
+
actions: {
|
|
75
|
+
noop: { flow: { kind: "halt", reason: "noop" } },
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
const snapshot = createSnapshot({ dummy: "initial" }, schema.hash, HOST_CONTEXT);
|
|
79
|
+
const result = apply(schema, snapshot, [{ op: "set", path: "dummy", value: 42 }], HOST_CONTEXT);
|
|
80
|
+
expect(result.data).toEqual({ dummy: "initial" });
|
|
81
|
+
expect(result.system.status).toBe("error");
|
|
82
|
+
expect(result.system.lastError?.code).toBe("TYPE_MISMATCH");
|
|
83
|
+
});
|
|
84
|
+
it("should ignore patches to computed and meta", () => {
|
|
85
|
+
const schema = {
|
|
86
|
+
id: "manifesto:test",
|
|
87
|
+
version: "1.0.0",
|
|
88
|
+
hash: "test-hash",
|
|
89
|
+
types: {},
|
|
90
|
+
state: {
|
|
91
|
+
fields: {
|
|
92
|
+
count: { type: "number", required: true },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
computed: {
|
|
96
|
+
fields: {
|
|
97
|
+
"computed.double": {
|
|
98
|
+
expr: {
|
|
99
|
+
kind: "mul",
|
|
100
|
+
left: { kind: "get", path: "count" },
|
|
101
|
+
right: { kind: "lit", value: 2 },
|
|
102
|
+
},
|
|
103
|
+
deps: ["count"],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
actions: {
|
|
108
|
+
noop: { flow: { kind: "halt", reason: "noop" } },
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
const snapshot = createSnapshot({ count: 2 }, schema.hash, HOST_CONTEXT);
|
|
112
|
+
const result = apply(schema, snapshot, [
|
|
113
|
+
{ op: "set", path: "computed.double", value: 999 },
|
|
114
|
+
{ op: "set", path: "meta.version", value: 999 },
|
|
115
|
+
{ op: "set", path: "count", value: 3 },
|
|
116
|
+
], HOST_CONTEXT);
|
|
117
|
+
expect(result.data).toEqual({ count: 3 });
|
|
118
|
+
expect(result.computed["computed.double"]).toBe(6);
|
|
119
|
+
expect(result.meta.version).toBe(snapshot.meta.version + 1);
|
|
120
|
+
});
|
|
121
|
+
it("should record errors for merge patches on non-object fields", () => {
|
|
122
|
+
const schema = {
|
|
123
|
+
id: "manifesto:test",
|
|
124
|
+
version: "1.0.0",
|
|
125
|
+
hash: "test-hash",
|
|
126
|
+
types: {},
|
|
127
|
+
state: {
|
|
128
|
+
fields: {
|
|
129
|
+
name: { type: "string", required: true },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
computed: { fields: {} },
|
|
133
|
+
actions: {
|
|
134
|
+
noop: { flow: { kind: "halt", reason: "noop" } },
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
const snapshot = createSnapshot({ name: "initial" }, schema.hash, HOST_CONTEXT);
|
|
138
|
+
const result = apply(schema, snapshot, [{ op: "merge", path: "name", value: { extra: "value" } }], HOST_CONTEXT);
|
|
139
|
+
expect(result.data).toEqual({ name: "initial" });
|
|
140
|
+
expect(result.system.status).toBe("error");
|
|
141
|
+
expect(result.system.lastError?.code).toBe("TYPE_MISMATCH");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=apply.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.test.js","sourceRoot":"","sources":["../../src/__tests__/apply.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcs.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/jcs.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { toJcs } from "../utils/canonical.js";
|
|
3
|
+
describe("toJcs", () => {
|
|
4
|
+
it("should serialize -0 as 0", () => {
|
|
5
|
+
expect(toJcs(-0)).toBe("0");
|
|
6
|
+
});
|
|
7
|
+
it("should use exponent form for large and small numbers", () => {
|
|
8
|
+
expect(toJcs(1e21)).toBe("1e+21");
|
|
9
|
+
expect(toJcs(1e-7)).toBe("1e-7");
|
|
10
|
+
});
|
|
11
|
+
it("should omit undefined and symbol object properties", () => {
|
|
12
|
+
const sym = Symbol("x");
|
|
13
|
+
const value = { b: 1, a: undefined, c: sym, d: null };
|
|
14
|
+
expect(toJcs(value)).toBe('{"b":1,"d":null}');
|
|
15
|
+
});
|
|
16
|
+
it("should convert non-serializable array items to null", () => {
|
|
17
|
+
const sym = Symbol("x");
|
|
18
|
+
const fn = () => { };
|
|
19
|
+
expect(toJcs([1, undefined, fn, sym, 2])).toBe("[1,null,null,null,2]");
|
|
20
|
+
});
|
|
21
|
+
it("should escape control characters in strings", () => {
|
|
22
|
+
const value = { text: "line\nbreak\tend" };
|
|
23
|
+
expect(toJcs(value)).toBe("{\"text\":\"line\\nbreak\\tend\"}");
|
|
24
|
+
});
|
|
25
|
+
it("should order keys by code point, including surrogate pairs", () => {
|
|
26
|
+
const keyA = "\uD834\uDD1E";
|
|
27
|
+
const keyB = "\uD834\uDD1F";
|
|
28
|
+
const value = {
|
|
29
|
+
[keyB]: 2,
|
|
30
|
+
a: 3,
|
|
31
|
+
[keyA]: 1,
|
|
32
|
+
};
|
|
33
|
+
const expected = `{"a":3,${JSON.stringify(keyA)}:1,${JSON.stringify(keyB)}:2}`;
|
|
34
|
+
expect(toJcs(value)).toBe(expected);
|
|
35
|
+
});
|
|
36
|
+
it("should escape quotes and backslashes", () => {
|
|
37
|
+
const value = { text: "quote\"slash\\end" };
|
|
38
|
+
expect(toJcs(value)).toBe("{\"text\":\"quote\\\"slash\\\\end\"}");
|
|
39
|
+
});
|
|
40
|
+
it("should escape null character", () => {
|
|
41
|
+
const value = { text: "nul\u0000end" };
|
|
42
|
+
expect(toJcs(value)).toBe("{\"text\":\"nul\\u0000end\"}");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=jcs.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jcs.test.js","sourceRoot":"","sources":["../../src/__tests__/jcs.test.ts"],"names":[],"mappings":"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"}
|
package/dist/core/apply.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DomainSchema } from "../schema/domain.js";
|
|
2
2
|
import type { Snapshot } from "../schema/snapshot.js";
|
|
3
3
|
import type { Patch } from "../schema/patch.js";
|
|
4
|
+
import type { HostContext } from "../schema/host-context.js";
|
|
4
5
|
/**
|
|
5
6
|
* Apply patches to a snapshot
|
|
6
7
|
*
|
|
@@ -12,5 +13,5 @@ import type { Patch } from "../schema/patch.js";
|
|
|
12
13
|
*
|
|
13
14
|
* Note: Version and timestamp are Core-owned - Host MUST NOT modify these directly.
|
|
14
15
|
*/
|
|
15
|
-
export declare function apply(schema: DomainSchema, snapshot: Snapshot, patches: readonly Patch[]): Snapshot;
|
|
16
|
+
export declare function apply(schema: DomainSchema, snapshot: Snapshot, patches: readonly Patch[], context: HostContext): Snapshot;
|
|
16
17
|
//# sourceMappingURL=apply.d.ts.map
|
package/dist/core/apply.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/core/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/core/apply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAS7D;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,SAAS,KAAK,EAAE,EACzB,OAAO,EAAE,WAAW,GACnB,QAAQ,CA+GV"}
|
package/dist/core/apply.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { setByPath, unsetByPath, mergeAtPath } from "../utils/path.js";
|
|
2
2
|
import { evaluateComputed } from "../evaluator/computed.js";
|
|
3
|
-
import { isOk } from "../schema/common.js";
|
|
3
|
+
import { isOk, isErr } from "../schema/common.js";
|
|
4
|
+
import { createError } from "../errors.js";
|
|
5
|
+
import { getFieldSpecAtPath, validateValueAgainstFieldSpec } from "./validation-utils.js";
|
|
4
6
|
/**
|
|
5
7
|
* Apply patches to a snapshot
|
|
6
8
|
*
|
|
@@ -12,41 +14,121 @@ import { isOk } from "../schema/common.js";
|
|
|
12
14
|
*
|
|
13
15
|
* Note: Version and timestamp are Core-owned - Host MUST NOT modify these directly.
|
|
14
16
|
*/
|
|
15
|
-
export function apply(schema, snapshot, patches) {
|
|
16
|
-
// 1. Apply patches to data
|
|
17
|
+
export function apply(schema, snapshot, patches, context) {
|
|
18
|
+
// 1. Apply patches to data/system/input (data is default root)
|
|
17
19
|
let newData = snapshot.data;
|
|
20
|
+
let newSystem = snapshot.system;
|
|
21
|
+
let newInput = snapshot.input;
|
|
22
|
+
const validationErrors = [];
|
|
23
|
+
const rootFields = { ...schema.state.fields };
|
|
24
|
+
if (!("$host" in rootFields)) {
|
|
25
|
+
rootFields.$host = { type: "object", required: false };
|
|
26
|
+
}
|
|
27
|
+
const rootSpec = { type: "object", required: true, fields: rootFields };
|
|
18
28
|
for (const patch of patches) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
const { root, subPath } = splitPatchPath(patch.path);
|
|
30
|
+
switch (root) {
|
|
31
|
+
case "data":
|
|
32
|
+
{
|
|
33
|
+
const fieldSpec = getFieldSpecAtPath(rootSpec, subPath);
|
|
34
|
+
if (!fieldSpec) {
|
|
35
|
+
validationErrors.push(createError("PATH_NOT_FOUND", `Unknown patch path: ${patch.path}`, snapshot.system.currentAction ?? "", patch.path, context.now, { patch }));
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (patch.op !== "unset") {
|
|
39
|
+
const result = validateValueAgainstFieldSpec(patch.value, fieldSpec, {
|
|
40
|
+
allowPartial: patch.op === "merge",
|
|
41
|
+
allowUndefined: false,
|
|
42
|
+
});
|
|
43
|
+
if (!result.ok) {
|
|
44
|
+
validationErrors.push(createError("TYPE_MISMATCH", `Invalid patch value at ${patch.path}: ${result.message ?? "type mismatch"}`, snapshot.system.currentAction ?? "", patch.path, context.now, { patch }));
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
newData = applyPatch(newData, patch, subPath);
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case "system":
|
|
52
|
+
newSystem = applyPatch(newSystem, patch, subPath);
|
|
22
53
|
break;
|
|
23
|
-
case "
|
|
24
|
-
|
|
54
|
+
case "input":
|
|
55
|
+
newInput = applyPatch(newInput, patch, subPath);
|
|
25
56
|
break;
|
|
26
|
-
case "
|
|
27
|
-
|
|
57
|
+
case "computed":
|
|
58
|
+
case "meta":
|
|
59
|
+
// Computed/meta are Core-owned; ignore external patch attempts.
|
|
28
60
|
break;
|
|
29
61
|
}
|
|
30
62
|
}
|
|
63
|
+
if (validationErrors.length > 0) {
|
|
64
|
+
const lastError = validationErrors[validationErrors.length - 1];
|
|
65
|
+
newSystem = {
|
|
66
|
+
...newSystem,
|
|
67
|
+
status: "error",
|
|
68
|
+
lastError,
|
|
69
|
+
errors: [...newSystem.errors, ...validationErrors],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
31
72
|
// 2. Create intermediate snapshot with new data
|
|
32
73
|
const intermediateSnapshot = {
|
|
33
74
|
...snapshot,
|
|
34
75
|
data: newData,
|
|
76
|
+
system: newSystem,
|
|
77
|
+
input: newInput,
|
|
35
78
|
};
|
|
36
79
|
// 3. Recompute all computed values
|
|
37
80
|
const computedResult = evaluateComputed(schema, intermediateSnapshot);
|
|
38
|
-
|
|
81
|
+
let computed = snapshot.computed;
|
|
82
|
+
if (isOk(computedResult)) {
|
|
83
|
+
computed = computedResult.value;
|
|
84
|
+
}
|
|
85
|
+
else if (isErr(computedResult)) {
|
|
86
|
+
const error = computedResult.error;
|
|
87
|
+
computed = {};
|
|
88
|
+
newSystem = {
|
|
89
|
+
...newSystem,
|
|
90
|
+
status: "error",
|
|
91
|
+
lastError: error,
|
|
92
|
+
errors: [...newSystem.errors, error],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
39
95
|
// 4. Return new snapshot with updated metadata
|
|
40
96
|
return {
|
|
41
97
|
data: newData,
|
|
42
98
|
computed,
|
|
43
|
-
system:
|
|
44
|
-
input:
|
|
99
|
+
system: newSystem,
|
|
100
|
+
input: newInput,
|
|
45
101
|
meta: {
|
|
46
102
|
...snapshot.meta,
|
|
47
103
|
version: snapshot.meta.version + 1,
|
|
48
|
-
timestamp:
|
|
104
|
+
timestamp: context.now,
|
|
105
|
+
randomSeed: context.randomSeed,
|
|
49
106
|
},
|
|
50
107
|
};
|
|
51
108
|
}
|
|
109
|
+
function splitPatchPath(path) {
|
|
110
|
+
if (path === "system" || path.startsWith("system.")) {
|
|
111
|
+
return { root: "system", subPath: path === "system" ? "" : path.slice(7) };
|
|
112
|
+
}
|
|
113
|
+
if (path === "input" || path.startsWith("input.")) {
|
|
114
|
+
return { root: "input", subPath: path === "input" ? "" : path.slice(6) };
|
|
115
|
+
}
|
|
116
|
+
if (path === "computed" || path.startsWith("computed.")) {
|
|
117
|
+
return { root: "computed", subPath: path === "computed" ? "" : path.slice(9) };
|
|
118
|
+
}
|
|
119
|
+
if (path === "meta" || path.startsWith("meta.")) {
|
|
120
|
+
return { root: "meta", subPath: path === "meta" ? "" : path.slice(5) };
|
|
121
|
+
}
|
|
122
|
+
return { root: "data", subPath: path };
|
|
123
|
+
}
|
|
124
|
+
function applyPatch(value, patch, subPath) {
|
|
125
|
+
switch (patch.op) {
|
|
126
|
+
case "set":
|
|
127
|
+
return setByPath(value, subPath, patch.value);
|
|
128
|
+
case "unset":
|
|
129
|
+
return unsetByPath(value, subPath);
|
|
130
|
+
case "merge":
|
|
131
|
+
return mergeAtPath(value, subPath, patch.value);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
52
134
|
//# sourceMappingURL=apply.js.map
|
package/dist/core/apply.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/core/apply.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/core/apply.ts"],"names":[],"mappings":"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"}
|
package/dist/core/compute.d.ts
CHANGED
|
@@ -2,16 +2,16 @@ import type { DomainSchema } from "../schema/domain.js";
|
|
|
2
2
|
import type { Snapshot } from "../schema/snapshot.js";
|
|
3
3
|
import type { Intent } from "../schema/patch.js";
|
|
4
4
|
import type { ComputeResult } from "../schema/result.js";
|
|
5
|
+
import type { HostContext } from "../schema/host-context.js";
|
|
5
6
|
/**
|
|
6
|
-
* Compute the result of dispatching an intent
|
|
7
|
+
* Compute the result of dispatching an intent (synchronous).
|
|
7
8
|
*
|
|
8
|
-
* This is the
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
* @returns ComputeResult with new snapshot, trace, and status
|
|
9
|
+
* This is the canonical computation path. Each call is independent -
|
|
10
|
+
* there is no suspended context.
|
|
11
|
+
*/
|
|
12
|
+
export declare function computeSync(schema: DomainSchema, snapshot: Snapshot, intent: Intent, context: HostContext): ComputeResult;
|
|
13
|
+
/**
|
|
14
|
+
* Compute the result of dispatching an intent (async wrapper).
|
|
15
15
|
*/
|
|
16
|
-
export declare function compute(schema: DomainSchema, snapshot: Snapshot, intent: Intent): Promise<ComputeResult>;
|
|
16
|
+
export declare function compute(schema: DomainSchema, snapshot: Snapshot, intent: Intent, context: HostContext): Promise<ComputeResult>;
|
|
17
17
|
//# sourceMappingURL=compute.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../../src/core/compute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AASxE
|
|
1
|
+
{"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../../src/core/compute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAC;AASxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACnB,aAAa,CA+Jf;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC,CAExB"}
|