You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

j-queue-sdk-web

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

j-queue-sdk-web - npm Package Compare versions

Comparing version

to
1.0.25

2

dist/j-queue-sdk-web.js

@@ -1,2 +0,2 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ConnectionJQueueSdkWeb=e():t.ConnectionJQueueSdkWeb=e()}(this,(()=>(()=>{"use strict";var t={156:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(s,o){function a(t){try{l(i.next(t))}catch(t){o(t)}}function r(t){try{l(i.throw(t))}catch(t){o(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,r)}l((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0});const s=n(613);class o{static log(t,e="info",n){("error"===e?console.error:"warn"===e?console.warn:console.log)(`[J-Queue] ${t}`,null!=n?n:"")}static injectStyles(t){if("undefined"==typeof document||document.querySelector("style[data-jqueue-styles]"))return;const e=document.createElement("style");e.dataset.jqueueStyles="",e.textContent=this.CONFIG.STYLES.LOADER(t),document.head.appendChild(e)}static createPopup(t,e){if("undefined"==typeof document)return;this.removePopup();const n=document.createElement("div");n.id="__jqueue_popup",n.style.cssText=null!=e?e:this.CONFIG.STYLES.POPUP,n.innerHTML=t,document.body.appendChild(n),this.state.popupEl=n}static removePopup(){var t;"undefined"!=typeof document&&(null===(t=this.state.popupEl)||void 0===t||t.remove(),this.state.popupEl=null)}static toggleNavigation(t){"undefined"!=typeof window&&this.state.isNavigating!==t&&(window.onbeforeunload=t?()=>{var t;return(null===(t=this.state.queueStatus)||void 0===t?void 0:t.uuid)&&this.state.apiUrl&&this.sendLeaveRequest(),"Navigation is currently blocked."}:null,this.state.isNavigating=t)}static sendLeaveRequest(){const{apiUrl:t,queueStatus:e}=this.state;if(t&&(null==e?void 0:e.uuid))try{const n=JSON.stringify({uuid:e.uuid});navigator.sendBeacon(`${t}${this.CONFIG.API_ENDPOINTS.LEAVE}`,n)}catch(t){this.log("Leave API (sendBeacon) failed","error",t)}}static getDefaultPopupContent(t,e="ko",n){var i;const s=this.CONFIG.MESSAGES[e],o=null!==(i=null==n?void 0:n.textColor)&&void 0!==i?i:"#276bff";return`\n <div style="display: flex; flex-direction: column; align-items: center; width: 100%;">\n <div style="padding: 20px; text-align: center;">\n <p style="font-size: 18px; line-height: 1.5; margin: 0 0 20px 0; color: ${o};">\n ${s.MESS_1}<br>${s.MESS_2}\n </p>\n <div style="position: relative; width: 150px; height: 150px; margin: 20px auto;">\n <span style="position: absolute; inset: 0;" class="loader-jqueue_popup"></span>\n <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center;">\n <div style="font-size: 14px; color: ${o};">${s.MESS_3}</div>\n <div style="font-size: 36px; color: ${o}; font-weight: bold;">${t}</div>\n </div>\n </div>\n </div>\n </div>\n `}static getAdjustedPollInterval(t,e){return t>=100?e+t/100*1e3:e}static handleStatusUpdate(t,e,n){var i,o;if(!(null==t?void 0:t.data))return void this.log("Invalid status response received","warn");const{status:a,position:r,uuid:l}=t.data;this.state.queueStatus={status:a,position:r,uuid:l},this.state.storageKey&&"undefined"!=typeof sessionStorage&&sessionStorage.setItem(this.state.storageKey,l),this.statusListeners.forEach((t=>t({status:a,position:r,uuid:l})));const u=this.getAdjustedPollInterval(r,this.CONFIG.TTL_INTERVAL);if(u!==n.value&&(n.value=u,this.startTtlEmission(n.value)),a===s.OnlineQueueStatus.ACTIVE)this.removePopup(),this.toggleNavigation(!1);else{const t="function"==typeof(null==e?void 0:e.content)?e.content(r):null!==(i=null==e?void 0:e.content)&&void 0!==i?i:this.getDefaultPopupContent(r,null!==(o=null==e?void 0:e.language)&&void 0!==o?o:"ko",e);this.createPopup(t,null==e?void 0:e.style),this.toggleNavigation(!0)}}static startTtlEmission(t){this.ttlInterval&&clearInterval(this.ttlInterval),this.ttlInterval=setInterval((()=>{var t,e;if((null===(t=this.state.socket)||void 0===t?void 0:t.readyState)===WebSocket.OPEN&&(null===(e=this.state.queueStatus)||void 0===e?void 0:e.uuid)&&this.state.socketConfig)try{this.state.socket.send(JSON.stringify({event:"online-queue:status",data:Object.assign(Object.assign({},this.state.socketConfig.query),{uuid:this.state.queueStatus.uuid})})),this.log("Sent online-queue:status")}catch(t){this.log("Failed to send online-queue:status","error",t)}}),t)}static reconnect(t,e,n,i,s){this.reconnectAttempts>=this.CONFIG.RECONNECTION_ATTEMPTS?this.log("Max reconnection attempts reached","error"):(this.reconnectAttempts++,this.log(`Reconnection attempt ${this.reconnectAttempts} in ${this.CONFIG.RECONNECTION_DELAY}ms`,"info"),setTimeout((()=>{this.setupWebSocket(t,e,n,i,s)}),this.CONFIG.RECONNECTION_DELAY))}static setupWebSocket(t,e,n,i,s){const o=new URLSearchParams(Object.assign(Object.assign({},e.query),{uuid:n})).toString(),a=new WebSocket(`${t}?${o}`);this.state.socket=a;const r={value:this.getAdjustedPollInterval(0,this.CONFIG.TTL_INTERVAL)};a.onopen=()=>{if(this.log("WebSocket connected"),this.reconnectAttempts=0,this.isFirstConnection)try{a.send(JSON.stringify({event:"online-queue:join",data:Object.assign({},e.query)})),this.log("Sent online-queue:join"),this.isFirstConnection=!1}catch(t){this.log("Failed to send online-queue:join","error",t)}this.startTtlEmission(r.value)},a.onmessage=t=>{try{const e=JSON.parse(t.data);if(!e.event||!e.data)return void this.log("Invalid WebSocket message format","warn");"online-queue:status"===e.event?this.handleStatusUpdate({data:e.data},s,r):i&&i[e.event]?i[e.event](e.data,{createPopup:this.createPopup.bind(this),removePopup:this.removePopup.bind(this),preventNavigation:()=>this.toggleNavigation(!0),allowNavigation:()=>this.toggleNavigation(!1)}):this.log(`Unhandled WebSocket event: ${e.event}`,"warn")}catch(t){this.log("Failed to parse WebSocket message","error",t)}},a.onerror=t=>{this.log("WebSocket error","error",t)},a.onclose=o=>{this.log(`WebSocket closed: code=${o.code}, reason=${o.reason}`,"warn"),this.ttlInterval&&(clearInterval(this.ttlInterval),this.ttlInterval=null),this.reconnect(t,e,n,i,s)}}static addStatusListener(t){this.statusListeners.push(t)}static removeStatusListener(t){this.statusListeners=this.statusListeners.filter((e=>e!==t))}static getQueueStatus(){return this.state.queueStatus}static init(t){return i(this,arguments,void 0,(function*({wsUrl:t,apiUrl:e,socketConfig:n={},popupConfig:i={},customEvents:s={},option:o={storageKey:this.CONFIG.STORAGE_KEY}}){var a;if(!t||!e)throw new Error("Both wsUrl and apiUrl are required for initialization");if("undefined"==typeof window)throw new Error("WebSocket is not supported in this environment.");this.state=Object.assign(Object.assign({},this.state),{storageKey:null!==(a=o.storageKey)&&void 0!==a?a:this.CONFIG.STORAGE_KEY,wsUrl:t,apiUrl:e,socketConfig:n}),this.injectStyles(i);try{return this.setupWebSocket(t,n,"",s,i),{disconnect:()=>this.disconnect()}}catch(t){return this.log("Initialization failed","error",t),{disconnect:()=>this.disconnect()}}}))}static cleanup(){this.state.storageKey&&"undefined"!=typeof sessionStorage&&sessionStorage.removeItem(this.state.storageKey),this.ttlInterval&&(clearInterval(this.ttlInterval),this.ttlInterval=null),this.removePopup(),this.toggleNavigation(!1),this.state={socket:null,popupEl:null,isNavigating:!1,storageKey:null,queueStatus:null,wsUrl:null,apiUrl:null,socketConfig:null},this.statusListeners=[],this.reconnectAttempts=0,this.isFirstConnection=!0}static disconnect(){var t,e;(null===(t=this.state.socket)||void 0===t?void 0:t.readyState)===WebSocket.OPEN&&(null===(e=this.state.queueStatus)||void 0===e?void 0:e.uuid)&&this.state.apiUrl&&this.sendLeaveRequest(),this.state.socket&&(this.state.socket.close(),this.state.socket=null),this.cleanup()}}o.CONFIG={TTL_INTERVAL:5e3,STORAGE_KEY:"queue_token",API_ENDPOINTS:{LEAVE:"/leave"},MESSAGES:{en:{MESS_1:"Progressing sequentially based on access order.",MESS_2:"We are doing our best to proceed quickly.",MESS_3:"Queue Number"},ko:{MESS_1:"접속한 순서대로 순차적 진행 중입니다.",MESS_2:"빠른 서비스 진행을 위해 최선을 다하고 있습니다.",MESS_3:"대기순번"}},STYLES:{POPUP:"\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n background: #fff;\n z-index: 10000;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 28px;\n ",LOADER:t=>{var e,n;return`\n .loader-jqueue_popup {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n display: inline-block;\n position: relative;\n background: linear-gradient(0deg, ${null!==(e=null==t?void 0:t.loaderGradientEnd)&&void 0!==e?e:"rgba(39,107,255,0.05)"} 33%, ${null!==(n=null==t?void 0:t.loaderGradientStart)&&void 0!==n?n:"#276bff"} 100%);\n box-sizing: border-box;\n animation: rotation 1s linear infinite;\n }\n .loader-jqueue_popup::after {\n content: '';\n box-sizing: border-box;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 96%;\n height: 96%;\n border-radius: 50%;\n background: #fff;\n }\n @keyframes rotation {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `}},RECONNECTION_ATTEMPTS:3,RECONNECTION_DELAY:1e3},o.state={socket:null,popupEl:null,isNavigating:!1,storageKey:null,queueStatus:null,wsUrl:null,apiUrl:null,socketConfig:null},o.ttlInterval=null,o.statusListeners=[],o.reconnectAttempts=0,o.isFirstConnection=!0,"undefined"!=typeof window&&(window.ConnectionJQueueSdkWeb=o,console.log("Initialized on window")),e.default=o},613:(t,e)=>{var n;Object.defineProperty(e,"__esModule",{value:!0}),e.OnlineQueueStatus=void 0,function(t){t[t.WAITING=1]="WAITING",t[t.ACTIVE=2]="ACTIVE"}(n||(e.OnlineQueueStatus=n={}))}},e={},n=function n(i){var s=e[i];if(void 0!==s)return s.exports;var o=e[i]={exports:{}};return t[i].call(o.exports,o,o.exports,n),o.exports}(156);return n.default})()));
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("io")):"function"==typeof define&&define.amd?define(["io"],e):"object"==typeof exports?exports.ConnectionJQueueSdkWeb=e(require("io")):t.ConnectionJQueueSdkWeb=e(t.io)}(this,(t=>(()=>{"use strict";var e={156:function(t,e,n){var i=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(s,o){function a(t){try{l(i.next(t))}catch(t){o(t)}}function u(t){try{l(i.throw(t))}catch(t){o(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,u)}l((i=i.apply(t,e||[])).next())}))};Object.defineProperty(e,"__esModule",{value:!0});const s=n(676),o=n(613);class a{static log(t,e="info",n){("error"===e?console.error:"warn"===e?console.warn:console.log)(`[J-Queue] ${t}`,null!=n?n:"")}static injectStyles(t){if("undefined"==typeof document||document.querySelector("style[data-jqueue-styles]"))return;const e=document.createElement("style");e.dataset.jqueueStyles="",e.textContent=this.CONFIG.STYLES.LOADER(t),document.head.appendChild(e)}static createPopup(t,e){if("undefined"==typeof document)return;this.removePopup();const n=document.createElement("div");n.id="__jqueue_popup",n.style.cssText=null!=e?e:this.CONFIG.STYLES.POPUP,n.innerHTML=t,document.body.appendChild(n),this.state.popupEl=n}static removePopup(){var t;"undefined"!=typeof document&&(null===(t=this.state.popupEl)||void 0===t||t.remove(),this.state.popupEl=null)}static toggleNavigation(t){"undefined"!=typeof window&&this.state.isNavigating!==t&&(window.onbeforeunload=t?()=>{var t;return(null===(t=this.state.queueStatus)||void 0===t?void 0:t.uuid)&&this.state.apiUrl&&this.sendLeaveRequest(),"Navigation is currently blocked."}:null,this.state.isNavigating=t)}static sendLeaveRequest(){const{apiUrl:t,queueStatus:e}=this.state;if(t&&(null==e?void 0:e.uuid))try{const n=JSON.stringify({uuid:e.uuid});navigator.sendBeacon(`${t}${this.CONFIG.API_ENDPOINTS.LEAVE}`,n)}catch(t){this.log("Leave API (sendBeacon) failed","error",t)}}static getDefaultPopupContent(t,e="ko",n){var i;const s=this.CONFIG.MESSAGES[e],o=null!==(i=null==n?void 0:n.textColor)&&void 0!==i?i:"#276bff";return`\n <div style="display: flex; flex-direction: column; align-items: center; width: 100%;">\n <div style="padding: 20px; text-align: center;">\n <p style="font-size: 16px; line-height: 1.5; margin: 0 0 20px 0; color: ${o};">\n ${s.MESS_1}<br>${s.MESS_2}\n </p>\n <div style="position: relative; width: 150px; height: 150px; margin: 20px auto;">\n <span style="position: absolute; inset: 0;" class="loader-jqueue_popup"></span>\n <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center;">\n <div style="font-size: 14px; color: ${o};">${s.MESS_3}</div>\n <div style="font-size: 36px; color: ${o}; font-weight: bold;">${t}</div>\n </div>\n </div>\n </div>\n </div>\n `}static getAdjustedPollInterval(t,e){return t>=100?e+t/100*1e3:e}static handleStatusUpdate(t,e,n){var i,s;if(!(null==t?void 0:t.data))return void this.log("Invalid status response received","warn");const{status:a,position:u,uuid:l}=t.data;this.state.queueStatus={status:a,position:u,uuid:l},this.state.storageKey&&"undefined"!=typeof sessionStorage&&sessionStorage.setItem(this.state.storageKey,l),this.statusListeners.forEach((t=>t({status:a,position:u,uuid:l})));const r=this.getAdjustedPollInterval(u,this.CONFIG.TTL_INTERVAL);if(r!==n.value&&(n.value=r,this.startTtlEmission(n.value)),a===o.OnlineQueueStatus.ACTIVE)this.removePopup(),this.toggleNavigation(!1);else{const t="function"==typeof(null==e?void 0:e.content)?e.content(u):null!==(i=null==e?void 0:e.content)&&void 0!==i?i:this.getDefaultPopupContent(u,null!==(s=null==e?void 0:e.language)&&void 0!==s?s:"ko",e);this.createPopup(t,null==e?void 0:e.style),this.toggleNavigation(!0)}}static startTtlEmission(t){this.ttlInterval&&clearInterval(this.ttlInterval),this.ttlInterval=setInterval((()=>{var t,e;(null===(t=this.state.socket)||void 0===t?void 0:t.connected)&&(null===(e=this.state.queueStatus)||void 0===e?void 0:e.uuid)&&this.state.socketConfig&&(this.state.socket.emit("online-queue:status",Object.assign(Object.assign({},this.state.socketConfig.query),{uuid:this.state.queueStatus.uuid})),this.log("Sent online-queue:status"))}),t)}static setupSocket(t,e,n,i,o){const a=(0,s.io)(t,{query:Object.assign(Object.assign({},e.query),{uuid:n}),transports:e.transports||["websocket"],reconnectionAttempts:e.reconnectionAttempts||3,reconnectionDelay:e.reconnectionDelay||1e3});this.state.socket=a;const u={value:this.getAdjustedPollInterval(0,this.CONFIG.TTL_INTERVAL)};let l=!0;a.on("connect",(()=>{this.log("Socket.IO connected"),l&&(a.emit("online-queue:join",Object.assign({},e.query)),this.log("Sent online-queue:join"),l=!1),this.startTtlEmission(u.value)})),a.on("online-queue:join",(t=>{this.handleStatusUpdate(t,o,u)})),a.on("online-queue:status",(t=>{this.handleStatusUpdate(t,o,u)})),i&&Object.keys(i).forEach((t=>{a.on(t,(e=>{i[t](e,{createPopup:this.createPopup.bind(this),removePopup:this.removePopup.bind(this),preventNavigation:()=>this.toggleNavigation(!0),allowNavigation:()=>this.toggleNavigation(!1)})}))})),a.on("connect_error",(t=>{this.log("Socket.IO connection error","error",t)})),a.on("disconnect",(t=>{this.log(`Socket.IO disconnected: ${t}`,"warn"),this.ttlInterval&&(clearInterval(this.ttlInterval),this.ttlInterval=null)}))}static addStatusListener(t){this.statusListeners.push(t)}static removeStatusListener(t){this.statusListeners=this.statusListeners.filter((e=>e!==t))}static getQueueStatus(){return this.state.queueStatus}static init(t){return i(this,arguments,void 0,(function*({wsUrl:t,apiUrl:e,socketConfig:n={},popupConfig:i={},customEvents:s={},option:o={storageKey:this.CONFIG.STORAGE_KEY}}){var a;if(!t||!e)throw new Error("Both wsUrl and apiUrl are required for initialization");if("undefined"==typeof window)throw new Error("Socket.IO is not supported in this environment.");this.state=Object.assign(Object.assign({},this.state),{storageKey:null!==(a=o.storageKey)&&void 0!==a?a:this.CONFIG.STORAGE_KEY,wsUrl:t,apiUrl:e,socketConfig:n}),this.injectStyles(i);try{return this.setupSocket(t,n,"",s,i),{disconnect:()=>this.disconnect()}}catch(t){return this.log("Initialization failed","error",t),{disconnect:()=>this.disconnect()}}}))}static cleanup(){this.state.storageKey&&"undefined"!=typeof sessionStorage&&sessionStorage.removeItem(this.state.storageKey),this.ttlInterval&&(clearInterval(this.ttlInterval),this.ttlInterval=null),this.removePopup(),this.toggleNavigation(!1),this.state={socket:null,popupEl:null,isNavigating:!1,storageKey:null,queueStatus:null,wsUrl:null,apiUrl:null,socketConfig:null},this.statusListeners=[]}static disconnect(){var t,e,n;(null===(t=this.state.socket)||void 0===t?void 0:t.connected)&&(null===(e=this.state.queueStatus)||void 0===e?void 0:e.uuid)&&this.state.apiUrl&&this.sendLeaveRequest(),null===(n=this.state.socket)||void 0===n||n.disconnect(),this.cleanup()}}a.CONFIG={TTL_INTERVAL:3e4,STORAGE_KEY:"queue_token",API_ENDPOINTS:{LEAVE:"/leave"},MESSAGES:{en:{MESS_1:"Progressing sequentially based on access order.",MESS_2:"We are doing our best to proceed quickly.",MESS_3:"Queue Number"},ko:{MESS_1:"접속한 순서대로 순차적 진행 중입니다.",MESS_2:"빠른 서비스 진행을 위해 최선을 다하고 있습니다.",MESS_3:"대기순번"}},STYLES:{POPUP:"\n position: fixed;\n inset: 0;\n width: 100%;\n height: 100%;\n background: #fff;\n z-index: 10000;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 28px;\n ",LOADER:t=>{var e,n;return`\n .loader-jqueue_popup {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n display: inline-block;\n position: relative;\n background: linear-gradient(0deg, ${null!==(e=null==t?void 0:t.loaderGradientEnd)&&void 0!==e?e:"rgba(39,107,255,0.05)"} 33%, ${null!==(n=null==t?void 0:t.loaderGradientStart)&&void 0!==n?n:"#276bff"} 100%);\n box-sizing: border-box;\n animation: rotation 1s linear infinite;\n }\n .loader-jqueue_popup::after {\n content: '';\n box-sizing: border-box;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 96%;\n height: 96%;\n border-radius: 50%;\n background: #fff;\n }\n @keyframes rotation {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n `}}},a.state={socket:null,popupEl:null,isNavigating:!1,storageKey:null,queueStatus:null,wsUrl:null,apiUrl:null,socketConfig:null},a.ttlInterval=null,a.statusListeners=[],"undefined"!=typeof window&&(window.ConnectionJQueueSdkWeb=a),e.default=a},613:(t,e)=>{var n;Object.defineProperty(e,"__esModule",{value:!0}),e.OnlineQueueStatus=void 0,function(t){t[t.WAITING=1]="WAITING",t[t.ACTIVE=2]="ACTIVE"}(n||(e.OnlineQueueStatus=n={}))},676:e=>{e.exports=t}},n={},i=function t(i){var s=n[i];if(void 0!==s)return s.exports;var o=n[i]={exports:{}};return e[i].call(o.exports,o,o.exports,t),o.exports}(156);return i.default})()));
//# sourceMappingURL=j-queue-sdk-web.js.map

