@archie/devtools 0.1.0 → 0.1.2
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/{chunk-THKKWDMJ.mjs → chunk-WBZJILZ6.mjs} +68 -8
- package/dist/client/client.js +20 -10
- package/dist/client/client.mjs +19 -9
- package/dist/collection-binding.mjs +1 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +68 -8
- package/dist/index.mjs +1 -1
- package/package.json +2 -1
|
@@ -151,11 +151,17 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
151
151
|
}
|
|
152
152
|
return "STATIC";
|
|
153
153
|
}
|
|
154
|
-
const SHELL_FILE_RE = /(^|\/)shell\.jsx$/;
|
|
154
|
+
const SHELL_FILE_RE = /(^|\/)shell\.(jsx|tsx)$/;
|
|
155
155
|
const SHELL_DIR_RE = /(^|\/)components\/shell\//;
|
|
156
|
+
const SHELL_BASENAME_RE = /shell/i;
|
|
156
157
|
const CHROME_ANCESTOR_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "header"]);
|
|
157
|
-
function
|
|
158
|
+
function isChromeFilePath(file) {
|
|
158
159
|
if (SHELL_FILE_RE.test(file) || SHELL_DIR_RE.test(file)) return true;
|
|
160
|
+
const base = file.split("/").pop() ?? file;
|
|
161
|
+
return SHELL_BASENAME_RE.test(base);
|
|
162
|
+
}
|
|
163
|
+
function computeIsChrome(file, path2) {
|
|
164
|
+
if (isChromeFilePath(file)) return true;
|
|
159
165
|
let current = path2.parentPath;
|
|
160
166
|
while (current) {
|
|
161
167
|
if (current.isJSXElement()) {
|
|
@@ -169,17 +175,65 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
169
175
|
function computeContainerKind(path2) {
|
|
170
176
|
const elPath = path2.parentPath;
|
|
171
177
|
if (!elPath?.isJSXElement()) return "none";
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const allPlain = children.every((c) =>
|
|
178
|
+
if (!elPath.node.closingElement) return "none";
|
|
179
|
+
const children = elPath.node.children;
|
|
180
|
+
const allPlain = children.every((c) => {
|
|
181
|
+
if (t.isJSXElement(c)) return true;
|
|
182
|
+
if (t.isJSXText(c)) return c.value.trim() === "";
|
|
183
|
+
return false;
|
|
184
|
+
});
|
|
175
185
|
return allPlain ? "plain" : "expression";
|
|
176
186
|
}
|
|
177
|
-
|
|
187
|
+
const kitBoundNamesCache = /* @__PURE__ */ new WeakMap();
|
|
188
|
+
function computeKitBoundNames(programPath) {
|
|
189
|
+
const cached = kitBoundNamesCache.get(programPath.node);
|
|
190
|
+
if (cached) return cached;
|
|
191
|
+
const names = /* @__PURE__ */ new Set();
|
|
192
|
+
for (const stmt of programPath.node.body) {
|
|
193
|
+
if (!t.isVariableDeclaration(stmt)) continue;
|
|
194
|
+
for (const decl of stmt.declarations) {
|
|
195
|
+
if (!t.isObjectPattern(decl.id)) continue;
|
|
196
|
+
if (!decl.init || !t.isIdentifier(decl.init) || decl.init.name !== "Kit") continue;
|
|
197
|
+
for (const prop of decl.id.properties) {
|
|
198
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
199
|
+
const value = t.isIdentifier(prop.value) ? prop.value : t.isIdentifier(prop.key) ? prop.key : null;
|
|
200
|
+
if (value) names.add(value.name);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
kitBoundNamesCache.set(programPath.node, names);
|
|
205
|
+
return names;
|
|
206
|
+
}
|
|
207
|
+
function isKitComponentTagName(path2) {
|
|
208
|
+
const name = path2.node.name;
|
|
209
|
+
let head = null;
|
|
210
|
+
if (t.isJSXIdentifier(name)) {
|
|
211
|
+
head = name.name;
|
|
212
|
+
} else if (t.isJSXMemberExpression(name)) {
|
|
213
|
+
let cur = name;
|
|
214
|
+
while (t.isJSXMemberExpression(cur)) cur = cur.object;
|
|
215
|
+
if (t.isJSXIdentifier(cur)) head = cur.name;
|
|
216
|
+
}
|
|
217
|
+
if (!head || !/^[A-Z]/.test(head)) return false;
|
|
218
|
+
if (head === "Kit") return true;
|
|
219
|
+
const programPath = path2.scope.getProgramParent().path;
|
|
220
|
+
if (programPath.isProgram() && computeKitBoundNames(programPath).has(head)) return true;
|
|
221
|
+
const binding = path2.scope.getBinding(head);
|
|
222
|
+
if (binding) {
|
|
223
|
+
const bp = binding.path;
|
|
224
|
+
const isImport = bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier();
|
|
225
|
+
if (isImport) {
|
|
226
|
+
const decl = bp.parentPath;
|
|
227
|
+
if (decl?.isImportDeclaration() && /kit-runtime/.test(decl.node.source.value)) return true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
function computeLockReason(isKitOrigin, isChrome, dynamicType) {
|
|
178
233
|
if (isKitOrigin) return "KIT_INTERNAL";
|
|
179
234
|
if (isChrome) return "CHROME_STRUCTURAL";
|
|
180
235
|
if (dynamicType === "ARRAY") return "DYNAMIC_ARRAY";
|
|
181
236
|
if (dynamicType === "CONDITIONAL") return "DYNAMIC_CONDITIONAL";
|
|
182
|
-
if (containerKind === "expression") return "EXPRESSION_CONTAINER";
|
|
183
237
|
return void 0;
|
|
184
238
|
}
|
|
185
239
|
function isMovable(path2) {
|
|
@@ -856,7 +910,8 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
856
910
|
const dynamicType = computeDynamicType(path2);
|
|
857
911
|
const isChrome = computeIsChrome(file, path2);
|
|
858
912
|
const containerKind = computeContainerKind(path2);
|
|
859
|
-
const
|
|
913
|
+
const isKitComponentContainer = isKitComponentTagName(path2);
|
|
914
|
+
const lockReason = computeLockReason(isKitOrigin, isChrome, dynamicType);
|
|
860
915
|
metaObj.properties.push(
|
|
861
916
|
t.objectProperty(t.identifier("vid"), t.stringLiteral(vid)),
|
|
862
917
|
t.objectProperty(t.identifier("isKitOrigin"), t.booleanLiteral(isKitOrigin)),
|
|
@@ -864,6 +919,11 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
864
919
|
t.objectProperty(t.identifier("isChrome"), t.booleanLiteral(isChrome)),
|
|
865
920
|
t.objectProperty(t.identifier("containerKind"), t.stringLiteral(containerKind))
|
|
866
921
|
);
|
|
922
|
+
if (isKitComponentContainer) {
|
|
923
|
+
metaObj.properties.push(
|
|
924
|
+
t.objectProperty(t.identifier("isKitContainer"), t.booleanLiteral(true))
|
|
925
|
+
);
|
|
926
|
+
}
|
|
867
927
|
if (lockReason) {
|
|
868
928
|
metaObj.properties.push(
|
|
869
929
|
t.objectProperty(t.identifier("lockReason"), t.stringLiteral(lockReason))
|
package/dist/client/client.js
CHANGED
|
@@ -4235,6 +4235,7 @@ function isNonDroppableNodeMeta(meta) {
|
|
|
4235
4235
|
if (meta.containerKind && meta.containerKind !== "plain") return true;
|
|
4236
4236
|
if (meta.isChrome) return true;
|
|
4237
4237
|
if (meta.isKitOrigin) return true;
|
|
4238
|
+
if (meta.isKitContainer) return true;
|
|
4238
4239
|
return false;
|
|
4239
4240
|
}
|
|
4240
4241
|
function isNonDraggableNodeMeta(meta) {
|
|
@@ -4261,26 +4262,37 @@ function collectSubtreeIds(rootId, projection) {
|
|
|
4261
4262
|
}
|
|
4262
4263
|
function computeDroppableSet(sourceId, projection, nodeMap) {
|
|
4263
4264
|
const excluded = collectSubtreeIds(sourceId, projection);
|
|
4265
|
+
const sourceFile = nodeMap.get(sourceId)?.editorMeta?.file;
|
|
4264
4266
|
const droppable = /* @__PURE__ */ new Set();
|
|
4265
4267
|
for (const containerId of projection.containerIndex.keys()) {
|
|
4266
4268
|
if (excluded.has(containerId)) continue;
|
|
4267
4269
|
if (isStructuralContainer(containerId, nodeMap)) continue;
|
|
4268
4270
|
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) continue;
|
|
4271
|
+
const containerFile = nodeMap.get(containerId)?.editorMeta?.file;
|
|
4272
|
+
if (sourceFile && containerFile && containerFile !== sourceFile) continue;
|
|
4269
4273
|
droppable.add(containerId);
|
|
4270
4274
|
}
|
|
4271
4275
|
return droppable;
|
|
4272
4276
|
}
|
|
4273
|
-
function buildBlockedNodeMetaContainerIds(projection, nodeMap) {
|
|
4277
|
+
function buildBlockedNodeMetaContainerIds(projection, nodeMap, sourceId) {
|
|
4278
|
+
const sourceFile = sourceId ? nodeMap.get(sourceId)?.editorMeta?.file : void 0;
|
|
4274
4279
|
const blocked = /* @__PURE__ */ new Set();
|
|
4275
4280
|
for (const containerId of projection.containerIndex.keys()) {
|
|
4276
4281
|
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) {
|
|
4277
4282
|
blocked.add(containerId);
|
|
4283
|
+
continue;
|
|
4284
|
+
}
|
|
4285
|
+
const containerFile = nodeMap.get(containerId)?.editorMeta?.file;
|
|
4286
|
+
if (sourceFile && containerFile && containerFile !== sourceFile) {
|
|
4287
|
+
blocked.add(containerId);
|
|
4278
4288
|
}
|
|
4279
4289
|
}
|
|
4280
4290
|
return blocked;
|
|
4281
4291
|
}
|
|
4282
4292
|
function resolveRefusalCode(meta, fallback) {
|
|
4283
|
-
|
|
4293
|
+
if (meta?.lockReason) return meta.lockReason;
|
|
4294
|
+
if (meta?.isKitContainer) return "KIT_INTERNAL";
|
|
4295
|
+
return fallback;
|
|
4284
4296
|
}
|
|
4285
4297
|
function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainerId) {
|
|
4286
4298
|
const blocked = /* @__PURE__ */ new Set();
|
|
@@ -4291,8 +4303,10 @@ function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainer
|
|
|
4291
4303
|
return blocked;
|
|
4292
4304
|
}
|
|
4293
4305
|
|
|
4306
|
+
// src/client/dnd/design-mode/node-meta-guard.ts
|
|
4307
|
+
var VID_PATTERN = /^[a-z0-9]{6,8}$/;
|
|
4308
|
+
|
|
4294
4309
|
// src/client/dnd/design-mode/fiber-bridge.ts
|
|
4295
|
-
var import_editor_protocol = require("@8base-archie/editor-protocol");
|
|
4296
4310
|
var FIBER_KEY_PREFIX = "__reactFiber$";
|
|
4297
4311
|
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
4298
4312
|
var metaCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4555,9 +4569,6 @@ function resolveDragSurface(el) {
|
|
|
4555
4569
|
};
|
|
4556
4570
|
}
|
|
4557
4571
|
|
|
4558
|
-
// src/types/editor-meta.ts
|
|
4559
|
-
var import_editor_protocol2 = require("@8base-archie/editor-protocol");
|
|
4560
|
-
|
|
4561
4572
|
// src/client/dnd/design-mode/node-key.ts
|
|
4562
4573
|
var _runtimeKeyMap = /* @__PURE__ */ new WeakMap();
|
|
4563
4574
|
var _runtimeKeyCounter = 0;
|
|
@@ -4585,7 +4596,7 @@ function getNodeKeyFromElement(el) {
|
|
|
4585
4596
|
}
|
|
4586
4597
|
function resolveVidFromElement(el) {
|
|
4587
4598
|
const key2 = getNodeKeyFromElement(el);
|
|
4588
|
-
return
|
|
4599
|
+
return VID_PATTERN.test(key2) ? key2 : null;
|
|
4589
4600
|
}
|
|
4590
4601
|
function getInspectorRefFromElement(el) {
|
|
4591
4602
|
const resolved = resolveDragSurface(el);
|
|
@@ -8595,7 +8606,7 @@ function useDragLifecycle({
|
|
|
8595
8606
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8596
8607
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8597
8608
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8598
|
-
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current)) {
|
|
8609
|
+
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current, anchorNodeId)) {
|
|
8599
8610
|
blockedContainerIds.add(id);
|
|
8600
8611
|
}
|
|
8601
8612
|
const droppableSet = computeDroppableSet(anchorNodeId, proj, refs.nodeMapRef.current);
|
|
@@ -8680,9 +8691,8 @@ function useDragLifecycle({
|
|
|
8680
8691
|
if (dropTargetId && !refs.droppableContainerIdsRef.current?.has(dropTargetId)) {
|
|
8681
8692
|
const targetContainerEl = resolveNodeElement(dropTargetId);
|
|
8682
8693
|
const targetMeta = refs.nodeMapRef.current.get(dropTargetId)?.editorMeta;
|
|
8683
|
-
const fallbackCode = targetMeta?.containerKind === "expression" ? "EXPRESSION_CONTAINER" : "CONTAINER_NOT_PLAIN";
|
|
8684
8694
|
emitRefused(
|
|
8685
|
-
resolveRefusalCode(targetMeta,
|
|
8695
|
+
resolveRefusalCode(targetMeta, "CONTAINER_NOT_PLAIN"),
|
|
8686
8696
|
"Drop target is outside the droppable set for this node.",
|
|
8687
8697
|
targetContainerEl
|
|
8688
8698
|
);
|
package/dist/client/client.mjs
CHANGED
|
@@ -4200,6 +4200,7 @@ function isNonDroppableNodeMeta(meta) {
|
|
|
4200
4200
|
if (meta.containerKind && meta.containerKind !== "plain") return true;
|
|
4201
4201
|
if (meta.isChrome) return true;
|
|
4202
4202
|
if (meta.isKitOrigin) return true;
|
|
4203
|
+
if (meta.isKitContainer) return true;
|
|
4203
4204
|
return false;
|
|
4204
4205
|
}
|
|
4205
4206
|
function isNonDraggableNodeMeta(meta) {
|
|
@@ -4226,26 +4227,37 @@ function collectSubtreeIds(rootId, projection) {
|
|
|
4226
4227
|
}
|
|
4227
4228
|
function computeDroppableSet(sourceId, projection, nodeMap) {
|
|
4228
4229
|
const excluded = collectSubtreeIds(sourceId, projection);
|
|
4230
|
+
const sourceFile = nodeMap.get(sourceId)?.editorMeta?.file;
|
|
4229
4231
|
const droppable = /* @__PURE__ */ new Set();
|
|
4230
4232
|
for (const containerId of projection.containerIndex.keys()) {
|
|
4231
4233
|
if (excluded.has(containerId)) continue;
|
|
4232
4234
|
if (isStructuralContainer(containerId, nodeMap)) continue;
|
|
4233
4235
|
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) continue;
|
|
4236
|
+
const containerFile = nodeMap.get(containerId)?.editorMeta?.file;
|
|
4237
|
+
if (sourceFile && containerFile && containerFile !== sourceFile) continue;
|
|
4234
4238
|
droppable.add(containerId);
|
|
4235
4239
|
}
|
|
4236
4240
|
return droppable;
|
|
4237
4241
|
}
|
|
4238
|
-
function buildBlockedNodeMetaContainerIds(projection, nodeMap) {
|
|
4242
|
+
function buildBlockedNodeMetaContainerIds(projection, nodeMap, sourceId) {
|
|
4243
|
+
const sourceFile = sourceId ? nodeMap.get(sourceId)?.editorMeta?.file : void 0;
|
|
4239
4244
|
const blocked = /* @__PURE__ */ new Set();
|
|
4240
4245
|
for (const containerId of projection.containerIndex.keys()) {
|
|
4241
4246
|
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) {
|
|
4242
4247
|
blocked.add(containerId);
|
|
4248
|
+
continue;
|
|
4249
|
+
}
|
|
4250
|
+
const containerFile = nodeMap.get(containerId)?.editorMeta?.file;
|
|
4251
|
+
if (sourceFile && containerFile && containerFile !== sourceFile) {
|
|
4252
|
+
blocked.add(containerId);
|
|
4243
4253
|
}
|
|
4244
4254
|
}
|
|
4245
4255
|
return blocked;
|
|
4246
4256
|
}
|
|
4247
4257
|
function resolveRefusalCode(meta, fallback) {
|
|
4248
|
-
|
|
4258
|
+
if (meta?.lockReason) return meta.lockReason;
|
|
4259
|
+
if (meta?.isKitContainer) return "KIT_INTERNAL";
|
|
4260
|
+
return fallback;
|
|
4249
4261
|
}
|
|
4250
4262
|
function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainerId) {
|
|
4251
4263
|
const blocked = /* @__PURE__ */ new Set();
|
|
@@ -4256,8 +4268,10 @@ function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainer
|
|
|
4256
4268
|
return blocked;
|
|
4257
4269
|
}
|
|
4258
4270
|
|
|
4271
|
+
// src/client/dnd/design-mode/node-meta-guard.ts
|
|
4272
|
+
var VID_PATTERN = /^[a-z0-9]{6,8}$/;
|
|
4273
|
+
|
|
4259
4274
|
// src/client/dnd/design-mode/fiber-bridge.ts
|
|
4260
|
-
import { NodeMetaSchema } from "@8base-archie/editor-protocol";
|
|
4261
4275
|
var FIBER_KEY_PREFIX = "__reactFiber$";
|
|
4262
4276
|
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
4263
4277
|
var metaCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4520,9 +4534,6 @@ function resolveDragSurface(el) {
|
|
|
4520
4534
|
};
|
|
4521
4535
|
}
|
|
4522
4536
|
|
|
4523
|
-
// src/types/editor-meta.ts
|
|
4524
|
-
import { VID_PATTERN, VID_ATTR } from "@8base-archie/editor-protocol";
|
|
4525
|
-
|
|
4526
4537
|
// src/client/dnd/design-mode/node-key.ts
|
|
4527
4538
|
var _runtimeKeyMap = /* @__PURE__ */ new WeakMap();
|
|
4528
4539
|
var _runtimeKeyCounter = 0;
|
|
@@ -8560,7 +8571,7 @@ function useDragLifecycle({
|
|
|
8560
8571
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8561
8572
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8562
8573
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8563
|
-
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current)) {
|
|
8574
|
+
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current, anchorNodeId)) {
|
|
8564
8575
|
blockedContainerIds.add(id);
|
|
8565
8576
|
}
|
|
8566
8577
|
const droppableSet = computeDroppableSet(anchorNodeId, proj, refs.nodeMapRef.current);
|
|
@@ -8645,9 +8656,8 @@ function useDragLifecycle({
|
|
|
8645
8656
|
if (dropTargetId && !refs.droppableContainerIdsRef.current?.has(dropTargetId)) {
|
|
8646
8657
|
const targetContainerEl = resolveNodeElement(dropTargetId);
|
|
8647
8658
|
const targetMeta = refs.nodeMapRef.current.get(dropTargetId)?.editorMeta;
|
|
8648
|
-
const fallbackCode = targetMeta?.containerKind === "expression" ? "EXPRESSION_CONTAINER" : "CONTAINER_NOT_PLAIN";
|
|
8649
8659
|
emitRefused(
|
|
8650
|
-
resolveRefusalCode(targetMeta,
|
|
8660
|
+
resolveRefusalCode(targetMeta, "CONTAINER_NOT_PLAIN"),
|
|
8651
8661
|
"Drop target is outside the droppable set for this node.",
|
|
8652
8662
|
targetContainerEl
|
|
8653
8663
|
);
|
package/dist/index.d.mts
CHANGED
|
@@ -644,6 +644,14 @@ interface EditorMeta {
|
|
|
644
644
|
* writable, static, non-chrome, non-kit element.
|
|
645
645
|
*/
|
|
646
646
|
lockReason?: 'KIT_INTERNAL' | 'DYNAMIC_ARRAY' | 'DYNAMIC_CONDITIONAL' | 'CHROME_STRUCTURAL' | 'EXPRESSION_CONTAINER';
|
|
647
|
+
/**
|
|
648
|
+
* `true` when this element's own tag is a Kit component instance
|
|
649
|
+
* (`isKitComponentTagName` in `babel-plugin-editor-meta.ts`). Devtools-local
|
|
650
|
+
* only, not in the `.strict()` NodeMeta protocol schema, and never folded
|
|
651
|
+
* into `isKitOrigin`/`lockReason` — it blocks this element as a drop
|
|
652
|
+
* CONTAINER only, not the element's own draggability/inspectability.
|
|
653
|
+
*/
|
|
654
|
+
isKitContainer?: boolean;
|
|
647
655
|
}
|
|
648
656
|
|
|
649
657
|
interface ArchieDevToolsOptions {
|
package/dist/index.d.ts
CHANGED
|
@@ -644,6 +644,14 @@ interface EditorMeta {
|
|
|
644
644
|
* writable, static, non-chrome, non-kit element.
|
|
645
645
|
*/
|
|
646
646
|
lockReason?: 'KIT_INTERNAL' | 'DYNAMIC_ARRAY' | 'DYNAMIC_CONDITIONAL' | 'CHROME_STRUCTURAL' | 'EXPRESSION_CONTAINER';
|
|
647
|
+
/**
|
|
648
|
+
* `true` when this element's own tag is a Kit component instance
|
|
649
|
+
* (`isKitComponentTagName` in `babel-plugin-editor-meta.ts`). Devtools-local
|
|
650
|
+
* only, not in the `.strict()` NodeMeta protocol schema, and never folded
|
|
651
|
+
* into `isKitOrigin`/`lockReason` — it blocks this element as a drop
|
|
652
|
+
* CONTAINER only, not the element's own draggability/inspectability.
|
|
653
|
+
*/
|
|
654
|
+
isKitContainer?: boolean;
|
|
647
655
|
}
|
|
648
656
|
|
|
649
657
|
interface ArchieDevToolsOptions {
|
package/dist/index.js
CHANGED
|
@@ -350,11 +350,17 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
350
350
|
}
|
|
351
351
|
return "STATIC";
|
|
352
352
|
}
|
|
353
|
-
const SHELL_FILE_RE = /(^|\/)shell\.jsx$/;
|
|
353
|
+
const SHELL_FILE_RE = /(^|\/)shell\.(jsx|tsx)$/;
|
|
354
354
|
const SHELL_DIR_RE = /(^|\/)components\/shell\//;
|
|
355
|
+
const SHELL_BASENAME_RE = /shell/i;
|
|
355
356
|
const CHROME_ANCESTOR_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "header"]);
|
|
356
|
-
function
|
|
357
|
+
function isChromeFilePath(file) {
|
|
357
358
|
if (SHELL_FILE_RE.test(file) || SHELL_DIR_RE.test(file)) return true;
|
|
359
|
+
const base = file.split("/").pop() ?? file;
|
|
360
|
+
return SHELL_BASENAME_RE.test(base);
|
|
361
|
+
}
|
|
362
|
+
function computeIsChrome(file, path) {
|
|
363
|
+
if (isChromeFilePath(file)) return true;
|
|
358
364
|
let current = path.parentPath;
|
|
359
365
|
while (current) {
|
|
360
366
|
if (current.isJSXElement()) {
|
|
@@ -368,17 +374,65 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
368
374
|
function computeContainerKind(path) {
|
|
369
375
|
const elPath = path.parentPath;
|
|
370
376
|
if (!elPath?.isJSXElement()) return "none";
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const allPlain = children.every((c) =>
|
|
377
|
+
if (!elPath.node.closingElement) return "none";
|
|
378
|
+
const children = elPath.node.children;
|
|
379
|
+
const allPlain = children.every((c) => {
|
|
380
|
+
if (t.isJSXElement(c)) return true;
|
|
381
|
+
if (t.isJSXText(c)) return c.value.trim() === "";
|
|
382
|
+
return false;
|
|
383
|
+
});
|
|
374
384
|
return allPlain ? "plain" : "expression";
|
|
375
385
|
}
|
|
376
|
-
|
|
386
|
+
const kitBoundNamesCache = /* @__PURE__ */ new WeakMap();
|
|
387
|
+
function computeKitBoundNames(programPath) {
|
|
388
|
+
const cached = kitBoundNamesCache.get(programPath.node);
|
|
389
|
+
if (cached) return cached;
|
|
390
|
+
const names = /* @__PURE__ */ new Set();
|
|
391
|
+
for (const stmt of programPath.node.body) {
|
|
392
|
+
if (!t.isVariableDeclaration(stmt)) continue;
|
|
393
|
+
for (const decl of stmt.declarations) {
|
|
394
|
+
if (!t.isObjectPattern(decl.id)) continue;
|
|
395
|
+
if (!decl.init || !t.isIdentifier(decl.init) || decl.init.name !== "Kit") continue;
|
|
396
|
+
for (const prop of decl.id.properties) {
|
|
397
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
398
|
+
const value = t.isIdentifier(prop.value) ? prop.value : t.isIdentifier(prop.key) ? prop.key : null;
|
|
399
|
+
if (value) names.add(value.name);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
kitBoundNamesCache.set(programPath.node, names);
|
|
404
|
+
return names;
|
|
405
|
+
}
|
|
406
|
+
function isKitComponentTagName(path) {
|
|
407
|
+
const name = path.node.name;
|
|
408
|
+
let head = null;
|
|
409
|
+
if (t.isJSXIdentifier(name)) {
|
|
410
|
+
head = name.name;
|
|
411
|
+
} else if (t.isJSXMemberExpression(name)) {
|
|
412
|
+
let cur = name;
|
|
413
|
+
while (t.isJSXMemberExpression(cur)) cur = cur.object;
|
|
414
|
+
if (t.isJSXIdentifier(cur)) head = cur.name;
|
|
415
|
+
}
|
|
416
|
+
if (!head || !/^[A-Z]/.test(head)) return false;
|
|
417
|
+
if (head === "Kit") return true;
|
|
418
|
+
const programPath = path.scope.getProgramParent().path;
|
|
419
|
+
if (programPath.isProgram() && computeKitBoundNames(programPath).has(head)) return true;
|
|
420
|
+
const binding = path.scope.getBinding(head);
|
|
421
|
+
if (binding) {
|
|
422
|
+
const bp = binding.path;
|
|
423
|
+
const isImport = bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier();
|
|
424
|
+
if (isImport) {
|
|
425
|
+
const decl = bp.parentPath;
|
|
426
|
+
if (decl?.isImportDeclaration() && /kit-runtime/.test(decl.node.source.value)) return true;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
function computeLockReason(isKitOrigin, isChrome, dynamicType) {
|
|
377
432
|
if (isKitOrigin) return "KIT_INTERNAL";
|
|
378
433
|
if (isChrome) return "CHROME_STRUCTURAL";
|
|
379
434
|
if (dynamicType === "ARRAY") return "DYNAMIC_ARRAY";
|
|
380
435
|
if (dynamicType === "CONDITIONAL") return "DYNAMIC_CONDITIONAL";
|
|
381
|
-
if (containerKind === "expression") return "EXPRESSION_CONTAINER";
|
|
382
436
|
return void 0;
|
|
383
437
|
}
|
|
384
438
|
function isMovable(path) {
|
|
@@ -1055,7 +1109,8 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
1055
1109
|
const dynamicType = computeDynamicType(path);
|
|
1056
1110
|
const isChrome = computeIsChrome(file, path);
|
|
1057
1111
|
const containerKind = computeContainerKind(path);
|
|
1058
|
-
const
|
|
1112
|
+
const isKitComponentContainer = isKitComponentTagName(path);
|
|
1113
|
+
const lockReason = computeLockReason(isKitOrigin, isChrome, dynamicType);
|
|
1059
1114
|
metaObj.properties.push(
|
|
1060
1115
|
t.objectProperty(t.identifier("vid"), t.stringLiteral(vid)),
|
|
1061
1116
|
t.objectProperty(t.identifier("isKitOrigin"), t.booleanLiteral(isKitOrigin)),
|
|
@@ -1063,6 +1118,11 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
1063
1118
|
t.objectProperty(t.identifier("isChrome"), t.booleanLiteral(isChrome)),
|
|
1064
1119
|
t.objectProperty(t.identifier("containerKind"), t.stringLiteral(containerKind))
|
|
1065
1120
|
);
|
|
1121
|
+
if (isKitComponentContainer) {
|
|
1122
|
+
metaObj.properties.push(
|
|
1123
|
+
t.objectProperty(t.identifier("isKitContainer"), t.booleanLiteral(true))
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1066
1126
|
if (lockReason) {
|
|
1067
1127
|
metaObj.properties.push(
|
|
1068
1128
|
t.objectProperty(t.identifier("lockReason"), t.stringLiteral(lockReason))
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archie/devtools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "DevTools for Archie generated applications - Route synchronization and editor communication",
|
|
5
|
+
"sideEffects": false,
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "git+https://github.com/8base-archie/archie-devtools.git"
|