Skip to content

Commit 2aec586

Browse files
committed
feat: 🎸 use FanOut for Link reactivity
1 parent 16b2b42 commit 2aec586

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

src/core/Link.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
1-
import { EventEmitter } from 'events';
21
import { constants, PATH } from '../constants';
2+
import { FanOut } from 'thingies/lib/fanout';
33
import type { Node } from './Node';
44
import type { Superblock } from './Superblock';
55

6+
export interface LinkEventChildAdd {
7+
type: 'child:add';
8+
link: Link;
9+
parent: Link;
10+
}
11+
12+
export interface LinkEventChildDelete {
13+
type: 'child:delete';
14+
link: Link;
15+
parent: Link;
16+
}
17+
18+
export type LinkEvent = LinkEventChildAdd | LinkEventChildDelete;
19+
620
const { S_IFREG } = constants;
721

822
/**
923
* Represents a hard link that points to an i-node `node`.
1024
*/
11-
export class Link extends EventEmitter {
25+
export class Link {
26+
public readonly changes = new FanOut<LinkEvent>();
27+
1228
vol: Superblock;
1329

1430
parent: Link | undefined;
@@ -45,7 +61,6 @@ export class Link extends EventEmitter {
4561
}
4662

4763
constructor(vol: Superblock, parent: Link | undefined, name: string) {
48-
super();
4964
this.vol = vol;
5065
this.parent = parent;
5166
this.name = name;
@@ -87,7 +102,7 @@ export class Link extends EventEmitter {
87102
}
88103

89104
this.getNode().mtime = new Date();
90-
this.emit('child:add', link, this);
105+
this.changes.emit({ type: 'child:add', link, parent: this });
91106

92107
return link;
93108
}
@@ -102,7 +117,7 @@ export class Link extends EventEmitter {
102117
this.length--;
103118

104119
this.getNode().mtime = new Date();
105-
this.emit('child:delete', link, this);
120+
this.changes.emit({ type: 'child:delete', link, parent: this });
106121
}
107122

108123
getChild(name: string): Link | undefined {

src/node/volume.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as pathModule from 'path';
2+
import { FanOutUnsubscribe } from 'thingies/lib/fanout';
23
import { Link, Superblock } from '../core';
34
import Stats from './Stats';
45
import Dirent from './Dirent';
@@ -2058,13 +2059,14 @@ export class FSWatcher extends EventEmitter {
20582059
}
20592060
}
20602061
// link children add/remove
2061-
link.on('child:add', onLinkChildAdd);
2062-
link.on('child:delete', onLinkChildDelete);
2062+
const unsubscribeLinkChanges = link.changes.listen((event) => {
2063+
if (event.type === 'child:add') onLinkChildAdd(event.link);
2064+
else if (event.type === 'child:delete') onLinkChildDelete(event.link);
2065+
});
20632066

20642067
const removers = this._listenerRemovers.get(node.ino) ?? [];
20652068
removers.push(() => {
2066-
link.removeListener('child:add', onLinkChildAdd);
2067-
link.removeListener('child:delete', onLinkChildDelete);
2069+
unsubscribeLinkChanges();
20682070
});
20692071

20702072
if (recursive) {
@@ -2080,26 +2082,23 @@ export class FSWatcher extends EventEmitter {
20802082

20812083
const parent = this._link.parent;
20822084
if (parent) {
2083-
// parent.on('child:add', this._onParentChild);
2084-
parent.setMaxListeners(parent.getMaxListeners() + 1);
2085-
parent.on('child:delete', this._onParentChild);
2085+
// parent.on('child:delete', this._onParentChild);
2086+
parent.changes.listen((event) => {
2087+
if (event.type === 'child:delete') this._onParentChild(event.link);
2088+
});
20862089
}
20872090

20882091
if (persistent) this._persist();
20892092
}
20902093

2094+
protected _parentChangesUnsub: FanOutUnsubscribe;
2095+
20912096
close() {
20922097
clearTimeout(this._timer);
2093-
20942098
this._listenerRemovers.forEach(removers => {
20952099
removers.forEach(r => r());
20962100
});
20972101
this._listenerRemovers.clear();
2098-
2099-
const parent = this._link.parent;
2100-
if (parent) {
2101-
// parent.removeListener('child:add', this._onParentChild);
2102-
parent.removeListener('child:delete', this._onParentChild);
2103-
}
2102+
this._parentChangesUnsub?.();
21042103
}
21052104
}

0 commit comments

Comments
 (0)