@almadar/ui 4.11.0 → 4.12.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.
@@ -4492,6 +4492,16 @@ function useUISlotManager() {
4492
4492
  },
4493
4493
  []
4494
4494
  );
4495
+ const updateTraitContent = React128.useCallback(
4496
+ (traitName, content) => {
4497
+ const id = generateId();
4498
+ const fullContent = { ...content, id, sourceTrait: traitName };
4499
+ indexTraitRender(traitName, fullContent);
4500
+ notifyTraitSubscribers(traitName, fullContent);
4501
+ return id;
4502
+ },
4503
+ [indexTraitRender, notifyTraitSubscribers]
4504
+ );
4495
4505
  return {
4496
4506
  slots,
4497
4507
  render,
@@ -4503,7 +4513,8 @@ function useUISlotManager() {
4503
4513
  hasContent,
4504
4514
  getContent,
4505
4515
  getTraitContent,
4506
- subscribeTrait
4516
+ subscribeTrait,
4517
+ updateTraitContent
4507
4518
  };
4508
4519
  }
4509
4520
  var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
@@ -51542,6 +51553,76 @@ function useResolvedSchema(schema, pageName) {
51542
51553
  return result;
51543
51554
  }
51544
51555
 
51556
+ // runtime/embedded-traits.ts
51557
+ var TRAIT_BINDING_PREFIX = "@trait.";
51558
+ function collectTraitRefsFromValue(value, into) {
51559
+ if (value === null || value === void 0) return;
51560
+ if (typeof value === "string") {
51561
+ if (value.startsWith(TRAIT_BINDING_PREFIX)) {
51562
+ const rest = value.slice(TRAIT_BINDING_PREFIX.length);
51563
+ const dot = rest.indexOf(".");
51564
+ const traitName = dot === -1 ? rest : rest.slice(0, dot);
51565
+ if (traitName.length > 0) into.add(traitName);
51566
+ }
51567
+ return;
51568
+ }
51569
+ if (Array.isArray(value)) {
51570
+ for (const item of value) collectTraitRefsFromValue(item, into);
51571
+ return;
51572
+ }
51573
+ if (typeof value === "object") {
51574
+ for (const v of Object.values(value)) {
51575
+ collectTraitRefsFromValue(v, into);
51576
+ }
51577
+ }
51578
+ }
51579
+ function collectTraitRefsFromEffects(effects, into) {
51580
+ if (!effects) return;
51581
+ for (const effect of effects) {
51582
+ if (!Array.isArray(effect)) continue;
51583
+ if (effect[0] === "render-ui" && effect.length >= 3) {
51584
+ collectTraitRefsFromValue(effect[2], into);
51585
+ continue;
51586
+ }
51587
+ for (let i = 1; i < effect.length; i++) {
51588
+ const arg = effect[i];
51589
+ if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
51590
+ else collectTraitRefsFromValue(arg, into);
51591
+ }
51592
+ }
51593
+ }
51594
+ function collectEmbeddedTraits(schema) {
51595
+ const out = /* @__PURE__ */ new Set();
51596
+ if (!schema?.orbitals) return out;
51597
+ for (const orbital of schema.orbitals) {
51598
+ if (!orbital || typeof orbital !== "object") continue;
51599
+ const traits2 = orbital.traits;
51600
+ if (!Array.isArray(traits2)) continue;
51601
+ for (const trait of traits2) {
51602
+ if (!trait || typeof trait !== "object") continue;
51603
+ const resolved = trait._resolved;
51604
+ const target = resolved && typeof resolved === "object" ? resolved : trait;
51605
+ const stateMachine = target.stateMachine;
51606
+ const transitions = stateMachine?.transitions;
51607
+ if (!Array.isArray(transitions)) continue;
51608
+ for (const t of transitions) {
51609
+ if (!t || typeof t !== "object") continue;
51610
+ const effects = t.effects;
51611
+ collectTraitRefsFromEffects(effects, out);
51612
+ }
51613
+ const initialEffects = target.initialEffects;
51614
+ collectTraitRefsFromEffects(initialEffects, out);
51615
+ const ticks2 = target.ticks;
51616
+ if (Array.isArray(ticks2)) {
51617
+ for (const tick of ticks2) {
51618
+ collectTraitRefsFromEffects(tick?.effects, out);
51619
+ }
51620
+ }
51621
+ }
51622
+ }
51623
+ return out;
51624
+ }
51625
+
51545
51626
  // hooks/index.ts
51546
51627
  init_useEventBus();
51547
51628
  init_useUISlots();
@@ -52322,11 +52403,19 @@ function ServerBridgeProvider({
52322
52403
  }
52323
52404
  }
52324
52405
  } else if (result.error) {
52325
- console.error("[ServerBridge] Event error:", result.error);
52406
+ xOrbitalLog2.warn("response:fail", {
52407
+ orbital: orbitalName,
52408
+ event,
52409
+ error: result.error
52410
+ });
52326
52411
  }
52327
52412
  return { effects, meta };
52328
52413
  } catch (err) {
52329
- console.error("[ServerBridge] Event send failed:", err);
52414
+ xOrbitalLog2.error("response:network", {
52415
+ orbital: orbitalName,
52416
+ event,
52417
+ error: err instanceof Error ? err.message : String(err)
52418
+ });
52330
52419
  return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
52331
52420
  }
52332
52421
  }, [connected, transport, eventBus]);
@@ -52516,32 +52605,49 @@ function SlotBridge() {
52516
52605
  }, [slots, render, clear]);
52517
52606
  return null;
