devframe 0.9.7 → 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.
Files changed (116) hide show
  1. package/dist/{_shared-BM3PdYli.mjs → _shared-C08SdQRl.mjs} +15 -4
  2. package/dist/{_shared-BJ6AmwTu.d.mts → _shared-CK3czkH4.d.mts} +25 -2
  3. package/dist/adapters/build.d.mts +6 -6
  4. package/dist/adapters/build.mjs +32 -22
  5. package/dist/adapters/cac.d.mts +16 -1
  6. package/dist/adapters/cac.mjs +8 -7
  7. package/dist/adapters/dev.d.mts +13 -13
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +28 -26
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +28 -14
  13. package/dist/adapters/mcp.mjs +75 -39
  14. package/dist/{agent-tool-name-EgfoFO8C.mjs → agent-tool-name-DGzeuWcO.mjs} +2 -2
  15. package/dist/cli/main.d.mts +1 -1
  16. package/dist/cli/main.mjs +41 -17
  17. package/dist/client/index.d.mts +36 -36
  18. package/dist/client/index.mjs +83 -51
  19. package/dist/client-assets-DNdhagGm.mjs +16 -0
  20. package/dist/constants.d.mts +8 -7
  21. package/dist/constants.mjs +7 -6
  22. package/dist/{context-BhBzOXVa.d.mts → context-4AIVRLYF.d.mts} +173 -122
  23. package/dist/{context-omlma_1n.mjs → context-CwPUinjn.mjs} +126 -88
  24. package/dist/{context-KUqAfawQ.mjs → context-DIUvJW4D.mjs} +3 -3
  25. package/dist/{context-HOnG-WvG.d.mts → context-rgBSPFHS.d.mts} +5 -5
  26. package/dist/{crypto-token-XCqTSMg9.mjs → crypto-token-TVbGGFuj.mjs} +1 -1
  27. package/dist/{dev-Czit5IP4.mjs → dev-Eqq5PX0k.mjs} +37 -18
  28. package/dist/{diagnostics-BXWW3VK-.mjs → diagnostics-BMfN8mb1.mjs} +30 -17
  29. package/dist/{diagnostics-CD8nlgll.mjs → diagnostics-D0EVm5M6.mjs} +2 -2
  30. package/dist/{events-4daw0uK9.mjs → events-BV4Dj59a.mjs} +2 -2
  31. package/dist/{host-h3-fRbF9yor.mjs → host-h3-BJ4siyz7.mjs} +1 -1
  32. package/dist/in-page-channel/index.d.mts +59 -22
  33. package/dist/in-page-channel/index.mjs +71 -56
  34. package/dist/{index-BzyopqxV.d.mts → index-pIVt92jP.d.mts} +9 -9
  35. package/dist/{index-DcKxIMoI.d.mts → index-pKl67H6w.d.mts} +4 -4
  36. package/dist/index.d.mts +11 -13
  37. package/dist/index.mjs +6 -7
  38. package/dist/{instance-registry-BjlMQbFB.mjs → instance-registry-C7-41RSp.mjs} +8 -8
  39. package/dist/{instance-shell-Bh4l9Vz_.d.mts → instance-shell-7Z52PE4_.d.mts} +18 -18
  40. package/dist/{instance-shell-CpVW4zG0.mjs → instance-shell-cdVETpfz.mjs} +227 -58
  41. package/dist/internal/index.d.mts +51 -21
  42. package/dist/internal/index.mjs +10 -9
  43. package/dist/node/auth.d.mts +2 -2
  44. package/dist/node/auth.mjs +2 -2
  45. package/dist/node/hub-internals.d.mts +2 -2
  46. package/dist/node/hub-internals.mjs +2 -2
  47. package/dist/node/index.d.mts +5 -5
  48. package/dist/node/index.mjs +2 -2
  49. package/dist/{nostics-SPGDgHEP.d.mts → nostics-0sKe5HIj.d.mts} +2 -2
  50. package/dist/{nostics-CzECRXpE.mjs → nostics-D0PvLZsn.mjs} +1 -1
  51. package/dist/origin-DGDH8BI9.d.mts +45 -0
  52. package/dist/origin-DZit9g29.mjs +80 -0
  53. package/dist/recipes/common-rpc-functions.d.mts +5 -5
  54. package/dist/recipes/common-rpc-functions.mjs +3 -3
  55. package/dist/recipes/interactive-auth.d.mts +6 -6
  56. package/dist/recipes/interactive-auth.mjs +6 -6
  57. package/dist/{remote-assets-DezQmPQU.mjs → remote-assets-BIFWOlBW.mjs} +26 -6
  58. package/dist/{remote-assets-B13_vRkJ.d.mts → remote-assets-eBvSKZMS.d.mts} +7 -7
  59. package/dist/{revoke-COLW0cOi.mjs → revoke-cqztiCX4.mjs} +1 -1
  60. package/dist/rpc/dump.d.mts +2 -11
  61. package/dist/rpc/dump.mjs +1 -1
  62. package/dist/rpc/index.d.mts +2 -2
  63. package/dist/rpc/index.mjs +3 -3
  64. package/dist/rpc/transports/sse-client.d.mts +1 -1
  65. package/dist/rpc/transports/sse-client.mjs +30 -14
  66. package/dist/rpc/transports/sse-server.d.mts +4 -4
  67. package/dist/rpc/transports/sse-server.mjs +7 -7
  68. package/dist/rpc/transports/ws-bun.d.mts +5 -5
  69. package/dist/rpc/transports/ws-bun.mjs +8 -2
  70. package/dist/rpc/transports/ws-client.d.mts +1 -1
  71. package/dist/rpc/transports/ws-client.mjs +2 -2
  72. package/dist/rpc/transports/ws-deno.d.mts +4 -4
  73. package/dist/rpc/transports/ws-deno.mjs +8 -2
  74. package/dist/rpc/transports/ws-server.d.mts +2 -1
  75. package/dist/rpc/transports/ws-server.mjs +232 -1
  76. package/dist/{rpc-core-BHUsDl7s.d.mts → rpc-core-Ceu6AUz8.d.mts} +4 -4
  77. package/dist/{rpc-core-DlHd276T.mjs → rpc-core-DVQ7xi89.mjs} +14 -2
  78. package/dist/{serialization-BGzEwAdr.mjs → serialization-DTZnPQ1-.mjs} +20 -18
  79. package/dist/{services-install-CqqQVls5.mjs → services-install-P_DV7VYL.mjs} +32 -21
  80. package/dist/session-DPfj6zQG.mjs +16 -0
  81. package/dist/{shared-state-DoXutg_U.mjs → shared-state-CaxB1q0h.mjs} +4 -3
  82. package/dist/{simple-schema-DQPZrAaZ.mjs → simple-schema-Bi40l-P6.mjs} +2 -2
  83. package/dist/{sse-client-DwX021ST.d.mts → sse-client-BQ4jS3eO.d.mts} +4 -4
  84. package/dist/{state-CK9LjrnT.mjs → state-CeQQWzM-.mjs} +4 -4
  85. package/dist/{static-DV_qUSRS.mjs → static-DZ8P2Kn7.mjs} +130 -135
  86. package/dist/{storage-BXNVhKyR.mjs → storage-Dccf_IyD.mjs} +1 -1
  87. package/dist/types/index.d.mts +6 -6
  88. package/dist/{types-CMdPYhOx.d.mts → types-Dq4i156u.d.mts} +17 -17
  89. package/dist/utils/agent-tool-name.d.mts +2 -2
  90. package/dist/utils/agent-tool-name.mjs +2 -2
  91. package/dist/utils/colors.d.mts +1 -1
  92. package/dist/utils/crypto-token.d.mts +1 -1
  93. package/dist/utils/crypto-token.mjs +1 -1
  94. package/dist/utils/events.d.mts +1 -1
  95. package/dist/utils/nostics.d.mts +1 -1
  96. package/dist/utils/nostics.mjs +1 -1
  97. package/dist/utils/open.mjs +1 -1
  98. package/dist/utils/origin.d.mts +2 -0
  99. package/dist/utils/origin.mjs +80 -0
  100. package/dist/utils/remote-assets.d.mts +2 -2
  101. package/dist/utils/remote-assets.mjs +1 -1
  102. package/dist/utils/serve-static.d.mts +4 -4
  103. package/dist/utils/serve-static.mjs +56 -19
  104. package/dist/utils/shared-state.d.mts +1 -1
  105. package/dist/utils/shared-state.mjs +1 -1
  106. package/dist/utils/simple-schema.d.mts +5 -5
  107. package/dist/utils/simple-schema.mjs +2 -2
  108. package/dist/utils/streaming-channel.d.mts +1 -1
  109. package/dist/utils/streaming-channel.mjs +2 -2
  110. package/dist/utils/when.d.mts +5 -5
  111. package/dist/{validation-YrZH6atx.mjs → validation-BOy8IoFZ.mjs} +2 -2
  112. package/dist/{wire-codec-0K-o5MYW.mjs → wire-codec-dcCeXcSo.mjs} +3 -3
  113. package/dist/{ws-client-7_lZi-B9.d.mts → ws-client-Xpxt0oPA.d.mts} +3 -3
  114. package/dist/{ws-server-Di2oqr4q.d.mts → ws-server-D2nv68Hg.d.mts} +13 -22
  115. package/package.json +6 -5
  116. package/dist/ws-server-BdSLrhxE.mjs +0 -267
