@supabase/realtime-js 2.12.2 → 2.14.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/dist/main/RealtimeChannel.d.ts.map +1 -1
- package/dist/main/RealtimeChannel.js +10 -1
- package/dist/main/RealtimeChannel.js.map +1 -1
- package/dist/main/RealtimeClient.d.ts +13 -2
- package/dist/main/RealtimeClient.d.ts.map +1 -1
- package/dist/main/RealtimeClient.js +311 -115
- package/dist/main/RealtimeClient.js.map +1 -1
- package/dist/main/index.d.ts +2 -1
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +3 -1
- package/dist/main/index.js.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/main/lib/websocket-factory.d.ts +41 -0
- package/dist/main/lib/websocket-factory.d.ts.map +1 -0
- package/dist/main/lib/websocket-factory.js +132 -0
- package/dist/main/lib/websocket-factory.js.map +1 -0
- package/dist/module/RealtimeChannel.d.ts.map +1 -1
- package/dist/module/RealtimeChannel.js +10 -1
- package/dist/module/RealtimeChannel.js.map +1 -1
- package/dist/module/RealtimeClient.d.ts +13 -2
- package/dist/module/RealtimeClient.d.ts.map +1 -1
- package/dist/module/RealtimeClient.js +312 -115
- package/dist/module/RealtimeClient.js.map +1 -1
- package/dist/module/index.d.ts +2 -1
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/index.js +2 -1
- package/dist/module/index.js.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.js +1 -1
- package/dist/module/lib/websocket-factory.d.ts +41 -0
- package/dist/module/lib/websocket-factory.d.ts.map +1 -0
- package/dist/module/lib/websocket-factory.js +128 -0
- package/dist/module/lib/websocket-factory.js.map +1 -0
- package/package.json +3 -4
- package/src/RealtimeChannel.ts +12 -1
- package/src/RealtimeClient.ts +358 -132
- package/src/index.ts +3 -0
- package/src/lib/version.ts +1 -1
- package/src/lib/websocket-factory.ts +189 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
export interface WebSocketLike {
|
|
2
|
+
readonly CONNECTING: number
|
|
3
|
+
readonly OPEN: number
|
|
4
|
+
readonly CLOSING: number
|
|
5
|
+
readonly CLOSED: number
|
|
6
|
+
readonly readyState: number
|
|
7
|
+
readonly url: string
|
|
8
|
+
readonly protocol: string
|
|
9
|
+
|
|
10
|
+
close(code?: number, reason?: string): void
|
|
11
|
+
send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void
|
|
12
|
+
|
|
13
|
+
onopen: ((this: any, ev: Event) => any) | null
|
|
14
|
+
onmessage: ((this: any, ev: MessageEvent) => any) | null
|
|
15
|
+
onclose: ((this: any, ev: CloseEvent) => any) | null
|
|
16
|
+
onerror: ((this: any, ev: Event) => any) | null
|
|
17
|
+
|
|
18
|
+
addEventListener(type: string, listener: EventListener): void
|
|
19
|
+
removeEventListener(type: string, listener: EventListener): void
|
|
20
|
+
|
|
21
|
+
// Add additional properties that may exist on WebSocket implementations
|
|
22
|
+
binaryType?: string
|
|
23
|
+
bufferedAmount?: number
|
|
24
|
+
extensions?: string
|
|
25
|
+
dispatchEvent?: (event: Event) => boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface WebSocketEnvironment {
|
|
29
|
+
type: 'native' | 'ws' | 'cloudflare' | 'unsupported'
|
|
30
|
+
constructor?: any
|
|
31
|
+
error?: string
|
|
32
|
+
workaround?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class WebSocketFactory {
|
|
36
|
+
/**
|
|
37
|
+
* Dynamic require that works in both CJS and ESM environments
|
|
38
|
+
* Bulletproof against strict ESM environments where require might not be in scope
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
private static dynamicRequire(moduleId: string): any {
|
|
42
|
+
try {
|
|
43
|
+
// Check if we're in a Node.js environment first
|
|
44
|
+
if (
|
|
45
|
+
typeof process !== 'undefined' &&
|
|
46
|
+
process.versions &&
|
|
47
|
+
process.versions.node
|
|
48
|
+
) {
|
|
49
|
+
// In Node.js, both CJS and ESM support require for dynamic imports
|
|
50
|
+
// Wrap in try/catch to handle strict ESM environments
|
|
51
|
+
if (typeof require !== 'undefined') {
|
|
52
|
+
return require(moduleId)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null
|
|
56
|
+
} catch {
|
|
57
|
+
// Catches any error from typeof require OR require() call in strict ESM
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private static detectEnvironment(): WebSocketEnvironment {
|
|
63
|
+
if (typeof WebSocket !== 'undefined') {
|
|
64
|
+
return { type: 'native', constructor: WebSocket }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (
|
|
68
|
+
typeof globalThis !== 'undefined' &&
|
|
69
|
+
typeof (globalThis as any).WebSocket !== 'undefined'
|
|
70
|
+
) {
|
|
71
|
+
return { type: 'native', constructor: (globalThis as any).WebSocket }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (
|
|
75
|
+
typeof global !== 'undefined' &&
|
|
76
|
+
typeof (global as any).WebSocket !== 'undefined'
|
|
77
|
+
) {
|
|
78
|
+
return { type: 'native', constructor: (global as any).WebSocket }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
typeof globalThis !== 'undefined' &&
|
|
83
|
+
typeof (globalThis as any).WebSocketPair !== 'undefined' &&
|
|
84
|
+
typeof globalThis.WebSocket === 'undefined'
|
|
85
|
+
) {
|
|
86
|
+
return {
|
|
87
|
+
type: 'cloudflare',
|
|
88
|
+
error:
|
|
89
|
+
'Cloudflare Workers detected. WebSocket clients are not supported in Cloudflare Workers.',
|
|
90
|
+
workaround:
|
|
91
|
+
'Use Cloudflare Workers WebSocket API for server-side WebSocket handling, or deploy to a different runtime.',
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
(typeof globalThis !== 'undefined' && (globalThis as any).EdgeRuntime) ||
|
|
97
|
+
(typeof navigator !== 'undefined' &&
|
|
98
|
+
navigator.userAgent?.includes('Vercel-Edge'))
|
|
99
|
+
) {
|
|
100
|
+
return {
|
|
101
|
+
type: 'unsupported',
|
|
102
|
+
error:
|
|
103
|
+
'Edge runtime detected (Vercel Edge/Netlify Edge). WebSockets are not supported in edge functions.',
|
|
104
|
+
workaround:
|
|
105
|
+
'Use serverless functions or a different deployment target for WebSocket functionality.',
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
typeof process !== 'undefined' &&
|
|
111
|
+
process.versions &&
|
|
112
|
+
process.versions.node
|
|
113
|
+
) {
|
|
114
|
+
const nodeVersion = parseInt(process.versions.node.split('.')[0])
|
|
115
|
+
if (nodeVersion >= 22) {
|
|
116
|
+
try {
|
|
117
|
+
if (typeof globalThis.WebSocket !== 'undefined') {
|
|
118
|
+
return { type: 'native', constructor: globalThis.WebSocket }
|
|
119
|
+
}
|
|
120
|
+
const undici = this.dynamicRequire('undici')
|
|
121
|
+
if (undici && undici.WebSocket) {
|
|
122
|
+
return { type: 'native', constructor: undici.WebSocket }
|
|
123
|
+
}
|
|
124
|
+
throw new Error('undici not available')
|
|
125
|
+
} catch (err) {
|
|
126
|
+
return {
|
|
127
|
+
type: 'unsupported',
|
|
128
|
+
error: `Node.js ${nodeVersion} detected but native WebSocket not found.`,
|
|
129
|
+
workaround:
|
|
130
|
+
'Install the "ws" package or check your Node.js installation.',
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
// Use dynamic require to work in both CJS and ESM environments
|
|
136
|
+
const ws = this.dynamicRequire('ws')
|
|
137
|
+
if (ws) {
|
|
138
|
+
return { type: 'ws', constructor: ws.WebSocket ?? ws }
|
|
139
|
+
}
|
|
140
|
+
throw new Error('ws package not available')
|
|
141
|
+
} catch (err) {
|
|
142
|
+
return {
|
|
143
|
+
type: 'unsupported',
|
|
144
|
+
error: `Node.js ${nodeVersion} detected without WebSocket support.`,
|
|
145
|
+
workaround: 'Install the "ws" package: npm install ws',
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
type: 'unsupported',
|
|
152
|
+
error: 'Unknown JavaScript runtime without WebSocket support.',
|
|
153
|
+
workaround:
|
|
154
|
+
"Ensure you're running in a supported environment (browser, Node.js, Deno) or provide a custom WebSocket implementation.",
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public static getWebSocketConstructor(): typeof WebSocket {
|
|
159
|
+
const env = this.detectEnvironment()
|
|
160
|
+
if (env.constructor) {
|
|
161
|
+
return env.constructor
|
|
162
|
+
}
|
|
163
|
+
let errorMessage =
|
|
164
|
+
env.error || 'WebSocket not supported in this environment.'
|
|
165
|
+
if (env.workaround) {
|
|
166
|
+
errorMessage += `\n\nSuggested solution: ${env.workaround}`
|
|
167
|
+
}
|
|
168
|
+
throw new Error(errorMessage)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public static createWebSocket(
|
|
172
|
+
url: string | URL,
|
|
173
|
+
protocols?: string | string[]
|
|
174
|
+
): WebSocketLike {
|
|
175
|
+
const WS = this.getWebSocketConstructor()
|
|
176
|
+
return new WS(url, protocols)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public static isWebSocketSupported(): boolean {
|
|
180
|
+
try {
|
|
181
|
+
const env = this.detectEnvironment()
|
|
182
|
+
return env.type === 'native' || env.type === 'ws'
|
|
183
|
+
} catch {
|
|
184
|
+
return false
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export default WebSocketFactory
|