52518
52607
  }
52519
- function applyServerEffects(effects, uiSlots, onNavigate) {
52608
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
52520
52609
  for (const eff of effects) {
52521
52610
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
52522
52611
  const patternRecord = eff.pattern;
52523
52612
  const { type: patternType, children, ...inlineProps } = patternRecord;
52524
52613
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
52525
- xOrbitalLog3.info("slot-write", {
52526
- slot: eff.slot,
52527
- sourceTrait: eff.traitName ?? "server",
52528
- patternType: typeof patternType === "string" ? patternType : void 0
52529
- });
52530
- uiSlots.render({
52531
- target: eff.slot,
52532
- pattern: patternType,
52533
- props: {
52534
- ...inlineProps,
52535
- ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
52536
- },
52537
- sourceTrait: eff.traitName ?? "server"
52538
- });
52614
+ const sourceTrait = eff.traitName ?? "server";
52615
+ const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
52616
+ const props = {
52617
+ ...inlineProps,
52618
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
52619
+ };
52620
+ if (isEmbedded) {
52621
+ xOrbitalLog3.info("slot:embed-routed", {
52622
+ sourceTrait,
52623
+ slot: eff.slot,
52624
+ patternType: typeof patternType === "string" ? patternType : void 0
52625
+ });
52626
+ uiSlots.updateTraitContent(sourceTrait, {
52627
+ pattern: patternType,
52628
+ props,
52629
+ priority: 0,
52630
+ animation: "fade"
52631
+ });
52632
+ } else {
52633
+ xOrbitalLog3.info("slot-write", {
52634
+ slot: eff.slot,
52635
+ sourceTrait,
52636
+ patternType: typeof patternType === "string" ? patternType : void 0
52637
+ });
52638
+ uiSlots.render({
52639
+ target: eff.slot,
52640
+ pattern: patternType,
52641
+ props,
52642
+ sourceTrait
52643
+ });
52644
+ }
52539
52645
  } else if (eff.type === "navigate" && eff.route && onNavigate) {
52540
52646
  onNavigate(eff.route, eff.params);
52541
52647
  }
52542
52648
  }
52543
52649
  }
52544
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
52650
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
52545
52651
  const slotsActions = useSlotsActions();
52546
52652
  const bridge = useServerBridge();
52547
52653
  const uiSlots = useUISlots();
@@ -52557,9 +52663,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52557
52663
  for (const name of targets) {
52558
52664
  const { effects, meta } = await bridge.sendEvent(name, event, payload);
52559
52665
  recordServerResponse(name, event, meta);
52560
- applyServerEffects(effects, uiSlots, onNavigate);
52666
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
52561
52667
  }
52562
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
52668
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
52563
52669
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
52564
52670
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
52565
52671
  const initSentRef = React128.useRef(false);
@@ -52599,10 +52705,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52599
52705
  effects: effectTraces,
52600
52706
  timestamp: Date.now()
52601
52707
  });
52602
- applyServerEffects(effects, uiSlots, onNavigate);
52708
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
52603
52709
  }
52604
52710
  })();
52605
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
52711
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
52606
52712
  return null;
52607
52713
  }
52608
52714
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -52708,6 +52814,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
52708
52814
  }
52709
52815
  return map;
52710
52816
  }, [schema]);
52817
+ const embeddedTraits = React128.useMemo(() => {
52818
+ return collectEmbeddedTraits(schema);
52819
+ }, [schema]);
52711
52820
  const inner = /* @__PURE__ */ jsxRuntime.jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
52712
52821
  EntitySchemaProvider,
52713
52822
  {
@@ -52722,6 +52831,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
52722
52831
  orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
52723
52832
  traitConfigsByName,
52724
52833
  orbitalsByTrait,
52834
+ embeddedTraits,
52725
52835
  onNavigate,
52726
52836
  onLocalFallback,
52727
52837
  persistence
package/dist/avl/index.js CHANGED
@@ -4446,6 +4446,16 @@ function useUISlotManager() {
4446
4446
  },
4447
4447
  []
4448
4448
  );
4449
+ const updateTraitContent = useCallback(
4450
+ (traitName, content) => {
4451
+ const id = generateId();
4452
+ const fullContent = { ...content, id, sourceTrait: traitName };
4453
+ indexTraitRender(traitName, fullContent);
4454
+ notifyTraitSubscribers(traitName, fullContent);
4455
+ return id;
4456
+ },
4457
+ [indexTraitRender, notifyTraitSubscribers]
4458
+ );
4449
4459
  return {
4450
4460
  slots,
4451
4461
  render,
@@ -4457,7 +4467,8 @@ function useUISlotManager() {
4457
4467
  hasContent,
4458
4468
  getContent,
4459
4469
  getTraitContent,
4460
- subscribeTrait
4470
+ subscribeTrait,
4471
+ updateTraitContent
4461
4472
  };
4462
4473
  }
4463
4474
  var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
@@ -51496,6 +51507,76 @@ function useResolvedSchema(schema, pageName) {
51496
51507
  return result;
51497
51508
  }
51498
51509
 
