diff --git a/packages/workerd/src/plugin.ts b/packages/workerd/src/plugin.ts index d232ffd..b86612c 100644 --- a/packages/workerd/src/plugin.ts +++ b/packages/workerd/src/plugin.ts @@ -157,22 +157,26 @@ export async function createWorkerdDevEnvironment( const ns = await miniflare.getDurableObjectNamespace("__viteRunner"); const runnerObject = ns.get(ns.idFromName("")); + // init via rpc + await (runnerObject as any).__viteInit(); // initial request to setup websocket - const initResponse = await runnerObject.fetch(ANY_URL + RUNNER_INIT_PATH, { - headers: { - Upgrade: "websocket", - }, - }); - tinyassert(initResponse.webSocket); - const { webSocket } = initResponse; - webSocket.accept(); + if (0) { + const initResponse = await runnerObject.fetch(ANY_URL + RUNNER_INIT_PATH, { + headers: { + Upgrade: "websocket", + }, + }); + tinyassert(initResponse.webSocket); + const { webSocket } = initResponse; + webSocket.accept(); + } // websocket hmr channgel let hotListener: (data: unknown) => void; const hot = createSimpleHMRChannel({ post: (data) => { (runnerObject as any).__viteServerSend(data); - webSocket.send(data); + // webSocket.send(data); }, on: (listener) => { hotListener = listener; diff --git a/packages/workerd/src/worker.ts b/packages/workerd/src/worker.ts index f35153f..04e16f6 100644 --- a/packages/workerd/src/worker.ts +++ b/packages/workerd/src/worker.ts @@ -1,5 +1,6 @@ import { DurableObject } from "cloudflare:workers"; import { objectPickBy, tinyassert } from "@hiogawa/utils"; +import type { HotPayload } from "vite"; import { ModuleRunner, ssrImportMetaKey, @@ -18,6 +19,7 @@ import { export class RunnerObject extends DurableObject { #env: RunnerEnv; #runner?: ModuleRunner; + #viteServerSend!: (payload: HotPayload) => void; constructor(...args: ConstructorParameters) { super(...args); @@ -37,14 +39,65 @@ export class RunnerObject extends DurableObject { } } - async __vite_init() { - console.log("!!vite init!!"); - return "foo"; + async __viteInit() { + const env = this.#env; + this.#runner = new ModuleRunner( + { + root: env.__viteRoot, + sourcemapInterceptor: "prepareStackTrace", + transport: { + fetchModule: async (...args) => { + const response = await env.__viteFetchModule.fetch( + new Request(ANY_URL, { + method: "POST", + body: JSON.stringify(args), + }), + ); + tinyassert(response.ok); + const result = response.json(); + return result as any; + }, + }, + hmr: { + connection: { + isReady: () => true, + onUpdate: (callback) => { + this.#viteServerSend = callback; + }, + send: (payload) => { + env.__viteRunnerSend.fetch( + new Request(ANY_URL, { + method: "POST", + body: JSON.stringify(payload), + }), + ); + }, + }, + }, + }, + { + runInlinedModule: async (context, transformed) => { + const codeDefinition = `'use strict';async (${Object.keys( + context, + ).join(",")})=>{{`; + const code = `${codeDefinition}${transformed}\n}}`; + const fn = env.__viteUnsafeEval.eval( + code, + context[ssrImportMetaKey].filename, + ); + await fn(...Object.values(context)); + Object.freeze(context[ssrModuleExportsKey]); + }, + async runExternalModule(filepath) { + return import(filepath); + }, + }, + ); + return { ok: true }; } - // TODO async __viteServerSend(payload: string) { - payload; + this.#viteServerSend(JSON.parse(payload)); } async #fetch(request: Request) {