@archie/devtools 0.0.48 → 0.1.0
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 +160 -2
- package/dist/client/client.mjs +160 -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 +4 -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()) {
|
|
@@ -4195,6 +4257,7 @@ function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainer
|
|
|
4195
4257
|
}
|
|
4196
4258
|
|
|
4197
4259
|
// src/client/dnd/design-mode/fiber-bridge.ts
|
|
4260
|
+
import { NodeMetaSchema } from "@8base-archie/editor-protocol";
|
|
4198
4261
|
var FIBER_KEY_PREFIX = "__reactFiber$";
|
|
4199
4262
|
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
4200
4263
|
var metaCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4457,6 +4520,9 @@ function resolveDragSurface(el) {
|
|
|
4457
4520
|
};
|
|
4458
4521
|
}
|
|
4459
4522
|
|
|
4523
|
+
// src/types/editor-meta.ts
|
|
4524
|
+
import { VID_PATTERN, VID_ATTR } from "@8base-archie/editor-protocol";
|
|
4525
|
+
|
|
4460
4526
|
// src/client/dnd/design-mode/node-key.ts
|
|
4461
4527
|
var _runtimeKeyMap = /* @__PURE__ */ new WeakMap();
|
|
4462
4528
|
var _runtimeKeyCounter = 0;
|
|
@@ -4474,11 +4540,18 @@ function getNodeKeyFromElement(el) {
|
|
|
4474
4540
|
const resolved = resolveDragSurface(el);
|
|
4475
4541
|
const host = resolved.host ?? el;
|
|
4476
4542
|
const meta = identityMeta(host);
|
|
4543
|
+
if (meta?.vid) return meta.vid;
|
|
4544
|
+
const domVid = host.getAttribute("data-vid");
|
|
4545
|
+
if (domVid) return domVid;
|
|
4477
4546
|
if (meta) return meta.nodeId;
|
|
4478
4547
|
const persisted = host.getAttribute("data-dnd-node-id");
|
|
4479
4548
|
if (persisted) return persisted;
|
|
4480
4549
|
return getRuntimeKey(host);
|
|
4481
4550
|
}
|
|
4551
|
+
function resolveVidFromElement(el) {
|
|
4552
|
+
const key2 = getNodeKeyFromElement(el);
|
|
4553
|
+
return VID_PATTERN.test(key2) ? key2 : null;
|
|
4554
|
+
}
|
|
4482
4555
|
function getInspectorRefFromElement(el) {
|
|
4483
4556
|
const resolved = resolveDragSurface(el);
|
|
4484
4557
|
const host = resolved.host ?? el;
|
|
@@ -4805,6 +4878,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4805
4878
|
afterSibling,
|
|
4806
4879
|
diagnostics,
|
|
4807
4880
|
binding,
|
|
4881
|
+
targetVid,
|
|
4882
|
+
containerVid,
|
|
4808
4883
|
componentName,
|
|
4809
4884
|
before,
|
|
4810
4885
|
after
|
|
@@ -4832,6 +4907,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4832
4907
|
afterSibling: afterSibling ?? null,
|
|
4833
4908
|
diagnostics: diagnostics ?? null,
|
|
4834
4909
|
binding: binding ?? null,
|
|
4910
|
+
targetVid: targetVid ?? null,
|
|
4911
|
+
containerVid: containerVid ?? null,
|
|
4835
4912
|
payload: { before, after },
|
|
4836
4913
|
at: now
|
|
4837
4914
|
};
|
|
@@ -4860,6 +4937,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4860
4937
|
nodeId,
|
|
4861
4938
|
inspectorRef,
|
|
4862
4939
|
componentName,
|
|
4940
|
+
targetVid,
|
|
4863
4941
|
before,
|
|
4864
4942
|
after
|
|
4865
4943
|
}) => {
|
|
@@ -4871,6 +4949,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4871
4949
|
nodeKey,
|
|
4872
4950
|
nodeId,
|
|
4873
4951
|
inspectorRef,
|
|
4952
|
+
targetVid: targetVid ?? null,
|
|
4874
4953
|
payload: { before, after },
|
|
4875
4954
|
at: now
|
|
4876
4955
|
};
|
|
@@ -4904,6 +4983,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4904
4983
|
tsxImports,
|
|
4905
4984
|
containerId,
|
|
4906
4985
|
containerNodeKey,
|
|
4986
|
+
containerVid,
|
|
4987
|
+
insertedVid,
|
|
4907
4988
|
index,
|
|
4908
4989
|
beforeSiblingInspectorRef,
|
|
4909
4990
|
beforeSiblingNodeKey
|
|
@@ -4922,6 +5003,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4922
5003
|
tsxImports: tsxImports ?? null,
|
|
4923
5004
|
containerId,
|
|
4924
5005
|
containerNodeKey,
|
|
5006
|
+
containerVid: containerVid ?? null,
|
|
5007
|
+
insertedVid: insertedVid ?? null,
|
|
4925
5008
|
index,
|
|
4926
5009
|
beforeSiblingInspectorRef: beforeSiblingInspectorRef ?? null,
|
|
4927
5010
|
beforeSiblingNodeKey: beforeSiblingNodeKey ?? null,
|
|
@@ -5035,6 +5118,7 @@ function shouldShowGrabFeedback(target, scannedByNodeId) {
|
|
|
5035
5118
|
}
|
|
5036
5119
|
function isEligibleForDrag(sc) {
|
|
5037
5120
|
if (sc.draggable === false) return false;
|
|
5121
|
+
if (isNonDraggableNodeMeta(sc.editorMeta)) return false;
|
|
5038
5122
|
const source = sc.eligibilitySource ?? "editor-meta";
|
|
5039
5123
|
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
5124
|
// Section, …) carrying the usage's projected meta.
|
|
@@ -6657,6 +6741,15 @@ function serializeArrangeChange(event, index) {
|
|
|
6657
6741
|
diagnostics: event.kind === "move" ? event.diagnostics : void 0,
|
|
6658
6742
|
// ARCH-1065 D17 — which slice row this move addresses.
|
|
6659
6743
|
binding: event.kind === "move" ? event.binding : void 0,
|
|
6744
|
+
// `data-vid` identity migration (`host-bridge.ts`'s `RuntimeMoveDetail`
|
|
6745
|
+
// fields). `index` here is `event.payload.after.index` — the MOVE's own
|
|
6746
|
+
// JSX-child index — never the `index` PARAMETER above (this change's
|
|
6747
|
+
// sequence position in the session). `targetVid` also carries the
|
|
6748
|
+
// resized node's vid on a `resize` change; `containerVid` also carries
|
|
6749
|
+
// the drop container's vid on an `insert` change.
|
|
6750
|
+
targetVid: event.kind === "move" || event.kind === "resize" ? event.targetVid : void 0,
|
|
6751
|
+
containerVid: event.kind === "move" || event.kind === "insert" ? event.containerVid : void 0,
|
|
6752
|
+
index: event.kind === "move" ? event.payload.after.index : void 0,
|
|
6660
6753
|
// Insert-specific fields
|
|
6661
6754
|
displayName: event.kind === "insert" ? event.displayName : void 0,
|
|
6662
6755
|
html: event.kind === "insert" ? event.html : void 0,
|
|
@@ -6664,6 +6757,7 @@ function serializeArrangeChange(event, index) {
|
|
|
6664
6757
|
tsxImports: event.kind === "insert" ? event.tsxImports : void 0,
|
|
6665
6758
|
containerId: event.kind === "insert" ? event.containerId : void 0,
|
|
6666
6759
|
containerNodeKey: event.kind === "insert" ? event.containerNodeKey : void 0,
|
|
6760
|
+
insertedVid: event.kind === "insert" ? event.insertedVid : void 0,
|
|
6667
6761
|
insertIndex: event.kind === "insert" ? event.index : void 0,
|
|
6668
6762
|
beforeSiblingInspectorRef: event.kind === "insert" ? event.beforeSiblingInspectorRef : void 0,
|
|
6669
6763
|
beforeSiblingNodeKey: event.kind === "insert" ? event.beforeSiblingNodeKey : void 0,
|
|
@@ -6920,6 +7014,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6920
7014
|
const resolvedReorderRef = useRef8(null);
|
|
6921
7015
|
const finalVisualKeyRef = useRef8(null);
|
|
6922
7016
|
const dragStartPositionRef = useRef8(null);
|
|
7017
|
+
const droppableContainerIdsRef = useRef8(null);
|
|
6923
7018
|
const sourceCommitLaneRef = useRef8(null);
|
|
6924
7019
|
const commitLaneCacheRef = useRef8(/* @__PURE__ */ new Map());
|
|
6925
7020
|
const safeZoneRef = useRef8(null);
|
|
@@ -6951,6 +7046,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6951
7046
|
resolvedReorderRef,
|
|
6952
7047
|
finalVisualKeyRef,
|
|
6953
7048
|
dragStartPositionRef,
|
|
7049
|
+
droppableContainerIdsRef,
|
|
6954
7050
|
sourceCommitLaneRef,
|
|
6955
7051
|
commitLaneCacheRef,
|
|
6956
7052
|
safeZoneRef,
|
|
@@ -8152,6 +8248,14 @@ function useDragVisualLoop({
|
|
|
8152
8248
|
|
|
8153
8249
|
// src/client/dnd/design-mode/useDragLifecycle.ts
|
|
8154
8250
|
import { useState as useState5, useCallback as useCallback6 } from "react";
|
|
8251
|
+
function emitRefused(code, cause, element) {
|
|
8252
|
+
dispatchRuntimeEvent({
|
|
8253
|
+
type: "drag-refused",
|
|
8254
|
+
code,
|
|
8255
|
+
cause,
|
|
8256
|
+
vid: element ? resolveVidFromElement(element) : null
|
|
8257
|
+
});
|
|
8258
|
+
}
|
|
8155
8259
|
function resolveLaneAllowedContainers(anchorElement, srcContainerId) {
|
|
8156
8260
|
if (!srcContainerId) return null;
|
|
8157
8261
|
if (!resolveRowBinding(anchorElement)) return null;
|
|
@@ -8268,6 +8372,10 @@ function recordCommittedMove(args) {
|
|
|
8268
8372
|
});
|
|
8269
8373
|
const componentName = getEditorMeta(anchorEl)?.componentName;
|
|
8270
8374
|
const operationId = `${command.at}:${anchorNodeId}`;
|
|
8375
|
+
const targetVid = resolveVidFromElement(selectedEl);
|
|
8376
|
+
const targetContainerId = command.to.parentNodeId ?? command.to.laneContainerId;
|
|
8377
|
+
const targetContainerEl = targetContainerId ? resolveNodeElement(targetContainerId) : null;
|
|
8378
|
+
const containerVid = targetContainerEl ? resolveVidFromElement(targetContainerEl) : null;
|
|
8271
8379
|
const binding = resolveRowBinding(selectedEl);
|
|
8272
8380
|
const beforePayload = buildMovePayloadWithEffectiveIdentities({
|
|
8273
8381
|
placement: command.from,
|
|
@@ -8299,6 +8407,8 @@ function recordCommittedMove(args) {
|
|
|
8299
8407
|
sourceAfterSibling: sourceAfterSiblingIdentity,
|
|
8300
8408
|
diagnostics,
|
|
8301
8409
|
binding,
|
|
8410
|
+
targetVid,
|
|
8411
|
+
containerVid,
|
|
8302
8412
|
container: containerIdentity,
|
|
8303
8413
|
beforeSibling: beforeSiblingIdentity,
|
|
8304
8414
|
afterSibling: afterSiblingIdentity,
|
|
@@ -8310,6 +8420,9 @@ function recordCommittedMove(args) {
|
|
|
8310
8420
|
type: "element-moved",
|
|
8311
8421
|
operationId,
|
|
8312
8422
|
commandType: command.type,
|
|
8423
|
+
targetVid,
|
|
8424
|
+
containerVid,
|
|
8425
|
+
index: command.to.index,
|
|
8313
8426
|
selected: {
|
|
8314
8427
|
nodeId: selectedNodeId,
|
|
8315
8428
|
nodeKey: selectedNodeKey,
|
|
@@ -8372,6 +8485,7 @@ function useDragLifecycle({
|
|
|
8372
8485
|
refs.resolvedReorderRef.current = null;
|
|
8373
8486
|
refs.finalVisualKeyRef.current = null;
|
|
8374
8487
|
refs.dragStartPositionRef.current = null;
|
|
8488
|
+
refs.droppableContainerIdsRef.current = null;
|
|
8375
8489
|
clearCommitLaneCache();
|
|
8376
8490
|
refs.safeZoneRef.current = null;
|
|
8377
8491
|
setInsideRect(null);
|
|
@@ -8405,6 +8519,11 @@ function useDragLifecycle({
|
|
|
8405
8519
|
eligibilitySource: found.eligibilitySource ?? "editor-meta",
|
|
8406
8520
|
draggable: found.draggable
|
|
8407
8521
|
});
|
|
8522
|
+
emitRefused(
|
|
8523
|
+
resolveRefusalCode(found.editorMeta, "GATE_REJECT"),
|
|
8524
|
+
"Node is not draggable (dynamic render, chrome, or kit-origin).",
|
|
8525
|
+
found.element
|
|
8526
|
+
);
|
|
8408
8527
|
return;
|
|
8409
8528
|
}
|
|
8410
8529
|
veTrace("dnd", "drag:start", {
|
|
@@ -8428,12 +8547,29 @@ function useDragLifecycle({
|
|
|
8428
8547
|
clearCommitLaneCache();
|
|
8429
8548
|
const anchor = resolveDragAnchor(activeId, proj, refs.nodeMapRef.current);
|
|
8430
8549
|
const anchorScanned = refs.nodeMapRef.current.get(anchor.anchorNodeId) ?? found;
|
|
8431
|
-
if (!anchorScanned || !isEligibleForDrag(anchorScanned))
|
|
8550
|
+
if (!anchorScanned || !isEligibleForDrag(anchorScanned)) {
|
|
8551
|
+
emitRefused(
|
|
8552
|
+
resolveRefusalCode(anchorScanned?.editorMeta, "GATE_REJECT"),
|
|
8553
|
+
"Resolved drag anchor is not draggable.",
|
|
8554
|
+
anchorScanned?.element ?? found.element
|
|
8555
|
+
);
|
|
8556
|
+
return;
|
|
8557
|
+
}
|
|
8432
8558
|
const anchorNodeId = anchor.anchorNodeId;
|
|
8433
8559
|
const srcContainerId = anchor.sourceContainerId;
|
|
8434
8560
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8435
8561
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8436
8562
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8563
|
+
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current)) {
|
|
8564
|
+
blockedContainerIds.add(id);
|
|
8565
|
+
}
|
|
8566
|
+
const droppableSet = computeDroppableSet(anchorNodeId, proj, refs.nodeMapRef.current);
|
|
8567
|
+
refs.droppableContainerIdsRef.current = droppableSet;
|
|
8568
|
+
dispatchRuntimeEvent({
|
|
8569
|
+
type: "drag-started",
|
|
8570
|
+
targetVid: resolveVidFromElement(anchorScanned.element),
|
|
8571
|
+
droppable: Array.from(droppableSet)
|
|
8572
|
+
});
|
|
8437
8573
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8438
8574
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8439
8575
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8506,6 +8642,19 @@ function useDragLifecycle({
|
|
|
8506
8642
|
syncHistoryAvailability();
|
|
8507
8643
|
return;
|
|
8508
8644
|
}
|
|
8645
|
+
if (dropTargetId && !refs.droppableContainerIdsRef.current?.has(dropTargetId)) {
|
|
8646
|
+
const targetContainerEl = resolveNodeElement(dropTargetId);
|
|
8647
|
+
const targetMeta = refs.nodeMapRef.current.get(dropTargetId)?.editorMeta;
|
|
8648
|
+
const fallbackCode = targetMeta?.containerKind === "expression" ? "EXPRESSION_CONTAINER" : "CONTAINER_NOT_PLAIN";
|
|
8649
|
+
emitRefused(
|
|
8650
|
+
resolveRefusalCode(targetMeta, fallbackCode),
|
|
8651
|
+
"Drop target is outside the droppable set for this node.",
|
|
8652
|
+
targetContainerEl
|
|
8653
|
+
);
|
|
8654
|
+
clearDragState();
|
|
8655
|
+
syncHistoryAvailability();
|
|
8656
|
+
return;
|
|
8657
|
+
}
|
|
8509
8658
|
let command = null;
|
|
8510
8659
|
if (nestTarget) {
|
|
8511
8660
|
if (!activeEl.contains(nestTarget.element) && !nestTarget.element.contains(activeEl) && sourcePos?.commitNodeId) {
|
|
@@ -8717,6 +8866,7 @@ function useResizeSession({
|
|
|
8717
8866
|
return;
|
|
8718
8867
|
}
|
|
8719
8868
|
const inspectorRef = getInspectorRefFromElement(element);
|
|
8869
|
+
const targetVid = resolveVidFromElement(element);
|
|
8720
8870
|
const resizeCmd = {
|
|
8721
8871
|
type: "resize",
|
|
8722
8872
|
mode,
|
|
@@ -8736,12 +8886,14 @@ function useResizeSession({
|
|
|
8736
8886
|
nodeId: selectedNodeId,
|
|
8737
8887
|
inspectorRef,
|
|
8738
8888
|
componentName: getEditorMeta(element)?.componentName,
|
|
8889
|
+
targetVid,
|
|
8739
8890
|
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
8891
|
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
8892
|
});
|
|
8742
8893
|
dispatchRuntimeEvent({
|
|
8743
8894
|
type: "element-resized",
|
|
8744
8895
|
operationId,
|
|
8896
|
+
targetVid,
|
|
8745
8897
|
selected: {
|
|
8746
8898
|
nodeId: selectedNodeId,
|
|
8747
8899
|
nodeKey: selectedNodeKey,
|
|
@@ -8964,6 +9116,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8964
9116
|
};
|
|
8965
9117
|
}
|
|
8966
9118
|
const operationId = `${insertCommand.at}:${nodeId}`;
|
|
9119
|
+
const containerVid = containerEl ? resolveVidFromElement(containerEl) : null;
|
|
9120
|
+
const insertedVid = resolveVidFromElement(newElement);
|
|
8967
9121
|
useDesignModeStore.getState().recordInsertChange({
|
|
8968
9122
|
operationId,
|
|
8969
9123
|
nodeKey,
|
|
@@ -8975,6 +9129,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8975
9129
|
tsxImports: component.tsxImports ?? null,
|
|
8976
9130
|
containerId: intent.containerId,
|
|
8977
9131
|
containerNodeKey,
|
|
9132
|
+
containerVid,
|
|
9133
|
+
insertedVid,
|
|
8978
9134
|
index: intent.index,
|
|
8979
9135
|
beforeSiblingInspectorRef: beforeSiblingIdentity?.inspectorRef ?? null,
|
|
8980
9136
|
beforeSiblingNodeKey: beforeSiblingIdentity?.nodeKey ?? null
|
|
@@ -8989,6 +9145,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8989
9145
|
tsxCode: component.tsxCode ?? null,
|
|
8990
9146
|
tsxImports: component.tsxImports ?? null,
|
|
8991
9147
|
container: containerIdentity,
|
|
9148
|
+
containerVid,
|
|
9149
|
+
insertedVid,
|
|
8992
9150
|
index: intent.index,
|
|
8993
9151
|
beforeSibling: beforeSiblingIdentity
|
|
8994
9152
|
});
|
|
@@ -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 {
|