From 44f934b4b9abc6d7dfa0c41b0765d59d44241877 Mon Sep 17 00:00:00 2001 From: Rizky Date: Fri, 16 Aug 2024 11:18:55 +0700 Subject: [PATCH] fix --- app/srv/package.json | 1 + app/srv/ws/sync/code/parts/init/frontend.ts | 77 ++-------------- app/srv/ws/sync/code/parts/internal.ts | 3 +- app/srv/ws/sync/code/parts/watcher.ts | 92 ++++++++++++++++++++ bun.lockb | Bin 284320 -> 284352 bytes dockerzip | Bin 4801 -> 4830 bytes 6 files changed, 100 insertions(+), 73 deletions(-) create mode 100644 app/srv/ws/sync/code/parts/watcher.ts diff --git a/app/srv/package.json b/app/srv/package.json index 902ffad4..37a72e01 100644 --- a/app/srv/package.json +++ b/app/srv/package.json @@ -6,6 +6,7 @@ "@hyrious/esbuild-plugin-style": "^0.3.5", "@node-rs/argon2": "^1.5.2", "@paralleldrive/cuid2": "^2.2.2", + "@parcel/watcher": "^2.4.1", "@types/lodash.isequal": "^4.5.8", "@types/mime-types": "^2.1.4", "esbuild": "^0.21.5", diff --git a/app/srv/ws/sync/code/parts/init/frontend.ts b/app/srv/ws/sync/code/parts/init/frontend.ts index 2382a544..444f1aeb 100644 --- a/app/srv/ws/sync/code/parts/init/frontend.ts +++ b/app/srv/ws/sync/code/parts/init/frontend.ts @@ -4,7 +4,6 @@ import { $ } from "bun"; import { dir } from "dir"; import { context, formatMessages } from "esbuild"; import { cleanPlugin } from "esbuild-clean-plugin"; -import { watch } from "fs"; import { existsAsync } from "fs-jetpack"; import { appendFile } from "node:fs/promises"; import { conns } from "../../../entity/conn"; @@ -12,6 +11,7 @@ import { user } from "../../../entity/user"; import { sendWS } from "../../../sync-handler"; import { SyncType } from "../../../type"; import { code } from "../../code"; +import { Watcher } from "../watcher"; const pending = {} as any; export const initFrontEnd = async ( @@ -50,83 +50,16 @@ export const initFrontEnd = async ( try { await isInstalling(id_site); - const broadcastLoading = async () => { - const client_ids = user.active - .findAll({ site_id: id_site }) - .map((e) => e.client_id); - - const now = Date.now(); - - client_ids.forEach((client_id) => { - const ws = conns.get(client_id)?.ws; - if (ws) - sendWS(ws, { - type: SyncType.Event, - event: "code_changes", - data: { ts: now, mode: "frontend", status: "building" }, - }); - }); - }; + if (code.internal.frontend[id_site]?.watch) { + await code.internal.frontend[id_site].watch.close(); + } code.internal.frontend[id_site] = { - ...(code.internal.frontend[id_site] || {}), ctx: await initBuildCtx({ id_site, root }), timeout: null, rebuilding: false, + watch: new Watcher(dir.data(root), id_site), }; - - if (code.internal.frontend[id_site].watch) { - code.internal.frontend[id_site].watch.close(); - } - console.log("watching", dir.data(root)); - code.internal.frontend[id_site].watch = watch( - dir.data(root), - { - recursive: true, - persistent: true - }, - async (event, filename) => { - const fe = code.internal.frontend[id_site]; - const srv = code.internal.server[id_site]; - - if ( - filename?.startsWith("node_modules") || - filename?.startsWith("typings") || - filename?.endsWith(".log") - ) - return; - - console.log( - event, - filename, - typeof fe !== "undefined" && !fe.rebuilding - ? "start-rebuild" - : "rebuilding..." - ); - if ( - filename?.endsWith(".tsx") || - filename?.endsWith(".ts") || - filename?.endsWith(".css") || - filename?.endsWith(".html") - ) { - if (typeof fe !== "undefined" && !fe.rebuilding) { - fe.rebuilding = true; - clearTimeout(fe.timeout); - fe.timeout = setTimeout(async () => { - try { - broadcastLoading(); - await fe.ctx.rebuild(); - fe.rebuilding = false; - } catch (e: any) { - console.error(`Frontend failed rebuild (site: ${id_site})`); - console.error(e.message); - fe.rebuilding = false; - } - }, 500); - } - } - } - ); const fe = code.internal.frontend[id_site]; fe.rebuilding = true; try { diff --git a/app/srv/ws/sync/code/parts/internal.ts b/app/srv/ws/sync/code/parts/internal.ts index 1d313a31..2699a3b8 100644 --- a/app/srv/ws/sync/code/parts/internal.ts +++ b/app/srv/ws/sync/code/parts/internal.ts @@ -2,6 +2,7 @@ import Parcel from "@parcel/core"; import { Subprocess } from "bun"; import type { BuildContext } from "esbuild"; import { FSWatcher } from "fs"; +import { Watcher } from "./watcher"; const g = global as unknown as { prasi_code: any; }; @@ -24,7 +25,7 @@ export const codeInternal = { { ctx: BuildContext; timeout: any; - watch?: FSWatcher; + watch?: Watcher; rebuilding: boolean; npm?: Promise; } diff --git a/app/srv/ws/sync/code/parts/watcher.ts b/app/srv/ws/sync/code/parts/watcher.ts new file mode 100644 index 00000000..3a9788d6 --- /dev/null +++ b/app/srv/ws/sync/code/parts/watcher.ts @@ -0,0 +1,92 @@ +import watcher, { AsyncSubscription } from "@parcel/watcher"; +import { readdir } from "node:fs/promises"; +import { statSync } from "node:fs"; +import { join } from "path"; +import { code } from "../code"; +import { user } from "../../entity/user"; +import { conns } from "../../entity/conn"; +import { sendWS } from "../../sync-handler"; +import { SyncType } from "../../type"; +export class Watcher { + subcription = null as null | AsyncSubscription; + + constructor(path: string, id_site: string) { + this.init(path, id_site); + // watcher.subscribe(path, (err, events) => { + // console.log(events); + // }); + // watch( + // path, + // { + // recursive: true, + // persistent: true, + // }, + // async (event, filename) => { + // } + // ); + } + + async init(path: string, id_site: string) { + const broadcastLoading = async () => { + const client_ids = user.active + .findAll({ site_id: id_site }) + .map((e) => e.client_id); + + const now = Date.now(); + + client_ids.forEach((client_id) => { + const ws = conns.get(client_id)?.ws; + if (ws) + sendWS(ws, { + type: SyncType.Event, + event: "code_changes", + data: { ts: now, mode: "frontend", status: "building" }, + }); + }); + }; + + this.subcription = await watcher.subscribe(path, (err, events) => { + for (const e of events) { + const filename = e.path.substring(path.length + 1); + if (e.type === "create" || e.type === "update") { + const fe = code.internal.frontend[id_site]; + if ( + filename?.startsWith("node_modules") || + filename?.startsWith("typings") || + filename?.endsWith(".log") + ) + return; + + if ( + filename?.endsWith(".tsx") || + filename?.endsWith(".ts") || + filename?.endsWith(".css") || + filename?.endsWith(".html") + ) { + if (typeof fe !== "undefined" && !fe.rebuilding) { + fe.rebuilding = true; + clearTimeout(fe.timeout); + fe.timeout = setTimeout(async () => { + try { + broadcastLoading(); + await fe.ctx.rebuild(); + fe.rebuilding = false; + } catch (e: any) { + console.error(`Frontend failed rebuild (site: ${id_site})`); + console.error(e.message); + fe.rebuilding = false; + } + }, 500); + } + } + } + } + }); + } + + async close() { + if (this.subcription) { + await this.subcription.unsubscribe(); + } + } +} diff --git a/bun.lockb b/bun.lockb index aba236dd6ae53f7c7e6c21f4a234ec7c733b8f2f..f35e3a41eb9d5848deb39b134110005912d63b8a 100755 GIT binary patch delta 4493 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 A5dZ)H diff --git a/dockerzip b/dockerzip index 02c8b7a30871bb03b113ff299e8e40d114511de3..bf2435989ce1982b2671b1929683f876b87ca6e0 100644 GIT binary patch delta 1690 zcmX@8dQX)%z?+$civa|pBLpV$O0nmj-uF`{uBK zgeJ$b%EH8e`oYR3&tuhui=AUl1*m>3vD7-S}2eKTeG zl#d--o0G67CAr^7V%@>$?ehMenRDLdJY!mQYKzo9R~}pO?{>znlQ%B7@IxhHle3kY z!(s8vSL;$|*qw_$K9#l8#*>lb=8h9CPq)7g&}=W**E+HM)^tU0@74{8GT}a_HR`o* zznJB#wkF}yZ!H(e-d&940pW+dLlSmQ%3@x=sx*DgzCQ7u)^Aq+VRLsao0j#?I=g+} z!aWz5o$J4P&W~Q$vVUgv%M0D_>JEKAvT2va+Tcr{qU-b0Dylnwhc8$i?^o&d-0S(p zZ}ts6a=sZUTF2X-a_wpp3pn=q!AiULf25YS)$hJ5diQF;f&b~3{c;&CPo9|Sb9~QS z>-O6ZmNG?M*uGD!^rOLnun+Cmub$KYc=0KY8*cvb4EO=E>64T zqSU_03s1gTJR|nRRI?cu(+$Np3wJ4mK4H{ZG2^EC$D+iSOTX%`F5upHBDS~BKERui zNsbv@s<42{o5^Q+H9(Ovc>$jcIHtwkK zaGeO(uN07GtekvQKptkJ3A&kFC}w_!nF-A!s75+~G`svia77uI%7 z(VP?NAh2fCuF`{uBK zgeJ$b%EH8e`oYR3&tuhui=AUl1*P|-8WBPR7^ncyNmK%zin%h>KcG$|GbvQzC{p}ZveyJZiW&a{}oo>|S zlKL(CUL-`j?3-m&rz@^>XyLMD@sFn6R=AdX>hSv4<<=!GbFEe@oZo)7=eebS;G^{G z=1q$?e12&0Os+5eM@5DG)Tx12x6Cv8p1S)tKT0%5g5w)XurkOn6lA9t>xYJ*2lwQ5 zRz5@;nC!@*2#-lv?6z^}!o|+9%1^$@p#qBGNt_CBVVF`EP92!o=5kJ3MsP~l&ZP~FRM5|582(5-FcMie`xv6 z-e90LG4{lPYf_JQPfv{8o&Br$!GZ6_HO2>0kKNcamG{i{oOgk2hfOP9pZlz8*n4^I z*%*h=nPG>QcPxDV=w|w|3?nfSsrf9?WuCWLGJYud-rdS``O%)zn8*nyCW|yoXzun2 z`L~0AY7xiwV2R4{jNyHB!5lP0M;`oqc@Y#yuC5o$J3WIKMXF(EKxdOWwGCuRnDA z$fjKuYlAO+s;)ZlrSc3!I7@|ShO#l@VxK2LA#h;jUWf$3C*w9VD$ zbMG&{@*%&x-ql=^>&O0_TPu|n)FpRLdO0ip`N@Zd6)PL$US!92@2Ze^?zMYM<>|IB zq6)kVLfPE%ce#nLeW)%e<@NEOMp%;VlpC4NlC@&l8>IqRRx0r)I37J?*Ev0ZT3yip zVy^9iv*%Qm{bdU9W@M6Mh8GY>Now*}URhAKoxG7>3@P=P@aaHBWxz4t#Aks;)g3-< z6jhr1=2%oU@x#sHMJYQb-{RN9qFzftTJSkL11z1hf{PW9`&6-cfPsOVK?0gP1Q^~r zs!g6KAPjSrBgnpA-=bnPfhu%>SRASrm^vAjG-h)^ZAnQ=PtDUuO{WNZt+3n6g<|hh zm|4mBMXA8-3D+(o4|0Ud{{vT)fwtBI3rsN-M`%v&7nH*i4Ce)