@sealcode/sealgen 0.17.14 → 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 +182 -17
- package/lib/notifier.js +72 -1
- package/package.json +1 -1
- package/src/build.ts +1 -1
- package/src/builders/colors-builder.ts +188 -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,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) =>
|
|
@@ -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,88 @@ 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
|
+
}
|
|
226
311
|
</style>
|
|
227
312
|
</head>
|
|
228
313
|
<body>
|
|
229
|
-
|
|
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>
|
|
230
354
|
</body>
|
|
231
355
|
<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
|
-
);
|
|
356
|
+
function pop_toast() {
|
|
242
357
|
const toast = document.createElement("div");
|
|
243
358
|
document.body.appendChild(toast);
|
|
244
359
|
toast.classList.add("toast");
|
|
@@ -257,8 +372,62 @@ export class ColorsBuilder extends Builder {
|
|
|
257
372
|
toast.addEventListener("animationend", () => {
|
|
258
373
|
toast.remove();
|
|
259
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
|
+
}
|
|
260
413
|
});
|
|
261
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>
|
|
262
431
|
</html>`,
|
|
263
432
|
"html"
|
|
264
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
|
}
|