import type { EnvironmentShellSummary } from "@t3tools/client-runtime/state/shell";import { BearerConnectionProfile, BearerConnectionTarget,} from "@t3tools/client-runtime/connection";import { EnvironmentId } from "@t3tools/contracts";import { describe, expect, it } from "@effect/vitest";import * as Option from "effect/Option"; import { projectWorkspaceEnvironment, projectWorkspaceState } from "./workspaceModel";import type { EnvironmentPresentation } from "./environments"; const ENVIRONMENT_ID = EnvironmentId.make("environment-1"); function environment( phase: EnvironmentPresentation["connection"]["phase"],): EnvironmentPresentation { const connectionId = `bearer:${ENVIRONMENT_ID}`; return { environmentId: ENVIRONMENT_ID, label: "Julius's MacBook Pro", displayUrl: "https://environment.example.test", relayManaged: false, entry: { target: new BearerConnectionTarget({ environmentId: ENVIRONMENT_ID, label: "Julius's MacBook Pro", connectionId, }), profile: Option.some( new BearerConnectionProfile({ connectionId, environmentId: ENVIRONMENT_ID, label: "Julius's MacBook Pro", httpBaseUrl: "https://environment.example.test", wsBaseUrl: "wss://environment.example.test", }), ), }, connection: { phase, error: phase === "error" ? "Connection failed." : null, traceId: phase === "error" ? "trace-1" : null, }, serverConfig: null, };} const EMPTY_SHELL_SUMMARY: EnvironmentShellSummary = { hasSnapshot: false, hasSynchronizingShell: false, hasCachedShell: false, hasLiveShell: false, firstError: null, latestSnapshotUpdatedAt: null,}; const CACHED_SHELL_SUMMARY: EnvironmentShellSummary = { ...EMPTY_SHELL_SUMMARY, hasSnapshot: true, hasSynchronizingShell: true, hasCachedShell: true, latestSnapshotUpdatedAt: "2026-06-07T00:00:00.000Z",}; describe("mobile workspace projection", () => { it("preserves explicit offline state without presenting it as a connection error", () => { const projected = projectWorkspaceEnvironment(environment("offline")); expect(projected.connectionState).toBe("offline"); expect(projected.connectionError).toBeNull(); }); it("reports offline before stale connected presentations", () => { const environments = [projectWorkspaceEnvironment(environment("connected"))]; const state = projectWorkspaceState({ isReady: true, networkStatus: "offline", environments, shellSummary: EMPTY_SHELL_SUMMARY, }); expect(state.connectionState).toBe("offline"); expect(state.networkStatus).toBe("offline"); expect(state.hasReadyEnvironment).toBe(false); }); it("projects reconnecting environments dynamically from active phases", () => { const environments = [ projectWorkspaceEnvironment(environment("reconnecting")), projectWorkspaceEnvironment({ ...environment("connected"), environmentId: EnvironmentId.make("environment-2"), }), ]; const state = projectWorkspaceState({ isReady: true, networkStatus: "online", environments, shellSummary: EMPTY_SHELL_SUMMARY, }); expect(state.connectingEnvironments).toHaveLength(1); expect(state.connectingEnvironments[0]?.connectionState).toBe("reconnecting"); expect(state.hasConnectingEnvironment).toBe(true); expect(state.hasReadyEnvironment).toBe(true); }); it("keeps retained snapshots visible while reconnecting without claiming readiness", () => { const environments = [projectWorkspaceEnvironment(environment("reconnecting"))]; const state = projectWorkspaceState({ isReady: true, networkStatus: "online", environments, shellSummary: CACHED_SHELL_SUMMARY, }); expect(state.hasLoadedShellSnapshot).toBe(true); expect(state.hasPendingShellSnapshot).toBe(true); expect(state.hasReadyEnvironment).toBe(false); expect(state.connectionState).toBe("reconnecting"); });});
import type { EnvironmentShellSummary } from "@t3tools/client-runtime/state/shell";
import {
BearerConnectionProfile,
BearerConnectionTarget,
} from "@t3tools/client-runtime/connection";
import { EnvironmentId } from "@t3tools/contracts";
import { describe, expect, it } from "@effect/vitest";
import * as Option from "effect/Option";
import { projectWorkspaceEnvironment, projectWorkspaceState } from "./workspaceModel";
import type { EnvironmentPresentation } from "./environments";
const ENVIRONMENT_ID = EnvironmentId.make("environment-1");
function environment(
phase: EnvironmentPresentation["connection"]["phase"],
): EnvironmentPresentation {
const connectionId = `bearer:${ENVIRONMENT_ID}`;
return {
environmentId: ENVIRONMENT_ID,
label: "Julius's MacBook Pro",
displayUrl: "https://environment.example.test",
relayManaged: false,
entry: {
target: new BearerConnectionTarget({
environmentId: ENVIRONMENT_ID,
label: "Julius's MacBook Pro",
connectionId,
}),
profile: Option.some(
new BearerConnectionProfile({
connectionId,
environmentId: ENVIRONMENT_ID,
label: "Julius's MacBook Pro",
httpBaseUrl: "https://environment.example.test",
wsBaseUrl: "wss://environment.example.test",
}),
),
},
connection: {
phase,
error: phase === "error" ? "Connection failed." : null,
traceId: phase === "error" ? "trace-1" : null,
},
serverConfig: null,
};
}
const EMPTY_SHELL_SUMMARY: EnvironmentShellSummary = {
hasSnapshot: false,
hasSynchronizingShell: false,
hasCachedShell: false,
hasLiveShell: false,
firstError: null,
latestSnapshotUpdatedAt: null,
};
const CACHED_SHELL_SUMMARY: EnvironmentShellSummary = {
...EMPTY_SHELL_SUMMARY,
hasSnapshot: true,
hasSynchronizingShell: true,
hasCachedShell: true,
latestSnapshotUpdatedAt: "2026-06-07T00:00:00.000Z",
};
describe("mobile workspace projection", () => {
it("preserves explicit offline state without presenting it as a connection error", () => {
const projected = projectWorkspaceEnvironment(environment("offline"));
expect(projected.connectionState).toBe("offline");
expect(projected.connectionError).toBeNull();
});
it("reports offline before stale connected presentations", () => {
const environments = [projectWorkspaceEnvironment(environment("connected"))];
const state = projectWorkspaceState({
isReady: true,
networkStatus: "offline",
environments,
shellSummary: EMPTY_SHELL_SUMMARY,
});
expect(state.connectionState).toBe("offline");
expect(state.networkStatus).toBe("offline");
expect(state.hasReadyEnvironment).toBe(false);
});
it("projects reconnecting environments dynamically from active phases", () => {
const environments = [
projectWorkspaceEnvironment(environment("reconnecting")),
projectWorkspaceEnvironment({
...environment("connected"),
environmentId: EnvironmentId.make("environment-2"),
}),
];
const state = projectWorkspaceState({
isReady: true,
networkStatus: "online",
environments,
shellSummary: EMPTY_SHELL_SUMMARY,
});
expect(state.connectingEnvironments).toHaveLength(1);
expect(state.connectingEnvironments[0]?.connectionState).toBe("reconnecting");
expect(state.hasConnectingEnvironment).toBe(true);
expect(state.hasReadyEnvironment).toBe(true);
});
it("keeps retained snapshots visible while reconnecting without claiming readiness", () => {
const environments = [projectWorkspaceEnvironment(environment("reconnecting"))];
const state = projectWorkspaceState({
isReady: true,
networkStatus: "online",
environments,
shellSummary: CACHED_SHELL_SUMMARY,
});
expect(state.hasLoadedShellSnapshot).toBe(true);
expect(state.hasPendingShellSnapshot).toBe(true);
expect(state.hasReadyEnvironment).toBe(false);
expect(state.connectionState).toBe("reconnecting");
});
});