api-ape 2.0.0 → 2.1.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
@@ -89,6 +89,7 @@ Include the bundled client and start calling:
89
89
  * **Real-time broadcasts** — Built-in `broadcast()` and `broadcastOthers()` methods for pushing to clients
90
90
  * **Promise-based calls** — Chainable paths like `ape.users.list()` map to `api/users/list.js`
91
91
  * **Automatic reconnection** — Client auto-reconnects on disconnect with exponential backoff
92
+ * **HTTP streaming fallback** — Automatically falls back to long polling when WebSockets are blocked
92
93
  * **JJS Encoding** — Extended JSON supporting Date, RegExp, Error, Set, Map, undefined, and circular refs
93
94
  * **Connection lifecycle hooks** — Customize behavior on connect, receive, send, error, and disconnect
94
95
 
@@ -152,6 +153,53 @@ ape.on('notification', ({ data, err, type }) => {
152
153
  })
153
154
  ```
154
155
 
156
+ #### `ape.configure(options)`
157
+
158
+ Configure client connection options.
159
+
160
+ ```js
161
+ // Configure transport mode
162
+ ape.configure({ transport: 'auto' }) // Auto-detect (default)
163
+ ape.configure({ transport: 'websocket' }) // Force WebSocket only
164
+ ape.configure({ transport: 'polling' }) // Force HTTP streaming
165
+
166
+ // Configure connection details
167
+ ape.configure({
168
+ port: 9010,
169
+ host: 'example.com',
170
+ transport: 'auto'
171
+ })
172
+ ```
173
+
174
+ | Option | Type | Description |
175
+ |--------|------|-------------|
176
+ | `port` | `number` | Server port (default: auto-detect) |
177
+ | `host` | `string` | Server hostname (default: auto-detect) |
178
+ | `transport` | `string` | Transport mode: `'auto'`, `'websocket'`, or `'polling'` |
179
+
180
+ #### `ape.getTransport()`
181
+
182
+ Get the currently active transport type.
183
+
184
+ ```js
185
+ const transport = ape.getTransport()
186
+ console.log(transport) // 'websocket' | 'polling' | null
187
+ ```
188
+
189
+ #### `ape.onConnectionChange(handler)`
190
+
191
+ Listen for connection state changes.
192
+
193
+ ```js
194
+ const unsubscribe = ape.onConnectionChange((state) => {
195
+ console.log('Connection state:', state)
196
+ // 'disconnected' | 'connecting' | 'connected'
197
+ })
198
+
199
+ // Later: stop listening
200
+ unsubscribe()
201
+ ```
202
+
155
203
  ---
156
204
 
157
205
  ## Configuration
@@ -295,6 +343,48 @@ This is automatic — send a Date, receive a Date. No configuration needed.
295
343
 
296
344
  ---
297
345
 
346
+ ## HTTP Streaming Fallback
347
+
348
+ api-ape automatically falls back to HTTP streaming when WebSockets are unavailable or blocked by firewalls/proxies.
349
+
350
+ ### How It Works
351
+
352
+ 1. **WebSocket First**: Client attempts WebSocket connection (4 second timeout)
353
+ 2. **Auto-Fallback**: On failure, switches to HTTP streaming transport
354
+ 3. **Background Retry**: Keeps attempting WebSocket reconnection every 30 seconds
355
+ 4. **Auto-Upgrade**: Switches back to WebSocket when available
356
+
357
+ ### Streaming Transport
358
+
359
+ When in polling mode:
360
+ - **GET `/api/ape/poll`**: Long-lived connection, server streams JSON messages
361
+ - **POST `/api/ape/poll`**: Client sends messages
362
+ - Cookie-based session (`apeHostId`) for authentication
363
+ - Heartbeat every 20 seconds to prevent proxy timeout
364
+
365
+ ### Force Transport Mode
366
+
367
+ ```js
368
+ // Force HTTP streaming (useful for testing)
369
+ ape.configure({ transport: 'polling' })
370
+
371
+ // Force WebSocket only (fail if unavailable)
372
+ ape.configure({ transport: 'websocket' })
373
+
374
+ // Auto-detect (default)
375
+ ape.configure({ transport: 'auto' })
376
+ ```
377
+
378
+ ### Check Active Transport
379
+
380
+ ```js
381
+ if (ape.getTransport() === 'polling') {
382
+ console.log('Using HTTP streaming fallback')
383
+ }
384
+ ```
385
+
386
+ ---
387
+
298
388
  ## Examples & Demos
299
389
 
300
390
  The repository contains working examples:
package/client/browser.js CHANGED
@@ -4,7 +4,7 @@ import connectSocket from './connectSocket.js'
4
4
  const port = window.location.port || (window.location.protocol === 'https:' ? 443 : 80)
5
5
  connectSocket.configure({ port: parseInt(port, 10) })
6
6
 
7
- const { sender, setOnReciver, onConnectionChange } = connectSocket()
7
+ const { sender, setOnReciver, onConnectionChange, getTransport } = connectSocket()
8
8
  connectSocket.autoReconnect()
9
9
 
10
10
  // Global API - use defineProperty to bypass Proxy interception
@@ -21,3 +21,15 @@ Object.defineProperty(window.ape, 'onConnectionChange', {
21
21
  enumerable: false,
22
22
  configurable: false
23
23
  })
24
+ Object.defineProperty(window.ape, 'configure', {
25
+ value: connectSocket.configure,
26
+ writable: false,
27
+ enumerable: false,
28
+ configurable: false
29
+ })
30
+ Object.defineProperty(window.ape, 'getTransport', {
31
+ value: getTransport,
32
+ writable: false,
33
+ enumerable: false,
34
+ configurable: false
35
+ })