@deepseek-ai/dsh-client-connection 0.2.1-alpha.2 → 0.2.1-alpha.4

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,8 +1,9 @@
1
1
  /** Host registry and HTTP adapter for generic Connection RPC channels. */
2
2
  import { Context, Service } from '@deepseek-ai/cordis';
3
- import type { PeerScope } from '@deepseek-ai/dsh-typert-protocol';
3
+ import type { PeerScope, Principal } from '@deepseek-ai/dsh-typert-protocol';
4
+ import type { ConnectionInteractions } from './connect-protocol.ts';
4
5
  import type { BrowserAuth } from './browser-auth.ts';
5
- import type { PeerAdmission, ConnectionIndexRequest, ConnectionIndexResponse, ConnectionFetchHandler, HostConnectionFetch, ConnectionRequestRejection, ConnectionTrustRequest, HostConnectionHandle, HostConnectionRpc } from './rpc.ts';
6
+ import type { PeerAdmission, ConnectionAdmission, ConnectionIndexRequest, ConnectionIndexResponse, ConnectionFetchHandler, HostConnectionFetch, ConnectionRequestRejection, ConnectionTrustRequest, HostConnectionHandle, HostConnectionRpc } from './rpc.ts';
6
7
  declare module '@deepseek-ai/cordis' {
7
8
  interface Context {
8
9
  /** Host Connection transport and RPC registrations. */
@@ -13,8 +14,11 @@ declare module '@deepseek-ai/cordis' {
13
14
  export declare class HostConnectionService extends Service implements HostConnectionHandle {
14
15
  private readonly trustedHosts;
15
16
  private readonly browserAuth;
16
- /** The operator Peer every admitted request speaks for. */
17
- readonly operator: PeerScope;
17
+ /** The Peer every authenticated browser connection shares. */
18
+ readonly browserPeer: PeerScope;
19
+ private readonly peers;
20
+ private readonly owner;
21
+ private disposed;
18
22
  private readonly interceptors;
19
23
  private readonly fetchRoutes;
20
24
  readonly allowsRemoteAuthorities: boolean;
@@ -29,10 +33,25 @@ export declare class HostConnectionService extends Service implements HostConnec
29
33
  get rpc(): HostConnectionRpc;
30
34
  /** Exact Fetch-route registry scoped to the Context reading this service. */
31
35
  get fetch(): HostConnectionFetch;
32
- /** Apply the Host/Origin fence, then browser authentication. */
36
+ /** Apply the Host/Origin fence and require an authenticated live Peer. */
33
37
  requestRejection(request: ConnectionTrustRequest): ConnectionRequestRejection;
34
- /** A request that passes the fence and authentication speaks for the operator. */
38
+ /** Browser requests share an owner Peer; API HTTP does not depend on an attached socket. */
35
39
  admit(request: ConnectionTrustRequest): PeerAdmission;
40
+ /** Create one in-process Peer owned by the Context that read this service. */
41
+ createPeer(options: {
42
+ readonly principal: Principal;
43
+ readonly interactions?: ConnectionInteractions;
44
+ }): PeerScope;
45
+ /** Claim API socket ownership synchronously; callers release on termination or failed upgrade. */
46
+ admitConnection(request: ConnectionTrustRequest): ConnectionAdmission;
47
+ private isTrusted;
48
+ private publishPeer;
49
+ /**
50
+ * Authenticate and publish a credential before sending the connect redirect.
51
+ * @param request - launch-token request on /connect.
52
+ * @param response - response owned to completion.
53
+ */
54
+ authorizeConnect(request: ConnectionIndexRequest, response: ConnectionIndexResponse): void;
36
55
  /**
37
56
  * Authenticate an index request; native TLS listeners mint Secure cookies.
38
57
  */
@@ -1,6 +1,6 @@
1
1
  /** Generic unary RPC contracts shared by the Host and Client Connection halves. */
2
2
  import type { Branded } from '@deepseek-ai/dsh-brand';
3
- import type { PeerScope } from '@deepseek-ai/dsh-typert-protocol';
3
+ import type { PeerScope, Principal } from '@deepseek-ai/dsh-typert-protocol';
4
4
  /** Correlation id minted by a caller and echoed by the Connection response. */
5
5
  export type RpcId = Branded<'rpc-id'>;
6
6
  /**
@@ -90,15 +90,23 @@ export interface ConnectionIndexResponse {
90
90
  writeHead(status: number, headers?: Readonly<Record<string, string>>): unknown;
91
91
  end(body?: string): unknown;
92
92
  }
93
- /** Outcome of admitting one request: the operator Peer it speaks for, or the status refusing it. */
93
+ /** Outcome of admitting one request: the Peer it speaks for, or the status refusing it. */
94
94
  export type PeerAdmission = {
95
95
  readonly peer: PeerScope;
96
96
  } | {
97
97
  readonly rejection: 401 | 403;
98
98
  };
99
+ /** Socket admission claims API ownership until its carrier calls release, including failed upgrades. */
100
+ export type ConnectionAdmission = {
101
+ readonly peer: PeerScope;
102
+ /** Remove and dispose an API Peer; browser releases leave the shared browser Peer intact. */
103
+ readonly release: () => Promise<void>;
104
+ } | {
105
+ readonly rejection: 401 | 403 | 409;
106
+ };
99
107
  /**
100
108
  * Handler invoked after Connection has decoded the transport envelope.
101
- * `peer` is the Peer the request was admitted as: the operator.
109
+ * `peer` is the Peer the carrier admitted or the in-process caller supplied.
102
110
  */
103
111
  export type ConnectionRpcHandler = (endpoint: string, payload: unknown, signal: AbortSignal, peer: PeerScope) => Promise<ConnectionRpcHandlerResult>;
104
112
  /** Synchronous ownership test for one endpoint on a shared RPC channel. */
@@ -115,7 +123,11 @@ export interface ConnectionFetchRoute {
115
123
  readonly methods: readonly ConnectionFetchMethod[];
116
124
  /** Buffered requests obey the configured JSON cap; streaming requests arrive with backpressure and no aggregate cap. */
117
125
  readonly requestBody: ConnectionRequestBodyMode;
118
- /** Handle one request after the physical carrier has applied its trust and authentication policy. */
126
+ /**
127
+ * Handle one request after the physical carrier has applied its trust and
128
+ * authentication policy. Only owner Peers reach an exact route; the shared
129
+ * handler answers 403 for every other principal.
130
+ */
119
131
  readonly fetch: (request: Request) => Promise<Response>;
120
132
  }
121
133
  /** Host registry for exact Fetch routes that cannot use JSON Remote invocation. */
@@ -151,8 +163,8 @@ export interface HostConnectionHandle {
151
163
  readonly rpc: HostConnectionRpc;
152
164
  /** Exact Fetch routes for streaming or browser-native responses. */
153
165
  readonly fetch: HostConnectionFetch;
154
- /** The operator Peer every admitted request speaks for; its scope lives as long as Connection. */
155
- readonly operator: PeerScope;
166
+ /** The owner Peer every authenticated browser connection shares. */
167
+ readonly browserPeer: PeerScope;
156
168
  /**
157
169
  * Whether this deployment accepts authorities beyond loopback: true only
158
170
  * when a validated `trustedHosts` entry names a non-loopback hostname.
@@ -172,12 +184,28 @@ export interface HostConnectionHandle {
172
184
  */
173
185
  requestRejection(request: ConnectionTrustRequest): ConnectionRequestRejection;
174
186
  /**
175
- * Admit one request: it passes {@link requestRejection} and speaks for the
176
- * operator, or it is refused with that status.
187
+ * Admit an HTTP request against its signed browser or API credential and live Peer.
177
188
  * @param request - request headers from the HTTP or upgrade request.
178
- * @returns the operator Peer, or the rejection status.
189
+ * @returns the credential's Peer, or the rejection status.
179
190
  */
180
191
  admit(request: ConnectionTrustRequest): PeerAdmission;
192
+ /**
193
+ * Create an independent in-process Peer, disposed with the Context that read `ctx.connection`.
194
+ * @param options - fixed principal and optional interaction participation (default `answer`).
195
+ * @returns a new Peer distinct from every other Peer.
196
+ */
197
+ createPeer(options: {
198
+ readonly principal: Principal;
199
+ readonly interactions?: 'answer' | 'none';
200
+ }): PeerScope;
201
+ /**
202
+ * Claim a physical socket for an API Peer; browser sockets share their owner Peer.
203
+ * @param request - authenticated upgrade request headers.
204
+ * @returns the Peer and idempotent release, or 409 for duplicate API ownership.
205
+ * The carrier releases on socket termination or failed upgrade; release removes
206
+ * API admission synchronously without cancelling independent HTTP calls.
207
+ */
208
+ admitConnection(request: ConnectionTrustRequest): ConnectionAdmission;
181
209
  /**
182
210
  * Authenticate one frontend index request, owning a token redirect or 401.
183
211
  * The cookie this mints is `Secure` when the mounted Web carrier serves TLS,
@@ -208,9 +236,10 @@ export interface ConnectionFetchHandler {
208
236
  /**
209
237
  * Dispatch one already-authenticated request.
210
238
  * @param request - Fetch request below the shared channel.
211
- * @returns the registered response or a 404 response.
239
+ * @param peer - Peer to dispatch as; required, never defaulted.
240
+ * @returns the registered response, a 403 response for an exact route and a non-owner Peer, or a 404 response.
212
241
  */
213
- fetch(request: Request): Promise<Response>;
242
+ fetch(request: Request, peer: PeerScope): Promise<Response>;
214
243
  }
215
244
  /** Client caller for logical RPC channels carried by the current transport. */
216
245
  export interface ClientConnectionRpc {
package/locale/en.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "connection"
4
+ }
5
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "客户端连接",
4
+ "description": "建立已认证的客户端通信,并管理连接生命周期。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-connection",
3
3
  "description": "Authenticated RPC transport and generation lifecycle",
4
- "version": "0.2.1-alpha.2",
4
+ "version": "0.2.1-alpha.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -20,10 +20,13 @@
20
20
  },
21
21
  "./client": {
22
22
  "types": "./lib/types/client/index.d.ts",
23
- "default": "./lib/client.js"
23
+ "node": "./lib/client.node.js",
24
+ "browser": "./lib/client.browser.js",
25
+ "default": "./lib/client.browser.js"
24
26
  },
25
27
  "./src/*": "./src/*",
26
- "./package.json": "./package.json"
28
+ "./package.json": "./package.json",
29
+ "./locale/*.json": "./locale/*.json"
27
30
  },
28
31
  "dsh": {
29
32
  "client": {
@@ -34,27 +37,29 @@
34
37
  },
35
38
  "license": "MIT",
36
39
  "dependencies": {
37
- "@deepseek-ai/dsh-credentials": "0.2.1-alpha.2",
38
- "@deepseek-ai/schemastery": "~3.18.5-alpha.1",
39
- "zod": "^4.4.3"
40
+ "@deepseek-ai/dsh-credentials": "0.2.1-alpha.4",
41
+ "@deepseek-ai/schemastery": "~3.18.5-alpha.2",
42
+ "zod": "4.4.3"
40
43
  },
41
44
  "files": [
45
+ "locale/*.json",
42
46
  "lib/index.js",
43
- "lib/client.js",
47
+ "lib/client.browser.js",
48
+ "lib/client.node.js",
44
49
  "lib/types/**/*.d.ts"
45
50
  ],
46
51
  "peerDependencies": {
47
- "@deepseek-ai/cordis": "~4.0.5-alpha.1",
48
- "@deepseek-ai/dsh-scope": "0.2.1-alpha.2"
52
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2",
53
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.4"
49
54
  },
50
55
  "devDependencies": {
51
- "@deepseek-ai/cordis": "~4.0.5-alpha.1",
52
- "@deepseek-ai/dsh-attachment": "0.2.1-alpha.2",
53
- "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
54
- "@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.2",
55
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
56
- "@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
57
- "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
58
- "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2"
56
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2",
57
+ "@deepseek-ai/dsh-attachment": "0.2.1-alpha.4",
58
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.4",
59
+ "@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.4",
60
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.4",
61
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.4",
62
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.4",
63
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4"
59
64
  }
60
65
  }
@@ -1,23 +0,0 @@
1
- /**
2
- * The operator Peer: the one party this Host answers to. Connection owns it
3
- * for its own lifetime, admits every request as it, and hands it to each
4
- * Remote call as `invocation.peer`.
5
- * @module @deepseek-ai/dsh-client-connection/src/operator-peer
6
- */
7
- import type { Context } from '@deepseek-ai/cordis';
8
- import type { PeerId, PeerScope } from '@deepseek-ai/dsh-typert-protocol';
9
- /**
10
- * The operator's scope. The instance is its own scope key, so `scopeOf(peer.ctx)`
11
- * returns it and events dispatched with `scopeTarget(subject, peer)` reach
12
- * listeners registered through `peer.ctx` and nobody else.
13
- */
14
- export declare class OperatorPeer implements PeerScope {
15
- readonly id: PeerId;
16
- readonly ctx: Context;
17
- private readonly scope;
18
- /** @param owner - Connection plugin context the scope fiber hangs under. */
19
- constructor(owner: Context);
20
- /** Tear down every connection-lifetime registration; racing calls share one completion. */
21
- dispose(): Promise<void>;
22
- }
23
- //# sourceMappingURL=operator-peer.d.ts.map