@zenfs/core 1.11.4 → 2.1.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.
- package/dist/backends/backend.d.ts +19 -15
- package/dist/backends/backend.js +36 -19
- package/dist/backends/cow.d.ts +20 -30
- package/dist/backends/cow.js +83 -192
- package/dist/backends/fetch.d.ts +1 -0
- package/dist/backends/fetch.js +30 -30
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/memory.d.ts +5 -7
- package/dist/backends/memory.js +2 -3
- package/dist/backends/passthrough.d.ts +19 -23
- package/dist/backends/passthrough.js +98 -288
- package/dist/backends/port.d.ts +220 -0
- package/dist/backends/port.js +328 -0
- package/dist/backends/single_buffer.d.ts +59 -47
- package/dist/backends/single_buffer.js +468 -219
- package/dist/backends/store/fs.d.ts +25 -35
- package/dist/backends/store/fs.js +276 -315
- package/dist/backends/store/store.d.ts +10 -15
- package/dist/backends/store/store.js +11 -10
- package/dist/config.d.ts +3 -12
- package/dist/config.js +17 -19
- package/dist/context.d.ts +8 -21
- package/dist/context.js +33 -10
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/contexts.d.ts +63 -0
- package/dist/internal/contexts.js +15 -0
- package/dist/internal/credentials.d.ts +2 -11
- package/dist/internal/credentials.js +0 -19
- package/dist/internal/devices.d.ts +18 -80
- package/dist/internal/devices.js +103 -316
- package/dist/internal/error.d.ts +9 -204
- package/dist/internal/error.js +19 -288
- package/dist/internal/file_index.d.ts +1 -1
- package/dist/internal/file_index.js +11 -11
- package/dist/internal/filesystem.d.ts +51 -94
- package/dist/internal/filesystem.js +21 -20
- package/dist/internal/index.d.ts +1 -2
- package/dist/internal/index.js +1 -2
- package/dist/internal/index_fs.d.ts +12 -30
- package/dist/internal/index_fs.js +37 -69
- package/dist/internal/inode.d.ts +140 -24
- package/dist/internal/inode.js +515 -66
- package/dist/mixins/async.js +52 -112
- package/dist/mixins/mutexed.d.ts +19 -18
- package/dist/mixins/mutexed.js +62 -64
- package/dist/mixins/readonly.d.ts +7 -6
- package/dist/mixins/readonly.js +24 -18
- package/dist/mixins/sync.js +8 -8
- package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
- package/dist/{vfs/path.js → path.js} +6 -9
- package/dist/polyfills.js +1 -1
- package/dist/readline.d.ts +134 -0
- package/dist/readline.js +623 -0
- package/dist/utils.d.ts +9 -37
- package/dist/utils.js +17 -85
- package/dist/vfs/acl.d.ts +42 -0
- package/dist/vfs/acl.js +268 -0
- package/dist/vfs/async.d.ts +9 -23
- package/dist/vfs/async.js +25 -27
- package/dist/vfs/config.d.ts +6 -18
- package/dist/vfs/config.js +8 -18
- package/dist/vfs/dir.d.ts +3 -3
- package/dist/vfs/dir.js +12 -12
- package/dist/vfs/file.d.ts +106 -0
- package/dist/vfs/file.js +244 -0
- package/dist/vfs/flags.d.ts +19 -0
- package/dist/vfs/flags.js +62 -0
- package/dist/vfs/index.d.ts +4 -10
- package/dist/vfs/index.js +4 -13
- package/dist/vfs/ioctl.d.ts +88 -0
- package/dist/vfs/ioctl.js +409 -0
- package/dist/vfs/promises.d.ts +81 -19
- package/dist/vfs/promises.js +404 -288
- package/dist/vfs/shared.d.ts +7 -37
- package/dist/vfs/shared.js +29 -85
- package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
- package/dist/{stats.js → vfs/stats.js} +11 -66
- package/dist/vfs/streams.d.ts +1 -0
- package/dist/vfs/streams.js +32 -27
- package/dist/vfs/sync.d.ts +3 -3
- package/dist/vfs/sync.js +263 -260
- package/dist/vfs/watchers.d.ts +2 -2
- package/dist/vfs/watchers.js +12 -12
- package/dist/vfs/xattr.d.ts +116 -0
- package/dist/vfs/xattr.js +201 -0
- package/package.json +5 -3
- package/readme.md +1 -1
- package/scripts/test.js +2 -2
- package/tests/assignment.ts +1 -1
- package/tests/backend/config.worker.js +4 -1
- package/tests/backend/fetch.test.ts +3 -0
- package/tests/backend/port.test.ts +19 -33
- package/tests/backend/remote.worker.js +4 -1
- package/tests/backend/single-buffer.test.ts +53 -0
- package/tests/backend/single-buffer.worker.js +30 -0
- package/tests/common/context.test.ts +3 -3
- package/tests/common/handle.test.ts +17 -12
- package/tests/common/mutex.test.ts +9 -9
- package/tests/common/path.test.ts +1 -1
- package/tests/common/readline.test.ts +104 -0
- package/tests/common.ts +4 -19
- package/tests/fetch/fetch.ts +2 -2
- package/tests/fs/append.test.ts +4 -4
- package/tests/fs/directory.test.ts +25 -25
- package/tests/fs/errors.test.ts +15 -19
- package/tests/fs/links.test.ts +4 -3
- package/tests/fs/open.test.ts +4 -21
- package/tests/fs/permissions.test.ts +14 -18
- package/tests/fs/read.test.ts +10 -9
- package/tests/fs/readFile.test.ts +10 -26
- package/tests/fs/rename.test.ts +4 -9
- package/tests/fs/stat.test.ts +8 -8
- package/tests/fs/streams.test.ts +2 -11
- package/tests/fs/times.test.ts +7 -7
- package/tests/fs/truncate.test.ts +8 -36
- package/tests/fs/watch.test.ts +10 -10
- package/tests/fs/write.test.ts +77 -13
- package/tests/fs/xattr.test.ts +85 -0
- package/tests/logs.js +22 -0
- package/tests/setup/context.ts +1 -1
- package/tests/setup/index.ts +3 -3
- package/tests/setup/port.ts +7 -1
- package/dist/backends/port/fs.d.ts +0 -84
- package/dist/backends/port/fs.js +0 -151
- package/dist/backends/port/rpc.d.ts +0 -77
- package/dist/backends/port/rpc.js +0 -100
- package/dist/backends/store/simple.d.ts +0 -20
- package/dist/backends/store/simple.js +0 -13
- package/dist/internal/file.d.ts +0 -359
- package/dist/internal/file.js +0 -751
- package/dist/internal/log.d.ts +0 -133
- package/dist/internal/log.js +0 -218
- package/tests/fs/writeFile.test.ts +0 -70
|
@@ -50,17 +50,17 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
-
import {
|
|
53
|
+
import { withErrno } from 'kerium';
|
|
54
|
+
import { crit, debug, err, notice, warn } from 'kerium/log';
|
|
55
|
+
import { sizeof } from 'memium';
|
|
56
|
+
import { _throw, canary, encodeUTF8 } from 'utilium';
|
|
54
57
|
import { extendBuffer } from 'utilium/buffer.js';
|
|
55
|
-
import { Errno, ErrnoError } from '../../internal/error.js';
|
|
56
|
-
import { LazyFile } from '../../internal/file.js';
|
|
57
58
|
import { Index } from '../../internal/file_index.js';
|
|
58
59
|
import { FileSystem } from '../../internal/filesystem.js';
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import { decodeDirListing, encodeDirListing
|
|
62
|
-
import { S_IFDIR, S_IFREG,
|
|
63
|
-
import { basename, dirname, join, parse, relative } from '../../vfs/path.js';
|
|
60
|
+
import { Inode, isDirectory, rootIno } from '../../internal/inode.js';
|
|
61
|
+
import { basename, dirname, join, parse, relative } from '../../path.js';
|
|
62
|
+
import { decodeDirListing, encodeDirListing } from '../../utils.js';
|
|
63
|
+
import { S_IFDIR, S_IFREG, size_max } from '../../vfs/constants.js';
|
|
64
64
|
import { WrappedTransaction } from './store.js';
|
|
65
65
|
/**
|
|
66
66
|
* A file system which uses a `Store`
|
|
@@ -132,8 +132,8 @@ export class StoreFS extends FileSystem {
|
|
|
132
132
|
this._initialized = true;
|
|
133
133
|
}
|
|
134
134
|
constructor(store) {
|
|
135
|
-
var _a, _b;
|
|
136
|
-
super((_a = store.
|
|
135
|
+
var _a, _b, _c;
|
|
136
|
+
super((_a = store.type) !== null && _a !== void 0 ? _a : 0x6b766673, store.name);
|
|
137
137
|
this.store = store;
|
|
138
138
|
/**
|
|
139
139
|
* A map of paths to inode IDs
|
|
@@ -146,9 +146,10 @@ export class StoreFS extends FileSystem {
|
|
|
146
146
|
*/
|
|
147
147
|
this._paths = new Map([[0, new Set('/')]]);
|
|
148
148
|
this._initialized = false;
|
|
149
|
-
this
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
store.fs = this;
|
|
150
|
+
this._uuid = (_b = store.uuid) !== null && _b !== void 0 ? _b : this.uuid;
|
|
151
|
+
this.label = store.label;
|
|
152
|
+
debug(this.name + ': supports features: ' + ((_c = this.store.flags) === null || _c === void 0 ? void 0 : _c.join(', ')));
|
|
152
153
|
}
|
|
153
154
|
/**
|
|
154
155
|
* @experimental
|
|
@@ -160,26 +161,6 @@ export class StoreFS extends FileSystem {
|
|
|
160
161
|
freeSpace: 0,
|
|
161
162
|
});
|
|
162
163
|
}
|
|
163
|
-
/* node:coverage disable */
|
|
164
|
-
/**
|
|
165
|
-
* Delete all contents stored in the file system.
|
|
166
|
-
* @deprecated
|
|
167
|
-
*/
|
|
168
|
-
async empty() {
|
|
169
|
-
log_deprecated('StoreFS#empty');
|
|
170
|
-
// Root always exists.
|
|
171
|
-
await this.checkRoot();
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Delete all contents stored in the file system.
|
|
175
|
-
* @deprecated
|
|
176
|
-
*/
|
|
177
|
-
emptySync() {
|
|
178
|
-
log_deprecated('StoreFS#emptySync');
|
|
179
|
-
// Root always exists.
|
|
180
|
-
this.checkRootSync();
|
|
181
|
-
}
|
|
182
|
-
/* node:coverage enable */
|
|
183
164
|
/**
|
|
184
165
|
* Load an index into the StoreFS.
|
|
185
166
|
* You *must* manually add non-directory files
|
|
@@ -191,7 +172,7 @@ export class StoreFS extends FileSystem {
|
|
|
191
172
|
const dirs = index.directories();
|
|
192
173
|
for (const [path, inode] of index) {
|
|
193
174
|
this._add(inode.ino, path);
|
|
194
|
-
await tx.set(inode.ino,
|
|
175
|
+
await tx.set(inode.ino, inode);
|
|
195
176
|
if (dirs.has(path))
|
|
196
177
|
await tx.set(inode.data, encodeDirListing(dirs.get(path)));
|
|
197
178
|
}
|
|
@@ -218,7 +199,7 @@ export class StoreFS extends FileSystem {
|
|
|
218
199
|
const dirs = index.directories();
|
|
219
200
|
for (const [path, inode] of index) {
|
|
220
201
|
this._add(inode.ino, path);
|
|
221
|
-
tx.setSync(inode.ino,
|
|
202
|
+
tx.setSync(inode.ino, inode);
|
|
222
203
|
if (dirs.has(path))
|
|
223
204
|
tx.setSync(inode.data, encodeDirListing(dirs.get(path)));
|
|
224
205
|
}
|
|
@@ -239,13 +220,13 @@ export class StoreFS extends FileSystem {
|
|
|
239
220
|
const index = new Index();
|
|
240
221
|
const tx = __addDisposableResource(env_3, this.transaction(), true);
|
|
241
222
|
const queue = [['/', 0]];
|
|
242
|
-
const silence = canary(
|
|
223
|
+
const silence = canary(withErrno('EDEADLK'));
|
|
243
224
|
while (queue.length) {
|
|
244
225
|
const [path, ino] = queue.shift();
|
|
245
226
|
const inode = new Inode(await tx.get(ino));
|
|
246
227
|
index.set(path, inode);
|
|
247
228
|
if (inode.mode & S_IFDIR) {
|
|
248
|
-
const dir = decodeDirListing((_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : _throw(
|
|
229
|
+
const dir = decodeDirListing((_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA')));
|
|
249
230
|
for (const [name, id] of Object.entries(dir)) {
|
|
250
231
|
queue.push([join(path, name), id]);
|
|
251
232
|
}
|
|
@@ -271,13 +252,13 @@ export class StoreFS extends FileSystem {
|
|
|
271
252
|
const index = new Index();
|
|
272
253
|
const tx = __addDisposableResource(env_4, this.transaction(), false);
|
|
273
254
|
const queue = [['/', 0]];
|
|
274
|
-
const silence = canary(
|
|
255
|
+
const silence = canary(withErrno('EDEADLK'));
|
|
275
256
|
while (queue.length) {
|
|
276
257
|
const [path, ino] = queue.shift();
|
|
277
258
|
const inode = new Inode(tx.getSync(ino));
|
|
278
259
|
index.set(path, inode);
|
|
279
260
|
if (inode.mode & S_IFDIR) {
|
|
280
|
-
const dir = decodeDirListing((_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : _throw(
|
|
261
|
+
const dir = decodeDirListing((_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA')));
|
|
281
262
|
for (const [name, id] of Object.entries(dir)) {
|
|
282
263
|
queue.push([join(path, name), id]);
|
|
283
264
|
}
|
|
@@ -304,9 +285,9 @@ export class StoreFS extends FileSystem {
|
|
|
304
285
|
const tx = __addDisposableResource(env_5, this.transaction(), true);
|
|
305
286
|
const _old = parse(oldPath), _new = parse(newPath),
|
|
306
287
|
// Remove oldPath from parent's directory listing.
|
|
307
|
-
oldDirNode = await this.findInode(tx, _old.dir
|
|
288
|
+
oldDirNode = await this.findInode(tx, _old.dir), oldDirList = decodeDirListing((_a = (await tx.get(oldDirNode.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA')));
|
|
308
289
|
if (!oldDirList[_old.base])
|
|
309
|
-
throw
|
|
290
|
+
throw withErrno('ENOENT');
|
|
310
291
|
const ino = oldDirList[_old.base];
|
|
311
292
|
if (ino != this._ids.get(oldPath))
|
|
312
293
|
err(`Ino mismatch while renaming ${oldPath} to ${newPath}`);
|
|
@@ -317,19 +298,17 @@ export class StoreFS extends FileSystem {
|
|
|
317
298
|
We append '/' to avoid matching folders that are a substring of the bottom-most folder in the path.
|
|
318
299
|
*/
|
|
319
300
|
if ((_new.dir + '/').startsWith(oldPath + '/'))
|
|
320
|
-
throw
|
|
321
|
-
// Add newPath to parent's directory listing.
|
|
301
|
+
throw withErrno('EBUSY');
|
|
322
302
|
const sameParent = _new.dir == _old.dir;
|
|
323
303
|
// Prevent us from re-grabbing the same directory listing, which still contains `old_path.base.`
|
|
324
|
-
const newDirNode = sameParent ? oldDirNode : await this.findInode(tx, _new.dir
|
|
304
|
+
const newDirNode = sameParent ? oldDirNode : await this.findInode(tx, _new.dir);
|
|
325
305
|
const newDirList = sameParent
|
|
326
306
|
? oldDirList
|
|
327
|
-
: decodeDirListing((_b = (await tx.get(newDirNode.data))) !== null && _b !== void 0 ? _b : _throw(
|
|
307
|
+
: decodeDirListing((_b = (await tx.get(newDirNode.data))) !== null && _b !== void 0 ? _b : _throw(withErrno('ENODATA')));
|
|
328
308
|
if (newDirList[_new.base]) {
|
|
329
|
-
|
|
330
|
-
const existing = new Inode((_c = (await tx.get(newDirList[_new.base]))) !== null && _c !== void 0 ? _c : _throw(ErrnoError.With('ENOENT', newPath, 'rename')));
|
|
309
|
+
const existing = new Inode((_c = (await tx.get(newDirList[_new.base]))) !== null && _c !== void 0 ? _c : _throw(withErrno('ENOENT')));
|
|
331
310
|
if (!existing.toStats().isFile())
|
|
332
|
-
throw
|
|
311
|
+
throw withErrno('EISDIR');
|
|
333
312
|
await tx.remove(existing.data);
|
|
334
313
|
await tx.remove(newDirList[_new.base]);
|
|
335
314
|
}
|
|
@@ -357,9 +336,9 @@ export class StoreFS extends FileSystem {
|
|
|
357
336
|
const tx = __addDisposableResource(env_6, this.transaction(), false);
|
|
358
337
|
const _old = parse(oldPath), _new = parse(newPath),
|
|
359
338
|
// Remove oldPath from parent's directory listing.
|
|
360
|
-
oldDirNode = this.findInodeSync(tx, _old.dir
|
|
339
|
+
oldDirNode = this.findInodeSync(tx, _old.dir), oldDirList = decodeDirListing((_a = tx.getSync(oldDirNode.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA')));
|
|
361
340
|
if (!oldDirList[_old.base])
|
|
362
|
-
throw
|
|
341
|
+
throw withErrno('ENOENT');
|
|
363
342
|
const ino = oldDirList[_old.base];
|
|
364
343
|
if (ino != this._ids.get(oldPath))
|
|
365
344
|
err(`Ino mismatch while renaming ${oldPath} to ${newPath}`);
|
|
@@ -370,19 +349,16 @@ export class StoreFS extends FileSystem {
|
|
|
370
349
|
We append '/' to avoid matching folders that are a substring of the bottom-most folder in the path.
|
|
371
350
|
*/
|
|
372
351
|
if ((_new.dir + '/').startsWith(oldPath + '/'))
|
|
373
|
-
throw
|
|
352
|
+
throw withErrno('EBUSY');
|
|
374
353
|
// Add newPath to parent's directory listing.
|
|
375
354
|
const sameParent = _new.dir === _old.dir;
|
|
376
355
|
// Prevent us from re-grabbing the same directory listing, which still contains `old_path.base.`
|
|
377
|
-
const newDirNode = sameParent ? oldDirNode : this.findInodeSync(tx, _new.dir
|
|
378
|
-
const newDirList = sameParent
|
|
379
|
-
? oldDirList
|
|
380
|
-
: decodeDirListing((_b = tx.getSync(newDirNode.data)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENODATA', _new.dir, 'rename')));
|
|
356
|
+
const newDirNode = sameParent ? oldDirNode : this.findInodeSync(tx, _new.dir);
|
|
357
|
+
const newDirList = sameParent ? oldDirList : decodeDirListing((_b = tx.getSync(newDirNode.data)) !== null && _b !== void 0 ? _b : _throw(withErrno('ENODATA')));
|
|
381
358
|
if (newDirList[_new.base]) {
|
|
382
|
-
|
|
383
|
-
const existing = new Inode((_c = tx.getSync(newDirList[_new.base])) !== null && _c !== void 0 ? _c : _throw(ErrnoError.With('ENOENT', newPath, 'rename')));
|
|
359
|
+
const existing = new Inode((_c = tx.getSync(newDirList[_new.base])) !== null && _c !== void 0 ? _c : _throw(withErrno('ENOENT')));
|
|
384
360
|
if (!existing.toStats().isFile())
|
|
385
|
-
throw
|
|
361
|
+
throw withErrno('EISDIR');
|
|
386
362
|
tx.removeSync(existing.data);
|
|
387
363
|
tx.removeSync(newDirList[_new.base]);
|
|
388
364
|
}
|
|
@@ -405,7 +381,7 @@ export class StoreFS extends FileSystem {
|
|
|
405
381
|
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
406
382
|
try {
|
|
407
383
|
const tx = __addDisposableResource(env_7, this.transaction(), true);
|
|
408
|
-
return
|
|
384
|
+
return await this.findInode(tx, path);
|
|
409
385
|
}
|
|
410
386
|
catch (e_7) {
|
|
411
387
|
env_7.error = e_7;
|
|
@@ -421,7 +397,7 @@ export class StoreFS extends FileSystem {
|
|
|
421
397
|
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
422
398
|
try {
|
|
423
399
|
const tx = __addDisposableResource(env_8, this.transaction(), false);
|
|
424
|
-
return this.findInodeSync(tx, path
|
|
400
|
+
return this.findInodeSync(tx, path);
|
|
425
401
|
}
|
|
426
402
|
catch (e_8) {
|
|
427
403
|
env_8.error = e_8;
|
|
@@ -431,20 +407,16 @@ export class StoreFS extends FileSystem {
|
|
|
431
407
|
__disposeResources(env_8);
|
|
432
408
|
}
|
|
433
409
|
}
|
|
434
|
-
async
|
|
435
|
-
const node = await this.commitNew(path, { mode: mode | S_IFREG, ...options }, new Uint8Array(), 'createFile');
|
|
436
|
-
return new LazyFile(this, path, flag, node.toStats());
|
|
437
|
-
}
|
|
438
|
-
createFileSync(path, flag, mode, options) {
|
|
439
|
-
const node = this.commitNewSync(path, { mode: mode | S_IFREG, ...options }, new Uint8Array(), 'createFile');
|
|
440
|
-
return new LazyFile(this, path, flag, node.toStats());
|
|
441
|
-
}
|
|
442
|
-
async openFile(path, flag) {
|
|
410
|
+
async touch(path, metadata) {
|
|
443
411
|
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
444
412
|
try {
|
|
445
413
|
const tx = __addDisposableResource(env_9, this.transaction(), true);
|
|
446
|
-
const
|
|
447
|
-
|
|
414
|
+
const inode = await this.findInode(tx, path);
|
|
415
|
+
if (inode.update(metadata)) {
|
|
416
|
+
this._add(inode.ino, path);
|
|
417
|
+
tx.setSync(inode.ino, inode);
|
|
418
|
+
}
|
|
419
|
+
await tx.commit();
|
|
448
420
|
}
|
|
449
421
|
catch (e_9) {
|
|
450
422
|
env_9.error = e_9;
|
|
@@ -456,12 +428,16 @@ export class StoreFS extends FileSystem {
|
|
|
456
428
|
await result_5;
|
|
457
429
|
}
|
|
458
430
|
}
|
|
459
|
-
|
|
431
|
+
touchSync(path, metadata) {
|
|
460
432
|
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
461
433
|
try {
|
|
462
434
|
const tx = __addDisposableResource(env_10, this.transaction(), false);
|
|
463
|
-
const
|
|
464
|
-
|
|
435
|
+
const inode = this.findInodeSync(tx, path);
|
|
436
|
+
if (inode.update(metadata)) {
|
|
437
|
+
this._add(inode.ino, path);
|
|
438
|
+
tx.setSync(inode.ino, inode);
|
|
439
|
+
}
|
|
440
|
+
tx.commitSync();
|
|
465
441
|
}
|
|
466
442
|
catch (e_10) {
|
|
467
443
|
env_10.error = e_10;
|
|
@@ -471,6 +447,14 @@ export class StoreFS extends FileSystem {
|
|
|
471
447
|
__disposeResources(env_10);
|
|
472
448
|
}
|
|
473
449
|
}
|
|
450
|
+
async createFile(path, options) {
|
|
451
|
+
options.mode |= S_IFREG;
|
|
452
|
+
return await this.commitNew(path, options, new Uint8Array());
|
|
453
|
+
}
|
|
454
|
+
createFileSync(path, options) {
|
|
455
|
+
options.mode |= S_IFREG;
|
|
456
|
+
return this.commitNewSync(path, options, new Uint8Array());
|
|
457
|
+
}
|
|
474
458
|
async unlink(path) {
|
|
475
459
|
return this.remove(path, false);
|
|
476
460
|
}
|
|
@@ -478,30 +462,30 @@ export class StoreFS extends FileSystem {
|
|
|
478
462
|
this.removeSync(path, false);
|
|
479
463
|
}
|
|
480
464
|
async rmdir(path) {
|
|
481
|
-
if ((await this.readdir(path)).length)
|
|
482
|
-
throw
|
|
483
|
-
}
|
|
465
|
+
if ((await this.readdir(path)).length)
|
|
466
|
+
throw withErrno('ENOTEMPTY');
|
|
484
467
|
await this.remove(path, true);
|
|
485
468
|
}
|
|
486
469
|
rmdirSync(path) {
|
|
487
|
-
if (this.readdirSync(path).length)
|
|
488
|
-
throw
|
|
489
|
-
}
|
|
470
|
+
if (this.readdirSync(path).length)
|
|
471
|
+
throw withErrno('ENOTEMPTY');
|
|
490
472
|
this.removeSync(path, true);
|
|
491
473
|
}
|
|
492
|
-
async mkdir(path,
|
|
493
|
-
|
|
474
|
+
async mkdir(path, options) {
|
|
475
|
+
options.mode |= S_IFDIR;
|
|
476
|
+
return await this.commitNew(path, options, encodeUTF8('{}'));
|
|
494
477
|
}
|
|
495
|
-
mkdirSync(path,
|
|
496
|
-
|
|
478
|
+
mkdirSync(path, options) {
|
|
479
|
+
options.mode |= S_IFDIR;
|
|
480
|
+
return this.commitNewSync(path, options, encodeUTF8('{}'));
|
|
497
481
|
}
|
|
498
482
|
async readdir(path) {
|
|
499
483
|
var _a;
|
|
500
484
|
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
501
485
|
try {
|
|
502
486
|
const tx = __addDisposableResource(env_11, this.transaction(), true);
|
|
503
|
-
const node = await this.findInode(tx, path
|
|
504
|
-
return Object.keys(decodeDirListing((_a = (await tx.get(node.data))) !== null && _a !== void 0 ? _a : _throw(
|
|
487
|
+
const node = await this.findInode(tx, path);
|
|
488
|
+
return Object.keys(decodeDirListing((_a = (await tx.get(node.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT'))));
|
|
505
489
|
}
|
|
506
490
|
catch (e_11) {
|
|
507
491
|
env_11.error = e_11;
|
|
@@ -518,8 +502,8 @@ export class StoreFS extends FileSystem {
|
|
|
518
502
|
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
519
503
|
try {
|
|
520
504
|
const tx = __addDisposableResource(env_12, this.transaction(), false);
|
|
521
|
-
const node = this.findInodeSync(tx, path
|
|
522
|
-
return Object.keys(decodeDirListing((_a = tx.getSync(node.data)) !== null && _a !== void 0 ? _a : _throw(
|
|
505
|
+
const node = this.findInodeSync(tx, path);
|
|
506
|
+
return Object.keys(decodeDirListing((_a = tx.getSync(node.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT'))));
|
|
523
507
|
}
|
|
524
508
|
catch (e_12) {
|
|
525
509
|
env_12.error = e_12;
|
|
@@ -531,19 +515,24 @@ export class StoreFS extends FileSystem {
|
|
|
531
515
|
}
|
|
532
516
|
/**
|
|
533
517
|
* Updated the inode and data node at `path`
|
|
534
|
-
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
535
518
|
*/
|
|
536
|
-
async sync(
|
|
519
|
+
async sync() { }
|
|
520
|
+
/**
|
|
521
|
+
* Updated the inode and data node at `path`
|
|
522
|
+
*/
|
|
523
|
+
syncSync() { }
|
|
524
|
+
async link(target, link) {
|
|
525
|
+
var _a;
|
|
537
526
|
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
538
527
|
try {
|
|
539
528
|
const tx = __addDisposableResource(env_13, this.transaction(), true);
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
529
|
+
const newDir = dirname(link), newDirNode = await this.findInode(tx, newDir), listing = decodeDirListing((_a = (await tx.get(newDirNode.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
530
|
+
const inode = await this.findInode(tx, target);
|
|
531
|
+
inode.nlink++;
|
|
532
|
+
listing[basename(link)] = inode.ino;
|
|
533
|
+
this._add(inode.ino, link);
|
|
534
|
+
await tx.set(inode.ino, inode);
|
|
535
|
+
await tx.set(newDirNode.data, encodeDirListing(listing));
|
|
547
536
|
await tx.commit();
|
|
548
537
|
}
|
|
549
538
|
catch (e_13) {
|
|
@@ -556,21 +545,18 @@ export class StoreFS extends FileSystem {
|
|
|
556
545
|
await result_7;
|
|
557
546
|
}
|
|
558
547
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
* @todo Ensure mtime updates properly, and use that to determine if a data update is required.
|
|
562
|
-
*/
|
|
563
|
-
syncSync(path, data, metadata) {
|
|
548
|
+
linkSync(target, link) {
|
|
549
|
+
var _a;
|
|
564
550
|
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
565
551
|
try {
|
|
566
552
|
const tx = __addDisposableResource(env_14, this.transaction(), false);
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
553
|
+
const newDir = dirname(link), newDirNode = this.findInodeSync(tx, newDir), listing = decodeDirListing((_a = tx.getSync(newDirNode.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
554
|
+
const inode = this.findInodeSync(tx, target);
|
|
555
|
+
inode.nlink++;
|
|
556
|
+
listing[basename(link)] = inode.ino;
|
|
557
|
+
this._add(inode.ino, link);
|
|
558
|
+
tx.setSync(inode.ino, inode);
|
|
559
|
+
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
574
560
|
tx.commitSync();
|
|
575
561
|
}
|
|
576
562
|
catch (e_14) {
|
|
@@ -581,19 +567,19 @@ export class StoreFS extends FileSystem {
|
|
|
581
567
|
__disposeResources(env_14);
|
|
582
568
|
}
|
|
583
569
|
}
|
|
584
|
-
async
|
|
570
|
+
async read(path, buffer, offset, end) {
|
|
585
571
|
var _a;
|
|
586
572
|
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
587
573
|
try {
|
|
588
574
|
const tx = __addDisposableResource(env_15, this.transaction(), true);
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
575
|
+
const inode = await this.findInode(tx, path);
|
|
576
|
+
if (inode.size == 0)
|
|
577
|
+
return;
|
|
578
|
+
const data = (_a = (await tx.get(inode.data, offset, end))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA'));
|
|
579
|
+
const _ = tx.flag('partial') ? data : data.subarray(offset, end);
|
|
580
|
+
if (_.byteLength > buffer.byteLength)
|
|
581
|
+
err(`Trying to place ${_.byteLength} bytes into a ${buffer.byteLength} byte buffer on read`);
|
|
582
|
+
buffer.set(_);
|
|
597
583
|
}
|
|
598
584
|
catch (e_15) {
|
|
599
585
|
env_15.error = e_15;
|
|
@@ -605,80 +591,34 @@ export class StoreFS extends FileSystem {
|
|
|
605
591
|
await result_8;
|
|
606
592
|
}
|
|
607
593
|
}
|
|
608
|
-
|
|
594
|
+
readSync(path, buffer, offset, end) {
|
|
609
595
|
var _a;
|
|
610
596
|
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
611
597
|
try {
|
|
612
598
|
const tx = __addDisposableResource(env_16, this.transaction(), false);
|
|
613
|
-
const
|
|
614
|
-
const inode = this.findInodeSync(tx, target, 'link');
|
|
615
|
-
inode.nlink++;
|
|
616
|
-
listing[basename(link)] = inode.ino;
|
|
617
|
-
this._add(inode.ino, link);
|
|
618
|
-
tx.setSync(inode.ino, serialize(inode));
|
|
619
|
-
tx.setSync(newDirNode.data, encodeDirListing(listing));
|
|
620
|
-
tx.commitSync();
|
|
621
|
-
}
|
|
622
|
-
catch (e_16) {
|
|
623
|
-
env_16.error = e_16;
|
|
624
|
-
env_16.hasError = true;
|
|
625
|
-
}
|
|
626
|
-
finally {
|
|
627
|
-
__disposeResources(env_16);
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
async read(path, buffer, offset, end) {
|
|
631
|
-
var _a;
|
|
632
|
-
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
633
|
-
try {
|
|
634
|
-
const tx = __addDisposableResource(env_17, this.transaction(), true);
|
|
635
|
-
const inode = await this.findInode(tx, path, 'read');
|
|
599
|
+
const inode = this.findInodeSync(tx, path);
|
|
636
600
|
if (inode.size == 0)
|
|
637
601
|
return;
|
|
638
|
-
const data = (_a =
|
|
602
|
+
const data = (_a = tx.getSync(inode.data, offset, end)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA'));
|
|
639
603
|
const _ = tx.flag('partial') ? data : data.subarray(offset, end);
|
|
640
604
|
if (_.byteLength > buffer.byteLength)
|
|
641
605
|
err(`Trying to place ${_.byteLength} bytes into a ${buffer.byteLength} byte buffer on read`);
|
|
642
606
|
buffer.set(_);
|
|
643
607
|
}
|
|
644
|
-
catch (
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
finally {
|
|
649
|
-
const result_9 = __disposeResources(env_17);
|
|
650
|
-
if (result_9)
|
|
651
|
-
await result_9;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
readSync(path, buffer, offset, end) {
|
|
655
|
-
var _a;
|
|
656
|
-
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
657
|
-
try {
|
|
658
|
-
const tx = __addDisposableResource(env_18, this.transaction(), false);
|
|
659
|
-
const inode = this.findInodeSync(tx, path, 'read');
|
|
660
|
-
if (inode.size == 0)
|
|
661
|
-
return;
|
|
662
|
-
const data = (_a = tx.getSync(inode.data, offset, end)) !== null && _a !== void 0 ? _a : _throw(ErrnoError.With('ENODATA', path, 'read'));
|
|
663
|
-
const _ = tx.flag('partial') ? data : data.subarray(offset, end);
|
|
664
|
-
if (_.byteLength > buffer.byteLength)
|
|
665
|
-
err(`Trying to place ${_.byteLength} bytes into a ${buffer.byteLength} byte buffer on read`);
|
|
666
|
-
buffer.set(_);
|
|
667
|
-
}
|
|
668
|
-
catch (e_18) {
|
|
669
|
-
env_18.error = e_18;
|
|
670
|
-
env_18.hasError = true;
|
|
608
|
+
catch (e_16) {
|
|
609
|
+
env_16.error = e_16;
|
|
610
|
+
env_16.hasError = true;
|
|
671
611
|
}
|
|
672
612
|
finally {
|
|
673
|
-
__disposeResources(
|
|
613
|
+
__disposeResources(env_16);
|
|
674
614
|
}
|
|
675
615
|
}
|
|
676
616
|
async write(path, data, offset) {
|
|
677
617
|
var _a;
|
|
678
|
-
const
|
|
618
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
679
619
|
try {
|
|
680
|
-
const tx = __addDisposableResource(
|
|
681
|
-
const inode = await this.findInode(tx, path
|
|
620
|
+
const tx = __addDisposableResource(env_17, this.transaction(), true);
|
|
621
|
+
const inode = await this.findInode(tx, path);
|
|
682
622
|
let buffer = data;
|
|
683
623
|
if (!tx.flag('partial')) {
|
|
684
624
|
buffer = extendBuffer((_a = (await tx.get(inode.data))) !== null && _a !== void 0 ? _a : new Uint8Array(), offset + data.byteLength);
|
|
@@ -686,27 +626,25 @@ export class StoreFS extends FileSystem {
|
|
|
686
626
|
offset = 0;
|
|
687
627
|
}
|
|
688
628
|
await tx.set(inode.data, buffer, offset);
|
|
689
|
-
inode.update({ mtimeMs: Date.now(), size: Math.max(inode.size, data.byteLength + offset) });
|
|
690
629
|
this._add(inode.ino, path);
|
|
691
|
-
await tx.set(inode.ino, serialize(inode));
|
|
692
630
|
await tx.commit();
|
|
693
631
|
}
|
|
694
|
-
catch (
|
|
695
|
-
|
|
696
|
-
|
|
632
|
+
catch (e_17) {
|
|
633
|
+
env_17.error = e_17;
|
|
634
|
+
env_17.hasError = true;
|
|
697
635
|
}
|
|
698
636
|
finally {
|
|
699
|
-
const
|
|
700
|
-
if (
|
|
701
|
-
await
|
|
637
|
+
const result_9 = __disposeResources(env_17);
|
|
638
|
+
if (result_9)
|
|
639
|
+
await result_9;
|
|
702
640
|
}
|
|
703
641
|
}
|
|
704
642
|
writeSync(path, data, offset) {
|
|
705
643
|
var _a;
|
|
706
|
-
const
|
|
644
|
+
const env_18 = { stack: [], error: void 0, hasError: false };
|
|
707
645
|
try {
|
|
708
|
-
const tx = __addDisposableResource(
|
|
709
|
-
const inode = this.findInodeSync(tx, path
|
|
646
|
+
const tx = __addDisposableResource(env_18, this.transaction(), false);
|
|
647
|
+
const inode = this.findInodeSync(tx, path);
|
|
710
648
|
let buffer = data;
|
|
711
649
|
if (!tx.flag('partial')) {
|
|
712
650
|
buffer = extendBuffer((_a = tx.getSync(inode.data)) !== null && _a !== void 0 ? _a : new Uint8Array(), offset + data.byteLength);
|
|
@@ -714,17 +652,15 @@ export class StoreFS extends FileSystem {
|
|
|
714
652
|
offset = 0;
|
|
715
653
|
}
|
|
716
654
|
tx.setSync(inode.data, buffer, offset);
|
|
717
|
-
inode.update({ mtimeMs: Date.now(), size: Math.max(inode.size, data.byteLength + offset) });
|
|
718
655
|
this._add(inode.ino, path);
|
|
719
|
-
tx.setSync(inode.ino, serialize(inode));
|
|
720
656
|
tx.commitSync();
|
|
721
657
|
}
|
|
722
|
-
catch (
|
|
723
|
-
|
|
724
|
-
|
|
658
|
+
catch (e_18) {
|
|
659
|
+
env_18.error = e_18;
|
|
660
|
+
env_18.hasError = true;
|
|
725
661
|
}
|
|
726
662
|
finally {
|
|
727
|
-
__disposeResources(
|
|
663
|
+
__disposeResources(env_18);
|
|
728
664
|
}
|
|
729
665
|
}
|
|
730
666
|
/**
|
|
@@ -738,73 +674,73 @@ export class StoreFS extends FileSystem {
|
|
|
738
674
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
739
675
|
*/
|
|
740
676
|
async checkRoot() {
|
|
741
|
-
const
|
|
677
|
+
const env_19 = { stack: [], error: void 0, hasError: false };
|
|
742
678
|
try {
|
|
743
|
-
const tx = __addDisposableResource(
|
|
679
|
+
const tx = __addDisposableResource(env_19, this.transaction(), true);
|
|
744
680
|
if (await tx.get(rootIno))
|
|
745
681
|
return;
|
|
746
682
|
const inode = new Inode({ ino: rootIno, data: 1, mode: 0o777 | S_IFDIR });
|
|
747
683
|
await tx.set(inode.data, encodeUTF8('{}'));
|
|
748
684
|
this._add(rootIno, '/');
|
|
749
|
-
await tx.set(rootIno,
|
|
685
|
+
await tx.set(rootIno, inode);
|
|
750
686
|
await tx.commit();
|
|
751
687
|
}
|
|
752
|
-
catch (
|
|
753
|
-
|
|
754
|
-
|
|
688
|
+
catch (e_19) {
|
|
689
|
+
env_19.error = e_19;
|
|
690
|
+
env_19.hasError = true;
|
|
755
691
|
}
|
|
756
692
|
finally {
|
|
757
|
-
const
|
|
758
|
-
if (
|
|
759
|
-
await
|
|
693
|
+
const result_10 = __disposeResources(env_19);
|
|
694
|
+
if (result_10)
|
|
695
|
+
await result_10;
|
|
760
696
|
}
|
|
761
697
|
}
|
|
762
698
|
/**
|
|
763
699
|
* Checks if the root directory exists. Creates it if it doesn't.
|
|
764
700
|
*/
|
|
765
701
|
checkRootSync() {
|
|
766
|
-
const
|
|
702
|
+
const env_20 = { stack: [], error: void 0, hasError: false };
|
|
767
703
|
try {
|
|
768
|
-
const tx = __addDisposableResource(
|
|
704
|
+
const tx = __addDisposableResource(env_20, this.transaction(), false);
|
|
769
705
|
if (tx.getSync(rootIno))
|
|
770
706
|
return;
|
|
771
707
|
const inode = new Inode({ ino: rootIno, data: 1, mode: 0o777 | S_IFDIR });
|
|
772
708
|
tx.setSync(inode.data, encodeUTF8('{}'));
|
|
773
709
|
this._add(rootIno, '/');
|
|
774
|
-
tx.setSync(rootIno,
|
|
710
|
+
tx.setSync(rootIno, inode);
|
|
775
711
|
tx.commitSync();
|
|
776
712
|
}
|
|
777
|
-
catch (
|
|
778
|
-
|
|
779
|
-
|
|
713
|
+
catch (e_20) {
|
|
714
|
+
env_20.error = e_20;
|
|
715
|
+
env_20.hasError = true;
|
|
780
716
|
}
|
|
781
717
|
finally {
|
|
782
|
-
__disposeResources(
|
|
718
|
+
__disposeResources(env_20);
|
|
783
719
|
}
|
|
784
720
|
}
|
|
785
721
|
/**
|
|
786
722
|
* Populates the `_ids` and `_paths` maps with all existing files stored in the underlying `Store`.
|
|
787
723
|
*/
|
|
788
724
|
async _populate() {
|
|
789
|
-
const
|
|
725
|
+
const env_21 = { stack: [], error: void 0, hasError: false };
|
|
790
726
|
try {
|
|
791
727
|
if (this._initialized) {
|
|
792
728
|
warn('Attempted to populate tables after initialization');
|
|
793
729
|
return;
|
|
794
730
|
}
|
|
795
731
|
debug('Populating tables with existing store metadata');
|
|
796
|
-
const tx = __addDisposableResource(
|
|
732
|
+
const tx = __addDisposableResource(env_21, this.transaction(), true);
|
|
797
733
|
const rootData = await tx.get(rootIno);
|
|
798
734
|
if (!rootData) {
|
|
799
735
|
notice('Store does not have a root inode');
|
|
800
736
|
const inode = new Inode({ ino: rootIno, data: 1, mode: 0o777 | S_IFDIR });
|
|
801
737
|
await tx.set(inode.data, encodeUTF8('{}'));
|
|
802
738
|
this._add(rootIno, '/');
|
|
803
|
-
await tx.set(rootIno,
|
|
739
|
+
await tx.set(rootIno, inode);
|
|
804
740
|
await tx.commit();
|
|
805
741
|
return;
|
|
806
742
|
}
|
|
807
|
-
if (rootData.length
|
|
743
|
+
if (rootData.length < sizeof(Inode)) {
|
|
808
744
|
crit('Store contains an invalid root inode. Refusing to populate tables');
|
|
809
745
|
return;
|
|
810
746
|
}
|
|
@@ -823,7 +759,7 @@ export class StoreFS extends FileSystem {
|
|
|
823
759
|
warn('Store is missing data for inode: ' + ino);
|
|
824
760
|
continue;
|
|
825
761
|
}
|
|
826
|
-
if (inodeData.length
|
|
762
|
+
if (inodeData.length < sizeof(Inode)) {
|
|
827
763
|
warn(`Invalid inode size for ino ${ino}: ${inodeData.length}`);
|
|
828
764
|
continue;
|
|
829
765
|
}
|
|
@@ -847,27 +783,63 @@ export class StoreFS extends FileSystem {
|
|
|
847
783
|
}
|
|
848
784
|
debug(`Added ${i} existing inode(s) from store`);
|
|
849
785
|
}
|
|
850
|
-
catch (
|
|
851
|
-
|
|
852
|
-
|
|
786
|
+
catch (e_21) {
|
|
787
|
+
env_21.error = e_21;
|
|
788
|
+
env_21.hasError = true;
|
|
853
789
|
}
|
|
854
790
|
finally {
|
|
855
|
-
const
|
|
856
|
-
if (
|
|
857
|
-
await
|
|
791
|
+
const result_11 = __disposeResources(env_21);
|
|
792
|
+
if (result_11)
|
|
793
|
+
await result_11;
|
|
858
794
|
}
|
|
859
795
|
}
|
|
796
|
+
/**
|
|
797
|
+
* Find an inode without using the ID tables
|
|
798
|
+
*/
|
|
799
|
+
async _findInode(tx, path, visited = new Set()) {
|
|
800
|
+
var _a, _b, _c;
|
|
801
|
+
if (visited.has(path))
|
|
802
|
+
throw crit(withErrno('EIO', 'Infinite loop detected while finding inode'));
|
|
803
|
+
visited.add(path);
|
|
804
|
+
if (path == '/')
|
|
805
|
+
return new Inode((_a = (await tx.get(rootIno))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENODATA')));
|
|
806
|
+
const { dir: parent, base: filename } = parse(path);
|
|
807
|
+
const inode = await this._findInode(tx, parent, visited);
|
|
808
|
+
const dirList = decodeDirListing((_b = (await tx.get(inode.data))) !== null && _b !== void 0 ? _b : _throw(withErrno('ENODATA')));
|
|
809
|
+
if (!(filename in dirList))
|
|
810
|
+
throw withErrno('ENOENT');
|
|
811
|
+
return new Inode((_c = (await tx.get(dirList[filename]))) !== null && _c !== void 0 ? _c : _throw(withErrno('ENODATA')));
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Find an inode without using the ID tables
|
|
815
|
+
*/
|
|
816
|
+
_findInodeSync(tx, path, visited = new Set()) {
|
|
817
|
+
var _a, _b, _c;
|
|
818
|
+
if (visited.has(path))
|
|
819
|
+
throw crit(withErrno('EIO', 'Infinite loop detected while finding inode'));
|
|
820
|
+
visited.add(path);
|
|
821
|
+
if (path == '/')
|
|
822
|
+
return new Inode((_a = tx.getSync(rootIno)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
823
|
+
const { dir: parent, base: filename } = parse(path);
|
|
824
|
+
const inode = this._findInodeSync(tx, parent, visited);
|
|
825
|
+
const dir = decodeDirListing((_b = tx.getSync(inode.data)) !== null && _b !== void 0 ? _b : _throw(withErrno('ENODATA')));
|
|
826
|
+
if (!(filename in dir))
|
|
827
|
+
throw withErrno('ENOENT');
|
|
828
|
+
return new Inode((_c = tx.getSync(dir[filename])) !== null && _c !== void 0 ? _c : _throw(withErrno('ENODATA')));
|
|
829
|
+
}
|
|
860
830
|
/**
|
|
861
831
|
* Finds the Inode of `path`.
|
|
862
832
|
* @param path The path to look up.
|
|
863
833
|
* @todo memoize/cache
|
|
864
834
|
*/
|
|
865
|
-
async findInode(tx, path
|
|
835
|
+
async findInode(tx, path) {
|
|
866
836
|
var _a;
|
|
837
|
+
if (this.attributes.has('no_id_tables'))
|
|
838
|
+
return await this._findInode(tx, path);
|
|
867
839
|
const ino = this._ids.get(path);
|
|
868
840
|
if (ino === undefined)
|
|
869
|
-
throw
|
|
870
|
-
return new Inode((_a = (await tx.get(ino))) !== null && _a !== void 0 ? _a : _throw(
|
|
841
|
+
throw withErrno('ENOENT');
|
|
842
|
+
return new Inode((_a = (await tx.get(ino))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
871
843
|
}
|
|
872
844
|
/**
|
|
873
845
|
* Finds the Inode of `path`.
|
|
@@ -875,23 +847,23 @@ export class StoreFS extends FileSystem {
|
|
|
875
847
|
* @return The Inode of the path p.
|
|
876
848
|
* @todo memoize/cache
|
|
877
849
|
*/
|
|
878
|
-
findInodeSync(tx, path
|
|
850
|
+
findInodeSync(tx, path) {
|
|
879
851
|
var _a;
|
|
852
|
+
if (this.attributes.has('no_id_tables'))
|
|
853
|
+
return this._findInodeSync(tx, path);
|
|
880
854
|
const ino = this._ids.get(path);
|
|
881
855
|
if (ino === undefined)
|
|
882
|
-
throw
|
|
883
|
-
return new Inode((_a = tx.getSync(ino)) !== null && _a !== void 0 ? _a : _throw(
|
|
856
|
+
throw withErrno('ENOENT');
|
|
857
|
+
return new Inode((_a = tx.getSync(ino)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
884
858
|
}
|
|
885
|
-
/**
|
|
886
|
-
|
|
887
|
-
*/
|
|
888
|
-
allocNew(path, syscall) {
|
|
859
|
+
/** Allocates a new ID and adds the ID/path */
|
|
860
|
+
allocNew(path) {
|
|
889
861
|
var _a;
|
|
890
862
|
(_a = this._lastID) !== null && _a !== void 0 ? _a : (this._lastID = Math.max(...this._paths.keys()));
|
|
891
863
|
this._lastID += 2;
|
|
892
864
|
const id = this._lastID;
|
|
893
865
|
if (id > size_max)
|
|
894
|
-
throw err(
|
|
866
|
+
throw err(withErrno('ENOSPC', 'No IDs available'));
|
|
895
867
|
this._add(id, path);
|
|
896
868
|
return id;
|
|
897
869
|
}
|
|
@@ -902,9 +874,9 @@ export class StoreFS extends FileSystem {
|
|
|
902
874
|
* @param options The options to create the new file with.
|
|
903
875
|
* @param data The data to store at the file's data node.
|
|
904
876
|
*/
|
|
905
|
-
async commitNew(path, options, data
|
|
877
|
+
async commitNew(path, options, data) {
|
|
906
878
|
var _a;
|
|
907
|
-
const
|
|
879
|
+
const env_22 = { stack: [], error: void 0, hasError: false };
|
|
908
880
|
try {
|
|
909
881
|
/*
|
|
910
882
|
The root always exists.
|
|
@@ -912,25 +884,24 @@ export class StoreFS extends FileSystem {
|
|
|
912
884
|
we will create a file with name '' in root if path is '/'.
|
|
913
885
|
*/
|
|
914
886
|
if (path == '/')
|
|
915
|
-
throw
|
|
916
|
-
const tx = __addDisposableResource(
|
|
887
|
+
throw withErrno('EEXIST');
|
|
888
|
+
const tx = __addDisposableResource(env_22, this.transaction(), true);
|
|
917
889
|
const { dir: parentPath, base: fname } = parse(path);
|
|
918
|
-
const parent = await this.findInode(tx, parentPath
|
|
919
|
-
const listing = decodeDirListing((_a = (await tx.get(parent.data))) !== null && _a !== void 0 ? _a : _throw(
|
|
890
|
+
const parent = await this.findInode(tx, parentPath);
|
|
891
|
+
const listing = decodeDirListing((_a = (await tx.get(parent.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
920
892
|
// Check if file already exists.
|
|
921
893
|
if (listing[fname])
|
|
922
|
-
throw
|
|
923
|
-
const id = this.allocNew(path
|
|
894
|
+
throw withErrno('EEXIST');
|
|
895
|
+
const id = this.allocNew(path);
|
|
924
896
|
// Commit data.
|
|
925
897
|
const inode = new Inode({
|
|
898
|
+
...options,
|
|
926
899
|
ino: id,
|
|
927
900
|
data: id + 1,
|
|
928
|
-
mode: options.mode,
|
|
929
901
|
size: data.byteLength,
|
|
930
|
-
|
|
931
|
-
gid: parent.mode & S_ISGID ? parent.gid : options.gid,
|
|
902
|
+
nlink: 1,
|
|
932
903
|
});
|
|
933
|
-
await tx.set(inode.ino,
|
|
904
|
+
await tx.set(inode.ino, inode);
|
|
934
905
|
await tx.set(inode.data, data);
|
|
935
906
|
// Update and commit parent directory listing.
|
|
936
907
|
listing[fname] = inode.ino;
|
|
@@ -938,14 +909,14 @@ export class StoreFS extends FileSystem {
|
|
|
938
909
|
await tx.commit();
|
|
939
910
|
return inode;
|
|
940
911
|
}
|
|
941
|
-
catch (
|
|
942
|
-
|
|
943
|
-
|
|
912
|
+
catch (e_22) {
|
|
913
|
+
env_22.error = e_22;
|
|
914
|
+
env_22.hasError = true;
|
|
944
915
|
}
|
|
945
916
|
finally {
|
|
946
|
-
const
|
|
947
|
-
if (
|
|
948
|
-
await
|
|
917
|
+
const result_12 = __disposeResources(env_22);
|
|
918
|
+
if (result_12)
|
|
919
|
+
await result_12;
|
|
949
920
|
}
|
|
950
921
|
}
|
|
951
922
|
/**
|
|
@@ -956,9 +927,9 @@ export class StoreFS extends FileSystem {
|
|
|
956
927
|
* @param data The data to store at the file's data node.
|
|
957
928
|
* @return The Inode for the new file.
|
|
958
929
|
*/
|
|
959
|
-
commitNewSync(path, options, data
|
|
930
|
+
commitNewSync(path, options, data) {
|
|
960
931
|
var _a;
|
|
961
|
-
const
|
|
932
|
+
const env_23 = { stack: [], error: void 0, hasError: false };
|
|
962
933
|
try {
|
|
963
934
|
/*
|
|
964
935
|
The root always exists.
|
|
@@ -966,122 +937,112 @@ export class StoreFS extends FileSystem {
|
|
|
966
937
|
we will create a file with name '' in root if path is '/'.
|
|
967
938
|
*/
|
|
968
939
|
if (path == '/')
|
|
969
|
-
throw
|
|
970
|
-
const tx = __addDisposableResource(
|
|
940
|
+
throw withErrno('EEXIST');
|
|
941
|
+
const tx = __addDisposableResource(env_23, this.transaction(), false);
|
|
971
942
|
const { dir: parentPath, base: fname } = parse(path);
|
|
972
|
-
const parent = this.findInodeSync(tx, parentPath
|
|
973
|
-
const listing = decodeDirListing((_a = tx.getSync(parent.data)) !== null && _a !== void 0 ? _a : _throw(
|
|
974
|
-
// Check if file already exists.
|
|
943
|
+
const parent = this.findInodeSync(tx, parentPath);
|
|
944
|
+
const listing = decodeDirListing((_a = tx.getSync(parent.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
975
945
|
if (listing[fname])
|
|
976
|
-
throw
|
|
977
|
-
const id = this.allocNew(path
|
|
978
|
-
// Commit data.
|
|
946
|
+
throw withErrno('EEXIST');
|
|
947
|
+
const id = this.allocNew(path);
|
|
979
948
|
const inode = new Inode({
|
|
949
|
+
...options,
|
|
980
950
|
ino: id,
|
|
981
951
|
data: id + 1,
|
|
982
|
-
mode: options.mode,
|
|
983
952
|
size: data.byteLength,
|
|
984
|
-
|
|
985
|
-
gid: parent.mode & S_ISGID ? parent.gid : options.gid,
|
|
953
|
+
nlink: 1,
|
|
986
954
|
});
|
|
987
955
|
// Update and commit parent directory listing.
|
|
988
|
-
tx.setSync(inode.ino,
|
|
956
|
+
tx.setSync(inode.ino, inode);
|
|
989
957
|
tx.setSync(inode.data, data);
|
|
990
958
|
listing[fname] = inode.ino;
|
|
991
959
|
tx.setSync(parent.data, encodeDirListing(listing));
|
|
992
960
|
tx.commitSync();
|
|
993
961
|
return inode;
|
|
994
962
|
}
|
|
995
|
-
catch (
|
|
996
|
-
|
|
997
|
-
|
|
963
|
+
catch (e_23) {
|
|
964
|
+
env_23.error = e_23;
|
|
965
|
+
env_23.hasError = true;
|
|
998
966
|
}
|
|
999
967
|
finally {
|
|
1000
|
-
__disposeResources(
|
|
968
|
+
__disposeResources(env_23);
|
|
1001
969
|
}
|
|
1002
970
|
}
|
|
1003
971
|
/**
|
|
1004
972
|
* Remove all traces of `path` from the file system.
|
|
1005
973
|
* @param path The path to remove from the file system.
|
|
1006
974
|
* @param isDir Does the path belong to a directory, or a file?
|
|
1007
|
-
* @todo Update mtime.
|
|
1008
975
|
*/
|
|
1009
976
|
async remove(path, isDir) {
|
|
1010
977
|
var _a, _b;
|
|
1011
|
-
const
|
|
978
|
+
const env_24 = { stack: [], error: void 0, hasError: false };
|
|
1012
979
|
try {
|
|
1013
|
-
const
|
|
1014
|
-
const
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
const fileIno = listing[fileName];
|
|
1020
|
-
// Get file inode.
|
|
1021
|
-
const fileNode = new Inode((_b = (await tx.get(fileIno))) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
1022
|
-
// Remove from directory listing of parent.
|
|
980
|
+
const tx = __addDisposableResource(env_24, this.transaction(), true);
|
|
981
|
+
const { dir: parent, base: fileName } = parse(path), parentNode = await this.findInode(tx, parent), listing = decodeDirListing((_a = (await tx.get(parentNode.data))) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT')));
|
|
982
|
+
if (!listing[fileName])
|
|
983
|
+
throw withErrno('ENOENT');
|
|
984
|
+
const ino = listing[fileName];
|
|
985
|
+
const inode = new Inode((_b = (await tx.get(ino))) !== null && _b !== void 0 ? _b : _throw(withErrno('ENOENT')));
|
|
1023
986
|
delete listing[fileName];
|
|
1024
|
-
if (!isDir &&
|
|
1025
|
-
throw
|
|
987
|
+
if (!isDir && isDirectory(inode))
|
|
988
|
+
throw withErrno('EISDIR');
|
|
1026
989
|
await tx.set(parentNode.data, encodeDirListing(listing));
|
|
1027
|
-
if (
|
|
1028
|
-
|
|
1029
|
-
await tx.
|
|
1030
|
-
|
|
1031
|
-
|
|
990
|
+
if (inode.nlink > 1) {
|
|
991
|
+
inode.update({ nlink: inode.nlink - 1 });
|
|
992
|
+
await tx.set(inode.ino, inode);
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
await tx.remove(inode.data);
|
|
996
|
+
await tx.remove(ino);
|
|
997
|
+
this._remove(ino);
|
|
1032
998
|
}
|
|
1033
|
-
// Success.
|
|
1034
999
|
await tx.commit();
|
|
1035
1000
|
}
|
|
1036
|
-
catch (
|
|
1037
|
-
|
|
1038
|
-
|
|
1001
|
+
catch (e_24) {
|
|
1002
|
+
env_24.error = e_24;
|
|
1003
|
+
env_24.hasError = true;
|
|
1039
1004
|
}
|
|
1040
1005
|
finally {
|
|
1041
|
-
const
|
|
1042
|
-
if (
|
|
1043
|
-
await
|
|
1006
|
+
const result_13 = __disposeResources(env_24);
|
|
1007
|
+
if (result_13)
|
|
1008
|
+
await result_13;
|
|
1044
1009
|
}
|
|
1045
1010
|
}
|
|
1046
1011
|
/**
|
|
1047
1012
|
* Remove all traces of `path` from the file system.
|
|
1048
1013
|
* @param path The path to remove from the file system.
|
|
1049
1014
|
* @param isDir Does the path belong to a directory, or a file?
|
|
1050
|
-
* @todo Update mtime.
|
|
1051
1015
|
*/
|
|
1052
1016
|
removeSync(path, isDir) {
|
|
1053
1017
|
var _a, _b;
|
|
1054
|
-
const
|
|
1018
|
+
const env_25 = { stack: [], error: void 0, hasError: false };
|
|
1055
1019
|
try {
|
|
1056
|
-
const
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
// Get file inode.
|
|
1062
|
-
const fileNode = new Inode((_b = tx.getSync(fileIno)) !== null && _b !== void 0 ? _b : _throw(ErrnoError.With('ENOENT', path, syscall)));
|
|
1063
|
-
// Remove from directory listing of parent.
|
|
1020
|
+
const tx = __addDisposableResource(env_25, this.transaction(), false);
|
|
1021
|
+
const { dir: parent, base: fileName } = parse(path), parentNode = this.findInodeSync(tx, parent), listing = decodeDirListing((_a = tx.getSync(parentNode.data)) !== null && _a !== void 0 ? _a : _throw(withErrno('ENOENT'))), ino = listing[fileName];
|
|
1022
|
+
if (!ino)
|
|
1023
|
+
throw withErrno('ENOENT');
|
|
1024
|
+
const inode = new Inode((_b = tx.getSync(ino)) !== null && _b !== void 0 ? _b : _throw(withErrno('ENOENT')));
|
|
1064
1025
|
delete listing[fileName];
|
|
1065
|
-
if (!isDir &&
|
|
1066
|
-
throw
|
|
1067
|
-
}
|
|
1068
|
-
// Update directory listing.
|
|
1026
|
+
if (!isDir && isDirectory(inode))
|
|
1027
|
+
throw withErrno('EISDIR');
|
|
1069
1028
|
tx.setSync(parentNode.data, encodeDirListing(listing));
|
|
1070
|
-
if (
|
|
1071
|
-
|
|
1072
|
-
tx.
|
|
1073
|
-
|
|
1074
|
-
|
|
1029
|
+
if (inode.nlink > 1) {
|
|
1030
|
+
inode.update({ nlink: inode.nlink - 1 });
|
|
1031
|
+
tx.setSync(inode.ino, inode);
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
tx.removeSync(inode.data);
|
|
1035
|
+
tx.removeSync(ino);
|
|
1036
|
+
this._remove(ino);
|
|
1075
1037
|
}
|
|
1076
|
-
// Success.
|
|
1077
1038
|
tx.commitSync();
|
|
1078
1039
|
}
|
|
1079
|
-
catch (
|
|
1080
|
-
|
|
1081
|
-
|
|
1040
|
+
catch (e_25) {
|
|
1041
|
+
env_25.error = e_25;
|
|
1042
|
+
env_25.hasError = true;
|
|
1082
1043
|
}
|
|
1083
1044
|
finally {
|
|
1084
|
-
__disposeResources(
|
|
1045
|
+
__disposeResources(env_25);
|
|
1085
1046
|
}
|
|
1086
1047
|
}
|
|
1087
1048
|
}
|