devframe 1.3.2 → 1.3.5

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.
Files changed (68) hide show
  1. package/dist/{_shared-CnKu5myY.d.mts → _shared-BxeuukaL.d.mts} +2 -2
  2. package/dist/{_shared-BGb9aDxr.mjs → _shared-CtXCQFTV.mjs} +1 -1
  3. package/dist/adapters/build.d.mts +1 -1
  4. package/dist/adapters/cac.d.mts +1 -1
  5. package/dist/adapters/cac.mjs +2 -2
  6. package/dist/adapters/dev.d.mts +4 -4
  7. package/dist/adapters/dev.mjs +2 -2
  8. package/dist/adapters/embedded.d.mts +1 -1
  9. package/dist/adapters/initiate.d.mts +4 -4
  10. package/dist/adapters/initiate.mjs +1 -1
  11. package/dist/adapters/mcp.d.mts +2 -2
  12. package/dist/{agentic-CCstJ5yv.d.mts → agentic-DVgUzwhV.d.mts} +1 -1
  13. package/dist/client/index.d.mts +5 -5
  14. package/dist/client/index.mjs +1 -1
  15. package/dist/{context-CsdPs3po.d.mts → context-B-AARy_U.d.mts} +1 -1
  16. package/dist/{dev-DaHYh5YK.mjs → dev-DF1pEq0n.mjs} +2 -2
  17. package/dist/{dist-DJydMELP.mjs → dist-CZ-TySHD.mjs} +1 -2
  18. package/dist/in-page-channel/index.d.mts +3 -2
  19. package/dist/in-page-channel/index.mjs +1 -1
  20. package/dist/{context-WxTq6kqb.d.mts → index-BhUqJUHG.d.mts} +1404 -1404
  21. package/dist/index.d.mts +5 -4
  22. package/dist/{instance-registry-CmZfF5u3.mjs → instance-registry-DwmnWyCK.mjs} +1 -1
  23. package/dist/{instance-shell-Dk2SejFT.mjs → instance-shell-C0yMifrP.mjs} +5 -5
  24. package/dist/{instance-shell-Bujp0BhE.d.mts → instance-shell-DTk514M9.d.mts} +4 -4
  25. package/dist/{interactive-auth-BURwIAvE.mjs → interactive-auth-CZ3CPfEs.mjs} +1 -1
  26. package/dist/internal/index.d.mts +7 -7
  27. package/dist/internal/index.mjs +4 -4
  28. package/dist/{mcp-content-CQQBt2An.d.mts → mcp-content-0a0mpCL5.d.mts} +1 -1
  29. package/dist/node/auth.d.mts +84 -3
  30. package/dist/node/auth.mjs +1 -1
  31. package/dist/node/hub-internals.d.mts +11 -2
  32. package/dist/node/hub-internals.mjs +1 -1
  33. package/dist/node/index.d.mts +4 -2
  34. package/dist/recipes/interactive-auth.d.mts +2 -2
  35. package/dist/recipes/interactive-auth.mjs +1 -1
  36. package/dist/{rolldown-runtime-DYf_mQCB.mjs → rolldown-runtime-BVN1G_yT.mjs} +4 -4
  37. package/dist/rpc/dump.d.mts +1 -1
  38. package/dist/rpc/index.d.mts +121 -3
  39. package/dist/rpc/transports/sse-client.d.mts +34 -2
  40. package/dist/rpc/transports/sse-server.d.mts +2 -2
  41. package/dist/rpc/transports/ws-bun.d.mts +2 -2
  42. package/dist/rpc/transports/ws-client.d.mts +27 -2
  43. package/dist/rpc/transports/ws-deno.d.mts +2 -2
  44. package/dist/rpc/transports/ws-server.d.mts +150 -3
  45. package/dist/{rpc-core-CDUizUQB.mjs → rpc-core-BmDHiDR6.mjs} +1 -1
  46. package/dist/{rpc-core-CFwyV10r.d.mts → rpc-core-CblgPYJ_.d.mts} +3 -3
  47. package/dist/{shared-state-COV7NCbd.mjs → shared-state-DiAsLHP8.mjs} +3 -2
  48. package/dist/{state-B_yjfeqo.mjs → state-TdDWqiG-.mjs} +2 -1
  49. package/dist/types/index.d.mts +3 -3
  50. package/dist/{types-844OBepb.d.mts → types-KZOyhez5.d.mts} +1 -0
  51. package/dist/utils/debounce.d.mts +6 -0
  52. package/dist/utils/events.d.mts +1 -1
  53. package/dist/utils/get-port.mjs +1 -1
  54. package/dist/utils/launch-editor.mjs +1 -1
  55. package/dist/utils/nostics.d.mts +40 -2
  56. package/dist/utils/origin.d.mts +55 -2
  57. package/dist/utils/serve-static.d.mts +1 -1
  58. package/dist/utils/shared-state.d.mts +1 -1
  59. package/dist/utils/shared-state.mjs +1 -1
  60. package/dist/utils/streaming-channel.d.mts +1 -1
  61. package/package.json +6 -6
  62. package/dist/index-D0qrBkhO.d.mts +0 -121
  63. package/dist/index-HMJPlexc.d.mts +0 -84
  64. package/dist/nostics-Dgwh7ytT.d.mts +0 -40
  65. package/dist/origin-D5i7K_Zb.d.mts +0 -56
  66. package/dist/sse-client-B2PrSz-H.d.mts +0 -35
  67. package/dist/ws-client-lqOeANcn.d.mts +0 -28
  68. package/dist/ws-server-CYHkeyA-.d.mts +0 -150
