@laplace.live/event-bridge-sdk 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -2
- package/dist/index.js +1 -1
- package/index.ts +63 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LAPLACE Event Bridge SDK
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A framework agnostic SDK for connecting to the LAPLACE Event Bridge server. This SDK allows clients to receive and send events from/to the LAPLACE Event Bridge.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -45,6 +45,27 @@ client.onAny(event => {
|
|
|
45
45
|
console.log(`Received event of type: ${event.type}`)
|
|
46
46
|
})
|
|
47
47
|
|
|
48
|
+
// Monitor connection state changes
|
|
49
|
+
client.onConnectionStateChange(state => {
|
|
50
|
+
console.log(`Connection state changed to: ${state}`)
|
|
51
|
+
|
|
52
|
+
// Handle different connection states
|
|
53
|
+
switch (state) {
|
|
54
|
+
case 'connected':
|
|
55
|
+
console.log('Connected to the server!')
|
|
56
|
+
break
|
|
57
|
+
case 'reconnecting':
|
|
58
|
+
console.log('Attempting to reconnect...')
|
|
59
|
+
break
|
|
60
|
+
case 'disconnected':
|
|
61
|
+
console.log('Disconnected from the server')
|
|
62
|
+
break
|
|
63
|
+
case 'connecting':
|
|
64
|
+
console.log('Establishing connection...')
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
48
69
|
// Disconnect when done
|
|
49
70
|
client.disconnect()
|
|
50
71
|
```
|
|
@@ -61,6 +82,19 @@ interface ConnectionOptions {
|
|
|
61
82
|
}
|
|
62
83
|
```
|
|
63
84
|
|
|
85
|
+
### Connection States
|
|
86
|
+
|
|
87
|
+
The SDK provides a `ConnectionState` enum that represents the current state of the connection:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
enum ConnectionState {
|
|
91
|
+
DISCONNECTED = 'disconnected',
|
|
92
|
+
CONNECTING = 'connecting',
|
|
93
|
+
CONNECTED = 'connected',
|
|
94
|
+
RECONNECTING = 'reconnecting',
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
64
98
|
### API Reference
|
|
65
99
|
|
|
66
100
|
#### Methods
|
|
@@ -69,9 +103,12 @@ interface ConnectionOptions {
|
|
|
69
103
|
- `disconnect()`: Disconnect from the event bridge.
|
|
70
104
|
- `on(eventType, handler)`: Register an event handler for a specific event type with automatic type inference.
|
|
71
105
|
- `onAny(handler)`: Register a handler for all events.
|
|
106
|
+
- `onConnectionStateChange(handler)`: Register a handler for connection state changes.
|
|
72
107
|
- `off(eventType, handler)`: Remove an event handler for a specific event type.
|
|
73
108
|
- `offAny(handler)`: Remove a handler for all events.
|
|
74
|
-
- `
|
|
109
|
+
- `offConnectionStateChange(handler)`: Remove a connection state change handler.
|
|
110
|
+
- `isConnectedToBridge()`: Check if the client is connected to the bridge. (Deprecated: use `getConnectionState()` instead)
|
|
111
|
+
- `getConnectionState()`: Get the current connection state.
|
|
75
112
|
- `getClientId()`: Get the client ID assigned by the bridge.
|
|
76
113
|
- `send(event)`: Send an event to the bridge.
|
|
77
114
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
var w;((q)=>{q.DISCONNECTED="disconnected";q.CONNECTING="connecting";q.CONNECTED="connected";q.RECONNECTING="reconnecting"})(w||={});class z{ws=null;eventHandlers=new Map;anyEventHandlers=[];connectionStateHandlers=[];reconnectTimer=null;reconnectAttempts=0;clientId=null;connectionState="disconnected";options={url:"ws://localhost:9696",token:"",reconnect:!0,reconnectInterval:3000,maxReconnectAttempts:10};constructor(b={}){this.options={...this.options,...b}}connect(){return new Promise((b,k)=>{try{if(this.ws)this.ws.close();this.setConnectionState("connecting");let m=[];if(this.options.token)m.push("laplace-event-bridge-role-client",this.options.token);this.ws=new WebSocket(this.options.url,m),this.ws.onopen=()=>{this.setConnectionState("connected"),this.reconnectAttempts=0,console.log("Connected to LAPLACE Event Bridge"),b()},this.ws.onmessage=(u)=>{try{let q=JSON.parse(u.data);if(q.type==="established"&&q.clientId)this.clientId=q.clientId,console.log(`Connection established with client ID: ${this.clientId}`);this.processEvent(q)}catch(q){console.error("Failed to parse event data:",q)}},this.ws.onerror=(u)=>{console.error("WebSocket error:",u),k(u)},this.ws.onclose=()=>{if(console.log("Disconnected from LAPLACE Event Bridge"),this.options.reconnect&&this.reconnectAttempts<this.options.maxReconnectAttempts)this.reconnectAttempts++,this.setConnectionState("reconnecting"),console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((u)=>{console.error("Reconnection failed:",u)})},this.options.reconnectInterval);else this.setConnectionState("disconnected")}}catch(m){this.setConnectionState("disconnected"),k(m)}})}disconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.ws)this.ws.close(),this.ws=null;this.setConnectionState("disconnected"),this.clientId=null}on(b,k){if(!this.eventHandlers.has(b))this.eventHandlers.set(b,[]);this.eventHandlers.get(b).push(k)}onAny(b){this.anyEventHandlers.push(b)}onConnectionStateChange(b){this.connectionStateHandlers.push(b),b(this.connectionState)}off(b,k){if(!this.eventHandlers.has(b))return;let m=this.eventHandlers.get(b),u=m.indexOf(k);if(u!==-1)m.splice(u,1);if(m.length===0)this.eventHandlers.delete(b)}offAny(b){let k=this.anyEventHandlers.indexOf(b);if(k!==-1)this.anyEventHandlers.splice(k,1)}offConnectionStateChange(b){let k=this.connectionStateHandlers.indexOf(b);if(k!==-1)this.connectionStateHandlers.splice(k,1)}isConnectedToBridge(){return this.connectionState==="connected"}getConnectionState(){return this.connectionState}getClientId(){return this.clientId}send(b){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("Not connected to LAPLACE Event Bridge");this.ws.send(JSON.stringify(b))}setConnectionState(b){if(this.connectionState!==b){this.connectionState=b;for(let k of this.connectionStateHandlers)try{k(b)}catch(m){console.error("Error in connection state change handler:",m)}}}processEvent(b){if(this.eventHandlers.has(b.type))for(let k of this.eventHandlers.get(b.type))try{k(b)}catch(m){console.error(`Error in event handler for type ${b.type}:`,m)}for(let k of this.anyEventHandlers)try{k(b)}catch(m){console.error("Error in any event handler:",m)}}}export{z as LaplaceEventBridgeClient,w as ConnectionState};
|
package/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { LaplaceEvent, LaplaceEventTypes } from '@laplace.live/event-types'
|
|
2
2
|
|
|
3
|
+
// Connection state enum to represent the current state of the connection
|
|
4
|
+
export enum ConnectionState {
|
|
5
|
+
DISCONNECTED = 'disconnected',
|
|
6
|
+
CONNECTING = 'connecting',
|
|
7
|
+
CONNECTED = 'connected',
|
|
8
|
+
RECONNECTING = 'reconnecting',
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
// Create a conditional type that maps from event type string to event object type
|
|
4
12
|
export type EventTypeMap = {
|
|
5
13
|
[K in LaplaceEventTypes]: Extract<LaplaceEvent, { type: K }>
|
|
@@ -8,6 +16,7 @@ export type EventTypeMap = {
|
|
|
8
16
|
export type EventHandler<T extends LaplaceEvent> = (event: T) => void
|
|
9
17
|
export type EventTypeHandler = (event: LaplaceEvent) => void
|
|
10
18
|
export type AnyEventHandler = (event: LaplaceEvent) => void
|
|
19
|
+
export type ConnectionStateChangeHandler = (state: ConnectionState) => void
|
|
11
20
|
|
|
12
21
|
export interface ConnectionOptions {
|
|
13
22
|
/**
|
|
@@ -42,10 +51,11 @@ export class LaplaceEventBridgeClient {
|
|
|
42
51
|
private ws: WebSocket | null = null
|
|
43
52
|
private eventHandlers = new Map<string, EventHandler<any>[]>()
|
|
44
53
|
private anyEventHandlers: AnyEventHandler[] = []
|
|
54
|
+
private connectionStateHandlers: ConnectionStateChangeHandler[] = []
|
|
45
55
|
private reconnectTimer: number | null = null
|
|
46
56
|
private reconnectAttempts = 0
|
|
47
57
|
private clientId: string | null = null
|
|
48
|
-
private
|
|
58
|
+
private connectionState: ConnectionState = ConnectionState.DISCONNECTED
|
|
49
59
|
|
|
50
60
|
private options: Required<ConnectionOptions> = {
|
|
51
61
|
url: 'ws://localhost:9696',
|
|
@@ -70,6 +80,8 @@ export class LaplaceEventBridgeClient {
|
|
|
70
80
|
this.ws.close()
|
|
71
81
|
}
|
|
72
82
|
|
|
83
|
+
this.setConnectionState(ConnectionState.CONNECTING)
|
|
84
|
+
|
|
73
85
|
const protocols: string[] = []
|
|
74
86
|
if (this.options.token) {
|
|
75
87
|
// Add the token as the second protocol parameter
|
|
@@ -79,7 +91,7 @@ export class LaplaceEventBridgeClient {
|
|
|
79
91
|
this.ws = new WebSocket(this.options.url, protocols)
|
|
80
92
|
|
|
81
93
|
this.ws.onopen = () => {
|
|
82
|
-
this.
|
|
94
|
+
this.setConnectionState(ConnectionState.CONNECTED)
|
|
83
95
|
this.reconnectAttempts = 0
|
|
84
96
|
console.log('Connected to LAPLACE Event Bridge')
|
|
85
97
|
resolve()
|
|
@@ -108,20 +120,23 @@ export class LaplaceEventBridgeClient {
|
|
|
108
120
|
}
|
|
109
121
|
|
|
110
122
|
this.ws.onclose = () => {
|
|
111
|
-
this.isConnected = false
|
|
112
123
|
console.log('Disconnected from LAPLACE Event Bridge')
|
|
113
124
|
|
|
114
125
|
if (this.options.reconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {
|
|
115
126
|
this.reconnectAttempts++
|
|
127
|
+
this.setConnectionState(ConnectionState.RECONNECTING)
|
|
116
128
|
console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`)
|
|
117
129
|
this.reconnectTimer = setTimeout(() => {
|
|
118
130
|
this.connect().catch(err => {
|
|
119
131
|
console.error('Reconnection failed:', err)
|
|
120
132
|
})
|
|
121
133
|
}, this.options.reconnectInterval) as unknown as number
|
|
134
|
+
} else {
|
|
135
|
+
this.setConnectionState(ConnectionState.DISCONNECTED)
|
|
122
136
|
}
|
|
123
137
|
}
|
|
124
138
|
} catch (err) {
|
|
139
|
+
this.setConnectionState(ConnectionState.DISCONNECTED)
|
|
125
140
|
reject(err)
|
|
126
141
|
}
|
|
127
142
|
})
|
|
@@ -141,7 +156,7 @@ export class LaplaceEventBridgeClient {
|
|
|
141
156
|
this.ws = null
|
|
142
157
|
}
|
|
143
158
|
|
|
144
|
-
this.
|
|
159
|
+
this.setConnectionState(ConnectionState.DISCONNECTED)
|
|
145
160
|
this.clientId = null
|
|
146
161
|
}
|
|
147
162
|
|
|
@@ -165,6 +180,16 @@ export class LaplaceEventBridgeClient {
|
|
|
165
180
|
this.anyEventHandlers.push(handler)
|
|
166
181
|
}
|
|
167
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Register a handler for connection state changes
|
|
185
|
+
* @param handler The handler function to call when the connection state changes
|
|
186
|
+
*/
|
|
187
|
+
public onConnectionStateChange(handler: ConnectionStateChangeHandler): void {
|
|
188
|
+
this.connectionStateHandlers.push(handler)
|
|
189
|
+
// Immediately call with current state to initialize
|
|
190
|
+
handler(this.connectionState)
|
|
191
|
+
}
|
|
192
|
+
|
|
168
193
|
/**
|
|
169
194
|
* Remove an event handler for a specific event type
|
|
170
195
|
* @param eventType The event type to remove the handler for
|
|
@@ -198,11 +223,30 @@ export class LaplaceEventBridgeClient {
|
|
|
198
223
|
}
|
|
199
224
|
}
|
|
200
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Remove a connection state change handler
|
|
228
|
+
* @param handler The handler function to remove
|
|
229
|
+
*/
|
|
230
|
+
public offConnectionStateChange(handler: ConnectionStateChangeHandler): void {
|
|
231
|
+
const index = this.connectionStateHandlers.indexOf(handler)
|
|
232
|
+
if (index !== -1) {
|
|
233
|
+
this.connectionStateHandlers.splice(index, 1)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
201
237
|
/**
|
|
202
238
|
* Check if the client is connected to the bridge
|
|
239
|
+
* @deprecated Use getConnectionState() instead for more detailed state information
|
|
203
240
|
*/
|
|
204
241
|
public isConnectedToBridge(): boolean {
|
|
205
|
-
return this.
|
|
242
|
+
return this.connectionState === ConnectionState.CONNECTED
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get the current connection state
|
|
247
|
+
*/
|
|
248
|
+
public getConnectionState(): ConnectionState {
|
|
249
|
+
return this.connectionState
|
|
206
250
|
}
|
|
207
251
|
|
|
208
252
|
/**
|
|
@@ -224,6 +268,20 @@ export class LaplaceEventBridgeClient {
|
|
|
224
268
|
this.ws.send(JSON.stringify(event))
|
|
225
269
|
}
|
|
226
270
|
|
|
271
|
+
private setConnectionState(state: ConnectionState): void {
|
|
272
|
+
if (this.connectionState !== state) {
|
|
273
|
+
this.connectionState = state
|
|
274
|
+
// Notify all connection state change handlers
|
|
275
|
+
for (const handler of this.connectionStateHandlers) {
|
|
276
|
+
try {
|
|
277
|
+
handler(state)
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error('Error in connection state change handler:', err)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
227
285
|
private processEvent(event: LaplaceEvent): void {
|
|
228
286
|
// Call specific event handlers
|
|
229
287
|
if (this.eventHandlers.has(event.type)) {
|