cybernate-ai
Version:
JavaScript SDK for Cybernate AI Security Platform
3 lines (2 loc) • 24.1 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).CybernateAI=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var n,r={exports:{}},s={exports:{}};function o(){return n||(n=1,function(t,n){var r="undefined"!=typeof globalThis&&globalThis||"undefined"!=typeof self&&self||void 0!==e&&e,s=function(){function e(){this.fetch=!1,this.DOMException=r.DOMException}return e.prototype=r,new e}();!function(t){!function(n){var r=void 0!==t&&t||"undefined"!=typeof self&&self||void 0!==e&&e||{},s="URLSearchParams"in r,o="Symbol"in r&&"iterator"in Symbol,i="FileReader"in r&&"Blob"in r&&function(){try{return new Blob,!0}catch(e){return!1}}(),a="FormData"in r,c="ArrayBuffer"in r;if(c)var h=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],u=ArrayBuffer.isView||function(e){return e&&h.indexOf(Object.prototype.toString.call(e))>-1};function d(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(e)||""===e)throw new TypeError('Invalid character in header field name: "'+e+'"');return e.toLowerCase()}function l(e){return"string"!=typeof e&&(e=String(e)),e}function f(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return o&&(t[Symbol.iterator]=function(){return t}),t}function y(e){this.map={},e instanceof y?e.forEach((function(e,t){this.append(t,e)}),this):Array.isArray(e)?e.forEach((function(e){if(2!=e.length)throw new TypeError("Headers constructor: expected name/value pair to be length 2, found"+e.length);this.append(e[0],e[1])}),this):e&&Object.getOwnPropertyNames(e).forEach((function(t){this.append(t,e[t])}),this)}function p(e){if(!e._noBody)return e.bodyUsed?Promise.reject(new TypeError("Already read")):void(e.bodyUsed=!0)}function b(e){return new Promise((function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}}))}function w(e){var t=new FileReader,n=b(t);return t.readAsArrayBuffer(e),n}function m(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function g(){return this.bodyUsed=!1,this._initBody=function(e){var t;this.bodyUsed=this.bodyUsed,this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:i&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:a&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:s&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():c&&i&&((t=e)&&DataView.prototype.isPrototypeOf(t))?(this._bodyArrayBuffer=m(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):c&&(ArrayBuffer.prototype.isPrototypeOf(e)||u(e))?this._bodyArrayBuffer=m(e):this._bodyText=e=Object.prototype.toString.call(e):(this._noBody=!0,this._bodyText=""),this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):s&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},i&&(this.blob=function(){var e=p(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))}),this.arrayBuffer=function(){if(this._bodyArrayBuffer){var e=p(this);return e||(ArrayBuffer.isView(this._bodyArrayBuffer)?Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset,this._bodyArrayBuffer.byteOffset+this._bodyArrayBuffer.byteLength)):Promise.resolve(this._bodyArrayBuffer))}if(i)return this.blob().then(w);throw new Error("could not read as ArrayBuffer")},this.text=function(){var e,t,n,r,s,o=p(this);if(o)return o;if(this._bodyBlob)return e=this._bodyBlob,t=new FileReader,n=b(t),r=/charset=([A-Za-z0-9_-]+)/.exec(e.type),s=r?r[1]:"utf-8",t.readAsText(e,s),n;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r<t.length;r++)n[r]=String.fromCharCode(t[r]);return n.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},a&&(this.formData=function(){return this.text().then(v)}),this.json=function(){return this.text().then(JSON.parse)},this}y.prototype.append=function(e,t){e=d(e),t=l(t);var n=this.map[e];this.map[e]=n?n+", "+t:t},y.prototype.delete=function(e){delete this.map[d(e)]},y.prototype.get=function(e){return e=d(e),this.has(e)?this.map[e]:null},y.prototype.has=function(e){return this.map.hasOwnProperty(d(e))},y.prototype.set=function(e,t){this.map[d(e)]=l(t)},y.prototype.forEach=function(e,t){for(var n in this.map)this.map.hasOwnProperty(n)&&e.call(t,this.map[n],n,this)},y.prototype.keys=function(){var e=[];return this.forEach((function(t,n){e.push(n)})),f(e)},y.prototype.values=function(){var e=[];return this.forEach((function(t){e.push(t)})),f(e)},y.prototype.entries=function(){var e=[];return this.forEach((function(t,n){e.push([n,t])})),f(e)},o&&(y.prototype[Symbol.iterator]=y.prototype.entries);var E=["CONNECT","DELETE","GET","HEAD","OPTIONS","PATCH","POST","PUT","TRACE"];function _(e,t){if(!(this instanceof _))throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');var n,s,o=(t=t||{}).body;if(e instanceof _){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new y(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,o||null==e._bodyInit||(o=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new y(t.headers)),this.method=(n=t.method||this.method||"GET",s=n.toUpperCase(),E.indexOf(s)>-1?s:n),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal||function(){if("AbortController"in r)return(new AbortController).signal}(),this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)throw new TypeError("Body not allowed for GET or HEAD requests");if(this._initBody(o),!("GET"!==this.method&&"HEAD"!==this.method||"no-store"!==t.cache&&"no-cache"!==t.cache)){var i=/([?&])_=[^&]*/;if(i.test(this.url))this.url=this.url.replace(i,"$1_="+(new Date).getTime());else{this.url+=(/\?/.test(this.url)?"&":"?")+"_="+(new Date).getTime()}}}function v(e){var t=new FormData;return e.trim().split("&").forEach((function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),s=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(s))}})),t}function T(e,t){if(!(this instanceof T))throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');if(t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.status<200||this.status>599)throw new RangeError("Failed to construct 'Response': The status provided (0) is outside the range [200, 599].");this.ok=this.status>=200&&this.status<300,this.statusText=void 0===t.statusText?"":""+t.statusText,this.headers=new y(t.headers),this.url=t.url||"",this._initBody(e)}_.prototype.clone=function(){return new _(this,{body:this._bodyInit})},g.call(_.prototype),g.call(T.prototype),T.prototype.clone=function(){return new T(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new y(this.headers),url:this.url})},T.error=function(){var e=new T(null,{status:200,statusText:""});return e.ok=!1,e.status=0,e.type="error",e};var k=[301,302,303,307,308];T.redirect=function(e,t){if(-1===k.indexOf(t))throw new RangeError("Invalid status code");return new T(null,{status:t,headers:{location:e}})},n.DOMException=r.DOMException;try{new n.DOMException}catch(e){n.DOMException=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},n.DOMException.prototype=Object.create(Error.prototype),n.DOMException.prototype.constructor=n.DOMException}function A(e,t){return new Promise((function(s,o){var a=new _(e,t);if(a.signal&&a.signal.aborted)return o(new n.DOMException("Aborted","AbortError"));var h=new XMLHttpRequest;function u(){h.abort()}if(h.onload=function(){var e,t,n={statusText:h.statusText,headers:(e=h.getAllResponseHeaders()||"",t=new y,e.replace(/\r?\n[\t ]+/g," ").split("\r").map((function(e){return 0===e.indexOf("\n")?e.substr(1,e.length):e})).forEach((function(e){var n=e.split(":"),r=n.shift().trim();if(r){var s=n.join(":").trim();try{t.append(r,s)}catch(e){console.warn("Response "+e.message)}}})),t)};0===a.url.indexOf("file://")&&(h.status<200||h.status>599)?n.status=200:n.status=h.status,n.url="responseURL"in h?h.responseURL:n.headers.get("X-Request-URL");var r="response"in h?h.response:h.responseText;setTimeout((function(){s(new T(r,n))}),0)},h.onerror=function(){setTimeout((function(){o(new TypeError("Network request failed"))}),0)},h.ontimeout=function(){setTimeout((function(){o(new TypeError("Network request timed out"))}),0)},h.onabort=function(){setTimeout((function(){o(new n.DOMException("Aborted","AbortError"))}),0)},h.open(a.method,function(e){try{return""===e&&r.location.href?r.location.href:e}catch(t){return e}}(a.url),!0),"include"===a.credentials?h.withCredentials=!0:"omit"===a.credentials&&(h.withCredentials=!1),"responseType"in h&&(i?h.responseType="blob":c&&(h.responseType="arraybuffer")),t&&"object"==typeof t.headers&&!(t.headers instanceof y||r.Headers&&t.headers instanceof r.Headers)){var f=[];Object.getOwnPropertyNames(t.headers).forEach((function(e){f.push(d(e)),h.setRequestHeader(e,l(t.headers[e]))})),a.headers.forEach((function(e,t){-1===f.indexOf(t)&&h.setRequestHeader(t,e)}))}else a.headers.forEach((function(e,t){h.setRequestHeader(t,e)}));a.signal&&(a.signal.addEventListener("abort",u),h.onreadystatechange=function(){4===h.readyState&&a.signal.removeEventListener("abort",u)}),h.send(void 0===a._bodyInit?null:a._bodyInit)}))}A.polyfill=!0,r.fetch||(r.fetch=A,r.Headers=y,r.Request=_,r.Response=T),n.Headers=y,n.Request=_,n.Response=T,n.fetch=A}({})}(s),s.fetch.ponyfill=!0,delete s.fetch.polyfill;var o=r.fetch?r:s;(n=o.fetch).default=o.fetch,n.fetch=o.fetch,n.Headers=o.Headers,n.Request=o.Request,n.Response=o.Response,t.exports=n}(s,s.exports)),s.exports}return function(e){let t;if("undefined"!=typeof window)t=window.fetch;else try{t=o()}catch(e){throw new Error("cross-fetch is required for Node.js environments")}class n{constructor(e,t={}){if(!e)throw new Error("API key is required");this.apiKey=e,this.baseUrl=t.baseUrl||"https://api.cybernate.ai/v1",this.timeout=t.timeout||3e4,this.autoReconnect=!1!==t.autoReconnect,this.enableWebSocket=!1!==t.enableWebSocket,this.reconnectAttempts=t.reconnectAttempts||5,this.reconnectDelay=t.reconnectDelay||1e3,this.eventListeners={},this.activeWatchers=new Map,this.socket=null,this.isConnected=!1,this.isConnecting=!1,this.reconnectCount=0,this.rateLimit={limit:0,remaining:0,reset:0}}async connect(){if(this.isConnecting)throw new Error("Connection already in progress");this.isConnecting=!0;try{const e=await this._request("GET","/auth/validate");if(this.user=e.user,this.organization=e.organization,this.enableWebSocket&&this._socketIsEnabled())try{await this._setupWebSocket()}catch(e){console.warn("WebSocket connection failed, falling back to HTTP-only mode:",e.message)}return this.isConnected=!0,this.isConnecting=!1,{connected:!0,user:this.user,organization:this.organization,websocketEnabled:!!this.socket?.connected}}catch(e){throw this.isConnected=!1,this.isConnecting=!1,new Error(`Failed to connect to Cybernate: ${e.message}`)}}async watch(e){if(this._ensureConnected(),!e.streamUrl&&!e.deviceId&&!e.businessId)throw new Error("You must specify either streamUrl, deviceId, or businessId");let t,n;if(e.streamUrl?(t="/events/watch",n={url:e.streamUrl,type:"stream",id:e.businessId,name:e.name||`Stream ${(new Date).toISOString()}`,detectionSettings:e.detectionSettings||{}}):e.deviceId?(t="/devices/watch",n={type:"device",id:e.deviceId,detectionSettings:e.detectionSettings||{}}):(t="/businesses/watch",n={type:"business",id:e.businessId,detectionSettings:e.detectionSettings||{}}),n.notificationSettings=e.notificationSettings||{method:this.socket?.connected?"socket":"webhook"},"webhook"===n.notificationSettings.method&&!n.notificationSettings.webhookUrl)throw new Error("webhookUrl is required for webhook notifications");console.log("Watch request:",{endpoint:t,payload:n,apiKey:this.apiKey?"Present":"Missing"});const r=await this._request("POST",t,n);return this.activeWatchers.set(r.watcherId,{id:r.watcherId,type:r.type,entityId:r.entityId,createdAt:new Date}),r}async unwatch(e){if(this._ensureConnected(),!e)throw new Error("watcherId is required");const t=await this._request("DELETE",`/events/watch/${e}`);return this.activeWatchers.delete(e),t}async getActiveWatchers(){this._ensureConnected();const e=await this._request("GET","/events/watchers");this.activeWatchers.clear();for(const t of e.watchers)this.activeWatchers.set(t.id,t);return e.watchers}async queryEvents(e={}){this._ensureConnected();const t=new URLSearchParams;return Object.entries(e).forEach((([e,n])=>{null!=n&&t.append(e,n)})),this._request("GET",`/events?${t.toString()}`)}async getEventStatistics(e={}){this._ensureConnected();const t=new URLSearchParams;return Object.entries(e).forEach((([e,n])=>{null!=n&&t.append(e,n)})),this._request("GET",`/events/statistics?${t.toString()}`)}async acknowledgeEvent(e,t){if(this._ensureConnected(),!e)throw new Error("eventId is required");return this._request("POST",`/events/${e}/acknowledge`,{notes:t||""})}async setWebhook(e){if(this._ensureConnected(),!e.url)throw new Error("url is required");return this._request("POST","/webhooks/configure",{url:e.url,events:e.events||["detection","connection_lost","alert"]})}async getWebhooks(){return this._ensureConnected(),this._request("GET","/webhooks")}async deleteWebhook(e){return this._ensureConnected(),this._request("DELETE",`/webhooks/${e}`)}async testWebhook(e,t){return this._ensureConnected(),this._request("POST","/webhooks/test",{url:e,payload:t})}async uploadFile(e){if(this._ensureConnected(),!e.file)throw new Error("file is required");if(!e.fileName)throw new Error("fileName is required");const n=new FormData;n.append("file",e.file),n.append("fileName",e.fileName),e.eventId&&n.append("eventId",e.eventId),e.streamId&&n.append("streamId",e.streamId),e.deviceId&&n.append("deviceId",e.deviceId),e.businessId&&n.append("businessId",e.businessId),e.metadata&&n.append("metadata",JSON.stringify(e.metadata)),void 0!==e.isPublic&&n.append("isPublic",e.isPublic);const r=`${this.baseUrl}/storage/upload`,s=await t(r,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:n,timeout:this.timeout});if(!s.ok){const e=await s.json().catch((()=>({})));throw new Error(e.message||`HTTP error ${s.status}`)}return await s.json()}async getFileInfo(e){return this._ensureConnected(),this._request("GET",`/storage/files/${e}`)}async queryFiles(e={}){this._ensureConnected();const t=new URLSearchParams;return Object.entries(e).forEach((([e,n])=>{null!=n&&t.append(e,n)})),this._request("GET",`/storage/files?${t.toString()}`)}async deleteFile(e){return this._ensureConnected(),this._request("DELETE",`/storage/files/${e}`)}async getFileUrl(e,t=3600){return this._ensureConnected(),this._request("GET",`/storage/files/${e}/url?expiresIn=${t}`)}async captureStreamFrame(e,t={}){return this._ensureConnected(),this._request("POST",`/storage/capture/${e}`,t)}async getAnalytics(e,t={}){this._ensureConnected();const n=new URLSearchParams;return n.append("businessId",e),Object.entries(t).forEach((([e,t])=>{null!=t&&n.append(e,t)})),this._request("GET",`/analytics?${n.toString()}`)}async getInsights(e,t={}){this._ensureConnected();const n=new URLSearchParams;return n.append("businessId",e),Object.entries(t).forEach((([e,t])=>{null!=t&&n.append(e,t)})),this._request("GET",`/analytics/insights?${n.toString()}`)}async acknowledgeInsight(e,t){return this._ensureConnected(),this._request("POST",`/analytics/insights/${e}/acknowledge`,{actionTaken:t||"Reviewed"})}async getDashboardAnalytics(e){return this._ensureConnected(),this._request("GET",`/analytics/dashboard/${e}`)}async getIntegrations(e={}){this._ensureConnected();const t=new URLSearchParams;return Object.entries(e).forEach((([e,n])=>{null!=n&&t.append(e,n)})),this._request("GET",`/integrations?${t.toString()}`)}async createIntegration(e){return this._ensureConnected(),this._request("POST","/integrations",e)}async getIntegration(e){return this._ensureConnected(),this._request("GET",`/integrations/${e}`)}async updateIntegration(e,t){return this._ensureConnected(),this._request("PUT",`/integrations/${e}`,t)}async deleteIntegration(e){return this._ensureConnected(),this._request("DELETE",`/integrations/${e}`)}async testIntegration(e){return this._ensureConnected(),this._request("POST",`/integrations/${e}/test`)}async triggerIntegration(e,t,n={}){return this._ensureConnected(),this._request("POST",`/integrations/${e}/trigger`,{action:t,data:n})}async getNotifications(e={}){this._ensureConnected();const t=new URLSearchParams;return Object.entries(e).forEach((([e,n])=>{null!=n&&t.append(e,n)})),this._request("GET",`/notifications?${t.toString()}`)}async markNotificationAsRead(e){return this._ensureConnected(),this._request("POST",`/notifications/${e}/read`)}async markAllNotificationsAsRead(){return this._ensureConnected(),this._request("POST","/notifications/read-all")}async getNotificationPreferences(){return this._ensureConnected(),this._request("GET","/notifications/preferences")}async updateNotificationPreferences(e){return this._ensureConnected(),this._request("PUT","/notifications/preferences",e)}async addDeviceToken(e){return this._ensureConnected(),this._request("POST","/notifications/device-token",{token:e})}async removeDeviceToken(e){return this._ensureConnected(),this._request("DELETE",`/notifications/device-token?token=${encodeURIComponent(e)}`)}on(e,t){if("function"!=typeof t)throw new Error("Callback must be a function");this.eventListeners[e]||(this.eventListeners[e]=[]),this.eventListeners[e].push(t),this.enableWebSocket&&this._socketIsEnabled()&&!this.socket?.connected&&this._setupWebSocket().catch((e=>console.warn("Failed to setup WebSocket for event listener:",e.message)))}off(e,t){this.eventListeners[e]&&(t?this.eventListeners[e]=this.eventListeners[e].filter((e=>e!==t)):delete this.eventListeners[e])}getConnectionStatus(){return{isConnected:this.isConnected,websocketConnected:!!this.socket?.connected,websocketEnabled:this.enableWebSocket,reconnectCount:this.reconnectCount,activeWatchers:this.activeWatchers.size}}async retryWebSocketConnection(){if(!this.enableWebSocket||!this._socketIsEnabled())throw new Error("WebSocket not enabled or available");if(this.socket?.connected)return!0;try{return await this._setupWebSocket(),!0}catch(e){return console.error("Manual WebSocket retry failed:",e.message),!1}}disconnect(){this.socket&&(this.socket.disconnect(),this.socket=null),this.isConnected=!1,this.isConnecting=!1,this.reconnectCount=0,this.activeWatchers.clear()}async _request(e,n,r=null){const s=`${this.baseUrl}${n}`,o={Authorization:`Bearer ${this.apiKey}`,"X-API-Key":this.apiKey,"Content-Type":"application/json","User-Agent":"Cybernate-SDK/1.0",Accept:"application/json"},i={method:e,headers:o,timeout:this.timeout};!r||"POST"!==e&&"PUT"!==e&&"PATCH"!==e||(i.body=JSON.stringify(r)),console.log("API Request:",{method:e,url:s,headers:{...o,Authorization:o.Authorization?"Bearer [REDACTED]":"Missing","X-API-Key":o["X-API-Key"]?"[REDACTED]":"Missing"},hasBody:!!i.body});try{const e=await t(s,i);if(e.headers.has("X-RateLimit-Limit")&&(this.rateLimit.limit=parseInt(e.headers.get("X-RateLimit-Limit"),10)),e.headers.has("X-RateLimit-Remaining")&&(this.rateLimit.remaining=parseInt(e.headers.get("X-RateLimit-Remaining"),10)),e.headers.has("X-RateLimit-Reset")&&(this.rateLimit.reset=parseInt(e.headers.get("X-RateLimit-Reset"),10)),!e.ok){let t;try{t=await e.json()}catch(n){t={message:`HTTP ${e.status}: ${e.statusText}`}}throw console.error("API Error Response:",{status:e.status,statusText:e.statusText,url:s,errorData:t}),401===e.status?new Error(`Authentication failed: ${t.message||"Invalid API key"}`):403===e.status?new Error(`Access forbidden: ${t.message||"Insufficient permissions"}`):404===e.status?new Error(`Endpoint not found: ${t.message||"The requested resource was not found"}`):e.status>=500?new Error(`Server error: ${t.message||"Internal server error"}`):new Error(t.message||`HTTP error ${e.status}`)}const n=await e.json();return console.log("API Response:",{status:e.status,data:n}),n}catch(e){if(e.message.includes("fetch"))throw new Error(`Network error: Unable to connect to ${s}. Please check your internet connection.`);throw new Error(`API request failed: ${e.message}`)}}async _setupWebSocket(){return new Promise(((e,t)=>{if(!this._socketIsEnabled())return t(new Error("WebSocket not enabled or supported"));try{let n;if("undefined"!=typeof window&&void 0!==window.io)n=window.io;else{try{n=require("socket.io-client")}catch(e){return t(new Error("socket.io-client package not found. Install with: npm install socket.io-client"))}}this.socket&&(this.socket.disconnect(),this.socket=null),this.socket=n(`${this.baseUrl}/events`,{auth:{token:this.apiKey},transports:["websocket","polling"],reconnection:this.autoReconnect,reconnectionAttempts:this.reconnectAttempts,reconnectionDelay:this.reconnectDelay,timeout:this.timeout,forceNew:!0}),this.socket.on("connect",(()=>{console.log("Connected to Cybernate events socket"),this.reconnectCount=0,e()})),this.socket.on("disconnect",(e=>{console.log("Disconnected from Cybernate events socket:",e),"io server disconnect"===e&&this.autoReconnect&&setTimeout((()=>{this.reconnectCount<this.reconnectAttempts&&(this.reconnectCount++,console.log(`Attempting to reconnect (${this.reconnectCount}/${this.reconnectAttempts})...`),this._setupWebSocket().catch((()=>{})))}),this.reconnectDelay)})),this.socket.on("connect_error",(e=>{console.error("Socket connection error:",e.message),0===this.reconnectCount&&t(new Error(`WebSocket connection failed: ${e.message}`))})),this.socket.on("error",(e=>{console.error("Socket error:",e)})),this.socket.on("event",(e=>{this._dispatchEvent(e)})),this.socket.on("notification",(e=>{this._dispatchEvent({...e,eventType:"notification"})})),this.socket.on("system",(e=>{this._dispatchEvent({...e,eventType:"system"})}));const r=setTimeout((()=>{this.socket?.connected||(this.socket?.disconnect(),t(new Error("WebSocket connection timeout")))}),this.timeout);this.socket.on("connect",(()=>{clearTimeout(r)}))}catch(e){t(new Error(`Failed to initialize WebSocket: ${e.message}`))}}))}_dispatchEvent(e){const t=e.eventType||"detection";this.eventListeners[t]&&this.eventListeners[t].forEach((n=>{try{n(e)}catch(e){console.error(`Error in event listener for ${t}:`,e)}})),this.eventListeners.all&&this.eventListeners.all.forEach((t=>{try{t(e)}catch(e){console.error('Error in "all" event listener:',e)}}))}_socketIsEnabled(){return"undefined"!=typeof window&&void 0!==window.io||this._isSocketIOAvailable()}_isSocketIOAvailable(){try{return require.resolve("socket.io-client"),!0}catch(e){return!1}}_ensureConnected(){if(!this.isConnected)throw new Error("Not connected to Cybernate API. Call connect() first.")}}e.exports?e.exports={CybernateAI:n}:"undefined"!=typeof window&&(window.CybernateAI=n)}(r),t(r.exports)}));
//# sourceMappingURL=index.umd.js.map