devframe 0.9.20 → 0.10.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 (100) hide show
  1. package/dist/_shared-B2PZsp-J.mjs +191 -0
  2. package/dist/{_shared-BIUet_Jh.d.mts → _shared-Dy1UBMUN.d.mts} +13 -14
  3. package/dist/adapters/build.d.mts +3 -4
  4. package/dist/adapters/build.mjs +4 -5
  5. package/dist/adapters/cac.d.mts +3 -4
  6. package/dist/adapters/cac.mjs +3 -3
  7. package/dist/adapters/dev.d.mts +8 -8
  8. package/dist/adapters/dev.mjs +2 -2
  9. package/dist/adapters/embedded.d.mts +1 -1
  10. package/dist/adapters/initiate.d.mts +8 -8
  11. package/dist/adapters/initiate.mjs +1 -1
  12. package/dist/adapters/mcp.d.mts +4 -142
  13. package/dist/adapters/mcp.mjs +1 -597
  14. package/dist/agentic-D4QQQUjE.d.mts +30 -0
  15. package/dist/cli/main.mjs +12 -260
  16. package/dist/client/index.d.mts +6 -6
  17. package/dist/client/index.mjs +3 -4
  18. package/dist/constants.d.mts +2 -1
  19. package/dist/constants.mjs +2 -1
  20. package/dist/{context-BA5FPz7K.d.mts → context-B4BKPuaa.d.mts} +1 -1
  21. package/dist/{context-BLXXjoBW.mjs → context-C141q8H4.mjs} +5 -5
  22. package/dist/{context-jXO5vzjH.mjs → context-CHpyLX8W.mjs} +1 -1
  23. package/dist/{context-BLHBDQcZ.d.mts → context-CTAxz9ec.d.mts} +108 -47
  24. package/dist/{dev-BdKKOH8S.mjs → dev-DM1mIlgi.mjs} +16 -24
  25. package/dist/{diagnostics-DZA6KQ_Z.mjs → diagnostics-Cx4_VjlG.mjs} +11 -3
  26. package/dist/dist-Bw3EbMj4.mjs +305 -0
  27. package/dist/dist-CO98PBnQ.mjs +265 -0
  28. package/dist/{host-agent-C3MBpNCd.mjs → host-agent-ZSKgzMVu.mjs} +2 -7
  29. package/dist/import-runtime-module-BzlEQ9PI.mjs +24 -0
  30. package/dist/in-page-channel/index.d.mts +2 -7
  31. package/dist/in-page-channel/index.mjs +1 -4
  32. package/dist/index-Bia1vKjL.d.mts +218 -0
  33. package/dist/{index-r6NstVmM.d.mts → index-CcPSKbxb.d.mts} +2 -2
  34. package/dist/index-CeEtxDmK.d.mts +78 -0
  35. package/dist/{index-CiA6C705.d.mts → index-DuEm0sDH.d.mts} +1 -1
  36. package/dist/index.d.mts +4 -11
  37. package/dist/index.mjs +1 -10
  38. package/dist/{instance-registry-DCq762YJ.mjs → instance-registry-DtvYxc0Y.mjs} +1 -1
  39. package/dist/{instance-shell-C6Vg97lg.d.mts → instance-shell-DOZSxst6.d.mts} +31 -5
  40. package/dist/{instance-shell-yfrM3_vK.mjs → instance-shell-wC2sfEU_.mjs} +7 -7
  41. package/dist/interactive-auth-BCa_iamv.mjs +384 -0
  42. package/dist/internal/index.d.mts +66 -22
  43. package/dist/internal/index.mjs +143 -8
  44. package/dist/mrmime-40h5OOIp.mjs +448 -0
  45. package/dist/node/auth.d.mts +2 -2
  46. package/dist/node/hub-internals.d.mts +2 -2
  47. package/dist/node/hub-internals.mjs +2 -2
  48. package/dist/node/index.d.mts +2 -4
  49. package/dist/node/index.mjs +2 -2
  50. package/dist/{nostics-0sKe5HIj.d.mts → nostics-DWvukRwa.d.mts} +11 -2
  51. package/dist/{origin-D_eBKEzr.mjs → origin-DZit9g29.mjs} +1 -21
  52. package/dist/recipes/interactive-auth.d.mts +2 -2
  53. package/dist/recipes/interactive-auth.mjs +1 -231
  54. package/dist/{remote-assets-D0StJVLp.mjs → remote-assets-B9MeWmW6.mjs} +2 -2
  55. package/dist/rpc/client.d.mts +1 -1
  56. package/dist/rpc/client.mjs +1 -1
  57. package/dist/rpc/dump.d.mts +2 -1
  58. package/dist/rpc/index.d.mts +3 -2
  59. package/dist/rpc/server.d.mts +1 -1
  60. package/dist/rpc/server.mjs +1 -1
  61. package/dist/rpc/transports/sse-client.d.mts +1 -1
  62. package/dist/rpc/transports/sse-server.d.mts +3 -3
  63. package/dist/rpc/transports/sse-server.mjs +1 -1
  64. package/dist/rpc/transports/ws-bun.d.mts +2 -2
  65. package/dist/rpc/transports/ws-bun.mjs +1 -1
  66. package/dist/rpc/transports/ws-client.d.mts +1 -1
  67. package/dist/rpc/transports/ws-deno.d.mts +2 -2
  68. package/dist/rpc/transports/ws-deno.mjs +1 -1
  69. package/dist/rpc/transports/ws-server.d.mts +1 -1
  70. package/dist/rpc/transports/ws-server.mjs +1 -1
  71. package/dist/{rpc-core-CvkU23bQ.mjs → rpc-core-BXyMjbKG.mjs} +1 -1
  72. package/dist/{rpc-core-BlL-Ip8n.d.mts → rpc-core-rLrwFEcw.d.mts} +4 -4
  73. package/dist/{services-install-Ben4yh52.mjs → services-install-D5YUwFXW.mjs} +17 -1
  74. package/dist/{sse-client-BcbYwXdD.d.mts → sse-client-DNdscfu_.d.mts} +2 -2
  75. package/dist/{storage-B70AXK64.mjs → storage-CHD1IkqU.mjs} +1 -1
  76. package/dist/types/index.d.mts +4 -4
  77. package/dist/{types-D2vGd7-2.d.mts → types-BmDbfHCx.d.mts} +2 -3
  78. package/dist/utils/debounce.d.mts +50 -0
  79. package/dist/utils/debounce.mjs +88 -0
  80. package/dist/utils/events.d.mts +1 -1
  81. package/dist/utils/launch-editor.d.mts +8 -0
  82. package/dist/utils/launch-editor.mjs +36 -1
  83. package/dist/utils/nostics.d.mts +2 -2
  84. package/dist/utils/remote-assets.mjs +1 -1
  85. package/dist/utils/serve-static.mjs +1 -1
  86. package/dist/utils/shared-state.d.mts +1 -1
  87. package/dist/utils/simple-schema.d.mts +3 -2
  88. package/dist/utils/streaming-channel.d.mts +1 -1
  89. package/dist/utils/url.d.mts +31 -0
  90. package/dist/utils/url.mjs +58 -0
  91. package/dist/{ws-client-CNpP6Ium.d.mts → ws-client-6Mrz6eC4.d.mts} +2 -2
  92. package/dist/{ws-server-BB8jhxeT.d.mts → ws-server-y2R76aSW.d.mts} +2 -2
  93. package/package.json +10 -11
  94. package/dist/_shared-U8D-xzrp.mjs +0 -115
  95. package/dist/agent-tool-name-DGzeuWcO.mjs +0 -31
  96. package/dist/client-assets-DNdhagGm.mjs +0 -16
  97. package/dist/nostics-DD6gsDZA.mjs +0 -108
  98. package/dist/recipes/common-rpc-functions.d.mts +0 -70
  99. package/dist/recipes/common-rpc-functions.mjs +0 -115
  100. package/dist/simple-schema-Bi40l-P6.mjs +0 -154
@@ -1,17 +1,15 @@
1
- import { t as resolveClientAssets } from "./client-assets-DNdhagGm.mjs";
2
1
  import { DEVFRAME_CONNECTION_META_FILENAME } from "./constants.mjs";
3
- import { t as diagnostics } from "./diagnostics-DZA6KQ_Z.mjs";
4
- import { t as createHostContext } from "./context-BLXXjoBW.mjs";
5
- import { t as resolveStaticAssetsSource } from "./remote-assets-D0StJVLp.mjs";
6
- import { a as resolveMcpConfig, i as resolveDevServerPort, n as normalizeBasePath, r as resolveBasePath, s as importRuntimeModule, t as loadAutoMcpAdapter } from "./_shared-U8D-xzrp.mjs";
2
+ import { t as diagnostics } from "./diagnostics-Cx4_VjlG.mjs";
3
+ import { t as createHostContext } from "./context-C141q8H4.mjs";
4
+ import { t as resolveStaticAssetsSource } from "./remote-assets-B9MeWmW6.mjs";
5
+ import { a as resolveMcpConfig, c as joinURL, d as withoutLeadingSlash, i as resolveDevServerPort, l as withBase, n as normalizeBasePath, r as resolveBasePath, s as importAgenticMcp, t as loadAutoMcpAdapter } from "./_shared-B2PZsp-J.mjs";
7
6
  import { t as createH3DevframeHost } from "./host-h3-BROI6SQ4.mjs";
8
- import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-yfrM3_vK.mjs";
7
+ import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-wC2sfEU_.mjs";
9
8
  import { open } from "./utils/open.mjs";
10
9
  import { mountStaticHandler } from "./utils/serve-static.mjs";
11
10
  import { resolve } from "pathe";
12
11
  import { createServer } from "node:http";
13
12
  import process from "node:process";
14
- import { joinURL, withBase, withoutLeadingSlash } from "ufo";
15
13
  import { H3, toNodeHandler } from "h3";
16
14
  //#region src/adapters/initiate.ts
17
15
  const INSTANCE_INTERNALS = /* @__PURE__ */ new WeakMap();
@@ -38,7 +36,7 @@ function getInstanceInternals(handler) {
38
36
  */
39
37
  function initDevframe(def, options) {
40
38
  const base = normalizeBasePath(options.base);
41
- const distDir = options.distDir === false ? void 0 : options.distDir ?? resolveClientAssets(def);
39
+ const distDir = options.distDir === false ? void 0 : options.distDir ?? def.clientAssets;
42
40
  const app = options.app ?? new H3();
43
41
  const host = options.host ?? def.cli?.host ?? "localhost";
44
42
  const shell = createInstanceShell({
@@ -88,7 +86,7 @@ function initDevframe(def, options) {
88
86
  for (const input of def.services ?? []) context.services.install(input, { resolveFrom: def.importMetaUrl });
89
87
  await context.services.ready();
90
88
  await def.setup(context, setupInfo);
91
- const mcp = await mountMcpRoute(app, context, def, base, options.mcp ?? def.cli?.mcp ?? "auto");
89
+ const mcp = await mountMcpRoute(app, context, def, base, options.mcp ?? "auto");
92
90
  return {
93
91
  context,
94
92
  ...mcp?.meta ? { mcp: mcp.meta } : {},
@@ -119,11 +117,14 @@ function initDevframe(def, options) {
119
117
  }
120
118
  /**
121
119
  * Mount the route-based MCP server at `<base>__mcp`, before the SPA static
122
- * catch-all so the exact route wins. The MCP SDK is pulled in dynamically
123
- * only when the route mounts, keeping it out of consumer bundles: `'auto'`
124
- * mounts once `setup()` left a non-empty agent surface (an empty surface
125
- * loads no MCP code); an explicit setting mounts unconditionally. The
126
- * resolved config is origin-only unless it opts into a bearer/callback.
120
+ * catch-all so the exact route wins. The adapter (from the optional
121
+ * `@devframes/agentic` peer) is pulled in dynamically only when the route
122
+ * mounts, keeping it and the MCP SDK out of consumer bundles: `'auto'`
123
+ * mounts once `setup()` left a non-empty agent surface AND the peer is
124
+ * installed (an empty surface loads no MCP code; a non-empty one without the
125
+ * peer warns once and mounts nothing); an explicit setting mounts
126
+ * unconditionally, throwing DF0079 when the peer is absent. The resolved
127
+ * config is origin-only unless it opts into a bearer/callback.
127
128
  */
128
129
  async function mountMcpRoute(app, context, def, base, setting) {
129
130
  let module;
@@ -134,16 +135,7 @@ async function mountMcpRoute(app, context, def, base, setting) {
134
135
  } else config = resolveMcpConfig(setting);
135
136
  if (!config) return void 0;
136
137
  const route = withoutLeadingSlash(config.path ?? "__mcp");
137
- if (!module) try {
138
- module = await importRuntimeModule("devframe/adapters/mcp");
139
- } catch (error) {
140
- const reason = error instanceof Error ? error.message : String(error);
141
- throw diagnostics.DF0017({
142
- transport: "http",
143
- reason,
144
- cause: error
145
- });
146
- }
138
+ module ??= await importAgenticMcp();
147
139
  const mounted = module.mountMcpHttp(app, context, joinURL(base, route), {
148
140
  serverName: `${def.id} (devframe)`,
149
141
  serverVersion: def.version ?? "0.0.0",
@@ -68,8 +68,8 @@ const diagnostics = defineDiagnostics({
68
68
  fix: "Discovery tooling (`devframe connect`) will not see this instance. Check that the registry directory is writable, point `DEVFRAME_INSTANCES_DIR` at a writable directory, or set `DEVFRAME_DISABLE_INSTANCE_REGISTRY=1` to opt out of registration."
69
69
  },
70
70
  DF0046: {
71
- why: (p) => `\`devframe connect\` requires the optional peer dependency @modelcontextprotocol/client: ${p.reason}`,
72
- fix: "Install it next to devframe (e.g. `npm install @modelcontextprotocol/client`) and run `devframe connect` again."
71
+ why: (p) => `\`devframe connect\` requires the optional peer dependency @devframes/agentic: ${p.reason}`,
72
+ fix: "Install it next to devframe (e.g. `npm install @devframes/agentic`) and run `devframe connect` again."
73
73
  },
74
74
  DF0047: {
75
75
  why: (p) => `Agent tool "${p.id}" is hidden from the MCP surface: its wire name "${p.name}" collides with the tool "${p.existing}".`,
@@ -89,7 +89,7 @@ const diagnostics = defineDiagnostics({
89
89
  },
90
90
  DF0051: {
91
91
  why: (p) => `The devframe instance on port ${p.port} has no MCP endpoint.`,
92
- fix: "Restart the instance with the --mcp flag (or set `cli.mcp: true` on its definition) to expose its tools, then list instances again."
92
+ fix: "Restart the instance with the --mcp flag to expose its tools, then list instances again."
93
93
  },
94
94
  DF0052: {
95
95
  why: (p) => `Failed to listen on ${p.host}:${p.port}: ${p.reason}`,
@@ -174,6 +174,14 @@ const diagnostics = defineDiagnostics({
174
174
  DF0076: {
175
175
  why: (p) => `\`attach\` / \`handleUpgrade\` drive a raw \`node:http\` upgrade into crossws's Node adapter, which refuses to run on ${p.runtime}.`,
176
176
  fix: "On Bun/Deno, serve the advertised `__ws` route from `Bun.serve` / `Deno.serve` with `attachBunWsTransport` / `attachDenoWsTransport` (see the hub-deno example), or connect over the SSE endpoint instead."
177
+ },
178
+ DF0078: {
179
+ why: "This devframe exposes agent tools, but the MCP endpoint stays off: the optional peer \"@devframes/agentic\" is not installed.",
180
+ fix: "Install `@devframes/agentic` next to devframe to serve the MCP endpoint, or set `mcp: false` to opt out silently."
181
+ },
182
+ DF0079: {
183
+ why: (p) => `The \`mcp\` option is enabled, but the optional peer "@devframes/agentic" could not be loaded: ${p.reason}`,
184
+ fix: "Install `@devframes/agentic` next to devframe (the MCP adapter and the MCP SDK live there), or remove the explicit `mcp` setting."
177
185
  }
178
186
  }
179
187
  });
@@ -0,0 +1,305 @@
1
+ import { colors } from "./utils/colors.mjs";
2
+ import { defineDiagnostics } from "nostics";
3
+ import { ansiFormatter } from "nostics/formatters/ansi";
4
+ //#region src/events.ts
5
+ /**
6
+ * Centralized registry of the core devframe event names: the node-side host
7
+ * bus events, the client RPC connection events, and the server→client
8
+ * broadcast notifications, so these names live in one place instead of
9
+ * scattered string literals.
10
+ *
11
+ * **Keep this in sync with [`docs/content/8.references/3.events.md`](../../../docs/content/8.references/3.events.md)**
12
+ * (the "Core devframe events" section): every name here appears in that page's
13
+ * tables, and every name there resolves to an entry here. Add, rename, or
14
+ * remove a name in both places in the same change, and reference
15
+ * `DEVFRAME_EVENTS.*` from call sites instead of re-typing a literal.
16
+ *
17
+ * This map covers **notifications** (events, broadcasts). The request/response
18
+ * RPC endpoints of the shared-state, streaming, and auth-handshake protocols
19
+ * (`devframe:rpc:server-state:*`, `devframe:streaming:subscribe`,
20
+ * `anonymous:devframe:auth`, …) are defined at their handlers and typed in
21
+ * `types/rpc-augments.ts`; they aren't events and stay out of this map.
22
+ *
23
+ * The `EventEmitter` maps (`RpcClientEvents`, `DevframeAgentHostEvents`) and the
24
+ * `DevframeRpcClientFunctions` augmentation declare these names as type-level
25
+ * keys (a literal is unavoidable in a type position); those declarations mirror
26
+ * this map and move with it.
27
+ */
28
+ const DEVFRAME_EVENTS = {
29
+ /**
30
+ * Node-side host `EventEmitter` events. The agent host (`ctx.agent.events`)
31
+ * emits these as its tool/resource surface changes; protocol adapters (e.g.
32
+ * MCP) subscribe to re-publish their manifest.
33
+ */
34
+ bus: {
35
+ agentManifestChanged: "agent:manifest:changed",
36
+ agentToolRegistered: "agent:tool:registered",
37
+ agentToolUnregistered: "agent:tool:unregistered",
38
+ agentResourceRegistered: "agent:resource:registered",
39
+ agentResourceUnregistered: "agent:resource:unregistered"
40
+ },
41
+ /**
42
+ * Client-side RPC connection `EventEmitter` events (`rpc.events`) a UI
43
+ * subscribes to for connection lifecycle and error surfacing.
44
+ */
45
+ client: {
46
+ isTrustedUpdated: "rpc:is-trusted:updated",
47
+ error: "rpc:error",
48
+ connectionStatus: "connection:status",
49
+ connectionError: "connection:error"
50
+ },
51
+ /**
52
+ * Broadcast notifications the server pushes to clients (server → client),
53
+ * `devframe:` prefix. The paired request methods (subscribe/get/set/…) are
54
+ * RPC endpoints, not events, and are omitted deliberately.
55
+ */
56
+ broadcast: {
57
+ authRevoked: "devframe:auth:revoked",
58
+ clientStateUpdated: "devframe:rpc:client-state:updated",
59
+ clientStatePatch: "devframe:rpc:client-state:patch",
60
+ streamingChunk: "devframe:streaming:chunk",
61
+ streamingEnd: "devframe:streaming:end",
62
+ streamingUploadCancel: "devframe:streaming:upload-cancel"
63
+ },
64
+ /**
65
+ * In-page channel notifications the page script pushes to its panels
66
+ * (page script → panel), `devframe:` prefix. The paired request methods
67
+ * (`devframe:in-page:page-state:subscribe`/`set`/`patch`) are call
68
+ * endpoints, not events, and are defined at their handlers
69
+ * (`in-page-channel/state.ts`).
70
+ */
71
+ inPageChannel: {
72
+ panelStateUpdated: "devframe:in-page:panel-state:updated",
73
+ panelStatePatch: "devframe:in-page:panel-state:patch"
74
+ },
75
+ /** `postMessage` channels the runtime posts across window boundaries. */
76
+ postMessage: {
77
+ remoteAssetsError: "devframe:remote-assets-error",
78
+ inPageChannel: "devframe:in-page-channel"
79
+ }
80
+ };
81
+ //#endregion
82
+ //#region src/utils/nostics.ts
83
+ const formatAnsi = ansiFormatter(colors);
84
+ /**
85
+ * The reporter every {@link defineDiagnostics} call below wires in ahead of
86
+ * any caller-supplied ones: prints the diagnostic through devframe's own
87
+ * ANSI colors via `console[method]` (default `'warn'`).
88
+ */
89
+ function devframeReporter(d, { method = "warn" } = {}) {
90
+ console[method](formatAnsi(d));
91
+ }
92
+ /**
93
+ * Drop-in replacement for `nostics`'s `defineDiagnostics()` with devframe's
94
+ * ANSI console reporter pre-wired ahead of any `reporters` passed in. Every
95
+ * `diagnostics.ts` in devframe core, `@devframes/hub`, `@devframes/json-render`,
96
+ * and the built-in plugins defines its codes through this instead of
97
+ * `nostics`'s own `defineDiagnostics`; the reporter registration lives
98
+ * here, once, so none of them need to build their own reporter (`colors`,
99
+ * `ansiFormatter`) or take a direct dependency on `nostics` themselves.
100
+ */
101
+ function defineDiagnostics$1(options) {
102
+ return defineDiagnostics({
103
+ ...options,
104
+ reporters: [devframeReporter, ...options.reporters ?? []]
105
+ });
106
+ }
107
+ //#endregion
108
+ //#region ../../node_modules/.pnpm/birpc@4.2.0/node_modules/birpc/dist/index.mjs
109
+ function createPromiseWithResolvers() {
110
+ let resolve;
111
+ let reject;
112
+ return {
113
+ promise: new Promise((res, rej) => {
114
+ resolve = res;
115
+ reject = rej;
116
+ }),
117
+ resolve,
118
+ reject
119
+ };
120
+ }
121
+ const random = Math.random.bind(Math);
122
+ const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
123
+ function nanoid(size = 21) {
124
+ let id = "";
125
+ let i = size;
126
+ while (i--) id += urlAlphabet[random() * 64 | 0];
127
+ return id;
128
+ }
129
+ const DEFAULT_TIMEOUT = 6e4;
130
+ const defaultSerialize = (i) => i;
131
+ const defaultDeserialize = defaultSerialize;
132
+ const { clearTimeout, setTimeout } = globalThis;
133
+ function createBirpc($functions, options) {
134
+ const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT, proxify = true } = options;
135
+ let $closed = false;
136
+ const _rpcPromiseMap = /* @__PURE__ */ new Map();
137
+ let _promiseInit;
138
+ let rpc;
139
+ async function _call(method, args, event, optional) {
140
+ if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
141
+ const req = {
142
+ m: method,
143
+ a: args,
144
+ t: "q"
145
+ };
146
+ if (optional) req.o = true;
147
+ const send = async (_req) => post(serialize(_req));
148
+ if (event) {
149
+ await send(req);
150
+ return;
151
+ }
152
+ if (_promiseInit) try {
153
+ await _promiseInit;
154
+ } finally {
155
+ _promiseInit = void 0;
156
+ }
157
+ let { promise, resolve, reject } = createPromiseWithResolvers();
158
+ const id = nanoid();
159
+ req.i = id;
160
+ let timeoutId;
161
+ async function handler(newReq = req) {
162
+ if (timeout >= 0) {
163
+ timeoutId = setTimeout(() => {
164
+ try {
165
+ if (options.onTimeoutError?.call(rpc, method, args) !== true) throw new Error(`[birpc] timeout on calling "${method}"`);
166
+ } catch (e) {
167
+ reject(e);
168
+ }
169
+ _rpcPromiseMap.delete(id);
170
+ }, timeout);
171
+ if (typeof timeoutId === "object") timeoutId = timeoutId.unref?.();
172
+ }
173
+ _rpcPromiseMap.set(id, {
174
+ resolve,
175
+ reject,
176
+ timeoutId,
177
+ method
178
+ });
179
+ await send(newReq);
180
+ return promise;
181
+ }
182
+ try {
183
+ if (options.onRequest) await options.onRequest.call(rpc, req, handler, resolve);
184
+ else await handler();
185
+ } catch (e) {
186
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
187
+ return;
188
+ } finally {
189
+ clearTimeout(timeoutId);
190
+ _rpcPromiseMap.delete(id);
191
+ }
192
+ return promise;
193
+ }
194
+ const builtinMethods = {
195
+ $call: (method, ...args) => _call(method, args, false),
196
+ $callOptional: (method, ...args) => _call(method, args, false, true),
197
+ $callEvent: (method, ...args) => _call(method, args, true),
198
+ $callRaw: (options) => _call(options.method, options.args, options.event, options.optional),
199
+ $rejectPendingCalls,
200
+ get $closed() {
201
+ return $closed;
202
+ },
203
+ get $meta() {
204
+ return options.meta;
205
+ },
206
+ $close,
207
+ $functions
208
+ };
209
+ if (proxify) rpc = new Proxy({}, { get(_, method) {
210
+ if (Object.hasOwn(builtinMethods, method)) return builtinMethods[method];
211
+ if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
212
+ const sendEvent = (...args) => _call(method, args, true);
213
+ if (eventNames.includes(method)) {
214
+ sendEvent.asEvent = sendEvent;
215
+ return sendEvent;
216
+ }
217
+ const sendCall = (...args) => _call(method, args, false);
218
+ sendCall.asEvent = sendEvent;
219
+ return sendCall;
220
+ } });
221
+ else rpc = builtinMethods;
222
+ function $close(customError) {
223
+ $closed = true;
224
+ _rpcPromiseMap.forEach(({ reject, method }) => {
225
+ const error = /* @__PURE__ */ new Error(`[birpc] rpc is closed, cannot call "${method}"`);
226
+ if (customError) {
227
+ customError.cause ??= error;
228
+ return reject(customError);
229
+ }
230
+ reject(error);
231
+ });
232
+ _rpcPromiseMap.clear();
233
+ off(onMessage);
234
+ }
235
+ function $rejectPendingCalls(handler) {
236
+ const handlerResults = Array.from(_rpcPromiseMap.values()).map(({ method, reject }) => {
237
+ if (!handler) return reject(/* @__PURE__ */ new Error(`[birpc]: rejected pending call "${method}".`));
238
+ return handler({
239
+ method,
240
+ reject
241
+ });
242
+ });
243
+ _rpcPromiseMap.clear();
244
+ return handlerResults;
245
+ }
246
+ async function onMessage(data, ...extra) {
247
+ let msg;
248
+ try {
249
+ msg = deserialize(data);
250
+ } catch (e) {
251
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
252
+ return;
253
+ }
254
+ if (msg.t === "q") {
255
+ const { m: method, a: args, o: optional } = msg;
256
+ let result, error;
257
+ let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
258
+ if (optional) fn ||= () => void 0;
259
+ if (!fn) error = /* @__PURE__ */ new Error(`[birpc] function "${method}" not found`);
260
+ else try {
261
+ result = await fn.apply(bind === "rpc" ? rpc : $functions, args);
262
+ } catch (e) {
263
+ error = e;
264
+ }
265
+ if (msg.i) {
266
+ if (error && options.onFunctionError) {
267
+ if (options.onFunctionError.call(rpc, error, method, args) === true) return;
268
+ }
269
+ if (!error) try {
270
+ await post(serialize({
271
+ t: "s",
272
+ i: msg.i,
273
+ r: result
274
+ }), ...extra);
275
+ return;
276
+ } catch (e) {
277
+ error = e;
278
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
279
+ }
280
+ try {
281
+ await post(serialize({
282
+ t: "s",
283
+ i: msg.i,
284
+ e: error
285
+ }), ...extra);
286
+ } catch (e) {
287
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
288
+ }
289
+ }
290
+ } else {
291
+ const { i: ack, r: result, e: error } = msg;
292
+ const promise = _rpcPromiseMap.get(ack);
293
+ if (promise) {
294
+ clearTimeout(promise.timeoutId);
295
+ if (error) promise.reject(error);
296
+ else promise.resolve(result);
297
+ }
298
+ _rpcPromiseMap.delete(ack);
299
+ }
300
+ }
301
+ _promiseInit = on(onMessage);
302
+ return rpc;
303
+ }
304
+ //#endregion
305
+ export { defineDiagnostics$1 as n, DEVFRAME_EVENTS as r, createBirpc as t };
@@ -0,0 +1,265 @@
1
+ //#region ../../node_modules/.pnpm/birpc@4.2.0/node_modules/birpc/dist/index.mjs
2
+ function createPromiseWithResolvers() {
3
+ let resolve;
4
+ let reject;
5
+ return {
6
+ promise: new Promise((res, rej) => {
7
+ resolve = res;
8
+ reject = rej;
9
+ }),
10
+ resolve,
11
+ reject
12
+ };
13
+ }
14
+ const _cacheMap = /* @__PURE__ */ new WeakMap();
15
+ function cachedMap(items, fn) {
16
+ return items.map((i) => {
17
+ let r = _cacheMap.get(i);
18
+ if (!r) {
19
+ r = fn(i);
20
+ _cacheMap.set(i, r);
21
+ }
22
+ return r;
23
+ });
24
+ }
25
+ const random = Math.random.bind(Math);
26
+ const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
27
+ function nanoid(size = 21) {
28
+ let id = "";
29
+ let i = size;
30
+ while (i--) id += urlAlphabet[random() * 64 | 0];
31
+ return id;
32
+ }
33
+ const DEFAULT_TIMEOUT = 6e4;
34
+ const defaultSerialize = (i) => i;
35
+ const defaultDeserialize = defaultSerialize;
36
+ const { clearTimeout, setTimeout } = globalThis;
37
+ function createBirpc($functions, options) {
38
+ const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT, proxify = true } = options;
39
+ let $closed = false;
40
+ const _rpcPromiseMap = /* @__PURE__ */ new Map();
41
+ let _promiseInit;
42
+ let rpc;
43
+ async function _call(method, args, event, optional) {
44
+ if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
45
+ const req = {
46
+ m: method,
47
+ a: args,
48
+ t: "q"
49
+ };
50
+ if (optional) req.o = true;
51
+ const send = async (_req) => post(serialize(_req));
52
+ if (event) {
53
+ await send(req);
54
+ return;
55
+ }
56
+ if (_promiseInit) try {
57
+ await _promiseInit;
58
+ } finally {
59
+ _promiseInit = void 0;
60
+ }
61
+ let { promise, resolve, reject } = createPromiseWithResolvers();
62
+ const id = nanoid();
63
+ req.i = id;
64
+ let timeoutId;
65
+ async function handler(newReq = req) {
66
+ if (timeout >= 0) {
67
+ timeoutId = setTimeout(() => {
68
+ try {
69
+ if (options.onTimeoutError?.call(rpc, method, args) !== true) throw new Error(`[birpc] timeout on calling "${method}"`);
70
+ } catch (e) {
71
+ reject(e);
72
+ }
73
+ _rpcPromiseMap.delete(id);
74
+ }, timeout);
75
+ if (typeof timeoutId === "object") timeoutId = timeoutId.unref?.();
76
+ }
77
+ _rpcPromiseMap.set(id, {
78
+ resolve,
79
+ reject,
80
+ timeoutId,
81
+ method
82
+ });
83
+ await send(newReq);
84
+ return promise;
85
+ }
86
+ try {
87
+ if (options.onRequest) await options.onRequest.call(rpc, req, handler, resolve);
88
+ else await handler();
89
+ } catch (e) {
90
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
91
+ return;
92
+ } finally {
93
+ clearTimeout(timeoutId);
94
+ _rpcPromiseMap.delete(id);
95
+ }
96
+ return promise;
97
+ }
98
+ const builtinMethods = {
99
+ $call: (method, ...args) => _call(method, args, false),
100
+ $callOptional: (method, ...args) => _call(method, args, false, true),
101
+ $callEvent: (method, ...args) => _call(method, args, true),
102
+ $callRaw: (options) => _call(options.method, options.args, options.event, options.optional),
103
+ $rejectPendingCalls,
104
+ get $closed() {
105
+ return $closed;
106
+ },
107
+ get $meta() {
108
+ return options.meta;
109
+ },
110
+ $close,
111
+ $functions
112
+ };
113
+ if (proxify) rpc = new Proxy({}, { get(_, method) {
114
+ if (Object.hasOwn(builtinMethods, method)) return builtinMethods[method];
115
+ if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
116
+ const sendEvent = (...args) => _call(method, args, true);
117
+ if (eventNames.includes(method)) {
118
+ sendEvent.asEvent = sendEvent;
119
+ return sendEvent;
120
+ }
121
+ const sendCall = (...args) => _call(method, args, false);
122
+ sendCall.asEvent = sendEvent;
123
+ return sendCall;
124
+ } });
125
+ else rpc = builtinMethods;
126
+ function $close(customError) {
127
+ $closed = true;
128
+ _rpcPromiseMap.forEach(({ reject, method }) => {
129
+ const error = /* @__PURE__ */ new Error(`[birpc] rpc is closed, cannot call "${method}"`);
130
+ if (customError) {
131
+ customError.cause ??= error;
132
+ return reject(customError);
133
+ }
134
+ reject(error);
135
+ });
136
+ _rpcPromiseMap.clear();
137
+ off(onMessage);
138
+ }
139
+ function $rejectPendingCalls(handler) {
140
+ const handlerResults = Array.from(_rpcPromiseMap.values()).map(({ method, reject }) => {
141
+ if (!handler) return reject(/* @__PURE__ */ new Error(`[birpc]: rejected pending call "${method}".`));
142
+ return handler({
143
+ method,
144
+ reject
145
+ });
146
+ });
147
+ _rpcPromiseMap.clear();
148
+ return handlerResults;
149
+ }
150
+ async function onMessage(data, ...extra) {
151
+ let msg;
152
+ try {
153
+ msg = deserialize(data);
154
+ } catch (e) {
155
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
156
+ return;
157
+ }
158
+ if (msg.t === "q") {
159
+ const { m: method, a: args, o: optional } = msg;
160
+ let result, error;
161
+ let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
162
+ if (optional) fn ||= () => void 0;
163
+ if (!fn) error = /* @__PURE__ */ new Error(`[birpc] function "${method}" not found`);
164
+ else try {
165
+ result = await fn.apply(bind === "rpc" ? rpc : $functions, args);
166
+ } catch (e) {
167
+ error = e;
168
+ }
169
+ if (msg.i) {
170
+ if (error && options.onFunctionError) {
171
+ if (options.onFunctionError.call(rpc, error, method, args) === true) return;
172
+ }
173
+ if (!error) try {
174
+ await post(serialize({
175
+ t: "s",
176
+ i: msg.i,
177
+ r: result
178
+ }), ...extra);
179
+ return;
180
+ } catch (e) {
181
+ error = e;
182
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
183
+ }
184
+ try {
185
+ await post(serialize({
186
+ t: "s",
187
+ i: msg.i,
188
+ e: error
189
+ }), ...extra);
190
+ } catch (e) {
191
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
192
+ }
193
+ }
194
+ } else {
195
+ const { i: ack, r: result, e: error } = msg;
196
+ const promise = _rpcPromiseMap.get(ack);
197
+ if (promise) {
198
+ clearTimeout(promise.timeoutId);
199
+ if (error) promise.reject(error);
200
+ else promise.resolve(result);
201
+ }
202
+ _rpcPromiseMap.delete(ack);
203
+ }
204
+ }
205
+ _promiseInit = on(onMessage);
206
+ return rpc;
207
+ }
208
+ function createBirpcGroup(functions, channels, options = {}) {
209
+ const { proxify = true } = options;
210
+ const getChannels = () => typeof channels === "function" ? channels() : channels;
211
+ const getClients = (channels = getChannels()) => cachedMap(channels, (s) => createBirpc(functions, {
212
+ ...options,
213
+ ...s
214
+ }));
215
+ function _boardcast(options) {
216
+ const clients = getClients();
217
+ return Promise.all(clients.map((c) => c.$callRaw(options)));
218
+ }
219
+ const broadcastBuiltin = {
220
+ $call: (method, ...args) => _boardcast({
221
+ method,
222
+ args,
223
+ event: false
224
+ }),
225
+ $callOptional: (method, ...args) => _boardcast({
226
+ method,
227
+ args,
228
+ event: false,
229
+ optional: true
230
+ }),
231
+ $callEvent: (method, ...args) => _boardcast({
232
+ method,
233
+ args,
234
+ event: true
235
+ }),
236
+ $callRaw: (options) => _boardcast(options)
237
+ };
238
+ const broadcastProxy = proxify ? new Proxy({}, { get(_, method) {
239
+ if (Object.hasOwn(broadcastBuiltin, method)) return broadcastBuiltin[method];
240
+ const callbacks = getClients().map((c) => c[method]);
241
+ const sendCall = (...args) => {
242
+ return Promise.all(callbacks.map((i) => i(...args)));
243
+ };
244
+ sendCall.asEvent = async (...args) => {
245
+ await Promise.all(callbacks.map((i) => i.asEvent(...args)));
246
+ };
247
+ return sendCall;
248
+ } }) : broadcastBuiltin;
249
+ function updateChannels(fn) {
250
+ const channels = getChannels();
251
+ fn?.(channels);
252
+ return getClients(channels);
253
+ }
254
+ getClients();
255
+ return {
256
+ get clients() {
257
+ return getClients();
258
+ },
259
+ functions,
260
+ updateChannels,
261
+ broadcast: broadcastProxy
262
+ };
263
+ }
264
+ //#endregion
265
+ export { createBirpcGroup as n, createBirpc as t };