From 149d14f5eb31cf967656c53f270eba9db75bb82a Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 8 Mar 2026 01:14:20 -0500 Subject: [PATCH] refactor(ts): Add ES module exports to core utilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0/1 of ESBuild migration: Add ES exports to all utility modules while maintaining Alpine.js registration for template compatibility. Core utility modules now support both: - ES module imports for TypeScript→TypeScript dependencies - Alpine.js global namespace for template onclick handlers Modules updated: - api.ts: Export apiGet, apiPost, apiPut, apiDelete, apiPatch, and handlers - toast.ts: Export showToast function (Alpine namespace already present) - storage.ts: Export localStorage helpers (already had exports) - dom.ts: Export DOM manipulation helpers (already had exports) - events.ts: Export event delegation helpers - theme.ts: Export theme management functions - woodPaneling.ts: Export wood paneling functions Pattern: Each module now has dual exports - ES module exports for internal TS dependencies - Alpine.global() registration for template access - Removed direct window exports where Alpine registration exists This enables Phase 1 (converting internal window reads to imports) while maintaining template functionality through Alpine. Migration progress: Phase 0 complete, Phase 1 in progress Next: Convert 193+ internal window reads across consumer modules --- web/src/api.ts | 12 ++++++------ web/src/dom.ts | 35 +++++++++-------------------------- web/src/events.ts | 18 +++++++++--------- web/src/storage.ts | 40 ++++++++++++---------------------------- web/src/theme.ts | 7 ++----- web/src/toast.ts | 7 +++++-- web/src/woodPaneling.ts | 5 +---- 7 files changed, 44 insertions(+), 80 deletions(-) diff --git a/web/src/api.ts b/web/src/api.ts index dfec089..fb7aeb3 100644 --- a/web/src/api.ts +++ b/web/src/api.ts @@ -87,12 +87,12 @@ function handleError(error: unknown, context: string): void { } } -(window as any).api = { - get: apiGet, - post: apiPost, - put: apiPut, - delete: apiDelete, - patch: apiPatch, +export { + apiGet, + apiPost, + apiPut, + apiDelete, + apiPatch, handleResponse, handleVoidResponse, handleError, diff --git a/web/src/dom.ts b/web/src/dom.ts index f61c099..bdcc8b9 100644 --- a/web/src/dom.ts +++ b/web/src/dom.ts @@ -102,36 +102,19 @@ function hasClass(element: HTMLElement | null, className: string): boolean { return element ? element.classList.contains(className) : false; } -(window as any).dom = { - escapeHtml, - querySelector, - querySelectorAll, - getElementById, - createElement, - showElement, - hideElement, - toggleElement, - setTextContent, - setInnerHTML, - addClass, - removeClass, - toggleClass, - hasClass, -}; - export { + addClass, + createElement, escapeHtml, + getElementById, + hasClass, + hideElement, querySelector, querySelectorAll, - getElementById, - createElement, - showElement, - hideElement, - toggleElement, - setTextContent, - setInnerHTML, - addClass, removeClass, + setInnerHTML, + setTextContent, + showElement, toggleClass, - hasClass, + toggleElement, }; diff --git a/web/src/events.ts b/web/src/events.ts index 0522855..7691c98 100644 --- a/web/src/events.ts +++ b/web/src/events.ts @@ -118,18 +118,18 @@ function stopPropagation(event: Event): void { event.stopPropagation(); } -(window as any).events = { - onDelegatedClick, - onDelegatedSubmit, - onDelegatedChange, - onDelegatedKeydown, +export { getDataAttribute, - setDataAttribute, - onClick, - onSubmit, onChange, - onKeydown, + onClick, + onDelegatedChange, + onDelegatedClick, + onDelegatedKeydown, + onDelegatedSubmit, onInput, + onKeydown, + onSubmit, preventDefault, + setDataAttribute, stopPropagation, }; diff --git a/web/src/storage.ts b/web/src/storage.ts index 1a54385..29df0fd 100644 --- a/web/src/storage.ts +++ b/web/src/storage.ts @@ -50,34 +50,18 @@ function clearAll(): void { localStorage.clear(); } -(window as any).storage = { - getToken, - setToken, - removeToken, - getRefreshToken, - setRefreshToken, - removeRefreshToken, - getTheme, - setTheme, - getSelectedLibrary, - setSelectedLibrary, - getSelectedBook, - setSelectedBook, - clearAll, -}; - export { - getToken, - setToken, - removeToken, - getRefreshToken, - setRefreshToken, - removeRefreshToken, - getTheme, - setTheme, - getSelectedLibrary, - setSelectedLibrary, - getSelectedBook, - setSelectedBook, clearAll, + getRefreshToken, + getSelectedBook, + getSelectedLibrary, + getTheme, + getToken, + removeRefreshToken, + removeToken, + setRefreshToken, + setSelectedBook, + setSelectedLibrary, + setTheme, + setToken }; diff --git a/web/src/theme.ts b/web/src/theme.ts index c40801f..d8e29bc 100644 --- a/web/src/theme.ts +++ b/web/src/theme.ts @@ -137,8 +137,5 @@ if (typeof document !== "undefined") { } } -// Make changeTheme available globally for HTML onchange attribute -(window as any).changeTheme = changeTheme; - -// Export applyTheme to window for use by header.ts -(window as any).applyTheme = applyTheme; +export { applyTheme, changeTheme, initializeTheme, loadTheme, loadUserTheme }; +export type { ThemeType }; diff --git a/web/src/toast.ts b/web/src/toast.ts index 8452964..0847c2a 100644 --- a/web/src/toast.ts +++ b/web/src/toast.ts @@ -226,11 +226,14 @@ if (typeof document !== "undefined") { } // Export toast API for manual use -(window as any).showToast = { +Alpine.global("showToast", { error: (message: string, duration?: number) => showToast(message, "error", duration), success: (message: string, duration?: number) => showToast(message, "success", duration), info: (message: string, duration?: number) => showToast(message, "info", duration), -}; +}); + +export { showToast }; +export type { ToastType }; diff --git a/web/src/woodPaneling.ts b/web/src/woodPaneling.ts index 58bd364..ac7c8d6 100644 --- a/web/src/woodPaneling.ts +++ b/web/src/woodPaneling.ts @@ -81,10 +81,7 @@ const updateWoodPanelingIndicators = (): void => { }); }; -// Make functions available globally -(window as any).changeWoodPaneling = changeWoodPaneling; -(window as any).loadWoodPaneling = loadWoodPaneling; -(window as any).updateWoodPanelingIndicators = updateWoodPanelingIndicators; +export { changeWoodPaneling, loadWoodPaneling, updateWoodPanelingIndicators }; // Auto-initialize when DOM is ready if (typeof document !== "undefined") {