51510
+ // runtime/embedded-traits.ts
51511
+ var TRAIT_BINDING_PREFIX = "@trait.";
51512
+ function collectTraitRefsFromValue(value, into) {
51513
+ if (value === null || value === void 0) return;
51514
+ if (typeof value === "string") {
51515
+ if (value.startsWith(TRAIT_BINDING_PREFIX)) {
51516
+ const rest = value.slice(TRAIT_BINDING_PREFIX.length);
51517
+ const dot = rest.indexOf(".");
51518
+ const traitName = dot === -1 ? rest : rest.slice(0, dot);
51519
+ if (traitName.length > 0) into.add(traitName);
51520
+ }
51521
+ return;
51522
+ }
51523
+ if (Array.isArray(value)) {
51524
+ for (const item of value) collectTraitRefsFromValue(item, into);
51525
+ return;
51526
+ }
51527
+ if (typeof value === "object") {
51528
+ for (const v of Object.values(value)) {
51529
+ collectTraitRefsFromValue(v, into);
51530
+ }
51531
+ }
51532
+ }
51533
+ function collectTraitRefsFromEffects(effects, into) {
51534
+ if (!effects) return;
51535
+ for (const effect of effects) {
51536
+ if (!Array.isArray(effect)) continue;
51537
+ if (effect[0] === "render-ui" && effect.length >= 3) {
51538
+ collectTraitRefsFromValue(effect[2], into);
51539
+ continue;
51540
+ }
51541
+ for (let i = 1; i < effect.length; i++) {
51542
+ const arg = effect[i];
51543
+ if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
51544
+ else collectTraitRefsFromValue(arg, into);
51545
+ }
51546
+ }
51547
+ }
51548
+ function collectEmbeddedTraits(schema) {
51549
+ const out = /* @__PURE__ */ new Set();
51550
+ if (!schema?.orbitals) return out;
51551
+ for (const orbital of schema.orbitals) {
51552
+ if (!orbital || typeof orbital !== "object") continue;
51553
+ const traits2 = orbital.traits;
51554
+ if (!Array.isArray(traits2)) continue;
51555
+ for (const trait of traits2) {
51556
+ if (!trait || typeof trait !== "object") continue;
51557
+ const resolved = trait._resolved;
51558
+ const target = resolved && typeof resolved === "object" ? resolved : trait;
51559
+ const stateMachine = target.stateMachine;
51560
+ const transitions = stateMachine?.transitions;
51561
+ if (!Array.isArray(transitions)) continue;
51562
+ for (const t of transitions) {
51563
+ if (!t || typeof t !== "object") continue;
51564
+ const effects = t.effects;
51565
+ collectTraitRefsFromEffects(effects, out);
51566
+ }
51567
+ const initialEffects = target.initialEffects;
51568
+ collectTraitRefsFromEffects(initialEffects, out);
51569
+ const ticks2 = target.ticks;
51570
+ if (Array.isArray(ticks2)) {
51571
+ for (const tick of ticks2) {
51572
+ collectTraitRefsFromEffects(tick?.effects, out);
51573
+ }
51574
+ }
51575
+ }
51576
+ }
51577
+ return out;
51578
+ }
51579
+
51499
51580
  // hooks/index.ts
51500
51581
  init_useEventBus();
51501
51582
  init_useUISlots();
@@ -52276,11 +52357,19 @@ function ServerBridgeProvider({
52276
52357
  }
52277
52358
  }
52278
52359
  } else if (result.error) {
52279
- console.error("[ServerBridge] Event error:", result.error);
52360
+ xOrbitalLog2.warn("response:fail", {
52361
+ orbital: orbitalName,
52362
+ event,
52363
+ error: result.error
52364
+ });
52280
52365
  }
52281
52366
  return { effects, meta };
52282
52367
  } catch (err) {
52283
- console.error("[ServerBridge] Event send failed:", err);
52368
+ xOrbitalLog2.error("response:network", {
52369
+ orbital: orbitalName,
52370
+ event,
52371
+ error: err instanceof Error ? err.message : String(err)
52372
+ });
52284
52373
  return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
52285
52374
  }
52286
52375
  }, [connected, transport, eventBus]);
@@ -52470,32 +52559,49 @@ function SlotBridge() {
52470
52559
  }, [slots, render, clear]);
52471
52560
  return null;
52472
52561
  }
52473
- function applyServerEffects(effects, uiSlots, onNavigate) {
52562
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
52474
52563
  for (const eff of effects) {
52475
52564
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
52476
52565
  const patternRecord = eff.pattern;
52477
52566
  const { type: patternType, children, ...inlineProps } = patternRecord;
52478
52567
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
52479
- xOrbitalLog3.info("slot-write", {
52480
- slot: eff.slot,
52481
- sourceTrait: eff.traitName ?? "server",
52482
- patternType: typeof patternType === "string" ? patternType : void 0
52483
- });
52484
- uiSlots.render({
52485
- target: eff.slot,
52486
- pattern: patternType,
52487
- props: {
52488
- ...inlineProps,
52489
- ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
52490
- },
52491
- sourceTrait: eff.traitName ?? "server"
52492
- });
52568
+ const sourceTrait = eff.traitName ?? "server";
52569
+ const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
52570
+ const props = {
52571
+ ...inlineProps,
52572
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
52573
+ };
52574
+ if (isEmbedded) {
52575
+ xOrbitalLog3.info("slot:embed-routed", {
52576
+ sourceTrait,
52577
+ slot: eff.slot,
52578
+ patternType: typeof patternType === "string" ? patternType : void 0
52579
+ });
52580
+ uiSlots.updateTraitContent(sourceTrait, {
52581
+ pattern: patternType,
52582
+ props,
52583
+ priority: 0,
52584
+ animation: "fade"
52585
+ });
52586
+ } else {
52587
+ xOrbitalLog3.info("slot-write", {
52588
+ slot: eff.slot,
52589
+ sourceTrait,
52590
+ patternType: typeof patternType === "string" ? patternType : void 0
52591
+ });
52592
+ uiSlots.render({
52593
+ target: eff.slot,
52594
+ pattern: patternType,
52595
+ props,
52596
+ sourceTrait
52597
+ });
52598
+ }
52493
52599
  } else if (eff.type === "navigate" && eff.route && onNavigate) {
52494
52600
  onNavigate(eff.route, eff.params);
52495
52601
  }
52496
52602
  }