@@ -1,267 +0,0 @@
1
- import "./constants.mjs";
2
- import { t as createRpcWireCodec } from "./wire-codec-0K-o5MYW.mjs";
3
- import { n as randomToken, r as timingSafeEqual } from "./crypto-token-XCqTSMg9.mjs";
4
- import { createServer } from "node:http";
5
- import { createServer as createServer$1 } from "node:https";
6
- import crossws from "crossws/adapters/node";
7
- //#region src/rpc/transports/session.ts
8
- let sessionId = 0;
9
- /**
10
- * Mint the per-connection session meta every transport binding shares —
11
- * one id space across transports, so session bookkeeping (streaming
12
- * subscriptions, shared-state sync, auth trust) never collides between a
13
- * WS peer and an SSE session on the same server.
14
- */
15
- function createRpcSessionMeta() {
16
- return {
17
- id: sessionId++,
18
- subscribedStates: /* @__PURE__ */ new Set()
19
- };
20
- }
21
- //#endregion
22
- //#region src/rpc/transports/ws-server.ts
23
- /**
24
- * Create a live, token-protected origin allowlist for external browser
25
- * viewers. Pass it to {@link WsRpcTransportOptions.allowedOrigins}, then use
26
- * `registerFromUrl()` in the connection metadata handler to authorize a
27
- * viewer without sharing a mutable array or disabling DNS-rebinding protection.
28
- */
29
- function createWsOriginRegistry(options = {}) {
30
- const token = randomToken();
31
- const origins = new Set(options.allowedOrigins ?? []);
32
- function normalizeOrigin(origin) {
33
- if (!origin) return;
34
- try {
35
- const url = new URL(origin);
36
- const normalized = url.origin === "null" ? `${url.protocol}//${url.host}` : url.origin;
37
- return origin === normalized ? normalized : void 0;
38
- } catch {}
39
- }
40
- function registerOrigin(origin, candidateToken) {
41
- const normalized = normalizeOrigin(origin);
42
- if (!normalized || !candidateToken || !timingSafeEqual(token, candidateToken)) return false;
43
- if (options.validateOrigin && !options.validateOrigin(normalized)) return false;
44
- origins.add(normalized);
45
- return true;
46
- }
47
- return {
48
- token,
49
- registerFromUrl(url) {
50
- let parsed;
51
- try {
52
- parsed = new URL(url, "http://localhost");
53
- } catch {
54
- return;
55
- }
56
- const origin = parsed.searchParams.get("devframe_viewer_origin") ?? void 0;
57
- return registerOrigin(origin, parsed.searchParams.get("devframe_viewer_origin_token") ?? void 0) ? origin : void 0;
58
- },
59
- isAllowed(origin) {
60
- return isAllowedOrigin(origin, [...origins]);
61
- }
62
- };
63
- }
64
- const EMPTY_DEFS = /* @__PURE__ */ new Map();
65
- function NOOP() {}
66
- function listen(server, port, host) {
67
- return new Promise((resolve, reject) => {
68
- const onError = (error) => reject(error);
69
- server.once("error", onError);
70
- try {
71
- server.listen(port, host, () => {
72
- server.off("error", onError);
73
- resolve();
74
- });
75
- } catch (error) {
76
- server.off("error", onError);
77
- reject(error);
78
- }
79
- });
80
- }
81
- /** Compare two URL paths ignoring a trailing slash. */
82
- function pathMatches(a, b) {
83
- const strip = (p) => p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
84
- return strip(a) === strip(b);
85
- }
86
- function isLoopbackHostname(hostname) {
87
- const h = hostname.replace(/^\[|\]$/g, "");
88
- return h === "localhost" || h === "127.0.0.1" || h === "::1" || h.endsWith(".localhost") || h.startsWith("127.");
89
- }
90
- /**
91
- * Default origin policy for a localhost dev tool: allow requests with no
92
- * `Origin` header (native, non-browser clients), allow any loopback origin
93
- * (so cross-port localhost dev setups keep working), and allow explicitly
94
- * configured origins. Everything else — a real remote page in the dev's
95
- * browser — is rejected.
96
- */
97
- function isAllowedOrigin(origin, allowedOrigins) {
98
- if (!origin) return true;
99
- if (allowedOrigins.includes(origin)) return true;
100
- try {
101
- return isLoopbackHostname(new URL(origin).hostname);
102
- } catch {
103
- return false;
104
- }
105
- }
106
- function isWsOriginRegistry(value) {
107
- return !!value && !Array.isArray(value);
108
- }
109
- /**
110
- * Build the `upgrade` listener that hands a request to the crossws adapter,
111
- * optionally filtered to a single `path`. Non-matching requests are left
112
- * untouched so other upgrade listeners (e.g. a Vite dev server's HMR socket)
113
- * can claim them, unless `destroyUnmatched` is set.
114
- */
115
- function createUpgradeListener(ws, path, destroyUnmatched, allowedOrigins) {
116
- return (req, socket, head) => {
117
- socket.on("error", () => {});
118
- if (path) {
119
- let pathname = req.url ?? "/";
120
- try {
121
- pathname = new URL(req.url ?? "/", "http://localhost").pathname;
122
- } catch {}
123
- if (!pathMatches(pathname, path)) {
124
- if (destroyUnmatched) {
125
- socket.write("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n");
126
- socket.destroy();
127
- }
128
- return;
129
- }
130
- }
131
- const originAllowed = isWsOriginRegistry(allowedOrigins) ? allowedOrigins.isAllowed(req.headers.origin) : isAllowedOrigin(req.headers.origin, allowedOrigins || []);
132
- if (allowedOrigins !== false && !originAllowed) {
133
- socket.write("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
134
- socket.destroy();
135
- return;
136
- }
137
- ws.handleUpgrade(req, socket, head);
138
- };
139
- }
140
- /**
141
- * The per-peer lifecycle hooks driving a devframe RPC WebSocket, shaped for
142
- * any [crossws](https://crossws.h3.dev) adapter. {@link attachWsRpcTransport}
143
- * feeds them to the Node adapter; runtime-specific attachments (e.g. Bun's
144
- * fetch-upgrade adapter) reuse the same hooks so every transport speaks the
145
- * identical wire protocol — one birpc channel per peer, per-method
146
- * `jsonSerializable` dispatch between strict JSON and structured-clone.
147
- */
148
- function createWsRpcPeerHooks(rpcGroup, options = {}) {
149
- const { onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
150
- const states = /* @__PURE__ */ new WeakMap();
151
- return {
152
- open: (peer) => {
153
- const meta = createRpcSessionMeta();
154
- meta.peer = peer;
155
- const connection = {
156
- id: meta.id,
157
- transport: "websocket",
158
- request: peer.request,
159
- send: (data) => peer.send(data),
160
- close: (code, reason) => peer.close(code, reason),
161
- peer
162
- };
163
- const codec = createRpcWireCodec(definitions);
164
- const state = {
165
- meta,
166
- connection,
167
- channel: void 0
168
- };
169
- const channel = {
170
- post: (data) => {
171
- peer.send(data);
172
- },
173
- on: (fn) => {
174
- state.onMessage = fn;
175
- },
176
- serialize: serializeOverride ?? codec.serialize,
177
- deserialize: deserializeOverride ?? codec.deserialize,
178
- meta
179
- };
180
- state.channel = channel;
181
- states.set(peer, state);
182
- rpcGroup.updateChannels((channels) => {
183
- channels.push(channel);
184
- });
185
- onConnected(connection, meta);
186
- },
187
- message: (peer, message) => {
188
- states.get(peer)?.onMessage?.(message.text());
189
- },
190
- close: (peer) => {
191
- const state = states.get(peer);
192
- if (!state) return;
193
- states.delete(peer);
194
- rpcGroup.updateChannels((channels) => {
195
- const index = channels.indexOf(state.channel);
196
- if (index >= 0) channels.splice(index, 1);
197
- });
198
- onDisconnected(state.connection, state.meta);
199
- }
200
- };
201
- }
202
- /**
203
- * Attach a WebSocket transport to an existing RPC group, powered by
204
- * [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
205
- * `server` (sharing its port, optionally scoped to a `path`), or let this
206
- * helper create a standalone server from `port` / `host` / `https`.
207
- *
208
- * Returns the crossws node adapter, standalone-server readiness/address
209
- * accessors, `detach` (remove the upgrade listener from a shared `server`),
210
- * and `close` (full deterministic teardown).
211
- */
212
- function attachWsRpcTransport(rpcGroup, options = {}) {
213
- const { server, port, host = "localhost", path, destroyUnmatched = false, unbound, https, allowedOrigins } = options;
214
- const ws = crossws({ hooks: createWsRpcPeerHooks(rpcGroup, options) });
215
- const sharedUpgradeListener = createUpgradeListener(ws, path, destroyUnmatched, allowedOrigins);
216
- const ownedUpgradeListener = createUpgradeListener(ws, path, true, allowedOrigins);
217
- /** Bind a server's `upgrade` events, tracked so `close()` detaches them. */
218
- const attachments = /* @__PURE__ */ new Set();
219
- function attachTo(target, listener) {
220
- target.on("upgrade", listener);
221
- const detachOne = () => {
222
- target.off("upgrade", listener);
223
- attachments.delete(detachOne);
224
- };
225
- attachments.add(detachOne);
226
- return detachOne;
227
- }
228
- let ready = Promise.resolve();
229
- let ownedServer;
230
- if (unbound) {} else if (server) attachTo(server, sharedUpgradeListener);
231
- else if (https) {
232
- ownedServer = createServer$1(https);
233
- attachTo(ownedServer, ownedUpgradeListener);
234
- ready = listen(ownedServer, port ?? 0, host);
235
- } else {
236
- ownedServer = createServer((_req, res) => {
237
- res.writeHead(426, { "content-type": "text/plain" });
238
- res.end("Upgrade Required");
239
- });
240
- attachTo(ownedServer, ownedUpgradeListener);
241
- ready = listen(ownedServer, port ?? 0, host);
242
- }
243
- const activeServer = server ?? ownedServer;
244
- function detachAll() {
245
- for (const detachOne of [...attachments]) detachOne();
246
- }
247
- return {
248
- ws,
249
- ready,
250
- address: () => activeServer?.address() ?? null,
251
- handleUpgrade: sharedUpgradeListener,
252
- attach: (target) => attachTo(target, sharedUpgradeListener),
253
- detach: detachAll,
254
- async close() {
255
- detachAll();
256
- ws.closeAll(void 0, void 0, true);
257
- if (ownedServer) {
258
- const srv = ownedServer;
259
- await ready.catch(() => {});
260
- if (!srv.listening) return;
261
- await new Promise((r) => srv.close(() => r()));
262
- }
263
- }
264
- };
265
- }
266
- //#endregion
267
- export { isLoopbackHostname as a, isAllowedOrigin as i, createWsOriginRegistry as n, createRpcSessionMeta as o, createWsRpcPeerHooks as r, attachWsRpcTransport as t };