@vex-chat/libvex 1.0.1 → 1.1.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.
Files changed (60) hide show
  1. package/dist/Client.d.ts +25 -15
  2. package/dist/Client.js +210 -159
  3. package/dist/Client.js.map +1 -1
  4. package/dist/IStorage.d.ts +1 -1
  5. package/dist/IStorage.js +1 -1
  6. package/dist/IStorage.js.map +1 -1
  7. package/dist/__tests__/harness/memory-storage.d.ts +45 -0
  8. package/dist/__tests__/harness/memory-storage.js +181 -0
  9. package/dist/__tests__/harness/memory-storage.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/keystore/memory.d.ts +11 -0
  12. package/dist/keystore/memory.js +18 -0
  13. package/dist/keystore/memory.js.map +1 -0
  14. package/dist/keystore/node.d.ts +10 -0
  15. package/dist/keystore/node.js +64 -0
  16. package/dist/keystore/node.js.map +1 -0
  17. package/dist/keystore/types.d.ts +4 -0
  18. package/dist/keystore/types.js +2 -0
  19. package/dist/keystore/types.js.map +1 -0
  20. package/dist/preset/expo.d.ts +2 -0
  21. package/dist/preset/expo.js +39 -0
  22. package/dist/preset/expo.js.map +1 -0
  23. package/dist/preset/node.d.ts +12 -0
  24. package/dist/preset/node.js +17 -0
  25. package/dist/preset/node.js.map +1 -0
  26. package/dist/preset/tauri.d.ts +2 -0
  27. package/dist/preset/tauri.js +36 -0
  28. package/dist/preset/tauri.js.map +1 -0
  29. package/dist/preset/test.d.ts +10 -0
  30. package/dist/preset/test.js +29 -0
  31. package/dist/preset/test.js.map +1 -0
  32. package/dist/preset/types.d.ts +14 -0
  33. package/dist/preset/types.js +2 -0
  34. package/dist/preset/types.js.map +1 -0
  35. package/dist/storage/expo.d.ts +3 -0
  36. package/dist/storage/expo.js +18 -0
  37. package/dist/storage/expo.js.map +1 -0
  38. package/dist/storage/node.d.ts +3 -0
  39. package/dist/storage/node.js +24 -0
  40. package/dist/storage/node.js.map +1 -0
  41. package/dist/storage/schema.d.ts +76 -0
  42. package/dist/storage/schema.js +2 -0
  43. package/dist/storage/schema.js.map +1 -0
  44. package/dist/{Storage.d.ts → storage/sqlite.d.ts} +19 -21
  45. package/dist/storage/sqlite.js +488 -0
  46. package/dist/storage/sqlite.js.map +1 -0
  47. package/dist/storage/tauri.d.ts +3 -0
  48. package/dist/storage/tauri.js +21 -0
  49. package/dist/storage/tauri.js.map +1 -0
  50. package/dist/transport/browser.d.ts +17 -0
  51. package/dist/transport/browser.js +56 -0
  52. package/dist/transport/browser.js.map +1 -0
  53. package/dist/transport/types.d.ts +20 -0
  54. package/dist/transport/types.js +2 -0
  55. package/dist/transport/types.js.map +1 -0
  56. package/dist/utils/createLogger.js +1 -8
  57. package/dist/utils/createLogger.js.map +1 -1
  58. package/package.json +100 -16
  59. package/dist/Storage.js +0 -444
  60. package/dist/Storage.js.map +0 -1
