devframe 0.9.0-beta.9 → 0.9.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.
- package/dist/_shared-BM3PdYli.mjs +68 -0
- package/dist/{_shared-BPmX9fqK.d.mts → _shared-DqbKCAew.d.mts} +1 -1
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +8 -6
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +4 -3
- package/dist/adapters/dev.d.mts +3 -3
- package/dist/adapters/dev.mjs +2 -2
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/embedded.mjs +1 -0
- package/dist/adapters/initiate.d.mts +2 -2
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/cli/main.mjs +2 -2
- package/dist/client/index.d.mts +48 -2
- package/dist/client/index.mjs +131 -22
- package/dist/constants.d.mts +74 -2
- package/dist/constants.mjs +9 -2
- package/dist/{context-CEe4PBz1.mjs → context-Bdkakk8S.mjs} +319 -21
- package/dist/{context-xdynGSLP.mjs → context-CXhjygJU.mjs} +2 -2
- package/dist/{context-B3YUu_95.d.mts → context-dqyXS6o3.d.mts} +1 -1
- package/dist/{dev-Chvlqs7I.mjs → dev-C8VHtuPP.mjs} +12 -9
- package/dist/{devframe-DJMg0WLe.d.mts → devframe-BlLEZR-x.d.mts} +741 -588
- package/dist/{diagnostics-DOQPnQmX.mjs → diagnostics-Di8ytitn.mjs} +24 -0
- package/dist/{_shared-CKZPvSrN.mjs → dist-CZXfGEkd.mjs} +2 -68
- package/dist/events-DKfSmoTj.mjs +65 -0
- package/dist/{host-agent-xLCSe65D.mjs → host-agent-BDdcOXhG.mjs} +14 -13
- package/dist/{http-8Kpkap4_.mjs → http-BbHCU5Zs.mjs} +9 -6
- package/dist/{index-CB-fSUyn.d.mts → index-BKFT9-jA.d.mts} +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/{instance-registry-WvQkt42E.mjs → instance-registry-CHunhMi5.mjs} +4 -4
- package/dist/{instance-shell-CljiKq1c.d.mts → instance-shell-0iw-cQ5V.d.mts} +2 -2
- package/dist/{instance-shell-XvN5USg4.mjs → instance-shell-DbDoozNM.mjs} +5 -5
- package/dist/internal/index.d.mts +46 -7
- package/dist/internal/index.mjs +8 -8
- 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 +1 -1
- package/dist/node/index.mjs +2 -2
- package/dist/recipes/common-rpc-functions.d.mts +1 -1
- package/dist/recipes/interactive-auth.d.mts +2 -2
- package/dist/recipes/interactive-auth.mjs +2 -2
- package/dist/{remote-assets-nTTxY2MU.mjs → remote-assets-DRfY2RjX.mjs} +6 -5
- package/dist/{revoke-DZbJ7Cl0.mjs → revoke-3Q6aDKWk.mjs} +2 -1
- package/dist/{rolldown-runtime-JspESFgx.mjs → rolldown-runtime-B4iAMlE-.mjs} +1 -1
- package/dist/rpc/transports/sse-client.mjs +1 -1
- package/dist/rpc/transports/sse-server.mjs +2 -2
- package/dist/rpc/transports/ws-bun.d.mts +1 -1
- package/dist/rpc/transports/ws-bun.mjs +1 -1
- package/dist/rpc/transports/ws-client.mjs +1 -1
- package/dist/rpc/transports/ws-server.mjs +1 -1
- package/dist/{rpc-core-Cc4lucI0.d.mts → rpc-core-CR8o34O9.d.mts} +2 -2
- package/dist/{rpc-core-DMTe-hLo.mjs → rpc-core-Dru9uoM0.mjs} +11 -4
- package/dist/{state-Cc1IeSmQ.mjs → state-CK9LjrnT.mjs} +1 -1
- package/dist/{storage-CYye7P7L.mjs → storage-D4a99Ung.mjs} +3 -3
- package/dist/types/index.d.mts +2 -2
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/get-port.d.mts +17 -0
- package/dist/utils/get-port.mjs +2 -0
- package/dist/utils/launch-editor.mjs +12 -11
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/remote-assets.mjs +1 -1
- package/dist/utils/serve-static.mjs +6 -5
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{wire-codec-GsoRxIsD.mjs → wire-codec-0K-o5MYW.mjs} +0 -2
- package/dist/{ws-server-BiUne4K7.mjs → ws-server-BdSLrhxE.mjs} +1 -1
- package/package.json +2 -1
- package/dist/{host-h3-Crkzm42q.mjs → host-h3-fRbF9yor.mjs} +1 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import "./constants.mjs";
|
|
2
|
+
import { n as getPort } from "./dist-CZXfGEkd.mjs";
|
|
3
|
+
import { cleanDoubleSlashes, withLeadingSlash, withTrailingSlash, withoutLeadingSlash } from "ufo";
|
|
4
|
+
//#region src/adapters/_shared.ts
|
|
5
|
+
const DEFAULT_PORT = 9999;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the mount base path for a devframe's SPA. Hosted adapters
|
|
8
|
+
* (`vite`, `embedded`) default to `/__<id>/` so they don't collide
|
|
9
|
+
* with the host app; standalone adapters (`cli`, `build`)
|
|
10
|
+
* default to `/` because they own the origin.
|
|
11
|
+
*
|
|
12
|
+
* The devframe author can override with `basePath` on the definition.
|
|
13
|
+
*/
|
|
14
|
+
function resolveBasePath(def, kind) {
|
|
15
|
+
if (def.basePath) return normalizeBasePath(def.basePath);
|
|
16
|
+
return kind === "standalone" ? "/" : `/__${def.id}/`;
|
|
17
|
+
}
|
|
18
|
+
function normalizeBasePath(base) {
|
|
19
|
+
return cleanDoubleSlashes(withTrailingSlash(withLeadingSlash(base)));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the listening port for `createDevServer` (and `createHandler`'s
|
|
23
|
+
* side-car tiers), honoring the definition's `cli.port` / `cli.portRange` /
|
|
24
|
+
* `cli.random` settings. Exposed separately so authors who run their own
|
|
25
|
+
* argv parsing can resolve a port up-front (to print it, log it, etc.)
|
|
26
|
+
* before starting the server.
|
|
27
|
+
*/
|
|
28
|
+
async function resolveDevServerPort(def, options = {}) {
|
|
29
|
+
const host = options.host ?? def.cli?.host ?? "localhost";
|
|
30
|
+
const portOptions = {
|
|
31
|
+
port: options.defaultPort ?? def.cli?.port ?? DEFAULT_PORT,
|
|
32
|
+
host
|
|
33
|
+
};
|
|
34
|
+
if (def.cli?.portRange) portOptions.portRange = def.cli.portRange;
|
|
35
|
+
if (def.cli?.random) portOptions.random = def.cli.random;
|
|
36
|
+
return getPort(portOptions);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Normalize the `cli.mcp` / `mcp` option (`boolean | McpRouteOptions`) into
|
|
40
|
+
* concrete options, or `undefined` when the MCP route is disabled.
|
|
41
|
+
*/
|
|
42
|
+
function resolveMcpConfig(mcp) {
|
|
43
|
+
if (!mcp) return void 0;
|
|
44
|
+
return mcp === true ? {} : mcp;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the `mcp` entry a `__connection.json` should advertise for a dev
|
|
48
|
+
* server started with the given `mcp` option (falling back to `def.cli?.mcp`,
|
|
49
|
+
* exactly like `createDevServer`), or `undefined` when the route is
|
|
50
|
+
* disabled.
|
|
51
|
+
*
|
|
52
|
+
* Hosted bridges that hand-roll their connection meta pass the side-car
|
|
53
|
+
* `port`: the advertised path becomes absolute (the side-car mounts at `/`)
|
|
54
|
+
* and the client dials `<page-host>:<port><path>`. Without `port` the path
|
|
55
|
+
* stays relative, resolved against `__connection.json`'s own location (the
|
|
56
|
+
* same-server default).
|
|
57
|
+
*/
|
|
58
|
+
function resolveMcpConnectionMeta(def, mcp, port) {
|
|
59
|
+
const config = resolveMcpConfig(mcp ?? def.cli?.mcp);
|
|
60
|
+
if (!config) return void 0;
|
|
61
|
+
const route = withoutLeadingSlash(config.path ?? "__mcp");
|
|
62
|
+
return port != null ? {
|
|
63
|
+
path: withLeadingSlash(route),
|
|
64
|
+
port
|
|
65
|
+
} : { path: route };
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { resolveMcpConnectionMeta as i, resolveBasePath as n, resolveDevServerPort as r, normalizeBasePath as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as ConnectionMeta, l as McpRouteOptions, n as DevframeDefinition, r as DevframeDeploymentKind } from "./devframe-
|
|
1
|
+
import { d as ConnectionMeta, l as McpRouteOptions, n as DevframeDefinition, r as DevframeDeploymentKind } from "./devframe-BlLEZR-x.mjs";
|
|
2
2
|
//#region src/adapters/_shared.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolve the mount base path for a devframe's SPA. Hosted adapters
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { n as DevframeDefinition } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { o as StaticAssetsSource } from "../remote-assets-Bg4gCUZ_.mjs";
|
|
3
3
|
//#region src/adapters/build.d.ts
|
|
4
4
|
interface CreateBuildOptions {
|
package/dist/adapters/build.mjs
CHANGED
|
@@ -3,14 +3,14 @@ import { n as strictJsonStringify } from "../serialization-BGzEwAdr.mjs";
|
|
|
3
3
|
import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_RPC_DUMP_DIRNAME, DEVFRAME_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
|
|
4
4
|
import { t as collectStaticRpcDump } from "../static-BPZ1_OPA.mjs";
|
|
5
5
|
import { n as structuredCloneStringify } from "../structured-clone-CbAV5rFI.mjs";
|
|
6
|
-
import { t as diagnostics } from "../diagnostics-
|
|
7
|
-
import { t as createHostContext } from "../context-
|
|
8
|
-
import { t as resolveStaticAssetsSource } from "../remote-assets-
|
|
9
|
-
import { t as createH3DevframeHost } from "../host-h3-
|
|
6
|
+
import { t as diagnostics } from "../diagnostics-Di8ytitn.mjs";
|
|
7
|
+
import { t as createHostContext } from "../context-Bdkakk8S.mjs";
|
|
8
|
+
import { t as resolveStaticAssetsSource } from "../remote-assets-DRfY2RjX.mjs";
|
|
9
|
+
import { t as createH3DevframeHost } from "../host-h3-fRbF9yor.mjs";
|
|
10
|
+
import process from "node:process";
|
|
11
|
+
import { dirname, resolve } from "pathe";
|
|
10
12
|
import { existsSync } from "node:fs";
|
|
11
13
|
import fs$1 from "node:fs/promises";
|
|
12
|
-
import { dirname, resolve } from "pathe";
|
|
13
|
-
import process from "node:process";
|
|
14
14
|
//#region src/adapters/build.ts
|
|
15
15
|
/**
|
|
16
16
|
* Produce a self-contained static deploy of a devframe:
|
|
@@ -47,7 +47,9 @@ async function createBuild(d, options = {}) {
|
|
|
47
47
|
mode: "build",
|
|
48
48
|
host
|
|
49
49
|
});
|
|
50
|
+
for (const input of d.services ?? []) ctx.services.install(input, { resolveFrom: d.packageName });
|
|
50
51
|
await d.setup(ctx);
|
|
52
|
+
await ctx.services.ready();
|
|
51
53
|
await fs$1.mkdir(resolve(outDir, DEVFRAME_RPC_DUMP_DIRNAME), { recursive: true });
|
|
52
54
|
const jsonSerializableMethods = [];
|
|
53
55
|
for (const def of ctx.rpc.definitions.values()) if (def.jsonSerializable === true) jsonSerializableMethods.push(def.name);
|
package/dist/adapters/cac.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ft as CliFlagsSchema, It as InferCliFlags, Lt as defineCliFlags, Rt as parseCliFlags, n as DevframeDefinition } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { CAC } from "cac";
|
|
3
3
|
import { H3 } from "h3";
|
|
4
4
|
//#region src/adapters/cac.d.ts
|
package/dist/adapters/cac.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as colors } from "../nostics-CzECRXpE.mjs";
|
|
2
|
-
import { r as resolveDevServerPort } from "../_shared-
|
|
2
|
+
import { r as resolveDevServerPort } from "../_shared-BM3PdYli.mjs";
|
|
3
3
|
import { createBuild } from "./build.mjs";
|
|
4
|
-
import { t as createDevServer } from "../dev-
|
|
4
|
+
import { t as createDevServer } from "../dev-C8VHtuPP.mjs";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import cac$1 from "cac";
|
|
7
7
|
//#region src/adapters/flags.ts
|
|
@@ -93,7 +93,8 @@ function flagKeyToOption(camel) {
|
|
|
93
93
|
function createCac(d, options = {}) {
|
|
94
94
|
const defaultPort = options.defaultPort ?? d.cli?.port ?? 9999;
|
|
95
95
|
const defaultHost = d.cli?.host ?? "localhost";
|
|
96
|
-
const
|
|
96
|
+
const command = d.cli?.command ?? d.id;
|
|
97
|
+
const cli = cac$1(command);
|
|
97
98
|
const devCommand = cli.command("[...args]", "Start a local dev server").option("--port <port>", "Port to listen on").option("--host <host>", "Host to bind to", { default: defaultHost }).option("--open", "Open the browser on start").option("--no-open", "Do not open the browser").option("--no-auth", "Disable the interactive authentication gate").option("--mcp", "Expose an MCP server over HTTP at /__mcp (use --no-mcp to disable)");
|
|
98
99
|
if (d.cli?.flags) for (const [key, schema] of Object.entries(d.cli.flags)) {
|
|
99
100
|
const optionName = flagKeyToOption(key);
|
package/dist/adapters/dev.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as DevframeNodeRpcSession, c as DevframeWsOptions, l as McpRouteOptions, n as DevframeDefinition, s as DevframeSseOptions, u as DevframeAuthHandler } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "../ws-server-D1d3QM9f.mjs";
|
|
3
3
|
import { o as StaticAssetsSource } from "../remote-assets-Bg4gCUZ_.mjs";
|
|
4
|
-
import { c as StartedServer } from "../instance-shell-
|
|
5
|
-
import { a as resolveMcpConnectionMeta, i as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-
|
|
4
|
+
import { c as StartedServer } from "../instance-shell-0iw-cQ5V.mjs";
|
|
5
|
+
import { a as resolveMcpConnectionMeta, i as resolveDevServerPort, t as ResolveDevServerPortOptions } from "../_shared-DqbKCAew.mjs";
|
|
6
6
|
import { H3 } from "h3";
|
|
7
7
|
//#region src/adapters/dev.d.ts
|
|
8
8
|
interface CreateDevServerOptions {
|
package/dist/adapters/dev.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as resolveMcpConnectionMeta, r as resolveDevServerPort } from "../_shared-
|
|
2
|
-
import { t as createDevServer } from "../dev-
|
|
1
|
+
import { i as resolveMcpConnectionMeta, r as resolveDevServerPort } from "../_shared-BM3PdYli.mjs";
|
|
2
|
+
import { t as createDevServer } from "../dev-C8VHtuPP.mjs";
|
|
3
3
|
export { createDevServer, resolveDevServerPort, resolveMcpConnectionMeta };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as DevframeNodeContext, n as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { g as DevframeNodeContext, n as DevframeDefinition } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
//#region src/adapters/embedded.d.ts
|
|
3
3
|
interface CreateEmbeddedOptions {
|
|
4
4
|
/** Target context the devframe is registered into. Required. */
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* effective default follows the hosted rule of `def.basePath ?? '/__<id>/'`.
|
|
10
10
|
*/
|
|
11
11
|
async function createEmbedded(d, options) {
|
|
12
|
+
for (const input of d.services ?? []) options.ctx.services.install(input, { resolveFrom: d.packageName });
|
|
12
13
|
await d.setup(options.ctx);
|
|
13
14
|
}
|
|
14
15
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as DevframeStorageScope, _ as DevframeNodeRpcSession, c as DevframeWsOptions, d as ConnectionMeta, g as DevframeNodeContext, l as McpRouteOptions, n as DevframeDefinition, s as DevframeSseOptions, u as DevframeAuthHandler } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { d as DevframeRpcConnection, n as WsOriginRegistry, u as DevframeNodeRpcSessionMeta } from "../ws-server-D1d3QM9f.mjs";
|
|
3
3
|
import { o as StaticAssetsSource } from "../remote-assets-Bg4gCUZ_.mjs";
|
|
4
|
-
import { c as StartedServer, f as DevframeInstanceRecord } from "../instance-shell-
|
|
4
|
+
import { c as StartedServer, f as DevframeInstanceRecord } from "../instance-shell-0iw-cQ5V.mjs";
|
|
5
5
|
import { Buffer } from "node:buffer";
|
|
6
6
|
import { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
7
7
|
import { Duplex } from "node:stream";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as getInstanceInternals, r as initDevframe } from "../dev-
|
|
1
|
+
import { n as getInstanceInternals, r as initDevframe } from "../dev-C8VHtuPP.mjs";
|
|
2
2
|
export { getInstanceInternals, initDevframe };
|
package/dist/adapters/mcp.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as DevframeNodeContext, n as DevframeDefinition } from "../devframe-
|
|
1
|
+
import { g as DevframeNodeContext, n as DevframeDefinition } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { H3 } from "h3";
|
|
3
3
|
import "@modelcontextprotocol/server";
|
|
4
4
|
//#region src/adapters/mcp/build-server.d.ts
|
package/dist/adapters/mcp.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as createMcpServer, n as mountMcpHttp, r as createMcpFetchHandler } from "../http-
|
|
1
|
+
import { i as createMcpServer, n as mountMcpHttp, r as createMcpFetchHandler } from "../http-BbHCU5Zs.mjs";
|
|
2
2
|
export { createMcpFetchHandler, createMcpServer, mountMcpHttp };
|
package/dist/cli/main.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as Diagnostic } from "../nostics-CzECRXpE.mjs";
|
|
2
|
-
import { t as diagnostics } from "../diagnostics-
|
|
3
|
-
import { n as listLiveDevframeInstances, r as probeDevframeOrigin } from "../instance-registry-
|
|
2
|
+
import { t as diagnostics } from "../diagnostics-Di8ytitn.mjs";
|
|
3
|
+
import { n as listLiveDevframeInstances, r as probeDevframeOrigin } from "../instance-registry-CHunhMi5.mjs";
|
|
4
4
|
import { t as toAgentToolName } from "../agent-tool-name-EgfoFO8C.mjs";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import { joinURL } from "ufo";
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { E as DevframeRpcServerFunctions, H as DevframeSettings, J as ScopedServerFunctions, M as DevframeServiceMeta, Mt as EventEmitter, P as DevframeServiceScopeOf, R as DevframeServicesState, T as DevframeRpcClientFunctions, X as SettingsForNamespace, Y as ScopedSharedStates, b as RpcSharedStateGetOptions, d as ConnectionMeta, gt as SharedState, ot as StreamReader, q as ScopedRpcFn, st as StreamSink, x as RpcSharedStateHost } from "../devframe-BlLEZR-x.mjs";
|
|
2
2
|
import { f as RpcCacheManager, p as RpcCacheOptions } from "../index-tdrk1bzV.mjs";
|
|
3
3
|
import { _ as RpcFunctionDefinition, w as RpcFunctionsCollector } from "../types-Djq7CBXh.mjs";
|
|
4
4
|
import { t as SseRpcChannelOptions } from "../sse-client-CFBOIaUi.mjs";
|
|
@@ -197,6 +197,45 @@ interface DevframeScopedClientContext<NS extends string = string, Settings exten
|
|
|
197
197
|
*/
|
|
198
198
|
declare function createScopedClientContext<NS extends string = string>(rpc: DevframeRpcClient, namespace: NS): DevframeScopedClientContext<NS>;
|
|
199
199
|
//#endregion
|
|
200
|
+
//#region src/client/rpc-services.d.ts
|
|
201
|
+
/**
|
|
202
|
+
* A typed handle on one advertised wire service — the service's
|
|
203
|
+
* advertisement meta plus an RPC surface scoped to its namespace, so
|
|
204
|
+
* `handle.rpc.call('fn-name', …)` targets `<scope>:fn-name`. Service
|
|
205
|
+
* packages type the calls by augmenting `DevframeRpcServerFunctions` with
|
|
206
|
+
* their fully-qualified ids and `DevframeServicesScopeRegistry` with their
|
|
207
|
+
* package → scope mapping.
|
|
208
|
+
*/
|
|
209
|
+
interface DevframeServiceClientHandle<NS extends string = string> extends DevframeServiceMeta {
|
|
210
|
+
readonly scope: NS;
|
|
211
|
+
/** RPC surface scoped to the service's namespace. */
|
|
212
|
+
readonly rpc: DevframeScopedClientRpc<NS>;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Client-side view of the server's wire-service registry, mirrored through
|
|
216
|
+
* the reactive `devframe:services` shared state. The accessors are
|
|
217
|
+
* synchronous snapshots — before the first sync lands (or on a server with
|
|
218
|
+
* no services) they read as empty. For reactive UI (e.g. hiding an
|
|
219
|
+
* "open in editor" button until the service appears), subscribe to the
|
|
220
|
+
* shared state itself via {@link DevframeServicesClient.state}.
|
|
221
|
+
*/
|
|
222
|
+
interface DevframeServicesClient {
|
|
223
|
+
/** Whether the service package is advertised as installed. */
|
|
224
|
+
has: (pkg: string) => boolean;
|
|
225
|
+
/**
|
|
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
|
+
*/
|
|
229
|
+
get: <PKG extends string>(pkg: PKG) => DevframeServiceClientHandle<DevframeServiceScopeOf<PKG>> | undefined;
|
|
230
|
+
/** Package names of every advertised service. */
|
|
231
|
+
keys: () => string[];
|
|
232
|
+
/**
|
|
233
|
+
* The mirrored `devframe:services` shared state — subscribe to its
|
|
234
|
+
* `updated` event for reactivity.
|
|
235
|
+
*/
|
|
236
|
+
state: () => Promise<SharedState<DevframeServicesState>>;
|
|
237
|
+
}
|
|
238
|
+
//#endregion
|
|
200
239
|
//#region src/client/rpc.d.ts
|
|
201
240
|
interface DevframeRpcContext {
|
|
202
241
|
/**
|
|
@@ -363,6 +402,13 @@ interface DevframeRpcClient {
|
|
|
363
402
|
* The shared state host
|
|
364
403
|
*/
|
|
365
404
|
sharedState: RpcSharedStateHost;
|
|
405
|
+
/**
|
|
406
|
+
* The server's advertised wire services (mirrored `devframe:services`
|
|
407
|
+
* shared state) — feature-detect a capability with
|
|
408
|
+
* `rpc.services.has('@devframes/service-x')` and get a scoped, typed RPC
|
|
409
|
+
* handle with `rpc.services.get(...)`. See {@link DevframeServicesClient}.
|
|
410
|
+
*/
|
|
411
|
+
services: DevframeServicesClient;
|
|
366
412
|
/**
|
|
367
413
|
* The streaming channel host. Subscribe to a server-side stream by
|
|
368
414
|
* channel + id; the returned reader is both `AsyncIterable<T>` and
|
|
@@ -505,4 +551,4 @@ declare function createClientSettings<T extends Record<string, any> = Record<str
|
|
|
505
551
|
//#region src/client/index.d.ts
|
|
506
552
|
declare const connectDevframe: typeof getDevframeRpcClient;
|
|
507
553
|
//#endregion
|
|
508
|
-
export { DevframeClientRpcHost, DevframeConnection, DevframeConnectionError, DevframeConnectionErrorKind, DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientCall, DevframeRpcClientCallEvent, DevframeRpcClientCallOptional, DevframeRpcClientMode, DevframeRpcClientOptions, DevframeRpcContext, DevframeScopedClientContext, DevframeScopedClientRpc, DevframeScopedClientStreamingHost, RpcClientEvents, RpcStreamingClientHost, SetupDevframeConnectionOptions, StreamingSubscribeOptions, type WsUrlLocation, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, registerDevframeViewerOrigin, resolveClientTransport, resolveSseUrl, resolveWsUrl, setupDevframeConnection };
|
|
554
|
+
export { DevframeClientRpcHost, DevframeConnection, DevframeConnectionError, DevframeConnectionErrorKind, DevframeConnectionStatus, DevframeRpcClient, DevframeRpcClientCall, DevframeRpcClientCallEvent, DevframeRpcClientCallOptional, DevframeRpcClientMode, DevframeRpcClientOptions, DevframeRpcContext, DevframeScopedClientContext, DevframeScopedClientRpc, DevframeScopedClientStreamingHost, type DevframeServiceClientHandle, type DevframeServicesClient, RpcClientEvents, RpcStreamingClientHost, SetupDevframeConnectionOptions, StreamingSubscribeOptions, type WsUrlLocation, authenticateWithUrlOtp, connectDevframe, consumeOtpFromUrl, createClientSettings, createRpcStreamingClientHost, createScopedClientContext, getDevframeConnection, getDevframeRpcClient, isCallableStatus, readOtpFromUrl, registerDevframeViewerOrigin, resolveClientTransport, resolveSseUrl, resolveWsUrl, setupDevframeConnection };
|
package/dist/client/index.mjs
CHANGED
|
@@ -8,6 +8,70 @@ import { defineDiagnostics } from "nostics";
|
|
|
8
8
|
import { ansiFormatter } from "nostics/formatters/ansi";
|
|
9
9
|
import { withBase, withProtocol } from "ufo";
|
|
10
10
|
import { createBirpc } from "birpc";
|
|
11
|
+
//#region src/events.ts
|
|
12
|
+
/**
|
|
13
|
+
* Centralized registry of the core devframe event names — the node-side host
|
|
14
|
+
* bus events, the client RPC connection events, and the server→client
|
|
15
|
+
* broadcast notifications — so these names live in one place instead of
|
|
16
|
+
* scattered string literals.
|
|
17
|
+
*
|
|
18
|
+
* **Keep this in sync with [`docs/guide/events.md`](../../../docs/guide/events.md)**
|
|
19
|
+
* (the "Core devframe events" section): every name here appears in that page's
|
|
20
|
+
* tables, and every name there resolves to an entry here. Add, rename, or
|
|
21
|
+
* remove a name in both places in the same change, and reference
|
|
22
|
+
* `DEVFRAME_EVENTS.*` from call sites instead of re-typing a literal.
|
|
23
|
+
*
|
|
24
|
+
* This map covers **notifications** (events, broadcasts). The request/response
|
|
25
|
+
* RPC endpoints of the shared-state, streaming, and auth-handshake protocols
|
|
26
|
+
* (`devframe:rpc:server-state:*`, `devframe:streaming:subscribe`,
|
|
27
|
+
* `anonymous:devframe:auth`, …) are defined at their handlers and typed in
|
|
28
|
+
* `types/rpc-augments.ts`; they aren't events and stay out of this map.
|
|
29
|
+
*
|
|
30
|
+
* The `EventEmitter` maps (`RpcClientEvents`, `DevframeAgentHostEvents`) and the
|
|
31
|
+
* `DevframeRpcClientFunctions` augmentation declare these names as type-level
|
|
32
|
+
* keys (a literal is unavoidable in a type position); those declarations mirror
|
|
33
|
+
* this map and move with it.
|
|
34
|
+
*/
|
|
35
|
+
const DEVFRAME_EVENTS = {
|
|
36
|
+
/**
|
|
37
|
+
* Node-side host `EventEmitter` events. The agent host (`ctx.agent.events`)
|
|
38
|
+
* emits these as its tool/resource surface changes; protocol adapters (e.g.
|
|
39
|
+
* MCP) subscribe to re-publish their manifest.
|
|
40
|
+
*/
|
|
41
|
+
bus: {
|
|
42
|
+
agentManifestChanged: "agent:manifest:changed",
|
|
43
|
+
agentToolRegistered: "agent:tool:registered",
|
|
44
|
+
agentToolUnregistered: "agent:tool:unregistered",
|
|
45
|
+
agentResourceRegistered: "agent:resource:registered",
|
|
46
|
+
agentResourceUnregistered: "agent:resource:unregistered"
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Client-side RPC connection `EventEmitter` events (`rpc.events`) a UI
|
|
50
|
+
* subscribes to for connection lifecycle and error surfacing.
|
|
51
|
+
*/
|
|
52
|
+
client: {
|
|
53
|
+
isTrustedUpdated: "rpc:is-trusted:updated",
|
|
54
|
+
error: "rpc:error",
|
|
55
|
+
connectionStatus: "connection:status",
|
|
56
|
+
connectionError: "connection:error"
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* Broadcast notifications the server pushes to clients (server → client),
|
|
60
|
+
* `devframe:` prefix. The paired request methods (subscribe/get/set/…) are
|
|
61
|
+
* RPC endpoints, not events, and are omitted deliberately.
|
|
62
|
+
*/
|
|
63
|
+
broadcast: {
|
|
64
|
+
authRevoked: "devframe:auth:revoked",
|
|
65
|
+
clientStateUpdated: "devframe:rpc:client-state:updated",
|
|
66
|
+
clientStatePatch: "devframe:rpc:client-state:patch",
|
|
67
|
+
streamingChunk: "devframe:streaming:chunk",
|
|
68
|
+
streamingEnd: "devframe:streaming:end",
|
|
69
|
+
streamingUploadCancel: "devframe:streaming:upload-cancel"
|
|
70
|
+
},
|
|
71
|
+
/** `postMessage` channels the runtime posts across window boundaries. */
|
|
72
|
+
postMessage: { remoteAssetsError: "devframe:remote-assets-error" }
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
11
75
|
//#region src/constants.ts
|
|
12
76
|
const DEVFRAME_CONNECTION_META_FILENAME = "__connection.json";
|
|
13
77
|
/**
|
|
@@ -25,6 +89,12 @@ const DEVFRAME_CONNECTION_KEY = "__DEVFRAME_CONNECTION__";
|
|
|
25
89
|
const DEVFRAME_SSE_SESSION_HEADER = "x-birpc-session";
|
|
26
90
|
const DEVFRAME_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
|
|
27
91
|
/**
|
|
92
|
+
* Shared-state key carrying the wire-service advertisements (package name →
|
|
93
|
+
* `DevframeServiceMeta`). Written by the node services host; mirrored to
|
|
94
|
+
* clients for feature-detection via `client.services`.
|
|
95
|
+
*/
|
|
96
|
+
const DEVFRAME_SERVICES_STATE_KEY = "devframe:services";
|
|
97
|
+
/**
|
|
28
98
|
* Page-URL **fragment** parameter carrying a one-time authentication code (OTP)
|
|
29
99
|
* for "magic link" auth. A host can print a link like
|
|
30
100
|
* `<origin>/#devframe_otp=<code>`; the client reads the code, exchanges it for a
|
|
@@ -47,6 +117,7 @@ const DEVFRAME_AUTH_TOKEN_QUERY_PARAM = "devframe_auth_token";
|
|
|
47
117
|
const DEVFRAME_VIEWER_ORIGIN_QUERY_PARAM = "devframe_viewer_origin";
|
|
48
118
|
/** Token that authorizes an external viewer origin registration. */
|
|
49
119
|
const DEVFRAME_VIEWER_ORIGIN_TOKEN_QUERY_PARAM = "devframe_viewer_origin_token";
|
|
120
|
+
DEVFRAME_EVENTS.postMessage.remoteAssetsError;
|
|
50
121
|
//#endregion
|
|
51
122
|
//#region src/rpc/cache.ts
|
|
52
123
|
/**
|
|
@@ -606,6 +677,43 @@ async function authenticateWithUrlOtp(rpc, options = {}) {
|
|
|
606
677
|
return rpc.requestTrustWithCode(code);
|
|
607
678
|
}
|
|
608
679
|
//#endregion
|
|
680
|
+
//#region src/client/rpc-services.ts
|
|
681
|
+
/** @internal */
|
|
682
|
+
function createDevframeServicesClient(rpc) {
|
|
683
|
+
let current = {};
|
|
684
|
+
const handles = /* @__PURE__ */ new WeakMap();
|
|
685
|
+
let statePromise;
|
|
686
|
+
const state = () => {
|
|
687
|
+
statePromise ??= rpc.sharedState.get(DEVFRAME_SERVICES_STATE_KEY, { initialValue: {} }).then((shared) => {
|
|
688
|
+
current = shared.value();
|
|
689
|
+
shared.on("updated", (value) => {
|
|
690
|
+
current = value;
|
|
691
|
+
});
|
|
692
|
+
return shared;
|
|
693
|
+
});
|
|
694
|
+
return statePromise;
|
|
695
|
+
};
|
|
696
|
+
state();
|
|
697
|
+
return {
|
|
698
|
+
state,
|
|
699
|
+
has: (pkg) => pkg in current,
|
|
700
|
+
keys: () => Object.keys(current),
|
|
701
|
+
get: (pkg) => {
|
|
702
|
+
const entry = current[pkg];
|
|
703
|
+
if (!entry) return void 0;
|
|
704
|
+
let handle = handles.get(entry);
|
|
705
|
+
if (!handle) {
|
|
706
|
+
handle = {
|
|
707
|
+
...entry,
|
|
708
|
+
rpc: rpc.scope(entry.scope).rpc
|
|
709
|
+
};
|
|
710
|
+
handles.set(entry, handle);
|
|
711
|
+
}
|
|
712
|
+
return handle;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
//#endregion
|
|
609
717
|
//#region src/client/rpc-shared-state.ts
|
|
610
718
|
function createRpcSharedStateClientHost(rpc) {
|
|
611
719
|
const sharedState = /* @__PURE__ */ new Map();
|
|
@@ -622,7 +730,7 @@ function createRpcSharedStateClientHost(rpc) {
|
|
|
622
730
|
return serverState;
|
|
623
731
|
}
|
|
624
732
|
rpc.client.register({
|
|
625
|
-
name:
|
|
733
|
+
name: DEVFRAME_EVENTS.broadcast.clientStateUpdated,
|
|
626
734
|
type: "event",
|
|
627
735
|
handler: (key, fullState, syncId) => {
|
|
628
736
|
const state = sharedState.get(key);
|
|
@@ -631,7 +739,7 @@ function createRpcSharedStateClientHost(rpc) {
|
|
|
631
739
|
}
|
|
632
740
|
});
|
|
633
741
|
rpc.client.register({
|
|
634
|
-
name:
|
|
742
|
+
name: DEVFRAME_EVENTS.broadcast.clientStatePatch,
|
|
635
743
|
type: "event",
|
|
636
744
|
handler: (key, patches, syncId) => {
|
|
637
745
|
const state = sharedState.get(key);
|
|
@@ -698,7 +806,7 @@ function createRpcSharedStateClientHost(rpc) {
|
|
|
698
806
|
if (!rpc.isTrusted) {
|
|
699
807
|
resolve(state);
|
|
700
808
|
let initialized = false;
|
|
701
|
-
rpc.events.on(
|
|
809
|
+
rpc.events.on(DEVFRAME_EVENTS.client.isTrustedUpdated, (isTrusted) => {
|
|
702
810
|
if (isTrusted && !initialized) {
|
|
703
811
|
initialized = true;
|
|
704
812
|
initSharedState();
|
|
@@ -722,7 +830,6 @@ const EMPTY_WIRE_DEFS = /* @__PURE__ */ new Map();
|
|
|
722
830
|
* don't collide across connections.
|
|
723
831
|
*
|
|
724
832
|
* @internal
|
|
725
|
-
* implementations; not part of the stable public API.
|
|
726
833
|
*/
|
|
727
834
|
function createRpcWireCodec(definitions = EMPTY_WIRE_DEFS) {
|
|
728
835
|
const pendingRequestMethods = /* @__PURE__ */ new Map();
|
|
@@ -927,7 +1034,7 @@ function createLiveRpcClientMode(options) {
|
|
|
927
1034
|
if (next === status) return;
|
|
928
1035
|
const previous = status;
|
|
929
1036
|
status = next;
|
|
930
|
-
events.emit(
|
|
1037
|
+
events.emit(DEVFRAME_EVENTS.client.connectionStatus, next, previous);
|
|
931
1038
|
}
|
|
932
1039
|
const pending = /* @__PURE__ */ new Set();
|
|
933
1040
|
function rejectAllPending(error) {
|
|
@@ -949,7 +1056,7 @@ function createLiveRpcClientMode(options) {
|
|
|
949
1056
|
const entry = { reject(error) {
|
|
950
1057
|
if (settled) return;
|
|
951
1058
|
finish();
|
|
952
|
-
events.emit(
|
|
1059
|
+
events.emit(DEVFRAME_EVENTS.client.error, error, method);
|
|
953
1060
|
reject(error);
|
|
954
1061
|
} };
|
|
955
1062
|
function finish() {
|
|
@@ -969,7 +1076,7 @@ function createLiveRpcClientMode(options) {
|
|
|
969
1076
|
if (settled) return;
|
|
970
1077
|
finish();
|
|
971
1078
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
972
|
-
events.emit(
|
|
1079
|
+
events.emit(DEVFRAME_EVENTS.client.error, err, method);
|
|
973
1080
|
reject(err);
|
|
974
1081
|
});
|
|
975
1082
|
});
|
|
@@ -980,7 +1087,7 @@ function createLiveRpcClientMode(options) {
|
|
|
980
1087
|
definitions,
|
|
981
1088
|
onError(error) {
|
|
982
1089
|
setStatus("error", error);
|
|
983
|
-
events.emit(
|
|
1090
|
+
events.emit(DEVFRAME_EVENTS.client.connectionError, error);
|
|
984
1091
|
rejectAllPending(new DevframeConnectionError("connection", "[devframe] Connection to the devframe server failed", { cause: error }));
|
|
985
1092
|
},
|
|
986
1093
|
onDisconnected() {
|
|
@@ -993,15 +1100,15 @@ function createLiveRpcClientMode(options) {
|
|
|
993
1100
|
rpcOptions
|
|
994
1101
|
});
|
|
995
1102
|
clientRpc.register({
|
|
996
|
-
name:
|
|
1103
|
+
name: DEVFRAME_EVENTS.broadcast.authRevoked,
|
|
997
1104
|
type: "event",
|
|
998
1105
|
handler: () => {
|
|
999
1106
|
isTrusted = false;
|
|
1000
1107
|
const authError = new DevframeConnectionError("auth", "[devframe] The devframe server revoked this client's trust");
|
|
1001
1108
|
setStatus("unauthorized", authError);
|
|
1002
|
-
events.emit(
|
|
1109
|
+
events.emit(DEVFRAME_EVENTS.client.connectionError, authError);
|
|
1003
1110
|
rejectAllPending(authError);
|
|
1004
|
-
events.emit(
|
|
1111
|
+
events.emit(DEVFRAME_EVENTS.client.isTrustedUpdated, false);
|
|
1005
1112
|
}
|
|
1006
1113
|
});
|
|
1007
1114
|
let currentAuthToken = authToken;
|
|
@@ -1019,9 +1126,9 @@ function createLiveRpcClientMode(options) {
|
|
|
1019
1126
|
} else {
|
|
1020
1127
|
const authError = new DevframeConnectionError("auth", "[devframe] The devframe server refused this client's credentials");
|
|
1021
1128
|
setStatus("unauthorized", authError);
|
|
1022
|
-
events.emit(
|
|
1129
|
+
events.emit(DEVFRAME_EVENTS.client.connectionError, authError);
|
|
1023
1130
|
}
|
|
1024
|
-
events.emit(
|
|
1131
|
+
events.emit(DEVFRAME_EVENTS.client.isTrustedUpdated, isTrusted);
|
|
1025
1132
|
return result.isTrusted;
|
|
1026
1133
|
}
|
|
1027
1134
|
async function requestTrustWithCode(code) {
|
|
@@ -1035,7 +1142,7 @@ function createLiveRpcClientMode(options) {
|
|
|
1035
1142
|
isTrusted = true;
|
|
1036
1143
|
trustedPromise.resolve(true);
|
|
1037
1144
|
setStatus("connected");
|
|
1038
|
-
events.emit(
|
|
1145
|
+
events.emit(DEVFRAME_EVENTS.client.isTrustedUpdated, true);
|
|
1039
1146
|
}
|
|
1040
1147
|
return token;
|
|
1041
1148
|
}
|
|
@@ -1074,7 +1181,7 @@ function createLiveRpcClientMode(options) {
|
|
|
1074
1181
|
const method = String(args[0]);
|
|
1075
1182
|
const failFast = terminalError();
|
|
1076
1183
|
if (failFast) {
|
|
1077
|
-
events.emit(
|
|
1184
|
+
events.emit(DEVFRAME_EVENTS.client.error, failFast, method);
|
|
1078
1185
|
return Promise.reject(failFast);
|
|
1079
1186
|
}
|
|
1080
1187
|
return guardCall(serverRpc.$call(...args), method);
|
|
@@ -1082,7 +1189,7 @@ function createLiveRpcClientMode(options) {
|
|
|
1082
1189
|
callEvent: (...args) => {
|
|
1083
1190
|
const failFast = terminalError();
|
|
1084
1191
|
if (failFast) {
|
|
1085
|
-
events.emit(
|
|
1192
|
+
events.emit(DEVFRAME_EVENTS.client.error, failFast, String(args[0]));
|
|
1086
1193
|
return;
|
|
1087
1194
|
}
|
|
1088
1195
|
return serverRpc.$callEvent(...args);
|
|
@@ -1091,7 +1198,7 @@ function createLiveRpcClientMode(options) {
|
|
|
1091
1198
|
const method = String(args[0]);
|
|
1092
1199
|
const failFast = terminalError();
|
|
1093
1200
|
if (failFast) {
|
|
1094
|
-
events.emit(
|
|
1201
|
+
events.emit(DEVFRAME_EVENTS.client.error, failFast, method);
|
|
1095
1202
|
return Promise.reject(failFast);
|
|
1096
1203
|
}
|
|
1097
1204
|
return guardCall(serverRpc.$callOptional(...args), method);
|
|
@@ -1288,14 +1395,14 @@ function createRpcStreamingClientHost(rpc) {
|
|
|
1288
1395
|
const readers = /* @__PURE__ */ new Map();
|
|
1289
1396
|
const uploads = /* @__PURE__ */ new Map();
|
|
1290
1397
|
rpc.client.register({
|
|
1291
|
-
name:
|
|
1398
|
+
name: DEVFRAME_EVENTS.broadcast.streamingChunk,
|
|
1292
1399
|
type: "event",
|
|
1293
1400
|
handler(channel, id, seq, chunk) {
|
|
1294
1401
|
readers.get(streamKey(channel, id))?._push(seq, chunk);
|
|
1295
1402
|
}
|
|
1296
1403
|
});
|
|
1297
1404
|
rpc.client.register({
|
|
1298
|
-
name:
|
|
1405
|
+
name: DEVFRAME_EVENTS.broadcast.streamingEnd,
|
|
1299
1406
|
type: "event",
|
|
1300
1407
|
handler(channel, id, error) {
|
|
1301
1408
|
const key = streamKey(channel, id);
|
|
@@ -1306,7 +1413,7 @@ function createRpcStreamingClientHost(rpc) {
|
|
|
1306
1413
|
}
|
|
1307
1414
|
});
|
|
1308
1415
|
rpc.client.register({
|
|
1309
|
-
name:
|
|
1416
|
+
name: DEVFRAME_EVENTS.broadcast.streamingUploadCancel,
|
|
1310
1417
|
type: "event",
|
|
1311
1418
|
handler(channel, id) {
|
|
1312
1419
|
const key = streamKey(channel, id);
|
|
@@ -1316,7 +1423,7 @@ function createRpcStreamingClientHost(rpc) {
|
|
|
1316
1423
|
uploads.delete(key);
|
|
1317
1424
|
}
|
|
1318
1425
|
});
|
|
1319
|
-
rpc.events.on(
|
|
1426
|
+
rpc.events.on(DEVFRAME_EVENTS.client.isTrustedUpdated, (isTrusted) => {
|
|
1320
1427
|
if (!isTrusted) return;
|
|
1321
1428
|
for (const [key, reader] of readers) {
|
|
1322
1429
|
if (reader.cancelled || reader.done) continue;
|
|
@@ -1345,7 +1452,7 @@ function createRpcStreamingClientHost(rpc) {
|
|
|
1345
1452
|
readers.set(key, reader);
|
|
1346
1453
|
if (rpc.isTrusted) rpc.callEvent("devframe:streaming:subscribe", channel, id, { afterSeq: 0 });
|
|
1347
1454
|
else {
|
|
1348
|
-
const off = rpc.events.on(
|
|
1455
|
+
const off = rpc.events.on(DEVFRAME_EVENTS.client.isTrustedUpdated, (trusted) => {
|
|
1349
1456
|
if (trusted) {
|
|
1350
1457
|
off();
|
|
1351
1458
|
if (readers.has(key) && !reader.cancelled && !reader.done) rpc.callEvent("devframe:streaming:subscribe", channel, id, { afterSeq: reader.lastSeenSeq });
|
|
@@ -1738,6 +1845,7 @@ async function getDevframeRpcClient(options = {}) {
|
|
|
1738
1845
|
callOptional: gateOnBootstrapAuth(mode.callOptional),
|
|
1739
1846
|
client: clientRpc,
|
|
1740
1847
|
sharedState: void 0,
|
|
1848
|
+
services: void 0,
|
|
1741
1849
|
streaming: void 0,
|
|
1742
1850
|
cacheManager,
|
|
1743
1851
|
scope: void 0,
|
|
@@ -1745,6 +1853,7 @@ async function getDevframeRpcClient(options = {}) {
|
|
|
1745
1853
|
};
|
|
1746
1854
|
rpc.sharedState = createRpcSharedStateClientHost(rpc);
|
|
1747
1855
|
rpc.streaming = createRpcStreamingClientHost(rpc);
|
|
1856
|
+
rpc.services = createDevframeServicesClient(rpc);
|
|
1748
1857
|
const scopedCache = /* @__PURE__ */ new Map();
|
|
1749
1858
|
rpc.scope = ((namespace) => {
|
|
1750
1859
|
if (!namespace) return rpc;
|