forked from mirrors/gecko-dev
		
	# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D35884 --HG-- extra : source : 60e4496cf9699dc59f2f4738cb60f87cbdb01e67
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* 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";
 | 
						|
 | 
						|
/**
 | 
						|
 * A middleware which acts like a service, because it is stateful
 | 
						|
 * and "long-running" in the background. It provides the ability
 | 
						|
 * for actions to install a function to be run once when a specific
 | 
						|
 * condition is met by an action coming through the system. Think of
 | 
						|
 * it as a thunk that blocks until the condition is met. Example:
 | 
						|
 *
 | 
						|
 * ```js
 | 
						|
 * const services = { WAIT_UNTIL: require('wait-service').NAME };
 | 
						|
 *
 | 
						|
 * { type: services.WAIT_UNTIL,
 | 
						|
 *   predicate: action => action.type === constants.ADD_ITEM,
 | 
						|
 *   run: (dispatch, getState, action) => {
 | 
						|
 *     // Do anything here. You only need to accept the arguments
 | 
						|
 *     // if you need them. `action` is the action that satisfied
 | 
						|
 *     // the predicate.
 | 
						|
 *   }
 | 
						|
 * }
 | 
						|
 * ```
 | 
						|
 */
 | 
						|
const NAME = (exports.NAME = "@@service/waitUntil");
 | 
						|
 | 
						|
function waitUntilService({ dispatch, getState }) {
 | 
						|
  let pending = [];
 | 
						|
 | 
						|
  function checkPending(action) {
 | 
						|
    const readyRequests = [];
 | 
						|
    const stillPending = [];
 | 
						|
 | 
						|
    // Find the pending requests whose predicates are satisfied with
 | 
						|
    // this action. Wait to run the requests until after we update the
 | 
						|
    // pending queue because the request handler may synchronously
 | 
						|
    // dispatch again and run this service (that use case is
 | 
						|
    // completely valid).
 | 
						|
    for (const request of pending) {
 | 
						|
      if (request.predicate(action)) {
 | 
						|
        readyRequests.push(request);
 | 
						|
      } else {
 | 
						|
        stillPending.push(request);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    pending = stillPending;
 | 
						|
    for (const request of readyRequests) {
 | 
						|
      request.run(dispatch, getState, action);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return next => action => {
 | 
						|
    if (action.type === NAME) {
 | 
						|
      pending.push(action);
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
    const result = next(action);
 | 
						|
    checkPending(action);
 | 
						|
    return result;
 | 
						|
  };
 | 
						|
}
 | 
						|
exports.waitUntilService = waitUntilService;
 |