tgo-widget-miniprogram 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,183 +1,1131 @@
1
- /**
2
- * WuKongIM EasyJSSDK wrapper for miniprogram
3
- * easyjssdk v1.1.0+ natively supports WeChat MiniProgram WebSocket
4
- */
5
- var WKIM = require('easyjssdk').WKIM
6
- var WKIMEvent = require('easyjssdk').WKIMEvent
7
- var adapter = require('../adapters/request')
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __commonJS = (cb, mod) => function __require() {
3
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4
+ };
8
5
 
9
- function WuKongIMService() {
10
- this._inited = false
11
- this._im = null
12
- this._cfg = null
13
- this._uid = null
14
- this._bound = false
15
- this._hConnect = null
16
- this._hDisconnect = null
17
- this._hError = null
18
- this._hMessage = null
19
- this._hCustom = null
20
- this._msgListeners = []
21
- this._statusListeners = []
22
- this._customListeners = []
23
- }
24
-
25
- WuKongIMService.prototype.isReady = function () {
26
- return this._inited && !!this._im && !!this._cfg
27
- }
28
-
29
- WuKongIMService.prototype.getUid = function () {
30
- return this._uid
31
- }
32
-
33
- WuKongIMService.prototype.init = function (opts) {
34
- var self = this
35
- this._cfg = Object.assign({}, opts, { channelType: opts.channelType || 'person' })
36
- this._uid = opts.uid
37
-
38
- return this._fetchRouteWsAddr(opts.apiBase, opts.uid, 10000).then(function (wsAddr) {
39
- if (self._im && self._bound) {
40
- try { self._unbindInternalEvents() } catch (e) {}
6
+ // node_modules/easyjssdk/dist/cjs/index.js
7
+ var require_cjs = __commonJS({
8
+ "node_modules/easyjssdk/dist/cjs/index.js"(exports2) {
9
+ "use strict";
10
+ Object.defineProperty(exports2, "__esModule", { value: true });
11
+ exports2.WKIMDeviceFlag = exports2.WKIMEvent = exports2.WKIMChannelType = exports2.WKIM = exports2.DeviceFlag = exports2.ReasonCode = exports2.Event = exports2.ChannelType = exports2.currentPlatform = exports2.PlatformType = void 0;
12
+ var WS_CONNECTING = 0;
13
+ var WS_OPEN = 1;
14
+ var WS_CLOSING = 2;
15
+ var WS_CLOSED = 3;
16
+ var PlatformType;
17
+ (function(PlatformType2) {
18
+ PlatformType2["Browser"] = "browser";
19
+ PlatformType2["NodeJS"] = "nodejs";
20
+ PlatformType2["WeChat"] = "wechat";
21
+ PlatformType2["Alipay"] = "alipay";
22
+ PlatformType2["UniApp"] = "uniapp";
23
+ })(PlatformType || (exports2.PlatformType = PlatformType = {}));
24
+ var WeChatWebSocketAdapter = class {
25
+ constructor(url) {
26
+ this.socketTask = null;
27
+ this._readyState = WS_CONNECTING;
28
+ this.onopen = null;
29
+ this.onmessage = null;
30
+ this.onerror = null;
31
+ this.onclose = null;
32
+ if (typeof wx === "undefined") {
33
+ throw new Error("WeChat Mini Program environment not detected");
34
+ }
35
+ this.socketTask = wx.connectSocket({
36
+ url,
37
+ success: () => {
38
+ console.log("WeChat WebSocket connecting...");
39
+ },
40
+ fail: (err) => {
41
+ console.error("WeChat WebSocket connection failed:", err);
42
+ this._readyState = WS_CLOSED;
43
+ if (this.onerror) {
44
+ this.onerror({ message: err.errMsg || "Connection failed" });
45
+ }
46
+ }
47
+ });
48
+ this.socketTask.onOpen((res) => {
49
+ this._readyState = WS_OPEN;
50
+ if (this.onopen) {
51
+ this.onopen(res);
52
+ }
53
+ });
54
+ this.socketTask.onMessage((res) => {
55
+ if (this.onmessage) {
56
+ const data = res.data instanceof ArrayBuffer ? new TextDecoder().decode(res.data) : res.data;
57
+ this.onmessage({ data });
58
+ }
59
+ });
60
+ this.socketTask.onError((res) => {
61
+ console.error("WeChat WebSocket error:", res);
62
+ if (this.onerror) {
63
+ this.onerror({ message: res.errMsg || "WebSocket error" });
64
+ }
65
+ });
66
+ this.socketTask.onClose((res) => {
67
+ this._readyState = WS_CLOSED;
68
+ if (this.onclose) {
69
+ this.onclose({ code: res.code || 1e3, reason: res.reason || "" });
70
+ }
71
+ });
72
+ }
73
+ get readyState() {
74
+ return this._readyState;
75
+ }
76
+ send(data) {
77
+ if (this._readyState !== WS_OPEN || !this.socketTask) {
78
+ throw new Error("WebSocket is not open");
79
+ }
80
+ this.socketTask.send({
81
+ data,
82
+ fail: (err) => {
83
+ console.error("WeChat WebSocket send failed:", err);
84
+ if (this.onerror) {
85
+ this.onerror({ message: "Send failed" });
86
+ }
87
+ }
88
+ });
89
+ }
90
+ close(code, reason) {
91
+ if (this._readyState === WS_CLOSED || this._readyState === WS_CLOSING) {
92
+ return;
93
+ }
94
+ this._readyState = WS_CLOSING;
95
+ if (this.socketTask) {
96
+ this.socketTask.close({
97
+ code: code || 1e3,
98
+ reason: reason || "",
99
+ fail: (err) => {
100
+ console.error("WeChat WebSocket close failed:", err);
101
+ }
102
+ });
103
+ }
104
+ }
105
+ };
106
+ var AlipayWebSocketAdapter = class {
107
+ constructor(url) {
108
+ this._readyState = WS_CONNECTING;
109
+ this.boundOnOpen = null;
110
+ this.boundOnMessage = null;
111
+ this.boundOnError = null;
112
+ this.boundOnClose = null;
113
+ this.onopen = null;
114
+ this.onmessage = null;
115
+ this.onerror = null;
116
+ this.onclose = null;
117
+ if (typeof my === "undefined") {
118
+ throw new Error("Alipay Mini Program environment not detected");
119
+ }
120
+ this.boundOnOpen = (res) => {
121
+ this._readyState = WS_OPEN;
122
+ if (this.onopen) {
123
+ this.onopen(res);
124
+ }
125
+ };
126
+ this.boundOnMessage = (res) => {
127
+ if (this.onmessage) {
128
+ const data = res.data instanceof ArrayBuffer ? new TextDecoder().decode(res.data) : res.data;
129
+ this.onmessage({ data });
130
+ }
131
+ };
132
+ this.boundOnError = (res) => {
133
+ console.error("Alipay WebSocket error:", res);
134
+ if (this.onerror) {
135
+ this.onerror({ message: res.errorMessage || "WebSocket error" });
136
+ }
137
+ };
138
+ this.boundOnClose = (res) => {
139
+ this._readyState = WS_CLOSED;
140
+ this.cleanup();
141
+ if (this.onclose) {
142
+ this.onclose({ code: res.code || 1e3, reason: res.reason || "" });
143
+ }
144
+ };
145
+ my.onSocketOpen(this.boundOnOpen);
146
+ my.onSocketMessage(this.boundOnMessage);
147
+ my.onSocketError(this.boundOnError);
148
+ my.onSocketClose(this.boundOnClose);
149
+ my.connectSocket({
150
+ url,
151
+ success: () => {
152
+ console.log("Alipay WebSocket connecting...");
153
+ },
154
+ fail: (err) => {
155
+ console.error("Alipay WebSocket connection failed:", err);
156
+ this._readyState = WS_CLOSED;
157
+ this.cleanup();
158
+ if (this.onerror) {
159
+ this.onerror({ message: err.errorMessage || "Connection failed" });
160
+ }
161
+ }
162
+ });
163
+ }
164
+ get readyState() {
165
+ return this._readyState;
166
+ }
167
+ send(data) {
168
+ if (typeof my === "undefined") {
169
+ throw new Error("Alipay Mini Program environment not detected");
170
+ }
171
+ if (this._readyState !== WS_OPEN) {
172
+ throw new Error("WebSocket is not open");
173
+ }
174
+ my.sendSocketMessage({
175
+ data,
176
+ fail: (err) => {
177
+ console.error("Alipay WebSocket send failed:", err);
178
+ if (this.onerror) {
179
+ this.onerror({ message: "Send failed" });
180
+ }
181
+ }
182
+ });
183
+ }
184
+ close(code, reason) {
185
+ if (typeof my === "undefined") {
186
+ return;
187
+ }
188
+ if (this._readyState === WS_CLOSED || this._readyState === WS_CLOSING) {
189
+ return;
190
+ }
191
+ this._readyState = WS_CLOSING;
192
+ my.closeSocket({
193
+ code: code || 1e3,
194
+ reason: reason || "",
195
+ fail: (err) => {
196
+ console.error("Alipay WebSocket close failed:", err);
197
+ }
198
+ });
199
+ }
200
+ cleanup() {
201
+ if (typeof my !== "undefined") {
202
+ my.offSocketOpen(this.boundOnOpen);
203
+ my.offSocketMessage(this.boundOnMessage);
204
+ my.offSocketError(this.boundOnError);
205
+ my.offSocketClose(this.boundOnClose);
206
+ this.boundOnOpen = null;
207
+ this.boundOnMessage = null;
208
+ this.boundOnError = null;
209
+ this.boundOnClose = null;
210
+ }
211
+ }
212
+ };
213
+ var UniAppWebSocketAdapter = class {
214
+ constructor(url) {
215
+ this.socketTask = null;
216
+ this._readyState = WS_CONNECTING;
217
+ this.onopen = null;
218
+ this.onmessage = null;
219
+ this.onerror = null;
220
+ this.onclose = null;
221
+ if (typeof uni === "undefined") {
222
+ throw new Error("UniApp environment not detected");
223
+ }
224
+ this.socketTask = uni.connectSocket({
225
+ url,
226
+ success: () => {
227
+ console.log("UniApp WebSocket connecting...");
228
+ },
229
+ fail: (err) => {
230
+ console.error("UniApp WebSocket connection failed:", err);
231
+ this._readyState = WS_CLOSED;
232
+ if (this.onerror) {
233
+ this.onerror({ message: err.errMsg || "Connection failed" });
234
+ }
235
+ }
236
+ });
237
+ this.socketTask.onOpen((res) => {
238
+ this._readyState = WS_OPEN;
239
+ if (this.onopen) {
240
+ this.onopen(res);
241
+ }
242
+ });
243
+ this.socketTask.onMessage((res) => {
244
+ if (this.onmessage) {
245
+ const data = res.data instanceof ArrayBuffer ? new TextDecoder().decode(res.data) : res.data;
246
+ this.onmessage({ data });
247
+ }
248
+ });
249
+ this.socketTask.onError((res) => {
250
+ console.error("UniApp WebSocket error:", res);
251
+ if (this.onerror) {
252
+ this.onerror({ message: res.errMsg || "WebSocket error" });
253
+ }
254
+ });
255
+ this.socketTask.onClose((res) => {
256
+ this._readyState = WS_CLOSED;
257
+ if (this.onclose) {
258
+ this.onclose({ code: res.code || 1e3, reason: res.reason || "" });
259
+ }
260
+ });
261
+ }
262
+ get readyState() {
263
+ return this._readyState;
264
+ }
265
+ send(data) {
266
+ if (this._readyState !== WS_OPEN || !this.socketTask) {
267
+ throw new Error("WebSocket is not open");
268
+ }
269
+ this.socketTask.send({
270
+ data,
271
+ fail: (err) => {
272
+ console.error("UniApp WebSocket send failed:", err);
273
+ if (this.onerror) {
274
+ this.onerror({ message: "Send failed" });
275
+ }
276
+ }
277
+ });
278
+ }
279
+ close(code, reason) {
280
+ if (this._readyState === WS_CLOSED || this._readyState === WS_CLOSING) {
281
+ return;
282
+ }
283
+ this._readyState = WS_CLOSING;
284
+ if (this.socketTask) {
285
+ this.socketTask.close({
286
+ code: code || 1e3,
287
+ reason: reason || "",
288
+ fail: (err) => {
289
+ console.error("UniApp WebSocket close failed:", err);
290
+ }
291
+ });
292
+ }
293
+ }
294
+ };
295
+ function detectPlatform() {
296
+ if (typeof uni !== "undefined" && typeof uni.connectSocket === "function") {
297
+ return PlatformType.UniApp;
298
+ }
299
+ if (typeof wx !== "undefined" && typeof wx.connectSocket === "function") {
300
+ return PlatformType.WeChat;
301
+ }
302
+ if (typeof my !== "undefined" && typeof my.connectSocket === "function") {
303
+ return PlatformType.Alipay;
304
+ }
305
+ if (typeof WebSocket !== "undefined") {
306
+ return PlatformType.Browser;
307
+ }
308
+ return PlatformType.NodeJS;
41
309
  }
42
- self._im = WKIM.init(wsAddr, { uid: opts.uid, token: opts.token || '' })
43
- self._bindInternalEvents()
44
- self._inited = true
45
- })
46
- }
47
-
48
- WuKongIMService.prototype._bindInternalEvents = function () {
49
- if (!this._im || this._bound) return
50
- var self = this
51
-
52
- this._hConnect = function (result) { self._emitStatus('connected', result) }
53
- this._hDisconnect = function (info) { self._emitStatus('disconnected', info) }
54
- this._hError = function (err) { self._emitStatus('error', err) }
55
- this._hMessage = function (message) { self._emitMessage(message) }
56
- this._hCustom = function (ev) { self._emitCustom(ev) }
57
-
58
- this._im.on(WKIMEvent.Connect, this._hConnect)
59
- this._im.on(WKIMEvent.Disconnect, this._hDisconnect)
60
- this._im.on(WKIMEvent.Error, this._hError)
61
- this._im.on(WKIMEvent.Message, this._hMessage)
62
- this._im.on(WKIMEvent.CustomEvent, this._hCustom)
63
- this._bound = true
64
- }
65
-
66
- WuKongIMService.prototype._unbindInternalEvents = function () {
67
- if (!this._im || !this._bound) return
68
- if (this._hConnect) this._im.off(WKIMEvent.Connect, this._hConnect)
69
- if (this._hDisconnect) this._im.off(WKIMEvent.Disconnect, this._hDisconnect)
70
- if (this._hError) this._im.off(WKIMEvent.Error, this._hError)
71
- if (this._hMessage) this._im.off(WKIMEvent.Message, this._hMessage)
72
- if (this._hCustom) this._im.off(WKIMEvent.CustomEvent, this._hCustom)
73
- this._hConnect = this._hDisconnect = this._hError = this._hMessage = this._hCustom = null
74
- this._bound = false
75
- }
76
-
77
- WuKongIMService.prototype._emitMessage = function (m) {
78
- this._msgListeners.forEach(function (fn) { try { fn(m) } catch (e) {} })
79
- }
80
-
81
- WuKongIMService.prototype._emitStatus = function (s, info) {
82
- this._statusListeners.forEach(function (fn) { try { fn(s, info) } catch (e) {} })
83
- }
84
-
85
- WuKongIMService.prototype._emitCustom = function (e) {
86
- this._customListeners.forEach(function (fn) { try { fn(e) } catch (e2) {} })
87
- }
88
-
89
- WuKongIMService.prototype.onMessage = function (cb) {
90
- this._msgListeners.push(cb)
91
- var self = this
92
- return function () {
93
- var idx = self._msgListeners.indexOf(cb)
94
- if (idx >= 0) self._msgListeners.splice(idx, 1)
95
- }
96
- }
97
-
98
- WuKongIMService.prototype.onStatus = function (cb) {
99
- this._statusListeners.push(cb)
100
- var self = this
101
- return function () {
102
- var idx = self._statusListeners.indexOf(cb)
103
- if (idx >= 0) self._statusListeners.splice(idx, 1)
104
- }
105
- }
106
-
107
- WuKongIMService.prototype.onCustom = function (cb) {
108
- this._customListeners.push(cb)
109
- var self = this
110
- return function () {
111
- var idx = self._customListeners.indexOf(cb)
112
- if (idx >= 0) self._customListeners.splice(idx, 1)
310
+ var currentPlatform = detectPlatform();
311
+ exports2.currentPlatform = currentPlatform;
312
+ function createWebSocket(url) {
313
+ switch (currentPlatform) {
314
+ case PlatformType.UniApp:
315
+ return new UniAppWebSocketAdapter(url);
316
+ case PlatformType.WeChat:
317
+ return new WeChatWebSocketAdapter(url);
318
+ case PlatformType.Alipay:
319
+ return new AlipayWebSocketAdapter(url);
320
+ case PlatformType.Browser:
321
+ return new WebSocket(url);
322
+ case PlatformType.NodeJS:
323
+ default:
324
+ try {
325
+ const dynamicRequire = new Function("mod", "return require(mod)");
326
+ const Ws = dynamicRequire("ws");
327
+ const WsImpl = Ws.WebSocket || Ws;
328
+ return new WsImpl(url);
329
+ } catch (e) {
330
+ throw new Error("WebSocket is not available in this environment. Install 'ws' package for Node.js.");
331
+ }
332
+ }
333
+ }
334
+ var ChannelType;
335
+ (function(ChannelType2) {
336
+ ChannelType2[ChannelType2["Person"] = 1] = "Person";
337
+ ChannelType2[ChannelType2["Group"] = 2] = "Group";
338
+ ChannelType2[ChannelType2["CustomerService"] = 3] = "CustomerService";
339
+ ChannelType2[ChannelType2["Community"] = 4] = "Community";
340
+ ChannelType2[ChannelType2["CommunityTopic"] = 5] = "CommunityTopic";
341
+ ChannelType2[ChannelType2["Info"] = 6] = "Info";
342
+ ChannelType2[ChannelType2["Data"] = 7] = "Data";
343
+ ChannelType2[ChannelType2["Temp"] = 8] = "Temp";
344
+ ChannelType2[ChannelType2["Live"] = 9] = "Live";
345
+ ChannelType2[ChannelType2["Visitors"] = 10] = "Visitors";
346
+ })(ChannelType || (exports2.WKIMChannelType = exports2.ChannelType = ChannelType = {}));
347
+ var Event;
348
+ (function(Event2) {
349
+ Event2["Connect"] = "connect";
350
+ Event2["Disconnect"] = "disconnect";
351
+ Event2["Message"] = "message";
352
+ Event2["Error"] = "error";
353
+ Event2["SendAck"] = "sendack";
354
+ Event2["Reconnecting"] = "reconnecting";
355
+ Event2["CustomEvent"] = "customevent";
356
+ })(Event || (exports2.WKIMEvent = exports2.Event = Event = {}));
357
+ var ReasonCode;
358
+ (function(ReasonCode2) {
359
+ ReasonCode2[ReasonCode2["Unknown"] = 0] = "Unknown";
360
+ ReasonCode2[ReasonCode2["Success"] = 1] = "Success";
361
+ ReasonCode2[ReasonCode2["AuthFail"] = 2] = "AuthFail";
362
+ ReasonCode2[ReasonCode2["SubscriberNotExist"] = 3] = "SubscriberNotExist";
363
+ ReasonCode2[ReasonCode2["InBlacklist"] = 4] = "InBlacklist";
364
+ ReasonCode2[ReasonCode2["ChannelNotExist"] = 5] = "ChannelNotExist";
365
+ ReasonCode2[ReasonCode2["UserNotOnNode"] = 6] = "UserNotOnNode";
366
+ ReasonCode2[ReasonCode2["SenderOffline"] = 7] = "SenderOffline";
367
+ ReasonCode2[ReasonCode2["MsgKeyError"] = 8] = "MsgKeyError";
368
+ ReasonCode2[ReasonCode2["PayloadDecodeError"] = 9] = "PayloadDecodeError";
369
+ ReasonCode2[ReasonCode2["ForwardSendPacketError"] = 10] = "ForwardSendPacketError";
370
+ ReasonCode2[ReasonCode2["NotAllowSend"] = 11] = "NotAllowSend";
371
+ ReasonCode2[ReasonCode2["ConnectKick"] = 12] = "ConnectKick";
372
+ ReasonCode2[ReasonCode2["NotInWhitelist"] = 13] = "NotInWhitelist";
373
+ ReasonCode2[ReasonCode2["QueryTokenError"] = 14] = "QueryTokenError";
374
+ ReasonCode2[ReasonCode2["SystemError"] = 15] = "SystemError";
375
+ ReasonCode2[ReasonCode2["ChannelIDError"] = 16] = "ChannelIDError";
376
+ ReasonCode2[ReasonCode2["NodeMatchError"] = 17] = "NodeMatchError";
377
+ ReasonCode2[ReasonCode2["NodeNotMatch"] = 18] = "NodeNotMatch";
378
+ ReasonCode2[ReasonCode2["Ban"] = 19] = "Ban";
379
+ ReasonCode2[ReasonCode2["NotSupportHeader"] = 20] = "NotSupportHeader";
380
+ ReasonCode2[ReasonCode2["ClientKeyIsEmpty"] = 21] = "ClientKeyIsEmpty";
381
+ ReasonCode2[ReasonCode2["RateLimit"] = 22] = "RateLimit";
382
+ ReasonCode2[ReasonCode2["NotSupportChannelType"] = 23] = "NotSupportChannelType";
383
+ ReasonCode2[ReasonCode2["Disband"] = 24] = "Disband";
384
+ ReasonCode2[ReasonCode2["SendBan"] = 25] = "SendBan";
385
+ })(ReasonCode || (exports2.ReasonCode = ReasonCode = {}));
386
+ var DeviceFlag;
387
+ (function(DeviceFlag2) {
388
+ DeviceFlag2[DeviceFlag2["App"] = 0] = "App";
389
+ DeviceFlag2[DeviceFlag2["Web"] = 1] = "Web";
390
+ DeviceFlag2[DeviceFlag2["Desktop"] = 2] = "Desktop";
391
+ })(DeviceFlag || (exports2.WKIMDeviceFlag = exports2.DeviceFlag = DeviceFlag = {}));
392
+ var WKIM2 = class _WKIM {
393
+ constructor(url, auth) {
394
+ this.ws = null;
395
+ this.isConnected = false;
396
+ this.connectionPromise = null;
397
+ this.pingInterval = null;
398
+ this.pingTimeout = null;
399
+ this.PING_INTERVAL_MS = 25 * 1e3;
400
+ this.PONG_TIMEOUT_MS = 10 * 1e3;
401
+ this.pendingRequests = /* @__PURE__ */ new Map();
402
+ this.eventListeners = /* @__PURE__ */ new Map();
403
+ this.reconnectAttempts = 0;
404
+ this.maxReconnectAttempts = 5;
405
+ this.initialReconnectDelay = 1e3;
406
+ this.isReconnecting = false;
407
+ this.manualDisconnect = false;
408
+ this.beforeUnloadHandler = null;
409
+ this.url = url;
410
+ this.auth = auth || {};
411
+ this.sessionId = this.generateUUID();
412
+ if (!this.auth.deviceId || this.auth.deviceId === "") {
413
+ this.auth.deviceId = `web_${this.sessionId.slice(0, 8)}_${Date.now()}`;
414
+ }
415
+ Object.values(Event).forEach((event) => this.eventListeners.set(event, []));
416
+ this.setupBeforeUnloadHandler();
417
+ }
418
+ /**
419
+ * Initializes the WKIM instance.
420
+ * @param url WebSocket server URL (e.g., "ws://localhost:5100")
421
+ * @param auth Authentication options { uid, token, ... }
422
+ * @param options Configuration options { singleton: boolean }
423
+ * @returns A WKIM instance
424
+ */
425
+ static init(url, auth, options = {}) {
426
+ if (!url || !auth || !auth.uid || !auth.token) {
427
+ throw new Error("URL, uid, and token are required for initialization.");
428
+ }
429
+ if (options.singleton && _WKIM.globalInstance) {
430
+ console.log("Destroying previous global instance...");
431
+ _WKIM.globalInstance.destroy();
432
+ }
433
+ const instance2 = new _WKIM(url, auth);
434
+ if (options.singleton !== false) {
435
+ _WKIM.globalInstance = instance2;
436
+ }
437
+ return instance2;
438
+ }
439
+ /**
440
+ * Establishes connection and authenticates with the server.
441
+ * Returns a Promise that resolves on successful connection/authentication,
442
+ * or rejects on failure.
443
+ */
444
+ connect() {
445
+ return new Promise((resolve, reject) => {
446
+ var _a;
447
+ if (this.isConnected || ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WS_CONNECTING) {
448
+ console.warn("Connection already established or in progress.");
449
+ if (this.isConnected) {
450
+ resolve();
451
+ } else if (this.connectionPromise) {
452
+ this.connectionPromise.resolve = resolve;
453
+ this.connectionPromise.reject = reject;
454
+ } else {
455
+ reject(new Error("Already connecting, but no connection promise found."));
456
+ }
457
+ return;
458
+ }
459
+ this.manualDisconnect = false;
460
+ this.connectionPromise = { resolve, reject };
461
+ try {
462
+ console.log(`Connecting to ${this.url}... (Platform: ${currentPlatform})`);
463
+ this.ws = createWebSocket(this.url);
464
+ this.ws.onopen = () => {
465
+ console.log("WebSocket connection opened. Authenticating...");
466
+ this.sendConnectRequest();
467
+ };
468
+ this.ws.onmessage = (event) => {
469
+ this.handleMessage(event.data);
470
+ };
471
+ this.ws.onerror = (event) => {
472
+ const errorMessage = event.message || (event.error ? event.error.message : "WebSocket error");
473
+ console.error("WebSocket error:", errorMessage, event);
474
+ this.emit(Event.Error, event.error || new Error(errorMessage));
475
+ };
476
+ this.ws.onclose = (event) => {
477
+ const wasConnected = this.isConnected;
478
+ console.log(`WebSocket connection closed. Code: ${event.code}, Reason: ${event.reason}`);
479
+ if (this.connectionPromise && !this.isConnected) {
480
+ this.connectionPromise.reject(new Error(`Connection closed before authentication (Code: ${event.code})`));
481
+ }
482
+ this.cleanupConnection();
483
+ this.emit(Event.Disconnect, { code: event.code, reason: event.reason });
484
+ if (wasConnected && !this.manualDisconnect) {
485
+ this.tryReconnect();
486
+ }
487
+ };
488
+ } catch (error) {
489
+ console.error("Failed to create WebSocket:", error);
490
+ this.emit(Event.Error, error);
491
+ if (this.connectionPromise) {
492
+ this.connectionPromise.reject(error);
493
+ this.connectionPromise = null;
494
+ }
495
+ this.cleanupConnection();
496
+ }
497
+ });
498
+ }
499
+ /**
500
+ * Disconnects from the server.
501
+ */
502
+ disconnect() {
503
+ console.log("Manual disconnect initiated.");
504
+ this.manualDisconnect = true;
505
+ this.isReconnecting = false;
506
+ this.cleanupBeforeUnloadHandler();
507
+ this.handleDisconnect(true, "Manual disconnection");
508
+ }
509
+ /**
510
+ * Completely destroys the SDK instance, cleaning up all resources.
511
+ * Call this when you no longer need the SDK instance.
512
+ */
513
+ destroy() {
514
+ console.log("Destroying SDK instance...");
515
+ this.disconnect();
516
+ this.eventListeners.clear();
517
+ this.pendingRequests.clear();
518
+ if (_WKIM.globalInstance === this) {
519
+ _WKIM.globalInstance = null;
520
+ }
521
+ }
522
+ /**
523
+ * Sends a message to a specific channel.
524
+ * @param channelId Target channel ID
525
+ * @param channelType Target channel type (e.g., WKIM.ChannelType.Person)
526
+ * @param payload Message payload (must be a JSON-serializable object)
527
+ * @param options Optional: { clientMsgNo, header, setting, msgKey, expire, topic }
528
+ * @returns Promise resolving with { messageId, messageSeq } on server ack, or rejecting on error.
529
+ */
530
+ send(channelId, channelType, payload, options = {}) {
531
+ if (!this.isConnected || !this.ws || this.ws.readyState !== WS_OPEN) {
532
+ return Promise.reject(new Error("Not connected. Call connect() first."));
533
+ }
534
+ if (typeof payload !== "object" || payload === null) {
535
+ return Promise.reject(new Error("Payload must be a non-null object."));
536
+ }
537
+ const header = options.header || {};
538
+ header.redDot = true;
539
+ const clientMsgNo = options.clientMsgNo || this.generateUUID();
540
+ const params = {
541
+ clientMsgNo,
542
+ channelId,
543
+ channelType,
544
+ payload: this._encodePayloadToBase64(payload),
545
+ header,
546
+ topic: options.topic,
547
+ setting: options.setting
548
+ };
549
+ return this.sendRequest("send", params);
550
+ }
551
+ /**
552
+ * Registers an event listener.
553
+ * @param eventName The event to listen for (e.g., WKIM.Event.Message)
554
+ * @param callback The function to call when the event occurs
555
+ */
556
+ on(eventName, callback) {
557
+ var _a;
558
+ if (this.eventListeners.has(eventName)) {
559
+ (_a = this.eventListeners.get(eventName)) === null || _a === void 0 ? void 0 : _a.push(callback);
560
+ } else {
561
+ console.warn(`Attempted to register listener for unknown event: ${eventName}`);
562
+ }
563
+ }
564
+ /**
565
+ * Removes an event listener.
566
+ * @param eventName The event to stop listening for
567
+ * @param callback The specific callback function to remove
568
+ */
569
+ off(eventName, callback) {
570
+ if (this.eventListeners.has(eventName)) {
571
+ const listeners = this.eventListeners.get(eventName);
572
+ if (listeners) {
573
+ const index = listeners.indexOf(callback);
574
+ if (index > -1) {
575
+ listeners.splice(index, 1);
576
+ }
577
+ }
578
+ }
579
+ }
580
+ // --- Private Methods ---
581
+ emit(eventName, ...args) {
582
+ const listeners = this.eventListeners.get(eventName);
583
+ if (listeners) {
584
+ listeners.forEach((callback) => {
585
+ try {
586
+ callback(...args);
587
+ } catch (error) {
588
+ console.error(`Error in event listener for ${eventName}:`, error);
589
+ }
590
+ });
591
+ }
592
+ }
593
+ generateUUID() {
594
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
595
+ const r = Math.random() * 16 | 0, v = c === "x" ? r : r & 3 | 8;
596
+ return v.toString(16);
597
+ });
598
+ }
599
+ sendConnectRequest() {
600
+ var _a;
601
+ const params = {
602
+ uid: this.auth.uid,
603
+ token: this.auth.token,
604
+ deviceId: this.auth.deviceId,
605
+ deviceFlag: (_a = this.auth.deviceFlag) !== null && _a !== void 0 ? _a : DeviceFlag.Web,
606
+ // Default to WEB
607
+ clientTimestamp: Date.now()
608
+ // Add version, clientKey if needed
609
+ };
610
+ this.sendRequest("connect", params, 5e3).then((result) => {
611
+ console.log("Authentication successful:", result);
612
+ this.isConnected = true;
613
+ this.reconnectAttempts = 0;
614
+ this.isReconnecting = false;
615
+ this.manualDisconnect = false;
616
+ this.startPing();
617
+ this.emit(Event.Connect, result);
618
+ if (this.connectionPromise) {
619
+ this.connectionPromise.resolve();
620
+ this.connectionPromise = null;
621
+ }
622
+ }).catch((error) => {
623
+ console.error("Authentication failed:", error);
624
+ this.emit(Event.Error, new Error(`Authentication failed: ${error.message || JSON.stringify(error)}`));
625
+ if (this.connectionPromise) {
626
+ this.connectionPromise.reject(error);
627
+ this.connectionPromise = null;
628
+ }
629
+ this.handleDisconnect(false, "Authentication failed");
630
+ this.cleanupConnection();
631
+ });
632
+ }
633
+ sendRequest(method, params, timeoutMs = 15e3) {
634
+ return new Promise((resolve, reject) => {
635
+ if (!this.ws || this.ws.readyState !== WS_OPEN) {
636
+ return reject(new Error("WebSocket is not open."));
637
+ }
638
+ const requestId = this.generateUUID();
639
+ const request = {
640
+ method,
641
+ params,
642
+ id: requestId
643
+ };
644
+ const timeoutTimer = setTimeout(() => {
645
+ this.pendingRequests.delete(requestId);
646
+ reject(new Error(`Request timeout for method ${method} (id: ${requestId})`));
647
+ }, timeoutMs);
648
+ this.pendingRequests.set(requestId, { resolve, reject, timeoutTimer });
649
+ try {
650
+ console.debug(`--> Sending request (id: ${requestId}):`, JSON.stringify(request));
651
+ this.ws.send(JSON.stringify(request));
652
+ } catch (error) {
653
+ clearTimeout(timeoutTimer);
654
+ this.pendingRequests.delete(requestId);
655
+ console.error(`Error sending request (id: ${requestId}):`, error);
656
+ reject(error);
657
+ }
658
+ });
659
+ }
660
+ sendNotification(method, params) {
661
+ if (!this.ws || this.ws.readyState !== WS_OPEN) {
662
+ console.error("Cannot send notification, WebSocket is not open.");
663
+ return;
664
+ }
665
+ const notification = {
666
+ method,
667
+ params
668
+ };
669
+ console.debug(`--> Sending notification:`, JSON.stringify(notification));
670
+ try {
671
+ this.ws.send(JSON.stringify(notification));
672
+ } catch (error) {
673
+ console.error(`Error sending notification (${method}):`, error);
674
+ this.emit(Event.Error, new Error(`Failed to send notification ${method}: ${error}`));
675
+ }
676
+ }
677
+ handleMessage(data) {
678
+ console.debug("<-- Received raw:", data);
679
+ let message;
680
+ try {
681
+ message = JSON.parse(data.toString());
682
+ } catch (error) {
683
+ console.error("Failed to parse incoming message:", error, data);
684
+ this.emit(Event.Error, new Error(`Failed to parse message: ${error}`));
685
+ return;
686
+ }
687
+ if ("id" in message) {
688
+ this.handleResponse(message);
689
+ } else if ("method" in message) {
690
+ this.handleNotification(message);
691
+ } else {
692
+ console.warn("Received unknown message format:", message);
693
+ }
694
+ }
695
+ handleResponse(response) {
696
+ console.debug(`<-- Handling response (id: ${response.id}):`, response);
697
+ const pending = this.pendingRequests.get(response.id);
698
+ if (pending) {
699
+ clearTimeout(pending.timeoutTimer);
700
+ this.pendingRequests.delete(response.id);
701
+ if (response.error) {
702
+ pending.reject(response.error);
703
+ } else {
704
+ pending.resolve(response.result);
705
+ }
706
+ } else {
707
+ console.warn(`Received response for unknown request ID: ${response.id}`);
708
+ }
709
+ }
710
+ handleNotification(notification) {
711
+ var _a, _b;
712
+ console.debug(`<-- Handling notification (${notification.method}):`, notification.params);
713
+ switch (notification.method) {
714
+ case "recv":
715
+ const messageData = notification.params;
716
+ if (typeof messageData.payload === "string") {
717
+ try {
718
+ messageData.payload = JSON.parse(this._decodeBase64ToStr(messageData.payload));
719
+ } catch (e) {
720
+ }
721
+ }
722
+ this.emit(Event.Message, messageData);
723
+ this.sendRecvAck(messageData.header, messageData.messageId, messageData.messageSeq);
724
+ break;
725
+ case "pong":
726
+ this.handlePong();
727
+ break;
728
+ case "disconnect":
729
+ console.warn("Server initiated disconnect:", notification.params);
730
+ this.emit(Event.Disconnect, notification.params);
731
+ this.handleDisconnect(false, `Server disconnected: ${((_a = notification.params) === null || _a === void 0 ? void 0 : _a.reason) || ((_b = notification.params) === null || _b === void 0 ? void 0 : _b.reasonCode)}`);
732
+ break;
733
+ case "event":
734
+ this.handleEventNotification(notification.params);
735
+ break;
736
+ // Handle other notifications if needed
737
+ default:
738
+ console.warn(`Received unhandled notification method: ${notification.method}`);
739
+ }
740
+ }
741
+ /**
742
+ * Encode payload object to base64 string.
743
+ * WuKongIM server expects payload as []byte (base64 in JSON).
744
+ */
745
+ _encodePayloadToBase64(payload) {
746
+ const json = JSON.stringify(payload);
747
+ if (typeof TextEncoder !== "undefined" && typeof btoa !== "undefined") {
748
+ const bytes = new TextEncoder().encode(json);
749
+ let binary = "";
750
+ for (let i = 0; i < bytes.length; i++) {
751
+ binary += String.fromCharCode(bytes[i]);
752
+ }
753
+ return btoa(binary);
754
+ }
755
+ if (typeof Buffer !== "undefined") {
756
+ return Buffer.from(json, "utf-8").toString("base64");
757
+ }
758
+ if (typeof wx !== "undefined" && (wx === null || wx === void 0 ? void 0 : wx.arrayBufferToBase64)) {
759
+ const encoder = new TextEncoder();
760
+ const bytes = encoder.encode(json);
761
+ return wx.arrayBufferToBase64(bytes.buffer);
762
+ }
763
+ throw new Error("No base64 encoding method available");
764
+ }
765
+ /**
766
+ * Decode base64 string to UTF-8 string.
767
+ */
768
+ _decodeBase64ToStr(base64Str) {
769
+ if (typeof atob !== "undefined" && typeof TextDecoder !== "undefined") {
770
+ const binary = atob(base64Str);
771
+ const bytes = new Uint8Array(binary.length);
772
+ for (let i = 0; i < binary.length; i++) {
773
+ bytes[i] = binary.charCodeAt(i);
774
+ }
775
+ return new TextDecoder().decode(bytes);
776
+ }
777
+ if (typeof Buffer !== "undefined") {
778
+ return Buffer.from(base64Str, "base64").toString("utf-8");
779
+ }
780
+ if (typeof wx !== "undefined" && (wx === null || wx === void 0 ? void 0 : wx.base64ToArrayBuffer)) {
781
+ const buf = wx.base64ToArrayBuffer(base64Str);
782
+ return new TextDecoder().decode(new Uint8Array(buf));
783
+ }
784
+ throw new Error("No base64 decoding method available");
785
+ }
786
+ sendRecvAck(header, messageId, messageSeq) {
787
+ const params = { header, messageId, messageSeq };
788
+ this.sendNotification("recvack", params);
789
+ }
790
+ /**
791
+ * Handles incoming event notifications from the server
792
+ * @param params Event notification parameters
793
+ */
794
+ handleEventNotification(params) {
795
+ try {
796
+ const eventData = {
797
+ header: params.header,
798
+ id: params.id,
799
+ type: params.type,
800
+ timestamp: params.timestamp,
801
+ data: params.data
802
+ };
803
+ if (!eventData.id || !eventData.type) {
804
+ console.error("Invalid event notification: missing required fields", params);
805
+ this.emit(Event.Error, new Error("Invalid event notification: missing required fields"));
806
+ return;
807
+ }
808
+ if (typeof eventData.data === "string") {
809
+ try {
810
+ eventData.data = JSON.parse(eventData.data);
811
+ } catch (e) {
812
+ console.debug("Event data is not JSON, keeping as string");
813
+ }
814
+ }
815
+ console.log(`Event notification received: type=${eventData.type}, id=${eventData.id}`);
816
+ this.emit(Event.CustomEvent, eventData);
817
+ } catch (error) {
818
+ console.error("Error handling event notification:", error);
819
+ this.emit(Event.Error, new Error(`Failed to handle event notification: ${error}`));
820
+ }
821
+ }
822
+ startPing() {
823
+ this.stopPing();
824
+ this.pingInterval = setInterval(() => {
825
+ if (this.ws && this.ws.readyState === WS_OPEN) {
826
+ this.sendRequest("ping", {}, this.PONG_TIMEOUT_MS).then(this.handlePong.bind(this)).catch((err) => {
827
+ console.error("Ping failed or timed out:", err);
828
+ this.emit(Event.Error, new Error(`Ping timeout: ${(err === null || err === void 0 ? void 0 : err.message) || err}`));
829
+ if (!this.manualDisconnect) {
830
+ this.handleDisconnect(false, "Ping timeout");
831
+ this.tryReconnect();
832
+ }
833
+ });
834
+ } else {
835
+ this.stopPing();
836
+ }
837
+ }, this.PING_INTERVAL_MS);
838
+ console.log(`Ping interval started (${this.PING_INTERVAL_MS}ms).`);
839
+ }
840
+ stopPing() {
841
+ if (this.pingInterval) {
842
+ clearInterval(this.pingInterval);
843
+ this.pingInterval = null;
844
+ console.log("Ping interval stopped.");
845
+ }
846
+ if (this.pingTimeout) {
847
+ clearTimeout(this.pingTimeout);
848
+ this.pingTimeout = null;
849
+ }
850
+ }
851
+ handlePong() {
852
+ }
853
+ handleDisconnect(graceful, reason) {
854
+ console.log(`Handling disconnect. Graceful: ${graceful}, Reason: ${reason}`);
855
+ if (this.ws) {
856
+ this.stopPing();
857
+ if (graceful && this.ws.readyState === WS_OPEN) {
858
+ this.ws.close(1e3, "Client disconnected");
859
+ } else if (this.ws.readyState === WS_CONNECTING || this.ws.readyState === WS_OPEN) {
860
+ this.ws.close(3001, reason.substring(0, 123));
861
+ }
862
+ }
863
+ this.cleanupConnection();
864
+ }
865
+ cleanupConnection() {
866
+ console.log("Cleaning up connection resources.");
867
+ this.isConnected = false;
868
+ this.stopPing();
869
+ this.pendingRequests.forEach((pending) => {
870
+ clearTimeout(pending.timeoutTimer);
871
+ pending.reject(new Error("Connection closed"));
872
+ });
873
+ this.pendingRequests.clear();
874
+ if (this.connectionPromise) {
875
+ if (!this.isReconnecting && !this.isConnected) {
876
+ this.connectionPromise.reject(new Error("Connection closed during operation"));
877
+ }
878
+ this.connectionPromise = null;
879
+ }
880
+ if (this.ws) {
881
+ this.ws.onopen = null;
882
+ this.ws.onmessage = null;
883
+ this.ws.onerror = null;
884
+ this.ws.onclose = null;
885
+ }
886
+ }
887
+ // --- Reconnection Methods ---
888
+ setupBeforeUnloadHandler() {
889
+ if (typeof window !== "undefined") {
890
+ this.beforeUnloadHandler = () => {
891
+ console.log("Page unloading, closing WebSocket connection...");
892
+ this.manualDisconnect = true;
893
+ this.isReconnecting = false;
894
+ if (this.ws && this.ws.readyState === WS_OPEN) {
895
+ this.ws.close(1e3, "Page unloaded");
896
+ }
897
+ };
898
+ window.addEventListener("beforeunload", this.beforeUnloadHandler);
899
+ window.addEventListener("pagehide", this.beforeUnloadHandler);
900
+ }
901
+ }
902
+ cleanupBeforeUnloadHandler() {
903
+ if (typeof window !== "undefined" && this.beforeUnloadHandler) {
904
+ window.removeEventListener("beforeunload", this.beforeUnloadHandler);
905
+ window.removeEventListener("pagehide", this.beforeUnloadHandler);
906
+ this.beforeUnloadHandler = null;
907
+ }
908
+ }
909
+ tryReconnect() {
910
+ if (this.isReconnecting || this.manualDisconnect) {
911
+ return;
912
+ }
913
+ this.isReconnecting = true;
914
+ this.scheduleReconnect();
915
+ }
916
+ scheduleReconnect() {
917
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
918
+ console.error("Max reconnect attempts reached. Giving up.");
919
+ this.isReconnecting = false;
920
+ this.reconnectAttempts = 0;
921
+ this.emit(Event.Error, new Error("Reconnection failed."));
922
+ return;
923
+ }
924
+ const delay = this.initialReconnectDelay * Math.pow(2, this.reconnectAttempts);
925
+ this.reconnectAttempts++;
926
+ console.log(`Will attempt to reconnect in ${delay / 1e3}s (Attempt ${this.reconnectAttempts}).`);
927
+ this.emit(Event.Reconnecting, { attempt: this.reconnectAttempts, delay });
928
+ setTimeout(() => {
929
+ if (!this.isReconnecting) {
930
+ console.log("Reconnection aborted.");
931
+ return;
932
+ }
933
+ this.connect().catch(() => {
934
+ if (this.isReconnecting) {
935
+ this.scheduleReconnect();
936
+ }
937
+ });
938
+ }, delay);
939
+ }
940
+ };
941
+ exports2.WKIM = WKIM2;
942
+ WKIM2.globalInstance = null;
113
943
  }
114
- }
944
+ });
115
945
 
