devframe 0.8.2 → 0.9.0-beta.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.
Files changed (103) hide show
  1. package/dist/_shared-CttmCMBi.mjs +70 -0
  2. package/dist/_shared-DmpWW-HH.d.mts +43 -0
  3. package/dist/adapters/build.d.mts +1 -1
  4. package/dist/adapters/build.mjs +6 -5
  5. package/dist/adapters/cac.d.mts +1 -1
  6. package/dist/adapters/cac.mjs +157 -1
  7. package/dist/adapters/dev.d.mts +20 -42
  8. package/dist/adapters/dev.mjs +2 -1
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +223 -0
  11. package/dist/adapters/initiate.mjs +2 -0
  12. package/dist/adapters/mcp.d.mts +26 -2
  13. package/dist/adapters/mcp.mjs +2 -2
  14. package/dist/cli/main.mjs +2 -2
  15. package/dist/client/index.d.mts +70 -6
  16. package/dist/client/index.mjs +743 -408
  17. package/dist/constants.d.mts +19 -6
  18. package/dist/constants.mjs +19 -6
  19. package/dist/{context-CBg8iRbQ.mjs → context-C33rR7n0.mjs} +1 -1
  20. package/dist/{context-DoSozfvx.d.mts → context-CSCwoABx.d.mts} +1 -1
  21. package/dist/{host-h3-D2hYZvDK.mjs → context-Du11TLcO.mjs} +5 -255
  22. package/dist/dev-BEveeA5H.mjs +233 -0
  23. package/dist/{devframe-mQ4qZAuo.d.mts → devframe-Bdd9YXTy.d.mts} +88 -25
  24. package/dist/{diagnostics-D7wM2cwM.mjs → diagnostics-DLYH5oD3.mjs} +16 -0
  25. package/dist/dist-D8jAMwxU.mjs +227 -0
  26. package/dist/helpers/vite.d.mts +43 -39
  27. package/dist/helpers/vite.mjs +26 -38
  28. package/dist/host-agent-CpbAoqBx.mjs +230 -0
  29. package/dist/host-h3-CzCZwtuV.mjs +26 -0
  30. package/dist/{fetch-BKaD0Vb3.mjs → http-DLr_cJZ7.mjs} +42 -4
  31. package/dist/{index-b64Uuhy2.d.mts → index-CZRd2K1C.d.mts} +2 -2
  32. package/dist/{index-Dbw1p5ch.d.mts → index-DSCq4M4q.d.mts} +2 -31
  33. package/dist/index.d.mts +9 -4
  34. package/dist/index.mjs +8 -1
  35. package/dist/{instance-registry-BnnA2Eoh.mjs → instance-registry-BQqGoDO9.mjs} +9 -2
  36. package/dist/instance-shell-DBTXTSjN.d.mts +264 -0
  37. package/dist/instance-shell-KRdee1QF.mjs +485 -0
  38. package/dist/internal/index.d.mts +150 -0
  39. package/dist/internal/index.mjs +7 -0
  40. package/dist/node/auth.d.mts +2 -2
  41. package/dist/node/hub-internals.d.mts +2 -14
  42. package/dist/node/hub-internals.mjs +2 -2
  43. package/dist/node/index.d.mts +3 -267
  44. package/dist/node/index.mjs +3 -5
  45. package/dist/recipes/common-rpc-functions.d.mts +3 -3
  46. package/dist/recipes/interactive-auth.d.mts +3 -3
  47. package/dist/recipes/interactive-auth.mjs +6 -6
  48. package/dist/rolldown-runtime-JspESFgx.mjs +35 -0
  49. package/dist/rpc/dump.d.mts +77 -1
  50. package/dist/rpc/dump.mjs +1 -1
  51. package/dist/rpc/index.d.mts +2 -2
  52. package/dist/rpc/index.mjs +3 -17
  53. package/dist/rpc/transports/sse-client.d.mts +2 -0
  54. package/dist/rpc/transports/sse-client.mjs +142 -0
  55. package/dist/rpc/transports/sse-server.d.mts +61 -0
  56. package/dist/rpc/transports/sse-server.mjs +209 -0
  57. package/dist/rpc/transports/ws-bun.d.mts +35 -0
  58. package/dist/rpc/transports/ws-bun.mjs +31 -0
  59. package/dist/rpc/transports/ws-client.d.mts +1 -1
  60. package/dist/rpc/transports/ws-client.mjs +10 -18
  61. package/dist/rpc/transports/ws-server.d.mts +2 -2
  62. package/dist/rpc/transports/ws-server.mjs +2 -235
  63. package/dist/rpc-core-CGctXToO.d.mts +48 -0
  64. package/dist/rpc-core-CqcJkAu9.mjs +81 -0
  65. package/dist/{serialization-C8Mnw9hK.mjs → serialization-BHY8M5NQ.mjs} +1 -1
  66. package/dist/{shared-state-6kHolYZy.mjs → shared-state-fRRbRUtD.mjs} +1 -1
  67. package/dist/sse-client-BsIK3hMD.d.mts +37 -0
  68. package/dist/{dump-CgZShDRB.mjs → static-CvjkO8QE.mjs} +2 -265
  69. package/dist/{storage-CTNVbuFB.mjs → storage-BcmVEJRc.mjs} +2 -2
  70. package/dist/types/index.d.mts +3 -3
  71. package/dist/types/index.mjs +1 -6
  72. package/dist/utils/events.d.mts +1 -1
  73. package/dist/utils/launch-editor.mjs +1 -25
  74. package/dist/utils/open.mjs +1 -1
  75. package/dist/utils/serve-static.mjs +1 -1
  76. package/dist/utils/shared-state.d.mts +1 -1
  77. package/dist/utils/shared-state.mjs +1 -1
  78. package/dist/utils/simple-schema.d.mts +101 -1
  79. package/dist/utils/streaming-channel.d.mts +1 -1
  80. package/dist/validation-BiuDXTKW.mjs +266 -0
  81. package/dist/wire-codec-9VhIKnyp.mjs +58 -0
  82. package/dist/{ws-client-B6Tnr0ic.d.mts → ws-client-CdNuATYa.d.mts} +6 -1
  83. package/dist/ws-server-Bk1hOG3X.mjs +267 -0
  84. package/dist/{ws-server-uKQcClcJ.d.mts → ws-server-Ces08fjP.d.mts} +89 -8
  85. package/package.json +10 -9
  86. package/skills/devframe/SKILL.md +84 -85
  87. package/dist/_shared-bWRzeSa0.mjs +0 -19
  88. package/dist/adapters/cli.d.mts +0 -11
  89. package/dist/adapters/cli.mjs +0 -6
  90. package/dist/cac-D4_9ok0z.mjs +0 -157
  91. package/dist/dev-Bc49u3qg.mjs +0 -439
  92. package/dist/http-C4T68YV6.mjs +0 -38
  93. package/dist/index-vAX6bYuc.d.mts +0 -78
  94. package/dist/recipes/open-helpers.d.mts +0 -6
  95. package/dist/recipes/open-helpers.mjs +0 -6
  96. package/dist/server-CD8XmBXl.mjs +0 -167
  97. package/dist/server-UHWae43Q.d.mts +0 -149
  98. package/dist/simple-schema-BDzLeJDk.d.mts +0 -102
  99. package/dist/utils/promise.d.mts +0 -8
  100. package/dist/utils/promise.mjs +0 -15
  101. package/dist/utils/scope.d.mts +0 -11
  102. package/dist/utils/scope.mjs +0 -15
  103. package/dist/{open-Deb5xmIT.mjs → open-Dz4V4irZ.mjs} +1 -1
