@archie/devtools 0.1.10 → 0.1.12

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.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  import {
2
+ VID_ATTR,
2
3
  __dirname,
3
4
  babelPluginEditorMeta
4
- } from "./chunk-ZG6HZFTJ.mjs";
5
+ } from "./chunk-ZTJ6RQQF.mjs";
5
6
 
6
7
  // src/index.ts
7
8
  import { readFileSync } from "fs";
@@ -175,7 +176,6 @@ function babelPluginDndAuto({ types: t }, opts = {}) {
175
176
  }
176
177
 
177
178
  // src/babel-plugin-strip-data-vid.ts
178
- import { VID_ATTR } from "@8base-archie/editor-protocol";
179
179
  function isStaticDataVidAttribute(t, attr) {
180
180
  if (!t.isJSXAttribute(attr)) return false;
181
181
  if (!t.isJSXIdentifier(attr.name, { name: VID_ATTR })) return false;
@@ -2139,6 +2139,10 @@
2139
2139
  vidIdentity: true,
2140
2140
  nodeMeta: true,
2141
2141
  refusals: true,
2142
+ // Host -> runtime `SELECT {vid}` (alias `SELECT_ELEMENT_BY_VID`)
2143
+ // re-selects a node by its stamped `data-vid`, e.g. after the
2144
+ // iframe reloaded and lost the selection.
2145
+ selectByVid: true,
2142
2146
  },
2143
2147
  }
2144
2148
  }
@@ -2198,9 +2202,27 @@
2198
2202
  }
2199
2203
  if (meta && meta.componentName) nodeMeta.component = meta.componentName
2200
2204
  if (meta && meta.lockReason) nodeMeta.lockReason = meta.lockReason
2205
+ if (nodeMeta.isKitOrigin) {
2206
+ var usage = resolveScreenUsageMeta(el)
2207
+ if (usage && usage.vid !== vid) {
2208
+ nodeMeta.usageVid = usage.vid
2209
+ if (usage.file) nodeMeta.usageFile = usage.file
2210
+ }
2211
+ }
2201
2212
  return nodeMeta
2202
2213
  }
2203
2214
 
