Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions apps/desktop/scripts/dev-electron.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import waitOn from "wait-on";

import { desktopDir, resolveElectronPath } from "./electron-launcher.mjs";

const port = Number(process.env.ELECTRON_RENDERER_PORT ?? 5733);
const devServerUrl = `http://localhost:${port}`;
const rendererPort = Number(process.env.ELECTRON_RENDERER_PORT ?? 5733);
const devServerUrl = process.env.VITE_DEV_SERVER_URL?.trim() || `http://localhost:${rendererPort}`;
const parsedDevServerUrl = new URL(devServerUrl);
const devServerPort = Number(
parsedDevServerUrl.port || (parsedDevServerUrl.protocol === "https:" ? 443 : 80),
);
const requiredFiles = [
"dist-electron/main.js",
"dist-electron/preload.js",
Expand All @@ -21,7 +25,7 @@ const restartDebounceMs = 120;
const childTreeGracePeriodMs = 1_200;

await waitOn({
resources: [`tcp:${port}`, ...requiredFiles.map((filePath) => `file:${filePath}`)],
resources: [`tcp:${devServerPort}`, ...requiredFiles.map((filePath) => `file:${filePath}`)],
});

const childEnv = { ...process.env };
Expand Down
13 changes: 12 additions & 1 deletion apps/web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import { defineConfig } from "vite";
import pkg from "./package.json" with { type: "json" };

const port = Number(process.env.PORT ?? 5733);
const DEFAULT_DEV_HOST = "127.0.0.1";
const isWildcardHost = (host: string): boolean =>
host === "0.0.0.0" || host === "::" || host === "[::]";
const configuredHost = process.env.T3CODE_HOST?.trim();
const resolvedHost = configuredHost === "[::]" ? "::" : configuredHost;
const bindHost = resolvedHost && resolvedHost !== "localhost" ? resolvedHost : DEFAULT_DEV_HOST;
const hmrHost =
!resolvedHost || resolvedHost === "localhost" || isWildcardHost(resolvedHost)
? DEFAULT_DEV_HOST
: resolvedHost;
const sourcemapEnv = process.env.T3CODE_WEB_SOURCEMAP?.trim().toLowerCase();

const buildSourcemap =
Expand Down Expand Up @@ -41,14 +51,15 @@ export default defineConfig({
tsconfigPaths: true,
},
server: {
host: bindHost,
port,
strictPort: true,
hmr: {
// Explicit config so Vite's HMR WebSocket connects reliably
// inside Electron's BrowserWindow. Vite 8 uses console.debug for
// connection logs — enable "Verbose" in DevTools to see them.
protocol: "ws",
host: "localhost",
host: hmrHost,
},
},
build: {
Expand Down
26 changes: 25 additions & 1 deletion scripts/dev-runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ it.layer(NodeServices.layer)("dev-runner", (it) => {
]);

assert.equal(env.T3CODE_STATE_DIR, defaultStateDir);
assert.equal(env.VITE_WS_URL, "ws://127.0.0.1:3773");
assert.equal(env.VITE_DEV_SERVER_URL, "http://127.0.0.1:5733");
}),
);

Expand All @@ -89,7 +91,7 @@ it.layer(NodeServices.layer)("dev-runner", (it) => {

assert.equal(env.T3CODE_STATE_DIR, resolve("/tmp/override-state"));
assert.equal(env.T3CODE_PORT, "4222");
assert.equal(env.VITE_WS_URL, "ws://localhost:4222");
assert.equal(env.VITE_WS_URL, "ws://127.0.0.1:4222");
assert.equal(env.T3CODE_NO_BROWSER, "1");
assert.equal(env.T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD, "0");
assert.equal(env.T3CODE_LOG_WS_EVENTS, "1");
Expand All @@ -98,6 +100,28 @@ it.layer(NodeServices.layer)("dev-runner", (it) => {
}),
);

it.effect("formats IPv6 hosts correctly in dev URLs", () =>
Effect.gen(function* () {
const env = yield* createDevRunnerEnv({
mode: "dev",
baseEnv: {},
serverOffset: 0,
webOffset: 0,
stateDir: undefined,
authToken: undefined,
noBrowser: undefined,
autoBootstrapProjectFromCwd: undefined,
logWebSocketEvents: undefined,
host: "::1",
port: 4222,
devUrl: undefined,
});

assert.equal(env.VITE_WS_URL, "ws://[::1]:4222");
assert.equal(env.VITE_DEV_SERVER_URL, "http://[::1]:5733");
}),
);

it.effect("does not force websocket logging on in dev mode when unset", () =>
Effect.gen(function* () {
const env = yield* createDevRunnerEnv({
Expand Down
21 changes: 19 additions & 2 deletions scripts/dev-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const BASE_SERVER_PORT = 3773;
const BASE_WEB_PORT = 5733;
const MAX_HASH_OFFSET = 3000;
const MAX_PORT = 65535;
const DEFAULT_DEV_HOST = "127.0.0.1";

export const DEFAULT_DEV_STATE_DIR = Effect.map(Effect.service(Path.Path), (path) =>
path.join(homedir(), ".t3", "dev"),
Expand Down Expand Up @@ -130,6 +131,21 @@ interface CreateDevRunnerEnvInput {
readonly devUrl: URL | undefined;
}

const isWildcardHost = (host: string): boolean =>
host === "0.0.0.0" || host === "::" || host === "[::]";

const formatHostForUrl = (host: string): string =>
host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;

const resolveDevHost = (host: string | undefined): string => {
const trimmedHost = host?.trim();
if (!trimmedHost || trimmedHost === "localhost" || isWildcardHost(trimmedHost)) {
return DEFAULT_DEV_HOST;
}

return trimmedHost;
};

export function createDevRunnerEnv({
mode,
baseEnv,
Expand All @@ -148,14 +164,15 @@ export function createDevRunnerEnv({
const serverPort = port ?? BASE_SERVER_PORT + serverOffset;
const webPort = BASE_WEB_PORT + webOffset;
const resolvedStateDir = yield* resolveStateDir(stateDir);
const webHost = resolveDevHost(host);

const output: NodeJS.ProcessEnv = {
...baseEnv,
T3CODE_PORT: String(serverPort),
PORT: String(webPort),
ELECTRON_RENDERER_PORT: String(webPort),
VITE_WS_URL: `ws://localhost:${serverPort}`,
VITE_DEV_SERVER_URL: devUrl?.toString() ?? `http://localhost:${webPort}`,
VITE_WS_URL: `ws://${formatHostForUrl(webHost)}:${serverPort}`,
VITE_DEV_SERVER_URL: devUrl?.toString() ?? `http://${formatHostForUrl(webHost)}:${webPort}`,
T3CODE_STATE_DIR: resolvedStateDir,
};

Expand Down
1 change: 1 addition & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"T3CODE_PORT",
"T3CODE_NO_BROWSER",
"T3CODE_STATE_DIR",
"T3CODE_HOST",
"T3CODE_AUTH_TOKEN",
"T3CODE_DESKTOP_WS_URL"
],
Expand Down