ly-utils-lib 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3329,6 +3329,341 @@ var pbkdf2 = (password, salt, iterations = 1e3, keySize = 32) => {
3329
3329
  var uuid2 = () => {
3330
3330
  return CryptoJS__namespace.lib.WordArray.random(16).toString();
3331
3331
  };
3332
+
3333
+ // src/modules/websocket/index.ts
3334
+ var websocket_exports = {};
3335
+ __export(websocket_exports, {
3336
+ WebSocketClient: () => WebSocketClient,
3337
+ WebSocketState: () => WebSocketState,
3338
+ createWebSocket: () => createWebSocket,
3339
+ default: () => websocket_default,
3340
+ quickConnect: () => quickConnect
3341
+ });
3342
+ var WebSocketState = /* @__PURE__ */ ((WebSocketState2) => {
3343
+ WebSocketState2[WebSocketState2["CONNECTING"] = 0] = "CONNECTING";
3344
+ WebSocketState2[WebSocketState2["OPEN"] = 1] = "OPEN";
3345
+ WebSocketState2[WebSocketState2["CLOSING"] = 2] = "CLOSING";
3346
+ WebSocketState2[WebSocketState2["CLOSED"] = 3] = "CLOSED";
3347
+ return WebSocketState2;
3348
+ })(WebSocketState || {});
3349
+ var WebSocketClient = class {
3350
+ constructor(options) {
3351
+ this.ws = null;
3352
+ this.handlers = {};
3353
+ this.reconnectTimer = null;
3354
+ this.heartbeatTimer = null;
3355
+ this.heartbeatTimeoutTimer = null;
3356
+ this.reconnectCount = 0;
3357
+ this.isManualDisconnect = false;
3358
+ this.messageQueue = [];
3359
+ this.connectResolve = null;
3360
+ this.connectReject = null;
3361
+ this.options = {
3362
+ url: options.url,
3363
+ protocol: options.protocol || (options.url.startsWith("https") ? "wss" : "ws"),
3364
+ protocols: options.protocols || [],
3365
+ autoReconnect: options.autoReconnect ?? true,
3366
+ reconnectAttempts: options.reconnectAttempts ?? 3,
3367
+ reconnectInterval: options.reconnectInterval ?? 3e3,
3368
+ heartbeatInterval: options.heartbeatInterval ?? 3e4,
3369
+ heartbeatMessage: options.heartbeatMessage ?? "ping",
3370
+ heartbeatTimeout: options.heartbeatTimeout ?? 5e3,
3371
+ connectTimeout: options.connectTimeout ?? 1e4,
3372
+ debug: options.debug ?? true
3373
+ };
3374
+ if (options.autoReconnect !== false) {
3375
+ this.connect();
3376
+ }
3377
+ }
3378
+ /**
3379
+ * 连接 WebSocket
3380
+ */
3381
+ connect() {
3382
+ if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
3383
+ this.log("WebSocket already connected or connecting");
3384
+ return;
3385
+ }
3386
+ this.isManualDisconnect = false;
3387
+ this.reconnectCount = 0;
3388
+ const protocol = this.options.url.startsWith("ws://") || this.options.url.startsWith("wss://") ? "" : `${this.options.protocol}://`;
3389
+ const wsUrl = protocol ? `${protocol}${this.options.url}` : this.options.url;
3390
+ this.log(`Connecting to ${wsUrl}`);
3391
+ try {
3392
+ this.ws = new WebSocket(wsUrl, this.options.protocols);
3393
+ this.setupEventHandlers();
3394
+ setTimeout(() => {
3395
+ if (this.ws && this.ws.readyState === WebSocket.CONNECTING) {
3396
+ this.ws.close();
3397
+ this.log("Connection timeout");
3398
+ if (this.connectReject) {
3399
+ this.connectReject(new Error("Connection timeout"));
3400
+ this.connectResolve = null;
3401
+ this.connectReject = null;
3402
+ }
3403
+ }
3404
+ }, this.options.connectTimeout);
3405
+ } catch (error) {
3406
+ this.log("Connection failed:", error);
3407
+ this.handleError(error);
3408
+ }
3409
+ }
3410
+ /**
3411
+ * 断开连接
3412
+ */
3413
+ disconnect() {
3414
+ this.isManualDisconnect = true;
3415
+ this.cleanup();
3416
+ if (this.ws) {
3417
+ this.ws.close();
3418
+ this.ws = null;
3419
+ }
3420
+ this.log("Disconnected manually");
3421
+ }
3422
+ /**
3423
+ * 发送消息(异步)
3424
+ */
3425
+ async send(data) {
3426
+ if (!this.isConnected()) {
3427
+ return new Promise((resolve, reject) => {
3428
+ this.messageQueue.push(data);
3429
+ const checkConnection = () => {
3430
+ if (this.isConnected()) {
3431
+ this.sendSync(data);
3432
+ resolve();
3433
+ } else if (!this.ws) {
3434
+ reject(new Error("WebSocket is not connected"));
3435
+ } else {
3436
+ setTimeout(checkConnection, 100);
3437
+ }
3438
+ };
3439
+ checkConnection();
3440
+ });
3441
+ }
3442
+ this.sendSync(data);
3443
+ }
3444
+ /**
3445
+ * 发送消息(同步)
3446
+ */
3447
+ sendSync(data) {
3448
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
3449
+ this.log("WebSocket is not connected, message queued");
3450
+ this.messageQueue.push(data);
3451
+ return;
3452
+ }
3453
+ try {
3454
+ const message = typeof data === "object" ? JSON.stringify(data) : data;
3455
+ this.ws.send(message);
3456
+ this.log("Message sent:", message);
3457
+ } catch (error) {
3458
+ this.log("Send error:", error);
3459
+ this.handleError(error);
3460
+ }
3461
+ }
3462
+ /**
3463
+ * 获取连接状态
3464
+ */
3465
+ getState() {
3466
+ return this.ws?.readyState ?? 3 /* CLOSED */;
3467
+ }
3468
+ /**
3469
+ * 是否已连接
3470
+ */
3471
+ isConnected() {
3472
+ return this.ws?.readyState === WebSocket.OPEN;
3473
+ }
3474
+ /**
3475
+ * 获取 WebSocket 实例
3476
+ */
3477
+ getInstance() {
3478
+ return this.ws;
3479
+ }
3480
+ /**
3481
+ * 设置事件处理器
3482
+ */
3483
+ on(event, handler) {
3484
+ this.handlers[event] = handler;
3485
+ }
3486
+ /**
3487
+ * 移除事件处理器
3488
+ */
3489
+ off(event, handler) {
3490
+ if (!handler || this.handlers[event] === handler) {
3491
+ delete this.handlers[event];
3492
+ }
3493
+ }
3494
+ /**
3495
+ * 重新连接
3496
+ */
3497
+ reconnect() {
3498
+ this.disconnect();
3499
+ this.reconnectCount = 0;
3500
+ this.isManualDisconnect = false;
3501
+ this.connect();
3502
+ }
3503
+ /**
3504
+ * 设置事件处理器
3505
+ */
3506
+ setupEventHandlers() {
3507
+ if (!this.ws) return;
3508
+ this.ws.onopen = (event) => {
3509
+ this.log("Connected");
3510
+ this.reconnectCount = 0;
3511
+ while (this.messageQueue.length > 0) {
3512
+ const message = this.messageQueue.shift();
3513
+ if (message) {
3514
+ this.sendSync(message);
3515
+ }
3516
+ }
3517
+ this.startHeartbeat();
3518
+ if (this.handlers.onOpen) {
3519
+ this.handlers.onOpen(event);
3520
+ }
3521
+ if (this.connectResolve) {
3522
+ this.connectResolve();
3523
+ this.connectResolve = null;
3524
+ this.connectReject = null;
3525
+ }
3526
+ };
3527
+ this.ws.onmessage = (event) => {
3528
+ this.log("Message received:", event.data);
3529
+ let data = event.data;
3530
+ if (typeof event.data === "string") {
3531
+ try {
3532
+ data = JSON.parse(event.data);
3533
+ } catch {
3534
+ }
3535
+ }
3536
+ if (this.handlers.onMessage) {
3537
+ this.handlers.onMessage(data, event);
3538
+ }
3539
+ };
3540
+ this.ws.onclose = (event) => {
3541
+ this.log("Connection closed:", event.code, event.reason);
3542
+ this.cleanup();
3543
+ if (this.handlers.onClose) {
3544
+ this.handlers.onClose(event);
3545
+ }
3546
+ if (!this.isManualDisconnect && this.options.autoReconnect) {
3547
+ this.attemptReconnect();
3548
+ }
3549
+ };
3550
+ this.ws.onerror = (event) => {
3551
+ this.log("Error:", event);
3552
+ if (this.handlers.onError) {
3553
+ this.handlers.onError(event);
3554
+ }
3555
+ };
3556
+ }
3557
+ /**
3558
+ * 尝试重连
3559
+ */
3560
+ attemptReconnect() {
3561
+ if (this.reconnectCount >= this.options.reconnectAttempts) {
3562
+ this.log("Reconnect failed, max attempts reached");
3563
+ this.cleanup();
3564
+ if (this.handlers.onReconnectFailed) {
3565
+ this.handlers.onReconnectFailed();
3566
+ }
3567
+ if (this.connectReject) {
3568
+ this.connectReject(new Error("Reconnect failed"));
3569
+ this.connectResolve = null;
3570
+ this.connectReject = null;
3571
+ }
3572
+ return;
3573
+ }
3574
+ this.reconnectCount++;
3575
+ this.log(`Reconnecting... Attempt ${this.reconnectCount}/${this.options.reconnectAttempts}`);
3576
+ if (this.handlers.onReconnect) {
3577
+ this.handlers.onReconnect(this.reconnectCount);
3578
+ }
3579
+ this.reconnectTimer = setTimeout(() => {
3580
+ this.connect();
3581
+ }, this.options.reconnectInterval);
3582
+ }
3583
+ /**
3584
+ * 启动心跳
3585
+ */
3586
+ startHeartbeat() {
3587
+ this.stopHeartbeat();
3588
+ this.heartbeatTimer = setInterval(() => {
3589
+ if (this.isConnected()) {
3590
+ const message = this.options.heartbeatMessage;
3591
+ this.log("Sending heartbeat");
3592
+ if (this.handlers.onHeartbeat) {
3593
+ this.handlers.onHeartbeat();
3594
+ }
3595
+ this.sendSync(message);
3596
+ this.heartbeatTimeoutTimer = setTimeout(() => {
3597
+ this.log("Heartbeat timeout");
3598
+ if (this.handlers.onHeartbeatTimeout) {
3599
+ this.handlers.onHeartbeatTimeout();
3600
+ }
3601
+ if (this.ws) {
3602
+ this.ws.close();
3603
+ }
3604
+ }, this.options.heartbeatTimeout);
3605
+ }
3606
+ }, this.options.heartbeatInterval);
3607
+ }
3608
+ /**
3609
+ * 停止心跳
3610
+ */
3611
+ stopHeartbeat() {
3612
+ if (this.heartbeatTimer) {
3613
+ clearInterval(this.heartbeatTimer);
3614
+ this.heartbeatTimer = null;
3615
+ }
3616
+ if (this.heartbeatTimeoutTimer) {
3617
+ clearTimeout(this.heartbeatTimeoutTimer);
3618
+ this.heartbeatTimeoutTimer = null;
3619
+ }
3620
+ }
3621
+ /**
3622
+ * 清理资源
3623
+ */
3624
+ cleanup() {
3625
+ this.stopHeartbeat();
3626
+ if (this.reconnectTimer) {
3627
+ clearTimeout(this.reconnectTimer);
3628
+ this.reconnectTimer = null;
3629
+ }
3630
+ }
3631
+ /**
3632
+ * 处理错误
3633
+ */
3634
+ handleError(error) {
3635
+ this.log("Error:", error.message);
3636
+ if (this.handlers.onError) {
3637
+ this.handlers.onError(new ErrorEvent("error", { error }));
3638
+ }
3639
+ }
3640
+ /**
3641
+ * 日志输出
3642
+ */
3643
+ log(...args) {
3644
+ if (this.options.debug) {
3645
+ console.log("[WebSocket]", ...args);
3646
+ }
3647
+ }
3648
+ };
3649
+ function createWebSocket(options) {
3650
+ return new WebSocketClient(options);
3651
+ }
3652
+ function quickConnect(url, handlers) {
3653
+ const client = new WebSocketClient({ url, autoReconnect: true });
3654
+ if (handlers) {
3655
+ Object.entries(handlers).forEach(([event, handler]) => {
3656
+ client.on(event, handler);
3657
+ });
3658
+ }
3659
+ return client;
3660
+ }
3661
+ var websocket_default = {
3662
+ WebSocketClient,
3663
+ createWebSocket,
3664
+ quickConnect,
3665
+ WebSocketState
3666
+ };
3332
3667
  /**
3333
3668
  * Utils Toolkit
3334
3669
  * 一个功能强大的 JavaScript/TypeScript 工具函数库
@@ -3351,5 +3686,6 @@ exports.pdf = pdf_exports;
3351
3686
  exports.storage = storage_exports;
3352
3687
  exports.string = string_exports;
3353
3688
  exports.utils = utils_exports;
3689
+ exports.websocket = websocket_exports;
3354
3690
  //# sourceMappingURL=index.cjs.map
3355
3691
  //# sourceMappingURL=index.cjs.map