@mailwoman/api-kit 8.1.0 → 8.3.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/error.ts +3 -1
- package/geo.ts +12 -4
- package/metrics.ts +16 -7
- package/openapi.ts +9 -3
- package/out/error.d.ts +3 -1
- package/out/error.d.ts.map +1 -1
- package/out/error.js +3 -1
- package/out/error.js.map +1 -1
- package/out/geo.d.ts +12 -4
- package/out/geo.d.ts.map +1 -1
- package/out/geo.js +12 -4
- package/out/geo.js.map +1 -1
- package/out/metrics.d.ts +6 -2
- package/out/metrics.d.ts.map +1 -1
- package/out/metrics.js +16 -7
- package/out/metrics.js.map +1 -1
- package/out/openapi.d.ts +6 -2
- package/out/openapi.d.ts.map +1 -1
- package/out/openapi.js +9 -3
- package/out/openapi.js.map +1 -1
- package/out/serve.d.ts +9 -3
- package/out/serve.d.ts.map +1 -1
- package/out/serve.js +3 -1
- package/out/serve.js.map +1 -1
- package/package.json +1 -1
- package/serve.ts +9 -3
package/error.ts
CHANGED
|
@@ -12,7 +12,9 @@ import { z } from "@hono/zod-openapi"
|
|
|
12
12
|
import type { Context } from "hono"
|
|
13
13
|
import type { ContentfulStatusCode } from "hono/utils/http-status"
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* The native error envelope: a short machine-stable `error` string plus an optional human `detail`.
|
|
17
|
+
*/
|
|
16
18
|
export const APIErrorSchema = z
|
|
17
19
|
.object({
|
|
18
20
|
error: z.string(),
|
package/geo.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
import { z } from "@hono/zod-openapi"
|
|
12
12
|
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* A GeoJSON Point geometry: `[lon, lat]`.
|
|
15
|
+
*/
|
|
14
16
|
export const PointGeometrySchema = z
|
|
15
17
|
.object({
|
|
16
18
|
type: z.literal("Point"),
|
|
@@ -18,10 +20,14 @@ export const PointGeometrySchema = z
|
|
|
18
20
|
})
|
|
19
21
|
.openapi("PointGeometry")
|
|
20
22
|
|
|
21
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* A `[minLon, minLat, maxLon, maxLat]`-style 4-tuple (photon's `extent` uses `[minLon, maxLat, maxLon, minLat]`).
|
|
25
|
+
*/
|
|
22
26
|
export const BBoxSchema = z.tuple([z.number(), z.number(), z.number(), z.number()])
|
|
23
27
|
|
|
24
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* GeoJSON Feature envelope over a surface-specific properties schema.
|
|
30
|
+
*/
|
|
25
31
|
export function featureSchema<P extends z.ZodTypeAny>(properties: P) {
|
|
26
32
|
return z.object({
|
|
27
33
|
type: z.literal("Feature"),
|
|
@@ -30,7 +36,9 @@ export function featureSchema<P extends z.ZodTypeAny>(properties: P) {
|
|
|
30
36
|
})
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* GeoJSON FeatureCollection envelope over a feature schema.
|
|
41
|
+
*/
|
|
34
42
|
export function featureCollectionSchema<F extends z.ZodTypeAny>(feature: F) {
|
|
35
43
|
return z.object({
|
|
36
44
|
type: z.literal("FeatureCollection"),
|
package/metrics.ts
CHANGED
|
@@ -12,13 +12,17 @@
|
|
|
12
12
|
* state: under `node:cluster` each worker reports its own snapshot — aggregate at the scraper.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Recent-latency reservoir size. ~2k samples gives stable p99 without unbounded memory.
|
|
17
|
+
*/
|
|
16
18
|
const MAX_SAMPLES = 2048
|
|
17
19
|
|
|
18
20
|
const latencies: number[] = []
|
|
19
21
|
let writeIdx = 0
|
|
20
22
|
|
|
21
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Null-prototype: tier keys are created lazily on first use, not eagerly pre-populated.
|
|
25
|
+
*/
|
|
22
26
|
const tierCounts: Record<string, number> = Object.create(null)
|
|
23
27
|
let total = 0
|
|
24
28
|
let errors = 0
|
|
@@ -46,7 +50,7 @@ export function recordTimed(latencyMs: number, tier: string): void {
|
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
function percentile(sorted: number[], p: number): number {
|
|
49
|
-
if (sorted.length
|
|
53
|
+
if (!sorted.length) return 0
|
|
50
54
|
const idx = Math.min(sorted.length - 1, Math.floor(p * sorted.length))
|
|
51
55
|
|
|
52
56
|
return Math.round(sorted[idx]! * 100) / 100
|
|
@@ -67,9 +71,11 @@ export interface MetricsSnapshot {
|
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Current metrics snapshot — sorted-reservoir percentiles + counters.
|
|
76
|
+
*/
|
|
71
77
|
export function metricsSnapshot(): MetricsSnapshot {
|
|
72
|
-
const sorted = [...latencies].
|
|
78
|
+
const sorted = [...latencies].toSorted((a, b) => a - b)
|
|
73
79
|
|
|
74
80
|
return {
|
|
75
81
|
uptime_s: Math.round((Date.now() - startedAt) / 1000),
|
|
@@ -82,7 +88,7 @@ export function metricsSnapshot(): MetricsSnapshot {
|
|
|
82
88
|
p50: percentile(sorted, 0.5),
|
|
83
89
|
p90: percentile(sorted, 0.9),
|
|
84
90
|
p99: percentile(sorted, 0.99),
|
|
85
|
-
max: Math.round(sorted
|
|
91
|
+
max: Math.round(sorted.at(-1)! * 100) / 100,
|
|
86
92
|
}
|
|
87
93
|
: null,
|
|
88
94
|
latency_samples: sorted.length,
|
|
@@ -90,12 +96,15 @@ export function metricsSnapshot(): MetricsSnapshot {
|
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Test-only reset of all counters + the reservoir.
|
|
101
|
+
*/
|
|
94
102
|
export function resetMetricsForTest(): void {
|
|
95
103
|
latencies.length = 0
|
|
96
104
|
writeIdx = 0
|
|
97
105
|
|
|
98
106
|
for (const key of Object.keys(tierCounts)) {
|
|
107
|
+
// oxlint-disable-next-line typescript/no-dynamic-delete -- removing one key from a plain record; the object is not on a hot path
|
|
99
108
|
delete tierCounts[key]
|
|
100
109
|
}
|
|
101
110
|
|
package/openapi.ts
CHANGED
|
@@ -35,7 +35,9 @@ export interface OpenAPIDocInfo {
|
|
|
35
35
|
security?: unknown[]
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Split an `OpenAPIDocInfo` into the document's `info` block and its top-level sibling fields.
|
|
40
|
+
*/
|
|
39
41
|
function toDocumentConfig(info: OpenAPIDocInfo) {
|
|
40
42
|
const { title, version, description, summary, license, contact, externalDocs, servers, tags, security } = info
|
|
41
43
|
|
|
@@ -48,14 +50,18 @@ function toDocumentConfig(info: OpenAPIDocInfo) {
|
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Mount the OpenAPI 3.1 document endpoint on `app` (default `/openapi.json`).
|
|
55
|
+
*/
|
|
52
56
|
export function attachOpenAPIDocs(app: OpenAPIHono, info: OpenAPIDocInfo, path = "/openapi.json"): void {
|
|
53
57
|
// openapi3-ts's InfoObject/OpenAPIObject carry an `x-${string}` extension index signature that
|
|
54
58
|
// a plain interface can't satisfy — cast at the boundary rather than widening the public type.
|
|
55
59
|
app.doc31(path, { openapi: "3.1.0", ...toDocumentConfig(info) } as never)
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Emit both document flavors programmatically (build artifacts, parity tests, client generation).
|
|
64
|
+
*/
|
|
59
65
|
export function emitOpenAPIDocuments(app: OpenAPIHono, info: OpenAPIDocInfo): { v31: object; v30: object } {
|
|
60
66
|
return {
|
|
61
67
|
v31: app.getOpenAPI31Document({ openapi: "3.1.0", ...toDocumentConfig(info) } as never),
|
package/out/error.d.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
import { z } from "@hono/zod-openapi";
|
|
11
11
|
import type { Context } from "hono";
|
|
12
12
|
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* The native error envelope: a short machine-stable `error` string plus an optional human `detail`.
|
|
15
|
+
*/
|
|
14
16
|
export declare const APIErrorSchema: z.ZodObject<{
|
|
15
17
|
error: z.ZodString;
|
|
16
18
|
detail: z.ZodOptional<z.ZodString>;
|
package/out/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAElE
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAElE;;GAEG;AACH,eAAO,MAAM,cAAc;;;iBAKN,CAAA;AAErB;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,oBAAoB,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;;;;;cAE7G"}
|
package/out/error.js
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* `@mailwoman/api` native `/v1/*` routes), where nothing constrains the wire shape but us.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from "@hono/zod-openapi";
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* The native error envelope: a short machine-stable `error` string plus an optional human `detail`.
|
|
13
|
+
*/
|
|
12
14
|
export const APIErrorSchema = z
|
|
13
15
|
.object({
|
|
14
16
|
error: z.string(),
|
package/out/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAIrC
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAIrC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC7B,MAAM,CAAC;IACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,OAAO,CAAC,UAAU,CAAC,CAAA;AAErB;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAiC,CAAU,EAAE,MAAS,EAAE,KAAa,EAAE,MAAe;IAC7G,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAA;AAC5E,CAAC"}
|
package/out/geo.d.ts
CHANGED
|
@@ -8,14 +8,20 @@
|
|
|
8
8
|
* guardrails in the 2026-07-12 design spec.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from "@hono/zod-openapi";
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* A GeoJSON Point geometry: `[lon, lat]`.
|
|
13
|
+
*/
|
|
12
14
|
export declare const PointGeometrySchema: z.ZodObject<{
|
|
13
15
|
type: z.ZodLiteral<"Point">;
|
|
14
16
|
coordinates: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
15
17
|
}, z.core.$strip>;
|
|
16
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* A `[minLon, minLat, maxLon, maxLat]`-style 4-tuple (photon's `extent` uses `[minLon, maxLat, maxLon, minLat]`).
|
|
20
|
+
*/
|
|
17
21
|
export declare const BBoxSchema: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
|
|
18
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* GeoJSON Feature envelope over a surface-specific properties schema.
|
|
24
|
+
*/
|
|
19
25
|
export declare function featureSchema<P extends z.ZodTypeAny>(properties: P): z.ZodObject<{
|
|
20
26
|
type: z.ZodLiteral<"Feature">;
|
|
21
27
|
geometry: z.ZodObject<{
|
|
@@ -24,7 +30,9 @@ export declare function featureSchema<P extends z.ZodTypeAny>(properties: P): z.
|
|
|
24
30
|
}, z.core.$strip>;
|
|
25
31
|
properties: P;
|
|
26
32
|
}, z.core.$strip>;
|
|
27
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* GeoJSON FeatureCollection envelope over a feature schema.
|
|
35
|
+
*/
|
|
28
36
|
export declare function featureCollectionSchema<F extends z.ZodTypeAny>(feature: F): z.ZodObject<{
|
|
29
37
|
type: z.ZodLiteral<"FeatureCollection">;
|
|
30
38
|
features: z.ZodArray<F>;
|
package/out/geo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC
|
|
1
|
+
{"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;iBAKN,CAAA;AAE1B;;GAEG;AACH,eAAO,MAAM,UAAU,wEAA4D,CAAA;AAEnF;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;;;;;;;kBAMlE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;;;kBAKzE"}
|
package/out/geo.js
CHANGED
|
@@ -8,16 +8,22 @@
|
|
|
8
8
|
* guardrails in the 2026-07-12 design spec.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from "@hono/zod-openapi";
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* A GeoJSON Point geometry: `[lon, lat]`.
|
|
13
|
+
*/
|
|
12
14
|
export const PointGeometrySchema = z
|
|
13
15
|
.object({
|
|
14
16
|
type: z.literal("Point"),
|
|
15
17
|
coordinates: z.tuple([z.number(), z.number()]),
|
|
16
18
|
})
|
|
17
19
|
.openapi("PointGeometry");
|
|
18
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A `[minLon, minLat, maxLon, maxLat]`-style 4-tuple (photon's `extent` uses `[minLon, maxLat, maxLon, minLat]`).
|
|
22
|
+
*/
|
|
19
23
|
export const BBoxSchema = z.tuple([z.number(), z.number(), z.number(), z.number()]);
|
|
20
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* GeoJSON Feature envelope over a surface-specific properties schema.
|
|
26
|
+
*/
|
|
21
27
|
export function featureSchema(properties) {
|
|
22
28
|
return z.object({
|
|
23
29
|
type: z.literal("Feature"),
|
|
@@ -25,7 +31,9 @@ export function featureSchema(properties) {
|
|
|
25
31
|
properties,
|
|
26
32
|
});
|
|
27
33
|
}
|
|
28
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* GeoJSON FeatureCollection envelope over a feature schema.
|
|
36
|
+
*/
|
|
29
37
|
export function featureCollectionSchema(feature) {
|
|
30
38
|
return z.object({
|
|
31
39
|
type: z.literal("FeatureCollection"),
|
package/out/geo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC
|
|
1
|
+
{"version":3,"file":"geo.js","sourceRoot":"","sources":["../geo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KAClC,MAAM,CAAC;IACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACxB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;CAC9C,CAAC;KACD,OAAO,CAAC,eAAe,CAAC,CAAA;AAE1B;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAEnF;;GAEG;AACH,MAAM,UAAU,aAAa,CAAyB,UAAa;IAClE,OAAO,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1B,QAAQ,EAAE,mBAAmB;QAC7B,UAAU;KACV,CAAC,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAyB,OAAU;IACzE,OAAO,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;QACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;KAC1B,CAAC,CAAA;AACH,CAAC"}
|
package/out/metrics.d.ts
CHANGED
|
@@ -35,8 +35,12 @@ export interface MetricsSnapshot {
|
|
|
35
35
|
latency_samples: number;
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Current metrics snapshot — sorted-reservoir percentiles + counters.
|
|
40
|
+
*/
|
|
39
41
|
export declare function metricsSnapshot(): MetricsSnapshot;
|
|
40
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Test-only reset of all counters + the reservoir.
|
|
44
|
+
*/
|
|
41
45
|
export declare function resetMetricsForTest(): void;
|
|
42
46
|
//# sourceMappingURL=metrics.d.ts.map
|
package/out/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkBH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAejE;AASD,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE;QACR,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd;;;WAGG;QACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7B,UAAU,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAA;QACzE,eAAe,EAAE,MAAM,CAAA;KACvB,CAAA;CACD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,CAoBjD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAW1C"}
|
package/out/metrics.js
CHANGED
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
* Surfaced by `GET /metrics`; reset on process restart (no persistence — scrape it). Per-process
|
|
12
12
|
* state: under `node:cluster` each worker reports its own snapshot — aggregate at the scraper.
|
|
13
13
|
*/
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Recent-latency reservoir size. ~2k samples gives stable p99 without unbounded memory.
|
|
16
|
+
*/
|
|
15
17
|
const MAX_SAMPLES = 2048;
|
|
16
18
|
const latencies = [];
|
|
17
19
|
let writeIdx = 0;
|
|
18
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Null-prototype: tier keys are created lazily on first use, not eagerly pre-populated.
|
|
22
|
+
*/
|
|
19
23
|
const tierCounts = Object.create(null);
|
|
20
24
|
let total = 0;
|
|
21
25
|
let errors = 0;
|
|
@@ -41,14 +45,16 @@ export function recordTimed(latencyMs, tier) {
|
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
function percentile(sorted, p) {
|
|
44
|
-
if (sorted.length
|
|
48
|
+
if (!sorted.length)
|
|
45
49
|
return 0;
|
|
46
50
|
const idx = Math.min(sorted.length - 1, Math.floor(p * sorted.length));
|
|
47
51
|
return Math.round(sorted[idx] * 100) / 100;
|
|
48
52
|
}
|
|
49
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Current metrics snapshot — sorted-reservoir percentiles + counters.
|
|
55
|
+
*/
|
|
50
56
|
export function metricsSnapshot() {
|
|
51
|
-
const sorted = [...latencies].
|
|
57
|
+
const sorted = [...latencies].toSorted((a, b) => a - b);
|
|
52
58
|
return {
|
|
53
59
|
uptime_s: Math.round((Date.now() - startedAt) / 1000),
|
|
54
60
|
timings: {
|
|
@@ -60,18 +66,21 @@ export function metricsSnapshot() {
|
|
|
60
66
|
p50: percentile(sorted, 0.5),
|
|
61
67
|
p90: percentile(sorted, 0.9),
|
|
62
68
|
p99: percentile(sorted, 0.99),
|
|
63
|
-
max: Math.round(sorted
|
|
69
|
+
max: Math.round(sorted.at(-1) * 100) / 100,
|
|
64
70
|
}
|
|
65
71
|
: null,
|
|
66
72
|
latency_samples: sorted.length,
|
|
67
73
|
},
|
|
68
74
|
};
|
|
69
75
|
}
|
|
70
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Test-only reset of all counters + the reservoir.
|
|
78
|
+
*/
|
|
71
79
|
export function resetMetricsForTest() {
|
|
72
80
|
latencies.length = 0;
|
|
73
81
|
writeIdx = 0;
|
|
74
82
|
for (const key of Object.keys(tierCounts)) {
|
|
83
|
+
// oxlint-disable-next-line typescript/no-dynamic-delete -- removing one key from a plain record; the object is not on a hot path
|
|
75
84
|
delete tierCounts[key];
|
|
76
85
|
}
|
|
77
86
|
total = 0;
|
package/out/metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../metrics.ts"],"names":[],"mappings":"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"}
|
package/out/openapi.d.ts
CHANGED
|
@@ -44,9 +44,13 @@ export interface OpenAPIDocInfo {
|
|
|
44
44
|
}>;
|
|
45
45
|
security?: unknown[];
|
|
46
46
|
}
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Mount the OpenAPI 3.1 document endpoint on `app` (default `/openapi.json`).
|
|
49
|
+
*/
|
|
48
50
|
export declare function attachOpenAPIDocs(app: OpenAPIHono, info: OpenAPIDocInfo, path?: string): void;
|
|
49
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Emit both document flavors programmatically (build artifacts, parity tests, client generation).
|
|
53
|
+
*/
|
|
50
54
|
export declare function emitOpenAPIDocuments(app: OpenAPIHono, info: OpenAPIDocInfo): {
|
|
51
55
|
v31: object;
|
|
52
56
|
v30: object;
|
package/out/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/C,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC,YAAY,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACpD,OAAO,CAAC,EAAE,KAAK,CAAC;QACf,GAAG,EAAE,MAAM,CAAA;QACX,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACrE,CAAC,CAAA;IACF,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CACpB;
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/C,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC,YAAY,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACpD,OAAO,CAAC,EAAE,KAAK,CAAC;QACf,GAAG,EAAE,MAAM,CAAA;QACX,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACrE,CAAC,CAAA;IACF,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CACpB;AAiBD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,SAAkB,GAAG,IAAI,CAItG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAKzG;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,IAAI,CAUN"}
|
package/out/openapi.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname } from "node:path";
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Split an `OpenAPIDocInfo` into the document's `info` block and its top-level sibling fields.
|
|
14
|
+
*/
|
|
13
15
|
function toDocumentConfig(info) {
|
|
14
16
|
const { title, version, description, summary, license, contact, externalDocs, servers, tags, security } = info;
|
|
15
17
|
return {
|
|
@@ -20,13 +22,17 @@ function toDocumentConfig(info) {
|
|
|
20
22
|
security,
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Mount the OpenAPI 3.1 document endpoint on `app` (default `/openapi.json`).
|
|
27
|
+
*/
|
|
24
28
|
export function attachOpenAPIDocs(app, info, path = "/openapi.json") {
|
|
25
29
|
// openapi3-ts's InfoObject/OpenAPIObject carry an `x-${string}` extension index signature that
|
|
26
30
|
// a plain interface can't satisfy — cast at the boundary rather than widening the public type.
|
|
27
31
|
app.doc31(path, { openapi: "3.1.0", ...toDocumentConfig(info) });
|
|
28
32
|
}
|
|
29
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Emit both document flavors programmatically (build artifacts, parity tests, client generation).
|
|
35
|
+
*/
|
|
30
36
|
export function emitOpenAPIDocuments(app, info) {
|
|
31
37
|
return {
|
|
32
38
|
v31: app.getOpenAPI31Document({ openapi: "3.1.0", ...toDocumentConfig(info) }),
|
package/out/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA0BnC
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA0BnC;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAoB;IAC7C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;IAE9G,OAAO;QACN,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;QAChE,YAAY;QACZ,OAAO;QACP,IAAI;QACJ,QAAQ;KACR,CAAA;AACF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAgB,EAAE,IAAoB,EAAE,IAAI,GAAG,eAAe;IAC/F,+FAA+F;IAC/F,+FAA+F;IAC/F,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAW,CAAC,CAAA;AAC1E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAgB,EAAE,IAAoB;IAC1E,OAAO;QACN,GAAG,EAAE,GAAG,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAW,CAAC;QACvF,GAAG,EAAE,GAAG,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAW,CAAC;KACrF,CAAA;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CACnC,GAAgB,EAChB,IAAoB,EACpB,OAA0C,EAAE;IAE5C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAE9D,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,CAAA;IACrC,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAClB,CAAC;AACF,CAAC"}
|
package/out/serve.d.ts
CHANGED
|
@@ -7,13 +7,17 @@
|
|
|
7
7
|
* surface packages stay web-standard (they only export `fetch`-shaped apps) so an edge
|
|
8
8
|
* deployment needs no changes to them.
|
|
9
9
|
*/
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* A `fetch`-shaped request handler (what `OpenAPIHono.fetch` provides).
|
|
12
|
+
*/
|
|
11
13
|
export type FetchLike = (request: Request, ...args: never[]) => Response | Promise<Response>;
|
|
12
14
|
export interface ServeNodeOptions {
|
|
13
15
|
fetch: FetchLike;
|
|
14
16
|
port: number;
|
|
15
17
|
hostname: string;
|
|
16
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Called once the listener is bound — receives the actual port (useful with `port: 0`).
|
|
20
|
+
*/
|
|
17
21
|
onListen?: (info: {
|
|
18
22
|
port: number;
|
|
19
23
|
address: string;
|
|
@@ -22,6 +26,8 @@ export interface ServeNodeOptions {
|
|
|
22
26
|
export interface ServerHandle {
|
|
23
27
|
close(): Promise<void>;
|
|
24
28
|
}
|
|
25
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Boot a node HTTP listener for a Hono app. Returns a handle whose `close()` resolves when the listener is down.
|
|
31
|
+
*/
|
|
26
32
|
export declare function serveNode(options: ServeNodeOptions): ServerHandle;
|
|
27
33
|
//# sourceMappingURL=serve.d.ts.map
|
package/out/serve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE5F,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5D;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAWjE"}
|
package/out/serve.js
CHANGED
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* deployment needs no changes to them.
|
|
9
9
|
*/
|
|
10
10
|
import { serve } from "@hono/node-server";
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Boot a node HTTP listener for a Hono app. Returns a handle whose `close()` resolves when the listener is down.
|
|
13
|
+
*/
|
|
12
14
|
export function serveNode(options) {
|
|
13
15
|
const server = serve({ fetch: options.fetch, port: options.port, hostname: options.hostname }, (info) => options.onListen?.({ port: info.port, address: info.address }));
|
|
14
16
|
return {
|
package/out/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAqBzC;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAc,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAChH,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAC9D,CAAA;IAED,OAAO;QACN,KAAK,EAAE,GAAG,EAAE,CACX,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QACrE,CAAC,CAAC;KACH,CAAA;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailwoman/api-kit",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"description": "API plumbing for Mailwoman's HTTP surfaces — Hono node serve wrapper, OpenAPI emit helpers, shared wire atoms. Plumbing only: domain schemas live with their routes.",
|
|
5
5
|
"license": "AGPL-3.0-only OR LicenseRef-Commercial",
|
|
6
6
|
"repository": {
|
package/serve.ts
CHANGED
|
@@ -10,14 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
import { serve } from "@hono/node-server"
|
|
12
12
|
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* A `fetch`-shaped request handler (what `OpenAPIHono.fetch` provides).
|
|
15
|
+
*/
|
|
14
16
|
export type FetchLike = (request: Request, ...args: never[]) => Response | Promise<Response>
|
|
15
17
|
|
|
16
18
|
export interface ServeNodeOptions {
|
|
17
19
|
fetch: FetchLike
|
|
18
20
|
port: number
|
|
19
21
|
hostname: string
|
|
20
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Called once the listener is bound — receives the actual port (useful with `port: 0`).
|
|
24
|
+
*/
|
|
21
25
|
onListen?: (info: { port: number; address: string }) => void
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -25,7 +29,9 @@ export interface ServerHandle {
|
|
|
25
29
|
close(): Promise<void>
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Boot a node HTTP listener for a Hono app. Returns a handle whose `close()` resolves when the listener is down.
|
|
34
|
+
*/
|
|
29
35
|
export function serveNode(options: ServeNodeOptions): ServerHandle {
|
|
30
36
|
const server = serve({ fetch: options.fetch as never, port: options.port, hostname: options.hostname }, (info) =>
|
|
31
37
|
options.onListen?.({ port: info.port, address: info.address })
|