Skip to content

@btravstack/core


@btravstack/core ​

Classes ​

HealthCheckFailed ​

Defined in: packages/core/src/health.ts:19

A component could not answer for itself. Modeled rather than thrown, because a health check that throws is a bug in the check; one that fails is the news /healthz exists to carry.

Extends ​

  • TaggedErrorInstance<"HealthCheckFailed", { reason: string; }>

Constructors ​

Constructor ​
ts
new HealthCheckFailed(args): HealthCheckFailed;

Defined in: node_modules/.pnpm/unthrown@5.12.1/node_modules/unthrown/dist/index.d.mts:2386

Parameters ​
ParameterType
argsobject & object
Returns ​

HealthCheckFailed

Inherited from ​

TaggedError("HealthCheckFailed")<{ readonly reason: string; }>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
_tagreadonly"HealthCheckFailed"TaggedError("HealthCheckFailed")._tagnode_modules/.pnpm/unthrown@5.12.1/node_modules/unthrown/dist/index.d.mts:2363
cause?publicunknownTaggedError("HealthCheckFailed").causenode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts:24
messagepublicstringTaggedError("HealthCheckFailed").messagenode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1075
namepublicstringTaggedError("HealthCheckFailed").namenode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1074
reasonreadonlystringTaggedError("HealthCheckFailed").reasonpackages/core/src/health.ts:20
stack?publicstringTaggedError("HealthCheckFailed").stacknode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1076

HealthChecks ​

Defined in: packages/core/src/health.ts:55

The set port every starter contributes to and the kernel reads whole.

A set port rather than a registry the kernel hands out: a starter DECLARES its check the same way it declares anything else, and a starter an application never composed contributes nothing — no registration call to forget, and no order to get wrong.

Extends ​

  • PortInstance<"HealthChecks", readonly HealthCheck[]> & object

Constructors ​

Constructor ​
ts
new HealthChecks(): HealthChecks;

Defined in: packages/di/dist/index.d.mts:29

Returns ​

HealthChecks

Inherited from ​

Port.many("HealthChecks")<HealthCheck>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"HealthChecks"Port.many("HealthChecks").[ID]packages/di/dist/index.d.mts:11
[MANY]readonlytruePort.many("HealthChecks").[MANY]packages/di/dist/index.d.mts:30
[SERVICE]readonlyreadonly HealthCheck[]Port.many("HealthChecks").[SERVICE]packages/di/dist/index.d.mts:12
manystatic readonlytruePort.many("HealthChecks").manypackages/di/dist/index.d.mts:33
portIdstatic readonly"HealthChecks"Port.many("HealthChecks").portIdpackages/di/dist/index.d.mts:32

Instrumentations ​

Defined in: packages/core/src/instrumentation.ts:32

The set port a package contributes its instrumentation to.

Nothing collects it unless an OTel SDK is composed, which is the point: a starter DECLARES what it can instrument, and composing @btravstack/observability/otel is what turns the declarations on. A graph without it registers nothing and pays nothing — the Spring Boot starter shape, in one port.

Extends ​

Constructors ​

Constructor ​
ts
new Instrumentations(): Instrumentations;

Defined in: packages/di/dist/index.d.mts:29

Returns ​

Instrumentations

Inherited from ​

Port.many("Instrumentations")<InstrumentationLoader>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"Instrumentations"Port.many("Instrumentations").[ID]packages/di/dist/index.d.mts:11
[MANY]readonlytruePort.many("Instrumentations").[MANY]packages/di/dist/index.d.mts:30
[SERVICE]readonlyreadonly InstrumentationLoader[]Port.many("Instrumentations").[SERVICE]packages/di/dist/index.d.mts:12
manystatic readonlytrueHealthChecks.manypackages/di/dist/index.d.mts:33
portIdstatic readonly"Instrumentations"Port.many("Instrumentations").portIdpackages/di/dist/index.d.mts:32

Logger ​

Defined in: packages/core/src/observability.ts:58

The application's logger, as a port — declared here and implemented in @btravstack/observability, because a contract every package may depend on has to be reachable without installing an implementation, and because the correlation an implementation stamps per line is the kernel's own ambient record.

An implementation must not throw: a logger that throws turns an observability problem into an outage. Synchronous void, not an AsyncResult — thesis 6's one deliberate exemption, since a lost line is not a modeled error.

Extends ​

Constructors ​

Constructor ​
ts
new Logger(): Logger;

Defined in: packages/di/dist/index.d.mts:15

Returns ​

Logger

Inherited from ​

Port("Logger")<LoggerService>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"Logger"Port("Logger").[ID]packages/di/dist/index.d.mts:11
[SERVICE]readonlyLoggerServicePort("Logger").[SERVICE]packages/di/dist/index.d.mts:12
portIdstatic readonly"Logger"Port("Logger").portIdpackages/di/dist/index.d.mts:16

Meter ​

Defined in: packages/core/src/observability.ts:114

The application's meter, as a port. See Tracer for why it does not name a vendor.

Extends ​

Constructors ​

Constructor ​
ts
new Meter(): Meter;

Defined in: packages/di/dist/index.d.mts:15

Returns ​

Meter

Inherited from ​

Port("Meter")<MeterService>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"Meter"Port("Meter").[ID]packages/di/dist/index.d.mts:11
[SERVICE]readonlyMeterServicePort("Meter").[SERVICE]packages/di/dist/index.d.mts:12
portIdstatic readonly"Meter"Port("Meter").portIdpackages/di/dist/index.d.mts:16

Observers ​

Defined in: packages/core/src/observation.ts:87

The set port a starter contributes its observability to, and reads whole.

Called at the START and answering a finisher, rather than told about a finished operation. That is what lets an observer open a span before the work and end it after — a span reconstructed afterwards from a duration is not the parent of anything that ran inside it.

A set port rather than a Meter in every starter's needs: an observer package an application never composed contributes nothing, and a starter costs a graph no ports to have observability available. That is the difference between "instrumented by default" and "instrumented if you asked for observability", and only the second is free.

A module that reads this port contributes a no-op member of its own, the way otel() does for Instrumentations: a collector depending on a set port NOTHING provides is an unmet dependency, at plan time and in Needs alike. Several no-ops in one graph cost a call each and nothing else.

Extends ​

  • PortInstance<"Observers", readonly ((operation) => Settle)[]> & object

Constructors ​

Constructor ​
ts
new Observers(): Observers;

Defined in: packages/di/dist/index.d.mts:29

Returns ​

Observers

Inherited from ​

Port.many("Observers")<(operation: Operation) => Settle>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"Observers"Port.many("Observers").[ID]packages/di/dist/index.d.mts:11
[MANY]readonlytruePort.many("Observers").[MANY]packages/di/dist/index.d.mts:30
[SERVICE]readonlyreadonly ((operation) => Settle)[]Port.many("Observers").[SERVICE]packages/di/dist/index.d.mts:12
manystatic readonlytruePort.many("Observers").manypackages/di/dist/index.d.mts:33
portIdstatic readonly"Observers"Port.many("Observers").portIdpackages/di/dist/index.d.mts:32

RuntimeStartFailed ​

Defined in: packages/core/src/runtime.ts:17

Extends ​

  • TaggedErrorInstance<"RuntimeStartFailed", { cause: unknown; runtime: string; }>

Constructors ​

Constructor ​
ts
new RuntimeStartFailed(args): RuntimeStartFailed;

