code: function recomputeStates(
    computedStates,
    minInvalidatedStateIndex,
    reducer,
    committedState,
    actionsById,
    stagedActionIds,
    skippedActionIds,
    shouldCatchErrors
  ) {
    // Optimization: exit early and return the same reference
    // if we know nothing could have changed.
    if (
      !computedStates ||
      minInvalidatedStateIndex === -1 ||
      (minInvalidatedStateIndex >= computedStates.length &&
        computedStates.length === stagedActionIds.length)
    ) {
      return computedStates;
    }
  
    const nextComputedStates = computedStates.slice(0, minInvalidatedStateIndex);
    for (let i = minInvalidatedStateIndex; i < stagedActionIds.length; i++) {
      const actionId = stagedActionIds[i];
      const action = actionsById[actionId].action;
  
      const previousEntry = nextComputedStates[i - 1];
      const previousState = previousEntry ? previousEntry.state : committedState;
  
      const shouldSkip = skippedActionIds.indexOf(actionId) > -1;
      let entry;
      if (shouldSkip) {
        entry = previousEntry;
      } else {
        if (shouldCatchErrors && previousEntry && previousEntry.error) {
          entry = {
            state: previousState,
            error: 'Interrupted by an error up the chain'
          };
        } else {
          entry = computeNextEntry(
            reducer,
            action,
            previousState,
            shouldCatchErrors
          );
        }
      }
      nextComputedStates.push(entry);
    }
  
    return nextComputedStates;
  }
docs: Runs the reducer on invalidated actions to get a fresh computation log.