Minimal, framework-agnostic SDK for building RefMD plugins.
- v0.1.x: API surface is small and focused on DOM primitives, a tiny UI kit, and host bridging helpers.
- No external deps, designed to be imported directly by plugins in the browser.
npm i @refmdio/plugin-sdk
Then in your plugin code:
import{createKit,resolveDocId}from'@refmdio/plugin-sdk'exportdefaultasyncfunctionmount(container: Element,host: any){constkit=createKit(host)conststate={docId: host?.context?.docId||resolveDocId(),text: ''}kit.store({
container,initialState: state,render: (s,set)=>kit.card({title: 'SDK Demo',body: kit.fragment(kit.input({value: s.text,onInput: (v)=>set({text: v})}),kit.button({label: 'Preview',onClick: async()=>{constout=document.createElement('div')container.appendChild(out)awaitkit.markdownPreview(s.text,out,{sanitize: true,absolute_attachments: true,doc_id: s.docId,base_origin: host.origin})}}))})})}- Core:
h,fragment,render,store - UI:
button,card,input,textarea,tokens - Utils:
markdownPreview(host, { text, options, target }),resolveDocId,escapeHtml - Host bridges:
createHostContext,normalizeExec,createRecordStore,createMarkdownRenderer,createMarkdownEditor,createUploader - Split editor bridge (v0.1.9+):
host.ui.mountSplitEditor(container, { docId, token, preview: { delegate }, document: { onReady } }) - Record store pagination (v0.1.10+):
createRecordStore(...).list({ limit, offset })passes pagination throughhost.records.list. - Document editor actions (v0.1.11+):
ctx.actions.exec(action, payload)runs a plugin-defined backend action. Use backend action effects for plugin state changes. - Document editor pane bridge: optional
canActivateDocumentEditor(ctx)andactivateDocumentEditor(ctx)exports can attach plugin behavior to the standard RefMD document editor. Usectx.documentPanes.register(...)for Backlinks-style right pane UI andctx.editorfor selection, insertion, reveal, content, and decorations.
Document editor API notes:
ctx.editor.setDecorations(ownerId, ...)andctx.editor.setHiddenRanges(ownerId, ...)use plugin-local owner IDs. RefMD scopes those IDs by plugin internally.ctx.records.list(kind, { limit, offset })supports pagination.ctx.kv.get(key)resolves to the stored value for document editor plugins.ctx.actions.exec(action, payload)is the write path for document editor plugins. Expose plugin-specific backend actions instead of mutating generic records or KV from the frontend.ctx.documentPanes.register({ icon })accepts a host-defined icon name string. Unknown values fall back to the host default.
Document editor pane plugins export named lifecycle functions:
importtype{DocumentEditorActivationContext}from'@refmdio/plugin-sdk'exportasyncfunctioncanActivateDocumentEditor(ctx: {document?: {type?: string|null}}){returnctx.document?.type==='markdown'}exportasyncfunctionactivateDocumentEditor(ctx: DocumentEditorActivationContext){constpane=ctx.documentPanes.register({id: 'comments',title: 'Comments',icon: 'message-square',render(container){container.textContent=ctx.document.getContent()return()=>{container.textContent=''}},})return()=>pane.dispose()}WC are not intended to be used directly by plugin authors; markdownPreview calls the host hydration routines under the hood.
npm run build
Outputs ESM + CJS + d.ts to dist/.
- Tag
v0.1.x→ GitHub Actions builds and publishes to npm.