Context

The context is the core Cordis object: every service, event, and lifecycle API is reached through ctx. Event methods are documented on Events, effects and the current fiber on Fiber, and plugin loading on Registry.

Root and child dependency containers for Cordis plugins.

A context is a proxy: normal property reads go through the service resolver, while extend(), isolate(), and intercept() create scoped child contexts without mutating their parent.

Source

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

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.

  • meta — own properties (including symbol keys) to define on the child.

Returns a child context inheriting from this one.

Source

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)

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.

  • name — the service name to isolate.
  • label — scope label to join; defaults to a fresh unique symbol.

Returns a child context whose name service resolves in the new scope.

Source

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

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.

  • name — the service name whose config to intercept.
  • config — the intercept config to merge for that service.

Returns a child context carrying the additional intercept entry.

Source

ctx.root

/** The root context of the application (every child context shares it). @experimental */
root: this

The root context of the application (every child context shares it). @experimental

Source

ctx.baseUrl

/** Base URL used to resolve relative plugin/module specifiers, if the runtime sets one. */
baseUrl?: string

Base URL used to resolve relative plugin/module specifiers, if the runtime sets one.

Source

ctx.events

/** The event bus. Its methods are also mixed onto `ctx` (`ctx.on`, `ctx.emit`, ...). */
events: EventsService

The event bus. Its methods are also mixed onto ctx (ctx.on, ctx.emit, ...).

Source

ctx.logger

/** The logging service. Call `ctx.logger(name)` for a named logger. */
logger: LoggerService

The logging service. Call ctx.logger(name) for a named logger.

Source

ctx.reflect

/** The reflection layer backing the context proxy (`ctx.get`, `ctx.provide`, ...). */
reflect: ReflectService

The reflection layer backing the context proxy (ctx.get, ctx.provide, ...).

Source

ctx.registry

/** The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject`). */
registry: RegistryService

The plugin registry. Its methods are mixed onto ctx (ctx.plugin, ctx.inject).

Source

Static members

Context.effect

/** Symbol key under which a disposer exposes its {@link EffectMeta} diagnostics tree. */
static readonly effect: unique symbol

Symbol key under which a disposer exposes its EffectMeta diagnostics tree.

Source

Context.filter

/** Symbol key for a context's listener filter, consulted on every event dispatch. */
static readonly filter: unique symbol

Symbol key for a context's listener filter, consulted on every event dispatch.

Source

Context.isolate

/** Symbol key of the isolation map (see the `Context[symbols.isolate]` property). */
static readonly isolate: unique symbol

Symbol key of the isolation map (see the Context[symbols.isolate] property).

Source

Context.intercept

/** Symbol key of the intercept map (see the `Context[symbols.intercept]` property). */
static readonly intercept: unique symbol

Symbol key of the intercept map (see the Context[symbols.intercept] property).

Source

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

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.

  • value — the value to test.

Returns true if value is a Cordis context, narrowing its type.

Source

Service store and mixins

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

Read a service from the store without the inject requirement.

  • name — the service name.
  • strict — when true (default), only return implementations whose providing fiber is currently active.

Returns the service value, or undefined when not (yet) provided.

Source

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

Overwrite a provided service's value.

Only the fiber that provided the service may set it; setting an unprovided name throws.

  • name — the service name.
  • value — the new service value.

Source

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

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.

  • name — the service name.
  • value — the service value.

Returns a disposer that unregisters the service.

Source

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

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.

  • name — the context property name.
  • options — the get hook and optional set hook.

Source

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

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.

  • name — the context property holding the source service.
  • mixins — keys to forward, or a source-key → ctx-key map.

Source

上下文

上下文是 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

事件总线。它的方法也会混入 ctxctx.onctx.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.getctx.provide 等)。

源码

ctx.registry

/** The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject`). */
registry: RegistryService

插件注册表。它的方法会混入 ctxctx.pluginctx.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:上下文属性名称。
  • optionsget 钩子和可选的 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 键的映射。

源码