If it’s helpful for anyone else, what I’ve settled on is to check the cache refs to see if there are any stale links. This could still be unsafe if multiple plugins are attempting to modify a file for the same event. It’s unfortunately not great, since it relies on sleeping/setTimeout.
const CHECK_SAFE_ATTEMPTS = 10;
const CHECK_SAFE_WAIT = 50;
async function safeToUpdate(
app: App,
file: TFile,
oldPath: string
): Promise<void> {
const oldLinks = pathToLinks(oldPath);
for (let i = 0; i < CHECK_SAFE_ATTEMPTS; i++) {
const refCache = await app.metadataCache.getFileCache(file);
const staleLinks = iterateCacheRefs(refCache, (ref) =>
oldLinks.includes(ref.link)
);
if (!staleLinks) {
return;
}
await new Promise((resolve) =>
setTimeout(resolve, CHECK_SAFE_WAIT + CHECK_SAFE_WAIT * i)
);
}
}
function pathToLinks(path: string): string[] {
const regex = /^(?<parent>\/?(?:[^./]+\/)*)(?<name>[^.]+)(?<ext>(?:\.\w+)+)/;
const { parent, name, ext } = path.match(regex).groups;
return parent.split("/").flatMap((_, idx, ps) => {
const path = ps.slice(idx).join("/");
return [path + name, path + name + ext];
});
}