api-ape 3.0.2 → 4.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 +59 -572
- package/client/README.md +73 -14
- package/client/auth/crypto/aead.js +214 -0
- package/client/auth/crypto/constants.js +32 -0
- package/client/auth/crypto/encoding.js +104 -0
- package/client/auth/crypto/files.md +27 -0
- package/client/auth/crypto/kdf.js +217 -0
- package/client/auth/crypto-utils.js +118 -0
- package/client/auth/files.md +52 -0
- package/client/auth/key-recovery.js +288 -0
- package/client/auth/recovery/constants.js +37 -0
- package/client/auth/recovery/files.md +23 -0
- package/client/auth/recovery/key-derivation.js +61 -0
- package/client/auth/recovery/sss-browser.js +189 -0
- package/client/auth/share-storage.js +205 -0
- package/client/auth/storage/constants.js +18 -0
- package/client/auth/storage/db.js +132 -0
- package/client/auth/storage/files.md +27 -0
- package/client/auth/storage/keys.js +173 -0
- package/client/auth/storage/shares.js +200 -0
- package/client/browser.js +190 -23
- package/client/connectSocket.js +418 -988
- package/client/connection/README.md +23 -0
- package/client/connection/fileDownload.js +256 -0
- package/client/connection/fileHandling.js +450 -0
- package/client/connection/fileUtils.js +346 -0
- package/client/connection/files.md +71 -0
- package/client/connection/messageHandler.js +105 -0
- package/client/connection/network.js +350 -0
- package/client/connection/proxy.js +233 -0
- package/client/connection/sender.js +333 -0
- package/client/connection/state.js +321 -0
- package/client/connection/subscriptions.js +151 -0
- package/client/files.md +53 -0
- package/client/index.js +298 -142
- package/client/transports/README.md +50 -0
- package/client/transports/files.md +41 -0
- package/client/transports/streamParser.js +195 -0
- package/client/transports/streaming.js +555 -203
- package/dist/ape.js +6 -1
- package/dist/ape.js.map +4 -4
- package/index.d.ts +38 -16
- package/package.json +31 -6
- package/server/README.md +272 -67
- package/server/adapters/README.md +23 -14
- package/server/adapters/files.md +68 -0
- package/server/adapters/firebase.js +543 -160
- package/server/adapters/index.js +362 -112
- package/server/adapters/mongo.js +530 -140
- package/server/adapters/postgres.js +534 -155
- package/server/adapters/redis.js +508 -143
- package/server/adapters/supabase.js +555 -186
- package/server/client/README.md +43 -0
- package/server/client/connection.js +586 -0
- package/server/client/files.md +40 -0
- package/server/client/index.js +342 -0
- package/server/files.md +54 -0
- package/server/index.js +322 -71
- package/server/lib/README.md +26 -0
- package/server/lib/broadcast/clients.js +219 -0
- package/server/lib/broadcast/files.md +58 -0
- package/server/lib/broadcast/index.js +57 -0
- package/server/lib/broadcast/publishProxy.js +110 -0
- package/server/lib/broadcast/pubsub.js +137 -0
- package/server/lib/broadcast/sendProxy.js +103 -0
- package/server/lib/bun.js +315 -99
- package/server/lib/fileTransfer/README.md +63 -0
- package/server/lib/fileTransfer/files.md +30 -0
- package/server/lib/fileTransfer/streaming.js +435 -0
- package/server/lib/fileTransfer.js +710 -326
- package/server/lib/files.md +111 -0
- package/server/lib/httpUtils.js +283 -0
- package/server/lib/loader.js +208 -7
- package/server/lib/longPolling/README.md +63 -0
- package/server/lib/longPolling/files.md +44 -0
- package/server/lib/longPolling/getHandler.js +365 -0
- package/server/lib/longPolling/postHandler.js +327 -0
- package/server/lib/longPolling.js +174 -219
- package/server/lib/main.js +369 -532
- package/server/lib/runtimes/README.md +42 -0
- package/server/lib/runtimes/bun.js +586 -0
- package/server/lib/runtimes/files.md +56 -0
- package/server/lib/runtimes/node.js +511 -0
- package/server/lib/wiring.js +539 -98
- package/server/lib/ws/README.md +35 -0
- package/server/lib/ws/adapters/README.md +54 -0
- package/server/lib/ws/adapters/bun.js +538 -170
- package/server/lib/ws/adapters/deno.js +623 -149
- package/server/lib/ws/adapters/files.md +42 -0
- package/server/lib/ws/files.md +74 -0
- package/server/lib/ws/frames.js +532 -154
- package/server/lib/ws/index.js +207 -10
- package/server/lib/ws/server.js +385 -92
- package/server/lib/ws/socket.js +549 -181
- package/server/lib/wsProvider.js +363 -89
- package/server/plugins/binary.js +282 -0
- package/server/security/README.md +92 -0
- package/server/security/auth/README.md +319 -0
- package/server/security/auth/adapters/files.md +95 -0
- package/server/security/auth/adapters/ldap/constants.js +37 -0
- package/server/security/auth/adapters/ldap/files.md +19 -0
- package/server/security/auth/adapters/ldap/helpers.js +111 -0
- package/server/security/auth/adapters/ldap.js +353 -0
- package/server/security/auth/adapters/oauth2/constants.js +41 -0
- package/server/security/auth/adapters/oauth2/files.md +19 -0
- package/server/security/auth/adapters/oauth2/helpers.js +123 -0
- package/server/security/auth/adapters/oauth2.js +273 -0
- package/server/security/auth/adapters/opaque-handlers.js +314 -0
- package/server/security/auth/adapters/opaque.js +205 -0
- package/server/security/auth/adapters/saml/constants.js +52 -0
- package/server/security/auth/adapters/saml/files.md +19 -0
- package/server/security/auth/adapters/saml/helpers.js +74 -0
- package/server/security/auth/adapters/saml.js +173 -0
- package/server/security/auth/adapters/totp.js +703 -0
- package/server/security/auth/adapters/webauthn.js +625 -0
- package/server/security/auth/files.md +61 -0
- package/server/security/auth/framework/constants.js +27 -0
- package/server/security/auth/framework/files.md +23 -0
- package/server/security/auth/framework/handlers.js +272 -0
- package/server/security/auth/framework/socket-auth.js +177 -0
- package/server/security/auth/handlers/auth-messages.js +143 -0
- package/server/security/auth/handlers/files.md +28 -0
- package/server/security/auth/index.js +290 -0
- package/server/security/auth/mfa/crypto/aead.js +148 -0
- package/server/security/auth/mfa/crypto/constants.js +35 -0
- package/server/security/auth/mfa/crypto/files.md +27 -0
- package/server/security/auth/mfa/crypto/kdf.js +120 -0
- package/server/security/auth/mfa/crypto/utils.js +68 -0
- package/server/security/auth/mfa/crypto-utils.js +80 -0
- package/server/security/auth/mfa/files.md +77 -0
- package/server/security/auth/mfa/ledger/constants.js +75 -0
- package/server/security/auth/mfa/ledger/errors.js +73 -0
- package/server/security/auth/mfa/ledger/files.md +23 -0
- package/server/security/auth/mfa/ledger/share-record.js +32 -0
- package/server/security/auth/mfa/ledger.js +255 -0
- package/server/security/auth/mfa/recovery/constants.js +67 -0
- package/server/security/auth/mfa/recovery/files.md +19 -0
- package/server/security/auth/mfa/recovery/handlers.js +216 -0
- package/server/security/auth/mfa/recovery.js +191 -0
- package/server/security/auth/mfa/sss/constants.js +21 -0
- package/server/security/auth/mfa/sss/files.md +23 -0
- package/server/security/auth/mfa/sss/gf256.js +103 -0
- package/server/security/auth/mfa/sss/serialization.js +82 -0
- package/server/security/auth/mfa/sss.js +161 -0
- package/server/security/auth/mfa/two-of-three/constants.js +58 -0
- package/server/security/auth/mfa/two-of-three/files.md +23 -0
- package/server/security/auth/mfa/two-of-three/handlers.js +241 -0
- package/server/security/auth/mfa/two-of-three/helpers.js +71 -0
- package/server/security/auth/mfa/two-of-three.js +136 -0
- package/server/security/auth/nonce-manager.js +89 -0
- package/server/security/auth/state-machine-mfa.js +269 -0
- package/server/security/auth/state-machine.js +257 -0
- package/server/security/extractRootDomain.js +144 -16
- package/server/security/files.md +51 -0
- package/server/security/origin.js +197 -15
- package/server/security/reply.js +274 -16
- package/server/socket/README.md +119 -0
- package/server/socket/authMiddleware.js +299 -0
- package/server/socket/files.md +86 -0
- package/server/socket/open.js +154 -8
- package/server/socket/pluginHooks.js +334 -0
- package/server/socket/receive.js +184 -224
- package/server/socket/receiveContext.js +117 -0
- package/server/socket/send.js +416 -78
- package/server/socket/tagUtils.js +402 -0
- package/server/utils/README.md +19 -0
- package/server/utils/deepRequire.js +255 -30
- package/server/utils/files.md +57 -0
- package/server/utils/genId.js +182 -20
- package/server/utils/parseUserAgent.js +313 -251
- package/server/utils/userAgent/README.md +65 -0
- package/server/utils/userAgent/files.md +46 -0
- package/server/utils/userAgent/patterns.js +545 -0
- package/utils/README.md +21 -0
- package/utils/files.md +66 -0
- package/utils/jss/README.md +21 -0
- package/utils/jss/decode.js +471 -0
- package/utils/jss/encode.js +312 -0
- package/utils/jss/files.md +68 -0
- package/utils/jss/plugins.js +210 -0
- package/utils/jss.js +219 -273
- package/utils/messageHash.js +238 -35
- package/dist/api-ape.min.js +0 -2
- package/dist/api-ape.min.js.map +0 -7
- package/server/client.js +0 -311
- package/server/lib/broadcast.js +0 -146
package/server/lib/wsProvider.js
CHANGED
|
@@ -1,135 +1,409 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebSocket Provider
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
2
|
+
* @fileoverview WebSocket Provider - Runtime-Aware WebSocket Implementation
|
|
3
|
+
*
|
|
4
|
+
* This module provides automatic detection of the JavaScript runtime environment
|
|
5
|
+
* and returns the most appropriate WebSocket implementation. It abstracts away
|
|
6
|
+
* the differences between Deno, Bun, Node.js, and provides a fallback polyfill.
|
|
7
|
+
*
|
|
8
|
+
* Provider Selection Priority:
|
|
9
|
+
* 1. **Deno Native**: Uses `Deno.upgradeWebSocket()` for optimal performance
|
|
10
|
+
* 2. **Bun Native**: Uses Bun's built-in WebSocket server
|
|
11
|
+
* 3. **Node.js 24+ Native**: Uses the stable `node:ws` module (when available)
|
|
12
|
+
* 4. **Polyfill**: Uses our RFC 6455 compliant implementation
|
|
13
|
+
*
|
|
14
|
+
* The provider is cached after first detection to ensure consistent behavior
|
|
15
|
+
* throughout the application lifecycle.
|
|
16
|
+
*
|
|
17
|
+
* @module server/lib/wsProvider
|
|
18
|
+
* @see {@link module:server/lib/ws} - WebSocket polyfill implementation
|
|
19
|
+
* @see {@link module:server/lib/ws/adapters/bun} - Bun adapter
|
|
20
|
+
* @see {@link module:server/lib/ws/adapters/deno} - Deno adapter
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Get the appropriate WebSocket provider for the current runtime
|
|
24
|
+
* const { getWebSocketProvider } = require('./wsProvider')
|
|
25
|
+
*
|
|
26
|
+
* const { type, WebSocketServer, runtime } = getWebSocketProvider()
|
|
27
|
+
* console.log(`Using ${type} WebSocket on ${runtime}`)
|
|
28
|
+
*
|
|
29
|
+
* // Create a WebSocket server
|
|
30
|
+
* const wss = new WebSocketServer({ noServer: true })
|
|
31
|
+
* wss.on('connection', (ws) => {
|
|
32
|
+
* console.log('Client connected')
|
|
33
|
+
* })
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Check runtime environment
|
|
37
|
+
* const { getRuntime, isDeno, isBun } = require('./wsProvider')
|
|
38
|
+
*
|
|
39
|
+
* console.log('Runtime:', getRuntime())
|
|
40
|
+
* console.log('Is Deno:', isDeno())
|
|
41
|
+
* console.log('Is Bun:', isBun())
|
|
10
42
|
*/
|
|
11
43
|
|
|
12
44
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
45
|
+
* @typedef {Object} WebSocketProvider
|
|
46
|
+
* Result from getWebSocketProvider() with runtime-appropriate WebSocket implementation.
|
|
47
|
+
*
|
|
48
|
+
* @property {string} type - The provider type identifier:
|
|
49
|
+
* - 'deno-native': Deno's built-in WebSocket
|
|
50
|
+
* - 'bun-native': Bun's built-in WebSocket
|
|
51
|
+
* - 'node-native': Node.js 24+ stable native WebSocket
|
|
52
|
+
* - 'polyfill': Our RFC 6455 compliant implementation
|
|
53
|
+
* @property {typeof import('./ws').WebSocketServer} WebSocketServer - WebSocket server constructor
|
|
54
|
+
* @property {string} runtime - The detected runtime ('deno', 'bun', 'node', 'unknown')
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {'deno'|'bun'|'node'|'unknown'} RuntimeType
|
|
59
|
+
* The detected JavaScript runtime environment.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Runtime override for testing. Set to mock runtime detection.
|
|
64
|
+
* @private
|
|
65
|
+
* @type {{deno?: boolean, bun?: boolean, node24?: boolean}|null}
|
|
66
|
+
*/
|
|
67
|
+
let _runtimeOverride = null;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Set runtime override for testing purposes.
|
|
71
|
+
* @param {{deno?: boolean, bun?: boolean, node24?: boolean}|null} override
|
|
72
|
+
*/
|
|
73
|
+
function _setRuntimeOverride(override) {
|
|
74
|
+
_runtimeOverride = override;
|
|
75
|
+
// Clear cached provider when runtime changes
|
|
76
|
+
cachedProvider = null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get current runtime override (for testing).
|
|
81
|
+
* @returns {{deno?: boolean, bun?: boolean, node24?: boolean}|null}
|
|
82
|
+
*/
|
|
83
|
+
function _getRuntimeOverride() {
|
|
84
|
+
return _runtimeOverride;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Checks if the code is running in the Deno runtime.
|
|
89
|
+
*
|
|
90
|
+
* Detection method: Checks for the global `Deno` object and its
|
|
91
|
+
* `upgradeWebSocket` function, which is Deno's WebSocket upgrade API.
|
|
92
|
+
*
|
|
93
|
+
* @function isDeno
|
|
94
|
+
* @returns {boolean} True if running in Deno
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* if (isDeno()) {
|
|
98
|
+
* console.log('Running in Deno')
|
|
99
|
+
* // Use Deno-specific APIs
|
|
100
|
+
* }
|
|
15
101
|
*/
|
|
16
102
|
function isDeno() {
|
|
17
|
-
|
|
103
|
+
// Check test override first
|
|
104
|
+
if (_runtimeOverride?.deno !== undefined) {
|
|
105
|
+
return _runtimeOverride.deno;
|
|
106
|
+
}
|
|
107
|
+
// Actual runtime detection
|
|
108
|
+
return (
|
|
109
|
+
typeof Deno !== "undefined" && typeof Deno.upgradeWebSocket === "function"
|
|
110
|
+
);
|
|
18
111
|
}
|
|
19
112
|
|
|
20
113
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
114
|
+
* Checks if the code is running in the Bun runtime.
|
|
115
|
+
*
|
|
116
|
+
* Detection method: Checks `process.versions.bun`, which is the officially
|
|
117
|
+
* recommended way to detect Bun according to Bun's documentation.
|
|
118
|
+
*
|
|
119
|
+
* Note: Bun also sets `process.versions.node`, so checking for Node.js
|
|
120
|
+
* detection should exclude Bun first.
|
|
121
|
+
*
|
|
122
|
+
* @function isBun
|
|
123
|
+
* @returns {boolean} True if running in Bun
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* if (isBun()) {
|
|
127
|
+
* console.log('Running in Bun version:', process.versions.bun)
|
|
128
|
+
* // Use Bun-specific APIs like Bun.serve()
|
|
129
|
+
* }
|
|
24
130
|
*/
|
|
25
131
|
function isBun() {
|
|
26
|
-
|
|
132
|
+
// Check test override first
|
|
133
|
+
if (_runtimeOverride?.bun !== undefined) {
|
|
134
|
+
return _runtimeOverride.bun;
|
|
135
|
+
}
|
|
136
|
+
// Actual runtime detection
|
|
137
|
+
return typeof process !== "undefined" && !!process.versions?.bun;
|
|
27
138
|
}
|
|
28
139
|
|
|
29
140
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
141
|
+
* Checks if running on Node.js version 24+ with stable WebSocket support.
|
|
142
|
+
*
|
|
143
|
+
* Node.js 24 introduced a stable, built-in WebSocket module (`node:ws`)
|
|
144
|
+
* that doesn't require external dependencies. This function checks:
|
|
145
|
+
*
|
|
146
|
+
* 1. That we're running in Node.js (not Bun, which also has `process.versions.node`)
|
|
147
|
+
* 2. That the major version is 24 or higher
|
|
148
|
+
* 3. That it's a stable release (not RC, alpha, or beta)
|
|
149
|
+
*
|
|
150
|
+
* Pre-release versions are identified by hyphens in the version string
|
|
151
|
+
* (e.g., "24.0.0-rc.1").
|
|
152
|
+
*
|
|
153
|
+
* @function isNode24Stable
|
|
154
|
+
* @returns {boolean} True if running on Node.js 24+ stable
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* if (isNode24Stable()) {
|
|
158
|
+
* // Can use native node:ws module
|
|
159
|
+
* const { WebSocketServer } = require('node:ws')
|
|
160
|
+
* } else {
|
|
161
|
+
* // Fall back to polyfill or external package
|
|
162
|
+
* }
|
|
32
163
|
*/
|
|
33
164
|
function isNode24Stable() {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
165
|
+
// Check test override first
|
|
166
|
+
if (_runtimeOverride?.node24 !== undefined) {
|
|
167
|
+
return _runtimeOverride.node24;
|
|
168
|
+
}
|
|
37
169
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
170
|
+
// Actual runtime detection
|
|
171
|
+
/* istanbul ignore next 6 - only reachable in browser/non-Node environments */
|
|
172
|
+
if (
|
|
173
|
+
typeof process === "undefined" ||
|
|
174
|
+
!process.versions ||
|
|
175
|
+
!process.versions.node
|
|
176
|
+
) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
42
179
|
|
|
43
|
-
|
|
44
|
-
|
|
180
|
+
// Skip if this is actually Bun (Bun also sets process.versions.node)
|
|
181
|
+
if (isBun()) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
45
184
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return false
|
|
49
|
-
}
|
|
185
|
+
const versionStr = process.versions.node;
|
|
186
|
+
const majorVersion = parseInt(versionStr.split(".")[0], 10);
|
|
50
187
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
188
|
+
// Must be Node 24+
|
|
189
|
+
if (majorVersion < 24) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
56
192
|
|
|
57
|
-
|
|
193
|
+
// Check if this is a stable release (not RC, alpha, beta)
|
|
194
|
+
// Pre-release versions contain hyphens like "24.0.0-rc.1"
|
|
195
|
+
/* istanbul ignore next 3 - only reachable on Node 24+ */
|
|
196
|
+
if (versionStr.includes("-")) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* istanbul ignore next - only reachable on Node 24+ */
|
|
201
|
+
return true;
|
|
58
202
|
}
|
|
59
203
|
|
|
60
204
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
205
|
+
* Gets the detected runtime type.
|
|
206
|
+
*
|
|
207
|
+
* Returns one of:
|
|
208
|
+
* - 'deno': Running in Deno runtime
|
|
209
|
+
* - 'bun': Running in Bun runtime
|
|
210
|
+
* - 'node': Running in Node.js (any version)
|
|
211
|
+
* - 'unknown': Unable to detect runtime
|
|
212
|
+
*
|
|
213
|
+
* @function getRuntime
|
|
214
|
+
* @returns {RuntimeType} The detected runtime identifier
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* const runtime = getRuntime()
|
|
218
|
+
* switch (runtime) {
|
|
219
|
+
* case 'deno':
|
|
220
|
+
* console.log('Deno detected')
|
|
221
|
+
* break
|
|
222
|
+
* case 'bun':
|
|
223
|
+
* console.log('Bun detected')
|
|
224
|
+
* break
|
|
225
|
+
* case 'node':
|
|
226
|
+
* console.log('Node.js version:', process.versions.node)
|
|
227
|
+
* break
|
|
228
|
+
* default:
|
|
229
|
+
* console.log('Unknown runtime')
|
|
230
|
+
* }
|
|
63
231
|
*/
|
|
64
232
|
function getRuntime() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
233
|
+
if (isDeno()) return "deno";
|
|
234
|
+
if (isBun()) return "bun";
|
|
235
|
+
if (typeof process !== "undefined" && process.versions?.node) return "node";
|
|
236
|
+
/* istanbul ignore next - only reachable in non-Node/Bun/Deno environments */
|
|
237
|
+
return "unknown";
|
|
69
238
|
}
|
|
70
239
|
|
|
71
240
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
241
|
+
* Gets the WebSocket provider based on runtime capabilities.
|
|
242
|
+
*
|
|
243
|
+
* This function detects the current runtime and returns the most appropriate
|
|
244
|
+
* WebSocket implementation:
|
|
245
|
+
*
|
|
246
|
+
* 1. **Deno**: Returns `DenoWebSocketServer` adapter
|
|
247
|
+
* 2. **Bun**: Returns `BunWebSocketServer` adapter
|
|
248
|
+
* 3. **Node.js 24+**: Attempts to load native `node:ws` module
|
|
249
|
+
* 4. **Fallback**: Returns our RFC 6455 compliant polyfill
|
|
250
|
+
*
|
|
251
|
+
* The returned `WebSocketServer` constructor is compatible with the `ws`
|
|
252
|
+
* library API, allowing seamless integration with existing code.
|
|
253
|
+
*
|
|
254
|
+
* @function getWebSocketProvider
|
|
255
|
+
* @returns {WebSocketProvider} Provider object with type, WebSocketServer, and runtime
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* const { type, WebSocketServer, runtime } = getWebSocketProvider()
|
|
259
|
+
*
|
|
260
|
+
* console.log(`Runtime: ${runtime}, Provider: ${type}`)
|
|
261
|
+
*
|
|
262
|
+
* // Create a WebSocket server with noServer mode
|
|
263
|
+
* const wss = new WebSocketServer({ noServer: true })
|
|
264
|
+
*
|
|
265
|
+
* // Handle HTTP upgrade requests
|
|
266
|
+
* server.on('upgrade', (req, socket, head) => {
|
|
267
|
+
* wss.handleUpgrade(req, socket, head, (ws) => {
|
|
268
|
+
* wss.emit('connection', ws, req)
|
|
269
|
+
* })
|
|
270
|
+
* })
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* // Conditional logic based on provider type
|
|
274
|
+
* const provider = getWebSocketProvider()
|
|
275
|
+
*
|
|
276
|
+
* if (provider.type === 'polyfill') {
|
|
277
|
+
* console.log('Using polyfill - consider upgrading to Node.js 24+')
|
|
278
|
+
* }
|
|
74
279
|
*/
|
|
75
280
|
function getWebSocketProvider() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
281
|
+
const runtime = getRuntime();
|
|
282
|
+
|
|
283
|
+
// 1. Check for Deno runtime
|
|
284
|
+
if (runtime === "deno") {
|
|
285
|
+
try {
|
|
286
|
+
const { DenoWebSocketServer } = require("./ws/adapters/deno");
|
|
287
|
+
return {
|
|
288
|
+
type: "deno-native",
|
|
289
|
+
WebSocketServer: DenoWebSocketServer,
|
|
290
|
+
runtime,
|
|
291
|
+
};
|
|
292
|
+
} catch {
|
|
293
|
+
// Adapter not available, fall through to polyfill
|
|
86
294
|
}
|
|
295
|
+
}
|
|
87
296
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
297
|
+
// 2. Check for Bun runtime
|
|
298
|
+
if (runtime === "bun") {
|
|
299
|
+
try {
|
|
300
|
+
const { BunWebSocketServer } = require("./ws/adapters/bun");
|
|
301
|
+
return {
|
|
302
|
+
type: "bun-native",
|
|
303
|
+
WebSocketServer: BunWebSocketServer,
|
|
304
|
+
runtime,
|
|
305
|
+
};
|
|
306
|
+
} catch {
|
|
307
|
+
// Adapter not available, fall through to polyfill
|
|
96
308
|
}
|
|
309
|
+
}
|
|
97
310
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
311
|
+
// 3. Try Node.js 24+ native WebSocketServer
|
|
312
|
+
/* istanbul ignore next 9 - only reachable on Node 24+ with native WebSocket */
|
|
313
|
+
if (isNode24Stable()) {
|
|
314
|
+
try {
|
|
315
|
+
const { WebSocketServer } = require("node:ws");
|
|
316
|
+
if (WebSocketServer) {
|
|
317
|
+
return { type: "node-native", WebSocketServer, runtime };
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
// node:ws not available, fall through to polyfill
|
|
108
321
|
}
|
|
322
|
+
}
|
|
109
323
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
324
|
+
// 4. Fall back to our RFC 6455 compliant polyfill
|
|
325
|
+
const { WebSocketServer } = require("./ws/index");
|
|
326
|
+
return { type: "polyfill", WebSocketServer, runtime };
|
|
113
327
|
}
|
|
114
328
|
|
|
115
|
-
|
|
116
|
-
|
|
329
|
+
/**
|
|
330
|
+
* Cached WebSocket provider instance.
|
|
331
|
+
* Populated on first call to getCachedProvider().
|
|
332
|
+
*
|
|
333
|
+
* @private
|
|
334
|
+
* @type {WebSocketProvider|null}
|
|
335
|
+
*/
|
|
336
|
+
let cachedProvider = null;
|
|
117
337
|
|
|
118
338
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
339
|
+
* Gets the cached WebSocket provider.
|
|
340
|
+
*
|
|
341
|
+
* This function caches the provider after first detection to ensure
|
|
342
|
+
* consistent behavior throughout the application lifecycle. The same
|
|
343
|
+
* provider is returned on subsequent calls.
|
|
344
|
+
*
|
|
345
|
+
* This is the primary export and should be used instead of calling
|
|
346
|
+
* getWebSocketProvider() directly unless you need to force re-detection.
|
|
347
|
+
*
|
|
348
|
+
* @function getCachedProvider
|
|
349
|
+
* @returns {WebSocketProvider} Cached provider object
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* // Multiple calls return the same provider instance
|
|
353
|
+
* const provider1 = getWebSocketProvider()
|
|
354
|
+
* const provider2 = getWebSocketProvider()
|
|
355
|
+
* console.log(provider1 === provider2) // true
|
|
121
356
|
*/
|
|
122
357
|
function getCachedProvider() {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
358
|
+
if (!cachedProvider) {
|
|
359
|
+
cachedProvider = getWebSocketProvider();
|
|
360
|
+
}
|
|
361
|
+
return cachedProvider;
|
|
127
362
|
}
|
|
128
363
|
|
|
129
364
|
module.exports = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
365
|
+
/**
|
|
366
|
+
* Get the cached WebSocket provider (recommended).
|
|
367
|
+
* Returns the same provider instance on subsequent calls.
|
|
368
|
+
* @function
|
|
369
|
+
*/
|
|
370
|
+
getWebSocketProvider: getCachedProvider,
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get the detected runtime type.
|
|
374
|
+
* @function
|
|
375
|
+
*/
|
|
376
|
+
getRuntime,
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Check if running in Deno.
|
|
380
|
+
* @function
|
|
381
|
+
*/
|
|
382
|
+
isDeno,
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Check if running in Bun.
|
|
386
|
+
* @function
|
|
387
|
+
*/
|
|
388
|
+
isBun,
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Check if running on Node.js 24+ stable.
|
|
392
|
+
* @function
|
|
393
|
+
*/
|
|
394
|
+
isNode24Stable,
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Set runtime override for testing purposes.
|
|
398
|
+
* @function
|
|
399
|
+
* @private
|
|
400
|
+
*/
|
|
401
|
+
_setRuntimeOverride,
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Get current runtime override (for testing).
|
|
405
|
+
* @function
|
|
406
|
+
* @private
|
|
407
|
+
*/
|
|
408
|
+
_getRuntimeOverride,
|
|
409
|
+
};
|