authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-05 22:07:29-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-05 22:07:29-07:00
log1200f530bdc8be25ca1c85affa42b6d9c259601c
tree738528b79a38ede7314410aab0973da8370695b3
parent226abe5f916ff828d8be2c19f1148b10feebfe43
signature Signed by PGP key B5690EEEBB952194

refactor(web): keep app utilities private and remove dead helpers (#10227)


22 files changed, 27 insertions(+), 52 deletions(-)

apps/web/src/browser/browserViewportActions.ts+1-1
......@@ -4,7 +4,7 @@ type BrowserViewportHandler = (setting: PreviewViewportSetting) => Promise<void>
44
55export const BROWSER_VIEWPORT_COMMIT_TIMEOUT_MS = 15_000;
66
7export class BrowserViewportCommitTimeoutError extends Error {
7class BrowserViewportCommitTimeoutError extends Error {
88 override readonly name = "BrowserViewportCommitTimeoutError";
99
1010 constructor(readonly tabId: string) {
apps/web/src/browser/webviewCrashRecovery.ts+2-2
......@@ -1,6 +1,6 @@
11export const WEBVIEW_CRASH_RECOVERY_WINDOW_MS = 30_000;
2export const WEBVIEW_CRASH_RECOVERY_MAX_ATTEMPTS = 3;
3export const WEBVIEW_CRASH_RECOVERY_BASE_DELAY_MS = 250;
2const WEBVIEW_CRASH_RECOVERY_MAX_ATTEMPTS = 3;
3const WEBVIEW_CRASH_RECOVERY_BASE_DELAY_MS = 250;
44
55export interface WebviewCrashRecoveryState {
66 readonly attempts: number;
apps/web/src/browserFaviconLogic.ts+1-1
......@@ -9,7 +9,7 @@ export type BrowserFaviconEntry = {
99};
1010
1111export const BROWSER_FAVICON_MAX_ENTRIES = 40;
12export const BROWSER_FAVICON_MAX_KEY_LENGTH = 4_096;
12const BROWSER_FAVICON_MAX_KEY_LENGTH = 4_096;
1313const BROWSER_FAVICON_MAX_FUTURE_SKEW_MS = 5 * 60 * 1_000;
1414export const BROWSER_FAVICON_MAX_ALIASES_PER_ENTRY = 4;
1515const BROWSER_FAVICON_MAX_ALIAS_LENGTH = 255;
apps/web/src/browserHistoryStore.ts+2-2
......@@ -14,7 +14,7 @@ export type BrowserHistoryEntry = { url: string; lastVisitedAt: number; title?:
1414
1515export const BROWSER_HISTORY_MAX_ENTRIES_PER_PROJECT = 50;
1616export const BROWSER_HISTORY_MAX_PROJECTS = 20;
17export const BROWSER_HISTORY_MAX_URL_LENGTH = 2048;
17const BROWSER_HISTORY_MAX_URL_LENGTH = 2048;
1818export const BROWSER_HISTORY_MAX_TITLE_LENGTH = 512;
1919const MAX_VALID_DATE_MS = 8_640_000_000_000_000;
2020
......@@ -35,7 +35,7 @@ export function normalizeHistoryUrl(raw: string): string | null {
3535 return parsed.href.length > BROWSER_HISTORY_MAX_URL_LENGTH ? null : parsed.href;
3636}
3737
38export function titleLookupKey(normalized: string, environmentHostname?: string | null): string {
38function titleLookupKey(normalized: string, environmentHostname?: string | null): string {
3939 const parsed = new URL(visitLookupKey(normalized, environmentHostname));
4040 if (parsed.pathname !== "/" && parsed.pathname.endsWith("/"))
4141 parsed.pathname = parsed.pathname.slice(0, -1);
apps/web/src/clientPersistenceStorage.ts+1-1
......@@ -2,7 +2,7 @@ import { ClientSettingsSchema, type ClientSettings } from "@t3tools/contracts";
22
33import { getLocalStorageItem, setLocalStorageItem } from "./hooks/useLocalStorage";
44
5export const CLIENT_SETTINGS_STORAGE_KEY = "t3code:client-settings:v1";
5const CLIENT_SETTINGS_STORAGE_KEY = "t3code:client-settings:v1";
66
77function hasWindow(): boolean {
88 return typeof window !== "undefined";
apps/web/src/composerDraftStore.ts+2-4
......@@ -769,7 +769,7 @@ const EMPTY_THREAD_DRAFT = Object.freeze<ComposerThreadDraftState>({
769769 * slice — adding a new field to the interface (e.g. `elementContexts`) only
770770 * has to be reflected here, not in every stub.
771771 */
772export function createEmptyThreadDraft(): ComposerThreadDraftState {
772function createEmptyThreadDraft(): ComposerThreadDraftState {
773773 return {
774774 prompt: "",
775775 images: [],
......@@ -4050,9 +4050,7 @@ export function useThreadHasUnsentDraft(threadRef: ScopedThreadRef): boolean {
40504050 );
40514051}
40524052
4053export function useComposerDraftModelState(
4054 threadRef: ComposerThreadTarget,
4055): ComposerDraftModelState {
4053function useComposerDraftModelState(threadRef: ComposerThreadTarget): ComposerDraftModelState {
40564054 return useComposerDraftStore(
40574055 useShallow((state) => {
40584056 const draft = getComposerDraftState(state, threadRef);
apps/web/src/desktopAppActivation.ts+1-1
......@@ -44,7 +44,7 @@ function failure(
4444 return { version: 1, requestId, ok: false, code, message };
4545}
4646
47export function desktopPlatformToEnvironmentOs(
47function desktopPlatformToEnvironmentOs(
4848 platform: DesktopAppActivationRequest["platform"],
4949): ExecutionEnvironmentPlatformOs {
5050 return platform === "win32" ? "windows" : platform;
apps/web/src/keybindings.ts-8
......@@ -377,14 +377,6 @@ export function isDiffToggleShortcut(
377377 return matchesCommandShortcut(event, keybindings, "diff.toggle", options);
378378}
379379
380export function isPreviewRefreshShortcut(
381 event: ShortcutEventLike,
382 keybindings: ResolvedKeybindingsConfig,
383 options?: ShortcutMatchOptions,
384): boolean {
385 return matchesCommandShortcut(event, keybindings, "preview.refresh", options);
386}
387
388380export function isOpenFavoriteEditorShortcut(
389381 event: ShortcutEventLike,
390382 keybindings: ResolvedKeybindingsConfig,
apps/web/src/lib/attachmentUploadQueue.ts+1-1
......@@ -445,7 +445,7 @@ export function startAttachmentUpload(input: {
445445 * persisted draft upload survives cancellation (an environment switch cancels
446446 * the old job, and the draft still references that server copy).
447447 */
448export function cancelAttachmentUpload(imageId: string): void {
448function cancelAttachmentUpload(imageId: string): void {
449449 const job = jobsByImageId.get(imageId);
450450 if (!job) {
451451 return;
apps/web/src/lib/diffRendering.ts+2-2
......@@ -1,7 +1,7 @@
11import { parsePatchFiles } from "@pierre/diffs/utils/parsePatchFiles";
22import type { FileDiffMetadata } from "@pierre/diffs/types";
33
4export const DIFF_THEME_NAMES = {
4const DIFF_THEME_NAMES = {
55 light: "pierre-light",
66 dark: "pierre-dark",
77} as const;
......@@ -81,7 +81,7 @@ interface RenderablePatchOptions {
8181 compactPartialHunkOffsets?: boolean;
8282}
8383
84export function compactPartialHunkOffsets(file: FileDiffMetadata): FileDiffMetadata {
84function compactPartialHunkOffsets(file: FileDiffMetadata): FileDiffMetadata {
8585 if (!file.isPartial) return file;
8686
8787 let splitLineStart = 0;
apps/web/src/lib/previewAnnotation.ts+1-1
......@@ -111,7 +111,7 @@ async function previewAnnotationScreenshotFile(
111111}
112112
113113/** Upper bound on turning a picked element's crop into a composer attachment. */
114export const PREVIEW_ANNOTATION_CAPTURE_TIMEOUT_MS = 5_000;
114const PREVIEW_ANNOTATION_CAPTURE_TIMEOUT_MS = 5_000;
115115
116116export type PreviewAnnotationCapture =
117117 /** The crop is ready to attach. */
apps/web/src/lib/storage.ts+1-1
......@@ -26,7 +26,7 @@ export function createMemoryStorage(): StateStorage {
2626 };
2727}
2828
29export function isStateStorage(
29function isStateStorage(
3030 storage: Partial<StateStorage> | null | undefined,
3131): storage is StateStorage {
3232 return (
apps/web/src/lib/terminalContext.ts+2-5
......@@ -65,7 +65,7 @@ export function filterTerminalContextsWithText<T extends { text: string }>(
6565 return contexts.filter((context) => hasTerminalContextText(context));
6666}
6767
68export function normalizeTerminalContextSelection(
68function normalizeTerminalContextSelection(
6969 selection: TerminalContextSelection,
7070): TerminalContextSelection | null {
7171 const text = normalizeTerminalContextText(selection.text);
......@@ -85,10 +85,7 @@ export function normalizeTerminalContextSelection(
8585 };
8686}
8787
88export function formatTerminalContextRange(selection: {
89 lineStart: number;
90 lineEnd: number;
91}): string {
88function formatTerminalContextRange(selection: { lineStart: number; lineEnd: number }): string {
9289 return selection.lineStart === selection.lineEnd
9390 ? `line ${selection.lineStart}`
9491 : `lines ${selection.lineStart}-${selection.lineEnd}`;
apps/web/src/lib/windowControlsOverlay.ts+1-1
......@@ -43,7 +43,7 @@ export function syncDocumentWindowControlsOverlayClass(): () => void {
4343 };
4444}
4545
46export function getElectronPlatformClassNames(
46function getElectronPlatformClassNames(
4747 platform: string,
4848):
4949 | readonly [typeof ELECTRON_CLASS_NAME]
apps/web/src/logicalProject.ts-1
......@@ -4,7 +4,6 @@ export {
44 deriveLogicalProjectKeyFromSettings,
55 derivePhysicalProjectKey,
66 derivePhysicalProjectKeyFromPath,
7 deriveProjectGroupLabel,
87 deriveProjectGroupingOverrideKey,
98 getProjectOrderKey,
109 resolveProjectGroupingMode,
apps/web/src/portDiscoveryState.ts+1-1
......@@ -43,7 +43,7 @@ export function boundConfiguredLocalServerUrls(
4343 return bounded;
4444}
4545
46export function useDiscoveredPorts(
46function useDiscoveredPorts(
4747 environmentId: EnvironmentId | null,
4848 configuredUrls?: ReadonlyArray<string>,
4949): ReadonlyArray<DiscoveredLocalServer> {
apps/web/src/projectIconOptions.ts+1-1
......@@ -1,7 +1,7 @@
11import { iconNames, type IconName } from "lucide-react/dynamic";
22export { PROJECT_ICON_COLORS, projectIconColorClassName } from "./projectIconColors";
33
4export const POPULAR_PROJECT_ICONS = [
4const POPULAR_PROJECT_ICONS = [
55 "folder-code",
66 "code-2",
77 "terminal",
apps/web/src/reviewCommentContext.ts-6
......@@ -180,12 +180,6 @@ export function parseReviewCommentMessageSegments(
180180 return segments;
181181}
182182
183export function hasReviewCommentMessageSegments(value: string): boolean {
184 return parseReviewCommentMessageSegments(value).some(
185 (segment) => segment.kind === "review-comment",
186 );
187}
188
189183export function formatReviewCommentFence(language: string, contents: string): string {
190184 const longestBacktickRun = Math.max(
191185 0,
apps/web/src/rightPanelStore.ts+2-2
......@@ -14,7 +14,7 @@ import { createJSONStorage, persist } from "zustand/middleware";
1414
1515import { resolveStorage } from "./lib/storage";
1616
17export const RIGHT_PANEL_KINDS = [
17const RIGHT_PANEL_KINDS = [
1818 "diff",
1919 "files",
2020 "file",
......@@ -193,7 +193,7 @@ export function pullRequestSurfaceId(target: {
193193 return `pull-request:${scope}${encodeURIComponent(target.projectId)}:${encodeURIComponent(target.repository)}:${target.number}`;
194194}
195195
196export function pullRequestSurface(target: {
196function pullRequestSurface(target: {
197197 environmentId?: string;
198198 projectId: string;
199199 repository: string;
apps/web/src/test/reactHookHarness.ts+1-1
......@@ -34,7 +34,7 @@ import type { Dispatch, SetStateAction } from "react";
3434 * Call `beginRender()` before each component invocation and `reset()` in
3535 * `beforeEach` to drop persisted state between tests.
3636 */
37export function createReactHookHarness() {
37function createReactHookHarness() {
3838 let cursor = 0;
3939 let slots: unknown[] = [];
4040 const nextIndex = () => cursor++;
apps/web/src/themePalette.ts+3-8
......@@ -22,15 +22,10 @@ export { EMBER_THEME, GROVE_THEME, IRIS_THEME, OCEAN_THEME, T3_CHAT_THEME, THEME
2222export type { ThemeAppearance, ThemeColorRole, ThemeColors, ThemeDefinition, ThemeVariants };
2323
2424export const T3_CHAT_THEME_ID = "t3-chat" as const;
25export const T3_CHAT_THEME_LABEL = "T3 Chat";
26export const GROVE_THEME_ID = "grove" as const;
27export const GROVE_THEME_LABEL = "Grove";
25const GROVE_THEME_ID = "grove" as const;
2826export const OCEAN_THEME_ID = "ocean" as const;
29export const OCEAN_THEME_LABEL = "Ocean";
30export const EMBER_THEME_ID = "ember" as const;
31export const EMBER_THEME_LABEL = "Ember";
32export const IRIS_THEME_ID = "iris" as const;
33export const IRIS_THEME_LABEL = "Iris";
27const EMBER_THEME_ID = "ember" as const;
28const IRIS_THEME_ID = "iris" as const;
3429export const THEME_FILE_VERSION = 1 as const;
3530export const CUSTOM_THEMES_STORAGE_KEY = "t3code:themes:v1";
3631export const THEME_FOLLOW_SYSTEM_STORAGE_KEY = "t3code:theme-follow-system";
apps/web/src/versionSkew.ts+1-1
......@@ -12,7 +12,7 @@ export interface VersionMismatch {
1212 readonly hint: string;
1313}
1414
15export const VERSION_MISMATCH_DISMISSALS_STORAGE_KEY = "t3code:version-mismatch-dismissals:v1";
15const VERSION_MISMATCH_DISMISSALS_STORAGE_KEY = "t3code:version-mismatch-dismissals:v1";
1616
1717// Runtime failures retain their identity until the next attempt. Dismiss only
1818// that attempt, across chat remounts, without clearing the error in Settings.