2026-03-07 12:23:08 +01:00
|
|
|
import { electronShim } from "./electron/index.js";
|
|
|
|
|
import { remoteShim } from "./electron/remote/index.js";
|
|
|
|
|
import { fsShim } from "./fs/index.js";
|
|
|
|
|
import { pathShim } from "./path.js";
|
|
|
|
|
import { urlShim } from "./url.js";
|
|
|
|
|
import { cryptoShim } from "./crypto/index.js";
|
|
|
|
|
import { processShim } from "./process.js";
|
2026-03-11 23:03:14 +01:00
|
|
|
import { installRequestUrlShim } from "./request-url.js";
|
|
|
|
|
import * as childProcessShim from "./node/child_process.js";
|
|
|
|
|
import * as eventsShim from "./node/events.js";
|
|
|
|
|
import * as osShim from "./node/os.js";
|
|
|
|
|
import * as netShim from "./node/net.js";
|
|
|
|
|
import * as httpShim from "./node/http.js";
|
2026-03-07 12:23:08 +01:00
|
|
|
|
|
|
|
|
const DEBUG = true;
|
|
|
|
|
const _accessLog = new Map(); // "module.property" -> count
|
|
|
|
|
|
|
|
|
|
function wrapWithProxy(obj, name) {
|
|
|
|
|
if (!DEBUG || !obj || typeof obj !== "object") return obj;
|
|
|
|
|
return new Proxy(obj, {
|
|
|
|
|
get(target, prop) {
|
|
|
|
|
if (
|
|
|
|
|
typeof prop === "string" &&
|
|
|
|
|
prop !== "then" &&
|
|
|
|
|
prop !== "toJSON" &&
|
|
|
|
|
!prop.startsWith("_")
|
|
|
|
|
) {
|
|
|
|
|
const key = `${name}.${prop}`;
|
|
|
|
|
_accessLog.set(key, (_accessLog.get(key) || 0) + 1);
|
|
|
|
|
if (!(prop in target)) {
|
2026-03-11 22:08:30 +01:00
|
|
|
console.warn(`[shim:MISS] ${key} - property not found on shim`);
|
2026-03-07 12:23:08 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return target[prop];
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.__shimLog = function () {
|
|
|
|
|
const sorted = [..._accessLog.entries()].sort((a, b) => b[1] - a[1]);
|
|
|
|
|
console.table(sorted.map(([k, v]) => ({ api: k, calls: v })));
|
|
|
|
|
};
|
|
|
|
|
window.__shimMisses = function () {
|
|
|
|
|
const sorted = [..._accessLog.entries()]
|
|
|
|
|
.filter(([k]) => {
|
|
|
|
|
const [mod, prop] = k.split(".");
|
|
|
|
|
const shim = rawRegistry[mod];
|
|
|
|
|
return shim && !(prop in shim);
|
|
|
|
|
})
|
|
|
|
|
.sort((a, b) => b[1] - a[1]);
|
|
|
|
|
console.table(sorted.map(([k, v]) => ({ api: k, calls: v })));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const rawRegistry = {
|
|
|
|
|
electron: electronShim,
|
|
|
|
|
"@electron/remote": remoteShim,
|
|
|
|
|
"original-fs": fsShim,
|
|
|
|
|
fs: fsShim,
|
|
|
|
|
path: pathShim,
|
|
|
|
|
url: urlShim,
|
|
|
|
|
crypto: cryptoShim,
|
2026-03-11 23:03:14 +01:00
|
|
|
child_process: childProcessShim,
|
|
|
|
|
events: eventsShim,
|
|
|
|
|
os: osShim,
|
|
|
|
|
net: netShim,
|
|
|
|
|
http: httpShim,
|
|
|
|
|
https: httpShim,
|
2026-03-07 12:23:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const shimRegistry = {};
|
|
|
|
|
for (const [name, shim] of Object.entries(rawRegistry)) {
|
|
|
|
|
shimRegistry[name] = wrapWithProxy(shim, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const throwOnRequire = new Set(["btime", "get-fonts", "vibrancy-win"]);
|
|
|
|
|
|
|
|
|
|
window.require = function (moduleName) {
|
|
|
|
|
if (throwOnRequire.has(moduleName)) {
|
|
|
|
|
throw new Error(`Cannot find module '${moduleName}'`);
|
|
|
|
|
}
|
|
|
|
|
if (shimRegistry[moduleName]) {
|
|
|
|
|
return shimRegistry[moduleName];
|
|
|
|
|
}
|
|
|
|
|
console.warn("[obsidian-bridge] Unshimmed require:", moduleName);
|
|
|
|
|
return wrapWithProxy({}, `UNKNOWN(${moduleName})`);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
window.process = processShim;
|
|
|
|
|
|
|
|
|
|
if (typeof window.Buffer === "undefined") {
|
|
|
|
|
window.Buffer = {
|
|
|
|
|
from: function (data, encoding) {
|
|
|
|
|
if (typeof data === "string") {
|
|
|
|
|
return new TextEncoder().encode(data);
|
|
|
|
|
}
|
|
|
|
|
if (data instanceof ArrayBuffer) {
|
|
|
|
|
return new Uint8Array(data);
|
|
|
|
|
}
|
|
|
|
|
return new Uint8Array(data);
|
|
|
|
|
},
|
|
|
|
|
concat: function (arrays) {
|
|
|
|
|
const total = arrays.reduce((sum, a) => sum + a.length, 0);
|
|
|
|
|
const result = new Uint8Array(total);
|
|
|
|
|
let offset = 0;
|
|
|
|
|
for (const arr of arrays) {
|
|
|
|
|
result.set(arr, offset);
|
|
|
|
|
offset += arr.length;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
},
|
|
|
|
|
isBuffer: function (obj) {
|
|
|
|
|
return obj instanceof Uint8Array;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.close = function () {
|
|
|
|
|
console.log("[obsidian-bridge] window.close() blocked");
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-10 20:49:10 +01:00
|
|
|
window.addEventListener(
|
|
|
|
|
"contextmenu",
|
|
|
|
|
(e) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
Object.defineProperty(e, "defaultPrevented", { get: () => false });
|
|
|
|
|
},
|
|
|
|
|
true,
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-10 22:31:01 +01:00
|
|
|
const _urlParams = new URLSearchParams(window.location.search);
|
|
|
|
|
window.__currentVaultId = _urlParams.get("vault") || "";
|
|
|
|
|
|
|
|
|
|
(function initVaultConfig() {
|
|
|
|
|
try {
|
|
|
|
|
const vaultParam = window.__currentVaultId
|
|
|
|
|
? "?vault=" + encodeURIComponent(window.__currentVaultId)
|
|
|
|
|
: "";
|
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open("GET", "/api/vault/info" + vaultParam, false);
|
|
|
|
|
xhr.send();
|
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
|
const info = JSON.parse(xhr.responseText);
|
|
|
|
|
window.__currentVaultId = info.id;
|
|
|
|
|
window.__vaultConfig = {
|
|
|
|
|
id: info.id,
|
|
|
|
|
path: "/",
|
|
|
|
|
};
|
|
|
|
|
console.log("[obsidian-bridge] Vault:", window.__vaultConfig);
|
2026-03-12 21:34:39 +01:00
|
|
|
} else {
|
|
|
|
|
console.warn("[obsidian-bridge] No vault found, will show manager");
|
2026-03-10 22:31:01 +01:00
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("[obsidian-bridge] Failed to fetch vault config:", e);
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
(function initVaultList() {
|
|
|
|
|
try {
|
|
|
|
|
const xhr = new XMLHttpRequest();
|
|
|
|
|
xhr.open("GET", "/api/vault/list", false);
|
|
|
|
|
xhr.send();
|
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
|
window.__vaultList = JSON.parse(xhr.responseText);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
window.__vaultList = [];
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
|
2026-03-07 12:23:08 +01:00
|
|
|
(function initMetadataCache() {
|
|
|
|
|
try {
|
2026-03-10 22:31:01 +01:00
|
|
|
const vaultParam = window.__currentVaultId
|
|
|
|
|
? "?vault=" + encodeURIComponent(window.__currentVaultId)
|
|
|
|
|
: "";
|
2026-03-07 12:23:08 +01:00
|
|
|
const xhr = new XMLHttpRequest();
|
2026-03-10 22:31:01 +01:00
|
|
|
xhr.open("GET", "/api/fs/tree" + vaultParam, false);
|
2026-03-07 12:23:08 +01:00
|
|
|
xhr.send();
|
|
|
|
|
if (xhr.status === 200) {
|
|
|
|
|
const tree = JSON.parse(xhr.responseText);
|
|
|
|
|
fsShim._metadataCache.populate(tree);
|
|
|
|
|
fsShim._metadataCache.set("", { type: "directory" });
|
|
|
|
|
fsShim._metadataCache.set("/", { type: "directory" });
|
|
|
|
|
console.log(
|
|
|
|
|
"[obsidian-bridge] Metadata cache populated:",
|
|
|
|
|
fsShim._metadataCache.size,
|
|
|
|
|
"entries",
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
console.error(
|
|
|
|
|
"[obsidian-bridge] Failed to fetch metadata tree:",
|
|
|
|
|
xhr.status,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("[obsidian-bridge] Failed to init metadata cache:", e);
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
|
2026-03-11 23:03:14 +01:00
|
|
|
installRequestUrlShim();
|
|
|
|
|
|
2026-03-07 12:23:08 +01:00
|
|
|
console.log("[obsidian-bridge] Shim loader initialized");
|