npm package: @jsenv/file-watcher
Description: Watch file changes on your filesystem
Latest version: 1.0.0

# jsenv file watcher

[![github package](https://img.shields.io/github/package-json/v/jsenv/jsenv-file-watcher.svg?logo=github&label=package)](https://github.com/jsenv/jsenv-file-watcher/packages)
[![npm package](https://img.shields.io/npm/v/@jsenv/file-watcher.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/file-watcher)
[![github ci](https://github.com/jsenv/jsenv-file-watcher/workflows/ci/badge.svg)](https://github.com/jsenv/jsenv-file-watcher/actions?workflow=ci)
[![codecov coverage](https://codecov.io/gh/jsenv/jsenv-file-watcher/branch/master/graph/badge.svg)](https://codecov.io/gh/jsenv/jsenv-file-watcher)

Watch file changes on your filesystem.

## Table of contents

- [Presentation](#Presentation)
- [Code example](#code-example)
- [registerDirectoryLifecycle](#registerDirectoryLifecycle)
- [registerFileLifecycle](#registerFileLifecycle)
- [Installation](#Installation)

## Presentation

This repository allows you to watch a given file or directory and be notified when a file is added, updated or removed.

It exists because [fs.watch documentation](https://nodejs.org/docs/latest/api/fs.html#fs_fs_watch_filename_options_listener) says you should not use it directly due to several limitations specific to the filesystem.

[chokidar](https://github.com/paulmillr/chokidar) exists but does it does more then what jsenv needs.

## registerDirectoryLifecycle

> `registerDirectoryLifecycle` is a function watching a `path` and calling `added`, `updated`, `removed` according to what is happening to the directory at that `path` .<br />

Implemented in [src/registerDirectoryLifecycle.js](./src/registerDirectoryLifecycle.js) and could be used as shown below.

```js
import { registerFolderLifecycle } from "@dmail/filesystem-watch"

const folderContentMap = {}
registerFolderLifecycle("/Users/you/folder", {
  added: ({ relativePath, type ) => {
    folderContentMap[relativePath] = type
  },
  removed: ({ relativePath }) => {
    delete folderContentMap[relativePath]
  },
})
```

Usually, filesystem takes less than 100ms to notify something has changed.

### added

> `added` is a function called after file is added in the directory.

This parameters is optional with a default value of:

```js
undefined
```

### updated

> `updated` is a function called after file is updated in the directory.

This parameters is optional with a default value of:

```js
undefined
```

### removed

> `removed` is a function called after file is removed in the directory.

This parameters is optional with a default value of:

```js
undefined
```

### watchDescription

> `watchDescription` in an object used to know what should be watched inside the directory.

This parameter is optional with a default value of:

```js
{
  "/**/*": true,
}
```

The default `watchDescription` watch everything but you should prefer to pass your own like this one for instance:

```js
{
  // exclude everything
  "/**/*": false,
  // include only js files
  "/**/*.js": true,
  // exclude js files inside node_modules
  "/**/node_modules/": false,
}
```

The pattern matching behaviour is documented here: https://github.com/jsenv/jsenv-url-meta#pattern-matching-behaviour

### notifyExistent

> `notifyExistent` is a boolean controlling if `added` is called immediatly for every file already existing inside the directory.

This parameters is optional with a default value of:

```js
false
```

### keepProcessAlive

> `keepProcessAlive` is a boolean controlling if watching directory keeps node process alive or not.

This parameters is optional with a default value of:

```js
true
```

### unregisterDirectoryLifecycle

> `unregisterDirectoryLifecycle` is a function you can call to stop watching.

It is returned by [registerDirectoryLifecycle](#registerDirectoryLifecycle), see below an example:

```js
import { registerDirectoryLifecycle } from "@jsenv/file-watcher"

const unregisterDirectoryLifecycle = registerDirectoryLifecycle("/Users/whatever/", {
  updated: () => {
    console.log("updated")
  },
})
unregisterDirectoryLifecycle()
```

First call to this function cleans up things required to watch file.<br />
Subsequent calls to this function are ignored.

## registerFileLifecycle

> `registerFileLifecycle` is a function watching a `path` and calling `added`, `updated`, `removed` according to what is happening to the file at that `path` .<br />

Implemented in [src/registerFileLifecycle.js](./src/registerFileLifecycle.js) and could be used as shown below.

```js
import { readFileSync } from "fs"
import { registerFileLifecycle } from "@jsenv/file-watcher"

const path = "/Users/whatever/file.json"
let currentConfig = null
registerFileLifecycle(path, {
  added: () => {
    currentConfig = JSON.parse(String(readFileSync(path)))
  },
  updated: () => {
    currentConfig = JSON.parse(String(readFileSync(path)))
  },
  removed: () => {
    currentConfig = null
  },
})
```

Usually, filesystem takes less than 100ms to notify something has changed.

### added

> `added` is a function called after file is added on your filesystem.

This parameters is optional with a default value of:

```js
undefined
```

### updated

> `updated` is a function called after file content or attributes like modification date has changed on your filesystem.

This parameters is optional with a default value of:

```js
undefined
```

### removed

> `removed` is a function called after file is removed from your filesystem.

This parameters is optional with a default value of:

```js
undefined
```

### notifyExistent

> `notifyExistent` is a boolean controlling if `added` is called immediatly when file already exists.

This parameters is optional with a default value of:

```js
false
```

### keepProcessAlive

> `keepProcessAlive` is a boolean controlling if watching file keeps node process alive or not.

This parameters is optional with a default value of:

```js
true
```

### unregisterFileLifecycle

> `unregisterFileLifecycle` is a function you can call to stop watching.

It is returned by [registerFileLifecycle](#registerFileLifecycle), see below an example:

```js
import { registerFileLifecycle } from "@jsenv/file-watcher"

const unregisterFileLifecycle = registerFileLifecycle("/Users/whatever/file.json", {
  updated: () => {
    console.log("updated")
  },
})

unregisterFileLifecycle()
```

First call to this function cleans up things required to watch file.<br />
Subsequent calls to this function are ignored.

## Installation

If you have never installed a jsenv package, read [Installing a jsenv package](https://github.com/jsenv/jsenv-core/blob/master/docs/installing-jsenv-package.md#installing-a-jsenv-package) before going further.

This documentation is up-to-date with a specific version so prefer any of the following commands

```console
npm install --save-dev @jsenv/file-watcher@1.0.0
```

```console
yarn add --dev @jsenv/file-watcher@1.0.0
```