@@ -1,84 +0,0 @@
1
- import { k as SharedState, o as DevframeNodeContext, s as DevframeNodeRpcSession } from "./context-WxTq6kqb.mjs";
2
- import { n as InternalAnonymousAuthStorage } from "./context-CsdPs3po.mjs";
3
- /**
4
- * Flip `isTrusted` to false on any live WS clients connected with `token`
5
- * and broadcast the `auth:revoked` event so they can react.
6
- *
7
- * Shared between persisted-auth revocation and remote-dock token revocation.
8
- */
9
- declare function revokeActiveConnectionsForToken(context: DevframeNodeContext, token: string): Promise<void>;
10
- /**
11
- * Revoke an auth token: remove from storage and notify all connected clients
12
- * using this token that they are no longer trusted.
13
- */
14
- declare function revokeAuthToken(context: DevframeNodeContext, storage: SharedState<InternalAnonymousAuthStorage>, token: string): Promise<void>;
15
- /**
16
- * Format a raw `navigator.userAgent` string into the short display label
17
- * shown for a trusted device (e.g. "Chrome 120 | macOS 14 desktop").
18
- *
19
- * The client used to parse+format this itself, but that pulled
20
- * `ua-parser-modern` into the browser bundle for a label nothing else on
21
- * the client needs; the client now sends the raw string and parsing
22
- * happens here, at the server ingress, keeping the persisted label format
23
- * identical.
24
- */
25
- declare function describeUA(userAgent: string): string;
26
- /**
27
- * The current one-time authentication code. Display this to the user (e.g. in
28
- * the dev-server terminal) so they can type it into the browser to authenticate.
29
- */
30
- declare function getTempAuthCode(): string;
31
- /**
32
- * The current code plus its expiry timestamp, for display (e.g. the auth
33
- * banner). An already-expired code is rotated first, so the returned code is
34
- * always redeemable for its remaining lifetime.
35
- */
36
- declare function getTempAuthCodeInfo(): {
37
- code: string;
38
- expireAt: number;
39
- };
40
- /**
41
- * Rotate the authentication code, resetting its expiry window and failed-attempt
42
- * counter. Call this when a new authentication flow begins (e.g. when an
43
- * untrusted client starts authenticating) so the displayed code is freshly
44
- * valid for its full TTL.
45
- */
46
- declare function refreshTempAuthCode(): string;
47
- /**
48
- * Build a "magic link" authentication URL that embeds a one-time code (OTP) in
49
- * the URL **fragment**. Opening it authenticates the client without typing;
50
- * print it on startup (devframe stays headless, so the host prints its own
51
- * banner). Defaults to the current code; the link is subject to the same TTL.
52
- *
53
- * The code rides the fragment (`#devframe_otp=…`), not the query string, so it
54
- * is never sent to the server, written to an access log, or leaked in a
55
- * `Referer` header; the browser client reads it locally (see
56
- * `consumeOtpFromUrl`). Any existing fragment parameters are preserved.
57
- */
58
- declare function buildOtpAuthUrl(baseUrl: string, code?: string): string;
59
- /**
60
- * Re-authenticate a connection that presents a previously-issued bearer token.
61
- * Returns `true` and marks the session trusted when the token is known.
62
- *
63
- * Used by the `anonymous:devframe:auth` handler so a client that already
64
- * authenticated (token persisted in the browser) is trusted on reconnect
65
- * without entering the code again.
66
- */
67
- declare function verifyAuthToken(token: string, session: DevframeNodeRpcSession, storage: SharedState<InternalAnonymousAuthStorage>): boolean;
68
- /**
69
- * Exchange a one-time authentication code for a fresh, node-issued bearer token.
70
- *
71
- * On success this mints a high-entropy token, records it in the trusted store,
72
- * marks the calling session trusted, rotates the code, and returns the token
73
- * for the client to persist. Returns `null` on any failure.
74
- *
75
- * Because the code is short and human-typed, verification is hardened against
76
- * brute force: it enforces a time-to-live, compares in constant time, and
77
- * rotates the code after {@link TEMP_AUTH_MAX_ATTEMPTS} failed attempts so an
78
- * attacker cannot keep guessing against the same code.
79
- */
80
- declare function exchangeTempAuthCode(code: string, session: DevframeNodeRpcSession, info: {
81
- ua: string;
82
- origin: string;
83
- }, storage: SharedState<InternalAnonymousAuthStorage>): string | null;
84
- export { getTempAuthCodeInfo as a, revokeActiveConnectionsForToken as c, getTempAuthCode as i, revokeAuthToken as l, describeUA as n, refreshTempAuthCode as o, exchangeTempAuthCode as r, verifyAuthToken as s, buildOtpAuthUrl as t };
@@ -1,40 +0,0 @@
1
- import { AnyDiagnosticReporter, AnyDiagnosticReporter as AnyDiagnosticReporter$1, ConsoleMethod, ConsoleReporterOptions, Diagnostic, Diagnostic as Diagnostic$1, DiagnosticCallParams, DiagnosticDefinition, DiagnosticDefinition as DiagnosticDefinition$1, DiagnosticHandle, DiagnosticInit, DiagnosticReporter, Diagnostics, Diagnostics as Diagnostics$1, createConsoleReporter, defineProdDiagnostics, formatDiagnostic } from "nostics";
2
- import { ansiFormatter } from "nostics/formatters/ansi";
3
- /**
4
- * The reporter every {@link defineDiagnostics} call below wires in ahead of
5
- * any caller-supplied ones: prints the diagnostic through devframe's own
6
- * ANSI colors via `console[method]` (default `'warn'`).
7
- */
8
- declare function devframeReporter(d: Diagnostic, { method }?: {
9
- method?: 'log' | 'warn' | 'error';
10
- }): void;
11
- /**
12
- * Options accepted by {@link defineDiagnostics}, identical to `nostics`'s
13
- * own `DefineDiagnosticsOptions`, minus the reporter devframe already
14
- * prepends.
15
- */
16
- type DevframeDefineDiagnosticsOptions<Codes extends Record<string, DiagnosticDefinition>, Reporters extends readonly AnyDiagnosticReporter[] = []> = Parameters<typeof defineDiagnostics<Codes, Reporters>>[0];
17
- /**
18
- * Drop-in replacement for `nostics`'s `defineDiagnostics()` with devframe's
19
- * ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
20
- * `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
21
- * and the built-in plugins defines its codes through this instead of
22
- * `nostics`'s own `defineDiagnostics`; the reporter registration lives
23
- * here, once, so none of them need to build their own reporter (`colors`,
24
- * `ansiFormatter`) or take a direct dependency on `nostics` themselves.
25
- */
26
- declare function defineDiagnostics<const Codes extends Record<string, DiagnosticDefinition>, const Reporters extends readonly AnyDiagnosticReporter[] = []>(options: {
27
- docsBase?: string | ((code: keyof Codes) => string | undefined);
28
- codes: Codes;
29
- reporters?: Reporters;
30
- }): DevframeDiagnostics<Codes, Reporters>;
31
- /**
32
- * The `Diagnostics` object returned by devframe's {@link defineDiagnostics}
33
- * (devframe's ANSI console reporter is always prepended). Integrations that
34
- * export their own `defineDiagnostics(...)` result as public API annotate it
35
- * with this type, so the reference resolves through `devframe/utils/nostics`
36
- * rather than inlining `nostics`'s types or taking a direct `nostics`
37
- * dependency.
38
- */
39
- type DevframeDiagnostics<Codes extends Record<string, DiagnosticDefinition>, Reporters extends readonly AnyDiagnosticReporter[] = []> = Diagnostics<Codes, readonly [typeof devframeReporter, ...Reporters]>;
40
- export { formatDiagnostic as _, DevframeDiagnostics as a, DiagnosticDefinition$1 as c, DiagnosticReporter as d, Diagnostics$1 as f, defineProdDiagnostics as g, defineDiagnostics as h, DevframeDefineDiagnosticsOptions as i, DiagnosticHandle as l, createConsoleReporter as m, ConsoleMethod as n, Diagnostic$1 as o, ansiFormatter as p, ConsoleReporterOptions as r, DiagnosticCallParams as s, AnyDiagnosticReporter$1 as t, DiagnosticInit as u };
@@ -1,56 +0,0 @@
1
- /**
2
- * Origin and hostname predicates shared by the RPC transports (the WS upgrade,
3
- * SSE, and MCP origin gates) and the instance shell's authentication-link
4
- * origin validation. Kept dependency-free and runtime-agnostic so any consumer
5
- * can pull in a single check without dragging in a transport's `crossws`
6
- * import.
7
- */
8
- /**
9
- * Whether `hostname` names a loopback host: `localhost` (or any `*.localhost`
10
- * subdomain), the IPv6 loopback `::1`, or an IPv4 literal inside the
11
- * `127.0.0.0/8` loopback block.
12
- *
13
- * The IPv4 case is matched **structurally**: the whole hostname must be a
14
- * canonical dotted-decimal IPv4 literal whose first octet is `127`. A bare
15
- * `startsWith('127.')` prefix check would also accept an attacker-controlled
16
- * DNS name that merely *begins* with `127.` (`127.attacker.example`,
17
- * `127.0.0.1.attacker.example`), letting a cross-origin browser page defeat
18
- * the loopback origin gate that guards the RPC/MCP surface (a DNS-rebinding /
19
- * cross-site WebSocket-hijacking bypass). Requiring a real IPv4 literal keeps
20
- * genuine loopback addresses (`127.0.0.1`, `127.5.5.5`) allowed while rejecting
21
- * those DNS names.
22
- */
23
- declare function isLoopbackHostname(hostname: string): boolean;
24
- /**
25
- * Whether `address` is a loopback peer address as reported by a socket
26
- * (`net.Socket.remoteAddress`): the IPv6 loopback `::1`, an IPv4 literal in
27
- * `127.0.0.0/8`, or an IPv4-mapped IPv6 form of one (`::ffff:127.0.0.1`).
28
- *
29
- * Unlike {@link isLoopbackHostname} this takes a raw address, not a hostname:
30
- * it never accepts a `localhost`-style name (a socket peer is always a literal
31
- * address) and understands the IPv4-mapped IPv6 form the OS hands back on a
32
- * dual-stack listener. Used to prove a same-machine caller from the connected
33
- * peer, which a client cannot forge, rather than from the `Origin` header,
34
- * which it can.
35
- */
36
- declare function isLoopbackAddress(address: string): boolean;
37
- /**
38
- * Default origin policy for a localhost dev tool: allow requests with no
39
- * `Origin` header (native, non-browser clients), allow any loopback origin
40
- * (so cross-port localhost dev setups keep working), and allow explicitly
41
- * configured origins. Everything else, such as a real remote page in the dev's
42
- * browser, is rejected.
43
- */
44
- declare function isAllowedOrigin(origin: string | undefined, allowedOrigins: readonly string[]): boolean;
45
- /**
46
- * Decide whether a request-derived origin candidate may back a devframe's
47
- * advertised public origin, the destination of the OTP magic link. Stricter
48
- * than {@link isAllowedOrigin}: it rejects credentials, a path, a query, a
49
- * fragment, a malformed port, and non-HTTP(S) schemes, and adopts a candidate
50
- * only when its hostname is loopback or its canonical origin exactly matches
51
- * an `allowedOrigins` entry (a caller with no static list passes none, so only
52
- * loopback qualifies). Returns the canonical origin to adopt, or `undefined`
53
- * to reject. Forwarded headers are never consulted.
54
- */
55
- declare function validateOriginCandidate(candidate: string, allowedOrigins?: readonly string[]): string | undefined;
56
- export { validateOriginCandidate as i, isLoopbackAddress as n, isLoopbackHostname as r, isAllowedOrigin as t };
@@ -1,35 +0,0 @@
1
- import { a as ChannelOptions } from "./index-BKu9BxcT.mjs";
2
- import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
3
- interface SseRpcChannelOptions {
4
- /** Resolved `http(s)://` URL of the SSE endpoint. */
5
- url: string;
6
- onConnected?: () => void;
7
- onError?: (e: Error) => void;
8
- onDisconnected?: () => void;
9
- authToken?: string;
10
- /**
11
- * RPC function definitions (or just the `jsonSerializable` flag per
12
- * method) used to dispatch the per-call wire serializer, the same contract
13
- * as the WS channel.
14
- */
15
- definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
16
- /** Fetch implementation. Default: `globalThis.fetch`. */
17
- fetch?: typeof globalThis.fetch;
18
- }
19
- /**
20
- * Build a birpc `ChannelOptions` object backed by an SSE stream (server →
21
- * client) and HTTP `POST` (client → server): the WebSocket-free counterpart
22
- * to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
23
- *
24
- * The stream is consumed via `fetch` streaming (not `EventSource`), so it
25
- * works in browsers and server runtimes alike. The server's first frame
26
- * (`event: session`) carries the session id; every `POST` echoes it in the
27
- * `x-birpc-session` header. A response to a client-initiated request comes
28
- * back in the `POST`'s own body and is re-injected into the channel; a
29
- * dropped stream terminates the channel; there is no reconnect, matching
30
- * the WS channel's closed-is-done semantics.
31
- */
32
- declare function createSseRpcChannel(options: SseRpcChannelOptions): ChannelOptions & {
33
- close: () => void;
34
- };
35
- export { createSseRpcChannel as n, SseRpcChannelOptions as t };
@@ -1,28 +0,0 @@
1
- import { a as ChannelOptions } from "./index-BKu9BxcT.mjs";
2
- import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
3
- interface WsRpcChannelOptions {
4
- url: string;
5
- onConnected?: (e: Event) => void;
6
- onError?: (e: Error) => void;
7
- onDisconnected?: (e: CloseEvent) => void;
8
- authToken?: string;
9
- /**
10
- * RPC function definitions (or just the `jsonSerializable` flag per
11
- * method) used to dispatch the per-call wire serializer. Pass an
12
- * empty / partial map on clients that don't have the full registry;
13
- * encoding falls back to structured-clone (the safer superset) and
14
- * decoding still routes correctly via the wire prefix.
15
- */
16
- definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
17
- }
18
- /**
19
- * Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
20
- * Pass the result straight to `createRpcClient`'s `channel` option.
21
- *
22
- * Also returns `close()`, closing the underlying socket, mirroring the server transport's
23
- * existing `WsRpcTransport.close()`. `birpc`'s own `ChannelOptions` has no teardown of its own.
24
- */
25
- declare function createWsRpcChannel(options: WsRpcChannelOptions): ChannelOptions & {
26
- close: () => void;
27
- };
28
- export { createWsRpcChannel as n, WsRpcChannelOptions as t };
@@ -1,150 +0,0 @@
1
- import { a as ChannelOptions, n as BirpcGroup } from "./index-BKu9BxcT.mjs";
2
- import { g as RpcFunctionDefinitionAny } from "./types-844OBepb.mjs";
3
- import { n as DevframeRpcConnection, t as DevframeNodeRpcSessionMeta } from "./session-Y9R6tqg4.mjs";
4
- import { Hooks } from "crossws";
5
- import { NodeAdapter } from "crossws/adapters/node";
6
- import { Buffer } from "node:buffer";
7
- import { IncomingMessage, Server } from "node:http";
8
- import { Server as Server$1, ServerOptions } from "node:https";
9
- import { AddressInfo } from "node:net";
10
- import { Duplex } from "node:stream";
11
- interface WsRpcTransportOptions {
12
- /**
13
- * Attach to an existing HTTP(S) server, sharing its port. Combine with
14
- * `path` to bind the WS endpoint to a single route so it coexists with
15
- * other upgrade handlers on the same server (e.g. a Vite dev server's HMR
16
- * socket). The shared server's lifecycle is owned by the caller; closing
17
- * this transport detaches the upgrade listener without closing the server.
18
- */
19
- server?: Server | Server$1;
20
- /**
21
- * Port for the standalone WebSocket server. Defaults to `0`, which lets the
22
- * operating system assign an available port.
23
- */
24
- port?: number;
25
- /** Host for the standalone WebSocket server. Defaults to `localhost`. */
26
- host?: string;
27
- /**
28
- * Restrict the WS endpoint to a single upgrade route (e.g. `/__ws`). When
29
- * sharing a `server`, non-matching upgrade requests are left untouched for
30
- * other listeners to handle, so devframe's socket can sit alongside
31
- * framework sockets (Vite HMR, etc.).
32
- */
33
- path?: string;
34
- /**
35
- * Create the adapter without binding it to anything: no server is created,
36
- * no port is bound, no `upgrade` listener is installed. The caller drives
37
- * the socket itself through {@link WsRpcTransport.handleUpgrade} (from its
38
- * own `upgrade` listener) or {@link WsRpcTransport.attach} (to bind a
39
- * server later). Takes precedence over `server` / `port` / `https`.
40
- */
41
- unbound?: boolean;
42
- /**
43
- * Destroy upgrade requests that don't match `path` instead of leaving them
44
- * for other listeners. Enable this when devframe owns the shared server
45
- * outright (nothing else handles its upgrades), so an off-route client is
46
- * rejected promptly rather than left hanging. Default: `false`
47
- * (coexist-friendly); servers this transport creates itself always
48
- * destroy unmatched upgrades.
49
- */
50
- destroyUnmatched?: boolean;
51
- /** When set, a new https.Server is created and the WS endpoint is attached to it. */
52
- https?: ServerOptions;
53
- /**
54
- * Extra origins to accept on the WS upgrade beyond the loopback default.
55
- * Add your LAN/tunnel origin here when reaching the tool from another host.
56
- * Pass `false` to disable origin checking entirely (not recommended).
57
- * Default: loopback-only.
58
- */
59
- allowedOrigins?: readonly string[] | WsOriginRegistry | false;
60
- /**
61
- * RPC function definitions, used by the per-call wire serializer to
62
- * dispatch between strict-JSON and structured-clone encoding based
63
- * on each function's `jsonSerializable` flag.
64
- *
65
- * When omitted, all messages fall back to structured-clone: safe but
66
- * loses dev-time validation for `jsonSerializable: true` declarations.
67
- */
68
- definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
69
- onConnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
70
- onDisconnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
71
- /** Override the default per-call serializer. Most callers should leave this unset. */
72
- serialize?: ChannelOptions['serialize'];
73
- /** Override the default per-call deserializer. Most callers should leave this unset. */
74
- deserialize?: ChannelOptions['deserialize'];
75
- }
76
- interface CreateWsOriginRegistryOptions {
77
- /** Origins allowed before any external viewers are registered. */
78
- allowedOrigins?: readonly string[];
79
- /** Additional validation to run after the registration token is verified. */
80
- validateOrigin?: (origin: string) => boolean;
81
- }
82
- interface WsOriginRegistry {
83
- /** Registration token to include in connection metadata. */
84
- readonly token: string;
85
- /** Read and register an origin from a connection bootstrap URL. */
86
- registerFromUrl: (url: string) => string | undefined;
87
- /** Check whether an origin is currently allowed. */
88
- isAllowed: (origin: string | undefined) => boolean;
89
- }
90
- /**
91
- * Create a live, token-protected origin allowlist for external browser
92
- * viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
93
- * `registerFromUrl()` in the connection metadata handler to authorize a
94
- * viewer without sharing a mutable array or disabling DNS-rebinding protection.
95
- */
96
- declare function createWsOriginRegistry(options?: CreateWsOriginRegistryOptions): WsOriginRegistry;
97
- interface WsRpcTransport {
98
- /**
99
- * The crossws node adapter driving the socket; exposes the connected
100
- * `peers` and pub/sub. See https://crossws.h3.dev.
101
- */
102
- ws: NodeAdapter;
103
- /** Resolves when the transport-owned server is listening. */
104
- ready: Promise<void>;
105
- /** Returns the bound address, or `null` when the server is not listening. */
106
- address: () => AddressInfo | string | null;
107
- /**
108
- * Complete a `node:http` `upgrade` event on this transport, applying the
109
- * same `path` filter and origin gate the transport's own listener uses.
110
- * Wire it into a host server directly (`server.on('upgrade',
111
- * transport.handleUpgrade)`) or call it from an existing listener.
112
- */
113
- handleUpgrade: (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
114
- /**
115
- * Route a server's `upgrade` events to this transport, returning a detach
116
- * function. Use it to bind an `unbound` transport once the host server
117
- * exists; {@link WsRpcTransport.close} detaches every server attached this
118
- * way (without closing them, since the caller owns their lifecycle).
119
- */
120
- attach: (server: Server | Server$1) => () => void;
121
- /** Remove the upgrade listener from a shared `server` (a no-op otherwise). */
122
- detach: () => void;
123
- /**
124
- * Tear the transport down deterministically: detach from a shared server,
125
- * force-terminate every connected peer, and close any server this
126
- * transport created itself (`port` / `https` modes).
127
- */
128
- close: () => Promise<void>;
129
- }
130
- /**
131
- * The per-peer lifecycle hooks driving a devframe RPC WebSocket, shaped for
132
- * any [crossws](https://crossws.h3.dev) adapter. {@link attachWsRpcTransport}
133
- * feeds them to the Node adapter; runtime-specific attachments (e.g. Bun's
134
- * fetch-upgrade adapter) reuse the same hooks so every transport speaks the
135
- * identical wire protocol: one birpc channel per peer, per-method
136
- * `jsonSerializable` dispatch between strict JSON and structured-clone.
137
- */
138
- declare function createWsRpcPeerHooks<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: Pick<WsRpcTransportOptions, 'onConnected' | 'onDisconnected' | 'definitions' | 'serialize' | 'deserialize'>): Partial<Hooks>;
139
- /**
140
- * Attach a WebSocket transport to an existing RPC group, powered by
141
- * [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
142
- * `server` (sharing its port, optionally scoped to a `path`), or let this
143
- * helper create a standalone server from `port` / `host` / `https`.
144
- *
145
- * Returns the crossws node adapter, standalone-server readiness/address
146
- * accessors, `detach` (remove the upgrade listener from a shared `server`),
147
- * and `close` (full deterministic teardown).
148
- */
149
- declare function attachWsRpcTransport<ClientFunctions extends object, ServerFunctions extends object>(rpcGroup: BirpcGroup<ClientFunctions, ServerFunctions, false>, options?: WsRpcTransportOptions): WsRpcTransport;
150
- export { attachWsRpcTransport as a, WsRpcTransportOptions as i, WsOriginRegistry as n, createWsOriginRegistry as o, WsRpcTransport as r, createWsRpcPeerHooks as s, CreateWsOriginRegistryOptions as t };