Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 5 additions & 1 deletion apps/server/scripts/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,11 @@ const publishCmd = Command.make(
const packageJsonPath = path.join(serverDir, "package.json");

// Assert build assets exist
for (const relPath of ["dist/bin.mjs", "dist/client/index.html"]) {
for (const relPath of [
"dist/bin.mjs",
"dist/service-launcher.mjs",
"dist/client/index.html",
]) {
const abs = path.join(serverDir, relPath);
if (!(yield* fs.exists(abs))) {
return yield* new ServerCliBuildAssetMissingError({ assetPath: abs });
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { sharedServerCommandFlags } from "./cli/config.ts";
import { projectCommand } from "./cli/project.ts";
import { runServerCommand, serveCommand, startCommand } from "./cli/server.ts";
import { serviceCommand } from "./cli/service.ts";
import { servicePreflightCommand } from "./cli/servicePreflight.ts";

const CliRuntimeLayer = Layer.mergeAll(NodeServices.layer, NetService.layer);

Expand Down Expand Up @@ -53,6 +54,7 @@ export const makeCli = ({ cloudEnabled = hasCloudPublicConfig } = {}) =>
authCommand,
projectCommand,
serviceCommand,
servicePreflightCommand,
cloudEnabled ? connectCommand : connectUnavailableCommand,
]),
);
Expand Down
19 changes: 18 additions & 1 deletion apps/server/src/cli/server.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as Effect from "effect/Effect";
import * as Runtime from "effect/Runtime";
import { Command, GlobalFlag } from "effect/unstable/cli";

import { ServerConfig, type StartupPresentation } from "../config.ts";
import { runServer } from "../server.ts";
import * as ServerShutdown from "../serverShutdown.ts";
import { type CliServerFlags, resolveServerConfig, sharedServerCommandFlags } from "./config.ts";

export const runServerCommand = (
Expand All @@ -15,9 +17,24 @@ export const runServerCommand = (
Effect.gen(function* () {
const logLevel = yield* GlobalFlag.LogLevel;
const config = yield* resolveServerConfig(flags, logLevel, options);
return yield* runServer.pipe(Effect.provideService(ServerConfig, config));
return yield* Effect.raceFirst(
runServer,
ServerShutdown.awaitRequest.pipe(
Effect.flatMap((exitCode) => Effect.fail(new ServerRequestedExit(exitCode))),
),
).pipe(Effect.provideService(ServerConfig, config));
});

class ServerRequestedExit extends Error {
override readonly [Runtime.errorReported] = false;
override readonly [Runtime.errorExitCode]: number;

constructor(exitCode: number) {
super(`Server requested exit ${String(exitCode)}.`);
this[Runtime.errorExitCode] = exitCode;
}
}

export const startCommand = Command.make("start", { ...sharedServerCommandFlags }).pipe(
Command.withDescription("Run the T3 Code server."),
Command.withHandler((flags) => runServerCommand(flags)),
Expand Down
3 changes: 2 additions & 1 deletion apps/server/src/cli/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ export function formatServiceStatus(
}
return [
"T3 Code service",
` Status: ${status.current ? `installed · t3@${cliVersion}` : "needs an update or repair"}`,
` Status: ${status.current ? `installed · t3@${status.activeVersion ?? cliVersion}` : "needs an update or repair"}`,
...(status.updateStatus === undefined ? [] : [` Last update: ${status.updateStatus}`]),
` Unit: ${status.unitPath}`,
` Logs: ${status.logPath}`,
...(status.current ? [] : [" Next: Run `npx t3@latest service update`."]),
Expand Down
17 changes: 17 additions & 0 deletions apps/server/src/cli/servicePreflight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as Console from "effect/Console";
import * as Effect from "effect/Effect";
import { Command, Flag } from "effect/unstable/cli";

import { runServicePreflight } from "../cloud/servicePreflight.ts";

export const servicePreflightCommand = Command.make("__service-preflight", {
databasePath: Flag.string("database-path"),
launcherProtocol: Flag.integer("launcher-protocol"),
}).pipe(
Command.withHidden,
Command.withHandler(({ databasePath, launcherProtocol }) =>
Console.log(JSON.stringify(runServicePreflight({ databasePath, launcherProtocol }))).pipe(
Effect.asVoid,
),
),
);
Loading
Loading