@sealcode/sealgen 0.17.14 → 0.17.16
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/@types/src/builders/colors-builder.d.ts +1 -1
- package/@types/src/notifier.d.ts +2 -1
- package/lib/build.js +1 -1
- package/lib/builders/colors-builder.js +204 -17
- package/lib/notifier.js +72 -1
- package/package.json +1 -1
- package/src/build.ts +1 -1
- package/src/builders/colors-builder.ts +210 -19
- package/src/notifier.ts +93 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Builder } from "./builder.js";
|
|
2
2
|
export declare const COLORS_TS_PATH = "src/back/colors.ts";
|
|
3
3
|
export declare const COLORS_CSS_PATH = "src/colors.css";
|
|
4
|
-
export declare const COLORS_HTML_PATH = "
|
|
4
|
+
export declare const COLORS_HTML_PATH = "public/dist/colors.html";
|
|
5
5
|
export declare class ColorsBuilder extends Builder {
|
|
6
6
|
getName(): string;
|
|
7
7
|
ownsFile(file_path: string): boolean;
|
package/@types/src/notifier.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare const APP_BACK_ALIVE_SIGNAL = "app-back-alive";
|
|
2
|
+
export declare function make_notifier(port: number, app_port: number): (message: string) => void;
|
package/lib/build.js
CHANGED
|
@@ -88,7 +88,7 @@ async function build(watch) {
|
|
|
88
88
|
if (watch) {
|
|
89
89
|
const watcher = chokidar.watch("src", { ignoreInitial: true });
|
|
90
90
|
const port = await get_notifier_port();
|
|
91
|
-
const notifier = make_notifier(port);
|
|
91
|
+
const notifier = make_notifier(port, 8080);
|
|
92
92
|
await write_notifier_config(watch, port);
|
|
93
93
|
watcher.on("all", (_, file_path) => {
|
|
94
94
|
console.log("Detected a change!", file_path);
|
|
@@ -6,9 +6,10 @@ import { colord } from "colord";
|
|
|
6
6
|
import { formatWithPrettier } from "../utils/prettier.js";
|
|
7
7
|
import { Builder } from "./builder.js";
|
|
8
8
|
import { exec } from "../utils/exec.js";
|
|
9
|
+
import { APP_BACK_ALIVE_SIGNAL } from "../notifier.js";
|
|
9
10
|
const COLORS_TS_PATH = "src/back/colors.ts";
|
|
10
11
|
const COLORS_CSS_PATH = "src/colors.css";
|
|
11
|
-
const COLORS_HTML_PATH = "
|
|
12
|
+
const COLORS_HTML_PATH = "public/dist/colors.html";
|
|
12
13
|
class ColorsBuilder extends Builder {
|
|
13
14
|
getName() {
|
|
14
15
|
return "colors";
|
|
@@ -72,15 +73,18 @@ class ColorsBuilder extends Builder {
|
|
|
72
73
|
group_name,
|
|
73
74
|
is_main = false
|
|
74
75
|
}) {
|
|
76
|
+
const c = colord(color);
|
|
75
77
|
return (
|
|
76
78
|
/* HTML */
|
|
77
79
|
`<div
|
|
78
|
-
class="color-box ${
|
|
80
|
+
class="color-box ${c.isDark() ? "is-dark" : ""} ${is_main ? "is-main" : ""} ${c.toHsl().l > 90 ? "is-almost-white" : ""}"
|
|
79
81
|
style="background-color: ${color}; order: ${parseInt(shade_no)}"
|
|
80
82
|
data-color-name="${name}"
|
|
81
83
|
data-color-group-name="${group_name}"
|
|
82
84
|
data-color-shade-number="${shade_no}"
|
|
83
|
-
|
|
85
|
+
>
|
|
86
|
+
<span class="hex">${c.toHex()}</span>
|
|
87
|
+
</div>`
|
|
84
88
|
);
|
|
85
89
|
}
|
|
86
90
|
for (const group_name of Object.keys(color_groups).sort(
|
|
@@ -126,11 +130,28 @@ class ColorsBuilder extends Builder {
|
|
|
126
130
|
}`,
|
|
127
131
|
"css"
|
|
128
132
|
);
|
|
133
|
+
function makeDemoPair(fg, bg, text, classname = "") {
|
|
134
|
+
return (
|
|
135
|
+
/* HTML */
|
|
136
|
+
` <div
|
|
137
|
+
class="pair ${classname}"
|
|
138
|
+
data-fg="${fg}"
|
|
139
|
+
data-bg="${bg}"
|
|
140
|
+
style="background-color: ${bg}; color: ${fg}"
|
|
141
|
+
>
|
|
142
|
+
<span>${text}</span>
|
|
143
|
+
</div>`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
129
146
|
const html = await formatWithPrettier(
|
|
130
147
|
/* HTML */
|
|
131
148
|
`<!DOCTYPE html>
|
|
132
149
|
<html>
|
|
133
150
|
<head>
|
|
151
|
+
<title>Color palettes</title>
|
|
152
|
+
<style>
|
|
153
|
+
${css}
|
|
154
|
+
</style>
|
|
134
155
|
<style>
|
|
135
156
|
* {
|
|
136
157
|
font-family: sans-serif;
|
|
@@ -151,6 +172,10 @@ class ColorsBuilder extends Builder {
|
|
|
151
172
|
&:hover {
|
|
152
173
|
transform: scale(1.1);
|
|
153
174
|
z-index: 2;
|
|
175
|
+
|
|
176
|
+
.hex {
|
|
177
|
+
visibility: visible;
|
|
178
|
+
}
|
|
154
179
|
}
|
|
155
180
|
|
|
156
181
|
&.is-main {
|
|
@@ -159,22 +184,42 @@ class ColorsBuilder extends Builder {
|
|
|
159
184
|
margin-top: -8px;
|
|
160
185
|
box-shadow: 0px 0px 6px 2px white;
|
|
161
186
|
z-index: 1;
|
|
187
|
+
|
|
188
|
+
&:before {
|
|
189
|
+
font-weight: bold;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
&.is-almost-white.is-main {
|
|
194
|
+
box-shadow: 0px 0px 6px 1px #00000078;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.hex {
|
|
198
|
+
padding: 8px;
|
|
199
|
+
font-family: Menlo, Consolas, Monaco,
|
|
200
|
+
Liberation Mono, Lucida Console,
|
|
201
|
+
monospace;
|
|
202
|
+
opacity: 0.5;
|
|
203
|
+
visibility: hidden;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
&.is-dark .hex {
|
|
207
|
+
color: white;
|
|
162
208
|
}
|
|
163
209
|
}
|
|
164
210
|
|
|
165
|
-
.color-box:
|
|
211
|
+
.color-box:before {
|
|
166
212
|
content: attr(data-color-shade-number);
|
|
167
213
|
box-sizing: border-box;
|
|
168
214
|
display: block;
|
|
169
215
|
color: black;
|
|
170
216
|
font-size: 14px;
|
|
171
217
|
width: 100%;
|
|
172
|
-
height: 100%;
|
|
173
218
|
padding: 10px;
|
|
174
219
|
opacity: 0.3;
|
|
175
220
|
}
|
|
176
221
|
|
|
177
|
-
.color-box.is-dark:
|
|
222
|
+
.color-box.is-dark:before {
|
|
178
223
|
color: white;
|
|
179
224
|
}
|
|
180
225
|
|
|
@@ -200,22 +245,110 @@ class ColorsBuilder extends Builder {
|
|
|
200
245
|
animation-timing-function: ease-out;
|
|
201
246
|
z-index: 3;
|
|
202
247
|
}
|
|
248
|
+
|
|
249
|
+
.container {
|
|
250
|
+
width: 100vw;
|
|
251
|
+
display: flex;
|
|
252
|
+
flex-flow: row wrap;
|
|
253
|
+
gap: 16px;
|
|
254
|
+
|
|
255
|
+
@media (max-width: 1400px) {
|
|
256
|
+
.demo {
|
|
257
|
+
order: 1;
|
|
258
|
+
}
|
|
259
|
+
.pallete {
|
|
260
|
+
order: 2;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.canvas {
|
|
265
|
+
background-color: var(--color-brand-canvas);
|
|
266
|
+
display: flex;
|
|
267
|
+
flex-flow: column;
|
|
268
|
+
border: 1px dashed gray;
|
|
269
|
+
color: gray;
|
|
270
|
+
|
|
271
|
+
gap: 8px;
|
|
272
|
+
padding: 8px;
|
|
273
|
+
|
|
274
|
+
& > * {
|
|
275
|
+
padding: 8px;
|
|
276
|
+
color: black;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.pair.single span {
|
|
280
|
+
opacity: 0.5;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.pair.link span {
|
|
284
|
+
text-decoration: underline;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
203
288
|
</style>
|
|
204
289
|
</head>
|
|
205
290
|
<body>
|
|
206
|
-
|
|
291
|
+
<div class="container">
|
|
292
|
+
<div class="pallete">${html_colors}</div>
|
|
293
|
+
<div class="demo">
|
|
294
|
+
<div class="canvas">
|
|
295
|
+
<span>canvas</span>
|
|
296
|
+
${makeDemoPair(
|
|
297
|
+
"var(--color-brand-text-fg)",
|
|
298
|
+
"var(--color-brand-text-bg)",
|
|
299
|
+
"text-fg on text-bg"
|
|
300
|
+
)}
|
|
301
|
+
${makeDemoPair(
|
|
302
|
+
"var(--color-brand-text-accent)",
|
|
303
|
+
"var(--color-brand-text-bg)",
|
|
304
|
+
"text-accent on text-bg"
|
|
305
|
+
)}
|
|
306
|
+
${makeDemoPair(
|
|
307
|
+
"var(--color-brand-link-fg)",
|
|
308
|
+
"var(--color-brand-text-bg)",
|
|
309
|
+
"link-fg on text-bg",
|
|
310
|
+
"link"
|
|
311
|
+
)}
|
|
312
|
+
${makeDemoPair(
|
|
313
|
+
"",
|
|
314
|
+
"var(--color-brand-accent)",
|
|
315
|
+
"accent",
|
|
316
|
+
"single"
|
|
317
|
+
)}
|
|
318
|
+
${makeDemoPair(
|
|
319
|
+
"",
|
|
320
|
+
"var(--color-brand-accent2)",
|
|
321
|
+
"accent2",
|
|
322
|
+
"single"
|
|
323
|
+
)}
|
|
324
|
+
${makeDemoPair(
|
|
325
|
+
"var(--color-brand-text-on-accent)",
|
|
326
|
+
"var(--color-brand-accent)",
|
|
327
|
+
"text-on-accent on accent"
|
|
328
|
+
)}
|
|
329
|
+
${makeDemoPair(
|
|
330
|
+
"var(--color-brand-text-on-accent2)",
|
|
331
|
+
"var(--color-brand-accent2)",
|
|
332
|
+
"text-on-accent2 on accent2"
|
|
333
|
+
)}
|
|
334
|
+
${makeDemoPair(
|
|
335
|
+
"var(--color-brand-link-on-accent)",
|
|
336
|
+
"var(--color-brand-accent)",
|
|
337
|
+
"link-on-accent on accent",
|
|
338
|
+
"link"
|
|
339
|
+
)}
|
|
340
|
+
${makeDemoPair(
|
|
341
|
+
"var(--color-brand-link-on-accent2)",
|
|
342
|
+
"var(--color-brand-accent2)",
|
|
343
|
+
"link-on-accent2 on accent2",
|
|
344
|
+
"link"
|
|
345
|
+
)}
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
207
349
|
</body>
|
|
208
350
|
<script>
|
|
209
|
-
|
|
210
|
-
navigator.clipboard.writeText(
|
|
211
|
-
\`var(--color-\${event.target.getAttribute(
|
|
212
|
-
"data-color-group-name"
|
|
213
|
-
)}-\${event.target.getAttribute(
|
|
214
|
-
"data-color-name"
|
|
215
|
-
)}-\${event.target.getAttribute(
|
|
216
|
-
"data-color-shade-number"
|
|
217
|
-
)})\`
|
|
218
|
-
);
|
|
351
|
+
function pop_toast() {
|
|
219
352
|
const toast = document.createElement("div");
|
|
220
353
|
document.body.appendChild(toast);
|
|
221
354
|
toast.classList.add("toast");
|
|
@@ -234,8 +367,62 @@ class ColorsBuilder extends Builder {
|
|
|
234
367
|
toast.addEventListener("animationend", () => {
|
|
235
368
|
toast.remove();
|
|
236
369
|
});
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
document.addEventListener("click", (event) => {
|
|
373
|
+
const box = event.target.closest(".color-box");
|
|
374
|
+
if (box) {
|
|
375
|
+
const css_var = box.classList.contains(
|
|
376
|
+
"is-main"
|
|
377
|
+
)
|
|
378
|
+
? \`var(--color-\${box.getAttribute(
|
|
379
|
+
"data-color-group-name"
|
|
380
|
+
)}-\${box.getAttribute(
|
|
381
|
+
"data-color-name"
|
|
382
|
+
)})\`
|
|
383
|
+
: \`var(--color-\${box.getAttribute(
|
|
384
|
+
"data-color-group-name"
|
|
385
|
+
)}-\${box.getAttribute(
|
|
386
|
+
"data-color-name"
|
|
387
|
+
)}-\${box.getAttribute(
|
|
388
|
+
"data-color-shade-number"
|
|
389
|
+
)})\`;
|
|
390
|
+
navigator.clipboard.writeText(css_var);
|
|
391
|
+
pop_toast();
|
|
392
|
+
}
|
|
393
|
+
const pair = event.target.closest(".pair");
|
|
394
|
+
if (pair) {
|
|
395
|
+
let to_copy = "";
|
|
396
|
+
if (pair.classList.contains("single")) {
|
|
397
|
+
to_copy = pair.getAttribute("data-bg");
|
|
398
|
+
} else {
|
|
399
|
+
to_copy = \`background-color: \${pair.getAttribute(
|
|
400
|
+
"data-bg"
|
|
401
|
+
)};\\ncolor: \${pair.getAttribute(
|
|
402
|
+
"data-fg"
|
|
403
|
+
)};\`;
|
|
404
|
+
}
|
|
405
|
+
navigator.clipboard.writeText(to_copy);
|
|
406
|
+
pop_toast();
|
|
407
|
+
}
|
|
237
408
|
});
|
|
238
409
|
</script>
|
|
410
|
+
<script>
|
|
411
|
+
(async function () {
|
|
412
|
+
const response = await (
|
|
413
|
+
await fetch("/dist/notifier.json")
|
|
414
|
+
).json();
|
|
415
|
+
const ws = new WebSocket(
|
|
416
|
+
\`http://localhost:\${response.port}\`
|
|
417
|
+
);
|
|
418
|
+
ws.addEventListener("message", (event) => {
|
|
419
|
+
console.log(event);
|
|
420
|
+
if (event.data == "${APP_BACK_ALIVE_SIGNAL}") {
|
|
421
|
+
document.location = document.location; // refresh
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
})();
|
|
425
|
+
</script>
|
|
239
426
|
</html>`,
|
|
240
427
|
"html"
|
|
241
428
|
);
|
package/lib/notifier.js
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
import { WebSocketServer } from "ws";
|
|
2
|
-
|
|
2
|
+
const APP_DOWN_ERROR_MESSAGE = "App is currently down";
|
|
3
|
+
const APP_BACK_ALIVE_SIGNAL = "app-back-alive";
|
|
4
|
+
const sleep = (time) => new Promise((resolve) => {
|
|
5
|
+
setTimeout(resolve, time);
|
|
6
|
+
});
|
|
7
|
+
async function get_status(app_port) {
|
|
8
|
+
const r = await fetch(`http://127.0.0.1:${app_port}/status.json`);
|
|
9
|
+
return await r.json();
|
|
10
|
+
}
|
|
11
|
+
async function wait_for_run_id_to_change(app_port) {
|
|
12
|
+
let first_timestamp;
|
|
13
|
+
try {
|
|
14
|
+
const { started_at } = await get_status(app_port);
|
|
15
|
+
first_timestamp = started_at;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
await wait_for_app_to_be_stable(app_port);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!first_timestamp) {
|
|
21
|
+
throw new Error(APP_DOWN_ERROR_MESSAGE);
|
|
22
|
+
}
|
|
23
|
+
while (true) {
|
|
24
|
+
const { started_at } = await get_status(app_port).catch(() => ({
|
|
25
|
+
started_at: first_timestamp
|
|
26
|
+
}));
|
|
27
|
+
if (started_at !== first_timestamp) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
await sleep(100);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function wait_for_app_to_be_stable(app_port, n = 3) {
|
|
34
|
+
console.log("Waiting for app to be stable....");
|
|
35
|
+
let counter = 0;
|
|
36
|
+
while (true) {
|
|
37
|
+
console.debug("notifier.ts:53");
|
|
38
|
+
const { status } = await get_status(app_port).catch(() => ({
|
|
39
|
+
status: "down"
|
|
40
|
+
}));
|
|
41
|
+
if (status == "running") {
|
|
42
|
+
console.log(counter);
|
|
43
|
+
counter++;
|
|
44
|
+
} else {
|
|
45
|
+
counter = 0;
|
|
46
|
+
}
|
|
47
|
+
if (counter == n) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await sleep(100);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let restart_promise = null;
|
|
54
|
+
async function wait_for_app_restart(app_port) {
|
|
55
|
+
if (restart_promise) {
|
|
56
|
+
return restart_promise;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
restart_promise = wait_for_run_id_to_change(app_port);
|
|
60
|
+
await restart_promise;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
if (e.message !== APP_DOWN_ERROR_MESSAGE) {
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
restart_promise = null;
|
|
67
|
+
await wait_for_app_to_be_stable(app_port);
|
|
68
|
+
}
|
|
69
|
+
function make_notifier(port, app_port) {
|
|
3
70
|
const server = new WebSocketServer({
|
|
4
71
|
port
|
|
5
72
|
});
|
|
@@ -15,9 +82,13 @@ function make_notifier(port) {
|
|
|
15
82
|
);
|
|
16
83
|
return function notify(message) {
|
|
17
84
|
sockets.forEach((s) => s.send(message));
|
|
85
|
+
void wait_for_app_restart(app_port).then(() => {
|
|
86
|
+
sockets.forEach((s) => s.send(APP_BACK_ALIVE_SIGNAL));
|
|
87
|
+
});
|
|
18
88
|
};
|
|
19
89
|
}
|
|
20
90
|
export {
|
|
91
|
+
APP_BACK_ALIVE_SIGNAL,
|
|
21
92
|
make_notifier
|
|
22
93
|
};
|
|
23
94
|
//# sourceMappingURL=notifier.js.map
|
package/package.json
CHANGED
package/src/build.ts
CHANGED
|
@@ -96,7 +96,7 @@ async function build(watch: boolean): Promise<void> {
|
|
|
96
96
|
if (watch) {
|
|
97
97
|
const watcher = chokidar.watch("src", { ignoreInitial: true });
|
|
98
98
|
const port = await get_notifier_port();
|
|
99
|
-
const notifier = make_notifier(port);
|
|
99
|
+
const notifier = make_notifier(port, 8080); // TODO: parse the app config to get the actual port
|
|
100
100
|
await write_notifier_config(watch, port);
|
|
101
101
|
watcher.on("all", (_, file_path) => {
|
|
102
102
|
console.log("Detected a change!", file_path);
|
|
@@ -10,9 +10,11 @@ import { formatWithPrettier } from "../utils/prettier.js";
|
|
|
10
10
|
import { Builder } from "./builder.js";
|
|
11
11
|
import { exec } from "../utils/exec.js";
|
|
12
12
|
|
|
13
|
+
import { APP_BACK_ALIVE_SIGNAL } from "../notifier.js";
|
|
14
|
+
|
|
13
15
|
export const COLORS_TS_PATH = "src/back/colors.ts"; // keeping it in src/back instead of just src to make typescript hints work there
|
|
14
16
|
export const COLORS_CSS_PATH = "src/colors.css";
|
|
15
|
-
export const COLORS_HTML_PATH = "
|
|
17
|
+
export const COLORS_HTML_PATH = "public/dist/colors.html";
|
|
16
18
|
|
|
17
19
|
export class ColorsBuilder extends Builder {
|
|
18
20
|
getName(): string {
|
|
@@ -88,15 +90,18 @@ export class ColorsBuilder extends Builder {
|
|
|
88
90
|
group_name: string;
|
|
89
91
|
is_main?: boolean;
|
|
90
92
|
}) {
|
|
93
|
+
const c = colord(color);
|
|
91
94
|
return /* HTML */ `<div
|
|
92
|
-
class="color-box ${
|
|
93
|
-
? "is-
|
|
94
|
-
: ""} ${
|
|
95
|
+
class="color-box ${c.isDark() ? "is-dark" : ""} ${is_main
|
|
96
|
+
? "is-main"
|
|
97
|
+
: ""} ${c.toHsl().l > 90 ? "is-almost-white" : ""}"
|
|
95
98
|
style="background-color: ${color}; order: ${parseInt(shade_no)}"
|
|
96
99
|
data-color-name="${name}"
|
|
97
100
|
data-color-group-name="${group_name}"
|
|
98
101
|
data-color-shade-number="${shade_no}"
|
|
99
|
-
|
|
102
|
+
>
|
|
103
|
+
<span class="hex">${c.toHex()}</span>
|
|
104
|
+
</div>`;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
for (const group_name of Object.keys(color_groups).sort((key) =>
|
|
@@ -150,10 +155,30 @@ export class ColorsBuilder extends Builder {
|
|
|
150
155
|
"css"
|
|
151
156
|
);
|
|
152
157
|
|
|
158
|
+
function makeDemoPair(
|
|
159
|
+
fg: string,
|
|
160
|
+
bg: string,
|
|
161
|
+
text: string,
|
|
162
|
+
classname = ""
|
|
163
|
+
) {
|
|
164
|
+
return /* HTML */ ` <div
|
|
165
|
+
class="pair ${classname}"
|
|
166
|
+
data-fg="${fg}"
|
|
167
|
+
data-bg="${bg}"
|
|
168
|
+
style="background-color: ${bg}; color: ${fg}"
|
|
169
|
+
>
|
|
170
|
+
<span>${text}</span>
|
|
171
|
+
</div>`;
|
|
172
|
+
}
|
|
173
|
+
|
|
153
174
|
const html = await formatWithPrettier(
|
|
154
175
|
/* HTML */ `<!DOCTYPE html>
|
|
155
176
|
<html>
|
|
156
177
|
<head>
|
|
178
|
+
<title>Color palettes</title>
|
|
179
|
+
<style>
|
|
180
|
+
${css}
|
|
181
|
+
</style>
|
|
157
182
|
<style>
|
|
158
183
|
* {
|
|
159
184
|
font-family: sans-serif;
|
|
@@ -174,6 +199,10 @@ export class ColorsBuilder extends Builder {
|
|
|
174
199
|
&:hover {
|
|
175
200
|
transform: scale(1.1);
|
|
176
201
|
z-index: 2;
|
|
202
|
+
|
|
203
|
+
.hex {
|
|
204
|
+
visibility: visible;
|
|
205
|
+
}
|
|
177
206
|
}
|
|
178
207
|
|
|
179
208
|
&.is-main {
|
|
@@ -182,22 +211,42 @@ export class ColorsBuilder extends Builder {
|
|
|
182
211
|
margin-top: -8px;
|
|
183
212
|
box-shadow: 0px 0px 6px 2px white;
|
|
184
213
|
z-index: 1;
|
|
214
|
+
|
|
215
|
+
&:before {
|
|
216
|
+
font-weight: bold;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
&.is-almost-white.is-main {
|
|
221
|
+
box-shadow: 0px 0px 6px 1px #00000078;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.hex {
|
|
225
|
+
padding: 8px;
|
|
226
|
+
font-family: Menlo, Consolas, Monaco,
|
|
227
|
+
Liberation Mono, Lucida Console,
|
|
228
|
+
monospace;
|
|
229
|
+
opacity: 0.5;
|
|
230
|
+
visibility: hidden;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
&.is-dark .hex {
|
|
234
|
+
color: white;
|
|
185
235
|
}
|
|
186
236
|
}
|
|
187
237
|
|
|
188
|
-
.color-box:
|
|
238
|
+
.color-box:before {
|
|
189
239
|
content: attr(data-color-shade-number);
|
|
190
240
|
box-sizing: border-box;
|
|
191
241
|
display: block;
|
|
192
242
|
color: black;
|
|
193
243
|
font-size: 14px;
|
|
194
244
|
width: 100%;
|
|
195
|
-
height: 100%;
|
|
196
245
|
padding: 10px;
|
|
197
246
|
opacity: 0.3;
|
|
198
247
|
}
|
|
199
248
|
|
|
200
|
-
.color-box.is-dark:
|
|
249
|
+
.color-box.is-dark:before {
|
|
201
250
|
color: white;
|
|
202
251
|
}
|
|
203
252
|
|
|
@@ -223,22 +272,110 @@ export class ColorsBuilder extends Builder {
|
|
|
223
272
|
animation-timing-function: ease-out;
|
|
224
273
|
z-index: 3;
|
|
225
274
|
}
|
|
275
|
+
|
|
276
|
+
.container {
|
|
277
|
+
width: 100vw;
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-flow: row wrap;
|
|
280
|
+
gap: 16px;
|
|
281
|
+
|
|
282
|
+
@media (max-width: 1400px) {
|
|
283
|
+
.demo {
|
|
284
|
+
order: 1;
|
|
285
|
+
}
|
|
286
|
+
.pallete {
|
|
287
|
+
order: 2;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.canvas {
|
|
292
|
+
background-color: var(--color-brand-canvas);
|
|
293
|
+
display: flex;
|
|
294
|
+
flex-flow: column;
|
|
295
|
+
border: 1px dashed gray;
|
|
296
|
+
color: gray;
|
|
297
|
+
|
|
298
|
+
gap: 8px;
|
|
299
|
+
padding: 8px;
|
|
300
|
+
|
|
301
|
+
& > * {
|
|
302
|
+
padding: 8px;
|
|
303
|
+
color: black;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.pair.single span {
|
|
307
|
+
opacity: 0.5;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.pair.link span {
|
|
311
|
+
text-decoration: underline;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
226
315
|
</style>
|
|
227
316
|
</head>
|
|
228
317
|
<body>
|
|
229
|
-
|
|
318
|
+
<div class="container">
|
|
319
|
+
<div class="pallete">${html_colors}</div>
|
|
320
|
+
<div class="demo">
|
|
321
|
+
<div class="canvas">
|
|
322
|
+
<span>canvas</span>
|
|
323
|
+
${makeDemoPair(
|
|
324
|
+
"var(--color-brand-text-fg)",
|
|
325
|
+
"var(--color-brand-text-bg)",
|
|
326
|
+
"text-fg on text-bg"
|
|
327
|
+
)}
|
|
328
|
+
${makeDemoPair(
|
|
329
|
+
"var(--color-brand-text-accent)",
|
|
330
|
+
"var(--color-brand-text-bg)",
|
|
331
|
+
"text-accent on text-bg"
|
|
332
|
+
)}
|
|
333
|
+
${makeDemoPair(
|
|
334
|
+
"var(--color-brand-link-fg)",
|
|
335
|
+
"var(--color-brand-text-bg)",
|
|
336
|
+
"link-fg on text-bg",
|
|
337
|
+
"link"
|
|
338
|
+
)}
|
|
339
|
+
${makeDemoPair(
|
|
340
|
+
"",
|
|
341
|
+
"var(--color-brand-accent)",
|
|
342
|
+
"accent",
|
|
343
|
+
"single"
|
|
344
|
+
)}
|
|
345
|
+
${makeDemoPair(
|
|
346
|
+
"",
|
|
347
|
+
"var(--color-brand-accent2)",
|
|
348
|
+
"accent2",
|
|
349
|
+
"single"
|
|
350
|
+
)}
|
|
351
|
+
${makeDemoPair(
|
|
352
|
+
"var(--color-brand-text-on-accent)",
|
|
353
|
+
"var(--color-brand-accent)",
|
|
354
|
+
"text-on-accent on accent"
|
|
355
|
+
)}
|
|
356
|
+
${makeDemoPair(
|
|
357
|
+
"var(--color-brand-text-on-accent2)",
|
|
358
|
+
"var(--color-brand-accent2)",
|
|
359
|
+
"text-on-accent2 on accent2"
|
|
360
|
+
)}
|
|
361
|
+
${makeDemoPair(
|
|
362
|
+
"var(--color-brand-link-on-accent)",
|
|
363
|
+
"var(--color-brand-accent)",
|
|
364
|
+
"link-on-accent on accent",
|
|
365
|
+
"link"
|
|
366
|
+
)}
|
|
367
|
+
${makeDemoPair(
|
|
368
|
+
"var(--color-brand-link-on-accent2)",
|
|
369
|
+
"var(--color-brand-accent2)",
|
|
370
|
+
"link-on-accent2 on accent2",
|
|
371
|
+
"link"
|
|
372
|
+
)}
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
230
376
|
</body>
|
|
231
377
|
<script>
|
|
232
|
-
|
|
233
|
-
navigator.clipboard.writeText(
|
|
234
|
-
\`var(--color-\${event.target.getAttribute(
|
|
235
|
-
"data-color-group-name"
|
|
236
|
-
)}-\${event.target.getAttribute(
|
|
237
|
-
"data-color-name"
|
|
238
|
-
)}-\${event.target.getAttribute(
|
|
239
|
-
"data-color-shade-number"
|
|
240
|
-
)})\`
|
|
241
|
-
);
|
|
378
|
+
function pop_toast() {
|
|
242
379
|
const toast = document.createElement("div");
|
|
243
380
|
document.body.appendChild(toast);
|
|
244
381
|
toast.classList.add("toast");
|
|
@@ -257,8 +394,62 @@ export class ColorsBuilder extends Builder {
|
|
|
257
394
|
toast.addEventListener("animationend", () => {
|
|
258
395
|
toast.remove();
|
|
259
396
|
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
document.addEventListener("click", (event) => {
|
|
400
|
+
const box = event.target.closest(".color-box");
|
|
401
|
+
if (box) {
|
|
402
|
+
const css_var = box.classList.contains(
|
|
403
|
+
"is-main"
|
|
404
|
+
)
|
|
405
|
+
? \`var(--color-\${box.getAttribute(
|
|
406
|
+
"data-color-group-name"
|
|
407
|
+
)}-\${box.getAttribute(
|
|
408
|
+
"data-color-name"
|
|
409
|
+
)})\`
|
|
410
|
+
: \`var(--color-\${box.getAttribute(
|
|
411
|
+
"data-color-group-name"
|
|
412
|
+
)}-\${box.getAttribute(
|
|
413
|
+
"data-color-name"
|
|
414
|
+
)}-\${box.getAttribute(
|
|
415
|
+
"data-color-shade-number"
|
|
416
|
+
)})\`;
|
|
417
|
+
navigator.clipboard.writeText(css_var);
|
|
418
|
+
pop_toast();
|
|
419
|
+
}
|
|
420
|
+
const pair = event.target.closest(".pair");
|
|
421
|
+
if (pair) {
|
|
422
|
+
let to_copy = "";
|
|
423
|
+
if (pair.classList.contains("single")) {
|
|
424
|
+
to_copy = pair.getAttribute("data-bg");
|
|
425
|
+
} else {
|
|
426
|
+
to_copy = \`background-color: \${pair.getAttribute(
|
|
427
|
+
"data-bg"
|
|
428
|
+
)};\\ncolor: \${pair.getAttribute(
|
|
429
|
+
"data-fg"
|
|
430
|
+
)};\`;
|
|
431
|
+
}
|
|
432
|
+
navigator.clipboard.writeText(to_copy);
|
|
433
|
+
pop_toast();
|
|
434
|
+
}
|
|
260
435
|
});
|
|
261
436
|
</script>
|
|
437
|
+
<script>
|
|
438
|
+
(async function () {
|
|
439
|
+
const response = await (
|
|
440
|
+
await fetch("/dist/notifier.json")
|
|
441
|
+
).json();
|
|
442
|
+
const ws = new WebSocket(
|
|
443
|
+
\`http://localhost:\${response.port}\`
|
|
444
|
+
);
|
|
445
|
+
ws.addEventListener("message", (event) => {
|
|
446
|
+
console.log(event);
|
|
447
|
+
if (event.data == "${APP_BACK_ALIVE_SIGNAL}") {
|
|
448
|
+
document.location = document.location; // refresh
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
})();
|
|
452
|
+
</script>
|
|
262
453
|
</html>`,
|
|
263
454
|
"html"
|
|
264
455
|
);
|
package/src/notifier.ts
CHANGED
|
@@ -1,6 +1,95 @@
|
|
|
1
1
|
import { WebSocketServer, WebSocket } from "ws";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const APP_DOWN_ERROR_MESSAGE = "App is currently down";
|
|
4
|
+
export const APP_BACK_ALIVE_SIGNAL = "app-back-alive";
|
|
5
|
+
|
|
6
|
+
const sleep = (time: number) =>
|
|
7
|
+
new Promise((resolve) => {
|
|
8
|
+
setTimeout(resolve, time);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
async function get_status(
|
|
12
|
+
app_port: number
|
|
13
|
+
): Promise<{ started_at: number; status: string }> {
|
|
14
|
+
const r = await fetch(`http://127.0.0.1:${app_port}/status.json`);
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
16
|
+
return (await r.json()) as { started_at: number; status: string };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function wait_for_run_id_to_change(app_port: number) {
|
|
20
|
+
let first_timestamp: number;
|
|
21
|
+
try {
|
|
22
|
+
const { started_at } = await get_status(app_port);
|
|
23
|
+
first_timestamp = started_at;
|
|
24
|
+
} catch (e) {
|
|
25
|
+
await wait_for_app_to_be_stable(app_port);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!first_timestamp) {
|
|
30
|
+
throw new Error(APP_DOWN_ERROR_MESSAGE);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// eslint-disable-next-line no-constant-condition
|
|
34
|
+
while (true) {
|
|
35
|
+
// eslint-disable-next-line no-await-in-loop
|
|
36
|
+
const { started_at } = await get_status(app_port).catch(() => ({
|
|
37
|
+
started_at: first_timestamp,
|
|
38
|
+
}));
|
|
39
|
+
if (started_at !== first_timestamp) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line no-await-in-loop
|
|
43
|
+
await sleep(100);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function wait_for_app_to_be_stable(app_port: number, n = 3) {
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.log("Waiting for app to be stable....");
|
|
50
|
+
let counter = 0;
|
|
51
|
+
// eslint-disable-next-line no-constant-condition
|
|
52
|
+
while (true) {
|
|
53
|
+
console.debug("notifier.ts:53");
|
|
54
|
+
// eslint-disable-next-line no-await-in-loop
|
|
55
|
+
const { status } = await get_status(app_port).catch(() => ({
|
|
56
|
+
status: "down",
|
|
57
|
+
}));
|
|
58
|
+
if (status == "running") {
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.log(counter);
|
|
61
|
+
counter++;
|
|
62
|
+
} else {
|
|
63
|
+
counter = 0;
|
|
64
|
+
}
|
|
65
|
+
if (counter == n) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// eslint-disable-next-line no-await-in-loop
|
|
69
|
+
await sleep(100);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let restart_promise: Promise<void> | null = null;
|
|
74
|
+
|
|
75
|
+
async function wait_for_app_restart(app_port: number) {
|
|
76
|
+
if (restart_promise) {
|
|
77
|
+
return restart_promise;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
restart_promise = wait_for_run_id_to_change(app_port);
|
|
81
|
+
await restart_promise;
|
|
82
|
+
} catch (e) {
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
84
|
+
if (e.message !== APP_DOWN_ERROR_MESSAGE) {
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
restart_promise = null;
|
|
89
|
+
await wait_for_app_to_be_stable(app_port);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function make_notifier(port: number, app_port: number) {
|
|
4
93
|
const server = new WebSocketServer({
|
|
5
94
|
port,
|
|
6
95
|
});
|
|
@@ -20,5 +109,8 @@ export function make_notifier(port: number) {
|
|
|
20
109
|
);
|
|
21
110
|
return function notify(message: string) {
|
|
22
111
|
sockets.forEach((s) => s.send(message));
|
|
112
|
+
void wait_for_app_restart(app_port).then(() => {
|
|
113
|
+
sockets.forEach((s) => s.send(APP_BACK_ALIVE_SIGNAL));
|
|
114
|
+
});
|
|
23
115
|
};
|
|
24
116
|
}
|