52497
52603
  }
52498
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
52604
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
52499
52605
  const slotsActions = useSlotsActions();
52500
52606
  const bridge = useServerBridge();
52501
52607
  const uiSlots = useUISlots();
@@ -52511,9 +52617,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52511
52617
  for (const name of targets) {
52512
52618
  const { effects, meta } = await bridge.sendEvent(name, event, payload);
52513
52619
  recordServerResponse(name, event, meta);
52514
- applyServerEffects(effects, uiSlots, onNavigate);
52620
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
52515
52621
  }
52516
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
52622
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
52517
52623
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
52518
52624
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
52519
52625
  const initSentRef = useRef(false);
@@ -52553,10 +52659,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
52553
52659
  effects: effectTraces,
52554
52660
  timestamp: Date.now()
52555
52661
  });
52556
- applyServerEffects(effects, uiSlots, onNavigate);
52662
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
52557
52663
  }
52558
52664
  })();
52559
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
52665
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
52560
52666
  return null;
52561
52667
  }
52562
52668
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -52662,6 +52768,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
52662
52768
  }
52663
52769
  return map;
52664
52770
  }, [schema]);
52771
+ const embeddedTraits = useMemo(() => {
52772
+ return collectEmbeddedTraits(schema);
52773
+ }, [schema]);
52665
52774
  const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
52666
52775
  EntitySchemaProvider,
52667
52776
  {
@@ -52676,6 +52785,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
52676
52785
  orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
52677
52786
  traitConfigsByName,
52678
52787
  orbitalsByTrait,
52788
+ embeddedTraits,
52679
52789
  onNavigate,
52680
52790
  onLocalFallback,
52681
52791
  persistence
@@ -41153,6 +41153,16 @@ function useUISlotManager() {
41153
41153
  },
41154
41154
  []
41155
41155
  );
41156
+ const updateTraitContent = React111.useCallback(
41157
+ (traitName, content) => {
41158
+ const id = generateId();
41159
+ const fullContent = { ...content, id, sourceTrait: traitName };
41160
+ indexTraitRender(traitName, fullContent);
41161
+ notifyTraitSubscribers(traitName, fullContent);
41162
+ return id;
41163
+ },
41164
+ [indexTraitRender, notifyTraitSubscribers]
41165
+ );
41156
41166
  return {
41157
41167
  slots,
41158
41168
  render,
@@ -41164,7 +41174,8 @@ function useUISlotManager() {
41164
41174
  hasContent,
41165
41175
  getContent,
41166
41176
  getTraitContent,
41167
- subscribeTrait
41177
+ subscribeTrait,
41178
+ updateTraitContent
41168
41179
  };
41169
41180
  }
41170
41181
 
@@ -41108,6 +41108,16 @@ function useUISlotManager() {
41108
41108
  },
41109
41109
  []
41110
41110
  );
41111
+ const updateTraitContent = useCallback(
41112
+ (traitName, content) => {
41113
+ const id = generateId();
41114
+ const fullContent = { ...content, id, sourceTrait: traitName };
41115
+ indexTraitRender(traitName, fullContent);
41116
+ notifyTraitSubscribers(traitName, fullContent);
41117
+ return id;
41118
+ },
41119
+ [indexTraitRender, notifyTraitSubscribers]
41120
+ );
41111
41121
  return {
41112
41122
  slots,
41113
41123
  render,
@@ -41119,7 +41129,8 @@ function useUISlotManager() {
41119
41129
  hasContent,
41120
41130
  getContent,
41121
41131
  getTraitContent,
41122
- subscribeTrait
41132
+ subscribeTrait,
41133
+ updateTraitContent
41123
41134
  };
41124
41135
  }
41125
41136
 
@@ -305,6 +305,16 @@ function useUISlotManager() {
305
305
  },
306
306
  []
307
307
  );
308
+ const updateTraitContent = react.useCallback(
309
+ (traitName, content) => {
310
+ const id = generateId();
311
+ const fullContent = { ...content, id, sourceTrait: traitName };
312
+ indexTraitRender(traitName, fullContent);
313
+ notifyTraitSubscribers(traitName, fullContent);
314
+ return id;
315
+ },
316
+ [indexTraitRender, notifyTraitSubscribers]
317
+ );
308
318
  return {
309
319
  slots,
310
320
  render,
@@ -316,7 +326,8 @@ function useUISlotManager() {
316
326
  hasContent,
317
327
  getContent,
318
328
  getTraitContent,
319
- subscribeTrait
329
+ subscribeTrait,
330
+ updateTraitContent
320
331
  };
321
332
  }
322
333
  var UISlotContext = react.createContext(null);
@@ -303,6 +303,16 @@ function useUISlotManager() {
303
303
  },
304
304
  []
305
305
  );
306
+ const updateTraitContent = useCallback(
307
+ (traitName, content) => {
308
+ const id = generateId();
309
+ const fullContent = { ...content, id, sourceTrait: traitName };
310
+ indexTraitRender(traitName, fullContent);
311
+ notifyTraitSubscribers(traitName, fullContent);
312
+ return id;
313
+ },
314
+ [indexTraitRender, notifyTraitSubscribers]
315
+ );
306
316
  return {
307
317
  slots,
308
318
  render,
@@ -314,7 +324,8 @@ function useUISlotManager() {
314
324
  hasContent,
315
325
  getContent,
316
326
  getTraitContent,
317
- subscribeTrait
327
+ subscribeTrait,
328
+ updateTraitContent
318
329
  };
319
330
  }
