1import { loadBuiltinTheme, registerBuiltinLanguages } from 'minwebide';
2import { openIde } from './ide';
3import { renderLanding } from './landing';
4import { registerMatlabLanguage } from './numbl/language';
5import { getProject } from './projects';
7// Routes:
8// #/ project picker (landing page)
9// #/project/<id> the IDE, opened on that project's file system
11async function start(): Promise<void> {
12 // dev never uses a service worker (isolation comes from server headers) —
13 // unregister any stale coi-serviceworker left over from a production
14 // build or an earlier version, since a controlling stale SW can block
15 // module workers with mismatched COEP headers
16 if (import.meta.env.DEV && 'serviceWorker' in navigator) {
17 const registrations = await navigator.serviceWorker.getRegistrations();
18 if (registrations.length > 0) {
19 await Promise.all(registrations.map(r => r.unregister()));
20 if (navigator.serviceWorker.controller) {
21 location.reload();
22 return;
23 }
24 }
25 }
27 const app = document.getElementById('app')!;
29 // one-time global setup: theme + languages are shared by all views;
30 // MATLAB registers last so it wins the .m extension
31 const theme = await loadBuiltinTheme('dark_modern');
32 await registerBuiltinLanguages(theme);
33 registerMatlabLanguage();
35 let current: { dispose(): void } | undefined;
36 let navigating = false;
38 const route = async () => {
39 if (navigating) {
40 return;
41 }
42 navigating = true;
43 try {
44 current?.dispose();
45 current = undefined;
46 app.textContent = '';
48 const match = location.hash.match(/^#\/project\/([a-z0-9]+)/i);
49 if (match) {
50 const project = getProject(match[1]);
51 if (project) {
52 current = await openIde(app, project, theme);
53 return;
54 }
55 // unknown project id: fall through to the landing page
56 history.replaceState(null, '', '#/');
57 }
58 current = renderLanding(app, theme);
59 } finally {
60 navigating = false;
61 }
62 };
64 window.addEventListener('hashchange', route);
65 await route();
66}
68start();