@nority/bridge-sdk 0.1.0 → 0.2.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/README.md +124 -10
- package/dist/agent.d.ts +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/bridge.d.ts +12 -22
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +97 -263
- package/dist/bridge.js.map +1 -1
- package/dist/connection-types.d.ts +20 -0
- package/dist/connection-types.d.ts.map +1 -0
- package/dist/connection-types.js +2 -0
- package/dist/connection-types.js.map +1 -0
- package/dist/connection.d.ts +36 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +174 -0
- package/dist/connection.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pairing/client.d.ts +44 -0
- package/dist/pairing/client.d.ts.map +1 -0
- package/dist/pairing/client.js +241 -0
- package/dist/pairing/client.js.map +1 -0
- package/dist/pairing/index.d.ts +3 -0
- package/dist/pairing/index.d.ts.map +1 -0
- package/dist/pairing/index.js +2 -0
- package/dist/pairing/index.js.map +1 -0
- package/dist/pairing/types.d.ts +20 -0
- package/dist/pairing/types.d.ts.map +1 -0
- package/dist/pairing/types.js +2 -0
- package/dist/pairing/types.js.map +1 -0
- package/package.json +1 -1
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentAdapter, BridgeLogger } from "./agent.js";
|
|
2
|
+
import type { AccessTokenRecord } from "./auth/jwt.js";
|
|
3
|
+
import type { WebSocketFactory } from "./transport/websocket.js";
|
|
4
|
+
export interface BridgeConnectionConfig {
|
|
5
|
+
backendUrl: string;
|
|
6
|
+
dataDir: string;
|
|
7
|
+
credential: string;
|
|
8
|
+
privateKeyPem: string;
|
|
9
|
+
agent: AgentAdapter;
|
|
10
|
+
logger?: BridgeLogger;
|
|
11
|
+
seedJwt?: AccessTokenRecord;
|
|
12
|
+
fetchImplementation?: typeof fetch;
|
|
13
|
+
webSocketFactory?: WebSocketFactory;
|
|
14
|
+
clock?: () => Date;
|
|
15
|
+
backoffRandom?: () => number;
|
|
16
|
+
heartbeatIntervalMs?: number;
|
|
17
|
+
idleTimeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export type BridgeConnectionState = "idle" | "connecting" | "connected" | "reconnecting" | "blocked" | "failed" | "stopped";
|
|
20
|
+
//# sourceMappingURL=connection-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-types.d.ts","sourceRoot":"","sources":["../src/connection-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,KAAK,CAAC;IACnC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B,MAAM,GACN,YAAY,GACZ,WAAW,GACX,cAAc,GACd,SAAS,GACT,QAAQ,GACR,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-types.js","sourceRoot":"","sources":["../src/connection-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BridgeConnectionConfig, BridgeConnectionState } from "./connection-types.js";
|
|
2
|
+
import type { ProactiveTurnRequest } from "./runtime/proactive.js";
|
|
3
|
+
import type { BridgeFrame } from "./protocol/frames.js";
|
|
4
|
+
/**
|
|
5
|
+
* Standalone bridge connection that takes a credential and handles
|
|
6
|
+
* auth, transport, reconnection, and conversation management.
|
|
7
|
+
*/
|
|
8
|
+
export declare class BridgeConnection {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly logger;
|
|
11
|
+
private readonly accessTokenManager;
|
|
12
|
+
private readonly conversationRuntime;
|
|
13
|
+
private state;
|
|
14
|
+
private transport;
|
|
15
|
+
private readonly pendingFrameTasks;
|
|
16
|
+
constructor(config: BridgeConnectionConfig);
|
|
17
|
+
getState(): BridgeConnectionState;
|
|
18
|
+
createProactiveTurnFrame(conversationId: string, request: ProactiveTurnRequest): BridgeFrame<"assistant_turn_start">;
|
|
19
|
+
/**
|
|
20
|
+
* Authenticates via challenge-response and opens the WebSocket.
|
|
21
|
+
* Resolves when the connection is established.
|
|
22
|
+
*/
|
|
23
|
+
connect(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Closes the connection and stops reconnecting.
|
|
26
|
+
* Aborts active agent invocations. Idempotent.
|
|
27
|
+
*/
|
|
28
|
+
disconnect(): Promise<void>;
|
|
29
|
+
private ensureAuthenticatedTransport;
|
|
30
|
+
private handleTransportStateChange;
|
|
31
|
+
private handleTransportFrame;
|
|
32
|
+
private trackFrameTask;
|
|
33
|
+
private sendTransportFrame;
|
|
34
|
+
private setState;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAKnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AASxD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,SAAS,CAAgD;IACjE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;gBAElD,MAAM,EAAE,sBAAsB;IAuC1C,QAAQ,IAAI,qBAAqB;IAIjC,wBAAwB,CACtB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,oBAAoB,GAC5B,WAAW,CAAC,sBAAsB,CAAC;IAOtC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAanB,4BAA4B;IA8B1C,OAAO,CAAC,0BAA0B;YAqCpB,oBAAoB;YAYpB,cAAc;IAS5B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { BridgeAccessTokenManager } from "./auth/reconnect.js";
|
|
2
|
+
import { ConversationRuntime } from "./conversation/runtime.js";
|
|
3
|
+
import { AuthenticatedWebSocketTransport, } from "./transport/websocket.js";
|
|
4
|
+
const noopLogger = {
|
|
5
|
+
debug: () => { },
|
|
6
|
+
info: () => { },
|
|
7
|
+
warn: () => { },
|
|
8
|
+
error: () => { },
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Standalone bridge connection that takes a credential and handles
|
|
12
|
+
* auth, transport, reconnection, and conversation management.
|
|
13
|
+
*/
|
|
14
|
+
export class BridgeConnection {
|
|
15
|
+
config;
|
|
16
|
+
logger;
|
|
17
|
+
accessTokenManager;
|
|
18
|
+
conversationRuntime;
|
|
19
|
+
state = "idle";
|
|
20
|
+
transport = null;
|
|
21
|
+
pendingFrameTasks = new Set();
|
|
22
|
+
constructor(config) {
|
|
23
|
+
if (!config) {
|
|
24
|
+
throw new Error("BridgeConnection: config is required");
|
|
25
|
+
}
|
|
26
|
+
if (!config.backendUrl) {
|
|
27
|
+
throw new Error("BridgeConnection: backendUrl is required");
|
|
28
|
+
}
|
|
29
|
+
if (!config.dataDir) {
|
|
30
|
+
throw new Error("BridgeConnection: dataDir is required");
|
|
31
|
+
}
|
|
32
|
+
if (!config.credential) {
|
|
33
|
+
throw new Error("BridgeConnection: credential is required");
|
|
34
|
+
}
|
|
35
|
+
if (!config.privateKeyPem) {
|
|
36
|
+
throw new Error("BridgeConnection: privateKeyPem is required");
|
|
37
|
+
}
|
|
38
|
+
if (!config.agent) {
|
|
39
|
+
throw new Error("BridgeConnection: agent is required");
|
|
40
|
+
}
|
|
41
|
+
this.config = config;
|
|
42
|
+
this.logger = config.logger ?? noopLogger;
|
|
43
|
+
this.accessTokenManager = new BridgeAccessTokenManager({
|
|
44
|
+
backendUrl: config.backendUrl,
|
|
45
|
+
fetchImplementation: config.fetchImplementation,
|
|
46
|
+
clock: config.clock,
|
|
47
|
+
});
|
|
48
|
+
this.conversationRuntime = new ConversationRuntime({
|
|
49
|
+
dataDir: config.dataDir,
|
|
50
|
+
agent: config.agent,
|
|
51
|
+
logger: this.logger,
|
|
52
|
+
clock: config.clock,
|
|
53
|
+
});
|
|
54
|
+
if (config.seedJwt) {
|
|
55
|
+
this.accessTokenManager.seed(config.seedJwt);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
getState() {
|
|
59
|
+
return this.state;
|
|
60
|
+
}
|
|
61
|
+
createProactiveTurnFrame(conversationId, request) {
|
|
62
|
+
return this.conversationRuntime.createProactiveTurnFrame(conversationId, request);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Authenticates via challenge-response and opens the WebSocket.
|
|
66
|
+
* Resolves when the connection is established.
|
|
67
|
+
*/
|
|
68
|
+
async connect() {
|
|
69
|
+
await this.conversationRuntime.loadPersistedConversations();
|
|
70
|
+
await this.ensureAuthenticatedTransport(false);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Closes the connection and stops reconnecting.
|
|
74
|
+
* Aborts active agent invocations. Idempotent.
|
|
75
|
+
*/
|
|
76
|
+
async disconnect() {
|
|
77
|
+
this.conversationRuntime.stop();
|
|
78
|
+
if (this.transport !== null) {
|
|
79
|
+
await this.transport.disconnect();
|
|
80
|
+
this.transport = null;
|
|
81
|
+
}
|
|
82
|
+
await Promise.allSettled(Array.from(this.pendingFrameTasks));
|
|
83
|
+
this.setState("stopped");
|
|
84
|
+
}
|
|
85
|
+
async ensureAuthenticatedTransport(forceRefresh) {
|
|
86
|
+
if (this.transport === null) {
|
|
87
|
+
this.transport = new AuthenticatedWebSocketTransport({
|
|
88
|
+
backendUrl: this.config.backendUrl,
|
|
89
|
+
webSocketFactory: this.config.webSocketFactory,
|
|
90
|
+
heartbeatIntervalMs: this.config.heartbeatIntervalMs,
|
|
91
|
+
idleTimeoutMs: this.config.idleTimeoutMs,
|
|
92
|
+
random: this.config.backoffRandom,
|
|
93
|
+
clock: this.config.clock,
|
|
94
|
+
logger: this.logger,
|
|
95
|
+
onFrame: async (frame) => {
|
|
96
|
+
await this.trackFrameTask(this.handleTransportFrame(frame));
|
|
97
|
+
},
|
|
98
|
+
onStateChange: (transportState) => {
|
|
99
|
+
this.handleTransportStateChange(transportState);
|
|
100
|
+
},
|
|
101
|
+
getAccessToken: async (refreshRequested = false) => {
|
|
102
|
+
const token = await this.accessTokenManager.getAccessToken({
|
|
103
|
+
credential: this.config.credential,
|
|
104
|
+
privateKeyPem: this.config.privateKeyPem,
|
|
105
|
+
forceRefresh: refreshRequested,
|
|
106
|
+
});
|
|
107
|
+
return token.accessJwt;
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
await this.transport.connect(forceRefresh);
|
|
112
|
+
}
|
|
113
|
+
handleTransportStateChange(transportState) {
|
|
114
|
+
switch (transportState) {
|
|
115
|
+
case "connecting":
|
|
116
|
+
this.setState("connecting");
|
|
117
|
+
break;
|
|
118
|
+
case "connected":
|
|
119
|
+
this.setState("connected");
|
|
120
|
+
if (this.transport !== null) {
|
|
121
|
+
const replayRequest = this.conversationRuntime.createReplayRequestFrame();
|
|
122
|
+
if (replayRequest !== null) {
|
|
123
|
+
this.transport.send(replayRequest);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
case "reconnecting":
|
|
128
|
+
this.setState("reconnecting");
|
|
129
|
+
break;
|
|
130
|
+
case "blocked":
|
|
131
|
+
this.setState("blocked");
|
|
132
|
+
break;
|
|
133
|
+
case "failed":
|
|
134
|
+
this.setState("failed");
|
|
135
|
+
break;
|
|
136
|
+
case "stopped":
|
|
137
|
+
if (this.state !== "stopped") {
|
|
138
|
+
this.setState("stopped");
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
case "idle":
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
throw new Error(`BridgeConnection: unsupported transport state ${transportState}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async handleTransportFrame(frame) {
|
|
148
|
+
if (this.transport === null) {
|
|
149
|
+
throw new Error("BridgeConnection: transport must exist while handling frames");
|
|
150
|
+
}
|
|
151
|
+
await this.conversationRuntime.handleFrame(frame, (outboundFrame) => {
|
|
152
|
+
this.sendTransportFrame(outboundFrame);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async trackFrameTask(task) {
|
|
156
|
+
this.pendingFrameTasks.add(task);
|
|
157
|
+
try {
|
|
158
|
+
await task;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
this.pendingFrameTasks.delete(task);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
sendTransportFrame(outboundFrame) {
|
|
165
|
+
if (this.transport === null) {
|
|
166
|
+
throw new Error("BridgeConnection: transport must exist while sending outbound frames");
|
|
167
|
+
}
|
|
168
|
+
this.transport.send(outboundFrame);
|
|
169
|
+
}
|
|
170
|
+
setState(nextState) {
|
|
171
|
+
this.state = nextState;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export type { AgentAdapter, AgentEvent, BridgeConfig, BridgeLogger, ChatTurn, ContentPart, InvokeRequest, MediaReference, PairingInfo, } from "./agent.js";
|
|
2
2
|
export { NorityBridge } from "./bridge.js";
|
|
3
3
|
export type { BridgeState } from "./bridge.js";
|
|
4
|
+
export { PairingClient } from "./pairing/index.js";
|
|
5
|
+
export type { PairingClientConfig, PairingResult } from "./pairing/index.js";
|
|
6
|
+
export { BridgeConnection } from "./connection.js";
|
|
7
|
+
export type { BridgeConnectionConfig, BridgeConnectionState } from "./connection-types.js";
|
|
4
8
|
export { validateConfig } from "./config.js";
|
|
5
9
|
export { validateFrame } from "./protocol/validation.js";
|
|
6
10
|
export type { ValidationResult } from "./protocol/validation.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EACL,qBAAqB,EACrB,mCAAmC,EACnC,qCAAqC,EACrC,cAAc,EACd,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,WAAW,EACX,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,GACL,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,iBAAiB,EACjB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EACL,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEnE,OAAO,EACL,qBAAqB,EACrB,mCAAmC,EACnC,qCAAqC,EACrC,cAAc,EACd,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,WAAW,EACX,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,GACL,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,iBAAiB,EACjB,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EACL,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { NorityBridge } from "./bridge.js";
|
|
2
|
+
export { PairingClient } from "./pairing/index.js";
|
|
3
|
+
export { BridgeConnection } from "./connection.js";
|
|
2
4
|
export { validateConfig } from "./config.js";
|
|
3
5
|
export { validateFrame } from "./protocol/validation.js";
|
|
4
6
|
export { createFrame, BRIDGE_FRAME_TYPES, BACKEND_FRAME_TYPES, } from "./protocol/frames.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,qBAAqB,EACrB,mCAAmC,EACnC,qCAAqC,EACrC,cAAc,EACd,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,WAAW,EACX,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,YAAY,GACb,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAWlC,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EACL,wBAAwB,GACzB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,qBAAqB,EACrB,mCAAmC,EACnC,qCAAqC,EACrC,cAAc,EACd,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,WAAW,EACX,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,QAAQ,EACR,YAAY,GACb,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,+BAA+B,EAC/B,eAAe,EACf,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAWlC,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EACL,wBAAwB,GACzB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PairingInfo } from "../agent.js";
|
|
2
|
+
import type { PairingClientConfig, PairingResult } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Standalone pairing client for the Nority bridge protocol.
|
|
5
|
+
* Handles the unauthenticated WebSocket pairing ceremony and returns a credential.
|
|
6
|
+
*/
|
|
7
|
+
export declare class PairingClient {
|
|
8
|
+
private readonly config;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private readonly stateStore;
|
|
11
|
+
private state;
|
|
12
|
+
private pairingInfo;
|
|
13
|
+
private pairingTimer;
|
|
14
|
+
private pairingSocket;
|
|
15
|
+
private durableState;
|
|
16
|
+
private pendingResolve;
|
|
17
|
+
private pendingReject;
|
|
18
|
+
private initPromise;
|
|
19
|
+
private intentionalClose;
|
|
20
|
+
constructor(config: PairingClientConfig);
|
|
21
|
+
getPairingInfo(): PairingInfo | null;
|
|
22
|
+
/**
|
|
23
|
+
* Performs the pairing ceremony.
|
|
24
|
+
* Resolves when the user approves pairing; rejects on cancel, WS failure, or invalid payload.
|
|
25
|
+
* Single-flight: throws if called while pairing is already in progress.
|
|
26
|
+
*/
|
|
27
|
+
pair(): Promise<PairingResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Cancels an in-progress pairing. Rejects the pending pair() promise.
|
|
30
|
+
* Idempotent — safe to call multiple times.
|
|
31
|
+
*/
|
|
32
|
+
cancel(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Regenerates the pairing token. Closes the existing WebSocket and opens a new one.
|
|
35
|
+
* Throws if not in pairing state.
|
|
36
|
+
*/
|
|
37
|
+
regenerateToken(): PairingInfo;
|
|
38
|
+
private beginPairingFlow;
|
|
39
|
+
private restartPairingFlow;
|
|
40
|
+
private handlePairingMessage;
|
|
41
|
+
private cleanup;
|
|
42
|
+
private clearPairingTimer;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/pairing/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqBrE;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAkD;IACxE,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,gBAAgB,CAAS;gBAErB,MAAM,EAAE,mBAAmB;IAevC,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IAoB9B;;;OAGG;IACH,MAAM,IAAI,IAAI;IAWd;;;OAGG;IACH,eAAe,IAAI,WAAW;YAkBhB,gBAAgB;YAKhB,kBAAkB;YA2DlB,oBAAoB;IA6DlC,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,iBAAiB;CAM1B"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { createPairingExpiry, createPairingToken, createDeeplinkUrl, PAIRING_TOKEN_TTL_SECONDS, } from "../auth/pairing.js";
|
|
2
|
+
import { FileBridgeStateStore } from "../storage/state-store.js";
|
|
3
|
+
import { createFrame } from "../protocol/frames.js";
|
|
4
|
+
import { getEd25519PublicKeyBase64 } from "../crypto/identity.js";
|
|
5
|
+
const noopLogger = {
|
|
6
|
+
debug: () => { },
|
|
7
|
+
info: () => { },
|
|
8
|
+
warn: () => { },
|
|
9
|
+
error: () => { },
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Standalone pairing client for the Nority bridge protocol.
|
|
13
|
+
* Handles the unauthenticated WebSocket pairing ceremony and returns a credential.
|
|
14
|
+
*/
|
|
15
|
+
export class PairingClient {
|
|
16
|
+
config;
|
|
17
|
+
logger;
|
|
18
|
+
stateStore;
|
|
19
|
+
state = "idle";
|
|
20
|
+
pairingInfo = null;
|
|
21
|
+
pairingTimer = null;
|
|
22
|
+
pairingSocket = null;
|
|
23
|
+
durableState = null;
|
|
24
|
+
pendingResolve = null;
|
|
25
|
+
pendingReject = null;
|
|
26
|
+
initPromise = null;
|
|
27
|
+
intentionalClose = false;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
if (!config) {
|
|
30
|
+
throw new Error("PairingClient: config is required");
|
|
31
|
+
}
|
|
32
|
+
if (!config.backendUrl) {
|
|
33
|
+
throw new Error("PairingClient: backendUrl is required");
|
|
34
|
+
}
|
|
35
|
+
if (!config.dataDir) {
|
|
36
|
+
throw new Error("PairingClient: dataDir is required");
|
|
37
|
+
}
|
|
38
|
+
this.config = config;
|
|
39
|
+
this.logger = config.logger ?? noopLogger;
|
|
40
|
+
this.stateStore = new FileBridgeStateStore(config.dataDir);
|
|
41
|
+
}
|
|
42
|
+
getPairingInfo() {
|
|
43
|
+
return this.pairingInfo === null ? null : { ...this.pairingInfo };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Performs the pairing ceremony.
|
|
47
|
+
* Resolves when the user approves pairing; rejects on cancel, WS failure, or invalid payload.
|
|
48
|
+
* Single-flight: throws if called while pairing is already in progress.
|
|
49
|
+
*/
|
|
50
|
+
pair() {
|
|
51
|
+
if (this.state === "pairing") {
|
|
52
|
+
throw new Error("PairingClient.pair: pairing is already in progress");
|
|
53
|
+
}
|
|
54
|
+
this.state = "pairing";
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
this.pendingResolve = resolve;
|
|
57
|
+
this.pendingReject = reject;
|
|
58
|
+
this.initPromise = this.beginPairingFlow();
|
|
59
|
+
this.initPromise.catch((err) => {
|
|
60
|
+
this.state = "failed";
|
|
61
|
+
this.cleanup();
|
|
62
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Cancels an in-progress pairing. Rejects the pending pair() promise.
|
|
68
|
+
* Idempotent — safe to call multiple times.
|
|
69
|
+
*/
|
|
70
|
+
cancel() {
|
|
71
|
+
if (this.state !== "pairing") {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.state = "cancelled";
|
|
75
|
+
const reject = this.pendingReject;
|
|
76
|
+
this.cleanup();
|
|
77
|
+
reject?.(new Error("PairingClient.cancel: pairing was cancelled"));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Regenerates the pairing token. Closes the existing WebSocket and opens a new one.
|
|
81
|
+
* Throws if not in pairing state.
|
|
82
|
+
*/
|
|
83
|
+
regenerateToken() {
|
|
84
|
+
if (this.state !== "pairing") {
|
|
85
|
+
throw new Error(`PairingClient.regenerateToken: must be in pairing state, got ${this.state}`);
|
|
86
|
+
}
|
|
87
|
+
if (this.durableState === null) {
|
|
88
|
+
throw new Error("PairingClient.regenerateToken: identity not loaded");
|
|
89
|
+
}
|
|
90
|
+
void this.restartPairingFlow(this.durableState);
|
|
91
|
+
if (this.pairingInfo === null) {
|
|
92
|
+
throw new Error("PairingClient.regenerateToken: pairingInfo must exist");
|
|
93
|
+
}
|
|
94
|
+
return { ...this.pairingInfo };
|
|
95
|
+
}
|
|
96
|
+
async beginPairingFlow() {
|
|
97
|
+
this.durableState = await this.stateStore.loadOrCreateIdentity();
|
|
98
|
+
await this.restartPairingFlow(this.durableState);
|
|
99
|
+
}
|
|
100
|
+
async restartPairingFlow(identity) {
|
|
101
|
+
const existingSocket = this.pairingSocket;
|
|
102
|
+
this.pairingSocket = null;
|
|
103
|
+
if (existingSocket !== null) {
|
|
104
|
+
this.intentionalClose = true;
|
|
105
|
+
existingSocket.close(1000, "pairing token rotated");
|
|
106
|
+
this.intentionalClose = false;
|
|
107
|
+
}
|
|
108
|
+
this.clearPairingTimer();
|
|
109
|
+
const token = this.config.pairingTokenFactory?.() ?? createPairingToken();
|
|
110
|
+
if (!token) {
|
|
111
|
+
throw new Error("PairingClient: pairing token must not be empty");
|
|
112
|
+
}
|
|
113
|
+
this.pairingInfo = {
|
|
114
|
+
token,
|
|
115
|
+
deeplinkUrl: createDeeplinkUrl(token),
|
|
116
|
+
expiresAt: createPairingExpiry({
|
|
117
|
+
clock: this.config.clock,
|
|
118
|
+
tokenTtlSeconds: PAIRING_TOKEN_TTL_SECONDS,
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
this.config.onPairingInfo?.({ ...this.pairingInfo });
|
|
122
|
+
this.pairingTimer = setTimeout(() => {
|
|
123
|
+
void this.restartPairingFlow(identity);
|
|
124
|
+
}, PAIRING_TOKEN_TTL_SECONDS * 1000);
|
|
125
|
+
const webSocketFactory = this.config.webSocketFactory;
|
|
126
|
+
if (webSocketFactory === undefined) {
|
|
127
|
+
throw new Error("PairingClient: webSocketFactory is required for pairing");
|
|
128
|
+
}
|
|
129
|
+
const socket = webSocketFactory.create(this.config.backendUrl, {});
|
|
130
|
+
this.pairingSocket = socket;
|
|
131
|
+
await waitForOpen(socket);
|
|
132
|
+
socket.addEventListener("message", (event) => {
|
|
133
|
+
void this.handlePairingMessage(event.data, identity);
|
|
134
|
+
});
|
|
135
|
+
socket.addEventListener("close", () => {
|
|
136
|
+
if (this.state === "pairing" && !this.intentionalClose) {
|
|
137
|
+
this.state = "failed";
|
|
138
|
+
const reject = this.pendingReject;
|
|
139
|
+
this.cleanup();
|
|
140
|
+
reject?.(new Error("PairingClient: WebSocket closed before pairing completed"));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
const pairRequest = createFrame("pair_request", {
|
|
144
|
+
pairing_token: token,
|
|
145
|
+
bridge_public_key: getEd25519PublicKeyBase64(identity.publicKeyPem),
|
|
146
|
+
});
|
|
147
|
+
socket.send(JSON.stringify(pairRequest));
|
|
148
|
+
}
|
|
149
|
+
async handlePairingMessage(rawData, identity) {
|
|
150
|
+
let frame;
|
|
151
|
+
try {
|
|
152
|
+
frame = JSON.parse(rawData);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.logger.warn("PairingClient: invalid JSON in pairing message", error);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (frame.type !== "paired") {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const payload = frame.payload;
|
|
162
|
+
if (!payload.agent_id ||
|
|
163
|
+
!payload.bridge_credential ||
|
|
164
|
+
!payload.access_jwt ||
|
|
165
|
+
!payload.expires_at) {
|
|
166
|
+
this.state = "failed";
|
|
167
|
+
const reject = this.pendingReject;
|
|
168
|
+
this.cleanup();
|
|
169
|
+
reject?.(new Error("PairingClient: paired payload missing required fields"));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.state = "paired";
|
|
173
|
+
this.clearPairingTimer();
|
|
174
|
+
const pairingSocket = this.pairingSocket;
|
|
175
|
+
this.pairingSocket = null;
|
|
176
|
+
if (pairingSocket !== null) {
|
|
177
|
+
pairingSocket.close(1000, "pairing completed");
|
|
178
|
+
}
|
|
179
|
+
const result = {
|
|
180
|
+
agentId: payload.agent_id,
|
|
181
|
+
credential: payload.bridge_credential,
|
|
182
|
+
identity: {
|
|
183
|
+
privateKeyPem: identity.privateKeyPem,
|
|
184
|
+
publicKeyPem: identity.publicKeyPem,
|
|
185
|
+
},
|
|
186
|
+
initialToken: {
|
|
187
|
+
accessJwt: payload.access_jwt,
|
|
188
|
+
expiresAt: payload.expires_at,
|
|
189
|
+
agentId: payload.agent_id,
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
const resolve = this.pendingResolve;
|
|
193
|
+
this.pendingResolve = null;
|
|
194
|
+
this.pendingReject = null;
|
|
195
|
+
resolve?.(result);
|
|
196
|
+
}
|
|
197
|
+
cleanup() {
|
|
198
|
+
this.clearPairingTimer();
|
|
199
|
+
const socket = this.pairingSocket;
|
|
200
|
+
this.pairingSocket = null;
|
|
201
|
+
if (socket !== null) {
|
|
202
|
+
socket.close(1000, "pairing cleanup");
|
|
203
|
+
}
|
|
204
|
+
this.pendingResolve = null;
|
|
205
|
+
this.pendingReject = null;
|
|
206
|
+
}
|
|
207
|
+
clearPairingTimer() {
|
|
208
|
+
if (this.pairingTimer !== null) {
|
|
209
|
+
clearTimeout(this.pairingTimer);
|
|
210
|
+
this.pairingTimer = null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function waitForOpen(socket) {
|
|
215
|
+
if (socket.readyState === 1) {
|
|
216
|
+
return Promise.resolve();
|
|
217
|
+
}
|
|
218
|
+
return new Promise((resolve, reject) => {
|
|
219
|
+
const handleOpen = () => {
|
|
220
|
+
cleanup();
|
|
221
|
+
resolve();
|
|
222
|
+
};
|
|
223
|
+
const handleError = () => {
|
|
224
|
+
cleanup();
|
|
225
|
+
reject(new Error("PairingClient: WebSocket error during connection"));
|
|
226
|
+
};
|
|
227
|
+
const handleClose = () => {
|
|
228
|
+
cleanup();
|
|
229
|
+
reject(new Error("PairingClient: WebSocket closed before opening"));
|
|
230
|
+
};
|
|
231
|
+
const cleanup = () => {
|
|
232
|
+
socket.removeEventListener("open", handleOpen);
|
|
233
|
+
socket.removeEventListener("error", handleError);
|
|
234
|
+
socket.removeEventListener("close", handleClose);
|
|
235
|
+
};
|
|
236
|
+
socket.addEventListener("open", handleOpen);
|
|
237
|
+
socket.addEventListener("error", handleError);
|
|
238
|
+
socket.addEventListener("close", handleClose);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=client.js.map
|