relay-link-batch
Version:
Relay Link that performs batching and operation on batched Operations
145 lines (139 loc) • 6.36 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var tslib = require('tslib');
var relayLink = require('relay-link');
var relayRuntime = require('relay-runtime');
var OperationBatcher = (function () {
function OperationBatcher(_a) {
var batchInterval = _a.batchInterval, batchMax = _a.batchMax, batchHandler = _a.batchHandler, batchKey = _a.batchKey;
this.queuedRequests = new Map();
this.batchInterval = batchInterval;
this.batchMax = batchMax || 0;
this.batchHandler = batchHandler;
this.batchKey = batchKey || (function () { return ''; });
}
OperationBatcher.prototype.enqueueRequest = function (request) {
var _this = this;
var requestCopy = tslib.__assign({}, request);
var queued = false;
var key = this.batchKey(request.operation);
if (!requestCopy.observable) {
requestCopy.observable = relayRuntime.Observable.create(function (sink) {
var _a, _b, _c;
if (!_this.queuedRequests.has(key)) {
_this.queuedRequests.set(key, []);
}
if (!queued) {
(_a = _this.queuedRequests.get(key)) === null || _a === void 0 ? void 0 : _a.push(requestCopy);
queued = true;
}
requestCopy.next = requestCopy.next || [];
if (sink.next)
requestCopy.next.push(sink.next.bind(sink));
requestCopy.error = requestCopy.error || [];
if (sink.error)
requestCopy.error.push(sink.error.bind(sink));
requestCopy.complete = requestCopy.complete || [];
if (sink.complete)
requestCopy.complete.push(sink.complete.bind(sink));
if (((_b = _this.queuedRequests.get(key)) === null || _b === void 0 ? void 0 : _b.length) === 1) {
setTimeout(function () { return _this.scheduleQueueConsumption(key); });
}
if (((_c = _this.queuedRequests.get(key)) === null || _c === void 0 ? void 0 : _c.length) === _this.batchMax) {
_this.consumeQueue(key);
}
});
}
return requestCopy.observable;
};
OperationBatcher.prototype.consumeQueue = function (key) {
var requestKey = key || '';
var queuedRequests = this.queuedRequests.get(requestKey);
if (!(queuedRequests === null || queuedRequests === void 0 ? void 0 : queuedRequests.length))
return;
this.queuedRequests.delete(requestKey);
var requests = queuedRequests.map(function (queuedRequest) { return queuedRequest.operation; });
var forwards = queuedRequests.map(function (queuedRequest) { return queuedRequest.forward; });
var batchedObservable = this.batchHandler(requests, forwards);
var observables = [];
var nexts = [];
var errors = [];
var completes = [];
queuedRequests.forEach(function (batchableRequest) {
observables.push(batchableRequest.observable);
nexts.push(batchableRequest.next);
errors.push(batchableRequest.error);
completes.push(batchableRequest.complete);
});
var onError = function (error) {
errors.forEach(function (rejecters) {
if (rejecters) {
rejecters.forEach(function (e) { return e(error); });
}
});
};
batchedObservable.subscribe({
next: function (results) {
if (!Array.isArray(results)) {
results = [results];
}
if (nexts.length !== results.length) {
var error = new Error("server returned results with length " + results.length + ", expected length of " + nexts.length);
error.result = results;
return onError(error);
}
results.forEach(function (result, index) {
var _a;
if (nexts[index]) {
(_a = nexts[index]) === null || _a === void 0 ? void 0 : _a.forEach(function (next) { return next(result); });
}
});
},
error: onError,
complete: function () {
completes.forEach(function (complete) {
if (complete) {
complete.forEach(function (c) { return c(); });
}
});
},
});
return observables;
};
OperationBatcher.prototype.scheduleQueueConsumption = function (key) {
var _this = this;
var requestKey = key || '';
setTimeout(function () {
var _a;
if ((_a = _this.queuedRequests.get(requestKey)) === null || _a === void 0 ? void 0 : _a.length) {
_this.consumeQueue(requestKey);
}
}, this.batchInterval);
};
return OperationBatcher;
}());
var BatchLink = (function (_super) {
tslib.__extends(BatchLink, _super);
function BatchLink(options) {
var _a;
var _this = _super.call(this) || this;
var _b = options.batchInterval, batchInterval = _b === void 0 ? 10 : _b, _c = options.batchMax, batchMax = _c === void 0 ? 0 : _c, batchHandler = options.batchHandler, _d = options.batchKey, batchKey = _d === void 0 ? function () { return ''; } : _d;
_this.batcher = new OperationBatcher({
batchInterval: batchInterval,
batchMax: batchMax,
batchHandler: batchHandler,
batchKey: batchKey,
});
if (((_a = options.batchHandler) === null || _a === void 0 ? void 0 : _a.length) <= 1) {
_this.request = function (operation) { return _this.batcher.enqueueRequest({ operation: operation }); };
}
return _this;
}
BatchLink.prototype.request = function (operation, forward) {
return this.batcher.enqueueRequest({ operation: operation, forward: forward });
};
return BatchLink;
}(relayLink.RelayLink));
exports.BatchLink = BatchLink;
exports.OperationBatcher = OperationBatcher;
//# sourceMappingURL=bundle.cjs.js.map