@goauthentik/esbuild-plugin-live-reload 1.0.5

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/LICENSE.txt ADDED
@@ -0,0 +1,18 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Authentik Security, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
17
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ **ESBuild Plugin Live Reload**
2
+
3
+ ---
4
+
5
+ _An ESBuild development plugin that watches for file changes and triggers automatic browser refreshes._
6
+
7
+ ## Quick start
8
+
9
+ ```sh
10
+ npm install -D @goauthentik/esbuild-plugin-live-reload
11
+ # Or with Yarn:
12
+ yarn add -D @goauthentik/esbuild-plugin-live-reload
13
+ ```
14
+
15
+ ### 1. Configure ESBuild
16
+
17
+ ```js
18
+ import { liveReloadPlugin } from "@goauthentik/esbuild-plugin-live-reload";
19
+ import esbuild from "esbuild";
20
+
21
+ const NodeEnvironment = process.env.NODE_ENV || "development";
22
+
23
+ /**
24
+ * @type {esbuild.BuildOptions}
25
+ */
26
+ const buildOptions = {
27
+ // ... Your build options.
28
+ define: {
29
+ "process.env.NODE_ENV": JSON.stringify(NodeEnvironment),
30
+ },
31
+ plugins: [
32
+ /** @see {@link LiveReloadPluginOptions} */
33
+ liveReloadPlugin(),
34
+ ],
35
+ };
36
+
37
+ const buildContext = await esbuild.context(buildOptions);
38
+
39
+ await buildContext.rebuild();
40
+ await buildContext.watch();
41
+ ```
42
+
43
+ ### 2. Connect your browser
44
+
45
+ Add the following import near the beginning of your application's entry point.
46
+
47
+ ```js
48
+ if (process.env.NODE_ENV === "development") {
49
+ await import("@goauthentik/esbuild-plugin-live-reload/client");
50
+ }
51
+ ```
52
+
53
+ That's it! Your browser will now automatically refresh whenever ESBuild finishes rebuilding your code.
54
+
55
+ ## About authentik
56
+
57
+ [authentik](https://goauthentik.io) is an open source Identity Provider that unifies your identity needs into a single platform, replacing Okta, Active Directory, and Auth0.
58
+
59
+ We built this plugin to streamline our development workflow, and we're sharing it with the community. If you have any questions, feature requests, or bug reports, please [open an issue](https://github.com/goauthentik/authentik/issues/new/choose).
60
+
61
+ ## License
62
+
63
+ This code is licensed under the [MIT License](https://www.tldrlegal.com/license/mit-license)
64
+
65
+ ## Plugin API
66
+
67
+ ### EventServerInit
68
+
69
+ #### Properties
70
+
71
+ | Property | Type |
72
+ | ------------------------------------ | ------------- |
73
+ | <a id="dispatcher"></a> `dispatcher` | `EventTarget` |
74
+ | <a id="logprefix"></a> `logPrefix?` | `string` |
75
+ | <a id="pathname"></a> `pathname` | `string` |
76
+
77
+ ---
78
+
79
+ ### LiveReloadPluginOptions
80
+
81
+ #### Properties
82
+
83
+ | Property | Type | Description |
84
+ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
85
+ | <a id="listenoptions"></a> `listenOptions?` | `ListenOptions` | Options for the server's listen method. |
86
+ | <a id="logprefix-1"></a> `logPrefix?` | `string` | A prefix to use for log messages. |
87
+ | <a id="publicurl"></a> `publicURL?` | `string` \| `URL` | A URL to listen on. If not provided, a random port will be used. |
88
+ | <a id="relativeroot"></a> `relativeRoot?` | `string` | A relative path to the root of the project. This is used to resolve build errors, line numbers, and file paths. |
89
+ | <a id="server"></a> `server?` | `Server`\<_typeof_ `IncomingMessage`, _typeof_ `ServerResponse`\> \| `Server`\<_typeof_ `IncomingMessage`, _typeof_ `ServerResponse`\> | A server to listen on. If not provided, a new server will be created. |
90
+
91
+ ---
92
+
93
+ ### RequestHandler()
94
+
95
+ > **RequestHandler**\<\> = (`req`, `res`) => `void`
96
+
97
+ #### Type Parameters
98
+
99
+ | Type Parameter |
100
+ | -------------- |
101
+
102
+ #### Parameters
103
+
104
+ | Parameter | Type |
105
+ | --------- | ---------------------- |
106
+ | `req` | `http.IncomingMessage` |
107
+ | `res` | `http.ServerResponse` |
108
+
109
+ #### Returns
110
+
111
+ `void`
112
+
113
+ ---
114
+
115
+ ### liveReloadPlugin()
116
+
117
+ > **liveReloadPlugin**(`options?`): `Plugin`
118
+
119
+ Creates a plugin that listens for build events and sends them to a server-sent event stream.
120
+
121
+ #### Parameters
122
+
123
+ | Parameter | Type | Description |
124
+ | ---------- | ----------------------------------------------------- | ----------- |
125
+ | `options?` | [`LiveReloadPluginOptions`](#livereloadpluginoptions) | |
126
+
127
+ #### Returns
128
+
129
+ `Plugin`
130
+
131
+ ---
132
+
133
+ ### default
134
+
135
+ Renames and re-exports [liveReloadPlugin](#livereloadplugin)
136
+
137
+ ## Server API
138
+
139
+ ### createRequestHandler()
140
+
141
+ > **createRequestHandler**(`options`): [`RequestHandler`](#requesthandler)
142
+
143
+ Create an event request handler.
144
+
145
+ #### Parameters
146
+
147
+ | Parameter | Type | Description |
148
+ | --------- | ------------------------------------- | ----------- |
149
+ | `options` | [`EventServerInit`](#eventserverinit) | |
150
+
151
+ #### Returns
152
+
153
+ [`RequestHandler`](#requesthandler)
154
+
155
+ #### Runtime
156
+
157
+ node
@@ -0,0 +1,221 @@
1
+ /// <reference types="./types.js" />
2
+
3
+ /**
4
+ * @file Client-side observer for ESBuild events.
5
+ *
6
+ * @import { Message as ESBuildMessage } from "esbuild";
7
+ */
8
+
9
+ const logPrefix = "authentik/dev/web: ";
10
+ const log = console.debug.bind(console, logPrefix);
11
+
12
+ /**
13
+ * @template {unknown} [Data=unknown]
14
+ * @typedef {(event: MessageEvent) => void} BuildEventListener
15
+ */
16
+
17
+ /**
18
+ * A client-side watcher for ESBuild.
19
+ *
20
+ * Note that this should be conditionally imported in your code, so that
21
+ * ESBuild may tree-shake it out of production builds.
22
+ *
23
+ * ```ts
24
+ * if (process.env.NODE_ENV === "development") {
25
+ * await import("@goauthentik/esbuild-plugin-live-reload/client")
26
+ * .catch(() => console.warn("Failed to import watcher"))
27
+ * }
28
+ * ```
29
+ *
30
+ * @implements {Disposable}
31
+ * @category Plugin
32
+ * runtime browser
33
+ */
34
+ export class ESBuildObserver extends EventSource {
35
+ /**
36
+ * Whether the watcher has a recent connection to the server.
37
+ */
38
+ alive = true;
39
+
40
+ /**
41
+ * The number of errors that have occurred since the watcher started.
42
+ */
43
+ errorCount = 0;
44
+
45
+ /**
46
+ * Whether a reload has been requested while offline.
47
+ */
48
+ deferredReload = false;
49
+
50
+ /**
51
+ * The last time a message was received from the server.
52
+ */
53
+ lastUpdatedAt = Date.now();
54
+
55
+ /**
56
+ * Whether the browser considers itself online.
57
+ */
58
+ online = true;
59
+
60
+ /**
61
+ * The ID of the animation frame for the reload.
62
+ */
63
+ #reloadFrameID = -1;
64
+
65
+ /**
66
+ * The interval for the keep-alive check.
67
+ * @type {ReturnType<typeof setInterval> | undefined}
68
+ */
69
+ #keepAliveInterval;
70
+
71
+ #trackActivity = () => {
72
+ this.lastUpdatedAt = Date.now();
73
+ this.alive = true;
74
+ };
75
+
76
+ /**
77
+ * @type {BuildEventListener}
78
+ */
79
+ #startListener = () => {
80
+ this.#trackActivity();
81
+ log("⏰ Build started...");
82
+ };
83
+
84
+ #internalErrorListener = () => {
85
+ this.errorCount += 1;
86
+
87
+ if (this.errorCount > 100) {
88
+ clearTimeout(this.#keepAliveInterval);
89
+
90
+ this.close();
91
+ log("⛔️ Closing connection");
92
+ }
93
+ };
94
+
95
+ /**
96
+ * @type {BuildEventListener<string>}
97
+ */
98
+ #errorListener = (event) => {
99
+ this.#trackActivity();
100
+
101
+ console.group(logPrefix, "⛔️⛔️⛔️ Build error...");
102
+
103
+ /**
104
+ * @type {ESBuildMessage[]}
105
+ */
106
+ const esbuildErrorMessages = JSON.parse(event.data);
107
+
108
+ for (const error of esbuildErrorMessages) {
109
+ console.warn(error.text);
110
+
111
+ if (error.location) {
112
+ console.debug(
113
+ `file://${error.location.file}:${error.location.line}:${error.location.column}`,
114
+ );
115
+ console.debug(error.location.lineText);
116
+ }
117
+ }
118
+
119
+ console.groupEnd();
120
+ };
121
+
122
+ /**
123
+ * @type {BuildEventListener}
124
+ */
125
+ #endListener = () => {
126
+ cancelAnimationFrame(this.#reloadFrameID);
127
+
128
+ this.#trackActivity();
129
+
130
+ if (!this.online) {
131
+ log("🚫 Build finished while offline.");
132
+ this.deferredReload = true;
133
+
134
+ return;
135
+ }
136
+
137
+ log("🛎️ Build completed! Reloading...");
138
+
139
+ // We use an animation frame to keep the reload from happening before the
140
+ // event loop has a chance to process the message.
141
+ this.#reloadFrameID = requestAnimationFrame(() => {
142
+ window.location.reload();
143
+ });
144
+ };
145
+
146
+ /**
147
+ * @type {BuildEventListener}
148
+ */
149
+ #keepAliveListener = () => {
150
+ this.#trackActivity();
151
+ log("🏓 Keep-alive");
152
+ };
153
+
154
+ /**
155
+ * Initialize the ESBuild observer.
156
+ * This should be called once in your application.
157
+ *
158
+ * @param {string | URL} [url]
159
+ * @returns {ESBuildObserver}
160
+ */
161
+ static initialize = (url) => {
162
+ const esbuildObserver = new ESBuildObserver(url);
163
+
164
+ return esbuildObserver;
165
+ };
166
+
167
+ /**
168
+ *
169
+ * @param {string | URL} [url]
170
+ */
171
+ constructor(url) {
172
+ if (!url) {
173
+ throw new TypeError("ESBuildObserver: Cannot construct without a URL");
174
+ }
175
+
176
+ super(url);
177
+
178
+ this.addEventListener("esbuild:start", this.#startListener);
179
+ this.addEventListener("esbuild:end", this.#endListener);
180
+ this.addEventListener("esbuild:error", this.#errorListener);
181
+ this.addEventListener("esbuild:keep-alive", this.#keepAliveListener);
182
+
183
+ this.addEventListener("error", this.#internalErrorListener);
184
+
185
+ window.addEventListener("offline", () => {
186
+ this.online = false;
187
+ });
188
+
189
+ window.addEventListener("online", () => {
190
+ this.online = true;
191
+
192
+ if (!this.deferredReload) return;
193
+
194
+ log("🛎️ Reloading after offline build...");
195
+ this.deferredReload = false;
196
+
197
+ window.location.reload();
198
+ });
199
+
200
+ log("🛎️ Listening for build changes...");
201
+
202
+ this.#keepAliveInterval = setInterval(() => {
203
+ const now = Date.now();
204
+
205
+ if (now - this.lastUpdatedAt < 10_000) return;
206
+
207
+ this.alive = false;
208
+ log("👋 Waiting for build to start...");
209
+ }, 15_000);
210
+ }
211
+
212
+ [Symbol.dispose]() {
213
+ return this.close();
214
+ }
215
+
216
+ dispose() {
217
+ return this[Symbol.dispose]();
218
+ }
219
+ }
220
+
221
+ export default ESBuildObserver;
@@ -0,0 +1,13 @@
1
+ /// <reference types="./types.js" />
2
+ /**
3
+ * @file Entry point for the ESBuild client-side observer.
4
+ */
5
+ import { ESBuildObserver } from "./ESBuildObserver.js";
6
+
7
+ if (import.meta.env?.ESBUILD_WATCHER_URL) {
8
+ const buildObserver = new ESBuildObserver(import.meta.env.ESBUILD_WATCHER_URL);
9
+
10
+ window.addEventListener("beforeunload", () => {
11
+ buildObserver.dispose();
12
+ });
13
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file Import meta environment variables available via ESBuild.
3
+ */
4
+
5
+ export {};
6
+ declare global {
7
+ /**
8
+ * Environment variables injected by ESBuild.
9
+ */
10
+ interface ImportMetaEnv {
11
+ /**
12
+ * The injected watcher URL for ESBuild.
13
+ * This is used for live reloading in development mode.
14
+ *
15
+ * @format url
16
+ */
17
+ readonly ESBUILD_WATCHER_URL?: string;
18
+ }
19
+
20
+ interface ImportMeta {
21
+ readonly env: ImportMetaEnv;
22
+ }
23
+ }
package/index.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @remarks Live reload plugin for ESBuild.
3
+ */
4
+
5
+ export * from "./client/index.js";
6
+ export * from "./plugin/index.js";
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @template {unknown} [Data=unknown]
3
+ * @typedef {(event: MessageEvent) => void} BuildEventListener
4
+ */
5
+ /**
6
+ * A client-side watcher for ESBuild.
7
+ *
8
+ * Note that this should be conditionally imported in your code, so that
9
+ * ESBuild may tree-shake it out of production builds.
10
+ *
11
+ * ```ts
12
+ * if (process.env.NODE_ENV === "development") {
13
+ * await import("@goauthentik/esbuild-plugin-live-reload/client")
14
+ * .catch(() => console.warn("Failed to import watcher"))
15
+ * }
16
+ * ```
17
+ *
18
+ * @implements {Disposable}
19
+ * @category Plugin
20
+ * runtime browser
21
+ */
22
+ export class ESBuildObserver extends EventSource implements Disposable {
23
+ /**
24
+ * Initialize the ESBuild observer.
25
+ * This should be called once in your application.
26
+ *
27
+ * @param {string | URL} [url]
28
+ * @returns {ESBuildObserver}
29
+ */
30
+ static initialize: (url?: string | URL) => ESBuildObserver;
31
+ /**
32
+ *
33
+ * @param {string | URL} [url]
34
+ */
35
+ constructor(url?: string | URL);
36
+ /**
37
+ * Whether the watcher has a recent connection to the server.
38
+ */
39
+ alive: boolean;
40
+ /**
41
+ * The number of errors that have occurred since the watcher started.
42
+ */
43
+ errorCount: number;
44
+ /**
45
+ * Whether a reload has been requested while offline.
46
+ */
47
+ deferredReload: boolean;
48
+ /**
49
+ * The last time a message was received from the server.
50
+ */
51
+ lastUpdatedAt: number;
52
+ /**
53
+ * Whether the browser considers itself online.
54
+ */
55
+ online: boolean;
56
+ dispose(): void;
57
+ [Symbol.dispose](): void;
58
+ #private;
59
+ }
60
+ export default ESBuildObserver;
61
+ export type BuildEventListener<Data extends unknown = unknown> = (event: MessageEvent) => void;
62
+ //# sourceMappingURL=ESBuildObserver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ESBuildObserver.d.ts","sourceRoot":"","sources":["../../client/ESBuildObserver.js"],"names":[],"mappings":"AAWA;;;GAGG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,4DAJgB,UAAU;IA4HtB;;;;;;OAMG;IACH,oBAAqB,MAHV,MAAM,GAAG,GAGI,KAFX,eAAe,CAM1B;IAEF;;;OAGG;IACH,kBAFW,MAAM,GAAG,GAAG,EAyCtB;IA/KD;;OAEG;IACH,eAAa;IAEb;;OAEG;IACH,mBAAe;IAEf;;OAEG;IACH,wBAAuB;IAEvB;;OAEG;IACH,sBAA2B;IAE3B;;OAEG;IACH,gBAAc;IA8Jd,gBAEC;IAND,yBAEC;;CAKJ;;+BA9MuB,IAAI,SAAf,OAAS,cACT,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../client/index.js"],"names":[],"mappings":""}
package/out/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./client/index.js";
2
+ export * from "./plugin/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":""}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Serializes a custom event to a text stream.
3
+ *
4
+ * @param {Event} event
5
+ * @returns {string}
6
+ *
7
+ * @category Server API
8
+ * @ignore
9
+ * @internal
10
+ * @runtime node
11
+ */
12
+ export function serializeCustomEventToStream(event: Event): string;
13
+ /**
14
+ * Event server initialization options.
15
+ *
16
+ * @typedef {Object} EventServerInit
17
+ *
18
+ * @property {string} pathname
19
+ * @property {EventTarget} dispatcher
20
+ * @property {string} [logPrefix]
21
+ *
22
+ * @category Server API
23
+ * @runtime node
24
+ */
25
+ /**
26
+ * @typedef {(req: http.IncomingMessage, res: http.ServerResponse) => void} RequestHandler
27
+ *
28
+ * @category Server API
29
+ * @runtime node
30
+ */
31
+ /**
32
+ * Create an event request handler.
33
+ *
34
+ * @param {EventServerInit} options
35
+ * @returns {RequestHandler}
36
+ *
37
+ * @category Server API
38
+ * @runtime node
39
+ */
40
+ export function createRequestHandler({ pathname, dispatcher, logPrefix }: EventServerInit): RequestHandler;
41
+ /**
42
+ * Options for the build observer plugin.
43
+ *
44
+ * @category Plugin API
45
+ * @runtime node
46
+ *
47
+ * @typedef {object} LiveReloadPluginOptions
48
+ *
49
+ * @property {HTTPServer | HTTPSServer} [server] A server to listen on. If not provided, a new server will be created.
50
+ * @property {ListenOptions} [listenOptions] Options for the server's listen method.
51
+ * @property {string | URL} [publicURL] A URL to listen on. If not provided, a random port will be used.
52
+ * @property {string} [logPrefix] A prefix to use for log messages.
53
+ * @property {string} [relativeRoot] A relative path to the root of the project. This is used to resolve build errors, line numbers, and file paths.
54
+ */
55
+ /**
56
+ * Creates a plugin that listens for build events and sends them to a server-sent event stream.
57
+ *
58
+ * @param {LiveReloadPluginOptions} [options]
59
+ * @returns {import('esbuild').Plugin}
60
+ */
61
+ export function liveReloadPlugin(options?: LiveReloadPluginOptions): import("esbuild").Plugin;
62
+ export default liveReloadPlugin;
63
+ /**
64
+ * Event server initialization options.
65
+ */
66
+ export type EventServerInit = {
67
+ pathname: string;
68
+ dispatcher: EventTarget;
69
+ logPrefix?: string | undefined;
70
+ };
71
+ export type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void;
72
+ /**
73
+ * Options for the build observer plugin.
74
+ */
75
+ export type LiveReloadPluginOptions = {
76
+ /**
77
+ * A server to listen on. If not provided, a new server will be created.
78
+ */
79
+ server?: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | HTTPSServer<typeof http.IncomingMessage, typeof http.ServerResponse> | undefined;
80
+ /**
81
+ * Options for the server's listen method.
82
+ */
83
+ listenOptions?: ListenOptions | undefined;
84
+ /**
85
+ * A URL to listen on. If not provided, a random port will be used.
86
+ */
87
+ publicURL?: string | URL | undefined;
88
+ /**
89
+ * A prefix to use for log messages.
90
+ */
91
+ logPrefix?: string | undefined;
92
+ /**
93
+ * A relative path to the root of the project. This is used to resolve build errors, line numbers, and file paths.
94
+ */
95
+ relativeRoot?: string | undefined;
96
+ };
97
+ import * as http from "node:http";
98
+ import type { Server as HTTPSServer } from "node:https";
99
+ import type { ListenOptions } from "node:net";
100
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../plugin/index.js"],"names":[],"mappings":"AAWA;;;;;;;;;;GAUG;AACH,oDARW,KAAK,GACH,MAAM,CAclB;AAyBD;;;;;;;;;;;GAWG;AAEH;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,0EANW,eAAe,GACb,cAAc,CA+D1B;AAED;;;;;;;;;;;;;GAaG;AAEH;;;;;GAKG;AACH,2CAHW,uBAAuB,GACrB,OAAO,SAAS,EAAE,MAAM,CAoGpC;;;;;;cA3Ma,MAAM;gBACN,WAAW;;;6BAQZ,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;sBA5DpD,WAAW;2CAHO,YAAY;mCAFlB,UAAU"}
@@ -0,0 +1 @@
1
+ {"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/typescript/lib/lib.es2023.d.ts","../../../node_modules/typescript/lib/lib.es2024.d.ts","../../../node_modules/typescript/lib/lib.esnext.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../node_modules/typescript/lib/lib.es2024.object.d.ts","../../../node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2024.string.d.ts","../../../node_modules/typescript/lib/lib.esnext.array.d.ts","../../../node_modules/typescript/lib/lib.esnext.collection.d.ts","../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../node_modules/typescript/lib/lib.esnext.promise.d.ts","../../../node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../../node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../../node_modules/typescript/lib/lib.esnext.float16.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../client/types.d.ts","../../../node_modules/esbuild/lib/main.d.ts","../client/ESBuildObserver.js","../client/index.js","../../../node_modules/find-free-ports/index.d.ts","../plugin/index.js","../index.js","../node_modules/@types/node/compatibility/disposable.d.ts","../node_modules/@types/node/compatibility/indexable.d.ts","../node_modules/@types/node/compatibility/iterators.d.ts","../node_modules/@types/node/compatibility/index.d.ts","../node_modules/@types/node/globals.typedarray.d.ts","../node_modules/@types/node/buffer.buffer.d.ts","../node_modules/undici-types/header.d.ts","../node_modules/undici-types/readable.d.ts","../node_modules/undici-types/file.d.ts","../node_modules/undici-types/fetch.d.ts","../node_modules/undici-types/formdata.d.ts","../node_modules/undici-types/connector.d.ts","../node_modules/undici-types/client.d.ts","../node_modules/undici-types/errors.d.ts","../node_modules/undici-types/dispatcher.d.ts","../node_modules/undici-types/global-dispatcher.d.ts","../node_modules/undici-types/global-origin.d.ts","../node_modules/undici-types/pool-stats.d.ts","../node_modules/undici-types/pool.d.ts","../node_modules/undici-types/handlers.d.ts","../node_modules/undici-types/balanced-pool.d.ts","../node_modules/undici-types/agent.d.ts","../node_modules/undici-types/mock-interceptor.d.ts","../node_modules/undici-types/mock-agent.d.ts","../node_modules/undici-types/mock-client.d.ts","../node_modules/undici-types/mock-pool.d.ts","../node_modules/undici-types/mock-errors.d.ts","../node_modules/undici-types/proxy-agent.d.ts","../node_modules/undici-types/env-http-proxy-agent.d.ts","../node_modules/undici-types/retry-handler.d.ts","../node_modules/undici-types/retry-agent.d.ts","../node_modules/undici-types/api.d.ts","../node_modules/undici-types/interceptors.d.ts","../node_modules/undici-types/util.d.ts","../node_modules/undici-types/cookies.d.ts","../node_modules/undici-types/patch.d.ts","../node_modules/undici-types/websocket.d.ts","../node_modules/undici-types/eventsource.d.ts","../node_modules/undici-types/filereader.d.ts","../node_modules/undici-types/diagnostics-channel.d.ts","../node_modules/undici-types/content-type.d.ts","../node_modules/undici-types/cache.d.ts","../node_modules/undici-types/index.d.ts","../node_modules/@types/node/globals.d.ts","../node_modules/@types/node/assert.d.ts","../node_modules/@types/node/assert/strict.d.ts","../node_modules/@types/node/async_hooks.d.ts","../node_modules/@types/node/buffer.d.ts","../node_modules/@types/node/child_process.d.ts","../node_modules/@types/node/cluster.d.ts","../node_modules/@types/node/console.d.ts","../node_modules/@types/node/constants.d.ts","../node_modules/@types/node/crypto.d.ts","../node_modules/@types/node/dgram.d.ts","../node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/@types/node/dns.d.ts","../node_modules/@types/node/dns/promises.d.ts","../node_modules/@types/node/domain.d.ts","../node_modules/@types/node/dom-events.d.ts","../node_modules/@types/node/events.d.ts","../node_modules/@types/node/fs.d.ts","../node_modules/@types/node/fs/promises.d.ts","../node_modules/@types/node/http.d.ts","../node_modules/@types/node/http2.d.ts","../node_modules/@types/node/https.d.ts","../node_modules/@types/node/inspector.d.ts","../node_modules/@types/node/module.d.ts","../node_modules/@types/node/net.d.ts","../node_modules/@types/node/os.d.ts","../node_modules/@types/node/path.d.ts","../node_modules/@types/node/perf_hooks.d.ts","../node_modules/@types/node/process.d.ts","../node_modules/@types/node/punycode.d.ts","../node_modules/@types/node/querystring.d.ts","../node_modules/@types/node/readline.d.ts","../node_modules/@types/node/readline/promises.d.ts","../node_modules/@types/node/repl.d.ts","../node_modules/@types/node/sea.d.ts","../node_modules/@types/node/sqlite.d.ts","../node_modules/@types/node/stream.d.ts","../node_modules/@types/node/stream/promises.d.ts","../node_modules/@types/node/stream/consumers.d.ts","../node_modules/@types/node/stream/web.d.ts","../node_modules/@types/node/string_decoder.d.ts","../node_modules/@types/node/test.d.ts","../node_modules/@types/node/timers.d.ts","../node_modules/@types/node/timers/promises.d.ts","../node_modules/@types/node/tls.d.ts","../node_modules/@types/node/trace_events.d.ts","../node_modules/@types/node/tty.d.ts","../node_modules/@types/node/url.d.ts","../node_modules/@types/node/util.d.ts","../node_modules/@types/node/v8.d.ts","../node_modules/@types/node/vm.d.ts","../node_modules/@types/node/wasi.d.ts","../node_modules/@types/node/worker_threads.d.ts","../node_modules/@types/node/zlib.d.ts","../node_modules/@types/node/index.d.ts","../../../node_modules/@types/unist/index.d.ts","../../../node_modules/@types/hast/index.d.ts"],"fileIdsList":[[93,135,186],[93,135],[85,93,135],[81,82,93,135],[81,83,93,135],[84,86,93,135],[93,132,135],[93,134,135],[135],[93,135,140,170],[93,135,136,141,147,148,155,167,178],[93,135,136,137,147,155],[88,89,90,93,135],[93,135,138,179],[93,135,139,140,148,156],[93,135,140,167,175],[93,135,141,143,147,155],[93,134,135,142],[93,135,143,144],[93,135,147],[93,135,145,147],[93,134,135,147],[93,135,147,148,149,167,178],[93,135,147,148,149,162,167,170],[93,130,135,183],[93,130,135,143,147,150,155,167,178],[93,135,147,148,150,151,155,167,175,178],[93,135,150,152,167,175,178],[91,92,93,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184],[93,135,147,153],[93,135,154,178],[93,135,143,147,155,167],[93,135,156],[93,135,157],[93,134,135,158],[93,132,133,134,135,136,137,138,139,140,141,142,143,144,145,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184],[93,135,160],[93,135,161],[93,135,147,162,163],[93,135,162,164,179,181],[93,135,147,167,168,170],[93,135,169,170],[93,135,167,168],[93,135,170],[93,135,171],[93,132,135,167],[93,135,147,173,174],[93,135,173,174],[93,135,140,155,167,175],[93,135,176],[93,135,155,177],[93,135,150,161,178],[93,135,140,179],[93,135,167,180],[93,135,154,181],[93,135,182],[93,135,140,147,149,158,167,178,181,183],[93,135,167,184],[93,102,106,135,178],[93,102,135,167,178],[93,97,135],[93,99,102,135,175,178],[93,135,155,175],[93,135,185],[93,97,135,185],[93,99,102,135,155,178],[93,94,95,98,101,135,147,167,178],[93,102,109,135],[93,94,100,135],[93,102,123,124,135],[93,98,102,135,170,178,185],[93,123,135,185],[93,96,97,135,185],[93,102,135],[93,96,97,98,99,100,101,102,103,104,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,124,125,126,127,128,129,135],[93,102,117,135],[93,102,109,110,135],[93,100,102,110,111,135],[93,101,135],[93,94,97,102,135],[93,102,106,110,111,135],[93,106,135],[93,100,102,105,135,178],[93,94,99,102,109,135],[93,135,167],[93,97,102,123,135,183,185],[82,85,93,135,150,152,155,157]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"8bf8b5e44e3c9c36f98e1007e8b7018c0f38d8adc07aecef42f5200114547c70","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"4245fee526a7d1754529d19227ecbf3be066ff79ebb6a380d78e41648f2f224d","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"5d006d8b45d30424b431931093b1d3bd8ca2d50aff8875f652f64c7d2d30041a","affectsGlobalScope":true,"impliedFormat":99},{"version":"dd7ca4f0ef3661dac7043fb2cdf1b99e008d2b6bc5cd998dd1fa5a2968034984","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d15813486c529d074c786f90887c611a9d9944a753b1985722a722ef7fcad21","signature":"30843d84ec4455dc5e9c92a007eccd4f5364558dffcc820de9fee538a02aaaad","impliedFormat":99},{"version":"14fef03569ba9d005db95be6e9052234a58783f28da209000780ad85072019a0","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":99},{"version":"f5285cc1d0d9174aff020298b80825c1bce381db29046fcab61cc68df2adb6f9","impliedFormat":1},{"version":"406342a48423fae91e94d76de5ac04aff69e14cc523bebe1a45b03e2677c0fb4","signature":"50ddc2010e2cd7546fbf0a5d7b2a455859b2ea4892f1533fca91aaecc3503d69","impliedFormat":99},{"version":"f46fd2c7fc1f73362ac2dd172089614265d3609d64c89de9bb19288af9727c2e","signature":"1102cacef34051374be330f24bf689f91dc59e234d47365a1d716d61be70bf1c","impliedFormat":99},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"030e350db2525514580ed054f712ffb22d273e6bc7eddc1bb7eda1e0ba5d395e","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"d802f0e6b5188646d307f070d83512e8eb94651858de8a82d1e47f60fb6da4e2","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"88d9a77d2abc23a7d26625dd6dae5b57199a8693b85c9819355651c9d9bab90f","affectsGlobalScope":true,"impliedFormat":1},{"version":"a38efe83ff77c34e0f418a806a01ca3910c02ee7d64212a59d59bca6c2c38fa1","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"3fe4022ba1e738034e38ad9afacbf0f1f16b458ed516326f5bf9e4a31e9be1dc","impliedFormat":1},{"version":"a957197054b074bcdf5555d26286e8461680c7c878040d0f4e2d5509a7524944","affectsGlobalScope":true,"impliedFormat":1},{"version":"4314c7a11517e221f7296b46547dbc4df047115b182f544d072bdccffa57fc72","impliedFormat":1},{"version":"e9b97d69510658d2f4199b7d384326b7c4053b9e6645f5c19e1c2a54ede427fc","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"f478f6f5902dc144c0d6d7bdc919c5177cac4d17a8ca8653c2daf6d7dc94317f","affectsGlobalScope":true,"impliedFormat":1},{"version":"19d5f8d3930e9f99aa2c36258bf95abbe5adf7e889e6181872d1cdba7c9a7dd5","impliedFormat":1},{"version":"b200675fd112ffef97c166d0341fb33f6e29e9f27660adde7868e95c5bc98beb","impliedFormat":1},{"version":"a6bf63d17324010ca1fbf0389cab83f93389bb0b9a01dc8a346d092f65b3605f","impliedFormat":1},{"version":"e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"ee1ee365d88c4c6c0c0a5a5701d66ebc27ccd0bcfcfaa482c6e2e7fe7b98edf7","affectsGlobalScope":true,"impliedFormat":1},{"version":"88bc59b32d0d5b4e5d9632ac38edea23454057e643684c3c0b94511296f2998c","affectsGlobalScope":true,"impliedFormat":1},{"version":"a0a1dda070290b92da5a50113b73ecc4dd6bcbffad66e3c86503d483eafbadcf","impliedFormat":1},{"version":"59dcad36c4549175a25998f6a8b33c1df8e18df9c12ebad1dfb25af13fd4b1ce","impliedFormat":1},{"version":"9ba5b6a30cb7961b68ad4fb18dca148db151c2c23b8d0a260fc18b83399d19d3","impliedFormat":1},{"version":"3f3edb8e44e3b9df3b7ca3219ab539710b6a7f4fe16bd884d441af207e03cd57","impliedFormat":1},{"version":"528b62e4272e3ddfb50e8eed9e359dedea0a4d171c3eb8f337f4892aac37b24b","impliedFormat":1},{"version":"d71535813e39c23baa113bc4a29a0e187b87d1105ccc8c5a6ebaca38d9a9bff2","impliedFormat":1},{"version":"8cf7e92bdb2862c2d28ba4535c43dc599cfbc0025db5ed9973d9b708dcbe3d98","affectsGlobalScope":true,"impliedFormat":1},{"version":"278e70975bd456bba5874eaee17692355432e8d379b809a97f6af0eee2b702d8","impliedFormat":1},{"version":"b1b6ee0d012aeebe11d776a155d8979730440082797695fc8e2a5c326285678f","impliedFormat":1},{"version":"45875bcae57270aeb3ebc73a5e3fb4c7b9d91d6b045f107c1d8513c28ece71c0","impliedFormat":1},{"version":"1dc73f8854e5c4506131c4d95b3a6c24d0c80336d3758e95110f4c7b5cb16397","affectsGlobalScope":true,"impliedFormat":1},{"version":"636302a00dfd1f9fe6e8e91e4e9350c6518dcc8d51a474e4fc3a9ba07135100b","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"e1120271ebbc9952fdc7b2dd3e145560e52e06956345e6fdf91d70ca4886464f","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"e1ce1d622f1e561f6cdf246372ead3bbc07ce0342024d0e9c7caf3136f712698","impliedFormat":1},{"version":"c878f74b6d10b267f6075c51ac1d8becd15b4aa6a58f79c0cfe3b24908357f60","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"125d792ec6c0c0f657d758055c494301cc5fdb327d9d9d5960b3f129aff76093","impliedFormat":1},{"version":"27e4532aaaa1665d0dd19023321e4dc12a35a741d6b8e1ca3517fcc2544e0efe","affectsGlobalScope":true,"impliedFormat":1},{"version":"2754d8221d77c7b382096651925eb476f1066b3348da4b73fe71ced7801edada","impliedFormat":1},{"version":"8c2ad42d5d1a2e8e6112625767f8794d9537f1247907378543106f7ba6c7df90","affectsGlobalScope":true,"impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"98ffdf93dfdd206516971d28e3e473f417a5cfd41172e46b4ce45008f640588e","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"7d6ff413e198d25639f9f01f16673e7df4e4bd2875a42455afd4ecc02ef156da","affectsGlobalScope":true,"impliedFormat":1},{"version":"12e8ce658dd17662d82fb0509d2057afc5e6ee30369a2e9e0957eff725b1f11d","affectsGlobalScope":true,"impliedFormat":1},{"version":"74736930d108365d7bbe740c7154706ccfb1b2a3855a897963ab3e5c07ecbf19","impliedFormat":1},{"version":"858f999b3e4a45a4e74766d43030941466460bf8768361d254234d5870480a53","impliedFormat":1},{"version":"ac5ed35e649cdd8143131964336ab9076937fa91802ec760b3ea63b59175c10a","impliedFormat":1},{"version":"63b05afa6121657f25e99e1519596b0826cda026f09372c9100dfe21417f4bd6","affectsGlobalScope":true,"impliedFormat":1},{"version":"3797dd6f4ea3dc15f356f8cdd3128bfa18122213b38a80d6c1f05d8e13cbdad8","impliedFormat":1},{"version":"ad90122e1cb599b3bc06a11710eb5489101be678f2920f2322b0ac3e195af78d","impliedFormat":1},{"version":"89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","impliedFormat":1},{"version":"79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","impliedFormat":1}],"root":[81,83,84,86,87],"options":{"alwaysStrict":true,"checkJs":true,"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":true,"esModuleInterop":false,"jsx":4,"module":199,"newLine":1,"noFallthroughCasesInSwitch":true,"noImplicitOverride":false,"noUncheckedIndexedAccess":true,"outDir":"./","skipDefaultLibCheck":true,"skipLibCheck":true,"sourceMap":true,"strict":true,"target":99,"useUnknownInCatchVariables":true},"referencedMap":[[187,1],[186,2],[82,2],[85,3],[79,2],[80,2],[13,2],[14,2],[16,2],[15,2],[2,2],[17,2],[18,2],[19,2],[20,2],[21,2],[22,2],[23,2],[24,2],[3,2],[25,2],[26,2],[4,2],[27,2],[31,2],[28,2],[29,2],[30,2],[32,2],[33,2],[34,2],[5,2],[35,2],[36,2],[37,2],[38,2],[6,2],[42,2],[39,2],[40,2],[41,2],[43,2],[7,2],[44,2],[49,2],[50,2],[45,2],[46,2],[47,2],[48,2],[8,2],[54,2],[51,2],[52,2],[53,2],[55,2],[9,2],[56,2],[57,2],[58,2],[60,2],[59,2],[61,2],[62,2],[10,2],[63,2],[64,2],[65,2],[11,2],[66,2],[67,2],[68,2],[69,2],[70,2],[1,2],[71,2],[72,2],[12,2],[76,2],[74,2],[78,2],[73,2],[77,2],[75,2],[83,4],[84,5],[81,2],[87,6],[132,7],[133,7],[134,8],[93,9],[135,10],[136,11],[137,12],[88,2],[91,13],[89,2],[90,2],[138,14],[139,15],[140,16],[141,17],[142,18],[143,19],[144,19],[146,20],[145,21],[147,22],[148,23],[149,24],[131,25],[92,2],[150,26],[151,27],[152,28],[185,29],[153,30],[154,31],[155,32],[156,33],[157,34],[158,35],[159,36],[160,37],[161,38],[162,39],[163,39],[164,40],[165,2],[166,2],[167,41],[169,42],[168,43],[170,44],[171,45],[172,46],[173,47],[174,48],[175,49],[176,50],[177,51],[178,52],[179,53],[180,54],[181,55],[182,56],[183,57],[184,58],[109,59],[119,60],[108,59],[129,61],[100,62],[99,63],[128,64],[122,65],[127,66],[102,67],[116,68],[101,69],[125,70],[97,71],[96,64],[126,72],[98,73],[103,74],[104,2],[107,74],[94,2],[130,75],[120,76],[111,77],[112,78],[114,79],[110,80],[113,81],[123,64],[105,82],[106,83],[115,84],[95,85],[118,76],[117,74],[121,2],[124,86],[86,87]],"latestChangedDtsFile":"./index.d.ts","version":"5.8.3"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@goauthentik/esbuild-plugin-live-reload",
3
+ "version": "1.0.5",
4
+ "description": "ESBuild + browser refresh. Build completes, page reloads.",
5
+ "license": "MIT",
6
+ "scripts": {
7
+ "build": "npm run build:types && npm run build:docs",
8
+ "build:docs": "typedoc",
9
+ "build:types": "tsc -p .",
10
+ "prettier": "prettier --cache --write -u .",
11
+ "prettier-check": "prettier --cache --check -u ."
12
+ },
13
+ "main": "index.js",
14
+ "type": "module",
15
+ "exports": {
16
+ "./package.json": "./package.json",
17
+ ".": {
18
+ "types": "./out/index.d.ts",
19
+ "import": "./index.js"
20
+ },
21
+ "./client": {
22
+ "types": "./out/client/index.d.ts",
23
+ "import": "./client/index.js"
24
+ },
25
+ "./plugin": {
26
+ "types": "./out/plugin/index.d.ts",
27
+ "import": "./plugin/index.js"
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "find-free-ports": "^3.1.1"
32
+ },
33
+ "devDependencies": {
34
+ "@goauthentik/prettier-config": "^1.0.5",
35
+ "@goauthentik/tsconfig": "^1.0.4",
36
+ "@trivago/prettier-plugin-sort-imports": "^5.2.2",
37
+ "@types/node": "^22.15.21",
38
+ "esbuild": "^0.25.4",
39
+ "prettier": "^3.5.3",
40
+ "prettier-plugin-packagejson": "^2.5.14",
41
+ "typedoc": "^0.28.5",
42
+ "typedoc-plugin-markdown": "^4.6.3",
43
+ "typescript": "^5.8.3"
44
+ },
45
+ "peerDependencies": {
46
+ "esbuild": "^0.25.4"
47
+ },
48
+ "engines": {
49
+ "node": ">=22"
50
+ },
51
+ "keywords": [
52
+ "esbuild",
53
+ "live-reload",
54
+ "browser",
55
+ "refresh",
56
+ "reload",
57
+ "authentik"
58
+ ],
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/goauthentik/authentik.git",
62
+ "directory": "web/packages/esbuild-plugin-live-reload"
63
+ },
64
+ "types": "./out/index.d.ts",
65
+ "files": [
66
+ "./index.js",
67
+ "client/**/*",
68
+ "plugin/**/*",
69
+ "out/**/*"
70
+ ],
71
+ "prettier": "@goauthentik/prettier-config",
72
+ "publishConfig": {
73
+ "access": "public"
74
+ }
75
+ }
@@ -0,0 +1,265 @@
1
+ /**
2
+ * @file Live reload plugin for ESBuild.
3
+ *
4
+ * @import { ListenOptions } from "node:net";
5
+ * @import {Server as HTTPServer} from "node:http";
6
+ * @import {Server as HTTPSServer} from "node:https";
7
+ */
8
+ import { findFreePorts } from "find-free-ports";
9
+ import * as http from "node:http";
10
+ import { resolve as resolvePath } from "node:path";
11
+
12
+ /**
13
+ * Serializes a custom event to a text stream.
14
+ *
15
+ * @param {Event} event
16
+ * @returns {string}
17
+ *
18
+ * @category Server API
19
+ * @ignore
20
+ * @internal
21
+ * @runtime node
22
+ */
23
+ export function serializeCustomEventToStream(event) {
24
+ // @ts-expect-error - TS doesn't know about the detail property
25
+ const data = event.detail ?? {};
26
+
27
+ const eventContent = [`event: ${event.type}`, `data: ${JSON.stringify(data)}`];
28
+
29
+ return eventContent.join("\n") + "\n\n";
30
+ }
31
+
32
+ const MIN_PORT = 1025;
33
+ const MAX_PORT = 65535;
34
+
35
+ /**
36
+ * Find a random port that is not in use, sufficiently far from the default port.
37
+ * @returns {Promise<number>}
38
+ */
39
+ async function findDisparatePort() {
40
+ const startPort = Math.floor(Math.random() * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT;
41
+
42
+ const wathcherPorts = await findFreePorts(1, {
43
+ startPort,
44
+ });
45
+
46
+ const [port] = wathcherPorts;
47
+
48
+ if (!port) {
49
+ throw new Error("No free ports available");
50
+ }
51
+
52
+ return port;
53
+ }
54
+
55
+ /**
56
+ * Event server initialization options.
57
+ *
58
+ * @typedef {Object} EventServerInit
59
+ *
60
+ * @property {string} pathname
61
+ * @property {EventTarget} dispatcher
62
+ * @property {string} [logPrefix]
63
+ *
64
+ * @category Server API
65
+ * @runtime node
66
+ */
67
+
68
+ /**
69
+ * @typedef {(req: http.IncomingMessage, res: http.ServerResponse) => void} RequestHandler
70
+ *
71
+ * @category Server API
72
+ * @runtime node
73
+ */
74
+
75
+ /**
76
+ * Create an event request handler.
77
+ *
78
+ * @param {EventServerInit} options
79
+ * @returns {RequestHandler}
80
+ *
81
+ * @category Server API
82
+ * @runtime node
83
+ */
84
+ export function createRequestHandler({ pathname, dispatcher, logPrefix = "Build Observer" }) {
85
+ const log = console.log.bind(console, `[${logPrefix}]`);
86
+
87
+ /**
88
+ * @type {RequestHandler}
89
+ */
90
+ const requestHandler = (req, res) => {
91
+ res.setHeader("Access-Control-Allow-Origin", "*");
92
+ res.setHeader("Access-Control-Allow-Methods", "GET");
93
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
94
+
95
+ if (req.url !== pathname) {
96
+ log(`🚫 Invalid request to ${req.url}`);
97
+ res.writeHead(404);
98
+ res.end();
99
+ return;
100
+ }
101
+
102
+ log("🔌 Client connected");
103
+
104
+ res.writeHead(200, {
105
+ "Content-Type": "text/event-stream",
106
+ "Cache-Control": "no-cache",
107
+ "Connection": "keep-alive",
108
+ });
109
+
110
+ /**
111
+ * @param {Event} event
112
+ */
113
+ const listener = (event) => {
114
+ const body = serializeCustomEventToStream(event);
115
+
116
+ res.write(body);
117
+ };
118
+
119
+ dispatcher.addEventListener("esbuild:start", listener);
120
+ dispatcher.addEventListener("esbuild:error", listener);
121
+ dispatcher.addEventListener("esbuild:end", listener);
122
+
123
+ req.on("close", () => {
124
+ log("🔌 Client disconnected");
125
+
126
+ clearInterval(keepAliveInterval);
127
+
128
+ dispatcher.removeEventListener("esbuild:start", listener);
129
+ dispatcher.removeEventListener("esbuild:error", listener);
130
+ dispatcher.removeEventListener("esbuild:end", listener);
131
+ });
132
+
133
+ const keepAliveInterval = setInterval(() => {
134
+ console.timeStamp("🏓 Keep-alive");
135
+
136
+ res.write("event: keep-alive\n\n");
137
+ res.write(serializeCustomEventToStream(new CustomEvent("esbuild:keep-alive")));
138
+ }, 15_000);
139
+ };
140
+
141
+ return requestHandler;
142
+ }
143
+
144
+ /**
145
+ * Options for the build observer plugin.
146
+ *
147
+ * @category Plugin API
148
+ * @runtime node
149
+ *
150
+ * @typedef {object} LiveReloadPluginOptions
151
+ *
152
+ * @property {HTTPServer | HTTPSServer} [server] A server to listen on. If not provided, a new server will be created.
153
+ * @property {ListenOptions} [listenOptions] Options for the server's listen method.
154
+ * @property {string | URL} [publicURL] A URL to listen on. If not provided, a random port will be used.
155
+ * @property {string} [logPrefix] A prefix to use for log messages.
156
+ * @property {string} [relativeRoot] A relative path to the root of the project. This is used to resolve build errors, line numbers, and file paths.
157
+ */
158
+
159
+ /**
160
+ * Creates a plugin that listens for build events and sends them to a server-sent event stream.
161
+ *
162
+ * @param {LiveReloadPluginOptions} [options]
163
+ * @returns {import('esbuild').Plugin}
164
+ */
165
+ export function liveReloadPlugin(options = {}) {
166
+ return {
167
+ name: "build-watcher",
168
+ setup: async (build) => {
169
+ const logPrefix = options.logPrefix || "Build Observer";
170
+
171
+ const timerLabel = `[${logPrefix}] 🏁`;
172
+ const relativeRoot = options.relativeRoot || process.cwd();
173
+
174
+ const dispatcher = new EventTarget();
175
+
176
+ /**
177
+ * @type {URL}
178
+ */
179
+ let publicURL;
180
+
181
+ if (!options.publicURL) {
182
+ const port = await findDisparatePort();
183
+
184
+ publicURL = new URL(`http://localhost:${port}/events`);
185
+ } else {
186
+ publicURL =
187
+ typeof options.publicURL === "string"
188
+ ? new URL(options.publicURL)
189
+ : options.publicURL;
190
+ }
191
+
192
+ build.initialOptions.define = {
193
+ ...build.initialOptions.define,
194
+ "import.meta.env.ESBUILD_WATCHER_URL": JSON.stringify(publicURL.href),
195
+ };
196
+
197
+ build.initialOptions.define["process.env.NODE_ENV"] ??= JSON.stringify(
198
+ process.env.NODE_ENV || "development",
199
+ );
200
+
201
+ const requestHandler = createRequestHandler({
202
+ pathname: publicURL.pathname,
203
+ dispatcher,
204
+ logPrefix,
205
+ });
206
+
207
+ const server = options.server || http.createServer(requestHandler);
208
+
209
+ const listenOptions = options.listenOptions || {
210
+ port: parseInt(publicURL.port, 10),
211
+ host: publicURL.hostname,
212
+ };
213
+
214
+ server.listen(listenOptions, () => {
215
+ console.log(`[${logPrefix}] Listening`);
216
+ });
217
+
218
+ build.onDispose(() => {
219
+ server?.close();
220
+ });
221
+
222
+ build.onStart(() => {
223
+ console.time(timerLabel);
224
+
225
+ dispatcher.dispatchEvent(
226
+ new CustomEvent("esbuild:start", {
227
+ detail: new Date().toISOString(),
228
+ }),
229
+ );
230
+ });
231
+
232
+ build.onEnd((buildResult) => {
233
+ console.timeEnd(timerLabel);
234
+
235
+ if (!buildResult.errors.length) {
236
+ dispatcher.dispatchEvent(
237
+ new CustomEvent("esbuild:end", {
238
+ detail: new Date().toISOString(),
239
+ }),
240
+ );
241
+
242
+ return;
243
+ }
244
+
245
+ console.warn(`Build ended with ${buildResult.errors.length} errors`);
246
+
247
+ dispatcher.dispatchEvent(
248
+ new CustomEvent("esbuild:error", {
249
+ detail: buildResult.errors.map((error) => ({
250
+ ...error,
251
+ location: error.location
252
+ ? {
253
+ ...error.location,
254
+ file: resolvePath(relativeRoot, error.location.file),
255
+ }
256
+ : null,
257
+ })),
258
+ }),
259
+ );
260
+ });
261
+ },
262
+ };
263
+ }
264
+
265
+ export default liveReloadPlugin;