@antzsoft/chat-core 1.0.6 → 1.0.8
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 +200 -3
- package/dist/index.cjs +98 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -6
- package/dist/index.d.ts +63 -6
- package/dist/index.js +97 -7
- package/dist/index.js.map +1 -1
- package/docs/integration-guide.html +456 -9
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -128,7 +128,14 @@ interface Message {
|
|
|
128
128
|
sentAt: string;
|
|
129
129
|
createdAt: string;
|
|
130
130
|
sender?: User;
|
|
131
|
-
readBy?:
|
|
131
|
+
readBy?: Array<{
|
|
132
|
+
userId: string;
|
|
133
|
+
readAt: string;
|
|
134
|
+
}>;
|
|
135
|
+
deliveredTo?: Array<{
|
|
136
|
+
userId: string;
|
|
137
|
+
deliveredAt: string;
|
|
138
|
+
}>;
|
|
132
139
|
isEncrypted?: boolean;
|
|
133
140
|
encryptionMode?: EncryptionMode;
|
|
134
141
|
encryptedContent?: EncryptedContent;
|
|
@@ -225,6 +232,12 @@ interface CursorPaginatedResponse<T> {
|
|
|
225
232
|
data: T[];
|
|
226
233
|
meta: CursorPaginationMeta;
|
|
227
234
|
}
|
|
235
|
+
type CompressionAlgorithm = 'webp' | 'jpeg' | 'gzip' | 'none';
|
|
236
|
+
interface CompressedFile extends UploadableFile {
|
|
237
|
+
originalSize: number;
|
|
238
|
+
compressed: boolean;
|
|
239
|
+
compressionAlgorithm: CompressionAlgorithm;
|
|
240
|
+
}
|
|
228
241
|
interface PresignedUrlRequest {
|
|
229
242
|
filename: string;
|
|
230
243
|
mimeType: string;
|
|
@@ -322,7 +335,10 @@ interface MessageAckEvent {
|
|
|
322
335
|
interface MessageDeliveredEvent {
|
|
323
336
|
messageId: string;
|
|
324
337
|
conversationId: string;
|
|
325
|
-
|
|
338
|
+
deliveredTo: Array<{
|
|
339
|
+
userId: string;
|
|
340
|
+
deliveredAt: Date;
|
|
341
|
+
}>;
|
|
326
342
|
}
|
|
327
343
|
interface MessagesDeliveredEvent {
|
|
328
344
|
conversationId: string;
|
|
@@ -338,6 +354,7 @@ interface SendMessageAttachment {
|
|
|
338
354
|
filename: string;
|
|
339
355
|
mimeType: string;
|
|
340
356
|
size: number;
|
|
357
|
+
duration?: number;
|
|
341
358
|
}
|
|
342
359
|
interface OptimisticAttachment extends SendMessageAttachment {
|
|
343
360
|
id: string;
|
|
@@ -415,6 +432,29 @@ interface PersistStorage {
|
|
|
415
432
|
setItem(key: string, value: string): void | Promise<void>;
|
|
416
433
|
removeItem(key: string): void | Promise<void>;
|
|
417
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Platform-provided compression function. Optional — if omitted, files are uploaded as-is.
|
|
437
|
+
* - Web: uses canvas (images) + CompressionStream (text/docs) — both browser-native
|
|
438
|
+
* - RN: uses expo-image-manipulator (images) + pako (text/docs)
|
|
439
|
+
* - Node: uses sharp (images) + zlib (text/docs)
|
|
440
|
+
*/
|
|
441
|
+
type PlatformCompressFn = (file: UploadableFile, options: ResolvedCompressionConfig) => Promise<CompressedFile>;
|
|
442
|
+
interface CompressionConfig {
|
|
443
|
+
/** Master switch. Default: true when platformCompressFn is provided, false otherwise */
|
|
444
|
+
enabled?: boolean;
|
|
445
|
+
/** WebP quality for images, 0–1. Default: 0.85 */
|
|
446
|
+
imageQuality?: number;
|
|
447
|
+
/** Longest side cap in px before encoding. Default: 1920 */
|
|
448
|
+
imageMaxDimension?: number;
|
|
449
|
+
/** Gzip text-based documents (plain, csv, json, xml, yaml, svg). Default: true */
|
|
450
|
+
compressDocuments?: boolean;
|
|
451
|
+
}
|
|
452
|
+
interface ResolvedCompressionConfig {
|
|
453
|
+
enabled: boolean;
|
|
454
|
+
imageQuality: number;
|
|
455
|
+
imageMaxDimension: number;
|
|
456
|
+
compressDocuments: boolean;
|
|
457
|
+
}
|
|
418
458
|
interface UploadConfig {
|
|
419
459
|
/**
|
|
420
460
|
* Per-type file size limits in MB. Can also pass a single number for all types.
|
|
@@ -469,6 +509,15 @@ interface AntzChatConfig {
|
|
|
469
509
|
/** Must match server ENCRYPTION_MODE env var. Default: 'none' */
|
|
470
510
|
encryptionMode?: 'none' | 'server';
|
|
471
511
|
upload?: UploadConfig;
|
|
512
|
+
/**
|
|
513
|
+
* Optional compression config. Compression is disabled if platformCompressFn is not provided.
|
|
514
|
+
*/
|
|
515
|
+
compression?: CompressionConfig;
|
|
516
|
+
/**
|
|
517
|
+
* Platform-specific compression implementation. Optional — omit to disable compression.
|
|
518
|
+
* Each SDK (web, RN) provides its own default; Node.js users wire in their own.
|
|
519
|
+
*/
|
|
520
|
+
platformCompressFn?: PlatformCompressFn;
|
|
472
521
|
/**
|
|
473
522
|
* Number of messages fetched per page when loading chat history.
|
|
474
523
|
* Default: 40
|
|
@@ -524,6 +573,8 @@ interface ResolvedConfig {
|
|
|
524
573
|
onProgress?: (progress: number) => void;
|
|
525
574
|
};
|
|
526
575
|
platformUploadFn: PlatformUploadFn;
|
|
576
|
+
platformCompressFn?: PlatformCompressFn;
|
|
577
|
+
compression: ResolvedCompressionConfig;
|
|
527
578
|
persistStorage: PersistStorage;
|
|
528
579
|
messagePageSize: number;
|
|
529
580
|
starredMessagePageSize: number;
|
|
@@ -531,6 +582,9 @@ interface ResolvedConfig {
|
|
|
531
582
|
}
|
|
532
583
|
declare function resolveConfig(config: AntzChatConfig): ResolvedConfig;
|
|
533
584
|
|
|
585
|
+
type CompressionStrategy = 'image' | 'gzip' | 'skip';
|
|
586
|
+
declare function getCompressionStrategy(mimeType: string, config: ResolvedCompressionConfig): CompressionStrategy;
|
|
587
|
+
|
|
534
588
|
declare const authApi: {
|
|
535
589
|
login(credentials: LoginCredentials): Promise<AuthResponse>;
|
|
536
590
|
register(payload: RegisterData): Promise<AuthResponse>;
|
|
@@ -622,7 +676,7 @@ declare const conversationsApi: {
|
|
|
622
676
|
pin(conversationId: string): Promise<void>;
|
|
623
677
|
unpin(conversationId: string): Promise<void>;
|
|
624
678
|
leave(conversationId: string): Promise<void>;
|
|
625
|
-
getMembers(conversationId: string): Promise<
|
|
679
|
+
getMembers(conversationId: string, filter?: "deleted" | "all"): Promise<Participant[]>;
|
|
626
680
|
/**
|
|
627
681
|
* Get unread message count for a single conversation.
|
|
628
682
|
* Use this after app foreground or socket reconnect to refresh a specific count.
|
|
@@ -673,8 +727,11 @@ declare const storageApi: {
|
|
|
673
727
|
* High-level batch upload.
|
|
674
728
|
* The actual binary transfer is delegated to platformUploadFn so this
|
|
675
729
|
* function is platform-agnostic (works on web and React Native).
|
|
730
|
+
* If platformCompressFn + compressionConfig are provided, each file is
|
|
731
|
+
* compressed before the presigned URL is requested (so the server receives
|
|
732
|
+
* the correct compressed size and MIME type).
|
|
676
733
|
*/
|
|
677
|
-
declare function uploadBatch(files: UploadableFile[], platformUploadFn: PlatformUploadFn, conversationId?: string, onProgress?: (pct: number) => void): Promise<BatchUploadResult>;
|
|
734
|
+
declare function uploadBatch(files: UploadableFile[], platformUploadFn: PlatformUploadFn, conversationId?: string, onProgress?: (pct: number) => void, platformCompressFn?: PlatformCompressFn, compressionConfig?: ResolvedCompressionConfig): Promise<BatchUploadResult>;
|
|
678
735
|
|
|
679
736
|
/** Shared fields for every device registration. */
|
|
680
737
|
interface DeviceTokenBase {
|
|
@@ -1006,7 +1063,7 @@ declare class AntzChatClient {
|
|
|
1006
1063
|
pin(conversationId: string): Promise<void>;
|
|
1007
1064
|
unpin(conversationId: string): Promise<void>;
|
|
1008
1065
|
leave(conversationId: string): Promise<void>;
|
|
1009
|
-
getMembers(conversationId: string): Promise<
|
|
1066
|
+
getMembers(conversationId: string, filter?: "deleted" | "all"): Promise<Participant[]>;
|
|
1010
1067
|
getUnreadCount(conversationId: string): Promise<ConversationUnreadCount>;
|
|
1011
1068
|
getUnreadSummary(): Promise<UnreadSummary>;
|
|
1012
1069
|
uploadIcon(conversationId: string, fileId: string): Promise<Conversation>;
|
|
@@ -1058,4 +1115,4 @@ declare class AntzChatClient {
|
|
|
1058
1115
|
uploadIcon(conversationId: string, file: UploadableFile): Promise<Conversation>;
|
|
1059
1116
|
}
|
|
1060
1117
|
|
|
1061
|
-
export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type Conversation, type ConversationListParams, type ConversationUnreadCount, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type LastReadEntry, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type QuietHours, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UnreadSummary, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserPreferences, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore, usersApi };
|
|
1118
|
+
export { AntzChatClient, type AntzChatConfig, type Attachment, type AuthResponse, type AuthTokens, type BatchUploadResult, type CompressedFile, type CompressionAlgorithm, type CompressionConfig, type Conversation, type ConversationListParams, type ConversationUnreadCount, type CreateDirectData, type CreateGroupData, type CursorPaginatedResponse, type EncryptedContent, type EncryptionKeyInfo, type EncryptionMode, type FileResponse, type FileSizeLimits, type FileType, type LastReadEntry, type ListMessagesParams, type LoginCredentials, type Message, type MessageAckEvent, type MessageContent, type MessageDeletedEvent, type MessageDeletedForMeEvent, type MessageDeliveredEvent, type MessageReaction, type MessageReplyReference, type MessageUpdatedEvent, type MessagesDeliveredEvent, type MobileDeviceToken, type NewMessageEvent, type OptimisticAttachment, type PaginatedResponse, type Participant, type PersistStorage, type PlatformCompressFn, type PlatformUploadFn, type PresignedUrlRequest, type PresignedUrlResponse, type QuietHours, type ReactionUpdatedEvent, type ReadReceiptEvent, type RegisterData, type RegisterDeviceTokenPayload, type ResolvedCompressionConfig, type ResolvedConfig, type ResolvedFileSizeLimits, type SearchParams, type SendData, type SendMessageAttachment, type SendMessagePayload, type SocketStatus, type StatusListener, type TokenStore, type TypingIndicatorEvent, type UnreadSummary, type UpdateConversationData, type UploadConfig, type UploadProgress, type UploadableFile, type User, type UserPreferences, type UserStatusEvent, type WebPushDeviceToken, authApi, connectSocket, conversationsApi, createAuthStore, devicesApi, disconnectSocket, getApiClient, getAuthStore, getCompressionStrategy, getSocket, getSocketStatus, initApiClient, initAuthStore, messagesApi, normalizeConversation, onSocketStatus, reconnectSocket, refreshSocketAuth, resetAuthStore, resolveConfig, setApiClientInstance, socketEmit, storageApi, tryGetSocket, uploadBatch, useChatStore, usersApi };
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,13 @@ function resolveConfig(config) {
|
|
|
47
47
|
onProgress: config.upload?.onProgress
|
|
48
48
|
},
|
|
49
49
|
platformUploadFn: config.platformUploadFn,
|
|
50
|
+
platformCompressFn: config.platformCompressFn,
|
|
51
|
+
compression: {
|
|
52
|
+
enabled: config.compression?.enabled ?? config.platformCompressFn != null,
|
|
53
|
+
imageQuality: config.compression?.imageQuality ?? 0.85,
|
|
54
|
+
imageMaxDimension: config.compression?.imageMaxDimension ?? 1920,
|
|
55
|
+
compressDocuments: config.compression?.compressDocuments ?? true
|
|
56
|
+
},
|
|
50
57
|
persistStorage: config.persistStorage,
|
|
51
58
|
messagePageSize: config.messagePageSize ?? 40,
|
|
52
59
|
starredMessagePageSize: config.starredMessagePageSize ?? 30,
|
|
@@ -54,6 +61,68 @@ function resolveConfig(config) {
|
|
|
54
61
|
};
|
|
55
62
|
}
|
|
56
63
|
|
|
64
|
+
// src/compression/compress.ts
|
|
65
|
+
var GZIP_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
66
|
+
"text/plain",
|
|
67
|
+
"text/csv",
|
|
68
|
+
"text/markdown",
|
|
69
|
+
"text/x-markdown",
|
|
70
|
+
"text/xml",
|
|
71
|
+
"application/xml",
|
|
72
|
+
"text/yaml",
|
|
73
|
+
"text/x-yaml",
|
|
74
|
+
"application/x-yaml",
|
|
75
|
+
"application/rtf",
|
|
76
|
+
"text/rtf",
|
|
77
|
+
"application/json",
|
|
78
|
+
"image/svg+xml"
|
|
79
|
+
]);
|
|
80
|
+
var IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
81
|
+
"image/jpeg",
|
|
82
|
+
"image/png",
|
|
83
|
+
"image/gif",
|
|
84
|
+
"image/webp",
|
|
85
|
+
"image/bmp",
|
|
86
|
+
"image/tiff"
|
|
87
|
+
]);
|
|
88
|
+
var SKIP_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
89
|
+
"video/mp4",
|
|
90
|
+
"video/webm",
|
|
91
|
+
"video/quicktime",
|
|
92
|
+
"audio/mpeg",
|
|
93
|
+
"audio/wav",
|
|
94
|
+
"audio/ogg",
|
|
95
|
+
"audio/webm",
|
|
96
|
+
"audio/mp4",
|
|
97
|
+
"application/zip",
|
|
98
|
+
"application/pdf",
|
|
99
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
100
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
101
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
102
|
+
]);
|
|
103
|
+
function getCompressionStrategy(mimeType, config) {
|
|
104
|
+
if (SKIP_MIME_TYPES.has(mimeType)) return "skip";
|
|
105
|
+
if (IMAGE_MIME_TYPES.has(mimeType)) return "image";
|
|
106
|
+
if (config.compressDocuments && GZIP_MIME_TYPES.has(mimeType)) return "gzip";
|
|
107
|
+
return "skip";
|
|
108
|
+
}
|
|
109
|
+
async function compressFile(file, platformCompressFn, config) {
|
|
110
|
+
const noop = {
|
|
111
|
+
...file,
|
|
112
|
+
originalSize: file.size,
|
|
113
|
+
compressed: false,
|
|
114
|
+
compressionAlgorithm: "none"
|
|
115
|
+
};
|
|
116
|
+
if (!config.enabled || !platformCompressFn) return noop;
|
|
117
|
+
const strategy = getCompressionStrategy(file.type, config);
|
|
118
|
+
if (strategy === "skip") return noop;
|
|
119
|
+
try {
|
|
120
|
+
return await platformCompressFn(file, config);
|
|
121
|
+
} catch {
|
|
122
|
+
return noop;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
57
126
|
// src/api/client.ts
|
|
58
127
|
import axios from "axios";
|
|
59
128
|
var _tokenStore = null;
|
|
@@ -370,8 +439,11 @@ var conversationsApi = {
|
|
|
370
439
|
async leave(conversationId) {
|
|
371
440
|
await getApiClient().delete(`/conversations/${conversationId}/leave`);
|
|
372
441
|
},
|
|
373
|
-
async getMembers(conversationId) {
|
|
374
|
-
const { data } = await getApiClient().get(
|
|
442
|
+
async getMembers(conversationId, filter) {
|
|
443
|
+
const { data } = await getApiClient().get(
|
|
444
|
+
`/conversations/${conversationId}/participants`,
|
|
445
|
+
filter ? { params: { filter } } : void 0
|
|
446
|
+
);
|
|
375
447
|
return data;
|
|
376
448
|
},
|
|
377
449
|
/**
|
|
@@ -447,12 +519,22 @@ var storageApi = {
|
|
|
447
519
|
return data;
|
|
448
520
|
}
|
|
449
521
|
};
|
|
450
|
-
async function uploadBatch(files, platformUploadFn, conversationId, onProgress) {
|
|
451
|
-
const
|
|
522
|
+
async function uploadBatch(files, platformUploadFn, conversationId, onProgress, platformCompressFn, compressionConfig) {
|
|
523
|
+
const compressedFiles = await Promise.all(
|
|
524
|
+
files.map((f) => compressFile(f, platformCompressFn, compressionConfig ?? { enabled: false, imageQuality: 0.85, imageMaxDimension: 1920, compressDocuments: true }))
|
|
525
|
+
);
|
|
526
|
+
const requests = compressedFiles.map((f) => ({
|
|
452
527
|
filename: f.name,
|
|
453
528
|
mimeType: f.type,
|
|
454
529
|
size: f.size,
|
|
455
|
-
conversationId
|
|
530
|
+
conversationId,
|
|
531
|
+
...f.compressed && {
|
|
532
|
+
metadata: {
|
|
533
|
+
compressed: true,
|
|
534
|
+
originalSize: f.originalSize,
|
|
535
|
+
compressionAlgorithm: f.compressionAlgorithm
|
|
536
|
+
}
|
|
537
|
+
}
|
|
456
538
|
}));
|
|
457
539
|
const { urls, errors: requestErrors } = await storageApi.requestPresignedUrlBatch(requests);
|
|
458
540
|
const progressMap = {};
|
|
@@ -466,7 +548,7 @@ async function uploadBatch(files, platformUploadFn, conversationId, onProgress)
|
|
|
466
548
|
const failed = [...requestErrors];
|
|
467
549
|
await Promise.all(
|
|
468
550
|
urls.map(async (presigned, idx) => {
|
|
469
|
-
const file =
|
|
551
|
+
const file = compressedFiles[idx];
|
|
470
552
|
progressMap[idx] = 0;
|
|
471
553
|
try {
|
|
472
554
|
await platformUploadFn(presigned, file, (pct) => {
|
|
@@ -858,7 +940,14 @@ var AntzChatClient = class {
|
|
|
858
940
|
disconnectSocket();
|
|
859
941
|
}
|
|
860
942
|
uploadFiles(files, conversationId) {
|
|
861
|
-
return uploadBatch(
|
|
943
|
+
return uploadBatch(
|
|
944
|
+
files,
|
|
945
|
+
this._config.platformUploadFn,
|
|
946
|
+
conversationId,
|
|
947
|
+
this._config.upload.onProgress,
|
|
948
|
+
this._config.platformCompressFn,
|
|
949
|
+
this._config.compression
|
|
950
|
+
);
|
|
862
951
|
}
|
|
863
952
|
async uploadIcon(conversationId, file) {
|
|
864
953
|
const result = await this.uploadFiles([file], conversationId);
|
|
@@ -877,6 +966,7 @@ export {
|
|
|
877
966
|
disconnectSocket,
|
|
878
967
|
getApiClient,
|
|
879
968
|
getAuthStore,
|
|
969
|
+
getCompressionStrategy,
|
|
880
970
|
getSocket,
|
|
881
971
|
getSocketStatus,
|
|
882
972
|
initApiClient,
|