320
331
  var UISlotContext = createContext(null);
@@ -1348,6 +1348,16 @@ function useUISlotManager() {
1348
1348
  },
1349
1349
  []
1350
1350
  );
1351
+ const updateTraitContent = react.useCallback(
1352
+ (traitName, content) => {
1353
+ const id = generateId();
1354
+ const fullContent = { ...content, id, sourceTrait: traitName };
1355
+ indexTraitRender(traitName, fullContent);
1356
+ notifyTraitSubscribers(traitName, fullContent);
1357
+ return id;
1358
+ },
1359
+ [indexTraitRender, notifyTraitSubscribers]
1360
+ );
1351
1361
  return {
1352
1362
  slots,
1353
1363
  render,
@@ -1359,7 +1369,8 @@ function useUISlotManager() {
1359
1369
  hasContent,
1360
1370
  getContent,
1361
1371
  getTraitContent,
1362
- subscribeTrait
1372
+ subscribeTrait,
1373
+ updateTraitContent
1363
1374
  };
1364
1375
  }
1365
1376
  var UI_PREFIX = "UI:";
@@ -1346,6 +1346,16 @@ function useUISlotManager() {
1346
1346
  },
1347
1347
  []
1348
1348
  );
1349
+ const updateTraitContent = useCallback(
1350
+ (traitName, content) => {
1351
+ const id = generateId();
1352
+ const fullContent = { ...content, id, sourceTrait: traitName };
1353
+ indexTraitRender(traitName, fullContent);
1354
+ notifyTraitSubscribers(traitName, fullContent);
1355
+ return id;
1356
+ },
1357
+ [indexTraitRender, notifyTraitSubscribers]
1358
+ );
1349
1359
  return {
1350
1360
  slots,
1351
1361
  render,
@@ -1357,7 +1367,8 @@ function useUISlotManager() {
1357
1367
  hasContent,
1358
1368
  getContent,
1359
1369
  getTraitContent,
1360
- subscribeTrait
1370
+ subscribeTrait,
1371
+ updateTraitContent
1361
1372
  };
1362
1373
  }
1363
1374
  var UI_PREFIX = "UI:";
@@ -119,6 +119,20 @@ export interface UISlotManager {
119
119
  * the trait they embed actually changes — not on every slot update.
120
120
  */
121
121
  subscribeTrait: (traitName: string, callback: TraitChangeCallback) => () => void;
122
+ /**
123
+ * Update only the per-trait sidecar without writing to any slot.
124
+ *
125
+ * Used for embed-aware slot routing: when a trait is referenced via
126
+ * `@trait.X` by a sibling layout's render-ui, its render output should
127
+ * not stack into the same slot the layout writes — the layout owns the
128
+ * slot and embeds the trait's frame via `<TraitFrame>`. This method
129
+ * keeps the per-trait sidecar (`traitIndexRef`) up-to-date so
130
+ * `<TraitFrame>` re-renders, while leaving `slots[target]` untouched.
131
+ *
132
+ * Mirrors what the compiled-path codegen does structurally — atoms
133
+ * inlined as JSX inside the layout's pattern, not writing slots.
134
+ */
135
+ updateTraitContent: (traitName: string, content: Omit<SlotContent, 'id' | 'sourceTrait'>) => string;
122
136
  }
123
137
  declare const DEFAULT_SLOTS: Record<UISlot, SlotContent | null>;
124
138
  /**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Embed-aware slot routing — static analysis pass.
3
+ *
4
+ * Walks every trait's `transitions[].effects` looking for `render-ui`
5
+ * patterns whose tree contains `@trait.<Name>` string literals. Returns
6
+ * the flat set of trait names that are referenced this way by some
7
+ * sibling layout.
8
+ *
9
+ * Used by `<OrbPreview>` to route `applyServerEffects` — when an
10
+ * embedded trait's render-ui effect arrives, the runtime updates that
11
+ * trait's per-trait sidecar (`traitIndexRef`) only and skips the slot
12
+ * write. The sibling layout owns the slot and embeds the trait's frame
13
+ * via `<TraitFrame>`. Mirrors the compiled-path codegen which inlines
14
+ * the atom views as JSX inside the layout's pattern, never having them
15
+ * write a shared slot.
16
+ *
17
+ * The walker is a structural twin of
18
+ * `packages/almadar-runtime/src/resolver/reference-resolver.ts`'s
19
+ * `renameEventsInRenderUiConfig` — same recursive pattern shape, just
20
+ * collecting `@trait.X` substrings instead of renaming events.
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+ import type { OrbitalSchema } from '@almadar/core';
25
+ /**
26
+ * Build the flat set of trait names that are referenced via `@trait.X`
27
+ * by at least one trait's render-ui in the resolved schema.
28
+ *
29
+ * Safe to call on the resolved (post-inline) schema. Memoize by
30
+ * reference at the call site.
31
+ */
32
+ export declare function collectEmbeddedTraits(schema: OrbitalSchema | undefined | null): ReadonlySet<string>;
@@ -38974,6 +38974,78 @@ init_Box();
38974
38974
  init_Typography();
38975
38975
  init_UISlotRenderer();
38976
38976
  init_useEventBus();
