pulse-js-framework 1.7.11 → 1.7.13
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 +80 -8
- package/cli/docs.js +712 -0
- package/cli/doctor.js +702 -0
- package/cli/index.js +338 -65
- package/cli/scaffold.js +1037 -0
- package/cli/test.js +455 -0
- package/package.json +19 -2
- package/runtime/a11y.js +824 -1
- package/runtime/context.js +374 -0
- package/runtime/graphql.js +1356 -0
- package/runtime/index.js +6 -0
- package/runtime/logger.js +2 -1
- package/runtime/websocket.js +874 -0
- package/types/context.d.ts +171 -0
- package/types/graphql.d.ts +490 -0
- package/types/index.d.ts +15 -0
- package/types/websocket.d.ts +347 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse WebSocket TypeScript Definitions
|
|
3
|
+
* @module pulse-js-framework/runtime/websocket
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Pulse } from './pulse';
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Error Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* WebSocket error codes
|
|
14
|
+
*/
|
|
15
|
+
export type WebSocketErrorCode =
|
|
16
|
+
| 'CONNECT_FAILED'
|
|
17
|
+
| 'CLOSE'
|
|
18
|
+
| 'TIMEOUT'
|
|
19
|
+
| 'PARSE_ERROR'
|
|
20
|
+
| 'SEND_FAILED'
|
|
21
|
+
| 'RECONNECT_EXHAUSTED'
|
|
22
|
+
| 'WEBSOCKET_ERROR';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* WebSocket connection state
|
|
26
|
+
*/
|
|
27
|
+
export type WebSocketState = 'connecting' | 'open' | 'closing' | 'closed';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* WebSocket Error with connection context
|
|
31
|
+
*/
|
|
32
|
+
export declare class WebSocketError extends Error {
|
|
33
|
+
readonly name: 'WebSocketError';
|
|
34
|
+
readonly code: WebSocketErrorCode;
|
|
35
|
+
readonly url: string | null;
|
|
36
|
+
readonly closeCode: number | null;
|
|
37
|
+
readonly closeReason: string | null;
|
|
38
|
+
readonly event: Event | null;
|
|
39
|
+
readonly isWebSocketError: true;
|
|
40
|
+
|
|
41
|
+
constructor(message: string, options?: {
|
|
42
|
+
code?: WebSocketErrorCode;
|
|
43
|
+
url?: string;
|
|
44
|
+
closeCode?: number;
|
|
45
|
+
closeReason?: string;
|
|
46
|
+
context?: string;
|
|
47
|
+
suggestion?: string;
|
|
48
|
+
event?: Event;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
static isWebSocketError(error: unknown): error is WebSocketError;
|
|
52
|
+
|
|
53
|
+
isConnectFailed(): boolean;
|
|
54
|
+
isClose(): boolean;
|
|
55
|
+
isTimeout(): boolean;
|
|
56
|
+
isParseError(): boolean;
|
|
57
|
+
isSendFailed(): boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Interceptor Types
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Message interceptor handler
|
|
66
|
+
*/
|
|
67
|
+
export interface MessageInterceptorHandler {
|
|
68
|
+
onMessage: (data: unknown) => unknown;
|
|
69
|
+
onError?: (error: Error) => void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Message interceptor manager
|
|
74
|
+
*/
|
|
75
|
+
export declare class MessageInterceptorManager {
|
|
76
|
+
/**
|
|
77
|
+
* Add a message interceptor
|
|
78
|
+
* @param onMessage Transform message data
|
|
79
|
+
* @param onError Handle interceptor errors
|
|
80
|
+
* @returns Interceptor ID for removal
|
|
81
|
+
*/
|
|
82
|
+
use(onMessage: (data: unknown) => unknown, onError?: (error: Error) => void): number;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Remove an interceptor by ID
|
|
86
|
+
*/
|
|
87
|
+
eject(id: number): void;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Remove all interceptors
|
|
91
|
+
*/
|
|
92
|
+
clear(): void;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Number of registered interceptors
|
|
96
|
+
*/
|
|
97
|
+
readonly size: number;
|
|
98
|
+
|
|
99
|
+
[Symbol.iterator](): IterableIterator<MessageInterceptorHandler>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// Configuration Types
|
|
104
|
+
// ============================================================================
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* WebSocket configuration options
|
|
108
|
+
*/
|
|
109
|
+
export interface WebSocketOptions {
|
|
110
|
+
// Connection
|
|
111
|
+
/** WebSocket subprotocols */
|
|
112
|
+
protocols?: string[];
|
|
113
|
+
/** Connection timeout in ms (default: 10000) */
|
|
114
|
+
connectTimeout?: number;
|
|
115
|
+
/** Connect immediately on creation (default: true) */
|
|
116
|
+
autoConnect?: boolean;
|
|
117
|
+
|
|
118
|
+
// Reconnection
|
|
119
|
+
/** Enable auto-reconnection (default: true) */
|
|
120
|
+
reconnect?: boolean;
|
|
121
|
+
/** Max reconnection attempts, 0 = infinite (default: 5) */
|
|
122
|
+
maxRetries?: number;
|
|
123
|
+
/** Base delay for exponential backoff in ms (default: 1000) */
|
|
124
|
+
baseDelay?: number;
|
|
125
|
+
/** Maximum delay between retries in ms (default: 30000) */
|
|
126
|
+
maxDelay?: number;
|
|
127
|
+
/** Jitter factor for backoff randomization 0-1 (default: 0.3) */
|
|
128
|
+
jitterFactor?: number;
|
|
129
|
+
|
|
130
|
+
// Heartbeat
|
|
131
|
+
/** Enable heartbeat/ping-pong (default: false) */
|
|
132
|
+
heartbeat?: boolean;
|
|
133
|
+
/** Heartbeat interval in ms (default: 30000) */
|
|
134
|
+
heartbeatInterval?: number;
|
|
135
|
+
/** Pong response timeout in ms (default: 10000) */
|
|
136
|
+
heartbeatTimeout?: number;
|
|
137
|
+
/** Message to send as heartbeat (default: 'ping') */
|
|
138
|
+
heartbeatMessage?: unknown;
|
|
139
|
+
/** Custom function to detect pong responses */
|
|
140
|
+
isPong?: (message: unknown) => boolean;
|
|
141
|
+
|
|
142
|
+
// Message handling
|
|
143
|
+
/** Queue messages when disconnected (default: true) */
|
|
144
|
+
queueWhileDisconnected?: boolean;
|
|
145
|
+
/** Maximum queued messages (default: 100) */
|
|
146
|
+
maxQueueSize?: number;
|
|
147
|
+
/** Default message type (default: 'json') */
|
|
148
|
+
messageType?: 'json' | 'text' | 'binary';
|
|
149
|
+
/** Auto-parse JSON messages (default: true) */
|
|
150
|
+
autoParseJson?: boolean;
|
|
151
|
+
|
|
152
|
+
// Callbacks
|
|
153
|
+
/** Called when connection opens */
|
|
154
|
+
onOpen?: (event: Event) => void;
|
|
155
|
+
/** Called when connection closes */
|
|
156
|
+
onClose?: (event: CloseEvent) => void;
|
|
157
|
+
/** Called on error */
|
|
158
|
+
onError?: (error: WebSocketError) => void;
|
|
159
|
+
/** Called on message received */
|
|
160
|
+
onMessage?: (data: unknown, event: MessageEvent) => void;
|
|
161
|
+
/** Called before each reconnection attempt */
|
|
162
|
+
onReconnecting?: (attempt: number, delay: number) => void;
|
|
163
|
+
/** Called after successful reconnection */
|
|
164
|
+
onReconnected?: () => void;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// WebSocket Instance Types
|
|
169
|
+
// ============================================================================
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* WebSocket instance returned by createWebSocket
|
|
173
|
+
*/
|
|
174
|
+
export interface WebSocketInstance {
|
|
175
|
+
// Reactive state
|
|
176
|
+
/** Connection state pulse */
|
|
177
|
+
readonly state: Pulse<WebSocketState>;
|
|
178
|
+
/** True when connected */
|
|
179
|
+
readonly connected: Pulse<boolean>;
|
|
180
|
+
/** True during reconnection attempts */
|
|
181
|
+
readonly reconnecting: Pulse<boolean>;
|
|
182
|
+
/** Current reconnection attempt number */
|
|
183
|
+
readonly reconnectAttempt: Pulse<number>;
|
|
184
|
+
/** Last error */
|
|
185
|
+
readonly error: Pulse<WebSocketError | null>;
|
|
186
|
+
/** Number of queued messages */
|
|
187
|
+
readonly queuedCount: Pulse<number>;
|
|
188
|
+
|
|
189
|
+
// Methods
|
|
190
|
+
/** Manually connect (if autoConnect=false) */
|
|
191
|
+
connect(): void;
|
|
192
|
+
/** Close connection */
|
|
193
|
+
disconnect(code?: number, reason?: string): void;
|
|
194
|
+
/** Send a message (auto-serializes objects to JSON) */
|
|
195
|
+
send(data: unknown): void;
|
|
196
|
+
/** Send JSON message */
|
|
197
|
+
sendJson(data: unknown): void;
|
|
198
|
+
/** Send binary message */
|
|
199
|
+
sendBinary(data: ArrayBuffer | ArrayBufferView | Blob): void;
|
|
200
|
+
/** Clean up and close permanently */
|
|
201
|
+
dispose(): void;
|
|
202
|
+
|
|
203
|
+
// Interceptors
|
|
204
|
+
readonly interceptors: {
|
|
205
|
+
incoming: MessageInterceptorManager;
|
|
206
|
+
outgoing: MessageInterceptorManager;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Events
|
|
210
|
+
/** Add event listener, returns unsubscribe function */
|
|
211
|
+
on(event: 'open', handler: (event: Event) => void): () => void;
|
|
212
|
+
on(event: 'close', handler: (event: CloseEvent) => void): () => void;
|
|
213
|
+
on(event: 'error', handler: (error: WebSocketError) => void): () => void;
|
|
214
|
+
on(event: 'message', handler: (data: unknown, event: MessageEvent) => void): () => void;
|
|
215
|
+
/** Remove event listener */
|
|
216
|
+
off(event: string, handler: Function): void;
|
|
217
|
+
/** Add one-time listener */
|
|
218
|
+
once(event: 'open', handler: (event: Event) => void): () => void;
|
|
219
|
+
once(event: 'close', handler: (event: CloseEvent) => void): () => void;
|
|
220
|
+
once(event: 'error', handler: (error: WebSocketError) => void): () => void;
|
|
221
|
+
once(event: 'message', handler: (data: unknown, event: MessageEvent) => void): () => void;
|
|
222
|
+
|
|
223
|
+
// Properties
|
|
224
|
+
/** WebSocket URL */
|
|
225
|
+
readonly url: string;
|
|
226
|
+
/** Raw WebSocket instance */
|
|
227
|
+
readonly socket: WebSocket | null;
|
|
228
|
+
/** Merged options */
|
|
229
|
+
readonly options: WebSocketOptions;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ============================================================================
|
|
233
|
+
// useWebSocket Hook Types
|
|
234
|
+
// ============================================================================
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* useWebSocket hook options
|
|
238
|
+
*/
|
|
239
|
+
export interface UseWebSocketOptions extends WebSocketOptions {
|
|
240
|
+
/** Connect immediately (default: true) */
|
|
241
|
+
immediate?: boolean;
|
|
242
|
+
/** Initial lastMessage value (default: null) */
|
|
243
|
+
initialData?: unknown;
|
|
244
|
+
/** Keep last N messages, 0 = no history (default: 0) */
|
|
245
|
+
messageHistorySize?: number;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* useWebSocket hook return type
|
|
250
|
+
*/
|
|
251
|
+
export interface UseWebSocketReturn {
|
|
252
|
+
// State
|
|
253
|
+
/** True when connected */
|
|
254
|
+
connected: Pulse<boolean>;
|
|
255
|
+
/** Most recent message */
|
|
256
|
+
lastMessage: Pulse<unknown>;
|
|
257
|
+
/** Message history (if messageHistorySize > 0) */
|
|
258
|
+
messages: Pulse<unknown[]>;
|
|
259
|
+
/** Last error */
|
|
260
|
+
error: Pulse<WebSocketError | null>;
|
|
261
|
+
/** True during reconnection */
|
|
262
|
+
reconnecting: Pulse<boolean>;
|
|
263
|
+
/** Connection state */
|
|
264
|
+
state: Pulse<WebSocketState>;
|
|
265
|
+
/** Number of queued messages */
|
|
266
|
+
queuedCount: Pulse<number>;
|
|
267
|
+
/** Current reconnection attempt */
|
|
268
|
+
reconnectAttempt: Pulse<number>;
|
|
269
|
+
|
|
270
|
+
// Methods
|
|
271
|
+
/** Send a message */
|
|
272
|
+
send(data: unknown): void;
|
|
273
|
+
/** Send JSON message */
|
|
274
|
+
sendJson(data: unknown): void;
|
|
275
|
+
/** Send binary message */
|
|
276
|
+
sendBinary(data: ArrayBuffer | ArrayBufferView | Blob): void;
|
|
277
|
+
/** Manually connect */
|
|
278
|
+
connect(): void;
|
|
279
|
+
/** Close connection */
|
|
280
|
+
disconnect(code?: number, reason?: string): void;
|
|
281
|
+
/** Clear message history */
|
|
282
|
+
clearMessages(): void;
|
|
283
|
+
/** Clear error state */
|
|
284
|
+
clearError(): void;
|
|
285
|
+
|
|
286
|
+
/** Underlying WebSocket instance */
|
|
287
|
+
readonly ws: WebSocketInstance;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// Factory Functions
|
|
292
|
+
// ============================================================================
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Create a WebSocket client with auto-reconnection, heartbeat, and message queuing.
|
|
296
|
+
*
|
|
297
|
+
* @param url WebSocket URL (ws:// or wss://)
|
|
298
|
+
* @param options Configuration options
|
|
299
|
+
* @returns WebSocket instance with reactive state and controls
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* const ws = createWebSocket('wss://api.example.com/ws', {
|
|
303
|
+
* reconnect: true,
|
|
304
|
+
* heartbeat: true
|
|
305
|
+
* });
|
|
306
|
+
*
|
|
307
|
+
* ws.on('message', (data) => console.log('Received:', data));
|
|
308
|
+
* ws.send({ type: 'subscribe', channel: 'updates' });
|
|
309
|
+
*/
|
|
310
|
+
export declare function createWebSocket(
|
|
311
|
+
url: string,
|
|
312
|
+
options?: WebSocketOptions
|
|
313
|
+
): WebSocketInstance;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Reactive WebSocket hook with automatic cleanup.
|
|
317
|
+
*
|
|
318
|
+
* @param url WebSocket URL
|
|
319
|
+
* @param options Configuration options
|
|
320
|
+
* @returns Reactive WebSocket state and controls
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* const { connected, lastMessage, send } = useWebSocket('wss://api.example.com/ws');
|
|
324
|
+
*
|
|
325
|
+
* effect(() => {
|
|
326
|
+
* if (connected.get()) {
|
|
327
|
+
* send({ type: 'subscribe' });
|
|
328
|
+
* }
|
|
329
|
+
* });
|
|
330
|
+
*/
|
|
331
|
+
export declare function useWebSocket(
|
|
332
|
+
url: string,
|
|
333
|
+
options?: UseWebSocketOptions
|
|
334
|
+
): UseWebSocketReturn;
|
|
335
|
+
|
|
336
|
+
// ============================================================================
|
|
337
|
+
// Default Export
|
|
338
|
+
// ============================================================================
|
|
339
|
+
|
|
340
|
+
declare const _default: {
|
|
341
|
+
createWebSocket: typeof createWebSocket;
|
|
342
|
+
useWebSocket: typeof useWebSocket;
|
|
343
|
+
WebSocketError: typeof WebSocketError;
|
|
344
|
+
MessageInterceptorManager: typeof MessageInterceptorManager;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export default _default;
|