UNPKG

rwlockfile

Version:

lockfile utility with reader/writers

97 lines (96 loc) 3.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function lockfile(prop, opts = {}) { const Lockfile = require('./lockfile').default; return methodDecorator(function ({ original, propertyName }) { return function (...args) { const lockfile = this[prop]; if (!(lockfile instanceof Lockfile)) { throw new Error('prop does not point to a Lockfile instance'); } if (opts.sync) { lockfile.addSync({ reason: propertyName.toString() }); try { return original.apply(this, args); } finally { lockfile.removeSync(); } } else { return (async () => { await lockfile.add({ reason: propertyName.toString() }); try { return await original.apply(this, args); } finally { await lockfile.remove(); } })(); } }; }); } exports.lockfile = lockfile; function rwlockfile(prop, type, opts = {}) { const RWLockfile = require('./rwlockfile').default; return methodDecorator(function ({ original, propertyName }) { return async function (...args) { const lockfile = this[prop]; if (!(lockfile instanceof RWLockfile)) { throw new Error('prop does not point to a Lockfile instance'); } const addOpts = { reason: propertyName.toString(), }; if (opts.ifLocked) { addOpts.ifLocked = () => this[opts.ifLocked](); } await lockfile.add(type, addOpts); let result; try { result = await original.apply(this, args); } finally { await lockfile.remove(type); } return result; }; }); } exports.rwlockfile = rwlockfile; function onceAtATime(argKey) { return methodDecorator(function ({ original }) { const key = Symbol('onceAtATime'); return async function (...args) { const subKey = argKey !== undefined ? args[argKey] : key; const cache = (this[key] = this[key] || {}); if (cache[subKey]) return cache[subKey]; cache[subKey] = original.apply(this, args); try { return await cache[subKey]; } finally { delete cache[subKey]; } }; }); } exports.onceAtATime = onceAtATime; function methodDecorator(fn) { return (target, propertyName, descriptor) => { if (isMethodDecorator(descriptor)) { descriptor.value = fn({ target, propertyName, descriptor, original: descriptor.value }); return descriptor; } else { throw new Error(`${propertyName} on ${target} is not a a method`); } }; } function isMethodDecorator(prop) { if (!prop) return false; return !!prop.value; }