devframe 0.9.8 → 0.9.10
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-CCzf9Hub.d.mts +83 -0
- package/dist/_shared-U8D-xzrp.mjs +115 -0
- package/dist/adapters/build.d.mts +6 -6
- package/dist/adapters/build.mjs +33 -36
- package/dist/adapters/cac.d.mts +12 -1
- package/dist/adapters/cac.mjs +8 -8
- package/dist/adapters/dev.d.mts +17 -17
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +31 -28
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +28 -14
- package/dist/adapters/mcp.mjs +76 -40
- 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 +90 -52
- 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-omlma_1n.mjs → context-B29Oh0oA.mjs} +166 -93
- package/dist/{context-DftYyXaR.d.mts → context-BJiKJqyW.d.mts} +5 -5
- package/dist/{context-CLF4-8Pp.d.mts → context-CHW4BZOj.d.mts} +203 -134
- package/dist/{context-KUqAfawQ.mjs → context-jXO5vzjH.mjs} +3 -3
- package/dist/{crypto-token-XCqTSMg9.mjs → crypto-token-TVbGGFuj.mjs} +1 -1
- package/dist/{dev-CzkPCJwi.mjs → dev-CRYHx7iG.mjs} +73 -40
- package/dist/{diagnostics-BXWW3VK-.mjs → diagnostics-DZA6KQ_Z.mjs} +32 -19
- package/dist/{events-4daw0uK9.mjs → events-BV4Dj59a.mjs} +2 -2
- package/dist/{services-install-CqqQVls5.mjs → host-agent-CKqSTEX9.mjs} +15 -151
- package/dist/{host-h3-fRbF9yor.mjs → host-h3-BROI6SQ4.mjs} +2 -2
- package/dist/in-page-channel/index.d.mts +14 -14
- package/dist/in-page-channel/index.mjs +63 -54
- package/dist/{index-D3k0BIhe.d.mts → index-CNC390b_.d.mts} +4 -4
- package/dist/{index-BzyopqxV.d.mts → index-pIVt92jP.d.mts} +9 -9
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +2 -2
- package/dist/{instance-registry-BjlMQbFB.mjs → instance-registry-DCq762YJ.mjs} +9 -9
- package/dist/{instance-shell-Tcp5hGoq.d.mts → instance-shell-DZipaP9k.d.mts} +18 -18
- package/dist/{instance-shell-CpVW4zG0.mjs → instance-shell-DvYCwrDy.mjs} +223 -67
- package/dist/internal/index.d.mts +45 -26
- 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-DMFzLSoH.mjs} +27 -7
- 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 +19 -12
- package/dist/rpc/dump.mjs +2 -2
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +2 -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-DlHd276T.mjs → rpc-core-CvkU23bQ.mjs} +14 -2
- package/dist/{rpc-core-B3W3z9ff.d.mts → rpc-core-DsyDViQy.d.mts} +4 -4
- package/dist/serialization-DFg5sUt6.mjs +116 -0
- package/dist/services-install-Ben4yh52.mjs +154 -0
- 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-Mwt6--el.mjs} +17 -9
- package/dist/{storage-BXNVhKyR.mjs → storage-B70AXK64.mjs} +2 -2
- 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-CfV1s0SF.mjs} +2 -2
- package/dist/{wire-codec-0K-o5MYW.mjs → wire-codec-BHGt0sSs.mjs} +3 -3
- package/dist/{static-DV_qUSRS.mjs → write-BuLCrn9h.mjs} +153 -137
- 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 +3 -6
- package/skills/devframe/SKILL.md +5 -3
- package/dist/_shared-BM3PdYli.mjs +0 -68
- package/dist/_shared-mtXpcJIv.d.mts +0 -41
- package/dist/diagnostics-CD8nlgll.mjs +0 -39
- package/dist/serialization-BGzEwAdr.mjs +0 -77
- package/dist/ws-server-Y_AumUQH.mjs +0 -294
package/dist/client/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-
|
|
2
|
-
import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-
|
|
3
|
-
import { Q as
|
|
4
|
-
import { t as SseRpcChannelOptions } from "../sse-client-
|
|
5
|
-
import { t as WsRpcChannelOptions } from "../ws-client-
|
|
1
|
+
import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-pIVt92jP.mjs";
|
|
2
|
+
import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-Dq4i156u.mjs";
|
|
3
|
+
import { Q as DevframeServiceMeta, Vt as EventEmitter, b as StreamSink, ct as DevframeSettings, d as RpcSharedStateHost, et as DevframeServiceScopeOf, gt as SettingsForNamespace, ht as ScopedSharedStates, it as DevframeServicesState, k as SharedState, mt as ScopedServerFunctions, pt as ScopedRpcFn, t as ConnectionMeta, u as RpcSharedStateGetOptions, vt as DevframeRpcClientFunctions, y as StreamReader, yt as DevframeRpcServerFunctions } from "../context-CHW4BZOj.mjs";
|
|
4
|
+
import { t as SseRpcChannelOptions } from "../sse-client-BQ4jS3eO.mjs";
|
|
5
|
+
import { t as WsRpcChannelOptions } from "../ws-client-Xpxt0oPA.mjs";
|
|
6
6
|
import { BirpcOptions, BirpcReturn } from "birpc";
|
|
7
7
|
//#region src/client/connection.d.ts
|
|
8
8
|
interface DevframeConnection {
|
|
@@ -50,15 +50,15 @@ declare function setupDevframeConnection(options?: SetupDevframeConnectionOption
|
|
|
50
50
|
* trust handshake, so a viewer never has to reason about the two dimensions
|
|
51
51
|
* separately.
|
|
52
52
|
*
|
|
53
|
-
* - `connecting
|
|
53
|
+
* - `connecting`: establishing the WebSocket / running the initial trust
|
|
54
54
|
* handshake. Calls issued here queue until the socket opens.
|
|
55
|
-
* - `connected
|
|
56
|
-
* - `unauthorized
|
|
55
|
+
* - `connected`: socket open and trusted; RPC calls will be served.
|
|
56
|
+
* - `unauthorized`: socket open but the server rejected trust (no valid token,
|
|
57
57
|
* or an auth-enforcing host refused it). Calls fail fast with an auth error;
|
|
58
58
|
* the UI should prompt for re-authentication or a reload.
|
|
59
|
-
* - `disconnected
|
|
59
|
+
* - `disconnected`: the socket closed (dropped mid-session, or never opened).
|
|
60
60
|
* Pending and new calls fail fast until the page reconnects.
|
|
61
|
-
* - `error
|
|
61
|
+
* - `error`: a fatal connection error (e.g. the WebSocket errored, or the
|
|
62
62
|
* connection meta could not be loaded).
|
|
63
63
|
*
|
|
64
64
|
* A `static` backend has no live socket, so it reports `connected` for its
|
|
@@ -67,9 +67,9 @@ declare function setupDevframeConnection(options?: SetupDevframeConnectionOption
|
|
|
67
67
|
type DevframeConnectionStatus = 'connecting' | 'connected' | 'unauthorized' | 'disconnected' | 'error';
|
|
68
68
|
/**
|
|
69
69
|
* What kind of failure a {@link DevframeConnectionError} describes:
|
|
70
|
-
* - `connection
|
|
71
|
-
* - `auth
|
|
72
|
-
* - `timeout
|
|
70
|
+
* - `connection`: the transport dropped, errored, or never opened.
|
|
71
|
+
* - `auth`: the server rejected trust for this client.
|
|
72
|
+
* - `timeout`: a call exceeded its {@link DevframeRpcClientOptions.callTimeout}.
|
|
73
73
|
*/
|
|
74
74
|
type DevframeConnectionErrorKind = 'connection' | 'auth' | 'timeout';
|
|
75
75
|
/**
|
|
@@ -199,7 +199,7 @@ declare function createScopedClientContext<NS extends string = string>(rpc: Devf
|
|
|
199
199
|
//#endregion
|
|
200
200
|
//#region src/client/rpc-services.d.ts
|
|
201
201
|
/**
|
|
202
|
-
* A typed handle on one advertised wire service
|
|
202
|
+
* A typed handle on one advertised wire service: the service's
|
|
203
203
|
* advertisement meta plus an RPC surface scoped to its namespace, so
|
|
204
204
|
* `handle.rpc.call('fn-name', …)` targets `<scope>:fn-name`. Service
|
|
205
205
|
* packages type the calls by augmenting `DevframeRpcServerFunctions` with
|
|
@@ -214,7 +214,7 @@ interface DevframeServiceClientHandle<NS extends string = string> extends Devfra
|
|
|
214
214
|
/**
|
|
215
215
|
* Client-side view of the server's wire-service registry, mirrored through
|
|
216
216
|
* the reactive `devframe:services` shared state. The accessors are
|
|
217
|
-
* synchronous snapshots
|
|
217
|
+
* synchronous snapshots; before the first sync lands (or on a server with
|
|
218
218
|
* no services) they read as empty. For reactive UI (e.g. hiding an
|
|
219
219
|
* "open in editor" button until the service appears), subscribe to the
|
|
220
220
|
* shared state itself via {@link DevframeServicesClient.state}.
|
|
@@ -223,14 +223,14 @@ interface DevframeServicesClient {
|
|
|
223
223
|
/** Whether the service package is advertised as installed. */
|
|
224
224
|
has: (pkg: string) => boolean;
|
|
225
225
|
/**
|
|
226
|
-
* A typed handle on an advertised service
|
|
227
|
-
* surface
|
|
226
|
+
* A typed handle on an advertised service (its meta plus a scoped RPC
|
|
227
|
+
* surface), or `undefined` while it isn't available (never throws).
|
|
228
228
|
*/
|
|
229
229
|
get: <PKG extends string>(pkg: PKG) => DevframeServiceClientHandle<DevframeServiceScopeOf<PKG>> | undefined;
|
|
230
230
|
/** Package names of every advertised service. */
|
|
231
231
|
keys: () => string[];
|
|
232
232
|
/**
|
|
233
|
-
* The mirrored `devframe:services` shared state
|
|
233
|
+
* The mirrored `devframe:services` shared state; subscribe to its
|
|
234
234
|
* `updated` event for reactivity.
|
|
235
235
|
*/
|
|
236
236
|
state: () => Promise<SharedState<DevframeServicesState>>;
|
|
@@ -257,7 +257,7 @@ interface RpcClientEvents {
|
|
|
257
257
|
*/
|
|
258
258
|
'connection:error': (error: Error) => void;
|
|
259
259
|
/**
|
|
260
|
-
* An RPC call rejected
|
|
260
|
+
* An RPC call rejected, either from the server, or because the connection
|
|
261
261
|
* was down / timed out. Useful for a global error feed or toast surface.
|
|
262
262
|
*/
|
|
263
263
|
'rpc:error': (error: Error, method: string) => void;
|
|
@@ -271,7 +271,7 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
|
|
|
271
271
|
* Query-param name on the page URL carrying a one-time authentication code
|
|
272
272
|
* (OTP) for "magic link" auth (e.g. a link the dev server prints). When
|
|
273
273
|
* present, the client exchanges the code for a token and removes the parameter
|
|
274
|
-
* from the URL. Set `false` to disable
|
|
274
|
+
* from the URL. Set `false` to disable, e.g. integrations that drive their
|
|
275
275
|
* own authentication via `authenticateWithUrlOtp`.
|
|
276
276
|
*
|
|
277
277
|
* @default 'devframe_otp'
|
|
@@ -281,7 +281,7 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
|
|
|
281
281
|
* Fall back to a native browser `prompt()` for the one-time authentication
|
|
282
282
|
* code when the server refuses trust and no other credential succeeds (a
|
|
283
283
|
* stored token, an injected token, or a magic-link OTP). The prompt fires
|
|
284
|
-
* only on a **top-level, unframed** page
|
|
284
|
+
* only on a **top-level, unframed** page; a framed plugin (e.g. mounted in
|
|
285
285
|
* a hub dock) never prompts, since a hub pre-authorizes it and browsers
|
|
286
286
|
* block `prompt()` in cross-origin frames anyway.
|
|
287
287
|
*
|
|
@@ -294,20 +294,20 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
|
|
|
294
294
|
/**
|
|
295
295
|
* Which live transport to connect over:
|
|
296
296
|
*
|
|
297
|
-
* - `'auto'` (default)
|
|
297
|
+
* - `'auto'` (default) trusts the server's advertisement: its declared
|
|
298
298
|
* primary (`backend`), preferring the WebSocket when both endpoints are
|
|
299
299
|
* present. A server that couldn't bind a socket advertises SSE as its
|
|
300
300
|
* primary, so no client-side fallback probing is needed.
|
|
301
|
-
* - `'websocket'` / `'sse'`
|
|
301
|
+
* - `'websocket'` / `'sse'` pins one transport; connecting fails with a
|
|
302
302
|
* clear error when the server doesn't advertise it. Reach for
|
|
303
|
-
* `transport: 'sse'` when an intermediary silently strips WS upgrades
|
|
303
|
+
* `transport: 'sse'` when an intermediary silently strips WS upgrades,
|
|
304
304
|
* something the server cannot detect.
|
|
305
305
|
*
|
|
306
306
|
* A `static` backend ignores this option (there is no live transport).
|
|
307
307
|
*/
|
|
308
308
|
transport?: 'auto' | 'websocket' | 'sse';
|
|
309
309
|
wsOptions?: Partial<WsRpcChannelOptions>;
|
|
310
|
-
/** Channel overrides for the SSE transport
|
|
310
|
+
/** Channel overrides for the SSE transport, the `wsOptions` counterpart. */
|
|
311
311
|
sseOptions?: Partial<SseRpcChannelOptions>;
|
|
312
312
|
rpcOptions?: Partial<BirpcOptions<DevframeRpcServerFunctions, DevframeRpcClientFunctions, boolean>>;
|
|
313
313
|
cacheOptions?: boolean | Partial<RpcCacheOptions>;
|
|
@@ -315,8 +315,8 @@ interface DevframeRpcClientOptions extends SetupDevframeConnectionOptions {
|
|
|
315
315
|
* Reject a pending `rpc.call(...)` if the server hasn't answered within this
|
|
316
316
|
* many milliseconds, with a {@link DevframeConnectionError} of kind
|
|
317
317
|
* `'timeout'`. Guards against a live-but-unresponsive server hanging the UI.
|
|
318
|
-
* Omit (or `0`) to wait indefinitely. Calls always fail fast
|
|
319
|
-
* this option
|
|
318
|
+
* Omit (or `0`) to wait indefinitely. Calls always fail fast, regardless of
|
|
319
|
+
* this option, once the socket closes or trust is refused.
|
|
320
320
|
*/
|
|
321
321
|
callTimeout?: number;
|
|
322
322
|
}
|
|
@@ -344,7 +344,7 @@ interface DevframeRpcClient {
|
|
|
344
344
|
*/
|
|
345
345
|
readonly connectionError: Error | null;
|
|
346
346
|
/**
|
|
347
|
-
* The transport this client is actually connected over
|
|
347
|
+
* The transport this client is actually connected over: `'websocket'`,
|
|
348
348
|
* `'sse'`, or `'static'`. Reflects the resolution of the `transport`
|
|
349
349
|
* option against the server's advertisement.
|
|
350
350
|
*/
|
|
@@ -404,7 +404,7 @@ interface DevframeRpcClient {
|
|
|
404
404
|
sharedState: RpcSharedStateHost;
|
|
405
405
|
/**
|
|
406
406
|
* The server's advertised wire services (mirrored `devframe:services`
|
|
407
|
-
* shared state)
|
|
407
|
+
* shared state); feature-detect a capability with
|
|
408
408
|
* `rpc.services.has('@devframes/service-x')` and get a scoped, typed RPC
|
|
409
409
|
* handle with `rpc.services.get(...)`. See {@link DevframeServicesClient}.
|
|
410
410
|
*/
|
|
@@ -437,11 +437,11 @@ interface DevframeRpcClient {
|
|
|
437
437
|
* a `websocket` backend closes the underlying `WebSocket`, which the server observes as a
|
|
438
438
|
* normal disconnect. Mirrors {@link WsRpcTransport.close} on the server side.
|
|
439
439
|
*
|
|
440
|
-
* There is no corresponding "reconnect"
|
|
440
|
+
* There is no corresponding "reconnect"; a closed client is done. Discard it and call
|
|
441
441
|
* {@link getDevframeRpcClient} again to reconnect.
|
|
442
442
|
*
|
|
443
|
-
* Optional so a `DevframeRpcClientMode` implemented before this method existed
|
|
444
|
-
* transport, a hand-typed mock
|
|
443
|
+
* Optional so a `DevframeRpcClientMode` implemented before this method existed (a custom
|
|
444
|
+
* transport, a hand-typed mock) still satisfies the interface; an absent `close` is treated
|
|
445
445
|
* as nothing to close.
|
|
446
446
|
*/
|
|
447
447
|
close?: () => void;
|
|
@@ -449,7 +449,7 @@ interface DevframeRpcClient {
|
|
|
449
449
|
interface DevframeRpcClientMode {
|
|
450
450
|
/**
|
|
451
451
|
* The transport this mode speaks. Optional so a mode implemented before
|
|
452
|
-
* this field existed
|
|
452
|
+
* this field existed (a custom transport, a hand-typed mock) still
|
|
453
453
|
* satisfies the interface; an absent value reads as `'websocket'`.
|
|
454
454
|
*/
|
|
455
455
|
readonly transport?: 'websocket' | 'sse' | 'static';
|
|
@@ -472,7 +472,7 @@ interface DevframeRpcClientMode {
|
|
|
472
472
|
}
|
|
473
473
|
/**
|
|
474
474
|
* Resolve the requested `transport` option against what the server
|
|
475
|
-
* advertises. `'auto'` trusts the advertisement
|
|
475
|
+
* advertises. `'auto'` trusts the advertisement: the server's declared
|
|
476
476
|
* primary (`backend`), preferring the WebSocket when both endpoints are
|
|
477
477
|
* present; an explicit `'websocket'` / `'sse'` pins that transport and
|
|
478
478
|
* throws when the server doesn't advertise it.
|
|
@@ -502,7 +502,7 @@ declare function consumeOtpFromUrl(param?: string): string | undefined;
|
|
|
502
502
|
*
|
|
503
503
|
* Higher-level integrations (e.g. Vite DevTools) that want to drive their own
|
|
504
504
|
* authentication UI can disable `connectDevframe`'s built-in handling with
|
|
505
|
-
* `otpParam: false` and call this
|
|
505
|
+
* `otpParam: false` and call this (or {@link consumeOtpFromUrl}) themselves.
|
|
506
506
|
*/
|
|
507
507
|
declare function authenticateWithUrlOtp(rpc: Pick<DevframeRpcClient, 'isTrusted' | 'requestTrustWithCode'>, options?: {
|
|
508
508
|
param?: string;
|
|
@@ -523,7 +523,7 @@ interface WsUrlLocation {
|
|
|
523
523
|
* The object / relative-path forms connect to the page's own origin (only the
|
|
524
524
|
* `http`→`ws` protocol swap is applied), resolving the path against where
|
|
525
525
|
* `__connection.json` was loaded. This is deliberately host-agnostic so the
|
|
526
|
-
* connection survives a reverse proxy that changes the domain or port
|
|
526
|
+
* connection survives a reverse proxy that changes the domain or port, since the
|
|
527
527
|
* client trusts its own location, never a server-baked hostname. An explicit
|
|
528
528
|
* `port`/`host` (or a full `ws(s)://` URL string) opts into a cross-origin
|
|
529
529
|
* endpoint, e.g. a side-car server on its own port.
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as DEVFRAME_EVENTS } from "../events-
|
|
1
|
+
import { t as DEVFRAME_EVENTS } from "../events-BV4Dj59a.mjs";
|
|
2
2
|
import { t as hash } from "../hash-DdPnc4k3.mjs";
|
|
3
3
|
import { colors } from "../utils/colors.mjs";
|
|
4
4
|
import { createEventEmitter } from "../utils/events.mjs";
|
|
5
|
-
import { t as createSharedState } from "../shared-state
|
|
5
|
+
import { t as createSharedState } from "../shared-state-CaxB1q0h.mjs";
|
|
6
6
|
import { i as structuredCloneStringify, n as structuredCloneParse, t as structuredCloneDeserialize } from "../structured-clone-CgtQ61SA.mjs";
|
|
7
7
|
import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
|
|
8
8
|
import { defineDiagnostics } from "nostics";
|
|
@@ -10,6 +10,7 @@ import { ansiFormatter } from "nostics/formatters/ansi";
|
|
|
10
10
|
import { withBase, withProtocol } from "ufo";
|
|
11
11
|
import { createBirpc } from "birpc";
|
|
12
12
|
//#region src/constants.ts
|
|
13
|
+
/** Devframe runtime routes and static output conventions. */
|
|
13
14
|
const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
|
|
14
15
|
/**
|
|
15
16
|
* Global key holding the serializable connection prepared by
|
|
@@ -110,7 +111,7 @@ function devframeReporter(d, { method = "warn" } = {}) {
|
|
|
110
111
|
* ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
|
|
111
112
|
* `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
|
|
112
113
|
* and the built-in plugins defines its codes through this instead of
|
|
113
|
-
* `nostics`'s own `defineDiagnostics
|
|
114
|
+
* `nostics`'s own `defineDiagnostics`; the reporter registration lives
|
|
114
115
|
* here, once, so none of them need to build their own reporter (`colors`,
|
|
115
116
|
* `ansiFormatter`) or take a direct dependency on `nostics` themselves.
|
|
116
117
|
*/
|
|
@@ -126,7 +127,7 @@ const diagnostics = defineDiagnostics$1({
|
|
|
126
127
|
docsBase: "https://devfra.me/errors",
|
|
127
128
|
codes: {
|
|
128
129
|
DF0019: {
|
|
129
|
-
why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true
|
|
130
|
+
why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\`; MCP requires JSON-serializable data.`,
|
|
130
131
|
fix: "Set `jsonSerializable: true` if the payload is JSON-safe, or remove `agent` to keep it RPC-only."
|
|
131
132
|
},
|
|
132
133
|
DF0020: {
|
|
@@ -207,7 +208,7 @@ async function validateRpcArgs(name, argsSchema, args) {
|
|
|
207
208
|
/**
|
|
208
209
|
* Validate a handler's resolved return value against its declared schema.
|
|
209
210
|
* Throws `DF0039` when the value fails the schema, otherwise returns the
|
|
210
|
-
* original value unchanged (guard-only, never rewriting the payload
|
|
211
|
+
* original value unchanged (guard-only, never rewriting the payload; see
|
|
211
212
|
* {@link validateRpcArgs}). Passes through when no return schema is set.
|
|
212
213
|
*
|
|
213
214
|
* @internal
|
|
@@ -350,16 +351,16 @@ function assertAgentJsonSerializable(fn) {
|
|
|
350
351
|
* instances, or `undefined` inside an array (silently becomes `null`).
|
|
351
352
|
*
|
|
352
353
|
* Native pass-throughs (no extra work needed):
|
|
353
|
-
* - circular references
|
|
354
|
-
* - `BigInt` at top level
|
|
354
|
+
* - circular references: `JSON.stringify` raises `TypeError`.
|
|
355
|
+
* - `BigInt` at top level: caught here for a friendlier error path.
|
|
355
356
|
*
|
|
356
357
|
* Lenient cases (allowed without throwing):
|
|
357
|
-
* - `undefined` as an object property
|
|
358
|
+
* - `undefined` as an object property: legitimate optional field;
|
|
358
359
|
* JSON.stringify just omits it.
|
|
359
|
-
* - `undefined` at the root
|
|
360
|
-
* - `Symbol` / `Function` values
|
|
360
|
+
* - `undefined` at the root: legitimate "action returned nothing".
|
|
361
|
+
* - `Symbol` / `Function` values: semantically "drop me" in JSON.
|
|
361
362
|
*
|
|
362
|
-
* `fnName` is used only for the diagnostic message
|
|
363
|
+
* `fnName` is used only for the diagnostic message; pass the RPC
|
|
363
364
|
* function name when calling from a wire serializer / dump writer so
|
|
364
365
|
* the error points at the offending function.
|
|
365
366
|
*/
|
|
@@ -371,19 +372,21 @@ function strictJsonStringify(value, fnName = "") {
|
|
|
371
372
|
if (Array.isArray(holder)) throw nonJsonAt(fnName, "undefined", holder, key);
|
|
372
373
|
return val;
|
|
373
374
|
}
|
|
374
|
-
if (original
|
|
375
|
-
if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
|
|
376
|
-
if (typeof original === "object") {
|
|
377
|
-
if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
|
|
378
|
-
if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
|
|
379
|
-
if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
|
|
380
|
-
if (Array.isArray(original)) return val;
|
|
381
|
-
const proto = Object.getPrototypeOf(original);
|
|
382
|
-
if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
|
|
383
|
-
}
|
|
375
|
+
if (original !== null) assertJsonSafe(original, holder, key, fnName);
|
|
384
376
|
return val;
|
|
385
377
|
});
|
|
386
378
|
}
|
|
379
|
+
/** Throw `DF0020` when `original` is a type JSON can't round-trip losslessly. */
|
|
380
|
+
function assertJsonSafe(original, holder, key, fnName) {
|
|
381
|
+
if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
|
|
382
|
+
if (typeof original !== "object") return;
|
|
383
|
+
if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
|
|
384
|
+
if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
|
|
385
|
+
if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
|
|
386
|
+
if (Array.isArray(original)) return;
|
|
387
|
+
const proto = Object.getPrototypeOf(original);
|
|
388
|
+
if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
|
|
389
|
+
}
|
|
387
390
|
function nonJsonAt(fnName, type, parent, key) {
|
|
388
391
|
const path = formatPath(parent, key);
|
|
389
392
|
return diagnostics.DF0020({
|
|
@@ -506,6 +509,10 @@ async function setupDevframeConnection(options = {}) {
|
|
|
506
509
|
if (options.connectionMeta) {
|
|
507
510
|
const connection = {
|
|
508
511
|
connectionMeta: options.connectionMeta,
|
|
512
|
+
/**
|
|
513
|
+
* Preserve the established connectionMeta behavior: an explicitly
|
|
514
|
+
* supplied descriptor resolves from the caller's explicit base.
|
|
515
|
+
*/
|
|
509
516
|
metaBaseUrl: resolveMetaBaseUrl(bases[0] ?? "./"),
|
|
510
517
|
authToken: readStoredAuthToken(options.authToken ?? options.connectionMeta.authToken)
|
|
511
518
|
};
|
|
@@ -526,9 +533,15 @@ async function setupDevframeConnection(options = {}) {
|
|
|
526
533
|
const response = await fetch(metaPath);
|
|
527
534
|
if (!response.ok) throw new Error(`Failed to fetch connection meta from ${metaUrl}: ${response.status}`);
|
|
528
535
|
const connectionMeta = await response.json();
|
|
536
|
+
const loadedFrom = response.url || metaUrl;
|
|
529
537
|
const connection = {
|
|
530
538
|
connectionMeta,
|
|
531
|
-
|
|
539
|
+
/**
|
|
540
|
+
* A served `baseUrl` re-points relative resolution (RPC dump shards,
|
|
541
|
+
* transport paths) at the meta that owns them: a static hub build's
|
|
542
|
+
* per-frame meta directs each frame SPA at the hub's own dump.
|
|
543
|
+
*/
|
|
544
|
+
metaBaseUrl: connectionMeta.baseUrl ? new URL(connectionMeta.baseUrl, loadedFrom).href : loadedFrom,
|
|
532
545
|
authToken: readStoredAuthToken(options.authToken ?? connectionMeta.authToken)
|
|
533
546
|
};
|
|
534
547
|
storeConnection(connection);
|
|
@@ -605,7 +618,7 @@ function consumeOtpFromUrl(param = DEVFRAME_OTP_URL_PARAM) {
|
|
|
605
618
|
*
|
|
606
619
|
* Higher-level integrations (e.g. Vite DevTools) that want to drive their own
|
|
607
620
|
* authentication UI can disable `connectDevframe`'s built-in handling with
|
|
608
|
-
* `otpParam: false` and call this
|
|
621
|
+
* `otpParam: false` and call this (or {@link consumeOtpFromUrl}) themselves.
|
|
609
622
|
*/
|
|
610
623
|
async function authenticateWithUrlOtp(rpc, options = {}) {
|
|
611
624
|
const code = consumeOtpFromUrl(options.param ?? "devframe_otp");
|
|
@@ -763,7 +776,7 @@ const EMPTY_WIRE_DEFS = /* @__PURE__ */ new Map();
|
|
|
763
776
|
* JSON (methods declared `jsonSerializable: true`) and `s:`-prefixed
|
|
764
777
|
* structured-clone (everything else, including all error envelopes), with a
|
|
765
778
|
* request-id → method map so a response independently picks the same
|
|
766
|
-
* encoder as its request. One codec per connection
|
|
779
|
+
* encoder as its request. One codec per connection; request-id spaces
|
|
767
780
|
* don't collide across connections.
|
|
768
781
|
*
|
|
769
782
|
* @internal
|
|
@@ -791,9 +804,32 @@ function createRpcWireCodec(definitions = EMPTY_WIRE_DEFS) {
|
|
|
791
804
|
//#endregion
|
|
792
805
|
//#region src/rpc/transports/sse-client.ts
|
|
793
806
|
function NOOP$1() {}
|
|
807
|
+
/** Split the next complete SSE frame (up to a blank line) off the buffer. */
|
|
808
|
+
function takeFrame(buffer) {
|
|
809
|
+
const boundary = buffer.search(/\n\n|\r\n\r\n/);
|
|
810
|
+
if (boundary < 0) return void 0;
|
|
811
|
+
return {
|
|
812
|
+
frame: buffer.slice(0, boundary),
|
|
813
|
+
rest: buffer.slice(boundary + (buffer[boundary] === "\r" ? 4 : 2))
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
/** Parse one SSE frame's lines into its event name and data lines. */
|
|
817
|
+
function parseFrame(frame) {
|
|
818
|
+
let event = "message";
|
|
819
|
+
const data = [];
|
|
820
|
+
for (const rawLine of frame.split(/\r?\n/)) {
|
|
821
|
+
if (rawLine.startsWith(":")) continue;
|
|
822
|
+
if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
|
|
823
|
+
else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
|
|
824
|
+
}
|
|
825
|
+
return {
|
|
826
|
+
event,
|
|
827
|
+
data
|
|
828
|
+
};
|
|
829
|
+
}
|
|
794
830
|
/**
|
|
795
831
|
* Build a birpc `ChannelOptions` object backed by an SSE stream (server →
|
|
796
|
-
* client) and HTTP `POST` (client → server)
|
|
832
|
+
* client) and HTTP `POST` (client → server): the WebSocket-free counterpart
|
|
797
833
|
* to `createWsRpcChannel`, wire-compatible with `attachSseRpcTransport`.
|
|
798
834
|
*
|
|
799
835
|
* The stream is consumed via `fetch` streaming (not `EventSource`), so it
|
|
@@ -801,7 +837,7 @@ function NOOP$1() {}
|
|
|
801
837
|
* (`event: session`) carries the session id; every `POST` echoes it in the
|
|
802
838
|
* `x-birpc-session` header. A response to a client-initiated request comes
|
|
803
839
|
* back in the `POST`'s own body and is re-injected into the channel; a
|
|
804
|
-
* dropped stream terminates the channel
|
|
840
|
+
* dropped stream terminates the channel; there is no reconnect, matching
|
|
805
841
|
* the WS channel's closed-is-done semantics.
|
|
806
842
|
*/
|
|
807
843
|
function createSseRpcChannel(options) {
|
|
@@ -852,17 +888,10 @@ function createSseRpcChannel(options) {
|
|
|
852
888
|
if (done) break;
|
|
853
889
|
buffer += decoder.decode(value, { stream: true });
|
|
854
890
|
for (;;) {
|
|
855
|
-
const
|
|
856
|
-
if (
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
let event = "message";
|
|
860
|
-
const data = [];
|
|
861
|
-
for (const rawLine of frame.split(/\r?\n/)) {
|
|
862
|
-
if (rawLine.startsWith(":")) continue;
|
|
863
|
-
if (rawLine.startsWith("event:")) event = rawLine.slice(6).trimStart();
|
|
864
|
-
else if (rawLine.startsWith("data:")) data.push(rawLine.slice(5).replace(/^ /, ""));
|
|
865
|
-
}
|
|
891
|
+
const taken = takeFrame(buffer);
|
|
892
|
+
if (!taken) break;
|
|
893
|
+
buffer = taken.rest;
|
|
894
|
+
const { event, data } = parseFrame(taken.frame);
|
|
866
895
|
if (data.length > 0) dispatch(event, data.join("\n"));
|
|
867
896
|
}
|
|
868
897
|
}
|
|
@@ -955,8 +984,8 @@ function promiseWithResolver() {
|
|
|
955
984
|
//#endregion
|
|
956
985
|
//#region src/client/rpc-live.ts
|
|
957
986
|
/**
|
|
958
|
-
* The transport-independent half of a live RPC client mode
|
|
959
|
-
* status, pending-call guarding, and the trust handshake
|
|
987
|
+
* The transport-independent half of a live RPC client mode (connection
|
|
988
|
+
* status, pending-call guarding, and the trust handshake), shared by the
|
|
960
989
|
* WebSocket and SSE modes. Each transport supplies only its channel.
|
|
961
990
|
*/
|
|
962
991
|
function createLiveRpcClientMode(options) {
|
|
@@ -984,7 +1013,7 @@ function createLiveRpcClientMode(options) {
|
|
|
984
1013
|
}
|
|
985
1014
|
/**
|
|
986
1015
|
* Wrap an in-flight call promise so it settles on server response, on an
|
|
987
|
-
* optional wall-clock timeout, or when the connection drops
|
|
1016
|
+
* optional wall-clock timeout, or when the connection drops, so it never hangs.
|
|
988
1017
|
*/
|
|
989
1018
|
function guardCall(promise, method) {
|
|
990
1019
|
return new Promise((resolve, reject) => {
|
|
@@ -1053,6 +1082,11 @@ function createLiveRpcClientMode(options) {
|
|
|
1053
1082
|
currentAuthToken = token;
|
|
1054
1083
|
const result = await serverRpc.$call("anonymous:devframe:auth", {
|
|
1055
1084
|
authToken: token,
|
|
1085
|
+
/**
|
|
1086
|
+
* Sent raw; the server parses it into a display label (see
|
|
1087
|
+
* `describeUA` in `node/auth/state.ts`) so `ua-parser-modern` stays
|
|
1088
|
+
* out of the browser bundle.
|
|
1089
|
+
*/
|
|
1056
1090
|
ua: navigator.userAgent,
|
|
1057
1091
|
origin: location.origin
|
|
1058
1092
|
});
|
|
@@ -1175,7 +1209,7 @@ function resolveSseUrl(sse, metaBaseUrl, loc) {
|
|
|
1175
1209
|
return new URL(str, base).href;
|
|
1176
1210
|
}
|
|
1177
1211
|
/**
|
|
1178
|
-
* The SSE-backed live client mode
|
|
1212
|
+
* The SSE-backed live client mode, picked by `connectDevframe` when the
|
|
1179
1213
|
* server advertises SSE as its primary transport (`backend: 'sse'`) or when
|
|
1180
1214
|
* the caller pins `transport: 'sse'`. Same status machine, call guarding,
|
|
1181
1215
|
* and trust handshake as the WebSocket mode, over `createSseRpcChannel`.
|
|
@@ -1218,13 +1252,11 @@ function createSseRpcClientMode(options) {
|
|
|
1218
1252
|
* the original `name`, and re-attaches any custom own properties.
|
|
1219
1253
|
*/
|
|
1220
1254
|
function reviveDumpError(stored) {
|
|
1221
|
-
const
|
|
1222
|
-
const
|
|
1223
|
-
error
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
error[key] = stored[key];
|
|
1227
|
-
}
|
|
1255
|
+
const { name, message, cause: rawCause, ...extras } = stored;
|
|
1256
|
+
const cause = rawCause instanceof Error ? rawCause : isPlainErrorShape(rawCause) ? reviveDumpError(rawCause) : rawCause;
|
|
1257
|
+
const error = cause !== void 0 ? new Error(message, { cause }) : new Error(message);
|
|
1258
|
+
error.name = name;
|
|
1259
|
+
Object.assign(error, extras);
|
|
1228
1260
|
return error;
|
|
1229
1261
|
}
|
|
1230
1262
|
function isPlainErrorShape(value) {
|
|
@@ -1305,15 +1337,21 @@ async function createStaticRpcClientMode(options) {
|
|
|
1305
1337
|
return {
|
|
1306
1338
|
transport: "static",
|
|
1307
1339
|
isTrusted: true,
|
|
1340
|
+
/**
|
|
1341
|
+
* A static backend has no live socket; every call is a local fetch, so it
|
|
1342
|
+
* is "connected" for its whole life.
|
|
1343
|
+
*/
|
|
1308
1344
|
status: "connected",
|
|
1309
1345
|
connectionError: null,
|
|
1310
1346
|
requestTrust: async () => true,
|
|
1311
1347
|
requestTrustWithToken: async () => true,
|
|
1348
|
+
/** Static backends are always trusted, so there's nothing to exchange. */
|
|
1312
1349
|
requestTrustWithCode: async () => null,
|
|
1313
1350
|
ensureTrusted: async () => true,
|
|
1314
1351
|
call: (...args) => staticCaller.call(args[0], args.slice(1)),
|
|
1315
1352
|
callEvent: (...args) => staticCaller.callEvent(args[0], args.slice(1)),
|
|
1316
1353
|
callOptional: (...args) => staticCaller.callOptional(args[0], args.slice(1)),
|
|
1354
|
+
/** No live socket to close; every call is a local fetch. */
|
|
1317
1355
|
close: () => {}
|
|
1318
1356
|
};
|
|
1319
1357
|
}
|
|
@@ -1426,7 +1464,7 @@ const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
|
1426
1464
|
* Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
|
|
1427
1465
|
* Pass the result straight to `createRpcClient`'s `channel` option.
|
|
1428
1466
|
*
|
|
1429
|
-
* Also returns `close()`, closing the underlying socket
|
|
1467
|
+
* Also returns `close()`, closing the underlying socket, mirroring the server transport's
|
|
1430
1468
|
* existing `WsRpcTransport.close()`. `birpc`'s own `ChannelOptions` has no teardown of its own.
|
|
1431
1469
|
*/
|
|
1432
1470
|
function createWsRpcChannel(options) {
|
|
@@ -1488,7 +1526,7 @@ function createWsRpcChannel(options) {
|
|
|
1488
1526
|
* The object / relative-path forms connect to the page's own origin (only the
|
|
1489
1527
|
* `http`→`ws` protocol swap is applied), resolving the path against where
|
|
1490
1528
|
* `__connection.json` was loaded. This is deliberately host-agnostic so the
|
|
1491
|
-
* connection survives a reverse proxy that changes the domain or port
|
|
1529
|
+
* connection survives a reverse proxy that changes the domain or port, since the
|
|
1492
1530
|
* client trusts its own location, never a server-baked hostname. An explicit
|
|
1493
1531
|
* `port`/`host` (or a full `ws(s)://` URL string) opts into a cross-origin
|
|
1494
1532
|
* endpoint, e.g. a side-car server on its own port.
|
|
@@ -1643,7 +1681,7 @@ function createScopedClientContext(rpc, namespace) {
|
|
|
1643
1681
|
//#region src/client/rpc.ts
|
|
1644
1682
|
/**
|
|
1645
1683
|
* Resolve the requested `transport` option against what the server
|
|
1646
|
-
* advertises. `'auto'` trusts the advertisement
|
|
1684
|
+
* advertises. `'auto'` trusts the advertisement: the server's declared
|
|
1647
1685
|
* primary (`backend`), preferring the WebSocket when both endpoints are
|
|
1648
1686
|
* present; an explicit `'websocket'` / `'sse'` pins that transport and
|
|
1649
1687
|
* throws when the server doesn't advertise it.
|
|
@@ -1663,7 +1701,7 @@ function resolveClientTransport(requested, meta) {
|
|
|
1663
1701
|
if (meta.backend === "sse" && hasSse) return "sse";
|
|
1664
1702
|
if (hasWebsocket) return "websocket";
|
|
1665
1703
|
if (hasSse) return "sse";
|
|
1666
|
-
throw new Error("[devframe] This server advertises no RPC transport (backend \"none\")
|
|
1704
|
+
throw new Error("[devframe] This server advertises no RPC transport (backend \"none\"), so there is nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.");
|
|
1667
1705
|
}
|
|
1668
1706
|
async function getDevframeRpcClient(options = {}) {
|
|
1669
1707
|
const { baseURL = "./", rpcOptions = {}, cacheOptions = false } = options;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//#region src/client-assets.ts
|
|
2
2
|
/**
|
|
3
|
-
* Resolve a definition's client assets source
|
|
3
|
+
* Resolve a definition's client assets source: the built SPA served as its
|
|
4
4
|
* UI. Prefers the top-level {@link DevframeDefinition.clientAssets} and falls
|
|
5
5
|
* back to the deprecated `cli.distDir`, so both the new and legacy shapes
|
|
6
|
-
* resolve. Returns `undefined` when neither is set (bridge mode
|
|
6
|
+
* resolve. Returns `undefined` when neither is set (bridge mode, where the SPA is
|
|
7
7
|
* hosted elsewhere).
|
|
8
8
|
*
|
|
9
9
|
* Internal: exposed to first-party integrations via `devframe/internal`, not
|
package/dist/constants.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/events.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Centralized registry of the core devframe event names
|
|
3
|
+
* Centralized registry of the core devframe event names: the node-side host
|
|
4
4
|
* bus events, the client RPC connection events, and the server→client
|
|
5
|
-
* broadcast notifications
|
|
5
|
+
* broadcast notifications, so these names live in one place instead of
|
|
6
6
|
* scattered string literals.
|
|
7
7
|
*
|
|
8
8
|
* **Keep this in sync with [`docs/content/8.references/3.events.md`](../../../docs/content/8.references/3.events.md)**
|
|
@@ -77,6 +77,7 @@ declare const DEVFRAME_EVENTS: {
|
|
|
77
77
|
};
|
|
78
78
|
//#endregion
|
|
79
79
|
//#region src/constants.d.ts
|
|
80
|
+
/** Devframe runtime routes and static output conventions. */
|
|
80
81
|
declare const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
|
|
81
82
|
/**
|
|
82
83
|
* Global key holding the serializable connection prepared by
|
|
@@ -87,7 +88,7 @@ declare const DEVFRAME_CONNECTION_KEY = "__DEVFRAME_CONNECTION__";
|
|
|
87
88
|
/**
|
|
88
89
|
* Route the WebSocket RPC endpoint is bound to, relative to a devframe's
|
|
89
90
|
* base path. Sits next to `__connection.json` so the deployed SPA can reach
|
|
90
|
-
* it on the same origin it loaded from
|
|
91
|
+
* it on the same origin it loaded from: the dev server shares one port for
|
|
91
92
|
* both HTTP and WS, and a host server (Vite, etc.) can mount the WS upgrade
|
|
92
93
|
* handler here without colliding with its own routes (HMR, asset serving).
|
|
93
94
|
*/
|
|
@@ -97,7 +98,7 @@ declare const DEVFRAME_WS_ROUTE = "__ws";
|
|
|
97
98
|
* path. A single method-dispatched route: `GET` opens the event stream
|
|
98
99
|
* (server→client), `POST` carries RPC frames (client→server). Sits next to
|
|
99
100
|
* `__connection.json` so the deployed SPA reaches it on the same origin it
|
|
100
|
-
* loaded from
|
|
101
|
+
* loaded from; the transport for hosts and proxies where the WebSocket
|
|
101
102
|
* upgrade isn't available.
|
|
102
103
|
*/
|
|
103
104
|
declare const DEVFRAME_SSE_ROUTE = "__sse";
|
|
@@ -111,7 +112,7 @@ declare const DEVFRAME_SSE_SESSION_HEADER = "x-birpc-session";
|
|
|
111
112
|
/**
|
|
112
113
|
* Route the Streamable-HTTP MCP endpoint is bound to, relative to a
|
|
113
114
|
* devframe's base path. Sits next to `__connection.json` and the WS route
|
|
114
|
-
* so an MCP client reaches it on the same origin the SPA loaded from
|
|
115
|
+
* so an MCP client reaches it on the same origin the SPA loaded from; the
|
|
115
116
|
* dev server shares one port for HTTP, WS, and MCP. Opt-in via `cli.mcp`.
|
|
116
117
|
*/
|
|
117
118
|
declare const DEVFRAME_MCP_ROUTE = "__mcp";
|
|
@@ -156,7 +157,7 @@ declare const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin
|
|
|
156
157
|
/**
|
|
157
158
|
* `postMessage` type the remote-assets fallback page posts to `window.parent`
|
|
158
159
|
* on load. That page is what a devframe serves (with a 502) when its client
|
|
159
|
-
* assets can be reached neither locally nor through their CDN provider
|
|
160
|
+
* assets can be reached neither locally nor through their CDN provider; the
|
|
160
161
|
* message lets an embedding viewer replace the bare page with its own UI
|
|
161
162
|
* (`@devframes/hub-ui` does, in its iframe view). Payload shape:
|
|
162
163
|
* `RemoteAssetsErrorMessage` (`devframe/types`).
|
|
@@ -164,7 +165,7 @@ declare const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin
|
|
|
164
165
|
declare const DEVFRAME_REMOTE_ASSETS_ERROR_MESSAGE_TYPE: string;
|
|
165
166
|
/**
|
|
166
167
|
* Prefix that marks an RPC method as callable before a connection is
|
|
167
|
-
* trusted. This is the *only* rule the pre-trust gate applies
|
|
168
|
+
* trusted. This is the *only* rule the pre-trust gate applies; there is no
|
|
168
169
|
* per-method allowlist. Any handshake method a host adapter needs to reach
|
|
169
170
|
* before authentication must be named `anonymous:<rest>` (e.g.
|
|
170
171
|
* `anonymous:devframe:auth`).
|