lazy and monadic file systems
██████████████████████████████████████
██████████████████████████████████████
██████████████████████████████████████
██ ██████████████████████████████████
█ ██ ██ █ █ ███ ██ █ █
██ ██ █ █ █ █ █ █ █
██ ██ █ █ █████ █ █ █ █ █████
██ ██ █ █ █████ █ █ █ █ █████
██ ██ █ █ █████ █ █ █ █ █████
██ ██ ██ █████ ███ ██ █████
███████████████████ █████████████████
███████████████████ █████████████████
███████████████████ █████████████████
██████████████████████████████████████
██████████████████████████████████████
- multiple potential input sources
- lazy execution and cancellable asynchronous operations
- excellent error handling
- parallel execution if wanted
#### Table of Contents
- TypedArray
- chainRej
- close
- Parameters
- fdatasync
- Parameters
- fsync
- Parameters
- rmdir
- Parameters
- unlink
- Parameters
- access
- Parameters
- chmod
- Parameters
- fchmod
- Parameters
- fstat
- Parameters
- lchmod
- Parameters
- link
- Parameters
- mkdir
- Parameters
- rename
- Parameters
- appendFile
- Parameters
- chown
- Parameters
- copyFile
- Parameters
- fchown
- Parameters
- futimes
- Parameters
- lchown
- Parameters
- symlink
- Parameters
- utimes
- Parameters
- writeFile
- Parameters
- Future
- Properties
- readAnyWithFormatOr
- Parameters
- readAnyWithFormat
- Parameters
- readAny
- Parameters
- callbackToTheFuture
- Parameters
- Examples
- proxifyN
- Parameters
- Examples
It's a TypedArray
Type: Object
It's a Future!
Type: Object
- **See:
for the source function this function wraps.
**
Wraps fs.close
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous close(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
#### Parameters
- fd number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.fdatasync
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous fdatasync(2).
>
> No arguments other than a possible exception are
> given to the completion callback.
#### Parameters
- fd number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.fsync
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous fsync(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
#### Parameters
- fd number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.rmdir
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous rmdir(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
>
> Using fs.rmdir() on a file (not a directory) results in an ENOENT error on
> Windows and an ENOTDIR error on POSIX.
#### Parameters
- path (string \| Buffer \| URL) \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.unlink
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously removes a file or symbolic link.
>
> No arguments other than a
> possible exception are given to the completion callback.
>
> // Assuming that 'path/file.txt' is a regular file..
> fs.unlink('path/file.txt', (err) => {
> if (err) throw err;
> console.log('path/file.txt was deleted');
> });
>
>
> fs.unlink() will not work on a directory, empty or otherwise.
>
> To remove a
> directory, use fs.rmdir().
>
> See also: unlink(2).
#### Parameters
- path (string \| Buffer \| URL) \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.access
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Tests a user's permissions for the file or directory specified by path.
> The mode argument is an optional number that specifies the accessibility
> checks to be performed.
>
> Check File Access Constants for possible values
> of mode.
>
> It is possible to create a mask consisting of the bitwise OR of
> two or more values (e.g.
>
> fs.constants.W_OK | fs.constants.R_OK).
>
> The final argument, callback, is a callback function that is invoked with
> a possible error argument.
>
> If any of the accessibility checks fail, the error
> argument will be an Error object.
>
> The following examples check if
> package.json exists, and if it is readable or writable.
>
> const file = 'package.json';${file} ${err ? 'does not exist' : 'exists'}\
>
> // Check if the file exists in the current directory.
> fs.access(file, fs.constants.F_OK, (err) => {
> console.log(\);${file} ${err ? 'is not readable' : 'is readable'}\
> });
>
> // Check if the file is readable.
> fs.access(file, fs.constants.R_OK, (err) => {
> console.log(\);${file} ${err ? 'is not writable' : 'is writable'}\
> });
>
> // Check if the file is writable.
> fs.access(file, fs.constants.W_OK, (err) => {
> console.log(\);${file} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}\
> });
>
> // Check if the file exists in the current directory, and if it is writable.
> fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
> if (err) {
> console.error(
> \);${file} exists, and it is writable\
> } else {
> console.log(\);.
> }
> });
>
>
> Using fs.access() to check for the accessibility of a file before calling
> fs.open(), fs.readFile() or fs.writeFile() is not recommended.
>
> Doing
> so introduces a race condition, since other processes may change the file's
> state between the two calls.
>
> Instead, user code should open/read/write the
> file directly and handle the error raised if the file is not accessible.
>
> fs.access('myfile', (err) => {.
> if (!err) {
> console.error('myfile already exists');
> return;
> }
>
> fs.open('myfile', 'wx', (err, fd) => {
> if (err) throw err;
> writeMyData(fd);
> });
> });
>
>
> fs.open('myfile', 'wx', (err, fd) => {.
> if (err) {
> if (err.code === 'EEXIST') {
> console.error('myfile already exists');
> return;
> }
>
> throw err;
> }
>
> writeMyData(fd);
> });
>
>
> fs.access('myfile', (err) => {.
> if (err) {
> if (err.code === 'ENOENT') {
> console.error('myfile does not exist');
> return;
> }
>
> throw err;
> }
>
> fs.open('myfile', 'r', (err, fd) => {
> if (err) throw err;
> readMyData(fd);
> });
> });
>
>
> fs.open('myfile', 'r', (err, fd) => {.
> if (err) {
> if (err.code === 'ENOENT') {
> console.error('myfile does not exist');
> return;
> }
>
> throw err;
> }
>
> readMyData(fd);
> });
>
>
> The "not recommended" examples above check for accessibility and then use the
> file; the "recommended" examples are better because they use the file directly
> and handle the error, if any.
>
> In general, check for the accessibility of a file only if the file will not be
> used directly, for example when its accessibility is a signal from another
> process.
>
> On Windows, access-control policies (ACLs) on a directory may limit access to
> a file or directory.
>
> The fs.access() function, however, does not check the
> ACL and therefore may report that a path is accessible even if the ACL restricts
> the user from reading or writing to it.
#### Parameters
- path (string \| Buffer \| URL) \-
- mode number Default: fs.constants.F_OK
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.chmod
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously changes the permissions of a file.
>
> No arguments other than a
> possible exception are given to the completion callback.
>
> See also: chmod(2).
>
> fs.chmod('my_file.txt', 0o775, (err) => {.
> if (err) throw err;
> console.log('The permissions for file "my_file.txt" have been changed!');
> });
>
>
> The mode argument used in both the fs.chmod() and fs.chmodSync()
> methods is a numeric bitmask created using a logical OR of the following
> constants:
> ConstantOctalDescription``fs.constants.S_IRUSR0o400`read by owner`fs.constants.S_IWUSR0o200`write by owner`fs.constants.S_IXUSR0o100`execute/search by owner`fs.constants.S_IRGRP0o40`read by group`fs.constants.S_IWGRP0o20`write by group`fs.constants.S_IXGRP0o10`execute/search by group`fs.constants.S_IROTH0o4`read by others`fs.constants.S_IWOTH0o2`write by others`fs.constants.S_IXOTH0o1`execute/search by others.mode
>
> An easier method of constructing the is to use a sequence of three765
> octal digits (e.g.
>
> ).7
>
> The left-most digit ( in the example), specifies6
> the permissions for the file owner.
>
> The middle digit ( in the example),5
> specifies permissions for the group.
>
> The right-most digit ( in the example),7
> specifies the permissions for others.
> NumberDescriptionread, write, and execute6read and write5read and execute4read only3write and execute2write only1execute only0no permission.0o765
>
> For example, the octal value means:0o777
>
> When using raw numbers where file modes are expected, any value larger than
> may result in platform-specific behaviors that are not supported to workS_ISVTX
> consistently.
>
> Therefore constants like , S_ISGID or S_ISUID are notfs.constants
> exposed in .
>
> Caveats: on Windows only the write permission can be changed, and the
> distinction among the permissions of group, owner or others is not
> implemented.
#### Parameters
- path (string \| Buffer \| URL) \-mode
- number \-The
- owner may read, write and execute the fileThe
- group may read and write the fileOthers
- may read and execute the file
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.fchmod
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous fchmod(2).
>
> No arguments other than a possible exception
> are given to the completion callback.
#### Parameters
- fd number \-mode
- number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.fstat
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous fstat(2).
>
> The callback gets two arguments (err, stats) wherestats
> is an fs.Stats object.fstat()
>
> is identical to stat(),fd
> except that the file to be stat-ed is specified by the file descriptor .
#### Parameters
- fd number \-options
- Object \-options.bigint
- boolean Whether the numeric values in the returned
Returns Future a future value
Wraps fs.lchmod
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous lchmod(2).
>
> No arguments other than a possible exception
> are given to the completion callback.
>
> Only available on macOS.
#### Parameters
- path (string \| Buffer \| URL) \-mode
- number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.link
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous link(2).
>
> No arguments other than a possible exception are given to
> the completion callback.
#### Parameters
- existingPath (string \| Buffer \| URL) \-newPath
- (string \| Buffer \| URL) \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.mkdir
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously creates a directory.
>
> No arguments other than a possible exception
> are given to the completion callback.
>
> The optional options argument can be an number specifying mode (permissionmode
> and sticky bits), or an object with a property and a recursivefs.mkdir()
> property indicating whether parent folders should be created.
>
> Calling
> when path is a directory that exists results in an error onlyrecursive
> when is false.// Creates /tmp/a/apple, regardless of whether \
>
> /tmp\ and /tmp/a exist.
> fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
> if (err) throw err;
> });
> .fs.mkdir()
>
> On Windows, using on the root directory even with recursion willfs.mkdir('/', { recursive: true }, (err) => {
> result in an error:
>
>
> // => [Error: EPERM: operation not permitted, mkdir 'C:\']
> });
> .mkdir(2)
>
> See also: .
#### Parameters
- path (string \| Buffer \| URL) \-options
- (Object \| number) \-options.recursive
- boolean Default: falseoptions.mode
- number Not supported on Windows Default: 0o777
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.rename
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously rename file at oldPath to the pathname providednewPath
> as .newPath
>
> In the case that already exists, it willnewPath
> be overwritten.
>
> If there is a directory at , an error willrename(2)
> be raised instead.
>
> No arguments other than a possible exception are
> given to the completion callback.
>
> See also: .fs.rename('oldFile.txt', 'newFile.txt', (err) => {
>
>
> if (err) throw err;
> console.log('Rename complete!');
> });
> .
#### Parameters
- oldPath (string \| Buffer \| URL) \-newPath
- (string \| Buffer \| URL) \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.appendFile
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously append data to a file, creating the file if it does not yet
> exist.
>
> data can be a string or a Buffer.fs.appendFile('message.txt', 'data to append', (err) => {
>
>
> if (err) throw err;
> console.log('The "data to append" was appended to file!');
> });
> .options
>
> If is a string, then it specifies the encoding:fs.appendFile('message.txt', 'data to append', 'utf8', callback);
>
>
> path
>
> The may be specified as a numeric file descriptor that has been openedfs.open()
> for appending (using or fs.openSync()).fs.open('message.txt', 'a', (err, fd) => {
>
> The file descriptor will
> not be closed automatically.
>
>
> if (err) throw err;
> fs.appendFile(fd, 'data to append', 'utf8', (err) => {
> fs.close(fd, (err) => {
> if (err) throw err;
> });
> if (err) throw err;
> });
> });
> .
#### Parameters
- path (string \| Buffer \| URL \| number) filename or file descriptordata
- (string \| Buffer) \-options
- (Object \| string) \-options.encoding
- (string | null) Default: 'utf8'options.mode
- number Default: 0o666options.flag
- string See {support of file system flags} - Default: 'a'
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.chown
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronously changes owner and group of a file.
>
> No arguments other than a
> possible exception are given to the completion callback.
>
> See also: chown(2).
#### Parameters
- path (string \| Buffer \| URL) \-uid
- number \-gid
- number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.copyFile
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Added in: v8.5.0
>
> Asynchronously copies src to dest.dest
>
> By default, is overwritten if itflags
> already exists.
>
> No arguments other than a possible exception are given to the
> callback function.
>
> Node.js makes no guarantees about the atomicity of the copy
> operation.
>
> If an error occurs after the destination file has been opened for
> writing, Node.js will attempt to remove the destination.
>
> is an optional number that specifies the behaviorfs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
> of the copy operation.
>
> It is possible to create a mask consisting of the bitwise
> OR of two or more values (e.g.
> ).const fs = require('fs');
>
>
>
> // destination.txt will be created or overwritten by default.
> fs.copyFile('source.txt', 'destination.txt', (err) => {
> if (err) throw err;
> console.log('source.txt was copied to destination.txt');
> });
> .flags
>
> If the third argument is a number, then it specifies :const fs = require('fs');
>
>
> const { COPYFILE_EXCL } = fs.constants;
>
> // By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
> fs.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL, callback);
> .
#### Parameters
- src (string \| Buffer \| URL) source filename to copydest
- (string \| Buffer \| URL) destination filename of the copy operationflags
- number modifiers for copy operation Default: 0
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.fchown
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous fchown(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
#### Parameters
- fd number \-uid
- number \-gid
- number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.futimes
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Change the file system timestamps of the object referenced by the supplied file
> descriptor.
>
> See fs.utimes().
>
> This function does not work on AIX versions before 7.1, it will return the
> error UV_ENOSYS.
#### Parameters
- fd number \-atime
- (number \| string \| Date) \-mtime
- (number \| string \| Date) \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.lchown
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous lchown(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
#### Parameters
- path (string \| Buffer \| URL) \-uid
- number \-gid
- number \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.symlink
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Asynchronous symlink(2).
>
> No arguments other than a possible exception are given
> to the completion callback.
>
> The type argument is only available on Windows'dir'
> and ignored on other platforms.
>
> It can be set to , 'file', or'junction'
> .type
>
> If the argument is not set, Node will autodetect target'file'
> type and use or 'dir'.target
>
> If the does not exist, 'file' will'junction'
> be used.
>
> Windows junction points require the destination path to be absolute.
> When using , the target argument will automatically be normalizedfs.symlink('./foo', './new-port', callback);
> to absolute path.
>
> Here is an example below:
>
>
>
>
> It creates a symbolic link named "new-port" that points to "foo".
#### Parameters
- target (string \| Buffer \| URL) \-path
- (string \| Buffer \| URL) \-type
- string \-
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.utimes
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> Change the file system timestamps of the object referenced by path.atime
>
> The and mtime arguments follow these rules:
#### Parameters
- path (string \| Buffer \| URL) \-atime
- (number \| string \| Date) \-mtime
- (number \| string \| Date) \-Values
- can be either numbers representing Unix epoch time, Dates, or aIf
- the value can not be converted to a number, or is NaN, Infinity or
Returns Future a future value
- **See:
for the source function this function wraps.
**
Wraps fs.writeFile
with fluture so that instead of taking a
callback it returns a Future. Unlike the raw function it wraps, this function now returns a
Future which wraps a value indicating whether the operation succeeded.
via node API docs:
> When file is a filename, asynchronously writes data to the file, replacing thedata
> file if it already exists.
>
> can be a string or a buffer.file
>
> When is a file descriptor, the behavior is similar to callingfs.write()
> directly (which is recommended).encoding
>
> See the notes below on using
> a file descriptor.
>
> The option is ignored if data is a buffer.const data = new Uint8Array(Buffer.from('Hello Node.js'));
>
>
> fs.writeFile('message.txt', data, (err) => {
> if (err) throw err;
> console.log('The file has been saved!');
> });
> .options
>
> If is a string, then it specifies the encoding:fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);
>
>
> fs.writeFile()
>
> It is unsafe to use multiple times on the same file withoutfs.createWriteStream()
> waiting for the callback.
>
> For this scenario, isfile
> recommended.
>
> When is a file descriptor, the behavior is almost identical to directlyfs.write()
> calling like:.fs.write(fd, Buffer.from(data, options.encoding), callback);
>
>
> fs.write()
>
> The difference from directly calling is that under some unusualfs.write()
> conditions, may write only part of the buffer and will need to befs.writeFile()
> retried to write the remaining data, whereas will retry untilfs.writeFile()
> the data is entirely written (or an error occurs).
>
> The implications of this are a common source of confusion.
>
> In
> the file descriptor case, the file is not replaced! The data is not necessarily
> written to the beginning of the file, and the file's original data may remain
> before and/or after the newly written data.
>
> For example, if is called twice in a row, first to write the'Hello'
> string , then to write the string ', World', the file would contain'Hello, World'
> , and might contain some of the file's original data (depending', World'
> on the size of the original file, and the position of the file descriptor).
>
> If
> a file name had been used instead of a descriptor, the file would be guaranteed
> to contain only .
#### Parameters
- file (string \| Buffer \| URL \| number) filename or file descriptordata
- (string \| Buffer \| TypedArray \| DataView) \-options
- (Object \| string) \-options.encoding
- (string | null) Default: 'utf8'options.mode
- number Default: 0o666options.flag
- string See {support of file system flags} - Default: 'w'
Returns Future a future value
Type: Object
#### Properties
- bimap function chain
- function fold
- function fork
- function map
- function mapRej
- function pipe
- function swap
- function It's a future
#### Parameters
- def any defaultformat
- string probably utf8?sources
- Array<string> a list of possible file sources
Returns Future the first matching file which resolves
#### Parameters
- format string probably utf8?sources
- Array<string> a list of possible file sources
Returns Future the first matching file which resolves
#### Parameters
- sources Array<string> a list of possible file sources
Returns Future the first matching file which resolves
takes an arity and nodeback function
and returns a future-returning function
NB: arity in this case doesn't take the callback into the count
so arity = 2 means a function with the shape (a, b, callback) => {}
#### Parameters
- arity number number of paramsfn
- Function a nodeback-style function
#### Examples
`javascript`
import fs from "fs"
import { callbackToTheFuture, fork } from "torpor/utils"
import { trace } from "xtrace"
const readFile = callbackToTheFuture(2, fs.readFile)
fork(trace("bad"), trace("good"), readFile("myfile.txt", "utf8"))
Returns Function Future-returning function
- **See: callbackToTheFuture
**
takes an arity and nodeback function
and returns a curried future-returning function
NB: arity in this case doesn't take the callback into the count
so arity = 2 means a function with the shape (a, b, callback) => {}
#### Parameters
- arity number arityfn
- Function a nodeback style function
#### Examples
`javascript``
import fs from "fs"
import { proxifyN, fork } from "torpor/utils"
import { trace } from "xtrace"
import { pipe, map, __ as $ } from "ramda"
const readFile = proxifyN(2, fs.readFile)
const utf8 = readFile($, "utf8")
pipe(map(JSON.parse), fork(trace("bad"))(trace("good")))(utf8("package.json"))
Returns Function curried Future-returning function