Skip to content

Commit 66b7a50

Browse files
committed
Allow mounting other http fs's
1 parent 2141ea7 commit 66b7a50

File tree

7 files changed

+82
-12
lines changed

7 files changed

+82
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ test-results
99
playwright-report
1010
playwright/.cache
1111

12+
public/private
1213
public/robots.txt
1314
public/rss.xml
1415
public/sitemap.xml

components/apps/Terminal/useCommandInterpreter.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const useCommandInterpreter = (
108108
lstat,
109109
mapFs,
110110
mkdirRecursive,
111+
mountHttpRequestFs,
111112
readdir,
112113
readFile,
113114
rename,
@@ -680,8 +681,27 @@ const useCommandInterpreter = (
680681
}
681682
}
682683
break;
683-
case "mount":
684-
if (isFileSystemMappingSupported()) {
684+
case "mount": {
685+
const [mountPoint, url, baseUrl] = commandArgs;
686+
687+
if (mountPoint && url) {
688+
try {
689+
await mountHttpRequestFs(
690+
mountPoint,
691+
url,
692+
baseUrl === "/" ? undefined : baseUrl || mountPoint
693+
);
694+
695+
const basePath = dirname(mountPoint);
696+
697+
updateFolder(
698+
basePath === "." ? "/" : basePath,
699+
basename(mountPoint)
700+
);
701+
} catch (error) {
702+
printLn(error);
703+
}
704+
} else if (isFileSystemMappingSupported()) {
685705
try {
686706
const mappedFolder = await mapFs(cd.current);
687707

@@ -700,6 +720,7 @@ const useCommandInterpreter = (
700720
printLn(COMMAND_NOT_SUPPORTED);
701721
}
702722
break;
723+
}
703724
case "move":
704725
case "mv":
705726
case "ren":
@@ -1255,6 +1276,7 @@ const useCommandInterpreter = (
12551276
lstat,
12561277
mapFs,
12571278
mkdirRecursive,
1279+
mountHttpRequestFs,
12581280
open,
12591281
processesRef,
12601282
readFile,

contexts/fileSystem/core.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import index from "public/.index/fs.9p.json";
88
import {
99
FS_HANDLES,
1010
MOUNTABLE_EXTENSIONS,
11+
MOUNTABLE_FS_TYPES,
1112
ONE_TIME_PASSIVE_EVENT,
1213
} from "utils/constants";
1314

@@ -21,7 +22,7 @@ type FS9PV3 = [
2122
number,
2223
FS9PV3[] | string,
2324
];
24-
type FS9PV4 = [string, number, number, FS9PV4[] | undefined];
25+
export type FS9PV4 = [string, number, number, FS9PV4[] | undefined];
2526
type FS9P = {
2627
fsroot: FS9PV3[];
2728
size: number;
@@ -76,7 +77,7 @@ export const get9pModifiedTime = (path: string): number =>
7677

7778
export const get9pSize = (path: string): number => get9pData(path, IDX_SIZE);
7879

79-
const parseDirectory = (array: FS9PV4[]): BFSFS => {
80+
export const parseDirectory = (array: FS9PV4[]): BFSFS => {
8081
const directory: BFSFS = {};
8182

8283
// eslint-disable-next-line unicorn/no-unreadable-array-destructuring
@@ -201,7 +202,7 @@ export const getFileSystemHandles = async (): Promise<FileSystemHandles> => {
201202

202203
export const isMountedFolder = (mount?: Mount): boolean =>
203204
typeof mount === "object" &&
204-
(mount.getName() === "FileSystemAccess" ||
205+
(MOUNTABLE_FS_TYPES.has(mount.getName()) ||
205206
(mount as ExtendedEmscriptenFileSystem)._FS?.DB_STORE_NAME === "FILE_DATA");
206207

207208
export const getMountUrl = (

contexts/fileSystem/useFileSystemContextState.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import {
2222
getFileSystemHandles,
2323
hasIndexedDB,
2424
isMountedFolder,
25+
parseDirectory,
2526
KEYVAL_DB,
27+
type FS9PV4,
2628
} from "contexts/fileSystem/core";
2729
import useAsyncFs, {
2830
type AsyncFS,
@@ -103,6 +105,11 @@ type FileSystemContextState = AsyncFS & {
103105
mkdirRecursive: (path: string) => Promise<void>;
104106
mountEmscriptenFs: (FS: EmscriptenFS, fsName?: string) => Promise<string>;
105107
mountFs: (url: string) => Promise<void>;
108+
mountHttpRequestFs: (
109+
mountPoint: string,
110+
url: string,
111+
baseUrl?: string
112+
) => Promise<void>;
106113
moveEntries: (entries: string[]) => void;
107114
pasteList: FilePasteOperations;
108115
removeFsWatcher: (folder: string, updateFiles: UpdateFiles) => void;
@@ -293,6 +300,40 @@ const useFileSystemContextState = (): FileSystemContextState => {
293300
}),
294301
[rootFs]
295302
);
303+
const mountHttpRequestFs = useCallback(
304+
async (
305+
mountPoint: string,
306+
url: string,
307+
baseUrl?: string
308+
): Promise<void> => {
309+
const index = (await (await fetch(url)).json()) as object;
310+
311+
if (!(typeof index === "object" && "fsroot" in index)) {
312+
throw new Error("Invalid HTTPRequest FS object.");
313+
}
314+
315+
const {
316+
FileSystem: { HTTPRequest },
317+
} = (await import(
318+
"public/System/BrowserFS/browserfs.min.js"
319+
)) as typeof IBrowserFS;
320+
321+
return new Promise((resolve, reject) => {
322+
HTTPRequest?.Create(
323+
{ baseUrl, index: parseDirectory(index.fsroot as FS9PV4[]) },
324+
(error, newFs) => {
325+
if (error || !newFs) {
326+
reject(new Error("Error while mounting HTTPRequest FS."));
327+
} else {
328+
rootFs?.mount?.(mountPoint, newFs);
329+
resolve();
330+
}
331+
}
332+
);
333+
});
334+
},
335+
[rootFs]
336+
);
296337
const mapFs = useCallback(
297338
async (
298339
directory: string,
@@ -658,6 +699,7 @@ const useFileSystemContextState = (): FileSystemContextState => {
658699
mkdirRecursive,
659700
mountEmscriptenFs,
660701
mountFs,
702+
mountHttpRequestFs,
661703
moveEntries,
662704
pasteList,
663705
removeFsWatcher,

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
"scripts": {
1515
"build": "yarn build:prebuild && next build",
1616
"build:bundle-analyzer": "yarn build",
17-
"build:fs": "node scripts/fs2json.js --exclude .index --out public/.index/fs.9p.json ./public",
17+
"build:fs:private": "node scripts/fs2json.js --out public/.index/fs.private.9p.json ./public/private",
18+
"build:fs:public": "node scripts/fs2json.js --exclude .index,private --out public/.index/fs.9p.json ./public",
1819
"build:minify": "node scripts/minifyHtml.js && node scripts/minifyJs.js",
19-
"build:prebuild": "node scripts/robots.js && node scripts/rssBuilder.js && node scripts/searchIndex.js && node scripts/preloadIcons.js && node scripts/cacheShortcuts.js && yarn build:fs",
20+
"build:prebuild": "node scripts/robots.js && node scripts/rssBuilder.js && node scripts/searchIndex.js && node scripts/preloadIcons.js && node scripts/cacheShortcuts.js && yarn build:fs:public",
2021
"docker:build": "docker build -t daedalos .",
2122
"docker:run": "docker run -dp 3000:3000 --rm --name daedalos daedalos",
2223
"dev": "next dev",

scripts/fs2json.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ const IDX_TARGET = 3;
1010

1111
const args = process.argv.slice(2);
1212
const argPath = resolvePath(args[args.length - 1]);
13-
const excludedPaths = [];
13+
let excludedPaths = [];
1414
let outputPath = "";
1515

1616
args.forEach((arg, index) => {
17-
if (arg === "--exclude") excludedPaths.push(args[index + 1]);
17+
if (arg === "--exclude") excludedPaths = args[index + 1].split(",");
1818
if (arg === "--out") outputPath = resolvePath(args[index + 1]);
1919
});
2020

@@ -43,9 +43,10 @@ const fs2json = (dir) => {
4343
return;
4444
}
4545

46-
const includedFiles = files.filter(
47-
(file) => !excludedPaths.includes(file)
48-
);
46+
const includedFiles =
47+
dir === walkDir
48+
? files.filter((file) => !excludedPaths.includes(file))
49+
: files;
4950

5051
const recur = () => {
5152
const file = includedFiles.shift();

utils/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ export const ZIP_EXTENSIONS = new Set([".jsdos", ".pk3", ".wsz", ".zip"]);
173173

174174
export const MOUNTABLE_EXTENSIONS = new Set([".iso", ...ZIP_EXTENSIONS]);
175175

176+
export const MOUNTABLE_FS_TYPES = new Set(["FileSystemAccess", "HTTPRequest"]);
177+
176178
export const SPREADSHEET_FORMATS = [
177179
".csv",
178180
".numbers",

0 commit comments

Comments
 (0)