@@ -11,107 +11,114 @@ import {
1111 getCount ,
1212} from './utils' ;
1313
14+ import LazyPaginationConnection from './LazyPaginationConnection' ;
15+
1416import {
1517 MakePaginateOptions ,
1618 PaginateOptions ,
1719 PaginationConnection ,
1820} from './types' ;
1921
22+ function getLazyPaginationConnection < ModelType extends Model > (
23+ modelClass : ModelStatic < ModelType > ,
24+ paginateOptions : PaginateOptions < ModelType > ,
25+ makePaginateOptions ?: MakePaginateOptions ,
26+ ) {
27+ const primaryKeyField =
28+ makePaginateOptions ?. primaryKeyField ?? getPrimaryKeyFields ( modelClass ) ;
29+
30+ const omitPrimaryKeyFromOrder =
31+ makePaginateOptions ?. omitPrimaryKeyFromOrder ?? false ;
32+
33+ const {
34+ order : orderOption ,
35+ where,
36+ after,
37+ before,
38+ limit,
39+ ...restQueryOptions
40+ } = paginateOptions ;
41+
42+ const normalizedOrder = normalizeOrder (
43+ orderOption ,
44+ primaryKeyField ,
45+ omitPrimaryKeyFromOrder ,
46+ ) ;
47+
48+ const order = before ? reverseOrder ( normalizedOrder ) : normalizedOrder ;
49+
50+ const cursor = after
51+ ? parseCursor ( after )
52+ : before
53+ ? parseCursor ( before )
54+ : null ;
55+
56+ const paginationQuery = cursor ? getPaginationQuery ( order , cursor ) : null ;
57+
58+ const paginationWhere : WhereOptions | undefined = paginationQuery
59+ ? { [ Op . and ] : [ paginationQuery , where ] }
60+ : where ;
61+
62+ const paginationQueryOptions = {
63+ where : paginationWhere ,
64+ limit,
65+ order,
66+ ...restQueryOptions ,
67+ } ;
68+
69+ const totalCountQueryOptions = {
70+ where,
71+ ...restQueryOptions ,
72+ } ;
73+
74+ const cursorCountQueryOptions = {
75+ where : paginationWhere ,
76+ ...restQueryOptions ,
77+ } ;
78+
79+ return new LazyPaginationConnection ( {
80+ getEdgesPromise : async ( ) => {
81+ const instances = await modelClass . findAll ( paginationQueryOptions ) ;
82+
83+ if ( before ) {
84+ instances . reverse ( ) ;
85+ }
86+
87+ return instances . map ( ( node ) => ( {
88+ node,
89+ cursor : createCursor ( node , order ) ,
90+ } ) ) ;
91+ } ,
92+ getTotalCountPromise : ( ) => getCount ( modelClass , totalCountQueryOptions ) ,
93+ getCursorCountPromise : ( ) => getCount ( modelClass , cursorCountQueryOptions ) ,
94+ isBefore : Boolean ( before ) ,
95+ } ) ;
96+ }
97+
2098const makePaginate = < ModelType extends Model > (
2199 model : ModelStatic < ModelType > ,
22- options ?: MakePaginateOptions ,
100+ makePaginateOptions ?: MakePaginateOptions ,
23101) => {
24- const primaryKeyField =
25- options ?. primaryKeyField ?? getPrimaryKeyFields ( model ) ;
26-
27- const omitPrimaryKeyFromOrder = options ?. omitPrimaryKeyFromOrder ?? false ;
28-
29102 async function paginate (
30103 this : unknown ,
31- queryOptions : PaginateOptions < ModelType > ,
104+ paginateOptions : PaginateOptions < ModelType > ,
32105 ) : Promise < PaginationConnection < ModelType > > {
33106 const modelClass : ModelStatic < ModelType > = isModelClass ( this )
34107 ? this
35108 : model ;
36109
37- const {
38- order : orderOption ,
39- where,
40- after,
41- before,
42- limit,
43- ...restQueryOptions
44- } = queryOptions ;
45-
46- const normalizedOrder = normalizeOrder (
47- orderOption ,
48- primaryKeyField ,
49- omitPrimaryKeyFromOrder ,
110+ const connection = getLazyPaginationConnection (
111+ modelClass ,
112+ paginateOptions ,
113+ makePaginateOptions ,
50114 ) ;
51115
52- const order = before ? reverseOrder ( normalizedOrder ) : normalizedOrder ;
53-
54- const cursor = after
55- ? parseCursor ( after )
56- : before
57- ? parseCursor ( before )
58- : null ;
59-
60- const paginationQuery = cursor ? getPaginationQuery ( order , cursor ) : null ;
61-
62- const paginationWhere : WhereOptions | undefined = paginationQuery
63- ? { [ Op . and ] : [ paginationQuery , where ] }
64- : where ;
65-
66- const paginationQueryOptions = {
67- where : paginationWhere ,
68- limit,
69- order,
70- ...restQueryOptions ,
71- } ;
72-
73- const totalCountQueryOptions = {
74- where,
75- ...restQueryOptions ,
76- } ;
77-
78- const cursorCountQueryOptions = {
79- where : paginationWhere ,
80- ...restQueryOptions ,
81- } ;
82-
83- const [ instances , totalCount , cursorCount ] = await Promise . all ( [
84- modelClass . findAll ( paginationQueryOptions ) ,
85- getCount ( modelClass , totalCountQueryOptions ) ,
86- getCount ( modelClass , cursorCountQueryOptions ) ,
116+ const [ edges , totalCount , pageInfo ] = await Promise . all ( [
117+ connection . getEdges ( ) ,
118+ connection . getTotalCount ( ) ,
119+ connection . getPageInfo ( ) ,
87120 ] ) ;
88121
89- if ( before ) {
90- instances . reverse ( ) ;
91- }
92-
93- const remaining = cursorCount - instances . length ;
94-
95- const hasNextPage =
96- ( ! before && remaining > 0 ) ||
97- ( Boolean ( before ) && totalCount - cursorCount > 0 ) ;
98-
99- const hasPreviousPage =
100- ( Boolean ( before ) && remaining > 0 ) ||
101- ( ! before && totalCount - cursorCount > 0 ) ;
102-
103- const edges = instances . map ( ( node ) => ( {
104- node,
105- cursor : createCursor ( node , order ) ,
106- } ) ) ;
107-
108- const pageInfo = {
109- hasNextPage,
110- hasPreviousPage,
111- startCursor : edges . length > 0 ? edges [ 0 ] . cursor : null ,
112- endCursor : edges . length > 0 ? edges [ edges . length - 1 ] . cursor : null ,
113- } ;
114-
115122 return {
116123 totalCount,
117124 edges,
@@ -122,4 +129,26 @@ const makePaginate = <ModelType extends Model>(
122129 return paginate ;
123130} ;
124131
132+ export function makePaginateLazy < ModelType extends Model > (
133+ model : ModelStatic < ModelType > ,
134+ makePaginateOptions ?: MakePaginateOptions ,
135+ ) {
136+ function paginateLazy (
137+ this : unknown ,
138+ paginateOptions : PaginateOptions < ModelType > ,
139+ ) {
140+ const modelClass : ModelStatic < ModelType > = isModelClass ( this )
141+ ? this
142+ : model ;
143+
144+ return getLazyPaginationConnection (
145+ modelClass ,
146+ paginateOptions ,
147+ makePaginateOptions ,
148+ ) ;
149+ }
150+
151+ return paginateLazy ;
152+ }
153+
125154export default makePaginate ;
0 commit comments