上下文
上下文是 Cordis 的核心对象:所有服务、事件和生命周期 API 都通过 ctx 访问。事件方法见事件,副作用与当前 fiber 见 Fiber,插件加载见注册表。
Cordis 插件的根依赖容器和子依赖容器。
上下文是一个代理:普通属性读取通过服务解析器进行,而 extend()、isolate() 和 intercept() 会创建有作用域的子上下文,且不修改其父上下文。
ctx.extend(meta?)
/**
* Create a child context with extra metadata on top of the current scope.
*
* The child prototypally inherits every property of this context; own
* properties of `meta` shadow the inherited ones. The parent is not mutated.
*
* @param meta — own properties (including symbol keys) to define on the child.
* @returns a child context inheriting from this one.
*/
extend(meta = {}): this在当前作用域之上创建一个带有额外元数据的子上下文。
子上下文通过原型继承当前上下文的所有属性;meta 的自有属性会遮蔽继承的同名属性。父上下文不会被修改。
meta:要在子上下文上定义的自有属性,包括以 symbol 为键的属性。
返回继承自当前上下文的子上下文。
ctx.isolate(name, label?)
/**
* Create a child context with an independent service scope for `name`.
*
* Below the returned context, reads and writes of the service `name`
* resolve against the new label instead of the parent's, so a different
* implementation can be provided without affecting the parent scope.
* Passing the same `label` to two `isolate()` calls joins their scopes.
*
* @param name — the service name to isolate.
* @param label — scope label to join; defaults to a fresh unique symbol.
* @returns a child context whose `name` service resolves in the new scope.
*/
isolate(name: string, label?: symbol)创建一个子上下文,使 name 拥有独立的服务作用域。
在返回的上下文之下,对服务 name 的读写会根据新标签解析,而不再根据父上下文的标签解析,因此可以提供不同的实现而不影响父作用域。将同一个 label 传给两次 isolate() 调用,可使二者加入同一作用域。
name:要隔离的服务名称。label:要加入的作用域标签;默认为一个新建的唯一 symbol。
返回一个子上下文,其 name 服务在新作用域中解析。
ctx.intercept(name, config)
/**
* Add service-specific intercept config for plugins started below this
* context.
*
* Plugins loaded under the returned context see `config` merged into the
* service's resolved config (ancestor entries first; see
* `Service[symbols.resolveConfig]`). The parent context is not affected.
*
* @param name — the service name whose config to intercept.
* @param config — the intercept config to merge for that service.
* @returns a child context carrying the additional intercept entry.
*/
intercept<K extends InjectKey>(name: K, config: Context[K] extends { [symbols.config]: infer T } ? T : never): this
intercept(name: string, config: any): this为在此上下文之下启动的插件添加服务专属的拦截配置。
在返回的上下文下加载的插件会看到 config 已合并到服务解析后的配置中(祖先条目在前;见 Service[symbols.resolveConfig])。父上下文不受影响。
name:要拦截其配置的服务名称。config:要为该服务合并的拦截配置。
返回一个携带额外拦截条目的子上下文。
ctx.root
/** The root context of the application (every child context shares it). @experimental */
root: this应用的根上下文,所有子上下文均共享它。@experimental
ctx.baseUrl
/** Base URL used to resolve relative plugin/module specifiers, if the runtime sets one. */
baseUrl?: string用于解析相对插件/模块说明符的基础 URL,前提是运行时设置了该值。
ctx.events
/** The event bus. Its methods are also mixed onto `ctx` (`ctx.on`, `ctx.emit`, ...). */
events: EventsService事件总线。它的方法也会混入 ctx(ctx.on、ctx.emit 等)。
ctx.logger
/** The logging service. Call `ctx.logger(name)` for a named logger. */
logger: LoggerService日志服务。调用 ctx.logger(name) 可获取具名 logger。
ctx.reflect
/** The reflection layer backing the context proxy (`ctx.get`, `ctx.provide`, ...). */
reflect: ReflectService为上下文代理提供支持的反射层(ctx.get、ctx.provide 等)。
ctx.registry
/** The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject`). */
registry: RegistryService插件注册表。它的方法会混入 ctx(ctx.plugin、ctx.inject)。
静态成员
Context.effect
/** Symbol key under which a disposer exposes its {@link EffectMeta} diagnostics tree. */
static readonly effect: unique symbol资源释放函数用于公开其 EffectMeta 诊断树的 symbol 键。
Context.filter
/** Symbol key for a context's listener filter, consulted on every event dispatch. */
static readonly filter: unique symbol上下文监听器过滤器的 symbol 键,每次分派事件时都会查询该过滤器。
Context.isolate
/** Symbol key of the isolation map (see the `Context[symbols.isolate]` property). */
static readonly isolate: unique symbol隔离映射的 symbol 键(见 Context[symbols.isolate] 属性)。
Context.intercept
/** Symbol key of the intercept map (see the `Context[symbols.intercept]` property). */
static readonly intercept: unique symbol拦截映射的 symbol 键(见 Context[symbols.intercept] 属性)。
Context.is(value)
/**
* Returns true for Cordis context proxies and context prototypes.
*
* Works across realms and across multiple copies of cordis, because the
* brand is keyed by a global symbol rather than by `instanceof`.
*
* @param value — the value to test.
* @returns `true` if `value` is a Cordis context, narrowing its type.
*/
static is(value: any): value is Context对于 Cordis 上下文代理和上下文原型,返回 true。
此方法可跨 realm 和多个 cordis 副本工作,因为其品牌标识以全局 symbol 为键,而不是通过 instanceof 判断。
value:要测试的值。
返回 true 时,value 是 Cordis 上下文,并会收窄其类型。
服务存储与混入
ctx.get(name, strict?)
/**
* Read a service from the store without the inject requirement.
*
* @param name — the service name.
* @param strict — when `true` (default), only return implementations
* whose providing fiber is currently active.
* @returns the service value, or `undefined` when not (yet) provided.
*/
get<K extends string & keyof this>(name: K, strict?: boolean): undefined | this[K]
get(name: string, strict?: boolean): any从存储中读取服务,无需满足注入要求。
name:服务名称。strict:设为true(默认值)时,仅返回其提供方 fiber 当前处于活动状态的实现。
返回服务值;如果尚未提供,则返回 undefined。
ctx.set(name, value)
/**
* Overwrite a provided service's value.
*
* Only the fiber that provided the service may set it; setting an
* unprovided name throws.
*
* @param name — the service name.
* @param value — the new service value.
*/
set<K extends string & keyof this>(name: K, value: undefined | this[K]): void
set(name: string, value: any): void覆盖已提供服务的值。
只有提供该服务的 fiber 才能设置它;设置尚未提供的名称会抛出异常。
name:服务名称。value:新的服务值。
ctx.provide(name, value)
/**
* Register a service implementation owned by the current fiber.
*
* The service becomes visible to dependents in the same isolation scope
* once the fiber is active; it is unregistered (waking dependents) when
* the returned disposer runs or the fiber unloads. Throws if the name is
* already provided in this scope or declared as an accessor.
*
* @param name — the service name.
* @param value — the service value.
* @returns a disposer that unregisters the service.
*/
provide<K extends string & keyof this>(name: K, value: undefined | this[K]): () => void
provide(name: string, value?: any): () => void注册一个归当前 fiber 所有的服务实现。
fiber 激活后,该服务对同一隔离作用域内的依赖方可见;当返回的资源释放函数运行或 fiber 卸载时,该服务会被取消注册,并唤醒依赖方。如果该名称已在此作用域中被提供,或已声明为访问器,则抛出异常。
name:服务名称。value:服务值。
返回一个用于取消注册该服务的资源释放函数。
ctx.accessor(name, options)
/**
* Define a computed context property backed by get/set hooks.
*
* The accessor is removed when the current fiber unloads. Throws if the
* name is already declared.
*
* @param name — the context property name.
* @param options — the `get` hook and optional `set` hook.
*/
accessor(name: string, options: Omit<Property.Accessor, 'type'>): void定义一个由 get/set 钩子支持的计算型上下文属性。
当前 fiber 卸载时会移除该访问器。如果该名称已被声明,则抛出异常。
name:上下文属性名称。options:get钩子和可选的set钩子。
ctx.mixin(name, mixins)
/**
* Expose selected members of a service directly on `ctx`.
*
* Each mixed-in key becomes an accessor that forwards to the service
* (binding methods to it), so e.g. `ctx.on` forwards to `ctx.events.on`.
* Mixins are removed when the current fiber unloads.
*
* @param name — the context property holding the source service.
* @param mixins — keys to forward, or a source-key → ctx-key map.
*/
mixin<K extends string & keyof this>(name: K, mixins: (keyof this & keyof this[K])[] | Dict<string>): void
mixin<T extends {}>(source: T, mixins: (keyof this & keyof T)[] | Dict<string>): void直接在 ctx 上公开服务的指定成员。
每个混入的键都会成为一个转发到该服务的访问器,并将方法绑定到该服务。例如,ctx.on 会转发到 ctx.events.on。当前 fiber 卸载时会移除这些混入。
name:存放源服务的上下文属性。mixins:要转发的键,或从源键到 ctx 键的映射。