@archie/devtools 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -89,6 +89,11 @@ opción `allowLegacyIds` es `true` (default en esta versión — transicional,
89
89
  se eliminará más adelante); con `allowLegacyIds: false` el elemento no se
90
90
  instrumenta.
91
91
 
92
+ El plugin nunca estampa `data-vid` en runtime (eso lo hace el stamper de
93
+ Genesis). El plugin Vite (`archieDevTools()`) solo VALIDA: en dev, un
94
+ `JSXOpeningElement` sin `data-vid` dispara un warning una vez por archivo
95
+ (`onMissingVid` en `babel-plugin-editor-meta.ts`).
96
+
92
97
  En runtime, `node-key.ts` resuelve la identidad con la prioridad
93
98
  `meta.vid` → `data-vid` del DOM → (legado) `meta.nodeId` → `runtime:N`, y
94
99
  `fiber-bridge.ts` expone `getNodeMeta(el)`, que valida el `NodeMeta`
@@ -63,8 +63,10 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
63
63
  includeHostSourceRef = false,
64
64
  origin = "screen",
65
65
  templateOrigin = false,
66
- allowLegacyIds = true
66
+ allowLegacyIds = true,
67
+ onMissingVid
67
68
  } = opts;
69
+ let missingVidWarned = false;
68
70
  function getJSXTagName(el) {
69
71
  const { name } = el;
70
72
  if (t.isJSXIdentifier(name)) return name.name;
@@ -883,6 +885,10 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
883
885
  }
884
886
  }
885
887
  const vid = readVidAttr(path2.node.attributes);
888
+ if (!vid && onMissingVid && !missingVidWarned) {
889
+ missingVidWarned = true;
890
+ onMissingVid({ file, line, col, componentName, instrumented: allowLegacyIds });
891
+ }
886
892
  if (!vid && !allowLegacyIds) return;
887
893
  const nodeId = vid ?? computeNodeId(file, line, col, componentName);
888
894
  const isKitOrigin = origin === "kit" || hasSlotAttr;
@@ -4598,6 +4598,15 @@ function resolveVidFromElement(el) {
4598
4598
  const key2 = getNodeKeyFromElement(el);
4599
4599
  return VID_PATTERN.test(key2) ? key2 : null;
4600
4600
  }