@@ -0,4 +1,5 @@

import { Socket } from 'socket.io-client';
import { InitConfig, OnlineQueueStatus } from './types';
interface ConnectionState {
socket: WebSocket | null;
socket: Socket | null;
popupEl: HTMLElement | null;

@@ -21,4 +22,2 @@ isNavigating: boolean;

private static statusListeners;
private static reconnectAttempts;
private static isFirstConnection;
/** Logs messages with a prefix, supporting different log levels. */

@@ -44,6 +43,4 @@ private static log;

private static startTtlEmission;
/** Attempts to reconnect to the WebSocket server. */
private static reconnect;
/** Configures the WebSocket connection with event handlers and periodic TTL emission. */
private static setupWebSocket;
/** Configures the Socket.IO connection with event handlers and periodic TTL emission. */
private static setupSocket;
/** Adds a listener for queue status updates. */

@@ -61,3 +58,3 @@ static addStatusListener(listener: (status: NonNullable<ConnectionState['queueStatus']>) => void): void;

private static cleanup;
/** Disconnects the WebSocket connection and cleans up resources. */
/** Disconnects the Socket.IO connection and cleans up resources. */
private static disconnect;

@@ -64,0 +61,0 @@ }

@@ -12,2 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const socket_io_client_1 = require("socket.io-client");
const types_1 = require("./types");

