devframe 0.5.3 → 0.6.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{_shared-CUFqO4kJ.mjs → _shared-bWRzeSa0.mjs} +2 -3
  2. package/dist/adapters/build.d.mts +1 -1
  3. package/dist/adapters/build.mjs +7 -7
  4. package/dist/adapters/cli.d.mts +1 -1
  5. package/dist/adapters/cli.mjs +2 -2
  6. package/dist/adapters/dev.d.mts +8 -2
  7. package/dist/adapters/dev.mjs +1 -1
  8. package/dist/adapters/embedded.d.mts +1 -1
  9. package/dist/adapters/mcp.d.mts +1 -1
  10. package/dist/adapters/mcp.mjs +4 -4
  11. package/dist/client/index.d.mts +148 -6
  12. package/dist/client/index.mjs +272 -49
  13. package/dist/constants.d.mts +17 -1
  14. package/dist/constants.mjs +17 -1
  15. package/dist/context-3x_bgBgZ.mjs +48 -0
  16. package/dist/{context-DTRcO_UH.d.mts → context-o-TwncyP.d.mts} +1 -1
  17. package/dist/{dev-Cv43GfqM.mjs → dev-CSpLSEVh.mjs} +39 -13
  18. package/dist/{devframe-BuR6n9ZD.d.mts → devframe-BwfavB78.d.mts} +365 -15
  19. package/dist/{diagnostics-GitRGKbr.mjs → diagnostics-BXwBQmoN.mjs} +1 -1
  20. package/dist/{dump-9lKIJTLh.mjs → dump-DoXkj4ku.mjs} +1 -1
  21. package/dist/helpers/vite.d.mts +1 -1
  22. package/dist/helpers/vite.mjs +11 -11
  23. package/dist/{host-h3-Dgpgr1Ul.mjs → host-h3-C5SZlk03.mjs} +134 -6
  24. package/dist/{index-C7M1hnvL.d.mts → index-CxaPKDXX.d.mts} +2 -2
  25. package/dist/{index-DH2sBIwd.d.mts → index-DXHWuwJk.d.mts} +1 -1
  26. package/dist/index.d.mts +4 -4
  27. package/dist/index.mjs +1 -1
  28. package/dist/node/auth.d.mts +43 -23
  29. package/dist/node/auth.mjs +84 -37
  30. package/dist/node/hub-internals.d.mts +2 -2
  31. package/dist/node/hub-internals.mjs +2 -2
  32. package/dist/node/index.d.mts +22 -6
  33. package/dist/node/index.mjs +4 -4
  34. package/dist/recipes/open-helpers.d.mts +1 -1
  35. package/dist/recipes/open-helpers.mjs +3 -3
  36. package/dist/revoke-ENfxWkFK.mjs +79 -0
  37. package/dist/rpc/dump.d.mts +1 -1
  38. package/dist/rpc/dump.mjs +1 -1
  39. package/dist/rpc/index.d.mts +3 -3
  40. package/dist/rpc/index.mjs +4 -4
  41. package/dist/rpc/transports/ws-client.d.mts +1 -1
  42. package/dist/rpc/transports/ws-client.mjs +2 -2
  43. package/dist/rpc/transports/ws-server.d.mts +2 -2
  44. package/dist/rpc/transports/ws-server.mjs +124 -60
  45. package/dist/{serialization-BD_qXGjd.mjs → serialization-DpLXCy13.mjs} +1 -1
  46. package/dist/{server-wHlpcdZ9.d.mts → server-oju7PTi2.d.mts} +30 -3
  47. package/dist/{server-BBaBJaUL.mjs → server-wyY3zh67.mjs} +18 -14
  48. package/dist/{shared-state-u0y123fi.mjs → shared-state-D4PPieA0.mjs} +4 -4
  49. package/dist/{shared-state-BlBNYziY.mjs → storage-l2ezeend.mjs} +128 -6
  50. package/dist/types/index.d.mts +4 -4
  51. package/dist/{types-BkkQ0Txg.d.mts → types-DZEx4ffs.d.mts} +9 -1
  52. package/dist/utils/crypto-token.d.mts +24 -0
  53. package/dist/utils/crypto-token.mjs +45 -0
  54. package/dist/utils/events.d.mts +1 -1
  55. package/dist/utils/hash.mjs +1 -1
  56. package/dist/utils/launch-editor.mjs +1 -1
  57. package/dist/utils/open.mjs +1 -1
  58. package/dist/utils/scope.d.mts +11 -0
  59. package/dist/utils/scope.mjs +15 -0
  60. package/dist/utils/shared-state.d.mts +1 -1
  61. package/dist/utils/shared-state.mjs +1 -1
  62. package/dist/utils/streaming-channel.d.mts +1 -1
  63. package/dist/utils/structured-clone.mjs +1 -1
  64. package/dist/{ws-client-CVYX9niP.d.mts → ws-client-D0z0pOhn.d.mts} +1 -1
  65. package/dist/ws-server-BVVMDo2n.d.mts +103 -0
  66. package/package.json +12 -7
  67. package/skills/devframe/SKILL.md +123 -23
  68. package/skills/devframe/templates/counter-devframe.ts +14 -4
  69. package/skills/devframe/templates/spa-devframe.ts +13 -3
  70. package/skills/devframe/templates/vite-client.ts +3 -2
  71. package/dist/context-DaKmhhHY.mjs +0 -164
  72. package/dist/revoke-CL0LSAN9.mjs +0 -803
  73. package/dist/utils/human-id.d.mts +0 -8
  74. package/dist/utils/human-id.mjs +0 -769
  75. package/dist/ws-server-C1LjmRnp.d.mts +0 -61
  76. /package/dist/{define-CW9gLnyG.mjs → define-BLWPsH6y.mjs} +0 -0
  77. /package/dist/{diagnostics-reporter-CBBZwoMv.mjs → diagnostics-reporter-CsIG85Q5.mjs} +0 -0
  78. /package/dist/{hash-bwOD8RgU.mjs → hash-DFc5WwhO.mjs} +0 -0
  79. /package/dist/{launch-editor-BbNhtg7b.mjs → launch-editor-CgXBgviI.mjs} +0 -0
  80. /package/dist/{open-DiQn6zCH.mjs → open-Dusa2Zzd.mjs} +0 -0
  81. /package/dist/{structured-clone-PdCZwt7F.mjs → structured-clone-CeZOHvkd.mjs} +0 -0
  82. /package/dist/{structured-clone-jegjz0hM.mjs → structured-clone-XpHLZ8nr.mjs} +0 -0
  83. /package/dist/{transports-DTFoMUbE.mjs → transports-BmDVn4SF.mjs} +0 -0
