@zenfs/core 0.16.4 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/backends/backend.d.ts +3 -4
  2. package/dist/backends/fetch.d.ts +8 -3
  3. package/dist/backends/fetch.js +3 -2
  4. package/dist/backends/{index/fs.d.ts → file_index.d.ts} +49 -10
  5. package/dist/backends/{index/fs.js → file_index.js} +84 -5
  6. package/dist/backends/memory.d.ts +6 -1
  7. package/dist/backends/memory.js +2 -1
  8. package/dist/backends/overlay.d.ts +16 -16
  9. package/dist/backends/overlay.js +59 -82
  10. package/dist/backends/port/fs.d.ts +6 -2
  11. package/dist/backends/port/fs.js +4 -2
  12. package/dist/backends/store/fs.js +484 -304
  13. package/dist/backends/store/simple.js +5 -1
  14. package/dist/backends/store/store.d.ts +4 -1
  15. package/dist/backends/store/store.js +9 -5
  16. package/dist/browser.min.js +4 -4
  17. package/dist/browser.min.js.map +4 -4
  18. package/dist/config.d.ts +3 -3
  19. package/dist/emulation/async.d.ts +0 -3
  20. package/dist/emulation/async.js +6 -2
  21. package/dist/emulation/dir.d.ts +4 -0
  22. package/dist/emulation/dir.js +8 -6
  23. package/dist/emulation/promises.d.ts +1 -3
  24. package/dist/emulation/promises.js +25 -2
  25. package/dist/emulation/sync.js +0 -1
  26. package/dist/emulation/watchers.d.ts +9 -4
  27. package/dist/emulation/watchers.js +7 -0
  28. package/dist/file.d.ts +17 -1
  29. package/dist/file.js +86 -1
  30. package/dist/filesystem.d.ts +0 -63
  31. package/dist/filesystem.js +0 -311
  32. package/dist/index.d.ts +1 -2
  33. package/dist/index.js +1 -2
  34. package/dist/mixins/async.d.ts +39 -0
  35. package/dist/mixins/async.js +216 -0
  36. package/dist/mixins/mutexed.d.ts +33 -0
  37. package/dist/mixins/mutexed.js +465 -0
  38. package/dist/mixins/readonly.d.ts +25 -0
  39. package/dist/mixins/readonly.js +57 -0
  40. package/dist/mixins/shared.d.ts +12 -0
  41. package/dist/mixins/shared.js +4 -0
  42. package/dist/mixins/sync.d.ts +6 -0
  43. package/dist/mixins/sync.js +43 -0
  44. package/package.json +1 -1
  45. package/src/backends/backend.ts +3 -4
  46. package/src/backends/fetch.ts +7 -3
  47. package/src/backends/{index/fs.ts → file_index.ts} +106 -8
  48. package/src/backends/memory.ts +5 -1
  49. package/src/backends/overlay.ts +64 -90
  50. package/src/backends/port/fs.ts +7 -2
  51. package/src/backends/{index/readme.md → readme.md} +1 -1
  52. package/src/backends/store/fs.ts +97 -155
  53. package/src/backends/store/simple.ts +5 -1
  54. package/src/backends/store/store.ts +10 -5
  55. package/src/config.ts +3 -1
  56. package/src/emulation/async.ts +15 -6
  57. package/src/emulation/dir.ts +19 -16
  58. package/src/emulation/promises.ts +28 -6
  59. package/src/emulation/sync.ts +1 -2
  60. package/src/emulation/watchers.ts +10 -4
  61. package/src/file.ts +94 -1
  62. package/src/filesystem.ts +3 -366
  63. package/src/index.ts +1 -2
  64. package/src/mixins/async.ts +211 -0
  65. package/src/mixins/mutexed.ts +245 -0
  66. package/src/mixins/readonly.ts +97 -0
  67. package/src/mixins/shared.ts +20 -0
  68. package/src/mixins/sync.ts +59 -0
  69. package/dist/backends/index/index.d.ts +0 -43
  70. package/dist/backends/index/index.js +0 -83
  71. package/dist/backends/locked.d.ts +0 -92
  72. package/dist/backends/locked.js +0 -487
  73. package/src/backends/index/index.ts +0 -104
  74. package/src/backends/locked.ts +0 -264
@@ -1,3 +1,48 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ }
13
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
14
+ env.stack.push({ value: value, dispose: dispose, async: async });
15
+ }
16
+ else if (async) {
17
+ env.stack.push({ async: true });
18
+ }
19
+ return value;
20
+ };
21
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
22
+ return function (env) {
23
+ function fail(e) {
24
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
25
+ env.hasError = true;
26
+ }
27
+ function next() {
28
+ while (env.stack.length) {
29
+ var rec = env.stack.pop();
30
+ try {
31
+ var result = rec.dispose && rec.dispose.call(rec.value);
32
+ if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
33
+ }
34
+ catch (e) {
35
+ fail(e);
36
+ }
37
+ }
38
+ if (env.hasError) throw env.error;
39
+ }
40
+ return next();
41
+ };
42
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
43
+ var e = new Error(message);
44
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
45
+ });
1
46
  import { R_OK, S_IFDIR, S_IFREG, W_OK } from '../../emulation/constants.js';
2
47
  import { basename, dirname, join, resolve } from '../../emulation/path.js';
3
48
  import { Errno, ErrnoError } from '../../error.js';
