@crawlee/utils 4.0.0-beta.112 → 4.0.0-beta.114

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.
@@ -3,7 +3,6 @@ import { PassThrough, pipeline, Readable, Transform } from 'node:stream';
3
3
  import { StringDecoder } from 'node:string_decoder';
4
4
  import { createGunzip } from 'node:zlib';
5
5
  import { FetchHttpClient } from '@crawlee/http-client';
6
- import sax from 'sax';
7
6
  import MIMEType from 'whatwg-mimetype';
8
7
  import { mergeAsyncIterables } from './iterables.js';
9
8
  import { RobotsTxtFile } from './robots.js';
@@ -47,11 +46,15 @@ class SitemapTxtParser extends Transform {
47
46
  }
48
47
  class SitemapXmlParser extends Transform {
49
48
  #decoder = new StringDecoder('utf8');
50
- #parser = new sax.SAXParser(true);
49
+ #parser;
51
50
  #rootTagName;
52
51
  #currentTag = undefined;
53
52
  #url = {};
54
- constructor() {
53
+ static async create() {
54
+ const { SAXParser } = await import('sax');
55
+ return new SitemapXmlParser(new SAXParser(true));
56
+ }
57
+ constructor(parser) {
55
58
  super({
56
59
  readableObjectMode: true,
57
60
  transform: (chunk, _encoding, callback) => {
@@ -67,6 +70,7 @@ class SitemapXmlParser extends Transform {
67
70
  callback();
68
71
  },
69
72
  });
73
+ this.#parser = parser;
70
74
  this.#parser.onopentag = this.onOpenTag.bind(this);
71
75
  this.#parser.onclosetag = this.onCloseTag.bind(this);
72
76
  this.#parser.ontext = this.onText.bind(this);
@@ -131,7 +135,7 @@ export async function* parseSitemap(initialSources, proxyUrl, options) {
131
135
  const { httpClient = new FetchHttpClient(), emitNestedSitemaps = false, maxDepth = Infinity, sitemapRetries = 3, timeoutMillis: timeout = 30000, reportNetworkErrors = true, nestedSitemapFilter, logger, } = options ?? {};
132
136
  const sources = [...initialSources];
133
137
  const visitedSitemapUrls = new Set();
134
- const createParser = (contentType = '', url) => {
138
+ const createParser = async (contentType = '', url) => {
135
139
  let mimeType;
136
140
  try {
137
141
  mimeType = new MIMEType(contentType);
@@ -140,7 +144,7 @@ export async function* parseSitemap(initialSources, proxyUrl, options) {
140
144
  mimeType = null;
141
145
  }
142
146
  if (mimeType?.isXML() || url?.pathname.endsWith('.xml')) {
143
- return new SitemapXmlParser();
147
+ return SitemapXmlParser.create();
144
148
  }
145
149
  if (mimeType?.essence === 'text/plain' || url?.pathname.endsWith('.txt')) {
146
150
  return new SitemapTxtParser();
@@ -194,7 +198,7 @@ export async function* parseSitemap(initialSources, proxyUrl, options) {
194
198
  sitemapUrl.pathname = sitemapUrl.pathname.substring(0, sitemapUrl.pathname.length - 3);
195
199
  }
196
200
  }
197
- items = pipeline(streamWithType, isGzipped ? createGunzip() : new PassThrough(), createParser(contentType ?? undefined, sitemapUrl), (e) => {
201
+ items = pipeline(streamWithType, isGzipped ? createGunzip() : new PassThrough(), await createParser(contentType ?? undefined, sitemapUrl), (e) => {
198
202
  if (e !== undefined && e !== null) {
199
203
  error = { type: 'parser', error: e };
200
204
  }
@@ -222,7 +226,7 @@ export async function* parseSitemap(initialSources, proxyUrl, options) {
222
226
  }
223
227
  }
224
228
  else if (source.type === 'raw') {
225
- items = pipeline(Readable.from([source.content]), createParser('text/xml'), (error) => {
229
+ items = pipeline(Readable.from([source.content]), await createParser('text/xml'), (error) => {
226
230
  if (error !== undefined) {
227
231
  logger?.warning(`Malformed sitemap content: ${error}`);
228
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/utils",
3
- "version": "4.0.0-beta.112",
3
+ "version": "4.0.0-beta.114",
4
4
  "description": "A set of shared utilities that can be used by crawlers",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -43,8 +43,8 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@apify/ps-tree": "^1.2.0",
46
- "@crawlee/http-client": "4.0.0-beta.112",
47
- "@crawlee/types": "4.0.0-beta.112",
46
+ "@crawlee/http-client": "4.0.0-beta.114",
47
+ "@crawlee/types": "4.0.0-beta.114",
48
48
  "@types/sax": "^1.2.7",
49
49
  "cheerio": "^1.0.0",
50
50
  "domhandler": "^5.0.3",
@@ -62,5 +62,5 @@
62
62
  }
63
63
  }
64
64
  },
65
- "gitHead": "5d1e107d4dc4ffd21f1c6cc5b1a1c10b59ca2b47"
65
+ "gitHead": "e00fd1671498a90451e62730d58cae1f5d89f2be"
66
66
  }