devframe 0.5.4 → 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.
- package/dist/{_shared-CUFqO4kJ.mjs → _shared-bWRzeSa0.mjs} +2 -3
- package/dist/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +7 -7
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +2 -2
- package/dist/adapters/dev.d.mts +8 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +4 -4
- package/dist/client/index.d.mts +148 -6
- package/dist/client/index.mjs +257 -44
- package/dist/constants.d.mts +17 -1
- package/dist/constants.mjs +17 -1
- package/dist/context-3x_bgBgZ.mjs +48 -0
- package/dist/{context-DTRcO_UH.d.mts → context-o-TwncyP.d.mts} +1 -1
- package/dist/{dev-Cv43GfqM.mjs → dev-CSpLSEVh.mjs} +39 -13
- package/dist/{devframe-BuR6n9ZD.d.mts → devframe-BwfavB78.d.mts} +365 -15
- package/dist/{diagnostics-GitRGKbr.mjs → diagnostics-BXwBQmoN.mjs} +1 -1
- package/dist/{dump-9lKIJTLh.mjs → dump-DoXkj4ku.mjs} +1 -1
- package/dist/helpers/vite.d.mts +1 -1
- package/dist/helpers/vite.mjs +11 -11
- package/dist/{host-h3-Dgpgr1Ul.mjs → host-h3-C5SZlk03.mjs} +134 -6
- package/dist/{index-C7M1hnvL.d.mts → index-CxaPKDXX.d.mts} +2 -2
- package/dist/{index-DH2sBIwd.d.mts → index-DXHWuwJk.d.mts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/dist/node/auth.d.mts +43 -23
- package/dist/node/auth.mjs +84 -37
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +2 -2
- package/dist/node/index.d.mts +22 -6
- package/dist/node/index.mjs +4 -4
- package/dist/recipes/open-helpers.d.mts +1 -1
- package/dist/recipes/open-helpers.mjs +3 -3
- package/dist/revoke-ENfxWkFK.mjs +79 -0
- package/dist/rpc/dump.d.mts +1 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +3 -3
- package/dist/rpc/index.mjs +4 -4
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +2 -2
- package/dist/rpc/transports/ws-server.d.mts +2 -2
- package/dist/rpc/transports/ws-server.mjs +124 -60
- package/dist/{serialization-BD_qXGjd.mjs → serialization-DpLXCy13.mjs} +1 -1
- package/dist/{server-wHlpcdZ9.d.mts → server-oju7PTi2.d.mts} +30 -3
- package/dist/{server-BBaBJaUL.mjs → server-wyY3zh67.mjs} +18 -14
- package/dist/{shared-state-u0y123fi.mjs → shared-state-D4PPieA0.mjs} +4 -4
- package/dist/{shared-state-BlBNYziY.mjs → storage-l2ezeend.mjs} +128 -6
- package/dist/types/index.d.mts +4 -4
- package/dist/{types-BkkQ0Txg.d.mts → types-DZEx4ffs.d.mts} +9 -1
- package/dist/utils/crypto-token.d.mts +24 -0
- package/dist/utils/crypto-token.mjs +45 -0
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/hash.mjs +1 -1
- package/dist/utils/launch-editor.mjs +1 -1
- package/dist/utils/open.mjs +1 -1
- package/dist/utils/scope.d.mts +11 -0
- package/dist/utils/scope.mjs +15 -0
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/utils/structured-clone.mjs +1 -1
- package/dist/{ws-client-CVYX9niP.d.mts → ws-client-D0z0pOhn.d.mts} +1 -1
- package/dist/ws-server-BVVMDo2n.d.mts +103 -0
- package/package.json +12 -7
- package/skills/devframe/SKILL.md +123 -23
- package/skills/devframe/templates/counter-devframe.ts +14 -4
- package/skills/devframe/templates/spa-devframe.ts +13 -3
- package/skills/devframe/templates/vite-client.ts +3 -2
- package/dist/context-DaKmhhHY.mjs +0 -164
- package/dist/revoke-CL0LSAN9.mjs +0 -803
- package/dist/utils/human-id.d.mts +0 -8
- package/dist/utils/human-id.mjs +0 -769
- package/dist/ws-server-C1LjmRnp.d.mts +0 -61
- /package/dist/{define-CW9gLnyG.mjs → define-BLWPsH6y.mjs} +0 -0
- /package/dist/{diagnostics-reporter-CBBZwoMv.mjs → diagnostics-reporter-CsIG85Q5.mjs} +0 -0
- /package/dist/{hash-bwOD8RgU.mjs → hash-DFc5WwhO.mjs} +0 -0
- /package/dist/{launch-editor-BbNhtg7b.mjs → launch-editor-CgXBgviI.mjs} +0 -0
- /package/dist/{open-DiQn6zCH.mjs → open-Dusa2Zzd.mjs} +0 -0
- /package/dist/{structured-clone-PdCZwt7F.mjs → structured-clone-CeZOHvkd.mjs} +0 -0
- /package/dist/{structured-clone-jegjz0hM.mjs → structured-clone-XpHLZ8nr.mjs} +0 -0
- /package/dist/{transports-DTFoMUbE.mjs → transports-BmDVn4SF.mjs} +0 -0
package/dist/rpc/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
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-
|
|
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 };
|
package/dist/rpc/index.mjs
CHANGED
|
@@ -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-
|
|
2
|
-
import { t as diagnostics } from "../diagnostics-
|
|
3
|
-
import { n as defineRpcFunction, t as createDefineWrapperWithContext } from "../define-
|
|
4
|
-
import { n as strictJsonStringify, t as STRUCTURED_CLONE_PREFIX } from "../serialization-
|
|
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-
|
|
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-
|
|
2
|
-
import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-
|
|
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
|
|
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-
|
|
2
|
-
import { n as structuredCloneStringify, t as structuredCloneParse } from "../../structured-clone-
|
|
3
|
-
import { createServer } from "node:
|
|
4
|
-
import {
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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 {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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(
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { it as DevframeRpcServerFunctions, m as DevframeNodeContext, rt as DevframeRpcClientFunctions } from "./devframe-BwfavB78.mjs";
|
|
2
2
|
import { BirpcGroup } from "birpc";
|
|
3
|
-
import {
|
|
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
|
-
|
|
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-
|
|
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
|
|
19
|
-
const
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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 =
|
|
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
|
-
|
|
75
|
+
ws,
|
|
71
76
|
rpcGroup,
|
|
72
77
|
async close() {
|
|
73
|
-
|
|
74
|
-
await new Promise((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(
|
|
840
|
-
if (isFunction(base) && p === PROTOTYPE) die(
|
|
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(
|
|
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(
|
|
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-
|
|
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(
|
|
922
|
-
if (isFunction(base) && p === PROTOTYPE) die(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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 };
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import {
|
|
3
|
-
import { t as DevframeNodeRpcSessionMeta } from "../ws-server-
|
|
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 {
|
|
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 };
|