sockress-client 0.1.5 → 0.1.6

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.
Files changed (2) hide show
  1. package/README.md +359 -61
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,61 +1,359 @@
1
- # Sockress Client SDK
2
-
3
- sockress-client is the companion SDK for Sockress-powered backends. It automatically prefers a WebSocket transport (sharing the same request/response semantics as HTTP) and silently falls back to etch when a socket is unavailable. Multipart uploads (FormData) are serialized over the wire, so you can use a single API surface for avatars, profile forms, and realtime commands.
4
-
5
- Created by **Also Coder** · [alsocoder.com](https://alsocoder.com) · [github.com/alsocoders](https://github.com/alsocoders)
6
-
7
- ## Installation
8
-
9
- `ash
10
- npm install sockress-client
11
- `
12
-
13
- ## Usage
14
-
15
- ` s
16
- import { sockressClient } from 'sockress-client';
17
-
18
- const api = sockressClient({
19
- baseUrl: 'http://localhost:5051',
20
- autoConnect: true,
21
- preferSocket: true
22
- });
23
-
24
- const login = async () => {
25
- const response = await api.post('/api/auth/login', {
26
- body: { email: 'demo@sockress.dev', password: 'pass123' }
27
- });
28
-
29
- console.log('token', response.body.token);
30
- };
31
- `
32
-
33
- ### File Uploads
34
-
35
- ` s
36
- export async function uploadAvatar(file, token) {
37
- const formData = new FormData();
38
- formData.append('avatar', file);
39
-
40
- const response = await api.request({
41
- path: '/api/profile/avatar',
42
- method: 'POST',
43
- body: formData,
44
- headers: { Authorization: Bearer }
45
- });
46
-
47
- return response.body;
48
- }
49
- `
50
-
51
- ### Events
52
-
53
- ` s
54
- api.on('open', () => console.log('socket ready')); // when the WebSocket connects
55
- api.on('error', (err) => console.error(err));
56
- api.on('reconnect', ({ attempt }) => console.log('retry', attempt));
57
- `
58
-
59
- ---
60
-
61
- Questions or feedback? Ping [alsocoder.com](https://alsocoder.com) or [@alsocoders](https://github.com/alsocoders).
1
+ # Sockress Client SDK
2
+
3
+ [`sockress-client`](https://www.npmjs.com/package/sockress-client) is the companion SDK for Sockress-powered backends. It automatically prefers the WebSocket transport (sharing the same request/response semantics as HTTP) and silently falls back to `fetch` when a socket is unavailable. Multipart uploads (`FormData`) are serialized over the wire, so you can use a single API surface for avatars, profile forms, and realtime commands.
4
+
5
+ **Created by [Also Coder](https://alsocoder.com) · GitHub [@alsocoders](https://github.com/alsocoders)**
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - Socket-first requests with automatic HTTP fallback
12
+ - `FormData`, `Blob`, and JSON serialization handled automatically
13
+ - Familiar API: `api.request()`, `api.get()`, `api.post()`, `api.put()`, `api.patch()`, `api.delete()`
14
+ - Built-in event emitters for `open`, `close`, `error`, and `reconnect`
15
+ - Works in browsers and Node.js (inject custom `fetch` / `wsFactory`)
16
+ - Automatic cookie handling (browser only)
17
+ - Request queuing when socket is not yet connected
18
+ - Automatic reconnection with exponential backoff
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install sockress-client
26
+ ```
27
+
28
+ Sockress Client supports both ESM and CommonJS:
29
+
30
+ ```ts
31
+ // ESM
32
+ import { sockressClient } from 'sockress-client';
33
+
34
+ // CommonJS
35
+ const { sockressClient } = require('sockress-client');
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ```ts
43
+ import { sockressClient } from 'sockress-client';
44
+
45
+ const api = sockressClient({
46
+ baseUrl: 'http://localhost:5051',
47
+ autoConnect: true,
48
+ preferSocket: true
49
+ });
50
+
51
+ // GET request
52
+ const users = await api.get('/api/users');
53
+ console.log(users.body);
54
+
55
+ // POST request
56
+ const response = await api.post('/api/auth/login', {
57
+ body: { email: 'user@example.com', password: 'secret' }
58
+ });
59
+ console.log(response.body.token);
60
+ ```
61
+
62
+ ---
63
+
64
+ ## API Methods
65
+
66
+ ### `api.request(options)`
67
+
68
+ Make a request with full control:
69
+
70
+ ```ts
71
+ const response = await api.request({
72
+ path: '/api/users',
73
+ method: 'GET',
74
+ headers: { 'Authorization': 'Bearer token' },
75
+ query: { page: 1, limit: 10 },
76
+ body: { name: 'John' },
77
+ timeout: 5000,
78
+ signal: abortController.signal,
79
+ disableHttpFallback: false
80
+ });
81
+ ```
82
+
83
+ ### `api.get(path, options?)`
84
+
85
+ ```ts
86
+ const response = await api.get('/api/users', {
87
+ query: { page: 1 },
88
+ headers: { 'Authorization': 'Bearer token' }
89
+ });
90
+ ```
91
+
92
+ ### `api.post(path, options?)`
93
+
94
+ ```ts
95
+ const response = await api.post('/api/users', {
96
+ body: { name: 'John', email: 'john@example.com' }
97
+ });
98
+ ```
99
+
100
+ ### `api.put(path, options?)`
101
+
102
+ ```ts
103
+ const response = await api.put('/api/users/123', {
104
+ body: { name: 'Jane' }
105
+ });
106
+ ```
107
+
108
+ ### `api.patch(path, options?)`
109
+
110
+ ```ts
111
+ const response = await api.patch('/api/users/123', {
112
+ body: { email: 'jane@example.com' }
113
+ });
114
+ ```
115
+
116
+ ### `api.delete(path, options?)`
117
+
118
+ ```ts
119
+ const response = await api.delete('/api/users/123');
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Response Object
125
+
126
+ All methods return a `SockressClientResponse`:
127
+
128
+ ```ts
129
+ interface SockressClientResponse<T> {
130
+ status: number; // HTTP status code
131
+ ok: boolean; // true if status is 200-299
132
+ headers: Record<string, string>; // response headers
133
+ body: T; // parsed response body
134
+ json: <R = T>() => R; // get body as JSON (type-safe)
135
+ text: () => string; // get body as string
136
+ raw: () => T; // get raw body
137
+ }
138
+ ```
139
+
140
+ Example:
141
+
142
+ ```ts
143
+ const response = await api.get('/api/users');
144
+ console.log(response.status); // 200
145
+ console.log(response.ok); // true
146
+ console.log(response.body); // parsed JSON
147
+ console.log(response.json()); // same as body
148
+ console.log(response.text()); // JSON string
149
+ ```
150
+
151
+ ---
152
+
153
+ ## File Uploads
154
+
155
+ Upload files using `FormData`:
156
+
157
+ ```ts
158
+ const formData = new FormData();
159
+ formData.append('avatar', file);
160
+ formData.append('name', 'John Doe');
161
+
162
+ const response = await api.post('/api/profile/avatar', {
163
+ body: formData,
164
+ headers: { 'Authorization': 'Bearer token' }
165
+ });
166
+
167
+ console.log(response.body.avatarUrl);
168
+ ```
169
+
170
+ The client automatically serializes `FormData` for socket transport and uses native `FormData` for HTTP fallback.
171
+
172
+ ---
173
+
174
+ ## Events
175
+
176
+ Listen to socket events:
177
+
178
+ ```ts
179
+ // Socket opened
180
+ api.on('open', () => {
181
+ console.log('Socket connected');
182
+ });
183
+
184
+ // Socket closed
185
+ api.on('close', ({ code, reason }) => {
186
+ console.log('Socket closed', code, reason);
187
+ });
188
+
189
+ // Error occurred
190
+ api.on('error', (error) => {
191
+ console.error('Socket error:', error);
192
+ });
193
+
194
+ // Reconnection attempt
195
+ api.on('reconnect', ({ attempt }) => {
196
+ console.log('Reconnecting, attempt:', attempt);
197
+ });
198
+ ```
199
+
200
+ Remove listeners:
201
+
202
+ ```ts
203
+ const unsubscribe = api.on('open', () => {
204
+ console.log('Connected');
205
+ });
206
+
207
+ // Later
208
+ api.off('open', handler);
209
+ // or
210
+ unsubscribe();
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Configuration
216
+
217
+ Create a client with custom options:
218
+
219
+ ```ts
220
+ const api = sockressClient({
221
+ baseUrl: 'http://localhost:5051', // required
222
+ socketPath: '/sockress', // WebSocket path (default: '/sockress')
223
+ headers: { 'X-Custom': 'value' }, // default headers
224
+ timeout: 15_000, // request timeout in ms (default: 15000)
225
+ reconnectInterval: 1_000, // initial reconnect delay (default: 1000)
226
+ maxReconnectInterval: 15_000, // max reconnect delay (default: 15000)
227
+ autoConnect: true, // auto-connect on creation (default: true)
228
+ preferSocket: true, // prefer socket over HTTP (default: true)
229
+ credentials: 'include', // fetch credentials (default: 'include')
230
+ fetchImpl: fetch, // custom fetch implementation
231
+ wsFactory: (url) => new WebSocket(url) // custom WebSocket factory
232
+ });
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Node.js Usage
238
+
239
+ In Node.js, you may need to provide custom implementations:
240
+
241
+ ```ts
242
+ import fetch from 'node-fetch';
243
+ import WebSocket from 'ws';
244
+
245
+ const api = sockressClient({
246
+ baseUrl: 'https://api.example.com',
247
+ fetchImpl: fetch as any,
248
+ wsFactory: (url) => new WebSocket(url) as any
249
+ });
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Manual Connection Management
255
+
256
+ Control socket connection manually:
257
+
258
+ ```ts
259
+ const api = sockressClient({
260
+ baseUrl: 'http://localhost:5051',
261
+ autoConnect: false // don't auto-connect
262
+ });
263
+
264
+ // Connect manually
265
+ await api.connect();
266
+
267
+ // Close manually
268
+ api.close();
269
+ ```
270
+
271
+ The client automatically closes the socket on process exit (Node.js) or page unload (browser).
272
+
273
+ ---
274
+
275
+ ## Request Options
276
+
277
+ ### `path` (required)
278
+ Request path (e.g., `'/api/users'`)
279
+
280
+ ### `method` (optional)
281
+ HTTP method: `'GET'`, `'POST'`, `'PUT'`, `'PATCH'`, `'DELETE'`, `'HEAD'`, `'OPTIONS'` (default: `'GET'`)
282
+
283
+ ### `headers` (optional)
284
+ Request headers object
285
+
286
+ ### `query` (optional)
287
+ Query parameters object (values can be strings, numbers, booleans, or arrays)
288
+
289
+ ```ts
290
+ await api.get('/api/users', {
291
+ query: {
292
+ page: 1,
293
+ limit: 10,
294
+ tags: ['js', 'ts'],
295
+ active: true
296
+ }
297
+ });
298
+ ```
299
+
300
+ ### `body` (optional)
301
+ Request body. Can be:
302
+ - Plain object (serialized as JSON)
303
+ - `FormData` (for file uploads)
304
+ - `Blob` or `ArrayBuffer`
305
+ - `URLSearchParams`
306
+ - String
307
+
308
+ ### `timeout` (optional)
309
+ Request timeout in milliseconds (overrides default)
310
+
311
+ ### `signal` (optional)
312
+ `AbortSignal` for canceling requests
313
+
314
+ ### `disableHttpFallback` (optional)
315
+ If `true`, throws an error if socket is unavailable instead of falling back to HTTP (default: `false`)
316
+
317
+ ---
318
+
319
+ ## Error Handling
320
+
321
+ Handle errors with try/catch:
322
+
323
+ ```ts
324
+ try {
325
+ const response = await api.post('/api/users', {
326
+ body: { name: 'John' }
327
+ });
328
+ console.log(response.body);
329
+ } catch (error) {
330
+ console.error('Request failed:', error);
331
+ }
332
+ ```
333
+
334
+ ---
335
+
336
+ ## TypeScript Support
337
+
338
+ Sockress Client is written in TypeScript and provides full type safety:
339
+
340
+ ```ts
341
+ interface User {
342
+ id: number;
343
+ name: string;
344
+ email: string;
345
+ }
346
+
347
+ const response = await api.get<User[]>('/api/users');
348
+ const users: User[] = response.body;
349
+ ```
350
+
351
+ ---
352
+
353
+ ## Links
354
+
355
+ - Website: [https://alsocoder.com](https://alsocoder.com)
356
+ - GitHub: [https://github.com/alsocoders/sockress](https://github.com/alsocoders/sockress)
357
+ - Issues: [https://github.com/alsocoders/sockress/issues](https://github.com/alsocoders/sockress/issues)
358
+
359
+ PRs and feedback welcome!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sockress-client",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Socket-first client SDK for Sockress servers with automatic HTTP fallback and FormData serialization.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",