/ concept-collection / numbl-web-ide
Sign in
concept-collection / numbl-web-ide
numbl-web-ide / src / main.ts
79 lines · 2.5 KBBlameHistoryRaw
1import { loadBuiltinTheme, registerBuiltinLanguages } from 'minwebide';
2import { openGitHubRoute } from './githubOpen';
3import { openIde } from './ide';
4import { renderLanding } from './landing';
5import { registerMatlabLanguage } from './numbl/language';
6import { getProject } from './projects';
8// Routes:
9// #/ project picker (landing page)
10// #/project/<id> the IDE, opened on that project's file system
11// #/github/<spec> a GitHub repo as its own workspace (owner/repo[@ref],
12// or a URL-encoded github.com URL); imports on first
13// visit, then keeps a local editable copy — the URL
14// stays on this route and no project is created
16async function start(): Promise<void> {
17 // dev never uses a service worker (isolation comes from server headers) —
18 // unregister any stale coi-serviceworker left over from a production
19 // build or an earlier version, since a controlling stale SW can block
20 // module workers with mismatched COEP headers
21 if (import.meta.env.DEV && 'serviceWorker' in navigator) {
22 const registrations = await navigator.serviceWorker.getRegistrations();
23 if (registrations.length > 0) {
24 await Promise.all(registrations.map(r => r.unregister()));
25 if (navigator.serviceWorker.controller) {
26 location.reload();
27 return;
28 }
29 }
30 }
32 const app = document.getElementById('app')!;
34 // one-time global setup: theme + languages are shared by all views;
35 // MATLAB registers last so it wins the .m extension
36 const theme = await loadBuiltinTheme('dark_modern');
37 await registerBuiltinLanguages(theme);
38 registerMatlabLanguage();
40 let current: { dispose(): void } | undefined;
41 let navigating = false;
43 const route = async () => {
44 if (navigating) {
45 return;
46 }
47 navigating = true;
48 try {
49 current?.dispose();
50 current = undefined;
51 app.textContent = '';
53 const github = location.hash.match(/^#\/github\/(.+)$/);
54 if (github) {
55 current = await openGitHubRoute(app, decodeURIComponent(github[1]), theme);
56 return;
57 }
59 const match = location.hash.match(/^#\/project\/([a-z0-9]+)/i);
60 if (match) {
61 const project = getProject(match[1]);
62 if (project) {
63 current = await openIde(app, project, theme);
64 return;
65 }
66 // unknown project id: fall through to the landing page
67 history.replaceState(null, '', '#/');
68 }
69 current = renderLanding(app, theme);
70 } finally {
71 navigating = false;
72 }
73 };
75 window.addEventListener('hashchange', route);
76 await route();
79start();
moveopenescclose