Defined in: node_modules/.pnpm/unthrown@5.12.1/node_modules/unthrown/dist/index.d.mts:2386

Parameters ​
ParameterType
argsobject & object
Returns ​

RuntimeStartFailed

Inherited from ​

TaggedError("RuntimeStartFailed")<{ readonly runtime: string; readonly cause: unknown; }>.constructor

Properties ​

PropertyModifierTypeOverridesInherited fromDefined in
_tagreadonly"RuntimeStartFailed"-TaggedError("RuntimeStartFailed")._tagnode_modules/.pnpm/unthrown@5.12.1/node_modules/unthrown/dist/index.d.mts:2363
causepublicunknown-HealthCheckFailed.causenode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es2022.error.d.ts:24
messagepublicstringTaggedError("RuntimeStartFailed").message-packages/core/src/runtime.ts:21
namepublicstring-TaggedError("RuntimeStartFailed").namenode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1074
runtimereadonlystring-TaggedError("RuntimeStartFailed").runtimepackages/core/src/runtime.ts:18
stack?publicstring-TaggedError("RuntimeStartFailed").stacknode_modules/.pnpm/typescript@6.0.3/node_modules/typescript/lib/lib.es5.d.ts:1076

Tracer ​

Defined in: packages/core/src/observability.ts:88

The application's tracer, as a port — declared without naming OpenTelemetry, because a port typed as a vendor's type points the dependency arrow outwards and makes the whole family install that vendor.

Extends ​

Constructors ​

Constructor ​
ts
new Tracer(): Tracer;

Defined in: packages/di/dist/index.d.mts:15

Returns ​

Tracer

Inherited from ​

Port("Tracer")<TracerService>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"Tracer"Port("Tracer").[ID]packages/di/dist/index.d.mts:11
[SERVICE]readonlyTracerServicePort("Tracer").[SERVICE]packages/di/dist/index.d.mts:12
portIdstatic readonly"Tracer"Port("Tracer").portIdpackages/di/dist/index.d.mts:16

UnitOverrides ​

Defined in: packages/core/src/unit-overrides.ts:16

Providers substituted inside a runtime's unit modules, keyed by the kind the runtime declares on Runtime.units — test-facing: @btravstack/testing's overridden(root, providers, { unit }) is the one contributor, and a production root never names it.

Each provider must already carry di's override brand. The kernel applies them at boot, before the runtime starts: every kind named must be one the runtime binds, and every port must be one that kind's module provides, or the boot is a defect — the same drift gate a root-level override has.

Extends ​

  • PortInstance<"UnitOverrides", readonly Readonly<Record<string, readonly AnyProvider[]>>[]> & object

Constructors ​

Constructor ​
ts
new UnitOverrides(): UnitOverrides;

Defined in: packages/di/dist/index.d.mts:29

Returns ​

UnitOverrides

Inherited from ​

Port.many("UnitOverrides")<Readonly<Record<string, readonly AnyProvider[]>>>.constructor

Properties ​

PropertyModifierTypeInherited fromDefined in
[ID]readonly"UnitOverrides"Port.many("UnitOverrides").[ID]packages/di/dist/index.d.mts:11
[MANY]readonlytruePort.many("UnitOverrides").[MANY]packages/di/dist/index.d.mts:30
[SERVICE]readonlyreadonly Readonly<Record<string, readonly AnyProvider[]>>[]Port.many("UnitOverrides").[SERVICE]packages/di/dist/index.d.mts:12
manystatic readonlytruePort.many("UnitOverrides").manypackages/di/dist/index.d.mts:33
portIdstatic readonly"UnitOverrides"Port.many("UnitOverrides").portIdpackages/di/dist/index.d.mts:32

Type Aliases ​

AnyUnitModule ​

ts
type AnyUnitModule = Module<never, never, unknown>;

Defined in: packages/core/src/unit-record.ts:17

A module a runtime's unit option may bind, as the upper bound a starter constrains its own Unit type parameter to. Module's _exports channel is contravariant, so Exports = never — never unknown — is what makes a REAL module's own (necessarily narrower) export type assignable to this bound: (x: Concrete) => void is assignable to (x: never) => void, not to (x: unknown) => void.


Attributes ​

ts
type Attributes = Readonly<Record<string, string | number | boolean | undefined>>;

Defined in: packages/core/src/observability.ts:22

What a line, a span or a measurement carries besides itself: a flat record of scalars.

Flat and scalar on purpose. A nested object is where a field's name stops being stable, and an unknown value is where a logger starts stringifying whatever it is handed — which is how a log call becomes the thing that throws. A failure has a channel of its own, cause.


Clock ​

ts
type Clock = object;

Defined in: packages/core/src/clock.ts:5

Properties ​

PropertyModifierTypeDefined in
nowreadonly() => numberpackages/core/src/clock.ts:6
sleepreadonly(ms, signal?) => AsyncResult<void, never>packages/core/src/clock.ts:7

ComponentHealth ​

ts
type ComponentHealth = object;

Defined in: packages/core/src/health.ts:57

Properties ​

PropertyModifierTypeDescriptionDefined in
namereadonlystring-packages/core/src/health.ts:58
reason?readonlystringPresent only when the component is unhealthy.packages/core/src/health.ts:61
statusreadonly"healthy" | "unhealthy"-packages/core/src/health.ts:59

Counter ​

ts
type Counter = object;

Defined in: packages/core/src/observability.ts:91

A monotonic count.

Properties ​

PropertyModifierTypeDefined in
addreadonly(value, attributes?) => voidpackages/core/src/observability.ts:91

DrainReport ​

ts
type DrainReport = object;

Defined in: packages/core/src/drain.ts:7

Properties ​

PropertyModifierTypeDescriptionDefined in
abandonedreadonlynumberUnits still open at the deadline. The exit-code decision reads this. It means "no longer AWAITED", not "did not finish". The kernel stops waiting and aborts each unit's signal; it cannot cancel work, and the transport underneath keeps running on its own clock. An abandoned AMQP delivery usually goes on to be acked, and an abandoned Temporal activity goes on to complete — after this report said they did not. The consequence, stated because nothing else states it: the process may not end by itself. runMain sets an exit code and deliberately never calls process.exit(), so the process ends when the event loop empties — and a transport still winding down is holding it open. Nothing here terminates it. Under a Kubernetes-initiated shutdown that ends at terminationGracePeriodSeconds, with SIGKILL, so exit 2 is what the report SAYS rather than what the orchestrator observes. Outside that lifecycle there is no SIGKILL: the process simply stays alive until the transport is done. kubectl logs --previous carries the report either way, which is what it is for.packages/core/src/drain.ts:38
completedreadonlynumberUnits that closed during the drain, counted from a monotonic total. It may exceed inFlightAtStart when in-flight work spawned more units — honest reporting, where inFlightAtStart - abandoned can go negative.packages/core/src/drain.ts:15
inFlightAtStartreadonlynumberUnits in flight when the drain began.packages/core/src/drain.ts:9

EventSink ​

ts
type EventSink = (event) => void;

Defined in: packages/core/src/events.ts:46

Parameters ​

ParameterType
eventKernelEvent

Returns ​

void


ExitReport ​

ts
type ExitReport = object;

Defined in: packages/core/src/start.ts:66

Properties ​

