Skip to content

Commit

Permalink
Add createBatch() JSDoc
Browse files Browse the repository at this point in the history
  • Loading branch information
noisysocks committed Jan 20, 2021
1 parent 4bf98b9 commit 5a9c126
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
66 changes: 63 additions & 3 deletions packages/core-data/src/batch/create-batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,39 @@ import { isFunction, zip } from 'lodash';
*/
import defaultProcessor from './default-processor';

/**
* Creates a batch, which can be used to combine multiple API requests into one
* API request using the WordPress batch processing API (/v1/batch).
*
* ```
* const batch = createBatch();
* const dunePromise = batch.add( {
* path: '/v1/books',
* method: 'POST',
* data: { title: 'Dune' }
* } );
* const lotrPromise = batch.add( {
* path: '/v1/books',
* method: 'POST',
* data: { title: 'Lord of the Rings' }
* } );
* const isSuccess = await batch.run(); // Sends one POST to /v1/batch.
* if ( isSuccess ) {
* console.log(
* 'Saved two books:',
* await dunePromise,
* await lotrPromise
* );
* }
* ```
*
* @param {Function} [processor] Processor function. Can be used to replace the
* default functionality which is to send an API
* request to /v1/batch. Is given an aray of
* inputs and must return a promise that
* resolves to an array of objects containing
* either `output` or `error`.
*/
export default function createBatch( processor = defaultProcessor ) {
const queue = [];

Expand All @@ -16,10 +49,30 @@ export default function createBatch( processor = defaultProcessor ) {
onFull = () => {};

return {
/**
* Adds an input to the batch and returns a promise that is resolved or
* rejected when the input is processed by `batch.run()`.
*
* You may also pass a thunk which allows inputs to be added
* asychronously.
*
* ```
* // Both are allowed:
* batch.add( { path: '/v1/books', ... } );
* batch.add( ( add ) => add( { path: '/v1/books', ... } ) );
* ```
*
* @param {any|Function} inputOrThunk Input to add or thunk to execute.
* @return {Promise|any} If given an input, returns a promise that
* is resolved or rejected when the batch is
* processed. If given a thunk, returns the return
* value of that thunk.
*/
add( inputOrThunk ) {
++expectedSize;

const doAdd = ( input ) =>
const add = ( input ) =>
new Promise( ( resolve, reject ) => {
queue.push( {
input,
Expand All @@ -33,12 +86,19 @@ export default function createBatch( processor = defaultProcessor ) {
} );

if ( isFunction( inputOrThunk ) ) {
return inputOrThunk( doAdd );
return inputOrThunk( add );
}

return doAdd( inputOrThunk );
return add( inputOrThunk );
},

/**
* Runs the batch. This calls `batchProcessor` and resolves or rejects
* all promises returned by `add()`.
*
* @return {Promise} A promise that resolves to a boolean which is true
* if all resolutions were succesful.
*/
async run() {
if ( actualSize !== expectedSize ) {
await new Promise( ( resolve ) => {
Expand Down
9 changes: 9 additions & 0 deletions packages/core-data/src/batch/default-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
*/
import apiFetch from '@wordpress/api-fetch';

/**
* Default batch processor. Sends its input requests to /v1/batch.
*
* @param {Array} requests List of API requests to perform at once.
*
* @return {Promise} Promise that resolves to a list of objects containing
* either `output` (if that request was succesful) or `error`
* (if not ).
*/
export default async function defaultProcessor( requests ) {
const batchResponse = await apiFetch( {
path: '/v1/batch',
Expand Down

0 comments on commit 5a9c126

Please sign in to comment.