38977
+
38978
+ // runtime/embedded-traits.ts
38979
+ var TRAIT_BINDING_PREFIX = "@trait.";
38980
+ function collectTraitRefsFromValue(value, into) {
38981
+ if (value === null || value === void 0) return;
38982
+ if (typeof value === "string") {
38983
+ if (value.startsWith(TRAIT_BINDING_PREFIX)) {
38984
+ const rest = value.slice(TRAIT_BINDING_PREFIX.length);
38985
+ const dot = rest.indexOf(".");
38986
+ const traitName = dot === -1 ? rest : rest.slice(0, dot);
38987
+ if (traitName.length > 0) into.add(traitName);
38988
+ }
38989
+ return;
38990
+ }
38991
+ if (Array.isArray(value)) {
38992
+ for (const item of value) collectTraitRefsFromValue(item, into);
38993
+ return;
38994
+ }
38995
+ if (typeof value === "object") {
38996
+ for (const v of Object.values(value)) {
38997
+ collectTraitRefsFromValue(v, into);
38998
+ }
38999
+ }
39000
+ }
39001
+ function collectTraitRefsFromEffects(effects, into) {
39002
+ if (!effects) return;
39003
+ for (const effect of effects) {
39004
+ if (!Array.isArray(effect)) continue;
39005
+ if (effect[0] === "render-ui" && effect.length >= 3) {
39006
+ collectTraitRefsFromValue(effect[2], into);
39007
+ continue;
39008
+ }
39009
+ for (let i = 1; i < effect.length; i++) {
39010
+ const arg = effect[i];
39011
+ if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
39012
+ else collectTraitRefsFromValue(arg, into);
39013
+ }
39014
+ }
39015
+ }
39016
+ function collectEmbeddedTraits(schema) {
39017
+ const out = /* @__PURE__ */ new Set();
39018
+ if (!schema?.orbitals) return out;
39019
+ for (const orbital of schema.orbitals) {
39020
+ if (!orbital || typeof orbital !== "object") continue;
39021
+ const traits2 = orbital.traits;
39022
+ if (!Array.isArray(traits2)) continue;
39023
+ for (const trait of traits2) {
39024
+ if (!trait || typeof trait !== "object") continue;
39025
+ const resolved = trait._resolved;
39026
+ const target = resolved && typeof resolved === "object" ? resolved : trait;
39027
+ const stateMachine = target.stateMachine;
39028
+ const transitions = stateMachine?.transitions;
39029
+ if (!Array.isArray(transitions)) continue;
39030
+ for (const t of transitions) {
39031
+ if (!t || typeof t !== "object") continue;
39032
+ const effects = t.effects;
39033
+ collectTraitRefsFromEffects(effects, out);
39034
+ }
39035
+ const initialEffects = target.initialEffects;
39036
+ collectTraitRefsFromEffects(initialEffects, out);
39037
+ const ticks2 = target.ticks;
39038
+ if (Array.isArray(ticks2)) {
39039
+ for (const tick of ticks2) {
39040
+ collectTraitRefsFromEffects(tick?.effects, out);
39041
+ }
39042
+ }
39043
+ }
39044
+ }
39045
+ return out;
39046
+ }
39047
+
39048
+ // runtime/OrbPreview.tsx
38977
39049
  init_SlotsContext();
38978
39050
  init_EntitySchemaContext();
38979
39051
 
@@ -39103,11 +39175,19 @@ function ServerBridgeProvider({
39103
39175
  }
39104
39176
  }
39105
39177
  } else if (result.error) {
39106
- console.error("[ServerBridge] Event error:", result.error);
39178
+ xOrbitalLog2.warn("response:fail", {
39179
+ orbital: orbitalName,
39180
+ event,
39181
+ error: result.error
39182
+ });
39107
39183
  }
39108
39184
  return { effects, meta };
39109
39185
  } catch (err) {
39110
- console.error("[ServerBridge] Event send failed:", err);
39186
+ xOrbitalLog2.error("response:network", {
39187
+ orbital: orbitalName,
39188
+ event,
39189
+ error: err instanceof Error ? err.message : String(err)
39190
+ });
39111
39191
  return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
39112
39192
  }
39113
39193
  }, [connected, transport, eventBus]);
@@ -39297,32 +39377,49 @@ function SlotBridge() {
39297
39377
  }, [slots, render, clear]);
39298
39378
  return null;
39299
39379
  }
39300
- function applyServerEffects(effects, uiSlots, onNavigate) {
39380
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
39301
39381
  for (const eff of effects) {
39302
39382
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
39303
39383
  const patternRecord = eff.pattern;
39304
39384
  const { type: patternType, children, ...inlineProps } = patternRecord;
39305
39385
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
39306
- xOrbitalLog3.info("slot-write", {
39307
- slot: eff.slot,
39308
- sourceTrait: eff.traitName ?? "server",
39309
- patternType: typeof patternType === "string" ? patternType : void 0
39310
- });
39311
- uiSlots.render({
39312
- target: eff.slot,
39313
- pattern: patternType,
39314
- props: {
39315
- ...inlineProps,
39316
- ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
39317
- },
39318
- sourceTrait: eff.traitName ?? "server"
39319
- });
39386
+ const sourceTrait = eff.traitName ?? "server";
39387
+ const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
39388
+ const props = {
39389
+ ...inlineProps,
39390
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
39391
+ };
39392
+ if (isEmbedded) {
39393
+ xOrbitalLog3.info("slot:embed-routed", {
39394
+ sourceTrait,
39395
+ slot: eff.slot,
39396
+ patternType: typeof patternType === "string" ? patternType : void 0
39397
+ });
39398
+ uiSlots.updateTraitContent(sourceTrait, {
39399
+ pattern: patternType,
39400
+ props,
39401
+ priority: 0,
39402
+ animation: "fade"
39403
+ });
39404
+ } else {
39405
+ xOrbitalLog3.info("slot-write", {
39406
+ slot: eff.slot,
39407
+ sourceTrait,
39408
+ patternType: typeof patternType === "string" ? patternType : void 0
39409
+ });
39410
+ uiSlots.render({
39411
+ target: eff.slot,
39412
+ pattern: patternType,
39413
+ props,
39414
+ sourceTrait
39415
+ });
39416
+ }
39320
39417
  } else if (eff.type === "navigate" && eff.route && onNavigate) {
39321
39418
  onNavigate(eff.route, eff.params);
39322
39419
  }
39323
39420
  }