PropertyModifierTypeDescriptionDefined in
abandonedAt?readonly"build" | "stop"Set when the kernel stopped WAITING for a phase that has no deadline of its own — "stop" for a Serving.stop or a finaliser still running at stopTimeoutMs, "build" for a graph abandoned before it ever served. It is "stopped waiting", not "cancelled": nothing here can cancel a finaliser, so a wedged one can still hold the event loop past this report and end in SIGKILL. What the field buys is that the report EXISTS and says which phase ran long — where the alternative was a process stuck in stopping with no event, no code and no exit report at all.packages/core/src/start.ts:84
drainreadonlyDrainReport | undefined-packages/core/src/start.ts:70
reasonreadonly"signal" | "runtimeStopped" | "uncaught"-packages/core/src/start.ts:67
teardownErrorsreadonlyreadonly TeardownError[]-packages/core/src/start.ts:71
unexpectedRuntimeStop?readonlytrueThe runtime stopped before any caller or signal requested shutdown; runMain exits nonzero.packages/core/src/start.ts:69
uptimeMsreadonlynumber-packages/core/src/start.ts:72

HealthCheck ​

ts
type HealthCheck = object;

Defined in: packages/core/src/health.ts:24

One contribution: what to call the component, and how to ask it.

Properties ​

PropertyModifierTypeDescriptionDefined in
checkreadonly() => AsyncResult<void, HealthCheckFailed>-packages/core/src/health.ts:26
namereadonlystring-packages/core/src/health.ts:25
readiness?readonly| boolean | { intervalMs: number; }Opt into gating /readyz. true caches the result for 1000 ms; an object selects a positive, finite interval. Concurrent probes share one evaluation, and /healthz uses the same cache for this check. Omitted or false leaves readiness independent of this component.packages/core/src/health.ts:44
timeoutMs?readonlynumberHow long this component gets to answer, overriding DEFAULT_HEALTH_TIMEOUT_MS. It is on the CONTRIBUTION because only the contributor knows: a SELECT 1 over a warm pool and an SMTP relay's greeting are two orders of magnitude apart, and one number for both is either a false unhealthy or a probe that outlives the orchestrator's patience. A component with nothing to say about its own latency omits it.packages/core/src/health.ts:37

HealthReport ​

ts
type HealthReport = object;

Defined in: packages/core/src/health.ts:64

Properties ​

PropertyModifierTypeDefined in
componentsreadonlyreadonly ComponentHealth[]packages/core/src/health.ts:66
statusreadonly"healthy" | "unhealthy"packages/core/src/health.ts:65

Histogram ​

ts
type Histogram = object;

Defined in: packages/core/src/observability.ts:94

A distribution of measurements.

Properties ​

PropertyModifierTypeDefined in
recordreadonly(value, attributes?) => voidpackages/core/src/observability.ts:94

InfrastructureExports ​

ts
type InfrastructureExports<I, P> = readonly VisibleInfrastructure<typeof Logger | typeof HealthChecks, Available<I, P>>[];

Defined in: packages/core/src/infrastructure-exports.ts:19

Kernel infrastructure publicly available through an application root.

Type Parameters ​

Type Parameter
I extends readonly AnyModule[]
P extends readonly AnyProvider[]

InstrumentationLoader ​

ts
type InstrumentationLoader = () => Promise<unknown>;

Defined in: packages/core/src/instrumentation.ts:21

One package's offer of an OpenTelemetry instrumentation.

Async, and answers undefined rather than failing, because the package supplying the instrumentation is an OPTIONAL peer. A starter cannot know at composition time whether the consumer installed it, so it contributes the ATTEMPT and the collector drops what did not load — which is what lets a starter declare an instrumentation without making every consumer install the package that supplies it. A contributor that wants to say why its load answered nothing logs that itself; it is the one that knows.

The instrumentation is unknown on purpose. Naming OpenTelemetry's Instrumentation would put the vendor in the package every other one peers on — the same reason Tracer and Meter are declared as narrowings rather than as OTel's own types. The collector (@btravstack/observability/otel) is where the vendor is already a dependency, so that is where the cast belongs.

Returns ​

Promise<unknown>


KernelEnvironment ​

ts
type KernelEnvironment = object;

Defined in: packages/core/src/start.ts:164

The kernel's own variables, all optional: each has a default, and each is pinned by the matching StartOptions field.

Properties ​

PropertyModifierTypeDefined in
DRAIN_TIMEOUT_MS?readonlystringpackages/core/src/start.ts:168
PRE_DRAIN_DELAY_MS?readonlystringpackages/core/src/start.ts:167
PROBE_HOST?readonlystringpackages/core/src/start.ts:166
PROBE_PORT?readonlystringpackages/core/src/start.ts:165
STOP_TIMEOUT_MS?readonlystringpackages/core/src/start.ts:169

KernelEvent ​

ts
type KernelEvent = 
  | {
  type: "building";
}
  | {
  cause: unknown;
  type: "startFailed";
}
  | {
  info: unknown;
  probePort: number | undefined;
  runtime: string;
  type: "serving";
}
  | {
  inFlight: number;
  type: "draining";
}
  | {
  report: DrainReport;
  type: "drained";
}
  | {
  afterMs: number | undefined;
  phase: "build" | "stop";
  type: "stoppedWaiting";
}
  | {
  type: "stopping";
}
  | {
  type: "exited";
}
  | {
  cause: unknown;
  port: string;
  type: "teardownError";
}
  | {
  cause: unknown;
  type: "uncaught";
};

Defined in: packages/core/src/events.ts:3

Union Members ​

Type Literal ​
ts
{
  type: "building";
}

Type Literal ​
ts
{
  cause: unknown;
  type: "startFailed";
}

Type Literal ​
ts
{
  info: unknown;
  probePort: number | undefined;
  runtime: string;
  type: "serving";
}
NameTypeDescriptionDefined in
infounknownWhatever the runtime published on Serving.info. unknown because the kernel does not know a runtime's Info at the event union — it is read off the module at start's call site, not here — and a sink is serialising it anyway. A generic KernelEvent<Info> would infect EventSink, stderrSink and every adapter for one field none of them reads structurally.packages/core/src/events.ts:17
probePortnumber | undefinedThe port the kernel's own probe listener bound, undefined when probes are off. Its own field rather than folded into info: the probe server is the kernel's, not the runtime's, so publishing it as something the runtime said would be a small lie.packages/core/src/events.ts:24
runtimestring-packages/core/src/events.ts:8
type"serving"-packages/core/src/events.ts:7

Type Literal ​
ts
{
  inFlight: number;
  type: "draining";
}

Type Literal ​
ts
{
  report: DrainReport;
  type: "drained";
}

Type Literal ​
ts
{
  afterMs: number | undefined;
  phase: "build" | "stop";
  type: "stoppedWaiting";
}
NameTypeDescriptionDefined in
afterMsnumber | undefinedThe deadline that expired, or undefined when a second signal cut the wait short.packages/core/src/events.ts:39
phase"build" | "stop""stop" for Serving.stop and the finalisers, "build" for a graph that never served.packages/core/src/events.ts:37
type"stoppedWaiting"The kernel stopped WAITING for a phase that has no deadline of its own, and reported anyway. Without it a stop that ran long and a stop that finished are the same two lines on stderr (stopping, exited), which is the silence ExitReport.abandonedAt exists to end.packages/core/src/events.ts:35

Type Literal ​
ts
{
  type: "stopping";
}

Type Literal ​
ts
{
  type: "exited";
}

