Skip to content
源码版本47f9438 (dsh@0.1)

Lifecycle and Middleware

Every ctx.plugin() returns a Fiber, which is a finite state machine. All registrations (ctx.on / ctx.effect / ctx.provide) are effects, recorded into the fiber's _disposables list and run in reverse order on unload. The event system's emit / parallel / serial / bail / waterfall dispatches cover all communication patterns: notification / aggregation / serial / short-circuit / middleware.

The Fiber State Machine

vendor/cordis/src/fiber.ts:147-154 defines const enum FiberState:
PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED
                    ↓ (failure)
                   FAILED

Six states: PENDING / LOADING / ACTIVE / FAILED / DISPOSED / UNLOADING, each with clear semantics.

Fiber Fields

The class Fiber fields at vendor/cordis/src/fiber.ts:184-194: uid / ctx / config / state / dispose / store / inject / runtime, with _disposables being a DisposableList.

Fiber Constructor

vendor/cordis/src/fiber.ts:222-263:
  • Creates the child ctx.
  • Injects the intercept config.
  • Sets up _runner.execute (new for classes, direct call for functions).
  • Registers fiber.dispose as an effect of the parent.

Effect: Reversible Registration

effect(execute, label) at vendor/cordis/src/fiber.ts:415-560 supports five Effect shapes:

  1. sync — synchronous function
  2. async — async function
  3. promise — a Promise
  4. Iterable — iterable (each next() yields a disposer)
  5. AsyncIterable — async iterable

Disposers fire once; the effectInertia WeakMap lets external code join an already-running cleanup.

Key point: Effect is synonymous with "reversible registration". ctx.on internally calls register, which in turn calls this.ctx.fiber.effect(...) to enqueue the listener and return a disposer — that is why "unload = cleanup" is automatic.

Reload and Unload

_reload

_reload() at vendor/cordis/src/fiber.ts:646-673:

  1. Waits a frame so the old epoch is invalidated.
  2. _resolveConfig (runs the internal/config waterfall).
  3. _execute(runner).
  4. Clears _error.

_unload

_unload() at vendor/cordis/src/fiber.ts:675-696:

ts
Promise.all(this._disposables.clear().map(...))

Runs disposers concurrently (reverse order is handled inside DisposableList), swallows errors and logs them.

Disposer ordering: inside a single effect, reverse order; across multiple async disposers, concurrent. If strict serial execution is required, await inside a single disposer.

update (the HMR mount point)

update(config, noSave) at vendor/cordis/src/fiber.ts:736-753:

ts
update(config, noSave) {
  ctx.waterfall(this, 'internal/update', config, noSave, () => restart())
}

The internal/update waterfall is the mount point for HMR and Loader persistence: the loader writes back entry.options.config = config and calls tree.write() here; HMR decides here whether to restart.

Event System: Five Dispatches

interface Events at vendor/cordis/src/events.ts:329-352 has eight built-in framework events:

internal/plugin | internal/status | internal/config | internal/update
internal/get    | internal/set    | internal/listener | internal/dispatch

The doc mode is annotated with @mode.

dispatch and filter

dispatch(type, args) at vendor/cordis/src/events.ts:165-175: strips thisArg / name, fires internal/dispatch, filters listeners by Context.filter.

waterfall: the Middleware Model

waterfall(...args) at vendor/cordis/src/events.ts:234-243:

ts
waterfall(...args) {
  const next = args.pop()
  // outer listener runs first, next() chains the delegation
  // not calling next() means veto
}

This is the classic onion-model middleware — the outer layer runs first, delegates inward via next(), and not calling next() is a veto.

Framework's Own Event Priority

When EventsService is constructed it auto-registers an internal/listener bail listener that re-routes listeners for internal/update into a separate fiber._hooks store — this is how "the framework's own events get priority", preventing plugin listeners from interfering with internal state changes.

Unofficial community learning site. Content based on the MIT-licensed deepseek-ai/deepseek-harness source. · Privacy · Terms · About