Skip to content

API reference / @jsprismarine/kernel

@jsprismarine/kernel ​

The module kernel from the server re-architecture plan. It owns three things: module lifecycle, a token-keyed service registry, and the event bus. Worlds, sessions, commands, networking, and the tick loop are modules; first-party and third-party modules use the same API.

A module declares the service tokens it depends on, provides its own services during register(), and does its I/O in start(). The kernel validates the dependency graph, starts modules in dependency order, and stops them in reverse. A module whose start throws rolls back the ones already started, and a stop() during a start cancels it. A module can only use() tokens it declared, so the declared list is the real dependency graph, not documentation.

A kernel is built once and restarted freely: registerAll() runs every register() phase exactly once (and get() resolves provided services from then on), start() runs it first when needed and then runs the start phases, and stop() returns the kernel to the registered state so start() may run again. Module services carry over across restarts; listeners a module needs after a restart belong in start(), since the bus detaches a module's listeners when it stops.

typescript
import { createToken, Kernel } from '@jsprismarine/kernel';

const bans = createToken<BanService>('prismarine:bans');

const banModule = {
    id: 'prismarine:ban-module',
    register(ctx) {
        ctx.provide(bans, createBanService(ctx.config));
    }
} satisfies Module<BanConfig>;

const kernel = new Kernel({ config: { 'prismarine:ban-module': banConfig } });
kernel.register(banModule);
await kernel.start();
kernel.get(bans);
await kernel.stop();

Event listeners registered through a module's context are tagged with the module id and detached when that module stops. The bus is a minimal typed async emitter; prismarine's EventEmitter is adapted to it in a later phase.

Testing a module ​

@jsprismarine/kernel/testing starts one module against a kernel containing only its declared dependencies, each backed by a stub the test supplies:

typescript
import { startTestModule, stubService } from '@jsprismarine/kernel/testing';

const handle = await startTestModule(banModule, {
    stubs: [stubService(storage, inMemoryStorage())],
    config: banConfig
});

A stub for a token the module no longer declares fails, as does a declared dependency without a stub and any use() of an undeclared token, so the dependency list cannot drift from what the module actually uses.

Classes ​

Interfaces ​

EventBus ​

Defined in: packages/kernel/src/events.ts:17

The minimal typed emitter the kernel owns. Prismarine's richer EventEmitter is adapted to this interface in a later phase; keep this surface small.

Type Parameters ​

Events ​

Events extends EventMap = EventMap

Methods ​

emit() ​

emit<K>(event, ...args): Promise<void>

Defined in: packages/kernel/src/events.ts:27

Emits an event, awaiting each listener in subscription order.

Type Parameters ​
K ​

K extends string

Parameters ​
event ​

K

args ​

...Events[K]

Returns ​

Promise<void>

on() ​

on<K>(event, listener): () => void

Defined in: packages/kernel/src/events.ts:23

Subscribes to an event.

Type Parameters ​
K ​

K extends string

Parameters ​
event ​

K

listener ​

EventListener<Events[K]>

Returns ​

A function that removes this subscription.

() => void


KernelLogger ​

Defined in: packages/kernel/src/logger.ts:7

The minimal logging surface the kernel needs.

@jsprismarine/logger's Logger satisfies this structurally; the kernel does not depend on it so that hosts and tests can supply any implementation.

Methods ​

debug() ​

debug(message): void

Defined in: packages/kernel/src/logger.ts:9

Logs diagnostic detail.

Parameters ​
message ​

string

Returns ​

void

error() ​

error(message): void

Defined in: packages/kernel/src/logger.ts:15

Logs a failure.

Parameters ​
message ​

string

Returns ​

void

info() ​

info(message): void

Defined in: packages/kernel/src/logger.ts:11

Logs routine lifecycle information.

Parameters ​
message ​

string

Returns ​

void

warn() ​

warn(message): void

Defined in: packages/kernel/src/logger.ts:13

Logs a recoverable problem.

Parameters ​
message ​

string

Returns ​

void


KernelOptions ​

Defined in: packages/kernel/src/kernel.ts:19

Options for constructing a kernel.

Properties ​

config? ​

readonly optional config?: Readonly<Record<string, unknown>>

Defined in: packages/kernel/src/kernel.ts:21

Per-module configuration, keyed by module id.

logger? ​

readonly optional logger?: KernelLogger

Defined in: packages/kernel/src/kernel.ts:23

Base logger; module loggers are scoped from it. Defaults to the console.


Module ​

Defined in: packages/kernel/src/module.ts:49

A unit the kernel manages. register() constructs and provides services (no I/O); start() runs in dependency order and may open sockets, worlds, and files; stop() runs in reverse order.

Type Parameters ​

Config ​

Config = undefined

Events ​

Events extends EventMap = EventMap

Properties ​

dependencies? ​

readonly optional dependencies?: readonly ServiceToken<unknown>[]

Defined in: packages/kernel/src/module.ts:53