@@ -0,0 +1,488 @@
1
+ /**
2
+ * Unified Kysely-based SQLite storage implementation.
3
+ *
4
+ * Accepts any `Kysely<ClientDatabase>` instance — the caller picks the
5
+ * dialect (better-sqlite3, Tauri plugin-sql, expo-sqlite, etc.) and
6
+ * passes the configured Kysely handle here.
7
+ *
8
+ * This replaces three separate storage classes (Storage.ts, TauriStorage,
9
+ * ExpoStorage) with a single implementation.
10
+ */
11
+ import { XKeyConvert, XUtils } from "@vex-chat/crypto";
12
+ import { EventEmitter } from "eventemitter3";
13
+ import nacl from "tweetnacl";
14
+ export class SqliteStorage extends EventEmitter {
15
+ ready = false;
16
+ closing = false;
17
+ db;
18
+ log;
19
+ idKeys;
20
+ constructor(db, SK, logger) {
21
+ super();
22
+ this.db = db;
23
+ this.log = logger;
24
+ const idKeys = XKeyConvert.convertKeyPair(nacl.sign.keyPair.fromSecretKey(XUtils.decodeHex(SK)));
25
+ if (!idKeys) {
26
+ throw new Error("Can't convert SK!");
27
+ }
28
+ this.idKeys = idKeys;
29
+ }
30
+ // ── Lifecycle ────────────────────────────────────────────────────────────
31
+ async init() {
32
+ this.log.info("Initializing database tables.");
33
+ try {
34
+ await this.db.schema
35
+ .createTable("messages")
36
+ .ifNotExists()
37
+ .addColumn("nonce", "text", (col) => col.primaryKey())
38
+ .addColumn("sender", "text")
39
+ .addColumn("recipient", "text")
40
+ .addColumn("group", "text")
41
+ .addColumn("mailID", "text")
42
+ .addColumn("message", "text")
43
+ .addColumn("direction", "text")
44
+ .addColumn("timestamp", "text")
45
+ .addColumn("decrypted", "integer")
46
+ .addColumn("forward", "integer")
47
+ .addColumn("authorID", "text")
48
+ .addColumn("readerID", "text")
49
+ .execute();
50
+ await this.db.schema
51
+ .createTable("devices")
52
+ .ifNotExists()
53
+ .addColumn("deviceID", "text", (col) => col.primaryKey())
54
+ .addColumn("owner", "text")
55
+ .addColumn("signKey", "text")
56
+ .addColumn("name", "text")
57
+ .addColumn("lastLogin", "text")
58
+ .addColumn("deleted", "integer")
59
+ .execute();
60
+ await this.db.schema
61
+ .createTable("sessions")
62
+ .ifNotExists()
63
+ .addColumn("sessionID", "text", (col) => col.primaryKey())
64
+ .addColumn("userID", "text")
65
+ .addColumn("deviceID", "text")
66
+ .addColumn("SK", "text", (col) => col.unique())
67
+ .addColumn("publicKey", "text")
68
+ .addColumn("fingerprint", "text")
69
+ .addColumn("mode", "text")
70
+ .addColumn("lastUsed", "text")
71
+ .addColumn("verified", "integer")
72
+ .execute();
73
+ await this.db.schema
74
+ .createTable("preKeys")
75
+ .ifNotExists()
76
+ .addColumn("index", "integer", (col) => col.primaryKey().autoIncrement())
77
+ .addColumn("keyID", "text", (col) => col.unique())
78
+ .addColumn("userID", "text")
79
+ .addColumn("deviceID", "text")
80
+ .addColumn("privateKey", "text")
81
+ .addColumn("publicKey", "text")
82
+ .addColumn("signature", "text")
83
+ .execute();
84
+ await this.db.schema
85
+ .createTable("oneTimeKeys")
86
+ .ifNotExists()
87
+ .addColumn("index", "integer", (col) => col.primaryKey().autoIncrement())
88
+ .addColumn("keyID", "text", (col) => col.unique())
89
+ .addColumn("userID", "text")
90
+ .addColumn("deviceID", "text")
91
+ .addColumn("privateKey", "text")
92
+ .addColumn("publicKey", "text")
93
+ .addColumn("signature", "text")
94
+ .execute();
95
+ this.ready = true;
96
+ this.emit("ready");
97
+ }
98
+ catch (err) {
99
+ this.emit("error", err);
100
+ }
101
+ }
102
+ async close() {
103
+ this.closing = true;
104
+ this.log.info("Closing database.");
105
+ await this.db.destroy();
106
+ }
107
+ // ── Messages ─────────────────────────────────────────────────────────────
108
+ async saveMessage(message) {
109
+ if (this.closing) {
110
+ this.log.warn("Database is closing, saveMessage() will not complete.");
111
+ return;
112
+ }
113
+ // Encrypt plaintext with our idkey before saving to disk
114
+ const encryptedMessage = XUtils.encodeHex(nacl.secretbox(XUtils.decodeUTF8(message.message), XUtils.decodeHex(message.nonce), this.idKeys.secretKey));
115
+ try {
116
+ await this.db
117
+ .insertInto("messages")
118
+ .values({
119
+ nonce: message.nonce,
120
+ sender: message.sender,
121
+ recipient: message.recipient,
122
+ group: message.group ?? null,
123
+ mailID: message.mailID,
124
+ message: encryptedMessage,
125
+ direction: message.direction,
126
+ timestamp: message.timestamp instanceof Date
127
+ ? message.timestamp.toISOString()
128
+ : String(message.timestamp),
129
+ decrypted: message.decrypted ? 1 : 0,
130
+ forward: message.forward ? 1 : 0,
131
+ authorID: message.authorID,
132
+ readerID: message.readerID,
133
+ })
134
+ .execute();
135
+ }
136
+ catch (err) {
137
+ if (this.closing)
138
+ return;
139
+ if (err?.errno === 19 || err?.message?.includes("UNIQUE")) {
140
+ this.log.warn("Duplicate nonce in message table.");
141
+ }
142
+ else {
143
+ throw err;
144
+ }
145
+ }
146
+ }
147
+ async deleteMessage(mailID) {
148
+ if (this.closing) {
149
+ this.log.warn("Database is closing, deleteMessage() will not complete.");
150
+ return;
151
+ }
152
+ await this.db
153
+ .deleteFrom("messages")
154
+ .where("mailID", "=", mailID)
155
+ .execute();
156
+ }
157
+ async getMessageHistory(userID) {
158
+ if (this.closing) {
159
+ this.log.warn("Database is closing, getMessageHistory() will not complete.");
160
+ return [];
161
+ }
162
+ const messages = await this.db
163
+ .selectFrom("messages")
164
+ .selectAll()
165
+ .where((eb) => eb.or([
166
+ eb.and([
167
+ eb("direction", "=", "incoming"),
168
+ eb("authorID", "=", userID),
169
+ eb("group", "is", null),
170
+ ]),
171
+ eb.and([
172
+ eb("direction", "=", "outgoing"),
173
+ eb("readerID", "=", userID),
174
+ eb("group", "is", null),
175
+ ]),
176
+ ]))
177
+ .orderBy("timestamp", "asc")
178
+ .execute();
179
+ return this.decryptMessages(messages);
180
+ }
181
+ async getGroupHistory(channelID) {
182
+ if (this.closing) {
183
+ this.log.warn("Database is closing, getGroupHistory() will not complete.");
184
+ return [];
185
+ }
186
+ const messages = await this.db
187
+ .selectFrom("messages")
188
+ .selectAll()
189
+ .where("group", "=", channelID)
190
+ .orderBy("timestamp", "asc")
191
+ .execute();
192
+ return this.decryptMessages(messages);
193
+ }
194
+ async deleteHistory(channelOrUserID, _olderThan) {
195
+ await this.db
196
+ .deleteFrom("messages")
197
+ .where((eb) => eb.or([
198
+ eb("group", "=", channelOrUserID),
199
+ eb.and([
200
+ eb("group", "is", null),
201
+ eb("authorID", "=", channelOrUserID),
202
+ ]),
203
+ eb.and([
204
+ eb("group", "is", null),
205
+ eb("readerID", "=", channelOrUserID),
206
+ ]),
207
+ ]))
208
+ .execute();
209
+ }
210
+ async purgeHistory() {
211
+ await this.db.deleteFrom("messages").execute();
212
+ }
213
+ // ── Sessions ─────────────────────────────────────────────────────────────
214
+ async markSessionVerified(sessionID) {
215
+ if (this.closing) {
216
+ this.log.warn("Database is closing, markSessionVerified() will not complete.");
217
+ return;
218
+ }
219
+ await this.db
220
+ .updateTable("sessions")
221
+ .set({ verified: 1 })
222
+ .where("sessionID", "=", sessionID)
223
+ .execute();
224
+ }
225
+ async markSessionUsed(sessionID) {
226
+ if (this.closing) {
227
+ this.log.warn("Database is closing, markSessionUsed() will not complete.");
228
+ return;
229
+ }
230
+ await this.db
231
+ .updateTable("sessions")
232
+ .set({ lastUsed: new Date(Date.now()).toISOString() })
233
+ .where("sessionID", "=", sessionID)
234
+ .execute();
235
+ }
236
+ async getSessionByPublicKey(publicKey) {
237
+ if (this.closing) {
238
+ this.log.warn("Database is closing, getSessionByPublicKey() will not complete.");
239
+ return null;
240
+ }
241
+ const hex = XUtils.encodeHex(publicKey);
242
+ const rows = await this.db
243
+ .selectFrom("sessions")
244
+ .selectAll()
245
+ .where("publicKey", "=", hex)
246
+ .limit(1)
247
+ .execute();
248
+ if (rows.length === 0) {
249
+ this.log.warn(`getSessionByPublicKey(${hex}) => ${JSON.stringify(null)}`);
250
+ return null;
251
+ }
252
+ return this.sqlToCrypto(rows[0]);
253
+ }
254
+ async getAllSessions() {
255
+ if (this.closing) {
256
+ this.log.warn("Database is closing, getAllSessions() will not complete.");
257
+ return [];
258
+ }
259
+ const rows = await this.db
260
+ .selectFrom("sessions")
261
+ .selectAll()
262
+ .orderBy("lastUsed", "desc")
263
+ .execute();
264
+ return rows.map((s) => ({
265
+ ...s,
266
+ verified: Boolean(s.verified),
267
+ }));
268
+ }
269
+ async getSessionByDeviceID(deviceID) {
270
+ if (this.closing) {
271
+ this.log.warn("Database is closing, getSessionByDeviceID() will not complete.");
272
+ return null;
273
+ }
274
+ const rows = await this.db
275
+ .selectFrom("sessions")
276
+ .selectAll()
277
+ .where("deviceID", "=", deviceID)
278
+ .orderBy("lastUsed", "desc")
279
+ .limit(1)
280
+ .execute();
281
+ if (rows.length === 0) {
282
+ this.log.debug("getSession() => " + JSON.stringify(null));
283
+ return null;
284
+ }
285
+ return this.sqlToCrypto(rows[0]);
286
+ }
287
+ async saveSession(session) {
288
+ if (this.closing) {
289
+ this.log.warn("Database is closing, saveSession() will not complete.");
290
+ return;
291
+ }
292
+ try {
293
+ await this.db
294
+ .insertInto("sessions")
295
+ .values({
296
+ sessionID: session.sessionID,
297
+ userID: session.userID,
298
+ deviceID: session.deviceID,
299
+ SK: session.SK,
300
+ publicKey: session.publicKey,
301
+ fingerprint: session.fingerprint,
302
+ mode: session.mode,
303
+ lastUsed: session.lastUsed instanceof Date
304
+ ? session.lastUsed.toISOString()
305
+ : String(session.lastUsed),
306
+ verified: session.verified ? 1 : 0,
307
+ })
308
+ .execute();
309
+ }
310
+ catch (err) {
311
+ if (err?.errno === 19 || err?.message?.includes("UNIQUE")) {
312
+ this.log.warn("Attempted to insert duplicate SK");
313
+ }
314
+ else {
315
+ throw err;
316
+ }
317
+ }
318
+ }
319
+ // ── PreKeys / OneTimeKeys ────────────────────────────────────────────────
320
+ async savePreKeys(preKeys, oneTime) {
321
+ await this.untilReady();
322
+ if (this.closing) {
323
+ this.log.warn("Database is closing, savePreKeys() will not complete.");
324
+ return [];
325
+ }
326
+ const table = oneTime ? "oneTimeKeys" : "preKeys";
327
+ const addedIndexes = [];
328
+ for (const preKey of preKeys) {
329
+ const result = await this.db
330
+ .insertInto(table)
331
+ .values({
332
+ privateKey: XUtils.encodeHex(preKey.keyPair.secretKey),
333
+ publicKey: XUtils.encodeHex(preKey.keyPair.publicKey),
334
+ signature: XUtils.encodeHex(preKey.signature),
335
+ })
336
+ .executeTakeFirst();
337
+ if (result.insertId !== undefined) {
338
+ addedIndexes.push(Number(result.insertId));
339
+ }
340
+ }
341
+ const rows = await this.db
342
+ .selectFrom(table)
343
+ .selectAll()
344
+ .where("index", "in", addedIndexes)
345
+ .execute();
346
+ return rows.map((key) => {
347
+ delete key.privateKey;
348
+ return key;
349
+ });
350
+ }
351
+ async getPreKeys() {
352
+ await this.untilReady();
353
+ if (this.closing) {
354
+ this.log.warn("Database is closing, getPreKeys() will not complete.");
355
+ return null;
356
+ }
357
+ const rows = await this.db.selectFrom("preKeys").selectAll().execute();
358
+ if (rows.length === 0) {
359
+ this.log.debug("getPreKeys() => " + JSON.stringify(null));
360
+ return null;
361
+ }
362
+ const preKeyInfo = rows[0];
363
+ return {
364
+ keyPair: nacl.box.keyPair.fromSecretKey(XUtils.decodeHex(preKeyInfo.privateKey)),
365
+ signature: XUtils.decodeHex(preKeyInfo.signature),
366
+ };
367
+ }
368
+ async getOneTimeKey(index) {
369
+ await this.untilReady();
370
+ if (this.closing) {
371
+ this.log.warn("Database is closing, getOneTimeKey() will not complete.");
372
+ return null;
373
+ }
374
+ const rows = await this.db
375
+ .selectFrom("oneTimeKeys")
376
+ .selectAll()
377
+ .where("index", "=", index)
378
+ .execute();
379
+ if (rows.length === 0) {
380
+ this.log.debug("getOneTimeKey() => " + JSON.stringify(null));
381
+ return null;
382
+ }
383
+ const otkInfo = rows[0];
384
+ return {
385
+ keyPair: nacl.box.keyPair.fromSecretKey(XUtils.decodeHex(otkInfo.privateKey)),
386
+ signature: XUtils.decodeHex(otkInfo.signature),
387
+ index: otkInfo.index,
388
+ };
389
+ }
390
+ async deleteOneTimeKey(index) {
391
+ if (this.closing) {
392
+ this.log.warn("Database is closing, deleteOneTimeKey() will not complete.");
393
+ return;
394
+ }
395
+ await this.db
396
+ .deleteFrom("oneTimeKeys")
397
+ .where("index", "=", index)
398
+ .execute();
399
+ }
400
+ // ── Devices ──────────────────────────────────────────────────────────────
401
+ async getDevice(deviceID) {
402
+ const rows = await this.db
403
+ .selectFrom("devices")
404
+ .selectAll()
405
+ .where("deviceID", "=", deviceID)
406
+ .execute();
407
+ if (rows.length === 0) {
408
+ return null;
409
+ }
410
+ return rows[0];
411
+ }
412
+ async saveDevice(device) {
413
+ if (this.closing) {
414
+ this.log.warn("Database is closing, saveDevice() will not complete.");
415
+ return;
416
+ }
417
+ try {
418
+ await this.db
419
+ .insertInto("devices")
420
+ .values({
421
+ deviceID: device.deviceID,
422
+ owner: device.owner,
423
+ signKey: device.signKey,
424
+ name: device.name,
425
+ lastLogin: device.lastLogin,
426
+ deleted: device.deleted ? 1 : 0,
427
+ })
428
+ .execute();
429
+ }
430
+ catch (err) {
431
+ if (err?.errno === 19 || err?.message?.includes("UNIQUE")) {
432
+ this.log.warn("Attempted to insert duplicate deviceID");
433
+ }
434
+ else {
435
+ throw err;
436
+ }
437
+ }
438
+ }
439
+ // ── Purge ────────────────────────────────────────────────────────────────
440
+ async purgeKeyData() {
441
+ await this.db.deleteFrom("sessions").execute();
442
+ await this.db.deleteFrom("oneTimeKeys").execute();
443
+ await this.db.deleteFrom("preKeys").execute();
444
+ await this.db.deleteFrom("messages").execute();
445
+ }
446
+ // ── Private helpers ──────────────────────────────────────────────────────
447
+ decryptMessages(messages) {
448
+ return messages.map((msg) => {
449
+ msg.timestamp = new Date(msg.timestamp);
450
+ msg.decrypted = Boolean(msg.decrypted);
451
+ msg.forward = Boolean(msg.forward);
452
+ if (msg.decrypted) {
453
+ const decrypted = nacl.secretbox.open(XUtils.decodeHex(msg.message), XUtils.decodeHex(msg.nonce), this.idKeys.secretKey);
454
+ if (decrypted) {
455
+ msg.message = XUtils.encodeUTF8(decrypted);
456
+ }
457
+ else {
458
+ throw new Error("Couldn't decrypt messages on disk!");
459
+ }
460
+ }
461
+ return msg;
462
+ });
463
+ }
464
+ sqlToCrypto(session) {
465
+ return {
466
+ sessionID: session.sessionID,
467
+ userID: session.userID,
468
+ mode: session.mode,
469
+ SK: XUtils.decodeHex(session.SK),
470
+ publicKey: XUtils.decodeHex(session.publicKey),
471
+ lastUsed: session.lastUsed,
472
+ fingerprint: XUtils.decodeHex(session.fingerprint),
473
+ };
474
+ }
475
+ async untilReady() {
476
+ if (this.ready)
477
+ return;
478
+ return new Promise((resolve) => {
479
+ const check = () => {
480
+ if (this.ready)
481
+ return resolve();
482
+ setTimeout(check, 10);
483
+ };
484
+ check();
485
+ });
486
+ }
487
+ }
488
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { IStorage } from "../IStorage.js";
2
+ import type { ILogger } from "../transport/types.js";
3
+ export declare function createTauriStorage(dbName: string, SK: string, logger: ILogger): Promise<IStorage>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Tauri storage factory — creates SqliteStorage with kysely-dialect-tauri.
3
+ *
4
+ * @tauri-apps/plugin-sql and kysely-dialect-tauri are peerDependencies —
5
+ * only available inside a Tauri app.
6
+ */
7
+ import { Kysely } from "kysely";
8
+ import { SqliteStorage } from "./sqlite.js";
9
+ export async function createTauriStorage(dbName, SK, logger) {
10
+ const { TauriSqliteDialect } = await import("kysely-dialect-tauri");
11
+ const { default: Database } = await import("@tauri-apps/plugin-sql");
12
+ const db = new Kysely({
13
+ dialect: new TauriSqliteDialect({
14
+ database: () => Database.load(`sqlite:${dbName}`),
15
+ }),
16
+ });
17
+ const storage = new SqliteStorage(db, SK, logger);
18
+ await storage.init();
19
+ return storage;
20
+ }
21
+ //# sourceMappingURL=tauri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.js","sourceRoot":"","sources":["../../src/storage/tauri.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,MAAc,EACd,EAAU,EACV,MAAe;IAEf,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACpE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACrE,MAAM,EAAE,GAAG,IAAI,MAAM,CAAiB;QAClC,OAAO,EAAE,IAAI,kBAAkB,CAAC;YAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;SACpD,CAAQ;KACZ,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACrB,OAAO,OAAO,CAAC;AACnB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Wraps the browser's native WebSocket to match the IWebSocketLike interface
3
+ * expected by Client. Used by Tauri (webview) and future web builds.
4
+ */
5
+ import type { IWebSocketLike } from "./types.js";
6
+ export declare class BrowserWebSocket implements IWebSocketLike {
7
+ private ws;
8
+ private listeners;
9
+ onerror: ((err: any) => void) | null;
10
+ constructor(url: string, _options?: object);
11
+ get readyState(): 0 | 1 | 2 | 3;
12
+ on(event: string, listener: (...args: any[]) => void): void;
13
+ off(event: string, listener: (...args: any[]) => void): void;
14
+ send(data: any): void;
15
+ close(): void;
16
+ terminate(): void;
17
+ }
@@ -0,0 +1,56 @@
1
+ export class BrowserWebSocket {
2
+ ws;
3
+ listeners = new Map();
4
+ onerror = null;
5
+ constructor(url, _options) {
6
+ this.ws = new globalThis.WebSocket(url);
7
+ this.ws.binaryType = "arraybuffer";
8
+ this.ws.onerror = (ev) => this.onerror?.(ev);
9
+ }
10
+ get readyState() {
11
+ return this.ws.readyState;
12
+ }
13
+ on(event, listener) {
14
+ let wrapped;
15
+ if (event === "message") {
16
+ // Browser WebSocket wraps data in MessageEvent — unwrap to Uint8Array
17
+ wrapped = (ev) => {
18
+ const data = ev.data;
19
+ if (data instanceof ArrayBuffer) {
20
+ listener(new Uint8Array(data));
21
+ }
22
+ else {
23
+ listener(data);
24
+ }
25
+ };
26
+ }
27
+ else if (event === "open" || event === "close" || event === "error") {
28
+ wrapped = () => listener();
29
+ }
30
+ else {
31
+ wrapped = (ev) => listener(ev);
32
+ }
33
+ if (!this.listeners.has(event)) {
34
+ this.listeners.set(event, new Map());
35
+ }
36
+ this.listeners.get(event).set(listener, wrapped);
37
+ this.ws.addEventListener(event, wrapped);
38
+ }
39
+ off(event, listener) {
40
+ const wrapped = this.listeners.get(event)?.get(listener);
41
+ if (wrapped) {
42
+ this.ws.removeEventListener(event, wrapped);
43
+ this.listeners.get(event).delete(listener);
44
+ }
45
+ }
46
+ send(data) {
47
+ this.ws.send(data);
48
+ }
49
+ close() {
50
+ this.ws.close();
51
+ }
52
+ terminate() {
53
+ this.ws.close();
54
+ }
55
+ }
56
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/transport/browser.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,gBAAgB;IACjB,EAAE,CAAY;IACd,SAAS,GAAG,IAAI,GAAG,EAA4C,CAAC;IACxE,OAAO,GAAgC,IAAI,CAAC;IAE5C,YAAY,GAAW,EAAE,QAAiB;QACtC,IAAI,CAAC,EAAE,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,UAAU,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED,EAAE,CAAC,KAAa,EAAE,QAAkC;QAChD,IAAI,OAA0B,CAAC;QAE/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,sEAAsE;YACtE,OAAO,GAAG,CAAC,EAAS,EAAE,EAAE;gBACpB,MAAM,IAAI,GAAI,EAAmB,CAAC,IAAI,CAAC;gBACvC,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;oBAC9B,QAAQ,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnC,CAAC;qBAAM,CAAC;oBACJ,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC;YACL,CAAC,CAAC;QACN,CAAC;aAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACpE,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACJ,OAAO,GAAG,CAAC,EAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,QAAkC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAc,CAAC,CAAC;YACnD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAS;QACV,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,KAAK;QACD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,SAAS;QACL,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;CACJ"}
@@ -0,0 +1,20 @@
1
+ export interface ILogger {
2
+ info(message: string, ...args: any[]): void;
3
+ warn(message: string, ...args: any[]): void;
4
+ error(message: string, ...args: any[]): void;
5
+ debug(message: string, ...args: any[]): void;
6
+ }
7
+ export type IWebSocketCtor = new (url: string, options?: object) => IWebSocketLike;
8
+ export interface IWebSocketLike {
9
+ on(event: string, listener: (...args: any[]) => void): void;
10
+ off(event: string, listener: (...args: any[]) => void): void;
11
+ send(data: any): void;
12
+ close(): void;
13
+ terminate?(): void;
14
+ onerror: ((err: any) => void) | null;
15
+ readyState: number;
16
+ }
17
+ export interface IClientAdapters {
18
+ logger: ILogger;
19
+ WebSocket: IWebSocketCtor;
20
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":""}