pushstream-client 0.1.0 → 0.2.0
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 +78 -10
- package/dist/pushstream.cjs.js +1 -1
- package/dist/pushstream.d.ts +314 -0
- package/dist/pushstream.esm.js +1 -1
- package/dist/pushstream.js +1 -1
- package/dist/pushstream.min.js +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# pushstream-
|
|
1
|
+
# pushstream-client
|
|
2
2
|
|
|
3
3
|
A lightweight, zero-dependency JavaScript client for consuming Server-Sent Events (SSE) with automatic reconnection, event subscriptions, and connection state management.
|
|
4
4
|
|
|
@@ -6,6 +6,7 @@ A lightweight, zero-dependency JavaScript client for consuming Server-Sent Event
|
|
|
6
6
|
|
|
7
7
|
- **Zero dependencies** - Pure JavaScript, no external libraries
|
|
8
8
|
- **Tiny footprint** - Less than 5KB minified
|
|
9
|
+
- **TypeScript support** - Full type definitions included
|
|
9
10
|
- **Auto-reconnection** - Exponential backoff with jitter to prevent thundering herd
|
|
10
11
|
- **Event-driven API** - Familiar `on()`/`off()` subscription pattern
|
|
11
12
|
- **JSON parsing** - Automatic payload parsing
|
|
@@ -17,17 +18,17 @@ A lightweight, zero-dependency JavaScript client for consuming Server-Sent Event
|
|
|
17
18
|
### npm / yarn / pnpm
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
|
-
npm install pushstream-
|
|
21
|
+
npm install pushstream-client
|
|
21
22
|
# or
|
|
22
|
-
yarn add pushstream-
|
|
23
|
+
yarn add pushstream-client
|
|
23
24
|
# or
|
|
24
|
-
pnpm add pushstream-
|
|
25
|
+
pnpm add pushstream-client
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
### CDN / Script Tag
|
|
28
29
|
|
|
29
30
|
```html
|
|
30
|
-
<script src="https://unpkg.com/pushstream-
|
|
31
|
+
<script src="https://unpkg.com/pushstream-client/dist/pushstream.min.js"></script>
|
|
31
32
|
<script>
|
|
32
33
|
const client = new PushStream.EventClient('/events');
|
|
33
34
|
</script>
|
|
@@ -36,7 +37,7 @@ pnpm add pushstream-js
|
|
|
36
37
|
## Quick Start
|
|
37
38
|
|
|
38
39
|
```javascript
|
|
39
|
-
import { EventClient } from 'pushstream-
|
|
40
|
+
import { EventClient } from 'pushstream-client';
|
|
40
41
|
|
|
41
42
|
// Create client
|
|
42
43
|
const client = new EventClient('/events');
|
|
@@ -62,6 +63,74 @@ client.connect();
|
|
|
62
63
|
client.disconnect();
|
|
63
64
|
```
|
|
64
65
|
|
|
66
|
+
## TypeScript
|
|
67
|
+
|
|
68
|
+
Full TypeScript support is included out of the box. No additional `@types` packages needed.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { EventClient, ConnectionState, BuiltInEvents } from 'pushstream-client';
|
|
72
|
+
|
|
73
|
+
// Define your event payload types
|
|
74
|
+
interface OrderUpdate {
|
|
75
|
+
orderId: string;
|
|
76
|
+
status: 'pending' | 'processing' | 'shipped' | 'delivered';
|
|
77
|
+
timestamp: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface TaskProgress {
|
|
81
|
+
taskId: string;
|
|
82
|
+
percentage: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const client = new EventClient('/events', {
|
|
86
|
+
reconnect: true,
|
|
87
|
+
maxReconnectAttempts: 5
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Generic type parameter for type-safe callbacks
|
|
91
|
+
client.on<OrderUpdate>('order.updated', (data) => {
|
|
92
|
+
console.log(data.orderId); // string
|
|
93
|
+
console.log(data.status); // 'pending' | 'processing' | 'shipped' | 'delivered'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
client.on<TaskProgress>('task.progress', (data) => {
|
|
97
|
+
console.log(data.percentage); // number
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Built-in events are also typed
|
|
101
|
+
client.on('stream.error', (error) => {
|
|
102
|
+
console.error(error.message);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
client.connect();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Available Types
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import {
|
|
112
|
+
// Classes
|
|
113
|
+
EventClient,
|
|
114
|
+
SubscriptionManager,
|
|
115
|
+
|
|
116
|
+
// Types
|
|
117
|
+
EventClientOptions,
|
|
118
|
+
EventCallback,
|
|
119
|
+
ConnectionStateValue,
|
|
120
|
+
|
|
121
|
+
// Constants
|
|
122
|
+
ConnectionState,
|
|
123
|
+
BuiltInEvents,
|
|
124
|
+
DefaultOptions,
|
|
125
|
+
|
|
126
|
+
// Built-in event data types
|
|
127
|
+
StreamOpenEvent,
|
|
128
|
+
StreamCloseEvent,
|
|
129
|
+
StreamErrorEvent,
|
|
130
|
+
StreamStateChangeEvent
|
|
131
|
+
} from 'pushstream-client';
|
|
132
|
+
```
|
|
133
|
+
|
|
65
134
|
## API Reference
|
|
66
135
|
|
|
67
136
|
### `new EventClient(url, options?)`
|
|
@@ -215,7 +284,7 @@ For Node.js 18+, use with an EventSource polyfill:
|
|
|
215
284
|
import { EventSource } from 'eventsource';
|
|
216
285
|
globalThis.EventSource = EventSource;
|
|
217
286
|
|
|
218
|
-
import { EventClient } from 'pushstream-
|
|
287
|
+
import { EventClient } from 'pushstream-client';
|
|
219
288
|
// ... use as normal
|
|
220
289
|
```
|
|
221
290
|
|
|
@@ -268,7 +337,7 @@ client.connect();
|
|
|
268
337
|
TypeScript definitions are planned for a future release. For now, you can create a basic `.d.ts` file:
|
|
269
338
|
|
|
270
339
|
```typescript
|
|
271
|
-
declare module 'pushstream-
|
|
340
|
+
declare module 'pushstream-client' {
|
|
272
341
|
export class EventClient {
|
|
273
342
|
constructor(url: string, options?: EventClientOptions);
|
|
274
343
|
connect(): void;
|
|
@@ -290,5 +359,4 @@ declare module 'pushstream-js' {
|
|
|
290
359
|
|
|
291
360
|
## License
|
|
292
361
|
|
|
293
|
-
MIT
|
|
294
|
-
|
|
362
|
+
MIT
|
package/dist/pushstream.cjs.js
CHANGED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// Type definitions for pushstream-client
|
|
2
|
+
// Project: https://github.com/mavidishu/PushStream
|
|
3
|
+
// Definitions by: Dishu Mavi
|
|
4
|
+
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Options
|
|
7
|
+
// =============================================================================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for EventClient.
|
|
11
|
+
*/
|
|
12
|
+
export interface EventClientOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Whether to automatically reconnect on connection loss.
|
|
15
|
+
* @default true
|
|
16
|
+
*/
|
|
17
|
+
reconnect?: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Base delay in milliseconds between reconnection attempts.
|
|
21
|
+
* @default 1000
|
|
22
|
+
*/
|
|
23
|
+
reconnectInterval?: number;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Maximum number of reconnection attempts before giving up.
|
|
27
|
+
* @default 10
|
|
28
|
+
*/
|
|
29
|
+
maxReconnectAttempts?: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Maximum delay cap for exponential backoff in milliseconds.
|
|
33
|
+
* @default 30000
|
|
34
|
+
*/
|
|
35
|
+
maxReconnectDelay?: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Whether to include credentials in cross-origin requests.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
withCredentials?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// =============================================================================
|
|
45
|
+
// Types
|
|
46
|
+
// =============================================================================
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Callback function type for event handlers.
|
|
50
|
+
* @template T - The type of the event data payload
|
|
51
|
+
*/
|
|
52
|
+
export type EventCallback<T = unknown> = (data: T) => void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Possible values for connection state.
|
|
56
|
+
*/
|
|
57
|
+
export type ConnectionStateValue = 'disconnected' | 'connecting' | 'connected';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Built-in event name values.
|
|
61
|
+
*/
|
|
62
|
+
export type BuiltInEventValue =
|
|
63
|
+
| 'stream.open'
|
|
64
|
+
| 'stream.close'
|
|
65
|
+
| 'stream.error'
|
|
66
|
+
| 'stream.statechange';
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Constants
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Connection states for EventClient.
|
|
74
|
+
*/
|
|
75
|
+
export const ConnectionState: Readonly<{
|
|
76
|
+
/** Client is not connected */
|
|
77
|
+
DISCONNECTED: 'disconnected';
|
|
78
|
+
/** Client is attempting to connect */
|
|
79
|
+
CONNECTING: 'connecting';
|
|
80
|
+
/** Client is connected and receiving events */
|
|
81
|
+
CONNECTED: 'connected';
|
|
82
|
+
}>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Built-in event names emitted by EventClient.
|
|
86
|
+
*/
|
|
87
|
+
export const BuiltInEvents: Readonly<{
|
|
88
|
+
/** Emitted when connection is established */
|
|
89
|
+
OPEN: 'stream.open';
|
|
90
|
+
/** Emitted when connection is closed */
|
|
91
|
+
CLOSE: 'stream.close';
|
|
92
|
+
/** Emitted when an error occurs */
|
|
93
|
+
ERROR: 'stream.error';
|
|
94
|
+
/** Emitted when connection state changes */
|
|
95
|
+
STATE_CHANGE: 'stream.statechange';
|
|
96
|
+
}>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Default options for EventClient.
|
|
100
|
+
*/
|
|
101
|
+
export const DefaultOptions: Readonly<{
|
|
102
|
+
/** Whether to automatically reconnect on connection loss */
|
|
103
|
+
reconnect: true;
|
|
104
|
+
/** Base delay in milliseconds between reconnection attempts */
|
|
105
|
+
reconnectInterval: 1000;
|
|
106
|
+
/** Maximum number of reconnection attempts before giving up */
|
|
107
|
+
maxReconnectAttempts: 10;
|
|
108
|
+
/** Maximum delay cap for exponential backoff (30 seconds) */
|
|
109
|
+
maxReconnectDelay: 30000;
|
|
110
|
+
/** Whether to include credentials in cross-origin requests */
|
|
111
|
+
withCredentials: false;
|
|
112
|
+
}>;
|
|
113
|
+
|
|
114
|
+
// =============================================================================
|
|
115
|
+
// Classes
|
|
116
|
+
// =============================================================================
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* EventClient provides a clean abstraction over EventSource for consuming SSE events.
|
|
120
|
+
*
|
|
121
|
+
* Features:
|
|
122
|
+
* - Automatic reconnection with exponential backoff and jitter
|
|
123
|
+
* - Event subscription management
|
|
124
|
+
* - Automatic JSON payload parsing
|
|
125
|
+
* - Connection state tracking
|
|
126
|
+
* - Built-in lifecycle events
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* import { EventClient } from 'pushstream-client';
|
|
131
|
+
*
|
|
132
|
+
* interface TaskProgress {
|
|
133
|
+
* taskId: string;
|
|
134
|
+
* percentage: number;
|
|
135
|
+
* }
|
|
136
|
+
*
|
|
137
|
+
* const client = new EventClient('/events');
|
|
138
|
+
*
|
|
139
|
+
* client.on<TaskProgress>('task.progress', (data) => {
|
|
140
|
+
* console.log(`Task ${data.taskId}: ${data.percentage}%`);
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* client.connect();
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export class EventClient {
|
|
147
|
+
/**
|
|
148
|
+
* Create a new EventClient instance.
|
|
149
|
+
* @param url - The SSE endpoint URL (relative or absolute)
|
|
150
|
+
* @param options - Configuration options
|
|
151
|
+
*/
|
|
152
|
+
constructor(url: string, options?: EventClientOptions);
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get the current connection state.
|
|
156
|
+
*/
|
|
157
|
+
readonly state: ConnectionStateValue;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get the endpoint URL.
|
|
161
|
+
*/
|
|
162
|
+
readonly url: string;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Establish an SSE connection to the server.
|
|
166
|
+
* This method is idempotent - calling it while already connected has no effect.
|
|
167
|
+
*/
|
|
168
|
+
connect(): void;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Close the SSE connection.
|
|
172
|
+
* This method is idempotent - calling it while already disconnected has no effect.
|
|
173
|
+
* After calling disconnect(), no automatic reconnection will be attempted.
|
|
174
|
+
*/
|
|
175
|
+
disconnect(): void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Subscribe to an event.
|
|
179
|
+
* Subscriptions can be registered before or after connecting.
|
|
180
|
+
*
|
|
181
|
+
* @template T - The type of the event data payload
|
|
182
|
+
* @param event - The event name to subscribe to (e.g., 'order.updated')
|
|
183
|
+
* @param callback - The callback to invoke when the event occurs
|
|
184
|
+
* @returns This instance for method chaining
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* interface OrderUpdate {
|
|
189
|
+
* orderId: string;
|
|
190
|
+
* status: string;
|
|
191
|
+
* }
|
|
192
|
+
*
|
|
193
|
+
* client.on<OrderUpdate>('order.updated', (data) => {
|
|
194
|
+
* console.log(data.orderId); // Fully typed!
|
|
195
|
+
* });
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
on<T = unknown>(event: string, callback: EventCallback<T>): this;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Unsubscribe from an event.
|
|
202
|
+
* @param event - The event name
|
|
203
|
+
* @param callback - Specific callback to remove. If omitted, removes all callbacks for the event.
|
|
204
|
+
* @returns This instance for method chaining
|
|
205
|
+
*/
|
|
206
|
+
off<T = unknown>(event: string, callback?: EventCallback<T>): this;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Manages event subscriptions with O(1) add/remove operations.
|
|
211
|
+
* Uses Map for event->callbacks storage and Set for callback deduplication.
|
|
212
|
+
*/
|
|
213
|
+
export class SubscriptionManager {
|
|
214
|
+
/**
|
|
215
|
+
* Create a new SubscriptionManager instance.
|
|
216
|
+
*/
|
|
217
|
+
constructor();
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Register a callback for a specific event.
|
|
221
|
+
* @param event - The event name to subscribe to
|
|
222
|
+
* @param callback - The callback to invoke when the event occurs
|
|
223
|
+
* @returns True if the callback was added, false if already exists
|
|
224
|
+
*/
|
|
225
|
+
add<T = unknown>(event: string, callback: EventCallback<T>): boolean;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Remove a specific callback for an event.
|
|
229
|
+
* @param event - The event name
|
|
230
|
+
* @param callback - The callback to remove
|
|
231
|
+
* @returns True if the callback was removed
|
|
232
|
+
*/
|
|
233
|
+
remove<T = unknown>(event: string, callback: EventCallback<T>): boolean;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Remove all callbacks for a specific event.
|
|
237
|
+
* @param event - The event name
|
|
238
|
+
* @returns True if any callbacks were removed
|
|
239
|
+
*/
|
|
240
|
+
removeAll(event: string): boolean;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Emit an event to all registered callbacks.
|
|
244
|
+
* Creates a snapshot of callbacks to allow safe modification during iteration.
|
|
245
|
+
* @param event - The event name
|
|
246
|
+
* @param data - The data to pass to callbacks
|
|
247
|
+
*/
|
|
248
|
+
emit<T = unknown>(event: string, data: T): void;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Check if an event has any subscribers.
|
|
252
|
+
* @param event - The event name
|
|
253
|
+
* @returns True if the event has subscribers
|
|
254
|
+
*/
|
|
255
|
+
has(event: string): boolean;
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Get all registered event names.
|
|
259
|
+
* @returns Array of event names
|
|
260
|
+
*/
|
|
261
|
+
getEvents(): string[];
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Get the number of callbacks for a specific event.
|
|
265
|
+
* @param event - The event name
|
|
266
|
+
* @returns Number of callbacks
|
|
267
|
+
*/
|
|
268
|
+
getCount(event: string): number;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Clear all subscriptions.
|
|
272
|
+
*/
|
|
273
|
+
clear(): void;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// =============================================================================
|
|
277
|
+
// Built-in Event Data Types
|
|
278
|
+
// =============================================================================
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Data payload for 'stream.open' event.
|
|
282
|
+
*/
|
|
283
|
+
export interface StreamOpenEvent {
|
|
284
|
+
/** The SSE endpoint URL */
|
|
285
|
+
url: string;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Data payload for 'stream.close' event.
|
|
290
|
+
*/
|
|
291
|
+
export interface StreamCloseEvent {
|
|
292
|
+
/** Whether the disconnection was manual (via disconnect()) */
|
|
293
|
+
manual: boolean;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Data payload for 'stream.error' event.
|
|
298
|
+
*/
|
|
299
|
+
export interface StreamErrorEvent {
|
|
300
|
+
/** Error message */
|
|
301
|
+
message: string;
|
|
302
|
+
/** Additional error details */
|
|
303
|
+
[key: string]: unknown;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Data payload for 'stream.statechange' event.
|
|
308
|
+
*/
|
|
309
|
+
export interface StreamStateChangeEvent {
|
|
310
|
+
/** Previous connection state */
|
|
311
|
+
previousState: ConnectionStateValue;
|
|
312
|
+
/** Current connection state */
|
|
313
|
+
currentState: ConnectionStateValue;
|
|
314
|
+
}
|
package/dist/pushstream.esm.js
CHANGED
package/dist/pushstream.js
CHANGED
package/dist/pushstream.min.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pushstream-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Lightweight JavaScript client for PushStream SSE events with auto-reconnection and event-driven API",
|
|
5
5
|
"author": "Dishu Mavi",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"main": "dist/pushstream.cjs.js",
|
|
27
27
|
"module": "dist/pushstream.esm.js",
|
|
28
28
|
"browser": "dist/pushstream.min.js",
|
|
29
|
+
"types": "dist/pushstream.d.ts",
|
|
30
|
+
"typings": "dist/pushstream.d.ts",
|
|
29
31
|
"unpkg": "dist/pushstream.min.js",
|
|
30
32
|
"jsdelivr": "dist/pushstream.min.js",
|
|
31
33
|
"exports": {
|
|
@@ -49,9 +51,10 @@
|
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
51
53
|
"@rollup/plugin-terser": "^0.4.4",
|
|
52
|
-
"rollup": "^4.9.0"
|
|
54
|
+
"rollup": "^4.9.0",
|
|
55
|
+
"typescript": "^5.9.3"
|
|
53
56
|
},
|
|
54
57
|
"engines": {
|
|
55
58
|
"node": ">=18.0.0"
|
|
56
59
|
}
|
|
57
|
-
}
|
|
60
|
+
}
|