@antzsoft/chat-core 1.2.3 → 1.2.5

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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as ResolvedCompressionConfig, n as LoginCredentials, c as AuthResponse, S as RegisterData, d as AuthTokens, a2 as User, a as AppConfig, Y as SendMessagePayload, k as CursorPaginatedResponse, M as Message, P as PaginatedResponse, w as MessageReceiptsResponse, h as ConversationListParams, g as Conversation, D as Participant, j as ConversationUnreadCount, _ as UnreadSummary, a3 as UserPreferences, V as ResolvedConfig, E as PersistStorage, I as PresignedUrlRequest, J as PresignedUrlResponse, F as FileResponse, m as FileType, A as AntzChatConfig, a1 as UploadableFile, B as BatchUploadResult } from './storage-DO8QIqKq.cjs';
2
- export { b as Attachment, C as CompressedFile, e as CompressionAlgorithm, f as CompressionConfig, i as ConversationType, l as FileSizeLimits, L as LastReaction, o as MessageAckEvent, p as MessageContent, q as MessageDeletedEvent, r as MessageDeletedForMeEvent, s as MessageDeliveredEvent, t as MessageMetadata, u as MessageReaction, v as MessageReceiptEntry, x as MessageReplyReference, y as MessageUpdatedEvent, z as MessagesDeliveredEvent, N as NewMessageEvent, O as OptimisticAttachment, G as PlatformCompressFn, H as PlatformUploadFn, Q as QuietHours, R as ReactionUpdatedEvent, K as ReadReceiptEvent, T as ReplyAttachmentSnapshot, W as ResolvedFileSizeLimits, X as SendMessageAttachment, Z as TypingIndicatorEvent, $ as UploadConfig, a0 as UploadProgress, a4 as UserStatusEvent, a5 as resolveConfig, a6 as storageApi, a7 as uploadBatch } from './storage-DO8QIqKq.cjs';
1
+ import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, c as AppConfig, S as SendMessagePayload, C as CursorPaginatedResponse, M as Message, P as PaginatedResponse, d as MessageReceiptsResponse, e as ConversationListParams, f as Conversation, g as Participant, h as ConversationUnreadCount, i as UnreadSummary, j as UserPreferences, k as ResolvedConfig, l as PersistStorage, m as PresignedUrlRequest, n as PresignedUrlResponse, F as FileResponse, o as CompletedPart, p as FileType, q as AntzChatConfig, r as UploadableFile, B as BatchUploadResult } from './storage-CctLCOnZ.cjs';
2
+ export { s as Attachment, t as CompressedFile, u as CompressionAlgorithm, v as CompressionConfig, w as ConversationType, x as FileSizeLimits, y as LastReaction, z as MessageAckEvent, D as MessageContent, E as MessageDeletedEvent, G as MessageDeletedForMeEvent, H as MessageDeliveredEvent, I as MessageMetadata, J as MessageReaction, K as MessageReceiptEntry, N as MessageReplyReference, O as MessageUpdatedEvent, Q as MessagesDeliveredEvent, T as MultipartPartUrl, V as MultipartUploadInfo, W as NewMessageEvent, X as OptimisticAttachment, Y as PlatformCompressFn, Z as PlatformUploadFn, _ as PlatformUploadPartFn, $ as QuietHours, a0 as ReactionUpdatedEvent, a1 as ReadReceiptEvent, a2 as ReplyAttachmentSnapshot, a3 as ResolvedFileSizeLimits, a4 as SendMessageAttachment, a5 as SystemMessageMetadata, a6 as TypingIndicatorEvent, a7 as UploadConfig, a8 as UploadProgress, a9 as UserStatusEvent, aa as resolveConfig, ab as storageApi, ac as uploadBatch } from './storage-CctLCOnZ.cjs';
3
3
  import { AxiosInstance } from 'axios';
4
4
  import { Socket } from 'socket.io-client';
5
5
  import * as zustand_middleware from 'zustand/middleware';
@@ -286,6 +286,35 @@ interface TransitSession {
286
286
  enabled: boolean;
287
287
  }
288
288
  declare function setTransitSession(session: TransitSession): void;
