Guppy implements a task queue for any actions that require exclusive access to the project's package.json and/or node_modules folder.
This currently includes dependency installation & uninstallation.
The queue has the following structure:
{
  [projectId: string]: Array<{
    action: 'install' : 'uninstall' : 'modify',
    active: true | false,
    ...extras,
  }>
}The extras keys are any key-value pairs specific to the action (think of them like key-value pairs added to Redux actions).
Each queueable action should have, at minimum, 4 action creators:
QUEUEABLE_ACTION_ADD
QUEUEABLE_ACTION_QUEUE
QUEUEABLE_ACTION_START
QUEUEABLE_ACTION_FINISH
- QUEUEABLE_ACTION_ADDshould fire when the user indicates the action should take place
- QUEUEABLE_ACTION_QUEUEshould add the action to the queue
- QUEUEABLE_ACTION_STARTshould handle starting the action once it gains priority on the queue
- QUEUEABLE_ACTION_FINISHshould handle any cleanup or results of the action, and start the next queued action
QUEUEABLE_ACTION_ADD should be handled in a saga, and should follow this pattern:
export function* handleQueueableActionAdd({ projectId }) {
  // check if the project has an active queue
  const queuedAction = yield select(getNextActionForProjectId, projectId);
  // fire the `QUEUEABLE_ACTION_QUEUE` action to add the action to the queue
  yield put(queueableActionQueue(projectId));
  // if the queue was previously empty, start the first action in the queue
  // (the one we just queued)
  if (!queuedAction) {
    yield put(startNextActionInQueue(projectId));
  }
}The first item in a queue will always be the action that is being currently processed, with the active key set to true.
As soon as the action is completed, it is removed from the queue and the next action in the queue becomes the first and has it's active key set to true.
This repeats until the queue is finished.