@dunx/http 2.5.0 → 3.0.1
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 +31 -909
- package/dist/chunk-25g22350.js +58 -0
- package/dist/chunk-b699cfes.js +130 -0
- package/dist/chunk-f6pw36av.js +1299 -0
- package/dist/{chunk-jh7jk0bn.js → chunk-sz4pvqxy.js} +1 -57
- package/dist/client/module.d.ts +2 -7
- package/dist/client/service.d.ts +11 -22
- package/dist/client.d.ts +1 -2
- package/dist/client.js +12 -142
- package/dist/compression/compression.d.ts +7 -12
- package/dist/compression/options.d.ts +11 -23
- package/dist/health/indicators.d.ts +5 -10
- package/dist/index.d.ts +13 -21
- package/dist/index.js +102 -1484
- package/dist/internal.d.ts +36 -0
- package/dist/internal.js +154 -0
- package/dist/route/metadata.d.ts +6 -9
- package/dist/route/schema.d.ts +27 -55
- package/dist/server/application.d.ts +33 -89
- package/dist/server/client-address.d.ts +6 -13
- package/dist/server/errors.d.ts +24 -55
- package/dist/server/request-id.d.ts +6 -11
- package/dist/server/request-logging.d.ts +29 -101
- package/dist/server/routes.d.ts +7 -19
- package/dist/server/trace-context.d.ts +6 -10
- package/dist/static/files.d.ts +5 -13
- package/dist/static/module.d.ts +10 -19
- package/dist/throttle/guard.d.ts +6 -9
- package/dist/throttle/module.d.ts +6 -8
- package/dist/throttle/store.d.ts +11 -20
- package/dist/ws/middleware.d.ts +12 -21
- package/dist/ws/redis-relay.d.ts +9 -19
- package/package.json +6 -2
|
@@ -105,60 +105,4 @@ var HttpStatusCode = Object.freeze({
|
|
|
105
105
|
GATEWAY_TIMEOUT: 504
|
|
106
106
|
});
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
var TRACEPARENT_HEADER = "traceparent";
|
|
110
|
-
var TRACESTATE_HEADER = "tracestate";
|
|
111
|
-
var HEX_32 = /^[0-9a-f]{32}$/;
|
|
112
|
-
var HEX_16 = /^[0-9a-f]{16}$/;
|
|
113
|
-
var HEX_2 = /^[0-9a-f]{2}$/;
|
|
114
|
-
var ZERO_TRACE = "0".repeat(32);
|
|
115
|
-
var ZERO_SPAN = "0".repeat(16);
|
|
116
|
-
var SAMPLED = 1;
|
|
117
|
-
var TRACE = Symbol.for("dunx.http.trace");
|
|
118
|
-
var mintSpanId = () => Buffer.from(crypto.getRandomValues(new Uint8Array(8))).toString("hex");
|
|
119
|
-
|
|
120
|
-
class TraceContext {
|
|
121
|
-
static adopt(req, requestId) {
|
|
122
|
-
const inbound = TraceContext.#parse(req.headers.get(TRACEPARENT_HEADER));
|
|
123
|
-
const state = req.headers.get(TRACESTATE_HEADER);
|
|
124
|
-
const trace = {
|
|
125
|
-
traceId: inbound?.traceId ?? requestId.replaceAll("-", ""),
|
|
126
|
-
spanId: mintSpanId(),
|
|
127
|
-
...inbound === undefined ? {} : { parentSpanId: inbound.spanId },
|
|
128
|
-
flags: inbound?.flags ?? "01",
|
|
129
|
-
...inbound !== undefined && state !== null ? { state } : {}
|
|
130
|
-
};
|
|
131
|
-
req[TRACE] = trace;
|
|
132
|
-
return trace;
|
|
133
|
-
}
|
|
134
|
-
static of(req) {
|
|
135
|
-
return req[TRACE];
|
|
136
|
-
}
|
|
137
|
-
static header(trace) {
|
|
138
|
-
return `00-${trace.traceId}-${trace.spanId}-${trace.flags}`;
|
|
139
|
-
}
|
|
140
|
-
static sampled(trace) {
|
|
141
|
-
return (Number.parseInt(trace.flags, 16) & SAMPLED) === SAMPLED;
|
|
142
|
-
}
|
|
143
|
-
static #parse(header) {
|
|
144
|
-
if (header === null)
|
|
145
|
-
return;
|
|
146
|
-
const parts = header.split("-");
|
|
147
|
-
if (parts.length < 4)
|
|
148
|
-
return;
|
|
149
|
-
const [version, traceId, spanId, flags] = parts;
|
|
150
|
-
if (!HEX_2.test(version) || version === "ff")
|
|
151
|
-
return;
|
|
152
|
-
if (version === "00" && parts.length !== 4)
|
|
153
|
-
return;
|
|
154
|
-
if (!HEX_32.test(traceId) || traceId === ZERO_TRACE)
|
|
155
|
-
return;
|
|
156
|
-
if (!HEX_16.test(spanId) || spanId === ZERO_SPAN)
|
|
157
|
-
return;
|
|
158
|
-
if (!HEX_2.test(flags))
|
|
159
|
-
return;
|
|
160
|
-
return { traceId, spanId, flags };
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export { __privateGet, __privateAdd, __decoratorStart, __decoratorMetadata, __runInitializers, __decorateElement, HttpStatusCode, TRACEPARENT_HEADER, TRACESTATE_HEADER, TraceContext };
|
|
108
|
+
export { __privateGet, __privateAdd, __decoratorStart, __decoratorMetadata, __runInitializers, __decorateElement, HttpStatusCode };
|
package/dist/client/module.d.ts
CHANGED
|
@@ -41,13 +41,8 @@ export declare class HttpModule {
|
|
|
41
41
|
*/
|
|
42
42
|
static forRoot(init?: HttpClientOptionsInit): DynamicModule;
|
|
43
43
|
/**
|
|
44
|
-
* `forRoot` with the options behind a factory,
|
|
45
|
-
*
|
|
46
|
-
* `ConfigService`.
|
|
47
|
-
*
|
|
48
|
-
* There is no separate async machinery - the container resolves eagerly and
|
|
49
|
-
* awaits factories before any constructor runs, so awaited config is settled by
|
|
50
|
-
* the time anything is built.
|
|
44
|
+
* `forRoot` with the options behind a factory, so the base url or the timeout
|
|
45
|
+
* can come off `ConfigService`.
|
|
51
46
|
*
|
|
52
47
|
* ```ts
|
|
53
48
|
* HttpModule.forRootAsync({
|
package/dist/client/service.d.ts
CHANGED
|
@@ -43,18 +43,12 @@ export interface RequestConfig<TRequest = unknown, TResponse = unknown> {
|
|
|
43
43
|
type BaseOptions<TRequest, TResponse> = Omit<RequestConfig<TRequest, TResponse>, 'method' | 'url' | 'payload'>;
|
|
44
44
|
/**
|
|
45
45
|
* A `fetch` client with a per-request timeout, retry with backoff, request-id
|
|
46
|
-
* propagation and one log line per call.
|
|
46
|
+
* propagation and one log line per call. `fetch` and nothing else, so there is no
|
|
47
|
+
* client dependency; what it adds is the parts every caller otherwise
|
|
48
|
+
* reimplements - the timeout, the retry policy, `Retry-After`, url building, and
|
|
49
|
+
* a failure that says which call failed.
|
|
47
50
|
*
|
|
48
|
-
* `
|
|
49
|
-
* is no client dependency to justify - which is also why `axios` and `node-fetch`
|
|
50
|
-
* are banned repo-wide. What this adds over calling `fetch` yourself is the parts
|
|
51
|
-
* every caller otherwise reimplements slightly differently: the timeout, the
|
|
52
|
-
* retry policy, `Retry-After`, url building, and a failure that says which call
|
|
53
|
-
* failed.
|
|
54
|
-
*
|
|
55
|
-
* Extends `UrlHelper` from `@arkv/shared`, so `buildUrl` and `interpolate` are
|
|
56
|
-
* available on the service, and there is one implementation of them across the
|
|
57
|
-
* owner's projects rather than a fork per repo.
|
|
51
|
+
* Extends `UrlHelper` from `@arkv/shared` for `buildUrl` and `interpolate`.
|
|
58
52
|
*/
|
|
59
53
|
export declare class HttpService extends UrlHelper {
|
|
60
54
|
private readonly options;
|
|
@@ -83,18 +77,13 @@ export declare class HttpService extends UrlHelper {
|
|
|
83
77
|
readonly method?: 'GET' | 'POST';
|
|
84
78
|
}): AsyncGenerator<string>;
|
|
85
79
|
/**
|
|
86
|
-
* Resolves the target
|
|
87
|
-
*
|
|
88
|
-
* `path`.
|
|
89
|
-
*
|
|
90
|
-
* `get('/users')` is the one worth calling out. A relative first argument is what
|
|
91
|
-
* every HTTP client takes once a base url exists, and passing it straight to
|
|
92
|
-
* `buildUrl` throws `ERR_INVALID_URL` from inside `new URL()` - a message naming
|
|
93
|
-
* neither the call nor the missing base. So a first argument that is not an
|
|
94
|
-
* absolute url is treated as the path, which is what it reads as.
|
|
80
|
+
* Resolves the target: an absolute url, a path relative to `baseUrl`, or
|
|
81
|
+
* `baseUrl` plus an explicit `path`.
|
|
95
82
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
83
|
+
* A relative first argument reaching `buildUrl` throws `ERR_INVALID_URL` from
|
|
84
|
+
* inside `new URL()`, naming neither the call nor the missing base, so one that
|
|
85
|
+
* is not absolute is treated as the path. `URL.canParse` decides rather than a
|
|
86
|
+
* regex, so it cannot disagree with `new URL`.
|
|
98
87
|
*/
|
|
99
88
|
private urlFor;
|
|
100
89
|
/** `serialised` is what a `headerFactory` signs, and is `''` for no body. */
|
package/dist/client.d.ts
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* `@dunx/http` does not load any of this.
|
|
7
7
|
*/
|
|
8
8
|
export { FetchError, FetchTransportError } from './client/errors.js';
|
|
9
|
-
export { isJsonBody, isPlainObject, safeStringify } from './client/json.js';
|
|
10
9
|
export { DEFAULT_REQUEST_ID_HEADER, HttpClientOptions, type HttpClientOptionsInit, } from './client/options.js';
|
|
11
|
-
export {
|
|
10
|
+
export type { BackoffOptions, RetryOptions } from './client/retry.js';
|
|
12
11
|
export { httpClient, HttpModule } from './client/module.js';
|
|
13
12
|
export { HttpService, type HeaderFactory, type RequestConfig, type RequestMethod, } from './client/service.js';
|
package/dist/client.js
CHANGED
|
@@ -1,73 +1,16 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
HttpStatusCode,
|
|
4
3
|
TRACEPARENT_HEADER,
|
|
5
4
|
TraceContext
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
response;
|
|
16
|
-
name = "FetchError";
|
|
17
|
-
constructor(status, statusText, body, response) {
|
|
18
|
-
super(`HTTP ${status} ${statusText} from ${response.method} ${response.url}`);
|
|
19
|
-
this.status = status;
|
|
20
|
-
this.statusText = statusText;
|
|
21
|
-
this.body = body;
|
|
22
|
-
this.response = response;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
Object.defineProperty(FetchError, Symbol.for("dunx.deps"), {
|
|
26
|
-
value: () => [{ unresolved: "readonly status: number" }, { unresolved: "readonly statusText: string" }, { unresolved: "readonly body: unknown" }, { unresolved: `readonly response: {
|
|
27
|
-
readonly method: string;
|
|
28
|
-
readonly url: string;
|
|
29
|
-
readonly headers: Headers;
|
|
30
|
-
}` }]
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
class FetchTransportError extends AppError {
|
|
34
|
-
response;
|
|
35
|
-
aborted;
|
|
36
|
-
name = "FetchTransportError";
|
|
37
|
-
constructor(response, aborted, options) {
|
|
38
|
-
super(`${response.method} ${response.url} failed: ${aborted ? "aborted" : "transport error"}`, options);
|
|
39
|
-
this.response = response;
|
|
40
|
-
this.aborted = aborted;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
Object.defineProperty(FetchTransportError, Symbol.for("dunx.deps"), {
|
|
44
|
-
value: () => [{ unresolved: "readonly response: { readonly method: string; readonly url: string }" }, { unresolved: "readonly aborted: boolean" }, ErrorOptions]
|
|
45
|
-
});
|
|
46
|
-
// src/client/json.ts
|
|
47
|
-
var safeStringify = (value) => {
|
|
48
|
-
const seen = new WeakSet;
|
|
49
|
-
return JSON.stringify(value, (_key, entry) => {
|
|
50
|
-
if (typeof entry === "object" && entry !== null) {
|
|
51
|
-
if (seen.has(entry))
|
|
52
|
-
return "[Circular]";
|
|
53
|
-
seen.add(entry);
|
|
54
|
-
}
|
|
55
|
-
return entry;
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
var isPlainObject = (value) => {
|
|
59
|
-
if (typeof value !== "object" || value === null)
|
|
60
|
-
return false;
|
|
61
|
-
const proto = Object.getPrototypeOf(value);
|
|
62
|
-
return proto === Object.prototype || proto === null;
|
|
63
|
-
};
|
|
64
|
-
var isJsonBody = (payload) => {
|
|
65
|
-
if (payload === null || payload === undefined)
|
|
66
|
-
return false;
|
|
67
|
-
if (typeof payload !== "object")
|
|
68
|
-
return typeof payload !== "string";
|
|
69
|
-
return !(payload instanceof FormData || payload instanceof URLSearchParams || payload instanceof Blob || payload instanceof ArrayBuffer || payload instanceof ReadableStream || ArrayBuffer.isView(payload));
|
|
70
|
-
};
|
|
5
|
+
} from "./chunk-25g22350.js";
|
|
6
|
+
import {
|
|
7
|
+
FetchError,
|
|
8
|
+
FetchTransportError,
|
|
9
|
+
executeWithRetry,
|
|
10
|
+
isJsonBody,
|
|
11
|
+
safeStringify
|
|
12
|
+
} from "./chunk-b699cfes.js";
|
|
13
|
+
import"./chunk-sz4pvqxy.js";
|
|
71
14
|
// src/client/options.ts
|
|
72
15
|
var DEFAULT_REQUEST_ID_HEADER = "x-request-id";
|
|
73
16
|
|
|
@@ -98,71 +41,7 @@ class HttpClientOptions {
|
|
|
98
41
|
].filter(([, value]) => value !== undefined));
|
|
99
42
|
}
|
|
100
43
|
}
|
|
101
|
-
Object.defineProperty(HttpClientOptions, Symbol.for("dunx.deps"), {
|
|
102
|
-
value: () => [{ unresolved: "init: HttpClientOptionsInit = {}" }]
|
|
103
|
-
});
|
|
104
|
-
// src/client/retry.ts
|
|
105
|
-
var uniform = () => {
|
|
106
|
-
const buffer = new Uint32Array(1);
|
|
107
|
-
crypto.getRandomValues(buffer);
|
|
108
|
-
return (buffer[0] ?? 0) / 2 ** 32;
|
|
109
|
-
};
|
|
110
|
-
var backoffDelay = (attempt, { baseMs, power = 2, jitterMs = 1000, maxMs = 30000 }) => Math.min(baseMs * power ** attempt + uniform() * jitterMs, maxMs);
|
|
111
|
-
var retryAfterMs = (headers, now = Date.now()) => {
|
|
112
|
-
const header = headers.get("retry-after");
|
|
113
|
-
if (header === null)
|
|
114
|
-
return;
|
|
115
|
-
const seconds = Number(header);
|
|
116
|
-
if (Number.isFinite(seconds))
|
|
117
|
-
return Math.max(0, seconds * 1000);
|
|
118
|
-
const at = Date.parse(header);
|
|
119
|
-
return Number.isNaN(at) ? undefined : Math.max(0, at - now);
|
|
120
|
-
};
|
|
121
|
-
var isRetryableStatus = (status) => status >= HttpStatusCode.INTERNAL_SERVER_ERROR || status === HttpStatusCode.REQUEST_TIMEOUT || status === HttpStatusCode.TOO_MANY_REQUESTS;
|
|
122
|
-
var decide = (error, attempt, options) => {
|
|
123
|
-
const {
|
|
124
|
-
retryDelayMs = 1000,
|
|
125
|
-
backoff,
|
|
126
|
-
shouldRetryOnStatus = isRetryableStatus,
|
|
127
|
-
respectRetryAfter = true
|
|
128
|
-
} = options;
|
|
129
|
-
const computed = backoffDelay(attempt, { baseMs: retryDelayMs, ...backoff });
|
|
130
|
-
if (error instanceof FetchTransportError) {
|
|
131
|
-
return { retry: !error.aborted, delayMs: computed };
|
|
132
|
-
}
|
|
133
|
-
if (error instanceof FetchError) {
|
|
134
|
-
if (!shouldRetryOnStatus(error.status))
|
|
135
|
-
return { retry: false, delayMs: 0 };
|
|
136
|
-
const asked = respectRetryAfter ? retryAfterMs(error.response.headers) : undefined;
|
|
137
|
-
const maxMs = backoff?.maxMs ?? 30000;
|
|
138
|
-
return {
|
|
139
|
-
retry: true,
|
|
140
|
-
delayMs: asked === undefined ? computed : Math.min(asked, maxMs)
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
return { retry: true, delayMs: computed };
|
|
144
|
-
};
|
|
145
|
-
var executeWithRetry = async (operation, options = {}) => {
|
|
146
|
-
const { maxRetries = 3, onAttempt, onError, onSuccess } = options;
|
|
147
|
-
let lastError;
|
|
148
|
-
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
149
|
-
onAttempt?.(attempt + 1, attempt > 0);
|
|
150
|
-
try {
|
|
151
|
-
const result = await operation();
|
|
152
|
-
onSuccess?.(result, attempt + 1);
|
|
153
|
-
return result;
|
|
154
|
-
} catch (error) {
|
|
155
|
-
lastError = error;
|
|
156
|
-
const { retry, delayMs } = decide(error, attempt, options);
|
|
157
|
-
const willRetry = retry && attempt < maxRetries;
|
|
158
|
-
onError?.(error, attempt + 1, willRetry);
|
|
159
|
-
if (!willRetry)
|
|
160
|
-
throw error;
|
|
161
|
-
await Bun.sleep(delayMs);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
throw lastError;
|
|
165
|
-
};
|
|
44
|
+
Object.defineProperty(HttpClientOptions, Symbol.for("dunx.deps"), { value: () => [{ unresolved: "init: HttpClientOptionsInit = {}", optional: true }] });
|
|
166
45
|
// src/client/module.ts
|
|
167
46
|
import {
|
|
168
47
|
Logger as Logger2,
|
|
@@ -372,9 +251,7 @@ class HttpService extends UrlHelper {
|
|
|
372
251
|
}
|
|
373
252
|
}
|
|
374
253
|
}
|
|
375
|
-
Object.defineProperty(HttpService, Symbol.for("dunx.deps"), {
|
|
376
|
-
value: () => [HttpClientOptions, Logger, RequestContext]
|
|
377
|
-
});
|
|
254
|
+
Object.defineProperty(HttpService, Symbol.for("dunx.deps"), { value: () => [HttpClientOptions, Logger, RequestContext] });
|
|
378
255
|
var urlOf = (url) => url === undefined ? {} : { url };
|
|
379
256
|
var readBody = async (response) => {
|
|
380
257
|
const text = await response.text().catch(() => "");
|
|
@@ -463,12 +340,5 @@ export {
|
|
|
463
340
|
HttpClientOptions,
|
|
464
341
|
HttpModule,
|
|
465
342
|
HttpService,
|
|
466
|
-
|
|
467
|
-
executeWithRetry,
|
|
468
|
-
httpClient,
|
|
469
|
-
isJsonBody,
|
|
470
|
-
isPlainObject,
|
|
471
|
-
isRetryableStatus,
|
|
472
|
-
retryAfterMs,
|
|
473
|
-
safeStringify
|
|
343
|
+
httpClient
|
|
474
344
|
};
|
|
@@ -3,25 +3,20 @@ import type { RouteContext } from '../server/context.js';
|
|
|
3
3
|
import type { Middleware, Next } from '../server/middleware.js';
|
|
4
4
|
import { CompressionOptions } from './options.js';
|
|
5
5
|
/**
|
|
6
|
-
* Response compression, on Bun's own compressors.
|
|
7
|
-
*
|
|
8
|
-
* **Not installed by default, and registered by the app rather than by a module:**
|
|
6
|
+
* Response compression, on Bun's own compressors. Not installed by default, and
|
|
7
|
+
* registered by the app rather than a module:
|
|
9
8
|
*
|
|
10
9
|
* ```ts
|
|
11
10
|
* const app = await HttpFactory.create(AppModule, { imports: [CompressionModule.forRoot()] });
|
|
12
11
|
* app.use(Compression);
|
|
13
12
|
* ```
|
|
14
13
|
*
|
|
15
|
-
* An app that never registers it pays nothing
|
|
16
|
-
*
|
|
17
|
-
* leaves it open: compression belongs inside request logging, so the logged status
|
|
18
|
-
* is the real one, and outside anything that wants to read the body it produced.
|
|
14
|
+
* An app that never registers it pays nothing. Position is the app's: compression
|
|
15
|
+
* belongs inside request logging and outside anything reading the body it made.
|
|
19
16
|
*
|
|
20
|
-
* Two encoders
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* streamed or oversized body goes through `CompressionStream` and loses the header,
|
|
24
|
-
* as it must.
|
|
17
|
+
* Two encoders. A known length under `BUFFER_LIMIT` goes through the sync
|
|
18
|
+
* compressors, which keep an accurate `content-length`; anything larger or
|
|
19
|
+
* streamed goes through `CompressionStream` and loses the header.
|
|
25
20
|
*/
|
|
26
21
|
export declare class Compression implements Middleware {
|
|
27
22
|
#private;
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The content codings this package produces.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* The `level` argument that would fix it is accepted and ignored: `{ level: 4 }`
|
|
8
|
-
* encodes in 6,345 us and produces the same 339 bytes as the default. Brotli
|
|
9
|
-
* belongs on a build artefact compressed once, not on a response encoded per
|
|
10
|
-
* request. Note also that the `CompressionStream` format is spelled `brotli`
|
|
11
|
-
* while the HTTP token is `br`, so the two never lined up anyway.
|
|
4
|
+
* Brotli is absent on measurement: 6,344 us to encode a 6.4 KB JSON body against
|
|
5
|
+
* gzip's 23 us, and the `level` argument that would fix it is accepted and
|
|
6
|
+
* ignored. It belongs on a build artefact, not a per-request response.
|
|
12
7
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `library`, `windowBits` and `level` all leave `deflateSync` raw - so offering
|
|
18
|
-
* the coding would flip wire format at the buffering threshold and serve bytes a
|
|
19
|
-
* strict client rejects. `gzip` is taken by everything that would have accepted
|
|
20
|
-
* `deflate`. Measured on Bun 1.4.0; see docs/bun-apis.md.
|
|
8
|
+
* `deflate` is absent because Bun's two encoders disagree: `Bun.deflateSync` emits
|
|
9
|
+
* raw DEFLATE while `CompressionStream('deflate')` emits zlib, which is what the
|
|
10
|
+
* header is defined as. Nothing reconciles them, so offering it would flip wire
|
|
11
|
+
* format at the buffering threshold. Measured on Bun 1.4.0; see docs/bun-apis.md.
|
|
21
12
|
*/
|
|
22
13
|
export declare const CompressionEncoding: Readonly<{
|
|
23
14
|
readonly ZSTD: 'zstd';
|
|
@@ -36,14 +27,11 @@ export declare const isCompressibleType: (contentType: string | null) => boolean
|
|
|
36
27
|
export interface CompressionOptionsInit {
|
|
37
28
|
/**
|
|
38
29
|
* The codings offered, most preferred first. A tie in the client's q-values is
|
|
39
|
-
* broken by this order
|
|
30
|
+
* broken by this order.
|
|
40
31
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* size advantage narrows with the body while the time one does not. A client
|
|
45
|
-
* that does not send `zstd` in `accept-encoding` gets gzip, so the order costs
|
|
46
|
-
* nothing to state.
|
|
32
|
+
* `zstd` leads for speed: 7.7 us to 372 bytes on a 6.4 KB JSON body where gzip
|
|
33
|
+
* takes 16.1 us to reach 576. On a 116 KB document the sizes land within 0.2%,
|
|
34
|
+
* so the size advantage narrows with the body while the time one does not.
|
|
47
35
|
*
|
|
48
36
|
* @default ['zstd', 'gzip']
|
|
49
37
|
*/
|
|
@@ -22,17 +22,12 @@ export declare class MemoryOptions {
|
|
|
22
22
|
constructor(init: MemoryOptionsInit);
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Resident set size against a ceiling.
|
|
25
|
+
* Resident set size against a ceiling. `process.memoryUsage()` costs 5.96 us,
|
|
26
|
+
* which is what makes it safe on an endpoint scraped every two seconds;
|
|
27
|
+
* `jsc.heapStats()` is 2.2 ms and up and `v8.getHeapStatistics()` 1 to 7.6 ms.
|
|
26
28
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* `jsc.heapStats()` walks every live object at 2.2 ms and up,
|
|
30
|
-
* `v8.getHeapStatistics()` is 1 to 7.6 ms, and `Bun.generateHeapSnapshot()` is
|
|
31
|
-
* hundreds of milliseconds and megabytes. None belongs on this path.
|
|
32
|
-
*
|
|
33
|
-
* Not critical: a process near its ceiling is worth seeing, and shedding traffic
|
|
34
|
-
* from it does not make it use less memory. Liveness is where a ceiling belongs, so
|
|
35
|
-
* the orchestrator restarts it.
|
|
29
|
+
* Not critical: shedding traffic from a process near its ceiling does not make it
|
|
30
|
+
* use less memory. A ceiling belongs on liveness, where it restarts.
|
|
36
31
|
*/
|
|
37
32
|
export declare class MemoryIndicator extends HealthIndicator {
|
|
38
33
|
private readonly options;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,39 @@
|
|
|
1
1
|
export { Controller, Delete, Get, Patch, Post, Put, } from './route/decorators.js';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export { ApiHidden, guardsOf, HIDDEN, meta, metaKey, metaOf, mergeMeta, Public, PUBLIC, Roles, ROLES, UNMATCHED, UseGuards, type MetaKey, type MetaRecord, } from './route/metadata.js';
|
|
2
|
+
export type { HttpMethod, RoutePath } from './route/marker.js';
|
|
3
|
+
export { ApiHidden, HIDDEN, meta, metaKey, metaOf, mergeMeta, Public, PUBLIC, Roles, ROLES, UNMATCHED, UseGuards, type MetaKey, type MetaRecord, } from './route/metadata.js';
|
|
5
4
|
export type { InferOutput, Input, JsonSchema, ResponseMap, Returns, RouteInput, RouteSchemas, StandardSchemaIssue, StandardSchemaResult, StandardSchemaV1, } from './route/schema.js';
|
|
6
|
-
export { gatewaysOf, routesOf, type GatewayHandler, type GatewayNode, type RouteInputs, type RouteNode, } from './inspect.js';
|
|
7
5
|
export { ClientAddress } from './server/client-address.js';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export { defaultErrorMapper, ErrorFilter, errorMapper, HttpError,
|
|
6
|
+
export type { RouteContext } from './server/context.js';
|
|
7
|
+
export type { CorsOptions, CorsOrigin } from './server/cors.js';
|
|
8
|
+
export { defaultErrorMapper, ErrorFilter, errorMapper, HttpError, ValidationError, type ErrorHandler, type ErrorMapper, type HttpErrorOptions, type InputSource, type ValidationIssue, } from './server/errors.js';
|
|
11
9
|
export { HttpFactory, type HttpApp, type HttpOptions, } from './server/factory.js';
|
|
12
10
|
export { REQUEST_ID_HEADER } from './server/request-id.js';
|
|
13
11
|
export { TRACEPARENT_HEADER, TRACESTATE_HEADER, TraceContext, type Trace, } from './server/trace-context.js';
|
|
14
12
|
export { RequestLoggingMiddleware, type RequestLoggingOptions, } from './server/request-logging.js';
|
|
15
|
-
export {
|
|
16
|
-
export { assertNoCollisions, assertNoGatewayCollisions, buildRoutes, withUpgradeRoutes, type BunRoutes, type GuardResolver, type RouteMethod, type ServeRoutes, } from './server/routes.js';
|
|
13
|
+
export type { Middleware, Next, RouteHandler } from './server/middleware.js';
|
|
17
14
|
export type { AppSettings } from './server/settings.js';
|
|
18
15
|
export { StaticFiles } from './static/files.js';
|
|
19
16
|
export { StaticModule } from './static/module.js';
|
|
20
|
-
export {
|
|
17
|
+
export { StaticOptions, type StaticOptionsInit } from './static/options.js';
|
|
21
18
|
export { Compression } from './compression/compression.js';
|
|
22
19
|
export { CompressionModule } from './compression/module.js';
|
|
23
|
-
export {
|
|
24
|
-
export { CompressionEncoding, CompressionOptions, isCompressibleType, type CompressionOptionsInit, } from './compression/options.js';
|
|
20
|
+
export { CompressionEncoding, CompressionOptions, type CompressionOptionsInit, } from './compression/options.js';
|
|
25
21
|
export { SKIP_THROTTLE, SkipThrottle, THROTTLE, Throttle, type ThrottleLimit, } from './throttle/decorators.js';
|
|
26
22
|
export { ThrottleGuard } from './throttle/guard.js';
|
|
27
23
|
export { ThrottleModule } from './throttle/module.js';
|
|
28
24
|
export { ThrottleOptions, type ThrottleOptionsInit, } from './throttle/options.js';
|
|
29
25
|
export { MemoryThrottleStore, RedisThrottleStore, ThrottleStore, type ThrottleRedis, } from './throttle/store.js';
|
|
30
26
|
export { HttpStatusCode, type HttpStatusName } from './server/status.js';
|
|
31
|
-
export { buildWebSocket, type UpgradeHandler, type WebSocketRuntime, } from './ws/adapter.js';
|
|
32
27
|
export { Gateway, OnClose, OnDrain, OnMessage, OnOpen, OnPing, OnPong, OnUpgrade, } from './ws/decorators.js';
|
|
33
|
-
export
|
|
34
|
-
export {
|
|
35
|
-
export { composeSocket, observe, type SocketContext, type SocketDispatch, type SocketFrame, type SocketMiddleware, type SocketNext, } from './ws/middleware.js';
|
|
28
|
+
export type { Envelope } from './ws/envelope.js';
|
|
29
|
+
export type { SocketContext, SocketDispatch, SocketFrame, SocketMiddleware, SocketNext, } from './ws/middleware.js';
|
|
36
30
|
export { SocketLoggingMiddleware, type SocketLoggingOptions, } from './ws/logging.js';
|
|
37
|
-
export { HandlerKind, isGateway, type HandlerMeta } from './ws/marker.js';
|
|
38
31
|
export { PubSub } from './ws/pubsub.js';
|
|
39
|
-
export {
|
|
40
|
-
export {
|
|
41
|
-
export { buildGateways, buildRuntime, type GatewayRuntime, } from './ws/runtime.js';
|
|
32
|
+
export { RedisRelay, type RedisRelayOptions } from './ws/redis-relay.js';
|
|
33
|
+
export { DEFAULT_RELAY_CHANNEL, type PubSubRelay, type RelayOptions, } from './ws/relay.js';
|
|
42
34
|
export type { Socket, SocketData, SocketErrorHandler, SocketOptions, } from './ws/socket.js';
|
|
43
35
|
export { HealthIndicator, PingProbe, QueryProbe, type ProbeResult, type ProbeState, } from './health/contracts.js';
|
|
44
|
-
export { HealthController
|
|
36
|
+
export { HealthController } from './health/controller.js';
|
|
45
37
|
export { DatabaseIndicator, DiskIndicator, DiskOptions, MemoryIndicator, MemoryOptions, RedisIndicator, type DiskOptionsInit, type MemoryOptionsInit, } from './health/indicators.js';
|
|
46
38
|
export { HealthModule } from './health/module.js';
|
|
47
39
|
export { HEALTH_REPORT_SCHEMA } from './health/report-schema.js';
|