From f90e7702e4c855ab388565a1d71523e58b77a2c6 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sun, 11 Feb 2024 16:23:47 +0100 Subject: [PATCH] Add support for refreshing component debug on ts build --- package-lock.json | 8 ++-- package.json | 2 +- src/back/html.ts | 68 ++++++++++++++++++++++++--- src/back/routes/components.css | 12 +++++ src/back/routes/components.sreact.tsx | 20 ++++---- src/back/routes/index.ts | 5 ++ 6 files changed, 96 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0e25c67..fb5aca9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@koa/router": "^12.0.1", "@playwright/test": "^1.36.1", "@sealcode/jdd": "^0.2.12", - "@sealcode/sealgen": "^0.11.7", + "@sealcode/sealgen": "^0.11.8", "@sealcode/ts-predicates": "^0.4.3", "@types/kill-port": "^2.0.0", "get-port": "^7.0.0", @@ -1304,9 +1304,9 @@ } }, "node_modules/@sealcode/sealgen": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.11.7.tgz", - "integrity": "sha512-JpvVkBCaO2eNTvdRB3J6gs6enYCzMWByaDAj+KmLSifOUqcN1M4DQ5nzF6mAA8q0Aabwe7KDxSHb3b9rPMtYnw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.11.8.tgz", + "integrity": "sha512-vhEEOcYSlZo+uxSJgWMYp8mZ38Op2EGANRoeF7Dc8YxpyQCI43WUXyXWZM6UyR4/SOWJy1NQMdF+khguGNtlGg==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/ts-predicates": "^0.4.3", diff --git a/package.json b/package.json index 29f686d..97cf6fe 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@koa/router": "^12.0.1", "@playwright/test": "^1.36.1", "@sealcode/jdd": "^0.2.12", - "@sealcode/sealgen": "^0.11.7", + "@sealcode/sealgen": "^0.11.8", "@sealcode/ts-predicates": "^0.4.3", "@types/kill-port": "^2.0.0", "get-port": "^7.0.0", diff --git a/src/back/html.ts b/src/back/html.ts index bb2d07e..7aa383c 100644 --- a/src/back/html.ts +++ b/src/back/html.ts @@ -79,12 +79,68 @@ export default function html( "turbo:morph", cleanup_css ); - const socket = new WebSocket("ws://localhost:60808"); - socket.onmessage = () => { - const new_link = make_new_link(); - new_link.onload = cleanup_css; - document.querySelector("head").appendChild(new_link); - }; + + const sleep = (time) => + new Promise((resolve) => { + setTimeout(resolve, time); + }); + + let last_known_start_timestamp = 0; + + async function wait_for_app_restart() { + while (true) { + const { started_at, status } = await fetch( + "/status.json" + ) + .then((r) => r.json()) + .catch(() => ({ + started_at: last_known_start_timestamp, + })); + if (started_at !== last_known_start_timestamp) { + last_known_start_timestamp = started_at; + return; + } + await sleep(100); + } + } + + (async function () { + const { started_at, status } = await fetch( + "/status.json" + ).then((r) => r.json()); + last_known_start_timestamp = started_at; + const { port, watch } = await fetch( + "/dist/notifier.json" + ).then((r) => r.json()); + if (!watch) { + console.warning( + "Not running auto refresh on watch because the build process is not running in watch mode" + ); + return; + } + const socket = new WebSocket(\`ws://localhost:\${port}\`); + socket.onmessage = async (message) => { + if (message.data === "css") { + const new_link = make_new_link(); + new_link.onload = cleanup_css; + document + .querySelector("head") + .appendChild(new_link); + } + if (message.data === "ts") { + document.documentElement.classList.add( + "restarting" + ); + await wait_for_app_restart(); + document.documentElement.dispatchEvent( + new Event("ts-rebuilt") + ); + document.documentElement.classList.remove( + "restarting" + ); + } + }; + })(); ` : ""} diff --git a/src/back/routes/components.css b/src/back/routes/components.css index 3e5f341..26d4d13 100644 --- a/src/back/routes/components.css +++ b/src/back/routes/components.css @@ -18,6 +18,12 @@ width: var(--resizable-column-width); overflow-x: auto; } + + transition: transform 200ms, opacity 200ms; + &.restarting { + transform: scale(0.99); + opacity: 0.6; + } } .component-preview-parameters { @@ -25,3 +31,9 @@ background-color: #80808024; } } + +.component-preview { + * { + transition: all 200ms; + } +} diff --git a/src/back/routes/components.sreact.tsx b/src/back/routes/components.sreact.tsx index d39415f..fb73ae2 100644 --- a/src/back/routes/components.sreact.tsx +++ b/src/back/routes/components.sreact.tsx @@ -219,7 +219,7 @@ export default new (class ComponentsPage extends StatefulPage +
{/*The below button has to be here in order for it to be the default behavior */} @@ -282,7 +282,7 @@ export default new (class ComponentsPage extends StatefulPage` } -
+
Preview {render( @@ -292,13 +292,17 @@ export default new (class ComponentsPage extends StatefulPage
+ { + /* HTML */ `` + }
); } - - // wrapInForm(state: State, content: Templatable): Templatable { - // return tempstream/* HTML */ ` - // ${super.wrapInForm(state, content)} - // `; - // } })(); diff --git a/src/back/routes/index.ts b/src/back/routes/index.ts index e2111b5..02c88d7 100644 --- a/src/back/routes/index.ts +++ b/src/back/routes/index.ts @@ -4,11 +4,16 @@ import { MainView } from "./common/main-view.js"; import mountAutoRoutes from "./routes.js"; export const mainRouter = (router: Router): void => { + const started_at = Date.now(); // necessary to detect aplication restarts + router.get("/", Middlewares.extractContext(), async (ctx) => { ctx.body = MainView(ctx); }); router.use(Middlewares.extractContext()); + router.get("/status.json", Middlewares.extractContext(), async (ctx) => { + ctx.body = { status: ctx.$app.status, started_at }; + }); mountAutoRoutes(router); };