Skip to content

Commit

Permalink
fileserver: refine BrowserFS typing
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 24, 2024
1 parent 4ded71b commit 37c6054
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 50 deletions.
2 changes: 1 addition & 1 deletion integ/browser-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"puppeteer": "^21.7.0",
"ts-loader": "^9.5.1",
"tslib": "^2.6.2",
"type-fest": "^4.10.0",
"type-fest": "^4.10.1",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
Expand Down
2 changes: 1 addition & 1 deletion mk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"js-yaml": "^4.1.0",
"readlink": "^3.0.0",
"split2": "^4.2.0",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
},
"dependencies": {
"compare-versions": "6.1.0"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"packageManager": "pnpm@8.14.3",
"devDependencies": {
"@types/node": "^20.11.5",
"@types/node": "^20.11.6",
"@types/wtfnode": "^0.7.3",
"@typescript/lib-dom": "npm:@types/web@0.0.135",
"@vitest/coverage-v8": "^1.2.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/autoconfig/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@
"@types/koa": "^2.14.0",
"@types/node-fetch": "^2.6.11",
"koa": "^2.15.0",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
}
}
62 changes: 35 additions & 27 deletions packages/fileserver/src/browserfs.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
import { type BackendOption, CreateBackend } from "@browserfs/core/backends/backend.js";
import { ApiError, BaseFile, BaseFileSystem, type Cred, ErrorCode, type File, type FileFlag, type FileSystem, type FileSystemMetadata, FileType, Stats } from "@browserfs/core/index.js";
import { ApiError, BaseFile, BaseFileSystem, type Cred, ErrorCode, type File, type FileFlag, type FileSystemMetadata, FileType, Stats } from "@browserfs/core/index.js";
import { assert } from "@ndn/util";
import LRUCache from "mnemonist/lru-cache.js";
import { collect, map, pipeline } from "streaming-iterables";

import { Client } from "./client";
import { type FileMetadata } from "./metadata";

