refactor utility functions

This commit is contained in:
Nystik
2026-06-03 01:15:27 +02:00
parent b90752e0ad
commit 05a3908a7a
10 changed files with 68 additions and 114 deletions

View File

@@ -1,5 +1,6 @@
import { showVaultManager } from "../ui-registry.js";
import { vaultService } from "@ignis/services";
import { arrayBufferToBase64, base64ToArrayBuffer } from "../util/base64.js";
const listeners = new Map();
@@ -85,29 +86,6 @@ const syncHandlers = {
resources: () => "",
};
function arrayBufferToBase64(buf) {
const bytes = new Uint8Array(buf);
let binary = "";
const chunk = 8192;
for (let i = 0; i < bytes.length; i += chunk) {
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
}
return btoa(binary);
}
function base64ToArrayBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
async function handleRequestUrl(requestId, request) {
try {
let body = request.body;

View File

@@ -1,17 +1,10 @@
// Shared echo suppression for file watcher.
// fs operations mark paths as "locally modified" so the watcher client
// can skip events that originated from this client.
// fs operations mark paths as "locally modified" so the watcher client can skip events that originated from this client.
import { normalize } from "../util/path.js";
const ECHO_SUPPRESS_MS = 1500;
const recentOps = new Map(); // normalized path -> timestamp
function normalize(p) {
return (p || "")
.replace(/\\/g, "/")
.replace(/^\/+/, "")
.replace(/\/+$/, "");
}
export function markLocalOp(path) {
recentOps.set(normalize(path), Date.now());
}

View File

@@ -5,19 +5,14 @@
// - 5-minute TTL per entry
// - Entries kept until TTL expires (plugins may read the same file multiple times)
import { normalize } from "../util/path.js";
const MAX_SIZE = 200 * 1024 * 1024;
const TTL_MS = 5 * 60 * 1000;
const cache = new Map(); // path -> { data, size, createdAt }
let currentSize = 0;
function normalize(p) {
return (p || "")
.replace(/\\/g, "/")
.replace(/^\/+/, "")
.replace(/\/+$/, "");
}
function evictExpired() {
const now = Date.now();

View File

@@ -2,9 +2,7 @@
// Path resolvers map logical paths to physical paths; read transforms post-process bytes after a read; write transforms pre-process bytes before a write.
// All hooks run at the shim's public surface, so caches and transport see only physical paths and as-stored bytes.
function normalize(p) {
return (p || "").replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
}
import { normalize } from "../util/path.js";
// --- Path resolvers ---

View File

@@ -1,8 +1,6 @@
// Virtual plugin source served from memory; the fs shim's read path checks here before disk.
function normalize(p) {
return (p || "").replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
}
import { normalize } from "../util/path.js";
const virtualFiles = new Map();

View File

@@ -4,6 +4,8 @@ import {
unregisterPopupWindow,
} from "./electron/remote/window.js";
import { showVaultManager } from "./ui-registry.js";
import { arrayBufferToBase64, base64ToArrayBuffer } from "./util/base64.js";
import { isSameOrigin } from "./util/url.js";
function installProcess() {
window.process = processShim;
@@ -115,51 +117,6 @@ function installWindowOpen() {
};
}
function arrayBufferToBase64(buf) {
const bytes = new Uint8Array(buf);
let binary = "";
const chunk = 8192;
for (let i = 0; i < bytes.length; i += chunk) {
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
}
return btoa(binary);
}
function base64ToArrayBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
export function isSameOrigin(url) {
if (
!url ||
url.startsWith("/") ||
url.startsWith("./") ||
url.startsWith("../")
) {
return true;
}
if (url.startsWith("data:") || url.startsWith("blob:")) {
return true;
}
try {
const parsed = new URL(url, window.location.origin);
return parsed.origin === window.location.origin;
} catch {
return true;
}
}
function installFetchShim() {
const originalFetch = window.fetch.bind(window);
window.__originalFetch = originalFetch;

View File

@@ -1,30 +1,8 @@
// Override window.requestUrl to proxy external requests through our server, bypassing CORS.
// Obsidian sets window.requestUrl in app.js, so we override it after app.js loads.
import { isSameOrigin } from "./globals.js";
function base64ToArrayBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
function arrayBufferToBase64(buf) {
const bytes = new Uint8Array(buf);
let binary = "";
const chunk = 8192;
for (let i = 0; i < bytes.length; i += chunk) {
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
}
return btoa(binary);
}
import { isSameOrigin } from "./util/url.js";
import { arrayBufferToBase64, base64ToArrayBuffer } from "./util/base64.js";
async function proxyRequestUrl(request) {
if (typeof request === "string") {

View File

@@ -0,0 +1,26 @@
// Base64 codec for the binary bodies exchanged with the server proxy.
function arrayBufferToBase64(buf) {
const bytes = new Uint8Array(buf);
let binary = "";
const chunk = 8192;
for (let i = 0; i < bytes.length; i += chunk) {
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
}
return btoa(binary);
}
function base64ToArrayBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
export { arrayBufferToBase64, base64ToArrayBuffer };

View File

@@ -0,0 +1,7 @@
// Canonical key form for fs paths: backslashes to forward slashes, no leading or trailing slash.
// Used by caches and registries that key on path.
function normalize(p) {
return (p || "").replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
}
export { normalize };

View File

@@ -0,0 +1,24 @@
// True when a request URL targets the page's own origin (so it can skip the cross-origin proxy).
function isSameOrigin(url) {
if (
!url ||
url.startsWith("/") ||
url.startsWith("./") ||
url.startsWith("../")
) {
return true;
}
if (url.startsWith("data:") || url.startsWith("blob:")) {
return true;
}
try {
const parsed = new URL(url, window.location.origin);
return parsed.origin === window.location.origin;
} catch {
return true;
}
}
export { isSameOrigin };