@manifesto-ai/core 0.3.0 → 1.3.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 +148 -498
- 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 +17 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/apply.js +130 -0
- package/dist/core/apply.js.map +1 -0
- package/dist/core/compute.d.ts +17 -0
- package/dist/core/compute.d.ts.map +1 -0
- package/dist/core/compute.js +287 -0
- package/dist/core/compute.js.map +1 -0
- package/dist/core/compute.test.d.ts +2 -0
- package/dist/core/compute.test.d.ts.map +1 -0
- package/dist/core/compute.test.js +633 -0
- package/dist/core/compute.test.js.map +1 -0
- package/dist/core/explain.d.ts +14 -0
- package/dist/core/explain.d.ts.map +1 -0
- package/dist/core/explain.js +78 -0
- package/dist/core/explain.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/validate.d.ts +16 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +361 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/validate.test.d.ts +2 -0
- package/dist/core/validate.test.d.ts.map +1 -0
- package/dist/core/validate.test.js +638 -0
- package/dist/core/validate.test.js.map +1 -0
- 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 +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/evaluator/computed.d.ts +14 -0
- package/dist/evaluator/computed.d.ts.map +1 -0
- package/dist/evaluator/computed.js +60 -0
- package/dist/evaluator/computed.js.map +1 -0
- package/dist/evaluator/context.d.ts +59 -0
- package/dist/evaluator/context.d.ts.map +1 -0
- package/dist/evaluator/context.js +41 -0
- package/dist/evaluator/context.js.map +1 -0
- package/dist/evaluator/dag.d.ts +30 -0
- package/dist/evaluator/dag.d.ts.map +1 -0
- package/dist/evaluator/dag.js +121 -0
- package/dist/evaluator/dag.js.map +1 -0
- package/dist/evaluator/expr.d.ts +11 -0
- package/dist/evaluator/expr.d.ts.map +1 -0
- package/dist/evaluator/expr.js +649 -0
- package/dist/evaluator/expr.js.map +1 -0
- package/dist/evaluator/expr.test.d.ts +2 -0
- package/dist/evaluator/expr.test.d.ts.map +1 -0
- package/dist/evaluator/expr.test.js +449 -0
- package/dist/evaluator/expr.test.js.map +1 -0
- package/dist/evaluator/flow.d.ts +35 -0
- package/dist/evaluator/flow.d.ts.map +1 -0
- package/dist/evaluator/flow.js +387 -0
- package/dist/evaluator/flow.js.map +1 -0
- package/dist/evaluator/flow.test.d.ts +2 -0
- package/dist/evaluator/flow.test.d.ts.map +1 -0
- package/dist/evaluator/flow.test.js +499 -0
- package/dist/evaluator/flow.test.js.map +1 -0
- package/dist/evaluator/index.d.ts +6 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/index.js +6 -0
- package/dist/evaluator/index.js.map +1 -0
- package/dist/factories.d.ts +22 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +44 -0
- package/dist/factories.js.map +1 -0
- package/dist/index.d.ts +47 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -45
- package/dist/index.js.map +1 -1
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +13 -0
- package/dist/index.test.js.map +1 -0
- package/dist/schema/action.d.ts +14 -0
- package/dist/schema/action.d.ts.map +1 -0
- package/dist/schema/action.js +30 -0
- package/dist/schema/action.js.map +1 -0
- package/dist/schema/common.d.ts +37 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/common.js +20 -0
- package/dist/schema/common.js.map +1 -0
- package/dist/schema/computed.d.ts +23 -0
- package/dist/schema/computed.d.ts.map +1 -0
- package/dist/schema/computed.js +34 -0
- package/dist/schema/computed.js.map +1 -0
- package/dist/schema/domain.d.ts +50 -0
- package/dist/schema/domain.d.ts.map +1 -0
- package/dist/schema/domain.js +60 -0
- package/dist/schema/domain.js.map +1 -0
- package/dist/schema/expr.d.ts +303 -0
- package/dist/schema/expr.d.ts.map +1 -0
- package/dist/schema/expr.js +283 -0
- package/dist/schema/expr.js.map +1 -0
- package/dist/schema/field.d.ts +48 -0
- package/dist/schema/field.d.ts.map +1 -0
- package/dist/schema/field.js +31 -0
- package/dist/schema/field.js.map +1 -0
- package/dist/schema/flow.d.ts +103 -0
- package/dist/schema/flow.d.ts.map +1 -0
- package/dist/schema/flow.js +82 -0
- package/dist/schema/flow.js.map +1 -0
- 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 +13 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +25 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/patch.d.ts +59 -0
- package/dist/schema/patch.d.ts.map +1 -0
- package/dist/schema/patch.js +60 -0
- package/dist/schema/patch.js.map +1 -0
- package/dist/schema/result.d.ts +142 -0
- package/dist/schema/result.d.ts.map +1 -0
- package/dist/schema/result.js +94 -0
- package/dist/schema/result.js.map +1 -0
- package/dist/schema/snapshot.d.ts +153 -0
- package/dist/schema/snapshot.d.ts.map +1 -0
- package/dist/schema/snapshot.js +160 -0
- package/dist/schema/snapshot.js.map +1 -0
- package/dist/schema/trace.d.ts +98 -0
- package/dist/schema/trace.d.ts.map +1 -0
- package/dist/schema/trace.js +90 -0
- package/dist/schema/trace.js.map +1 -0
- 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 +37 -0
- package/dist/utils/canonical.d.ts.map +1 -0
- package/dist/utils/canonical.js +122 -0
- package/dist/utils/canonical.js.map +1 -0
- package/dist/utils/canonical.test.d.ts +2 -0
- package/dist/utils/canonical.test.d.ts.map +1 -0
- package/dist/utils/canonical.test.js +183 -0
- package/dist/utils/canonical.test.js.map +1 -0
- package/dist/utils/hash.d.ts +28 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +152 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/hash.test.d.ts +2 -0
- package/dist/utils/hash.test.d.ts.map +1 -0
- package/dist/utils/hash.test.js +170 -0
- package/dist/utils/hash.test.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/path.d.ts +40 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +132 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/utils/path.test.d.ts +2 -0
- package/dist/utils/path.test.d.ts.map +1 -0
- package/dist/utils/path.test.js +191 -0
- package/dist/utils/path.test.js.map +1 -0
- package/package.json +28 -41
- package/LICENSE +0 -21
- package/dist/dag/graph.d.ts +0 -62
- package/dist/dag/graph.d.ts.map +0 -1
- package/dist/dag/graph.js +0 -244
- package/dist/dag/graph.js.map +0 -1
- package/dist/dag/index.d.ts +0 -4
- package/dist/dag/index.d.ts.map +0 -1
- package/dist/dag/index.js +0 -4
- package/dist/dag/index.js.map +0 -1
- package/dist/dag/propagation.d.ts +0 -58
- package/dist/dag/propagation.d.ts.map +0 -1
- package/dist/dag/propagation.js +0 -224
- package/dist/dag/propagation.js.map +0 -1
- package/dist/dag/topological.d.ts +0 -33
- package/dist/dag/topological.d.ts.map +0 -1
- package/dist/dag/topological.js +0 -173
- package/dist/dag/topological.js.map +0 -1
- package/dist/domain/define.d.ts +0 -82
- package/dist/domain/define.d.ts.map +0 -1
- package/dist/domain/define.js +0 -105
- package/dist/domain/define.js.map +0 -1
- package/dist/domain/index.d.ts +0 -4
- package/dist/domain/index.d.ts.map +0 -1
- package/dist/domain/index.js +0 -4
- package/dist/domain/index.js.map +0 -1
- package/dist/domain/types.d.ts +0 -203
- package/dist/domain/types.d.ts.map +0 -1
- package/dist/domain/types.js +0 -2
- package/dist/domain/types.js.map +0 -1
- package/dist/domain/validate.d.ts +0 -17
- package/dist/domain/validate.d.ts.map +0 -1
- package/dist/domain/validate.js +0 -204
- package/dist/domain/validate.js.map +0 -1
- package/dist/effect/index.d.ts +0 -4
- package/dist/effect/index.d.ts.map +0 -1
- package/dist/effect/index.js +0 -4
- package/dist/effect/index.js.map +0 -1
- package/dist/effect/result.d.ts +0 -100
- package/dist/effect/result.d.ts.map +0 -1
- package/dist/effect/result.js +0 -163
- package/dist/effect/result.js.map +0 -1
- package/dist/effect/runner.d.ts +0 -98
- package/dist/effect/runner.d.ts.map +0 -1
- package/dist/effect/runner.js +0 -321
- package/dist/effect/runner.js.map +0 -1
- package/dist/effect/types.d.ts +0 -169
- package/dist/effect/types.d.ts.map +0 -1
- package/dist/effect/types.js +0 -28
- package/dist/effect/types.js.map +0 -1
- package/dist/expression/analyzer.d.ts +0 -42
- package/dist/expression/analyzer.d.ts.map +0 -1
- package/dist/expression/analyzer.js +0 -166
- package/dist/expression/analyzer.js.map +0 -1
- package/dist/expression/evaluator.d.ts +0 -16
- package/dist/expression/evaluator.d.ts.map +0 -1
- package/dist/expression/evaluator.js +0 -382
- package/dist/expression/evaluator.js.map +0 -1
- package/dist/expression/index.d.ts +0 -5
- package/dist/expression/index.d.ts.map +0 -1
- package/dist/expression/index.js +0 -5
- package/dist/expression/index.js.map +0 -1
- package/dist/expression/parser.d.ts +0 -37
- package/dist/expression/parser.d.ts.map +0 -1
- package/dist/expression/parser.js +0 -201
- package/dist/expression/parser.js.map +0 -1
- package/dist/expression/types.d.ts +0 -123
- package/dist/expression/types.d.ts.map +0 -1
- package/dist/expression/types.js +0 -10
- package/dist/expression/types.js.map +0 -1
- package/dist/policy/field-policy.d.ts +0 -63
- package/dist/policy/field-policy.d.ts.map +0 -1
- package/dist/policy/field-policy.js +0 -138
- package/dist/policy/field-policy.js.map +0 -1
- package/dist/policy/index.d.ts +0 -3
- package/dist/policy/index.d.ts.map +0 -1
- package/dist/policy/index.js +0 -3
- package/dist/policy/index.js.map +0 -1
- package/dist/policy/precondition.d.ts +0 -58
- package/dist/policy/precondition.d.ts.map +0 -1
- package/dist/policy/precondition.js +0 -115
- package/dist/policy/precondition.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -4
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js +0 -4
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -94
- package/dist/runtime/runtime.d.ts.map +0 -1
- package/dist/runtime/runtime.js +0 -294
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/snapshot.d.ts +0 -39
- package/dist/runtime/snapshot.d.ts.map +0 -1
- package/dist/runtime/snapshot.js +0 -264
- package/dist/runtime/snapshot.js.map +0 -1
- package/dist/runtime/subscription.d.ts +0 -82
- package/dist/runtime/subscription.d.ts.map +0 -1
- package/dist/runtime/subscription.js +0 -222
- package/dist/runtime/subscription.js.map +0 -1
- package/dist/schema/integration.d.ts +0 -89
- package/dist/schema/integration.d.ts.map +0 -1
- package/dist/schema/integration.js +0 -171
- package/dist/schema/integration.js.map +0 -1
- package/dist/schema/validation.d.ts +0 -51
- package/dist/schema/validation.d.ts.map +0 -1
- package/dist/schema/validation.js +0 -212
- package/dist/schema/validation.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,566 +1,216 @@
|
|
|
1
1
|
# @manifesto-ai/core
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> **Core** is the pure semantic calculator of Manifesto. It computes state transitions deterministically with no side effects.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
pnpm add @manifesto-ai/core
|
|
11
|
-
# or
|
|
12
|
-
npm install @manifesto-ai/core
|
|
13
|
-
```
|
|
7
|
+
## What is Core?
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
Core is responsible for evaluating domain semantics. Given a schema, snapshot, and intent, it computes what patches and effects should result—but never executes them.
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
defineDomain,
|
|
20
|
-
createRuntime,
|
|
21
|
-
defineDerived,
|
|
22
|
-
defineAction,
|
|
23
|
-
defineSource,
|
|
24
|
-
sequence,
|
|
25
|
-
setState,
|
|
26
|
-
setValue,
|
|
27
|
-
z
|
|
28
|
-
} from '@manifesto-ai/core';
|
|
29
|
-
|
|
30
|
-
// Define a domain
|
|
31
|
-
const todosDomain = defineDomain({
|
|
32
|
-
id: 'todos',
|
|
33
|
-
name: 'Todos',
|
|
34
|
-
description: 'Todo list management domain',
|
|
35
|
-
|
|
36
|
-
dataSchema: z.object({
|
|
37
|
-
items: z.array(z.object({
|
|
38
|
-
id: z.string(),
|
|
39
|
-
title: z.string(),
|
|
40
|
-
completed: z.boolean()
|
|
41
|
-
}))
|
|
42
|
-
}),
|
|
43
|
-
|
|
44
|
-
stateSchema: z.object({
|
|
45
|
-
filter: z.enum(['all', 'active', 'completed']),
|
|
46
|
-
isLoading: z.boolean()
|
|
47
|
-
}),
|
|
48
|
-
|
|
49
|
-
initialState: {
|
|
50
|
-
filter: 'all',
|
|
51
|
-
isLoading: false
|
|
52
|
-
},
|
|
11
|
+
In the Manifesto architecture:
|
|
53
12
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
id: z.string(),
|
|
60
|
-
title: z.string(),
|
|
61
|
-
completed: z.boolean()
|
|
62
|
-
})),
|
|
63
|
-
defaultValue: [],
|
|
64
|
-
semantic: { type: 'list', description: 'Todo items' }
|
|
65
|
-
})
|
|
66
|
-
},
|
|
67
|
-
derived: {
|
|
68
|
-
// Auto-prefixed: 'activeCount' becomes 'derived.activeCount'
|
|
69
|
-
activeCount: defineDerived({
|
|
70
|
-
deps: ['data.items'],
|
|
71
|
-
expr: ['length', ['filter', ['get', 'data.items'], ['!', '$.completed']]],
|
|
72
|
-
semantic: { type: 'count', description: 'Number of active todos' }
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
actions: {
|
|
78
|
-
// Set filter action
|
|
79
|
-
setFilter: defineAction({
|
|
80
|
-
deps: ['state.filter'],
|
|
81
|
-
input: z.object({ filter: z.enum(['all', 'active', 'completed']) }),
|
|
82
|
-
effect: setState('state.filter', ['get', 'input.filter'], 'Set filter'),
|
|
83
|
-
semantic: { type: 'action', verb: 'set', description: 'Set todo filter' }
|
|
84
|
-
}),
|
|
85
|
-
|
|
86
|
-
// Clear completed todos
|
|
87
|
-
clearCompleted: defineAction({
|
|
88
|
-
deps: ['data.items'],
|
|
89
|
-
effect: setValue('data.items',
|
|
90
|
-
['filter', ['get', 'data.items'], ['!', '$.completed']],
|
|
91
|
-
'Clear completed todos'
|
|
92
|
-
),
|
|
93
|
-
semantic: { type: 'action', verb: 'clear', description: 'Remove completed todos' }
|
|
94
|
-
})
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Create runtime
|
|
99
|
-
const runtime = createRuntime({ domain: todosDomain });
|
|
100
|
-
|
|
101
|
-
// Use the runtime
|
|
102
|
-
runtime.set('data.items', [
|
|
103
|
-
{ id: '1', title: 'Learn Manifesto', completed: false }
|
|
104
|
-
]);
|
|
105
|
-
|
|
106
|
-
console.log(runtime.get('derived.activeCount')); // 1
|
|
13
|
+
```
|
|
14
|
+
Host ──→ CORE ──→ ComputeResult
|
|
15
|
+
│
|
|
16
|
+
Computes patches & effects
|
|
17
|
+
(pure, no IO, deterministic)
|
|
107
18
|
```
|
|
108
19
|
|
|
109
|
-
|
|
20
|
+
---
|
|
110
21
|
|
|
111
|
-
|
|
22
|
+
## What Core Does
|
|
112
23
|
|
|
113
|
-
|
|
24
|
+
| Responsibility | Description |
|
|
25
|
+
|----------------|-------------|
|
|
26
|
+
| Compute state transitions | Given (schema, snapshot, intent), produce patches and effects |
|
|
27
|
+
| Apply patches | Transform snapshots by applying patch operations |
|
|
28
|
+
| Validate schemas | Check DomainSchema structure for correctness |
|
|
29
|
+
| Explain values | Trace why a computed value has its current result |
|
|
114
30
|
|
|
115
|
-
|
|
31
|
+
---
|
|
116
32
|
|
|
117
|
-
|
|
33
|
+
## What Core Does NOT Do
|
|
118
34
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
initialState: { ... }, // Required: Initial state values
|
|
127
|
-
paths: {
|
|
128
|
-
sources: { ... }, // Optional: Source definitions
|
|
129
|
-
derived: { ... }, // Optional: Computed values
|
|
130
|
-
async: { ... }, // Optional: Async data sources
|
|
131
|
-
},
|
|
132
|
-
actions: { ... }, // Optional: Domain actions
|
|
133
|
-
meta: { ... } // Optional: Domain metadata
|
|
134
|
-
});
|
|
135
|
-
```
|
|
35
|
+
| NOT Responsible For | Who Is |
|
|
36
|
+
|--------------------|--------|
|
|
37
|
+
| Execute effects | Host |
|
|
38
|
+
| Perform IO (network, filesystem) | Host |
|
|
39
|
+
| Persist snapshots | Host |
|
|
40
|
+
| Govern authority/proposals | World |
|
|
41
|
+
| Handle UI bindings | Bridge / React |
|
|
136
42
|
|
|
137
|
-
|
|
43
|
+
---
|
|
138
44
|
|
|
139
|
-
|
|
45
|
+
## Installation
|
|
140
46
|
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
schema: z.object({ name: z.string(), email: z.string() }),
|
|
146
|
-
defaultValue: { name: '', email: '' },
|
|
147
|
-
semantic: {
|
|
148
|
-
type: 'entity',
|
|
149
|
-
description: 'Current user information'
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
};
|
|
47
|
+
```bash
|
|
48
|
+
npm install @manifesto-ai/core
|
|
49
|
+
# or
|
|
50
|
+
pnpm add @manifesto-ai/core
|
|
153
51
|
```
|
|
154
52
|
|
|
155
|
-
|
|
53
|
+
---
|
|
156
54
|
|
|
157
|
-
|
|
55
|
+
## Quick Example
|
|
158
56
|
|
|
159
57
|
```typescript
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
fullName: defineDerived({
|
|
163
|
-
deps: ['data.firstName', 'data.lastName'],
|
|
164
|
-
expr: ['concat', ['get', 'data.firstName'], ' ', ['get', 'data.lastName']],
|
|
165
|
-
semantic: {
|
|
166
|
-
type: 'computed',
|
|
167
|
-
description: 'User full name'
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
};
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
#### `defineAsync(options)`
|
|
58
|
+
import { createCore, createSnapshot, createIntent } from "@manifesto-ai/core";
|
|
59
|
+
import type { DomainSchema } from "@manifesto-ai/core";
|
|
174
60
|
|
|
175
|
-
|
|
61
|
+
// Create core instance
|
|
62
|
+
const core = createCore();
|
|
176
63
|
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
method: 'GET',
|
|
187
|
-
endpoint: '/api/user',
|
|
188
|
-
description: 'Fetch user data'
|
|
64
|
+
// Define a simple schema (usually from @manifesto-ai/builder)
|
|
65
|
+
const schema: DomainSchema = {
|
|
66
|
+
id: "example:counter",
|
|
67
|
+
version: "1.0.0",
|
|
68
|
+
hash: "example-hash",
|
|
69
|
+
types: {},
|
|
70
|
+
state: {
|
|
71
|
+
fields: {
|
|
72
|
+
count: { type: "number", required: true, default: 0 },
|
|
189
73
|
},
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
effect: sequence([
|
|
214
|
-
setState('state.isSubmitting', true),
|
|
215
|
-
apiCall({ method: 'POST', url: '/api/submit' }),
|
|
216
|
-
setState('state.isSubmitting', false)
|
|
217
|
-
]),
|
|
218
|
-
semantic: {
|
|
219
|
-
type: 'action',
|
|
220
|
-
verb: 'submit',
|
|
221
|
-
description: 'Submit the order',
|
|
222
|
-
risk: 'medium'
|
|
223
|
-
}
|
|
224
|
-
})
|
|
74
|
+
},
|
|
75
|
+
computed: {
|
|
76
|
+
fields: {
|
|
77
|
+
"computed.count": {
|
|
78
|
+
deps: ["count"],
|
|
79
|
+
expr: { kind: "get", path: "count" },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
actions: {
|
|
84
|
+
increment: {
|
|
85
|
+
flow: {
|
|
86
|
+
kind: "patch",
|
|
87
|
+
op: "set",
|
|
88
|
+
path: "count",
|
|
89
|
+
value: {
|
|
90
|
+
kind: "add",
|
|
91
|
+
left: { kind: "get", path: "count" },
|
|
92
|
+
right: { kind: "lit", value: 1 },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
225
97
|
};
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Runtime
|
|
229
|
-
|
|
230
|
-
#### `createRuntime(options)`
|
|
231
|
-
|
|
232
|
-
Creates a runtime instance for a domain.
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
const runtime = createRuntime({
|
|
236
|
-
domain: myDomain,
|
|
237
|
-
initialData: { count: 0 },
|
|
238
|
-
initialState: { isLoading: false }
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
#### Runtime Methods
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
// Get a value by path
|
|
246
|
-
runtime.get('data.user.name'); // Returns the value
|
|
247
|
-
runtime.get('derived.fullName'); // Computes and returns
|
|
248
|
-
|
|
249
|
-
// Set a value
|
|
250
|
-
runtime.set('data.count', 10);
|
|
251
|
-
runtime.set('state.isLoading', true);
|
|
252
|
-
|
|
253
|
-
// Subscribe to changes
|
|
254
|
-
const unsubscribe = runtime.subscribe('data.count', (value) => {
|
|
255
|
-
console.log('Count:', value);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
// Subscribe to all changes
|
|
259
|
-
runtime.subscribeAll((snapshot) => {
|
|
260
|
-
console.log('Snapshot changed:', snapshot);
|
|
261
|
-
});
|
|
262
98
|
|
|
263
|
-
//
|
|
264
|
-
const
|
|
99
|
+
// Create host context (deterministic inputs)
|
|
100
|
+
const context = { now: 0, randomSeed: "seed" };
|
|
265
101
|
|
|
266
|
-
//
|
|
267
|
-
const
|
|
268
|
-
// { available: true, reason: null }
|
|
102
|
+
// Create initial snapshot
|
|
103
|
+
const snapshot = createSnapshot({ count: 0 }, schema.hash, context);
|
|
269
104
|
|
|
270
|
-
//
|
|
271
|
-
|
|
105
|
+
// Create intent
|
|
106
|
+
const intent = createIntent("increment", "intent-1");
|
|
272
107
|
|
|
273
|
-
//
|
|
274
|
-
const
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### Expression DSL
|
|
278
|
-
|
|
279
|
-
Manifesto uses a JSON-based DSL for declarative expressions. All expressions use **array format**: `['operator', ...args]`.
|
|
280
|
-
|
|
281
|
-
#### Path Reference
|
|
108
|
+
// Compute result (pure, deterministic)
|
|
109
|
+
const result = await core.compute(schema, snapshot, intent, context);
|
|
282
110
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
['get', 'state.isLoading'] // Get state value
|
|
286
|
-
['get', 'derived.total'] // Get derived value
|
|
287
|
-
|
|
288
|
-
// In predicates (filter, map, etc.)
|
|
289
|
-
'$.price' // Current item's price field
|
|
290
|
-
'$.completed' // Current item's completed field
|
|
291
|
-
'$' // Current item itself
|
|
111
|
+
console.log(result.status); // → "complete"
|
|
112
|
+
console.log(result.snapshot.data.count); // → 1
|
|
292
113
|
```
|
|
293
114
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
['==', a, b] // a === b
|
|
298
|
-
['!=', a, b] // a !== b
|
|
299
|
-
['>', a, b] // a > b
|
|
300
|
-
['>=', a, b] // a >= b
|
|
301
|
-
['<', a, b] // a < b
|
|
302
|
-
['<=', a, b] // a <= b
|
|
303
|
-
```
|
|
115
|
+
> See [GUIDE.md](../../docs/packages/core/GUIDE.md) for the full tutorial.
|
|
304
116
|
|
|
305
|
-
|
|
117
|
+
---
|
|
306
118
|
|
|
307
|
-
|
|
308
|
-
['all', expr1, expr2, ...] // All expressions must be true (AND)
|
|
309
|
-
['any', expr1, expr2, ...] // Any expression is true (OR)
|
|
310
|
-
['!', expr] // Negation (NOT)
|
|
311
|
-
```
|
|
119
|
+
## Core API
|
|
312
120
|
|
|
313
|
-
|
|
121
|
+
### Main Exports
|
|
314
122
|
|
|
315
123
|
```typescript
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
['*', a, b] // a * b
|
|
319
|
-
```
|
|
124
|
+
// Factory
|
|
125
|
+
function createCore(): ManifestoCore;
|
|
320
126
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
#### Array Functions
|
|
331
|
-
|
|
332
|
-
```typescript
|
|
333
|
-
['length', array] // Array length
|
|
334
|
-
['at', array, index] // Element at index (0 = first, -1 = last)
|
|
335
|
-
['filter', array, predicate] // Filter elements
|
|
336
|
-
['map', array, transform] // Transform elements
|
|
337
|
-
['some', array, predicate] // Any element matches
|
|
338
|
-
['every', array, predicate] // All elements match
|
|
339
|
-
['concat', array1, array2] // Concatenate arrays
|
|
340
|
-
['includes', array, element] // Array contains element
|
|
341
|
-
['sort', array, key] // Sort by key
|
|
342
|
-
['slice', array, start, end] // Slice array
|
|
343
|
-
['indexOf', array, element] // Find index of element
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
> **Note:** There is no `find` operator. Use `['at', ['filter', array, predicate], 0]` instead.
|
|
347
|
-
|
|
348
|
-
#### Conditional
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
// Case expression (if-else chain) - each condition-value pair is a tuple
|
|
352
|
-
['case',
|
|
353
|
-
[condition1, value1],
|
|
354
|
-
[condition2, value2],
|
|
355
|
-
defaultValue
|
|
356
|
-
]
|
|
357
|
-
|
|
358
|
-
// Example: return 'large', 'medium', or 'small' based on total
|
|
359
|
-
['case',
|
|
360
|
-
[['>', ['get', 'derived.total'], 100], 'large'],
|
|
361
|
-
[['>', ['get', 'derived.total'], 50], 'medium'],
|
|
362
|
-
'small'
|
|
363
|
-
]
|
|
364
|
-
|
|
365
|
-
// Match expression (pattern matching)
|
|
366
|
-
['match', value,
|
|
367
|
-
[pattern1, result1],
|
|
368
|
-
[pattern2, result2],
|
|
369
|
-
defaultResult
|
|
370
|
-
]
|
|
371
|
-
|
|
372
|
-
// Coalesce (first non-null value)
|
|
373
|
-
['coalesce', value1, value2, value3]
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
#### Object Operations
|
|
377
|
-
|
|
378
|
-
```typescript
|
|
379
|
-
['pick', object, ['key1', 'key2']] // Pick specific keys
|
|
380
|
-
['omit', object, ['key1', 'key2']] // Omit specific keys
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
#### Examples
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
// Filter active todos
|
|
387
|
-
['filter', ['get', 'data.items'], ['!', '$.completed']]
|
|
388
|
-
|
|
389
|
-
// Count completed items
|
|
390
|
-
['length', ['filter', ['get', 'data.items'], '$.completed']]
|
|
391
|
-
|
|
392
|
-
// Find first item by id (no find operator, use filter + at)
|
|
393
|
-
['at', ['filter', ['get', 'data.items'], ['==', '$.id', ['get', 'input.id']]], 0]
|
|
394
|
-
|
|
395
|
-
// Concatenate first and last name
|
|
396
|
-
['concat', ['get', 'data.firstName'], ' ', ['get', 'data.lastName']]
|
|
127
|
+
// Core interface
|
|
128
|
+
interface ManifestoCore {
|
|
129
|
+
compute(schema, snapshot, intent, context): Promise<ComputeResult>;
|
|
130
|
+
apply(schema, snapshot, patches, context): Snapshot;
|
|
131
|
+
validate(schema): ValidationResult;
|
|
132
|
+
explain(schema, snapshot, path): ExplainResult;
|
|
133
|
+
}
|
|
397
134
|
|
|
398
|
-
//
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
135
|
+
// Key types
|
|
136
|
+
type DomainSchema = { id, version, hash, types, state, computed, actions, meta? };
|
|
137
|
+
type Snapshot = { data, computed, system, input, meta };
|
|
138
|
+
type Intent = { type, input?, intentId };
|
|
139
|
+
type Patch = { op: "set" | "unset" | "merge", path, value? };
|
|
140
|
+
type ComputeResult = { status, snapshot, requirements, trace };
|
|
404
141
|
```
|
|
405
142
|
|
|
406
|
-
|
|
143
|
+
> See [SPEC.md](../../docs/packages/core/SPEC.md) for complete API reference.
|
|
407
144
|
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
// ❌ This does NOT work
|
|
411
|
-
['concat', ['get', 'data.items'], [{ id: ['get', 'input.id'], name: 'New' }]]
|
|
145
|
+
---
|
|
412
146
|
|
|
413
|
-
|
|
414
|
-
['pick', '$', ['id', 'name']]
|
|
415
|
-
```
|
|
147
|
+
## Core Concepts
|
|
416
148
|
|
|
417
|
-
|
|
149
|
+
### Snapshot as Sole Medium
|
|
418
150
|
|
|
419
|
-
|
|
151
|
+
All communication between Core and Host happens through Snapshot. There is no hidden state, no suspended context, no continuation.
|
|
420
152
|
|
|
421
|
-
###
|
|
153
|
+
### Deterministic Computation
|
|
422
154
|
|
|
423
|
-
|
|
155
|
+
Given the same (schema, snapshot, intent), Core always produces the same result. This enables:
|
|
156
|
+
- Reliable testing without mocks
|
|
157
|
+
- Time-travel debugging
|
|
158
|
+
- Reproducible bug reports
|
|
424
159
|
|
|
425
|
-
|
|
160
|
+
### Effects as Declarations
|
|
426
161
|
|
|
427
|
-
|
|
428
|
-
// Set a value
|
|
429
|
-
setValue('data.count', 10)
|
|
430
|
-
setValue('data.count', ['+', ['get', 'data.count'], 1])
|
|
431
|
-
|
|
432
|
-
// Set state
|
|
433
|
-
setState('state.isLoading', true)
|
|
434
|
-
|
|
435
|
-
// API call
|
|
436
|
-
apiCall({
|
|
437
|
-
method: 'POST',
|
|
438
|
-
url: '/api/orders',
|
|
439
|
-
body: ['get', 'data.order'],
|
|
440
|
-
headers: { 'Content-Type': 'application/json' }
|
|
441
|
-
})
|
|
162
|
+
When an action needs IO (API call, timer, etc.), Core doesn't execute it. Instead, it records an Effect as a Requirement in the snapshot. Host reads these and executes them.
|
|
442
163
|
|
|
443
|
-
|
|
444
|
-
navigate('/success')
|
|
445
|
-
|
|
446
|
-
// Delay
|
|
447
|
-
delay(1000) // milliseconds
|
|
448
|
-
|
|
449
|
-
// Emit event
|
|
450
|
-
emitEvent('orderCreated', { orderId: '123' })
|
|
451
|
-
```
|
|
164
|
+
---
|
|
452
165
|
|
|
453
|
-
|
|
166
|
+
## Relationship with Other Packages
|
|
454
167
|
|
|
455
|
-
```typescript
|
|
456
|
-
// Sequential execution
|
|
457
|
-
sequence([
|
|
458
|
-
setState('state.isLoading', true),
|
|
459
|
-
apiCall({ method: 'GET', url: '/api/data' }),
|
|
460
|
-
setState('state.isLoading', false)
|
|
461
|
-
])
|
|
462
|
-
|
|
463
|
-
// Parallel execution
|
|
464
|
-
parallel([
|
|
465
|
-
apiCall({ method: 'GET', url: '/api/user' }),
|
|
466
|
-
apiCall({ method: 'GET', url: '/api/settings' })
|
|
467
|
-
])
|
|
468
|
-
|
|
469
|
-
// Conditional execution
|
|
470
|
-
conditional(
|
|
471
|
-
['get', 'state.isPremium'],
|
|
472
|
-
apiCall({ method: 'GET', url: '/api/premium' }),
|
|
473
|
-
apiCall({ method: 'GET', url: '/api/basic' })
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
// Error handling
|
|
477
|
-
catchEffect(
|
|
478
|
-
apiCall({ method: 'POST', url: '/api/submit' }),
|
|
479
|
-
setState('state.error', ['get', 'error.message'])
|
|
480
|
-
)
|
|
481
168
|
```
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
if (isOk(result)) {
|
|
499
|
-
console.log('Success:', result.value);
|
|
500
|
-
} else {
|
|
501
|
-
console.log('Error:', result.error);
|
|
502
|
-
}
|
|
169
|
+
┌─────────────┐
|
|
170
|
+
│ Host │ ← Uses Core to compute
|
|
171
|
+
└──────┬──────┘
|
|
172
|
+
│
|
|
173
|
+
▼
|
|
174
|
+
┌─────────────┐
|
|
175
|
+
│ CORE │
|
|
176
|
+
└─────────────┘
|
|
177
|
+
▲
|
|
178
|
+
│
|
|
179
|
+
┌─────────────┐
|
|
180
|
+
│ Builder │ ← Produces DomainSchema for Core
|
|
181
|
+
└─────────────┘
|
|
503
182
|
```
|
|
504
183
|
|
|
505
|
-
|
|
184
|
+
| Relationship | Package | How |
|
|
185
|
+
|--------------|---------|-----|
|
|
186
|
+
| Used by | `@manifesto-ai/host` | Host calls compute() and apply() |
|
|
187
|
+
| Schema from | `@manifesto-ai/builder` | Builder produces DomainSchema |
|
|
506
188
|
|
|
507
|
-
|
|
189
|
+
---
|
|
508
190
|
|
|
509
|
-
|
|
510
|
-
import { ok, err, isOk, isErr, map, flatMap, unwrapOr } from '@manifesto-ai/core';
|
|
191
|
+
## When to Use Core Directly
|
|
511
192
|
|
|
512
|
-
|
|
513
|
-
const success = ok(42);
|
|
514
|
-
const failure = err({ code: 'NOT_FOUND', message: 'Item not found' });
|
|
193
|
+
**Most users don't need to use Core directly.**
|
|
515
194
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
195
|
+
Use Core directly when:
|
|
196
|
+
- Building a custom Host implementation
|
|
197
|
+
- Testing domain logic in isolation
|
|
198
|
+
- Building developer tools (debuggers, visualizers)
|
|
520
199
|
|
|
521
|
-
|
|
522
|
-
const doubled = map(success, (x) => x * 2); // ok(84)
|
|
200
|
+
For typical usage, see [`@manifesto-ai/react`](../react/) or [`@manifesto-ai/host`](../host/).
|
|
523
201
|
|
|
524
|
-
|
|
525
|
-
const result = flatMap(success, (x) =>
|
|
526
|
-
x > 0 ? ok(x) : err({ code: 'INVALID', message: 'Must be positive' })
|
|
527
|
-
);
|
|
202
|
+
---
|
|
528
203
|
|
|
529
|
-
|
|
530
|
-
const value = unwrapOr(failure, 0); // 0
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
### Schema Utilities
|
|
534
|
-
|
|
535
|
-
```typescript
|
|
536
|
-
import {
|
|
537
|
-
schemaToSource,
|
|
538
|
-
validateValue,
|
|
539
|
-
zodErrorToValidationResult,
|
|
540
|
-
CommonSchemas
|
|
541
|
-
} from '@manifesto-ai/core';
|
|
542
|
-
|
|
543
|
-
// Common schemas
|
|
544
|
-
CommonSchemas.email // z.string().email()
|
|
545
|
-
CommonSchemas.phone // Phone number pattern
|
|
546
|
-
CommonSchemas.money // Positive number with 2 decimals
|
|
547
|
-
|
|
548
|
-
// Validate values
|
|
549
|
-
const result = validateValue(userSchema, inputData);
|
|
550
|
-
if (!result.valid) {
|
|
551
|
-
console.log(result.issues);
|
|
552
|
-
}
|
|
553
|
-
```
|
|
204
|
+
## Documentation
|
|
554
205
|
|
|
555
|
-
|
|
206
|
+
| Document | Purpose |
|
|
207
|
+
|----------|---------|
|
|
208
|
+
| [GUIDE.md](../../docs/packages/core/GUIDE.md) | Step-by-step usage guide |
|
|
209
|
+
| [SPEC.md](docs/SPEC.md) | Complete specification |
|
|
210
|
+
| [FDR.md](docs/FDR.md) | Design rationale |
|
|
556
211
|
|
|
557
|
-
|
|
558
|
-
- [@manifesto-ai/bridge-zustand](../bridge-zustand) - Zustand integration
|
|
559
|
-
- [@manifesto-ai/bridge-react-hook-form](../bridge-react-hook-form) - React Hook Form integration
|
|
560
|
-
- [@manifesto-ai/projection-ui](../projection-ui) - UI state projection
|
|
561
|
-
- [@manifesto-ai/projection-agent](../projection-agent) - AI agent context
|
|
562
|
-
- [@manifesto-ai/projection-graphql](../projection-graphql) - GraphQL schema generation
|
|
212
|
+
---
|
|
563
213
|
|
|
564
214
|
## License
|
|
565
215
|
|
|
566
|
-
MIT
|
|
216
|
+
[MIT](../../LICENSE)
|