Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to latest version of hot reload master plugin #2179

Merged
merged 1 commit into from
Dec 30, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 58 additions & 31 deletions test-vault/.obsidian/plugins/hot-reload-master/main.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
const {Plugin, Notice} = require("obsidian");
const {Plugin, Notice, debounce} = require("obsidian");
const fs = require("fs");

const watchNeeded = window.process.platform !== "darwin" && window.process.platform !== "win32";

module.exports = class HotReload extends Plugin {

onload() { this.app.workspace.onLayoutReady( this._onload.bind(this) ); }
statCache = new Map(); // path -> Stat
queue = Promise.resolve();

async _onload() {
this.pluginReloaders = {};
this.inProgress = null;
await this.getPluginNames();
this.reindexPlugins = this.debouncedMethod(500, this.getPluginNames);
this.registerEvent( this.app.vault.on("raw", this.onFileChange.bind(this)) );
this.watch(".obsidian/plugins");
run(val, err) {
return this.queue = this.queue.then(val, err);
}

reindexPlugins = debounce(() => this.run(() => this.getPluginNames()), 500, true);
requestScan = debounce(() => this.run(() => this.checkVersions()), 250, true);

onload() {
app.workspace.onLayoutReady(async ()=> {
this.pluginReloaders = {};
this.inProgress = null;
await this.getPluginNames();
this.registerEvent( this.app.vault.on("raw", this.requestScan));
this.watch(".obsidian/plugins");
this.requestScan();
this.addCommand({
id: "scan-for-changes",
name: "Check plugins for changes and reload them",
callback: () => this.requestScan()
})
});
}

watch(path) {
Expand All @@ -25,6 +40,22 @@ module.exports = class HotReload extends Plugin {
}
}

async checkVersions() {
const base = this.app.plugins.getPluginFolder();
for (const dir of Object.keys(this.pluginNames)) {
for (const file of ["manifest.json", "main.js", "styles.css", ".hotreload"]) {
const path = `${base}/${dir}/${file}`;
const stat = await app.vault.adapter.stat(path);
if (stat) {
if (this.statCache.has(path) && stat.mtime !== this.statCache.get(path).mtime) {
this.onFileChange(path);
}
this.statCache.set(path, stat);
}
}
}
}

async getPluginNames() {
const plugins = {}, enabled = new Set();
for (const {id, dir} of Object.values(app.plugins.manifests)) {
Expand All @@ -50,34 +81,30 @@ module.exports = class HotReload extends Plugin {
if (base !== "main.js" && base !== "styles.css") return;
if (!this.enabledPlugins.has(plugin)) return;
const reloader = this.pluginReloaders[plugin] || (
this.pluginReloaders[plugin] = this.debouncedMethod(750, this.requestReload, plugin)
this.pluginReloaders[plugin] = debounce(() => this.run(() => this.reload(plugin), console.error), 750, true)
);
reloader();
}

requestReload(plugin) {
const next = this.inProgress = this.reload(plugin, this.inProgress);
next.finally(() => {if (this.inProgress === next) this.inProgress = null;})
}
async reload(plugin) {
const plugins = app.plugins;

// Don't reload disabled plugins
if (!plugins.enabledPlugins.has(plugin)) return;

await plugins.disablePlugin(plugin);
console.debug("disabled", plugin);

async reload(plugin, previous) {
const plugins = this.app.plugins;
// Ensure sourcemaps are loaded (Obsidian 14+)
const oldDebug = localStorage.getItem("debug-plugin");
localStorage.setItem("debug-plugin", "1");
try {
// Wait for any other queued/in-progress reloads to finish
await previous;
await plugins.disablePlugin(plugin);
console.debug("disabled", plugin);
await plugins.enablePlugin(plugin);
console.debug("enabled", plugin);
new Notice(`Plugin "${plugin}" has been reloaded`);
} catch(e) {}
}

debouncedMethod(ms, func, ...args) {
var timeout;
return () => {
if (timeout) clearTimeout(timeout);
timeout = setTimeout( () => { timeout = null; func.apply(this, args); }, ms);
} finally {
// Restore previous setting
if (oldDebug === null) localStorage.removeItem("debug-plugin"); else localStorage.setItem("debug-plugin", oldDebug);
}
console.debug("enabled", plugin);
new Notice(`Plugin "${plugin}" has been reloaded`);
}
}
}