@almadar/runtime 6.0.4 → 6.2.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.
@@ -263,9 +263,16 @@ declare class StateMachineManager {
263
263
  /**
264
264
  * Send an event to all traits.
265
265
  *
266
+ * `entityByTrait` lets callers supply per-trait entity rows for guard
267
+ * evaluation when traits accumulate scalar state via `(set @entity.X)`
268
+ * effects across transitions. The runtime UI hook builds this map from
269
+ * its `traitFieldStatesRef` before each dispatch so guards reading
270
+ * `@entity.X` see prior step writes — required for [runtime] entities
271
+ * that have no persistence row to reload.
272
+ *
266
273
  * @returns Array of transition results (one per trait that had a matching transition)
267
274
  */
268
- sendEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow): Array<{
275
+ sendEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow, entityByTrait?: Record<string, EntityRow>): Array<{
269
276
  traitName: string;
270
277
  result: TransitionResult;
271
278
  }>;
@@ -276,7 +283,7 @@ declare class StateMachineManager {
276
283
  * trait to process them sequentially (actor-model guarantee: one event
277
284
  * at a time per trait, effects fully awaited before the next event).
278
285
  */
279
- enqueueEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow): void;
286
+ enqueueEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow, entityByTrait?: Record<string, EntityRow>): void;
280
287
  /**
281
288
  * Drain a single (trait, entity) pair's event queue, processing
282
289
  * events sequentially. Pass `entityId` to drain a specific entity
@@ -1,5 +1,5 @@
1
1
  import '@almadar/core';
2
2
  import 'express';
3
- export { C as ClientEffectTuple, B as ClientNavigateTuple, D as ClientNotifyTuple, F as ClientRenderUITuple, G as EffectResult, H as LoaderConfig, O as OrbitalEventRequest, e as OrbitalEventResponse, J as OrbitalServerRuntime, f as OrbitalServerRuntimeConfig, R as RegisteredOrbital, j as RuntimeOrbital, k as RuntimeOrbitalSchema, l as RuntimeTrait, K as RuntimeTraitTick, n as collectDeclaredConfigDefaults, M as createOrbitalServerRuntime } from './OrbitalServerRuntime-D0ciuYXu.js';
3
+ export { C as ClientEffectTuple, B as ClientNavigateTuple, D as ClientNotifyTuple, F as ClientRenderUITuple, G as EffectResult, H as LoaderConfig, O as OrbitalEventRequest, e as OrbitalEventResponse, J as OrbitalServerRuntime, f as OrbitalServerRuntimeConfig, R as RegisteredOrbital, j as RuntimeOrbital, k as RuntimeOrbitalSchema, l as RuntimeTrait, K as RuntimeTraitTick, n as collectDeclaredConfigDefaults, M as createOrbitalServerRuntime } from './OrbitalServerRuntime-BMRm0DUS.js';
4
4
  import './types-cuy5gd29.js';
5
5
  export { I as InMemoryPersistence, P as PersistenceAdapter } from './PersistenceAdapter-B6dQCbbU.js';
@@ -1,4 +1,4 @@
1
- export { InMemoryPersistence, OrbitalServerRuntime, collectDeclaredConfigDefaults, createOrbitalServerRuntime } from './chunk-BA4E5MG4.js';
1
+ export { InMemoryPersistence, OrbitalServerRuntime, collectDeclaredConfigDefaults, createOrbitalServerRuntime } from './chunk-P3WRK4G3.js';
2
2
  import './chunk-PZ5AY32C.js';
3
3
  //# sourceMappingURL=OrbitalServerRuntime.js.map
4
4
  //# sourceMappingURL=OrbitalServerRuntime.js.map
@@ -692,21 +692,29 @@ var StateMachineManager = class {
692
692
  /**
693
693
  * Send an event to all traits.
694
694
  *
695
+ * `entityByTrait` lets callers supply per-trait entity rows for guard
696
+ * evaluation when traits accumulate scalar state via `(set @entity.X)`
697
+ * effects across transitions. The runtime UI hook builds this map from
698
+ * its `traitFieldStatesRef` before each dispatch so guards reading
699
+ * `@entity.X` see prior step writes — required for [runtime] entities
700
+ * that have no persistence row to reload.
701
+ *
695
702
  * @returns Array of transition results (one per trait that had a matching transition)
696
703
  */
