syn-link 1.0.0
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/LICENSE +75 -0
- package/README.md +80 -0
- package/dist/crypto.d.ts +140 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +326 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +204 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +671 -0
- package/dist/index.js.map +1 -0
- package/dist/local.d.ts +44 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +67 -0
- package/dist/local.js.map +1 -0
- package/dist/ratchet.d.ts +83 -0
- package/dist/ratchet.d.ts.map +1 -0
- package/dist/ratchet.js +233 -0
- package/dist/ratchet.js.map +1 -0
- package/dist/relay-client.d.ts +162 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +209 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/sse.d.ts +19 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +139 -0
- package/dist/sse.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/ws.d.ts +18 -0
- package/dist/ws.d.ts.map +1 -0
- package/dist/ws.js +100 -0
- package/dist/ws.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { AgentInfo, ChatInfo, RawIncomingMessage, ChatCapabilities, BlockRule, RateLimitConfig } from "./types.js";
|
|
2
|
+
export interface RelayConfig {
|
|
3
|
+
relay_url: string;
|
|
4
|
+
agent_id: string;
|
|
5
|
+
api_key: string;
|
|
6
|
+
signing_secret_key?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function saveConfig(config: RelayConfig, dataDir?: string): void;
|
|
9
|
+
export declare function loadConfig(dataDir?: string): RelayConfig | null;
|
|
10
|
+
export declare function registerWithRelay(relayUrl: string, username: string, name: string, description: string, publicKey: string, signingPublicKey?: string, visibility?: string, statusVisibility?: string): Promise<RelayConfig>;
|
|
11
|
+
export declare class RelayClient {
|
|
12
|
+
private relayUrl;
|
|
13
|
+
private apiKey;
|
|
14
|
+
private signingSecretKey?;
|
|
15
|
+
agentId: string;
|
|
16
|
+
constructor(config: RelayConfig);
|
|
17
|
+
private request;
|
|
18
|
+
listAgents(): Promise<{
|
|
19
|
+
agents: AgentInfo[];
|
|
20
|
+
}>;
|
|
21
|
+
getAgent(agentId: string): Promise<AgentInfo>;
|
|
22
|
+
getAgentCard(agentId: string): Promise<Record<string, unknown>>;
|
|
23
|
+
updateAgent(updates: {
|
|
24
|
+
visibility?: string;
|
|
25
|
+
status_visibility?: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
setRateLimits(config: RateLimitConfig): Promise<void>;
|
|
30
|
+
setBlockRules(rules: BlockRule[]): Promise<void>;
|
|
31
|
+
createChat(participantIds: string[], myCapabilities?: string[]): Promise<{
|
|
32
|
+
chat_id: string;
|
|
33
|
+
participants: string[];
|
|
34
|
+
is_large_group: boolean;
|
|
35
|
+
}>;
|
|
36
|
+
listChats(): Promise<{
|
|
37
|
+
chats: ChatInfo[];
|
|
38
|
+
}>;
|
|
39
|
+
getChat(chatId: string): Promise<ChatInfo>;
|
|
40
|
+
getCapabilities(chatId: string): Promise<ChatCapabilities>;
|
|
41
|
+
updateCapabilities(chatId: string, capabilities: string[]): Promise<void>;
|
|
42
|
+
sendMessage(payload: {
|
|
43
|
+
chat_id: string;
|
|
44
|
+
content_type: string;
|
|
45
|
+
reply_expected: boolean;
|
|
46
|
+
reply_to?: string;
|
|
47
|
+
mentions?: string[];
|
|
48
|
+
version?: number;
|
|
49
|
+
recipients?: Array<{
|
|
50
|
+
agent_id: string;
|
|
51
|
+
encrypted_content: string;
|
|
52
|
+
nonce: string;
|
|
53
|
+
ratchet_header?: string;
|
|
54
|
+
}>;
|
|
55
|
+
group_encrypted_content?: string;
|
|
56
|
+
group_nonce?: string;
|
|
57
|
+
group_key_version?: number;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
message_id: string;
|
|
60
|
+
delivered_to?: number;
|
|
61
|
+
large_group?: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
checkMessages(chatId?: string, markRead?: boolean, maxBytes?: number): Promise<{
|
|
64
|
+
count: number;
|
|
65
|
+
messages: RawIncomingMessage[];
|
|
66
|
+
batch?: {
|
|
67
|
+
bytes_returned: number;
|
|
68
|
+
max_bytes: number;
|
|
69
|
+
has_more: boolean;
|
|
70
|
+
total_pending?: number;
|
|
71
|
+
};
|
|
72
|
+
}>;
|
|
73
|
+
rotateKey(newPublicKey: string, signature: string): Promise<void>;
|
|
74
|
+
deleteAgent(signature: string): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Upgrade from API key to signature-only auth (Protocol v1 §6.2).
|
|
77
|
+
* Signs "UPGRADE-AUTH <agent_id>" with the signing key, sends to relay,
|
|
78
|
+
* and switches this client to signature-only mode.
|
|
79
|
+
*/
|
|
80
|
+
upgradeAuth(signingSecretKey: string): Promise<void>;
|
|
81
|
+
distributeGroupKey(chatId: string, keyVersion: number, keys: Array<{
|
|
82
|
+
agent_id: string;
|
|
83
|
+
encrypted_key: string;
|
|
84
|
+
nonce: string;
|
|
85
|
+
}>): Promise<void>;
|
|
86
|
+
getGroupKey(chatId: string, version?: number): Promise<{
|
|
87
|
+
chat_id: string;
|
|
88
|
+
key_version: number;
|
|
89
|
+
encrypted_key: string;
|
|
90
|
+
nonce: string;
|
|
91
|
+
}>;
|
|
92
|
+
rotateGroupKey(chatId: string, keys: Array<{
|
|
93
|
+
agent_id: string;
|
|
94
|
+
encrypted_key: string;
|
|
95
|
+
nonce: string;
|
|
96
|
+
}>): Promise<{
|
|
97
|
+
new_key_version: number;
|
|
98
|
+
}>;
|
|
99
|
+
uploadPreKeyBundle(bundle: {
|
|
100
|
+
identity_key: string;
|
|
101
|
+
signed_pre_key: string;
|
|
102
|
+
signed_pre_key_signature: string;
|
|
103
|
+
signed_pre_key_id: number;
|
|
104
|
+
one_time_pre_keys: Array<{
|
|
105
|
+
key_id: number;
|
|
106
|
+
public_key: string;
|
|
107
|
+
}>;
|
|
108
|
+
}): Promise<void>;
|
|
109
|
+
getPreKeyBundle(agentId: string): Promise<{
|
|
110
|
+
bundle: {
|
|
111
|
+
identity_key: string;
|
|
112
|
+
signed_pre_key: string;
|
|
113
|
+
signed_pre_key_signature: string;
|
|
114
|
+
signed_pre_key_id: number;
|
|
115
|
+
one_time_pre_key?: {
|
|
116
|
+
key_id: number;
|
|
117
|
+
public_key: string;
|
|
118
|
+
} | null;
|
|
119
|
+
} | null;
|
|
120
|
+
}>;
|
|
121
|
+
replenishPreKeys(keys: Array<{
|
|
122
|
+
key_id: number;
|
|
123
|
+
public_key: string;
|
|
124
|
+
}>): Promise<{
|
|
125
|
+
count: number;
|
|
126
|
+
}>;
|
|
127
|
+
createConnectKey(opts?: {
|
|
128
|
+
label?: string;
|
|
129
|
+
metadata?: Record<string, unknown>;
|
|
130
|
+
max_uses?: number;
|
|
131
|
+
expires_at?: string;
|
|
132
|
+
}): Promise<{
|
|
133
|
+
key: string;
|
|
134
|
+
agent_id: string;
|
|
135
|
+
label: string;
|
|
136
|
+
metadata: Record<string, unknown>;
|
|
137
|
+
max_uses: number | null;
|
|
138
|
+
expires_at: string | null;
|
|
139
|
+
}>;
|
|
140
|
+
redeemConnectKey(key: string, metadata?: Record<string, unknown>): Promise<{
|
|
141
|
+
message: string;
|
|
142
|
+
agent: Record<string, unknown>;
|
|
143
|
+
connect_key: string;
|
|
144
|
+
already_connected: boolean;
|
|
145
|
+
}>;
|
|
146
|
+
listConnectKeys(): Promise<{
|
|
147
|
+
keys: Array<{
|
|
148
|
+
id: string;
|
|
149
|
+
label: string;
|
|
150
|
+
metadata: Record<string, unknown>;
|
|
151
|
+
max_uses: number | null;
|
|
152
|
+
used_count: number;
|
|
153
|
+
expires_at: string | null;
|
|
154
|
+
created_at: string;
|
|
155
|
+
}>;
|
|
156
|
+
}>;
|
|
157
|
+
revokeConnectKey(key: string): Promise<{
|
|
158
|
+
revoked: boolean;
|
|
159
|
+
key: string;
|
|
160
|
+
}>;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=relay-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.d.ts","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// SYN Link SDK — Relay HTTP + WebSocket Client (Protocol v1)
|
|
2
|
+
// Talks to the Cloudflare Workers relay server.
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import os from "os";
|
|
6
|
+
import { signRequest, signMessage } from "./crypto.js";
|
|
7
|
+
export function saveConfig(config, dataDir) {
|
|
8
|
+
const dir = dataDir || path.join(os.homedir(), ".syn");
|
|
9
|
+
const configFile = path.join(dir, "config.json");
|
|
10
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
11
|
+
fs.writeFileSync(configFile, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
12
|
+
}
|
|
13
|
+
export function loadConfig(dataDir) {
|
|
14
|
+
const dir = dataDir || path.join(os.homedir(), ".syn");
|
|
15
|
+
const configFile = path.join(dir, "config.json");
|
|
16
|
+
if (!fs.existsSync(configFile))
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(fs.readFileSync(configFile, "utf-8"));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function registerWithRelay(relayUrl, username, name, description, publicKey, signingPublicKey, visibility, statusVisibility) {
|
|
26
|
+
const url = `${relayUrl.replace(/\/$/, "")}/v1/agents/register`;
|
|
27
|
+
const res = await fetch(url, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "Content-Type": "application/json" },
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
username, name, description,
|
|
32
|
+
public_key: publicKey,
|
|
33
|
+
signing_public_key: signingPublicKey,
|
|
34
|
+
visibility,
|
|
35
|
+
status_visibility: statusVisibility,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
const data = (await res.json());
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
throw new Error(data.error || `Registration failed: ${res.status}`);
|
|
41
|
+
return { relay_url: relayUrl, agent_id: data.agent_id, api_key: data.api_key };
|
|
42
|
+
}
|
|
43
|
+
export class RelayClient {
|
|
44
|
+
relayUrl;
|
|
45
|
+
apiKey;
|
|
46
|
+
signingSecretKey;
|
|
47
|
+
agentId;
|
|
48
|
+
constructor(config) {
|
|
49
|
+
this.relayUrl = config.relay_url.replace(/\/$/, "");
|
|
50
|
+
this.apiKey = config.api_key;
|
|
51
|
+
this.agentId = config.agent_id;
|
|
52
|
+
this.signingSecretKey = config.signing_secret_key;
|
|
53
|
+
}
|
|
54
|
+
async request(method, path, body) {
|
|
55
|
+
const url = `${this.relayUrl}${path}`;
|
|
56
|
+
const headers = {
|
|
57
|
+
"Content-Type": "application/json",
|
|
58
|
+
};
|
|
59
|
+
// Use signature auth if signing key is available, otherwise API key
|
|
60
|
+
if (this.signingSecretKey) {
|
|
61
|
+
const bodyStr = body ? JSON.stringify(body) : undefined;
|
|
62
|
+
const sigHeaders = await signRequest(method, path, bodyStr, this.agentId, this.signingSecretKey);
|
|
63
|
+
Object.assign(headers, sigHeaders);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
headers["X-API-Key"] = this.apiKey;
|
|
67
|
+
}
|
|
68
|
+
const doFetch = () => fetch(url, {
|
|
69
|
+
method,
|
|
70
|
+
headers,
|
|
71
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
72
|
+
});
|
|
73
|
+
let res = await doFetch();
|
|
74
|
+
// Single retry on transient server errors (5xx)
|
|
75
|
+
if (res.status >= 500) {
|
|
76
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
77
|
+
res = await doFetch();
|
|
78
|
+
}
|
|
79
|
+
const text = await res.text();
|
|
80
|
+
let data;
|
|
81
|
+
try {
|
|
82
|
+
data = JSON.parse(text);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new Error(`Relay returned non-JSON from ${method} ${path} (${res.status}): ${text.slice(0, 200)}`);
|
|
86
|
+
}
|
|
87
|
+
if (!res.ok) {
|
|
88
|
+
throw new Error(data.error || `Relay error: ${res.status}`);
|
|
89
|
+
}
|
|
90
|
+
return data;
|
|
91
|
+
}
|
|
92
|
+
// ─── Agents ──────────────────────────────────────────────
|
|
93
|
+
async listAgents() {
|
|
94
|
+
return (await this.request("GET", "/v1/agents"));
|
|
95
|
+
}
|
|
96
|
+
async getAgent(agentId) {
|
|
97
|
+
return (await this.request("GET", `/v1/agents/${agentId}`));
|
|
98
|
+
}
|
|
99
|
+
async getAgentCard(agentId) {
|
|
100
|
+
return (await this.request("GET", `/v1/agents/${agentId}/agent-card`));
|
|
101
|
+
}
|
|
102
|
+
async updateAgent(updates) {
|
|
103
|
+
await this.request("PATCH", "/v1/agents/me", updates);
|
|
104
|
+
}
|
|
105
|
+
// ─── Rate Limits & Block Rules ───────────────────────────
|
|
106
|
+
async setRateLimits(config) {
|
|
107
|
+
await this.request("PATCH", "/v1/agents/me/rate-limits", config);
|
|
108
|
+
}
|
|
109
|
+
async setBlockRules(rules) {
|
|
110
|
+
await this.request("POST", "/v1/agents/me/block-rules", { rules });
|
|
111
|
+
}
|
|
112
|
+
// ─── Chats ───────────────────────────────────────────────
|
|
113
|
+
async createChat(participantIds, myCapabilities) {
|
|
114
|
+
const body = { participant_ids: participantIds };
|
|
115
|
+
if (myCapabilities)
|
|
116
|
+
body.my_capabilities = myCapabilities;
|
|
117
|
+
return (await this.request("POST", "/v1/chats", body));
|
|
118
|
+
}
|
|
119
|
+
async listChats() {
|
|
120
|
+
return (await this.request("GET", "/v1/chats"));
|
|
121
|
+
}
|
|
122
|
+
async getChat(chatId) {
|
|
123
|
+
return (await this.request("GET", `/v1/chats/${chatId}`));
|
|
124
|
+
}
|
|
125
|
+
async getCapabilities(chatId) {
|
|
126
|
+
return (await this.request("GET", `/v1/chats/${chatId}/capabilities`));
|
|
127
|
+
}
|
|
128
|
+
async updateCapabilities(chatId, capabilities) {
|
|
129
|
+
await this.request("PATCH", `/v1/chats/${chatId}/capabilities`, { my_capabilities: capabilities });
|
|
130
|
+
}
|
|
131
|
+
// ─── Messages ────────────────────────────────────────────
|
|
132
|
+
async sendMessage(payload) {
|
|
133
|
+
return (await this.request("POST", "/v1/messages", payload));
|
|
134
|
+
}
|
|
135
|
+
async checkMessages(chatId, markRead = true, maxBytes) {
|
|
136
|
+
let queryPath = `/v1/messages?mark_read=${markRead}`;
|
|
137
|
+
if (chatId)
|
|
138
|
+
queryPath += `&chat_id=${chatId}`;
|
|
139
|
+
if (maxBytes !== undefined)
|
|
140
|
+
queryPath += `&max_bytes=${maxBytes}`;
|
|
141
|
+
return (await this.request("GET", queryPath));
|
|
142
|
+
}
|
|
143
|
+
// ─── Key Management ──────────────────────────────────────
|
|
144
|
+
async rotateKey(newPublicKey, signature) {
|
|
145
|
+
await this.request("POST", "/v1/agents/me/rotate-key", {
|
|
146
|
+
new_public_key: newPublicKey,
|
|
147
|
+
signature,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
async deleteAgent(signature) {
|
|
151
|
+
await this.request("DELETE", "/v1/agents/me", { signature });
|
|
152
|
+
}
|
|
153
|
+
// ─── Auth Upgrade ────────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Upgrade from API key to signature-only auth (Protocol v1 §6.2).
|
|
156
|
+
* Signs "UPGRADE-AUTH <agent_id>" with the signing key, sends to relay,
|
|
157
|
+
* and switches this client to signature-only mode.
|
|
158
|
+
*/
|
|
159
|
+
async upgradeAuth(signingSecretKey) {
|
|
160
|
+
const message = `UPGRADE-AUTH ${this.agentId}`;
|
|
161
|
+
const signature = signMessage(message, signingSecretKey);
|
|
162
|
+
await this.request("POST", "/v1/agents/me/upgrade-auth", { signature });
|
|
163
|
+
// Switch to signature-only mode
|
|
164
|
+
this.signingSecretKey = signingSecretKey;
|
|
165
|
+
this.apiKey = "";
|
|
166
|
+
}
|
|
167
|
+
// ─── Group Key Management (Large Groups §7) ─────────────
|
|
168
|
+
async distributeGroupKey(chatId, keyVersion, keys) {
|
|
169
|
+
await this.request("POST", `/v1/chats/${chatId}/keys`, {
|
|
170
|
+
key_version: keyVersion,
|
|
171
|
+
keys,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async getGroupKey(chatId, version) {
|
|
175
|
+
const versionParam = version !== undefined ? `?version=${version}` : "";
|
|
176
|
+
return (await this.request("GET", `/v1/chats/${chatId}/keys${versionParam}`));
|
|
177
|
+
}
|
|
178
|
+
async rotateGroupKey(chatId, keys) {
|
|
179
|
+
return (await this.request("POST", `/v1/chats/${chatId}/rotate-key`, { keys }));
|
|
180
|
+
}
|
|
181
|
+
// ─── Pre-Key Bundles (X3DH §4.2) ────────────────────────
|
|
182
|
+
async uploadPreKeyBundle(bundle) {
|
|
183
|
+
await this.request("PUT", "/v1/agents/me/prekeys", bundle);
|
|
184
|
+
}
|
|
185
|
+
async getPreKeyBundle(agentId) {
|
|
186
|
+
return (await this.request("GET", `/v1/agents/${agentId}/prekeys`));
|
|
187
|
+
}
|
|
188
|
+
async replenishPreKeys(keys) {
|
|
189
|
+
return (await this.request("POST", "/v1/agents/me/prekeys/replenish", {
|
|
190
|
+
one_time_pre_keys: keys,
|
|
191
|
+
}));
|
|
192
|
+
}
|
|
193
|
+
// ─── Connect Keys (Business Connect) ─────────────────────
|
|
194
|
+
async createConnectKey(opts) {
|
|
195
|
+
return (await this.request("POST", "/v1/connect-keys", opts || {}));
|
|
196
|
+
}
|
|
197
|
+
async redeemConnectKey(key, metadata) {
|
|
198
|
+
return (await this.request("POST", `/v1/connect-keys/${key}/redeem`, {
|
|
199
|
+
metadata,
|
|
200
|
+
}));
|
|
201
|
+
}
|
|
202
|
+
async listConnectKeys() {
|
|
203
|
+
return (await this.request("GET", "/v1/connect-keys"));
|
|
204
|
+
}
|
|
205
|
+
async revokeConnectKey(key) {
|
|
206
|
+
return (await this.request("DELETE", `/v1/connect-keys/${key}`));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=relay-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}
|
package/dist/sse.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RawIncomingMessage } from "./types.js";
|
|
2
|
+
export declare class SSEManager {
|
|
3
|
+
private relayUrl;
|
|
4
|
+
private agentId;
|
|
5
|
+
private apiKey;
|
|
6
|
+
private signingSecretKey?;
|
|
7
|
+
private abortController;
|
|
8
|
+
private reconnectTimer;
|
|
9
|
+
private reconnectAttempt;
|
|
10
|
+
private shouldReconnect;
|
|
11
|
+
private onMessage;
|
|
12
|
+
constructor(relayUrl: string, agentId: string, apiKey: string, signingSecretKey?: string);
|
|
13
|
+
connect(onMessage: (message: RawIncomingMessage) => void): void;
|
|
14
|
+
disconnect(): void;
|
|
15
|
+
private open;
|
|
16
|
+
private handleEvent;
|
|
17
|
+
private scheduleReconnect;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,qBAAa,UAAU;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAwD;gBAE7D,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAOxF,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI;IAO/D,UAAU,IAAI,IAAI;YAMJ,IAAI;IA0ElB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,iBAAiB;CAM5B"}
|
package/dist/sse.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// SYN Link SDK — SSE (Server-Sent Events) Manager
|
|
2
|
+
// Real-time message push via SSE — simpler and cheaper than WebSocket.
|
|
3
|
+
// Same auto-reconnect and token exchange pattern, but one-way (server→client).
|
|
4
|
+
import { signRequest } from "./crypto.js";
|
|
5
|
+
export class SSEManager {
|
|
6
|
+
relayUrl;
|
|
7
|
+
agentId;
|
|
8
|
+
apiKey;
|
|
9
|
+
signingSecretKey;
|
|
10
|
+
abortController = null;
|
|
11
|
+
reconnectTimer = null;
|
|
12
|
+
reconnectAttempt = 0;
|
|
13
|
+
shouldReconnect = false;
|
|
14
|
+
onMessage = null;
|
|
15
|
+
constructor(relayUrl, agentId, apiKey, signingSecretKey) {
|
|
16
|
+
this.relayUrl = relayUrl;
|
|
17
|
+
this.agentId = agentId;
|
|
18
|
+
this.apiKey = apiKey;
|
|
19
|
+
this.signingSecretKey = signingSecretKey;
|
|
20
|
+
}
|
|
21
|
+
connect(onMessage) {
|
|
22
|
+
this.onMessage = onMessage;
|
|
23
|
+
this.shouldReconnect = true;
|
|
24
|
+
this.reconnectAttempt = 0;
|
|
25
|
+
this.open();
|
|
26
|
+
}
|
|
27
|
+
disconnect() {
|
|
28
|
+
this.shouldReconnect = false;
|
|
29
|
+
if (this.reconnectTimer) {
|
|
30
|
+
clearTimeout(this.reconnectTimer);
|
|
31
|
+
this.reconnectTimer = null;
|
|
32
|
+
}
|
|
33
|
+
if (this.abortController) {
|
|
34
|
+
this.abortController.abort();
|
|
35
|
+
this.abortController = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async open() {
|
|
39
|
+
// Step 1: Exchange credentials for a short-lived token (same as WebSocket)
|
|
40
|
+
let token;
|
|
41
|
+
try {
|
|
42
|
+
const headers = { "Content-Type": "application/json" };
|
|
43
|
+
if (this.signingSecretKey) {
|
|
44
|
+
const sigHeaders = await signRequest("POST", "/v1/ws/token", undefined, this.agentId, this.signingSecretKey);
|
|
45
|
+
Object.assign(headers, sigHeaders);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
headers["X-API-Key"] = this.apiKey;
|
|
49
|
+
}
|
|
50
|
+
const res = await fetch(`${this.relayUrl}/v1/ws/token`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers,
|
|
53
|
+
});
|
|
54
|
+
if (!res.ok)
|
|
55
|
+
throw new Error(`Token exchange failed: ${res.status}`);
|
|
56
|
+
token = (await res.json()).token;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
this.scheduleReconnect();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Step 2: Open SSE connection
|
|
63
|
+
const sseUrl = `${this.relayUrl}/v1/sse?agent_id=${encodeURIComponent(this.agentId)}&token=${encodeURIComponent(token)}`;
|
|
64
|
+
this.abortController = new AbortController();
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(sseUrl, {
|
|
67
|
+
headers: { "Accept": "text/event-stream" },
|
|
68
|
+
signal: this.abortController.signal,
|
|
69
|
+
});
|
|
70
|
+
if (!res.ok || !res.body) {
|
|
71
|
+
throw new Error(`SSE connection failed: ${res.status}`);
|
|
72
|
+
}
|
|
73
|
+
this.reconnectAttempt = 0;
|
|
74
|
+
// Parse SSE stream
|
|
75
|
+
const reader = res.body.getReader();
|
|
76
|
+
const decoder = new TextDecoder();
|
|
77
|
+
let buffer = "";
|
|
78
|
+
const processStream = async () => {
|
|
79
|
+
try {
|
|
80
|
+
while (true) {
|
|
81
|
+
const { done, value } = await reader.read();
|
|
82
|
+
if (done)
|
|
83
|
+
break;
|
|
84
|
+
buffer += decoder.decode(value, { stream: true });
|
|
85
|
+
const events = buffer.split("\n\n");
|
|
86
|
+
buffer = events.pop() || ""; // Keep incomplete event in buffer
|
|
87
|
+
for (const event of events) {
|
|
88
|
+
if (!event.trim())
|
|
89
|
+
continue;
|
|
90
|
+
this.handleEvent(event);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err instanceof Error && err.name === "AbortError")
|
|
96
|
+
return;
|
|
97
|
+
// Stream ended unexpectedly
|
|
98
|
+
}
|
|
99
|
+
// Stream closed — reconnect
|
|
100
|
+
this.scheduleReconnect();
|
|
101
|
+
};
|
|
102
|
+
processStream();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
this.scheduleReconnect();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
handleEvent(raw) {
|
|
109
|
+
let eventType = "message";
|
|
110
|
+
let data = "";
|
|
111
|
+
for (const line of raw.split("\n")) {
|
|
112
|
+
if (line.startsWith("event: ")) {
|
|
113
|
+
eventType = line.slice(7).trim();
|
|
114
|
+
}
|
|
115
|
+
else if (line.startsWith("data: ")) {
|
|
116
|
+
data += line.slice(6);
|
|
117
|
+
}
|
|
118
|
+
else if (line.startsWith("data:")) {
|
|
119
|
+
data += line.slice(5);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (eventType === "message" && data && this.onMessage) {
|
|
123
|
+
try {
|
|
124
|
+
const parsed = JSON.parse(data);
|
|
125
|
+
this.onMessage(parsed);
|
|
126
|
+
}
|
|
127
|
+
catch { /* ignore malformed events */ }
|
|
128
|
+
}
|
|
129
|
+
// Ignore "connected" and "ping" events — they're just keepalive
|
|
130
|
+
}
|
|
131
|
+
scheduleReconnect() {
|
|
132
|
+
if (!this.shouldReconnect)
|
|
133
|
+
return;
|
|
134
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempt), 60_000) + Math.random() * 1000;
|
|
135
|
+
this.reconnectAttempt++;
|
|
136
|
+
this.reconnectTimer = setTimeout(() => this.open(), delay);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=sse.js.map
|
package/dist/sse.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}
|