@almadar/runtime 3.1.2 → 3.1.4

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.
@@ -96,6 +96,11 @@ declare function findInitialState(trait: TraitDefinition): string;
96
96
  declare function createInitialTraitState(trait: TraitDefinition): TraitState;
97
97
  /**
98
98
  * Find a matching transition from the current state for the given event.
99
+ *
100
+ * **Guard-unaware**: returns the first transition matching `from` /
101
+ * `event` regardless of any attached guard. Use `findMatchingTransitions`
102
+ * when multiple sibling transitions share the same `from`/`event` and
103
+ * disambiguate by guard.
99
104
  */
100
105
  declare function findTransition(trait: TraitDefinition, currentState: string, eventKey: string): TraitDefinition['transitions'][0] | undefined;
101
106
  /**
@@ -1,4 +1,4 @@
1
1
  import 'express';
2
- export { v as EffectResult, L as LoaderConfig, w as LocalPersistenceAdapter, O as OrbitalEventRequest, c as OrbitalEventResponse, x as OrbitalServerRuntime, d as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, i as RuntimeOrbital, j as RuntimeOrbitalSchema, k as RuntimeTrait, y as RuntimeTraitTick, z as createOrbitalServerRuntime } from './OrbitalServerRuntime-DrZB9ksb.js';
2
+ export { v as EffectResult, L as LoaderConfig, w as LocalPersistenceAdapter, O as OrbitalEventRequest, c as OrbitalEventResponse, x as OrbitalServerRuntime, d as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, i as RuntimeOrbital, j as RuntimeOrbitalSchema, k as RuntimeTrait, y as RuntimeTraitTick, z as createOrbitalServerRuntime } from './OrbitalServerRuntime-DWJYcIJG.js';
3
3
  import './types-CM6txTNy.js';
4
4
  import '@almadar/core';
@@ -1,4 +1,4 @@
1
- import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-KCXJNXQZ.js';
1
+ import { EventBus, createUnifiedLoader, preprocessSchema, StateMachineManager, createContextFromBindings, EffectExecutor } from './chunk-6PAKTVTR.js';
2
2
  import './chunk-PZ5AY32C.js';
3
3
  import { Router } from 'express';
4
4
  import * as fs from 'fs';
@@ -304,17 +304,20 @@ function createInitialTraitState(trait) {
304
304
  context: {}
305
305
  };
306
306
  }
307
- function findTransition(trait, currentState, eventKey) {
307
+ function findMatchingTransitions(trait, currentState, eventKey) {
308
308
  if (!trait.transitions || trait.transitions.length === 0) {
309
- return void 0;
309
+ return [];
310
310
  }
311
- return trait.transitions.find((t) => {
311
+ return trait.transitions.filter((t) => {
312
312
  if (Array.isArray(t.from)) {
313
313
  return t.from.includes(currentState) && t.event === eventKey;
314
314
  }
315
315
  return t.from === currentState && t.event === eventKey;
316
316
  });
317
317
  }
318
+ function findTransition(trait, currentState, eventKey) {
319
+ return findMatchingTransitions(trait, currentState, eventKey)[0];
320
+ }
318
321
  function normalizeEventKey(eventKey) {
319
322
  if (!eventKey) return "";
320
323
  return eventKey.startsWith("UI:") ? eventKey.slice(3) : eventKey;
@@ -331,8 +334,8 @@ function processEvent(options) {
331
334
  contextExtensions
332
335
  } = options;
333
336
  const normalizedEvent = normalizeEventKey(eventKey);
334
- const transition = findTransition(trait, traitState.currentState, normalizedEvent);
335
- if (!transition) {
337
+ const candidates = findMatchingTransitions(trait, traitState.currentState, normalizedEvent);
338
+ if (candidates.length === 0) {
336
339
  smLog.debug("noTransition", { trait: trait.name, event: normalizedEvent, currentState: traitState.currentState });
337
340
  return {
338
341
  executed: false,
@@ -341,8 +344,22 @@ function processEvent(options) {
341
344
  effects: []
342
345
  };
343
346
  }
344
- smLog.debug("processEvent", { trait: trait.name, event: normalizedEvent, currentState: traitState.currentState, to: transition.to });
345
- if (transition.guard) {
347
+ let lastFailedGuardTransition;
348
+ for (const transition of candidates) {
349
+ smLog.debug("processEvent", { trait: trait.name, event: normalizedEvent, currentState: traitState.currentState, to: transition.to });
350
+ if (!transition.guard) {
351
+ return {
352
+ executed: true,
353
+ newState: transition.to,
354
+ previousState: traitState.currentState,
355
+ effects: transition.effects || [],
356
+ transition: {
357
+ from: traitState.currentState,
358
+ to: transition.to,
359
+ event: normalizedEvent
360
+ }
361
+ };
362
+ }
346
363
  const ctx = createContextFromBindings({
347
364
  entity: entityData,
348
365
  payload,
@@ -354,20 +371,21 @@ function processEvent(options) {
354
371
  ctx
355
372
  );
356
373
  smLog.debug("guard:evaluate", { trait: trait.name, event: normalizedEvent, guardResult: guardPasses });
357
- if (!guardPasses) {
374
+ if (guardPasses) {
358
375
  return {
359
- executed: false,
360
- newState: traitState.currentState,
376
+ executed: true,
377
+ newState: transition.to,
361
378
  previousState: traitState.currentState,
362
- effects: [],
379
+ effects: transition.effects || [],
363
380
  transition: {
364
381
  from: traitState.currentState,
365
382
  to: transition.to,
366
383
  event: normalizedEvent
367
384
  },
368
- guardResult: false
385
+ guardResult: true
369
386
  };
370
387
  }
388
+ lastFailedGuardTransition = transition;
371
389
  } catch (error) {
372
390
  if (guardMode === "strict") {
373
391
  console.error(
@@ -388,19 +406,31 @@ function processEvent(options) {
388
406
  };
389
407
  }
390
408
  console.error("[StateMachineCore] Guard evaluation error:", error);
409
+ return {
410
+ executed: true,
411
+ newState: transition.to,
412
+ previousState: traitState.currentState,
413
+ effects: transition.effects || [],
414
+ transition: {
415
+ from: traitState.currentState,
416
+ to: transition.to,
417
+ event: normalizedEvent
418
+ },
419
+ guardResult: true
420
+ };
391
421
  }
392
422
  }
393
423
  return {
394
- executed: true,
395
- newState: transition.to,
424
+ executed: false,
425
+ newState: traitState.currentState,
396
426
  previousState: traitState.currentState,
397
- effects: transition.effects || [],
398
- transition: {
427
+ effects: [],
428
+ transition: lastFailedGuardTransition ? {
399
429
  from: traitState.currentState,
400
- to: transition.to,
430
+ to: lastFailedGuardTransition.to,
401
431
  event: normalizedEvent
402
- },
403
- guardResult: transition.guard ? true : void 0
432
+ } : void 0,
433
+ guardResult: false
404
434
  };
405
435
  }
406
436
  var SINGLETON_SCOPE = "__singleton__";
@@ -856,7 +886,16 @@ var EffectExecutor = class {
856
886
  }
857
887
  const { operator, args } = parsed;
858
888
  const isCompound = operator === "do" || operator === "when";
859
- const resolvedArgs = isCompound ? args : resolveArgs(args, this.bindings, this.strictBindings, this.contextExtensions);
889
+ const isSet3Elem = operator === "set" && args.length === 2 && typeof args[0] === "string" && args[0].startsWith("@entity.");
890
+ let resolvedArgs;
891
+ if (isCompound) {
892
+ resolvedArgs = args;
893
+ } else if (isSet3Elem) {
894
+ const ctx = createContextFromBindings(this.bindings, this.strictBindings, this.contextExtensions);
895
+ resolvedArgs = [args[0], interpolateValue(args[1], ctx)];
896
+ } else {
897
+ resolvedArgs = resolveArgs(args, this.bindings, this.strictBindings, this.contextExtensions);
898
+ }
860
899
  effectLog.debug("execute", { operator, argCount: resolvedArgs.length, context: this.context.traitName });
861
900
  if (this.debug) {
862
901
  console.log("[EffectExecutor] Executing:", operator, resolvedArgs);
@@ -945,9 +984,25 @@ var EffectExecutor = class {
945
984
  break;
946
985
  }
947
986
  case "set": {
948
- const [entityId, field, value] = args;
949
- this.handlers.set(entityId, field, value);
950
987
  const entity = this.bindings.entity;
988
+ let entityId;
989
+ let field;
990
+ let value;
991
+ if (args.length === 2 && typeof args[0] === "string" && args[0].startsWith("@entity.")) {
992
+ const path = args[0];
993
+ field = path.slice("@entity.".length);
994
+ value = args[1];
995
+ entityId = typeof entity?.["id"] === "string" ? entity["id"] : void 0;
996
+ if (!entityId) {
997
+ effectLog.warn("set:missing-entity-id", { path });
998
+ break;
999
+ }
1000
+ } else {
1001
+ entityId = args[0];
1002
+ field = args[1];
1003
+ value = args[2];
1004
+ }
1005
+ this.handlers.set(entityId, field, value);
951
1006
  if (entity && entity["id"] === entityId) {
952
1007
  entity[field] = value;
953
1008
  }
@@ -2504,5 +2559,5 @@ function parseNamespacedEvent(eventName) {
2504
2559
  }
2505
2560
 
2506
2561
  export { EffectExecutor, EventBus, HANDLER_MANIFEST, StateMachineManager, containsBindings, createContextFromBindings, createInitialTraitState, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isNamespacedEvent, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent };
2507
- //# sourceMappingURL=chunk-KCXJNXQZ.js.map
2508
- //# sourceMappingURL=chunk-KCXJNXQZ.js.map
2562
+ //# sourceMappingURL=chunk-6PAKTVTR.js.map
2563
+ //# sourceMappingURL=chunk-6PAKTVTR.js.map