@manifesto-ai/core 0.2.0 → 1.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.
Files changed (259) hide show
  1. package/README.md +130 -368
  2. package/dist/core/apply.d.ts +16 -0
  3. package/dist/core/apply.d.ts.map +1 -0
  4. package/dist/core/apply.js +52 -0
  5. package/dist/core/apply.js.map +1 -0
  6. package/dist/core/compute.d.ts +17 -0
  7. package/dist/core/compute.d.ts.map +1 -0
  8. package/dist/core/compute.js +197 -0
  9. package/dist/core/compute.js.map +1 -0
  10. package/dist/core/compute.test.d.ts +2 -0
  11. package/dist/core/compute.test.d.ts.map +1 -0
  12. package/dist/core/compute.test.js +400 -0
  13. package/dist/core/compute.test.js.map +1 -0
  14. package/dist/core/explain.d.ts +14 -0
  15. package/dist/core/explain.d.ts.map +1 -0
  16. package/dist/core/explain.js +74 -0
  17. package/dist/core/explain.js.map +1 -0
  18. package/dist/core/index.d.ts +5 -0
  19. package/dist/core/index.d.ts.map +1 -0
  20. package/dist/core/index.js +5 -0
  21. package/dist/core/index.js.map +1 -0
  22. package/dist/core/validate.d.ts +15 -0
  23. package/dist/core/validate.d.ts.map +1 -0
  24. package/dist/core/validate.js +143 -0
  25. package/dist/core/validate.js.map +1 -0
  26. package/dist/core/validate.test.d.ts +2 -0
  27. package/dist/core/validate.test.d.ts.map +1 -0
  28. package/dist/core/validate.test.js +450 -0
  29. package/dist/core/validate.test.js.map +1 -0
  30. package/dist/errors.d.ts +30 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +51 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/evaluator/computed.d.ts +14 -0
  35. package/dist/evaluator/computed.d.ts.map +1 -0
  36. package/dist/evaluator/computed.js +57 -0
  37. package/dist/evaluator/computed.js.map +1 -0
  38. package/dist/evaluator/context.d.ts +46 -0
  39. package/dist/evaluator/context.d.ts.map +1 -0
  40. package/dist/evaluator/context.js +35 -0
  41. package/dist/evaluator/context.js.map +1 -0
  42. package/dist/evaluator/dag.d.ts +30 -0
  43. package/dist/evaluator/dag.d.ts.map +1 -0
  44. package/dist/evaluator/dag.js +121 -0
  45. package/dist/evaluator/dag.js.map +1 -0
  46. package/dist/evaluator/expr.d.ts +11 -0
  47. package/dist/evaluator/expr.d.ts.map +1 -0
  48. package/dist/evaluator/expr.js +498 -0
  49. package/dist/evaluator/expr.js.map +1 -0
  50. package/dist/evaluator/expr.test.d.ts +2 -0
  51. package/dist/evaluator/expr.test.d.ts.map +1 -0
  52. package/dist/evaluator/expr.test.js +426 -0
  53. package/dist/evaluator/expr.test.js.map +1 -0
  54. package/dist/evaluator/flow.d.ts +35 -0
  55. package/dist/evaluator/flow.d.ts.map +1 -0
  56. package/dist/evaluator/flow.js +234 -0
  57. package/dist/evaluator/flow.js.map +1 -0
  58. package/dist/evaluator/flow.test.d.ts +2 -0
  59. package/dist/evaluator/flow.test.d.ts.map +1 -0
  60. package/dist/evaluator/flow.test.js +446 -0
  61. package/dist/evaluator/flow.test.js.map +1 -0
  62. package/dist/evaluator/index.d.ts +6 -0
  63. package/dist/evaluator/index.d.ts.map +1 -0
  64. package/dist/evaluator/index.js +6 -0
  65. package/dist/evaluator/index.js.map +1 -0
  66. package/dist/factories.d.ts +20 -0
  67. package/dist/factories.d.ts.map +1 -0
  68. package/dist/factories.js +43 -0
  69. package/dist/factories.js.map +1 -0
  70. package/dist/index.d.ts +46 -11
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +30 -45
  73. package/dist/index.js.map +1 -1
  74. package/dist/index.test.d.ts +2 -0
  75. package/dist/index.test.d.ts.map +1 -0
  76. package/dist/index.test.js +13 -0
  77. package/dist/index.test.js.map +1 -0
  78. package/dist/schema/action.d.ts +14 -0
  79. package/dist/schema/action.d.ts.map +1 -0
  80. package/dist/schema/action.js +30 -0
  81. package/dist/schema/action.js.map +1 -0
  82. package/dist/schema/common.d.ts +37 -0
  83. package/dist/schema/common.d.ts.map +1 -0
  84. package/dist/schema/common.js +20 -0
  85. package/dist/schema/common.js.map +1 -0
  86. package/dist/schema/computed.d.ts +23 -0
  87. package/dist/schema/computed.d.ts.map +1 -0
  88. package/dist/schema/computed.js +34 -0
  89. package/dist/schema/computed.js.map +1 -0
  90. package/dist/schema/domain.d.ts +46 -0
  91. package/dist/schema/domain.d.ts.map +1 -0
  92. package/dist/schema/domain.js +54 -0
  93. package/dist/schema/domain.js.map +1 -0
  94. package/dist/schema/expr.d.ts +260 -0
  95. package/dist/schema/expr.d.ts.map +1 -0
  96. package/dist/schema/expr.js +247 -0
  97. package/dist/schema/expr.js.map +1 -0
  98. package/dist/schema/field.d.ts +48 -0
  99. package/dist/schema/field.d.ts.map +1 -0
  100. package/dist/schema/field.js +31 -0
  101. package/dist/schema/field.js.map +1 -0
  102. package/dist/schema/flow.d.ts +103 -0
  103. package/dist/schema/flow.d.ts.map +1 -0
  104. package/dist/schema/flow.js +82 -0
  105. package/dist/schema/flow.js.map +1 -0
  106. package/dist/schema/index.d.ts +11 -2
  107. package/dist/schema/index.d.ts.map +1 -1
  108. package/dist/schema/index.js +22 -2
  109. package/dist/schema/index.js.map +1 -1
  110. package/dist/schema/patch.d.ts +59 -0
  111. package/dist/schema/patch.d.ts.map +1 -0
  112. package/dist/schema/patch.js +60 -0
  113. package/dist/schema/patch.js.map +1 -0
  114. package/dist/schema/result.d.ts +130 -0
  115. package/dist/schema/result.d.ts.map +1 -0
  116. package/dist/schema/result.js +90 -0
  117. package/dist/schema/result.js.map +1 -0
  118. package/dist/schema/snapshot.d.ts +151 -0
  119. package/dist/schema/snapshot.d.ts.map +1 -0
  120. package/dist/schema/snapshot.js +156 -0
  121. package/dist/schema/snapshot.js.map +1 -0
  122. package/dist/schema/trace.d.ts +87 -0
  123. package/dist/schema/trace.d.ts.map +1 -0
  124. package/dist/schema/trace.js +79 -0
  125. package/dist/schema/trace.js.map +1 -0
  126. package/dist/utils/canonical.d.ts +29 -0
  127. package/dist/utils/canonical.d.ts.map +1 -0
  128. package/dist/utils/canonical.js +56 -0
  129. package/dist/utils/canonical.js.map +1 -0
  130. package/dist/utils/canonical.test.d.ts +2 -0
  131. package/dist/utils/canonical.test.d.ts.map +1 -0
  132. package/dist/utils/canonical.test.js +153 -0
  133. package/dist/utils/canonical.test.js.map +1 -0
  134. package/dist/utils/hash.d.ts +20 -0
  135. package/dist/utils/hash.d.ts.map +1 -0
  136. package/dist/utils/hash.js +38 -0
  137. package/dist/utils/hash.js.map +1 -0
  138. package/dist/utils/hash.test.d.ts +2 -0
  139. package/dist/utils/hash.test.d.ts.map +1 -0
  140. package/dist/utils/hash.test.js +146 -0
  141. package/dist/utils/hash.test.js.map +1 -0
  142. package/dist/utils/index.d.ts +4 -0
  143. package/dist/utils/index.d.ts.map +1 -0
  144. package/dist/utils/index.js +4 -0
  145. package/dist/utils/index.js.map +1 -0
  146. package/dist/utils/path.d.ts +40 -0
  147. package/dist/utils/path.d.ts.map +1 -0
  148. package/dist/utils/path.js +132 -0
  149. package/dist/utils/path.js.map +1 -0
  150. package/dist/utils/path.test.d.ts +2 -0
  151. package/dist/utils/path.test.d.ts.map +1 -0
  152. package/dist/utils/path.test.js +191 -0
  153. package/dist/utils/path.test.js.map +1 -0
  154. package/package.json +28 -42
  155. package/LICENSE +0 -21
  156. package/dist/dag/graph.d.ts +0 -62
  157. package/dist/dag/graph.d.ts.map +0 -1
  158. package/dist/dag/graph.js +0 -244
  159. package/dist/dag/graph.js.map +0 -1
  160. package/dist/dag/index.d.ts +0 -4
  161. package/dist/dag/index.d.ts.map +0 -1
  162. package/dist/dag/index.js +0 -4
  163. package/dist/dag/index.js.map +0 -1
  164. package/dist/dag/propagation.d.ts +0 -58
  165. package/dist/dag/propagation.d.ts.map +0 -1
  166. package/dist/dag/propagation.js +0 -224
  167. package/dist/dag/propagation.js.map +0 -1
  168. package/dist/dag/topological.d.ts +0 -33
  169. package/dist/dag/topological.d.ts.map +0 -1
  170. package/dist/dag/topological.js +0 -173
  171. package/dist/dag/topological.js.map +0 -1
  172. package/dist/domain/define.d.ts +0 -82
  173. package/dist/domain/define.d.ts.map +0 -1
  174. package/dist/domain/define.js +0 -91
  175. package/dist/domain/define.js.map +0 -1
  176. package/dist/domain/index.d.ts +0 -4
  177. package/dist/domain/index.d.ts.map +0 -1
  178. package/dist/domain/index.js +0 -4
  179. package/dist/domain/index.js.map +0 -1
  180. package/dist/domain/types.d.ts +0 -203
  181. package/dist/domain/types.d.ts.map +0 -1
  182. package/dist/domain/types.js +0 -2
  183. package/dist/domain/types.js.map +0 -1
  184. package/dist/domain/validate.d.ts +0 -17
  185. package/dist/domain/validate.d.ts.map +0 -1
  186. package/dist/domain/validate.js +0 -204
  187. package/dist/domain/validate.js.map +0 -1
  188. package/dist/effect/index.d.ts +0 -4
  189. package/dist/effect/index.d.ts.map +0 -1
  190. package/dist/effect/index.js +0 -4
  191. package/dist/effect/index.js.map +0 -1
  192. package/dist/effect/result.d.ts +0 -100
  193. package/dist/effect/result.d.ts.map +0 -1
  194. package/dist/effect/result.js +0 -163
  195. package/dist/effect/result.js.map +0 -1
  196. package/dist/effect/runner.d.ts +0 -98
  197. package/dist/effect/runner.d.ts.map +0 -1
  198. package/dist/effect/runner.js +0 -321
  199. package/dist/effect/runner.js.map +0 -1
  200. package/dist/effect/types.d.ts +0 -169
  201. package/dist/effect/types.d.ts.map +0 -1
  202. package/dist/effect/types.js +0 -28
  203. package/dist/effect/types.js.map +0 -1
  204. package/dist/expression/analyzer.d.ts +0 -42
  205. package/dist/expression/analyzer.d.ts.map +0 -1
  206. package/dist/expression/analyzer.js +0 -166
  207. package/dist/expression/analyzer.js.map +0 -1
  208. package/dist/expression/evaluator.d.ts +0 -16
  209. package/dist/expression/evaluator.d.ts.map +0 -1
  210. package/dist/expression/evaluator.js +0 -382
  211. package/dist/expression/evaluator.js.map +0 -1
  212. package/dist/expression/index.d.ts +0 -5
  213. package/dist/expression/index.d.ts.map +0 -1
  214. package/dist/expression/index.js +0 -5
  215. package/dist/expression/index.js.map +0 -1
  216. package/dist/expression/parser.d.ts +0 -37
  217. package/dist/expression/parser.d.ts.map +0 -1
  218. package/dist/expression/parser.js +0 -201
  219. package/dist/expression/parser.js.map +0 -1
  220. package/dist/expression/types.d.ts +0 -123
  221. package/dist/expression/types.d.ts.map +0 -1
  222. package/dist/expression/types.js +0 -10
  223. package/dist/expression/types.js.map +0 -1
  224. package/dist/policy/field-policy.d.ts +0 -63
  225. package/dist/policy/field-policy.d.ts.map +0 -1
  226. package/dist/policy/field-policy.js +0 -138
  227. package/dist/policy/field-policy.js.map +0 -1
  228. package/dist/policy/index.d.ts +0 -3
  229. package/dist/policy/index.d.ts.map +0 -1
  230. package/dist/policy/index.js +0 -3
  231. package/dist/policy/index.js.map +0 -1
  232. package/dist/policy/precondition.d.ts +0 -58
  233. package/dist/policy/precondition.d.ts.map +0 -1
  234. package/dist/policy/precondition.js +0 -115
  235. package/dist/policy/precondition.js.map +0 -1
  236. package/dist/runtime/index.d.ts +0 -4
  237. package/dist/runtime/index.d.ts.map +0 -1
  238. package/dist/runtime/index.js +0 -4
  239. package/dist/runtime/index.js.map +0 -1
  240. package/dist/runtime/runtime.d.ts +0 -94
  241. package/dist/runtime/runtime.d.ts.map +0 -1
  242. package/dist/runtime/runtime.js +0 -294
  243. package/dist/runtime/runtime.js.map +0 -1
  244. package/dist/runtime/snapshot.d.ts +0 -39
  245. package/dist/runtime/snapshot.d.ts.map +0 -1
  246. package/dist/runtime/snapshot.js +0 -264
  247. package/dist/runtime/snapshot.js.map +0 -1
  248. package/dist/runtime/subscription.d.ts +0 -82
  249. package/dist/runtime/subscription.d.ts.map +0 -1
  250. package/dist/runtime/subscription.js +0 -222
  251. package/dist/runtime/subscription.js.map +0 -1
  252. package/dist/schema/integration.d.ts +0 -89
  253. package/dist/schema/integration.d.ts.map +0 -1
  254. package/dist/schema/integration.js +0 -171
  255. package/dist/schema/integration.js.map +0 -1
  256. package/dist/schema/validation.d.ts +0 -51
  257. package/dist/schema/validation.d.ts.map +0 -1
  258. package/dist/schema/validation.js +0 -212
  259. package/dist/schema/validation.js.map +0 -1
