@deepseek-ai/dsh-client-connection 0.1.1-rc.2 → 0.1.2-alpha.3

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.
@@ -1,40 +1,160 @@
1
1
  /** Generic unary RPC contracts shared by the Host and Client Connection halves. */
2
- import type { RpcResult } from '@deepseek-ai/dsh-host-apiproxy/api';
3
- /** Trust fence applied before a Host RPC channel reaches its handler. */
4
- export type ConnectionRpcAuthority = 'trusted-host' | 'loopback';
5
- /** Registration policy for one logical RPC channel. */
6
- export interface ConnectionRpcHandlerOptions {
7
- /** Browser authority accepted by every endpoint in this channel. */
8
- readonly authority: ConnectionRpcAuthority;
2
+ import type { Branded } from '@deepseek-ai/dsh-brand';
3
+ /** Correlation id minted by a caller and echoed by the Connection response. */
4
+ export type RpcId = Branded<'rpc-id'>;
5
+ /**
6
+ * Brand one validated string as a Connection correlation id.
7
+ * @param id - validated wire identity.
8
+ * @returns the same string with the correlation-id brand.
9
+ */
10
+ export declare function RpcId(id: string): RpcId;
11
+ /** Carrier-neutral failure returned by one logical RPC endpoint. */
12
+ export interface ConnectionRpcFailure {
13
+ readonly code: string;
14
+ readonly message: string;
15
+ readonly details: object;
16
+ }
17
+ /** Carrier-neutral result returned by one logical RPC endpoint. */
18
+ export type ConnectionRpcResult<T> = {
19
+ readonly ok: true;
20
+ readonly value: T;
21
+ } | {
22
+ readonly ok: false;
23
+ readonly error: ConnectionRpcFailure;
24
+ };
25
+ /** Historical short name for a generic Connection result. */
26
+ export type RpcResult<T> = ConnectionRpcResult<T>;
27
+ /**
28
+ * Convert a rejected transport operation into a generic failure result.
29
+ * @param error - rejected transport value.
30
+ * @returns an `internal` failure preserving the available message.
31
+ */
32
+ export declare function transportError<T>(error: unknown): RpcResult<T>;
33
+ /** Narrow request form used by direct fixture adapters. */
34
+ export interface RpcRequest<P> {
35
+ readonly rpcId: RpcId;
36
+ readonly payload: P;
37
+ }
38
+ /** Narrow response form used by direct fixture adapters. */
39
+ export interface RpcResponse<T> {
40
+ readonly rpcId: RpcId;
41
+ readonly result: RpcResult<T>;
42
+ }
43
+ /** Full request envelope carried by Connection RPC transports. */
44
+ export interface ClientRequest {
45
+ readonly type: 'client-request';
46
+ readonly rpcId: RpcId;
47
+ readonly method: string;
48
+ readonly payload: unknown;
49
+ }
50
+ /** Full response envelope carried by Connection RPC transports. */
51
+ export interface ServerResponse {
52
+ readonly type: 'server-response';
53
+ readonly rpcId: RpcId;
54
+ readonly result: ConnectionRpcResult<unknown>;
55
+ }
56
+ /** Complete Connection RPC envelope union. */
57
+ export type RpcMessage = ClientRequest | ServerResponse;
58
+ /** HTTP request facts consumed by browser trust and authentication. */
59
+ export interface ConnectionTrustRequest {
60
+ /** Request headers supplied by either the Fetch or node:http representation. */
61
+ readonly headers: Headers | Readonly<Record<string, string | readonly string[] | undefined>>;
62
+ }
63
+ /** HTTP status returned before dispatch, or undefined when the request may proceed. */
64
+ export type ConnectionRequestRejection = 401 | 403 | undefined;
65
+ /** Root/index request facts used by the browser-token exchange. */
66
+ export interface ConnectionIndexRequest extends ConnectionTrustRequest {
67
+ readonly method?: string | undefined;
68
+ readonly url?: string | undefined;
69
+ }
70
+ /** Root/index response operations owned by the browser-token exchange. */
71
+ export interface ConnectionIndexResponse {
72
+ writeHead(status: number, headers?: Readonly<Record<string, string>>): unknown;
73
+ end(body?: string): unknown;
9
74
  }
10
75
  /** Handler invoked after Connection has decoded the transport envelope. */
11
- export type ConnectionRpcHandler = (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<RpcResult<unknown>>;
76
+ export type ConnectionRpcHandler = (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<ConnectionRpcResult<unknown>>;
12
77
  /** Synchronous ownership test for one endpoint on a shared RPC channel. */
13
78
  export type ConnectionRpcEndpointMatcher = (endpoint: string) => boolean;
79
+ /** HTTP methods supported by exact Fetch routes on the shared API channel. */
80
+ export type ConnectionFetchMethod = 'GET' | 'HEAD';
81
+ /** One exact, transport-independent Fetch route owned by a Host feature. */
82
+ export interface ConnectionFetchRoute {
83
+ /** Absolute path below `/api`; query parameters remain available on the request URL. */
84
+ readonly path: string;
85
+ /** Methods this route owns. Other methods continue through normal shared-channel dispatch. */
86
+ readonly methods: readonly ConnectionFetchMethod[];
87
+ /** Handle one request after the physical carrier has applied its trust and authentication policy. */
88
+ readonly fetch: (request: Request) => Promise<Response>;
89
+ }
90
+ /** Host registry for exact Fetch routes that cannot use JSON Remote invocation. */
91
+ export interface HostConnectionFetch {
92
+ /**
93
+ * Register one exact route on the shared API channel.
94
+ * @param route - path, methods, and Fetch-shaped implementation.
95
+ * @returns asynchronous disposer removing this exact contribution.
96
+ */
97
+ register(route: ConnectionFetchRoute): () => Promise<void>;
98
+ }
14
99
  /** Host registry for logical RPC channels carried by the current transport. */
15
100
  export interface HostConnectionRpc {
16
101
  /**
17
- * Register one absolute channel prefix and its trust policy.
102
+ * Register one authenticated absolute channel prefix.
18
103
  * @param channel - absolute logical channel such as `/rpc`.
19
104
  * @param handler - decoded endpoint handler returning the existing RPC result shape.
20
- * @param options - channel trust policy.
21
105
  * @returns asynchronous disposer removing the channel and its physical route.
22
106
  */
23
- handle(channel: string, handler: ConnectionRpcHandler, options: ConnectionRpcHandlerOptions): () => Promise<void>;
107
+ handle(channel: string, handler: ConnectionRpcHandler): () => Promise<void>;
24
108
  /**
25
109
  * Intercept owned endpoints on the shared `/api` channel before its fallback.
26
110
  * @param channel - reserved shared channel; currently `/api`.
27
111
  * @param matches - synchronous endpoint ownership test.
28
112
  * @param handler - decoded endpoint handler returning the existing RPC result shape.
29
- * @param options - trust policy for every endpoint claimed by this interceptor.
30
113
  * @returns asynchronous disposer removing the interceptor.
31
114
  */
32
- intercept(channel: '/api', matches: ConnectionRpcEndpointMatcher, handler: ConnectionRpcHandler, options: ConnectionRpcHandlerOptions): () => Promise<void>;
115
+ intercept(channel: '/api', matches: ConnectionRpcEndpointMatcher, handler: ConnectionRpcHandler): () => Promise<void>;
33
116
  }
34
117
  /** Host `ctx.connection` shape consumed by transport-independent adapters. */
35
118
  export interface HostConnectionHandle {
36
119
  /** Generic RPC channel registry. */
37
120
  readonly rpc: HostConnectionRpc;
121
+ /** Exact Fetch routes for streaming or browser-native responses. */
122
+ readonly fetch: HostConnectionFetch;
123
+ /**
124
+ * Compose exact Fetch routes and the shared-channel RPC interceptor.
125
+ * @param channel - shared channel mounted by Connection.
126
+ * @returns Fetch handler for trusted, authenticated requests.
127
+ */
128
+ createSharedFetchHandler(channel: '/api'): ConnectionFetchHandler;
129
+ /**
130
+ * Apply Connection's Host/Origin checks and browser authentication to
131
+ * another Web route.
132
+ * @param request - request headers from the HTTP or upgrade request.
133
+ * @returns rejection status, or undefined when the route may accept the request.
134
+ */
135
+ requestRejection(request: ConnectionTrustRequest): ConnectionRequestRejection;
136
+ /**
137
+ * Authenticate one frontend index request, owning a token redirect or 401.
138
+ * @param request - root or configured-index HTTP request.
139
+ * @param response - response owned when the result is false.
140
+ * @returns true only when the frontend may serve index.html.
141
+ */
142
+ authorizeIndex(request: ConnectionIndexRequest, response: ConnectionIndexResponse): boolean;
143
+ /**
144
+ * Add the fresh process token to an ordinary Web application URL.
145
+ * @param baseUrl - clean canonical browser origin.
146
+ * @returns root URL accepted by {@link authorizeIndex} for initial login.
147
+ */
148
+ authenticatedUrl(baseUrl: string): string;
149
+ }
150
+ /** Transport-independent Fetch handler used by HTTP and worker carriers. */
151
+ export interface ConnectionFetchHandler {
152
+ /**
153
+ * Dispatch one already-authenticated request.
154
+ * @param request - Fetch request below the shared channel.
155
+ * @returns the registered response or a 404 response.
156
+ */
157
+ fetch(request: Request): Promise<Response>;
38
158
  }
39
159
  /** Client caller for logical RPC channels carried by the current transport. */
40
160
  export interface ClientConnectionRpc {
@@ -44,8 +164,18 @@ export interface ClientConnectionRpc {
44
164
  * @param endpoint - channel-relative endpoint such as `goals/create`.
45
165
  * @param payload - channel-owned request payload.
46
166
  * @param signal - optional caller cancellation.
47
- * @returns the existing RPC success/error result; correlation stays inside Connection.
167
+ * @returns the endpoint-owned success/error result; correlation stays inside Connection.
168
+ */
169
+ call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<ConnectionRpcResult<unknown>>;
170
+ /**
171
+ * Open an in-process logical stream when the selected carrier supplies one.
172
+ * Browser transports omit this method; API Gateway owns their WebSocket mux.
173
+ * @param channel - absolute logical channel such as `/api`.
174
+ * @param endpoint - channel-relative endpoint such as `session/follow`.
175
+ * @param payload - channel-owned request payload.
176
+ * @param signal - caller cancellation for this logical stream.
177
+ * @returns decoded stream values from the in-process carrier.
48
178
  */
49
- call(channel: string, endpoint: string, payload: unknown, signal?: AbortSignal): Promise<RpcResult<unknown>>;
179
+ readonly open?: (channel: string, endpoint: string, payload: unknown, signal: AbortSignal) => AsyncIterable<unknown>;
50
180
  }
51
181
  //# sourceMappingURL=rpc.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-connection",
3
- "description": "Wire consumer layer: HTTP-up/WebSocket-down client, ConnectionController dual streams with reconnect, and fixture api",
4
- "version": "0.1.1-rc.2",
3
+ "description": "Authenticated RPC transport, generation lifecycle, and browser fixture",
4
+ "version": "0.1.2-alpha.3",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -38,8 +38,9 @@
38
38
  },
39
39
  "license": "MIT",
40
40
  "dependencies": {
41
- "ws": "^8.21.0",
42
- "@deepseek-ai/schemastery": "^3.18.1"
41
+ "zod": "^4.4.3",
42
+ "@deepseek-ai/dsh-credentials": "^0.1.2-alpha.3",
43
+ "@deepseek-ai/schemastery": "^3.18.2"
43
44
  },
44
45
  "files": [
45
46
  "lib/index.js",
@@ -48,26 +49,20 @@
48
49
  "lib/types/**/*.d.ts"
49
50
  ],
50
51
  "peerDependencies": {
51
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
52
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
53
- "@deepseek-ai/cordis": "^4.0.1",
54
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.2",
55
- "@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
56
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
57
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
58
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
59
- "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2"
52
+ "@deepseek-ai/cordis": "^4.0.2"
60
53
  },
61
54
  "devDependencies": {
62
- "@types/ws": "^8.18.1",
63
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.2",
64
- "@deepseek-ai/cordis": "^4.0.1",
65
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
66
- "@deepseek-ai/dsh-attachment": "^0.1.1-rc.2",
67
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
68
- "@deepseek-ai/dsh-commands": "^0.1.1-rc.2",
69
- "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
70
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
71
- "@deepseek-ai/dsh-host-apiproxy": "^0.1.1-rc.2"
55
+ "@deepseek-ai/cordis": "^4.0.2",
56
+ "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.3",
57
+ "@deepseek-ai/dsh-brand": "^0.1.2-alpha.3",
58
+ "@deepseek-ai/dsh-commands": "^0.1.2-alpha.3",
59
+ "@deepseek-ai/dsh-host-directory-picker": "^0.1.2-alpha.3",
60
+ "@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.3",
61
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.3",
62
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.3",
63
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.3",
64
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.3",
65
+ "@deepseek-ai/dsh-tool-todo": "^0.1.2-alpha.3",
66
+ "@deepseek-ai/dsh-util-values": "^0.1.2-alpha.3"
72
67
  }
73
68
  }
@@ -1,11 +0,0 @@
1
- /** Browser API carrier: HTTP upstream plus one WebSocket per downstream event stream. */
2
- import type { ApiProxy, HostFrame, MuxFrame, RpcRequest } from './api.ts';
3
- import { AbstractApiClient } from './api.ts';
4
- /** Browser platform subclass: unary/respond use fetch; mux/host use downlink-only WebSockets. */
5
- export declare class WebApiClient extends AbstractApiClient {
6
- protected doFetch(input: URL, init?: RequestInit): Promise<Response>;
7
- protected openMux(_payload: Parameters<ApiProxy['events']['mux']>[0]['payload'], signal: AbortSignal, onOpen?: () => void): AsyncIterable<RpcRequest<MuxFrame>>;
8
- protected openHost(_payload: Parameters<ApiProxy['events']['host']>[0]['payload'], signal: AbortSignal, onOpen?: () => void): AsyncIterable<RpcRequest<HostFrame>>;
9
- private readWebSocket;
10
- }
11
- //# sourceMappingURL=web-api-client.d.ts.map
@@ -1,43 +0,0 @@
1
- /** Host-side WebSocket carrier for the two server-to-browser event streams. */
2
- import type { IncomingMessage } from 'node:http';
3
- import type { Duplex } from 'node:stream';
4
- import type { ApiProxy } from '@deepseek-ai/dsh-host-apiproxy/api';
5
- /**
6
- * Owns WebSocket negotiation and frame pumping for the connection plugin's
7
- * two downlinks. Client messages are a protocol violation: upstream traffic
8
- * remains on HTTP.
9
- */
10
- export declare class WebSocketDownlinks {
11
- private readonly api;
12
- private readonly server;
13
- private readonly pumps;
14
- /** @param api - host API supplying the typed event streams. */
15
- constructor(api: ApiProxy);
16
- /**
17
- * Upgrade one socket and pump the mux stream until either side closes.
18
- * @param req - HTTP upgrade request.
19
- * @param socket - Raw socket transferred by the HTTP server.
20
- * @param head - Bytes already read after the upgrade headers.
21
- */
22
- handleMux(req: IncomingMessage, socket: Duplex, head: Buffer): void;
23
- /**
24
- * Upgrade one socket and pump the host stream until either side closes.
25
- * @param req - HTTP upgrade request.
26
- * @param socket - Raw socket transferred by the HTTP server.
27
- * @param head - Bytes already read after the upgrade headers.
28
- */
29
- handleHost(req: IncomingMessage, socket: Duplex, head: Buffer): void;
30
- /**
31
- * Terminate owned sockets and await the no-server acceptor plus frame pumps.
32
- * @returns A promise resolving after every socket and source iterator stops.
33
- */
34
- close(): Promise<void>;
35
- private upgrade;
36
- private pump;
37
- }
38
- /**
39
- * Reject an untrusted upgrade before protocol negotiation.
40
- * @param socket - Raw HTTP socket that remains owned by the caller.
41
- */
42
- export declare function rejectWebSocketUpgrade(socket: Duplex): void;
43
- //# sourceMappingURL=websocket-downlink.d.ts.map