@almadar/ui 4.15.4 → 4.15.6

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.
@@ -4348,6 +4348,13 @@ function useUISlotManager() {
4348
4348
  indexTraitRender(content.sourceTrait, content);
4349
4349
  notifyTraitSubscribers(content.sourceTrait, content);
4350
4350
  }
4351
+ slotLog.info("slot:written", {
4352
+ slot: config.target,
4353
+ sourceKey,
4354
+ sourceTrait: content.sourceTrait,
4355
+ patternType: content.pattern,
4356
+ priority: content.priority
4357
+ });
4351
4358
  notifySubscribers(config.target, aggregateSlot(nextSources));
4352
4359
  return nextAll;
4353
4360
  });
@@ -4385,7 +4392,10 @@ function useUISlotManager() {
4385
4392
  const sourceKey = sourceTrait;
4386
4393
  setSources((prev) => {
4387
4394
  const slotSources = prev[slot];
4388
- if (!slotSources || !(sourceKey in slotSources)) return prev;
4395
+ if (!slotSources || !(sourceKey in slotSources)) {
4396
+ slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
4397
+ return prev;
4398
+ }
4389
4399
  const content = slotSources[sourceKey];
4390
4400
  const timer = timersRef.current.get(content.id);
4391
4401
  if (timer) {
@@ -4399,6 +4409,7 @@ function useUISlotManager() {
4399
4409
  }
4400
4410
  const nextSources = { ...slotSources };
4401
4411
  delete nextSources[sourceKey];
4412
+ slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
4402
4413
  notifySubscribers(slot, aggregateSlot(nextSources));
4403
4414
  return { ...prev, [slot]: nextSources };
4404
4415
  });
@@ -4517,10 +4528,12 @@ function useUISlotManager() {
4517
4528
  updateTraitContent
4518
4529
  };
4519
4530
  }
4520
- var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
4531
+ var slotLog, DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
4521
4532
  var init_useUISlots = __esm({
4522
4533
  "hooks/useUISlots.ts"() {
4523
4534
  "use client";
4535
+ init_logger();
4536
+ slotLog = createLogger("almadar:ui:useUISlots");
4524
4537
  DEFAULT_SOURCE_KEY = "__default__";
4525
4538
  MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
4526
4539
  ALL_SLOTS = [
@@ -5426,11 +5439,11 @@ function refId(obj) {
5426
5439
  refIds.set(obj, id);
5427
5440
  return id;
5428
5441
  }
5429
- var slotLog, refIds, nextRefId;
5442
+ var slotLog2, refIds, nextRefId;
5430
5443
  var init_slot_types = __esm({
5431
5444
  "runtime/ui/slot-types.ts"() {
5432
5445
  init_logger();
5433
- slotLog = createLogger("almadar:ui:slot-render");
5446
+ slotLog2 = createLogger("almadar:ui:slot-render");
5434
5447
  refIds = /* @__PURE__ */ new WeakMap();
5435
5448
  nextRefId = 1;
5436
5449
  }
@@ -21985,6 +21998,17 @@ function DataGrid({
21985
21998
  };
21986
21999
  eventBus.emit(`UI:${action.event}`, payload);
21987
22000
  };
22001
+ const hasRenderProp = typeof children === "function";
22002
+ React127.useEffect(() => {
22003
+ if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
22004
+ const renderItemRaw = schemaRenderItem;
22005
+ const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
22006
+ dataGridLog.warn("renderItem-unresolved", {
22007
+ rowCount: data.length,
22008
+ renderItemIsFnLambda: isFnLambda
22009
+ });
22010
+ }
22011
+ }, [data, hasRenderProp, schemaRenderItem, fields]);
21988
22012
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
21989
22013
  const colsClass = cols ? {
21990
22014
  1: "grid-cols-1",
@@ -22003,17 +22027,6 @@ function DataGrid({
22003
22027
  if (data.length === 0) {
22004
22028
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
22005
22029
  }
22006
- const hasRenderProp = typeof children === "function";
22007
- React127.useEffect(() => {
22008
- if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
22009
- const renderItemRaw = schemaRenderItem;
22010
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
22011
- dataGridLog.warn("renderItem-unresolved", {
22012
- rowCount: data.length,
22013
- renderItemIsFnLambda: isFnLambda
22014
- });
22015
- }
22016
- }, [data, hasRenderProp, schemaRenderItem, fields]);
22017
22030
  const allIds = data.map((item, i) => item.id || String(i));
22018
22031
  const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
22019
22032
  const someSelected = selectedIds.size > 0;
@@ -22913,7 +22926,7 @@ var init_FilterGroup = __esm({
22913
22926
  eventBus.emit("UI:FILTER", {
22914
22927
  entity,
22915
22928
  field,
22916
- value: value === "all" ? null : value,
22929
+ value: value === "all" || value === null ? "" : value,
22917
22930
  query
22918
22931
  });
22919
22932
  },
@@ -23725,7 +23738,7 @@ var init_SearchInput = __esm({
23725
23738
  /* @__PURE__ */ jsxRuntime.jsx(
23726
23739
  Input,
23727
23740
  {
23728
- type: "search",
23741
+ type: "text",
23729
23742
  value: searchValue,
23730
23743
  onChange: handleChange,
23731
23744
  placeholder: resolvedPlaceholder,
@@ -47008,7 +47021,7 @@ function SlotContentRenderer({
47008
47021
  }) {
47009
47022
  const entityProp = content.props.entity;
47010
47023
  if (content.pattern === "form-section") {
47011
- slotLog.debug("SlotContentRenderer:form-section-render", {
47024
+ slotLog2.debug("SlotContentRenderer:form-section-render", {
47012
47025
  contentId: content.id,
47013
47026
  sourceTrait: content.sourceTrait,
47014
47027
  entityRefId: refId(entityProp),
@@ -51757,6 +51770,7 @@ init_traitRegistry();
51757
51770
  init_verificationRegistry();
51758
51771
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
51759
51772
  var flushLog = createLogger("almadar:ui:slot-flush");
51773
+ var stateLog = createLogger("almadar:ui:state-transitions");
51760
51774
  function toTraitDefinition(binding) {
51761
51775
  return {
51762
51776
  name: binding.trait.name,
@@ -52189,21 +52203,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52189
52203
  const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
52190
52204
  try {
52191
52205
  await executor.executeAll(result.effects);
52192
- console.log(
52193
- "[TraitStateMachine] After executeAll, pendingSlots:",
52194
- Object.fromEntries(pendingSlots.entries())
52195
- );
52206
+ stateLog.info("transition:render-ui-dispatched", {
52207
+ traitName,
52208
+ fromState: result.previousState,
52209
+ toState: result.newState,
52210
+ event: eventKey,
52211
+ slotsTouched: Array.from(pendingSlots.keys()).join(","),
52212
+ patternTypes: Array.from(pendingSlots.entries()).map(
52213
+ ([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
52214
+ ).join(";")
52215
+ });
52196
52216
  void slotSource;
52197
52217
  for (const [slot, patterns] of pendingSlots) {
52198
52218
  flushSlot(traitName, slot, patterns);
52199
52219
  }
52200
52220
  } catch (error) {
52201
- console.error(
52202
- "[TraitStateMachine] Effect execution error:",
52203
- error,
52204
- "| effects:",
52205
- JSON.stringify(result.effects)
52206
- );
52221
+ stateLog.error("transition:effect-error", {
52222
+ traitName,
52223
+ fromState: result.previousState,
52224
+ toState: result.newState,
52225
+ event: eventKey,
52226
+ error: error instanceof Error ? error.message : String(error),
52227
+ effectCount: result.effects.length
52228
+ });
52207
52229
  }
52208
52230
  } else if (!result.executed) {
52209
52231
  if (result.guardResult === false) {
@@ -52349,13 +52371,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52349
52371
  if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
52350
52372
  continue;
52351
52373
  }
52352
- const unsub = eventBus.on(`UI:${orbitalName}.${traitName}.${eventKey}`, (event) => {
52374
+ const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
52375
+ crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
52376
+ const unsub = eventBus.on(selfBusKey, (event) => {
52353
52377
  if (event.source && event.source.fromBridge) {
52378
+ crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
52354
52379
  return;
52355
52380
  }
52381
+ crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
52356
52382
  enqueueAndDrain(eventKey, event.payload);
52357
52383
  });
52358
- unsubscribes.push(unsub);
52384
+ unsubscribes.push(() => {
52385
+ crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
52386
+ unsub();
52387
+ });
52359
52388
  }
52360
52389
  }
52361
52390
  for (const binding of traitBindings) {
@@ -52373,18 +52402,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52373
52402
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52374
52403
  if (!sourceOrbital) continue;
52375
52404
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52376
- crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52405
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
52377
52406
  const unsub = eventBus.on(busKey, (event) => {
52378
52407
  crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52379
52408
  enqueueAndDrain(listen.triggers, event.payload);
52380
52409
  });
52381
- unsubscribes.push(unsub);
52410
+ unsubscribes.push(() => {
52411
+ crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52412
+ unsub();
52413
+ });
52382
52414
  }
52383
52415
  }
52384
52416
  return () => {
52417
+ crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
52385
52418
  for (const unsub of unsubscribes) {
52386
52419
  unsub();
52387
52420
  }
52421
+ crossTraitLog.debug("cleanup:done", {});
52388
52422
  };
52389
52423
  }, [traitBindings, eventBus, enqueueAndDrain]);
52390
52424
  return {
package/dist/avl/index.js CHANGED
@@ -4302,6 +4302,13 @@ function useUISlotManager() {
4302
4302
  indexTraitRender(content.sourceTrait, content);
4303
4303
  notifyTraitSubscribers(content.sourceTrait, content);
4304
4304
  }
4305
+ slotLog.info("slot:written", {
4306
+ slot: config.target,
4307
+ sourceKey,
4308
+ sourceTrait: content.sourceTrait,
4309
+ patternType: content.pattern,
4310
+ priority: content.priority
4311
+ });
4305
4312
  notifySubscribers(config.target, aggregateSlot(nextSources));
4306
4313
  return nextAll;
4307
4314
  });
@@ -4339,7 +4346,10 @@ function useUISlotManager() {
4339
4346
  const sourceKey = sourceTrait;
4340
4347
  setSources((prev) => {
4341
4348
  const slotSources = prev[slot];
4342
- if (!slotSources || !(sourceKey in slotSources)) return prev;
4349
+ if (!slotSources || !(sourceKey in slotSources)) {
4350
+ slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
4351
+ return prev;
4352
+ }
4343
4353
  const content = slotSources[sourceKey];
4344
4354
  const timer = timersRef.current.get(content.id);
4345
4355
  if (timer) {
@@ -4353,6 +4363,7 @@ function useUISlotManager() {
4353
4363
  }
4354
4364
  const nextSources = { ...slotSources };
4355
4365
  delete nextSources[sourceKey];
4366
+ slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
4356
4367
  notifySubscribers(slot, aggregateSlot(nextSources));
4357
4368
  return { ...prev, [slot]: nextSources };
4358
4369
  });
@@ -4471,10 +4482,12 @@ function useUISlotManager() {
4471
4482
  updateTraitContent
4472
4483
  };
4473
4484
  }
4474
- var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
4485
+ var slotLog, DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
4475
4486
  var init_useUISlots = __esm({
4476
4487
  "hooks/useUISlots.ts"() {
4477
4488
  "use client";
4489
+ init_logger();
4490
+ slotLog = createLogger("almadar:ui:useUISlots");
4478
4491
  DEFAULT_SOURCE_KEY = "__default__";
4479
4492
  MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
4480
4493
  ALL_SLOTS = [
@@ -5380,11 +5393,11 @@ function refId(obj) {
5380
5393
  refIds.set(obj, id);
5381
5394
  return id;
5382
5395
  }
5383
- var slotLog, refIds, nextRefId;
5396
+ var slotLog2, refIds, nextRefId;
5384
5397
  var init_slot_types = __esm({
5385
5398
  "runtime/ui/slot-types.ts"() {
5386
5399
  init_logger();
5387
- slotLog = createLogger("almadar:ui:slot-render");
5400
+ slotLog2 = createLogger("almadar:ui:slot-render");
5388
5401
  refIds = /* @__PURE__ */ new WeakMap();
5389
5402
  nextRefId = 1;
5390
5403
  }
@@ -21939,6 +21952,17 @@ function DataGrid({
21939
21952
  };
21940
21953
  eventBus.emit(`UI:${action.event}`, payload);
21941
21954
  };
21955
+ const hasRenderProp = typeof children === "function";
21956
+ useEffect(() => {
21957
+ if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
21958
+ const renderItemRaw = schemaRenderItem;
21959
+ const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
21960
+ dataGridLog.warn("renderItem-unresolved", {
21961
+ rowCount: data.length,
21962
+ renderItemIsFnLambda: isFnLambda
21963
+ });
21964
+ }
21965
+ }, [data, hasRenderProp, schemaRenderItem, fields]);
21942
21966
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
21943
21967
  const colsClass = cols ? {
21944
21968
  1: "grid-cols-1",
@@ -21957,17 +21981,6 @@ function DataGrid({
21957
21981
  if (data.length === 0) {
21958
21982
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
21959
21983
  }
21960
- const hasRenderProp = typeof children === "function";
21961
- useEffect(() => {
21962
- if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
21963
- const renderItemRaw = schemaRenderItem;
21964
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
21965
- dataGridLog.warn("renderItem-unresolved", {
21966
- rowCount: data.length,
21967
- renderItemIsFnLambda: isFnLambda
21968
- });
21969
- }
21970
- }, [data, hasRenderProp, schemaRenderItem, fields]);
21971
21984
  const allIds = data.map((item, i) => item.id || String(i));
21972
21985
  const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
21973
21986
  const someSelected = selectedIds.size > 0;
@@ -22867,7 +22880,7 @@ var init_FilterGroup = __esm({
22867
22880
  eventBus.emit("UI:FILTER", {
22868
22881
  entity,
22869
22882
  field,
22870
- value: value === "all" ? null : value,
22883
+ value: value === "all" || value === null ? "" : value,
22871
22884
  query
22872
22885
  });
22873
22886
  },
@@ -23679,7 +23692,7 @@ var init_SearchInput = __esm({
23679
23692
  /* @__PURE__ */ jsx(
23680
23693
  Input,
23681
23694
  {
23682
- type: "search",
23695
+ type: "text",
23683
23696
  value: searchValue,
23684
23697
  onChange: handleChange,
23685
23698
  placeholder: resolvedPlaceholder,
@@ -46962,7 +46975,7 @@ function SlotContentRenderer({
46962
46975
  }) {
46963
46976
  const entityProp = content.props.entity;
46964
46977
  if (content.pattern === "form-section") {
46965
- slotLog.debug("SlotContentRenderer:form-section-render", {
46978
+ slotLog2.debug("SlotContentRenderer:form-section-render", {
46966
46979
  contentId: content.id,
46967
46980
  sourceTrait: content.sourceTrait,
46968
46981
  entityRefId: refId(entityProp),
@@ -51711,6 +51724,7 @@ init_traitRegistry();
51711
51724
  init_verificationRegistry();
51712
51725
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
51713
51726
  var flushLog = createLogger("almadar:ui:slot-flush");
51727
+ var stateLog = createLogger("almadar:ui:state-transitions");
51714
51728
  function toTraitDefinition(binding) {
51715
51729
  return {
51716
51730
  name: binding.trait.name,
@@ -52143,21 +52157,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52143
52157
  const executor = new EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
52144
52158
  try {
52145
52159
  await executor.executeAll(result.effects);
52146
- console.log(
52147
- "[TraitStateMachine] After executeAll, pendingSlots:",
52148
- Object.fromEntries(pendingSlots.entries())
52149
- );
52160
+ stateLog.info("transition:render-ui-dispatched", {
52161
+ traitName,
52162
+ fromState: result.previousState,
52163
+ toState: result.newState,
52164
+ event: eventKey,
52165
+ slotsTouched: Array.from(pendingSlots.keys()).join(","),
52166
+ patternTypes: Array.from(pendingSlots.entries()).map(
52167
+ ([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
52168
+ ).join(";")
52169
+ });
52150
52170
  void slotSource;
52151
52171
  for (const [slot, patterns] of pendingSlots) {
52152
52172
  flushSlot(traitName, slot, patterns);
52153
52173
  }
52154
52174
  } catch (error) {
52155
- console.error(
52156
- "[TraitStateMachine] Effect execution error:",
52157
- error,
52158
- "| effects:",
52159
- JSON.stringify(result.effects)
52160
- );
52175
+ stateLog.error("transition:effect-error", {
52176
+ traitName,
52177
+ fromState: result.previousState,
52178
+ toState: result.newState,
52179
+ event: eventKey,
52180
+ error: error instanceof Error ? error.message : String(error),
52181
+ effectCount: result.effects.length
52182
+ });
52161
52183
  }
52162
52184
  } else if (!result.executed) {
52163
52185
  if (result.guardResult === false) {
@@ -52303,13 +52325,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52303
52325
  if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
52304
52326
  continue;
52305
52327
  }
52306
- const unsub = eventBus.on(`UI:${orbitalName}.${traitName}.${eventKey}`, (event) => {
52328
+ const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
52329
+ crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
52330
+ const unsub = eventBus.on(selfBusKey, (event) => {
52307
52331
  if (event.source && event.source.fromBridge) {
52332
+ crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
52308
52333
  return;
52309
52334
  }
52335
+ crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
52310
52336
  enqueueAndDrain(eventKey, event.payload);
52311
52337
  });
52312
- unsubscribes.push(unsub);
52338
+ unsubscribes.push(() => {
52339
+ crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
52340
+ unsub();
52341
+ });
52313
52342
  }
52314
52343
  }
52315
52344
  for (const binding of traitBindings) {
@@ -52327,18 +52356,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52327
52356
  const sourceOrbital = listen.source?.orbital ?? ownOrbital;
52328
52357
  if (!sourceOrbital) continue;
52329
52358
  const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
52330
- crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52359
+ crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
52331
52360
  const unsub = eventBus.on(busKey, (event) => {
52332
52361
  crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52333
52362
  enqueueAndDrain(listen.triggers, event.payload);
52334
52363
  });
52335
- unsubscribes.push(unsub);
52364
+ unsubscribes.push(() => {
52365
+ crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
52366
+ unsub();
52367
+ });
52336
52368
  }
52337
52369
  }
52338
52370
  return () => {
52371
+ crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
52339
52372
  for (const unsub of unsubscribes) {
52340
52373
  unsub();
52341
52374
  }
52375
+ crossTraitLog.debug("cleanup:done", {});
52342
52376
  };
52343
52377
  }, [traitBindings, eventBus, enqueueAndDrain]);
52344
52378
  return {
@@ -17426,6 +17426,17 @@ function DataGrid({
17426
17426
  };
17427
17427
  eventBus.emit(`UI:${action.event}`, payload);
17428
17428
  };
17429
+ const hasRenderProp = typeof children === "function";
17430
+ React110.useEffect(() => {
17431
+ if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
17432
+ const renderItemRaw = schemaRenderItem;
17433
+ const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
17434
+ dataGridLog.warn("renderItem-unresolved", {
17435
+ rowCount: data.length,
17436
+ renderItemIsFnLambda: isFnLambda
17437
+ });
17438
+ }
17439
+ }, [data, hasRenderProp, schemaRenderItem, fields]);
17429
17440
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
17430
17441
  const colsClass = cols ? {
17431
17442
  1: "grid-cols-1",
@@ -17444,17 +17455,6 @@ function DataGrid({
17444
17455
  if (data.length === 0) {
17445
17456
  return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17446
17457
  }
17447
- const hasRenderProp = typeof children === "function";
17448
- React110.useEffect(() => {
17449
- if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
17450
- const renderItemRaw = schemaRenderItem;
17451
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
17452
- dataGridLog.warn("renderItem-unresolved", {
17453
- rowCount: data.length,
17454
- renderItemIsFnLambda: isFnLambda
17455
- });
17456
- }
17457
- }, [data, hasRenderProp, schemaRenderItem, fields]);
17458
17458
  const allIds = data.map((item, i) => item.id || String(i));
17459
17459
  const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
17460
17460
  const someSelected = selectedIds.size > 0;
@@ -18362,7 +18362,7 @@ var init_FilterGroup = __esm({
18362
18362
  eventBus.emit("UI:FILTER", {
18363
18363
  entity,
18364
18364
  field,
18365
- value: value === "all" ? null : value,
18365
+ value: value === "all" || value === null ? "" : value,
18366
18366
  query
18367
18367
  });
18368
18368
  },
@@ -19174,7 +19174,7 @@ var init_SearchInput = __esm({
19174
19174
  /* @__PURE__ */ jsxRuntime.jsx(
19175
19175
  exports.Input,
19176
19176
  {
19177
- type: "search",
19177
+ type: "text",
19178
19178
  value: searchValue,
19179
19179
  onChange: handleChange,
19180
19180
  placeholder: resolvedPlaceholder,
@@ -40897,6 +40897,10 @@ function useDeepAgentGeneration() {
40897
40897
 
40898
40898
  // hooks/index.ts
40899
40899
  init_useEventBus();
40900
+
40901
+ // hooks/useUISlots.ts
40902
+ init_logger();
40903
+ var slotLog2 = createLogger("almadar:ui:useUISlots");
40900
40904
  var DEFAULT_SOURCE_KEY = "__default__";
40901
40905
  var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
40902
40906
  var ALL_SLOTS2 = [
@@ -41055,6 +41059,13 @@ function useUISlotManager() {
41055
41059
  indexTraitRender(content.sourceTrait, content);
41056
41060
  notifyTraitSubscribers(content.sourceTrait, content);
41057
41061
  }
41062
+ slotLog2.info("slot:written", {
41063
+ slot: config.target,
41064
+ sourceKey,
41065
+ sourceTrait: content.sourceTrait,
41066
+ patternType: content.pattern,
41067
+ priority: content.priority
41068
+ });
41058
41069
  notifySubscribers(config.target, aggregateSlot(nextSources));
41059
41070
  return nextAll;
41060
41071
  });
@@ -41092,7 +41103,10 @@ function useUISlotManager() {
41092
41103
  const sourceKey = sourceTrait;
41093
41104
  setSources((prev) => {
41094
41105
  const slotSources = prev[slot];
41095
- if (!slotSources || !(sourceKey in slotSources)) return prev;
41106
+ if (!slotSources || !(sourceKey in slotSources)) {
41107
+ slotLog2.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
41108
+ return prev;
41109
+ }
41096
41110
  const content = slotSources[sourceKey];
41097
41111
  const timer = timersRef.current.get(content.id);
41098
41112
  if (timer) {
@@ -41106,6 +41120,7 @@ function useUISlotManager() {
41106
41120
  }
41107
41121
  const nextSources = { ...slotSources };
41108
41122
  delete nextSources[sourceKey];
41123
+ slotLog2.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
41109
41124
  notifySubscribers(slot, aggregateSlot(nextSources));
41110
41125
  return { ...prev, [slot]: nextSources };
41111
41126
  });
@@ -17381,6 +17381,17 @@ function DataGrid({
17381
17381
  };
17382
17382
  eventBus.emit(`UI:${action.event}`, payload);
17383
17383
  };
17384
+ const hasRenderProp = typeof children === "function";
17385
+ useEffect(() => {
17386
+ if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
17387
+ const renderItemRaw = schemaRenderItem;
17388
+ const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
17389
+ dataGridLog.warn("renderItem-unresolved", {
17390
+ rowCount: data.length,
17391
+ renderItemIsFnLambda: isFnLambda
17392
+ });
17393
+ }
17394
+ }, [data, hasRenderProp, schemaRenderItem, fields]);
17384
17395
  const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
17385
17396
  const colsClass = cols ? {
17386
17397
  1: "grid-cols-1",
@@ -17399,17 +17410,6 @@ function DataGrid({
17399
17410
  if (data.length === 0) {
17400
17411
  return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
17401
17412
  }
17402
- const hasRenderProp = typeof children === "function";
17403
- useEffect(() => {
17404
- if (data.length > 0 && !hasRenderProp && (!fields || fields.length === 0)) {
17405
- const renderItemRaw = schemaRenderItem;
17406
- const isFnLambda = Array.isArray(renderItemRaw) && renderItemRaw.length >= 3 && (renderItemRaw[0] === "fn" || renderItemRaw[0] === "lambda");
17407
- dataGridLog.warn("renderItem-unresolved", {
17408
- rowCount: data.length,
17409
- renderItemIsFnLambda: isFnLambda
17410
- });
17411
- }
17412
- }, [data, hasRenderProp, schemaRenderItem, fields]);
17413
17413
  const allIds = data.map((item, i) => item.id || String(i));
17414
17414
  const allSelected = allIds.length > 0 && allIds.every((id) => selectedIds.has(id));
17415
17415
  const someSelected = selectedIds.size > 0;
@@ -18317,7 +18317,7 @@ var init_FilterGroup = __esm({
18317
18317
  eventBus.emit("UI:FILTER", {
18318
18318
  entity,
18319
18319
  field,
18320
- value: value === "all" ? null : value,
18320
+ value: value === "all" || value === null ? "" : value,
18321
18321
  query
18322
18322
  });
18323
18323
  },
@@ -19129,7 +19129,7 @@ var init_SearchInput = __esm({
19129
19129
  /* @__PURE__ */ jsx(
19130
19130
  Input,
19131
19131
  {
19132
- type: "search",
19132
+ type: "text",
19133
19133
  value: searchValue,
19134
19134
  onChange: handleChange,
19135
19135
  placeholder: resolvedPlaceholder,
@@ -40852,6 +40852,10 @@ function useDeepAgentGeneration() {
40852
40852
 
40853
40853
  // hooks/index.ts
40854
40854
  init_useEventBus();
40855
+
40856
+ // hooks/useUISlots.ts
40857
+ init_logger();
40858
+ var slotLog2 = createLogger("almadar:ui:useUISlots");
40855
40859
  var DEFAULT_SOURCE_KEY = "__default__";
40856
40860
  var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
40857
40861
  var ALL_SLOTS2 = [
@@ -41010,6 +41014,13 @@ function useUISlotManager() {
41010
41014
  indexTraitRender(content.sourceTrait, content);
41011
41015
  notifyTraitSubscribers(content.sourceTrait, content);
41012
41016
  }
41017
+ slotLog2.info("slot:written", {
41018
+ slot: config.target,
41019
+ sourceKey,
41020
+ sourceTrait: content.sourceTrait,
41021
+ patternType: content.pattern,
41022
+ priority: content.priority
41023
+ });
41013
41024
  notifySubscribers(config.target, aggregateSlot(nextSources));
41014
41025
  return nextAll;
41015
41026
  });
@@ -41047,7 +41058,10 @@ function useUISlotManager() {
41047
41058
  const sourceKey = sourceTrait;
41048
41059
  setSources((prev) => {
41049
41060
  const slotSources = prev[slot];
41050
- if (!slotSources || !(sourceKey in slotSources)) return prev;
41061
+ if (!slotSources || !(sourceKey in slotSources)) {
41062
+ slotLog2.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
41063
+ return prev;
41064
+ }
41051
41065
  const content = slotSources[sourceKey];
41052
41066
  const timer = timersRef.current.get(content.id);
41053
41067
  if (timer) {
@@ -41061,6 +41075,7 @@ function useUISlotManager() {
41061
41075
  }
41062
41076
  const nextSources = { ...slotSources };
41063
41077
  delete nextSources[sourceKey];
41078
+ slotLog2.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
41064
41079
  notifySubscribers(slot, aggregateSlot(nextSources));
41065
41080
  return { ...prev, [slot]: nextSources };
41066
41081
  });