Skip to content

Commit

Permalink
feat: 🎸 setup webfs
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent 3439fc4 commit 68f0014
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 10 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -39,6 +39,7 @@
"tslint": "tslint \"src/**/*.ts\" -t verbose",
"typecheck": "tsc -p .",
"watch": "watch \"npm run build\" ./src",
"demo:webfs": "webpack serve --config ./src/webfs/webpack.config.js",
"demo:fsa-to-node-sync-tests": "webpack serve --config ./demo/fsa-to-node-sync-tests/webpack.config.js",
"demo:fsa-to-node-zipfile": "webpack serve --config ./demo/fsa-to-node-zipfile/webpack.config.js"
},
Expand Down
16 changes: 12 additions & 4 deletions src/fsa-to-node/FsaNodeCore.ts
Expand Up @@ -13,9 +13,17 @@ export class FsaNodeCore {
protected readonly fds = new Map<number, FsaNodeFsOpenFile>();

public constructor(
protected readonly root: fsa.IFileSystemDirectoryHandle,
protected syncAdapter?: FsaNodeSyncAdapter,
) {}
protected readonly root: fsa.IFileSystemDirectoryHandle | Promise<fsa.IFileSystemDirectoryHandle>,
public syncAdapter?: FsaNodeSyncAdapter,
) {
if (root instanceof Promise) {
root
.then((root) => {
(this as any).root = root;
})
.catch((error) => {});
}
}

protected getSyncAdapter(): FsaNodeSyncAdapter {
const adapter = this.syncAdapter;
Expand All @@ -39,7 +47,7 @@ export class FsaNodeCore {
* @param create Whether to create the folders if they don't exist.
*/
protected async getDir(path: string[], create: boolean, funcName?: string): Promise<fsa.IFileSystemDirectoryHandle> {
let curr: fsa.IFileSystemDirectoryHandle = this.root;
let curr: fsa.IFileSystemDirectoryHandle = await this.root;
const options: fsa.GetDirectoryHandleOptions = { create };
try {
for (const name of path) {
Expand Down
2 changes: 1 addition & 1 deletion src/fsa-to-node/FsaNodeFs.ts
Expand Up @@ -377,7 +377,7 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono
const filename = util.pathToFilename(path);
const [folder, name] = pathToLocation(filename);
(async () => {
const node = folder.length || name ? await this.getFileOrDir(folder, name, 'access') : this.root;
const node = folder.length || name ? await this.getFileOrDir(folder, name, 'access') : await this.root;
const checkIfCanExecute = mode & AMODE.X_OK;
if (checkIfCanExecute) throw util.createError('EACCESS', 'access', filename);
const checkIfCanWrite = mode & AMODE.W_OK;
Expand Down
8 changes: 4 additions & 4 deletions src/fsa-to-node/worker/FsaNodeSyncAdapterWorker.ts
Expand Up @@ -17,29 +17,29 @@ import type {
let rootId = 0;

export class FsaNodeSyncAdapterWorker implements FsaNodeSyncAdapter {
public static async start(url: string, dir: fsa.IFileSystemDirectoryHandle): Promise<FsaNodeSyncAdapterWorker> {
public static async start(url: string, dir: fsa.IFileSystemDirectoryHandle | Promise<fsa.IFileSystemDirectoryHandle>): Promise<FsaNodeSyncAdapterWorker> {
const worker = new Worker(url);
const future = new Defer<FsaNodeSyncAdapterWorker>();
let id = rootId++;
let messenger: SyncMessenger | undefined = undefined;
const _dir = await dir;
worker.onmessage = e => {
const data = e.data;
if (!Array.isArray(data)) return;
console.log('<', data);
const msg = data as FsaNodeWorkerMsg;
const code = msg[0] as FsaNodeWorkerMessageCode;
switch (code) {
case FsaNodeWorkerMessageCode.Init: {
const [, sab] = msg as FsaNodeWorkerMsgInit;
messenger = new SyncMessenger(sab);
const setRootMessage: FsaNodeWorkerMsgSetRoot = [FsaNodeWorkerMessageCode.SetRoot, id, dir];
const setRootMessage: FsaNodeWorkerMsgSetRoot = [FsaNodeWorkerMessageCode.SetRoot, id, _dir];
worker.postMessage(setRootMessage);
break;
}
case FsaNodeWorkerMessageCode.RootSet: {
const [, rootId] = msg as FsaNodeWorkerMsgRootSet;
if (id !== rootId) return;
const adapter = new FsaNodeSyncAdapterWorker(messenger!, dir);
const adapter = new FsaNodeSyncAdapterWorker(messenger!, _dir);
future.resolve(adapter);
break;
}
Expand Down
1 change: 0 additions & 1 deletion src/fsa-to-node/worker/FsaNodeSyncWorker.ts
Expand Up @@ -22,7 +22,6 @@ export class FsaNodeSyncWorker {
public start() {
onmessage = e => {
if (!Array.isArray(e.data)) return;
console.log('>', e.data);
this.onPostMessage(e.data as FsaNodeWorkerMsg);
};
const initMsg: FsaNodeWorkerMsgInit = [FsaNodeWorkerMessageCode.Init, this.sab];
Expand Down
22 changes: 22 additions & 0 deletions src/webfs/index.ts
@@ -0,0 +1,22 @@
(<any>self).process = require('process/browser');
(<any>self).Buffer = require('buffer').Buffer;

import {FsaNodeFs, FsaNodeSyncAdapterWorker} from "../fsa-to-node";
import {FsaNodeSyncWorker} from "../../src/fsa-to-node/worker/FsaNodeSyncWorker";
import type {IFileSystemDirectoryHandle} from "../fsa/types";

if (typeof window === 'object') {
const url = (<any>document.currentScript).src;
const dir = navigator.storage.getDirectory() as unknown as Promise<IFileSystemDirectoryHandle>;
const fs = (<any>window).fs = new FsaNodeFs(dir);
if (url) {
FsaNodeSyncAdapterWorker.start(url, dir)
.then(adapter => {
fs.syncAdapter = adapter;
})
.catch(() => {});
}
} else {
const worker = new FsaNodeSyncWorker();
worker.start();
}
52 changes: 52 additions & 0 deletions src/webfs/webpack.config.js
@@ -0,0 +1,52 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const root = require('app-root-path');

module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: {
bundle: __dirname + '/index',
},
plugins: [
// new ForkTsCheckerWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Development',
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'ts-loader',
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
fallback: {
assert: require.resolve('assert'),
buffer: require.resolve('buffer'),
path: require.resolve('path-browserify'),
process: require.resolve('process/browser'),
stream: require.resolve('readable-stream'),
// url: require.resolve('url'),
},
},
output: {
filename: '[name].js',
path: path.resolve(root.path, 'dist'),
},
devServer: {
// HTTPS is required for SharedArrayBuffer to work.
https: true,
headers: {
// These two headers are required for SharedArrayBuffer to work.
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
},
port: 9876,
hot: false,
},
};

0 comments on commit 68f0014

Please sign in to comment.