code:
var test = require('tape');
var resolve = require('../');
var path = require('path');

test('shadowed core modules still return core module', function (t) {
    t.plan(2);

    resolve('util', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, 'util');
    });
});

test('shadowed core modules still return core module [sync]', function (t) {
    t.plan(1);

    var res = resolve.sync('util', { basedir: path.join(__dirname, 'shadowed_core') });

    t.equal(res, 'util');
});

test('shadowed core modules return shadow when appending `/`', function (t) {
    t.plan(2);

    resolve('util/', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
    });
});

test('shadowed core modules return shadow when appending `/` [sync]', function (t) {
    t.plan(1);

    var res = resolve.sync('util/', { basedir: path.join(__dirname, 'shadowed_core') });

    t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
});

test('shadowed core modules return shadow with `includeCoreModules: false`', function (t) {
    t.plan(2);

    resolve('util', { basedir: path.join(__dirname, 'shadowed_core'), includeCoreModules: false }, function (err, res) {
        t.ifError(err);
        t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
    });
});

test('shadowed core modules return shadow with `includeCoreModules: false` [sync]', function (t) {
    t.plan(1);

    var res = resolve.sync('util', { basedir: path.join(__dirname, 'shadowed_core'), includeCoreModules: false });

    t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
});


code:
var test = require('tape');
var resolve = require('../');
var path = require('path');

test('subdirs', function (t) {
    t.plan(2);

    var dir = path.join(__dirname, '/subdirs');
    resolve('a/b/c/x.json', { basedir: dir }, function (err, res) {
        t.ifError(err);
        t.equal(res, path.join(dir, 'node_modules/a/b/c/x.json'));
    });
});

license: mit


code:
var path = require('path');
var fs = require('fs');
var test = require('tape');
var map = require('array.prototype.map');
var resolve = require('../');

var symlinkDir = path.join(__dirname, 'resolver', 'symlinked', 'symlink');
var packageDir = path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'package');
var modADir = path.join(__dirname, 'symlinks', 'source', 'node_modules', 'mod-a');
var symlinkModADir = path.join(__dirname, 'symlinks', 'dest', 'node_modules', 'mod-a');
try {
    fs.unlinkSync(symlinkDir);
} catch (err) {}
try {
    fs.unlinkSync(packageDir);
} catch (err) {}
try {
    fs.unlinkSync(modADir);
} catch (err) {}
try {
    fs.unlinkSync(symlinkModADir);
} catch (err) {}

try {
    fs.symlinkSync('./_/symlink_target', symlinkDir, 'dir');
} catch (err) {
    // if fails then it is probably on Windows and lets try to create a junction
    fs.symlinkSync(path.join(__dirname, 'resolver', 'symlinked', '_', 'symlink_target') + '\\', symlinkDir, 'junction');
}
try {
    fs.symlinkSync('../../package', packageDir, 'dir');
} catch (err) {
    // if fails then it is probably on Windows and lets try to create a junction
    fs.symlinkSync(path.join(__dirname, '..', '..', 'package') + '\\', packageDir, 'junction');
}
try {
    fs.symlinkSync('../../source/node_modules/mod-a', symlinkModADir, 'dir');
} catch (err) {
    // if fails then it is probably on Windows and lets try to create a junction
    fs.symlinkSync(path.join(__dirname, '..', '..', 'source', 'node_modules', 'mod-a') + '\\', symlinkModADir, 'junction');
}

test('symlink', function (t) {
    t.plan(2);

    resolve('foo', { basedir: symlinkDir, preserveSymlinks: false }, function (err, res, pkg) {
        t.error(err);
        t.equal(res, path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'foo.js'));
    });
});

test('sync symlink when preserveSymlinks = true', function (t) {
    t.plan(4);

    resolve('foo', { basedir: symlinkDir }, function (err, res, pkg) {
        t.ok(err, 'there is an error');
        t.notOk(res, 'no result');

        t.equal(err && err.code, 'MODULE_NOT_FOUND', 'error code matches require.resolve');
        t.equal(
            err && err.message,
            'Cannot find module \'foo\' from \'' + symlinkDir + '\'',
            'can not find nonexistent module'
        );
    });
});

test('sync symlink', function (t) {
    var start = new Date();
    t.doesNotThrow(function () {
        t.equal(
            resolve.sync('foo', { basedir: symlinkDir, preserveSymlinks: false }),
            path.join(__dirname, 'resolver', 'symlinked', '_', 'node_modules', 'foo.js')
        );
    });
    t.ok(new Date() - start < 50, 'resolve.sync timedout');
    t.end();
});

test('sync symlink when preserveSymlinks = true', function (t) {
    t.throws(function () {
        resolve.sync('foo', { basedir: symlinkDir });
    }, /Cannot find module 'foo'/);
    t.end();
});

test('sync symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
    var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
    var fn = resolve.sync('package', { basedir: basedir, preserveSymlinks: false });

    t.equal(fn, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
    t.end();
});

test('async symlink from node_modules to other dir when preserveSymlinks = false', function (t) {
    t.plan(2);
    var basedir = path.join(__dirname, 'resolver', 'symlinked', '_');
    resolve('package', { basedir: basedir, preserveSymlinks: false }, function (err, result) {
        t.notOk(err, 'no error');
        t.equal(result, path.resolve(__dirname, 'resolver/symlinked/package/bar.js'));
    });
});

test('packageFilter', function (t) {
    function relative(x) {
        return path.relative(__dirname, x);
    }

    function testPackageFilter(preserveSymlinks) {
        return function (st) {
            st.plan('is 1.x' ? 3 : 5); // eslint-disable-line no-constant-condition

            var destMain = 'symlinks/dest/node_modules/mod-a/index.js';
            var destPkg = 'symlinks/dest/node_modules/mod-a/package.json';
            var sourceMain = 'symlinks/source/node_modules/mod-a/index.js';
            var sourcePkg = 'symlinks/source/node_modules/mod-a/package.json';
            var destDir = path.join(__dirname, 'symlinks', 'dest');

            /* eslint multiline-comment-style: 0 */
            /* v2.x will restore these tests
            var packageFilterPath = [];
            var actualPath = resolve.sync('mod-a', {
                basedir: destDir,
                preserveSymlinks: preserveSymlinks,
                packageFilter: function (pkg, pkgfile, dir) {
                    packageFilterPath.push(pkgfile);
                }
            });
            st.equal(
                relative(actualPath),
                path.normalize(preserveSymlinks ? destMain : sourceMain),
                'sync: actual path is correct'
            );
            st.deepEqual(
                map(packageFilterPath, relative),
                map(preserveSymlinks ? [destPkg, destPkg] : [sourcePkg, sourcePkg], path.normalize),
                'sync: packageFilter pkgfile arg is correct'
            );
            */

            var asyncPackageFilterPath = [];
            resolve(
                'mod-a',
                {
                    basedir: destDir,
                    preserveSymlinks: preserveSymlinks,
                    packageFilter: function (pkg, pkgfile) {
                        asyncPackageFilterPath.push(pkgfile);
                    }
                },
                function (err, actualPath) {
                    st.error(err, 'no error');
                    st.equal(
                        relative(actualPath),
                        path.normalize(preserveSymlinks ? destMain : sourceMain),
                        'async: actual path is correct'
                    );
                    st.deepEqual(
                        map(asyncPackageFilterPath, relative),
                        map(
                            preserveSymlinks ? [destPkg, destPkg, destPkg] : [sourcePkg, sourcePkg, sourcePkg],
                            path.normalize
                        ),
                        'async: packageFilter pkgfile arg is correct'
                    );
                }
            );
        };
    }

    t.test('preserveSymlinks: false', testPackageFilter(false));

    t.test('preserveSymlinks: true', testPackageFilter(true));

    t.end();
});


code:
/**
Gracefully restore the CLI cursor on exit.

Prevent the cursor you have hidden interactively from remaining hidden if the process crashes.

It does nothing if run in a non-TTY context.

@example
```
import restoreCursor from 'restore-cursor';

restoreCursor();
```
*/
export default function restoreCursor(): void;


code:
import process from 'node:process';
import onetime from 'onetime';
import {onExit} from 'signal-exit';

const terminal = process.stderr.isTTY
	? process.stderr
	: (process.stdout.isTTY ? process.stdout : undefined);

const restoreCursor = terminal ? onetime(() => {
	onExit(() => {
		terminal.write('\u001B[?25h');
	}, {alwaysLast: true});
}) : () => {};

export default restoreCursor;


code:
export type Options = {
	/**
	Throw an error when called more than once.

	@default false
	*/
	readonly throw?: boolean;
};

declare const onetime: {
	/**
	Ensure a function is only called once. When called multiple times it will return the return value from the first call.

	@param fn - The function that should only be called once.
	@returns A function that only calls `fn` once.

	@example
	```
	import onetime from 'onetime';

	let index = 0;

	const foo = onetime(() => ++index);

	foo(); //=> 1
	foo(); //=> 1
	foo(); //=> 1

	onetime.callCount(foo); //=> 3
	```
	*/
	<ArgumentsType extends unknown[], ReturnType>(
		fn: (...arguments_: ArgumentsType) => ReturnType,
		options?: Options
	): (...arguments_: ArgumentsType) => ReturnType;

	/**
	Get the number of times `fn` has been called.

	@param fn - The function to get call count from.
	@returns A number representing how many times `fn` has been called.

	@example
	```
	import onetime from 'onetime';

	const foo = onetime(() => {});
	foo();
	foo();
	foo();

	console.log(onetime.callCount(foo));
	//=> 3
	```
	*/
	callCount(fn: (...arguments_: any[]) => unknown): number;
};

export default onetime;


code:
import mimicFunction from 'mimic-function';

const calledFunctions = new WeakMap();

const onetime = (function_, options = {}) => {
	if (typeof function_ !== 'function') {
		throw new TypeError('Expected a function');
	}

	let returnValue;
	let callCount = 0;
	const functionName = function_.displayName || function_.name || '<anonymous>';

	const onetime = function (...arguments_) {
		calledFunctions.set(onetime, ++callCount);

		if (callCount === 1) {
			returnValue = function_.apply(this, arguments_);
			function_ = undefined;
		} else if (options.throw === true) {
			throw new Error(`Function \`${functionName}\` can only be called once`);
		}

		return returnValue;
	};

	mimicFunction(onetime, function_);
	calledFunctions.set(onetime, callCount);

	return onetime;
};

onetime.callCount = function_ => {
	if (!calledFunctions.has(function_)) {
		throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
	}

	return calledFunctions.get(function_);
};

export default onetime;


onetime

description: Ensure a function is only called once

license: MIT

repository: sindresorhus/onetime

type: module

test: xo && ava && tsd

keywords: once function one onetime func fn single call called prevent


code:
# onetime

> Ensure a function is only called once

When called multiple times it will return the return value from the first call.

