I’ve finally figure out the way to fully publish API type definitions of plugins, including custom events hooked into Vault
/ metadataCache
.
Solutions
So currently, I’ve worked out two methods to provide API that works:
- Method 1: export API to global namespace directly (thanks @pjeby for the enlightenment)
- Method 2: access from
plugin.app.plugins.plugins["your-plugin-id"]?.api
For details, here is the example of a minimal project, with some tricks in typescirpt to keep types of on
args and trigger
args for events in sync:
Example for inter-plugin API declaration in obisidian (github.com)
Real-world demo
In folder-note-core, I’ve exposed getApi
, isPluginEnabled
and, registerApi
in index.ts, which use method 1 and method 2 underneath, and declare API in api.ts
Limitations & Proposal
However, method 1 is definitely polluting the global namespace, despite the convenience to detect and access API. It is risky if other plugins accidentally use the package that relies on a member exported to global, whose name coincides with the API name. And accessing API via method 2 is truly lengthy.
So here I propose two potential solutions for obsidian to improve:
- declare a member
pluginApi
in the global namespace, similar toapp
, so that plugin devs can add their API towindow.pluginApi.API_NAMEv3
to avoid pollution - add
loadApi(api: any)
andunloadApi(api: any)
method toPlugin
class and have an additional member in Plugin class:apis
to access other apis. The type ofapp.apis
can be an id-api map like:
(theMap<string, { version: string; [key: string]: any }>
version
can be used to check compatibility of API in case of breaking changes)