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 CHANGED
@@ -1,4 +1,4 @@
1
- # pushstream-js
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-js
21
+ npm install pushstream-client
21
22
  # or
22
- yarn add pushstream-js
23
+ yarn add pushstream-client
23
24
  # or
24
- pnpm add pushstream-js
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-js/dist/pushstream.min.js"></script>
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-js';
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-js';
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-js' {
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
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * PushStream JavaScript Client v0.1.0
2
+ * PushStream JavaScript Client v0.2.0
3
3
  * A lightweight, zero-dependency SSE client library
4
4
  * (c) 2026
5
5
  * Released under the MIT License
@@ -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
+ }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * PushStream JavaScript Client v0.1.0
2
+ * PushStream JavaScript Client v0.2.0
3
3
  * A lightweight, zero-dependency SSE client library
4
4
  * (c) 2026
5
5
  * Released under the MIT License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * PushStream JavaScript Client v0.1.0
2
+ * PushStream JavaScript Client v0.2.0
3
3
  * A lightweight, zero-dependency SSE client library
4
4
  * (c) 2026
5
5
  * Released under the MIT License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * PushStream JavaScript Client v0.1.0
2
+ * PushStream JavaScript Client v0.2.0
3
3
  * A lightweight, zero-dependency SSE client library
4
4
  * (c) 2026
5
5
  * Released under the MIT License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushstream-client",
3
- "version": "0.1.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
+ }