697
- sendEvent(eventKey, payload, entityData) {
704
+ sendEvent(eventKey, payload, entityData, entityByTrait) {
698
705
  const results = [];
699
706
  const scope = scopeOf(entityData);
700
707
  for (const [traitName, trait] of this.traits) {
701
708
  const traitState = this.getOrInitState(traitName, scope);
702
709
  if (!traitState) continue;
703
710
  const key = compositeKey(traitName, scope);
711
+ const perTraitEntity = entityByTrait?.[traitName] ?? entityData;
704
712
  const result = processEvent({
705
713
  traitState,
706
714
  trait,
707
715
  eventKey,
708
716
  payload,
709
- entityData,
717
+ entityData: perTraitEntity,
710
718
  config: this.traitConfigs.get(traitName),
711
719
  guardMode: this.config.guardMode,
712
720
  strictBindings: this.config.strictBindings,
@@ -746,12 +754,12 @@ var StateMachineManager = class {
746
754
  * trait to process them sequentially (actor-model guarantee: one event
747
755
  * at a time per trait, effects fully awaited before the next event).
748
756
  */
749
- enqueueEvent(eventKey, payload, entityData) {
757
+ enqueueEvent(eventKey, payload, entityData, entityByTrait) {
750
758
  const scope = scopeOf(entityData);
751
759
  for (const [traitName] of this.traits) {
752
760
  const key = compositeKey(traitName, scope);
753
761
  const queue = this.queues.get(key) ?? [];
754
- queue.push({ eventKey, payload, entityData });
762
+ queue.push({ eventKey, payload, entityData, entityByTrait });
755
763
  this.queues.set(key, queue);
756
764
  }
757
765
  }
@@ -771,12 +779,13 @@ var StateMachineManager = class {
771
779
  const trait = this.traits.get(traitName);
772
780
  const traitState = this.getOrInitState(traitName, scope);
773
781
  if (!trait || !traitState) continue;
782
+ const perTraitEntity = entry.entityByTrait?.[traitName] ?? entry.entityData;
774
783
  const result = processEvent({
775
784
  traitState,
776
785
  trait,
777
786
  eventKey: entry.eventKey,
778
787
  payload: entry.payload,
779
- entityData: entry.entityData,
788
+ entityData: perTraitEntity,
780
789
  config: this.traitConfigs.get(traitName),
781
790
  guardMode: this.config.guardMode,
782
791
  strictBindings: this.config.strictBindings,
@@ -1732,6 +1741,10 @@ function buildEmitsFromTraits(traits, explicitEmits) {
1732
1741
  }
1733
1742
  var mockLog = createLogger("almadar:runtime:mock");
1734
1743
  var DEFAULT_MOCK_SEED = 42;
1744
+ function picsumUrl(entityName, fieldName, width = 400, height = 400) {
1745
+ const seed = `${entityName}-${fieldName}-${faker.number.int({ min: 0, max: 1e3 })}`;
1746
+ return `https://picsum.photos/seed/${encodeURIComponent(seed)}/${width}/${height}`;
1747
+ }
1735
1748
  var SEED_REFERENCE_TIMESTAMP = "2024-01-01T00:00:00.000Z";
1736
1749
  var MockPersistenceAdapter = class {
1737
1750
  stores = /* @__PURE__ */ new Map();
@@ -1922,18 +1935,24 @@ var MockPersistenceAdapter = class {
1922
1935
  return faker.date.recent().toISOString().split("T")[0];
1923
1936
  case "datetime":
1924
1937
  return faker.date.recent().toISOString();
1925
- default: {
1926
- const value = faker.lorem.words(2);
1927
- mockLog.warn("field:fallback-lorem", {
1928
- entityName,
1929
- fieldName: field.name,
1930
- hasValues: false,
1931
- format: field.format ?? null,
1932
- generated: value
1933
- });
1934
- return value;
1935
- }
1938
+ case "image":
1939
+ case "avatar":
1940
+ case "thumbnail":
1941
+ return picsumUrl(entityName, field.name);
1936
1942
  }
1943
+ const lname = field.name.toLowerCase();
1944
+ if (lname === "image" || lname === "imageurl" || lname === "image_url" || lname === "photo" || lname === "photourl" || lname === "photo_url" || lname === "avatar" || lname === "avatarurl" || lname === "avatar_url" || lname === "thumbnail" || lname === "thumbnailurl" || lname === "thumbnail_url" || lname === "picture" || lname === "pictureurl" || lname === "cover" || lname === "coverurl" || lname === "banner" || lname === "bannerurl") {
1945
+ return picsumUrl(entityName, field.name);
1946
+ }
1947
+ const value = faker.lorem.words(2);
1948
+ mockLog.warn("field:fallback-lorem", {
1949
+ entityName,
1950
+ fieldName: field.name,
1951
+ hasValues: false,
1952
+ format: field.format ?? null,
1953
+ generated: value
1954
+ });
1955
+ return value;
1937
1956
  }
1938
1957
  /**
1939
1958
  * Generate a date value. Uses the field's `format` (date vs datetime) to
@@ -4419,7 +4438,18 @@ var OrbitalServerRuntime = class {
4419
4438
  entityData = stored;
4420
4439
  }
4421
4440
  }
4422
- const results = registered.manager.sendEvent(event, cleanPayload, entityData);
4441
+ const entityByTrait = {};
4442
+ for (const [name, fields] of registered.traitFieldStates) {
4443
+ if (fields && Object.keys(fields).length > 0) {
4444
+ entityByTrait[name] = fields;
4445
+ }
4446
+ }
4447
+ const results = registered.manager.sendEvent(
4448
+ event,
4449
+ cleanPayload,
4450
+ entityData,
4451
+ entityByTrait
4452
+ );
4423
4453
  const filteredResults = activeTraits && activeTraits.length > 0 ? results.filter(({ traitName }) => activeTraits.includes(traitName)) : results;
4424
4454
  if (this.config.debug && activeTraits) {
4425
4455
  console.log(`[OrbitalRuntime] Filtering traits: ${results.length} total, ${filteredResults.length} active (${activeTraits.join(", ")})`);
@@ -5342,5 +5372,5 @@ function buildMatcher(src, listenerOrbital) {
5342
5372
  }
5343
5373
 
5344
5374
  export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, OrbitalServerRuntime, StateMachineManager, buildEmitsFromTraits, collectDeclaredConfigDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createLogger, createMockPersistence, createOrbitalServerRuntime, createTestExecutor, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, normalizeEventKey, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes };
5345
- //# sourceMappingURL=chunk-BA4E5MG4.js.map
5346
- //# sourceMappingURL=chunk-BA4E5MG4.js.map
5375
+ //# sourceMappingURL=chunk-P3WRK4G3.js.map
5376
+ //# sourceMappingURL=chunk-P3WRK4G3.js.map