@archie/devtools 0.0.47 → 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 +625 -90
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -73,6 +73,42 @@ Changes to `babel-plugin-editor-meta.ts`'s `__editorMeta` prop shape and
|
|
|
73
73
|
`inspector.standalone.js`'s meta-read paths have a load-bearing publish
|
|
74
74
|
order — see [`docs/deploy-order.md`](docs/deploy-order.md).
|
|
75
75
|
|
|
76
|
+
## Identidad `data-vid`, NodeMeta, protocolo 1.x
|
|
77
|
+
|
|
78
|
+
`babelPluginEditorMeta` ahora LEE `data-vid` (persistido en el source por el
|
|
79
|
+
stamper de Genesis, `/^[a-z0-9]{6,8}$/`) en vez de derivar la identidad de
|
|
80
|
+
`file:line:col:componentName`, que se invalida en cada escritura del source.
|
|
81
|
+
Cuando el elemento tiene `data-vid`, `__editorMeta.nodeId === __editorMeta.vid`
|
|
82
|
+
y el plugin también emite los campos de `NodeMeta`
|
|
83
|
+
(`@8base-archie/editor-protocol`): `dynamicType`, `isKitOrigin`, `isChrome`,
|
|
84
|
+
`containerKind` y, cuando aplica, `lockReason`. `parentNodeId` usa el `vid`
|
|
85
|
+
del padre cuando existe.
|
|
86
|
+
|
|
87
|
+
Sin `data-vid`, el plugin cae al direccionamiento legado SOLO cuando la
|
|
88
|
+
opción `allowLegacyIds` es `true` (default en esta versión — transicional,
|
|
89
|
+
se eliminará más adelante); con `allowLegacyIds: false` el elemento no se
|
|
90
|
+
instrumenta.
|
|
91
|
+
|
|
92
|
+
En runtime, `node-key.ts` resuelve la identidad con la prioridad
|
|
93
|
+
`meta.vid` → `data-vid` del DOM → (legado) `meta.nodeId` → `runtime:N`, y
|
|
94
|
+
`fiber-bridge.ts` expone `getNodeMeta(el)`, que valida el `NodeMeta`
|
|
95
|
+
ensamblado contra `NodeMetaSchema` antes de devolverlo. `structural-policy.ts`
|
|
96
|
+
añade `isNonDraggableNodeMeta`, `isNonDroppableNodeMeta` y
|
|
97
|
+
`computeDroppableSet` sobre esos mismos campos.
|
|
98
|
+
|
|
99
|
+
El handshake (`INSPECTOR_SCRIPT_LOADED`/`CAPABILITIES_RESULT`) añade
|
|
100
|
+
`editorProtocolVersion` (el `PROTOCOL_VERSION` semver del paquete de
|
|
101
|
+
contrato — un campo NUEVO, nunca superpuesto al `protocolVersion` numérico
|
|
102
|
+
existente que `archie-app` ya compara estrictamente) y las capabilities
|
|
103
|
+
`vidIdentity`, `nodeMeta`, `refusals`. `ELEMENT_SELECTED` añade `vid` y
|
|
104
|
+
`nodeMeta`. El vocabulario `REFUSED{code, cause, vid}` está disponible
|
|
105
|
+
(`refuseNode` en `inspector.standalone.js`) para cuando un host rechaza un
|
|
106
|
+
gesto de arrastre/drop fuera de política.
|
|
107
|
+
|
|
108
|
+
Consume `@8base-archie/editor-protocol` como fuente única del contrato
|
|
109
|
+
(`Vid`, `NodeMeta`, `LockReason`, los schemas Zod) — ver
|
|
110
|
+
`src/types/editor-meta.ts`, que re-exporta esos tipos en vez de duplicarlos.
|
|
111
|
+
|
|
76
112
|
## Local linking
|
|
77
113
|
|
|
78
114
|
```bash
|
|
@@ -6,6 +6,7 @@ var getDirname = () => path.dirname(getFilename());
|
|
|
6
6
|
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
7
|
|
|
8
8
|
// src/babel-plugin-editor-meta.ts
|
|
9
|
+
import { VID_ATTR, VID_PATTERN } from "@8base-archie/editor-protocol";
|
|
9
10
|
import * as nodePath from "path";
|
|
10
11
|
function meaningfulChildren(t, children) {
|
|
11
12
|
return children.filter((child) => {
|
|
@@ -61,7 +62,8 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
61
62
|
instrumentImported = true,
|
|
62
63
|
includeHostSourceRef = false,
|
|
63
64
|
origin = "screen",
|
|
64
|
-
templateOrigin = false
|
|
65
|
+
templateOrigin = false,
|
|
66
|
+
allowLegacyIds = true
|
|
65
67
|
} = opts;
|
|
66
68
|
function getJSXTagName(el) {
|
|
67
69
|
const { name } = el;
|
|
@@ -109,6 +111,77 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
109
111
|
function computeNodeId(file, line, col, componentName) {
|
|
110
112
|
return `${file}:${line}:${col}:${componentName}`;
|
|
111
113
|
}
|
|
114
|
+
function readVidAttr(attrs) {
|
|
115
|
+
for (const attr of attrs) {
|
|
116
|
+
if (!t.isJSXAttribute(attr)) continue;
|
|
117
|
+
if (!t.isJSXIdentifier(attr.name, { name: VID_ATTR })) continue;
|
|
118
|
+
const { value } = attr;
|
|
119
|
+
let raw = null;
|
|
120
|
+
if (t.isStringLiteral(value)) {
|
|
121
|
+
raw = value.value;
|
|
122
|
+
} else if (t.isJSXExpressionContainer(value) && t.isStringLiteral(value.expression)) {
|
|
123
|
+
raw = value.expression.value;
|
|
124
|
+
}
|
|
125
|
+
if (raw !== null && VID_PATTERN.test(raw)) return raw;
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function computeDynamicType(path2) {
|
|
131
|
+
let current = path2.parentPath;
|
|
132
|
+
while (current) {
|
|
133
|
+
if (current.isJSXExpressionContainer()) {
|
|
134
|
+
const expr = current.node.expression;
|
|
135
|
+
if (t.isConditionalExpression(expr) || t.isLogicalExpression(expr)) {
|
|
136
|
+
return "CONDITIONAL";
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (current.isArrowFunctionExpression() || current.isFunctionExpression()) {
|
|
140
|
+
const call = current.parentPath;
|
|
141
|
+
if (call?.isCallExpression()) {
|
|
142
|
+
const callee = call.node.callee;
|
|
143
|
+
if (t.isMemberExpression(callee) && !callee.computed && t.isIdentifier(callee.property) && /^(map|flatMap|forEach)$/.test(callee.property.name)) {
|
|
144
|
+
return "ARRAY";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
if (current.isFunctionDeclaration()) break;
|
|
150
|
+
current = current.parentPath;
|
|
151
|
+
}
|
|
152
|
+
return "STATIC";
|
|
153
|
+
}
|
|
154
|
+
const SHELL_FILE_RE = /(^|\/)shell\.jsx$/;
|
|
155
|
+
const SHELL_DIR_RE = /(^|\/)components\/shell\//;
|
|
156
|
+
const CHROME_ANCESTOR_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "header"]);
|
|
157
|
+
function computeIsChrome(file, path2) {
|
|
158
|
+
if (SHELL_FILE_RE.test(file) || SHELL_DIR_RE.test(file)) return true;
|
|
159
|
+
let current = path2.parentPath;
|
|
160
|
+
while (current) {
|
|
161
|
+
if (current.isJSXElement()) {
|
|
162
|
+
const tag = getJSXTagName(current.node.openingElement);
|
|
163
|
+
if (CHROME_ANCESTOR_TAGS.has(tag)) return true;
|
|
164
|
+
}
|
|
165
|
+
current = current.parentPath;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
function computeContainerKind(path2) {
|
|
170
|
+
const elPath = path2.parentPath;
|
|
171
|
+
if (!elPath?.isJSXElement()) return "none";
|
|
172
|
+
const children = meaningfulChildren(t, elPath.node.children);
|
|
173
|
+
if (children.length === 0) return "none";
|
|
174
|
+
const allPlain = children.every((c) => t.isJSXElement(c) || t.isJSXText(c));
|
|
175
|
+
return allPlain ? "plain" : "expression";
|
|
176
|
+
}
|
|
177
|
+
function computeLockReason(isKitOrigin, isChrome, dynamicType, containerKind) {
|
|
178
|
+
if (isKitOrigin) return "KIT_INTERNAL";
|
|
179
|
+
if (isChrome) return "CHROME_STRUCTURAL";
|
|
180
|
+
if (dynamicType === "ARRAY") return "DYNAMIC_ARRAY";
|
|
181
|
+
if (dynamicType === "CONDITIONAL") return "DYNAMIC_CONDITIONAL";
|
|
182
|
+
if (containerKind === "expression") return "EXPRESSION_CONTAINER";
|
|
183
|
+
return void 0;
|
|
184
|
+
}
|
|
112
185
|
function isMovable(path2) {
|
|
113
186
|
const elPath = path2.parentPath;
|
|
114
187
|
if (!elPath) return false;
|
|
@@ -126,6 +199,9 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
126
199
|
while (ancestor) {
|
|
127
200
|
if (ancestor.isJSXElement()) {
|
|
128
201
|
const opening = ancestor.node.openingElement;
|
|
202
|
+
const parentVid = readVidAttr(opening.attributes);
|
|
203
|
+
if (parentVid) return parentVid;
|
|
204
|
+
if (!allowLegacyIds) return null;
|
|
129
205
|
const loc = opening.loc?.start;
|
|
130
206
|
if (loc) {
|
|
131
207
|
const tag = getJSXTagName(opening);
|
|
@@ -752,7 +828,9 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
752
828
|
return;
|
|
753
829
|
}
|
|
754
830
|
}
|
|
755
|
-
const
|
|
831
|
+
const vid = readVidAttr(path2.node.attributes);
|
|
832
|
+
if (!vid && !allowLegacyIds) return;
|
|
833
|
+
const nodeId = vid ?? computeNodeId(file, line, col, componentName);
|
|
756
834
|
const isKitOrigin = origin === "kit" || hasSlotAttr;
|
|
757
835
|
const movable = isKitOrigin ? false : isMovable(path2);
|
|
758
836
|
const parentNodeId = getParentNodeId(path2, file);
|
|
@@ -774,6 +852,24 @@ function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
|
774
852
|
parentNodeId ? t.stringLiteral(parentNodeId) : t.nullLiteral()
|
|
775
853
|
)
|
|
776
854
|
]);
|
|
855
|
+
if (vid) {
|
|
856
|
+
const dynamicType = computeDynamicType(path2);
|
|
857
|
+
const isChrome = computeIsChrome(file, path2);
|
|
858
|
+
const containerKind = computeContainerKind(path2);
|
|
859
|
+
const lockReason = computeLockReason(isKitOrigin, isChrome, dynamicType, containerKind);
|
|
860
|
+
metaObj.properties.push(
|
|
861
|
+
t.objectProperty(t.identifier("vid"), t.stringLiteral(vid)),
|
|
862
|
+
t.objectProperty(t.identifier("isKitOrigin"), t.booleanLiteral(isKitOrigin)),
|
|
863
|
+
t.objectProperty(t.identifier("dynamicType"), t.stringLiteral(dynamicType)),
|
|
864
|
+
t.objectProperty(t.identifier("isChrome"), t.booleanLiteral(isChrome)),
|
|
865
|
+
t.objectProperty(t.identifier("containerKind"), t.stringLiteral(containerKind))
|
|
866
|
+
);
|
|
867
|
+
if (lockReason) {
|
|
868
|
+
metaObj.properties.push(
|
|
869
|
+
t.objectProperty(t.identifier("lockReason"), t.stringLiteral(lockReason))
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
777
873
|
if (isKitOrigin) {
|
|
778
874
|
if (templateOrigin) {
|
|
779
875
|
metaObj.properties.push(
|
package/dist/client/client.js
CHANGED
|
@@ -4116,13 +4116,21 @@ function summarizeRuntimeEvent(detail) {
|
|
|
4116
4116
|
container: summarizeIdentity(detail.container),
|
|
4117
4117
|
beforeSibling: summarizeIdentity(detail.beforeSibling),
|
|
4118
4118
|
sourceContainer: summarizeIdentity(detail.sourceContainer),
|
|
4119
|
-
diagnostics: detail.diagnostics ?? null
|
|
4119
|
+
diagnostics: detail.diagnostics ?? null,
|
|
4120
|
+
targetVid: detail.targetVid ?? null,
|
|
4121
|
+
containerVid: detail.containerVid ?? null,
|
|
4122
|
+
index: detail.index
|
|
4120
4123
|
};
|
|
4124
|
+
case "drag-started":
|
|
4125
|
+
return { targetVid: detail.targetVid, droppableCount: detail.droppable.length };
|
|
4126
|
+
case "drag-refused":
|
|
4127
|
+
return { code: detail.code, cause: detail.cause, vid: detail.vid };
|
|
4121
4128
|
case "element-resized":
|
|
4122
4129
|
return {
|
|
4123
4130
|
operationId: detail.operationId,
|
|
4124
4131
|
selected: summarizeIdentity(detail.selected),
|
|
4125
4132
|
anchor: summarizeIdentity(detail.anchor),
|
|
4133
|
+
targetVid: detail.targetVid ?? null,
|
|
4126
4134
|
resize: {
|
|
4127
4135
|
mode: detail.resize.mode,
|
|
4128
4136
|
selectedNodeKey: detail.resize.selectedNodeKey,
|
|
@@ -4139,6 +4147,8 @@ function summarizeRuntimeEvent(detail) {
|
|
|
4139
4147
|
nodeKey: detail.nodeKey,
|
|
4140
4148
|
displayName: detail.displayName,
|
|
4141
4149
|
container: summarizeIdentity(detail.container),
|
|
4150
|
+
containerVid: detail.containerVid ?? null,
|
|
4151
|
+
insertedVid: detail.insertedVid ?? null,
|
|
4142
4152
|
index: detail.index,
|
|
4143
4153
|
beforeSibling: summarizeIdentity(detail.beforeSibling),
|
|
4144
4154
|
hasTsxCode: !!detail.tsxCode,
|
|
@@ -4220,6 +4230,58 @@ function isValidLaneContainer(containerId, projection, nodeMap) {
|
|
|
4220
4230
|
if (container.children.length === 0) return false;
|
|
4221
4231
|
return !isStructuralContainer(containerId, nodeMap);
|
|
4222
4232
|
}
|
|
4233
|
+
function isNonDroppableNodeMeta(meta) {
|
|
4234
|
+
if (!meta) return false;
|
|
4235
|
+
if (meta.containerKind && meta.containerKind !== "plain") return true;
|
|
4236
|
+
if (meta.isChrome) return true;
|
|
4237
|
+
if (meta.isKitOrigin) return true;
|
|
4238
|
+
return false;
|
|
4239
|
+
}
|
|
4240
|
+
function isNonDraggableNodeMeta(meta) {
|
|
4241
|
+
if (!meta) return false;
|
|
4242
|
+
if (meta.dynamicType && meta.dynamicType !== "STATIC") return true;
|
|
4243
|
+
if (meta.isChrome) return true;
|
|
4244
|
+
if (meta.isKitOrigin) return true;
|
|
4245
|
+
return false;
|
|
4246
|
+
}
|
|
4247
|
+
function collectSubtreeIds(rootId, projection) {
|
|
4248
|
+
const ids2 = /* @__PURE__ */ new Set([rootId]);
|
|
4249
|
+
const stack = [rootId];
|
|
4250
|
+
while (stack.length > 0) {
|
|
4251
|
+
const id = stack.pop();
|
|
4252
|
+
const node = projection.containerIndex.get(id);
|
|
4253
|
+
if (!node) continue;
|
|
4254
|
+
for (const childId of node.children) {
|
|
4255
|
+
if (ids2.has(childId)) continue;
|
|
4256
|
+
ids2.add(childId);
|
|
4257
|
+
stack.push(childId);
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
return ids2;
|
|
4261
|
+
}
|
|
4262
|
+
function computeDroppableSet(sourceId, projection, nodeMap) {
|
|
4263
|
+
const excluded = collectSubtreeIds(sourceId, projection);
|
|
4264
|
+
const droppable = /* @__PURE__ */ new Set();
|
|
4265
|
+
for (const containerId of projection.containerIndex.keys()) {
|
|
4266
|
+
if (excluded.has(containerId)) continue;
|
|
4267
|
+
if (isStructuralContainer(containerId, nodeMap)) continue;
|
|
4268
|
+
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) continue;
|
|
4269
|
+
droppable.add(containerId);
|
|
4270
|
+
}
|
|
4271
|
+
return droppable;
|
|
4272
|
+
}
|
|
4273
|
+
function buildBlockedNodeMetaContainerIds(projection, nodeMap) {
|
|
4274
|
+
const blocked = /* @__PURE__ */ new Set();
|
|
4275
|
+
for (const containerId of projection.containerIndex.keys()) {
|
|
4276
|
+
if (isNonDroppableNodeMeta(nodeMap.get(containerId)?.editorMeta)) {
|
|
4277
|
+
blocked.add(containerId);
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
return blocked;
|
|
4281
|
+
}
|
|
4282
|
+
function resolveRefusalCode(meta, fallback) {
|
|
4283
|
+
return meta?.lockReason ?? fallback;
|
|
4284
|
+
}
|
|
4223
4285
|
function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainerId) {
|
|
4224
4286
|
const blocked = /* @__PURE__ */ new Set();
|
|
4225
4287
|
for (const containerId of projection.containerIndex.keys()) {
|
|
@@ -4230,6 +4292,7 @@ function buildBlockedStructuralContainerIds(projection, nodeMap, sourceContainer
|
|
|
4230
4292
|
}
|
|
4231
4293
|
|
|
4232
4294
|
// src/client/dnd/design-mode/fiber-bridge.ts
|
|
4295
|
+
var import_editor_protocol = require("@8base-archie/editor-protocol");
|
|
4233
4296
|
var FIBER_KEY_PREFIX = "__reactFiber$";
|
|
4234
4297
|
var PROPS_KEY_PREFIX = "__reactProps$";
|
|
4235
4298
|
var metaCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4492,6 +4555,9 @@ function resolveDragSurface(el) {
|
|
|
4492
4555
|
};
|
|
4493
4556
|
}
|
|
4494
4557
|
|
|
4558
|
+
// src/types/editor-meta.ts
|
|
4559
|
+
var import_editor_protocol2 = require("@8base-archie/editor-protocol");
|
|
4560
|
+
|
|
4495
4561
|
// src/client/dnd/design-mode/node-key.ts
|
|
4496
4562
|
var _runtimeKeyMap = /* @__PURE__ */ new WeakMap();
|
|
4497
4563
|
var _runtimeKeyCounter = 0;
|
|
@@ -4509,11 +4575,18 @@ function getNodeKeyFromElement(el) {
|
|
|
4509
4575
|
const resolved = resolveDragSurface(el);
|
|
4510
4576
|
const host = resolved.host ?? el;
|
|
4511
4577
|
const meta = identityMeta(host);
|
|
4578
|
+
if (meta?.vid) return meta.vid;
|
|
4579
|
+
const domVid = host.getAttribute("data-vid");
|
|
4580
|
+
if (domVid) return domVid;
|
|
4512
4581
|
if (meta) return meta.nodeId;
|
|
4513
4582
|
const persisted = host.getAttribute("data-dnd-node-id");
|
|
4514
4583
|
if (persisted) return persisted;
|
|
4515
4584
|
return getRuntimeKey(host);
|
|
4516
4585
|
}
|
|
4586
|
+
function resolveVidFromElement(el) {
|
|
4587
|
+
const key2 = getNodeKeyFromElement(el);
|
|
4588
|
+
return import_editor_protocol2.VID_PATTERN.test(key2) ? key2 : null;
|
|
4589
|
+
}
|
|
4517
4590
|
function getInspectorRefFromElement(el) {
|
|
4518
4591
|
const resolved = resolveDragSurface(el);
|
|
4519
4592
|
const host = resolved.host ?? el;
|
|
@@ -4840,6 +4913,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4840
4913
|
afterSibling,
|
|
4841
4914
|
diagnostics,
|
|
4842
4915
|
binding,
|
|
4916
|
+
targetVid,
|
|
4917
|
+
containerVid,
|
|
4843
4918
|
componentName,
|
|
4844
4919
|
before,
|
|
4845
4920
|
after
|
|
@@ -4867,6 +4942,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4867
4942
|
afterSibling: afterSibling ?? null,
|
|
4868
4943
|
diagnostics: diagnostics ?? null,
|
|
4869
4944
|
binding: binding ?? null,
|
|
4945
|
+
targetVid: targetVid ?? null,
|
|
4946
|
+
containerVid: containerVid ?? null,
|
|
4870
4947
|
payload: { before, after },
|
|
4871
4948
|
at: now
|
|
4872
4949
|
};
|
|
@@ -4895,6 +4972,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4895
4972
|
nodeId,
|
|
4896
4973
|
inspectorRef,
|
|
4897
4974
|
componentName,
|
|
4975
|
+
targetVid,
|
|
4898
4976
|
before,
|
|
4899
4977
|
after
|
|
4900
4978
|
}) => {
|
|
@@ -4906,6 +4984,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4906
4984
|
nodeKey,
|
|
4907
4985
|
nodeId,
|
|
4908
4986
|
inspectorRef,
|
|
4987
|
+
targetVid: targetVid ?? null,
|
|
4909
4988
|
payload: { before, after },
|
|
4910
4989
|
at: now
|
|
4911
4990
|
};
|
|
@@ -4939,6 +5018,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4939
5018
|
tsxImports,
|
|
4940
5019
|
containerId,
|
|
4941
5020
|
containerNodeKey,
|
|
5021
|
+
containerVid,
|
|
5022
|
+
insertedVid,
|
|
4942
5023
|
index,
|
|
4943
5024
|
beforeSiblingInspectorRef,
|
|
4944
5025
|
beforeSiblingNodeKey
|
|
@@ -4957,6 +5038,8 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4957
5038
|
tsxImports: tsxImports ?? null,
|
|
4958
5039
|
containerId,
|
|
4959
5040
|
containerNodeKey,
|
|
5041
|
+
containerVid: containerVid ?? null,
|
|
5042
|
+
insertedVid: insertedVid ?? null,
|
|
4960
5043
|
index,
|
|
4961
5044
|
beforeSiblingInspectorRef: beforeSiblingInspectorRef ?? null,
|
|
4962
5045
|
beforeSiblingNodeKey: beforeSiblingNodeKey ?? null,
|
|
@@ -5070,6 +5153,7 @@ function shouldShowGrabFeedback(target, scannedByNodeId) {
|
|
|
5070
5153
|
}
|
|
5071
5154
|
function isEligibleForDrag(sc) {
|
|
5072
5155
|
if (sc.draggable === false) return false;
|
|
5156
|
+
if (isNonDraggableNodeMeta(sc.editorMeta)) return false;
|
|
5073
5157
|
const source = sc.eligibilitySource ?? "editor-meta";
|
|
5074
5158
|
return source === "editor-meta" || source === "force-allow" || source === "inferred-sortable-descendant" || // RFC E2.4 P1: single host root of a kit-component usage (MetricCard,
|
|
5075
5159
|
// Section, …) carrying the usage's projected meta.
|
|
@@ -6692,6 +6776,15 @@ function serializeArrangeChange(event, index) {
|
|
|
6692
6776
|
diagnostics: event.kind === "move" ? event.diagnostics : void 0,
|
|
6693
6777
|
// ARCH-1065 D17 — which slice row this move addresses.
|
|
6694
6778
|
binding: event.kind === "move" ? event.binding : void 0,
|
|
6779
|
+
// `data-vid` identity migration (`host-bridge.ts`'s `RuntimeMoveDetail`
|
|
6780
|
+
// fields). `index` here is `event.payload.after.index` — the MOVE's own
|
|
6781
|
+
// JSX-child index — never the `index` PARAMETER above (this change's
|
|
6782
|
+
// sequence position in the session). `targetVid` also carries the
|
|
6783
|
+
// resized node's vid on a `resize` change; `containerVid` also carries
|
|
6784
|
+
// the drop container's vid on an `insert` change.
|
|
6785
|
+
targetVid: event.kind === "move" || event.kind === "resize" ? event.targetVid : void 0,
|
|
6786
|
+
containerVid: event.kind === "move" || event.kind === "insert" ? event.containerVid : void 0,
|
|
6787
|
+
index: event.kind === "move" ? event.payload.after.index : void 0,
|
|
6695
6788
|
// Insert-specific fields
|
|
6696
6789
|
displayName: event.kind === "insert" ? event.displayName : void 0,
|
|
6697
6790
|
html: event.kind === "insert" ? event.html : void 0,
|
|
@@ -6699,6 +6792,7 @@ function serializeArrangeChange(event, index) {
|
|
|
6699
6792
|
tsxImports: event.kind === "insert" ? event.tsxImports : void 0,
|
|
6700
6793
|
containerId: event.kind === "insert" ? event.containerId : void 0,
|
|
6701
6794
|
containerNodeKey: event.kind === "insert" ? event.containerNodeKey : void 0,
|
|
6795
|
+
insertedVid: event.kind === "insert" ? event.insertedVid : void 0,
|
|
6702
6796
|
insertIndex: event.kind === "insert" ? event.index : void 0,
|
|
6703
6797
|
beforeSiblingInspectorRef: event.kind === "insert" ? event.beforeSiblingInspectorRef : void 0,
|
|
6704
6798
|
beforeSiblingNodeKey: event.kind === "insert" ? event.beforeSiblingNodeKey : void 0,
|
|
@@ -6955,6 +7049,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6955
7049
|
const resolvedReorderRef = (0, import_react11.useRef)(null);
|
|
6956
7050
|
const finalVisualKeyRef = (0, import_react11.useRef)(null);
|
|
6957
7051
|
const dragStartPositionRef = (0, import_react11.useRef)(null);
|
|
7052
|
+
const droppableContainerIdsRef = (0, import_react11.useRef)(null);
|
|
6958
7053
|
const sourceCommitLaneRef = (0, import_react11.useRef)(null);
|
|
6959
7054
|
const commitLaneCacheRef = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
6960
7055
|
const safeZoneRef = (0, import_react11.useRef)(null);
|
|
@@ -6986,6 +7081,7 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6986
7081
|
resolvedReorderRef,
|
|
6987
7082
|
finalVisualKeyRef,
|
|
6988
7083
|
dragStartPositionRef,
|
|
7084
|
+
droppableContainerIdsRef,
|
|
6989
7085
|
sourceCommitLaneRef,
|
|
6990
7086
|
commitLaneCacheRef,
|
|
6991
7087
|
safeZoneRef,
|
|
@@ -8187,6 +8283,14 @@ function useDragVisualLoop({
|
|
|
8187
8283
|
|
|
8188
8284
|
// src/client/dnd/design-mode/useDragLifecycle.ts
|
|
8189
8285
|
var import_react13 = require("react");
|
|
8286
|
+
function emitRefused(code, cause, element) {
|
|
8287
|
+
dispatchRuntimeEvent({
|
|
8288
|
+
type: "drag-refused",
|
|
8289
|
+
code,
|
|
8290
|
+
cause,
|
|
8291
|
+
vid: element ? resolveVidFromElement(element) : null
|
|
8292
|
+
});
|
|
8293
|
+
}
|
|
8190
8294
|
function resolveLaneAllowedContainers(anchorElement, srcContainerId) {
|
|
8191
8295
|
if (!srcContainerId) return null;
|
|
8192
8296
|
if (!resolveRowBinding(anchorElement)) return null;
|
|
@@ -8303,6 +8407,10 @@ function recordCommittedMove(args) {
|
|
|
8303
8407
|
});
|
|
8304
8408
|
const componentName = getEditorMeta(anchorEl)?.componentName;
|
|
8305
8409
|
const operationId = `${command.at}:${anchorNodeId}`;
|
|
8410
|
+
const targetVid = resolveVidFromElement(selectedEl);
|
|
8411
|
+
const targetContainerId = command.to.parentNodeId ?? command.to.laneContainerId;
|
|
8412
|
+
const targetContainerEl = targetContainerId ? resolveNodeElement(targetContainerId) : null;
|
|
8413
|
+
const containerVid = targetContainerEl ? resolveVidFromElement(targetContainerEl) : null;
|
|
8306
8414
|
const binding = resolveRowBinding(selectedEl);
|
|
8307
8415
|
const beforePayload = buildMovePayloadWithEffectiveIdentities({
|
|
8308
8416
|
placement: command.from,
|
|
@@ -8334,6 +8442,8 @@ function recordCommittedMove(args) {
|
|
|
8334
8442
|
sourceAfterSibling: sourceAfterSiblingIdentity,
|
|
8335
8443
|
diagnostics,
|
|
8336
8444
|
binding,
|
|
8445
|
+
targetVid,
|
|
8446
|
+
containerVid,
|
|
8337
8447
|
container: containerIdentity,
|
|
8338
8448
|
beforeSibling: beforeSiblingIdentity,
|
|
8339
8449
|
afterSibling: afterSiblingIdentity,
|
|
@@ -8345,6 +8455,9 @@ function recordCommittedMove(args) {
|
|
|
8345
8455
|
type: "element-moved",
|
|
8346
8456
|
operationId,
|
|
8347
8457
|
commandType: command.type,
|
|
8458
|
+
targetVid,
|
|
8459
|
+
containerVid,
|
|
8460
|
+
index: command.to.index,
|
|
8348
8461
|
selected: {
|
|
8349
8462
|
nodeId: selectedNodeId,
|
|
8350
8463
|
nodeKey: selectedNodeKey,
|
|
@@ -8407,6 +8520,7 @@ function useDragLifecycle({
|
|
|
8407
8520
|
refs.resolvedReorderRef.current = null;
|
|
8408
8521
|
refs.finalVisualKeyRef.current = null;
|
|
8409
8522
|
refs.dragStartPositionRef.current = null;
|
|
8523
|
+
refs.droppableContainerIdsRef.current = null;
|
|
8410
8524
|
clearCommitLaneCache();
|
|
8411
8525
|
refs.safeZoneRef.current = null;
|
|
8412
8526
|
setInsideRect(null);
|
|
@@ -8440,6 +8554,11 @@ function useDragLifecycle({
|
|
|
8440
8554
|
eligibilitySource: found.eligibilitySource ?? "editor-meta",
|
|
8441
8555
|
draggable: found.draggable
|
|
8442
8556
|
});
|
|
8557
|
+
emitRefused(
|
|
8558
|
+
resolveRefusalCode(found.editorMeta, "GATE_REJECT"),
|
|
8559
|
+
"Node is not draggable (dynamic render, chrome, or kit-origin).",
|
|
8560
|
+
found.element
|
|
8561
|
+
);
|
|
8443
8562
|
return;
|
|
8444
8563
|
}
|
|
8445
8564
|
veTrace("dnd", "drag:start", {
|
|
@@ -8463,12 +8582,29 @@ function useDragLifecycle({
|
|
|
8463
8582
|
clearCommitLaneCache();
|
|
8464
8583
|
const anchor = resolveDragAnchor(activeId, proj, refs.nodeMapRef.current);
|
|
8465
8584
|
const anchorScanned = refs.nodeMapRef.current.get(anchor.anchorNodeId) ?? found;
|
|
8466
|
-
if (!anchorScanned || !isEligibleForDrag(anchorScanned))
|
|
8585
|
+
if (!anchorScanned || !isEligibleForDrag(anchorScanned)) {
|
|
8586
|
+
emitRefused(
|
|
8587
|
+
resolveRefusalCode(anchorScanned?.editorMeta, "GATE_REJECT"),
|
|
8588
|
+
"Resolved drag anchor is not draggable.",
|
|
8589
|
+
anchorScanned?.element ?? found.element
|
|
8590
|
+
);
|
|
8591
|
+
return;
|
|
8592
|
+
}
|
|
8467
8593
|
const anchorNodeId = anchor.anchorNodeId;
|
|
8468
8594
|
const srcContainerId = anchor.sourceContainerId;
|
|
8469
8595
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8470
8596
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8471
8597
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8598
|
+
for (const id of buildBlockedNodeMetaContainerIds(proj, refs.nodeMapRef.current)) {
|
|
8599
|
+
blockedContainerIds.add(id);
|
|
8600
|
+
}
|
|
8601
|
+
const droppableSet = computeDroppableSet(anchorNodeId, proj, refs.nodeMapRef.current);
|
|
8602
|
+
refs.droppableContainerIdsRef.current = droppableSet;
|
|
8603
|
+
dispatchRuntimeEvent({
|
|
8604
|
+
type: "drag-started",
|
|
8605
|
+
targetVid: resolveVidFromElement(anchorScanned.element),
|
|
8606
|
+
droppable: Array.from(droppableSet)
|
|
8607
|
+
});
|
|
8472
8608
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8473
8609
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8474
8610
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8541,6 +8677,19 @@ function useDragLifecycle({
|
|
|
8541
8677
|
syncHistoryAvailability();
|
|
8542
8678
|
return;
|
|
8543
8679
|
}
|
|
8680
|
+
if (dropTargetId && !refs.droppableContainerIdsRef.current?.has(dropTargetId)) {
|
|
8681
|
+
const targetContainerEl = resolveNodeElement(dropTargetId);
|
|
8682
|
+
const targetMeta = refs.nodeMapRef.current.get(dropTargetId)?.editorMeta;
|
|
8683
|
+
const fallbackCode = targetMeta?.containerKind === "expression" ? "EXPRESSION_CONTAINER" : "CONTAINER_NOT_PLAIN";
|
|
8684
|
+
emitRefused(
|
|
8685
|
+
resolveRefusalCode(targetMeta, fallbackCode),
|
|
8686
|
+
"Drop target is outside the droppable set for this node.",
|
|
8687
|
+
targetContainerEl
|
|
8688
|
+
);
|
|
8689
|
+
clearDragState();
|
|
8690
|
+
syncHistoryAvailability();
|
|
8691
|
+
return;
|
|
8692
|
+
}
|
|
8544
8693
|
let command = null;
|
|
8545
8694
|
if (nestTarget) {
|
|
8546
8695
|
if (!activeEl.contains(nestTarget.element) && !nestTarget.element.contains(activeEl) && sourcePos?.commitNodeId) {
|
|
@@ -8752,6 +8901,7 @@ function useResizeSession({
|
|
|
8752
8901
|
return;
|
|
8753
8902
|
}
|
|
8754
8903
|
const inspectorRef = getInspectorRefFromElement(element);
|
|
8904
|
+
const targetVid = resolveVidFromElement(element);
|
|
8755
8905
|
const resizeCmd = {
|
|
8756
8906
|
type: "resize",
|
|
8757
8907
|
mode,
|
|
@@ -8771,12 +8921,14 @@ function useResizeSession({
|
|
|
8771
8921
|
nodeId: selectedNodeId,
|
|
8772
8922
|
inspectorRef,
|
|
8773
8923
|
componentName: getEditorMeta(element)?.componentName,
|
|
8924
|
+
targetVid,
|
|
8774
8925
|
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 } },
|
|
8775
8926
|
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 } }
|
|
8776
8927
|
});
|
|
8777
8928
|
dispatchRuntimeEvent({
|
|
8778
8929
|
type: "element-resized",
|
|
8779
8930
|
operationId,
|
|
8931
|
+
targetVid,
|
|
8780
8932
|
selected: {
|
|
8781
8933
|
nodeId: selectedNodeId,
|
|
8782
8934
|
nodeKey: selectedNodeKey,
|
|
@@ -8999,6 +9151,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8999
9151
|
};
|
|
9000
9152
|
}
|
|
9001
9153
|
const operationId = `${insertCommand.at}:${nodeId}`;
|
|
9154
|
+
const containerVid = containerEl ? resolveVidFromElement(containerEl) : null;
|
|
9155
|
+
const insertedVid = resolveVidFromElement(newElement);
|
|
9002
9156
|
useDesignModeStore.getState().recordInsertChange({
|
|
9003
9157
|
operationId,
|
|
9004
9158
|
nodeKey,
|
|
@@ -9010,6 +9164,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
9010
9164
|
tsxImports: component.tsxImports ?? null,
|
|
9011
9165
|
containerId: intent.containerId,
|
|
9012
9166
|
containerNodeKey,
|
|
9167
|
+
containerVid,
|
|
9168
|
+
insertedVid,
|
|
9013
9169
|
index: intent.index,
|
|
9014
9170
|
beforeSiblingInspectorRef: beforeSiblingIdentity?.inspectorRef ?? null,
|
|
9015
9171
|
beforeSiblingNodeKey: beforeSiblingIdentity?.nodeKey ?? null
|
|
@@ -9024,6 +9180,8 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
9024
9180
|
tsxCode: component.tsxCode ?? null,
|
|
9025
9181
|
tsxImports: component.tsxImports ?? null,
|
|
9026
9182
|
container: containerIdentity,
|
|
9183
|
+
containerVid,
|
|
9184
|
+
insertedVid,
|
|
9027
9185
|
index: intent.index,
|
|
9028
9186
|
beforeSibling: beforeSiblingIdentity
|
|
9029
9187
|
});
|