/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /** * Redux middleware for debouncing actions. * * Schedules actions with { meta: { debounce: true } } to be delayed * by wait milliseconds. If another action is fired during this * time-frame both actions are inserted into a queue and delayed. * Maximum delay is defined by maxWait argument. * * Handling more actions at once results in better performance since * components need to be re-rendered less often. * * @param string wait Wait for specified amount of milliseconds * before executing an action. The time is used * to collect more actions and handle them all * at once. * @param string maxWait Max waiting time. It's used in case of * a long stream of actions. */ function debounceActions(wait, maxWait) { let queuedActions = []; return () => next => { const debounced = debounce( () => { next(batchActions(queuedActions)); queuedActions = []; }, wait, maxWait ); return action => { if (!action.meta || !action.meta.debounce) { return next(action); } if (!wait || !maxWait) { return next(action); } if (action.type == BATCH_ACTIONS) { queuedActions.push(...action.actions); } else { queuedActions.push(action); } return debounced(); }; }; } function debounce(cb, wait, maxWait) { let timeout, maxTimeout; const doFunction = () => { clearTimeout(timeout); clearTimeout(maxTimeout); timeout = maxTimeout = null; cb(); }; return () => { return new Promise(resolve => { const onTimeout = () => { doFunction(); resolve(); }; clearTimeout(timeout); timeout = setTimeout(onTimeout, wait); if (!maxTimeout) { maxTimeout = setTimeout(onTimeout, maxWait); } }); }; } const BATCH_ACTIONS = Symbol("BATCH_ACTIONS"); /** * Action creator for action-batching. */ function batchActions(batchedActions, debounceFlag = true) { return { type: BATCH_ACTIONS, meta: { debounce: debounceFlag }, actions: batchedActions, }; } module.exports = { BATCH_ACTIONS, batchActions, debounceActions, };