package/README.md CHANGED
@@ -1,434 +1,196 @@
1
1
  # @manifesto-ai/core
2
2
 
3
- > AI Native Semantic Layer for SaaS Business Logic
3
+ > **Core** is the pure semantic calculator of Manifesto. It computes state transitions deterministically with no side effects.
4
4
 
5
- The core package provides domain definition, runtime execution, expression evaluation, and effect system for Manifesto AI.
5
+ ---
6
6
 
7
- ## Installation
7
+ ## What is Core?
8
8
 
9
- ```bash
10
- pnpm add @manifesto-ai/core
11
- # or
12
- npm install @manifesto-ai/core
13
- ```
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.
14
10
 
15
- ## Quick Start
11
+ In the Manifesto architecture:
16
12
 
17
- ```typescript
18
- import {
19
- defineDomain,
20
- createRuntime,
21
- defineDerived,
22
- defineAction,
23
- sequence,
24
- setState,
25
- apiCall,
26
- z
27
- } from '@manifesto-ai/core';
28
-
29
- // Define a domain
30
- const todosDomain = defineDomain('todos', {
31
- dataSchema: z.object({
32
- items: z.array(z.object({
33
- id: z.string(),
34
- title: z.string(),
35
- completed: z.boolean()
36
- }))
37
- }),
38
-
39
- stateSchema: z.object({
40
- filter: z.enum(['all', 'active', 'completed']).default('all'),
41
- isLoading: z.boolean().default(false)
42
- }),
43
-
44
- derived: {
45
- 'derived.activeCount': defineDerived(
46
- { $size: { $filter: ['data.items', { $eq: ['$item.completed', false] }] } },
47
- z.number()
48
- ),
49
- 'derived.filteredItems': defineDerived(
50
- {
51
- $if: [
52
- { $eq: [{ $get: 'state.filter' }, 'all'] },
53
- { $get: 'data.items' },
54
- { $filter: ['data.items', {
55
- $eq: ['$item.completed', { $eq: [{ $get: 'state.filter' }, 'completed'] }]
56
- }] }
57
- ]
58
- },
59
- z.array(z.object({ id: z.string(), title: z.string(), completed: z.boolean() }))
60
- )
61
- },
62
-
63
- actions: {
64
- addTodo: defineAction({
65
- precondition: { $gt: [{ $size: { $get: 'input.title' } }, 0] },
66
- effect: setValue('data.items', {
67
- $concat: [
68
- { $get: 'data.items' },
69
- [{ id: { $get: 'input.id' }, title: { $get: 'input.title' }, completed: false }]
70
- ]
71
- })
72
- })
73
- }
74
- });
75
-
76
- // Create runtime
77
- const runtime = createRuntime(todosDomain);
78
-
79
- // Use the runtime
80
- runtime.set('data.items', [
81
- { id: '1', title: 'Learn Manifesto', completed: false }
82
- ]);
83
-
84
- console.log(runtime.get('derived.activeCount')); // 1
85
13
  ```
