@manifesto-ai/sdk 2.3.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -29
- package/dist/chunk-NGW654NU.js +375 -0
- package/dist/chunk-NGW654NU.js.map +1 -0
- package/dist/create-manifesto.d.ts +3 -0
- package/dist/errors.d.ts +37 -0
- package/dist/index.d.ts +12 -422
- package/dist/index.js +265 -376
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +51 -0
- package/dist/internal.js +25 -0
- package/dist/internal.js.map +1 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/types.d.ts +113 -0
- package/package.json +11 -8
package/dist/index.js
CHANGED
|
@@ -1,240 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTION_PARAM_NAMES,
|
|
3
|
+
AlreadyActivatedError,
|
|
4
|
+
CompileError,
|
|
5
|
+
DisposedError,
|
|
6
|
+
ManifestoError,
|
|
7
|
+
ReservedEffectError,
|
|
8
|
+
activateComposable,
|
|
9
|
+
attachRuntimeKernelFactory,
|
|
10
|
+
createBaseRuntimeInstance,
|
|
11
|
+
createRuntimeKernel
|
|
12
|
+
} from "./chunk-NGW654NU.js";
|
|
13
|
+
|
|
1
14
|
// src/create-manifesto.ts
|
|
2
15
|
import {
|
|
3
16
|
createHost
|
|
4
17
|
} from "@manifesto-ai/host";
|
|
5
18
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
19
|
+
createIntent as createCoreIntent,
|
|
20
|
+
extractDefaults,
|
|
21
|
+
hashSchemaSync,
|
|
22
|
+
semanticPathToPatchPath
|
|
10
23
|
} from "@manifesto-ai/core";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
constructor(code, message, options) {
|
|
17
|
-
super(message, options);
|
|
18
|
-
this.name = "ManifestoError";
|
|
19
|
-
this.code = code;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
var ReservedEffectError = class extends ManifestoError {
|
|
23
|
-
effectType;
|
|
24
|
-
constructor(effectType) {
|
|
25
|
-
super(
|
|
26
|
-
"RESERVED_EFFECT",
|
|
27
|
-
`Effect type "${effectType}" is reserved and cannot be overridden`
|
|
28
|
-
);
|
|
29
|
-
this.name = "ReservedEffectError";
|
|
30
|
-
this.effectType = effectType;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
var CompileError = class extends ManifestoError {
|
|
34
|
-
diagnostics;
|
|
35
|
-
constructor(diagnostics, formattedMessage) {
|
|
36
|
-
super("COMPILE_ERROR", formattedMessage);
|
|
37
|
-
this.name = "CompileError";
|
|
38
|
-
this.diagnostics = diagnostics;
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
var DisposedError = class extends ManifestoError {
|
|
42
|
-
constructor() {
|
|
43
|
-
super("DISPOSED", "Cannot dispatch on a disposed ManifestoInstance");
|
|
44
|
-
this.name = "DisposedError";
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// src/create-manifesto.ts
|
|
24
|
+
import {
|
|
25
|
+
compileMelDomain,
|
|
26
|
+
parse as parseMel,
|
|
27
|
+
tokenize as tokenizeMel
|
|
28
|
+
} from "@manifesto-ai/compiler";
|
|
49
29
|
var RESERVED_EFFECT_TYPE = "system.get";
|
|
50
30
|
var RESERVED_NAMESPACE_PREFIX = "system.";
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (RESERVED_EFFECT_TYPE in
|
|
31
|
+
var BASE_LAWS = Object.freeze({ __baseLaws: true });
|
|
32
|
+
function createManifesto(schemaInput, effects) {
|
|
33
|
+
if (RESERVED_EFFECT_TYPE in effects) {
|
|
54
34
|
throw new ReservedEffectError(RESERVED_EFFECT_TYPE);
|
|
55
35
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
36
|
+
const resolved = resolveSchema(schemaInput);
|
|
37
|
+
validateReservedNamespaces(resolved.schema);
|
|
38
|
+
const manifesto = {
|
|
39
|
+
_laws: BASE_LAWS,
|
|
40
|
+
schema: resolved.schema,
|
|
41
|
+
activate() {
|
|
42
|
+
activateComposable(manifesto);
|
|
43
|
+
return createBaseRuntimeInstance(
|
|
44
|
+
createRuntimeKernel({
|
|
45
|
+
schema: resolved.schema,
|
|
46
|
+
host: createInternalHost(resolved.schema, effects),
|
|
47
|
+
MEL: buildTypedMel(resolved.schema, resolved.actionParamMetadata),
|
|
48
|
+
createIntent: buildCreateIntent()
|
|
49
|
+
})
|
|
50
|
+
);
|
|
67
51
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
52
|
+
};
|
|
53
|
+
return attachRuntimeKernelFactory(
|
|
54
|
+
manifesto,
|
|
55
|
+
() => createRuntimeKernel({
|
|
56
|
+
schema: resolved.schema,
|
|
57
|
+
host: createInternalHost(resolved.schema, effects),
|
|
58
|
+
MEL: buildTypedMel(resolved.schema, resolved.actionParamMetadata),
|
|
59
|
+
createIntent: buildCreateIntent()
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function resolveSchema(schema) {
|
|
64
|
+
const resolved = typeof schema === "string" ? compileSchema(schema) : {
|
|
65
|
+
schema,
|
|
66
|
+
actionParamMetadata: deriveActionParamMetadata(schema)
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
schema: withPlatformNamespaces(resolved.schema),
|
|
70
|
+
actionParamMetadata: resolved.actionParamMetadata
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function compileSchema(source) {
|
|
74
|
+
const result = compileMelDomain(source, { mode: "domain" });
|
|
75
|
+
if (result.errors.length > 0) {
|
|
76
|
+
const formatted = result.errors.map((diagnostic) => {
|
|
77
|
+
const loc = diagnostic.location;
|
|
78
|
+
if (!loc || loc.start.line === 0 && loc.start.column === 0) {
|
|
79
|
+
return `[${diagnostic.code}] ${diagnostic.message}`;
|
|
95
80
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
currentSnapshot = result.snapshot;
|
|
101
|
-
notifySubscribers();
|
|
102
|
-
emitEvent("dispatch:failed", {
|
|
103
|
-
intentId: intent.intentId,
|
|
104
|
-
intent,
|
|
105
|
-
error: result.error ?? new ManifestoError("HOST_ERROR", "Host dispatch failed")
|
|
106
|
-
});
|
|
107
|
-
return;
|
|
81
|
+
const header = `[${diagnostic.code}] ${diagnostic.message} (${loc.start.line}:${loc.start.column})`;
|
|
82
|
+
const line = source.split("\n")[loc.start.line - 1];
|
|
83
|
+
if (!line) {
|
|
84
|
+
return header;
|
|
108
85
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
function subscribe(selector, listener) {
|
|
125
|
-
if (disposed) return () => {
|
|
126
|
-
};
|
|
127
|
-
const sub = {
|
|
128
|
-
selector,
|
|
129
|
-
listener,
|
|
130
|
-
lastValue: selector(currentSnapshot),
|
|
131
|
-
initialized: true
|
|
132
|
-
};
|
|
133
|
-
subscribers.add(sub);
|
|
134
|
-
return () => {
|
|
135
|
-
subscribers.delete(sub);
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
function on(event, handler) {
|
|
139
|
-
if (disposed) return () => {
|
|
140
|
-
};
|
|
141
|
-
let listeners = eventListeners.get(event);
|
|
142
|
-
if (!listeners) {
|
|
143
|
-
listeners = /* @__PURE__ */ new Set();
|
|
144
|
-
eventListeners.set(event, listeners);
|
|
145
|
-
}
|
|
146
|
-
listeners.add(handler);
|
|
147
|
-
return () => {
|
|
148
|
-
listeners.delete(handler);
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
function isActionAvailable(actionName) {
|
|
152
|
-
return queryActionAvailable(schema, currentSnapshot, actionName);
|
|
153
|
-
}
|
|
154
|
-
function getAvailableActions() {
|
|
155
|
-
return queryAvailableActions(schema, currentSnapshot);
|
|
156
|
-
}
|
|
157
|
-
function getSnapshot() {
|
|
158
|
-
return Object.freeze(structuredClone(currentSnapshot));
|
|
159
|
-
}
|
|
160
|
-
function dispose() {
|
|
161
|
-
if (disposed) return;
|
|
162
|
-
disposed = true;
|
|
163
|
-
subscribers.clear();
|
|
164
|
-
eventListeners.clear();
|
|
165
|
-
}
|
|
166
|
-
function notifySubscribers() {
|
|
167
|
-
const frozenSnap = Object.freeze(structuredClone(currentSnapshot));
|
|
168
|
-
for (const sub of subscribers) {
|
|
169
|
-
const selected = sub.selector(frozenSnap);
|
|
170
|
-
if (sub.initialized && Object.is(sub.lastValue, selected)) {
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
sub.lastValue = selected;
|
|
174
|
-
sub.initialized = true;
|
|
175
|
-
sub.listener(selected);
|
|
176
|
-
}
|
|
86
|
+
const lineNum = String(loc.start.line).padStart(4, " ");
|
|
87
|
+
const underlineLen = Math.max(
|
|
88
|
+
1,
|
|
89
|
+
loc.end.line === loc.start.line ? Math.min(loc.end.column - loc.start.column, Math.max(1, line.length - loc.start.column + 1)) : 1
|
|
90
|
+
);
|
|
91
|
+
const padding = " ".repeat(lineNum.length + 3 + loc.start.column - 1);
|
|
92
|
+
return `${header}
|
|
93
|
+
${lineNum} | ${line}
|
|
94
|
+
${padding}${"^".repeat(underlineLen)}`;
|
|
95
|
+
}).join("\n\n");
|
|
96
|
+
throw new CompileError(result.errors, `MEL compilation failed:
|
|
97
|
+
${formatted}`);
|
|
177
98
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (!listeners) return;
|
|
181
|
-
for (const handler of listeners) {
|
|
182
|
-
try {
|
|
183
|
-
handler(payload);
|
|
184
|
-
} catch {
|
|
185
|
-
}
|
|
186
|
-
}
|
|
99
|
+
if (!result.schema) {
|
|
100
|
+
throw new ManifestoError("COMPILE_ERROR", "MEL compilation produced no schema");
|
|
187
101
|
}
|
|
102
|
+
const schema = result.schema;
|
|
188
103
|
return {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
getSnapshot,
|
|
195
|
-
dispose
|
|
104
|
+
schema,
|
|
105
|
+
actionParamMetadata: deriveActionParamMetadata(
|
|
106
|
+
schema,
|
|
107
|
+
extractActionParamOrderFromMel(source)
|
|
108
|
+
)
|
|
196
109
|
};
|
|
197
110
|
}
|
|
198
|
-
function resolveSchema(schema) {
|
|
199
|
-
let domainSchema;
|
|
200
|
-
if (typeof schema === "string") {
|
|
201
|
-
const result = compileMelDomain(schema, { mode: "domain" });
|
|
202
|
-
if (result.errors.length > 0) {
|
|
203
|
-
const formatted = result.errors.map((d) => {
|
|
204
|
-
const loc = d.location;
|
|
205
|
-
const header = loc && (loc.start.line > 0 || loc.start.column > 0) ? `[${d.code}] ${d.message} (${loc.start.line}:${loc.start.column})` : `[${d.code}] ${d.message}`;
|
|
206
|
-
if (!loc || loc.start.line === 0) return header;
|
|
207
|
-
const sourceLines = schema.split("\n");
|
|
208
|
-
const lineContent = sourceLines[loc.start.line - 1];
|
|
209
|
-
if (!lineContent) return header;
|
|
210
|
-
const lineNumStr = String(loc.start.line).padStart(4, " ");
|
|
211
|
-
const underlineLen = Math.max(
|
|
212
|
-
1,
|
|
213
|
-
loc.end.line === loc.start.line ? Math.min(loc.end.column - loc.start.column, lineContent.length - loc.start.column + 1) : 1
|
|
214
|
-
);
|
|
215
|
-
const padding = " ".repeat(lineNumStr.length + 3 + loc.start.column - 1);
|
|
216
|
-
return `${header}
|
|
217
|
-
${lineNumStr} | ${lineContent}
|
|
218
|
-
${padding}${"^".repeat(underlineLen)}`;
|
|
219
|
-
}).join("\n\n");
|
|
220
|
-
throw new CompileError(
|
|
221
|
-
result.errors,
|
|
222
|
-
`MEL compilation failed:
|
|
223
|
-
${formatted}`
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
if (!result.schema) {
|
|
227
|
-
throw new ManifestoError(
|
|
228
|
-
"COMPILE_ERROR",
|
|
229
|
-
"MEL compilation produced no schema"
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
domainSchema = result.schema;
|
|
233
|
-
} else {
|
|
234
|
-
domainSchema = schema;
|
|
235
|
-
}
|
|
236
|
-
return withPlatformNamespaces(domainSchema);
|
|
237
|
-
}
|
|
238
111
|
function withPlatformNamespaces(schema) {
|
|
239
112
|
const fields = { ...schema.state.fields };
|
|
240
113
|
let changed = false;
|
|
@@ -246,10 +119,7 @@ function withPlatformNamespaces(schema) {
|
|
|
246
119
|
};
|
|
247
120
|
changed = true;
|
|
248
121
|
} else if (fields.$host.type !== "object") {
|
|
249
|
-
throw new ManifestoError(
|
|
250
|
-
"SCHEMA_ERROR",
|
|
251
|
-
"Reserved namespace '$host' must be an object field"
|
|
252
|
-
);
|
|
122
|
+
throw new ManifestoError("SCHEMA_ERROR", "Reserved namespace '$host' must be an object field");
|
|
253
123
|
} else if (fields.$host.default === void 0) {
|
|
254
124
|
fields.$host = { ...fields.$host, default: {} };
|
|
255
125
|
changed = true;
|
|
@@ -276,10 +146,7 @@ function withPlatformNamespaces(schema) {
|
|
|
276
146
|
};
|
|
277
147
|
changed = true;
|
|
278
148
|
} else if (fields.$mel.type !== "object") {
|
|
279
|
-
throw new ManifestoError(
|
|
280
|
-
"SCHEMA_ERROR",
|
|
281
|
-
"Reserved namespace '$mel' must be an object field"
|
|
282
|
-
);
|
|
149
|
+
throw new ManifestoError("SCHEMA_ERROR", "Reserved namespace '$mel' must be an object field");
|
|
283
150
|
} else {
|
|
284
151
|
let nextMel = fields.$mel;
|
|
285
152
|
if (nextMel.default === void 0) {
|
|
@@ -309,13 +176,10 @@ function withPlatformNamespaces(schema) {
|
|
|
309
176
|
};
|
|
310
177
|
changed = true;
|
|
311
178
|
} else if (guardsField.type !== "object") {
|
|
312
|
-
throw new ManifestoError(
|
|
313
|
-
"SCHEMA_ERROR",
|
|
314
|
-
"Reserved namespace '$mel.guards' must be an object field"
|
|
315
|
-
);
|
|
179
|
+
throw new ManifestoError("SCHEMA_ERROR", "Reserved namespace '$mel.guards' must be an object field");
|
|
316
180
|
} else {
|
|
317
181
|
let nextGuards = guardsField;
|
|
318
|
-
if (
|
|
182
|
+
if (nextGuards.default === void 0) {
|
|
319
183
|
nextGuards = { ...nextGuards, default: { intent: {} } };
|
|
320
184
|
changed = true;
|
|
321
185
|
}
|
|
@@ -335,10 +199,7 @@ function withPlatformNamespaces(schema) {
|
|
|
335
199
|
};
|
|
336
200
|
changed = true;
|
|
337
201
|
} else if (intentField.type !== "object") {
|
|
338
|
-
throw new ManifestoError(
|
|
339
|
-
"SCHEMA_ERROR",
|
|
340
|
-
"Reserved namespace '$mel.guards.intent' must be an object field"
|
|
341
|
-
);
|
|
202
|
+
throw new ManifestoError("SCHEMA_ERROR", "Reserved namespace '$mel.guards.intent' must be an object field");
|
|
342
203
|
} else if (intentField.default === void 0) {
|
|
343
204
|
nextGuards = {
|
|
344
205
|
...nextGuards,
|
|
@@ -361,21 +222,26 @@ function withPlatformNamespaces(schema) {
|
|
|
361
222
|
}
|
|
362
223
|
if (nextMel !== fields.$mel) {
|
|
363
224
|
fields.$mel = nextMel;
|
|
364
|
-
changed = true;
|
|
365
225
|
}
|
|
366
226
|
}
|
|
367
|
-
if (!changed)
|
|
368
|
-
|
|
227
|
+
if (!changed) {
|
|
228
|
+
return schema;
|
|
229
|
+
}
|
|
230
|
+
const nextSchema = {
|
|
369
231
|
...schema,
|
|
370
232
|
state: {
|
|
371
233
|
...schema.state,
|
|
372
234
|
fields
|
|
373
235
|
}
|
|
374
236
|
};
|
|
237
|
+
const { hash: _hash, ...schemaWithoutHash } = nextSchema;
|
|
238
|
+
return {
|
|
239
|
+
...nextSchema,
|
|
240
|
+
hash: hashSchemaSync(schemaWithoutHash)
|
|
241
|
+
};
|
|
375
242
|
}
|
|
376
243
|
function validateReservedNamespaces(schema) {
|
|
377
|
-
const
|
|
378
|
-
for (const actionType of Object.keys(actions)) {
|
|
244
|
+
for (const actionType of Object.keys(schema.actions ?? {})) {
|
|
379
245
|
if (actionType.startsWith(RESERVED_NAMESPACE_PREFIX)) {
|
|
380
246
|
throw new ManifestoError(
|
|
381
247
|
"RESERVED_NAMESPACE",
|
|
@@ -384,21 +250,131 @@ function validateReservedNamespaces(schema) {
|
|
|
384
250
|
}
|
|
385
251
|
}
|
|
386
252
|
}
|
|
387
|
-
function
|
|
388
|
-
const
|
|
389
|
-
|
|
253
|
+
function buildTypedMel(schema, actionParamMetadata) {
|
|
254
|
+
const actions = Object.fromEntries(
|
|
255
|
+
Object.keys(schema.actions).map((name) => {
|
|
256
|
+
const ref = {
|
|
257
|
+
__kind: "ActionRef",
|
|
258
|
+
name
|
|
259
|
+
};
|
|
260
|
+
Object.defineProperty(ref, ACTION_PARAM_NAMES, {
|
|
261
|
+
enumerable: false,
|
|
262
|
+
configurable: false,
|
|
263
|
+
writable: false,
|
|
264
|
+
value: Object.hasOwn(actionParamMetadata, name) ? actionParamMetadata[name] : []
|
|
265
|
+
});
|
|
266
|
+
return [name, Object.freeze(ref)];
|
|
267
|
+
})
|
|
268
|
+
);
|
|
269
|
+
const state = Object.fromEntries(
|
|
270
|
+
Object.keys(schema.state.fields).filter((name) => !name.startsWith("$")).map((name) => [name, Object.freeze({
|
|
271
|
+
__kind: "FieldRef",
|
|
272
|
+
path: name
|
|
273
|
+
})])
|
|
274
|
+
);
|
|
275
|
+
const computed = Object.fromEntries(
|
|
276
|
+
Object.keys(schema.computed.fields).map((name) => [name, Object.freeze({
|
|
277
|
+
__kind: "ComputedRef",
|
|
278
|
+
path: name
|
|
279
|
+
})])
|
|
280
|
+
);
|
|
281
|
+
return Object.freeze({
|
|
282
|
+
actions: Object.freeze(actions),
|
|
283
|
+
state: Object.freeze(state),
|
|
284
|
+
computed: Object.freeze(computed)
|
|
390
285
|
});
|
|
391
|
-
|
|
392
|
-
|
|
286
|
+
}
|
|
287
|
+
function buildCreateIntent() {
|
|
288
|
+
return (action, ...args) => {
|
|
289
|
+
const actionRef = action;
|
|
290
|
+
const intentId = generateUUID();
|
|
291
|
+
const input = packIntentInput(actionRef, args);
|
|
292
|
+
return createCoreIntent(
|
|
293
|
+
String(action.name),
|
|
294
|
+
input,
|
|
295
|
+
intentId
|
|
296
|
+
);
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
function getActionParamNames(input) {
|
|
300
|
+
if (!input || input.type !== "object" || !input.fields) {
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
return Object.keys(input.fields);
|
|
304
|
+
}
|
|
305
|
+
function deriveActionParamMetadata(schema, actionParamOrder) {
|
|
306
|
+
return Object.freeze(Object.fromEntries(
|
|
307
|
+
Object.entries(schema.actions).map(([name, action]) => {
|
|
308
|
+
const preferredOrder = actionParamOrder?.[name];
|
|
309
|
+
if (preferredOrder && preferredOrder.length > 0) {
|
|
310
|
+
return [name, Object.freeze([...preferredOrder])];
|
|
311
|
+
}
|
|
312
|
+
if (!action.input || action.input.type !== "object" || !action.input.fields) {
|
|
313
|
+
return [name, []];
|
|
314
|
+
}
|
|
315
|
+
const fieldNames = getActionParamNames(action.input);
|
|
316
|
+
return [name, fieldNames.length <= 1 ? fieldNames : null];
|
|
317
|
+
})
|
|
318
|
+
));
|
|
319
|
+
}
|
|
320
|
+
function extractActionParamOrderFromMel(source) {
|
|
321
|
+
const lexed = tokenizeMel(source);
|
|
322
|
+
if (lexed.diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
323
|
+
return void 0;
|
|
324
|
+
}
|
|
325
|
+
const parsed = parseMel(lexed.tokens);
|
|
326
|
+
if (!parsed.program) {
|
|
327
|
+
return void 0;
|
|
328
|
+
}
|
|
329
|
+
return Object.freeze(Object.fromEntries(
|
|
330
|
+
parsed.program.domain.members.filter((member) => member.kind === "action").map((action) => [action.name, Object.freeze(action.params.map((param) => param.name))])
|
|
331
|
+
));
|
|
332
|
+
}
|
|
333
|
+
function packIntentInput(action, args) {
|
|
334
|
+
const paramNames = Object.hasOwn(action, ACTION_PARAM_NAMES) ? action[ACTION_PARAM_NAMES] : [];
|
|
335
|
+
if (args.length === 0) {
|
|
336
|
+
return void 0;
|
|
337
|
+
}
|
|
338
|
+
if (paramNames === null) {
|
|
339
|
+
if (args.length === 1 && isPlainObject(args[0])) {
|
|
340
|
+
return args[0];
|
|
341
|
+
}
|
|
342
|
+
throw new ManifestoError(
|
|
343
|
+
"INVALID_INTENT_ARGS",
|
|
344
|
+
`Action "${String(action.name)}" requires a single object argument because positional parameter metadata is unavailable`
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
if (paramNames.length === 0) {
|
|
348
|
+
if (args.length === 1) {
|
|
349
|
+
return args[0];
|
|
350
|
+
}
|
|
351
|
+
throw new ManifestoError(
|
|
352
|
+
"INVALID_INTENT_ARGS",
|
|
353
|
+
`Action "${String(action.name)}" does not accept multiple positional arguments`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
if (args.length === 1 && isPlainObject(args[0]) && paramNames.length > 1) {
|
|
357
|
+
return args[0];
|
|
393
358
|
}
|
|
359
|
+
return Object.fromEntries(args.map((value, index) => [
|
|
360
|
+
paramNames[index] ?? `arg${index}`,
|
|
361
|
+
value
|
|
362
|
+
]));
|
|
363
|
+
}
|
|
364
|
+
function isPlainObject(value) {
|
|
365
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
366
|
+
}
|
|
367
|
+
function createInternalHost(schema, effects) {
|
|
368
|
+
const host = createHost(schema, {
|
|
369
|
+
initialData: extractDefaults(schema.state)
|
|
370
|
+
});
|
|
394
371
|
host.registerEffect(RESERVED_EFFECT_TYPE, async (_type, params, ctx) => {
|
|
395
372
|
const { patches } = executeSystemGet(params, ctx.snapshot);
|
|
396
373
|
return patches;
|
|
397
374
|
});
|
|
398
375
|
for (const [effectType, appHandler] of Object.entries(effects)) {
|
|
399
376
|
const hostHandler = async (_type, params, ctx) => {
|
|
400
|
-
const
|
|
401
|
-
const patches = await appHandler(params, appCtx);
|
|
377
|
+
const patches = await appHandler(params, { snapshot: freezeSnapshot(ctx.snapshot) });
|
|
402
378
|
return patches;
|
|
403
379
|
};
|
|
404
380
|
host.registerEffect(effectType, hostHandler);
|
|
@@ -408,6 +384,29 @@ function createInternalHost(schema, effects, initialSnapshot) {
|
|
|
408
384
|
function isGenerateParams(params) {
|
|
409
385
|
return typeof params === "object" && params !== null && "key" in params && "into" in params;
|
|
410
386
|
}
|
|
387
|
+
function executeSystemGet(params, snapshot) {
|
|
388
|
+
if (isGenerateParams(params)) {
|
|
389
|
+
return {
|
|
390
|
+
patches: [{
|
|
391
|
+
op: "set",
|
|
392
|
+
path: normalizeTargetPath(params.into),
|
|
393
|
+
value: generateSystemValue(params.key)
|
|
394
|
+
}]
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
const { path, target } = params;
|
|
398
|
+
const result = resolvePathValue(path, snapshot);
|
|
399
|
+
if (!target) {
|
|
400
|
+
return { patches: [] };
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
patches: [{
|
|
404
|
+
op: "set",
|
|
405
|
+
path: normalizeTargetPath(target),
|
|
406
|
+
value: result.value
|
|
407
|
+
}]
|
|
408
|
+
};
|
|
409
|
+
}
|
|
411
410
|
function generateSystemValue(key) {
|
|
412
411
|
switch (key) {
|
|
413
412
|
case "uuid":
|
|
@@ -421,37 +420,10 @@ function generateSystemValue(key) {
|
|
|
421
420
|
return null;
|
|
422
421
|
}
|
|
423
422
|
}
|
|
424
|
-
function
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
429
|
-
const r = Math.random() * 16 | 0;
|
|
430
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
431
|
-
return v.toString(16);
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
function executeSystemGet(params, snapshot) {
|
|
435
|
-
if (isGenerateParams(params)) {
|
|
436
|
-
const value = generateSystemValue(params.key);
|
|
437
|
-
const patches2 = [{
|
|
438
|
-
op: "set",
|
|
439
|
-
path: normalizeTargetPath(params.into),
|
|
440
|
-
value
|
|
441
|
-
}];
|
|
442
|
-
return { patches: patches2 };
|
|
443
|
-
}
|
|
444
|
-
const { path, target } = params;
|
|
445
|
-
const result = resolvePathValue(path, snapshot);
|
|
446
|
-
const patches = [];
|
|
447
|
-
if (target) {
|
|
448
|
-
patches.push({
|
|
449
|
-
op: "set",
|
|
450
|
-
path: normalizeTargetPath(target),
|
|
451
|
-
value: result.value
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
return { patches };
|
|
423
|
+
function normalizeTargetPath(path) {
|
|
424
|
+
const normalized = normalizePath(path);
|
|
425
|
+
const withoutDataRoot = normalized.startsWith("data.") ? normalized.slice("data.".length) : normalized;
|
|
426
|
+
return semanticPathToPatchPath(withoutDataRoot);
|
|
455
427
|
}
|
|
456
428
|
function normalizePath(path) {
|
|
457
429
|
if (path.startsWith("/")) {
|
|
@@ -459,19 +431,13 @@ function normalizePath(path) {
|
|
|
459
431
|
}
|
|
460
432
|
return path;
|
|
461
433
|
}
|
|
462
|
-
function normalizeTargetPath(path) {
|
|
463
|
-
const normalized = normalizePath(path);
|
|
464
|
-
const withoutDataRoot = normalized.startsWith("data.") ? normalized.slice("data.".length) : normalized;
|
|
465
|
-
return semanticPathToPatchPath(withoutDataRoot);
|
|
466
|
-
}
|
|
467
434
|
function resolvePathValue(path, snapshot) {
|
|
468
435
|
const normalized = normalizePath(path);
|
|
469
436
|
const parts = normalized.split(".");
|
|
470
437
|
if (parts.length === 0) {
|
|
471
438
|
return { value: void 0, found: false };
|
|
472
439
|
}
|
|
473
|
-
const root = parts
|
|
474
|
-
const rest = parts.slice(1);
|
|
440
|
+
const [root, ...rest] = parts;
|
|
475
441
|
let current;
|
|
476
442
|
switch (root) {
|
|
477
443
|
case "data":
|
|
@@ -489,116 +455,39 @@ function resolvePathValue(path, snapshot) {
|
|
|
489
455
|
default:
|
|
490
456
|
current = snapshot.data;
|
|
491
457
|
rest.unshift(root);
|
|
458
|
+
break;
|
|
492
459
|
}
|
|
493
460
|
for (const part of rest) {
|
|
494
|
-
if (current === null || current === void 0) {
|
|
495
|
-
return { value: void 0, found: false };
|
|
496
|
-
}
|
|
497
|
-
if (typeof current !== "object") {
|
|
461
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
498
462
|
return { value: void 0, found: false };
|
|
499
463
|
}
|
|
500
464
|
current = current[part];
|
|
501
465
|
}
|
|
502
466
|
return { value: current, found: current !== void 0 };
|
|
503
467
|
}
|
|
504
|
-
function
|
|
505
|
-
return
|
|
468
|
+
function freezeSnapshot(snapshot) {
|
|
469
|
+
return Object.freeze(structuredClone(snapshot));
|
|
506
470
|
}
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
var DispatchRejectedError = class extends Error {
|
|
510
|
-
code = "DISPATCH_REJECTED";
|
|
511
|
-
intentId;
|
|
512
|
-
constructor(intentId, reason) {
|
|
513
|
-
super(reason ?? "Intent was rejected by guard");
|
|
514
|
-
this.name = "DispatchRejectedError";
|
|
515
|
-
this.intentId = intentId;
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
|
-
function dispatchAsync(instance, intent) {
|
|
519
|
-
const intentId = intent.intentId ?? generateId();
|
|
520
|
-
const enriched = intent.intentId ? intent : { ...intent, intentId };
|
|
521
|
-
return new Promise((resolve, reject) => {
|
|
522
|
-
const cleanup = () => {
|
|
523
|
-
unsubCompleted();
|
|
524
|
-
unsubFailed();
|
|
525
|
-
unsubRejected();
|
|
526
|
-
};
|
|
527
|
-
const unsubCompleted = instance.on("dispatch:completed", (e) => {
|
|
528
|
-
if (e.intentId === intentId) {
|
|
529
|
-
cleanup();
|
|
530
|
-
resolve(e.snapshot);
|
|
531
|
-
}
|
|
532
|
-
});
|
|
533
|
-
const unsubFailed = instance.on("dispatch:failed", (e) => {
|
|
534
|
-
if (e.intentId === intentId) {
|
|
535
|
-
cleanup();
|
|
536
|
-
reject(e.error ?? new Error("Dispatch failed"));
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
const unsubRejected = instance.on("dispatch:rejected", (e) => {
|
|
540
|
-
if (e.intentId === intentId) {
|
|
541
|
-
cleanup();
|
|
542
|
-
reject(new DispatchRejectedError(intentId, e.reason));
|
|
543
|
-
}
|
|
544
|
-
});
|
|
545
|
-
instance.dispatch(enriched);
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
function generateId() {
|
|
549
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
471
|
+
function generateUUID() {
|
|
472
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
550
473
|
return crypto.randomUUID();
|
|
551
474
|
}
|
|
552
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (
|
|
553
|
-
const
|
|
554
|
-
const
|
|
555
|
-
return
|
|
475
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
476
|
+
const random = Math.random() * 16 | 0;
|
|
477
|
+
const value = char === "x" ? random : random & 3 | 8;
|
|
478
|
+
return value.toString(16);
|
|
556
479
|
});
|
|
557
480
|
}
|
|
558
481
|
|
|
559
|
-
// src/typed-ops.ts
|
|
560
|
-
import { semanticPathToPatchPath as semanticPathToPatchPath2 } from "@manifesto-ai/core";
|
|
561
|
-
function defineOps() {
|
|
562
|
-
const toPatchPath = (path) => semanticPathToPatchPath2(path);
|
|
563
|
-
return {
|
|
564
|
-
set(path, value) {
|
|
565
|
-
return { op: "set", path: toPatchPath(path), value };
|
|
566
|
-
},
|
|
567
|
-
unset(path) {
|
|
568
|
-
return { op: "unset", path: toPatchPath(path) };
|
|
569
|
-
},
|
|
570
|
-
merge(path, value) {
|
|
571
|
-
return { op: "merge", path: toPatchPath(path), value };
|
|
572
|
-
},
|
|
573
|
-
raw: {
|
|
574
|
-
set(path, value) {
|
|
575
|
-
return { op: "set", path: toPatchPath(path), value };
|
|
576
|
-
},
|
|
577
|
-
unset(path) {
|
|
578
|
-
return { op: "unset", path: toPatchPath(path) };
|
|
579
|
-
},
|
|
580
|
-
merge(path, value) {
|
|
581
|
-
return { op: "merge", path: toPatchPath(path), value };
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
|
|
587
482
|
// src/index.ts
|
|
588
|
-
import {
|
|
589
|
-
import { createWorld } from "@manifesto-ai/world";
|
|
483
|
+
import { createSnapshot } from "@manifesto-ai/core";
|
|
590
484
|
export {
|
|
485
|
+
AlreadyActivatedError,
|
|
591
486
|
CompileError,
|
|
592
|
-
DispatchRejectedError,
|
|
593
487
|
DisposedError,
|
|
594
488
|
ManifestoError,
|
|
595
489
|
ReservedEffectError,
|
|
596
|
-
createCore,
|
|
597
|
-
createIntent,
|
|
598
490
|
createManifesto,
|
|
599
|
-
createSnapshot
|
|
600
|
-
createWorld,
|
|
601
|
-
defineOps,
|
|
602
|
-
dispatchAsync
|
|
491
|
+
createSnapshot
|
|
603
492
|
};
|
|
604
493
|
//# sourceMappingURL=index.js.map
|