update docs

This commit is contained in:
Conduitry 2018-03-09 06:27:49 -05:00
parent 91630bb21a
commit c5d37bedd0
2 changed files with 23 additions and 34 deletions

34
API.md
View File

@ -67,9 +67,9 @@ A new `Defiler` instance to represent a collection of physical files and virtual
- `watch` - _(optional)_ whether to actually watch the directory for changes. Defaults to `true`. If `false`, the files will still be run through the transform, but any changes to them will not be
- `debounce` - _(optional)_ The length of the timeout in milliseconds to use to debounce incoming events from `fs.watch`. Defaults to 10. Multiple events are often emitted for a single change, and events can also be emitted before `fs.stat` reports the changes. Defiler will wait until `debounce` milliseconds have passed since the last `fs.watch` event for a file before handling it. The default of 10ms Works On My Machine
- Transform configuration
- `transform({ defiler, file, get })` - a transform function, which is passed an object containing the `Defiler` instance, the `File` instance to mutate, and a function `get(path)` (see [the `get(path)` function](#the-getpath-function)). The transform function can return a `Promise` to indicate when it's done
- `transform({ defiler, file })` - a transform function, which is passed an object containing the `Defiler` instance and the `File` instance to mutate. The transform function can return a `Promise` to indicate when it's done
- Generator configuration
- `generators` - an array of generator functions, each of the form `generator({ defiler, get })`. Each generator is passed an object containing the `Defiler` instance and a function `get(path)` (see [the `get(path)` function](#the-getpath-function)). Each generator function can return a `Promise` to indicate when it's done
- `generators` - an array of generator functions, each of the form `generator({ defiler })`. Each generator is passed an object containing the `Defiler` instance. Each generator function can return a `Promise` to indicate when it's done
## Properties
@ -81,29 +81,15 @@ A `Set` of the original relative paths of all of the physical files. (This does
A `Map` of original relative paths to `File` instances for the transformed files. (This includes physical and virtual files.) During the initial wave of processing, this will only contain the files that are done being transformed.
## Execution
## Methods
### `exec()`
Start the Defiler running. Returns a promise that resolves when the initial wave of processing is complete.
## Operation
### `get(path)`
### `add(file)`
Manually insert a virtual `File`, running it through the transform.
For convenience, you can also call this with a plain old JavaScript object, and a new `File` instance will be created for you with properties `Object.assign`ed from the object.
### `depend(dependent, path)`
Manually register that `dependent` depends on `path`. When the file at `path` changes, the file at `dependent` will be automatically re-transformed.
Defiler will typically call this automatically (via [the `get(path)` function](#the-getpath-function)), and so you shouldn't need to call it unless you're doing something peculiar.
## The `get(path)` function
The transform and generators are all passed a `get` function. This waits for a file or array of files to be ready and retrieves the `File` instance(s).
Wait for a file or array of files to be ready and retrieve the `File` instance(s).
- `path` - the path, or array of paths, to wait for to become available and to then return
@ -111,7 +97,15 @@ Returns a `Promise` resolving to the `File` instance or an array of `File` insta
This can be asked for physical or virtual files. If you ask for a file during the initial wave of processing before it is available, Defiler will wait for the file to be ready and transformed. If it ever happens that every in-progress file is waiting for a file to become available, the deadlock will be broken by Defiler resolving all of the pending `File`s to `undefined`. This may happen multiple times during the initial wave of processing.
When used in your transform, this will also register the file being transformed as depending on the file or files in `path`, using the [`depend` method](#dependdependent-path). Once the initial wave of processing is complete, any changes to dependencies will cause their dependents to be re-transformed. When used in a generator, this will register the generator as depending on the file on files in `path`, and any changes to dependencies will cause the generator to be re-run.
When used in your transform, this will also register the file being transformed as depending on the file or files in `path`. Once the initial wave of processing is complete, any changes to dependencies will cause their dependents to be re-transformed. When used in a generator, this will register the generator as depending on the file on files in `path`, and any changes to dependencies will cause the generator to be re-run.
### `add(file)`
Manually insert a virtual `File`, running it through the transform.
- `file` - the `File` object (or plain old JavaScript object) representing the virtual file to add
For convenience, you can call this with a POJO, and a new `File` instance will be created for you with properties `Object.assign`ed from the object.
## Events

View File

@ -14,29 +14,29 @@ See the [API docs](API.md#file) for more information.
Every file (physical and virtual) is run through the transform function you register with Defiler. The transform mutates the object representing the file in-place, and returns a promise indicating when it's finished.
The transform is called, for each file, with an object containing `defiler` (the `Defiler` instance), `file` (the `File` instance), and a `get` function (see [dependence](#dependence)). The transform should mutate the `file` object as it sees fit. It can also take whichever actions it wishes based on the file (including, for example, writing output to disk). Files' paths can be changed as they're transformed, but the main way to refer to them will continue to be by their original path (see [dependence](#dependence)).
The transform is called, for each file, with an object containing `defiler` (the `Defiler` instance) and `file` (the `File` instance). The transform should mutate the `file` object as it sees fit. It can also take whichever actions it wishes based on the file (including, for example, writing output to disk). Files' paths can be changed as they're transformed, but the main way to refer to them will continue to be by their original path (see [dependence](#dependence)).
## Dependence
Files can be made to depend on other files, so that changes to a dependency cause the dependent to be re-transformed. For physical files, the file does not need to be re-read from the disk before it can be re-transformed, as the original version is kept in memory.
The `get` function passed to the transform lets you depend on and retrieve other transformed files. It should be passed the original path of a file, and will return a `Promise` resolving to the transformed `File` instance. If the requested file does not exist (or if you have a deadlock via a system of mutually-depending files, none of which will continue transforming until another one finishes), the `Promise` will resolve to `undefined`.
The `defiler.get(path)` method, when used inside the transform, lets you depend on and retrieve other transformed files. It should be passed the original path of a file, and will return a `Promise` resolving to the transformed `File` instance. If the requested file does not exist (or if you have a deadlock via a system of mutually-depending files, none of which will continue transforming until another one finishes), the `Promise` will resolve to `undefined`.
The `get` function can also be passed an array of (original) paths, in which case it will return a `Promise` resolving to an array of `File` instances (or `undefined`s).
The `defiler.get` method can also be passed an array of (original) paths, in which case it will return a `Promise` resolving to an array of `File` instances (or `undefined`s).
See the [API docs](API.md#the-getpath-function) for more information.
See the [API docs](API.md#getpath) for more information.
## Virtual files
During the transform's processing of a file, you can also create virtual files, which don't directly correspond one-to-one with physical files. The `Defiler` instance has an `add(file)` method, which you can pass a `File` instance to (or a POJO, which will be turned into a `File`). The virtual file will run through the transform and will thereafter be treated pretty much like a physical file. In particular, you can make other files depend on it with `get`.
During the transform's processing of a file, you can also create virtual files, which don't directly correspond one-to-one with physical files. The `Defiler` instance has a `defiler.add(file)` method, which you can pass a `File` instance to (or a POJO, which will be turned into a `File`). The virtual file will run through the transform and will thereafter be treated pretty much like a physical file. In particular, you can make other files depend on it with `defiler.get(path)`.
Since Defiler has no way of knowing which virtual files will be created from transforming which files, when `get` is used to request a file that doesn't exist yet, Defiler waits until it does get created. Requesting a file that's never going to exist would cause a deadlock, so Defiler resolves this as a generalization of the above-mentioned deadlock resolution: If it ever happens that every in-process action is waiting for some other transformed file to exist, Defiler will resolve each of those pending `Promise`s returned by `get` to `undefined`.
Since Defiler has no way of knowing which virtual files will be created from transforming which files, when `defiler.get` is used to request a file that doesn't exist yet, Defiler waits until it does get created. Requesting a file that's never going to exist would cause a deadlock, so Defiler resolves this as a generalization of the above-mentioned deadlock resolution: If it ever happens that every in-process action is waiting for some other transformed file to exist, Defiler will resolve each of those pending `Promise`s returned by `defiler.get` to `undefined`.
## Generators
Generators are an independent way of interacting with the Defiler instance, for things that do not fit well into the main transform. Each generator is a function that accepts one argument, an object containing `defiler` and `get`. A generator would typically call `get` and/or `defiler.add` to retrieve dependencies and write new virtual files. Automatic dependence handling also works here, so when one of the files retrieved by `get` changes, that generator will be re-run.
Generators are an independent way of interacting with the Defiler instance, for things that do not fit well into the main transform. Each generator is a function that accepts one argument, an object containing `defiler`. A generator would typically call `defiler.get` and/or `defiler.add` to retrieve dependencies and write new virtual files. Automatic dependence handling also works here, so when one of the files retrieved by `defiler.get` changes, that generator will be re-run.
It's beneficial to write more, smaller generators, rather than one monolithic ones. This helps ensure that more work than needed is not done when a file changes.
It's beneficial to write multiple smaller generators, rather than one monolithic ones. This helps ensure that unneeded recalculation is not done when a file changes.
# Usage
@ -48,14 +48,9 @@ Useful things available on the `Defiler` instance for you to use in the transfor
- [`defiler.paths`](API.md#paths-1) - a `Set` of the paths of all of the physical files
- [`defiler.files`](API.md#files) - a `Map` of original paths to the transformed `File` instances
- [`defiler.get(path)`](API.md#getpath) - a method to retrieve one or more transformed `File`s based on their original paths
- [`defiler.add(file)`](API.md#addfile) - a method to add a virtual file, which is then transformed like a physical one is, and which can be depended on by other files
Also:
- [`get(path)`](API.md#the-getpath-function) - not a method on the `Defiler` instance, but a function that is passed to the transform and to the generators, which retrieves one or more transformed `File`s based on their original paths
The `Defiler` instance also [emits some events](API.md#events) you can listen for.
# In closing
See [the API docs](API.md#readme) for more information, and for a couple of other things not covered here.