"use strict"; const Promise = require("bluebird"); const ms = require("ms"); const promiseDelayEvery = require("@joepie91/promise-delay-every"); const propagateAbort = require("@promistream/propagate-abort"); const propagatePeek = require("@promistream/propagate-peek"); const debug = require("debug")("promistream:rate-limit"); function makeClonableInstance(interval) { let intervalInMilliseconds = (typeof interval === "number") ? interval : ms(interval); debug(`Creating clonable with interval of ${intervalInMilliseconds}ms`); let delayer = promiseDelayEvery(intervalInMilliseconds); return function createClone () { debug("Creating clone"); return { _promistreamVersion: 0, description: `rate-limited stream (1 per ${interval})`, read: (source) => { return Promise.try(() => { debug("Attempted read"); return delayer(); }).then(() => { debug("Delay passed, completing read"); return source.read(); }); }, peek: propagatePeek, abort: propagateAbort }; }; } module.exports = function rateLimitedStream(... args) { // Internally, we treat a non-clonable stream as a clonable stream that will only ever have one clone - this makes implementation much simpler let createClone = makeClonableInstance(... args); return createClone(); }; module.exports.clonable = makeClonableInstance;