vanshi-sdk 1.0.4

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.cjs ADDED
@@ -0,0 +1,1015 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/sdk/index.ts
30
+ var sdk_exports = {};
31
+ __export(sdk_exports, {
32
+ clearConversationTotalUnreadMessageCount: () => clearConversationTotalUnreadMessageCount,
33
+ clearConversationUnreadMessageCount: () => clearConversationUnreadMessageCount,
34
+ create: () => initSocket,
35
+ default: () => sdk_default,
36
+ deleteAllConversationMessages: () => deleteAllConversationMessages,
37
+ deleteAllConversations: () => deleteAllConversations,
38
+ deleteAllMessage: () => deleteAllMessage,
39
+ deleteConversation: () => deleteConversation,
40
+ deleteMessages: () => deleteMessages,
41
+ isConnected: () => isSocketConnected,
42
+ login: () => login,
43
+ logout: () => logout,
44
+ off: () => off,
45
+ on: () => on,
46
+ queryConversation: () => queryConversation,
47
+ queryGroupMessageReceiptReadMemberList: () => queryGroupMessageReceiptReadMemberList,
48
+ queryGroupMessageReceiptUnreadMemberList: () => queryGroupMessageReceiptUnreadMemberList,
49
+ queryHistoryMessage: () => queryHistoryMessage,
50
+ queryMessageReceiptsInfo: () => queryMessageReceiptsInfo,
51
+ revokeMessage: () => revokeMessage,
52
+ sendMediaMessage: () => sendMediaMessage,
53
+ sendMessage: () => sendMessage,
54
+ sendMessageReceiptsRead: () => sendMessageReceiptsRead
55
+ });
56
+ module.exports = __toCommonJS(sdk_exports);
57
+
58
+ // src/plugins/socketio/client.ts
59
+ var import_socket = __toESM(require("socket.io-client"), 1);
60
+
61
+ // src/sdk/runtime.ts
62
+ var SDK_TOKEN_KEY = "VanshiSdk_Token";
63
+ var SDK_LOGIN_KEY = "VanshiSdk_isLogin";
64
+ function getBrowserStorage() {
65
+ if (typeof localStorage === "undefined") {
66
+ return void 0;
67
+ }
68
+ return localStorage;
69
+ }
70
+ var SdkRuntimeError = class extends Error {
71
+ constructor(result) {
72
+ super(result.message || `SDK request failed${result.code !== void 0 ? `: ${String(result.code)}` : ""}`);
73
+ this.name = "SdkRuntimeError";
74
+ this.code = result.code;
75
+ this.data = result.data;
76
+ this.raw = result.raw;
77
+ this.parsed = result.parsed;
78
+ }
79
+ };
80
+ function parseJsonSafely(value) {
81
+ if (value == null) {
82
+ return void 0;
83
+ }
84
+ if (typeof value !== "string") {
85
+ return value;
86
+ }
87
+ try {
88
+ return JSON.parse(value);
89
+ } catch {
90
+ return void 0;
91
+ }
92
+ }
93
+ function isSuccessCode(code) {
94
+ return code === 0 || code === "0" || code === true;
95
+ }
96
+ function toSdkEnvelope(response) {
97
+ if (response && typeof response === "object") {
98
+ return response;
99
+ }
100
+ return {};
101
+ }
102
+ function unwrapSdkData(response) {
103
+ const result = unwrapSdkDetailedData(response);
104
+ if (!result.success) {
105
+ throw new SdkRuntimeError(result);
106
+ }
107
+ return result.data;
108
+ }
109
+ function unwrapSdkResponse(response) {
110
+ const envelope = toSdkEnvelope(response);
111
+ const parsed = parseJsonSafely(envelope.data);
112
+ if (parsed && typeof parsed === "object" && "code" in parsed) {
113
+ return parsed;
114
+ }
115
+ return {
116
+ code: envelope.code,
117
+ message: envelope.message,
118
+ data: parsed !== void 0 ? parsed : envelope.data
119
+ };
120
+ }
121
+ function unwrapSdkDetailedData(response) {
122
+ const envelope = toSdkEnvelope(response);
123
+ const parsed = parseJsonSafely(envelope.data);
124
+ if (parsed && typeof parsed === "object" && "code" in parsed) {
125
+ const success = isSuccessCode(parsed.code);
126
+ return {
127
+ success,
128
+ code: parsed.code,
129
+ message: parsed.message || envelope.message,
130
+ data: parsed.data,
131
+ raw: response,
132
+ parsed
133
+ };
134
+ }
135
+ if (envelope.code !== void 0 || envelope.message !== void 0) {
136
+ return {
137
+ success: isSuccessCode(envelope.code),
138
+ code: envelope.code,
139
+ message: envelope.message,
140
+ data: parsed !== void 0 ? parsed : envelope.data,
141
+ raw: response,
142
+ parsed
143
+ };
144
+ }
145
+ return {
146
+ success: true,
147
+ data: parsed !== void 0 ? parsed : envelope.data,
148
+ raw: response,
149
+ parsed
150
+ };
151
+ }
152
+ function getStoredToken() {
153
+ return getBrowserStorage()?.getItem(SDK_TOKEN_KEY) || "";
154
+ }
155
+ function setSdkSession(token) {
156
+ const storage = getBrowserStorage();
157
+ if (!storage) {
158
+ return;
159
+ }
160
+ storage.setItem(SDK_TOKEN_KEY, token);
161
+ storage.setItem(SDK_LOGIN_KEY, "true");
162
+ }
163
+ function clearSdkSession() {
164
+ const storage = getBrowserStorage();
165
+ if (!storage) {
166
+ return;
167
+ }
168
+ storage.removeItem(SDK_TOKEN_KEY);
169
+ storage.removeItem(SDK_LOGIN_KEY);
170
+ }
171
+ function getSocketUrl() {
172
+ const globalUrl = typeof window !== "undefined" ? window.__VANSHI_SOCKET_URL : void 0;
173
+ return globalUrl || "wss://ws-vanshi-chat-sdk.xchatclub.com";
174
+ }
175
+ function getUploadUrl() {
176
+ const globalHttpUrl = typeof window !== "undefined" ? window.__VANSHI_HTTP_URL : void 0;
177
+ return globalHttpUrl || "https://vanshi-chat-api.xchatclub.com/api/files/sdkUpload";
178
+ }
179
+
180
+ // src/sdk/session.ts
181
+ var reconnectLoginHandler = null;
182
+ function registerReconnectLoginHandler(handler) {
183
+ reconnectLoginHandler = handler;
184
+ }
185
+ async function restoreSessionAfterReconnect() {
186
+ if (!reconnectLoginHandler) {
187
+ return false;
188
+ }
189
+ const token = getStoredToken();
190
+ if (!token) {
191
+ return false;
192
+ }
193
+ try {
194
+ return await reconnectLoginHandler(token);
195
+ } catch {
196
+ return false;
197
+ }
198
+ }
199
+ function clearSessionState() {
200
+ clearSdkSession();
201
+ }
202
+
203
+ // src/plugins/socketio/client.ts
204
+ function parseSocketConnectErrorPayload(value) {
205
+ if (!value) {
206
+ return void 0;
207
+ }
208
+ if (typeof value === "string") {
209
+ try {
210
+ const parsed = JSON.parse(value);
211
+ if (parsed && typeof parsed === "object") {
212
+ return parsed;
213
+ }
214
+ } catch {
215
+ return void 0;
216
+ }
217
+ }
218
+ if (typeof value === "object") {
219
+ return value;
220
+ }
221
+ return void 0;
222
+ }
223
+ function normalizeSocketConnectError(error) {
224
+ const rawMessage = error && typeof error === "object" && "message" in error ? error.message : void 0;
225
+ const rawData = error && typeof error === "object" && "data" in error ? error.data : void 0;
226
+ const payload = parseSocketConnectErrorPayload(rawData) || parseSocketConnectErrorPayload(rawMessage);
227
+ const normalized = new Error(
228
+ payload?.message || (typeof rawMessage === "string" ? rawMessage : "") || "socket connect failed"
229
+ );
230
+ normalized.name = "SocketConnectError";
231
+ normalized.code = payload?.code;
232
+ normalized.data = payload;
233
+ normalized.requestId = payload?.requestId;
234
+ normalized.raw = error;
235
+ return normalized;
236
+ }
237
+ var SocketClient = class {
238
+ constructor() {
239
+ this.pending = /* @__PURE__ */ new Map();
240
+ this.emitQueue = [];
241
+ this.connectPromise = null;
242
+ this.url = "";
243
+ this.handleResponse = (res) => {
244
+ const entry = this.pending.get(res.id);
245
+ if (!entry)
246
+ return;
247
+ clearTimeout(entry.timer);
248
+ this.pending.delete(res.id);
249
+ res.error ? entry.reject(res.error) : entry.resolve(res.payload);
250
+ };
251
+ }
252
+ connect(url, auth, opts = {}) {
253
+ if (this.connectPromise)
254
+ return this.connectPromise;
255
+ if (this.isConnected())
256
+ return Promise.resolve();
257
+ if (this.socket) {
258
+ try {
259
+ this.socket.off();
260
+ this.socket.io.off();
261
+ this.socket = void 0;
262
+ } catch {
263
+ }
264
+ }
265
+ if (this.isConnected())
266
+ return Promise.resolve();
267
+ const { baseUrl, namespace } = this.parseUrl(url);
268
+ this.url = url;
269
+ const ioOpts = {
270
+ ...opts,
271
+ transports: ["websocket"],
272
+ // 🔥 只保留 websocket,不会多条连接
273
+ query: { namespace },
274
+ forceNew: true,
275
+ reconnection: true,
276
+ reconnectionAttempts: 9999,
277
+ reconnectionDelay: 1e4,
278
+ timeout: 15e3
279
+ };
280
+ this.connectPromise = new Promise((resolve, reject) => {
281
+ const socket = (0, import_socket.default)(`${baseUrl}/im/user`, ioOpts);
282
+ this.socket = socket;
283
+ console.log("[SocketClient] \u65B0\u8FDE\u63A5\u521B\u5EFA\uFF1A", `${baseUrl}/im/user`);
284
+ const handleConnect = () => {
285
+ socket.off("connect_error", handleError);
286
+ socket.on("api:response", this.handleResponse);
287
+ this.processEmitQueue();
288
+ resolve();
289
+ };
290
+ const handleError = (err) => {
291
+ const normalizedError = normalizeSocketConnectError(err);
292
+ console.error("[SocketClient] \u8FDE\u63A5\u5931\u8D25\uFF1A:", normalizedError);
293
+ socket.off("connect", handleConnect);
294
+ reject(normalizedError);
295
+ };
296
+ socket.once("connect", handleConnect);
297
+ socket.once("connect_error", handleError);
298
+ socket.on("disconnect", (reason) => {
299
+ this.cleanupAllPending("disconnected: " + reason);
300
+ this.connectPromise = null;
301
+ });
302
+ socket.io.off("reconnect");
303
+ socket.io.on("reconnect", async () => {
304
+ console.log("[SocketClient] \u91CD\u8FDE\u6210\u529F \u2192 \u7B49\u5F85 socket \u5B8C\u5168\u5C31\u7EEA", this.socket?.connected);
305
+ await new Promise(
306
+ (resolveReconnect) => setTimeout(resolveReconnect, 200)
307
+ );
308
+ if (!this.isConnected() || !this.socket) {
309
+ console.log("[SocketClient] socket \u672A\u5C31\u7EEA\uFF0C\u8DF3\u8FC7\u767B\u5F55");
310
+ return;
311
+ }
312
+ try {
313
+ console.log("[SocketClient] \u5F00\u59CB\u81EA\u52A8\u767B\u5F55 \u2705");
314
+ const res = await restoreSessionAfterReconnect();
315
+ if (res) {
316
+ this.processEmitQueue();
317
+ } else {
318
+ clearSessionState();
319
+ }
320
+ } catch (err) {
321
+ console.error("[SocketClient] \u81EA\u52A8\u767B\u5F55\u5931\u8D25", err);
322
+ clearSessionState();
323
+ }
324
+ });
325
+ });
326
+ this.connectPromise.finally(() => {
327
+ this.connectPromise = null;
328
+ });
329
+ return this.connectPromise;
330
+ }
331
+ disconnect() {
332
+ if (!this.socket)
333
+ return;
334
+ try {
335
+ this.socket.off("api:response", this.handleResponse);
336
+ this.socket.io.off("reconnect");
337
+ this.socket.disconnect();
338
+ } catch {
339
+ }
340
+ this.socket = void 0;
341
+ this.cleanupAllPending("client disconnected");
342
+ }
343
+ emitWithAck(event, payload, timeoutMs = 1e4) {
344
+ if (this.isConnected()) {
345
+ return this.createEmitPromise(event, payload, timeoutMs);
346
+ }
347
+ if (this.connectPromise) {
348
+ return new Promise((resolve, reject) => {
349
+ this.emitQueue.push({ event, payload, timeoutMs, resolve, reject });
350
+ });
351
+ }
352
+ return Promise.reject(new Error("socket not initialized"));
353
+ }
354
+ request(path, payload, timeoutMs = 1e4) {
355
+ if (!this.socket) {
356
+ return Promise.reject(new Error("socket not initialized"));
357
+ }
358
+ const id = this.generateId();
359
+ const envelope = { id, path, payload };
360
+ return new Promise((resolve, reject) => {
361
+ const timer = setTimeout(() => {
362
+ this.pending.delete(id);
363
+ reject(new Error("request timeout"));
364
+ }, timeoutMs);
365
+ this.pending.set(id, { resolve, reject, timer });
366
+ try {
367
+ this.socket.emit("api:request", envelope);
368
+ } catch (err) {
369
+ clearTimeout(timer);
370
+ this.pending.delete(id);
371
+ reject(err);
372
+ }
373
+ });
374
+ }
375
+ on(event, handler) {
376
+ this.socket?.on(event, handler);
377
+ }
378
+ off(event, handler) {
379
+ if (!this.socket)
380
+ return;
381
+ handler ? this.socket.off(event, handler) : this.socket.off(event);
382
+ }
383
+ isConnected() {
384
+ return !!this.socket?.connected;
385
+ }
386
+ parseUrl(url) {
387
+ let baseUrl = url;
388
+ let namespace = "/im/user";
389
+ try {
390
+ const urlObj = new URL(url);
391
+ const queryNs = urlObj.searchParams.get("namespace");
392
+ if (queryNs)
393
+ namespace = queryNs;
394
+ baseUrl = urlObj.origin + urlObj.pathname.replace(/\/$/, "");
395
+ } catch {
396
+ console.warn("[Socket] URL parse failed:", url);
397
+ }
398
+ return { baseUrl, namespace };
399
+ }
400
+ generateId() {
401
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 9);
402
+ }
403
+ createEmitPromise(event, payload, timeoutMs) {
404
+ return new Promise((resolve, reject) => {
405
+ let timedOut = false;
406
+ const timer = setTimeout(() => {
407
+ timedOut = true;
408
+ reject(new Error("ack timeout"));
409
+ }, timeoutMs);
410
+ try {
411
+ this.socket.emit(event, payload, (response) => {
412
+ if (timedOut)
413
+ return;
414
+ clearTimeout(timer);
415
+ if (response?.code !== void 0) {
416
+ isSuccessCode(response.code) ? resolve(response) : reject(new Error(response.message || `code=${response.code}`));
417
+ } else {
418
+ resolve(response);
419
+ }
420
+ });
421
+ } catch (err) {
422
+ clearTimeout(timer);
423
+ reject(err);
424
+ }
425
+ });
426
+ }
427
+ processEmitQueue() {
428
+ if (!this.isConnected())
429
+ return;
430
+ while (this.emitQueue.length) {
431
+ const item = this.emitQueue.shift();
432
+ this.createEmitPromise(item.event, item.payload, item.timeoutMs).then(item.resolve).catch(item.reject);
433
+ }
434
+ }
435
+ cleanupAllPending(reason) {
436
+ for (const [, entry] of this.pending) {
437
+ clearTimeout(entry.timer);
438
+ entry.reject(new Error(reason));
439
+ }
440
+ this.pending.clear();
441
+ for (const item of this.emitQueue) {
442
+ item.reject(new Error(reason));
443
+ }
444
+ this.emitQueue = [];
445
+ }
446
+ };
447
+ var socketClient = new SocketClient();
448
+ var client_default = socketClient;
449
+
450
+ // src/plugins/request/index.ts
451
+ async function request(config) {
452
+ if (!config || !config.path) {
453
+ return Promise.reject(new Error("invalid request config"));
454
+ }
455
+ const path = config.path;
456
+ const isSdkApi = path.startsWith("/sdk/") || path.startsWith("sdk/");
457
+ if (isSdkApi) {
458
+ const eventName = path.replace(/^\/?sdk\//, "");
459
+ const timeoutMs2 = typeof config.timeoutMs === "number" ? config.timeoutMs : 1e4;
460
+ if (!client_default.isConnected()) {
461
+ return Promise.reject(new Error("socket not connected"));
462
+ }
463
+ try {
464
+ const res = await client_default.emitWithAck(
465
+ eventName,
466
+ config.data,
467
+ timeoutMs2
468
+ );
469
+ if (res && typeof res === "object" && typeof res.code === "number") {
470
+ return res;
471
+ }
472
+ return { code: 0, message: "", data: res };
473
+ } catch (err) {
474
+ return Promise.reject(err);
475
+ }
476
+ }
477
+ if (!client_default.isConnected()) {
478
+ return Promise.reject(new Error("socket not connected"));
479
+ }
480
+ const timeoutMs = typeof config.timeoutMs === "number" ? config.timeoutMs : 1e4;
481
+ return client_default.request(config.path, config.data, timeoutMs);
482
+ }
483
+
484
+ // src/apis/SdkQueryConversationPostApi.ts
485
+ var postSdkQueryConversationApiRequest = (data) => {
486
+ return request({
487
+ path: "/sdk/queryConversation",
488
+ method: "POST",
489
+ data
490
+ });
491
+ };
492
+
493
+ // src/apis/SdkDeleteAllConversationsPostApi.ts
494
+ var postSdkDeleteAllConversationsApiRequest = (data) => {
495
+ return request({
496
+ path: "/sdk/deleteAllConversations",
497
+ method: "POST",
498
+ data
499
+ });
500
+ };
501
+
502
+ // src/apis/SdkDeleteConversationPostApi.ts
503
+ var postSdkDeleteConversationApiRequest = (data) => {
504
+ return request({
505
+ path: "/sdk/deleteConversation",
506
+ method: "POST",
507
+ data
508
+ });
509
+ };
510
+
511
+ // src/apis/SdkClearConversationTotalUnreadMessageCountPostApi.ts
512
+ var postSdkClearConversationTotalUnreadMessageCountApiRequest = (data) => {
513
+ return request({
514
+ path: "/sdk/clearConversationTotalUnreadMessageCount",
515
+ method: "POST",
516
+ data
517
+ });
518
+ };
519
+
520
+ // src/apis/SdkClearConversationUnreadMessageCountPostApi.ts
521
+ var postSdkClearConversationUnreadMessageCountApiRequest = (data) => {
522
+ return request({
523
+ path: "/sdk/clearConversationUnreadMessageCount",
524
+ method: "POST",
525
+ data
526
+ });
527
+ };
528
+
529
+ // src/sdk/conversation.ts
530
+ async function queryConversation(payload) {
531
+ const response = await postSdkQueryConversationApiRequest(payload);
532
+ return unwrapSdkData(response) ?? [];
533
+ }
534
+ async function deleteAllConversations() {
535
+ const response = await postSdkDeleteAllConversationsApiRequest(
536
+ { config: true }
537
+ );
538
+ return unwrapSdkResponse(response);
539
+ }
540
+ async function deleteConversation(payload) {
541
+ const response = await postSdkDeleteConversationApiRequest(payload);
542
+ return unwrapSdkResponse(response);
543
+ }
544
+ async function clearConversationTotalUnreadMessageCount() {
545
+ const response = await postSdkClearConversationTotalUnreadMessageCountApiRequest(
546
+ {}
547
+ );
548
+ return unwrapSdkResponse(response);
549
+ }
550
+ async function clearConversationUnreadMessageCount(conversationID, conversationType) {
551
+ const response = await postSdkClearConversationUnreadMessageCountApiRequest(
552
+ {
553
+ conversationID,
554
+ conversationType: String(conversationType)
555
+ }
556
+ );
557
+ return unwrapSdkResponse(response);
558
+ }
559
+
560
+ // src/sdk/initSocket.ts
561
+ async function initSocket() {
562
+ const baseUrl = getSocketUrl();
563
+ if (!client_default.isConnected()) {
564
+ await client_default.connect(baseUrl);
565
+ }
566
+ }
567
+ function isSocketConnected() {
568
+ return client_default.isConnected();
569
+ }
570
+ function on(event, handler) {
571
+ client_default.on(event, handler);
572
+ }
573
+ function off(event, handler) {
574
+ client_default.off(event, handler);
575
+ }
576
+
577
+ // src/apis/SdkLoginPostApi.ts
578
+ var postSdkLoginApiRequest = (data) => {
579
+ return request({
580
+ path: "/sdk/login",
581
+ method: "POST",
582
+ data
583
+ });
584
+ };
585
+ var postSdkLogoutApiRequest = (data) => {
586
+ return request({
587
+ path: "/sdk/logout",
588
+ method: "POST",
589
+ data
590
+ });
591
+ };
592
+
593
+ // src/sdk/loginCore.ts
594
+ async function performLogin(payload, { requestLogin, setSession = setSdkSession, clearSession = clearSdkSession }) {
595
+ try {
596
+ const resp = await requestLogin(payload);
597
+ if (unwrapSdkData(resp)) {
598
+ setSession(payload.token);
599
+ return true;
600
+ }
601
+ } catch (error) {
602
+ clearSession();
603
+ throw error;
604
+ }
605
+ clearSession();
606
+ return false;
607
+ }
608
+
609
+ // src/sdk/login.ts
610
+ async function login(payload) {
611
+ return performLogin(payload, {
612
+ requestLogin: postSdkLoginApiRequest
613
+ });
614
+ }
615
+ registerReconnectLoginHandler((token) => login({ token }));
616
+ async function logout(disconnect = true) {
617
+ let success = false;
618
+ try {
619
+ const resp = await postSdkLogoutApiRequest(
620
+ {}
621
+ );
622
+ let res = JSON.parse(resp);
623
+ const result = unwrapSdkData(res);
624
+ success = Boolean(result) || isSuccessCode(res.code);
625
+ } catch {
626
+ success = false;
627
+ } finally {
628
+ clearSdkSession();
629
+ }
630
+ return success;
631
+ }
632
+
633
+ // src/apis/SdkSendMessagePostApi.ts
634
+ var postSdkSendMessageApiRequest = (data) => {
635
+ return request({
636
+ path: "/sdk/sendMessage",
637
+ method: "POST",
638
+ data
639
+ });
640
+ };
641
+
642
+ // src/apis/SdkSendMediaMessagePostApi.ts
643
+ var postSdkSendMediaMessageApiRequest = (data) => {
644
+ return request({
645
+ path: "/sdk/sendMediaMessage",
646
+ method: "POST",
647
+ data
648
+ });
649
+ };
650
+
651
+ // src/apis/SdkQueryHistoryMessagePostApi.ts
652
+ var postSdkQueryHistoryMessageApiRequest = (data) => {
653
+ return request({
654
+ path: "/sdk/queryHistoryMessage",
655
+ method: "POST",
656
+ data
657
+ });
658
+ };
659
+
660
+ // src/apis/SdkDeleteAllConversationMessagesPostApi.ts
661
+ var postSdkDeleteAllConversationMessagesApiRequest = (data) => {
662
+ return request({
663
+ path: "/sdk/deleteAllConversationMessages",
664
+ method: "POST",
665
+ data
666
+ });
667
+ };
668
+
669
+ // src/apis/SdkDeleteMessagesPostApi.ts
670
+ var postSdkDeleteMessagesApiRequest = (data) => {
671
+ return request({
672
+ path: "/sdk/deleteMessages",
673
+ method: "POST",
674
+ data
675
+ });
676
+ };
677
+
678
+ // src/apis/SdkRevokeMessagePostApi.ts
679
+ var postSdkRevokeMessageApiRequest = (data) => {
680
+ return request({
681
+ path: "/sdk/revokeMessage",
682
+ method: "POST",
683
+ data
684
+ });
685
+ };
686
+
687
+ // helper/index.ts
688
+ function isSameUid(id, uid) {
689
+ return id?.toString() === uid?.toString();
690
+ }
691
+ var getVideoDurationAndFirstFrame = (file) => {
692
+ return new Promise((resolve, reject) => {
693
+ const video = document.createElement("video");
694
+ const canvas = document.createElement("canvas");
695
+ const ctx = canvas.getContext("2d");
696
+ let duration = 0;
697
+ let videoWidth = 0;
698
+ let videoHeight = 0;
699
+ video.preload = "metadata";
700
+ video.muted = true;
701
+ video.playsInline = true;
702
+ video.autoplay = true;
703
+ video.onloadedmetadata = () => {
704
+ canvas.width = video.videoWidth || 640;
705
+ canvas.height = video.videoHeight || 360;
706
+ window.URL.revokeObjectURL(video.src);
707
+ duration = video?.duration;
708
+ videoWidth = video.videoWidth || 640;
709
+ videoHeight = video.videoHeight || 360;
710
+ };
711
+ video.oncanplay = () => {
712
+ video.oncanplay = null;
713
+ video.pause();
714
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
715
+ canvas.toBlob(
716
+ (blob) => {
717
+ if (!blob) {
718
+ reject(new Error("\u622A\u53D6\u7B2C\u4E00\u5E27\u5931\u8D25"));
719
+ return;
720
+ }
721
+ const firstFrameFile = new File(
722
+ [blob],
723
+ `video_first_frame_${Date.now()}.jpg`,
724
+ { type: "image/jpeg" }
725
+ );
726
+ URL.revokeObjectURL(video.src);
727
+ video.src = "";
728
+ canvas.width = 0;
729
+ canvas.height = 0;
730
+ resolve({
731
+ duration,
732
+ firstFrameFile,
733
+ // 这就是你要的文件流
734
+ videoWidth,
735
+ videoHeight
736
+ });
737
+ },
738
+ "image/jpeg",
739
+ 0.9
740
+ // 图片质量 0-1
741
+ );
742
+ };
743
+ video.onerror = () => {
744
+ URL.revokeObjectURL(video.src);
745
+ reject(new Error("\u89C6\u9891\u6587\u4EF6\u635F\u574F\u6216\u683C\u5F0F\u4E0D\u652F\u6301"));
746
+ };
747
+ video.src = URL.createObjectURL(file);
748
+ });
749
+ };
750
+ function getAudioDuration(file) {
751
+ return new Promise((resolve, reject) => {
752
+ const audio = document.createElement("audio");
753
+ audio.preload = "metadata";
754
+ audio.onloadedmetadata = () => {
755
+ const duration = audio.duration;
756
+ URL.revokeObjectURL(audio.src);
757
+ resolve(duration);
758
+ };
759
+ audio.onerror = () => {
760
+ URL.revokeObjectURL(audio.src);
761
+ reject(new Error("\u97F3\u9891\u6587\u4EF6\u65E0\u6CD5\u8BFB\u53D6\u6216\u683C\u5F0F\u4E0D\u652F\u6301"));
762
+ };
763
+ audio.src = URL.createObjectURL(file);
764
+ });
765
+ }
766
+
767
+ // src/apis/SdkDeleteAllMessagePostApi.ts
768
+ var postSdkDeleteAllMessageApiRequest = (data) => {
769
+ return request({
770
+ path: "/sdk/deleteAllMessage",
771
+ method: "POST",
772
+ data
773
+ });
774
+ };
775
+
776
+ // src/sdk/message.ts
777
+ async function getImageSize(file) {
778
+ return new Promise((resolve, reject) => {
779
+ const url = URL.createObjectURL(file);
780
+ const img = new Image();
781
+ img.onload = () => {
782
+ resolve({
783
+ width: img.naturalWidth,
784
+ height: img.naturalHeight
785
+ });
786
+ URL.revokeObjectURL(url);
787
+ };
788
+ img.onerror = () => {
789
+ URL.revokeObjectURL(url);
790
+ reject(new Error("\u56FE\u7247\u6587\u4EF6\u65E0\u6CD5\u8BFB\u53D6\u6216\u683C\u5F0F\u4E0D\u652F\u6301"));
791
+ };
792
+ img.src = url;
793
+ });
794
+ }
795
+ async function uploadSdkFile(file) {
796
+ const formData = new FormData();
797
+ formData.append("file", file);
798
+ const response = await fetch(getUploadUrl(), {
799
+ method: "POST",
800
+ headers: {
801
+ Authorization: getStoredToken()
802
+ },
803
+ body: formData
804
+ });
805
+ if (!response.ok) {
806
+ throw new Error(`file upload failed: ${response.status}`);
807
+ }
808
+ const payload = await response.json();
809
+ if (payload.Code !== 0 && payload.Code !== "0") {
810
+ throw new Error(payload.Message || "file upload failed");
811
+ }
812
+ if (!payload.Result) {
813
+ throw new Error("file upload result is empty");
814
+ }
815
+ return payload.Result;
816
+ }
817
+ async function enrichMediaMessage(message) {
818
+ const file = message.file;
819
+ if (!file) {
820
+ throw new Error("media message file is required");
821
+ }
822
+ const enrichedMessage = {
823
+ ...message,
824
+ fileName: file.name || message.fileName || "",
825
+ fileSize: String(file.size)
826
+ };
827
+ if (isSameUid(message.type, "11" /* Image */)) {
828
+ const { width, height } = await getImageSize(file);
829
+ enrichedMessage.thumbnailWidth = String(width);
830
+ enrichedMessage.thumbnailHeight = String(height);
831
+ } else if (isSameUid(message.type, "13" /* Audio */)) {
832
+ const duration = await getAudioDuration(file);
833
+ enrichedMessage.duration = String(duration);
834
+ } else if (isSameUid(message.type, "14" /* Video */)) {
835
+ const res = await getVideoDurationAndFirstFrame(file);
836
+ enrichedMessage.duration = String(res.duration);
837
+ enrichedMessage.thumbnailWidth = String(res.videoWidth);
838
+ enrichedMessage.thumbnailHeight = String(res.videoHeight);
839
+ enrichedMessage.thumbnailDownloadUrl = await uploadSdkFile(res.firstFrameFile);
840
+ }
841
+ const fileDownloadUrl = await uploadSdkFile(file);
842
+ enrichedMessage.fileDownloadUrl = fileDownloadUrl;
843
+ if (isSameUid(message.type, "11" /* Image */)) {
844
+ enrichedMessage.thumbnailDownloadUrl = fileDownloadUrl;
845
+ }
846
+ delete enrichedMessage.file;
847
+ return enrichedMessage;
848
+ }
849
+ async function sendMessage(payload) {
850
+ const response = await postSdkSendMessageApiRequest(payload);
851
+ return unwrapSdkData(response);
852
+ }
853
+ async function sendMediaMessage(payload) {
854
+ const response = await postSdkSendMediaMessageApiRequest({
855
+ ...payload,
856
+ message: await enrichMediaMessage(payload.message)
857
+ });
858
+ return unwrapSdkData(response);
859
+ }
860
+ async function queryHistoryMessage(payload) {
861
+ const response = await postSdkQueryHistoryMessageApiRequest(payload);
862
+ return unwrapSdkData(response);
863
+ }
864
+ async function deleteAllConversationMessages() {
865
+ const response = await postSdkDeleteAllConversationMessagesApiRequest(
866
+ {
867
+ config: {
868
+ isAlsoDeleteServerMessage: true
869
+ // 是否同时删除服务器消息,默认为 false
870
+ }
871
+ }
872
+ );
873
+ return unwrapSdkResponse(response);
874
+ }
875
+ async function deleteMessages(conversationID, conversationType, messageList) {
876
+ const response = await postSdkDeleteMessagesApiRequest({
877
+ conversationID: Number(conversationID),
878
+ conversationType: conversationType.toString(),
879
+ messageList: messageList.map((msg) => ({
880
+ messageID: msg.messageID,
881
+ type: Number(msg.type)
882
+ }))
883
+ });
884
+ return unwrapSdkResponse(response);
885
+ }
886
+ async function revokeMessage(message, config) {
887
+ const response = await postSdkRevokeMessageApiRequest({ message, config });
888
+ return unwrapSdkResponse(response);
889
+ }
890
+ async function deleteAllMessage(conversationID, conversationType) {
891
+ const response = await postSdkDeleteAllMessageApiRequest({
892
+ conversationID: Number(conversationID),
893
+ conversationType: conversationType.toString()
894
+ });
895
+ return unwrapSdkResponse(response);
896
+ }
897
+
898
+ // src/apis/SdkQueryGroupMessageReceiptReadMemberListPostApi.ts
899
+ var postSdkQueryGroupMessageReceiptReadMemberListApiRequest = (data) => {
900
+ return request({
901
+ path: "/sdk/queryGroupMessageReceiptReadMemberList",
902
+ method: "POST",
903
+ data
904
+ });
905
+ };
906
+
907
+ // src/apis/SdkQueryGroupMessageReceiptUnreadMemberListPostApi.ts
908
+ var postSdkQueryGroupMessageReceiptUnreadMemberListApiRequest = (data) => {
909
+ return request({
910
+ path: "/sdk/queryGroupMessageReceiptUnreadMemberList",
911
+ method: "POST",
912
+ data
913
+ });
914
+ };
915
+
916
+ // src/apis/SdkQueryMessageReceiptsInfoPostApi.ts
917
+ var postSdkQueryMessageReceiptsInfoApiRequest = (data) => {
918
+ return request({
919
+ path: "/sdk/queryMessageReceiptsInfo",
920
+ method: "POST",
921
+ data
922
+ });
923
+ };
924
+
925
+ // src/apis/SdkSendMessageReceiptsReadPostApi.ts
926
+ var postSdkSendMessageReceiptsReadApiRequest = (data) => {
927
+ return request({
928
+ path: "/sdk/sendMessageReceiptsRead",
929
+ method: "POST",
930
+ data
931
+ });
932
+ };
933
+
934
+ // src/sdk/messageReceipts.ts
935
+ async function sendMessageReceiptsRead(conversationID, conversationType, messageList) {
936
+ const response = await postSdkSendMessageReceiptsReadApiRequest({
937
+ conversationID,
938
+ conversationType: conversationType.toString(),
939
+ messageList
940
+ });
941
+ return unwrapSdkResponse(response);
942
+ }
943
+ async function queryMessageReceiptsInfo(conversationID, conversationType, messageList) {
944
+ const response = await postSdkQueryMessageReceiptsInfoApiRequest({
945
+ conversationID: Number(conversationID),
946
+ conversationType: conversationType.toString(),
947
+ messageList
948
+ });
949
+ return unwrapSdkResponse(response);
950
+ }
951
+ async function queryGroupMessageReceiptUnreadMemberList(groupID, config, message) {
952
+ const response = await postSdkQueryGroupMessageReceiptUnreadMemberListApiRequest({
953
+ groupID,
954
+ config,
955
+ message
956
+ });
957
+ return unwrapSdkResponse(response);
958
+ }
959
+ async function queryGroupMessageReceiptReadMemberList(groupID, config, message) {
960
+ const response = await postSdkQueryGroupMessageReceiptReadMemberListApiRequest({
961
+ groupID,
962
+ config,
963
+ message
964
+ });
965
+ return unwrapSdkResponse(response);
966
+ }
967
+
968
+ // src/sdk/index.ts
969
+ var VanshiSdk = {
970
+ // 创建 ws 实例
971
+ create: initSocket,
972
+ // 退出 SDK 登录并断开 ws 连接
973
+ logout,
974
+ // 判断当前 ws 是否连接
975
+ isConnected: isSocketConnected,
976
+ // 监听推送事件
977
+ on,
978
+ // 解除推送事件监听
979
+ off,
980
+ // 登录 SDK
981
+ login,
982
+ // 查询会话列表
983
+ queryConversation,
984
+ // 删除全部会话列表
985
+ deleteAllConversations,
986
+ // 删除单个会话
987
+ deleteConversation,
988
+ // 清除全部会话未读数
989
+ clearConversationTotalUnreadMessageCount,
990
+ // 清除单个会话未读数
991
+ clearConversationUnreadMessageCount,
992
+ // 查询历史消息
993
+ queryHistoryMessage,
994
+ // 发送文本消息
995
+ sendMessage,
996
+ // 发送媒体消息
997
+ sendMediaMessage,
998
+ // 删除全部会话消息
999
+ deleteAllConversationMessages,
1000
+ // 删除指定消息
1001
+ deleteMessages,
1002
+ // 删除当前会话全部消息
1003
+ deleteAllMessage,
1004
+ // 撤回消息
1005
+ revokeMessage,
1006
+ // 发送已读回执
1007
+ sendMessageReceiptsRead,
1008
+ // 查询一批消息回执信息
1009
+ queryMessageReceiptsInfo,
1010
+ // 查询群消息未读成员列表。
1011
+ queryGroupMessageReceiptUnreadMemberList,
1012
+ // 查询群消息已读成员列表。
1013
+ queryGroupMessageReceiptReadMemberList
1014
+ };
1015
+ var sdk_default = VanshiSdk;