@@ -85,3 +86,3 @@ class ConnectionJQueueSdkWeb {

<div style="padding: 20px; text-align: center;">
<p style="font-size: 18px; line-height: 1.5; margin: 0 0 20px 0; color: ${textColor};">
<p style="font-size: 16px; line-height: 1.5; margin: 0 0 20px 0; color: ${textColor};">
${messages.MESS_1}<br>${messages.MESS_2}

@@ -142,87 +143,51 @@ </p>

var _a, _b;
if (((_a = this.state.socket) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN && ((_b = this.state.queueStatus) === null || _b === void 0 ? void 0 : _b.uuid) && this.state.socketConfig) {
try {
this.state.socket.send(JSON.stringify({
event: 'online-queue:status',
data: Object.assign(Object.assign({}, this.state.socketConfig.query), { uuid: this.state.queueStatus.uuid }),
}));
this.log('Sent online-queue:status');
}
catch (error) {
this.log('Failed to send online-queue:status', 'error', error);
}
if (((_a = this.state.socket) === null || _a === void 0 ? void 0 : _a.connected) && ((_b = this.state.queueStatus) === null || _b === void 0 ? void 0 : _b.uuid) && this.state.socketConfig) {
this.state.socket.emit('online-queue:status', Object.assign(Object.assign({}, this.state.socketConfig.query), { uuid: this.state.queueStatus.uuid }));
this.log('Sent online-queue:status');
}
}, interval);
}
/** Attempts to reconnect to the WebSocket server. */
static reconnect(wsUrl, socketConfig, uuid, customEvents, popupConfig) {
if (this.reconnectAttempts >= this.CONFIG.RECONNECTION_ATTEMPTS) {
this.log('Max reconnection attempts reached', 'error');
return;
}
this.reconnectAttempts++;
this.log(`Reconnection attempt ${this.reconnectAttempts} in ${this.CONFIG.RECONNECTION_DELAY}ms`, 'info');
setTimeout(() => {
this.setupWebSocket(wsUrl, socketConfig, uuid, customEvents, popupConfig);
}, this.CONFIG.RECONNECTION_DELAY);
}
/** Configures the WebSocket connection with event handlers and periodic TTL emission. */
static setupWebSocket(wsUrl, socketConfig, uuid, customEvents, popupConfig) {
// Append query parameters to wsUrl
const query = new URLSearchParams(Object.assign(Object.assign({}, socketConfig.query), { uuid })).toString();
const ws = new WebSocket(`${wsUrl}?${query}`);
this.state.socket = ws;
/** Configures the Socket.IO connection with event handlers and periodic TTL emission. */
static setupSocket(wsUrl, socketConfig, uuid, customEvents, popupConfig) {
const socket = (0, socket_io_client_1.io)(wsUrl, {
query: Object.assign(Object.assign({}, socketConfig.query), { uuid }),
transports: socketConfig.transports || ['websocket'],
reconnectionAttempts: socketConfig.reconnectionAttempts || 3,
reconnectionDelay: socketConfig.reconnectionDelay || 1000,
});
this.state.socket = socket;
const currentTtlInterval = { value: this.getAdjustedPollInterval(0, this.CONFIG.TTL_INTERVAL) };
ws.onopen = () => {
this.log('WebSocket connected');
this.reconnectAttempts = 0; // Reset reconnection attempts
if (this.isFirstConnection) {
try {
ws.send(JSON.stringify({
event: 'online-queue:join',
data: Object.assign({}, socketConfig.query),
}));
this.log('Sent online-queue:join');
this.isFirstConnection = false;
}
catch (error) {
this.log('Failed to send online-queue:join', 'error', error);
}
let isFirstConnection = true;
socket.on('connect', () => {
this.log('Socket.IO connected');
if (isFirstConnection) {
socket.emit('online-queue:join', Object.assign({}, socketConfig.query));
this.log('Sent online-queue:join');
isFirstConnection = false;
}
this.startTtlEmission(currentTtlInterval.value);
};
ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
if (!message.event || !message.data) {
this.log('Invalid WebSocket message format', 'warn');
return;
}
switch (message.event) {
case 'online-queue:status':
this.handleStatusUpdate({ data: message.data }, popupConfig, currentTtlInterval);
break;
default:
if (customEvents && customEvents[message.event]) {
customEvents[message.event](message.data, {
createPopup: this.createPopup.bind(this),
removePopup: this.removePopup.bind(this),
preventNavigation: () => this.toggleNavigation(true),
allowNavigation: () => this.toggleNavigation(false),
});
}
else {
this.log(`Unhandled WebSocket event: ${message.event}`, 'warn');
}
}
}
catch (error) {
this.log('Failed to parse WebSocket message', 'error', error);
}
};
ws.onerror = (error) => {
this.log('WebSocket error', 'error', error);
};
ws.onclose = (event) => {
this.log(`WebSocket closed: code=${event.code}, reason=${event.reason}`, 'warn');
});
socket.on('online-queue:join', (data) => {
this.handleStatusUpdate(data, popupConfig, currentTtlInterval);
});
socket.on('online-queue:status', (data) => {
this.handleStatusUpdate(data, popupConfig, currentTtlInterval);
});
if (customEvents) {
Object.keys(customEvents).forEach((event) => {
socket.on(event, (data) => {
customEvents[event](data, {
createPopup: this.createPopup.bind(this),
removePopup: this.removePopup.bind(this),
preventNavigation: () => this.toggleNavigation(true),
allowNavigation: () => this.toggleNavigation(false),
});
});
});
}
socket.on('connect_error', (error) => {
this.log('Socket.IO connection error', 'error', error);
});
socket.on('disconnect', (reason) => {
this.log(`Socket.IO disconnected: ${reason}`, 'warn');
if (this.ttlInterval) {

@@ -232,4 +197,3 @@ clearInterval(this.ttlInterval);

}
this.reconnect(wsUrl, socketConfig, uuid, customEvents, popupConfig);
};
});
}