86
-
87
- ## API Reference
88
-
89
- ### Domain Definition
90
-
91
- #### `defineDomain(name, config)`
92
-
93
- Creates a domain definition.
94
-
95
- ```typescript
96
- const domain = defineDomain('myDomain', {
97
- dataSchema: z.object({ ... }), // Required: Source data schema
98
- stateSchema: z.object({ ... }), // Optional: UI state schema
99
- derived: { ... }, // Optional: Computed values
100
- async: { ... }, // Optional: Async data sources
101
- actions: { ... } // Optional: Domain actions
102
- });
14
+ Host ──→ CORE ──→ ComputeResult
15
+
16
+ Computes patches & effects
17
+ (pure, no IO, deterministic)
103
18
  ```
104
19
 
105
- #### `defineSource(schema, meta?)`
20
+ ---
106
21
 
107
- Defines a source field with optional metadata.
22
+ ## What Core Does
108
23
 
109
- ```typescript
110
- const sources = {
111
- 'data.user': defineSource(
112
- z.object({ name: z.string(), email: z.string() }),
113
- { description: 'Current user information' }
114
- )
115
- };
116
- ```
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 |
117
30
 
118
- #### `defineDerived(expression, schema, meta?)`
31
+ ---
119
32
 
120
- Defines a computed value.
33
+ ## What Core Does NOT Do
121
34
 