Tokens this module resolves with use(). The kernel orders start/stop from these.

id ​

readonly id: string

Defined in: packages/kernel/src/module.ts:51

Unique module id, also the key of its config slice.

Methods ​

register() ​

register(ctx): void | Promise<void>

Defined in: packages/kernel/src/module.ts:55

Phase 1: construct and provide() services. No I/O.

Parameters ​
ctx ​

ModuleContext<Config, Events>

Returns ​

void | Promise<void>

start()? ​

optional start(ctx): void | Promise<void>

Defined in: packages/kernel/src/module.ts:57

Phase 2, in dependency order: open sockets, worlds, files.

Parameters ​
ctx ​

ModuleContext<Config, Events>

Returns ​

void | Promise<void>

stop()? ​

optional stop(ctx): void | Promise<void>

Defined in: packages/kernel/src/module.ts:59

Teardown, in reverse dependency order.

Parameters ​
ctx ​

ModuleContext<Config, Events>

Returns ​

void | Promise<void>


ModuleContext ​

Defined in: packages/kernel/src/module.ts:17

The kernel capabilities handed to one module. Everything a module reaches — services, events, logging, configuration — flows through its context.

Type Parameters ​

Config ​

Config = undefined

Events ​

Events extends EventMap = EventMap

Properties ​

config ​

readonly config: Config

Defined in: packages/kernel/src/module.ts:41

This module's slice of the kernel configuration, keyed by module id.

events ​

readonly events: EventBus<Events>

Defined in: packages/kernel/src/module.ts:37

Event bus handle scoped to this module: listeners registered here are detached automatically when the module stops.

logger ​

readonly logger: KernelLogger

Defined in: packages/kernel/src/module.ts:39

Logger pre-scoped with the module id.

Methods ​

provide() ​

provide<T>(token, service, options?): void

Defined in: packages/kernel/src/module.ts:32

Publishes a service under a token. Legal only while this module's register() runs.

Type Parameters ​
T ​

T

Parameters ​
token ​

ServiceToken<T>

service ​

T

options? ​

ProvideOptions

Returns ​

void

Throws ​

KernelError outside the register phase, or when the token already has a provider and override is not set.

use() ​

use<T>(token): T

Defined in: packages/kernel/src/module.ts:24

Resolves a service this module declared in dependencies.

Type Parameters ​
T ​

T

Parameters ​
token ​

ServiceToken<T>

Returns ​

T

Throws ​

KernelError when the token is not declared, or (during the register phase) when its provider has not registered yet.


ProvideOptions ​

Defined in: packages/kernel/src/module.ts:8

Options for ModuleContext.provide.

Properties ​

override? ​

readonly optional override?: boolean

Defined in: packages/kernel/src/module.ts:10

Replace an existing provider for the same token instead of failing.


ServiceToken ​

Defined in: packages/kernel/src/token.ts:10

A typed key into the kernel's service registry.

The id is a namespaced string such as prismarine:worlds; two tokens with the same id name the same service. The phantom marker ties the service interface to the token at compile time only and never exists at runtime.

Type Parameters ​

T ​

T

Properties ​

[serviceType]? ​

readonly optional [serviceType]?: T

Defined in: packages/kernel/src/token.ts:14

Compile-time marker carrying the service type. Never set at runtime.

id ​

readonly id: string

Defined in: packages/kernel/src/token.ts:12

Namespaced identifier in namespace:name form, e.g. prismarine:worlds.

Type Aliases ​

EventListener ​

EventListener<Args> = (...args) => void | Promise<void>

Defined in: packages/kernel/src/events.ts:11

A listener for one event. A returned promise is awaited by emit.

Type Parameters ​

Args ​

Args extends readonly unknown[]

Parameters ​

args ​

...Args

Returns ​

void | Promise<void>


EventMap ​

EventMap = Record<string, readonly unknown[]>

Defined in: packages/kernel/src/events.ts:6

Maps event names to the argument tuples their listeners receive. Hosts extend this by declaring their own map and passing it as the kernel's Events generic.

Variables ​

consoleLogger ​

const consoleLogger: KernelLogger

Defined in: packages/kernel/src/logger.ts:21

The default kernel logger, backed by the global console.

Functions ​

createToken() ​

createToken<T>(id): ServiceToken<T>

Defined in: packages/kernel/src/token.ts:23

Creates a service token for the given namespaced id.

Type Parameters ​

T ​

T

Parameters ​

id ​

string

Namespaced identifier in namespace:name form.

Returns ​

ServiceToken<T>

Throws ​

Error when the id is not of the form namespace:name with both parts non-empty.


scopedLogger() ​

scopedLogger(base, scope): KernelLogger

Defined in: packages/kernel/src/logger.ts:33

Wraps a logger so every message is prefixed with a scope, e.g. a module id.

Parameters ​

base ​

KernelLogger

scope ​

string

Returns ​

KernelLogger