Skip to main content

max / makenotwork

3.8 KB · 85 lines History Blame Raw
1 // MNW frontend core, entry point.
2 //
3 // Loaded once, globally, as a `<script type="module">` in place of the retired
4 // `static/mnw.js`. It installs every delegated listener the old god-file did
5 // (toasts, HTMX glue, the data-action + hx-callback dispatchers, copy-link,
6 // keyboard, tabs, restart banner) and bridges the shared primitives onto
7 // `window` so the not-yet-migrated `static/*.js` files keep resolving them.
8 //
9 // As feature files migrate into frontend/src, drop their entries from the
10 // bridge and register their handlers via `dispatch.register()` instead of a
11 // global; the `frontend_globals` seal ratchets the legacy count down.
12
13 import { escapeHtml, escapeAttr } from './dom.ts';
14 import { csrfHeaders, apiError } from './net.ts';
15 import { showToast, initToasts } from './toast.ts';
16 import { safeGet, safeSet } from './storage.ts';
17 import { copyWithFeedback, initCopyLink } from './clipboard.ts';
18 import { resolveHtmxLoadingButton, withLoadingState } from './loading.ts';
19 import { initActionDispatcher, initHxCallbackDispatcher } from './dispatch.ts';
20 import { setActiveTab, initTabs } from './tabs.ts';
21 import { toggleShortcutsHelp, initKeyboard } from './keyboard.ts';
22 import { initRestartBanner } from './restart-banner.ts';
23 import { initHtmxGlue } from './htmx-glue.ts';
24
25 // Common, lightweight islands are registered globally here (side-effect import
26 // defines the custom element). Heavy or page-specific islands (media player,
27 // uploader) load per-page instead. Custom elements auto-upgrade on connect, so
28 // carousels in HTMX-swapped content wire themselves with no extra glue.
29 import '../islands/carousel.ts';
30 // Image uploader appears in HTMX-swapped wizard steps, so it's registered
31 // globally (auto-upgrades on swap). The heavier upload flows (item audio/version
32 // queue, gallery, bundle) still use the legacy static/upload.js until migrated.
33 import '../islands/uploader/image-uploader.ts';
34 // SyncKit dashboard: the keys-endpoint secret action. Registers a dispatcher
35 // verb (no window global) and is inert on pages without the button.
36 import '../islands/synckit-keys-secret.ts';
37 // /pricing list-vs-founder toggle. Tiny, and inert on every other page and on
38 // /pricing itself once the founder window closes.
39 import '../islands/price-mode.ts';
40
41 /**
42 * Legacy bridge, the not-yet-migrated `static/*.js` files call these by their
43 * historical global names. `mnw.js` exposed them as classic-script globals
44 * (function declarations / `window.*`); the module re-exposes them so the
45 * cutover is behavior-preserving. Retire each entry as its consumers move into
46 * frontend/src.
47 */
48 function installLegacyBridge(): void {
49 const w = window as unknown as Record<string, unknown>;
50 w.escapeHtml = escapeHtml;
51 w.escapeAttr = escapeAttr;
52 w.csrfHeaders = csrfHeaders;
53 w.showToast = showToast;
54 w.safeStorageGet = safeGet;
55 w.safeStorageSet = safeSet;
56 w.setActiveTab = setActiveTab;
57 w.toggleShortcutsHelp = toggleShortcutsHelp;
58 w.copyWithFeedback = copyWithFeedback;
59 w.resolveHtmxLoadingButton = resolveHtmxLoadingButton;
60 w.withLoadingState = withLoadingState;
61 // Historical name; wraps apiError so the (response, fallback) signature and
62 // the Promise<string> return match the old global exactly.
63 w.apiErrorMessage = (response: Response | null | undefined, fallback?: string) => apiError(response, fallback);
64 }
65
66 function initCore(): void {
67 installLegacyBridge();
68 initToasts();
69 initHtmxGlue();
70 initActionDispatcher();
71 initHxCallbackDispatcher();
72 initCopyLink();
73 initKeyboard();
74 initTabs();
75 initRestartBanner();
76 }
77
78 // A module script is deferred, so the DOM is already parsed by the time this
79 // runs; the readyState guard is belt-and-suspenders.
80 if (document.readyState === 'loading') {
81 document.addEventListener('DOMContentLoaded', initCore);
82 } else {
83 initCore();
84 }
85