@laplace.live/event-bridge-sdk 0.0.1 → 0.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.
package/README.md CHANGED
@@ -6,13 +6,13 @@ A TypeScript SDK for connecting to the LAPLACE Event Bridge server. This SDK all
6
6
 
7
7
  ```bash
8
8
  # Using npm
9
- npm install @laplace.live/event-bridge
9
+ npm install @laplace.live/event-bridge-sdk
10
10
 
11
11
  # Using Yarn
12
- yarn add @laplace.live/event-bridge
12
+ yarn add @laplace.live/event-bridge-sdk
13
13
 
14
14
  # Using Bun
15
- bun add @laplace.live/event-bridge
15
+ bun add @laplace.live/event-bridge-sdk
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -20,49 +20,49 @@ bun add @laplace.live/event-bridge
20
20
  ### Basic Usage
21
21
 
22
22
  ```typescript
23
- import { LaplaceEventClient } from '@laplace.live/event-bridge';
24
- import type { Message, System } from '@laplace.live/event-types';
23
+ import { LaplaceEventBridgeClient } from '@laplace.live/event-bridge-sdk'
24
+ import type { Message, System } from '@laplace.live/event-types'
25
25
 
26
26
  // Create a new client
27
- const client = new LaplaceEventClient({
27
+ const client = new LaplaceEventBridgeClient({
28
28
  url: 'ws://localhost:9696',
29
29
  token: 'your-auth-token', // Optional
30
30
  reconnect: true,
31
- });
31
+ })
32
32
 
33
33
  // Connect to the bridge
34
- await client.connect();
34
+ await client.connect()
35
35
 
36
36
  // Event types are automatically inferred from the event type string!
37
- client.on('message', (event) => {
37
+ client.on('message', event => {
38
38
  // TypeScript knows 'event' is of type 'Message' here
39
- console.log(`${event.username}: ${event.message}`);
40
- });
39
+ console.log(`${event.username}: ${event.message}`)
40
+ })
41
41
 
42
42
  // No need for explicit type parameters
43
- client.on('system', (event) => {
43
+ client.on('system', event => {
44
44
  // TypeScript knows 'event' is of type 'System' here
45
- console.log(`System: ${event.message}`);
46
- });
45
+ console.log(`System: ${event.message}`)
46
+ })
47
47
 
48
48
  // Listen for any event
49
- client.onAny((event) => {
50
- console.log(`Received event of type: ${event.type}`);
51
- });
49
+ client.onAny(event => {
50
+ console.log(`Received event of type: ${event.type}`)
51
+ })
52
52
 
53
53
  // Disconnect when done
54
- client.disconnect();
54
+ client.disconnect()
55
55
  ```
56
56
 
57
57
  ### Connection Options
58
58
 
59
59
  ```typescript
60
60
  interface ConnectionOptions {
61
- url?: string; // WebSocket URL, default: 'ws://localhost:9696'
62
- token?: string; // Authentication token, default: ''
63
- reconnect?: boolean; // Auto reconnect on disconnect, default: true
64
- reconnectInterval?: number; // Milliseconds between reconnect attempts, default: 3000
65
- maxReconnectAttempts?: number; // Maximum reconnect attempts, default: 10
61
+ url?: string // WebSocket URL, default: 'ws://localhost:9696'
62
+ token?: string // Authentication token, default: ''
63
+ reconnect?: boolean // Auto reconnect on disconnect, default: true
64
+ reconnectInterval?: number // Milliseconds between reconnect attempts, default: 3000
65
+ maxReconnectAttempts?: number // Maximum reconnect attempts, default: 10
66
66
  }
67
67
  ```
68
68
 
@@ -88,18 +88,18 @@ For example:
88
88
 
89
89
  ```typescript
90
90
  // This will infer that 'event' is of type 'Message'
91
- client.on('message', (event) => {
91
+ client.on('message', event => {
92
92
  // TypeScript knows these properties exist
93
- console.log(event.username);
94
- console.log(event.message);
95
- });
93
+ console.log(event.username)
94
+ console.log(event.message)
95
+ })
96
96
 
97
97
  // This will infer that 'event' is of type 'Gift'
