@@ -5,12 +5,12 @@ export function query<T extends GenericObject, P extends QueryParams<T>>(
55 data : T [ ] ,
66 params : P ,
77) : QueryResult < T , P > {
8- let result = Array . from ( lazyQuery ( data , params ) )
8+ let result : Iterable < T > = lazyQuery ( data , params )
99
1010 if ( params . sort )
11- result = sortedQuery ( result , params . sort )
11+ result = lazySortedQuery ( result , params . sort )
1212
13- return paginateQuery ( result , params )
13+ return paginateQuery ( Array . from ( result ) , params )
1414}
1515
1616function * lazyQuery < T extends GenericObject > ( data : T [ ] , params : QueryParams < T > ) : Generator < T > {
@@ -59,24 +59,59 @@ function matchesFilters<T extends GenericObject>(item: T, filters?: (QueryFilter
5959 } )
6060}
6161
62- function sortedQuery < T extends GenericObject > ( data : T [ ] , sortOptions ?: QueryParams < T > [ 'sort' ] ) : T [ ] {
63- if ( ! sortOptions )
64- return data
62+ function * lazySortedQuery < T extends GenericObject > (
63+ data : Iterable < T > ,
64+ sortOptions ?: QueryParams < T > [ 'sort' ] ,
65+ ) : Generator < T , void , undefined > {
66+ if ( ! sortOptions ) {
67+ yield * data
68+ return
69+ }
6570
6671 const sortArray = Array . isArray ( sortOptions ) ? sortOptions : [ sortOptions ]
67- return data . slice ( ) . sort ( ( a , b ) => {
72+ const buffer : T [ ] = [ ]
73+ const compare = ( a : T , b : T ) => {
6874 for ( const { key, dir, parser } of sortArray ) {
69- const parserHandler = typeof parser === 'function' ? parser : ( v : any ) => parser === 'number' ? Number ( v ) : parser === 'boolean' ? Boolean ( v ) : parser === 'string' ? String ( v ) : v
75+ const parserHandler = typeof parser === 'function'
76+ ? parser
77+ : ( v : any ) =>
78+ parser === 'number'
79+ ? Number ( v )
80+ : parser === 'boolean'
81+ ? Boolean ( v )
82+ : parser === 'string' ? String ( v ) : v
7083 const aParsed = parserHandler ( getObjectProperty ( a , key ) ) ?? null
7184 const bParsed = parserHandler ( getObjectProperty ( b , key ) ) ?? null
72-
7385 if ( aParsed !== bParsed ) {
7486 const comparison = ( aParsed < bParsed ) ? - 1 : 1
7587 return dir === 'asc' ? comparison : - comparison
7688 }
7789 }
7890 return 0
79- } )
91+ }
92+
93+ for ( const item of data ) {
94+ buffer . push ( item )
95+ if ( buffer . length >= 1000 )
96+ break
97+ }
98+
99+ buffer . sort ( compare )
100+
101+ while ( buffer . length > 0 ) {
102+ yield buffer [ 0 ]
103+ buffer . shift ( )
104+
105+ for ( const item of data ) {
106+ let insertIndex = buffer . findIndex ( bufferItem => compare ( item , bufferItem ) < 0 )
107+ if ( insertIndex === - 1 ) {
108+ insertIndex = buffer . length
109+ }
110+ buffer . splice ( insertIndex , 0 , item )
111+ if ( buffer . length >= 1000 )
112+ break
113+ }
114+ }
80115}
81116
82117function paginateQuery < T extends GenericObject , P extends QueryParams < T > > ( data : T [ ] , params : P ) : QueryResult < T , P > {
0 commit comments