2215
+ // The nearest non-template meta above `el` (the screen-file usage of
2216
+ // the kit instance owning it) when it carries a valid vid, else null.
2217
+ function resolveScreenUsageMeta(el) {
2218
+ var owner = getUsageMetaOwnerFiberFromElement(el)
2219
+ var usage = owner && resolveEditorMetaValue(owner.memoizedProps.__editorMeta)
2220
+ if (usage && typeof usage.vid === "string" && VID_PATTERN.test(usage.vid)) {
2221
+ return usage
2222
+ }
2223
+ return null
2224
+ }
2225
+
2204
2226
  /**
2205
2227
  * Emit `REFUSED` (vid-identity migration) instead of letting a
2206
2228
  * drag/drop the runtime's own policy would reject proceed silently —
@@ -2283,6 +2305,53 @@
2283
2305
  var inspectorCleanupMap = new WeakMap()
2284
2306
  var BADGE_UPDATE_DELAY_MS = 50
2285
2307
 
2308
+ // Host-driven selection by `data-vid`: same end state as a single
2309
+ // user click (styles, `selectedElements`, design-mode sync, an
2310
+ // `ELEMENT_SELECTED` carrying `extractMetadata`). Silent when the vid
2311
+ // is malformed or nothing renders it.
2312
+ function selectElementByVid(vid) {
2313
+ if (typeof vid !== "string" || !VID_PATTERN.test(vid)) return
2314
+ var target = safeQuerySelector('[data-vid="' + vid + '"]')
2315
+ if (!target || !isValidContentElement(target)) {
2316
+ inspectorLog("[Inspector] SELECT: no element for vid", vid)
2317
+ return
2318
+ }
2319
+
2320
+ removeHighlight()
2321
+ var previousSelection = selectedElements.slice()
2322
+ previousSelection.forEach(function (el) {
2323
+ removeInspectorStyles(el)
2324
+ cleanupElementListeners(el)
2325
+ })
2326
+ selectedElements = [target]
2327
+ selectedElement = target
2328
+ window._inspectorSelectedElement = target
2329
+ if (window.__ARCHIE_INSPECTOR__)
2330
+ window.__ARCHIE_INSPECTOR__.selectedElement = target
2331
+ isElementSelected = true
2332
+
2333
+ applyInspectorStyles(target)
2334
+ createSelectedBadge(target)
2335
+ updateSharedHighlights()
2336
+ setupBadgePositionListeners(target)
2337
+
2338
+ var rect = target.getBoundingClientRect()
2339
+ var offscreen =
2340
+ rect.bottom < 0 ||
2341
+ rect.right < 0 ||
2342
+ rect.top > window.innerHeight ||
2343
+ rect.left > window.innerWidth
2344
+ if (offscreen && typeof target.scrollIntoView === "function") {
2345
+ target.scrollIntoView({ block: "center", inline: "nearest" })
2346
+ }
2347
+
2348
+ postMessageToParent({
2349
+ type: "ELEMENT_SELECTED",
2350
+ metadata: extractMetadata(target),
2351
+ })
2352
+ publishSelectionToDesignMode()
2353
+ }
2354
+
2286
2355
  /**
2287
2356
  * Bridge to design-mode store: publish current inspector selection as
2288
2357
  * DND nodeIds so arrange overlay knows when to show resize handles +
@@ -5059,6 +5128,12 @@
5059
5128
  metadata: metadata,
5060
5129
  })
5061
5130
  }
5131
+ } else if (
5132
+ event.data &&
5133
+ (event.data.type === "SELECT" ||
5134
+ event.data.type === "SELECT_ELEMENT_BY_VID")
5135
+ ) {
5136
+ selectElementByVid(event.data.vid)
5062
5137
  } else if (event.data && event.data.type === "HIDE_SELECTED_ELEMENT") {
5063
5138
  if (selectedElement) {
5064
5139
  deleteElementCleanup(selectedElement)
@@ -2139,6 +2139,10 @@
2139
2139
  vidIdentity: true,
2140
2140
  nodeMeta: true,
2141
2141
  refusals: true,
2142
+ // Host -> runtime `SELECT {vid}` (alias `SELECT_ELEMENT_BY_VID`)
2143
+ // re-selects a node by its stamped `data-vid`, e.g. after the
2144
+ // iframe reloaded and lost the selection.
2145
+ selectByVid: true,
2142
2146
  },
2143
2147
  }
2144
2148
  }
@@ -2198,9 +2202,27 @@
2198
2202
  }
2199
2203
  if (meta && meta.componentName) nodeMeta.component = meta.componentName
2200
2204
  if (meta && meta.lockReason) nodeMeta.lockReason = meta.lockReason
2205
+ if (nodeMeta.isKitOrigin) {
2206
+ var usage = resolveScreenUsageMeta(el)
2207
+ if (usage && usage.vid !== vid) {
2208
+ nodeMeta.usageVid = usage.vid
2209
+ if (usage.file) nodeMeta.usageFile = usage.file
2210
+ }
2211
+ }
2201
2212
  return nodeMeta
2202
2213
  }
2203
2214
 
2215
+ // The nearest non-template meta above `el` (the screen-file usage of
2216
+ // the kit instance owning it) when it carries a valid vid, else null.
2217
+ function resolveScreenUsageMeta(el) {
2218
+ var owner = getUsageMetaOwnerFiberFromElement(el)
2219
+ var usage = owner && resolveEditorMetaValue(owner.memoizedProps.__editorMeta)
2220
+ if (usage && typeof usage.vid === "string" && VID_PATTERN.test(usage.vid)) {
2221
+ return usage
2222
+ }
2223
+ return null
2224
+ }
2225
+
2204
2226
  /**
2205
2227
  * Emit `REFUSED` (vid-identity migration) instead of letting a
2206
2228
  * drag/drop the runtime's own policy would reject proceed silently —
@@ -2283,6 +2305,53 @@
2283
2305
  var inspectorCleanupMap = new WeakMap()
2284
2306
  var BADGE_UPDATE_DELAY_MS = 50
2285
2307
 
2308
+ // Host-driven selection by `data-vid`: same end state as a single
2309
+ // user click (styles, `selectedElements`, design-mode sync, an
2310
+ // `ELEMENT_SELECTED` carrying `extractMetadata`). Silent when the vid
2311
+ // is malformed or nothing renders it.
2312
+ function selectElementByVid(vid) {
2313
+ if (typeof vid !== "string" || !VID_PATTERN.test(vid)) return
2314
+ var target = safeQuerySelector('[data-vid="' + vid + '"]')
2315
+ if (!target || !isValidContentElement(target)) {
2316
+ inspectorLog("[Inspector] SELECT: no element for vid", vid)
2317
+ return
2318
+ }
2319
+
2320
+ removeHighlight()
2321
+ var previousSelection = selectedElements.slice()
2322
+ previousSelection.forEach(function (el) {
2323
+ removeInspectorStyles(el)
2324
+ cleanupElementListeners(el)
2325
+ })
2326
+ selectedElements = [target]
2327
+ selectedElement = target
2328
+ window._inspectorSelectedElement = target
2329
+ if (window.__ARCHIE_INSPECTOR__)
2330
+ window.__ARCHIE_INSPECTOR__.selectedElement = target
2331
+ isElementSelected = true
2332
+
2333
+ applyInspectorStyles(target)
2334
+ createSelectedBadge(target)
2335
+ updateSharedHighlights()
2336
+ setupBadgePositionListeners(target)
2337
+
2338
+ var rect = target.getBoundingClientRect()
2339
+ var offscreen =
2340
+ rect.bottom < 0 ||
2341
+ rect.right < 0 ||
2342
+ rect.top > window.innerHeight ||
2343
+ rect.left > window.innerWidth
2344
+ if (offscreen && typeof target.scrollIntoView === "function") {
2345
+ target.scrollIntoView({ block: "center", inline: "nearest" })
2346
+ }
2347
+
2348
+ postMessageToParent({
2349
+ type: "ELEMENT_SELECTED",
2350
+ metadata: extractMetadata(target),
2351
+ })
2352
+ publishSelectionToDesignMode()
2353
+ }
2354
+
2286
2355
  /**
2287
2356
  * Bridge to design-mode store: publish current inspector selection as
2288
2357
  * DND nodeIds so arrange overlay knows when to show resize handles +
@@ -5059,6 +5128,12 @@
5059
5128
  metadata: metadata,
5060
5129
  })
5061
5130
  }
5131
+ } else if (
5132
+ event.data &&
5133
+ (event.data.type === "SELECT" ||
5134
+ event.data.type === "SELECT_ELEMENT_BY_VID")
5135
+ ) {
5136
+ selectElementByVid(event.data.vid)
5062
5137
  } else if (event.data && event.data.type === "HIDE_SELECTED_ELEMENT") {
5063
5138
  if (selectedElement) {
5064
5139
  deleteElementCleanup(selectedElement)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archie/devtools",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "DevTools for Archie generated applications - Route synchronization and editor communication",
5
5
  "sideEffects": false,
6
6
  "repository": {
@@ -38,6 +38,7 @@
38
38
  "build": "tsup",
39
39
  "build:local": "ARCHIE_INSPECTOR_INCLUDE_STANDALONE=1 tsup",
40
40
  "typecheck": "tsc --noEmit",
41
+ "check:private-deps": "node scripts/check-no-private-deps.mjs",
41
42
  "release": "node publish.js"
42
43
  },
43
44
  "files": [
@@ -54,6 +55,7 @@
54
55
  "author": "8base",
55
56
  "license": "UNLICENSED",
56
57
  "devDependencies": {
58
+ "@8base-archie/editor-protocol": "1.0.0-rc.12",
57
59
  "@dnd-kit/core": "6.3.1",
58
60
  "@dnd-kit/sortable": "10.0.0",
59
61
  "@dnd-kit/utilities": "3.2.2",
@@ -77,7 +79,6 @@
77
79
  "react-dom": ">=18.0.0"
78
80
  },
79
81
  "dependencies": {
80
- "@8base-archie/editor-protocol": "1.0.0-rc.1",
81
82
  "@babel/core": "7.29.0",
82
83
  "@babel/types": "7.29.0",
83
84
  "zod": "^4.6.5"