@almadar/runtime 6.34.0 → 6.36.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.
@@ -1,5 +1,5 @@
1
1
  import { Router } from 'express';
2
- import { I as IEventBus, R as RuntimeEvent, a as EventListener, U as Unsubscribe, T as TraitDefinition, b as RuntimeConfig, c as TransitionObserver, d as TraitState, C as ConfigContext, e as TransitionResult, f as EvaluationContextExtensions, E as EffectHandlers } from './types-C8RsO0xa.js';
2
+ import { I as IEventBus, R as RuntimeEvent, a as EventListener, U as Unsubscribe, T as TraitDefinition, b as RuntimeConfig, c as TransitionObserver, d as TraitState, C as ConfigContext, e as TransitionResult, f as EvaluationContextExtensions, E as EffectHandlers } from './types-BAD9bSMA.js';
3
3
  import { EventPayload, EventId, EntityRow, Orbital, ServiceCallResult, TraitConfig, DeclaredTraitConfig, Entity, OrbitalSchema, Trait, PatternConfig, ResolvedPatternProps, SExpr, BusEventSource, OrbitalDefinition, TraitTick } from '@almadar/core';
4
4
 
5
5
  /**
@@ -308,7 +308,7 @@ declare class StateMachineManager {
308
308
  *
309
309
  * @returns Array of transition results (one per trait that had a matching transition)
310
310
  */
