@nwire/endpoint 0.10.0 → 0.11.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 +9 -12
- package/dist/adapter.d.ts +25 -0
- package/dist/endpoint-index.d.ts +1 -1
- package/dist/endpoint.d.ts +27 -5
- package/dist/endpoint.js +40 -10
- package/dist/lifecycle.d.ts +3 -3
- package/dist/lifecycle.js +9 -9
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -18,10 +18,7 @@ import { httpKoa } from "@nwire/koa";
|
|
|
18
18
|
const app = createApp({ appName: "api" });
|
|
19
19
|
// ... app.wire(...) wires here ...
|
|
20
20
|
|
|
21
|
-
await endpoint("api", { port: 3000 })
|
|
22
|
-
.use(httpKoa())
|
|
23
|
-
.mount(app)
|
|
24
|
-
.run();
|
|
21
|
+
await endpoint("api", { port: 3000 }).use(httpKoa()).mount(app).run();
|
|
25
22
|
```
|
|
26
23
|
|
|
27
24
|
`.use(adopter)` installs a transport runtime — `httpKoa`, `expressAdapter`,
|
|
@@ -70,12 +67,12 @@ through the runtime when forge is in play, or directly otherwise.
|
|
|
70
67
|
|
|
71
68
|
## Lifecycle
|
|
72
69
|
|
|
73
|
-
| Stage
|
|
74
|
-
|
|
|
75
|
-
| `boot`
|
|
76
|
-
| `serve`
|
|
77
|
-
| `drain`
|
|
78
|
-
| `close`
|
|
70
|
+
| Stage | What runs |
|
|
71
|
+
| ------- | ------------------------------------------------------ |
|
|
72
|
+
| `boot` | App plugins boot; adopters consume wires; probes open. |
|
|
73
|
+
| `serve` | Adopters listen / subscribe; readiness flips green. |
|
|
74
|
+
| `drain` | SIGTERM/SIGINT: stop accepting new work, finish open. |
|
|
75
|
+
| `close` | Adopters shut down in reverse order; probes close. |
|
|
79
76
|
|
|
80
77
|
`endpoint()` returns a `RunningEndpoint` from `.run()`. Tests call
|
|
81
78
|
`running.shutdown("test")` to skip the SIGTERM dance.
|
|
@@ -84,10 +81,10 @@ through the runtime when forge is in play, or directly otherwise.
|
|
|
84
81
|
|
|
85
82
|
```ts
|
|
86
83
|
endpoint("api", {
|
|
87
|
-
banner: true,
|
|
84
|
+
banner: true, // boot banner on stdout
|
|
88
85
|
probes: { port: 9_400, enabled: true },
|
|
89
86
|
shutdown: { drainTimeout: 30_000, hardTimeout: 5_000 },
|
|
90
|
-
exitOnShutdown: true,
|
|
87
|
+
exitOnShutdown: true, // tests pass false
|
|
91
88
|
});
|
|
92
89
|
```
|
|
93
90
|
|
package/dist/adapter.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import type { Wire } from "@nwire/wires";
|
|
13
13
|
import type { Container } from "@nwire/container";
|
|
14
14
|
import type { Logger } from "@nwire/logger";
|
|
15
|
+
import type { OutboundStage } from "@nwire/runtime";
|
|
15
16
|
import type { HealthCheck } from "./lifecycle.js";
|
|
16
17
|
export interface AdapterBootContext {
|
|
17
18
|
/**
|
|
@@ -38,15 +39,39 @@ export interface AdapterBootContext {
|
|
|
38
39
|
readonly port?: number;
|
|
39
40
|
/** Endpoint-level host hint, paired with `port`. */
|
|
40
41
|
readonly host?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Install an outbound pipeline stage on the mounted App's runtime.
|
|
44
|
+
* Outbound adapters (queuePublisher, natsPublisher, webhookSink, …) call
|
|
45
|
+
* this at boot to install their terminal stage; inbound adapters ignore
|
|
46
|
+
* it. Undefined when no App is mounted — the adapter is free to skip
|
|
47
|
+
* or fall back to a foreign-host integration.
|
|
48
|
+
*/
|
|
49
|
+
readonly installSinkStage?: (stage: OutboundStage) => void;
|
|
41
50
|
}
|
|
42
51
|
/**
|
|
43
52
|
* Structural shape every transport adopter satisfies. Adopters never
|
|
44
53
|
* extend a base class — the contract is duck-typed at the endpoint.
|
|
54
|
+
*
|
|
55
|
+
* `direction` distinguishes the two membrane roles:
|
|
56
|
+
*
|
|
57
|
+
* - "inbound" — transport → execute. HTTP server, queue listener, cron.
|
|
58
|
+
* These consume wires and translate inbound traffic to
|
|
59
|
+
* `app.execute(handler, input)`.
|
|
60
|
+
*
|
|
61
|
+
* - "outbound" — sink → transport. Queue publisher, NATS publisher,
|
|
62
|
+
* webhook delivery, OTLP exporter. These install a
|
|
63
|
+
* terminal sink stage at boot and translate published
|
|
64
|
+
* events into transport messages.
|
|
65
|
+
*
|
|
66
|
+
* Optional, defaulting to "inbound" so adapters that haven't declared
|
|
67
|
+
* direction continue to behave as inbound transports.
|
|
45
68
|
*/
|
|
46
69
|
export interface Adapter {
|
|
47
70
|
readonly $kind: "adapter";
|
|
48
71
|
/** Adopter-kind tag — matches `binding.$adapter` on the wires it consumes. */
|
|
49
72
|
readonly kind: string;
|
|
73
|
+
/** Membrane direction. Defaults to "inbound" if absent. */
|
|
74
|
+
readonly direction?: "inbound" | "outbound";
|
|
50
75
|
boot(opts: AdapterBootContext): Promise<void>;
|
|
51
76
|
shutdown(reason?: string): Promise<void>;
|
|
52
77
|
/**
|
package/dist/endpoint-index.d.ts
CHANGED
|
@@ -19,6 +19,6 @@
|
|
|
19
19
|
* (`http-terminator` + `lightship`). The high-level builder is what most
|
|
20
20
|
* projects reach for; the low-level form is for adapters and tests.
|
|
21
21
|
*/
|
|
22
|
-
export { endpoint, EndpointBuilder, isAppServable, isForeignServable, type AppServable, type EndpointConfig, type ForeignServable, type RunningEndpoint, type Servable, } from "./endpoint.js";
|
|
22
|
+
export { endpoint, EndpointBuilder, isAppServable, isForeignServable, type AppServable, type EndpointConfig, type ProcessConfig, type ForeignServable, type RunningEndpoint, type Servable, } from "./endpoint.js";
|
|
23
23
|
export { attachLifecycle, defineCheck, type HealthCheck, type HealthConfig, type LifecycleManager, type ShutdownConfig, } from "./lifecycle.js";
|
|
24
24
|
export { isAdapter, type Adapter, type AdapterBootContext } from "./adapter.js";
|
package/dist/endpoint.d.ts
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* ## Why this exists
|
|
29
29
|
*
|
|
30
30
|
* Every framework eventually needs a process layer — something that knows
|
|
31
|
-
* about SIGTERM, drains in-flight requests, exposes `/
|
|
31
|
+
* about SIGTERM, drains in-flight requests, exposes `/live`, and binds
|
|
32
32
|
* to a port. Most frameworks bolt this on as a deployment afterthought.
|
|
33
33
|
* `@nwire/endpoint` makes it the first-class entry point so you don't
|
|
34
34
|
* write the same K8s-readiness code on every project. It works alone —
|
|
@@ -90,7 +90,12 @@ export interface ForeignServable {
|
|
|
90
90
|
export interface AppServable {
|
|
91
91
|
readonly $nwireApp: true;
|
|
92
92
|
readonly container: Container;
|
|
93
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Boot the app. Optional `appConfig` — when present, bound on the app's
|
|
95
|
+
* container as "config" so plugin boot callbacks can read it (foundation
|
|
96
|
+
* §19). Endpoint threads what was passed to `.mount(app, appConfig)`.
|
|
97
|
+
*/
|
|
98
|
+
boot(appConfig?: unknown): Promise<void>;
|
|
94
99
|
shutdown(): Promise<void>;
|
|
95
100
|
/**
|
|
96
101
|
* Optional — app name used in lifecycle event payloads. Defaults to
|
|
@@ -105,6 +110,12 @@ export interface AppServable {
|
|
|
105
110
|
*/
|
|
106
111
|
dispatchFrameworkEvent?(eventName: string, payload: unknown): Promise<boolean>;
|
|
107
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Process-level configuration for an endpoint. Owns OS-shaped concerns
|
|
115
|
+
* only: port, bind address, signal/drain budgets, probe port, banner
|
|
116
|
+
* toggle. App-level configuration (database URLs, API keys, feature
|
|
117
|
+
* flags) goes through `.mount(app, appConfig)`.
|
|
118
|
+
*/
|
|
108
119
|
export interface EndpointConfig {
|
|
109
120
|
/** Port for HTTP-class transports. Omit for queue-only / cron-only endpoints. */
|
|
110
121
|
readonly port?: number;
|
|
@@ -119,6 +130,8 @@ export interface EndpointConfig {
|
|
|
119
130
|
/** Test seam — skip process.exit() during shutdown. Default unset. */
|
|
120
131
|
readonly exitOnShutdown?: boolean;
|
|
121
132
|
}
|
|
133
|
+
/** Foundation §19 alias — `endpoint("name", processConfig)` reads as intent. */
|
|
134
|
+
export type ProcessConfig = EndpointConfig;
|
|
122
135
|
export interface RunningEndpoint {
|
|
123
136
|
readonly name: string;
|
|
124
137
|
readonly server?: Server;
|
|
@@ -162,6 +175,8 @@ export declare class EndpointBuilder {
|
|
|
162
175
|
private foreignServables;
|
|
163
176
|
private adapters;
|
|
164
177
|
private mounted;
|
|
178
|
+
/** App config threaded into `app.boot(...)` at `run()`. */
|
|
179
|
+
private mountedAppConfig;
|
|
165
180
|
/**
|
|
166
181
|
* Per-phase lifecycle hooks. Created lazily at builder-construction so
|
|
167
182
|
* they appear in `listHooks()` (and `.nwire/hooks.json` after scan)
|
|
@@ -192,10 +207,17 @@ export declare class EndpointBuilder {
|
|
|
192
207
|
use(adopter: Adapter): EndpointBuilder;
|
|
193
208
|
/**
|
|
194
209
|
* Mount the source whose wires the adopters consume. One source per
|
|
195
|
-
* endpoint — App or standalone Interface. For multi-app
|
|
196
|
-
* compose via `appCompose(...)` from `@nwire/app` and
|
|
210
|
+
* endpoint — an App or a standalone Interface. For multi-app
|
|
211
|
+
* topologies, compose via `appCompose(...)` from `@nwire/app` and
|
|
212
|
+
* mount the result.
|
|
213
|
+
*
|
|
214
|
+
* `appConfig` (when mounting an App) is threaded to `app.boot(appConfig)`
|
|
215
|
+
* at `.run()` time. Plugin boot callbacks read it via
|
|
216
|
+
* `container.resolve("config")`. The process/app config split:
|
|
217
|
+
* process config goes to `endpoint(name, processConfig)`, app config
|
|
218
|
+
* goes here.
|
|
197
219
|
*/
|
|
198
|
-
mount(source: WireSource): EndpointBuilder;
|
|
220
|
+
mount(source: WireSource, appConfig?: unknown): EndpointBuilder;
|
|
199
221
|
/**
|
|
200
222
|
* Boot all served apps in order, then attach all served interfaces +
|
|
201
223
|
* foreign apps, then start listening. Returns a {@link RunningEndpoint}
|
package/dist/endpoint.js
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* ## Why this exists
|
|
29
29
|
*
|
|
30
30
|
* Every framework eventually needs a process layer — something that knows
|
|
31
|
-
* about SIGTERM, drains in-flight requests, exposes `/
|
|
31
|
+
* about SIGTERM, drains in-flight requests, exposes `/live`, and binds
|
|
32
32
|
* to a port. Most frameworks bolt this on as a deployment afterthought.
|
|
33
33
|
* `@nwire/endpoint` makes it the first-class entry point so you don't
|
|
34
34
|
* write the same K8s-readiness code on every project. It works alone —
|
|
@@ -81,6 +81,8 @@ export class EndpointBuilder {
|
|
|
81
81
|
// ─── New-shape state (.use / .mount) ─────────────────────────────────
|
|
82
82
|
adapters = [];
|
|
83
83
|
mounted;
|
|
84
|
+
/** App config threaded into `app.boot(...)` at `run()`. */
|
|
85
|
+
mountedAppConfig = undefined;
|
|
84
86
|
/**
|
|
85
87
|
* Per-phase lifecycle hooks. Created lazily at builder-construction so
|
|
86
88
|
* they appear in `listHooks()` (and `.nwire/hooks.json` after scan)
|
|
@@ -146,10 +148,17 @@ export class EndpointBuilder {
|
|
|
146
148
|
}
|
|
147
149
|
/**
|
|
148
150
|
* Mount the source whose wires the adopters consume. One source per
|
|
149
|
-
* endpoint — App or standalone Interface. For multi-app
|
|
150
|
-
* compose via `appCompose(...)` from `@nwire/app` and
|
|
151
|
+
* endpoint — an App or a standalone Interface. For multi-app
|
|
152
|
+
* topologies, compose via `appCompose(...)` from `@nwire/app` and
|
|
153
|
+
* mount the result.
|
|
154
|
+
*
|
|
155
|
+
* `appConfig` (when mounting an App) is threaded to `app.boot(appConfig)`
|
|
156
|
+
* at `.run()` time. Plugin boot callbacks read it via
|
|
157
|
+
* `container.resolve("config")`. The process/app config split:
|
|
158
|
+
* process config goes to `endpoint(name, processConfig)`, app config
|
|
159
|
+
* goes here.
|
|
151
160
|
*/
|
|
152
|
-
mount(source) {
|
|
161
|
+
mount(source, appConfig) {
|
|
153
162
|
if (this.mounted) {
|
|
154
163
|
throw new Error(`endpoint("${this.name}").mount(): a source is already mounted ("${"appName" in this.mounted ? this.mounted.appName : "interface"}"). ` +
|
|
155
164
|
`One source per endpoint — use appCompose(...) from "@nwire/app" to compose multiple apps.`);
|
|
@@ -158,6 +167,7 @@ export class EndpointBuilder {
|
|
|
158
167
|
throw new Error(`endpoint("${this.name}").mount(): expected an App with .interface, or a standalone Interface.`);
|
|
159
168
|
}
|
|
160
169
|
this.mounted = source;
|
|
170
|
+
this.mountedAppConfig = appConfig;
|
|
161
171
|
// If mounting an App, also boot it via the existing apps array.
|
|
162
172
|
if (isAppWithInterface(source) && !this.apps.includes(source)) {
|
|
163
173
|
this.apps.push(source);
|
|
@@ -200,7 +210,15 @@ export class EndpointBuilder {
|
|
|
200
210
|
startedAt: new Date().toISOString(),
|
|
201
211
|
});
|
|
202
212
|
for (const app of this.apps) {
|
|
203
|
-
|
|
213
|
+
// Pass appConfig only to the mounted app — appCompose sub-apps don't
|
|
214
|
+
// carry their own per-app config in this path.
|
|
215
|
+
const appConfig = this.mounted && app === this.mounted ? this.mountedAppConfig : undefined;
|
|
216
|
+
if (appConfig !== undefined) {
|
|
217
|
+
await app.boot(appConfig);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
await app.boot();
|
|
221
|
+
}
|
|
204
222
|
}
|
|
205
223
|
// The container the host hands to each adopter — the first served
|
|
206
224
|
// app's. Multi-app composites carry per-wire app references that
|
|
@@ -243,14 +261,24 @@ export class EndpointBuilder {
|
|
|
243
261
|
? mountedSource
|
|
244
262
|
: mountedSource.interface;
|
|
245
263
|
const containerOf = (_w) => {
|
|
246
|
-
//
|
|
247
|
-
// container
|
|
248
|
-
//
|
|
249
|
-
// per-wire container routing.
|
|
264
|
+
// Wires tagged with a source app (via `appCompose`) route to that
|
|
265
|
+
// app's container; un-tagged wires fall back to the mounted
|
|
266
|
+
// source's container.
|
|
250
267
|
const sourceApp = mountedSource && !isInterfaceShape(mountedSource) ? mountedSource : undefined;
|
|
251
268
|
const wireApp = _w.app;
|
|
252
269
|
return wireApp?.container ?? sourceApp?.container;
|
|
253
270
|
};
|
|
271
|
+
// Outbound adapters install sink terminals on the mounted App's
|
|
272
|
+
// runtime at boot. Available only when an App with a Runtime is
|
|
273
|
+
// mounted.
|
|
274
|
+
const mountedAppRuntime = mountedSource && isAppWithInterface(mountedSource)
|
|
275
|
+
? mountedSource.runtime
|
|
276
|
+
: undefined;
|
|
277
|
+
const installSinkStage = mountedAppRuntime?.sink
|
|
278
|
+
? (stage) => {
|
|
279
|
+
mountedAppRuntime.sink(stage);
|
|
280
|
+
}
|
|
281
|
+
: undefined;
|
|
254
282
|
for (const adopter of this.adapters) {
|
|
255
283
|
const wires = sourceInterface?.forAdapter(adopter.kind) ?? [];
|
|
256
284
|
await adopter.boot({
|
|
@@ -260,6 +288,8 @@ export class EndpointBuilder {
|
|
|
260
288
|
addCheck: (c) => accumulatedChecks.push(c),
|
|
261
289
|
port: this.config.port,
|
|
262
290
|
host: this.config.host,
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
|
+
installSinkStage: installSinkStage,
|
|
263
293
|
});
|
|
264
294
|
}
|
|
265
295
|
// 3. Wrap the server (if any) with graceful shutdown + probes.
|
|
@@ -405,7 +435,7 @@ function printBanner(opts) {
|
|
|
405
435
|
: ` data: (no HTTP listener)`,
|
|
406
436
|
];
|
|
407
437
|
if (opts.probePort !== undefined) {
|
|
408
|
-
// lightship's actual paths — not /
|
|
438
|
+
// lightship's actual paths — not /ready + /live (which was a
|
|
409
439
|
// historical misnaming in our docs).
|
|
410
440
|
lines.push(` probes: http://${opts.host}:${opts.probePort}/live · /ready`);
|
|
411
441
|
}
|
package/dist/lifecycle.d.ts
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* `server.close()`. Without it, in-flight requests on persistent
|
|
8
8
|
* connections silently die when the process exits.
|
|
9
9
|
* - **lightship** — Kubernetes-style readiness/liveness probes on a
|
|
10
|
-
* separate operational port. Flips `/
|
|
10
|
+
* separate operational port. Flips `/ready` to 503 the moment shutdown
|
|
11
11
|
* starts so the load balancer stops sending new traffic — the single
|
|
12
12
|
* most important step in a zero-downtime rolling deploy.
|
|
13
13
|
*
|
|
14
14
|
* Sequence on SIGTERM/SIGINT:
|
|
15
15
|
*
|
|
16
|
-
* 1. lightship: /
|
|
16
|
+
* 1. lightship: /ready → 503 (LB removes us from rotation)
|
|
17
17
|
* 2. wait `drainDelay` (LB has time to catch up; default 10s)
|
|
18
18
|
* 3. stop accepting new connections (http-terminator)
|
|
19
19
|
* 4. drain in-flight requests (http-terminator; bounded by drainTimeout)
|
|
@@ -105,7 +105,7 @@ export interface LifecycleManager {
|
|
|
105
105
|
addCheck(check: HealthCheck): void;
|
|
106
106
|
/**
|
|
107
107
|
* Bare Node http handler for probes-on-main deployments. Mount on your
|
|
108
|
-
* own HTTP server's /
|
|
108
|
+
* own HTTP server's /live and /ready routes; the third arg picks which.
|
|
109
109
|
* No framework lock-in — works with Express, Fastify, Koa, raw http.
|
|
110
110
|
*/
|
|
111
111
|
probeHandler(req: {
|
package/dist/lifecycle.js
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* `server.close()`. Without it, in-flight requests on persistent
|
|
8
8
|
* connections silently die when the process exits.
|
|
9
9
|
* - **lightship** — Kubernetes-style readiness/liveness probes on a
|
|
10
|
-
* separate operational port. Flips `/
|
|
10
|
+
* separate operational port. Flips `/ready` to 503 the moment shutdown
|
|
11
11
|
* starts so the load balancer stops sending new traffic — the single
|
|
12
12
|
* most important step in a zero-downtime rolling deploy.
|
|
13
13
|
*
|
|
14
14
|
* Sequence on SIGTERM/SIGINT:
|
|
15
15
|
*
|
|
16
|
-
* 1. lightship: /
|
|
16
|
+
* 1. lightship: /ready → 503 (LB removes us from rotation)
|
|
17
17
|
* 2. wait `drainDelay` (LB has time to catch up; default 10s)
|
|
18
18
|
* 3. stop accepting new connections (http-terminator)
|
|
19
19
|
* 4. drain in-flight requests (http-terminator; bounded by drainTimeout)
|
|
@@ -53,8 +53,8 @@ export async function attachLifecycle(opts) {
|
|
|
53
53
|
const healthCfg = {
|
|
54
54
|
enabled: opts.health?.enabled ?? true,
|
|
55
55
|
port: opts.health?.port ?? 9_400,
|
|
56
|
-
livenessPath: opts.health?.livenessPath ?? "/
|
|
57
|
-
readinessPath: opts.health?.readinessPath ?? "/
|
|
56
|
+
livenessPath: opts.health?.livenessPath ?? "/live",
|
|
57
|
+
readinessPath: opts.health?.readinessPath ?? "/ready",
|
|
58
58
|
checks: opts.health?.checks ?? [],
|
|
59
59
|
};
|
|
60
60
|
const terminator = createHttpTerminator({
|
|
@@ -138,9 +138,9 @@ export async function attachLifecycle(opts) {
|
|
|
138
138
|
try {
|
|
139
139
|
if (lightship) {
|
|
140
140
|
lightship.signalNotReady();
|
|
141
|
-
console.log(`[lifecycle] /
|
|
141
|
+
console.log(`[lifecycle] /ready → 503; waiting ${shutdownCfg.drainDelay}ms for LB to catch up`);
|
|
142
142
|
// The drain delay exists to give the LB time to redirect traffic
|
|
143
|
-
// after /
|
|
143
|
+
// after /ready flips to 503. Without lightship, there's no probe
|
|
144
144
|
// for an LB to poll — waiting would just stall shutdown.
|
|
145
145
|
await new Promise((r) => setTimeout(r, shutdownCfg.drainDelay));
|
|
146
146
|
}
|
|
@@ -166,13 +166,13 @@ export async function attachLifecycle(opts) {
|
|
|
166
166
|
process.once("SIGTERM", () => void shutdown("SIGTERM"));
|
|
167
167
|
process.once("SIGINT", () => void shutdown("SIGINT"));
|
|
168
168
|
/**
|
|
169
|
-
* Bare Node http handler for `/
|
|
169
|
+
* Bare Node http handler for `/live` / `/ready` on the MAIN port. Use
|
|
170
170
|
* when probes-on-main is the deployment shape (Cloud Run, Lambda Function
|
|
171
171
|
* URLs, simple K8s sidecar-free setups).
|
|
172
172
|
*
|
|
173
173
|
* const probeHandler = lifecycle.probeHandler;
|
|
174
|
-
* expressApp.get("/
|
|
175
|
-
* expressApp.get("/
|
|
174
|
+
* expressApp.get("/live", (req, res) => probeHandler(req, res, "live"));
|
|
175
|
+
* expressApp.get("/ready", (req, res) => probeHandler(req, res, "ready"));
|
|
176
176
|
*
|
|
177
177
|
* `live` is always 200 unless the process is shutting down.
|
|
178
178
|
* `ready` is 200 only when all checks pass AND we're not shutting down.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nwire/endpoint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Nwire — production process lifecycle. Wraps any Node server (Express, Fastify, Koa, Nest, Nwire interfaces) with K8s-grade graceful shutdown, http-terminator drain, and lightship readiness/liveness probes. Standalone — no framework dependency beyond @nwire/container.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"endpoint",
|
|
@@ -32,10 +32,11 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"http-terminator": "^3.2.0",
|
|
34
34
|
"lightship": "^9.0.4",
|
|
35
|
-
"@nwire/
|
|
36
|
-
"@nwire/
|
|
37
|
-
"@nwire/
|
|
38
|
-
"@nwire/
|
|
35
|
+
"@nwire/hooks": "0.11.0",
|
|
36
|
+
"@nwire/runtime": "0.11.0",
|
|
37
|
+
"@nwire/container": "0.11.0",
|
|
38
|
+
"@nwire/wires": "0.11.0",
|
|
39
|
+
"@nwire/logger": "0.11.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@types/node": "^22.19.9",
|