@crawlee/core 4.0.0-beta.194 → 4.0.0-beta.196

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/core",
3
- "version": "4.0.0-beta.194",
3
+ "version": "4.0.0-beta.196",
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"
@@ -53,10 +53,10 @@
53
53
  "@apify/log": "^3.0.1",
54
54
  "@apify/timeout": "^1.0.1",
55
55
  "@apify/utilities": "^3.0.1",
56
- "@crawlee/fs-storage": "4.0.0-beta.194",
57
- "@crawlee/http-client": "4.0.0-beta.194",
58
- "@crawlee/types": "4.0.0-beta.194",
59
- "@crawlee/utils": "4.0.0-beta.194",
56
+ "@crawlee/fs-storage": "4.0.0-beta.196",
57
+ "@crawlee/http-client": "4.0.0-beta.196",
58
+ "@crawlee/types": "4.0.0-beta.196",
59
+ "@crawlee/utils": "4.0.0-beta.196",
60
60
  "@sapphire/async-queue": "^1.5.5",
61
61
  "@standard-schema/spec": "^1.0.0",
62
62
  "@vladfrangu/async_event_emitter": "^2.4.6",
@@ -76,5 +76,5 @@
76
76
  }
77
77
  }
78
78
  },
79
- "gitHead": "c1f1ba3f6d24d5de59360c0616c49ce557ceb290"
79
+ "gitHead": "769227e112c5e1694b3e80b5a56dc4c007407d3d"
80
80
  }
package/request.js CHANGED
@@ -2,11 +2,11 @@ import crypto from 'node:crypto';
2
2
  import { z } from 'zod';
3
3
  import { cryptoRandomObjectId, normalizeUrl } from '@apify/utilities';
4
4
  import { serviceLocator } from './service_locator.js';
5
- import { keys } from './typedefs.js';
6
5
  import { parseArgument, schemas } from './validators.js';
7
- const requestUrlSchema = z.object({ url: z.string() });
8
6
  // new properties on the Request object breaks serialization
9
- const requestOptionalSchemaShapes = {
7
+ // Compiled once: every `Request` runs it, and the generated fast path skips zod's interpreter.
8
+ const requestOptionsSchema = z.compile(z.looseObject({
9
+ url: z.string(),
10
10
  uniqueKey: z.string().optional(),
11
11
  method: z.string().optional(),
12
12
  payload: z.union([z.string(), z.instanceof(Uint8Array)]).optional(),
@@ -23,9 +23,7 @@ const requestOptionalSchemaShapes = {
23
23
  crawlDepth: schemas.anyNumber
24
24
  .refine((value) => value >= 0, 'Expected a number greater than or equal to 0')
25
25
  .optional(),
26
- };
27
- // Each schema is wrapped in a single-key object so validation errors carry the property name.
28
- const requestOptionalSchemas = Object.fromEntries(Object.entries(requestOptionalSchemaShapes).map(([key, schema]) => [key, z.object({ [key]: schema })]));
26
+ }));
29
27
  /**
30
28
  * Represents a URL to be crawled, optionally including HTTP method, headers, payload and other metadata, together
31
29
  * with the processing state a request queue keeps about it (`retryCount`, `errorMessages`, `handledAt`, ...).
@@ -110,22 +108,7 @@ class CrawleeRequest {
110
108
  'Did you mean `new Request({ url })`?');
111
109
  }
112
110
  parseArgument(options, schemas.anyObject, 'RequestOptions');
113
- parseArgument(options, requestUrlSchema, 'RequestOptions');
114
- // Full-shape validation is slow, because it checks all predicates
115
- // even if the validated object has only 1 property.
116
- // This custom validation loop iterates only over existing
117
- // properties and speeds up the validation cca 3-fold.
118
- keys(options).forEach((prop) => {
119
- // skip url, because it is validated above
120
- if (prop === 'url') {
121
- return;
122
- }
123
- const schema = requestOptionalSchemas[prop];
124
- const value = options[prop];
125
- if (schema) {
126
- parseArgument({ [prop]: value }, schema, 'RequestOptions');
127
- }
128
- });
111
+ parseArgument(options, requestOptionsSchema, 'RequestOptions');
129
112
  const { url, uniqueKey, payload, noRetry = false, sessionId, maxRetries, headers = {}, userData = {}, label, keepUrlFragment = false, useExtendedUniqueKey = false, alwaysEnqueue = false, skipNavigation, enqueueStrategy, crawlDepth, } = options;
130
113
  let { method = 'GET' } = options;
131
114
  method = method.toUpperCase();
@@ -38,19 +38,20 @@ const addRequestsBatchedOptionsSchema = z.strictObject({
38
38
  waitBetweenBatchesMillis: schemas.anyNumber.default(1000),
39
39
  maxNewRequests: schemas.anyNumber.optional(),
40
40
  });
41
- const newRequestLikeSchema = z.looseObject({
41
+ // Compiled: these run once per request.
42
+ const newRequestLikeSchema = z.compile(z.looseObject({
42
43
  url: z.string(),
43
44
  id: z.undefined().optional(),
44
- });
45
- const handledRequestSchema = z.looseObject({
45
+ }));
46
+ const handledRequestSchema = z.compile(z.looseObject({
46
47
  id: z.string(),
47
48
  uniqueKey: z.string(),
48
49
  handledAt: z.string().optional(),
49
- });
50
- const reclaimedRequestSchema = z.looseObject({
50
+ }));
51
+ const reclaimedRequestSchema = z.compile(z.looseObject({
51
52
  id: z.string(),
52
53
  uniqueKey: z.string(),
53
- });
54
+ }));
54
55
  const uniqueKeySchema = z.string();
55
56
  const openOptionsSchema = z.strictObject({
56
57
  configuration: z.instanceof(Configuration).optional(),