startgg-helper 2.3.2 → 2.4.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/query.js +54 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "startgg-helper",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "A set of functions and classes useful to communicate with the start.gg API, using any client (YOU NEED TO PROVIDE A CLIENT YOURSELF, SEE README)",
5
5
  "main": "main.js",
6
6
  "module": "main.js",
package/src/query.js CHANGED
@@ -5,6 +5,17 @@ function isConnection(val){
5
5
  return val instanceof Object && val.nodes instanceof Array
6
6
  }
7
7
 
8
+ export class PageResult {
9
+ /**
10
+ * @param {any} result
11
+ * @param {boolean} stop
12
+ */
13
+ constructor(result, stop){
14
+ this.result = result;
15
+ this.stop = stop;
16
+ }
17
+ }
18
+
8
19
  /**
9
20
  * A GraphQL Document/Schema. Allows easily batch-requesting with the same schema but different parameters.
10
21
  */
@@ -94,6 +105,8 @@ export class Query {
94
105
  OUT: 3
95
106
  }
96
107
 
108
+ /** @typedef {(localResult: T[], currentResult: T[], pageIndex: number) => (T[]|PageResult|boolean)?} PageCallback*/
109
+
97
110
  /**
98
111
  * Queries a whole paginated collection (of a *Connection type). See the start.gg API doc or this package's documentation for more info about pagniated collections. This is done through executing the query repeatedly while increasing the page index each time.
99
112
  * The target collection must be pointed to by the "path" argument, and will be agregated in a single array. The schema must have a variable (whose name can be specified in parameters) that is used as the page index of the paginated field.
@@ -103,7 +116,7 @@ export class Query {
103
116
  * @param {{[varName: string]: value}} params GraphQL variables ; does not include the page index variable.
104
117
  * @param {string} connectionPathInQuery JSON path to the paginated collection that must be aggregated in the query (JSON path : property names separated by dots, see deep_get())
105
118
  * @param {TimedQuerySemaphore} limiter A request limiter object; see TimedQuerySemaphore
106
- * @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, delay?: number, maxElements?: number, includeWholeQuery?: number, callback: (localResult: T[]) => T[]?}} config
119
+ * @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, delay?: number, maxElements?: number, includeWholeQuery?: number, callback: PageCallback?}} config
107
120
  * @param config.pageParamName name of the variable representing the page index. This variable must exist in your query, and be used as an argument in a paginated collection field
108
121
  * @param config.delay number of miliseconds to wait for between each query. No delay if absent.
109
122
  * @param config.maxElements if present, queries will stop once this many elements have been fetched
@@ -150,29 +163,58 @@ export class Query {
150
163
 
151
164
  let localResult = connection.nodes;
152
165
 
153
- if (connection.pageInfo && connection.pageInfo.totalPages){
166
+ if (connection.pageInfo && connection.pageInfo.totalPages){ //if the query contains pageInfo we use that to determine if we're at the last page
154
167
  let totalPages = connection.pageInfo.totalPages;
155
- if (!totalPages || currentPage >= totalPages) {
168
+ if (currentPage >= totalPages) {
156
169
  if (config.callback){
157
- let cbRes = config.callback(localResult, currentPage);
158
- if (!cbRes) break;
159
- localResult = cbRes;
170
+ let cbRes = config.callback(localResult, currentResult, pageIndex)
171
+
172
+ if (cbRes instanceof PageResult){
173
+ if (cbRes.result){ //If the user gives us a result we take it ofc
174
+ result = cbRes.result;
175
+ } else {
176
+ result = result.concat(localResult);
177
+ }
178
+ } else if (cbRes && cbRes !== true) { //cbres isn't one that means something loop-control-related (it's over anyways so we don't care!)
179
+ result = result.concat(cbRes);
180
+ }
181
+ } else {
182
+ result = result.concat(localResult);
160
183
  }
161
- result = result.concat(localResult);
162
184
  break;
163
185
  }
164
- } else {
186
+ } else { //if not, we only know when we get an empty page
165
187
  if (localResult.length < 1) break;
166
188
  }
167
189
 
168
190
  if (config.callback){
169
191
  let cbRes = config.callback(localResult, currentPage);
170
- if (!cbRes) break;
171
- localResult = cbRes;
192
+
193
+ if (cbRes instanceof PageResult){
194
+ if (cbRes.result){ //If the user gives us a result we take it ofc
195
+ result = cbRes.result;
196
+ } else {
197
+ result = result.concat(localResult);
198
+ }
199
+ if (cbRes.stop){
200
+ break;
201
+ }
202
+ currentPage++;
203
+ } else if (!cbRes) { //"normal case" : basic callback that doesn't touch the flow of the pexecution, we concat and increment normally
204
+ result = result.concat(localResult)
205
+ currentPage++;
206
+ } else if (cbRes === true){ //callback is asking us to stop by returning true
207
+ break;
208
+ } else { //callback returns a non-boolean value : it's the local result (and we increment normally)
209
+ result = result.concat(cbRes);
210
+ currentPage++;
211
+ }
212
+
213
+ } else {
214
+ result = result.concat(localResult);
215
+ currentPage++;
172
216
  }
173
217
 
174
- result = result.concat(localResult);
175
- currentPage++;
176
218
  params[pageParamName] = currentPage;
177
219
 
178
220
  if (delay)