122
- ```typescript
123
- const derived = {
124
- 'derived.fullName': defineDerived(
125
- { $concat: [{ $get: 'data.firstName' }, ' ', { $get: 'data.lastName' }] },
126
- z.string(),
127
- { description: 'User full name' }
128
- )
129
- };
130
- ```
131
-
132
- #### `defineAsync(config, schema, meta?)`
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 |
133
42
 
134
- Defines an async data source.
43
+ ---
135
44
 
136
- ```typescript
137
- const async = {
138
- 'async.userData': defineAsync(
139
- {
140
- fetch: { method: 'GET', url: '/api/user' },
141
- dependencies: ['data.userId']
142
- },
143
- z.object({ name: z.string() })
144
- )
145
- };
146
- ```
147
-
148
- #### `defineAction(config)`
149
-
150
- Defines a domain action with preconditions and effects.
45
+ ## Installation
151
46
 
152
- ```typescript
153
- const actions = {
154
- submit: defineAction({
155
- precondition: { $and: [
156
- { $gt: [{ $get: 'derived.total' }, 0] },
157
- { $not: { $get: 'state.isSubmitting' } }
158
- ]},
159
- effect: sequence([
160
- setState('state.isSubmitting', true),
161
- apiCall({ method: 'POST', url: '/api/submit' }),
162
- setState('state.isSubmitting', false)
163
- ])
164
- })
165
- };
47
+ ```bash
48
+ npm install @manifesto-ai/core
49
+ # or
50
+ pnpm add @manifesto-ai/core
166
51
  ```
167
52
 
168
- ### Runtime
169
-
170
- #### `createRuntime(domain, options?)`
53
+ ---
171
54
 
172
- Creates a runtime instance for a domain.
55
+ ## Quick Example
173
56
 
174
57
  ```typescript
