Plugins
A plugin is an object with a setup(content) function that runs at construction time. It can register parsers, hook into watch events, and expose new methods on the Content instance: with full TypeScript inference for the consumer.
Built-in plugins
Usage
Plugins are passed in the plugins array. The Content instance calls setup(content) synchronously at construction, so any new methods are available immediately:
import { comarkContent } from 'comark-content'
import fs from 'comark-content/sources/fs'
import sqlite from 'comark-content/database/sqlite-node'
import sqlQuery from 'comark-content/plugins/sql-query'
import sqliteFullTextSearch from 'comark-content/plugins/sqlite-full-text-search'
const database = sqlite()
export const content = comarkContent({
source: fs('./content'),
plugins: [
sqlQuery({ database }),
sqliteFullTextSearch({ database }),
],
})
// `content.query` and `content.search` are added by the plugins above.
const rows = await content.query('default').where('data.title', 'LIKE', '%intro%').all()
const hits = await content.search(['default'], 'hello world')Plugin order
Plugins run in array order. If a plugin's setup reads another plugin's contribution, put it later:
plugins: [
sqlQuery({ database }), // adds content.query, content.prepareQueryIndex
customAnalytics({ content }), // can use content.query inside setup
]The Content instance doesn't enforce ordering: it's your responsibility when plugins depend on each other.
How plugins are typed
comarkContent infers methods added by plugins through the defineContentPlugin helper. You always get correct types on the returned Content: no manual augmentation needed.
const content = comarkContent({
plugins: [sqlQuery({ database }), sqliteFullTextSearch({ database })],
})
content.query // (source) => SourceQueryBuilder<...>
content.search // (sources, query, opts?) => Promise<SearchResult[]>
content.get // unchanged, with all base methodsSee Custom plugins for the full pattern.