devframe 0.2.2 → 0.3.0

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 (62) hide show
  1. package/dist/adapters/build.d.mts +1 -1
  2. package/dist/adapters/build.mjs +5 -5
  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 +8 -7
  10. package/dist/client/index.d.mts +18 -4
  11. package/dist/client/index.mjs +321 -8
  12. package/dist/{context-BDpuScNZ.d.mts → context-CwjX6sCG.d.mts} +1 -1
  13. package/dist/{dev-CZ9ZQkuO.mjs → dev-BbmanqL7.mjs} +1 -1
  14. package/dist/{devframe-DAfZWnpI.d.mts → devframe-sc4cb5xr.d.mts} +48 -90
  15. package/dist/diagnostics-GitRGKbr.mjs +33 -0
  16. package/dist/diagnostics-reporter-CBBZwoMv.mjs +38 -0
  17. package/dist/{rpc-BlVCyk9W.mjs → dump-zMleojnD.mjs} +147 -134
  18. package/dist/helpers/vite.d.mts +1 -1
  19. package/dist/helpers/vite.mjs +6 -5
  20. package/dist/{host-h3-DEfOpa0j.mjs → host-h3-TTunNr_n.mjs} +284 -44
  21. package/dist/human-id-Dq-qgtES.mjs +803 -0
  22. package/dist/index-C5PmWqBf.d.mts +79 -0
  23. package/dist/{index-BNAsgVNz.d.mts → index-CTK6fuXs.d.mts} +31 -78
  24. package/dist/index-DTeZXHSi.d.mts +639 -0
  25. package/dist/index.d.mts +4 -4
  26. package/dist/node/auth.d.mts +2 -2
  27. package/dist/node/auth.mjs +1 -2
  28. package/dist/node/index.d.mts +10 -14
  29. package/dist/node/index.mjs +2 -2
  30. package/dist/node/internal.d.mts +2 -2
  31. package/dist/node/internal.mjs +2 -3
  32. package/dist/recipes/open-helpers.d.mts +1 -1
  33. package/dist/rpc/dump.d.mts +2 -0
  34. package/dist/rpc/dump.mjs +2 -0
  35. package/dist/rpc/index.d.mts +2 -2
  36. package/dist/rpc/index.mjs +128 -2
  37. package/dist/rpc/transports/ws-client.d.mts +25 -1
  38. package/dist/rpc/transports/ws-client.mjs +2 -2
  39. package/dist/rpc/transports/ws-server.d.mts +1 -1
  40. package/dist/rpc/transports/ws-server.mjs +2 -2
  41. package/dist/{serialization-CwO31axa.mjs → serialization-BlqLh4_J.mjs} +4 -38
  42. package/dist/{server-BGSrxsQb.d.mts → server-ouL4gZbu.d.mts} +1 -1
  43. package/dist/shared-state-CasqoUba.mjs +1019 -0
  44. package/dist/{shared-state-BJXkPxtf.mjs → shared-state-u0y123fi.mjs} +6 -6
  45. package/dist/{storage-D-jLaxDA.mjs → storage-K-OxR1xf.mjs} +5 -3
  46. package/dist/structured-clone-jegjz0hM.mjs +208 -0
  47. package/dist/types/index.d.mts +4 -4
  48. package/dist/utils/events.d.mts +1 -1
  49. package/dist/utils/hash.mjs +1 -1
  50. package/dist/utils/shared-state.d.mts +1 -1
  51. package/dist/utils/shared-state.mjs +1 -1
  52. package/dist/utils/streaming-channel.d.mts +1 -1
  53. package/dist/utils/structured-clone.mjs +1 -1
  54. package/dist/{ws-server-DKlqI8XP.d.mts → ws-server-DOwLJL23.d.mts} +1 -1
  55. package/package.json +3 -2
  56. package/skills/devframe/SKILL.md +1 -1
  57. package/dist/diagnostics-DNxVjo6X.mjs +0 -56
  58. package/dist/revoke-DDa7VSJa.mjs +0 -35
  59. package/dist/ws-client-CrLsflnY.d.mts +0 -26
  60. /package/dist/{hash-CIBte1yS.mjs → hash-bwOD8RgU.mjs} +0 -0
  61. /package/dist/{structured-clone-CD2l4fI3.mjs → structured-clone-PdCZwt7F.mjs} +0 -0
  62. /package/dist/{types-DmcujDa5.d.mts → types-BXL7EIDM.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { r as DevframeDefinition } from "../devframe-DAfZWnpI.mjs";
1
+ import { r as DevframeDefinition } from "../devframe-sc4cb5xr.mjs";
2
2
 
3
3
  //#region src/adapters/build.d.ts
4
4
  interface CreateBuildOptions {
@@ -1,9 +1,9 @@
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-zMleojnD.mjs";
2
+ import { n as colors } from "../diagnostics-reporter-CBBZwoMv.mjs";
3
3
  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";
4
+ import { n as strictJsonStringify } from "../serialization-BlqLh4_J.mjs";
5
+ import { n as structuredCloneStringify } from "../structured-clone-jegjz0hM.mjs";
6
+ import { n as createHostContext, t as createH3DevToolsHost } from "../host-h3-TTunNr_n.mjs";
7
7
  import { n as resolveBasePath } from "../_shared-CUFqO4kJ.mjs";
8
8
  import { existsSync } from "node:fs";
9
9
  import process from "node:process";
@@ -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 CliFlagsSchema, J as parseCliFlags, K as InferCliFlags, q as defineCliFlags, r as DevframeDefinition } from "../devframe-sc4cb5xr.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 { n as colors } from "../diagnostics-reporter-CBBZwoMv.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-BbmanqL7.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-sc4cb5xr.mjs";
2
+ import { n as StartedServer } from "../server-ouL4gZbu.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-BbmanqL7.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-sc4cb5xr.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-sc4cb5xr.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 { i as diagnostics } from "../shared-state-CasqoUba.mjs";
2
+ import { n as createHostContext } from "../host-h3-TTunNr_n.mjs";
3
3
  import { homedir } from "node:os";
4
4
  import process from "node:process";
5
5
  import { join } from "pathe";
@@ -185,10 +185,10 @@ function buildMcpServerFromContext(ctx, options) {
185
185
  */
186
186
  async function createMcpServer(definition, options = {}) {
187
187
  const transport = options.transport ?? "stdio";
188
- if (transport !== "stdio") throw logger.DF0017({
188
+ if (transport !== "stdio") throw diagnostics.DF0017.throw({
189
189
  transport,
190
190
  reason: "Only stdio transport is supported in this release."
191
- }).throw();
191
+ });
192
192
  const ctx = await createHostContext({
193
193
  cwd: process.cwd(),
194
194
  mode: "dev",
@@ -210,10 +210,11 @@ async function createMcpServer(definition, options = {}) {
210
210
  stop = await startStdioTransport(server);
211
211
  } catch (error) {
212
212
  const reason = error instanceof Error ? error.message : String(error);
213
- throw logger.DF0017({
213
+ throw diagnostics.DF0017.throw({
214
214
  transport,
215
- reason
216
- }, { cause: error }).throw();
215
+ reason,
216
+ cause: error
217
+ });
217
218
  }
218
219
  options.onReady?.({ transport: "stdio" });
219
220
  return { async stop() {
@@ -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-DTeZXHSi.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,260 @@
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";
2
+ import { colors } from "../utils/colors.mjs";
7
3
  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
4
  import { humanId } from "../utils/human-id.mjs";
5
+ import { t as createSharedState } from "../shared-state-u0y123fi.mjs";
6
+ import { i as structuredCloneStringify, n as structuredCloneParse, t as structuredCloneDeserialize } from "../structured-clone-PdCZwt7F.mjs";
7
+ import { createStreamReader, createStreamSink } from "../utils/streaming-channel.mjs";
11
8
  import { promiseWithResolver } from "../utils/promise.mjs";
9
+ import { defineDiagnostics } from "nostics";
10
+ import { ansiFormatter } from "nostics/formatters/ansi";
11
+ import { createBirpc } from "birpc";
12
+ //#region src/constants.ts
13
+ const DEVTOOLS_CONNECTION_META_FILENAME = "__connection.json";
14
+ const DEVTOOLS_RPC_DUMP_MANIFEST_FILENAME = "__rpc-dump/index.json";
15
+ //#endregion
16
+ //#region src/utils/diagnostics-reporter.ts
17
+ const formatAnsi = ansiFormatter(colors);
18
+ function devframeReporter(d, { method = "warn" } = {}) {
19
+ console[method](formatAnsi(d));
20
+ }
21
+ //#endregion
22
+ //#region src/rpc/diagnostics.ts
23
+ const diagnostics = defineDiagnostics({
24
+ docsBase: "https://devfra.me/errors",
25
+ reporters: [devframeReporter],
26
+ codes: {
27
+ DF0019: {
28
+ why: (p) => `RPC function "${p.name}" has \`agent\` set but \`jsonSerializable\` is not \`true\` — MCP requires JSON-serializable data.`,
29
+ fix: "Set `jsonSerializable: true` if the payload is JSON-safe, or remove `agent` to keep it RPC-only."
30
+ },
31
+ DF0020: {
32
+ why: (p) => `RPC function "${p.name}" declares \`jsonSerializable: true\` but the value at "${p.path}" is a ${p.type}.`,
33
+ fix: "Either drop `jsonSerializable: true` (falls back to structured-clone) or change the value to a JSON-safe shape."
34
+ },
35
+ DF0021: {
36
+ why: (p) => `RPC function "${p.name}" is already registered`,
37
+ fix: "Use the `force` parameter to overwrite an existing registration."
38
+ },
39
+ DF0022: { why: (p) => `RPC function "${p.name}" is not registered. Use register() to add new functions.` },
40
+ DF0023: { why: (p) => `RPC function "${p.name}" is not registered` },
41
+ DF0024: { why: (p) => `Either handler or setup function must be provided for RPC function "${p.name}"` },
42
+ DF0025: { why: (p) => `Function "${p.name}" not found in dump store` },
43
+ DF0026: { why: (p) => `No dump match for "${p.name}" with args: ${p.args}` },
44
+ DF0027: { why: (p) => `Function "${p.name}" with type "${p.type}" cannot have dump configuration. Only "static" and "query" types support dumps.` },
45
+ DF0028: {
46
+ why: (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.`,
47
+ fix: "Remove `snapshot: true`, or change the function type to `query`."
48
+ }
49
+ }
50
+ });
51
+ //#endregion
52
+ //#region src/rpc/dump/error.ts
53
+ /**
54
+ * Inverse of {@link serializeDumpError}: rebuild a thrown `Error` from
55
+ * the plain object stored in a dump record. Preserves `cause`, restores
56
+ * the original `name`, and re-attaches any custom own properties.
57
+ */
58
+ function reviveDumpError(stored) {
59
+ const cause = stored.cause instanceof Error ? stored.cause : isPlainErrorShape(stored.cause) ? reviveDumpError(stored.cause) : stored.cause;
60
+ const error = cause !== void 0 ? new Error(stored.message, { cause }) : new Error(stored.message);
61
+ error.name = stored.name;
62
+ for (const key of Object.keys(stored)) {
63
+ if (key === "name" || key === "message" || key === "cause") continue;
64
+ error[key] = stored[key];
65
+ }
66
+ return error;
67
+ }
68
+ function isPlainErrorShape(value) {
69
+ return typeof value === "object" && value !== null && typeof value.message === "string" && typeof value.name === "string";
70
+ }
71
+ //#endregion
72
+ //#region src/rpc/handler.ts
73
+ async function getRpcResolvedSetupResult(definition, context) {
74
+ if (definition.__resolved) return definition.__resolved;
75
+ if (!definition.setup) return {};
76
+ definition.__promise ??= Promise.resolve(definition.setup(context)).then((r) => {
77
+ definition.__resolved = r;
78
+ definition.__promise = void 0;
79
+ return r;
80
+ });
81
+ return definition.__resolved ??= await definition.__promise;
82
+ }
83
+ async function getRpcHandler(definition, context) {
84
+ if (definition.handler) return definition.handler;
85
+ const result = await getRpcResolvedSetupResult(definition, context);
86
+ if (!result.handler) throw diagnostics.DF0024.throw({ name: definition.name });
87
+ return result.handler;
88
+ }
89
+ //#endregion
90
+ //#region src/rpc/cache.ts
91
+ /**
92
+ * @experimental API is expected to change.
93
+ */
94
+ var RpcCacheManager = class {
95
+ cacheMap = /* @__PURE__ */ new Map();
96
+ options;
97
+ keySerializer;
98
+ constructor(options) {
99
+ this.options = options;
100
+ this.keySerializer = options.keySerializer || ((args) => hash(args));
101
+ }
102
+ updateOptions(options) {
103
+ this.options = {
104
+ ...this.options,
105
+ ...options
106
+ };
107
+ }
108
+ cached(m, a) {
109
+ const methodCache = this.cacheMap.get(m);
110
+ if (methodCache) return methodCache.get(this.keySerializer(a));
111
+ }
112
+ apply(req, res) {
113
+ const methodCache = this.cacheMap.get(req.m) || /* @__PURE__ */ new Map();
114
+ methodCache.set(this.keySerializer(req.a), res);
115
+ this.cacheMap.set(req.m, methodCache);
116
+ }
117
+ validate(m) {
118
+ return this.options.functions.includes(m);
119
+ }
120
+ clear(fn) {
121
+ if (fn) this.cacheMap.delete(fn);
122
+ else this.cacheMap.clear();
123
+ }
124
+ };
125
+ //#endregion
126
+ //#region src/rpc/collector.ts
127
+ var RpcFunctionsCollectorBase = class {
128
+ context;
129
+ definitions = /* @__PURE__ */ new Map();
130
+ functions;
131
+ _onChanged = [];
132
+ constructor(context) {
133
+ this.context = context;
134
+ const definitions = this.definitions;
135
+ const self = this;
136
+ this.functions = new Proxy({}, {
137
+ get(_, prop) {
138
+ const definition = definitions.get(prop);
139
+ if (!definition) return void 0;
140
+ return getRpcHandler(definition, self.context);
141
+ },
142
+ has(_, prop) {
143
+ return definitions.has(prop);
144
+ },
145
+ getOwnPropertyDescriptor(_, prop) {
146
+ return {
147
+ value: definitions.get(prop)?.handler,
148
+ configurable: true,
149
+ enumerable: true
150
+ };
151
+ },
152
+ ownKeys() {
153
+ return Array.from(definitions.keys());
154
+ }
155
+ });
156
+ }
157
+ register(fn, force = false) {
158
+ if (this.definitions.has(fn.name) && !force) throw diagnostics.DF0021.throw({ name: fn.name });
159
+ assertAgentJsonSerializable(fn);
160
+ this.definitions.set(fn.name, fn);
161
+ this._onChanged.forEach((cb) => cb(fn.name));
162
+ }
163
+ update(fn, force = false) {
164
+ if (!this.definitions.has(fn.name) && !force) throw diagnostics.DF0022.throw({ name: fn.name });
165
+ assertAgentJsonSerializable(fn);
166
+ this.definitions.set(fn.name, fn);
167
+ this._onChanged.forEach((cb) => cb(fn.name));
168
+ }
169
+ onChanged(fn) {
170
+ this._onChanged.push(fn);
171
+ return () => {
172
+ const index = this._onChanged.indexOf(fn);
173
+ if (index !== -1) this._onChanged.splice(index, 1);
174
+ };
175
+ }
176
+ async getHandler(name) {
177
+ return await getRpcHandler(this.definitions.get(name), this.context);
178
+ }
179
+ getSchema(name) {
180
+ const definition = this.definitions.get(name);
181
+ if (!definition) throw diagnostics.DF0023.throw({ name: String(name) });
182
+ return {
183
+ args: definition.args,
184
+ returns: definition.returns
185
+ };
186
+ }
187
+ has(name) {
188
+ return this.definitions.has(name);
189
+ }
190
+ get(name) {
191
+ return this.definitions.get(name);
192
+ }
193
+ list() {
194
+ return Array.from(this.definitions.keys());
195
+ }
196
+ };
197
+ function assertAgentJsonSerializable(fn) {
198
+ if (fn.agent && fn.jsonSerializable !== true) throw diagnostics.DF0019.throw({ name: fn.name });
199
+ }
200
+ //#endregion
201
+ //#region src/rpc/serialization.ts
202
+ /**
203
+ * `JSON.stringify` with a single-pass strict replacer.
204
+ *
205
+ * Throws `DF0020` synchronously when the value contains a type JSON
206
+ * cannot round-trip losslessly: `Map`, `Set`, `Date`, `BigInt`, class
207
+ * instances, or `undefined` inside an array (silently becomes `null`).
208
+ *
209
+ * Native pass-throughs (no extra work needed):
210
+ * - circular references — `JSON.stringify` raises `TypeError`.
211
+ * - `BigInt` at top level — caught here for a friendlier error path.
212
+ *
213
+ * Lenient cases (allowed without throwing):
214
+ * - `undefined` as an object property — legitimate optional field;
215
+ * JSON.stringify just omits it.
216
+ * - `undefined` at the root — legitimate "action returned nothing".
217
+ * - `Symbol` / `Function` values — semantically "drop me" in JSON.
218
+ *
219
+ * `fnName` is used only for the diagnostic message — pass the RPC
220
+ * function name when calling from a wire serializer / dump writer so
221
+ * the error points at the offending function.
222
+ */
223
+ function strictJsonStringify(value, fnName = "") {
224
+ return JSON.stringify(value, function strictReplacer(key, val) {
225
+ const holder = this;
226
+ const original = holder != null ? holder[key] : val;
227
+ if (original === void 0) {
228
+ if (Array.isArray(holder)) throw nonJsonAt(fnName, "undefined", holder, key);
229
+ return val;
230
+ }
231
+ if (original === null) return val;
232
+ if (typeof original === "bigint") throw nonJsonAt(fnName, "BigInt", holder, key);
233
+ if (typeof original === "object") {
234
+ if (original instanceof Map) throw nonJsonAt(fnName, "Map", holder, key);
235
+ if (original instanceof Set) throw nonJsonAt(fnName, "Set", holder, key);
236
+ if (original instanceof Date) throw nonJsonAt(fnName, "Date", holder, key);
237
+ if (Array.isArray(original)) return val;
238
+ const proto = Object.getPrototypeOf(original);
239
+ if (proto !== null && proto !== Object.prototype) throw nonJsonAt(fnName, original.constructor?.name ?? "class instance", holder, key);
240
+ }
241
+ return val;
242
+ });
243
+ }
244
+ function nonJsonAt(fnName, type, parent, key) {
245
+ const path = formatPath(parent, key);
246
+ return diagnostics.DF0020.throw({
247
+ name: fnName || "<anonymous>",
248
+ type,
249
+ path
250
+ });
251
+ }
252
+ function formatPath(parent, key) {
253
+ if (Array.isArray(parent)) return `[${key}]`;
254
+ if (key === "") return "<root>";
255
+ return key;
256
+ }
257
+ //#endregion
12
258
  //#region src/client/rpc-shared-state.ts
13
259
  function createRpcSharedStateClientHost(rpc) {
14
260
  const sharedState = /* @__PURE__ */ new Map();
@@ -273,6 +519,73 @@ function createRpcStreamingClientHost(rpc) {
273
519
  };
274
520
  }
275
521
  //#endregion
522
+ //#region src/rpc/client.ts
523
+ function createRpcClient(functions, options) {
524
+ const { channel, rpcOptions = {} } = options;
525
+ return createBirpc(functions, {
526
+ ...channel,
527
+ timeout: -1,
528
+ ...rpcOptions,
529
+ proxify: false
530
+ });
531
+ }
532
+ //#endregion
533
+ //#region src/rpc/transports/ws-client.ts
534
+ function NOOP() {}
535
+ const EMPTY_DEFS = /* @__PURE__ */ new Map();
536
+ /**
537
+ * Build a birpc `ChannelOptions` object backed by a browser `WebSocket`.
538
+ * Pass the result straight to `createRpcClient`'s `channel` option.
539
+ */
540
+ function createWsRpcChannel(options) {
541
+ let url = options.url;
542
+ if (options.authToken) url = `${url}?vite_devtools_auth_token=${encodeURIComponent(options.authToken)}`;
543
+ const ws = new WebSocket(url);
544
+ const { onConnected = NOOP, onError = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS } = options;
545
+ ws.addEventListener("open", (e) => {
546
+ onConnected(e);
547
+ });
548
+ ws.addEventListener("error", (e) => {
549
+ onError(e instanceof Error ? e : new Error(e.type));
550
+ });
551
+ ws.addEventListener("close", (e) => {
552
+ onDisconnected(e);
553
+ });
554
+ const pendingRequestMethods = /* @__PURE__ */ new Map();
555
+ return {
556
+ on: (handler) => {
557
+ ws.addEventListener("message", (e) => {
558
+ handler(e.data);
559
+ });
560
+ },
561
+ post: (data) => {
562
+ if (ws.readyState === WebSocket.OPEN) ws.send(data);
563
+ else {
564
+ function handler() {
565
+ ws.send(data);
566
+ ws.removeEventListener("open", handler);
567
+ }
568
+ ws.addEventListener("open", handler);
569
+ }
570
+ },
571
+ serialize: (msg) => {
572
+ let method;
573
+ if (msg.t === "q") method = msg.m;
574
+ else {
575
+ method = pendingRequestMethods.get(msg.i);
576
+ pendingRequestMethods.delete(msg.i);
577
+ }
578
+ if (!(msg.t === "s" && "e" in msg) && !!method && definitions.get(method)?.jsonSerializable === true) return strictJsonStringify(msg, method ?? "");
579
+ return `s:${structuredCloneStringify(msg)}`;
580
+ },
581
+ deserialize: (raw) => {
582
+ const msg = raw.startsWith("s:") ? structuredCloneParse(raw.slice(2)) : JSON.parse(raw);
583
+ if (msg.t === "q" && msg.i && msg.m) pendingRequestMethods.set(msg.i, msg.m);
584
+ return msg;
585
+ }
586
+ };
587
+ }
588
+ //#endregion
276
589
  //#region ../../node_modules/.pnpm/ua-parser-modern@0.1.1/node_modules/ua-parser-modern/dist/index.mjs
277
590
  const EMPTY = "";
278
591
  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-sc4cb5xr.mjs";
2
2
 
3
3
  //#region src/node/internal/context.d.ts
4
4
  interface InternalAnonymousAuthStorage {
@@ -1,5 +1,5 @@
1
1
  import { DEVTOOLS_CONNECTION_META_FILENAME } from "./constants.mjs";
2
- import { n as createHostContext, t as createH3DevToolsHost } from "./host-h3-DEfOpa0j.mjs";
2
+ import { n as createHostContext, t as createH3DevToolsHost } from "./host-h3-TTunNr_n.mjs";
3
3
  import { t as startHttpAndWs } from "./server-BO8IDVsJ.mjs";
4
4
  import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-CUFqO4kJ.mjs";
5
5
  import { t as open } from "./open-DiQn6zCH.mjs";