@sendbird/uikit-utils
Version:
A collection of utility functions and constants for building chat UI components with Sendbird UIKit.
110 lines (109 loc) • 3.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BufferedRequest = void 0;
var _BufferedRequest;
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
let REQ_PER_TIMEOUT = 5;
let TIMEOUT_MILLS = 1000;
const SAFE_TIMEOUT_BUFFER = 100;
function generateRandomId() {
return Math.random().toString(16).slice(2);
}
class BufferedRequest {
static updateMarkAsReadOptions(reqPerTimeout, timeoutMills) {
BufferedRequest.markAsRead = BufferedRequest.create(reqPerTimeout, timeoutMills);
}
static updateMarkAsDeliveredOptions(reqPerTimeout, timeoutMills) {
BufferedRequest.markAsDelivered = BufferedRequest.create(reqPerTimeout, timeoutMills);
}
static get reqPerTimeout() {
return REQ_PER_TIMEOUT;
}
static set reqPerTimeout(value) {
REQ_PER_TIMEOUT = value;
BufferedRequest.markAsRead = BufferedRequest.create();
BufferedRequest.markAsDelivered = BufferedRequest.create();
}
static get timeoutMills() {
return TIMEOUT_MILLS;
}
static set timeoutMills(value) {
TIMEOUT_MILLS = value;
BufferedRequest.markAsRead = BufferedRequest.create();
BufferedRequest.markAsDelivered = BufferedRequest.create();
}
static create(reqPerTimeout = REQ_PER_TIMEOUT, timeoutMills = TIMEOUT_MILLS) {
const waitQueue = new Map();
const nextQueue = new Map();
let state = 'idle';
let timeout;
return {
push(func, lane) {
waitQueue.set(lane ?? generateRandomId(), func);
this.invoke();
},
shift() {
if (nextQueue.size < reqPerTimeout) {
const nextRemains = Math.min(reqPerTimeout - nextQueue.size, waitQueue.size);
const lanes = [...waitQueue.keys()];
for (let n = 0; n < nextRemains; n++) {
const lane = lanes[n];
const func = waitQueue.get(lane);
if (func) {
waitQueue.delete(lane);
nextQueue.set(lane, func);
}
}
}
},
handleIdle() {
if (0 < nextQueue.size) {
state = 'processing';
this.invoke();
}
},
handleProcessing() {
if (timeout) return;
timeout = setTimeout(() => {
timeout = undefined;
if (0 < nextQueue.size || 0 < waitQueue.size) {
this.invoke();
} else {
state = 'idle';
}
}, timeoutMills + SAFE_TIMEOUT_BUFFER);
let index = 0;
const nextRequestBaseTimeout = timeoutMills / nextQueue.size;
nextQueue.forEach(func => {
setTimeout(() => {
func().catch(_ => {
// do nothing
});
// TODO: Add retry
//.catch(() => waitQueue.set(lane, func));
}, nextRequestBaseTimeout * index);
index++;
});
nextQueue.clear();
},
invoke() {
this.shift();
if (state === 'idle') {
this.handleIdle();
}
if (state === 'processing') {
this.handleProcessing();
}
}
};
}
}
exports.BufferedRequest = BufferedRequest;
_BufferedRequest = BufferedRequest;
_defineProperty(BufferedRequest, "markAsRead", _BufferedRequest.create());
_defineProperty(BufferedRequest, "markAsDelivered", _BufferedRequest.create());
//# sourceMappingURL=bufferedRequest.js.map