devframe 0.2.2 → 0.2.3
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/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +6 -6
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +2 -2
- package/dist/adapters/dev.d.mts +2 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +3 -3
- package/dist/client/index.d.mts +18 -4
- package/dist/client/index.mjs +314 -8
- package/dist/{context-BDpuScNZ.d.mts → context-GUzIxrEK.d.mts} +1 -1
- package/dist/{dev-CZ9ZQkuO.mjs → dev-BVtS7qBK.mjs} +4 -4
- package/dist/{devframe-DAfZWnpI.d.mts → devframe-C4DNeFuG.d.mts} +3 -52
- package/dist/diagnostics-D7miaTpL.mjs +36 -0
- package/dist/{rpc-BlVCyk9W.mjs → dump-C5LPsKJC.mjs} +139 -126
- package/dist/helpers/vite.d.mts +1 -1
- package/dist/helpers/vite.mjs +3 -3
- package/dist/{host-h3-DEfOpa0j.mjs → host-h3-DYFKJxAV.mjs} +255 -7
- package/dist/human-id-CiBWzVcg.mjs +803 -0
- package/dist/{index-BNAsgVNz.d.mts → index-CSi2Y5JU.d.mts} +31 -78
- package/dist/index-DWczSqdd.d.mts +79 -0
- package/dist/index-aNunf5Za.d.mts +639 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +1 -2
- package/dist/node/index.d.mts +5 -5
- package/dist/node/index.mjs +3 -3
- package/dist/node/internal.d.mts +2 -2
- package/dist/node/internal.mjs +3 -4
- package/dist/recipes/open-helpers.d.mts +1 -1
- package/dist/recipes/open-helpers.mjs +2 -2
- package/dist/rpc/dump.d.mts +2 -0
- package/dist/rpc/dump.mjs +2 -0
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +129 -3
- package/dist/rpc/transports/ws-client.d.mts +25 -1
- package/dist/rpc/transports/ws-client.mjs +2 -2
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/rpc/transports/ws-server.mjs +2 -2
- package/dist/{serialization-CwO31axa.mjs → serialization-lBLV02kQ.mjs} +2 -36
- package/dist/{server-BGSrxsQb.d.mts → server-DjMtJQhO.d.mts} +1 -1
- package/dist/shared-state-SzgfilJP.mjs +1058 -0
- package/dist/{shared-state-BJXkPxtf.mjs → shared-state-u0y123fi.mjs} +6 -6
- package/dist/{storage-D-jLaxDA.mjs → storage-CTlHUtXI.mjs} +1 -2
- package/dist/structured-clone-qP1sPovr.mjs +208 -0
- package/dist/types/index.d.mts +3 -3
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/hash.mjs +1 -1
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/utils/structured-clone.mjs +1 -1
- package/dist/{ws-server-DKlqI8XP.d.mts → ws-server-lHQaafrS.d.mts} +1 -1
- package/package.json +2 -1
- package/dist/diagnostics-DNxVjo6X.mjs +0 -56
- package/dist/revoke-DDa7VSJa.mjs +0 -35
- package/dist/ws-client-CrLsflnY.d.mts +0 -26
- /package/dist/{_shared-CUFqO4kJ.mjs → _shared-BNoPn1NG.mjs} +0 -0
- /package/dist/{define-CW9gLnyG.mjs → define-Bb4zh-Dc.mjs} +0 -0
- /package/dist/{hash-CIBte1yS.mjs → hash-bwOD8RgU.mjs} +0 -0
- /package/dist/{open-DiQn6zCH.mjs → open-CX4CiMyw.mjs} +0 -0
- /package/dist/{server-BO8IDVsJ.mjs → server-DxiOFSpu.mjs} +0 -0
- /package/dist/{structured-clone-CD2l4fI3.mjs → structured-clone-PdCZwt7F.mjs} +0 -0
- /package/dist/{transports-DTFoMUbE.mjs → transports-Bl1zuYhZ.mjs} +0 -0
- /package/dist/{types-DmcujDa5.d.mts → types-kKDaD2NT.d.mts} +0 -0
package/dist/adapters/build.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as collectStaticRpcDump } from "../
|
|
2
|
-
import { n as strictJsonStringify } from "../serialization-CwO31axa.mjs";
|
|
1
|
+
import { t as collectStaticRpcDump } from "../dump-C5LPsKJC.mjs";
|
|
3
2
|
import { DEVTOOLS_CONNECTION_META_FILENAME, DEVTOOLS_RPC_DUMP_DIRNAME, DEVTOOLS_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
3
|
+
import { n as strictJsonStringify } from "../serialization-lBLV02kQ.mjs";
|
|
4
|
+
import { n as structuredCloneStringify } from "../structured-clone-qP1sPovr.mjs";
|
|
5
|
+
import { o as colors } from "../shared-state-SzgfilJP.mjs";
|
|
6
|
+
import { n as createHostContext, t as createH3DevToolsHost } from "../host-h3-DYFKJxAV.mjs";
|
|
7
|
+
import { n as resolveBasePath } from "../_shared-BNoPn1NG.mjs";
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
import process from "node:process";
|
|
10
10
|
import { dirname, resolve } from "pathe";
|
package/dist/adapters/cli.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as InferCliFlags, K as defineCliFlags, W as CliFlagsSchema, q as parseCliFlags, r as DevframeDefinition } from "../devframe-C4DNeFuG.mjs";
|
|
2
2
|
import { H3 } from "h3";
|
|
3
3
|
import { CAC } from "cac";
|
|
4
4
|
|
package/dist/adapters/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { colors } from "../
|
|
1
|
+
import { o as colors } from "../shared-state-SzgfilJP.mjs";
|
|
2
2
|
import { createBuild } from "./build.mjs";
|
|
3
|
-
import { n as resolveDevServerPort, t as createDevServer } from "../dev-
|
|
3
|
+
import { n as resolveDevServerPort, t as createDevServer } from "../dev-BVtS7qBK.mjs";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import cac from "cac";
|
|
6
6
|
import { safeParse } from "valibot";
|
package/dist/adapters/dev.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as DevframeDefinition } from "../devframe-
|
|
2
|
-
import { n as StartedServer } from "../server-
|
|
1
|
+
import { r as DevframeDefinition } from "../devframe-C4DNeFuG.mjs";
|
|
2
|
+
import { n as StartedServer } from "../server-DjMtJQhO.mjs";
|
|
3
3
|
import { H3 } from "h3";
|
|
4
4
|
|
|
5
5
|
//#region src/adapters/dev.d.ts
|
package/dist/adapters/dev.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as resolveDevServerPort, t as createDevServer } from "../dev-
|
|
1
|
+
import { n as resolveDevServerPort, t as createDevServer } from "../dev-BVtS7qBK.mjs";
|
|
2
2
|
export { createDevServer, resolveDevServerPort };
|
package/dist/adapters/mcp.d.mts
CHANGED
package/dist/adapters/mcp.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as createHostContext } from "../host-h3-
|
|
1
|
+
import { a as logger } from "../shared-state-SzgfilJP.mjs";
|
|
2
|
+
import { n as createHostContext } from "../host-h3-DYFKJxAV.mjs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import { join } from "pathe";
|
|
@@ -204,7 +204,7 @@ async function createMcpServer(definition, options = {}) {
|
|
|
204
204
|
serverVersion: options.serverVersion ?? definition.version ?? "0.0.0",
|
|
205
205
|
exposeSharedState: options.exposeSharedState ?? true
|
|
206
206
|
});
|
|
207
|
-
const { startStdioTransport } = await import("../transports-
|
|
207
|
+
const { startStdioTransport } = await import("../transports-Bl1zuYhZ.mjs");
|
|
208
208
|
let stop;
|
|
209
209
|
try {
|
|
210
210
|
stop = await startStdioTransport(server);
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as RpcCacheManager, w as RpcCacheOptions } from "../index-BNAsgVNz.mjs";
|
|
3
|
-
import { C as RpcFunctionsCollector } from "../types-DmcujDa5.mjs";
|
|
4
|
-
import { t as WsRpcChannelOptions } from "../ws-client-CrLsflnY.mjs";
|
|
1
|
+
import { D as RpcCacheOptions, E as RpcCacheManager, O as RpcFunctionDefinitionAny, i as DevToolsRpcServerFunctions, k as RpcFunctionsCollector, l as StreamReader, n as RpcSharedStateHost, r as DevToolsRpcClientFunctions, t as ConnectionMeta, u as StreamSink, w as EventEmitter } from "../index-aNunf5Za.mjs";
|
|
5
2
|
import { BirpcOptions, BirpcReturn } from "birpc";
|
|
6
3
|
|
|
4
|
+
//#region src/rpc/transports/ws-client.d.ts
|
|
5
|
+
interface WsRpcChannelOptions {
|
|
6
|
+
url: string;
|
|
7
|
+
onConnected?: (e: Event) => void;
|
|
8
|
+
onError?: (e: Error) => void;
|
|
9
|
+
onDisconnected?: (e: CloseEvent) => void;
|
|
10
|
+
authToken?: string;
|
|
11
|
+
/**
|
|
12
|
+
* RPC function definitions (or just the `jsonSerializable` flag per
|
|
13
|
+
* method) used to dispatch the per-call wire serializer. Pass an
|
|
14
|
+
* empty / partial map on clients that don't have the full registry —
|
|
15
|
+
* encoding falls back to structured-clone (the safer superset) and
|
|
16
|
+
* decoding still routes correctly via the wire prefix.
|
|
17
|
+
*/
|
|
18
|
+
definitions?: ReadonlyMap<string, Pick<RpcFunctionDefinitionAny, 'jsonSerializable'>>;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
7
21
|
//#region src/client/rpc-streaming.d.ts
|
|
8
22
|
interface StreamingSubscribeOptions {
|
|
9
23
|
/** Maximum buffered chunks before the oldest is dropped. Default 256. */
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,14 +1,253 @@
|
|
|
1
|
-
import { t as hash } from "../hash-
|
|
2
|
-
import { a as reviveDumpError, f as RpcCacheManager, l as RpcFunctionsCollectorBase } from "../rpc-BlVCyk9W.mjs";
|
|
3
|
-
import { DEVTOOLS_CONNECTION_META_FILENAME, DEVTOOLS_RPC_DUMP_MANIFEST_FILENAME } from "../constants.mjs";
|
|
4
|
-
import { createRpcClient } from "../rpc/client.mjs";
|
|
5
|
-
import { t as structuredCloneDeserialize } from "../structured-clone-CD2l4fI3.mjs";
|
|
6
|
-
import { createWsRpcChannel } from "../rpc/transports/ws-client.mjs";
|
|
1
|
+
import { t as hash } from "../hash-bwOD8RgU.mjs";
|
|
7
2
|
import { createEventEmitter } from "../utils/events.mjs";
|
|
8
|
-
import { t as createSharedState } from "../shared-state-BJXkPxtf.mjs";
|
|
9
|
-
import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
|
|
10
3
|
import { humanId } from "../utils/human-id.mjs";
|
|
4
|
+
import { t as createSharedState } from "../shared-state-u0y123fi.mjs";
|
|
5
|
+
import { i as structuredCloneStringify, n as structuredCloneParse, t as structuredCloneDeserialize } from "../structured-clone-PdCZwt7F.mjs";
|
|
6
|
+
import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
|
|
11
7
|
import { promiseWithResolver } from "../utils/promise.mjs";
|
|
8
|
+
import { consoleReporter, createLogger, defineDiagnostics, plainFormatter } from "logs-sdk";
|
|
9
|
+
import { createBirpc } from "birpc";
|
|
10
|
+
//#region src/constants.ts
|
|
11
|
+
const DEVTOOLS_CONNECTION_META_FILENAME = "__connection.json";
|
|
12
|
+
const DEVTOOLS_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
|
|
13
|
+
const logger = createLogger({
|
|
14
|
+
diagnostics: [defineDiagnostics({
|
|
15
|
+
docsBase: "https://devfra.me/errors",
|
|
16
|
+
codes: {
|
|
17
|
+
DF0019: {
|
|
18
|
+
message: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\` — MCP requires JSON-serializable data.`,
|
|
19
|
+
hint: "Set `jsonSerializable: true` if the payload is JSON-safe, or remove `agent` to keep it RPC-only."
|
|
20
|
+
},
|
|
21
|
+
DF0020: {
|
|
22
|
+
message: (p) => `RPC function "${p.name}" declares \`jsonSerializable: true\` but the value at "${p.path}" is a ${p.type}.`,
|
|
23
|
+
hint: "Either drop `jsonSerializable: true` (falls back to structured-clone) or change the value to a JSON-safe shape."
|
|
24
|
+
},
|
|
25
|
+
DF0021: {
|
|
26
|
+
message: (p) => `RPC function "${p.name}" is already registered`,
|
|
27
|
+
hint: "Use the `force` parameter to overwrite an existing registration."
|
|
28
|
+
},
|
|
29
|
+
DF0022: { message: (p) => `RPC function "${p.name}" is not registered. Use register() to add new functions.` },
|
|
30
|
+
DF0023: { message: (p) => `RPC function "${p.name}" is not registered` },
|
|
31
|
+
DF0024: { message: (p) => `Either handler or setup function must be provided for RPC function "${p.name}"` },
|
|
32
|
+
DF0025: { message: (p) => `Function "${p.name}" not found in dump store` },
|
|
33
|
+
DF0026: { message: (p) => `No dump match for "${p.name}" with args: ${p.args}` },
|
|
34
|
+
DF0027: { message: (p) => `Function "${p.name}" with type "${p.type}" cannot have dump configuration. Only "static" and "query" types support dumps.` },
|
|
35
|
+
DF0028: {
|
|
36
|
+
message: (p) => `Function "${p.name}" with type "${p.type}" cannot use \`snapshot: true\`. Only "query" functions support this sugar; "static" functions have equivalent default behavior already.`,
|
|
37
|
+
hint: "Remove `snapshot: true`, or change the function type to `query`."
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
})],
|
|
41
|
+
formatter: plainFormatter,
|
|
42
|
+
reporters: consoleReporter
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/rpc/dump/error.ts
|
|
46
|
+
/**
|
|
47
|
+
* Inverse of {@link serializeDumpError}: rebuild a thrown `Error` from
|
|
48
|
+
* the plain object stored in a dump record. Preserves `cause`, restores
|
|
49
|
+
* the original `name`, and re-attaches any custom own properties.
|
|
50
|
+
*/
|
|
51
|
+
function reviveDumpError(stored) {
|
|
52
|
+
const cause = stored.cause instanceof Error ? stored.cause : isPlainErrorShape(stored.cause) ? reviveDumpError(stored.cause) : stored.cause;
|
|
53
|
+
const error = cause !== void 0 ? new Error(stored.message, { cause }) : new Error(stored.message);
|
|
54
|
+
error.name = stored.name;
|
|
55
|
+
for (const key of Object.keys(stored)) {
|
|
56
|
+
if (key === "name" || key === "message" || key === "cause") continue;
|
|
57
|
+
error[key] = stored[key];
|
|
58
|
+
}
|
|
59
|
+
return error;
|
|
60
|
+
}
|
|
61
|
+
function isPlainErrorShape(value) {
|
|
62
|
+
return typeof value === "object" && value !== null && typeof value.message === "string" && typeof value.name === "string";
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/rpc/handler.ts
|
|
66
|
+
async function getRpcResolvedSetupResult(definition, context) {
|
|
67
|
+
if (definition.__resolved) return definition.__resolved;
|
|
68
|
+
if (!definition.setup) return {};
|
|
69
|
+
definition.__promise ??= Promise.resolve(definition.setup(context)).then((r) => {
|
|
70
|
+
definition.__resolved = r;
|
|
71
|
+
definition.__promise = void 0;
|
|
72
|
+
return r;
|
|
73
|
+
});
|
|
74
|
+
return definition.__resolved ??= await definition.__promise;
|
|
75
|
+
}
|
|
76
|
+
async function getRpcHandler(definition, context) {
|
|
77
|
+
if (definition.handler) return definition.handler;
|
|
78
|
+
const result = await getRpcResolvedSetupResult(definition, context);
|
|
79
|
+
if (!result.handler) throw logger.DF0024({ name: definition.name }).throw();
|
|
80
|
+
return result.handler;
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/rpc/cache.ts
|
|
84
|
+
/**
|
|
85
|
+
* @experimental API is expected to change.
|
|
86
|
+
*/
|
|
87
|
+
var RpcCacheManager = class {
|
|
88
|
+
cacheMap = /* @__PURE__ */ new Map();
|
|
89
|
+
options;
|
|
90
|
+
keySerializer;
|
|
91
|
+
constructor(options) {
|
|
92
|
+
this.options = options;
|
|
93
|
+
this.keySerializer = options.keySerializer || ((args) => hash(args));
|
|
94
|
+
}
|
|
95
|
+
updateOptions(options) {
|
|
96
|
+
this.options = {
|
|
97
|
+
...this.options,
|
|
98
|
+
...options
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
cached(m, a) {
|
|
102
|
+
const methodCache = this.cacheMap.get(m);
|
|
103
|
+
if (methodCache) return methodCache.get(this.keySerializer(a));
|
|
104
|
+
}
|
|
105
|
+
apply(req, res) {
|
|
106
|
+
const methodCache = this.cacheMap.get(req.m) || /* @__PURE__ */ new Map();
|
|
107
|
+
methodCache.set(this.keySerializer(req.a), res);
|
|
108
|
+
this.cacheMap.set(req.m, methodCache);
|
|
109
|
+
}
|
|
110
|
+
validate(m) {
|
|
111
|
+
return this.options.functions.includes(m);
|
|
112
|
+
}
|
|
113
|
+
clear(fn) {
|
|
114
|
+
if (fn) this.cacheMap.delete(fn);
|
|
115
|
+
else this.cacheMap.clear();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/rpc/collector.ts
|
|
120
|
+
var RpcFunctionsCollectorBase = class {
|
|
121
|
+
context;
|
|
122
|
+
definitions = /* @__PURE__ */ new Map();
|
|
123
|
+
functions;
|
|
124
|
+
_onChanged = [];
|
|
125
|
+
constructor(context) {
|
|
126
|
+
this.context = context;
|
|
127
|
+
const definitions = this.definitions;
|
|
128
|
+
const self = this;
|
|
129
|
+
this.functions = new Proxy({}, {
|
|
130
|
+
get(_, prop) {
|
|
131
|
+
const definition = definitions.get(prop);
|
|
132
|
+
if (!definition) return void 0;
|
|
133
|
+
return getRpcHandler(definition, self.context);
|
|
134
|
+
},
|
|
135
|
+
has(_, prop) {
|
|
136
|
+
return definitions.has(prop);
|
|
137
|
+
},
|
|
138
|
+
getOwnPropertyDescriptor(_, prop) {
|
|
139
|
+
return {
|
|
140
|
+
value: definitions.get(prop)?.handler,
|
|
141
|
+
configurable: true,
|
|
142
|
+
enumerable: true
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
ownKeys() {
|
|
146
|
+
return Array.from(definitions.keys());
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
register(fn, force = false) {
|
|
151
|
+
if (this.definitions.has(fn.name) && !force) throw logger.DF0021({ name: fn.name }).throw();
|
|
152
|
+
assertAgentJsonSerializable(fn);
|
|
153
|
+
this.definitions.set(fn.name, fn);
|
|
154
|
+
this._onChanged.forEach((cb) => cb(fn.name));
|
|
155
|
+
}
|
|
156
|
+
update(fn, force = false) {
|
|
157
|
+
if (!this.definitions.has(fn.name) && !force) throw logger.DF0022({ name: fn.name }).throw();
|
|
158
|
+
assertAgentJsonSerializable(fn);
|
|
159
|
+
this.definitions.set(fn.name, fn);
|
|
160
|
+
this._onChanged.forEach((cb) => cb(fn.name));
|
|
161
|
+
}
|
|
162
|
+
onChanged(fn) {
|
|
163
|
+
this._onChanged.push(fn);
|
|
164
|
+
return () => {
|
|
165
|
+
const index = this._onChanged.indexOf(fn);
|
|
166
|
+
if (index !== -1) this._onChanged.splice(index, 1);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async getHandler(name) {
|
|
170
|
+
return await getRpcHandler(this.definitions.get(name), this.context);
|
|
171
|
+
}
|
|
172
|
+
getSchema(name) {
|
|
173
|
+
const definition = this.definitions.get(name);
|
|
174
|
+
if (!definition) throw logger.DF0023({ name: String(name) }).throw();
|
|
175
|
+
return {
|
|
176
|
+
args: definition.args,
|
|
177
|
+
returns: definition.returns
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
has(name) {
|
|
181
|
+
return this.definitions.has(name);
|
|
182
|
+
}
|
|
183
|
+
get(name) {
|
|
184
|
+
return this.definitions.get(name);
|
|
185
|
+
}
|
|
186
|
+
list() {
|
|
187
|
+
return Array.from(this.definitions.keys());
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
function assertAgentJsonSerializable(fn) {
|
|
191
|
+
if (fn.agent && fn.jsonSerializable !== true) throw logger.DF0019({ name: fn.name }).throw();
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region src/rpc/serialization.ts
|
|
195
|
+
/**
|
|
196
|
+
* `JSON.stringify` with a single-pass strict replacer.
|
|
197
|
+
*
|
|
198
|
+
* Throws `DF0020` synchronously when the value contains a type JSON
|
|
199
|
+
* cannot round-trip losslessly: `Map`, `Set`, `Date`, `BigInt`, class
|
|
200
|
+
* instances, or `undefined` inside an array (silently becomes `null`).
|
|
201
|
+
*
|
|
202
|
+
* Native pass-throughs (no extra work needed):
|
|
203
|
+
* - circular references — `JSON.stringify` raises `TypeError`.
|
|
204
|
+
* - `BigInt` at top level — caught here for a friendlier error path.
|
|
205
|
+
*
|
|
206
|
+
* Lenient cases (allowed without throwing):
|
|
207
|
+
* - `undefined` as an object property — legitimate optional field;
|
|
208
|
+
* JSON.stringify just omits it.
|
|
209
|
+
* - `undefined` at the root — legitimate "action returned nothing".
|
|
210
|
+
* - `Symbol` / `Function` values — semantically "drop me" in JSON.
|
|
211
|
+
*
|
|
212
|
+
* `fnName` is used only for the diagnostic message — pass the RPC
|
|
213
|
+
* function name when calling from a wire serializer / dump writer so
|
|
214
|
+
* the error points at the offending function.
|
|
215
|
+
*/
|
|
216
|
+
function strictJsonStringify(value, fnName = "") {
|
|
217
|
+
return JSON.stringify(value, function strictReplacer(key, val) {
|
|
218
|
+
const holder = this;
|
|
219
|
+
const original = holder != null ? holder[key] : val;
|
|
220
|
+
if (original === void 0) {
|
|
221
|
+
if (Array.isArray(holder)) throw nonJsonAt(fnName, "undefined", holder, key);
|
|
222
|
+
return val;
|
|
223
|
+
}
|
|
224
|
+
if (original === null) return val;
|
|
225
|
+
if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
|
|
226
|
+
if (typeof original === "object") {
|
|
227
|
+
if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
|
|
228
|
+
if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
|
|
229
|
+
if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
|
|
230
|
+
if (Array.isArray(original)) return val;
|
|
231
|
+
const proto = Object.getPrototypeOf(original);
|
|
232
|
+
if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
|
|
233
|
+
}
|
|
234
|
+
return val;
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
function nonJsonAt(fnName, type, parent, key) {
|
|
238
|
+
const path = formatPath(parent, key);
|
|
239
|
+
return logger.DF0020({
|
|
240
|
+
name: fnName || "<anonymous>",
|
|
241
|
+
type,
|
|
242
|
+
path
|
|
243
|
+
}).throw();
|
|
244
|
+
}
|
|
245
|
+
function formatPath(parent, key) {
|
|
246
|
+
if (Array.isArray(parent)) return `[${key}]`;
|
|
247
|
+
if (key === "") return "<root>";
|
|
248
|
+
return key;
|
|
249
|
+
}
|
|
250
|
+
//#endregion
|
|
12
251
|
//#region src/client/rpc-shared-state.ts
|
|
13
252
|
function createRpcSharedStateClientHost(rpc) {
|
|
14
253
|
const sharedState = /* @__PURE__ */ new Map();
|
|
@@ -273,6 +512,73 @@ function createRpcStreamingClientHost(rpc) {
|
|
|
273
512
|
};
|
|
274
513
|
}
|
|
275
514
|
//#endregion
|
|
515
|
+
//#region src/rpc/client.ts
|
|
516
|
+
function createRpcClient(functions, options) {
|
|
517
|
+
const { channel, rpcOptions = {} } = options;
|
|
518
|
+
return createBirpc(functions, {
|
|
519
|
+
...channel,
|
|
520
|
+
timeout: -1,
|
|
521
|
+
...rpcOptions,
|
|
522
|
+
proxify: false
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
//#endregion
|
|
526
|
+
//#region src/rpc/transports/ws-client.ts
|
|
527
|
+
function NOOP() {}
|
|
528
|
+
const EMPTY_DEFS = /* @__PURE__ */ new Map();
|
|
529
|
+
/**
|
|
530
|
+
* Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
|
|
531
|
+
* Pass the result straight to `createRpcClient`'s `channel` option.
|
|
532
|
+
*/
|
|
533
|
+
function createWsRpcChannel(options) {
|
|
534
|
+
let url = options.url;
|
|
535
|
+
if (options.authToken) url = `${url}?vite_devtools_auth_token=${encodeURIComponent(options.authToken)}`;
|
|
536
|
+
const ws = new WebSocket(url);
|
|
537
|
+
const { onConnected = NOOP, onError = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS } = options;
|
|
538
|
+
ws.addEventListener("open", (e) => {
|
|
539
|
+
onConnected(e);
|
|
540
|
+
});
|
|
541
|
+
ws.addEventListener("error", (e) => {
|
|
542
|
+
onError(e instanceof Error ? e : new Error(e.type));
|
|
543
|
+
});
|
|
544
|
+
ws.addEventListener("close", (e) => {
|
|
545
|
+
onDisconnected(e);
|
|
546
|
+
});
|
|
547
|
+
const pendingRequestMethods = /* @__PURE__ */ new Map();
|
|
548
|
+
return {
|
|
549
|
+
on: (handler) => {
|
|
550
|
+
ws.addEventListener("message", (e) => {
|
|
551
|
+
handler(e.data);
|
|
552
|
+
});
|
|
553
|
+
},
|
|
554
|
+
post: (data) => {
|
|
555
|
+
if (ws.readyState === WebSocket.OPEN) ws.send(data);
|
|
556
|
+
else {
|
|
557
|
+
function handler() {
|
|
558
|
+
ws.send(data);
|
|
559
|
+
ws.removeEventListener("open", handler);
|
|
560
|
+
}
|
|
561
|
+
ws.addEventListener("open", handler);
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
serialize: (msg) => {
|
|
565
|
+
let method;
|
|
566
|
+
if (msg.t === "q") method = msg.m;
|
|
567
|
+
else {
|
|
568
|
+
method = pendingRequestMethods.get(msg.i);
|
|
569
|
+
pendingRequestMethods.delete(msg.i);
|
|
570
|
+
}
|
|
571
|
+
if (!(msg.t === "s" && "e" in msg) && !!method && definitions.get(method)?.jsonSerializable === true) return strictJsonStringify(msg, method ?? "");
|
|
572
|
+
return `s:${structuredCloneStringify(msg)}`;
|
|
573
|
+
},
|
|
574
|
+
deserialize: (raw) => {
|
|
575
|
+
const msg = raw.startsWith("s:") ? structuredCloneParse(raw.slice(2)) : JSON.parse(raw);
|
|
576
|
+
if (msg.t === "q" && msg.i && msg.m) pendingRequestMethods.set(msg.i, msg.m);
|
|
577
|
+
return msg;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
//#endregion
|
|
276
582
|
//#region ../../node_modules/.pnpm/ua-parser-modern@0.1.1/node_modules/ua-parser-modern/dist/index.mjs
|
|
277
583
|
const EMPTY = "";
|
|
278
584
|
const UNKNOWN = "?";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DEVTOOLS_CONNECTION_META_FILENAME } from "./constants.mjs";
|
|
2
|
-
import { n as createHostContext, t as createH3DevToolsHost } from "./host-h3-
|
|
3
|
-
import { t as startHttpAndWs } from "./server-
|
|
4
|
-
import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-
|
|
5
|
-
import { t as open } from "./open-
|
|
2
|
+
import { n as createHostContext, t as createH3DevToolsHost } from "./host-h3-DYFKJxAV.mjs";
|
|
3
|
+
import { t as startHttpAndWs } from "./server-DxiOFSpu.mjs";
|
|
4
|
+
import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-BNoPn1NG.mjs";
|
|
5
|
+
import { t as open } from "./open-CX4CiMyw.mjs";
|
|
6
6
|
import { mountStaticHandler } from "./utils/serve-static.mjs";
|
|
7
7
|
import { networkInterfaces } from "node:os";
|
|
8
8
|
import process$1 from "node:process";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as RpcFunctionsCollectorBase } from "./index-
|
|
2
|
-
import { t as DevToolsNodeRpcSessionMeta } from "./ws-server-
|
|
1
|
+
import { S as RpcFunctionsCollectorBase } from "./index-CSi2Y5JU.mjs";
|
|
2
|
+
import { t as DevToolsNodeRpcSessionMeta } from "./ws-server-lHQaafrS.mjs";
|
|
3
3
|
import { Logger, createLogger, defineDiagnostics } from "logs-sdk";
|
|
4
4
|
import { BirpcReturn } from "birpc";
|
|
5
5
|
import { CAC } from "cac";
|
|
@@ -564,19 +564,6 @@ interface SharedState<T> {
|
|
|
564
564
|
interface SharedStateEvents<T> {
|
|
565
565
|
updated: (fullState: T, patches: SharedStatePatch[] | undefined, syncId: string) => void;
|
|
566
566
|
}
|
|
567
|
-
interface SharedStateOptions<T> {
|
|
568
|
-
/**
|
|
569
|
-
* Initial state.
|
|
570
|
-
*/
|
|
571
|
-
initialValue: T;
|
|
572
|
-
/**
|
|
573
|
-
* Enable patches.
|
|
574
|
-
*
|
|
575
|
-
* @default false
|
|
576
|
-
*/
|
|
577
|
-
enablePatches?: boolean;
|
|
578
|
-
}
|
|
579
|
-
declare function createSharedState<T extends object>(options: SharedStateOptions<T>): SharedState<T>;
|
|
580
567
|
//#endregion
|
|
581
568
|
//#region src/utils/streaming-channel.d.ts
|
|
582
569
|
/**
|
|
@@ -604,14 +591,6 @@ interface StreamSinkEvents<T> {
|
|
|
604
591
|
/** Terminal — fired exactly once per sink lifetime. */
|
|
605
592
|
end: (error?: StreamErrorPayload) => void;
|
|
606
593
|
}
|
|
607
|
-
interface CreateStreamSinkOptions {
|
|
608
|
-
id?: string;
|
|
609
|
-
/**
|
|
610
|
-
* Size of the per-stream ring buffer kept for replay-on-resubscribe.
|
|
611
|
-
* `0` (default) disables replay.
|
|
612
|
-
*/
|
|
613
|
-
replayWindow?: number;
|
|
614
|
-
}
|
|
615
594
|
/**
|
|
616
595
|
* Server-side producer handle. Two equivalent surfaces share one piece of
|
|
617
596
|
* state: the imperative `write/error/close` triple, and a `WritableStream<T>`
|
|
@@ -652,22 +631,6 @@ interface StreamSink<T> {
|
|
|
652
631
|
*/
|
|
653
632
|
readonly buffer: ReadonlyArray<BufferedChunk<T>>;
|
|
654
633
|
}
|
|
655
|
-
interface CreateStreamReaderOptions {
|
|
656
|
-
id?: string;
|
|
657
|
-
/**
|
|
658
|
-
* Maximum number of buffered chunks held client-side while the consumer
|
|
659
|
-
* isn't draining. On overflow, the oldest chunk is dropped.
|
|
660
|
-
*/
|
|
661
|
-
highWaterMark?: number;
|
|
662
|
-
/**
|
|
663
|
-
* Called when the chunk queue overflows the high-water mark. The RPC
|
|
664
|
-
* layer wires this to a coded warning; the primitive itself is
|
|
665
|
-
* RPC-agnostic.
|
|
666
|
-
*/
|
|
667
|
-
onOverflow?: (dropped: number) => void;
|
|
668
|
-
/** Called when the consumer cancels — the RPC layer sends `:cancel` upstream. */
|
|
669
|
-
onCancel?: () => void;
|
|
670
|
-
}
|
|
671
634
|
/**
|
|
672
635
|
* Client-side consumer handle. Both an `AsyncIterable<T>` (for `for await`)
|
|
673
636
|
* and exposes `readable: ReadableStream<T>` (for `pipeTo`). Pick one — they
|
|
@@ -687,18 +650,6 @@ interface StreamReader<T> extends AsyncIterable<T> {
|
|
|
687
650
|
/** @internal */
|
|
688
651
|
_end: (error?: StreamErrorPayload) => void;
|
|
689
652
|
}
|
|
690
|
-
/**
|
|
691
|
-
* Build a server-side stream sink. RPC-agnostic — the RPC host wires
|
|
692
|
-
* `events.on('chunk' | 'end')` to broadcast, and reads `buffer` to replay
|
|
693
|
-
* for late or reconnecting subscribers.
|
|
694
|
-
*/
|
|
695
|
-
declare function createStreamSink<T>(options?: CreateStreamSinkOptions): StreamSink<T>;
|
|
696
|
-
/**
|
|
697
|
-
* Build a client-side stream reader. RPC-agnostic — the RPC host calls
|
|
698
|
-
* `_push(seq, chunk)` on each incoming chunk and `_end(error?)` on the
|
|
699
|
-
* terminal frame. Consumers iterate with `for await` or pipe `readable`.
|
|
700
|
-
*/
|
|
701
|
-
declare function createStreamReader<T>(options?: CreateStreamReaderOptions): StreamReader<T>;
|
|
702
653
|
//#endregion
|
|
703
654
|
//#region src/types/rpc.d.ts
|
|
704
655
|
interface DevToolsNodeRpcSession {
|
|
@@ -1047,4 +998,4 @@ interface DevframeDefinition {
|
|
|
1047
998
|
}
|
|
1048
999
|
declare function defineDevframe(d: DevframeDefinition): DevframeDefinition;
|
|
1049
1000
|
//#endregion
|
|
1050
|
-
export {
|
|
1001
|
+
export { DevToolsDiagnosticsHost as A, DevToolsAgentHostEvents as B, PartialWithoutId as C, DevToolsRpcSharedStates as D, DevToolsRpcServerFunctions as E, AgentResourceContent as F, InferCliFlags as G, EventUnsubscribe as H, AgentResourceInput as I, defineCliFlags as K, AgentTool as L, AgentHandle as M, AgentManifest as N, DevToolsHost as O, AgentResource as P, AgentToolInput as R, EntriesToObject as S, DevToolsRpcClientFunctions as T, EventsMap as U, EventEmitter as V, CliFlagsSchema as W, RpcStreamingChannel as _, DevframeRuntime as a, SharedState as b, defineDevframe as c, DevToolsNodeContext as d, DevToolsNodeRpcSession as f, RpcSharedStateHost as g, RpcSharedStateGetOptions as h, DevframeDeploymentKind as i, DevToolsDiagnosticsLogger as j, DevToolsDiagnosticsDefinition as k, ConnectionMeta as l, RpcFunctionsHost as m, DevframeCliOptions as n, DevframeSetupInfo as o, RpcBroadcastOptions as p, parseCliFlags as q, DevframeDefinition as r, DevframeSpaOptions as s, DevframeBrowserContext as t, DevToolsCapabilities as u, RpcStreamingChannelOptions as v, Thenable as w, DevToolsViewHost as x, RpcStreamingHost as y, DevToolsAgentHost as z };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { consoleReporter, createLogger, defineDiagnostics, plainFormatter } from "logs-sdk";
|
|
2
|
+
//#region src/rpc/diagnostics.ts
|
|
3
|
+
const diagnostics = defineDiagnostics({
|
|
4
|
+
docsBase: "https://devfra.me/errors",
|
|
5
|
+
codes: {
|
|
6
|
+
DF0019: {
|
|
7
|
+
message: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\` — MCP requires JSON-serializable data.`,
|
|
8
|
+
hint: "Set `jsonSerializable: true` if the payload is JSON-safe, or remove `agent` to keep it RPC-only."
|
|
9
|
+
},
|
|
10
|
+
DF0020: {
|
|
11
|
+
message: (p) => `RPC function "${p.name}" declares \`jsonSerializable: true\` but the value at "${p.path}" is a ${p.type}.`,
|
|
12
|
+
hint: "Either drop `jsonSerializable: true` (falls back to structured-clone) or change the value to a JSON-safe shape."
|
|
13
|
+
},
|
|
14
|
+
DF0021: {
|
|
15
|
+
message: (p) => `RPC function "${p.name}" is already registered`,
|
|
16
|
+
hint: "Use the `force` parameter to overwrite an existing registration."
|
|
17
|
+
},
|
|
18
|
+
DF0022: { message: (p) => `RPC function "${p.name}" is not registered. Use register() to add new functions.` },
|
|
19
|
+
DF0023: { message: (p) => `RPC function "${p.name}" is not registered` },
|
|
20
|
+
DF0024: { message: (p) => `Either handler or setup function must be provided for RPC function "${p.name}"` },
|
|
21
|
+
DF0025: { message: (p) => `Function "${p.name}" not found in dump store` },
|
|
22
|
+
DF0026: { message: (p) => `No dump match for "${p.name}" with args: ${p.args}` },
|
|
23
|
+
DF0027: { message: (p) => `Function "${p.name}" with type "${p.type}" cannot have dump configuration. Only "static" and "query" types support dumps.` },
|
|
24
|
+
DF0028: {
|
|
25
|
+
message: (p) => `Function "${p.name}" with type "${p.type}" cannot use \`snapshot: true\`. Only "query" functions support this sugar; "static" functions have equivalent default behavior already.`,
|
|
26
|
+
hint: "Remove `snapshot: true`, or change the function type to `query`."
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const logger = createLogger({
|
|
31
|
+
diagnostics: [diagnostics],
|
|
32
|
+
formatter: plainFormatter,
|
|
33
|
+
reporters: consoleReporter
|
|
34
|
+
});
|
|
35
|
+
//#endregion
|
|
36
|
+
export { logger as n, diagnostics as t };
|