@dunx/http 0.1.0 → 0.1.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 +46 -46
- package/dist/index.js +2 -2
- package/dist/index.js.map +22 -22
- package/dist/route/metadata.d.ts +1 -1
- package/dist/route/schema.d.ts +3 -3
- package/dist/server/application.d.ts +4 -4
- package/dist/server/context.d.ts +2 -2
- package/dist/server/cors.d.ts +2 -2
- package/dist/server/errors.d.ts +1 -1
- package/dist/server/input.d.ts +3 -3
- package/dist/server/middleware.d.ts +3 -3
- package/dist/server/request-logging.d.ts +6 -6
- package/dist/server/routes.d.ts +3 -3
- package/dist/server/settings.d.ts +1 -1
- package/dist/server/status.d.ts +1 -1
- package/dist/ws/discover.d.ts +1 -1
- package/dist/ws/envelope.d.ts +2 -2
- package/dist/ws/pubsub.d.ts +4 -4
- package/dist/ws/redis-relay.d.ts +2 -2
- package/dist/ws/relay.d.ts +6 -6
- package/dist/ws/runtime.d.ts +1 -1
- package/dist/ws/socket.d.ts +1 -1
- package/package.json +3 -3
package/dist/route/metadata.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export declare const PUBLIC: MetaKey<boolean>;
|
|
|
23
23
|
export declare const Roles: (...roles: readonly string[]) => <F extends object>(target: F) => F;
|
|
24
24
|
export declare const Public: () => <F extends object>(target: F) => F;
|
|
25
25
|
/**
|
|
26
|
-
* Guards are middleware, so they compose rather than override
|
|
26
|
+
* Guards are middleware, so they compose rather than override - which is why they
|
|
27
27
|
* are not a `MetaKey`. Valid on a method or on a class.
|
|
28
28
|
*/
|
|
29
29
|
export declare const UseGuards: (...guards: readonly Ctor<Middleware>[]) => <F extends object>(target: F) => F;
|
package/dist/route/schema.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface StandardSchemaIssue {
|
|
|
31
31
|
readonly key: PropertyKey;
|
|
32
32
|
})[] | undefined;
|
|
33
33
|
}
|
|
34
|
-
/** The validated output of a schema
|
|
34
|
+
/** The validated output of a schema - `InferOutput<typeof CreateNote>` is `Note`. */
|
|
35
35
|
export type InferOutput<S> = S extends StandardSchemaV1<unknown, infer Out> ? Out : never;
|
|
36
36
|
/**
|
|
37
37
|
* The second argument to `@Get`/`@Post`/... Declaring a schema is what makes the
|
|
@@ -47,9 +47,9 @@ export interface RouteSchemas {
|
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* The handler's parameter type, derived from its own options object. It has to be
|
|
50
|
-
* written out
|
|
50
|
+
* written out - a standard method decorator can *check* a parameter's type but
|
|
51
51
|
* cannot contextually type an unannotated one (docs/ARCHITECTURE.md, "Verified
|
|
52
|
-
* constraints")
|
|
52
|
+
* constraints") - but every field type still comes from the schemas, so nothing
|
|
53
53
|
* is declared twice:
|
|
54
54
|
*
|
|
55
55
|
* ```ts
|
|
@@ -29,7 +29,7 @@ export interface HttpOptions extends AppOptions {
|
|
|
29
29
|
*/
|
|
30
30
|
readonly websocket?: SocketOptions;
|
|
31
31
|
/**
|
|
32
|
-
* Multi-node websocket fan-out. Absent
|
|
32
|
+
* Multi-node websocket fan-out. Absent - the default - means `PubSub` publishes
|
|
33
33
|
* to this process only, which is exactly Bun's native pub/sub and costs nothing.
|
|
34
34
|
*
|
|
35
35
|
* `new RedisRelay({ url })` is the batteries-included one. Anything with a
|
|
@@ -43,7 +43,7 @@ export interface HttpOptions extends AppOptions {
|
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* Everything below `listen()` configures the route table, which is built exactly
|
|
46
|
-
* once
|
|
46
|
+
* once - when the server binds. Calling any of them afterwards throws rather than
|
|
47
47
|
* being quietly dropped.
|
|
48
48
|
*/
|
|
49
49
|
export interface HttpApp extends App {
|
|
@@ -55,7 +55,7 @@ export interface HttpApp extends App {
|
|
|
55
55
|
setting<K extends keyof AppSettings>(key: K): AppSettings[K];
|
|
56
56
|
/** Mounts an `OPTIONS` preflight per path. Last call wins. */
|
|
57
57
|
enableCors(options?: CorsOptions): this;
|
|
58
|
-
/** The same `inject(ClientAddress)` singleton
|
|
58
|
+
/** The same `inject(ClientAddress)` singleton - honours `'trust proxy'`. */
|
|
59
59
|
clientIp(req: BunRequest): string | undefined;
|
|
60
60
|
/** Every gateway path this app upgrades on, exactly as mounted. */
|
|
61
61
|
readonly gatewayPaths: readonly string[];
|
|
@@ -75,7 +75,7 @@ export declare class HttpApplication implements HttpApp {
|
|
|
75
75
|
clientIp(req: BunRequest): string | undefined;
|
|
76
76
|
/**
|
|
77
77
|
* The one `Bun.serve` call. A gateway's upgrade is a native `GET` route in the
|
|
78
|
-
* same table, so Bun's router
|
|
78
|
+
* same table, so Bun's router - not a hand-written `fetch` fallback - is what
|
|
79
79
|
* matches an upgrade, and no `fetch` handler is needed at all.
|
|
80
80
|
*/
|
|
81
81
|
listen(port?: number): Promise<string>;
|
package/dist/server/context.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { MetaKey } from '../route/metadata.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Which route the middleware is running for, and what that route's decorators
|
|
6
6
|
* declared. `get` resolves the handler's metadata first and the controller class's
|
|
7
|
-
* second
|
|
7
|
+
* second - the same override direction as Nest's `getAllAndOverride`.
|
|
8
8
|
*/
|
|
9
9
|
export interface RouteContext {
|
|
10
10
|
readonly controller: string;
|
|
@@ -15,7 +15,7 @@ export interface RouteContext {
|
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* One frozen context per route, built when the table is built and closed over by
|
|
18
|
-
* the chain. The merge already happened at discovery, so `get` is a Map lookup
|
|
18
|
+
* the chain. The merge already happened at discovery, so `get` is a Map lookup -
|
|
19
19
|
* not a prototype walk, and nothing is read per request.
|
|
20
20
|
*/
|
|
21
21
|
export declare const buildContext: (route: DiscoveredRoute) => RouteContext;
|
package/dist/server/cors.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export type CorsOrigin = string | readonly string[] | ((origin: string) => boole
|
|
|
3
3
|
export interface CorsOptions {
|
|
4
4
|
/**
|
|
5
5
|
* `'*'` by default. A concrete string, a list, or a predicate all answer with the
|
|
6
|
-
* caller's own origin only when it is allowed
|
|
6
|
+
* caller's own origin only when it is allowed - a request from anywhere else gets
|
|
7
7
|
* no CORS headers at all, which is what makes the browser block it.
|
|
8
8
|
*/
|
|
9
9
|
readonly origin?: CorsOrigin;
|
|
@@ -20,7 +20,7 @@ export interface CorsOptions {
|
|
|
20
20
|
export declare const withCors: (options: CorsOptions, handler: RouteHandler) => RouteHandler;
|
|
21
21
|
/**
|
|
22
22
|
* `Bun.serve({ routes })` answers a method miss with 404, so a preflight cannot be
|
|
23
|
-
* inferred
|
|
23
|
+
* inferred - every CORS-enabled path gets its own `OPTIONS` handler, built at boot
|
|
24
24
|
* from the methods that path actually declares.
|
|
25
25
|
*/
|
|
26
26
|
export declare const preflight: (options: CorsOptions, methods: readonly string[]) => RouteHandler;
|
package/dist/server/errors.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export interface ValidationIssue {
|
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* A declared schema rejected the input. Always a 400, and the issues survive into
|
|
16
|
-
* the response body
|
|
16
|
+
* the response body - a caller cannot fix what it cannot see.
|
|
17
17
|
*/
|
|
18
18
|
export declare class ValidationError extends HttpError {
|
|
19
19
|
readonly source: InputSource;
|
package/dist/server/input.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { BunRequest } from 'bun';
|
|
|
2
2
|
import type { RouteInput, RouteSchemas } from '../route/schema.js';
|
|
3
3
|
/**
|
|
4
4
|
* Built once per route at boot. A route that declares nothing gets the identity
|
|
5
|
-
* reader
|
|
5
|
+
* reader - no parse, no validation, not even a promise.
|
|
6
6
|
*
|
|
7
7
|
* A reader **returns a promise only when it has something to wait for**. A `body`
|
|
8
|
-
* schema always does; `query` and `params` against a synchronous validator
|
|
9
|
-
* zod, Valibot and ArkType all are
|
|
8
|
+
* schema always does; `query` and `params` against a synchronous validator - which
|
|
9
|
+
* zod, Valibot and ArkType all are - resolve without one.
|
|
10
10
|
*/
|
|
11
11
|
export type InputReader = (req: BunRequest) => RouteInput | Promise<RouteInput>;
|
|
12
12
|
/**
|
|
@@ -4,7 +4,7 @@ export type Next = () => Promise<Response>;
|
|
|
4
4
|
/**
|
|
5
5
|
* The single extension point. A guard is middleware that throws, an interceptor
|
|
6
6
|
* wraps `next()`, a filter is the error mapper. `ctx` names the route and carries
|
|
7
|
-
* what its decorators declared, resolved at boot
|
|
7
|
+
* what its decorators declared, resolved at boot - so a guard costs a Map lookup.
|
|
8
8
|
*/
|
|
9
9
|
export interface Middleware {
|
|
10
10
|
handle(req: BunRequest, ctx: RouteContext, next: Next): Promise<Response>;
|
|
@@ -13,8 +13,8 @@ export type RouteHandler = (req: BunRequest) => Promise<Response>;
|
|
|
13
13
|
/**
|
|
14
14
|
* What goes into the `Bun.serve` route table. Wider than `RouteHandler` because
|
|
15
15
|
* Bun accepts a plain `Response`, which is what lets a route with nothing to
|
|
16
|
-
* await skip promises altogether
|
|
16
|
+
* await skip promises altogether - see `buildRoutes`.
|
|
17
17
|
*/
|
|
18
18
|
export type ServedHandler = (req: BunRequest) => Response | Promise<Response>;
|
|
19
|
-
/** Folded into one closure per route at boot
|
|
19
|
+
/** Folded into one closure per route at boot - no per-request array iteration. */
|
|
20
20
|
export declare const compose: (middleware: readonly Middleware[], ctx: RouteContext, handler: RouteHandler) => RouteHandler;
|
|
@@ -9,7 +9,7 @@ export interface RequestLoggingOptions {
|
|
|
9
9
|
/**
|
|
10
10
|
* Log the request body. Default **`false`**.
|
|
11
11
|
*
|
|
12
|
-
* Reading it means `req.clone().text()`
|
|
12
|
+
* Reading it means `req.clone().text()` - a second copy of every payload,
|
|
13
13
|
* buffered and parsed, on the hot path. Measured on the `validate` scenario in
|
|
14
14
|
* `tools/bench`, turning both body options on costs roughly two thirds of the
|
|
15
15
|
* throughput. It is also the field most likely to contain a password.
|
|
@@ -17,17 +17,17 @@ export interface RequestLoggingOptions {
|
|
|
17
17
|
* Turn it on in development, where seeing the payload is the point.
|
|
18
18
|
*/
|
|
19
19
|
readonly requestBody?: boolean;
|
|
20
|
-
/** Log the response body. Default **`false`**
|
|
20
|
+
/** Log the response body. Default **`false`** - same clone-and-buffer cost. */
|
|
21
21
|
readonly responseBody?: boolean;
|
|
22
|
-
/** Paths to skip entirely
|
|
22
|
+
/** Paths to skip entirely - a health check polled every second, say. */
|
|
23
23
|
readonly ignore?: readonly string[];
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* One structured entry per request, carrying the request and its response.
|
|
27
27
|
*
|
|
28
28
|
* Installed by `HttpFactory.create` unless `requestLogging: false`. It injects
|
|
29
|
-
* `Logger` and `RequestContext`
|
|
30
|
-
* default
|
|
29
|
+
* `Logger` and `RequestContext` - both `@dunx/core` contracts, both bound by
|
|
30
|
+
* default - so it works with no logging module imported, and picks up
|
|
31
31
|
* `@arkv/logger` automatically once `@dunx/infra/logger` is.
|
|
32
32
|
*
|
|
33
33
|
* **One entry, not two.** Nest needs a middleware for the inbound half and an
|
|
@@ -42,7 +42,7 @@ export interface RequestLoggingOptions {
|
|
|
42
42
|
*
|
|
43
43
|
* **Nothing here is `async`.** Reading the request or the response body are the
|
|
44
44
|
* only steps that can ever wait, both are off by default, and both are adopted
|
|
45
|
-
* with `.then` rather than awaited
|
|
45
|
+
* with `.then` rather than awaited - the same rule `input.ts` follows, for the
|
|
46
46
|
* same measured reason. An `async` scope callback alone cost 0.44 µs/request
|
|
47
47
|
* against a synchronous one on raw `Bun.serve`.
|
|
48
48
|
*/
|
package/dist/server/routes.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { type ErrorMapper } from './errors.js';
|
|
|
7
7
|
import { type Middleware, type RouteHandler, type ServedHandler } from './middleware.js';
|
|
8
8
|
/** How a `@UseGuards` class becomes an instance. `listen()` passes `app.get`. */
|
|
9
9
|
export type GuardResolver = (guard: Ctor<Middleware>) => Middleware;
|
|
10
|
-
/** `OPTIONS` is never a `@Get`-style route
|
|
10
|
+
/** `OPTIONS` is never a `@Get`-style route - only CORS mounts one. */
|
|
11
11
|
export type RouteMethod = HttpMethod | 'OPTIONS';
|
|
12
12
|
export type BunRoutes = Record<string, Partial<Record<RouteMethod, ServedHandler>>>;
|
|
13
13
|
/**
|
|
@@ -28,12 +28,12 @@ export declare const assertNoCollisions: (discovered: readonly DiscoveredRoute[]
|
|
|
28
28
|
export declare const assertNoGatewayCollisions: (discovered: readonly DiscoveredRoute[], gatewayPaths: readonly string[]) => void;
|
|
29
29
|
/**
|
|
30
30
|
* The two tables in one. A gateway's `GET` is what Bun's router matches on an
|
|
31
|
-
* upgrade
|
|
31
|
+
* upgrade - the reason no `fetch` handler is needed for a socket to connect.
|
|
32
32
|
*/
|
|
33
33
|
export declare const withUpgradeRoutes: (routes: BunRoutes, gateways: ReadonlyMap<string, UpgradeHandler>) => ServeRoutes;
|
|
34
34
|
/**
|
|
35
35
|
* Bun answers an unmatched path itself, so nothing in the middleware chain ever
|
|
36
|
-
* sees it
|
|
36
|
+
* sees it - which makes a 404 invisible to request logging, metrics and tracing.
|
|
37
37
|
*
|
|
38
38
|
* This is the only `fetch` handler dunx installs, and it is not a router: Bun
|
|
39
39
|
* still does all the matching, and this runs only once Bun has decided nothing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The settings `app.set()` accepts. A key has to be declared here to be settable,
|
|
3
|
-
* so the map is checked at compile time instead of being a string bag
|
|
3
|
+
* so the map is checked at compile time instead of being a string bag - a typo is
|
|
4
4
|
* a type error, not a setting that silently never applies.
|
|
5
5
|
*/
|
|
6
6
|
export interface AppSettings {
|
package/dist/server/status.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Frozen object plus an indexed-access union, not an `enum`. An enum emits a
|
|
3
|
-
* runtime object that no other syntax can produce, which is why the repo bans it
|
|
3
|
+
* runtime object that no other syntax can produce, which is why the repo bans it -
|
|
4
4
|
* see CLAUDE.md. This gives the same `HttpStatusCode.NOT_FOUND` ergonomics, a
|
|
5
5
|
* narrower type, and erases cleanly.
|
|
6
6
|
*/
|
package/dist/ws/discover.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare const discoverGateway: (instance: object) => DiscoveredGateway;
|
|
|
34
34
|
export declare const findHandlerMethod: (ctor: Ctor<unknown>) => string | undefined;
|
|
35
35
|
/**
|
|
36
36
|
* Gateways are declared in `@Module({ providers })` like any other injectable and
|
|
37
|
-
* found here by their marker
|
|
37
|
+
* found here by their marker - the same discovery-by-inspection controllers get,
|
|
38
38
|
* with no second registration key to keep in step.
|
|
39
39
|
*/
|
|
40
40
|
export declare const discoverGateways: (modules: readonly ResolvedModule[], resolve: (token: InjectionToken<unknown>) => unknown) => readonly DiscoveredGateway[];
|
package/dist/ws/envelope.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The whole wire protocol: one JSON object, an event name, and a payload. It is
|
|
3
3
|
* only ever read for a gateway that declares at least one `@OnMessage(event)`
|
|
4
|
-
* handler
|
|
4
|
+
* handler - a gateway with only a raw `@OnMessage()` never parses anything.
|
|
5
5
|
*/
|
|
6
6
|
export interface Envelope {
|
|
7
7
|
readonly event: string;
|
|
@@ -9,7 +9,7 @@ export interface Envelope {
|
|
|
9
9
|
}
|
|
10
10
|
export declare const encode: (event: string, data: unknown) => string;
|
|
11
11
|
/**
|
|
12
|
-
* `undefined` for anything that is not an envelope
|
|
12
|
+
* `undefined` for anything that is not an envelope - binary frames, invalid JSON,
|
|
13
13
|
* a non-object, or a missing `event`. Those fall through to the raw handler
|
|
14
14
|
* instead of being rejected here.
|
|
15
15
|
*/
|
package/dist/ws/pubsub.d.ts
CHANGED
|
@@ -6,11 +6,11 @@ import type { SocketData } from './socket.js';
|
|
|
6
6
|
* runtime, not in a JavaScript registry: `socket.subscribe(topic)` is what joins
|
|
7
7
|
* one, and Bun does the fan-out.
|
|
8
8
|
*
|
|
9
|
-
* Injectable
|
|
9
|
+
* Injectable - `HttpFactory` binds it, so a service can publish without holding a
|
|
10
10
|
* socket and without registering anything.
|
|
11
11
|
*
|
|
12
12
|
* With a {@link PubSubRelay} attached the same publish also reaches the other
|
|
13
|
-
* nodes. Without one
|
|
13
|
+
* nodes. Without one - the default - nothing here touches a broker and the cost is
|
|
14
14
|
* exactly Bun's.
|
|
15
15
|
*/
|
|
16
16
|
export declare class PubSub {
|
|
@@ -25,12 +25,12 @@ export declare class PubSub {
|
|
|
25
25
|
* Opt into multi-node fan-out: every `publish` from here on also goes to
|
|
26
26
|
* `relay`, and everything other nodes put on the channel is fanned out locally.
|
|
27
27
|
*
|
|
28
|
-
* `HttpFactory.create(root, { relay })` is the shorthand
|
|
28
|
+
* `HttpFactory.create(root, { relay })` is the shorthand - `listen()` calls this.
|
|
29
29
|
* Call it directly when the relay has to come out of the container, which is the
|
|
30
30
|
* case for an app reusing its own `@dunx/infra/redis` connection:
|
|
31
31
|
* `app.get(PubSub).relayThrough(app.get(RedisConnection))` before `listen()`.
|
|
32
32
|
*
|
|
33
|
-
* A broker that cannot be reached is reported through `onError` and left alone
|
|
33
|
+
* A broker that cannot be reached is reported through `onError` and left alone -
|
|
34
34
|
* local fan-out is unaffected, and the app boots either way.
|
|
35
35
|
*/
|
|
36
36
|
relayThrough(relay: PubSubRelay, options?: RelayOptions): Promise<void>;
|
package/dist/ws/redis-relay.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface RedisRelayOptions {
|
|
|
10
10
|
* `0` by default, and that default is not a preference: a `Bun.RedisClient` that
|
|
11
11
|
* never connects keeps an internal retry timer alive past `close()`, and the
|
|
12
12
|
* process then never exits. A relay is exactly the connection most likely to be
|
|
13
|
-
* absent
|
|
13
|
+
* absent - a single-node deployment with `REDIS_URL` left over from staging -
|
|
14
14
|
* so the default has to be the one that lets the app boot, degrade, and still
|
|
15
15
|
* exit. Raise it when Redis is a hard requirement and you want Bun to reconnect
|
|
16
16
|
* for you.
|
|
@@ -23,7 +23,7 @@ export interface RedisRelayOptions {
|
|
|
23
23
|
readonly tls?: boolean | Bun.TLSOptions;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* A {@link PubSubRelay} on `Bun.RedisClient`
|
|
26
|
+
* A {@link PubSubRelay} on `Bun.RedisClient` - a Bun global, so this costs
|
|
27
27
|
* `@dunx/http` no dependency at all.
|
|
28
28
|
*
|
|
29
29
|
* **Two connections, not one.** A client in subscriber mode rejects every data
|
package/dist/ws/relay.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What `PubSub` needs from something that carries a message to the other nodes:
|
|
3
3
|
* publish, and subscribe. Nothing else, so anything that already talks to a
|
|
4
|
-
* broker satisfies it
|
|
4
|
+
* broker satisfies it - `@dunx/infra/redis`'s `RedisConnection` does, structurally
|
|
5
5
|
* and with no adapter, and so does a bare `Bun.RedisClient` pair.
|
|
6
6
|
*
|
|
7
7
|
* The return types are `unknown` rather than `Promise<void>` deliberately: Bun's
|
|
@@ -15,7 +15,7 @@ export interface PubSubRelay {
|
|
|
15
15
|
publish(channel: string, message: string): unknown;
|
|
16
16
|
/**
|
|
17
17
|
* Deliver every message published to `channel` to `listener`. Called once, with
|
|
18
|
-
* one channel
|
|
18
|
+
* one channel - pattern subscription is not used, because Bun's `psubscribe`
|
|
19
19
|
* does not work (see docs/bun-apis.md).
|
|
20
20
|
*/
|
|
21
21
|
subscribe(channel: string, listener: (message: string) => void): unknown;
|
|
@@ -34,7 +34,7 @@ export interface RelayOptions {
|
|
|
34
34
|
* The one broker channel every topic's frames travel on.
|
|
35
35
|
*
|
|
36
36
|
* One channel rather than one per topic, because a node cannot know which
|
|
37
|
-
* topics its sockets joined
|
|
37
|
+
* topics its sockets joined - `socket.subscribe()` goes straight into Bun - and
|
|
38
38
|
* `psubscribe` is unusable. The cost is that every node reads every relayed
|
|
39
39
|
* frame and drops the ones for topics it has no local subscriber on, which is a
|
|
40
40
|
* `server.publish` returning `0`. Two apps sharing a Redis need two channels.
|
|
@@ -50,8 +50,8 @@ export interface RelayOptions {
|
|
|
50
50
|
*/
|
|
51
51
|
readonly onError?: (error: unknown, phase: RelayPhase) => void;
|
|
52
52
|
/**
|
|
53
|
-
* What to do when the **boot** subscribe fails. Publishing recovers on its own
|
|
54
|
-
* every publish retries the broker
|
|
53
|
+
* What to do when the **boot** subscribe fails. Publishing recovers on its own -
|
|
54
|
+
* every publish retries the broker - but a failed subscribe used to be retried
|
|
55
55
|
* by nothing, so the node stayed permanently deaf to other nodes while still
|
|
56
56
|
* looking healthy.
|
|
57
57
|
*
|
|
@@ -69,7 +69,7 @@ export declare const DEFAULT_RELAY_CHANNEL = "dunx:ws";
|
|
|
69
69
|
export declare const defaultRelayError: (error: unknown, phase: RelayPhase) => void;
|
|
70
70
|
/**
|
|
71
71
|
* One relayed publish: which process published it, which topic it belongs to, and
|
|
72
|
-
* the frame itself. `origin` is the whole duplicate-delivery defence
|
|
72
|
+
* the frame itself. `origin` is the whole duplicate-delivery defence - the broker
|
|
73
73
|
* echoes a publish back to the publisher, and fanning that out locally a second
|
|
74
74
|
* time would give every client on the originating node the message twice.
|
|
75
75
|
*/
|
package/dist/ws/runtime.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DiscoveredGateway, Invoke } from './discover.js';
|
|
2
2
|
/**
|
|
3
3
|
* One gateway reduced to direct references, built once at boot. Dispatch reads
|
|
4
|
-
* these fields and nothing else
|
|
4
|
+
* these fields and nothing else - no lookup, no metadata, no DI per message.
|
|
5
5
|
*/
|
|
6
6
|
export interface GatewayRuntime {
|
|
7
7
|
readonly name: string;
|
package/dist/ws/socket.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface SocketData<T = unknown> {
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Bun's native socket, unwrapped. `send`, `subscribe`, `unsubscribe`,
|
|
13
|
-
* `isSubscribed`, `publish`, `cork` and `close` are its own methods
|
|
13
|
+
* `isSubscribed`, `publish`, `cork` and `close` are its own methods - nothing here
|
|
14
14
|
* reimplements them.
|
|
15
15
|
*/
|
|
16
16
|
export type Socket<T = unknown> = ServerWebSocket<SocketData<T>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dunx/http",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Bun.serve adapter for the dunx framework: controllers, middleware and WebSocket gateways",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"websocket"
|
|
14
14
|
],
|
|
15
15
|
"homepage": "https://github.com/petarzarkov/dunx/tree/main/packages/http#readme",
|
|
16
|
-
"license": "
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Petar Zarkov",
|
|
19
19
|
"email": "pzarko1@gmail.com",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@dunx/core": "workspace:*"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@dunx/core": "0.1.
|
|
54
|
+
"@dunx/core": "0.1.1",
|
|
55
55
|
"@types/bun": ">=1.3.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependenciesMeta": {
|