apify-client 3.0.0-beta.46 → 3.0.0-beta.48

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.
@@ -70,35 +70,39 @@ export class ApiClient {
70
70
  // `buildParams()` and the query string. The same goes for `timeoutSecs` and `signal`, which callers take out
71
71
  // before calling this, since they also apply to every page request.
72
72
  const { chunkSize, ...listOptions } = options;
73
- const paginatedListPromise = getPaginatedList({
74
- ...listOptions,
75
- limit: minForLimitParam(options.limit, chunkSize),
76
- });
73
+ const firstPageLimit = minForLimitParam(options.limit, chunkSize);
74
+ const paginatedListPromise = getPaginatedList({ ...listOptions, limit: firstPageLimit });
77
75
  // A page can return more or fewer items than the rows it scanned (see `SCANNED_COUNT`). The next offset and
78
- // the stop condition follow the scanned number alone: advancing by `items.length` would re-scan rows after a
79
- // filter dropped some and skip rows after `unwind` multiplied them, and stopping at an empty page would end
80
- // the iteration in front of rows a filter hid.
81
- const scannedRows = (page) => page[SCANNED_COUNT] ?? page.items.length;
76
+ // the stop condition follow the scanned rows: advancing by `items.length` would re-scan rows after a filter
77
+ // dropped some and skip rows after `unwind` multiplied them, and stopping at an empty page would end the
78
+ // iteration in front of rows a filter hid. The scanned number is derived from a dataset's item count, which
79
+ // lags a fresh push, so the larger of it and `items.length` is taken, capped at the rows the request asked for
80
+ // so that an unwound page does not advance past rows the next request would then never read.
81
+ const scannedRows = (page, requestedLimit) => {
82
+ const scanned = Math.max(page[SCANNED_COUNT] ?? 0, page.items.length);
83
+ return requestedLimit ? Math.min(scanned, requestedLimit) : scanned;
84
+ };
85
+ // `total` is not consulted, as it changes when the listed resource grows during the iteration.
82
86
  async function* asyncGenerator() {
83
87
  let currentPage = await paginatedListPromise;
84
88
  yield* currentPage.items;
85
- const offset = options.offset ?? 0;
86
- const limit = Math.min(options.limit || currentPage.total, currentPage.total);
87
- let pageScanned = scannedRows(currentPage);
88
- let currentOffset = offset + pageScanned;
89
- let remainingItems = Math.min(currentPage.total - offset, limit) - pageScanned;
89
+ let pageScanned = scannedRows(currentPage, firstPageLimit);
90
+ let currentOffset = (options.offset ?? 0) + pageScanned;
91
+ let remainingItems = options.limit ? options.limit - pageScanned : undefined;
90
92
  while (pageScanned > 0 && // Continue only if the last page scanned some rows.
91
- remainingItems > 0) {
93
+ (remainingItems === undefined || remainingItems > 0)) {
94
+ const requestedLimit = minForLimitParam(remainingItems, chunkSize);
92
95
  const newOptions = {
93
96
  ...listOptions,
94
- limit: minForLimitParam(remainingItems, chunkSize),
97
+ limit: requestedLimit,
95
98
  offset: currentOffset,
96
99
  };
97
100
  currentPage = await getPaginatedList(newOptions);
98
101
  yield* currentPage.items;
99
- pageScanned = scannedRows(currentPage);
102
+ pageScanned = scannedRows(currentPage, requestedLimit);
100
103
  currentOffset += pageScanned;
101
- remainingItems -= pageScanned;
104
+ if (remainingItems !== undefined)
105
+ remainingItems -= pageScanned;
102
106
  }
103
107
  }
104
108
  return Object.defineProperty(paginatedListPromise, Symbol.asyncIterator, {
@@ -11,6 +11,11 @@ export declare class ResourceCollectionClient extends ApiClient {
11
11
  * @private
12
12
  */
13
13
  protected listResources<T, R>(schema: z.ZodType, options: T | undefined, timeoutSecs: Timeout, signal?: AbortSignal): Promise<R>;
14
+ /**
15
+ * Lists an endpoint that returns every item in one response and ignores `offset` and `limit`. The result can be
16
+ * awaited as that response or iterated over its items, with a single request either way.
17
+ */
18
+ protected listUnpaginatedResources<Data, R extends PaginatedResponse<Data>>(schema: z.ZodType, timeoutSecs: Timeout, signal?: AbortSignal): AsyncIterable<Data> & Promise<R>;
14
19
  /**
15
20
  * Returns async iterator to iterate through all items and Promise that can be awaited to get first page of results.
16
21
  * `defaultTimeoutSecs` applies to every page request unless `options.timeoutSecs` overrides it, and
@@ -18,6 +18,18 @@ export class ResourceCollectionClient extends ApiClient {
18
18
  });
19
19
  return parseResponse(response, schema);
20
20
  }
21
+ /**
22
+ * Lists an endpoint that returns every item in one response and ignores `offset` and `limit`. The result can be
23
+ * awaited as that response or iterated over its items, with a single request either way.
24
+ */
25
+ listUnpaginatedResources(schema, timeoutSecs, signal) {
26
+ const listPromise = this.listResources(schema, undefined, timeoutSecs, signal);
27
+ return Object.defineProperty(listPromise, Symbol.asyncIterator, {
28
+ async *value() {
29
+ yield* (await listPromise).items;
30
+ },
31
+ });
32
+ }
21
33
  /**
22
34
  * Returns async iterator to iterate through all items and Promise that can be awaited to get first page of results.
23
35
  * `defaultTimeoutSecs` applies to every page request unless `options.timeoutSecs` overrides it, and