@manifesto-ai/core 0.2.0 → 0.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 +237 -105
- package/dist/domain/define.d.ts.map +1 -1
- package/dist/domain/define.js +17 -3
- package/dist/domain/define.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -20,14 +20,19 @@ import {
|
|
|
20
20
|
createRuntime,
|
|
21
21
|
defineDerived,
|
|
22
22
|
defineAction,
|
|
23
|
+
defineSource,
|
|
23
24
|
sequence,
|
|
24
25
|
setState,
|
|
25
|
-
|
|
26
|
+
setValue,
|
|
26
27
|
z
|
|
27
28
|
} from '@manifesto-ai/core';
|
|
28
29
|
|
|
29
30
|
// Define a domain
|
|
30
|
-
const todosDomain = defineDomain(
|
|
31
|
+
const todosDomain = defineDomain({
|
|
32
|
+
id: 'todos',
|
|
33
|
+
name: 'Todos',
|
|
34
|
+
description: 'Todo list management domain',
|
|
35
|
+
|
|
31
36
|
dataSchema: z.object({
|
|
32
37
|
items: z.array(z.object({
|
|
33
38
|
id: z.string(),
|
|
@@ -37,44 +42,61 @@ const todosDomain = defineDomain('todos', {
|
|
|
37
42
|
}),
|
|
38
43
|
|
|
39
44
|
stateSchema: z.object({
|
|
40
|
-
filter: z.enum(['all', 'active', 'completed'])
|
|
41
|
-
isLoading: z.boolean()
|
|
45
|
+
filter: z.enum(['all', 'active', 'completed']),
|
|
46
|
+
isLoading: z.boolean()
|
|
42
47
|
}),
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
'
|
|
46
|
-
|
|
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
|
-
)
|
|
49
|
+
initialState: {
|
|
50
|
+
filter: 'all',
|
|
51
|
+
isLoading: false
|
|
61
52
|
},
|
|
62
53
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
54
|
+
paths: {
|
|
55
|
+
sources: {
|
|
56
|
+
// Auto-prefixed: 'items' becomes 'data.items'
|
|
57
|
+
items: defineSource({
|
|
58
|
+
schema: z.array(z.object({
|
|
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' }
|
|
71
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' }
|
|
72
94
|
})
|
|
73
95
|
}
|
|
74
96
|
});
|
|
75
97
|
|
|
76
98
|
// Create runtime
|
|
77
|
-
const runtime = createRuntime(todosDomain);
|
|
99
|
+
const runtime = createRuntime({ domain: todosDomain });
|
|
78
100
|
|
|
79
101
|
// Use the runtime
|
|
80
102
|
runtime.set('data.items', [
|
|
@@ -88,91 +110,130 @@ console.log(runtime.get('derived.activeCount')); // 1
|
|
|
88
110
|
|
|
89
111
|
### Domain Definition
|
|
90
112
|
|
|
91
|
-
|
|
113
|
+
> **Note:** Keys in `sources`, `derived`, and `async` are auto-prefixed (`data.`, `derived.`, `async.` respectively). Keys with existing prefixes are preserved for backward compatibility. Both `activeCount` and `'derived.activeCount'` are valid.
|
|
114
|
+
|
|
115
|
+
#### `defineDomain(options)`
|
|
92
116
|
|
|
93
117
|
Creates a domain definition.
|
|
94
118
|
|
|
95
119
|
```typescript
|
|
96
|
-
const domain = defineDomain(
|
|
120
|
+
const domain = defineDomain({
|
|
121
|
+
id: 'myDomain',
|
|
122
|
+
name: 'My Domain',
|
|
123
|
+
description: 'Domain description for AI understanding',
|
|
97
124
|
dataSchema: z.object({ ... }), // Required: Source data schema
|
|
98
|
-
stateSchema: z.object({ ... }), //
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
125
|
+
stateSchema: z.object({ ... }), // Required: UI state schema
|
|
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
|
|
102
134
|
});
|
|
103
135
|
```
|
|
104
136
|
|
|
105
|
-
#### `defineSource(
|
|
137
|
+
#### `defineSource(options)`
|
|
106
138
|
|
|
107
|
-
Defines a source field with
|
|
139
|
+
Defines a source field with semantic metadata.
|
|
108
140
|
|
|
109
141
|
```typescript
|
|
110
142
|
const sources = {
|
|
111
|
-
'data.user'
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
|
|
143
|
+
// Auto-prefixed: 'user' becomes 'data.user'
|
|
144
|
+
user: defineSource({
|
|
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
|
+
})
|
|
115
152
|
};
|
|
116
153
|
```
|
|
117
154
|
|
|
118
|
-
#### `defineDerived(
|
|
155
|
+
#### `defineDerived(options)`
|
|
119
156
|
|
|
120
|
-
Defines a computed value.
|
|
157
|
+
Defines a computed value with explicit dependencies.
|
|
121
158
|
|
|
122
159
|
```typescript
|
|
123
160
|
const derived = {
|
|
124
|
-
'derived.fullName'
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
// Auto-prefixed: 'fullName' becomes 'derived.fullName'
|
|
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
|
+
})
|
|
129
170
|
};
|
|
130
171
|
```
|
|
131
172
|
|
|
132
|
-
#### `defineAsync(
|
|
173
|
+
#### `defineAsync(options)`
|
|
133
174
|
|
|
134
|
-
Defines an async data source.
|
|
175
|
+
Defines an async data source with result paths.
|
|
135
176
|
|
|
136
177
|
```typescript
|
|
137
178
|
const async = {
|
|
138
|
-
'async.userData'
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
179
|
+
// Auto-prefixed: 'userData' becomes 'async.userData'
|
|
180
|
+
userData: defineAsync({
|
|
181
|
+
deps: ['data.userId'],
|
|
182
|
+
condition: ['!=', ['get', 'data.userId'], null],
|
|
183
|
+
debounce: 300,
|
|
184
|
+
effect: {
|
|
185
|
+
_tag: 'ApiCall',
|
|
186
|
+
method: 'GET',
|
|
187
|
+
endpoint: '/api/user',
|
|
188
|
+
description: 'Fetch user data'
|
|
142
189
|
},
|
|
143
|
-
|
|
144
|
-
|
|
190
|
+
resultPath: 'state.userData',
|
|
191
|
+
loadingPath: 'state.userLoading',
|
|
192
|
+
errorPath: 'state.userError',
|
|
193
|
+
semantic: {
|
|
194
|
+
type: 'async',
|
|
195
|
+
description: 'User data from API'
|
|
196
|
+
}
|
|
197
|
+
})
|
|
145
198
|
};
|
|
146
199
|
```
|
|
147
200
|
|
|
148
|
-
#### `defineAction(
|
|
201
|
+
#### `defineAction(options)`
|
|
149
202
|
|
|
150
203
|
Defines a domain action with preconditions and effects.
|
|
151
204
|
|
|
152
205
|
```typescript
|
|
153
206
|
const actions = {
|
|
154
207
|
submit: defineAction({
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
|
|
208
|
+
deps: ['derived.total', 'state.isSubmitting'],
|
|
209
|
+
preconditions: [
|
|
210
|
+
{ path: 'derived.hasItems', expect: 'true', reason: 'Cart must have items' },
|
|
211
|
+
{ path: 'state.isSubmitting', expect: 'false', reason: 'Already submitting' }
|
|
212
|
+
],
|
|
159
213
|
effect: sequence([
|
|
160
214
|
setState('state.isSubmitting', true),
|
|
161
215
|
apiCall({ method: 'POST', url: '/api/submit' }),
|
|
162
216
|
setState('state.isSubmitting', false)
|
|
163
|
-
])
|
|
217
|
+
]),
|
|
218
|
+
semantic: {
|
|
219
|
+
type: 'action',
|
|
220
|
+
verb: 'submit',
|
|
221
|
+
description: 'Submit the order',
|
|
222
|
+
risk: 'medium'
|
|
223
|
+
}
|
|
164
224
|
})
|
|
165
225
|
};
|
|
166
226
|
```
|
|
167
227
|
|
|
168
228
|
### Runtime
|
|
169
229
|
|
|
170
|
-
#### `createRuntime(
|
|
230
|
+
#### `createRuntime(options)`
|
|
171
231
|
|
|
172
232
|
Creates a runtime instance for a domain.
|
|
173
233
|
|
|
174
234
|
```typescript
|
|
175
|
-
const runtime = createRuntime(
|
|
235
|
+
const runtime = createRuntime({
|
|
236
|
+
domain: myDomain,
|
|
176
237
|
initialData: { count: 0 },
|
|
177
238
|
initialState: { isLoading: false }
|
|
178
239
|
});
|
|
@@ -215,77 +276,148 @@ const explanation = runtime.explain('derived.total');
|
|
|
215
276
|
|
|
216
277
|
### Expression DSL
|
|
217
278
|
|
|
218
|
-
Manifesto uses a JSON-based DSL for declarative expressions.
|
|
279
|
+
Manifesto uses a JSON-based DSL for declarative expressions. All expressions use **array format**: `['operator', ...args]`.
|
|
280
|
+
|
|
281
|
+
#### Path Reference
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
['get', 'data.user.name'] // Get value at path
|
|
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
|
|
292
|
+
```
|
|
219
293
|
|
|
220
294
|
#### Comparison Operators
|
|
221
295
|
|
|
222
296
|
```typescript
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
|
229
303
|
```
|
|
230
304
|
|
|
231
305
|
#### Logical Operators
|
|
232
306
|
|
|
233
307
|
```typescript
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
308
|
+
['all', expr1, expr2, ...] // All expressions must be true (AND)
|
|
309
|
+
['any', expr1, expr2, ...] // Any expression is true (OR)
|
|
310
|
+
['!', expr] // Negation (NOT)
|
|
237
311
|
```
|
|
238
312
|
|
|
239
313
|
#### Arithmetic Operators
|
|
240
314
|
|
|
241
315
|
```typescript
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
{ $divide: [a, b] } // a / b
|
|
246
|
-
{ $modulo: [a, b] } // a % b
|
|
316
|
+
['+', a, b] // a + b
|
|
317
|
+
['-', a, b] // a - b
|
|
318
|
+
['*', a, b] // a * b
|
|
247
319
|
```
|
|
248
320
|
|
|
249
321
|
#### String Functions
|
|
250
322
|
|
|
251
323
|
```typescript
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
{ $split: [str, delimiter] } // Split string
|
|
257
|
-
{ $includes: [str, search] } // Contains substring
|
|
324
|
+
['concat', str1, str2, ...] // Concatenate strings
|
|
325
|
+
['join', array, delimiter] // Join array elements
|
|
326
|
+
['includes', str, search] // Contains substring
|
|
327
|
+
['slice', str, start, end] // Substring
|
|
258
328
|
```
|
|
259
329
|
|
|
260
330
|
#### Array Functions
|
|
261
331
|
|
|
262
332
|
```typescript
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
|
273
344
|
```
|
|
274
345
|
|
|
346
|
+
> **Note:** There is no `find` operator. Use `['at', ['filter', array, predicate], 0]` instead.
|
|
347
|
+
|
|
275
348
|
#### Conditional
|
|
276
349
|
|
|
277
350
|
```typescript
|
|
278
|
-
|
|
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]
|
|
279
374
|
```
|
|
280
375
|
|
|
281
|
-
####
|
|
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
|
|
282
384
|
|
|
283
385
|
```typescript
|
|
284
|
-
|
|
285
|
-
'
|
|
286
|
-
|
|
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']]
|
|
397
|
+
|
|
398
|
+
// Conditional value (each condition-value pair is a tuple)
|
|
399
|
+
['case',
|
|
400
|
+
[['>', ['get', 'derived.total'], 100], 'large'],
|
|
401
|
+
[['>', ['get', 'derived.total'], 50], 'medium'],
|
|
402
|
+
'small'
|
|
403
|
+
]
|
|
287
404
|
```
|
|
288
405
|
|
|
406
|
+
#### Known Limitations
|
|
407
|
+
|
|
408
|
+
1. **No object literal construction**: You cannot create new objects with dynamic values directly in expressions.
|
|
409
|
+
```typescript
|
|
410
|
+
// ❌ This does NOT work
|
|
411
|
+
['concat', ['get', 'data.items'], [{ id: ['get', 'input.id'], name: 'New' }]]
|
|
412
|
+
|
|
413
|
+
// ✅ Use pick/omit for existing objects, or handle in effect handlers
|
|
414
|
+
['pick', '$', ['id', 'name']]
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
2. **No empty object literal**: `{}` is not a valid expression. Use `['coalesce']` or handle in application code.
|
|
418
|
+
|
|
419
|
+
3. **No `find` operator**: Use `['at', ['filter', array, predicate], 0]` instead.
|
|
420
|
+
|
|
289
421
|
### Effect System
|
|
290
422
|
|
|
291
423
|
Effects describe side effects as data.
|
|
@@ -295,7 +427,7 @@ Effects describe side effects as data.
|
|
|
295
427
|
```typescript
|
|
296
428
|
// Set a value
|
|
297
429
|
setValue('data.count', 10)
|
|
298
|
-
setValue('data.count',
|
|
430
|
+
setValue('data.count', ['+', ['get', 'data.count'], 1])
|
|
299
431
|
|
|
300
432
|
// Set state
|
|
301
433
|
setState('state.isLoading', true)
|
|
@@ -304,7 +436,7 @@ setState('state.isLoading', true)
|
|
|
304
436
|
apiCall({
|
|
305
437
|
method: 'POST',
|
|
306
438
|
url: '/api/orders',
|
|
307
|
-
body:
|
|
439
|
+
body: ['get', 'data.order'],
|
|
308
440
|
headers: { 'Content-Type': 'application/json' }
|
|
309
441
|
})
|
|
310
442
|
|
|
@@ -336,7 +468,7 @@ parallel([
|
|
|
336
468
|
|
|
337
469
|
// Conditional execution
|
|
338
470
|
conditional(
|
|
339
|
-
|
|
471
|
+
['get', 'state.isPremium'],
|
|
340
472
|
apiCall({ method: 'GET', url: '/api/premium' }),
|
|
341
473
|
apiCall({ method: 'GET', url: '/api/basic' })
|
|
342
474
|
)
|
|
@@ -344,7 +476,7 @@ conditional(
|
|
|
344
476
|
// Error handling
|
|
345
477
|
catchEffect(
|
|
346
478
|
apiCall({ method: 'POST', url: '/api/submit' }),
|
|
347
|
-
setState('state.error',
|
|
479
|
+
setState('state.error', ['get', 'error.message'])
|
|
348
480
|
)
|
|
349
481
|
```
|
|
350
482
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/domain/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,KAAK,EAAE,MAAM,IAAI;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/domain/define.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/define.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds namespace prefix to keys if not already present.
|
|
3
|
+
* Supports nested paths (e.g., 'user.name' → 'data.user.name').
|
|
4
|
+
*/
|
|
5
|
+
function prefixKeys(record, prefix) {
|
|
6
|
+
if (!record)
|
|
7
|
+
return {};
|
|
8
|
+
const result = {};
|
|
9
|
+
for (const [key, value] of Object.entries(record)) {
|
|
10
|
+
const prefixedKey = key.startsWith(`${prefix}.`) ? key : `${prefix}.${key}`;
|
|
11
|
+
result[prefixedKey] = value;
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
1
15
|
/**
|
|
2
16
|
* 도메인 정의 헬퍼 함수
|
|
3
17
|
*/
|
|
@@ -10,9 +24,9 @@ export function defineDomain(options) {
|
|
|
10
24
|
stateSchema: options.stateSchema,
|
|
11
25
|
initialState: options.initialState,
|
|
12
26
|
paths: {
|
|
13
|
-
sources: options.paths?.sources
|
|
14
|
-
derived: options.paths?.derived
|
|
15
|
-
async: options.paths?.async
|
|
27
|
+
sources: prefixKeys(options.paths?.sources, 'data'),
|
|
28
|
+
derived: prefixKeys(options.paths?.derived, 'derived'),
|
|
29
|
+
async: prefixKeys(options.paths?.async, 'async'),
|
|
16
30
|
},
|
|
17
31
|
actions: options.actions ?? {},
|
|
18
32
|
meta: options.meta,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/domain/define.ts"],"names":[],"mappings":"AAiCA;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA2C;IAE3C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,KAAK,EAAE;YACL,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/domain/define.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manifesto-ai/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "AI Native Semantic Layer for SaaS Business Logic",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,14 +17,6 @@
|
|
|
17
17
|
"README.md",
|
|
18
18
|
"LICENSE"
|
|
19
19
|
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsc",
|
|
22
|
-
"test": "vitest run",
|
|
23
|
-
"test:watch": "vitest",
|
|
24
|
-
"test:coverage": "vitest run --coverage",
|
|
25
|
-
"typecheck": "tsc --noEmit",
|
|
26
|
-
"clean": "rm -rf dist"
|
|
27
|
-
},
|
|
28
20
|
"keywords": [
|
|
29
21
|
"manifesto",
|
|
30
22
|
"ai",
|
|
@@ -54,5 +46,13 @@
|
|
|
54
46
|
"@vitest/coverage-v8": "^2.1.9",
|
|
55
47
|
"typescript": "^5.7.2",
|
|
56
48
|
"vitest": "^2.1.9"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"test:coverage": "vitest run --coverage",
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"clean": "rm -rf dist"
|
|
57
57
|
}
|
|
58
|
-
}
|
|
58
|
+
}
|