unplugin-https-reverse-proxy 3.0.0 → 4.0.1

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.
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/hmr-sse-bridge.ts
21
+ var hmr_sse_bridge_exports = {};
22
+ __export(hmr_sse_bridge_exports, {
23
+ hmrSseBridgeClientScript: () => hmrSseBridgeClientScript,
24
+ setupHmrSseBridge: () => setupHmrSseBridge
25
+ });
26
+ module.exports = __toCommonJS(hmr_sse_bridge_exports);
27
+ var SSE_PATH = "/__hmr_sse";
28
+ var SEND_PATH = "/__hmr_send";
29
+ var MAX_POST_BODY = 64 * 1024;
30
+ function setupHmrSseBridge(server) {
31
+ const sseClients = /* @__PURE__ */ new Set();
32
+ const originalSend = server.ws.send.bind(server.ws);
33
+ server.ws.send = (...args) => {
34
+ ;
35
+ originalSend(...args);
36
+ let payload;
37
+ if (typeof args[0] === "string") {
38
+ payload = JSON.stringify({ type: "custom", event: args[0], data: args[1] });
39
+ } else {
40
+ payload = JSON.stringify(args[0]);
41
+ }
42
+ for (const res of sseClients) {
43
+ try {
44
+ res.write(`data: ${payload}
45
+
46
+ `);
47
+ } catch {
48
+ sseClients.delete(res);
49
+ }
50
+ }
51
+ };
52
+ server.middlewares.use((req, res, next) => {
53
+ var _a;
54
+ const url = (_a = req.url) == null ? void 0 : _a.split("?")[0];
55
+ if (url === SSE_PATH && req.method === "GET") {
56
+ handleSseConnection(req, res, sseClients);
57
+ return;
58
+ }
59
+ if (url === SEND_PATH && req.method === "POST") {
60
+ handleClientMessage(req, res, server);
61
+ return;
62
+ }
63
+ next();
64
+ });
65
+ }
66
+ function handleSseConnection(_req, res, sseClients) {
67
+ res.writeHead(200, {
68
+ "Content-Type": "text/event-stream",
69
+ "Cache-Control": "no-cache",
70
+ "Connection": "keep-alive"
71
+ });
72
+ res.write(`data: ${JSON.stringify({ type: "connected" })}
73
+
74
+ `);
75
+ sseClients.add(res);
76
+ const keepAlive = setInterval(() => {
77
+ try {
78
+ res.write(": ping\n\n");
79
+ } catch {
80
+ cleanup();
81
+ }
82
+ }, 3e4);
83
+ function cleanup() {
84
+ clearInterval(keepAlive);
85
+ sseClients.delete(res);
86
+ }
87
+ res.on("close", cleanup);
88
+ res.on("error", cleanup);
89
+ }
90
+ function handleClientMessage(req, res, server) {
91
+ let body = "";
92
+ let overflow = false;
93
+ req.on("data", (chunk) => {
94
+ body += chunk.toString();
95
+ if (body.length > MAX_POST_BODY) {
96
+ overflow = true;
97
+ req.destroy();
98
+ }
99
+ });
100
+ req.on("end", () => {
101
+ var _a, _b, _c, _d, _e;
102
+ if (overflow) {
103
+ res.writeHead(413);
104
+ res.end('{"ok":false}');
105
+ return;
106
+ }
107
+ try {
108
+ const data = JSON.parse(body);
109
+ if (data.type === "custom" && data.event) {
110
+ const dummyClient = {
111
+ send: (...args) => {
112
+ server.ws.send(...args);
113
+ }
114
+ };
115
+ (_e = (_d = (_c = (_b = (_a = server.environments) == null ? void 0 : _a.client) == null ? void 0 : _b.hot) == null ? void 0 : _c.api) == null ? void 0 : _d.emit) == null ? void 0 : _e.call(_d, data.event, data.data, dummyClient);
116
+ }
117
+ res.writeHead(200, {
118
+ "Content-Type": "application/json"
119
+ });
120
+ res.end('{"ok":true}');
121
+ } catch {
122
+ res.writeHead(400);
123
+ res.end('{"ok":false}');
124
+ }
125
+ });
126
+ }
127
+ var hmrSseBridgeClientScript = `
128
+ (function() {
129
+ // Activate when served over HTTPS to bypass WSS self-signed cert issues
130
+ if (location.protocol !== 'https:') return;
131
+
132
+ var OriginalWebSocket = window.WebSocket;
133
+
134
+ function SseWebSocket(originalUrl) {
135
+ var self = this;
136
+ // WebSocket readyState constants on instance
137
+ self.CONNECTING = 0;
138
+ self.OPEN = 1;
139
+ self.CLOSING = 2;
140
+ self.CLOSED = 3;
141
+ self.readyState = 0;
142
+ self.onopen = null;
143
+ self.onmessage = null;
144
+ self.onclose = null;
145
+ self.onerror = null;
146
+ self.bufferedAmount = 0;
147
+ self.extensions = '';
148
+ self.binaryType = 'blob';
149
+ self.protocol = 'vite-hmr';
150
+ self.url = originalUrl;
151
+ self._listeners = {};
152
+ self._opened = false;
153
+
154
+ var sseUrl = location.origin + '${SSE_PATH}';
155
+ var sendUrl = location.origin + '${SEND_PATH}';
156
+ self._sendUrl = sendUrl;
157
+
158
+ var es = new EventSource(sseUrl);
159
+ self._es = es;
160
+
161
+ es.onopen = function() {
162
+ if (self._opened) return;
163
+ self._opened = true;
164
+ self.readyState = 1;
165
+ var evt = new Event('open');
166
+ if (self.onopen) self.onopen(evt);
167
+ self._emit('open', evt);
168
+ };
169
+
170
+ es.onmessage = function(e) {
171
+ var evt = new MessageEvent('message', { data: e.data });
172
+ if (self.onmessage) self.onmessage(evt);
173
+ self._emit('message', evt);
174
+ };
175
+
176
+ es.onerror = function() {
177
+ // EventSource auto-reconnects on error; don't treat as fatal close
178
+ // Only emit error event, never close event (SSE handles reconnect internally)
179
+ if (self.readyState >= 2) return;
180
+ // EventSource auto-reconnects; no action needed
181
+ };
182
+ }
183
+
184
+ SseWebSocket.prototype.send = function(data) {
185
+ if (this.readyState !== 1) return;
186
+ fetch(this._sendUrl, {
187
+ method: 'POST',
188
+ headers: { 'Content-Type': 'application/json' },
189
+ body: data
190
+ }).catch(function() {});
191
+ };
192
+
193
+ SseWebSocket.prototype.close = function() {
194
+ if (this.readyState >= 2) return;
195
+ this.readyState = 3;
196
+ if (this._es) this._es.close();
197
+ var evt = new CloseEvent('close', { code: 1000, reason: '', wasClean: true });
198
+ if (this.onclose) this.onclose(evt);
199
+ this._emit('close', evt);
200
+ };
201
+
202
+ SseWebSocket.prototype.addEventListener = function(type, fn, options) {
203
+ if (!this._listeners[type]) this._listeners[type] = [];
204
+ var entry = { fn: fn, once: !!(options && options.once) };
205
+ this._listeners[type].push(entry);
206
+ };
207
+
208
+ SseWebSocket.prototype.removeEventListener = function(type, fn) {
209
+ var list = this._listeners[type];
210
+ if (!list) return;
211
+ this._listeners[type] = list.filter(function(e) { return e.fn !== fn; });
212
+ };
213
+
214
+ SseWebSocket.prototype.dispatchEvent = function(evt) {
215
+ this._emit(evt.type, evt);
216
+ return true;
217
+ };
218
+
219
+ SseWebSocket.prototype._emit = function(type, evt) {
220
+ var list = this._listeners[type];
221
+ if (!list) return;
222
+ var remaining = [];
223
+ list.forEach(function(entry) {
224
+ entry.fn(evt);
225
+ if (!entry.once) remaining.push(entry);
226
+ });
227
+ this._listeners[type] = remaining;
228
+ };
229
+
230
+ function PatchedWebSocket(url, protocols) {
231
+ // Only intercept Vite HMR connections (protocol 'vite-hmr')
232
+ var isViteHmr = protocols === 'vite-hmr'
233
+ || (Array.isArray(protocols) && protocols.indexOf('vite-hmr') !== -1);
234
+ if (!isViteHmr) {
235
+ if (protocols !== undefined) {
236
+ return new OriginalWebSocket(url, protocols);
237
+ }
238
+ return new OriginalWebSocket(url);
239
+ }
240
+ return new SseWebSocket(url);
241
+ }
242
+
243
+ PatchedWebSocket.CONNECTING = 0;
244
+ PatchedWebSocket.OPEN = 1;
245
+ PatchedWebSocket.CLOSING = 2;
246
+ PatchedWebSocket.CLOSED = 3;
247
+ PatchedWebSocket.prototype = Object.create(OriginalWebSocket.prototype);
248
+ PatchedWebSocket.prototype.constructor = PatchedWebSocket;
249
+
250
+ window.WebSocket = PatchedWebSocket;
251
+ })();
252
+ `;
253
+ // Annotate the CommonJS export names for ESM import in node:
254
+ 0 && (module.exports = {
255
+ hmrSseBridgeClientScript,
256
+ setupHmrSseBridge
257
+ });
258
+ exports.default = module.exports;
@@ -0,0 +1,10 @@
1
+ import { ViteDevServer } from 'vite';
2
+
3
+ declare function setupHmrSseBridge(server: ViteDevServer): void;
4
+ /**
5
+ * Client-side script that patches WebSocket to use SSE+fetch on iOS Safari.
6
+ * This script is injected via Vite's transformIndexHtml hook.
7
+ */
8
+ declare const hmrSseBridgeClientScript = "\n(function() {\n // Activate when served over HTTPS to bypass WSS self-signed cert issues\n if (location.protocol !== 'https:') return;\n\n var OriginalWebSocket = window.WebSocket;\n\n function SseWebSocket(originalUrl) {\n var self = this;\n // WebSocket readyState constants on instance\n self.CONNECTING = 0;\n self.OPEN = 1;\n self.CLOSING = 2;\n self.CLOSED = 3;\n self.readyState = 0;\n self.onopen = null;\n self.onmessage = null;\n self.onclose = null;\n self.onerror = null;\n self.bufferedAmount = 0;\n self.extensions = '';\n self.binaryType = 'blob';\n self.protocol = 'vite-hmr';\n self.url = originalUrl;\n self._listeners = {};\n self._opened = false;\n\n var sseUrl = location.origin + '/__hmr_sse';\n var sendUrl = location.origin + '/__hmr_send';\n self._sendUrl = sendUrl;\n\n var es = new EventSource(sseUrl);\n self._es = es;\n\n es.onopen = function() {\n if (self._opened) return;\n self._opened = true;\n self.readyState = 1;\n var evt = new Event('open');\n if (self.onopen) self.onopen(evt);\n self._emit('open', evt);\n };\n\n es.onmessage = function(e) {\n var evt = new MessageEvent('message', { data: e.data });\n if (self.onmessage) self.onmessage(evt);\n self._emit('message', evt);\n };\n\n es.onerror = function() {\n // EventSource auto-reconnects on error; don't treat as fatal close\n // Only emit error event, never close event (SSE handles reconnect internally)\n if (self.readyState >= 2) return;\n // EventSource auto-reconnects; no action needed\n };\n }\n\n SseWebSocket.prototype.send = function(data) {\n if (this.readyState !== 1) return;\n fetch(this._sendUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: data\n }).catch(function() {});\n };\n\n SseWebSocket.prototype.close = function() {\n if (this.readyState >= 2) return;\n this.readyState = 3;\n if (this._es) this._es.close();\n var evt = new CloseEvent('close', { code: 1000, reason: '', wasClean: true });\n if (this.onclose) this.onclose(evt);\n this._emit('close', evt);\n };\n\n SseWebSocket.prototype.addEventListener = function(type, fn, options) {\n if (!this._listeners[type]) this._listeners[type] = [];\n var entry = { fn: fn, once: !!(options && options.once) };\n this._listeners[type].push(entry);\n };\n\n SseWebSocket.prototype.removeEventListener = function(type, fn) {\n var list = this._listeners[type];\n if (!list) return;\n this._listeners[type] = list.filter(function(e) { return e.fn !== fn; });\n };\n\n SseWebSocket.prototype.dispatchEvent = function(evt) {\n this._emit(evt.type, evt);\n return true;\n };\n\n SseWebSocket.prototype._emit = function(type, evt) {\n var list = this._listeners[type];\n if (!list) return;\n var remaining = [];\n list.forEach(function(entry) {\n entry.fn(evt);\n if (!entry.once) remaining.push(entry);\n });\n this._listeners[type] = remaining;\n };\n\n function PatchedWebSocket(url, protocols) {\n // Only intercept Vite HMR connections (protocol 'vite-hmr')\n var isViteHmr = protocols === 'vite-hmr'\n || (Array.isArray(protocols) && protocols.indexOf('vite-hmr') !== -1);\n if (!isViteHmr) {\n if (protocols !== undefined) {\n return new OriginalWebSocket(url, protocols);\n }\n return new OriginalWebSocket(url);\n }\n return new SseWebSocket(url);\n }\n\n PatchedWebSocket.CONNECTING = 0;\n PatchedWebSocket.OPEN = 1;\n PatchedWebSocket.CLOSING = 2;\n PatchedWebSocket.CLOSED = 3;\n PatchedWebSocket.prototype = Object.create(OriginalWebSocket.prototype);\n PatchedWebSocket.prototype.constructor = PatchedWebSocket;\n\n window.WebSocket = PatchedWebSocket;\n})();\n";
9
+
10
+ export { hmrSseBridgeClientScript, setupHmrSseBridge };
@@ -0,0 +1,10 @@
1
+ import { ViteDevServer } from 'vite';
2
+
3
+ declare function setupHmrSseBridge(server: ViteDevServer): void;
4
+ /**
5
+ * Client-side script that patches WebSocket to use SSE+fetch on iOS Safari.
6
+ * This script is injected via Vite's transformIndexHtml hook.
7
+ */
8
+ declare const hmrSseBridgeClientScript = "\n(function() {\n // Activate when served over HTTPS to bypass WSS self-signed cert issues\n if (location.protocol !== 'https:') return;\n\n var OriginalWebSocket = window.WebSocket;\n\n function SseWebSocket(originalUrl) {\n var self = this;\n // WebSocket readyState constants on instance\n self.CONNECTING = 0;\n self.OPEN = 1;\n self.CLOSING = 2;\n self.CLOSED = 3;\n self.readyState = 0;\n self.onopen = null;\n self.onmessage = null;\n self.onclose = null;\n self.onerror = null;\n self.bufferedAmount = 0;\n self.extensions = '';\n self.binaryType = 'blob';\n self.protocol = 'vite-hmr';\n self.url = originalUrl;\n self._listeners = {};\n self._opened = false;\n\n var sseUrl = location.origin + '/__hmr_sse';\n var sendUrl = location.origin + '/__hmr_send';\n self._sendUrl = sendUrl;\n\n var es = new EventSource(sseUrl);\n self._es = es;\n\n es.onopen = function() {\n if (self._opened) return;\n self._opened = true;\n self.readyState = 1;\n var evt = new Event('open');\n if (self.onopen) self.onopen(evt);\n self._emit('open', evt);\n };\n\n es.onmessage = function(e) {\n var evt = new MessageEvent('message', { data: e.data });\n if (self.onmessage) self.onmessage(evt);\n self._emit('message', evt);\n };\n\n es.onerror = function() {\n // EventSource auto-reconnects on error; don't treat as fatal close\n // Only emit error event, never close event (SSE handles reconnect internally)\n if (self.readyState >= 2) return;\n // EventSource auto-reconnects; no action needed\n };\n }\n\n SseWebSocket.prototype.send = function(data) {\n if (this.readyState !== 1) return;\n fetch(this._sendUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: data\n }).catch(function() {});\n };\n\n SseWebSocket.prototype.close = function() {\n if (this.readyState >= 2) return;\n this.readyState = 3;\n if (this._es) this._es.close();\n var evt = new CloseEvent('close', { code: 1000, reason: '', wasClean: true });\n if (this.onclose) this.onclose(evt);\n this._emit('close', evt);\n };\n\n SseWebSocket.prototype.addEventListener = function(type, fn, options) {\n if (!this._listeners[type]) this._listeners[type] = [];\n var entry = { fn: fn, once: !!(options && options.once) };\n this._listeners[type].push(entry);\n };\n\n SseWebSocket.prototype.removeEventListener = function(type, fn) {\n var list = this._listeners[type];\n if (!list) return;\n this._listeners[type] = list.filter(function(e) { return e.fn !== fn; });\n };\n\n SseWebSocket.prototype.dispatchEvent = function(evt) {\n this._emit(evt.type, evt);\n return true;\n };\n\n SseWebSocket.prototype._emit = function(type, evt) {\n var list = this._listeners[type];\n if (!list) return;\n var remaining = [];\n list.forEach(function(entry) {\n entry.fn(evt);\n if (!entry.once) remaining.push(entry);\n });\n this._listeners[type] = remaining;\n };\n\n function PatchedWebSocket(url, protocols) {\n // Only intercept Vite HMR connections (protocol 'vite-hmr')\n var isViteHmr = protocols === 'vite-hmr'\n || (Array.isArray(protocols) && protocols.indexOf('vite-hmr') !== -1);\n if (!isViteHmr) {\n if (protocols !== undefined) {\n return new OriginalWebSocket(url, protocols);\n }\n return new OriginalWebSocket(url);\n }\n return new SseWebSocket(url);\n }\n\n PatchedWebSocket.CONNECTING = 0;\n PatchedWebSocket.OPEN = 1;\n PatchedWebSocket.CLOSING = 2;\n PatchedWebSocket.CLOSED = 3;\n PatchedWebSocket.prototype = Object.create(OriginalWebSocket.prototype);\n PatchedWebSocket.prototype.constructor = PatchedWebSocket;\n\n window.WebSocket = PatchedWebSocket;\n})();\n";
9
+
10
+ export { hmrSseBridgeClientScript, setupHmrSseBridge };
@@ -0,0 +1,8 @@
1
+ import {
2
+ hmrSseBridgeClientScript,
3
+ setupHmrSseBridge
4
+ } from "./chunk-RSBXFJ3Z.js";
5
+ export {
6
+ hmrSseBridgeClientScript,
7
+ setupHmrSseBridge
8
+ };