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