@btravstack/core 0.14.0 → 0.15.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 +30 -4
- package/dist/index.cjs +216 -93
- package/dist/index.d.cts +138 -7
- package/dist/index.d.mts +138 -7
- package/dist/index.mjs +216 -94
- package/package.json +7 -8
package/dist/index.mjs
CHANGED
|
@@ -32,6 +32,26 @@ var HealthCheckFailed = class extends TaggedError("HealthCheckFailed") {};
|
|
|
32
32
|
*/
|
|
33
33
|
var HealthChecks = class extends Port.many("HealthChecks") {};
|
|
34
34
|
/**
|
|
35
|
+
* A check that never settles, bounded. `unref`'d, so a pending probe is never
|
|
36
|
+
* the reason a process stays alive, and cleared on the winning branch so a
|
|
37
|
+
* slow-but-answering check leaves no timer behind.
|
|
38
|
+
*
|
|
39
|
+
* It bounds the WAIT, not the check: nothing here can cancel whatever the check
|
|
40
|
+
* is blocked on. That is the same bargain the drain and the stop deadline make,
|
|
41
|
+
* and it is why this reports rather than recovers.
|
|
42
|
+
*/
|
|
43
|
+
const answeringWithin = (health, ms) => {
|
|
44
|
+
let timer;
|
|
45
|
+
const timeout = new Promise((resolve) => {
|
|
46
|
+
timer = setTimeout(() => resolve(Err(new HealthCheckFailed({ reason: `did not answer within ${String(ms)} ms` }))), ms);
|
|
47
|
+
timer.unref();
|
|
48
|
+
});
|
|
49
|
+
const answering = OkAsync().flatMap(() => health.check());
|
|
50
|
+
return fromSafePromise(Promise.race([answering, timeout]).finally(() => {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
})).flatMap((settled) => settled);
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
35
55
|
* Runs every check and folds the results into one report — the whole app is
|
|
36
56
|
* unhealthy if any single component is.
|
|
37
57
|
*
|
|
@@ -43,8 +63,15 @@ var HealthChecks = class extends Port.many("HealthChecks") {};
|
|
|
43
63
|
* a defecting `AsyncResult` alike are recovered into an unhealthy line —
|
|
44
64
|
* escaped, the first would reach the kernel's own `uncaughtException` handler
|
|
45
65
|
* and the second would leave `/healthz` hanging with nothing written.
|
|
66
|
+
*
|
|
67
|
+
* **A check that never settles is the third case, and it needed a deadline
|
|
68
|
+
* rather than a recovery.** Neither recovery above can see one: there is no
|
|
69
|
+
* error and no defect, only silence, so `/healthz` held a socket open per hit
|
|
70
|
+
* while kubelet timed out against a report that named nothing. Each check now
|
|
71
|
+
* races {@link HealthOptions.timeoutMs}, and the component that hung is named
|
|
72
|
+
* in the report like any other unhealthy one.
|
|
46
73
|
*/
|
|
47
|
-
const runHealthChecks = (checks) => allAsync(checks.map((health) =>
|
|
74
|
+
const runHealthChecks = (checks, options = {}) => allAsync(checks.map((health) => answeringWithin(health, health.timeoutMs ?? options.timeoutMs ?? 800).map(() => ({
|
|
48
75
|
name: health.name,
|
|
49
76
|
status: "healthy"
|
|
50
77
|
})).recoverErrCases((matcher) => matcher.with(P.tag("HealthCheckFailed"), (error) => ({
|
|
@@ -103,6 +130,24 @@ const observe = (observers, operation) => {
|
|
|
103
130
|
for (const settle of settlers) settle(settled);
|
|
104
131
|
};
|
|
105
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* {@link observe}, wrapped around one call: every observer is started before
|
|
135
|
+
* `call` runs and settled from whichever channel it comes back on — `ok` on
|
|
136
|
+
* success, `error` carrying the `Err` or the defect as `cause` otherwise. The
|
|
137
|
+
* wrapper is transparent to the `Result`: whatever `call` answers is what the
|
|
138
|
+
* caller receives.
|
|
139
|
+
*
|
|
140
|
+
* `settled` replaces either default where a starter has more to say: `ok`
|
|
141
|
+
* receives the value (a cache reports a hit or a miss), `failure` the
|
|
142
|
+
* `FailureView` (a store reports a missing object as an ordinary answer).
|
|
143
|
+
*/
|
|
144
|
+
const observed = (observers, operation, call, settled = {}) => {
|
|
145
|
+
const settle = observe(observers, operation);
|
|
146
|
+
return call().tap((value) => settle(settled.ok?.(value) ?? { outcome: "ok" })).tapFailure((failure) => settle(settled.failure?.(failure) ?? {
|
|
147
|
+
outcome: "error",
|
|
148
|
+
cause: failure.tag === "Err" ? failure.error : failure.cause
|
|
149
|
+
}));
|
|
150
|
+
};
|
|
106
151
|
//#endregion
|
|
107
152
|
//#region src/clock.ts
|
|
108
153
|
const systemClock = {
|
|
@@ -335,7 +380,7 @@ const startProbeServer = (args) => fromSafePromise(new Promise((resolve) => {
|
|
|
335
380
|
const ignoreServingError = () => {};
|
|
336
381
|
server.once("error", onBindError);
|
|
337
382
|
try {
|
|
338
|
-
server.listen(args.port,
|
|
383
|
+
server.listen(args.port, args.hostname, () => {
|
|
339
384
|
server.removeListener("error", onBindError);
|
|
340
385
|
server.on("error", ignoreServingError);
|
|
341
386
|
const address = server.address();
|
|
@@ -442,6 +487,13 @@ const createUnitRegistry = () => {
|
|
|
442
487
|
};
|
|
443
488
|
//#endregion
|
|
444
489
|
//#region src/start.ts
|
|
490
|
+
/**
|
|
491
|
+
* An arm of a race that has lost and has nothing to report: it never settles,
|
|
492
|
+
* so the winner decides. It holds no timer and no handle, which is what makes
|
|
493
|
+
* it safe — the alternative is an arm that answers a report no consumer reads,
|
|
494
|
+
* and whose side effects then have to be guarded one by one.
|
|
495
|
+
*/
|
|
496
|
+
const withdrawn = () => fromSafePromise(new Promise(() => {}));
|
|
445
497
|
const providesEnv = (module) => module.provides.some((provider) => provider.port.portId === Env.portId) || module.imports.some(providesEnv);
|
|
446
498
|
/**
|
|
447
499
|
* What the kernel reads from the environment for itself. Each field is pinned
|
|
@@ -450,13 +502,21 @@ const providesEnv = (module) => module.provides.some((provider) => provider.port
|
|
|
450
502
|
*/
|
|
451
503
|
const KERNEL_DEFAULTS = {
|
|
452
504
|
probePort: 9e3,
|
|
505
|
+
probeHost: "0.0.0.0",
|
|
453
506
|
preDrainDelayMs: 5e3,
|
|
454
|
-
drainTimeoutMs: 2e4
|
|
507
|
+
drainTimeoutMs: 2e4,
|
|
508
|
+
stopTimeoutMs: 5e3
|
|
455
509
|
};
|
|
456
510
|
const readKernelConfig = (options, env) => {
|
|
457
|
-
const
|
|
511
|
+
const probes = options.probes === false ? {
|
|
512
|
+
port: KERNEL_DEFAULTS.probePort,
|
|
513
|
+
host: KERNEL_DEFAULTS.probeHost
|
|
514
|
+
} : options.probes;
|
|
515
|
+
const probePort = probes?.port;
|
|
516
|
+
const probeHost = probes?.host;
|
|
458
517
|
const result = Config.object({
|
|
459
518
|
probePort: Config.pinned(probePort, Config.port("PROBE_PORT", { default: KERNEL_DEFAULTS.probePort })),
|
|
519
|
+
probeHost: Config.pinned(probeHost, Config.string("PROBE_HOST", { default: KERNEL_DEFAULTS.probeHost })),
|
|
460
520
|
preDrainDelayMs: Config.pinned(options.preDrainDelayMs, Config.integer("PRE_DRAIN_DELAY_MS", {
|
|
461
521
|
default: KERNEL_DEFAULTS.preDrainDelayMs,
|
|
462
522
|
min: 0
|
|
@@ -464,6 +524,10 @@ const readKernelConfig = (options, env) => {
|
|
|
464
524
|
drainTimeoutMs: Config.pinned(options.drainTimeoutMs, Config.integer("DRAIN_TIMEOUT_MS", {
|
|
465
525
|
default: KERNEL_DEFAULTS.drainTimeoutMs,
|
|
466
526
|
min: 0
|
|
527
|
+
})),
|
|
528
|
+
stopTimeoutMs: Config.pinned(options.stopTimeoutMs, Config.integer("STOP_TIMEOUT_MS", {
|
|
529
|
+
default: KERNEL_DEFAULTS.stopTimeoutMs,
|
|
530
|
+
min: 0
|
|
467
531
|
}))
|
|
468
532
|
})["~standard"].validate(env);
|
|
469
533
|
return result.issues === void 0 ? Ok(result.value) : Err(new RuntimeStartFailed({
|
|
@@ -496,8 +560,14 @@ const start = (module, options = {}) => {
|
|
|
496
560
|
const teardownErrors = [];
|
|
497
561
|
const startedAt = clock.now();
|
|
498
562
|
const kernelConfig = readKernelConfig(options, env);
|
|
499
|
-
const { preDrainDelayMs, drainTimeoutMs } = kernelConfig.getOrElse(() => KERNEL_DEFAULTS);
|
|
563
|
+
const { preDrainDelayMs, drainTimeoutMs, stopTimeoutMs } = kernelConfig.getOrElse(() => KERNEL_DEFAULTS);
|
|
500
564
|
const skipDrain = new AbortController();
|
|
565
|
+
const stopSettled = new AbortController();
|
|
566
|
+
let lifecycleSettled = false;
|
|
567
|
+
const onLifecycleSettled = () => {
|
|
568
|
+
lifecycleSettled = true;
|
|
569
|
+
stopSettled.abort();
|
|
570
|
+
};
|
|
501
571
|
let shutdownRequestedAt = startedAt;
|
|
502
572
|
let shutdownRequested = false;
|
|
503
573
|
const sinceShutdownRequested = () => clock.now() - shutdownRequestedAt;
|
|
@@ -516,7 +586,11 @@ const start = (module, options = {}) => {
|
|
|
516
586
|
const ready = () => tracker.current() === "serving" && !forcedUnready;
|
|
517
587
|
const disposeSignals = options.signals === false ? () => {} : installSignalHandlers({
|
|
518
588
|
onFirst: () => requestShutdown("signal"),
|
|
519
|
-
onSecond: () =>
|
|
589
|
+
onSecond: () => {
|
|
590
|
+
skipDrain.abort();
|
|
591
|
+
stopSettled.abort();
|
|
592
|
+
abandonBuild("signal");
|
|
593
|
+
}
|
|
520
594
|
});
|
|
521
595
|
const disposeUncaught = options.signals === false ? () => {} : installUncaughtHandlers((cause) => {
|
|
522
596
|
emit({
|
|
@@ -526,17 +600,63 @@ const start = (module, options = {}) => {
|
|
|
526
600
|
onUnready();
|
|
527
601
|
skipDrain.abort();
|
|
528
602
|
requestShutdown("uncaught");
|
|
603
|
+
abandonBuild("uncaught");
|
|
529
604
|
});
|
|
530
605
|
let disposeProbes = () => {};
|
|
606
|
+
const disposeAll = () => {
|
|
607
|
+
disposeSignals();
|
|
608
|
+
disposeUncaught();
|
|
609
|
+
tracker.advanceTo("exited");
|
|
610
|
+
disposeProbes();
|
|
611
|
+
};
|
|
612
|
+
const reportOf = (reason, drain, abandonedAt) => ({
|
|
613
|
+
reason,
|
|
614
|
+
drain,
|
|
615
|
+
teardownErrors,
|
|
616
|
+
uptimeMs: clock.now() - startedAt,
|
|
617
|
+
...abandonedAt === void 0 ? {} : { abandonedAt }
|
|
618
|
+
});
|
|
531
619
|
let healthChecks = [];
|
|
532
620
|
const health = () => runHealthChecks(healthChecks);
|
|
533
621
|
const probeBound = Promise.withResolvers();
|
|
534
622
|
const runtimePublished = Promise.withResolvers();
|
|
623
|
+
const stopping = Promise.withResolvers();
|
|
624
|
+
const stopAbandoned = () => fromSafePromise(stopping.promise).flatMap(({ reason, drain }) => clock.sleep(stopTimeoutMs, stopSettled.signal).flatMap(() => lifecycleSettled ? withdrawn() : OkAsync(abandonStop(reason, drain))));
|
|
625
|
+
const abandonStop = (reason, drain) => {
|
|
626
|
+
emit({
|
|
627
|
+
type: "stoppedWaiting",
|
|
628
|
+
phase: "stop",
|
|
629
|
+
afterMs: stopSettled.signal.aborted ? void 0 : stopTimeoutMs
|
|
630
|
+
});
|
|
631
|
+
disposeAll();
|
|
632
|
+
return reportOf(reason, drain, "stop");
|
|
633
|
+
};
|
|
634
|
+
const abandoningBuild = Promise.withResolvers();
|
|
635
|
+
const buildAbandoned = () => fromSafePromise(abandoningBuild.promise).map((reason) => {
|
|
636
|
+
emit({
|
|
637
|
+
type: "stoppedWaiting",
|
|
638
|
+
phase: "build",
|
|
639
|
+
afterMs: void 0
|
|
640
|
+
});
|
|
641
|
+
registry.abortAll();
|
|
642
|
+
runtimePublished.resolve(void 0);
|
|
643
|
+
tracker.advanceTo("stopping");
|
|
644
|
+
disposeAll();
|
|
645
|
+
return reportOf(reason, void 0, "build");
|
|
646
|
+
});
|
|
647
|
+
const abandonBuild = (reason) => {
|
|
648
|
+
const phase = tracker.current();
|
|
649
|
+
if (phase === "building" || phase === "starting") abandoningBuild.resolve(reason);
|
|
650
|
+
};
|
|
535
651
|
emit({ type: "building" });
|
|
536
|
-
const probesOptions = kernelConfig.map(({ probePort }) => options.probes === false ? false : {
|
|
652
|
+
const probesOptions = kernelConfig.map(({ probePort, probeHost }) => options.probes === false ? false : {
|
|
653
|
+
port: probePort,
|
|
654
|
+
hostname: probeHost
|
|
655
|
+
});
|
|
537
656
|
if (options.probes === false) probeBound.resolve(void 0);
|
|
538
657
|
const probesStarted = probesOptions.toAsync().flatMap((probes) => probes === false ? OkAsync() : startProbeServer({
|
|
539
658
|
port: probes.port,
|
|
659
|
+
hostname: probes.hostname,
|
|
540
660
|
live,
|
|
541
661
|
ready,
|
|
542
662
|
health
|
|
@@ -591,97 +711,98 @@ const start = (module, options = {}) => {
|
|
|
591
711
|
if (reason !== "signal") registry.abortAll();
|
|
592
712
|
return (reason === "signal" ? runDrain(serving) : OkAsync(void 0)).flatMap((report) => {
|
|
593
713
|
tracker.advanceTo("stopping");
|
|
714
|
+
stopping.resolve({
|
|
715
|
+
reason,
|
|
716
|
+
drain: report
|
|
717
|
+
});
|
|
594
718
|
return serving.stop().map(() => {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
tracker.advanceTo("exited");
|
|
598
|
-
disposeProbes();
|
|
599
|
-
return {
|
|
600
|
-
reason,
|
|
601
|
-
drain: report,
|
|
602
|
-
teardownErrors,
|
|
603
|
-
uptimeMs: clock.now() - startedAt
|
|
604
|
-
};
|
|
719
|
+
disposeAll();
|
|
720
|
+
return reportOf(reason, report);
|
|
605
721
|
});
|
|
606
722
|
});
|
|
607
723
|
};
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
return fromSafePromise(ready.promise);
|
|
638
|
-
};
|
|
639
|
-
const outcome = (async () => {
|
|
640
|
-
try {
|
|
641
|
-
return await work({
|
|
642
|
-
ctx: runtimeCtx,
|
|
643
|
-
fork
|
|
644
|
-
}, signal);
|
|
645
|
-
} finally {
|
|
646
|
-
hasSettled = true;
|
|
647
|
-
settled.resolve();
|
|
648
|
-
if (closing !== void 0) await closing;
|
|
649
|
-
}
|
|
650
|
-
})();
|
|
651
|
-
return fromSafePromise(outcome).flatMap((result) => result);
|
|
652
|
-
});
|
|
653
|
-
const host = {
|
|
654
|
-
ctx: runtimeCtx,
|
|
655
|
-
run
|
|
724
|
+
const built = () => Module.scoped(root, (ctx) => {
|
|
725
|
+
tracker.advanceTo("starting");
|
|
726
|
+
const runtime = ctx.get(RuntimePort);
|
|
727
|
+
runtimeName = runtime.name;
|
|
728
|
+
healthChecks = ctx.get(HealthChecks);
|
|
729
|
+
const runtimeCtx = ctx;
|
|
730
|
+
const run = (meta, work) => registry.run(meta, (signal) => {
|
|
731
|
+
const settled = Promise.withResolvers();
|
|
732
|
+
let closing;
|
|
733
|
+
let hasSettled = false;
|
|
734
|
+
const fork = (module, seed) => {
|
|
735
|
+
if (hasSettled) return fromSafePromise(Promise.reject(/* @__PURE__ */ new Error("a unit forks after it has already settled")));
|
|
736
|
+
if (closing !== void 0) return fromSafePromise(Promise.reject(/* @__PURE__ */ new Error("a unit forks its scope once")));
|
|
737
|
+
const ready = Promise.withResolvers();
|
|
738
|
+
closing = Module.forkScope(ctx, module, (forked) => {
|
|
739
|
+
ready.resolve(forked);
|
|
740
|
+
return fromSafePromise(settled.promise);
|
|
741
|
+
}, {
|
|
742
|
+
seed,
|
|
743
|
+
onTeardownError: (port, cause) => emit({
|
|
744
|
+
type: "teardownError",
|
|
745
|
+
port,
|
|
746
|
+
cause
|
|
747
|
+
})
|
|
748
|
+
}).recoverDefect((cause) => {
|
|
749
|
+
ready.reject(cause);
|
|
750
|
+
return Ok();
|
|
751
|
+
}).get();
|
|
752
|
+
return fromSafePromise(ready.promise);
|
|
656
753
|
};
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
754
|
+
const outcome = (async () => {
|
|
755
|
+
try {
|
|
756
|
+
return await work({
|
|
757
|
+
ctx: runtimeCtx,
|
|
758
|
+
fork
|
|
759
|
+
}, signal);
|
|
760
|
+
} finally {
|
|
761
|
+
hasSettled = true;
|
|
762
|
+
settled.resolve();
|
|
763
|
+
if (closing !== void 0) await closing;
|
|
764
|
+
}
|
|
765
|
+
})();
|
|
766
|
+
return fromSafePromise(outcome).flatMap((result) => result);
|
|
767
|
+
});
|
|
768
|
+
const host = {
|
|
769
|
+
ctx: runtimeCtx,
|
|
770
|
+
run
|
|
771
|
+
};
|
|
772
|
+
return runtime.start(host).flatMap((serving) => {
|
|
773
|
+
servingInfo = serving.info;
|
|
774
|
+
tracker.advanceTo("serving");
|
|
775
|
+
runtimePublished.resolve(serving.info);
|
|
776
|
+
serving.stopped?.().map(() => {
|
|
777
|
+
requestShutdown("runtimeStopped");
|
|
677
778
|
});
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
})
|
|
779
|
+
return fromSafePromise(shutdown.promise).flatMap((reason) => finish(serving, reason));
|
|
780
|
+
});
|
|
781
|
+
}, { onTeardownError: (port, cause) => {
|
|
782
|
+
teardownErrors.push({
|
|
783
|
+
port,
|
|
784
|
+
cause
|
|
785
|
+
});
|
|
786
|
+
emit({
|
|
787
|
+
type: "teardownError",
|
|
788
|
+
port,
|
|
789
|
+
cause
|
|
790
|
+
});
|
|
791
|
+
} }).tapFailure((failure) => {
|
|
792
|
+
if (tracker.current() !== "stopping") emit({
|
|
793
|
+
type: "startFailed",
|
|
794
|
+
cause: failure.tag === "Err" ? failure.error : failure.cause
|
|
795
|
+
});
|
|
796
|
+
runtimePublished.resolve(void 0);
|
|
797
|
+
tracker.advanceTo("stopping");
|
|
798
|
+
disposeAll();
|
|
799
|
+
}).tap(onLifecycleSettled).tapFailure(onLifecycleSettled);
|
|
800
|
+
return {
|
|
801
|
+
exited: probesStarted.flatMap(() => fromSafePromise(Promise.race([
|
|
802
|
+
built(),
|
|
803
|
+
stopAbandoned(),
|
|
804
|
+
buildAbandoned()
|
|
805
|
+
])).flatMap((settled) => settled)),
|
|
685
806
|
stop: () => requestShutdown("runtimeStopped"),
|
|
686
807
|
requestDrain: () => requestShutdown("signal"),
|
|
687
808
|
phase: tracker.current,
|
|
@@ -697,7 +818,7 @@ const EX_CONFIG = 78;
|
|
|
697
818
|
const isConfig = (error) => error instanceof ConfigInvalid || error instanceof RuntimeStartFailed && error.cause instanceof ConfigInvalid;
|
|
698
819
|
const codeFor = (report) => {
|
|
699
820
|
if (report.reason === "uncaught") return EX_SOFTWARE;
|
|
700
|
-
return (report.drain?.abandoned ?? 0) > 0 || report.teardownErrors.length > 0 ? 2 : 0;
|
|
821
|
+
return (report.drain?.abandoned ?? 0) > 0 || report.teardownErrors.length > 0 || report.abandonedAt !== void 0 ? 2 : 0;
|
|
701
822
|
};
|
|
702
823
|
/**
|
|
703
824
|
* The exit-code half of `runMain`, on its own so the code table can be asserted
|
|
@@ -730,6 +851,7 @@ const awaitExit = async (app, exit) => {
|
|
|
730
851
|
* | a configuration port that could not be bound (`ConfigInvalid`, `PROBE_PORT` included) | `78` |
|
|
731
852
|
* | drained with work abandoned | `2` |
|
|
732
853
|
* | exited with teardown errors | `2` |
|
|
854
|
+
* | stopped waiting for the teardown or a build (`ExitReport.abandonedAt`) | `2` |
|
|
733
855
|
* | stopped by an uncaught exception or unhandled rejection | `70` |
|
|
734
856
|
* | a defect | `70` |
|
|
735
857
|
*
|
|
@@ -749,4 +871,4 @@ const runMain = async (module, options = {}, exit = (code) => {
|
|
|
749
871
|
await awaitExit(start(module, options), exit);
|
|
750
872
|
};
|
|
751
873
|
//#endregion
|
|
752
|
-
export { HealthCheckFailed, HealthChecks, Instrumentations, LEVELS, Logger, Meter, Observers, RuntimePort, RuntimeStartFailed, SPAN_STATUS, Tracer, currentUnit, noObserver, observe, releasedBy, runHealthChecks, runMain, start, stderrSink, systemClock, traceIdOfTraceparent };
|
|
874
|
+
export { HealthCheckFailed, HealthChecks, Instrumentations, LEVELS, Logger, Meter, Observers, RuntimePort, RuntimeStartFailed, SPAN_STATUS, Tracer, currentUnit, noObserver, observe, observed, 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.15.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",
|
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
"./package.json": "./package.json"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
+
"@btravstack/config": "0.15.0",
|
|
49
|
+
"@btravstack/di": "0.15.0",
|
|
48
50
|
"@btravstack/tsconfig": "0.4.0",
|
|
49
51
|
"@types/node": "26.4.1",
|
|
50
52
|
"@unthrown/vitest": "5.8.0",
|
|
@@ -52,14 +54,12 @@
|
|
|
52
54
|
"tsdown": "0.23.0",
|
|
53
55
|
"typescript": "7.0.2",
|
|
54
56
|
"unthrown": "5.8.0",
|
|
55
|
-
"vitest": "4.1.11"
|
|
56
|
-
"@btravstack/config": "0.14.0",
|
|
57
|
-
"@btravstack/di": "0.14.0"
|
|
57
|
+
"vitest": "4.1.11"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"
|
|
61
|
-
"@btravstack/
|
|
62
|
-
"
|
|
60
|
+
"@btravstack/config": "^0.15.0",
|
|
61
|
+
"@btravstack/di": "^0.15.0",
|
|
62
|
+
"unthrown": "^5.0.0"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">=22"
|
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch --tsconfig tsconfig.build.json",
|
|
70
70
|
"generate": "node ../../docs/scripts/extract-doc-samples.ts --group core --out src/generated/doc-samples",
|
|
71
71
|
"test": "vitest run --coverage",
|
|
72
|
-
"test:types": "tsc --noEmit -p tsconfig.test-d.json",
|
|
73
72
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test-d.json"
|
|
74
73
|
}
|
|
75
74
|
}
|