39324
39421
  }
39325
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
39422
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
39326
39423
  const slotsActions = useSlotsActions();
39327
39424
  const bridge = useServerBridge();
39328
39425
  const uiSlots = context.useUISlots();
@@ -39338,9 +39435,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
39338
39435
  for (const name of targets) {
39339
39436
  const { effects, meta } = await bridge.sendEvent(name, event, payload);
39340
39437
  recordServerResponse(name, event, meta);
39341
- applyServerEffects(effects, uiSlots, onNavigate);
39438
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
39342
39439
  }
39343
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
39440
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
39344
39441
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
39345
39442
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
39346
39443
  const initSentRef = React115.useRef(false);
@@ -39380,10 +39477,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
39380
39477
  effects: effectTraces,
39381
39478
  timestamp: Date.now()
39382
39479
  });
39383
- applyServerEffects(effects, uiSlots, onNavigate);
39480
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
39384
39481
  }
39385
39482
  })();
39386
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
39483
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
39387
39484
  return null;
39388
39485
  }
39389
39486
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -39489,6 +39586,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
39489
39586
  }
39490
39587
  return map;
39491
39588
  }, [schema]);
39589
+ const embeddedTraits = React115.useMemo(() => {
39590
+ return collectEmbeddedTraits(schema);
39591
+ }, [schema]);
39492
39592
  const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
39493
39593
  EntitySchemaProvider,
39494
39594
  {
@@ -39503,6 +39603,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
39503
39603
  orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
39504
39604
  traitConfigsByName,
39505
39605
  orbitalsByTrait,
39606
+ embeddedTraits,
39506
39607
  onNavigate,
39507
39608
  onLocalFallback,
39508
39609
  persistence
@@ -38929,6 +38929,78 @@ init_Box();
38929
38929
  init_Typography();
38930
38930
  init_UISlotRenderer();
38931
38931
  init_useEventBus();
38932
+
38933
+ // runtime/embedded-traits.ts
38934
+ var TRAIT_BINDING_PREFIX = "@trait.";
38935
+ function collectTraitRefsFromValue(value, into) {
38936
+ if (value === null || value === void 0) return;
38937
+ if (typeof value === "string") {
38938
+ if (value.startsWith(TRAIT_BINDING_PREFIX)) {
38939
+ const rest = value.slice(TRAIT_BINDING_PREFIX.length);
38940
+ const dot = rest.indexOf(".");
38941
+ const traitName = dot === -1 ? rest : rest.slice(0, dot);
38942
+ if (traitName.length > 0) into.add(traitName);
38943
+ }
38944
+ return;
38945
+ }
38946
+ if (Array.isArray(value)) {
38947
+ for (const item of value) collectTraitRefsFromValue(item, into);
38948
+ return;
38949
+ }
38950
+ if (typeof value === "object") {
38951
+ for (const v of Object.values(value)) {
38952
+ collectTraitRefsFromValue(v, into);
38953
+ }
38954
+ }
38955
+ }
38956
+ function collectTraitRefsFromEffects(effects, into) {
38957
+ if (!effects) return;
38958
+ for (const effect of effects) {
38959
+ if (!Array.isArray(effect)) continue;
38960
+ if (effect[0] === "render-ui" && effect.length >= 3) {
38961
+ collectTraitRefsFromValue(effect[2], into);
38962
+ continue;
38963
+ }
38964
+ for (let i = 1; i < effect.length; i++) {
38965
+ const arg = effect[i];
38966
+ if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
38967
+ else collectTraitRefsFromValue(arg, into);
38968
+ }
38969
+ }
38970
+ }
38971
+ function collectEmbeddedTraits(schema) {
38972
+ const out = /* @__PURE__ */ new Set();
38973
+ if (!schema?.orbitals) return out;
38974
+ for (const orbital of schema.orbitals) {
38975
+ if (!orbital || typeof orbital !== "object") continue;
38976
+ const traits2 = orbital.traits;
38977
+ if (!Array.isArray(traits2)) continue;
38978
+ for (const trait of traits2) {
38979
+ if (!trait || typeof trait !== "object") continue;
38980
+ const resolved = trait._resolved;
38981
+ const target = resolved && typeof resolved === "object" ? resolved : trait;
38982
+ const stateMachine = target.stateMachine;
38983
+ const transitions = stateMachine?.transitions;
38984
+ if (!Array.isArray(transitions)) continue;
38985
+ for (const t of transitions) {
38986
+ if (!t || typeof t !== "object") continue;
38987
+ const effects = t.effects;
38988
+ collectTraitRefsFromEffects(effects, out);
38989
+ }
38990
+ const initialEffects = target.initialEffects;
38991
+ collectTraitRefsFromEffects(initialEffects, out);
38992
+ const ticks2 = target.ticks;
38993
+ if (Array.isArray(ticks2)) {
38994
+ for (const tick of ticks2) {
38995
+ collectTraitRefsFromEffects(tick?.effects, out);
38996
+ }
38997
+ }
38998
+ }
38999
+ }
39000
+ return out;
39001
+ }
39002
+
39003
+ // runtime/OrbPreview.tsx
38932
39004
  init_SlotsContext();
38933
39005
  init_EntitySchemaContext();
38934
39006
 
@@ -39058,11 +39130,19 @@ function ServerBridgeProvider({
39058
39130
  }
39059
39131
  }
39060
39132
  } else if (result.error) {
39061
- console.error("[ServerBridge] Event error:", result.error);
39133
+ xOrbitalLog2.warn("response:fail", {
39134
+ orbital: orbitalName,
39135
+ event,
39136
+ error: result.error
39137
+ });
39062
39138
  }
