From 663343c4a893044f92283b8283f560784e1a74af Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Sun, 27 Oct 2024 13:55:19 +0900 Subject: [PATCH] refactor: createHotListenerManager --- examples/react-ssr-workerd/public/favicon.ico | Bin 0 -> 4286 bytes packages/workerd/src/plugin.ts | 81 ++++++++---------- 2 files changed, 36 insertions(+), 45 deletions(-) create mode 100644 examples/react-ssr-workerd/public/favicon.ico diff --git a/examples/react-ssr-workerd/public/favicon.ico b/examples/react-ssr-workerd/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..4aff076603f8f01fb3b7d8b5e38df77cc1efdd69 GIT binary patch literal 4286 zcmc(jeOQ&{9mmi9Y5(N4wKaEHmR6cpj%~hXo13+jb7bn2986aeCEr<~nOgZmpr$E` zf`o4brE!#(M1gZu646vl&`1pxMdw?|n=m>c+@F0P;mO>tlyk0ib#r~sdCqh0=e|Gp z@BY2q2Z!Sa`s>)yVZAyw{@CGY>u@-_O1kCfFIo4mH+}bzU$dHTI2`!e8Vx4;1ZKh^ zxKi)yD84^;xC-;kZcMM8u;Hxl=0 zrl(}R$D9P?+i+ezRaK9fv=7rK8`IkjJ!J!H{(<@MS+!R~`O?{>ox=Qa3-rsRXz(63 z2OX9VwCuy2qfp=E%do9`=6nq%BuDe7!jtKI6u6hZ(Up|S59#T~^xp-0ue5F~Z+jVS zZek&3&_;~E69#PN+~91w#MclR`Z@H~e)M!gs0@p&odJ103qFqWoKTLTHzP(@mAxzj(#e6hoycovD(ij}ivB{e#lRuP=cG5k$iaRo)dtx=G zM`-QOi1(><%*tYDlHdB;$}2ES5-{NlF)zQ3nIet}%c&n1$C&sM{8FwGkZ_g`sUGg! z3T>ptZyW}H`KjW=1Y|*Rxo@*u@#a=udF@Tij3~@2VhCG&oq>tVm=kl5JGI?yq#tEV znyQW7d%s`BnUNog;R7)^G4l^7CpCJ{a9%Yn`Yp_y*_byXFtZ{t(-+7Viy(9{&V^aD zbs2uD6#Nr0*t#nRmP8cFH{WZ{6~oeCpO^7?twAxY_*(EPM7@rgXEDr!SrITj3c}}8 zG&hNdv%li*9q=>hZiT(2yL8>xDH{YUC=?&&*$uMcN6JZFoDoXp$8j^YkZG`J2F#yD zT~q{{;?mf*+{vkkRh*ogz;80kX{(g`^V}P1yAv!$FZ=}TTrvCu$T`)zJ@6=Iw#2~7 zDX=^omRbzcx$<@-Pv=~u!|o<}xvTke<^?+EHqb5)?vdJw!(HPN#foO70Yl-k>>`W6NT?SD*WDt)y&<{AiS7Soz8*XK=RiTNo5?#oDKo7j&K*4as9+{Y$WBf^0FF zhPW_7T*Y)e2oGsl4=Su|Js>7q|IHS&LZG8pDR+w@NcCf#pc|Y1m!a|mxHMN<5IFx1 z8~>pkE;}TKz}oRNCQKpRUBH8fptD@dQYW$4vY4(*To35FgLJ?22Ui7UQ&lU1W0kw( zmA{hV*u|UYZ&JK{x(u?0L*`#0{co^Y3@IiNbQp!w zO~^{sk=0O8+H8YsRd7@>zI!0-dJcAo!6iFvdtPxEsQr*FoZ{FpidEZFc~oV-Tk*|$ zOiZ@A>Uvn-1u7yJ!OXeJSCKGPdDF_>p{gGfEe6%GMd?tjc)TqC{6ur_9{_tS27fUO z62lPLLUzcOFS-?jc~K-4?ZfXl{PI|{{KR7G7oUNpZc?8j4+TjnD#%v;R^FZ=O;ZgC zQw<4K9kXibq*$#{4s=ZGD|!+NHE*G=kG!mVVn4kRE-IKSOQ7zG>Zpg*Dnk!_{PpKI z^ege$`kG68tF7N7moCV*M=`td75h4u#3o_hR4h!F4JOMLvlF2rN59`Pl%M4|o^y(g zS}=__`)A81R}DOVN=Mz3(8JOR)qGpx>fXX;*=W+gG@L^E>t@wck4JM=z=<;1T8?r+ z2K1tp)T{Jd($Pnl{u<(`)5^1QqbH<3;_5B+5|_m^P~VlR|NpaD%c*J7PrU}Yugsfq z6=KWbwaXB4Ua4MOgTyu9jE-TFWv}nL35VJirUPP1tyZ~^yM!slY|{1Zn*D!(@9X_P D`VsgZ literal 0 HcmV?d00001 diff --git a/packages/workerd/src/plugin.ts b/packages/workerd/src/plugin.ts index 75bde5cf..52910560 100644 --- a/packages/workerd/src/plugin.ts +++ b/packages/workerd/src/plugin.ts @@ -1,6 +1,5 @@ import { fileURLToPath } from "node:url"; import type { Fetcher } from "@cloudflare/workers-types/experimental"; -import { DefaultMap } from "@hiogawa/utils"; import { webToNodeHandler } from "@hiogawa/utils-node"; import { Miniflare, @@ -10,7 +9,6 @@ import { mergeWorkerOptions, } from "miniflare"; import { - type CustomPayload, DevEnvironment, type HotChannel, type Plugin, @@ -111,7 +109,7 @@ export async function createWorkerdDevEnvironment( }, __viteRunnerSend: async (request) => { const payload = await request.json(); - hotListener(payload); + hotListener.dispatch(payload); return MiniflareResponse.json(null); }, }, @@ -153,19 +151,18 @@ export async function createWorkerdDevEnvironment( // init via rpc await runnerObject.__viteInit(); - // hmr channgel - let hotListener: (data: unknown) => void; - const hot = createSimpleHMRChannel({ - post: (data) => { - runnerObject.__viteServerSend(data); - }, - on: (listener) => { - hotListener = listener; - return () => {}; + // hmr channel + const hotListener = createHotListenerManager(); + const hot: HotChannel = { + listen: () => {}, + close: () => {}, + on: hotListener.on, + off: hotListener.off, + send(...args: any[]) { + const payload = normalizeServerSendPayload(...args); + runnerObject.__viteServerSend(payload); }, - serialize: (v) => v, - deserialize: (v) => v, - }); + }; // TODO: move initialization code to `init`? // inheritance to extend dispose @@ -207,40 +204,34 @@ export async function createWorkerdDevEnvironment( return Object.assign(devEnv, { api }) as WorkerdDevEnvironment; } -// cf. -// https://github.com/vitejs/vite/blob/feat/environment-api/packages/vite/src/node/server/hmr.ts/#L909-L910 -// https://github.com/vitejs/vite/blob/feat/environment-api/packages/vite/src/node/ssr/runtime/serverHmrConnector.ts/#L33-L34 -function createSimpleHMRChannel(options: { - post: (data: any) => any; - on: (listener: (data: any) => void) => () => void; - serialize: (v: any) => any; - deserialize: (v: any) => any; -}): HotChannel { - const listerMap = new DefaultMap>(() => new Set()); - let dispose: (() => void) | undefined; +// wrapper to simplify listener management +function createHotListenerManager(): Pick & { + dispatch: (payload: any) => void; +} { + const listerMap: Record> = {}; + const getListerMap = (e: string) => (listerMap[e] ??= new Set()); return { - listen() { - dispose = options.on((data) => { - const payload = options.deserialize(data) as CustomPayload; - for (const f of listerMap.get(payload.event)) { - f(payload.data); - } - }); - }, - close() { - dispose?.(); - dispose = undefined; - }, - on(event: string, listener: (...args: any[]) => any) { - listerMap.get(event).add(listener); + on(event: string, listener: Function) { + // console.log("[channel.on]", event, listener); + if (event === "connection") { + return; + } + getListerMap(event).add(listener); }, - off(event: string, listener: (...args: any[]) => any) { - listerMap.get(event).delete(listener); + off(event, listener: any) { + // console.log("[channel.off]", event, listener); + if (event === "connection") { + return; + } + getListerMap(event).delete(listener); }, - send(...args: any[]) { - const payload = normalizeServerSendPayload(...args); - options.post(options.serialize(payload)); + dispatch(payload) { + if (payload.type === "custom") { + for (const lister of getListerMap(payload.event)) { + lister(payload.data); + } + } }, }; }