@xberg-io/crawlberg-wasm 1.1.4 → 1.3.2

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": "@xberg-io/crawlberg-wasm",
3
- "version": "1.1.4",
3
+ "version": "1.3.2",
4
4
  "private": false,
5
5
  "description": "High-performance web crawling engine",
6
6
  "license": "MIT",
@@ -13,15 +13,19 @@
13
13
  "access": "public"
14
14
  },
15
15
  "type": "module",
16
- "files": [
17
- "pkg",
18
- "*.wasm",
19
- "*.d.ts",
20
- "README.md"
21
- ],
16
+ "files": ["pkg", "*.wasm", "*.d.ts", "README.md"],
22
17
  "main": "pkg/nodejs/crawlberg_wasm.js",
23
18
  "module": "pkg/web/crawlberg_wasm.js",
24
19
  "types": "pkg/nodejs/crawlberg_wasm.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./pkg/nodejs/crawlberg_wasm.d.ts",
23
+ "browser": "./pkg/web/crawlberg_wasm.js",
24
+ "import": "./pkg/nodejs/crawlberg_wasm.js",
25
+ "require": "./pkg/nodejs/crawlberg_wasm.js",
26
+ "default": "./pkg/nodejs/crawlberg_wasm.js"
27
+ }
28
+ },
25
29
  "engines": {
26
30
  "node": ">= 22"
27
31
  },
@@ -267,6 +267,13 @@ export class WasmContentConfig {
267
267
  wrapWidth: number;
268
268
  }
269
269
 
270
+ /**
271
+ * Content filter applied to each crawled page before it reaches the result.
272
+ */
273
+ export enum WasmContentFilterKind {
274
+ Bm25 = 0,
275
+ }
276
+
270
277
  /**
271
278
  * Information about an HTTP cookie received from a response.
272
279
  */
