uidex 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -102,6 +102,7 @@ interface ReportRecord {
102
102
  interface Registry {
103
103
  add(entity: Entity): void;
104
104
  get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
105
+ matchPattern<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
105
106
  list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>;
106
107
  query(predicate: (entity: Entity) => boolean): Entity[];
107
108
  byScope(scope: Scope): Entity[];
@@ -434,6 +435,11 @@ interface InspectorOptions {
434
435
  x: number;
435
436
  y: number;
436
437
  }) => void;
438
+ /** Fired when the cursor enters an iframe or otherwise leaves the inspectable document. */
439
+ onObscured?: (cursor: {
440
+ x: number;
441
+ y: number;
442
+ }) => void;
437
443
  }
438
444
  interface Inspector {
439
445
  mount(): void;
@@ -635,6 +641,8 @@ interface DetailSurface {
635
641
  entityKind: EntityKind;
636
642
  /** Registry lookup failed — renders the "not found" placeholder. */
637
643
  notFound?: EntityRef;
644
+ /** Entity exists in the DOM but not in the registry (gen file). */
645
+ unregistered?: boolean;
638
646
  /** Entity display name, rendered as the heading. */
639
647
  title?: string;
640
648
  subtitle?: DetailSubtitle;
package/dist/index.d.ts CHANGED
@@ -102,6 +102,7 @@ interface ReportRecord {
102
102
  interface Registry {
103
103
  add(entity: Entity): void;
104
104
  get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
105
+ matchPattern<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
105
106
  list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>;
106
107
  query(predicate: (entity: Entity) => boolean): Entity[];
107
108
  byScope(scope: Scope): Entity[];
@@ -434,6 +435,11 @@ interface InspectorOptions {
434
435
  x: number;
435
436
  y: number;
436
437
  }) => void;
438
+ /** Fired when the cursor enters an iframe or otherwise leaves the inspectable document. */
439
+ onObscured?: (cursor: {
440
+ x: number;
441
+ y: number;
442
+ }) => void;
437
443
  }
438
444
  interface Inspector {
439
445
  mount(): void;
@@ -635,6 +641,8 @@ interface DetailSurface {
635
641
  entityKind: EntityKind;
636
642
  /** Registry lookup failed — renders the "not found" placeholder. */
637
643
  notFound?: EntityRef;
644
+ /** Entity exists in the DOM but not in the registry (gen file). */
645
+ unregistered?: boolean;
638
646
  /** Entity display name, rendered as the heading. */
639
647
  title?: string;
640
648
  subtitle?: DetailSubtitle;
package/dist/index.js CHANGED
@@ -67,6 +67,7 @@ function freezeEntity(entity, flows) {
67
67
  function createRegistry() {
68
68
  const store = emptyStore();
69
69
  let flowsCache = null;
70
+ const patternCache = /* @__PURE__ */ new Map();
70
71
  const getFlows = () => {
71
72
  if (flowsCache === null) flowsCache = Array.from(store.flow.values());
72
73
  return flowsCache;
@@ -76,6 +77,7 @@ function createRegistry() {
76
77
  const key = entityKey(entity);
77
78
  store[entity.kind].set(key, entity);
78
79
  flowsCache = null;
80
+ patternCache.delete(entity.kind);
79
81
  };
80
82
  const get = (kind, id) => {
81
83
  assertEntityKind(kind);
@@ -83,6 +85,38 @@ function createRegistry() {
83
85
  if (raw === void 0) return void 0;
84
86
  return freezeEntity(raw, getFlows());
85
87
  };
88
+ const getPatternsForKind = (kind) => {
89
+ const cached = patternCache.get(kind);
90
+ if (cached !== void 0)
91
+ return cached;
92
+ const patterns = [];
93
+ for (const [key, entity] of store[kind]) {
94
+ if (key.endsWith("*")) {
95
+ patterns.push({
96
+ prefix: key.slice(0, -1),
97
+ entity
98
+ });
99
+ }
100
+ }
101
+ patternCache.set(
102
+ kind,
103
+ patterns
104
+ );
105
+ return patterns;
106
+ };
107
+ const matchPattern = (kind, id) => {
108
+ assertEntityKind(kind);
109
+ const patterns = getPatternsForKind(kind);
110
+ if (patterns.length === 0) return void 0;
111
+ let best;
112
+ for (const entry of patterns) {
113
+ if (id.startsWith(entry.prefix) && (best === void 0 || entry.prefix.length > best.prefix.length)) {
114
+ best = entry;
115
+ }
116
+ }
117
+ if (best === void 0) return void 0;
118
+ return freezeEntity(best.entity, getFlows());
119
+ };
86
120
  const list = (kind) => {
87
121
  assertEntityKind(kind);
88
122
  const flows = getFlows();
@@ -133,6 +167,7 @@ function createRegistry() {
133
167
  return {
134
168
  add,
135
169
  get,
170
+ matchPattern,
136
171
  list,
137
172
  query,
138
173
  byScope,
@@ -1094,6 +1129,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1094
1129
  .relative {
1095
1130
  position: relative;
1096
1131
  }
1132
+ .static {
1133
+ position: static;
1134
+ }
1097
1135
  .inset-0 {
1098
1136
  inset: calc(var(--spacing) * 0);
1099
1137
  }
@@ -3484,16 +3522,18 @@ function createCursorTooltip(deps) {
3484
3522
  const renderBody = () => {
3485
3523
  body.replaceChildren();
3486
3524
  if (typeof currentContent === "string") {
3487
- applyColor(DEFAULT_TOOLTIP_COLOR);
3525
+ applyColor("#a1a1aa");
3526
+ el2.style.opacity = "0.6";
3488
3527
  body.append(document.createTextNode(currentContent));
3489
3528
  return;
3490
3529
  }
3491
3530
  if (!currentContent) return;
3531
+ el2.style.opacity = "1";
3492
3532
  const { entity, node } = currentContent;
3493
3533
  const style = KIND_STYLE[entity.kind];
3494
3534
  const demoted = entity.kind === "primitive";
3495
3535
  applyColor(style?.color ?? DEFAULT_TOOLTIP_COLOR);
3496
- el2.style.opacity = demoted ? "0.55" : "1";
3536
+ if (demoted) el2.style.opacity = "0.55";
3497
3537
  if (style) {
3498
3538
  const svg2 = createLucideElement(style.icon);
3499
3539
  svg2.setAttribute("aria-hidden", "true");
@@ -3544,7 +3584,7 @@ function createCursorTooltip(deps) {
3544
3584
  // src/browser/surface/inspector.ts
3545
3585
  function entityForRef(ref2, registry) {
3546
3586
  if (registry) {
3547
- const found = registry.get(ref2.kind, ref2.id);
3587
+ const found = registry.get(ref2.kind, ref2.id) ?? registry.matchPattern?.(ref2.kind, ref2.id);
3548
3588
  if (found) return found;
3549
3589
  }
3550
3590
  if (ref2.kind === "route") return { kind: "route", path: ref2.id, page: ref2.id };
@@ -3654,7 +3694,8 @@ function createInspector(options) {
3654
3694
  resolveAll = (target) => defaultResolveAllMatches(target, registry),
3655
3695
  onHover,
3656
3696
  onSelect,
3657
- onCycle
3697
+ onCycle,
3698
+ onObscured
3658
3699
  } = options;
3659
3700
  let mounted = false;
3660
3701
  let currentEl = null;
@@ -3663,6 +3704,13 @@ function createInspector(options) {
3663
3704
  let layerIndex = 0;
3664
3705
  let lastCursor = { x: 0, y: 0 };
3665
3706
  const makeStack = () => stack.length > 0 ? { matches: stack, index: layerIndex, current: stack[layerIndex] } : null;
3707
+ const onDocumentLeave = () => {
3708
+ currentEl = null;
3709
+ stack = [];
3710
+ layerIndex = 0;
3711
+ session.highlight.unhover();
3712
+ onObscured?.(lastCursor);
3713
+ };
3666
3714
  const onMouseMove = (e) => {
3667
3715
  if (!(e.target instanceof Element)) return;
3668
3716
  const matches = resolveAll(e.target);
@@ -3715,6 +3763,7 @@ function createInspector(options) {
3715
3763
  document.head.appendChild(cursorStyleEl);
3716
3764
  }
3717
3765
  document.addEventListener("mousemove", onMouseMove);
3766
+ document.addEventListener("mouseleave", onDocumentLeave);
3718
3767
  document.addEventListener("click", onClick, true);
3719
3768
  document.addEventListener("contextmenu", onContextMenu, true);
3720
3769
  },
@@ -3729,6 +3778,7 @@ function createInspector(options) {
3729
3778
  cursorStyleEl = null;
3730
3779
  }
3731
3780
  document.removeEventListener("mousemove", onMouseMove);
3781
+ document.removeEventListener("mouseleave", onDocumentLeave);
3732
3782
  document.removeEventListener("click", onClick, true);
3733
3783
  document.removeEventListener("contextmenu", onContextMenu, true);
3734
3784
  session.highlight.unhover();
@@ -4636,6 +4686,10 @@ function createSurfaceShell(options) {
4636
4686
  },
4637
4687
  onCycle: (stack, cursor) => {
4638
4688
  showStack(stack, cursor);
4689
+ },
4690
+ onObscured: (cursor) => {
4691
+ overlay.hide();
4692
+ tooltip.update("iframe", cursor);
4639
4693
  }
4640
4694
  });
4641
4695
  cleanup.add(inspector);
@@ -5545,6 +5599,14 @@ var badgeVariants = cva(badgeBase, {
5545
5599
  }
5546
5600
  }
5547
5601
  });
5602
+ function badgeTpl(content, options = {}) {
5603
+ const { variant, size, class: extra } = options;
5604
+ return html`
5605
+ <span class=${cn(badgeVariants({ variant, size }), extra)} data-slot="badge"
5606
+ >${content}</span
5607
+ >
5608
+ `;
5609
+ }
5548
5610
 
5549
5611
  // src/browser/views/primitives/chip.ts
5550
5612
  var CHIP_CLASS = "inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground";
@@ -6901,7 +6963,10 @@ function renderDetailSurface(surface, ctx, root) {
6901
6963
  >
6902
6964
  ${surface.title}
6903
6965
  </h2>` : nothing}
6904
- <span class="ml-auto">${kindBadgeTpl(surface.entityKind)}</span>
6966
+ <span class="ml-auto flex items-center gap-1">
6967
+ ${surface.unregistered ? badgeTpl("Unregistered", { variant: "warning", size: "sm" }) : nothing}
6968
+ ${kindBadgeTpl(surface.entityKind)}
6969
+ </span>
6905
6970
  </div>
6906
6971
  ${surface.subtitle ? subtitleTpl(surface.subtitle) : nothing}
6907
6972
  <div
@@ -9787,12 +9852,11 @@ function createEntityDetailView(config) {
9787
9852
  if (!ctx.ref || ctx.ref.kind !== kind) {
9788
9853
  return { kind: "detail", entityKind: kind };
9789
9854
  }
9790
- const entity = ctx.registry.get(kind, ctx.ref.id);
9791
- if (!entity) {
9792
- return { kind: "detail", entityKind: kind, notFound: ctx.ref };
9793
- }
9794
- const metaEntity = entity;
9795
- const meta = metaEntity.meta;
9855
+ const exactEntity = ctx.registry.get(kind, ctx.ref.id);
9856
+ const patternEntity = exactEntity ? void 0 : ctx.registry.matchPattern?.(kind, ctx.ref.id);
9857
+ const entity = exactEntity ?? patternEntity;
9858
+ const metaEntity = entity ? entity : null;
9859
+ const meta = metaEntity?.meta;
9796
9860
  const actions = [];
9797
9861
  const cloud = ctx.cloud;
9798
9862
  actions.push({ ...reportAction(ctx.ref), group: "Report" });
@@ -9810,14 +9874,16 @@ function createEntityDetailView(config) {
9810
9874
  actions.push({ ...highlightElementAction(ctx.ref), group: "Inspect" });
9811
9875
  actions.push({ ...copyScreenshotAction(ctx.ref), group: "Inspect" });
9812
9876
  }
9813
- actions.push({
9814
- ...copyPathAction(ctx.ref, metaEntity.loc),
9815
- group: "Inspect"
9816
- });
9817
- actions.push({
9818
- ...copySnapshotAction(ctx.ref, metaEntity.loc),
9819
- group: "Inspect"
9820
- });
9877
+ if (metaEntity?.loc) {
9878
+ actions.push({
9879
+ ...copyPathAction(ctx.ref, metaEntity.loc),
9880
+ group: "Inspect"
9881
+ });
9882
+ actions.push({
9883
+ ...copySnapshotAction(ctx.ref, metaEntity.loc),
9884
+ group: "Inspect"
9885
+ });
9886
+ }
9821
9887
  const sections = [];
9822
9888
  if (meta?.description) {
9823
9889
  sections.push({ id: "description", text: meta.description });
@@ -9825,8 +9891,10 @@ function createEntityDetailView(config) {
9825
9891
  if (offerAcceptance && meta?.acceptance?.length) {
9826
9892
  sections.push({ id: "acceptance", items: meta.acceptance });
9827
9893
  }
9828
- for (const s of config.extraSections?.(ctx, entity) ?? []) {
9829
- sections.push(s);
9894
+ if (entity) {
9895
+ for (const s of config.extraSections?.(ctx, entity) ?? []) {
9896
+ sections.push(s);
9897
+ }
9830
9898
  }
9831
9899
  if (!DOM_BACKED_KINDS2.has(kind)) {
9832
9900
  sections.push({
@@ -9855,8 +9923,9 @@ function createEntityDetailView(config) {
9855
9923
  return {
9856
9924
  kind: "detail",
9857
9925
  entityKind: kind,
9858
- title: displayName(metaEntity),
9859
- subtitle: config.subtitle?.(ctx, entity),
9926
+ title: patternEntity ? ctx.ref.id : metaEntity ? displayName(metaEntity) : ctx.ref.id,
9927
+ subtitle: exactEntity ? config.subtitle?.(ctx, exactEntity) : void 0,
9928
+ unregistered: !entity,
9860
9929
  actions,
9861
9930
  sections
9862
9931
  };