@btravstack/core 0.11.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 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
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
@@ -709,3 +742,4 @@ exports.runMain = runMain;
709
742
  exports.start = start;
710
743
  exports.stderrSink = stderrSink;
711
744
  exports.systemClock = systemClock;
745
+ exports.traceIdOfTraceparent = traceIdOfTraceparent;
package/dist/index.d.cts CHANGED
@@ -432,6 +432,34 @@ type RuntimeInstance = InstanceType<PortClass<"Runtime">>;
432
432
  type RuntimeOf<X> = ServiceOf<Extract<X, RuntimeInstance>>;
433
433
  type RuntimeResolvesOf<X> = RuntimeOf<X> extends Runtime<infer Resolves, unknown> ? Resolves : never;
434
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;
435
463
  /**
436
464
  * `running`, but no later than the kernel's drain deadline — the primitive a
437
465
  * `Serving.drain` needs when the work it awaits settles on somebody else's
@@ -666,4 +694,4 @@ declare const start: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<
666
694
  */
667
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>;
668
696
  //#endregion
669
- 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
@@ -432,6 +432,34 @@ type RuntimeInstance = InstanceType<PortClass<"Runtime">>;
432
432
  type RuntimeOf<X> = ServiceOf<Extract<X, RuntimeInstance>>;
433
433
  type RuntimeResolvesOf<X> = RuntimeOf<X> extends Runtime<infer Resolves, unknown> ? Resolves : never;
434
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;
435
463
  /**
436
464
  * `running`, but no later than the kernel's drain deadline — the primitive a
437
465
  * `Serving.drain` needs when the work it awaits settles on somebody else's
@@ -666,4 +694,4 @@ declare const start: <X, E, N, UnitX = never, UnitNeeds = never>(module: Module<
666
694
  */
667
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>;
668
696
  //#endregion
669
- 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
@@ -688,4 +721,4 @@ const runMain = async (module, options = {}, exit = (code) => {
688
721
  await awaitExit(start(module, options), exit);
689
722
  };
690
723
  //#endregion
691
- 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.11.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/di": "0.11.0",
57
- "@btravstack/config": "0.11.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.11.0",
62
- "@btravstack/di": "^0.11.0"
61
+ "@btravstack/config": "^0.12.0",
62
+ "@btravstack/di": "^0.12.0"
63
63
  },
64
64
  "engines": {
65
65
  "node": ">=22"