@@ -290,7 +297,7 @@ export class WasmCrawlConfig {
290
297
  free(): void;
291
298
  [Symbol.dispose](): void;
292
299
  static default(): WasmCrawlConfig;
293
- constructor(respectRobotsTxt?: boolean | null, softHttpErrors?: boolean | null, stayOnDomain?: boolean | null, allowSubdomains?: boolean | null, includePaths?: string[] | null, excludePaths?: string[] | null, customHeaders?: any | null, requestTimeout?: bigint | null, maxRedirects?: number | null, retryCount?: number | null, retryCodes?: Uint16Array | null, cookiesEnabled?: boolean | null, removeTags?: string[] | null, content?: WasmContentConfig | null, downloadAssets?: boolean | null, assetTypes?: any[] | null, browser?: WasmBrowserConfig | null, userAgents?: string[] | null, captureScreenshot?: boolean | null, followDocumentUrls?: boolean | null, downloadDocuments?: boolean | null, documentMimeTypes?: string[] | null, saveBrowserProfile?: boolean | null, ssrf?: WasmSsrfPolicy | null, maxDepth?: number | null, maxPages?: number | null, maxConcurrent?: number | null, userAgent?: string | null, rateLimitMs?: bigint | null, auth?: any | null, maxBodySize?: number | null, mapLimit?: number | null, mapSearch?: string | null, maxAssetSize?: number | null, proxy?: WasmProxyConfig | null, documentUrlDepth?: number | null, documentMaxSize?: number | null, warcOutput?: string | null, browserProfile?: string | null);
300
+ constructor(crawlStrategy?: WasmCrawlStrategyKind | null, respectRobotsTxt?: boolean | null, softHttpErrors?: boolean | null, stayOnDomain?: boolean | null, allowSubdomains?: boolean | null, includePaths?: string[] | null, excludePaths?: string[] | null, customHeaders?: any | null, requestTimeout?: bigint | null, maxRedirects?: number | null, retryCount?: number | null, retryCodes?: Uint16Array | null, cookiesEnabled?: boolean | null, removeTags?: string[] | null, content?: WasmContentConfig | null, downloadAssets?: boolean | null, assetTypes?: any[] | null, browser?: WasmBrowserConfig | null, userAgents?: string[] | null, captureScreenshot?: boolean | null, followDocumentUrls?: boolean | null, downloadDocuments?: boolean | null, documentMimeTypes?: string[] | null, saveBrowserProfile?: boolean | null, ssrf?: WasmSsrfPolicy | null, maxDepth?: number | null, maxPages?: number | null, maxLinksPerPage?: number | null, maxConcurrent?: number | null, contentFilter?: WasmContentFilterKind | null, bm25Query?: string | null, bm25Threshold?: number | null, userAgent?: string | null, rateLimitMs?: bigint | null, auth?: any | null, maxBodySize?: number | null, mapLimit?: number | null, mapSearch?: string | null, maxAssetSize?: number | null, proxy?: WasmProxyConfig | null, documentUrlDepth?: number | null, documentMaxSize?: number | null, documentOutputDir?: string | null, documentContentEncoding?: WasmDocumentContentEncoding | null, warcOutput?: string | null, browserProfile?: string | null, ssrfDenyPrivateExplicit?: boolean | null);
294
301
  /**
295
302
  * Validate the configuration, returning an error if any values are invalid.
296
303
  */
@@ -299,16 +306,28 @@ export class WasmCrawlConfig {
299
306
  assetTypes: string[];
300
307
  get auth(): any | undefined;
301
308
  set auth(value: any | null | undefined);
309
+ get bm25Query(): string | undefined;
310
+ set bm25Query(value: string | null | undefined);
311
+ get bm25Threshold(): number | undefined;
312
+ set bm25Threshold(value: number | null | undefined);
302
313
  browser: WasmBrowserConfig;
303
314
  get browserProfile(): string | undefined;
304
315
  set browserProfile(value: string | null | undefined);
305
316
  captureScreenshot: boolean;
306
317
  content: WasmContentConfig;
318
+ get contentFilter(): string | undefined;
319
+ set contentFilter(value: WasmContentFilterKind | null | undefined);
307
320
  cookiesEnabled: boolean;
321
+ get crawlStrategy(): string;
322
+ set crawlStrategy(value: WasmCrawlStrategyKind);
308
323
  customHeaders: any;
324
+ get documentContentEncoding(): string | undefined;
325
+ set documentContentEncoding(value: WasmDocumentContentEncoding | null | undefined);
309
326
  get documentMaxSize(): number | undefined;
310
327
  set documentMaxSize(value: number | null | undefined);
311
328
  documentMimeTypes: string[];
329
+ get documentOutputDir(): string | undefined;
330
+ set documentOutputDir(value: string | null | undefined);
312
331
  get documentUrlDepth(): number | undefined;
313
332
  set documentUrlDepth(value: number | null | undefined);
314
333
  downloadAssets: boolean;
@@ -328,6 +347,8 @@ export class WasmCrawlConfig {
328
347
  set maxConcurrent(value: number | null | undefined);
329
348
  get maxDepth(): number | undefined;
330
349
  set maxDepth(value: number | null | undefined);
350
+ get maxLinksPerPage(): number | undefined;
351
+ set maxLinksPerPage(value: number | null | undefined);
331
352
  get maxPages(): number | undefined;
332
353
  set maxPages(value: number | null | undefined);
333
354
  maxRedirects: number;
@@ -344,6 +365,8 @@ export class WasmCrawlConfig {
344
365
  saveBrowserProfile: boolean;
345
366
  softHttpErrors: boolean;
346
367
  ssrf: WasmSsrfPolicy;
368
+ get ssrfDenyPrivateExplicit(): boolean | undefined;
369
+ set ssrfDenyPrivateExplicit(value: boolean | null | undefined);
347
370
  stayOnDomain: boolean;
348
371
  get userAgent(): string | undefined;
349
372
  set userAgent(value: string | null | undefined);
@@ -410,6 +433,13 @@ export class WasmCrawlResult {
410
433
  constructor(pages?: WasmCrawlPageResult[] | null, finalUrl?: string | null, redirectCount?: number | null, wasSkipped?: boolean | null, cookies?: WasmCookieInfo[] | null, stayedOnDomain?: boolean | null, browserUsed?: boolean | null, error?: string | null);
411
434
  /**
412
435
  * Returns the count of unique normalized URLs encountered during crawling.
436
+ *
437
+ * Computed from `pages` (not the deprecated `normalized_urls` field) so it
438
+ * is correct across every binding that reconstructs `CrawlResult` from
439
+ * `pages` alone. In streaming mode `pages` is empty, so this returns 0 on
440
+ * the opaque-handle (C/Go/C#/Zig/Dart) path where it previously counted
441
+ * streamed pages — a known, accepted cost of making the other ten binding
442
+ * families correct.
413
443
  */
414
444
  uniqueNormalizedUrls(): number;
415
445
  browserUsed: boolean;
@@ -423,6 +453,32 @@ export class WasmCrawlResult {
423
453
  wasSkipped: boolean;
424
454
  }
425
455
 
456
+ /**
457
+ * Traversal order for a crawl.
458
+ *
459
+ * Selects both the queue discipline and the selection strategy, because global order is a
460
+ * property of the frontier: the engine hands its bounded selection window to the strategy, so
461
+ * a strategy alone can only reorder URLs that have already been dequeued.
462
+ */
463
+ export enum WasmCrawlStrategyKind {
464
+ Bfs = 0,
465
+ Dfs = 1,
466
+ BestFirst = 2,
467
+ Adaptive = 3,
468
+ }
469
+
470
+ /**
471
+ * Opt-in encoding applied to a downloaded document's bytes for callers who need the
472
+ * content available in a serializable field rather than reading it from disk.
473
+ *
474
+ * `None` (the `CrawlConfig.document_content_encoding` default) produces neither — unlike
475
+ * screenshots, base64-encoding a document by default would duplicate an already
476
+ * up-to-`document_max_size` buffer (50 MB default) in memory per document.
477
+ */
478
+ export enum WasmDocumentContentEncoding {
479
+ Base64 = 0,
480
+ }
481
+
426
482
  /**
427
483
  * A downloaded asset from a page.
428
484
  */
@@ -453,13 +509,18 @@ export class WasmDownloadedDocument {
453
509
  free(): void;
454
510
  [Symbol.dispose](): void;
455
511
  static default(): WasmDownloadedDocument;
456
- constructor(url?: string | null, mimeType?: string | null, size?: number | null, contentHash?: string | null, headers?: any | null, filename?: string | null);
512
+ constructor(url?: string | null, mimeType?: string | null, size?: number | null, contentHash?: string | null, headers?: any | null, truncated?: boolean | null, filename?: string | null, contentPath?: string | null, contentBase64?: string | null);
513
+ get contentBase64(): string | undefined;
514
+ set contentBase64(value: string | null | undefined);
457
515
  contentHash: string;
516
+ get contentPath(): string | undefined;
517
+ set contentPath(value: string | null | undefined);
458
518
  get filename(): string | undefined;
459
519
  set filename(value: string | null | undefined);
460
520
  headers: any;
461
521
  mimeType: string;
462
522
  size: number;
523
+ truncated: boolean;
463
524
  url: string;
464
525
  }
465
526
 
@@ -534,6 +595,33 @@ export class WasmHeadingInfo {
534
595
  text: string;
535
596
  }
536
597
 
598
+ /**
599
+ * Hostname/IP allowlist matcher for SSRF policy.
600
+ *
601
+ * Serializes as an internally-tagged object so each variant is distinguishable on the
602
+ * wire and round-trips losslessly:
603
+ *
604
+ * ```json
605
+ * {"type": "exact", "value": "api.example.com"}
606
+ * {"type": "suffix", "value": ".example.com"}
607
+ * {"type": "cidr", "value": "10.0.0.0/8"}
608
+ * ```
609
+ *
610
+ * A bare JSON string is still accepted on deserialization and resolves to `Exact`,
611
+ * preserving configs written against the previous untagged representation.
612
+ *
613
+ * `Exact`: HostMatcher.Exact
614
+ */
615
+ export class WasmHostMatcher {
616
+ free(): void;
617
+ [Symbol.dispose](): void;
618
+ static default(): WasmHostMatcher;
619
+ constructor();
620
+ type: string;
621
+ get value(): string | undefined;
622
+ set value(value: string | null | undefined);
623
+ }
624
+
537
625
  /**
538
626
  * An hreflang alternate link entry.
539
627
  */
@@ -582,10 +670,12 @@ export class WasmInteractionResult {
582
670
  free(): void;
583
671
  [Symbol.dispose](): void;
584
672
  static default(): WasmInteractionResult;
585
- constructor(actionResults?: WasmActionResult[] | null, finalHtml?: string | null, finalUrl?: string | null);
673
+ constructor(actionResults?: WasmActionResult[] | null, finalHtml?: string | null, finalUrl?: string | null, screenshotBase64?: string | null);
586
674
  actionResults: WasmActionResult[];
587
675
  finalHtml: string;
588
676
  finalUrl: string;
677
+ get screenshotBase64(): string | undefined;
678
+ set screenshotBase64(value: string | null | undefined);
589
679
  }
590
680
 
591
681
  /**
@@ -830,7 +920,7 @@ export class WasmScrapeResult {
830
920
  free(): void;
831
921
  [Symbol.dispose](): void;
832
922
  static default(): WasmScrapeResult;
833
- constructor(statusCode?: number | null, finalUrl?: string | null, contentType?: string | null, html?: string | null, bodySize?: number | null, metadata?: WasmPageMetadata | null, links?: WasmLinkInfo[] | null, images?: WasmImageInfo[] | null, feeds?: WasmFeedInfo[] | null, jsonLd?: WasmJsonLdEntry[] | null, isAllowed?: boolean | null, noindexDetected?: boolean | null, nofollowDetected?: boolean | null, isPdf?: boolean | null, wasSkipped?: boolean | null, authHeaderSent?: boolean | null, assets?: WasmDownloadedAsset[] | null, jsRenderHint?: boolean | null, browserUsed?: boolean | null, crawlDelay?: bigint | null, xRobotsTag?: string | null, detectedCharset?: string | null, responseMeta?: WasmResponseMeta | null, markdown?: WasmMarkdownResult | null, extractedData?: any | null, extractionMeta?: WasmExtractionMeta | null, downloadedDocument?: WasmDownloadedDocument | null, browser?: WasmBrowserExtras | null);
923
+ constructor(statusCode?: number | null, finalUrl?: string | null, contentType?: string | null, html?: string | null, bodySize?: number | null, metadata?: WasmPageMetadata | null, links?: WasmLinkInfo[] | null, images?: WasmImageInfo[] | null, feeds?: WasmFeedInfo[] | null, jsonLd?: WasmJsonLdEntry[] | null, isAllowed?: boolean | null, noindexDetected?: boolean | null, nofollowDetected?: boolean | null, isPdf?: boolean | null, wasSkipped?: boolean | null, authHeaderSent?: boolean | null, assets?: WasmDownloadedAsset[] | null, jsRenderHint?: boolean | null, browserUsed?: boolean | null, crawlDelay?: bigint | null, xRobotsTag?: string | null, detectedCharset?: string | null, responseMeta?: WasmResponseMeta | null, markdown?: WasmMarkdownResult | null, extractedData?: any | null, extractionMeta?: WasmExtractionMeta | null, screenshotBase64?: string | null, downloadedDocument?: WasmDownloadedDocument | null, browser?: WasmBrowserExtras | null);
834
924
  assets: WasmDownloadedAsset[];
835
925
  authHeaderSent: boolean;
836
926
  bodySize: number;
@@ -864,6 +954,8 @@ export class WasmScrapeResult {
864
954
  noindexDetected: boolean;
865
955
  get responseMeta(): WasmResponseMeta | undefined;
866
956
  set responseMeta(value: WasmResponseMeta | null | undefined);
957
+ get screenshotBase64(): string | undefined;
958
+ set screenshotBase64(value: string | null | undefined);
867
959
  statusCode: number;
868
960
  wasSkipped: boolean;
869
961
  get xRobotsTag(): string | undefined;
@@ -913,9 +1005,18 @@ export class WasmSsrfPolicy {
913
1005
  * - Outbound requests in a browser go through the fetch API, which enforces its own network policies.
914
1006
  * - Rust-side SSRF checking is unenforceable and redundant in a wasm32 context.
915
1007
  * - For testing and localhost access, the host's network sandbox is the enforcing boundary.
1008
+ *
1009
+ * **Node.js caveat:** `deny_private` (whatever its value) has no effect on hostname-based
1010
+ * requests under `wasm32`. There is no DNS resolution on this target, so `validate_url`
1011
+ * only ever checks a literal IP host; a domain name falls straight through to `Ok(())`. In a
1012
+ * browser this is covered by same-origin/CORS. Node's `fetch` enforces no CORS, so a Node
1013
+ * service embedding this wasm module can be driven to internal hosts by domain name even
1014
+ * though `deny_private = true`. Do not rely on this policy to stop that in Node — enforce
1015
+ * egress restrictions (network policy, firewall, proxy allowlist) outside the process.
916
1016
  */
917
1017
  static fromEnv(): WasmSsrfPolicy;
918
- constructor(denyPrivate?: boolean | null, maxRedirects?: number | null);
1018
+ constructor(denyPrivate?: boolean | null, allowlist?: any | null, maxRedirects?: number | null);
1019
+ allowlist: any;
919
1020
  denyPrivate: boolean;
920
1021
  maxRedirects: number;
921
1022
  }
@@ -5,5 +5,5 @@ import { __wbg_set_wasm } from "./crawlberg_wasm_bg.js";
5
5
  __wbg_set_wasm(wasm);
6
6
  wasm.__wbindgen_start();
7
7
  export {
8
- WasmActionResult, WasmArticleMetadata, WasmAssetCategory, WasmAuthConfig, WasmBatchCrawlResult, WasmBatchCrawlResults, WasmBatchScrapeResult, WasmBatchScrapeResults, WasmBrowserBackend, WasmBrowserConfig, WasmBrowserExtras, WasmBrowserMode, WasmBrowserWait, WasmCitationReference, WasmCitationResult, WasmContentConfig, WasmCookieInfo, WasmCrawlConfig, WasmCrawlEngineHandle, WasmCrawlPageResult, WasmCrawlResult, WasmDownloadedAsset, WasmDownloadedDocument, WasmExtractionMeta, WasmFaviconInfo, WasmFeedInfo, WasmFeedType, WasmHeadingInfo, WasmHreflangEntry, WasmImageInfo, WasmImageSource, WasmInteractionResult, WasmJsonLdEntry, WasmLinkInfo, WasmLinkType, WasmMapResult, WasmMarkdownResult, WasmPageAction, WasmPageMetadata, WasmProxyConfig, WasmResponseMeta, WasmScrapeResult, WasmScrollDirection, WasmSitemapUrl, WasmSsrfPolicy, batchCrawl, batchScrape, crawl, createEngine, generateCitations, interact, mapUrls, scrape
8
+ WasmActionResult, WasmArticleMetadata, WasmAssetCategory, WasmAuthConfig, WasmBatchCrawlResult, WasmBatchCrawlResults, WasmBatchScrapeResult, WasmBatchScrapeResults, WasmBrowserBackend, WasmBrowserConfig, WasmBrowserExtras, WasmBrowserMode, WasmBrowserWait, WasmCitationReference, WasmCitationResult, WasmContentConfig, WasmContentFilterKind, WasmCookieInfo, WasmCrawlConfig, WasmCrawlEngineHandle, WasmCrawlPageResult, WasmCrawlResult, WasmCrawlStrategyKind, WasmDocumentContentEncoding, WasmDownloadedAsset, WasmDownloadedDocument, WasmExtractionMeta, WasmFaviconInfo, WasmFeedInfo, WasmFeedType, WasmHeadingInfo, WasmHostMatcher, WasmHreflangEntry, WasmImageInfo, WasmImageSource, WasmInteractionResult, WasmJsonLdEntry, WasmLinkInfo, WasmLinkType, WasmMapResult, WasmMarkdownResult, WasmPageAction, WasmPageMetadata, WasmProxyConfig, WasmResponseMeta, WasmScrapeResult, WasmScrollDirection, WasmSitemapUrl, WasmSsrfPolicy, batchCrawl, batchScrape, crawl, createEngine, generateCitations, interact, mapUrls, scrape
9
9
  } from "./crawlberg_wasm_bg.js";