@laplace.live/event-bridge-sdk 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +1 -1
  2. package/index.ts +11 -13
  3. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var K;((A)=>{A.DISCONNECTED="disconnected";A.CONNECTING="connecting";A.CONNECTED="connected";A.RECONNECTING="reconnecting"})(K||={});class N{ws=null;eventHandlers=new Map;anyEventHandlers=[];connectionStateHandlers=[];reconnectTimer=null;reconnectAttempts=0;clientId=null;serverVersion=null;connectionState="disconnected";lastPingTime=null;pingMonitorTimer=null;options={url:"ws://localhost:9696",token:"",reconnect:!0,reconnectInterval:3000,maxReconnectAttempts:1000,pingTimeout:90000};constructor(q={}){this.options={...this.options,...q}}connect(){return new Promise((q,w)=>{try{if(this.ws)this.ws.close();this.setConnectionState("connecting");let z=this.options.url,E=[];if(this.options.token){E.push("laplace-event-bridge-role-client",this.options.token);let A=new URL(z);A.searchParams.set("token",this.options.token),z=A.toString()}this.ws=new WebSocket(z,E),this.ws.onopen=()=>{this.setConnectionState("connected"),this.reconnectAttempts=0,q()},this.ws.onmessage=(A)=>{try{let B=JSON.parse(A.data);if(B.type==="ping"){this.lastPingTime=Date.now(),this.ws?.send(JSON.stringify({type:"pong",timestamp:Date.now(),respondingTo:B.timestamp}));return}if(B.type==="established"){this.clientId=B.clientId,this.serverVersion=B.version;let G=(()=>{let F=new URL(z);if(F.searchParams.has("token"))F.searchParams.set("token","***");return F.toString()})();if(console.log(`Welcome to LAPLACE Event Bridge ${`v${B.version}`||"(unknown version)"}: ${G} with client ID ${this.clientId||"unknown"}`),this.shouldMonitorPing())this.startPingMonitoring()}this.processEvent(B)}catch(B){console.error("Failed to parse event data:",B)}},this.ws.onerror=(A)=>{console.error("WebSocket error:",A),w(A)},this.ws.onclose=()=>{if(console.log("Disconnected from LAPLACE Event Bridge"),this.stopPingMonitoring(),this.lastPingTime=null,this.options.reconnect&&this.reconnectAttempts<this.options.maxReconnectAttempts){this.reconnectAttempts++,this.setConnectionState("reconnecting");let A=this.options.reconnectInterval,B=1.5,G=60000,F=Math.min(A*Math.pow(B,this.reconnectAttempts-1),G),H=Math.round(F);console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts}) in ${H}ms...`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((J)=>{console.error("Reconnection failed:",J)})},H)}else this.setConnectionState("disconnected")}}catch(z){this.setConnectionState("disconnected"),w(z)}})}disconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.stopPingMonitoring(),this.ws)this.ws.close(),this.ws=null;this.setConnectionState("disconnected"),this.clientId=null,this.serverVersion=null,this.lastPingTime=null}on(q,w){if(!this.eventHandlers.has(q))this.eventHandlers.set(q,[]);this.eventHandlers.get(q).push(w)}onAny(q){this.anyEventHandlers.push(q)}onConnectionStateChange(q){this.connectionStateHandlers.push(q),q(this.connectionState)}off(q,w){if(!this.eventHandlers.has(q))return;let z=this.eventHandlers.get(q),E=z.indexOf(w);if(E!==-1)z.splice(E,1);if(z.length===0)this.eventHandlers.delete(q)}offAny(q){let w=this.anyEventHandlers.indexOf(q);if(w!==-1)this.anyEventHandlers.splice(w,1)}offConnectionStateChange(q){let w=this.connectionStateHandlers.indexOf(q);if(w!==-1)this.connectionStateHandlers.splice(w,1)}isConnectedToBridge(){return this.connectionState==="connected"}getConnectionState(){return this.connectionState}getClientId(){return this.clientId}send(q){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("Not connected to LAPLACE Event Bridge");this.ws.send(JSON.stringify(q))}setConnectionState(q){if(this.connectionState!==q){this.connectionState=q;for(let w of this.connectionStateHandlers)try{w(q)}catch(z){console.error("Error in connection state change handler:",z)}}}processEvent(q){if(this.eventHandlers.has(q.type))for(let w of this.eventHandlers.get(q.type))try{w(q)}catch(z){console.error(`Error in event handler for type ${q.type}:`,z)}for(let w of this.anyEventHandlers)try{w(q)}catch(z){console.error("Error in any event handler:",z)}}shouldMonitorPing(){if(!this.serverVersion)return!1;let q=this.serverVersion.split(".").map((A)=>parseInt(A,10));if(q.length<3||q.some(isNaN))return console.warn(`Invalid server version format: ${this.serverVersion}`),!1;let w=q[0],z=q[1],E=q[2];if(w>4)return!0;if(w===4){if(z>0)return!0;if(z===0&&E>=3)return!0}return!1}startPingMonitoring(){this.stopPingMonitoring(),console.log(`Ping monitoring enabled (timeout: ${this.options.pingTimeout}ms)`),this.lastPingTime=Date.now(),this.pingMonitorTimer=setInterval(()=>{if(!this.lastPingTime)return;let q=Date.now()-this.lastPingTime;if(q>this.options.pingTimeout){if(console.warn(`Ping timeout detected (${q}ms since last ping). Reconnecting...`),this.stopPingMonitoring(),this.ws)this.ws.close()}},this.options.pingTimeout/3)}stopPingMonitoring(){if(this.pingMonitorTimer)clearInterval(this.pingMonitorTimer),this.pingMonitorTimer=null}}export{N as LaplaceEventBridgeClient,K as ConnectionState};
1
+ var K;((A)=>{A.DISCONNECTED="disconnected";A.CONNECTING="connecting";A.CONNECTED="connected";A.RECONNECTING="reconnecting"})(K||={});class N{ws=null;eventHandlers=new Map;anyEventHandlers=[];connectionStateHandlers=[];reconnectTimer=null;reconnectAttempts=0;clientId=null;serverVersion=null;connectionState="disconnected";lastPingTime=null;pingMonitorTimer=null;options={url:"ws://localhost:9696",token:"",reconnect:!0,reconnectInterval:3000,maxReconnectAttempts:1000,pingTimeout:90000};constructor(q={}){this.options={...this.options,...q}}connect(){return new Promise((q,z)=>{try{if(this.ws)this.ws.close();this.setConnectionState("connecting");let w=this.options.url,B=[];if(this.options.token){B.push("laplace-event-bridge-role-client",this.options.token);let A=new URL(w);A.searchParams.set("token",this.options.token),w=A.toString()}this.ws=new WebSocket(w,B),this.ws.onopen=()=>{this.setConnectionState("connected"),this.reconnectAttempts=0,q()},this.ws.onmessage=(A)=>{try{let E=JSON.parse(A.data);if(E.type==="ping"){this.lastPingTime=Date.now(),this.ws?.send(JSON.stringify({type:"pong",timestamp:Date.now(),respondingTo:E.timestamp}));return}if(E.type==="established"){this.clientId=E.clientId,this.serverVersion=E.version;let G=(()=>{let F=new URL(w);if(F.searchParams.has("token"))F.searchParams.set("token","***");return F.toString()})();if(console.log(`Welcome to LAPLACE Event Bridge ${`v${E.version}`||"(unknown version)"}: ${G} with client ID ${this.clientId||"unknown"}`),this.shouldMonitorPing())this.startPingMonitoring()}this.processEvent(E)}catch(E){console.error("Failed to parse event data:",E)}},this.ws.onerror=(A)=>{console.error("WebSocket error:",A),z(A)},this.ws.onclose=()=>{if(console.log("Disconnected from LAPLACE Event Bridge"),this.stopPingMonitoring(),this.lastPingTime=null,this.options.reconnect&&this.reconnectAttempts<this.options.maxReconnectAttempts){this.reconnectAttempts++,this.setConnectionState("reconnecting");let A=this.options.reconnectInterval,E=1.5,G=60000,F=Math.min(A*E**(this.reconnectAttempts-1),G),H=Math.round(F);console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts}) in ${H}ms...`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((J)=>{console.error("Reconnection failed:",J)})},H)}else this.setConnectionState("disconnected")}}catch(w){this.setConnectionState("disconnected"),z(w)}})}disconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.stopPingMonitoring(),this.ws)this.ws.close(),this.ws=null;this.setConnectionState("disconnected"),this.clientId=null,this.serverVersion=null,this.lastPingTime=null}on(q,z){let w=this.eventHandlers.get(q)||[];w.push(z),this.eventHandlers.set(q,w)}onAny(q){this.anyEventHandlers.push(q)}onConnectionStateChange(q){this.connectionStateHandlers.push(q),q(this.connectionState)}off(q,z){let w=this.eventHandlers.get(q);if(!w)return;let B=w.indexOf(z);if(B!==-1)w.splice(B,1);if(w.length===0)this.eventHandlers.delete(q)}offAny(q){let z=this.anyEventHandlers.indexOf(q);if(z!==-1)this.anyEventHandlers.splice(z,1)}offConnectionStateChange(q){let z=this.connectionStateHandlers.indexOf(q);if(z!==-1)this.connectionStateHandlers.splice(z,1)}isConnectedToBridge(){return this.connectionState==="connected"}getConnectionState(){return this.connectionState}getClientId(){return this.clientId}send(q){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("Not connected to LAPLACE Event Bridge");this.ws.send(JSON.stringify(q))}setConnectionState(q){if(this.connectionState!==q){this.connectionState=q;for(let z of this.connectionStateHandlers)try{z(q)}catch(w){console.error("Error in connection state change handler:",w)}}}processEvent(q){let z=this.eventHandlers.get(q.type);if(z)for(let w of z)try{w(q)}catch(B){console.error(`Error in event handler for type ${q.type}:`,B)}for(let w of this.anyEventHandlers)try{w(q)}catch(B){console.error("Error in any event handler:",B)}}shouldMonitorPing(){if(!this.serverVersion)return!1;let q=this.serverVersion.split(".").map((A)=>parseInt(A,10));if(q.length<3||q.some(Number.isNaN))return console.warn(`Invalid server version format: ${this.serverVersion}`),!1;let[z=0,w=0,B=0]=q;if(z>4)return!0;if(z===4){if(w>0)return!0;if(w===0&&B>=3)return!0}return!1}startPingMonitoring(){this.stopPingMonitoring(),console.log(`Ping monitoring enabled (timeout: ${this.options.pingTimeout}ms)`),this.lastPingTime=Date.now(),this.pingMonitorTimer=setInterval(()=>{if(!this.lastPingTime)return;let q=Date.now()-this.lastPingTime;if(q>this.options.pingTimeout){if(console.warn(`Ping timeout detected (${q}ms since last ping). Reconnecting...`),this.stopPingMonitoring(),this.ws)this.ws.close()}},this.options.pingTimeout/3)}stopPingMonitoring(){if(this.pingMonitorTimer)clearInterval(this.pingMonitorTimer),this.pingMonitorTimer=null}}export{N as LaplaceEventBridgeClient,K as ConnectionState};
package/index.ts CHANGED
@@ -199,7 +199,7 @@ export class LaplaceEventBridgeClient {
199
199
 
200
200
  // Calculate delay: base * (multiplier ^ (attempt - 1))
201
201
  const calculatedDelay = Math.min(
202
- baseInterval * Math.pow(backoffMultiplier, this.reconnectAttempts - 1),
202
+ baseInterval * backoffMultiplier ** (this.reconnectAttempts - 1),
203
203
  maxInterval
204
204
  )
205
205
  const delay = Math.round(calculatedDelay)
@@ -251,10 +251,9 @@ export class LaplaceEventBridgeClient {
251
251
  * @param handler The handler function to call when the event is received
252
252
  */
253
253
  public on<T extends LaplaceEventTypes>(eventType: T, handler: (event: EventTypeMap[T]) => void): void {
254
- if (!this.eventHandlers.has(eventType)) {
255
- this.eventHandlers.set(eventType, [])
256
- }
257
- this.eventHandlers.get(eventType)!.push(handler)
254
+ const handlers = this.eventHandlers.get(eventType) || []
255
+ handlers.push(handler)
256
+ this.eventHandlers.set(eventType, handlers)
258
257
  }
259
258
 
260
259
  /**
@@ -281,11 +280,11 @@ export class LaplaceEventBridgeClient {
281
280
  * @param handler The handler function to remove
282
281
  */
283
282
  public off<T extends LaplaceEventTypes>(eventType: T, handler: (event: EventTypeMap[T]) => void): void {
284
- if (!this.eventHandlers.has(eventType)) {
283
+ const handlers = this.eventHandlers.get(eventType)
284
+ if (!handlers) {
285
285
  return
286
286
  }
287
287
 
288
- const handlers = this.eventHandlers.get(eventType)!
289
288
  const index = handlers.indexOf(handler)
290
289
 
291
290
  if (index !== -1) {
@@ -369,8 +368,9 @@ export class LaplaceEventBridgeClient {
369
368
 
370
369
  private processEvent(event: LaplaceEvent): void {
371
370
  // Call specific event handlers
372
- if (this.eventHandlers.has(event.type)) {
373
- for (const handler of this.eventHandlers.get(event.type)!) {
371
+ const handlers = this.eventHandlers.get(event.type)
372
+ if (handlers) {
373
+ for (const handler of handlers) {
374
374
  try {
375
375
  handler(event)
376
376
  } catch (err) {
@@ -401,14 +401,12 @@ export class LaplaceEventBridgeClient {
401
401
  const versionParts = this.serverVersion.split('.').map(part => parseInt(part, 10))
402
402
 
403
403
  // Ensure we have at least 3 version parts
404
- if (versionParts.length < 3 || versionParts.some(isNaN)) {
404
+ if (versionParts.length < 3 || versionParts.some(Number.isNaN)) {
405
405
  console.warn(`Invalid server version format: ${this.serverVersion}`)
406
406
  return false
407
407
  }
408
408
 
409
- const major = versionParts[0]!
410
- const minor = versionParts[1]!
411
- const patch = versionParts[2]!
409
+ const [major = 0, minor = 0, patch = 0] = versionParts
412
410
 
413
411
  // Check if version is >= 4.0.3
414
412
  if (major > 4) return true
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@laplace.live/event-bridge-sdk",
3
3
  "description": "LAPLACE Event Bridge SDK",
4
- "version": "1.0.3",
4
+ "version": "1.0.4",
5
5
  "module": "index.ts",
6
6
  "types": "index.ts",
7
7
  "license": "MIT",
8
8
  "type": "module",
9
9
  "scripts": {
10
- "build": "bun build index.ts --outdir dist --target browser --minify"
10
+ "build": "bun build index.ts --outdir dist --target browser --minify",
11
+ "lint": "biome check",
12
+ "format": "biome format --write"
11
13
  },
12
14
  "exports": {
13
15
  ".": {