refactor(ts): Add ES module exports to core utilities

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
This commit is contained in:
2026-03-08 01:14:20 -05:00
parent e20857d760
commit 149d14f5eb
7 changed files with 44 additions and 80 deletions
+6 -6
View File
@@ -87,12 +87,12 @@ function handleError(error: unknown, context: string): void {
} }
} }
(window as any).api = { export {
get: apiGet, apiGet,
post: apiPost, apiPost,
put: apiPut, apiPut,
delete: apiDelete, apiDelete,
patch: apiPatch, apiPatch,
handleResponse, handleResponse,
handleVoidResponse, handleVoidResponse,
handleError, handleError,
+9 -26
View File
@@ -102,36 +102,19 @@ function hasClass(element: HTMLElement | null, className: string): boolean {
return element ? element.classList.contains(className) : false; 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 { export {
addClass,
createElement,
escapeHtml, escapeHtml,
getElementById,
hasClass,
hideElement,
querySelector, querySelector,
querySelectorAll, querySelectorAll,
getElementById,
createElement,
showElement,
hideElement,
toggleElement,
setTextContent,
setInnerHTML,
addClass,
removeClass, removeClass,
setInnerHTML,
setTextContent,
showElement,
toggleClass, toggleClass,
hasClass, toggleElement,
}; };
+9 -9
View File
@@ -118,18 +118,18 @@ function stopPropagation(event: Event): void {
event.stopPropagation(); event.stopPropagation();
} }
(window as any).events = { export {
onDelegatedClick,
onDelegatedSubmit,
onDelegatedChange,
onDelegatedKeydown,
getDataAttribute, getDataAttribute,
setDataAttribute,
onClick,
onSubmit,
onChange, onChange,
onKeydown, onClick,
onDelegatedChange,
onDelegatedClick,
onDelegatedKeydown,
onDelegatedSubmit,
onInput, onInput,
onKeydown,
onSubmit,
preventDefault, preventDefault,
setDataAttribute,
stopPropagation, stopPropagation,
}; };
+12 -28
View File
@@ -50,34 +50,18 @@ function clearAll(): void {
localStorage.clear(); localStorage.clear();
} }
(window as any).storage = {
getToken,
setToken,
removeToken,
getRefreshToken,
setRefreshToken,
removeRefreshToken,
getTheme,
setTheme,
getSelectedLibrary,
setSelectedLibrary,
getSelectedBook,
setSelectedBook,
clearAll,
};
export { export {
getToken,
setToken,
removeToken,
getRefreshToken,
setRefreshToken,
removeRefreshToken,
getTheme,
setTheme,
getSelectedLibrary,
setSelectedLibrary,
getSelectedBook,
setSelectedBook,
clearAll, clearAll,
getRefreshToken,
getSelectedBook,
getSelectedLibrary,
getTheme,
getToken,
removeRefreshToken,
removeToken,
setRefreshToken,
setSelectedBook,
setSelectedLibrary,
setTheme,
setToken
}; };
+2 -5
View File
@@ -137,8 +137,5 @@ if (typeof document !== "undefined") {
} }
} }
// Make changeTheme available globally for HTML onchange attribute export { applyTheme, changeTheme, initializeTheme, loadTheme, loadUserTheme };
(window as any).changeTheme = changeTheme; export type { ThemeType };
// Export applyTheme to window for use by header.ts
(window as any).applyTheme = applyTheme;
+5 -2
View File
@@ -226,11 +226,14 @@ if (typeof document !== "undefined") {
} }
// Export toast API for manual use // Export toast API for manual use
(window as any).showToast = { Alpine.global("showToast", {
error: (message: string, duration?: number) => error: (message: string, duration?: number) =>
showToast(message, "error", duration), showToast(message, "error", duration),
success: (message: string, duration?: number) => success: (message: string, duration?: number) =>
showToast(message, "success", duration), showToast(message, "success", duration),
info: (message: string, duration?: number) => info: (message: string, duration?: number) =>
showToast(message, "info", duration), showToast(message, "info", duration),
}; });
export { showToast };
export type { ToastType };
+1 -4
View File
@@ -81,10 +81,7 @@ const updateWoodPanelingIndicators = (): void => {
}); });
}; };
// Make functions available globally export { changeWoodPaneling, loadWoodPaneling, updateWoodPanelingIndicators };
(window as any).changeWoodPaneling = changeWoodPaneling;
(window as any).loadWoodPaneling = loadWoodPaneling;
(window as any).updateWoodPanelingIndicators = updateWoodPanelingIndicators;
// Auto-initialize when DOM is ready // Auto-initialize when DOM is ready
if (typeof document !== "undefined") { if (typeof document !== "undefined") {