@almadar/ui 4.9.0 → 4.10.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.
@@ -51429,13 +51429,47 @@ OrbitalProvider.displayName = "OrbitalProvider";
51429
51429
  init_UISlotContext();
51430
51430
  init_UISlotRenderer();
51431
51431
  init_useEventBus();
51432
+
51433
+ // runtime/useResolvedSchema.ts
51434
+ init_logger();
51435
+ var resolvedSchemaLog = createLogger("almadar:ui:resolved-schema");
51432
51436
  function useResolvedSchema(schema, pageName) {
51433
51437
  const [loading, setLoading] = React128.useState(true);
51434
51438
  const [error, setError] = React128.useState(null);
51435
51439
  const ir = React128.useMemo(() => {
51436
51440
  if (!schema) return null;
51437
51441
  try {
51438
- return core.schemaToIR(schema);
51442
+ const resolved = core.schemaToIR(schema);
51443
+ const callSiteListensByTrait = /* @__PURE__ */ new Map();
51444
+ for (const orb of schema.orbitals) {
51445
+ for (const traitRef of orb.traits ?? []) {
51446
+ if (typeof traitRef === "string") continue;
51447
+ const t = traitRef;
51448
+ if (typeof t.name !== "string" || !t.listens?.length) continue;
51449
+ callSiteListensByTrait.set(t.name, t.listens);
51450
+ }
51451
+ }
51452
+ for (const [traitName, trait] of resolved.traits) {
51453
+ const callSiteListens = callSiteListensByTrait.get(traitName);
51454
+ if (!callSiteListens) continue;
51455
+ const beforeCount = trait.listens.length;
51456
+ trait.listens = callSiteListens.map((l) => ({
51457
+ event: l.event,
51458
+ triggers: l.triggers,
51459
+ source: l.source
51460
+ }));
51461
+ resolvedSchemaLog.info("listens:restored", {
51462
+ trait: traitName,
51463
+ beforeCount,
51464
+ afterCount: trait.listens.length,
51465
+ listens: callSiteListens.map((l) => {
51466
+ const src = l.source;
51467
+ const label = !src ? "(no-source)" : src.kind === "any" ? "*" : src.trait;
51468
+ return `${label}.${l.event}->${l.triggers}`;
51469
+ }).join(",")
51470
+ });
51471
+ }
51472
+ return resolved;
51439
51473
  } catch (err) {
51440
51474
  setError(err instanceof Error ? err.message : "Schema resolution failed");
51441
51475
  return null;
@@ -51507,6 +51541,9 @@ var ALMADAR_DND_MIME = "application/x-almadar-dnd";
51507
51541
  init_useEventBus();
51508
51542
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
51509
51543
 
51544
+ // runtime/useTraitStateMachine.ts
51545
+ init_logger();
51546
+
51510
51547
  // runtime/createClientEffectHandlers.ts
51511
51548
  function createClientEffectHandlers(options) {
51512
51549
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -51545,6 +51582,7 @@ function createClientEffectHandlers(options) {
51545
51582
  init_EntitySchemaContext();
51546
51583
  init_traitRegistry();
51547
51584
  init_verificationRegistry();
51585
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
51548
51586
  function toTraitDefinition(binding) {
51549
51587
  return {
51550
51588
  name: binding.trait.name,
@@ -51772,8 +51810,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51772
51810
  const currentManager = managerRef.current;
51773
51811
  const actions = slotsActionsRef.current;
51774
51812
  console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
51813
+ crossTraitLog.debug("processEvent:enter", {
51814
+ event: normalizedEvent,
51815
+ traitCount: bindings.length,
51816
+ traitNames: bindings.map((b) => b.trait.name).join(","),
51817
+ orbitalsByTrait: JSON.stringify(orbitalsByTrait ?? null)
51818
+ });
51775
51819
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
51776
51820
  const results = currentManager.sendEvent(normalizedEvent, payload);
51821
+ crossTraitLog.debug("processEvent:results", {
51822
+ event: normalizedEvent,
51823
+ executedCount: results.length,
51824
+ executedTraits: results.map((r2) => r2.traitName).join(",")
51825
+ });
51777
51826
  const emittedByTrait = /* @__PURE__ */ new Map();
51778
51827
  for (const { traitName, result } of results) {
51779
51828
  const binding = bindingMap.get(traitName);
@@ -52017,6 +52066,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52017
52066
  fromBridge: true
52018
52067
  });
52019
52068
  }
52069
+ const executedTraits = new Set(results.map((r2) => r2.traitName));
52070
+ for (const binding of bindings) {
52071
+ const traitName = binding.trait.name;
52072
+ if (executedTraits.has(traitName)) continue;
52073
+ const { events: traitEvents, transitions: traitTransitions } = binding.trait;
52074
+ const eventDeclared = traitEvents.some((e) => e.key === normalizedEvent);
52075
+ const hasTransition = traitTransitions.some((t) => t.event === normalizedEvent);
52076
+ crossTraitLog.debug("rebroadcast:second-pass:candidate", {
52077
+ event: normalizedEvent,
52078
+ traitName,
52079
+ eventDeclared,
52080
+ hasTransition,
52081
+ orbitalName: orbitalsByTrait?.[traitName],
52082
+ traitEventKeys: traitEvents.map((e) => e.key).join(",")
52083
+ });
52084
+ if (!eventDeclared || hasTransition) continue;
52085
+ const orbitalName = orbitalsByTrait?.[traitName];
52086
+ if (!orbitalName) continue;
52087
+ const busKey = `UI:${orbitalName}.${traitName}.${normalizedEvent}`;
52088
+ crossTraitLog.info("rebroadcast:emit", { busKey, traitName, event: normalizedEvent });
52089
+ eventBus.emit(busKey, payload, {
52090
+ orbital: orbitalName,
52091
+ trait: traitName,
52092
+ fromBridge: true
52093
+ });
52094
+ }
52020
52095
  }
52021
52096
  if (results.length > 0) {
52022
52097
  setTraitStates(currentManager.getAllStates());
@@ -52094,13 +52169,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52094
52169
  for (const binding of traitBindings) {
52095
52170
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
52096
52171
  const listens = binding.trait.listens ?? [];
52172
+ crossTraitLog.debug("listen:subscribe", {
52173
+ trait: binding.trait.name,
52174
+ ownOrbital,
52175
+ listenCount: listens.length,
52176
+ listens: listens.map((l) => `${l.source?.trait ?? "?"}.${l.event}->${l.triggers}`).join(",")
52177
+ });
52097
52178
  for (const listen of listens) {
52098
52179
  const sourceTrait = listen.source?.trait;
52099
52180
  if (!sourceTrait) continue;
52100
52181
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52101
52182
  if (!sourceOrbital) continue;
52102
52183
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52184
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52103
52185
  const unsub = eventBus.on(busKey, (event) => {
52186
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52104
52187
  enqueueAndDrain(listen.triggers, event.payload);
52105
52188
  });
52106
52189
  unsubscribes.push(unsub);
package/dist/avl/index.js CHANGED
@@ -51383,13 +51383,47 @@ OrbitalProvider.displayName = "OrbitalProvider";
51383
51383
  init_UISlotContext();
51384
51384
  init_UISlotRenderer();
51385
51385
  init_useEventBus();
51386
+
51387
+ // runtime/useResolvedSchema.ts
51388
+ init_logger();
51389
+ var resolvedSchemaLog = createLogger("almadar:ui:resolved-schema");
51386
51390
  function useResolvedSchema(schema, pageName) {
51387
51391
  const [loading, setLoading] = useState(true);
51388
51392
  const [error, setError] = useState(null);
51389
51393
  const ir = useMemo(() => {
51390
51394
  if (!schema) return null;
51391
51395
  try {
51392
- return schemaToIR(schema);
51396
+ const resolved = schemaToIR(schema);
51397
+ const callSiteListensByTrait = /* @__PURE__ */ new Map();
51398
+ for (const orb of schema.orbitals) {
51399
+ for (const traitRef of orb.traits ?? []) {
51400
+ if (typeof traitRef === "string") continue;
51401
+ const t = traitRef;
51402
+ if (typeof t.name !== "string" || !t.listens?.length) continue;
51403
+ callSiteListensByTrait.set(t.name, t.listens);
51404
+ }
51405
+ }
51406
+ for (const [traitName, trait] of resolved.traits) {
51407
+ const callSiteListens = callSiteListensByTrait.get(traitName);
51408
+ if (!callSiteListens) continue;
51409
+ const beforeCount = trait.listens.length;
51410
+ trait.listens = callSiteListens.map((l) => ({
51411
+ event: l.event,
51412
+ triggers: l.triggers,
51413
+ source: l.source
51414
+ }));
51415
+ resolvedSchemaLog.info("listens:restored", {
51416
+ trait: traitName,
51417
+ beforeCount,
51418
+ afterCount: trait.listens.length,
51419
+ listens: callSiteListens.map((l) => {
51420
+ const src = l.source;
51421
+ const label = !src ? "(no-source)" : src.kind === "any" ? "*" : src.trait;
51422
+ return `${label}.${l.event}->${l.triggers}`;
51423
+ }).join(",")
51424
+ });
51425
+ }
51426
+ return resolved;
51393
51427
  } catch (err) {
51394
51428
  setError(err instanceof Error ? err.message : "Schema resolution failed");
51395
51429
  return null;
@@ -51461,6 +51495,9 @@ var ALMADAR_DND_MIME = "application/x-almadar-dnd";
51461
51495
  init_useEventBus();
51462
51496
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
51463
51497
 
51498
+ // runtime/useTraitStateMachine.ts
51499
+ init_logger();
51500
+
51464
51501
  // runtime/createClientEffectHandlers.ts
51465
51502
  function createClientEffectHandlers(options) {
51466
51503
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -51499,6 +51536,7 @@ function createClientEffectHandlers(options) {
51499
51536
  init_EntitySchemaContext();
51500
51537
  init_traitRegistry();
51501
51538
  init_verificationRegistry();
51539
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
51502
51540
  function toTraitDefinition(binding) {
51503
51541
  return {
51504
51542
  name: binding.trait.name,
@@ -51726,8 +51764,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51726
51764
  const currentManager = managerRef.current;
51727
51765
  const actions = slotsActionsRef.current;
51728
51766
  console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
51767
+ crossTraitLog.debug("processEvent:enter", {
51768
+ event: normalizedEvent,
51769
+ traitCount: bindings.length,
51770
+ traitNames: bindings.map((b) => b.trait.name).join(","),
51771
+ orbitalsByTrait: JSON.stringify(orbitalsByTrait ?? null)
51772
+ });
51729
51773
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
51730
51774
  const results = currentManager.sendEvent(normalizedEvent, payload);
51775
+ crossTraitLog.debug("processEvent:results", {
51776
+ event: normalizedEvent,
51777
+ executedCount: results.length,
51778
+ executedTraits: results.map((r2) => r2.traitName).join(",")
51779
+ });
51731
51780
  const emittedByTrait = /* @__PURE__ */ new Map();
51732
51781
  for (const { traitName, result } of results) {
51733
51782
  const binding = bindingMap.get(traitName);
@@ -51971,6 +52020,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51971
52020
  fromBridge: true
51972
52021
  });
51973
52022
  }
52023
+ const executedTraits = new Set(results.map((r2) => r2.traitName));
52024
+ for (const binding of bindings) {
52025
+ const traitName = binding.trait.name;
52026
+ if (executedTraits.has(traitName)) continue;
52027
+ const { events: traitEvents, transitions: traitTransitions } = binding.trait;
52028
+ const eventDeclared = traitEvents.some((e) => e.key === normalizedEvent);
52029
+ const hasTransition = traitTransitions.some((t) => t.event === normalizedEvent);
52030
+ crossTraitLog.debug("rebroadcast:second-pass:candidate", {
52031
+ event: normalizedEvent,
52032
+ traitName,
52033
+ eventDeclared,
52034
+ hasTransition,
52035
+ orbitalName: orbitalsByTrait?.[traitName],
52036
+ traitEventKeys: traitEvents.map((e) => e.key).join(",")
52037
+ });
52038
+ if (!eventDeclared || hasTransition) continue;
52039
+ const orbitalName = orbitalsByTrait?.[traitName];
52040
+ if (!orbitalName) continue;
52041
+ const busKey = `UI:${orbitalName}.${traitName}.${normalizedEvent}`;
52042
+ crossTraitLog.info("rebroadcast:emit", { busKey, traitName, event: normalizedEvent });
52043
+ eventBus.emit(busKey, payload, {
52044
+ orbital: orbitalName,
52045
+ trait: traitName,
52046
+ fromBridge: true
52047
+ });
52048
+ }
51974
52049
  }
51975
52050
  if (results.length > 0) {
51976
52051
  setTraitStates(currentManager.getAllStates());
@@ -52048,13 +52123,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52048
52123
  for (const binding of traitBindings) {
52049
52124
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
52050
52125
  const listens = binding.trait.listens ?? [];
52126
+ crossTraitLog.debug("listen:subscribe", {
52127
+ trait: binding.trait.name,
52128
+ ownOrbital,
52129
+ listenCount: listens.length,
52130
+ listens: listens.map((l) => `${l.source?.trait ?? "?"}.${l.event}->${l.triggers}`).join(",")
52131
+ });
52051
52132
  for (const listen of listens) {
52052
52133
  const sourceTrait = listen.source?.trait;
52053
52134
  if (!sourceTrait) continue;
52054
52135
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52055
52136
  if (!sourceOrbital) continue;
52056
52137
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52138
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52057
52139
  const unsub = eventBus.on(busKey, (event) => {
52140
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52058
52141
  enqueueAndDrain(listen.triggers, event.payload);
52059
52142
  });
52060
52143
  unsubscribes.push(unsub);
@@ -38166,6 +38166,9 @@ init_useEventBus();
38166
38166
  init_useEventBus();
38167
38167
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
38168
38168
 
38169
+ // runtime/useTraitStateMachine.ts
38170
+ init_logger();
38171
+
38169
38172
  // runtime/createClientEffectHandlers.ts
38170
38173
  function createClientEffectHandlers(options) {
38171
38174
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -38204,6 +38207,7 @@ function createClientEffectHandlers(options) {
38204
38207
  init_EntitySchemaContext();
38205
38208
  init_traitRegistry();
38206
38209
  init_verificationRegistry();
38210
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
38207
38211
  function toTraitDefinition(binding) {
38208
38212
  return {
38209
38213
  name: binding.trait.name,
@@ -38431,8 +38435,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38431
38435
  const currentManager = managerRef.current;
38432
38436
  const actions = slotsActionsRef.current;
38433
38437
  console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
38438
+ crossTraitLog.debug("processEvent:enter", {
38439
+ event: normalizedEvent,
38440
+ traitCount: bindings.length,
38441
+ traitNames: bindings.map((b) => b.trait.name).join(","),
38442
+ orbitalsByTrait: JSON.stringify(orbitalsByTrait ?? null)
38443
+ });
38434
38444
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
38435
38445
  const results = currentManager.sendEvent(normalizedEvent, payload);
38446
+ crossTraitLog.debug("processEvent:results", {
38447
+ event: normalizedEvent,
38448
+ executedCount: results.length,
38449
+ executedTraits: results.map((r) => r.traitName).join(",")
38450
+ });
38436
38451
  const emittedByTrait = /* @__PURE__ */ new Map();
38437
38452
  for (const { traitName, result } of results) {
38438
38453
  const binding = bindingMap.get(traitName);
@@ -38676,6 +38691,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38676
38691
  fromBridge: true
38677
38692
  });
38678
38693
  }
38694
+ const executedTraits = new Set(results.map((r) => r.traitName));
38695
+ for (const binding of bindings) {
38696
+ const traitName = binding.trait.name;
38697
+ if (executedTraits.has(traitName)) continue;
38698
+ const { events: traitEvents, transitions: traitTransitions } = binding.trait;
38699
+ const eventDeclared = traitEvents.some((e) => e.key === normalizedEvent);
38700
+ const hasTransition = traitTransitions.some((t) => t.event === normalizedEvent);
38701
+ crossTraitLog.debug("rebroadcast:second-pass:candidate", {
38702
+ event: normalizedEvent,
38703
+ traitName,
38704
+ eventDeclared,
38705
+ hasTransition,
38706
+ orbitalName: orbitalsByTrait?.[traitName],
38707
+ traitEventKeys: traitEvents.map((e) => e.key).join(",")
38708
+ });
38709
+ if (!eventDeclared || hasTransition) continue;
38710
+ const orbitalName = orbitalsByTrait?.[traitName];
38711
+ if (!orbitalName) continue;
38712
+ const busKey = `UI:${orbitalName}.${traitName}.${normalizedEvent}`;
38713
+ crossTraitLog.info("rebroadcast:emit", { busKey, traitName, event: normalizedEvent });
38714
+ eventBus.emit(busKey, payload, {
38715
+ orbital: orbitalName,
38716
+ trait: traitName,
38717
+ fromBridge: true
38718
+ });
38719
+ }
38679
38720
  }
38680
38721
  if (results.length > 0) {
38681
38722
  setTraitStates(currentManager.getAllStates());
@@ -38753,13 +38794,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38753
38794
  for (const binding of traitBindings) {
38754
38795
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
38755
38796
  const listens = binding.trait.listens ?? [];
38797
+ crossTraitLog.debug("listen:subscribe", {
38798
+ trait: binding.trait.name,
38799
+ ownOrbital,
38800
+ listenCount: listens.length,
38801
+ listens: listens.map((l) => `${l.source?.trait ?? "?"}.${l.event}->${l.triggers}`).join(",")
38802
+ });
38756
38803
  for (const listen of listens) {
38757
38804
  const sourceTrait = listen.source?.trait;
38758
38805
  if (!sourceTrait) continue;
38759
38806
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
38760
38807
  if (!sourceOrbital) continue;
38761
38808
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
38809
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
38762
38810
  const unsub = eventBus.on(busKey, (event) => {
38811
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
38763
38812
  enqueueAndDrain(listen.triggers, event.payload);
38764
38813
  });
38765
38814
  unsubscribes.push(unsub);
@@ -38778,13 +38827,47 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38778
38827
  canHandleEvent
38779
38828
  };
38780
38829
  }
38830
+
38831
+ // runtime/useResolvedSchema.ts
38832
+ init_logger();
38833
+ var resolvedSchemaLog = createLogger("almadar:ui:resolved-schema");
38781
38834
  function useResolvedSchema(schema, pageName) {
38782
38835
  const [loading, setLoading] = React115.useState(true);
38783
38836
  const [error, setError] = React115.useState(null);
38784
38837
  const ir = React115.useMemo(() => {
38785
38838
  if (!schema) return null;
38786
38839
  try {
38787
- return core.schemaToIR(schema);
38840
+ const resolved = core.schemaToIR(schema);
38841
+ const callSiteListensByTrait = /* @__PURE__ */ new Map();
38842
+ for (const orb of schema.orbitals) {
38843
+ for (const traitRef of orb.traits ?? []) {
38844
+ if (typeof traitRef === "string") continue;
38845
+ const t = traitRef;
38846
+ if (typeof t.name !== "string" || !t.listens?.length) continue;
38847
+ callSiteListensByTrait.set(t.name, t.listens);
38848
+ }
38849
+ }
38850
+ for (const [traitName, trait] of resolved.traits) {
38851
+ const callSiteListens = callSiteListensByTrait.get(traitName);
38852
+ if (!callSiteListens) continue;
38853
+ const beforeCount = trait.listens.length;
38854
+ trait.listens = callSiteListens.map((l) => ({
38855
+ event: l.event,
38856
+ triggers: l.triggers,
38857
+ source: l.source
38858
+ }));
38859
+ resolvedSchemaLog.info("listens:restored", {
38860
+ trait: traitName,
38861
+ beforeCount,
38862
+ afterCount: trait.listens.length,
38863
+ listens: callSiteListens.map((l) => {
38864
+ const src = l.source;
38865
+ const label = !src ? "(no-source)" : src.kind === "any" ? "*" : src.trait;
38866
+ return `${label}.${l.event}->${l.triggers}`;
38867
+ }).join(",")
38868
+ });
38869
+ }
38870
+ return resolved;
38788
38871
  } catch (err) {
38789
38872
  setError(err instanceof Error ? err.message : "Schema resolution failed");
38790
38873
  return null;
@@ -38121,6 +38121,9 @@ init_useEventBus();
38121
38121
  init_useEventBus();
38122
38122
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
38123
38123
 
38124
+ // runtime/useTraitStateMachine.ts
38125
+ init_logger();
38126
+
38124
38127
  // runtime/createClientEffectHandlers.ts
38125
38128
  function createClientEffectHandlers(options) {
38126
38129
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -38159,6 +38162,7 @@ function createClientEffectHandlers(options) {
38159
38162
  init_EntitySchemaContext();
38160
38163
  init_traitRegistry();
38161
38164
  init_verificationRegistry();
38165
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
38162
38166
  function toTraitDefinition(binding) {
38163
38167
  return {
38164
38168
  name: binding.trait.name,
@@ -38386,8 +38390,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38386
38390
  const currentManager = managerRef.current;
38387
38391
  const actions = slotsActionsRef.current;
38388
38392
  console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
38393
+ crossTraitLog.debug("processEvent:enter", {
38394
+ event: normalizedEvent,
38395
+ traitCount: bindings.length,
38396
+ traitNames: bindings.map((b) => b.trait.name).join(","),
38397
+ orbitalsByTrait: JSON.stringify(orbitalsByTrait ?? null)
38398
+ });
38389
38399
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
38390
38400
  const results = currentManager.sendEvent(normalizedEvent, payload);
38401
+ crossTraitLog.debug("processEvent:results", {
38402
+ event: normalizedEvent,
38403
+ executedCount: results.length,
38404
+ executedTraits: results.map((r) => r.traitName).join(",")
38405
+ });
38391
38406
  const emittedByTrait = /* @__PURE__ */ new Map();
38392
38407
  for (const { traitName, result } of results) {
38393
38408
  const binding = bindingMap.get(traitName);
@@ -38631,6 +38646,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38631
38646
  fromBridge: true
38632
38647
  });
38633
38648
  }
38649
+ const executedTraits = new Set(results.map((r) => r.traitName));
38650
+ for (const binding of bindings) {
38651
+ const traitName = binding.trait.name;
38652
+ if (executedTraits.has(traitName)) continue;
38653
+ const { events: traitEvents, transitions: traitTransitions } = binding.trait;
38654
+ const eventDeclared = traitEvents.some((e) => e.key === normalizedEvent);
38655
+ const hasTransition = traitTransitions.some((t) => t.event === normalizedEvent);
38656
+ crossTraitLog.debug("rebroadcast:second-pass:candidate", {
38657
+ event: normalizedEvent,
38658
+ traitName,
38659
+ eventDeclared,
38660
+ hasTransition,
38661
+ orbitalName: orbitalsByTrait?.[traitName],
38662
+ traitEventKeys: traitEvents.map((e) => e.key).join(",")
38663
+ });
38664
+ if (!eventDeclared || hasTransition) continue;
38665
+ const orbitalName = orbitalsByTrait?.[traitName];
38666
+ if (!orbitalName) continue;
38667
+ const busKey = `UI:${orbitalName}.${traitName}.${normalizedEvent}`;
38668
+ crossTraitLog.info("rebroadcast:emit", { busKey, traitName, event: normalizedEvent });
38669
+ eventBus.emit(busKey, payload, {
38670
+ orbital: orbitalName,
38671
+ trait: traitName,
38672
+ fromBridge: true
38673
+ });
38674
+ }
38634
38675
  }
38635
38676
  if (results.length > 0) {
38636
38677
  setTraitStates(currentManager.getAllStates());
@@ -38708,13 +38749,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38708
38749
  for (const binding of traitBindings) {
38709
38750
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
38710
38751
  const listens = binding.trait.listens ?? [];
38752
+ crossTraitLog.debug("listen:subscribe", {
38753
+ trait: binding.trait.name,
38754
+ ownOrbital,
38755
+ listenCount: listens.length,
38756
+ listens: listens.map((l) => `${l.source?.trait ?? "?"}.${l.event}->${l.triggers}`).join(",")
38757
+ });
38711
38758
  for (const listen of listens) {
38712
38759
  const sourceTrait = listen.source?.trait;
38713
38760
  if (!sourceTrait) continue;
38714
38761
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
38715
38762
  if (!sourceOrbital) continue;
38716
38763
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
38764
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
38717
38765
  const unsub = eventBus.on(busKey, (event) => {
38766
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
38718
38767
  enqueueAndDrain(listen.triggers, event.payload);
38719
38768
  });
38720
38769
  unsubscribes.push(unsub);
@@ -38733,13 +38782,47 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
38733
38782
  canHandleEvent
38734
38783
  };
38735
38784
  }
38785
+
38786
+ // runtime/useResolvedSchema.ts
38787
+ init_logger();
38788
+ var resolvedSchemaLog = createLogger("almadar:ui:resolved-schema");
38736
38789
  function useResolvedSchema(schema, pageName) {
38737
38790
  const [loading, setLoading] = useState(true);
38738
38791
  const [error, setError] = useState(null);
38739
38792
  const ir = useMemo(() => {
38740
38793
  if (!schema) return null;
38741
38794
  try {
38742
- return schemaToIR(schema);
38795
+ const resolved = schemaToIR(schema);
38796
+ const callSiteListensByTrait = /* @__PURE__ */ new Map();
38797
+ for (const orb of schema.orbitals) {
38798
+ for (const traitRef of orb.traits ?? []) {
38799
+ if (typeof traitRef === "string") continue;
38800
+ const t = traitRef;
38801
+ if (typeof t.name !== "string" || !t.listens?.length) continue;
38802
+ callSiteListensByTrait.set(t.name, t.listens);
38803
+ }
38804
+ }
38805
+ for (const [traitName, trait] of resolved.traits) {
38806
+ const callSiteListens = callSiteListensByTrait.get(traitName);
38807
+ if (!callSiteListens) continue;
38808
+ const beforeCount = trait.listens.length;
38809
+ trait.listens = callSiteListens.map((l) => ({
38810
+ event: l.event,
38811
+ triggers: l.triggers,
38812
+ source: l.source
38813
+ }));
38814
+ resolvedSchemaLog.info("listens:restored", {
38815
+ trait: traitName,
38816
+ beforeCount,
38817
+ afterCount: trait.listens.length,
38818
+ listens: callSiteListens.map((l) => {
38819
+ const src = l.source;
38820
+ const label = !src ? "(no-source)" : src.kind === "any" ? "*" : src.trait;
38821
+ return `${label}.${l.event}->${l.triggers}`;
38822
+ }).join(",")
38823
+ });
38824
+ }
38825
+ return resolved;
38743
38826
  } catch (err) {
38744
38827
  setError(err instanceof Error ? err.message : "Schema resolution failed");
38745
38828
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.9.0",
3
+ "version": "4.10.1",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",