Type Literal ​
ts
{
  cause: unknown;
  port: string;
  type: "teardownError";
}

Type Literal ​
ts
{
  cause: unknown;
  type: "uncaught";
}

Level ​

ts
type Level = "trace" | "debug" | "info" | "warn" | "error" | "fatal";

Defined in: packages/core/src/observability.ts:8

The severity of one line, and the whole of the set: six levels, ordered, with no caller-defined additions — which is what lets LOG_LEVEL be validated at startup and isEnabled be a comparison rather than a lookup.


LoggerService ​

ts
type LoggerService = object;

Defined in: packages/core/src/observability.ts:33

Every method takes the same three arguments in the same order: (message, attributes?, cause?).

Uniform on purpose. A failure is not a property of severity — an info line reporting a recovered fault carries one too — so every level can take a cause, at the cost of logger.error("boom", undefined, cause) for a failure with nothing else to say.

Properties ​

PropertyModifierTypeDescriptionDefined in
debugreadonly(message, attributes?, cause?) => void-packages/core/src/observability.ts:35
errorreadonly(message, attributes?, cause?) => voidcause is the failure itself — an Error, an unthrown Err's error, a rejected value.packages/core/src/observability.ts:39
fatalreadonly(message, attributes?, cause?) => void-packages/core/src/observability.ts:40
inforeadonly(message, attributes?, cause?) => void-packages/core/src/observability.ts:36
isEnabledreadonly(level) => booleanWhether a line at level would be written — for a payload expensive enough to be worth not building.packages/core/src/observability.ts:44
tracereadonly(message, attributes?, cause?) => void-packages/core/src/observability.ts:34
warnreadonly(message, attributes?, cause?) => void-packages/core/src/observability.ts:37
withreadonly(attributes) => LoggerServiceA logger carrying attributes on every line it writes, on top of this one's. Never mutates this one.packages/core/src/observability.ts:42

MeterService ​

ts
type MeterService = object;

Defined in: packages/core/src/observability.ts:102

What a Meter does: mint the two instruments a framework package needs — it counts what happened and measures how long it took. A gauge is something an application declares about its own domain, reaching the vendor's meter for it as it would any other adapter.

Properties ​

PropertyModifierTypeDefined in
createCounterreadonly(name, options?) => Counterpackages/core/src/observability.ts:103
createHistogramreadonly(name, options?) => Histogrampackages/core/src/observability.ts:107

Operation ​

ts
type Operation = object;

Defined in: packages/core/src/observation.ts:19

One operation worth observing, named before it runs.

component is the starter's own word for itself — "http", "cache", "amqp" — and it is what lets an observer mint per-component instrument and span names without knowing anything about the component. name is the operation within it ("get", "unit"), and attributes are the dimensions known before the call.

The dimensions are the contributor's business and their cardinality is its responsibility: a request path or a workflow id here mints a time series per value, which is how a metrics bill becomes the incident.

Properties ​

PropertyModifierTypeDescriptionDefined in
attributesreadonlyAttributesThe DIMENSIONS: bounded, and what a metrics observer may put on an instrument. A cache operation, an HTTP method, an activity type. Their cardinality is the contributor's responsibility — a request path or a cache key here mints a time series per value, which is how a metrics bill becomes the incident. That is what Operation.details is for.packages/core/src/observation.ts:30
componentreadonlystring-packages/core/src/observation.ts:20
details?readonlyAttributesUnbounded context: a cache key, a mail subject, a URL. It rides spans and log lines, where one more field costs one more field — and never a metric, where it would cost a time series per value. The split is the whole reason an observer can be shared: without it every contributor would have to choose between a useful span and a safe metric.packages/core/src/observation.ts:39
namereadonlystring-packages/core/src/observation.ts:21
traced?readonlybooleanWhether a tracing observer should open a span (default true). false is for an operation a span would say nothing about — one whose spans already come from somewhere better, or one with no duration at all. Counting and timing still happen. @btravstack/amqp-worker's broker diagnostics pass it, being zero-length events; @btravstack/prisma no longer does, since Prisma 8 ships no engine tracer and its middleware is the only span there is. Whether a span is worth opening is the CONTRIBUTOR's knowledge, which is why it rides the operation rather than being configured on the observer.packages/core/src/observation.ts:53

Phase ​

ts
type Phase = "building" | "starting" | "serving" | "draining" | "stopping" | "exited";

Defined in: packages/core/src/phase.ts:1


Refuse ​

ts
type Refuse<T, Marker, Detail> = T extends readonly [...(infer Head), unknown] ? readonly [...Head, readonly [Marker, Detail]] : readonly [readonly [Marker, Detail]];

Defined in: packages/core/src/pieces.ts:15

A refused array: as long as the array the caller wrote, its head the caller's own elements — which match — and its LAST element the marker paired with what is wrong.

TypeScript compares two equal-length tuples element by element, so the extra diagnostic it reports lands on the trailing element and carries both the sentence and the missing key. A fixed two-element tuple named the key only when the array happened to be two elements long; every other arity was a length mismatch, and the developer diffed the contract against the array by hand.

Type Parameters ​

Type Parameter
T extends readonly unknown[]
Marker extends string
Detail

RunningApp ​

ts
type RunningApp<E, Info> = object;

Defined in: packages/core/src/start.ts:239

Type Parameters ​

Type ParameterDefault type
E-
Infonever

Properties ​

PropertyModifierTypeDescriptionDefined in
exitedreadonlyAsyncResult<ExitReport, E | RuntimeStartFailed>-packages/core/src/start.ts:240
phasereadonly() => Phase-packages/core/src/start.ts:243
probePortreadonly() => AsyncResult<number | undefined, never>The port the probe server actually bound, once the bind attempt has settled; undefined when probes are disabled or the bind failed.packages/core/src/start.ts:254
readyreadonly() => booleanThe synchronous lifecycle predicate: serving, and not forced unready by a drain or an uncaught exception. /readyz additionally consults opted-in dependency checks; this method does not evaluate them.packages/core/src/start.ts:249
requestDrainreadonly() => void-packages/core/src/start.ts:242
runtimeInforeadonly() => AsyncResult<Info | undefined, never>Whatever the runtime published on Serving.info once it is serving; undefined when it publishes nothing or never reached serving.packages/core/src/start.ts:259
stopreadonly() => void-packages/core/src/start.ts:241

Runtime ​

ts
type Runtime<Resolves, Info> = object;

Defined in: packages/core/src/runtime.ts:142

Type Parameters ​

Type ParameterDefault type
Resolves extends AnyPortnever
Infonever

Properties ​

PropertyModifierTypeDescriptionDefined in
namereadonlystring-packages/core/src/runtime.ts:143
resolvesreadonlyreadonly Resolves[]-packages/core/src/runtime.ts:148
startreadonly(host) => AsyncResult<Serving<Info>, RuntimeStartFailed>-packages/core/src/runtime.ts:149
units?readonlyReadonly<Record<string, AnyUnitModule | undefined>>The unit modules this runtime forks, by kind — { message: … }, or one per HTTP scheme. Optional, and read for one thing only: a test's UnitOverrides name a kind, fork is handed a module, and this is what maps one onto the other. A runtime that omits it refuses every unit override at boot rather than ignoring it.packages/core/src/runtime.ts:157

RuntimeHost ​

ts
type RuntimeHost<Resolves> = object;

Defined in: packages/core/src/runtime.ts:94