@@ -1,235 +1,2 @@
1
- import "../../constants.mjs";
2
- import { n as strictJsonStringify } from "../../serialization-C8Mnw9hK.mjs";
3
- import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-CbAV5rFI.mjs";
4
- import { n as randomToken, r as timingSafeEqual } from "../../crypto-token-XCqTSMg9.mjs";
5
- import { createServer } from "node:http";
6
- import { createServer as createServer$1 } from "node:https";
7
- import crossws from "crossws/adapters/node";
8
- //#region src/rpc/transports/ws-server.ts
9
- /**
10
- * Create a live, token-protected origin allowlist for external browser
11
- * viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
12
- * `registerFromUrl()` in the connection metadata handler to authorize a
13
- * viewer without sharing a mutable array or disabling DNS-rebinding protection.
14
- */
15
- function createWsOriginRegistry(options = {}) {
16
- const token = randomToken();
17
- const origins = new Set(options.allowedOrigins ?? []);
18
- function normalizeOrigin(origin) {
19
- if (!origin) return;
20
- try {
21
- const url = new URL(origin);
22
- const normalized = url.origin === "null" ? `${url.protocol}//${url.host}` : url.origin;
23
- return origin === normalized ? normalized : void 0;
24
- } catch {}
25
- }
26
- function registerOrigin(origin, candidateToken) {
27
- const normalized = normalizeOrigin(origin);
28
- if (!normalized || !candidateToken || !timingSafeEqual(token, candidateToken)) return false;
29
- if (options.validateOrigin && !options.validateOrigin(normalized)) return false;
30
- origins.add(normalized);
31
- return true;
32
- }
33
- return {
34
- token,
35
- registerFromUrl(url) {
36
- let parsed;
37
- try {
38
- parsed = new URL(url, "http://localhost");
39
- } catch {
40
- return;
41
- }
42
- const origin = parsed.searchParams.get("devframe_viewer_origin") ?? void 0;
43
- return registerOrigin(origin, parsed.searchParams.get("devframe_viewer_origin_token") ?? void 0) ? origin : void 0;
44
- },
45
- isAllowed(origin) {
46
- return isAllowedOrigin(origin, [...origins]);
47
- }
48
- };
49
- }
50
- let sessionId = 0;
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 isLoopbackHostname(hostname) {
74
- const h = hostname.replace(/^\[|\]$/g, "");
75
- return h === "localhost" || h === "127.0.0.1" || h === "::1" || h.endsWith(".localhost") || h.startsWith("127.");
76
- }
77
- /**
78
- * Default origin policy for a localhost dev tool: allow requests with no
79
- * `Origin` header (native, non-browser clients), allow any loopback origin
80
- * (so cross-port localhost dev setups keep working), and allow explicitly
81
- * configured origins. Everything else — a real remote page in the dev's
82
- * browser — is rejected.
83
- */
84
- function isAllowedOrigin(origin, allowedOrigins) {
85
- if (!origin) return true;
86
- if (allowedOrigins.includes(origin)) return true;
87
- try {
88
- return isLoopbackHostname(new URL(origin).hostname);
89
- } catch {
90
- return false;
91
- }
92
- }
93
- function isWsOriginRegistry(value) {
94
- return !!value && !Array.isArray(value);
95
- }
96
- /**
97
- * Route `upgrade` events on a server to the crossws adapter, optionally
98
- * filtered to a single `path`. Non-matching requests are left untouched so
99
- * other upgrade listeners (e.g. a Vite dev server's HMR socket) can claim
100
- * them, unless `destroyUnmatched` is set. Returns a detach function that
101
- * removes the listener.
102
- */
103
- function routeUpgrades(server, ws, path, destroyUnmatched, allowedOrigins) {
104
- const listener = (req, socket, head) => {
105
- socket.on("error", () => {});
106
- if (path) {
107
- let pathname = req.url ?? "/";
108
- try {
109
- pathname = new URL(req.url ?? "/", "http://localhost").pathname;
110
- } catch {}
111
- if (!pathMatches(pathname, path)) {
112
- if (destroyUnmatched) {
113
- socket.write("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n");
114
- socket.destroy();
115
- }
116
- return;
117
- }
118
- }
119
- const originAllowed = isWsOriginRegistry(allowedOrigins) ? allowedOrigins.isAllowed(req.headers.origin) : isAllowedOrigin(req.headers.origin, allowedOrigins || []);
120
- if (allowedOrigins !== false && !originAllowed) {
121
- socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
122
- socket.destroy();
123
- return;
124
- }
125
- ws.handleUpgrade(req, socket, head);
126
- };
127
- server.on("upgrade", listener);
128
- return () => server.off("upgrade", listener);
129
- }
130
- /**
131
- * Attach a WebSocket transport to an existing RPC group, powered by
132
- * [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
133
- * `server` (sharing its port, optionally scoped to a `path`), or let this
134
- * helper create a standalone server from `port` / `host` / `https`.
135
- *
136
- * Returns the crossws node adapter, standalone-server readiness/address
137
- * accessors, `detach` (remove the upgrade listener from a shared `server`),
138
- * and `close` (full deterministic teardown).
139
- */
140
- function attachWsRpcTransport(rpcGroup, options = {}) {
141
- const { server, port, host = "localhost", path, destroyUnmatched = false, https, allowedOrigins, onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
142
- const states = /* @__PURE__ */ new WeakMap();
143
- const ws = crossws({ hooks: {
144
- open: (peer) => {
145
- const meta = {
146
- id: sessionId++,
147
- peer,
148
- subscribedStates: /* @__PURE__ */ new Set()
149
- };
150
- const pendingRequestMethods = /* @__PURE__ */ new Map();
151
- const state = {
152
- meta,
153
- channel: void 0
154
- };
155
- const channel = {
156
- post: (data) => {
157
- peer.send(data);
158
- },
159
- on: (fn) => {
160
- state.onMessage = fn;
161
- },
162
- serialize: serializeOverride ?? ((msg) => {
163
- let method;
164
- if (msg.t === "q") method = msg.m;
165
- else {
166
- method = pendingRequestMethods.get(msg.i);
167
- pendingRequestMethods.delete(msg.i);
168
- }
169
- if (!(msg.t === "s" && "e" in msg) && !!method && definitions.get(method)?.jsonSerializable === true) return strictJsonStringify(msg, method ?? "");
170
- return `s:${structuredCloneStringify(msg)}`;
171
- }),
172
- deserialize: deserializeOverride ?? ((raw) => {
173
- const msg = raw.startsWith("s:") ? structuredCloneParse(raw.slice(2)) : JSON.parse(raw);
174
- if (msg.t === "q" && msg.i && msg.m) pendingRequestMethods.set(msg.i, msg.m);
175
- return msg;
176
- }),
177
- meta
178
- };
179
- state.channel = channel;
180
- states.set(peer, state);
181
- rpcGroup.updateChannels((channels) => {
182
- channels.push(channel);
183
- });
184
- onConnected(peer, meta);
185
- },
186
- message: (peer, message) => {
187
- states.get(peer)?.onMessage?.(message.text());
188
- },
189
- close: (peer) => {
190
- const state = states.get(peer);
191
- if (!state) return;
192
- states.delete(peer);
193
- rpcGroup.updateChannels((channels) => {
194
- const index = channels.indexOf(state.channel);
195
- if (index >= 0) channels.splice(index, 1);
196
- });
197
- onDisconnected(peer, state.meta);
198
- }
199
- } });
200
- let detach = NOOP;
201
- let ready = Promise.resolve();
202
- let ownedServer;
203
- if (server) detach = routeUpgrades(server, ws, path, destroyUnmatched, allowedOrigins);
204
- else if (https) {
205
- ownedServer = createServer$1(https);
206
- detach = routeUpgrades(ownedServer, ws, path, true, allowedOrigins);
207
- ready = listen(ownedServer, port ?? 0, host);
208
- } else {
209
- ownedServer = createServer((_req, res) => {
210
- res.writeHead(426, { "content-type": "text/plain" });
211
- res.end("Upgrade Required");
212
- });
213
- detach = routeUpgrades(ownedServer, ws, path, true, allowedOrigins);
214
- ready = listen(ownedServer, port ?? 0, host);
215
- }
216
- const activeServer = server ?? ownedServer;
217
- return {
218
- ws,
219
- ready,
220
- address: () => activeServer?.address() ?? null,
221
- detach,
222
- async close() {
223
- detach();
224
- ws.closeAll(void 0, void 0, true);
225
- if (ownedServer) {
226
- const srv = ownedServer;
227
- await ready.catch(() => {});
228
- if (!srv.listening) return;
229
- await new Promise((r) => srv.close(() => r()));
230
- }
231
- }
232
- };
233
- }
234
- //#endregion
235
- export { attachWsRpcTransport, createWsOriginRegistry, isAllowedOrigin, isLoopbackHostname };
1
+ import { a as isLoopbackHostname, i as isAllowedOrigin, n as createWsOriginRegistry, r as createWsRpcPeerHooks, t as attachWsRpcTransport } from "../../ws-server-Bk1hOG3X.mjs";
2
+ export { attachWsRpcTransport, createWsOriginRegistry, createWsRpcPeerHooks, isAllowedOrigin, isLoopbackHostname };
@@ -0,0 +1,48 @@
1
+ import { $ as DevframeRpcClientFunctions, G as DevframeNodeRpcSession, et as DevframeRpcServerFunctions, p as DevframeAuthHandler, x as DevframeNodeContext } from "./devframe-Bdd9YXTy.mjs";
2
+ import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-Ces08fjP.mjs";
3
+ import "./index-CZRd2K1C.mjs";
4
+ import { BirpcGroup, EventOptions } from "birpc";
5
+ //#region src/node/rpc-core.d.ts
6
+ interface CreateContextRpcServerOptions {
7
+ context: DevframeNodeContext;
8
+ /**
9
+ * Auth intent: `true`/omitted gates by default, `false` opts out (auto-trust
10
+ * handshake shim), a {@link DevframeAuthHandler} installs a custom scheme.
11
+ */
12
+ auth?: boolean | DevframeAuthHandler;
13
+ /** Lower-level per-call gate by method name and session, without a full handler. */
14
+ authorize?: (methodName: string, session: DevframeNodeRpcSession) => boolean;
15
+ /** Called once per new RPC connection, right after its session is created. */
16
+ onPeerConnect?: (connection: DevframeRpcConnection, session: DevframeNodeRpcSession) => void;
17
+ /** Called once per closed RPC connection, after the transport's disconnect bookkeeping. */
18
+ onPeerDisconnect?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
19
+ /** Forwarded verbatim to birpc's `rpcOptions` so a host keeps seeing RPC failures. */
20
+ rpcOptions?: Pick<EventOptions<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>, 'onFunctionError' | 'onGeneralError'>;
21
+ }
22
+ interface ContextRpcServer {
23
+ rpcGroup: BirpcGroup<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>;
24
+ /** The resolved auth handler when `auth` was passed as one. */
25
+ authHandler?: DevframeAuthHandler;
26
+ /**
27
+ * Connection lifecycle handlers to wire into a transport binding
28
+ * (`attachWsRpcTransport`'s `onConnected` / `onDisconnected`, or any other
29
+ * crossws adapter's peer hooks via `createWsRpcPeerHooks`).
30
+ */
31
+ onConnected?: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
32
+ onDisconnected: (connection: DevframeRpcConnection, meta: DevframeNodeRpcSessionMeta) => void;
33
+ }
34
+ /**
35
+ * Bind a devframe context's registered RPC functions to a birpc group,
36
+ * transport-agnostically — the shared core under the instance shell's own
37
+ * HTTP+WS binding (Node http + WS) and the Bun fetch-upgrade tier of
38
+ * `createHandler`.
39
+ *
40
+ * Owns everything about serving RPC that is independent of *how* peers
41
+ * connect: the auth handler's function registration, the
42
+ * `AsyncLocalStorage`-based session resolver (so
43
+ * `ctx.rpc.getCurrentRpcSession()` works inside handlers), the
44
+ * `authorize` gate, and the `auth: false` auto-trust handshake shim.
45
+ */
46
+ declare function createContextRpcServer(options: CreateContextRpcServerOptions): ContextRpcServer;
47
+ //#endregion
48
+ export { CreateContextRpcServerOptions as n, createContextRpcServer as r, ContextRpcServer as t };
@@ -0,0 +1,81 @@
1
+ import { n as __exportAll } from "./rolldown-runtime-JspESFgx.mjs";
2
+ import { createRpcServer } from "./rpc/server.mjs";
3
+ import { t as diagnostics } from "./diagnostics-DLYH5oD3.mjs";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
5
+ //#region src/node/rpc-core.ts
6
+ var rpc_core_exports = /* @__PURE__ */ __exportAll({ createContextRpcServer: () => createContextRpcServer });
7
+ /**
8
+ * Bind a devframe context's registered RPC functions to a birpc group,
9
+ * transport-agnostically — the shared core under the instance shell's own
10
+ * HTTP+WS binding (Node http + WS) and the Bun fetch-upgrade tier of
11
+ * `createHandler`.
12
+ *
13
+ * Owns everything about serving RPC that is independent of *how* peers
14
+ * connect: the auth handler's function registration, the
15
+ * `AsyncLocalStorage`-based session resolver (so
16
+ * `ctx.rpc.getCurrentRpcSession()` works inside handlers), the
17
+ * `authorize` gate, and the `auth: false` auto-trust handshake shim.
18
+ */
19
+ function createContextRpcServer(options) {
20
+ const { context } = options;
21
+ const rpcHost = context.rpc;
22
+ const asyncStorage = new AsyncLocalStorage();
23
+ const authHandler = typeof options.auth === "object" ? options.auth : void 0;
24
+ const effectiveAuthorize = options.authorize ?? authHandler?.authorize;
25
+ if (authHandler) {
26
+ for (const fn of authHandler.rpcFunctions) if (!rpcHost.definitions.has(fn.name)) rpcHost.register(fn);
27
+ }
28
+ const rpcGroup = createRpcServer(rpcHost.functions, { rpcOptions: {
29
+ onFunctionError: options.rpcOptions?.onFunctionError,
30
+ onGeneralError: options.rpcOptions?.onGeneralError,
31
+ resolver(name, fn) {
32
+ const rpc = this;
33
+ if (!fn) return void 0;
34
+ return async function(...args) {
35
+ const meta = rpc.$meta;
36
+ if (effectiveAuthorize && !effectiveAuthorize(name, {
37
+ meta,
38
+ rpc
39
+ })) throw diagnostics.DF0036({ name });
40
+ return await asyncStorage.run({
41
+ rpc,
42
+ meta
43
+ }, async () => {
44
+ return (await fn).apply(this, args);
45
+ });
46
+ };
47
+ }
48
+ } });
49
+ rpcHost._rpcGroup = rpcGroup;
50
+ rpcHost._asyncStorage = asyncStorage;
51
+ rpcHost._authDisabled = options.auth === false;
52
+ if (options.auth === false && !rpcHost.definitions.has("anonymous:devframe:auth")) rpcHost.register({
53
+ name: "anonymous:devframe:auth",
54
+ type: "action",
55
+ handler: () => {
56
+ const session = rpcHost.getCurrentRpcSession();
57
+ if (session) session.meta.isTrusted = true;
58
+ return { isTrusted: true };
59
+ }
60
+ });
61
+ const onConnected = authHandler || options.onPeerConnect ? (connection, meta) => {
62
+ const session = {
63
+ meta,
64
+ rpc: rpcGroup.clients.find((client) => client.$meta === meta)
65
+ };
66
+ authHandler?.onConnect(connection, session);
67
+ options.onPeerConnect?.(connection, session);
68
+ } : void 0;
69
+ const onDisconnected = (connection, meta) => {
70
+ options.onPeerDisconnect?.(connection, meta);
71
+ rpcHost._emitSessionDisconnected(meta);
72
+ };
73
+ return {
74
+ rpcGroup,
75
+ authHandler,
76
+ onConnected,
77
+ onDisconnected
78
+ };
79
+ }
80
+ //#endregion
81
+ export { rpc_core_exports as n, createContextRpcServer as t };
@@ -1,7 +1,7 @@
1
1
  import { t as diagnostics } from "./diagnostics-hwjXp_UV.mjs";
2
2
  //#region src/rpc/serialization.ts
3
3
  /**
4
- * Wire format used by the WS RPC transport.
4
+ * Wire format used by the live RPC transports (WebSocket and SSE).
5
5
  *
6
6
  * - **JSON (default, unprefixed):** payload is plain JSON text. Used when
7
7
  * the dispatched method is declared `jsonSerializable: true`. Encoded
@@ -1,6 +1,6 @@
1
1
  import { createEventEmitter } from "./utils/events.mjs";
2
2
  import { nanoid } from "./utils/nanoid.mjs";
3
- //#region ../../node_modules/.pnpm/immer@11.1.15/node_modules/immer/dist/immer.mjs
3
+ //#region ../../node_modules/.pnpm/immer@11.1.16/node_modules/immer/dist/immer.mjs
4
4
  var NOTHING = Symbol.for("immer-nothing");
5
5
  var DRAFTABLE = Symbol.for("immer-draftable");
6
6
  var DRAFT_STATE = Symbol.for("immer-state");
@@ -0,0 +1,37 @@
1
+ import { v as RpcFunctionDefinitionAny } from "./types-CnJSgRVa.mjs";
2
+ import { ChannelOptions } from "birpc";
3
+ //#region src/rpc/transports/sse-client.d.ts
4
+ interface SseRpcChannelOptions {
5
+ /** Resolved `http(s)://` URL of the SSE endpoint. */
6
+ url: string;
7
+ onConnected?: () => void;
8
+ onError?: (e: Error) => void;
9
+ onDisconnected?: () => void;
10
+ authToken?: string;
11
+ /**
12
+ * RPC function definitions (or just the `jsonSerializable` flag per
13
+ * method) used to dispatch the per-call wire serializer — same contract
14
+ * as the WS channel.
15
+ */
16
+ definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
17
+ /** Fetch implementation. Default: `globalThis.fetch`. */
18
+ fetch?: typeof globalThis.fetch;
19
+ }
20
+ /**
21
+ * Build a birpc `ChannelOptions` object backed by an SSE stream (server →
22
+ * client) and HTTP `POST` (client → server) — the WebSocket-free counterpart
23
+ * to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
24
+ *
25
+ * The stream is consumed via `fetch` streaming (not `EventSource`), so it
26
+ * works in browsers and server runtimes alike. The server's first frame
27
+ * (`event: session`) carries the session id; every `POST` echoes it in the
28
+ * `x-birpc-session` header. A response to a client-initiated request comes
29
+ * back in the `POST`'s own body and is re-injected into the channel; a
30
+ * dropped stream terminates the channel — there is no reconnect, matching
31
+ * the WS channel's closed-is-done semantics.
32
+ */
33
+ declare function createSseRpcChannel(options: SseRpcChannelOptions): ChannelOptions & {
34
+ close: () => void;
35
+ };
36
+ //#endregion
37
+ export { createSseRpcChannel as n, SseRpcChannelOptions as t };