import { onCleanup , createRoot , untrack , createSignal , Owner , Accessor , Setter } from "./signal" ; const FALLBACK = Symbol ( "fallback" ) ; function dispose ( d ) { for ( let i = 0 ; i < d . length ; i ++ ) d [ i ] ( ) ; } description export function mapArray < T , U > ( list , mapFn , options = { } ) { let items = [ ] , mapped = [ ] , disposers = [ ] , len = 0 , indexes = mapFn . length > 1 ? [ ] : null ; onCleanup ( ( ) => dispose ( disposers ) ) ; return ( ) => { let newItems = list ( ) || [ ] , i , j ; return untrack ( ( ) => { let newLen = newItems . length , newIndices , newIndicesNext , temp , tempdisposers , tempIndexes , start , end , newEnd , item ; if ( newLen === 0 ) { if ( len !== 0 ) { dispose ( disposers ) ; disposers = [ ] ; items = [ ] ; mapped = [ ] ; len = 0 ; indexes && ( indexes = [ ] ) ; } if ( options . fallback ) { items = [ FALLBACK ] ; mapped [ 0 ] = createRoot ( disposer => { disposers [ 0 ] = disposer ; return options . fallback ! ( ) ; } ) ; len = 1 ; } } else if ( len === 0 ) { mapped = new Array ( newLen ) ; for ( j = 0 ; j < newLen ; j ++ ) { items [ j ] = newItems [ j ] ; mapped [ j ] = createRoot ( mapper ) ; } len = newLen ; } else { temp = new Array ( newLen ) ; tempdisposers = new Array ( newLen ) ; indexes && ( tempIndexes = new Array ( newLen ) ) ; for ( start = 0 , end = Math . min ( len , newLen ) ; start < end && items [ start ] === newItems [ start ] ; start ++ ) ; for ( end = len - 1 , newEnd = newLen - 1 ; end >= start && newEnd >= start && items [ end ] === newItems [ newEnd ] ; end -- , newEnd -- ) { temp [ newEnd ] = mapped [ end ] ; tempdisposers [ newEnd ] = disposers [ end ] ; indexes && ( tempIndexes ! [ newEnd ] = indexes [ end ] ) ; } newIndices = new Map < T , number > ( ) ; newIndicesNext = new Array ( newEnd + 1 ) ; for ( j = newEnd ; j >= start ; j -- ) { item = newItems [ j ] ; i = newIndices . get ( item ) ! ; newIndicesNext [ j ] = i === undefined ? - 1 : i ; newIndices . set ( item , j ) ; } for ( i = start ; i <= end ; i ++ ) { item = items [ i ] ; j = newIndices . get ( item ) ! ; if ( j !== undefined && j !== - 1 ) { temp [ j ] = mapped [ i ] ; tempdisposers [ j ] = disposers [ i ] ; indexes && ( tempIndexes ! [ j ] = indexes [ i ] ) ; j = newIndicesNext [ j ] ; newIndices . set ( item , j ) ; } else disposers [ i ] ( ) ; } for ( j = start ; j < newLen ; j ++ ) { if ( j in temp ) { mapped [ j ] = temp [ j ] ; disposers [ j ] = tempdisposers [ j ] ; if ( indexes ) { indexes [ j ] = tempIndexes ! [ j ] ; indexes [ j ] ( j ) ; } } else mapped [ j ] = createRoot ( mapper ) ; } mapped = mapped . slice ( 0 , ( len = newLen ) ) ; items = newItems . slice ( 0 ) ; } return mapped ; } ) ; function mapper ( disposer ) { disposers [ j ] = disposer ; if ( indexes ) { const [ s , set ] = createSignal ( j ) ; indexes [ j ] = set ; return mapFn ( newItems [ j ] , s ) ; } return ( mapFn as any ) ( newItems [ j ] ) ; } } ; } description export function indexArray < T , U > ( list , mapFn , options = { } ) { let items = [ ] , mapped = [ ] , disposers = [ ] , signals = [ ] , len = 0 , i ; onCleanup ( ( ) => dispose ( disposers ) ) ; return ( ) => { const newItems = list ( ) || [ ] ; return untrack ( ( ) => { if ( newItems . length === 0 ) { if ( len !== 0 ) { dispose ( disposers ) ; disposers = [ ] ; items = [ ] ; mapped = [ ] ; len = 0 ; signals = [ ] ; } if ( options . fallback ) { items = [ FALLBACK ] ; mapped [ 0 ] = createRoot ( disposer => { disposers [ 0 ] = disposer ; return options . fallback ! ( ) ; } ) ; len = 1 ; } return mapped ; } if ( items [ 0 ] === FALLBACK ) { disposers [ 0 ] ( ) ; disposers = [ ] ; items = [ ] ; mapped = [ ] ; len = 0 ; } for ( i = 0 ; i < newItems . length ; i ++ ) { if ( i < items . length && items [ i ] !== newItems [ i ] ) { signals [ i ] ( ( ) => newItems [ i ] ) ; } else if ( i >= items . length ) { mapped [ i ] = createRoot ( mapper ) ; } } for ( ; i < items . length ; i ++ ) { disposers [ i ] ( ) ; } len = signals . length = disposers . length = newItems . length ; items = newItems . slice ( 0 ) ; return ( mapped = mapped . slice ( 0 , len ) ) ; } ) ; function mapper ( disposer ) { disposers [ i ] = disposer ; const [ s , set ] = createSignal ( newItems [ i ] ) ; signals [ i ] = set ; return mapFn ( s , i ) ; } } ; }