UNPKG

@wordpress/core-data

Version:
161 lines (159 loc) 5.29 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/core-data/src/batch/create-batch.js var create_batch_exports = {}; __export(create_batch_exports, { default: () => createBatch }); module.exports = __toCommonJS(create_batch_exports); var import_default_processor = __toESM(require("./default-processor")); function createBatch(processor = import_default_processor.default) { let lastId = 0; let queue = []; const pending = new ObservableSet(); 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 * asynchronously. * * ``` * // Both are allowed: * batch.add( { path: '/v1/books', ... } ); * batch.add( ( add ) => add( { path: '/v1/books', ... } ) ); * ``` * * If a thunk is passed, `batch.run()` will pause until either: * * - The thunk calls its `add` argument, or; * - The thunk returns a promise and that promise resolves, or; * - The thunk returns a non-promise. * * @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) { const id = ++lastId; pending.add(id); const add = (input) => new Promise((resolve, reject) => { queue.push({ input, resolve, reject }); pending.delete(id); }); if (typeof inputOrThunk === "function") { return Promise.resolve(inputOrThunk(add)).finally(() => { pending.delete(id); }); } return add(inputOrThunk); }, /** * Runs the batch. This calls `batchProcessor` and resolves or rejects * all promises returned by `add()`. * * @return {Promise<boolean>} A promise that resolves to a boolean that is true * if the processor returned no errors. */ async run() { if (pending.size) { await new Promise((resolve) => { const unsubscribe = pending.subscribe(() => { if (!pending.size) { unsubscribe(); resolve(void 0); } }); }); } let results; try { results = await processor( queue.map(({ input }) => input) ); if (results.length !== queue.length) { throw new Error( "run: Array returned by processor must be same size as input array." ); } } catch (error) { for (const { reject } of queue) { reject(error); } throw error; } let isSuccess = true; results.forEach((result, key) => { const queueItem = queue[key]; if (result?.error) { queueItem?.reject(result.error); isSuccess = false; } else { queueItem?.resolve(result?.output ?? result); } }); queue = []; return isSuccess; } }; } var ObservableSet = class { constructor(...args) { this.set = new Set(...args); this.subscribers = /* @__PURE__ */ new Set(); } get size() { return this.set.size; } add(value) { this.set.add(value); this.subscribers.forEach((subscriber) => subscriber()); return this; } delete(value) { const isSuccess = this.set.delete(value); this.subscribers.forEach((subscriber) => subscriber()); return isSuccess; } subscribe(subscriber) { this.subscribers.add(subscriber); return () => { this.subscribers.delete(subscriber); }; } }; //# sourceMappingURL=create-batch.js.map