@zenfs/core 1.10.0 → 1.10.2
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/{overlay.d.ts → cow.d.ts} +91 -41
- package/dist/backends/{overlay.js → cow.js} +136 -196
- package/dist/backends/index.d.ts +1 -1
- package/dist/backends/index.js +1 -1
- package/dist/backends/port/fs.js +1 -1
- package/dist/backends/single_buffer.js +4 -4
- package/dist/backends/store/fs.js +3 -3
- package/dist/index.d.ts +1 -7
- package/dist/index.js +2 -0
- package/dist/internal/devices.js +1 -1
- package/dist/internal/file.js +7 -7
- package/dist/internal/log.d.ts +6 -5
- package/dist/internal/log.js +48 -7
- package/dist/mixins/async.js +21 -25
- package/dist/mixins/shared.d.ts +2 -2
- package/dist/polyfills.d.ts +0 -4
- package/dist/polyfills.js +16 -13
- package/dist/vfs/async.js +42 -19
- package/dist/vfs/promises.d.ts +7 -13
- package/dist/vfs/promises.js +55 -58
- package/dist/vfs/shared.js +2 -2
- package/dist/vfs/streams.d.ts +2 -2
- package/dist/vfs/streams.js +24 -18
- package/dist/vfs/sync.js +5 -5
- package/package.json +3 -3
- package/readme.md +1 -4
- package/tests/common/mutex.test.ts +1 -1
- package/tests/fetch/server.js +1 -1
- package/tests/fs/directory.test.ts +11 -59
- package/tests/fs/errors.test.ts +1 -1
- package/tests/fs/stat.test.ts +2 -6
- package/tests/fs/streams.test.ts +71 -66
- package/tests/setup/cow.ts +13 -0
- package/tests/tsconfig.json +1 -4
- package/types/README.md +1 -0
- package/types/readable-stream.d.ts +17 -0
- package/tests/setup/_overlay.ts +0 -7
package/tests/fs/streams.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { suite, test } from 'node:test';
|
|
3
3
|
import { fs } from '../common.js';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
4
5
|
|
|
5
6
|
// Top-level initialization
|
|
6
7
|
const testFilePath = 'test-file.txt';
|
|
@@ -10,9 +11,10 @@ await fs.promises.writeFile(testFilePath, testData);
|
|
|
10
11
|
const testFilePathWrite = 'test-file-write.txt';
|
|
11
12
|
await fs.promises.writeFile(testFilePathWrite, ''); // Ensure the file exists
|
|
12
13
|
|
|
13
|
-
suite('
|
|
14
|
+
suite('Streams', () => {
|
|
14
15
|
test('ReadStream reads data correctly', (_, done) => {
|
|
15
16
|
const readStream = fs.createReadStream(testFilePath);
|
|
17
|
+
|
|
16
18
|
let data = '';
|
|
17
19
|
readStream.on('data', chunk => {
|
|
18
20
|
data += chunk;
|
|
@@ -28,12 +30,14 @@ suite('ReadStream', () => {
|
|
|
28
30
|
|
|
29
31
|
test('ReadStream close method works', (_, done) => {
|
|
30
32
|
const readStream = fs.createReadStream(testFilePath);
|
|
33
|
+
|
|
31
34
|
let closed = false;
|
|
32
35
|
readStream.on('close', () => {
|
|
33
36
|
closed = true;
|
|
34
37
|
});
|
|
38
|
+
|
|
35
39
|
readStream.close(err => {
|
|
36
|
-
assert.
|
|
40
|
+
assert.ifError(err);
|
|
37
41
|
assert(closed);
|
|
38
42
|
done();
|
|
39
43
|
});
|
|
@@ -55,36 +59,24 @@ suite('ReadStream', () => {
|
|
|
55
59
|
assert(!readStream.pending);
|
|
56
60
|
});
|
|
57
61
|
|
|
58
|
-
test('ReadStream close method can be called multiple times', (
|
|
62
|
+
test('ReadStream close method can be called multiple times', async () => {
|
|
59
63
|
const readStream = new fs.ReadStream();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
assert.equal(err2, null);
|
|
65
|
-
done();
|
|
66
|
-
});
|
|
67
|
-
});
|
|
64
|
+
|
|
65
|
+
const close = promisify(readStream.close);
|
|
66
|
+
await close();
|
|
67
|
+
await close();
|
|
68
68
|
});
|
|
69
|
-
});
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
test.skip('WriteStream writes data correctly', (_, done) => {
|
|
70
|
+
test('WriteStream writes data correctly', async () => {
|
|
73
71
|
const writeStream = fs.createWriteStream(testFilePathWrite);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
assert(fs.readFileSync(testFilePathWrite, 'utf8') == testData);
|
|
83
|
-
done();
|
|
84
|
-
});
|
|
85
|
-
writeStream.on('error', err => {
|
|
86
|
-
done(err);
|
|
87
|
-
});
|
|
72
|
+
|
|
73
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
74
|
+
writeStream.on('finish', resolve);
|
|
75
|
+
writeStream.on('error', reject);
|
|
76
|
+
writeStream.end(testData, 'utf8');
|
|
77
|
+
await promise;
|
|
78
|
+
|
|
79
|
+
assert.equal(fs.readFileSync(testFilePathWrite, 'utf8'), testData);
|
|
88
80
|
});
|
|
89
81
|
|
|
90
82
|
test('WriteStream close method works', (_, done) => {
|
|
@@ -94,7 +86,7 @@ suite('WriteStream', () => {
|
|
|
94
86
|
closed = true;
|
|
95
87
|
});
|
|
96
88
|
writeStream.close(err => {
|
|
97
|
-
assert.
|
|
89
|
+
assert.ifError(err);
|
|
98
90
|
assert(closed);
|
|
99
91
|
done();
|
|
100
92
|
});
|
|
@@ -116,62 +108,75 @@ suite('WriteStream', () => {
|
|
|
116
108
|
assert(writeStream.pending);
|
|
117
109
|
});
|
|
118
110
|
|
|
119
|
-
test('WriteStream close method can be called multiple times', (
|
|
111
|
+
test('WriteStream close method can be called multiple times', async () => {
|
|
120
112
|
const writeStream = new fs.WriteStream();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
assert.equal(err2, null);
|
|
126
|
-
done();
|
|
127
|
-
});
|
|
128
|
-
});
|
|
113
|
+
|
|
114
|
+
const close = promisify(writeStream.close);
|
|
115
|
+
await close();
|
|
116
|
+
await close();
|
|
129
117
|
});
|
|
130
|
-
});
|
|
131
118
|
|
|
132
|
-
|
|
133
|
-
|
|
119
|
+
test('createReadStream with start', async () => {
|
|
120
|
+
await fs.promises.writeFile('hello.txt', 'Hello world');
|
|
121
|
+
|
|
122
|
+
const stream = fs.createReadStream('hello.txt', { start: 6, encoding: 'utf-8' });
|
|
123
|
+
|
|
124
|
+
const data = (await stream.toArray()).join('');
|
|
125
|
+
|
|
126
|
+
assert.equal(data, 'world');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('createReadStream with end', async () => {
|
|
130
|
+
await fs.promises.writeFile('hello.txt', 'Hello world');
|
|
131
|
+
|
|
132
|
+
const stream = fs.createReadStream('hello.txt', { end: 5, encoding: 'utf-8' });
|
|
133
|
+
|
|
134
|
+
const data = (await stream.toArray()).join('');
|
|
135
|
+
|
|
136
|
+
assert.equal(data, 'Hello');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('FileHandle.createReadStream reads data correctly', async () => {
|
|
134
140
|
const fileHandle = await fs.promises.open(testFilePath, 'r');
|
|
135
|
-
const readStream = fileHandle.createReadStream();
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
readStream.on('data', chunk => {
|
|
139
|
-
data += chunk;
|
|
140
|
-
});
|
|
141
|
-
readStream.on('end', () => {
|
|
142
|
-
assert.equal(data, testData);
|
|
143
|
-
resolve();
|
|
144
|
-
});
|
|
145
|
-
readStream.on('error', reject);
|
|
146
|
-
});
|
|
141
|
+
const readStream = fileHandle.createReadStream({ encoding: 'utf-8' });
|
|
142
|
+
const [data] = await readStream.toArray();
|
|
143
|
+
assert.equal(data, testData);
|
|
147
144
|
await fileHandle.close();
|
|
148
145
|
});
|
|
149
146
|
|
|
150
|
-
test
|
|
147
|
+
test('FileHandle.createWriteStream writes data correctly', async () => {
|
|
151
148
|
const fileHandle = await fs.promises.open(testFilePathWrite, 'w');
|
|
152
149
|
const writeStream = fileHandle.createWriteStream();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
});
|
|
150
|
+
|
|
151
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
152
|
+
writeStream.on('finish', resolve);
|
|
153
|
+
writeStream.on('error', reject);
|
|
154
|
+
writeStream.end(testData, 'utf8');
|
|
155
|
+
await promise;
|
|
156
|
+
|
|
161
157
|
const data = await fs.promises.readFile(testFilePathWrite, 'utf8');
|
|
162
158
|
assert.equal(data, testData);
|
|
163
159
|
await fileHandle.close();
|
|
164
160
|
});
|
|
165
161
|
|
|
166
|
-
test('FileHandle.createReadStream after close should
|
|
162
|
+
test('FileHandle.createReadStream after close should give an error', async () => {
|
|
167
163
|
const fileHandle = await fs.promises.open(testFilePath, 'r');
|
|
168
164
|
await fileHandle.close();
|
|
169
|
-
|
|
165
|
+
const stream = fileHandle.createReadStream();
|
|
166
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
167
|
+
setTimeout(resolve, 100);
|
|
168
|
+
stream.on('error', reject);
|
|
169
|
+
assert.rejects(promise);
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
-
test
|
|
172
|
+
test('FileHandle.createWriteStream after close should give an error', async () => {
|
|
173
173
|
const fileHandle = await fs.promises.open(testFilePathWrite, 'w');
|
|
174
174
|
await fileHandle.close();
|
|
175
|
-
|
|
175
|
+
const stream = fileHandle.createWriteStream();
|
|
176
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
177
|
+
setTimeout(resolve, 100);
|
|
178
|
+
stream.on('error', reject);
|
|
179
|
+
assert.rejects(promise);
|
|
180
|
+
stream.write('Nuh-uh');
|
|
176
181
|
});
|
|
177
182
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { configureSingle, InMemory, CopyOnWrite, resolveMountConfig, fs } from '../../dist/index.js';
|
|
2
|
+
import { copySync, data } from '../setup.js';
|
|
3
|
+
|
|
4
|
+
fs.umount('/');
|
|
5
|
+
const readable = await resolveMountConfig({ backend: InMemory, label: 'ro' });
|
|
6
|
+
fs.mount('/', readable);
|
|
7
|
+
copySync(data);
|
|
8
|
+
|
|
9
|
+
await configureSingle({
|
|
10
|
+
backend: CopyOnWrite,
|
|
11
|
+
readable,
|
|
12
|
+
writable: InMemory.create({ label: 'cow' }),
|
|
13
|
+
});
|
package/tests/tsconfig.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "../tsconfig.json",
|
|
2
3
|
"type": "module",
|
|
3
4
|
"compilerOptions": {
|
|
4
|
-
"module": "NodeNext",
|
|
5
5
|
"target": "ES2022",
|
|
6
6
|
"noEmit": true,
|
|
7
|
-
"lib": ["ESNext", "ESNext.Disposable"],
|
|
8
|
-
"moduleResolution": "NodeNext",
|
|
9
7
|
"esModuleInterop": true,
|
|
10
8
|
"allowSyntheticDefaultImports": true,
|
|
11
|
-
"strict": true,
|
|
12
9
|
"allowJs": true
|
|
13
10
|
},
|
|
14
11
|
"include": ["**/*.ts", "*.ts", "**/*.js"]
|
package/types/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This directory contains declaration files. Due to numerous TypeScript shenanigans, placing them into `src` is a really bad idea. Instead, we put them here.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
@types/readable-stream has *many* problems:
|
|
3
|
+
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/71923
|
|
4
|
+
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/71307
|
|
5
|
+
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/71083
|
|
6
|
+
https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/66049
|
|
7
|
+
... and many more
|
|
8
|
+
|
|
9
|
+
This allows us to bypass those problems.
|
|
10
|
+
|
|
11
|
+
Warning: Do not install @types/readable-stream alongside this package!
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
declare module 'readable-stream' {
|
|
15
|
+
import { Readable, Writable } from 'node:stream';
|
|
16
|
+
export { Readable, Writable };
|
|
17
|
+
}
|