98
- client.on('gift', (event) => {
98
+ client.on('gift', event => {
99
99
  // TypeScript knows these properties exist
100
- console.log(event.giftName);
101
- console.log(event.giftCount);
102
- });
100
+ console.log(event.giftName)
101
+ console.log(event.giftCount)
102
+ })
103
103
  ```
104
104
 
105
105
  ## Event Types
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- class A{ws=null;eventHandlers=new Map;anyEventHandlers=[];reconnectTimer=null;reconnectAttempts=0;clientId=null;isConnected=!1;options={url:"ws://localhost:9696",token:"",reconnect:!0,reconnectInterval:3000,maxReconnectAttempts:10};constructor(k={}){this.options={...this.options,...k}}connect(){return new Promise((k,q)=>{try{if(this.ws)this.ws.close();let u=[];if(this.options.token)u.push("laplace-event-bridge-role-client",this.options.token);this.ws=new WebSocket(this.options.url,u),this.ws.onopen=()=>{this.isConnected=!0,this.reconnectAttempts=0,console.log("Connected to LAPLACE Event Bridge"),k()},this.ws.onmessage=(w)=>{try{let z=JSON.parse(w.data);if(z.type==="established"&&z.clientId)this.clientId=z.clientId,console.log(`Connection established with client ID: ${this.clientId}`);this.processEvent(z)}catch(z){console.error("Failed to parse event data:",z)}},this.ws.onerror=(w)=>{console.error("WebSocket error:",w),q(w)},this.ws.onclose=()=>{if(this.isConnected=!1,console.log("Disconnected from LAPLACE Event Bridge"),this.options.reconnect&&this.reconnectAttempts<this.options.maxReconnectAttempts)this.reconnectAttempts++,console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((w)=>{console.error("Reconnection failed:",w)})},this.options.reconnectInterval)}}catch(u){q(u)}})}disconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.ws)this.ws.close(),this.ws=null;this.isConnected=!1,this.clientId=null}on(k,q){if(!this.eventHandlers.has(k))this.eventHandlers.set(k,[]);this.eventHandlers.get(k).push(q)}onAny(k){this.anyEventHandlers.push(k)}off(k,q){if(!this.eventHandlers.has(k))return;let u=this.eventHandlers.get(k),w=u.indexOf(q);if(w!==-1)u.splice(w,1);if(u.length===0)this.eventHandlers.delete(k)}offAny(k){let q=this.anyEventHandlers.indexOf(k);if(q!==-1)this.anyEventHandlers.splice(q,1)}isConnectedToBridge(){return this.isConnected}getClientId(){return this.clientId}send(k){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("Not connected to LAPLACE Event Bridge");this.ws.send(JSON.stringify(k))}processEvent(k){if(this.eventHandlers.has(k.type))for(let q of this.eventHandlers.get(k.type))try{q(k)}catch(u){console.error(`Error in event handler for type ${k.type}:`,u)}for(let q of this.anyEventHandlers)try{q(k)}catch(u){console.error("Error in any event handler:",u)}}}export{A as LaplaceEventClient};
1
+ class A{ws=null;eventHandlers=new Map;anyEventHandlers=[];reconnectTimer=null;reconnectAttempts=0;clientId=null;isConnected=!1;options={url:"ws://localhost:9696",token:"",reconnect:!0,reconnectInterval:3000,maxReconnectAttempts:10};constructor(k={}){this.options={...this.options,...k}}connect(){return new Promise((k,q)=>{try{if(this.ws)this.ws.close();let u=[];if(this.options.token)u.push("laplace-event-bridge-role-client",this.options.token);this.ws=new WebSocket(this.options.url,u),this.ws.onopen=()=>{this.isConnected=!0,this.reconnectAttempts=0,console.log("Connected to LAPLACE Event Bridge"),k()},this.ws.onmessage=(w)=>{try{let z=JSON.parse(w.data);if(z.type==="established"&&z.clientId)this.clientId=z.clientId,console.log(`Connection established with client ID: ${this.clientId}`);this.processEvent(z)}catch(z){console.error("Failed to parse event data:",z)}},this.ws.onerror=(w)=>{console.error("WebSocket error:",w),q(w)},this.ws.onclose=()=>{if(this.isConnected=!1,console.log("Disconnected from LAPLACE Event Bridge"),this.options.reconnect&&this.reconnectAttempts<this.options.maxReconnectAttempts)this.reconnectAttempts++,console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`),this.reconnectTimer=setTimeout(()=>{this.connect().catch((w)=>{console.error("Reconnection failed:",w)})},this.options.reconnectInterval)}}catch(u){q(u)}})}disconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.ws)this.ws.close(),this.ws=null;this.isConnected=!1,this.clientId=null}on(k,q){if(!this.eventHandlers.has(k))this.eventHandlers.set(k,[]);this.eventHandlers.get(k).push(q)}onAny(k){this.anyEventHandlers.push(k)}off(k,q){if(!this.eventHandlers.has(k))return;let u=this.eventHandlers.get(k),w=u.indexOf(q);if(w!==-1)u.splice(w,1);if(u.length===0)this.eventHandlers.delete(k)}offAny(k){let q=this.anyEventHandlers.indexOf(k);if(q!==-1)this.anyEventHandlers.splice(q,1)}isConnectedToBridge(){return this.isConnected}getClientId(){return this.clientId}send(k){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("Not connected to LAPLACE Event Bridge");this.ws.send(JSON.stringify(k))}processEvent(k){if(this.eventHandlers.has(k.type))for(let q of this.eventHandlers.get(k.type))try{q(k)}catch(u){console.error(`Error in event handler for type ${k.type}:`,u)}for(let q of this.anyEventHandlers)try{q(k)}catch(u){console.error("Error in any event handler:",u)}}}export{A as LaplaceEventBridgeClient};
package/index.ts ADDED
@@ -0,0 +1,248 @@
1
+ import type { LaplaceEvent, LaplaceEventTypes } from '@laplace.live/event-types'
2
+
3
+ // Create a conditional type that maps from event type string to event object type
4
+ export type EventTypeMap = {
5
+ [K in LaplaceEventTypes]: Extract<LaplaceEvent, { type: K }>
6
+ }
7
+
8
+ export type EventHandler<T extends LaplaceEvent> = (event: T) => void
9
+ export type EventTypeHandler = (event: LaplaceEvent) => void
10
+ export type AnyEventHandler = (event: LaplaceEvent) => void
11
+
12
+ export interface ConnectionOptions {
13
+ /**
14
+ * The URL of the LAPLACE Event Bridge server
15
+ *
16
+ * @example 'ws://localhost:9696'
17
+ */
18
+ url?: string
19
+ /**
20
+ * The authentication token for the LAPLACE Event Bridge server
21
+ */
22
+ token?: string
23
+ /**
24
+ * Whether to automatically reconnect to the LAPLACE Event Bridge server
25
+ */
26
+ reconnect?: boolean
27
+ /**
28
+ * The interval between reconnect attempts in milliseconds
29
+ *
30
+ * @default 3000
31
+ */
32
+ reconnectInterval?: number
33
+ /**
34
+ * The maximum number of reconnect attempts
35
+ *
36
+ * @default 10
37
+ */
38
+ maxReconnectAttempts?: number
39
+ }
40
+
41
+ export class LaplaceEventBridgeClient {
42
+ private ws: WebSocket | null = null
43
+ private eventHandlers = new Map<string, EventHandler<any>[]>()
44
+ private anyEventHandlers: AnyEventHandler[] = []
45
+ private reconnectTimer: number | null = null
46
+ private reconnectAttempts = 0
47
+ private clientId: string | null = null
48
+ private isConnected = false
49
+
50
+ private options: Required<ConnectionOptions> = {
51
+ url: 'ws://localhost:9696',
52
+ token: '',
53
+ reconnect: true,
54
+ reconnectInterval: 3000,
55
+ maxReconnectAttempts: 10,
56
+ }
57
+
58
+ constructor(options: ConnectionOptions = {}) {
59
+ this.options = { ...this.options, ...options }
60
+ }
61
+
62
+ /**
63
+ * Connect to the LAPLACE Event Bridge
64
+ * @returns A promise that resolves when the connection is established
65
+ */
66
+ public connect(): Promise<void> {
67
+ return new Promise((resolve, reject) => {
68
+ try {
69
+ if (this.ws) {
70
+ this.ws.close()
71
+ }
72
+
73
+ const protocols: string[] = []
74
+ if (this.options.token) {
75
+ // Add the token as the second protocol parameter
76
+ protocols.push('laplace-event-bridge-role-client', this.options.token)
77
+ }
78
+
79
+ this.ws = new WebSocket(this.options.url, protocols)
80
+
81
+ this.ws.onopen = () => {
82
+ this.isConnected = true
83
+ this.reconnectAttempts = 0
84
+ console.log('Connected to LAPLACE Event Bridge')
85
+ resolve()
86
+ }
87
+
88
+ this.ws.onmessage = event => {
89
+ try {
90
+ const data = JSON.parse(event.data)
91
+
92
+ // Store client ID from the established message
93
+ if (data.type === 'established' && data.clientId) {
94
+ this.clientId = data.clientId
95
+ console.log(`Connection established with client ID: ${this.clientId}`)
96
+ }
97
+
98
+ // Process the event
99
+ this.processEvent(data)
100
+ } catch (err) {
101
+ console.error('Failed to parse event data:', err)
102
+ }
103
+ }
104
+
105
+ this.ws.onerror = error => {
106
+ console.error('WebSocket error:', error)
107
+ reject(error)
108
+ }
109
+
110
+ this.ws.onclose = () => {
111
+ this.isConnected = false
112
+ console.log('Disconnected from LAPLACE Event Bridge')
113
+
114
+ if (this.options.reconnect && this.reconnectAttempts < this.options.maxReconnectAttempts) {
115
+ this.reconnectAttempts++
116
+ console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.options.maxReconnectAttempts})...`)
117
+ this.reconnectTimer = setTimeout(() => {
118
+ this.connect().catch(err => {
119
+ console.error('Reconnection failed:', err)
120
+ })
121
+ }, this.options.reconnectInterval) as unknown as number
122
+ }
123
+ }
124
+ } catch (err) {
125
+ reject(err)
126
+ }
127
+ })
128
+ }
129
+
130
+ /**
131
+ * Disconnect from the LAPLACE Event Bridge
132
+ */
133
+ public disconnect(): void {
134
+ if (this.reconnectTimer) {
135
+ clearTimeout(this.reconnectTimer)
136
+ this.reconnectTimer = null
137
+ }
138
+
139
+ if (this.ws) {
140
+ this.ws.close()
141
+ this.ws = null
142
+ }
143
+
144
+ this.isConnected = false
145
+ this.clientId = null
146
+ }
147
+
148
+ /**
149
+ * Register an event handler for a specific event type
150
+ * @param eventType The event type to listen for
151
+ * @param handler The handler function to call when the event is received
152
+ */
153
+ public on<T extends LaplaceEventTypes>(eventType: T, handler: (event: EventTypeMap[T]) => void): void {
154
+ if (!this.eventHandlers.has(eventType)) {
155
+ this.eventHandlers.set(eventType, [])
156
+ }
157
+ this.eventHandlers.get(eventType)!.push(handler)
158
+ }
159
+
160
+ /**
161
+ * Register a handler for all events
162
+ * @param handler The handler function to call for any event
163
+ */
164
+ public onAny(handler: AnyEventHandler): void {
165
+ this.anyEventHandlers.push(handler)
166
+ }
167
+
168
+ /**
169
+ * Remove an event handler for a specific event type
170
+ * @param eventType The event type to remove the handler for
171
+ * @param handler The handler function to remove
172
+ */
173
+ public off<T extends LaplaceEventTypes>(eventType: T, handler: (event: EventTypeMap[T]) => void): void {
174
+ if (!this.eventHandlers.has(eventType)) {
175
+ return
176
+ }
177
+
178
+ const handlers = this.eventHandlers.get(eventType)!
179
+ const index = handlers.indexOf(handler)
180
+
181
+ if (index !== -1) {
182
+ handlers.splice(index, 1)
183
+ }
184
+
185
+ if (handlers.length === 0) {
186
+ this.eventHandlers.delete(eventType)
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Remove a handler for all events
192
+ * @param handler The handler function to remove
193
+ */
194
+ public offAny(handler: AnyEventHandler): void {
195
+ const index = this.anyEventHandlers.indexOf(handler)
196
+ if (index !== -1) {
197
+ this.anyEventHandlers.splice(index, 1)
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Check if the client is connected to the bridge
203
+ */
204
+ public isConnectedToBridge(): boolean {
205
+ return this.isConnected
206
+ }
207
+
208
+ /**
209
+ * Get the client ID assigned by the bridge
210
+ */
211
+ public getClientId(): string | null {
212
+ return this.clientId
213
+ }
214
+
215
+ /**
216
+ * Send an event to the bridge
217
+ * @param event The event to send
218
+ */
219
+ public send(event: LaplaceEvent): void {
220
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
221
+ throw new Error('Not connected to LAPLACE Event Bridge')
222
+ }
223
+
224
+ this.ws.send(JSON.stringify(event))
225
+ }
226
+
227
+ private processEvent(event: LaplaceEvent): void {
228
+ // Call specific event handlers
229
+ if (this.eventHandlers.has(event.type)) {
230
+ for (const handler of this.eventHandlers.get(event.type)!) {
231
+ try {
232
+ handler(event)
233
+ } catch (err) {
234
+ console.error(`Error in event handler for type ${event.type}:`, err)
235
+ }
236
+ }
237
+ }
238
+
239
+ // Call any event handlers
240
+ for (const handler of this.anyEventHandlers) {
241
+ try {
242
+ handler(event)
243
+ } catch (err) {
244
+ console.error('Error in any event handler:', err)
245
+ }
246
+ }
247
+ }
248
+ }
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@laplace.live/event-bridge-sdk",
3
3
  "description": "LAPLACE Event Bridge SDK",
4
- "version": "0.0.1",
4
+ "version": "0.0.4",
5
5
  "module": "index.ts",
6
+ "license": "MIT",
6
7
  "type": "module",
7
8
  "scripts": {
8
- "build": "bun build index.ts --outdir dist --target browser --minify"
9
+ "build": "bun build index.ts --outdir dist --target browser --minify",
10
+ "publish": "bun run build && bun publish"
9
11
  },
10
12
  "exports": {
11
13
  ".": {
@@ -15,7 +17,7 @@
15
17
  },
16
18
  "files": [
17
19
  "dist",
18
- "src",
20
+ "index.ts",
19
21
  "README.md",
20
22
  "LICENSE"
21
23
  ],