175
- const runtime = createRuntime(domain, {
176
- initialData: { count: 0 },
177
- initialState: { isLoading: false }
178
- });
179
- ```
180
-
181
- #### Runtime Methods
182
-
183
- ```typescript
184
- // Get a value by path
185
- runtime.get('data.user.name'); // Returns the value
186
- runtime.get('derived.fullName'); // Computes and returns
187
-
188
- // Set a value
189
- runtime.set('data.count', 10);
190
- runtime.set('state.isLoading', true);
58
+ import { createCore, createSnapshot, createIntent } from "@manifesto-ai/core";
59
+ import type { DomainSchema } from "@manifesto-ai/core";
191
60
 
192
- // Subscribe to changes
193
- const unsubscribe = runtime.subscribe('data.count', (value) => {
194
- console.log('Count:', value);
195
- });
61
+ // Create core instance
62
+ const core = createCore();
196
63
 
197
- // Subscribe to all changes
198
- runtime.subscribeAll((snapshot) => {
199
- console.log('Snapshot changed:', snapshot);
200
- });
201
-
202
- // Get current snapshot
203
- const snapshot = runtime.getSnapshot();
204
-
205
- // Check action availability
206
- const canSubmit = runtime.checkAction('submit');
207
- // { available: true, reason: null }
208
-
209
- // Execute an action
210
- await runtime.executeAction('submit', { orderId: '123' });
211
-
212
- // Explain why a value is what it is
213
- const explanation = runtime.explain('derived.total');
214
- ```
215
-
216
- ### Expression DSL
217
-
218
- Manifesto uses a JSON-based DSL for declarative expressions.
64
+ // Define a simple schema (usually from @manifesto-ai/builder)
65
+ const schema: DomainSchema = {
66
+ version: "1.0.0",
67
+ state: {
68
+ count: { type: "number", default: 0 },
69
+ },
70
+ actions: {
71
+ increment: {
72
+ flow: {
73
+ kind: "patch",
74
+ op: "set",
75
+ path: "/data/count",
76
+ value: { kind: "add", left: { kind: "get", path: "/data/count" }, right: 1 },
77
+ },
78
+ },
79
+ },
80
+ };
219
81
 
220
- #### Comparison Operators
82
+ // Create initial snapshot
83
+ const snapshot = createSnapshot(schema);
221
84
 
222
- ```typescript
223
- { $eq: [a, b] } // a === b
224
- { $ne: [a, b] } // a !== b
225
- { $gt: [a, b] } // a > b
226
- { $gte: [a, b] } // a >= b
227
- { $lt: [a, b] } // a < b
228
- { $lte: [a, b] } // a <= b
229
- ```
85
+ // Create intent
86
+ const intent = createIntent("increment");
230
87
 
231
- #### Logical Operators
88
+ // Compute result (pure, deterministic)
89
+ const result = await core.compute(schema, snapshot, intent);
232
90
 
233
- ```typescript
234
- { $and: [expr1, expr2, ...] } // All true
235
- { $or: [expr1, expr2, ...] } // Any true
236
- { $not: expr } // Negation
91
+ console.log(result.status); // → "completed"
92
+ console.log(result.snapshot.data.count); // 1
237
93
  ```
238
94
 
239
- #### Arithmetic Operators
95
+ > See [GUIDE.md](../../docs/packages/core/GUIDE.md) for the full tutorial.
240
96
 
241
- ```typescript
242
- { $add: [a, b] } // a + b
243
- { $subtract: [a, b] } // a - b
244
- { $multiply: [a, b] } // a * b
245
- { $divide: [a, b] } // a / b
246
- { $modulo: [a, b] } // a % b
247
- ```
248
-
249
- #### String Functions
97
+ ---
250
98
 
251
- ```typescript
252
- { $concat: [str1, str2, ...] } // Concatenate strings
253
- { $upper: str } // Uppercase
254
- { $lower: str } // Lowercase
255
- { $trim: str } // Trim whitespace
256
- { $split: [str, delimiter] } // Split string
257
- { $includes: [str, search] } // Contains substring
258
- ```
99
+ ## Core API
259
100
 
260
- #### Array Functions
101
+ ### Main Exports
261
102
 
262
103
  ```typescript
