plugin/plugin-lifecycle
Node-side helpers for the plugin-lifecycle cases every plugin should be tested against, and which every suite used to hand-roll or skip:
- reloadPlugin: disable the plugin, put its
data.jsoninto a given state — absent, as on a fresh install, or holding text that is not JSON, as after a crash mid-write or a bad Sync merge — and enable it again. The enable happens with the vault open and its layout ready, so it is also the “turned on later, in settings” path. - detectPluginUnloadLeak: disable the plugin and report whether its instance was garbage collected. A plugin that leaves a listener, an interval or a patch behind on unload keeps its instance alive through it, and every disable and re-enable then leaks a whole plugin.
Both run on the Node side, like app-config.ts, because each is several evaluations with work in between (a garbage collection is a CDP command, not something a renderer closure can ask for).
Interfaces
Section titled “Interfaces”| Interface | Description |
|---|---|
| DetectPluginUnloadLeakParams | Parameters for detectPluginUnloadLeak. |
| PluginLifecycleTarget | Which plugin, and where. Shared by both helpers here. |
| PluginUnloadLeakResult | What detectPluginUnloadLeak found. |
| ReloadPluginParams | Parameters for reloadPlugin. |
| ReloadPluginResult | What reloadPlugin found when it enabled the plugin again. |
Functions
Section titled “Functions”| Function | Description |
|---|---|
| detectPluginUnloadLeak | Disables a plugin, checks whether its instance is garbage collected, and enables it again. The instance is the sentinel: everything a plugin owns is reachable only through it, so a collected instance means the unload released the plugin’s whole graph, and a surviving one means something outside the plugin still holds it. A WeakRef gives an exact answer where a heap measurement would be noisy. Needs a transport that can force a garbage collection (collectGarbage): desktop, and Android over local adb. |
| reloadPlugin | Disables a plugin, optionally puts its data.json into a given state, and enables it again. Covers three cases a suite otherwise never reaches, because the setup always enables the plugin once, at startup, with whatever settings it last saved: - a fresh install: shouldRemoveDataJson: true, so loadData() resolves null; - a corrupt file: dataJsonText: '\{ not json', so loadData() resolves undefined (Obsidian’s readJson logs the parse error and returns nothing), and a plugin that then calls saveData() overwrites the user’s file; - enabled later: the enable runs with the layout already ready, so onLayoutReady fires at once. The result is returned rather than thrown, because a test of a corrupt data.json asserts on exactly whether the plugin’s onload survived it. |