verani 0.1.6 → 0.1.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.
@@ -0,0 +1 @@
1
+ const require_types=require(`./types-083oWz55.cjs`);function encodeClientMessage$1(t){return require_types.n(t)}function decodeServerMessage$1(t){return require_types.s(t)}const DEFAULT_RECONNECTION_CONFIG={enabled:!0,maxAttempts:10,initialDelay:1e3,maxDelay:3e4,backoffMultiplier:1.5};var ConnectionManager=class{constructor(e=DEFAULT_RECONNECTION_CONFIG,t){this.config=e,this.onStateChange=t,this.state=`disconnected`,this.reconnectAttempts=0,this.currentDelay=e.initialDelay}getState(){return this.state}isValidStateTransition(e,t){return{disconnected:[`connecting`,`reconnecting`],connecting:[`connected`,`disconnected`,`error`,`reconnecting`],connected:[`disconnected`,`reconnecting`],reconnecting:[`connecting`,`disconnected`,`error`],error:[`reconnecting`,`disconnected`,`connecting`]}[e]?.includes(t)??!1}setState(e){this.state!==e&&(this.isValidStateTransition(this.state,e),this.state=e,this.onStateChange?.(e))}resetReconnection(){this.reconnectAttempts=0,this.currentDelay=this.config.initialDelay,this.clearReconnectTimer()}scheduleReconnect(e){return this.config.enabled?this.config.maxAttempts>0&&this.reconnectAttempts>=this.config.maxAttempts?(this.setState(`error`),!1):(this.clearReconnectTimer(),this.setState(`reconnecting`),this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{e(),this.currentDelay=Math.min(this.currentDelay*this.config.backoffMultiplier,this.config.maxDelay)},this.currentDelay),!0):!1}cancelReconnect(){this.clearReconnectTimer(),this.state===`reconnecting`&&this.setState(`disconnected`)}clearReconnectTimer(){this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0)}getReconnectAttempts(){return this.reconnectAttempts}getNextDelay(){return this.currentDelay}destroy(){this.clearReconnectTimer()}},VeraniClient=class{constructor(e,t={}){this.url=e,this.listeners=new Map,this.messageQueue=[],this.isConnecting=!1,this.connectionId=0,this.options={reconnection:{enabled:t.reconnection?.enabled??DEFAULT_RECONNECTION_CONFIG.enabled,maxAttempts:t.reconnection?.maxAttempts??DEFAULT_RECONNECTION_CONFIG.maxAttempts,initialDelay:t.reconnection?.initialDelay??DEFAULT_RECONNECTION_CONFIG.initialDelay,maxDelay:t.reconnection?.maxDelay??DEFAULT_RECONNECTION_CONFIG.maxDelay,backoffMultiplier:t.reconnection?.backoffMultiplier??DEFAULT_RECONNECTION_CONFIG.backoffMultiplier},maxQueueSize:t.maxQueueSize??100,connectionTimeout:t.connectionTimeout??1e4},this.connectionManager=new ConnectionManager(this.options.reconnection,e=>{this.onStateChangeCallback?.(e)}),this.connect()}cleanupWebSocket(){if(this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.ws){let e=this.ws;if(this.ws=void 0,e.readyState===WebSocket.OPEN||e.readyState===WebSocket.CONNECTING)try{e.close(1e3,`Cleanup`)}catch{}}}connect(){if(!this.isConnecting&&!this.isConnected()){this.cleanupWebSocket();try{this.isConnecting=!0,this.connectionId++;let e=this.connectionId;this.connectionManager.setState(`connecting`),this.emitLifecycleEvent(`connecting`),this.ws=new WebSocket(this.url),this.connectionTimeout=setTimeout(()=>{this.isConnecting&&this.connectionId===e&&(this.ws?.close(),this.handleConnectionError(Error(`Connection timeout`)))},this.options.connectionTimeout),this.ws.addEventListener(`open`,()=>{this.connectionId===e&&this.handleOpen()}),this.ws.addEventListener(`message`,t=>{this.connectionId===e&&this.handleMessage(t)}),this.ws.addEventListener(`close`,t=>{this.connectionId===e&&this.handleClose(t)}),this.ws.addEventListener(`error`,t=>{this.connectionId===e&&this.handleError(t)})}catch(e){this.isConnecting=!1,this.handleConnectionError(e)}}}handleOpen(){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionManager.setState(`connected`),this.connectionManager.resetReconnection(),this.flushMessageQueue(),this.connectionResolve&&(this.connectionResolve(),this.connectionPromise=void 0,this.connectionResolve=void 0,this.connectionReject=void 0),this.emitLifecycleEvent(`open`),this.emitLifecycleEvent(`connected`),this.onOpenCallback?.()}handleMessage(e){let t=decodeServerMessage$1(e.data);if(!t)return;let r=t.type,i=t.data;t.type===`event`&&t.data&&typeof t.data==`object`&&`type`in t.data&&(r=t.data.type,i=t.data);let a=this.listeners.get(r);if(a)for(let e of a)try{e(i)}catch{}}handleClose(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionManager.setState(`disconnected`),this.connectionReject&&=(this.connectionReject(Error(`Connection closed: ${e.reason||`Unknown reason`}`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.emitLifecycleEvent(`close`,e),this.emitLifecycleEvent(`disconnected`,e),this.onCloseCallback?.(e),e.code!==1e3&&e.code!==1001&&this.connectionManager.scheduleReconnect(()=>this.connect())&&this.emitLifecycleEvent(`reconnecting`)}handleError(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.emitLifecycleEvent(`error`,e),this.onErrorCallback?.(e),this.handleConnectionError(Error(`WebSocket error`))}handleConnectionError(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionReject&&=(this.connectionReject(e),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.emitLifecycleEvent(`error`,e),this.connectionManager.scheduleReconnect(()=>this.connect())&&this.emitLifecycleEvent(`reconnecting`)}emitLifecycleEvent(e,t){let n=this.listeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}flushMessageQueue(){if(!(!this.ws||this.ws.readyState!==WebSocket.OPEN))for(;this.messageQueue.length>0;){let e=this.messageQueue.shift();try{this.ws.send(encodeClientMessage$1(e))}catch{}}}getState(){return this.connectionManager.getState()}isConnected(){return this.ws?.readyState===WebSocket.OPEN&&this.connectionManager.getState()===`connected`}getConnectionState(){return{state:this.connectionManager.getState(),isConnected:this.isConnected(),isConnecting:this.isConnecting,reconnectAttempts:this.connectionManager.getReconnectAttempts(),connectionId:this.connectionId}}waitForConnection(){return this.isConnected()?Promise.resolve():(this.connectionPromise||=new Promise((e,t)=>{this.connectionResolve=e,this.connectionReject=t;let n=setTimeout(()=>{this.connectionReject&&=(this.connectionReject(Error(`Connection wait timeout`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0)},this.options.connectionTimeout*2);this.connectionPromise&&this.connectionPromise.finally(()=>{clearTimeout(n)})}),this.connectionPromise)}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t){let n=r=>{this.off(e,n),t(r)};this.on(e,n)}emit(e,n){let r={type:e,data:n};if(this.isConnected())try{this.ws.send(encodeClientMessage$1(r))}catch{this.queueMessage(r)}else this.queueMessage(r)}queueMessage(e){this.messageQueue.length>=this.options.maxQueueSize&&this.messageQueue.shift(),this.messageQueue.push(e)}onOpen(e){this.onOpenCallback=e}onClose(e){this.onCloseCallback=e}onError(e){this.onErrorCallback=e}onStateChange(e){this.onStateChangeCallback=e}reconnect(){this.connectionManager.resetReconnection(),this.connectionManager.cancelReconnect(),this.cleanupWebSocket(),this.isConnecting=!1,this.connectionManager.setState(`disconnected`),this.connect()}disconnect(){this.connectionManager.cancelReconnect(),this.isConnecting=!1,this.connectionReject&&=(this.connectionReject(Error(`Connection disconnected`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.cleanupWebSocket(),this.connectionManager.setState(`disconnected`)}close(){this.connectionReject&&=(this.connectionReject(Error(`Client closed`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.disconnect(),this.listeners.clear(),this.messageQueue=[],this.connectionManager.destroy()}};exports.ConnectionManager=ConnectionManager,exports.DEFAULT_RECONNECTION_CONFIG=DEFAULT_RECONNECTION_CONFIG,exports.PROTOCOL_VERSION=require_types.t,exports.VeraniClient=VeraniClient,exports.decodeClientMessage=require_types.a,exports.decodeFrame=require_types.o,exports.decodeServerMessage=require_types.s,exports.encodeClientMessage=require_types.n,exports.encodeFrame=require_types.r,exports.encodeServerMessage=require_types.i;
@@ -0,0 +1,229 @@
1
+ import { a as encodeFrame, d as ServerMessage, f as VeraniMessage, i as encodeClientMessage, n as decodeFrame, o as encodeServerMessage, r as decodeServerMessage, s as ClientMessage, t as decodeClientMessage, u as PROTOCOL_VERSION } from "./decode-DMA_rBWB.cjs";
2
+
3
+ //#region src/client/connection.d.ts
4
+ /**
5
+ * Connection state management for Verani client
6
+ */
7
+ type ConnectionState = "connecting" | "connected" | "disconnected" | "reconnecting" | "error";
8
+ interface ReconnectionConfig {
9
+ /** Enable automatic reconnection */
10
+ enabled: boolean;
11
+ /** Maximum number of reconnection attempts (0 = infinite) */
12
+ maxAttempts: number;
13
+ /** Initial delay in milliseconds */
14
+ initialDelay: number;
15
+ /** Maximum delay in milliseconds */
16
+ maxDelay: number;
17
+ /** Backoff multiplier for exponential backoff */
18
+ backoffMultiplier: number;
19
+ }
20
+ declare const DEFAULT_RECONNECTION_CONFIG: ReconnectionConfig;
21
+ /**
22
+ * Manages WebSocket connection lifecycle and reconnection logic
23
+ */
24
+ declare class ConnectionManager {
25
+ private config;
26
+ private onStateChange?;
27
+ private state;
28
+ private reconnectAttempts;
29
+ private reconnectTimer?;
30
+ private currentDelay;
31
+ constructor(config?: ReconnectionConfig, onStateChange?: ((state: ConnectionState) => void) | undefined);
32
+ /**
33
+ * Gets the current connection state
34
+ */
35
+ getState(): ConnectionState;
36
+ /**
37
+ * Validates if a state transition is valid
38
+ */
39
+ private isValidStateTransition;
40
+ /**
41
+ * Updates the connection state and notifies listeners
42
+ */
43
+ setState(newState: ConnectionState): void;
44
+ /**
45
+ * Resets reconnection state (called on successful connection)
46
+ */
47
+ resetReconnection(): void;
48
+ /**
49
+ * Schedules a reconnection attempt
50
+ */
51
+ scheduleReconnect(connectFn: () => void): boolean;
52
+ /**
53
+ * Cancels any pending reconnection
54
+ */
55
+ cancelReconnect(): void;
56
+ /**
57
+ * Clears the reconnect timer
58
+ */
59
+ private clearReconnectTimer;
60
+ /**
61
+ * Gets the current reconnection attempt count
62
+ */
63
+ getReconnectAttempts(): number;
64
+ /**
65
+ * Gets the next reconnection delay
66
+ */
67
+ getNextDelay(): number;
68
+ /**
69
+ * Cleanup method
70
+ */
71
+ destroy(): void;
72
+ }
73
+ //#endregion
74
+ //#region src/client/client.d.ts
75
+ /**
76
+ * Client options for configuring the Verani client
77
+ */
78
+ interface VeraniClientOptions {
79
+ /** Reconnection configuration */
80
+ reconnection?: Partial<ReconnectionConfig>;
81
+ /** Maximum number of messages to queue when disconnected */
82
+ maxQueueSize?: number;
83
+ /** Connection timeout in milliseconds */
84
+ connectionTimeout?: number;
85
+ }
86
+ /**
87
+ * Verani WebSocket client with automatic reconnection and lifecycle management
88
+ */
89
+ declare class VeraniClient {
90
+ private url;
91
+ private ws?;
92
+ private listeners;
93
+ private connectionManager;
94
+ private messageQueue;
95
+ private options;
96
+ private onOpenCallback?;
97
+ private onCloseCallback?;
98
+ private onErrorCallback?;
99
+ private onStateChangeCallback?;
100
+ private connectionPromise?;
101
+ private connectionResolve?;
102
+ private connectionReject?;
103
+ private connectionTimeout?;
104
+ private isConnecting;
105
+ private connectionId;
106
+ /**
107
+ * Creates a new Verani client
108
+ * @param url - WebSocket URL to connect to
109
+ * @param options - Client configuration options
110
+ */
111
+ constructor(url: string, options?: VeraniClientOptions);
112
+ /**
113
+ * Cleans up existing WebSocket connection and resources
114
+ */
115
+ private cleanupWebSocket;
116
+ /**
117
+ * Establishes WebSocket connection
118
+ */
119
+ private connect;
120
+ /**
121
+ * Handles successful WebSocket connection
122
+ */
123
+ private handleOpen;
124
+ /**
125
+ * Handles incoming WebSocket messages
126
+ */
127
+ private handleMessage;
128
+ /**
129
+ * Handles WebSocket closure
130
+ */
131
+ private handleClose;
132
+ /**
133
+ * Handles WebSocket errors
134
+ */
135
+ private handleError;
136
+ /**
137
+ * Handles connection errors
138
+ */
139
+ private handleConnectionError;
140
+ /**
141
+ * Emits a lifecycle event to registered listeners
142
+ */
143
+ private emitLifecycleEvent;
144
+ /**
145
+ * Flushes queued messages when connection is established
146
+ */
147
+ private flushMessageQueue;
148
+ /**
149
+ * Gets the current connection state
150
+ */
151
+ getState(): ConnectionState;
152
+ /**
153
+ * Checks if the client is currently connected
154
+ */
155
+ isConnected(): boolean;
156
+ /**
157
+ * Gets detailed connection information
158
+ */
159
+ getConnectionState(): {
160
+ state: ConnectionState;
161
+ isConnected: boolean;
162
+ isConnecting: boolean;
163
+ reconnectAttempts: number;
164
+ connectionId: number;
165
+ };
166
+ /**
167
+ * Waits for the connection to be established
168
+ * @returns Promise that resolves when connected
169
+ */
170
+ waitForConnection(): Promise<void>;
171
+ /**
172
+ * Registers an event listener
173
+ * @param event - Event type to listen for
174
+ * @param callback - Callback function to invoke when event is received
175
+ */
176
+ on(event: string, callback: (data: any) => void): void;
177
+ /**
178
+ * Removes an event listener
179
+ * @param event - Event type to remove listener from
180
+ * @param callback - Callback function to remove
181
+ */
182
+ off(event: string, callback: (data: any) => void): void;
183
+ /**
184
+ * Registers a one-time event listener
185
+ * @param event - Event type to listen for
186
+ * @param callback - Callback function to invoke once
187
+ */
188
+ once(event: string, callback: (data: any) => void): void;
189
+ /**
190
+ * Sends a message to the server
191
+ * @param type - Message type
192
+ * @param data - Optional message data
193
+ */
194
+ emit(type: string, data?: any): void;
195
+ /**
196
+ * Queues a message for sending when connected
197
+ */
198
+ private queueMessage;
199
+ /**
200
+ * Registers lifecycle callback for connection open
201
+ */
202
+ onOpen(callback: () => void): void;
203
+ /**
204
+ * Registers lifecycle callback for connection close
205
+ */
206
+ onClose(callback: (event: CloseEvent) => void): void;
207
+ /**
208
+ * Registers lifecycle callback for connection error
209
+ */
210
+ onError(callback: (error: Event) => void): void;
211
+ /**
212
+ * Registers lifecycle callback for state changes
213
+ */
214
+ onStateChange(callback: (state: ConnectionState) => void): void;
215
+ /**
216
+ * Manually triggers a reconnection
217
+ */
218
+ reconnect(): void;
219
+ /**
220
+ * Closes the connection without reconnecting
221
+ */
222
+ disconnect(): void;
223
+ /**
224
+ * Closes the connection and cleans up resources
225
+ */
226
+ close(): void;
227
+ }
228
+ //#endregion
229
+ export { type ClientMessage, ConnectionManager, type ConnectionState, DEFAULT_RECONNECTION_CONFIG, PROTOCOL_VERSION, type ReconnectionConfig, type ServerMessage, VeraniClient, type VeraniClientOptions, type VeraniMessage, decodeClientMessage, decodeFrame, decodeServerMessage, encodeClientMessage, encodeFrame, encodeServerMessage };
@@ -0,0 +1,229 @@
1
+ import { a as encodeFrame, d as ServerMessage, f as VeraniMessage, i as encodeClientMessage, n as decodeFrame, o as encodeServerMessage, r as decodeServerMessage, s as ClientMessage, t as decodeClientMessage, u as PROTOCOL_VERSION } from "./decode-9DerwlQ1.mjs";
2
+
3
+ //#region src/client/connection.d.ts
4
+ /**
5
+ * Connection state management for Verani client
6
+ */
7
+ type ConnectionState = "connecting" | "connected" | "disconnected" | "reconnecting" | "error";
8
+ interface ReconnectionConfig {
9
+ /** Enable automatic reconnection */
10
+ enabled: boolean;
11
+ /** Maximum number of reconnection attempts (0 = infinite) */
12
+ maxAttempts: number;
13
+ /** Initial delay in milliseconds */
14
+ initialDelay: number;
15
+ /** Maximum delay in milliseconds */
16
+ maxDelay: number;
17
+ /** Backoff multiplier for exponential backoff */
18
+ backoffMultiplier: number;
19
+ }
20
+ declare const DEFAULT_RECONNECTION_CONFIG: ReconnectionConfig;
21
+ /**
22
+ * Manages WebSocket connection lifecycle and reconnection logic
23
+ */
24
+ declare class ConnectionManager {
25
+ private config;
26
+ private onStateChange?;
27
+ private state;
28
+ private reconnectAttempts;
29
+ private reconnectTimer?;
30
+ private currentDelay;
31
+ constructor(config?: ReconnectionConfig, onStateChange?: ((state: ConnectionState) => void) | undefined);
32
+ /**
33
+ * Gets the current connection state
34
+ */
35
+ getState(): ConnectionState;
36
+ /**
37
+ * Validates if a state transition is valid
38
+ */
39
+ private isValidStateTransition;
40
+ /**
41
+ * Updates the connection state and notifies listeners
42
+ */
43
+ setState(newState: ConnectionState): void;
44
+ /**
45
+ * Resets reconnection state (called on successful connection)
46
+ */
47
+ resetReconnection(): void;
48
+ /**
49
+ * Schedules a reconnection attempt
50
+ */
51
+ scheduleReconnect(connectFn: () => void): boolean;
52
+ /**
53
+ * Cancels any pending reconnection
54
+ */
55
+ cancelReconnect(): void;
56
+ /**
57
+ * Clears the reconnect timer
58
+ */
59
+ private clearReconnectTimer;
60
+ /**
61
+ * Gets the current reconnection attempt count
62
+ */
63
+ getReconnectAttempts(): number;
64
+ /**
65
+ * Gets the next reconnection delay
66
+ */
67
+ getNextDelay(): number;
68
+ /**
69
+ * Cleanup method
70
+ */
71
+ destroy(): void;
72
+ }
73
+ //#endregion
74
+ //#region src/client/client.d.ts
75
+ /**
76
+ * Client options for configuring the Verani client
77
+ */
78
+ interface VeraniClientOptions {
79
+ /** Reconnection configuration */
80
+ reconnection?: Partial<ReconnectionConfig>;
81
+ /** Maximum number of messages to queue when disconnected */
82
+ maxQueueSize?: number;
83
+ /** Connection timeout in milliseconds */
84
+ connectionTimeout?: number;
85
+ }
86
+ /**
87
+ * Verani WebSocket client with automatic reconnection and lifecycle management
88
+ */
89
+ declare class VeraniClient {
90
+ private url;
91
+ private ws?;
92
+ private listeners;
93
+ private connectionManager;
94
+ private messageQueue;
95
+ private options;
96
+ private onOpenCallback?;
97
+ private onCloseCallback?;
98
+ private onErrorCallback?;
99
+ private onStateChangeCallback?;
100
+ private connectionPromise?;
101
+ private connectionResolve?;
102
+ private connectionReject?;
103
+ private connectionTimeout?;
104
+ private isConnecting;
105
+ private connectionId;
106
+ /**
107
+ * Creates a new Verani client
108
+ * @param url - WebSocket URL to connect to
109
+ * @param options - Client configuration options
110
+ */
111
+ constructor(url: string, options?: VeraniClientOptions);
112
+ /**
113
+ * Cleans up existing WebSocket connection and resources
114
+ */
115
+ private cleanupWebSocket;
116
+ /**
117
+ * Establishes WebSocket connection
118
+ */
119
+ private connect;
120
+ /**
121
+ * Handles successful WebSocket connection
122
+ */
123
+ private handleOpen;
124
+ /**
125
+ * Handles incoming WebSocket messages
126
+ */
127
+ private handleMessage;
128
+ /**
129
+ * Handles WebSocket closure
130
+ */
131
+ private handleClose;
132
+ /**
133
+ * Handles WebSocket errors
134
+ */
135
+ private handleError;
136
+ /**
137
+ * Handles connection errors
138
+ */
139
+ private handleConnectionError;
140
+ /**
141
+ * Emits a lifecycle event to registered listeners
142
+ */
143
+ private emitLifecycleEvent;
144
+ /**
145
+ * Flushes queued messages when connection is established
146
+ */
147
+ private flushMessageQueue;
148
+ /**
149
+ * Gets the current connection state
150
+ */
151
+ getState(): ConnectionState;
152
+ /**
153
+ * Checks if the client is currently connected
154
+ */
155
+ isConnected(): boolean;
156
+ /**
157
+ * Gets detailed connection information
158
+ */
159
+ getConnectionState(): {
160
+ state: ConnectionState;
161
+ isConnected: boolean;
162
+ isConnecting: boolean;
163
+ reconnectAttempts: number;
164
+ connectionId: number;
165
+ };
166
+ /**
167
+ * Waits for the connection to be established
168
+ * @returns Promise that resolves when connected
169
+ */
170
+ waitForConnection(): Promise<void>;
171
+ /**
172
+ * Registers an event listener
173
+ * @param event - Event type to listen for
174
+ * @param callback - Callback function to invoke when event is received
175
+ */
176
+ on(event: string, callback: (data: any) => void): void;
177
+ /**
178
+ * Removes an event listener
179
+ * @param event - Event type to remove listener from
180
+ * @param callback - Callback function to remove
181
+ */
182
+ off(event: string, callback: (data: any) => void): void;
183
+ /**
184
+ * Registers a one-time event listener
185
+ * @param event - Event type to listen for
186
+ * @param callback - Callback function to invoke once
187
+ */
188
+ once(event: string, callback: (data: any) => void): void;
189
+ /**
190
+ * Sends a message to the server
191
+ * @param type - Message type
192
+ * @param data - Optional message data
193
+ */
194
+ emit(type: string, data?: any): void;
195
+ /**
196
+ * Queues a message for sending when connected
197
+ */
198
+ private queueMessage;
199
+ /**
200
+ * Registers lifecycle callback for connection open
201
+ */
202
+ onOpen(callback: () => void): void;
203
+ /**
204
+ * Registers lifecycle callback for connection close
205
+ */
206
+ onClose(callback: (event: CloseEvent) => void): void;
207
+ /**
208
+ * Registers lifecycle callback for connection error
209
+ */
210
+ onError(callback: (error: Event) => void): void;
211
+ /**
212
+ * Registers lifecycle callback for state changes
213
+ */
214
+ onStateChange(callback: (state: ConnectionState) => void): void;
215
+ /**
216
+ * Manually triggers a reconnection
217
+ */
218
+ reconnect(): void;
219
+ /**
220
+ * Closes the connection without reconnecting
221
+ */
222
+ disconnect(): void;
223
+ /**
224
+ * Closes the connection and cleans up resources
225
+ */
226
+ close(): void;
227
+ }
228
+ //#endregion
229
+ export { type ClientMessage, ConnectionManager, type ConnectionState, DEFAULT_RECONNECTION_CONFIG, PROTOCOL_VERSION, type ReconnectionConfig, type ServerMessage, VeraniClient, type VeraniClientOptions, type VeraniMessage, decodeClientMessage, decodeFrame, decodeServerMessage, encodeClientMessage, encodeFrame, encodeServerMessage };
@@ -0,0 +1 @@
1
+ import{a as decodeClientMessage,i as encodeServerMessage,n as encodeClientMessage,o as decodeFrame,r as encodeFrame,s as decodeServerMessage,t as PROTOCOL_VERSION}from"./types-CJLnZrA8.mjs";function encodeClientMessage$1(e){return encodeClientMessage(e)}function decodeServerMessage$1(e){return decodeServerMessage(e)}const DEFAULT_RECONNECTION_CONFIG={enabled:!0,maxAttempts:10,initialDelay:1e3,maxDelay:3e4,backoffMultiplier:1.5};var ConnectionManager=class{constructor(e=DEFAULT_RECONNECTION_CONFIG,c){this.config=e,this.onStateChange=c,this.state=`disconnected`,this.reconnectAttempts=0,this.currentDelay=e.initialDelay}getState(){return this.state}isValidStateTransition(e,c){return{disconnected:[`connecting`,`reconnecting`],connecting:[`connected`,`disconnected`,`error`,`reconnecting`],connected:[`disconnected`,`reconnecting`],reconnecting:[`connecting`,`disconnected`,`error`],error:[`reconnecting`,`disconnected`,`connecting`]}[e]?.includes(c)??!1}setState(e){this.state!==e&&(this.isValidStateTransition(this.state,e),this.state=e,this.onStateChange?.(e))}resetReconnection(){this.reconnectAttempts=0,this.currentDelay=this.config.initialDelay,this.clearReconnectTimer()}scheduleReconnect(e){return this.config.enabled?this.config.maxAttempts>0&&this.reconnectAttempts>=this.config.maxAttempts?(this.setState(`error`),!1):(this.clearReconnectTimer(),this.setState(`reconnecting`),this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{e(),this.currentDelay=Math.min(this.currentDelay*this.config.backoffMultiplier,this.config.maxDelay)},this.currentDelay),!0):!1}cancelReconnect(){this.clearReconnectTimer(),this.state===`reconnecting`&&this.setState(`disconnected`)}clearReconnectTimer(){this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0)}getReconnectAttempts(){return this.reconnectAttempts}getNextDelay(){return this.currentDelay}destroy(){this.clearReconnectTimer()}},VeraniClient=class{constructor(e,c={}){this.url=e,this.listeners=new Map,this.messageQueue=[],this.isConnecting=!1,this.connectionId=0,this.options={reconnection:{enabled:c.reconnection?.enabled??DEFAULT_RECONNECTION_CONFIG.enabled,maxAttempts:c.reconnection?.maxAttempts??DEFAULT_RECONNECTION_CONFIG.maxAttempts,initialDelay:c.reconnection?.initialDelay??DEFAULT_RECONNECTION_CONFIG.initialDelay,maxDelay:c.reconnection?.maxDelay??DEFAULT_RECONNECTION_CONFIG.maxDelay,backoffMultiplier:c.reconnection?.backoffMultiplier??DEFAULT_RECONNECTION_CONFIG.backoffMultiplier},maxQueueSize:c.maxQueueSize??100,connectionTimeout:c.connectionTimeout??1e4},this.connectionManager=new ConnectionManager(this.options.reconnection,e=>{this.onStateChangeCallback?.(e)}),this.connect()}cleanupWebSocket(){if(this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.ws){let e=this.ws;if(this.ws=void 0,e.readyState===WebSocket.OPEN||e.readyState===WebSocket.CONNECTING)try{e.close(1e3,`Cleanup`)}catch{}}}connect(){if(!this.isConnecting&&!this.isConnected()){this.cleanupWebSocket();try{this.isConnecting=!0,this.connectionId++;let e=this.connectionId;this.connectionManager.setState(`connecting`),this.emitLifecycleEvent(`connecting`),this.ws=new WebSocket(this.url),this.connectionTimeout=setTimeout(()=>{this.isConnecting&&this.connectionId===e&&(this.ws?.close(),this.handleConnectionError(Error(`Connection timeout`)))},this.options.connectionTimeout),this.ws.addEventListener(`open`,()=>{this.connectionId===e&&this.handleOpen()}),this.ws.addEventListener(`message`,c=>{this.connectionId===e&&this.handleMessage(c)}),this.ws.addEventListener(`close`,c=>{this.connectionId===e&&this.handleClose(c)}),this.ws.addEventListener(`error`,c=>{this.connectionId===e&&this.handleError(c)})}catch(e){this.isConnecting=!1,this.handleConnectionError(e)}}}handleOpen(){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionManager.setState(`connected`),this.connectionManager.resetReconnection(),this.flushMessageQueue(),this.connectionResolve&&(this.connectionResolve(),this.connectionPromise=void 0,this.connectionResolve=void 0,this.connectionReject=void 0),this.emitLifecycleEvent(`open`),this.emitLifecycleEvent(`connected`),this.onOpenCallback?.()}handleMessage(e){let c=decodeServerMessage$1(e.data);if(!c)return;let l=c.type,u=c.data;c.type===`event`&&c.data&&typeof c.data==`object`&&`type`in c.data&&(l=c.data.type,u=c.data);let d=this.listeners.get(l);if(d)for(let e of d)try{e(u)}catch{}}handleClose(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionManager.setState(`disconnected`),this.connectionReject&&=(this.connectionReject(Error(`Connection closed: ${e.reason||`Unknown reason`}`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.emitLifecycleEvent(`close`,e),this.emitLifecycleEvent(`disconnected`,e),this.onCloseCallback?.(e),e.code!==1e3&&e.code!==1001&&this.connectionManager.scheduleReconnect(()=>this.connect())&&this.emitLifecycleEvent(`reconnecting`)}handleError(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.emitLifecycleEvent(`error`,e),this.onErrorCallback?.(e),this.handleConnectionError(Error(`WebSocket error`))}handleConnectionError(e){this.isConnecting=!1,this.connectionTimeout!==void 0&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=void 0),this.connectionReject&&=(this.connectionReject(e),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.emitLifecycleEvent(`error`,e),this.connectionManager.scheduleReconnect(()=>this.connect())&&this.emitLifecycleEvent(`reconnecting`)}emitLifecycleEvent(e,c){let l=this.listeners.get(e);if(l)for(let e of l)try{e(c)}catch{}}flushMessageQueue(){if(!(!this.ws||this.ws.readyState!==WebSocket.OPEN))for(;this.messageQueue.length>0;){let e=this.messageQueue.shift();try{this.ws.send(encodeClientMessage$1(e))}catch{}}}getState(){return this.connectionManager.getState()}isConnected(){return this.ws?.readyState===WebSocket.OPEN&&this.connectionManager.getState()===`connected`}getConnectionState(){return{state:this.connectionManager.getState(),isConnected:this.isConnected(),isConnecting:this.isConnecting,reconnectAttempts:this.connectionManager.getReconnectAttempts(),connectionId:this.connectionId}}waitForConnection(){return this.isConnected()?Promise.resolve():(this.connectionPromise||=new Promise((e,c)=>{this.connectionResolve=e,this.connectionReject=c;let l=setTimeout(()=>{this.connectionReject&&=(this.connectionReject(Error(`Connection wait timeout`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0)},this.options.connectionTimeout*2);this.connectionPromise&&this.connectionPromise.finally(()=>{clearTimeout(l)})}),this.connectionPromise)}on(e,c){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(c)}off(e,c){let l=this.listeners.get(e);l&&(l.delete(c),l.size===0&&this.listeners.delete(e))}once(e,c){let l=u=>{this.off(e,l),c(u)};this.on(e,l)}emit(e,c){let l={type:e,data:c};if(this.isConnected())try{this.ws.send(encodeClientMessage$1(l))}catch{this.queueMessage(l)}else this.queueMessage(l)}queueMessage(e){this.messageQueue.length>=this.options.maxQueueSize&&this.messageQueue.shift(),this.messageQueue.push(e)}onOpen(e){this.onOpenCallback=e}onClose(e){this.onCloseCallback=e}onError(e){this.onErrorCallback=e}onStateChange(e){this.onStateChangeCallback=e}reconnect(){this.connectionManager.resetReconnection(),this.connectionManager.cancelReconnect(),this.cleanupWebSocket(),this.isConnecting=!1,this.connectionManager.setState(`disconnected`),this.connect()}disconnect(){this.connectionManager.cancelReconnect(),this.isConnecting=!1,this.connectionReject&&=(this.connectionReject(Error(`Connection disconnected`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.cleanupWebSocket(),this.connectionManager.setState(`disconnected`)}close(){this.connectionReject&&=(this.connectionReject(Error(`Client closed`)),this.connectionPromise=void 0,this.connectionResolve=void 0,void 0),this.disconnect(),this.listeners.clear(),this.messageQueue=[],this.connectionManager.destroy()}};export{ConnectionManager,DEFAULT_RECONNECTION_CONFIG,PROTOCOL_VERSION,VeraniClient,decodeClientMessage,decodeFrame,decodeServerMessage,encodeClientMessage,encodeFrame,encodeServerMessage};
@@ -0,0 +1,87 @@
1
+ //#region src/shared/types.d.ts
2
+ /**
3
+ * Core message types shared between client and server
4
+ */
5
+ /**
6
+ * Base message frame structure used for all WebSocket communication
7
+ */
8
+ interface MessageFrame {
9
+ type: string;
10
+ channel?: string;
11
+ data?: any;
12
+ }
13
+ /**
14
+ * Message sent from client to server
15
+ */
16
+ interface ClientMessage extends MessageFrame {
17
+ type: string;
18
+ channel?: string;
19
+ data?: any;
20
+ }
21
+ /**
22
+ * Message sent from server to client
23
+ */
24
+ interface ServerMessage extends MessageFrame {
25
+ type: string;
26
+ channel?: string;
27
+ data?: any;
28
+ }
29
+ /**
30
+ * Connection metadata attached to each WebSocket
31
+ */
32
+ interface ConnectionMeta {
33
+ userId: string;
34
+ clientId: string;
35
+ channels: string[];
36
+ }
37
+ /**
38
+ * Unified message type for both directions
39
+ */
40
+ type VeraniMessage = ClientMessage | ServerMessage;
41
+ /**
42
+ * Protocol version for future compatibility
43
+ */
44
+ declare const PROTOCOL_VERSION = "1.0.0";
45
+ //#endregion
46
+ //#region src/shared/encode.d.ts
47
+ /**
48
+ * Encodes a message frame to JSON string for transmission
49
+ * @param frame - The message frame to encode
50
+ * @returns JSON string representation of the frame
51
+ * @throws Error if encoding fails
52
+ */
53
+ declare function encodeFrame(frame: MessageFrame): string;
54
+ /**
55
+ * Encodes a client message to JSON string
56
+ * @param message - The client message to encode
57
+ * @returns JSON string representation
58
+ */
59
+ declare function encodeClientMessage(message: MessageFrame): string;
60
+ /**
61
+ * Encodes a server message to JSON string
62
+ * @param message - The server message to encode
63
+ * @returns JSON string representation
64
+ */
65
+ declare function encodeServerMessage(message: MessageFrame): string;
66
+ //#endregion
67
+ //#region src/shared/decode.d.ts
68
+ /**
69
+ * Decodes a raw message into a MessageFrame
70
+ * @param raw - Raw data from WebSocket (string, ArrayBuffer, etc)
71
+ * @returns Decoded MessageFrame or null if invalid
72
+ */
73
+ declare function decodeFrame(raw: any): MessageFrame | null;
74
+ /**
75
+ * Decodes a client message
76
+ * @param raw - Raw data from client WebSocket
77
+ * @returns Decoded message or null if invalid
78
+ */
79
+ declare function decodeClientMessage(raw: any): MessageFrame | null;
80
+ /**
81
+ * Decodes a server message
82
+ * @param raw - Raw data from server WebSocket
83
+ * @returns Decoded message or null if invalid
84
+ */
85
+ declare function decodeServerMessage(raw: any): MessageFrame | null;
86
+ //#endregion
87
+ export { encodeFrame as a, ConnectionMeta as c, ServerMessage as d, VeraniMessage as f, encodeClientMessage as i, MessageFrame as l, decodeFrame as n, encodeServerMessage as o, decodeServerMessage as r, ClientMessage as s, decodeClientMessage as t, PROTOCOL_VERSION as u };
@@ -0,0 +1,87 @@
1
+ //#region src/shared/types.d.ts
2
+ /**
3
+ * Core message types shared between client and server
4
+ */
5
+ /**
6
+ * Base message frame structure used for all WebSocket communication
7
+ */
8
+ interface MessageFrame {
9
+ type: string;
10
+ channel?: string;
11
+ data?: any;
12
+ }
13
+ /**
14
+ * Message sent from client to server
15
+ */
16
+ interface ClientMessage extends MessageFrame {
17
+ type: string;
18
+ channel?: string;
19
+ data?: any;
20
+ }
21
+ /**
22
+ * Message sent from server to client
23
+ */
24
+ interface ServerMessage extends MessageFrame {
25
+ type: string;
26
+ channel?: string;
27
+ data?: any;
28
+ }
29
+ /**
30
+ * Connection metadata attached to each WebSocket
31
+ */
32
+ interface ConnectionMeta {
33
+ userId: string;
34
+ clientId: string;
35
+ channels: string[];
36
+ }
37
+ /**
38
+ * Unified message type for both directions
39
+ */
40
+ type VeraniMessage = ClientMessage | ServerMessage;
41
+ /**
42
+ * Protocol version for future compatibility
43
+ */
44
+ declare const PROTOCOL_VERSION = "1.0.0";
45
+ //#endregion
46
+ //#region src/shared/encode.d.ts
47
+ /**
48
+ * Encodes a message frame to JSON string for transmission
49
+ * @param frame - The message frame to encode
50
+ * @returns JSON string representation of the frame
51
+ * @throws Error if encoding fails
52
+ */
53
+ declare function encodeFrame(frame: MessageFrame): string;
54
+ /**
55
+ * Encodes a client message to JSON string
56
+ * @param message - The client message to encode
57
+ * @returns JSON string representation
58
+ */
59
+ declare function encodeClientMessage(message: MessageFrame): string;
60
+ /**
61
+ * Encodes a server message to JSON string
62
+ * @param message - The server message to encode
63
+ * @returns JSON string representation
64
+ */
65
+ declare function encodeServerMessage(message: MessageFrame): string;
66
+ //#endregion
67
+ //#region src/shared/decode.d.ts
68
+ /**
69
+ * Decodes a raw message into a MessageFrame
70
+ * @param raw - Raw data from WebSocket (string, ArrayBuffer, etc)
71
+ * @returns Decoded MessageFrame or null if invalid
72
+ */
73
+ declare function decodeFrame(raw: any): MessageFrame | null;
74
+ /**
75
+ * Decodes a client message
76
+ * @param raw - Raw data from client WebSocket
77
+ * @returns Decoded message or null if invalid
78
+ */
79
+ declare function decodeClientMessage(raw: any): MessageFrame | null;
80
+ /**
81
+ * Decodes a server message
82
+ * @param raw - Raw data from server WebSocket
83
+ * @returns Decoded message or null if invalid
84
+ */
85
+ declare function decodeServerMessage(raw: any): MessageFrame | null;
86
+ //#endregion
87
+ export { encodeFrame as a, ConnectionMeta as c, ServerMessage as d, VeraniMessage as f, encodeClientMessage as i, MessageFrame as l, decodeFrame as n, encodeServerMessage as o, decodeServerMessage as r, ClientMessage as s, decodeClientMessage as t, PROTOCOL_VERSION as u };
@@ -0,0 +1 @@
1
+ function isValidFrame(e){return e&&typeof e==`object`&&typeof e.type==`string`&&(e.channel===void 0||typeof e.channel==`string`)}function decodeFrame(a){try{let o=typeof a==`string`?a:a.toString(),s=JSON.parse(o);return isValidFrame(s)?s:null}catch{return null}}function decodeClientMessage(e){return decodeFrame(e)}function decodeServerMessage(e){return decodeFrame(e)}function encodeFrame(e){try{return JSON.stringify(e)}catch(e){throw Error(`Failed to encode frame: ${e instanceof Error?e.message:`unknown error`}`)}}function encodeClientMessage(e){return encodeFrame(e)}function encodeServerMessage(e){return encodeFrame(e)}const PROTOCOL_VERSION=`1.0.0`;Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return decodeClientMessage}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return encodeServerMessage}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return encodeClientMessage}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return decodeFrame}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return encodeFrame}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return decodeServerMessage}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return`1.0.0`}});
@@ -0,0 +1 @@
1
+ function isValidFrame(e){return e&&typeof e==`object`&&typeof e.type==`string`&&(e.channel===void 0||typeof e.channel==`string`)}function decodeFrame(a){try{let o=typeof a==`string`?a:a.toString(),s=JSON.parse(o);return isValidFrame(s)?s:null}catch{return null}}function decodeClientMessage(e){return decodeFrame(e)}function decodeServerMessage(e){return decodeFrame(e)}function encodeFrame(e){try{return JSON.stringify(e)}catch(e){throw Error(`Failed to encode frame: ${e instanceof Error?e.message:`unknown error`}`)}}function encodeClientMessage(e){return encodeFrame(e)}function encodeServerMessage(e){return encodeFrame(e)}const PROTOCOL_VERSION=`1.0.0`;export{decodeClientMessage as a,encodeServerMessage as i,encodeClientMessage as n,decodeFrame as o,encodeFrame as r,decodeServerMessage as s,PROTOCOL_VERSION as t};