Release 0.0.9

This commit is contained in:
2026-04-20 21:32:36 +00:00
parent c99788f3e2
commit 43d1a61535
5 changed files with 111 additions and 10 deletions

View File

@@ -41,6 +41,7 @@ function worldCollectionEntries() {
sourceLabel: `${doc.documentName ?? "Document"} ${doc.id}`,
sourceName: doc.name ?? null,
sourceUuid: doc.uuid ?? null,
resolveSourceTrail: candidatePath => resolveSourceTrail(doc, candidatePath),
value: doc.toObject ? doc.toObject() : doc
});
}
@@ -95,6 +96,7 @@ async function* packagePackEntries(onProgress = null) {
sourceLabel: `${pack.collection} ${document.id}`,
sourceName: document.name ?? null,
sourceUuid: document.uuid ?? null,
resolveSourceTrail: candidatePath => resolveSourceTrail(document, candidatePath),
value: document.toObject ? document.toObject() : document
};
}
@@ -119,3 +121,73 @@ export async function runRuntimeAnalysis({ onProgress }={}) {
function format(key, data) {
return game.i18n?.format(key, data) ?? key;
}
function resolveSourceTrail(document, candidatePath = []) {
const trail = [createTrailNode(document.uuid, document.name ?? `${document.documentName ?? "Document"} ${document.id}`)];
const path = Array.isArray(candidatePath) ? candidatePath : [];
if (!path.length) return trail;
if (document.documentName === "Actor") {
const itemNode = resolveActorItemTrail(document, path);
if (itemNode) trail.push(itemNode);
return trail;
}
if (document.documentName === "Scene") {
const sceneTrail = resolveSceneTrail(document, path);
if (sceneTrail.length) trail.push(...sceneTrail);
}
return trail;
}
function resolveActorItemTrail(actor, path) {
if ((path[0] !== "items") || !Number.isInteger(path[1])) return null;
const itemData = actor.items?.contents?.[path[1]] ?? actor.toObject?.().items?.[path[1]] ?? null;
const itemId = itemData?.id ?? itemData?._id ?? null;
if (!itemId) return null;
const itemName = itemData?.name ?? `Item ${itemId}`;
return createTrailNode(`${actor.uuid}.Item.${itemId}`, itemName);
}
function resolveSceneTrail(scene, path) {
if ((path[0] !== "tokens") || !Number.isInteger(path[1])) return [];
const token = scene.tokens?.contents?.[path[1]] ?? scene.toObject?.().tokens?.[path[1]] ?? null;
const actorId = token?.actorId ?? token?.actor?.id ?? null;
const actor = actorId ? game.actors?.get(actorId) ?? null : null;
if (!actor) return [];
const trail = [createTrailNode(actor.uuid, actor.name ?? `Actor ${actor.id}`)];
const itemPath = extractTokenItemPath(path);
if (!itemPath) return trail;
const tokenData = scene.toObject?.().tokens?.[path[1]] ?? null;
const itemData = resolveTokenItemData(tokenData, itemPath.itemIndex);
const itemId = itemData?._id ?? itemData?.id ?? null;
if (!itemId) return trail;
trail.push(createTrailNode(`${actor.uuid}.Item.${itemId}`, itemData?.name ?? `Item ${itemId}`));
return trail;
}
function extractTokenItemPath(path) {
if ((path[2] === "actorData") && (path[3] === "items") && Number.isInteger(path[4])) {
return { itemIndex: path[4] };
}
if ((path[2] === "delta") && (path[3] === "items") && Number.isInteger(path[4])) {
return { itemIndex: path[4] };
}
return null;
}
function resolveTokenItemData(tokenData, itemIndex) {
if (!tokenData || !Number.isInteger(itemIndex)) return null;
if (Array.isArray(tokenData.actorData?.items)) return tokenData.actorData.items[itemIndex] ?? null;
if (Array.isArray(tokenData.delta?.items)) return tokenData.delta.items[itemIndex] ?? null;
return null;
}
function createTrailNode(uuid, label) {
return { uuid, label };
}