mirror of
https://github.com/ansible/awx.git
synced 2026-02-15 18:20:00 -03:30
moving render/record keeping and scroll functionality out of pagers
This commit is contained in:
@@ -17,12 +17,12 @@ let scroll;
|
|||||||
let status;
|
let status;
|
||||||
let slide;
|
let slide;
|
||||||
let stream;
|
let stream;
|
||||||
|
let page;
|
||||||
|
|
||||||
let vm;
|
let vm;
|
||||||
|
|
||||||
const listeners = [];
|
const listeners = [];
|
||||||
|
let lockFrames = false;
|
||||||
|
|
||||||
let lockFrames;
|
|
||||||
function onFrames (events) {
|
function onFrames (events) {
|
||||||
events = slide.pushFrames(events);
|
events = slide.pushFrames(events);
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ function onFrames (events) {
|
|||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const popCount = events.length - slide.getCapacity();
|
const popCount = events.length - render.getCapacity();
|
||||||
const isAttached = events.length > 0;
|
const isAttached = events.length > 0;
|
||||||
|
|
||||||
if (!isAttached) {
|
if (!isAttached) {
|
||||||
@@ -52,13 +52,13 @@ function onFrames (events) {
|
|||||||
scroll.scrollToBottom();
|
scroll.scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return slide.popBack(popCount)
|
return render.popBack(popCount)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (vm.isFollowing) {
|
if (vm.isFollowing) {
|
||||||
scroll.scrollToBottom();
|
scroll.scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return slide.pushFront(events);
|
return render.pushFrames(events);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (vm.isFollowing) {
|
if (vm.isFollowing) {
|
||||||
@@ -71,7 +71,11 @@ function onFrames (events) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function first () {
|
//
|
||||||
|
// Menu Controls (Running)
|
||||||
|
//
|
||||||
|
|
||||||
|
function firstRange () {
|
||||||
if (scroll.isPaused()) {
|
if (scroll.isPaused()) {
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
}
|
}
|
||||||
@@ -81,9 +85,15 @@ function first () {
|
|||||||
|
|
||||||
stopFollowing();
|
stopFollowing();
|
||||||
|
|
||||||
return slide.getFirst()
|
return render.clear()
|
||||||
.then(() => {
|
.then(() => slide.getFirst())
|
||||||
scroll.resetScrollPosition();
|
.then(results => render.pushFront(results))
|
||||||
|
.then(() => slide.getNext())
|
||||||
|
.then(results => {
|
||||||
|
const popCount = results.length - render.getCapacity();
|
||||||
|
|
||||||
|
return render.popBack(popCount)
|
||||||
|
.then(() => render.pushFront(results));
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
scroll.resume();
|
scroll.resume();
|
||||||
@@ -91,7 +101,7 @@ function first () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function next () {
|
function nextRange () {
|
||||||
if (vm.isFollowing) {
|
if (vm.isFollowing) {
|
||||||
scroll.scrollToBottom();
|
scroll.scrollToBottom();
|
||||||
|
|
||||||
@@ -110,26 +120,43 @@ function next () {
|
|||||||
lockFrames = true;
|
lockFrames = true;
|
||||||
|
|
||||||
return slide.getNext()
|
return slide.getNext()
|
||||||
|
.then(results => {
|
||||||
|
const popCount = results.length - render.getCapacity();
|
||||||
|
|
||||||
|
return render.popBack(popCount)
|
||||||
|
.then(() => render.pushFront(results));
|
||||||
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
scroll.resume();
|
scroll.resume();
|
||||||
lockFrames = false;
|
lockFrames = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function previous () {
|
function previousRange () {
|
||||||
if (scroll.isPaused()) {
|
if (scroll.isPaused()) {
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
scroll.pause();
|
scroll.pause();
|
||||||
lockFrames = true;
|
lockFrames = true;
|
||||||
|
|
||||||
stopFollowing();
|
stopFollowing();
|
||||||
|
|
||||||
const initialPosition = scroll.getScrollPosition();
|
let initialPosition;
|
||||||
|
let popHeight;
|
||||||
|
|
||||||
return slide.getPrevious()
|
return slide.getPrevious()
|
||||||
.then(popHeight => {
|
.then(results => {
|
||||||
|
const popCount = results.length - render.getCapacity();
|
||||||
|
initialPosition = scroll.getScrollPosition();
|
||||||
|
|
||||||
|
return render.popFront(popCount)
|
||||||
|
.then(() => {
|
||||||
|
popHeight = scroll.getScrollHeight();
|
||||||
|
|
||||||
|
return render.pushBack(results);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
const currentHeight = scroll.getScrollHeight();
|
const currentHeight = scroll.getScrollHeight();
|
||||||
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
||||||
|
|
||||||
@@ -138,10 +165,12 @@ function previous () {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
scroll.resume();
|
scroll.resume();
|
||||||
lockFrames = false;
|
lockFrames = false;
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function last () {
|
function lastRange () {
|
||||||
if (scroll.isPaused()) {
|
if (scroll.isPaused()) {
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
}
|
}
|
||||||
@@ -149,9 +178,10 @@ function last () {
|
|||||||
scroll.pause();
|
scroll.pause();
|
||||||
lockFrames = true;
|
lockFrames = true;
|
||||||
|
|
||||||
return slide.getLast()
|
return render.clear()
|
||||||
|
.then(() => slide.getLast())
|
||||||
|
.then(results => render.pushFront(results))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
stream.setMissingCounterThreshold(slide.getTailCounter() + 1);
|
|
||||||
scroll.scrollToBottom();
|
scroll.scrollToBottom();
|
||||||
|
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
@@ -159,9 +189,30 @@ function last () {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
scroll.resume();
|
scroll.resume();
|
||||||
lockFrames = false;
|
lockFrames = false;
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function menuLastRange () {
|
||||||
|
if (vm.isFollowing) {
|
||||||
|
lockFollow = true;
|
||||||
|
stopFollowing();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
lockFollow = false;
|
||||||
|
|
||||||
|
if (slide.isOnLastPage()) {
|
||||||
|
scroll.scrollToBottom();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return last();
|
||||||
|
}
|
||||||
|
|
||||||
let followOnce;
|
let followOnce;
|
||||||
let lockFollow;
|
let lockFollow;
|
||||||
function canStartFollowing () {
|
function canStartFollowing () {
|
||||||
@@ -207,23 +258,159 @@ function stopFollowing () {
|
|||||||
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Menu Controls (Page Mode)
|
||||||
|
//
|
||||||
|
|
||||||
|
function firstPage () {
|
||||||
|
if (scroll.isPaused()) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll.pause();
|
||||||
|
|
||||||
|
return render.clear()
|
||||||
|
.then(() => page.getFirst())
|
||||||
|
.then(results => render.pushFront(results))
|
||||||
|
.then(() => page.getNext())
|
||||||
|
.then(results => {
|
||||||
|
const popCount = page.trimHead();
|
||||||
|
|
||||||
|
return render.popBack(popCount)
|
||||||
|
.then(() => render.pushFront(results));
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
scroll.resume();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function lastPage () {
|
||||||
|
if (scroll.isPaused()) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll.pause();
|
||||||
|
|
||||||
|
return render.clear()
|
||||||
|
.then(() => page.getLast())
|
||||||
|
.then(results => render.pushBack(results))
|
||||||
|
.then(() => page.getPrevious())
|
||||||
|
.then(results => {
|
||||||
|
const popCount = page.trimTail();
|
||||||
|
|
||||||
|
return render.popFront(popCount)
|
||||||
|
.then(() => render.pushBack(results));
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
scroll.scrollToBottom();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
scroll.resume();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextPage () {
|
||||||
|
if (scroll.isPaused()) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll.pause();
|
||||||
|
|
||||||
|
return page.getNext()
|
||||||
|
.then(results => {
|
||||||
|
const popCount = page.trimHead();
|
||||||
|
|
||||||
|
return render.popBack(popCount)
|
||||||
|
.then(() => render.pushFront(results));
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
scroll.resume();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function previousPage () {
|
||||||
|
if (scroll.isPaused()) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll.pause();
|
||||||
|
|
||||||
|
let initialPosition;
|
||||||
|
let popHeight;
|
||||||
|
|
||||||
|
return page.getPrevious()
|
||||||
|
.then(results => {
|
||||||
|
const popCount = page.trimTail();
|
||||||
|
initialPosition = scroll.getScrollPosition();
|
||||||
|
|
||||||
|
return render.popFront(popCount)
|
||||||
|
.then(() => {
|
||||||
|
popHeight = scroll.getScrollHeight();
|
||||||
|
|
||||||
|
return render.pushBack(results);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
const currentHeight = scroll.getScrollHeight();
|
||||||
|
scroll.setScrollPosition(currentHeight - popHeight + initialPosition);
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
scroll.resume();
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Menu Controls
|
||||||
|
//
|
||||||
|
|
||||||
|
function first () {
|
||||||
|
if (vm.isProcessingFinished) {
|
||||||
|
return firstPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
function last () {
|
||||||
|
if (vm.isProcessingFinished) {
|
||||||
|
return lastPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
function next () {
|
||||||
|
if (vm.isProcessingFinished) {
|
||||||
|
return nextPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
function previous () {
|
||||||
|
if (vm.isProcessingFinished) {
|
||||||
|
return previousPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return previousRange();
|
||||||
|
}
|
||||||
|
|
||||||
function menuLast () {
|
function menuLast () {
|
||||||
if (vm.isFollowing) {
|
if (vm.isProcessingFinished) {
|
||||||
lockFollow = true;
|
return lastPage();
|
||||||
stopFollowing();
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lockFollow = false;
|
return menuLastRange();
|
||||||
|
|
||||||
if (slide.isOnLastPage()) {
|
|
||||||
scroll.scrollToBottom();
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return last();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function down () {
|
function down () {
|
||||||
@@ -238,6 +425,10 @@ function togglePanelExpand () {
|
|||||||
vm.isPanelExpanded = !vm.isPanelExpanded;
|
vm.isPanelExpanded = !vm.isPanelExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Line Interaction
|
||||||
|
//
|
||||||
|
|
||||||
const iconCollapsed = 'fa-angle-right';
|
const iconCollapsed = 'fa-angle-right';
|
||||||
const iconExpanded = 'fa-angle-down';
|
const iconExpanded = 'fa-angle-down';
|
||||||
const iconSelector = '.at-Stdout-toggle > i';
|
const iconSelector = '.at-Stdout-toggle > i';
|
||||||
@@ -246,7 +437,7 @@ const lineCollapsed = 'hidden';
|
|||||||
function toggleCollapseAll () {
|
function toggleCollapseAll () {
|
||||||
if (scroll.isPaused()) return;
|
if (scroll.isPaused()) return;
|
||||||
|
|
||||||
const records = Object.keys(render.record).map(key => render.record[key]);
|
const records = Object.keys(render.records).map(key => render.records[key]);
|
||||||
const plays = records.filter(({ name }) => name === EVENT_START_PLAY);
|
const plays = records.filter(({ name }) => name === EVENT_START_PLAY);
|
||||||
const tasks = records.filter(({ name }) => name === EVENT_START_TASK);
|
const tasks = records.filter(({ name }) => name === EVENT_START_TASK);
|
||||||
|
|
||||||
@@ -286,7 +477,7 @@ function toggleCollapseAll () {
|
|||||||
function toggleCollapse (uuid) {
|
function toggleCollapse (uuid) {
|
||||||
if (scroll.isPaused()) return;
|
if (scroll.isPaused()) return;
|
||||||
|
|
||||||
const record = render.record[uuid];
|
const record = render.records[uuid];
|
||||||
|
|
||||||
if (record.name === EVENT_START_PLAY) {
|
if (record.name === EVENT_START_PLAY) {
|
||||||
togglePlayCollapse(uuid);
|
togglePlayCollapse(uuid);
|
||||||
@@ -298,7 +489,7 @@ function toggleCollapse (uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function togglePlayCollapse (uuid) {
|
function togglePlayCollapse (uuid) {
|
||||||
const record = render.record[uuid];
|
const record = render.records[uuid];
|
||||||
const descendants = record.children || [];
|
const descendants = record.children || [];
|
||||||
|
|
||||||
const icon = $(`#${uuid} ${iconSelector}`);
|
const icon = $(`#${uuid} ${iconSelector}`);
|
||||||
@@ -329,11 +520,11 @@ function togglePlayCollapse (uuid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
descendants
|
descendants
|
||||||
.map(item => render.record[item])
|
.map(item => render.records[item])
|
||||||
.filter(({ name }) => name === EVENT_START_TASK)
|
.filter(({ name }) => name === EVENT_START_TASK)
|
||||||
.forEach(rec => { render.record[rec.uuid].isCollapsed = true; });
|
.forEach(rec => { render.records[rec.uuid].isCollapsed = true; });
|
||||||
|
|
||||||
render.record[uuid].isCollapsed = !isCollapsed;
|
render.records[uuid].isCollapsed = !isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTaskCollapse (uuid) {
|
function toggleTaskCollapse (uuid) {
|
||||||
@@ -352,7 +543,7 @@ function toggleTaskCollapse (uuid) {
|
|||||||
lines.addClass(lineCollapsed);
|
lines.addClass(lineCollapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
render.record[uuid].isCollapsed = !isCollapsed;
|
render.records[uuid].isCollapsed = !isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile (html) {
|
function compile (html) {
|
||||||
@@ -363,6 +554,14 @@ function showHostDetails (id, uuid) {
|
|||||||
$state.go('output.host-event.json', { eventId: id, taskUuid: uuid });
|
$state.go('output.host-event.json', { eventId: id, taskUuid: uuid });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showMissingEvents (uuid) {
|
||||||
|
console.log(`expandMissingEvents: ${uuid}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Handling
|
||||||
|
//
|
||||||
|
|
||||||
let streaming;
|
let streaming;
|
||||||
function stopListening () {
|
function stopListening () {
|
||||||
streaming = null;
|
streaming = null;
|
||||||
@@ -433,12 +632,20 @@ function handleSummaryEvent (data) {
|
|||||||
stream.setFinalCounter(data.final_counter);
|
stream.setFinalCounter(data.final_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Search
|
||||||
|
//
|
||||||
|
|
||||||
function reloadState (params) {
|
function reloadState (params) {
|
||||||
params.isPanelExpanded = vm.isPanelExpanded;
|
params.isPanelExpanded = vm.isPanelExpanded;
|
||||||
|
|
||||||
return $state.transitionTo($state.current, params, { inherit: false, location: 'replace' });
|
return $state.transitionTo($state.current, params, { inherit: false, location: 'replace' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debug Mode
|
||||||
|
//
|
||||||
|
|
||||||
function clear () {
|
function clear () {
|
||||||
stopListening();
|
stopListening();
|
||||||
render.clear();
|
render.clear();
|
||||||
@@ -449,7 +656,7 @@ function clear () {
|
|||||||
|
|
||||||
stream.bufferInit();
|
stream.bufferInit();
|
||||||
status.init(resource);
|
status.init(resource);
|
||||||
slide.init(render, resource.events, scroll);
|
slide.init(resource.events, render);
|
||||||
status.subscribe(data => { vm.status = data.status; });
|
status.subscribe(data => { vm.status = data.status; });
|
||||||
|
|
||||||
startListening();
|
startListening();
|
||||||
@@ -484,7 +691,8 @@ function OutputIndexController (
|
|||||||
render = _render_;
|
render = _render_;
|
||||||
status = _status_;
|
status = _status_;
|
||||||
stream = _stream_;
|
stream = _stream_;
|
||||||
slide = isProcessingFinished ? _page_ : _slide_;
|
slide = _slide_;
|
||||||
|
page = _page_;
|
||||||
|
|
||||||
vm = this || {};
|
vm = this || {};
|
||||||
|
|
||||||
@@ -495,6 +703,7 @@ function OutputIndexController (
|
|||||||
vm.resource = resource;
|
vm.resource = resource;
|
||||||
vm.reloadState = reloadState;
|
vm.reloadState = reloadState;
|
||||||
vm.isPanelExpanded = isPanelExpanded;
|
vm.isPanelExpanded = isPanelExpanded;
|
||||||
|
vm.isProcessingFinished = isProcessingFinished;
|
||||||
vm.togglePanelExpand = togglePanelExpand;
|
vm.togglePanelExpand = togglePanelExpand;
|
||||||
|
|
||||||
// Stdout Navigation
|
// Stdout Navigation
|
||||||
@@ -504,15 +713,18 @@ function OutputIndexController (
|
|||||||
vm.toggleCollapseAll = toggleCollapseAll;
|
vm.toggleCollapseAll = toggleCollapseAll;
|
||||||
vm.toggleCollapse = toggleCollapse;
|
vm.toggleCollapse = toggleCollapse;
|
||||||
vm.showHostDetails = showHostDetails;
|
vm.showHostDetails = showHostDetails;
|
||||||
|
vm.showMissingEvents = showMissingEvents;
|
||||||
vm.toggleLineEnabled = resource.model.get('type') === 'job';
|
vm.toggleLineEnabled = resource.model.get('type') === 'job';
|
||||||
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
vm.followTooltip = vm.strings.get('tooltips.MENU_LAST');
|
||||||
vm.debug = _debug;
|
vm.debug = _debug;
|
||||||
|
|
||||||
render.requestAnimationFrame(() => {
|
render.requestAnimationFrame(() => {
|
||||||
status.init(resource);
|
|
||||||
slide.init(render, resource.events, scroll);
|
|
||||||
render.init({ compile, toggles: vm.toggleLineEnabled });
|
render.init({ compile, toggles: vm.toggleLineEnabled });
|
||||||
|
|
||||||
|
status.init(resource);
|
||||||
|
page.init(resource.events);
|
||||||
|
slide.init(resource.events, render);
|
||||||
|
|
||||||
scroll.init({
|
scroll.init({
|
||||||
next,
|
next,
|
||||||
previous,
|
previous,
|
||||||
@@ -600,4 +812,3 @@ OutputIndexController.$inject = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
module.exports = OutputIndexController;
|
module.exports = OutputIndexController;
|
||||||
|
|
||||||
|
|||||||
@@ -2,244 +2,153 @@
|
|||||||
import { OUTPUT_PAGE_LIMIT } from './constants';
|
import { OUTPUT_PAGE_LIMIT } from './constants';
|
||||||
|
|
||||||
function PageService ($q) {
|
function PageService ($q) {
|
||||||
this.init = (storage, api, { getScrollHeight }) => {
|
this.init = ({ getPage, getFirst, getLast, getLastPageNumber }) => {
|
||||||
const { prepend, append, shift, pop, deleteRecord } = storage;
|
|
||||||
const { getPage, getFirst, getLast, getLastPageNumber, getMaxCounter } = api;
|
|
||||||
|
|
||||||
this.api = {
|
this.api = {
|
||||||
getPage,
|
getPage,
|
||||||
getFirst,
|
getFirst,
|
||||||
getLast,
|
getLast,
|
||||||
getLastPageNumber,
|
getLastPageNumber,
|
||||||
getMaxCounter,
|
|
||||||
};
|
};
|
||||||
|
this.pages = {};
|
||||||
this.storage = {
|
this.state = { head: 0, tail: 0 };
|
||||||
prepend,
|
|
||||||
append,
|
|
||||||
shift,
|
|
||||||
pop,
|
|
||||||
deleteRecord,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.hooks = {
|
|
||||||
getScrollHeight,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.records = {};
|
|
||||||
this.uuids = {};
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
head: 0,
|
|
||||||
tail: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.chain = $q.resolve();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pushFront = (results, key) => {
|
|
||||||
if (!results) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.storage.append(results)
|
|
||||||
.then(() => {
|
|
||||||
const tail = key || ++this.state.tail;
|
|
||||||
|
|
||||||
this.records[tail] = {};
|
|
||||||
results.forEach(({ counter, start_line, end_line, uuid }) => {
|
|
||||||
this.records[tail][counter] = { start_line, end_line };
|
|
||||||
this.uuids[counter] = uuid;
|
|
||||||
});
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pushBack = (results, key) => {
|
|
||||||
if (!results) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.storage.prepend(results)
|
|
||||||
.then(() => {
|
|
||||||
const head = key || --this.state.head;
|
|
||||||
|
|
||||||
this.records[head] = {};
|
|
||||||
results.forEach(({ counter, start_line, end_line, uuid }) => {
|
|
||||||
this.records[head][counter] = { start_line, end_line };
|
|
||||||
this.uuids[counter] = uuid;
|
|
||||||
});
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.popBack = () => {
|
|
||||||
if (this.getRecordCount() === 0) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageRecord = this.records[this.state.head] || {};
|
|
||||||
|
|
||||||
let lines = 0;
|
|
||||||
const counters = [];
|
|
||||||
|
|
||||||
Object.keys(pageRecord)
|
|
||||||
.forEach(counter => {
|
|
||||||
lines += pageRecord[counter].end_line - pageRecord[counter].start_line;
|
|
||||||
counters.push(counter);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.storage.shift(lines)
|
|
||||||
.then(() => {
|
|
||||||
counters.forEach(counter => {
|
|
||||||
this.storage.deleteRecord(this.uuids[counter]);
|
|
||||||
delete this.uuids[counter];
|
|
||||||
});
|
|
||||||
|
|
||||||
delete this.records[this.state.head++];
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.popFront = () => {
|
|
||||||
if (this.getRecordCount() === 0) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pageRecord = this.records[this.state.tail] || {};
|
|
||||||
|
|
||||||
let lines = 0;
|
|
||||||
const counters = [];
|
|
||||||
|
|
||||||
Object.keys(pageRecord)
|
|
||||||
.forEach(counter => {
|
|
||||||
lines += pageRecord[counter].end_line - pageRecord[counter].start_line;
|
|
||||||
counters.push(counter);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.storage.pop(lines)
|
|
||||||
.then(() => {
|
|
||||||
counters.forEach(counter => {
|
|
||||||
this.storage.deleteRecord(this.uuids[counter]);
|
|
||||||
delete this.uuids[counter];
|
|
||||||
});
|
|
||||||
|
|
||||||
delete this.records[this.state.tail--];
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getNext = () => {
|
this.getNext = () => {
|
||||||
const lastPageNumber = this.api.getLastPageNumber();
|
const lastPageNumber = this.api.getLastPageNumber();
|
||||||
const number = Math.min(this.state.tail + 1, lastPageNumber);
|
const number = Math.min(this.state.tail + 1, lastPageNumber);
|
||||||
|
|
||||||
const isLoaded = (number >= this.state.head && number <= this.state.tail);
|
if (number < 1) {
|
||||||
const isValid = (number >= 1 && number <= lastPageNumber);
|
return $q.resolve([]);
|
||||||
|
|
||||||
let popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
if (!isValid || isLoaded) {
|
|
||||||
this.chain = this.chain
|
|
||||||
.then(() => $q.resolve(popHeight));
|
|
||||||
|
|
||||||
return this.chain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageCount = this.state.head - this.state.tail;
|
if (number > lastPageNumber) {
|
||||||
|
return $q.resolve([]);
|
||||||
if (pageCount >= OUTPUT_PAGE_LIMIT) {
|
|
||||||
this.chain = this.chain
|
|
||||||
.then(() => this.popBack())
|
|
||||||
.then(() => {
|
|
||||||
popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chain = this.chain
|
let promise;
|
||||||
.then(() => this.api.getPage(number))
|
|
||||||
.then(events => this.pushFront(events))
|
|
||||||
.then(() => $q.resolve(popHeight));
|
|
||||||
|
|
||||||
return this.chain;
|
if (this.pages[number]) {
|
||||||
|
promise = $q.resolve(this.pages[number]);
|
||||||
|
} else {
|
||||||
|
promise = this.api.getPage(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise
|
||||||
|
.then(results => {
|
||||||
|
if (results.length <= 0) {
|
||||||
|
return $q.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.tail = number;
|
||||||
|
this.pages[number] = results;
|
||||||
|
|
||||||
|
return $q.resolve(results);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getPrevious = () => {
|
this.getPrevious = () => {
|
||||||
const number = Math.max(this.state.head - 1, 1);
|
const number = Math.max(this.state.head - 1, 1);
|
||||||
|
|
||||||
const isLoaded = (number >= this.state.head && number <= this.state.tail);
|
if (number < 1) {
|
||||||
const isValid = (number >= 1 && number <= this.api.getLastPageNumber());
|
return $q.resolve([]);
|
||||||
|
|
||||||
let popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
if (!isValid || isLoaded) {
|
|
||||||
this.chain = this.chain
|
|
||||||
.then(() => $q.resolve(popHeight));
|
|
||||||
|
|
||||||
return this.chain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pageCount = this.state.head - this.state.tail;
|
if (number > this.api.getLastPageNumber()) {
|
||||||
|
return $q.resolve([]);
|
||||||
if (pageCount >= OUTPUT_PAGE_LIMIT) {
|
|
||||||
this.chain = this.chain
|
|
||||||
.then(() => this.popFront())
|
|
||||||
.then(() => {
|
|
||||||
popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chain = this.chain
|
let promise;
|
||||||
.then(() => this.api.getPage(number))
|
|
||||||
.then(events => this.pushBack(events))
|
|
||||||
.then(() => $q.resolve(popHeight));
|
|
||||||
|
|
||||||
return this.chain;
|
if (this.pages[number]) {
|
||||||
|
promise = $q.resolve(this.pages[number]);
|
||||||
|
} else {
|
||||||
|
promise = this.api.getPage(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise
|
||||||
|
.then(results => {
|
||||||
|
if (results.length <= 0) {
|
||||||
|
return $q.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.head = number;
|
||||||
|
this.pages[number] = results;
|
||||||
|
|
||||||
|
return $q.resolve(results);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clear = () => {
|
this.getLast = () => this.api.getLast()
|
||||||
const count = this.getRecordCount();
|
.then(results => {
|
||||||
|
if (results.length <= 0) {
|
||||||
|
return $q.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i <= count; ++i) {
|
const number = this.api.getLastPageNumber();
|
||||||
this.chain = this.chain.then(() => this.popBack());
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.chain;
|
this.state.head = number;
|
||||||
};
|
this.state.tail = number;
|
||||||
|
this.pages[number] = results;
|
||||||
|
|
||||||
this.getLast = () => this.clear()
|
return $q.resolve(results);
|
||||||
.then(() => this.api.getLast())
|
});
|
||||||
.then(events => {
|
|
||||||
const lastPage = this.api.getLastPageNumber();
|
|
||||||
|
|
||||||
this.state.head = lastPage;
|
this.getFirst = () => this.api.getFirst()
|
||||||
this.state.tail = lastPage;
|
.then(results => {
|
||||||
|
if (results.length <= 0) {
|
||||||
|
return $q.resolve([]);
|
||||||
|
}
|
||||||
|
|
||||||
return this.pushBack(events, lastPage);
|
|
||||||
})
|
|
||||||
.then(() => this.getPrevious());
|
|
||||||
|
|
||||||
this.getFirst = () => this.clear()
|
|
||||||
.then(() => this.api.getFirst())
|
|
||||||
.then(events => {
|
|
||||||
this.state.head = 1;
|
this.state.head = 1;
|
||||||
this.state.tail = 1;
|
this.state.tail = 1;
|
||||||
|
this.pages[1] = results;
|
||||||
|
|
||||||
return this.pushBack(events, 1);
|
return $q.resolve(results);
|
||||||
})
|
});
|
||||||
.then(() => this.getNext());
|
|
||||||
|
|
||||||
this.isOnLastPage = () => this.api.getLastPageNumber() === this.state.tail;
|
this.trimTail = () => {
|
||||||
this.getRecordCount = () => Object.keys(this.records).length;
|
const { tail, head } = this.state;
|
||||||
this.getTailCounter = () => this.state.tail;
|
let popCount = 0;
|
||||||
this.getMaxCounter = () => this.api.getMaxCounter();
|
|
||||||
|
for (let i = tail; i > head; i--) {
|
||||||
|
if (!this.isOverCapacity()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.pages[i]) {
|
||||||
|
popCount += this.pages[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.pages[i];
|
||||||
|
|
||||||
|
this.state.tail--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return popCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.trimHead = () => {
|
||||||
|
const { head, tail } = this.state;
|
||||||
|
let popCount = 0;
|
||||||
|
|
||||||
|
for (let i = head; i < tail; i++) {
|
||||||
|
if (!this.isOverCapacity()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.pages[i]) {
|
||||||
|
popCount += this.pages[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.pages[i];
|
||||||
|
|
||||||
|
this.state.head++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return popCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isOverCapacity = () => this.state.tail - this.state.head > OUTPUT_PAGE_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageService.$inject = ['$q'];
|
PageService.$inject = ['$q'];
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/* eslint camelcase: 0 */
|
/* eslint camelcase: 0 */
|
||||||
import {
|
import {
|
||||||
API_MAX_PAGE_SIZE,
|
|
||||||
OUTPUT_EVENT_LIMIT,
|
OUTPUT_EVENT_LIMIT,
|
||||||
OUTPUT_PAGE_SIZE,
|
OUTPUT_PAGE_SIZE,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
@@ -34,9 +33,8 @@ function getContinuous (events, reverse = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function SlidingWindowService ($q) {
|
function SlidingWindowService ($q) {
|
||||||
this.init = (storage, api, { getScrollHeight }) => {
|
this.init = ({ getRange, getFirst, getLast, getMaxCounter }, storage) => {
|
||||||
const { prepend, append, shift, pop, getRecord, deleteRecord, clear } = storage;
|
const { getHeadCounter, getTailCounter } = storage;
|
||||||
const { getRange, getFirst, getLast, getMaxCounter } = api;
|
|
||||||
|
|
||||||
this.api = {
|
this.api = {
|
||||||
getRange,
|
getRange,
|
||||||
@@ -46,36 +44,24 @@ function SlidingWindowService ($q) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.storage = {
|
this.storage = {
|
||||||
clear,
|
getHeadCounter,
|
||||||
prepend,
|
getTailCounter,
|
||||||
append,
|
|
||||||
shift,
|
|
||||||
pop,
|
|
||||||
getRecord,
|
|
||||||
deleteRecord,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.hooks = {
|
|
||||||
getScrollHeight,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.lines = {};
|
|
||||||
this.uuids = {};
|
|
||||||
this.chain = $q.resolve();
|
|
||||||
|
|
||||||
this.state = { head: null, tail: null };
|
|
||||||
this.cache = { first: null };
|
|
||||||
|
|
||||||
this.buffer = {
|
this.buffer = {
|
||||||
events: [],
|
events: [],
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 0,
|
max: 0,
|
||||||
count: 0,
|
count: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.cache = {
|
||||||
|
first: null
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getBoundedRange = range => {
|
this.getBoundedRange = range => {
|
||||||
const bounds = [0, this.getMaxCounter()];
|
const bounds = [1, this.getMaxCounter()];
|
||||||
|
|
||||||
return [Math.max(range[0], bounds[0]), Math.min(range[1], bounds[1])];
|
return [Math.max(range[0], bounds[0]), Math.min(range[1], bounds[1])];
|
||||||
};
|
};
|
||||||
@@ -92,273 +78,48 @@ function SlidingWindowService ($q) {
|
|||||||
return this.getBoundedRange([head - 1 - displacement, head - 1]);
|
return this.getBoundedRange([head - 1 - displacement, head - 1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.createRecord = ({ counter, uuid, start_line, end_line }) => {
|
|
||||||
this.lines[counter] = end_line - start_line;
|
|
||||||
this.uuids[counter] = uuid;
|
|
||||||
|
|
||||||
if (this.state.tail === null) {
|
|
||||||
this.state.tail = counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter > this.state.tail) {
|
|
||||||
this.state.tail = counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.head === null) {
|
|
||||||
this.state.head = counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (counter < this.state.head) {
|
|
||||||
this.state.head = counter;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteRecord = counter => {
|
|
||||||
this.storage.deleteRecord(this.uuids[counter]);
|
|
||||||
|
|
||||||
delete this.uuids[counter];
|
|
||||||
delete this.lines[counter];
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getLineCount = counter => {
|
|
||||||
const record = this.storage.getRecord(counter);
|
|
||||||
|
|
||||||
if (record && record.lineCount) {
|
|
||||||
return record.lineCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.lines[counter]) {
|
|
||||||
return this.lines[counter];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pushFront = events => {
|
|
||||||
const tail = this.getTailCounter();
|
|
||||||
const newEvents = events.filter(({ counter }) => counter > tail);
|
|
||||||
|
|
||||||
return this.storage.append(newEvents)
|
|
||||||
.then(() => {
|
|
||||||
newEvents.forEach(event => this.createRecord(event));
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pushBack = events => {
|
|
||||||
const [head, tail] = this.getRange();
|
|
||||||
const newEvents = events
|
|
||||||
.filter(({ counter }) => counter < head || counter > tail);
|
|
||||||
|
|
||||||
return this.storage.prepend(newEvents)
|
|
||||||
.then(() => {
|
|
||||||
newEvents.forEach(event => this.createRecord(event));
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.popFront = count => {
|
|
||||||
if (!count || count <= 0) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const max = this.getTailCounter();
|
|
||||||
const min = max - count;
|
|
||||||
|
|
||||||
let lines = 0;
|
|
||||||
|
|
||||||
for (let i = max; i >= min; --i) {
|
|
||||||
lines += this.getLineCount(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.storage.pop(lines)
|
|
||||||
.then(() => {
|
|
||||||
for (let i = max; i >= min; --i) {
|
|
||||||
this.deleteRecord(i);
|
|
||||||
this.state.tail--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.popBack = count => {
|
|
||||||
if (!count || count <= 0) {
|
|
||||||
return $q.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const min = this.getHeadCounter();
|
|
||||||
const max = min + count;
|
|
||||||
|
|
||||||
let lines = 0;
|
|
||||||
|
|
||||||
for (let i = min; i <= max; ++i) {
|
|
||||||
lines += this.getLineCount(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.storage.shift(lines)
|
|
||||||
.then(() => {
|
|
||||||
for (let i = min; i <= max; ++i) {
|
|
||||||
this.deleteRecord(i);
|
|
||||||
this.state.head++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clear = () => this.storage.clear()
|
|
||||||
.then(() => {
|
|
||||||
const [head, tail] = this.getRange();
|
|
||||||
|
|
||||||
for (let i = head; i <= tail; ++i) {
|
|
||||||
this.deleteRecord(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state.head = null;
|
|
||||||
this.state.tail = null;
|
|
||||||
|
|
||||||
return $q.resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getNext = (displacement = OUTPUT_PAGE_SIZE) => {
|
this.getNext = (displacement = OUTPUT_PAGE_SIZE) => {
|
||||||
const next = this.getNextRange(displacement);
|
const next = this.getNextRange(displacement);
|
||||||
const [head, tail] = this.getRange();
|
|
||||||
|
|
||||||
this.chain = this.chain
|
return this.api.getRange(next)
|
||||||
.then(() => this.api.getRange(next))
|
.then(results => getContinuous(results));
|
||||||
.then(events => {
|
|
||||||
const results = getContinuous(events);
|
|
||||||
const min = Math.min(...results.map(({ counter }) => counter));
|
|
||||||
|
|
||||||
if (min > tail + 1) {
|
|
||||||
return $q.resolve([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $q.resolve(results);
|
|
||||||
})
|
|
||||||
.then(results => {
|
|
||||||
const count = (tail - head + results.length);
|
|
||||||
const excess = count - OUTPUT_EVENT_LIMIT;
|
|
||||||
|
|
||||||
return this.popBack(excess)
|
|
||||||
.then(() => {
|
|
||||||
const popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
return this.pushFront(results).then(() => $q.resolve(popHeight));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.chain;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getPrevious = (displacement = OUTPUT_PAGE_SIZE) => {
|
this.getPrevious = (displacement = OUTPUT_PAGE_SIZE) => {
|
||||||
const previous = this.getPreviousRange(displacement);
|
const previous = this.getPreviousRange(displacement);
|
||||||
const [head, tail] = this.getRange();
|
|
||||||
|
|
||||||
this.chain = this.chain
|
return this.api.getRange(previous)
|
||||||
.then(() => this.api.getRange(previous))
|
.then(results => getContinuous(results, true));
|
||||||
.then(events => {
|
|
||||||
const results = getContinuous(events, true);
|
|
||||||
const max = Math.max(...results.map(({ counter }) => counter));
|
|
||||||
|
|
||||||
if (head > max + 1) {
|
|
||||||
return $q.resolve([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $q.resolve(results);
|
|
||||||
})
|
|
||||||
.then(results => {
|
|
||||||
const count = (tail - head + results.length);
|
|
||||||
const excess = count - OUTPUT_EVENT_LIMIT;
|
|
||||||
|
|
||||||
return this.popFront(excess)
|
|
||||||
.then(() => {
|
|
||||||
const popHeight = this.hooks.getScrollHeight();
|
|
||||||
|
|
||||||
return this.pushBack(results).then(() => $q.resolve(popHeight));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.chain;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getFirst = () => {
|
this.getFirst = () => {
|
||||||
this.chain = this.chain
|
if (this.cache.first) {
|
||||||
.then(() => this.clear())
|
return $q.resolve(this.cache.first);
|
||||||
.then(() => {
|
}
|
||||||
if (this.cache.first) {
|
|
||||||
return $q.resolve(this.cache.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.api.getFirst();
|
return this.api.getFirst()
|
||||||
})
|
|
||||||
.then(events => {
|
.then(events => {
|
||||||
if (events.length === OUTPUT_PAGE_SIZE) {
|
if (events.length === OUTPUT_PAGE_SIZE) {
|
||||||
this.cache.first = events;
|
this.cache.first = events;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.pushFront(events);
|
return $q.resolve(events);
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.chain
|
|
||||||
.then(() => this.getNext());
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getLast = () => {
|
this.getLast = () => this.getFrames()
|
||||||
this.chain = this.chain
|
.then(frames => {
|
||||||
.then(() => this.getFrames())
|
if (frames.length > 0) {
|
||||||
.then(frames => {
|
return $q.resolve(frames);
|
||||||
if (frames.length > 0) {
|
}
|
||||||
return $q.resolve(frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.api.getLast();
|
return this.api.getLast();
|
||||||
})
|
});
|
||||||
.then(events => {
|
|
||||||
const min = Math.min(...events.map(({ counter }) => counter));
|
|
||||||
|
|
||||||
if (min <= this.getTailCounter() + 1) {
|
|
||||||
return this.pushFront(events);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.clear()
|
|
||||||
.then(() => this.pushBack(events));
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.chain
|
|
||||||
.then(() => this.getPrevious());
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getTailCounter = () => {
|
|
||||||
if (this.state.tail === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.tail < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.state.tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getHeadCounter = () => {
|
|
||||||
if (this.state.head === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.state.head < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.state.head;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pushFrames = events => {
|
this.pushFrames = events => {
|
||||||
|
const head = this.getHeadCounter();
|
||||||
|
const tail = this.getTailCounter();
|
||||||
const frames = this.buffer.events.concat(events);
|
const frames = this.buffer.events.concat(events);
|
||||||
const [head, tail] = this.getRange();
|
|
||||||
|
|
||||||
let min;
|
let min;
|
||||||
let max;
|
let max;
|
||||||
@@ -367,7 +128,7 @@ function SlidingWindowService ($q) {
|
|||||||
for (let i = frames.length - 1; i >= 0; i--) {
|
for (let i = frames.length - 1; i >= 0; i--) {
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (count > API_MAX_PAGE_SIZE) {
|
if (count > OUTPUT_EVENT_LIMIT) {
|
||||||
frames.splice(i, 1);
|
frames.splice(i, 1);
|
||||||
|
|
||||||
count--;
|
count--;
|
||||||
@@ -417,9 +178,9 @@ function SlidingWindowService ($q) {
|
|||||||
return this.getTailCounter() >= (this.getMaxCounter() - OUTPUT_PAGE_SIZE);
|
return this.getTailCounter() >= (this.getMaxCounter() - OUTPUT_PAGE_SIZE);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getRange = () => [this.getHeadCounter(), this.getTailCounter()];
|
this.isOnFirstPage = () => this.getHeadCounter() === 1;
|
||||||
this.getRecordCount = () => Object.keys(this.lines).length;
|
this.getTailCounter = () => this.storage.getTailCounter();
|
||||||
this.getCapacity = () => OUTPUT_EVENT_LIMIT - this.getRecordCount();
|
this.getHeadCounter = () => this.storage.getHeadCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
SlidingWindowService.$inject = ['$q'];
|
SlidingWindowService.$inject = ['$q'];
|
||||||
|
|||||||
Reference in New Issue
Block a user