@btravstack/core 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/dist/index.cjs +34 -1
- package/dist/index.d.cts +57 -11
- package/dist/index.d.mts +57 -11
- package/dist/index.mjs +34 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -112,6 +112,22 @@ and turns the outcome into a process exit code — one call, and the whole of a
|
|
|
112
112
|
`TickerApp` that does not export `Greeter` is a type error at the call, and so
|
|
113
113
|
is a module that exports no runtime port at all.
|
|
114
114
|
|
|
115
|
+
## For a runtime author
|
|
116
|
+
|
|
117
|
+
Two helpers sit beside the `Runtime` contract, because every transport needs
|
|
118
|
+
them and none should own a private copy:
|
|
119
|
+
|
|
120
|
+
- **`releasedBy(signal, running)`** — `running`, but no later than the kernel's
|
|
121
|
+
drain deadline, for a `Serving.drain` whose work settles on somebody else's
|
|
122
|
+
clock.
|
|
123
|
+
- **`traceIdOfTraceparent(header)`** — the trace-id field of a W3C
|
|
124
|
+
`traceparent`, and nothing else of it: the parent's span id is dropped, since
|
|
125
|
+
`UnitMeta.traceId` is a correlation id rather than a span context. Answers
|
|
126
|
+
`undefined` for anything the specification calls invalid — a malformed
|
|
127
|
+
header, an all-zero trace id, an all-zero parent id, the reserved version
|
|
128
|
+
`ff` — so your runtime falls back to its own id instead of adopting one that
|
|
129
|
+
means nothing. A higher version's extra fields are read rather than refused.
|
|
130
|
+
|
|
115
131
|
## What you get
|
|
116
132
|
|
|
117
133
|
- **A drain that survives Kubernetes.** On SIGTERM: readiness flips false, the
|
|
@@ -132,7 +148,7 @@ is a module that exports no runtime port at all.
|
|
|
132
148
|
- **A per-unit scope no handler manages** — pass a module as
|
|
133
149
|
`StartOptions.unit` and the kernel forks it around every unit.
|
|
134
150
|
- **An ambient record, not an ambient container** — `currentUnit()` reads
|
|
135
|
-
`{ unitId, traceId, tenantId,
|
|
151
|
+
`{ unitId, traceId, tenantId, signal }`; services never travel
|
|
136
152
|
there. `signal` is the very `AbortSignal` the unit's work callback is handed,
|
|
137
153
|
so a runtime whose work is a library's `next()` — a Temporal activity, an
|
|
138
154
|
AMQP delivery — can still honour the drain deadline.
|
package/dist/index.cjs
CHANGED
|
@@ -206,6 +206,39 @@ var RuntimeStartFailed = class extends (0, unthrown.TaggedError)("RuntimeStartFa
|
|
|
206
206
|
*/
|
|
207
207
|
const RuntimePort = (0, _btravstack_di.Port)("Runtime");
|
|
208
208
|
/**
|
|
209
|
+
* The trace id inside a W3C `traceparent` header, and nothing else of it.
|
|
210
|
+
*
|
|
211
|
+
* @remarks
|
|
212
|
+
* The parent's **span id is dropped**, deliberately: `UnitMeta.traceId` is a
|
|
213
|
+
* correlation id rather than a span context, and half-carrying one would
|
|
214
|
+
* suggest a parent-child link nothing here maintains.
|
|
215
|
+
*
|
|
216
|
+
* Three things the specification calls invalid are refused like a malformed
|
|
217
|
+
* header, because adopting one would replace a runtime's own usable id with a
|
|
218
|
+
* value that means nothing: an **all-zero trace id**, an **all-zero parent
|
|
219
|
+
* id** (the header is well-formed and names no span), and **version `ff`**,
|
|
220
|
+
* which is reserved and never a version a caller may send.
|
|
221
|
+
*
|
|
222
|
+
* It is here rather than in a runtime because **every** transport carrying an
|
|
223
|
+
* inbound trace needs the same answer, and two copies of a parser is two
|
|
224
|
+
* places for the all-zero rule to be forgotten. A runtime pairs it with the
|
|
225
|
+
* adopt-only-a-non-blank-inbound-id rule its own headers need:
|
|
226
|
+
* `UnitMeta.traceId` defaults to `meta.id` when it is nullish and `""` is not,
|
|
227
|
+
* so an empty header would hand a caller's every unit the same blank id.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```ts
|
|
231
|
+
* const parent = request.headers["traceparent"];
|
|
232
|
+
* const traceId = typeof parent === "string" ? traceIdOfTraceparent(parent) : undefined;
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
const traceIdOfTraceparent = (header) => {
|
|
236
|
+
const [, version, traceId, parentId, extra] = /^(?!ff)([\da-f]{2})-([\da-f]{32})-([\da-f]{16})-[\da-f]{2}(-.*)?$/.exec(header.trim()) ?? [];
|
|
237
|
+
if (traceId === void 0 || parentId === void 0) return void 0;
|
|
238
|
+
if (version === "00" && extra !== void 0) return void 0;
|
|
239
|
+
return /^0+$/.test(traceId) || /^0+$/.test(parentId) ? void 0 : traceId;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
209
242
|
* `running`, but no later than the kernel's drain deadline — the primitive a
|
|
210
243
|
* `Serving.drain` needs when the work it awaits settles on somebody else's
|
|
211
244
|
* clock (Temporal's `shutdownForceTime`, a broker library's close) and so
|
|
@@ -386,7 +419,6 @@ const createUnitRegistry = () => {
|
|
|
386
419
|
unitId: nextId(),
|
|
387
420
|
traceId: meta.traceId ?? meta.id,
|
|
388
421
|
tenantId: meta.tenantId,
|
|
389
|
-
deadline: meta.deadline,
|
|
390
422
|
signal: controller.signal
|
|
391
423
|
};
|
|
392
424
|
return (0, unthrown.fromSafePromise)(runWithUnit(record, async () => {
|
|
@@ -710,3 +742,4 @@ exports.runMain = runMain;
|
|
|
710
742
|
exports.start = start;
|
|
711
743
|
exports.stderrSink = stderrSink;
|
|
712
744
|
exports.systemClock = systemClock;
|
|
745
|
+
exports.traceIdOfTraceparent = traceIdOfTraceparent;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AsyncResult, Result } from "unthrown";
|
|
2
|
-
import { AnyPort, Context, Module, PortClass, Scope, ServiceOf } from "@btravstack/di";
|
|
2
|
+
import { AnyPort, Context, Module, PortClass, PortInstance, Scope, ServiceOf } from "@btravstack/di";
|
|
3
3
|
import { Env, Environment } from "@btravstack/config";
|
|
4
4
|
//#region src/instrumentation.d.ts
|
|
5
5
|
/**
|
|
@@ -315,7 +315,6 @@ type UnitRecord = {
|
|
|
315
315
|
readonly unitId: string;
|
|
316
316
|
readonly traceId: string;
|
|
317
317
|
readonly tenantId: string | undefined;
|
|
318
|
-
readonly deadline: number | undefined;
|
|
319
318
|
readonly signal: AbortSignal;
|
|
320
319
|
};
|
|
321
320
|
declare const currentUnit: () => UnitRecord | undefined;
|
|
@@ -339,7 +338,6 @@ type UnitMeta = {
|
|
|
339
338
|
readonly id: string;
|
|
340
339
|
readonly traceId?: string;
|
|
341
340
|
readonly tenantId?: string;
|
|
342
|
-
readonly deadline?: number;
|
|
343
341
|
};
|
|
344
342
|
type UnitWork<T, E> = (signal: AbortSignal) => AsyncResult<T, E> | Promise<Result<T, E>> | Result<T, E>;
|
|
345
343
|
type UnitRegistry = {
|
|
@@ -434,6 +432,34 @@ type RuntimeInstance = InstanceType<PortClass<"Runtime">>;
|
|
|
434
432
|
type RuntimeOf<X> = ServiceOf<Extract<X, RuntimeInstance>>;
|
|
435
433
|
type RuntimeResolvesOf<X> = RuntimeOf<X> extends Runtime<infer Resolves, unknown> ? Resolves : never;
|
|
436
434
|
type RuntimeInfoOf<X> = RuntimeOf<X> extends Runtime<AnyPort, infer Info> ? Info : never;
|
|
435
|
+
/**
|
|
436
|
+
* The trace id inside a W3C `traceparent` header, and nothing else of it.
|
|
437
|
+
*
|
|
438
|
+
* @remarks
|
|
439
|
+
* The parent's **span id is dropped**, deliberately: `UnitMeta.traceId` is a
|
|
440
|
+
* correlation id rather than a span context, and half-carrying one would
|
|
441
|
+
* suggest a parent-child link nothing here maintains.
|
|
442
|
+
*
|
|
443
|
+
* Three things the specification calls invalid are refused like a malformed
|
|
444
|
+
* header, because adopting one would replace a runtime's own usable id with a
|
|
445
|
+
* value that means nothing: an **all-zero trace id**, an **all-zero parent
|
|
446
|
+
* id** (the header is well-formed and names no span), and **version `ff`**,
|
|
447
|
+
* which is reserved and never a version a caller may send.
|
|
448
|
+
*
|
|
449
|
+
* It is here rather than in a runtime because **every** transport carrying an
|
|
450
|
+
* inbound trace needs the same answer, and two copies of a parser is two
|
|
451
|
+
* places for the all-zero rule to be forgotten. A runtime pairs it with the
|
|
452
|
+
* adopt-only-a-non-blank-inbound-id rule its own headers need:
|
|
453
|
+
* `UnitMeta.traceId` defaults to `meta.id` when it is nullish and `""` is not,
|
|
454
|
+
* so an empty header would hand a caller's every unit the same blank id.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```ts
|
|
458
|
+
* const parent = request.headers["traceparent"];
|
|
459
|
+
* const traceId = typeof parent === "string" ? traceIdOfTraceparent(parent) : undefined;
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare const traceIdOfTraceparent: (header: string) => string | undefined;
|
|
437
463
|
/**
|
|
438
464
|
* `running`, but no later than the kernel's drain deadline — the primitive a
|
|
439
465
|
* `Serving.drain` needs when the work it awaits settles on somebody else's
|
|
@@ -600,18 +626,38 @@ type RunningApp<E, Info = never> = {
|
|
|
600
626
|
};
|
|
601
627
|
/**
|
|
602
628
|
* The phantom marker `start`, `runMain` and `Boot` all intersect onto their
|
|
603
|
-
* `module` parameter: `unknown` — and invisible — when the module
|
|
604
|
-
* runtime, its exports cover what that
|
|
605
|
-
* unit module's needs;
|
|
606
|
-
* site as the parameter type the argument did
|
|
629
|
+
* `module` parameter: `unknown` — and invisible — when nothing the module
|
|
630
|
+
* needs is unprovided, it exports a runtime, its exports cover what that
|
|
631
|
+
* runtime resolves and they cover the unit module's needs; a diagnostic
|
|
632
|
+
* otherwise, printed at the call site as the parameter type the argument did
|
|
633
|
+
* not match.
|
|
607
634
|
*
|
|
608
635
|
* `unknown` is the satisfied arm because intersecting it leaves the module
|
|
609
636
|
* type untouched. A runtime's `resolves` is checked against the module's
|
|
610
637
|
* exports only, never the unit module's: `RuntimeHost.ctx` is the application
|
|
611
638
|
* context, so a unit-only port would resolve to nothing there.
|
|
639
|
+
*
|
|
640
|
+
* **Unmet needs are checked FIRST, and answered in di's own words rather than
|
|
641
|
+
* a sentence of the kernel's.** A root that forgot `provides: [router]` used
|
|
642
|
+
* to be told `Type 'HttpRouterPort' is not assignable to type 'Scope'` — an
|
|
643
|
+
* internal phantom nobody has heard of — or, when the port was missing from
|
|
644
|
+
* `exports` too, `UNSATISFIED RUNTIME PORTS`, which is a correct diagnosis of
|
|
645
|
+
* the second mistake that reads as a wrong one of the first and steers the fix
|
|
646
|
+
* into the wrong list. It is the same defect `Module.build` reports, so it
|
|
647
|
+
* prints the same sentence and ends on the port that is missing.
|
|
612
648
|
*/
|
|
613
|
-
|
|
614
|
-
|
|
649
|
+
/**
|
|
650
|
+
* A port's declared id, which is what a marker names it by: an id is the short
|
|
651
|
+
* string the application wrote in `Port("…")`, where the port TYPE of a
|
|
652
|
+
* starter's own generic port — `AmqpHandlers` over a contract — expands to
|
|
653
|
+
* hundreds of characters of the caller's own schema and truncates before the
|
|
654
|
+
* name is reached.
|
|
655
|
+
*/
|
|
656
|
+
type PortIdOf<P> = P extends PortInstance<infer Id, infer _Service> ? Id : P;
|
|
657
|
+
type StartGate<X, UnitNeeds = never, N = never> = [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] ? [Exclude<UnitNeeds, X | Scope | Env>] extends [never] ? unknown : "UNSATISFIED UNIT NEEDS — the unit module needs a port the module does not export" : "UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export" : {
|
|
658
|
+
readonly "UNSATISFIED DEPENDENCIES — nothing provides": PortIdOf<Exclude<N, Scope | Env>>;
|
|
659
|
+
};
|
|
660
|
+
declare const start: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<X, E, N> & StartGate<X, UnitNeeds, N>, options?: StartOptions<UnitX, UnitNeeds>) => RunningApp<E, RuntimeInfoOf<X>>;
|
|
615
661
|
//#endregion
|
|
616
662
|
//#region src/run-main.d.ts
|
|
617
663
|
/**
|
|
@@ -646,6 +692,6 @@ declare const start: <X, E, UnitX = never, UnitNeeds = never>(module: Module<X,
|
|
|
646
692
|
* await runMain(OrderApi);
|
|
647
693
|
* ```
|
|
648
694
|
*/
|
|
649
|
-
declare const runMain: <X, E, UnitX = never, UnitNeeds = never>(module: Module<X, E,
|
|
695
|
+
declare const runMain: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<X, E, N> & StartGate<X, UnitNeeds, N>, options?: StartOptions<UnitX, UnitNeeds>, exit?: (code: number) => void) => Promise<void>;
|
|
650
696
|
//#endregion
|
|
651
|
-
export { type Attributes, type Clock, type ComponentHealth, type Counter, type DrainReport, type EventSink, type ExitReport, type HealthCheck, HealthCheckFailed, HealthChecks, type HealthReport, type Histogram, type InstrumentationLoader, Instrumentations, type KernelEvent, LEVELS, type Level, Logger, type LoggerService, Meter, type MeterService, Observers, type Operation, type Phase, type RunUnit, type RunningApp, type Runtime, type RuntimeHost, type RuntimeInfoOf, RuntimePort, RuntimeStartFailed, SPAN_STATUS, type Serving, type Settle, type Settled, type Span, type SpanStatusCode, type StartGate, type StartOptions, type TeardownError, Tracer, type TracerService, type UnitMeta, type UnitRecord, type UnitRegistry, type UnitWork, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock };
|
|
697
|
+
export { type Attributes, type Clock, type ComponentHealth, type Counter, type DrainReport, type EventSink, type ExitReport, type HealthCheck, HealthCheckFailed, HealthChecks, type HealthReport, type Histogram, type InstrumentationLoader, Instrumentations, type KernelEvent, LEVELS, type Level, Logger, type LoggerService, Meter, type MeterService, Observers, type Operation, type Phase, type RunUnit, type RunningApp, type Runtime, type RuntimeHost, type RuntimeInfoOf, RuntimePort, RuntimeStartFailed, SPAN_STATUS, type Serving, type Settle, type Settled, type Span, type SpanStatusCode, type StartGate, type StartOptions, type TeardownError, Tracer, type TracerService, type UnitMeta, type UnitRecord, type UnitRegistry, type UnitWork, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock, traceIdOfTraceparent };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyPort, Context, Module, PortClass, Scope, ServiceOf } from "@btravstack/di";
|
|
1
|
+
import { AnyPort, Context, Module, PortClass, PortInstance, Scope, ServiceOf } from "@btravstack/di";
|
|
2
2
|
import { AsyncResult, Result } from "unthrown";
|
|
3
3
|
import { Env, Environment } from "@btravstack/config";
|
|
4
4
|
//#region src/instrumentation.d.ts
|
|
@@ -315,7 +315,6 @@ type UnitRecord = {
|
|
|
315
315
|
readonly unitId: string;
|
|
316
316
|
readonly traceId: string;
|
|
317
317
|
readonly tenantId: string | undefined;
|
|
318
|
-
readonly deadline: number | undefined;
|
|
319
318
|
readonly signal: AbortSignal;
|
|
320
319
|
};
|
|
321
320
|
declare const currentUnit: () => UnitRecord | undefined;
|
|
@@ -339,7 +338,6 @@ type UnitMeta = {
|
|
|
339
338
|
readonly id: string;
|
|
340
339
|
readonly traceId?: string;
|
|
341
340
|
readonly tenantId?: string;
|
|
342
|
-
readonly deadline?: number;
|
|
343
341
|
};
|
|
344
342
|
type UnitWork<T, E> = (signal: AbortSignal) => AsyncResult<T, E> | Promise<Result<T, E>> | Result<T, E>;
|
|
345
343
|
type UnitRegistry = {
|
|
@@ -434,6 +432,34 @@ type RuntimeInstance = InstanceType<PortClass<"Runtime">>;
|
|
|
434
432
|
type RuntimeOf<X> = ServiceOf<Extract<X, RuntimeInstance>>;
|
|
435
433
|
type RuntimeResolvesOf<X> = RuntimeOf<X> extends Runtime<infer Resolves, unknown> ? Resolves : never;
|
|
436
434
|
type RuntimeInfoOf<X> = RuntimeOf<X> extends Runtime<AnyPort, infer Info> ? Info : never;
|
|
435
|
+
/**
|
|
436
|
+
* The trace id inside a W3C `traceparent` header, and nothing else of it.
|
|
437
|
+
*
|
|
438
|
+
* @remarks
|
|
439
|
+
* The parent's **span id is dropped**, deliberately: `UnitMeta.traceId` is a
|
|
440
|
+
* correlation id rather than a span context, and half-carrying one would
|
|
441
|
+
* suggest a parent-child link nothing here maintains.
|
|
442
|
+
*
|
|
443
|
+
* Three things the specification calls invalid are refused like a malformed
|
|
444
|
+
* header, because adopting one would replace a runtime's own usable id with a
|
|
445
|
+
* value that means nothing: an **all-zero trace id**, an **all-zero parent
|
|
446
|
+
* id** (the header is well-formed and names no span), and **version `ff`**,
|
|
447
|
+
* which is reserved and never a version a caller may send.
|
|
448
|
+
*
|
|
449
|
+
* It is here rather than in a runtime because **every** transport carrying an
|
|
450
|
+
* inbound trace needs the same answer, and two copies of a parser is two
|
|
451
|
+
* places for the all-zero rule to be forgotten. A runtime pairs it with the
|
|
452
|
+
* adopt-only-a-non-blank-inbound-id rule its own headers need:
|
|
453
|
+
* `UnitMeta.traceId` defaults to `meta.id` when it is nullish and `""` is not,
|
|
454
|
+
* so an empty header would hand a caller's every unit the same blank id.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```ts
|
|
458
|
+
* const parent = request.headers["traceparent"];
|
|
459
|
+
* const traceId = typeof parent === "string" ? traceIdOfTraceparent(parent) : undefined;
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
declare const traceIdOfTraceparent: (header: string) => string | undefined;
|
|
437
463
|
/**
|
|
438
464
|
* `running`, but no later than the kernel's drain deadline — the primitive a
|
|
439
465
|
* `Serving.drain` needs when the work it awaits settles on somebody else's
|
|
@@ -600,18 +626,38 @@ type RunningApp<E, Info = never> = {
|
|
|
600
626
|
};
|
|
601
627
|
/**
|
|
602
628
|
* The phantom marker `start`, `runMain` and `Boot` all intersect onto their
|
|
603
|
-
* `module` parameter: `unknown` — and invisible — when the module
|
|
604
|
-
* runtime, its exports cover what that
|
|
605
|
-
* unit module's needs;
|
|
606
|
-
* site as the parameter type the argument did
|
|
629
|
+
* `module` parameter: `unknown` — and invisible — when nothing the module
|
|
630
|
+
* needs is unprovided, it exports a runtime, its exports cover what that
|
|
631
|
+
* runtime resolves and they cover the unit module's needs; a diagnostic
|
|
632
|
+
* otherwise, printed at the call site as the parameter type the argument did
|
|
633
|
+
* not match.
|
|
607
634
|
*
|
|
608
635
|
* `unknown` is the satisfied arm because intersecting it leaves the module
|
|
609
636
|
* type untouched. A runtime's `resolves` is checked against the module's
|
|
610
637
|
* exports only, never the unit module's: `RuntimeHost.ctx` is the application
|
|
611
638
|
* context, so a unit-only port would resolve to nothing there.
|
|
639
|
+
*
|
|
640
|
+
* **Unmet needs are checked FIRST, and answered in di's own words rather than
|
|
641
|
+
* a sentence of the kernel's.** A root that forgot `provides: [router]` used
|
|
642
|
+
* to be told `Type 'HttpRouterPort' is not assignable to type 'Scope'` — an
|
|
643
|
+
* internal phantom nobody has heard of — or, when the port was missing from
|
|
644
|
+
* `exports` too, `UNSATISFIED RUNTIME PORTS`, which is a correct diagnosis of
|
|
645
|
+
* the second mistake that reads as a wrong one of the first and steers the fix
|
|
646
|
+
* into the wrong list. It is the same defect `Module.build` reports, so it
|
|
647
|
+
* prints the same sentence and ends on the port that is missing.
|
|
612
648
|
*/
|
|
613
|
-
|
|
614
|
-
|
|
649
|
+
/**
|
|
650
|
+
* A port's declared id, which is what a marker names it by: an id is the short
|
|
651
|
+
* string the application wrote in `Port("…")`, where the port TYPE of a
|
|
652
|
+
* starter's own generic port — `AmqpHandlers` over a contract — expands to
|
|
653
|
+
* hundreds of characters of the caller's own schema and truncates before the
|
|
654
|
+
* name is reached.
|
|
655
|
+
*/
|
|
656
|
+
type PortIdOf<P> = P extends PortInstance<infer Id, infer _Service> ? Id : P;
|
|
657
|
+
type StartGate<X, UnitNeeds = never, N = never> = [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] ? [Exclude<UnitNeeds, X | Scope | Env>] extends [never] ? unknown : "UNSATISFIED UNIT NEEDS — the unit module needs a port the module does not export" : "UNSATISFIED RUNTIME PORTS — the runtime resolves a port the module does not export" : {
|
|
658
|
+
readonly "UNSATISFIED DEPENDENCIES — nothing provides": PortIdOf<Exclude<N, Scope | Env>>;
|
|
659
|
+
};
|
|
660
|
+
declare const start: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<X, E, N> & StartGate<X, UnitNeeds, N>, options?: StartOptions<UnitX, UnitNeeds>) => RunningApp<E, RuntimeInfoOf<X>>;
|
|
615
661
|
//#endregion
|
|
616
662
|
//#region src/run-main.d.ts
|
|
617
663
|
/**
|
|
@@ -646,6 +692,6 @@ declare const start: <X, E, UnitX = never, UnitNeeds = never>(module: Module<X,
|
|
|
646
692
|
* await runMain(OrderApi);
|
|
647
693
|
* ```
|
|
648
694
|
*/
|
|
649
|
-
declare const runMain: <X, E, UnitX = never, UnitNeeds = never>(module: Module<X, E,
|
|
695
|
+
declare const runMain: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<X, E, N> & StartGate<X, UnitNeeds, N>, options?: StartOptions<UnitX, UnitNeeds>, exit?: (code: number) => void) => Promise<void>;
|
|
650
696
|
//#endregion
|
|
651
|
-
export { type Attributes, type Clock, type ComponentHealth, type Counter, type DrainReport, type EventSink, type ExitReport, type HealthCheck, HealthCheckFailed, HealthChecks, type HealthReport, type Histogram, type InstrumentationLoader, Instrumentations, type KernelEvent, LEVELS, type Level, Logger, type LoggerService, Meter, type MeterService, Observers, type Operation, type Phase, type RunUnit, type RunningApp, type Runtime, type RuntimeHost, type RuntimeInfoOf, RuntimePort, RuntimeStartFailed, SPAN_STATUS, type Serving, type Settle, type Settled, type Span, type SpanStatusCode, type StartGate, type StartOptions, type TeardownError, Tracer, type TracerService, type UnitMeta, type UnitRecord, type UnitRegistry, type UnitWork, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock };
|
|
697
|
+
export { type Attributes, type Clock, type ComponentHealth, type Counter, type DrainReport, type EventSink, type ExitReport, type HealthCheck, HealthCheckFailed, HealthChecks, type HealthReport, type Histogram, type InstrumentationLoader, Instrumentations, type KernelEvent, LEVELS, type Level, Logger, type LoggerService, Meter, type MeterService, Observers, type Operation, type Phase, type RunUnit, type RunningApp, type Runtime, type RuntimeHost, type RuntimeInfoOf, RuntimePort, RuntimeStartFailed, SPAN_STATUS, type Serving, type Settle, type Settled, type Span, type SpanStatusCode, type StartGate, type StartOptions, type TeardownError, Tracer, type TracerService, type UnitMeta, type UnitRecord, type UnitRegistry, type UnitWork, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock, traceIdOfTraceparent };
|
package/dist/index.mjs
CHANGED
|
@@ -205,6 +205,39 @@ var RuntimeStartFailed = class extends TaggedError("RuntimeStartFailed") {
|
|
|
205
205
|
*/
|
|
206
206
|
const RuntimePort = Port("Runtime");
|
|
207
207
|
/**
|
|
208
|
+
* The trace id inside a W3C `traceparent` header, and nothing else of it.
|
|
209
|
+
*
|
|
210
|
+
* @remarks
|
|
211
|
+
* The parent's **span id is dropped**, deliberately: `UnitMeta.traceId` is a
|
|
212
|
+
* correlation id rather than a span context, and half-carrying one would
|
|
213
|
+
* suggest a parent-child link nothing here maintains.
|
|
214
|
+
*
|
|
215
|
+
* Three things the specification calls invalid are refused like a malformed
|
|
216
|
+
* header, because adopting one would replace a runtime's own usable id with a
|
|
217
|
+
* value that means nothing: an **all-zero trace id**, an **all-zero parent
|
|
218
|
+
* id** (the header is well-formed and names no span), and **version `ff`**,
|
|
219
|
+
* which is reserved and never a version a caller may send.
|
|
220
|
+
*
|
|
221
|
+
* It is here rather than in a runtime because **every** transport carrying an
|
|
222
|
+
* inbound trace needs the same answer, and two copies of a parser is two
|
|
223
|
+
* places for the all-zero rule to be forgotten. A runtime pairs it with the
|
|
224
|
+
* adopt-only-a-non-blank-inbound-id rule its own headers need:
|
|
225
|
+
* `UnitMeta.traceId` defaults to `meta.id` when it is nullish and `""` is not,
|
|
226
|
+
* so an empty header would hand a caller's every unit the same blank id.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* const parent = request.headers["traceparent"];
|
|
231
|
+
* const traceId = typeof parent === "string" ? traceIdOfTraceparent(parent) : undefined;
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
const traceIdOfTraceparent = (header) => {
|
|
235
|
+
const [, version, traceId, parentId, extra] = /^(?!ff)([\da-f]{2})-([\da-f]{32})-([\da-f]{16})-[\da-f]{2}(-.*)?$/.exec(header.trim()) ?? [];
|
|
236
|
+
if (traceId === void 0 || parentId === void 0) return void 0;
|
|
237
|
+
if (version === "00" && extra !== void 0) return void 0;
|
|
238
|
+
return /^0+$/.test(traceId) || /^0+$/.test(parentId) ? void 0 : traceId;
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
208
241
|
* `running`, but no later than the kernel's drain deadline — the primitive a
|
|
209
242
|
* `Serving.drain` needs when the work it awaits settles on somebody else's
|
|
210
243
|
* clock (Temporal's `shutdownForceTime`, a broker library's close) and so
|
|
@@ -385,7 +418,6 @@ const createUnitRegistry = () => {
|
|
|
385
418
|
unitId: nextId(),
|
|
386
419
|
traceId: meta.traceId ?? meta.id,
|
|
387
420
|
tenantId: meta.tenantId,
|
|
388
|
-
deadline: meta.deadline,
|
|
389
421
|
signal: controller.signal
|
|
390
422
|
};
|
|
391
423
|
return fromSafePromise(runWithUnit(record, async () => {
|
|
@@ -689,4 +721,4 @@ const runMain = async (module, options = {}, exit = (code) => {
|
|
|
689
721
|
await awaitExit(start(module, options), exit);
|
|
690
722
|
};
|
|
691
723
|
//#endregion
|
|
692
|
-
export { HealthCheckFailed, HealthChecks, Instrumentations, LEVELS, Logger, Meter, Observers, RuntimePort, RuntimeStartFailed, SPAN_STATUS, Tracer, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock };
|
|
724
|
+
export { HealthCheckFailed, HealthChecks, Instrumentations, LEVELS, Logger, Meter, Observers, RuntimePort, RuntimeStartFailed, SPAN_STATUS, Tracer, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock, traceIdOfTraceparent };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "The application kernel: boot a di module into a running process, and stop it without losing work",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"application",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"typescript": "7.0.2",
|
|
54
54
|
"unthrown": "5.7.0",
|
|
55
55
|
"vitest": "4.1.11",
|
|
56
|
-
"@btravstack/config": "0.
|
|
57
|
-
"@btravstack/di": "0.
|
|
56
|
+
"@btravstack/config": "0.12.0",
|
|
57
|
+
"@btravstack/di": "0.12.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"unthrown": "^5.0.0",
|
|
61
|
-
"@btravstack/config": "^0.
|
|
62
|
-
"@btravstack/di": "^0.
|
|
61
|
+
"@btravstack/config": "^0.12.0",
|
|
62
|
+
"@btravstack/di": "^0.12.0"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">=22"
|