311
- sendEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow, entityByTrait?: Record<string, EntityRow>, eventId?: EventId): Array<{
311
+ sendEvent(eventKey: string, payload?: EventPayload, entityData?: EntityRow, entityByTrait?: Record<string, EntityRow>, eventId?: EventId, targetTrait?: string): Array<{
312
312
  traitName: string;
313
313
  result: TransitionResult;
314
314
  }>;
@@ -945,6 +945,13 @@ interface OrbitalEventRequest {
945
945
  eventId?: EventId;
946
946
  payload?: EventPayload;
947
947
  entityId?: string;
948
+ /**
949
+ * Scoped-listen delivery: dispatch to THIS trait only. A listens-matched
950
+ * trigger is addressed to the listening trait; without this, a trigger
951
+ * renamed to INIT broadcast orbital-wide and re-ran every trait's
952
+ * initializer (R-SCOPED-LISTEN-INIT-RENAME-FREEZE re-fire cascade).
953
+ */
954
+ targetTrait?: string;
948
955
  /** User context for @user bindings (from Firebase auth) */
949
956
  user?: {
950
957
  uid: string;
@@ -952,6 +959,22 @@ interface OrbitalEventRequest {
952
959
  displayName?: string;
953
960
  [key: string]: unknown;
954
961
  };
962
+ /** Per-tab client identity (UUID) — excludes this request's origin from live-broadcast delivery. */
963
+ clientId?: string;
964
+ }
965
+ /**
966
+ * One persist-envelope success emit, handed to the live-broadcast sink
967
+ * (`setLiveBroadcastSink`). Fired only from the `persist` effect's
968
+ * `emit:{success}` envelope (batch and single-op) — never from the generic
969
+ * emit funnel — so transport layers can fan it out to every OTHER
970
+ * connected client without matching on event names.
971
+ */
972
+ interface LiveBroadcastItem {
973
+ event: string;
974
+ payload?: EventPayload;
975
+ source: BusEventSource;
976
+ /** `clientId` of the request that produced this emit; excluded from delivery by the transport. */
977
+ originClientId?: string;
955
978
  }
956
979
  /**
957
980
  * Response from event processing
@@ -1097,6 +1120,8 @@ declare class OrbitalServerRuntime {
1097
1120
  private substrateHandlers;
1098
1121
  private substrateHandlersPromise;
1099
1122
  private resolvedSchema;
1123
+ /** Wired by the hosting server (e.g. the playground SSE endpoint) via `setLiveBroadcastSink`. */
1124
+ private liveBroadcastSink;
1100
1125
  /**
1101
1126
  * Trait name -> resolved `TraitConfig`, computed once per `register()` via
1102
1127
  * `buildResolvedTraitConfigs` (`@almadar/core`). An embedded sub-trait's
@@ -1266,6 +1291,14 @@ declare class OrbitalServerRuntime {
1266
1291
  * layer is not MockPersistenceAdapter.
1267
1292
  */
1268
1293
  resetMockPersistence(): void;
1294
+ /**
1295
+ * Wire a live-broadcast sink. Called only from a `persist` effect's
1296
+ * `emit:{success}` envelope firing site (batch and single-op) — see
1297
+ * `docs/Almadar_Live_Push.md`. The hosting server (e.g. the playground's
1298
+ * `/api/events` SSE endpoint) uses this to fan persist mutations out to
1299
+ * every OTHER connected client; a fresh call replaces the previous sink.
1300
+ */
1301
+ setLiveBroadcastSink(sink: (item: LiveBroadcastItem) => void): void;
1269
1302
  /**
1270
1303
  * Process an event for an orbital
1271
1304
  *
@@ -1355,4 +1388,4 @@ declare class OrbitalServerRuntime {
1355
1388
  */
1356
1389
  declare function createOrbitalServerRuntime(config?: OrbitalServerRuntimeConfig): OrbitalServerRuntime;
1357
1390
 
1358
- export { normalizeEventKey as A, parseNamespacedEvent as B, preprocessSchema as C, processEvent as D, type EntitySharingMap as E, type ClientEffectTuple as F, type ClientNavigateTuple as G, type ClientNotifyTuple as H, type ImportChainLike as I, type ClientRenderUITuple as J, type EffectResult as K, type LoadResult as L, type LoaderConfig as M, OrbitalServerRuntime as N, type OrbitalEventRequest as O, type PersistenceAdapter as P, type RuntimeTraitTick as Q, type RegisteredOrbital as R, type SchemaLoader as S, createOrbitalServerRuntime as T, type UnifiedLoaderOptions as U, type LoadedSchema as a, type LoadedOrbital as b, EventBus as c, type EventNamespaceMap as d, InMemoryPersistence as e, type OrbitalEventResponse as f, type OrbitalServerRuntimeConfig as g, type PreprocessOptions as h, type PreprocessResult as i, type PreprocessedSchema as j, type ProcessEventOptions as k, type RuntimeOrbital as l, type RuntimeOrbitalSchema as m, type RuntimeTrait as n, StateMachineManager as o, collectDeclaredConfigDefaults as p, collectDeclaredEntityDefaults as q, createInitialTraitState as r, findInitialState as s, findTransition as t, getIsolatedCollectionName as u, getNamespacedEvent as v, isBrowser as w, isElectron as x, isNamespacedEvent as y, isNode as z };
1391
+ export { normalizeEventKey as A, parseNamespacedEvent as B, preprocessSchema as C, processEvent as D, type EntitySharingMap as E, type ClientEffectTuple as F, type ClientNavigateTuple as G, type ClientNotifyTuple as H, type ImportChainLike as I, type ClientRenderUITuple as J, type EffectResult as K, type LoadResult as L, type LiveBroadcastItem as M, type LoaderConfig as N, type OrbitalEventRequest as O, type PersistenceAdapter as P, OrbitalServerRuntime as Q, type RegisteredOrbital as R, type SchemaLoader as S, type RuntimeTraitTick as T, type UnifiedLoaderOptions as U, createOrbitalServerRuntime as V, type LoadedSchema as a, type LoadedOrbital as b, EventBus as c, type EventNamespaceMap as d, InMemoryPersistence as e, type OrbitalEventResponse as f, type OrbitalServerRuntimeConfig as g, type PreprocessOptions as h, type PreprocessResult as i, type PreprocessedSchema as j, type ProcessEventOptions as k, type RuntimeOrbital as l, type RuntimeOrbitalSchema as m, type RuntimeTrait as n, StateMachineManager as o, collectDeclaredConfigDefaults as p, collectDeclaredEntityDefaults as q, createInitialTraitState as r, findInitialState as s, findTransition as t, getIsolatedCollectionName as u, getNamespacedEvent as v, isBrowser as w, isElectron as x, isNamespacedEvent as y, isNode as z };
@@ -1,4 +1,4 @@
1
1
  import 'express';
2
- export { F as ClientEffectTuple, G as ClientNavigateTuple, H as ClientNotifyTuple, J as ClientRenderUITuple, K as EffectResult, e as InMemoryPersistence, M as LoaderConfig, O as OrbitalEventRequest, f as OrbitalEventResponse, N as OrbitalServerRuntime, g as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, Q as RuntimeTraitTick, p as collectDeclaredConfigDefaults, T as createOrbitalServerRuntime } from './OrbitalServerRuntime-BrHSXDfp.js';
3
- import './types-C8RsO0xa.js';
2
+ export { F as ClientEffectTuple, G as ClientNavigateTuple, H as ClientNotifyTuple, J as ClientRenderUITuple, K as EffectResult, e as InMemoryPersistence, M as LiveBroadcastItem, N as LoaderConfig, O as OrbitalEventRequest, f as OrbitalEventResponse, Q as OrbitalServerRuntime, g as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, T as RuntimeTraitTick, p as collectDeclaredConfigDefaults, V as createOrbitalServerRuntime } from './OrbitalServerRuntime-IMGtH9rA.js';
3
+ import './types-BAD9bSMA.js';
4
4
  import '@almadar/core';
@@ -1,5 +1,5 @@
1
- import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, createContextFromBindings, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-TRA44DDY.js';
2
- export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-TRA44DDY.js';
1
+ import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, createContextFromBindings, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-5XS7DD4H.js';
2
+ export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-5XS7DD4H.js';
3
3
  import { isValidCronExpression } from './chunk-OU3ITB5S.js';
4
4
  import './chunk-OQJIK6PZ.js';
5
5
  import './chunk-SCRAHWOC.js';
@@ -7,7 +7,7 @@ import './chunk-MLKGABMK.js';
7
7
  import { createLogger } from '@almadar/logger';
8
8
  import * as nodeModule from 'module';
9
9
  import { evaluateGuard, evaluate } from '@almadar/evaluator';
10
- import { buildResolvedTraitConfigs, isInlineTrait, isEntityCall } from '@almadar/core';
10
+ import { buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping } from '@almadar/core';
11
11
 
12
12
  // src/identity/routing.ts
13
13
  function eventRouteKey(eventName, eventId) {
@@ -97,6 +97,8 @@ var OrbitalServerRuntime = class {
97
97
  substrateHandlers = null;
98
98
  substrateHandlersPromise = null;
99
99
  resolvedSchema = null;
100
+ /** Wired by the hosting server (e.g. the playground SSE endpoint) via `setLiveBroadcastSink`. */
101
+ liveBroadcastSink = null;
100
102
  /**
101
103
  * Trait name -> resolved `TraitConfig`, computed once per `register()` via
102
104
  * `buildResolvedTraitConfigs` (`@almadar/core`). An embedded sub-trait's
@@ -614,20 +616,10 @@ var OrbitalServerRuntime = class {
614
616
  sourceTrait: event.source?.trait ?? "?"
615
617
  }));
616
618
  }
617
- let mappedPayload = event.payload;
618
- if (listener.payloadMapping && event.payload) {
619
- mappedPayload = {};
620
- for (const [key, expr] of Object.entries(
621
- listener.payloadMapping
622
- )) {
623
- if (typeof expr === "string" && expr.startsWith("@payload.")) {
624
- const field = expr.slice("@payload.".length);
625
- mappedPayload[key] = event.payload[field];
626
- } else {
627
- mappedPayload[key] = expr;
628
- }
629
- }
630
- }
619
+ const mappedPayload = applyListenPayloadMapping(
620
+ listener.payloadMapping,
621
+ event.payload
622
+ );
631
623
  const raw = event.payload;
632
624
  const mapped = mappedPayload;
633
625
  const pickId = (field) => mapped?.[field] ?? raw?.[field];
@@ -636,7 +628,8 @@ var OrbitalServerRuntime = class {
636
628
  event: listener.triggers,
637
629
  eventId: listener.triggersId,
638
630
  payload: mappedPayload,
639
- entityId: forwardedEntityId
631
+ entityId: forwardedEntityId,
632
+ targetTrait: trait.name
640
633
  });
641
634
  });
642
635
  this.listenerCleanups.push(cleanup);
@@ -844,6 +837,16 @@ var OrbitalServerRuntime = class {
844
837
  }
845
838
  }
846
839
  }
840
+ /**
841
+ * Wire a live-broadcast sink. Called only from a `persist` effect's
842
+ * `emit:{success}` envelope firing site (batch and single-op) — see
843
+ * `docs/Almadar_Live_Push.md`. The hosting server (e.g. the playground's
844
+ * `/api/events` SSE endpoint) uses this to fan persist mutations out to
845
+ * every OTHER connected client; a fresh call replaces the previous sink.
846
+ */
847
+ setLiveBroadcastSink(sink) {
848
+ this.liveBroadcastSink = sink;
849
+ }
847
850
  // ==========================================================================
848
851
  // Event Processing
849
852
  // ==========================================================================
@@ -899,7 +902,8 @@ var OrbitalServerRuntime = class {
899
902
  request.payload?.["_activeTraits"] ?? null
900
903
  )
901
904
  }));
902
- const { event, eventId, payload, entityId, user } = request;
905
+ const { event, eventId, payload, entityId, user, clientId } = request;
906
+ const targetTrait = request.targetTrait ?? payload?.["_targetTrait"];
903
907
  const validationFailures = [];
904
908
  for (const trait of registered.traits) {
905
909
  const eventSchema = trait.stateMachine?.events?.find((e) => e.key === event);
@@ -927,6 +931,7 @@ var OrbitalServerRuntime = class {
927
931
  const cleanPayload = payload ? { ...payload } : void 0;
928
932
  if (cleanPayload) {
929
933
  delete cleanPayload._activeTraits;
934
+ delete cleanPayload._targetTrait;
930
935
  }
931
936
  let entityData = {};
932
937
  if (entityId) {
@@ -949,7 +954,8 @@ var OrbitalServerRuntime = class {
949
954
  cleanPayload,
950
955
  entityData,
951
956
  entityByTrait,
952
- eventId
957
+ eventId,
958
+ targetTrait
953
959
  );
954
960
  const filteredResults = activeTraits && activeTraits.length > 0 ? results.filter(({ traitName }) => activeTraits.includes(traitName)) : results;
955
961
  if (this.config.debug && activeTraits) {
@@ -974,7 +980,8 @@ var OrbitalServerRuntime = class {
974
980
  effectResults,
975
981
  user,
976
982
  clientEffectsByTrait,
977
- onPush
983
+ onPush,
984
+ clientId
978
985
  );
979
986
  }
980
987
  }
@@ -1018,7 +1025,7 @@ var OrbitalServerRuntime = class {
1018
1025
  /**
1019
1026
  * Execute effects from a transition
1020
1027
  */
1021
- async executeEffects(registered, traitName, effects, payload, entityData, entityId, emittedEvents, fetchedData, clientEffects, effectResults, user, clientEffectsByTrait, onPush) {
1028
+ async executeEffects(registered, traitName, effects, payload, entityData, entityId, emittedEvents, fetchedData, clientEffects, effectResults, user, clientEffectsByTrait, onPush, originClientId) {
1022
1029
  const entityType = registered.entity.name;
1023
1030
  const pushClientEffect = (effect) => {
1024
1031
  clientEffects.push(effect);
@@ -1028,7 +1035,7 @@ var OrbitalServerRuntime = class {
1028
1035
  let bindingsRef = null;
1029
1036
  let contextRef = null;
1030
1037
  const handlers = {
1031
- emit: (event, eventPayload, source) => {
1038
+ emit: (event, eventPayload, source, fromPersistSuccess) => {
1032
1039
  if (this.config.debug) {
1033
1040
  busLog.debug("emit:dispatch", () => ({
1034
1041
  event,
@@ -1068,6 +1075,16 @@ var OrbitalServerRuntime = class {
1068
1075
  sourceTrait: stamp.trait,
1069
1076
  dispatchOrbital: registered.schema.name
1070
1077
  });
1078
+ if (fromPersistSuccess) {
1079
+ busLog.debug("live-broadcast:sink-call", {
1080
+ event,
1081
+ sourceOrbital: stamp.orbital,
1082
+ sourceTrait: stamp.trait,
1083
+ originClientId,
1084
+ sinkWired: this.liveBroadcastSink !== null
1085
+ });
1086
+ this.liveBroadcastSink?.({ event, payload: eventPayload, source: stamp, originClientId });
1087
+ }
1071
1088
  },
1072
1089
  set: async (targetId, field, value) => {
1073
1090
  let fieldState = registered.traitFieldStates.get(traitName);
@@ -1,4 +1,4 @@
1
- import { I as IEventBus } from './types-C8RsO0xa.js';
1
+ import { I as IEventBus } from './types-BAD9bSMA.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
@@ -956,10 +956,11 @@ var StateMachineManager = class {
956
956
  *
957
957
  * @returns Array of transition results (one per trait that had a matching transition)
958
958
  */
959
- sendEvent(eventKey, payload, entityData, entityByTrait, eventId) {
959
+ sendEvent(eventKey, payload, entityData, entityByTrait, eventId, targetTrait) {
960
960
  const results = [];
961
961
  const scope = scopeOf(entityData);
962
962
  for (const [traitName, trait] of this.traits) {
963
+ if (targetTrait !== void 0 && traitName !== targetTrait) continue;
963
964
  const traitState = this.getOrInitState(traitName, scope);
964
965
  if (!traitState) continue;
965
966
  const key = compositeKey(traitName, scope);
@@ -1431,10 +1432,10 @@ var EffectExecutor = class _EffectExecutor {
1431
1432
  transition: this.context.transition
1432
1433
  };
1433
1434
  }
1434
- emitSuccess(emit, key, payload) {
1435
+ emitSuccess(emit, key, payload, fromPersistSuccess) {
1435
1436
  const eventName = emit?.[key];
1436
1437
  if (eventName) {
1437
- this.handlers.emit(eventName, payload, this.sourceStamp());
1438
+ this.handlers.emit(eventName, payload, this.sourceStamp(), fromPersistSuccess);
1438
1439
  }
1439
1440
  }
1440
1441
  emitFailure(emit, err) {
@@ -1570,7 +1571,7 @@ var EffectExecutor = class _EffectExecutor {
1570
1571
  opCount: operations.length,
1571
1572
  willEmit: emitCfg?.success
1572
1573
  });
1573
- this.emitSuccess(emitCfg, "success", operations);
1574
+ this.emitSuccess(emitCfg, "success", operations, true);
1574
1575
  persistLog.debug("persist:emit-fired", { action, eventName: emitCfg?.success });
1575
1576
  } else {
1576
1577
  const entityType = args[1];
@@ -1583,7 +1584,7 @@ var EffectExecutor = class _EffectExecutor {
1583
1584
  dataId,
1584
1585
  willEmit: emitCfg?.success
1585
1586
  });
1586
- this.emitSuccess(emitCfg, "success", data);
1587
+ this.emitSuccess(emitCfg, "success", data, true);
1587
1588
  persistLog.debug("persist:emit-fired", { action, eventName: emitCfg?.success });
1588
1589
  }
1589
1590
  } catch (err) {
@@ -3862,10 +3863,13 @@ function resolveConfigRefsById(trait, idIndex) {
3862
3863
  const entry = idIndex.get(field.refId);
3863
3864
  if (!entry || entry.kind !== expectedKind) continue;
3864
3865
  const currentName = entry.kind === "entity" ? entry.node.name : entry.kind === "event" ? entry.node.key : entry.node.name;
3865
- if (!currentName || currentName === field.default) continue;
3866
+ if (!currentName) continue;
3867
+ const isTraitBinding = entry.kind === "trait" && typeof field.default === "string" && field.default.startsWith("@trait.");
3868
+ const nextDefault = isTraitBinding ? `@trait.${currentName}` : currentName;
3869
+ if (nextDefault === field.default) continue;
3866
3870
  nextSchema ??= { ...schema };
3867
- nextSchema[key] = { ...field, default: currentName };
3868
- rewrites.push({ key, from: field.default, to: currentName });
3871
+ nextSchema[key] = { ...field, default: nextDefault };
3872
+ rewrites.push({ key, from: field.default, to: nextDefault });
3869
3873
  }
3870
3874
  if (!nextSchema) return trait;
3871
3875
  refResolverLog.info("config-ref:id-resolve", {
@@ -1,4 +1,4 @@
1
- import { E as EffectHandlers } from './types-C8RsO0xa.js';
1
+ import { E as EffectHandlers } from './types-BAD9bSMA.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, g as EffectContext, h as ExecutionEnvironment, i as EffectResult, T as TraitDefinition } from './types-C8RsO0xa.js';
2
- export { j as BrowserFileMeta, k as BrowserFilePickerOptions, l as BrowserGeolocationOptions, m as BrowserGeolocationPosition, C as ConfigContext, n as Effect, a as EventListener, H as HANDLER_MANIFEST, I as IEventBus, b as RuntimeConfig, R as RuntimeEvent, d as TraitState, c as TransitionObserver, e as TransitionResult, U as Unsubscribe } from './types-C8RsO0xa.js';
3
- import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital, P as PersistenceAdapter } from './OrbitalServerRuntime-BrHSXDfp.js';
4
- export { E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, O as OrbitalEventRequest, f as OrbitalEventResponse, g as OrbitalServerRuntimeConfig, h as PreprocessOptions, i as PreprocessResult, j as PreprocessedSchema, k as ProcessEventOptions, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, o as StateMachineManager, p as collectDeclaredConfigDefaults, q as collectDeclaredEntityDefaults, r as createInitialTraitState, s as findInitialState, t as findTransition, u as getIsolatedCollectionName, v as getNamespacedEvent, w as isBrowser, x as isElectron, y as isNamespacedEvent, z as isNode, A as normalizeEventKey, B as parseNamespacedEvent, C as preprocessSchema, D as processEvent } from './OrbitalServerRuntime-BrHSXDfp.js';
1
+ import { B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, g as EffectContext, h as ExecutionEnvironment, i as EffectResult, T as TraitDefinition } from './types-BAD9bSMA.js';
2
+ export { j as BrowserFileMeta, k as BrowserFilePickerOptions, l as BrowserGeolocationOptions, m as BrowserGeolocationPosition, C as ConfigContext, n as Effect, a as EventListener, H as HANDLER_MANIFEST, I as IEventBus, b as RuntimeConfig, R as RuntimeEvent, d as TraitState, c as TransitionObserver, e as TransitionResult, U as Unsubscribe } from './types-BAD9bSMA.js';
3
+ import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital, P as PersistenceAdapter } from './OrbitalServerRuntime-IMGtH9rA.js';
4
+ export { E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, O as OrbitalEventRequest, f as OrbitalEventResponse, g as OrbitalServerRuntimeConfig, h as PreprocessOptions, i as PreprocessResult, j as PreprocessedSchema, k as ProcessEventOptions, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, o as StateMachineManager, p as collectDeclaredConfigDefaults, q as collectDeclaredEntityDefaults, r as createInitialTraitState, s as findInitialState, t as findTransition, u as getIsolatedCollectionName, v as getNamespacedEvent, w as isBrowser, x as isElectron, y as isNamespacedEvent, z as isNode, A as normalizeEventKey, B as parseNamespacedEvent, C as preprocessSchema, D as processEvent } from './OrbitalServerRuntime-IMGtH9rA.js';
5
5
  import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
6
6
  export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
7
7
  import { TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, ServiceParams, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { EffectExecutor, createContextFromBindings } from './chunk-TRA44DDY.js';
2
- export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes } from './chunk-TRA44DDY.js';
1
+ import { EffectExecutor, createContextFromBindings } from './chunk-5XS7DD4H.js';
2
+ export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes } from './chunk-5XS7DD4H.js';
3
3
  export { cronMatches, cronMinuteKey, isValidCronExpression, parseCron, parseCronField } from './chunk-OU3ITB5S.js';
4
4
  import './chunk-OQJIK6PZ.js';
5
5
  export { PERF_NAMESPACE, RendererContractViolationError, adjustSchemaForMockData, aggregateSlotContent, assertIsMultiSourceSlotManager, assertIsSlotManager, bindEventBus, bindTraitStateGetter, buildMockData, buildOrbitalsByTrait, clearPerf, createSlotSetter, ensureVerificationApi, getOrbitalVerification, perfEnd, perfStart, perfStore, perfTime, prepareSchemaForPreview, pushPerfEntry, validateSlotContent, wrapCallbackForEvent } from './chunk-O5VGKPTG.js';
@@ -1,5 +1,5 @@
1
1
  import * as _almadar_core from '@almadar/core';
2
- import { TraitId, EventId, SExpr, EventPayload, AgentContext, LlmContext, WorkspaceContext, SessionContext, MemoryContext, TraceContext, IntegrationContext, TraitConfig, BusEvent, EntityRow, FieldValue, ServiceParams, FetchResult, PatternConfig, ResolvedPatternProps, Orbital, ServiceCallResult, BusEventSource, BusEventListener, Unsubscribe as Unsubscribe$1 } from '@almadar/core';
2
+ import { TraitId, EventId, SExpr, AgentContext, LlmContext, WorkspaceContext, SessionContext, MemoryContext, TraceContext, IntegrationContext, TraitConfig, EventPayload, BusEvent, EntityRow, FieldValue, ServiceParams, FetchResult, PatternConfig, ResolvedPatternProps, Orbital, ServiceCallResult, BusEventSource, BusEventListener, Unsubscribe as Unsubscribe$1 } from '@almadar/core';
3
3
 
4
4
  /** Alias for ResolvedPatternProps to avoid breaking internal consumers */
5
5
  type PatternProps = ResolvedPatternProps;
@@ -101,7 +101,8 @@ interface TraitDefinition {
101
101
  triggers: string;
102
102
  /** V4 dual-carry id sibling of `triggers` — optional until the Phase-7 flip. */
103
103
  triggersId?: EventId;
104
- payloadMapping?: EventPayload;
104
+ /** `with { ... }` payload rewrite: `{ targetField: "@payload.<sourceField>" | literal }` */
105
+ payloadMapping?: Record<string, string>;
105
106
  }>;
106
107
  }
107
108
  /**
@@ -119,8 +120,15 @@ interface EffectHandlers {
119
120
  * `Orbital.TraitName EVENT -> TRIGGER` in .lolo) can filter incoming
120
121
  * events by their originating trait. Omitted when the emit is
121
122
  * synthesized by a non-trait context (e.g. test harness).
123
+ *
124
+ * `fromPersistSuccess` is set only by `EffectExecutor`'s `persist` case
125
+ * (batch and single-op), never inferred from the event name — the
126
+ * positional signal a server-side implementation uses to also fan this
127
+ * emit out to other connected clients (live-broadcast). Absent/false
128
+ * for every other emit source (plain `emit` effect, `set`/`call-service`/
129
+ * `fetch` success envelopes, cascade re-emits).
122
130
  */
123
- emit: (event: string, payload?: EventPayload, source?: RuntimeEvent['source']) => void;
131
+ emit: (event: string, payload?: EventPayload, source?: RuntimeEvent['source'], fromPersistSuccess?: boolean) => void;
124
132
  /** Persist data (create/update/delete/batch) */
125
133
  persist: (action: 'create' | 'update' | 'delete' | 'batch', entityType: string, data?: EntityRow) => Promise<void>;
126
134
  /** Set a field value on an entity */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/runtime",
3
- "version": "6.34.0",
3
+ "version": "6.36.0",
4
4
  "description": "Interpreted runtime for Almadar orbital applications (OrbitalServerRuntime)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,11 +52,11 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@almadar/core": "^10.31.0",
56
- "@almadar/evaluator": "^2.31.0",
55
+ "@almadar/core": "^10.33.0",
56
+ "@almadar/evaluator": "^2.34.0",
57
57
  "@almadar/logger": "^1.9.0",
58
- "@almadar/server": "^2.25.0",
59
- "@almadar/std": "^16.141.0"
58
+ "@almadar/server": "^2.26.1",
59
+ "@almadar/std": "^16.143.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "express": "^5.0.0"
@@ -67,7 +67,7 @@
67
67
  }
68
68
  },
69
69
  "devDependencies": {
70
- "@almadar/eslint-plugin": "^2.14.0",
70
+ "@almadar/eslint-plugin": "^2.15.0",
71
71
  "@types/express": "^5.0.0",
72
72
  "@types/node": "^20.0.0",
73
73
  "@typescript-eslint/parser": "8.56.0",