Skip to content

Services ​

Services let plugins cooperate (the framework's Service model). The framework provides built-in services; plugins can provide services to others (provide) and consume them via inject.

Built-in Services ​

ServiceDescription
storedata store (danmaku / videos / subtitles / kv)
modeldynamic tables (ctx.model.define, see Data Model)
appversion / pid / uptime() / getConfig() / saveConfig() / restart()
loggerleveled logs: debug/info/warn/error(scope, msg) + ring buffer
httpfetch wrapper: get/post/json (with timeout)
routerExpress routing (ctx.router.get/post/use...)

Services declared in manifest.inject are attached to ctx directly:

js
apply(ctx, config) {
  ctx.logger.info('hello', 'version ' + ctx.app.version);
}

Providing Services ​

Plugin A provides; plugin B declares the dependency (插件框架 ctx.provide):

js
// Plugin A: openvideo-plugin-stats
module.exports = {
  name: 'stats',
  provide: ['danmuStats'],
  apply(ctx, config) {
    const state = { count: 0 };
    ctx.on('danmu:send', () => { state.count++; });
    ctx.provide('danmuStats', { count: () => state.count });
  }
};
js
// Plugin B: "openvideoPlugin": { "inject": ["danmuStats"] }
module.exports = {
  apply(ctx, config) {
    setInterval(() => { ctx.danmuStats.count(); }, 60000);
  }
};

Resolution Rules ​

  • Enabling plugin B auto-enables and loads its provider A first (topological order)
  • Circular dependencies fail with a clear error
  • Missing providers fail the load with a clear reason
  • Built-in service names are reserved (store/model/app/logger/router/http/version...)

Runtime Access ​

js
const s = ctx.service('danmuStats');
if (s) s.count();

Framework Mapping ​

插件框架OpenVideoAPI
ctx.provide('name', service)same
inject: ['service']same (manifest.inject)
ctx.service accesssame

MIT License · Made with ♥ by yangyang8002