263
- { $size: array } // Array length
264
- { $first: array } // First element
265
- { $last: array } // Last element
266
- { $filter: [array, predicate] } // Filter elements
267
- { $map: [array, transform] } // Transform elements
268
- { $find: [array, predicate] } // Find first match
269
- { $some: [array, predicate] } // Any match
270
- { $every: [array, predicate] } // All match
271
- { $sum: array } // Sum numbers
272
- { $reduce: [array, reducer, initial] } // Reduce array
273
- ```
104
+ // Factory
105
+ function createCore(): ManifestoCore;
274
106
 
275
- #### Conditional
107
+ // Core interface
108
+ interface ManifestoCore {
109
+ compute(schema, snapshot, intent): Promise<ComputeResult>;
110
+ apply(schema, snapshot, patches): Snapshot;
111
+ validate(schema): ValidationResult;
112
+ explain(schema, snapshot, path): ExplainResult;
113
+ }
276
114
 
277
- ```typescript
278
- { $if: [condition, thenValue, elseValue] }
115
+ // Key types
116
+ type DomainSchema = { version, state, computed?, actions?, flows?, meta? };
117
+ type Snapshot = { data, computed, system, input, meta };
118
+ type Intent = { type, input?, intentId };
119
+ type Patch = { op: "set" | "unset" | "merge", path, value? };
120
+ type ComputeResult = { status, snapshot, patches, requirements, trace };
279
121
  ```
280
122
 
281
- #### Path Reference
123
+ > See [SPEC.md](../../docs/packages/core/SPEC.md) for complete API reference.
282
124
 
283
- ```typescript
284
- { $get: 'data.user.name' } // Get value at path
285
- '$item.price' // Current item in iteration
286
- '$index' // Current index in iteration
287
- ```
125
+ ---
288
126
 
289
- ### Effect System
127
+ ## Core Concepts
290
128
 
291
- Effects describe side effects as data.
129
+ ### Snapshot as Sole Medium
292
130
 
293
- #### Effect Types
131
+ All communication between Core and Host happens through Snapshot. There is no hidden state, no suspended context, no continuation.
294
132
 
295
- ```typescript
296
- // Set a value
297
- setValue('data.count', 10)
298
- setValue('data.count', { $add: [{ $get: 'data.count' }, 1] })
133
+ ### Deterministic Computation
299
134
 
300
- // Set state
301
- setState('state.isLoading', true)
135
+ Given the same (schema, snapshot, intent), Core always produces the same result. This enables:
136
+ - Reliable testing without mocks
137
+ - Time-travel debugging
138
+ - Reproducible bug reports
302
139
 
303
- // API call
304
- apiCall({
305
- method: 'POST',
306
- url: '/api/orders',
307
- body: { $get: 'data.order' },
308
- headers: { 'Content-Type': 'application/json' }
309
- })
140
+ ### Effects as Declarations
310
141
 
311
- // Navigation
312
- navigate('/success')
142
+ 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.
313
143
 
314
- // Delay
315
- delay(1000) // milliseconds
144
+ ---
316
145
 
