feat(lib/plugins): improve types and documentation
This commit is contained in:
parent
f5ed49d4e2
commit
601d5a28f5
3 changed files with 90 additions and 40 deletions
|
|
@ -1,32 +1,22 @@
|
|||
import { getPluginDependencies, pMetadata } from '.'
|
||||
import type {
|
||||
InitPluginApi,
|
||||
Plugin,
|
||||
PluginApi,
|
||||
PreInitPluginApi,
|
||||
} from '../types'
|
||||
import type { Plugin, PluginApiDecorator } from '../types'
|
||||
import type { AnyPlugin, InternalPluginMeta } from '.'
|
||||
|
||||
export type PluginApiDecoratorStore<
|
||||
A extends PreInitPluginApi | InitPluginApi | PluginApi,
|
||||
> = WeakMap<AnyPlugin, Parameters<A['decorate']>[0][]>
|
||||
export type PluginApiDecoratorStore<T extends 'PreInit' | 'Init' | 'Start'> =
|
||||
WeakMap<AnyPlugin, PluginApiDecorator<any, T>[]>
|
||||
|
||||
// Set of plugins that will always decorate the API of every other plugin.
|
||||
export const pImplicitDeps = new Set<AnyPlugin>()
|
||||
|
||||
export const pDecoratorsPreInit: PluginApiDecoratorStore<PreInitPluginApi> =
|
||||
new WeakMap()
|
||||
|
||||
export const pDecoratorsInit: PluginApiDecoratorStore<InitPluginApi> =
|
||||
new WeakMap()
|
||||
|
||||
export const pDecoratorsStart: PluginApiDecoratorStore<PluginApi> =
|
||||
export const pDecoratorsPreInit: PluginApiDecoratorStore<'PreInit'> =
|
||||
new WeakMap()
|
||||
export const pDecoratorsInit: PluginApiDecoratorStore<'Init'> = new WeakMap()
|
||||
export const pDecoratorsStart: PluginApiDecoratorStore<'Start'> = new WeakMap()
|
||||
|
||||
export function addPluginApiDecorator(
|
||||
store: PluginApiDecoratorStore<any>,
|
||||
plugin: AnyPlugin,
|
||||
decorator: Parameters<NonNullable<AnyPlugin['api']>['decorate']>[0],
|
||||
decorator: PluginApiDecorator<any, any>,
|
||||
) {
|
||||
let list = store.get(plugin)
|
||||
if (!list) {
|
||||
|
|
@ -38,9 +28,7 @@ export function addPluginApiDecorator(
|
|||
}
|
||||
|
||||
export function decoratePluginApi(
|
||||
store: PluginApiDecoratorStore<
|
||||
PreInitPluginApi | InitPluginApi | PluginApi
|
||||
>,
|
||||
store: PluginApiDecoratorStore<any>,
|
||||
plugin: Plugin<any, any>,
|
||||
meta: InternalPluginMeta,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
/**
|
||||
* The plugin flags.
|
||||
*/
|
||||
export const PluginFlags = {
|
||||
/**
|
||||
* The plugin is enabled.
|
||||
|
|
@ -18,6 +21,9 @@ export const PluginFlags = {
|
|||
EnabledLate: 1 << 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin status.
|
||||
*/
|
||||
export const PluginStatus = {
|
||||
PreIniting: 1 << 0,
|
||||
PreInited: 1 << 1,
|
||||
|
|
|
|||
|
|
@ -39,9 +39,62 @@ export interface UnscopedPluginApi<
|
|||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> extends UnscopedInitPluginApi<O> {}
|
||||
|
||||
/**
|
||||
* A cleanup function that can be registered to be called when the plugin is stopped.
|
||||
*/
|
||||
export type PluginCleanup = () => any
|
||||
/**
|
||||
* Registers cleanup functions to be called when the plugin is stopped.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* cleanup(unpatch)
|
||||
* cleanup(unsub)
|
||||
* ```
|
||||
*/
|
||||
export type PluginCleanupApi = (...fns: PluginCleanup[]) => void
|
||||
|
||||
/**
|
||||
* Decorates the plugin API for the dependents of the plugin with a decorator function.
|
||||
* @param decorator The decorator function to apply.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Your plugin's `init` function:
|
||||
* init({ decorate }) {
|
||||
* decorate((plugin, options) => {
|
||||
* plugin.api.customMethod = () => {
|
||||
* console.log('Custom method called!')
|
||||
* }
|
||||
* })
|
||||
* }
|
||||
*
|
||||
* // In another plugin, with your plugin as a dependency:
|
||||
* init({ customMethod }) {
|
||||
* customMethod() // Logs: "Custom method called!"
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export type PluginDecorateApi<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
S extends
|
||||
keyof PluginApiInLifecycleMap<O> = keyof PluginApiInLifecycleMap<O>,
|
||||
> = (decorator: PluginApiDecorator<O, S>) => void
|
||||
|
||||
/**
|
||||
* The decorator function that modifies the plugin API.
|
||||
*
|
||||
* @param plugin The plugin being decorated.
|
||||
* @param options The options the plugin passed.
|
||||
*
|
||||
* @see {@link PluginDecorateApi}
|
||||
*/
|
||||
export type PluginApiDecorator<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
S extends
|
||||
keyof PluginApiInLifecycleMap<O> = keyof PluginApiInLifecycleMap<O>,
|
||||
> = (plugin: Plugin<O, S>, options: O) => void
|
||||
|
||||
/**
|
||||
* The plugin API (very limited).
|
||||
* Available in the `preInit` phase.
|
||||
|
|
@ -49,9 +102,7 @@ export type PluginCleanupApi = (...fns: PluginCleanup[]) => void
|
|||
export interface PreInitPluginApi<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> {
|
||||
decorate(
|
||||
decorator: (plugin: Plugin<O, 'PreInit'>, options: O) => void,
|
||||
): void
|
||||
decorate: PluginDecorateApi<O, 'PreInit'>
|
||||
unscoped: UnscopedPreInitPluginApi
|
||||
cleanup: PluginCleanupApi
|
||||
plugin: Plugin
|
||||
|
|
@ -65,7 +116,7 @@ export interface PreInitPluginApi<
|
|||
export interface InitPluginApi<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> extends PreInitPluginApi<O> {
|
||||
decorate(decorator: (plugin: Plugin<O, 'Init'>, options: O) => void): void
|
||||
decorate: PluginDecorateApi<O, 'Init'>
|
||||
unscoped: UnscopedInitPluginApi
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +128,7 @@ export interface InitPluginApi<
|
|||
export interface PluginApi<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> extends InitPluginApi<O> {
|
||||
decorate(decorator: (plugin: Plugin<O, 'Start'>, options: O) => void): void
|
||||
decorate: PluginDecorateApi<O, 'Start'>
|
||||
unscoped: UnscopedPluginApi
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +148,9 @@ export interface PluginApi<
|
|||
// url: string
|
||||
// }
|
||||
|
||||
/**
|
||||
* The plugin manifest.
|
||||
*/
|
||||
export interface PluginManifest {
|
||||
/**
|
||||
* The unique identifier for the plugin.
|
||||
|
|
@ -142,6 +196,9 @@ export interface PluginOptions<
|
|||
SettingsComponent?: PluginSettingsComponent<O>
|
||||
}
|
||||
|
||||
/**
|
||||
* The plugin lifecycles.
|
||||
*/
|
||||
export interface PluginLifecycles<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> {
|
||||
|
|
@ -175,29 +232,22 @@ export interface PluginLifecycles<
|
|||
|
||||
export interface Plugin<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
S extends keyof PluginApiInStage<O> = keyof PluginApiInStage<O>,
|
||||
S extends
|
||||
keyof PluginApiInLifecycleMap<O> = keyof PluginApiInLifecycleMap<O>,
|
||||
> {
|
||||
// TODO(plugins): support plugin bundles
|
||||
// /**
|
||||
// * The plugin bundle this plugin belongs to.
|
||||
// */
|
||||
// bundle: PluginBundle
|
||||
/**
|
||||
* The plugin manifest.
|
||||
*/
|
||||
manifest: PluginManifest
|
||||
/**
|
||||
* The plugin lifecycles.
|
||||
*/
|
||||
lifecycles: PluginLifecycles<O>
|
||||
|
||||
/**
|
||||
* The plugin flags.
|
||||
* @see {@link PluginFlags}
|
||||
*/
|
||||
flags: number
|
||||
/**
|
||||
* The plugin status.
|
||||
* @see {@link PluginStatus}
|
||||
*/
|
||||
status: number
|
||||
|
|
@ -206,13 +256,11 @@ export interface Plugin<
|
|||
*/
|
||||
errors: unknown[]
|
||||
|
||||
/**
|
||||
* The plugin settings page.
|
||||
*/
|
||||
SettingsComponent?: PluginSettingsComponent<O>
|
||||
|
||||
/**
|
||||
* Disable the plugin. This will also stop the plugin if it is running.
|
||||
* Disable the plugin.
|
||||
* This will also stop the plugin if it is running.
|
||||
*/
|
||||
disable(): Promise<void>
|
||||
/**
|
||||
|
|
@ -225,16 +273,24 @@ export interface Plugin<
|
|||
*
|
||||
* Not recommended to use this directly.
|
||||
*/
|
||||
api: PluginApiInStage<O>[S]
|
||||
api: PluginApiInLifecycleMap<O>[S]
|
||||
}
|
||||
|
||||
type PluginApiInStage<O extends PluginApiExtensionsOptions> = {
|
||||
/**
|
||||
* The plugin API in a specific stage.
|
||||
*/
|
||||
export type PluginApiInLifecycleMap<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> = {
|
||||
Register: undefined
|
||||
PreInit: PreInitPluginApi<O>
|
||||
Init: InitPluginApi<O>
|
||||
Start: PluginApi<O>
|
||||
}
|
||||
|
||||
/**
|
||||
* The component that renders the plugin settings page.
|
||||
*/
|
||||
export interface PluginSettingsComponent<
|
||||
O extends PluginApiExtensionsOptions = PluginApiExtensionsOptions,
|
||||
> extends FunctionComponent<{ api: PluginApi<O> }> {}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue