devframe 0.3.0 → 0.4.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/adapters/build.d.mts +1 -1
- package/dist/adapters/build.mjs +3 -3
- package/dist/adapters/cli.d.mts +2 -2
- package/dist/adapters/cli.mjs +1 -1
- package/dist/adapters/dev.d.mts +2 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/mcp.d.mts +1 -3
- package/dist/adapters/mcp.mjs +3 -3
- package/dist/client/index.d.mts +4 -18
- package/dist/client/index.mjs +6 -6
- package/dist/{context-CwjX6sCG.d.mts → context-C9oW88gr.d.mts} +1 -1
- package/dist/{dev-BbmanqL7.mjs → dev-C2wjXjGB.mjs} +1 -1
- package/dist/{devframe-sc4cb5xr.d.mts → devframe-K4IxpM4a.d.mts} +64 -13
- package/dist/{dump-zMleojnD.mjs → dump-B1wd4u68.mjs} +6 -6
- package/dist/helpers/vite.d.mts +1 -1
- package/dist/helpers/vite.mjs +2 -2
- package/dist/{host-h3-TTunNr_n.mjs → host-h3-Div5Vp8R.mjs} +13 -13
- package/dist/{index-C5PmWqBf.d.mts → index-BhtRKN7X.d.mts} +1 -1
- package/dist/{index-CTK6fuXs.d.mts → index-CBSBvT9K.d.mts} +2 -2
- package/dist/index.d.mts +3 -3
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/index.d.mts +5 -5
- package/dist/node/index.mjs +2 -2
- package/dist/node/internal.d.mts +2 -2
- package/dist/node/internal.mjs +1 -1
- package/dist/recipes/open-helpers.d.mts +1 -1
- package/dist/rpc/dump.d.mts +1 -1
- package/dist/rpc/dump.mjs +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +6 -6
- package/dist/rpc/transports/ws-client.d.mts +1 -25
- package/dist/rpc/transports/ws-client.mjs +1 -1
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/rpc/transports/ws-server.mjs +1 -1
- package/dist/{serialization-BlqLh4_J.mjs → serialization-BD_qXGjd.mjs} +1 -1
- package/dist/{server-ouL4gZbu.d.mts → server-KzCqriO9.d.mts} +1 -1
- package/dist/{storage-K-OxR1xf.mjs → storage-CZVTPKsw.mjs} +1 -1
- package/dist/types/index.d.mts +3 -3
- package/dist/{types-BXL7EIDM.d.mts → types-dNW3UmMl.d.mts} +1 -1
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/ws-client-BZptK_Mf.d.mts +26 -0
- package/dist/{ws-server-DOwLJL23.d.mts → ws-server-CTeMCO1r.d.mts} +2 -2
- package/package.json +4 -3
- package/dist/index-DTeZXHSi.d.mts +0 -639
|
@@ -1,639 +0,0 @@
|
|
|
1
|
-
import { defineDiagnostics } from "nostics";
|
|
2
|
-
import { BirpcReturn } from "birpc";
|
|
3
|
-
import { GenericSchema, InferInput } from "valibot";
|
|
4
|
-
//#region src/rpc/utils.d.ts
|
|
5
|
-
/** Infers TypeScript tuple type from Valibot schema array */
|
|
6
|
-
type InferArgsType<S extends RpcArgsSchema | undefined> = S extends readonly [] ? [] : S extends readonly [infer H, ...infer T] ? H extends GenericSchema ? T extends readonly GenericSchema[] ? [InferInput<H>, ...InferArgsType<T>] : never : never : never;
|
|
7
|
-
/** Infers TypeScript return type from Valibot return schema */
|
|
8
|
-
type InferReturnType<S extends RpcReturnSchema | undefined> = S extends RpcReturnSchema ? InferInput<S> : void;
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region src/rpc/types.d.ts
|
|
11
|
-
type Thenable<T> = T | Promise<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Type of the RPC function,
|
|
14
|
-
* - static: A function that returns a static data, no arguments (can be cached and dumped)
|
|
15
|
-
* - action: A function that performs an action (no data returned)
|
|
16
|
-
* - event: A function that emits an event (no data returned), and does not wait for a response
|
|
17
|
-
* - query: A function that queries a resource
|
|
18
|
-
*
|
|
19
|
-
* By default, the function is a query function.
|
|
20
|
-
*/
|
|
21
|
-
type RpcFunctionType = 'static' | 'action' | 'event' | 'query';
|
|
22
|
-
/**
|
|
23
|
-
* Agent exposure settings for an RPC function. When this field is set,
|
|
24
|
-
* the function is surfaced to agents (e.g. via the devframe MCP adapter)
|
|
25
|
-
* as a callable tool. Functions without an `agent` field are not exposed —
|
|
26
|
-
* default-deny.
|
|
27
|
-
*
|
|
28
|
-
* @experimental The agent-native surface is experimental and may change
|
|
29
|
-
* without a major version bump until it stabilizes.
|
|
30
|
-
*/
|
|
31
|
-
interface RpcFunctionAgentOptions {
|
|
32
|
-
/**
|
|
33
|
-
* Human-readable description shown to the agent. Required — agents
|
|
34
|
-
* rely on this to decide when to invoke the tool. Keep it to ~1–3
|
|
35
|
-
* sentences explaining what the tool does and when to use it.
|
|
36
|
-
*/
|
|
37
|
-
description: string;
|
|
38
|
-
/**
|
|
39
|
-
* Optional human-friendly display title. Maps to the MCP tool `title`
|
|
40
|
-
* annotation. Falls back to the RPC function `name` when omitted.
|
|
41
|
-
*/
|
|
42
|
-
title?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Safety classification. Drives MCP annotations (`readOnlyHint`,
|
|
45
|
-
* `destructiveHint`) downstream.
|
|
46
|
-
* - `'read'` — no side effects; safe to call freely.
|
|
47
|
-
* - `'action'` — mutates state but not destructive.
|
|
48
|
-
* - `'destructive'` — may perform destructive updates.
|
|
49
|
-
*
|
|
50
|
-
* When omitted it is inferred from the function `type`:
|
|
51
|
-
* - `'static'` / `'query'` → `'read'`
|
|
52
|
-
* - `'action'` / `'event'` → `'action'`
|
|
53
|
-
*/
|
|
54
|
-
safety?: 'read' | 'action' | 'destructive';
|
|
55
|
-
/** Free-form tags for grouping or filtering. */
|
|
56
|
-
tags?: readonly string[];
|
|
57
|
-
/**
|
|
58
|
-
* Optional example invocations shown to agents. Returned verbatim in
|
|
59
|
-
* the agent manifest.
|
|
60
|
-
*/
|
|
61
|
-
examples?: readonly {
|
|
62
|
-
args: unknown[];
|
|
63
|
-
description?: string;
|
|
64
|
-
}[];
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Manages dynamic function registration and provides a type-safe proxy for accessing functions.
|
|
68
|
-
*/
|
|
69
|
-
interface RpcFunctionsCollector<LocalFunctions, SetupContext = undefined> {
|
|
70
|
-
/** User-provided context passed to setup functions */
|
|
71
|
-
context: SetupContext;
|
|
72
|
-
/** Type-safe proxy for calling registered functions */
|
|
73
|
-
readonly functions: LocalFunctions;
|
|
74
|
-
/** Map of registered function definitions keyed by function name */
|
|
75
|
-
readonly definitions: Map<string, RpcFunctionDefinitionAnyWithContext<SetupContext>>;
|
|
76
|
-
/** Register a new function definition */
|
|
77
|
-
register: (fn: RpcFunctionDefinitionAnyWithContext<SetupContext>) => void;
|
|
78
|
-
/** Update an existing function definition */
|
|
79
|
-
update: (fn: RpcFunctionDefinitionAnyWithContext<SetupContext>) => void;
|
|
80
|
-
/** Subscribe to function changes, returns unsubscribe function */
|
|
81
|
-
onChanged: (fn: (id?: string) => void) => (() => void);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Result returned by a function's setup method.
|
|
85
|
-
*/
|
|
86
|
-
interface RpcFunctionSetupResult<ARGS extends any[], RETURN = void> {
|
|
87
|
-
/** Function handler */
|
|
88
|
-
handler?: (...args: ARGS) => RETURN;
|
|
89
|
-
/** Optional dump definition (overrides definition-level dump) */
|
|
90
|
-
dump?: RpcDumpDefinition<ARGS, RETURN>;
|
|
91
|
-
}
|
|
92
|
-
/** Valibot schema array for validating function arguments */
|
|
93
|
-
type RpcArgsSchema = readonly GenericSchema[];
|
|
94
|
-
/** Valibot schema for validating function return value */
|
|
95
|
-
type RpcReturnSchema = GenericSchema;
|
|
96
|
-
/**
|
|
97
|
-
* Serialized representation of a thrown value in a dump record.
|
|
98
|
-
*
|
|
99
|
-
* Errors are stored as plain objects so they round-trip through both the
|
|
100
|
-
* strict-JSON and structured-clone codecs. `message` and `name` are always
|
|
101
|
-
* present; `cause` and any own enumerable properties of the original
|
|
102
|
-
* `Error` are preserved on a best-effort basis. Non-`Error` throws are
|
|
103
|
-
* normalized to `{ name: 'Error', message: String(thrown) }`.
|
|
104
|
-
*/
|
|
105
|
-
interface RpcDumpRecordError {
|
|
106
|
-
/** Error message (mirrors `Error.message`). */
|
|
107
|
-
message: string;
|
|
108
|
-
/** Error type name (e.g., "Error", "TypeError"). */
|
|
109
|
-
name: string;
|
|
110
|
-
/** `Error.cause`, recursively serialized when it is itself an `Error`. */
|
|
111
|
-
cause?: unknown;
|
|
112
|
-
/** Own enumerable properties of the original error (excluding `message`/`name`/`cause`). */
|
|
113
|
-
[key: string]: unknown;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Single record in a dump store with pre-computed results.
|
|
117
|
-
*/
|
|
118
|
-
interface RpcDumpRecord<ARGS extends any[] = any[], RETURN = any> {
|
|
119
|
-
/** Function arguments */
|
|
120
|
-
inputs: ARGS;
|
|
121
|
-
/** Result (value or lazy function) */
|
|
122
|
-
output?: RETURN;
|
|
123
|
-
/** Error if execution failed */
|
|
124
|
-
error?: RpcDumpRecordError;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Defines argument combinations to pre-compute for a function.
|
|
128
|
-
*/
|
|
129
|
-
interface RpcDumpDefinition<ARGS extends any[] = any[], RETURN = any> {
|
|
130
|
-
/** Argument combinations to pre-compute by executing handler */
|
|
131
|
-
inputs?: ARGS[];
|
|
132
|
-
/** Pre-computed records to use directly (bypasses handler execution) */
|
|
133
|
-
records?: RpcDumpRecord<ARGS, RETURN>[];
|
|
134
|
-
/** Fallback value when no match found */
|
|
135
|
-
fallback?: RETURN;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Dynamically generates dump definitions based on context.
|
|
139
|
-
*/
|
|
140
|
-
type RpcDumpGetter<ARGS extends any[] = any[], RETURN = any, CONTEXT = any> = (context: CONTEXT, handler: (...args: ARGS) => RETURN) => Thenable<RpcDumpDefinition<ARGS, RETURN>>;
|
|
141
|
-
/**
|
|
142
|
-
* Dump configuration (static object or dynamic function).
|
|
143
|
-
*/
|
|
144
|
-
type RpcDump<ARGS extends any[] = any[], RETURN = any, CONTEXT = any> = RpcDumpDefinition<ARGS, RETURN> | RpcDumpGetter<ARGS, RETURN, CONTEXT>;
|
|
145
|
-
/**
|
|
146
|
-
* RPC function definition with optional dump support.
|
|
147
|
-
*/
|
|
148
|
-
type RpcFunctionDefinition<NAME extends string, TYPE extends RpcFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined, CONTEXT = undefined> = [AS, RS] extends [undefined, undefined] ? {
|
|
149
|
-
/** Function name (unique identifier) */name: NAME; /** Function type (static, action, event, or query) */
|
|
150
|
-
type?: TYPE; /** Whether the function results should be cached */
|
|
151
|
-
cacheable?: boolean; /** Valibot schema array for validating function arguments */
|
|
152
|
-
args?: AS; /** Valibot schema for validating function return value */
|
|
153
|
-
returns?: RS;
|
|
154
|
-
/**
|
|
155
|
-
* Declares whether this function's args/return are JSON-serializable
|
|
156
|
-
* (no Map/Set/Date/BigInt/cycles/class instances/undefined/Symbol/Function).
|
|
157
|
-
*
|
|
158
|
-
* - `true` — wire and dump use strict `JSON.stringify`; misshapen
|
|
159
|
-
* values throw `DF0019` at the call site. Required for `agent`.
|
|
160
|
-
* - `false` (default) — `structured-clone-es` round-trips fancy
|
|
161
|
-
* types. Cannot be `agent`-exposed (registration throws `DF0018`).
|
|
162
|
-
*/
|
|
163
|
-
jsonSerializable?: boolean;
|
|
164
|
-
/**
|
|
165
|
-
* Expose this function to agents (e.g. via the MCP adapter).
|
|
166
|
-
* When omitted, the function is not agent-exposed (default-deny).
|
|
167
|
-
*
|
|
168
|
-
* @experimental
|
|
169
|
-
*/
|
|
170
|
-
agent?: RpcFunctionAgentOptions; /** Setup function called with context to initialize handler and dump */
|
|
171
|
-
setup?: (context: CONTEXT) => Thenable<RpcFunctionSetupResult<ARGS, RETURN>>; /** Function implementation (required if setup doesn't provide one) */
|
|
172
|
-
handler?: (...args: ARGS) => RETURN; /** Dump definition (setup dump takes priority) */
|
|
173
|
-
dump?: RpcDump<ARGS, RETURN, CONTEXT>;
|
|
174
|
-
/**
|
|
175
|
-
* Sugar for "query in dev, single baked snapshot in build": when
|
|
176
|
-
* `true` and no `dump` is provided, the build adapter runs the
|
|
177
|
-
* handler once with no arguments and stores the result as both a
|
|
178
|
-
* no-args record and the fallback so any call variant resolves
|
|
179
|
-
* to the same snapshot. Only valid on `query` (or untyped)
|
|
180
|
-
* functions — `static` already has equivalent default behavior.
|
|
181
|
-
*/
|
|
182
|
-
snapshot?: boolean;
|
|
183
|
-
__resolved?: RpcFunctionSetupResult<ARGS, RETURN>;
|
|
184
|
-
__promise?: Thenable<RpcFunctionSetupResult<ARGS, RETURN>>;
|
|
185
|
-
} : {
|
|
186
|
-
/** Function name (unique identifier) */name: NAME; /** Function type (static, action, event, or query) */
|
|
187
|
-
type?: TYPE; /** Whether the function results should be cached */
|
|
188
|
-
cacheable?: boolean; /** Valibot schema array for validating function arguments */
|
|
189
|
-
args: AS; /** Valibot schema for validating function return value */
|
|
190
|
-
returns: RS;
|
|
191
|
-
/**
|
|
192
|
-
* Declares whether this function's args/return are JSON-serializable
|
|
193
|
-
* (no Map/Set/Date/BigInt/cycles/class instances/undefined/Symbol/Function).
|
|
194
|
-
*
|
|
195
|
-
* - `true` — wire and dump use strict `JSON.stringify`; misshapen
|
|
196
|
-
* values throw `DF0019` at the call site. Required for `agent`.
|
|
197
|
-
* - `false` (default) — `structured-clone-es` round-trips fancy
|
|
198
|
-
* types. Cannot be `agent`-exposed (registration throws `DF0018`).
|
|
199
|
-
*/
|
|
200
|
-
jsonSerializable?: boolean;
|
|
201
|
-
/**
|
|
202
|
-
* Expose this function to agents (e.g. via the MCP adapter).
|
|
203
|
-
* When omitted, the function is not agent-exposed (default-deny).
|
|
204
|
-
*
|
|
205
|
-
* @experimental
|
|
206
|
-
*/
|
|
207
|
-
agent?: RpcFunctionAgentOptions; /** Setup function called with context to initialize handler and dump */
|
|
208
|
-
setup?: (context: CONTEXT) => Thenable<RpcFunctionSetupResult<InferArgsType<AS>, InferReturnType<RS>>>; /** Function implementation (required if setup doesn't provide one) */
|
|
209
|
-
handler?: (...args: InferArgsType<AS>) => InferReturnType<RS>; /** Dump definition (setup dump takes priority) */
|
|
210
|
-
dump?: RpcDump<InferArgsType<AS>, InferReturnType<RS>, CONTEXT>;
|
|
211
|
-
/**
|
|
212
|
-
* Sugar for "query in dev, single baked snapshot in build": when
|
|
213
|
-
* `true` and no `dump` is provided, the build adapter runs the
|
|
214
|
-
* handler once with no arguments and stores the result as both a
|
|
215
|
-
* no-args record and the fallback so any call variant resolves
|
|
216
|
-
* to the same snapshot. Only valid on `query` (or untyped)
|
|
217
|
-
* functions — `static` already has equivalent default behavior.
|
|
218
|
-
*/
|
|
219
|
-
snapshot?: boolean;
|
|
220
|
-
__resolved?: RpcFunctionSetupResult<InferArgsType<AS>, InferReturnType<RS>>;
|
|
221
|
-
__promise?: Thenable<RpcFunctionSetupResult<InferArgsType<AS>, InferReturnType<RS>>>;
|
|
222
|
-
};
|
|
223
|
-
type RpcFunctionDefinitionAny = RpcFunctionDefinition<string, any, any, any, any, any, any>;
|
|
224
|
-
type RpcFunctionDefinitionAnyWithContext<CONTEXT = undefined> = RpcFunctionDefinition<string, any, any, any, any, any, CONTEXT>;
|
|
225
|
-
//#endregion
|
|
226
|
-
//#region src/rpc/cache.d.ts
|
|
227
|
-
interface RpcCacheOptions {
|
|
228
|
-
functions: string[];
|
|
229
|
-
keySerializer?: (args: unknown[]) => string;
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* @experimental API is expected to change.
|
|
233
|
-
*/
|
|
234
|
-
declare class RpcCacheManager {
|
|
235
|
-
private cacheMap;
|
|
236
|
-
private options;
|
|
237
|
-
private keySerializer;
|
|
238
|
-
constructor(options: RpcCacheOptions);
|
|
239
|
-
updateOptions(options: Partial<RpcCacheOptions>): void;
|
|
240
|
-
cached<T>(m: string, a: unknown[]): T | undefined;
|
|
241
|
-
apply(req: {
|
|
242
|
-
m: string;
|
|
243
|
-
a: unknown[];
|
|
244
|
-
}, res: unknown): void;
|
|
245
|
-
validate(m: string): boolean;
|
|
246
|
-
clear(fn?: string): void;
|
|
247
|
-
}
|
|
248
|
-
//#endregion
|
|
249
|
-
//#region src/types/events.d.ts
|
|
250
|
-
interface EventsMap {
|
|
251
|
-
[event: string]: any;
|
|
252
|
-
}
|
|
253
|
-
interface EventUnsubscribe {
|
|
254
|
-
(): void;
|
|
255
|
-
}
|
|
256
|
-
interface EventEmitter<Events extends EventsMap> {
|
|
257
|
-
/**
|
|
258
|
-
* Calls each of the listeners registered for a given event.
|
|
259
|
-
*
|
|
260
|
-
* ```js
|
|
261
|
-
* ee.emit('tick', tickType, tickDuration)
|
|
262
|
-
* ```
|
|
263
|
-
*
|
|
264
|
-
* @param event The event name.
|
|
265
|
-
* @param args The arguments for listeners.
|
|
266
|
-
*/
|
|
267
|
-
emit: <K extends keyof Events>(event: K, ...args: Parameters<Events[K]>) => void;
|
|
268
|
-
/**
|
|
269
|
-
* Calls the listeners for a given event once and then removes the listener.
|
|
270
|
-
*
|
|
271
|
-
* @param event The event name.
|
|
272
|
-
* @param args The arguments for listeners.
|
|
273
|
-
*/
|
|
274
|
-
emitOnce: <K extends keyof Events>(event: K, ...args: Parameters<Events[K]>) => void;
|
|
275
|
-
/**
|
|
276
|
-
* Event names in keys and arrays with listeners in values.
|
|
277
|
-
*
|
|
278
|
-
* @internal
|
|
279
|
-
*/
|
|
280
|
-
_listeners: Partial<{ [E in keyof Events]: Events[E][] }>;
|
|
281
|
-
/**
|
|
282
|
-
* Add a listener for a given event.
|
|
283
|
-
*
|
|
284
|
-
* ```js
|
|
285
|
-
* const unbind = ee.on('tick', (tickType, tickDuration) => {
|
|
286
|
-
* count += 1
|
|
287
|
-
* })
|
|
288
|
-
*
|
|
289
|
-
* disable () {
|
|
290
|
-
* unbind()
|
|
291
|
-
* }
|
|
292
|
-
* ```
|
|
293
|
-
*
|
|
294
|
-
* @param event The event name.
|
|
295
|
-
* @param cb The listener function.
|
|
296
|
-
* @returns Unbind listener from event.
|
|
297
|
-
*/
|
|
298
|
-
on: <K extends keyof Events>(event: K, cb: Events[K]) => EventUnsubscribe;
|
|
299
|
-
/**
|
|
300
|
-
* Add a listener for a given event once.
|
|
301
|
-
*
|
|
302
|
-
* ```js
|
|
303
|
-
* const unbind = ee.once('tick', (tickType, tickDuration) => {
|
|
304
|
-
* count += 1
|
|
305
|
-
* })
|
|
306
|
-
*
|
|
307
|
-
* disable () {
|
|
308
|
-
* unbind()
|
|
309
|
-
* }
|
|
310
|
-
* ```
|
|
311
|
-
*
|
|
312
|
-
* @param event The event name.
|
|
313
|
-
* @param cb The listener function.
|
|
314
|
-
* @returns Unbind listener from event.
|
|
315
|
-
*/
|
|
316
|
-
once: <K extends keyof Events>(event: K, cb: Events[K]) => EventUnsubscribe;
|
|
317
|
-
}
|
|
318
|
-
//#endregion
|
|
319
|
-
//#region src/utils/shared-state.d.ts
|
|
320
|
-
type ImmutablePrimitive = undefined | null | boolean | string | number | Function;
|
|
321
|
-
type Immutable<T> = T extends ImmutablePrimitive ? T : T extends Array<infer U> ? ImmutableArray<U> : T extends Map<infer K, infer V> ? ImmutableMap<K, V> : T extends Set<infer M> ? ImmutableSet<M> : ImmutableObject<T>;
|
|
322
|
-
type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
|
|
323
|
-
type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
|
|
324
|
-
type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
|
|
325
|
-
type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
|
|
326
|
-
/**
|
|
327
|
-
* Serializable patch describing a single mutation to a `SharedState`.
|
|
328
|
-
* Structurally compatible with JSON-Patch and is safe to send over RPC.
|
|
329
|
-
*/
|
|
330
|
-
interface SharedStatePatch {
|
|
331
|
-
op: 'add' | 'remove' | 'replace';
|
|
332
|
-
path: readonly (string | number)[];
|
|
333
|
-
value?: unknown;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* State host that is immutable by default with explicit mutate.
|
|
337
|
-
*/
|
|
338
|
-
interface SharedState<T> {
|
|
339
|
-
/**
|
|
340
|
-
* Get the current state. Immutable.
|
|
341
|
-
*/
|
|
342
|
-
value: () => Immutable<T>;
|
|
343
|
-
/**
|
|
344
|
-
* Subscribe to state changes.
|
|
345
|
-
*/
|
|
346
|
-
on: EventEmitter<SharedStateEvents<T>>['on'];
|
|
347
|
-
/**
|
|
348
|
-
* Mutate the state.
|
|
349
|
-
*/
|
|
350
|
-
mutate: (fn: (state: T) => void, syncId?: string) => void;
|
|
351
|
-
/**
|
|
352
|
-
* Apply patches to the state.
|
|
353
|
-
*/
|
|
354
|
-
patch: (patches: SharedStatePatch[], syncId?: string) => void;
|
|
355
|
-
/**
|
|
356
|
-
* Sync IDs that have been applied to the state.
|
|
357
|
-
*/
|
|
358
|
-
syncIds: Set<string>;
|
|
359
|
-
}
|
|
360
|
-
interface SharedStateEvents<T> {
|
|
361
|
-
updated: (fullState: T, patches: SharedStatePatch[] | undefined, syncId: string) => void;
|
|
362
|
-
}
|
|
363
|
-
interface SharedStateOptions<T> {
|
|
364
|
-
/**
|
|
365
|
-
* Initial state.
|
|
366
|
-
*/
|
|
367
|
-
initialValue: T;
|
|
368
|
-
/**
|
|
369
|
-
* Enable patches.
|
|
370
|
-
*
|
|
371
|
-
* @default false
|
|
372
|
-
*/
|
|
373
|
-
enablePatches?: boolean;
|
|
374
|
-
}
|
|
375
|
-
declare function createSharedState<T extends object>(options: SharedStateOptions<T>): SharedState<T>;
|
|
376
|
-
//#endregion
|
|
377
|
-
//#region src/utils/streaming-channel.d.ts
|
|
378
|
-
/**
|
|
379
|
-
* Serialized error shape sent over the wire when a stream ends with a failure.
|
|
380
|
-
* Stays JSON-safe so the strict-JSON encoder can carry it without coercion.
|
|
381
|
-
*/
|
|
382
|
-
interface StreamErrorPayload {
|
|
383
|
-
name: string;
|
|
384
|
-
message: string;
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Single buffered chunk in the server-side ring buffer.
|
|
388
|
-
*
|
|
389
|
-
* Sequence numbers start at 1 and increment per write. Subscribers track
|
|
390
|
-
* `lastSeenSeq` and ask for `afterSeq` on resubscribe so the server can
|
|
391
|
-
* replay any chunks the client missed during a brief disconnect.
|
|
392
|
-
*/
|
|
393
|
-
interface BufferedChunk<T> {
|
|
394
|
-
seq: number;
|
|
395
|
-
chunk: T;
|
|
396
|
-
}
|
|
397
|
-
interface StreamSinkEvents<T> {
|
|
398
|
-
/** Fired for each `write()`. The RPC layer subscribes and broadcasts. */
|
|
399
|
-
chunk: (seq: number, chunk: T) => void;
|
|
400
|
-
/** Terminal — fired exactly once per sink lifetime. */
|
|
401
|
-
end: (error?: StreamErrorPayload) => void;
|
|
402
|
-
}
|
|
403
|
-
interface CreateStreamSinkOptions {
|
|
404
|
-
id?: string;
|
|
405
|
-
/**
|
|
406
|
-
* Size of the per-stream ring buffer kept for replay-on-resubscribe.
|
|
407
|
-
* `0` (default) disables replay.
|
|
408
|
-
*/
|
|
409
|
-
replayWindow?: number;
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Server-side producer handle. Two equivalent surfaces share one piece of
|
|
413
|
-
* state: the imperative `write/error/close` triple, and a `WritableStream<T>`
|
|
414
|
-
* for `pipeTo`-style consumption.
|
|
415
|
-
*/
|
|
416
|
-
interface StreamSink<T> {
|
|
417
|
-
/** Stable id used by clients to subscribe. */
|
|
418
|
-
readonly id: string;
|
|
419
|
-
/**
|
|
420
|
-
* Aborts when the consumer cancels (server-side) or when the transport
|
|
421
|
-
* loses every subscriber. Producers should poll `signal.aborted` and exit
|
|
422
|
-
* cleanly.
|
|
423
|
-
*/
|
|
424
|
-
readonly signal: AbortSignal;
|
|
425
|
-
/** `true` after `close()` / `error()`. Further writes throw. */
|
|
426
|
-
readonly closed: boolean;
|
|
427
|
-
/** Last allocated sequence number. `0` until the first write. */
|
|
428
|
-
readonly lastSeq: number;
|
|
429
|
-
write: (chunk: T) => void;
|
|
430
|
-
error: (reason: unknown) => void;
|
|
431
|
-
close: () => void;
|
|
432
|
-
/** External-cancel path. Aborts the signal so handlers can short-circuit. */
|
|
433
|
-
abort: (reason?: unknown) => void;
|
|
434
|
-
/** `WritableStream<T>` adapter — same in-memory state as the imperative API. */
|
|
435
|
-
readonly writable: WritableStream<T>;
|
|
436
|
-
/**
|
|
437
|
-
* Internal — RPC layer subscribes to receive chunk/end notifications.
|
|
438
|
-
* Not part of the public contract; do not call directly.
|
|
439
|
-
*
|
|
440
|
-
* @internal
|
|
441
|
-
*/
|
|
442
|
-
readonly events: EventEmitter<StreamSinkEvents<T>>;
|
|
443
|
-
/**
|
|
444
|
-
* Internal — replay buffer. RPC layer reads on (re)subscribe to feed
|
|
445
|
-
* missed chunks before going live.
|
|
446
|
-
*
|
|
447
|
-
* @internal
|
|
448
|
-
*/
|
|
449
|
-
readonly buffer: ReadonlyArray<BufferedChunk<T>>;
|
|
450
|
-
}
|
|
451
|
-
interface CreateStreamReaderOptions {
|
|
452
|
-
id?: string;
|
|
453
|
-
/**
|
|
454
|
-
* Maximum number of buffered chunks held client-side while the consumer
|
|
455
|
-
* isn't draining. On overflow, the oldest chunk is dropped.
|
|
456
|
-
*/
|
|
457
|
-
highWaterMark?: number;
|
|
458
|
-
/**
|
|
459
|
-
* Called when the chunk queue overflows the high-water mark. The RPC
|
|
460
|
-
* layer wires this to a coded warning; the primitive itself is
|
|
461
|
-
* RPC-agnostic.
|
|
462
|
-
*/
|
|
463
|
-
onOverflow?: (dropped: number) => void;
|
|
464
|
-
/** Called when the consumer cancels — the RPC layer sends `:cancel` upstream. */
|
|
465
|
-
onCancel?: () => void;
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Client-side consumer handle. Both an `AsyncIterable<T>` (for `for await`)
|
|
469
|
-
* and exposes `readable: ReadableStream<T>` (for `pipeTo`). Pick one — they
|
|
470
|
-
* share a single internal queue, so concurrent draining will race.
|
|
471
|
-
*/
|
|
472
|
-
interface StreamReader<T> extends AsyncIterable<T> {
|
|
473
|
-
readonly id: string;
|
|
474
|
-
readonly cancelled: boolean;
|
|
475
|
-
readonly done: boolean;
|
|
476
|
-
/** Highest `seq` observed. Used for replay on reconnect. */
|
|
477
|
-
readonly lastSeenSeq: number;
|
|
478
|
-
/** `ReadableStream<T>` adapter for `pipeTo`-style consumption. */
|
|
479
|
-
readonly readable: ReadableStream<T>;
|
|
480
|
-
cancel: () => void;
|
|
481
|
-
/** @internal */
|
|
482
|
-
_push: (seq: number, chunk: T) => void;
|
|
483
|
-
/** @internal */
|
|
484
|
-
_end: (error?: StreamErrorPayload) => void;
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Build a server-side stream sink. RPC-agnostic — the RPC host wires
|
|
488
|
-
* `events.on('chunk' | 'end')` to broadcast, and reads `buffer` to replay
|
|
489
|
-
* for late or reconnecting subscribers.
|
|
490
|
-
*/
|
|
491
|
-
declare function createStreamSink<T>(options?: CreateStreamSinkOptions): StreamSink<T>;
|
|
492
|
-
/**
|
|
493
|
-
* Build a client-side stream reader. RPC-agnostic — the RPC host calls
|
|
494
|
-
* `_push(seq, chunk)` on each incoming chunk and `_end(error?)` on the
|
|
495
|
-
* terminal frame. Consumers iterate with `for await` or pipe `readable`.
|
|
496
|
-
*/
|
|
497
|
-
declare function createStreamReader<T>(options?: CreateStreamReaderOptions): StreamReader<T>;
|
|
498
|
-
//#endregion
|
|
499
|
-
//#region src/types/rpc-augments.d.ts
|
|
500
|
-
/**
|
|
501
|
-
* To be extended
|
|
502
|
-
*/
|
|
503
|
-
interface DevToolsRpcClientFunctions {
|
|
504
|
-
/**
|
|
505
|
-
* Streaming chunk pushed from server to subscribed clients. Wired by
|
|
506
|
-
* `RpcStreamingHost`; do not register manually.
|
|
507
|
-
*
|
|
508
|
-
* @internal
|
|
509
|
-
*/
|
|
510
|
-
'devframe:streaming:chunk': (channel: string, id: string, seq: number, chunk: any) => Promise<void>;
|
|
511
|
-
/**
|
|
512
|
-
* Streaming terminator pushed from server to subscribed clients. Wired by
|
|
513
|
-
* `RpcStreamingHost`; do not register manually.
|
|
514
|
-
*
|
|
515
|
-
* @internal
|
|
516
|
-
*/
|
|
517
|
-
'devframe:streaming:end': (channel: string, id: string, error?: {
|
|
518
|
-
name: string;
|
|
519
|
-
message: string;
|
|
520
|
-
}) => Promise<void>;
|
|
521
|
-
/**
|
|
522
|
-
* Server→client cancel for an in-flight upload. Wired by
|
|
523
|
-
* `RpcStreamingHost`; do not register manually.
|
|
524
|
-
*
|
|
525
|
-
* @internal
|
|
526
|
-
*/
|
|
527
|
-
'devframe:streaming:upload-cancel': (channel: string, id: string) => Promise<void>;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* To be extended
|
|
531
|
-
*/
|
|
532
|
-
interface DevToolsRpcServerFunctions {
|
|
533
|
-
/**
|
|
534
|
-
* Subscribe a client to a shared-state key. Wired by
|
|
535
|
-
* `RpcSharedStateHost`; do not register manually.
|
|
536
|
-
*
|
|
537
|
-
* @internal
|
|
538
|
-
*/
|
|
539
|
-
'devframe:rpc:server-state:subscribe': (key: string) => Promise<void>;
|
|
540
|
-
/**
|
|
541
|
-
* Read the current value for a shared-state key. Wired by
|
|
542
|
-
* `RpcSharedStateHost`; do not register manually.
|
|
543
|
-
*
|
|
544
|
-
* @internal
|
|
545
|
-
*/
|
|
546
|
-
'devframe:rpc:server-state:get': (key: string) => Promise<any>;
|
|
547
|
-
/**
|
|
548
|
-
* Replace a shared-state value (from the client). Wired by
|
|
549
|
-
* `RpcSharedStateHost`; do not register manually.
|
|
550
|
-
*
|
|
551
|
-
* @internal
|
|
552
|
-
*/
|
|
553
|
-
'devframe:rpc:server-state:set': (key: string, value: any, syncId: string) => Promise<void>;
|
|
554
|
-
/**
|
|
555
|
-
* Apply a patch to a shared-state value (from the client). Wired by
|
|
556
|
-
* `RpcSharedStateHost`; do not register manually.
|
|
557
|
-
*
|
|
558
|
-
* @internal
|
|
559
|
-
*/
|
|
560
|
-
'devframe:rpc:server-state:patch': (key: string, patches: any[], syncId: string) => Promise<void>;
|
|
561
|
-
/**
|
|
562
|
-
* Client→server streaming subscription with optional replay cursor.
|
|
563
|
-
* Wired by `RpcStreamingHost`; do not register manually.
|
|
564
|
-
*
|
|
565
|
-
* @internal
|
|
566
|
-
*/
|
|
567
|
-
'devframe:streaming:subscribe': (channel: string, id: string, opts?: {
|
|
568
|
-
afterSeq?: number;
|
|
569
|
-
}) => Promise<void>;
|
|
570
|
-
/**
|
|
571
|
-
* Client→server streaming unsubscribe. Wired by `RpcStreamingHost`;
|
|
572
|
-
* do not register manually.
|
|
573
|
-
*
|
|
574
|
-
* @internal
|
|
575
|
-
*/
|
|
576
|
-
'devframe:streaming:unsubscribe': (channel: string, id: string) => Promise<void>;
|
|
577
|
-
/**
|
|
578
|
-
* Client→server streaming cancellation request. Wired by
|
|
579
|
-
* `RpcStreamingHost`; do not register manually.
|
|
580
|
-
*
|
|
581
|
-
* @internal
|
|
582
|
-
*/
|
|
583
|
-
'devframe:streaming:cancel': (channel: string, id: string) => Promise<void>;
|
|
584
|
-
/**
|
|
585
|
-
* Client→server upload chunk. Wired by `RpcStreamingHost`; do not
|
|
586
|
-
* register manually.
|
|
587
|
-
*
|
|
588
|
-
* @internal
|
|
589
|
-
*/
|
|
590
|
-
'devframe:streaming:upload-chunk': (channel: string, id: string, seq: number, chunk: any) => Promise<void>;
|
|
591
|
-
/**
|
|
592
|
-
* Client→server upload terminator. Wired by `RpcStreamingHost`; do not
|
|
593
|
-
* register manually.
|
|
594
|
-
*
|
|
595
|
-
* @internal
|
|
596
|
-
*/
|
|
597
|
-
'devframe:streaming:upload-end': (channel: string, id: string, error?: {
|
|
598
|
-
name: string;
|
|
599
|
-
message: string;
|
|
600
|
-
}) => Promise<void>;
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* To be extended
|
|
604
|
-
*/
|
|
605
|
-
interface DevToolsRpcSharedStates {}
|
|
606
|
-
//#endregion
|
|
607
|
-
//#region src/types/rpc.d.ts
|
|
608
|
-
interface RpcSharedStateGetOptions<T> {
|
|
609
|
-
sharedState?: SharedState<T>;
|
|
610
|
-
initialValue?: T;
|
|
611
|
-
}
|
|
612
|
-
interface RpcSharedStateHost {
|
|
613
|
-
get: <T extends keyof DevToolsRpcSharedStates>(key: T, options?: RpcSharedStateGetOptions<DevToolsRpcSharedStates[T]>) => Promise<SharedState<DevToolsRpcSharedStates[T]>>;
|
|
614
|
-
keys: () => string[];
|
|
615
|
-
/**
|
|
616
|
-
* Subscribe to new shared-state keys becoming available. Fires when
|
|
617
|
-
* `get(key, ...)` creates a fresh entry (not on subsequent gets).
|
|
618
|
-
* Useful for protocol adapters (e.g. MCP) that surface shared state
|
|
619
|
-
* as dynamic resources.
|
|
620
|
-
*/
|
|
621
|
-
onKeyAdded: (fn: (key: string) => void) => () => void;
|
|
622
|
-
}
|
|
623
|
-
//#endregion
|
|
624
|
-
//#region src/types/context.d.ts
|
|
625
|
-
interface ConnectionMeta {
|
|
626
|
-
backend: 'websocket' | 'static';
|
|
627
|
-
websocket?: number | string;
|
|
628
|
-
/**
|
|
629
|
-
* Names of RPC functions that have declared `jsonSerializable: true`.
|
|
630
|
-
* Used by the WS / static client to dispatch the per-call wire
|
|
631
|
-
* serializer (strict JSON for these methods, structured-clone for
|
|
632
|
-
* the rest). Populated by the server / build adapter; absent on
|
|
633
|
-
* legacy clients, in which case all outgoing messages fall back to
|
|
634
|
-
* structured-clone.
|
|
635
|
-
*/
|
|
636
|
-
jsonSerializableMethods?: string[];
|
|
637
|
-
}
|
|
638
|
-
//#endregion
|
|
639
|
-
export { createSharedState as C, RpcCacheOptions as D, RpcCacheManager as E, RpcFunctionDefinitionAny as O, SharedStatePatch as S, EventsMap as T, ImmutableObject as _, BufferedChunk as a, SharedStateEvents as b, StreamErrorPayload as c, StreamSinkEvents as d, createStreamReader as f, ImmutableMap as g, ImmutableArray as h, DevToolsRpcServerFunctions as i, RpcFunctionsCollector as k, StreamReader as l, Immutable as m, RpcSharedStateHost as n, CreateStreamReaderOptions as o, createStreamSink as p, DevToolsRpcClientFunctions as r, CreateStreamSinkOptions as s, ConnectionMeta as t, StreamSink as u, ImmutableSet as v, EventEmitter as w, SharedStateOptions as x, SharedState as y };
|