39063
39139
  return { effects, meta };
39064
39140
  } catch (err) {
39065
- console.error("[ServerBridge] Event send failed:", err);
39141
+ xOrbitalLog2.error("response:network", {
39142
+ orbital: orbitalName,
39143
+ event,
39144
+ error: err instanceof Error ? err.message : String(err)
39145
+ });
39066
39146
  return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
39067
39147
  }
39068
39148
  }, [connected, transport, eventBus]);
@@ -39252,32 +39332,49 @@ function SlotBridge() {
39252
39332
  }, [slots, render, clear]);
39253
39333
  return null;
39254
39334
  }
39255
- function applyServerEffects(effects, uiSlots, onNavigate) {
39335
+ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
39256
39336
  for (const eff of effects) {
39257
39337
  if (eff.type === "render-ui" && eff.slot && eff.pattern) {
39258
39338
  const patternRecord = eff.pattern;
39259
39339
  const { type: patternType, children, ...inlineProps } = patternRecord;
39260
39340
  const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
39261
- xOrbitalLog3.info("slot-write", {
39262
- slot: eff.slot,
39263
- sourceTrait: eff.traitName ?? "server",
39264
- patternType: typeof patternType === "string" ? patternType : void 0
39265
- });
39266
- uiSlots.render({
39267
- target: eff.slot,
39268
- pattern: patternType,
39269
- props: {
39270
- ...inlineProps,
39271
- ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
39272
- },
39273
- sourceTrait: eff.traitName ?? "server"
39274
- });
39341
+ const sourceTrait = eff.traitName ?? "server";
39342
+ const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
39343
+ const props = {
39344
+ ...inlineProps,
39345
+ ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
39346
+ };
39347
+ if (isEmbedded) {
39348
+ xOrbitalLog3.info("slot:embed-routed", {
39349
+ sourceTrait,
39350
+ slot: eff.slot,
39351
+ patternType: typeof patternType === "string" ? patternType : void 0
39352
+ });
39353
+ uiSlots.updateTraitContent(sourceTrait, {
39354
+ pattern: patternType,
39355
+ props,
39356
+ priority: 0,
39357
+ animation: "fade"
39358
+ });
39359
+ } else {
39360
+ xOrbitalLog3.info("slot-write", {
39361
+ slot: eff.slot,
39362
+ sourceTrait,
39363
+ patternType: typeof patternType === "string" ? patternType : void 0
39364
+ });
39365
+ uiSlots.render({
39366
+ target: eff.slot,
39367
+ pattern: patternType,
39368
+ props,
39369
+ sourceTrait
39370
+ });
39371
+ }
39275
39372
  } else if (eff.type === "navigate" && eff.route && onNavigate) {
39276
39373
  onNavigate(eff.route, eff.params);
39277
39374
  }
39278
39375
  }
39279
39376
  }
39280
- function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
39377
+ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
39281
39378
  const slotsActions = useSlotsActions();
39282
39379
  const bridge = useServerBridge();
39283
39380
  const uiSlots = useUISlots();
@@ -39293,9 +39390,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
39293
39390
  for (const name of targets) {
39294
39391
  const { effects, meta } = await bridge.sendEvent(name, event, payload);
39295
39392
  recordServerResponse(name, event, meta);
39296
- applyServerEffects(effects, uiSlots, onNavigate);
39393
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
39297
39394
  }
39298
- }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
39395
+ }, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
39299
39396
  const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
39300
39397
  const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
39301
39398
  const initSentRef = useRef(false);
@@ -39335,10 +39432,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
39335
39432
  effects: effectTraces,
39336
39433
  timestamp: Date.now()
39337
39434
  });
39338
- applyServerEffects(effects, uiSlots, onNavigate);
39435
+ applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
39339
39436
  }
39340
39437
  })();
39341
- }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
39438
+ }, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
39342
39439
  return null;
39343
39440
  }
39344
39441
  function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
@@ -39444,6 +39541,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
39444
39541
  }
39445
39542
  return map;
39446
39543
  }, [schema]);
39544
+ const embeddedTraits = useMemo(() => {
39545
+ return collectEmbeddedTraits(schema);
39546
+ }, [schema]);
39447
39547
  const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
39448
39548
  EntitySchemaProvider,
39449
39549
  {
@@ -39458,6 +39558,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
39458
39558
  orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
39459
39559
  traitConfigsByName,
39460
39560
  orbitalsByTrait,
39561
+ embeddedTraits,
39461
39562
  onNavigate,
39462
39563
  onLocalFallback,
39463
39564
  persistence
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.11.0",
3
+ "version": "4.12.1",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",