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.
- package/README.md +6 -1
- package/dist/{chunk-5MC5SB7O.js → chunk-QURDG7SD.js} +115 -34
- package/dist/chunk-RSBXFJ3Z.js +232 -0
- package/dist/esbuild.cjs +339 -34
- package/dist/esbuild.js +2 -1
- package/dist/hmr-sse-bridge.cjs +258 -0
- package/dist/hmr-sse-bridge.d.cts +10 -0
- package/dist/hmr-sse-bridge.d.ts +10 -0
- package/dist/hmr-sse-bridge.js +8 -0
- package/dist/index.cjs +339 -34
- package/dist/index.js +2 -1
- package/dist/nuxt.cjs +202 -29
- package/dist/nuxt.js +2 -1
- package/dist/rollup.cjs +339 -34
- package/dist/rollup.js +2 -1
- package/dist/rspack.cjs +339 -34
- package/dist/rspack.js +2 -1
- package/dist/vite.cjs +339 -34
- package/dist/vite.js +2 -1
- package/dist/webpack.cjs +339 -34
- package/dist/webpack.js +2 -1
- package/package.json +1 -1
- package/src/caddy/caddyfile.ts +58 -19
- package/src/caddy/config.ts +7 -2
- package/src/caddy/index.ts +17 -10
- package/src/hmr-sse-bridge.ts +266 -0
- package/src/index.ts +44 -2
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# unplugin-https-reverse-proxy
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/unplugin-https-reverse-proxy)
|
|
4
|
+
[](https://deepwiki.com/zcf0508/unplugin-https-reverse-proxy)
|
|
4
5
|
|
|
5
6
|
A plugin for https reverse proxy, support `vite`、`webpack` and `rspack`.
|
|
6
7
|
|
|
@@ -170,6 +171,7 @@ const reverseProxyOptions = {
|
|
|
170
171
|
enable: false,
|
|
171
172
|
target: 'xxx',
|
|
172
173
|
https: false,
|
|
174
|
+
healthCheck: true,
|
|
173
175
|
}
|
|
174
176
|
|
|
175
177
|
module.exports = {
|
|
@@ -209,7 +211,10 @@ module.exports = {
|
|
|
209
211
|
// nuxt.config.js
|
|
210
212
|
export default defineNuxtConfig({
|
|
211
213
|
modules: [
|
|
212
|
-
['unplugin-https-reverse-proxy/nuxt', {
|
|
214
|
+
['unplugin-https-reverse-proxy/nuxt', {
|
|
215
|
+
/* options */
|
|
216
|
+
healthCheck: false, // important for nuxt
|
|
217
|
+
}],
|
|
213
218
|
],
|
|
214
219
|
})
|
|
215
220
|
```
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hmrSseBridgeClientScript,
|
|
3
|
+
setupHmrSseBridge
|
|
4
|
+
} from "./chunk-RSBXFJ3Z.js";
|
|
1
5
|
import {
|
|
2
6
|
chmodRecursive,
|
|
3
7
|
consola,
|
|
@@ -13391,33 +13395,63 @@ var caddyTemplate = `{
|
|
|
13391
13395
|
}
|
|
13392
13396
|
}
|
|
13393
13397
|
|
|
13394
|
-
{% for
|
|
13395
|
-
{{
|
|
13396
|
-
{{
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13398
|
+
{% for host in hosts %}
|
|
13399
|
+
{{ host.host }}{{ host.portSuffix }} {
|
|
13400
|
+
{{ host.tls }}
|
|
13401
|
+
|
|
13402
|
+
{% for route in host.routes %}
|
|
13403
|
+
handle {{ route.base }}* {
|
|
13404
|
+
reverse_proxy http://{{ route.source }} {% if route.healthCheck %} {
|
|
13405
|
+
health_uri {{ route.base }}
|
|
13406
|
+
health_interval 2s
|
|
13407
|
+
health_timeout 5s
|
|
13408
|
+
health_headers {
|
|
13409
|
+
User-Agent {http.request.header.User-Agent}
|
|
13410
|
+
Accept text/html,application/json,*/*
|
|
13411
|
+
}
|
|
13412
|
+
fail_duration 2s
|
|
13413
|
+
unhealthy_status 502 503 504 404
|
|
13414
|
+
lb_try_duration 3s
|
|
13415
|
+
lb_try_interval 300ms
|
|
13405
13416
|
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
|
|
13410
|
-
|
|
13417
|
+
@error status 502 503 504 404
|
|
13418
|
+
handle_response @error {
|
|
13419
|
+
respond * 503 {
|
|
13420
|
+
body "Service Unavailable"
|
|
13421
|
+
close
|
|
13422
|
+
}
|
|
13411
13423
|
}
|
|
13412
13424
|
}
|
|
13425
|
+
{% endif %}
|
|
13413
13426
|
}
|
|
13414
|
-
{%
|
|
13427
|
+
{% endfor %}
|
|
13415
13428
|
}
|
|
13416
13429
|
{% endfor %}
|
|
13417
13430
|
`;
|
|
13418
13431
|
var liquid = new Liquid();
|
|
13419
13432
|
async function genCaddyfile(ctx) {
|
|
13420
|
-
|
|
13433
|
+
const hostsMap = /* @__PURE__ */ new Map();
|
|
13434
|
+
for (const proxy of ctx.proxies) {
|
|
13435
|
+
const key = `${proxy.target}${proxy.portSuffix}`;
|
|
13436
|
+
if (!hostsMap.has(key)) {
|
|
13437
|
+
hostsMap.set(key, {
|
|
13438
|
+
host: proxy.target,
|
|
13439
|
+
portSuffix: proxy.portSuffix,
|
|
13440
|
+
tls: proxy.tls,
|
|
13441
|
+
routes: []
|
|
13442
|
+
});
|
|
13443
|
+
}
|
|
13444
|
+
let base = proxy.base || "/";
|
|
13445
|
+
if (!base.startsWith("/"))
|
|
13446
|
+
base = `/${base}`;
|
|
13447
|
+
if (base !== "/" && !base.endsWith("/"))
|
|
13448
|
+
base = `${base}/`;
|
|
13449
|
+
hostsMap.get(key).routes.push({ ...proxy, base });
|
|
13450
|
+
}
|
|
13451
|
+
for (const host of hostsMap.values())
|
|
13452
|
+
host.routes.sort((a, b) => b.base.length - a.base.length);
|
|
13453
|
+
const hosts = Array.from(hostsMap.values());
|
|
13454
|
+
return await liquid.parseAndRender(caddyTemplate, { ...ctx, hosts });
|
|
13421
13455
|
}
|
|
13422
13456
|
|
|
13423
13457
|
// src/caddy/config.ts
|
|
@@ -13582,8 +13616,13 @@ function useCaddyConfig() {
|
|
|
13582
13616
|
function writeCaddyConfig(_proxies) {
|
|
13583
13617
|
const proxies = configJsonRef() || {};
|
|
13584
13618
|
_proxies.forEach((p) => {
|
|
13585
|
-
|
|
13586
|
-
|
|
13619
|
+
let base = p.base || "/";
|
|
13620
|
+
if (!base.startsWith("/"))
|
|
13621
|
+
base = `/${base}`;
|
|
13622
|
+
if (base !== "/" && !base.endsWith("/"))
|
|
13623
|
+
base = `${base}/`;
|
|
13624
|
+
const index = `${p.target}${p.portSuffix}${base}`;
|
|
13625
|
+
proxies[index] = { ...p, base };
|
|
13587
13626
|
});
|
|
13588
13627
|
const content = JSON.stringify(proxies, null, 2);
|
|
13589
13628
|
configContentRef(content);
|
|
@@ -13801,13 +13840,22 @@ var CaddyInstant = class {
|
|
|
13801
13840
|
throw new Error("update host failed");
|
|
13802
13841
|
consola.success("update host success\n");
|
|
13803
13842
|
const targetHost = target.split(":")[0];
|
|
13843
|
+
const normalizeBase = (b) => {
|
|
13844
|
+
let out = b || "/";
|
|
13845
|
+
if (!out.startsWith("/"))
|
|
13846
|
+
out = `/${out}`;
|
|
13847
|
+
if (out !== "/" && !out.endsWith("/"))
|
|
13848
|
+
out = `${out}/`;
|
|
13849
|
+
return out;
|
|
13850
|
+
};
|
|
13851
|
+
const baseNormalized = normalizeBase(base);
|
|
13804
13852
|
const proxies = [
|
|
13805
13853
|
{
|
|
13806
13854
|
target: targetHost,
|
|
13807
13855
|
portSuffix: https ? "" : ":80",
|
|
13808
13856
|
tls: https ? "tls internal" : "",
|
|
13809
13857
|
source,
|
|
13810
|
-
base,
|
|
13858
|
+
base: baseNormalized,
|
|
13811
13859
|
healthCheck
|
|
13812
13860
|
}
|
|
13813
13861
|
];
|
|
@@ -13817,14 +13865,12 @@ var CaddyInstant = class {
|
|
|
13817
13865
|
effect(async () => {
|
|
13818
13866
|
const { configJsonRef } = getCaddyConfig();
|
|
13819
13867
|
const proxies2 = Object.values(configJsonRef() || {});
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
await this.writeCaddyfile();
|
|
13827
|
-
}
|
|
13868
|
+
const ctx = validateTemplateContext({
|
|
13869
|
+
caddy_root: this.caddyRoot,
|
|
13870
|
+
proxies: proxies2
|
|
13871
|
+
});
|
|
13872
|
+
this.caddyfile = await genCaddyfile(ctx);
|
|
13873
|
+
await this.writeCaddyfile();
|
|
13828
13874
|
})
|
|
13829
13875
|
);
|
|
13830
13876
|
if (!existsSync3(caddyLockFilePath))
|
|
@@ -13963,6 +14009,7 @@ ${line}
|
|
|
13963
14009
|
// src/index.ts
|
|
13964
14010
|
var config;
|
|
13965
14011
|
var caddy;
|
|
14012
|
+
var hmrSseBridgeActive = false;
|
|
13966
14013
|
var cwd = process5.cwd();
|
|
13967
14014
|
function colorUrl(url2) {
|
|
13968
14015
|
return c.green(url2.replace(/:(\d+)\//, (_, port) => `:${c.bold(port)}/`));
|
|
@@ -14049,10 +14096,24 @@ var unpluginFactory = (options) => ({
|
|
|
14049
14096
|
}
|
|
14050
14097
|
const base = server.config.base || "/";
|
|
14051
14098
|
server.printUrls = () => vitePrintUrls(options, source, target, base, _printUrls);
|
|
14099
|
+
if (options.https) {
|
|
14100
|
+
setupHmrSseBridge(server);
|
|
14101
|
+
hmrSseBridgeActive = true;
|
|
14102
|
+
consola.info("HMR SSE bridge enabled for iOS Safari WSS workaround");
|
|
14103
|
+
}
|
|
14104
|
+
},
|
|
14105
|
+
transformIndexHtml() {
|
|
14106
|
+
if (!hmrSseBridgeActive)
|
|
14107
|
+
return [];
|
|
14108
|
+
return [{
|
|
14109
|
+
tag: "script",
|
|
14110
|
+
children: hmrSseBridgeClientScript,
|
|
14111
|
+
injectTo: "head-prepend"
|
|
14112
|
+
}];
|
|
14052
14113
|
}
|
|
14053
14114
|
},
|
|
14054
14115
|
webpack(compiler) {
|
|
14055
|
-
var _a4, _b3;
|
|
14116
|
+
var _a4, _b3, _c2;
|
|
14056
14117
|
if (process5.env.NODE_ENV !== "development")
|
|
14057
14118
|
return;
|
|
14058
14119
|
const {
|
|
@@ -14083,7 +14144,16 @@ var unpluginFactory = (options) => ({
|
|
|
14083
14144
|
const source = `${devServer.host}:${devServer.port}`;
|
|
14084
14145
|
if (caddy)
|
|
14085
14146
|
return;
|
|
14086
|
-
|
|
14147
|
+
let base = "/";
|
|
14148
|
+
const publicPath = (_b3 = compiler.options.output) == null ? void 0 : _b3.publicPath;
|
|
14149
|
+
if (typeof publicPath === "string" && publicPath) {
|
|
14150
|
+
base = publicPath;
|
|
14151
|
+
}
|
|
14152
|
+
if (!base.startsWith("/"))
|
|
14153
|
+
base = `/${base}`;
|
|
14154
|
+
if (base !== "/" && !base.endsWith("/"))
|
|
14155
|
+
base = `${base}/`;
|
|
14156
|
+
const _close = (_c2 = compiler.close) == null ? void 0 : _c2.bind(compiler);
|
|
14087
14157
|
if (_close) {
|
|
14088
14158
|
compiler.close = async (callback) => {
|
|
14089
14159
|
process5.on("exit", () => {
|
|
@@ -14095,18 +14165,19 @@ var unpluginFactory = (options) => ({
|
|
|
14095
14165
|
}
|
|
14096
14166
|
caddy = new CaddyInstant();
|
|
14097
14167
|
caddy.run(source, target, {
|
|
14168
|
+
base,
|
|
14098
14169
|
...options
|
|
14099
14170
|
}).then(() => {
|
|
14100
14171
|
compiler.hooks.done.tap("unplugin-https-reverse-proxy", async () => {
|
|
14101
14172
|
await printForwardProxy();
|
|
14102
|
-
consola.success(` ${c.green("\u279C")} ${c.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}`)}`);
|
|
14173
|
+
consola.success(` ${c.green("\u279C")} ${c.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}${base}`)}`);
|
|
14103
14174
|
});
|
|
14104
14175
|
}).catch((e) => {
|
|
14105
14176
|
throw e;
|
|
14106
14177
|
});
|
|
14107
14178
|
},
|
|
14108
14179
|
async rspack(compiler) {
|
|
14109
|
-
var _a4, _b3, _c2;
|
|
14180
|
+
var _a4, _b3, _c2, _d2;
|
|
14110
14181
|
if (process5.env.NODE_ENV !== "development")
|
|
14111
14182
|
return;
|
|
14112
14183
|
const {
|
|
@@ -14139,11 +14210,21 @@ var unpluginFactory = (options) => ({
|
|
|
14139
14210
|
if (caddy)
|
|
14140
14211
|
return;
|
|
14141
14212
|
caddy = new CaddyInstant();
|
|
14213
|
+
let base = "/";
|
|
14214
|
+
const publicPath = (_d2 = compiler.options.output) == null ? void 0 : _d2.publicPath;
|
|
14215
|
+
if (typeof publicPath === "string" && publicPath) {
|
|
14216
|
+
base = publicPath;
|
|
14217
|
+
}
|
|
14218
|
+
if (!base.startsWith("/"))
|
|
14219
|
+
base = `/${base}`;
|
|
14220
|
+
if (base !== "/" && !base.endsWith("/"))
|
|
14221
|
+
base = `${base}/`;
|
|
14142
14222
|
caddy.run(source, target, {
|
|
14223
|
+
base,
|
|
14143
14224
|
...options
|
|
14144
14225
|
}).then(async () => {
|
|
14145
14226
|
await printForwardProxy();
|
|
14146
|
-
consola.success(` ${c.green("\u279C")} ${c.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}`)}`);
|
|
14227
|
+
consola.success(` ${c.green("\u279C")} ${c.bold("run caddy reverse proxy success")}: ${colorUrl(`${options.https ? "https" : "http"}://${target}${base}`)}`);
|
|
14147
14228
|
}).catch((e) => {
|
|
14148
14229
|
throw e;
|
|
14149
14230
|
});
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// src/hmr-sse-bridge.ts
|
|
2
|
+
var SSE_PATH = "/__hmr_sse";
|
|
3
|
+
var SEND_PATH = "/__hmr_send";
|
|
4
|
+
var MAX_POST_BODY = 64 * 1024;
|
|
5
|
+
function setupHmrSseBridge(server) {
|
|
6
|
+
const sseClients = /* @__PURE__ */ new Set();
|
|
7
|
+
const originalSend = server.ws.send.bind(server.ws);
|
|
8
|
+
server.ws.send = (...args) => {
|
|
9
|
+
;
|
|
10
|
+
originalSend(...args);
|
|
11
|
+
let payload;
|
|
12
|
+
if (typeof args[0] === "string") {
|
|
13
|
+
payload = JSON.stringify({ type: "custom", event: args[0], data: args[1] });
|
|
14
|
+
} else {
|
|
15
|
+
payload = JSON.stringify(args[0]);
|
|
16
|
+
}
|
|
17
|
+
for (const res of sseClients) {
|
|
18
|
+
try {
|
|
19
|
+
res.write(`data: ${payload}
|
|
20
|
+
|
|
21
|
+
`);
|
|
22
|
+
} catch {
|
|
23
|
+
sseClients.delete(res);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
server.middlewares.use((req, res, next) => {
|
|
28
|
+
var _a;
|
|
29
|
+
const url = (_a = req.url) == null ? void 0 : _a.split("?")[0];
|
|
30
|
+
if (url === SSE_PATH && req.method === "GET") {
|
|
31
|
+
handleSseConnection(req, res, sseClients);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (url === SEND_PATH && req.method === "POST") {
|
|
35
|
+
handleClientMessage(req, res, server);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
next();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function handleSseConnection(_req, res, sseClients) {
|
|
42
|
+
res.writeHead(200, {
|
|
43
|
+
"Content-Type": "text/event-stream",
|
|
44
|
+
"Cache-Control": "no-cache",
|
|
45
|
+
"Connection": "keep-alive"
|
|
46
|
+
});
|
|
47
|
+
res.write(`data: ${JSON.stringify({ type: "connected" })}
|
|
48
|
+
|
|
49
|
+
`);
|
|
50
|
+
sseClients.add(res);
|
|
51
|
+
const keepAlive = setInterval(() => {
|
|
52
|
+
try {
|
|
53
|
+
res.write(": ping\n\n");
|
|
54
|
+
} catch {
|
|
55
|
+
cleanup();
|
|
56
|
+
}
|
|
57
|
+
}, 3e4);
|
|
58
|
+
function cleanup() {
|
|
59
|
+
clearInterval(keepAlive);
|
|
60
|
+
sseClients.delete(res);
|
|
61
|
+
}
|
|
62
|
+
res.on("close", cleanup);
|
|
63
|
+
res.on("error", cleanup);
|
|
64
|
+
}
|
|
65
|
+
function handleClientMessage(req, res, server) {
|
|
66
|
+
let body = "";
|
|
67
|
+
let overflow = false;
|
|
68
|
+
req.on("data", (chunk) => {
|
|
69
|
+
body += chunk.toString();
|
|
70
|
+
if (body.length > MAX_POST_BODY) {
|
|
71
|
+
overflow = true;
|
|
72
|
+
req.destroy();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
req.on("end", () => {
|
|
76
|
+
var _a, _b, _c, _d, _e;
|
|
77
|
+
if (overflow) {
|
|
78
|
+
res.writeHead(413);
|
|
79
|
+
res.end('{"ok":false}');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const data = JSON.parse(body);
|
|
84
|
+
if (data.type === "custom" && data.event) {
|
|
85
|
+
const dummyClient = {
|
|
86
|
+
send: (...args) => {
|
|
87
|
+
server.ws.send(...args);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
(_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);
|
|
91
|
+
}
|
|
92
|
+
res.writeHead(200, {
|
|
93
|
+
"Content-Type": "application/json"
|
|
94
|
+
});
|
|
95
|
+
res.end('{"ok":true}');
|
|
96
|
+
} catch {
|
|
97
|
+
res.writeHead(400);
|
|
98
|
+
res.end('{"ok":false}');
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
var hmrSseBridgeClientScript = `
|
|
103
|
+
(function() {
|
|
104
|
+
// Activate when served over HTTPS to bypass WSS self-signed cert issues
|
|
105
|
+
if (location.protocol !== 'https:') return;
|
|
106
|
+
|
|
107
|
+
var OriginalWebSocket = window.WebSocket;
|
|
108
|
+
|
|
109
|
+
function SseWebSocket(originalUrl) {
|
|
110
|
+
var self = this;
|
|
111
|
+
// WebSocket readyState constants on instance
|
|
112
|
+
self.CONNECTING = 0;
|
|
113
|
+
self.OPEN = 1;
|
|
114
|
+
self.CLOSING = 2;
|
|
115
|
+
self.CLOSED = 3;
|
|
116
|
+
self.readyState = 0;
|
|
117
|
+
self.onopen = null;
|
|
118
|
+
self.onmessage = null;
|
|
119
|
+
self.onclose = null;
|
|
120
|
+
self.onerror = null;
|
|
121
|
+
self.bufferedAmount = 0;
|
|
122
|
+
self.extensions = '';
|
|
123
|
+
self.binaryType = 'blob';
|
|
124
|
+
self.protocol = 'vite-hmr';
|
|
125
|
+
self.url = originalUrl;
|
|
126
|
+
self._listeners = {};
|
|
127
|
+
self._opened = false;
|
|
128
|
+
|
|
129
|
+
var sseUrl = location.origin + '${SSE_PATH}';
|
|
130
|
+
var sendUrl = location.origin + '${SEND_PATH}';
|
|
131
|
+
self._sendUrl = sendUrl;
|
|
132
|
+
|
|
133
|
+
var es = new EventSource(sseUrl);
|
|
134
|
+
self._es = es;
|
|
135
|
+
|
|
136
|
+
es.onopen = function() {
|
|
137
|
+
if (self._opened) return;
|
|
138
|
+
self._opened = true;
|
|
139
|
+
self.readyState = 1;
|
|
140
|
+
var evt = new Event('open');
|
|
141
|
+
if (self.onopen) self.onopen(evt);
|
|
142
|
+
self._emit('open', evt);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
es.onmessage = function(e) {
|
|
146
|
+
var evt = new MessageEvent('message', { data: e.data });
|
|
147
|
+
if (self.onmessage) self.onmessage(evt);
|
|
148
|
+
self._emit('message', evt);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
es.onerror = function() {
|
|
152
|
+
// EventSource auto-reconnects on error; don't treat as fatal close
|
|
153
|
+
// Only emit error event, never close event (SSE handles reconnect internally)
|
|
154
|
+
if (self.readyState >= 2) return;
|
|
155
|
+
// EventSource auto-reconnects; no action needed
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
SseWebSocket.prototype.send = function(data) {
|
|
160
|
+
if (this.readyState !== 1) return;
|
|
161
|
+
fetch(this._sendUrl, {
|
|
162
|
+
method: 'POST',
|
|
163
|
+
headers: { 'Content-Type': 'application/json' },
|
|
164
|
+
body: data
|
|
165
|
+
}).catch(function() {});
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
SseWebSocket.prototype.close = function() {
|
|
169
|
+
if (this.readyState >= 2) return;
|
|
170
|
+
this.readyState = 3;
|
|
171
|
+
if (this._es) this._es.close();
|
|
172
|
+
var evt = new CloseEvent('close', { code: 1000, reason: '', wasClean: true });
|
|
173
|
+
if (this.onclose) this.onclose(evt);
|
|
174
|
+
this._emit('close', evt);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
SseWebSocket.prototype.addEventListener = function(type, fn, options) {
|
|
178
|
+
if (!this._listeners[type]) this._listeners[type] = [];
|
|
179
|
+
var entry = { fn: fn, once: !!(options && options.once) };
|
|
180
|
+
this._listeners[type].push(entry);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
SseWebSocket.prototype.removeEventListener = function(type, fn) {
|
|
184
|
+
var list = this._listeners[type];
|
|
185
|
+
if (!list) return;
|
|
186
|
+
this._listeners[type] = list.filter(function(e) { return e.fn !== fn; });
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
SseWebSocket.prototype.dispatchEvent = function(evt) {
|
|
190
|
+
this._emit(evt.type, evt);
|
|
191
|
+
return true;
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
SseWebSocket.prototype._emit = function(type, evt) {
|
|
195
|
+
var list = this._listeners[type];
|
|
196
|
+
if (!list) return;
|
|
197
|
+
var remaining = [];
|
|
198
|
+
list.forEach(function(entry) {
|
|
199
|
+
entry.fn(evt);
|
|
200
|
+
if (!entry.once) remaining.push(entry);
|
|
201
|
+
});
|
|
202
|
+
this._listeners[type] = remaining;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
function PatchedWebSocket(url, protocols) {
|
|
206
|
+
// Only intercept Vite HMR connections (protocol 'vite-hmr')
|
|
207
|
+
var isViteHmr = protocols === 'vite-hmr'
|
|
208
|
+
|| (Array.isArray(protocols) && protocols.indexOf('vite-hmr') !== -1);
|
|
209
|
+
if (!isViteHmr) {
|
|
210
|
+
if (protocols !== undefined) {
|
|
211
|
+
return new OriginalWebSocket(url, protocols);
|
|
212
|
+
}
|
|
213
|
+
return new OriginalWebSocket(url);
|
|
214
|
+
}
|
|
215
|
+
return new SseWebSocket(url);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
PatchedWebSocket.CONNECTING = 0;
|
|
219
|
+
PatchedWebSocket.OPEN = 1;
|
|
220
|
+
PatchedWebSocket.CLOSING = 2;
|
|
221
|
+
PatchedWebSocket.CLOSED = 3;
|
|
222
|
+
PatchedWebSocket.prototype = Object.create(OriginalWebSocket.prototype);
|
|
223
|
+
PatchedWebSocket.prototype.constructor = PatchedWebSocket;
|
|
224
|
+
|
|
225
|
+
window.WebSocket = PatchedWebSocket;
|
|
226
|
+
})();
|
|
227
|
+
`;
|
|
228
|
+
|
|
229
|
+
export {
|
|
230
|
+
setupHmrSseBridge,
|
|
231
|
+
hmrSseBridgeClientScript
|
|
232
|
+
};
|