@@ -1,3 +1,3 @@
1
- import { C as RpcFunctionsCollector, S as RpcFunctionType, T as Thenable, _ as RpcFunctionDefinitionAny, a as RpcDefinitionsFilter, b as RpcFunctionDefinitionToFunction, c as RpcDumpClientOptions, d as RpcDumpGetter, f as RpcDumpRecord, g as RpcFunctionDefinition, h as RpcFunctionAgentOptions, i as RpcArgsSchema, l as RpcDumpCollectionOptions, m as RpcDumpStore, n as BirpcReturn, o as RpcDefinitionsToFunctions, p as RpcDumpRecordError, r as EntriesToObject, s as RpcDump, t as BirpcFn, u as RpcDumpDefinition, v as RpcFunctionDefinitionAnyWithContext, w as RpcReturnSchema, x as RpcFunctionSetupResult, y as RpcFunctionDefinitionBase } from "../types-BkkQ0Txg.mjs";
2
- import { C as RpcCacheManager, S as RpcFunctionsCollectorBase, _ as strictJsonStringify, a as StaticRpcDumpManifestStaticEntry, b as createDefineWrapperWithContext, c as collectStaticRpcDump, d as getDefinitionsWithDumps, f as reviveDumpError, g as STRUCTURED_CLONE_PREFIX, h as validateDefinitions, i as StaticRpcDumpManifestQueryEntry, l as createClientFromDump, m as validateDefinition, n as StaticRpcDumpFile, o as StaticRpcDumpManifestValue, p as serializeDumpError, r as StaticRpcDumpManifest, s as StaticRpcDumpSerialization, t as StaticRpcDumpCollection, u as dumpFunctions, v as getRpcHandler, w as RpcCacheOptions, x as defineRpcFunction, y as getRpcResolvedSetupResult } from "../index-C7M1hnvL.mjs";
3
- export { BirpcFn, BirpcReturn, EntriesToObject, RpcArgsSchema, RpcCacheManager, RpcCacheOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcDump, RpcDumpClientOptions, RpcDumpCollectionOptions, RpcDumpDefinition, RpcDumpGetter, RpcDumpRecord, RpcDumpRecordError, RpcDumpStore, RpcFunctionAgentOptions, RpcFunctionDefinition, RpcFunctionDefinitionAny, RpcFunctionDefinitionAnyWithContext, RpcFunctionDefinitionBase, RpcFunctionDefinitionToFunction, RpcFunctionSetupResult, RpcFunctionType, RpcFunctionsCollector, RpcFunctionsCollectorBase, RpcReturnSchema, STRUCTURED_CLONE_PREFIX, StaticRpcDumpCollection, StaticRpcDumpFile, StaticRpcDumpManifest, StaticRpcDumpManifestQueryEntry, StaticRpcDumpManifestStaticEntry, StaticRpcDumpManifestValue, StaticRpcDumpSerialization, Thenable, collectStaticRpcDump, createClientFromDump, createDefineWrapperWithContext, defineRpcFunction, dumpFunctions, getDefinitionsWithDumps, getRpcHandler, getRpcResolvedSetupResult, reviveDumpError, serializeDumpError, strictJsonStringify, validateDefinition, validateDefinitions };
1
+ import { C as RpcFunctionType, E as Thenable, S as RpcFunctionSetupResult, T as RpcReturnSchema, _ as RpcFunctionDefinition, a as RpcDefinitionsFilter, b as RpcFunctionDefinitionBase, c as RpcDump, d as RpcDumpDefinition, f as RpcDumpGetter, g as RpcFunctionAgentOptions, h as RpcDumpStore, i as RpcArgsSchema, l as RpcDumpClientOptions, m as RpcDumpRecordError, n as BirpcReturn, o as RpcDefinitionsToFunctions, p as RpcDumpRecord, r as EntriesToObject, s as RpcDefinitionsToFunctionsWithNamespace, t as BirpcFn, u as RpcDumpCollectionOptions, v as RpcFunctionDefinitionAny, w as RpcFunctionsCollector, x as RpcFunctionDefinitionToFunction, y as RpcFunctionDefinitionAnyWithContext } from "../types-DZEx4ffs.mjs";
2
+ import { C as RpcCacheManager, S as RpcFunctionsCollectorBase, _ as strictJsonStringify, a as StaticRpcDumpManifestStaticEntry, b as createDefineWrapperWithContext, c as collectStaticRpcDump, d as getDefinitionsWithDumps, f as reviveDumpError, g as STRUCTURED_CLONE_PREFIX, h as validateDefinitions, i as StaticRpcDumpManifestQueryEntry, l as createClientFromDump, m as validateDefinition, n as StaticRpcDumpFile, o as StaticRpcDumpManifestValue, p as serializeDumpError, r as StaticRpcDumpManifest, s as StaticRpcDumpSerialization, t as StaticRpcDumpCollection, u as dumpFunctions, v as getRpcHandler, w as RpcCacheOptions, x as defineRpcFunction, y as getRpcResolvedSetupResult } from "../index-CxaPKDXX.mjs";
3
+ export { BirpcFn, BirpcReturn, EntriesToObject, RpcArgsSchema, RpcCacheManager, RpcCacheOptions, RpcDefinitionsFilter, RpcDefinitionsToFunctions, RpcDefinitionsToFunctionsWithNamespace, RpcDump, RpcDumpClientOptions, RpcDumpCollectionOptions, RpcDumpDefinition, RpcDumpGetter, RpcDumpRecord, RpcDumpRecordError, RpcDumpStore, RpcFunctionAgentOptions, RpcFunctionDefinition, RpcFunctionDefinitionAny, RpcFunctionDefinitionAnyWithContext, RpcFunctionDefinitionBase, RpcFunctionDefinitionToFunction, RpcFunctionSetupResult, RpcFunctionType, RpcFunctionsCollector, RpcFunctionsCollectorBase, RpcReturnSchema, STRUCTURED_CLONE_PREFIX, StaticRpcDumpCollection, StaticRpcDumpFile, StaticRpcDumpManifest, StaticRpcDumpManifestQueryEntry, StaticRpcDumpManifestStaticEntry, StaticRpcDumpManifestValue, StaticRpcDumpSerialization, Thenable, collectStaticRpcDump, createClientFromDump, createDefineWrapperWithContext, defineRpcFunction, dumpFunctions, getDefinitionsWithDumps, getRpcHandler, getRpcResolvedSetupResult, reviveDumpError, serializeDumpError, strictJsonStringify, validateDefinition, validateDefinitions };
@@ -1,7 +1,7 @@
1
- import { a as dumpFunctions$1, c as serializeDumpError$1, d as hash, i as createClientFromDump$1, l as validateDefinition, n as getRpcHandler, o as getDefinitionsWithDumps$1, r as getRpcResolvedSetupResult, s as reviveDumpError$1, t as collectStaticRpcDump$1, u as validateDefinitions } from "../dump-9lKIJTLh.mjs";
2
- import { t as diagnostics } from "../diagnostics-GitRGKbr.mjs";
3
- import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-CW9gLnyG.mjs";
4
- import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-BD_qXGjd.mjs";
1
+ import { a as dumpFunctions$1, c as serializeDumpError$1, d as hash, i as createClientFromDump$1, l as validateDefinition, n as getRpcHandler, o as getDefinitionsWithDumps$1, r as getRpcResolvedSetupResult, s as reviveDumpError$1, t as collectStaticRpcDump$1, u as validateDefinitions } from "../dump-DoXkj4ku.mjs";
2
+ import { t as diagnostics } from "../diagnostics-BXwBQmoN.mjs";
3
+ import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-BLWPsH6y.mjs";
4
+ import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-DpLXCy13.mjs";
5
5
  //#region src/rpc/cache.ts
