dropspace 0.0.0-stage → 0.1.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 +17 -2
- package/dist/automerge/index.d.ts +108 -0
- package/dist/automerge/index.d.ts.map +1 -0
- package/dist/automerge/index.js +437 -0
- package/dist/automerge/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +372 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/channel.d.ts +153 -0
- package/dist/client/channel.d.ts.map +1 -0
- package/dist/client/channel.js +704 -0
- package/dist/client/channel.js.map +1 -0
- package/dist/client/client.d.ts +376 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1421 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/events.d.ts +14 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +71 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/identity.d.ts +89 -0
- package/dist/client/identity.d.ts.map +1 -0
- package/dist/client/identity.js +274 -0
- package/dist/client/identity.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/peer-connection.d.ts +190 -0
- package/dist/client/peer-connection.d.ts.map +1 -0
- package/dist/client/peer-connection.js +647 -0
- package/dist/client/peer-connection.js.map +1 -0
- package/dist/client/peer-selection.d.ts +70 -0
- package/dist/client/peer-selection.d.ts.map +1 -0
- package/dist/client/peer-selection.js +193 -0
- package/dist/client/peer-selection.js.map +1 -0
- package/dist/client/storage.d.ts +118 -0
- package/dist/client/storage.d.ts.map +1 -0
- package/dist/client/storage.js +463 -0
- package/dist/client/storage.js.map +1 -0
- package/dist/files/index.d.ts +140 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +751 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/sha256.d.ts +24 -0
- package/dist/files/sha256.d.ts.map +1 -0
- package/dist/files/sha256.js +147 -0
- package/dist/files/sha256.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/envelope.d.ts +61 -0
- package/dist/protocol/envelope.d.ts.map +1 -0
- package/dist/protocol/envelope.js +268 -0
- package/dist/protocol/envelope.js.map +1 -0
- package/dist/protocol/framing.d.ts +69 -0
- package/dist/protocol/framing.d.ts.map +1 -0
- package/dist/protocol/framing.js +145 -0
- package/dist/protocol/framing.js.map +1 -0
- package/dist/protocol/index.d.ts +3 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +3 -0
- package/dist/protocol/index.js.map +1 -0
- package/fixtures/envelopes.json +132 -0
- package/package.json +51 -4
package/dist/cli.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir, hostname } from "node:os";
|
|
4
|
+
import { dirname, join, resolve } from "node:path";
|
|
5
|
+
import { parseArgs } from "node:util";
|
|
6
|
+
import WebSocket from "ws";
|
|
7
|
+
import { DropspaceClient, loadOrCreateDeviceIdentity, } from "./client/index.js";
|
|
8
|
+
const CLI_VERSION = "0.1.0";
|
|
9
|
+
const DEFAULT_BASE_URL = "https://dropspace.app";
|
|
10
|
+
class FileIdentityStorageAdapter {
|
|
11
|
+
filePath;
|
|
12
|
+
supportsCryptoKeyCloning = false;
|
|
13
|
+
constructor(filePath) {
|
|
14
|
+
this.filePath = filePath;
|
|
15
|
+
}
|
|
16
|
+
async load() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await readFile(this.filePath, "utf8");
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err?.code === "ENOENT") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async save(record) {
|
|
29
|
+
await mkdir(dirname(this.filePath), { recursive: true, mode: 0o700 });
|
|
30
|
+
await writeFile(this.filePath, JSON.stringify(record, null, 2), {
|
|
31
|
+
encoding: "utf8",
|
|
32
|
+
mode: 0o600,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async clear() {
|
|
36
|
+
await rm(this.filePath, { force: true });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const nodeWebSocketFactory = (url) => new WebSocket(url);
|
|
40
|
+
function printHelp() {
|
|
41
|
+
console.log(`dropspace v${CLI_VERSION} — Dropspace P2P & Signaling CLI
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
dropspace <command> [options]
|
|
45
|
+
|
|
46
|
+
Commands:
|
|
47
|
+
health Check server /healthz and /v1/config
|
|
48
|
+
identity [show|reset] Show or reset local device identity
|
|
49
|
+
invite create Create a pairing invite for a space
|
|
50
|
+
invite claim <tokenOrUrl> Claim a pairing invite token or deep link
|
|
51
|
+
peers List peers in a space
|
|
52
|
+
listen Connect and stream presence, pairing, and message events
|
|
53
|
+
send Send a text or JSON message (via --via-hub)
|
|
54
|
+
|
|
55
|
+
Global Options:
|
|
56
|
+
-u, --url <url> Dropspace Core URL (default: $DROPSPACE_URL or ${DEFAULT_BASE_URL})
|
|
57
|
+
-a, --app <appId> Registered App ID (default: $DROPSPACE_APP_ID)
|
|
58
|
+
-s, --space <spaceId> Space ID (default: $DROPSPACE_SPACE_ID)
|
|
59
|
+
-p, --profile <name> Local identity profile name (default: default)
|
|
60
|
+
--dir <path> Directory for identity files (default: ~/.dropspace)
|
|
61
|
+
--label <name> Device label
|
|
62
|
+
--json Output JSON
|
|
63
|
+
-h, --help Show this help
|
|
64
|
+
-v, --version Show CLI version
|
|
65
|
+
|
|
66
|
+
Command Options:
|
|
67
|
+
--ttl <seconds> Invite TTL in seconds (invite create)
|
|
68
|
+
--permissions <csv> Comma-separated permissions (e.g. chat,files,sync)
|
|
69
|
+
--to <deviceId> Target peer deviceId (send)
|
|
70
|
+
--via-hub <hubDeviceId> Hub deviceId to relay through (send)
|
|
71
|
+
--channel <name> Channel name (send, default: default)
|
|
72
|
+
--text <message> Plain text message (send)
|
|
73
|
+
--data <json> JSON payload string (send)
|
|
74
|
+
--auto-approve Automatically approve incoming pairing requests (listen)
|
|
75
|
+
`);
|
|
76
|
+
}
|
|
77
|
+
function resolveIdentityPath(dirOpt, profileOpt) {
|
|
78
|
+
const baseDir = dirOpt ? resolve(dirOpt) : join(homedir(), ".dropspace");
|
|
79
|
+
const safeProfile = (profileOpt || "default").replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
80
|
+
return join(baseDir, `${safeProfile}.json`);
|
|
81
|
+
}
|
|
82
|
+
function parsePermissions(raw) {
|
|
83
|
+
if (!raw)
|
|
84
|
+
return undefined;
|
|
85
|
+
const list = raw
|
|
86
|
+
.split(",")
|
|
87
|
+
.map((s) => s.trim())
|
|
88
|
+
.filter(Boolean);
|
|
89
|
+
return list.length > 0 ? list : undefined;
|
|
90
|
+
}
|
|
91
|
+
function createCliClient(opts) {
|
|
92
|
+
return new DropspaceClient({
|
|
93
|
+
baseUrl: opts.baseUrl,
|
|
94
|
+
appId: opts.appId,
|
|
95
|
+
deviceLabel: opts.label || `dropspace-cli (${hostname()})`,
|
|
96
|
+
identityStorage: new FileIdentityStorageAdapter(opts.identityPath),
|
|
97
|
+
webSocketFactory: nodeWebSocketFactory,
|
|
98
|
+
autoConnectTrustedPeers: false,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
async function run() {
|
|
102
|
+
const { values, positionals } = parseArgs({
|
|
103
|
+
args: process.argv.slice(2),
|
|
104
|
+
allowPositionals: true,
|
|
105
|
+
options: {
|
|
106
|
+
url: { type: "string", short: "u" },
|
|
107
|
+
app: { type: "string", short: "a" },
|
|
108
|
+
space: { type: "string", short: "s" },
|
|
109
|
+
profile: { type: "string", short: "p" },
|
|
110
|
+
dir: { type: "string" },
|
|
111
|
+
label: { type: "string" },
|
|
112
|
+
json: { type: "boolean", default: false },
|
|
113
|
+
help: { type: "boolean", short: "h", default: false },
|
|
114
|
+
version: { type: "boolean", short: "v", default: false },
|
|
115
|
+
ttl: { type: "string" },
|
|
116
|
+
permissions: { type: "string" },
|
|
117
|
+
to: { type: "string" },
|
|
118
|
+
"via-hub": { type: "string" },
|
|
119
|
+
channel: { type: "string" },
|
|
120
|
+
text: { type: "string" },
|
|
121
|
+
data: { type: "string" },
|
|
122
|
+
"auto-approve": { type: "boolean", default: false },
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
if (values.version) {
|
|
126
|
+
console.log(CLI_VERSION);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const cmd = positionals[0];
|
|
130
|
+
if (values.help || !cmd || cmd === "help") {
|
|
131
|
+
printHelp();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const baseUrl = (values.url || process.env.DROPSPACE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
135
|
+
const appId = values.app || process.env.DROPSPACE_APP_ID;
|
|
136
|
+
const spaceId = values.space || process.env.DROPSPACE_SPACE_ID;
|
|
137
|
+
const identityPath = resolveIdentityPath(values.dir, values.profile);
|
|
138
|
+
const asJson = Boolean(values.json);
|
|
139
|
+
if (cmd === "health") {
|
|
140
|
+
const healthRes = await fetch(`${baseUrl}/healthz`);
|
|
141
|
+
const healthText = await healthRes.text();
|
|
142
|
+
let healthBody = healthText;
|
|
143
|
+
try {
|
|
144
|
+
healthBody = JSON.parse(healthText);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// keep raw text
|
|
148
|
+
}
|
|
149
|
+
let configBody = null;
|
|
150
|
+
try {
|
|
151
|
+
const cfgRes = await fetch(`${baseUrl}/v1/config`);
|
|
152
|
+
if (cfgRes.ok) {
|
|
153
|
+
configBody = await cfgRes.json();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// optional
|
|
158
|
+
}
|
|
159
|
+
if (asJson) {
|
|
160
|
+
console.log(JSON.stringify({ baseUrl, ok: healthRes.ok, status: healthRes.status, health: healthBody, config: configBody }, null, 2));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.log(`Server: ${baseUrl}`);
|
|
164
|
+
console.log(`Health: ${healthRes.status} ${healthRes.ok ? "OK" : "FAIL"}`);
|
|
165
|
+
if (configBody && typeof configBody === "object") {
|
|
166
|
+
console.log(`Config: ${JSON.stringify(configBody)}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!healthRes.ok)
|
|
170
|
+
process.exitCode = 1;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (cmd === "identity") {
|
|
174
|
+
const sub = positionals[1] || "show";
|
|
175
|
+
const storage = new FileIdentityStorageAdapter(identityPath);
|
|
176
|
+
if (sub === "reset") {
|
|
177
|
+
await storage.clear();
|
|
178
|
+
if (asJson) {
|
|
179
|
+
console.log(JSON.stringify({ reset: true, path: identityPath }));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.log(`Cleared identity at ${identityPath}`);
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const id = await loadOrCreateDeviceIdentity({
|
|
187
|
+
storage,
|
|
188
|
+
deviceLabel: values.label || `dropspace-cli (${hostname()})`,
|
|
189
|
+
});
|
|
190
|
+
const out = {
|
|
191
|
+
deviceId: id.deviceId,
|
|
192
|
+
deviceLabel: id.deviceLabel,
|
|
193
|
+
algorithm: id.algorithm,
|
|
194
|
+
fingerprint: id.fingerprint,
|
|
195
|
+
path: identityPath,
|
|
196
|
+
};
|
|
197
|
+
if (asJson) {
|
|
198
|
+
console.log(JSON.stringify(out, null, 2));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
console.log(`Device ID: ${out.deviceId}`);
|
|
202
|
+
console.log(`Label: ${out.deviceLabel}`);
|
|
203
|
+
console.log(`Algorithm: ${out.algorithm}`);
|
|
204
|
+
console.log(`Fingerprint: ${out.fingerprint}`);
|
|
205
|
+
console.log(`Path: ${out.path}`);
|
|
206
|
+
}
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const client = createCliClient({
|
|
210
|
+
baseUrl,
|
|
211
|
+
appId,
|
|
212
|
+
label: values.label,
|
|
213
|
+
identityPath,
|
|
214
|
+
});
|
|
215
|
+
try {
|
|
216
|
+
await client.start();
|
|
217
|
+
const identity = client.getIdentity();
|
|
218
|
+
const session = client.getSessionInfo();
|
|
219
|
+
const activeSpaceId = spaceId || session.defaultSpaceId || undefined;
|
|
220
|
+
if (spaceId && spaceId !== session.defaultSpaceId) {
|
|
221
|
+
await client.devices.subscribeSpace(spaceId);
|
|
222
|
+
}
|
|
223
|
+
if (cmd === "invite") {
|
|
224
|
+
const sub = positionals[1];
|
|
225
|
+
if (sub === "create") {
|
|
226
|
+
const ttlSec = values.ttl ? Number(values.ttl) : undefined;
|
|
227
|
+
const invite = await client.pairing.createInvite({
|
|
228
|
+
spaceId: activeSpaceId,
|
|
229
|
+
ttlMs: ttlSec !== undefined && Number.isFinite(ttlSec) ? ttlSec * 1000 : undefined,
|
|
230
|
+
permissions: parsePermissions(values.permissions),
|
|
231
|
+
});
|
|
232
|
+
if (asJson) {
|
|
233
|
+
console.log(JSON.stringify(invite, null, 2));
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.log(`Space: ${invite.spaceId}`);
|
|
237
|
+
console.log(`Pairing ID: ${invite.pairingId}`);
|
|
238
|
+
console.log(`Token: ${invite.inviteToken}`);
|
|
239
|
+
console.log(`Deep Link: ${invite.deepLink}`);
|
|
240
|
+
console.log(`Expires At: ${new Date(invite.expiresAt).toISOString()}`);
|
|
241
|
+
}
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (sub === "claim") {
|
|
245
|
+
const tokenOrDeepLink = positionals[2];
|
|
246
|
+
if (!tokenOrDeepLink) {
|
|
247
|
+
throw new Error("Missing <tokenOrUrl>. Usage: dropspace invite claim <tokenOrUrl>");
|
|
248
|
+
}
|
|
249
|
+
const result = await client.pairing.claimInvite(tokenOrDeepLink);
|
|
250
|
+
if (asJson) {
|
|
251
|
+
console.log(JSON.stringify(result, null, 2));
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(`Claimed pairing ${result.pairingId} in space ${result.spaceId}`);
|
|
255
|
+
}
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
throw new Error(`Unknown invite subcommand '${sub ?? ""}'. Use 'invite create' or 'invite claim'.`);
|
|
259
|
+
}
|
|
260
|
+
if (cmd === "peers") {
|
|
261
|
+
if (!activeSpaceId) {
|
|
262
|
+
throw new Error("No spaceId available. Pass --space <spaceId>.");
|
|
263
|
+
}
|
|
264
|
+
const peers = client.devices.getPeers(activeSpaceId);
|
|
265
|
+
if (asJson) {
|
|
266
|
+
console.log(JSON.stringify({ spaceId: activeSpaceId, selfDeviceId: identity.deviceId, peers }, null, 2));
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.log(`Self: ${identity.deviceId}`);
|
|
270
|
+
console.log(`Space: ${activeSpaceId}`);
|
|
271
|
+
if (peers.length === 0) {
|
|
272
|
+
console.log("Peers: (none)");
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
for (const p of peers) {
|
|
276
|
+
const flags = [
|
|
277
|
+
p.online ? "online" : "offline",
|
|
278
|
+
p.capabilities.join(",") || "no-caps",
|
|
279
|
+
].join(", ");
|
|
280
|
+
console.log(`- ${p.deviceId} (${p.deviceLabel}) [${flags}]`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (cmd === "send") {
|
|
287
|
+
const to = values.to;
|
|
288
|
+
if (!to) {
|
|
289
|
+
throw new Error("Missing --to <peerDeviceId>.");
|
|
290
|
+
}
|
|
291
|
+
if (!values.text && !values.data) {
|
|
292
|
+
throw new Error("Provide either --text <message> or --data <json>.");
|
|
293
|
+
}
|
|
294
|
+
const viaHub = values["via-hub"];
|
|
295
|
+
if (!viaHub) {
|
|
296
|
+
throw new Error("Direct WebRTC from Node CLI requires a WebRTC peerConnectionFactory; pass --via-hub <hubDeviceId> to relay via a space hub.");
|
|
297
|
+
}
|
|
298
|
+
const payload = values.data
|
|
299
|
+
? JSON.parse(values.data)
|
|
300
|
+
: { text: values.text };
|
|
301
|
+
const receipt = await client.channels.sendJson(to, payload, {
|
|
302
|
+
channel: values.channel || "default",
|
|
303
|
+
viaHubDeviceId: viaHub,
|
|
304
|
+
});
|
|
305
|
+
if (asJson) {
|
|
306
|
+
console.log(JSON.stringify(receipt, null, 2));
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
console.log(`Sent message ${receipt.messageId} to ${to} via hub ${viaHub}`);
|
|
310
|
+
}
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (cmd === "listen") {
|
|
314
|
+
console.log(`Listening as ${identity.deviceId} in space ${activeSpaceId ?? "(none)"}...`);
|
|
315
|
+
client.events.on("presenceUpdate", ({ spaceId: sp, status, peer }) => {
|
|
316
|
+
if (asJson) {
|
|
317
|
+
console.log(JSON.stringify({ event: "presenceUpdate", spaceId: sp, status, peer }));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.log(`[presence] ${peer.deviceId} (${peer.deviceLabel}) -> ${status} in ${sp}`);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
client.events.on("pairingAwaitingApproval", (req) => {
|
|
324
|
+
if (asJson) {
|
|
325
|
+
console.log(JSON.stringify({ event: "pairingAwaitingApproval", request: req }));
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
console.log(`[pairing] ${req.claimerDeviceId} (${req.claimerLabel}) awaiting approval (${req.pairingId})`);
|
|
329
|
+
}
|
|
330
|
+
if (values["auto-approve"]) {
|
|
331
|
+
void client.pairing
|
|
332
|
+
.approve(req.pairingId)
|
|
333
|
+
.then(() => {
|
|
334
|
+
if (!asJson)
|
|
335
|
+
console.log(`[pairing] Auto-approved ${req.pairingId}`);
|
|
336
|
+
})
|
|
337
|
+
.catch((err) => {
|
|
338
|
+
console.error(`[pairing] Failed to approve ${req.pairingId}:`, err);
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
client.events.on("message", (msg) => {
|
|
343
|
+
if (asJson) {
|
|
344
|
+
console.log(JSON.stringify({ event: "message", ...msg }));
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
console.log(`[message] from ${msg.peerDeviceId} (${msg.channel}): ${JSON.stringify(msg.json ?? "<binary>")}`);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
await new Promise((resolve) => {
|
|
351
|
+
const stop = () => {
|
|
352
|
+
client.close();
|
|
353
|
+
resolve();
|
|
354
|
+
};
|
|
355
|
+
process.once("SIGINT", stop);
|
|
356
|
+
process.once("SIGTERM", stop);
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
throw new Error(`Unknown command '${cmd}'. Run 'dropspace --help' for usage.`);
|
|
361
|
+
}
|
|
362
|
+
finally {
|
|
363
|
+
if (cmd !== "listen") {
|
|
364
|
+
client.close();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
run().catch((err) => {
|
|
369
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
370
|
+
process.exitCode = 1;
|
|
371
|
+
});
|
|
372
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { WireFrameType, type AckSemantics, type WireFrameHeader, type DecodedWireFrame } from "../protocol/index.js";
|
|
2
|
+
import { TypedEventEmitter } from "./events.js";
|
|
3
|
+
export interface DataChannelLike {
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readyState: "connecting" | "open" | "closing" | "closed";
|
|
6
|
+
bufferedAmount: number;
|
|
7
|
+
bufferedAmountLowThreshold: number;
|
|
8
|
+
binaryType?: BinaryType;
|
|
9
|
+
send(data: Uint8Array | ArrayBuffer): void;
|
|
10
|
+
close(): void;
|
|
11
|
+
addEventListener(type: string, listener: (ev: any) => void): void;
|
|
12
|
+
removeEventListener(type: string, listener: (ev: any) => void): void;
|
|
13
|
+
}
|
|
14
|
+
export interface SendMessageOptions {
|
|
15
|
+
channel?: string;
|
|
16
|
+
messageId?: string;
|
|
17
|
+
ack?: AckSemantics | false;
|
|
18
|
+
ackTimeoutMs?: number;
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
viaHubDeviceId?: string;
|
|
23
|
+
spaceId?: string;
|
|
24
|
+
maxHops?: number;
|
|
25
|
+
meta?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface IncomingMessageEvent {
|
|
28
|
+
peerDeviceId: string;
|
|
29
|
+
channel: string;
|
|
30
|
+
messageId: string;
|
|
31
|
+
frameType: WireFrameType;
|
|
32
|
+
header: WireFrameHeader;
|
|
33
|
+
binary: Uint8Array;
|
|
34
|
+
json?: unknown;
|
|
35
|
+
routedViaHub?: string;
|
|
36
|
+
/** Call when using manual `persisted` or `processed` ACK semantics */
|
|
37
|
+
acknowledge(semantics?: AckSemantics): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
export declare class MessagingError extends Error {
|
|
40
|
+
readonly code: "QUEUE_OVERFLOW" | "CHANNEL_CLOSED" | "ABORTED" | "TIMEOUT" | "ACK_TIMEOUT" | "MESSAGE_TOO_LARGE" | "HUB_ROUTE_FAILED";
|
|
41
|
+
constructor(message: string, code: "QUEUE_OVERFLOW" | "CHANNEL_CLOSED" | "ABORTED" | "TIMEOUT" | "ACK_TIMEOUT" | "MESSAGE_TOO_LARGE" | "HUB_ROUTE_FAILED");
|
|
42
|
+
}
|
|
43
|
+
export type FramePriority = "high" | "interactive" | "bulk";
|
|
44
|
+
export interface ChannelMultiplexerOptions {
|
|
45
|
+
peerDeviceId: string;
|
|
46
|
+
localDeviceId: string;
|
|
47
|
+
maxFramePayloadBytes?: number;
|
|
48
|
+
maxTotalFrameBytes?: number;
|
|
49
|
+
bufferedAmountHighWaterMark?: number;
|
|
50
|
+
bufferedAmountLowWaterMark?: number;
|
|
51
|
+
maxSendQueueFrames?: number;
|
|
52
|
+
maxSendQueueBytes?: number;
|
|
53
|
+
maxReassemblyChunks?: number;
|
|
54
|
+
maxReassemblyBytes?: number;
|
|
55
|
+
reassemblyTimeoutMs?: number;
|
|
56
|
+
dedupWindowMs?: number;
|
|
57
|
+
maxDedupEntries?: number;
|
|
58
|
+
onRawFrame?: (frame: DecodedWireFrame) => void;
|
|
59
|
+
}
|
|
60
|
+
export type ChannelMultiplexerEvents = {
|
|
61
|
+
message: IncomingMessageEvent;
|
|
62
|
+
transferFrame: DecodedWireFrame;
|
|
63
|
+
crdtFrame: DecodedWireFrame;
|
|
64
|
+
hubRelayFrame: DecodedWireFrame;
|
|
65
|
+
backpressureChange: {
|
|
66
|
+
bufferedAmount: number;
|
|
67
|
+
queuedBytes: number;
|
|
68
|
+
paused: boolean;
|
|
69
|
+
};
|
|
70
|
+
error: Error;
|
|
71
|
+
close: void;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Reliable binary-first framing, chunking, backpressure queue, and optional application ACK engine
|
|
75
|
+
* over an underlying `RTCDataChannel` (Section 13).
|
|
76
|
+
*
|
|
77
|
+
* Important Transport Note:
|
|
78
|
+
* Even an ordered, reliable `RTCDataChannel` only guarantees SCTP in-order delivery within a single
|
|
79
|
+
* active transport association. Across reconnects or new `RTCPeerConnection` instances, in-flight
|
|
80
|
+
* SCTP packets can be lost or re-sent. Enable `ack: "received" | "persisted" | "processed"` when
|
|
81
|
+
* application-level delivery confirmation and deduplication across retries are required.
|
|
82
|
+
*/
|
|
83
|
+
export declare class PeerChannelMultiplexer {
|
|
84
|
+
private readonly options;
|
|
85
|
+
readonly events: TypedEventEmitter<ChannelMultiplexerEvents>;
|
|
86
|
+
private dataChannel;
|
|
87
|
+
private readonly maxFramePayloadBytes;
|
|
88
|
+
private maxTotalFrameBytes;
|
|
89
|
+
private readonly highWaterMark;
|
|
90
|
+
private readonly lowWaterMark;
|
|
91
|
+
private readonly maxQueueFrames;
|
|
92
|
+
private readonly maxQueueBytes;
|
|
93
|
+
private readonly maxReassemblyChunks;
|
|
94
|
+
private readonly maxReassemblyBytes;
|
|
95
|
+
private readonly reassemblyTimeoutMs;
|
|
96
|
+
private readonly dedupWindowMs;
|
|
97
|
+
private readonly maxDedupEntries;
|
|
98
|
+
private readonly highQueue;
|
|
99
|
+
private readonly interactiveQueue;
|
|
100
|
+
private readonly bulkQueue;
|
|
101
|
+
private queuedBytes;
|
|
102
|
+
private reassemblyBytes;
|
|
103
|
+
private isFlushing;
|
|
104
|
+
private backpressurePaused;
|
|
105
|
+
private closed;
|
|
106
|
+
private readonly pendingAcks;
|
|
107
|
+
private readonly seenMessageIds;
|
|
108
|
+
private readonly partialAssemblies;
|
|
109
|
+
private readonly boundOnMessage;
|
|
110
|
+
private readonly boundOnBufferedAmountLow;
|
|
111
|
+
private readonly boundOnClose;
|
|
112
|
+
constructor(options: ChannelMultiplexerOptions);
|
|
113
|
+
attachDataChannel(dc: DataChannelLike): void;
|
|
114
|
+
detachDataChannel(): void;
|
|
115
|
+
private get totalQueuedFrames();
|
|
116
|
+
setMaxTotalFrameBytes(limitBytes: number): void;
|
|
117
|
+
getMaxTotalFrameBytes(): number;
|
|
118
|
+
private getEffectiveChunkPayloadBytes;
|
|
119
|
+
getQueueMetrics(): {
|
|
120
|
+
queuedFrames: number;
|
|
121
|
+
queuedBytes: number;
|
|
122
|
+
bufferedAmount: number;
|
|
123
|
+
};
|
|
124
|
+
sendBinary(payload: Uint8Array, options?: SendMessageOptions): Promise<{
|
|
125
|
+
messageId: string;
|
|
126
|
+
ackSemantics?: AckSemantics;
|
|
127
|
+
}>;
|
|
128
|
+
sendJson(value: unknown, options?: SendMessageOptions): Promise<{
|
|
129
|
+
messageId: string;
|
|
130
|
+
ackSemantics?: AckSemantics;
|
|
131
|
+
}>;
|
|
132
|
+
private priorityForFrameType;
|
|
133
|
+
sendRawWireFrame(frameType: WireFrameType, header: WireFrameHeader, payload?: Uint8Array, signal?: AbortSignal): Promise<void>;
|
|
134
|
+
private sendInternal;
|
|
135
|
+
private waitForAck;
|
|
136
|
+
private queueForPriority;
|
|
137
|
+
private dequeueNextFrame;
|
|
138
|
+
private removeQueuedItem;
|
|
139
|
+
private enqueueEncodedFrame;
|
|
140
|
+
private flushQueue;
|
|
141
|
+
private waitForBufferDrain;
|
|
142
|
+
private handleIncomingRaw;
|
|
143
|
+
private handleControlFrame;
|
|
144
|
+
private prunePartialAssemblies;
|
|
145
|
+
private handleApplicationFrame;
|
|
146
|
+
deliverHubUnwrappedFrame(innerFrame: DecodedWireFrame, hubDeviceId: string): void;
|
|
147
|
+
private deliverReassembledMessage;
|
|
148
|
+
private pruneDeduplicationMap;
|
|
149
|
+
private rejectQueuedFrames;
|
|
150
|
+
close(): void;
|
|
151
|
+
dispose(): void;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/client/channel.ts"],"names":[],"mappings":"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"}
|