filespy

This module is a wrapper around the erlang FS library. It allows you to create a listener for file change events for any operating system.

Note: on Linux and BSD, you need inotify-tools installed.

Types

Handler function used with an actor handler

pub type ActorHandler(a) =
  fn(Change, a) -> actor.Next(Change, a)

Opaque builder type to instantiate the listener

Instantiate it with new.

pub opaque type Builder(a, d, h, s)

A filesystem change

pub type Change {
  Change(path: String, events: List(Event))
}

Constructors

  • Change(path: String, events: List(Event))

Possible filesystem events

pub type Event {
  Created
  Modified
  Closed
  Deleted
  Renamed
  Attribute
  Unknown(Atom)
}

Constructors

  • Created
  • Modified
  • Closed
  • Deleted
  • Renamed
  • Attribute
  • Unknown(Atom)

Handler function called when an event is detected

pub type Handler =
  fn(String, Event) -> Nil

Phantom type to indicate the Builder has directories

pub type HasDirectories

Phantom type to indicate the Builder has a handler

pub type HasHandler

Phantom type to indicate the Builder has an initial state

pub type HasInitialState

Phantom type to indicate the Builder has no directories

pub type NoDirectories

Phantom type to indicate the Builder has no handlers

pub type NoHandler

Phantom type to indicate the Builder has no initial state

pub type NoInitialState

Functions

pub fn add_dir(builder: Builder(a, b, c, d), directory: String) -> Builder(
  a,
  HasDirectories,
  c,
  d,
)

Add a directory to watch

Examples

filespy.new()
|> filespy.add_dir("./watched")
pub fn add_dirs(builder: Builder(a, b, c, d), directories: List(
    String,
  )) -> Builder(a, HasDirectories, c, d)

Add multiple directories at once

pub fn new() -> Builder(
  a,
  NoDirectories,
  NoHandler,
  NoInitialState,
)

Create a new builder

Use this with the add_dir and handler functions to configure the watcher

pub fn selector() -> Selector(Change)

Get a Selector which can be used to select for filesystem events.

pub fn set_actor_handler(builder: Builder(a, b, NoHandler, c), handler: fn(
    Change,
    a,
  ) -> Next(Change, a)) -> Builder(a, b, HasHandler, c)

Set the actor handler

Use this if you want to have a more thorough control over the generated actor. You will also need to set an initial state, with set_initial_state.

pub fn set_handler(builder: Builder(
    Nil,
    a,
    NoHandler,
    NoInitialState,
  ), handler: fn(String, Event) -> Nil) -> Builder(
  Nil,
  a,
  HasHandler,
  HasInitialState,
)

Set the handler

Examples

filespy.new()
|> filespy.add_dir("./watched")
|> filespy.set_handler(fn (path: String, event: filespy.Event) {
    case event {
      filespy.Created -> {
        io.println("File " <> path <> " created")
      }
      _ -> {
        io.println("Something else happened to " <> path)
      }
  }
})
pub fn set_initial_state(builder: Builder(a, b, c, NoInitialState), state: a) -> Builder(
  a,
  b,
  c,
  HasInitialState,
)

Set the initial state

Use this if you want to have a more thorough control over the generated actor. You’ll only have access to this state if you set your handler with set_actor_handler.

pub fn set_initializer(builder: Builder(a, b, c, NoInitialState), initializer: fn() ->
    a) -> Builder(a, b, c, HasInitialState)

Set the initializer

Use this if you want to, for example, return a subject in the state. The initializer will run in the actor’s on_init, so it’ll run under the watcher process

pub fn spec(builder: Builder(
    a,
    HasDirectories,
    HasHandler,
    HasInitialState,
  )) -> Spec(a, Change)

Get an actor Spec for the watcher

pub fn start(builder: Builder(
    a,
    HasDirectories,
    HasHandler,
    HasInitialState,
  )) -> Result(Subject(Change), StartError)

Start an actor which will receive filesystem events

In order for this to work, you’ll need to have set some directories to be watched, with add_dir, and set a handler with either set_handler or set_actor_handler and set_initial_state.

Search Document