@sealcode/sealgen 0.17.13 → 0.17.15
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 +184 -19
- package/lib/notifier.js +72 -1
- package/package.json +1 -1
- package/src/build.ts +1 -1
- package/src/builders/colors-builder.ts +191 -21
- 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(
|
|
@@ -101,13 +105,13 @@ class ColorsBuilder extends Builder {
|
|
|
101
105
|
group_name
|
|
102
106
|
});
|
|
103
107
|
color_info.shades.forEach((shaded_color, index) => {
|
|
108
|
+
const shade_no = index.toString().padStart(2, "0");
|
|
109
|
+
css_colors += `--color-${group_name}-${color_name}-${shade_no}: ${shaded_color};`;
|
|
104
110
|
if (Math.abs(
|
|
105
111
|
colord(shaded_color).toHsl().l - colord(main_color).toHsl().l
|
|
106
112
|
) < 10) {
|
|
107
113
|
return;
|
|
108
114
|
}
|
|
109
|
-
const shade_no = index.toString().padStart(2, "0");
|
|
110
|
-
css_colors += `--color-${group_name}-${color_name}-${shade_no}: ${shaded_color};`;
|
|
111
115
|
html_colors += html_color_box({
|
|
112
116
|
color: shaded_color,
|
|
113
117
|
shade_no,
|
|
@@ -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,88 @@ 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
|
+
}
|
|
203
284
|
</style>
|
|
204
285
|
</head>
|
|
205
286
|
<body>
|
|
206
|
-
|
|
287
|
+
<div class="container">
|
|
288
|
+
<div class="pallete">${html_colors}</div>
|
|
289
|
+
<div class="demo">
|
|
290
|
+
<div class="canvas">
|
|
291
|
+
<span>canvas</span>
|
|
292
|
+
${makeDemoPair(
|
|
293
|
+
"var(--color-brand-text-fg)",
|
|
294
|
+
"var(--color-brand-text-bg)",
|
|
295
|
+
"text-fg on text-bg"
|
|
296
|
+
)}
|
|
297
|
+
${makeDemoPair(
|
|
298
|
+
"var(--color-brand-text-accent)",
|
|
299
|
+
"var(--color-brand-text-bg)",
|
|
300
|
+
"text-accent on text-bg"
|
|
301
|
+
)}
|
|
302
|
+
${makeDemoPair(
|
|
303
|
+
"",
|
|
304
|
+
"var(--color-brand-accent)",
|
|
305
|
+
"accent",
|
|
306
|
+
"single"
|
|
307
|
+
)}
|
|
308
|
+
${makeDemoPair(
|
|
309
|
+
"",
|
|
310
|
+
"var(--color-brand-accent2)",
|
|
311
|
+
"accent2",
|
|
312
|
+
"single"
|
|
313
|
+
)}
|
|
314
|
+
${makeDemoPair(
|
|
315
|
+
"var(--color-brand-text-on-accent)",
|
|
316
|
+
"var(--color-brand-accent)",
|
|
317
|
+
"text-on-accent on accent"
|
|
318
|
+
)}
|
|
319
|
+
${makeDemoPair(
|
|
320
|
+
"var(--color-brand-text-on-accent2)",
|
|
321
|
+
"var(--color-brand-accent2)",
|
|
322
|
+
"text-on-accent2 on accent2"
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
207
327
|
</body>
|
|
208
328
|
<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
|
-
);
|
|
329
|
+
function pop_toast() {
|
|
219
330
|
const toast = document.createElement("div");
|
|
220
331
|
document.body.appendChild(toast);
|
|
221
332
|
toast.classList.add("toast");
|
|
@@ -234,8 +345,62 @@ class ColorsBuilder extends Builder {
|
|
|
234
345
|
toast.addEventListener("animationend", () => {
|
|
235
346
|
toast.remove();
|
|
236
347
|
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
document.addEventListener("click", (event) => {
|
|
351
|
+
const box = event.target.closest(".color-box");
|
|
352
|
+
if (box) {
|
|
353
|
+
const css_var = box.classList.contains(
|
|
354
|
+
"is-main"
|
|
355
|
+
)
|
|
356
|
+
? \`var(--color-\${box.getAttribute(
|
|
357
|
+
"data-color-group-name"
|
|
358
|
+
)}-\${box.getAttribute(
|
|
359
|
+
"data-color-name"
|
|
360
|
+
)})\`
|
|
361
|
+
: \`var(--color-\${box.getAttribute(
|
|
362
|
+
"data-color-group-name"
|
|
363
|
+
)}-\${box.getAttribute(
|
|
364
|
+
"data-color-name"
|
|
365
|
+
)}-\${box.getAttribute(
|
|
366
|
+
"data-color-shade-number"
|
|
367
|
+
)})\`;
|
|
368
|
+
navigator.clipboard.writeText(css_var);
|
|
369
|
+
pop_toast();
|
|
370
|
+
}
|
|
371
|
+
const pair = event.target.closest(".pair");
|
|
372
|
+
if (pair) {
|
|
373
|
+
let to_copy = "";
|
|
374
|
+
if (pair.classList.contains("single")) {
|
|
375
|
+
to_copy = pair.getAttribute("data-bg");
|
|
376
|
+
} else {
|
|
377
|
+
to_copy = \`background-color: \${pair.getAttribute(
|
|
378
|
+
"data-bg"
|
|
379
|
+
)};\\ncolor: \${pair.getAttribute(
|
|
380
|
+
"data-fg"
|
|
381
|
+
)};\`;
|
|
382
|
+
}
|
|
383
|
+
navigator.clipboard.writeText(to_copy);
|
|
384
|
+
pop_toast();
|
|
385
|
+
}
|
|
237
386
|
});
|
|
238
387
|
</script>
|
|
388
|
+
<script>
|
|
389
|
+
(async function () {
|
|
390
|
+
const response = await (
|
|
391
|
+
await fetch("/dist/notifier.json")
|
|
392
|
+
).json();
|
|
393
|
+
const ws = new WebSocket(
|
|
394
|
+
\`http://localhost:\${response.port}\`
|
|
395
|
+
);
|
|
396
|
+
ws.addEventListener("message", (event) => {
|
|
397
|
+
console.log(event);
|
|
398
|
+
if (event.data == "${APP_BACK_ALIVE_SIGNAL}") {
|
|
399
|
+
document.location = document.location; // refresh
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
})();
|
|
403
|
+
</script>
|
|
239
404
|
</html>`,
|
|
240
405
|
"html"
|
|
241
406
|
);
|
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) =>
|
|
@@ -119,16 +124,17 @@ export class ColorsBuilder extends Builder {
|
|
|
119
124
|
group_name,
|
|
120
125
|
});
|
|
121
126
|
color_info.shades.forEach((shaded_color, index) => {
|
|
127
|
+
const shade_no = index.toString().padStart(2, "0");
|
|
128
|
+
css_colors += `--color-${group_name}-${color_name}-${shade_no}: ${shaded_color};`;
|
|
122
129
|
if (
|
|
123
130
|
Math.abs(
|
|
124
131
|
colord(shaded_color).toHsl().l -
|
|
125
132
|
colord(main_color).toHsl().l
|
|
126
133
|
) < 10
|
|
127
134
|
) {
|
|
135
|
+
// this color is already in HTML as the main color, skipping adding it to html to avoid duplication
|
|
128
136
|
return;
|
|
129
137
|
}
|
|
130
|
-
const shade_no = index.toString().padStart(2, "0");
|
|
131
|
-
css_colors += `--color-${group_name}-${color_name}-${shade_no}: ${shaded_color};`;
|
|
132
138
|
html_colors += html_color_box({
|
|
133
139
|
color: shaded_color,
|
|
134
140
|
shade_no,
|
|
@@ -149,10 +155,30 @@ export class ColorsBuilder extends Builder {
|
|
|
149
155
|
"css"
|
|
150
156
|
);
|
|
151
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
|
+
|
|
152
174
|
const html = await formatWithPrettier(
|
|
153
175
|
/* HTML */ `<!DOCTYPE html>
|
|
154
176
|
<html>
|
|
155
177
|
<head>
|
|
178
|
+
<title>Color palettes</title>
|
|
179
|
+
<style>
|
|
180
|
+
${css}
|
|
181
|
+
</style>
|
|
156
182
|
<style>
|
|
157
183
|
* {
|
|
158
184
|
font-family: sans-serif;
|
|
@@ -173,6 +199,10 @@ export class ColorsBuilder extends Builder {
|
|
|
173
199
|
&:hover {
|
|
174
200
|
transform: scale(1.1);
|
|
175
201
|
z-index: 2;
|
|
202
|
+
|
|
203
|
+
.hex {
|
|
204
|
+
visibility: visible;
|
|
205
|
+
}
|
|
176
206
|
}
|
|
177
207
|
|
|
178
208
|
&.is-main {
|
|
@@ -181,22 +211,42 @@ export class ColorsBuilder extends Builder {
|
|
|
181
211
|
margin-top: -8px;
|
|
182
212
|
box-shadow: 0px 0px 6px 2px white;
|
|
183
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;
|
|
184
235
|
}
|
|
185
236
|
}
|
|
186
237
|
|
|
187
|
-
.color-box:
|
|
238
|
+
.color-box:before {
|
|
188
239
|
content: attr(data-color-shade-number);
|
|
189
240
|
box-sizing: border-box;
|
|
190
241
|
display: block;
|
|
191
242
|
color: black;
|
|
192
243
|
font-size: 14px;
|
|
193
244
|
width: 100%;
|
|
194
|
-
height: 100%;
|
|
195
245
|
padding: 10px;
|
|
196
246
|
opacity: 0.3;
|
|
197
247
|
}
|
|
198
248
|
|
|
199
|
-
.color-box.is-dark:
|
|
249
|
+
.color-box.is-dark:before {
|
|
200
250
|
color: white;
|
|
201
251
|
}
|
|
202
252
|
|
|
@@ -222,22 +272,88 @@ export class ColorsBuilder extends Builder {
|
|
|
222
272
|
animation-timing-function: ease-out;
|
|
223
273
|
z-index: 3;
|
|
224
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
|
+
}
|
|
225
311
|
</style>
|
|
226
312
|
</head>
|
|
227
313
|
<body>
|
|
228
|
-
|
|
314
|
+
<div class="container">
|
|
315
|
+
<div class="pallete">${html_colors}</div>
|
|
316
|
+
<div class="demo">
|
|
317
|
+
<div class="canvas">
|
|
318
|
+
<span>canvas</span>
|
|
319
|
+
${makeDemoPair(
|
|
320
|
+
"var(--color-brand-text-fg)",
|
|
321
|
+
"var(--color-brand-text-bg)",
|
|
322
|
+
"text-fg on text-bg"
|
|
323
|
+
)}
|
|
324
|
+
${makeDemoPair(
|
|
325
|
+
"var(--color-brand-text-accent)",
|
|
326
|
+
"var(--color-brand-text-bg)",
|
|
327
|
+
"text-accent on text-bg"
|
|
328
|
+
)}
|
|
329
|
+
${makeDemoPair(
|
|
330
|
+
"",
|
|
331
|
+
"var(--color-brand-accent)",
|
|
332
|
+
"accent",
|
|
333
|
+
"single"
|
|
334
|
+
)}
|
|
335
|
+
${makeDemoPair(
|
|
336
|
+
"",
|
|
337
|
+
"var(--color-brand-accent2)",
|
|
338
|
+
"accent2",
|
|
339
|
+
"single"
|
|
340
|
+
)}
|
|
341
|
+
${makeDemoPair(
|
|
342
|
+
"var(--color-brand-text-on-accent)",
|
|
343
|
+
"var(--color-brand-accent)",
|
|
344
|
+
"text-on-accent on accent"
|
|
345
|
+
)}
|
|
346
|
+
${makeDemoPair(
|
|
347
|
+
"var(--color-brand-text-on-accent2)",
|
|
348
|
+
"var(--color-brand-accent2)",
|
|
349
|
+
"text-on-accent2 on accent2"
|
|
350
|
+
)}
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
229
354
|
</body>
|
|
230
355
|
<script>
|
|
231
|
-
|
|
232
|
-
navigator.clipboard.writeText(
|
|
233
|
-
\`var(--color-\${event.target.getAttribute(
|
|
234
|
-
"data-color-group-name"
|
|
235
|
-
)}-\${event.target.getAttribute(
|
|
236
|
-
"data-color-name"
|
|
237
|
-
)}-\${event.target.getAttribute(
|
|
238
|
-
"data-color-shade-number"
|
|
239
|
-
)})\`
|
|
240
|
-
);
|
|
356
|
+
function pop_toast() {
|
|
241
357
|
const toast = document.createElement("div");
|
|
242
358
|
document.body.appendChild(toast);
|
|
243
359
|
toast.classList.add("toast");
|
|
@@ -256,8 +372,62 @@ export class ColorsBuilder extends Builder {
|
|
|
256
372
|
toast.addEventListener("animationend", () => {
|
|
257
373
|
toast.remove();
|
|
258
374
|
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
document.addEventListener("click", (event) => {
|
|
378
|
+
const box = event.target.closest(".color-box");
|
|
379
|
+
if (box) {
|
|
380
|
+
const css_var = box.classList.contains(
|
|
381
|
+
"is-main"
|
|
382
|
+
)
|
|
383
|
+
? \`var(--color-\${box.getAttribute(
|
|
384
|
+
"data-color-group-name"
|
|
385
|
+
)}-\${box.getAttribute(
|
|
386
|
+
"data-color-name"
|
|
387
|
+
)})\`
|
|
388
|
+
: \`var(--color-\${box.getAttribute(
|
|
389
|
+
"data-color-group-name"
|
|
390
|
+
)}-\${box.getAttribute(
|
|
391
|
+
"data-color-name"
|
|
392
|
+
)}-\${box.getAttribute(
|
|
393
|
+
"data-color-shade-number"
|
|
394
|
+
)})\`;
|
|
395
|
+
navigator.clipboard.writeText(css_var);
|
|
396
|
+
pop_toast();
|
|
397
|
+
}
|
|
398
|
+
const pair = event.target.closest(".pair");
|
|
399
|
+
if (pair) {
|
|
400
|
+
let to_copy = "";
|
|
401
|
+
if (pair.classList.contains("single")) {
|
|
402
|
+
to_copy = pair.getAttribute("data-bg");
|
|
403
|
+
} else {
|
|
404
|
+
to_copy = \`background-color: \${pair.getAttribute(
|
|
405
|
+
"data-bg"
|
|
406
|
+
)};\\ncolor: \${pair.getAttribute(
|
|
407
|
+
"data-fg"
|
|
408
|
+
)};\`;
|
|
409
|
+
}
|
|
410
|
+
navigator.clipboard.writeText(to_copy);
|
|
411
|
+
pop_toast();
|
|
412
|
+
}
|
|
259
413
|
});
|
|
260
414
|
</script>
|
|
415
|
+
<script>
|
|
416
|
+
(async function () {
|
|
417
|
+
const response = await (
|
|
418
|
+
await fetch("/dist/notifier.json")
|
|
419
|
+
).json();
|
|
420
|
+
const ws = new WebSocket(
|
|
421
|
+
\`http://localhost:\${response.port}\`
|
|
422
|
+
);
|
|
423
|
+
ws.addEventListener("message", (event) => {
|
|
424
|
+
console.log(event);
|
|
425
|
+
if (event.data == "${APP_BACK_ALIVE_SIGNAL}") {
|
|
426
|
+
document.location = document.location; // refresh
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
})();
|
|
430
|
+
</script>
|
|
261
431
|
</html>`,
|
|
262
432
|
"html"
|
|
263
433
|
);
|
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
|
}
|