What a runtime is handed at start: the application services and the kernel's RunUnit. Handing it a bare Context would leave every runtime inventing its own unit tracking — the thing the kernel exists to own.

Remarks ​

The two contracts a runtime author owes, neither checkable by the kernel: a unit's response must be flushed inside the work callback (see RunUnit), and UnitMeta.id must be unique per unit unless a traceId is supplied (see UnitMeta).

ctx is the application context: a port a unit's fork module provides exists only in the Context fork hands back, so a runtime naming it in resolves is rejected at start's call site.

Type Parameters ​

Type Parameter
Resolves extends AnyPort

Properties ​

PropertyModifierTypeDefined in
ctxreadonlyContext<InstanceType<Resolves>>packages/core/src/runtime.ts:95
runreadonlyRunUnit<Resolves>packages/core/src/runtime.ts:96

RuntimeInfoOf ​

ts
type RuntimeInfoOf<X> = RuntimeOf<X> extends object ? Info : never;

Defined in: packages/core/src/runtime.ts:187

Type Parameters ​

Type Parameter
X

RunUnit ​

ts
type RunUnit<Resolves> = <T, E>(meta, work) => AsyncResult<T, E>;

Defined in: packages/core/src/runtime.ts:53

Submit one piece of work as a unit: the kernel counts it towards the drain, hands it an AbortSignal and an ambient record, and gives the work's own Result straight back — mapping that outcome to a transport is the runtime's job, never the kernel's.

Type Parameters ​

Type Parameter
Resolves extends AnyPort

Type Parameters ​

Type Parameter
T
E

Parameters ​

ParameterType
metaUnitMeta
work(unit, signal) => ReturnType<UnitWork<T, E>>

Returns ​

AsyncResult<T, E>

Remarks ​

Everything the client must receive has to be flushed INSIDE work, never after the returned AsyncResult settles. A unit closes the instant its Result settles, and an idle registry is the drain's permission to call Serving.stop() — so a runtime that writes after resolving is racing the transport being torn down.

UnitMeta.id must be unique per unit unless a traceId is supplied — see UnitMeta.

A runtime forks the unit's scope itself, through UnitHost.fork, at the moment it holds the unit's input; the kernel closes that scope when the unit settles, after the response is flushed. Work that subscribes to an event after a fork must first check whether it already fired.

signal aborts at the drain deadline, at once when the drain is skipped, and once the unit settles — after its scope has closed — so work the runtime left running past the unit, such as an HTTP handler whose client disconnected, is told to stop. Only the first two count as abandoned.


Serving ​

ts
type Serving<Info> = object;

Defined in: packages/core/src/runtime.ts:107

What a runtime is, once it is up — plus, optionally, what it wants to say about itself, read back through RunningApp.runtimeInfo().

Info is the runtime's own shape rather than a port number: a queue consumer has no port and might publish { queue, prefetch }. It defaults to never, so info is unwritable for a runtime with nothing to publish.

Type Parameters ​

Type ParameterDefault type
Infonever

Properties ​

PropertyModifierTypeDescriptionDefined in
drainreadonly(signal) => AsyncResult<void, never>-packages/core/src/runtime.ts:110
info?readonlyInfo-packages/core/src/runtime.ts:112
stopreadonly() => AsyncResult<void, never>-packages/core/src/runtime.ts:111
stopped?readonly() => AsyncResult<void, never>Settles when the runtime has stopped serving on its own account — nobody asked it to, and it is not coming back. Without this a runtime has no way to say so, and the kernel's lifecycle only ever moves on a signal or a stop() call. So a Temporal worker whose run() rejected mid-flight, or an AMQP consumer the server cancelled and nothing re-subscribed, left the process alive and /readyz answering 200 — a pod in a Service's endpoints, consuming nothing. The orchestrator has no way to learn that on its own: liveness answers from building onward, and readiness is the lifecycle's, not the transport's. The kernel races it against its own shutdown deferred and reports reason: "runtimeStopped", which runMain exits 1 for — a restart, which is the right answer to a transport that has given up. Optional, and a runtime that cannot know omits it. An HTTP server that is listening is serving; there is no third state for it to report, and a field it had to write OkAsync() into would be a promise it could not keep. A never-settling AsyncResult is the other honest spelling for a runtime that could report this and has nothing to say yet. It says nothing about WHY. The runtime that knows writes that line itself, through Observers or its own diagnostics; this channel exists so the process ends, not so the reason travels.packages/core/src/runtime.ts:139

Settle ​

ts
type Settle = (settled) => void;

Defined in: packages/core/src/observation.ts:66

What an observer answers: a finisher, called exactly once when the operation settles.

Parameters ​

ParameterType
settledSettled

Returns ​

void


Settled ​

ts
type Settled = object;

Defined in: packages/core/src/observation.ts:57

How an operation came out, plus whatever was only knowable at the end.

Properties ​

PropertyModifierTypeDescriptionDefined in
attributes?readonlyAttributesDimensions known only at the end, merged over the operation's own — an HTTP status, a cache hit or miss.packages/core/src/observation.ts:60
cause?readonlyunknownThe failure itself, for an observer that writes a line about it.packages/core/src/observation.ts:62
outcomereadonly"ok" | "error"-packages/core/src/observation.ts:58

Span ​

ts
type Span = object;

Defined in: packages/core/src/observability.ts:71

One span, narrowed to what a framework package does with it: label it, say how it ended, end it. The numbers are OpenTelemetry's own, so an OTel span satisfies this structurally with no translation in between.

Properties ​

PropertyModifierTypeDefined in
endreadonly() => voidpackages/core/src/observability.ts:77
setAttributesreadonly(attributes) => unknownpackages/core/src/observability.ts:72
setStatusreadonly(status) => unknownpackages/core/src/observability.ts:73

SpanStatusCode ​

ts
type SpanStatusCode = typeof SPAN_STATUS[keyof typeof SPAN_STATUS];

Defined in: packages/core/src/observability.ts:64

The three codes SPAN_STATUS names, as the type a Span takes.


StartEnvironment ​

ts
type StartEnvironment<M> = M extends Module<infer _X, infer _E, infer N> ? EnvironmentFor<N> & KernelEnvironment : never;

Defined in: packages/core/src/start.ts:177

The env a start of M accepts — what the module's configuration reads, plus the kernel's own variables. For typing an environment kept apart from the call, such as a test's shared one.

Type Parameters ​

Type Parameter
M

StartGate ​

ts
type StartGate<X, N> = [Exclude<N, Scope | Env>] extends [never] ? [Extract<X, RuntimeInstance>] extends [never] ? "NO RUNTIME — the module exports no port declared over RuntimePort" : [InstanceType<RuntimeResolvesOf<X>>] extends [X] ? unknown : "UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export" : object;

Defined in: packages/core/src/start.ts:296

Type Parameters ​

Type ParameterDefault type
X-
Nnever

StartOptions ​

ts
type StartOptions<Ev> = object;

Defined in: packages/core/src/start.ts:180

Type Parameters ​

Type ParameterDefault type
EvEnvironment

Properties ​

