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.
Files changed (68) hide show
  1. package/dist/adapters/build.d.mts +1 -1
  2. package/dist/adapters/build.mjs +6 -6
  3. package/dist/adapters/cli.d.mts +1 -1
  4. package/dist/adapters/cli.mjs +2 -2
  5. package/dist/adapters/dev.d.mts +2 -2
  6. package/dist/adapters/dev.mjs +1 -1
  7. package/dist/adapters/embedded.d.mts +1 -1
  8. package/dist/adapters/mcp.d.mts +1 -1
  9. package/dist/adapters/mcp.mjs +3 -3
  10. package/dist/client/index.d.mts +18 -4
  11. package/dist/client/index.mjs +314 -8
  12. package/dist/{context-BDpuScNZ.d.mts → context-GUzIxrEK.d.mts} +1 -1
  13. package/dist/{dev-CZ9ZQkuO.mjs → dev-BVtS7qBK.mjs} +4 -4
  14. package/dist/{devframe-DAfZWnpI.d.mts → devframe-C4DNeFuG.d.mts} +3 -52
  15. package/dist/diagnostics-D7miaTpL.mjs +36 -0
  16. package/dist/{rpc-BlVCyk9W.mjs → dump-C5LPsKJC.mjs} +139 -126
  17. package/dist/helpers/vite.d.mts +1 -1
  18. package/dist/helpers/vite.mjs +3 -3
  19. package/dist/{host-h3-DEfOpa0j.mjs → host-h3-DYFKJxAV.mjs} +255 -7
  20. package/dist/human-id-CiBWzVcg.mjs +803 -0
  21. package/dist/{index-BNAsgVNz.d.mts → index-CSi2Y5JU.d.mts} +31 -78
  22. package/dist/index-DWczSqdd.d.mts +79 -0
  23. package/dist/index-aNunf5Za.d.mts +639 -0
  24. package/dist/index.d.mts +3 -3
  25. package/dist/index.mjs +1 -1
  26. package/dist/node/auth.d.mts +2 -2
  27. package/dist/node/auth.mjs +1 -2
  28. package/dist/node/index.d.mts +5 -5
  29. package/dist/node/index.mjs +3 -3
  30. package/dist/node/internal.d.mts +2 -2
  31. package/dist/node/internal.mjs +3 -4
  32. package/dist/recipes/open-helpers.d.mts +1 -1
  33. package/dist/recipes/open-helpers.mjs +2 -2
  34. package/dist/rpc/dump.d.mts +2 -0
  35. package/dist/rpc/dump.mjs +2 -0
  36. package/dist/rpc/index.d.mts +2 -2
  37. package/dist/rpc/index.mjs +129 -3
  38. package/dist/rpc/transports/ws-client.d.mts +25 -1
  39. package/dist/rpc/transports/ws-client.mjs +2 -2
  40. package/dist/rpc/transports/ws-server.d.mts +1 -1
  41. package/dist/rpc/transports/ws-server.mjs +2 -2
  42. package/dist/{serialization-CwO31axa.mjs → serialization-lBLV02kQ.mjs} +2 -36
  43. package/dist/{server-BGSrxsQb.d.mts → server-DjMtJQhO.d.mts} +1 -1
  44. package/dist/shared-state-SzgfilJP.mjs +1058 -0
  45. package/dist/{shared-state-BJXkPxtf.mjs → shared-state-u0y123fi.mjs} +6 -6
  46. package/dist/{storage-D-jLaxDA.mjs → storage-CTlHUtXI.mjs} +1 -2
  47. package/dist/structured-clone-qP1sPovr.mjs +208 -0
  48. package/dist/types/index.d.mts +3 -3
  49. package/dist/utils/events.d.mts +1 -1
  50. package/dist/utils/hash.mjs +1 -1
  51. package/dist/utils/open.mjs +1 -1
  52. package/dist/utils/shared-state.d.mts +1 -1
  53. package/dist/utils/shared-state.mjs +1 -1
  54. package/dist/utils/streaming-channel.d.mts +1 -1
  55. package/dist/utils/structured-clone.mjs +1 -1
  56. package/dist/{ws-server-DKlqI8XP.d.mts → ws-server-lHQaafrS.d.mts} +1 -1
  57. package/package.json +2 -1
  58. package/dist/diagnostics-DNxVjo6X.mjs +0 -56
  59. package/dist/revoke-DDa7VSJa.mjs +0 -35
  60. package/dist/ws-client-CrLsflnY.d.mts +0 -26
  61. /package/dist/{_shared-CUFqO4kJ.mjs → _shared-BNoPn1NG.mjs} +0 -0
  62. /package/dist/{define-CW9gLnyG.mjs → define-Bb4zh-Dc.mjs} +0 -0
  63. /package/dist/{hash-CIBte1yS.mjs → hash-bwOD8RgU.mjs} +0 -0
  64. /package/dist/{open-DiQn6zCH.mjs → open-CX4CiMyw.mjs} +0 -0
  65. /package/dist/{server-BO8IDVsJ.mjs → server-DxiOFSpu.mjs} +0 -0
  66. /package/dist/{structured-clone-CD2l4fI3.mjs → structured-clone-PdCZwt7F.mjs} +0 -0
  67. /package/dist/{transports-DTFoMUbE.mjs → transports-Bl1zuYhZ.mjs} +0 -0
  68. /package/dist/{types-DmcujDa5.d.mts → types-kKDaD2NT.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { r as DevframeDefinition } from "../devframe-DAfZWnpI.mjs";
1
+ import { r as DevframeDefinition } from "../devframe-C4DNeFuG.mjs";
2
2
 
3
3
  //#region src/adapters/build.d.ts
4
4
  interface CreateBuildOptions {
@@ -1,10 +1,10 @@
1
- import { t as collectStaticRpcDump } from "../rpc-BlVCyk9W.mjs";
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 { i as structuredCloneStringify } from "../structured-clone-CD2l4fI3.mjs";
5
- import { colors } from "../utils/colors.mjs";
6
- import { n as createHostContext, t as createH3DevToolsHost } from "../host-h3-DEfOpa0j.mjs";
7
- import { n as resolveBasePath } from "../_shared-CUFqO4kJ.mjs";
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";
@@ -1,4 +1,4 @@
1
- import { ct as CliFlagsSchema, dt as parseCliFlags, lt as InferCliFlags, r as DevframeDefinition, ut as defineCliFlags } from "../devframe-DAfZWnpI.mjs";
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
 
@@ -1,6 +1,6 @@
1
- import { colors } from "../utils/colors.mjs";
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-CZ9ZQkuO.mjs";
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";
@@ -1,5 +1,5 @@
1
- import { r as DevframeDefinition } from "../devframe-DAfZWnpI.mjs";
2
- import { n as StartedServer } from "../server-BGSrxsQb.mjs";
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
@@ -1,2 +1,2 @@
1
- import { n as resolveDevServerPort, t as createDevServer } from "../dev-CZ9ZQkuO.mjs";
1
+ import { n as resolveDevServerPort, t as createDevServer } from "../dev-BVtS7qBK.mjs";
2
2
  export { createDevServer, resolveDevServerPort };
@@ -1,4 +1,4 @@
1
- import { d as DevToolsNodeContext, r as DevframeDefinition } from "../devframe-DAfZWnpI.mjs";
1
+ import { d as DevToolsNodeContext, r as DevframeDefinition } from "../devframe-C4DNeFuG.mjs";
2
2
 
3
3
  //#region src/adapters/embedded.d.ts
4
4
  interface CreateEmbeddedOptions {
@@ -1,4 +1,4 @@
1
- import { r as DevframeDefinition } from "../devframe-DAfZWnpI.mjs";
1
+ import { r as DevframeDefinition } from "../devframe-C4DNeFuG.mjs";
2
2
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
3
 
4
4
  //#region src/adapters/mcp/build-server.d.ts
@@ -1,5 +1,5 @@
1
- import { n as logger } from "../diagnostics-DNxVjo6X.mjs";
2
- import { n as createHostContext } from "../host-h3-DEfOpa0j.mjs";
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-DTFoMUbE.mjs");
207
+ const { startStdioTransport } = await import("../transports-Bl1zuYhZ.mjs");
208
208
  let stop;
209
209
  try {
210
210
  stop = await startStdioTransport(server);
@@ -1,9 +1,23 @@
1
- import { T as StreamSink, U as DevToolsRpcClientFunctions, W as DevToolsRpcServerFunctions, at as EventEmitter, g as RpcSharedStateHost, l as ConnectionMeta, w as StreamReader } from "../devframe-DAfZWnpI.mjs";
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. */
@@ -1,14 +1,253 @@
1
- import { t as hash } from "../hash-CIBte1yS.mjs";
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,4 +1,4 @@
1
- import { P as SharedState, d as DevToolsNodeContext } from "./devframe-DAfZWnpI.mjs";
1
+ import { b as SharedState, d as DevToolsNodeContext } from "./devframe-C4DNeFuG.mjs";
2
2
 
3
3
  //#region src/node/internal/context.d.ts
4
4
  interface InternalAnonymousAuthStorage {
@@ -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-DEfOpa0j.mjs";
3
- import { t as startHttpAndWs } from "./server-BO8IDVsJ.mjs";
4
- import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-CUFqO4kJ.mjs";
5
- import { t as open } from "./open-DiQn6zCH.mjs";
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-BNAsgVNz.mjs";
2
- import { t as DevToolsNodeRpcSessionMeta } from "./ws-server-DKlqI8XP.mjs";
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 { AgentResourceContent as $, ImmutableArray as A, EntriesToObject as B, StreamErrorPayload as C, createStreamReader as D, StreamSinkEvents as E, SharedStateEvents as F, DevToolsRpcSharedStates as G, Thenable as H, SharedStateOptions as I, DevToolsDiagnosticsHost as J, DevToolsHost as K, SharedStatePatch as L, ImmutableObject as M, ImmutableSet as N, createStreamSink as O, SharedState as P, AgentResource as Q, createSharedState as R, CreateStreamSinkOptions as S, StreamSink as T, DevToolsRpcClientFunctions as U, PartialWithoutId as V, DevToolsRpcServerFunctions as W, AgentHandle as X, DevToolsDiagnosticsLogger as Y, AgentManifest as Z, RpcStreamingChannel as _, DevframeRuntime as a, EventEmitter as at, BufferedChunk as b, defineDevframe as c, CliFlagsSchema as ct, DevToolsNodeContext as d, parseCliFlags as dt, AgentResourceInput as et, DevToolsNodeRpcSession as f, RpcSharedStateHost as g, RpcSharedStateGetOptions as h, DevframeDeploymentKind as i, DevToolsAgentHostEvents as it, ImmutableMap as j, Immutable as k, ConnectionMeta as l, InferCliFlags as lt, RpcFunctionsHost as m, DevframeCliOptions as n, AgentToolInput as nt, DevframeSetupInfo as o, EventUnsubscribe as ot, RpcBroadcastOptions as p, DevToolsDiagnosticsDefinition as q, DevframeDefinition as r, DevToolsAgentHost as rt, DevframeSpaOptions as s, EventsMap as st, DevframeBrowserContext as t, AgentTool as tt, DevToolsCapabilities as u, defineCliFlags as ut, RpcStreamingChannelOptions as v, StreamReader as w, CreateStreamReaderOptions as x, RpcStreamingHost as y, DevToolsViewHost as z };
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 };