Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@infinite-list/data-model

Package Overview
Dependencies
Maintainers
1
Versions
155
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@infinite-list/data-model - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1-recycle-alpha.0

dist/struct/Heap.d.ts

5

dist/BaseLayout.d.ts

@@ -14,2 +14,3 @@ import SelectValue from '@x-oasis/select-value';

private _stickyHeaderIndices;
private _recycleThreshold;
readonly _onEndReachedThreshold: number;

@@ -19,3 +20,2 @@ readonly _fillingMode: FillingMode;

id: string;
fillingMode?: FillingMode;
horizontal?: boolean;

@@ -29,2 +29,4 @@ getContainerLayout?: ContainerLayoutGetter;

stickyHeaderIndices?: Array<number>;
recycleThreshold?: number;
recycleEnabled?: boolean;
});

@@ -37,2 +39,3 @@ get initialNumToRender(): number;

set stickyHeaderIndices(indices: Array<number>);
get recycleThreshold(): number;
getHorizontal(): boolean;

@@ -39,0 +42,0 @@ get horizontal(): boolean;

15

dist/ListDimensions.d.ts

@@ -5,3 +5,3 @@ import Batchinator from '@x-oasis/batchinator';

import PrefixIntervalTree from '@x-oasis/prefix-interval-tree';
import { SpaceStateToken, IndexInfo, ItemLayout, KeysChangedType, ListDimensionsProps, ListRenderState, ListState, OnEndReached, PreStateResult, ScrollMetrics, StateListener, SpaceStateTokenPosition } from './types';
import { SpaceStateToken, IndexInfo, ItemLayout, KeysChangedType, ListDimensionsProps, ListRenderState, ListState, OnEndReached, PreStateResult, ScrollMetrics, StateListener, ListStateResult, SpaceStateTokenPosition } from './types';
import OnEndReachedHelper from './viewable/OnEndReachedHelper';

@@ -37,9 +37,11 @@ import EnabledSelector from './utils/EnabledSelector';

private _selector;
private _bufferSet;
private memoizedResolveSpaceState;
private memoizedResolveRecycleState;
constructor(props: ListDimensionsProps<ItemT>);
get length(): number;
get selector(): EnabledSelector;
get stateResult(): import("./types").SpaceStateResult<ItemT>;
get stateResult(): ListStateResult<ItemT>;
set offsetInListGroup(offset: number);
getState(): import("./types").SpaceStateResult<ItemT>;
getState(): ListStateResult<ItemT>;
cleanup(): void;

@@ -82,4 +84,2 @@ resolveInitialActiveValue(active: boolean): boolean;

pump(data: Array<ItemT>, baseIndex: number, keyToMetaMap: Map<string, ItemMeta>, intervalTree: PrefixIntervalTree): void;
intersect(): void;
restart(): void;
append(data: Array<ItemT>): void;

@@ -104,2 +104,7 @@ shuffle(data: Array<ItemT>): void;

hydrateSpaceStateToken(spaceStateResult: Array<SpaceStateToken<ItemT>>, item: ItemT, index: number, position: SpaceStateTokenPosition): void;
getPosition(rowIndex: number, startIndex: number, endIndex: number): number;
resolveRecycleState(state: ListState<ItemT>): {
recycleState: any[];
spaceState: any[];
};
resolveSpaceState(state: ListState<ItemT>): SpaceStateToken<ItemT>[];

@@ -106,0 +111,0 @@ updateState(newState: PreStateResult, scrollMetrics: ScrollMetrics, performItemsMetaChange?: boolean): void;

@@ -11,2 +11,3 @@ import ListDimensions from '../ListDimensions';

distanceFromEnd: number;
actionType: ActionType;
};

@@ -19,4 +20,11 @@ export declare type ActionPayload = {

};
export declare enum ActionType {
HydrationWithBatchUpdate = "hydrationWithBatchUpdate",
ScrollDown = "scrollDown",
ScrollUp = "scrollUp",
Recalculate = "recalculate",
Initial = "initial"
}
export declare type Action = {
type: 'hydrationWithBatchUpdate' | 'scrollDown' | 'scrollUp' | 'recalculate';
type: ActionType;
payload: ActionPayload;

@@ -23,0 +31,0 @@ };

@@ -5,2 +5,3 @@ import BaseDimensions from '../BaseDimensions';

import ListGroupDimensions from '../ListGroupDimensions';
import { ActionType } from '../state/types';
import { OnEndReachedHelperProps } from './onEndReachedHelper';