*Unlike the module [once](https://github.com/isaacs/once), this one isn't naughty and extending `Function.prototype`.*

## Install

```sh
npm install onetime
```

## Usage

```js
import onetime from 'onetime';

let index = 0;

const foo = onetime(() => ++index);

foo(); //=> 1
foo(); //=> 1
foo(); //=> 1

onetime.callCount(foo); //=> 3
```

```js
import onetime from 'onetime';

const foo = onetime(() => {}, {throw: true});

foo();

foo();
//=> Error: Function `foo` can only be called once
```

## API

### onetime(fn, options?)

Returns a function that only calls `fn` once.

#### fn

Type: `Function`

The function that should only be called once.

#### options

Type: `object`

##### throw

Type: `boolean`\
Default: `false`

Throw an error when called more than once.

### onetime.callCount(fn)

Returns a number representing how many times `fn` has been called.

Note: It throws an error if you pass in a function that is not wrapped by `onetime`.

```js
import onetime from 'onetime';

const foo = onetime(() => {});

foo();
foo();
foo();

console.log(onetime.callCount(foo));
//=> 3
```

#### fn

Type: `Function`

The function to get call count from.


code:
# signal-exit

When you want to fire an event no matter how a process exits:

- reaching the end of execution.
- explicitly having `process.exit(code)` called.
- having `process.kill(pid, sig)` called.
- receiving a fatal signal from outside the process

Use `signal-exit`.

```js
// Hybrid module, either works
import { onExit } from 'signal-exit'
// or:
// const { onExit } = require('signal-exit')

onExit((code, signal) => {
  console.log('process exited!', code, signal)
})
```

## API

`remove = onExit((code, signal) => {}, options)`

The return value of the function is a function that will remove
the handler.

Note that the function _only_ fires for signals if the signal
would cause the process to exit. That is, there are no other
listeners, and it is a fatal signal.

If the global `process` object is not suitable for this purpose
(ie, it's unset, or doesn't have an `emit` method, etc.) then the
`onExit` function is a no-op that returns a no-op `remove` method.

### Options

- `alwaysLast`: Run this handler after any other signal or exit
  handlers. This causes `process.emit` to be monkeypatched.

### Capturing Signal Exits

If the handler returns an exact boolean `true`, and the exit is a
due to signal, then the signal will be considered handled, and
will _not_ trigger a synthetic `process.kill(process.pid,
signal)` after firing the `onExit` handlers.

In this case, it your responsibility as the caller to exit with a
signal (for example, by calling `process.kill()`) if you wish to
preserve the same exit status that would otherwise have occurred.
If you do not, then the process will likely exit gracefully with
status 0 at some point, assuming that no other terminating signal
or other exit trigger occurs.

Prior to calling handlers, the `onExit` machinery is unloaded, so
any subsequent exits or signals will not be handled, even if the
signal is captured and the exit is thus prevented.

Note that numeric code exits may indicate that the process is
already committed to exiting, for example due to a fatal
exception or unhandled promise rejection, and so there is no way to
prevent it safely.

### Browser Fallback

The `'signal-exit/browser'` module is the same fallback shim that
just doesn't do anything, but presents the same function
interface.

Patches welcome to add something that hooks onto
`window.onbeforeunload` or similar, but it might just not be a
thing that makes sense there.


code:
/**
 * This is a browser shim that provides the same functional interface
 * as the main node export, but it does nothing.
 * @module
 */
import type { Handler } from './index.js';
export declare const onExit: (cb: Handler, opts: {
    alwaysLast?: boolean;
}) => () => void;
export declare const load: () => void;
export declare const unload: () => void;
//# sourceMappingURL=browser.d.ts.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unload = exports.load = exports.onExit = void 0;
const onExit = () => () => { };
exports.onExit = onExit;
const load = () => { };
exports.load = load;
const unload = () => { };
exports.unload = unload;
//# sourceMappingURL=browser.js.map


sourcesContent:
/**
 * This is a browser shim that provides the same functional interface
 * as the main node export, but it does nothing.
 * @module
 */
import type { Handler } from './index.js'
export const onExit: (
  cb: Handler,
  opts: { alwaysLast?: boolean }
) => () => void = () => () => {}
export const load = () => {}
export const unload = () => {}


code:
/// <reference types="node" />
import { signals } from './signals.js';
export { signals };
/**
 * A function that takes an exit code and signal as arguments
 *
 * In the case of signal exits *only*, a return value of true
 * will indicate that the signal is being handled, and we should
 * not synthetically exit with the signal we received. Regardless
 * of the handler return value, the handler is unloaded when an
 * otherwise fatal signal is received, so you get exactly 1 shot
 * at it, unless you add another onExit handler at that point.
 *
 * In the case of numeric code exits, we may already have committed
 * to exiting the process, for example via a fatal exception or
 * unhandled promise rejection, so it is impossible to stop safely.
 */
export type Handler = (code: number | null | undefined, signal: NodeJS.Signals | null) => true | void;
export declare const
/**
 * Called when the process is exiting, whether via signal, explicit
 * exit, or running out of stuff to do.
 *
 * If the global process object is not suitable for instrumentation,
 * then this will be a no-op.
 *
 * Returns a function that may be used to unload signal-exit.
 */
onExit: (cb: Handler, opts?: {
    alwaysLast?: boolean | undefined;
} | undefined) => () => void,
/**
 * Load the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
load: () => void,
/**
 * Unload the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
unload: () => void;
//# sourceMappingURL=index.d.ts.map


code:
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.unload = exports.load = exports.onExit = exports.signals = void 0;
// Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
// grab a reference to node's real process object right away
const signals_js_1 = require("./signals.js");
Object.defineProperty(exports, "signals", { enumerable: true, get: function () { return signals_js_1.signals; } });
const processOk = (process) => !!process &&
    typeof process === 'object' &&
    typeof process.removeListener === 'function' &&
    typeof process.emit === 'function' &&
    typeof process.reallyExit === 'function' &&
    typeof process.listeners === 'function' &&
    typeof process.kill === 'function' &&
    typeof process.pid === 'number' &&
    typeof process.on === 'function';
const kExitEmitter = Symbol.for('signal-exit emitter');
const global = globalThis;
const ObjectDefineProperty = Object.defineProperty.bind(Object);
// teeny special purpose ee
class Emitter {
    emitted = {
        afterExit: false,
        exit: false,
    };
    listeners = {
        afterExit: [],
        exit: [],
    };
    count = 0;
    id = Math.random();
    constructor() {
        if (global[kExitEmitter]) {
            return global[kExitEmitter];
        }
        ObjectDefineProperty(global, kExitEmitter, {
            value: this,
            writable: false,
            enumerable: false,
            configurable: false,
        });
    }
    on(ev, fn) {
        this.listeners[ev].push(fn);
    }
    removeListener(ev, fn) {
        const list = this.listeners[ev];
        const i = list.indexOf(fn);
        /* c8 ignore start */
        if (i === -1) {
            return;
        }
        /* c8 ignore stop */
        if (i === 0 && list.length === 1) {
            list.length = 0;
        }
        else {
            list.splice(i, 1);
        }
    }
    emit(ev, code, signal) {
        if (this.emitted[ev]) {
            return false;
        }
        this.emitted[ev] = true;
        let ret = false;
        for (const fn of this.listeners[ev]) {
            ret = fn(code, signal) === true || ret;
        }
        if (ev === 'exit') {
            ret = this.emit('afterExit', code, signal) || ret;
        }
        return ret;
    }
}
class SignalExitBase {
}
const signalExitWrap = (handler) => {
    return {
        onExit(cb, opts) {
            return handler.onExit(cb, opts);
        },
        load() {
            return handler.load();
        },
        unload() {
            return handler.unload();
        },
    };
};
class SignalExitFallback extends SignalExitBase {
    onExit() {
        return () => { };
    }
    load() { }
    unload() { }
}
class SignalExit extends SignalExitBase {
    // "SIGHUP" throws an `ENOSYS` error on Windows,
    // so use a supported signal instead
    /* c8 ignore start */
    #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP';
    /* c8 ignore stop */
    #emitter = new Emitter();
    #process;
    #originalProcessEmit;
    #originalProcessReallyExit;
    #sigListeners = {};
    #loaded = false;
    constructor(process) {
        super();
        this.#process = process;
        // { <signal>: <listener fn>, ... }
        this.#sigListeners = {};
        for (const sig of signals_js_1.signals) {
            this.#sigListeners[sig] = () => {
                // If there are no other listeners, an exit is coming!
                // Simplest way: remove us and then re-send the signal.
                // We know that this will kill the process, so we can
                // safely emit now.
                const listeners = this.#process.listeners(sig);
                let { count } = this.#emitter;
                // This is a workaround for the fact that signal-exit v3 and signal
                // exit v4 are not aware of each other, and each will attempt to let
                // the other handle it, so neither of them do. To correct this, we
                // detect if we're the only handler *except* for previous versions
                // of signal-exit, and increment by the count of listeners it has
                // created.
                /* c8 ignore start */
                const p = process;
                if (typeof p.__signal_exit_emitter__ === 'object' &&
                    typeof p.__signal_exit_emitter__.count === 'number') {
                    count += p.__signal_exit_emitter__.count;
                }
                /* c8 ignore stop */
                if (listeners.length === count) {
                    this.unload();
                    const ret = this.#emitter.emit('exit', null, sig);
                    /* c8 ignore start */
                    const s = sig === 'SIGHUP' ? this.#hupSig : sig;
                    if (!ret)
                        process.kill(process.pid, s);
                    /* c8 ignore stop */
                }
            };
        }
        this.#originalProcessReallyExit = process.reallyExit;
        this.#originalProcessEmit = process.emit;
    }
    onExit(cb, opts) {
        /* c8 ignore start */
        if (!processOk(this.#process)) {
            return () => { };
        }
        /* c8 ignore stop */
        if (this.#loaded === false) {
            this.load();
        }
        const ev = opts?.alwaysLast ? 'afterExit' : 'exit';
        this.#emitter.on(ev, cb);
        return () => {
            this.#emitter.removeListener(ev, cb);
            if (this.#emitter.listeners['exit'].length === 0 &&
                this.#emitter.listeners['afterExit'].length === 0) {
                this.unload();
            }
        };
    }
    load() {
        if (this.#loaded) {
            return;
        }
        this.#loaded = true;
        // This is the number of onSignalExit's that are in play.
        // It's important so that we can count the correct number of
        // listeners on signals, and don't wait for the other one to
        // handle it instead of us.
        this.#emitter.count += 1;
        for (const sig of signals_js_1.signals) {
            try {
                const fn = this.#sigListeners[sig];
                if (fn)
                    this.#process.on(sig, fn);
            }
            catch (_) { }
        }
        this.#process.emit = (ev, ...a) => {
            return this.#processEmit(ev, ...a);
        };
        this.#process.reallyExit = (code) => {
            return this.#processReallyExit(code);
        };
    }
    unload() {
        if (!this.#loaded) {
            return;
        }
        this.#loaded = false;
        signals_js_1.signals.forEach(sig => {
            const listener = this.#sigListeners[sig];
            /* c8 ignore start */
            if (!listener) {
                throw new Error('Listener not defined for signal: ' + sig);
            }
            /* c8 ignore stop */
            try {
                this.#process.removeListener(sig, listener);
                /* c8 ignore start */
            }
            catch (_) { }
            /* c8 ignore stop */
        });
        this.#process.emit = this.#originalProcessEmit;
        this.#process.reallyExit = this.#originalProcessReallyExit;
        this.#emitter.count -= 1;
    }
    #processReallyExit(code) {
        /* c8 ignore start */
        if (!processOk(this.#process)) {
            return 0;
        }
        this.#process.exitCode = code || 0;
        /* c8 ignore stop */
        this.#emitter.emit('exit', this.#process.exitCode, null);
        return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
    }
    #processEmit(ev, ...args) {
        const og = this.#originalProcessEmit;
        if (ev === 'exit' && processOk(this.#process)) {
            if (typeof args[0] === 'number') {
                this.#process.exitCode = args[0];
                /* c8 ignore start */
            }
            /* c8 ignore start */
            const ret = og.call(this.#process, ev, ...args);
            /* c8 ignore start */
            this.#emitter.emit('exit', this.#process.exitCode, null);
            /* c8 ignore stop */
            return ret;
        }
        else {
            return og.call(this.#process, ev, ...args);
        }
    }
}
const process = globalThis.process;
// wrap so that we call the method on the actual handler, without
// exporting it directly.
_a = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback()),
/**
 * Called when the process is exiting, whether via signal, explicit
 * exit, or running out of stuff to do.
 *
 * If the global process object is not suitable for instrumentation,
 * then this will be a no-op.
 *
 * Returns a function that may be used to unload signal-exit.
 */
exports.onExit = _a.onExit,
/**
 * Load the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
exports.load = _a.load,
/**
 * Unload the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
exports.unload = _a.unload;
//# sourceMappingURL=index.js.map


code:
/// <reference types="node" />
/**
 * This is not the set of all possible signals.
 *
 * It IS, however, the set of all signals that trigger
 * an exit on either Linux or BSD systems.  Linux is a
 * superset of the signal names supported on BSD, and
 * the unknown signals just fail to register, so we can
 * catch that easily enough.
 *
 * Windows signals are a different set, since there are
 * signals that terminate Windows processes, but don't
 * terminate (or don't even exist) on Posix systems.
 *
 * Don't bother with SIGKILL.  It's uncatchable, which
 * means that we can't fire any callbacks anyway.
 *
 * If a user does happen to register a handler on a non-
 * fatal signal like SIGWINCH or something, and then
 * exit, it'll end up firing `process.emit('exit')`, so
 * the handler will be fired anyway.
 *
 * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
 * artificially, inherently leave the process in a
 * state from which it is not safe to try and enter JS
 * listeners.
 */
export declare const signals: NodeJS.Signals[];
//# sourceMappingURL=signals.d.ts.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.signals = void 0;
/**
 * This is not the set of all possible signals.
 *
 * It IS, however, the set of all signals that trigger
 * an exit on either Linux or BSD systems.  Linux is a
 * superset of the signal names supported on BSD, and
 * the unknown signals just fail to register, so we can
 * catch that easily enough.
 *
 * Windows signals are a different set, since there are
 * signals that terminate Windows processes, but don't
 * terminate (or don't even exist) on Posix systems.
 *
 * Don't bother with SIGKILL.  It's uncatchable, which
 * means that we can't fire any callbacks anyway.
 *
 * If a user does happen to register a handler on a non-
 * fatal signal like SIGWINCH or something, and then
 * exit, it'll end up firing `process.emit('exit')`, so
 * the handler will be fired anyway.
 *
 * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
 * artificially, inherently leave the process in a
 * state from which it is not safe to try and enter JS
 * listeners.
 */
exports.signals = [];
exports.signals.push('SIGHUP', 'SIGINT', 'SIGTERM');
if (process.platform !== 'win32') {
    exports.signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT'
    // should detect profiler and enable/disable accordingly.
    // see #21
    // 'SIGPROF'
    );
}
if (process.platform === 'linux') {
    exports.signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT');
}
//# sourceMappingURL=signals.js.map


code:
export const onExit = () => () => { };
export const load = () => { };
export const unload = () => { };
//# sourceMappingURL=browser.js.map


code:
// Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
// grab a reference to node's real process object right away
import { signals } from './signals.js';
export { signals };
const processOk = (process) => !!process &&
    typeof process === 'object' &&
    typeof process.removeListener === 'function' &&
    typeof process.emit === 'function' &&
    typeof process.reallyExit === 'function' &&
    typeof process.listeners === 'function' &&
    typeof process.kill === 'function' &&
    typeof process.pid === 'number' &&
    typeof process.on === 'function';
const kExitEmitter = Symbol.for('signal-exit emitter');
const global = globalThis;
const ObjectDefineProperty = Object.defineProperty.bind(Object);
// teeny special purpose ee
class Emitter {
    emitted = {
        afterExit: false,
        exit: false,
    };
    listeners = {
        afterExit: [],
        exit: [],
    };
    count = 0;
    id = Math.random();
    constructor() {
        if (global[kExitEmitter]) {
            return global[kExitEmitter];
        }
        ObjectDefineProperty(global, kExitEmitter, {
            value: this,
            writable: false,
            enumerable: false,
            configurable: false,
        });
    }
    on(ev, fn) {
        this.listeners[ev].push(fn);
    }
    removeListener(ev, fn) {
        const list = this.listeners[ev];
        const i = list.indexOf(fn);
        /* c8 ignore start */
        if (i === -1) {
            return;
        }
        /* c8 ignore stop */
        if (i === 0 && list.length === 1) {
            list.length = 0;
        }
        else {
            list.splice(i, 1);
        }
    }
    emit(ev, code, signal) {
        if (this.emitted[ev]) {
            return false;
        }
        this.emitted[ev] = true;
        let ret = false;
        for (const fn of this.listeners[ev]) {
            ret = fn(code, signal) === true || ret;
        }
        if (ev === 'exit') {
            ret = this.emit('afterExit', code, signal) || ret;
        }
        return ret;
    }
}
class SignalExitBase {
}
const signalExitWrap = (handler) => {
    return {
        onExit(cb, opts) {
            return handler.onExit(cb, opts);
        },
        load() {
            return handler.load();
        },
        unload() {
            return handler.unload();
        },
    };
};
class SignalExitFallback extends SignalExitBase {
    onExit() {
        return () => { };
    }
    load() { }
    unload() { }
}
class SignalExit extends SignalExitBase {
    // "SIGHUP" throws an `ENOSYS` error on Windows,
    // so use a supported signal instead
    /* c8 ignore start */
    #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP';
    /* c8 ignore stop */
    #emitter = new Emitter();
    #process;
    #originalProcessEmit;
    #originalProcessReallyExit;
    #sigListeners = {};
    #loaded = false;
    constructor(process) {
        super();
        this.#process = process;
        // { <signal>: <listener fn>, ... }
        this.#sigListeners = {};
        for (const sig of signals) {
            this.#sigListeners[sig] = () => {
                // If there are no other listeners, an exit is coming!
                // Simplest way: remove us and then re-send the signal.
                // We know that this will kill the process, so we can
                // safely emit now.
                const listeners = this.#process.listeners(sig);
                let { count } = this.#emitter;
                // This is a workaround for the fact that signal-exit v3 and signal
                // exit v4 are not aware of each other, and each will attempt to let
                // the other handle it, so neither of them do. To correct this, we
                // detect if we're the only handler *except* for previous versions
                // of signal-exit, and increment by the count of listeners it has
                // created.
                /* c8 ignore start */
                const p = process;
                if (typeof p.__signal_exit_emitter__ === 'object' &&
                    typeof p.__signal_exit_emitter__.count === 'number') {
                    count += p.__signal_exit_emitter__.count;
                }
                /* c8 ignore stop */
                if (listeners.length === count) {
                    this.unload();
                    const ret = this.#emitter.emit('exit', null, sig);
                    /* c8 ignore start */
                    const s = sig === 'SIGHUP' ? this.#hupSig : sig;
                    if (!ret)
                        process.kill(process.pid, s);
                    /* c8 ignore stop */
                }
            };
        }
        this.#originalProcessReallyExit = process.reallyExit;
        this.#originalProcessEmit = process.emit;
    }
    onExit(cb, opts) {
        /* c8 ignore start */
        if (!processOk(this.#process)) {
            return () => { };
        }
        /* c8 ignore stop */
        if (this.#loaded === false) {
            this.load();
        }
        const ev = opts?.alwaysLast ? 'afterExit' : 'exit';
        this.#emitter.on(ev, cb);
        return () => {
            this.#emitter.removeListener(ev, cb);
            if (this.#emitter.listeners['exit'].length === 0 &&
                this.#emitter.listeners['afterExit'].length === 0) {
                this.unload();
            }
        };
    }
    load() {
        if (this.#loaded) {
            return;
        }
        this.#loaded = true;
        // This is the number of onSignalExit's that are in play.
        // It's important so that we can count the correct number of
        // listeners on signals, and don't wait for the other one to
        // handle it instead of us.
        this.#emitter.count += 1;
        for (const sig of signals) {
            try {
                const fn = this.#sigListeners[sig];
                if (fn)
                    this.#process.on(sig, fn);
            }
            catch (_) { }
        }
        this.#process.emit = (ev, ...a) => {
            return this.#processEmit(ev, ...a);
        };
        this.#process.reallyExit = (code) => {
            return this.#processReallyExit(code);
        };
    }
    unload() {
        if (!this.#loaded) {
            return;
        }
        this.#loaded = false;
        signals.forEach(sig => {
            const listener = this.#sigListeners[sig];
            /* c8 ignore start */
            if (!listener) {
                throw new Error('Listener not defined for signal: ' + sig);
            }
            /* c8 ignore stop */
            try {
                this.#process.removeListener(sig, listener);
                /* c8 ignore start */
            }
            catch (_) { }
            /* c8 ignore stop */
        });
        this.#process.emit = this.#originalProcessEmit;
        this.#process.reallyExit = this.#originalProcessReallyExit;
        this.#emitter.count -= 1;
    }
    #processReallyExit(code) {
        /* c8 ignore start */
        if (!processOk(this.#process)) {
            return 0;
        }
        this.#process.exitCode = code || 0;
        /* c8 ignore stop */
        this.#emitter.emit('exit', this.#process.exitCode, null);
        return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
    }
    #processEmit(ev, ...args) {
        const og = this.#originalProcessEmit;
        if (ev === 'exit' && processOk(this.#process)) {
            if (typeof args[0] === 'number') {
                this.#process.exitCode = args[0];
                /* c8 ignore start */
            }
            /* c8 ignore start */
            const ret = og.call(this.#process, ev, ...args);
            /* c8 ignore start */
            this.#emitter.emit('exit', this.#process.exitCode, null);
            /* c8 ignore stop */
            return ret;
        }
        else {
            return og.call(this.#process, ev, ...args);
        }
    }
}
const process = globalThis.process;
// wrap so that we call the method on the actual handler, without
// exporting it directly.
export const {
/**
 * Called when the process is exiting, whether via signal, explicit
 * exit, or running out of stuff to do.
 *
 * If the global process object is not suitable for instrumentation,
 * then this will be a no-op.
 *
 * Returns a function that may be used to unload signal-exit.
 */
onExit,
/**
 * Load the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
load,
/**
 * Unload the listeners.  Likely you never need to call this, unless
 * doing a rather deep integration with signal-exit functionality.
 * Mostly exposed for the benefit of testing.
 *
 * @internal
 */
unload, } = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback());
//# sourceMappingURL=index.js.map


code:
/**
 * This is not the set of all possible signals.
 *
 * It IS, however, the set of all signals that trigger
 * an exit on either Linux or BSD systems.  Linux is a
 * superset of the signal names supported on BSD, and
 * the unknown signals just fail to register, so we can
 * catch that easily enough.
 *
 * Windows signals are a different set, since there are
 * signals that terminate Windows processes, but don't
 * terminate (or don't even exist) on Posix systems.
 *
 * Don't bother with SIGKILL.  It's uncatchable, which
 * means that we can't fire any callbacks anyway.
 *
 * If a user does happen to register a handler on a non-
 * fatal signal like SIGWINCH or something, and then
 * exit, it'll end up firing `process.emit('exit')`, so
 * the handler will be fired anyway.
 *
 * SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
 * artificially, inherently leave the process in a
 * state from which it is not safe to try and enter JS
 * listeners.
 */
export const signals = [];
signals.push('SIGHUP', 'SIGINT', 'SIGTERM');
if (process.platform !== 'win32') {
    signals.push('SIGALRM', 'SIGABRT', 'SIGVTALRM', 'SIGXCPU', 'SIGXFSZ', 'SIGUSR2', 'SIGTRAP', 'SIGSYS', 'SIGQUIT', 'SIGIOT'
    // should detect profiler and enable/disable accordingly.
    // see #21
    // 'SIGPROF'
    );
}
if (process.platform === 'linux') {
    signals.push('SIGIO', 'SIGPOLL', 'SIGPWR', 'SIGSTKFLT');
}
//# sourceMappingURL=signals.js.map


signal-exit

description: when you want to fire an event no matter how a process exits.

type: git

keywords: signal exit

author: Ben Coe <ben@npmjs.com>

license: ISC

preversion: npm test

postversion: npm publish

prepublishOnly: git push origin --follow-tags

preprepare: rm -rf dist

prepare: tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh

pretest: npm run prepare

presnap: npm run prepare

test: c8 tap

snap: c8 tap

format: prettier --write . --loglevel warn

typedoc: typedoc --tsconfig tsconfig-esm.json ./src/*.ts

arrowParens: avoid

endOfLine: lf

node-arg: --no-warnings --loader ts-node/esm


restore-cursor

description: Gracefully restore the CLI cursor on exit

repository: sindresorhus/restore-cursor

test: xo && tsd && node --test

keywords: exit quit process graceful shutdown sigterm sigint terminate kill stop cli cursor ansi show term terminal console tty shell command-line


code:
# restore-cursor

> Gracefully restore the CLI cursor on exit

Prevent the cursor you have hidden interactively from remaining hidden if the process crashes.

It does nothing if run in a non-TTY context.

## Install

```sh
npm install restore-cursor
```

## Usage

```js
import restoreCursor from 'restore-cursor';

restoreCursor();
```


code:
<!-- badges/ -->
[![Build Status](https://secure.travis-ci.org/tim-kos/node-retry.svg?branch=master)](http://travis-ci.org/tim-kos/node-retry "Check this project's build status on TravisCI")
[![codecov](https://codecov.io/gh/tim-kos/node-retry/branch/master/graph/badge.svg)](https://codecov.io/gh/tim-kos/node-retry)
<!-- /badges -->

# retry

Abstraction for exponential and custom retry strategies for failed operations.

## Installation

    npm install retry

## Current Status

This module has been tested and is ready to be used.

## Tutorial

The example below will retry a potentially failing `dns.resolve` operation
`10` times using an exponential backoff strategy. With the default settings, this
means the last attempt is made after `17 minutes and 3 seconds`.

``` javascript
var dns = require('dns');
var retry = require('retry');

function faultTolerantResolve(address, cb) {
  var operation = retry.operation();

  operation.attempt(function(currentAttempt) {
    dns.resolve(address, function(err, addresses) {
      if (operation.retry(err)) {
        return;
      }

      cb(err ? operation.mainError() : null, addresses);
    });
  });
}

faultTolerantResolve('nodejs.org', function(err, addresses) {
  console.log(err, addresses);
});
```

Of course you can also configure the factors that go into the exponential
backoff. See the API documentation below for all available settings.
currentAttempt is an int representing the number of attempts so far.

``` javascript
var operation = retry.operation({
  retries: 5,
  factor: 3,
  minTimeout: 1 * 1000,
  maxTimeout: 60 * 1000,
  randomize: true,
});
```

## API

### retry.operation([options])

Creates a new `RetryOperation` object. `options` is the same as `retry.timeouts()`'s `options`, with three additions:

* `forever`: Whether to retry forever, defaults to `false`.
* `unref`: Whether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`.
* `maxRetryTime`: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is `Infinity`.

### retry.timeouts([options])

Returns an array of timeouts. All time `options` and return values are in
milliseconds. If `options` is an array, a copy of that array is returned.

`options` is a JS object that can contain any of the following keys:

* `retries`: The maximum amount of times to retry the operation. Default is `10`. Seting this to `1` means `do it once, then retry it once`.
* `factor`: The exponential factor to use. Default is `2`.
* `minTimeout`: The number of milliseconds before starting the first retry. Default is `1000`.
* `maxTimeout`: The maximum number of milliseconds between two retries. Default is `Infinity`.
* `randomize`: Randomizes the timeouts by multiplying with a factor between `1` to `2`. Default is `false`.

The formula used to calculate the individual timeouts is:

```
Math.min(random * minTimeout * Math.pow(factor, attempt), maxTimeout)
```

Have a look at [this article][article] for a better explanation of approach.

If you want to tune your `factor` / `times` settings to attempt the last retry
after a certain amount of time, you can use wolfram alpha. For example in order
to tune for `10` attempts in `5 minutes`, you can use this equation:

![screenshot](https://github.com/tim-kos/node-retry/raw/master/equation.gif)

Explaining the various values from left to right:

* `k = 0 ... 9`:  The `retries` value (10)
* `1000`: The `minTimeout` value in ms (1000)
* `x^k`: No need to change this, `x` will be your resulting factor
* `5 * 60 * 1000`: The desired total amount of time for retrying in ms (5 minutes)

To make this a little easier for you, use wolfram alpha to do the calculations:

<http://www.wolframalpha.com/input/?i=Sum%5B1000*x^k%2C+{k%2C+0%2C+9}%5D+%3D+5+*+60+*+1000>

[article]: http://dthain.blogspot.com/2009/02/exponential-backoff-in-distributed.html

### retry.createTimeout(attempt, opts)

Returns a new `timeout` (integer in milliseconds) based on the given parameters.

`attempt` is an integer representing for which retry the timeout should be calculated. If your retry operation was executed 4 times you had one attempt and 3 retries. If you then want to calculate a new timeout, you should set `attempt` to 4 (attempts are zero-indexed).

`opts` can include `factor`, `minTimeout`, `randomize` (boolean) and `maxTimeout`. They are documented above.

`retry.createTimeout()` is used internally by `retry.timeouts()` and is public for you to be able to create your own timeouts for reinserting an item, see [issue #13](https://github.com/tim-kos/node-retry/issues/13).

### retry.wrap(obj, [options], [methodNames])

Wrap all functions of the `obj` with retry. Optionally you can pass operation options and
an array of method names which need to be wrapped.

```
retry.wrap(obj)

retry.wrap(obj, ['method1', 'method2'])

retry.wrap(obj, {retries: 3})

retry.wrap(obj, {retries: 3}, ['method1', 'method2'])
```
The `options` object can take any options that the usual call to `retry.operation` can take.

### new RetryOperation(timeouts, [options])

Creates a new `RetryOperation` where `timeouts` is an array where each value is
a timeout given in milliseconds.

Available options:
* `forever`: Whether to retry forever, defaults to `false`.
* `unref`: Wether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`.

If `forever` is true, the following changes happen:
* `RetryOperation.errors()` will only output an array of one item: the last error.
* `RetryOperation` will repeatedly use the `timeouts` array. Once all of its timeouts have been used up, it restarts with the first timeout, then uses the second and so on.

#### retryOperation.errors()

Returns an array of all errors that have been passed to `retryOperation.retry()` so far. The
returning array has the errors ordered chronologically based on when they were passed to
`retryOperation.retry()`, which means the first passed error is at index zero and the last is
at the last index.

#### retryOperation.mainError()

A reference to the error object that occured most frequently. Errors are
compared using the `error.message` property.

If multiple error messages occured the same amount of time, the last error
object with that message is returned.

If no errors occured so far, the value is `null`.

#### retryOperation.attempt(fn, timeoutOps)

Defines the function `fn` that is to be retried and executes it for the first
time right away. The `fn` function can receive an optional `currentAttempt` callback that represents the number of attempts to execute `fn` so far.

Optionally defines `timeoutOps` which is an object having a property `timeout` in miliseconds and a property `cb` callback function.
Whenever your retry operation takes longer than `timeout` to execute, the timeout callback function `cb` is called.

#### retryOperation.try(fn)

This is an alias for `retryOperation.attempt(fn)`. This is deprecated. Please use `retryOperation.attempt(fn)` instead.

#### retryOperation.start(fn)

This is an alias for `retryOperation.attempt(fn)`. This is deprecated. Please use `retryOperation.attempt(fn)` instead.

#### retryOperation.retry(error)

Returns `false` when no `error` value is given, or the maximum amount of retries
has been reached.

Otherwise it returns `true`, and retries the operation after the timeout for
the current attempt number.

#### retryOperation.stop()

Allows you to stop the operation being retried. Useful for aborting the operation on a fatal error etc.

#### retryOperation.reset()

Resets the internal state of the operation object, so that you can call `attempt()` again as if this was a new operation object.

#### retryOperation.attempts()

Returns an int representing the number of attempts it took to call `fn` before it was successful.

## License

retry is licensed under the MIT license.

# Changelog

0.10.0 Adding `stop` functionality, thanks to @maxnachlinger.

0.9.0 Adding `unref` functionality, thanks to @satazor.

0.8.0 Implementing retry.wrap.

0.7.0 Some bug fixes and made retry.createTimeout() public. Fixed issues [#10](https://github.com/tim-kos/node-retry/issues/10), [#12](https://github.com/tim-kos/node-retry/issues/12), and [#13](https://github.com/tim-kos/node-retry/issues/13).

0.6.0 Introduced optional timeOps parameter for the attempt() function which is an object having a property timeout in milliseconds and a property cb callback function. Whenever your retry operation takes longer than timeout to execute, the timeout callback function cb is called.

0.5.0 Some minor refactoring.

0.4.0 Changed retryOperation.try() to retryOperation.attempt(). Deprecated the aliases start() and try() for it.

0.3.0 Added retryOperation.start() which is an alias for retryOperation.try().

0.2.0 Added attempts() function and parameter to retryOperation.try() representing the number of attempts it took to call fn().


code:
var dns = require('dns');
var retry = require('../lib/retry');

function faultTolerantResolve(address, cb) {
  var opts = {
    retries: 2,
    factor: 2,
    minTimeout: 1 * 1000,
    maxTimeout: 2 * 1000,
    randomize: true
  };
  var operation = retry.operation(opts);

  operation.attempt(function(currentAttempt) {
    dns.resolve(address, function(err, addresses) {
      if (operation.retry(err)) {
        return;
      }

      cb(operation.mainError(), operation.errors(), addresses);
    });
  });
}

faultTolerantResolve('nodejs.org', function(err, errors, addresses) {
  console.warn('err:');
  console.log(err);

  console.warn('addresses:');
  console.log(addresses);
});


code:
var retry = require('../lib/retry');

function attemptAsyncOperation(someInput, cb) {
  var opts = {
    retries: 2,
    factor: 2,
    minTimeout: 1 * 1000,
    maxTimeout: 2 * 1000,
    randomize: true
  };
  var operation = retry.operation(opts);

  operation.attempt(function(currentAttempt) {
    failingAsyncOperation(someInput, function(err, result) {

      if (err && err.message === 'A fatal error') {
        operation.stop();
        return cb(err);
      }

      if (operation.retry(err)) {
        return;
      }

      cb(operation.mainError(), operation.errors(), result);
    });
  });
}

attemptAsyncOperation('test input', function(err, errors, result) {
  console.warn('err:');
  console.log(err);

  console.warn('result:');
  console.log(result);
});

function failingAsyncOperation(input, cb) {
  return setImmediate(cb.bind(null, new Error('A fatal error')));
}


code:
var RetryOperation = require('./retry_operation');

exports.operation = function(options) {
  var timeouts = exports.timeouts(options);
  return new RetryOperation(timeouts, {
      forever: options && (options.forever || options.retries === Infinity),
      unref: options && options.unref,
      maxRetryTime: options && options.maxRetryTime
  });
};

exports.timeouts = function(options) {
  if (options instanceof Array) {
    return [].concat(options);
  }

  var opts = {
    retries: 10,
    factor: 2,
    minTimeout: 1 * 1000,
    maxTimeout: Infinity,
    randomize: false
  };
  for (var key in options) {
    opts[key] = options[key];
  }

  if (opts.minTimeout > opts.maxTimeout) {
    throw new Error('minTimeout is greater than maxTimeout');
  }

  var timeouts = [];
  for (var i = 0; i < opts.retries; i++) {
    timeouts.push(this.createTimeout(i, opts));
  }

  if (options && options.forever && !timeouts.length) {
    timeouts.push(this.createTimeout(i, opts));
  }

  // sort the array numerically ascending
  timeouts.sort(function(a,b) {
    return a - b;
  });

  return timeouts;
};

exports.createTimeout = function(attempt, opts) {
  var random = (opts.randomize)
    ? (Math.random() + 1)
    : 1;

  var timeout = Math.round(random * Math.max(opts.minTimeout, 1) * Math.pow(opts.factor, attempt));
  timeout = Math.min(timeout, opts.maxTimeout);

  return timeout;
};

exports.wrap = function(obj, options, methods) {
  if (options instanceof Array) {
    methods = options;
    options = null;
  }

  if (!methods) {
    methods = [];
    for (var key in obj) {
      if (typeof obj[key] === 'function') {
        methods.push(key);
      }
    }
  }

  for (var i = 0; i < methods.length; i++) {
    var method   = methods[i];
    var original = obj[method];

    obj[method] = function retryWrapper(original) {
      var op       = exports.operation(options);
      var args     = Array.prototype.slice.call(arguments, 1);
      var callback = args.pop();

      args.push(function(err) {
        if (op.retry(err)) {
          return;
        }
        if (err) {
          arguments[0] = op.mainError();
        }
        callback.apply(this, arguments);
      });

      op.attempt(function() {
        original.apply(obj, args);
      });
    }.bind(obj, original);
    obj[method].options = options;
  }
};


code:
function RetryOperation(timeouts, options) {
  // Compatibility for the old (timeouts, retryForever) signature
  if (typeof options === 'boolean') {
    options = { forever: options };
  }

  this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
  this._timeouts = timeouts;
  this._options = options || {};
  this._maxRetryTime = options && options.maxRetryTime || Infinity;
  this._fn = null;
  this._errors = [];
  this._attempts = 1;
  this._operationTimeout = null;
  this._operationTimeoutCb = null;
  this._timeout = null;
  this._operationStart = null;
  this._timer = null;

  if (this._options.forever) {
    this._cachedTimeouts = this._timeouts.slice(0);
  }
}
module.exports = RetryOperation;

RetryOperation.prototype.reset = function() {
  this._attempts = 1;
  this._timeouts = this._originalTimeouts.slice(0);
}

RetryOperation.prototype.stop = function() {
  if (this._timeout) {
    clearTimeout(this._timeout);
  }
  if (this._timer) {
    clearTimeout(this._timer);
  }

  this._timeouts       = [];
  this._cachedTimeouts = null;
};

RetryOperation.prototype.retry = function(err) {
  if (this._timeout) {
    clearTimeout(this._timeout);
  }

  if (!err) {
    return false;
  }
  var currentTime = new Date().getTime();
  if (err && currentTime - this._operationStart >= this._maxRetryTime) {
    this._errors.push(err);
    this._errors.unshift(new Error('RetryOperation timeout occurred'));
    return false;
  }

  this._errors.push(err);

  var timeout = this._timeouts.shift();
  if (timeout === undefined) {
    if (this._cachedTimeouts) {
      // retry forever, only keep last error
      this._errors.splice(0, this._errors.length - 1);
      timeout = this._cachedTimeouts.slice(-1);
    } else {
      return false;
    }
  }

  var self = this;
  this._timer = setTimeout(function() {
    self._attempts++;

    if (self._operationTimeoutCb) {
      self._timeout = setTimeout(function() {
        self._operationTimeoutCb(self._attempts);
      }, self._operationTimeout);

      if (self._options.unref) {
          self._timeout.unref();
      }
    }

    self._fn(self._attempts);
  }, timeout);

  if (this._options.unref) {
      this._timer.unref();
  }

  return true;
};

RetryOperation.prototype.attempt = function(fn, timeoutOps) {
  this._fn = fn;

  if (timeoutOps) {
    if (timeoutOps.timeout) {
      this._operationTimeout = timeoutOps.timeout;
    }
    if (timeoutOps.cb) {
      this._operationTimeoutCb = timeoutOps.cb;
    }
  }

  var self = this;
  if (this._operationTimeoutCb) {
    this._timeout = setTimeout(function() {
      self._operationTimeoutCb();
    }, self._operationTimeout);
  }

  this._operationStart = new Date().getTime();

  this._fn(this._attempts);
};

RetryOperation.prototype.try = function(fn) {
  console.log('Using RetryOperation.try() is deprecated');
  this.attempt(fn);
};

RetryOperation.prototype.start = function(fn) {
  console.log('Using RetryOperation.start() is deprecated');
  this.attempt(fn);
};

RetryOperation.prototype.start = RetryOperation.prototype.try;

RetryOperation.prototype.errors = function() {
  return this._errors;
};

RetryOperation.prototype.attempts = function() {
  return this._attempts;
};

RetryOperation.prototype.mainError = function() {
  if (this._errors.length === 0) {
    return null;
  }

  var counts = {};
  var mainError = null;
  var mainErrorCount = 0;

  for (var i = 0; i < this._errors.length; i++) {
    var error = this._errors[i];
    var message = error.message;
    var count = (counts[message] || 0) + 1;

    counts[message] = count;

    if (count >= mainErrorCount) {
      mainError = error;
      mainErrorCount = count;
    }
  }

  return mainError;
};


retry

author: Tim Koschützki <tim@debuggable.com> (http://debuggable.com/)

description: Abstraction for exponential and custom retry strategies for failed operations.

files: lib example

lib: ./lib

test: ./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape ./test/integration/*.js

release:major: env SEMANTIC=major npm run release

release:minor: env SEMANTIC=minor npm run release

release:patch: env SEMANTIC=patch npm run release

release: npm version ${SEMANTIC:-patch} -m "Release %s" && git push && git push --tags && npm publish


code:
language: node_js
sudo: false

node_js:
  - 9
  - 8
  - 7
  - 6
  - 5
  - 4
  - 4.0
  - iojs-v3
  - iojs-v2
  - iojs-v1
  - 0.12
  - 0.10

cache:
  directories:
    - node_modules

after_script:
- npm run coverage

notifications:
  email:
    on_success: never
    on_failure: always


code:
# reusify

[![npm version][npm-badge]][npm-url]
[![Build Status][travis-badge]][travis-url]
[![Coverage Status][coveralls-badge]][coveralls-url]

Reuse your objects and functions for maximum speed. This technique will
make any function run ~10% faster. You call your functions a
lot, and it adds up quickly in hot code paths.

```
$ node benchmarks/createNoCodeFunction.js
Total time 53133
Total iterations 100000000
Iteration/s 1882069.5236482036

$ node benchmarks/reuseNoCodeFunction.js
Total time 50617
Total iterations 100000000
Iteration/s 1975620.838848608
```

The above benchmark uses fibonacci to simulate a real high-cpu load.
The actual numbers might differ for your use case, but the difference
should not.

The benchmark was taken using Node v6.10.0.

This library was extracted from
[fastparallel](http://npm.im/fastparallel).

## Example

```js
var reusify = require('reusify')
var fib = require('reusify/benchmarks/fib')
var instance = reusify(MyObject)

// get an object from the cache,
// or creates a new one when cache is empty
var obj = instance.get()

// set the state
obj.num = 100
obj.func()

// reset the state.
// if the state contains any external object
// do not use delete operator (it is slow)
// prefer set them to null
obj.num = 0

// store an object in the cache
instance.release(obj)

function MyObject () {
  // you need to define this property
  // so V8 can compile MyObject into an
  // hidden class
  this.next = null
  this.num = 0

  var that = this

  // this function is never reallocated,
  // so it can be optimized by V8
  this.func = function () {
    if (null) {
      // do nothing
    } else {
      // calculates fibonacci
      fib(that.num)
    }
  }
}
```

The above example was intended for synchronous code, let's see async:
```js
var reusify = require('reusify')
var instance = reusify(MyObject)

for (var i = 0; i < 100; i++) {
  getData(i, console.log)
}

function getData (value, cb) {
  var obj = instance.get()

  obj.value = value
  obj.cb = cb
  obj.run()
}

function MyObject () {
  this.next = null
  this.value = null

  var that = this

  this.run = function () {
    asyncOperation(that.value, that.handle)
  }

  this.handle = function (err, result) {
    that.cb(err, result)
    that.value = null
    that.cb = null
    instance.release(that)
  }
}
```

Also note how in the above examples, the code, that consumes an istance of `MyObject`,
reset the state to initial condition, just before storing it in the cache.
That's needed so that every subsequent request for an instance from the cache,
could get a clean instance.

## Why

It is faster because V8 doesn't have to collect all the functions you
create. On a short-lived benchmark, it is as fast as creating the
nested function, but on a longer time frame it creates less
pressure on the garbage collector.

## Other examples
If you want to see some complex example, checkout [middie](https://github.com/fastify/middie) and [steed](https://github.com/mcollina/steed).

## Acknowledgements

Thanks to [Trevor Norris](https://github.com/trevnorris) for
getting me down the rabbit hole of performance, and thanks to [Mathias
Buss](http://github.com/mafintosh) for suggesting me to share this
trick.

## License

MIT

[npm-badge]: https://badge.fury.io/js/reusify.svg
[npm-url]: https://badge.fury.io/js/reusify
[travis-badge]: https://api.travis-ci.org/mcollina/reusify.svg
[travis-url]: https://travis-ci.org/mcollina/reusify
[coveralls-badge]: https://coveralls.io/repos/mcollina/reusify/badge.svg?branch=master&service=github
[coveralls-url]:  https://coveralls.io/github/mcollina/reusify?branch=master


code:
'use strict'

var fib = require('./fib')
var max = 100000000
var start = Date.now()

// create a funcion with the typical error
// pattern, that delegates the heavy load
// to something else
function createNoCodeFunction () {
  /* eslint no-constant-condition: "off" */
  var num = 100

  ;(function () {
    if (null) {
      // do nothing
    } else {
      fib(num)
    }
  })()
}

for (var i = 0; i < max; i++) {
  createNoCodeFunction()
}

var time = Date.now() - start
console.log('Total time', time)
console.log('Total iterations', max)
console.log('Iteration/s', max / time * 1000)


code:
'use strict'

function fib (num) {
  var fib = []

  fib[0] = 0
  fib[1] = 1
  for (var i = 2; i <= num; i++) {
    fib[i] = fib[i - 2] + fib[i - 1]
  }
}

module.exports = fib


code:
'use strict'

var reusify = require('../')
var fib = require('./fib')
var instance = reusify(MyObject)
var max = 100000000
var start = Date.now()

function reuseNoCodeFunction () {
  var obj = instance.get()
  obj.num = 100
  obj.func()
  obj.num = 0
  instance.release(obj)
}

function MyObject () {
  this.next = null
  var that = this
  this.num = 0
  this.func = function () {
    /* eslint no-constant-condition: "off" */
    if (null) {
      // do nothing
    } else {
      fib(that.num)
    }
  }
}

for (var i = 0; i < max; i++) {
  reuseNoCodeFunction()
}

var time = Date.now() - start
console.log('Total time', time)
console.log('Total iterations', max)
console.log('Iteration/s', max / time * 1000)


reusify

description: Reuse objects and functions with style

lint: standard

test: tape test.js | faucet

istanbul: istanbul cover tape test.js

coverage: npm run istanbul; cat coverage/lcov.info | coveralls

pre-commit: lint test

keywords: reuse object performance function fast


code:
'use strict'

function reusify (Constructor) {
  var head = new Constructor()
  var tail = head

  function get () {
    var current = head

    if (current.next) {
      head = current.next
    } else {
      head = new Constructor()
      tail = head
    }

    current.next = null

    return current
  }

  function release (obj) {
    tail.next = obj
    tail = obj
  }

  return {
    get: get,
    release: release
  }
}

module.exports = reusify


code:
'use strict'

var test = require('tape')
var reusify = require('./')

test('reuse objects', function (t) {
  t.plan(6)

  function MyObject () {
    t.pass('constructor called')
    this.next = null
  }

  var instance = reusify(MyObject)
  var obj = instance.get()

  t.notEqual(obj, instance.get(), 'two instance created')
  t.notOk(obj.next, 'next must be null')

  instance.release(obj)

  // the internals keeps a hot copy ready for reuse
  // putting this one back in the queue
  instance.release(instance.get())

  // comparing the old one with the one we got
  // never do this in real code, after release you
  // should never reuse that instance
  t.equal(obj, instance.get(), 'instance must be reused')
})

test('reuse more than 2 objects', function (t) {
  function MyObject () {
    t.pass('constructor called')
    this.next = null
  }

  var instance = reusify(MyObject)
  var obj = instance.get()
  var obj2 = instance.get()
  var obj3 = instance.get()

  t.notOk(obj.next, 'next must be null')
  t.notOk(obj2.next, 'next must be null')
  t.notOk(obj3.next, 'next must be null')

  t.notEqual(obj, obj2)
  t.notEqual(obj, obj3)
  t.notEqual(obj3, obj2)

  instance.release(obj)
  instance.release(obj2)
  instance.release(obj3)

  // skip one
  instance.get()

  var obj4 = instance.get()
  var obj5 = instance.get()
  var obj6 = instance.get()

  t.equal(obj4, obj)
  t.equal(obj5, obj2)
  t.equal(obj6, obj3)
  t.end()
})


code:
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        os: [ubuntu-latest]
        node-version: [8.x, 10.x, 12.x, 14.x, 16.x, 18.x, 20.x, 22.x]

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm install
    - run: npm run ci


code:
'use strict'

module.exports = require('./index.js')()


code:
declare namespace rfdc {
  interface Options {
    proto?: boolean;
    circles?: boolean;
    constructorHandlers?: ConstructorHandlerConfig[];
  }
}
type Constructor<T> = {new(...args: any[]): T};
type ConstructorHandlerConfig<T = any> = [Constructor<T>, (o: T) => T];

declare function rfdc(options?: rfdc.Options): <T>(input: T) => T;

export = rfdc;


code:
'use strict'
module.exports = rfdc

function copyBuffer (cur) {
  if (cur instanceof Buffer) {
    return Buffer.from(cur)
  }

  return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)
}

function rfdc (opts) {
  opts = opts || {}
  if (opts.circles) return rfdcCircles(opts)

  const constructorHandlers = new Map()
  constructorHandlers.set(Date, (o) => new Date(o))
  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))
  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))
  if (opts.constructorHandlers) {
    for (const handler of opts.constructorHandlers) {
      constructorHandlers.set(handler[0], handler[1])
    }
  }

  let handler = null

  return opts.proto ? cloneProto : clone

  function cloneArray (a, fn) {
    const keys = Object.keys(a)
    const a2 = new Array(keys.length)
    for (let i = 0; i < keys.length; i++) {
      const k = keys[i]
      const cur = a[k]
      if (typeof cur !== 'object' || cur === null) {
        a2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        a2[k] = handler(cur, fn)
      } else if (ArrayBuffer.isView(cur)) {
        a2[k] = copyBuffer(cur)
      } else {
        a2[k] = fn(cur)
      }
    }
    return a2
  }

  function clone (o) {
    if (typeof o !== 'object' || o === null) return o
    if (Array.isArray(o)) return cloneArray(o, clone)
    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
      return handler(o, clone)
    }
    const o2 = {}
    for (const k in o) {
      if (Object.hasOwnProperty.call(o, k) === false) continue
      const cur = o[k]
      if (typeof cur !== 'object' || cur === null) {
        o2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        o2[k] = handler(cur, clone)
      } else if (ArrayBuffer.isView(cur)) {
        o2[k] = copyBuffer(cur)
      } else {
        o2[k] = clone(cur)
      }
    }
    return o2
  }

  function cloneProto (o) {
    if (typeof o !== 'object' || o === null) return o
    if (Array.isArray(o)) return cloneArray(o, cloneProto)
    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
      return handler(o, cloneProto)
    }
    const o2 = {}
    for (const k in o) {
      const cur = o[k]
      if (typeof cur !== 'object' || cur === null) {
        o2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        o2[k] = handler(cur, cloneProto)
      } else if (ArrayBuffer.isView(cur)) {
        o2[k] = copyBuffer(cur)
      } else {
        o2[k] = cloneProto(cur)
      }
    }
    return o2
  }
}

function rfdcCircles (opts) {
  const refs = []
  const refsNew = []

  const constructorHandlers = new Map()
  constructorHandlers.set(Date, (o) => new Date(o))
  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))
  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))
  if (opts.constructorHandlers) {
    for (const handler of opts.constructorHandlers) {
      constructorHandlers.set(handler[0], handler[1])
    }
  }

  let handler = null
  return opts.proto ? cloneProto : clone

  function cloneArray (a, fn) {
    const keys = Object.keys(a)
    const a2 = new Array(keys.length)
    for (let i = 0; i < keys.length; i++) {
      const k = keys[i]
      const cur = a[k]
      if (typeof cur !== 'object' || cur === null) {
        a2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        a2[k] = handler(cur, fn)
      } else if (ArrayBuffer.isView(cur)) {
        a2[k] = copyBuffer(cur)
      } else {
        const index = refs.indexOf(cur)
        if (index !== -1) {
          a2[k] = refsNew[index]
        } else {
          a2[k] = fn(cur)
        }
      }
    }
    return a2
  }

  function clone (o) {
    if (typeof o !== 'object' || o === null) return o
    if (Array.isArray(o)) return cloneArray(o, clone)
    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
      return handler(o, clone)
    }
    const o2 = {}
    refs.push(o)
    refsNew.push(o2)
    for (const k in o) {
      if (Object.hasOwnProperty.call(o, k) === false) continue
      const cur = o[k]
      if (typeof cur !== 'object' || cur === null) {
        o2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        o2[k] = handler(cur, clone)
      } else if (ArrayBuffer.isView(cur)) {
        o2[k] = copyBuffer(cur)
      } else {
        const i = refs.indexOf(cur)
        if (i !== -1) {
          o2[k] = refsNew[i]
        } else {
          o2[k] = clone(cur)
        }
      }
    }
    refs.pop()
    refsNew.pop()
    return o2
  }

  function cloneProto (o) {
    if (typeof o !== 'object' || o === null) return o
    if (Array.isArray(o)) return cloneArray(o, cloneProto)
    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {
      return handler(o, cloneProto)
    }
    const o2 = {}
    refs.push(o)
    refsNew.push(o2)
    for (const k in o) {
      const cur = o[k]
      if (typeof cur !== 'object' || cur === null) {
        o2[k] = cur
      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {
        o2[k] = handler(cur, cloneProto)
      } else if (ArrayBuffer.isView(cur)) {
        o2[k] = copyBuffer(cur)
      } else {
        const i = refs.indexOf(cur)
        if (i !== -1) {
          o2[k] = refsNew[i]
        } else {
          o2[k] = cloneProto(cur)
        }
      }
    }
    refs.pop()
    refsNew.pop()
    return o2
  }
}


code:
import { expectType } from 'tsd';
import rfdc = require('.');

const clone = rfdc();

expectType<number>(clone(5));
expectType<{ lorem: string }>(clone({ lorem: "ipsum" }));

const cloneHandlers = rfdc({
  constructorHandlers: [
    [RegExp, (o) => new RegExp(o)],
  ],
})


rfdc

description: Really Fast Deep Clone

test: tap -R min test && npm run lint

bench: node benchmark

lint: standard --fix

cov: tap --100 test

cov-ui: tap --coverage-report=html test

ci: standard && tap --100 --coverage-report=text-lcov test | codecov --pipe

keywords: object obj properties clone copy deep recursive key keys values prop deep-clone deepclone deep-copy deepcopy fast performance performant fastclone fastcopy fast-clone fast-deep-clone fast-copy fast-deep-copy

author: David Mark Clements <david.clements@nearform.com>

test: test


code:
# rfdc

Really Fast Deep Clone

[![build status](https://img.shields.io/travis/davidmarkclements/rfdc.svg)](https://travis-ci.org/davidmarkclements/rfdc)
[![coverage](https://img.shields.io/codecov/c/github/davidmarkclements/rfdc.svg)](https://codecov.io/gh/davidmarkclements/rfdc)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)

## Usage

```js
const clone = require('rfdc')()
clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
```

## API

### `require('rfdc')(opts = { proto: false, circles: false, constructorHandlers: [] }) => clone(obj) => obj2`

#### `proto` option

Copy prototype properties as well as own properties into the new object.

It's marginally faster to allow enumerable properties on the prototype
to be copied into the cloned object (not onto it's prototype, directly onto the object).

To explain by way of code:

```js
require('rfdc')({ proto: false })(Object.create({a: 1})) // => {}
require('rfdc')({ proto: true })(Object.create({a: 1})) // => {a: 1}
```

Setting `proto` to `true` will provide an additional 2% performance boost.

#### `circles` option

Keeping track of circular references will slow down performance with an
additional 25% overhead. Even if an object doesn't have any circular references,
the tracking overhead is the cost. By default if an object with a circular
reference is passed to `rfdc`, it will throw (similar to how `JSON.stringify` \
would throw).

Use the `circles` option to detect and preserve circular references in the
object. If performance is important, try removing the circular reference from
the object (set to `undefined`) and then add it back manually after cloning
instead of using this option.

#### `constructorHandlers` option

Sometimes consumers may want to add custom clone behaviour for particular classes
(for example `RegExp` or `ObjectId`, which aren't supported out-of-the-box).

This can be done by passing `constructorHandlers`, which takes an array of tuples,
where the first item is the class to match, and the second item is a function that
takes the input and returns a cloned output:

```js
const clone = require('rfdc')({
  constructorHandlers: [
    [RegExp, (o) => new RegExp(o)],
  ]
})

clone({r: /foo/}) // => {r: /foo/}
```

**NOTE**: For performance reasons, the handlers will only match an instance of the
*exact* class (not a subclass). Subclasses will need to be added separately if they
also need special clone behaviour.

### `default` import
It is also possible to directly import the clone function with all options set
to their default:

```js
const clone = require("rfdc/default")
clone({a: 1, b: {c: 2}}) // => {a: 1, b: {c: 2}}
```

### Types

`rfdc` clones all JSON types:

* `Object`
* `Array`
* `Number`
* `String`
* `null`

With additional support for:

* `Date` (copied)
* `undefined` (copied)
* `Buffer` (copied)
* `TypedArray` (copied)
* `Map` (copied)
* `Set` (copied)
* `Function` (referenced)
* `AsyncFunction` (referenced)
* `GeneratorFunction` (referenced)
* `arguments` (copied to a normal object)

All other types have output values that match the output
of `JSON.parse(JSON.stringify(o))`.

For instance:

```js
const rfdc = require('rfdc')()
const err = Error()
err.code = 1
JSON.parse(JSON.stringify(e)) // {code: 1}
rfdc(e) // {code: 1}

JSON.parse(JSON.stringify({rx: /foo/})) // {rx: {}}
rfdc({rx: /foo/}) // {rx: {}}
```

## Benchmarks

```sh
npm run bench
```

```
benchDeepCopy*100: 671.675ms
benchLodashCloneDeep*100: 1.574s
benchCloneDeep*100: 936.792ms
benchFastCopy*100: 822.668ms
benchFastestJsonCopy*100: 363.898ms // See note below
benchPlainObjectClone*100: 556.635ms
benchNanoCopy*100: 770.234ms
benchRamdaClone*100: 2.695s
benchJsonParseJsonStringify*100: 2.290s // JSON.parse(JSON.stringify(obj))
benchRfdc*100: 412.818ms
benchRfdcProto*100: 424.076ms
benchRfdcCircles*100: 443.357ms
benchRfdcCirclesProto*100: 465.053ms
```

It is true that [fastest-json-copy](https://www.npmjs.com/package/fastest-json-copy) may be faster, BUT it has such huge limitations that it is rarely useful. For example, it treats things like `Date` and `Map` instances the same as empty `{}`. It can't handle circular references. [plain-object-clone](https://www.npmjs.com/package/plain-object-clone) is also really limited in capability.

## Tests

```sh
npm test
```

```
169 passing (342.514ms)
```

### Coverage

```sh
npm run cov
```

```
----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.js |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
```

### `__proto__` own property copying

`rfdc` works the same way as `Object.assign` when it comes to copying `['__proto__']` (e.g. when
an object has an own property key called '__proto__'). It results in the target object
prototype object being set per the value of the `['__proto__']` own property.

For detailed write-up on how a way to handle this security-wise see https://www.fastify.io/docs/latest/Guides/Prototype-Poisoning/.

## License

MIT


code:
'use strict'

const { test } = require('tap')
const rfdc = require('..')
const cloneDefault = require('../default')
const clone = rfdc()
const cloneProto = rfdc({ proto: true })
const cloneCircles = rfdc({ circles: true })
const cloneCirclesProto = rfdc({ circles: true, proto: true })

const rnd = (max) => Math.round(Math.random() * max)

types(clone, 'default')
types(cloneProto, 'proto option')
types(cloneCircles, 'circles option')
types(cloneCirclesProto, 'circles and proto option')

test('default – does not copy proto properties', async ({ is }) => {
  is(clone(Object.create({ a: 1 })).a, undefined, 'value not copied')
})
test('default – shorthand import', async ({ same }) => {
  same(
    clone(Object.create({ a: 1 })),
    cloneDefault(Object.create({ a: 1 })),
    'import equals clone with default options'
  )
})
test('proto option – copies enumerable proto properties', async ({ is }) => {
  is(cloneProto(Object.create({ a: 1 })).a, 1, 'value copied')
})
test('circles option - circular object', async ({ same, is, isNot }) => {
  const o = { nest: { a: 1, b: 2 } }
  o.circular = o
  same(cloneCircles(o), o, 'same values')
  isNot(cloneCircles(o), o, 'different objects')
  isNot(cloneCircles(o).nest, o.nest, 'different nested objects')
  const c = cloneCircles(o)
  is(c.circular, c, 'circular references point to copied parent')
  isNot(c.circular, o, 'circular references do not point to original parent')
})
test('circles option – deep circular object', async ({ same, is, isNot }) => {
  const o = { nest: { a: 1, b: 2 } }
  o.nest.circular = o
  same(cloneCircles(o), o, 'same values')
  isNot(cloneCircles(o), o, 'different objects')
  isNot(cloneCircles(o).nest, o.nest, 'different nested objects')
  const c = cloneCircles(o)
  is(c.nest.circular, c, 'circular references point to copied parent')
  isNot(
    c.nest.circular,
    o,
    'circular references do not point to original parent'
  )
})
test('circles option alone – does not copy proto properties', async ({
  is
}) => {
  is(cloneCircles(Object.create({ a: 1 })).a, undefined, 'value not copied')
})
test('circles and proto option – copies enumerable proto properties', async ({
  is
}) => {
  is(cloneCirclesProto(Object.create({ a: 1 })).a, 1, 'value copied')
})
test('circles and proto option - circular object', async ({
  same,
  is,
  isNot
}) => {
  const o = { nest: { a: 1, b: 2 } }
  o.circular = o
  same(cloneCirclesProto(o), o, 'same values')
  isNot(cloneCirclesProto(o), o, 'different objects')
  isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
  const c = cloneCirclesProto(o)
  is(c.circular, c, 'circular references point to copied parent')
  isNot(c.circular, o, 'circular references do not point to original parent')
})
test('circles and proto option – deep circular object', async ({
  same,
  is,
  isNot
}) => {
  const o = { nest: { a: 1, b: 2 } }
  o.nest.circular = o
  same(cloneCirclesProto(o), o, 'same values')
  isNot(cloneCirclesProto(o), o, 'different objects')
  isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
  const c = cloneCirclesProto(o)
  is(c.nest.circular, c, 'circular references point to copied parent')
  isNot(
    c.nest.circular,
    o,
    'circular references do not point to original parent'
  )
})
test('circles and proto option – deep circular array', async ({
  same,
  is,
  isNot
}) => {
  const o = { nest: [1, 2] }
  o.nest.push(o)
  same(cloneCirclesProto(o), o, 'same values')
  isNot(cloneCirclesProto(o), o, 'different objects')
  isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
  const c = cloneCirclesProto(o)
  is(c.nest[2], c, 'circular references point to copied parent')
  isNot(c.nest[2], o, 'circular references do not point to original parent')
})
test('custom constructor handler', async ({ same, ok, isNot }) => {
  class Foo {
    constructor (s) {
      this.s = s
    }
  }
  const data = { foo: new Foo('foo') }
  const cloned = rfdc({ constructorHandlers: [[Foo, (o) => new Foo(o.s)]] })(data)
  ok(cloned.foo instanceof Foo)
  same(cloned.foo.s, data.foo.s, 'same values')
  isNot(cloned.foo, data.foo, 'different objects')
})
test('custom RegExp handler', async ({ same, ok, isNot }) => {
  const data = { regex: /foo/ }
  const cloned = rfdc({ constructorHandlers: [[RegExp, (o) => new RegExp(o)]] })(data)
  isNot(cloned.regex, data.regex, 'different objects')
  ok(cloned.regex.test('foo'))
})

function types (clone, label) {
  test(label + ' – number', async ({ is }) => {
    is(clone(42), 42, 'same value')
  })
  test(label + ' – string', async ({ is }) => {
    is(clone('str'), 'str', 'same value')
  })
  test(label + ' – boolean', async ({ is }) => {
    is(clone(true), true, 'same value')
  })
  test(label + ' – function', async ({ is }) => {
    const fn = () => {}
    is(clone(fn), fn, 'same function')
  })
  test(label + ' – async function', async ({ is }) => {
    const fn = async () => {}
    is(clone(fn), fn, 'same function')
  })
  test(label + ' – generator function', async ({ is }) => {
    const fn = function * () {}
    is(clone(fn), fn, 'same function')
  })
  test(label + ' – date', async ({ is, isNot }) => {
    const date = new Date()
    is(+clone(date), +date, 'same value')
    isNot(clone(date), date, 'different object')
  })
  test(label + ' – null', async ({ is }) => {
    is(clone(null), null, 'same value')
  })
  test(label + ' – shallow object', async ({ same, isNot }) => {
    const o = { a: 1, b: 2 }
    same(clone(o), o, 'same values')
    isNot(clone(o), o, 'different object')
  })
  test(label + ' – shallow array', async ({ same, isNot }) => {
    const o = [1, 2]
    same(clone(o), o, 'same values')
    isNot(clone(o), o, 'different arrays')
  })
  test(label + ' – deep object', async ({ same, isNot }) => {
    const o = { nest: { a: 1, b: 2 } }
    same(clone(o), o, 'same values')
    isNot(clone(o), o, 'different objects')
    isNot(clone(o).nest, o.nest, 'different nested objects')
  })
  test(label + ' – deep array', async ({ same, isNot }) => {
    const o = [{ a: 1, b: 2 }, [3]]
    same(clone(o), o, 'same values')
    isNot(clone(o), o, 'different arrays')
    isNot(clone(o)[0], o[0], 'different array elements')
    isNot(clone(o)[1], o[1], 'different array elements')
  })
  test(label + ' – nested number', async ({ is }) => {
    is(clone({ a: 1 }).a, 1, 'same value')
  })
  test(label + ' – nested string', async ({ is }) => {
    is(clone({ s: 'str' }).s, 'str', 'same value')
  })
  test(label + ' – nested boolean', async ({ is }) => {
    is(clone({ b: true }).b, true, 'same value')
  })
  test(label + ' – nested function', async ({ is }) => {
    const fn = () => {}
    is(clone({ fn }).fn, fn, 'same function')
  })
  test(label + ' – nested async function', async ({ is }) => {
    const fn = async () => {}
    is(clone({ fn }).fn, fn, 'same function')
  })
  test(label + ' – nested generator function', async ({ is }) => {
    const fn = function * () {}
    is(clone({ fn }).fn, fn, 'same function')
  })
  test(label + ' – nested date', async ({ is, isNot }) => {
    const date = new Date()
    is(+clone({ d: date }).d, +date, 'same value')
    isNot(clone({ d: date }).d, date, 'different object')
  })
  test(label + ' – nested date in array', async ({ is, isNot }) => {
    const date = new Date()
    is(+clone({ d: [date] }).d[0], +date, 'same value')
    isNot(clone({ d: [date] }).d[0], date, 'different object')
    is(+cloneCircles({ d: [date] }).d[0], +date, 'same value')
    isNot(cloneCircles({ d: [date] }).d, date, 'different object')
  })
  test(label + ' – nested null', async ({ is }) => {
    is(clone({ n: null }).n, null, 'same value')
  })
  test(label + ' – arguments', async ({ isNot, same }) => {
    function fn (...args) {
      same(clone(arguments), args, 'same values')
      isNot(clone(arguments), arguments, 'different object')
    }
    fn(1, 2, 3)
  })
  test(`${label} copies buffers from object correctly`, async ({ ok, is, isNot }) => {
    const input = Date.now().toString(36)
    const inputBuffer = Buffer.from(input)
    const clonedBuffer = clone({ a: inputBuffer }).a
    ok(Buffer.isBuffer(clonedBuffer), 'cloned value is buffer')
    isNot(clonedBuffer, inputBuffer, 'cloned buffer is not same as input buffer')
    is(clonedBuffer.toString(), input, 'cloned buffer content is correct')
  })
  test(`${label} copies buffers from arrays correctly`, async ({ ok, is, isNot }) => {
    const input = Date.now().toString(36)
    const inputBuffer = Buffer.from(input)
    const [clonedBuffer] = clone([inputBuffer])
    ok(Buffer.isBuffer(clonedBuffer), 'cloned value is buffer')
    isNot(clonedBuffer, inputBuffer, 'cloned buffer is not same as input buffer')
    is(clonedBuffer.toString(), input, 'cloned buffer content is correct')
  })
  test(`${label} copies TypedArrays from object correctly`, async ({ ok, is, isNot }) => {
    const [input1, input2] = [rnd(10), rnd(10)]
    const buffer = new ArrayBuffer(8)
    const int32View = new Int32Array(buffer)
    int32View[0] = input1
    int32View[1] = input2
    const cloned = clone({ a: int32View }).a
    ok(cloned instanceof Int32Array, 'cloned value is instance of class')
    isNot(cloned, int32View, 'cloned value is not same as input value')
    is(cloned[0], input1, 'cloned value content is correct')
    is(cloned[1], input2, 'cloned value content is correct')
  })
  test(`${label} copies TypedArrays from array correctly`, async ({ ok, is, isNot }) => {
    const [input1, input2] = [rnd(10), rnd(10)]
    const buffer = new ArrayBuffer(16)
    const int32View = new Int32Array(buffer)
    int32View[0] = input1
    int32View[1] = input2
    const [cloned] = clone([int32View])
    ok(cloned instanceof Int32Array, 'cloned value is instance of class')
    isNot(cloned, int32View, 'cloned value is not same as input value')
    is(cloned[0], input1, 'cloned value content is correct')
    is(cloned[1], input2, 'cloned value content is correct')
  })
  test(`${label} copies complex TypedArrays`, async ({ ok, deepEqual, is, isNot }) => {
    const [input1, input2, input3] = [rnd(10), rnd(10), rnd(10)]
    const buffer = new ArrayBuffer(4)
    const view1 = new Int8Array(buffer, 0, 2)
    const view2 = new Int8Array(buffer, 2, 2)
    const view3 = new Int8Array(buffer)
    view1[0] = input1
    view2[0] = input2
    view3[3] = input3
    const cloned = clone({ view1, view2, view3 })
    ok(cloned.view1 instanceof Int8Array, 'cloned value is instance of class')
    ok(cloned.view2 instanceof Int8Array, 'cloned value is instance of class')
    ok(cloned.view3 instanceof Int8Array, 'cloned value is instance of class')
    isNot(cloned.view1, view1, 'cloned value is not same as input value')
    isNot(cloned.view2, view2, 'cloned value is not same as input value')
    isNot(cloned.view3, view3, 'cloned value is not same as input value')
    deepEqual(Array.from(cloned.view1), [input1, 0], 'cloned value content is correct')
    deepEqual(Array.from(cloned.view2), [input2, input3], 'cloned value content is correct')
    deepEqual(Array.from(cloned.view3), [input1, 0, input2, input3], 'cloned value content is correct')
  })
  test(`${label} - maps`, async ({ same, isNot }) => {
    const map = new Map([['a', 1]])
    same(Array.from(clone(map)), [['a', 1]], 'same value')
    isNot(clone(map), map, 'different object')
  })
  test(`${label} - sets`, async ({ same, isNot }) => {
    const set = new Set([1])
    same(Array.from(clone(set)), [1])
    isNot(clone(set), set, 'different object')
  })
  test(`${label} - nested maps`, async ({ same, isNot }) => {
    const data = { m: new Map([['a', 1]]) }
    same(Array.from(clone(data).m), [['a', 1]], 'same value')
    isNot(clone(data).m, data.m, 'different object')
  })
  test(`${label} - nested sets`, async ({ same, isNot }) => {
    const data = { s: new Set([1]) }
    same(Array.from(clone(data).s), [1], 'same value')
    isNot(clone(data).s, data.s, 'different object')
  })
}


code:
# v3.0

- Add `--preserve-root` option to executable (default true)
- Drop support for Node.js below version 6

# v2.7

- Make `glob` an optional dependency

# 2.6

- Retry on EBUSY on non-windows platforms as well
- Make `rimraf.sync` 10000% more reliable on Windows

# 2.5

- Handle Windows EPERM when lstat-ing read-only dirs
- Add glob option to pass options to glob

# 2.4

- Add EPERM to delay/retry loop
- Add `disableGlob` option

# 2.3

- Make maxBusyTries and emfileWait configurable
- Handle weird SunOS unlink-dir issue
- Glob the CLI arg for better Windows support

# 2.2

- Handle ENOENT properly on Windows
- Allow overriding fs methods
- Treat EPERM as indicative of non-empty dir
- Remove optional graceful-fs dep
- Consistently return null error instead of undefined on success
- win32: Treat ENOTEMPTY the same as EBUSY
- Add `rimraf` binary

# 2.1

- Fix SunOS error code for a non-empty directory
- Try rmdir before readdir
- Treat EISDIR like EPERM
- Remove chmod
- Remove lstat polyfill, node 0.7 is not supported

# 2.0

- Fix myGid call to check process.getgid
- Simplify the EBUSY backoff logic.
- Use fs.lstat in node >= 0.7.9
- Remove gently option
- remove fiber implementation
- Delete files that are marked read-only

# 1.0

- Allow ENOENT in sync method
- Throw when no callback is provided
- Make opts.gently an absolute path
- use 'stat' if 'lstat' is not available
- Consistent error naming, and rethrow non-ENOENT stat errors
- add fiber implementation


code:
[![Build Status](https://travis-ci.org/isaacs/rimraf.svg?branch=master)](https://travis-ci.org/isaacs/rimraf) [![Dependency Status](https://david-dm.org/isaacs/rimraf.svg)](https://david-dm.org/isaacs/rimraf) [![devDependency Status](https://david-dm.org/isaacs/rimraf/dev-status.svg)](https://david-dm.org/isaacs/rimraf#info=devDependencies)

The [UNIX command](http://en.wikipedia.org/wiki/Rm_(Unix)) `rm -rf` for node.

Install with `npm install rimraf`, or just drop rimraf.js somewhere.

## API

`rimraf(f, [opts], callback)`

The first parameter will be interpreted as a globbing pattern for files. If you
want to disable globbing you can do so with `opts.disableGlob` (defaults to
`false`). This might be handy, for instance, if you have filenames that contain
globbing wildcard characters.

The callback will be called with an error if there is one.  Certain
errors are handled for you:

* Windows: `EBUSY` and `ENOTEMPTY` - rimraf will back off a maximum of
  `opts.maxBusyTries` times before giving up, adding 100ms of wait
  between each attempt.  The default `maxBusyTries` is 3.
* `ENOENT` - If the file doesn't exist, rimraf will return
  successfully, since your desired outcome is already the case.
* `EMFILE` - Since `readdir` requires opening a file descriptor, it's
  possible to hit `EMFILE` if too many file descriptors are in use.
  In the sync case, there's nothing to be done for this.  But in the
  async case, rimraf will gradually back off with timeouts up to
  `opts.emfileWait` ms, which defaults to 1000.

## options

* unlink, chmod, stat, lstat, rmdir, readdir,
  unlinkSync, chmodSync, statSync, lstatSync, rmdirSync, readdirSync

    In order to use a custom file system library, you can override
    specific fs functions on the options object.

    If any of these functions are present on the options object, then
    the supplied function will be used instead of the default fs
    method.

    Sync methods are only relevant for `rimraf.sync()`, of course.

    For example:

    ```javascript
    var myCustomFS = require('some-custom-fs')

    rimraf('some-thing', myCustomFS, callback)
    ```

* maxBusyTries

    If an `EBUSY`, `ENOTEMPTY`, or `EPERM` error code is encountered
    on Windows systems, then rimraf will retry with a linear backoff
    wait of 100ms longer on each try.  The default maxBusyTries is 3.

    Only relevant for async usage.

* emfileWait

    If an `EMFILE` error is encountered, then rimraf will retry
    repeatedly with a linear backoff of 1ms longer on each try, until
    the timeout counter hits this max.  The default limit is 1000.

    If you repeatedly encounter `EMFILE` errors, then consider using
    [graceful-fs](http://npm.im/graceful-fs) in your program.

    Only relevant for async usage.

* glob

    Set to `false` to disable [glob](http://npm.im/glob) pattern
    matching.

    Set to an object to pass options to the glob module.  The default
    glob options are `{ nosort: true, silent: true }`.

    Glob version 6 is used in this module.

    Relevant for both sync and async usage.

* disableGlob

    Set to any non-falsey value to disable globbing entirely.
    (Equivalent to setting `glob: false`.)

## rimraf.sync

It can remove stuff synchronously, too.  But that's not so good.  Use
the async API.  It's better.

## CLI

If installed with `npm install rimraf -g` it can be used as a global
command `rimraf <path> [<path> ...]` which is useful for cross platform support.

## mkdirp

If you need to create a directory recursively, check out
[mkdirp](https://github.com/substack/node-mkdirp).


code:
#!/usr/bin/env node

const rimraf = require('./')

const path = require('path')

const isRoot = arg => /^(\/|[a-zA-Z]:\\)$/.test(path.resolve(arg))
const filterOutRoot = arg => {
  const ok = preserveRoot === false || !isRoot(arg)
  if (!ok) {
    console.error(`refusing to remove ${arg}`)
    console.error('Set --no-preserve-root to allow this')
  }
  return ok
}

let help = false
let dashdash = false
let noglob = false
let preserveRoot = true
const args = process.argv.slice(2).filter(arg => {
  if (dashdash)
    return !!arg
  else if (arg === '--')
    dashdash = true
  else if (arg === '--no-glob' || arg === '-G')
    noglob = true
  else if (arg === '--glob' || arg === '-g')
    noglob = false
  else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))
    help = true
  else if (arg === '--preserve-root')
    preserveRoot = true
  else if (arg === '--no-preserve-root')
    preserveRoot = false
  else
    return !!arg
}).filter(arg => !preserveRoot || filterOutRoot(arg))

const go = n => {
  if (n >= args.length)
    return
  const options = noglob ? { glob: false } : {}
  rimraf(args[n], options, er => {
    if (er)
      throw er
    go(n+1)
  })
}

if (help || args.length === 0) {
  // If they didn't ask for help, then this is not a "success"
  const log = help ? console.log : console.error
  log('Usage: rimraf <path> [<path> ...]')
  log('')
  log('  Deletes all files and folders at "path" recursively.')
  log('')
  log('Options:')
  log('')
  log('  -h, --help          Display this usage info')
  log('  -G, --no-glob       Do not expand glob patterns in arguments')
  log('  -g, --glob          Expand glob patterns in arguments (default)')
  log('  --preserve-root     Do not remove \'/\' (default)')
  log('  --no-preserve-root  Do not treat \'/\' specially')
  log('  --                  Stop parsing flags')
  process.exit(help ? 0 : 1)
} else
  go(0)


rimraf

description: A deep deletion module for node (like `rm -rf`)

author: Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)

postpublish: git push origin --follow-tags

test: tap test/*.js