@archie/devtools 0.1.1 → 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 +5 -0
- package/dist/{chunk-THKKWDMJ.mjs → chunk-U4KG6UDY.mjs} +75 -9
- package/dist/client/client.js +53 -20
- package/dist/client/client.mjs +53 -20
- package/dist/collection-binding.mjs +1 -1
- package/dist/index.d.mts +25 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +92 -11
- package/dist/index.mjs +18 -3
- package/dist/inspector.standalone@0.1.3.js +6044 -0
- package/package.json +1 -1
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;
|
|
@@ -350,11 +352,17 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
350
352
|
}
|
|
351
353
|
return "STATIC";
|
|
352
354
|
}
|
|
353
|
-
const SHELL_FILE_RE = /(^|\/)shell\.jsx$/;
|
|
355
|
+
const SHELL_FILE_RE = /(^|\/)shell\.(jsx|tsx)$/;
|
|
354
356
|
const SHELL_DIR_RE = /(^|\/)components\/shell\//;
|
|
357
|
+
const SHELL_BASENAME_RE = /shell/i;
|
|
355
358
|
const CHROME_ANCESTOR_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "header"]);
|
|
356
|
-
function
|
|
359
|
+
function isChromeFilePath(file) {
|
|
357
360
|
if (SHELL_FILE_RE.test(file) || SHELL_DIR_RE.test(file)) return true;
|
|
361
|
+
const base = file.split("/").pop() ?? file;
|
|
362
|
+
return SHELL_BASENAME_RE.test(base);
|
|
363
|
+
}
|
|
364
|
+
function computeIsChrome(file, path) {
|
|
365
|
+
if (isChromeFilePath(file)) return true;
|
|
358
366
|
let current = path.parentPath;
|
|
359
367
|
while (current) {
|
|
360
368
|
if (current.isJSXElement()) {
|
|
@@ -368,17 +376,65 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
368
376
|
function computeContainerKind(path) {
|
|
369
377
|
const elPath = path.parentPath;
|
|
370
378
|
if (!elPath?.isJSXElement()) return "none";
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const allPlain = children.every((c) =>
|
|
379
|
+
if (!elPath.node.closingElement) return "none";
|
|
380
|
+
const children = elPath.node.children;
|
|
381
|
+
const allPlain = children.every((c) => {
|
|
382
|
+
if (t.isJSXElement(c)) return true;
|
|
383
|
+
if (t.isJSXText(c)) return c.value.trim() === "";
|
|
384
|
+
return false;
|
|
385
|
+
});
|
|
374
386
|
return allPlain ? "plain" : "expression";
|
|
375
387
|
}
|
|
376
|
-
|
|
388
|
+
const kitBoundNamesCache = /* @__PURE__ */ new WeakMap();
|
|
389
|
+
function computeKitBoundNames(programPath) {
|
|
390
|
+
const cached = kitBoundNamesCache.get(programPath.node);
|
|
391
|
+
if (cached) return cached;
|
|
392
|
+
const names = /* @__PURE__ */ new Set();
|
|
393
|
+
for (const stmt of programPath.node.body) {
|
|
394
|
+
if (!t.isVariableDeclaration(stmt)) continue;
|
|
395
|
+
for (const decl of stmt.declarations) {
|
|
396
|
+
if (!t.isObjectPattern(decl.id)) continue;
|
|
397
|
+
if (!decl.init || !t.isIdentifier(decl.init) || decl.init.name !== "Kit") continue;
|
|
398
|
+
for (const prop of decl.id.properties) {
|
|
399
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
400
|
+
const value = t.isIdentifier(prop.value) ? prop.value : t.isIdentifier(prop.key) ? prop.key : null;
|
|
401
|
+
if (value) names.add(value.name);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
kitBoundNamesCache.set(programPath.node, names);
|
|
406
|
+
return names;
|
|
407
|
+
}
|
|
408
|
+
function isKitComponentTagName(path) {
|
|
409
|
+
const name = path.node.name;
|
|
410
|
+
let head = null;
|
|
411
|
+
if (t.isJSXIdentifier(name)) {
|
|
412
|
+
head = name.name;
|
|
413
|
+
} else if (t.isJSXMemberExpression(name)) {
|
|
414
|
+
let cur = name;
|
|
415
|
+
while (t.isJSXMemberExpression(cur)) cur = cur.object;
|
|
416
|
+
if (t.isJSXIdentifier(cur)) head = cur.name;
|
|
417
|
+
}
|
|
418
|
+
if (!head || !/^[A-Z]/.test(head)) return false;
|
|
419
|
+
if (head === "Kit") return true;
|
|
420
|
+
const programPath = path.scope.getProgramParent().path;
|
|
421
|
+
if (programPath.isProgram() && computeKitBoundNames(programPath).has(head)) return true;
|
|
422
|
+
const binding = path.scope.getBinding(head);
|
|
423
|
+
if (binding) {
|
|
424
|
+
const bp = binding.path;
|
|
425
|
+
const isImport = bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier();
|
|
426
|
+
if (isImport) {
|
|
427
|
+
const decl = bp.parentPath;
|
|
428
|
+
if (decl?.isImportDeclaration() && /kit-runtime/.test(decl.node.source.value)) return true;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
function computeLockReason(isKitOrigin, isChrome, dynamicType) {
|
|
377
434
|
if (isKitOrigin) return "KIT_INTERNAL";
|
|
378
435
|
if (isChrome) return "CHROME_STRUCTURAL";
|
|
379
436
|
if (dynamicType === "ARRAY") return "DYNAMIC_ARRAY";
|
|
380
437
|
if (dynamicType === "CONDITIONAL") return "DYNAMIC_CONDITIONAL";
|
|
381
|
-
if (containerKind === "expression") return "EXPRESSION_CONTAINER";
|
|
382
438
|
return void 0;
|
|
383
439
|
}
|
|
384
440
|
function isMovable(path) {
|
|
@@ -1028,6 +1084,10 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
1028
1084
|
}
|
|
1029
1085
|
}
|
|
1030
1086
|
const vid = readVidAttr(path.node.attributes);
|
|
1087
|
+
if (!vid && onMissingVid && !missingVidWarned) {
|
|
1088
|
+
missingVidWarned = true;
|
|
1089
|
+
onMissingVid({ file, line, col, componentName, instrumented: allowLegacyIds });
|
|
1090
|
+
}
|
|
1031
1091
|
if (!vid && !allowLegacyIds) return;
|
|
1032
1092
|
const nodeId = vid ?? computeNodeId(file, line, col, componentName);
|
|
1033
1093
|
const isKitOrigin = origin === "kit" || hasSlotAttr;
|
|
@@ -1055,7 +1115,8 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
1055
1115
|
const dynamicType = computeDynamicType(path);
|
|
1056
1116
|
const isChrome = computeIsChrome(file, path);
|
|
1057
1117
|
const containerKind = computeContainerKind(path);
|
|
1058
|
-
const
|
|
1118
|
+
const isKitComponentContainer = isKitComponentTagName(path);
|
|
1119
|
+
const lockReason = computeLockReason(isKitOrigin, isChrome, dynamicType);
|
|
1059
1120
|
metaObj.properties.push(
|
|
1060
1121
|
t.objectProperty(t.identifier("vid"), t.stringLiteral(vid)),
|
|
1061
1122
|
t.objectProperty(t.identifier("isKitOrigin"), t.booleanLiteral(isKitOrigin)),
|
|
@@ -1063,6 +1124,11 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
1063
1124
|
t.objectProperty(t.identifier("isChrome"), t.booleanLiteral(isChrome)),
|
|
1064
1125
|
t.objectProperty(t.identifier("containerKind"), t.stringLiteral(containerKind))
|
|
1065
1126
|
);
|
|
1127
|
+
if (isKitComponentContainer) {
|
|
1128
|
+
metaObj.properties.push(
|
|
1129
|
+
t.objectProperty(t.identifier("isKitContainer"), t.booleanLiteral(true))
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1066
1132
|
if (lockReason) {
|
|
1067
1133
|
metaObj.properties.push(
|
|
1068
1134
|
t.objectProperty(t.identifier("lockReason"), t.stringLiteral(lockReason))
|
|
@@ -1156,7 +1222,17 @@ function archieDevTools(options = {}) {
|
|
|
1156
1222
|
};
|
|
1157
1223
|
let babelCore = null;
|
|
1158
1224
|
let includeHostSourceRef = false;
|
|
1225
|
+
let isDevServer = false;
|
|
1159
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
|
+
}
|
|
1160
1236
|
const plugin = {
|
|
1161
1237
|
name: "vite-plugin-archie-devtools",
|
|
1162
1238
|
enforce: "pre",
|
|
@@ -1172,6 +1248,7 @@ function archieDevTools(options = {}) {
|
|
|
1172
1248
|
},
|
|
1173
1249
|
configResolved(config) {
|
|
1174
1250
|
includeHostSourceRef = !config.isProduction;
|
|
1251
|
+
isDevServer = config.command === "serve";
|
|
1175
1252
|
},
|
|
1176
1253
|
configureServer(server) {
|
|
1177
1254
|
server.middlewares.use(LOCAL_INSPECTOR_SERVE_PATH, (_req, res) => {
|
|
@@ -1207,7 +1284,10 @@ function archieDevTools(options = {}) {
|
|
|
1207
1284
|
const result = await babel.transformAsync(code, {
|
|
1208
1285
|
filename: id,
|
|
1209
1286
|
plugins: [
|
|
1210
|
-
(b) => babelPluginEditorMeta(b, {
|
|
1287
|
+
(b) => babelPluginEditorMeta(b, {
|
|
1288
|
+
includeHostSourceRef,
|
|
1289
|
+
onMissingVid: isDevServer ? warnMissingVid : void 0
|
|
1290
|
+
}),
|
|
1211
1291
|
...dndPages.test(id) ? [(b) => babelPluginDndAuto(b, { importSource: INTERNAL_DND_SCOPE_IMPORT_SOURCE })] : []
|
|
1212
1292
|
],
|
|
1213
1293
|
parserOpts: {
|
|
@@ -1247,7 +1327,8 @@ function archieDevTools(options = {}) {
|
|
|
1247
1327
|
if (!/node_modules/.test(context.id) && !transformedByHook.has(context.id)) {
|
|
1248
1328
|
babelOptions.plugins.push(
|
|
1249
1329
|
(babel) => babelPluginEditorMeta(babel, {
|
|
1250
|
-
includeHostSourceRef
|
|
1330
|
+
includeHostSourceRef,
|
|
1331
|
+
onMissingVid: isDevServer ? warnMissingVid : void 0
|
|
1251
1332
|
})
|
|
1252
1333
|
);
|
|
1253
1334
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__dirname,
|
|
3
3
|
babelPluginEditorMeta
|
|
4
|
-
} from "./chunk-
|
|
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, {
|
|
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
|
}
|