@almadar/ui 4.10.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,6 +51429,10 @@ 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);
@@ -51436,31 +51440,33 @@ function useResolvedSchema(schema, pageName) {
51436
51440
  if (!schema) return null;
51437
51441
  try {
51438
51442
  const resolved = core.schemaToIR(schema);
51439
- const sourceListsByTrait = /* @__PURE__ */ new Map();
51440
- const orbitals = schema.orbitals;
51441
- if (Array.isArray(orbitals)) {
51442
- for (const orb of orbitals) {
51443
- const traits2 = orb.traits;
51444
- if (!Array.isArray(traits2)) continue;
51445
- for (const trait of traits2) {
51446
- const t = trait;
51447
- if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
51448
- const sources = t.listens.map((listen) => {
51449
- const l = listen;
51450
- return l.source;
51451
- });
51452
- sourceListsByTrait.set(t.name, sources);
51453
- }
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);
51454
51450
  }
51455
51451
  }
51456
51452
  for (const [traitName, trait] of resolved.traits) {
51457
- const sources = sourceListsByTrait.get(traitName);
51458
- if (!sources) continue;
51459
- trait.listens.forEach((listen, i) => {
51460
- const src = sources[i];
51461
- if (src !== void 0) {
51462
- listen.source = src;
51463
- }
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(",")
51464
51470
  });
51465
51471
  }
51466
51472
  return resolved;
@@ -51535,6 +51541,9 @@ var ALMADAR_DND_MIME = "application/x-almadar-dnd";
51535
51541
  init_useEventBus();
51536
51542
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
51537
51543
 
51544
+ // runtime/useTraitStateMachine.ts
51545
+ init_logger();
51546
+
51538
51547
  // runtime/createClientEffectHandlers.ts
51539
51548
  function createClientEffectHandlers(options) {
51540
51549
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -51573,6 +51582,7 @@ function createClientEffectHandlers(options) {
51573
51582
  init_EntitySchemaContext();
51574
51583
  init_traitRegistry();
51575
51584
  init_verificationRegistry();
51585
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
51576
51586
  function toTraitDefinition(binding) {
51577
51587
  return {
51578
51588
  name: binding.trait.name,
@@ -51800,8 +51810,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51800
51810
  const currentManager = managerRef.current;
51801
51811
  const actions = slotsActionsRef.current;
51802
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
+ });
51803
51819
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
51804
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
+ });
51805
51826
  const emittedByTrait = /* @__PURE__ */ new Map();
51806
51827
  for (const { traitName, result } of results) {
51807
51828
  const binding = bindingMap.get(traitName);
@@ -52045,6 +52066,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52045
52066
  fromBridge: true
52046
52067
  });
52047
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
+ }
52048
52095
  }
52049
52096
  if (results.length > 0) {
52050
52097
  setTraitStates(currentManager.getAllStates());
@@ -52122,13 +52169,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52122
52169
  for (const binding of traitBindings) {
52123
52170
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
52124
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
+ });
52125
52178
  for (const listen of listens) {
52126
52179
  const sourceTrait = listen.source?.trait;
52127
52180
  if (!sourceTrait) continue;
52128
52181
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52129
52182
  if (!sourceOrbital) continue;
52130
52183
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52184
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52131
52185
  const unsub = eventBus.on(busKey, (event) => {
52186
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52132
52187
  enqueueAndDrain(listen.triggers, event.payload);
52133
52188
  });
52134
52189
  unsubscribes.push(unsub);
package/dist/avl/index.js CHANGED
@@ -51383,6 +51383,10 @@ 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);
@@ -51390,31 +51394,33 @@ function useResolvedSchema(schema, pageName) {
51390
51394
  if (!schema) return null;
51391
51395
  try {
51392
51396
  const resolved = schemaToIR(schema);
51393
- const sourceListsByTrait = /* @__PURE__ */ new Map();
51394
- const orbitals = schema.orbitals;
51395
- if (Array.isArray(orbitals)) {
51396
- for (const orb of orbitals) {
51397
- const traits2 = orb.traits;
51398
- if (!Array.isArray(traits2)) continue;
51399
- for (const trait of traits2) {
51400
- const t = trait;
51401
- if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
51402
- const sources = t.listens.map((listen) => {
51403
- const l = listen;
51404
- return l.source;
51405
- });
51406
- sourceListsByTrait.set(t.name, sources);
51407
- }
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);
51408
51404
  }
51409
51405
  }
51410
51406
  for (const [traitName, trait] of resolved.traits) {
51411
- const sources = sourceListsByTrait.get(traitName);
51412
- if (!sources) continue;
51413
- trait.listens.forEach((listen, i) => {
51414
- const src = sources[i];
51415
- if (src !== void 0) {
51416
- listen.source = src;
51417
- }
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(",")
51418
51424
  });
51419
51425
  }
51420
51426
  return resolved;
@@ -51489,6 +51495,9 @@ var ALMADAR_DND_MIME = "application/x-almadar-dnd";
51489
51495
  init_useEventBus();
51490
51496
  typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_API_URL : "http://localhost:3000";
51491
51497
 
51498
+ // runtime/useTraitStateMachine.ts
51499
+ init_logger();
51500
+
51492
51501
  // runtime/createClientEffectHandlers.ts
51493
51502
  function createClientEffectHandlers(options) {
51494
51503
  const { eventBus, slotSetter, navigate, notify } = options;
@@ -51527,6 +51536,7 @@ function createClientEffectHandlers(options) {
51527
51536
  init_EntitySchemaContext();
51528
51537
  init_traitRegistry();
51529
51538
  init_verificationRegistry();
51539
+ var crossTraitLog = createLogger("almadar:ui:cross-trait");
51530
51540
  function toTraitDefinition(binding) {
51531
51541
  return {
51532
51542
  name: binding.trait.name,
@@ -51754,8 +51764,19 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51754
51764
  const currentManager = managerRef.current;
51755
51765
  const actions = slotsActionsRef.current;
51756
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
+ });
51757
51773
  const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
51758
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
+ });
51759
51780
  const emittedByTrait = /* @__PURE__ */ new Map();
51760
51781
  for (const { traitName, result } of results) {
51761
51782
  const binding = bindingMap.get(traitName);
@@ -51999,6 +52020,32 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
51999
52020
  fromBridge: true
52000
52021
  });