116
- WuKongIMService.prototype.connect = function () {
117
- if (!this._im) throw new Error('WuKongIMService not initialized')
118
- this._emitStatus('connecting')
119
- return this._im.connect()
946
+ // miniprogram_dist/services/wukongim.js
947
+ var WKIM = require_cjs().WKIM;
948
+ var WKIMEvent = require_cjs().WKIMEvent;
949
+ var adapter = require("../adapters/request");
950
+ function WuKongIMService() {
951
+ this._inited = false;
952
+ this._im = null;
953
+ this._cfg = null;
954
+ this._uid = null;
955
+ this._bound = false;
956
+ this._hConnect = null;
957
+ this._hDisconnect = null;
958
+ this._hError = null;
959
+ this._hMessage = null;
960
+ this._hCustom = null;
961
+ this._msgListeners = [];
962
+ this._statusListeners = [];
963
+ this._customListeners = [];
120
964
  }
121
-
122
- WuKongIMService.prototype.disconnect = function () {
123
- if (!this._im) return Promise.resolve()
124
- if (typeof this._im.disconnect === 'function') {
125
- try { return this._im.disconnect() } catch (e) { return Promise.resolve() }
965
+ WuKongIMService.prototype.isReady = function() {
966
+ return this._inited && !!this._im && !!this._cfg;
967
+ };
968
+ WuKongIMService.prototype.getUid = function() {
969
+ return this._uid;
970
+ };
971
+ WuKongIMService.prototype.init = function(opts) {
972
+ var self = this;
973
+ this._cfg = Object.assign({}, opts, { channelType: opts.channelType || "person" });
974
+ this._uid = opts.uid;
975
+ return this._fetchRouteWsAddr(opts.apiBase, opts.uid, 1e4).then(function(wsAddr) {
976
+ if (self._im && self._bound) {
977
+ try {
978
+ self._unbindInternalEvents();
979
+ } catch (e) {
980
+ }
981
+ }
982
+ self._im = WKIM.init(wsAddr, { uid: opts.uid, token: opts.token || "" });
983
+ self._bindInternalEvents();
984
+ self._inited = true;
985
+ });
986
+ };
987
+ WuKongIMService.prototype._bindInternalEvents = function() {
988
+ if (!this._im || this._bound) return;
989
+ var self = this;
990
+ this._hConnect = function(result) {
991
+ self._emitStatus("connected", result);
992
+ };
993
+ this._hDisconnect = function(info) {
994
+ self._emitStatus("disconnected", info);
995
+ };
996
+ this._hError = function(err) {
997
+ self._emitStatus("error", err);
998
+ };
999
+ this._hMessage = function(message) {
1000
+ self._emitMessage(message);
1001
+ };
1002
+ this._hCustom = function(ev) {
1003
+ self._emitCustom(ev);
1004
+ };
1005
+ this._im.on(WKIMEvent.Connect, this._hConnect);
1006
+ this._im.on(WKIMEvent.Disconnect, this._hDisconnect);
1007
+ this._im.on(WKIMEvent.Error, this._hError);
1008
+ this._im.on(WKIMEvent.Message, this._hMessage);
1009
+ this._im.on(WKIMEvent.CustomEvent, this._hCustom);
1010
+ this._bound = true;
1011
+ };
1012
+ WuKongIMService.prototype._unbindInternalEvents = function() {
1013
+ if (!this._im || !this._bound) return;
1014
+ if (this._hConnect) this._im.off(WKIMEvent.Connect, this._hConnect);
1015
+ if (this._hDisconnect) this._im.off(WKIMEvent.Disconnect, this._hDisconnect);
1016
+ if (this._hError) this._im.off(WKIMEvent.Error, this._hError);
1017
+ if (this._hMessage) this._im.off(WKIMEvent.Message, this._hMessage);
1018
+ if (this._hCustom) this._im.off(WKIMEvent.CustomEvent, this._hCustom);
1019
+ this._hConnect = this._hDisconnect = this._hError = this._hMessage = this._hCustom = null;
1020
+ this._bound = false;
1021
+ };
1022
+ WuKongIMService.prototype._emitMessage = function(m) {
1023
+ this._msgListeners.forEach(function(fn) {
1024
+ try {
1025
+ fn(m);
1026
+ } catch (e) {
1027
+ }
1028
+ });
1029
+ };
1030
+ WuKongIMService.prototype._emitStatus = function(s, info) {
1031
+ this._statusListeners.forEach(function(fn) {
1032
+ try {
1033
+ fn(s, info);
1034
+ } catch (e) {
1035
+ }
1036
+ });
1037
+ };
1038
+ WuKongIMService.prototype._emitCustom = function(e) {
1039
+ this._customListeners.forEach(function(fn) {
1040
+ try {
1041
+ fn(e);
1042
+ } catch (e2) {
1043
+ }
1044
+ });
1045
+ };
1046
+ WuKongIMService.prototype.onMessage = function(cb) {
1047
+ this._msgListeners.push(cb);
1048
+ var self = this;
1049
+ return function() {
1050
+ var idx = self._msgListeners.indexOf(cb);
1051
+ if (idx >= 0) self._msgListeners.splice(idx, 1);
1052
+ };
1053
+ };
1054
+ WuKongIMService.prototype.onStatus = function(cb) {
1055
+ this._statusListeners.push(cb);
1056
+ var self = this;
1057
+ return function() {
1058
+ var idx = self._statusListeners.indexOf(cb);
1059
+ if (idx >= 0) self._statusListeners.splice(idx, 1);
1060
+ };
1061
+ };
1062
+ WuKongIMService.prototype.onCustom = function(cb) {
1063
+ this._customListeners.push(cb);
1064
+ var self = this;
1065
+ return function() {
1066
+ var idx = self._customListeners.indexOf(cb);
1067
+ if (idx >= 0) self._customListeners.splice(idx, 1);
1068
+ };
1069
+ };
1070
+ WuKongIMService.prototype.connect = function() {
1071
+ if (!this._im) throw new Error("WuKongIMService not initialized");
1072
+ this._emitStatus("connecting");
1073
+ return this._im.connect();
1074
+ };
1075
+ WuKongIMService.prototype.disconnect = function() {
1076
+ if (!this._im) return Promise.resolve();
1077
+ if (typeof this._im.disconnect === "function") {
1078
+ try {
1079
+ return this._im.disconnect();
1080
+ } catch (e) {
1081
+ return Promise.resolve();
1082
+ }
126
1083
  }
127
- return Promise.resolve()
128
- }
129
-
130
- WuKongIMService.prototype._fetchRouteWsAddr = function (apiBase, uid, timeoutMs) {
131
- var base = apiBase.endsWith('/') ? apiBase : apiBase + '/'
132
- var url = base + 'v1/wukongim/route?uid=' + encodeURIComponent(uid)
133
-
1084
+ return Promise.resolve();
1085
+ };
1086
+ WuKongIMService.prototype._fetchRouteWsAddr = function(apiBase, uid, timeoutMs) {
1087
+ var base = apiBase.endsWith("/") ? apiBase : apiBase + "/";
1088
+ var url = base + "v1/wukongim/route?uid=" + encodeURIComponent(uid);
134
1089
  return adapter.request({
135
- url: url,
136
- method: 'GET',
137
- timeout: timeoutMs || 10000
138
- }).then(function (res) {
139
- if (!res.ok) throw new Error('route HTTP ' + res.status)
140
- return res.json().then(function (data) {
141
- // Priority 1: wss_addr
142
- if (data && data.wss_addr && typeof data.wss_addr === 'string' && data.wss_addr.trim()) {
143
- return data.wss_addr.trim()
144
- }
145
- // Priority 2: ws_addr fallbacks
146
- var addr = data.ws_addr || data.ws || data.ws_url || data.wsAddr || data.websocket
147
- if (!addr && data.wss) addr = data.wss
148
- if (!addr || typeof addr !== 'string') throw new Error('missing ws address')
149
- var wsAddr = String(addr)
150
- if (/^http(s)?:/i.test(wsAddr)) wsAddr = wsAddr.replace(/^http/i, 'ws')
151
- return wsAddr
152
- })
153
- }).catch(function (e) {
154
- var msg = e && e.message ? String(e.message) : String(e)
155
- throw new Error('[WuKongIM] route fetch failed: ' + msg)
156
- })
157
- }
158
-
159
- WuKongIMService.prototype.sendText = function (text, opts) {
160
- if (!this._im || !this._cfg) throw new Error('WuKongIMService not ready')
161
- opts = opts || {}
162
- var to = opts.to || this._cfg.target
163
- var payload = { type: 1, content: text }
1090
+ url,
1091
+ method: "GET",
1092
+ timeout: timeoutMs || 1e4
1093
+ }).then(function(res) {
1094
+ if (!res.ok) throw new Error("route HTTP " + res.status);
1095
+ return res.json().then(function(data) {
1096
+ if (data && data.wss_addr && typeof data.wss_addr === "string" && data.wss_addr.trim()) {
1097
+ return data.wss_addr.trim();
1098
+ }
1099
+ var addr = data.ws_addr || data.ws || data.ws_url || data.wsAddr || data.websocket;
1100
+ if (!addr && data.wss) addr = data.wss;
1101
+ if (!addr || typeof addr !== "string") throw new Error("missing ws address");
1102
+ var wsAddr = String(addr);
1103
+ if (/^http(s)?:/i.test(wsAddr)) wsAddr = wsAddr.replace(/^http/i, "ws");
1104
+ return wsAddr;
1105
+ });
1106
+ }).catch(function(e) {
1107
+ var msg = e && e.message ? String(e.message) : String(e);
1108
+ throw new Error("[WuKongIM] route fetch failed: " + msg);
1109
+ });
1110
+ };
1111
+ WuKongIMService.prototype.sendText = function(text, opts) {
1112
+ if (!this._im || !this._cfg) throw new Error("WuKongIMService not ready");
1113
+ opts = opts || {};
1114
+ var to = opts.to || this._cfg.target;
1115
+ var payload = { type: 1, content: text };
164
1116
  return this._im.send(to, opts.channelType || 251, payload, {
165
1117
  clientMsgNo: opts.clientMsgNo,
166
1118
  header: opts.header
167
- })
168
- }
169
-
170
- WuKongIMService.prototype.sendPayload = function (payload, opts) {
171
- if (!this._im || !this._cfg) throw new Error('WuKongIMService not ready')
172
- opts = opts || {}
173
- var to = opts.to || this._cfg.target
1119
+ });
1120
+ };
1121
+ WuKongIMService.prototype.sendPayload = function(payload, opts) {
1122
+ if (!this._im || !this._cfg) throw new Error("WuKongIMService not ready");
1123
+ opts = opts || {};
1124
+ var to = opts.to || this._cfg.target;
174
1125
  return this._im.send(to, opts.channelType || 251, payload, {
175
1126
  clientMsgNo: opts.clientMsgNo,
176
1127
  header: opts.header
177
- })
178
- }
179
-
180
- // Singleton
181
- var instance = new WuKongIMService()
182
-
183
- module.exports = instance
1128
+ });
1129
+ };
1130
+ var instance = new WuKongIMService();
1131
+ module.exports = instance;