/** ndn6-file-server client wrapped as BrowserFS backend. */
export class NDNFileSystem extends BaseFileSystem implements FileSystem {
/**
* ndn6-file-server client wrapped as BrowserFS backend.
* This backend only supports async operations.
*/
export class NDNFileSystem extends BaseFileSystem {
public static override readonly Name = "NDN";
public static readonly Create = CreateBackend.bind(this);
public static readonly Options = {
public static readonly Options: Record<string, BackendOption<unknown>> = {
client: {
type: "object",
description: "Client instance",
validator(opt: Client) {
validator(opt) {
assert(opt instanceof Client);
},
} satisfies BackendOption<Client>,
},
statsCacheCapacity: {
type: "number",
description: "cache capacity for FileMetadata",
description: "cache capacity for FileMetadata, 0 disables cache",
optional: true,
validator(opt: number) {
validator(opt) {
assert(typeof opt === "number");
},
} satisfies BackendOption<number>,
} satisfies Record<string, BackendOption<unknown>>;
},
};

public static isAvailable(): boolean {
return true;
}

constructor({
client,
statsCacheCapacity = 16,
}: Partial<NDNFileSystem.Options> = {}) {
super();
constructor(opts: Partial<NDNFileSystem.Options> = {}) {
// opts is declared as optional and Partial to satisfy typing,
// but bfs.configure() would validate it against Options definition.
super(opts);
const {
client,
statsCacheCapacity = 16,
} = opts;

// use Partial<Options> to avoid typing error in Create function
assert(!!client);
assert(client instanceof Client);
this.client = client;

if (statsCacheCapacity > 0) {
Expand All @@ -52,9 +57,10 @@ export class NDNFileSystem extends BaseFileSystem implements FileSystem {
private readonly statsCache?: LRUCache<string, FileMetadata>;

public override get metadata(): FileSystemMetadata {
return Object.assign(super.metadata, {
return {
...super.metadata,
readonly: true,
} as Partial<FileSystemMetadata>);
};
}

private async getFileMetadata(p: string): Promise<FileMetadata> {
Expand Down Expand Up @@ -111,14 +117,6 @@ class NDNFile extends BaseFile implements File {
private readonly m: FileMetadata,
) {
super();
for (const methodName of fileMethodsNotsup) {
this[methodName] = () => {
throw new ApiError(ErrorCode.ENOTSUP);
};
}
for (const methodName of fileMethodsAsync) {
this[methodName] = async (...args: any[]) => (this[`${methodName}Sync`] as any)(...args);
}
}

public getPos(): number | undefined {
Expand Down Expand Up @@ -153,6 +151,16 @@ const fileMethodsAsync = [
"truncate",
"write",
] as const satisfies ReadonlyArray<keyof File>;
for (const methodName of fileMethodsNotsup) {
NDNFile.prototype[methodName] = () => {
throw new ApiError(ErrorCode.ENOTSUP);
};
}
for (const methodName of fileMethodsAsync) {
NDNFile.prototype[methodName] = async function (this: NDNFile, ...args: any[]) {
return (this[`${methodName}Sync`] as any)(...args);
};
}

function statsFromFileMetadata(m: FileMetadata): Stats {
return new Stats(
Expand Down
31 changes: 22 additions & 9 deletions packages/fileserver/tests/client.t.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ test.each(readFileIntoCases)("readFileInto [%d,%d)", async (...tc) => {
}, ...tc);
});

test("bfs rejects", async () => {
expect(() => bfs.statSync("/N/A")).toThrow(/ENOTSUP/);
expect(() => bfs.readdirSync("/N/A")).toThrow(/ENOTSUP/);
await expect(bfs.promises.open("/N/A/B.bin", "w")).rejects.toThrow(/ENOTSUP/);

// below are not ENOTSUP due to BaseFilesystem wrappers
expect(() => bfs.readFileSync("/N/A/B.bin")).toThrow(/ENOENT/);
expect(() => bfs.openSync("/N/A/B.bin", "r")).toThrow(/ENOENT/);
});

test("bfs stat", async () => {
const statRoot = await bfs.promises.stat("/N");
expect(statRoot.isDirectory()).toBeTruthy();
Expand All @@ -163,15 +173,6 @@ test("bfs stat", async () => {
expect(statB.size).toBe(bodyB.length);
});

test("bfs open reject", async () => {
await expect(bfs.promises.open("/N/A/B.bin", "w")).rejects.toThrow();
});

test("bfs readdir", async () => {
await expect(bfs.promises.readdir("/N")).resolves.toEqual(["A"]);
await expect(bfs.promises.readdir("/N/A")).resolves.toEqual(["B.bin"]);
});

describe("bfs open", () => {
let fd: number;
beforeAll(async () => {
Expand All @@ -183,7 +184,14 @@ describe("bfs open", () => {
await bfs.promises.close(fd);
});

test("rejects", () => {
const buf = new Uint8Array(16);
expect(() => bfs.readSync(fd, buf)).toThrow(/ENOTSUP/);
expect(() => bfs.readSync(fd, buf, 0, 16, 0)).toThrow(/ENOTSUP/);
});

test("stat", async () => {
expect(bfs.fstatSync(fd).size).toBe(bodyB.length);
expect((await bfs.promises.fstat(fd)).size).toBe(bodyB.length);
});

Expand All @@ -194,6 +202,11 @@ describe("bfs open", () => {
});
});

test("bfs readdir", async () => {
await expect(bfs.promises.readdir("/N")).resolves.toEqual(["A"]);
await expect(bfs.promises.readdir("/N/A")).resolves.toEqual(["B.bin"]);
});

test("bfs readFile", async () => {
await expect(bfs.promises.readFile("/N/A/B.bin")).resolves.toEqualUint8Array(bodyB);
});
2 changes: 1 addition & 1 deletion packages/l3face/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"retry": "^0.13.1",
"streaming-iterables": "^8.0.1",
"tslib": "^2.6.2",
"type-fest": "^4.10.0",
"type-fest": "^4.10.1",
"typescript-event-target": "^1.1.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/nac/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@yoursunny/asn1": "0.0.20200718",
"mnemonist": "^0.39.7",
"tslib": "^2.6.2",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
},
"devDependencies": {
"@ndn/repo": "workspace:*"
Expand Down
2 changes: 1 addition & 1 deletion packages/ndncert/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"nodemailer": "^6.9.8",
"p-timeout": "^6.1.2",
"tslib": "^2.6.2",
"type-fest": "^4.10.0",
"type-fest": "^4.10.1",
"typescript-event-target": "^1.1.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/nfdmgmt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"devDependencies": {
"@ndn/l3face": "workspace:*",
"@ndn/node-transport": "workspace:*",
"type-fest": "^4.10.0",
"type-fest": "^4.10.1",
"typescript-event-target": "^1.1.0"
}
}
2 changes: 1 addition & 1 deletion packages/node-transport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@ndn/l3face": "workspace:*",
"event-iterator": "^2.0.0",
"tslib": "^2.6.2",
"type-fest": "^4.10.0",
"type-fest": "^4.10.1",
"url-format-lax": "^2.0.0",
"url-parse-lax": "^5.0.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/packet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"buffer-compare": "^1.1.1",
"mnemonist": "^0.39.7",
"tslib": "^2.6.2",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
},
"devDependencies": {
"@types/buffer-compare": "^0.0.33"
Expand Down
2 changes: 1 addition & 1 deletion packages/repo-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@
"@types/tmp": "^0.2.6",
"stream-mock": "^2.0.5",
"tmp": "^0.2.1",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
}
}
2 changes: 1 addition & 1 deletion packages/segmented-object/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@
"@ndn/l3face": "workspace:*",
"@ndn/repo-api": "workspace:*",
"stream-mock": "^2.0.5",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
}
}
2 changes: 1 addition & 1 deletion packages/tlv/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
"@ndn/util": "workspace:*",
"mnemonist": "^0.39.7",
"tslib": "^2.6.2",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
}
}
2 changes: 1 addition & 1 deletion packages/trust-schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@ndn/util": "workspace:*",
"mnemonist": "^0.39.7",
"tslib": "^2.6.2",
"type-fest": "^4.10.0"
"type-fest": "^4.10.1"
},
"devDependencies": {
"@ndn/repo": "workspace:*",
Expand Down

0 comments on commit 37c6054

Please sign in to comment.