@archie/devtools 0.0.48 → 0.1.1
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 +36 -0
- package/dist/{chunk-P5XMHBFS.mjs → chunk-THKKWDMJ.mjs} +98 -2
- package/dist/client/client.js +159 -2
- package/dist/client/client.mjs +159 -2
- package/dist/collection-binding.js +1 -0
- package/dist/collection-binding.mjs +1 -1
- package/dist/index.d.mts +92 -1
- package/dist/index.d.ts +92 -1
- package/dist/index.js +98 -2
- package/dist/index.mjs +1 -1
- package/dist/inspector.standalone.js +133 -0
- package/package.json +5 -2
package/dist/client/client.mjs
CHANGED
|
@@ -4081,13 +4081,21 @@ function summarizeRuntimeEvent(detail) {
|
|
|
4081
4081
|
container: summarizeIdentity(detail.container),
|
|
4082
4082
|
beforeSibling: summarizeIdentity(detail.beforeSibling),
|
|
4083
4083
|
sourceContainer: summarizeIdentity(detail.sourceContainer),
|
|
4084
|
-
diagnostics: detail.diagnostics ?? null
|
|
4084
|
+
diagnostics: detail.diagnostics ?? null,
|
|
4085
|
+
targetVid: detail.targetVid ?? null,
|
|
4086
|
+
containerVid: detail.containerVid ?? null,
|
|
4087
|
+
index: detail.index
|
|
4085
4088
|
};
|
|
4089
|
+
case "drag-started":
|
|
4090
|
+
return { targetVid: detail.targetVid, droppableCount: detail.droppable.length };
|
|
4091
|
+
case "drag-refused":
|
|
4092
|
+
return { code: detail.code, cause: detail.cause, vid: detail.vid };
|
|
4086
4093
|
case "element-resized":
|
|
4087
4094
|
return {
|
|
4088
4095
|
operationId: detail.operationId,
|
|
4089
4096
|
selected: summarizeIdentity(detail.selected),
|
|
4090
4097
|
anchor: summarizeIdentity(detail.anchor),
|
|
4098
|
+
targetVid: detail.targetVid ?? null,
|
|
4091
4099
|
resize: {
|
|
4092
4100
|
mode: detail.resize.mode,
|
|
4093
4101
|
selectedNodeKey: detail.resize.selectedNodeKey,
|
|
@@ -4104,6 +4112,8 @@ function summarizeRuntimeEvent(detail) {
|
|
|
4104
4112
|
nodeKey: detail.nodeKey,
|
|
4105
4113
|
displayName: detail.displayName,
|
|
4106
4114
|
container: summarizeIdentity(detail.container),
|
|
4115
|
+
containerVid: detail.containerVid ?? null,
|
|
4116
|
+
insertedVid: detail.insertedVid ?? null,
|
|
4107
4117
|
index: detail.index,
|
|
4108
4118
|
beforeSibling: summarizeIdentity(detail.beforeSibling),
|
|
4109
4119
|
hasTsxCode: !!detail.tsxCode,
|
|
@@ -4185,6 +4195,58 @@ function isValidLaneContainer(containerId, projection, nodeMap) {
|
|
|
4185
4195
|
if (container.children.length === 0) return false;
|
|
4186
4196
|
return !isStructuralContainer(containerId, nodeMap);
|
|
4187
4197
|
}
|
|
4198
|
+
function isNonDroppableNodeMeta(meta) {
|
|
4199
|
+
if (!meta) return false;
|
|
4200
|
+
if (meta.containerKind && meta.containerKind !== "plain") return true;
|
|
4201
|
+
if (meta.isChrome) return true;
|
|
4202
|
+
if (meta.isKitOrigin) return true;
|
|
4203
|
+
return false;
|
|
4204
|
+
}
|
|
4205
|
+
function isNonDraggableNodeMeta(meta) {
|
|
4206
|
+
if (!meta) return false;
|
|
4207
|
+
if (meta.dynamicType && meta.dynamicType !== "STATIC") return true;
|
|
4208
|
+
if (meta.isChrome) return true;
|
|
4209
|
+
if (meta.isKitOrigin) return true;
|
|
4210
|
+
return false;
|
|
4211
|
+
}
|
|
4212
|
+
function collectSubtreeIds(rootId, projection) {
|
|
4213
|
+
const ids2 = /* @__PURE__ */ new Set([rootId]);
|
|
4214
|
+
const stack = [rootId];
|
|
4215
|
+
while (stack.length > 0) {
|
|
4216
|
+
const id = stack.pop();
|
|
4217
|
+
const node = projection.containerIndex.get(id);
|
|
4218
|
+
if (!node) continue;
|
|
4219
|
+
for (const childId of node.children) {
|
|
4220
|
+
if (ids2.has(childId)) continue;
|
|
4221
|
+
ids2.add(childId);
|
|
4222
|
+
stack.push(childId);
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
return ids2;
|
|
4226
|
+
}
|
|
4227
|
+
function computeDroppableSet(sourceId, projection, nodeMap) {
|
|
4228
|
+
const excluded = collectSubtreeIds(sourceId, projection);
|
|
4229
|
+
const droppable = /* @__PURE__ */ new Set();
|
|
4230
|
+
for (const containerId of projection.containerIndex.keys()) {
|
|
4231
|
+
if (excluded.has(containerId)) continue;
|
|
4232
|
+
if (isStructuralContainer(containerId, nodeMap)) continue;
|
|
4233
|
+
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) continue;
|
|
4234
|
+
droppable.add(containerId);
|
|
4235
|
+
}
|
|
4236
|
+
return droppable;
|
|
4237
|
+
}
|
|
4238
|
+
function buildBlockedNodeMetaContainerIds(projection, nodeMap) {
|
|
4239
|
+
const blocked = /* @__PURE__ */ new Set();
|
|
4240
|
+
for (const containerId of projection.containerIndex.keys()) {
|
|
4241
|
+
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) {
|
|
4242
|
+
blocked.add(containerId);
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
return blocked;
|
|
4246
|
+
}
|
|
4247
|
+
function resolveRefusalCode(meta, fallback) {
|
|
4248
|
+
return meta?.lockReason ?? fallback;
|
|
4249
|
+
}
|
|
4188
4250
|
function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainerId) {
|
|
4189
4251
|
const blocked = /* @__PURE__ */ new Set();
|
|
4190
4252
|
for (const containerId of projection.containerIndex.keys()) {
|
|
@@ -4194,6 +4256,9 @@ function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainer
|
|
|
4194
4256
|
return blocked;
|
|
4195
4257
|
}
|
|
4196
4258
|
|
|
4259
|
+
// src/client/dnd/design-mode/node-meta-guard.ts
|
|
4260
|
+
var VID_PATTERN = /^[a-z0-9]{6,8}$/;
|
|
4261
|
+
|
|
4197
4262
|
// src/client/dnd/design-mode/fiber-bridge.ts
|
|
4198
4263
|
var FIBER_KEY_PREFIX = "__reactFiber$";
|
|
4199
4264
|
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
@@ -4474,11 +4539,18 @@ function getNodeKeyFromElement(el) {
|
|
|
4474
4539
|
const resolved = resolveDragSurface(el);
|
|
4475
4540
|
const host = resolved.host ?? el;
|
|
4476
4541
|
const meta = identityMeta(host);
|
|
4542
|
+
if (meta?.vid) return meta.vid;
|
|
4543
|
+
const domVid = host.getAttribute("data-vid");
|
|
4544
|
+
if (domVid) return domVid;
|
|
4477
4545
|
if (meta) return meta.nodeId;
|
|
4478
4546
|
const persisted = host.getAttribute("data-dnd-node-id");
|
|
4479
4547
|
if (persisted) return persisted;
|
|
4480
4548
|
return getRuntimeKey(host);
|
|
4481
4549
|
}
|
|
4550
|
+
function resolveVidFromElement(el) {
|
|
4551
|
+
const key2 = getNodeKeyFromElement(el);
|
|
4552
|
+
return VID_PATTERN.test(key2) ? key2 : null;
|
|
4553
|
+
}
|
|
4482
4554
|
function getInspectorRefFromElement(el) {
|
|
4483
4555
|
const resolved = resolveDragSurface(el);
|
|
4484
4556
|
const host = resolved.host ?? el;
|
|
@@ -4805,6 +4877,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4805
4877
|
afterSibling,
|
|
4806
4878
|
diagnostics,
|
|
4807
4879
|
binding,
|
|
4880
|
+
targetVid,
|
|
4881
|
+
containerVid,
|
|
4808
4882
|
componentName,
|
|
4809
4883
|
before,
|
|
4810
4884
|
after
|
|
@@ -4832,6 +4906,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4832
4906
|
afterSibling: afterSibling ?? null,
|
|
4833
4907
|
diagnostics: diagnostics ?? null,
|
|
4834
4908
|
binding: binding ?? null,
|
|
4909
|
+
targetVid: targetVid ?? null,
|
|
4910
|
+
containerVid: containerVid ?? null,
|
|
4835
4911
|
payload: { before, after },
|
|
4836
4912
|
at: now
|
|
4837
4913
|
};
|
|
@@ -4860,6 +4936,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4860
4936
|
nodeId,
|
|
4861
4937
|
inspectorRef,
|
|
4862
4938
|
componentName,
|
|
4939
|
+
targetVid,
|
|
4863
4940
|
before,
|
|
4864
4941
|
after
|
|
4865
4942
|
}) => {
|
|
@@ -4871,6 +4948,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4871
4948
|
nodeKey,
|
|
4872
4949
|
nodeId,
|
|
4873
4950
|
inspectorRef,
|
|
4951
|
+
targetVid: targetVid ?? null,
|
|
4874
4952
|
payload: { before, after },
|
|
4875
4953
|
at: now
|
|
4876
4954
|
};
|
|
@@ -4904,6 +4982,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4904
4982
|
tsxImports,
|
|
4905
4983
|
containerId,
|
|
4906
4984
|
containerNodeKey,
|
|
4985
|
+
containerVid,
|
|
4986
|
+
insertedVid,
|
|
4907
4987
|
index,
|
|
4908
4988
|
beforeSiblingInspectorRef,
|
|
4909
4989
|
beforeSiblingNodeKey
|
|
@@ -4922,6 +5002,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4922
5002
|
tsxImports: tsxImports ?? null,
|
|
4923
5003
|
containerId,
|
|
4924
5004
|
containerNodeKey,
|
|
5005
|
+
containerVid: containerVid ?? null,
|
|
5006
|
+
insertedVid: insertedVid ?? null,
|
|
4925
5007
|
index,
|
|
4926
5008
|
beforeSiblingInspectorRef: beforeSiblingInspectorRef ?? null,
|
|
4927
5009
|
beforeSiblingNodeKey: beforeSiblingNodeKey ?? null,
|
|
@@ -5035,6 +5117,7 @@ function shouldShowGrabFeedback(target, scannedByNodeId) {
|
|
|
5035
5117
|
}
|
|
5036
5118
|
function isEligibleForDrag(sc) {
|
|
5037
5119
|
if (sc.draggable === false) return false;
|
|
5120
|
+
if (isNonDraggableNodeMeta(sc.editorMeta)) return false;
|
|
5038
5121
|
const source = sc.eligibilitySource ?? "editor-meta";
|
|
5039
5122
|
return source === "editor-meta" || source === "force-allow" || source === "inferred-sortable-descendant" || // RFC E2.4 P1: single host root of a kit-component usage (MetricCard,
|
|
5040
5123
|
// Section, …) carrying the usage's projected meta.
|
|
@@ -6657,6 +6740,15 @@ function serializeArrangeChange(event, index) {
|
|
|
6657
6740
|
diagnostics: event.kind === "move" ? event.diagnostics : void 0,
|
|
6658
6741
|
// ARCH-1065 D17 — which slice row this move addresses.
|
|
6659
6742
|
binding: event.kind === "move" ? event.binding : void 0,
|
|
6743
|
+
// `data-vid` identity migration (`host-bridge.ts`'s `RuntimeMoveDetail`
|
|
6744
|
+
// fields). `index` here is `event.payload.after.index` — the MOVE's own
|
|
6745
|
+
// JSX-child index — never the `index` PARAMETER above (this change's
|
|
6746
|
+
// sequence position in the session). `targetVid` also carries the
|
|
6747
|
+
// resized node's vid on a `resize` change; `containerVid` also carries
|
|
6748
|
+
// the drop container's vid on an `insert` change.
|
|
6749
|
+
targetVid: event.kind === "move" || event.kind === "resize" ? event.targetVid : void 0,
|
|
6750
|
+
containerVid: event.kind === "move" || event.kind === "insert" ? event.containerVid : void 0,
|
|
6751
|
+
index: event.kind === "move" ? event.payload.after.index : void 0,
|
|
6660
6752
|
// Insert-specific fields
|
|
6661
6753
|
displayName: event.kind === "insert" ? event.displayName : void 0,
|
|
6662
6754
|
html: event.kind === "insert" ? event.html : void 0,
|
|
@@ -6664,6 +6756,7 @@ function serializeArrangeChange(event, index) {
|
|
|
6664
6756
|
tsxImports: event.kind === "insert" ? event.tsxImports : void 0,
|
|
6665
6757
|
containerId: event.kind === "insert" ? event.containerId : void 0,
|
|
6666
6758
|
containerNodeKey: event.kind === "insert" ? event.containerNodeKey : void 0,
|
|
6759
|
+
insertedVid: event.kind === "insert" ? event.insertedVid : void 0,
|
|
6667
6760
|
insertIndex: event.kind === "insert" ? event.index : void 0,
|
|
6668
6761
|
beforeSiblingInspectorRef: event.kind === "insert" ? event.beforeSiblingInspectorRef : void 0,
|
|
6669
6762
|
beforeSiblingNodeKey: event.kind === "insert" ? event.beforeSiblingNodeKey : void 0,
|
|
@@ -6920,6 +7013,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6920
7013
|
const resolvedReorderRef = useRef8(null);
|
|
6921
7014
|
const finalVisualKeyRef = useRef8(null);
|
|
6922
7015
|
const dragStartPositionRef = useRef8(null);
|
|
7016
|
+
const droppableContainerIdsRef = useRef8(null);
|
|
6923
7017
|
const sourceCommitLaneRef = useRef8(null);
|
|
6924
7018
|
const commitLaneCacheRef = useRef8(/* @__PURE__ */ new Map());
|
|
6925
7019
|
const safeZoneRef = useRef8(null);
|
|
@@ -6951,6 +7045,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6951
7045
|
resolvedReorderRef,
|
|
6952
7046
|
finalVisualKeyRef,
|
|
6953
7047
|
dragStartPositionRef,
|
|
7048
|
+
droppableContainerIdsRef,
|
|
6954
7049
|
sourceCommitLaneRef,
|
|
6955
7050
|
commitLaneCacheRef,
|
|
6956
7051
|
safeZoneRef,
|
|
@@ -8152,6 +8247,14 @@ function useDragVisualLoop({
|
|
|
8152
8247
|
|
|
8153
8248
|
// src/client/dnd/design-mode/useDragLifecycle.ts
|
|
8154
8249
|
import { useState as useState5, useCallback as useCallback6 } from "react";
|
|
8250
|
+
function emitRefused(code, cause, element) {
|
|
8251
|
+
dispatchRuntimeEvent({
|
|
8252
|
+
type: "drag-refused",
|
|
8253
|
+
code,
|
|
8254
|
+
cause,
|
|
8255
|
+
vid: element ? resolveVidFromElement(element) : null
|
|
8256
|
+
});
|
|
8257
|
+
}
|
|
8155
8258
|
function resolveLaneAllowedContainers(anchorElement, srcContainerId) {
|
|
8156
8259
|
if (!srcContainerId) return null;
|
|
8157
8260
|
if (!resolveRowBinding(anchorElement)) return null;
|
|
@@ -8268,6 +8371,10 @@ function recordCommittedMove(args) {
|
|
|
8268
8371
|
});
|
|
8269
8372
|
const componentName = getEditorMeta(anchorEl)?.componentName;
|
|
8270
8373
|
const operationId = `${command.at}:${anchorNodeId}`;
|
|
8374
|
+
const targetVid = resolveVidFromElement(selectedEl);
|
|
8375
|
+
const targetContainerId = command.to.parentNodeId ?? command.to.laneContainerId;
|
|
8376
|
+
const targetContainerEl = targetContainerId ? resolveNodeElement(targetContainerId) : null;
|
|
8377
|
+
const containerVid = targetContainerEl ? resolveVidFromElement(targetContainerEl) : null;
|
|
8271
8378
|
const binding = resolveRowBinding(selectedEl);
|
|
8272
8379
|
const beforePayload = buildMovePayloadWithEffectiveIdentities({
|
|
8273
8380
|
placement: command.from,
|
|
@@ -8299,6 +8406,8 @@ function recordCommittedMove(args) {
|
|
|
8299
8406
|
sourceAfterSibling: sourceAfterSiblingIdentity,
|
|
8300
8407
|
diagnostics,
|
|
8301
8408
|
binding,
|
|
8409
|
+
targetVid,
|
|
8410
|
+
containerVid,
|
|
8302
8411
|
container: containerIdentity,
|
|
8303
8412
|
beforeSibling: beforeSiblingIdentity,
|
|
8304
8413
|
afterSibling: afterSiblingIdentity,
|
|
@@ -8310,6 +8419,9 @@ function recordCommittedMove(args) {
|
|
|
8310
8419
|
type: "element-moved",
|
|
8311
8420
|
operationId,
|
|
8312
8421
|
commandType: command.type,
|
|
8422
|
+
targetVid,
|
|
8423
|
+
containerVid,
|
|
8424
|
+
index: command.to.index,
|
|
8313
8425
|
selected: {
|
|
8314
8426
|
nodeId: selectedNodeId,
|
|
8315
8427
|
nodeKey: selectedNodeKey,
|
|
@@ -8372,6 +8484,7 @@ function useDragLifecycle({
|
|
|
8372
8484
|
refs.resolvedReorderRef.current = null;
|
|
8373
8485
|
refs.finalVisualKeyRef.current = null;
|
|
8374
8486
|
refs.dragStartPositionRef.current = null;
|
|
8487
|
+
refs.droppableContainerIdsRef.current = null;
|
|
8375
8488
|
clearCommitLaneCache();
|
|
8376
8489
|
refs.safeZoneRef.current = null;
|
|
8377
8490
|
setInsideRect(null);
|
|
@@ -8405,6 +8518,11 @@ function useDragLifecycle({
|
|
|
8405
8518
|
eligibilitySource: found.eligibilitySource ?? "editor-meta",
|
|
8406
8519
|
draggable: found.draggable
|
|
8407
8520
|
});
|
|
8521
|
+
emitRefused(
|
|
8522
|
+
resolveRefusalCode(found.editorMeta, "GATE_REJECT"),
|
|
8523
|
+
"Node is not draggable (dynamic render, chrome, or kit-origin).",
|
|
8524
|
+
found.element
|
|
8525
|
+
);
|
|
8408
8526
|
return;
|
|
8409
8527
|
}
|
|
8410
8528
|
veTrace("dnd", "drag:start", {
|
|
@@ -8428,12 +8546,29 @@ function useDragLifecycle({
|
|
|
8428
8546
|
clearCommitLaneCache();
|
|
8429
8547
|
const anchor = resolveDragAnchor(activeId, proj, refs.nodeMapRef.current);
|
|
8430
8548
|
const anchorScanned = refs.nodeMapRef.current.get(anchor.anchorNodeId) ?? found;
|
|
8431
|
-
if (!anchorScanned || !isEligibleForDrag(anchorScanned))
|
|
8549
|
+
if (!anchorScanned || !isEligibleForDrag(anchorScanned)) {
|
|
8550
|
+
emitRefused(
|
|
8551
|
+
resolveRefusalCode(anchorScanned?.editorMeta, "GATE_REJECT"),
|
|
8552
|
+
"Resolved drag anchor is not draggable.",
|
|
8553
|
+
anchorScanned?.element ?? found.element
|
|
8554
|
+
);
|
|
8555
|
+
return;
|
|
8556
|
+
}
|
|
8432
8557
|
const anchorNodeId = anchor.anchorNodeId;
|
|
8433
8558
|
const srcContainerId = anchor.sourceContainerId;
|
|
8434
8559
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8435
8560
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8436
8561
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8562
|
+
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current)) {
|
|
8563
|
+
blockedContainerIds.add(id);
|
|
8564
|
+
}
|
|
8565
|
+
const droppableSet = computeDroppableSet(anchorNodeId, proj, refs.nodeMapRef.current);
|
|
8566
|
+
refs.droppableContainerIdsRef.current = droppableSet;
|
|
8567
|
+
dispatchRuntimeEvent({
|
|
8568
|
+
type: "drag-started",
|
|
8569
|
+
targetVid: resolveVidFromElement(anchorScanned.element),
|
|
8570
|
+
droppable: Array.from(droppableSet)
|
|
8571
|
+
});
|
|
8437
8572
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8438
8573
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8439
8574
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8506,6 +8641,19 @@ function useDragLifecycle({
|
|
|
8506
8641
|
syncHistoryAvailability();
|
|
8507
8642
|
return;
|
|
8508
8643
|
}
|
|
8644
|
+
if (dropTargetId && !refs.droppableContainerIdsRef.current?.has(dropTargetId)) {
|
|
8645
|
+
const targetContainerEl = resolveNodeElement(dropTargetId);
|
|
8646
|
+
const targetMeta = refs.nodeMapRef.current.get(dropTargetId)?.editorMeta;
|
|
8647
|
+
const fallbackCode = targetMeta?.containerKind === "expression" ? "EXPRESSION_CONTAINER" : "CONTAINER_NOT_PLAIN";
|
|
8648
|
+
emitRefused(
|
|
8649
|
+
resolveRefusalCode(targetMeta, fallbackCode),
|
|
8650
|
+
"Drop target is outside the droppable set for this node.",
|
|
8651
|
+
targetContainerEl
|
|
8652
|
+
);
|
|
8653
|
+
clearDragState();
|
|
8654
|
+
syncHistoryAvailability();
|
|
8655
|
+
return;
|
|
8656
|
+
}
|
|
8509
8657
|
let command = null;
|
|
8510
8658
|
if (nestTarget) {
|
|
8511
8659
|
if (!activeEl.contains(nestTarget.element) && !nestTarget.element.contains(activeEl) && sourcePos?.commitNodeId) {
|
|
@@ -8717,6 +8865,7 @@ function useResizeSession({
|
|
|
8717
8865
|
return;
|
|
8718
8866
|
}
|
|
8719
8867
|
const inspectorRef = getInspectorRefFromElement(element);
|
|
8868
|
+
const targetVid = resolveVidFromElement(element);
|
|
8720
8869
|
const resizeCmd = {
|
|
8721
8870
|
type: "resize",
|
|
8722
8871
|
mode,
|
|
@@ -8736,12 +8885,14 @@ function useResizeSession({
|
|
|
8736
8885
|
nodeId: selectedNodeId,
|
|
8737
8886
|
inspectorRef,
|
|
8738
8887
|
componentName: getEditorMeta(element)?.componentName,
|
|
8888
|
+
targetVid,
|
|
8739
8889
|
before: { mode, selectedNodeKey, targetNodeKey, targetNodeId, width: resizeCmd.before.width, height: resizeCmd.before.height, colSpan: resizeCmd.before.colSpan, rowSpan: resizeCmd.before.rowSpan, styleDiff: { before: beforeStyles, after: afterStyles } },
|
|
8740
8890
|
after: { mode, selectedNodeKey, targetNodeKey, targetNodeId, width: resizeCmd.after.width, height: resizeCmd.after.height, colSpan: resizeCmd.after.colSpan, rowSpan: resizeCmd.after.rowSpan, styleDiff: { before: beforeStyles, after: afterStyles } }
|
|
8741
8891
|
});
|
|
8742
8892
|
dispatchRuntimeEvent({
|
|
8743
8893
|
type: "element-resized",
|
|
8744
8894
|
operationId,
|
|
8895
|
+
targetVid,
|
|
8745
8896
|
selected: {
|
|
8746
8897
|
nodeId: selectedNodeId,
|
|
8747
8898
|
nodeKey: selectedNodeKey,
|
|
@@ -8964,6 +9115,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8964
9115
|
};
|
|
8965
9116
|
}
|
|
8966
9117
|
const operationId = `${insertCommand.at}:${nodeId}`;
|
|
9118
|
+
const containerVid = containerEl ? resolveVidFromElement(containerEl) : null;
|
|
9119
|
+
const insertedVid = resolveVidFromElement(newElement);
|
|
8967
9120
|
useDesignModeStore.getState().recordInsertChange({
|
|
8968
9121
|
operationId,
|
|
8969
9122
|
nodeKey,
|
|
@@ -8975,6 +9128,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8975
9128
|
tsxImports: component.tsxImports ?? null,
|
|
8976
9129
|
containerId: intent.containerId,
|
|
8977
9130
|
containerNodeKey,
|
|
9131
|
+
containerVid,
|
|
9132
|
+
insertedVid,
|
|
8978
9133
|
index: intent.index,
|
|
8979
9134
|
beforeSiblingInspectorRef: beforeSiblingIdentity?.inspectorRef ?? null,
|
|
8980
9135
|
beforeSiblingNodeKey: beforeSiblingIdentity?.nodeKey ?? null
|
|
@@ -8989,6 +9144,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8989
9144
|
tsxCode: component.tsxCode ?? null,
|
|
8990
9145
|
tsxImports: component.tsxImports ?? null,
|
|
8991
9146
|
container: containerIdentity,
|
|
9147
|
+
containerVid,
|
|
9148
|
+
insertedVid,
|
|
8992
9149
|
index: intent.index,
|
|
8993
9150
|
beforeSibling: beforeSiblingIdentity
|
|
8994
9151
|
});
|
|
@@ -26,6 +26,7 @@ module.exports = __toCommonJS(babel_plugin_collection_binding_exports);
|
|
|
26
26
|
var import_types = require("@babel/types");
|
|
27
27
|
|
|
28
28
|
// src/babel-plugin-editor-meta.ts
|
|
29
|
+
var import_editor_protocol = require("@8base-archie/editor-protocol");
|
|
29
30
|
function meaningfulChildren(t, children) {
|
|
30
31
|
return children.filter((child) => {
|
|
31
32
|
if (t.isJSXText(child)) return child.value.trim() !== "";
|
package/dist/index.d.mts
CHANGED
|
@@ -16,6 +16,13 @@ import { types, PluginObj } from '@babel/core';
|
|
|
16
16
|
* + (ARCH-1450) childrenSource, propSources — same-file identifier tracing
|
|
17
17
|
* for values `propBindings` cannot reach (no destructured-prop component
|
|
18
18
|
* in scope, or a value that never touches a prop at all)
|
|
19
|
+
* + (data-vid identity migration) vid, isKitOrigin, dynamicType, isChrome,
|
|
20
|
+
* containerKind, lockReason — read from a `data-vid` attribute (stamped
|
|
21
|
+
* into persisted source by the Genesis stamper) plus the `NodeMeta`
|
|
22
|
+
* contract fields (`@8base-archie/editor-protocol`) computed from the
|
|
23
|
+
* element's own JSX/function ancestry. `nodeId === vid` when `data-vid`
|
|
24
|
+
* is present; `allowLegacyIds` (default `true`, transitional) governs
|
|
25
|
+
* what happens when it is not — see `EditorMetaPluginOptions` below.
|
|
19
26
|
*
|
|
20
27
|
* At runtime the Fiber bridge reads `memoizedProps.__editorMeta` to resolve
|
|
21
28
|
* element identity without any DOM attributes.
|
|
@@ -136,6 +143,28 @@ interface EditorMetaPluginOptions {
|
|
|
136
143
|
* @default false
|
|
137
144
|
*/
|
|
138
145
|
templateOrigin?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* `data-vid` identity migration (vid-identity, decision binding). When a
|
|
148
|
+
* `JSXOpeningElement` carries a well-formed `data-vid` attribute
|
|
149
|
+
* (`VID_PATTERN`, `/^[a-z0-9]{6,8}$/`, stamped into persisted source by
|
|
150
|
+
* the Genesis stamper — see `@8base-archie/editor-protocol`'s
|
|
151
|
+
* `src/ids.ts`), the plugin ALWAYS reads it and uses it as `nodeId`
|
|
152
|
+
* (`meta.vid` is also emitted). This option only controls what happens
|
|
153
|
+
* when NO `data-vid` is present:
|
|
154
|
+
*
|
|
155
|
+
* - `true` (default in this version — TRANSITIONAL, to be removed once
|
|
156
|
+
* every source tree is stamped) — fall back to the legacy
|
|
157
|
+
* `"file:line:col:componentName"` addressing, exactly as before this
|
|
158
|
+
* change.
|
|
159
|
+
* - `false` — an element with no `data-vid` is NOT instrumented at all
|
|
160
|
+
* (no `__editorMeta` is emitted for it): a stable identity contract
|
|
161
|
+
* cannot be met by an addressing scheme that invalidates on every
|
|
162
|
+
* source write, so the plugin declines rather than silently hand out
|
|
163
|
+
* one.
|
|
164
|
+
*
|
|
165
|
+
* @default true
|
|
166
|
+
*/
|
|
167
|
+
allowLegacyIds?: boolean;
|
|
139
168
|
}
|
|
140
169
|
declare function babelPluginEditorMeta({ types: t }: {
|
|
141
170
|
types: typeof types;
|
|
@@ -347,10 +376,27 @@ type PropSource = {
|
|
|
347
376
|
} | {
|
|
348
377
|
kind: 'other';
|
|
349
378
|
};
|
|
379
|
+
|
|
350
380
|
/** Metadata injected into every JSX element by babel-plugin-editor-meta. */
|
|
351
381
|
interface EditorMeta {
|
|
352
|
-
/**
|
|
382
|
+
/**
|
|
383
|
+
* Stable identifier for this node. `vid` identity (see below) is the
|
|
384
|
+
* canonical shape going forward: when the persisted source carries a
|
|
385
|
+
* `data-vid` attribute, `nodeId === vid`. Absent a `data-vid` (a bundle
|
|
386
|
+
* built with `allowLegacyIds: true`, the plugin's transitional default),
|
|
387
|
+
* this falls back to the legacy `"file:line:col:componentName"` shape,
|
|
388
|
+
* which invalidates on every write to the source.
|
|
389
|
+
*/
|
|
353
390
|
nodeId: string;
|
|
391
|
+
/**
|
|
392
|
+
* `data-vid` identity (vid-identity migration) — present only when the
|
|
393
|
+
* source element carried a well-formed `data-vid` attribute
|
|
394
|
+
* (`VID_PATTERN`, `/^[a-z0-9]{6,8}$/`). Stamped into PERSISTED source by
|
|
395
|
+
* the Genesis stamper, NOT computed here — the plugin only reads it.
|
|
396
|
+
* Absent on a node with no `data-vid` (legacy addressing) and on every
|
|
397
|
+
* bundle built before this change.
|
|
398
|
+
*/
|
|
399
|
+
vid?: string;
|
|
354
400
|
/** Relative file path from project root. */
|
|
355
401
|
file: string;
|
|
356
402
|
line: number;
|
|
@@ -553,6 +599,51 @@ interface EditorMeta {
|
|
|
553
599
|
* already says). Absent on every bundle built before ARCH-1450.
|
|
554
600
|
*/
|
|
555
601
|
propSources?: Record<string, PropSource>;
|
|
602
|
+
/**
|
|
603
|
+
* `NodeMeta` fields (vid-identity migration, `@8base-archie/editor-protocol`
|
|
604
|
+
* contract). Emitted only alongside `vid` (a legacy, `data-vid`-less node
|
|
605
|
+
* has no NodeMeta to report) — read via `fiber-bridge.ts`'s `getNodeMeta`,
|
|
606
|
+
* which validates the assembled `NodeMeta` object with `NodeMetaSchema`
|
|
607
|
+
* rather than trusting these fields individually.
|
|
608
|
+
*
|
|
609
|
+
* `isKitOrigin` restates the existing `origin === 'kit'` fact as a plain
|
|
610
|
+
* boolean (the `NodeMeta` contract's shape) — `origin` itself is
|
|
611
|
+
* unchanged and stays the field every existing consumer already reads.
|
|
612
|
+
*/
|
|
613
|
+
isKitOrigin?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Whether this node renders under a `.map`/`forEach`/`flatMap` callback
|
|
616
|
+
* (`'ARRAY'`), under a `ConditionalExpression`/`LogicalExpression` inside a
|
|
617
|
+
* `JSXExpressionContainer` (`'CONDITIONAL'`), or neither (`'STATIC'`).
|
|
618
|
+
* Computed at compile time by walking JSX/function ancestors — see
|
|
619
|
+
* `computeDynamicType` in `babel-plugin-editor-meta.ts` for the exact walk
|
|
620
|
+
* and its stopping rule at the first non-qualifying function boundary.
|
|
621
|
+
*/
|
|
622
|
+
dynamicType?: 'STATIC' | 'ARRAY' | 'CONDITIONAL';
|
|
623
|
+
/**
|
|
624
|
+
* True for a node inside `shell.jsx`, `components/shell/**`, or with a
|
|
625
|
+
* `nav`/`aside`/`header` ancestor in the same file — the app shell/chrome
|
|
626
|
+
* region, structurally locked against drag/drop regardless of
|
|
627
|
+
* `isKitOrigin`. See `computeIsChrome` in `babel-plugin-editor-meta.ts`.
|
|
628
|
+
*/
|
|
629
|
+
isChrome?: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Shape of this element's JSX children for drop-target purposes: `'plain'`
|
|
632
|
+
* when every child is a `JSXElement` or whitespace-trimmed `JSXText`,
|
|
633
|
+
* `'expression'` when any child is a `JSXExpressionContainer`/spread/
|
|
634
|
+
* iteration, `'none'` when the element has no element children (including
|
|
635
|
+
* self-closing). See `computeContainerKind` in `babel-plugin-editor-meta.ts`.
|
|
636
|
+
*/
|
|
637
|
+
containerKind?: 'plain' | 'expression' | 'none';
|
|
638
|
+
/**
|
|
639
|
+
* Derived refusal reason, in priority order: `KIT_INTERNAL` (kit-origin) >
|
|
640
|
+
* `CHROME_STRUCTURAL` (shell/chrome) > `DYNAMIC_ARRAY`/`DYNAMIC_CONDITIONAL`
|
|
641
|
+
* (dynamic rendering shape) > `EXPRESSION_CONTAINER` (only relevant when
|
|
642
|
+
* this node is considered as a DROP TARGET, i.e. `containerKind ===
|
|
643
|
+
* 'expression'`). Absent when none of these apply — the node is a normal,
|
|
644
|
+
* writable, static, non-chrome, non-kit element.
|
|
645
|
+
*/
|
|
646
|
+
lockReason?: 'KIT_INTERNAL' | 'DYNAMIC_ARRAY' | 'DYNAMIC_CONDITIONAL' | 'CHROME_STRUCTURAL' | 'EXPRESSION_CONTAINER';
|
|
556
647
|
}
|
|
557
648
|
|
|
558
649
|
interface ArchieDevToolsOptions {
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,13 @@ import { types, PluginObj } from '@babel/core';
|
|
|
16
16
|
* + (ARCH-1450) childrenSource, propSources — same-file identifier tracing
|
|
17
17
|
* for values `propBindings` cannot reach (no destructured-prop component
|
|
18
18
|
* in scope, or a value that never touches a prop at all)
|
|
19
|
+
* + (data-vid identity migration) vid, isKitOrigin, dynamicType, isChrome,
|
|
20
|
+
* containerKind, lockReason — read from a `data-vid` attribute (stamped
|
|
21
|
+
* into persisted source by the Genesis stamper) plus the `NodeMeta`
|
|
22
|
+
* contract fields (`@8base-archie/editor-protocol`) computed from the
|
|
23
|
+
* element's own JSX/function ancestry. `nodeId === vid` when `data-vid`
|
|
24
|
+
* is present; `allowLegacyIds` (default `true`, transitional) governs
|
|
25
|
+
* what happens when it is not — see `EditorMetaPluginOptions` below.
|
|
19
26
|
*
|
|
20
27
|
* At runtime the Fiber bridge reads `memoizedProps.__editorMeta` to resolve
|
|
21
28
|
* element identity without any DOM attributes.
|
|
@@ -136,6 +143,28 @@ interface EditorMetaPluginOptions {
|
|
|
136
143
|
* @default false
|
|
137
144
|
*/
|
|
138
145
|
templateOrigin?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* `data-vid` identity migration (vid-identity, decision binding). When a
|
|
148
|
+
* `JSXOpeningElement` carries a well-formed `data-vid` attribute
|
|
149
|
+
* (`VID_PATTERN`, `/^[a-z0-9]{6,8}$/`, stamped into persisted source by
|
|
150
|
+
* the Genesis stamper — see `@8base-archie/editor-protocol`'s
|
|
151
|
+
* `src/ids.ts`), the plugin ALWAYS reads it and uses it as `nodeId`
|
|
152
|
+
* (`meta.vid` is also emitted). This option only controls what happens
|
|
153
|
+
* when NO `data-vid` is present:
|
|
154
|
+
*
|
|
155
|
+
* - `true` (default in this version — TRANSITIONAL, to be removed once
|
|
156
|
+
* every source tree is stamped) — fall back to the legacy
|
|
157
|
+
* `"file:line:col:componentName"` addressing, exactly as before this
|
|
158
|
+
* change.
|
|
159
|
+
* - `false` — an element with no `data-vid` is NOT instrumented at all
|
|
160
|
+
* (no `__editorMeta` is emitted for it): a stable identity contract
|
|
161
|
+
* cannot be met by an addressing scheme that invalidates on every
|
|
162
|
+
* source write, so the plugin declines rather than silently hand out
|
|
163
|
+
* one.
|
|
164
|
+
*
|
|
165
|
+
* @default true
|
|
166
|
+
*/
|
|
167
|
+
allowLegacyIds?: boolean;
|
|
139
168
|
}
|
|
140
169
|
declare function babelPluginEditorMeta({ types: t }: {
|
|
141
170
|
types: typeof types;
|
|
@@ -347,10 +376,27 @@ type PropSource = {
|
|
|
347
376
|
} | {
|
|
348
377
|
kind: 'other';
|
|
349
378
|
};
|
|
379
|
+
|
|
350
380
|
/** Metadata injected into every JSX element by babel-plugin-editor-meta. */
|
|
351
381
|
interface EditorMeta {
|
|
352
|
-
/**
|
|
382
|
+
/**
|
|
383
|
+
* Stable identifier for this node. `vid` identity (see below) is the
|
|
384
|
+
* canonical shape going forward: when the persisted source carries a
|
|
385
|
+
* `data-vid` attribute, `nodeId === vid`. Absent a `data-vid` (a bundle
|
|
386
|
+
* built with `allowLegacyIds: true`, the plugin's transitional default),
|
|
387
|
+
* this falls back to the legacy `"file:line:col:componentName"` shape,
|
|
388
|
+
* which invalidates on every write to the source.
|
|
389
|
+
*/
|
|
353
390
|
nodeId: string;
|
|
391
|
+
/**
|
|
392
|
+
* `data-vid` identity (vid-identity migration) — present only when the
|
|
393
|
+
* source element carried a well-formed `data-vid` attribute
|
|
394
|
+
* (`VID_PATTERN`, `/^[a-z0-9]{6,8}$/`). Stamped into PERSISTED source by
|
|
395
|
+
* the Genesis stamper, NOT computed here — the plugin only reads it.
|
|
396
|
+
* Absent on a node with no `data-vid` (legacy addressing) and on every
|
|
397
|
+
* bundle built before this change.
|
|
398
|
+
*/
|
|
399
|
+
vid?: string;
|
|
354
400
|
/** Relative file path from project root. */
|
|
355
401
|
file: string;
|
|
356
402
|
line: number;
|
|
@@ -553,6 +599,51 @@ interface EditorMeta {
|
|
|
553
599
|
* already says). Absent on every bundle built before ARCH-1450.
|
|
554
600
|
*/
|
|
555
601
|
propSources?: Record<string, PropSource>;
|
|
602
|
+
/**
|
|
603
|
+
* `NodeMeta` fields (vid-identity migration, `@8base-archie/editor-protocol`
|
|
604
|
+
* contract). Emitted only alongside `vid` (a legacy, `data-vid`-less node
|
|
605
|
+
* has no NodeMeta to report) — read via `fiber-bridge.ts`'s `getNodeMeta`,
|
|
606
|
+
* which validates the assembled `NodeMeta` object with `NodeMetaSchema`
|
|
607
|
+
* rather than trusting these fields individually.
|
|
608
|
+
*
|
|
609
|
+
* `isKitOrigin` restates the existing `origin === 'kit'` fact as a plain
|
|
610
|
+
* boolean (the `NodeMeta` contract's shape) — `origin` itself is
|
|
611
|
+
* unchanged and stays the field every existing consumer already reads.
|
|
612
|
+
*/
|
|
613
|
+
isKitOrigin?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Whether this node renders under a `.map`/`forEach`/`flatMap` callback
|
|
616
|
+
* (`'ARRAY'`), under a `ConditionalExpression`/`LogicalExpression` inside a
|
|
617
|
+
* `JSXExpressionContainer` (`'CONDITIONAL'`), or neither (`'STATIC'`).
|
|
618
|
+
* Computed at compile time by walking JSX/function ancestors — see
|
|
619
|
+
* `computeDynamicType` in `babel-plugin-editor-meta.ts` for the exact walk
|
|
620
|
+
* and its stopping rule at the first non-qualifying function boundary.
|
|
621
|
+
*/
|
|
622
|
+
dynamicType?: 'STATIC' | 'ARRAY' | 'CONDITIONAL';
|
|
623
|
+
/**
|
|
624
|
+
* True for a node inside `shell.jsx`, `components/shell/**`, or with a
|
|
625
|
+
* `nav`/`aside`/`header` ancestor in the same file — the app shell/chrome
|
|
626
|
+
* region, structurally locked against drag/drop regardless of
|
|
627
|
+
* `isKitOrigin`. See `computeIsChrome` in `babel-plugin-editor-meta.ts`.
|
|
628
|
+
*/
|
|
629
|
+
isChrome?: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Shape of this element's JSX children for drop-target purposes: `'plain'`
|
|
632
|
+
* when every child is a `JSXElement` or whitespace-trimmed `JSXText`,
|
|
633
|
+
* `'expression'` when any child is a `JSXExpressionContainer`/spread/
|
|
634
|
+
* iteration, `'none'` when the element has no element children (including
|
|
635
|
+
* self-closing). See `computeContainerKind` in `babel-plugin-editor-meta.ts`.
|
|
636
|
+
*/
|
|
637
|
+
containerKind?: 'plain' | 'expression' | 'none';
|
|
638
|
+
/**
|
|
639
|
+
* Derived refusal reason, in priority order: `KIT_INTERNAL` (kit-origin) >
|
|
640
|
+
* `CHROME_STRUCTURAL` (shell/chrome) > `DYNAMIC_ARRAY`/`DYNAMIC_CONDITIONAL`
|
|
641
|
+
* (dynamic rendering shape) > `EXPRESSION_CONTAINER` (only relevant when
|
|
642
|
+
* this node is considered as a DROP TARGET, i.e. `containerKind ===
|
|
643
|
+
* 'expression'`). Absent when none of these apply — the node is a normal,
|
|
644
|
+
* writable, static, non-chrome, non-kit element.
|
|
645
|
+
*/
|
|
646
|
+
lockReason?: 'KIT_INTERNAL' | 'DYNAMIC_ARRAY' | 'DYNAMIC_CONDITIONAL' | 'CHROME_STRUCTURAL' | 'EXPRESSION_CONTAINER';
|
|
556
647
|
}
|
|
557
648
|
|
|
558
649
|
interface ArchieDevToolsOptions {
|