@@ -255,3 +219,3 @@ /** Adds a listener for queue status updates. */

if (typeof window === 'undefined')
throw new Error('WebSocket is not supported in this environment.');
throw new Error('Socket.IO is not supported in this environment.');
this.state = Object.assign(Object.assign({}, this.state), { storageKey: (_b = option.storageKey) !== null && _b !== void 0 ? _b : this.CONFIG.STORAGE_KEY, wsUrl,

@@ -262,3 +226,4 @@ apiUrl,

try {
this.setupWebSocket(wsUrl, socketConfig, '', customEvents, popupConfig);
// Connect socket immediately
this.setupSocket(wsUrl, socketConfig, '', customEvents, popupConfig);
return { disconnect: () => this.disconnect() };

@@ -294,15 +259,10 @@ }

this.statusListeners = [];
this.reconnectAttempts = 0;
this.isFirstConnection = true;
}
/** Disconnects the WebSocket connection and cleans up resources. */
/** Disconnects the Socket.IO connection and cleans up resources. */
static disconnect() {
var _a, _b;
if (((_a = this.state.socket) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN && ((_b = this.state.queueStatus) === null || _b === void 0 ? void 0 : _b.uuid) && this.state.apiUrl) {
var _a, _b, _c;
if (((_a = this.state.socket) === null || _a === void 0 ? void 0 : _a.connected) && ((_b = this.state.queueStatus) === null || _b === void 0 ? void 0 : _b.uuid) && this.state.apiUrl) {
this.sendLeaveRequest();
}
if (this.state.socket) {
this.state.socket.close();
this.state.socket = null;
}
(_c = this.state.socket) === null || _c === void 0 ? void 0 : _c.disconnect();
this.cleanup();

@@ -312,3 +272,3 @@ }

ConnectionJQueueSdkWeb.CONFIG = {
TTL_INTERVAL: 5000, // Base interval for online-queue:status
TTL_INTERVAL: 30000, // Base interval for online-queue:status
STORAGE_KEY: 'queue_token',

@@ -375,4 +335,2 @@ API_ENDPOINTS: {

},
RECONNECTION_ATTEMPTS: 3,
RECONNECTION_DELAY: 1000,
};

@@ -391,8 +349,6 @@ ConnectionJQueueSdkWeb.state = {

ConnectionJQueueSdkWeb.statusListeners = [];
ConnectionJQueueSdkWeb.reconnectAttempts = 0;
ConnectionJQueueSdkWeb.isFirstConnection = true;
if (typeof window !== 'undefined') {
window.ConnectionJQueueSdkWeb = ConnectionJQueueSdkWeb;
console.log('Initialized on window');
// console.log('Initialized on window');
}
exports.default = ConnectionJQueueSdkWeb;
{
"name": "j-queue-sdk-web",
"version": "1.0.24",
"version": "1.0.25",
"description": "A TypeScript package to check WebSocket connection status and control web access with a popup",

@@ -5,0 +5,0 @@ "main": "dist/j-queue-sdk-web.js",

@@ -0,5 +1,6 @@

import { io, Socket } from 'socket.io-client';
import { InitConfig, PopupConfig, OnlineQueueStatus, CustomEventUtils } from './types';
interface ConnectionState {
socket: WebSocket | null;
socket: Socket | null;
popupEl: HTMLElement | null;

@@ -26,3 +27,3 @@ isNavigating: boolean;

private static readonly CONFIG = {
TTL_INTERVAL: 5000, // Base interval for online-queue:status
TTL_INTERVAL: 30000, // Base interval for online-queue:status
STORAGE_KEY: 'queue_token',

@@ -86,4 +87,2 @@ API_ENDPOINTS: {

},
RECONNECTION_ATTEMPTS: 3,
RECONNECTION_DELAY: 1000,
};

@@ -104,4 +103,2 @@

private static statusListeners: Array<(status: NonNullable<ConnectionState['queueStatus']>) => void> = [];
private static reconnectAttempts = 0;
private static isFirstConnection = true;

@@ -174,3 +171,3 @@ /** Logs messages with a prefix, supporting different log levels. */

<div style="padding: 20px; text-align: center;">
<p style="font-size: 18px; line-height: 1.5; margin: 0 0 20px 0; color: ${textColor};">
<p style="font-size: 16px; line-height: 1.5; margin: 0 0 20px 0; color: ${textColor};">
${messages.MESS_1}<br>${messages.MESS_2}

@@ -236,12 +233,5 @@ </p>

this.ttlInterval = setInterval(() => {
if (this.state.socket?.readyState === WebSocket.OPEN && this.state.queueStatus?.uuid && this.state.socketConfig) {
try {
this.state.socket.send(JSON.stringify({
event: 'online-queue:status',
data: { ...this.state.socketConfig.query, uuid: this.state.queueStatus.uuid },
}));
this.log('Sent online-queue:status');
} catch (error) {
this.log('Failed to send online-queue:status', 'error', error);
}
if (this.state.socket?.connected && this.state.queueStatus?.uuid && this.state.socketConfig) {
this.state.socket.emit('online-queue:status', { ...this.state.socketConfig.query, uuid: this.state.queueStatus.uuid });
this.log('Sent online-queue:status');
}

@@ -251,19 +241,4 @@ }, interval);

/** Attempts to reconnect to the WebSocket server. */
private static reconnect(wsUrl: string, socketConfig: NonNullable<InitConfig['socketConfig']>, uuid: string, customEvents: InitConfig['customEvents'], popupConfig: InitConfig['popupConfig']): void {
if (this.reconnectAttempts >= this.CONFIG.RECONNECTION_ATTEMPTS) {
this.log('Max reconnection attempts reached', 'error');
return;
}
this.reconnectAttempts++;
this.log(`Reconnection attempt ${this.reconnectAttempts} in ${this.CONFIG.RECONNECTION_DELAY}ms`, 'info');
setTimeout(() => {
this.setupWebSocket(wsUrl, socketConfig, uuid, customEvents, popupConfig);
}, this.CONFIG.RECONNECTION_DELAY);
}
/** Configures the WebSocket connection with event handlers and periodic TTL emission. */
private static setupWebSocket(
/** Configures the Socket.IO connection with event handlers and periodic TTL emission. */
private static setupSocket(
wsUrl: string,

@@ -275,64 +250,50 @@ socketConfig: NonNullable<InitConfig['socketConfig']>,

): void {
// Append query parameters to wsUrl
const query = new URLSearchParams({ ...socketConfig.query, uuid }).toString();
const ws = new WebSocket(`${wsUrl}?${query}`);
this.state.socket = ws;
const socket = io(wsUrl, {
query: { ...socketConfig.query, uuid },
transports: socketConfig.transports || ['websocket'],
reconnectionAttempts: socketConfig.reconnectionAttempts || 3,
reconnectionDelay: socketConfig.reconnectionDelay || 1000,
});
this.state.socket = socket;
const currentTtlInterval = { value: this.getAdjustedPollInterval(0, this.CONFIG.TTL_INTERVAL) };
let isFirstConnection = true;
ws.onopen = () => {
this.log('WebSocket connected');
this.reconnectAttempts = 0; // Reset reconnection attempts
if (this.isFirstConnection) {
try {
ws.send(JSON.stringify({
event: 'online-queue:join',
data: { ...socketConfig.query },
}));
this.log('Sent online-queue:join');
this.isFirstConnection = false;
} catch (error) {
this.log('Failed to send online-queue:join', 'error', error);
}
socket.on('connect', () => {
this.log('Socket.IO connected');
if (isFirstConnection) {
socket.emit('online-queue:join', { ...socketConfig.query });
this.log('Sent online-queue:join');
isFirstConnection = false;
}
this.startTtlEmission(currentTtlInterval.value);
};
});
ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data as string);
if (!message.event || !message.data) {
this.log('Invalid WebSocket message format', 'warn');
return;
}
socket.on('online-queue:join', (data: StatusResponse) => {
this.handleStatusUpdate(data, popupConfig, currentTtlInterval);
});
switch (message.event) {
case 'online-queue:status':
this.handleStatusUpdate({ data: message.data }, popupConfig, currentTtlInterval);
break;
default:
if (customEvents && customEvents[message.event]) {
customEvents[message.event](message.data, {
createPopup: this.createPopup.bind(this),
removePopup: this.removePopup.bind(this),
preventNavigation: () => this.toggleNavigation(true),
allowNavigation: () => this.toggleNavigation(false),
});
} else {
this.log(`Unhandled WebSocket event: ${message.event}`, 'warn');
}
}
} catch (error) {
this.log('Failed to parse WebSocket message', 'error', error);
}
};
socket.on('online-queue:status', (data: StatusResponse) => {
this.handleStatusUpdate(data, popupConfig, currentTtlInterval);
});
ws.onerror = (error) => {
this.log('WebSocket error', 'error', error);
};
if (customEvents) {
Object.keys(customEvents).forEach((event) => {
socket.on(event, (data: any) => {
customEvents[event](data, {
createPopup: this.createPopup.bind(this),
removePopup: this.removePopup.bind(this),
preventNavigation: () => this.toggleNavigation(true),
allowNavigation: () => this.toggleNavigation(false),
});
});
});
}
ws.onclose = (event) => {
this.log(`WebSocket closed: code=${event.code}, reason=${event.reason}`, 'warn');
socket.on('connect_error', (error) => {
this.log('Socket.IO connection error', 'error', error);
});
socket.on('disconnect', (reason) => {
this.log(`Socket.IO disconnected: ${reason}`, 'warn');
if (this.ttlInterval) {

@@ -342,4 +303,3 @@ clearInterval(this.ttlInterval);

}
this.reconnect(wsUrl, socketConfig, uuid, customEvents, popupConfig);
};
});
}

@@ -372,3 +332,3 @@

if (!wsUrl || !apiUrl) throw new Error('Both wsUrl and apiUrl are required for initialization');
if (typeof window === 'undefined') throw new Error('WebSocket is not supported in this environment.');
if (typeof window === 'undefined') throw new Error('Socket.IO is not supported in this environment.');

@@ -385,3 +345,4 @@ this.state = {

try {
this.setupWebSocket(wsUrl, socketConfig, '', customEvents, popupConfig);
// Connect socket immediately
this.setupSocket(wsUrl, socketConfig, '', customEvents, popupConfig);
return { disconnect: () => this.disconnect() };

@@ -416,15 +377,10 @@ } catch (error) {

this.statusListeners = [];
this.reconnectAttempts = 0;
this.isFirstConnection = true;
}
/** Disconnects the WebSocket connection and cleans up resources. */
/** Disconnects the Socket.IO connection and cleans up resources. */
private static disconnect(): void {
if (this.state.socket?.readyState === WebSocket.OPEN && this.state.queueStatus?.uuid && this.state.apiUrl) {
if (this.state.socket?.connected && this.state.queueStatus?.uuid && this.state.apiUrl) {
this.sendLeaveRequest();
}
if (this.state.socket) {
this.state.socket.close();
this.state.socket = null;
}
this.state.socket?.disconnect();
this.cleanup();

@@ -442,3 +398,3 @@ }

window.ConnectionJQueueSdkWeb = ConnectionJQueueSdkWeb;
console.log('Initialized on window');
// console.log('Initialized on window');
}

@@ -445,0 +401,0 @@

Sorry, the diff of this file is not supported yet