317
- // Emit event
318
- emitEvent('orderCreated', { orderId: '123' })
319
- ```
320
-
321
- #### Effect Composition
146
+ ## Relationship with Other Packages
322
147
 
323
- ```typescript
324
- // Sequential execution
325
- sequence([
326
- setState('state.isLoading', true),
327
- apiCall({ method: 'GET', url: '/api/data' }),
328
- setState('state.isLoading', false)
329
- ])
330
-
331
- // Parallel execution
332
- parallel([
333
- apiCall({ method: 'GET', url: '/api/user' }),
334
- apiCall({ method: 'GET', url: '/api/settings' })
335
- ])
336
-
337
- // Conditional execution
338
- conditional(
339
- { $get: 'state.isPremium' },
340
- apiCall({ method: 'GET', url: '/api/premium' }),
341
- apiCall({ method: 'GET', url: '/api/basic' })
342
- )
343
-
344
- // Error handling
345
- catchEffect(
346
- apiCall({ method: 'POST', url: '/api/submit' }),
347
- setState('state.error', { $get: 'error.message' })
348
- )
349
148
  ```
350
-
351
- #### Running Effects
352
-
353
- ```typescript
354
- import { runEffect } from '@manifesto-ai/core';
355
-
356
- const result = await runEffect(effect, runtime, {
357
- apiHandler: async (config) => {
358
- const response = await fetch(config.url, {
359
- method: config.method,
360
- body: JSON.stringify(config.body)
361
- });
362
- return response.json();
363
- }
364
- });
365
-
366
- if (isOk(result)) {
367
- console.log('Success:', result.value);
368
- } else {
369
- console.log('Error:', result.error);
370
- }
149
+ ┌─────────────┐
150
+ │ Host │ Uses Core to compute
151
+ └──────┬──────┘
152
+
153
+
154
+ ┌─────────────┐
155
+ │ CORE │
156
+ └─────────────┘
157
+
158
+
159
+ ┌─────────────┐
160
+ │ Builder │ ← Produces DomainSchema for Core
161
+ └─────────────┘
371
162
  ```
372
163
 
373
- ### Result Type
374
-
375
- A functional error handling type.
376
-
377
- ```typescript
378
- import { ok, err, isOk, isErr, map, flatMap, unwrapOr } from '@manifesto-ai/core';
164
+ | Relationship | Package | How |
165
+ |--------------|---------|-----|
166
+ | Used by | `@manifesto-ai/host` | Host calls compute() and apply() |
167
+ | Schema from | `@manifesto-ai/builder` | Builder produces DomainSchema |
379
168
 
380
- // Create results
381
- const success = ok(42);
382
- const failure = err({ code: 'NOT_FOUND', message: 'Item not found' });
169
+ ---
383
170
 
384
- // Check type
385
- if (isOk(success)) {
386
- console.log(success.value); // 42
387
- }
171
+ ## When to Use Core Directly
388
172
 
389
- // Transform
390
- const doubled = map(success, (x) => x * 2); // ok(84)
173
+ **Most users don't need to use Core directly.**
391
174
 
392
- // Chain operations
393
- const result = flatMap(success, (x) =>
394
- x > 0 ? ok(x) : err({ code: 'INVALID', message: 'Must be positive' })
395
- );
175
+ Use Core directly when:
176
+ - Building a custom Host implementation
177
+ - Testing domain logic in isolation
178
+ - Building developer tools (debuggers, visualizers)
396
179
 
