@crawlee/core 4.0.0-beta.169 → 4.0.0-beta.170
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.
- package/autoscaling/system_status.d.ts +3 -3
- package/crawlers/statistics.d.ts +34 -42
- package/crawlers/statistics.js +52 -60
- package/package.json +6 -6
|
@@ -80,12 +80,12 @@ export interface LoadSignalInfo {
|
|
|
80
80
|
actualRatio: number;
|
|
81
81
|
}
|
|
82
82
|
export interface FinalStatistics {
|
|
83
|
-
|
|
83
|
+
requestsSucceeded: number;
|
|
84
84
|
requestsFailed: number;
|
|
85
85
|
retryHistogram: number[];
|
|
86
86
|
requestAvgFailedDurationMillis: number;
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
requestAvgSucceededDurationMillis: number;
|
|
88
|
+
requestsSucceededPerMinute: number;
|
|
89
89
|
requestsFailedPerMinute: number;
|
|
90
90
|
requestTotalDurationMillis: number;
|
|
91
91
|
requestsTotal: number;
|
package/crawlers/statistics.d.ts
CHANGED
|
@@ -33,16 +33,16 @@ export interface IStatistics<StateExtension extends object = {}> {
|
|
|
33
33
|
readonly errorTrackerRetry: ErrorTracker;
|
|
34
34
|
/** The live statistics state the crawler reads for status messages and the final summary. */
|
|
35
35
|
readonly state: StatisticState & StateExtension;
|
|
36
|
-
/** Retries histogram - index `i` holds the number of requests that
|
|
36
|
+
/** Retries histogram - index `i` holds the number of requests that settled after `i` retries. */
|
|
37
37
|
readonly requestRetryHistogram: number[];
|
|
38
|
-
/** Marks a request as started, so its duration can be measured on
|
|
39
|
-
|
|
40
|
-
/** Marks a started request as
|
|
41
|
-
|
|
38
|
+
/** Marks a request as started, so its duration can be measured on success/failure. */
|
|
39
|
+
recordRequestStart(id: number | string): void;
|
|
40
|
+
/** Marks a started request as succeeded, updating the succeeded counters and durations. */
|
|
41
|
+
recordRequestSuccess(id: number | string, retryCount: number): void;
|
|
42
42
|
/** Marks a started request as failed, updating the failed counters and durations. */
|
|
43
|
-
|
|
44
|
-
/** Drops a started request without counting it as
|
|
45
|
-
|
|
43
|
+
recordRequestFailure(id: number | string, retryCount: number): void;
|
|
44
|
+
/** Drops a started request without counting it as succeeded or failed (e.g. skipped by robots.txt). */
|
|
45
|
+
discardRequestRecord(id: number | string): void;
|
|
46
46
|
/** Increments the counter for the given HTTP status code. */
|
|
47
47
|
registerStatusCode(code: number): void;
|
|
48
48
|
/** Computes the derived aggregates (averages, per-minute rates, totals) from the current state. */
|
|
@@ -61,15 +61,15 @@ export interface IStatistics<StateExtension extends object = {}> {
|
|
|
61
61
|
export interface CalculatedStatistics {
|
|
62
62
|
/** Mean duration of a failed request, in milliseconds; `Infinity` when nothing has failed. */
|
|
63
63
|
requestAvgFailedDurationMillis: number;
|
|
64
|
-
/** Mean duration of a
|
|
65
|
-
|
|
66
|
-
/** Requests
|
|
67
|
-
|
|
64
|
+
/** Mean duration of a succeeded request, in milliseconds; `Infinity` when nothing has succeeded. */
|
|
65
|
+
requestAvgSucceededDurationMillis: number;
|
|
66
|
+
/** Requests succeeded per minute over the run so far. */
|
|
67
|
+
requestsSucceededPerMinute: number;
|
|
68
68
|
/** Requests failed per minute over the run so far. */
|
|
69
69
|
requestsFailedPerMinute: number;
|
|
70
|
-
/** Combined duration of all
|
|
70
|
+
/** Combined duration of all succeeded and failed requests, in milliseconds. */
|
|
71
71
|
requestTotalDurationMillis: number;
|
|
72
|
-
/** Total number of settled requests (
|
|
72
|
+
/** Total number of settled requests (succeeded plus failed). */
|
|
73
73
|
requestsTotal: number;
|
|
74
74
|
/** Wall-clock runtime since capturing started, in milliseconds. */
|
|
75
75
|
crawlerRuntimeMillis: number;
|
|
@@ -131,27 +131,19 @@ export declare class Statistics<StateExtension extends object = {}, PersistedSta
|
|
|
131
131
|
* Increments the status code counter.
|
|
132
132
|
*/
|
|
133
133
|
registerStatusCode(code: number): void;
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Mark job as failed and sets the state
|
|
146
|
-
* @ignore
|
|
147
|
-
*/
|
|
148
|
-
failJob(id: number | string, retryCount: number): void;
|
|
149
|
-
/**
|
|
150
|
-
* Discards a started job without affecting the finished/failed counters, e.g. when a request
|
|
151
|
-
* turns out to be skipped (robots.txt, enqueue strategy) after `startJob` was already called for it.
|
|
134
|
+
/** @ignore */
|
|
135
|
+
recordRequestStart(id: number | string): void;
|
|
136
|
+
/** @ignore */
|
|
137
|
+
recordRequestSuccess(id: number | string, retryCount: number): void;
|
|
138
|
+
/** @ignore */
|
|
139
|
+
recordRequestFailure(id: number | string, retryCount: number): void;
|
|
140
|
+
/**
|
|
141
|
+
* Discards a started request without affecting the succeeded/failed counters, e.g. when a request
|
|
142
|
+
* turns out to be skipped (robots.txt, enqueue strategy) after `recordRequestStart` was already
|
|
143
|
+
* called for it.
|
|
152
144
|
* @ignore
|
|
153
145
|
*/
|
|
154
|
-
|
|
146
|
+
discardRequestRecord(id: number | string): void;
|
|
155
147
|
/**
|
|
156
148
|
* Calculate the current statistics
|
|
157
149
|
*/
|
|
@@ -165,7 +157,7 @@ export declare class Statistics<StateExtension extends object = {}, PersistedSta
|
|
|
165
157
|
* Stops logging and remove event listeners, then persist
|
|
166
158
|
*/
|
|
167
159
|
stopCapturing(): Promise<void>;
|
|
168
|
-
private
|
|
160
|
+
private saveRetryCountForRequest;
|
|
169
161
|
/**
|
|
170
162
|
* Persist internal state to the key value store.
|
|
171
163
|
*
|
|
@@ -277,12 +269,12 @@ export interface StatisticStateExtensionOptions<StateExtension extends object, P
|
|
|
277
269
|
* Format of the persisted stats.
|
|
278
270
|
*
|
|
279
271
|
* The `null`s are `Infinity` on the way out - JSON has no infinity, so a record written before anything
|
|
280
|
-
*
|
|
272
|
+
* succeeded or failed carries a `null` in its place.
|
|
281
273
|
*/
|
|
282
|
-
export interface StatisticPersistedState extends Omit<StatisticState, 'statsPersistedAt' | 'crawlerStartedAt' | 'crawlerFinishedAt' | 'requestMinDurationMillis' | 'requestsFailedPerMinute' | '
|
|
274
|
+
export interface StatisticPersistedState extends Omit<StatisticState, 'statsPersistedAt' | 'crawlerStartedAt' | 'crawlerFinishedAt' | 'requestMinDurationMillis' | 'requestsFailedPerMinute' | 'requestsSucceededPerMinute' | 'requestRetryHistogram' | 'instanceStart'> {
|
|
283
275
|
statsId: string;
|
|
284
276
|
requestsFailedPerMinute: number | null;
|
|
285
|
-
|
|
277
|
+
requestsSucceededPerMinute: number | null;
|
|
286
278
|
/** ISO strings - the live state keeps these as `Date`s. */
|
|
287
279
|
crawlerStartedAt: string | null;
|
|
288
280
|
crawlerFinishedAt: string | null;
|
|
@@ -291,7 +283,7 @@ export interface StatisticPersistedState extends Omit<StatisticState, 'statsPers
|
|
|
291
283
|
/** A retry count that no request ever reached leaves a `null` here. */
|
|
292
284
|
requestRetryHistogram: (number | null)[];
|
|
293
285
|
requestAvgFailedDurationMillis: number | null;
|
|
294
|
-
|
|
286
|
+
requestAvgSucceededDurationMillis: number | null;
|
|
295
287
|
requestTotalDurationMillis: number;
|
|
296
288
|
requestsTotal: number;
|
|
297
289
|
/** {@link StatisticState.instanceStart} of the run that wrote the record. */
|
|
@@ -301,15 +293,15 @@ export interface StatisticPersistedState extends Omit<StatisticState, 'statsPers
|
|
|
301
293
|
* Contains the statistics state
|
|
302
294
|
*/
|
|
303
295
|
export interface StatisticState {
|
|
304
|
-
|
|
296
|
+
requestsSucceeded: number;
|
|
305
297
|
requestsFailed: number;
|
|
306
298
|
requestsRetries: number;
|
|
307
299
|
requestsFailedPerMinute: number;
|
|
308
|
-
|
|
300
|
+
requestsSucceededPerMinute: number;
|
|
309
301
|
requestMinDurationMillis: number;
|
|
310
302
|
requestMaxDurationMillis: number;
|
|
311
303
|
requestTotalFailedDurationMillis: number;
|
|
312
|
-
|
|
304
|
+
requestTotalSucceededDurationMillis: number;
|
|
313
305
|
crawlerStartedAt: Date | string | null;
|
|
314
306
|
crawlerFinishedAt: Date | string | null;
|
|
315
307
|
crawlerRuntimeMillis: number;
|
|
@@ -317,7 +309,7 @@ export interface StatisticState {
|
|
|
317
309
|
errors: Record<string, unknown>;
|
|
318
310
|
retryErrors: Record<string, unknown>;
|
|
319
311
|
requestsWithStatusCode: Record<string, number>;
|
|
320
|
-
/** Retries histogram - index `i` holds the number of requests that
|
|
312
|
+
/** Retries histogram - index `i` holds the number of requests that settled after `i` retries. */
|
|
321
313
|
requestRetryHistogram: number[];
|
|
322
314
|
/**
|
|
323
315
|
* When the current capture window started, as a `Date.now()` timestamp. Rebased on load so that the runtime
|
package/crawlers/statistics.js
CHANGED
|
@@ -7,15 +7,13 @@ import { ErrorTracker } from './error_tracker.js';
|
|
|
7
7
|
/**
|
|
8
8
|
* @ignore
|
|
9
9
|
*/
|
|
10
|
-
class
|
|
10
|
+
class RequestProcessingRecord {
|
|
11
11
|
#lastRunAt = null;
|
|
12
|
-
#durationMillis;
|
|
13
12
|
run() {
|
|
14
13
|
this.#lastRunAt = Date.now();
|
|
15
14
|
}
|
|
16
15
|
finish() {
|
|
17
|
-
|
|
18
|
-
return this.#durationMillis;
|
|
16
|
+
return Date.now() - this.#lastRunAt;
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
const statisticsOptionsSchema = z.strictObject({
|
|
@@ -53,15 +51,15 @@ const errorTrackerConfig = {
|
|
|
53
51
|
* validated by their own conversion on the way back, so the keys it does not know about are simply dropped here.
|
|
54
52
|
*/
|
|
55
53
|
const persistedStatisticState = z.object({
|
|
56
|
-
|
|
54
|
+
requestsSucceeded: z.number(),
|
|
57
55
|
requestsFailed: z.number(),
|
|
58
56
|
requestsRetries: z.number(),
|
|
59
57
|
requestsFailedPerMinute: z.number().nullable(),
|
|
60
|
-
|
|
58
|
+
requestsSucceededPerMinute: z.number().nullable(),
|
|
61
59
|
requestMinDurationMillis: z.number().nullable(),
|
|
62
60
|
requestMaxDurationMillis: z.number(),
|
|
63
61
|
requestTotalFailedDurationMillis: z.number(),
|
|
64
|
-
|
|
62
|
+
requestTotalSucceededDurationMillis: z.number(),
|
|
65
63
|
crawlerStartedAt: z.string().nullable(),
|
|
66
64
|
crawlerFinishedAt: z.string().nullable(),
|
|
67
65
|
statsPersistedAt: z.string(),
|
|
@@ -72,7 +70,7 @@ const persistedStatisticState = z.object({
|
|
|
72
70
|
requestRetryHistogram: z.array(z.number().nullable()),
|
|
73
71
|
statsId: z.string(),
|
|
74
72
|
requestAvgFailedDurationMillis: z.number().nullable(),
|
|
75
|
-
|
|
73
|
+
requestAvgSucceededDurationMillis: z.number().nullable(),
|
|
76
74
|
requestTotalDurationMillis: z.number(),
|
|
77
75
|
requestsTotal: z.number(),
|
|
78
76
|
requestsWithStatusCode: z.record(z.string(), z.number()),
|
|
@@ -97,11 +95,11 @@ function buildStatisticStateCodec(statistics) {
|
|
|
97
95
|
return z.codec(persistedStatisticState, z.custom(), {
|
|
98
96
|
decode: (record) => ({
|
|
99
97
|
...statistics.defaultState(),
|
|
100
|
-
|
|
98
|
+
requestsSucceeded: record.requestsSucceeded,
|
|
101
99
|
requestsFailed: record.requestsFailed,
|
|
102
100
|
requestsRetries: record.requestsRetries,
|
|
103
101
|
requestTotalFailedDurationMillis: record.requestTotalFailedDurationMillis,
|
|
104
|
-
|
|
102
|
+
requestTotalSucceededDurationMillis: record.requestTotalSucceededDurationMillis,
|
|
105
103
|
// Restoring the `null` as-is would make every later `duration < min` comparison fail, leaving the
|
|
106
104
|
// minimum `null` for the rest of the run.
|
|
107
105
|
requestMinDurationMillis: record.requestMinDurationMillis ?? Infinity,
|
|
@@ -117,10 +115,12 @@ function buildStatisticStateCodec(statistics) {
|
|
|
117
115
|
instanceStart: Date.now() - (new Date(record.statsPersistedAt).getTime() - record.crawlerLastStartTimestamp),
|
|
118
116
|
}),
|
|
119
117
|
encode: (state) => {
|
|
118
|
+
// The per-minute rates fall through into `counters` and are overwritten below by `calculate()`'s,
|
|
119
|
+
// which are the ones the record carries.
|
|
120
120
|
const { requestsWithStatusCode, errors, retryErrors, requestRetryHistogram, instanceStart, ...counters } = state;
|
|
121
121
|
// Every rate and average `calculate()` derives is `Infinity` until the run is long enough, or until
|
|
122
|
-
// something has
|
|
123
|
-
const { requestAvgFailedDurationMillis,
|
|
122
|
+
// something has succeeded or failed, to divide by.
|
|
123
|
+
const { requestAvgFailedDurationMillis, requestAvgSucceededDurationMillis, requestsFailedPerMinute, requestsSucceededPerMinute, ...aggregates } = statistics.calculate();
|
|
124
124
|
return {
|
|
125
125
|
...counters,
|
|
126
126
|
requestMinDurationMillis: finiteOrNull(state.requestMinDurationMillis),
|
|
@@ -134,9 +134,9 @@ function buildStatisticStateCodec(statistics) {
|
|
|
134
134
|
statsId: statistics.statsId,
|
|
135
135
|
...aggregates,
|
|
136
136
|
requestAvgFailedDurationMillis: finiteOrNull(requestAvgFailedDurationMillis),
|
|
137
|
-
|
|
137
|
+
requestAvgSucceededDurationMillis: finiteOrNull(requestAvgSucceededDurationMillis),
|
|
138
138
|
requestsFailedPerMinute: finiteOrNull(requestsFailedPerMinute),
|
|
139
|
-
|
|
139
|
+
requestsSucceededPerMinute: finiteOrNull(requestsSucceededPerMinute),
|
|
140
140
|
requestsWithStatusCode,
|
|
141
141
|
errors,
|
|
142
142
|
retryErrors,
|
|
@@ -284,15 +284,15 @@ export class Statistics {
|
|
|
284
284
|
/** The built-in half of {@link Statistics.defaultState}, before any custom fields are merged over it. */
|
|
285
285
|
#builtInDefaultState() {
|
|
286
286
|
return {
|
|
287
|
-
|
|
287
|
+
requestsSucceeded: 0,
|
|
288
288
|
requestsFailed: 0,
|
|
289
289
|
requestsRetries: 0,
|
|
290
290
|
requestsFailedPerMinute: 0,
|
|
291
|
-
|
|
291
|
+
requestsSucceededPerMinute: 0,
|
|
292
292
|
requestMinDurationMillis: Infinity,
|
|
293
293
|
requestMaxDurationMillis: 0,
|
|
294
294
|
requestTotalFailedDurationMillis: 0,
|
|
295
|
-
|
|
295
|
+
requestTotalSucceededDurationMillis: 0,
|
|
296
296
|
crawlerStartedAt: null,
|
|
297
297
|
crawlerFinishedAt: null,
|
|
298
298
|
statsPersistedAt: null,
|
|
@@ -323,70 +323,62 @@ export class Statistics {
|
|
|
323
323
|
}
|
|
324
324
|
this.state.requestsWithStatusCode[s]++;
|
|
325
325
|
}
|
|
326
|
-
/**
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
job = new Job();
|
|
334
|
-
job.run();
|
|
335
|
-
this.#requestsInProgress.set(id, job);
|
|
326
|
+
/** @ignore */
|
|
327
|
+
recordRequestStart(id) {
|
|
328
|
+
let record = this.#requestsInProgress.get(id);
|
|
329
|
+
if (!record)
|
|
330
|
+
record = new RequestProcessingRecord();
|
|
331
|
+
record.run();
|
|
332
|
+
this.#requestsInProgress.set(id, record);
|
|
336
333
|
}
|
|
337
|
-
/**
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
finishJob(id, retryCount) {
|
|
342
|
-
const job = this.#requestsInProgress.get(id);
|
|
343
|
-
if (!job)
|
|
334
|
+
/** @ignore */
|
|
335
|
+
recordRequestSuccess(id, retryCount) {
|
|
336
|
+
const record = this.#requestsInProgress.get(id);
|
|
337
|
+
if (!record)
|
|
344
338
|
return;
|
|
345
|
-
const
|
|
346
|
-
this.state.
|
|
347
|
-
this.state.
|
|
348
|
-
this.
|
|
349
|
-
if (
|
|
350
|
-
this.state.requestMinDurationMillis =
|
|
351
|
-
if (
|
|
352
|
-
this.state.requestMaxDurationMillis =
|
|
339
|
+
const durationMillis = record.finish();
|
|
340
|
+
this.state.requestsSucceeded++;
|
|
341
|
+
this.state.requestTotalSucceededDurationMillis += durationMillis;
|
|
342
|
+
this.saveRetryCountForRequest(retryCount);
|
|
343
|
+
if (durationMillis < this.state.requestMinDurationMillis)
|
|
344
|
+
this.state.requestMinDurationMillis = durationMillis;
|
|
345
|
+
if (durationMillis > this.state.requestMaxDurationMillis)
|
|
346
|
+
this.state.requestMaxDurationMillis = durationMillis;
|
|
353
347
|
this.#requestsInProgress.delete(id);
|
|
354
348
|
}
|
|
355
|
-
/**
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
failJob(id, retryCount) {
|
|
360
|
-
const job = this.#requestsInProgress.get(id);
|
|
361
|
-
if (!job)
|
|
349
|
+
/** @ignore */
|
|
350
|
+
recordRequestFailure(id, retryCount) {
|
|
351
|
+
const record = this.#requestsInProgress.get(id);
|
|
352
|
+
if (!record)
|
|
362
353
|
return;
|
|
363
|
-
this.state.requestTotalFailedDurationMillis +=
|
|
354
|
+
this.state.requestTotalFailedDurationMillis += record.finish();
|
|
364
355
|
this.state.requestsFailed++;
|
|
365
|
-
this.
|
|
356
|
+
this.saveRetryCountForRequest(retryCount);
|
|
366
357
|
this.#requestsInProgress.delete(id);
|
|
367
358
|
}
|
|
368
359
|
/**
|
|
369
|
-
* Discards a started
|
|
370
|
-
* turns out to be skipped (robots.txt, enqueue strategy) after `
|
|
360
|
+
* Discards a started request without affecting the succeeded/failed counters, e.g. when a request
|
|
361
|
+
* turns out to be skipped (robots.txt, enqueue strategy) after `recordRequestStart` was already
|
|
362
|
+
* called for it.
|
|
371
363
|
* @ignore
|
|
372
364
|
*/
|
|
373
|
-
|
|
365
|
+
discardRequestRecord(id) {
|
|
374
366
|
this.#requestsInProgress.delete(id);
|
|
375
367
|
}
|
|
376
368
|
/**
|
|
377
369
|
* Calculate the current statistics
|
|
378
370
|
*/
|
|
379
371
|
calculate() {
|
|
380
|
-
const { requestsFailed,
|
|
372
|
+
const { requestsFailed, requestsSucceeded, requestTotalFailedDurationMillis, requestTotalSucceededDurationMillis, } = this.state;
|
|
381
373
|
const totalMillis = Date.now() - this.state.instanceStart;
|
|
382
374
|
const totalMinutes = totalMillis / 1000 / 60;
|
|
383
375
|
return {
|
|
384
376
|
requestAvgFailedDurationMillis: Math.round(requestTotalFailedDurationMillis / requestsFailed) || Infinity,
|
|
385
|
-
|
|
386
|
-
|
|
377
|
+
requestAvgSucceededDurationMillis: Math.round(requestTotalSucceededDurationMillis / requestsSucceeded) || Infinity,
|
|
378
|
+
requestsSucceededPerMinute: Math.round(requestsSucceeded / totalMinutes) || 0,
|
|
387
379
|
requestsFailedPerMinute: Math.floor(requestsFailed / totalMinutes) || 0,
|
|
388
|
-
requestTotalDurationMillis:
|
|
389
|
-
requestsTotal: requestsFailed +
|
|
380
|
+
requestTotalDurationMillis: requestTotalSucceededDurationMillis + requestTotalFailedDurationMillis,
|
|
381
|
+
requestsTotal: requestsFailed + requestsSucceeded,
|
|
390
382
|
crawlerRuntimeMillis: totalMillis,
|
|
391
383
|
};
|
|
392
384
|
}
|
|
@@ -420,7 +412,7 @@ export class Statistics {
|
|
|
420
412
|
this.state.crawlerFinishedAt = new Date();
|
|
421
413
|
await this.#recoverableState.teardown();
|
|
422
414
|
}
|
|
423
|
-
|
|
415
|
+
saveRetryCountForRequest(retryCount) {
|
|
424
416
|
if (retryCount > 0)
|
|
425
417
|
this.state.requestsRetries++;
|
|
426
418
|
this.requestRetryHistogram[retryCount] ??= 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crawlee/core",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.170",
|
|
4
4
|
"description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0"
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"@apify/log": "^3.0.1",
|
|
53
53
|
"@apify/timeout": "^1.0.1",
|
|
54
54
|
"@apify/utilities": "^3.0.1",
|
|
55
|
-
"@crawlee/fs-storage": "4.0.0-beta.
|
|
56
|
-
"@crawlee/http-client": "4.0.0-beta.
|
|
57
|
-
"@crawlee/types": "4.0.0-beta.
|
|
58
|
-
"@crawlee/utils": "4.0.0-beta.
|
|
55
|
+
"@crawlee/fs-storage": "4.0.0-beta.170",
|
|
56
|
+
"@crawlee/http-client": "4.0.0-beta.170",
|
|
57
|
+
"@crawlee/types": "4.0.0-beta.170",
|
|
58
|
+
"@crawlee/utils": "4.0.0-beta.170",
|
|
59
59
|
"@sapphire/async-queue": "^1.5.5",
|
|
60
60
|
"@standard-schema/spec": "^1.0.0",
|
|
61
61
|
"@vladfrangu/async_event_emitter": "^2.4.6",
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "86e1c891da983125e9e18f1a2327fbcf5e0f5fc2"
|
|
82
82
|
}
|