From 478df24645e8447777f1e02605978049c89d2114 Mon Sep 17 00:00:00 2001 From: PathGao Date: Mon, 3 Aug 2026 19:51:09 +0800 Subject: [PATCH] refactor(lib): stop exporting 23 symbols that never leave their module Fixes no bug. Every one of these compiles, runs, and behaves exactly as before -- the only change is that a reader opening one of these modules now sees an interface that matches what the module actually promises. 23 declarations lose the `export` keyword. None are deleted: all 23 are called or referenced inside their own file, so the declaration stays and only its visibility narrows. The line drawn here: a type keeps `export` when it is directly the parameter type or the return type of an exported function, or the declared type of an exported constant -- a caller who builds the argument in a separate statement, or holds the result in a typed field, has to be able to name it. It loses `export` when it is only reachable inside such a type (a field of an options bag), or appears only in value positions internal to the module. A function loses `export` when every call to it is in its own file. 26 of the 49 candidates are kept on that basis. No renames, no reordering, no adjacent cleanup. `npm test` 565/565 unchanged, `npm run check` 637 files / 0 errors, `npm run build` clean. No Rust touched. Co-Authored-By: Claude Opus 5 --- src/lib/stores/settings.svelte.ts | 10 +++++----- src/lib/stores/update.svelte.ts | 4 ++-- src/lib/utils/editorToolbar.ts | 4 ++-- src/lib/utils/exportFonts.ts | 8 ++++---- src/lib/utils/frontMatter.ts | 4 ++-- src/lib/utils/markdownLinks.ts | 2 +- src/lib/utils/mermaidPrint.ts | 2 +- src/lib/utils/openExportedFile.ts | 2 +- src/lib/utils/pasteContext.ts | 6 +++--- src/lib/utils/tabFileActions.ts | 2 +- src/lib/utils/titlebarToolbar.ts | 2 +- 11 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/lib/stores/settings.svelte.ts b/src/lib/stores/settings.svelte.ts index 99399d52..73587822 100644 --- a/src/lib/stores/settings.svelte.ts +++ b/src/lib/stores/settings.svelte.ts @@ -52,7 +52,7 @@ export type LanguageCode = | 'id' // Indonesian | 'tr'; // Turkish -export const SUPPORTED_LANGUAGES: { code: LanguageCode; name: string; nativeName: string }[] = [ +const SUPPORTED_LANGUAGES: { code: LanguageCode; name: string; nativeName: string }[] = [ { code: 'cs', name: 'Czech', nativeName: 'Čeština' }, { code: 'da', name: 'Danish', nativeName: 'Dansk' }, { code: 'nl', name: 'Dutch', nativeName: 'Nederlands' }, @@ -81,9 +81,9 @@ export const SUPPORTED_LANGUAGES: { code: LanguageCode; name: string; nativeName { code: 'zh-TW', name: 'Chinese (Traditional)', nativeName: '繁體中文' }, ]; -export const SUPPORTED_LANGUAGE_CODES: readonly LanguageCode[] = SUPPORTED_LANGUAGES.map((entry) => entry.code); +const SUPPORTED_LANGUAGE_CODES: readonly LanguageCode[] = SUPPORTED_LANGUAGES.map((entry) => entry.code); -export function isSupportedLanguage(value: unknown): value is LanguageCode { +function isSupportedLanguage(value: unknown): value is LanguageCode { return typeof value === 'string' && (SUPPORTED_LANGUAGE_CODES as readonly string[]).includes(value); } @@ -305,7 +305,7 @@ export function writeStoredSetting(key: string, value: string | null): boolean { } /** Applies everything currently in localStorage onto `target`. */ -export function loadPersistedSettings(target: T, entries: readonly PersistedSetting[]): void { +function loadPersistedSettings(target: T, entries: readonly PersistedSetting[]): void { if (typeof localStorage === 'undefined') return; for (const entry of entries) { entry.load(target, localStorage.getItem(entry.key)); @@ -326,7 +326,7 @@ export function loadPersistedSettings(target: T, entries: readonly PersistedS * *other* same-origin document, so each window folds its siblings' changes into * its own state instead of drifting until the next restart. */ -export function installPersistedSettings(target: T, entries: readonly PersistedSetting[]): void { +function installPersistedSettings(target: T, entries: readonly PersistedSetting[]): void { for (const entry of entries) { $effect(() => { writeStoredSetting(entry.key, entry.read(target)); diff --git a/src/lib/stores/update.svelte.ts b/src/lib/stores/update.svelte.ts index d281ce18..d2119391 100644 --- a/src/lib/stores/update.svelte.ts +++ b/src/lib/stores/update.svelte.ts @@ -2,7 +2,7 @@ import { check, type Update } from '@tauri-apps/plugin-updater'; import { relaunch } from '@tauri-apps/plugin-process'; import { getVersion } from '@tauri-apps/api/app'; -export type UpdatePhase = +type UpdatePhase = | 'idle' | 'checking' | 'up-to-date' @@ -10,7 +10,7 @@ export type UpdatePhase = | 'downloading' | 'error'; -export type ErrorSource = 'check' | 'download' | 'install'; +type ErrorSource = 'check' | 'download' | 'install'; // Match only messages that genuinely indicate the updater plugin lacks an // endpoint / pubkey configuration. We deliberately do NOT match the bare diff --git a/src/lib/utils/editorToolbar.ts b/src/lib/utils/editorToolbar.ts index 2415d0e1..69c57ae0 100644 --- a/src/lib/utils/editorToolbar.ts +++ b/src/lib/utils/editorToolbar.ts @@ -1,4 +1,4 @@ -export type EditorToolbarGroup = 'inline' | 'block' | 'list' | 'insert'; +type EditorToolbarGroup = 'inline' | 'block' | 'list' | 'insert'; export type EditorToolbarTool = { id: string; @@ -13,7 +13,7 @@ export type EditorToolbarMove = { toIndex: number; }; -export const EDITOR_TOOLBAR_TOOLS: EditorToolbarTool[] = [ +const EDITOR_TOOLBAR_TOOLS: EditorToolbarTool[] = [ { id: 'fmt-bold', label: 'B', name: 'Bold', shortcut: (modifier) => `${modifier}+B`, group: 'inline' }, { id: 'fmt-italic', label: 'I', name: 'Italic', shortcut: (modifier) => `${modifier}+I`, group: 'inline' }, { id: 'fmt-underline', label: 'U', name: 'Underline', shortcut: (modifier) => `${modifier}+U`, group: 'inline' }, diff --git a/src/lib/utils/exportFonts.ts b/src/lib/utils/exportFonts.ts index 804fb643..5299bb41 100644 --- a/src/lib/utils/exportFonts.ts +++ b/src/lib/utils/exportFonts.ts @@ -53,7 +53,7 @@ function selectorClasses(selector: string): string[] { .filter((name) => name !== 'katex'); } -export interface KatexFamilyRule { +interface KatexFamilyRule { /** Class tokens that must all be present for the rule to apply. */ classes: string[]; families: string[]; @@ -64,7 +64,7 @@ export interface KatexFamilyRule { * family, read out of the stylesheet rather than hard-coded, so a KaTeX upgrade * that renames a class or adds a family is picked up without edits here. */ -export function parseKatexFamilyRules(css: string): KatexFamilyRule[] { +function parseKatexFamilyRules(css: string): KatexFamilyRule[] { const rules: KatexFamilyRule[] = []; for (const match of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) { const selector = match[1].trim(); @@ -81,7 +81,7 @@ export function parseKatexFamilyRules(css: string): KatexFamilyRule[] { } /** Every class token used anywhere under `root`, including `root` itself. */ -export function collectClassNames(root: Element): Set { +function collectClassNames(root: Element): Set { const names = new Set(); // Walked rather than selected: `querySelectorAll('*')` is the one call that // would tie this to a full selector engine, and the walk is no slower. @@ -221,7 +221,7 @@ export function katexFontUrlsToEmbed(css: string, usedFamilies: Set): st } /** `btoa` in chunks: a 30 KB font blows the argument limit of `apply`. */ -export function bytesToBase64(bytes: Uint8Array): string { +function bytesToBase64(bytes: Uint8Array): string { let binary = ''; const chunk = 0x8000; for (let index = 0; index < bytes.length; index += chunk) { diff --git a/src/lib/utils/frontMatter.ts b/src/lib/utils/frontMatter.ts index 3f256d01..4eff8b1a 100644 --- a/src/lib/utils/frontMatter.ts +++ b/src/lib/utils/frontMatter.ts @@ -1,6 +1,6 @@ import { parseDocument } from 'yaml'; -export type FrontMatterValueKind = 'string' | 'number' | 'boolean' | 'list' | 'object' | 'null'; +type FrontMatterValueKind = 'string' | 'number' | 'boolean' | 'list' | 'object' | 'null'; export type FrontMatterField = { key: string; @@ -198,7 +198,7 @@ export function updateFrontMatterField(content: string, key: string, value: unkn return `---${parsed.lineEnding}${serialized}${parsed.lineEnding}---${parsed.lineEnding}${parsed.lineEnding}${parsed.body}`; } -export function parseFrontMatterTagInput(value: string): string[] { +function parseFrontMatterTagInput(value: string): string[] { return value .split(',') .map((item) => item.trim()) diff --git a/src/lib/utils/markdownLinks.ts b/src/lib/utils/markdownLinks.ts index 53772a32..11a31294 100644 --- a/src/lib/utils/markdownLinks.ts +++ b/src/lib/utils/markdownLinks.ts @@ -15,7 +15,7 @@ export function hasMarkdownLinkExtension(path: string): boolean { return /\.(md|markdown|mdown|mkd|txt)$/i.test(path); } -export function isAbsoluteMarkdownPath(path: string): boolean { +function isAbsoluteMarkdownPath(path: string): boolean { return path.startsWith('/') || path.startsWith('\\') || /^[a-z]:/i.test(path); } diff --git a/src/lib/utils/mermaidPrint.ts b/src/lib/utils/mermaidPrint.ts index 70879482..2f7ca8ce 100644 --- a/src/lib/utils/mermaidPrint.ts +++ b/src/lib/utils/mermaidPrint.ts @@ -22,7 +22,7 @@ const SOURCE_ATTR = 'data-mermaid-source'; export const MERMAID_PRINT_THEME = 'neutral'; -export interface MermaidRenderer { +interface MermaidRenderer { initialize(config: { startOnLoad: boolean; theme: string }): void; render(id: string, source: string): Promise<{ svg: string }>; } diff --git a/src/lib/utils/openExportedFile.ts b/src/lib/utils/openExportedFile.ts index 1799ee3b..c494bddb 100644 --- a/src/lib/utils/openExportedFile.ts +++ b/src/lib/utils/openExportedFile.ts @@ -1,7 +1,7 @@ export type ExportedFileFormat = 'HTML' | 'PDF'; export type OpenExportedFileResult = 'opened' | 'declined' | 'failed'; -export type OpenExportedFileLabels = { +type OpenExportedFileLabels = { title?: string; message?: string; }; diff --git a/src/lib/utils/pasteContext.ts b/src/lib/utils/pasteContext.ts index ae491fbb..aa67de07 100644 --- a/src/lib/utils/pasteContext.ts +++ b/src/lib/utils/pasteContext.ts @@ -26,7 +26,7 @@ export const MARKDOWN_LANGUAGE_ID = 'markdown'; * A plain letter is used on purpose: it carries no markdown meaning, so it * cannot open or close a construct that would change the caret's own token. */ -export const PASTE_PROBE_CHARACTER = 'x'; +const PASTE_PROBE_CHARACTER = 'x'; export type PasteContextToken = { readonly offset: number; @@ -34,7 +34,7 @@ export type PasteContextToken = { readonly language: string; }; -export type PasteContextTokenizer = (text: string) => readonly (readonly PasteContextToken[])[]; +type PasteContextTokenizer = (text: string) => readonly (readonly PasteContextToken[])[]; /** * Token types Monaco's markdown grammar emits for code. The `.md` suffix is @@ -79,7 +79,7 @@ export function findTokenAtOffset( return found; } -export function isCodeAtOffset(tokens: readonly PasteContextToken[], offset: number): boolean { +function isCodeAtOffset(tokens: readonly PasteContextToken[], offset: number): boolean { const token = findTokenAtOffset(tokens, offset); return token ? isCodeToken(token) : false; } diff --git a/src/lib/utils/tabFileActions.ts b/src/lib/utils/tabFileActions.ts index d0e070e7..b6e7eea7 100644 --- a/src/lib/utils/tabFileActions.ts +++ b/src/lib/utils/tabFileActions.ts @@ -1,6 +1,6 @@ import { isHomePath } from './homeTab.js'; -export type TabFileActionId = 'copy-path' | 'open-location'; +type TabFileActionId = 'copy-path' | 'open-location'; export type TabFileAction = { id: TabFileActionId; diff --git a/src/lib/utils/titlebarToolbar.ts b/src/lib/utils/titlebarToolbar.ts index 3c60d5f9..14e7a411 100644 --- a/src/lib/utils/titlebarToolbar.ts +++ b/src/lib/utils/titlebarToolbar.ts @@ -20,7 +20,7 @@ export type ConfiguredTitlebarToolbarIds = { menuIds: string[]; }; -export const TITLEBAR_TOOLBAR_ACTIONS: TitlebarToolbarAction[] = [ +const TITLEBAR_TOOLBAR_ACTIONS: TitlebarToolbarAction[] = [ { id: 'back', labelKey: 'menu.back', fallbackName: 'Back', sample: '<', defaultPlacement: 'bar' }, { id: 'forward', labelKey: 'menu.forward', fallbackName: 'Forward', sample: '>', defaultPlacement: 'bar' }, { id: 'reload', labelKey: 'tooltip.reloadFromDisk', fallbackName: 'Reload from Disk', sample: 'R', defaultPlacement: 'bar' },