397
- // Get with default
398
- const value = unwrapOr(failure, 0); // 0
399
- ```
180
+ For typical usage, see [`@manifesto-ai/react`](../react/) or [`@manifesto-ai/host`](../host/).
400
181
 
401
- ### Schema Utilities
182
+ ---
402
183
 
403
- ```typescript
404
- import {
405
- schemaToSource,
406
- validateValue,
407
- zodErrorToValidationResult,
408
- CommonSchemas
409
- } from '@manifesto-ai/core';
410
-
411
- // Common schemas
412
- CommonSchemas.email // z.string().email()
413
- CommonSchemas.phone // Phone number pattern
414
- CommonSchemas.money // Positive number with 2 decimals
415
-
416
- // Validate values
417
- const result = validateValue(userSchema, inputData);
418
- if (!result.valid) {
419
- console.log(result.issues);
420
- }
421
- ```
184
+ ## Documentation
422
185
 
423
- ## Related Packages
186
+ | Document | Purpose |
187
+ |----------|---------|
188
+ | [GUIDE.md](../../docs/packages/core/GUIDE.md) | Step-by-step usage guide |
189
+ | [SPEC.md](../../docs/packages/core/SPEC.md) | Complete specification |
190
+ | [FDR.md](../../docs/packages/core/FDR.md) | Design rationale |
424
191
 
425
- - [@manifesto-ai/bridge](../bridge) - Framework adapters
426
- - [@manifesto-ai/bridge-zustand](../bridge-zustand) - Zustand integration
427
- - [@manifesto-ai/bridge-react-hook-form](../bridge-react-hook-form) - React Hook Form integration
428
- - [@manifesto-ai/projection-ui](../projection-ui) - UI state projection
429
- - [@manifesto-ai/projection-agent](../projection-agent) - AI agent context
430
- - [@manifesto-ai/projection-graphql](../projection-graphql) - GraphQL schema generation
192
+ ---
431
193
 
432
194
  ## License
433
195
 
434
- MIT
196
+ [MIT](../../LICENSE)
@@ -0,0 +1,16 @@
1
+ import type { DomainSchema } from "../schema/domain.js";
2
+ import type { Snapshot } from "../schema/snapshot.js";
3
+ import type { Patch } from "../schema/patch.js";
4
+ /**
5
+ * Apply patches to a snapshot
6
+ *
7
+ * This function:
8
+ * 1. Applies all patches to the data
9
+ * 2. Recomputes all computed values
10
+ * 3. Increments the version number
11
+ * 4. Updates the timestamp
12
+ *
13
+ * Note: Version and timestamp are Core-owned - Host MUST NOT modify these directly.
14
+ */
15
+ export declare function apply(schema: DomainSchema, snapshot: Snapshot, patches: readonly Patch[]): Snapshot;
16
+ //# sourceMappingURL=apply.d.ts.map
@@ -0,0 +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;AAKhD;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,SAAS,KAAK,EAAE,GACxB,QAAQ,CAwCV"}
@@ -0,0 +1,52 @@
1
+ import { setByPath, unsetByPath, mergeAtPath } from "../utils/path.js";
2
+ import { evaluateComputed } from "../evaluator/computed.js";
3
+ import { isOk } from "../schema/common.js";
4
+ /**
5
+ * Apply patches to a snapshot
6
+ *
7
+ * This function:
8
+ * 1. Applies all patches to the data
9
+ * 2. Recomputes all computed values
10
+ * 3. Increments the version number
11
+ * 4. Updates the timestamp
12
+ *
13
+ * Note: Version and timestamp are Core-owned - Host MUST NOT modify these directly.
14
+ */
15
+ export function apply(schema, snapshot, patches) {
16
+ // 1. Apply patches to data
17
+ let newData = snapshot.data;
18
+ for (const patch of patches) {
19
+ switch (patch.op) {
20
+ case "set":
21
+ newData = setByPath(newData, patch.path, patch.value);
22
+ break;
23
+ case "unset":
24
+ newData = unsetByPath(newData, patch.path);
25
+ break;
26
+ case "merge":
27
+ newData = mergeAtPath(newData, patch.path, patch.value);
28
+ break;
29
+ }
30
+ }
31
+ // 2. Create intermediate snapshot with new data
32
+ const intermediateSnapshot = {
33
+ ...snapshot,
34
+ data: newData,
35
+ };
36
+ // 3. Recompute all computed values
37
+ const computedResult = evaluateComputed(schema, intermediateSnapshot);
38
+ const computed = isOk(computedResult) ? computedResult.value : snapshot.computed;
39
+ // 4. Return new snapshot with updated metadata
40
+ return {
41
+ data: newData,
42
+ computed,
43
+ system: snapshot.system,
44
+ input: snapshot.input,
45
+ meta: {
46
+ ...snapshot.meta,
47
+ version: snapshot.meta.version + 1,
48
+ timestamp: Date.now(),
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/core/apply.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,KAAK,CACnB,MAAoB,EACpB,QAAkB,EAClB,OAAyB;IAEzB,2BAA2B;IAC3B,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,QAAQ,KAAK,CAAC,EAAE,EAAE,CAAC;YACjB,KAAK,KAAK;gBACR,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtD,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3C,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACxD,MAAM;QACV,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,MAAM,oBAAoB,GAAa;QACrC,GAAG,QAAQ;QACX,IAAI,EAAE,OAAO;KACd,CAAC;IAEF,mCAAmC;IACnC,MAAM,cAAc,GAAG,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAEjF,+CAA+C;IAC/C,OAAO;QACL,IAAI,EAAE,OAAO;QACb,QAAQ;QACR,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE;YACJ,GAAG,QAAQ,CAAC,IAAI;YAChB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC;YAClC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { DomainSchema } from "../schema/domain.js";
2
+ import type { Snapshot } from "../schema/snapshot.js";
3
+ import type { Intent } from "../schema/patch.js";
4
+ import type { ComputeResult } from "../schema/result.js";
5
+ /**
6
+ * Compute the result of dispatching an intent
7
+ *
8
+ * This is the ONLY entry point for computation.
9
+ * Each call is independent - there is no suspended context.
10
+ *
11
+ * @param schema - The domain schema
12
+ * @param snapshot - Current snapshot state
13
+ * @param intent - The intent to process
14
+ * @returns ComputeResult with new snapshot, trace, and status
15
+ */
16
+ export declare function compute(schema: DomainSchema, snapshot: Snapshot, intent: Intent): Promise<ComputeResult>;
17
+ //# sourceMappingURL=compute.d.ts.map
@@ -0,0 +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;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CA6HxB"}