UNPKG

batchloader

Version:

BatchLoader is a utility for data fetching layer to reduce requests via batching written in TypeScript. Inspired by Facebook's DataLoader

127 lines 5.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var cacheloader_1 = require("./cacheloader"); var mappedbatchloader_1 = require("./mappedbatchloader"); var sleep = function (ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); }; var BatchLoader = (function () { function BatchLoader(batchFn, keyToUniqueId, batchDelay, batchSize) { if (batchDelay === void 0) { batchDelay = 0; } if (batchSize === void 0) { batchSize = Number.MAX_SAFE_INTEGER; } this.batchFn = batchFn; this.keyToUniqueId = keyToUniqueId; this.batchDelay = batchDelay; this.batchSize = batchSize; this.queuedKeys = []; this.batchPromise = null; } BatchLoader.prototype.load = function (key) { var queuedKeys = this.queuedKeys; var index = queuedKeys.length; queuedKeys.push(key); return this.triggerBatch().then(function (values) { return values[index]; }); }; BatchLoader.prototype.loadMany = function (keys) { if (keys.length) { var queuedKeys = this.queuedKeys; var index_1 = queuedKeys.length; queuedKeys.push.apply(queuedKeys, keys); var length_1 = keys.length; return this.triggerBatch().then(function (values) { return values.slice(index_1, index_1 + length_1); }); } return Promise.resolve([]); }; BatchLoader.prototype.mapLoader = function (mapFn) { return new mappedbatchloader_1.MappedBatchLoader(this, mapFn); }; BatchLoader.prototype.cacheLoader = function (cache) { return new cacheloader_1.CacheLoader(this, cache); }; BatchLoader.prototype.triggerBatch = function () { var _this = this; return (this.batchPromise || (this.batchPromise = new Promise(function (resolve, reject) { setTimeout(function () { _this.batchPromise = null; _this.runBatchNow().then(resolve, reject); }, _this.batchDelay); }))); }; BatchLoader.prototype.runBatchNow = function () { var _a = this, queuedKeys = _a.queuedKeys, keyToUniqueId = _a.keyToUniqueId; this.queuedKeys = []; if (keyToUniqueId) { var idMap = {}; var indexToId_1 = []; var idToNewIndex_1 = {}; var newIndex = 0; var uniqueKeys = []; var len = queuedKeys.length; for (var i = 0; i < len; i += 1) { var key = queuedKeys[i]; var id = keyToUniqueId(key); indexToId_1[i] = id; if (idMap[id] !== true) { idMap[id] = true; idToNewIndex_1[id] = newIndex; newIndex += 1; uniqueKeys.push(key); } } return this.maybeBatchInChunks(uniqueKeys).then(function (values) { return queuedKeys.map(function (_key, i) { return values[idToNewIndex_1[indexToId_1[i]]]; }); }); } return this.maybeBatchInChunks(queuedKeys); }; BatchLoader.prototype.maybeBatchInChunks = function (keys) { if (keys.length <= this.batchSize) { return Promise.resolve(this.batchFn(keys)); } return this.batchInChunks(keys); }; BatchLoader.prototype.batchInChunks = function (keys) { return tslib_1.__awaiter(this, void 0, void 0, function () { var _a, batchSize, batchDelay, promises, kLen, i, results, rLen, values, i; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: _a = this, batchSize = _a.batchSize, batchDelay = _a.batchDelay; promises = []; kLen = keys.length; i = 0; _b.label = 1; case 1: if (!(i < kLen)) return [3, 4]; promises.push(this.batchFn(keys.slice(i, i + batchSize))); if (!batchDelay) return [3, 3]; return [4, sleep(batchDelay)]; case 2: _b.sent(); _b.label = 3; case 3: i += batchSize; return [3, 1]; case 4: return [4, Promise.all(promises)]; case 5: results = _b.sent(); rLen = results.length; values = []; for (i = 0; i < rLen; i += 1) { values = values.concat(results[i]); } return [2, values]; } }); }); }; return BatchLoader; }()); exports.BatchLoader = BatchLoader; //# sourceMappingURL=batchloader.js.map