289
+ declare function getSessionKey(): CryptoKey | Uint8Array | null;
290
+ declare function getSessionId(): string | null;
291
+
292
+ interface TransitEnvelope {
293
+ v: 1;
294
+ iv: string;
295
+ tag: string;
296
+ ct: string;
297
+ }
298
+ type AnySessionKey = CryptoKey | Uint8Array;
299
+ declare function encryptPayload(data: unknown, sessionKey: AnySessionKey): Promise<TransitEnvelope>;
300
+ declare function decryptPayload(envelope: TransitEnvelope, sessionKey: AnySessionKey): Promise<unknown>;
301
+ declare function isTransitEnvelope(v: unknown): v is TransitEnvelope;
302
+
303
+ interface ServerPublicKeys {
304
+ x25519: string;
305
+ p256: string;
306
+ enabled: boolean;
307
+ }
308
+ declare function fetchServerKeys(apiUrl: string): Promise<ServerPublicKeys>;
309
+ declare function generateEphemeralKey(algo: TransitAlgo, serverKeys: ServerPublicKeys): Promise<{
310
+ ephemeralPubB64: string;
311
+ deriveSessionKey: (sessionId: string) => Promise<unknown>;
312
+ }>;
313
+ declare function createRestTransitSession(apiUrl: string): Promise<{
314
+ sessionId: string;
315
+ sessionKey: CryptoKey | Uint8Array;
316
+ } | null>;
317
+ declare function performHandshake(algo: TransitAlgo, serverKeys: ServerPublicKeys, socketHandshakeAuth: Record<string, unknown>): Promise<(sessionId: string) => Promise<unknown>>;
289
318
 
