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.
@@ -94,6 +94,7 @@ interface ReportRecord {
94
94
  interface Registry {
95
95
  add(entity: Entity): void;
96
96
  get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
97
+ matchPattern<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
97
98
  list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>;
98
99
  query(predicate: (entity: Entity) => boolean): Entity[];
99
100
  byScope(scope: Scope): Entity[];
@@ -362,6 +363,8 @@ interface DetailSurface {
362
363
  entityKind: EntityKind;
363
364
  /** Registry lookup failed — renders the "not found" placeholder. */
364
365
  notFound?: EntityRef;
366
+ /** Entity exists in the DOM but not in the registry (gen file). */
367
+ unregistered?: boolean;
365
368
  /** Entity display name, rendered as the heading. */
366
369
  title?: string;
367
370
  subtitle?: DetailSubtitle;
@@ -94,6 +94,7 @@ interface ReportRecord {
94
94
  interface Registry {
95
95
  add(entity: Entity): void;
96
96
  get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
97
+ matchPattern<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined;
97
98
  list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>;
98
99
  query(predicate: (entity: Entity) => boolean): Entity[];
99
100
  byScope(scope: Scope): Entity[];
@@ -362,6 +363,8 @@ interface DetailSurface {
362
363
  entityKind: EntityKind;
363
364
  /** Registry lookup failed — renders the "not found" placeholder. */
364
365
  notFound?: EntityRef;
366
+ /** Entity exists in the DOM but not in the registry (gen file). */
367
+ unregistered?: boolean;
365
368
  /** Entity display name, rendered as the heading. */
366
369
  title?: string;
367
370
  subtitle?: DetailSubtitle;
@@ -74,6 +74,7 @@ function freezeEntity(entity, flows) {
74
74
  function createRegistry() {
75
75
  const store = emptyStore();
76
76
  let flowsCache = null;
77
+ const patternCache = /* @__PURE__ */ new Map();
77
78
  const getFlows = () => {
78
79
  if (flowsCache === null) flowsCache = Array.from(store.flow.values());
79
80
  return flowsCache;
@@ -83,6 +84,7 @@ function createRegistry() {
83
84
  const key = entityKey(entity);
84
85
  store[entity.kind].set(key, entity);
85
86
  flowsCache = null;
87
+ patternCache.delete(entity.kind);
86
88
  };
87
89
  const get = (kind, id) => {
88
90
  assertEntityKind(kind);
@@ -90,6 +92,38 @@ function createRegistry() {
90
92
  if (raw === void 0) return void 0;
91
93
  return freezeEntity(raw, getFlows());
92
94
  };
95
+ const getPatternsForKind = (kind) => {
96
+ const cached = patternCache.get(kind);
97
+ if (cached !== void 0)
98
+ return cached;
99
+ const patterns = [];
100
+ for (const [key, entity] of store[kind]) {
101
+ if (key.endsWith("*")) {
102
+ patterns.push({
103
+ prefix: key.slice(0, -1),
104
+ entity
105
+ });
106
+ }
107
+ }
108
+ patternCache.set(
109
+ kind,
110
+ patterns
111
+ );
112
+ return patterns;
113
+ };
114
+ const matchPattern = (kind, id) => {
115
+ assertEntityKind(kind);
116
+ const patterns = getPatternsForKind(kind);
117
+ if (patterns.length === 0) return void 0;
118
+ let best;
119
+ for (const entry of patterns) {
120
+ if (id.startsWith(entry.prefix) && (best === void 0 || entry.prefix.length > best.prefix.length)) {
121
+ best = entry;
122
+ }
123
+ }
124
+ if (best === void 0) return void 0;
125
+ return freezeEntity(best.entity, getFlows());
126
+ };
93
127
  const list = (kind) => {
94
128
  assertEntityKind(kind);
95
129
  const flows = getFlows();
@@ -140,6 +174,7 @@ function createRegistry() {
140
174
  return {
141
175
  add,
142
176
  get,
177
+ matchPattern,
143
178
  list,
144
179
  query,
145
180
  byScope,
@@ -1098,6 +1133,9 @@ var tailwind_built_default = `/*! tailwindcss v4.2.2 | MIT License | https://tai
1098
1133
  .relative {
1099
1134
  position: relative;
1100
1135
  }
1136
+ .static {
1137
+ position: static;
1138
+ }
1101
1139
  .inset-0 {
1102
1140
  inset: calc(var(--spacing) * 0);
1103
1141
  }
@@ -3488,16 +3526,18 @@ function createCursorTooltip(deps) {
3488
3526
  const renderBody = () => {
3489
3527
  body.replaceChildren();
3490
3528
  if (typeof currentContent === "string") {
3491
- applyColor(DEFAULT_TOOLTIP_COLOR);
3529
+ applyColor("#a1a1aa");
3530
+ el2.style.opacity = "0.6";
3492
3531
  body.append(document.createTextNode(currentContent));
3493
3532
  return;
3494
3533
  }
3495
3534
  if (!currentContent) return;
3535
+ el2.style.opacity = "1";
3496
3536
  const { entity, node } = currentContent;
3497
3537
  const style = KIND_STYLE[entity.kind];
3498
3538
  const demoted = entity.kind === "primitive";
3499
3539
  applyColor(style?.color ?? DEFAULT_TOOLTIP_COLOR);
3500
- el2.style.opacity = demoted ? "0.55" : "1";
3540
+ if (demoted) el2.style.opacity = "0.55";
3501
3541
  if (style) {
3502
3542
  const svg2 = createLucideElement(style.icon);
3503
3543
  svg2.setAttribute("aria-hidden", "true");
@@ -3548,7 +3588,7 @@ function createCursorTooltip(deps) {
3548
3588
  // src/browser/surface/inspector.ts
3549
3589
  function entityForRef(ref2, registry) {
3550
3590
  if (registry) {
3551
- const found = registry.get(ref2.kind, ref2.id);
3591
+ const found = registry.get(ref2.kind, ref2.id) ?? registry.matchPattern?.(ref2.kind, ref2.id);
3552
3592
  if (found) return found;
3553
3593
  }
3554
3594
  if (ref2.kind === "route") return { kind: "route", path: ref2.id, page: ref2.id };
@@ -3614,7 +3654,8 @@ function createInspector(options) {
3614
3654
  resolveAll = (target) => defaultResolveAllMatches(target, registry),
3615
3655
  onHover,
3616
3656
  onSelect,
3617
- onCycle
3657
+ onCycle,
3658
+ onObscured
3618
3659
  } = options;
3619
3660
  let mounted = false;
3620
3661
  let currentEl = null;
@@ -3623,6 +3664,13 @@ function createInspector(options) {
3623
3664
  let layerIndex = 0;
3624
3665
  let lastCursor = { x: 0, y: 0 };
3625
3666
  const makeStack = () => stack.length > 0 ? { matches: stack, index: layerIndex, current: stack[layerIndex] } : null;
3667
+ const onDocumentLeave = () => {
3668
+ currentEl = null;
3669
+ stack = [];
3670
+ layerIndex = 0;
3671
+ session.highlight.unhover();
3672
+ onObscured?.(lastCursor);
3673
+ };
3626
3674
  const onMouseMove = (e) => {
3627
3675
  if (!(e.target instanceof Element)) return;
3628
3676
  const matches = resolveAll(e.target);
@@ -3675,6 +3723,7 @@ function createInspector(options) {
3675
3723
  document.head.appendChild(cursorStyleEl);
3676
3724
  }
3677
3725
  document.addEventListener("mousemove", onMouseMove);
3726
+ document.addEventListener("mouseleave", onDocumentLeave);
3678
3727
  document.addEventListener("click", onClick, true);
3679
3728
  document.addEventListener("contextmenu", onContextMenu, true);
3680
3729
  },
@@ -3689,6 +3738,7 @@ function createInspector(options) {
3689
3738
  cursorStyleEl = null;
3690
3739
  }
3691
3740
  document.removeEventListener("mousemove", onMouseMove);
3741
+ document.removeEventListener("mouseleave", onDocumentLeave);
3692
3742
  document.removeEventListener("click", onClick, true);
3693
3743
  document.removeEventListener("contextmenu", onContextMenu, true);
3694
3744
  session.highlight.unhover();
@@ -4596,6 +4646,10 @@ function createSurfaceShell(options) {
4596
4646
  },
4597
4647
  onCycle: (stack, cursor) => {
4598
4648
  showStack(stack, cursor);
4649
+ },
4650
+ onObscured: (cursor) => {
4651
+ overlay.hide();
4652
+ tooltip.update("iframe", cursor);
4599
4653
  }
4600
4654
  });
4601
4655
  cleanup.add(inspector);
@@ -5505,6 +5559,14 @@ var badgeVariants = cva(badgeBase, {
5505
5559
  }
5506
5560
  }
5507
5561
  });
5562
+ function badgeTpl(content, options = {}) {
5563
+ const { variant, size, class: extra } = options;
5564
+ return html`
5565
+ <span class=${cn(badgeVariants({ variant, size }), extra)} data-slot="badge"
5566
+ >${content}</span
5567
+ >
5568
+ `;
5569
+ }
5508
5570
 
5509
5571
  // src/browser/views/primitives/chip.ts
5510
5572
  var CHIP_CLASS = "inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground";
@@ -6861,7 +6923,10 @@ function renderDetailSurface(surface, ctx, root) {
6861
6923
  >
6862
6924
  ${surface.title}
6863
6925
  </h2>` : nothing}
6864
- <span class="ml-auto">${kindBadgeTpl(surface.entityKind)}</span>
6926
+ <span class="ml-auto flex items-center gap-1">
6927
+ ${surface.unregistered ? badgeTpl("Unregistered", { variant: "warning", size: "sm" }) : nothing}
6928
+ ${kindBadgeTpl(surface.entityKind)}
6929
+ </span>
6865
6930
  </div>
6866
6931
  ${surface.subtitle ? subtitleTpl(surface.subtitle) : nothing}
6867
6932
  <div
@@ -9747,12 +9812,11 @@ function createEntityDetailView(config) {
9747
9812
  if (!ctx.ref || ctx.ref.kind !== kind) {
9748
9813
  return { kind: "detail", entityKind: kind };
9749
9814
  }
9750
- const entity = ctx.registry.get(kind, ctx.ref.id);
9751
- if (!entity) {
9752
- return { kind: "detail", entityKind: kind, notFound: ctx.ref };
9753
- }
9754
- const metaEntity = entity;
9755
- const meta = metaEntity.meta;
9815
+ const exactEntity = ctx.registry.get(kind, ctx.ref.id);
9816
+ const patternEntity = exactEntity ? void 0 : ctx.registry.matchPattern?.(kind, ctx.ref.id);
9817
+ const entity = exactEntity ?? patternEntity;
9818
+ const metaEntity = entity ? entity : null;
9819
+ const meta = metaEntity?.meta;
9756
9820
  const actions = [];
9757
9821
  const cloud = ctx.cloud;
9758
9822
  actions.push({ ...reportAction(ctx.ref), group: "Report" });
@@ -9770,14 +9834,16 @@ function createEntityDetailView(config) {
9770
9834
  actions.push({ ...highlightElementAction(ctx.ref), group: "Inspect" });
9771
9835
  actions.push({ ...copyScreenshotAction(ctx.ref), group: "Inspect" });
9772
9836
  }
9773
- actions.push({
9774
- ...copyPathAction(ctx.ref, metaEntity.loc),
9775
- group: "Inspect"
9776
- });
9777
- actions.push({
9778
- ...copySnapshotAction(ctx.ref, metaEntity.loc),
9779
- group: "Inspect"
9780
- });
9837
+ if (metaEntity?.loc) {
9838
+ actions.push({
9839
+ ...copyPathAction(ctx.ref, metaEntity.loc),
9840
+ group: "Inspect"
9841
+ });
9842
+ actions.push({
9843
+ ...copySnapshotAction(ctx.ref, metaEntity.loc),
9844
+ group: "Inspect"
9845
+ });
9846
+ }
9781
9847
  const sections = [];
9782
9848
  if (meta?.description) {
9783
9849
  sections.push({ id: "description", text: meta.description });
@@ -9785,8 +9851,10 @@ function createEntityDetailView(config) {
9785
9851
  if (offerAcceptance && meta?.acceptance?.length) {
9786
9852
  sections.push({ id: "acceptance", items: meta.acceptance });
9787
9853
  }
9788
- for (const s of config.extraSections?.(ctx, entity) ?? []) {
9789
- sections.push(s);
9854
+ if (entity) {
9855
+ for (const s of config.extraSections?.(ctx, entity) ?? []) {
9856
+ sections.push(s);
9857
+ }
9790
9858
  }
9791
9859
  if (!DOM_BACKED_KINDS2.has(kind)) {
9792
9860
  sections.push({
@@ -9815,8 +9883,9 @@ function createEntityDetailView(config) {
9815
9883
  return {
9816
9884
  kind: "detail",
9817
9885
  entityKind: kind,
9818
- title: displayName(metaEntity),
9819
- subtitle: config.subtitle?.(ctx, entity),
9886
+ title: patternEntity ? ctx.ref.id : metaEntity ? displayName(metaEntity) : ctx.ref.id,
9887
+ subtitle: exactEntity ? config.subtitle?.(ctx, exactEntity) : void 0,
9888
+ unregistered: !entity,
9820
9889
  actions,
9821
9890
  sections
9822
9891
  };