resolve workspace and appearance from the warm cache at boot

This commit is contained in:
Nystik
2026-06-16 23:44:26 +02:00
parent b6c538fb33
commit 0aa2b2bd45
3 changed files with 45 additions and 88 deletions

View File

@@ -171,8 +171,7 @@ function applyCoreSyncGuard(plugins) {
return data; return data;
} }
let text = let text = typeof data === "string" ? data : new TextDecoder().decode(data);
typeof data === "string" ? data : new TextDecoder().decode(data);
try { try {
const config = JSON.parse(text); const config = JSON.parse(text);
@@ -226,6 +225,13 @@ function updateBootProgress(received, total) {
label.textContent = `Loading plugins... ${mb(received)}/${mb(total)} MB`; label.textContent = `Loading plugins... ${mb(received)}/${mb(total)} MB`;
} }
// Resolve the active workspace and snapshot the appearance config.
function resolveWorkspaceAndAppearance() {
resolveWorkspaceName();
loadPresetIfRequested();
initNativeMenuGuard();
}
export function initialize() { export function initialize() {
if (maybeProvisionDemoVault()) { if (maybeProvisionDemoVault()) {
window.__ignisBootReady = Promise.resolve(); window.__ignisBootReady = Promise.resolve();
@@ -233,9 +239,6 @@ export function initialize() {
} }
resolveVaultId(); resolveVaultId();
resolveWorkspaceName();
loadPresetIfRequested();
initNativeMenuGuard(window.__currentVaultId);
const bootstrap = fetchBootstrap(); const bootstrap = fetchBootstrap();
@@ -258,13 +261,16 @@ export function initialize() {
{ onProgress: updateBootProgress }, { onProgress: updateBootProgress },
); );
window.__ignisBootReady = priority; // Chain workspace/appearance resolution onto readiness so its config reads hit the warm priority slice instead of the network.
window.__ignisBootReady = priority.then(resolveWorkspaceAndAppearance);
} else { } else {
window.__ignisBootReady = Promise.resolve();
initVaultConfigFallback(); initVaultConfigFallback();
initVaultListFallback(); initVaultListFallback();
initMetadataCacheFallback(); initMetadataCacheFallback();
initCoreSyncGuardFallback(); initCoreSyncGuardFallback();
// No prefetch on the fallback path, so resolve directly; the reads fall through to the network.
resolveWorkspaceAndAppearance();
window.__ignisBootReady = Promise.resolve();
} }
installRequestUrlShim(); installRequestUrlShim();

View File

@@ -6,34 +6,16 @@ import {
registerReadTransform, registerReadTransform,
registerWriteTransform, registerWriteTransform,
} from "./fs/transforms.js"; } from "./fs/transforms.js";
import { fsShim } from "./fs/index.js";
const APPEARANCE_PATH = ".obsidian/appearance.json"; const APPEARANCE_PATH = ".obsidian/appearance.json";
// undefined = key absent on disk; write transform keeps it absent. // undefined = key absent on disk; write transform keeps it absent.
let preservedNativeMenus = undefined; let preservedNativeMenus = undefined;
function snapshotAppearance(vaultId) { function snapshotAppearance() {
if (!vaultId) {
return;
}
try { try {
const xhr = new XMLHttpRequest(); const obj = JSON.parse(fsShim.readFileSync(APPEARANCE_PATH, "utf-8"));
const url =
"/api/fs/readFile?vault=" +
encodeURIComponent(vaultId) +
"&path=" +
encodeURIComponent(APPEARANCE_PATH) +
"&encoding=utf-8";
xhr.open("GET", url, false);
xhr.send();
if (xhr.status !== 200) {
return;
}
const obj = JSON.parse(xhr.responseText);
if ("nativeMenus" in obj) { if ("nativeMenus" in obj) {
preservedNativeMenus = obj.nativeMenus; preservedNativeMenus = obj.nativeMenus;
@@ -158,9 +140,9 @@ function disableNativeMenuToggle() {
}); });
} }
export function initNativeMenuGuard(vaultId) { export function initNativeMenuGuard() {
// Snapshot before registering transforms so the write transform has the original disk value to substitute back. // Snapshot before registering the read transform so the captured value is the original on disk, not the forced value.
snapshotAppearance(vaultId); snapshotAppearance();
registerReadTransform(APPEARANCE_PATH, readTransform); registerReadTransform(APPEARANCE_PATH, readTransform);
registerWriteTransform(APPEARANCE_PATH, writeTransform); registerWriteTransform(APPEARANCE_PATH, writeTransform);
patchSetConfig(); patchSetConfig();

View File

@@ -86,71 +86,40 @@ export function loadPresetIfRequested() {
} }
} }
export function resolveWorkspaceName() { function readJsonIfPresent(path) {
try { try {
const vaultParam = window.__currentVaultId return JSON.parse(fsShim.readFileSync(path, "utf-8"));
? "?vault=" + encodeURIComponent(window.__currentVaultId) } catch {
: ""; return null;
}
}
const sep = vaultParam ? "&" : "?"; export function resolveWorkspaceName() {
// With no URL param, only resolve a workspace when the workspaces core plugin is enabled.
if (!window.__workspaceName) {
const corePlugins = readJsonIfPresent(".obsidian/core-plugins.json");
// If no param provided, check if workspaces plugin is enabled before resolving. if (!corePlugins || !corePlugins.workspaces) {
if (!window.__workspaceName) {
const coreXhr = new XMLHttpRequest();
coreXhr.open(
"GET",
"/api/fs/readFile" +
vaultParam +
sep +
"path=.obsidian/core-plugins.json&encoding=utf-8",
false,
);
coreXhr.send();
if (coreXhr.status !== 200) {
return;
}
const corePlugins = JSON.parse(coreXhr.responseText);
if (!corePlugins.workspaces) {
return;
}
}
// Read workspaces.json to get the active field.
const xhr = new XMLHttpRequest();
xhr.open(
"GET",
"/api/fs/readFile" +
vaultParam +
sep +
"path=.obsidian/workspaces.json&encoding=utf-8",
false,
);
xhr.send();
if (xhr.status !== 200) {
return; return;
} }
}
const workspaces = JSON.parse(xhr.responseText); const workspaces = readJsonIfPresent(WORKSPACES_PATH);
// Always store the original active value for the write transform. if (!workspaces) {
if (workspaces.active) { return;
window.__originalActiveWorkspace = workspaces.active; }
}
// If no param was provided, seed from the active workspace. // Keep the original active value so the write transform can restore it on disk.
if (!window.__workspaceName && workspaces.active) { if (workspaces.active) {
window.__workspaceName = workspaces.active; window.__originalActiveWorkspace = workspaces.active;
setWorkspaceParam(workspaces.active); }
console.log("[ignis] Workspace resolved from active:", workspaces.active);
} // With no URL param, seed from the active workspace.
} catch (e) { if (!window.__workspaceName && workspaces.active) {
console.warn("[ignis] Failed to resolve workspace name:", e); window.__workspaceName = workspaces.active;
setWorkspaceParam(workspaces.active);
console.log("[ignis] Workspace resolved from active:", workspaces.active);
} }
} }