52001
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
+ }
52002
52049
  }
52003
52050
  if (results.length > 0) {
52004
52051
  setTraitStates(currentManager.getAllStates());
@@ -52076,13 +52123,21 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
52076
52123
  for (const binding of traitBindings) {
52077
52124
  const ownOrbital = orbitalsByTrait?.[binding.trait.name];
52078
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
+ });
52079
52132
  for (const listen of listens) {
52080
52133
  const sourceTrait = listen.source?.trait;
52081
52134
  if (!sourceTrait) continue;
52082
52135
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52083
52136
  if (!sourceOrbital) continue;
52084
52137
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52138
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52085
52139
  const unsub = eventBus.on(busKey, (event) => {
52140
+ crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52086
52141
  enqueueAndDrain(listen.triggers, event.payload);
52087
52142
  });
52088
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,6 +38827,10 @@ 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);
@@ -38785,31 +38838,33 @@ function useResolvedSchema(schema, pageName) {
38785
38838
  if (!schema) return null;
38786
38839
  try {
38787
38840
  const resolved = core.schemaToIR(schema);
38788
- const sourceListsByTrait = /* @__PURE__ */ new Map();
38789
- const orbitals = schema.orbitals;
38790
- if (Array.isArray(orbitals)) {
38791
- for (const orb of orbitals) {
38792
- const traits2 = orb.traits;
38793
- if (!Array.isArray(traits2)) continue;
38794
- for (const trait of traits2) {
38795
- const t = trait;
38796
- if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
38797
- const sources = t.listens.map((listen) => {
38798
- const l = listen;
38799
- return l.source;
38800
- });
38801
- sourceListsByTrait.set(t.name, sources);
38802
- }
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);
38803
38848
  }
38804
38849
  }
38805
38850
  for (const [traitName, trait] of resolved.traits) {
38806
- const sources = sourceListsByTrait.get(traitName);
38807
- if (!sources) continue;
38808
- trait.listens.forEach((listen, i) => {
38809
- const src = sources[i];
38810
- if (src !== void 0) {
38811
- listen.source = src;
38812
- }
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(",")
38813
38868
  });
38814
38869
  }
38815
38870
  return resolved;
@@ -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,6 +38782,10 @@ 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);
@@ -38740,31 +38793,33 @@ function useResolvedSchema(schema, pageName) {
38740
38793
  if (!schema) return null;
38741
38794
  try {
38742
38795
  const resolved = schemaToIR(schema);
38743
- const sourceListsByTrait = /* @__PURE__ */ new Map();
38744
- const orbitals = schema.orbitals;
38745
- if (Array.isArray(orbitals)) {
38746
- for (const orb of orbitals) {
38747
- const traits2 = orb.traits;
38748
- if (!Array.isArray(traits2)) continue;
38749
- for (const trait of traits2) {
38750
- const t = trait;
38751
- if (typeof t.name !== "string" || !Array.isArray(t.listens)) continue;
38752
- const sources = t.listens.map((listen) => {
38753
- const l = listen;
38754
- return l.source;
38755
- });
38756
- sourceListsByTrait.set(t.name, sources);
38757
- }
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);
38758
38803
  }
38759
38804
  }
38760
38805
  for (const [traitName, trait] of resolved.traits) {
38761
- const sources = sourceListsByTrait.get(traitName);
38762
- if (!sources) continue;
38763
- trait.listens.forEach((listen, i) => {
38764
- const src = sources[i];
38765
- if (src !== void 0) {
38766
- listen.source = src;
38767
- }
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(",")
38768
38823
  });
38769
38824
  }
38770
38825
  return resolved;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.10.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",