@eighty4/dank 0.0.4-2 → 0.0.4-3
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/client/client.js +1 -0
- package/lib/bin.ts +8 -11
- package/lib/build.ts +43 -70
- package/lib/build_tag.ts +3 -3
- package/lib/config.ts +184 -29
- package/lib/dank.ts +7 -0
- package/lib/define.ts +6 -4
- package/lib/developer.ts +33 -4
- package/lib/dirs.ts +83 -0
- package/lib/errors.ts +6 -0
- package/lib/esbuild.ts +19 -29
- package/lib/flags.ts +16 -122
- package/lib/html.ts +196 -112
- package/lib/http.ts +59 -43
- package/lib/public.ts +10 -10
- package/lib/{metadata.ts → registry.ts} +216 -83
- package/lib/serve.ts +101 -336
- package/lib/services.ts +8 -8
- package/lib/watch.ts +39 -0
- package/lib_js/bin.js +8 -10
- package/lib_js/build.js +31 -45
- package/lib_js/build_tag.js +2 -2
- package/lib_js/config.js +108 -29
- package/lib_js/define.js +3 -3
- package/lib_js/dirs.js +61 -0
- package/lib_js/errors.js +9 -0
- package/lib_js/esbuild.js +17 -19
- package/lib_js/flags.js +9 -98
- package/lib_js/html.js +127 -64
- package/lib_js/http.js +18 -18
- package/lib_js/public.js +9 -9
- package/lib_js/{metadata.js → registry.js} +121 -51
- package/lib_js/serve.js +53 -177
- package/lib_js/services.js +6 -6
- package/lib_js/watch.js +35 -0
- package/lib_types/dank.d.ts +5 -0
- package/package.json +6 -4
- package/client/esbuild.js +0 -1
package/lib_js/serve.js
CHANGED
|
@@ -1,148 +1,61 @@
|
|
|
1
|
-
import { mkdir,
|
|
2
|
-
import { extname, join
|
|
1
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
3
|
import { buildWebsite } from "./build.js";
|
|
4
4
|
import { loadConfig } from "./config.js";
|
|
5
5
|
import { createGlobalDefinitions } from "./define.js";
|
|
6
6
|
import { esbuildDevContext } from "./esbuild.js";
|
|
7
|
-
import { resolveServeFlags } from "./flags.js";
|
|
8
|
-
import { HtmlEntrypoint } from "./html.js";
|
|
9
7
|
import { createBuiltDistFilesFetcher, createDevServeFilesFetcher, startWebServer } from "./http.js";
|
|
10
|
-
import { WebsiteRegistry } from "./
|
|
8
|
+
import { WebsiteRegistry } from "./registry.js";
|
|
11
9
|
import { startDevServices, updateDevServices } from "./services.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import { watch } from "./watch.js";
|
|
11
|
+
let c;
|
|
12
|
+
async function serveWebsite() {
|
|
13
|
+
c = await loadConfig("serve", process.cwd());
|
|
14
|
+
await rm(c.dirs.buildRoot, { force: true, recursive: true });
|
|
15
15
|
const abortController = new AbortController();
|
|
16
16
|
process.once("exit", () => abortController.abort());
|
|
17
|
-
if (
|
|
18
|
-
await startPreviewMode(
|
|
17
|
+
if (c.flags.preview) {
|
|
18
|
+
await startPreviewMode(abortController.signal);
|
|
19
19
|
} else {
|
|
20
|
-
await startDevMode(
|
|
20
|
+
await startDevMode(abortController.signal);
|
|
21
21
|
}
|
|
22
22
|
return new Promise(() => {
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
async function startPreviewMode(
|
|
25
|
+
async function startPreviewMode(signal) {
|
|
26
26
|
const manifest = await buildWebsite(c);
|
|
27
|
-
const frontend = createBuiltDistFilesFetcher(
|
|
28
|
-
const devServices = startDevServices(c, signal);
|
|
29
|
-
|
|
30
|
-
urls: Object.keys(c.pages),
|
|
31
|
-
urlRewrites: collectUrlRewrites(c)
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
function collectUrlRewrites(c) {
|
|
35
|
-
return Object.keys(c.pages).sort().map((url) => {
|
|
27
|
+
const frontend = createBuiltDistFilesFetcher(c.dirs, manifest);
|
|
28
|
+
const devServices = startDevServices(c.services, signal);
|
|
29
|
+
const urlRewrites = Object.keys(c.pages).sort().map((url) => {
|
|
36
30
|
const mapping = c.pages[url];
|
|
37
31
|
return typeof mapping !== "object" || !mapping.pattern ? null : { url, pattern: mapping.pattern };
|
|
38
32
|
}).filter((mapping) => mapping !== null);
|
|
33
|
+
startWebServer(c.dankPort, c.flags, c.dirs, { urlRewrites }, frontend, devServices.http);
|
|
39
34
|
}
|
|
40
|
-
async function startDevMode(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const clientJS = await loadClientJS(serve.esbuildPort);
|
|
44
|
-
const pagesByUrlPath = {};
|
|
45
|
-
const partialsByUrlPath = {};
|
|
46
|
-
const entryPointsByUrlPath = {};
|
|
35
|
+
async function startDevMode(signal) {
|
|
36
|
+
const registry = new WebsiteRegistry(c);
|
|
37
|
+
await mkdir(c.dirs.buildWatch, { recursive: true });
|
|
47
38
|
let buildContext = null;
|
|
48
|
-
registry.on("workers", () => {
|
|
49
|
-
resetBuildContext();
|
|
50
|
-
});
|
|
51
39
|
watch("dank.config.ts", signal, async () => {
|
|
52
|
-
let updated;
|
|
53
40
|
try {
|
|
54
|
-
|
|
41
|
+
await c.reload();
|
|
55
42
|
} catch (ignore) {
|
|
56
43
|
return;
|
|
57
44
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
c.pages[urlPath] = mapping;
|
|
61
|
-
const srcPath = typeof mapping === "string" ? mapping : mapping.webpage;
|
|
62
|
-
if (!pagesByUrlPath[urlPath]) {
|
|
63
|
-
await addPage(urlPath, srcPath);
|
|
64
|
-
} else {
|
|
65
|
-
prevPages.delete(urlPath);
|
|
66
|
-
if (pagesByUrlPath[urlPath].fsPath !== srcPath) {
|
|
67
|
-
await updatePage(urlPath);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}));
|
|
71
|
-
for (const prevPage of Array.from(prevPages)) {
|
|
72
|
-
delete c.pages[prevPage];
|
|
73
|
-
deletePage(prevPage);
|
|
74
|
-
}
|
|
75
|
-
updateDevServices(updated);
|
|
45
|
+
registry.configSync();
|
|
46
|
+
updateDevServices(c.services);
|
|
76
47
|
});
|
|
77
|
-
watch(
|
|
48
|
+
watch(c.dirs.pages, signal, (filename) => {
|
|
78
49
|
if (extname(filename) === ".html") {
|
|
79
|
-
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
for (const [urlPath, partials] of Object.entries(partialsByUrlPath)) {
|
|
85
|
-
if (partials.includes(filename)) {
|
|
86
|
-
updatePage(urlPath, filename);
|
|
50
|
+
registry.htmlEntrypoints.forEach((html) => {
|
|
51
|
+
if (html.fsPath === filename) {
|
|
52
|
+
html.emit("change");
|
|
53
|
+
} else if (html.usesPartial(filename)) {
|
|
54
|
+
html.emit("change", filename);
|
|
87
55
|
}
|
|
88
|
-
}
|
|
56
|
+
});
|
|
89
57
|
}
|
|
90
58
|
});
|
|
91
|
-
await Promise.all(Object.entries(c.pages).map(async ([urlPath, mapping]) => {
|
|
92
|
-
const srcPath = typeof mapping === "string" ? mapping : mapping.webpage;
|
|
93
|
-
await addPage(urlPath, srcPath);
|
|
94
|
-
return new Promise((res) => pagesByUrlPath[urlPath].once("entrypoints", res));
|
|
95
|
-
}));
|
|
96
|
-
async function addPage(urlPath, srcPath) {
|
|
97
|
-
await mkdir(join(serve.dirs.buildWatch, urlPath), { recursive: true });
|
|
98
|
-
const htmlEntrypoint = pagesByUrlPath[urlPath] = new HtmlEntrypoint(serve, registry.resolver, urlPath, srcPath, [{ type: "script", js: clientJS }]);
|
|
99
|
-
htmlEntrypoint.on("entrypoints", (entrypoints) => {
|
|
100
|
-
const pathsIn = new Set(entrypoints.map((e) => e.in));
|
|
101
|
-
if (!entryPointsByUrlPath[urlPath] || !matchingEntrypoints(entryPointsByUrlPath[urlPath].pathsIn, pathsIn)) {
|
|
102
|
-
entryPointsByUrlPath[urlPath] = { entrypoints, pathsIn };
|
|
103
|
-
resetBuildContext();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
htmlEntrypoint.on("partial", (partial) => {
|
|
107
|
-
if (!partialsByUrlPath[urlPath]) {
|
|
108
|
-
partialsByUrlPath[urlPath] = [];
|
|
109
|
-
}
|
|
110
|
-
partialsByUrlPath[urlPath].push(partial);
|
|
111
|
-
});
|
|
112
|
-
htmlEntrypoint.on("partials", (partials) => {
|
|
113
|
-
partialsByUrlPath[urlPath] = partials;
|
|
114
|
-
});
|
|
115
|
-
htmlEntrypoint.on("output", (html) => {
|
|
116
|
-
const path = join(serve.dirs.buildWatch, urlPath, "index.html");
|
|
117
|
-
writeFile(path, html);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
function deletePage(urlPath) {
|
|
121
|
-
pagesByUrlPath[urlPath].removeAllListeners();
|
|
122
|
-
delete pagesByUrlPath[urlPath];
|
|
123
|
-
delete entryPointsByUrlPath[urlPath];
|
|
124
|
-
resetBuildContext();
|
|
125
|
-
}
|
|
126
|
-
async function updatePage(urlPath, partial) {
|
|
127
|
-
pagesByUrlPath[urlPath].emit("change", partial);
|
|
128
|
-
}
|
|
129
|
-
function collectEntrypoints() {
|
|
130
|
-
const unique = /* @__PURE__ */ new Set();
|
|
131
|
-
const pageBundles = Object.values(entryPointsByUrlPath).flatMap((entrypointState) => entrypointState.entrypoints).filter((entryPoint) => {
|
|
132
|
-
if (unique.has(entryPoint.in)) {
|
|
133
|
-
return false;
|
|
134
|
-
} else {
|
|
135
|
-
unique.add(entryPoint.in);
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
const workerBundles = registry.workerEntryPoints();
|
|
140
|
-
if (workerBundles) {
|
|
141
|
-
return [...pageBundles, ...workerBundles];
|
|
142
|
-
} else {
|
|
143
|
-
return pageBundles;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
59
|
function resetBuildContext() {
|
|
147
60
|
switch (buildContext) {
|
|
148
61
|
case "starting":
|
|
@@ -161,7 +74,7 @@ async function startDevMode(c, serve, signal) {
|
|
|
161
74
|
});
|
|
162
75
|
} else {
|
|
163
76
|
buildContext = "starting";
|
|
164
|
-
startEsbuildWatch(
|
|
77
|
+
startEsbuildWatch(registry).then((ctx) => {
|
|
165
78
|
if (buildContext === "dirty") {
|
|
166
79
|
buildContext = "disposing";
|
|
167
80
|
ctx.dispose().then(() => {
|
|
@@ -174,76 +87,39 @@ async function startDevMode(c, serve, signal) {
|
|
|
174
87
|
});
|
|
175
88
|
}
|
|
176
89
|
}
|
|
90
|
+
registry.on("webpage", (html) => {
|
|
91
|
+
html.on("error", (e) => console.log(`\x1B[31merror:\x1B[0m`, e.message));
|
|
92
|
+
html.on("output", (output) => writeHtml(html, output));
|
|
93
|
+
});
|
|
94
|
+
registry.on("workers", () => {
|
|
95
|
+
resetBuildContext();
|
|
96
|
+
});
|
|
97
|
+
registry.configSync();
|
|
98
|
+
await Promise.all(registry.htmlEntrypoints.map((html) => html.process()));
|
|
99
|
+
registry.on("entrypoints", () => resetBuildContext());
|
|
177
100
|
resetBuildContext();
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
},
|
|
182
|
-
get urlRewrites() {
|
|
183
|
-
return collectUrlRewrites(c);
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
const frontend = createDevServeFilesFetcher(pageRoutes, serve);
|
|
187
|
-
const devServices = startDevServices(c, signal);
|
|
188
|
-
startWebServer(serve, frontend, devServices.http, pageRoutes);
|
|
101
|
+
const frontend = createDevServeFilesFetcher(c.esbuildPort, c.dirs, registry);
|
|
102
|
+
const devServices = startDevServices(c.services, signal);
|
|
103
|
+
startWebServer(c.dankPort, c.flags, c.dirs, registry, frontend, devServices.http);
|
|
189
104
|
}
|
|
190
|
-
function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
for (const v in a) {
|
|
195
|
-
if (!b.has(v)) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
async function startEsbuildWatch(c, registry, serve, entryPoints) {
|
|
202
|
-
const ctx = await esbuildDevContext(serve, registry, createGlobalDefinitions(serve), entryPoints, c.esbuild);
|
|
105
|
+
async function startEsbuildWatch(registry) {
|
|
106
|
+
const entryPoints = registry.webpageAndWorkerEntryPoints;
|
|
107
|
+
const ctx = await esbuildDevContext(registry, createGlobalDefinitions(c), entryPoints);
|
|
203
108
|
await ctx.watch();
|
|
204
109
|
await ctx.serve({
|
|
205
110
|
host: "127.0.0.1",
|
|
206
|
-
port:
|
|
111
|
+
port: c.esbuildPort,
|
|
207
112
|
cors: {
|
|
208
|
-
origin: ["127.0.0.1", "localhost"].map((hostname) => `http://${hostname}:${
|
|
113
|
+
origin: ["127.0.0.1", "localhost"].map((hostname) => `http://${hostname}:${c.dankPort}`)
|
|
209
114
|
}
|
|
210
115
|
});
|
|
211
116
|
return ctx;
|
|
212
117
|
}
|
|
213
|
-
async function
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const delayFire = 90;
|
|
219
|
-
const timeout = 100;
|
|
220
|
-
let changes = {};
|
|
221
|
-
try {
|
|
222
|
-
for await (const { filename } of _watch(p, {
|
|
223
|
-
recursive: true,
|
|
224
|
-
signal
|
|
225
|
-
})) {
|
|
226
|
-
if (filename) {
|
|
227
|
-
if (!changes[filename]) {
|
|
228
|
-
const now = Date.now();
|
|
229
|
-
changes[filename] = now + delayFire;
|
|
230
|
-
setTimeout(() => {
|
|
231
|
-
const now2 = Date.now();
|
|
232
|
-
for (const [filename2, then] of Object.entries(changes)) {
|
|
233
|
-
if (then <= now2) {
|
|
234
|
-
fire(filename2);
|
|
235
|
-
delete changes[filename2];
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}, timeout);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
} catch (e) {
|
|
243
|
-
if (e.name !== "AbortError") {
|
|
244
|
-
throw e;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
118
|
+
async function writeHtml(html, output) {
|
|
119
|
+
const dir = join(c.dirs.buildWatch, html.url);
|
|
120
|
+
await mkdir(dir, { recursive: true });
|
|
121
|
+
const path = join(dir, "index.html");
|
|
122
|
+
await writeFile(path, output);
|
|
247
123
|
}
|
|
248
124
|
export {
|
|
249
125
|
serveWebsite
|
package/lib_js/services.js
CHANGED
|
@@ -3,10 +3,10 @@ import { basename, isAbsolute, resolve } from "node:path";
|
|
|
3
3
|
const running = [];
|
|
4
4
|
let signal;
|
|
5
5
|
let updating = null;
|
|
6
|
-
function startDevServices(
|
|
6
|
+
function startDevServices(services, _signal) {
|
|
7
7
|
signal = _signal;
|
|
8
|
-
if (
|
|
9
|
-
for (const s of
|
|
8
|
+
if (services?.length) {
|
|
9
|
+
for (const s of services) {
|
|
10
10
|
running.push({ s, process: startService(s) });
|
|
11
11
|
}
|
|
12
12
|
}
|
|
@@ -18,8 +18,8 @@ function startDevServices(c, _signal) {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
function updateDevServices(
|
|
22
|
-
if (!
|
|
21
|
+
function updateDevServices(services) {
|
|
22
|
+
if (!services?.length) {
|
|
23
23
|
if (running.length) {
|
|
24
24
|
if (updating === null) {
|
|
25
25
|
updating = { stopping: [], starting: [] };
|
|
@@ -39,7 +39,7 @@ function updateDevServices(c) {
|
|
|
39
39
|
}
|
|
40
40
|
const keep = [];
|
|
41
41
|
const next = [];
|
|
42
|
-
for (const s of
|
|
42
|
+
for (const s of services) {
|
|
43
43
|
let found = false;
|
|
44
44
|
for (let i = 0; i < running.length; i++) {
|
|
45
45
|
const p = running[i].s;
|
package/lib_js/watch.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { watch as createWatch } from "node:fs/promises";
|
|
2
|
+
async function watch(p, signal, fire) {
|
|
3
|
+
const delayFire = 90;
|
|
4
|
+
const timeout = 100;
|
|
5
|
+
let changes = {};
|
|
6
|
+
try {
|
|
7
|
+
for await (const { filename } of createWatch(p, {
|
|
8
|
+
recursive: true,
|
|
9
|
+
signal
|
|
10
|
+
})) {
|
|
11
|
+
if (filename) {
|
|
12
|
+
if (!changes[filename]) {
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
changes[filename] = now + delayFire;
|
|
15
|
+
setTimeout(() => {
|
|
16
|
+
const now2 = Date.now();
|
|
17
|
+
for (const [filename2, then] of Object.entries(changes)) {
|
|
18
|
+
if (then <= now2) {
|
|
19
|
+
fire(filename2);
|
|
20
|
+
delete changes[filename2];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, timeout);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
if (e.name !== "AbortError") {
|
|
29
|
+
throw e;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
watch
|
|
35
|
+
};
|
package/lib_types/dank.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Plugin as EsbuildPlugin } from 'esbuild';
|
|
|
2
2
|
export type DankConfig = {
|
|
3
3
|
esbuild?: EsbuildConfig;
|
|
4
4
|
pages: Record<`/${string}`, `${string}.html` | PageMapping>;
|
|
5
|
+
devPages?: Record<`/__${string}`, `${string}.html` | DevPageMapping>;
|
|
5
6
|
port?: number;
|
|
6
7
|
previewPort?: number;
|
|
7
8
|
services?: Array<DevService>;
|
|
@@ -10,6 +11,10 @@ export type PageMapping = {
|
|
|
10
11
|
pattern?: RegExp;
|
|
11
12
|
webpage: `${string}.html`;
|
|
12
13
|
};
|
|
14
|
+
export type DevPageMapping = {
|
|
15
|
+
label: string;
|
|
16
|
+
webpage: `${string}.html`;
|
|
17
|
+
};
|
|
13
18
|
export type DevService = {
|
|
14
19
|
command: string;
|
|
15
20
|
cwd?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eighty4/dank",
|
|
3
|
-
"version": "0.0.4-
|
|
3
|
+
"version": "0.0.4-3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Adam McKee Bennett <adam.be.g84d@gmail.com>",
|
|
@@ -37,18 +37,20 @@
|
|
|
37
37
|
"typescript": "^5.9.2"
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
|
-
"client/
|
|
40
|
+
"client/client.js",
|
|
41
41
|
"lib/*.ts",
|
|
42
42
|
"lib_js/*.js",
|
|
43
43
|
"lib_types/*.d.ts"
|
|
44
44
|
],
|
|
45
45
|
"scripts": {
|
|
46
|
-
"build": "
|
|
46
|
+
"build": "pnpm build:client && pnpm build:lib",
|
|
47
|
+
"build:client": "node scripts/build_client.ts",
|
|
48
|
+
"build:lib": "tsc && tsc -p tsconfig.exports.json",
|
|
47
49
|
"build:release": "pnpm build && ./scripts/prepare_release.ts",
|
|
48
50
|
"fmt": "prettier --write .",
|
|
49
51
|
"fmtcheck": "prettier --check .",
|
|
50
52
|
"test": "node --test \"test/**/*.test.ts\"",
|
|
51
53
|
"test:rebuild": "pnpm build && pnpm test",
|
|
52
|
-
"typecheck": "tsc --noEmit"
|
|
54
|
+
"typecheck": "tsc --noEmit && tsc -p tsconfig.client.json --noEmit"
|
|
53
55
|
}
|
|
54
56
|
}
|
package/client/esbuild.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
new EventSource("http://127.0.0.1:3995/esbuild").addEventListener("change",t=>{const{updated:i}=JSON.parse(t.data),e=new Set;for(const s of i)e.add(s);const c=Array.from(e).filter(s=>s.endsWith(".css"));if(c.length){console.log("esbuild css updates",c);const s={};for(const o of document.getElementsByTagName("link"))if(o.getAttribute("rel")==="stylesheet"){const n=new URL(o.href);(n.host=location.host)&&(s[n.pathname]=o)}let a=!1;for(const o of c){const n=s[o];if(n){const r=n.cloneNode();r.href=`${o}?${Math.random().toString(36).slice(2)}`,r.onload=()=>n.remove(),n.parentNode.insertBefore(r,n.nextSibling),a=!0}}a&&l()}if(c.length<e.size){const s=Array.from(e).filter(o=>!o.endsWith(".css")),a=new Set;for(const o of document.getElementsByTagName("script"))if(o.src.length){const n=new URL(o.src);(n.host=location.host)&&a.add(n.pathname)}s.some(o=>a.has(o))&&(console.log("esbuild js updates require reload"),p())}});function l(){const t=d("green","9999");t.style.opacity="0",t.animate([{opacity:0},{opacity:1},{opacity:1},{opacity:1},{opacity:.75},{opacity:.5},{opacity:.25},{opacity:0}],{duration:400,iterations:1,direction:"normal",easing:"linear"}),document.body.appendChild(t),Promise.all(t.getAnimations().map(i=>i.finished)).then(()=>t.remove())}function p(){const t=d("orange","9000");t.style.opacity="0",t.animate([{opacity:0},{opacity:1}],{duration:400,iterations:1,direction:"normal",easing:"ease-in"}),document.body.appendChild(t)}function d(t,i){const e=document.createElement("div");return e.style.border="6px dashed "+t,e.style.zIndex=i,e.style.position="fixed",e.style.top=e.style.left="1px",e.style.height=e.style.width="calc(100% - 2px)",e.style.boxSizing="border-box",e}export{l as addCssUpdateIndicator};
|