PropertyModifierTypeDescriptionDefined in
clock?readonlyClock-packages/core/src/start.ts:191
drainTimeoutMs?readonlynumberHow long in-flight work gets before it is aborted and reported abandoned. Unset, it is bound from DRAIN_TIMEOUT_MS in env (default 20_000). Keep it under the pod's terminationGracePeriodSeconds, which is the reason this one belongs in the environment: the two are set together, in the same manifest.packages/core/src/start.ts:220
env?readonlyEvThe environment the graph is configured from, provided to it as the Env port and read for the kernel's own variables. Defaults to process.env. Typed by what the graph reads: at start(module, { env }) it accepts the variables the module's configuration names and the kernel's own, requires the ones nothing defaults or pins, and refuses any other — unless some reader named none, when any record is accepted.packages/core/src/start.ts:190
onEvent?readonlyEventSink-packages/core/src/start.ts:236
preDrainDelayMs?readonlynumberHow long readiness stays false before the runtime is told to stop accepting. Unset, it is bound from PRE_DRAIN_DELAY_MS in env (default 5_000) — the window that covers Kubernetes' eventually-consistent endpoint removal, which is a property of the cluster rather than of the code, so a deployment must be able to set it.packages/core/src/start.ts:212
probes?readonly| { host?: string; port: number; } | falseThe probe server's port and interface. Unset, they are bound from PROBE_PORT (default 9000) and PROBE_HOST (default 0.0.0.0) in env; false disables the probe server and reads neither. 0.0.0.0 matches HOST's own default for HOST's own reason: a kubelet httpGet probe connects over the POD IP, so the loopback-only bind this used to hardcode could not answer the probe shape every manifest reaches for first. Pin host: "127.0.0.1" where the port is shared with something else on the host, and probe it with exec from inside the container.packages/core/src/start.ts:204
signals?readonlyboolean-packages/core/src/start.ts:192
stopTimeoutMs?readonlynumberHow long the kernel waits for Serving.stop and the application scope's finalisers together before it stops waiting and reports ExitReport.abandonedAt: "stop". Unset, it is bound from STOP_TIMEOUT_MS in env (default 5_000). It exists because beat 3's deadline covers in-flight WORK and nothing covered the teardown: a release that never settles — a socket to a host that stopped answering — left the phase at stopping with no exit report, which is the one artefact the lifecycle exists to produce. The three timings are cumulative against the pod's terminationGracePeriodSeconds, so the defaults sum to 30 s exactly (5_000 + 20_000 + 5_000): raise one and raise the grace period with it.packages/core/src/start.ts:235

TeardownError ​

ts
type TeardownError = object;

Defined in: packages/core/src/start.ts:49

Properties ​

PropertyModifierTypeDefined in
causereadonlyunknownpackages/core/src/start.ts:49
portreadonlystringpackages/core/src/start.ts:49

TracerService ​

ts
type TracerService = object;

Defined in: packages/core/src/observability.ts:81

What a Tracer does: start a span, by name.

Properties ​

PropertyModifierTypeDefined in
startSpanreadonly(name) => Spanpackages/core/src/observability.ts:81

UnitExportsOf ​

ts
type UnitExportsOf<M> = M extends Module<infer X, never, unknown> ? X : never;

Defined in: packages/core/src/unit-record.ts:41

What a bound unit module exports — the port instances a piece of that kind may read.

Type Parameters ​

Type Parameter
M

UnitGate ​

ts
type UnitGate<Unit, Declared> = [UnprovidedBy<Unit, Declared>] extends [never] ? unknown : object;

Defined in: packages/core/src/unit-record.ts:62

A piece injecting a port the bound unit module does not export. unknown when every declared port is covered — including the empty case, so a worker whose pieces declare no unit: is gated on nothing. A union of modules is checked module by module.

Type Parameters ​

Type Parameter
Unit
Declared

UnitHost ​

ts
type UnitHost<Resolves> = object;

Defined in: packages/core/src/runtime.ts:70

What the kernel hands a unit's work: the application context, and the one way to open the unit's own scope.

fork builds module over the application context plus seed and hands the forked context back. The scope is torn down when the unit closes — inside the registry's unit, so the unit is not counted closed until its finalisers have run, and inside the unit's ambient record, so a teardown log line carries the unit's ids. A construction failure rides the unit's defect path. A unit forks once; a second call is a defect, and so is a call made after the unit has settled — nothing awaits that scope's teardown.

Type Parameters ​

Type Parameter
Resolves extends AnyPort

Properties ​

PropertyModifierTypeDefined in
ctxreadonlyContext<InstanceType<Resolves>>packages/core/src/runtime.ts:71
forkreadonly<UnitX, N, Seeded>(module, seed) => AsyncResult<Context<InstanceType<Resolves> | UnitX | InstanceType<Seeded>>, never>packages/core/src/runtime.ts:72

UnitMeta ​

ts
type UnitMeta = object;

Defined in: packages/core/src/units.ts:72

What a runtime says about one piece of work as it submits it. kind is the category ("http", "tick", "job"); id identifies this unit.

Remarks ​

id must be unique per unit unless a traceId is supplied, because traceId defaults to it. A runtime passing a CATEGORY as the id — a route template such as "POST /orders" — gives every request the same trace id and silently defeats the ambient record. A route template is a kind.

The kernel cannot check this, so uniqueness is the runtime's to guarantee. What it does guarantee is UnitRecord's unitId, a UUID minted per unit, so no two units share one across replicas either; traceId is the CORRELATION id, which is why it is the one a runtime may supply — it carries an id from outside the process.

Properties ​

PropertyModifierTypeDefined in
idreadonlystringpackages/core/src/units.ts:74
kindreadonlystringpackages/core/src/units.ts:73
tenantId?readonlystringpackages/core/src/units.ts:76
traceId?readonlystringpackages/core/src/units.ts:75

UnitNeedsOf ​

ts
type UnitNeedsOf<Unit, Seeded> = Unit extends Module<never, never, infer N> ? 
  | Exclude<N, Scope | Seeded | Env>
  | [Extract<N, Env>] extends [never] ? never : PortInstance<"UNIT READS CONFIGURATION — Env is application-scoped: parse it in a root provider and inject the result", never> : never;

Defined in: packages/core/src/unit-record.ts:28

The needs a bound unit module still owes, or never when none is bound. Scope is excluded, since nothing can ever provide it — the same exemption NeedsGate itself carries — and so is Seeded, the port the runtime's own fork seed discharges. Env is replaced by a refusal nothing provides, so start names it: a unit forks per unit of work, so configuration read there would be parsed per request rather than once at boot. Inline rather than a named alias, so a consumer's declaration emit never has to name it.

Type Parameters ​

Type ParameterDefault type
Unit-
Seedednever

UnitOutcome ​

ts
type UnitOutcome = "ok" | "error";

Defined in: packages/core/src/units.ts:34

How a unit's work settled: ok, or error for an Err, a Defect and a throw alike.


UnitRecord ​

ts
type UnitRecord = object;

Defined in: packages/core/src/units.ts:20

What the kernel opens per unit and currentUnit() reads: a small, fixed record of data about this unit, and never a service.

signal is the same AbortSignal the work callback receives — aborted at the drain deadline, at once on a path that skips the drain, and once the unit has settled, so work that outlives its unit — an HTTP handler whose client disconnected — is told to stop. The settle abort's reason is an AbortError DOMException whose message is "The unit has settled"; the kernel's own aborts keep the default reason. It is here because the callback is not always where the work is: a middleware-shaped runtime opens the unit around a call whose arguments it does not own. A transport's own cancellation is a different clock, not this one.

Properties ​