6
6
  /**
7
7
  * @experimental API is expected to change.
@@ -1,2 +1,2 @@
1
- import { n as createWsRpcChannel, t as WsRpcChannelOptions } from "../../ws-client-CVYX9niP.mjs";
1
+ import { n as createWsRpcChannel, t as WsRpcChannelOptions } from "../../ws-client-D0z0pOhn.mjs";
2
2
  export { WsRpcChannelOptions, createWsRpcChannel };
@@ -1,5 +1,5 @@
1
- import { n as strictJsonStringify } from "../../serialization-BD_qXGjd.mjs";
2
- import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-jegjz0hM.mjs";
1
+ import { n as strictJsonStringify } from "../../serialization-DpLXCy13.mjs";
2
+ import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-XpHLZ8nr.mjs";
3
3
  //#region src/rpc/transports/ws-client.ts
4
4
  function NOOP() {}
5
5
  const EMPTY_DEFS = /* @__PURE__ */ new Map();
@@ -1,2 +1,2 @@
1
- import { n as WsRpcTransportOptions, r as attachWsRpcTransport, t as DevframeNodeRpcSessionMeta } from "../../ws-server-C1LjmRnp.mjs";
2
- export { DevframeNodeRpcSessionMeta, WsRpcTransportOptions, attachWsRpcTransport };
1
+ import { i as attachWsRpcTransport, n as WsRpcTransport, r as WsRpcTransportOptions, t as DevframeNodeRpcSessionMeta } from "../../ws-server-BVVMDo2n.mjs";
2
+ export { DevframeNodeRpcSessionMeta, WsRpcTransport, WsRpcTransportOptions, attachWsRpcTransport };
@@ -1,74 +1,138 @@
1
- import { n as strictJsonStringify } from "../../serialization-BD_qXGjd.mjs";
2
- import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-jegjz0hM.mjs";
3
- import { createServer } from "node:https";
4
- import { WebSocketServer } from "ws";
1
+ import { n as strictJsonStringify } from "../../serialization-DpLXCy13.mjs";
2
+ import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-XpHLZ8nr.mjs";
3
+ import { createServer } from "node:http";
4
+ import { createServer as createServer$1 } from "node:https";
5
+ import crossws from "crossws/adapters/node";
5
6
  //#region src/rpc/transports/ws-server.ts
6
7
  let sessionId = 0;
7
8
  const EMPTY_DEFS = /* @__PURE__ */ new Map();
8
9
  function NOOP() {}
10
+ /** Compare two URL paths ignoring a trailing slash. */
11
+ function pathMatches(a, b) {
12
+ const strip = (p) => p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
13
+ return strip(a) === strip(b);
14
+ }
9
15
  /**
10
- * Attach a WebSocket transport to an existing RPC group. Either pass an
11
- * existing `WebSocketServer` via `wss`, or let this helper create one from
12
- * `port` / `host` / `https`.
16
+ * Route `upgrade` events on a server to the crossws adapter, optionally
17
+ * filtered to a single `path`. Non-matching requests are left untouched so
18
+ * other upgrade listeners (e.g. a Vite dev server's HMR socket) can claim
19
+ * them, unless `destroyUnmatched` is set. Returns a detach function that
20
+ * removes the listener.
21
+ */
22
+ function routeUpgrades(server, ws, path, destroyUnmatched) {
23
+ const listener = (req, socket, head) => {
24
+ if (path) {
25
+ let pathname = req.url ?? "/";
26
+ try {
27
+ pathname = new URL(req.url ?? "/", "http://localhost").pathname;
28
+ } catch {}
29
+ if (!pathMatches(pathname, path)) {
30
+ if (destroyUnmatched) socket.destroy();
31
+ return;
32
+ }
33
+ }
34
+ ws.handleUpgrade(req, socket, head);
35
+ };
36
+ server.on("upgrade", listener);
37
+ return () => server.off("upgrade", listener);
38
+ }
39
+ /**
40
+ * Attach a WebSocket transport to an existing RPC group, powered by
41
+ * [crossws](https://crossws.h3.dev). Either attach to an existing HTTP(S)
42
+ * `server` (sharing its port, optionally scoped to a `path`), or let this
43
+ * helper create a standalone server from `port` / `host` / `https`.
44
+ *
45
+ * Returns the crossws node adapter plus `detach` (remove the upgrade
46
+ * listener from a shared `server`) and `close` (full deterministic
47
+ * teardown).
13
48
  */
