FsaNodeSyncWorker.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.FsaNodeSyncWorker = void 0;
  4. const SyncMessenger_1 = require("./SyncMessenger");
  5. const FsaNodeFs_1 = require("../FsaNodeFs");
  6. const json_1 = require("../json");
  7. class FsaNodeSyncWorker {
  8. constructor() {
  9. this.sab = new SharedArrayBuffer(1024 * 1024);
  10. this.messenger = new SyncMessenger_1.SyncMessenger(this.sab);
  11. this.onPostMessage = (msg) => {
  12. switch (msg[0]) {
  13. case 1 /* FsaNodeWorkerMessageCode.SetRoot */: {
  14. const [, id, dir] = msg;
  15. this.root = dir;
  16. this.fs = new FsaNodeFs_1.FsaNodeFs(this.root);
  17. const response = [2 /* FsaNodeWorkerMessageCode.RootSet */, id];
  18. postMessage(response);
  19. this.messenger.serveAsync(this.onRequest);
  20. break;
  21. }
  22. }
  23. };
  24. this.onRequest = async (request) => {
  25. try {
  26. const message = json_1.decoder.decode(request);
  27. if (!Array.isArray(message))
  28. throw new Error('Invalid message format');
  29. const code = message[0];
  30. if (code !== 3 /* FsaNodeWorkerMessageCode.Request */)
  31. throw new Error('Invalid message code');
  32. const [, method, payload] = message;
  33. const handler = this.handlers[method];
  34. if (!handler)
  35. throw new Error(`Unknown method ${method}`);
  36. const response = await handler(payload);
  37. return json_1.encoder.encode([4 /* FsaNodeWorkerMessageCode.Response */, response]);
  38. }
  39. catch (err) {
  40. const message = err && typeof err === 'object' && err.message ? err.message : 'Unknown error';
  41. const error = { message };
  42. if (err && typeof err === 'object' && (err.code || err.name))
  43. error.code = err.code || err.name;
  44. return json_1.encoder.encode([5 /* FsaNodeWorkerMessageCode.ResponseError */, error]);
  45. }
  46. };
  47. this.handlers = {
  48. stat: async (location) => {
  49. const handle = await this.getFileOrDir(location[0], location[1], 'statSync');
  50. return {
  51. kind: handle.kind,
  52. };
  53. },
  54. access: async ([filename, mode]) => {
  55. await this.fs.promises.access(filename, mode);
  56. },
  57. readFile: async ([filename, opts]) => {
  58. const buf = (await this.fs.promises.readFile(filename, Object.assign(Object.assign({}, opts), { encoding: 'buffer' })));
  59. const uint8 = new Uint8Array(buf, buf.byteOffset, buf.byteLength);
  60. return uint8;
  61. },
  62. writeFile: async ([filename, data, opts]) => {
  63. await this.fs.promises.writeFile(filename, data, Object.assign(Object.assign({}, opts), { encoding: 'buffer' }));
  64. },
  65. appendFile: async ([filename, data, opts]) => {
  66. await this.fs.promises.appendFile(filename, data, Object.assign(Object.assign({}, opts), { encoding: 'buffer' }));
  67. },
  68. copy: async ([src, dst, flags]) => {
  69. await this.fs.promises.copyFile(src, dst, flags);
  70. },
  71. move: async ([src, dst]) => {
  72. await this.fs.promises.rename(src, dst);
  73. },
  74. rmdir: async ([filename, options]) => {
  75. await this.fs.promises.rmdir(filename, options);
  76. },
  77. rm: async ([filename, options]) => {
  78. await this.fs.promises.rm(filename, options);
  79. },
  80. mkdir: async ([filename, options]) => {
  81. return await this.fs.promises.mkdir(filename, options);
  82. },
  83. mkdtemp: async ([filename]) => {
  84. return (await this.fs.promises.mkdtemp(filename, { encoding: 'utf8' }));
  85. },
  86. trunc: async ([filename, len]) => {
  87. await this.fs.promises.truncate(filename, len);
  88. },
  89. unlink: async ([filename]) => {
  90. await this.fs.promises.unlink(filename);
  91. },
  92. readdir: async ([filename]) => {
  93. const list = (await this.fs.promises.readdir(filename, { withFileTypes: true, encoding: 'utf8' }));
  94. const res = list.map(entry => ({
  95. kind: entry.isDirectory() ? 'directory' : 'file',
  96. name: entry.name,
  97. }));
  98. return res;
  99. },
  100. read: async ([filename, position, length]) => {
  101. let uint8 = new Uint8Array(length);
  102. const handle = await this.fs.promises.open(filename, 'r');
  103. const bytesRead = await new Promise((resolve, reject) => {
  104. this.fs.read(handle.fd, uint8, 0, length, position, (err, bytesRead) => {
  105. if (err)
  106. return reject(err);
  107. resolve(bytesRead || length);
  108. });
  109. });
  110. if (bytesRead < length)
  111. uint8 = uint8.slice(0, bytesRead);
  112. return uint8;
  113. },
  114. write: async ([filename, data, position]) => {
  115. const handle = await this.fs.promises.open(filename, 'a');
  116. const { bytesWritten } = await handle.write(data, 0, data.length, position || undefined);
  117. return bytesWritten;
  118. },
  119. open: async ([filename, flags, mode]) => {
  120. const handle = await this.fs.promises.open(filename, flags, mode);
  121. const file = await this.fs.__getFileById(handle.fd);
  122. await handle.close();
  123. return file;
  124. },
  125. };
  126. }
  127. start() {
  128. onmessage = e => {
  129. if (!Array.isArray(e.data))
  130. return;
  131. this.onPostMessage(e.data);
  132. };
  133. const initMsg = [0 /* FsaNodeWorkerMessageCode.Init */, this.sab];
  134. postMessage(initMsg);
  135. }
  136. async getDir(path, create, funcName) {
  137. let curr = this.root;
  138. const options = { create };
  139. try {
  140. for (const name of path) {
  141. curr = await curr.getDirectoryHandle(name, options);
  142. }
  143. }
  144. catch (error) {
  145. // if (error && typeof error === 'object' && error.name === 'TypeMismatchError')
  146. // throw createError('ENOTDIR', funcName, path.join(FsaToNodeConstants.Separator));
  147. throw error;
  148. }
  149. return curr;
  150. }
  151. async getFile(path, name, funcName, create) {
  152. const dir = await this.getDir(path, false, funcName);
  153. const file = await dir.getFileHandle(name, { create });
  154. return file;
  155. }
  156. async getFileOrDir(path, name, funcName, create) {
  157. const dir = await this.getDir(path, false, funcName);
  158. try {
  159. const file = await dir.getFileHandle(name);
  160. return file;
  161. }
  162. catch (error) {
  163. if (error && typeof error === 'object') {
  164. switch (error.name) {
  165. case 'TypeMismatchError':
  166. return await dir.getDirectoryHandle(name);
  167. // case 'NotFoundError':
  168. // throw createError('ENOENT', funcName, path.join(FsaToNodeConstants.Separator));
  169. }
  170. }
  171. throw error;
  172. }
  173. }
  174. }
  175. exports.FsaNodeSyncWorker = FsaNodeSyncWorker;
  176. //# sourceMappingURL=FsaNodeSyncWorker.js.map