PropertyModifierTypeDefined in
signalreadonlyAbortSignalpackages/core/src/units.ts:24
tenantIdreadonlystring | undefinedpackages/core/src/units.ts:23
traceIdreadonlystringpackages/core/src/units.ts:22
unitIdreadonlystringpackages/core/src/units.ts:21

UnitRecordOf ​

ts
type UnitRecordOf<U> = { readonly [N in keyof U]: ServiceOf<InstanceType<U[N]>> };

Defined in: packages/core/src/unit-record.ts:44

A piece's declared unit: record, as the services it reads off context.unit.

Type Parameters ​

Type Parameter
U extends Readonly<Record<string, AnyPort>>

UnitRegistry ​

ts
type UnitRegistry = object;

Defined in: packages/core/src/units.ts:84

Properties ​

PropertyModifierTypeDefined in
abortAllreadonly() => voidpackages/core/src/units.ts:90
awaitIdlereadonly() => AsyncResult<void, never>packages/core/src/units.ts:91
closedreadonly() => numberpackages/core/src/units.ts:89
inFlightreadonly() => numberpackages/core/src/units.ts:86
runreadonly<T, E>(meta, work) => AsyncResult<T, E>packages/core/src/units.ts:85

UnitWork ​

ts
type UnitWork<T, E> = (signal) => 
  | AsyncResult<T, E>
  | Promise<Result<T, E>>
  | Result<T, E>;

Defined in: packages/core/src/units.ts:79

Type Parameters ​

Type Parameter
T
E

Parameters ​

ParameterType
signalAbortSignal

Returns ​

| AsyncResult<T, E> | Promise<Result<T, E>> | Result<T, E>

Variables ​

LEVELS ​

ts
const LEVELS: readonly Level[];

Defined in: packages/core/src/observability.ts:11

The levels in order, least severe first — what isEnabled compares through.


noObserverMember ​

ts
const noObserverMember: Provider<Observers, never, never> & object;

Defined in: packages/core/src/starter.ts:12

The no-op member every module reading Observers provides, so the set it reads is never the empty dependency di refuses: a graph composing no observability still starts. One provider, shared — di de-duplicates a graph's providers by reference, so however many modules contribute it, an operation costs one inert call.

Type Declaration ​

NameTypeDefined in
porttypeof Observerspackages/di/dist/index.d.mts:320

RuntimePort ​

ts
const RuntimePort: PortClass<"Runtime">;

Defined in: packages/core/src/runtime.ts:171

The port the kernel resolves its runtime from. A runtime is a service the module provides, not an option handed to start: a runtime package declares its own port over this one — class HttpRuntime extends RuntimePort<Runtime<never, HttpInfo>> {} — so it is built by di like everything else, and the kernel owns nothing but the lifecycle.

Left generic on purpose: every runtime port is one id at runtime, since a process boots exactly one, while each carries its own Resolves/Info in the type.


SPAN_STATUS ​

ts
const SPAN_STATUS: object;

Defined in: packages/core/src/observability.ts:61

A span's outcome: unset until something says otherwise, then ok or error.

Type Declaration ​

NameTypeDefault valueDefined in
error22packages/core/src/observability.ts:61
ok11packages/core/src/observability.ts:61
unset00packages/core/src/observability.ts:61

stderrSink ​

ts
const stderrSink: EventSink;

Defined in: packages/core/src/events.ts:70


systemClock ​

ts
const systemClock: Clock;

Defined in: packages/core/src/clock.ts:10

Functions ​

composeByPrefix() ​

ts
function composeByPrefix(
   port, 
   prefix, 
   withUnit
): (first) => unknown;

Defined in: packages/core/src/pieces.ts:54

The runtime half of a starter's composing provider — AmqpHandlers(contract), TemporalActivities(contract) — and its two arms. An array of pieces is composed into one record keyed by each piece's port id less prefix, so the services record IS the composed record; a { inject?, unit?, sync } record has withUnit applied to every entry sync answers.

Parameters ​

ParameterType
portAnyPort
prefixstring
withUnitEntryWrapper

Returns ​

(first) => unknown


currentUnit() ​

ts
function currentUnit(): UnitRecord | undefined;

Defined in: packages/core/src/units.ts:31

Returns ​

UnitRecord | undefined


dispatchUnit() ​

ts
function dispatchUnit<T, E>(dispatch): AsyncResult<T, E>;

Defined in: packages/core/src/unit-record.ts:135

A worker middleware's body: observe operation, open one kernel unit, fork unit — when one is bound — seeded with seed, and call next with the forked context where withUnitRecord finds it. With no unit bound, next() runs unchanged.

Observed from whichever channel the unit settles on, a defect included: a defect is a failed unit too, and an errors count that omitted it would be the reassuring half.

Type Parameters ​

Type Parameter
T
E

Parameters ​

ParameterType
dispatch{ host: RuntimeHost<never>; meta: UnitMeta; next: (overrides?) => AsyncResult<T, E>; observers: readonly ((operation) => Settle)[]; operation: Operation; seed: readonly [AnyPort, unknown]; unit: AnyUnitModule | undefined; }
dispatch.hostRuntimeHost<never>
dispatch.metaUnitMeta
dispatch.next(overrides?) => AsyncResult<T, E>
dispatch.observersreadonly ((operation) => Settle)[]
dispatch.operationOperation
dispatch.seedreadonly [AnyPort, unknown]
dispatch.unitAnyUnitModule | undefined

Returns ​

AsyncResult<T, E>


infrastructureExports() ​

ts
function infrastructureExports<I, P>(imports, provides): InfrastructureExports<I, P>;

Defined in: packages/core/src/infrastructure-exports.ts:28

Export visible Logger and HealthChecks ports without exposing private or business ports.

Type Parameters ​

Type Parameter
I extends readonly AnyModule[]
P extends readonly AnyProvider[]

Parameters ​

ParameterType
importsI
providesP

Returns ​

InfrastructureExports<I, P>


mintPiece() ​

ts
function mintPiece(port, withUnit): (options) => unknown;

Defined in: packages/core/src/pieces.ts:40

The runtime half of a starter's piece factory — AmqpHandler(contract, key), TemporalWorkflowActivities(contract, key): a provider on port whose service is what sync answers, wrapped once by withUnit so it reads the record the piece declared. The starter keeps the types; this keeps the body.

Parameters ​

ParameterType
portAnyPort
withUnitEntryWrapper

Returns ​

(options) => unknown


noObserver() ​

ts
function noObserver(): Settle;

Defined in: packages/core/src/observation.ts:90

The no-op member every reader of Observers contributes, so the set is never empty.

Returns ​

Settle


observe() ​

ts
function observe(observers, operation): Settle;

Defined in: packages/core/src/observation.ts:107

Run every observer around one operation, and hand back the one finisher that settles them all.

Observers are started in order and settled in order, and the finisher is guarded: a second call is dropped. "Called exactly once" is therefore a property of this function rather than a rule each starter re-keeps — which matters because the settling call sites are error paths, where a tap and a tapFailure on the same chain, or a retry, is exactly the shape that fires twice and doubles a failure count.

A broken observer is dropped independently, on startup and settlement. No recursive reporting is attempted: telemetry must never alter the operation or prevent another observer from settling.

Parameters ​

ParameterType
observersreadonly ((operation) => Settle)[]
operationOperation

Returns ​

Settle


observed() ​

ts
function observed<T, E>(
   observers, 
   operation, 
   call, 
   settled?
): AsyncResult<T, E>;

Defined in: packages/core/src/observation.ts:140

