@zenfs/core 2.3.10 → 2.3.11
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.
|
@@ -30,6 +30,8 @@ export declare abstract class IndexFS extends FileSystem {
|
|
|
30
30
|
protected create(path: string, options: CreationOptions): Inode;
|
|
31
31
|
createFile(path: string, options: CreationOptions): Promise<InodeLike>;
|
|
32
32
|
createFileSync(path: string, options: CreationOptions): InodeLike;
|
|
33
|
+
protected _mkdir?(path: string, options: CreationOptions): Promise<void>;
|
|
34
|
+
protected _mkdirSync?(path: string, options: CreationOptions): void;
|
|
33
35
|
mkdir(path: string, options: CreationOptions): Promise<InodeLike>;
|
|
34
36
|
mkdirSync(path: string, options: CreationOptions): InodeLike;
|
|
35
37
|
link(target: string, link: string): Promise<void>;
|
|
@@ -38,31 +38,56 @@ export class IndexFS extends FileSystem {
|
|
|
38
38
|
to = to.slice(0, -1);
|
|
39
39
|
toRename.push({ from, to, inode });
|
|
40
40
|
}
|
|
41
|
+
toRename.sort((a, b) => b.from.length - a.from.length);
|
|
41
42
|
return toRename;
|
|
42
43
|
}
|
|
43
44
|
async rename(oldPath, newPath) {
|
|
44
45
|
if (oldPath == newPath)
|
|
45
46
|
return;
|
|
46
|
-
|
|
47
|
+
const toRename = this.pathsForRename(oldPath, newPath);
|
|
48
|
+
const contents = new Map();
|
|
49
|
+
for (const { from, to, inode } of toRename) {
|
|
47
50
|
const data = new Uint8Array(inode.size);
|
|
48
51
|
await this.read(from, data, 0, inode.size);
|
|
52
|
+
contents.set(to, data);
|
|
49
53
|
this.index.delete(from);
|
|
54
|
+
await this.remove(from);
|
|
55
|
+
if (this.index.has(to))
|
|
56
|
+
await this.remove(to);
|
|
57
|
+
}
|
|
58
|
+
toRename.reverse();
|
|
59
|
+
for (const { to, inode } of toRename) {
|
|
60
|
+
const data = contents.get(to);
|
|
50
61
|
this.index.set(to, inode);
|
|
51
|
-
|
|
62
|
+
if ((inode.mode & S_IFMT) == S_IFDIR)
|
|
63
|
+
await this._mkdir?.(to, inode);
|
|
64
|
+
else
|
|
65
|
+
await this.write(to, data, 0);
|
|
52
66
|
}
|
|
53
|
-
await this.remove(oldPath);
|
|
54
67
|
}
|
|
55
68
|
renameSync(oldPath, newPath) {
|
|
56
69
|
if (oldPath == newPath)
|
|
57
70
|
return;
|
|
58
|
-
|
|
71
|
+
const toRename = this.pathsForRename(oldPath, newPath);
|
|
72
|
+
const contents = new Map();
|
|
73
|
+
for (const { from, to, inode } of toRename) {
|
|
59
74
|
const data = new Uint8Array(inode.size);
|
|
60
75
|
this.readSync(from, data, 0, inode.size);
|
|
76
|
+
contents.set(to, data);
|
|
61
77
|
this.index.delete(from);
|
|
78
|
+
this.removeSync(from);
|
|
79
|
+
if (this.index.has(to))
|
|
80
|
+
this.removeSync(to);
|
|
81
|
+
}
|
|
82
|
+
toRename.reverse();
|
|
83
|
+
for (const { to, inode } of toRename) {
|
|
84
|
+
const data = contents.get(to);
|
|
62
85
|
this.index.set(to, inode);
|
|
63
|
-
|
|
86
|
+
if ((inode.mode & S_IFMT) == S_IFDIR)
|
|
87
|
+
this._mkdirSync?.(to, inode);
|
|
88
|
+
else
|
|
89
|
+
this.writeSync(to, data, 0);
|
|
64
90
|
}
|
|
65
|
-
this.removeSync(oldPath);
|
|
66
91
|
}
|
|
67
92
|
async stat(path) {
|
|
68
93
|
const inode = this.index.get(path);
|
|
@@ -148,11 +173,15 @@ export class IndexFS extends FileSystem {
|
|
|
148
173
|
}
|
|
149
174
|
async mkdir(path, options) {
|
|
150
175
|
options.mode |= S_IFDIR;
|
|
151
|
-
|
|
176
|
+
const inode = this.create(path, options);
|
|
177
|
+
await this._mkdir?.(path, options);
|
|
178
|
+
return inode;
|
|
152
179
|
}
|
|
153
180
|
mkdirSync(path, options) {
|
|
154
181
|
options.mode |= S_IFDIR;
|
|
155
|
-
|
|
182
|
+
const inode = this.create(path, options);
|
|
183
|
+
this._mkdirSync?.(path, options);
|
|
184
|
+
return inode;
|
|
156
185
|
}
|
|
157
186
|
link(target, link) {
|
|
158
187
|
throw withErrno('ENOSYS');
|
package/dist/mixins/mutexed.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export declare class _MutexedFS<T extends FileSystem> implements FileSystem {
|
|
|
49
49
|
* If the path is currently locked, waits for it to be unlocked.
|
|
50
50
|
* @internal
|
|
51
51
|
*/
|
|
52
|
-
lock(): Promise<MutexLock>;
|
|
52
|
+
lock(timeout?: number): Promise<MutexLock>;
|
|
53
53
|
/**
|
|
54
54
|
* Locks `path` asynchronously.
|
|
55
55
|
* If the path is currently locked, an error will be thrown
|
package/dist/mixins/mutexed.js
CHANGED
|
@@ -135,7 +135,7 @@ export class _MutexedFS {
|
|
|
135
135
|
* If the path is currently locked, waits for it to be unlocked.
|
|
136
136
|
* @internal
|
|
137
137
|
*/
|
|
138
|
-
async lock() {
|
|
138
|
+
async lock(timeout = 5000) {
|
|
139
139
|
const previous = this.currentLock;
|
|
140
140
|
const lock = this.addLock();
|
|
141
141
|
const stack = new Error().stack;
|
|
@@ -145,7 +145,7 @@ export class _MutexedFS {
|
|
|
145
145
|
error.stack += stack?.slice('Error'.length);
|
|
146
146
|
throw err(error);
|
|
147
147
|
}
|
|
148
|
-
},
|
|
148
|
+
}, timeout);
|
|
149
149
|
await previous?.done();
|
|
150
150
|
return lock;
|
|
151
151
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenfs/core",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.11",
|
|
4
4
|
"description": "A filesystem, anywhere",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"format": "prettier --write .",
|
|
61
61
|
"format:check": "prettier --check .",
|
|
62
62
|
"lint": "eslint src tests",
|
|
63
|
-
"test": "npx zenfs-test --clean; npx zenfs-test -
|
|
63
|
+
"test": "npx zenfs-test --clean; npx zenfs-test -abcp; tests/fetch/run.sh; npx zenfs-test --report",
|
|
64
64
|
"build": "tsc -p tsconfig.json",
|
|
65
65
|
"build:docs": "typedoc",
|
|
66
66
|
"dev": "npm run build -- --watch",
|
|
@@ -12,7 +12,7 @@ setupLogs();
|
|
|
12
12
|
const timeoutChannel = new MessageChannel();
|
|
13
13
|
timeoutChannel.port2.unref();
|
|
14
14
|
|
|
15
|
-
await suite('Timeout',
|
|
15
|
+
await suite('Timeout', () => {
|
|
16
16
|
test('Misconfiguration', async () => {
|
|
17
17
|
const configured = configure({
|
|
18
18
|
mounts: {
|
|
@@ -20,11 +20,11 @@ suite('Mutexed FS', () => {
|
|
|
20
20
|
let lock1Resolved = false;
|
|
21
21
|
let lock2Resolved = false;
|
|
22
22
|
|
|
23
|
-
const lock1 = fs.lock().then(lock => {
|
|
23
|
+
const lock1 = fs.lock(100).then(lock => {
|
|
24
24
|
lock1Resolved = true;
|
|
25
25
|
lock.unlock();
|
|
26
26
|
});
|
|
27
|
-
const lock2 = fs.lock().then(lock => {
|
|
27
|
+
const lock2 = fs.lock(100).then(lock => {
|
|
28
28
|
lock2Resolved = true;
|
|
29
29
|
lock.unlock();
|
|
30
30
|
});
|
|
@@ -50,7 +50,7 @@ suite('Mutexed FS', () => {
|
|
|
50
50
|
let x = 1;
|
|
51
51
|
|
|
52
52
|
async function foo() {
|
|
53
|
-
const lock = await fs.lock();
|
|
53
|
+
const lock = await fs.lock(100);
|
|
54
54
|
await wait(25);
|
|
55
55
|
x++;
|
|
56
56
|
lock.unlock();
|