@dokebi/core
v0.4.5
Published
Minimal composable Node.js application and plugin lifecycle framework.
Maintainers
Readme
@dokebi/core
The Dokebi runtime core, version 0.4.0 (unpublished, D-0067). What changed since 0.1.1 (the config API, plugin contract v2, the ready hook) is in the CHANGELOG. ESM only, Node.js >=24.0.0. The default CI runs Node 24; the actually verified range is in the repository records.
Installing core from npm also installs its regular dependency @dokebi/config. Config is registered in every app automatically from the list of required plugins, so you never install or register it yourself. Web, workers, DB, Redis, NATS and locks are optional plugins.
import { Application, loadConfig } from "@dokebi/core";
const document = await loadConfig("dokebi.yaml");
const app = new Application({ config: document.options });
await app.start();
try {
app.logger.log("info", "Application started");
} finally {
await app.stop();
}The YAML file has schemaVersion: 1 and an options object. app.config is a deep read-only snapshot of the whole options object and can be read right after construction and after stop. Passing a type guard to loadConfig checks the real values and narrows the type at once. Constructing an Application never searches for or reads a file; new Application() runs with an empty configuration.
The factory's app and the context.app of every hook are the same ApplicationView. The view is created once per app, frozen, and offers only state, config, logger and runtime; it has no start, stop, register or get. context.logger is the plugin's logger, context.app.logger the app's. A plugin factory takes { app, options?, entry? } only (the 0.1.x dependencies input is gone). Create new plugins with definePlugin.
An optional plugin provides metadata, setup and optionally start, ready and drain, and is registered with app.register. ready runs in dependency order right after every plugin's start has finished and the app is running. It is where a plugin starts taking outside traffic; a failure there is a start failure (PLUGIN_READY_FAILED, D-0034). After start, pass the same instance to app.get to get its API. Register cleanups with context.defer during setup or start. Stopping and cancelling are cooperative: a finished app cannot restart and running work is never killed.
Application, ConsoleLogger, CoreError and the config loading and validation API are exported from the package root. @dokebi/core/libraries has the categories hash, path, collections, time and diagnostics. sha256Stream and sha256File hash byte streams and files; portablePathKey is a normalised comparison key for portable relative paths. BoundedKeyedQueue keeps FIFO order and capacity for unique pending-item IDs, and Deadline lets several steps share one time budget. The queue is not a job runner or canceller, and Deadline has no timer and does not abort anything.
The stage-3 core primitives (D-0063) are additions only:
- The error base
DokebiError(code,plugin,fix,hint,status,data,details) and the shape checkisDokebiError, which needs no inheritance.CoreErroris a subclass. - The
diagnosticscategory:describeError,errorCode,logError,logDebugand one repeat suppressor,Repeats. defineOptionsandoptionbuild an option parser (no Ajv, path-taggedINVALID_OPTIONS) and the JSON Schema from one declaration, which goes straight intodefinePlugin({ options }). It supports discriminated unions and renamed keys (option.alias,option.renamed, D-0071).app.runtimeandcontext.runtimegive the runtime role (solo,primary,worker) andserving.definePoint,context.contributeandcontext.collectare contribution points: plugins exchange values without knowing each other's names, and contributors set up before collectors.defineProviderkeeps a provider package's name, package and range in one place, its./dependencysubpath.defineExtension,checkExtensionandcreateExtensionare the extension contract (D-0064): users subclass a plugin's small base class and override only its documented protected hooks.readExtensionEntry,addExtensionDependencies,isExtensionOfandownDataValue(core 0.4.2, D-0111) read a plugin's user entry module the same way in every plugin with an extension class.DriverBackendsandtransientTranslator(core 0.4.2, D-0111) are the shared machinery of plugins with named backends over registered drivers (dokebi-cache, dokebi-lock): driver registry, entry module and extension hooks, optional driver package loading, setup, cleanup and the provider, and the retryable 503 translator of their transient errors.- The test entry point
@dokebi/core/testingprovidescreateTestApplication(stops automatically, replaces providers with fakes by name, a slot for the web plugin'sinject) andcaptureLogger.
Encryption is not part of core. The optional package @dokebi/seal (D-0059, formerly @dokebi/crypto) owns it and the browser WebSocket client.
The log level comes from the environment variable DOKEBI_LOG_LEVEL (debug, info, warn, error, silent), then dokebi.yaml options.logging.level, then info. options.logging.plugins sets a level per plugin. When code passes a logger, that logger decides the app level. At debug, every plugin's lifecycle steps are logged with begin, end and elapsed time (D-0047).
Do not confuse configuration with connection objects, and never log a whole configuration that holds secrets. The current API exists since 0.2.0.
npm install @dokebi/core also brings @dokebi/config of the same version. Usually you create a project with the CLI (npx -y @dokebi/cli init <new folder>). The npm package dokebi is not the Dokebi CLI, so never use npx -y dokebi.
Core is MIT licensed. See the bundled AI guide, the public type declarations and the repository.
