private scheduleHistoryBatch(): void {
if (
this.subscriptions.closed ||
this.historyBatchRunning ||
this.activeSymbolIds.length === 0 ||
this.currentInterval === Intervals.All
) {
return;
}
this.historyBatchRunning = true;
requestAnimationFrame(() => {
if (this.subscriptions.closed || this.currentInterval === Intervals.All) {
this.historyBatchRunning = false;
return;
}
const symbolIds = this.activeSymbolIds.slice();
const timeframe = this.eventManager.getTimeframe();
const oldestTimes = symbolIds.map((symbolId) => this.dataSource.getOldestTime(symbolId));
Promise.all(symbolIds.map((symbolId) => this.dataSource.loadMoreHistory(symbolId))).finally(() => {
this.finishHistoryBatch(symbolIds, oldestTimes, timeframe);
});
});
}
private finishHistoryBatch(
symbolIds: string[],
oldestTimes: (number | null)[],
timeframe: ReturnType<EventManager['getTimeframe']>,
): void {
this.historyBatchRunning = false;
if (this.subscriptions.closed || this.currentInterval === Intervals.All) {
return;
}
const contextChanged =
timeframe !== this.eventManager.getTimeframe() || !sameSymbolIds(symbolIds, this.activeSymbolIds);
const hasProgress = this.hasHistoryProgress(symbolIds, oldestTimes);
if (!contextChanged && !hasProgress) {
return;
}
const range = this.lwcChart.timeScale().getVisibleLogicalRange();
if (range && range.from < HISTORY_LOAD_THRESHOLD) {
this.scheduleHistoryBatch();
}
}
private hasHistoryProgress(symbolIds: string[], oldestTimes: (number | null)[]): boolean {
return symbolIds.some((symbolId, index) => {
if (!this.activeSymbolIds.includes(symbolId)) {
return false;
}
const previousOldestTime = oldestTimes[index];
const currentOldestTime = this.dataSource.getOldestTime(symbolId);
return currentOldestTime !== null && (previousOldestTime === null || currentOldestTime < previousOldestTime);
});
}