observe, wrapped around one call: every observer is started before call runs and settled from whichever channel it comes back on — ok on success, error carrying the Err or the defect as cause otherwise. The wrapper is transparent to the Result: whatever call answers is what the caller receives.

settled replaces either default where a starter has more to say: ok receives the value (a cache reports a hit or a miss), failure the FailureView (a store reports a missing object as an ordinary answer). A throwing shaping hook is dropped and the ordinary settlement is used.

Type Parameters ​

Type Parameter
T
E

Parameters ​

ParameterType
observersreadonly ((operation) => Settle)[]
operationOperation
call() => AsyncResult<T, E>
settled?{ failure?: (failure) => Settled; ok?: (value) => Settled; }
settled.failure?(failure) => Settled
settled.ok?(value) => Settled

Returns ​

AsyncResult<T, E>


releasedBy() ​

ts
function releasedBy(signal, running): AsyncResult<void, never>;

Defined in: packages/core/src/runtime.ts:253

running, but no later than the kernel's drain deadline — the primitive a Serving.drain needs when the work it awaits settles on somebody else's clock (Temporal's shutdownForceTime, a broker library's close) and so cannot honour signal itself.

The losing branch's Result is dropped, which is the point rather than an oversight: once the deadline wins, the kernel has already moved on and the eventual outcome has no consumer left. What that costs is the runtime's own business — an un-acked AMQP delivery is redelivered, so abandoning one repeats work rather than losing it, while a Temporal activity is retried on another worker.

Deliberately Clock-agnostic: there is no duration here, only a signal, so it behaves identically under @btravstack/testing's fake clock. Racing work against a timeout is a different primitive and belongs on Clock (drain.ts uses clock.sleep for exactly that, so a fake clock can control it) — do not fold the two together.

Parameters ​

ParameterType
signalAbortSignal
runningAsyncResult<void, never>

Returns ​

AsyncResult<void, never>


runHealthChecks() ​

ts
function runHealthChecks(checks): AsyncResult<HealthReport, never>;

Defined in: packages/core/src/health.ts:127

Runs every check and folds the results into one report — the whole app is unhealthy if any single component is.

Each check's failure is recovered into a component line BEFORE allAsync sees it, so a failing dependency cannot short-circuit the others: a report naming one component is worth less than one naming all of them. A check that throws rather than answers is a bug in the check, and it is folded in too: each check is STARTED inside the pipeline, so a synchronous throw and a defecting AsyncResult alike are recovered into an unhealthy line — escaped, the first would reach the kernel's own uncaughtException handler and the second would leave /healthz hanging with nothing written.

A check that never settles is the third case, and it needed a deadline rather than a recovery. Neither recovery above can see one: there is no error and no defect, only silence, so /healthz held a socket open per hit while kubelet timed out against a report that named nothing. Each check now races its own timeoutMs (default DEFAULT_HEALTH_TIMEOUT_MS), and the component that hung is named in the report like any other unhealthy one.

Parameters ​

ParameterType
checksreadonly HealthCheck[]

Returns ​

AsyncResult<HealthReport, never>


runMain() ​

ts
function runMain<X, E, N>(
   module, 
   options?, 
   exit?
): Promise<void>;

Defined in: packages/core/src/run-main.ts:100

Boot a module and turn its outcome into a process exit code — the front door, and the one sanctioned place this package decides a process's fate. start composed with the wait for exited: use start instead when the RunningApp itself is wanted (a test, an embedder, a dev runner booting two applications — none of which may claim process.exitCode).

exit is injectable and defaults to setting process.exitCode: runMain never calls process.exit(), so pending output is flushed, an embedding host keeps control of its own lifetime, and a test can observe the code without ending the run.

outcomecode
exited cleanly0
startup failure (a modeled Err)1
a runtime stopped before shutdown was requested1
a configuration port that could not be bound (ConfigInvalid, PROBE_PORT included)78
drained with work abandoned2
exited with teardown errors2
stopped waiting for the teardown or a build (ExitReport.abandonedAt)2
stopped by an uncaught exception or unhandled rejection70
a defect70

The two 70s are the same statement reached through the two channels a bug can take. A crash takes precedence over abandoned work.

Type Parameters ​

Type Parameter
X
E
N

Parameters ​

ParameterType
moduleModule<X, E, N> & StartGate<X, N>
options?StartOptions<EnvironmentFor<N> & KernelEnvironment>
exit?(code) => void

Returns ​

Promise<void>

Example ​

ts
// `OrderApi` is an `HttpModule`, which exports `HttpRuntime`. `PORT`, `HOST` and `PROBE_PORT` are read inside the graph.
await runMain(OrderApi);

start() ​

ts
function start<X, E, N>(module, options?): RunningApp<E, RuntimeInfoOf<X>>;

Defined in: packages/core/src/start.ts:304

Type Parameters ​

Type Parameter
X
E
N

Parameters ​

ParameterType
moduleModule<X, E, N> & StartGate<X, N>
options?StartOptions<EnvironmentFor<N> & KernelEnvironment>

Returns ​

RunningApp<E, RuntimeInfoOf<X>>


traceIdOfTraceparent() ​

ts
function traceIdOfTraceparent(header): string | undefined;

Defined in: packages/core/src/runtime.ts:221

The trace id inside a W3C traceparent header, and nothing else of it.

Parameters ​

ParameterType
headerstring

Returns ​

string | undefined

Remarks ​

The parent's span id is dropped, deliberately: UnitMeta.traceId is a correlation id rather than a span context, and half-carrying one would suggest a parent-child link nothing here maintains.

Three things the specification calls invalid are refused like a malformed header, because adopting one would replace a runtime's own usable id with a value that means nothing: an all-zero trace id, an all-zero parent id (the header is well-formed and names no span), and version ff, which is reserved and never a version a caller may send.

It is here rather than in a runtime because every transport carrying an inbound trace needs the same answer, and two copies of a parser is two places for the all-zero rule to be forgotten. A runtime pairs it with the adopt-only-a-non-blank-inbound-id rule its own headers need: UnitMeta.traceId defaults to meta.id when it is nullish and "" is not, so an empty header would hand a caller's every unit the same blank id.

Example ​

ts
const parent = request.headers["traceparent"];
const traceId = typeof parent === "string" ? traceIdOfTraceparent(parent) : undefined;

unitOutcome() ​

ts
function unitOutcome(): UnitOutcome | undefined;

Defined in: packages/core/src/units.ts:51

How the current unit's work settled, for the code that runs AFTER it: a unit module's onStop, which tears down inside the record but is handed only its own service. undefined outside a unit and while the work is still running. Whether the unit was aborted is the record's own signal.

It is the kernel's outcome, not the transport's: an HTTP unit that answered a 500 still settled ok, since the kernel never maps a status.

Returns ​

UnitOutcome | undefined


withUnitRecord() ​

ts
function withUnitRecord(record, implementation): (helpers, input) => unknown;

Defined in: packages/core/src/unit-record.ts:107

One (helpers, input) implementation with its piece's declared record put on helpers.context.unit, resolved out of the fork dispatchUnit opened. Applied once per piece as di constructs it, so a unit costs one record and one context object. Each worker maps it over its own entry shape.

Parameters ​

ParameterType
recordReadonly<Record<string, AnyPort>>
implementation(helpers, input) => unknown

Returns ​

(helpers, input) => unknown

Released under the MIT License.