Full-featured .scad text editor w/ autocomplete
This commit is contained in:
parent
6486d698d4
commit
186049b215
14 changed files with 930 additions and 13 deletions
104
src/filesystem.ts
Normal file
104
src/filesystem.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// import FS from "browserfs/dist/node/core/FS";
|
||||
import { BrowserFS } from "./BrowserFS";
|
||||
import { zipArchives } from "./zip-archives";
|
||||
|
||||
export interface FS {
|
||||
readdir(path: string, cb: (err: any, files: string[]) => void): void;
|
||||
symlink(target: string, source: string): void;
|
||||
}
|
||||
|
||||
export type FSMounts = {
|
||||
[n: string]: {fs: string, options: {zipData: Buffer}}
|
||||
}
|
||||
|
||||
export type Symlinks = {[alias: string]: string};
|
||||
|
||||
export function readDirAsArray(fs: FS, path: string): Promise<string[] | undefined> {
|
||||
return new Promise((res, rej) => fs.readdir(path, (err, files) => err ? rej(err) : res(files)));
|
||||
}
|
||||
|
||||
export async function getBrowserFSLibrariesMounts(archiveNames: string[]) {
|
||||
const Buffer = BrowserFS.BFSRequire('buffer').Buffer;
|
||||
const fetchData = async (url: string) => (await fetch(url)).arrayBuffer();
|
||||
const results: [string, ArrayBuffer][] =
|
||||
await Promise.all(archiveNames.map(async (n: string) => [n, await fetchData(`./libraries/${n}.zip`)]));
|
||||
|
||||
const zipMounts: FSMounts = {};
|
||||
for (const [n, zipData] of results) {
|
||||
zipMounts[n] = {
|
||||
fs: "ZipFS",
|
||||
options: {
|
||||
zipData: Buffer.from(zipData)
|
||||
}
|
||||
}
|
||||
}
|
||||
return zipMounts;
|
||||
}
|
||||
|
||||
export async function symlinkLibraries(archiveNames: string[], fs: FS, prefix='/libraries', cwd='/tmp') {
|
||||
const createSymlink = async (target: string, source: string) => {
|
||||
// console.log('symlink', target, source);
|
||||
await fs.symlink(target, source);
|
||||
// await symlink(target, source);
|
||||
};
|
||||
|
||||
await Promise.all(archiveNames.map(n => (async () => {
|
||||
if (!(n in zipArchives)) throw `Archive named ${n} invalid (valid ones: ${Object.keys(zipArchives).join(', ')})`;
|
||||
const {symlinks} = (zipArchives)[n];
|
||||
if (symlinks) {
|
||||
for (const from in symlinks) {
|
||||
const to = symlinks[from];
|
||||
const target = to == '.' ? `${prefix}/${n}` : `${prefix}/${n}/${to}`;
|
||||
const source = from.startsWith('/') ? from : `${cwd}/${from}`;
|
||||
await createSymlink(target, source);
|
||||
}
|
||||
} else {
|
||||
await createSymlink(`${prefix}/${n}`, `${cwd}/${n}`);
|
||||
}
|
||||
})()));
|
||||
}
|
||||
|
||||
function configureAndInstallFS(windowOrSelf: Window, options: any) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
BrowserFS.install(windowOrSelf);
|
||||
try {
|
||||
BrowserFS.configure(options, function (e: any) {
|
||||
if (e) reject(e);
|
||||
else resolve(null);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function createEditorFS(workingDir='/home') {
|
||||
const archiveNames = Object.keys(zipArchives);
|
||||
const librariesMounts = await getBrowserFSLibrariesMounts(archiveNames);
|
||||
const allMounts: FSMounts = {};
|
||||
for (const n in librariesMounts) {
|
||||
allMounts[`${workingDir}/${n}`] = librariesMounts[n];
|
||||
}
|
||||
|
||||
await configureAndInstallFS(window, {
|
||||
fs: "OverlayFS",
|
||||
options: {
|
||||
readable: {
|
||||
fs: "MountableFileSystem",
|
||||
options: {
|
||||
...allMounts,
|
||||
}
|
||||
},
|
||||
writable: {
|
||||
fs: "InMemory"
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var fs = BrowserFS.BFSRequire('fs');
|
||||
// const symlink = (target, source) => new Promise((res, rej) => fs.symlink(target, source, (err) => err ? rej(err) : res()));
|
||||
|
||||
// await setupLibraries(archiveNames, symlink, '/libraries', workingDir);
|
||||
return fs;
|
||||
}
|
||||
Loading…
Reference in a new issue