0ca9741Seed the GitHub workspace locally after publishJeremy Magland 1import { attachGitHubSourceControl, createIndexedDBFileSystem, createWorkbench, transplantGitHubWorkspace, type Workbench, type WorkbenchTheme, type WorkspaceFileSystem } from 'minwebide';
2import { githubWorkspaceDbName } from './githubOpen';
caef63amip integration: system store in IndexedDB, shared across projectsJeremy Magland 3import { createMipSystem } from './numbl/mipSystem';
ecdc868numbl web IDE: run .m files in the browser with numblJeremy Magland 4import { createNumblRunner } from './numbl/runner';
5import { openProjectFileSystem, touchProject, type ProjectInfo } from './projects';
af97089Open GitHub repos as workspaces via #/github/<spec>Jeremy Magland 7export interface NumblWorkbench {
8 readonly workbench: Workbench;
9 dispose(): void;
10}
13 * Assembles the numbl workbench (mip system + runner) on a file system.
14 * Shared by project IDEs and GitHub repo IDEs; does not own `fs` — the
15 * caller disposes it.
16 */
17export async function openNumblWorkbench(container: HTMLElement, fs: WorkspaceFileSystem, workspaceName: string, theme: WorkbenchTheme): Promise<NumblWorkbench> {
caef63amip integration: system store in IndexedDB, shared across projectsJeremy Magland 18 const mip = await createMipSystem();
19 // fetch/refresh mip core in the background; runs await it (and say so
20 // in the output channel if they actually have to wait)
21 void mip.ensureCore().catch(() => { /* retried on the next run */ });
23 const workbench = createWorkbench(container, {
24 fileSystem: fs,
25 theme,
caef63amip integration: system store in IndexedDB, shared across projectsJeremy Magland 29 const numbl = createNumblRunner(fs, workbench, mip);
ecdc868numbl web IDE: run .m files in the browser with numblJeremy Magland 30 workbench.registerRunner(numbl.runner);
33 workbench,
34 dispose() {
35 numbl.dispose();
36 workbench.dispose();
37 mip.dispose();
38 },
39 };
40}
af97089Open GitHub repos as workspaces via #/github/<spec>Jeremy Magland 42/** Opens the most useful starting file, if any. */
43export async function openStartingFile(fs: WorkspaceFileSystem, workbench: Workbench): Promise<void> {
ecdc868numbl web IDE: run .m files in the browser with numblJeremy Magland 44 for (const path of ['/waves.m', '/main.m', '/README.md']) {
45 const uri = fs.root.with({ path });
46 if (await fs.fileService.exists(uri)) {
47 await workbench.openFile(uri);
50 }
53/** Opens the IDE for a project. Returns a disposable view. */
54export async function openIde(container: HTMLElement, project: ProjectInfo, theme: WorkbenchTheme): Promise<{ dispose(): void }> {
55 touchProject(project.id);
56 document.title = `${project.name} — numbl web IDE`;
58 const fs = await openProjectFileSystem(project.id);
59 const ide = await openNumblWorkbench(container, fs, project.name, theme);
61 // the project indicator: click to go back to the project list
62 ide.workbench.statusBar.setItem('project', 'left', project.name, {
63 icon: 'folder-opened',
64 title: 'Back to projects',
65 onClick: () => { location.hash = '#/'; },
66 });
67 // replace the default branding item with the project indicator
68 ide.workbench.statusBar.removeItem('branding');
70 // source control: publish this project to a new GitHub repo, or — once
71 // published — track changes and push
72 const sourceControl = await attachGitHubSourceControl(ide.workbench, fs, {
73 appName: 'numbl web IDE',
74 defaultRepoName: project.name,
0ca9741Seed the GitHub workspace locally after publishJeremy Magland 75 // after publishing, seed the repo's own workspace from the local copy
76 // (no re-download — the local state IS the pushed state) and make its
77 // route the canonical place to work
78 onPublished: async ({ owner, repo }) => {
79 const ghFs = await createIndexedDBFileSystem({ dbName: githubWorkspaceDbName({ owner, repo }) });
80 try {
81 await transplantGitHubWorkspace(fs, ghFs);
82 } finally {
83 ghFs.dispose();
84 }
85 location.hash = `#/github/${owner}/${repo}`;
86 },
89 await openStartingFile(fs, ide.workbench);
91 return {
92 dispose() {
af97089Open GitHub repos as workspaces via #/github/<spec>Jeremy Magland 93 sourceControl.dispose();
94 ide.dispose();
96 },
97 };
98}