Skip to content

Commit 5dceeca

Browse files
committed
feat: 🎸 normalize write path
1 parent 416b391 commit 5dceeca

2 files changed

Lines changed: 75 additions & 7 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Volume } from '../volume';
2+
import { FsEvent, FsEventType } from '@jsonjoy.com/fs-core';
3+
4+
const setup = () => {
5+
const vol = new Volume();
6+
const events: FsEvent[] = [];
7+
(vol as any)._core.onchange = (e: FsEvent) => events.push(e);
8+
return { vol, events };
9+
};
10+
11+
describe('Volume forwards core events through the public API', () => {
12+
it('writeFileSync emits MODIFY', () => {
13+
const { vol, events } = setup();
14+
vol.writeFileSync('/a.txt', 'hello');
15+
expect(events.some(e => e.type === FsEventType.MODIFY)).toBe(true);
16+
});
17+
18+
it('writeSync(fd) emits MODIFY', () => {
19+
const { vol, events } = setup();
20+
const fd = vol.openSync('/b.txt', 'w');
21+
events.length = 0;
22+
vol.writeSync(fd, Buffer.from('hello'));
23+
vol.closeSync(fd);
24+
expect(events.map(e => e.type)).toContain(FsEventType.MODIFY);
25+
});
26+
27+
it('writevSync(fd) emits MODIFY', () => {
28+
const { vol, events } = setup();
29+
const fd = vol.openSync('/c.txt', 'w');
30+
events.length = 0;
31+
vol.writevSync(fd, [Buffer.from('a'), Buffer.from('b')]);
32+
vol.closeSync(fd);
33+
expect(events.map(e => e.type)).toContain(FsEventType.MODIFY);
34+
});
35+
36+
it('createWriteStream emits MODIFY', done => {
37+
const { vol, events } = setup();
38+
const stream = vol.createWriteStream('/d.txt');
39+
stream.write('hello');
40+
stream.end(() => {
41+
expect(events.map(e => e.type)).toContain(FsEventType.MODIFY);
42+
done();
43+
});
44+
});
45+
46+
it('mkdirSync emits CREATE, rmdirSync emits DELETE', () => {
47+
const { vol, events } = setup();
48+
vol.mkdirSync('/dir');
49+
vol.rmdirSync('/dir');
50+
expect(events.map(e => e.type)).toEqual([FsEventType.CREATE, FsEventType.DELETE]);
51+
});
52+
53+
it('renameSync emits MOVE with both paths', () => {
54+
const { vol, events } = setup();
55+
vol.writeFileSync('/x.txt', '1');
56+
events.length = 0;
57+
vol.renameSync('/x.txt', '/y.txt');
58+
expect(events.length).toBe(1);
59+
expect(events[0].type).toBe(FsEventType.MOVE);
60+
expect(events[0].steps).toEqual(['', 'y.txt']);
61+
expect(events[0].oldSteps).toEqual(['', 'x.txt']);
62+
});
63+
64+
it('metadata ops emit MODIFY via Volume (chmod, utimes)', () => {
65+
const { vol, events } = setup();
66+
vol.writeFileSync('/m.txt', '1');
67+
events.length = 0;
68+
vol.chmodSync('/m.txt', 0o600);
69+
vol.utimesSync('/m.txt', new Date(), new Date());
70+
expect(events.map(e => e.type)).toEqual([FsEventType.MODIFY, FsEventType.MODIFY]);
71+
});
72+
});

packages/fs-node/src/volume.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -448,11 +448,7 @@ export class Volume implements FsCallbackApi, FsSynchronousApi {
448448
};
449449

450450
private _write(fd: number, buf: Buffer, offset?: number, length?: number, position?: number | null): number {
451-
const file = this._core.getFileByFdOrThrow(fd, 'write');
452-
if (file.node.isSymlink()) {
453-
throw createError(ERROR_CODE.EBADF, 'write', file.link.getPath());
454-
}
455-
return file.write(buf, offset, length, position === -1 || typeof position !== 'number' ? undefined : position);
451+
return this._core.write(fd, buf, offset, length, position);
456452
}
457453

458454
public writeSync: {
@@ -513,15 +509,15 @@ export class Volume implements FsCallbackApi, FsSynchronousApi {
513509
};
514510

515511
private writevBase(fd: number, buffers: ArrayBufferView[], position: number | null): number {
516-
const file = this._core.getFileByFdOrThrow(fd);
512+
this._core.getFileByFdOrThrow(fd);
517513
let p = position ?? undefined;
518514
if (p === -1) {
519515
p = undefined;
520516
}
521517
let bytesWritten = 0;
522518
for (const buffer of buffers) {
523519
const nodeBuf = Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength);
524-
const bytes = file.write(nodeBuf, 0, nodeBuf.byteLength, p);
520+
const bytes = this._core.write(fd, nodeBuf, 0, nodeBuf.byteLength, p ?? null);
525521
p = undefined;
526522
bytesWritten += bytes;
527523
if (bytes < nodeBuf.byteLength) break;

0 commit comments

Comments
 (0)