devframe 0.9.8 → 0.9.9
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/dist/{_shared-BM3PdYli.mjs → _shared-C08SdQRl.mjs} +15 -4
- package/dist/{_shared-mtXpcJIv.d.mts → _shared-CK3czkH4.d.mts} +25 -2
- package/dist/adapters/build.d.mts +6 -6
- package/dist/adapters/build.mjs +32 -22
- package/dist/adapters/cac.d.mts +16 -1
- package/dist/adapters/cac.mjs +8 -7
- package/dist/adapters/dev.d.mts +13 -13
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +28 -26
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +28 -14
- package/dist/adapters/mcp.mjs +75 -39
- package/dist/{agent-tool-name-EgfoFO8C.mjs → agent-tool-name-DGzeuWcO.mjs} +2 -2
- package/dist/cli/main.d.mts +1 -1
- package/dist/cli/main.mjs +41 -17
- package/dist/client/index.d.mts +36 -36
- package/dist/client/index.mjs +83 -51
- package/dist/{client-assets-C7SXgTWY.mjs → client-assets-DNdhagGm.mjs} +2 -2
- package/dist/constants.d.mts +8 -7
- package/dist/constants.mjs +7 -6
- package/dist/{context-CLF4-8Pp.d.mts → context-4AIVRLYF.d.mts} +158 -122
- package/dist/{context-omlma_1n.mjs → context-CwPUinjn.mjs} +126 -88
- package/dist/{context-KUqAfawQ.mjs → context-DIUvJW4D.mjs} +3 -3
- package/dist/{context-DftYyXaR.d.mts → context-rgBSPFHS.d.mts} +5 -5
- package/dist/{crypto-token-XCqTSMg9.mjs → crypto-token-TVbGGFuj.mjs} +1 -1
- package/dist/{dev-CzkPCJwi.mjs → dev-Eqq5PX0k.mjs} +37 -18
- package/dist/{diagnostics-BXWW3VK-.mjs → diagnostics-BMfN8mb1.mjs} +30 -17
- package/dist/{diagnostics-CD8nlgll.mjs → diagnostics-D0EVm5M6.mjs} +2 -2
- package/dist/{events-4daw0uK9.mjs → events-BV4Dj59a.mjs} +2 -2
- package/dist/{host-h3-fRbF9yor.mjs → host-h3-BJ4siyz7.mjs} +1 -1
- package/dist/in-page-channel/index.d.mts +14 -14
- package/dist/in-page-channel/index.mjs +63 -54
- package/dist/{index-BzyopqxV.d.mts → index-pIVt92jP.d.mts} +9 -9
- package/dist/{index-D3k0BIhe.d.mts → index-pKl67H6w.d.mts} +4 -4
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +2 -2
- package/dist/{instance-registry-BjlMQbFB.mjs → instance-registry-C7-41RSp.mjs} +8 -8
- package/dist/{instance-shell-Tcp5hGoq.d.mts → instance-shell-7Z52PE4_.d.mts} +18 -18
- package/dist/{instance-shell-CpVW4zG0.mjs → instance-shell-cdVETpfz.mjs} +227 -58
- package/dist/internal/index.d.mts +40 -23
- package/dist/internal/index.mjs +10 -10
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +2 -2
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +5 -5
- package/dist/node/index.mjs +2 -2
- package/dist/{nostics-SPGDgHEP.d.mts → nostics-0sKe5HIj.d.mts} +2 -2
- package/dist/{nostics-CzECRXpE.mjs → nostics-D0PvLZsn.mjs} +1 -1
- package/dist/origin-DGDH8BI9.d.mts +45 -0
- package/dist/origin-DZit9g29.mjs +80 -0
- package/dist/recipes/common-rpc-functions.d.mts +5 -5
- package/dist/recipes/common-rpc-functions.mjs +3 -3
- package/dist/recipes/interactive-auth.d.mts +6 -6
- package/dist/recipes/interactive-auth.mjs +6 -6
- package/dist/{remote-assets-DezQmPQU.mjs → remote-assets-BIFWOlBW.mjs} +26 -6
- package/dist/{remote-assets-B13_vRkJ.d.mts → remote-assets-eBvSKZMS.d.mts} +7 -7
- package/dist/{revoke-COLW0cOi.mjs → revoke-cqztiCX4.mjs} +1 -1
- package/dist/rpc/dump.d.mts +2 -11
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +3 -3
- package/dist/rpc/transports/sse-client.d.mts +1 -1
- package/dist/rpc/transports/sse-client.mjs +30 -14
- package/dist/rpc/transports/sse-server.d.mts +4 -4
- package/dist/rpc/transports/sse-server.mjs +7 -7
- package/dist/rpc/transports/ws-bun.d.mts +5 -5
- package/dist/rpc/transports/ws-bun.mjs +8 -2
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +2 -2
- package/dist/rpc/transports/ws-deno.d.mts +4 -4
- package/dist/rpc/transports/ws-deno.mjs +8 -2
- package/dist/rpc/transports/ws-server.d.mts +2 -1
- package/dist/rpc/transports/ws-server.mjs +232 -1
- package/dist/{rpc-core-B3W3z9ff.d.mts → rpc-core-Ceu6AUz8.d.mts} +4 -4
- package/dist/{rpc-core-DlHd276T.mjs → rpc-core-DVQ7xi89.mjs} +14 -2
- package/dist/{serialization-BGzEwAdr.mjs → serialization-DTZnPQ1-.mjs} +20 -18
- package/dist/{services-install-CqqQVls5.mjs → services-install-P_DV7VYL.mjs} +32 -21
- package/dist/session-DPfj6zQG.mjs +16 -0
- package/dist/{shared-state--sduc6Xi.mjs → shared-state-CaxB1q0h.mjs} +2 -2
- package/dist/{simple-schema-DQPZrAaZ.mjs → simple-schema-Bi40l-P6.mjs} +2 -2
- package/dist/{sse-client-DwX021ST.d.mts → sse-client-BQ4jS3eO.d.mts} +4 -4
- package/dist/{state-CK9LjrnT.mjs → state-CeQQWzM-.mjs} +4 -4
- package/dist/{static-DV_qUSRS.mjs → static-DZ8P2Kn7.mjs} +130 -135
- package/dist/{storage-BXNVhKyR.mjs → storage-Dccf_IyD.mjs} +1 -1
- package/dist/types/index.d.mts +6 -6
- package/dist/{types-CMdPYhOx.d.mts → types-Dq4i156u.d.mts} +17 -17
- package/dist/utils/agent-tool-name.d.mts +2 -2
- package/dist/utils/agent-tool-name.mjs +2 -2
- package/dist/utils/colors.d.mts +1 -1
- package/dist/utils/crypto-token.d.mts +1 -1
- package/dist/utils/crypto-token.mjs +1 -1
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/nostics.d.mts +1 -1
- package/dist/utils/nostics.mjs +1 -1
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/origin.d.mts +2 -0
- package/dist/utils/origin.mjs +80 -0
- package/dist/utils/remote-assets.d.mts +2 -2
- package/dist/utils/remote-assets.mjs +1 -1
- package/dist/utils/serve-static.d.mts +4 -4
- package/dist/utils/serve-static.mjs +56 -19
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/simple-schema.d.mts +5 -5
- package/dist/utils/simple-schema.mjs +2 -2
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/utils/streaming-channel.mjs +2 -2
- package/dist/utils/when.d.mts +5 -5
- package/dist/{validation-YrZH6atx.mjs → validation-BOy8IoFZ.mjs} +2 -2
- package/dist/{wire-codec-0K-o5MYW.mjs → wire-codec-dcCeXcSo.mjs} +3 -3
- package/dist/{ws-client-7_lZi-B9.d.mts → ws-client-Xpxt0oPA.d.mts} +3 -3
- package/dist/{ws-server-VyHlanzy.d.mts → ws-server-D2nv68Hg.d.mts} +13 -37
- package/package.json +2 -1
- package/dist/ws-server-Y_AumUQH.mjs +0 -294
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Resolution order at serve time:
|
|
8
8
|
*
|
|
9
|
-
* 1. The package installed locally (resolved from {@link resolveFrom})
|
|
10
|
-
*
|
|
9
|
+
* 1. The package installed locally (resolved from {@link resolveFrom}),
|
|
10
|
+
* the zero-network / air-gap path. Version skew warns; a major
|
|
11
11
|
* version mismatch throws.
|
|
12
12
|
* 2. The per-file cache under
|
|
13
13
|
* `<storageDir project>/.remote-assets/<package>@<version>/`.
|
|
14
|
-
* 3. The CDN {@link provider}
|
|
14
|
+
* 3. The CDN {@link provider}: each requested file streams through to
|
|
15
15
|
* the browser while being written into the cache.
|
|
16
16
|
*
|
|
17
17
|
* Anywhere a static mount accepts a dist directory (`clientAssets`,
|
|
18
|
-
* `hostStatic`, `mountStatic`) it also accepts this object
|
|
18
|
+
* `hostStatic`, `mountStatic`) it also accepts this object; see
|
|
19
19
|
* {@link StaticAssetsSource}.
|
|
20
20
|
*/
|
|
21
21
|
interface RemoteAssets {
|
|
@@ -39,7 +39,7 @@ interface RemoteAssets {
|
|
|
39
39
|
* `import.meta.url` of the declaring module. When set, a locally
|
|
40
40
|
* installed copy of {@link package} is resolved from this module's own
|
|
41
41
|
* dependency graph first (works under pnpm's strict layout) and served
|
|
42
|
-
* with zero network. Omitting it skips the installed-package step
|
|
42
|
+
* with zero network. Omitting it skips the installed-package step;
|
|
43
43
|
* cache + CDN still work.
|
|
44
44
|
*/
|
|
45
45
|
resolveFrom?: string | null;
|
|
@@ -54,7 +54,7 @@ interface RemoteAssets {
|
|
|
54
54
|
offline?: boolean;
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* Built-in CDN providers (`'jsdelivr'
|
|
57
|
+
* Built-in CDN providers (`'jsdelivr'`, the default, or `'unpkg'`) or a custom
|
|
58
58
|
* provider for corp mirrors.
|
|
59
59
|
*/
|
|
60
60
|
type RemoteAssetsProvider = 'jsdelivr' | 'unpkg' | RemoteAssetsProviderCustom;
|
|
@@ -97,7 +97,7 @@ interface RemoteAssetsErrorMessage {
|
|
|
97
97
|
reason: string;
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
-
* A resolved, servable handle over a {@link RemoteAssets} declaration
|
|
100
|
+
* A resolved, servable handle over a {@link RemoteAssets} declaration,
|
|
101
101
|
* produced by `resolveStaticAssetsSource()` (`devframe/utils/remote-assets`)
|
|
102
102
|
* and consumed by the static-serving engine (`devframe/utils/serve-static`).
|
|
103
103
|
*/
|
package/dist/rpc/dump.d.mts
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
import { h as RpcDumpStore, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny } from "../types-
|
|
1
|
+
import { h as RpcDumpStore, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny } from "../types-Dq4i156u.mjs";
|
|
2
2
|
//#region src/rpc/dump/collect.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Collects pre-computed dumps by executing functions with their defined input combinations.
|
|
5
|
-
* Static functions without dump config automatically get `{ inputs: [[]] }`.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```ts
|
|
9
|
-
* const store = await dumpFunctions([greet], context, { concurrency: 10 })
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
3
|
declare function dumpFunctions<T extends readonly RpcFunctionDefinitionAny[]>(definitions: T, context?: any, options?: RpcDumpCollectionOptions): Promise<RpcDumpStore<RpcDefinitionsToFunctions<T>>>;
|
|
13
4
|
/**
|
|
14
5
|
* Creates a client that serves pre-computed results from a dump store.
|
|
@@ -64,7 +55,7 @@ type StaticRpcDumpManifest = Record<string, StaticRpcDumpManifestValue>;
|
|
|
64
55
|
interface StaticRpcDumpFile {
|
|
65
56
|
/** Whether this file was written via `JSON.stringify` or `structured-clone-es.stringify`. */
|
|
66
57
|
serialization: StaticRpcDumpSerialization;
|
|
67
|
-
/** Function name the file belongs to
|
|
58
|
+
/** Function name the file belongs to, used to scope `DF0019` errors during write. */
|
|
68
59
|
fnName: string;
|
|
69
60
|
/** Payload to encode. */
|
|
70
61
|
data: unknown;
|
package/dist/rpc/dump.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as reviveDumpError, i as getDefinitionsWithDumps, n as createClientFromDump, o as serializeDumpError, r as dumpFunctions, t as collectStaticRpcDump } from "../static-
|
|
1
|
+
import { a as reviveDumpError, i as getDefinitionsWithDumps, n as createClientFromDump, o as serializeDumpError, r as dumpFunctions, t as collectStaticRpcDump } from "../static-DZ8P2Kn7.mjs";
|
|
2
2
|
export { collectStaticRpcDump, createClientFromDump, dumpFunctions, getDefinitionsWithDumps, reviveDumpError, serializeDumpError };
|
package/dist/rpc/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as STRUCTURED_CLONE_PREFIX, c as getRpcResolvedSetupResult, d as RpcFunctionsCollectorBase, f as RpcCacheManager, i as validateRpcReturn, l as createDefineWrapperWithContext, n as validateDefinitions, o as strictJsonStringify, p as RpcCacheOptions, r as validateRpcArgs, s as getRpcHandler, t as validateDefinition, u as defineRpcFunction } from "../index-
|
|
2
|
-
import { C as RpcFunctionType, E as Thenable, S as RpcFunctionSetupResult, T as RpcReturnSchema, _ as RpcFunctionDefinition, a as RpcDefinitionsFilter, b as RpcFunctionDefinitionBase, c as RpcDump, d as RpcDumpDefinition, f as RpcDumpGetter, g as RpcFunctionAgentOptions, h as RpcDumpStore, i as RpcArgsSchema, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, p as RpcDumpRecord, r as EntriesToObject, s as RpcDefinitionsToFunctionsWithNamespace, t as BirpcFn, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny, w as RpcFunctionsCollector, x as RpcFunctionDefinitionToFunction, y as RpcFunctionDefinitionAnyWithContext } from "../types-
|
|
1
|
+
import { a as STRUCTURED_CLONE_PREFIX, c as getRpcResolvedSetupResult, d as RpcFunctionsCollectorBase, f as RpcCacheManager, i as validateRpcReturn, l as createDefineWrapperWithContext, n as validateDefinitions, o as strictJsonStringify, p as RpcCacheOptions, r as validateRpcArgs, s as getRpcHandler, t as validateDefinition, u as defineRpcFunction } from "../index-pIVt92jP.mjs";
|
|
2
|
+
import { C as RpcFunctionType, E as Thenable, S as RpcFunctionSetupResult, T as RpcReturnSchema, _ as RpcFunctionDefinition, a as RpcDefinitionsFilter, b as RpcFunctionDefinitionBase, c as RpcDump, d as RpcDumpDefinition, f as RpcDumpGetter, g as RpcFunctionAgentOptions, h as RpcDumpStore, i as RpcArgsSchema, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, p as RpcDumpRecord, r as EntriesToObject, s as RpcDefinitionsToFunctionsWithNamespace, t as BirpcFn, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny, w as RpcFunctionsCollector, x as RpcFunctionDefinitionToFunction, y as RpcFunctionDefinitionAnyWithContext } from "../types-Dq4i156u.mjs";
|
|
3
3
|
export { type BirpcFn, type BirpcReturn, EntriesToObject, RpcArgsSchema, RpcCacheManager, RpcCacheOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcDefinitionsToFunctionsWithNamespace, RpcDump, RpcDumpClientOptions, RpcDumpCollectionOptions, RpcDumpDefinition, RpcDumpGetter, RpcDumpRecord, RpcDumpRecordError, RpcDumpStore, RpcFunctionAgentOptions, RpcFunctionDefinition, RpcFunctionDefinitionAny, RpcFunctionDefinitionAnyWithContext, RpcFunctionDefinitionBase, RpcFunctionDefinitionToFunction, RpcFunctionSetupResult, RpcFunctionType, RpcFunctionsCollector, RpcFunctionsCollectorBase, RpcReturnSchema, STRUCTURED_CLONE_PREFIX, Thenable, createDefineWrapperWithContext, defineRpcFunction, getRpcHandler, getRpcResolvedSetupResult, strictJsonStringify, validateDefinition, validateDefinitions, validateRpcArgs, validateRpcReturn };
|
package/dist/rpc/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as validateRpcArgs, i as getRpcResolvedSetupResult, n as validateDefinitions, o as validateRpcReturn, r as getRpcHandler, s as hash, t as validateDefinition } from "../validation-
|
|
2
|
-
import { t as diagnostics } from "../diagnostics-
|
|
1
|
+
import { a as validateRpcArgs, i as getRpcResolvedSetupResult, n as validateDefinitions, o as validateRpcReturn, r as getRpcHandler, s as hash, t as validateDefinition } from "../validation-BOy8IoFZ.mjs";
|
|
2
|
+
import { t as diagnostics } from "../diagnostics-D0EVm5M6.mjs";
|
|
3
3
|
import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-BLWPsH6y.mjs";
|
|
4
|
-
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-
|
|
4
|
+
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-DTZnPQ1-.mjs";
|
|
5
5
|
//#region src/rpc/cache.ts
|
|
6
6
|
/**
|
|
7
7
|
* @experimental API is expected to change.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createSseRpcChannel, t as SseRpcChannelOptions } from "../../sse-client-
|
|
1
|
+
import { n as createSseRpcChannel, t as SseRpcChannelOptions } from "../../sse-client-BQ4jS3eO.mjs";
|
|
2
2
|
export { SseRpcChannelOptions, createSseRpcChannel };
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { DEVFRAME_AUTH_TOKEN_QUERY_PARAM, DEVFRAME_SSE_SESSION_HEADER } from "../../constants.mjs";
|
|
2
|
-
import { t as createRpcWireCodec } from "../../wire-codec-
|
|
2
|
+
import { t as createRpcWireCodec } from "../../wire-codec-dcCeXcSo.mjs";
|
|
3
3
|
//#region src/rpc/transports/sse-client.ts
|
|
4
4
|
function NOOP() {}
|
|
5
|
+
/** Split the next complete SSE frame (up to a blank line) off the buffer. */
|
|
6
|
+
function takeFrame(buffer) {
|
|
7
|
+
const boundary = buffer.search(/\n\n|\r\n\r\n/);
|
|
8
|
+
if (boundary < 0) return void 0;
|
|
9
|
+
return {
|
|
10
|
+
frame: buffer.slice(0, boundary),
|
|
11
|
+
rest: buffer.slice(boundary + (buffer[boundary] === "\r" ? 4 : 2))
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Parse one SSE frame's lines into its event name and data lines. */
|
|
15
|
+
function parseFrame(frame) {
|
|
16
|
+
let event = "message";
|
|
17
|
+
const data = [];
|
|
18
|
+
for (const rawLine of frame.split(/\r?\n/)) {
|
|
19
|
+
if (rawLine.startsWith(":")) continue;
|
|
20
|
+
if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
|
|
21
|
+
else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
event,
|
|
25
|
+
data
|
|
26
|
+
};
|
|
27
|
+
}
|
|
5
28
|
/**
|
|
6
29
|
* Build a birpc `ChannelOptions` object backed by an SSE stream (server →
|
|
7
|
-
* client) and HTTP `POST` (client → server)
|
|
30
|
+
* client) and HTTP `POST` (client → server): the WebSocket-free counterpart
|
|
8
31
|
* to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
|
|
9
32
|
*
|
|
10
33
|
* The stream is consumed via `fetch` streaming (not `EventSource`), so it
|
|
@@ -12,7 +35,7 @@ function NOOP() {}
|
|
|
12
35
|
* (`event: session`) carries the session id; every `POST` echoes it in the
|
|
13
36
|
* `x-birpc-session` header. A response to a client-initiated request comes
|
|
14
37
|
* back in the `POST`'s own body and is re-injected into the channel; a
|
|
15
|
-
* dropped stream terminates the channel
|
|
38
|
+
* dropped stream terminates the channel; there is no reconnect, matching
|
|
16
39
|
* the WS channel's closed-is-done semantics.
|
|
17
40
|
*/
|
|
18
41
|
function createSseRpcChannel(options) {
|
|
@@ -63,17 +86,10 @@ function createSseRpcChannel(options) {
|
|
|
63
86
|
if (done) break;
|
|
64
87
|
buffer += decoder.decode(value, { stream: true });
|
|
65
88
|
for (;;) {
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
let event = "message";
|
|
71
|
-
const data = [];
|
|
72
|
-
for (const rawLine of frame.split(/\r?\n/)) {
|
|
73
|
-
if (rawLine.startsWith(":")) continue;
|
|
74
|
-
if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
|
|
75
|
-
else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
|
|
76
|
-
}
|
|
89
|
+
const taken = takeFrame(buffer);
|
|
90
|
+
if (!taken) break;
|
|
91
|
+
buffer = taken.rest;
|
|
92
|
+
const { event, data } = parseFrame(taken.frame);
|
|
77
93
|
if (data.length > 0) dispatch(event, data.join("\n"));
|
|
78
94
|
}
|
|
79
95
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as RpcFunctionDefinitionAny } from "../../types-
|
|
2
|
-
import {
|
|
1
|
+
import { v as RpcFunctionDefinitionAny } from "../../types-Dq4i156u.mjs";
|
|
2
|
+
import { c as DevframeNodeRpcSessionMeta, l as DevframeRpcConnection, n as WsOriginRegistry } from "../../ws-server-D2nv68Hg.mjs";
|
|
3
3
|
import { BirpcGroup } from "birpc";
|
|
4
4
|
//#region src/rpc/transports/sse-server.d.ts
|
|
5
5
|
interface SseRpcTransportOptions {
|
|
@@ -14,7 +14,7 @@ interface SseRpcTransportOptions {
|
|
|
14
14
|
* RPC function definitions, used by the per-call wire serializer to
|
|
15
15
|
* dispatch between strict-JSON and structured-clone encoding based on
|
|
16
16
|
* each function's `jsonSerializable` flag. When omitted, all messages
|
|
17
|
-
* fall back to structured-clone
|
|
17
|
+
* fall back to structured-clone, the same contract as the WS transport.
|
|
18
18
|
*/
|
|
19
19
|
definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
|
|
20
20
|
onConnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
|
|
@@ -42,7 +42,7 @@ interface SseRpcTransport {
|
|
|
42
42
|
close: () => void;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* Attach an SSE + HTTP POST transport to an existing RPC group
|
|
45
|
+
* Attach an SSE + HTTP POST transport to an existing RPC group: the
|
|
46
46
|
* WebSocket-free counterpart to `attachWsRpcTransport`, for hosts and
|
|
47
47
|
* proxies where the upgrade isn't available. Speaks the same birpc wire
|
|
48
48
|
* protocol (one channel per session, per-method `jsonSerializable`
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { DEVFRAME_SSE_SESSION_HEADER } from "../../constants.mjs";
|
|
2
|
-
import { n as peekRpcWireFrame, t as createRpcWireCodec } from "../../wire-codec-
|
|
3
|
-
import {
|
|
2
|
+
import { n as peekRpcWireFrame, t as createRpcWireCodec } from "../../wire-codec-dcCeXcSo.mjs";
|
|
3
|
+
import { t as isAllowedOrigin } from "../../origin-DZit9g29.mjs";
|
|
4
|
+
import { t as createRpcSessionMeta } from "../../session-DPfj6zQG.mjs";
|
|
4
5
|
//#region src/rpc/transports/sse-server.ts
|
|
5
6
|
const SSE_STREAM_HEADERS = {
|
|
6
7
|
"content-type": "text/event-stream",
|
|
7
8
|
"cache-control": "no-cache, no-transform",
|
|
9
|
+
/** Tell buffering reverse proxies (nginx) to pass frames through as-is. */
|
|
8
10
|
"x-accel-buffering": "no"
|
|
9
11
|
};
|
|
10
12
|
function NOOP() {}
|
|
11
13
|
/**
|
|
12
|
-
* Attach an SSE + HTTP POST transport to an existing RPC group
|
|
14
|
+
* Attach an SSE + HTTP POST transport to an existing RPC group: the
|
|
13
15
|
* WebSocket-free counterpart to `attachWsRpcTransport`, for hosts and
|
|
14
16
|
* proxies where the upgrade isn't available. Speaks the same birpc wire
|
|
15
17
|
* protocol (one channel per session, per-method `jsonSerializable`
|
|
@@ -33,7 +35,7 @@ function attachSseRpcTransport(rpcGroup, options = {}) {
|
|
|
33
35
|
return allowedOrigins && !Array.isArray(allowedOrigins) ? allowedOrigins.isAllowed(origin) : isAllowedOrigin(origin, allowedOrigins ?? []);
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
|
-
* CORS headers for a browser on another (allowed) origin
|
|
38
|
+
* CORS headers for a browser on another (allowed) origin: the side-car /
|
|
37
39
|
* registered-viewer case. Same-origin requests carry no `Origin` (or their
|
|
38
40
|
* own), where these headers are inert.
|
|
39
41
|
*/
|
|
@@ -65,8 +67,6 @@ function attachSseRpcTransport(rpcGroup, options = {}) {
|
|
|
65
67
|
const session = {
|
|
66
68
|
id,
|
|
67
69
|
meta,
|
|
68
|
-
connection: void 0,
|
|
69
|
-
channel: void 0,
|
|
70
70
|
parked: /* @__PURE__ */ new Map(),
|
|
71
71
|
closed: false,
|
|
72
72
|
close: () => {
|
|
@@ -80,7 +80,7 @@ function attachSseRpcTransport(rpcGroup, options = {}) {
|
|
|
80
80
|
controller?.close();
|
|
81
81
|
} catch {}
|
|
82
82
|
rpcGroup.updateChannels((channels) => {
|
|
83
|
-
const index = channels.indexOf(session.channel);
|
|
83
|
+
const index = session.channel ? channels.indexOf(session.channel) : -1;
|
|
84
84
|
if (index >= 0) channels.splice(index, 1);
|
|
85
85
|
});
|
|
86
86
|
onDisconnected(session.connection, meta);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as WsOriginRegistry } from "../../ws-server-
|
|
2
|
-
import { t as ContextRpcServer } from "../../rpc-core-
|
|
1
|
+
import { n as WsOriginRegistry } from "../../ws-server-D2nv68Hg.mjs";
|
|
2
|
+
import { t as ContextRpcServer } from "../../rpc-core-Ceu6AUz8.mjs";
|
|
3
3
|
//#region src/rpc/transports/ws-bun.d.ts
|
|
4
4
|
interface AttachBunWsTransportOptions {
|
|
5
5
|
/** Same contract as `WsRpcTransportOptions.allowedOrigins`. */
|
|
@@ -7,7 +7,7 @@ interface AttachBunWsTransportOptions {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Structural view of the Bun `Bun.serve({ websocket })` handler object the
|
|
10
|
-
* crossws Bun adapter produces
|
|
10
|
+
* crossws Bun adapter produces, typed loosely so devframe carries no
|
|
11
11
|
* dependency on Bun's own types.
|
|
12
12
|
*/
|
|
13
13
|
interface BunWsTierWebSocket {
|
|
@@ -17,14 +17,14 @@ interface BunWsTierWebSocket {
|
|
|
17
17
|
drain?: (ws: unknown) => unknown;
|
|
18
18
|
}
|
|
19
19
|
interface BunWsTier {
|
|
20
|
-
/** Complete a WS upgrade request
|
|
20
|
+
/** Complete a WS upgrade request; `Bun.serve`'s server as 2nd argument. */
|
|
21
21
|
handleUpgrade: (request: Request, server: unknown) => Promise<Response | undefined>;
|
|
22
22
|
/** The handlers to spread into `Bun.serve({ websocket })`. */
|
|
23
23
|
websocket: BunWsTierWebSocket;
|
|
24
24
|
close: () => Promise<void>;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* The Bun fetch-upgrade WebSocket tier for `initDevframe` / `initHub
|
|
27
|
+
* The Bun fetch-upgrade WebSocket tier for `initDevframe` / `initHub`: the
|
|
28
28
|
* same RPC peer wiring as `attachWsRpcTransport`, driven by crossws's Bun
|
|
29
29
|
* adapter so upgrades complete through `handler(request, server)` on the
|
|
30
30
|
* app's own origin, with no side-car server. Load it dynamically so the Bun
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as isAllowedOrigin } from "../../origin-DZit9g29.mjs";
|
|
2
|
+
import { createWsRpcPeerHooks } from "./ws-server.mjs";
|
|
2
3
|
//#region src/rpc/transports/ws-bun.ts
|
|
3
4
|
/**
|
|
4
|
-
* The Bun fetch-upgrade WebSocket tier for `initDevframe` / `initHub
|
|
5
|
+
* The Bun fetch-upgrade WebSocket tier for `initDevframe` / `initHub`: the
|
|
5
6
|
* same RPC peer wiring as `attachWsRpcTransport`, driven by crossws's Bun
|
|
6
7
|
* adapter so upgrades complete through `handler(request, server)` on the
|
|
7
8
|
* app's own origin, with no side-car server. Load it dynamically so the Bun
|
|
@@ -15,6 +16,11 @@ async function attachBunWsTransport(core, options = {}) {
|
|
|
15
16
|
onConnected: core.onConnected,
|
|
16
17
|
onDisconnected: core.onDisconnected
|
|
17
18
|
}),
|
|
19
|
+
/**
|
|
20
|
+
* The same origin policy `routeUpgrades` applies for the Node
|
|
21
|
+
* transport, enforced at the upgrade hook since Bun upgrades arrive
|
|
22
|
+
* as fetch requests rather than `upgrade` socket events.
|
|
23
|
+
*/
|
|
18
24
|
upgrade(request) {
|
|
19
25
|
const origin = request.headers.get("origin") ?? void 0;
|
|
20
26
|
const allowed = allowedOrigins && !Array.isArray(allowedOrigins) ? allowedOrigins.isAllowed(origin) : isAllowedOrigin(origin, allowedOrigins || []);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createWsRpcChannel, t as WsRpcChannelOptions } from "../../ws-client-
|
|
1
|
+
import { n as createWsRpcChannel, t as WsRpcChannelOptions } from "../../ws-client-Xpxt0oPA.mjs";
|
|
2
2
|
export { WsRpcChannelOptions, createWsRpcChannel };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEVFRAME_AUTH_TOKEN_QUERY_PARAM } from "../../constants.mjs";
|
|
2
|
-
import { t as createRpcWireCodec } from "../../wire-codec-
|
|
2
|
+
import { t as createRpcWireCodec } from "../../wire-codec-dcCeXcSo.mjs";
|
|
3
3
|
//#region src/rpc/transports/ws-client.ts
|
|
4
4
|
function NOOP() {}
|
|
5
5
|
const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
@@ -7,7 +7,7 @@ const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
|
7
7
|
* Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
|
|
8
8
|
* Pass the result straight to `createRpcClient`'s `channel` option.
|
|
9
9
|
*
|
|
10
|
-
* Also returns `close()`, closing the underlying socket
|
|
10
|
+
* Also returns `close()`, closing the underlying socket, mirroring the server transport's
|
|
11
11
|
* existing `WsRpcTransport.close()`. `birpc`'s own `ChannelOptions` has no teardown of its own.
|
|
12
12
|
*/
|
|
13
13
|
function createWsRpcChannel(options) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as WsOriginRegistry } from "../../ws-server-
|
|
2
|
-
import { t as ContextRpcServer } from "../../rpc-core-
|
|
1
|
+
import { n as WsOriginRegistry } from "../../ws-server-D2nv68Hg.mjs";
|
|
2
|
+
import { t as ContextRpcServer } from "../../rpc-core-Ceu6AUz8.mjs";
|
|
3
3
|
//#region src/rpc/transports/ws-deno.d.ts
|
|
4
4
|
interface AttachDenoWsTransportOptions {
|
|
5
5
|
/** Same contract as `WsRpcTransportOptions.allowedOrigins`. */
|
|
@@ -7,7 +7,7 @@ interface AttachDenoWsTransportOptions {
|
|
|
7
7
|
}
|
|
8
8
|
interface DenoWsTier {
|
|
9
9
|
/**
|
|
10
|
-
* Complete a WS upgrade request
|
|
10
|
+
* Complete a WS upgrade request; `Deno.serve`'s handler info as the 2nd
|
|
11
11
|
* argument. Unlike Bun, Deno's adapter attaches the socket to the returned
|
|
12
12
|
* `Response` itself, so there is no `websocket` handler object to register.
|
|
13
13
|
*/
|
|
@@ -15,7 +15,7 @@ interface DenoWsTier {
|
|
|
15
15
|
close: () => Promise<void>;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* The Deno fetch-upgrade WebSocket tier for `initDevframe` / `initHub
|
|
18
|
+
* The Deno fetch-upgrade WebSocket tier for `initDevframe` / `initHub`: the
|
|
19
19
|
* same RPC peer wiring as `attachWsRpcTransport`, driven by crossws's Deno
|
|
20
20
|
* adapter so upgrades complete through `handleUpgrade(request, info)` on the
|
|
21
21
|
* app's own origin, with no side-car server. Load it dynamically so the Deno
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as isAllowedOrigin } from "../../origin-DZit9g29.mjs";
|
|
2
|
+
import { createWsRpcPeerHooks } from "./ws-server.mjs";
|
|
2
3
|
//#region src/rpc/transports/ws-deno.ts
|
|
3
4
|
/**
|
|
4
|
-
* The Deno fetch-upgrade WebSocket tier for `initDevframe` / `initHub
|
|
5
|
+
* The Deno fetch-upgrade WebSocket tier for `initDevframe` / `initHub`: the
|
|
5
6
|
* same RPC peer wiring as `attachWsRpcTransport`, driven by crossws's Deno
|
|
6
7
|
* adapter so upgrades complete through `handleUpgrade(request, info)` on the
|
|
7
8
|
* app's own origin, with no side-car server. Load it dynamically so the Deno
|
|
@@ -15,6 +16,11 @@ async function attachDenoWsTransport(core, options = {}) {
|
|
|
15
16
|
onConnected: core.onConnected,
|
|
16
17
|
onDisconnected: core.onDisconnected
|
|
17
18
|
}),
|
|
19
|
+
/**
|
|
20
|
+
* The same origin policy `routeUpgrades` applies for the Node
|
|
21
|
+
* transport, enforced at the upgrade hook since Deno upgrades arrive
|
|
22
|
+
* as fetch requests rather than `upgrade` socket events.
|
|
23
|
+
*/
|
|
18
24
|
upgrade(request) {
|
|
19
25
|
const origin = request.headers.get("origin") ?? void 0;
|
|
20
26
|
const allowed = allowedOrigins && !Array.isArray(allowedOrigins) ? allowedOrigins.isAllowed(origin) : isAllowedOrigin(origin, allowedOrigins || []);
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { a as attachWsRpcTransport, c as
|
|
1
|
+
import { a as attachWsRpcTransport, c as DevframeNodeRpcSessionMeta, d as DevframeRpcTransportKind, i as WsRpcTransportOptions, l as DevframeRpcConnection, n as WsOriginRegistry, o as createWsOriginRegistry, r as WsRpcTransport, s as createWsRpcPeerHooks, t as CreateWsOriginRegistryOptions, u as DevframeRpcConnectionRequest } from "../../ws-server-D2nv68Hg.mjs";
|
|
2
|
+
import { n as isLoopbackHostname, t as isAllowedOrigin } from "../../origin-DGDH8BI9.mjs";
|
|
2
3
|
export { CreateWsOriginRegistryOptions, type DevframeNodeRpcSessionMeta, type DevframeRpcConnection, type DevframeRpcConnectionRequest, type DevframeRpcTransportKind, WsOriginRegistry, WsRpcTransport, WsRpcTransportOptions, attachWsRpcTransport, createWsOriginRegistry, createWsRpcPeerHooks, isAllowedOrigin, isLoopbackHostname };
|
|
@@ -1,2 +1,233 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../../constants.mjs";
|
|
2
|
+
import { t as createRpcWireCodec } from "../../wire-codec-dcCeXcSo.mjs";
|
|
3
|
+
import { n as isLoopbackHostname, t as isAllowedOrigin } from "../../origin-DZit9g29.mjs";
|
|
4
|
+
import { t as createRpcSessionMeta } from "../../session-DPfj6zQG.mjs";
|
|
5
|
+
import { n as randomToken, r as timingSafeEqual } from "../../crypto-token-TVbGGFuj.mjs";
|
|
6
|
+
import { createServer } from "node:http";
|
|
7
|
+
import { createServer as createServer$1 } from "node:https";
|
|
8
|
+
import crossws from "crossws/adapters/node";
|
|
9
|
+
//#region src/rpc/transports/ws-server.ts
|
|
10
|
+
/**
|
|
11
|
+
* Create a live, token-protected origin allowlist for external browser
|
|
12
|
+
* viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
|
|
13
|
+
* `registerFromUrl()` in the connection metadata handler to authorize a
|
|
14
|
+
* viewer without sharing a mutable array or disabling DNS-rebinding protection.
|
|
15
|
+
*/
|
|
16
|
+
function createWsOriginRegistry(options = {}) {
|
|
17
|
+
const token = randomToken();
|
|
18
|
+
const origins = new Set(options.allowedOrigins ?? []);
|
|
19
|
+
function normalizeOrigin(origin) {
|
|
20
|
+
if (!origin) return;
|
|
21
|
+
try {
|
|
22
|
+
const url = new URL(origin);
|
|
23
|
+
const normalized = url.origin === "null" ? `${url.protocol}//${url.host}` : url.origin;
|
|
24
|
+
return origin === normalized ? normalized : void 0;
|
|
25
|
+
} catch {}
|
|
26
|
+
}
|
|
27
|
+
function registerOrigin(origin, candidateToken) {
|
|
28
|
+
const normalized = normalizeOrigin(origin);
|
|
29
|
+
if (!normalized || !candidateToken || !timingSafeEqual(token, candidateToken)) return false;
|
|
30
|
+
if (options.validateOrigin && !options.validateOrigin(normalized)) return false;
|
|
31
|
+
origins.add(normalized);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
token,
|
|
36
|
+
registerFromUrl(url) {
|
|
37
|
+
let parsed;
|
|
38
|
+
try {
|
|
39
|
+
parsed = new URL(url, "http://localhost");
|
|
40
|
+
} catch {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const origin = parsed.searchParams.get("devframe_viewer_origin") ?? void 0;
|
|
44
|
+
return registerOrigin(origin, parsed.searchParams.get("devframe_viewer_origin_token") ?? void 0) ? origin : void 0;
|
|
45
|
+
},
|
|
46
|
+
isAllowed(origin) {
|
|
47
|
+
return isAllowedOrigin(origin, [...origins]);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
52
|
+
function NOOP() {}
|
|
53
|
+
function listen(server, port, host) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const onError = (error) => reject(error);
|
|
56
|
+
server.once("error", onError);
|
|
57
|
+
try {
|
|
58
|
+
server.listen(port, host, () => {
|
|
59
|
+
server.off("error", onError);
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
server.off("error", onError);
|
|
64
|
+
reject(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Compare two URL paths ignoring a trailing slash. */
|
|
69
|
+
function pathMatches(a, b) {
|
|
70
|
+
const strip = (p) => p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
71
|
+
return strip(a) === strip(b);
|
|
72
|
+
}
|
|
73
|
+
function isWsOriginRegistry(value) {
|
|
74
|
+
return !!value && !Array.isArray(value);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build the `upgrade` listener that hands a request to the crossws adapter,
|
|
78
|
+
* optionally filtered to a single `path`. Non-matching requests are left
|
|
79
|
+
* untouched so other upgrade listeners (e.g. a Vite dev server's HMR socket)
|
|
80
|
+
* can claim them, unless `destroyUnmatched` is set.
|
|
81
|
+
*/
|
|
82
|
+
function createUpgradeListener(ws, path, destroyUnmatched, allowedOrigins) {
|
|
83
|
+
return (req, socket, head) => {
|
|
84
|
+
socket.on("error", () => {});
|
|
85
|
+
if (path) {
|
|
86
|
+
let pathname = req.url ?? "/";
|
|
87
|
+
try {
|
|
88
|
+
pathname = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
89
|
+
} catch {}
|
|
90
|
+
if (!pathMatches(pathname, path)) {
|
|
91
|
+
if (destroyUnmatched) {
|
|
92
|
+
socket.write("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n");
|
|
93
|
+
socket.destroy();
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const originAllowed = isWsOriginRegistry(allowedOrigins) ? allowedOrigins.isAllowed(req.headers.origin) : isAllowedOrigin(req.headers.origin, allowedOrigins || []);
|
|
99
|
+
if (allowedOrigins !== false && !originAllowed) {
|
|
100
|
+
socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
|
|
101
|
+
socket.destroy();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
ws.handleUpgrade(req, socket, head);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The per-peer lifecycle hooks driving a devframe RPC WebSocket, shaped for
|
|
109
|
+
* any [crossws](https://crossws.h3.dev) adapter. {@link attachWsRpcTransport}
|
|
110
|
+
* feeds them to the Node adapter; runtime-specific attachments (e.g. Bun's
|
|
111
|
+
* fetch-upgrade adapter) reuse the same hooks so every transport speaks the
|
|
112
|
+
* identical wire protocol: one birpc channel per peer, per-method
|
|
113
|
+
* `jsonSerializable` dispatch between strict JSON and structured-clone.
|
|
114
|
+
*/
|
|
115
|
+
function createWsRpcPeerHooks(rpcGroup, options = {}) {
|
|
116
|
+
const { onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
|
|
117
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
118
|
+
return {
|
|
119
|
+
open: (peer) => {
|
|
120
|
+
const meta = createRpcSessionMeta();
|
|
121
|
+
meta.peer = peer;
|
|
122
|
+
const connection = {
|
|
123
|
+
id: meta.id,
|
|
124
|
+
transport: "websocket",
|
|
125
|
+
request: peer.request,
|
|
126
|
+
send: (data) => peer.send(data),
|
|
127
|
+
close: (code, reason) => peer.close(code, reason),
|
|
128
|
+
peer
|
|
129
|
+
};
|
|
130
|
+
const codec = createRpcWireCodec(definitions);
|
|
131
|
+
const state = {
|
|
132
|
+
meta,
|
|
133
|
+
connection
|
|
134
|
+
};
|
|
135
|
+
const channel = {
|
|
136
|
+
post: (data) => {
|
|
137
|
+
peer.send(data);
|
|
138
|
+
},
|
|
139
|
+
on: (fn) => {
|
|
140
|
+
state.onMessage = fn;
|
|
141
|
+
},
|
|
142
|
+
serialize: serializeOverride ?? codec.serialize,
|
|
143
|
+
deserialize: deserializeOverride ?? codec.deserialize,
|
|
144
|
+
meta
|
|
145
|
+
};
|
|
146
|
+
state.channel = channel;
|
|
147
|
+
states.set(peer, state);
|
|
148
|
+
rpcGroup.updateChannels((channels) => {
|
|
149
|
+
channels.push(channel);
|
|
150
|
+
});
|
|
151
|
+
onConnected(connection, meta);
|
|
152
|
+
},
|
|
153
|
+
message: (peer, message) => {
|
|
154
|
+
states.get(peer)?.onMessage?.(message.text());
|
|
155
|
+
},
|
|
156
|
+
close: (peer) => {
|
|
157
|
+
const state = states.get(peer);
|
|
158
|
+
if (!state) return;
|
|
159
|
+
states.delete(peer);
|
|
160
|
+
rpcGroup.updateChannels((channels) => {
|
|
161
|
+
const index = state.channel ? channels.indexOf(state.channel) : -1;
|
|
162
|
+
if (index >= 0) channels.splice(index, 1);
|
|
163
|
+
});
|
|
164
|
+
onDisconnected(state.connection, state.meta);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Attach a WebSocket transport to an existing RPC group, powered by
|
|
170
|
+
* [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
|
|
171
|
+
* `server` (sharing its port, optionally scoped to a `path`), or let this
|
|
172
|
+
* helper create a standalone server from `port` / `host` / `https`.
|
|
173
|
+
*
|
|
174
|
+
* Returns the crossws node adapter, standalone-server readiness/address
|
|
175
|
+
* accessors, `detach` (remove the upgrade listener from a shared `server`),
|
|
176
|
+
* and `close` (full deterministic teardown).
|
|
177
|
+
*/
|
|
178
|
+
function attachWsRpcTransport(rpcGroup, options = {}) {
|
|
179
|
+
const { server, port, host = "localhost", path, destroyUnmatched = false, unbound, https, allowedOrigins } = options;
|
|
180
|
+
const ws = crossws({ hooks: createWsRpcPeerHooks(rpcGroup, options) });
|
|
181
|
+
const sharedUpgradeListener = createUpgradeListener(ws, path, destroyUnmatched, allowedOrigins);
|
|
182
|
+
const ownedUpgradeListener = createUpgradeListener(ws, path, true, allowedOrigins);
|
|
183
|
+
/** Bind a server's `upgrade` events, tracked so `close()` detaches them. */
|
|
184
|
+
const attachments = /* @__PURE__ */ new Set();
|
|
185
|
+
function attachTo(target, listener) {
|
|
186
|
+
target.on("upgrade", listener);
|
|
187
|
+
const detachOne = () => {
|
|
188
|
+
target.off("upgrade", listener);
|
|
189
|
+
attachments.delete(detachOne);
|
|
190
|
+
};
|
|
191
|
+
attachments.add(detachOne);
|
|
192
|
+
return detachOne;
|
|
193
|
+
}
|
|
194
|
+
let ready = Promise.resolve();
|
|
195
|
+
let ownedServer;
|
|
196
|
+
if (unbound) {} else if (server) attachTo(server, sharedUpgradeListener);
|
|
197
|
+
else if (https) {
|
|
198
|
+
ownedServer = createServer$1(https);
|
|
199
|
+
attachTo(ownedServer, ownedUpgradeListener);
|
|
200
|
+
ready = listen(ownedServer, port ?? 0, host);
|
|
201
|
+
} else {
|
|
202
|
+
ownedServer = createServer((_req, res) => {
|
|
203
|
+
res.writeHead(426, { "content-type": "text/plain" });
|
|
204
|
+
res.end("Upgrade Required");
|
|
205
|
+
});
|
|
206
|
+
attachTo(ownedServer, ownedUpgradeListener);
|
|
207
|
+
ready = listen(ownedServer, port ?? 0, host);
|
|
208
|
+
}
|
|
209
|
+
const activeServer = server ?? ownedServer;
|
|
210
|
+
function detachAll() {
|
|
211
|
+
for (const detachOne of [...attachments]) detachOne();
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
ws,
|
|
215
|
+
ready,
|
|
216
|
+
address: () => activeServer?.address() ?? null,
|
|
217
|
+
handleUpgrade: sharedUpgradeListener,
|
|
218
|
+
attach: (target) => attachTo(target, sharedUpgradeListener),
|
|
219
|
+
detach: detachAll,
|
|
220
|
+
async close() {
|
|
221
|
+
detachAll();
|
|
222
|
+
ws.closeAll(void 0, void 0, true);
|
|
223
|
+
if (ownedServer) {
|
|
224
|
+
const srv = ownedServer;
|
|
225
|
+
await ready.catch(() => {});
|
|
226
|
+
if (!srv.listening) return;
|
|
227
|
+
await new Promise((r) => srv.close(() => r()));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
2
233
|
export { attachWsRpcTransport, createWsOriginRegistry, createWsRpcPeerHooks, isAllowedOrigin, isLoopbackHostname };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import "./index-
|
|
1
|
+
import { c as DevframeNodeRpcSessionMeta, l as DevframeRpcConnection } from "./ws-server-D2nv68Hg.mjs";
|
|
2
|
+
import { _t as DevframeRpcClientFunctions, o as DevframeNodeContext, s as DevframeNodeRpcSession, vt as DevframeRpcServerFunctions, wt as DevframeAuthHandler } from "./context-4AIVRLYF.mjs";
|
|
3
|
+
import "./index-pKl67H6w.mjs";
|
|
4
4
|
import { BirpcGroup, EventOptions } from "birpc";
|
|
5
5
|
//#region src/node/rpc-core.d.ts
|
|
6
6
|
interface CreateContextRpcServerOptions {
|
|
@@ -33,7 +33,7 @@ interface ContextRpcServer {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Bind a devframe context's registered RPC functions to a birpc group,
|
|
36
|
-
* transport-agnostically
|
|
36
|
+
* transport-agnostically: the shared core under the instance shell's own
|
|
37
37
|
* HTTP+WS binding (Node http + WS) and the Bun fetch-upgrade tier of
|
|
38
38
|
* `createHandler`.
|
|
39
39
|
*
|