zen-fs / core

A filesystem, anywhere
https://zen-fs.github.io/core/
MIT License
103 stars 14 forks source link

Watch features #6

Closed james-pre closed 1 day ago

james-pre commented 11 months ago

Originally jvilk/BrowserFS#163

By @amir-arad

james-pre commented 10 months ago

Closing this since it is part of #24

james-pre commented 4 months ago

Reopening since this will be done separately from #24, due to the internal API changes that will be needed.

james-pre commented 4 months ago

Noting my thoughts on how the watch features can be implemented, keeping in mind that the goal is to implement the various watch functions:

File changes must be detected and an event dispatched to the listener passed to a watch function.

One easy way to do this would be to have FileSystem extend EventEmitter. Then, some events could be defined.

Perhaps:


interface FileSystemEvent {
    path: string;
    // more can be added
}

abstract class FileSystem extends EventEmitter<Record<'change' | 'rename' | 'create' | 'delete', FileSystemEvent>> {
    //...
}

// Then, an implementation can emit the event

class SomeFS extends FileSystem {
    //...
    async rename(path, /*...*/) {
        this.emit('rename', { path });
        //...
    }
    //...
}

// Finally, the watch functions can listen for these events

interface Watcher {
    path: string
    listener: WatchListener
}

const watchers: Set<Watcher>

function watch(path, listener) {
    watchers.add({ path, listener })
}

// And they will be caught

function watchListener(eventType, event) {
    for(const { path, listener } of watchers) {
        if(event.path != path) { // or some other way to match it
            continue;
        }

        listener({
            eventType,
            filename: path
        });
    }
}

function mount(point, fs) {
    //...
    fs.on('change', (event) => watchListener('change', event));
    fs.on('rename', (event) => watchListener('change', event));
    //...
}
james-pre commented 1 day ago

Note the approach I drafted above was not used, instead the watch features were implemented in the emulation layer.