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 +90 -0
- package/client/browser.js +13 -1
- package/client/connectSocket.js +523 -367
- package/client/transports/streaming.js +253 -0
- package/dist/ape.js +651 -301
- package/index.d.ts +9 -0
- package/package.json +26 -10
- package/server/README.md +54 -9
- package/server/lib/longPolling.js +221 -0
- package/server/lib/main.js +17 -0
- package/server/security/origin.js +16 -4
- package/server/utils/deepRequire.js +25 -10
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
|
+
})
|