Voyair
Watches and maintains a persistent, accurate cache of post-processing data pulled from a collection of files on disk.
What that means is that Voyair is for when you have a lot of files that can change often, and you need to perform some sort of computational-heavy work on them to make them usable in your app.
Huh? See Usecase immediately below for an example that should make things clearer on how Voyair can help you.
Uses chokidar for watching (which was the only fsevent library I could find that actually worked as advertised.)
A Usecase
Let's say you have a directory filled with html files.
You want to display a list of contents of the title tags from each file.
You could parse each file to find the <title>
every time you want to display the list and do some sort of caching to disk or you could let Voyair manage it all for you.
Read the "File Processing Example" section at the end of the readme for commented code that illustrates this example a little bit better.
Getting Started
Windows untested but in theory it should work if chokidar supports it.
npm install voyair
var Voyair = ;var voyair = ; // glob (any valid chokidar pattern)voyairstart'./path/to/watch/**/*.html'; // process file and store result in item.data(key, value)voyair; // our data is ready to usevoyair; // by default, writes to ./watched.jsonvoyair;
Options
// default options. overwrite with new Voyair(options) // e.g. new Voyair({ saveDestination: './something-else.json' }) // nonexistent or misspelled options throw // this is where the voyeur snapshot/db is read/written // this file also includes the item.data meta data saveDestination: './watched.json' // should snapshot be pretty printed or not savePretty: true // Automatically persist snapshot to disk every N milliseconds // Falsey to disable saveEvery: 360000 // voyair.get returns entry even if item.expired = true returnExpired: true // If now revision time provided, defaultRevision will be used // Can't think of a reason you'd want to change this but it's here anyway defaultRevision: -Infinity // Logger to use // - Set to logger: Voyair.consoleLogger to log to console // - Falsey disables log // - Any object matching format. See Loggers below logger: null // PROVIDER OPTIONS // See Providers section below for details on providers // Automatically call the provider attached to the file's Item autoProvide: true // A default provider function to assign to all Items defaultProvider: null // How long should provider be given to complete providerTimeout: 5000 // What should happen if provider times out // valid options are: // - fatal: throws // - warn: console.warn // - ignore: noop providerTimeoutOutcome: 'warn' ;
Loggers
A console logger is included with Voyair and the source is below. You could also pass a bunyan instance as the logger option or any other object that matches the format.
VoyairconsoleLogger = info: consoleinfo warn: consolewarn error: consoleerror debug: consolelog log: consolelog;
Providers
In addition to events, Voyair provides a mechanism known as "providers" for dealing with processing files.
A provider is basically a function that gets called every time a file's meta data needs updating. It's a little bit like a combination of item:created and item:expired in one, but has some extra functionality with timeouts built on top of it.
In most cases, you'll probably be happier with using providers instead of juggling the item:*
events. Either works, though with providers there is a bit more to understand.
Serializing/Unserializing Meta Data
If the meta data you're storing needs some sort of serialization before being converted to json, be sure to add a toJSON
method to your object.
To unserialze data from json, an item:imported
event is called for each item being loaded from disk at which point you can do the unserializing.
Status / Todo
As far as I know things are pretty complete and working well. I've been using this with my static site generator fancy with positive results.
Here's the list of things that could be better:
- Tests, of course. There are some minimal tests and a lot of placeholders
- confirm adding/removing entire directories works (it seems to)
- confirm providers work as expected (they seem to)
- Windows testing
File Processing Example
Using the example we started above, we have a directory of *.html files that change often and we want to keep an accurate list of what their <title>
tags are.
// note: this snippet is untestedvar fs = ;var voyair = ; // Starts watching the glob pattern (passed directly to chokidar so those options apply)voyairstart'./**/*.html'; // As new files are discovered and created inside Voyair, item:created events are fired for each // Once voyair knows about a file, it will not fire item:created again unless the // file becomes invalid // item:created is where you want to do your file processing. In our case we're// grabbing the title tag, but it could just as easily be generating a thumbnail // from a video or some other CPU-heavy taskvoyair; // if a file is already known and unmodified, item:current fires instead of item:createvoyair; // or alternatively, you could retrieve an entry by relative path once Voyair is ready:voyair; // These are all the item:* (file) events:// 'item:imported', -- When reloading/importing a snapshot, item:imported fires for each entry regardless of state// 'item:created', -- Fires once for each new/changed/expired file// 'item:current', -- Fires instead of item:created for known files// 'item:expired', -- Fires when a file has changed or otherwise become invalid/expired// 'item:removed', -- File deleted. Fires immediately prior to entry being removed from snapshot // There are also a few watcher:* events that bubble from chokidar// See examples/development.js // When shutting down the Voyair snapshot/database will persist to diskvoyair; // by default, writes to ./watched.json process;
License
Copyright (c) 2015 Cory Mawhorter Licensed under the MIT license.