mirror of
https://github.com/svm0n/datadeck.git
synced 2026-07-22 08:31:46 +00:00
Plugin is CSV-only. registerExtensions(["csv"]); SheetJS gone; the _csv_helpers/ mirror collapses to a single canonical CSV. Bundle drops 720 KB → 297 KB (-59%); parse+eval 0.9 ms → 0.5 ms. Migration plan was empirically validated before any data was touched: xlsx-to-csv-roundtrip.mjs reads each xlsx, Papa.unparse → Papa.parse, cell-by-cell compares the result to the source. All 10 checks passed across books / movies / quotes / dictionary / habit_tracker — proves the round-trip is lossless including multiline notes, stars, embedded punctuation, and unicode. migrate-xlsx-to-csv.mjs is the cutover: writes canonical csv, moves xlsx → Archive/<name>_pre-csv-migration.xlsx (recoverable), removes the _csv_helpers/ folder, rewrites data.json fileConfigs keys from *.xlsx → *.csv so per-file overrides survive. Code surface: - main.ts: onLoadFile / doSave / generateMobileFiles / renderAddEntryForm all collapsed to the csv-only path; loadXLSX + isXlsx removed. - mobile dashboards: csv-add and dataviewjs now point at the same canonical csv (used to be split because Dataview couldn't read xlsx). - regenerate-mobile-dashboards.mjs: drops the helper-folder path. - package.json: xlsx dependency removed (9 transitive packages gone). Also included in this commit (carried over from the same session): - mobile toolbar: ⚙ Columns / 📱 Mobile / 💾 Backup collapse into a ⋯ overflow menu on screens ≤ 600 px so the toolbar fits on one row. - mobile compact density: pure-CSS media-query switch for Library (2-col compact grid + mobile-md card style), tighter Kanban cards, smaller Table cells. Tests: 88 plugin + 21 mobile-dashboard, all green. Typecheck clean. Verified manually: open books.csv, edit a note (saves debounce), open on iPhone (compact library grid, ⋯ menu, csv-add form pre-fills). Class name XLSXCardView left in place to keep this commit focused on behavior; rename to CardView is a noted follow-up in handoff.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.8 KiB
JavaScript
62 lines
2.8 KiB
JavaScript
/**
|
|
* Approximate the cost Obsidian pays when enabling the plugin.
|
|
*
|
|
* Two numbers worth comparing across a refactor:
|
|
*
|
|
* Parse — time V8 spends turning the bundle text into bytecode the first
|
|
* time it sees it. This is what Obsidian's plugin-enable step pays
|
|
* on every launch. Lazy-parsed function bodies (uncalled functions)
|
|
* don't count here; they only get parsed on first call.
|
|
*
|
|
* Eval — time spent executing the bundle's top-level code. For Obsidian
|
|
* this is the plugin's `onload()` plus every module's top-level
|
|
* initialiser (Chart.js registers default components, etc.). Used
|
|
* to be more dramatic when SheetJS was in here too — the
|
|
* CSV-only migration retired that ~700 KB lazy chunk.
|
|
*
|
|
* The bundle uses Obsidian APIs and a few globals, so we stub `require` and
|
|
* `module` enough for the file to evaluate without throwing.
|
|
*/
|
|
import { readFileSync } from "fs";
|
|
import vm from "vm";
|
|
|
|
const path = process.argv[2] ?? "main.js";
|
|
const code = readFileSync(path, "utf8");
|
|
const sizeKB = (code.length / 1024).toFixed(1);
|
|
|
|
const RUNS = 5;
|
|
|
|
// ── Parse only (no execution) ────────────────────────────────────────────────
|
|
const parseTimes = [];
|
|
for (let i = 0; i < RUNS; i++) {
|
|
const t = performance.now();
|
|
new vm.Script(code, { filename: path });
|
|
parseTimes.push(performance.now() - t);
|
|
}
|
|
const parseAvg = parseTimes.reduce((a, b) => a + b, 0) / RUNS;
|
|
|
|
// ── Parse + top-level execute ────────────────────────────────────────────────
|
|
// Stub the bits the bundle pokes at module scope. We don't care about correctness
|
|
// here, only about reaching the end of top-level evaluation.
|
|
const stubObsidian = new Proxy({}, { get: () => class { register() {} addCommand() {} addSettingTab() {} } });
|
|
const evalTimes = [];
|
|
for (let i = 0; i < RUNS; i++) {
|
|
const ctx = vm.createContext({
|
|
module: { exports: {} },
|
|
exports: {},
|
|
require: (id) => (id === "obsidian" ? stubObsidian : {}),
|
|
globalThis: {},
|
|
process: { env: {} },
|
|
setTimeout, clearTimeout, setInterval, clearInterval, console,
|
|
});
|
|
const t = performance.now();
|
|
try { new vm.Script(code, { filename: path }).runInContext(ctx); }
|
|
catch { /* downstream throws are fine — we only care about reaching parse + top-level eval */ }
|
|
evalTimes.push(performance.now() - t);
|
|
}
|
|
const evalAvg = evalTimes.reduce((a, b) => a + b, 0) / RUNS;
|
|
|
|
console.log(`${path}`);
|
|
console.log(` Size: ${sizeKB} KB`);
|
|
console.log(` Parse only: ${parseAvg.toFixed(1)} ms (avg of ${RUNS})`);
|
|
console.log(` Parse+eval: ${evalAvg.toFixed(1)} ms (avg of ${RUNS})`);
|