@deepseek-ai/dsh-client-connection 0.2.1-alpha.1 → 0.2.1-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.
- package/README.i18n.yaml +8 -8
- package/README.md +14 -7
- package/README.zh.md +14 -7
- package/lib/{client.js → client.browser.js} +22 -2
- package/lib/client.node.js +624 -0
- package/lib/index.js +296 -74
- package/lib/types/api-request-trust.d.ts +16 -9
- package/lib/types/browser-auth.d.ts +25 -2
- package/lib/types/client/index.d.ts +19 -3
- package/lib/types/client/socket.d.ts +50 -0
- package/lib/types/connect-protocol.d.ts +6 -0
- package/lib/types/http-bridge.d.ts +3 -1
- package/lib/types/index.d.ts +9 -9
- package/lib/types/peer.d.ts +36 -0
- package/lib/types/rpc-host.d.ts +29 -7
- package/lib/types/rpc.d.ts +47 -11
- package/locale/en.json +5 -0
- package/locale/zh.json +6 -0
- package/package.json +22 -17
- package/lib/types/operator-peer.d.ts +0 -23
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** Browser-session authentication for the Host Connection carrier. */
|
|
2
|
+
import type { PeerId } from '@deepseek-ai/dsh-typert-protocol';
|
|
3
|
+
import { type ConnectionInteractions } from './connect-protocol.ts';
|
|
2
4
|
import type { CredentialProvider } from '@deepseek-ai/dsh-credentials';
|
|
3
5
|
import type { ConnectionIndexRequest, ConnectionIndexResponse, ConnectionTrustRequest } from './rpc.ts';
|
|
4
6
|
/**
|
|
@@ -33,15 +35,36 @@ export declare class BrowserAuth {
|
|
|
33
35
|
* 401 response.
|
|
34
36
|
* @param req - incoming root or configured-index request.
|
|
35
37
|
* @param res - response owned when this method returns false.
|
|
38
|
+
* @param secure - whether the listener receiving this request serves TLS; the
|
|
39
|
+
* minted cookie carries `Secure` when it does. Only that listener's own
|
|
40
|
+
* protocol decides, never a `publicUrl` announcement or a forwarded header:
|
|
41
|
+
* those describe a hop this process does not terminate.
|
|
36
42
|
* @returns true only when the caller may serve index.html.
|
|
37
43
|
*/
|
|
38
|
-
authorizeIndex(req: ConnectionIndexRequest, res: ConnectionIndexResponse): boolean;
|
|
44
|
+
authorizeIndex(req: ConnectionIndexRequest, res: ConnectionIndexResponse, secure?: boolean): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Exchange the launch token for an independent API operator; omitted interactions default to none.
|
|
47
|
+
* @param req - trusted GET request on /connect with at most one interactions declaration.
|
|
48
|
+
* @param res - response owned to completion, redirecting to the API mux on success.
|
|
49
|
+
* @param secure - whether the receiving listener serves TLS.
|
|
50
|
+
* @param publish - synchronously create the operator before exposing its signed credential.
|
|
51
|
+
*/
|
|
52
|
+
authorizeConnect(req: ConnectionIndexRequest, res: ConnectionIndexResponse, secure: boolean, publish: (interactions: ConnectionInteractions) => PeerId): void;
|
|
39
53
|
/**
|
|
40
54
|
* Verify the authority-bound browser cookie on a Host request.
|
|
41
55
|
* @param request - request headers carrying Host and Cookie.
|
|
56
|
+
* @param secure - whether the receiving listener uses TLS, including its default port.
|
|
42
57
|
* @returns true only for an unexpired cookie signed by this activation's loaded secret.
|
|
43
58
|
*/
|
|
44
|
-
isAuthenticated(request: ConnectionTrustRequest): boolean;
|
|
59
|
+
isAuthenticated(request: ConnectionTrustRequest, secure?: boolean): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Verify an API credential without creating or reviving its operator.
|
|
62
|
+
* @param request - request headers carrying Host and Cookie.
|
|
63
|
+
* @param secure - whether the receiving listener uses TLS.
|
|
64
|
+
* @returns the signed operator id, or undefined for invalid, expired, or browser cookies.
|
|
65
|
+
*/
|
|
66
|
+
authenticateApi(request: ConnectionTrustRequest, secure?: boolean): PeerId | undefined;
|
|
67
|
+
private authenticate;
|
|
45
68
|
private writeUnauthorized;
|
|
46
69
|
}
|
|
47
70
|
//# sourceMappingURL=browser-auth.d.ts.map
|
|
@@ -3,6 +3,10 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
3
3
|
import { type ConnectionRecoveryConfig, type ConnectionGeneration, type ConnectionGenerationSource, type ConnectionSinks, type ConnectionState } from './connection.ts';
|
|
4
4
|
import { type RpcFetch, type RpcStreamOpen } from './rpc.ts';
|
|
5
5
|
import type { ClientConnectionRpc } from '../rpc.ts';
|
|
6
|
+
import type { ConnectionInteractions } from '../connect-protocol.ts';
|
|
7
|
+
import { type ConnectionWebSocket, type ConnectionWebSocketFactory } from './socket.ts';
|
|
8
|
+
export type { ConnectionInteractions } from '../connect-protocol.ts';
|
|
9
|
+
export type { ConnectionWebSocket, ConnectionWebSocketFactory } from './socket.ts';
|
|
6
10
|
declare module '@deepseek-ai/cordis' {
|
|
7
11
|
interface Events {
|
|
8
12
|
/**
|
|
@@ -60,13 +64,15 @@ export interface ClientTransportHooks {
|
|
|
60
64
|
/**
|
|
61
65
|
* The transport owner declares the page owns the Host outright: the Host
|
|
62
66
|
* runs inside a worker this page spawned, so no other party can reach it and
|
|
63
|
-
* the loopback stand-in for "the
|
|
67
|
+
* the loopback stand-in for "the owner's own machine" is vacuous.
|
|
64
68
|
* `ctx.connection.isLoopback` then reports the privileged surface reachable
|
|
65
69
|
* regardless of the page authority. Only a shell that assembles its own
|
|
66
70
|
* transport can set this; served pages never carry the global at all.
|
|
67
71
|
*/
|
|
68
72
|
ownsHost?: boolean;
|
|
69
|
-
/**
|
|
73
|
+
/** Authenticated WebSocket factory; omission uses the browser API and its cookie jar. */
|
|
74
|
+
createWebSocket?: ConnectionWebSocketFactory;
|
|
75
|
+
/** Host base URL for desktop or Node sockets; omission uses the document base. */
|
|
70
76
|
streamBaseUrl?: string;
|
|
71
77
|
}
|
|
72
78
|
/** Browser location fields used to classify loopback authority. */
|
|
@@ -75,6 +81,8 @@ export interface ConnectionLocation {
|
|
|
75
81
|
}
|
|
76
82
|
/** Instance-local inputs for installing a Connection service. */
|
|
77
83
|
export interface ConnectionInstallOptions {
|
|
84
|
+
/** Forwarded-event participation; omission selects answer for a page and none otherwise. */
|
|
85
|
+
readonly interactions?: ConnectionInteractions;
|
|
78
86
|
/** Explicit physical carrier; omit for the browser HTTP + WebSocket carrier. */
|
|
79
87
|
readonly transport?: ClientTransportHooks;
|
|
80
88
|
/** Reconnect timing overrides; omitted fields use controller defaults. */
|
|
@@ -87,6 +95,8 @@ export interface ConnectionInstallOptions {
|
|
|
87
95
|
* and reset callbacks; Connection stays independent of downstream domain state.
|
|
88
96
|
*/
|
|
89
97
|
export interface ConnectionHandle {
|
|
98
|
+
/** Forwarded-event participation selected at installation. */
|
|
99
|
+
readonly interactions: ConnectionInteractions;
|
|
90
100
|
/**
|
|
91
101
|
* Whether the privileged surface is reachable: the page authority is
|
|
92
102
|
* loopback, the transport declares the page owns the Host
|
|
@@ -99,6 +109,12 @@ export interface ConnectionHandle {
|
|
|
99
109
|
readonly state: ConnectionStateSource;
|
|
100
110
|
/** Generic logical RPC channels over the same Connection transport. */
|
|
101
111
|
readonly rpc: ClientConnectionRpc;
|
|
112
|
+
/**
|
|
113
|
+
* Create a socket on the selected carrier; the channel owns framing and closing.
|
|
114
|
+
* @param path - absolute logical channel path, resolved beneath the Host mount.
|
|
115
|
+
* @returns a newly connecting socket using the installed authentication factory.
|
|
116
|
+
*/
|
|
117
|
+
openWebSocket(path: string): ConnectionWebSocket;
|
|
102
118
|
/** Reset retry progression and replace the current attempt immediately. */
|
|
103
119
|
reconnect(): void;
|
|
104
120
|
/**
|
|
@@ -125,7 +141,7 @@ export interface ConnectionLoop {
|
|
|
125
141
|
/**
|
|
126
142
|
* Install one Context-owned Connection service from explicit composition inputs.
|
|
127
143
|
* @param ctx - client Cordis context.
|
|
128
|
-
* @param options - physical carrier, reconnect timing, and page location.
|
|
144
|
+
* @param options - interaction participation, physical carrier, reconnect timing, and page location.
|
|
129
145
|
*/
|
|
130
146
|
export declare function installConnection(ctx: Context, options?: ConnectionInstallOptions): void;
|
|
131
147
|
/**
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Physical socket selection for browser, desktop, and authenticated Node connections. */
|
|
2
|
+
/** Socket events consumed by the Gateway on browser and Node carriers. */
|
|
3
|
+
export interface ConnectionWebSocketEventMap {
|
|
4
|
+
readonly open: object;
|
|
5
|
+
readonly error: object;
|
|
6
|
+
readonly close: object;
|
|
7
|
+
readonly message: {
|
|
8
|
+
readonly data: unknown;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Text WebSocket operations shared by the browser API and Node carriers. */
|
|
12
|
+
export interface ConnectionWebSocket {
|
|
13
|
+
/** Standard WebSocket state, from CONNECTING (0) through CLOSED (3). */
|
|
14
|
+
readonly readyState: number;
|
|
15
|
+
/** @param data - complete text frame to send. */
|
|
16
|
+
send(data: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* @param code - protocol close code.
|
|
19
|
+
* @param reason - peer-facing close explanation.
|
|
20
|
+
*/
|
|
21
|
+
close(code?: number, reason?: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* @param event - physical socket event.
|
|
24
|
+
* @param listener - callback for that event.
|
|
25
|
+
* @param options - whether the callback is removed after its first delivery.
|
|
26
|
+
*/
|
|
27
|
+
addEventListener<Event extends keyof ConnectionWebSocketEventMap>(event: Event, listener: (event: ConnectionWebSocketEventMap[Event]) => void, options?: {
|
|
28
|
+
readonly once?: boolean;
|
|
29
|
+
}): void;
|
|
30
|
+
/**
|
|
31
|
+
* @param event - physical socket event.
|
|
32
|
+
* @param listener - previously registered callback.
|
|
33
|
+
*/
|
|
34
|
+
removeEventListener<Event extends keyof ConnectionWebSocketEventMap>(event: Event, listener: (event: ConnectionWebSocketEventMap[Event]) => void): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create an authenticated socket; its consumer owns framing and closing.
|
|
38
|
+
* @param url - absolute WebSocket URL beneath the selected Host mount.
|
|
39
|
+
* @returns a newly connecting socket, before it emits open or failure.
|
|
40
|
+
*/
|
|
41
|
+
export type ConnectionWebSocketFactory = (url: string) => ConnectionWebSocket;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a logical channel against the explicit Host or the page's document base.
|
|
44
|
+
* @param path - absolute logical channel path.
|
|
45
|
+
* @param factory - authenticated socket factory; omission uses the browser API.
|
|
46
|
+
* @param baseUrl - Host base URL, required outside a document.
|
|
47
|
+
* @returns a socket owned by the calling channel.
|
|
48
|
+
*/
|
|
49
|
+
export declare function openConnectionWebSocket(path: string, factory?: ConnectionWebSocketFactory, baseUrl?: string): ConnectionWebSocket;
|
|
50
|
+
//# sourceMappingURL=socket.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** API connection inputs shared by the Host and its clients. */
|
|
2
|
+
/** Whether a Peer participates in forwarded human interactions. */
|
|
3
|
+
export type ConnectionInteractions = 'answer' | 'none';
|
|
4
|
+
/** Launch-token exchange route for API clients. */
|
|
5
|
+
export declare const CONNECT_PATH = "/connect";
|
|
6
|
+
//# sourceMappingURL=connect-protocol.d.ts.map
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* web carrier; the fetch-shaped handler itself is transport-agnostic).
|
|
4
4
|
*/
|
|
5
5
|
import type { IncomingMessage } from 'node:http';
|
|
6
|
+
import type { PeerScope } from '@deepseek-ai/dsh-typert-protocol';
|
|
6
7
|
import type { ConnectionFetchHandler } from './rpc.ts';
|
|
7
8
|
/** Default carrier cap for all HTTP RPC bodies: sized for the default
|
|
8
9
|
* aggregate image limit (200 MiB) after base64 expansion plus envelope
|
|
@@ -25,8 +26,9 @@ interface BridgeServerResponse {
|
|
|
25
26
|
* @param req - incoming node:http request.
|
|
26
27
|
* @param res - node:http response the bridge writes and owns to completion.
|
|
27
28
|
* @param apiHandler - fetch-shaped API carrier the request is dispatched to.
|
|
29
|
+
* @param peer - Peer the carrier admitted the request as.
|
|
28
30
|
* @param maxRequestBodyBytes - maximum bytes buffered for a buffered route.
|
|
29
31
|
*/
|
|
30
|
-
export declare function bridge(req: IncomingMessage, res: BridgeServerResponse, apiHandler: ConnectionFetchHandler, maxRequestBodyBytes?: number): Promise<void>;
|
|
32
|
+
export declare function bridge(req: IncomingMessage, res: BridgeServerResponse, apiHandler: ConnectionFetchHandler, peer: PeerScope, maxRequestBodyBytes?: number): Promise<void>;
|
|
31
33
|
export {};
|
|
32
34
|
//# sourceMappingURL=http-bridge.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
3
3
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
4
4
|
import z from '@deepseek-ai/schemastery';
|
|
5
5
|
import { type ConnectionRecoveryConfig } from './recovery-config.ts';
|
|
6
|
-
export type { PeerAdmission, ConnectionFetchMethod, ConnectionFetchHandler, ConnectionFetchRoute, ConnectionIndexRequest, ConnectionIndexResponse, ConnectionRpcEndpointMatcher, ConnectionRpcAttachment, ConnectionRpcFailure, ConnectionRpcHandler, ConnectionRpcHandlerResult, ConnectionRequestRejection, ConnectionRpcResult, ConnectionRequestBodyMode, ConnectionTrustRequest, ClientRequest, HostConnectionHandle, HostConnectionFetch, HostConnectionRpc, RpcMessage, ServerResponse, } from './rpc.ts';
|
|
7
|
-
export type { PeerId, PeerScope, RemoteInvocation } from '@deepseek-ai/dsh-typert-protocol';
|
|
6
|
+
export type { PeerAdmission, ConnectionAdmission, ConnectionFetchMethod, ConnectionFetchHandler, ConnectionFetchRoute, ConnectionIndexRequest, ConnectionIndexResponse, ConnectionRpcEndpointMatcher, ConnectionRpcAttachment, ConnectionRpcFailure, ConnectionRpcHandler, ConnectionRpcHandlerResult, ConnectionRequestRejection, ConnectionRpcResult, ConnectionRequestBodyMode, ConnectionTrustRequest, ClientRequest, HostConnectionHandle, HostConnectionFetch, HostConnectionRpc, RpcMessage, ServerResponse, } from './rpc.ts';
|
|
7
|
+
export type { PeerId, PeerScope, Principal, RemoteInvocation } from '@deepseek-ai/dsh-typert-protocol';
|
|
8
8
|
export { RpcId, transportError } from './rpc.ts';
|
|
9
|
-
export {
|
|
9
|
+
export { Peer } from './peer.ts';
|
|
10
|
+
export type { PeerOptions } from './peer.ts';
|
|
11
|
+
export { CONNECT_PATH, type ConnectionInteractions } from './connect-protocol.ts';
|
|
10
12
|
export { clientRequestSchema, rpcErrorSchema, rpcIdSchema, rpcMessageSchema, rpcResultSchema, serverResponseSchema, } from './rpc-schema.ts';
|
|
11
13
|
export { HostConnectionService } from './rpc-host.ts';
|
|
12
14
|
export { API_PATH } from './api-path.ts';
|
|
@@ -33,14 +35,12 @@ export interface ConnectionConfig {
|
|
|
33
35
|
recovery?: ConnectionRecoveryConfig;
|
|
34
36
|
/**
|
|
35
37
|
* Authorities this deployment serves beyond loopback: exact `host:port`, or
|
|
36
|
-
* port-less `host` matching any port. The
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* by; the Web runtime derives LAN IP literals from an active all-interface
|
|
40
|
-
* bind. An entry that is not a bare, canonical authority fails plugin load.
|
|
38
|
+
* port-less `host` matching any port. The fence accepts loopback and the
|
|
39
|
+
* listener's own bind IP independently; other remote authorities require
|
|
40
|
+
* an entry here. A non-canonical or non-bare authority fails plugin load.
|
|
41
41
|
*/
|
|
42
42
|
trustedHosts?: string[];
|
|
43
|
-
/** Absolute browser
|
|
43
|
+
/** Absolute browser and API cookie lifetime in days. Default: 30. */
|
|
44
44
|
cookieMaxAgeDays?: number;
|
|
45
45
|
/** Maximum buffered JSON body for every `/api` request. Default: 300 MiB. */
|
|
46
46
|
maxRequestBodyBytes?: number;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Peer: one party admitted to this Host. Its creator fixes the principal
|
|
3
|
+
* it speaks for and owns its lifetime; Gateway hands it to each Remote call as
|
|
4
|
+
* `invocation.peer`.
|
|
5
|
+
* @module @deepseek-ai/dsh-client-connection/src/peer
|
|
6
|
+
*/
|
|
7
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
8
|
+
import type { PeerId, PeerScope, Principal } from '@deepseek-ai/dsh-typert-protocol';
|
|
9
|
+
/** Construction options for one {@link Peer}. */
|
|
10
|
+
export interface PeerOptions {
|
|
11
|
+
/** Caller identity every call through this Peer speaks for. */
|
|
12
|
+
readonly principal: Principal;
|
|
13
|
+
/** Omission permits an event stream; non-owner Peers still cannot answer waterfalls. */
|
|
14
|
+
readonly interactions?: 'answer' | 'none';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One Peer's scope. The instance is its own scope key, so `scopeOf(peer.ctx)`
|
|
18
|
+
* returns it and events dispatched with `scopeTarget(subject, peer)` reach
|
|
19
|
+
* listeners registered through `peer.ctx` and nobody else.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Peer implements PeerScope {
|
|
22
|
+
readonly id: PeerId;
|
|
23
|
+
readonly ctx: Context;
|
|
24
|
+
readonly principal: Principal;
|
|
25
|
+
readonly interactions: 'answer' | 'none';
|
|
26
|
+
readonly signal: AbortSignal;
|
|
27
|
+
private readonly scope;
|
|
28
|
+
/**
|
|
29
|
+
* @param owner - Context the scope fiber hangs under; disposing it disposes the Peer.
|
|
30
|
+
* @param options - the principal fixed for this Peer's lifetime.
|
|
31
|
+
*/
|
|
32
|
+
constructor(owner: Context, options: PeerOptions);
|
|
33
|
+
/** Tear down every connection-lifetime registration; racing calls share one completion. */
|
|
34
|
+
dispose(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=peer.d.ts.map
|
package/lib/types/rpc-host.d.ts
CHANGED
|
@@ -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,10 +14,14 @@ 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
|
|
17
|
-
readonly
|
|
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;
|
|
24
|
+
readonly allowsRemoteAuthorities: boolean;
|
|
20
25
|
/**
|
|
21
26
|
* Provide the Host half over the active HTTP server.
|
|
22
27
|
* @param ctx - owning Connection plugin context.
|
|
@@ -28,11 +33,28 @@ export declare class HostConnectionService extends Service implements HostConnec
|
|
|
28
33
|
get rpc(): HostConnectionRpc;
|
|
29
34
|
/** Exact Fetch-route registry scoped to the Context reading this service. */
|
|
30
35
|
get fetch(): HostConnectionFetch;
|
|
31
|
-
/** Apply the
|
|
36
|
+
/** Apply the Host/Origin fence and require an authenticated live Peer. */
|
|
32
37
|
requestRejection(request: ConnectionTrustRequest): ConnectionRequestRejection;
|
|
33
|
-
/**
|
|
38
|
+
/** Browser requests share an owner Peer; API HTTP does not depend on an attached socket. */
|
|
34
39
|
admit(request: ConnectionTrustRequest): PeerAdmission;
|
|
35
|
-
/**
|
|
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;
|
|
55
|
+
/**
|
|
56
|
+
* Authenticate an index request; native TLS listeners mint Secure cookies.
|
|
57
|
+
*/
|
|
36
58
|
authorizeIndex(request: ConnectionIndexRequest, response: ConnectionIndexResponse): boolean;
|
|
37
59
|
/** Add this process's launch token to the clean application URL. */
|
|
38
60
|
authenticatedUrl(baseUrl: string): string;
|
package/lib/types/rpc.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
/**
|
|
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,13 @@ 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
|
|
155
|
-
readonly
|
|
166
|
+
/** The owner Peer every authenticated browser connection shares. */
|
|
167
|
+
readonly browserPeer: PeerScope;
|
|
168
|
+
/**
|
|
169
|
+
* Whether this deployment accepts authorities beyond loopback: true only
|
|
170
|
+
* when a validated `trustedHosts` entry names a non-loopback hostname.
|
|
171
|
+
*/
|
|
172
|
+
readonly allowsRemoteAuthorities: boolean;
|
|
156
173
|
/**
|
|
157
174
|
* Compose exact Fetch routes and the shared-channel RPC interceptor.
|
|
158
175
|
* @param channel - shared channel mounted by Connection.
|
|
@@ -167,14 +184,32 @@ export interface HostConnectionHandle {
|
|
|
167
184
|
*/
|
|
168
185
|
requestRejection(request: ConnectionTrustRequest): ConnectionRequestRejection;
|
|
169
186
|
/**
|
|
170
|
-
* Admit
|
|
171
|
-
* operator, or it is refused with that status.
|
|
187
|
+
* Admit an HTTP request against its signed browser or API credential and live Peer.
|
|
172
188
|
* @param request - request headers from the HTTP or upgrade request.
|
|
173
|
-
* @returns the
|
|
189
|
+
* @returns the credential's Peer, or the rejection status.
|
|
174
190
|
*/
|
|
175
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;
|
|
176
209
|
/**
|
|
177
210
|
* Authenticate one frontend index request, owning a token redirect or 401.
|
|
211
|
+
* The cookie this mints is `Secure` when the mounted Web carrier serves TLS,
|
|
212
|
+
* which only that listener's protocol decides.
|
|
178
213
|
* @param request - root or configured-index HTTP request.
|
|
179
214
|
* @param response - response owned when the result is false.
|
|
180
215
|
* @returns true only when the frontend may serve index.html.
|
|
@@ -201,9 +236,10 @@ export interface ConnectionFetchHandler {
|
|
|
201
236
|
/**
|
|
202
237
|
* Dispatch one already-authenticated request.
|
|
203
238
|
* @param request - Fetch request below the shared channel.
|
|
204
|
-
* @
|
|
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.
|
|
205
241
|
*/
|
|
206
|
-
fetch(request: Request): Promise<Response>;
|
|
242
|
+
fetch(request: Request, peer: PeerScope): Promise<Response>;
|
|
207
243
|
}
|
|
208
244
|
/** Client caller for logical RPC channels carried by the current transport. */
|
|
209
245
|
export interface ClientConnectionRpc {
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
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.
|
|
4
|
+
"version": "0.2.1-alpha.3",
|
|
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
|
-
"
|
|
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
|
-
"
|
|
38
|
-
"@deepseek-ai/schemastery": "~3.18.5-alpha.
|
|
39
|
-
"
|
|
40
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-alpha.3",
|
|
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/
|
|
48
|
-
"@deepseek-ai/
|
|
52
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.3"
|
|
49
54
|
},
|
|
50
55
|
"devDependencies": {
|
|
51
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.
|
|
52
|
-
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.
|
|
53
|
-
"@deepseek-ai/dsh-brand": "0.2.1-alpha.
|
|
54
|
-
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@deepseek-ai/dsh-session": "0.2.1-alpha.
|
|
58
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.
|
|
56
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.3",
|
|
58
|
+
"@deepseek-ai/dsh-brand": "0.2.1-alpha.3",
|
|
59
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.3",
|
|
60
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.3",
|
|
61
|
+
"@deepseek-ai/dsh-scope": "0.2.1-alpha.3",
|
|
62
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.3",
|
|
63
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.3"
|
|
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
|