@@ -55,175 +100,221 @@ export class StoreFS extends FileSystem {
55
100
  * @todo Make rename compatible with the cache.
56
101
  */
57
102
  async rename(oldPath, newPath, cred) {
58
- const tx = this.store.transaction(), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
59
- // Remove oldPath from parent's directory listing.
60
- oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldDirNode, oldParent);
61
- if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
62
- throw ErrnoError.With('EACCES', oldPath, 'rename');
63
- }
64
- if (!oldDirList[oldName]) {
65
- throw ErrnoError.With('ENOENT', oldPath, 'rename');
66
- }
67
- const nodeId = oldDirList[oldName];
68
- delete oldDirList[oldName];
69
- // Invariant: Can't move a folder inside itself.
70
- // This funny little hack ensures that the check passes only if oldPath
71
- // is a subpath of newParent. We append '/' to avoid matching folders that
72
- // are a substring of the bottom-most folder in the path.
73
- if ((newParent + '/').indexOf(oldPath + '/') === 0) {
74
- throw new ErrnoError(Errno.EBUSY, oldParent);
75
- }
76
- // Add newPath to parent's directory listing.
77
- let newDirNode, newDirList;
78
- if (newParent === oldParent) {
79
- // Prevent us from re-grabbing the same directory listing, which still
80
- // contains oldName.
81
- newDirNode = oldDirNode;
82
- newDirList = oldDirList;
83
- }
84
- else {
85
- newDirNode = await this.findINode(tx, newParent);
86
- newDirList = await this.getDirListing(tx, newDirNode, newParent);
87
- }
88
- if (newDirList[newName]) {
89
- // If it's a file, delete it.
90
- const newNameNode = await this.getINode(tx, newDirList[newName], newPath);
91
- if (newNameNode.toStats().isFile()) {
92
- try {
103
+ const env_1 = { stack: [], error: void 0, hasError: false };
104
+ try {
105
+ const tx = __addDisposableResource(env_1, this.store.transaction(), true);
106
+ const oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
107
+ // Remove oldPath from parent's directory listing.
108
+ oldDirNode = await this.findINode(tx, oldParent), oldDirList = await this.getDirListing(tx, oldDirNode, oldParent);
109
+ if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
110
+ throw ErrnoError.With('EACCES', oldPath, 'rename');
111
+ }
112
+ if (!oldDirList[oldName]) {
113
+ throw ErrnoError.With('ENOENT', oldPath, 'rename');
114
+ }
115
+ const nodeId = oldDirList[oldName];
116
+ delete oldDirList[oldName];
117
+ // Invariant: Can't move a folder inside itself.
118
+ // This funny little hack ensures that the check passes only if oldPath
119
+ // is a subpath of newParent. We append '/' to avoid matching folders that
120
+ // are a substring of the bottom-most folder in the path.
121
+ if ((newParent + '/').indexOf(oldPath + '/') === 0) {
122
+ throw new ErrnoError(Errno.EBUSY, oldParent);
123
+ }
124
+ // Add newPath to parent's directory listing.
125
+ let newDirNode, newDirList;
126
+ if (newParent === oldParent) {
127
+ // Prevent us from re-grabbing the same directory listing, which still
128
+ // contains oldName.
129
+ newDirNode = oldDirNode;
130
+ newDirList = oldDirList;
131
+ }
132
+ else {
133
+ newDirNode = await this.findINode(tx, newParent);
134
+ newDirList = await this.getDirListing(tx, newDirNode, newParent);
135
+ }
136
+ if (newDirList[newName]) {
137
+ // If it's a file, delete it.
138
+ const newNameNode = await this.getINode(tx, newDirList[newName], newPath);
139
+ if (newNameNode.toStats().isFile()) {
93
140
  await tx.remove(newNameNode.ino);
94
141
  await tx.remove(newDirList[newName]);
95
142
  }
96
- catch (e) {
97
- await tx.abort();
98
- throw e;
143
+ else {
144
+ // If it's a directory, throw a permissions error.
145
+ throw ErrnoError.With('EPERM', newPath, 'rename');
99
146
  }
100
147
  }
101
- else {
102
- // If it's a directory, throw a permissions error.
103
- throw ErrnoError.With('EPERM', newPath, 'rename');
104
- }
105
- }
106
- newDirList[newName] = nodeId;
107
- // Commit the two changed directory listings.
108
- try {
148
+ newDirList[newName] = nodeId;
149
+ // Commit the two changed directory listings.
109
150
  await tx.set(oldDirNode.ino, encodeDirListing(oldDirList));
110
151
  await tx.set(newDirNode.ino, encodeDirListing(newDirList));
152
+ await tx.commit();
111
153
  }
112
- catch (e) {
113
- await tx.abort();
114
- throw e;
154
+ catch (e_1) {
155
+ env_1.error = e_1;
156
+ env_1.hasError = true;
157
+ }
158
+ finally {
159
+ const result_1 = __disposeResources(env_1);
160
+ if (result_1)
161
+ await result_1;
115
162
  }
116
- await tx.commit();
117
163
  }
118
164
  renameSync(oldPath, newPath, cred) {
119
- const tx = this.store.transaction(), oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
120
- // Remove oldPath from parent's directory listing.
121
- oldDirNode = this.findINodeSync(tx, oldParent), oldDirList = this.getDirListingSync(tx, oldDirNode, oldParent);
122
- if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
123
- throw ErrnoError.With('EACCES', oldPath, 'rename');
124
- }
125
- if (!oldDirList[oldName]) {
126
- throw ErrnoError.With('ENOENT', oldPath, 'rename');
127
- }
128
- const ino = oldDirList[oldName];
129
- delete oldDirList[oldName];
130
- // Invariant: Can't move a folder inside itself.
131
- // This funny little hack ensures that the check passes only if oldPath
132
- // is a subpath of newParent. We append '/' to avoid matching folders that
133
- // are a substring of the bottom-most folder in the path.
134
- if ((newParent + '/').indexOf(oldPath + '/') == 0) {
135
- throw new ErrnoError(Errno.EBUSY, oldParent);
136
- }
137
- // Add newPath to parent's directory listing.
138
- let newDirNode, newDirList;
139
- if (newParent === oldParent) {
140
- // Prevent us from re-grabbing the same directory listing, which still
141
- // contains oldName.
142
- newDirNode = oldDirNode;
143
- newDirList = oldDirList;
144
- }
145
- else {
146
- newDirNode = this.findINodeSync(tx, newParent);
147
- newDirList = this.getDirListingSync(tx, newDirNode, newParent);
148
- }
149
- if (newDirList[newName]) {
150
- // If it's a file, delete it.
151
- const newNameNode = this.getINodeSync(tx, newDirList[newName], newPath);
152
- if (newNameNode.toStats().isFile()) {
153
- try {
165
+ const env_2 = { stack: [], error: void 0, hasError: false };
166
+ try {
167
+ const tx = __addDisposableResource(env_2, this.store.transaction(), false);
168
+ const oldParent = dirname(oldPath), oldName = basename(oldPath), newParent = dirname(newPath), newName = basename(newPath),
169
+ // Remove oldPath from parent's directory listing.
170
+ oldDirNode = this.findINodeSync(tx, oldParent), oldDirList = this.getDirListingSync(tx, oldDirNode, oldParent);
171
+ if (!oldDirNode.toStats().hasAccess(W_OK, cred)) {
172
+ throw ErrnoError.With('EACCES', oldPath, 'rename');
173
+ }
174
+ if (!oldDirList[oldName]) {
175
+ throw ErrnoError.With('ENOENT', oldPath, 'rename');
176
+ }
177
+ const ino = oldDirList[oldName];
178
+ delete oldDirList[oldName];
179
+ // Invariant: Can't move a folder inside itself.
180
+ // This funny little hack ensures that the check passes only if oldPath
181
+ // is a subpath of newParent. We append '/' to avoid matching folders that
182
+ // are a substring of the bottom-most folder in the path.
183
+ if ((newParent + '/').indexOf(oldPath + '/') == 0) {
184
+ throw new ErrnoError(Errno.EBUSY, oldParent);
185
+ }
186
+ // Add newPath to parent's directory listing.
187
+ let newDirNode, newDirList;
188
+ if (newParent === oldParent) {
189
+ // Prevent us from re-grabbing the same directory listing, which still
190
+ // contains oldName.
191
+ newDirNode = oldDirNode;
192
+ newDirList = oldDirList;
193
+ }
194
+ else {
195
+ newDirNode = this.findINodeSync(tx, newParent);
196
+ newDirList = this.getDirListingSync(tx, newDirNode, newParent);
197
+ }
198
+ if (newDirList[newName]) {
199
+ // If it's a file, delete it.
200
+ const newNameNode = this.getINodeSync(tx, newDirList[newName], newPath);
201
+ if (newNameNode.toStats().isFile()) {
154
202
  tx.removeSync(newNameNode.ino);
155
203
  tx.removeSync(newDirList[newName]);
156
204
  }
157
- catch (e) {
158
- tx.abortSync();
159
- throw e;
205
+ else {
206
+ // If it's a directory, throw a permissions error.
207
+ throw ErrnoError.With('EPERM', newPath, 'rename');
160
208
  }
161
209
  }
162
- else {
163
- // If it's a directory, throw a permissions error.
164
- throw ErrnoError.With('EPERM', newPath, 'rename');
165
- }
166
- }
167
- newDirList[newName] = ino;
168
- // Commit the two changed directory listings.
169
- try {
210
+ newDirList[newName] = ino;
211
+ // Commit the two changed directory listings.
170
212
  tx.setSync(oldDirNode.ino, encodeDirListing(oldDirList));
171
213
  tx.setSync(newDirNode.ino, encodeDirListing(newDirList));
214
+ tx.commitSync();
215
+ }
216
+ catch (e_2) {
217
+ env_2.error = e_2;
218
+ env_2.hasError = true;
172
219
  }
173
- catch (e) {
174
- tx.abortSync();
175
- throw e;
220
+ finally {
221
+ __disposeResources(env_2);
176
222
  }
177
- tx.commitSync();
178
223
  }
179
224
  async stat(path, cred) {
180
- const tx = this.store.transaction();
181
- const inode = await this.findINode(tx, path);
182
- if (!inode) {
183
- throw ErrnoError.With('ENOENT', path, 'stat');
225
+ const env_3 = { stack: [], error: void 0, hasError: false };
226
+ try {
227
+ const tx = __addDisposableResource(env_3, this.store.transaction(), true);
228
+ const inode = await this.findINode(tx, path);
229
+ if (!inode) {
230
+ throw ErrnoError.With('ENOENT', path, 'stat');
231
+ }
232
+ const stats = inode.toStats();
233
+ if (!stats.hasAccess(R_OK, cred)) {
234
+ throw ErrnoError.With('EACCES', path, 'stat');
235
+ }
236
+ return stats;
237
+ }
238
+ catch (e_3) {
239
+ env_3.error = e_3;
240
+ env_3.hasError = true;
184
241
  }
185
- const stats = inode.toStats();
186
- if (!stats.hasAccess(R_OK, cred)) {
187
- throw ErrnoError.With('EACCES', path, 'stat');
242
+ finally {
243
+ const result_2 = __disposeResources(env_3);
244
+ if (result_2)
245
+ await result_2;
188
246
  }
189
- return stats;
190
247
  }
191
248
  statSync(path, cred) {
192
- // Get the inode to the item, convert it into a Stats object.
193
- const stats = this.findINodeSync(this.store.transaction(), path).toStats();
194
- if (!stats.hasAccess(R_OK, cred)) {
195
- throw ErrnoError.With('EACCES', path, 'stat');
249
+ const env_4 = { stack: [], error: void 0, hasError: false };
250
+ try {
251
+ const tx = __addDisposableResource(env_4, this.store.transaction(), false);
252
+ // Get the inode to the item, convert it into a Stats object.
253
+ const stats = this.findINodeSync(tx, path).toStats();
254
+ if (!stats.hasAccess(R_OK, cred)) {
255
+ throw ErrnoError.With('EACCES', path, 'stat');
256
+ }
257
+ return stats;
258
+ }
259
+ catch (e_4) {
260
+ env_4.error = e_4;
261
+ env_4.hasError = true;
262
+ }
263
+ finally {
264
+ __disposeResources(env_4);
196
265
  }
197
- return stats;
198
266
  }
199
267
  async createFile(path, flag, mode, cred) {
200
- const data = new Uint8Array(0);
201
- const file = await this.commitNew(this.store.transaction(), path, S_IFREG, mode, cred, data);
202
- return new PreloadFile(this, path, flag, file.toStats(), data);
268
+ const node = await this.commitNew(path, S_IFREG, mode, cred, new Uint8Array(0));
269
+ return new PreloadFile(this, path, flag, node.toStats(), new Uint8Array(0));
203
270
  }
204
271
  createFileSync(path, flag, mode, cred) {
205
272
  this.commitNewSync(path, S_IFREG, mode, cred);
206
273
  return this.openFileSync(path, flag, cred);
207
274
  }
208
275
  async openFile(path, flag, cred) {
209
- const tx = this.store.transaction(), node = await this.findINode(tx, path), data = await tx.get(node.ino);
210
- if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
211
- throw ErrnoError.With('EACCES', path, 'openFile');
276
+ const env_5 = { stack: [], error: void 0, hasError: false };
277
+ try {
278
+ const tx = __addDisposableResource(env_5, this.store.transaction(), true);
279
+ const node = await this.findINode(tx, path), data = await tx.get(node.ino);
280
+ if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
281
+ throw ErrnoError.With('EACCES', path, 'openFile');
282
+ }
283
+ if (!data) {
284
+ throw ErrnoError.With('ENOENT', path, 'openFile');
285
+ }
286
+ return new PreloadFile(this, path, flag, node.toStats(), data);
212
287
  }
213
- if (!data) {
214
- throw ErrnoError.With('ENOENT', path, 'openFile');
288
+ catch (e_5) {
289
+ env_5.error = e_5;
290
+ env_5.hasError = true;
291
+ }
292
+ finally {
293
+ const result_3 = __disposeResources(env_5);
294
+ if (result_3)
295
+ await result_3;
215
296
  }
216
- return new PreloadFile(this, path, flag, node.toStats(), data);
217
297
  }
218
298
  openFileSync(path, flag, cred) {
219
- const tx = this.store.transaction(), node = this.findINodeSync(tx, path), data = tx.getSync(node.ino);
220
- if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
221
- throw ErrnoError.With('EACCES', path, 'openFile');
299
+ const env_6 = { stack: [], error: void 0, hasError: false };
300
+ try {
301
+ const tx = __addDisposableResource(env_6, this.store.transaction(), false);
302
+ const node = this.findINodeSync(tx, path), data = tx.getSync(node.ino);
303
+ if (!node.toStats().hasAccess(flagToMode(flag), cred)) {
304
+ throw ErrnoError.With('EACCES', path, 'openFile');
305
+ }
306
+ if (!data) {
307
+ throw ErrnoError.With('ENOENT', path, 'openFile');
308
+ }
309
+ return new PreloadFile(this, path, flag, node.toStats(), data);
222
310
  }
223
- if (!data) {
224
- throw ErrnoError.With('ENOENT', path, 'openFile');
311
+ catch (e_6) {
312
+ env_6.error = e_6;
313
+ env_6.hasError = true;
314
+ }
315
+ finally {
316
+ __disposeResources(env_6);
225
317
  }
226
- return new PreloadFile(this, path, flag, node.toStats(), data);
227
318
  }
228
319
  async unlink(path, cred) {
229
320
  return this.remove(path, false, cred);
@@ -249,155 +340,220 @@ export class StoreFS extends FileSystem {
249
340
  }
250
341
  }
251
342
  async mkdir(path, mode, cred) {
252
- const tx = this.store.transaction(), data = encode('{}');
253
- await this.commitNew(tx, path, S_IFDIR, mode, cred, data);
343
+ await this.commitNew(path, S_IFDIR, mode, cred, encode('{}'));
254
344
  }
255
345
  mkdirSync(path, mode, cred) {
256
346
  this.commitNewSync(path, S_IFDIR, mode, cred, encode('{}'));
257
347
  }
258
348
  async readdir(path, cred) {
259
- const tx = this.store.transaction();
260
- const node = await this.findINode(tx, path);
261
- if (!node.toStats().hasAccess(R_OK, cred)) {
262
- throw ErrnoError.With('EACCES', path, 'readdur');
349
+ const env_7 = { stack: [], error: void 0, hasError: false };
350
+ try {
351
+ const tx = __addDisposableResource(env_7, this.store.transaction(), true);
352
+ const node = await this.findINode(tx, path);
353
+ if (!node.toStats().hasAccess(R_OK, cred)) {
354
+ throw ErrnoError.With('EACCES', path, 'readdur');
355
+ }
356
+ return Object.keys(await this.getDirListing(tx, node, path));
357
+ }
358
+ catch (e_7) {
359
+ env_7.error = e_7;
360
+ env_7.hasError = true;
361
+ }
362
+ finally {
363
+ const result_4 = __disposeResources(env_7);
364
+ if (result_4)
365
+ await result_4;
263
366
  }
264
- return Object.keys(await this.getDirListing(tx, node, path));
265
367
  }
266
368
  readdirSync(path, cred) {
267
- const tx = this.store.transaction();
268
- const node = this.findINodeSync(tx, path);
269
- if (!node.toStats().hasAccess(R_OK, cred)) {
270
- throw ErrnoError.With('EACCES', path, 'readdir');
369
+ const env_8 = { stack: [], error: void 0, hasError: false };
370
+ try {
371
+ const tx = __addDisposableResource(env_8, this.store.transaction(), false);
372
+ const node = this.findINodeSync(tx, path);
373
+ if (!node.toStats().hasAccess(R_OK, cred)) {
374
+ throw ErrnoError.With('EACCES', path, 'readdir');
375
+ }
376
+ return Object.keys(this.getDirListingSync(tx, node, path));
377
+ }
378
+ catch (e_8) {
379
+ env_8.error = e_8;
380
+ env_8.hasError = true;
381
+ }
382
+ finally {
383
+ __disposeResources(env_8);
271
384
  }
272
- return Object.keys(this.getDirListingSync(tx, node, path));
273
385
  }
274
386
  /**
275
387
  * Updated the inode and data node at the given path
276
388
  * @todo Ensure mtime updates properly, and use that to determine if a data update is required.
277
389
  */
278
390
  async sync(path, data, stats) {
279
- const tx = this.store.transaction(),
280
- // We use _findInode because we actually need the INode id.
281
- fileInodeId = await this._findINode(tx, dirname(path), basename(path)), fileInode = await this.getINode(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
391
+ const env_9 = { stack: [], error: void 0, hasError: false };
282
392
  try {
393
+ const tx = __addDisposableResource(env_9, this.store.transaction(), true);
394
+ // We use _findInode because we actually need the INode id.
395
+ const fileInodeId = await this._findINode(tx, dirname(path), basename(path)), fileInode = await this.getINode(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
283
396
  // Sync data.
284
397
  await tx.set(fileInode.ino, data);
285
398
  // Sync metadata.
286
399
  if (inodeChanged) {
287
400
  await tx.set(fileInodeId, fileInode.data);
288
401
  }
402
+ await tx.commit();
289
403
  }
290
- catch (e) {
291
- await tx.abort();
292
- throw e;
404
+ catch (e_9) {
405
+ env_9.error = e_9;
406
+ env_9.hasError = true;
407
+ }
408
+ finally {
409
+ const result_5 = __disposeResources(env_9);
410
+ if (result_5)
411
+ await result_5;
293
412
  }
294
- await tx.commit();
295
413
  }
296
414
  /**
297
415
  * Updated the inode and data node at the given path
298
416
  * @todo Ensure mtime updates properly, and use that to determine if a data update is required.
299
417
  */
300
418
  syncSync(path, data, stats) {
301
- const tx = this.store.transaction(),
302
- // We use _findInode because we actually need the INode id.
303
- fileInodeId = this._findINodeSync(tx, dirname(path), basename(path)), fileInode = this.getINodeSync(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
419
+ const env_10 = { stack: [], error: void 0, hasError: false };
304
420
  try {
421
+ const tx = __addDisposableResource(env_10, this.store.transaction(), false);
422
+ // We use _findInode because we actually need the INode id.
423
+ const fileInodeId = this._findINodeSync(tx, dirname(path), basename(path)), fileInode = this.getINodeSync(tx, fileInodeId, path), inodeChanged = fileInode.update(stats);
305
424
  // Sync data.
306
425
  tx.setSync(fileInode.ino, data);
307
426
  // Sync metadata.
308
427
  if (inodeChanged) {
309
428
  tx.setSync(fileInodeId, fileInode.data);
310
429
  }
430
+ tx.commitSync();
431
+ }
432
+ catch (e_10) {
433
+ env_10.error = e_10;
434
+ env_10.hasError = true;
311
435
  }
312
- catch (e) {
313
- tx.abortSync();
314
- throw e;
436
+ finally {
437
+ __disposeResources(env_10);
315
438
  }
316
- tx.commitSync();
317
439
  }
318
440
  async link(existing, newpath, cred) {
319
- const tx = this.store.transaction(), existingDir = dirname(existing), existingDirNode = await this.findINode(tx, existingDir);
320
- if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
321
- throw ErrnoError.With('EACCES', existingDir, 'link');
322
- }
323
- const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);
324
- if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
325
- throw ErrnoError.With('EACCES', newDir, 'link');
326
- }
327
- const ino = await this._findINode(tx, existingDir, basename(existing));
328
- const node = await this.getINode(tx, ino, existing);
329
- if (!node.toStats().hasAccess(W_OK, cred)) {
330
- throw ErrnoError.With('EACCES', newpath, 'link');
331
- }
332
- node.nlink++;
333
- newListing[basename(newpath)] = ino;
441
+ const env_11 = { stack: [], error: void 0, hasError: false };
334
442
  try {
443
+ const tx = __addDisposableResource(env_11, this.store.transaction(), true);
444
+ const existingDir = dirname(existing), existingDirNode = await this.findINode(tx, existingDir);
445
+ if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
446
+ throw ErrnoError.With('EACCES', existingDir, 'link');
447
+ }
448
+ const newDir = dirname(newpath), newDirNode = await this.findINode(tx, newDir), newListing = await this.getDirListing(tx, newDirNode, newDir);
449
+ if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
450
+ throw ErrnoError.With('EACCES', newDir, 'link');
451
+ }
452
+ const ino = await this._findINode(tx, existingDir, basename(existing));
453
+ const node = await this.getINode(tx, ino, existing);
454
+ if (!node.toStats().hasAccess(W_OK, cred)) {
455
+ throw ErrnoError.With('EACCES', newpath, 'link');
456
+ }
457
+ node.nlink++;
458
+ newListing[basename(newpath)] = ino;
335
459
  tx.setSync(ino, node.data);
336
460
  tx.setSync(newDirNode.ino, encodeDirListing(newListing));
461
+ tx.commitSync();
337
462
  }
338
- catch (e) {
339
- tx.abortSync();
340
- throw e;
463
+ catch (e_11) {
464
+ env_11.error = e_11;
465
+ env_11.hasError = true;
466
+ }
467
+ finally {
468
+ const result_6 = __disposeResources(env_11);
469
+ if (result_6)
470
+ await result_6;
341
471
  }
342
- tx.commitSync();
343
472
  }
344
473
  linkSync(existing, newpath, cred) {
345
- const tx = this.store.transaction(), existingDir = dirname(existing), existingDirNode = this.findINodeSync(tx, existingDir);
346
- if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
347
- throw ErrnoError.With('EACCES', existingDir, 'link');
348
- }
349
- const newDir = dirname(newpath), newDirNode = this.findINodeSync(tx, newDir), newListing = this.getDirListingSync(tx, newDirNode, newDir);
350
- if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
351
- throw ErrnoError.With('EACCES', newDir, 'link');
352
- }
353
- const ino = this._findINodeSync(tx, existingDir, basename(existing));
354
- const node = this.getINodeSync(tx, ino, existing);
355
- if (!node.toStats().hasAccess(W_OK, cred)) {
356
- throw ErrnoError.With('EACCES', newpath, 'link');
357
- }
358
- node.nlink++;
359
- newListing[basename(newpath)] = ino;
474
+ const env_12 = { stack: [], error: void 0, hasError: false };
360
475
  try {
476
+ const tx = __addDisposableResource(env_12, this.store.transaction(), false);
477
+ const existingDir = dirname(existing), existingDirNode = this.findINodeSync(tx, existingDir);
478
+ if (!existingDirNode.toStats().hasAccess(R_OK, cred)) {
479
+ throw ErrnoError.With('EACCES', existingDir, 'link');
480
+ }
481
+ const newDir = dirname(newpath), newDirNode = this.findINodeSync(tx, newDir), newListing = this.getDirListingSync(tx, newDirNode, newDir);
482
+ if (!newDirNode.toStats().hasAccess(W_OK, cred)) {
483
+ throw ErrnoError.With('EACCES', newDir, 'link');
484
+ }
485
+ const ino = this._findINodeSync(tx, existingDir, basename(existing));
486
+ const node = this.getINodeSync(tx, ino, existing);
487
+ if (!node.toStats().hasAccess(W_OK, cred)) {
488
+ throw ErrnoError.With('EACCES', newpath, 'link');
489
+ }
490
+ node.nlink++;
491
+ newListing[basename(newpath)] = ino;
361
492
  tx.setSync(ino, node.data);
362
493
  tx.setSync(newDirNode.ino, encodeDirListing(newListing));
494
+ tx.commitSync();
495
+ }
496
+ catch (e_12) {
497
+ env_12.error = e_12;
498
+ env_12.hasError = true;
363
499
  }
364
- catch (e) {
365
- tx.abortSync();
366
- throw e;
500
+ finally {
501
+ __disposeResources(env_12);
367
502
  }
368
- tx.commitSync();
369
503
  }
370
504
  /**
371
505
  * Checks if the root directory exists. Creates it if it doesn't.
372
506
  */
373
507
  async checkRoot() {
374
- const tx = this.store.transaction();
375
- if (await tx.get(rootIno)) {
376
- return;
508
+ const env_13 = { stack: [], error: void 0, hasError: false };
509
+ try {
510
+ const tx = __addDisposableResource(env_13, this.store.transaction(), true);
511
+ if (await tx.get(rootIno)) {
512
+ return;
513
+ }
514
+ // Create new inode. o777, owned by root:root
515
+ const inode = new Inode();
516
+ inode.mode = 0o777 | S_IFDIR;
517
+ // If the root doesn't exist, the first random ID shouldn't exist either.
518
+ await tx.set(inode.ino, encode('{}'));
519
+ await tx.set(rootIno, inode.data);
520
+ await tx.commit();
521
+ }
522
+ catch (e_13) {
523
+ env_13.error = e_13;
524
+ env_13.hasError = true;
525
+ }
526
+ finally {
527
+ const result_7 = __disposeResources(env_13);
528
+ if (result_7)
529
+ await result_7;
377
530
  }
378
- // Create new inode. o777, owned by root:root
379
- const inode = new Inode();
380
- inode.mode = 0o777 | S_IFDIR;
381
- // If the root doesn't exist, the first random ID shouldn't exist either.
382
- await tx.set(inode.ino, encode('{}'));
383
- await tx.set(rootIno, inode.data);
384
- await tx.commit();
385
531
  }
386
532
  /**
387
533
  * Checks if the root directory exists. Creates it if it doesn't.
388
534
  */
389
535
  checkRootSync() {
390
- const tx = this.store.transaction();
391
- if (tx.getSync(rootIno)) {
392
- return;
536
+ const env_14 = { stack: [], error: void 0, hasError: false };
537
+ try {
538
+ const tx = __addDisposableResource(env_14, this.store.transaction(), false);
539
+ if (tx.getSync(rootIno)) {
540
+ return;
541
+ }
542
+ // Create new inode, mode o777, owned by root:root
543
+ const inode = new Inode();
544
+ inode.mode = 0o777 | S_IFDIR;
545
+ // If the root doesn't exist, the first random ID shouldn't exist either.
546
+ tx.setSync(inode.ino, encode('{}'));
547
+ tx.setSync(rootIno, inode.data);
548
+ tx.commitSync();
549
+ }
550
+ catch (e_14) {
551
+ env_14.error = e_14;
552
+ env_14.hasError = true;
553
+ }
554
+ finally {
555
+ __disposeResources(env_14);
393
556
  }
394
- // Create new inode, mode o777, owned by root:root
395
- const inode = new Inode();
396
- inode.mode = 0o777 | S_IFDIR;
397
- // If the root doesn't exist, the first random ID shouldn't exist either.
398
- tx.setSync(inode.ino, encode('{}'));
399
- tx.setSync(rootIno, inode.data);
400
- tx.commitSync();
401
557
  }
402
558
  /**
403
559
  * Helper function for findINode.
@@ -563,27 +719,29 @@ export class StoreFS extends FileSystem {
563
719
  * @param cred The UID/GID to create the file with
564
720
  * @param data The data to store at the file's data node.
565
721
  */
566
- async commitNew(tx, path, type, mode, cred, data) {
567
- const parentPath = dirname(path), parent = await this.findINode(tx, parentPath);
568
- //Check that the creater has correct access
569
- if (!parent.toStats().hasAccess(W_OK, cred)) {
570
- throw ErrnoError.With('EACCES', path, 'commitNewFile');
571
- }
572
- const fname = basename(path), listing = await this.getDirListing(tx, parent, parentPath);
573
- /*
574
- The root always exists.
575
- If we don't check this prior to taking steps below,
576
- we will create a file with name '' in root should path == '/'.
577
- */
578
- if (path === '/') {
579
- throw ErrnoError.With('EEXIST', path, 'commitNewFile');
580
- }
581
- // Check if file already exists.
582
- if (listing[fname]) {
583
- await tx.abort();
584
- throw ErrnoError.With('EEXIST', path, 'commitNewFile');
585
- }
722
+ async commitNew(path, type, mode, cred, data) {
723
+ const env_15 = { stack: [], error: void 0, hasError: false };
586
724
  try {
725
+ const tx = __addDisposableResource(env_15, this.store.transaction(), true);
726
+ const parentPath = dirname(path), parent = await this.findINode(tx, parentPath);
727
+ //Check that the creater has correct access
728
+ if (!parent.toStats().hasAccess(W_OK, cred)) {
729
+ throw ErrnoError.With('EACCES', path, 'commitNewFile');
730
+ }
731
+ const fname = basename(path), listing = await this.getDirListing(tx, parent, parentPath);
732
+ /*
733
+ The root always exists.
734
+ If we don't check this prior to taking steps below,
735
+ we will create a file with name '' in root should path == '/'.
736
+ */
737
+ if (path === '/') {
738
+ throw ErrnoError.With('EEXIST', path, 'commitNewFile');
739
+ }
740
+ // Check if file already exists.
741
+ if (listing[fname]) {
742
+ await tx.abort();
743
+ throw ErrnoError.With('EEXIST', path, 'commitNewFile');
744
+ }
587
745
  // Commit data.
588
746
  const inode = new Inode();
589
747
  inode.ino = await this.addNew(tx, data, path);
@@ -597,9 +755,14 @@ export class StoreFS extends FileSystem {
597
755
  await tx.commit();
598
756
  return inode;
599
757
  }
600
- catch (e) {
601
- await tx.abort();
602
- throw e;
758
+ catch (e_15) {
759
+ env_15.error = e_15;
760
+ env_15.hasError = true;
761
+ }
762
+ finally {
763
+ const result_8 = __disposeResources(env_15);
764
+ if (result_8)
765
+ await result_8;
603
766
  }
604
767
  }
605
768
  /**
@@ -612,27 +775,29 @@ export class StoreFS extends FileSystem {
612
775
  * @return The Inode for the new file.
613
776
  */
614
777
  commitNewSync(path, type, mode, cred, data = new Uint8Array()) {
615
- const tx = this.store.transaction(), parentPath = dirname(path), parent = this.findINodeSync(tx, parentPath);
616
- //Check that the creater has correct access
617
- if (!parent.toStats().hasAccess(W_OK, cred)) {
618
- throw ErrnoError.With('EACCES', path, 'commitNewFile');
619
- }
620
- const fname = basename(path), listing = this.getDirListingSync(tx, parent, parentPath);
621
- /*
622
- The root always exists.
623
- If we don't check this prior to taking steps below,
624
- we will create a file with name '' in root should p == '/'.
625
- */
626
- if (path === '/') {
627
- throw ErrnoError.With('EEXIST', path, 'commitNewFile');
628
- }
629
- // Check if file already exists.
630
- if (listing[fname]) {
631
- throw ErrnoError.With('EEXIST', path, 'commitNewFile');
632
- }
633
- const node = new Inode();
778
+ const env_16 = { stack: [], error: void 0, hasError: false };
634
779
  try {
780
+ const tx = __addDisposableResource(env_16, this.store.transaction(), false);
781
+ const parentPath = dirname(path), parent = this.findINodeSync(tx, parentPath);
782
+ //Check that the creater has correct access
783
+ if (!parent.toStats().hasAccess(W_OK, cred)) {
784
+ throw ErrnoError.With('EACCES', path, 'commitNewFile');
785
+ }
786
+ const fname = basename(path), listing = this.getDirListingSync(tx, parent, parentPath);
787
+ /*
788
+ The root always exists.
789
+ If we don't check this prior to taking steps below,
790
+ we will create a file with name '' in root should p == '/'.
791
+ */
792
+ if (path === '/') {
793
+ throw ErrnoError.With('EEXIST', path, 'commitNewFile');
794
+ }
795
+ // Check if file already exists.
796
+ if (listing[fname]) {
797
+ throw ErrnoError.With('EEXIST', path, 'commitNewFile');
798
+ }
635
799
  // Commit data.
800
+ const node = new Inode();
636
801
  node.ino = this.addNewSync(tx, data, path);
637
802
  node.size = data.length;
638
803
  node.mode = mode | type;
@@ -641,13 +806,16 @@ export class StoreFS extends FileSystem {
641
806
  // Update and commit parent directory listing.
642
807
  listing[fname] = this.addNewSync(tx, node.data, path);
643
808
  tx.setSync(parent.ino, encodeDirListing(listing));
809
+ tx.commitSync();
810
+ return node;
811
+ }
812
+ catch (e_16) {
813
+ env_16.error = e_16;
814
+ env_16.hasError = true;
644
815
  }
645
- catch (e) {
646
- tx.abortSync();
647
- throw e;
816
+ finally {
817
+ __disposeResources(env_16);
648
818
  }
649
- tx.commitSync();
650
- return node;
651
819
  }
652
820
  /**
653
821
  * Remove all traces of the given path from the file system.
@@ -656,38 +824,45 @@ export class StoreFS extends FileSystem {
656
824
  * @todo Update mtime.
657
825
  */
658
826
  async remove(path, isDir, cred) {
659
- const tx = this.store.transaction(), parent = dirname(path), parentNode = await this.findINode(tx, parent), listing = await this.getDirListing(tx, parentNode, parent), fileName = basename(path);
660
- if (!listing[fileName]) {
661
- throw ErrnoError.With('ENOENT', path, 'removeEntry');
662
- }
663
- const fileIno = listing[fileName];
664
- // Get file inode.
665
- const fileNode = await this.getINode(tx, fileIno, path);
666
- if (!fileNode.toStats().hasAccess(W_OK, cred)) {
667
- throw ErrnoError.With('EACCES', path, 'removeEntry');
668
- }
669
- // Remove from directory listing of parent.
670
- delete listing[fileName];
671
- if (!isDir && fileNode.toStats().isDirectory()) {
672
- throw ErrnoError.With('EISDIR', path, 'removeEntry');
673
- }
674
- if (isDir && !fileNode.toStats().isDirectory()) {
675
- throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
676
- }
827
+ const env_17 = { stack: [], error: void 0, hasError: false };
677
828
  try {
829
+ const tx = __addDisposableResource(env_17, this.store.transaction(), true);
830
+ const parent = dirname(path), parentNode = await this.findINode(tx, parent), listing = await this.getDirListing(tx, parentNode, parent), fileName = basename(path);
831
+ if (!listing[fileName]) {
832
+ throw ErrnoError.With('ENOENT', path, 'removeEntry');
833
+ }
834
+ const fileIno = listing[fileName];
835
+ // Get file inode.
836
+ const fileNode = await this.getINode(tx, fileIno, path);
837
+ if (!fileNode.toStats().hasAccess(W_OK, cred)) {
838
+ throw ErrnoError.With('EACCES', path, 'removeEntry');
839
+ }
840
+ // Remove from directory listing of parent.
841
+ delete listing[fileName];
842
+ if (!isDir && fileNode.toStats().isDirectory()) {
843
+ throw ErrnoError.With('EISDIR', path, 'removeEntry');
844
+ }
845
+ if (isDir && !fileNode.toStats().isDirectory()) {
846
+ throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
847
+ }
678
848
  await tx.set(parentNode.ino, encodeDirListing(listing));
679
849
  if (--fileNode.nlink < 1) {
680
850
  // remove file
681
851
  await tx.remove(fileNode.ino);
682
852
  await tx.remove(fileIno);
683
853
  }
854
+ // Success.
855
+ await tx.commit();
856
+ }
857
+ catch (e_17) {
858
+ env_17.error = e_17;
859
+ env_17.hasError = true;
684
860
  }
685
- catch (e) {
686
- await tx.abort();
687
- throw e;
861
+ finally {
862
+ const result_9 = __disposeResources(env_17);
863
+ if (result_9)
864
+ await result_9;
688
865
  }
689
- // Success.
690
- await tx.commit();
691
866
  }
692
867
  /**
693
868
  * Remove all traces of the given path from the file system.
@@ -696,24 +871,26 @@ export class StoreFS extends FileSystem {
696
871
  * @todo Update mtime.
697
872
  */
698
873
  removeSync(path, isDir, cred) {
699
- const tx = this.store.transaction(), parent = dirname(path), parentNode = this.findINodeSync(tx, parent), listing = this.getDirListingSync(tx, parentNode, parent), fileName = basename(path), fileIno = listing[fileName];
700
- if (!fileIno) {
701
- throw ErrnoError.With('ENOENT', path, 'removeEntry');
702
- }
703
- // Get file inode.
704
- const fileNode = this.getINodeSync(tx, fileIno, path);
705
- if (!fileNode.toStats().hasAccess(W_OK, cred)) {
706
- throw ErrnoError.With('EACCES', path, 'removeEntry');
707
- }
708
- // Remove from directory listing of parent.
709
- delete listing[fileName];
710
- if (!isDir && fileNode.toStats().isDirectory()) {
711
- throw ErrnoError.With('EISDIR', path, 'removeEntry');
712
- }
713
- if (isDir && !fileNode.toStats().isDirectory()) {
714
- throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
715
- }
874
+ const env_18 = { stack: [], error: void 0, hasError: false };
716
875
  try {
876
+ const tx = __addDisposableResource(env_18, this.store.transaction(), false);
877
+ const parent = dirname(path), parentNode = this.findINodeSync(tx, parent), listing = this.getDirListingSync(tx, parentNode, parent), fileName = basename(path), fileIno = listing[fileName];
878
+ if (!fileIno) {
879
+ throw ErrnoError.With('ENOENT', path, 'removeEntry');
880
+ }
881
+ // Get file inode.
882
+ const fileNode = this.getINodeSync(tx, fileIno, path);
883
+ if (!fileNode.toStats().hasAccess(W_OK, cred)) {
884
+ throw ErrnoError.With('EACCES', path, 'removeEntry');
885
+ }
886
+ // Remove from directory listing of parent.
887
+ delete listing[fileName];
888
+ if (!isDir && fileNode.toStats().isDirectory()) {
889
+ throw ErrnoError.With('EISDIR', path, 'removeEntry');
890
+ }
891
+ if (isDir && !fileNode.toStats().isDirectory()) {
892
+ throw ErrnoError.With('ENOTDIR', path, 'removeEntry');
893
+ }
717
894
  // Update directory listing.
718
895
  tx.setSync(parentNode.ino, encodeDirListing(listing));
719
896
  if (--fileNode.nlink < 1) {
@@ -721,12 +898,15 @@ export class StoreFS extends FileSystem {
721
898
  tx.removeSync(fileNode.ino);
722
899
  tx.removeSync(fileIno);
723
900
  }
901
+ // Success.
902
+ tx.commitSync();
903
+ }
904
+ catch (e_18) {
905
+ env_18.error = e_18;
906
+ env_18.hasError = true;
724
907
  }
725
- catch (e) {
726
- tx.abortSync();
727
- throw e;
908
+ finally {
909
+ __disposeResources(env_18);
728
910
  }
729
- // Success.
730
- tx.commitSync();
731
911
  }
732
912
  }