176 lines
7.6 KiB
JavaScript
176 lines
7.6 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.FsaNodeSyncWorker = void 0;
|
|
const SyncMessenger_1 = require("./SyncMessenger");
|
|
const FsaNodeFs_1 = require("../FsaNodeFs");
|
|
const json_1 = require("../json");
|
|
class FsaNodeSyncWorker {
|
|
constructor() {
|
|
this.sab = new SharedArrayBuffer(1024 * 1024);
|
|
this.messenger = new SyncMessenger_1.SyncMessenger(this.sab);
|
|
this.onPostMessage = (msg) => {
|
|
switch (msg[0]) {
|
|
case 1 /* FsaNodeWorkerMessageCode.SetRoot */: {
|
|
const [, id, dir] = msg;
|
|
this.root = dir;
|
|
this.fs = new FsaNodeFs_1.FsaNodeFs(this.root);
|
|
const response = [2 /* FsaNodeWorkerMessageCode.RootSet */, id];
|
|
postMessage(response);
|
|
this.messenger.serveAsync(this.onRequest);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
this.onRequest = async (request) => {
|
|
try {
|
|
const message = json_1.decoder.decode(request);
|
|
if (!Array.isArray(message))
|
|
throw new Error('Invalid message format');
|
|
const code = message[0];
|
|
if (code !== 3 /* FsaNodeWorkerMessageCode.Request */)
|
|
throw new Error('Invalid message code');
|
|
const [, method, payload] = message;
|
|
const handler = this.handlers[method];
|
|
if (!handler)
|
|
throw new Error(`Unknown method ${method}`);
|
|
const response = await handler(payload);
|
|
return json_1.encoder.encode([4 /* FsaNodeWorkerMessageCode.Response */, response]);
|
|
}
|
|
catch (err) {
|
|
const message = err && typeof err === 'object' && err.message ? err.message : 'Unknown error';
|
|
const error = { message };
|
|
if (err && typeof err === 'object' && (err.code || err.name))
|
|
error.code = err.code || err.name;
|
|
return json_1.encoder.encode([5 /* FsaNodeWorkerMessageCode.ResponseError */, error]);
|
|
}
|
|
};
|
|
this.handlers = {
|
|
stat: async (location) => {
|
|
const handle = await this.getFileOrDir(location[0], location[1], 'statSync');
|
|
return {
|
|
kind: handle.kind,
|
|
};
|
|
},
|
|
access: async ([filename, mode]) => {
|
|
await this.fs.promises.access(filename, mode);
|
|
},
|
|
readFile: async ([filename, opts]) => {
|
|
const buf = (await this.fs.promises.readFile(filename, Object.assign(Object.assign({}, opts), { encoding: 'buffer' })));
|
|
const uint8 = new Uint8Array(buf, buf.byteOffset, buf.byteLength);
|
|
return uint8;
|
|
},
|
|
writeFile: async ([filename, data, opts]) => {
|
|
await this.fs.promises.writeFile(filename, data, Object.assign(Object.assign({}, opts), { encoding: 'buffer' }));
|
|
},
|
|
appendFile: async ([filename, data, opts]) => {
|
|
await this.fs.promises.appendFile(filename, data, Object.assign(Object.assign({}, opts), { encoding: 'buffer' }));
|
|
},
|
|
copy: async ([src, dst, flags]) => {
|
|
await this.fs.promises.copyFile(src, dst, flags);
|
|
},
|
|
move: async ([src, dst]) => {
|
|
await this.fs.promises.rename(src, dst);
|
|
},
|
|
rmdir: async ([filename, options]) => {
|
|
await this.fs.promises.rmdir(filename, options);
|
|
},
|
|
rm: async ([filename, options]) => {
|
|
await this.fs.promises.rm(filename, options);
|
|
},
|
|
mkdir: async ([filename, options]) => {
|
|
return await this.fs.promises.mkdir(filename, options);
|
|
},
|
|
mkdtemp: async ([filename]) => {
|
|
return (await this.fs.promises.mkdtemp(filename, { encoding: 'utf8' }));
|
|
},
|
|
trunc: async ([filename, len]) => {
|
|
await this.fs.promises.truncate(filename, len);
|
|
},
|
|
unlink: async ([filename]) => {
|
|
await this.fs.promises.unlink(filename);
|
|
},
|
|
readdir: async ([filename]) => {
|
|
const list = (await this.fs.promises.readdir(filename, { withFileTypes: true, encoding: 'utf8' }));
|
|
const res = list.map(entry => ({
|
|
kind: entry.isDirectory() ? 'directory' : 'file',
|
|
name: entry.name,
|
|
}));
|
|
return res;
|
|
},
|
|
read: async ([filename, position, length]) => {
|
|
let uint8 = new Uint8Array(length);
|
|
const handle = await this.fs.promises.open(filename, 'r');
|
|
const bytesRead = await new Promise((resolve, reject) => {
|
|
this.fs.read(handle.fd, uint8, 0, length, position, (err, bytesRead) => {
|
|
if (err)
|
|
return reject(err);
|
|
resolve(bytesRead || length);
|
|
});
|
|
});
|
|
if (bytesRead < length)
|
|
uint8 = uint8.slice(0, bytesRead);
|
|
return uint8;
|
|
},
|
|
write: async ([filename, data, position]) => {
|
|
const handle = await this.fs.promises.open(filename, 'a');
|
|
const { bytesWritten } = await handle.write(data, 0, data.length, position || undefined);
|
|
return bytesWritten;
|
|
},
|
|
open: async ([filename, flags, mode]) => {
|
|
const handle = await this.fs.promises.open(filename, flags, mode);
|
|
const file = await this.fs.__getFileById(handle.fd);
|
|
await handle.close();
|
|
return file;
|
|
},
|
|
};
|
|
}
|
|
start() {
|
|
onmessage = e => {
|
|
if (!Array.isArray(e.data))
|
|
return;
|
|
this.onPostMessage(e.data);
|
|
};
|
|
const initMsg = [0 /* FsaNodeWorkerMessageCode.Init */, this.sab];
|
|
postMessage(initMsg);
|
|
}
|
|
async getDir(path, create, funcName) {
|
|
let curr = this.root;
|
|
const options = { create };
|
|
try {
|
|
for (const name of path) {
|
|
curr = await curr.getDirectoryHandle(name, options);
|
|
}
|
|
}
|
|
catch (error) {
|
|
// if (error && typeof error === 'object' && error.name === 'TypeMismatchError')
|
|
// throw createError('ENOTDIR', funcName, path.join(FsaToNodeConstants.Separator));
|
|
throw error;
|
|
}
|
|
return curr;
|
|
}
|
|
async getFile(path, name, funcName, create) {
|
|
const dir = await this.getDir(path, false, funcName);
|
|
const file = await dir.getFileHandle(name, { create });
|
|
return file;
|
|
}
|
|
async getFileOrDir(path, name, funcName, create) {
|
|
const dir = await this.getDir(path, false, funcName);
|
|
try {
|
|
const file = await dir.getFileHandle(name);
|
|
return file;
|
|
}
|
|
catch (error) {
|
|
if (error && typeof error === 'object') {
|
|
switch (error.name) {
|
|
case 'TypeMismatchError':
|
|
return await dir.getDirectoryHandle(name);
|
|
// case 'NotFoundError':
|
|
// throw createError('ENOENT', funcName, path.join(FsaToNodeConstants.Separator));
|
|
}
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
exports.FsaNodeSyncWorker = FsaNodeSyncWorker;
|
|
//# sourceMappingURL=FsaNodeSyncWorker.js.map
|