vscroll 1.4.0-beta.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/vscroll.esm5.js +383 -392
- package/dist/bundles/vscroll.esm5.js.map +1 -1
- package/dist/bundles/vscroll.esm5.min.js +2 -2
- package/dist/bundles/vscroll.esm5.min.js.map +1 -1
- package/dist/bundles/vscroll.esm6.js +337 -342
- package/dist/bundles/vscroll.esm6.js.map +1 -1
- package/dist/bundles/vscroll.esm6.min.js +2 -2
- package/dist/bundles/vscroll.esm6.min.js.map +1 -1
- package/dist/bundles/vscroll.umd.js +386 -395
- package/dist/bundles/vscroll.umd.js.map +1 -1
- package/dist/bundles/vscroll.umd.min.js +2 -2
- package/dist/bundles/vscroll.umd.min.js.map +1 -1
- package/dist/esm2015/classes/buffer/checkCall.js.map +1 -1
- package/dist/esm2015/classes/buffer.js +0 -16
- package/dist/esm2015/classes/buffer.js.map +1 -1
- package/dist/esm2015/classes/domRoutines.js +56 -0
- package/dist/esm2015/classes/domRoutines.js.map +1 -1
- package/dist/esm2015/classes/item.js +4 -0
- package/dist/esm2015/classes/item.js.map +1 -1
- package/dist/esm2015/classes/paddings.js +3 -1
- package/dist/esm2015/classes/paddings.js.map +1 -1
- package/dist/esm2015/classes/state/cycle.js +7 -6
- package/dist/esm2015/classes/state/cycle.js.map +1 -1
- package/dist/esm2015/classes/state/fetch.js +0 -12
- package/dist/esm2015/classes/state/fetch.js.map +1 -1
- package/dist/esm2015/classes/state/render.js +1 -1
- package/dist/esm2015/classes/state/render.js.map +1 -1
- package/dist/esm2015/classes/state/scroll.js +6 -6
- package/dist/esm2015/classes/state/scroll.js.map +1 -1
- package/dist/esm2015/classes/state.js +23 -15
- package/dist/esm2015/classes/state.js.map +1 -1
- package/dist/esm2015/classes/viewport.js +12 -29
- package/dist/esm2015/classes/viewport.js.map +1 -1
- package/dist/esm2015/interfaces/index.js.map +1 -1
- package/dist/esm2015/interfaces/state.js.map +1 -1
- package/dist/esm2015/processes/adapter/append.js +15 -74
- package/dist/esm2015/processes/adapter/append.js.map +1 -1
- package/dist/esm2015/processes/adapter/reload.js +1 -1
- package/dist/esm2015/processes/adapter/reload.js.map +1 -1
- package/dist/esm2015/processes/adjust.js +44 -15
- package/dist/esm2015/processes/adjust.js.map +1 -1
- package/dist/esm2015/processes/end.js +18 -16
- package/dist/esm2015/processes/end.js.map +1 -1
- package/dist/esm2015/processes/fetch.js +3 -3
- package/dist/esm2015/processes/fetch.js.map +1 -1
- package/dist/esm2015/processes/init.js +2 -2
- package/dist/esm2015/processes/init.js.map +1 -1
- package/dist/esm2015/processes/render.js +8 -11
- package/dist/esm2015/processes/render.js.map +1 -1
- package/dist/esm2015/processes/scroll.js +21 -21
- package/dist/esm2015/processes/scroll.js.map +1 -1
- package/dist/esm2015/version.js +1 -1
- package/dist/esm2015/version.js.map +1 -1
- package/dist/esm2015/workflow.js +5 -6
- package/dist/esm2015/workflow.js.map +1 -1
- package/dist/esm5/classes/buffer/checkCall.js.map +1 -1
- package/dist/esm5/classes/buffer/defaultSize.js +1 -1
- package/dist/esm5/classes/buffer/defaultSize.js.map +1 -1
- package/dist/esm5/classes/buffer.js +7 -23
- package/dist/esm5/classes/buffer.js.map +1 -1
- package/dist/esm5/classes/domRoutines.js +56 -0
- package/dist/esm5/classes/domRoutines.js.map +1 -1
- package/dist/esm5/classes/item.js +4 -0
- package/dist/esm5/classes/item.js.map +1 -1
- package/dist/esm5/classes/logger.js +5 -5
- package/dist/esm5/classes/logger.js.map +1 -1
- package/dist/esm5/classes/paddings.js +3 -1
- package/dist/esm5/classes/paddings.js.map +1 -1
- package/dist/esm5/classes/state/cycle.js +7 -6
- package/dist/esm5/classes/state/cycle.js.map +1 -1
- package/dist/esm5/classes/state/fetch.js +0 -12
- package/dist/esm5/classes/state/fetch.js.map +1 -1
- package/dist/esm5/classes/state/render.js +1 -1
- package/dist/esm5/classes/state/render.js.map +1 -1
- package/dist/esm5/classes/state/scroll.js +11 -11
- package/dist/esm5/classes/state/scroll.js.map +1 -1
- package/dist/esm5/classes/state.js +23 -15
- package/dist/esm5/classes/state.js.map +1 -1
- package/dist/esm5/classes/viewport.js +13 -31
- package/dist/esm5/classes/viewport.js.map +1 -1
- package/dist/esm5/inputs/validation.js +2 -2
- package/dist/esm5/inputs/validation.js.map +1 -1
- package/dist/esm5/interfaces/index.js.map +1 -1
- package/dist/esm5/interfaces/state.js.map +1 -1
- package/dist/esm5/processes/adapter/append.js +15 -75
- package/dist/esm5/processes/adapter/append.js.map +1 -1
- package/dist/esm5/processes/adapter/fix.js +1 -1
- package/dist/esm5/processes/adapter/fix.js.map +1 -1
- package/dist/esm5/processes/adapter/insert.js +1 -1
- package/dist/esm5/processes/adapter/insert.js.map +1 -1
- package/dist/esm5/processes/adapter/reload.js +1 -1
- package/dist/esm5/processes/adapter/reload.js.map +1 -1
- package/dist/esm5/processes/adapter/remove.js +1 -1
- package/dist/esm5/processes/adapter/remove.js.map +1 -1
- package/dist/esm5/processes/adjust.js +44 -15
- package/dist/esm5/processes/adjust.js.map +1 -1
- package/dist/esm5/processes/end.js +18 -16
- package/dist/esm5/processes/end.js.map +1 -1
- package/dist/esm5/processes/fetch.js +3 -3
- package/dist/esm5/processes/fetch.js.map +1 -1
- package/dist/esm5/processes/init.js +2 -2
- package/dist/esm5/processes/init.js.map +1 -1
- package/dist/esm5/processes/preFetch.js +1 -1
- package/dist/esm5/processes/preFetch.js.map +1 -1
- package/dist/esm5/processes/render.js +8 -11
- package/dist/esm5/processes/render.js.map +1 -1
- package/dist/esm5/processes/scroll.js +21 -21
- package/dist/esm5/processes/scroll.js.map +1 -1
- package/dist/esm5/version.js +1 -1
- package/dist/esm5/version.js.map +1 -1
- package/dist/esm5/workflow.js +10 -13
- package/dist/esm5/workflow.js.map +1 -1
- package/dist/typings/classes/buffer.d.ts +0 -2
- package/dist/typings/classes/domRoutines.d.ts +12 -0
- package/dist/typings/classes/item.d.ts +1 -0
- package/dist/typings/classes/state/cycle.d.ts +1 -1
- package/dist/typings/classes/state/fetch.d.ts +0 -2
- package/dist/typings/classes/state/render.d.ts +1 -1
- package/dist/typings/classes/state/scroll.d.ts +4 -4
- package/dist/typings/classes/state.d.ts +6 -3
- package/dist/typings/classes/viewport.d.ts +2 -2
- package/dist/typings/interfaces/index.d.ts +2 -2
- package/dist/typings/interfaces/state.d.ts +2 -15
- package/dist/typings/processes/adapter/append.d.ts +1 -4
- package/dist/typings/processes/adjust.d.ts +1 -0
- package/dist/typings/processes/end.d.ts +1 -2
- package/dist/typings/workflow.d.ts +1 -1
- package/package.json +17 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vscroll.esm5.js","sources":["../../src/classes/reactive.ts","../../src/classes/adapter/props.ts","../../src/version.ts","../../src/classes/adapter/context.ts","../../src/classes/datasource.ts","../../src/inputs/common.ts","../../src/inputs/validation.ts","../../src/inputs/datasource.ts","../../src/inputs/settings.ts","../../src/processes/misc/enums.ts","../../src/inputs/adapter.ts","../../src/classes/settings.ts","../../src/processes/misc/base.ts","../../src/processes/init.ts","../../src/processes/scroll.ts","../../src/processes/adapter/reset.ts","../../src/processes/adapter/reload.ts","../../src/classes/item.ts","../../src/processes/adapter/update.ts","../../src/processes/adapter/append.ts","../../src/processes/adapter/check.ts","../../src/processes/adapter/remove.ts","../../src/processes/adapter/clip.ts","../../src/processes/adapter/insert.ts","../../src/processes/adapter/replace.ts","../../src/processes/adapter/fix.ts","../../src/processes/start.ts","../../src/processes/preFetch.ts","../../src/processes/fetch.ts","../../src/processes/postFetch.ts","../../src/processes/render.ts","../../src/processes/adjust.ts","../../src/processes/preClip.ts","../../src/processes/clip.ts","../../src/processes/end.ts","../../src/classes/logger.ts","../../src/classes/domRoutines.ts","../../src/classes/paddings.ts","../../src/classes/viewport.ts","../../src/classes/buffer/defaultSize.ts","../../src/classes/buffer/cache.ts","../../src/classes/buffer/checkCall.ts","../../src/classes/buffer.ts","../../src/classes/state/cycle.ts","../../src/classes/state/fetch.ts","../../src/classes/state/clip.ts","../../src/classes/state/render.ts","../../src/classes/state/scroll.ts","../../src/classes/state.ts","../../src/classes/adapter.ts","../../src/scroller.ts","../../src/workflow-transducer.ts","../../src/workflow.ts"],"sourcesContent":["type On<T> = (value: T) => void;\ntype Off = () => void;\n\ninterface Subscription<T> {\n emit: On<T>;\n off: Off;\n}\n\ninterface Options {\n emitOnSubscribe?: boolean; // if set, emit right on subscribe (like rxjs BehaviorSubject)\n emitEqual?: boolean; // if set, emit when new value is equal to the old one\n}\n\nexport class Reactive<T> {\n\n private initialValue: T;\n private value: T;\n private id: number;\n private options: Options;\n private subscriptions: Map<number, Subscription<T>>;\n\n constructor(value?: T, options?: Options) {\n this.id = 0;\n if (value !== void 0) {\n this.value = value;\n this.initialValue = value;\n }\n this.options = options || {};\n this.subscriptions = new Map();\n }\n\n set(value: T): void {\n if (this.value === value && !this.options.emitEqual) {\n return;\n }\n this.value = value;\n for (const [, sub] of this.subscriptions) {\n sub.emit(value);\n if (this.value !== value) {\n break;\n }\n }\n }\n\n get(): T {\n return this.value;\n }\n\n on(func: On<T>): Off {\n const id = this.id++;\n const subscription: Subscription<T> = {\n emit: func,\n off: () => {\n subscription.emit = () => null;\n this.subscriptions.delete(id);\n }\n };\n this.subscriptions.set(id, subscription);\n if (this.options.emitOnSubscribe) {\n subscription.emit(this.value);\n }\n return () => subscription.off();\n }\n\n once(func: On<T>): Off {\n const off = this.on(v => {\n off();\n func(v);\n });\n return off;\n }\n\n reset(): void {\n this.set(this.initialValue);\n }\n\n dispose(): void {\n this.subscriptions.forEach(sub => sub.off());\n }\n}\n","import { Reactive } from '../reactive';\nimport {\n IAdapterProp, IBufferInfo, ItemAdapter, IPackages, AdapterMethodResult, IReactivePropsStore\n} from '../../interfaces/index';\n\nexport enum AdapterPropName {\n id = 'id',\n mock = 'mock',\n augmented = 'augmented',\n version = 'version',\n init = 'init',\n init$ = 'init$',\n packageInfo = 'packageInfo',\n itemsCount = 'itemsCount',\n bufferInfo = 'bufferInfo',\n isLoading = 'isLoading',\n isLoading$ = 'isLoading$',\n loopPending = 'loopPending',\n loopPending$ = 'loopPending$',\n firstVisible = 'firstVisible',\n firstVisible$ = 'firstVisible$',\n lastVisible = 'lastVisible',\n lastVisible$ = 'lastVisible$',\n bof = 'bof',\n bof$ = 'bof$',\n eof = 'eof',\n eof$ = 'eof$',\n reset = 'reset',\n reload = 'reload',\n append = 'append',\n prepend = 'prepend',\n check = 'check',\n remove = 'remove',\n clip = 'clip',\n insert = 'insert',\n replace = 'replace',\n update = 'update',\n fix = 'fix',\n relax = 'relax',\n showLog = 'showLog',\n}\n\nexport enum AdapterPropType {\n Scalar,\n Reactive,\n WorkflowRunner,\n Function,\n}\n\nconst Name = AdapterPropName;\nconst Type = AdapterPropType;\n\nconst noop = () => null;\n\nexport const methodPreResult: AdapterMethodResult = {\n immediate: true,\n success: true,\n details: 'Adapter is not initialized'\n};\n\nconst noopWF = () => Promise.resolve(methodPreResult);\n\nconst emptyPackageInfo: IPackages = {\n core: {\n name: '',\n version: ''\n },\n consumer: {\n name: '',\n version: ''\n }\n};\n\nconst bufferInfoDefault: IBufferInfo = {\n firstIndex: NaN,\n lastIndex: NaN,\n minIndex: NaN,\n maxIndex: NaN,\n absMinIndex: -Infinity,\n absMaxIndex: +Infinity,\n defaultSize: NaN,\n};\n\nexport const EMPTY_ITEM = {\n data: {},\n element: {}\n} as ItemAdapter;\n\nexport const getDefaultAdapterProps = (): IAdapterProp[] => [\n {\n type: Type.Scalar,\n name: Name.id,\n value: 0,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.mock,\n value: true,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.augmented,\n value: false,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.version,\n value: '',\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.init,\n value: false,\n reactive: Name.init$\n },\n {\n type: Type.Scalar,\n name: Name.packageInfo,\n value: emptyPackageInfo,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.itemsCount,\n value: 0,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.bufferInfo,\n value: bufferInfoDefault,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.isLoading,\n value: false,\n reactive: Name.isLoading$\n },\n {\n type: Type.Scalar,\n name: Name.loopPending,\n value: false,\n reactive: Name.loopPending$\n },\n {\n type: Type.Scalar,\n name: Name.firstVisible,\n value: EMPTY_ITEM,\n reactive: Name.firstVisible$,\n wanted: true\n },\n {\n type: Type.Scalar,\n name: Name.lastVisible,\n value: EMPTY_ITEM,\n reactive: Name.lastVisible$,\n wanted: true\n },\n {\n type: Type.Scalar,\n name: Name.bof,\n value: false,\n reactive: Name.bof$\n },\n {\n type: Type.Scalar,\n name: Name.eof,\n value: false,\n reactive: Name.eof$\n },\n {\n type: Type.WorkflowRunner,\n name: Name.reset,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.reload,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.append,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.prepend,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.check,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.remove,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.clip,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.insert,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.replace,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.update,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.fix,\n value: noopWF\n },\n {\n type: Type.Function,\n name: Name.relax,\n value: noop\n },\n {\n type: Type.Function,\n name: Name.showLog,\n value: noop\n },\n {\n type: Type.Reactive,\n name: Name.init$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.isLoading$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.loopPending$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.firstVisible$,\n value: new Reactive<ItemAdapter>(EMPTY_ITEM, { emitOnSubscribe: true })\n },\n {\n type: Type.Reactive,\n name: Name.lastVisible$,\n value: new Reactive<ItemAdapter>(EMPTY_ITEM, { emitOnSubscribe: true })\n },\n {\n type: Type.Reactive,\n name: Name.bof$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.eof$,\n value: new Reactive<boolean>()\n }\n];\n\nexport const reactiveConfigStorage = new Map<number, IReactivePropsStore>();\n","export default {\n name: 'vscroll',\n version: '1.4.0-beta.2'\n};\n","import { AdapterPropName, AdapterPropType, getDefaultAdapterProps, reactiveConfigStorage } from './props';\nimport core from '../../version';\nimport { Reactive } from '../reactive';\nimport { IReactivePropsStore, IAdapterConfig } from '../../interfaces/index';\n\nlet instanceCount = 0;\n\nexport class AdapterContext {\n\n constructor(config: IAdapterConfig) {\n const { mock, reactive } = config;\n const id = ++instanceCount;\n const conf = { configurable: true };\n const reactivePropsStore: IReactivePropsStore = {};\n\n // set up permanent props\n Object.defineProperty(this, AdapterPropName.id, { get: () => id, ...conf });\n Object.defineProperty(this, AdapterPropName.mock, { get: () => mock, ...conf });\n Object.defineProperty(this, AdapterPropName.augmented, { get: () => false, ...conf });\n Object.defineProperty(this, AdapterPropName.version, { get: () => core.version, ...conf });\n\n // set up default props, they will be reassigned during the Adapter instantiation\n getDefaultAdapterProps()\n .filter(({ permanent }) => !permanent)\n .forEach(({ name, value, type }) => {\n\n // reactive props might be reconfigured by the vscroll consumer\n if (reactive && type === AdapterPropType.Reactive) {\n const react = reactive[name];\n if (react) {\n // here we have a configured reactive property that came from the outer config\n // this prop must be exposed via Adapter, but at the same time we need to\n // persist the original default value as it will be used by the Adapter internally\n reactivePropsStore[name] = {\n ...react,\n default: value as Reactive<unknown> // persisting the default native Reactive prop\n };\n value = react.source; // exposing the configured prop instead of the default one\n }\n }\n\n Object.defineProperty(this, name, {\n get: () => value,\n ...conf\n });\n });\n\n if (reactive) { // save both configured and default reactive props in the store\n reactiveConfigStorage.set(id, reactivePropsStore);\n }\n }\n}\n","import { AdapterContext } from './adapter/context';\r\nimport { reactiveConfigStorage } from './adapter/props';\r\nimport {\r\n IDatasource,\r\n IDatasourceConstructed,\r\n DatasourceGet,\r\n Settings,\r\n DevSettings,\r\n IAdapter,\r\n IAdapterConfig,\r\n} from '../interfaces/index';\r\n\r\nexport class DatasourceGeneric<Data> implements IDatasourceConstructed<Data> {\r\n get: DatasourceGet<Data>;\r\n settings?: Settings<Data>;\r\n devSettings?: DevSettings;\r\n adapter: IAdapter<Data>;\r\n\r\n constructor(datasource: IDatasource<Data>, config?: IAdapterConfig) {\r\n this.get = datasource.get;\r\n if (datasource.settings) {\r\n this.settings = datasource.settings;\r\n }\r\n if (datasource.devSettings) {\r\n this.devSettings = datasource.devSettings;\r\n }\r\n const adapterContext = new AdapterContext(config || { mock: false });\r\n this.adapter = adapterContext as IAdapter<Data>;\r\n }\r\n\r\n dispose(): void { // todo: should it be published?\r\n reactiveConfigStorage.delete(this.adapter.id);\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\r\nexport const makeDatasource = (getConfig?: () => IAdapterConfig) =>\r\n class <Data = unknown> extends DatasourceGeneric<Data> {\r\n constructor(datasource: IDatasource<Data>) {\r\n const config = typeof getConfig === 'function' ? getConfig() : void 0;\r\n super(datasource, config);\r\n }\r\n };\r\n\r\nexport const Datasource = makeDatasource();\r\n","export enum Direction {\n forward = 'forward',\n backward = 'backward'\n}\n\nexport enum SizeStrategy {\n Average = 'average',\n Constant = 'constant',\n Frequent = 'frequent'\n}\n","import { IValidationContext } from '../interfaces/validation';\nimport {\n IValidator,\n ValidatedValue,\n IValidatedData,\n IValidatedCommonProps,\n ICommonProps,\n ICommonProp,\n} from '../interfaces/index';\n\nexport enum ValidatorType {\n number = 'must be a number',\n integer = 'must be an integer',\n integerUnlimited = 'must be an integer or infinity',\n moreOrEqual = 'must be a number greater than (or equal to) {arg1}',\n itemList = 'must be an array of items {arg1}',\n boolean = 'must be a boolean',\n object = 'must be an object',\n element = 'must be an html element',\n function = 'must be a function',\n funcOfxArguments = 'must have {arg1} argument(s)',\n funcOfxAndMoreArguments = 'must have at least {arg1} argument(s)',\n funcOfXToYArguments = 'must have {arg1} to {arg2} arguments',\n oneOfCan = 'can be present as only one item of {arg1} list',\n oneOfMust = 'must be present as only one item of {arg1} list',\n or = 'must satisfy at least 1 validator from {arg1} list',\n enum = 'must belong to {arg1} list',\n}\n\nconst getError = (msg: ValidatorType, args?: string[]) =>\n (args || ['']).reduce((acc, arg, index) => acc.replace(`{arg${index + 1}}`, arg), msg);\n\nconst getNumber = (value: unknown): number =>\n typeof value === 'number' || (typeof value === 'string' && value !== '')\n ? Number(value)\n : NaN;\n\nconst onNumber = (value: unknown): ValidatedValue => {\n const parsedValue = getNumber(value);\n const errors = [];\n if (Number.isNaN(parsedValue)) {\n errors.push(ValidatorType.number);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onInteger = (value: unknown): ValidatedValue => {\n const errors = [];\n value = getNumber(value);\n const parsedValue = parseInt(String(value), 10);\n if (value !== parsedValue) {\n errors.push(ValidatorType.integer);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onIntegerUnlimited = (value: unknown): ValidatedValue => {\n let parsedValue = value;\n const errors = [];\n value = getNumber(value);\n if (!Number.isFinite(value)) {\n parsedValue = value;\n } else {\n parsedValue = parseInt(String(value), 10);\n }\n if (value !== parsedValue) {\n errors.push(ValidatorType.integerUnlimited);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onMoreOrEqual = (limit: number, fallback?: boolean) => (value: unknown): ValidatedValue => {\n const result = onNumber(value);\n if (!result.isValid) {\n return result;\n }\n let parsedValue = result.value as number;\n const errors = [];\n if (parsedValue < limit) {\n if (!fallback) {\n errors.push(getError(ValidatorType.moreOrEqual, [String(limit)]));\n } else {\n parsedValue = limit;\n }\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onBoolean = (value: unknown): ValidatedValue => {\n const errors = [];\n let parsedValue = value;\n if (value === 'true') {\n parsedValue = true;\n } else if (value === 'false') {\n parsedValue = false;\n }\n if (typeof parsedValue !== 'boolean') {\n errors.push(ValidatorType.boolean);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onObject = (value: unknown): ValidatedValue => {\n const errors = [];\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n errors.push(ValidatorType.object);\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onHtmlElement = (value: unknown): ValidatedValue => {\n const errors = [];\n if (!(value instanceof Element) && !(value instanceof HTMLDocument)) {\n errors.push(ValidatorType.element);\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onItemList = (value: unknown): ValidatedValue => {\n let parsedValue = value;\n const errors = [];\n if (!Array.isArray(value)) {\n errors.push(ValidatorType.itemList);\n parsedValue = [];\n } else if (!value.length) {\n errors.push(getError(ValidatorType.itemList, ['with at least 1 item']));\n } else if (value.length > 1) {\n const type = typeof value[0];\n for (let i = value.length - 1; i >= 0; i--) {\n if (typeof value[i] !== type) {\n errors.push(getError(ValidatorType.itemList, ['of items of the same type']));\n break;\n }\n }\n }\n return { value: parsedValue as unknown[], isSet: true, isValid: !errors.length, errors };\n};\n\ntype Func = (...args: any[]) => void;\n\nconst onFunction = (value: unknown): ValidatedValue => {\n const errors = [];\n if (typeof value !== 'function') {\n errors.push(ValidatorType.function);\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXArguments = (argsCount: number) => (value: unknown) => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length !== argsCount) {\n errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXAndMoreArguments = (argsCount: number) => (value: unknown): ValidatedValue => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length < argsCount) {\n errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXToYArguments = (from: number, to: number) => (value: unknown): ValidatedValue => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length < from || (value as Func).length > to) {\n errors.push(getError(ValidatorType.funcOfXToYArguments, [String(from), String(to)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onOneOf = (tokens: string[], must: boolean) => (value: unknown, context?: IValidationContext): ValidatedValue => {\n const errors = [];\n const isSet = value !== void 0;\n let noOneIsPresent = !isSet;\n const err = must ? ValidatorType.oneOfMust : ValidatorType.oneOfCan;\n if (!Array.isArray(tokens) || !tokens.length) {\n errors.push(getError(err, ['undefined']));\n } else {\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i];\n if (typeof token !== 'string') {\n errors.push(getError(err, [tokens.join('\", \"')]) + ' (non-string token)');\n break;\n }\n const isAnotherPresent = context && Object.prototype.hasOwnProperty.call(context, token);\n if (isSet && isAnotherPresent) {\n errors.push(getError(err, [tokens.join('\", \"')]) + ` (${token} is present)`);\n break;\n }\n if (noOneIsPresent && isAnotherPresent) {\n noOneIsPresent = false;\n }\n }\n if (must && noOneIsPresent) {\n errors.push(getError(err, [tokens.join('\", \"')]));\n }\n }\n return { value, isSet, isValid: !errors.length, errors };\n};\n\nconst onOr = (validators: IValidator[]) => (value: unknown): ValidatedValue => {\n const errors = [];\n if (validators.every(validator => !validator.method(value).isValid)) {\n errors.push(validators.map(v => v.type).join(' OR '));\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nenum AbstractEnum { }\ntype TEnum = typeof AbstractEnum;\n\nconst onEnum = (list: TEnum) => (value: unknown): ValidatedValue => {\n const errors = [];\n const values = Object.keys(list).filter(k => isNaN(Number(k))).map(k => list[k as unknown as number]);\n if (!values.some(item => item === value)) {\n errors.push(getError(ValidatorType.enum, ['[' + values.join(',') + ']']));\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nexport const VALIDATORS = {\n NUMBER: {\n type: ValidatorType.number,\n method: onNumber\n },\n INTEGER: {\n type: ValidatorType.integer,\n method: onInteger\n },\n INTEGER_UNLIMITED: {\n type: ValidatorType.integerUnlimited,\n method: onIntegerUnlimited\n },\n MORE_OR_EQUAL: (limit: number, fallback?: boolean): IValidator => ({\n type: ValidatorType.moreOrEqual,\n method: onMoreOrEqual(limit, fallback)\n }),\n BOOLEAN: {\n type: ValidatorType.boolean,\n method: onBoolean\n },\n OBJECT: {\n type: ValidatorType.object,\n method: onObject\n },\n ITEM_LIST: {\n type: ValidatorType.itemList,\n method: onItemList\n },\n ELEMENT: {\n type: ValidatorType.element,\n method: onHtmlElement\n },\n FUNC: {\n type: ValidatorType.function,\n method: onFunction\n },\n FUNC_WITH_X_ARGUMENTS: (count: number): IValidator => ({\n type: ValidatorType.funcOfxArguments,\n method: onFunctionWithXArguments(count)\n }),\n FUNC_WITH_X_AND_MORE_ARGUMENTS: (count: number): IValidator => ({\n type: ValidatorType.funcOfxAndMoreArguments,\n method: onFunctionWithXAndMoreArguments(count)\n }),\n FUNC_WITH_X_TO_Y_ARGUMENTS: (from: number, to: number): IValidator => ({\n type: ValidatorType.funcOfXToYArguments,\n method: onFunctionWithXToYArguments(from, to)\n }),\n ONE_OF_CAN: (list: string[]): IValidator => ({\n type: ValidatorType.oneOfCan,\n method: onOneOf(list, false)\n }),\n ONE_OF_MUST: (list: string[]): IValidator => ({\n type: ValidatorType.oneOfMust,\n method: onOneOf(list, true)\n }),\n OR: (list: IValidator[]): IValidator => ({\n type: ValidatorType.or,\n method: onOr(list)\n }),\n ENUM: (list: TEnum): IValidator => ({\n type: ValidatorType.enum,\n method: onEnum(list)\n })\n};\n\nexport class ValidatedData implements IValidatedData {\n\n context: IValidationContext;\n isValidContext: boolean;\n isValid: boolean;\n errors: string[];\n params: IValidatedCommonProps<PropertyKey>;\n\n private contextErrors: string[];\n\n constructor(context: unknown) {\n this.params = {};\n this.contextErrors = [];\n this.errors = [];\n this.isValid = true;\n this.setContext(context);\n }\n\n private setContext(context: unknown): void {\n if (!context || Object.prototype.toString.call(context) !== '[object Object]') {\n this.setCommonError('context is not an object');\n this.isValidContext = false;\n } else {\n this.isValidContext = true;\n }\n this.context = context as IValidationContext;\n }\n\n private setValidity() {\n this.errors = Object.keys(this.params).reduce((acc: string[], key: string) => [\n ...acc, ...this.params[key].errors\n ], []);\n this.isValid = !this.errors.length;\n }\n\n setCommonError(error: string): void {\n this.contextErrors.push(error);\n this.errors.push(error);\n this.isValid = false;\n }\n\n setParam(token: string, value: ValidatedValue): void {\n if (!value.isValid) {\n value.errors = !value.isSet\n ? [`\"${token}\" must be set`]\n : value.errors.map((err: string) =>\n `\"${token}\" ${err}`\n );\n }\n this.params[token] = value;\n this.setValidity();\n }\n\n showErrors(): string {\n return this.errors.length\n ? 'validation failed: ' + this.errors.join(', ')\n : '';\n }\n}\n\nexport const runValidator = (\n current: ValidatedValue,\n validator: IValidator,\n context: IValidationContext\n): ValidatedValue => {\n const { value, errors } = current;\n const result = validator.method(value, context);\n const _errors = [...errors, ...result.errors];\n return {\n value: result.value,\n isSet: result.isSet,\n isValid: !_errors.length,\n errors: _errors\n };\n};\n\nconst getDefault = (value: unknown, prop: ICommonProp): ValidatedValue => {\n const empty = value === void 0;\n const auto = !prop.mandatory && prop.defaultValue !== void 0;\n return {\n value: !empty ? value : (auto ? prop.defaultValue : void 0),\n isSet: !empty || auto,\n isValid: !empty || !prop.mandatory,\n errors: []\n };\n};\n\nexport const validateOne = (\n context: IValidationContext, name: string, prop: ICommonProp\n): ValidatedValue => {\n const result = getDefault(context[name], prop);\n if (!result.isSet) {\n const oneOfMust = prop.validators.find(v => v.type === ValidatorType.oneOfMust);\n if (oneOfMust) {\n return runValidator(result, oneOfMust, context);\n }\n } else {\n for (const validator of Object.values(prop.validators)) {\n const current = runValidator(result, validator, context);\n if (!current.isValid && prop.defaultValue !== void 0) {\n return {\n value: prop.defaultValue,\n isSet: true,\n isValid: true,\n errors: []\n };\n }\n Object.assign(result, current);\n }\n }\n return result;\n};\n\nexport const validate = (\n context: unknown, params: ICommonProps<PropertyKey>\n): IValidatedData => {\n const data = new ValidatedData(context);\n Object.entries(params).forEach(([key, prop]) =>\n data.setParam(key, data.isValidContext\n ? validateOne(data.context, key, prop)\n : getDefault(void 0, prop)\n )\n );\n return data;\n};\n","import { VALIDATORS } from './validation';\nimport { ICommonProps } from '../interfaces/index';\n\nconst { OBJECT, FUNC_WITH_X_AND_MORE_ARGUMENTS } = VALIDATORS;\n\nexport enum DatasourceProps {\n get = 'get',\n settings = 'settings',\n devSettings = 'devSettings',\n}\n\nexport const DATASOURCE: ICommonProps<DatasourceProps> = {\n [DatasourceProps.get]: {\n validators: [FUNC_WITH_X_AND_MORE_ARGUMENTS(2)],\n mandatory: true\n },\n [DatasourceProps.settings]: {\n validators: [OBJECT]\n },\n [DatasourceProps.devSettings]: {\n validators: [OBJECT]\n }\n};\n","import { VALIDATORS } from './validation';\nimport { ICommonProps } from '../interfaces/index';\nimport { SizeStrategy, Direction } from './common';\n\nconst { NUMBER, INTEGER, INTEGER_UNLIMITED, MORE_OR_EQUAL, BOOLEAN, ELEMENT, FUNC, OR, ENUM } = VALIDATORS;\n\nenum Settings {\n adapter = 'adapter',\n startIndex = 'startIndex',\n minIndex = 'minIndex',\n maxIndex = 'maxIndex',\n itemSize = 'itemSize',\n bufferSize = 'bufferSize',\n padding = 'padding',\n infinite = 'infinite',\n horizontal = 'horizontal',\n windowViewport = 'windowViewport',\n viewportElement = 'viewportElement',\n inverse = 'inverse',\n onBeforeClip = 'onBeforeClip',\n sizeStrategy = 'sizeStrategy',\n}\n\nenum DevSettings {\n debug = 'debug',\n immediateLog = 'immediateLog',\n logProcessRun = 'logProcessRun',\n logTime = 'logTime',\n throttle = 'throttle',\n initDelay = 'initDelay',\n initWindowDelay = 'initWindowDelay',\n cacheData = 'cacheData',\n cacheOnReload = 'cacheOnReload',\n dismissOverflowAnchor = 'dismissOverflowAnchor',\n directionPriority = 'directionPriority',\n}\n\nexport const MIN = {\n [Settings.itemSize]: 1,\n [Settings.bufferSize]: 1,\n [Settings.padding]: 0.01,\n [DevSettings.throttle]: 0,\n [DevSettings.initDelay]: 0,\n [DevSettings.initWindowDelay]: 0,\n};\n\nexport const SETTINGS: ICommonProps<Settings> = {\n [Settings.adapter]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.startIndex]: {\n validators: [INTEGER],\n defaultValue: 1\n },\n [Settings.minIndex]: {\n validators: [INTEGER_UNLIMITED],\n defaultValue: -Infinity\n },\n [Settings.maxIndex]: {\n validators: [INTEGER_UNLIMITED],\n defaultValue: Infinity\n },\n [Settings.itemSize]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[Settings.itemSize], true)],\n defaultValue: NaN\n },\n [Settings.bufferSize]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[Settings.bufferSize], true)],\n defaultValue: 5\n },\n [Settings.padding]: {\n validators: [NUMBER, MORE_OR_EQUAL(MIN[Settings.padding], true)],\n defaultValue: 0.5\n },\n [Settings.infinite]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.horizontal]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.windowViewport]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.viewportElement]: {\n validators: [OR([ELEMENT, FUNC])],\n defaultValue: null\n },\n [Settings.inverse]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.onBeforeClip]: {\n validators: [FUNC],\n defaultValue: null\n },\n [Settings.sizeStrategy]: {\n validators: [ENUM(SizeStrategy)],\n defaultValue: SizeStrategy.Average\n },\n};\n\nexport const DEV_SETTINGS: ICommonProps<DevSettings> = {\n [DevSettings.debug]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.immediateLog]: {\n validators: [BOOLEAN],\n defaultValue: true\n },\n [DevSettings.logProcessRun]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.logTime]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.throttle]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.throttle], true)],\n defaultValue: 40\n },\n [DevSettings.initDelay]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.initDelay], true)],\n defaultValue: 1\n },\n [DevSettings.initWindowDelay]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.initWindowDelay], true)],\n defaultValue: 40\n },\n [DevSettings.cacheData]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.cacheOnReload]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.dismissOverflowAnchor]: {\n validators: [BOOLEAN],\n defaultValue: true\n },\n [DevSettings.directionPriority]: {\n validators: [ENUM(Direction)],\n defaultValue: Direction.backward\n },\n};\n","export enum CommonProcess {\n init = 'init',\n scroll = 'scroll',\n start = 'start',\n preFetch = 'preFetch',\n fetch = 'fetch',\n postFetch = 'postFetch',\n render = 'render',\n preClip = 'preClip',\n clip = 'clip',\n adjust = 'adjust',\n end = 'end',\n}\n\nexport enum AdapterProcess {\n reset = 'adapter.reset',\n reload = 'adapter.reload',\n append = 'adapter.append',\n prepend = 'adapter.prepend',\n check = 'adapter.check',\n remove = 'adapter.remove',\n replace = 'adapter.replace',\n update = 'adapter.update',\n clip = 'adapter.clip',\n insert = 'adapter.insert',\n fix = 'adapter.fix',\n}\n\nexport enum ProcessStatus {\n start = 'start',\n next = 'next',\n done = 'done',\n error = 'error'\n}\n","import { VALIDATORS } from './validation';\nimport { DatasourceProps as AdapterResetParams } from './datasource';\nimport { AdapterProcess as Process } from '../processes/misc/enums';\nimport { ICommonProps, AdapterProcessMap } from '../interfaces/index';\n\nconst {\n INTEGER,\n INTEGER_UNLIMITED,\n BOOLEAN,\n OBJECT,\n ITEM_LIST,\n FUNC_WITH_X_ARGUMENTS,\n FUNC_WITH_X_AND_MORE_ARGUMENTS,\n FUNC_WITH_X_TO_Y_ARGUMENTS,\n ONE_OF_MUST,\n ONE_OF_CAN,\n OR,\n} = VALIDATORS;\n\nenum AdapterNoParams { }\nconst NO_METHOD_PARAMS: ICommonProps<AdapterNoParams> = {};\n\nconst RESET_METHOD_PARAMS: ICommonProps<AdapterResetParams> = {\n [AdapterResetParams.get]: {\n validators: [FUNC_WITH_X_AND_MORE_ARGUMENTS(2)]\n },\n [AdapterResetParams.settings]: {\n validators: [OBJECT]\n },\n [AdapterResetParams.devSettings]: {\n validators: [OBJECT]\n },\n};\n\nenum AdapterReloadParams {\n reloadIndex = 'reloadIndex',\n}\n\nconst RELOAD_METHOD_PARAMS: ICommonProps<AdapterReloadParams> = {\n [AdapterReloadParams.reloadIndex]: {\n validators: [INTEGER]\n },\n};\n\nenum AdapterPrependParams {\n items = 'items',\n bof = 'bof',\n increase = 'increase',\n}\n\nconst PREPEND_METHOD_PARAMS: ICommonProps<AdapterPrependParams> = {\n [AdapterPrependParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterPrependParams.bof]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [AdapterPrependParams.increase]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterAppendParams {\n items = 'items',\n eof = 'eof',\n decrease = 'decrease',\n}\n\nconst APPEND_METHOD_PARAMS: ICommonProps<AdapterAppendParams> = {\n [AdapterAppendParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterAppendParams.eof]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [AdapterAppendParams.decrease]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterRemoveParams {\n predicate = 'predicate',\n indexes = 'indexes',\n increase = 'increase',\n}\n\nconst REMOVE_METHOD_PARAMS: ICommonProps<AdapterRemoveParams> = {\n [AdapterRemoveParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([AdapterRemoveParams.indexes])]\n },\n [AdapterRemoveParams.indexes]: {\n validators: [ITEM_LIST, ONE_OF_MUST([AdapterRemoveParams.predicate])]\n },\n [AdapterRemoveParams.increase]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterClipParams {\n backwardOnly = 'backwardOnly',\n forwardOnly = 'forwardOnly',\n}\n\nconst CLIP_METHOD_PARAMS: ICommonProps<AdapterClipParams> = {\n [AdapterClipParams.backwardOnly]: {\n validators: [BOOLEAN, ONE_OF_CAN([AdapterClipParams.forwardOnly])],\n defaultValue: false\n },\n [AdapterClipParams.forwardOnly]: {\n validators: [BOOLEAN, ONE_OF_CAN([AdapterClipParams.backwardOnly])],\n defaultValue: false\n },\n};\n\nenum AdapterInsertParams {\n items = 'items',\n before = 'before',\n after = 'after',\n beforeIndex = 'beforeIndex',\n afterIndex = 'afterIndex',\n decrease = 'decrease',\n}\n\nconst INSERT_METHOD_PARAMS: ICommonProps<AdapterInsertParams> = {\n [AdapterInsertParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterInsertParams.before]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([\n AdapterInsertParams.after, AdapterInsertParams.beforeIndex, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.after]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.beforeIndex, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.beforeIndex]: {\n validators: [INTEGER, ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.after, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.afterIndex]: {\n validators: [INTEGER, ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.after, AdapterInsertParams.beforeIndex\n ])]\n },\n [AdapterInsertParams.decrease]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterReplaceParams {\n items = 'items',\n predicate = 'predicate',\n fixRight = 'fixRight',\n}\n\nconst REPLACE_METHOD_PARAMS: ICommonProps<AdapterReplaceParams> = {\n [AdapterInsertParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterReplaceParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)],\n mandatory: true\n },\n [AdapterReplaceParams.fixRight]: {\n validators: [BOOLEAN],\n defaultValue: false\n }\n};\n\nenum AdapterUpdateParams {\n predicate = 'predicate',\n fixRight = 'fixRight',\n}\n\nconst UPDATE_METHOD_PARAMS: ICommonProps<AdapterUpdateParams> = {\n [AdapterUpdateParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)],\n mandatory: true\n },\n [AdapterUpdateParams.fixRight]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterFixParams {\n scrollPosition = 'scrollPosition',\n minIndex = 'minIndex',\n maxIndex = 'maxIndex',\n updater = 'updater',\n scrollToItem = 'scrollToItem',\n scrollToItemOpt = 'scrollToItemOpt',\n}\n\nconst FIX_METHOD_PARAMS: ICommonProps<AdapterFixParams> = {\n [AdapterFixParams.scrollPosition]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.minIndex]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.maxIndex]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.updater]: {\n validators: [FUNC_WITH_X_TO_Y_ARGUMENTS(1, 2)]\n },\n [AdapterFixParams.scrollToItem]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)]\n },\n [AdapterFixParams.scrollToItemOpt]: {\n validators: [OR([BOOLEAN, OBJECT])]\n },\n};\n\nexport const AdapterMethods: AdapterProcessMap<{ [key: string]: string }> = {\n [Process.reset]: AdapterResetParams,\n [Process.reload]: AdapterReloadParams,\n [Process.prepend]: AdapterPrependParams,\n [Process.append]: AdapterAppendParams,\n [Process.check]: AdapterNoParams,\n [Process.remove]: AdapterRemoveParams,\n [Process.clip]: AdapterClipParams,\n [Process.insert]: AdapterInsertParams,\n [Process.replace]: AdapterReplaceParams,\n [Process.update]: AdapterUpdateParams,\n [Process.fix]: AdapterFixParams,\n};\n\nexport const ADAPTER_METHODS: AdapterProcessMap<ICommonProps<PropertyKey>> = {\n [Process.reset]: RESET_METHOD_PARAMS,\n [Process.reload]: RELOAD_METHOD_PARAMS,\n [Process.prepend]: PREPEND_METHOD_PARAMS,\n [Process.append]: APPEND_METHOD_PARAMS,\n [Process.check]: NO_METHOD_PARAMS,\n [Process.remove]: REMOVE_METHOD_PARAMS,\n [Process.clip]: CLIP_METHOD_PARAMS,\n [Process.insert]: INSERT_METHOD_PARAMS,\n [Process.replace]: REPLACE_METHOD_PARAMS,\n [Process.update]: UPDATE_METHOD_PARAMS,\n [Process.fix]: FIX_METHOD_PARAMS,\n};\n","import { SETTINGS, DEV_SETTINGS, validate, validateOne, VALIDATORS, SizeStrategy, Direction } from '../inputs/index';\nimport { Settings as ISettings, DevSettings as IDevSettings, ICommonProps, ItemsProcessor } from '../interfaces/index';\n\nexport class Settings<Data = unknown> implements ISettings, IDevSettings {\n\n // user settings\n adapter: boolean;\n startIndex: number;\n minIndex: number;\n maxIndex: number;\n itemSize: number;\n bufferSize: number;\n padding: number;\n infinite: boolean;\n horizontal: boolean;\n windowViewport: boolean;\n viewportElement: HTMLElement | (() => void) | null;\n inverse: boolean; // if true, bwd padding element will have a priority when filling the viewport (if lack of items)\n onBeforeClip: ItemsProcessor | null; // if set, it will be run before clipping items from Buffer after they are hidden\n sizeStrategy: SizeStrategy; // \"average\" | \"frequent\", determines behavior of unknown items\n\n /**\n * Development setting.\n * If true, logging is enabled.\n * Default value: false.\n * @type {boolean}\n */\n debug: boolean; // if true, \n\n /**\n * Development setting.\n * If false, in-memory logging is enabled, Adapter.showLog() method should be called to print the log.\n * Default value: true.\n * @type {boolean}\n */\n immediateLog: boolean;\n\n /**\n * Development setting.\n * If true, time differences will be logged.\n * Default value: false.\n * @type {boolean}\n */\n logTime: boolean;\n\n /**\n * Development setting.\n * If true, process fire/run info will be logged.\n * Default value: false.\n * @type {boolean}\n */\n logProcessRun: boolean;\n\n /**\n * Development setting.\n * If set, scroll event handling is throttled (ms).\n * Default value: 40. Minimal value: 0.\n * @type {number} ms\n */\n throttle: number;\n\n /**\n * Development setting.\n * If set, the Workflow initialization will be postponed (ms).\n * Default value: 1. Minimal value: 0.\n * @type {number} ms\n */\n initDelay: number;\n\n /**\n * Development setting.\n * If set and the entire window is scrollable, the Workflow initialization will be postponed (ms).\n * Default value: 40. Minimal value: 0.\n * @type {number} ms\n */\n initWindowDelay: number;\n\n /**\n * Development setting.\n * If true, item's data will be cached along with item's size and index.\n * Default value: false.\n * @type {boolean}\n */\n cacheData: boolean;\n\n /**\n * Development setting.\n * If true, cache will not be flushed on reload.\n * Default value: false.\n * @type {boolean}\n */\n cacheOnReload: boolean;\n\n /**\n * Development setting.\n * If true, the viewport will receive \"overflowAnchor: none\" css property.\n * Default value: false.\n * @type {boolean}\n */\n dismissOverflowAnchor: boolean;\n\n /**\n * Development setting.\n * Determines the strategy of fixing the difference between estimated and real (rendered) sizes\n * on scroll position adjustments. If set to 'backward', the difference is always resolved in favour of the\n * backward direction: top/left content is fixed and appears in accordance with pre-render expectations.\n * If set to 'forward', both directions could be used, and there is a case when bottom/right content is fixed:\n * new items are to the left of the previously rendered\n * and at least one previously rendered item remains.\n * Default value: 'backward'. Allowed values: 'backward', 'forward'.\n * @type {string}\n */\n directionPriority: Direction;\n\n /**\n * Internal setting. Stores the index of the Scroller instance.\n * @type {number}\n */\n instanceIndex: number;\n\n /**\n * Internal setting. Stores the Workflow initialization delay based on initDelay and initWindowDelay settings.\n * @type {number}\n */\n initializeDelay: number;\n\n /**\n * Internal setting. Stores the viewport based on viewportElement setting (which can be element or function).\n * @type {HTMLElement|null}\n */\n viewport: HTMLElement | null;\n\n constructor(\n settings: ISettings<Data> | undefined, devSettings: IDevSettings | undefined, instanceIndex: number\n ) {\n this.parseInput(settings, SETTINGS);\n this.parseInput(devSettings, DEV_SETTINGS);\n this.instanceIndex = instanceIndex;\n this.initializeDelay = this.getInitializeDelay();\n this.viewport = this.getViewport();\n // todo: min/max indexes must be ignored if infinite mode is enabled ??\n }\n\n parseInput(input: ISettings<Data> | IDevSettings | undefined, props: ICommonProps<PropertyKey>): void {\n const result = validate(input, props);\n if (!result.isValid) {\n throw new Error('Invalid settings');\n }\n Object.entries(result.params).forEach(([key, par]) =>\n Object.assign(this, { [key]: par.value })\n );\n }\n\n getInitializeDelay(): number {\n let result = 0;\n if (this.windowViewport && this.initWindowDelay && !('scrollRestoration' in history)) {\n result = this.initWindowDelay;\n }\n if (this.initDelay > 0) {\n result = Math.max(result, this.initDelay);\n }\n return result;\n }\n\n getViewport(): HTMLElement | null {\n if (typeof this.viewportElement !== 'function') {\n return this.viewportElement;\n }\n const value = this.viewportElement();\n const result = validateOne({ value }, 'value', { validators: [VALIDATORS.ELEMENT] });\n if (!result.isValid) {\n return null; // fallback to default (null) if Function didn't return HTML element synchronously\n }\n return result.value as HTMLElement;\n }\n}\n","import { AdapterProcess, ProcessStatus } from './enums';\nimport { Scroller } from '../../scroller';\nimport { ADAPTER_METHODS, validate } from '../../inputs/index';\nimport { ProcessName, IBaseProcess, IBaseAdapterProcess, IAdapterInput } from '../../interfaces/index';\n\nexport const BaseProcessFactory = (process: ProcessName): IBaseProcess =>\n\n class BaseProcess {\n\n static process: ProcessName = process;\n\n };\n\nexport const BaseAdapterProcessFactory = (process: AdapterProcess): IBaseAdapterProcess =>\n\n class BaseAdapterProcess extends (BaseProcessFactory(process) as IBaseProcess) {\n\n static process: AdapterProcess = process;\n\n static parseInput<T>(\n scroller: Scroller, options: T, ignoreErrors = false, _process?: AdapterProcess\n ): IAdapterInput<T> {\n const result: IAdapterInput<T> = {\n data: validate(options, ADAPTER_METHODS[_process || process])\n };\n\n if (result.data.isValid) {\n result.params = Object.entries(result.data.params)\n .reduce((acc, [key, { value }]) => ({\n ...acc,\n [key]: value\n }), {} as T);\n } else {\n scroller.logger.log(() => result.data.showErrors());\n if (!ignoreErrors) {\n scroller.workflow.call({\n process,\n status: ProcessStatus.error,\n payload: { error: `Wrong argument of the \"${process}\" method call` }\n });\n }\n }\n\n return result;\n }\n\n };\n","import { BaseProcessFactory, CommonProcess, AdapterProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { ProcessName } from '../interfaces/index';\n\nconst initProcesses = [CommonProcess.init, AdapterProcess.reset, AdapterProcess.reload];\n\nexport default class Init extends BaseProcessFactory(CommonProcess.init) {\n\n static run(scroller: Scroller, process: ProcessName): void {\n const { state: { cycle }, workflow } = scroller;\n const isInitial = initProcesses.includes(process);\n scroller.logger.logCycle(true);\n cycle.start(isInitial, process);\n workflow.call({\n process: Init.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\nimport { ScrollEventData, ScrollerWorkflow } from '../interfaces/index';\n\nexport default class Scroll extends BaseProcessFactory(CommonProcess.scroll) {\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static run(scroller: Scroller, payload?: { event?: Event }): void {\n const { workflow, viewport } = scroller;\n const position = viewport.scrollPosition;\n\n if (Scroll.onSynthetic(scroller, position)) {\n return;\n }\n\n Scroll.onThrottle(scroller, position, () =>\n Scroll.onScroll(scroller, workflow)\n );\n }\n\n static onSynthetic(scroller: Scroller, position: number): boolean {\n const { scrollState } = scroller.state;\n const synthPos = scrollState.syntheticPosition;\n if (synthPos !== null) {\n if (scrollState.syntheticFulfill) {\n scrollState.syntheticPosition = null;\n }\n if (!scrollState.syntheticFulfill || synthPos === position) {\n scroller.logger.log(() => [\n 'skipping scroll', position, `[${scrollState.syntheticFulfill ? '' : 'pre-'}synthetic]`\n ]);\n return true;\n }\n scroller.logger.log(() => [\n 'synthetic scroll has been fulfilled:', position, position < synthPos ? '<' : '>', synthPos\n ]);\n }\n return false;\n }\n\n static onThrottle(scroller: Scroller, position: number, done: () => void): void {\n const { state: { scrollState }, settings: { throttle }, logger } = scroller;\n scrollState.current = Scroll.getScrollEvent(position, scrollState.previous);\n const { direction, time } = scrollState.current;\n const timeDiff = scrollState.previous ? time - scrollState.previous.time : Infinity;\n const delta = throttle - timeDiff;\n const shouldDelay = isFinite(delta) && delta > 0;\n const alreadyDelayed = !!scrollState.scrollTimer;\n logger.log(() => [\n direction === Direction.backward ? '\\u2934' : '\\u2935',\n position,\n shouldDelay ? (timeDiff + 'ms') : '0ms',\n shouldDelay ? (alreadyDelayed ? 'delayed' : `/ ${delta}ms delay`) : ''\n ]);\n if (!shouldDelay) {\n if (scrollState.scrollTimer) {\n clearTimeout(scrollState.scrollTimer);\n scrollState.scrollTimer = null;\n }\n done();\n return;\n }\n if (!alreadyDelayed) {\n scrollState.scrollTimer = setTimeout(() => {\n logger.log(() => {\n const curr = Scroll.getScrollEvent(scroller.viewport.scrollPosition, scrollState.current);\n return [\n curr.direction === Direction.backward ? '\\u2934' : '\\u2935',\n curr.position,\n (curr.time - time) + 'ms',\n 'triggered by timer set on',\n position\n ];\n });\n scrollState.scrollTimer = null;\n done();\n }, delta);\n }\n }\n\n static getScrollEvent(position: number, previous: ScrollEventData | null): ScrollEventData {\n const time = Number(new Date());\n let direction: Direction | null = Direction.forward;\n if (previous) {\n if (position === previous.position) {\n direction = previous.direction;\n } else if (position < previous.position) {\n direction = Direction.backward;\n }\n }\n return { position, direction, time };\n }\n\n static onScroll(scroller: Scroller, workflow: ScrollerWorkflow): void {\n const { state: { scrollState, cycle } } = scroller;\n scrollState.previous = { ...(scrollState.current as ScrollEventData) };\n scrollState.current = null;\n\n if (cycle.busy.get()) {\n scroller.logger.log(() => ['skipping scroll', (scrollState.previous as ScrollEventData).position, '[pending]']);\n return;\n }\n\n workflow.call({\n process: Scroll.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { DatasourceProps } from '../../inputs/index';\nimport { Datasource } from '../../classes/datasource';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { IDatasourceOptional, ProcessPayload } from '../../interfaces/index';\n\nexport default class Reset extends BaseAdapterProcessFactory(AdapterProcess.reset) {\n\n static run(scroller: Scroller, options?: IDatasourceOptional): void {\n const { datasource, buffer, viewport: { paddings }, state: { cycle } } = scroller;\n\n if (options) {\n const { data } = Reset.parseInput(scroller, options);\n if (!data.isValid) {\n return;\n }\n const constructed = options instanceof Datasource;\n Object.keys(DatasourceProps).forEach(key => {\n const param = data.params[key];\n const ds = datasource as unknown as { [key: string]: unknown };\n if (param.isSet || (constructed && ds[key])) {\n ds[key] = param.value;\n }\n });\n }\n\n buffer.reset(true);\n paddings.backward.reset();\n paddings.forward.reset();\n\n const payload: ProcessPayload = { datasource };\n if (cycle.busy.get()) {\n payload.finalize = true;\n cycle.interrupter = Reset.process;\n }\n\n scroller.workflow.call({\n process: Reset.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { ProcessPayload } from '../../interfaces/index';\n\nexport default class Reload extends BaseAdapterProcessFactory(AdapterProcess.reload) {\n\n static run(scroller: Scroller, reloadIndex: number): void {\n const { viewport, state, buffer } = scroller;\n\n const { params } = Reload.parseInput(scroller, { reloadIndex }, true);\n\n buffer.reset(false, params ? params.reloadIndex : void 0);\n viewport.reset(buffer.startIndex);\n\n const payload: ProcessPayload = {};\n if (state.cycle.busy.get()) {\n state.scrollState.cleanupTimers();\n payload.finalize = true;\n state.cycle.interrupter = Reload.process;\n }\n\n scroller.workflow.call({\n process: Reload.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { Routines } from './domRoutines';\nimport { Direction } from '../inputs/index';\nimport { Item as _Item, ItemAdapter } from '../interfaces/index';\n\nexport class Item<Data = unknown> implements _Item<Data> {\n nodeId: string;\n routines: Routines;\n preSize: number; // estimated size\n size: number; // real size\n invisible: boolean;\n toRemove: boolean;\n toInsert: boolean;\n removeDirection: Direction;\n\n private container: ItemAdapter<Data>;\n\n get $index(): number {\n return this.container.$index;\n }\n set $index(value: number) {\n this.container.$index = value;\n }\n\n get data(): Data {\n return this.container.data;\n }\n set data(value: Data) {\n this.container.data = value;\n }\n\n get element(): HTMLElement {\n return this.container.element as HTMLElement;\n }\n set element(value: HTMLElement) {\n this.container.element = value;\n }\n\n constructor($index: number, data: Data, routines: Routines) {\n this.container = {\n $index,\n data\n };\n this.nodeId = String($index);\n this.routines = routines;\n this.invisible = true;\n this.toRemove = false;\n this.toInsert = false;\n }\n\n dispose(): void {\n delete this.container.element;\n }\n\n setSize(preSize = 0): void {\n this.preSize = preSize;\n if (this.element) {\n this.size = this.routines.getSize(this.element);\n }\n }\n\n hide(): void {\n if (this.element) {\n this.routines.hideElement(this.element);\n }\n }\n\n scrollTo(argument?: boolean | ScrollIntoViewOptions): void {\n if (this.element) {\n this.routines.scrollTo(this.element, argument);\n }\n }\n\n updateIndex(index: number): void {\n this.$index = index;\n this.nodeId = String(index);\n }\n\n get(): ItemAdapter<Data> {\n return this.container;\n }\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Item } from '../../classes/item';\nimport { Direction } from '../../inputs/index';\nimport { AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Update extends BaseAdapterProcessFactory(AdapterProcess.update) {\n\n static run(scroller: Scroller, options: AdapterUpdateOptions): void {\n const { params } = Update.parseInput(scroller, options);\n if (!params) {\n return;\n }\n\n const shouldUpdate = Update.doUpdate(scroller, params);\n\n scroller.workflow.call({\n process: Update.process,\n status: shouldUpdate ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doUpdate(scroller: Scroller, params: AdapterUpdateOptions): boolean {\n const { buffer, viewport, state: { fetch }, routines, logger } = scroller;\n if (!buffer.items) {\n logger.log(() => 'no items in Buffer');\n return false;\n }\n const { item: firstItem, index: firstIndex, diff: firstItemDiff } =\n viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n\n const { trackedIndex, toRemove } = buffer.updateItems(\n params.predicate,\n (index, data) => new Item(index, data, routines),\n firstIndex,\n !!params.fixRight\n );\n\n let delta = 0;\n const trackedItem = buffer.get(trackedIndex);\n if (firstItem && firstItem === trackedItem) {\n delta = - buffer.getSizeByIndex(trackedIndex) + firstItemDiff;\n }\n\n toRemove.forEach(item => item.hide());\n logger.log(() => toRemove.length\n ? 'items to remove: [' + toRemove.map(({ $index }) => $index).join(',') + ']'\n : 'no items to remove'\n );\n if (toRemove.length) { // insertions will be processed on render\n buffer.checkDefaultSize();\n }\n\n const toRender = buffer.items.filter(({ toInsert }) => toInsert);\n logger.log(() => toRender.length\n ? 'items to render: [' + toRender.map(({ $index }) => $index).join(',') + ']'\n : 'no items to render'\n );\n\n fetch.update(trackedIndex, delta, toRender, toRemove);\n return !!toRemove.length || !!toRender.length;\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { Item } from '../../classes/item';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Direction } from '../../inputs/index';\nimport { AdapterAppendOptions, AdapterPrependOptions, AdapterUpdateOptions } from '../../interfaces/index';\n\ntype AdapterAppendPrependOptions = AdapterAppendOptions & AdapterPrependOptions;\n\ninterface AppendRunOptions {\n process: AdapterProcess;\n options: AdapterAppendPrependOptions;\n}\n\nexport default class Append extends BaseAdapterProcessFactory(AdapterProcess.append) {\n\n static run(scroller: Scroller, { process, options }: AppendRunOptions): void {\n const { params } = Append.parseInput(scroller, options, false, process);\n if (!params) {\n return;\n }\n const shouldAppend = Append.doAppend(scroller, params, process !== AdapterProcess.append);\n\n scroller.workflow.call({\n process: Append.process,\n status: shouldAppend ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doAppend(scroller: Scroller, params: AdapterAppendPrependOptions, prepend: boolean): boolean {\n const { buffer } = scroller;\n const { items, bof, eof, increase, decrease } = params;\n const fixRight = (prepend && !increase) || (!prepend && !!decrease);\n let result = false;\n if ((prepend && bof && !buffer.bof.get()) || (!prepend && eof && !buffer.eof.get())) {\n result = Append.doVirtual(scroller, items, prepend, fixRight);\n } else {\n if (!buffer.size) {\n result = Append.doEmpty(scroller, items, prepend, fixRight);\n } else {\n result = Append.doRegular(scroller, items, prepend, fixRight);\n }\n }\n return result;\n }\n\n static doVirtual(scroller: Scroller, items: unknown[], prepend: boolean, fixRight: boolean): boolean {\n const { buffer, logger, viewport, state: { fetch } } = scroller;\n const absIndexToken = fixRight ? 'absMinIndex' : 'absMaxIndex';\n if (!isFinite(buffer[absIndexToken])) {\n return false;\n }\n if (prepend) {\n buffer.prependVirtually(items.length, fixRight);\n } else {\n buffer.appendVirtually(items.length, fixRight);\n }\n const { index, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = index;\n if (!isNaN(index)) {\n fetch.simulate = true;\n fetch.firstVisible.delta = - buffer.getSizeByIndex(index) + diff;\n }\n logger.log(() => `buffer.${[absIndexToken]} value is set to ${buffer[absIndexToken]}`);\n logger.stat(`after virtual ${prepend ? 'prepend' : 'append'}`);\n return true;\n }\n\n static doEmpty(scroller: Scroller, items: unknown[], prepend: boolean, fixRight: boolean): boolean {\n const { buffer, state: { fetch } } = scroller;\n const absIndexToken = fixRight ? 'absMinIndex' : 'absMaxIndex';\n const shift = prepend && !fixRight ? items.length - 1 : (!prepend && fixRight ? 1 - items.length : 0);\n const bufferLimit = buffer[absIndexToken] + (fixRight ? -1 : 1) * (items.length - 1);\n const newItems: Item[] = [];\n const startIndex = buffer[prepend ? 'minIndex' : 'maxIndex'];\n let index = startIndex;\n\n items.forEach(item => {\n const newItem = new Item(index + shift, item, scroller.routines);\n Array.prototype[prepend ? 'unshift' : 'push'].call(newItems, newItem);\n index += (prepend ? -1 : 1);\n });\n\n if (bufferLimit !== buffer[absIndexToken]) {\n buffer[absIndexToken] = bufferLimit;\n scroller.logger.log(() => `buffer.${absIndexToken} value is set to ${buffer[absIndexToken]}`);\n }\n\n (prepend ? fetch.prepend : fetch.append).call(fetch, newItems);\n buffer.setItems(newItems);\n fetch.first.indexBuffer = !isNaN(buffer.firstIndex) ? buffer.firstIndex : index;\n fetch.last.indexBuffer = !isNaN(buffer.lastIndex) ? buffer.lastIndex : index;\n fetch.firstVisible.index = startIndex;\n return true;\n }\n\n static doRegular(scroller: Scroller, items: unknown[], prepend: boolean, fixRight: boolean): boolean {\n const index = scroller.buffer[prepend ? 'firstIndex' : 'lastIndex'];\n const updateOptions: AdapterUpdateOptions = {\n predicate: ({ $index, data }) => {\n if ($index === index) {\n return prepend ? [...items.reverse(), data] : [data, ...items];\n }\n return true;\n },\n fixRight\n };\n return Update.doUpdate(scroller, updateOptions);\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Direction } from '../../inputs/index';\n\nexport default class Check extends BaseAdapterProcessFactory(AdapterProcess.check) {\n\n static run(scroller: Scroller): void {\n const { workflow, buffer, state: { fetch }, viewport } = scroller;\n let min = Infinity, max = -Infinity;\n\n buffer.items.forEach(item => {\n const size = item.size;\n item.setSize();\n if (item.size !== size) {\n buffer.cacheItem(item);\n min = Math.min(min, item.$index);\n max = Math.max(max, item.$index);\n }\n });\n\n if (Number.isFinite(min)) {\n fetch.first.indexBuffer = buffer.firstIndex;\n fetch.last.indexBuffer = buffer.lastIndex;\n const { index: firstIndex, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = firstIndex;\n if (!isNaN(firstIndex)) {\n fetch.firstVisible.delta = - buffer.getSizeByIndex(firstIndex) + diff;\n }\n fetch.check(\n buffer.items.filter(item => item.$index >= min && item.$index <= max)\n );\n }\n\n scroller.logger.stat('check');\n\n workflow.call({\n process: Check.process,\n status: Number.isFinite(min) ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Direction } from '../../inputs/index';\nimport { AdapterRemoveOptions, AdapterUpdateOptions, ItemsPredicate } from '../../interfaces/index';\n\nexport default class Remove extends BaseAdapterProcessFactory(AdapterProcess.remove) {\n\n static run(scroller: Scroller, options: AdapterRemoveOptions): void {\n const { params } = Remove.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldRemove = Remove.doRemove(scroller, params);\n\n scroller.workflow.call({\n process: Remove.process,\n status: shouldRemove ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doRemove(scroller: Scroller, params: AdapterRemoveOptions): boolean {\n const { fetch } = scroller.state;\n fetch.firstVisible.index = NaN;\n const removed = Remove.removeBufferedItems(scroller, params);\n const shouldBuffered = removed.length > 0;\n if (shouldBuffered) {\n // exclude just removed in-buffer indexes\n if (params.indexes && params.indexes.length) {\n params.indexes = params.indexes.filter(i => !removed.includes(i));\n }\n // shift virtual indexes that remain\n if (params.indexes && params.indexes.length) {\n const diffLeft = (params.increase ? 1 : 0) * removed.length;\n const diffRight = (params.increase ? 0 : -1) * removed.length;\n params.indexes = params.indexes.map(index =>\n index + (index < removed[0] ? diffLeft : diffRight)\n );\n }\n }\n const shouldVirtual = Remove.removeVirtualItems(scroller, params);\n if (!shouldBuffered && !shouldVirtual) {\n return false;\n }\n scroller.logger.stat('after remove');\n return true;\n }\n\n static removeBufferedItems(scroller: Scroller, options: AdapterRemoveOptions): number[] {\n const { predicate, indexes, increase } = options;\n if (!predicate && !indexes) {\n return [];\n }\n const newPredicate: ItemsPredicate = item =>\n (predicate && predicate(item)) ||\n (!!indexes && indexes.includes(item.$index));\n\n const indexesToRemove: number[] = scroller.buffer.items.reduce((acc, item) =>\n newPredicate(item) ? [...acc, item.$index] : acc, [] as number[]\n );\n const updateOptions: AdapterUpdateOptions = {\n predicate: item => !newPredicate(item),\n fixRight: increase\n };\n Update.doUpdate(scroller, updateOptions);\n return indexesToRemove;\n }\n\n static removeVirtualItems(scroller: Scroller, params: AdapterRemoveOptions): boolean {\n const { indexes, increase } = params;\n if (!indexes || !indexes.length) {\n return false;\n }\n const { buffer, viewport, state: { fetch } } = scroller;\n\n // get items to remove\n const { finiteAbsMinIndex, firstIndex, finiteAbsMaxIndex, lastIndex } = buffer;\n const toRemove = [];\n for (let i = 0, len = indexes.length; i < len; i++) {\n const index = indexes[i];\n if (index >= finiteAbsMinIndex && !isNaN(firstIndex) && index < firstIndex) {\n toRemove.push(index); // backward;\n } else if (index <= finiteAbsMaxIndex && !isNaN(lastIndex) && index > lastIndex) {\n toRemove.push(index); // forward;\n } else {\n continue;\n }\n }\n\n if (!toRemove.length) {\n return false;\n }\n\n // what should be shown after remove; Buffer removal has priority\n if (isNaN(fetch.firstVisible.index)) {\n const { index, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = index;\n if (!isNaN(index)) {\n fetch.firstVisible.delta = - buffer.getSizeByIndex(index) + diff;\n }\n }\n\n // virtual removal\n scroller.logger.log(() => `going to remove ${toRemove.length} item(s) virtually`);\n buffer.removeVirtually(toRemove, !!increase);\n buffer.checkDefaultSize();\n Remove.shiftFirstVisibleIndex(scroller, toRemove, !!increase);\n\n return true;\n }\n\n static shiftFirstVisibleIndex(scroller: Scroller, listToRemove: number[], increase: boolean): void {\n const { firstVisible } = scroller.state.fetch;\n if (isNaN(firstVisible.index)) {\n return;\n }\n const shift = listToRemove.reduce((acc, index) => acc + (\n ((increase && index > firstVisible.index) || (!increase && index < firstVisible.index)) ? 1 : 0\n ), 0);\n firstVisible.index = firstVisible.index + (increase ? shift : -shift);\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { AdapterClipOptions } from '../../interfaces/index';\n\nexport default class UserClip extends BaseAdapterProcessFactory(AdapterProcess.clip) {\n\n static run(scroller: Scroller, options?: AdapterClipOptions): void {\n const { params } = UserClip.parseInput(scroller, options);\n\n scroller.state.clip.forceForward = !(params && params.backwardOnly);\n scroller.state.clip.forceBackward = !(params && params.forwardOnly);\n\n scroller.workflow.call({\n process: UserClip.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Item } from '../../classes/item';\nimport { Direction } from '../../inputs/index';\nimport { AdapterInsertOptions, AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Insert extends BaseAdapterProcessFactory(AdapterProcess.insert) {\n\n static run(scroller: Scroller, options: AdapterInsertOptions): void {\n const { params } = Insert.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldInsert = Insert.doInsert(scroller, params);\n\n scroller.workflow.call({\n process: Insert.process,\n status: shouldInsert ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doInsert(scroller: Scroller, params: AdapterInsertOptions): boolean {\n if (!Insert.insertEmpty(scroller, params)) {\n if (!Insert.insertInBuffer(scroller, params)) {\n if (!Insert.insertVirtually(scroller, params)) {\n return false;\n }\n }\n }\n return true;\n }\n\n static insertEmpty(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { buffer, routines, state: { fetch } } = scroller;\n if (buffer.size) {\n return false;\n }\n const { beforeIndex, afterIndex, items, decrease } = params;\n if (!buffer.fillEmpty(\n items, beforeIndex, afterIndex, !!decrease,\n (index, data) => new Item(index, data, routines)\n )) {\n return false;\n }\n fetch.fill(buffer.items, buffer.startIndex);\n\n return true;\n }\n\n static insertInBuffer(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { before, after, beforeIndex, afterIndex, items, decrease } = params;\n const indexToInsert = scroller.buffer.getIndexToInsert(before || after, beforeIndex, afterIndex);\n\n if (isNaN(indexToInsert)) {\n return false;\n }\n const isBackward = Number.isInteger(beforeIndex) || before;\n\n const updateOptions: AdapterUpdateOptions = {\n predicate: ({ $index, data }) => {\n if (indexToInsert === $index) {\n return isBackward ? [...items, data] : [data, ...items];\n }\n return true;\n },\n fixRight: decrease\n };\n\n return Update.doUpdate(scroller, updateOptions);\n }\n\n static insertVirtually(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { beforeIndex, afterIndex, items, decrease } = params;\n const { buffer, state: { fetch }, viewport } = scroller;\n const direction = Number.isInteger(beforeIndex) ? Direction.backward : Direction.forward;\n const indexToInsert = (direction === Direction.backward ? beforeIndex : afterIndex) as number;\n\n if (!buffer.insertVirtually(items, indexToInsert, direction, !!decrease)) {\n return false;\n }\n\n const { index, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = index;\n if (!isNaN(index)) {\n fetch.simulate = true;\n fetch.firstVisible.delta = - buffer.getSizeByIndex(index) + diff;\n }\n\n return true;\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { AdapterReplaceOptions, AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Replace extends BaseAdapterProcessFactory(AdapterProcess.replace) {\n\n static run(scroller: Scroller, options: AdapterReplaceOptions): void {\n const { params } = Replace.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldReplace = Replace.doReplace(scroller, params);\n\n scroller.workflow.call({\n process: Replace.process,\n status: shouldReplace ? ProcessStatus.next : ProcessStatus.done,\n });\n }\n\n static doReplace(scroller: Scroller, params: AdapterReplaceOptions): boolean {\n const toRemove = scroller.buffer.items\n .filter(item => params.predicate(item))\n .map(item => item.$index);\n\n if (!toRemove.length) {\n scroller.logger.log('no items to be replaced');\n return false;\n }\n\n let injected = false;\n const updateOptions: AdapterUpdateOptions = {\n predicate: ({ $index }) => {\n if (!toRemove.includes($index)) {\n return true;\n }\n if (!injected) {\n injected = true;\n return params.items;\n }\n return false;\n },\n fixRight: params.fixRight\n };\n\n return Update.doUpdate(scroller, updateOptions);\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { AdapterMethods } from '../../inputs/index';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport {\n ItemsPredicate,\n ItemsUpdater,\n AdapterFixOptions,\n IValidatedData,\n} from '../../interfaces/index';\n\nconst { [AdapterProcess.fix]: FixParams } = AdapterMethods;\n\nexport default class Fix extends BaseAdapterProcessFactory(AdapterProcess.fix) {\n\n static run(scroller: Scroller, options: AdapterFixOptions): void {\n const { workflow } = scroller;\n\n const { data, params } = Fix.parseInput(scroller, options);\n if (!params) {\n return;\n }\n\n Object.entries(data.params).forEach(([key, value]) => {\n if (value.isSet && value.isValid) {\n Fix.runByType(scroller, key, value.value, data);\n }\n });\n\n workflow.call({\n process: Fix.process,\n status: ProcessStatus.done\n });\n }\n\n static runByType(scroller: Scroller, token: string, value: unknown, methodData: IValidatedData): void {\n switch (token) {\n case FixParams.scrollPosition:\n return Fix.setScrollPosition(scroller, value as number);\n case FixParams.minIndex:\n return Fix.setMinIndex(scroller, value as number);\n case FixParams.maxIndex:\n return Fix.setMaxIndex(scroller, value as number);\n case FixParams.updater:\n return Fix.updateItems(scroller, value as ItemsUpdater);\n case FixParams.scrollToItem:\n if (methodData.params) {\n const scrollToItemOpt = methodData.params[FixParams.scrollToItemOpt];\n const options = scrollToItemOpt ? scrollToItemOpt.value as AdapterFixOptions['scrollToItemOpt'] : void 0;\n return Fix.scrollToItem(scroller, value as ItemsPredicate, options);\n }\n return;\n case FixParams.scrollToItemOpt:\n return;\n }\n }\n\n static setScrollPosition({ viewport }: Scroller, value: number): void {\n let result = value;\n if (value === -Infinity) {\n result = 0;\n } else if (value === Infinity) {\n result = viewport.getScrollableSize();\n }\n viewport.setPosition(result);\n }\n\n static setMinIndex({ buffer, settings }: Scroller, value: number): void {\n settings.minIndex = value;\n buffer.absMinIndex = value;\n }\n\n static setMaxIndex({ buffer, settings }: Scroller, value: number): void {\n settings.maxIndex = value;\n buffer.absMaxIndex = value;\n }\n\n static updateItems({ buffer, logger }: Scroller, value: ItemsUpdater): void {\n let updateReference = false;\n const updater = () => updateReference = true;\n buffer.items.forEach(item => value(item.get(), updater));\n if (updateReference) {\n logger.log(() => 'update Buffer.items reference');\n buffer.items = [...buffer.items];\n }\n }\n\n static scrollToItem(scroller: Scroller, value: ItemsPredicate, options?: boolean | ScrollIntoViewOptions): void {\n const found = scroller.buffer.items.find(item => value(item.get()));\n if (!found) {\n scroller.logger.log(() => 'scrollToItem cancelled, item not found');\n return;\n }\n found.scrollTo(options);\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\n\nexport default class Start extends BaseProcessFactory(CommonProcess.start) {\n\n static run(scroller: Scroller): void {\n const payload = scroller.state.startInnerLoop();\n\n scroller.workflow.call({\n process: Start.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, AdapterProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\n\nexport default class PreFetch extends BaseProcessFactory(CommonProcess.preFetch) {\n\n static run(scroller: Scroller): void {\n const { workflow, buffer, state: { fetch, cycle } } = scroller;\n fetch.minIndex = buffer.minIndex;\n\n // set first and last indexes of items to fetch\n PreFetch.setPositionsAndIndexes(scroller);\n\n // skip indexes that are in buffer\n PreFetch.skipBufferedItems(scroller);\n\n if (scroller.settings.infinite) {\n // fill indexes to include buffer if no clip\n PreFetch.checkBufferGaps(scroller);\n }\n\n // add indexes if there are too few items to fetch (clip padding)\n PreFetch.checkFetchPackSize(scroller);\n\n // set fetch direction\n PreFetch.setFetchDirection(scroller);\n\n workflow.call({\n process: PreFetch.process,\n status: PreFetch.getStatus(scroller),\n payload: { process: cycle.initiator }\n });\n }\n\n static setPositionsAndIndexes(scroller: Scroller): void {\n PreFetch.setPositions(scroller);\n PreFetch.setFirstIndex(scroller);\n PreFetch.setLastIndex(scroller);\n scroller.logger.fetch();\n }\n\n static setPositions(scroller: Scroller): void {\n const { state: { fetch: { positions } }, viewport } = scroller;\n const paddingDelta = viewport.getBufferPadding();\n positions.before = viewport.scrollPosition;\n positions.startDelta = PreFetch.getStartDelta(scroller);\n positions.relative = positions.before - positions.startDelta;\n positions.start = positions.relative - paddingDelta;\n positions.end = positions.relative + viewport.getSize() + paddingDelta;\n }\n\n static getStartDelta(scroller: Scroller): number { // calculate size before start index\n const { buffer, viewport: { offset } } = scroller;\n let startDelta = 0;\n if (offset) {\n startDelta += offset;\n }\n if (!buffer.defaultSize) {\n return startDelta;\n }\n for (let index = buffer.finiteAbsMinIndex; index < buffer.startIndex; index++) {\n startDelta += buffer.getSizeByIndex(index);\n }\n scroller.logger.log(() => [\n `start delta is ${startDelta}`, ...(offset ? [` (+${offset} offset)`] : [])\n ]);\n return startDelta;\n }\n\n static setFirstIndex(scroller: Scroller): void {\n const { state, buffer } = scroller;\n const { positions: { start }, first } = state.fetch;\n let firstIndex = buffer.startIndex;\n let firstIndexPosition = 0;\n if (state.cycle.innerLoop.isInitial) {\n scroller.logger.log('skipping fetch backward direction [initial loop]');\n } else if (!buffer.defaultSize) {\n scroller.logger.log('skipping fetch backward direction [no item size]');\n } else {\n let position = firstIndexPosition;\n let index = firstIndex;\n while (1) { // eslint-disable-line no-constant-condition\n if (start >= 0) {\n const size = buffer.getSizeByIndex(index);\n const diff = (position + size) - start;\n if (diff > 0) {\n firstIndex = index;\n firstIndexPosition = position;\n break;\n }\n position += size;\n index++;\n if (index < buffer.absMinIndex) {\n break;\n }\n }\n if (start < 0) {\n index--;\n if (index < buffer.absMinIndex) {\n break;\n }\n position -= buffer.getSizeByIndex(index);\n const diff = position - start;\n firstIndex = index;\n firstIndexPosition = position;\n if (diff <= 0) {\n break;\n }\n }\n }\n }\n first.index = first.indexBuffer = Math.max(firstIndex, buffer.absMinIndex);\n first.position = firstIndexPosition;\n }\n\n static setLastIndex(scroller: Scroller): void {\n const { state: { fetch, cycle }, buffer, settings } = scroller;\n const { firstVisible, positions: { relative, end }, first, last } = fetch;\n let lastIndex;\n if (!buffer.defaultSize) {\n // just to fetch forward bufferSize items if neither averageItemSize nor itemSize are present\n lastIndex = buffer.startIndex + settings.bufferSize - 1;\n scroller.logger.log('forcing fetch forward direction [no item size]');\n } else {\n let index = first.indexBuffer;\n let position = first.position;\n lastIndex = index;\n while (1) { // eslint-disable-line no-constant-condition\n lastIndex = index;\n const size = buffer.getSizeByIndex(index);\n position += size;\n if (isNaN(firstVisible.index) && position > relative) {\n firstVisible.index = index;\n if (!cycle.innerLoop.isInitial) {\n firstVisible.delta = position - size - relative;\n }\n }\n if (position >= end) {\n break;\n }\n if (index++ > buffer.absMaxIndex) {\n break;\n }\n }\n }\n last.index = last.indexBuffer = Math.min(lastIndex, buffer.absMaxIndex);\n }\n\n static skipBufferedItems(scroller: Scroller): void {\n const { buffer } = scroller;\n if (!buffer.size) {\n return;\n }\n const { fetch } = scroller.state;\n const firstIndex = fetch.first.index;\n const lastIndex = fetch.last.index;\n const packs: number[][] = [[]];\n let p = 0;\n for (let i = firstIndex; i <= lastIndex; i++) {\n if (!buffer.get(i)) {\n packs[p].push(i);\n } else if (packs[p].length) {\n packs[++p] = [];\n }\n }\n let pack = packs[0];\n if (packs[0].length && packs[1] && packs[1].length) {\n fetch.hasAnotherPack = true;\n // todo: need to look for biggest pack in visible area\n // todo: or think about merging two requests in a single Fetch process\n if (packs[1].length >= packs[0].length) {\n pack = packs[1];\n }\n }\n fetch.first.index = Math.max(pack[0], buffer.absMinIndex);\n fetch.last.index = Math.min(pack[pack.length - 1], buffer.absMaxIndex);\n if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) {\n scroller.logger.fetch('after Buffer flushing');\n }\n }\n\n static checkBufferGaps(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (!buffer.size) {\n return;\n }\n const fetchFirst = fetch.first.index;\n const bufferLast = buffer.lastIndex;\n if (fetchFirst > bufferLast) {\n fetch.first.index = fetch.first.indexBuffer = bufferLast + 1;\n }\n const bufferFirst = buffer.firstIndex;\n const fetchLast = fetch.last.index;\n if (fetchLast < bufferFirst) {\n fetch.last.index = fetch.last.indexBuffer = bufferFirst - 1;\n }\n if (fetch.first.index !== fetchFirst || fetch.last.index !== fetchLast) {\n scroller.logger.fetch('after Buffer filling (no clip case)');\n }\n }\n\n static checkFetchPackSize(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (!fetch.shouldFetch) {\n return;\n }\n const firstIndex = fetch.first.index;\n const lastIndex = fetch.last.index;\n const diff = scroller.settings.bufferSize - (lastIndex - firstIndex + 1);\n if (diff <= 0) {\n return;\n }\n if (!buffer.size || lastIndex > buffer.items[0].$index) { // forward\n const newLastIndex = Math.min(lastIndex + diff, buffer.absMaxIndex);\n if (newLastIndex > lastIndex) {\n fetch.last.index = fetch.last.indexBuffer = newLastIndex;\n }\n } else {\n const newFirstIndex = Math.max(firstIndex - diff, buffer.absMinIndex);\n if (newFirstIndex < firstIndex) {\n fetch.first.index = fetch.first.indexBuffer = newFirstIndex;\n }\n }\n if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) {\n scroller.logger.fetch('after bufferSize adjustment');\n PreFetch.skipBufferedItems(scroller);\n }\n }\n\n static setFetchDirection(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (fetch.last.index) {\n let direction = Direction.forward;\n if (buffer.size) {\n direction = fetch.last.index < buffer.items[0].$index ? Direction.backward : Direction.forward;\n }\n fetch.direction = direction;\n scroller.logger.log(() => `fetch direction is \"${direction}\"`);\n }\n }\n\n static getStatus(scroller: Scroller): ProcessStatus {\n const { cycle, fetch } = scroller.state;\n if (cycle.initiator === AdapterProcess.clip) {\n scroller.logger.log(() => `going to skip fetch due to \"${AdapterProcess.clip}\" process`);\n return ProcessStatus.next;\n }\n if (fetch.shouldFetch) {\n scroller.logger.log(() => `going to fetch ${fetch.count} items started from index ${fetch.index}`);\n return ProcessStatus.next;\n }\n return ProcessStatus.done;\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { ObservableLike } from '../interfaces/index';\n\ninterface Immediate {\n data: unknown[] | null;\n error: unknown | null;\n isError: boolean;\n}\n\ntype FetchGetResult = Immediate | Promise<unknown>;\n\ninterface FetchBox {\n success: (value: unknown[]) => void;\n fail: (value: unknown) => void;\n}\n\nexport default class Fetch extends BaseProcessFactory(CommonProcess.fetch) {\n\n static run(scroller: Scroller): void {\n const { workflow } = scroller;\n\n const box = {\n success: (data: unknown[]) => {\n scroller.logger.log(() =>\n `resolved ${data.length} items ` +\n `(index = ${scroller.state.fetch.index}, count = ${scroller.state.fetch.count})`\n );\n scroller.state.fetch.newItemsData = data;\n workflow.call({\n process: Fetch.process,\n status: ProcessStatus.next\n });\n },\n fail: (error: unknown) =>\n workflow.call({\n process: Fetch.process,\n status: ProcessStatus.error,\n payload: { error }\n })\n };\n\n const result = Fetch.get(scroller);\n Fetch.complete(scroller, box, result);\n }\n\n static complete(scroller: Scroller, box: FetchBox, result: FetchGetResult): void {\n if (Object.prototype.hasOwnProperty.call(result, 'data')) {\n const { data, error, isError } = result as Immediate;\n if (!isError) {\n box.success(data || []);\n } else {\n box.fail(error);\n }\n } else {\n const { state: { scrollState, fetch }, viewport } = scroller;\n if (scrollState.positionBeforeAsync === null) {\n scrollState.positionBeforeAsync = viewport.scrollPosition;\n }\n fetch.cancel = () => {\n box.success = () => null;\n box.fail = () => null;\n };\n (result as Promise<unknown[]>).then(\n (data) => box.success(data),\n (error) => box.fail(error)\n );\n }\n }\n\n static get(scroller: Scroller): FetchGetResult {\n const _get = scroller.datasource.get;\n const { index, count } = scroller.state.fetch;\n\n let immediateData, immediateError;\n let resolve: (value: unknown) => void, reject: (value: unknown) => void;\n\n const done = (data: unknown[]) => {\n if (!resolve) {\n immediateData = data || null;\n return;\n }\n resolve(data);\n };\n const fail = (error: unknown) => {\n if (!reject) {\n immediateError = error || null;\n return;\n }\n reject(error);\n };\n\n const getResult = _get(index, count, done, fail);\n\n if (getResult && typeof getResult === 'object' && getResult !== null) {\n if (typeof (getResult as PromiseLike<unknown>).then === 'function') {\n return getResult as Promise<unknown>;\n } else if (typeof (getResult as ObservableLike).subscribe === 'function') {\n const sub = (getResult as ObservableLike).subscribe(done, fail, () => {\n if (sub && typeof sub === 'object' && typeof sub.unsubscribe === 'function') {\n sub.unsubscribe();\n }\n });\n }\n }\n\n if (immediateData || immediateError) { // callback case or immediate observable\n return {\n data: immediateError ? null : (immediateData || []),\n error: immediateError,\n isError: !!immediateError\n };\n }\n\n return new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Item } from '../classes/item';\n\nexport default class PostFetch extends BaseProcessFactory(CommonProcess.postFetch) {\n\n static run(scroller: Scroller): void {\n const { workflow } = scroller;\n if (PostFetch.setItems(scroller)) {\n PostFetch.setBufferLimits(scroller);\n workflow.call({\n process: PostFetch.process,\n status: scroller.state.fetch.hasNewItems\n ? ProcessStatus.next\n : ProcessStatus.done\n });\n } else {\n workflow.call({\n process: PostFetch.process,\n status: ProcessStatus.error,\n payload: { error: 'Can\\'t set buffer items' }\n });\n }\n }\n\n static setBufferLimits(scroller: Scroller): void {\n const { buffer, state: { fetch, cycle: { innerLoop } } } = scroller;\n const { items, first: { index: first }, last: { index: last } } = fetch;\n if (!items.length) {\n if (last < buffer.minIndex || innerLoop.isInitial) {\n buffer.absMinIndex = buffer.minIndex;\n }\n if (first > buffer.maxIndex || innerLoop.isInitial) {\n buffer.absMaxIndex = buffer.maxIndex;\n }\n } else {\n const lastIndex = items.length - 1;\n if (first < items[0].$index) {\n buffer.absMinIndex = items[0].$index;\n }\n if (last > items[lastIndex].$index) {\n buffer.absMaxIndex = items[lastIndex].$index;\n }\n }\n }\n\n static setItems(scroller: Scroller): boolean {\n const { buffer, state: { fetch, cycle } } = scroller;\n const items = fetch.newItemsData;\n if (!items || !items.length) { // empty result\n return true;\n }\n // eof/bof case, need to shift fetch index if bof\n let fetchIndex = fetch.index;\n if (items.length < fetch.count) {\n if (cycle.innerLoop.isInitial) {\n // let's treat initial poor fetch as startIndex-bof\n fetchIndex = buffer.startIndex;\n } else if (fetch.first.index < buffer.minIndex) { // normal bof\n fetchIndex = buffer.minIndex - items.length;\n }\n }\n fetch.items = items.map((item, index: number) =>\n new Item(fetchIndex + index, item, scroller.routines)\n );\n return buffer.setItems(fetch.items);\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Item } from '../classes/item';\n\nexport default class Render extends BaseProcessFactory(CommonProcess.render) {\n\n static run(scroller: Scroller): void {\n const { workflow, state: { cycle, render, scrollState }, viewport } = scroller;\n scroller.logger.stat('before new items render');\n if (scrollState.positionBeforeAsync === null) {\n scrollState.positionBeforeAsync = viewport.scrollPosition;\n }\n render.renderTimer = setTimeout(() => {\n render.renderTimer = null;\n if (Render.doRender(scroller)) {\n workflow.call({\n process: Render.process,\n status: render.noSize ? ProcessStatus.done : ProcessStatus.next,\n payload: { process: cycle.initiator }\n });\n } else {\n workflow.call({\n process: Render.process,\n status: ProcessStatus.error,\n payload: { error: 'Can\\'t associate item with element' }\n });\n }\n }, 0);\n }\n\n static doRender(scroller: Scroller): boolean {\n const { state: { fetch, render }, viewport, buffer, logger } = scroller;\n render.positionBefore = viewport.scrollPosition;\n if (!fetch.isCheck) {\n render.sizeBefore = viewport.getScrollableSize();\n if (!fetch.items.every(item =>\n Render.processElement(scroller, item)\n )) {\n return false;\n }\n }\n buffer.checkDefaultSize();\n render.sizeAfter = viewport.getScrollableSize();\n logger.stat('after new items render');\n logger.log(() => render.noSize ? 'viewport size has not been changed' : void 0);\n return true;\n }\n\n static processElement(scroller: Scroller, item: Item): boolean {\n const { viewport, buffer } = scroller;\n const element = viewport.element.querySelector(`[data-sid=\"${item.nodeId}\"]`);\n if (!element) {\n return false;\n }\n item.element = element as HTMLElement;\n item.element.style.left = '';\n item.element.style.top = '';\n item.element.style.position = '';\n item.invisible = false;\n item.setSize(buffer.getSizeByIndex(item.$index));\n buffer.cacheItem(item);\n return true;\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\r\nimport { Scroller } from '../scroller';\r\n\r\nexport default class Adjust extends BaseProcessFactory(CommonProcess.adjust) {\r\n\r\n static run(scroller: Scroller): void {\r\n const { workflow, viewport, state: { scrollState } } = scroller;\r\n\r\n scrollState.positionBeforeAdjust = viewport.scrollPosition;\r\n Adjust.setPaddings(scroller);\r\n scrollState.positionAfterAdjust = viewport.scrollPosition;\r\n\r\n // scroll position adjustments\r\n const position = Adjust.calculatePosition(scroller);\r\n\r\n // set new position using animation frame\r\n Adjust.setPosition(scroller, position, () =>\r\n workflow.call({\r\n process: Adjust.process,\r\n status: ProcessStatus.done\r\n })\r\n );\r\n }\r\n\r\n static setPaddings(scroller: Scroller): void {\r\n const { viewport, buffer, settings: { inverse }, state: { fetch } } = scroller;\r\n const firstItem = buffer.getFirstVisibleItem();\r\n const lastItem = buffer.getLastVisibleItem();\r\n let first, last;\r\n if (firstItem && lastItem) {\r\n first = firstItem.$index;\r\n last = lastItem.$index;\r\n } else {\r\n first = !isNaN(fetch.firstVisible.index) ? fetch.firstVisible.index : buffer.startIndex;\r\n last = first - 1;\r\n }\r\n const { forward, backward } = viewport.paddings;\r\n let index, bwdSize = 0, fwdSize = 0;\r\n\r\n // new backward and forward paddings size\r\n for (index = buffer.finiteAbsMinIndex; index < first; index++) {\r\n bwdSize += buffer.getSizeByIndex(index);\r\n }\r\n for (index = last + 1; index <= buffer.finiteAbsMaxIndex; index++) {\r\n fwdSize += buffer.getSizeByIndex(index);\r\n }\r\n\r\n // lack of items case\r\n const bufferSize = viewport.getScrollableSize() - forward.size - backward.size;\r\n const viewportSizeDiff = viewport.getSize() - (bwdSize + bufferSize + fwdSize);\r\n if (viewportSizeDiff > 0) {\r\n if (inverse) {\r\n bwdSize += viewportSizeDiff;\r\n } else {\r\n fwdSize += viewportSizeDiff;\r\n }\r\n scroller.logger.log(() =>\r\n inverse ? 'backward' : 'forward' + ` padding will be increased by ${viewportSizeDiff} to fill the viewport`\r\n );\r\n }\r\n\r\n backward.size = bwdSize;\r\n forward.size = fwdSize;\r\n\r\n scroller.logger.stat('after paddings adjustments');\r\n }\r\n\r\n static calculatePosition(scroller: Scroller): number {\r\n const { viewport, buffer, state: { fetch, render, scrollState } } = scroller;\r\n let position = viewport.paddings.backward.size;\r\n\r\n // increase the position to meet the expectation of the first visible item\r\n if (!isNaN(fetch.firstVisible.index) && !isNaN(buffer.firstIndex)) {\r\n scroller.logger.log(`first index = ${fetch.firstVisible.index}, delta = ${fetch.firstVisible.delta}`);\r\n const shouldCheckPreSizeExpectation = fetch.shouldCheckPreSizeExpectation(buffer.lastIndex);\r\n buffer.items.forEach(item => {\r\n // 1) shift of the buffered items before the first visible item\r\n if (item.$index < fetch.firstVisible.index) {\r\n position += item.size;\r\n return;\r\n }\r\n // 2) delta of the first visible item\r\n if (item.$index === fetch.firstVisible.index && fetch.firstVisible.delta) {\r\n position -= fetch.firstVisible.delta;\r\n }\r\n // 3) difference between expected and real sizes of fetched items after the first visible\r\n if (shouldCheckPreSizeExpectation && item.preSize && fetch.items.includes(item)) {\r\n position += item.size - item.preSize;\r\n }\r\n });\r\n }\r\n\r\n // slow fetch/render case\r\n if (scrollState.positionBeforeAsync !== null) {\r\n const diff = render.positionBefore - scrollState.positionBeforeAsync;\r\n if (diff !== 0) {\r\n scroller.logger.log(`shift position due to fetch-render difference (${diff})`);\r\n position += diff;\r\n }\r\n }\r\n\r\n // increase the position due to viewport's offset\r\n if (viewport.offset > 0 && (position || fetch.positions.before)) {\r\n position += viewport.offset;\r\n }\r\n\r\n return Math.round(position);\r\n }\r\n\r\n static setPosition(scroller: Scroller, position: number, done: () => void): void {\r\n const { state: { scrollState }, viewport } = scroller;\r\n if (!scrollState.hasPositionChanged(position)) {\r\n return done();\r\n }\r\n scrollState.syntheticPosition = position;\r\n scrollState.syntheticFulfill = false;\r\n\r\n scrollState.animationFrameId = requestAnimationFrame(() => {\r\n const inertiaDiff = (scrollState.positionAfterAdjust as number) - viewport.scrollPosition;\r\n let diffLog = '';\r\n if (inertiaDiff > 0) {\r\n position -= inertiaDiff;\r\n scrollState.syntheticPosition = position;\r\n diffLog = ` (-${inertiaDiff})`;\r\n }\r\n scrollState.syntheticFulfill = true;\r\n viewport.scrollPosition = position;\r\n scroller.logger.stat('after scroll adjustment' + diffLog);\r\n done();\r\n });\r\n }\r\n\r\n}\r\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\n\nexport default class PreClip extends BaseProcessFactory(CommonProcess.preClip) {\n\n static run(scroller: Scroller): void {\n PreClip.prepareClip(scroller);\n\n scroller.workflow.call({\n process: PreClip.process,\n status: ProcessStatus.next,\n payload: {\n doClip: scroller.state.clip.doClip\n }\n });\n }\n\n static prepareClip(scroller: Scroller): void {\n const { state: { fetch, clip } } = scroller;\n if (PreClip.shouldNotClip(scroller)) {\n return;\n }\n const firstIndex = fetch.first.indexBuffer;\n const lastIndex = fetch.last.indexBuffer;\n scroller.logger.log(() =>\n `looking for ${fetch.direction ? 'anti-' + fetch.direction + ' ' : ''}items ` +\n `that are out of [${firstIndex}..${lastIndex}] range`);\n if (PreClip.isBackward(scroller, firstIndex)) {\n PreClip.prepareClipByDirection(scroller, Direction.backward, firstIndex);\n }\n if (PreClip.isForward(scroller, lastIndex)) {\n PreClip.prepareClipByDirection(scroller, Direction.forward, lastIndex);\n }\n if (!clip.doClip) {\n scroller.logger.log('skipping clip [no items to clip]');\n }\n return;\n }\n\n static shouldNotClip(scroller: Scroller): boolean {\n const { settings, buffer, state } = scroller;\n if (settings.infinite && !state.clip.force) {\n scroller.logger.log('skipping clip [infinite mode]');\n return true;\n }\n if (!buffer.size) {\n scroller.logger.log('skipping clip [empty buffer]');\n return true;\n }\n if (state.cycle.isInitial) {\n scroller.logger.log('skipping clip [initial cycle]');\n return true;\n }\n return false;\n }\n\n static isBackward(scroller: Scroller, firstIndex: number): boolean {\n const { buffer, state: { clip, fetch } } = scroller;\n if (clip.force) {\n return clip.forceBackward;\n }\n if (fetch.direction !== Direction.backward) {\n if (firstIndex - 1 >= buffer.absMinIndex) {\n return true;\n }\n }\n return false;\n }\n\n static isForward(scroller: Scroller, lastIndex: number): boolean {\n const { buffer, state: { clip, fetch } } = scroller;\n if (clip.force) {\n return clip.forceForward;\n }\n if (fetch.direction !== Direction.forward) {\n if (lastIndex + 1 <= buffer.absMaxIndex) {\n return true;\n }\n }\n return false;\n }\n\n static prepareClipByDirection(scroller: Scroller, direction: Direction, edgeIndex: number): void {\n const forward = direction === Direction.forward;\n scroller.buffer.items.forEach(item => {\n if (\n (!forward && item.$index < edgeIndex) ||\n (forward && item.$index > edgeIndex)\n ) {\n item.toRemove = true;\n item.removeDirection = direction;\n scroller.state.clip.doClip = true;\n }\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\r\nimport { Scroller } from '../scroller';\r\nimport { Direction } from '../inputs/index';\r\n\r\nexport default class Clip extends BaseProcessFactory(CommonProcess.clip) {\r\n\r\n static run(scroller: Scroller): void {\r\n const { workflow } = scroller;\r\n\r\n Clip.doClip(scroller);\r\n\r\n workflow.call({\r\n process: Clip.process,\r\n status: ProcessStatus.next\r\n });\r\n }\r\n\r\n static doClip(scroller: Scroller): void {\r\n const { buffer, viewport: { paddings }, state: { clip }, logger } = scroller;\r\n const size = { [Direction.backward]: 0, [Direction.forward]: 0 };\r\n\r\n logger.stat(`before clip (${++clip.callCount})`);\r\n\r\n const itemsToRemove = buffer.items.filter(item => {\r\n if (!item.toRemove) {\r\n return false;\r\n }\r\n item.hide();\r\n size[item.removeDirection] += item.size;\r\n return true;\r\n });\r\n\r\n if (itemsToRemove.length) {\r\n if (size[Direction.backward]) {\r\n paddings.byDirection(Direction.backward).size += size[Direction.backward];\r\n }\r\n if (size[Direction.forward]) {\r\n paddings.byDirection(Direction.forward).size += size[Direction.forward];\r\n }\r\n if (scroller.settings.onBeforeClip) {\r\n scroller.settings.onBeforeClip(itemsToRemove.map(item => item.get()));\r\n }\r\n }\r\n\r\n buffer.clip();\r\n\r\n logger.log(() => {\r\n const list = itemsToRemove.map(({ $index }) => $index);\r\n return list.length\r\n ? [\r\n `clipped ${list.length} item(s) from Buffer` +\r\n (size.backward ? `, +${size.backward} fwd px` : '') +\r\n (size.forward ? `, +${size.forward} bwd px` : '') +\r\n `, range: [${list[0]}..${list[list.length - 1]}]`\r\n ]\r\n : 'clipped 0 items from Buffer';\r\n });\r\n\r\n logger.stat('after clip');\r\n }\r\n\r\n}\r\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\nimport { EMPTY_ITEM } from '../classes/adapter/props';\nimport { ScrollerWorkflow } from '../interfaces/index';\n\nconst isInterrupted = ({ call }: ScrollerWorkflow): boolean => !!call.interrupted;\n\nexport default class End extends BaseProcessFactory(CommonProcess.end) {\n\n static run(scroller: Scroller, { error }: { error?: unknown } = {}): void {\n const { workflow, state: { cycle: { interrupter } } } = scroller;\n\n if (!error && !interrupter) {\n // set out params accessible via Adapter\n End.calculateParams(scroller, workflow);\n }\n\n // explicit interruption for we don't want to go through the inner loop finalizing\n if (isInterrupted(workflow)) {\n workflow.call({ process: End.process, status: ProcessStatus.done });\n return;\n }\n\n const next = End.finalizeInnerLoop(scroller, error);\n\n workflow.call({\n process: End.process,\n status: next ? ProcessStatus.next : ProcessStatus.done,\n payload: { ...(interrupter ? { process: interrupter } : {}) }\n });\n }\n\n static calculateParams(scroller: Scroller, workflow: ScrollerWorkflow): void {\n const { adapter, viewport, buffer: { items } } = scroller;\n\n if (adapter.wanted.firstVisible) {\n const { item } = viewport.getEdgeVisibleItem(items, Direction.backward);\n if (!item || item.element !== adapter.firstVisible.element) {\n adapter.firstVisible = item ? item.get() : EMPTY_ITEM;\n }\n }\n\n // the workflow can be interrupter on firstVisible change\n if (adapter.wanted.lastVisible && !isInterrupted(workflow)) {\n const { item } = viewport.getEdgeVisibleItem(items, Direction.forward);\n if (!item || item.element !== adapter.lastVisible.element) {\n adapter.lastVisible = item ? item.get() : EMPTY_ITEM;\n }\n }\n }\n\n static finalizeInnerLoop(scroller: Scroller, error: unknown): boolean {\n const { state, state: { cycle, clip, fetch } } = scroller;\n const next = !!cycle.interrupter || (error ? false : End.getNext(scroller));\n cycle.innerLoop.isInitial = false;\n fetch.stopSimulate();\n clip.reset(true);\n state.endInnerLoop();\n return next;\n }\n\n static getNext(scroller: Scroller): boolean {\n const { state: { fetch, render } } = scroller;\n if (fetch.simulate && fetch.isCheck && !render.noSize) { // Adapter.check\n return true;\n }\n if (fetch.simulate && fetch.doRemove) { // Adapter.remove or Adapter.update with clip\n return true;\n }\n if ( // common inner loop (App start, Scroll, Adapter.clip) accompanied by fetch\n !fetch.simulate && ((fetch.hasNewItems && !render.noSize) || fetch.hasAnotherPack)\n ) {\n return true;\n }\n return false;\n }\n\n}\n","import { Scroller } from '../scroller';\nimport { CommonProcess, AdapterProcess, ProcessStatus as Status } from '../processes/index';\nimport { IPackages, ProcessSubject } from '../interfaces/index';\n\ntype LogType = [unknown?, ...unknown[]];\n\nexport class Logger {\n\n readonly debug: boolean;\n readonly immediateLog: boolean;\n readonly logTime: boolean;\n readonly getTime: () => string;\n readonly getStat: () => string;\n readonly getFetchRange: () => string;\n readonly getWorkflowCycleData: () => string;\n readonly getLoopId: () => string;\n readonly getLoopIdNext: () => string;\n readonly getScrollPosition: (element: HTMLElement) => number;\n private logs: unknown[][] = [];\n\n constructor(scroller: Scroller, packageInfo: IPackages, adapter?: { id: number }) {\n const { settings } = scroller;\n this.debug = settings.debug;\n this.immediateLog = settings.immediateLog;\n this.logTime = settings.logTime;\n this.getTime = (): string =>\n scroller.state && ` // time: ${scroller.state.time}`;\n this.getStat = (): string => {\n const { buffer, viewport } = scroller;\n const first = buffer.getFirstVisibleItem();\n const last = buffer.getLastVisibleItem();\n return 'pos: ' + viewport.scrollPosition + ', ' +\n 'size: ' + viewport.getScrollableSize() + ', ' +\n 'bwd_p: ' + viewport.paddings.backward.size + ', ' +\n 'fwd_p: ' + viewport.paddings.forward.size + ', ' +\n 'default: ' + (buffer.defaultSize || 'no') + ', ' +\n 'items: ' + buffer.getVisibleItemsCount() + ', ' +\n 'range: ' + (first && last ? `[${first.$index}..${last.$index}]` : 'no');\n };\n this.getFetchRange = (): string => {\n const { first: { index: first }, last: { index: last } } = scroller.state.fetch;\n return !Number.isNaN(first) && !Number.isNaN(last)\n ? `[${first}..${last}]`\n : 'no';\n };\n this.getLoopId = (): string => scroller.state.cycle.loopId;\n this.getLoopIdNext = (): string => scroller.state.cycle.loopIdNext;\n this.getWorkflowCycleData = (): string =>\n `${settings.instanceIndex}-${scroller.state.cycle.count}`;\n this.getScrollPosition = (element: HTMLElement) => scroller.routines.getScrollPosition(element);\n this.log(() =>\n 'vscroll Workflow has been started, ' +\n `core: ${packageInfo.core.name} v${packageInfo.core.version}, ` +\n `consumer: ${packageInfo.consumer.name} v${packageInfo.consumer.version}, ` +\n `scroller instance: ${settings.instanceIndex}, adapter ` +\n (!adapter ? 'is not instantiated' : `instance: ${adapter.id}`)\n );\n }\n\n object(str: string, obj: unknown, stringify?: boolean): void {\n this.log(() => [\n str,\n stringify\n ? JSON.stringify(obj, (k, v) => {\n if (Number.isNaN(v)) {\n return 'NaN';\n }\n if (v === Infinity) {\n return 'Infinity';\n }\n if (v === -Infinity) {\n return '-Infinity';\n }\n if (v instanceof Element) {\n return 'HTMLElement';\n }\n if (v instanceof HTMLDocument) {\n return 'HTMLDocument';\n }\n if (typeof v === 'function') {\n return 'Function';\n }\n return v;\n })\n .replace(/\"/g, '')\n .replace(/(\\{|:|,)/g, '$1 ')\n .replace(/(\\})/g, ' $1')\n : obj\n ]);\n }\n\n stat(str?: string): void {\n if (this.debug) {\n const logStyles = [\n 'color: #888; border: dashed #888 0; border-bottom-width: 0px',\n 'color: #000; border-width: 0'\n ];\n this.log(() => ['%cstat' + (str ? ` ${str}` : '') + ',%c ' + this.getStat(), ...logStyles]);\n }\n }\n\n fetch(str?: string): void {\n if (this.debug) {\n const _text = 'fetch interval' + (str ? ` ${str}` : '');\n const logStyles = ['color: #888', 'color: #000'];\n this.log(() => [`%c${_text}: %c${this.getFetchRange()}`, ...logStyles]);\n }\n }\n\n prepareForLog(data: unknown): unknown {\n return data instanceof Event && data.target\n ? this.getScrollPosition(data.target as HTMLElement)\n : data;\n }\n\n logProcess(data: ProcessSubject): void {\n if (!this.debug) {\n return;\n }\n const { process, status, payload } = data;\n\n // inner loop start-end log\n const loopLog: string[] = [];\n if (\n process === CommonProcess.init && status === Status.next\n ) {\n loopLog.push(`%c---=== loop ${this.getLoopIdNext()} start`);\n } else if (\n process === CommonProcess.end\n ) {\n loopLog.push(`%c---=== loop ${this.getLoopId()} done`);\n const parent = payload && payload.process;\n if (status === Status.next && (parent !== AdapterProcess.reset && parent !== AdapterProcess.reload)) {\n loopLog[0] += `, loop ${this.getLoopIdNext()} start`;\n }\n }\n if (loopLog.length) {\n this.log(() => [...loopLog, 'color: #006600;']);\n }\n }\n\n logCycle(start = true): void {\n const logData = this.getWorkflowCycleData();\n const border = start ? '1px 0 0 1px' : '0 0 1px 1px';\n const logStyles = `color: #0000aa; border: solid #555 1px; border-width: ${border}; margin-left: -2px`;\n this.log(() => [`%c ~~~ WF Cycle ${logData} ${start ? 'STARTED' : 'FINALIZED'} ~~~ `, logStyles]);\n }\n\n logError(str: string): void {\n if (this.debug) {\n const logStyles = ['color: #a00;', 'color: #000'];\n this.log(() => ['error:%c' + (str ? ` ${str}` : '') + `%c (loop ${this.getLoopIdNext()})`, ...logStyles]);\n }\n }\n\n logAdapterMethod = (methodName: string, args?: unknown, add?: string): void => {\n if (!this.debug) {\n return;\n }\n const params = (\n args === void 0 ? [] : (Array.isArray(args) ? args : [args])\n )\n .map((arg: unknown) => {\n if (typeof arg === 'function') {\n return 'func';\n } else if (typeof arg !== 'object' || !arg) {\n return arg;\n } else if (Array.isArray(arg)) {\n return `[of ${arg.length}]`;\n }\n return '{ ' + Object.keys(arg).join(', ') + ' }';\n })\n .join(', ');\n this.log(`adapter: ${methodName}(${params || ''})${add || ''}`);\n }\n\n log(...args: any[]): void {\n if (this.debug) {\n if (typeof args[0] === 'function') {\n args = args[0]();\n if (!Array.isArray(args)) {\n args = [args];\n }\n }\n if (args.every(item => item === void 0)) {\n return;\n }\n if (this.logTime) {\n args = [...args, this.getTime()];\n }\n args = args.map((arg: unknown) => this.prepareForLog(arg));\n if (this.immediateLog) {\n console.log.apply(this, args as LogType);\n } else {\n this.logs.push(args);\n }\n }\n }\n\n // logNow(...args: any[]) {\n // const immediateLog = this.immediateLog;\n // const debug = this.debug;\n // (this as any).debug = true;\n // (this as any).immediateLog = true;\n // this.log.apply(this, args);\n // (this as any).debug = debug;\n // (this as any).immediateLog = immediateLog;\n // }\n\n logForce(...args: unknown[]): void {\n if (this.debug) {\n if (!this.immediateLog && this.logs.length) {\n this.logs.forEach(logArgs => console.log.apply(this, logArgs));\n this.logs = [];\n }\n if (args.length) {\n console.log.apply(this, args as LogType);\n }\n }\n }\n}\n","import { Settings } from './settings';\nimport { Direction } from '../inputs/index';\n\nexport class Routines {\n\n readonly horizontal: boolean;\n readonly window: boolean;\n\n constructor(settings: Settings) {\n this.horizontal = settings.horizontal;\n this.window = settings.windowViewport;\n }\n\n checkElement(element: HTMLElement): void {\n if (!element) {\n throw new Error('HTML element is not defined');\n }\n }\n\n getScrollPosition(element: HTMLElement): number {\n if (this.window) {\n return window.pageYOffset;\n }\n this.checkElement(element);\n return element[this.horizontal ? 'scrollLeft' : 'scrollTop'];\n }\n\n setScrollPosition(element: HTMLElement, value: number): void {\n value = Math.max(0, value);\n if (this.window) {\n if (this.horizontal) {\n window.scrollTo(value, window.scrollY);\n } else {\n window.scrollTo(window.scrollX, value);\n }\n return;\n }\n this.checkElement(element);\n element[this.horizontal ? 'scrollLeft' : 'scrollTop'] = value;\n }\n\n getParams(element: HTMLElement, doNotBind?: boolean): DOMRect {\n this.checkElement(element);\n if (this.window && doNotBind) {\n const { clientWidth, clientHeight, clientLeft, clientTop } = element;\n return {\n 'height': clientHeight,\n 'width': clientWidth,\n 'top': clientTop,\n 'bottom': clientTop + clientHeight,\n 'left': clientLeft,\n 'right': clientLeft + clientWidth,\n 'x': clientLeft,\n 'y': clientTop,\n 'toJSON': () => null,\n };\n }\n return element.getBoundingClientRect();\n }\n\n getSize(element: HTMLElement, doNotBind?: boolean): number {\n return this.getParams(element, doNotBind)[this.horizontal ? 'width' : 'height'];\n }\n\n getSizeStyle(element: HTMLElement): number {\n this.checkElement(element);\n const size = element.style[this.horizontal ? 'width' : 'height'];\n return parseFloat(size as string) || 0;\n }\n\n setSizeStyle(element: HTMLElement, value: number): void {\n this.checkElement(element);\n value = Math.max(0, Math.round(value));\n element.style[this.horizontal ? 'width' : 'height'] = `${value}px`;\n }\n\n getEdge(element: HTMLElement, direction: Direction, doNotBind?: boolean): number {\n const params = this.getParams(element, doNotBind);\n const isFwd = direction === Direction.forward;\n return params[isFwd ? (this.horizontal ? 'right' : 'bottom') : (this.horizontal ? 'left' : 'top')];\n }\n\n getEdge2(element: HTMLElement, direction: Direction, relativeElement: HTMLElement, opposite: boolean): number {\n // vertical only ?\n return element.offsetTop - (relativeElement ? relativeElement.scrollTop : 0) +\n (direction === (!opposite ? Direction.forward : Direction.backward) ? this.getSize(element) : 0);\n }\n\n hideElement(element: HTMLElement): void {\n this.checkElement(element);\n element.style.display = 'none';\n }\n\n getOffset(element: HTMLElement): number {\n this.checkElement(element);\n return (this.horizontal ? element.offsetLeft : element.offsetTop) || 0;\n }\n\n scrollTo(element: HTMLElement, argument?: boolean | ScrollIntoViewOptions): void {\n this.checkElement(element);\n element.scrollIntoView(argument);\n }\n\n}\n","import { Routines } from './domRoutines';\r\nimport { Settings } from './settings';\r\nimport { Direction } from '../inputs/index';\r\n\r\nexport class Padding {\r\n\r\n element: HTMLElement;\r\n direction: Direction;\r\n routines: Routines;\r\n\r\n constructor(element: HTMLElement, direction: Direction, routines: Routines) {\r\n this.element = element.querySelector(`[data-padding-${direction}]`) as HTMLElement;\r\n this.direction = direction;\r\n this.routines = routines;\r\n }\r\n\r\n reset(size?: number): void {\r\n this.size = size || 0;\r\n }\r\n\r\n get size(): number {\r\n return this.routines.getSizeStyle(this.element);\r\n }\r\n\r\n set size(value: number) {\r\n this.routines.setSizeStyle(this.element, value);\r\n }\r\n\r\n}\r\n\r\nexport class Paddings {\r\n settings: Settings;\r\n forward: Padding;\r\n backward: Padding;\r\n\r\n constructor(element: HTMLElement, routines: Routines, settings: Settings) {\r\n this.settings = settings;\r\n this.forward = new Padding(element, Direction.forward, routines);\r\n this.backward = new Padding(element, Direction.backward, routines);\r\n }\r\n\r\n byDirection(direction: Direction, opposite?: boolean): Padding {\r\n return direction === Direction.backward\r\n ? (opposite ? this.forward : this.backward)\r\n : (opposite ? this.backward : this.forward);\r\n }\r\n\r\n reset(viewportSize: number, startIndex: number, offset: number): void {\r\n const positive = this.getPositiveSize(startIndex, viewportSize, offset);\r\n const negative = this.getNegativeSize(startIndex);\r\n if (this.settings.inverse) {\r\n this.forward.reset(negative);\r\n this.backward.reset(positive);\r\n const diff = viewportSize - this.backward.size - offset;\r\n if (diff > 0) {\r\n this.backward.size += diff;\r\n this.forward.size -= diff;\r\n }\r\n } else {\r\n this.forward.reset(positive);\r\n this.backward.reset(negative);\r\n const diff = viewportSize - this.forward.size - offset;\r\n if (diff > 0) {\r\n this.backward.size -= diff;\r\n this.forward.size += diff;\r\n }\r\n }\r\n\r\n }\r\n\r\n getPositiveSize(startIndex: number, viewportSize: number, offset: number): number {\r\n const { settings } = this;\r\n let positiveSize = viewportSize;\r\n if (isFinite(settings.maxIndex)) {\r\n positiveSize = (settings.maxIndex - startIndex + 1) * settings.itemSize;\r\n }\r\n if (offset) {\r\n positiveSize = Math.max(positiveSize - offset, 0);\r\n }\r\n return positiveSize;\r\n }\r\n\r\n getNegativeSize(startIndex: number): number {\r\n const { settings } = this;\r\n let negativeSize = 0;\r\n if (isFinite(settings.minIndex)) {\r\n negativeSize = (startIndex - settings.minIndex) * settings.itemSize;\r\n }\r\n return negativeSize;\r\n }\r\n}\r\n","import { Paddings } from './paddings';\nimport { Settings } from './settings';\nimport { Routines } from './domRoutines';\nimport { Item } from './item';\nimport { State } from './state';\nimport { Logger } from './logger';\nimport { Direction } from '../inputs/index';\n\nexport class Viewport {\n\n offset: number;\n paddings: Paddings;\n\n readonly element: HTMLElement;\n readonly settings: Settings;\n readonly routines: Routines;\n readonly state: State;\n readonly logger: Logger;\n\n readonly hostElement: HTMLElement;\n readonly scrollEventReceiver: HTMLElement | Window;\n\n private disabled: boolean;\n\n constructor(element: HTMLElement, settings: Settings, routines: Routines, state: State, logger: Logger) {\n this.element = element;\n this.settings = settings;\n this.routines = routines;\n this.state = state;\n this.logger = logger;\n this.disabled = false;\n\n if (settings.windowViewport) {\n this.hostElement = document.documentElement as HTMLElement;\n this.scrollEventReceiver = window;\n } else {\n this.hostElement = settings.viewport || this.element.parentElement as HTMLElement;\n this.scrollEventReceiver = this.hostElement;\n }\n\n this.paddings = new Paddings(this.element, this.routines, settings);\n\n if (settings.windowViewport && 'scrollRestoration' in history) {\n history.scrollRestoration = 'manual';\n }\n\n if (settings.dismissOverflowAnchor) {\n this.hostElement.style.overflowAnchor = 'none';\n }\n }\n\n reset(startIndex: number): void {\n this.setOffset();\n this.paddings.reset(this.getSize(), startIndex, this.offset);\n this.scrollPosition = this.paddings.backward.size || 0;\n this.state.scrollState.reset();\n }\n\n setPosition(value: number): number {\n const oldPosition = this.scrollPosition;\n if (oldPosition === value) {\n this.logger.log(() => ['setting scroll position at', value, '[cancelled]']);\n return value;\n }\n this.routines.setScrollPosition(this.hostElement, value);\n const position = this.scrollPosition;\n this.logger.log(() => [\n 'setting scroll position at', position, ...(position !== value ? [`(${value})`] : [])\n ]);\n return position;\n }\n\n get scrollPosition(): number {\n return this.routines.getScrollPosition(this.hostElement);\n }\n\n set scrollPosition(value: number) {\n this.setPosition(value);\n }\n\n disableScrollForOneLoop(): void {\n if (this.disabled) {\n return;\n }\n const { style } = this.hostElement;\n if (style.overflowY === 'hidden') {\n return;\n }\n this.disabled = true;\n const overflow = style.overflowY;\n setTimeout(() => {\n this.disabled = false;\n style.overflowY = overflow;\n });\n style.overflowY = 'hidden';\n }\n\n getSize(): number {\n return this.routines.getSize(this.hostElement, true);\n }\n\n getScrollableSize(): number {\n return this.routines.getSize(this.element);\n }\n\n getBufferPadding(): number {\n return this.getSize() * this.settings.padding;\n }\n\n getEdge(direction: Direction): number {\n return this.routines.getEdge(this.hostElement, direction, true);\n }\n\n setOffset(): void {\n this.offset = this.routines.getOffset(this.element);\n if (!this.settings.windowViewport) {\n this.offset -= this.routines.getOffset(this.hostElement);\n }\n }\n\n getEdgeVisibleItem(items: Item[], direction: Direction): { item?: Item, index: number, diff: number } {\n const bwd = direction === Direction.backward;\n const opposite = bwd ? Direction.forward : Direction.backward;\n const viewportEdge = this.getEdge(direction);\n let item, diff = 0;\n for (\n let i = bwd ? 0 : items.length - 1;\n bwd ? i <= items.length - 1 : i >= 0;\n i += bwd ? 1 : -1\n ) {\n const itemEdge = this.routines.getEdge(items[i].element, opposite);\n diff = itemEdge - viewportEdge;\n if (bwd && diff > 0 || !bwd && diff < 0) {\n item = items[i];\n break;\n }\n }\n return { item, index: item ? item.$index : NaN, diff };\n }\n\n}\n","import { SizeStrategy } from '../../inputs/index';\n\ninterface ItemSize {\n size: number;\n newSize?: number;\n}\n\nexport class SizesRecalculation {\n newItems: ItemSize[];\n oldItems: ItemSize[];\n removed: ItemSize[];\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.newItems = [];\n this.oldItems = [];\n this.removed = [];\n }\n}\n\nexport class DefaultSize {\n private readonly itemSize: number;\n private readonly sizeStrategy: SizeStrategy;\n private sizeMap: Map<number, number>;\n private recalculation: SizesRecalculation;\n\n private constantSize: number;\n private frequentSize: number;\n private averageSize: number;\n private averageSizeFloat: number;\n\n constructor(itemSize: number, sizeStrategy: SizeStrategy) {\n this.itemSize = itemSize;\n this.sizeStrategy = sizeStrategy;\n this.sizeMap = new Map<number, number>();\n this.recalculation = new SizesRecalculation();\n }\n\n reset(force: boolean): void {\n if (force) {\n this.constantSize = this.itemSize;\n this.frequentSize = this.itemSize;\n this.averageSize = this.itemSize;\n this.averageSizeFloat = this.itemSize;\n this.sizeMap.clear();\n }\n this.recalculation.reset();\n }\n\n get(): number {\n switch (this.sizeStrategy) {\n case SizeStrategy.Average:\n return this.averageSize;\n case SizeStrategy.Frequent:\n return this.frequentSize;\n default:\n return this.constantSize;\n }\n }\n\n private recalculateAverageSize(cacheSize: number): void {\n const { oldItems, newItems, removed } = this.recalculation;\n if (oldItems.length) {\n const oldSize = oldItems.reduce((acc, item) => acc + item.size, 0);\n const newSize = oldItems.reduce((acc, item) => acc + (item.newSize as number), 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = averageSize - (oldSize - newSize) / (cacheSize - newItems.length);\n }\n if (newItems.length) {\n const newSize = newItems.reduce((acc, item) => acc + item.size, 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = ((cacheSize - newItems.length) * averageSize + newSize) / cacheSize;\n }\n if (removed.length) {\n const removedSize = removed.reduce((acc, item) => acc + item.size, 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = ((cacheSize + removed.length) * averageSize - removedSize) / cacheSize;\n }\n this.averageSize = Math.round(this.averageSizeFloat);\n }\n\n private recalculateFrequentSize(): void {\n const { oldItems, newItems, removed } = this.recalculation;\n const oldFrequentSizeCount = this.sizeMap.get(this.frequentSize);\n if (newItems.length) {\n newItems.forEach(({ size }) => this.sizeMap.set(size, (this.sizeMap.get(size) || 0) + 1));\n }\n if (oldItems.length) {\n oldItems.forEach(({ size }) => this.sizeMap.set(size, Math.max((this.sizeMap.get(size) || 0) - 1, 0)));\n oldItems.forEach(({ newSize: s }) => this.sizeMap.set(s as number, (this.sizeMap.get(s as number) || 0) + 1));\n }\n if (removed.length) {\n removed.forEach(({ size }) => this.sizeMap.set(size, Math.max((this.sizeMap.get(size) || 0) - 1, 0)));\n }\n const sorted = [...this.sizeMap.entries()].sort((a, b) => b[1] - a[1]);\n const mostFrequentCount = sorted[0][1];\n const listEqual = sorted.filter(i => i[1] === mostFrequentCount);\n if (listEqual.length > 1 && listEqual.find(i => i[0] === oldFrequentSizeCount)) {\n // if there are more than 1 most frequent sizes, but the old one is present\n return;\n }\n this.frequentSize = sorted[0][0];\n }\n\n recalculate(cacheSize: number): boolean {\n if (this.sizeStrategy === SizeStrategy.Constant) {\n return false;\n }\n const { oldItems, newItems, removed } = this.recalculation;\n if (!oldItems.length && !newItems.length && !removed.length) {\n return false;\n }\n const oldValue = this.get();\n if (!cacheSize) {\n this.reset(true);\n } else {\n if (this.sizeStrategy === SizeStrategy.Average) {\n this.recalculateAverageSize(cacheSize);\n } else {\n this.recalculateFrequentSize();\n }\n this.recalculation.reset();\n }\n return this.get() !== oldValue;\n }\n\n setExisted(oldSize: number, newSize: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.oldItems.push({\n size: oldSize,\n newSize\n });\n }\n }\n\n setNew(size: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.newItems.push({ size });\n } else {\n if (!this.constantSize) {\n this.constantSize = size;\n }\n }\n }\n\n setRemoved(size: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.removed.push({ size });\n }\n }\n}\n","import { DefaultSize } from './defaultSize';\nimport { Item } from '../item';\nimport { Settings } from '../settings';\nimport { Logger } from '../logger';\nimport { SizeStrategy, Direction } from '../../inputs/index';\n\ninterface ItemToCache<Data> {\n $index: number;\n data: Data;\n size?: number;\n}\n\ninterface ItemUpdate {\n $index: number;\n size: number;\n toRemove?: boolean;\n}\n\nexport class ItemCache<Data = unknown> {\n $index: number;\n data: Data | null;\n size?: number;\n position: number;\n\n constructor(item: ItemToCache<Data>, saveData: boolean) {\n this.$index = item.$index;\n this.data = saveData ? item.data : null;\n this.size = item.size;\n }\n\n changeIndex(value: number): void {\n this.$index = value;\n }\n}\n\nexport class Cache<Data = unknown> {\n minIndex: number;\n maxIndex: number;\n\n readonly itemSize: number;\n readonly saveData: boolean;\n readonly cacheOnReload: boolean;\n readonly sizeStrategy: SizeStrategy;\n readonly logger: Logger;\n private items: Map<number, ItemCache<Data>>;\n private defaultSize: DefaultSize;\n\n constructor({ itemSize, cacheData, cacheOnReload, sizeStrategy }: Settings, logger: Logger) {\n this.itemSize = itemSize;\n this.saveData = cacheData;\n this.cacheOnReload = cacheOnReload;\n this.sizeStrategy = sizeStrategy;\n this.logger = logger;\n this.items = new Map<number, ItemCache<Data>>();\n this.defaultSize = new DefaultSize(itemSize, sizeStrategy);\n this.reset(true);\n }\n\n reset(force: boolean): void {\n force = force || !this.cacheOnReload;\n if (force) {\n this.minIndex = +Infinity;\n this.maxIndex = -Infinity;\n this.items.clear();\n }\n this.defaultSize.reset(force);\n }\n\n get size(): number {\n return this.items.size;\n }\n\n get(index: number): ItemCache<Data> | undefined {\n return this.items.get(index);\n }\n\n getSizeByIndex(index: number): number {\n const item = this.get(index);\n return item && item.size || this.defaultSize.get();\n }\n\n getDefaultSize(): number {\n return this.defaultSize.get();\n }\n\n recalculateDefaultSize(): boolean {\n if (this.defaultSize.recalculate(this.size)) {\n this.logger.log(() => `default size has been updated: ${this.defaultSize.get()}`);\n return true;\n }\n return false;\n }\n\n /**\n * Adds item to Set by $index, replaces existed item if $index matches.\n * Maintains min/max indexes and default item size.\n *\n * @param {Item<Data>} item A Buffer item to be cached, an objects with { $index, data, size } props.\n * \n * @returns {ItemCache<Data>} Cached item.\n */\n add(item: Item<Data>): ItemCache<Data> {\n let itemCache = this.get(item.$index);\n if (itemCache) { // adding item is already cached\n if (this.saveData) {\n itemCache.data = item.data;\n }\n if (itemCache.size !== item.size) {\n if (itemCache.size) {\n this.defaultSize.setExisted(itemCache.size, item.size);\n } else {\n this.defaultSize.setNew(item.size);\n }\n itemCache.size = item.size;\n }\n } else {\n itemCache = new ItemCache<Data>(item, this.saveData);\n this.items.set(item.$index, itemCache);\n this.defaultSize.setNew(item.size);\n }\n if (item.$index < this.minIndex) {\n this.minIndex = item.$index;\n }\n if (item.$index > this.maxIndex) {\n this.maxIndex = item.$index;\n }\n return itemCache;\n }\n\n /**\n * Inserts items to Set, shifts $indexes of items that remain.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes.\n *\n * @param {Data[]} toInsert List of non-indexed items to be inserted.\n * @param {number} index The index before/after which the insertion is performed.\n * @param {Direction} direction Determines the direction of insertion.\n * @param {boolean} fixRight Defines indexes shifting strategy.\n * If false, indexes that are greater than the inserted ones are increased.\n * If true, indexes that are less than than the inserted ones are decreased.\n */\n insertItems(toInsert: Data[], index: number, direction: Direction, fixRight: boolean): void {\n const items = new Map<number, ItemCache<Data>>();\n const length = toInsert.length;\n let min = Infinity, max = -Infinity;\n const set = (item: ItemCache<Data>) => {\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n };\n this.items.forEach(item => {\n let shift = 0;\n if (direction === Direction.backward) {\n if (item.$index < index && fixRight) {\n shift = -length;\n } else if (item.$index >= index && !fixRight) {\n shift = length;\n }\n } else if (direction === Direction.forward) {\n if (item.$index <= index && fixRight) {\n shift = -length;\n } else if (item.$index > index && !fixRight) {\n shift = length;\n }\n }\n if (shift) {\n item.changeIndex(item.$index + shift);\n }\n set(item);\n });\n if (this.saveData) { // persist data with no sizes\n toInsert.forEach((data, i) => {\n const $index = index + i - (fixRight ? length : 0) + (direction === Direction.forward ? 1 : 0);\n const item = new ItemCache<Data>({ $index, data }, this.saveData);\n set(item);\n });\n }\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n\n /**\n * Removes items from Set, shifts $indexes of items that remain.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes and default item size.\n *\n * @param {number[]} toRemove List of indexes to be removed.\n * @param {boolean} fixRight Defines indexes shifting strategy.\n * If false, indexes that are greater than the removed ones will be decreased.\n * If true, indexes that are less than than the removed ones will be increased.\n */\n removeItems(toRemove: number[], fixRight: boolean): void {\n const items = new Map<number, ItemCache<Data>>();\n let min = Infinity, max = -Infinity;\n this.items.forEach(item => {\n if (toRemove.some(index => index === item.$index)) {\n if (item.size) {\n this.defaultSize.setRemoved(item.size);\n }\n return;\n }\n const diff = fixRight\n ? toRemove.reduce((acc, index) => acc + (item.$index < index ? 1 : 0), 0)\n : toRemove.reduce((acc, index) => acc - (item.$index > index ? 1 : 0), 0);\n item.changeIndex(item.$index + diff);\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n });\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n\n /**\n * Destructively updates Set based on subset (before-after) changes.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes. Maintains default item size on remove only.\n *\n * @param {ItemUpdate[]} before Initial subset of items to be replaced by \"after\".\n * Each element is an object with { $index, size, toRemove } props. Must be $index-incremental.\n * Items to be removed must have toRemove flag: before[].toRemove = true.\n * @param {Item<Data>[]} after Transformed subset that replaces \"before\". Must be $index-incremental.\n * Must contain at least 1 $index from \"before\" or be empty.\n * @param {boolean} fixRight This is to fix right indexes during subset collapsing. Acts only if \"after\" is empty.\n */\n updateSubset(before: ItemUpdate[], after: Item<Data>[], fixRight?: boolean): void {\n if (!this.size || !before.length) {\n return;\n }\n const minB = before[0].$index, maxB = before[before.length - 1].$index;\n let leftDiff: number, rightDiff: number;\n if (after.length) {\n const minA = after[0].$index, maxA = after[after.length - 1].$index;\n leftDiff = minA - minB;\n rightDiff = maxA - maxB;\n } else {\n leftDiff = fixRight ? maxB - minB + 1 : 0;\n rightDiff = fixRight ? 0 : minB - maxB - 1;\n }\n const items = new Map<number, ItemCache<Data>>();\n this.items.forEach(item => {\n if (item.$index < minB) { // items to the left of the subset\n item.changeIndex(item.$index + leftDiff);\n items.set(item.$index, item);\n return;\n } else if (item.$index > maxB) { // items to the right of the subset\n item.changeIndex(item.$index + rightDiff);\n items.set(item.$index, item);\n return;\n }\n });\n after.forEach(item => // subset items\n items.set(item.$index, new ItemCache<Data>(item, this.saveData))\n );\n before // to maintain default size on remove\n .filter(item => item.toRemove)\n .forEach(item => this.defaultSize.setRemoved(item.size));\n this.minIndex += leftDiff;\n this.maxIndex += rightDiff;\n this.items = items;\n }\n\n /**\n * Shifts all indexes by some value.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes.\n *\n * @param {number} delta A shift value.\n */\n shiftIndexes(delta: number): void {\n const items = new Map<number, ItemCache<Data>>();\n let min = Infinity, max = -Infinity;\n this.items.forEach(item => {\n item.changeIndex(item.$index + delta);\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n });\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n}\n","import { Buffer } from '../buffer';\nimport { Logger } from '../logger';\nimport { Direction } from '../../inputs/index';\nimport { ItemsPredicate } from '../../interfaces/index';\n\nexport class CheckBufferCall<Data> {\n private context: Buffer<Data>;\n private logger: Logger;\n\n constructor(context: Buffer<Data>, logger: Logger) {\n this.context = context;\n this.logger = logger;\n }\n\n fillEmpty(items: Data[], before?: number, after?: number): boolean {\n if (!items.length) {\n this.logger.log('no items to fill the buffer; empty list');\n return false;\n }\n if (!Number.isInteger(before) && !Number.isInteger(after)) {\n this.logger.log('no items to fill the buffer; wrong indexes');\n return false;\n }\n this.logger.log(() => `going to fill the buffer with ${items.length} item(s)`);\n return true;\n }\n\n insertInBuffer(predicate?: ItemsPredicate, before?: number, after?: number): number {\n const index = Number.isInteger(before) ? before : (Number.isInteger(after) ? after : NaN);\n const found = this.context.items.find(item =>\n (predicate && predicate(item.get())) ||\n (Number.isInteger(index) && index === item.$index)\n );\n if (!found) {\n this.logger.log('no items to insert in buffer; empty predicate\\'s result');\n return NaN;\n }\n return found.$index;\n }\n\n insertVirtual(items: Data[], index: number, direction: Direction): boolean {\n if (!items.length) {\n this.logger.log('no items to insert virtually; empty list');\n return false;\n }\n const { firstIndex, lastIndex, finiteAbsMinIndex, finiteAbsMaxIndex } = this.context;\n if (index < finiteAbsMinIndex || index > finiteAbsMaxIndex) {\n this.logger.log(() =>\n 'no items to insert virtually; ' +\n `selected index (${index}) does not match virtual area [${finiteAbsMinIndex}..${finiteAbsMaxIndex}]`\n );\n return false;\n }\n const before = direction === Direction.backward;\n if (!(index < firstIndex + (before ? 1 : 0) || index > lastIndex - (before ? 0 : 1))) {\n this.logger.log(() =>\n `no items to insert virtually; selected index (${index}) belongs Buffer [${firstIndex}..${lastIndex}]`\n );\n return false;\n }\n this.logger.log(() => `going to insert ${items.length} item(s) virtually`);\n return true;\n }\n\n}","import { Cache } from './buffer/cache';\nimport { CheckBufferCall } from './buffer/checkCall';\nimport { Item } from './item';\nimport { Settings } from './settings';\nimport { Logger } from './logger';\nimport { Reactive } from './reactive';\nimport { Direction } from '../inputs/index';\nimport { OnDataChanged, BufferUpdater, ItemsPredicate } from '../interfaces/index';\n\nexport class Buffer<Data> {\n\n private _items: Item<Data>[] = [];\n private _absMinIndex: number;\n private _absMaxIndex: number;\n bof: Reactive<boolean>;\n eof: Reactive<boolean>;\n\n changeItems: OnDataChanged<Data>;\n minIndexUser: number;\n maxIndexUser: number;\n startIndexUser: number;\n startIndex: number;\n\n private pristine: boolean;\n private cache: Cache<Data>;\n private checkCall: CheckBufferCall<Data>;\n private readonly logger: Logger;\n\n constructor(settings: Settings<Data>, onDataChanged: OnDataChanged<Data>, logger: Logger) {\n this.logger = logger;\n this.changeItems = onDataChanged;\n this.bof = new Reactive<boolean>(false);\n this.eof = new Reactive<boolean>(false);\n this.cache = new Cache<Data>(settings, logger);\n this.checkCall = new CheckBufferCall(this, logger);\n this.startIndexUser = settings.startIndex;\n this.minIndexUser = settings.minIndex;\n this.maxIndexUser = settings.maxIndex;\n this.reset(true);\n }\n\n dispose(): void {\n this.bof.dispose();\n this.eof.dispose();\n this._items.forEach(item => item.dispose());\n this._items = [];\n }\n\n reset(force: boolean, startIndex?: number): void {\n this.items.forEach(item => item.hide());\n this.pristine = true;\n this.items = [];\n this.cache.reset(force);\n this.absMinIndex = this.minIndexUser;\n this.absMaxIndex = this.maxIndexUser;\n this.setCurrentStartIndex(startIndex);\n this.bof.set(false);\n this.eof.set(false);\n this.pristine = false;\n }\n\n setCurrentStartIndex(newStartIndex?: unknown): void {\n const min = this.minIndexUser;\n const max = this.maxIndexUser;\n const start = this.startIndexUser;\n let index = Number(newStartIndex);\n if (Number.isNaN(index)) {\n this.logger.log(() => `fallback startIndex to settings.startIndex (${start})`);\n index = start;\n }\n if (index < min) {\n this.logger.log(() => `setting startIndex to settings.minIndex (${min}) because ${index} < ${min}`);\n index = min;\n }\n if (index > max) {\n this.logger.log(() => `setting startIndex to settings.maxIndex (${max}) because ${index} > ${max}`);\n index = max;\n }\n this.startIndex = index;\n }\n\n set items(items: Item<Data>[]) {\n this._items = items;\n this.changeItems(items);\n if (!this.pristine) {\n this.checkBOF();\n this.checkEOF();\n }\n }\n\n get items(): Item<Data>[] {\n return this._items;\n }\n\n set absMinIndex(value: number) {\n if (this._absMinIndex !== value) {\n this._absMinIndex = Number.isFinite(this._absMaxIndex) && value > this._absMaxIndex ? this._absMaxIndex : value;\n }\n if (!this.pristine) {\n this.checkBOF();\n }\n }\n\n get absMinIndex(): number {\n return this._absMinIndex;\n }\n\n set absMaxIndex(value: number) {\n if (this._absMaxIndex !== value) {\n this._absMaxIndex = Number.isFinite(this._absMinIndex) && value < this._absMinIndex ? this._absMinIndex : value;\n }\n if (!this.pristine) {\n this.checkEOF();\n }\n }\n\n get absMaxIndex(): number {\n return this._absMaxIndex;\n }\n\n private checkBOF() {\n // since bof has no setter, need to call checkBOF() on items and absMinIndex change\n const bof = this.items.length\n ? (this.items[0].$index === this.absMinIndex)\n : isFinite(this.absMinIndex);\n this.bof.set(bof);\n }\n\n private checkEOF() {\n // since eof has no setter, need to call checkEOF() on items and absMaxIndex change\n const eof = this.items.length\n ? (this.items[this.items.length - 1].$index === this.absMaxIndex)\n : isFinite(this.absMaxIndex);\n this.eof.set(eof);\n }\n\n get size(): number {\n return this._items.length;\n }\n\n get cacheSize(): number {\n return this.cache.size;\n }\n\n get defaultSize(): number {\n return this.cache.getDefaultSize();\n }\n\n get minIndex(): number {\n return isFinite(this.cache.minIndex) ? this.cache.minIndex : this.startIndex;\n }\n\n get maxIndex(): number {\n return isFinite(this.cache.maxIndex) ? this.cache.maxIndex : this.startIndex;\n }\n\n get firstIndex(): number {\n return this.items.length ? this.items[0].$index : NaN;\n }\n\n get lastIndex(): number {\n return this.items.length ? this.items[this.items.length - 1].$index : NaN;\n }\n\n get finiteAbsMinIndex(): number {\n return isFinite(this.absMinIndex) ? this.absMinIndex : this.minIndex;\n }\n\n get finiteAbsMaxIndex(): number {\n return isFinite(this.absMaxIndex) ? this.absMaxIndex : this.maxIndex;\n }\n\n get($index: number): Item<Data> | undefined {\n return this.items.find(item => item.$index === $index);\n }\n\n setItems(items: Item<Data>[]): boolean {\n if (!this.items.length) {\n this.items = [...items];\n } else if (this.items[0].$index > items[items.length - 1].$index) {\n this.items = [...items, ...this.items];\n } else if (items[0].$index > this.items[this.items.length - 1].$index) {\n this.items = [...this.items, ...items];\n } else {\n return false;\n }\n return true;\n }\n\n clip(): void {\n this.items = this.items.filter(({ toRemove }) => !toRemove);\n }\n\n getIndexToInsert(predicate?: ItemsPredicate, before?: number, after?: number): number {\n return this.checkCall.insertInBuffer(predicate, before, after);\n }\n\n private shiftExtremum(amount: number, fixRight: boolean) {\n if (!fixRight) {\n this.absMaxIndex += amount;\n } else {\n this.absMinIndex -= amount;\n this.startIndex -= amount;\n }\n if (this.startIndex > this.absMaxIndex) {\n this.startIndex = this.absMaxIndex;\n } else if (this.startIndex < this.absMinIndex) {\n this.startIndex = this.absMinIndex;\n }\n }\n\n appendVirtually(count: number, fixRight: boolean): void {\n if (fixRight) {\n this.items.forEach(item => item.updateIndex(item.$index - count));\n this.cache.shiftIndexes(-count);\n this.items = [...this.items];\n }\n this.shiftExtremum(count, fixRight);\n }\n\n prependVirtually(count: number, fixRight: boolean): void {\n if (!fixRight) {\n this.items.forEach(item => item.updateIndex(item.$index + count));\n this.cache.shiftIndexes(count);\n this.items = [...this.items];\n }\n this.shiftExtremum(count, fixRight);\n }\n\n insertVirtually(items: Data[], index: number, direction: Direction, fixRight: boolean): boolean {\n if (!this.checkCall.insertVirtual(items, index, direction)) {\n return false;\n }\n let shift = 0;\n if (index <= this.firstIndex && !fixRight) {\n shift = items.length;\n } else if (index >= this.lastIndex && fixRight) {\n shift = -items.length;\n }\n if (shift) {\n this.items.forEach(item => item.updateIndex(item.$index + shift));\n this.cache.insertItems(items, index, direction, fixRight);\n this.items = [...this.items];\n }\n this.shiftExtremum(items.length, fixRight);\n return true;\n }\n\n removeVirtually(indexes: number[], fixRight: boolean): void {\n const length = this.items.length;\n let shifted = false;\n for (\n let i = fixRight ? length - 1 : 0;\n fixRight ? i >= 0 : i < length;\n fixRight ? i-- : i++\n ) {\n const item = this.items[i];\n const diff = indexes.reduce((acc, index) => acc + (fixRight\n ? (item.$index < index ? 1 : 0)\n : (item.$index > index ? -1 : 0)\n ), 0);\n shifted = shifted || !!diff;\n item.updateIndex(item.$index + diff);\n }\n this.shiftExtremum(-indexes.length, fixRight);\n if (shifted) {\n this.items = [...this.items];\n }\n this.cache.removeItems(indexes, fixRight);\n }\n\n fillEmpty(\n items: Data[], beforeIndex: number | undefined, afterIndex: number | undefined, fixRight: boolean,\n generator: (index: number, data: Data) => Item<Data>,\n ): boolean {\n if (!this.checkCall.fillEmpty(items, beforeIndex, afterIndex)) {\n return false;\n }\n const before = Number.isInteger(beforeIndex);\n const index = (before ? beforeIndex : afterIndex) as number;\n const shift = (fixRight ? items.length : (before ? 1 : 0));\n this.items = items.map((data, i) =>\n generator(index + i + (!before ? 1 : 0) - shift, data)\n );\n this._absMinIndex = this.items[0].$index;\n this._absMaxIndex = this.items[this.size - 1].$index;\n if (this.startIndex <= this.absMinIndex) {\n this.startIndex = this.absMinIndex;\n } else if (this.startIndex > this.absMaxIndex) {\n this.startIndex = this.absMaxIndex;\n }\n return true;\n }\n\n updateItems(\n predicate: BufferUpdater<Data>,\n generator: (index: number, data: Data) => Item<Data>,\n indexToTrack: number,\n fixRight: boolean\n ): { trackedIndex: number, toRemove: Item<Data>[] } {\n if (!this.size || Number.isNaN(this.firstIndex)) {\n return { trackedIndex: NaN, toRemove: [] };\n }\n let trackedIndex = indexToTrack;\n let index = fixRight ? this.lastIndex : this.firstIndex;\n const items: Item<Data>[] = [];\n const diff = fixRight ? -1 : 1;\n const limit = this.size - 1;\n const beforeMap = new Map<number, Item>(); // need to persist original $indexes\n const updateArray = Array.prototype[fixRight ? 'unshift' : 'push'];\n\n for (let i = fixRight ? limit : 0; fixRight ? i >= 0 : i <= limit; i += diff) {\n const item = this.items[i];\n beforeMap.set(item.$index, item);\n const result = predicate(item);\n\n // if predicate result is falsy or empty array -> delete\n if (!result || (Array.isArray(result) && !result.length)) {\n item.toRemove = true;\n trackedIndex += item.$index >= indexToTrack ? (fixRight ? 1 : 0) : (fixRight ? 0 : -1);\n this.shiftExtremum(-1, fixRight);\n continue;\n }\n\n // if predicate result is truthy but not array -> leave\n if (!Array.isArray(result)) {\n item.updateIndex(index);\n updateArray.call(items, item);\n index += diff;\n continue;\n }\n\n // if predicate result is non-empty array -> insert/replace\n if (item.$index < indexToTrack) {\n trackedIndex += fixRight ? 0 : result.length - 1;\n } else if (item.$index > indexToTrack) {\n trackedIndex += fixRight ? 1 - result.length : 0;\n }\n let toRemove = true;\n const newItems: Item<Data>[] = [];\n (fixRight ? [...result].reverse() : result).forEach((data, i) => {\n let newItem: Item<Data>;\n if (item.data === data) {\n if (indexToTrack === item.$index) {\n trackedIndex = index + i * diff;\n }\n item.updateIndex(index + i * diff);\n newItem = item;\n toRemove = false; // insert case\n } else {\n newItem = generator(index + i * diff, data);\n newItem.toInsert = true;\n }\n updateArray.call(newItems, newItem);\n });\n item.toRemove = toRemove;\n updateArray.call(items, ...newItems);\n index += diff * result.length;\n if (result.length > 1) {\n this.shiftExtremum(result.length - 1, fixRight);\n }\n }\n\n const toRemove = this.items.filter(item => item.toRemove);\n const itemsBefore = Array.from(beforeMap)\n .map(([$index, { size, toRemove }]) => ({ $index, size, toRemove }))\n .sort((a, b) => a.$index - b.$index);\n this.items = items;\n this.cache.updateSubset(itemsBefore, items, fixRight);\n\n if (this.finiteAbsMinIndex === this.finiteAbsMaxIndex) {\n trackedIndex = NaN;\n } else if (trackedIndex > this.finiteAbsMaxIndex) {\n trackedIndex = this.finiteAbsMaxIndex;\n } else if (trackedIndex < this.finiteAbsMinIndex) {\n trackedIndex = this.finiteAbsMinIndex;\n }\n return { trackedIndex, toRemove };\n }\n\n cacheItem(item: Item<Data>): void {\n this.cache.add(item);\n }\n\n getFirstVisibleItemIndex(): number {\n const length = this.items.length;\n for (let i = 0; i < length; i++) {\n if (!this.items[i].invisible) {\n return i;\n }\n }\n return -1;\n }\n\n getLastVisibleItemIndex(): number {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (!this.items[i].invisible) {\n return i;\n }\n }\n return -1;\n }\n\n getFirstVisibleItem(): Item<Data> | undefined {\n const index = this.getFirstVisibleItemIndex();\n if (index >= 0) {\n return this.items[index];\n }\n }\n\n getLastVisibleItem(): Item<Data> | undefined {\n const index = this.getLastVisibleItemIndex();\n if (index >= 0) {\n return this.items[index];\n }\n }\n\n getEdgeVisibleItem(direction: Direction, opposite?: boolean): Item<Data> | undefined {\n return direction === (!opposite ? Direction.forward : Direction.backward) ?\n this.getLastVisibleItem() : this.getFirstVisibleItem();\n }\n\n getVisibleItemsCount(): number {\n return this.items.reduce((acc: number, item) => acc + (item.invisible ? 0 : 1), 0);\n }\n\n getSizeByIndex(index: number): number {\n return this.cache.getSizeByIndex(index);\n }\n\n checkDefaultSize(): boolean {\n return this.cache.recalculateDefaultSize();\n }\n\n}\n","import { ProcessName } from '../../interfaces/index';\nimport { Reactive } from '../reactive';\n\nclass InnerLoopModel {\n total: number;\n count: number;\n isInitial: boolean;\n busy: Reactive<boolean>;\n\n get first(): boolean {\n return this.count === 0;\n }\n\n constructor(total: number) {\n this.total = total;\n this.isInitial = false;\n this.busy = new Reactive<boolean>(false);\n }\n\n done() {\n this.count++;\n this.total++;\n this.busy.set(false);\n }\n\n start() {\n this.busy.set(true);\n }\n\n dispose() {\n this.busy.dispose();\n }\n}\n\nexport class WorkflowCycleModel {\n instanceIndex: number;\n count: number;\n isInitial: boolean;\n initiator: ProcessName;\n innerLoop: InnerLoopModel;\n interrupter: ProcessName | null;\n busy: Reactive<boolean>;\n\n get loopId(): string {\n return `${this.instanceIndex}-${this.count}-${this.innerLoop.total}`;\n }\n\n get loopIdNext(): string {\n return `${this.instanceIndex}-${this.count}-${this.innerLoop.total + 1}`;\n }\n\n constructor(instanceIndex: number, cycle?: WorkflowCycleModel) {\n const cycleCount = cycle ? cycle.count : 1;\n const loopCount = cycle ? cycle.innerLoop.count : 0;\n\n this.instanceIndex = instanceIndex;\n this.innerLoop = new InnerLoopModel(loopCount);\n this.interrupter = null;\n this.busy = new Reactive<boolean>(false);\n this.done(cycleCount);\n }\n\n done(count: number): void {\n this.count = count;\n this.isInitial = false;\n this.busy.set(false);\n }\n\n start(isInitial: boolean, initiator: ProcessName): void {\n this.isInitial = isInitial;\n this.initiator = initiator;\n this.innerLoop.isInitial = isInitial;\n this.innerLoop.count = 0;\n this.interrupter = null;\n this.busy.set(true);\n }\n\n dispose(forever?: boolean): void {\n if (forever) {\n // otherwise the value will be persisted during re-instantiation\n this.busy.dispose();\n }\n this.innerLoop.dispose();\n }\n}\n","import { Item } from '../item';\nimport { Direction } from '../../inputs/index';\n\nclass Positions {\n startDelta: number;\n before: number;\n relative: number;\n start: number;\n end: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.startDelta = 0;\n this.before = 0;\n }\n}\n\nclass First {\n index: number;\n indexBuffer: number;\n position: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.indexBuffer = NaN;\n this.position = NaN;\n }\n}\n\nclass Last {\n index: number;\n indexBuffer: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.indexBuffer = NaN;\n }\n}\n\nclass FirstVisible {\n index: number;\n delta: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.delta = 0;\n }\n}\n\nexport class FetchModel {\n private readonly directionPriority: Direction;\n private _newItemsData: unknown[] | null; // there are public setter and getter\n\n items: Item[];\n positions: Positions;\n first: First;\n last: Last;\n hasAnotherPack: boolean;\n callCount: number;\n minIndex: number;\n firstVisible: FirstVisible;\n direction: Direction | null;\n cancel: (() => void) | null;\n\n simulate: boolean;\n isCheck: boolean;\n doRemove: boolean;\n\n constructor(directionPriority: Direction) {\n this.directionPriority = directionPriority;\n this.callCount = 0;\n this.positions = new Positions();\n this.first = new First();\n this.last = new Last();\n this.firstVisible = new FirstVisible();\n this.reset();\n }\n\n reset(): void {\n this._newItemsData = null;\n this.items = [];\n this.positions.reset();\n this.first.reset();\n this.last.reset();\n this.firstVisible.reset();\n this.hasAnotherPack = false;\n this.direction = null;\n this.cancel = null;\n this.simulate = false;\n this.isCheck = false;\n this.doRemove = false;\n }\n\n get newItemsData(): unknown[] | null {\n return this._newItemsData;\n }\n\n set newItemsData(items: unknown[] | null) {\n this._newItemsData = items;\n if (items && items.length) {\n this.callCount++;\n }\n }\n\n get shouldFetch(): boolean {\n return !!this.count;\n }\n\n get hasNewItems(): boolean {\n return !!((this._newItemsData && this._newItemsData.length));\n }\n\n get index(): number {\n return this.first.index;\n }\n\n get count(): number {\n return !isNaN(this.first.index) && !isNaN(this.last.index) ? this.last.index - this.first.index + 1 : 0;\n }\n\n shouldCheckPreSizeExpectation(lastBufferedIndex: number): boolean {\n if (this.directionPriority === Direction.backward) {\n return false;\n }\n const lastFetched = this.items[this.items.length - 1];\n return lastFetched && lastFetched.$index < lastBufferedIndex;\n }\n\n startSimulate(items: Item[]): void {\n this.simulate = true;\n this._newItemsData = items.map(item => item.data);\n this.items = items;\n this.hasAnotherPack = false;\n }\n\n stopSimulate(): void {\n this.simulate = false;\n this.isCheck = false;\n this.doRemove = false;\n }\n\n fill(items: Item[], start: number): void {\n this.startSimulate(items);\n this.first.index = items[0].$index;\n this.last.index = items[items.length - 1].$index;\n this.direction = Direction.forward;\n this.firstVisible.index = start;\n this.firstVisible.delta = 0;\n }\n\n append(items: Item[]): void {\n this.startSimulate(items);\n this.last.index = items[items.length - 1].$index;\n this.first.index = items[0].$index;\n this.direction = Direction.forward;\n }\n\n prepend(items: Item[]): void {\n this.startSimulate(items);\n this.last.index = items[0].$index;\n this.first.index = items[items.length - 1].$index;\n this.direction = Direction.backward;\n }\n\n check(items: Item[]): void {\n this.startSimulate(items);\n this.last.index = items[0].$index;\n this.first.index = items[items.length - 1].$index;\n this.isCheck = true;\n }\n\n update(index: number, delta: number, items: Item[], itemsToRemove: Item[]): void {\n this.startSimulate(items);\n this.firstVisible.index = index;\n this.firstVisible.delta = delta;\n this.doRemove = itemsToRemove.length > 0;\n }\n}\n","export class ClipModel {\n doClip: boolean;\n callCount: number;\n forceForward: boolean;\n forceBackward: boolean;\n\n get force(): boolean {\n return this.forceForward || this.forceBackward;\n }\n\n constructor() {\n this.callCount = 0;\n this.reset();\n }\n\n reset(force?: boolean): void {\n this.doClip = false;\n if (!force) {\n this.forceForward = false;\n this.forceBackward = false;\n }\n }\n\n}\n","export class RenderModel {\n sizeBefore: number;\n sizeAfter: number;\n positionBefore: number;\n renderTimer: ReturnType<typeof setTimeout> | null;\n\n get noSize(): boolean {\n return this.sizeBefore === this.sizeAfter;\n }\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.sizeBefore = 0;\n this.sizeAfter = 0;\n this.positionBefore = 0;\n this.renderTimer = null;\n }\n}\n","import {\n ScrollEventData as IScrollEventData,\n ScrollState as IScrollState\n} from '../../interfaces/index';\n\nexport class ScrollState implements IScrollState {\n previous: IScrollEventData | null;\n current: IScrollEventData | null;\n\n scrollTimer: ReturnType<typeof setTimeout> | null;\n\n syntheticPosition: number | null;\n syntheticFulfill: boolean;\n animationFrameId: number;\n positionBeforeAsync: number | null;\n positionBeforeAdjust: number | null;\n positionAfterAdjust: number | null;\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.previous = null;\n this.current = null;\n this.syntheticPosition = null;\n this.syntheticFulfill = false;\n this.positionBeforeAsync = null;\n this.positionBeforeAdjust = null;\n this.positionAfterAdjust = null;\n this.cleanupTimers();\n }\n\n cleanupTimers(): void {\n if (this.scrollTimer) {\n clearTimeout(this.scrollTimer);\n this.scrollTimer = null;\n }\n if (this.animationFrameId) {\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = 0;\n }\n }\n\n hasPositionChanged(position: number): boolean {\n const before = this.positionBeforeAdjust;\n const after = this.positionAfterAdjust;\n return before === null || before !== position || after === null || after !== position;\n }\n}\n","import { Settings } from './settings';\r\nimport { WorkflowCycleModel } from './state/cycle';\r\nimport { FetchModel } from './state/fetch';\r\nimport { ClipModel } from './state/clip';\r\nimport { RenderModel } from './state/render';\r\nimport { ScrollState } from './state/scroll';\r\nimport { State as IState, IPackages, ScrollState as IScrollState, ProcessName } from '../interfaces/index';\r\n\r\nexport class State implements IState {\r\n\r\n readonly packageInfo: IPackages;\r\n private settings: Settings;\r\n\r\n initTime: number;\r\n\r\n cycle: WorkflowCycleModel;\r\n\r\n fetch: FetchModel;\r\n clip: ClipModel;\r\n render: RenderModel;\r\n\r\n scrollState: IScrollState;\r\n\r\n get time(): number {\r\n return Number(new Date()) - this.initTime;\r\n }\r\n\r\n constructor(packageInfo: IPackages, settings: Settings, state?: IState) {\r\n this.packageInfo = packageInfo;\r\n this.settings = settings;\r\n\r\n this.initTime = Number(new Date());\r\n\r\n this.cycle = new WorkflowCycleModel(this.settings.instanceIndex, state ? state.cycle : void 0);\r\n\r\n this.fetch = new FetchModel(settings.directionPriority);\r\n this.clip = new ClipModel();\r\n this.render = new RenderModel();\r\n\r\n this.scrollState = new ScrollState();\r\n }\r\n\r\n endInnerLoop(): void {\r\n const { fetch, render, cycle } = this;\r\n if (fetch.cancel) {\r\n fetch.cancel();\r\n fetch.cancel = null;\r\n }\r\n if (render.renderTimer) {\r\n clearTimeout(render.renderTimer);\r\n render.renderTimer = null;\r\n }\r\n cycle.innerLoop.done();\r\n }\r\n\r\n startInnerLoop(): { process?: ProcessName, doRender?: boolean } {\r\n const { cycle, scrollState: scroll, fetch, render, clip } = this;\r\n\r\n cycle.innerLoop.start();\r\n scroll.positionBeforeAsync = null;\r\n\r\n if (!fetch.simulate) {\r\n fetch.reset();\r\n }\r\n clip.reset(clip.force);\r\n render.reset();\r\n\r\n return {\r\n ...(cycle.innerLoop.first ? {\r\n process: cycle.initiator,\r\n doRender: fetch.simulate && fetch.items.length > 0\r\n } : {})\r\n };\r\n }\r\n\r\n dispose(): void {\r\n this.cycle.dispose();\r\n this.endInnerLoop();\r\n this.scrollState.cleanupTimers();\r\n }\r\n\r\n}\r\n","import { Logger } from './logger';\r\nimport { Buffer } from './buffer';\r\nimport { Reactive } from './reactive';\r\nimport {\r\n AdapterPropName, AdapterPropType, getDefaultAdapterProps, methodPreResult, reactiveConfigStorage\r\n} from './adapter/props';\r\nimport { AdapterProcess, ProcessStatus } from '../processes/index';\r\nimport {\r\n WorkflowGetter,\r\n IAdapterProp,\r\n AdapterMethodResult,\r\n IAdapter,\r\n ItemAdapter,\r\n ItemsPredicate,\r\n AdapterPrependOptions,\r\n AdapterAppendOptions,\r\n AdapterRemoveOptions,\r\n AdapterClipOptions,\r\n AdapterInsertOptions,\r\n AdapterReplaceOptions,\r\n AdapterUpdateOptions,\r\n AdapterFixOptions,\r\n ScrollerWorkflow,\r\n IDatasourceOptional,\r\n IPackages,\r\n IBufferInfo,\r\n State,\r\n ProcessSubject,\r\n} from '../interfaces/index';\r\n\r\ntype MethodResolver = (...args: any[]) => Promise<AdapterMethodResult>;\r\n\r\nconst ADAPTER_PROPS_STUB = getDefaultAdapterProps();\r\n\r\nconst _has = (obj: unknown, prop: string): boolean =>\r\n typeof obj === 'object' && obj !== null && Object.prototype.hasOwnProperty.call(obj, prop);\r\n\r\nconst convertAppendArgs = <Item>(prepend: boolean, options: unknown, eof?: boolean) => {\r\n let result = options as AdapterAppendOptions<Item> & AdapterPrependOptions<Item>;\r\n if (!_has(options, 'items')) {\r\n const items = !Array.isArray(options) ? [options] : options;\r\n result = prepend ? { items, bof: eof } : { items, eof: eof };\r\n }\r\n return result;\r\n};\r\n\r\nconst convertRemoveArgs = <Item>(options: AdapterRemoveOptions<Item> | ItemsPredicate<Item>) => {\r\n if (!(_has(options, 'predicate') || _has(options, 'indexes'))) {\r\n const predicate = options as ItemsPredicate<Item>;\r\n options = { predicate };\r\n }\r\n return options;\r\n};\r\n\r\nexport class Adapter<Item = unknown> implements IAdapter<Item> {\r\n private externalContext: IAdapter<Item>;\r\n private logger: Logger;\r\n private getWorkflow: WorkflowGetter<Item>;\r\n private reloadCounter: number;\r\n private source: { [key: string]: Reactive<unknown> } = {}; // for Reactive props\r\n private box: { [key: string]: unknown } = {}; // for Scalars over Reactive props\r\n private demand: { [key: string]: unknown } = {}; // for Scalars on demand\r\n public wanted: { [key: string]: boolean } = {};\r\n\r\n get workflow(): ScrollerWorkflow<Item> {\r\n return this.getWorkflow();\r\n }\r\n get reloadCount(): number {\r\n return this.reloadCounter;\r\n }\r\n get reloadId(): string {\r\n return this.id + '.' + this.reloadCounter;\r\n }\r\n\r\n id: number;\r\n mock: boolean;\r\n augmented: boolean;\r\n version: string;\r\n init: boolean;\r\n init$: Reactive<boolean>;\r\n packageInfo: IPackages;\r\n itemsCount: number;\r\n bufferInfo: IBufferInfo;\r\n isLoading: boolean;\r\n isLoading$: Reactive<boolean>;\r\n loopPending: boolean;\r\n loopPending$: Reactive<boolean>;\r\n firstVisible: ItemAdapter<Item>;\r\n firstVisible$: Reactive<ItemAdapter<Item>>;\r\n lastVisible: ItemAdapter<Item>;\r\n lastVisible$: Reactive<ItemAdapter<Item>>;\r\n bof: boolean;\r\n bof$: Reactive<boolean>;\r\n eof: boolean;\r\n eof$: Reactive<boolean>;\r\n\r\n private relax$: Reactive<AdapterMethodResult> | null;\r\n private relaxRun: Promise<AdapterMethodResult> | null;\r\n\r\n private getPromisifiedMethod(method: MethodResolver, defaultMethod: MethodResolver) {\r\n return (...args: any[]): Promise<AdapterMethodResult> =>\r\n this.relax$\r\n ? new Promise(resolve => {\r\n if (this.relax$) {\r\n this.relax$.once(value => resolve(value));\r\n }\r\n method.apply(this, args);\r\n })\r\n : defaultMethod.apply(this, args);\r\n }\r\n\r\n constructor(context: IAdapter<Item> | null, getWorkflow: WorkflowGetter<Item>, logger: Logger) {\r\n this.getWorkflow = getWorkflow;\r\n this.logger = logger;\r\n this.relax$ = null;\r\n this.relaxRun = null;\r\n this.reloadCounter = 0;\r\n\r\n // public context (if exists) should provide access Reactive props configuration by id\r\n const reactivePropsStore = context && reactiveConfigStorage.get(context.id) || {};\r\n\r\n // make array of the original values from public context if present\r\n const adapterProps = context\r\n ? ADAPTER_PROPS_STUB.map(prop => {\r\n let value = context[prop.name];\r\n // if context is augmented, we need to replace external reactive props with inner ones\r\n if (context.augmented) {\r\n const reactiveProp = reactivePropsStore[prop.name];\r\n if (reactiveProp) {\r\n value = reactiveProp.default as Reactive<boolean>; // boolean doesn't matter here\r\n }\r\n }\r\n return ({ ...prop, value });\r\n })\r\n : getDefaultAdapterProps();\r\n\r\n // restore default reactive props if they were configured\r\n Object.entries(reactivePropsStore).forEach(([key, value]) => {\r\n const prop = adapterProps.find(({ name }) => name === key);\r\n if (prop && value) {\r\n prop.value = value.default;\r\n }\r\n });\r\n\r\n // Scalar permanent props\r\n adapterProps\r\n .filter(({ type, permanent }) => type === AdapterPropType.Scalar && permanent)\r\n .forEach(({ name, value }: IAdapterProp) =>\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => value\r\n })\r\n );\r\n\r\n // Reactive props\r\n // 1) store original values in \"source\" container, to avoid extra .get() calls on scalar twins set\r\n // 2) \"wanted\" container is bound with scalars; get() updates it\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Reactive)\r\n .forEach(({ name, value }: IAdapterProp) => {\r\n this.source[name] = value as Reactive<unknown>;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => {\r\n const scalarWanted = ADAPTER_PROPS_STUB.find(\r\n ({ wanted, reactive }) => wanted && reactive === name\r\n );\r\n if (scalarWanted) {\r\n this.wanted[scalarWanted.name] = true;\r\n }\r\n return this.source[name];\r\n }\r\n });\r\n });\r\n\r\n // Scalar props that have Reactive twins\r\n // 1) scalars should use \"box\" container\r\n // 2) \"wanted\" should be updated on get\r\n // 3) reactive props (from \"source\") are triggered on set\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Scalar && !!prop.reactive)\r\n .forEach(({ name, value, reactive, wanted }: IAdapterProp) => {\r\n if (wanted) {\r\n this.wanted[name] = false;\r\n }\r\n this.box[name] = value;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n set: (newValue: unknown) => {\r\n if (newValue !== this.box[name]) {\r\n this.box[name] = newValue;\r\n this.source[reactive as AdapterPropName].set(newValue);\r\n // need to emit new value through the configured reactive prop if present\r\n const reactiveProp = reactivePropsStore[reactive as AdapterPropName];\r\n if (reactiveProp) {\r\n reactiveProp.emit(reactiveProp.source, newValue);\r\n }\r\n }\r\n },\r\n get: () => {\r\n if (wanted) {\r\n this.wanted[name] = true;\r\n }\r\n return this.box[name];\r\n }\r\n });\r\n });\r\n\r\n // Scalar props on-demand\r\n // these scalars should use \"demand\" container\r\n // setting defaults should be overridden on init()\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Scalar && prop.onDemand)\r\n .forEach(({ name, value }: IAdapterProp) => {\r\n this.demand[name] = value;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => this.demand[name]\r\n });\r\n });\r\n\r\n if (!context) {\r\n return;\r\n }\r\n\r\n // Adapter public context augmentation\r\n adapterProps\r\n .forEach(({ name, type, value: defaultValue, permanent }: IAdapterProp) => {\r\n let value = (this as IAdapter)[name];\r\n if (type === AdapterPropType.Function) {\r\n value = (value as () => void).bind(this);\r\n } else if (type === AdapterPropType.WorkflowRunner) {\r\n value = this.getPromisifiedMethod(value as MethodResolver, defaultValue as MethodResolver);\r\n } else if (type === AdapterPropType.Reactive && reactivePropsStore[name]) {\r\n value = (context as IAdapter)[name];\r\n } else if (name === AdapterPropName.augmented) {\r\n value = true;\r\n }\r\n Object.defineProperty(context, name, {\r\n configurable: true,\r\n get: () => !permanent && type === AdapterPropType.Scalar\r\n ? (this as IAdapter)[name] // non-permanent Scalars should be taken in runtime\r\n : value // Reactive props and methods (Functions/WorkflowRunners) can be defined once\r\n });\r\n });\r\n\r\n this.externalContext = context;\r\n }\r\n\r\n initialize(buffer: Buffer<Item>, state: State, logger: Logger, adapterRun$?: Reactive<ProcessSubject>): void {\r\n // buffer\r\n Object.defineProperty(this.demand, AdapterPropName.itemsCount, {\r\n get: () => buffer.getVisibleItemsCount()\r\n });\r\n Object.defineProperty(this.demand, AdapterPropName.bufferInfo, {\r\n get: (): IBufferInfo => ({\r\n firstIndex: buffer.firstIndex,\r\n lastIndex: buffer.lastIndex,\r\n minIndex: buffer.minIndex,\r\n maxIndex: buffer.maxIndex,\r\n absMinIndex: buffer.absMinIndex,\r\n absMaxIndex: buffer.absMaxIndex,\r\n defaultSize: buffer.defaultSize,\r\n })\r\n });\r\n this.bof = buffer.bof.get();\r\n buffer.bof.on(bof => this.bof = bof);\r\n this.eof = buffer.eof.get();\r\n buffer.eof.on(eof => this.eof = eof);\r\n\r\n // state\r\n Object.defineProperty(this.demand, AdapterPropName.packageInfo, {\r\n get: () => state.packageInfo\r\n });\r\n this.loopPending = state.cycle.innerLoop.busy.get();\r\n state.cycle.innerLoop.busy.on(busy => this.loopPending = busy);\r\n this.isLoading = state.cycle.busy.get();\r\n state.cycle.busy.on(busy => this.isLoading = busy);\r\n\r\n // logger\r\n this.logger = logger;\r\n\r\n // self-pending subscription; set up only on the very first init\r\n if (adapterRun$) {\r\n if (!this.relax$) {\r\n this.relax$ = new Reactive();\r\n }\r\n const relax$ = this.relax$;\r\n adapterRun$.on(({ status, payload }) => {\r\n let unSubRelax = () => { };\r\n if (status === ProcessStatus.start) {\r\n unSubRelax = this.isLoading$.on(value => {\r\n if (!value) {\r\n unSubRelax();\r\n relax$.set({ success: true, immediate: false, details: null });\r\n }\r\n });\r\n } else if (status === ProcessStatus.done || status === ProcessStatus.error) {\r\n unSubRelax();\r\n relax$.set({\r\n success: status !== ProcessStatus.error,\r\n immediate: true,\r\n details: status === ProcessStatus.error && payload ? String(payload.error) : null\r\n });\r\n }\r\n });\r\n }\r\n\r\n // init\r\n this.init = true;\r\n }\r\n\r\n dispose(): void {\r\n if (this.relax$) {\r\n this.relax$.dispose();\r\n }\r\n if (this.externalContext) {\r\n this.resetContext();\r\n }\r\n Object.getOwnPropertyNames(this).forEach(prop => {\r\n delete (this as Record<string, unknown>)[prop];\r\n });\r\n }\r\n\r\n resetContext(): void {\r\n const reactiveStore = reactiveConfigStorage.get(this.externalContext.id);\r\n ADAPTER_PROPS_STUB\r\n .forEach(({ type, permanent, name, value }) => {\r\n // assign initial values to non-reactive non-permanent props\r\n if (type !== AdapterPropType.Reactive && !permanent) {\r\n Object.defineProperty(this.externalContext, name, {\r\n configurable: true,\r\n get: () => value\r\n });\r\n }\r\n // reset reactive props\r\n if (type === AdapterPropType.Reactive && reactiveStore) {\r\n const property = reactiveStore[name];\r\n if (property) {\r\n property.default.reset();\r\n property.emit(property.source, property.default.get());\r\n }\r\n }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reset(options?: IDatasourceOptional): any {\r\n this.reloadCounter++;\r\n this.logger.logAdapterMethod('reset', options, ` of ${this.reloadId}`);\r\n this.workflow.call({\r\n process: AdapterProcess.reset,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reload(options?: number | string): any {\r\n this.reloadCounter++;\r\n this.logger.logAdapterMethod('reload', options, ` of ${this.reloadId}`);\r\n this.workflow.call({\r\n process: AdapterProcess.reload,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n append(_options: AdapterAppendOptions<Item> | unknown, eof?: boolean): any {\r\n const options = convertAppendArgs(false, _options, eof); // support old signature\r\n this.logger.logAdapterMethod('append', [options.items, options.eof]);\r\n this.workflow.call({\r\n process: AdapterProcess.append,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n prepend(_options: AdapterPrependOptions<Item> | unknown, bof?: boolean): any {\r\n const options = convertAppendArgs(true, _options, bof); // support old signature\r\n this.logger.logAdapterMethod('prepend', [options.items, options.bof]);\r\n this.workflow.call({\r\n process: AdapterProcess.prepend,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n check(): any {\r\n this.logger.logAdapterMethod('check');\r\n this.workflow.call({\r\n process: AdapterProcess.check,\r\n status: ProcessStatus.start\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n remove(options: AdapterRemoveOptions<Item> | ItemsPredicate<Item>): any {\r\n options = convertRemoveArgs(options); // support old signature\r\n this.logger.logAdapterMethod('remove', options);\r\n this.workflow.call({\r\n process: AdapterProcess.remove,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n clip(options?: AdapterClipOptions): any {\r\n this.logger.logAdapterMethod('clip', options);\r\n this.workflow.call({\r\n process: AdapterProcess.clip,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n insert(options: AdapterInsertOptions<Item>): any {\r\n this.logger.logAdapterMethod('insert', options);\r\n this.workflow.call({\r\n process: AdapterProcess.insert,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n replace(options: AdapterReplaceOptions<Item>): any {\r\n this.logger.logAdapterMethod('replace', options);\r\n this.workflow.call({\r\n process: AdapterProcess.replace,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n update(options: AdapterUpdateOptions<Item>): any {\r\n this.logger.logAdapterMethod('update', options);\r\n this.workflow.call({\r\n process: AdapterProcess.update,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n fix(options: AdapterFixOptions<Item>): any {\r\n this.logger.logAdapterMethod('fix', options);\r\n this.workflow.call({\r\n process: AdapterProcess.fix,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n relaxUnchained(callback: (() => void) | undefined, reloadId: string): Promise<AdapterMethodResult> {\r\n const runCallback = () => typeof callback === 'function' && reloadId === this.reloadId && callback();\r\n if (!this.isLoading) {\r\n runCallback();\r\n }\r\n return new Promise<boolean>(resolve => {\r\n if (!this.isLoading) {\r\n resolve(true);\r\n return;\r\n }\r\n this.isLoading$.once(() => {\r\n runCallback();\r\n resolve(false);\r\n });\r\n }).then(immediate => {\r\n const success = reloadId === this.reloadId;\r\n this.logger.log(() => !success ? `relax promise cancelled due to ${reloadId} != ${this.reloadId}` : void 0);\r\n return {\r\n immediate,\r\n success,\r\n details: !success ? 'Interrupted by reload or reset' : null\r\n };\r\n });\r\n }\r\n\r\n relax(callback?: () => void): Promise<AdapterMethodResult> {\r\n const reloadId = this.reloadId;\r\n this.logger.logAdapterMethod('relax', callback, ` of ${reloadId}`);\r\n if (!this.init) {\r\n return Promise.resolve(methodPreResult);\r\n }\r\n return this.relaxRun = this.relaxRun\r\n ? this.relaxRun.then(() => this.relaxUnchained(callback, reloadId))\r\n : this.relaxUnchained(callback, reloadId).then((result) => {\r\n this.relaxRun = null;\r\n return result;\r\n });\r\n }\r\n\r\n showLog(): void {\r\n this.logger.logAdapterMethod('showLog');\r\n this.logger.logForce();\r\n }\r\n}\r\n","import { DatasourceGeneric, makeDatasource } from './classes/datasource';\nimport { Settings } from './classes/settings';\nimport { Logger } from './classes/logger';\nimport { Routines } from './classes/domRoutines';\nimport { Viewport } from './classes/viewport';\nimport { Buffer } from './classes/buffer';\nimport { State } from './classes/state';\nimport { Adapter } from './classes/adapter';\nimport { Reactive } from './classes/reactive';\nimport { validate, DATASOURCE } from './inputs/index';\nimport core from './version';\nimport {\n ScrollerWorkflow, IDatasource, IDatasourceConstructed, ScrollerParams, IPackages, ProcessSubject\n} from './interfaces/index';\n\nexport const INVALID_DATASOURCE_PREFIX = 'Invalid datasource:';\n\nlet instanceCount = 0;\n\nexport class Scroller<Data = unknown> {\n public datasource: IDatasourceConstructed<Data>;\n public workflow: ScrollerWorkflow<Data>;\n\n public settings: Settings<Data>;\n public logger: Logger;\n public routines: Routines;\n public viewport: Viewport;\n public buffer: Buffer<Data>;\n public state: State;\n public adapter: Adapter<Data>;\n\n constructor({ datasource, consumer, element, workflow, scroller }: ScrollerParams<Data>) {\n const { params: { get } } = validate(datasource, DATASOURCE);\n if (!get.isValid) {\n throw new Error(`${INVALID_DATASOURCE_PREFIX} ${get.errors[0]}`);\n }\n\n const packageInfo = scroller ? scroller.state.packageInfo : ({ consumer, core } as IPackages);\n element = scroller ? scroller.viewport.element : (element as HTMLElement);\n workflow = scroller ? scroller.workflow : (workflow as ScrollerWorkflow<Data>);\n\n this.workflow = workflow;\n this.settings = new Settings<Data>(datasource.settings, datasource.devSettings, ++instanceCount);\n this.logger = new Logger(this as Scroller, packageInfo, datasource.adapter);\n this.routines = new Routines(this.settings);\n this.state = new State(packageInfo, this.settings, scroller ? scroller.state : void 0);\n this.buffer = new Buffer<Data>(this.settings, workflow.onDataChanged, this.logger);\n this.viewport = new Viewport(element, this.settings, this.routines, this.state, this.logger);\n this.logger.object('vscroll settings object', this.settings, true);\n\n this.initDatasource(datasource, scroller);\n }\n\n initDatasource(datasource: IDatasource<Data>, scroller?: Scroller<Data>): void {\n if (scroller) { // scroller re-instantiating case\n this.datasource = datasource as IDatasourceConstructed<Data>;\n this.adapter = scroller.adapter;\n // todo: what about (this.settings.adapter !== scroller.setting.adapter) case?\n return;\n }\n // scroller is being instantiated for the first time\n const constructed = datasource instanceof DatasourceGeneric;\n const mockAdapter = !constructed && !this.settings.adapter;\n if (constructed) { // datasource is already instantiated\n this.datasource = datasource as IDatasourceConstructed<Data>;\n } else { // datasource as POJO\n const DS = makeDatasource(() => ({ mock: mockAdapter }));\n this.datasource = new DS<Data>(datasource);\n if (this.settings.adapter) {\n datasource.adapter = this.datasource.adapter;\n }\n }\n const publicContext = !mockAdapter ? this.datasource.adapter : null;\n this.adapter = new Adapter<Data>(publicContext, () => this.workflow, this.logger);\n }\n\n init(adapterRun$?: Reactive<ProcessSubject>): void {\n this.viewport.reset(this.buffer.startIndex);\n this.logger.stat('initialization');\n this.adapter.initialize(this.buffer, this.state, this.logger, adapterRun$);\n }\n\n dispose(forever?: boolean): void {\n if (forever) { // Adapter is not re-instantiated on reset\n this.adapter.dispose();\n }\n this.buffer.dispose();\n this.state.dispose();\n }\n\n finalize(): void {\n }\n\n}\n","import {\n CommonProcess,\n AdapterProcess,\n ProcessStatus as Status,\n Init,\n Scroll,\n Reset,\n Reload,\n Append,\n Check,\n Remove,\n UserClip,\n Insert,\n Replace,\n Update,\n Fix,\n Start,\n PreFetch,\n Fetch,\n PostFetch,\n Render,\n PreClip,\n Clip,\n Adjust,\n End,\n} from './processes/index';\n\nimport { StateMachineParams } from './interfaces/index';\n\nexport const runStateMachine = ({\n input: { process, status, payload = {} },\n methods: { run, interrupt, done, onError }\n}: StateMachineParams): void => {\n if (status === Status.error) {\n onError(process, payload);\n if (!process.startsWith('adapter')) {\n run(End)(payload);\n }\n return;\n }\n const { options } = payload;\n switch (process) {\n case CommonProcess.init:\n if (status === Status.start) { // App start\n run(Init)(process);\n }\n if (status === Status.next) {\n run(Start)();\n }\n break;\n case CommonProcess.scroll:\n if (status === Status.start) {\n run(Scroll)(payload);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.reset:\n case AdapterProcess.reload:\n if (status === Status.start) {\n if (process === AdapterProcess.reset) {\n run(Reset)(options);\n } else {\n run(Reload)(options);\n }\n }\n if (status === Status.next) {\n interrupt({ process, ...payload });\n if (payload.finalize) {\n run(End)();\n } else {\n run(Init)(process);\n }\n }\n break;\n case AdapterProcess.append:\n case AdapterProcess.prepend:\n if (status === Status.start) {\n run(Append)({ process, options });\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.check:\n if (status === Status.start) {\n run(Check)();\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.remove:\n if (status === Status.start) {\n run(Remove)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.clip:\n if (status === Status.start) {\n run(UserClip)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.insert:\n if (status === Status.start) {\n run(Insert)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.replace:\n if (status === Status.start) {\n run(Replace)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.update:\n if (status === Status.start) {\n run(Update)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.fix:\n if (status === Status.start) {\n run(Fix)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case CommonProcess.start:\n switch (payload.process) {\n case AdapterProcess.append:\n case AdapterProcess.insert:\n case AdapterProcess.replace:\n case AdapterProcess.update:\n if (payload.doRender) {\n run(Render)();\n } else {\n run(Adjust)();\n }\n break;\n case AdapterProcess.check:\n run(Render)();\n break;\n case AdapterProcess.remove:\n run(Adjust)();\n break;\n default:\n run(PreFetch)();\n }\n break;\n case CommonProcess.preFetch:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.clip:\n run(PreClip)();\n break;\n default:\n run(Fetch)();\n }\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.fetch:\n run(PostFetch)();\n break;\n case CommonProcess.postFetch:\n if (status === Status.next) {\n run(Render)();\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.render:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.append:\n case AdapterProcess.check:\n case AdapterProcess.insert:\n case AdapterProcess.replace:\n case AdapterProcess.update:\n run(Adjust)();\n break;\n default:\n run(PreClip)();\n }\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.preClip:\n if (payload.doClip) {\n run(Clip)();\n } else {\n run(Adjust)();\n }\n break;\n case CommonProcess.clip:\n run(Adjust)();\n break;\n case CommonProcess.adjust:\n run(End)();\n break;\n case CommonProcess.end:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.reset:\n case AdapterProcess.reload:\n done();\n run(Init)(payload.process);\n break;\n default:\n run(Start)();\n }\n }\n if (status === Status.done) {\n done();\n }\n break;\n }\n};\n","import { Scroller } from './scroller';\nimport { runStateMachine } from './workflow-transducer';\nimport { Reactive } from './classes/reactive';\nimport { Item } from './classes/item';\nimport { CommonProcess, ProcessStatus as Status, } from './processes/index';\nimport {\n WorkflowParams,\n ProcessName,\n ProcessPayload,\n ProcessClass,\n ProcessSubject,\n WorkflowError,\n InterruptParams,\n StateMachineMethods,\n ScrollerWorkflow,\n} from './interfaces/index';\n\nexport class Workflow<ItemData = unknown> {\n\n isInitialized: boolean;\n initTimer: ReturnType<typeof setTimeout> | null;\n adapterRun$: Reactive<ProcessSubject>;\n cyclesDone: number;\n interruptionCount: number;\n errors: WorkflowError[];\n\n private disposeScrollEventHandler: () => void;\n readonly propagateChanges: WorkflowParams<ItemData>['run'];\n readonly stateMachineMethods: StateMachineMethods<ItemData>;\n\n scroller: Scroller<ItemData>;\n\n constructor({ element, datasource, consumer, run }: WorkflowParams<ItemData>) {\n this.isInitialized = false;\n this.initTimer = null;\n this.adapterRun$ = new Reactive();\n this.cyclesDone = 0;\n this.interruptionCount = 0;\n this.errors = [];\n this.disposeScrollEventHandler = () => null;\n this.propagateChanges = run;\n this.stateMachineMethods = {\n run: this.runProcess(),\n interrupt: this.interrupt.bind(this),\n done: this.done.bind(this),\n onError: this.onError.bind(this)\n };\n\n this.scroller = new Scroller<ItemData>({ element, datasource, consumer, workflow: this.getUpdater() });\n\n if (this.scroller.settings.initializeDelay) {\n this.initTimer = setTimeout(() => {\n this.initTimer = null;\n this.init();\n }, this.scroller.settings.initializeDelay);\n } else {\n this.init();\n }\n }\n\n init(): void {\n this.scroller.init(this.adapterRun$);\n this.isInitialized = true;\n\n // run the Workflow\n this.callWorkflow({\n process: CommonProcess.init,\n status: Status.start\n });\n\n // set up scroll event listener\n const { scrollEventReceiver } = this.scroller.viewport;\n const onScrollHandler: EventListener =\n event => this.callWorkflow({\n process: CommonProcess.scroll,\n status: Status.start,\n payload: { event }\n });\n scrollEventReceiver.addEventListener('scroll', onScrollHandler);\n this.disposeScrollEventHandler = () =>\n scrollEventReceiver.removeEventListener('scroll', onScrollHandler);\n }\n\n changeItems(items: Item<ItemData>[]): void {\n this.propagateChanges(items);\n }\n\n callWorkflow(processSubject: ProcessSubject): void {\n if (!this.isInitialized) {\n return;\n }\n const { process, status } = processSubject;\n if (process && process.startsWith('adapter') && status !== Status.next) {\n this.adapterRun$.set(processSubject);\n }\n this.process(processSubject);\n }\n\n getUpdater(): ScrollerWorkflow<ItemData> {\n return {\n call: this.callWorkflow.bind(this),\n onDataChanged: this.changeItems.bind(this),\n };\n }\n\n process(data: ProcessSubject): void {\n const { status, process, payload } = data;\n if (this.scroller.settings.logProcessRun) {\n this.scroller.logger.log(() => [\n '%cfire%c', ...['color: #cc7777;', 'color: #000000;'],\n process, `\"${status}\"`, ...(payload !== void 0 ? [payload] : [])\n ]);\n }\n this.scroller.logger.logProcess(data);\n\n if (process === CommonProcess.end) {\n this.scroller.finalize();\n }\n runStateMachine({\n input: data,\n methods: this.stateMachineMethods as StateMachineMethods<unknown>\n });\n }\n\n runProcess() {\n return ({ run, process, name }: ProcessClass) =>\n (...args: any[]): void => {\n if (this.scroller.settings.logProcessRun) {\n this.scroller.logger.log(() => [\n '%crun%c', ...['color: #333399;', 'color: #000000;'],\n process || name, ...args\n ]);\n }\n run(this.scroller as Scroller, ...args);\n };\n }\n\n onError(process: ProcessName, payload?: ProcessPayload): void {\n const message: string = payload && String(payload.error) || '';\n const { time, cycle } = this.scroller.state;\n this.errors.push({\n process,\n message,\n time,\n loop: cycle.loopIdNext\n });\n this.scroller.logger.logError(message);\n }\n\n interrupt({ process, finalize, datasource }: InterruptParams<ItemData>): void {\n if (finalize) {\n const { workflow, logger } = this.scroller;\n // we are going to create a new reference for the scroller.workflow object\n // calling the old version of the scroller.workflow by any outstanding async processes will be skipped\n workflow.call = (p: ProcessSubject) => // eslint-disable-line @typescript-eslint/no-unused-vars\n logger.log('[skip wf call]');\n workflow.call.interrupted = true;\n this.scroller.workflow = this.getUpdater();\n this.interruptionCount++;\n logger.log(() => `workflow had been interrupted by the ${process} process (${this.interruptionCount})`);\n }\n if (datasource) { // Scroller re-initialization case\n this.scroller.adapter.relax(() => {\n this.scroller.logger.log('new Scroller instantiation');\n const scroller = new Scroller<ItemData>({ datasource, scroller: this.scroller });\n this.scroller.dispose();\n this.scroller = scroller;\n this.scroller.init();\n });\n }\n }\n\n done(): void {\n const { state, logger } = this.scroller;\n this.cyclesDone++;\n logger.logCycle(false);\n state.cycle.done(this.cyclesDone + 1);\n this.finalize();\n }\n\n dispose(): void {\n if (this.initTimer) {\n clearTimeout(this.initTimer);\n }\n this.disposeScrollEventHandler();\n this.adapterRun$.dispose();\n this.scroller.dispose(true);\n Object.getOwnPropertyNames(this).forEach(prop => {\n delete (this as Record<string, unknown>)[prop];\n });\n }\n\n finalize(): void {\n }\n\n}\n"],"names":["instanceCount","OBJECT","FUNC_WITH_X_AND_MORE_ARGUMENTS","INTEGER","INTEGER_UNLIMITED","BOOLEAN","OR","Settings"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vscroll.esm5.js","sources":["../../src/classes/reactive.ts","../../src/classes/adapter/props.ts","../../src/version.ts","../../src/classes/adapter/context.ts","../../src/classes/datasource.ts","../../src/inputs/common.ts","../../src/inputs/validation.ts","../../src/inputs/datasource.ts","../../src/inputs/settings.ts","../../src/processes/misc/enums.ts","../../src/inputs/adapter.ts","../../src/classes/settings.ts","../../src/processes/misc/base.ts","../../src/processes/init.ts","../../src/processes/scroll.ts","../../src/processes/adapter/reset.ts","../../src/processes/adapter/reload.ts","../../src/classes/item.ts","../../src/processes/adapter/update.ts","../../src/processes/adapter/insert.ts","../../src/processes/adapter/append.ts","../../src/processes/adapter/check.ts","../../src/processes/adapter/remove.ts","../../src/processes/adapter/clip.ts","../../src/processes/adapter/replace.ts","../../src/processes/adapter/fix.ts","../../src/processes/start.ts","../../src/processes/preFetch.ts","../../src/processes/fetch.ts","../../src/processes/postFetch.ts","../../src/processes/render.ts","../../src/processes/end.ts","../../src/processes/adjust.ts","../../src/processes/preClip.ts","../../src/processes/clip.ts","../../src/classes/logger.ts","../../src/classes/domRoutines.ts","../../src/classes/paddings.ts","../../src/classes/viewport.ts","../../src/classes/buffer/defaultSize.ts","../../src/classes/buffer/cache.ts","../../src/classes/buffer/checkCall.ts","../../src/classes/buffer.ts","../../src/classes/state/cycle.ts","../../src/classes/state/fetch.ts","../../src/classes/state/clip.ts","../../src/classes/state/render.ts","../../src/classes/state/scroll.ts","../../src/classes/state.ts","../../src/classes/adapter.ts","../../src/scroller.ts","../../src/workflow-transducer.ts","../../src/workflow.ts"],"sourcesContent":["type On<T> = (value: T) => void;\ntype Off = () => void;\n\ninterface Subscription<T> {\n emit: On<T>;\n off: Off;\n}\n\ninterface Options {\n emitOnSubscribe?: boolean; // if set, emit right on subscribe (like rxjs BehaviorSubject)\n emitEqual?: boolean; // if set, emit when new value is equal to the old one\n}\n\nexport class Reactive<T> {\n\n private initialValue: T;\n private value: T;\n private id: number;\n private options: Options;\n private subscriptions: Map<number, Subscription<T>>;\n\n constructor(value?: T, options?: Options) {\n this.id = 0;\n if (value !== void 0) {\n this.value = value;\n this.initialValue = value;\n }\n this.options = options || {};\n this.subscriptions = new Map();\n }\n\n set(value: T): void {\n if (this.value === value && !this.options.emitEqual) {\n return;\n }\n this.value = value;\n for (const [, sub] of this.subscriptions) {\n sub.emit(value);\n if (this.value !== value) {\n break;\n }\n }\n }\n\n get(): T {\n return this.value;\n }\n\n on(func: On<T>): Off {\n const id = this.id++;\n const subscription: Subscription<T> = {\n emit: func,\n off: () => {\n subscription.emit = () => null;\n this.subscriptions.delete(id);\n }\n };\n this.subscriptions.set(id, subscription);\n if (this.options.emitOnSubscribe) {\n subscription.emit(this.value);\n }\n return () => subscription.off();\n }\n\n once(func: On<T>): Off {\n const off = this.on(v => {\n off();\n func(v);\n });\n return off;\n }\n\n reset(): void {\n this.set(this.initialValue);\n }\n\n dispose(): void {\n this.subscriptions.forEach(sub => sub.off());\n }\n}\n","import { Reactive } from '../reactive';\nimport {\n IAdapterProp, IBufferInfo, ItemAdapter, IPackages, AdapterMethodResult, IReactivePropsStore\n} from '../../interfaces/index';\n\nexport enum AdapterPropName {\n id = 'id',\n mock = 'mock',\n augmented = 'augmented',\n version = 'version',\n init = 'init',\n init$ = 'init$',\n packageInfo = 'packageInfo',\n itemsCount = 'itemsCount',\n bufferInfo = 'bufferInfo',\n isLoading = 'isLoading',\n isLoading$ = 'isLoading$',\n loopPending = 'loopPending',\n loopPending$ = 'loopPending$',\n firstVisible = 'firstVisible',\n firstVisible$ = 'firstVisible$',\n lastVisible = 'lastVisible',\n lastVisible$ = 'lastVisible$',\n bof = 'bof',\n bof$ = 'bof$',\n eof = 'eof',\n eof$ = 'eof$',\n reset = 'reset',\n reload = 'reload',\n append = 'append',\n prepend = 'prepend',\n check = 'check',\n remove = 'remove',\n clip = 'clip',\n insert = 'insert',\n replace = 'replace',\n update = 'update',\n fix = 'fix',\n relax = 'relax',\n showLog = 'showLog',\n}\n\nexport enum AdapterPropType {\n Scalar,\n Reactive,\n WorkflowRunner,\n Function,\n}\n\nconst Name = AdapterPropName;\nconst Type = AdapterPropType;\n\nconst noop = () => null;\n\nexport const methodPreResult: AdapterMethodResult = {\n immediate: true,\n success: true,\n details: 'Adapter is not initialized'\n};\n\nconst noopWF = () => Promise.resolve(methodPreResult);\n\nconst emptyPackageInfo: IPackages = {\n core: {\n name: '',\n version: ''\n },\n consumer: {\n name: '',\n version: ''\n }\n};\n\nconst bufferInfoDefault: IBufferInfo = {\n firstIndex: NaN,\n lastIndex: NaN,\n minIndex: NaN,\n maxIndex: NaN,\n absMinIndex: -Infinity,\n absMaxIndex: +Infinity,\n defaultSize: NaN,\n};\n\nexport const EMPTY_ITEM = {\n data: {},\n element: {}\n} as ItemAdapter;\n\nexport const getDefaultAdapterProps = (): IAdapterProp[] => [\n {\n type: Type.Scalar,\n name: Name.id,\n value: 0,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.mock,\n value: true,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.augmented,\n value: false,\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.version,\n value: '',\n permanent: true\n },\n {\n type: Type.Scalar,\n name: Name.init,\n value: false,\n reactive: Name.init$\n },\n {\n type: Type.Scalar,\n name: Name.packageInfo,\n value: emptyPackageInfo,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.itemsCount,\n value: 0,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.bufferInfo,\n value: bufferInfoDefault,\n onDemand: true\n },\n {\n type: Type.Scalar,\n name: Name.isLoading,\n value: false,\n reactive: Name.isLoading$\n },\n {\n type: Type.Scalar,\n name: Name.loopPending,\n value: false,\n reactive: Name.loopPending$\n },\n {\n type: Type.Scalar,\n name: Name.firstVisible,\n value: EMPTY_ITEM,\n reactive: Name.firstVisible$,\n wanted: true\n },\n {\n type: Type.Scalar,\n name: Name.lastVisible,\n value: EMPTY_ITEM,\n reactive: Name.lastVisible$,\n wanted: true\n },\n {\n type: Type.Scalar,\n name: Name.bof,\n value: false,\n reactive: Name.bof$\n },\n {\n type: Type.Scalar,\n name: Name.eof,\n value: false,\n reactive: Name.eof$\n },\n {\n type: Type.WorkflowRunner,\n name: Name.reset,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.reload,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.append,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.prepend,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.check,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.remove,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.clip,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.insert,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.replace,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.update,\n value: noopWF\n },\n {\n type: Type.WorkflowRunner,\n name: Name.fix,\n value: noopWF\n },\n {\n type: Type.Function,\n name: Name.relax,\n value: noop\n },\n {\n type: Type.Function,\n name: Name.showLog,\n value: noop\n },\n {\n type: Type.Reactive,\n name: Name.init$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.isLoading$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.loopPending$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.firstVisible$,\n value: new Reactive<ItemAdapter>(EMPTY_ITEM, { emitOnSubscribe: true })\n },\n {\n type: Type.Reactive,\n name: Name.lastVisible$,\n value: new Reactive<ItemAdapter>(EMPTY_ITEM, { emitOnSubscribe: true })\n },\n {\n type: Type.Reactive,\n name: Name.bof$,\n value: new Reactive<boolean>()\n },\n {\n type: Type.Reactive,\n name: Name.eof$,\n value: new Reactive<boolean>()\n }\n];\n\nexport const reactiveConfigStorage = new Map<number, IReactivePropsStore>();\n","export default {\n name: 'vscroll',\n version: '1.4.3'\n};\n","import { AdapterPropName, AdapterPropType, getDefaultAdapterProps, reactiveConfigStorage } from './props';\nimport core from '../../version';\nimport { Reactive } from '../reactive';\nimport { IReactivePropsStore, IAdapterConfig } from '../../interfaces/index';\n\nlet instanceCount = 0;\n\nexport class AdapterContext {\n\n constructor(config: IAdapterConfig) {\n const { mock, reactive } = config;\n const id = ++instanceCount;\n const conf = { configurable: true };\n const reactivePropsStore: IReactivePropsStore = {};\n\n // set up permanent props\n Object.defineProperty(this, AdapterPropName.id, { get: () => id, ...conf });\n Object.defineProperty(this, AdapterPropName.mock, { get: () => mock, ...conf });\n Object.defineProperty(this, AdapterPropName.augmented, { get: () => false, ...conf });\n Object.defineProperty(this, AdapterPropName.version, { get: () => core.version, ...conf });\n\n // set up default props, they will be reassigned during the Adapter instantiation\n getDefaultAdapterProps()\n .filter(({ permanent }) => !permanent)\n .forEach(({ name, value, type }) => {\n\n // reactive props might be reconfigured by the vscroll consumer\n if (reactive && type === AdapterPropType.Reactive) {\n const react = reactive[name];\n if (react) {\n // here we have a configured reactive property that came from the outer config\n // this prop must be exposed via Adapter, but at the same time we need to\n // persist the original default value as it will be used by the Adapter internally\n reactivePropsStore[name] = {\n ...react,\n default: value as Reactive<unknown> // persisting the default native Reactive prop\n };\n value = react.source; // exposing the configured prop instead of the default one\n }\n }\n\n Object.defineProperty(this, name, {\n get: () => value,\n ...conf\n });\n });\n\n if (reactive) { // save both configured and default reactive props in the store\n reactiveConfigStorage.set(id, reactivePropsStore);\n }\n }\n}\n","import { AdapterContext } from './adapter/context';\r\nimport { reactiveConfigStorage } from './adapter/props';\r\nimport {\r\n IDatasource,\r\n IDatasourceConstructed,\r\n DatasourceGet,\r\n Settings,\r\n DevSettings,\r\n IAdapter,\r\n IAdapterConfig,\r\n} from '../interfaces/index';\r\n\r\nexport class DatasourceGeneric<Data> implements IDatasourceConstructed<Data> {\r\n get: DatasourceGet<Data>;\r\n settings?: Settings<Data>;\r\n devSettings?: DevSettings;\r\n adapter: IAdapter<Data>;\r\n\r\n constructor(datasource: IDatasource<Data>, config?: IAdapterConfig) {\r\n this.get = datasource.get;\r\n if (datasource.settings) {\r\n this.settings = datasource.settings;\r\n }\r\n if (datasource.devSettings) {\r\n this.devSettings = datasource.devSettings;\r\n }\r\n const adapterContext = new AdapterContext(config || { mock: false });\r\n this.adapter = adapterContext as IAdapter<Data>;\r\n }\r\n\r\n dispose(): void { // todo: should it be published?\r\n reactiveConfigStorage.delete(this.adapter.id);\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\r\nexport const makeDatasource = (getConfig?: () => IAdapterConfig) =>\r\n class <Data = unknown> extends DatasourceGeneric<Data> {\r\n constructor(datasource: IDatasource<Data>) {\r\n const config = typeof getConfig === 'function' ? getConfig() : void 0;\r\n super(datasource, config);\r\n }\r\n };\r\n\r\nexport const Datasource = makeDatasource();\r\n","export enum Direction {\n forward = 'forward',\n backward = 'backward'\n}\n\nexport enum SizeStrategy {\n Average = 'average',\n Constant = 'constant',\n Frequent = 'frequent'\n}\n","import { IValidationContext } from '../interfaces/validation';\nimport {\n IValidator,\n ValidatedValue,\n IValidatedData,\n IValidatedCommonProps,\n ICommonProps,\n ICommonProp,\n} from '../interfaces/index';\n\nexport enum ValidatorType {\n number = 'must be a number',\n integer = 'must be an integer',\n integerUnlimited = 'must be an integer or infinity',\n moreOrEqual = 'must be a number greater than (or equal to) {arg1}',\n itemList = 'must be an array of items {arg1}',\n boolean = 'must be a boolean',\n object = 'must be an object',\n element = 'must be an html element',\n function = 'must be a function',\n funcOfxArguments = 'must have {arg1} argument(s)',\n funcOfxAndMoreArguments = 'must have at least {arg1} argument(s)',\n funcOfXToYArguments = 'must have {arg1} to {arg2} arguments',\n oneOfCan = 'can be present as only one item of {arg1} list',\n oneOfMust = 'must be present as only one item of {arg1} list',\n or = 'must satisfy at least 1 validator from {arg1} list',\n enum = 'must belong to {arg1} list',\n}\n\nconst getError = (msg: ValidatorType, args?: string[]) =>\n (args || ['']).reduce((acc, arg, index) => acc.replace(`{arg${index + 1}}`, arg), msg);\n\nconst getNumber = (value: unknown): number =>\n typeof value === 'number' || (typeof value === 'string' && value !== '')\n ? Number(value)\n : NaN;\n\nconst onNumber = (value: unknown): ValidatedValue => {\n const parsedValue = getNumber(value);\n const errors = [];\n if (Number.isNaN(parsedValue)) {\n errors.push(ValidatorType.number);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onInteger = (value: unknown): ValidatedValue => {\n const errors = [];\n value = getNumber(value);\n const parsedValue = parseInt(String(value), 10);\n if (value !== parsedValue) {\n errors.push(ValidatorType.integer);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onIntegerUnlimited = (value: unknown): ValidatedValue => {\n let parsedValue = value;\n const errors = [];\n value = getNumber(value);\n if (!Number.isFinite(value)) {\n parsedValue = value;\n } else {\n parsedValue = parseInt(String(value), 10);\n }\n if (value !== parsedValue) {\n errors.push(ValidatorType.integerUnlimited);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onMoreOrEqual = (limit: number, fallback?: boolean) => (value: unknown): ValidatedValue => {\n const result = onNumber(value);\n if (!result.isValid) {\n return result;\n }\n let parsedValue = result.value as number;\n const errors = [];\n if (parsedValue < limit) {\n if (!fallback) {\n errors.push(getError(ValidatorType.moreOrEqual, [String(limit)]));\n } else {\n parsedValue = limit;\n }\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onBoolean = (value: unknown): ValidatedValue => {\n const errors = [];\n let parsedValue = value;\n if (value === 'true') {\n parsedValue = true;\n } else if (value === 'false') {\n parsedValue = false;\n }\n if (typeof parsedValue !== 'boolean') {\n errors.push(ValidatorType.boolean);\n }\n return { value: parsedValue, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onObject = (value: unknown): ValidatedValue => {\n const errors = [];\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n errors.push(ValidatorType.object);\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onHtmlElement = (value: unknown): ValidatedValue => {\n const errors = [];\n if (!(value instanceof Element) && !(value instanceof HTMLDocument)) {\n errors.push(ValidatorType.element);\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onItemList = (value: unknown): ValidatedValue => {\n let parsedValue = value;\n const errors = [];\n if (!Array.isArray(value)) {\n errors.push(ValidatorType.itemList);\n parsedValue = [];\n } else if (!value.length) {\n errors.push(getError(ValidatorType.itemList, ['with at least 1 item']));\n } else if (value.length > 1) {\n const type = typeof value[0];\n for (let i = value.length - 1; i >= 0; i--) {\n if (typeof value[i] !== type) {\n errors.push(getError(ValidatorType.itemList, ['of items of the same type']));\n break;\n }\n }\n }\n return { value: parsedValue as unknown[], isSet: true, isValid: !errors.length, errors };\n};\n\ntype Func = (...args: any[]) => void;\n\nconst onFunction = (value: unknown): ValidatedValue => {\n const errors = [];\n if (typeof value !== 'function') {\n errors.push(ValidatorType.function);\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXArguments = (argsCount: number) => (value: unknown) => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length !== argsCount) {\n errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXAndMoreArguments = (argsCount: number) => (value: unknown): ValidatedValue => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length < argsCount) {\n errors.push(getError(ValidatorType.funcOfxArguments, [String(argsCount)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onFunctionWithXToYArguments = (from: number, to: number) => (value: unknown): ValidatedValue => {\n const result = onFunction(value);\n if (!result.isValid) {\n return result;\n }\n value = result.value;\n const errors = [];\n if ((value as Func).length < from || (value as Func).length > to) {\n errors.push(getError(ValidatorType.funcOfXToYArguments, [String(from), String(to)]));\n }\n return { value: value as Func, isSet: true, isValid: !errors.length, errors };\n};\n\nconst onOneOf = (tokens: string[], must: boolean) => (value: unknown, context?: IValidationContext): ValidatedValue => {\n const errors = [];\n const isSet = value !== void 0;\n let noOneIsPresent = !isSet;\n const err = must ? ValidatorType.oneOfMust : ValidatorType.oneOfCan;\n if (!Array.isArray(tokens) || !tokens.length) {\n errors.push(getError(err, ['undefined']));\n } else {\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i];\n if (typeof token !== 'string') {\n errors.push(getError(err, [tokens.join('\", \"')]) + ' (non-string token)');\n break;\n }\n const isAnotherPresent = context && Object.prototype.hasOwnProperty.call(context, token);\n if (isSet && isAnotherPresent) {\n errors.push(getError(err, [tokens.join('\", \"')]) + ` (${token} is present)`);\n break;\n }\n if (noOneIsPresent && isAnotherPresent) {\n noOneIsPresent = false;\n }\n }\n if (must && noOneIsPresent) {\n errors.push(getError(err, [tokens.join('\", \"')]));\n }\n }\n return { value, isSet, isValid: !errors.length, errors };\n};\n\nconst onOr = (validators: IValidator[]) => (value: unknown): ValidatedValue => {\n const errors = [];\n if (validators.every(validator => !validator.method(value).isValid)) {\n errors.push(validators.map(v => v.type).join(' OR '));\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nenum AbstractEnum { }\ntype TEnum = typeof AbstractEnum;\n\nconst onEnum = (list: TEnum) => (value: unknown): ValidatedValue => {\n const errors = [];\n const values = Object.keys(list).filter(k => isNaN(Number(k))).map(k => list[k as unknown as number]);\n if (!values.some(item => item === value)) {\n errors.push(getError(ValidatorType.enum, ['[' + values.join(',') + ']']));\n }\n return { value, isSet: true, isValid: !errors.length, errors };\n};\n\nexport const VALIDATORS = {\n NUMBER: {\n type: ValidatorType.number,\n method: onNumber\n },\n INTEGER: {\n type: ValidatorType.integer,\n method: onInteger\n },\n INTEGER_UNLIMITED: {\n type: ValidatorType.integerUnlimited,\n method: onIntegerUnlimited\n },\n MORE_OR_EQUAL: (limit: number, fallback?: boolean): IValidator => ({\n type: ValidatorType.moreOrEqual,\n method: onMoreOrEqual(limit, fallback)\n }),\n BOOLEAN: {\n type: ValidatorType.boolean,\n method: onBoolean\n },\n OBJECT: {\n type: ValidatorType.object,\n method: onObject\n },\n ITEM_LIST: {\n type: ValidatorType.itemList,\n method: onItemList\n },\n ELEMENT: {\n type: ValidatorType.element,\n method: onHtmlElement\n },\n FUNC: {\n type: ValidatorType.function,\n method: onFunction\n },\n FUNC_WITH_X_ARGUMENTS: (count: number): IValidator => ({\n type: ValidatorType.funcOfxArguments,\n method: onFunctionWithXArguments(count)\n }),\n FUNC_WITH_X_AND_MORE_ARGUMENTS: (count: number): IValidator => ({\n type: ValidatorType.funcOfxAndMoreArguments,\n method: onFunctionWithXAndMoreArguments(count)\n }),\n FUNC_WITH_X_TO_Y_ARGUMENTS: (from: number, to: number): IValidator => ({\n type: ValidatorType.funcOfXToYArguments,\n method: onFunctionWithXToYArguments(from, to)\n }),\n ONE_OF_CAN: (list: string[]): IValidator => ({\n type: ValidatorType.oneOfCan,\n method: onOneOf(list, false)\n }),\n ONE_OF_MUST: (list: string[]): IValidator => ({\n type: ValidatorType.oneOfMust,\n method: onOneOf(list, true)\n }),\n OR: (list: IValidator[]): IValidator => ({\n type: ValidatorType.or,\n method: onOr(list)\n }),\n ENUM: (list: TEnum): IValidator => ({\n type: ValidatorType.enum,\n method: onEnum(list)\n })\n};\n\nexport class ValidatedData implements IValidatedData {\n\n context: IValidationContext;\n isValidContext: boolean;\n isValid: boolean;\n errors: string[];\n params: IValidatedCommonProps<PropertyKey>;\n\n private contextErrors: string[];\n\n constructor(context: unknown) {\n this.params = {};\n this.contextErrors = [];\n this.errors = [];\n this.isValid = true;\n this.setContext(context);\n }\n\n private setContext(context: unknown): void {\n if (!context || Object.prototype.toString.call(context) !== '[object Object]') {\n this.setCommonError('context is not an object');\n this.isValidContext = false;\n } else {\n this.isValidContext = true;\n }\n this.context = context as IValidationContext;\n }\n\n private setValidity() {\n this.errors = Object.keys(this.params).reduce((acc: string[], key: string) => [\n ...acc, ...this.params[key].errors\n ], []);\n this.isValid = !this.errors.length;\n }\n\n setCommonError(error: string): void {\n this.contextErrors.push(error);\n this.errors.push(error);\n this.isValid = false;\n }\n\n setParam(token: string, value: ValidatedValue): void {\n if (!value.isValid) {\n value.errors = !value.isSet\n ? [`\"${token}\" must be set`]\n : value.errors.map((err: string) =>\n `\"${token}\" ${err}`\n );\n }\n this.params[token] = value;\n this.setValidity();\n }\n\n showErrors(): string {\n return this.errors.length\n ? 'validation failed: ' + this.errors.join(', ')\n : '';\n }\n}\n\nexport const runValidator = (\n current: ValidatedValue,\n validator: IValidator,\n context: IValidationContext\n): ValidatedValue => {\n const { value, errors } = current;\n const result = validator.method(value, context);\n const _errors = [...errors, ...result.errors];\n return {\n value: result.value,\n isSet: result.isSet,\n isValid: !_errors.length,\n errors: _errors\n };\n};\n\nconst getDefault = (value: unknown, prop: ICommonProp): ValidatedValue => {\n const empty = value === void 0;\n const auto = !prop.mandatory && prop.defaultValue !== void 0;\n return {\n value: !empty ? value : (auto ? prop.defaultValue : void 0),\n isSet: !empty || auto,\n isValid: !empty || !prop.mandatory,\n errors: []\n };\n};\n\nexport const validateOne = (\n context: IValidationContext, name: string, prop: ICommonProp\n): ValidatedValue => {\n const result = getDefault(context[name], prop);\n if (!result.isSet) {\n const oneOfMust = prop.validators.find(v => v.type === ValidatorType.oneOfMust);\n if (oneOfMust) {\n return runValidator(result, oneOfMust, context);\n }\n } else {\n for (const validator of Object.values(prop.validators)) {\n const current = runValidator(result, validator, context);\n if (!current.isValid && prop.defaultValue !== void 0) {\n return {\n value: prop.defaultValue,\n isSet: true,\n isValid: true,\n errors: []\n };\n }\n Object.assign(result, current);\n }\n }\n return result;\n};\n\nexport const validate = (\n context: unknown, params: ICommonProps<PropertyKey>\n): IValidatedData => {\n const data = new ValidatedData(context);\n Object.entries(params).forEach(([key, prop]) =>\n data.setParam(key, data.isValidContext\n ? validateOne(data.context, key, prop)\n : getDefault(void 0, prop)\n )\n );\n return data;\n};\n","import { VALIDATORS } from './validation';\nimport { ICommonProps } from '../interfaces/index';\n\nconst { OBJECT, FUNC_WITH_X_AND_MORE_ARGUMENTS } = VALIDATORS;\n\nexport enum DatasourceProps {\n get = 'get',\n settings = 'settings',\n devSettings = 'devSettings',\n}\n\nexport const DATASOURCE: ICommonProps<DatasourceProps> = {\n [DatasourceProps.get]: {\n validators: [FUNC_WITH_X_AND_MORE_ARGUMENTS(2)],\n mandatory: true\n },\n [DatasourceProps.settings]: {\n validators: [OBJECT]\n },\n [DatasourceProps.devSettings]: {\n validators: [OBJECT]\n }\n};\n","import { VALIDATORS } from './validation';\nimport { ICommonProps } from '../interfaces/index';\nimport { SizeStrategy, Direction } from './common';\n\nconst { NUMBER, INTEGER, INTEGER_UNLIMITED, MORE_OR_EQUAL, BOOLEAN, ELEMENT, FUNC, OR, ENUM } = VALIDATORS;\n\nenum Settings {\n adapter = 'adapter',\n startIndex = 'startIndex',\n minIndex = 'minIndex',\n maxIndex = 'maxIndex',\n itemSize = 'itemSize',\n bufferSize = 'bufferSize',\n padding = 'padding',\n infinite = 'infinite',\n horizontal = 'horizontal',\n windowViewport = 'windowViewport',\n viewportElement = 'viewportElement',\n inverse = 'inverse',\n onBeforeClip = 'onBeforeClip',\n sizeStrategy = 'sizeStrategy',\n}\n\nenum DevSettings {\n debug = 'debug',\n immediateLog = 'immediateLog',\n logProcessRun = 'logProcessRun',\n logTime = 'logTime',\n throttle = 'throttle',\n initDelay = 'initDelay',\n initWindowDelay = 'initWindowDelay',\n cacheData = 'cacheData',\n cacheOnReload = 'cacheOnReload',\n dismissOverflowAnchor = 'dismissOverflowAnchor',\n directionPriority = 'directionPriority',\n}\n\nexport const MIN = {\n [Settings.itemSize]: 1,\n [Settings.bufferSize]: 1,\n [Settings.padding]: 0.01,\n [DevSettings.throttle]: 0,\n [DevSettings.initDelay]: 0,\n [DevSettings.initWindowDelay]: 0,\n};\n\nexport const SETTINGS: ICommonProps<Settings> = {\n [Settings.adapter]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.startIndex]: {\n validators: [INTEGER],\n defaultValue: 1\n },\n [Settings.minIndex]: {\n validators: [INTEGER_UNLIMITED],\n defaultValue: -Infinity\n },\n [Settings.maxIndex]: {\n validators: [INTEGER_UNLIMITED],\n defaultValue: Infinity\n },\n [Settings.itemSize]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[Settings.itemSize], true)],\n defaultValue: NaN\n },\n [Settings.bufferSize]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[Settings.bufferSize], true)],\n defaultValue: 5\n },\n [Settings.padding]: {\n validators: [NUMBER, MORE_OR_EQUAL(MIN[Settings.padding], true)],\n defaultValue: 0.5\n },\n [Settings.infinite]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.horizontal]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.windowViewport]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.viewportElement]: {\n validators: [OR([ELEMENT, FUNC])],\n defaultValue: null\n },\n [Settings.inverse]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [Settings.onBeforeClip]: {\n validators: [FUNC],\n defaultValue: null\n },\n [Settings.sizeStrategy]: {\n validators: [ENUM(SizeStrategy)],\n defaultValue: SizeStrategy.Average\n },\n};\n\nexport const DEV_SETTINGS: ICommonProps<DevSettings> = {\n [DevSettings.debug]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.immediateLog]: {\n validators: [BOOLEAN],\n defaultValue: true\n },\n [DevSettings.logProcessRun]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.logTime]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.throttle]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.throttle], true)],\n defaultValue: 40\n },\n [DevSettings.initDelay]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.initDelay], true)],\n defaultValue: 1\n },\n [DevSettings.initWindowDelay]: {\n validators: [INTEGER, MORE_OR_EQUAL(MIN[DevSettings.initWindowDelay], true)],\n defaultValue: 40\n },\n [DevSettings.cacheData]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.cacheOnReload]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [DevSettings.dismissOverflowAnchor]: {\n validators: [BOOLEAN],\n defaultValue: true\n },\n [DevSettings.directionPriority]: {\n validators: [ENUM(Direction)],\n defaultValue: Direction.backward\n },\n};\n","export enum CommonProcess {\n init = 'init',\n scroll = 'scroll',\n start = 'start',\n preFetch = 'preFetch',\n fetch = 'fetch',\n postFetch = 'postFetch',\n render = 'render',\n preClip = 'preClip',\n clip = 'clip',\n adjust = 'adjust',\n end = 'end',\n}\n\nexport enum AdapterProcess {\n reset = 'adapter.reset',\n reload = 'adapter.reload',\n append = 'adapter.append',\n prepend = 'adapter.prepend',\n check = 'adapter.check',\n remove = 'adapter.remove',\n replace = 'adapter.replace',\n update = 'adapter.update',\n clip = 'adapter.clip',\n insert = 'adapter.insert',\n fix = 'adapter.fix',\n}\n\nexport enum ProcessStatus {\n start = 'start',\n next = 'next',\n done = 'done',\n error = 'error'\n}\n","import { VALIDATORS } from './validation';\nimport { DatasourceProps as AdapterResetParams } from './datasource';\nimport { AdapterProcess as Process } from '../processes/misc/enums';\nimport { ICommonProps, AdapterProcessMap } from '../interfaces/index';\n\nconst {\n INTEGER,\n INTEGER_UNLIMITED,\n BOOLEAN,\n OBJECT,\n ITEM_LIST,\n FUNC_WITH_X_ARGUMENTS,\n FUNC_WITH_X_AND_MORE_ARGUMENTS,\n FUNC_WITH_X_TO_Y_ARGUMENTS,\n ONE_OF_MUST,\n ONE_OF_CAN,\n OR,\n} = VALIDATORS;\n\nenum AdapterNoParams { }\nconst NO_METHOD_PARAMS: ICommonProps<AdapterNoParams> = {};\n\nconst RESET_METHOD_PARAMS: ICommonProps<AdapterResetParams> = {\n [AdapterResetParams.get]: {\n validators: [FUNC_WITH_X_AND_MORE_ARGUMENTS(2)]\n },\n [AdapterResetParams.settings]: {\n validators: [OBJECT]\n },\n [AdapterResetParams.devSettings]: {\n validators: [OBJECT]\n },\n};\n\nenum AdapterReloadParams {\n reloadIndex = 'reloadIndex',\n}\n\nconst RELOAD_METHOD_PARAMS: ICommonProps<AdapterReloadParams> = {\n [AdapterReloadParams.reloadIndex]: {\n validators: [INTEGER]\n },\n};\n\nenum AdapterPrependParams {\n items = 'items',\n bof = 'bof',\n increase = 'increase',\n}\n\nconst PREPEND_METHOD_PARAMS: ICommonProps<AdapterPrependParams> = {\n [AdapterPrependParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterPrependParams.bof]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [AdapterPrependParams.increase]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterAppendParams {\n items = 'items',\n eof = 'eof',\n decrease = 'decrease',\n}\n\nconst APPEND_METHOD_PARAMS: ICommonProps<AdapterAppendParams> = {\n [AdapterAppendParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterAppendParams.eof]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n [AdapterAppendParams.decrease]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterRemoveParams {\n predicate = 'predicate',\n indexes = 'indexes',\n increase = 'increase',\n}\n\nconst REMOVE_METHOD_PARAMS: ICommonProps<AdapterRemoveParams> = {\n [AdapterRemoveParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([AdapterRemoveParams.indexes])]\n },\n [AdapterRemoveParams.indexes]: {\n validators: [ITEM_LIST, ONE_OF_MUST([AdapterRemoveParams.predicate])]\n },\n [AdapterRemoveParams.increase]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterClipParams {\n backwardOnly = 'backwardOnly',\n forwardOnly = 'forwardOnly',\n}\n\nconst CLIP_METHOD_PARAMS: ICommonProps<AdapterClipParams> = {\n [AdapterClipParams.backwardOnly]: {\n validators: [BOOLEAN, ONE_OF_CAN([AdapterClipParams.forwardOnly])],\n defaultValue: false\n },\n [AdapterClipParams.forwardOnly]: {\n validators: [BOOLEAN, ONE_OF_CAN([AdapterClipParams.backwardOnly])],\n defaultValue: false\n },\n};\n\nenum AdapterInsertParams {\n items = 'items',\n before = 'before',\n after = 'after',\n beforeIndex = 'beforeIndex',\n afterIndex = 'afterIndex',\n decrease = 'decrease',\n}\n\nconst INSERT_METHOD_PARAMS: ICommonProps<AdapterInsertParams> = {\n [AdapterInsertParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterInsertParams.before]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([\n AdapterInsertParams.after, AdapterInsertParams.beforeIndex, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.after]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1), ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.beforeIndex, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.beforeIndex]: {\n validators: [INTEGER, ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.after, AdapterInsertParams.afterIndex\n ])]\n },\n [AdapterInsertParams.afterIndex]: {\n validators: [INTEGER, ONE_OF_MUST([\n AdapterInsertParams.before, AdapterInsertParams.after, AdapterInsertParams.beforeIndex\n ])]\n },\n [AdapterInsertParams.decrease]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterReplaceParams {\n items = 'items',\n predicate = 'predicate',\n fixRight = 'fixRight',\n}\n\nconst REPLACE_METHOD_PARAMS: ICommonProps<AdapterReplaceParams> = {\n [AdapterInsertParams.items]: {\n validators: [ITEM_LIST],\n mandatory: true\n },\n [AdapterReplaceParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)],\n mandatory: true\n },\n [AdapterReplaceParams.fixRight]: {\n validators: [BOOLEAN],\n defaultValue: false\n }\n};\n\nenum AdapterUpdateParams {\n predicate = 'predicate',\n fixRight = 'fixRight',\n}\n\nconst UPDATE_METHOD_PARAMS: ICommonProps<AdapterUpdateParams> = {\n [AdapterUpdateParams.predicate]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)],\n mandatory: true\n },\n [AdapterUpdateParams.fixRight]: {\n validators: [BOOLEAN],\n defaultValue: false\n },\n};\n\nenum AdapterFixParams {\n scrollPosition = 'scrollPosition',\n minIndex = 'minIndex',\n maxIndex = 'maxIndex',\n updater = 'updater',\n scrollToItem = 'scrollToItem',\n scrollToItemOpt = 'scrollToItemOpt',\n}\n\nconst FIX_METHOD_PARAMS: ICommonProps<AdapterFixParams> = {\n [AdapterFixParams.scrollPosition]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.minIndex]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.maxIndex]: {\n validators: [INTEGER_UNLIMITED]\n },\n [AdapterFixParams.updater]: {\n validators: [FUNC_WITH_X_TO_Y_ARGUMENTS(1, 2)]\n },\n [AdapterFixParams.scrollToItem]: {\n validators: [FUNC_WITH_X_ARGUMENTS(1)]\n },\n [AdapterFixParams.scrollToItemOpt]: {\n validators: [OR([BOOLEAN, OBJECT])]\n },\n};\n\nexport const AdapterMethods: AdapterProcessMap<{ [key: string]: string }> = {\n [Process.reset]: AdapterResetParams,\n [Process.reload]: AdapterReloadParams,\n [Process.prepend]: AdapterPrependParams,\n [Process.append]: AdapterAppendParams,\n [Process.check]: AdapterNoParams,\n [Process.remove]: AdapterRemoveParams,\n [Process.clip]: AdapterClipParams,\n [Process.insert]: AdapterInsertParams,\n [Process.replace]: AdapterReplaceParams,\n [Process.update]: AdapterUpdateParams,\n [Process.fix]: AdapterFixParams,\n};\n\nexport const ADAPTER_METHODS: AdapterProcessMap<ICommonProps<PropertyKey>> = {\n [Process.reset]: RESET_METHOD_PARAMS,\n [Process.reload]: RELOAD_METHOD_PARAMS,\n [Process.prepend]: PREPEND_METHOD_PARAMS,\n [Process.append]: APPEND_METHOD_PARAMS,\n [Process.check]: NO_METHOD_PARAMS,\n [Process.remove]: REMOVE_METHOD_PARAMS,\n [Process.clip]: CLIP_METHOD_PARAMS,\n [Process.insert]: INSERT_METHOD_PARAMS,\n [Process.replace]: REPLACE_METHOD_PARAMS,\n [Process.update]: UPDATE_METHOD_PARAMS,\n [Process.fix]: FIX_METHOD_PARAMS,\n};\n","import { SETTINGS, DEV_SETTINGS, validate, validateOne, VALIDATORS, SizeStrategy, Direction } from '../inputs/index';\nimport { Settings as ISettings, DevSettings as IDevSettings, ICommonProps, ItemsProcessor } from '../interfaces/index';\n\nexport class Settings<Data = unknown> implements ISettings, IDevSettings {\n\n // user settings\n adapter: boolean;\n startIndex: number;\n minIndex: number;\n maxIndex: number;\n itemSize: number;\n bufferSize: number;\n padding: number;\n infinite: boolean;\n horizontal: boolean;\n windowViewport: boolean;\n viewportElement: HTMLElement | (() => void) | null;\n inverse: boolean; // if true, bwd padding element will have a priority when filling the viewport (if lack of items)\n onBeforeClip: ItemsProcessor | null; // if set, it will be run before clipping items from Buffer after they are hidden\n sizeStrategy: SizeStrategy; // \"average\" | \"frequent\", determines behavior of unknown items\n\n /**\n * Development setting.\n * If true, logging is enabled.\n * Default value: false.\n * @type {boolean}\n */\n debug: boolean; // if true, \n\n /**\n * Development setting.\n * If false, in-memory logging is enabled, Adapter.showLog() method should be called to print the log.\n * Default value: true.\n * @type {boolean}\n */\n immediateLog: boolean;\n\n /**\n * Development setting.\n * If true, time differences will be logged.\n * Default value: false.\n * @type {boolean}\n */\n logTime: boolean;\n\n /**\n * Development setting.\n * If true, process fire/run info will be logged.\n * Default value: false.\n * @type {boolean}\n */\n logProcessRun: boolean;\n\n /**\n * Development setting.\n * If set, scroll event handling is throttled (ms).\n * Default value: 40. Minimal value: 0.\n * @type {number} ms\n */\n throttle: number;\n\n /**\n * Development setting.\n * If set, the Workflow initialization will be postponed (ms).\n * Default value: 1. Minimal value: 0.\n * @type {number} ms\n */\n initDelay: number;\n\n /**\n * Development setting.\n * If set and the entire window is scrollable, the Workflow initialization will be postponed (ms).\n * Default value: 40. Minimal value: 0.\n * @type {number} ms\n */\n initWindowDelay: number;\n\n /**\n * Development setting.\n * If true, item's data will be cached along with item's size and index.\n * Default value: false.\n * @type {boolean}\n */\n cacheData: boolean;\n\n /**\n * Development setting.\n * If true, cache will not be flushed on reload.\n * Default value: false.\n * @type {boolean}\n */\n cacheOnReload: boolean;\n\n /**\n * Development setting.\n * If true, the viewport will receive \"overflowAnchor: none\" css property.\n * Default value: false.\n * @type {boolean}\n */\n dismissOverflowAnchor: boolean;\n\n /**\n * Development setting.\n * Determines the strategy of fixing the difference between estimated and real (rendered) sizes\n * on scroll position adjustments. If set to 'backward', the difference is always resolved in favour of the\n * backward direction: top/left content is fixed and appears in accordance with pre-render expectations.\n * If set to 'forward', both directions could be used, and there is a case when bottom/right content is fixed:\n * new items are to the left of the previously rendered\n * and at least one previously rendered item remains.\n * Default value: 'backward'. Allowed values: 'backward', 'forward'.\n * @type {string}\n */\n directionPriority: Direction;\n\n /**\n * Internal setting. Stores the index of the Scroller instance.\n * @type {number}\n */\n instanceIndex: number;\n\n /**\n * Internal setting. Stores the Workflow initialization delay based on initDelay and initWindowDelay settings.\n * @type {number}\n */\n initializeDelay: number;\n\n /**\n * Internal setting. Stores the viewport based on viewportElement setting (which can be element or function).\n * @type {HTMLElement|null}\n */\n viewport: HTMLElement | null;\n\n constructor(\n settings: ISettings<Data> | undefined, devSettings: IDevSettings | undefined, instanceIndex: number\n ) {\n this.parseInput(settings, SETTINGS);\n this.parseInput(devSettings, DEV_SETTINGS);\n this.instanceIndex = instanceIndex;\n this.initializeDelay = this.getInitializeDelay();\n this.viewport = this.getViewport();\n // todo: min/max indexes must be ignored if infinite mode is enabled ??\n }\n\n parseInput(input: ISettings<Data> | IDevSettings | undefined, props: ICommonProps<PropertyKey>): void {\n const result = validate(input, props);\n if (!result.isValid) {\n throw new Error('Invalid settings');\n }\n Object.entries(result.params).forEach(([key, par]) =>\n Object.assign(this, { [key]: par.value })\n );\n }\n\n getInitializeDelay(): number {\n let result = 0;\n if (this.windowViewport && this.initWindowDelay && !('scrollRestoration' in history)) {\n result = this.initWindowDelay;\n }\n if (this.initDelay > 0) {\n result = Math.max(result, this.initDelay);\n }\n return result;\n }\n\n getViewport(): HTMLElement | null {\n if (typeof this.viewportElement !== 'function') {\n return this.viewportElement;\n }\n const value = this.viewportElement();\n const result = validateOne({ value }, 'value', { validators: [VALIDATORS.ELEMENT] });\n if (!result.isValid) {\n return null; // fallback to default (null) if Function didn't return HTML element synchronously\n }\n return result.value as HTMLElement;\n }\n}\n","import { AdapterProcess, ProcessStatus } from './enums';\nimport { Scroller } from '../../scroller';\nimport { ADAPTER_METHODS, validate } from '../../inputs/index';\nimport { ProcessName, IBaseProcess, IBaseAdapterProcess, IAdapterInput } from '../../interfaces/index';\n\nexport const BaseProcessFactory = (process: ProcessName): IBaseProcess =>\n\n class BaseProcess {\n\n static process: ProcessName = process;\n\n };\n\nexport const BaseAdapterProcessFactory = (process: AdapterProcess): IBaseAdapterProcess =>\n\n class BaseAdapterProcess extends (BaseProcessFactory(process) as IBaseProcess) {\n\n static process: AdapterProcess = process;\n\n static parseInput<T>(\n scroller: Scroller, options: T, ignoreErrors = false, _process?: AdapterProcess\n ): IAdapterInput<T> {\n const result: IAdapterInput<T> = {\n data: validate(options, ADAPTER_METHODS[_process || process])\n };\n\n if (result.data.isValid) {\n result.params = Object.entries(result.data.params)\n .reduce((acc, [key, { value }]) => ({\n ...acc,\n [key]: value\n }), {} as T);\n } else {\n scroller.logger.log(() => result.data.showErrors());\n if (!ignoreErrors) {\n scroller.workflow.call({\n process,\n status: ProcessStatus.error,\n payload: { error: `Wrong argument of the \"${process}\" method call` }\n });\n }\n }\n\n return result;\n }\n\n };\n","import { BaseProcessFactory, CommonProcess, AdapterProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { ProcessName } from '../interfaces/index';\n\nconst initProcesses = [CommonProcess.init, AdapterProcess.reset, AdapterProcess.reload];\n\nexport default class Init extends BaseProcessFactory(CommonProcess.init) {\n\n static run(scroller: Scroller, process: ProcessName): void {\n const { state, workflow } = scroller;\n const isInitial = initProcesses.includes(process);\n scroller.logger.logCycle(true);\n state.startWorkflowCycle(isInitial, process);\n workflow.call({\n process: Init.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\nimport { ScrollEventData, ScrollerWorkflow } from '../interfaces/index';\n\nexport default class Scroll extends BaseProcessFactory(CommonProcess.scroll) {\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static run(scroller: Scroller, payload?: { event?: Event }): void {\n const { workflow, viewport } = scroller;\n const position = viewport.scrollPosition;\n\n if (Scroll.onSynthetic(scroller, position)) {\n return;\n }\n\n Scroll.onThrottle(scroller, position, () =>\n Scroll.onScroll(scroller, workflow)\n );\n }\n\n static onSynthetic(scroller: Scroller, position: number): boolean {\n const { scroll } = scroller.state;\n const synthPos = scroll.syntheticPosition;\n if (synthPos !== null) {\n if (scroll.syntheticFulfill) {\n scroll.syntheticPosition = null;\n }\n if (!scroll.syntheticFulfill || synthPos === position) {\n scroller.logger.log(() => [\n 'skipping scroll', position, `[${scroll.syntheticFulfill ? '' : 'pre-'}synthetic]`\n ]);\n return true;\n }\n scroller.logger.log(() => [\n 'synthetic scroll has been fulfilled:', position, position < synthPos ? '<' : '>', synthPos\n ]);\n }\n return false;\n }\n\n static onThrottle(scroller: Scroller, position: number, done: () => void): void {\n const { state: { scroll }, settings: { throttle }, logger } = scroller;\n scroll.current = Scroll.getScrollEvent(position, scroll.previous);\n const { direction, time } = scroll.current;\n const timeDiff = scroll.previous ? time - scroll.previous.time : Infinity;\n const delta = throttle - timeDiff;\n const shouldDelay = isFinite(delta) && delta > 0;\n const alreadyDelayed = !!scroll.scrollTimer;\n logger.log(() => [\n direction === Direction.backward ? '\\u2934' : '\\u2935',\n position,\n shouldDelay ? (timeDiff + 'ms') : '0ms',\n shouldDelay ? (alreadyDelayed ? 'delayed' : `/ ${delta}ms delay`) : ''\n ]);\n if (!shouldDelay) {\n if (scroll.scrollTimer) {\n clearTimeout(scroll.scrollTimer);\n scroll.scrollTimer = null;\n }\n done();\n return;\n }\n if (!alreadyDelayed) {\n scroll.scrollTimer = setTimeout(() => {\n logger.log(() => {\n const curr = Scroll.getScrollEvent(scroller.viewport.scrollPosition, scroll.current);\n return [\n curr.direction === Direction.backward ? '\\u2934' : '\\u2935',\n curr.position,\n (curr.time - time) + 'ms',\n 'triggered by timer set on',\n position\n ];\n });\n scroll.scrollTimer = null;\n done();\n }, delta);\n }\n }\n\n static getScrollEvent(position: number, previous: ScrollEventData | null): ScrollEventData {\n const time = Number(new Date());\n let direction: Direction | null = Direction.forward;\n if (previous) {\n if (position === previous.position) {\n direction = previous.direction;\n } else if (position < previous.position) {\n direction = Direction.backward;\n }\n }\n return { position, direction, time };\n }\n\n static onScroll(scroller: Scroller, workflow: ScrollerWorkflow): void {\n const { state: { scroll, cycle } } = scroller;\n scroll.previous = { ...(scroll.current as ScrollEventData) };\n scroll.current = null;\n\n if (cycle.busy.get()) {\n scroller.logger.log(() => ['skipping scroll', (scroll.previous as ScrollEventData).position, '[pending]']);\n return;\n }\n\n workflow.call({\n process: Scroll.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { DatasourceProps } from '../../inputs/index';\nimport { Datasource } from '../../classes/datasource';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { IDatasourceOptional, ProcessPayload } from '../../interfaces/index';\n\nexport default class Reset extends BaseAdapterProcessFactory(AdapterProcess.reset) {\n\n static run(scroller: Scroller, options?: IDatasourceOptional): void {\n const { datasource, buffer, viewport: { paddings }, state: { cycle } } = scroller;\n\n if (options) {\n const { data } = Reset.parseInput(scroller, options);\n if (!data.isValid) {\n return;\n }\n const constructed = options instanceof Datasource;\n Object.keys(DatasourceProps).forEach(key => {\n const param = data.params[key];\n const ds = datasource as unknown as { [key: string]: unknown };\n if (param.isSet || (constructed && ds[key])) {\n ds[key] = param.value;\n }\n });\n }\n\n buffer.reset(true);\n paddings.backward.reset();\n paddings.forward.reset();\n\n const payload: ProcessPayload = { datasource };\n if (cycle.busy.get()) {\n payload.finalize = true;\n cycle.interrupter = Reset.process;\n }\n\n scroller.workflow.call({\n process: Reset.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { ProcessPayload } from '../../interfaces/index';\n\nexport default class Reload extends BaseAdapterProcessFactory(AdapterProcess.reload) {\n\n static run(scroller: Scroller, reloadIndex: number): void {\n const { viewport, state, buffer } = scroller;\n\n const { params } = Reload.parseInput(scroller, { reloadIndex }, true);\n\n buffer.reset(false, params ? params.reloadIndex : void 0);\n viewport.reset(buffer.startIndex);\n\n const payload: ProcessPayload = {};\n if (state.cycle.busy.get()) {\n state.scroll.stop();\n payload.finalize = true;\n state.cycle.interrupter = Reload.process;\n }\n\n scroller.workflow.call({\n process: Reload.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { Routines } from './domRoutines';\nimport { Direction } from '../inputs/index';\nimport { Item as _Item, ItemAdapter } from '../interfaces/index';\n\nexport class Item<Data = unknown> implements _Item<Data> {\n nodeId: string;\n routines: Routines;\n preSize: number; // estimated size\n size: number; // real size\n invisible: boolean;\n toRemove: boolean;\n toInsert: boolean;\n removeDirection: Direction;\n\n private container: ItemAdapter<Data>;\n\n get $index(): number {\n return this.container.$index;\n }\n set $index(value: number) {\n this.container.$index = value;\n }\n\n get data(): Data {\n return this.container.data;\n }\n set data(value: Data) {\n this.container.data = value;\n }\n\n get element(): HTMLElement {\n return this.container.element as HTMLElement;\n }\n set element(value: HTMLElement) {\n this.container.element = value;\n }\n\n constructor($index: number, data: Data, routines: Routines) {\n this.container = {\n $index,\n data\n };\n this.nodeId = String($index);\n this.routines = routines;\n this.invisible = true;\n this.toRemove = false;\n this.toInsert = false;\n }\n\n dispose(): void {\n delete this.container.element;\n }\n\n setSize(preSize = 0): void {\n this.preSize = preSize;\n if (this.element) {\n this.size = this.routines.getSize(this.element);\n }\n }\n\n makeVisible(): void {\n this.routines.makeElementVisible(this.element);\n this.invisible = false;\n }\n\n hide(): void {\n if (this.element) {\n this.routines.hideElement(this.element);\n }\n }\n\n scrollTo(argument?: boolean | ScrollIntoViewOptions): void {\n if (this.element) {\n this.routines.scrollTo(this.element, argument);\n }\n }\n\n updateIndex(index: number): void {\n this.$index = index;\n this.nodeId = String(index);\n }\n\n get(): ItemAdapter<Data> {\n return this.container;\n }\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Item } from '../../classes/item';\nimport { Direction } from '../../inputs/index';\nimport { AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Update extends BaseAdapterProcessFactory(AdapterProcess.update) {\n\n static run(scroller: Scroller, options: AdapterUpdateOptions): void {\n const { params } = Update.parseInput(scroller, options);\n if (!params) {\n return;\n }\n\n const shouldUpdate = Update.doUpdate(scroller, params);\n\n scroller.workflow.call({\n process: Update.process,\n status: shouldUpdate ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doUpdate(scroller: Scroller, params: AdapterUpdateOptions): boolean {\n const { buffer, viewport, state: { fetch }, routines, logger } = scroller;\n if (!buffer.items) {\n logger.log(() => 'no items in Buffer');\n return false;\n }\n const { item: firstItem, index: firstIndex, diff: firstItemDiff } =\n viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n\n const { trackedIndex, toRemove } = buffer.updateItems(\n params.predicate,\n (index, data) => new Item(index, data, routines),\n firstIndex,\n !!params.fixRight\n );\n\n let delta = 0;\n const trackedItem = buffer.get(trackedIndex);\n if (firstItem && firstItem === trackedItem) {\n delta = - buffer.getSizeByIndex(trackedIndex) + firstItemDiff;\n }\n\n toRemove.forEach(item => item.hide());\n logger.log(() => toRemove.length\n ? 'items to remove: [' + toRemove.map(({ $index }) => $index).join(',') + ']'\n : 'no items to remove'\n );\n if (toRemove.length) { // insertions will be processed on render\n buffer.checkDefaultSize();\n }\n\n const toRender = buffer.items.filter(({ toInsert }) => toInsert);\n logger.log(() => toRender.length\n ? 'items to render: [' + toRender.map(({ $index }) => $index).join(',') + ']'\n : 'no items to render'\n );\n\n fetch.update(trackedIndex, delta, toRender, toRemove);\n return !!toRemove.length || !!toRender.length;\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Item } from '../../classes/item';\nimport { Direction } from '../../inputs/index';\nimport { AdapterInsertOptions, AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Insert extends BaseAdapterProcessFactory(AdapterProcess.insert) {\n\n static run(scroller: Scroller, options: AdapterInsertOptions): void {\n const { params } = Insert.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldInsert = Insert.doInsert(scroller, params);\n\n scroller.workflow.call({\n process: Insert.process,\n status: shouldInsert ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doInsert(scroller: Scroller, params: AdapterInsertOptions): boolean {\n if (!Insert.insertEmpty(scroller, params)) {\n if (!Insert.insertInBuffer(scroller, params)) {\n if (!Insert.insertVirtually(scroller, params)) {\n return false;\n }\n }\n }\n return true;\n }\n\n static insertEmpty(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { buffer, routines, state: { fetch } } = scroller;\n if (buffer.size) {\n return false;\n }\n const { beforeIndex, afterIndex, items, decrease } = params;\n if (!buffer.fillEmpty(\n items, beforeIndex, afterIndex, !!decrease,\n (index, data) => new Item(index, data, routines)\n )) {\n return false;\n }\n fetch.fill(buffer.items, buffer.startIndex);\n\n return true;\n }\n\n static insertInBuffer(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { before, after, beforeIndex, afterIndex, items, decrease } = params;\n const indexToInsert = scroller.buffer.getIndexToInsert(before || after, beforeIndex, afterIndex);\n\n if (isNaN(indexToInsert)) {\n return false;\n }\n const isBackward = Number.isInteger(beforeIndex) || before;\n\n const updateOptions: AdapterUpdateOptions = {\n predicate: ({ $index, data }) => {\n if (indexToInsert === $index) {\n return isBackward ? [...items, data] : [data, ...items];\n }\n return true;\n },\n fixRight: decrease\n };\n\n return Update.doUpdate(scroller, updateOptions);\n }\n\n static insertVirtually(scroller: Scroller, params: AdapterInsertOptions): boolean {\n const { beforeIndex, afterIndex, items, decrease } = params;\n const { buffer, state: { fetch }, viewport } = scroller;\n const direction = Number.isInteger(beforeIndex) ? Direction.backward : Direction.forward;\n const indexToInsert = (direction === Direction.backward ? beforeIndex : afterIndex) as number;\n\n if (!buffer.insertVirtually(items, indexToInsert, direction, !!decrease)) {\n return false;\n }\n\n const { index, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = index;\n if (!isNaN(index)) {\n fetch.simulate = true;\n fetch.firstVisible.delta = - buffer.getSizeByIndex(index) + diff;\n }\n\n return true;\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Insert from './insert';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { AdapterAppendOptions, AdapterPrependOptions } from '../../interfaces/index';\n\ntype AdapterAppendPrependOptions = AdapterAppendOptions & AdapterPrependOptions;\n\ninterface AppendRunOptions {\n process: AdapterProcess;\n options: AdapterAppendPrependOptions;\n}\n\nexport default class Append extends BaseAdapterProcessFactory(AdapterProcess.append) {\n\n static run(scroller: Scroller, { process, options }: AppendRunOptions): void {\n const { params } = Append.parseInput(scroller, options, false, process);\n if (!params) {\n return;\n }\n\n const shouldAppend = Append.doAppend(scroller, process, params);\n\n scroller.workflow.call({\n process: Append.process,\n status: shouldAppend ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doAppend(scroller: Scroller, process: AdapterProcess, params: AdapterAppendPrependOptions): boolean {\n const { bof, eof, increase, decrease } = params;\n const { buffer } = scroller;\n const prepend = process === AdapterProcess.prepend;\n const opposite = prepend ? !increase : decrease;\n let beforeIndex, afterIndex, items = params.items;\n if (prepend) {\n beforeIndex = (bof ? buffer.absMinIndex : buffer.minIndex) + (!buffer.size ? 1 : 0);\n items = [...items].reverse();\n } else {\n afterIndex = (eof ? buffer.absMaxIndex : buffer.maxIndex) - (!buffer.size && !opposite ? 1 : 0);\n }\n return Insert.doInsert(scroller, {\n items,\n beforeIndex,\n afterIndex,\n decrease: opposite\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Direction } from '../../inputs/index';\n\nexport default class Check extends BaseAdapterProcessFactory(AdapterProcess.check) {\n\n static run(scroller: Scroller): void {\n const { workflow, buffer, state: { fetch }, viewport } = scroller;\n let min = Infinity, max = -Infinity;\n\n buffer.items.forEach(item => {\n const size = item.size;\n item.setSize();\n if (item.size !== size) {\n buffer.cacheItem(item);\n min = Math.min(min, item.$index);\n max = Math.max(max, item.$index);\n }\n });\n\n if (Number.isFinite(min)) {\n fetch.first.indexBuffer = buffer.firstIndex;\n fetch.last.indexBuffer = buffer.lastIndex;\n const { index: firstIndex, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = firstIndex;\n if (!isNaN(firstIndex)) {\n fetch.firstVisible.delta = - buffer.getSizeByIndex(firstIndex) + diff;\n }\n fetch.check(\n buffer.items.filter(item => item.$index >= min && item.$index <= max)\n );\n }\n\n scroller.logger.stat('check');\n\n workflow.call({\n process: Check.process,\n status: Number.isFinite(min) ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { Direction } from '../../inputs/index';\nimport { AdapterRemoveOptions, AdapterUpdateOptions, ItemsPredicate } from '../../interfaces/index';\n\nexport default class Remove extends BaseAdapterProcessFactory(AdapterProcess.remove) {\n\n static run(scroller: Scroller, options: AdapterRemoveOptions): void {\n const { params } = Remove.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldRemove = Remove.doRemove(scroller, params);\n\n scroller.workflow.call({\n process: Remove.process,\n status: shouldRemove ? ProcessStatus.next : ProcessStatus.done\n });\n }\n\n static doRemove(scroller: Scroller, params: AdapterRemoveOptions): boolean {\n const { fetch } = scroller.state;\n fetch.firstVisible.index = NaN;\n const removed = Remove.removeBufferedItems(scroller, params);\n const shouldBuffered = removed.length > 0;\n if (shouldBuffered) {\n // exclude just removed in-buffer indexes\n if (params.indexes && params.indexes.length) {\n params.indexes = params.indexes.filter(i => !removed.includes(i));\n }\n // shift virtual indexes that remain\n if (params.indexes && params.indexes.length) {\n const diffLeft = (params.increase ? 1 : 0) * removed.length;\n const diffRight = (params.increase ? 0 : -1) * removed.length;\n params.indexes = params.indexes.map(index =>\n index + (index < removed[0] ? diffLeft : diffRight)\n );\n }\n }\n const shouldVirtual = Remove.removeVirtualItems(scroller, params);\n if (!shouldBuffered && !shouldVirtual) {\n return false;\n }\n scroller.logger.stat('after remove');\n return true;\n }\n\n static removeBufferedItems(scroller: Scroller, options: AdapterRemoveOptions): number[] {\n const { predicate, indexes, increase } = options;\n if (!predicate && !indexes) {\n return [];\n }\n const newPredicate: ItemsPredicate = item =>\n (predicate && predicate(item)) ||\n (!!indexes && indexes.includes(item.$index));\n\n const indexesToRemove: number[] = scroller.buffer.items.reduce((acc, item) =>\n newPredicate(item) ? [...acc, item.$index] : acc, [] as number[]\n );\n const updateOptions: AdapterUpdateOptions = {\n predicate: item => !newPredicate(item),\n fixRight: increase\n };\n Update.doUpdate(scroller, updateOptions);\n return indexesToRemove;\n }\n\n static removeVirtualItems(scroller: Scroller, params: AdapterRemoveOptions): boolean {\n const { indexes, increase } = params;\n if (!indexes || !indexes.length) {\n return false;\n }\n const { buffer, viewport, state: { fetch } } = scroller;\n\n // get items to remove\n const { finiteAbsMinIndex, firstIndex, finiteAbsMaxIndex, lastIndex } = buffer;\n const toRemove = [];\n for (let i = 0, len = indexes.length; i < len; i++) {\n const index = indexes[i];\n if (index >= finiteAbsMinIndex && !isNaN(firstIndex) && index < firstIndex) {\n toRemove.push(index); // backward;\n } else if (index <= finiteAbsMaxIndex && !isNaN(lastIndex) && index > lastIndex) {\n toRemove.push(index); // forward;\n } else {\n continue;\n }\n }\n\n if (!toRemove.length) {\n return false;\n }\n\n // what should be shown after remove; Buffer removal has priority\n if (isNaN(fetch.firstVisible.index)) {\n const { index, diff } = viewport.getEdgeVisibleItem(buffer.items, Direction.backward);\n fetch.firstVisible.index = index;\n if (!isNaN(index)) {\n fetch.firstVisible.delta = - buffer.getSizeByIndex(index) + diff;\n }\n }\n\n // virtual removal\n scroller.logger.log(() => `going to remove ${toRemove.length} item(s) virtually`);\n buffer.removeVirtually(toRemove, !!increase);\n buffer.checkDefaultSize();\n Remove.shiftFirstVisibleIndex(scroller, toRemove, !!increase);\n\n return true;\n }\n\n static shiftFirstVisibleIndex(scroller: Scroller, listToRemove: number[], increase: boolean): void {\n const { firstVisible } = scroller.state.fetch;\n if (isNaN(firstVisible.index)) {\n return;\n }\n const shift = listToRemove.reduce((acc, index) => acc + (\n ((increase && index > firstVisible.index) || (!increase && index < firstVisible.index)) ? 1 : 0\n ), 0);\n firstVisible.index = firstVisible.index + (increase ? shift : -shift);\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { AdapterClipOptions } from '../../interfaces/index';\n\nexport default class UserClip extends BaseAdapterProcessFactory(AdapterProcess.clip) {\n\n static run(scroller: Scroller, options?: AdapterClipOptions): void {\n const { params } = UserClip.parseInput(scroller, options);\n\n scroller.state.clip.forceForward = !(params && params.backwardOnly);\n scroller.state.clip.forceBackward = !(params && params.forwardOnly);\n\n scroller.workflow.call({\n process: UserClip.process,\n status: ProcessStatus.next\n });\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport Update from './update';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport { AdapterReplaceOptions, AdapterUpdateOptions } from '../../interfaces/index';\n\nexport default class Replace extends BaseAdapterProcessFactory(AdapterProcess.replace) {\n\n static run(scroller: Scroller, options: AdapterReplaceOptions): void {\n const { params } = Replace.parseInput(scroller, options);\n if (!params) {\n return;\n }\n const shouldReplace = Replace.doReplace(scroller, params);\n\n scroller.workflow.call({\n process: Replace.process,\n status: shouldReplace ? ProcessStatus.next : ProcessStatus.done,\n });\n }\n\n static doReplace(scroller: Scroller, params: AdapterReplaceOptions): boolean {\n const toRemove = scroller.buffer.items\n .filter(item => params.predicate(item))\n .map(item => item.$index);\n\n if (!toRemove.length) {\n scroller.logger.log('no items to be replaced');\n return false;\n }\n\n let injected = false;\n const updateOptions: AdapterUpdateOptions = {\n predicate: ({ $index }) => {\n if (!toRemove.includes($index)) {\n return true;\n }\n if (!injected) {\n injected = true;\n return params.items;\n }\n return false;\n },\n fixRight: params.fixRight\n };\n\n return Update.doUpdate(scroller, updateOptions);\n }\n\n}\n","import { Scroller } from '../../scroller';\nimport { AdapterMethods } from '../../inputs/index';\nimport { BaseAdapterProcessFactory, AdapterProcess, ProcessStatus } from '../misc/index';\nimport {\n ItemsPredicate,\n ItemsUpdater,\n AdapterFixOptions,\n IValidatedData,\n} from '../../interfaces/index';\n\nconst { [AdapterProcess.fix]: FixParams } = AdapterMethods;\n\nexport default class Fix extends BaseAdapterProcessFactory(AdapterProcess.fix) {\n\n static run(scroller: Scroller, options: AdapterFixOptions): void {\n const { workflow } = scroller;\n\n const { data, params } = Fix.parseInput(scroller, options);\n if (!params) {\n return;\n }\n\n Object.entries(data.params).forEach(([key, value]) => {\n if (value.isSet && value.isValid) {\n Fix.runByType(scroller, key, value.value, data);\n }\n });\n\n workflow.call({\n process: Fix.process,\n status: ProcessStatus.done\n });\n }\n\n static runByType(scroller: Scroller, token: string, value: unknown, methodData: IValidatedData): void {\n switch (token) {\n case FixParams.scrollPosition:\n return Fix.setScrollPosition(scroller, value as number);\n case FixParams.minIndex:\n return Fix.setMinIndex(scroller, value as number);\n case FixParams.maxIndex:\n return Fix.setMaxIndex(scroller, value as number);\n case FixParams.updater:\n return Fix.updateItems(scroller, value as ItemsUpdater);\n case FixParams.scrollToItem:\n if (methodData.params) {\n const scrollToItemOpt = methodData.params[FixParams.scrollToItemOpt];\n const options = scrollToItemOpt ? scrollToItemOpt.value as AdapterFixOptions['scrollToItemOpt'] : void 0;\n return Fix.scrollToItem(scroller, value as ItemsPredicate, options);\n }\n return;\n case FixParams.scrollToItemOpt:\n return;\n }\n }\n\n static setScrollPosition({ viewport }: Scroller, value: number): void {\n let result = value;\n if (value === -Infinity) {\n result = 0;\n } else if (value === Infinity) {\n result = viewport.getScrollableSize();\n }\n viewport.setPosition(result);\n }\n\n static setMinIndex({ buffer, settings }: Scroller, value: number): void {\n settings.minIndex = value;\n buffer.absMinIndex = value;\n }\n\n static setMaxIndex({ buffer, settings }: Scroller, value: number): void {\n settings.maxIndex = value;\n buffer.absMaxIndex = value;\n }\n\n static updateItems({ buffer, logger }: Scroller, value: ItemsUpdater): void {\n let updateReference = false;\n const updater = () => updateReference = true;\n buffer.items.forEach(item => value(item.get(), updater));\n if (updateReference) {\n logger.log(() => 'update Buffer.items reference');\n buffer.items = [...buffer.items];\n }\n }\n\n static scrollToItem(scroller: Scroller, value: ItemsPredicate, options?: boolean | ScrollIntoViewOptions): void {\n const found = scroller.buffer.items.find(item => value(item.get()));\n if (!found) {\n scroller.logger.log(() => 'scrollToItem cancelled, item not found');\n return;\n }\n found.scrollTo(options);\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\n\nexport default class Start extends BaseProcessFactory(CommonProcess.start) {\n\n static run(scroller: Scroller): void {\n const payload = scroller.state.startInnerLoop();\n\n scroller.workflow.call({\n process: Start.process,\n status: ProcessStatus.next,\n payload\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, AdapterProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\n\nexport default class PreFetch extends BaseProcessFactory(CommonProcess.preFetch) {\n\n static run(scroller: Scroller): void {\n const { workflow, buffer, state: { fetch, cycle } } = scroller;\n fetch.minIndex = buffer.minIndex;\n\n // set first and last indexes of items to fetch\n PreFetch.setPositionsAndIndexes(scroller);\n\n // skip indexes that are in buffer\n PreFetch.skipBufferedItems(scroller);\n\n if (scroller.settings.infinite) {\n // fill indexes to include buffer if no clip\n PreFetch.checkBufferGaps(scroller);\n }\n\n // add indexes if there are too few items to fetch (clip padding)\n PreFetch.checkFetchPackSize(scroller);\n\n // set fetch direction\n PreFetch.setFetchDirection(scroller);\n\n workflow.call({\n process: PreFetch.process,\n status: PreFetch.getStatus(scroller),\n payload: { process: cycle.initiator }\n });\n }\n\n static setPositionsAndIndexes(scroller: Scroller): void {\n PreFetch.setPositions(scroller);\n PreFetch.setFirstIndex(scroller);\n PreFetch.setLastIndex(scroller);\n scroller.logger.fetch();\n }\n\n static setPositions(scroller: Scroller): void {\n const { state: { fetch: { positions } }, viewport } = scroller;\n const paddingDelta = viewport.getBufferPadding();\n positions.before = viewport.scrollPosition;\n positions.startDelta = PreFetch.getStartDelta(scroller);\n positions.relative = positions.before - positions.startDelta;\n positions.start = positions.relative - paddingDelta;\n positions.end = positions.relative + viewport.getSize() + paddingDelta;\n }\n\n static getStartDelta(scroller: Scroller): number { // calculate size before start index\n const { buffer, viewport: { offset } } = scroller;\n let startDelta = 0;\n if (offset) {\n startDelta += offset;\n }\n if (!buffer.defaultSize) {\n return startDelta;\n }\n for (let index = buffer.finiteAbsMinIndex; index < buffer.startIndex; index++) {\n startDelta += buffer.getSizeByIndex(index);\n }\n scroller.logger.log(() => [\n `start delta is ${startDelta}`, ...(offset ? [` (+${offset} offset)`] : [])\n ]);\n return startDelta;\n }\n\n static setFirstIndex(scroller: Scroller): void {\n const { state, buffer } = scroller;\n const { positions: { start }, first } = state.fetch;\n let firstIndex = buffer.startIndex;\n let firstIndexPosition = 0;\n if (state.cycle.innerLoop.isInitial) {\n scroller.logger.log('skipping fetch backward direction [initial loop]');\n } else if (!buffer.defaultSize) {\n scroller.logger.log('skipping fetch backward direction [no item size]');\n } else {\n let position = firstIndexPosition;\n let index = firstIndex;\n while (1) { // eslint-disable-line no-constant-condition\n if (start >= 0) {\n const size = buffer.getSizeByIndex(index);\n const diff = (position + size) - start;\n if (diff > 0) {\n firstIndex = index;\n firstIndexPosition = position;\n break;\n }\n position += size;\n index++;\n if (index < buffer.absMinIndex) {\n break;\n }\n }\n if (start < 0) {\n index--;\n if (index < buffer.absMinIndex) {\n break;\n }\n position -= buffer.getSizeByIndex(index);\n const diff = position - start;\n firstIndex = index;\n firstIndexPosition = position;\n if (diff <= 0) {\n break;\n }\n }\n }\n }\n first.index = first.indexBuffer = Math.max(firstIndex, buffer.absMinIndex);\n first.position = firstIndexPosition;\n }\n\n static setLastIndex(scroller: Scroller): void {\n const { state: { fetch, cycle }, buffer, settings } = scroller;\n const { firstVisible, positions: { relative, end }, first, last } = fetch;\n let lastIndex;\n if (!buffer.defaultSize) {\n // just to fetch forward bufferSize items if neither averageItemSize nor itemSize are present\n lastIndex = buffer.startIndex + settings.bufferSize - 1;\n scroller.logger.log('forcing fetch forward direction [no item size]');\n } else {\n let index = first.indexBuffer;\n let position = first.position;\n lastIndex = index;\n while (1) { // eslint-disable-line no-constant-condition\n lastIndex = index;\n const size = buffer.getSizeByIndex(index);\n position += size;\n if (isNaN(firstVisible.index) && position > relative) {\n firstVisible.index = index;\n if (!cycle.innerLoop.isInitial) {\n firstVisible.delta = position - size - relative;\n }\n }\n if (position >= end) {\n break;\n }\n if (index++ > buffer.absMaxIndex) {\n break;\n }\n }\n }\n last.index = last.indexBuffer = Math.min(lastIndex, buffer.absMaxIndex);\n }\n\n static skipBufferedItems(scroller: Scroller): void {\n const { buffer } = scroller;\n if (!buffer.size) {\n return;\n }\n const { fetch } = scroller.state;\n const firstIndex = fetch.first.index;\n const lastIndex = fetch.last.index;\n const packs: number[][] = [[]];\n let p = 0;\n for (let i = firstIndex; i <= lastIndex; i++) {\n if (!buffer.get(i)) {\n packs[p].push(i);\n } else if (packs[p].length) {\n packs[++p] = [];\n }\n }\n let pack = packs[0];\n if (packs[0].length && packs[1] && packs[1].length) {\n fetch.hasAnotherPack = true;\n // todo: need to look for biggest pack in visible area\n // todo: or think about merging two requests in a single Fetch process\n if (packs[1].length >= packs[0].length) {\n pack = packs[1];\n }\n }\n fetch.first.index = Math.max(pack[0], buffer.absMinIndex);\n fetch.last.index = Math.min(pack[pack.length - 1], buffer.absMaxIndex);\n if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) {\n scroller.logger.fetch('after Buffer flushing');\n }\n }\n\n static checkBufferGaps(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (!buffer.size) {\n return;\n }\n const fetchFirst = fetch.first.index;\n const bufferLast = buffer.lastIndex;\n if (fetchFirst > bufferLast) {\n fetch.first.index = fetch.first.indexBuffer = bufferLast + 1;\n }\n const bufferFirst = buffer.firstIndex;\n const fetchLast = fetch.last.index;\n if (fetchLast < bufferFirst) {\n fetch.last.index = fetch.last.indexBuffer = bufferFirst - 1;\n }\n if (fetch.first.index !== fetchFirst || fetch.last.index !== fetchLast) {\n scroller.logger.fetch('after Buffer filling (no clip case)');\n }\n }\n\n static checkFetchPackSize(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (!fetch.shouldFetch) {\n return;\n }\n const firstIndex = fetch.first.index;\n const lastIndex = fetch.last.index;\n const diff = scroller.settings.bufferSize - (lastIndex - firstIndex + 1);\n if (diff <= 0) {\n return;\n }\n if (!buffer.size || lastIndex > buffer.items[0].$index) { // forward\n const newLastIndex = Math.min(lastIndex + diff, buffer.absMaxIndex);\n if (newLastIndex > lastIndex) {\n fetch.last.index = fetch.last.indexBuffer = newLastIndex;\n }\n } else {\n const newFirstIndex = Math.max(firstIndex - diff, buffer.absMinIndex);\n if (newFirstIndex < firstIndex) {\n fetch.first.index = fetch.first.indexBuffer = newFirstIndex;\n }\n }\n if (fetch.first.index !== firstIndex || fetch.last.index !== lastIndex) {\n scroller.logger.fetch('after bufferSize adjustment');\n PreFetch.skipBufferedItems(scroller);\n }\n }\n\n static setFetchDirection(scroller: Scroller): void {\n const { buffer, state: { fetch } } = scroller;\n if (fetch.last.index) {\n let direction = Direction.forward;\n if (buffer.size) {\n direction = fetch.last.index < buffer.items[0].$index ? Direction.backward : Direction.forward;\n }\n fetch.direction = direction;\n scroller.logger.log(() => `fetch direction is \"${direction}\"`);\n }\n }\n\n static getStatus(scroller: Scroller): ProcessStatus {\n const { cycle, fetch } = scroller.state;\n if (cycle.initiator === AdapterProcess.clip) {\n scroller.logger.log(() => `going to skip fetch due to \"${AdapterProcess.clip}\" process`);\n return ProcessStatus.next;\n }\n if (fetch.shouldFetch) {\n scroller.logger.log(() => `going to fetch ${fetch.count} items started from index ${fetch.index}`);\n return ProcessStatus.next;\n }\n return ProcessStatus.done;\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { ObservableLike } from '../interfaces/index';\n\ninterface Immediate {\n data: unknown[] | null;\n error: unknown | null;\n isError: boolean;\n}\n\ntype FetchGetResult = Immediate | Promise<unknown>;\n\ninterface FetchBox {\n success: (value: unknown[]) => void;\n fail: (value: unknown) => void;\n}\n\nexport default class Fetch extends BaseProcessFactory(CommonProcess.fetch) {\n\n static run(scroller: Scroller): void {\n const { workflow } = scroller;\n\n const box = {\n success: (data: unknown[]) => {\n scroller.logger.log(() =>\n `resolved ${data.length} items ` +\n `(index = ${scroller.state.fetch.index}, count = ${scroller.state.fetch.count})`\n );\n scroller.state.fetch.newItemsData = data;\n workflow.call({\n process: Fetch.process,\n status: ProcessStatus.next\n });\n },\n fail: (error: unknown) =>\n workflow.call({\n process: Fetch.process,\n status: ProcessStatus.error,\n payload: { error }\n })\n };\n\n const result = Fetch.get(scroller);\n Fetch.complete(scroller, box, result);\n }\n\n static complete(scroller: Scroller, box: FetchBox, result: FetchGetResult): void {\n if (Object.prototype.hasOwnProperty.call(result, 'data')) {\n const { data, error, isError } = result as Immediate;\n if (!isError) {\n box.success(data || []);\n } else {\n box.fail(error);\n }\n } else {\n const { state: { scroll, fetch }, viewport } = scroller;\n if (scroll.positionBeforeAsync === null) {\n scroll.positionBeforeAsync = viewport.scrollPosition;\n }\n fetch.cancel = () => {\n box.success = () => null;\n box.fail = () => null;\n };\n (result as Promise<unknown[]>).then(\n (data) => box.success(data),\n (error) => box.fail(error)\n );\n }\n }\n\n static get(scroller: Scroller): FetchGetResult {\n const _get = scroller.datasource.get;\n const { index, count } = scroller.state.fetch;\n\n let immediateData, immediateError;\n let resolve: (value: unknown) => void, reject: (value: unknown) => void;\n\n const done = (data: unknown[]) => {\n if (!resolve) {\n immediateData = data || null;\n return;\n }\n resolve(data);\n };\n const fail = (error: unknown) => {\n if (!reject) {\n immediateError = error || null;\n return;\n }\n reject(error);\n };\n\n const getResult = _get(index, count, done, fail);\n\n if (getResult && typeof getResult === 'object' && getResult !== null) {\n if (typeof (getResult as PromiseLike<unknown>).then === 'function') {\n return getResult as Promise<unknown>;\n } else if (typeof (getResult as ObservableLike).subscribe === 'function') {\n const sub = (getResult as ObservableLike).subscribe(done, fail, () => {\n if (sub && typeof sub === 'object' && typeof sub.unsubscribe === 'function') {\n sub.unsubscribe();\n }\n });\n }\n }\n\n if (immediateData || immediateError) { // callback case or immediate observable\n return {\n data: immediateError ? null : (immediateData || []),\n error: immediateError,\n isError: !!immediateError\n };\n }\n\n return new Promise((_resolve, _reject) => {\n resolve = _resolve;\n reject = _reject;\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Item } from '../classes/item';\n\nexport default class PostFetch extends BaseProcessFactory(CommonProcess.postFetch) {\n\n static run(scroller: Scroller): void {\n const { workflow } = scroller;\n if (PostFetch.setItems(scroller)) {\n PostFetch.setBufferLimits(scroller);\n workflow.call({\n process: PostFetch.process,\n status: scroller.state.fetch.hasNewItems\n ? ProcessStatus.next\n : ProcessStatus.done\n });\n } else {\n workflow.call({\n process: PostFetch.process,\n status: ProcessStatus.error,\n payload: { error: 'Can\\'t set buffer items' }\n });\n }\n }\n\n static setBufferLimits(scroller: Scroller): void {\n const { buffer, state: { fetch, cycle: { innerLoop } } } = scroller;\n const { items, first: { index: first }, last: { index: last } } = fetch;\n if (!items.length) {\n if (last < buffer.minIndex || innerLoop.isInitial) {\n buffer.absMinIndex = buffer.minIndex;\n }\n if (first > buffer.maxIndex || innerLoop.isInitial) {\n buffer.absMaxIndex = buffer.maxIndex;\n }\n } else {\n const lastIndex = items.length - 1;\n if (first < items[0].$index) {\n buffer.absMinIndex = items[0].$index;\n }\n if (last > items[lastIndex].$index) {\n buffer.absMaxIndex = items[lastIndex].$index;\n }\n }\n }\n\n static setItems(scroller: Scroller): boolean {\n const { buffer, state: { fetch, cycle } } = scroller;\n const items = fetch.newItemsData;\n if (!items || !items.length) { // empty result\n return true;\n }\n // eof/bof case, need to shift fetch index if bof\n let fetchIndex = fetch.index;\n if (items.length < fetch.count) {\n if (cycle.innerLoop.isInitial) {\n // let's treat initial poor fetch as startIndex-bof\n fetchIndex = buffer.startIndex;\n } else if (fetch.first.index < buffer.minIndex) { // normal bof\n fetchIndex = buffer.minIndex - items.length;\n }\n }\n fetch.items = items.map((item, index: number) =>\n new Item(fetchIndex + index, item, scroller.routines)\n );\n return buffer.setItems(fetch.items);\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Item } from '../classes/item';\n\nexport default class Render extends BaseProcessFactory(CommonProcess.render) {\n\n static run(scroller: Scroller): void {\n const { workflow, state: { cycle, render, scroll }, viewport, routines } = scroller;\n scroller.logger.stat('before new items render');\n if (scroll.positionBeforeAsync === null) {\n scroll.positionBeforeAsync = viewport.scrollPosition;\n }\n render.cancel = routines.render(() => {\n render.cancel = null;\n if (Render.doRender(scroller)) {\n workflow.call({\n process: Render.process,\n status: render.noSize ? ProcessStatus.done : ProcessStatus.next,\n payload: { process: cycle.initiator }\n });\n } else {\n workflow.call({\n process: Render.process,\n status: ProcessStatus.error,\n payload: { error: 'Can\\'t associate item with element' }\n });\n }\n });\n }\n\n static doRender(scroller: Scroller): boolean {\n const { state: { fetch, render }, viewport, buffer, logger } = scroller;\n render.positionBefore = viewport.scrollPosition;\n if (!fetch.isCheck) {\n render.sizeBefore = viewport.getScrollableSize();\n if (!fetch.items.every(item =>\n Render.processElement(scroller, item)\n )) {\n return false;\n }\n }\n buffer.checkDefaultSize();\n render.sizeAfter = viewport.getScrollableSize();\n logger.stat('after new items render');\n logger.log(() => render.noSize ? 'viewport size has not been changed' : void 0);\n return true;\n }\n\n static processElement(scroller: Scroller, item: Item): boolean {\n const { viewport, buffer } = scroller;\n const element = viewport.findItemElementById(item.nodeId);\n if (!element) {\n return false;\n }\n item.element = element as HTMLElement;\n item.makeVisible();\n item.setSize(buffer.getSizeByIndex(item.$index));\n buffer.cacheItem(item);\n return true;\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\nimport { EMPTY_ITEM } from '../classes/adapter/props';\nimport { ScrollerWorkflow } from '../interfaces/index';\n\nconst isInterrupted = ({ call }: ScrollerWorkflow): boolean => !!call.interrupted;\n\nexport default class End extends BaseProcessFactory(CommonProcess.end) {\n\n static run(scroller: Scroller, { error }: { error?: unknown } = {}): void {\n const { workflow, state: { cycle: { interrupter } } } = scroller;\n\n if (!error && !interrupter) {\n // set out params accessible via Adapter\n End.calculateParams(scroller, workflow);\n }\n\n // explicit interruption for we don't want to go through the inner loop finalizing\n if (isInterrupted(workflow)) {\n workflow.call({ process: End.process, status: ProcessStatus.done });\n return;\n }\n\n const next = End.shouldContinueRun(scroller, error);\n scroller.state.endInnerLoop();\n\n workflow.call({\n process: End.process,\n status: next ? ProcessStatus.next : ProcessStatus.done,\n payload: { ...(interrupter ? { process: interrupter } : {}) }\n });\n }\n\n static calculateParams(scroller: Scroller, workflow: ScrollerWorkflow): void {\n const { adapter, viewport, buffer: { items } } = scroller;\n\n if (adapter.wanted.firstVisible) {\n const { item } = viewport.getEdgeVisibleItem(items, Direction.backward);\n if (!item || item.element !== adapter.firstVisible.element) {\n adapter.firstVisible = item ? item.get() : EMPTY_ITEM;\n }\n }\n\n // the workflow can be interrupter on firstVisible change\n if (adapter.wanted.lastVisible && !isInterrupted(workflow)) {\n const { item } = viewport.getEdgeVisibleItem(items, Direction.forward);\n if (!item || item.element !== adapter.lastVisible.element) {\n adapter.lastVisible = item ? item.get() : EMPTY_ITEM;\n }\n }\n }\n\n static shouldContinueRun(scroller: Scroller, error: unknown): boolean {\n const { cycle, fetch, render } = scroller.state;\n // Adapter.reload or Adapter.reset\n if (cycle.interrupter) {\n return true;\n }\n // critical error\n if (error) {\n return false;\n }\n // Adapter.check\n if (fetch.simulate && fetch.isCheck && !render.noSize) {\n return true;\n }\n // Adapter.remove or Adapter.update with clip\n if (fetch.simulate && fetch.doRemove) {\n return true;\n }\n // common inner loop (App start, scroll, Adapter.clip) with full fetch\n if (!fetch.simulate && ((fetch.hasNewItems && !render.noSize) || fetch.hasAnotherPack)) {\n return true;\n }\n return false;\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\r\nimport { Scroller } from '../scroller';\r\nimport End from './end';\r\n\r\nexport default class Adjust extends BaseProcessFactory(CommonProcess.adjust) {\r\n\r\n static run(scroller: Scroller): void {\r\n const { workflow, viewport, state: { scroll } } = scroller;\r\n\r\n scroll.positionBeforeAdjust = viewport.scrollPosition;\r\n Adjust.setPaddings(scroller);\r\n scroll.positionAfterAdjust = viewport.scrollPosition;\r\n\r\n // scroll position adjustments\r\n const position = Adjust.calculatePosition(scroller);\r\n\r\n // additional adjustment if the position can't be reached during the initial cycle\r\n Adjust.setAdditionalForwardPadding(scroller, position);\r\n\r\n // set new position using animation frame\r\n Adjust.setPosition(scroller, position, () =>\r\n workflow.call({\r\n process: Adjust.process,\r\n status: ProcessStatus.done\r\n })\r\n );\r\n }\r\n\r\n static setPaddings(scroller: Scroller): void {\r\n const { viewport, buffer, settings: { inverse }, state: { fetch } } = scroller;\r\n const firstItem = buffer.getFirstVisibleItem();\r\n const lastItem = buffer.getLastVisibleItem();\r\n let first, last;\r\n if (firstItem && lastItem) {\r\n first = firstItem.$index;\r\n last = lastItem.$index;\r\n } else {\r\n first = !isNaN(fetch.firstVisible.index) ? fetch.firstVisible.index : buffer.startIndex;\r\n last = first - 1;\r\n }\r\n const { forward, backward } = viewport.paddings;\r\n let index, bwdSize = 0, fwdSize = 0;\r\n\r\n // new backward and forward paddings size\r\n for (index = buffer.finiteAbsMinIndex; index < first; index++) {\r\n bwdSize += buffer.getSizeByIndex(index);\r\n }\r\n for (index = last + 1; index <= buffer.finiteAbsMaxIndex; index++) {\r\n fwdSize += buffer.getSizeByIndex(index);\r\n }\r\n\r\n // lack of items case\r\n const bufferSize = viewport.getScrollableSize() - forward.size - backward.size;\r\n const scrollSize = bwdSize + bufferSize + fwdSize;\r\n const viewportSizeDiff = viewport.getSize() - scrollSize;\r\n if (viewportSizeDiff > 0) {\r\n if (inverse) {\r\n bwdSize += viewportSizeDiff;\r\n } else {\r\n fwdSize += viewportSizeDiff;\r\n }\r\n scroller.logger.log(() =>\r\n inverse ? 'backward' : 'forward' + ` padding will be increased by ${viewportSizeDiff} to fill the viewport`\r\n );\r\n }\r\n\r\n backward.size = bwdSize;\r\n forward.size = fwdSize;\r\n\r\n scroller.logger.stat('after paddings adjustments');\r\n }\r\n\r\n static calculatePosition(scroller: Scroller): number {\r\n const { viewport, buffer, state: { fetch, render, scroll } } = scroller;\r\n let position = viewport.paddings.backward.size;\r\n\r\n // increase the position to meet the expectation of the first visible item\r\n if (!isNaN(fetch.firstVisible.index) && !isNaN(buffer.firstIndex)) {\r\n scroller.logger.log(`first index = ${fetch.firstVisible.index}, delta = ${fetch.firstVisible.delta}`);\r\n const shouldCheckPreSizeExpectation = fetch.shouldCheckPreSizeExpectation(buffer.lastIndex);\r\n buffer.items.forEach(item => {\r\n // 1) shift of the buffered items before the first visible item\r\n if (item.$index < fetch.firstVisible.index) {\r\n position += item.size;\r\n return;\r\n }\r\n // 2) delta of the first visible item\r\n if (item.$index === fetch.firstVisible.index && fetch.firstVisible.delta) {\r\n position -= fetch.firstVisible.delta;\r\n }\r\n // 3) difference between expected and real sizes of fetched items after the first visible\r\n if (shouldCheckPreSizeExpectation && item.preSize && fetch.items.includes(item)) {\r\n position += item.size - item.preSize;\r\n }\r\n });\r\n }\r\n\r\n // slow fetch/render case\r\n if (scroll.positionBeforeAsync !== null) {\r\n const diff = render.positionBefore - scroll.positionBeforeAsync;\r\n if (diff !== 0) {\r\n scroller.logger.log(`shift position due to fetch-render difference (${diff})`);\r\n position += diff;\r\n }\r\n }\r\n\r\n // increase the position due to viewport's offset\r\n if (viewport.offset > 0 && (position || fetch.positions.before)) {\r\n position += viewport.offset;\r\n }\r\n\r\n return Math.round(position);\r\n }\r\n\r\n static setAdditionalForwardPadding(scroller: Scroller, position: number): void {\r\n const { viewport, buffer, state: { cycle } } = scroller;\r\n if (!cycle.isInitial || !End.shouldContinueRun(scroller, null)) {\r\n return;\r\n }\r\n const diff = position - viewport.getMaxScrollPosition();\r\n if (diff <= 0) {\r\n return;\r\n }\r\n const last = buffer.getLastVisibleItem();\r\n if (!last) {\r\n return;\r\n }\r\n let size = 0;\r\n let index = last.$index + 1;\r\n while (size <= diff && index <= buffer.absMaxIndex) {\r\n size += buffer.getSizeByIndex(index++);\r\n }\r\n const shift = Math.min(size, diff);\r\n if (shift) {\r\n viewport.paddings.forward.size += shift;\r\n scroller.logger.log(`increase fwd padding due to lack of items (${diff} -> ${shift})`);\r\n }\r\n }\r\n\r\n static setPosition(scroller: Scroller, position: number, done: () => void): void {\r\n const { state: { scroll }, viewport, routines } = scroller;\r\n if (!scroll.hasPositionChanged(position)) {\r\n return done();\r\n }\r\n scroll.syntheticPosition = position;\r\n scroll.syntheticFulfill = false;\r\n\r\n scroll.cancelAnimation = routines.animate(() => {\r\n scroll.cancelAnimation = null;\r\n const inertiaDiff = (scroll.positionAfterAdjust as number) - viewport.scrollPosition;\r\n let diffLog = '';\r\n if (inertiaDiff > 0) {\r\n position -= inertiaDiff;\r\n scroll.syntheticPosition = position;\r\n diffLog = ` (-${inertiaDiff})`;\r\n }\r\n scroll.syntheticFulfill = true;\r\n viewport.scrollPosition = position;\r\n scroller.logger.stat('after scroll adjustment' + diffLog);\r\n done();\r\n });\r\n }\r\n\r\n}\r\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\nimport { Scroller } from '../scroller';\nimport { Direction } from '../inputs/index';\n\nexport default class PreClip extends BaseProcessFactory(CommonProcess.preClip) {\n\n static run(scroller: Scroller): void {\n PreClip.prepareClip(scroller);\n\n scroller.workflow.call({\n process: PreClip.process,\n status: ProcessStatus.next,\n payload: {\n doClip: scroller.state.clip.doClip\n }\n });\n }\n\n static prepareClip(scroller: Scroller): void {\n const { state: { fetch, clip } } = scroller;\n if (PreClip.shouldNotClip(scroller)) {\n return;\n }\n const firstIndex = fetch.first.indexBuffer;\n const lastIndex = fetch.last.indexBuffer;\n scroller.logger.log(() =>\n `looking for ${fetch.direction ? 'anti-' + fetch.direction + ' ' : ''}items ` +\n `that are out of [${firstIndex}..${lastIndex}] range`);\n if (PreClip.isBackward(scroller, firstIndex)) {\n PreClip.prepareClipByDirection(scroller, Direction.backward, firstIndex);\n }\n if (PreClip.isForward(scroller, lastIndex)) {\n PreClip.prepareClipByDirection(scroller, Direction.forward, lastIndex);\n }\n if (!clip.doClip) {\n scroller.logger.log('skipping clip [no items to clip]');\n }\n return;\n }\n\n static shouldNotClip(scroller: Scroller): boolean {\n const { settings, buffer, state } = scroller;\n if (settings.infinite && !state.clip.force) {\n scroller.logger.log('skipping clip [infinite mode]');\n return true;\n }\n if (!buffer.size) {\n scroller.logger.log('skipping clip [empty buffer]');\n return true;\n }\n if (state.cycle.isInitial) {\n scroller.logger.log('skipping clip [initial cycle]');\n return true;\n }\n return false;\n }\n\n static isBackward(scroller: Scroller, firstIndex: number): boolean {\n const { buffer, state: { clip, fetch } } = scroller;\n if (clip.force) {\n return clip.forceBackward;\n }\n if (fetch.direction !== Direction.backward) {\n if (firstIndex - 1 >= buffer.absMinIndex) {\n return true;\n }\n }\n return false;\n }\n\n static isForward(scroller: Scroller, lastIndex: number): boolean {\n const { buffer, state: { clip, fetch } } = scroller;\n if (clip.force) {\n return clip.forceForward;\n }\n if (fetch.direction !== Direction.forward) {\n if (lastIndex + 1 <= buffer.absMaxIndex) {\n return true;\n }\n }\n return false;\n }\n\n static prepareClipByDirection(scroller: Scroller, direction: Direction, edgeIndex: number): void {\n const forward = direction === Direction.forward;\n scroller.buffer.items.forEach(item => {\n if (\n (!forward && item.$index < edgeIndex) ||\n (forward && item.$index > edgeIndex)\n ) {\n item.toRemove = true;\n item.removeDirection = direction;\n scroller.state.clip.doClip = true;\n }\n });\n }\n\n}\n","import { BaseProcessFactory, CommonProcess, ProcessStatus } from './misc/index';\r\nimport { Scroller } from '../scroller';\r\nimport { Direction } from '../inputs/index';\r\n\r\nexport default class Clip extends BaseProcessFactory(CommonProcess.clip) {\r\n\r\n static run(scroller: Scroller): void {\r\n const { workflow } = scroller;\r\n\r\n Clip.doClip(scroller);\r\n\r\n workflow.call({\r\n process: Clip.process,\r\n status: ProcessStatus.next\r\n });\r\n }\r\n\r\n static doClip(scroller: Scroller): void {\r\n const { buffer, viewport: { paddings }, state: { clip }, logger } = scroller;\r\n const size = { [Direction.backward]: 0, [Direction.forward]: 0 };\r\n\r\n logger.stat(`before clip (${++clip.callCount})`);\r\n\r\n const itemsToRemove = buffer.items.filter(item => {\r\n if (!item.toRemove) {\r\n return false;\r\n }\r\n item.hide();\r\n size[item.removeDirection] += item.size;\r\n return true;\r\n });\r\n\r\n if (itemsToRemove.length) {\r\n if (size[Direction.backward]) {\r\n paddings.byDirection(Direction.backward).size += size[Direction.backward];\r\n }\r\n if (size[Direction.forward]) {\r\n paddings.byDirection(Direction.forward).size += size[Direction.forward];\r\n }\r\n if (scroller.settings.onBeforeClip) {\r\n scroller.settings.onBeforeClip(itemsToRemove.map(item => item.get()));\r\n }\r\n }\r\n\r\n buffer.clip();\r\n\r\n logger.log(() => {\r\n const list = itemsToRemove.map(({ $index }) => $index);\r\n return list.length\r\n ? [\r\n `clipped ${list.length} item(s) from Buffer` +\r\n (size.backward ? `, +${size.backward} fwd px` : '') +\r\n (size.forward ? `, +${size.forward} bwd px` : '') +\r\n `, range: [${list[0]}..${list[list.length - 1]}]`\r\n ]\r\n : 'clipped 0 items from Buffer';\r\n });\r\n\r\n logger.stat('after clip');\r\n }\r\n\r\n}\r\n","import { Scroller } from '../scroller';\nimport { CommonProcess, AdapterProcess, ProcessStatus as Status } from '../processes/index';\nimport { IPackages, ProcessSubject } from '../interfaces/index';\n\ntype LogType = [unknown?, ...unknown[]];\n\nexport class Logger {\n\n readonly debug: boolean;\n readonly immediateLog: boolean;\n readonly logTime: boolean;\n readonly getTime: () => string;\n readonly getStat: () => string;\n readonly getFetchRange: () => string;\n readonly getWorkflowCycleData: () => string;\n readonly getLoopId: () => string;\n readonly getLoopIdNext: () => string;\n readonly getScrollPosition: (element: HTMLElement) => number;\n private logs: unknown[][] = [];\n\n constructor(scroller: Scroller, packageInfo: IPackages, adapter?: { id: number }) {\n const { settings } = scroller;\n this.debug = settings.debug;\n this.immediateLog = settings.immediateLog;\n this.logTime = settings.logTime;\n this.getTime = (): string =>\n scroller.state && ` // time: ${scroller.state.time}`;\n this.getStat = (): string => {\n const { buffer, viewport } = scroller;\n const first = buffer.getFirstVisibleItem();\n const last = buffer.getLastVisibleItem();\n return 'pos: ' + viewport.scrollPosition + ', ' +\n 'size: ' + viewport.getScrollableSize() + ', ' +\n 'bwd_p: ' + viewport.paddings.backward.size + ', ' +\n 'fwd_p: ' + viewport.paddings.forward.size + ', ' +\n 'default: ' + (buffer.defaultSize || 'no') + ', ' +\n 'items: ' + buffer.getVisibleItemsCount() + ', ' +\n 'range: ' + (first && last ? `[${first.$index}..${last.$index}]` : 'no');\n };\n this.getFetchRange = (): string => {\n const { first: { index: first }, last: { index: last } } = scroller.state.fetch;\n return !Number.isNaN(first) && !Number.isNaN(last)\n ? `[${first}..${last}]`\n : 'no';\n };\n this.getLoopId = (): string => scroller.state.cycle.loopId;\n this.getLoopIdNext = (): string => scroller.state.cycle.loopIdNext;\n this.getWorkflowCycleData = (): string =>\n `${settings.instanceIndex}-${scroller.state.cycle.count}`;\n this.getScrollPosition = (element: HTMLElement) => scroller.routines.getScrollPosition(element);\n this.log(() =>\n 'vscroll Workflow has been started, ' +\n `core: ${packageInfo.core.name} v${packageInfo.core.version}, ` +\n `consumer: ${packageInfo.consumer.name} v${packageInfo.consumer.version}, ` +\n `scroller instance: ${settings.instanceIndex}, adapter ` +\n (!adapter ? 'is not instantiated' : `instance: ${adapter.id}`)\n );\n }\n\n object(str: string, obj: unknown, stringify?: boolean): void {\n this.log(() => [\n str,\n stringify\n ? JSON.stringify(obj, (k, v) => {\n if (Number.isNaN(v)) {\n return 'NaN';\n }\n if (v === Infinity) {\n return 'Infinity';\n }\n if (v === -Infinity) {\n return '-Infinity';\n }\n if (v instanceof Element) {\n return 'HTMLElement';\n }\n if (v instanceof HTMLDocument) {\n return 'HTMLDocument';\n }\n if (typeof v === 'function') {\n return 'Function';\n }\n return v;\n })\n .replace(/\"/g, '')\n .replace(/(\\{|:|,)/g, '$1 ')\n .replace(/(\\})/g, ' $1')\n : obj\n ]);\n }\n\n stat(str?: string): void {\n if (this.debug) {\n const logStyles = [\n 'color: #888; border: dashed #888 0; border-bottom-width: 0px',\n 'color: #000; border-width: 0'\n ];\n this.log(() => ['%cstat' + (str ? ` ${str}` : '') + ',%c ' + this.getStat(), ...logStyles]);\n }\n }\n\n fetch(str?: string): void {\n if (this.debug) {\n const _text = 'fetch interval' + (str ? ` ${str}` : '');\n const logStyles = ['color: #888', 'color: #000'];\n this.log(() => [`%c${_text}: %c${this.getFetchRange()}`, ...logStyles]);\n }\n }\n\n prepareForLog(data: unknown): unknown {\n return data instanceof Event && data.target\n ? this.getScrollPosition(data.target as HTMLElement)\n : data;\n }\n\n logProcess(data: ProcessSubject): void {\n if (!this.debug) {\n return;\n }\n const { process, status, payload } = data;\n\n // inner loop start-end log\n const loopLog: string[] = [];\n if (\n process === CommonProcess.init && status === Status.next\n ) {\n loopLog.push(`%c---=== loop ${this.getLoopIdNext()} start`);\n } else if (\n process === CommonProcess.end\n ) {\n loopLog.push(`%c---=== loop ${this.getLoopId()} done`);\n const parent = payload && payload.process;\n if (status === Status.next && (parent !== AdapterProcess.reset && parent !== AdapterProcess.reload)) {\n loopLog[0] += `, loop ${this.getLoopIdNext()} start`;\n }\n }\n if (loopLog.length) {\n this.log(() => [...loopLog, 'color: #006600;']);\n }\n }\n\n logCycle(start = true): void {\n const logData = this.getWorkflowCycleData();\n const border = start ? '1px 0 0 1px' : '0 0 1px 1px';\n const logStyles = `color: #0000aa; border: solid #555 1px; border-width: ${border}; margin-left: -2px`;\n this.log(() => [`%c ~~~ WF Cycle ${logData} ${start ? 'STARTED' : 'FINALIZED'} ~~~ `, logStyles]);\n }\n\n logError(str: string): void {\n if (this.debug) {\n const logStyles = ['color: #a00;', 'color: #000'];\n this.log(() => ['error:%c' + (str ? ` ${str}` : '') + `%c (loop ${this.getLoopIdNext()})`, ...logStyles]);\n }\n }\n\n logAdapterMethod = (methodName: string, args?: unknown, add?: string): void => {\n if (!this.debug) {\n return;\n }\n const params = (\n args === void 0 ? [] : (Array.isArray(args) ? args : [args])\n )\n .map((arg: unknown) => {\n if (typeof arg === 'function') {\n return 'func';\n } else if (typeof arg !== 'object' || !arg) {\n return arg;\n } else if (Array.isArray(arg)) {\n return `[of ${arg.length}]`;\n }\n return '{ ' + Object.keys(arg).join(', ') + ' }';\n })\n .join(', ');\n this.log(`adapter: ${methodName}(${params || ''})${add || ''}`);\n }\n\n log(...args: any[]): void {\n if (this.debug) {\n if (typeof args[0] === 'function') {\n args = args[0]();\n if (!Array.isArray(args)) {\n args = [args];\n }\n }\n if (args.every(item => item === void 0)) {\n return;\n }\n if (this.logTime) {\n args = [...args, this.getTime()];\n }\n args = args.map((arg: unknown) => this.prepareForLog(arg));\n if (this.immediateLog) {\n console.log.apply(this, args as LogType);\n } else {\n this.logs.push(args);\n }\n }\n }\n\n // logNow(...args: any[]) {\n // const immediateLog = this.immediateLog;\n // const debug = this.debug;\n // (this as any).debug = true;\n // (this as any).immediateLog = true;\n // this.log.apply(this, args);\n // (this as any).debug = debug;\n // (this as any).immediateLog = immediateLog;\n // }\n\n logForce(...args: unknown[]): void {\n if (this.debug) {\n if (!this.immediateLog && this.logs.length) {\n this.logs.forEach(logArgs => console.log.apply(this, logArgs));\n this.logs = [];\n }\n if (args.length) {\n console.log.apply(this, args as LogType);\n }\n }\n }\n}\n","import { Settings } from './settings';\nimport { Direction } from '../inputs/index';\n\nexport class Routines {\n\n readonly horizontal: boolean;\n readonly window: boolean;\n readonly viewport: HTMLElement | null;\n\n constructor(settings: Settings) {\n this.horizontal = settings.horizontal;\n this.window = settings.windowViewport;\n this.viewport = settings.viewport;\n }\n\n checkElement(element: HTMLElement): void {\n if (!element) {\n throw new Error('HTML element is not defined');\n }\n }\n\n getHostElement(element: HTMLElement): HTMLElement {\n if (this.window) {\n return document.documentElement;\n }\n if (this.viewport) {\n return this.viewport;\n }\n this.checkElement(element);\n const parent = element.parentElement as HTMLElement;\n this.checkElement(parent);\n return parent;\n }\n\n getScrollEventReceiver(element: HTMLElement): HTMLElement | Window {\n if (this.window) {\n return window;\n }\n return this.getHostElement(element);\n }\n\n setupScrollRestoration(): void {\n if ('scrollRestoration' in history) {\n history.scrollRestoration = 'manual';\n }\n }\n\n dismissOverflowAnchor(element: HTMLElement): void {\n this.checkElement(element);\n element.style.overflowAnchor = 'none';\n }\n\n findElementBySelector(element: HTMLElement, selector: string): HTMLElement | null {\n this.checkElement(element);\n return element.querySelector(selector);\n }\n\n findPaddingElement(element: HTMLElement, direction: Direction): HTMLElement | null {\n return this.findElementBySelector(element, `[data-padding-${direction}]`);\n }\n\n findItemElement(element: HTMLElement, id: string): HTMLElement | null {\n return this.findElementBySelector(element, `[data-sid=\"${id}\"]`);\n }\n\n getScrollPosition(element: HTMLElement): number {\n if (this.window) {\n return window.pageYOffset;\n }\n this.checkElement(element);\n return element[this.horizontal ? 'scrollLeft' : 'scrollTop'];\n }\n\n setScrollPosition(element: HTMLElement, value: number): void {\n value = Math.max(0, value);\n if (this.window) {\n if (this.horizontal) {\n window.scrollTo(value, window.scrollY);\n } else {\n window.scrollTo(window.scrollX, value);\n }\n return;\n }\n this.checkElement(element);\n element[this.horizontal ? 'scrollLeft' : 'scrollTop'] = value;\n }\n\n getParams(element: HTMLElement, doNotBind?: boolean): DOMRect {\n this.checkElement(element);\n if (this.window && doNotBind) {\n const { clientWidth, clientHeight, clientLeft, clientTop } = element;\n return {\n 'height': clientHeight,\n 'width': clientWidth,\n 'top': clientTop,\n 'bottom': clientTop + clientHeight,\n 'left': clientLeft,\n 'right': clientLeft + clientWidth,\n 'x': clientLeft,\n 'y': clientTop,\n 'toJSON': () => null,\n };\n }\n return element.getBoundingClientRect();\n }\n\n getSize(element: HTMLElement, doNotBind?: boolean): number {\n return this.getParams(element, doNotBind)[this.horizontal ? 'width' : 'height'];\n }\n\n getSizeStyle(element: HTMLElement): number {\n this.checkElement(element);\n const size = element.style[this.horizontal ? 'width' : 'height'];\n return parseFloat(size as string) || 0;\n }\n\n setSizeStyle(element: HTMLElement, value: number): void {\n this.checkElement(element);\n value = Math.max(0, Math.round(value));\n element.style[this.horizontal ? 'width' : 'height'] = `${value}px`;\n }\n\n getEdge(element: HTMLElement, direction: Direction, doNotBind?: boolean): number {\n const params = this.getParams(element, doNotBind);\n const isFwd = direction === Direction.forward;\n return params[isFwd ? (this.horizontal ? 'right' : 'bottom') : (this.horizontal ? 'left' : 'top')];\n }\n\n getEdge2(element: HTMLElement, direction: Direction, relativeElement: HTMLElement, opposite: boolean): number {\n // vertical only ?\n return element.offsetTop - (relativeElement ? relativeElement.scrollTop : 0) +\n (direction === (!opposite ? Direction.forward : Direction.backward) ? this.getSize(element) : 0);\n }\n\n makeElementVisible(element: HTMLElement): void {\n this.checkElement(element);\n element.style.left = '';\n element.style.top = '';\n element.style.position = '';\n }\n\n hideElement(element: HTMLElement): void {\n this.checkElement(element);\n element.style.display = 'none';\n }\n\n getOffset(element: HTMLElement): number {\n this.checkElement(element);\n return (this.horizontal ? element.offsetLeft : element.offsetTop) || 0;\n }\n\n scrollTo(element: HTMLElement, argument?: boolean | ScrollIntoViewOptions): void {\n this.checkElement(element);\n element.scrollIntoView(argument);\n }\n\n render(cb: () => void): () => void {\n const timeoutId = setTimeout(() => cb());\n return () => clearTimeout(timeoutId);\n }\n\n animate(cb: () => void): () => void {\n const animationFrameId = requestAnimationFrame(() => cb());\n return () => cancelAnimationFrame(animationFrameId);\n }\n\n onScroll(element: HTMLElement | Window, handler: EventListener): () => void {\n element.addEventListener('scroll', handler);\n return () => element.removeEventListener('scroll', handler);\n }\n\n}\n","import { Routines } from './domRoutines';\r\nimport { Settings } from './settings';\r\nimport { Direction } from '../inputs/index';\r\n\r\nexport class Padding {\r\n\r\n element: HTMLElement;\r\n direction: Direction;\r\n routines: Routines;\r\n\r\n constructor(element: HTMLElement, direction: Direction, routines: Routines) {\r\n const found = routines.findPaddingElement(element, direction);\r\n routines.checkElement(found as HTMLElement);\r\n this.element = found as HTMLElement;\r\n this.direction = direction;\r\n this.routines = routines;\r\n }\r\n\r\n reset(size?: number): void {\r\n this.size = size || 0;\r\n }\r\n\r\n get size(): number {\r\n return this.routines.getSizeStyle(this.element);\r\n }\r\n\r\n set size(value: number) {\r\n this.routines.setSizeStyle(this.element, value);\r\n }\r\n\r\n}\r\n\r\nexport class Paddings {\r\n settings: Settings;\r\n forward: Padding;\r\n backward: Padding;\r\n\r\n constructor(element: HTMLElement, routines: Routines, settings: Settings) {\r\n this.settings = settings;\r\n this.forward = new Padding(element, Direction.forward, routines);\r\n this.backward = new Padding(element, Direction.backward, routines);\r\n }\r\n\r\n byDirection(direction: Direction, opposite?: boolean): Padding {\r\n return direction === Direction.backward\r\n ? (opposite ? this.forward : this.backward)\r\n : (opposite ? this.backward : this.forward);\r\n }\r\n\r\n reset(viewportSize: number, startIndex: number, offset: number): void {\r\n const positive = this.getPositiveSize(startIndex, viewportSize, offset);\r\n const negative = this.getNegativeSize(startIndex);\r\n if (this.settings.inverse) {\r\n this.forward.reset(negative);\r\n this.backward.reset(positive);\r\n const diff = viewportSize - this.backward.size - offset;\r\n if (diff > 0) {\r\n this.backward.size += diff;\r\n this.forward.size -= diff;\r\n }\r\n } else {\r\n this.forward.reset(positive);\r\n this.backward.reset(negative);\r\n const diff = viewportSize - this.forward.size - offset;\r\n if (diff > 0) {\r\n this.backward.size -= diff;\r\n this.forward.size += diff;\r\n }\r\n }\r\n\r\n }\r\n\r\n getPositiveSize(startIndex: number, viewportSize: number, offset: number): number {\r\n const { settings } = this;\r\n let positiveSize = viewportSize;\r\n if (isFinite(settings.maxIndex)) {\r\n positiveSize = (settings.maxIndex - startIndex + 1) * settings.itemSize;\r\n }\r\n if (offset) {\r\n positiveSize = Math.max(positiveSize - offset, 0);\r\n }\r\n return positiveSize;\r\n }\r\n\r\n getNegativeSize(startIndex: number): number {\r\n const { settings } = this;\r\n let negativeSize = 0;\r\n if (isFinite(settings.minIndex)) {\r\n negativeSize = (startIndex - settings.minIndex) * settings.itemSize;\r\n }\r\n return negativeSize;\r\n }\r\n}\r\n","import { Paddings } from './paddings';\nimport { Settings } from './settings';\nimport { Routines } from './domRoutines';\nimport { Item } from './item';\nimport { State } from './state';\nimport { Logger } from './logger';\nimport { Direction } from '../inputs/index';\n\nexport class Viewport {\n\n offset: number;\n paddings: Paddings;\n\n readonly element: HTMLElement;\n readonly settings: Settings;\n readonly routines: Routines;\n readonly state: State;\n readonly logger: Logger;\n\n readonly hostElement: HTMLElement;\n readonly scrollEventReceiver: HTMLElement | Window;\n\n constructor(element: HTMLElement, settings: Settings, routines: Routines, state: State, logger: Logger) {\n this.element = element;\n this.settings = settings;\n this.routines = routines;\n this.state = state;\n this.logger = logger;\n\n this.hostElement = this.routines.getHostElement(this.element);\n this.scrollEventReceiver = this.routines.getScrollEventReceiver(this.element);\n\n if (settings.windowViewport) {\n this.routines.setupScrollRestoration();\n }\n if (settings.dismissOverflowAnchor) {\n this.routines.dismissOverflowAnchor(this.hostElement);\n }\n\n this.paddings = new Paddings(this.element, this.routines, settings);\n }\n\n reset(startIndex: number): void {\n this.setOffset();\n this.paddings.reset(this.getSize(), startIndex, this.offset);\n this.scrollPosition = this.paddings.backward.size || 0;\n this.state.scroll.reset();\n }\n\n setPosition(value: number): number {\n const oldPosition = this.scrollPosition;\n if (oldPosition === value) {\n this.logger.log(() => ['setting scroll position at', value, '[cancelled]']);\n return value;\n }\n this.routines.setScrollPosition(this.hostElement, value);\n const position = this.scrollPosition;\n this.logger.log(() => [\n 'setting scroll position at', position, ...(position !== value ? [`(${value})`] : [])\n ]);\n return position;\n }\n\n get scrollPosition(): number {\n return this.routines.getScrollPosition(this.hostElement);\n }\n\n set scrollPosition(value: number) {\n this.setPosition(value);\n }\n\n getSize(): number {\n return this.routines.getSize(this.hostElement, true);\n }\n\n getScrollableSize(): number {\n return this.routines.getSize(this.element);\n }\n\n getMaxScrollPosition(): number {\n return this.getScrollableSize() - this.getSize();\n }\n\n getBufferPadding(): number {\n return this.getSize() * this.settings.padding;\n }\n\n getEdge(direction: Direction): number {\n return this.routines.getEdge(this.hostElement, direction, true);\n }\n\n setOffset(): void {\n this.offset = this.routines.getOffset(this.element);\n if (!this.settings.windowViewport) {\n this.offset -= this.routines.getOffset(this.hostElement);\n }\n }\n\n findItemElementById(id: string): HTMLElement | null {\n return this.routines.findItemElement(this.element, id);\n }\n\n getEdgeVisibleItem(items: Item[], direction: Direction): { item?: Item, index: number, diff: number } {\n const bwd = direction === Direction.backward;\n const opposite = bwd ? Direction.forward : Direction.backward;\n const viewportEdge = this.getEdge(direction);\n let item, diff = 0;\n for (\n let i = bwd ? 0 : items.length - 1;\n bwd ? i <= items.length - 1 : i >= 0;\n i += bwd ? 1 : -1\n ) {\n const itemEdge = this.routines.getEdge(items[i].element, opposite);\n diff = itemEdge - viewportEdge;\n if (bwd && diff > 0 || !bwd && diff < 0) {\n item = items[i];\n break;\n }\n }\n return { item, index: item ? item.$index : NaN, diff };\n }\n\n}\n","import { SizeStrategy } from '../../inputs/index';\n\ninterface ItemSize {\n size: number;\n newSize?: number;\n}\n\nexport class SizesRecalculation {\n newItems: ItemSize[];\n oldItems: ItemSize[];\n removed: ItemSize[];\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.newItems = [];\n this.oldItems = [];\n this.removed = [];\n }\n}\n\nexport class DefaultSize {\n private readonly itemSize: number;\n private readonly sizeStrategy: SizeStrategy;\n private sizeMap: Map<number, number>;\n private recalculation: SizesRecalculation;\n\n private constantSize: number;\n private frequentSize: number;\n private averageSize: number;\n private averageSizeFloat: number;\n\n constructor(itemSize: number, sizeStrategy: SizeStrategy) {\n this.itemSize = itemSize;\n this.sizeStrategy = sizeStrategy;\n this.sizeMap = new Map<number, number>();\n this.recalculation = new SizesRecalculation();\n }\n\n reset(force: boolean): void {\n if (force) {\n this.constantSize = this.itemSize;\n this.frequentSize = this.itemSize;\n this.averageSize = this.itemSize;\n this.averageSizeFloat = this.itemSize;\n this.sizeMap.clear();\n }\n this.recalculation.reset();\n }\n\n get(): number {\n switch (this.sizeStrategy) {\n case SizeStrategy.Average:\n return this.averageSize;\n case SizeStrategy.Frequent:\n return this.frequentSize;\n default:\n return this.constantSize;\n }\n }\n\n private recalculateAverageSize(cacheSize: number): void {\n const { oldItems, newItems, removed } = this.recalculation;\n if (oldItems.length) {\n const oldSize = oldItems.reduce((acc, item) => acc + item.size, 0);\n const newSize = oldItems.reduce((acc, item) => acc + (item.newSize as number), 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = averageSize - (oldSize - newSize) / (cacheSize - newItems.length);\n }\n if (newItems.length) {\n const newSize = newItems.reduce((acc, item) => acc + item.size, 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = ((cacheSize - newItems.length) * averageSize + newSize) / cacheSize;\n }\n if (removed.length) {\n const removedSize = removed.reduce((acc, item) => acc + item.size, 0);\n const averageSize = this.averageSizeFloat || 0;\n this.averageSizeFloat = ((cacheSize + removed.length) * averageSize - removedSize) / cacheSize;\n }\n this.averageSize = Math.round(this.averageSizeFloat);\n }\n\n private recalculateFrequentSize(): void {\n const { oldItems, newItems, removed } = this.recalculation;\n const oldFrequentSizeCount = this.sizeMap.get(this.frequentSize);\n if (newItems.length) {\n newItems.forEach(({ size }) => this.sizeMap.set(size, (this.sizeMap.get(size) || 0) + 1));\n }\n if (oldItems.length) {\n oldItems.forEach(({ size }) => this.sizeMap.set(size, Math.max((this.sizeMap.get(size) || 0) - 1, 0)));\n oldItems.forEach(({ newSize: s }) => this.sizeMap.set(s as number, (this.sizeMap.get(s as number) || 0) + 1));\n }\n if (removed.length) {\n removed.forEach(({ size }) => this.sizeMap.set(size, Math.max((this.sizeMap.get(size) || 0) - 1, 0)));\n }\n const sorted = [...this.sizeMap.entries()].sort((a, b) => b[1] - a[1]);\n const mostFrequentCount = sorted[0][1];\n const listEqual = sorted.filter(i => i[1] === mostFrequentCount);\n if (listEqual.length > 1 && listEqual.find(i => i[0] === oldFrequentSizeCount)) {\n // if there are more than 1 most frequent sizes, but the old one is present\n return;\n }\n this.frequentSize = sorted[0][0];\n }\n\n recalculate(cacheSize: number): boolean {\n if (this.sizeStrategy === SizeStrategy.Constant) {\n return false;\n }\n const { oldItems, newItems, removed } = this.recalculation;\n if (!oldItems.length && !newItems.length && !removed.length) {\n return false;\n }\n const oldValue = this.get();\n if (!cacheSize) {\n this.reset(true);\n } else {\n if (this.sizeStrategy === SizeStrategy.Average) {\n this.recalculateAverageSize(cacheSize);\n } else {\n this.recalculateFrequentSize();\n }\n this.recalculation.reset();\n }\n return this.get() !== oldValue;\n }\n\n setExisted(oldSize: number, newSize: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.oldItems.push({\n size: oldSize,\n newSize\n });\n }\n }\n\n setNew(size: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.newItems.push({ size });\n } else {\n if (!this.constantSize) {\n this.constantSize = size;\n }\n }\n }\n\n setRemoved(size: number): void {\n if (this.sizeStrategy !== SizeStrategy.Constant) {\n this.recalculation.removed.push({ size });\n }\n }\n}\n","import { DefaultSize } from './defaultSize';\nimport { Item } from '../item';\nimport { Settings } from '../settings';\nimport { Logger } from '../logger';\nimport { SizeStrategy, Direction } from '../../inputs/index';\n\ninterface ItemToCache<Data> {\n $index: number;\n data: Data;\n size?: number;\n}\n\ninterface ItemUpdate {\n $index: number;\n size: number;\n toRemove?: boolean;\n}\n\nexport class ItemCache<Data = unknown> {\n $index: number;\n data: Data | null;\n size?: number;\n position: number;\n\n constructor(item: ItemToCache<Data>, saveData: boolean) {\n this.$index = item.$index;\n this.data = saveData ? item.data : null;\n this.size = item.size;\n }\n\n changeIndex(value: number): void {\n this.$index = value;\n }\n}\n\nexport class Cache<Data = unknown> {\n minIndex: number;\n maxIndex: number;\n\n readonly itemSize: number;\n readonly saveData: boolean;\n readonly cacheOnReload: boolean;\n readonly sizeStrategy: SizeStrategy;\n readonly logger: Logger;\n private items: Map<number, ItemCache<Data>>;\n private defaultSize: DefaultSize;\n\n constructor({ itemSize, cacheData, cacheOnReload, sizeStrategy }: Settings, logger: Logger) {\n this.itemSize = itemSize;\n this.saveData = cacheData;\n this.cacheOnReload = cacheOnReload;\n this.sizeStrategy = sizeStrategy;\n this.logger = logger;\n this.items = new Map<number, ItemCache<Data>>();\n this.defaultSize = new DefaultSize(itemSize, sizeStrategy);\n this.reset(true);\n }\n\n reset(force: boolean): void {\n force = force || !this.cacheOnReload;\n if (force) {\n this.minIndex = +Infinity;\n this.maxIndex = -Infinity;\n this.items.clear();\n }\n this.defaultSize.reset(force);\n }\n\n get size(): number {\n return this.items.size;\n }\n\n get(index: number): ItemCache<Data> | undefined {\n return this.items.get(index);\n }\n\n getSizeByIndex(index: number): number {\n const item = this.get(index);\n return item && item.size || this.defaultSize.get();\n }\n\n getDefaultSize(): number {\n return this.defaultSize.get();\n }\n\n recalculateDefaultSize(): boolean {\n if (this.defaultSize.recalculate(this.size)) {\n this.logger.log(() => `default size has been updated: ${this.defaultSize.get()}`);\n return true;\n }\n return false;\n }\n\n /**\n * Adds item to Set by $index, replaces existed item if $index matches.\n * Maintains min/max indexes and default item size.\n *\n * @param {Item<Data>} item A Buffer item to be cached, an objects with { $index, data, size } props.\n * \n * @returns {ItemCache<Data>} Cached item.\n */\n add(item: Item<Data>): ItemCache<Data> {\n let itemCache = this.get(item.$index);\n if (itemCache) { // adding item is already cached\n if (this.saveData) {\n itemCache.data = item.data;\n }\n if (itemCache.size !== item.size) {\n if (itemCache.size) {\n this.defaultSize.setExisted(itemCache.size, item.size);\n } else {\n this.defaultSize.setNew(item.size);\n }\n itemCache.size = item.size;\n }\n } else {\n itemCache = new ItemCache<Data>(item, this.saveData);\n this.items.set(item.$index, itemCache);\n this.defaultSize.setNew(item.size);\n }\n if (item.$index < this.minIndex) {\n this.minIndex = item.$index;\n }\n if (item.$index > this.maxIndex) {\n this.maxIndex = item.$index;\n }\n return itemCache;\n }\n\n /**\n * Inserts items to Set, shifts $indexes of items that remain.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes.\n *\n * @param {Data[]} toInsert List of non-indexed items to be inserted.\n * @param {number} index The index before/after which the insertion is performed.\n * @param {Direction} direction Determines the direction of insertion.\n * @param {boolean} fixRight Defines indexes shifting strategy.\n * If false, indexes that are greater than the inserted ones are increased.\n * If true, indexes that are less than than the inserted ones are decreased.\n */\n insertItems(toInsert: Data[], index: number, direction: Direction, fixRight: boolean): void {\n const items = new Map<number, ItemCache<Data>>();\n const length = toInsert.length;\n let min = Infinity, max = -Infinity;\n const set = (item: ItemCache<Data>) => {\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n };\n this.items.forEach(item => {\n let shift = 0;\n if (direction === Direction.backward) {\n if (item.$index < index && fixRight) {\n shift = -length;\n } else if (item.$index >= index && !fixRight) {\n shift = length;\n }\n } else if (direction === Direction.forward) {\n if (item.$index <= index && fixRight) {\n shift = -length;\n } else if (item.$index > index && !fixRight) {\n shift = length;\n }\n }\n if (shift) {\n item.changeIndex(item.$index + shift);\n }\n set(item);\n });\n if (this.saveData) { // persist data with no sizes\n toInsert.forEach((data, i) => {\n const $index = index + i - (fixRight ? length : 0) + (direction === Direction.forward ? 1 : 0);\n const item = new ItemCache<Data>({ $index, data }, this.saveData);\n set(item);\n });\n }\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n\n /**\n * Removes items from Set, shifts $indexes of items that remain.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes and default item size.\n *\n * @param {number[]} toRemove List of indexes to be removed.\n * @param {boolean} fixRight Defines indexes shifting strategy.\n * If false, indexes that are greater than the removed ones will be decreased.\n * If true, indexes that are less than than the removed ones will be increased.\n */\n removeItems(toRemove: number[], fixRight: boolean): void {\n const items = new Map<number, ItemCache<Data>>();\n let min = Infinity, max = -Infinity;\n this.items.forEach(item => {\n if (toRemove.some(index => index === item.$index)) {\n if (item.size) {\n this.defaultSize.setRemoved(item.size);\n }\n return;\n }\n const diff = fixRight\n ? toRemove.reduce((acc, index) => acc + (item.$index < index ? 1 : 0), 0)\n : toRemove.reduce((acc, index) => acc - (item.$index > index ? 1 : 0), 0);\n item.changeIndex(item.$index + diff);\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n });\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n\n /**\n * Destructively updates Set based on subset (before-after) changes.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes. Maintains default item size on remove only.\n *\n * @param {ItemUpdate[]} before Initial subset of items to be replaced by \"after\".\n * Each element is an object with { $index, size, toRemove } props. Must be $index-incremental.\n * Items to be removed must have toRemove flag: before[].toRemove = true.\n * @param {Item<Data>[]} after Transformed subset that replaces \"before\". Must be $index-incremental.\n * Must contain at least 1 $index from \"before\" or be empty.\n * @param {boolean} fixRight This is to fix right indexes during subset collapsing. Acts only if \"after\" is empty.\n */\n updateSubset(before: ItemUpdate[], after: Item<Data>[], fixRight?: boolean): void {\n if (!this.size || !before.length) {\n return;\n }\n const minB = before[0].$index, maxB = before[before.length - 1].$index;\n let leftDiff: number, rightDiff: number;\n if (after.length) {\n const minA = after[0].$index, maxA = after[after.length - 1].$index;\n leftDiff = minA - minB;\n rightDiff = maxA - maxB;\n } else {\n leftDiff = fixRight ? maxB - minB + 1 : 0;\n rightDiff = fixRight ? 0 : minB - maxB - 1;\n }\n const items = new Map<number, ItemCache<Data>>();\n this.items.forEach(item => {\n if (item.$index < minB) { // items to the left of the subset\n item.changeIndex(item.$index + leftDiff);\n items.set(item.$index, item);\n return;\n } else if (item.$index > maxB) { // items to the right of the subset\n item.changeIndex(item.$index + rightDiff);\n items.set(item.$index, item);\n return;\n }\n });\n after.forEach(item => // subset items\n items.set(item.$index, new ItemCache<Data>(item, this.saveData))\n );\n before // to maintain default size on remove\n .filter(item => item.toRemove)\n .forEach(item => this.defaultSize.setRemoved(item.size));\n this.minIndex += leftDiff;\n this.maxIndex += rightDiff;\n this.items = items;\n }\n\n /**\n * Shifts all indexes by some value.\n * Replaces current Set with a new one with new regular $indexes.\n * Maintains min/max indexes.\n *\n * @param {number} delta A shift value.\n */\n shiftIndexes(delta: number): void {\n const items = new Map<number, ItemCache<Data>>();\n let min = Infinity, max = -Infinity;\n this.items.forEach(item => {\n item.changeIndex(item.$index + delta);\n items.set(item.$index, item);\n min = item.$index < min ? item.$index : min;\n max = item.$index > max ? item.$index : max;\n });\n this.items = items;\n this.minIndex = min;\n this.maxIndex = max;\n }\n}\n","import { Buffer } from '../buffer';\nimport { Logger } from '../logger';\nimport { Direction } from '../../inputs/index';\nimport { ItemsPredicate } from '../../interfaces/index';\n\nexport class CheckBufferCall<Data> {\n private context: Buffer<Data>;\n private logger: Logger;\n\n constructor(context: Buffer<Data>, logger: Logger) {\n this.context = context;\n this.logger = logger;\n }\n\n fillEmpty(items: Data[], before?: number, after?: number): boolean {\n if (!items.length) {\n this.logger.log('no items to fill the buffer; empty list');\n return false;\n }\n if (!Number.isInteger(before) && !Number.isInteger(after)) {\n this.logger.log('no items to fill the buffer; wrong indexes');\n return false;\n }\n this.logger.log(() => `going to fill the buffer with ${items.length} item(s)`);\n return true;\n }\n\n insertInBuffer(predicate?: ItemsPredicate, before?: number, after?: number): number {\n const index = Number.isInteger(before) ? before : (Number.isInteger(after) ? after : NaN);\n const found = this.context.items.find(item =>\n (predicate && predicate(item.get())) ||\n (Number.isInteger(index) && index === item.$index)\n );\n if (!found) {\n this.logger.log('no items to insert in buffer; empty predicate\\'s result');\n return NaN;\n }\n return found.$index;\n }\n\n insertVirtual(items: Data[], index: number, direction: Direction): boolean {\n if (!items.length) {\n this.logger.log('no items to insert virtually; empty list');\n return false;\n }\n const { firstIndex, lastIndex, finiteAbsMinIndex, finiteAbsMaxIndex } = this.context;\n if (index < finiteAbsMinIndex || index > finiteAbsMaxIndex) {\n this.logger.log(() =>\n 'no items to insert virtually; ' +\n `selected index (${index}) does not match virtual area [${finiteAbsMinIndex}..${finiteAbsMaxIndex}]`\n );\n return false;\n }\n const before = direction === Direction.backward;\n if (!(index < firstIndex + (before ? 1 : 0) || index > lastIndex - (before ? 0 : 1))) {\n this.logger.log(() =>\n `no items to insert virtually; selected index (${index}) belongs Buffer [${firstIndex}..${lastIndex}]`\n );\n return false;\n }\n this.logger.log(() => `going to insert ${items.length} item(s) virtually`);\n return true;\n }\n\n}\n","import { Cache } from './buffer/cache';\nimport { CheckBufferCall } from './buffer/checkCall';\nimport { Item } from './item';\nimport { Settings } from './settings';\nimport { Logger } from './logger';\nimport { Reactive } from './reactive';\nimport { Direction } from '../inputs/index';\nimport { OnDataChanged, BufferUpdater, ItemsPredicate } from '../interfaces/index';\n\nexport class Buffer<Data> {\n\n private _items: Item<Data>[] = [];\n private _absMinIndex: number;\n private _absMaxIndex: number;\n bof: Reactive<boolean>;\n eof: Reactive<boolean>;\n\n changeItems: OnDataChanged<Data>;\n minIndexUser: number;\n maxIndexUser: number;\n startIndexUser: number;\n startIndex: number;\n\n private pristine: boolean;\n private cache: Cache<Data>;\n private checkCall: CheckBufferCall<Data>;\n private readonly logger: Logger;\n\n constructor(settings: Settings<Data>, onDataChanged: OnDataChanged<Data>, logger: Logger) {\n this.logger = logger;\n this.changeItems = onDataChanged;\n this.bof = new Reactive<boolean>(false);\n this.eof = new Reactive<boolean>(false);\n this.cache = new Cache<Data>(settings, logger);\n this.checkCall = new CheckBufferCall(this, logger);\n this.startIndexUser = settings.startIndex;\n this.minIndexUser = settings.minIndex;\n this.maxIndexUser = settings.maxIndex;\n this.reset(true);\n }\n\n dispose(): void {\n this.bof.dispose();\n this.eof.dispose();\n this._items.forEach(item => item.dispose());\n this._items = [];\n }\n\n reset(force: boolean, startIndex?: number): void {\n this.items.forEach(item => item.hide());\n this.pristine = true;\n this.items = [];\n this.cache.reset(force);\n this.absMinIndex = this.minIndexUser;\n this.absMaxIndex = this.maxIndexUser;\n this.setCurrentStartIndex(startIndex);\n this.bof.set(false);\n this.eof.set(false);\n this.pristine = false;\n }\n\n setCurrentStartIndex(newStartIndex?: unknown): void {\n const min = this.minIndexUser;\n const max = this.maxIndexUser;\n const start = this.startIndexUser;\n let index = Number(newStartIndex);\n if (Number.isNaN(index)) {\n this.logger.log(() => `fallback startIndex to settings.startIndex (${start})`);\n index = start;\n }\n if (index < min) {\n this.logger.log(() => `setting startIndex to settings.minIndex (${min}) because ${index} < ${min}`);\n index = min;\n }\n if (index > max) {\n this.logger.log(() => `setting startIndex to settings.maxIndex (${max}) because ${index} > ${max}`);\n index = max;\n }\n this.startIndex = index;\n }\n\n set items(items: Item<Data>[]) {\n this._items = items;\n this.changeItems(items);\n if (!this.pristine) {\n this.checkBOF();\n this.checkEOF();\n }\n }\n\n get items(): Item<Data>[] {\n return this._items;\n }\n\n set absMinIndex(value: number) {\n if (this._absMinIndex !== value) {\n this._absMinIndex = Number.isFinite(this._absMaxIndex) && value > this._absMaxIndex ? this._absMaxIndex : value;\n }\n if (!this.pristine) {\n this.checkBOF();\n }\n }\n\n get absMinIndex(): number {\n return this._absMinIndex;\n }\n\n set absMaxIndex(value: number) {\n if (this._absMaxIndex !== value) {\n this._absMaxIndex = Number.isFinite(this._absMinIndex) && value < this._absMinIndex ? this._absMinIndex : value;\n }\n if (!this.pristine) {\n this.checkEOF();\n }\n }\n\n get absMaxIndex(): number {\n return this._absMaxIndex;\n }\n\n private checkBOF() {\n // since bof has no setter, need to call checkBOF() on items and absMinIndex change\n const bof = this.items.length\n ? (this.items[0].$index === this.absMinIndex)\n : isFinite(this.absMinIndex);\n this.bof.set(bof);\n }\n\n private checkEOF() {\n // since eof has no setter, need to call checkEOF() on items and absMaxIndex change\n const eof = this.items.length\n ? (this.items[this.items.length - 1].$index === this.absMaxIndex)\n : isFinite(this.absMaxIndex);\n this.eof.set(eof);\n }\n\n get size(): number {\n return this._items.length;\n }\n\n get cacheSize(): number {\n return this.cache.size;\n }\n\n get defaultSize(): number {\n return this.cache.getDefaultSize();\n }\n\n get minIndex(): number {\n return isFinite(this.cache.minIndex) ? this.cache.minIndex : this.startIndex;\n }\n\n get maxIndex(): number {\n return isFinite(this.cache.maxIndex) ? this.cache.maxIndex : this.startIndex;\n }\n\n get firstIndex(): number {\n return this.items.length ? this.items[0].$index : NaN;\n }\n\n get lastIndex(): number {\n return this.items.length ? this.items[this.items.length - 1].$index : NaN;\n }\n\n get finiteAbsMinIndex(): number {\n return isFinite(this.absMinIndex) ? this.absMinIndex : this.minIndex;\n }\n\n get finiteAbsMaxIndex(): number {\n return isFinite(this.absMaxIndex) ? this.absMaxIndex : this.maxIndex;\n }\n\n get($index: number): Item<Data> | undefined {\n return this.items.find(item => item.$index === $index);\n }\n\n setItems(items: Item<Data>[]): boolean {\n if (!this.items.length) {\n this.items = [...items];\n } else if (this.items[0].$index > items[items.length - 1].$index) {\n this.items = [...items, ...this.items];\n } else if (items[0].$index > this.items[this.items.length - 1].$index) {\n this.items = [...this.items, ...items];\n } else {\n return false;\n }\n return true;\n }\n\n clip(): void {\n this.items = this.items.filter(({ toRemove }) => !toRemove);\n }\n\n getIndexToInsert(predicate?: ItemsPredicate, before?: number, after?: number): number {\n return this.checkCall.insertInBuffer(predicate, before, after);\n }\n\n private shiftExtremum(amount: number, fixRight: boolean) {\n if (!fixRight) {\n this.absMaxIndex += amount;\n } else {\n this.absMinIndex -= amount;\n this.startIndex -= amount;\n }\n if (this.startIndex > this.absMaxIndex) {\n this.startIndex = this.absMaxIndex;\n } else if (this.startIndex < this.absMinIndex) {\n this.startIndex = this.absMinIndex;\n }\n }\n\n insertVirtually(items: Data[], index: number, direction: Direction, fixRight: boolean): boolean {\n if (!this.checkCall.insertVirtual(items, index, direction)) {\n return false;\n }\n let shift = 0;\n if (index <= this.firstIndex && !fixRight) {\n shift = items.length;\n } else if (index >= this.lastIndex && fixRight) {\n shift = -items.length;\n }\n if (shift) {\n this.items.forEach(item => item.updateIndex(item.$index + shift));\n this.cache.insertItems(items, index, direction, fixRight);\n this.items = [...this.items];\n }\n this.shiftExtremum(items.length, fixRight);\n return true;\n }\n\n removeVirtually(indexes: number[], fixRight: boolean): void {\n const length = this.items.length;\n let shifted = false;\n for (\n let i = fixRight ? length - 1 : 0;\n fixRight ? i >= 0 : i < length;\n fixRight ? i-- : i++\n ) {\n const item = this.items[i];\n const diff = indexes.reduce((acc, index) => acc + (fixRight\n ? (item.$index < index ? 1 : 0)\n : (item.$index > index ? -1 : 0)\n ), 0);\n shifted = shifted || !!diff;\n item.updateIndex(item.$index + diff);\n }\n this.shiftExtremum(-indexes.length, fixRight);\n if (shifted) {\n this.items = [...this.items];\n }\n this.cache.removeItems(indexes, fixRight);\n }\n\n fillEmpty(\n items: Data[], beforeIndex: number | undefined, afterIndex: number | undefined, fixRight: boolean,\n generator: (index: number, data: Data) => Item<Data>,\n ): boolean {\n if (!this.checkCall.fillEmpty(items, beforeIndex, afterIndex)) {\n return false;\n }\n const before = Number.isInteger(beforeIndex);\n const index = (before ? beforeIndex : afterIndex) as number;\n const shift = (fixRight ? items.length : (before ? 1 : 0));\n this.items = items.map((data, i) =>\n generator(index + i + (!before ? 1 : 0) - shift, data)\n );\n this._absMinIndex = this.items[0].$index;\n this._absMaxIndex = this.items[this.size - 1].$index;\n if (this.startIndex <= this.absMinIndex) {\n this.startIndex = this.absMinIndex;\n } else if (this.startIndex > this.absMaxIndex) {\n this.startIndex = this.absMaxIndex;\n }\n return true;\n }\n\n updateItems(\n predicate: BufferUpdater<Data>,\n generator: (index: number, data: Data) => Item<Data>,\n indexToTrack: number,\n fixRight: boolean\n ): { trackedIndex: number, toRemove: Item<Data>[] } {\n if (!this.size || Number.isNaN(this.firstIndex)) {\n return { trackedIndex: NaN, toRemove: [] };\n }\n let trackedIndex = indexToTrack;\n let index = fixRight ? this.lastIndex : this.firstIndex;\n const items: Item<Data>[] = [];\n const diff = fixRight ? -1 : 1;\n const limit = this.size - 1;\n const beforeMap = new Map<number, Item>(); // need to persist original $indexes\n const updateArray = Array.prototype[fixRight ? 'unshift' : 'push'];\n\n for (let i = fixRight ? limit : 0; fixRight ? i >= 0 : i <= limit; i += diff) {\n const item = this.items[i];\n beforeMap.set(item.$index, item);\n const result = predicate(item);\n\n // if predicate result is falsy or empty array -> delete\n if (!result || (Array.isArray(result) && !result.length)) {\n item.toRemove = true;\n trackedIndex += item.$index >= indexToTrack ? (fixRight ? 1 : 0) : (fixRight ? 0 : -1);\n this.shiftExtremum(-1, fixRight);\n continue;\n }\n\n // if predicate result is truthy but not array -> leave\n if (!Array.isArray(result)) {\n item.updateIndex(index);\n updateArray.call(items, item);\n index += diff;\n continue;\n }\n\n // if predicate result is non-empty array -> insert/replace\n if (item.$index < indexToTrack) {\n trackedIndex += fixRight ? 0 : result.length - 1;\n } else if (item.$index > indexToTrack) {\n trackedIndex += fixRight ? 1 - result.length : 0;\n }\n let toRemove = true;\n const newItems: Item<Data>[] = [];\n (fixRight ? [...result].reverse() : result).forEach((data, i) => {\n let newItem: Item<Data>;\n if (item.data === data) {\n if (indexToTrack === item.$index) {\n trackedIndex = index + i * diff;\n }\n item.updateIndex(index + i * diff);\n newItem = item;\n toRemove = false; // insert case\n } else {\n newItem = generator(index + i * diff, data);\n newItem.toInsert = true;\n }\n updateArray.call(newItems, newItem);\n });\n item.toRemove = toRemove;\n updateArray.call(items, ...newItems);\n index += diff * result.length;\n if (result.length > 1) {\n this.shiftExtremum(result.length - 1, fixRight);\n }\n }\n\n const toRemove = this.items.filter(item => item.toRemove);\n const itemsBefore = Array.from(beforeMap)\n .map(([$index, { size, toRemove }]) => ({ $index, size, toRemove }))\n .sort((a, b) => a.$index - b.$index);\n this.items = items;\n this.cache.updateSubset(itemsBefore, items, fixRight);\n\n if (this.finiteAbsMinIndex === this.finiteAbsMaxIndex) {\n trackedIndex = NaN;\n } else if (trackedIndex > this.finiteAbsMaxIndex) {\n trackedIndex = this.finiteAbsMaxIndex;\n } else if (trackedIndex < this.finiteAbsMinIndex) {\n trackedIndex = this.finiteAbsMinIndex;\n }\n return { trackedIndex, toRemove };\n }\n\n cacheItem(item: Item<Data>): void {\n this.cache.add(item);\n }\n\n getFirstVisibleItemIndex(): number {\n const length = this.items.length;\n for (let i = 0; i < length; i++) {\n if (!this.items[i].invisible) {\n return i;\n }\n }\n return -1;\n }\n\n getLastVisibleItemIndex(): number {\n for (let i = this.items.length - 1; i >= 0; i--) {\n if (!this.items[i].invisible) {\n return i;\n }\n }\n return -1;\n }\n\n getFirstVisibleItem(): Item<Data> | undefined {\n const index = this.getFirstVisibleItemIndex();\n if (index >= 0) {\n return this.items[index];\n }\n }\n\n getLastVisibleItem(): Item<Data> | undefined {\n const index = this.getLastVisibleItemIndex();\n if (index >= 0) {\n return this.items[index];\n }\n }\n\n getEdgeVisibleItem(direction: Direction, opposite?: boolean): Item<Data> | undefined {\n return direction === (!opposite ? Direction.forward : Direction.backward) ?\n this.getLastVisibleItem() : this.getFirstVisibleItem();\n }\n\n getVisibleItemsCount(): number {\n return this.items.reduce((acc: number, item) => acc + (item.invisible ? 0 : 1), 0);\n }\n\n getSizeByIndex(index: number): number {\n return this.cache.getSizeByIndex(index);\n }\n\n checkDefaultSize(): boolean {\n return this.cache.recalculateDefaultSize();\n }\n\n}\n","import { ProcessName } from '../../interfaces/index';\nimport { Reactive } from '../reactive';\n\nclass InnerLoopModel {\n total: number;\n count: number;\n isInitial: boolean;\n busy: Reactive<boolean>;\n\n get first(): boolean {\n return this.count === 0;\n }\n\n constructor(total: number) {\n this.total = total;\n this.isInitial = false;\n this.busy = new Reactive<boolean>(false);\n }\n\n done() {\n this.isInitial = false;\n this.count++;\n this.total++;\n this.busy.set(false);\n }\n\n start() {\n this.busy.set(true);\n }\n\n dispose() {\n this.busy.dispose();\n }\n}\n\nexport class WorkflowCycleModel {\n instanceIndex: number;\n count: number;\n isInitial: boolean;\n initiator: ProcessName;\n innerLoop: InnerLoopModel;\n interrupter: ProcessName | null;\n busy: Reactive<boolean>;\n\n get loopId(): string {\n return `${this.instanceIndex}-${this.count}-${this.innerLoop.total}`;\n }\n\n get loopIdNext(): string {\n return `${this.instanceIndex}-${this.count}-${this.innerLoop.total + 1}`;\n }\n\n constructor(instanceIndex: number, cycle?: WorkflowCycleModel) {\n const cycleCount = cycle ? cycle.count : 1;\n const loopCount = cycle ? cycle.innerLoop.count : 0;\n\n this.instanceIndex = instanceIndex;\n this.innerLoop = new InnerLoopModel(loopCount);\n this.interrupter = null;\n this.busy = new Reactive<boolean>(false);\n this.end(cycleCount);\n }\n\n start(isInitial: boolean, initiator: ProcessName): void {\n this.isInitial = isInitial;\n this.initiator = initiator;\n this.innerLoop.isInitial = isInitial;\n this.innerLoop.count = 0;\n this.interrupter = null;\n this.busy.set(true);\n }\n\n end(count: number): void {\n this.count = count;\n this.isInitial = false;\n this.busy.set(false);\n }\n\n dispose(forever?: boolean): void {\n if (forever) {\n // otherwise the value will be persisted during re-instantiation\n this.busy.dispose();\n }\n this.innerLoop.dispose();\n }\n}\n","import { Item } from '../item';\nimport { Direction } from '../../inputs/index';\n\nclass Positions {\n startDelta: number;\n before: number;\n relative: number;\n start: number;\n end: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.startDelta = 0;\n this.before = 0;\n }\n}\n\nclass First {\n index: number;\n indexBuffer: number;\n position: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.indexBuffer = NaN;\n this.position = NaN;\n }\n}\n\nclass Last {\n index: number;\n indexBuffer: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.indexBuffer = NaN;\n }\n}\n\nclass FirstVisible {\n index: number;\n delta: number;\n\n constructor() {\n this.reset();\n }\n\n reset() {\n this.index = NaN;\n this.delta = 0;\n }\n}\n\nexport class FetchModel {\n private readonly directionPriority: Direction;\n private _newItemsData: unknown[] | null; // there are public setter and getter\n\n items: Item[];\n positions: Positions;\n first: First;\n last: Last;\n hasAnotherPack: boolean;\n callCount: number;\n minIndex: number;\n firstVisible: FirstVisible;\n direction: Direction | null;\n cancel: (() => void) | null;\n\n simulate: boolean;\n isCheck: boolean;\n doRemove: boolean;\n\n constructor(directionPriority: Direction) {\n this.directionPriority = directionPriority;\n this.callCount = 0;\n this.positions = new Positions();\n this.first = new First();\n this.last = new Last();\n this.firstVisible = new FirstVisible();\n this.reset();\n }\n\n reset(): void {\n this._newItemsData = null;\n this.items = [];\n this.positions.reset();\n this.first.reset();\n this.last.reset();\n this.firstVisible.reset();\n this.hasAnotherPack = false;\n this.direction = null;\n this.cancel = null;\n this.simulate = false;\n this.isCheck = false;\n this.doRemove = false;\n }\n\n get newItemsData(): unknown[] | null {\n return this._newItemsData;\n }\n\n set newItemsData(items: unknown[] | null) {\n this._newItemsData = items;\n if (items && items.length) {\n this.callCount++;\n }\n }\n\n get shouldFetch(): boolean {\n return !!this.count;\n }\n\n get hasNewItems(): boolean {\n return !!((this._newItemsData && this._newItemsData.length));\n }\n\n get index(): number {\n return this.first.index;\n }\n\n get count(): number {\n return !isNaN(this.first.index) && !isNaN(this.last.index) ? this.last.index - this.first.index + 1 : 0;\n }\n\n shouldCheckPreSizeExpectation(lastBufferedIndex: number): boolean {\n if (this.directionPriority === Direction.backward) {\n return false;\n }\n const lastFetched = this.items[this.items.length - 1];\n return lastFetched && lastFetched.$index < lastBufferedIndex;\n }\n\n startSimulate(items: Item[]): void {\n this.simulate = true;\n this._newItemsData = items.map(item => item.data);\n this.items = items;\n this.hasAnotherPack = false;\n }\n\n stopSimulate(): void {\n this.simulate = false;\n this.isCheck = false;\n this.doRemove = false;\n }\n\n fill(items: Item[], start: number): void {\n this.startSimulate(items);\n this.first.index = items[0].$index;\n this.last.index = items[items.length - 1].$index;\n this.direction = Direction.forward;\n this.firstVisible.index = start;\n this.firstVisible.delta = 0;\n }\n\n check(items: Item[]): void {\n this.startSimulate(items);\n this.last.index = items[0].$index;\n this.first.index = items[items.length - 1].$index;\n this.isCheck = true;\n }\n\n update(index: number, delta: number, items: Item[], itemsToRemove: Item[]): void {\n this.startSimulate(items);\n this.firstVisible.index = index;\n this.firstVisible.delta = delta;\n this.doRemove = itemsToRemove.length > 0;\n }\n}\n","export class ClipModel {\n doClip: boolean;\n callCount: number;\n forceForward: boolean;\n forceBackward: boolean;\n\n get force(): boolean {\n return this.forceForward || this.forceBackward;\n }\n\n constructor() {\n this.callCount = 0;\n this.reset();\n }\n\n reset(force?: boolean): void {\n this.doClip = false;\n if (!force) {\n this.forceForward = false;\n this.forceBackward = false;\n }\n }\n\n}\n","export class RenderModel {\n sizeBefore: number;\n sizeAfter: number;\n positionBefore: number;\n cancel: (() => void) | null;\n\n get noSize(): boolean {\n return this.sizeBefore === this.sizeAfter;\n }\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.sizeBefore = 0;\n this.sizeAfter = 0;\n this.positionBefore = 0;\n this.cancel = null;\n }\n}\n","import { ScrollEventData as IScrollEventData } from '../../interfaces/index';\n\nexport class ScrollModel {\n previous: IScrollEventData | null;\n current: IScrollEventData | null;\n\n scrollTimer: ReturnType<typeof setTimeout> | null;\n\n syntheticPosition: number | null;\n syntheticFulfill: boolean;\n cancelAnimation: (() => void) | null;\n positionBeforeAsync: number | null;\n positionBeforeAdjust: number | null;\n positionAfterAdjust: number | null;\n\n constructor() {\n this.reset();\n }\n\n reset(): void {\n this.previous = null;\n this.current = null;\n this.syntheticPosition = null;\n this.syntheticFulfill = false;\n this.positionBeforeAsync = null;\n this.positionBeforeAdjust = null;\n this.positionAfterAdjust = null;\n this.stop();\n }\n\n stop(): void {\n if (this.scrollTimer) {\n clearTimeout(this.scrollTimer);\n this.scrollTimer = null;\n }\n if (this.cancelAnimation) {\n this.cancelAnimation();\n this.cancelAnimation = null;\n }\n }\n\n hasPositionChanged(position: number): boolean {\n const before = this.positionBeforeAdjust;\n const after = this.positionAfterAdjust;\n return before === null || before !== position || after === null || after !== position;\n }\n}\n","import { Settings } from './settings';\r\nimport { WorkflowCycleModel } from './state/cycle';\r\nimport { FetchModel } from './state/fetch';\r\nimport { ClipModel } from './state/clip';\r\nimport { RenderModel } from './state/render';\r\nimport { ScrollModel } from './state/scroll';\r\nimport { State as IState, IPackages, ProcessName } from '../interfaces/index';\r\n\r\nexport class State implements IState {\r\n\r\n readonly packageInfo: IPackages;\r\n private settings: Settings;\r\n initTime: number;\r\n\r\n cycle: WorkflowCycleModel;\r\n fetch: FetchModel;\r\n clip: ClipModel;\r\n render: RenderModel;\r\n scroll: ScrollModel;\r\n\r\n get time(): number {\r\n return Number(new Date()) - this.initTime;\r\n }\r\n\r\n constructor(packageInfo: IPackages, settings: Settings, state?: IState) {\r\n this.packageInfo = packageInfo;\r\n this.settings = settings;\r\n this.initTime = Number(new Date());\r\n\r\n this.cycle = new WorkflowCycleModel(this.settings.instanceIndex, state ? state.cycle : void 0);\r\n this.fetch = new FetchModel(settings.directionPriority);\r\n this.clip = new ClipModel();\r\n this.render = new RenderModel();\r\n this.scroll = new ScrollModel();\r\n }\r\n\r\n startWorkflowCycle(isInitial: boolean, initiator: ProcessName): void {\r\n this.cycle.start(isInitial, initiator);\r\n }\r\n\r\n endWorkflowCycle(count: number): void {\r\n this.cycle.end(count);\r\n }\r\n\r\n startInnerLoop(): { process?: ProcessName, doRender?: boolean } {\r\n const { cycle, scroll: scroll, fetch, render, clip } = this;\r\n\r\n cycle.innerLoop.start();\r\n scroll.positionBeforeAsync = null;\r\n\r\n if (!fetch.simulate) {\r\n fetch.reset();\r\n }\r\n clip.reset(clip.force);\r\n render.reset();\r\n\r\n return {\r\n ...(cycle.innerLoop.first ? {\r\n process: cycle.initiator,\r\n doRender: fetch.simulate && fetch.items.length > 0\r\n } : {})\r\n };\r\n }\r\n\r\n endInnerLoop(): void {\r\n const { fetch, clip, render, cycle } = this;\r\n fetch.stopSimulate();\r\n clip.reset(true);\r\n if (fetch.cancel) {\r\n fetch.cancel();\r\n fetch.cancel = null;\r\n }\r\n if (render.cancel) {\r\n render.cancel();\r\n render.cancel = null;\r\n }\r\n cycle.innerLoop.done();\r\n }\r\n\r\n dispose(): void {\r\n this.scroll.stop();\r\n this.cycle.dispose();\r\n this.endInnerLoop();\r\n }\r\n\r\n}\r\n","import { Logger } from './logger';\r\nimport { Buffer } from './buffer';\r\nimport { Reactive } from './reactive';\r\nimport {\r\n AdapterPropName, AdapterPropType, getDefaultAdapterProps, methodPreResult, reactiveConfigStorage\r\n} from './adapter/props';\r\nimport { AdapterProcess, ProcessStatus } from '../processes/index';\r\nimport {\r\n WorkflowGetter,\r\n IAdapterProp,\r\n AdapterMethodResult,\r\n IAdapter,\r\n ItemAdapter,\r\n ItemsPredicate,\r\n AdapterPrependOptions,\r\n AdapterAppendOptions,\r\n AdapterRemoveOptions,\r\n AdapterClipOptions,\r\n AdapterInsertOptions,\r\n AdapterReplaceOptions,\r\n AdapterUpdateOptions,\r\n AdapterFixOptions,\r\n ScrollerWorkflow,\r\n IDatasourceOptional,\r\n IPackages,\r\n IBufferInfo,\r\n State,\r\n ProcessSubject,\r\n} from '../interfaces/index';\r\n\r\ntype MethodResolver = (...args: any[]) => Promise<AdapterMethodResult>;\r\n\r\nconst ADAPTER_PROPS_STUB = getDefaultAdapterProps();\r\n\r\nconst _has = (obj: unknown, prop: string): boolean =>\r\n typeof obj === 'object' && obj !== null && Object.prototype.hasOwnProperty.call(obj, prop);\r\n\r\nconst convertAppendArgs = <Item>(prepend: boolean, options: unknown, eof?: boolean) => {\r\n let result = options as AdapterAppendOptions<Item> & AdapterPrependOptions<Item>;\r\n if (!_has(options, 'items')) {\r\n const items = !Array.isArray(options) ? [options] : options;\r\n result = prepend ? { items, bof: eof } : { items, eof: eof };\r\n }\r\n return result;\r\n};\r\n\r\nconst convertRemoveArgs = <Item>(options: AdapterRemoveOptions<Item> | ItemsPredicate<Item>) => {\r\n if (!(_has(options, 'predicate') || _has(options, 'indexes'))) {\r\n const predicate = options as ItemsPredicate<Item>;\r\n options = { predicate };\r\n }\r\n return options;\r\n};\r\n\r\nexport class Adapter<Item = unknown> implements IAdapter<Item> {\r\n private externalContext: IAdapter<Item>;\r\n private logger: Logger;\r\n private getWorkflow: WorkflowGetter<Item>;\r\n private reloadCounter: number;\r\n private source: { [key: string]: Reactive<unknown> } = {}; // for Reactive props\r\n private box: { [key: string]: unknown } = {}; // for Scalars over Reactive props\r\n private demand: { [key: string]: unknown } = {}; // for Scalars on demand\r\n public wanted: { [key: string]: boolean } = {};\r\n\r\n get workflow(): ScrollerWorkflow<Item> {\r\n return this.getWorkflow();\r\n }\r\n get reloadCount(): number {\r\n return this.reloadCounter;\r\n }\r\n get reloadId(): string {\r\n return this.id + '.' + this.reloadCounter;\r\n }\r\n\r\n id: number;\r\n mock: boolean;\r\n augmented: boolean;\r\n version: string;\r\n init: boolean;\r\n init$: Reactive<boolean>;\r\n packageInfo: IPackages;\r\n itemsCount: number;\r\n bufferInfo: IBufferInfo;\r\n isLoading: boolean;\r\n isLoading$: Reactive<boolean>;\r\n loopPending: boolean;\r\n loopPending$: Reactive<boolean>;\r\n firstVisible: ItemAdapter<Item>;\r\n firstVisible$: Reactive<ItemAdapter<Item>>;\r\n lastVisible: ItemAdapter<Item>;\r\n lastVisible$: Reactive<ItemAdapter<Item>>;\r\n bof: boolean;\r\n bof$: Reactive<boolean>;\r\n eof: boolean;\r\n eof$: Reactive<boolean>;\r\n\r\n private relax$: Reactive<AdapterMethodResult> | null;\r\n private relaxRun: Promise<AdapterMethodResult> | null;\r\n\r\n private getPromisifiedMethod(method: MethodResolver, defaultMethod: MethodResolver) {\r\n return (...args: any[]): Promise<AdapterMethodResult> =>\r\n this.relax$\r\n ? new Promise(resolve => {\r\n if (this.relax$) {\r\n this.relax$.once(value => resolve(value));\r\n }\r\n method.apply(this, args);\r\n })\r\n : defaultMethod.apply(this, args);\r\n }\r\n\r\n constructor(context: IAdapter<Item> | null, getWorkflow: WorkflowGetter<Item>, logger: Logger) {\r\n this.getWorkflow = getWorkflow;\r\n this.logger = logger;\r\n this.relax$ = null;\r\n this.relaxRun = null;\r\n this.reloadCounter = 0;\r\n\r\n // public context (if exists) should provide access Reactive props configuration by id\r\n const reactivePropsStore = context && reactiveConfigStorage.get(context.id) || {};\r\n\r\n // make array of the original values from public context if present\r\n const adapterProps = context\r\n ? ADAPTER_PROPS_STUB.map(prop => {\r\n let value = context[prop.name];\r\n // if context is augmented, we need to replace external reactive props with inner ones\r\n if (context.augmented) {\r\n const reactiveProp = reactivePropsStore[prop.name];\r\n if (reactiveProp) {\r\n value = reactiveProp.default as Reactive<boolean>; // boolean doesn't matter here\r\n }\r\n }\r\n return ({ ...prop, value });\r\n })\r\n : getDefaultAdapterProps();\r\n\r\n // restore default reactive props if they were configured\r\n Object.entries(reactivePropsStore).forEach(([key, value]) => {\r\n const prop = adapterProps.find(({ name }) => name === key);\r\n if (prop && value) {\r\n prop.value = value.default;\r\n }\r\n });\r\n\r\n // Scalar permanent props\r\n adapterProps\r\n .filter(({ type, permanent }) => type === AdapterPropType.Scalar && permanent)\r\n .forEach(({ name, value }: IAdapterProp) =>\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => value\r\n })\r\n );\r\n\r\n // Reactive props\r\n // 1) store original values in \"source\" container, to avoid extra .get() calls on scalar twins set\r\n // 2) \"wanted\" container is bound with scalars; get() updates it\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Reactive)\r\n .forEach(({ name, value }: IAdapterProp) => {\r\n this.source[name] = value as Reactive<unknown>;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => {\r\n const scalarWanted = ADAPTER_PROPS_STUB.find(\r\n ({ wanted, reactive }) => wanted && reactive === name\r\n );\r\n if (scalarWanted) {\r\n this.wanted[scalarWanted.name] = true;\r\n }\r\n return this.source[name];\r\n }\r\n });\r\n });\r\n\r\n // Scalar props that have Reactive twins\r\n // 1) scalars should use \"box\" container\r\n // 2) \"wanted\" should be updated on get\r\n // 3) reactive props (from \"source\") are triggered on set\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Scalar && !!prop.reactive)\r\n .forEach(({ name, value, reactive, wanted }: IAdapterProp) => {\r\n if (wanted) {\r\n this.wanted[name] = false;\r\n }\r\n this.box[name] = value;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n set: (newValue: unknown) => {\r\n if (newValue !== this.box[name]) {\r\n this.box[name] = newValue;\r\n this.source[reactive as AdapterPropName].set(newValue);\r\n // need to emit new value through the configured reactive prop if present\r\n const reactiveProp = reactivePropsStore[reactive as AdapterPropName];\r\n if (reactiveProp) {\r\n reactiveProp.emit(reactiveProp.source, newValue);\r\n }\r\n }\r\n },\r\n get: () => {\r\n if (wanted) {\r\n this.wanted[name] = true;\r\n }\r\n return this.box[name];\r\n }\r\n });\r\n });\r\n\r\n // Scalar props on-demand\r\n // these scalars should use \"demand\" container\r\n // setting defaults should be overridden on init()\r\n adapterProps\r\n .filter(prop => prop.type === AdapterPropType.Scalar && prop.onDemand)\r\n .forEach(({ name, value }: IAdapterProp) => {\r\n this.demand[name] = value;\r\n Object.defineProperty(this, name, {\r\n configurable: true,\r\n get: () => this.demand[name]\r\n });\r\n });\r\n\r\n if (!context) {\r\n return;\r\n }\r\n\r\n // Adapter public context augmentation\r\n adapterProps\r\n .forEach(({ name, type, value: defaultValue, permanent }: IAdapterProp) => {\r\n let value = (this as IAdapter)[name];\r\n if (type === AdapterPropType.Function) {\r\n value = (value as () => void).bind(this);\r\n } else if (type === AdapterPropType.WorkflowRunner) {\r\n value = this.getPromisifiedMethod(value as MethodResolver, defaultValue as MethodResolver);\r\n } else if (type === AdapterPropType.Reactive && reactivePropsStore[name]) {\r\n value = (context as IAdapter)[name];\r\n } else if (name === AdapterPropName.augmented) {\r\n value = true;\r\n }\r\n Object.defineProperty(context, name, {\r\n configurable: true,\r\n get: () => !permanent && type === AdapterPropType.Scalar\r\n ? (this as IAdapter)[name] // non-permanent Scalars should be taken in runtime\r\n : value // Reactive props and methods (Functions/WorkflowRunners) can be defined once\r\n });\r\n });\r\n\r\n this.externalContext = context;\r\n }\r\n\r\n initialize(buffer: Buffer<Item>, state: State, logger: Logger, adapterRun$?: Reactive<ProcessSubject>): void {\r\n // buffer\r\n Object.defineProperty(this.demand, AdapterPropName.itemsCount, {\r\n get: () => buffer.getVisibleItemsCount()\r\n });\r\n Object.defineProperty(this.demand, AdapterPropName.bufferInfo, {\r\n get: (): IBufferInfo => ({\r\n firstIndex: buffer.firstIndex,\r\n lastIndex: buffer.lastIndex,\r\n minIndex: buffer.minIndex,\r\n maxIndex: buffer.maxIndex,\r\n absMinIndex: buffer.absMinIndex,\r\n absMaxIndex: buffer.absMaxIndex,\r\n defaultSize: buffer.defaultSize,\r\n })\r\n });\r\n this.bof = buffer.bof.get();\r\n buffer.bof.on(bof => this.bof = bof);\r\n this.eof = buffer.eof.get();\r\n buffer.eof.on(eof => this.eof = eof);\r\n\r\n // state\r\n Object.defineProperty(this.demand, AdapterPropName.packageInfo, {\r\n get: () => state.packageInfo\r\n });\r\n this.loopPending = state.cycle.innerLoop.busy.get();\r\n state.cycle.innerLoop.busy.on(busy => this.loopPending = busy);\r\n this.isLoading = state.cycle.busy.get();\r\n state.cycle.busy.on(busy => this.isLoading = busy);\r\n\r\n // logger\r\n this.logger = logger;\r\n\r\n // self-pending subscription; set up only on the very first init\r\n if (adapterRun$) {\r\n if (!this.relax$) {\r\n this.relax$ = new Reactive();\r\n }\r\n const relax$ = this.relax$;\r\n adapterRun$.on(({ status, payload }) => {\r\n let unSubRelax = () => { };\r\n if (status === ProcessStatus.start) {\r\n unSubRelax = this.isLoading$.on(value => {\r\n if (!value) {\r\n unSubRelax();\r\n relax$.set({ success: true, immediate: false, details: null });\r\n }\r\n });\r\n } else if (status === ProcessStatus.done || status === ProcessStatus.error) {\r\n unSubRelax();\r\n relax$.set({\r\n success: status !== ProcessStatus.error,\r\n immediate: true,\r\n details: status === ProcessStatus.error && payload ? String(payload.error) : null\r\n });\r\n }\r\n });\r\n }\r\n\r\n // init\r\n this.init = true;\r\n }\r\n\r\n dispose(): void {\r\n if (this.relax$) {\r\n this.relax$.dispose();\r\n }\r\n if (this.externalContext) {\r\n this.resetContext();\r\n }\r\n Object.getOwnPropertyNames(this).forEach(prop => {\r\n delete (this as Record<string, unknown>)[prop];\r\n });\r\n }\r\n\r\n resetContext(): void {\r\n const reactiveStore = reactiveConfigStorage.get(this.externalContext.id);\r\n ADAPTER_PROPS_STUB\r\n .forEach(({ type, permanent, name, value }) => {\r\n // assign initial values to non-reactive non-permanent props\r\n if (type !== AdapterPropType.Reactive && !permanent) {\r\n Object.defineProperty(this.externalContext, name, {\r\n configurable: true,\r\n get: () => value\r\n });\r\n }\r\n // reset reactive props\r\n if (type === AdapterPropType.Reactive && reactiveStore) {\r\n const property = reactiveStore[name];\r\n if (property) {\r\n property.default.reset();\r\n property.emit(property.source, property.default.get());\r\n }\r\n }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reset(options?: IDatasourceOptional): any {\r\n this.reloadCounter++;\r\n this.logger.logAdapterMethod('reset', options, ` of ${this.reloadId}`);\r\n this.workflow.call({\r\n process: AdapterProcess.reset,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n reload(options?: number | string): any {\r\n this.reloadCounter++;\r\n this.logger.logAdapterMethod('reload', options, ` of ${this.reloadId}`);\r\n this.workflow.call({\r\n process: AdapterProcess.reload,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n append(_options: AdapterAppendOptions<Item> | unknown, eof?: boolean): any {\r\n const options = convertAppendArgs(false, _options, eof); // support old signature\r\n this.logger.logAdapterMethod('append', [options.items, options.eof]);\r\n this.workflow.call({\r\n process: AdapterProcess.append,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n prepend(_options: AdapterPrependOptions<Item> | unknown, bof?: boolean): any {\r\n const options = convertAppendArgs(true, _options, bof); // support old signature\r\n this.logger.logAdapterMethod('prepend', [options.items, options.bof]);\r\n this.workflow.call({\r\n process: AdapterProcess.prepend,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n check(): any {\r\n this.logger.logAdapterMethod('check');\r\n this.workflow.call({\r\n process: AdapterProcess.check,\r\n status: ProcessStatus.start\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n remove(options: AdapterRemoveOptions<Item> | ItemsPredicate<Item>): any {\r\n options = convertRemoveArgs(options); // support old signature\r\n this.logger.logAdapterMethod('remove', options);\r\n this.workflow.call({\r\n process: AdapterProcess.remove,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n clip(options?: AdapterClipOptions): any {\r\n this.logger.logAdapterMethod('clip', options);\r\n this.workflow.call({\r\n process: AdapterProcess.clip,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n insert(options: AdapterInsertOptions<Item>): any {\r\n this.logger.logAdapterMethod('insert', options);\r\n this.workflow.call({\r\n process: AdapterProcess.insert,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n replace(options: AdapterReplaceOptions<Item>): any {\r\n this.logger.logAdapterMethod('replace', options);\r\n this.workflow.call({\r\n process: AdapterProcess.replace,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n update(options: AdapterUpdateOptions<Item>): any {\r\n this.logger.logAdapterMethod('update', options);\r\n this.workflow.call({\r\n process: AdapterProcess.update,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n fix(options: AdapterFixOptions<Item>): any {\r\n this.logger.logAdapterMethod('fix', options);\r\n this.workflow.call({\r\n process: AdapterProcess.fix,\r\n status: ProcessStatus.start,\r\n payload: { options }\r\n });\r\n }\r\n\r\n relaxUnchained(callback: (() => void) | undefined, reloadId: string): Promise<AdapterMethodResult> {\r\n const runCallback = () => typeof callback === 'function' && reloadId === this.reloadId && callback();\r\n if (!this.isLoading) {\r\n runCallback();\r\n }\r\n return new Promise<boolean>(resolve => {\r\n if (!this.isLoading) {\r\n resolve(true);\r\n return;\r\n }\r\n this.isLoading$.once(() => {\r\n runCallback();\r\n resolve(false);\r\n });\r\n }).then(immediate => {\r\n const success = reloadId === this.reloadId;\r\n this.logger.log(() => !success ? `relax promise cancelled due to ${reloadId} != ${this.reloadId}` : void 0);\r\n return {\r\n immediate,\r\n success,\r\n details: !success ? 'Interrupted by reload or reset' : null\r\n };\r\n });\r\n }\r\n\r\n relax(callback?: () => void): Promise<AdapterMethodResult> {\r\n const reloadId = this.reloadId;\r\n this.logger.logAdapterMethod('relax', callback, ` of ${reloadId}`);\r\n if (!this.init) {\r\n return Promise.resolve(methodPreResult);\r\n }\r\n return this.relaxRun = this.relaxRun\r\n ? this.relaxRun.then(() => this.relaxUnchained(callback, reloadId))\r\n : this.relaxUnchained(callback, reloadId).then((result) => {\r\n this.relaxRun = null;\r\n return result;\r\n });\r\n }\r\n\r\n showLog(): void {\r\n this.logger.logAdapterMethod('showLog');\r\n this.logger.logForce();\r\n }\r\n}\r\n","import { DatasourceGeneric, makeDatasource } from './classes/datasource';\nimport { Settings } from './classes/settings';\nimport { Logger } from './classes/logger';\nimport { Routines } from './classes/domRoutines';\nimport { Viewport } from './classes/viewport';\nimport { Buffer } from './classes/buffer';\nimport { State } from './classes/state';\nimport { Adapter } from './classes/adapter';\nimport { Reactive } from './classes/reactive';\nimport { validate, DATASOURCE } from './inputs/index';\nimport core from './version';\nimport {\n ScrollerWorkflow, IDatasource, IDatasourceConstructed, ScrollerParams, IPackages, ProcessSubject\n} from './interfaces/index';\n\nexport const INVALID_DATASOURCE_PREFIX = 'Invalid datasource:';\n\nlet instanceCount = 0;\n\nexport class Scroller<Data = unknown> {\n public datasource: IDatasourceConstructed<Data>;\n public workflow: ScrollerWorkflow<Data>;\n\n public settings: Settings<Data>;\n public logger: Logger;\n public routines: Routines;\n public viewport: Viewport;\n public buffer: Buffer<Data>;\n public state: State;\n public adapter: Adapter<Data>;\n\n constructor({ datasource, consumer, element, workflow, scroller }: ScrollerParams<Data>) {\n const { params: { get } } = validate(datasource, DATASOURCE);\n if (!get.isValid) {\n throw new Error(`${INVALID_DATASOURCE_PREFIX} ${get.errors[0]}`);\n }\n\n const packageInfo = scroller ? scroller.state.packageInfo : ({ consumer, core } as IPackages);\n element = scroller ? scroller.viewport.element : (element as HTMLElement);\n workflow = scroller ? scroller.workflow : (workflow as ScrollerWorkflow<Data>);\n\n this.workflow = workflow;\n this.settings = new Settings<Data>(datasource.settings, datasource.devSettings, ++instanceCount);\n this.logger = new Logger(this as Scroller, packageInfo, datasource.adapter);\n this.routines = new Routines(this.settings);\n this.state = new State(packageInfo, this.settings, scroller ? scroller.state : void 0);\n this.buffer = new Buffer<Data>(this.settings, workflow.onDataChanged, this.logger);\n this.viewport = new Viewport(element, this.settings, this.routines, this.state, this.logger);\n this.logger.object('vscroll settings object', this.settings, true);\n\n this.initDatasource(datasource, scroller);\n }\n\n initDatasource(datasource: IDatasource<Data>, scroller?: Scroller<Data>): void {\n if (scroller) { // scroller re-instantiating case\n this.datasource = datasource as IDatasourceConstructed<Data>;\n this.adapter = scroller.adapter;\n // todo: what about (this.settings.adapter !== scroller.setting.adapter) case?\n return;\n }\n // scroller is being instantiated for the first time\n const constructed = datasource instanceof DatasourceGeneric;\n const mockAdapter = !constructed && !this.settings.adapter;\n if (constructed) { // datasource is already instantiated\n this.datasource = datasource as IDatasourceConstructed<Data>;\n } else { // datasource as POJO\n const DS = makeDatasource(() => ({ mock: mockAdapter }));\n this.datasource = new DS<Data>(datasource);\n if (this.settings.adapter) {\n datasource.adapter = this.datasource.adapter;\n }\n }\n const publicContext = !mockAdapter ? this.datasource.adapter : null;\n this.adapter = new Adapter<Data>(publicContext, () => this.workflow, this.logger);\n }\n\n init(adapterRun$?: Reactive<ProcessSubject>): void {\n this.viewport.reset(this.buffer.startIndex);\n this.logger.stat('initialization');\n this.adapter.initialize(this.buffer, this.state, this.logger, adapterRun$);\n }\n\n dispose(forever?: boolean): void {\n if (forever) { // Adapter is not re-instantiated on reset\n this.adapter.dispose();\n }\n this.buffer.dispose();\n this.state.dispose();\n }\n\n finalize(): void {\n }\n\n}\n","import {\n CommonProcess,\n AdapterProcess,\n ProcessStatus as Status,\n Init,\n Scroll,\n Reset,\n Reload,\n Append,\n Check,\n Remove,\n UserClip,\n Insert,\n Replace,\n Update,\n Fix,\n Start,\n PreFetch,\n Fetch,\n PostFetch,\n Render,\n PreClip,\n Clip,\n Adjust,\n End,\n} from './processes/index';\n\nimport { StateMachineParams } from './interfaces/index';\n\nexport const runStateMachine = ({\n input: { process, status, payload = {} },\n methods: { run, interrupt, done, onError }\n}: StateMachineParams): void => {\n if (status === Status.error) {\n onError(process, payload);\n if (!process.startsWith('adapter')) {\n run(End)(payload);\n }\n return;\n }\n const { options } = payload;\n switch (process) {\n case CommonProcess.init:\n if (status === Status.start) { // App start\n run(Init)(process);\n }\n if (status === Status.next) {\n run(Start)();\n }\n break;\n case CommonProcess.scroll:\n if (status === Status.start) {\n run(Scroll)(payload);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.reset:\n case AdapterProcess.reload:\n if (status === Status.start) {\n if (process === AdapterProcess.reset) {\n run(Reset)(options);\n } else {\n run(Reload)(options);\n }\n }\n if (status === Status.next) {\n interrupt({ process, ...payload });\n if (payload.finalize) {\n run(End)();\n } else {\n run(Init)(process);\n }\n }\n break;\n case AdapterProcess.append:\n case AdapterProcess.prepend:\n if (status === Status.start) {\n run(Append)({ process, options });\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.check:\n if (status === Status.start) {\n run(Check)();\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.remove:\n if (status === Status.start) {\n run(Remove)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.clip:\n if (status === Status.start) {\n run(UserClip)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.insert:\n if (status === Status.start) {\n run(Insert)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.replace:\n if (status === Status.start) {\n run(Replace)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.update:\n if (status === Status.start) {\n run(Update)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case AdapterProcess.fix:\n if (status === Status.start) {\n run(Fix)(options);\n }\n if (status === Status.next) {\n run(Init)(process);\n }\n break;\n case CommonProcess.start:\n switch (payload.process) {\n case AdapterProcess.append:\n case AdapterProcess.insert:\n case AdapterProcess.replace:\n case AdapterProcess.update:\n if (payload.doRender) {\n run(Render)();\n } else {\n run(Adjust)();\n }\n break;\n case AdapterProcess.check:\n run(Render)();\n break;\n case AdapterProcess.remove:\n run(Adjust)();\n break;\n default:\n run(PreFetch)();\n }\n break;\n case CommonProcess.preFetch:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.clip:\n run(PreClip)();\n break;\n default:\n run(Fetch)();\n }\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.fetch:\n run(PostFetch)();\n break;\n case CommonProcess.postFetch:\n if (status === Status.next) {\n run(Render)();\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.render:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.append:\n case AdapterProcess.check:\n case AdapterProcess.insert:\n case AdapterProcess.replace:\n case AdapterProcess.update:\n run(Adjust)();\n break;\n default:\n run(PreClip)();\n }\n }\n if (status === Status.done) {\n run(End)();\n }\n break;\n case CommonProcess.preClip:\n if (payload.doClip) {\n run(Clip)();\n } else {\n run(Adjust)();\n }\n break;\n case CommonProcess.clip:\n run(Adjust)();\n break;\n case CommonProcess.adjust:\n run(End)();\n break;\n case CommonProcess.end:\n if (status === Status.next) {\n switch (payload.process) {\n case AdapterProcess.reset:\n case AdapterProcess.reload:\n done();\n run(Init)(payload.process);\n break;\n default:\n run(Start)();\n }\n }\n if (status === Status.done) {\n done();\n }\n break;\n }\n};\n","import { Scroller } from './scroller';\nimport { runStateMachine } from './workflow-transducer';\nimport { Reactive } from './classes/reactive';\nimport { Item } from './classes/item';\nimport { CommonProcess, ProcessStatus as Status, } from './processes/index';\nimport {\n WorkflowParams,\n ProcessName,\n ProcessPayload,\n ProcessClass,\n ProcessSubject,\n WorkflowError,\n InterruptParams,\n StateMachineMethods,\n ScrollerWorkflow,\n} from './interfaces/index';\n\nexport class Workflow<ItemData = unknown> {\n\n isInitialized: boolean;\n initTimer: ReturnType<typeof setTimeout> | null;\n adapterRun$: Reactive<ProcessSubject>;\n cyclesDone: number;\n interruptionCount: number;\n errors: WorkflowError[];\n\n private offScroll: () => void;\n readonly propagateChanges: WorkflowParams<ItemData>['run'];\n readonly stateMachineMethods: StateMachineMethods<ItemData>;\n\n scroller: Scroller<ItemData>;\n\n constructor({ element, datasource, consumer, run }: WorkflowParams<ItemData>) {\n this.isInitialized = false;\n this.initTimer = null;\n this.adapterRun$ = new Reactive();\n this.cyclesDone = 0;\n this.interruptionCount = 0;\n this.errors = [];\n this.offScroll = () => null;\n this.propagateChanges = run;\n this.stateMachineMethods = {\n run: this.runProcess(),\n interrupt: this.interrupt.bind(this),\n done: this.done.bind(this),\n onError: this.onError.bind(this)\n };\n\n this.scroller = new Scroller<ItemData>({ element, datasource, consumer, workflow: this.getUpdater() });\n\n if (this.scroller.settings.initializeDelay) {\n this.initTimer = setTimeout(() => {\n this.initTimer = null;\n this.init();\n }, this.scroller.settings.initializeDelay);\n } else {\n this.init();\n }\n }\n\n init(): void {\n this.scroller.init(this.adapterRun$);\n this.isInitialized = true;\n\n // run the Workflow\n this.callWorkflow({\n process: CommonProcess.init,\n status: Status.start\n });\n\n // set up scroll event listener\n const { viewport: { scrollEventReceiver }, routines } = this.scroller;\n const onScrollHandler: EventListener =\n event => this.callWorkflow({\n process: CommonProcess.scroll,\n status: Status.start,\n payload: { event }\n });\n this.offScroll = routines.onScroll(scrollEventReceiver, onScrollHandler);\n }\n\n changeItems(items: Item<ItemData>[]): void {\n this.propagateChanges(items);\n }\n\n callWorkflow(processSubject: ProcessSubject): void {\n if (!this.isInitialized) {\n return;\n }\n const { process, status } = processSubject;\n if (process && process.startsWith('adapter') && status !== Status.next) {\n this.adapterRun$.set(processSubject);\n }\n this.process(processSubject);\n }\n\n getUpdater(): ScrollerWorkflow<ItemData> {\n return {\n call: this.callWorkflow.bind(this),\n onDataChanged: this.changeItems.bind(this),\n };\n }\n\n process(data: ProcessSubject): void {\n const { status, process, payload } = data;\n if (this.scroller.settings.logProcessRun) {\n this.scroller.logger.log(() => [\n '%cfire%c', ...['color: #cc7777;', 'color: #000000;'],\n process, `\"${status}\"`, ...(payload !== void 0 ? [payload] : [])\n ]);\n }\n this.scroller.logger.logProcess(data);\n\n if (process === CommonProcess.end) {\n this.scroller.finalize();\n }\n runStateMachine({\n input: data,\n methods: this.stateMachineMethods as StateMachineMethods<unknown>\n });\n }\n\n runProcess() {\n return ({ run, process, name }: ProcessClass) =>\n (...args: any[]): void => {\n if (this.scroller.settings.logProcessRun) {\n this.scroller.logger.log(() => [\n '%crun%c', ...['color: #333399;', 'color: #000000;'],\n process || name, ...args\n ]);\n }\n run(this.scroller as Scroller, ...args);\n };\n }\n\n onError(process: ProcessName, payload?: ProcessPayload): void {\n const message: string = payload && String(payload.error) || '';\n const { time, cycle } = this.scroller.state;\n this.errors.push({\n process,\n message,\n time,\n loop: cycle.loopIdNext\n });\n this.scroller.logger.logError(message);\n }\n\n interrupt({ process, finalize, datasource }: InterruptParams<ItemData>): void {\n if (finalize) {\n const { workflow, logger } = this.scroller;\n // we are going to create a new reference for the scroller.workflow object\n // calling the old version of the scroller.workflow by any outstanding async processes will be skipped\n workflow.call = (p: ProcessSubject) => // eslint-disable-line @typescript-eslint/no-unused-vars\n logger.log('[skip wf call]');\n workflow.call.interrupted = true;\n this.scroller.workflow = this.getUpdater();\n this.interruptionCount++;\n logger.log(() => `workflow had been interrupted by the ${process} process (${this.interruptionCount})`);\n }\n if (datasource) { // Scroller re-initialization case\n this.scroller.adapter.relax(() => {\n this.scroller.logger.log('new Scroller instantiation');\n const scroller = new Scroller<ItemData>({ datasource, scroller: this.scroller });\n this.scroller.dispose();\n this.scroller = scroller;\n this.scroller.init();\n });\n }\n }\n\n done(): void {\n const { state, logger } = this.scroller;\n this.cyclesDone++;\n logger.logCycle(false);\n state.endWorkflowCycle(this.cyclesDone + 1);\n this.finalize();\n }\n\n dispose(): void {\n if (this.initTimer) {\n clearTimeout(this.initTimer);\n }\n this.offScroll();\n this.adapterRun$.dispose();\n this.scroller.dispose(true);\n Object.getOwnPropertyNames(this).forEach(prop => {\n delete (this as Record<string, unknown>)[prop];\n });\n }\n\n finalize(): void {\n }\n\n}\n"],"names":["instanceCount","OBJECT","FUNC_WITH_X_AND_MORE_ARGUMENTS","INTEGER","INTEGER_UNLIMITED","BOOLEAN","OR","Settings"],"mappings":"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"}
|