@@ -59,2 +60,4 @@ import { OnViewableItemsChanged, ViewabilityConfig, ViewabilityConfigCallbackPairs } from './viewable';

onBatchLayoutFinished?: () => boolean;
recycleThreshold?: number;
recycleEnabled?: boolean;
} & BaseDimensionsProps & OnEndReachedHelperProps;

@@ -109,2 +112,3 @@ export declare type ItemsDimensionsProps = BaseDimensionsProps;

distanceFromEnd: number;
actionType: ActionType;
};

@@ -174,3 +178,7 @@ export declare type ListState<ItemT extends {} = {}> = {

export declare type SpaceStateResult<ItemT> = Array<SpaceStateToken<ItemT>>;
export declare type ListStateResult<ItemT> = SpaceStateResult<ItemT>;
export declare type RecycleStateResult<ItemT> = {
spaceState: SpaceStateResult<ItemT>;
recycleState: SpaceStateResult<ItemT>;
};
export declare type ListStateResult<ItemT> = SpaceStateResult<ItemT> | RecycleStateResult<ItemT>;
export declare type StateListener<ItemT = {}> = (newState: ListStateResult<ItemT>, oldState: ListStateResult<ItemT>) => void;

@@ -177,0 +185,0 @@ export declare enum FillingMode {

{
"name": "@infinite-list/data-model",
"version": "0.1.0",
"version": "0.1.1-recycle-alpha.0",
"files": [

@@ -35,2 +35,3 @@ "dist",

"build": "tsdx build --tsconfig tsconfig.build.json",
"watch": "tsdx watch --tsconfig tsconfig.build.json",
"clean": "rimraf ./dist",

@@ -37,0 +38,0 @@ "test": "vitest"

@@ -23,3 +23,3 @@ import ListDimensions from '../ListDimensions';

keyExtractor: defaultKeyExtractor,
data: buildData(20),
data: buildData(50),
maxToRenderPerBatch: 7,

@@ -26,0 +26,0 @@ windowSize: 9,

@@ -5,2 +5,3 @@ import createStore from '../state/createStore';

import { defaultKeyExtractor } from '../exportedUtils';
import { ActionType } from '../state/types';
import { vi, describe, it, expect } from 'vitest';

@@ -58,3 +59,3 @@ const buildData = (count: number) =>

store.dispatch({
type: 'scrollDown',
type: ActionType.ScrollDown,
payload: {

@@ -72,2 +73,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.ScrollDown,
visibleStartIndex: -1,

@@ -119,3 +121,3 @@ visibleEndIndex: -1,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -132,2 +134,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: -1,

@@ -140,3 +143,3 @@ visibleEndIndex: -1,

store.dispatch({
type: 'scrollDown',
type: ActionType.ScrollDown,
payload: {

@@ -154,2 +157,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.ScrollDown,
visibleStartIndex: -1,

@@ -188,3 +192,3 @@ visibleEndIndex: -1,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -201,2 +205,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: 0,

@@ -237,3 +242,3 @@ visibleEndIndex: 0,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -250,2 +255,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: 0,

@@ -288,3 +294,3 @@ visibleEndIndex: 0,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -301,2 +307,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: 0,

@@ -373,3 +380,3 @@ visibleEndIndex: 19,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -386,2 +393,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: 0,

@@ -458,3 +466,3 @@ visibleEndIndex: 20,

store.dispatch({
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -471,2 +479,3 @@ dimension: listGroupDimensions,

expect(store.getState()).toEqual({
actionType: ActionType.HydrationWithBatchUpdate,
visibleStartIndex: 0,

@@ -473,0 +482,0 @@ visibleEndIndex: 9,

@@ -26,2 +26,3 @@ import {

private _stickyHeaderIndices = [];
private _recycleThreshold: number;
readonly _onEndReachedThreshold: number;

@@ -32,3 +33,2 @@ readonly _fillingMode: FillingMode;

id: string;
fillingMode?: FillingMode;
horizontal?: boolean;

@@ -42,6 +42,11 @@ getContainerLayout?: ContainerLayoutGetter;

stickyHeaderIndices?: Array<number>;
recycleThreshold?: number;
recycleEnabled?: boolean;
}) {
const {
id,
recycleThreshold,
persistanceIndices,
recycleEnabled = false,
horizontal = false,

@@ -51,3 +56,2 @@ getContainerLayout,

windowSize = WINDOW_SIZE,
fillingMode = FillingMode.SPACE,
maxToRenderPerBatch = MAX_TO_RENDER_PER_BATCH,

@@ -65,3 +69,8 @@ initialNumToRender = INITIAL_NUM_TO_RENDER,

this._windowSize = windowSize;
this._fillingMode = fillingMode;
this._fillingMode = recycleEnabled
? FillingMode.RECYCLE
: FillingMode.SPACE;
this._recycleThreshold = recycleEnabled
? recycleThreshold || maxToRenderPerBatch * 2
: 0;
this._stickyHeaderIndices = stickyHeaderIndices;

@@ -99,2 +108,6 @@ this._maxToRenderPerBatch = maxToRenderPerBatch;

get recycleThreshold() {
return this._recycleThreshold;
}
getHorizontal() {

@@ -101,0 +114,0 @@ return this._horizontal;

@@ -14,3 +14,3 @@ import noop from '@x-oasis/noop';

import createStore from './state/createStore';
import { ReducerResult, Store } from './state/types';
import { ActionType, ReducerResult, Store } from './state/types';
import {

@@ -34,2 +34,4 @@ SpaceStateToken,

FillingMode,
RecycleStateResult,
SpaceStateResult,
} from './types';

@@ -41,2 +43,3 @@ import ListSpyUtils from './utils/ListSpyUtils';

import memoizeOne from 'memoize-one';
import IntegerBufferSet from './struct/IntegerBufferSet';

@@ -92,5 +95,10 @@ class ListDimensions<ItemT extends {} = {}> extends BaseDimensions {

private _bufferSet = new IntegerBufferSet();
private memoizedResolveSpaceState: (
state: ListState<ItemT>
) => Array<SpaceStateToken<ItemT>>;
) => SpaceStateResult<ItemT>;
private memoizedResolveRecycleState: (
state: ListState<ItemT>
) => RecycleStateResult<ItemT>;

@@ -170,3 +178,9 @@ constructor(props: ListDimensionsProps<ItemT>) {

);
this._stateResult = this.memoizedResolveSpaceState(this._state);
this.memoizedResolveRecycleState = memoizeOne(
this.resolveRecycleState.bind(this)
);
this._stateResult =
this.fillingMode === FillingMode.RECYCLE
? this.memoizedResolveRecycleState(this._state)
: this.memoizedResolveSpaceState(this._state);

@@ -264,3 +278,3 @@ this._store = createStore<ReducerResult>() || store;

data: [],
// itemKeys: [],
actionType: ActionType.Initial,
};

@@ -279,3 +293,3 @@

data: this._data.slice(0, maxIndex + 1),
// itemKeys: this._indexKeys.slice(0, maxIndex + 1),
actionType: ActionType.Initial,
};

@@ -704,6 +718,2 @@ }

intersect() {}
restart() {}
append(data: Array<ItemT>) {

@@ -812,2 +822,8 @@ const baseIndex = this._indexKeys.length;

this._stateResult = stateResult;
} else if (this.fillingMode === FillingMode.RECYCLE) {
const stateResult = this.memoizedResolveRecycleState(state);
if (typeof this._stateListener === 'function') {
this._stateListener(stateResult, this._stateResult);
}
this._stateResult = stateResult;
}

@@ -846,3 +862,3 @@ }

const itemLength =
(itemLayout?.height || 0) + (itemMeta.getSeparatorLength() || 0);
(itemLayout?.height || 0) + (itemMeta?.getSeparatorLength() || 0);

@@ -870,2 +886,178 @@ if (!isSticky && isSpace && lastToken && lastToken.isSpace) {

getPosition(rowIndex: number, startIndex: number, endIndex: number) {
let position = this._bufferSet.getValuePosition(rowIndex);
if (
position === null &&
this._bufferSet.getSize() >= this.recycleThreshold
) {
position = this._bufferSet.replaceFurthestValuePosition(
startIndex,
endIndex,
rowIndex
);
}
if (position === null) {
position = this._bufferSet.getNewPositionForValue(rowIndex);
}
return position;
}
resolveRecycleState(state: ListState<ItemT>) {
const {
visibleEndIndex,
bufferedEndIndex,
visibleStartIndex,
bufferedStartIndex,
actionType,
data,
} = state;
const targetIndices = [];
const scrolling = actionType === 'scrollDown' || actionType === 'scrollUp';
const originalPositionSize = this._bufferSet.getSize();
const recycleEnabled = originalPositionSize >= this.recycleThreshold;
for (let index = bufferedStartIndex; index < visibleStartIndex; index++) {
const position = this.getPosition(
index,
bufferedStartIndex,
visibleStartIndex
);
if (position !== null) targetIndices[position] = index;
}
if (bufferedEndIndex >= 0) {
for (
let index = visibleEndIndex + 1;
index <= bufferedEndIndex;
index++
) {
const position = this.getPosition(
index,
visibleEndIndex + 1,
bufferedEndIndex
);
if (position !== null) targetIndices[position] = index;
}
}
if (visibleEndIndex >= 0 && scrolling) {
for (let index = visibleStartIndex; index <= visibleEndIndex; index++) {
const position = this.getPosition(
index,
visibleStartIndex,
visibleEndIndex
);
if (position !== null) targetIndices[position] = index;
}
}
const recycleStateResult = [];
if (recycleEnabled) {
const indexToOffsetMap = {};
const minValue = this._bufferSet.getMinValue();
const maxValue = this._bufferSet.getMaxValue();
let startOffset = this.getIndexKeyOffset(minValue);
for (let index = minValue; index <= maxValue; index++) {
indexToOffsetMap[index] = startOffset;
const item = data[index];
const itemMeta = this.getItemMeta(item, index);
startOffset +=
(itemMeta?.getLayout()?.height || 0) +
(itemMeta?.getSeparatorLength() || 0);
}
targetIndices.forEach((targetIndex, index) => {
const item = data[targetIndex];
if (!item) return;
const itemKey = this.getItemKey(item, targetIndex);
const itemMeta = this.getItemMeta(item, targetIndex);
const itemLayout = itemMeta?.getLayout();
const itemLength =
(itemLayout?.height || 0) + (itemMeta?.getSeparatorLength() || 0);
recycleStateResult.push({
key: `recycle_${index}`,
targetKey: itemKey,
length: itemLength,
isSpace: false,
isSticky: false,
item,
offset: indexToOffsetMap[targetIndex],
position: 'buffered',
});
});
}
let spaceStateResult = [];
// 滚动中
if (scrolling && recycleEnabled) {
spaceStateResult.push({
key: 'spacer',
length: this.getTotalLength(),
isSpace: true,
isSticky: false,
item: null,
position: 'buffered',
});
} else {
if (recycleEnabled) {
if (visibleStartIndex > 0) {
spaceStateResult.push({
key: 'spacer_before',
length: this.getIndexKeyOffset(visibleStartIndex),
isSpace: true,
isSticky: false,
item: null,
position: 'buffered',
});
}
for (let index = visibleStartIndex; index <= visibleEndIndex; index++) {
const item = data[index];
if (item)
this.hydrateSpaceStateToken(
spaceStateResult,
item,
index,
'buffered'
);
}
if (
visibleEndIndex < data.length - 1 &&
typeof this.getTotalLength() === 'number'
) {
spaceStateResult.push({
key: 'spacer_after',
length:
(this.getTotalLength() as number) -
this.getIndexKeyOffset(visibleEndIndex + 1),
isSpace: true,
isSticky: false,
item: null,
position: 'buffered',
});
}
} else {
spaceStateResult = this.resolveSpaceState(state);
}
}
const stateResult = {
recycleState: recycleStateResult,
spaceState: spaceStateResult,
};
return stateResult;
}
resolveSpaceState(state: ListState<ItemT>) {

@@ -872,0 +1064,0 @@ const { data, bufferedEndIndex, bufferedStartIndex } = state;

import ListDimensions from '../ListDimensions';
import { ScrollMetrics } from '../types';
import { Action, ReducerResult } from './types';
import { Action, ActionType, ReducerResult } from './types';

@@ -21,3 +21,3 @@ export const resolveAction = <State extends ReducerResult = ReducerResult>(

return {
type: 'hydrationWithBatchUpdate',
type: ActionType.HydrationWithBatchUpdate,
payload: {

@@ -34,3 +34,3 @@ dimension,

return {
type: 'scrollDown',
type: ActionType.ScrollDown,
payload: {

@@ -47,3 +47,3 @@ dimension,

return {
type: 'scrollUp',
type: ActionType.ScrollUp,
payload: {

@@ -60,3 +60,3 @@ dimension,

return {
type: 'recalculate',
type: ActionType.Recalculate,
payload: {

@@ -63,0 +63,0 @@ dimension,

@@ -8,3 +8,2 @@ import { ActionPayload, Ctx, ReducerResult } from '../types';

) => {
const { dimension } = payload;
const { bufferedIndexRange, visibleIndexRange } = ctx;

@@ -11,0 +10,0 @@

@@ -13,3 +13,3 @@ import BaseDimensions from '../../BaseDimensions';

if (dimension instanceof BaseDimensions) {
maxIndex = dimension.length;
maxIndex = dimension.length - 1;
} else if (dimension instanceof ListGroupDimensions) {

@@ -16,0 +16,0 @@ maxIndex = dimension.getDataLength() - 1;

@@ -0,1 +1,2 @@

import preCheck from './middleware/preCheck';
import addBatch from './middleware/addBatch';

@@ -9,4 +10,3 @@ import bufferedEndIndexShouldBeReserved from './middleware/bufferedEndIndexShouldBeReserved';

import resolveUnLayoutLimitation from './middleware/resolveUnLayoutLimitation';
import preCheck from './middleware/preCheck';
import { Action, ActionPayload, Ctx, ReducerResult } from './types';
import { Action, ActionPayload, ActionType, Ctx, ReducerResult } from './types';

@@ -41,2 +41,3 @@ const hydrationWithBatchUpdate = <State extends ReducerResult = ReducerResult>(

distanceFromEnd,
actionType: 'hydrationWithBatchUpdate',
visibleStartIndex: visibleIndexRange.startIndex,

@@ -77,2 +78,3 @@ visibleEndIndex: Math.min(visibleIndexRange.endIndex, maxIndex),

distanceFromEnd,
actionType: 'recalculate',
visibleStartIndex: visibleIndexRange.startIndex,

@@ -111,2 +113,3 @@ visibleEndIndex: Math.min(visibleIndexRange.endIndex, maxIndex),

...state,
actionType: 'scrollDown',
isEndReached,

@@ -149,2 +152,3 @@ distanceFromEnd,

distanceFromEnd,
actionType: 'scrollUp',
visibleStartIndex: visibleIndexRange.startIndex,

@@ -164,11 +168,12 @@ visibleEndIndex: Math.min(visibleIndexRange.endIndex, maxIndex),

switch (type) {
case 'hydrationWithBatchUpdate':
case ActionType.HydrationWithBatchUpdate:
return hydrationWithBatchUpdate(state, payload);
case 'scrollDown':
case ActionType.ScrollDown:
return scrollDown(state, payload);
case 'scrollUp':
case ActionType.ScrollUp:
return scrollUp(state, payload);
case 'recalculate':
case ActionType.Initial:
case ActionType.Recalculate:
return recalculate(state, payload);
}
};

@@ -12,2 +12,3 @@ import ListDimensions from '../ListDimensions';

distanceFromEnd: number;
actionType: ActionType;
};

@@ -22,5 +23,12 @@

export enum ActionType {
HydrationWithBatchUpdate = 'hydrationWithBatchUpdate',
ScrollDown = 'scrollDown',
ScrollUp = 'scrollUp',
Recalculate = 'recalculate',
Initial = 'initial',
}
export type Action = {
type: // 应用触底了,但是List仍旧有数据没有渲染
'hydrationWithBatchUpdate' | 'scrollDown' | 'scrollUp' | 'recalculate';
type: ActionType; // 应用触底了,但是List仍旧有数据没有渲染
payload: ActionPayload;

@@ -27,0 +35,0 @@ };

@@ -5,2 +5,3 @@ import BaseDimensions from '../BaseDimensions';

import ListGroupDimensions from '../ListGroupDimensions';
import { ActionType } from '../state/types';
import { OnEndReachedHelperProps } from './onEndReachedHelper';

@@ -71,2 +72,6 @@ import {

onBatchLayoutFinished?: () => boolean;
recycleThreshold?: number;
recycleEnabled?: boolean;
} & BaseDimensionsProps &

@@ -145,2 +150,3 @@ OnEndReachedHelperProps;

distanceFromEnd: number;
actionType: ActionType;
};

@@ -150,4 +156,2 @@

data: Array<ItemT>;
// itemKeys: Array<string>;
// spaceState?: ListSpaceStateResult<ItemT>;
} & PreStateResult;

@@ -225,4 +229,10 @@

export type SpaceStateResult<ItemT> = Array<SpaceStateToken<ItemT>>;
export type RecycleStateResult<ItemT> = {
spaceState: SpaceStateResult<ItemT>;
recycleState: SpaceStateResult<ItemT>;
};
export type ListStateResult<ItemT> = SpaceStateResult<ItemT>;
export type ListStateResult<ItemT> =
| SpaceStateResult<ItemT>
| RecycleStateResult<ItemT>;

@@ -229,0 +239,0 @@ export type StateListener<ItemT = {}> = (

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc