vscroll
Version:
Virtual scroll engine
87 lines • 3.92 kB
JavaScript
import { DatasourceGeneric, makeDatasource } from './classes/datasource';
import { Settings } from './classes/settings';
import { Logger } from './classes/logger';
import { Routines } from './classes/domRoutines';
import { Viewport } from './classes/viewport';
import { Buffer } from './classes/buffer';
import { State } from './classes/state';
import { Adapter } from './classes/adapter';
import { validate, DATASOURCE } from './inputs/index';
import core from './version';
export const INVALID_DATASOURCE_PREFIX = 'Invalid datasource:';
let instanceCount = 0;
export class Scroller {
constructor({ datasource, consumer, element, workflow, Routines: CustomRoutines, scroller }) {
const { params: { get } } = validate(datasource, DATASOURCE);
if (!get.isValid) {
throw new Error(`${INVALID_DATASOURCE_PREFIX} ${get.errors[0]}`);
}
const packageInfo = scroller ? scroller.state.packageInfo : { consumer, core };
element = scroller ? scroller.routines.element : element;
workflow = scroller ? scroller.workflow : workflow;
// In general, custom Routines must extend the original Routines. If not, we provide implicit extending.
// This is undocumented feature. It should be removed in vscroll v2.
if (CustomRoutines && !(CustomRoutines.prototype instanceof Routines)) {
class __Routines extends Routines {
}
Object.getOwnPropertyNames(CustomRoutines.prototype)
.filter(method => method !== 'constructor')
.forEach(method => __Routines.prototype[method] = CustomRoutines === null || CustomRoutines === void 0 ? void 0 : CustomRoutines.prototype[method]);
CustomRoutines = __Routines;
}
this.workflow = workflow;
this.settings = new Settings(datasource.settings, datasource.devSettings, ++instanceCount);
this.logger = new Logger(this, packageInfo, datasource.adapter);
this.routines = new (CustomRoutines || Routines)(element, this.settings);
this.state = new State(packageInfo, this.settings, scroller ? scroller.state : void 0);
this.buffer = new Buffer(this.settings, workflow.onDataChanged, this.logger);
this.viewport = new Viewport(this.settings, this.routines, this.state, this.logger);
this.logger.object('vscroll settings object', this.settings, true);
this.initDatasource(datasource, scroller);
}
initDatasource(datasource, scroller) {
if (scroller) { // scroller re-instantiating case
this.datasource = datasource;
this.adapter = scroller.adapter;
// todo: what about (this.settings.adapter !== scroller.setting.adapter) case?
return;
}
// scroller is being instantiated for the first time
const constructed = datasource instanceof DatasourceGeneric;
const mockAdapter = !constructed && !this.settings.adapter;
if (constructed) { // datasource is already instantiated
this.datasource = datasource;
}
else { // datasource as POJO
const DS = makeDatasource(() => ({ mock: mockAdapter }));
this.datasource = new DS(datasource);
if (this.settings.adapter) {
datasource.adapter = this.datasource.adapter;
}
}
const publicContext = !mockAdapter ? this.datasource.adapter : null;
this.adapter = new Adapter(publicContext, () => this.workflow, this.logger);
}
init(adapterRun$) {
this.viewport.reset(this.buffer.startIndex);
this.logger.stat('initialization');
this.adapter.initialize({
buffer: this.buffer,
state: this.state,
viewport: this.viewport,
logger: this.logger, adapterRun$,
getWorkflow: () => this.workflow
});
}
dispose(forever) {
this.logger.log(() => 'disposing scroller' + (forever ? ' (forever)' : ''));
if (forever) { // Adapter is not re-instantiated on reset
this.adapter.dispose();
}
this.buffer.dispose();
this.state.dispose();
}
finalize() {
}
}
//# sourceMappingURL=scroller.js.map