14
49
  function attachWsRpcTransport(rpcGroup, options = {}) {
15
- const { wss: externalWss, port, host = "localhost", https, onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
16
- let wss;
17
- if (externalWss) wss = externalWss;
18
- else if (https) {
19
- const httpsServer = createServer(https);
20
- wss = new WebSocketServer({ server: httpsServer });
21
- httpsServer.listen(port, host);
22
- } else wss = new WebSocketServer({
23
- port,
24
- host
25
- });
26
- wss.on("connection", (ws, req) => {
27
- const meta = {
28
- id: sessionId++,
29
- ws,
30
- subscribedStates: /* @__PURE__ */ new Set()
31
- };
32
- const pendingRequestMethods = /* @__PURE__ */ new Map();
33
- const channel = {
34
- post: (data) => {
35
- ws.send(data);
36
- },
37
- on: (fn) => {
38
- ws.on("message", (data) => {
39
- fn(data.toString());
40
- });
41
- },
42
- serialize: serializeOverride ?? ((msg) => {
43
- let method;
44
- if (msg.t === "q") method = msg.m;
45
- else {
46
- method = pendingRequestMethods.get(msg.i);
47
- pendingRequestMethods.delete(msg.i);
48
- }
49
- if (!(msg.t === "s" && "e" in msg) && !!method && definitions.get(method)?.jsonSerializable === true) return strictJsonStringify(msg, method ?? "");
50
- return `s:${structuredCloneStringify(msg)}`;
51
- }),
52
- deserialize: deserializeOverride ?? ((raw) => {
53
- const msg = raw.startsWith("s:") ? structuredCloneParse(raw.slice(2)) : JSON.parse(raw);
54
- if (msg.t === "q" && msg.i && msg.m) pendingRequestMethods.set(msg.i, msg.m);
55
- return msg;
56
- }),
57
- meta
58
- };
59
- rpcGroup.updateChannels((channels) => {
60
- channels.push(channel);
61
- });
62
- ws.on("close", () => {
50
+ const { server, port, host = "localhost", path, destroyUnmatched = false, https, onConnected = NOOP, onDisconnected = NOOP, definitions = EMPTY_DEFS, serialize: serializeOverride, deserialize: deserializeOverride } = options;
51
+ const states = /* @__PURE__ */ new WeakMap();
52
+ const ws = crossws({ hooks: {
53
+ open: (peer) => {
54
+ const meta = {
55
+ id: sessionId++,
56
+ peer,
57
+ subscribedStates: /* @__PURE__ */ new Set()
58
+ };
59
+ const pendingRequestMethods = /* @__PURE__ */ new Map();
60
+ const state = {
61
+ meta,
62
+ channel: void 0
63
+ };
64
+ const channel = {
65
+ post: (data) => {
66
+ peer.send(data);
67
+ },
68
+ on: (fn) => {
69
+ state.onMessage = fn;
70
+ },
71
+ serialize: serializeOverride ?? ((msg) => {
72
+ let method;
73
+ if (msg.t === "q") method = msg.m;
74
+ else {
75
+ method = pendingRequestMethods.get(msg.i);
76
+ pendingRequestMethods.delete(msg.i);
77
+ }
78
+ if (!(msg.t === "s" && "e" in msg) && !!method && definitions.get(method)?.jsonSerializable === true) return strictJsonStringify(msg, method ?? "");
79
+ return `s:${structuredCloneStringify(msg)}`;
80
+ }),
81
+ deserialize: deserializeOverride ?? ((raw) => {
82
+ const msg = raw.startsWith("s:") ? structuredCloneParse(raw.slice(2)) : JSON.parse(raw);
83
+ if (msg.t === "q" && msg.i && msg.m) pendingRequestMethods.set(msg.i, msg.m);
84
+ return msg;
85
+ }),
86
+ meta
87
+ };
88
+ state.channel = channel;
89
+ states.set(peer, state);
90
+ rpcGroup.updateChannels((channels) => {
91
+ channels.push(channel);
92
+ });
93
+ onConnected(peer, meta);
94
+ },
95
+ message: (peer, message) => {
96
+ states.get(peer)?.onMessage?.(message.text());
97
+ },
98
+ close: (peer) => {
99
+ const state = states.get(peer);
100
+ if (!state) return;
101
+ states.delete(peer);
63
102
  rpcGroup.updateChannels((channels) => {
64
- const index = channels.indexOf(channel);
103
+ const index = channels.indexOf(state.channel);
65
104
  if (index >= 0) channels.splice(index, 1);
66
105
  });
67
- onDisconnected(ws, meta);
106
+ onDisconnected(peer, state.meta);
107
+ }
108
+ } });
109
+ let detach = NOOP;
110
+ let ownedServer;
111
+ if (server) detach = routeUpgrades(server, ws, path, destroyUnmatched);
112
+ else if (https) {
113
+ ownedServer = createServer$1(https);
114
+ detach = routeUpgrades(ownedServer, ws, path, true);
115
+ ownedServer.listen(port, host);
116
+ } else {
117
+ ownedServer = createServer((_req, res) => {
118
+ res.writeHead(426, { "content-type": "text/plain" });
119
+ res.end("Upgrade Required");
68
120
  });
69
- onConnected(ws, req, meta);
70
- });
71
- return { wss };
121
+ detach = routeUpgrades(ownedServer, ws, path, true);
122
+ ownedServer.listen(port, host);
123
+ }
124
+ return {
125
+ ws,
126
+ detach,
127
+ async close() {
128
+ detach();
129
+ ws.closeAll(void 0, void 0, true);
130
+ if (ownedServer) {
131
+ const srv = ownedServer;
132
+ await new Promise((r) => srv.close(() => r()));
133
+ }
134
+ }
135
+ };
72
136
  }
73
137
  //#endregion
74
138
  export { attachWsRpcTransport };
@@ -1,4 +1,4 @@
1
- import { t as diagnostics } from "./diagnostics-GitRGKbr.mjs";
1
+ import { t as diagnostics } from "./diagnostics-BXwBQmoN.mjs";
2
2
  //#region src/rpc/serialization.ts
3
3
  /**
4
4
  * Wire format used by the WS RPC transport.
@@ -1,6 +1,7 @@
1
- import { U as DevframeRpcClientFunctions, W as DevframeRpcServerFunctions, d as DevframeNodeContext } from "./devframe-BuR6n9ZD.mjs";
1
+ import { it as DevframeRpcServerFunctions, m as DevframeNodeContext, rt as DevframeRpcClientFunctions } from "./devframe-BwfavB78.mjs";
2
2
  import { BirpcGroup } from "birpc";
3
- import { WebSocketServer } from "ws";
3
+ import { NodeAdapter } from "crossws/adapters/node";
4
+ import { Server } from "node:http";
4
5
  import { H3 } from "h3";
5
6
 
6
7
  //#region src/node/server.d.ts
@@ -14,6 +15,31 @@ interface StartHttpAndWsOptions {
14
15
  * auth middleware, etc.) first.
15
16
  */
16
17
  app?: H3;
18
+ /**
19
+ * Bind the WS endpoint to a single upgrade route (e.g. `/__devframe_ws`) instead of
20
+ * claiming every upgrade on the port. This lets the socket share a server
21
+ * with other upgrade handlers (Vite HMR, a host framework's own sockets)
22
+ * and is what the SPA's `__connection.json` points at. When omitted, the WS
23
+ * server handles every upgrade on the port (legacy behaviour).
24
+ */
25
+ path?: string;
26
+ /**
27
+ * Bind the WS endpoint on its own port instead of sharing the HTTP server's.
28
+ * The HTTP/SPA server still listens on `port`; the socket gets a dedicated
29
+ * `ws` server on `wsPort` (same `host`). Use this for the "different port"
30
+ * connection scenario. Ignored when a `server` is supplied.
31
+ */
32
+ wsPort?: number;
33
+ /**
34
+ * Mount the WS endpoint onto an existing HTTP server, sharing its port,
35
+ * rather than creating and listening on a fresh one. Use this to embed
36
+ * devframe's RPC socket inside a host server (e.g. a Vite dev server) — pair
37
+ * it with `path` so it coexists with the host's routes. The caller owns the
38
+ * server's lifecycle: {@link StartedServer.close} detaches devframe's upgrade
39
+ * listener but leaves the host server running. When set, `host`/`port` are
40
+ * only used to report the resolved origin.
41
+ */
42
+ server?: Server;
17
43
  /**
18
44
  * When `false`, the RPC server is started without a trust handshake.
19
45
  * Intended for single-user localhost tools where an auth round-trip
@@ -41,7 +67,8 @@ interface StartedServer {
41
67
  origin: string;
42
68
  port: number;
43
69
  app: H3;
44
- wss: WebSocketServer;
70
+ /** The crossws node adapter driving the RPC socket (connected peers, pub/sub). */
71
+ ws: NodeAdapter;
45
72
  rpcGroup: BirpcGroup<DevframeRpcClientFunctions, DevframeRpcServerFunctions, false>;
46
73
  close: () => Promise<void>;
47
74
  }
@@ -1,9 +1,8 @@
1
1
  import { createRpcServer } from "./rpc/server.mjs";
2
2
  import { attachWsRpcTransport } from "./rpc/transports/ws-server.mjs";
3
- import { t as getInternalContext } from "./context-DaKmhhHY.mjs";
4
- import { WebSocketServer } from "ws";
5
- import { AsyncLocalStorage } from "node:async_hooks";
3
+ import { t as getInternalContext } from "./context-3x_bgBgZ.mjs";
6
4
  import { createServer } from "node:http";
5
+ import { AsyncLocalStorage } from "node:async_hooks";
7
6
  import { H3, toNodeHandler } from "h3";
8
7
  //#region src/node/server.ts
9
8
  /**
@@ -15,8 +14,8 @@ async function startHttpAndWs(options) {
15
14
  const { context, port } = options;
16
15
  const bindHost = options.host ?? "localhost";
17
16
  const app = options.app ?? new H3();
18
- const httpServer = createServer(toNodeHandler(app));
19
- const wss = new WebSocketServer({ server: httpServer });
17
+ const ownsHttpServer = !options.server;
18
+ const httpServer = options.server ?? createServer(toNodeHandler(app));
20
19
  const rpcHost = context.rpc;
21
20
  const asyncStorage = new AsyncLocalStorage();
22
21
  const rpcGroup = createRpcServer(rpcHost.functions, { rpcOptions: { resolver(name, fn) {
@@ -31,9 +30,15 @@ async function startHttpAndWs(options) {
31
30
  });
32
31
  };
33
32
  } } });
34
- attachWsRpcTransport(rpcGroup, {
35
- wss,
36
- onDisconnected: (_ws, meta) => {
33
+ const separateWsPort = ownsHttpServer && options.wsPort != null && options.wsPort !== port ? options.wsPort : void 0;
34
+ const { ws, close: closeWs } = attachWsRpcTransport(rpcGroup, {
35
+ ...separateWsPort != null ? {
36
+ port: separateWsPort,
37
+ host: bindHost
38
+ } : { server: httpServer },
39
+ path: options.path,
40
+ destroyUnmatched: ownsHttpServer,
41
+ onDisconnected: (_peer, meta) => {
37
42
  rpcHost._emitSessionDisconnected(meta);
38
43
  }
39
44
  });
@@ -49,14 +54,14 @@ async function startHttpAndWs(options) {
49
54
  return { isTrusted: true };
50
55
  }
51
56
  });
52
- await new Promise((resolveListen) => {
57
+ if (ownsHttpServer) await new Promise((resolveListen) => {
53
58
  httpServer.listen(port, bindHost, () => resolveListen());
54
59
  });
55
60
  const address = httpServer.address();
56
61
  const resolvedPort = typeof address === "object" && address ? address.port : port;
57
62
  const origin = `http://${bindHost}:${resolvedPort}`;
58
63
  const internal = getInternalContext(context);
59
- const wsUrl = origin.replace(/^http/, "ws");
64
+ const wsUrl = `ws://${bindHost}:${separateWsPort ?? resolvedPort}${options.path ?? ""}`;
60
65
  internal.wsEndpoint = { url: wsUrl };
61
66
  if (options.onReady) await options.onReady({
62
67
  origin,
@@ -67,12 +72,11 @@ async function startHttpAndWs(options) {
67
72
  origin,
68
73
  port: resolvedPort,
69
74
  app,
70
- wss,
75
+ ws,
71
76
  rpcGroup,
72
77
  async close() {
73
- for (const ws of wss.clients) ws.terminate();
74
- await new Promise((r) => wss.close(() => r()));
75
- await new Promise((r) => httpServer.close(() => r()));
78
+ await closeWs();
79
+ if (ownsHttpServer) await new Promise((r) => httpServer.close(() => r()));
76
80
  if (getInternalContext(context).wsEndpoint?.url === wsUrl) getInternalContext(context).wsEndpoint = void 0;
77
81
  }
78
82
  };
@@ -836,10 +836,10 @@ function enablePatches() {
836
836
  const parentType = getArchtype(base);
837
837
  let p = path[i];
838
838
  if (typeof p !== "string" && typeof p !== "number") p = "" + p;
839
- if ((parentType === 0 || parentType === 1) && (p === "__proto__" || p === CONSTRUCTOR)) die(errorOffset + 3);
840
- if (isFunction(base) && p === PROTOTYPE) die(errorOffset + 3);
839
+ if ((parentType === 0 || parentType === 1) && (p === "__proto__" || p === CONSTRUCTOR)) die(19);
840
+ if (isFunction(base) && p === PROTOTYPE) die(19);
841
841
  base = get(base, p);
842
- if (!isObjectish(base)) die(errorOffset + 2, path.join("/"));
842
+ if (!isObjectish(base)) die(18, path.join("/"));
843
843
  }
844
844
  const type = getArchtype(base);
845
845
  const value = deepClonePatchValue(patch.value);
@@ -862,7 +862,7 @@ function enablePatches() {
862
862
  case 3: return base.delete(patch.value);
863
863
  default: return delete base[key];
864
864
  }
865
- default: die(errorOffset + 1, op);
865
+ default: die(17, op);
866
866
  }
867
867
  });
868
868
  return draft;
@@ -1,5 +1,8 @@
1
- import { t as devframeReporter } from "./diagnostics-reporter-CBBZwoMv.mjs";
1
+ import { t as devframeReporter } from "./diagnostics-reporter-CsIG85Q5.mjs";
2
2
  import { defineDiagnostics } from "nostics";
3
+ import fs from "node:fs";
4
+ import { dirname } from "pathe";
5
+ import { destr } from "destr";
3
6
  //#region src/node/diagnostics.ts
4
7
  const diagnostics = defineDiagnostics({
5
8
  docsBase: "https://devfra.me/errors",
@@ -39,6 +42,10 @@ const diagnostics = defineDiagnostics({
39
42
  DF0033: {
40
43
  why: (p) => `Failed to start dev RPC bridge for "${p.id}": ${p.reason}`,
41
44
  fix: "Verify the bridge port is free and the devframe setup function does not throw. Pin a port via `cli.port` / `cli.portRange` on the definition, or via `devMiddleware.port` on `viteDevBridge`."
45
+ },
46
+ DF0034: {
47
+ why: (p) => `Scoped RPC registration for namespace "${p.namespace}" received an already-namespaced function name "${p.name}".`,
48
+ fix: "A scoped context auto-namespaces ids. Pass a bare name without a \":\" separator (e.g. `register({ name: \"get-cwd\" })`), or use the unscoped `ctx.base.rpc.register` for a fully-qualified name."
42
49
  }
43
50
  }
44
51
  });
@@ -918,10 +925,10 @@ function enablePatches() {
918
925
  const parentType = getArchtype(base);
919
926
  let p = path[i];
920
927
  if (typeof p !== "string" && typeof p !== "number") p = "" + p;
921
- if ((parentType === 0 || parentType === 1) && (p === "__proto__" || p === CONSTRUCTOR)) die(errorOffset + 3);
922
- if (isFunction(base) && p === PROTOTYPE) die(errorOffset + 3);
928
+ if ((parentType === 0 || parentType === 1) && (p === "__proto__" || p === CONSTRUCTOR)) die(19);
929
+ if (isFunction(base) && p === PROTOTYPE) die(19);
923
930
  base = get(base, p);
924
- if (!isObjectish(base)) die(errorOffset + 2, path.join("/"));
931
+ if (!isObjectish(base)) die(18, path.join("/"));
925
932
  }
926
933
  const type = getArchtype(base);
927
934
  const value = deepClonePatchValue(patch.value);
@@ -944,7 +951,7 @@ function enablePatches() {
944
951
  case 3: return base.delete(patch.value);
945
952
  default: return delete base[key];
946
953
  }
947
- default: die(errorOffset + 1, op);
954
+ default: die(17, op);
948
955
  }
949
956
  });
950
957
  return draft;
@@ -1016,4 +1023,119 @@ function createSharedState(options) {
1016
1023
  };
1017
1024
  }
1018
1025
  //#endregion
1019
- export { diagnostics as i, nanoid as n, createEventEmitter as r, createSharedState as t };
1026
+ //#region ../../node_modules/.pnpm/perfect-debounce@2.1.0/node_modules/perfect-debounce/dist/index.mjs
1027
+ const DEBOUNCE_DEFAULTS = { trailing: true };
1028
+ /**
1029
+ Debounce functions
1030
+ @param fn - Promise-returning/async function to debounce.
1031
+ @param wait - Milliseconds to wait before calling `fn`. Default value is 25ms
1032
+ @returns A function that delays calling `fn` until after `wait` milliseconds have elapsed since the last time it was called.
1033
+ @example
1034
+ ```
1035
+ import { debounce } from 'perfect-debounce';
1036
+ const expensiveCall = async input => input;
1037
+ const debouncedFn = debounce(expensiveCall, 200);
1038
+ for (const number of [1, 2, 3]) {
1039
+ console.log(await debouncedFn(number));
1040
+ }
1041
+ //=> 1
1042
+ //=> 2
1043
+ //=> 3
1044
+ ```
1045
+ */
1046
+ function debounce(fn, wait = 25, options = {}) {
1047
+ options = {
1048
+ ...DEBOUNCE_DEFAULTS,
1049
+ ...options
1050
+ };
1051
+ if (!Number.isFinite(wait)) throw new TypeError("Expected `wait` to be a finite number");
1052
+ let leadingValue;
1053
+ let timeout;
1054
+ let resolveList = [];
1055
+ let currentPromise;
1056
+ let trailingArgs;
1057
+ const applyFn = (_this, args) => {
1058
+ currentPromise = _applyPromised(fn, _this, args);
1059
+ currentPromise.finally(() => {
1060
+ currentPromise = null;
1061
+ if (options.trailing && trailingArgs && !timeout) {
1062
+ const promise = applyFn(_this, trailingArgs);
1063
+ trailingArgs = null;
1064
+ return promise;
1065
+ }
1066
+ });
1067
+ return currentPromise;
1068
+ };
1069
+ const debounced = function(...args) {
1070
+ if (options.trailing) trailingArgs = args;
1071
+ if (currentPromise) return currentPromise;
1072
+ return new Promise((resolve) => {
1073
+ const shouldCallNow = !timeout && options.leading;
1074
+ clearTimeout(timeout);
1075
+ timeout = setTimeout(() => {
1076
+ timeout = null;
1077
+ const promise = options.leading ? leadingValue : applyFn(this, args);
1078
+ trailingArgs = null;
1079
+ for (const _resolve of resolveList) _resolve(promise);
1080
+ resolveList = [];
1081
+ }, wait);
1082
+ if (shouldCallNow) {
1083
+ leadingValue = applyFn(this, args);
1084
+ resolve(leadingValue);
1085
+ } else resolveList.push(resolve);
1086
+ });
1087
+ };
1088
+ const _clearTimeout = (timer) => {
1089
+ if (timer) {
1090
+ clearTimeout(timer);
1091
+ timeout = null;
1092
+ }
1093
+ };
1094
+ debounced.isPending = () => !!timeout;
1095
+ debounced.cancel = () => {
1096
+ _clearTimeout(timeout);
1097
+ resolveList = [];
1098
+ trailingArgs = null;
1099
+ };
1100
+ debounced.flush = () => {
1101
+ _clearTimeout(timeout);
1102
+ if (!trailingArgs || currentPromise) return;
1103
+ const args = trailingArgs;
1104
+ trailingArgs = null;
1105
+ return applyFn(this, args);
1106
+ };
1107
+ return debounced;
1108
+ }
1109
+ async function _applyPromised(fn, _this, args) {
1110
+ return await fn.apply(_this, args);
1111
+ }
1112
+ //#endregion
1113
+ //#region src/node/storage.ts
1114
+ function createStorage(options) {
1115
+ const { mergeInitialValue = (initialValue, savedValue) => ({
1116
+ ...initialValue,
1117
+ ...savedValue
1118
+ }), debounce: debounceTime = 100 } = options;
1119
+ let initialValue = options.initialValue;
1120
+ if (fs.existsSync(options.filepath)) try {
1121
+ const savedValue = destr(fs.readFileSync(options.filepath, "utf-8"), { strict: true });
1122
+ initialValue = mergeInitialValue ? mergeInitialValue(options.initialValue, savedValue) : savedValue;
1123
+ } catch (error) {
1124
+ diagnostics.DF0012({
1125
+ filepath: options.filepath,
1126
+ cause: error
1127
+ }, { method: "warn" });
1128
+ initialValue = options.initialValue;
1129
+ }
1130
+ const state = createSharedState({
1131
+ initialValue,
1132
+ enablePatches: false
1133
+ });
1134
+ state.on("updated", debounce((newState) => {
1135
+ fs.mkdirSync(dirname(options.filepath), { recursive: true });
1136
+ fs.writeFileSync(options.filepath, `${JSON.stringify(newState, null, 2)}\n`);
1137
+ }, debounceTime));
1138
+ return state;
1139
+ }
1140
+ //#endregion
1141
+ export { diagnostics as a, createEventEmitter as i, createSharedState as n, nanoid as r, createStorage as t };
@@ -1,4 +1,4 @@
1
- import { $ as AgentResource, B as EntriesToObject, G as DevframeRpcSharedStates, H as Thenable, J as DevframeDiagnosticsDefinition, K as DevframeHost, Q as AgentManifest, U as DevframeRpcClientFunctions, V as PartialWithoutId, W as DevframeRpcServerFunctions, X as DevframeDiagnosticsLogger, Y as DevframeDiagnosticsHost, Z as AgentHandle, _ as RpcStreamingChannel, a as DevframeRuntime, at as DevframeAgentHostEvents, c as defineDevframe, ct as EventsMap, d as DevframeNodeContext, et as AgentResourceContent, f as DevframeNodeRpcSession, g as RpcSharedStateHost, h as RpcSharedStateGetOptions, i as DevframeDeploymentKind, it as DevframeAgentHost, l as ConnectionMeta, m as RpcFunctionsHost, n as DevframeCliOptions, nt as AgentTool, o as DevframeSetupInfo, ot as EventEmitter, p as RpcBroadcastOptions, q as DevframeDefineDiagnosticsOptions, r as DevframeDefinition, rt as AgentToolInput, s as DevframeSpaOptions, st as EventUnsubscribe, t as DevframeBrowserContext, tt as AgentResourceInput, u as DevframeCapabilities, v as RpcStreamingChannelOptions, y as RpcStreamingHost, z as DevframeViewHost } from "../devframe-BuR6n9ZD.mjs";
2
- import { h as RpcFunctionAgentOptions } from "../types-BkkQ0Txg.mjs";
3
- import { t as DevframeNodeRpcSessionMeta } from "../ws-server-C1LjmRnp.mjs";
4
- export { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, ConnectionMeta, DevframeAgentHost, DevframeAgentHostEvents, DevframeBrowserContext, DevframeCapabilities, DevframeCliOptions, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsDefinition, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRuntime, DevframeSetupInfo, DevframeSpaOptions, DevframeViewHost, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, PartialWithoutId, RpcBroadcastOptions, RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, Thenable, defineDevframe };
1
+ import { $ as ScopedServerFunctions, G as DevframeScopedNodeContext, H as EntriesToObject, J as DevframeSettings, K as DevframeScopedNodeRpc, Q as ScopedClientFunctions, S as RpcStreamingHost, St as EventsMap, U as PartialWithoutId, W as Thenable, X as DevframeSettingsStore, Y as DevframeSettingsRegistry, Z as ScopedBroadcastOptions, _ as RpcFunctionsHost, _t as AgentToolInput, a as DevframeDuplicationStrategy, at as DevframeRpcSharedStates, b as RpcStreamingChannel, bt as EventEmitter, c as DevframeSpaOptions, ct as DevframeDiagnosticsDefinition, d as ConnectionMeta, dt as AgentHandle, et as ScopedSharedStates, f as ConnectionMetaWebsocket, ft as AgentManifest, g as RpcBroadcastOptions, gt as AgentTool, h as DevframeNodeRpcSession, ht as AgentResourceInput, i as DevframeDeploymentKind, it as DevframeRpcServerFunctions, l as DevframeWsOptions, lt as DevframeDiagnosticsHost, m as DevframeNodeContext, mt as AgentResourceContent, n as DevframeCliOptions, nt as DevframeViewHost, o as DevframeRuntime, ot as DevframeHost, p as DevframeCapabilities, pt as AgentResource, q as DevframeScopedStreamingHost, r as DevframeDefinition, rt as DevframeRpcClientFunctions, s as DevframeSetupInfo, st as DevframeDefineDiagnosticsOptions, t as DevframeBrowserContext, tt as SettingsForNamespace, u as defineDevframe, ut as DevframeDiagnosticsLogger, v as RpcSharedStateGetOptions, vt as DevframeAgentHost, x as RpcStreamingChannelOptions, xt as EventUnsubscribe, y as RpcSharedStateHost, yt as DevframeAgentHostEvents } from "../devframe-BwfavB78.mjs";
2
+ import { g as RpcFunctionAgentOptions } from "../types-DZEx4ffs.mjs";
3
+ import { t as DevframeNodeRpcSessionMeta } from "../ws-server-BVVMDo2n.mjs";
4
+ export { AgentHandle, AgentManifest, AgentResource, AgentResourceContent, AgentResourceInput, AgentTool, AgentToolInput, ConnectionMeta, ConnectionMetaWebsocket, DevframeAgentHost, DevframeAgentHostEvents, DevframeBrowserContext, DevframeCapabilities, DevframeCliOptions, DevframeDefineDiagnosticsOptions, DevframeDefinition, DevframeDeploymentKind, DevframeDiagnosticsDefinition, DevframeDiagnosticsHost, DevframeDiagnosticsLogger, DevframeDuplicationStrategy, DevframeHost, DevframeNodeContext, DevframeNodeRpcSession, DevframeNodeRpcSessionMeta, DevframeRpcClientFunctions, DevframeRpcServerFunctions, DevframeRpcSharedStates, DevframeRuntime, DevframeScopedNodeContext, DevframeScopedNodeRpc, DevframeScopedStreamingHost, DevframeSettings, DevframeSettingsRegistry, DevframeSettingsStore, DevframeSetupInfo, DevframeSpaOptions, DevframeViewHost, DevframeWsOptions, EntriesToObject, EventEmitter, EventUnsubscribe, EventsMap, PartialWithoutId, RpcBroadcastOptions, RpcFunctionAgentOptions, RpcFunctionsHost, RpcSharedStateGetOptions, RpcSharedStateHost, RpcStreamingChannel, RpcStreamingChannelOptions, RpcStreamingHost, ScopedBroadcastOptions, ScopedClientFunctions, ScopedServerFunctions, ScopedSharedStates, SettingsForNamespace, Thenable, defineDevframe };
@@ -282,8 +282,16 @@ type RpcFunctionDefinitionToFunction<T extends RpcFunctionDefinitionAny> = T ext
282
282
  type RpcFunctionDefinitionAny = RpcFunctionDefinition<string, any, any, any, any, any, any>;
283
283
  type RpcFunctionDefinitionAnyWithContext<CONTEXT = undefined> = RpcFunctionDefinition<string, any, any, any, any, any, CONTEXT>;
284
284
  type RpcDefinitionsToFunctions<T extends readonly RpcFunctionDefinitionAny[]> = EntriesToObject<{ [K in keyof T]: [T[K]['name'], RpcFunctionDefinitionToFunction<T[K]>] }>;
285
+ /**
286
+ * Like {@link RpcDefinitionsToFunctions}, but prefixes every (bare)
287
+ * definition name with `<NS>:`. Use this when functions are defined with
288
+ * bare names and registered through a scoped context
289
+ * (`ctx.scope(NS).rpc.register(...)`), so the augmented registry keys
290
+ * match the namespaced ids stored at runtime.
291
+ */
292
+ type RpcDefinitionsToFunctionsWithNamespace<NS extends string, T extends readonly RpcFunctionDefinitionAny[]> = EntriesToObject<{ [K in keyof T]: [`${NS}:${T[K]['name'] & string}`, RpcFunctionDefinitionToFunction<T[K]>] }>;
285
293
  type RpcDefinitionsFilter<T extends readonly RpcFunctionDefinitionAny[], Type extends RpcFunctionType> = { [K in keyof T]: T[K] extends {
286
294
  type: Type;
287
295
  } ? T[K] : never };
288
296
  //#endregion
289
- export { RpcFunctionsCollector as C, RpcFunctionType as S, Thenable as T, RpcFunctionDefinitionAny as _, RpcDefinitionsFilter as a, RpcFunctionDefinitionToFunction as b, RpcDumpClientOptions as c, RpcDumpGetter as d, RpcDumpRecord as f, RpcFunctionDefinition as g, RpcFunctionAgentOptions as h, RpcArgsSchema as i, RpcDumpCollectionOptions as l, RpcDumpStore as m, BirpcReturn$1 as n, RpcDefinitionsToFunctions as o, RpcDumpRecordError as p, EntriesToObject as r, RpcDump as s, BirpcFn as t, RpcDumpDefinition as u, RpcFunctionDefinitionAnyWithContext as v, RpcReturnSchema as w, RpcFunctionSetupResult as x, RpcFunctionDefinitionBase as y };
297
+ export { RpcFunctionType as C, Thenable as E, RpcFunctionSetupResult as S, RpcReturnSchema as T, RpcFunctionDefinition as _, RpcDefinitionsFilter as a, RpcFunctionDefinitionBase as b, RpcDump as c, RpcDumpDefinition as d, RpcDumpGetter as f, RpcFunctionAgentOptions as g, RpcDumpStore as h, RpcArgsSchema as i, RpcDumpClientOptions as l, RpcDumpRecordError as m, BirpcReturn$1 as n, RpcDefinitionsToFunctions as o, RpcDumpRecord as p, EntriesToObject as r, RpcDefinitionsToFunctionsWithNamespace as s, BirpcFn as t, RpcDumpCollectionOptions as u, RpcFunctionDefinitionAny as v, RpcFunctionsCollector as w, RpcFunctionDefinitionToFunction as x, RpcFunctionDefinitionAnyWithContext as y };
@@ -0,0 +1,24 @@
1
+ //#region src/utils/crypto-token.d.ts
2
+ /**
3
+ * Generate a high-entropy, URL-safe (hex) random token suitable for use as a
4
+ * bearer credential — e.g. the persistent client auth token or an ephemeral
5
+ * remote-dock token. Defaults to 16 bytes (128 bits) of entropy.
6
+ */
7
+ declare function randomToken(byteLength?: number): string;
8
+ /**
9
+ * Generate a uniformly-distributed string of decimal digits using rejection
10
+ * sampling to avoid modulo bias. Intended for short, human-typed one-time
11
+ * codes (e.g. a 6-digit authentication code). Leading zeros are preserved.
12
+ */
13
+ declare function randomDigits(length: number): string;
14
+ /**
15
+ * Constant-time string equality. Compares every character so the comparison
16
+ * time does not depend on the position of the first mismatch, mitigating
17
+ * timing side-channels when verifying secrets.
18
+ *
19
+ * Length is treated as public (it short-circuits on differing lengths), which
20
+ * is appropriate for fixed-length codes and tokens.
21
+ */
22
+ declare function timingSafeEqual(a: string, b: string): boolean;
23
+ //#endregion
24
+ export { randomDigits, randomToken, timingSafeEqual };