4601
+ function resolveVidForScannedNode(nodeId, nodeMap, fallbackEl) {
4602
+ const scannedVid = nodeId ? nodeMap.get(nodeId)?.editorMeta?.vid : void 0;
4603
+ if (scannedVid && VID_PATTERN.test(scannedVid)) return scannedVid;
4604
+ return fallbackEl ? resolveVidFromElement(fallbackEl) : null;
4605
+ }
4606
+ function resolveVidForScannedNodeStrict(nodeId, nodeMap) {
4607
+ const scannedVid = nodeId ? nodeMap.get(nodeId)?.editorMeta?.vid : void 0;
4608
+ return scannedVid && VID_PATTERN.test(scannedVid) ? scannedVid : null;
4609
+ }
4601
4610
  function getInspectorRefFromElement(el) {
4602
4611
  const resolved = resolveDragSurface(el);
4603
4612
  const host = resolved.host ?? el;
@@ -8294,12 +8303,12 @@ function useDragVisualLoop({
8294
8303
 
8295
8304
  // src/client/dnd/design-mode/useDragLifecycle.ts
8296
8305
  var import_react13 = require("react");
8297
- function emitRefused(code, cause, element) {
8306
+ function emitRefused(code, cause, vid) {
8298
8307
  dispatchRuntimeEvent({
8299
8308
  type: "drag-refused",
8300
8309
  code,
8301
8310
  cause,
8302
- vid: element ? resolveVidFromElement(element) : null
8311
+ vid
8303
8312
  });
8304
8313
  }
8305
8314
  function resolveLaneAllowedContainers(anchorElement, srcContainerId) {
@@ -8373,7 +8382,8 @@ function recordCommittedMove(args) {
8373
8382
  sourceLaneSnapshot,
8374
8383
  targetLaneSnapshot,
8375
8384
  resolveNodeElement,
8376
- recordMoveChange
8385
+ recordMoveChange,
8386
+ nodeMap
8377
8387
  } = args;
8378
8388
  const sourceLaneIdentitySnapshot = captureCommitLaneIdentitySnapshot(
8379
8389
  sourceLaneSnapshot,
@@ -8418,10 +8428,10 @@ function recordCommittedMove(args) {
8418
8428
  });
8419
8429
  const componentName = getEditorMeta(anchorEl)?.componentName;
8420
8430
  const operationId = `${command.at}:${anchorNodeId}`;
8421
- const targetVid = resolveVidFromElement(selectedEl);
8422
8431
  const targetContainerId = command.to.parentNodeId ?? command.to.laneContainerId;
8423
8432
  const targetContainerEl = targetContainerId ? resolveNodeElement(targetContainerId) : null;
8424
- const containerVid = targetContainerEl ? resolveVidFromElement(targetContainerEl) : null;
8433
+ const targetVid = resolveVidForScannedNode(selectedNodeId, nodeMap, selectedEl);
8434
+ const containerVid = resolveVidForScannedNode(targetContainerId, nodeMap, targetContainerEl);
8425
8435
  const binding = resolveRowBinding(selectedEl);
8426
8436
  const beforePayload = buildMovePayloadWithEffectiveIdentities({
8427
8437
  placement: command.from,
@@ -8568,7 +8578,7 @@ function useDragLifecycle({
8568
8578
  emitRefused(
8569
8579
  resolveRefusalCode(found.editorMeta, "GATE_REJECT"),
8570
8580
  "Node is not draggable (dynamic render, chrome, or kit-origin).",
8571
- found.element
8581
+ resolveVidForScannedNode(activeId, refs.nodeMapRef.current, found.element)
8572
8582
  );
8573
8583
  return;
8574
8584
  }
@@ -8597,7 +8607,11 @@ function useDragLifecycle({
8597
8607
  emitRefused(
8598
8608
  resolveRefusalCode(anchorScanned?.editorMeta, "GATE_REJECT"),
8599
8609
  "Resolved drag anchor is not draggable.",
8600
- anchorScanned?.element ?? found.element
8610
+ resolveVidForScannedNode(
8611
+ anchor.anchorNodeId,
8612
+ refs.nodeMapRef.current,
8613
+ anchorScanned?.element ?? found.element
8614
+ )
8601
8615
  );
8602
8616
  return;
8603
8617
  }
@@ -8613,7 +8627,7 @@ function useDragLifecycle({
8613
8627
  refs.droppableContainerIdsRef.current = droppableSet;
8614
8628
  dispatchRuntimeEvent({
8615
8629
  type: "drag-started",
8616
- targetVid: resolveVidFromElement(anchorScanned.element),
8630
+ targetVid: resolveVidForScannedNode(anchorNodeId, refs.nodeMapRef.current, anchorScanned.element),
8617
8631
  droppable: Array.from(droppableSet)
8618
8632
  });
8619
8633
  const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
@@ -8694,7 +8708,7 @@ function useDragLifecycle({
8694
8708
  emitRefused(
8695
8709
  resolveRefusalCode(targetMeta, "CONTAINER_NOT_PLAIN"),
8696
8710
  "Drop target is outside the droppable set for this node.",
8697
- targetContainerEl
8711
+ resolveVidForScannedNode(dropTargetId, refs.nodeMapRef.current, targetContainerEl)
8698
8712
  );
8699
8713
  clearDragState();
8700
8714
  syncHistoryAvailability();
@@ -8760,7 +8774,8 @@ function useDragLifecycle({
8760
8774
  sourceLaneSnapshot,
8761
8775
  targetLaneSnapshot,
8762
8776
  resolveNodeElement,
8763
- recordMoveChange
8777
+ recordMoveChange,
8778
+ nodeMap: refs.nodeMapRef.current
8764
8779
  });
8765
8780
  }
8766
8781
  }
@@ -8911,7 +8926,7 @@ function useResizeSession({
8911
8926
  return;
8912
8927
  }
8913
8928
  const inspectorRef = getInspectorRefFromElement(element);
8914
- const targetVid = resolveVidFromElement(element);
8929
+ const targetVid = resolveVidForScannedNode(targetNodeId, refs.nodeMapRef.current, element);
8915
8930
  const resizeCmd = {
8916
8931
  type: "resize",
8917
8932
  mode,
@@ -9161,7 +9176,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
9161
9176
  };
9162
9177
  }
9163
9178
  const operationId = `${insertCommand.at}:${nodeId}`;
9164
- const containerVid = containerEl ? resolveVidFromElement(containerEl) : null;
9179
+ const containerVid = resolveVidForScannedNodeStrict(intent.containerId, refs.nodeMapRef.current);
9165
9180
  const insertedVid = resolveVidFromElement(newElement);
9166
9181
  useDesignModeStore.getState().recordInsertChange({
9167
9182
  operationId,
@@ -10003,8 +10018,14 @@ function isPreviewOrigin(origin) {
10003
10018
 
10004
10019
  // src/client/inject-inspector/injectInspector.ts
10005
10020
  var DEFAULT_SCRIPT_ID = "archie-inspector-script";
10006
- var REMOTE_INSPECTOR_SCRIPT_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev/inspector.standalone.js";
10007
- function getInspectorScriptUrl(base, cacheBust = true) {
10021
+ var R2_INSPECTOR_BASE_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev";
10022
+ function readBuildVersion() {
10023
+ return "0.1.3" ? "0.1.3" : null;
10024
+ }
10025
+ var REMOTE_INSPECTOR_VERSION = readBuildVersion();
10026
+ var isRemoteInspectorUrlVersioned = REMOTE_INSPECTOR_VERSION !== null;
10027
+ var REMOTE_INSPECTOR_SCRIPT_URL = REMOTE_INSPECTOR_VERSION ? `${R2_INSPECTOR_BASE_URL}/inspector.standalone@${REMOTE_INSPECTOR_VERSION}.js` : `${R2_INSPECTOR_BASE_URL}/inspector.standalone.js`;
10028
+ function getInspectorScriptUrl(base, cacheBust) {
10008
10029
  const separator = base.includes("?") ? "&" : "?";
10009
10030
  return cacheBust ? `${base}${separator}h=${Date.now()}` : base;
10010
10031
  }
@@ -10060,7 +10081,8 @@ function injectInspector(opts = {}) {
10060
10081
  }
10061
10082
  }
10062
10083
  const useLocal = opts.scriptSource === "local";
10063
- const scriptUrl = useLocal ? opts.localScriptUrl ?? "/_archie/inspector.js" : getInspectorScriptUrl(opts.scriptUrl ?? REMOTE_INSPECTOR_SCRIPT_URL, true);
10084
+ const usingDefaultVersionedUrl = opts.scriptUrl === void 0 && isRemoteInspectorUrlVersioned;
10085
+ const scriptUrl = useLocal ? opts.localScriptUrl ?? "/_archie/inspector.js" : getInspectorScriptUrl(opts.scriptUrl ?? REMOTE_INSPECTOR_SCRIPT_URL, !usingDefaultVersionedUrl);
10064
10086
  const script = document.createElement("script");
10065
10087
  script.id = id;
10066
10088
  script.src = scriptUrl;
@@ -4563,6 +4563,15 @@ function resolveVidFromElement(el) {
4563
4563
  const key2 = getNodeKeyFromElement(el);
4564
4564
  return VID_PATTERN.test(key2) ? key2 : null;
4565
4565
  }
4566
+ function resolveVidForScannedNode(nodeId, nodeMap, fallbackEl) {
4567
+ const scannedVid = nodeId ? nodeMap.get(nodeId)?.editorMeta?.vid : void 0;
4568
+ if (scannedVid && VID_PATTERN.test(scannedVid)) return scannedVid;
4569
+ return fallbackEl ? resolveVidFromElement(fallbackEl) : null;
4570
+ }
4571
+ function resolveVidForScannedNodeStrict(nodeId, nodeMap) {
4572
+ const scannedVid = nodeId ? nodeMap.get(nodeId)?.editorMeta?.vid : void 0;
4573
+ return scannedVid && VID_PATTERN.test(scannedVid) ? scannedVid : null;
4574
+ }
4566
4575
  function getInspectorRefFromElement(el) {
4567
4576
  const resolved = resolveDragSurface(el);
4568
4577
  const host = resolved.host ?? el;
@@ -8259,12 +8268,12 @@ function useDragVisualLoop({
8259
8268
 
8260
8269
  // src/client/dnd/design-mode/useDragLifecycle.ts
8261
8270
  import { useState as useState5, useCallback as useCallback6 } from "react";
8262
- function emitRefused(code, cause, element) {
8271
+ function emitRefused(code, cause, vid) {
8263
8272
  dispatchRuntimeEvent({
8264
8273
  type: "drag-refused",
8265
8274
  code,
8266
8275
  cause,
8267
- vid: element ? resolveVidFromElement(element) : null
8276
+ vid
8268
8277
  });
8269
8278
  }
8270
8279
  function resolveLaneAllowedContainers(anchorElement, srcContainerId) {
@@ -8338,7 +8347,8 @@ function recordCommittedMove(args) {
8338
8347
  sourceLaneSnapshot,
8339
8348
  targetLaneSnapshot,
8340
8349
  resolveNodeElement,
8341
- recordMoveChange
8350
+ recordMoveChange,
8351
+ nodeMap
8342
8352
  } = args;
8343
8353
  const sourceLaneIdentitySnapshot = captureCommitLaneIdentitySnapshot(
8344
8354
  sourceLaneSnapshot,
@@ -8383,10 +8393,10 @@ function recordCommittedMove(args) {
8383
8393
  });
8384
8394
  const componentName = getEditorMeta(anchorEl)?.componentName;
8385
8395
  const operationId = `${command.at}:${anchorNodeId}`;
8386
- const targetVid = resolveVidFromElement(selectedEl);
8387
8396
  const targetContainerId = command.to.parentNodeId ?? command.to.laneContainerId;
8388
8397
  const targetContainerEl = targetContainerId ? resolveNodeElement(targetContainerId) : null;
8389
- const containerVid = targetContainerEl ? resolveVidFromElement(targetContainerEl) : null;
8398
+ const targetVid = resolveVidForScannedNode(selectedNodeId, nodeMap, selectedEl);
8399
+ const containerVid = resolveVidForScannedNode(targetContainerId, nodeMap, targetContainerEl);
8390
8400
  const binding = resolveRowBinding(selectedEl);
8391
8401
  const beforePayload = buildMovePayloadWithEffectiveIdentities({
8392
8402
  placement: command.from,
@@ -8533,7 +8543,7 @@ function useDragLifecycle({
8533
8543
  emitRefused(
8534
8544
  resolveRefusalCode(found.editorMeta, "GATE_REJECT"),
8535
8545
  "Node is not draggable (dynamic render, chrome, or kit-origin).",
8536
- found.element
8546
+ resolveVidForScannedNode(activeId, refs.nodeMapRef.current, found.element)
8537
8547
  );
8538
8548
  return;
8539
8549
  }
@@ -8562,7 +8572,11 @@ function useDragLifecycle({
8562
8572
  emitRefused(
8563
8573
  resolveRefusalCode(anchorScanned?.editorMeta, "GATE_REJECT"),
8564
8574
  "Resolved drag anchor is not draggable.",
8565
- anchorScanned?.element ?? found.element
8575
+ resolveVidForScannedNode(
8576
+ anchor.anchorNodeId,
8577
+ refs.nodeMapRef.current,
8578
+ anchorScanned?.element ?? found.element
8579
+ )
8566
8580
  );
8567
8581
  return;
8568
8582
  }
@@ -8578,7 +8592,7 @@ function useDragLifecycle({
8578
8592
  refs.droppableContainerIdsRef.current = droppableSet;
8579
8593
  dispatchRuntimeEvent({
8580
8594
  type: "drag-started",
8581
- targetVid: resolveVidFromElement(anchorScanned.element),
8595
+ targetVid: resolveVidForScannedNode(anchorNodeId, refs.nodeMapRef.current, anchorScanned.element),
8582
8596
  droppable: Array.from(droppableSet)
8583
8597
  });
8584
8598
  const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
@@ -8659,7 +8673,7 @@ function useDragLifecycle({
8659
8673
  emitRefused(
8660
8674
  resolveRefusalCode(targetMeta, "CONTAINER_NOT_PLAIN"),
8661
8675
  "Drop target is outside the droppable set for this node.",
8662
- targetContainerEl
8676
+ resolveVidForScannedNode(dropTargetId, refs.nodeMapRef.current, targetContainerEl)
8663
8677
  );
8664
8678
  clearDragState();
8665
8679
  syncHistoryAvailability();
@@ -8725,7 +8739,8 @@ function useDragLifecycle({
8725
8739
  sourceLaneSnapshot,
8726
8740
  targetLaneSnapshot,
8727
8741
  resolveNodeElement,
8728
- recordMoveChange
8742
+ recordMoveChange,
8743
+ nodeMap: refs.nodeMapRef.current
8729
8744
  });
8730
8745
  }
8731
8746
  }
@@ -8876,7 +8891,7 @@ function useResizeSession({
8876
8891
  return;
8877
8892
  }
8878
8893
  const inspectorRef = getInspectorRefFromElement(element);
8879
- const targetVid = resolveVidFromElement(element);
8894
+ const targetVid = resolveVidForScannedNode(targetNodeId, refs.nodeMapRef.current, element);
8880
8895
  const resizeCmd = {
8881
8896
  type: "resize",
8882
8897
  mode,
@@ -9126,7 +9141,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
9126
9141
  };
9127
9142
  }
9128
9143
  const operationId = `${insertCommand.at}:${nodeId}`;
9129
- const containerVid = containerEl ? resolveVidFromElement(containerEl) : null;
9144
+ const containerVid = resolveVidForScannedNodeStrict(intent.containerId, refs.nodeMapRef.current);
9130
9145
  const insertedVid = resolveVidFromElement(newElement);
9131
9146
  useDesignModeStore.getState().recordInsertChange({
9132
9147
  operationId,
@@ -9968,8 +9983,14 @@ function isPreviewOrigin(origin) {
9968
9983
 
9969
9984
  // src/client/inject-inspector/injectInspector.ts
9970
9985
  var DEFAULT_SCRIPT_ID = "archie-inspector-script";
9971
- var REMOTE_INSPECTOR_SCRIPT_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev/inspector.standalone.js";
9972
- function getInspectorScriptUrl(base, cacheBust = true) {
9986
+ var R2_INSPECTOR_BASE_URL = "https://pub-bf238c278d9644b39ec34ecaca1d315c.r2.dev";
9987
+ function readBuildVersion() {
9988
+ return "0.1.3" ? "0.1.3" : null;
9989
+ }
9990
+ var REMOTE_INSPECTOR_VERSION = readBuildVersion();
9991
+ var isRemoteInspectorUrlVersioned = REMOTE_INSPECTOR_VERSION !== null;
9992
+ var REMOTE_INSPECTOR_SCRIPT_URL = REMOTE_INSPECTOR_VERSION ? `${R2_INSPECTOR_BASE_URL}/inspector.standalone@${REMOTE_INSPECTOR_VERSION}.js` : `${R2_INSPECTOR_BASE_URL}/inspector.standalone.js`;
9993
+ function getInspectorScriptUrl(base, cacheBust) {
9973
9994
  const separator = base.includes("?") ? "&" : "?";
9974
9995
  return cacheBust ? `${base}${separator}h=${Date.now()}` : base;
9975
9996
  }
@@ -10025,7 +10046,8 @@ function injectInspector(opts = {}) {
10025
10046
  }
10026
10047
  }
10027
10048
  const useLocal = opts.scriptSource === "local";
10028
- const scriptUrl = useLocal ? opts.localScriptUrl ?? "/_archie/inspector.js" : getInspectorScriptUrl(opts.scriptUrl ?? REMOTE_INSPECTOR_SCRIPT_URL, true);
10049
+ const usingDefaultVersionedUrl = opts.scriptUrl === void 0 && isRemoteInspectorUrlVersioned;
10050
+ const scriptUrl = useLocal ? opts.localScriptUrl ?? "/_archie/inspector.js" : getInspectorScriptUrl(opts.scriptUrl ?? REMOTE_INSPECTOR_SCRIPT_URL, !usingDefaultVersionedUrl);
10029
10051
  const script = document.createElement("script");
10030
10052
  script.id = id;
10031
10053
  script.src = scriptUrl;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  meaningfulChildren
3
- } from "./chunk-WBZJILZ6.mjs";
3
+ } from "./chunk-U4KG6UDY.mjs";
4
4
 
5
5
  // src/babel-plugin-collection-binding.ts
6
6
  import { VISITOR_KEYS } from "@babel/types";
package/dist/index.d.mts CHANGED
@@ -165,6 +165,23 @@ interface EditorMetaPluginOptions {
165
165
  * @default true
166
166
  */
167
167
  allowLegacyIds?: boolean;
168
+ /**
169
+ * Called at most once per file, the first time a `JSXOpeningElement` has
170
+ * no well-formed `data-vid`. Signal only — never itself changes
171
+ * instrumentation. `instrumented` reports what THIS element gets right
172
+ * after the callback returns: `true` when it falls back to legacy
173
+ * `file:line:col:componentName` addressing (`allowLegacyIds` true, the
174
+ * default), `false` when the plugin declines to instrument it at all
175
+ * (`allowLegacyIds: false`) — the callback fires before that decision, so
176
+ * a caller cannot infer it from call order alone.
177
+ */
178
+ onMissingVid?: (info: {
179
+ file: string;
180
+ line: number;
181
+ col: number;
182
+ componentName: string;
183
+ instrumented: boolean;
184
+ }) => void;
168
185
  }
169
186
  declare function babelPluginEditorMeta({ types: t }: {
170
187
  types: typeof types;
package/dist/index.d.ts CHANGED
@@ -165,6 +165,23 @@ interface EditorMetaPluginOptions {
165
165
  * @default true
166
166
  */
167
167
  allowLegacyIds?: boolean;
168
+ /**
169
+ * Called at most once per file, the first time a `JSXOpeningElement` has
170
+ * no well-formed `data-vid`. Signal only — never itself changes
171
+ * instrumentation. `instrumented` reports what THIS element gets right
172
+ * after the callback returns: `true` when it falls back to legacy
173
+ * `file:line:col:componentName` addressing (`allowLegacyIds` true, the
174
+ * default), `false` when the plugin declines to instrument it at all
175
+ * (`allowLegacyIds: false`) — the callback fires before that decision, so
176
+ * a caller cannot infer it from call order alone.
177
+ */
178
+ onMissingVid?: (info: {
179
+ file: string;
180
+ line: number;
181
+ col: number;
182
+ componentName: string;
183
+ instrumented: boolean;
184
+ }) => void;
168
185
  }
169
186
  declare function babelPluginEditorMeta({ types: t }: {
170
187
  types: typeof types;
package/dist/index.js CHANGED
@@ -262,8 +262,10 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
262
262
  includeHostSourceRef = false,
263
263
  origin = "screen",
264
264
  templateOrigin = false,
265
- allowLegacyIds = true
265
+ allowLegacyIds = true,
266
+ onMissingVid
266
267
  } = opts;
268
+ let missingVidWarned = false;
267
269
  function getJSXTagName(el) {
268
270
  const { name } = el;
269
271
  if (t.isJSXIdentifier(name)) return name.name;
@@ -1082,6 +1084,10 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
1082
1084
  }
1083
1085
  }
1084
1086
  const vid = readVidAttr(path.node.attributes);
1087
+ if (!vid && onMissingVid && !missingVidWarned) {
1088
+ missingVidWarned = true;
1089
+ onMissingVid({ file, line, col, componentName, instrumented: allowLegacyIds });
1090
+ }
1085
1091
  if (!vid && !allowLegacyIds) return;
1086
1092
  const nodeId = vid ?? computeNodeId(file, line, col, componentName);
1087
1093
  const isKitOrigin = origin === "kit" || hasSlotAttr;
@@ -1216,7 +1222,17 @@ function archieDevTools(options = {}) {
1216
1222
  };
1217
1223
  let babelCore = null;
1218
1224
  let includeHostSourceRef = false;
1225
+ let isDevServer = false;
1219
1226
  const transformedByHook = /* @__PURE__ */ new Set();
1227
+ const warnedMissingVidFiles = /* @__PURE__ */ new Set();
1228
+ function warnMissingVid(info) {
1229
+ if (warnedMissingVidFiles.has(info.file)) return;
1230
+ warnedMissingVidFiles.add(info.file);
1231
+ const outcome = info.instrumented ? "the visual editor falls back to legacy file:line:col addressing for it, which breaks on every source edit" : "this file is not instrumented for the visual editor at all";
1232
+ console.warn(
1233
+ `[Archie DevTools] Missing data-vid on <${info.componentName}> at ${info.file}:${info.line}:${info.col}. This file was not stamped with stable element ids \u2014 ${outcome}. Re-run the Genesis stamper.`
1234
+ );
1235
+ }
1220
1236
  const plugin = {
1221
1237
  name: "vite-plugin-archie-devtools",
1222
1238
  enforce: "pre",
@@ -1232,6 +1248,7 @@ function archieDevTools(options = {}) {
1232
1248
  },
1233
1249
  configResolved(config) {
1234
1250
  includeHostSourceRef = !config.isProduction;
1251
+ isDevServer = config.command === "serve";
1235
1252
  },
1236
1253
  configureServer(server) {
1237
1254
  server.middlewares.use(LOCAL_INSPECTOR_SERVE_PATH, (_req, res) => {
@@ -1267,7 +1284,10 @@ function archieDevTools(options = {}) {
1267
1284
  const result = await babel.transformAsync(code, {
1268
1285
  filename: id,
1269
1286
  plugins: [
1270
- (b) => babelPluginEditorMeta(b, { includeHostSourceRef }),
1287
+ (b) => babelPluginEditorMeta(b, {
1288
+ includeHostSourceRef,
1289
+ onMissingVid: isDevServer ? warnMissingVid : void 0
1290
+ }),
1271
1291
  ...dndPages.test(id) ? [(b) => babelPluginDndAuto(b, { importSource: INTERNAL_DND_SCOPE_IMPORT_SOURCE })] : []
1272
1292
  ],
1273
1293
  parserOpts: {
@@ -1307,7 +1327,8 @@ function archieDevTools(options = {}) {
1307
1327
  if (!/node_modules/.test(context.id) && !transformedByHook.has(context.id)) {
1308
1328
  babelOptions.plugins.push(
1309
1329
  (babel) => babelPluginEditorMeta(babel, {
1310
- includeHostSourceRef
1330
+ includeHostSourceRef,
1331
+ onMissingVid: isDevServer ? warnMissingVid : void 0
1311
1332
  })
1312
1333
  );
1313
1334
  }
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __dirname,
3
3
  babelPluginEditorMeta
4
- } from "./chunk-WBZJILZ6.mjs";
4
+ } from "./chunk-U4KG6UDY.mjs";
5
5
 
6
6
  // src/index.ts
7
7
  import { readFileSync } from "fs";
@@ -186,7 +186,17 @@ function archieDevTools(options = {}) {
186
186
  };
187
187
  let babelCore = null;
188
188
  let includeHostSourceRef = false;
189
+ let isDevServer = false;
189
190
  const transformedByHook = /* @__PURE__ */ new Set();
191
+ const warnedMissingVidFiles = /* @__PURE__ */ new Set();
192
+ function warnMissingVid(info) {
193
+ if (warnedMissingVidFiles.has(info.file)) return;
194
+ warnedMissingVidFiles.add(info.file);
195
+ const outcome = info.instrumented ? "the visual editor falls back to legacy file:line:col addressing for it, which breaks on every source edit" : "this file is not instrumented for the visual editor at all";
196
+ console.warn(
197
+ `[Archie DevTools] Missing data-vid on <${info.componentName}> at ${info.file}:${info.line}:${info.col}. This file was not stamped with stable element ids \u2014 ${outcome}. Re-run the Genesis stamper.`
198
+ );
199
+ }
190
200
  const plugin = {
191
201
  name: "vite-plugin-archie-devtools",
192
202
  enforce: "pre",
@@ -202,6 +212,7 @@ function archieDevTools(options = {}) {
202
212
  },
203
213
  configResolved(config) {
204
214
  includeHostSourceRef = !config.isProduction;
215
+ isDevServer = config.command === "serve";
205
216
  },
206
217
  configureServer(server) {
207
218
  server.middlewares.use(LOCAL_INSPECTOR_SERVE_PATH, (_req, res) => {
@@ -237,7 +248,10 @@ function archieDevTools(options = {}) {
237
248
  const result = await babel.transformAsync(code, {
238
249
  filename: id,
239
250
  plugins: [
240
- (b) => babelPluginEditorMeta(b, { includeHostSourceRef }),
251
+ (b) => babelPluginEditorMeta(b, {
252
+ includeHostSourceRef,
253
+ onMissingVid: isDevServer ? warnMissingVid : void 0
254
+ }),
241
255
  ...dndPages.test(id) ? [(b) => babelPluginDndAuto(b, { importSource: INTERNAL_DND_SCOPE_IMPORT_SOURCE })] : []
242
256
  ],
243
257
  parserOpts: {
@@ -277,7 +291,8 @@ function archieDevTools(options = {}) {
277
291
  if (!/node_modules/.test(context.id) && !transformedByHook.has(context.id)) {
278
292
  babelOptions.plugins.push(
279
293
  (babel) => babelPluginEditorMeta(babel, {
280
- includeHostSourceRef
294
+ includeHostSourceRef,
295
+ onMissingVid: isDevServer ? warnMissingVid : void 0
281
296
  })
282
297
  );
283
298
  }