290
319
  interface AuthState {
291
320
  user: User | null;
@@ -398,6 +427,8 @@ interface ChatState {
398
427
  isSidebarOpen: boolean;
399
428
  isGroupInfoOpen: boolean;
400
429
  isStarredPanelOpen: boolean;
430
+ /** messageId currently shown in the Message Info panel, null = closed */
431
+ messageInfoId: string | null;
401
432
  setActiveConversation: (id: string | null) => void;
402
433
  setPendingTarget: (target: {
403
434
  conversationId: string;
@@ -418,6 +449,7 @@ interface ChatState {
418
449
  setGroupInfoOpen: (open: boolean) => void;
419
450
  toggleStarredPanel: () => void;
420
451
  setStarredPanelOpen: (open: boolean) => void;
452
+ setMessageInfoId: (id: string | null) => void;
421
453
  }
422
454
  declare const useChatStore: zustand.UseBoundStore<zustand.StoreApi<ChatState>>;
423
455
 
@@ -530,6 +562,7 @@ declare class AntzChatClient {
530
562
  expiresAt: string;
531
563
  }>;
532
564
  deleteFile(fileId: string): Promise<void>;
565
+ completeMultipartUpload(fileId: string, uploadId: string, parts: CompletedPart[]): Promise<FileResponse>;
533
566
  getConversationFiles(conversationId: string, params?: {
534
567
  page?: number;
535
568
  limit?: number;
@@ -562,4 +595,4 @@ declare class AntzChatClient {
562
595
  uploadIcon(conversationId: string, file: UploadableFile): Promise<Conversation>;
563
596
  }
564
597
 
565
- export { AntzChatClient, AntzChatConfig, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, Conversation, ConversationListParams, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CursorPaginatedResponse, FileResponse, FileType, type LastReadEntry, type ListMessagesParams, LoginCredentials, Message, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getCompressionStrategy, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveSystemMessageText, setApiClientInstance, setTransitSession, socketEmit, tryGetSocket, useChatStore, usersApi };
598
+ export { AntzChatClient, AntzChatConfig, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CursorPaginatedResponse, FileResponse, FileType, type LastReadEntry, type ListMessagesParams, LoginCredentials, Message, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isTransitEnvelope, messagesApi, normalizeConversation, onSocketStatus, performHandshake, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveSystemMessageText, setApiClientInstance, setTransitSession, socketEmit, tryGetSocket, useChatStore, usersApi };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as ResolvedCompressionConfig, n as LoginCredentials, c as AuthResponse, S as RegisterData, d as AuthTokens, a2 as User, a as AppConfig, Y as SendMessagePayload, k as CursorPaginatedResponse, M as Message, P as PaginatedResponse, w as MessageReceiptsResponse, h as ConversationListParams, g as Conversation, D as Participant, j as ConversationUnreadCount, _ as UnreadSummary, a3 as UserPreferences, V as ResolvedConfig, E as PersistStorage, I as PresignedUrlRequest, J as PresignedUrlResponse, F as FileResponse, m as FileType, A as AntzChatConfig, a1 as UploadableFile, B as BatchUploadResult } from './storage-DO8QIqKq.js';
2
- export { b as Attachment, C as CompressedFile, e as CompressionAlgorithm, f as CompressionConfig, i as ConversationType, l as FileSizeLimits, L as LastReaction, o as MessageAckEvent, p as MessageContent, q as MessageDeletedEvent, r as MessageDeletedForMeEvent, s as MessageDeliveredEvent, t as MessageMetadata, u as MessageReaction, v as MessageReceiptEntry, x as MessageReplyReference, y as MessageUpdatedEvent, z as MessagesDeliveredEvent, N as NewMessageEvent, O as OptimisticAttachment, G as PlatformCompressFn, H as PlatformUploadFn, Q as QuietHours, R as ReactionUpdatedEvent, K as ReadReceiptEvent, T as ReplyAttachmentSnapshot, W as ResolvedFileSizeLimits, X as SendMessageAttachment, Z as TypingIndicatorEvent, $ as UploadConfig, a0 as UploadProgress, a4 as UserStatusEvent, a5 as resolveConfig, a6 as storageApi, a7 as uploadBatch } from './storage-DO8QIqKq.js';
1
+ import { R as ResolvedCompressionConfig, L as LoginCredentials, A as AuthResponse, a as RegisterData, b as AuthTokens, U as User, c as AppConfig, S as SendMessagePayload, C as CursorPaginatedResponse, M as Message, P as PaginatedResponse, d as MessageReceiptsResponse, e as ConversationListParams, f as Conversation, g as Participant, h as ConversationUnreadCount, i as UnreadSummary, j as UserPreferences, k as ResolvedConfig, l as PersistStorage, m as PresignedUrlRequest, n as PresignedUrlResponse, F as FileResponse, o as CompletedPart, p as FileType, q as AntzChatConfig, r as UploadableFile, B as BatchUploadResult } from './storage-CctLCOnZ.js';
2
+ export { s as Attachment, t as CompressedFile, u as CompressionAlgorithm, v as CompressionConfig, w as ConversationType, x as FileSizeLimits, y as LastReaction, z as MessageAckEvent, D as MessageContent, E as MessageDeletedEvent, G as MessageDeletedForMeEvent, H as MessageDeliveredEvent, I as MessageMetadata, J as MessageReaction, K as MessageReceiptEntry, N as MessageReplyReference, O as MessageUpdatedEvent, Q as MessagesDeliveredEvent, T as MultipartPartUrl, V as MultipartUploadInfo, W as NewMessageEvent, X as OptimisticAttachment, Y as PlatformCompressFn, Z as PlatformUploadFn, _ as PlatformUploadPartFn, $ as QuietHours, a0 as ReactionUpdatedEvent, a1 as ReadReceiptEvent, a2 as ReplyAttachmentSnapshot, a3 as ResolvedFileSizeLimits, a4 as SendMessageAttachment, a5 as SystemMessageMetadata, a6 as TypingIndicatorEvent, a7 as UploadConfig, a8 as UploadProgress, a9 as UserStatusEvent, aa as resolveConfig, ab as storageApi, ac as uploadBatch } from './storage-CctLCOnZ.js';
3
3
  import { AxiosInstance } from 'axios';
4
4
  import { Socket } from 'socket.io-client';
5
5
  import * as zustand_middleware from 'zustand/middleware';
@@ -286,6 +286,35 @@ interface TransitSession {
286
286
  enabled: boolean;
287
287
  }
288
288
  declare function setTransitSession(session: TransitSession): void;
289
+ declare function getSessionKey(): CryptoKey | Uint8Array | null;
290
+ declare function getSessionId(): string | null;
291
+
292
+ interface TransitEnvelope {
293
+ v: 1;
294
+ iv: string;
295
+ tag: string;
296
+ ct: string;
297
+ }
298
+ type AnySessionKey = CryptoKey | Uint8Array;
299
+ declare function encryptPayload(data: unknown, sessionKey: AnySessionKey): Promise<TransitEnvelope>;
300
+ declare function decryptPayload(envelope: TransitEnvelope, sessionKey: AnySessionKey): Promise<unknown>;
301
+ declare function isTransitEnvelope(v: unknown): v is TransitEnvelope;
302
+
303
+ interface ServerPublicKeys {
304
+ x25519: string;
305
+ p256: string;
306
+ enabled: boolean;
307
+ }
308
+ declare function fetchServerKeys(apiUrl: string): Promise<ServerPublicKeys>;
309
+ declare function generateEphemeralKey(algo: TransitAlgo, serverKeys: ServerPublicKeys): Promise<{
310
+ ephemeralPubB64: string;
311
+ deriveSessionKey: (sessionId: string) => Promise<unknown>;
312
+ }>;
313
+ declare function createRestTransitSession(apiUrl: string): Promise<{
314
+ sessionId: string;
315
+ sessionKey: CryptoKey | Uint8Array;
316
+ } | null>;
317
+ declare function performHandshake(algo: TransitAlgo, serverKeys: ServerPublicKeys, socketHandshakeAuth: Record<string, unknown>): Promise<(sessionId: string) => Promise<unknown>>;
289
318
 
290
319
  interface AuthState {
291
320
  user: User | null;
@@ -398,6 +427,8 @@ interface ChatState {
398
427
  isSidebarOpen: boolean;
399
428
  isGroupInfoOpen: boolean;
400
429
  isStarredPanelOpen: boolean;
430
+ /** messageId currently shown in the Message Info panel, null = closed */
431
+ messageInfoId: string | null;
401
432
  setActiveConversation: (id: string | null) => void;
402
433
  setPendingTarget: (target: {
403
434
  conversationId: string;
@@ -418,6 +449,7 @@ interface ChatState {
418
449
  setGroupInfoOpen: (open: boolean) => void;
419
450
  toggleStarredPanel: () => void;
420
451
  setStarredPanelOpen: (open: boolean) => void;
452
+ setMessageInfoId: (id: string | null) => void;
421
453
  }
422
454
  declare const useChatStore: zustand.UseBoundStore<zustand.StoreApi<ChatState>>;
423
455
 
@@ -530,6 +562,7 @@ declare class AntzChatClient {
530
562
  expiresAt: string;
531
563
  }>;
532
564
  deleteFile(fileId: string): Promise<void>;
565
+ completeMultipartUpload(fileId: string, uploadId: string, parts: CompletedPart[]): Promise<FileResponse>;
533
566
  getConversationFiles(conversationId: string, params?: {
534
567
  page?: number;
535
568
  limit?: number;
@@ -562,4 +595,4 @@ declare class AntzChatClient {
562
595
  uploadIcon(conversationId: string, file: UploadableFile): Promise<Conversation>;
563
596
  }
564
597
 
565
- export { AntzChatClient, AntzChatConfig, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, Conversation, ConversationListParams, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CursorPaginatedResponse, FileResponse, FileType, type LastReadEntry, type ListMessagesParams, LoginCredentials, Message, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getCompressionStrategy, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveSystemMessageText, setApiClientInstance, setTransitSession, socketEmit, tryGetSocket, useChatStore, usersApi };
598
+ export { AntzChatClient, AntzChatConfig, AppConfig, AuthResponse, AuthTokens, BatchUploadResult, CompletedPart, Conversation, ConversationListParams, ConversationUnreadCount, type CreateDirectData, type CreateGroupData, CursorPaginatedResponse, FileResponse, FileType, type LastReadEntry, type ListMessagesParams, LoginCredentials, Message, MessageReceiptsResponse, type MobileDeviceToken, PaginatedResponse, Participant, PersistStorage, PresignedUrlRequest, PresignedUrlResponse, RegisterData, type RegisterDeviceTokenPayload, ResolvedCompressionConfig, ResolvedConfig, type SearchParams, type SendData, SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, UnreadSummary, type UpdateConversationData, type UpdateProfilePayload, UploadableFile, User, UserPreferences, type WebPushDeviceToken, appConfigApi, authApi, connectSocket, conversationsApi, createAuthStore, createRestTransitSession, decryptPayload, devicesApi, disconnectSocket, encryptPayload, fetchServerKeys, generateEphemeralKey, getApiClient, getAuthStore, getCompressionStrategy, getSessionId, getSessionKey, getSocket, getSocketStatus, initApiClient, initAuthStore, isTransitEnvelope, messagesApi, normalizeConversation, onSocketStatus, performHandshake, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveSystemMessageText, setApiClientInstance, setTransitSession, socketEmit, tryGetSocket, useChatStore, usersApi };
package/dist/index.js CHANGED
@@ -1,22 +1,31 @@
1
1
  import {
2
2
  clearTransitSession,
3
3
  configureTransit,
4
+ createRestTransitSession,
4
5
  decryptPayload,
6
+ detectTransitAlgo,
5
7
  encryptPayload,
8
+ fetchServerKeys,
9
+ generateEphemeralKey,
6
10
  getApiClient,
7
11
  getCompressionStrategy,
12
+ getSessionId,
8
13
  getSessionKey,
14
+ getTransitHandshakePromise,
15
+ getTransitSession,
9
16
  initApiClient,
10
17
  isTransitEnabled,
11
18
  isTransitEnvelope,
19
+ performHandshake,
20
+ resetAlgoCache,
12
21
  setApiClientInstance,
13
22
  setTransitSession,
14
23
  storageApi,
15
24
  uploadBatch
16
- } from "./chunk-P7VAN6NA.js";
25
+ } from "./chunk-ZNA6B2R5.js";
17
26
  import {
18
27
  useChatStore
19
- } from "./chunk-GUO5QQGK.js";
28
+ } from "./chunk-EOL5B7GS.js";
20
29
 
21
30
  // src/config/types.ts
22
31
  function resolveConfig(config) {
@@ -63,6 +72,7 @@ function resolveConfig(config) {
63
72
  onProgress: config.upload?.onProgress
64
73
  },
65
74
  platformUploadFn: config.platformUploadFn,
75
+ platformUploadPartFn: config.platformUploadPartFn,
66
76
  platformCompressFn: config.platformCompressFn,
67
77
  compression: {
68
78
  enabled: config.compression?.enabled ?? config.platformCompressFn != null,
@@ -366,7 +376,7 @@ function normalizeLastMessage(lastMsg) {
366
376
  id: lastMsg.messageId ?? "",
367
377
  tenantId: "",
368
378
  conversationId: "",
369
- senderId: "",
379
+ senderId: lastMsg.senderId ?? "",
370
380
  content: {
371
381
  type: lastMsg.hasAttachments ? "attachment" : "text",
372
382
  text: lastMsg.contentPreview
@@ -377,7 +387,8 @@ function normalizeLastMessage(lastMsg) {
377
387
  isEdited: false,
378
388
  sentAt: lastMsg.sentAt ?? "",
379
389
  createdAt: lastMsg.sentAt ?? "",
380
- ...lastMsg.senderName && { senderName: lastMsg.senderName }
390
+ ...lastMsg.senderName && { senderName: lastMsg.senderName },
391
+ ...lastMsg.attachmentType && { attachmentType: lastMsg.attachmentType }
381
392
  };
382
393
  }
383
394
  function normalizeConversation(conv) {
@@ -567,122 +578,6 @@ var usersApi = {
567
578
 
568
579
  // src/socket/socket.ts
569
580
  import { io } from "socket.io-client";
570
-
571
- // src/crypto/detect.ts
572
- var _cached = null;
573
- async function detectTransitAlgo() {
574
- if (_cached) return _cached;
575
- try {
576
- await globalThis.crypto.subtle.generateKey(
577
- { name: "X25519" },
578
- false,
579
- ["deriveKey"]
580
- );
581
- _cached = "x25519";
582
- } catch {
583
- _cached = "p256";
584
- }
585
- return _cached;
586
- }
587
- function resetAlgoCache() {
588
- _cached = null;
589
- }
590
-
591
- // src/crypto/handshake.ts
592
- function hasWebCrypto() {
593
- return typeof globalThis.crypto?.subtle !== "undefined";
594
- }
595
- async function fetchServerKeys(apiUrl) {
596
- const res = await fetch(`${apiUrl}/crypto/pubkey`);
597
- if (!res.ok) throw new Error(`[AntzChat] Failed to fetch server public key: ${res.status}`);
598
- const body = await res.json();
599
- return body?.data ?? body;
600
- }
601
- async function performHandshake(algo, serverKeys, socketHandshakeAuth) {
602
- if (hasWebCrypto()) {
603
- return performWebCryptoHandshake(algo, serverKeys, socketHandshakeAuth);
604
- }
605
- return performNobleHandshake(serverKeys, socketHandshakeAuth);
606
- }
607
- async function performWebCryptoHandshake(algo, serverKeys, socketHandshakeAuth) {
608
- const ephemeral = await globalThis.crypto.subtle.generateKey(
609
- algo === "x25519" ? { name: "X25519" } : { name: "ECDH", namedCurve: "P-256" },
610
- false,
611
- ["deriveBits"]
612
- );
613
- const pubRaw = await globalThis.crypto.subtle.exportKey("raw", ephemeral.publicKey);
614
- socketHandshakeAuth["transitEphemeralPub"] = bufToB64(pubRaw);
615
- socketHandshakeAuth["transitAlgo"] = algo;
616
- const ephemeralPriv = ephemeral.privateKey;
617
- return (sessionId) => deriveWebCryptoSessionKey(ephemeralPriv, algo, serverKeys, sessionId);
618
- }
619
- async function deriveWebCryptoSessionKey(ephemeralPriv, algo, serverKeys, sessionId) {
620
- const serverPubRaw = b64ToBuf(algo === "x25519" ? serverKeys.x25519 : serverKeys.p256);
621
- const keyAlgoParams = algo === "x25519" ? { name: "X25519" } : { name: "ECDH", namedCurve: "P-256" };
622
- const serverPubKey = await globalThis.crypto.subtle.importKey("raw", serverPubRaw, keyAlgoParams, false, []);
623
- const sharedBits = await globalThis.crypto.subtle.deriveBits(
624
- { name: algo === "x25519" ? "X25519" : "ECDH", public: serverPubKey },
625
- ephemeralPriv,
626
- 256
627
- );
628
- const hkdfKey = await globalThis.crypto.subtle.importKey("raw", sharedBits, "HKDF", false, ["deriveKey"]);
629
- const salt = new TextEncoder().encode(sessionId);
630
- const info = new TextEncoder().encode("antz-transit-v1");
631
- return globalThis.crypto.subtle.deriveKey(
632
- { name: "HKDF", hash: "SHA-256", salt, info },
633
- hkdfKey,
634
- { name: "AES-GCM", length: 256 },
635
- false,
636
- ["encrypt", "decrypt"]
637
- );
638
- }
639
- async function performNobleHandshake(serverKeys, socketHandshakeAuth) {
640
- const { x25519 } = await import("@noble/curves/ed25519");
641
- const { hkdf } = await import("@noble/hashes/hkdf");
642
- const { sha256 } = await import("@noble/hashes/sha256");
643
- const { randomBytes } = await import("@noble/hashes/utils");
644
- const ephemeralPriv = randomBytes(32);
645
- const ephemeralPub = x25519.getPublicKey(ephemeralPriv);
646
- const serverPubBytes = base64ToUint8(serverKeys.x25519);
647
- socketHandshakeAuth["transitEphemeralPub"] = uint8ToBase64(ephemeralPub);
648
- socketHandshakeAuth["transitAlgo"] = "x25519";
649
- return (sessionId) => {
650
- const sharedSecret = x25519.getSharedSecret(ephemeralPriv, serverPubBytes);
651
- const salt = new TextEncoder().encode(sessionId);
652
- const info = new TextEncoder().encode("antz-transit-v1");
653
- const sessionKey = hkdf(sha256, sharedSecret, salt, info, 32);
654
- return Promise.resolve(sessionKey);
655
- };
656
- }
657
- function bufToB64(buf) {
658
- const bytes = new Uint8Array(buf);
659
- let str = "";
660
- bytes.forEach((b) => {
661
- str += String.fromCharCode(b);
662
- });
663
- return btoa(str);
664
- }
665
- function b64ToBuf(b64) {
666
- const bin = atob(b64);
667
- const buf = new Uint8Array(bin.length);
668
- for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
669
- return buf.buffer;
670
- }
671
- function uint8ToBase64(bytes) {
672
- let str = "";
673
- bytes.forEach((b) => {
674
- str += String.fromCharCode(b);
675
- });
676
- return btoa(str);
677
- }
678
- function base64ToUint8(b64) {
679
- const bin = atob(b64);
680
- const buf = new Uint8Array(bin.length);
681
- for (let i = 0; i < bin.length; i++) buf[i] = bin.charCodeAt(i);
682
- return buf;
683
- }
684
-
685
- // src/socket/socket.ts
686
581
  var _socket = null;
687
582
  var _socketProxy = null;
688
583
  var _connectingPromise = null;
@@ -779,17 +674,35 @@ async function _doConnect(config, getToken) {
779
674
  };
780
675
  let boundDeriveSessionKey = null;
781
676
  if (config.transitEncryption) {
782
- try {
783
- const serverKeys = await fetchServerKeys(config.apiUrl);
784
- if (!serverKeys.enabled) {
785
- throw new Error(
786
- "[AntzChat] Transit encryption mismatch: SDK has transitEncryption=true but server has TRANSIT_ENCRYPTION_ENABLED=false. Align the config on both sides."
787
- );
677
+ const inFlight = getTransitHandshakePromise();
678
+ if (inFlight) await inFlight;
679
+ const existingSession = getTransitSession();
680
+ let httpsSession = null;
681
+ if (existingSession?.enabled && existingSession.sessionId) {
682
+ httpsSession = { sessionId: existingSession.sessionId, sessionKey: existingSession.sessionKey };
683
+ } else {
684
+ httpsSession = await createRestTransitSession(config.apiUrl);
685
+ if (httpsSession) {
686
+ const algo = globalThis.crypto?.subtle ? await detectTransitAlgo() : "x25519";
687
+ setTransitSession({ sessionKey: httpsSession.sessionKey, algo, sessionId: httpsSession.sessionId, enabled: true });
688
+ }
689
+ }
690
+ if (httpsSession) {
691
+ socketHandshakeAuth["transitSessionId"] = httpsSession.sessionId;
692
+ boundDeriveSessionKey = null;
693
+ } else {
694
+ try {
695
+ const serverKeys = await fetchServerKeys(config.apiUrl);
696
+ if (!serverKeys.enabled) {
697
+ throw new Error(
698
+ "[AntzChat] Transit encryption mismatch: SDK has transitEncryption=true but server has TRANSIT_ENCRYPTION_ENABLED=false. Align the config on both sides."
699
+ );
700
+ }
701
+ const algo = globalThis.crypto?.subtle ? await detectTransitAlgo() : "x25519";
702
+ boundDeriveSessionKey = await performHandshake(algo, serverKeys, socketHandshakeAuth);
703
+ } catch (err) {
704
+ throw err;
788
705
  }
789
- const algo = globalThis.crypto?.subtle ? await detectTransitAlgo() : "x25519";
790
- boundDeriveSessionKey = await performHandshake(algo, serverKeys, socketHandshakeAuth);
791
- } catch (err) {
792
- throw err;
793
706
  }
794
707
  } else {
795
708
  try {
@@ -852,13 +765,13 @@ async function _doConnect(config, getToken) {
852
765
  });
853
766
  }
854
767
  secureOn(_socket, "read_receipt", (event) => {
855
- import("./chat.store-JC6QYDDL.js").then(({ useChatStore: useChatStore2 }) => {
768
+ import("./chat.store-DLNRJ5ZT.js").then(({ useChatStore: useChatStore2 }) => {
856
769
  const e = event;
857
770
  useChatStore2.getState().setLastRead(e.conversationId, e.messageId, e.readAt);
858
771
  });
859
772
  });
860
773
  secureOn(_socket, "user_online", (event) => {
861
- import("./chat.store-JC6QYDDL.js").then(({ useChatStore: useChatStore2 }) => {
774
+ import("./chat.store-DLNRJ5ZT.js").then(({ useChatStore: useChatStore2 }) => {
862
775
  const store = useChatStore2.getState();
863
776
  const e = event;
864
777
  store.setUserOnline(e.userId);
@@ -866,7 +779,7 @@ async function _doConnect(config, getToken) {
866
779
  });
867
780
  });
868
781
  secureOn(_socket, "user_offline", (event) => {
869
- import("./chat.store-JC6QYDDL.js").then(({ useChatStore: useChatStore2 }) => {
782
+ import("./chat.store-DLNRJ5ZT.js").then(({ useChatStore: useChatStore2 }) => {
870
783
  const e = event;
871
784
  const store = useChatStore2.getState();
872
785
  store.setUserOffline(e.userId);
@@ -947,11 +860,7 @@ async function drainSendQueue(conversationId) {
947
860
  entry.reject(new Error("[AntzChat] Message dropped: queued too long"));
948
861
  continue;
949
862
  }
950
- try {
951
- entry.resolve(await entry.run());
952
- } catch (e) {
953
- entry.reject(e);
954
- }
863
+ entry.run().then(entry.resolve).catch(entry.reject);
955
864
  }
956
865
  sendQueues.delete(conversationId);
957
866
  sendQueueRunning.delete(conversationId);
@@ -995,11 +904,13 @@ async function withAck(event, payload) {
995
904
  }
996
905
  if (!socket) return Promise.reject(new Error(`[AntzChat] Socket not connected (event: ${event})`));
997
906
  return new Promise((resolve, reject) => {
998
- const timer = setTimeout(() => reject(new Error(`Socket ack timeout: ${event}`)), ACK_TIMEOUT);
907
+ let timer;
999
908
  secureEmit(socket, event, payload, (response) => {
1000
909
  clearTimeout(timer);
1001
910
  resolve(response);
1002
- });
911
+ }).then(() => {
912
+ timer = setTimeout(() => reject(new Error(`Socket ack timeout: ${event}`)), ACK_TIMEOUT);
913
+ }).catch(reject);
1003
914
  });
1004
915
  }
1005
916
  function fireAndForget(event, payload) {
@@ -1049,7 +960,7 @@ var socketEmit = {
1049
960
  const socket = tryGetSocket();
1050
961
  if (!socket) return Promise.resolve([]);
1051
962
  return new Promise((resolve, reject) => {
1052
- const timer = setTimeout(() => reject(new Error("get_online_users timeout")), ACK_TIMEOUT);
963
+ let timer;
1053
964
  secureEmit(socket, "get_online_users", { userIds }, (response) => {
1054
965
  clearTimeout(timer);
1055
966
  if (response && typeof response === "object" && "onlineStatus" in response) {
@@ -1060,7 +971,9 @@ var socketEmit = {
1060
971
  } else {
1061
972
  resolve([]);
1062
973
  }
1063
- });
974
+ }).then(() => {
975
+ timer = setTimeout(() => reject(new Error("get_online_users timeout")), ACK_TIMEOUT);
976
+ }).catch(reject);
1064
977
  });
1065
978
  },
1066
979
  getTypingUsers(conversationId) {
@@ -1124,18 +1037,27 @@ export {
1124
1037
  connectSocket,
1125
1038
  conversationsApi,
1126
1039
  createAuthStore,
1040
+ createRestTransitSession,
1041
+ decryptPayload,
1127
1042
  devicesApi,
1128
1043
  disconnectSocket,
1044
+ encryptPayload,
1045
+ fetchServerKeys,
1046
+ generateEphemeralKey,
1129
1047
  getApiClient,
1130
1048
  getAuthStore,
1131
1049
  getCompressionStrategy,
1050
+ getSessionId,
1051
+ getSessionKey,
1132
1052
  getSocket,
1133
1053
  getSocketStatus,
1134
1054
  initApiClient,
1135
1055
  initAuthStore,
1056
+ isTransitEnvelope,
1136
1057
  messagesApi,
1137
1058
  normalizeConversation,
1138
1059
  onSocketStatus,
1060
+ performHandshake,
1139
1061
  reconnectSocket,
1140
1062
  refreshSocketAuth,
1141
1063
  resetAuthStore,