@archie/devtools 0.0.23 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/inspector.standalone.js +179 -0
- package/package.json +1 -1
|
@@ -274,6 +274,156 @@
|
|
|
274
274
|
return null
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
// ── ARCH-883 F2 — usage chain + instance identity ───────────────────
|
|
278
|
+
// Vanilla twins of collectEditorMetaChain (fiber-bridge.ts) and
|
|
279
|
+
// resolveInstanceIdentity (instance-identity.ts). Those files carry the
|
|
280
|
+
// full rationale; keep the three in step.
|
|
281
|
+
var MAX_META_CHAIN = 24
|
|
282
|
+
|
|
283
|
+
// Every __editorMeta on the fiber return chain, innermost first. The host
|
|
284
|
+
// needs the FULL metas (staticProps/propBindings/propOwner), not the
|
|
285
|
+
// narrowed inspectorSource shape: routing a kit-internal node means
|
|
286
|
+
// finding the USAGE above it and reading the prop value AT that usage.
|
|
287
|
+
function collectEditorMetaChain(el) {
|
|
288
|
+
var chain = []
|
|
289
|
+
var fiber = getFiberFromElement(el)
|
|
290
|
+
while (fiber && chain.length < MAX_META_CHAIN) {
|
|
291
|
+
if (fiber.memoizedProps && fiber.memoizedProps.__editorMeta) {
|
|
292
|
+
var meta = resolveEditorMetaValue(fiber.memoizedProps.__editorMeta)
|
|
293
|
+
if (meta) chain.push(meta)
|
|
294
|
+
}
|
|
295
|
+
fiber = fiber["return"]
|
|
296
|
+
}
|
|
297
|
+
return chain
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
var MAX_ROW_ROOT_DEPTH = 12
|
|
301
|
+
var MAX_KEY_WALK = 40
|
|
302
|
+
|
|
303
|
+
// The fiber that OWNS the nearest __editorMeta for `el`. Vanilla twin of
|
|
304
|
+
// getEditorMetaOwnerFiber (fiber-bridge.ts).
|
|
305
|
+
function getEditorMetaOwnerFiberFromElement(el) {
|
|
306
|
+
var fiber = getFiberFromElement(el)
|
|
307
|
+
while (fiber) {
|
|
308
|
+
if (fiber.memoizedProps && fiber.memoizedProps.__editorMeta) {
|
|
309
|
+
return fiber
|
|
310
|
+
}
|
|
311
|
+
fiber = fiber["return"]
|
|
312
|
+
}
|
|
313
|
+
return null
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// The SINGLE host element `owner` renders, or null when it renders zero
|
|
317
|
+
// or several, or crosses a HostPortal (tag 4). Vanilla twin of
|
|
318
|
+
// getSingleHostElement (fiber-bridge.ts) — conservative by design.
|
|
319
|
+
function getSingleHostElementFromFiber(owner) {
|
|
320
|
+
var hosts = []
|
|
321
|
+
var stack = owner && owner.child ? [owner.child] : []
|
|
322
|
+
while (stack.length > 0) {
|
|
323
|
+
var fiber = stack.pop()
|
|
324
|
+
if (!fiber) continue
|
|
325
|
+
if (fiber.tag === 4) return null
|
|
326
|
+
if (
|
|
327
|
+
typeof fiber.type === "string" &&
|
|
328
|
+
fiber.stateNode &&
|
|
329
|
+
fiber.stateNode.nodeType === 1
|
|
330
|
+
) {
|
|
331
|
+
hosts.push(fiber.stateNode)
|
|
332
|
+
if (hosts.length > 1) return null
|
|
333
|
+
} else if (fiber.child) {
|
|
334
|
+
stack.push(fiber.child)
|
|
335
|
+
}
|
|
336
|
+
if (fiber.sibling) stack.push(fiber.sibling)
|
|
337
|
+
}
|
|
338
|
+
return hosts.length === 1 ? hosts[0] : null
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Vanilla twin of projectUsageMeta (useElementScanner.ts): the usage meta
|
|
342
|
+
// when `el` is the SINGLE host root a component usage renders and that
|
|
343
|
+
// component destructured its props, so the host fiber carries no meta.
|
|
344
|
+
function projectUsageMetaFromElement(el) {
|
|
345
|
+
if (getDirectEditorMetaFromElement(el)) return null
|
|
346
|
+
var owner = getEditorMetaOwnerFiberFromElement(el)
|
|
347
|
+
if (!owner) return null
|
|
348
|
+
if (getSingleHostElementFromFiber(owner) !== el) return null
|
|
349
|
+
return resolveEditorMetaValue(owner.memoizedProps.__editorMeta)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// The nodeId this element carries AS ITS OWN — direct fiber meta, or the
|
|
353
|
+
// single-host projection. NEVER an inherited ancestor nodeId: walking the
|
|
354
|
+
// fiber chain here made every UNSTAMPED subtree (any two siblings
|
|
355
|
+
// rendered by a component the plugin never transformed — anything from
|
|
356
|
+
// node_modules, and here SVG internals too, since this twin accepts any
|
|
357
|
+
// element node) look like a repeated collection. Meanwhile a
|
|
358
|
+
// direct-meta-ONLY rule would make every kit component that destructures
|
|
359
|
+
// its props look like a singleton — which is the fail-OPEN mistake, and
|
|
360
|
+
// would write a literal into a mapped usage, changing every row.
|
|
361
|
+
// See instance-identity.ts for the full rationale.
|
|
362
|
+
function ownMetaNodeId(el) {
|
|
363
|
+
if (!el || el.nodeType !== 1) return null
|
|
364
|
+
var direct = getDirectEditorMetaFromElement(el)
|
|
365
|
+
if (direct && direct.nodeId) return direct.nodeId
|
|
366
|
+
var projected = projectUsageMetaFromElement(el)
|
|
367
|
+
return projected && projected.nodeId ? projected.nodeId : null
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// The repeated-row boundary above `el`, or null. INNERMOST repetition
|
|
371
|
+
// wins (a tag inside a card inside a list is identified by the tag's key).
|
|
372
|
+
function findCollectionWindow(el) {
|
|
373
|
+
var node = el
|
|
374
|
+
for (var depth = 0; depth < MAX_ROW_ROOT_DEPTH; depth++) {
|
|
375
|
+
var parent = node.parentElement
|
|
376
|
+
if (!parent) return null
|
|
377
|
+
|
|
378
|
+
var nodeId = ownMetaNodeId(node)
|
|
379
|
+
if (nodeId !== null) {
|
|
380
|
+
var twins = []
|
|
381
|
+
for (var i = 0; i < parent.children.length; i++) {
|
|
382
|
+
var child = parent.children[i]
|
|
383
|
+
if (ownMetaNodeId(child) === nodeId) twins.push(child)
|
|
384
|
+
}
|
|
385
|
+
if (twins.length >= 2) {
|
|
386
|
+
return {
|
|
387
|
+
rowRoot: node,
|
|
388
|
+
container: parent,
|
|
389
|
+
ordinal: twins.indexOf(node),
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
node = parent
|
|
395
|
+
}
|
|
396
|
+
return null
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Nearest React key BETWEEN the row root and the collection container.
|
|
400
|
+
// Stopping at the container is the point: a keyed ancestor above it
|
|
401
|
+
// identifies a page, not a row.
|
|
402
|
+
function keyWithinWindow(rowRoot, container) {
|
|
403
|
+
var fiber = getFiberFromElement(rowRoot)
|
|
404
|
+
for (var steps = 0; fiber && steps < MAX_KEY_WALK; steps++) {
|
|
405
|
+
if (fiber.stateNode === container) return null
|
|
406
|
+
var key = fiber.key
|
|
407
|
+
if (typeof key === "string" && key.length > 0) return key
|
|
408
|
+
if (typeof key === "number") return String(key)
|
|
409
|
+
fiber = fiber["return"]
|
|
410
|
+
}
|
|
411
|
+
return null
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// WHICH instance of a possibly-repeated node this element is.
|
|
415
|
+
// `scanOrdinal` is telemetry/UI only — the host must REJECT an intent
|
|
416
|
+
// with inCollection && fiberKey === null, never fall back to it.
|
|
417
|
+
function resolveInstanceIdentity(el) {
|
|
418
|
+
var win = findCollectionWindow(el)
|
|
419
|
+
if (!win) return { fiberKey: null, scanOrdinal: 0, inCollection: false }
|
|
420
|
+
return {
|
|
421
|
+
fiberKey: keyWithinWindow(win.rowRoot, win.container),
|
|
422
|
+
scanOrdinal: win.ordinal,
|
|
423
|
+
inCollection: true,
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
277
427
|
if (window._inspectorSharedTargetObserver) {
|
|
278
428
|
try {
|
|
279
429
|
window._inspectorSharedTargetObserver.disconnect()
|
|
@@ -2061,6 +2211,35 @@
|
|
|
2061
2211
|
// this script's version. The slot string is opaque here; validating it
|
|
2062
2212
|
// against kit-runtime's `slot-vocabulary` is the host's job.
|
|
2063
2213
|
editorMeta: editorMeta ? editorMeta.meta : null,
|
|
2214
|
+
// ARCH-883 F2 — the two things the host cannot derive from
|
|
2215
|
+
// `editorMeta` alone (SDD §2.9):
|
|
2216
|
+
//
|
|
2217
|
+
// editorMetaChain: routing a kit-internal node needs the USAGE
|
|
2218
|
+
// (`<Kit.AuthFrame headline="…"/>` in screens/<slug>.jsx), which
|
|
2219
|
+
// is NOT the nearest meta — the nearest meta is the <h1> inside
|
|
2220
|
+
// AuthFrame's own template. The host locates the usage by
|
|
2221
|
+
// matching `propOwner` against a chain entry's componentName and
|
|
2222
|
+
// applies the usage-value law to that entry's staticProps. Both
|
|
2223
|
+
// fields live only on the full meta.
|
|
2224
|
+
//
|
|
2225
|
+
// editorInstance: WHICH row of a repeated node was clicked. The
|
|
2226
|
+
// nodeId is a source position and collides across instances; the
|
|
2227
|
+
// only identity that survives an insert above the edited row is
|
|
2228
|
+
// React's `key`, which exists on the fiber and nowhere else.
|
|
2229
|
+
//
|
|
2230
|
+
// Both are plain data, so an already-published copy of this script
|
|
2231
|
+
// forwards them through structured clone unchanged.
|
|
2232
|
+
//
|
|
2233
|
+
// The chain starts at the element the meta was FOUND on (the same
|
|
2234
|
+
// element `editorMeta` above describes) — a clicked node with no
|
|
2235
|
+
// fiber of its own would otherwise yield an empty chain while
|
|
2236
|
+
// reporting a meta resolved from its parent. The instance walk starts
|
|
2237
|
+
// at the CLICKED element, so an inner collection wins over an outer
|
|
2238
|
+
// one (a tag inside a card inside a list).
|
|
2239
|
+
editorMetaChain: collectEditorMetaChain(
|
|
2240
|
+
editorMeta ? editorMeta.element : element
|
|
2241
|
+
),
|
|
2242
|
+
editorInstance: resolveInstanceIdentity(element),
|
|
2064
2243
|
computedStyles: {
|
|
2065
2244
|
display: computed.display,
|
|
2066
2245
|
position: computed.position,
|