diff --git a/docs/photoniq/event-delivery/clients/index.md b/docs/photoniq/event-delivery/clients/index.md index 693d122dbd..11ac256155 100644 --- a/docs/photoniq/event-delivery/clients/index.md +++ b/docs/photoniq/event-delivery/clients/index.md @@ -115,11 +115,20 @@ let connection = PhotoniqEdsSdk.create(config); | **Property** | **Type** | **Requred** | **Description** | |----------------------|-----------|-----------|-----------------------------------| -| `host` | `string` | Yes | Host of the connectionn | +| `host` | `string` | Yes | Host of the connection | | `customerId` | `string` | Yes | Customer ID credentails | | `apiKey` | `string` | Yes | ApiKey credentails | | `fabric` | `string` | No | Fabric to be used. Default is `_system` | -| `connectionTypes` | `string[]` | No | Use type of connection and priority. Default is `["ws"]`. Types: `ws`, `sse` | -| `queryType` | `string` | No | Type of query to use. Types: `"SQL"` | +| `connectionTypes` | `(string `\|` SubConfig)[]` | No | Use type of connection and priority. Default is `["ws"]`. Types: `ws`, `sse` | | `autoReconnect` | `boolean` | No | Automatically reconnect in case of network issues. Default is `true` | -| `pingSeconds` | `number` | No | Seconds between ping-pong messages to the WebSocket server. Default is `29` | + +#### `SubConfig` instance schema: + +| **Property** | **Type** | **Requred** | **Description** | +|----------------------|-----------|-----------|-----------------------------------| +| `type` | `string` | Yes | Type of the connection. Value: `ws` or `sse` | +| `customerId` | `string` | No | Customer ID credentails. Default set from `Config` | +| `apiKey` | `string` | No | ApiKey credentails. Default set from `Config` | +| `fabric` | `string` | No | Fabric to be used. Default set from `Config` | +| `pingSeconds` | `number` | No | Seconds between ping-pong messages to the WebSocket server. Default is `29`. Acceptable only for `ws` connection. | +| `flushTimeoutMs` | `number` | No | Seconds between ping-pong messages to the WebSocket server. Default is `20`. Acceptable only for `sse` connection. | \ No newline at end of file diff --git a/docs/photoniq/event-delivery/clients/query-set-and-batch.md b/docs/photoniq/event-delivery/clients/query-set-and-batch.md index 0569ea9320..a6622fcb0f 100644 --- a/docs/photoniq/event-delivery/clients/query-set-and-batch.md +++ b/docs/photoniq/event-delivery/clients/query-set-and-batch.md @@ -25,8 +25,8 @@ querySet.retrieve("SELECT * FROM WHERE key=", (event |--------------|------------|----------|------------------------| | `query` | `string` | Yes | SQL query to retrieve/listen | | `resultListener`| `function` | Yes | [Info](/photoniq/event-delivery/clients/listeners-and-errors#result-listener) | -| `errorListener`| `function` | No | [Info](/photoniq/event-delivery/clients/listeners-and-errors#error-listener) | -| `compress` | `boolean` | No | Compress incoming initial data. | +| `errorListenerOrOptions`| `function `\|` QueryOptions` | No | [Info](/photoniq/event-delivery/clients/listeners-and-errors#error-listener) or set query options | +| `options` | `QueryOptions` | No | Set query options. | ### retrieveAndSubscribe @@ -41,8 +41,8 @@ querySet.retrieveAndSubscribe("SELECT * FROM WHERE key= WHERE key=", (even |--------------|------------|----------|-------------------| | `query` | `string` | Yes | SQL query to retrieve/listen | | `resultListener`| `function` | Yes | [Info](/photoniq/event-delivery/clients/listeners-and-errors#result-listener) | -| `errorListener`| `function` | No | [Info](/photoniq/event-delivery/clients/listeners-and-errors#error-listener) | +| `errorListenerOrOptions`| `function `\|` QueryOptions` | No | [Info](/photoniq/event-delivery/clients/listeners-and-errors#error-listener) or set query options | +| `options` | `QueryOptions` | No | Set query options. | ### unubscribe @@ -92,3 +93,10 @@ Removes all subscriptions in the `QuerySet`: ```js querySet.unsubscribeAll(); ``` + + +#### `QueryOptions` instance schema: + +| **Property** | **Type** | **Requred** | **Description** | +|--------------|----------|-------------|-----------------| +| `compress` | `bolean` | No | compress response data | \ No newline at end of file diff --git a/static/download/eds-clients/photoniq-eds-sdk.min.js b/static/download/eds-clients/photoniq-eds-sdk.min.js index 9e0bea88ff..5c411de54c 100644 --- a/static/download/eds-clients/photoniq-eds-sdk.min.js +++ b/static/download/eds-clients/photoniq-eds-sdk.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PhotoniqEdsSdk=t():e.PhotoniqEdsSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{connect:()=>m,create:()=>b});const r="x-photoniq-es";var i,s;!function(e){e.Open="open",e.Close="close",e.Properties="properties",e.ServerQueryError="server-query-error",e.ServerGlobalError="server-global-error",e.ClientQueryError="client-query-error",e.ClientGlobalError="client-global-error",e.Message="message"}(i||(i={})),function(e){e.Closed="closed",e.Connecting="connecting",e.Open="open",e.Closing="closing"}(s||(s={}));var n=function(e,t,r,i){return new(r||(r=Promise))((function(s,n){function o(e){try{l(i.next(e))}catch(e){n(e)}}function c(e){try{l(i.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,c)}l((i=i.apply(e,t||[])).next())}))};function o(e){for(let t in e){let r=t.split(".");if(r.length<=1)continue;let i=e;for(let e=0;ee.charCodeAt(0))),r=new Blob([t],{type:"application/octet-stream"}),i=new DecompressionStream("gzip"),s=r.stream().pipeThrough(i),n=yield new Response(s);return yield n.text()}))}class l{constructor(e,t){this.STUB_FILTER="%7B%22action%22%3A%22remove%22%2C%22queries%22%3A%5B%22SELECT%20%2A%20FROM%20fake%22%5D%7D",this.DEFAULT_PING_SECONDS=29,this.properties={},this.config=e,this.filtersState=t}connect(){let e=this;const t=`wss://${this.config.host}/api/es/v1/subscribe?type=collection&x-customer-id=${this.config.customerId}&apiKey=${this.config.apiKey}&fabric=${this.config.fabric}&filters=${this.STUB_FILTER}`;this.ws=new WebSocket(t),this.ws.addEventListener("open",(function(t){var r;null===(r=e.openListener)||void 0===r||r.call(e,t);let i=e.filtersState.activeFilters();e.send(i),e.updatePingInterval()})),this.ws.addEventListener("message",(function(t){var i;if(e.properties[r])(function(e){return n(this,void 0,void 0,(function*(){return new Promise(((t,r)=>{try{t(JSON.parse(e))}catch(i){try{c(e).then((e=>t(JSON.parse(e))))}catch(e){r(e)}}}))}))})(t.data).then((t=>{var r,i;if(t.error)null===(i=e.errorListener)||void 0===i||i.call(e,t,!0);else for(let i in t){let s=t[i],n=e.filtersState.filterForQuery(i);if(n){e.filtersState.increment(n),null===(r=e.messageListener)||void 0===r||r.call(e,i,n,s);let t=e.filtersState.tryToRemove(n,i);t&&e.send([t])}}}));else{const r=t.data.split("\n");for(const t of r){const r=t.split(":");2==r.length&&(e.properties[r[0].trim()]=r[1].trim())}null===(i=e.propertiesListener)||void 0===i||i.call(e,e.properties)}e.updatePingInterval()})),this.ws.addEventListener("close",(function(t){var r;null===(r=e.closeListener)||void 0===r||r.call(e,t)})),this.ws.addEventListener("error",(function(t){var r;null===(r=e.errorListener)||void 0===r||r.call(e,t,!1)}))}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onClose(e){this.closeListener=e,this.pingIntervalId&&clearInterval(this.pingIntervalId)}onError(e){this.errorListener=e}send(e){var t;if(this.getStatus()===s.Open)for(const r of e)null===(t=this.ws)||void 0===t||t.send(JSON.stringify(r))}disconnect(){return!!this.ws&&(this.ws.close(),!0)}getStatus(){var e;switch(null===(e=this.ws)||void 0===e?void 0:e.readyState){case WebSocket.CONNECTING:return s.Connecting;case WebSocket.OPEN:return s.Open;case WebSocket.CLOSING:return s.Closing;default:return s.Closed}}getId(){return this.properties[r]}getProperty(e){return this.properties[e]}getProperties(){return this.properties}updatePingInterval(){var e;void 0!==this.pingIntervalId&&(clearInterval(this.pingIntervalId),this.pingIntervalId=void 0);let t=this;(!t.config.pingSeconds||t.config.pingSeconds>0)&&(this.pingIntervalId=setInterval((()=>{var e;t.getStatus()===s.Open&&(null===(e=t.ws)||void 0===e||e.send("{1}"))}),1e3*(null!==(e=t.config.pingSeconds)&&void 0!==e?e:this.DEFAULT_PING_SECONDS)))}}class a{constructor(e,t){this.properties={},this.url=e,this.headers=t}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onError(e){this.errorListener=e}onClose(e){this.closeListener=e}connect(e){return t=this,r=void 0,s=function*(){var t,r,i,s,n,o;try{const o=yield fetch(this.url,{method:"POST",headers:this.headers,body:JSON.stringify(e)});o.ok?null===(r=this.openListener)||void 0===r||r.call(this,o):null===(t=this.errorListener)||void 0===t||t.call(this,o);const c=o.body;let l,a="";for(this.reader=c.getReader();!(l=yield this.reader.read()).done;){let e,t=new TextDecoder("utf-8").decode(l.value);for(a+=t;(e=a.indexOf("\n\n"))>-1;){let r=!1,n=a.substring(0,e);if(a=a.substring(e+2),n.startsWith(":")){const e=t.split("\n");for(const t of e){const e=t.split(":");3==e.length&&(this.properties[e[1].trim()]=e[2].trim(),r=!0)}}else{let e=n.indexOf(":");if(e>-1){let t=n.substring(0,e).trim();" "===n[e+1]&&e++,e++;let r=n.substring(e).replace(/\ndata: ?/g,"\n");"data"===t?null===(i=this.messageListener)||void 0===i||i.call(this,r):console.warn(`Not supported message with type of message ${t}: ${r}`)}}r&&(null===(s=this.propertiesListener)||void 0===s||s.call(this,this.properties))}}null===(n=this.closeListener)||void 0===n||n.call(this,"Connection closed")}catch(e){null===(o=this.errorListener)||void 0===o||o.call(this,e)}},new((i=void 0)||(i=Promise))((function(e,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function c(e){try{l(s.throw(e))}catch(e){n(e)}}function l(t){var r;t.done?e(t.value):(r=t.value,r instanceof i?r:new i((function(e){e(r)}))).then(o,c)}l((s=s.apply(t,r||[])).next())}));var t,r,i,s}disconnect(){var e;null===(e=this.reader)||void 0===e||e.cancel()}getProperty(e){return this.properties[e]}getProperties(){return this.properties}}const u="FALSE",h="TRUE",d="add",f="remove";class p{constructor(e,t){this.config=e,this.queries=new Map,this.globalListener=t}calculateFilter(e,t,r){return{action:e,queries:[t],initialData:r.querySets.some((e=>e.initialData))?h:void 0,once:r.querySets.every((e=>e.once))?h:void 0,compress:r.querySets.some((e=>e.compress))?h:void 0,filterType:this.config.queryType}}increment(e){for(const t of e.querySets)t.count++}tryToRemove(e,t){if(e.querySets.every((e=>e.once)))return this.queries.delete(t),{action:f,queries:[t]}}equalFiltersWithoutQueries(e,t){return e.action===t.action&&e.compress===t.compress&&e.initialData===t.initialData&&e.once===t.once}addQueries(e,t,r,i,s){let n=[];for(const o of e){let e=this.queries.get(o.query);if(e){let c=this.calculateFilter(d,o.query,e),l=e.querySets.find((e=>e.querySet===s));l?(l.initialData=t,l.once=r,l.compress=i,-1==l.callbacks.indexOf(o.listener)&&l.callbacks.push(o.listener),-1==l.errorCallbacks.indexOf(o.errorListener)&&l.errorCallbacks.push(o.errorListener)):e.querySets.push({querySet:s,initialData:t,compress:i,once:r,count:0,callbacks:o.listener?[o.listener]:[],errorCallbacks:o.errorListener?[o.errorListener]:[]});let a=this.calculateFilter(d,o.query,e);if(!this.equalFiltersWithoutQueries(c,a)){let e=n.find((e=>this.equalFiltersWithoutQueries(e,a)));e?e.queries.push(o.query):n.push(a)}}else{let e={querySets:[{querySet:s,initialData:t,compress:i,once:r,count:0,callbacks:o.listener?[o.listener]:[],errorCallbacks:o.errorListener?[o.errorListener]:[]}]};this.queries.set(o.query,e);let c=this.calculateFilter(d,o.query,e),l=n.find((e=>this.equalFiltersWithoutQueries(e,c)));l?l.queries.push(o.query):n.push(c)}}return n}filterForQuery(e){return this.queries.get(e)}removeAllQueries(e){let t=Array.from(this.queries.keys());return this.removeQueries(t,e)}removeQueries(e,t){let r=[];for(const i of e){let e=this.queries.get(i);if(e){let s=e.querySets.findIndex((e=>e.querySet===t));s>-1&&e.querySets.splice(s,1),e.querySets.length||(this.queries.delete(i),r.push(i))}}if(r.length)return{action:f,queries:r}}activeFilters(){let e=[];for(const[t,r]of this.queries){const i=this.calculateFilter(d,t,r);let s=e.find((e=>this.equalFiltersWithoutQueries(e,i)));s?s.queries.push(t):e.push(i)}return e}handleErrorListeners(e,t,r){for(let i of e)try{i(r)}catch(e){console.warn(`Error while handling error listener for query: ${t}`,e)}}handleGlobalListener(e){var t;try{null===(t=this.globalListener)||void 0===t||t.call(this,e)}catch(e){console.warn("Error while handling global error listener",e)}}}class v{constructor(e,t){this.ENCODED_GZ_CONTENT="encoded-gz-content: ",this.FAILED_TO_PARSE_QUERY="Failed to parse query: ",this.config=e,this.filtersState=t,this.url=`https://${this.config.host}/api/es/sse/v1/subscribe`,this.headers={"Content-Type":"application/json",Authorization:`${this.config.apiKey}`,"x-customer-id":`${this.config.customerId}`},this.status=s.Closed}send(e){if(null==e?void 0:e.length){let t=this.filtersState.activeFilters();this.eventSource?(this.eventSource.disconnect(),this.eventSource=void 0,this.retrieve(e,(()=>{this.subscribe(t)}))):this.retrieve(t,(()=>{this.subscribe(t)}))}}connect(){if(this.eventSource)throw Error("SSE connection already opened");let e=this.filtersState.activeFilters();this.retrieve(e,(()=>{this.subscribe(e)}))}retrieve(e,t){var r;let i=e.filter((e=>e.initialData===h)).map((e=>e.queries)).reduce(((e,t)=>e.concat(t)),[]);if(!i.length)return this.subscribe(e),void t();let n=e.filter((e=>e.initialData===h)).some((e=>e.compress)),o={type:"collection",fabric:this.config.fabric,filters:{once:h,compress:n?h:u,initialData:h,queries:i}},c=this;this.eventSource||null===(r=this.openListener)||void 0===r||r.call(this,"SSE connection opened"),this.eventSource=new a(this.url,this.headers),this.eventSource.onOpen((e=>{var t;c.status===s.Connecting&&(c.status=s.Open,null===(t=c.openListener)||void 0===t||t.call(c,e))})),this.eventSource.onProperties((e=>{var t;null===(t=c.propertiesListener)||void 0===t||t.call(c,e)})),this.eventSource.onError((e=>{var t;null===(t=c.errorListener)||void 0===t||t.call(c,e,!1)})),this.eventSource.onMessage((e=>{c.handleMessage(e).then((r=>{var s,n;if(r)try{let r=JSON.parse(e);for(let e in r){let t=i.indexOf(e);t>-1&&i.splice(t,1)}i.length||(null===(s=c.eventSource)||void 0===s||s.disconnect(),c.eventSource=void 0,t())}catch(e){null===(n=c.errorListener)||void 0===n||n.call(c,e,!1)}}))})),this.status===s.Closed&&(this.status=s.Connecting),this.eventSource.connect(o)}subscribe(e){let t=e.filter((e=>e.once!==h)).map((e=>e.queries)).reduce(((e,t)=>e.concat(t)),[]);if(!t.length)return;let r=e.filter((e=>e.once!==h)).some((e=>e.compress)),i={type:"collection",fabric:this.config.fabric,filters:{action:d,filterType:"SQL",once:u,compress:r?h:u,initialData:u,queries:t}},n=this;this.eventSource=new a(this.url,this.headers),this.eventSource.onOpen((e=>{var t;n.status===s.Connecting&&(n.status=s.Open,null===(t=n.openListener)||void 0===t||t.call(n,e))})),this.eventSource.onError((e=>{var t,r;null===(t=n.errorListener)||void 0===t||t.call(n,e,!1),null===(r=n.closeListener)||void 0===r||r.call(n,e)})),this.eventSource.onProperties((e=>{var t;null===(t=n.propertiesListener)||void 0===t||t.call(n,e)})),this.eventSource.onMessage((e=>{n.handleMessage(e)})),this.eventSource.onClose((e=>{var t;this.status===s.Closing&&(this.status=s.Closed,null===(t=n.closeListener)||void 0===t||t.call(n,e))})),this.status===s.Closed&&(this.status=s.Connecting),this.eventSource.connect(i)}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onClose(e){this.closeListener=e}onError(e){this.errorListener=e}getStatus(){return this.status}disconnect(){var e;return!!this.eventSource&&(this.status=s.Closing,null===(e=this.eventSource)||void 0===e||e.disconnect(),this.eventSource=void 0,!0)}getId(){return this.getProperty(r)}getProperty(e){var t;return null===(t=this.eventSource)||void 0===t?void 0:t.getProperty(e)}getProperties(){return this.eventSource?this.eventSource.getProperties():{}}handleMessage(e){return this.tryToDecodeData(e).then((e=>{var t,r;if(e.error)return null===(r=this.errorListener)||void 0===r||r.call(this,e,!0),!1;for(let r in e){let i=e[r],s=this.filtersState.filterForQuery(r);s&&(this.filtersState.increment(s),null===(t=this.messageListener)||void 0===t||t.call(this,r,s,i),this.filtersState.tryToRemove(s,r))}return!0}))}tryToDecodeData(e){return t=this,r=void 0,s=function*(){return new Promise(((t,r)=>{if(e.startsWith(this.ENCODED_GZ_CONTENT))try{c(e.substring(this.ENCODED_GZ_CONTENT.length)).then((e=>t(JSON.parse(e))))}catch(e){r(e)}else if(e.startsWith(this.FAILED_TO_PARSE_QUERY))t({error:e,code:400});else try{t(JSON.parse(e))}catch(e){r(e)}}))},new((i=void 0)||(i=Promise))((function(e,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function c(e){try{l(s.throw(e))}catch(e){n(e)}}function l(t){var r;t.done?e(t.value):(r=t.value,r instanceof i?r:new i((function(e){e(r)}))).then(o,c)}l((s=s.apply(t,r||[])).next())}));var t,r,i,s}}class g{constructor(e,t,r){this.subscribeQueries=[],this.retrieveAndSubscribeQueries=[],this.retrieveQueries=[],this.unsubscribeQueries=[],this.querySet=e,this.connection=t,this.filtersState=r}subscribe(e,t,r){return this.subscribeQueries.push({query:e,listener:t,errorListener:r,compress:!1}),this}retrieveAndSubscribe(e,t,r,i){return this.retrieveAndSubscribeQueries.push({query:e,listener:t,errorListener:r,compress:!0===i}),this}retrieve(e,t,r,i){return this.retrieveQueries.push({query:e,listener:t,errorListener:r,compress:!0===i}),this}unsubscribe(e){return this.unsubscribeQueries.push(e),this}assemble(){let e=this.retrieveQueries.some((e=>e.compress)),t=this.filtersState.addQueries(this.retrieveQueries,!0,!0,e,this.querySet),r=this.retrieveAndSubscribeQueries.some((e=>e.compress)),i=this.filtersState.addQueries(this.retrieveAndSubscribeQueries,!0,!1,r,this.querySet);this.joinFilters(t,i);let s=this.filtersState.addQueries(this.subscribeQueries,!1,!1,!1,this.querySet);this.joinFilters(t,s);let n=this.filtersState.removeQueries(this.unsubscribeQueries,this.querySet);n&&t.push(n),this.connection.send(t)}joinFilters(e,t){for(const r of t){let t=e.find((e=>this.filtersState.equalFiltersWithoutQueries(e,r)));t?t.queries.push(...r.queries):e.push(r)}}}class S{constructor(e,t){this.connection=e,this.filtersState=t}subscribe(e,t,r){let i=[{query:e,listener:t,errorListener:r,compress:!1}],s=this.filtersState.addQueries(i,!1,!1,!1,this);for(const e of s)this.connection.send([e])}retrieveAndSubscribe(e,t,r,i){let s=[{query:e,listener:t,errorListener:r,compress:!0===i}],n=this.filtersState.addQueries(s,!0,!1,!0===i,this);for(const e of n)this.connection.send([e])}retrieve(e,t,r,i){let s=[{query:e,listener:t,errorListener:r,compress:!0===i}],n=this.filtersState.addQueries(s,!0,!0,!0===i,this);for(const e of n)this.connection.send([e])}unsubscribe(e){let t=this.filtersState.removeQueries([e],this);t&&this.connection.send([t])}unsubscribeAll(){let e=this.filtersState.removeAllQueries(this);e&&this.connection.send([e])}batch(){return new g(this,this.connection,this.filtersState)}}class y{constructor(e,t){this.connectionTypes=["ws"],this.reconnection=-1,this.config=e,this.filtersState=new p(e,t)}connect(){var e;if(this.connection)throw new Error(`Already connected with status: ${this.getStatus()}`);(null===(e=this.config.connectionTypes)||void 0===e?void 0:e.length)&&(this.connectionTypes=this.config.connectionTypes),-1===this.reconnection&&(this.reconnection=0);let t=this.connectionTypes[this.reconnection%this.connectionTypes.length];switch(t){case"ws":this.connection=new l(this.config,this.filtersState);break;case"sse":this.connection=new v(this.config,this.filtersState);break;default:throw new Error(`Connection type not supported: ${t}`)}let r=this;this.connection.onOpen((function(e){let t=r.reconnection;if(r.reconnection=0,-1===t){const t={type:i.Open,connection:r,data:e};r.filtersState.handleGlobalListener(t)}})),this.connection.onProperties((function(e){const t={type:i.Properties,connection:r,data:e};r.filtersState.handleGlobalListener(t)})),this.connection.onMessage((function(e,t,s){let n=s,c=Array.isArray(n);if(c)for(let e=0;e-1){let e=Math.pow(2,6+r.reconnection++);setTimeout((function(){r.connect()}),e)}else{r.reconnection=-1;const t={type:i.Close,connection:r,data:e};r.filtersState.handleGlobalListener(t)}})),this.connection.connect()}send(e){var t;null===(t=this.connection)||void 0===t||t.send(e)}disconnect(){var e;return-1!==this.reconnection&&(this.reconnection=-1,null===(e=this.connection)||void 0===e||e.disconnect(),!0)}getConfig(){return this.config}getStatus(){return-1===this.reconnection?s.Closed:this.connection?this.connection.getStatus():s.Connecting}getId(){var e;return null===(e=this.connection)||void 0===e?void 0:e.getId()}getProperty(e){var t;return null===(t=this.connection)||void 0===t?void 0:t.getProperty(e)}getProperties(){return this.connection?this.connection.getProperties():{}}querySet(){return new S(this,this.filtersState)}}function b(e,t){return new y(e,t)}function m(e,t){let r=new y(e,t);return r.connect(),r}return t})())); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PhotoniqEdsSdk=t():e.PhotoniqEdsSdk=t()}(this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var r in i)e.o(i,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:i[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{connect:()=>m,create:()=>b});const i="x-photoniq-es";var r,s;!function(e){e.Open="open",e.Close="close",e.Properties="properties",e.ServerQueryError="server-query-error",e.ServerGlobalError="server-global-error",e.ClientQueryError="client-query-error",e.ClientGlobalError="client-global-error",e.Message="message"}(r||(r={})),function(e){e.Closed="closed",e.Connecting="connecting",e.Open="open",e.Closing="closing"}(s||(s={}));var n=function(e,t,i,r){return new(i||(i=Promise))((function(s,n){function o(e){try{c(r.next(e))}catch(e){n(e)}}function l(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,l)}c((r=r.apply(e,t||[])).next())}))};function o(e){for(let t in e){let i=t.split(".");if(i.length<=1)continue;let r=e;for(let e=0;ee.charCodeAt(0))),i=new Blob([t],{type:"application/octet-stream"}),r=new DecompressionStream("gzip"),s=i.stream().pipeThrough(r),n=yield new Response(s);return yield n.text()}))}class c{constructor(e,t,i){this.STUB_FILTER="%7B%22action%22%3A%22remove%22%2C%22queries%22%3A%5B%22SELECT%20%2A%20FROM%20fake%22%5D%7D",this.DEFAULT_PING_SECONDS=29,this.properties={},this.config=e,this.subConfig=t,this.filtersState=i}connect(){let e=this,t=this.subConfig.url?this.subConfig.url:`wss://${this.config.host}/api/es/v1/subscribe`,r=this.subConfig.apiKey?this.subConfig.apiKey:this.config.apiKey,o=this.subConfig.fabric?this.subConfig.fabric:this.config.fabric?this.config.fabric:"_system";const c=`${t}?type=collection&x-customer-id=${this.subConfig.fabric?this.subConfig.fabric:this.config.customerId}&apiKey=${r}&fabric=${o}&filters=${this.STUB_FILTER}`;this.ws=new WebSocket(c),this.ws.addEventListener("open",(function(t){var i,r;null===(i=e.openListener)||void 0===i||i.call(e,t);let n=e.filtersState.activeFilters();if(e.getStatus()===s.Open)for(const t of n)null===(r=e.ws)||void 0===r||r.send(JSON.stringify(t)),e.filtersState.activeFilterSent(t);e.updatePingInterval()})),this.ws.addEventListener("message",(function(t){var r;if(e.properties[i])(function(e){return n(this,void 0,void 0,(function*(){return new Promise(((t,i)=>{try{t(JSON.parse(e))}catch(r){try{l(e).then((e=>t(JSON.parse(e))))}catch(e){i(e)}}}))}))})(t.data).then((t=>{var i,r;if(t.error)null===(r=e.errorListener)||void 0===r||r.call(e,t,!0);else for(let r in t){let s=t[r],n=e.filtersState.filterForQuery(r);n&&(e.filtersState.increment(n),null===(i=e.messageListener)||void 0===i||i.call(e,r,n,s),e.filtersState.tryToRemove(n,r),e.flush())}}));else{const i=t.data.split("\n");for(const t of i){const i=t.split(":");2==i.length&&(e.properties[i[0].trim()]=i[1].trim())}null===(r=e.propertiesListener)||void 0===r||r.call(e,e.properties)}e.updatePingInterval()})),this.ws.addEventListener("close",(function(t){var i;null===(i=e.closeListener)||void 0===i||i.call(e,t)})),this.ws.addEventListener("error",(function(t){var i;null===(i=e.errorListener)||void 0===i||i.call(e,t,!1)}))}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onClose(e){this.closeListener=e,this.pingIntervalId&&clearInterval(this.pingIntervalId)}onError(e){this.errorListener=e}flush(){var e,t;if(this.getStatus()===s.Open){let i=this.filtersState.removeFilter();i&&(null===(e=this.ws)||void 0===e||e.send(JSON.stringify(i)),this.filtersState.removeFilterSent());let r=this.filtersState.activeNotSentFilters();for(const e of r)null===(t=this.ws)||void 0===t||t.send(JSON.stringify(e)),this.filtersState.activeFilterSent(e)}}disconnect(){return!!this.ws&&(this.ws.close(),!0)}getStatus(){var e;switch(null===(e=this.ws)||void 0===e?void 0:e.readyState){case WebSocket.CONNECTING:return s.Connecting;case WebSocket.OPEN:return s.Open;case WebSocket.CLOSING:return s.Closing;default:return s.Closed}}getId(){return this.properties[i]}getProperty(e){return this.properties[e]}getProperties(){return this.properties}updatePingInterval(){var e;void 0!==this.pingIntervalId&&(clearInterval(this.pingIntervalId),this.pingIntervalId=void 0);let t=this;(!t.subConfig.pingSeconds||t.subConfig.pingSeconds>0)&&(this.pingIntervalId=setInterval((()=>{var e;t.getStatus()===s.Open&&(null===(e=t.ws)||void 0===e||e.send("{1}"))}),1e3*(null!==(e=t.subConfig.pingSeconds)&&void 0!==e?e:this.DEFAULT_PING_SECONDS)))}}class a{constructor(e,t){this.properties={},this.disconnected=!1,this.url=e,this.headers=t}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onError(e){this.errorListener=e}onClose(e){this.closeListener=e}connect(e){return t=this,i=void 0,s=function*(){var t,i,r,s,n,o;try{const o=yield fetch(this.url,{method:"POST",headers:this.headers,body:JSON.stringify(e)});o.ok?null===(i=this.openListener)||void 0===i||i.call(this,o):null===(t=this.errorListener)||void 0===t||t.call(this,o);const l=o.body;let c,a="";for(this.reader=l.getReader(),this.disconnected&&this.disconnect();!(c=yield this.reader.read()).done;){let e,t=new TextDecoder("utf-8").decode(c.value);for(a+=t;(e=a.indexOf("\n\n"))>-1;){let i=!1,n=a.substring(0,e);if(a=a.substring(e+2),n.startsWith(":")){const e=t.split("\n");for(const t of e){const e=t.split(":");3==e.length&&(this.properties[e[1].trim()]=e[2].trim(),i=!0)}}else{let e=n.indexOf(":");if(e>-1){let t=n.substring(0,e).trim();" "===n[e+1]&&e++,e++;let i=n.substring(e).replace(/\ndata: ?/g,"\n");"data"===t?null===(r=this.messageListener)||void 0===r||r.call(this,i):console.warn(`Not supported message with type of message ${t}: ${i}`)}}i&&(null===(s=this.propertiesListener)||void 0===s||s.call(this,this.properties))}}null===(n=this.closeListener)||void 0===n||n.call(this,"Connection closed")}catch(e){null===(o=this.errorListener)||void 0===o||o.call(this,e)}},new((r=void 0)||(r=Promise))((function(e,n){function o(e){try{c(s.next(e))}catch(e){n(e)}}function l(e){try{c(s.throw(e))}catch(e){n(e)}}function c(t){var i;t.done?e(t.value):(i=t.value,i instanceof r?i:new r((function(e){e(i)}))).then(o,l)}c((s=s.apply(t,i||[])).next())}));var t,i,r,s}disconnect(){var e;this.disconnected=!0,null===(e=this.reader)||void 0===e||e.cancel()}getProperty(e){return this.properties[e]}getProperties(){return this.properties}}const u="FALSE",h="TRUE",f="add",d="remove";class p{constructor(e,t){this.config=e,this.queries=new Map,this.queriesToRemove=[],this.globalListener=t}calculateFilter(e,t,i){return{action:e,queries:[t],initialData:i.querySets.some((e=>e.initialData&&0===e.count))?h:void 0,once:i.querySets.every((e=>e.once))?h:void 0,compress:i.querySets.some((e=>e.compress))?h:void 0}}increment(e){for(const t of e.querySets)t.count++}tryToRemove(e,t){if(e.querySets.every((e=>e.once)))return this.queries.delete(t),-1==this.queriesToRemove.indexOf(t)&&this.queriesToRemove.push(t),{action:d,queries:[t]}}equalFiltersWithoutQueries(e,t){return e.action===t.action&&e.compress===t.compress&&e.initialData===t.initialData&&e.once===t.once}addQueries(e,t,i,r,s){let n=[];for(const o of e){let e=this.queries.get(o.query);if(e){let l=this.calculateFilter(f,o.query,e),c=e.querySets.find((e=>e.querySet===s));c?(c.initialData=t,c.once=i,c.compress=r,-1==c.callbacks.indexOf(o.listener)&&c.callbacks.push(o.listener),-1==c.errorCallbacks.indexOf(o.errorListener)&&c.errorCallbacks.push(o.errorListener)):e.querySets.push({querySet:s,initialData:t,compress:r,once:i,count:0,callbacks:o.listener?[o.listener]:[],errorCallbacks:o.errorListener?[o.errorListener]:[]});let a=this.calculateFilter(f,o.query,e);if(!this.equalFiltersWithoutQueries(l,a)){e.sent=!1;let t=n.find((e=>this.equalFiltersWithoutQueries(e,a)));t?t.queries.push(o.query):n.push(a)}}else{let e={querySets:[{querySet:s,initialData:t,compress:r,once:i,count:0,callbacks:o.listener?[o.listener]:[],errorCallbacks:o.errorListener?[o.errorListener]:[]}],sent:!1};this.queries.set(o.query,e);let l=this.calculateFilter(f,o.query,e),c=n.find((e=>this.equalFiltersWithoutQueries(e,l)));c?c.queries.push(o.query):n.push(l)}}return n}filterForQuery(e){return this.queries.get(e)}removeAllQueries(e){let t=Array.from(this.queries.keys());return this.removeQueries(t,e)}removeQueries(e,t){for(const i of e){let e=this.queries.get(i);if(e){let r=e.querySets.findIndex((e=>e.querySet===t));r>-1&&e.querySets.splice(r,1),e.querySets.length||(this.queries.delete(i),-1==this.queriesToRemove.indexOf(i)&&this.queriesToRemove.push(i))}}if(this.queriesToRemove.length)return{action:d,queries:this.queriesToRemove}}activeFilters(){let e=[];for(const[t,i]of this.queries){const r=this.calculateFilter(f,t,i);let s=e.find((e=>this.equalFiltersWithoutQueries(e,r)));s?s.queries.push(t):e.push(r)}return e}activeNotSentFilters(){let e=[];for(const[t,i]of this.queries){if(i.sent)continue;const r=this.calculateFilter(f,t,i);let s=e.find((e=>this.equalFiltersWithoutQueries(e,r)));s?s.queries.push(t):e.push(r)}return e}activeFiltersSent(e){for(let t of e)this.activeFilterSent(t)}activeFilterSent(e){for(let t of e.queries){let e=this.queries.get(t);e&&(e.sent=!0)}}allFiltersNotSent(){for(const[e,t]of this.queries)t.sent=!1}removeFilter(){let e=this.queriesToRemove.filter((e=>!this.queries.has(e)));if(0!==e.length)return{action:d,queries:e}}removeFilterSent(){this.queriesToRemove.splice(0,this.queriesToRemove.length)}handleErrorListeners(e,t,i){for(let r of e)try{r(i)}catch(e){console.warn(`Error while handling error listener for query: ${t}`,e)}}handleGlobalListener(e){var t;try{null===(t=this.globalListener)||void 0===t||t.call(this,e)}catch(e){console.warn("Error while handling global error listener",e)}}}class v{constructor(e,t,i){this.ENCODED_GZ_CONTENT="encoded-gz-content: ",this.FAILED_TO_PARSE_QUERY="Failed to parse query: ",this.DEFAULT_FLUSH_TIMEOUT_MS=20,this.config=e,this.subConfig=t,this.filtersState=i,this.url=this.subConfig.url?this.subConfig.url:`https://${this.config.host}/api/es/sse/v1/subscribe`;let r=this.subConfig.apiKey?this.subConfig.apiKey:this.config.apiKey;this.fabric=this.subConfig.fabric?this.subConfig.fabric:this.config.fabric?this.config.fabric:"_system";let n=this.subConfig.fabric?this.subConfig.fabric:this.config.customerId;this.retrievingInitialData=!1,this.retrieveInitialDataAgain=!1,this.headers={"Content-Type":"application/json",Authorization:`${r}`,"x-customer-id":`${n}`},this.status=s.Closed}flush(){var e;let t=this;this.retrieveTimeout||(this.retrieveTimeout=setTimeout((function(){t.retrieveTimeout=void 0,t.retrievingInitialData?t.retrieveInitialDataAgain=!0:t.flushNow()}),void 0!==(null===(e=this.subConfig)||void 0===e?void 0:e.flushTimeoutMs)?this.subConfig.flushTimeoutMs:this.DEFAULT_FLUSH_TIMEOUT_MS))}flushNow(){let e=this.filtersState.activeNotSentFilters();if(e.length>0){let t=this.filtersState.activeFilters(),i=e.filter((e=>e.initialData===h)).map((e=>e.queries)).reduce(((e,t)=>e.concat(t)),[]);if(this.filtersState.activeFiltersSent(e),i.length){let r=e.filter((e=>e.initialData===h)).some((e=>e.compress));this.retrievingInitialData=!0,this.retrieve(i,r,(()=>{this.retrievingInitialData=!1,this.retrieveInitialDataAgain?(this.retrieveInitialDataAgain=!1,this.flushNow()):this.subscribe(t)}))}else this.subscribe(t)}}connect(){if(this.eventSource)throw Error("SSE connection already opened");this.flush()}retrieve(e,t,i){var r;let n={type:"collection",fabric:this.fabric,filters:{once:h,compress:t?h:u,initialData:h,queries:e}},o=this;this.eventSource?this.eventSource.disconnect():null===(r=this.openListener)||void 0===r||r.call(this,"SSE connection opened"),this.eventSource=new a(this.url,this.headers),this.eventSource.onOpen((e=>{var t;o.status===s.Connecting&&(o.status=s.Open,null===(t=o.openListener)||void 0===t||t.call(o,e))})),this.eventSource.onProperties((e=>{var t;null===(t=o.propertiesListener)||void 0===t||t.call(o,e)})),this.eventSource.onError((e=>{var t;null===(t=o.errorListener)||void 0===t||t.call(o,e,!1)})),this.eventSource.onMessage((t=>{o.handleMessage(t).then((t=>{var r,s;if(t)try{for(let i in t){let t=e.indexOf(i);t>-1&&e.splice(t,1)}e.length||(null===(r=o.eventSource)||void 0===r||r.disconnect(),o.eventSource=void 0,i())}catch(e){null===(s=o.errorListener)||void 0===s||s.call(o,e,!1)}}))})),this.status===s.Closed&&(this.status=s.Connecting),this.eventSource.connect(n)}subscribe(e){var t;let i=e.filter((e=>e.once!==h)).map((e=>e.queries)).reduce(((e,t)=>e.concat(t)),[]);if(!i.length)return;this.eventSource?this.eventSource.disconnect():null===(t=this.openListener)||void 0===t||t.call(this,"SSE connection opened");let r=e.filter((e=>e.once!==h)).some((e=>e.compress)),n={type:"collection",fabric:this.fabric,filters:{once:u,compress:r?h:u,initialData:u,queries:i}},o=this;this.eventSource=new a(this.url,this.headers),this.eventSource.onOpen((e=>{var t;o.status===s.Connecting&&(o.status=s.Open,null===(t=o.openListener)||void 0===t||t.call(o,e))})),this.eventSource.onError((e=>{var t,i;null===(t=o.errorListener)||void 0===t||t.call(o,e,!1),null===(i=o.closeListener)||void 0===i||i.call(o,e)})),this.eventSource.onProperties((e=>{var t;null===(t=o.propertiesListener)||void 0===t||t.call(o,e)})),this.eventSource.onMessage((e=>{o.handleMessage(e)})),this.eventSource.onClose((e=>{var t;this.status===s.Closing&&(this.status=s.Closed,null===(t=o.closeListener)||void 0===t||t.call(o,e))})),this.status===s.Closed&&(this.status=s.Connecting),this.eventSource.connect(n)}onOpen(e){this.openListener=e}onProperties(e){this.propertiesListener=e}onMessage(e){this.messageListener=e}onClose(e){this.closeListener=e}onError(e){this.errorListener=e}getStatus(){return this.status}disconnect(){var e;return this.retrieveTimeout=void 0,!!this.eventSource&&(this.status=s.Closing,null===(e=this.eventSource)||void 0===e||e.disconnect(),this.eventSource=void 0,!0)}getId(){return this.getProperty(i)}getProperty(e){var t;return null===(t=this.eventSource)||void 0===t?void 0:t.getProperty(e)}getProperties(){return this.eventSource?this.eventSource.getProperties():{}}handleMessage(e){return this.tryToDecodeData(e).then((e=>{var t,i;if(!e.error){for(let i in e){let r=e[i],s=this.filtersState.filterForQuery(i);s&&(this.filtersState.increment(s),null===(t=this.messageListener)||void 0===t||t.call(this,i,s,r),this.filtersState.tryToRemove(s,i)&&this.flush())}return e}null===(i=this.errorListener)||void 0===i||i.call(this,e,!0)}))}tryToDecodeData(e){return t=this,i=void 0,s=function*(){return new Promise(((t,i)=>{if(e.startsWith(this.ENCODED_GZ_CONTENT))try{l(e.substring(this.ENCODED_GZ_CONTENT.length)).then((e=>t(JSON.parse(e))))}catch(e){i(e)}else if(e.startsWith(this.FAILED_TO_PARSE_QUERY))t({error:e,code:400});else try{t(JSON.parse(e))}catch(e){i(e)}}))},new((r=void 0)||(r=Promise))((function(e,n){function o(e){try{c(s.next(e))}catch(e){n(e)}}function l(e){try{c(s.throw(e))}catch(e){n(e)}}function c(t){var i;t.done?e(t.value):(i=t.value,i instanceof r?i:new r((function(e){e(i)}))).then(o,l)}c((s=s.apply(t,i||[])).next())}));var t,i,r,s}}class g{constructor(e,t,i){this.querySet=e,this.connection=t,this.filtersState=i}subscribe(e,t,i,r){return this.handleSubscription(e,t,!1,!1,i,r)}retrieveAndSubscribe(e,t,i,r){return this.handleSubscription(e,t,!0,!1,i,r)}retrieve(e,t,i,r){return this.handleSubscription(e,t,!0,!0,i,r)}handleSubscription(e,t,i,r,s,n){let o={query:e,listener:t};return"function"==typeof s?o.errorListener=s:"object"==typeof s&&null!==s&&(n=s),this.filtersState.addQueries([o],i,r,!0===(null==n?void 0:n.compress),this.querySet),this}unsubscribe(e){return this.filtersState.removeQueries([e],this.querySet),this}assemble(){this.connection.flush()}}class S{constructor(e,t){this.connection=e,this.filtersState=t}subscribe(e,t,i,r){this.handleSubscription(e,t,!1,!1,i,r)}retrieveAndSubscribe(e,t,i,r){this.handleSubscription(e,t,!0,!1,i,r)}retrieve(e,t,i,r){this.handleSubscription(e,t,!0,!0,i,r)}handleSubscription(e,t,i,r,s,n){let o={query:e,listener:t};"function"==typeof s?o.errorListener=s:"object"==typeof s&&null!==s&&(n=s),this.filtersState.addQueries([o],i,r,!0===(null==n?void 0:n.compress),this),this.connection.flush()}unsubscribe(e){this.filtersState.removeQueries([e],this),this.connection.flush()}unsubscribeAll(){this.filtersState.removeAllQueries(this),this.connection.flush()}batch(){return new g(this,this.connection,this.filtersState)}}class y{constructor(e,t){this.connectionTypes=["ws"],this.reconnection=-1,this.config=e,this.filtersState=new p(e,t)}connect(){var e;if(this.connection)throw new Error(`Already connected with status: ${this.getStatus()}`);(null===(e=this.config.connectionTypes)||void 0===e?void 0:e.length)&&(this.connectionTypes=this.config.connectionTypes),-1===this.reconnection&&(this.reconnection=0);let t=this.connectionTypes[this.reconnection%this.connectionTypes.length];switch("string"==typeof t?t:t.type){case"ws":let e="string"==typeof t?{type:t}:t;this.connection=new c(this.config,e,this.filtersState);break;case"sse":let i="string"==typeof t?{type:t}:t;this.connection=new v(this.config,i,this.filtersState);break;default:throw new Error(`Connection type not supported: ${t}`)}let i=this;this.connection.onOpen((function(e){let t=i.reconnection;if(i.reconnection=0,-1===t){const t={type:r.Open,connection:i,data:e};i.filtersState.handleGlobalListener(t)}})),this.connection.onProperties((function(e){const t={type:r.Properties,connection:i,data:e};i.filtersState.handleGlobalListener(t)})),this.connection.onMessage((function(e,t,s){let n=s,l=Array.isArray(n);if(l)for(let e=0;e-1){let e=Math.pow(2,6+i.reconnection++);setTimeout((function(){i.connect()}),e)}else{i.reconnection=-1;const t={type:r.Close,connection:i,data:e};i.filtersState.handleGlobalListener(t)}})),this.connection.connect()}flush(){var e;null===(e=this.connection)||void 0===e||e.flush()}disconnect(){var e;return-1!==this.reconnection&&(this.reconnection=-1,null===(e=this.connection)||void 0===e||e.disconnect(),!0)}getConfig(){return this.config}getStatus(){return-1===this.reconnection?s.Closed:this.connection?this.connection.getStatus():s.Connecting}getId(){var e;return null===(e=this.connection)||void 0===e?void 0:e.getId()}getProperty(e){var t;return null===(t=this.connection)||void 0===t?void 0:t.getProperty(e)}getProperties(){return this.connection?this.connection.getProperties():{}}querySet(){return new S(this,this.filtersState)}}function b(e,t){return new y(e,t)}function m(e,t){let i=new y(e,t);return i.connect(),i}return t})())); \ No newline at end of file