@gscdump/engine-gsc-api 0.27.2 → 0.28.1

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/dist/index.mjs +59 -25
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -218,47 +218,69 @@ async function runGscSyncSlice(opts) {
218
218
  let totalRows = 0;
219
219
  let pageCount = 0;
220
220
  let metadata;
221
- while (true) {
222
- if (pageCount >= maxPages) return {
223
- totalRows,
224
- hasMore: true,
225
- nextStartRow: startRow,
226
- metadata
227
- };
228
- if (Date.now() - loopStart >= cpuBudgetMs) return {
229
- totalRows,
230
- hasMore: true,
231
- nextStartRow: startRow,
232
- metadata
233
- };
221
+ const fetchPage = async (row) => {
234
222
  const query = {
235
223
  startDate: opts.startDate,
236
224
  endDate: opts.endDate,
237
225
  dimensions,
238
226
  rowLimit,
239
- startRow,
227
+ startRow: row,
240
228
  dataState,
241
229
  type: searchType,
242
230
  ...dimensionFilterGroups ? { dimensionFilterGroups } : {}
243
231
  };
244
- const response = await opts.client._rawQuery(opts.siteUrl, query).catch((err) => {
245
- if (isTimeoutLike(err)) return null;
246
- throw err;
247
- });
248
- if (!response) return {
232
+ try {
233
+ const response = await opts.client._rawQuery(opts.siteUrl, query);
234
+ return {
235
+ kind: "ok",
236
+ startRow: row,
237
+ rows: response.rows ?? [],
238
+ metadata: response.metadata
239
+ };
240
+ } catch (err) {
241
+ if (isTimeoutLike(err)) return {
242
+ kind: "timeout",
243
+ startRow: row
244
+ };
245
+ return {
246
+ kind: "error",
247
+ error: err
248
+ };
249
+ }
250
+ };
251
+ const startFetchIfAllowed = (row) => {
252
+ if (pageCount >= maxPages) return null;
253
+ if (Date.now() - loopStart >= cpuBudgetMs) return null;
254
+ return fetchPage(row);
255
+ };
256
+ let pending = startFetchIfAllowed(startRow);
257
+ if (pending === null) return {
258
+ totalRows,
259
+ hasMore: true,
260
+ nextStartRow: startRow,
261
+ metadata
262
+ };
263
+ while (pending !== null) {
264
+ const page = await pending;
265
+ pending = null;
266
+ if (page.kind === "error") throw page.error;
267
+ if (page.kind === "timeout") return {
249
268
  totalRows,
250
269
  hasMore: true,
251
- nextStartRow: startRow,
270
+ nextStartRow: page.startRow,
252
271
  metadata
253
272
  };
254
- const rows = response.rows ?? [];
273
+ const rows = page.rows;
255
274
  totalRows += rows.length;
256
275
  pageCount++;
257
- if (response.metadata) metadata = response.metadata;
276
+ if (page.metadata) metadata = page.metadata;
258
277
  opts.onPage?.({
259
278
  searchType,
260
279
  rowsThisPage: rows.length
261
280
  });
281
+ const isLastPage = rows.length < rowLimit;
282
+ const nextStartRow = page.startRow + rows.length;
283
+ const prefetch = isLastPage ? null : startFetchIfAllowed(nextStartRow);
262
284
  if (rows.length > 0) {
263
285
  if (await opts.onBatch(rows).then(() => false).catch((err) => {
264
286
  if (isTimeoutLike(err)) return true;
@@ -266,12 +288,24 @@ async function runGscSyncSlice(opts) {
266
288
  })) return {
267
289
  totalRows: totalRows - rows.length,
268
290
  hasMore: true,
269
- nextStartRow: startRow,
291
+ nextStartRow: page.startRow,
270
292
  metadata
271
293
  };
272
294
  }
273
- if (rows.length < rowLimit) break;
274
- startRow += rows.length;
295
+ if (isLastPage) return {
296
+ totalRows,
297
+ hasMore: false,
298
+ nextStartRow,
299
+ metadata
300
+ };
301
+ if (prefetch === null) return {
302
+ totalRows,
303
+ hasMore: true,
304
+ nextStartRow,
305
+ metadata
306
+ };
307
+ startRow = nextStartRow;
308
+ pending = prefetch;
275
309
  }
276
310
  return {
277
311
  totalRows,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/engine-gsc-api",
3
3
  "type": "module",
4
- "version": "0.27.2",
4
+ "version": "0.28.1",
5
5
  "description": "GSC live-API engine adapter — wraps the Search Analytics REST API as an AnalysisQuerySource for typed analyzer dispatch.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -36,8 +36,8 @@
36
36
  "node": ">=18"
37
37
  },
38
38
  "dependencies": {
39
- "gscdump": "0.27.2",
40
- "@gscdump/engine": "0.27.2"
39
+ "@gscdump/engine": "0.28.1",
40
+ "gscdump": "0.28.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "vitest": "^4.1.9"