jumpy-lion 0.1.6-beta.7 → 1.0.0-beta.0
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/README.md +1 -607
- package/browser/fonts/macos-bundle/40-macos-aliases.conf +515 -0
- package/browser/fonts/macos-bundle/README.md +24 -0
- package/browser/fonts/macos-bundle/install.sh +83 -0
- package/dist/browser-controller.d.ts +47 -4
- package/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +219 -278
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +82 -110
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +376 -379
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/align-fingerprint-config.d.ts +36 -0
- package/dist/browser-process/align-fingerprint-config.d.ts.map +1 -0
- package/dist/browser-process/align-fingerprint-config.js +74 -0
- package/dist/browser-process/align-fingerprint-config.js.map +1 -0
- package/dist/browser-process/anti-detect-browser.d.ts +2 -2
- package/dist/browser-process/anti-detect-browser.js +7 -7
- package/dist/browser-process/anti-detect-config.d.ts +131 -2
- package/dist/browser-process/anti-detect-config.d.ts.map +1 -1
- package/dist/browser-process/anti-detect-config.js +337 -127
- package/dist/browser-process/anti-detect-config.js.map +1 -1
- package/dist/browser-process/browser.d.ts +25 -92
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +429 -73
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/browser-process/fingerprint-config.d.ts +146 -0
- package/dist/browser-process/fingerprint-config.d.ts.map +1 -0
- package/dist/browser-process/fingerprint-config.js +308 -0
- package/dist/browser-process/fingerprint-config.js.map +1 -0
- package/dist/browser-process/get-chrome-executable.d.ts +6 -0
- package/dist/browser-process/get-chrome-executable.d.ts.map +1 -1
- package/dist/browser-process/get-chrome-executable.js +79 -4
- package/dist/browser-process/get-chrome-executable.js.map +1 -1
- package/dist/browser-process/gpu-family-profiles.d.ts +58 -0
- package/dist/browser-process/gpu-family-profiles.d.ts.map +1 -0
- package/dist/browser-process/gpu-family-profiles.js +480 -0
- package/dist/browser-process/gpu-family-profiles.js.map +1 -0
- package/dist/browser-process/launch-options.d.ts +301 -0
- package/dist/browser-process/launch-options.d.ts.map +1 -0
- package/dist/browser-process/launch-options.js +2 -0
- package/dist/browser-process/launch-options.js.map +1 -0
- package/dist/browser-process/port-allocator.d.ts +64 -0
- package/dist/browser-process/port-allocator.d.ts.map +1 -0
- package/dist/browser-process/port-allocator.js +198 -0
- package/dist/browser-process/port-allocator.js.map +1 -0
- package/dist/browser-process/process.d.ts +85 -0
- package/dist/browser-process/process.d.ts.map +1 -1
- package/dist/browser-process/process.js +235 -19
- package/dist/browser-process/process.js.map +1 -1
- package/dist/browser-process/signal-cleanup.d.ts +40 -0
- package/dist/browser-process/signal-cleanup.d.ts.map +1 -0
- package/dist/browser-process/signal-cleanup.js +105 -0
- package/dist/browser-process/signal-cleanup.js.map +1 -0
- package/dist/browser-process/widevine-cdm.d.ts +144 -0
- package/dist/browser-process/widevine-cdm.d.ts.map +1 -0
- package/dist/browser-process/widevine-cdm.js +298 -0
- package/dist/browser-process/widevine-cdm.js.map +1 -0
- package/dist/browser-profiles/chrome/populate-profile.d.ts.map +1 -1
- package/dist/browser-profiles/chrome/populate-profile.js +21 -22
- package/dist/browser-profiles/chrome/populate-profile.js.map +1 -1
- package/dist/connection/cdp-reconnection.d.ts +50 -0
- package/dist/connection/cdp-reconnection.d.ts.map +1 -0
- package/dist/connection/cdp-reconnection.js +75 -0
- package/dist/connection/cdp-reconnection.js.map +1 -0
- package/dist/connection/page-session.d.ts +114 -0
- package/dist/connection/page-session.d.ts.map +1 -0
- package/dist/connection/page-session.js +237 -0
- package/dist/connection/page-session.js.map +1 -0
- package/dist/connection/session-client.d.ts +34 -0
- package/dist/connection/session-client.d.ts.map +1 -0
- package/dist/connection/session-client.js +129 -0
- package/dist/connection/session-client.js.map +1 -0
- package/dist/crawler.d.ts +9 -88
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js +157 -8
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.d.ts +24 -114
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +305 -611
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +16 -14
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +6 -2
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js +6 -2
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.d.ts +18 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.js +136 -0
- package/dist/fingerprinting/fingerprint-overrides/navigator-override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/override.d.ts +151 -0
- package/dist/fingerprinting/fingerprint-overrides/override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/override.js +14 -0
- package/dist/fingerprinting/fingerprint-overrides/override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +46 -15
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/registry.d.ts +43 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.js +342 -0
- package/dist/fingerprinting/fingerprint-overrides/registry.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.d.ts +16 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.js +175 -0
- package/dist/fingerprinting/fingerprint-overrides/screen-override.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js +4 -4
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +75 -9
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +34 -20
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +25 -6
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +1 -1
- package/dist/fingerprinting/hardware-realism.d.ts +83 -0
- package/dist/fingerprinting/hardware-realism.d.ts.map +1 -0
- package/dist/fingerprinting/hardware-realism.js +156 -0
- package/dist/fingerprinting/hardware-realism.js.map +1 -0
- package/dist/fingerprinting/injection-planner.d.ts +133 -0
- package/dist/fingerprinting/injection-planner.d.ts.map +1 -0
- package/dist/fingerprinting/injection-planner.js +497 -0
- package/dist/fingerprinting/injection-planner.js.map +1 -0
- package/dist/fingerprinting/locale-resolver.d.ts +8 -1
- package/dist/fingerprinting/locale-resolver.d.ts.map +1 -1
- package/dist/fingerprinting/locale-resolver.js +26 -3
- package/dist/fingerprinting/locale-resolver.js.map +1 -1
- package/dist/fingerprinting/non-apify-fingerprint-generator.d.ts +4 -4
- package/dist/fingerprinting/non-apify-fingerprint-generator.d.ts.map +1 -1
- package/dist/fingerprinting/non-apify-fingerprint-generator.js +24 -58
- package/dist/fingerprinting/non-apify-fingerprint-generator.js.map +1 -1
- package/dist/fingerprinting/non-apify-profiles.json +10515 -8494
- package/dist/fingerprinting/os-consistency.d.ts +28 -0
- package/dist/fingerprinting/os-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/os-consistency.js +45 -0
- package/dist/fingerprinting/os-consistency.js.map +1 -0
- package/dist/fingerprinting/profile-quality.d.ts +25 -0
- package/dist/fingerprinting/profile-quality.d.ts.map +1 -0
- package/dist/fingerprinting/profile-quality.js +310 -0
- package/dist/fingerprinting/profile-quality.js.map +1 -0
- package/dist/fingerprinting/profile-selector.d.ts +102 -0
- package/dist/fingerprinting/profile-selector.d.ts.map +1 -0
- package/dist/fingerprinting/profile-selector.js +168 -0
- package/dist/fingerprinting/profile-selector.js.map +1 -0
- package/dist/fingerprinting/ua-alignment.d.ts +83 -0
- package/dist/fingerprinting/ua-alignment.d.ts.map +1 -0
- package/dist/fingerprinting/ua-alignment.js +197 -0
- package/dist/fingerprinting/ua-alignment.js.map +1 -0
- package/dist/fingerprinting/ua-ch-brands.d.ts +88 -0
- package/dist/fingerprinting/ua-ch-brands.d.ts.map +1 -0
- package/dist/fingerprinting/ua-ch-brands.js +174 -0
- package/dist/fingerprinting/ua-ch-brands.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/input/dropdown-selector.d.ts +90 -0
- package/dist/input/dropdown-selector.d.ts.map +1 -0
- package/dist/input/dropdown-selector.js +394 -0
- package/dist/input/dropdown-selector.js.map +1 -0
- package/dist/input/element-target.d.ts +152 -0
- package/dist/input/element-target.d.ts.map +1 -0
- package/dist/input/element-target.js +461 -0
- package/dist/input/element-target.js.map +1 -0
- package/dist/input/input-emulator.d.ts +85 -0
- package/dist/input/input-emulator.d.ts.map +1 -0
- package/dist/input/input-emulator.js +325 -0
- package/dist/input/input-emulator.js.map +1 -0
- package/dist/input/input-transport.d.ts +60 -0
- package/dist/input/input-transport.d.ts.map +1 -0
- package/dist/input/input-transport.js +28 -0
- package/dist/input/input-transport.js.map +1 -0
- package/dist/input/recording-transport.d.ts +32 -0
- package/dist/input/recording-transport.d.ts.map +1 -0
- package/dist/input/recording-transport.js +43 -0
- package/dist/input/recording-transport.js.map +1 -0
- package/dist/keyboard-layout.d.ts +2 -2
- package/dist/keyboard-layout.js +2 -2
- package/dist/navigation/page-navigation.d.ts +67 -0
- package/dist/navigation/page-navigation.d.ts.map +1 -0
- package/dist/navigation/page-navigation.js +122 -0
- package/dist/navigation/page-navigation.js.map +1 -0
- package/dist/network/network-watch.d.ts +110 -0
- package/dist/network/network-watch.d.ts.map +1 -0
- package/dist/network/network-watch.js +223 -0
- package/dist/network/network-watch.js.map +1 -0
- package/dist/page.d.ts +118 -104
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +311 -1130
- package/dist/page.js.map +1 -1
- package/dist/session/inject-hook.d.ts +24 -0
- package/dist/session/inject-hook.d.ts.map +1 -0
- package/dist/session/inject-hook.js +80 -0
- package/dist/session/inject-hook.js.map +1 -0
- package/dist/session/save.d.ts +21 -0
- package/dist/session/save.d.ts.map +1 -0
- package/dist/session/save.js +163 -0
- package/dist/session/save.js.map +1 -0
- package/dist/session/tar-data-dir.d.ts +18 -0
- package/dist/session/tar-data-dir.d.ts.map +1 -0
- package/dist/session/tar-data-dir.js +105 -0
- package/dist/session/tar-data-dir.js.map +1 -0
- package/dist/session/types.d.ts +80 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +29 -0
- package/dist/session/types.js.map +1 -0
- package/dist/session-profile.d.ts +102 -0
- package/dist/session-profile.d.ts.map +1 -0
- package/dist/session-profile.js +163 -0
- package/dist/session-profile.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +17 -6
- package/scripts/postinstall.cjs +58 -0
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts +0 -87
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts.map +0 -1
- package/dist/fingerprinting/custom-fingerprint-injector.js +0 -342
- package/dist/fingerprinting/custom-fingerprint-injector.js.map +0 -1
- package/dist/launcher-wrap.d.ts +0 -10
- package/dist/launcher-wrap.d.ts.map +0 -1
- package/dist/launcher-wrap.js +0 -11
- package/dist/launcher-wrap.js.map +0 -1
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import type { FingerprintConfigJson } from './anti-detect-config.js';
|
|
2
|
+
import type { ResolvedLocale } from '../fingerprinting/locale-resolver.js';
|
|
3
|
+
/**
|
|
4
|
+
* Fingerprint-GENERATION inputs - mirrors the subset of Crawlee's
|
|
5
|
+
* `browserPoolOptions.fingerprintOptions.fingerprintGeneratorOptions`
|
|
6
|
+
* (from `fingerprint-generator`) that cdp-crawler forwards. This selects
|
|
7
|
+
* *which* fingerprint identity to synthesize; it is a wholly separate concept
|
|
8
|
+
* from `FingerprintOptions` below (which spoof surfaces to enforce and how).
|
|
9
|
+
* See issue #80 - the two must not be conflated.
|
|
10
|
+
*/
|
|
11
|
+
export interface FingerprintGeneratorOptions {
|
|
12
|
+
/** Operating systems to generate fingerprints for (e.g., ["windows"], ["macos"], ["linux"]) */
|
|
13
|
+
operatingSystems?: string[];
|
|
14
|
+
/** Devices to generate fingerprints for (e.g., ["desktop"], ["mobile"]) */
|
|
15
|
+
devices?: string[];
|
|
16
|
+
/** Browsers to generate fingerprints for (e.g., ["chrome"], ["firefox"]) */
|
|
17
|
+
browsers?: string[];
|
|
18
|
+
/** Locales to generate fingerprints for (e.g., ["en-US"], ["it-IT"]) */
|
|
19
|
+
locales?: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Humanization options for simulating realistic user behavior.
|
|
23
|
+
* All options are disabled by default for performance.
|
|
24
|
+
*/
|
|
25
|
+
export interface HumanizationOptions {
|
|
26
|
+
/** Enable mouse movement humanization. Default: false */
|
|
27
|
+
mouse?: boolean;
|
|
28
|
+
/** Enable keyboard humanization. Default: false */
|
|
29
|
+
keyboard?: boolean;
|
|
30
|
+
/** Enable scroll humanization. Default: false */
|
|
31
|
+
scroll?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Fingerprint-spoofing options shared by the JS override pipeline
|
|
35
|
+
* (CdpFingerprintInjector) and the native-stealth (C++) launch path.
|
|
36
|
+
*/
|
|
37
|
+
export interface FingerprintOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Legacy nested location for the top-level `useNativeStealth` flag.
|
|
40
|
+
* Normalized to `launchOptions.useNativeStealth` by resolveUseNativeStealth()
|
|
41
|
+
* in session-profile.ts before launch; prefer the top-level field.
|
|
42
|
+
*/
|
|
43
|
+
useNativeStealth?: boolean;
|
|
44
|
+
enableAdvancedStealth?: boolean;
|
|
45
|
+
bypassRuntimeEnable?: boolean;
|
|
46
|
+
spoofWebGL?: boolean;
|
|
47
|
+
spoofAudioContext?: boolean;
|
|
48
|
+
spoofClientRects?: boolean;
|
|
49
|
+
maskAutomationFlags?: boolean;
|
|
50
|
+
useFingerprintDefaults?: boolean;
|
|
51
|
+
platform?: 'Win32' | 'MacIntel' | 'Linux x86_64';
|
|
52
|
+
spoofFonts?: boolean;
|
|
53
|
+
spoofPerformance?: boolean;
|
|
54
|
+
spoofLocale?: boolean;
|
|
55
|
+
detectTimezone?: boolean;
|
|
56
|
+
useExperimentalFingerprints?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* BCP-47 locale tag (e.g. 'ko-KR', 'de-DE'). One flag that coherently drives
|
|
59
|
+
* navigator.language(s), Accept-Language header, Intl defaults, currency
|
|
60
|
+
* symbol, date/number formatting, and timezone (derived from region).
|
|
61
|
+
* When unset, falls back to proxy-country lookup → fingerprint language → 'en-US'.
|
|
62
|
+
*/
|
|
63
|
+
locale?: string;
|
|
64
|
+
/** Explicit IANA timezone (e.g. 'Asia/Seoul'). Overrides locale-derived timezone. */
|
|
65
|
+
timezone?: string;
|
|
66
|
+
/** Explicit Accept-Language header (e.g. 'ko-KR,ko;q=0.9'). Overrides locale-derived list. */
|
|
67
|
+
languages?: string;
|
|
68
|
+
bypassCDPDetection?: boolean;
|
|
69
|
+
spoofStorage?: boolean;
|
|
70
|
+
spoofTiming?: boolean;
|
|
71
|
+
enableDataDomeBypass?: boolean;
|
|
72
|
+
/** WebRTC policy inside page scripts. Default: 'spoof'. */
|
|
73
|
+
webRtcPolicy?: 'spoof' | 'disable';
|
|
74
|
+
/** Humanization options (all disabled by default) */
|
|
75
|
+
humanization?: HumanizationOptions;
|
|
76
|
+
/** Enable debug logging in browser console. Default: true for debugging */
|
|
77
|
+
debug?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Use real Chrome device profiles (Camoufox-inspired) instead of the
|
|
80
|
+
* Apify fingerprint-generator statistical model. Profiles are sampled from
|
|
81
|
+
* a bundled database of real devices where every property - navigator,
|
|
82
|
+
* screen, GPU, UA-CH - was measured on the same physical hardware,
|
|
83
|
+
* guaranteeing cross-property consistency. If the `camoufox` Python package
|
|
84
|
+
* is installed and `preferCamoufox` is true, Firefox device-level data is
|
|
85
|
+
* extracted and mapped to Chrome values.
|
|
86
|
+
* Default: false
|
|
87
|
+
*/
|
|
88
|
+
useNonApifyFingerprints?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Explicit fingerprint seed key for tests / A-B harvest comparisons.
|
|
91
|
+
* Production derives the seed from the proxy URL's `session-X` token;
|
|
92
|
+
* this field lets harvest runs on different hosts (Mac vs Linux Docker)
|
|
93
|
+
* hit the SAME bundled profile without needing a fake proxy.
|
|
94
|
+
*/
|
|
95
|
+
seedKey?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Force WebGL to render through the in-process emulated WebGraphics
|
|
98
|
+
* Context3DProvider instead of relying on a real GPU. Default: false.
|
|
99
|
+
*
|
|
100
|
+
* Why this matters on Apify-linux Docker containers:
|
|
101
|
+
* The Docker image has no GPU. The Chromium GPU process therefore
|
|
102
|
+
* crashes during init (vkCreateInstance: no drivers, no compositor
|
|
103
|
+
* adapter, "Exiting GPU process due to errors during initialization"),
|
|
104
|
+
* which transitively kills WebGL context creation in the renderer:
|
|
105
|
+
*
|
|
106
|
+
* [...]ERROR:gpu/command_buffer/.../gles2_cmd_decoder_passthrough.cc:1073]
|
|
107
|
+
* Automatic fallback to software WebGL has been deprecated.
|
|
108
|
+
* Please use the --enable-unsafe-swiftshader flag to opt in to
|
|
109
|
+
* lower security guarantees for trusted content.
|
|
110
|
+
*
|
|
111
|
+
* Chrome ≥126 removed the implicit fall-back-to-SwiftShader behaviour
|
|
112
|
+
* that used to mask a missing GPU. Without an explicit switch,
|
|
113
|
+
* `canvas.getContext('webgl')` returns null on a GPU-less container.
|
|
114
|
+
* Real Chrome on a real desktop ALWAYS exposes WebGL, so a missing
|
|
115
|
+
* WebGL context is itself a strong bot tell.
|
|
116
|
+
*
|
|
117
|
+
* What setting this to true does:
|
|
118
|
+
* Pushes the anti-detect binary's bespoke `--force-webgl-emulation`
|
|
119
|
+
* Chromium command-line switch. The switch is declared in
|
|
120
|
+
* chrome/common/chrome_switches.{h,cc} and propagated to renderer/
|
|
121
|
+
* GPU child processes via the kCommonSwitchNames list in
|
|
122
|
+
* chrome/browser/chrome_content_browser_client.cc. The renderer-side
|
|
123
|
+
* factory hook at third_party/blink/renderer/modules/webgl/
|
|
124
|
+
* webgl_rendering_context_base.cc::CreateContextProviderInternal
|
|
125
|
+
* reads the switch + FingerprintConfig::IsLoaded() and, when both
|
|
126
|
+
* are true, instantiates the in-process
|
|
127
|
+
* EmulatedWebGraphicsContext3DProvider instead of asking the GPU
|
|
128
|
+
* process for a command buffer. The provider returns a non-null
|
|
129
|
+
* WebGLRenderingContext whose getParameter values come from
|
|
130
|
+
* FingerprintConfig (vendor/renderer/max texture size) and a
|
|
131
|
+
* bundled Mac M1 baseline (other queryable params), and whose
|
|
132
|
+
* readPixels output is a deterministic xoshiro256** noise pattern
|
|
133
|
+
* seeded from FingerprintConfig.seed (plus a recorded baseline
|
|
134
|
+
* pixel buffer for known fingerprint probe shaders).
|
|
135
|
+
*
|
|
136
|
+
* The C++ provider ALSO acts as a fallback (without this switch)
|
|
137
|
+
* when the upstream real-GL / SwiftShader path returns null - set
|
|
138
|
+
* this flag to TRUE only when you want to skip real-GL entirely on
|
|
139
|
+
* hosts where it might otherwise succeed but degrade unpredictably
|
|
140
|
+
* (e.g. Apify Linux containers).
|
|
141
|
+
*/
|
|
142
|
+
forceEmulateWebgl?: boolean;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Advanced options for the JS fingerprint-override pipeline (issue #80).
|
|
146
|
+
*
|
|
147
|
+
* These configure the JS injector's per-surface override modules. They belong
|
|
148
|
+
* under `stealth.overrides` when the `js` engine is selected - see
|
|
149
|
+
* {@link StealthOptions}. They are meaningless on the native engine (the C++
|
|
150
|
+
* binary owns every surface), which is why the discriminated union makes them
|
|
151
|
+
* settable ONLY under `engine: 'js'`.
|
|
152
|
+
*
|
|
153
|
+
* Keys are the community-canonical fingerprint-surface names (canvas/webgl/audio/
|
|
154
|
+
* clientRects/fonts/webrtc/… - the vocabulary used by fingerprintjs, CreepJS,
|
|
155
|
+
* puppeteer-extra) rather than ad-hoc `spoofX`/`maskX`/`bypassX` verbs. Each maps
|
|
156
|
+
* 1:1 onto an entry in the internal override registry. All spoof surfaces default
|
|
157
|
+
* to ON (opt-out); `webrtc` defaults to `'spoof'`; `dataDomeBypass` defaults OFF.
|
|
158
|
+
*
|
|
159
|
+
* Identity/locale/routing knobs (`platform`, `locale`, `useNonApifyFingerprints`,
|
|
160
|
+
* …) are intentionally NOT part of this group. The legacy per-surface toggles on
|
|
161
|
+
* `fingerprintOptions` (`spoofWebGL`, `maskAutomationFlags`, …) remain honoured as
|
|
162
|
+
* a deprecated alias.
|
|
163
|
+
*/
|
|
164
|
+
export interface JsOverrideOptions {
|
|
165
|
+
/** Master gate for the advanced spoof set. Default: true. */
|
|
166
|
+
advancedStealth?: boolean;
|
|
167
|
+
/** WebGL `getParameter` / debug-renderer spoofing. Default: true. */
|
|
168
|
+
webgl?: boolean;
|
|
169
|
+
/** AudioContext fingerprint noise. Default: true. */
|
|
170
|
+
audio?: boolean;
|
|
171
|
+
/** `getBoundingClientRect` sub-pixel jitter. Default: true. */
|
|
172
|
+
clientRects?: boolean;
|
|
173
|
+
/** Font-enumeration spoofing. Default: true. */
|
|
174
|
+
fonts?: boolean;
|
|
175
|
+
/** `performance.now` shaping. Default: true. */
|
|
176
|
+
performance?: boolean;
|
|
177
|
+
/** `Intl` / locale formatting consistency. Default: true. */
|
|
178
|
+
locale?: boolean;
|
|
179
|
+
/** Storage-quota consistency. Default: true. */
|
|
180
|
+
storage?: boolean;
|
|
181
|
+
/** `Date.now` alignment. Default: true. */
|
|
182
|
+
timing?: boolean;
|
|
183
|
+
/** CDP-detection bypass (iframe/eval/sourceURL hiding). Default: true. */
|
|
184
|
+
cdpDetection?: boolean;
|
|
185
|
+
/** navigator.webdriver removal + automation-artifact masking. Default: true. */
|
|
186
|
+
automation?: boolean;
|
|
187
|
+
/** WebRTC handling. Default: `'spoof'`. */
|
|
188
|
+
webrtc?: 'spoof' | 'disable';
|
|
189
|
+
/** DataDome-specific bypass (JS challenges, proof-of-work). Default: false. */
|
|
190
|
+
dataDomeBypass?: boolean;
|
|
191
|
+
/** Human-like input behavior (mouse/keyboard/scroll). All off by default. */
|
|
192
|
+
humanization?: HumanizationOptions;
|
|
193
|
+
/**
|
|
194
|
+
* Use the generated fingerprint's values instead of hardcoded defaults for
|
|
195
|
+
* navigator/WebGL/UA-CH. Default: true for synthetic profiles.
|
|
196
|
+
*/
|
|
197
|
+
useFingerprintDefaults?: boolean;
|
|
198
|
+
/** Verbose in-page debug logging. Default: false. */
|
|
199
|
+
debug?: boolean;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The fingerprint-enforcement engine - a mutually-exclusive choice (issue #80).
|
|
203
|
+
*
|
|
204
|
+
* Native stealth (the C++ anti-detect binary) and the JS override pipeline are
|
|
205
|
+
* two engines that cannot both run: under native stealth the JS bundle is
|
|
206
|
+
* skipped entirely, so JS spoof toggles are silently inert. Modelling the choice
|
|
207
|
+
* as a discriminated union makes that exclusivity explicit - `overrides` is only
|
|
208
|
+
* settable under `engine: 'js'`, so it is a *type error* to configure JS spoof
|
|
209
|
+
* toggles while the native engine is selected.
|
|
210
|
+
*
|
|
211
|
+
* Canonical selector for `launchOptions.stealth`. The legacy `useNativeStealth`
|
|
212
|
+
* boolean (+ its nested/root mirrors) and the JS toggles on `fingerprintOptions`
|
|
213
|
+
* are still honoured as deprecated aliases; `stealth` wins when set.
|
|
214
|
+
*/
|
|
215
|
+
export type StealthOptions = {
|
|
216
|
+
/** C++ anti-detect binary owns every fingerprint surface; no JS overrides apply. */
|
|
217
|
+
engine: 'native';
|
|
218
|
+
} | {
|
|
219
|
+
/** JS fingerprint-override injection pipeline (stock Chrome). */
|
|
220
|
+
engine: 'js';
|
|
221
|
+
/** Advanced spoof/humanization toggles - only meaningful on this engine. */
|
|
222
|
+
overrides?: JsOverrideOptions;
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Launch options shared by the plugin layer (CDPBrowserPlugin) and the
|
|
226
|
+
* process layer (browser-process/browser.ts). Each layer extends this with
|
|
227
|
+
* its own fields - the plugin adds Crawlee-facing fields (browserType,
|
|
228
|
+
* proxyUrl, sessionBundle, …); the process layer adds spawn-time fields
|
|
229
|
+
* (anonymizedProxyUrl, debuggingPort, …).
|
|
230
|
+
*/
|
|
231
|
+
export interface BaseLaunchBrowserOptions {
|
|
232
|
+
/**
|
|
233
|
+
* The fingerprint-enforcement engine and its config (issue #80). Selecting
|
|
234
|
+
* `{ engine: 'js', overrides: { … } }` is the canonical, discoverable home
|
|
235
|
+
* for the JS spoof/humanization toggles; `{ engine: 'native' }` selects the
|
|
236
|
+
* C++ binary and makes those toggles a type error. Wins over the deprecated
|
|
237
|
+
* `useNativeStealth` boolean and the JS toggles on `fingerprintOptions`.
|
|
238
|
+
*/
|
|
239
|
+
stealth?: StealthOptions;
|
|
240
|
+
ignoreHttpsErrors?: boolean;
|
|
241
|
+
headless?: boolean;
|
|
242
|
+
executablePath?: string;
|
|
243
|
+
useExperimentalFingerprints?: boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Use the C++ anti-detect browser patches (Cromite-based custom binary)
|
|
246
|
+
* instead of the JS fingerprint override pipeline. When true, the plugin
|
|
247
|
+
* auto-resolves the binary installed by postinstall.js unless an explicit
|
|
248
|
+
* `executablePath` (or ANTI_DETECT_CHROME_PATH) pins one, and the entire
|
|
249
|
+
* JS injection bundle is skipped - C++ patches handle all fingerprinting.
|
|
250
|
+
* If the binary is not an anti-detect build, the process layer falls back
|
|
251
|
+
* to plain stealth args for system Chrome.
|
|
252
|
+
* Default: false
|
|
253
|
+
*/
|
|
254
|
+
useNativeStealth?: boolean;
|
|
255
|
+
/** Whether to start the browser maximized and fullscreen. Default: true */
|
|
256
|
+
maximizeWindow?: boolean;
|
|
257
|
+
/** Window width in pixels. Default: 1920 */
|
|
258
|
+
windowWidth?: number;
|
|
259
|
+
/** Window height in pixels. Default: 1080 */
|
|
260
|
+
windowHeight?: number;
|
|
261
|
+
/**
|
|
262
|
+
* Reuse a specific Chrome user data directory across runs.
|
|
263
|
+
* When provided, this directory is preserved by default.
|
|
264
|
+
*/
|
|
265
|
+
userDataDir?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Force keeping or cleaning the profile directory on close.
|
|
268
|
+
* Defaults to true for temporary profiles and false for custom userDataDir.
|
|
269
|
+
*/
|
|
270
|
+
keepUserDataDir?: boolean;
|
|
271
|
+
/**
|
|
272
|
+
* DNS-over-HTTPS endpoint template, for example:
|
|
273
|
+
* https://cloudflare-dns.com/dns-query
|
|
274
|
+
*/
|
|
275
|
+
dnsOverHttpsServer?: string;
|
|
276
|
+
/** Chromium secure DNS mode. Default: 'secure' when dnsOverHttpsServer is set. */
|
|
277
|
+
secureDnsMode?: 'off' | 'automatic' | 'secure';
|
|
278
|
+
/**
|
|
279
|
+
* WebRTC IP handling policy. Recommended stealth value:
|
|
280
|
+
* disable_non_proxied_udp
|
|
281
|
+
*/
|
|
282
|
+
webrtcIpHandlingPolicy?: 'default' | 'default_public_interface_only' | 'default_public_and_private_interfaces' | 'disable_non_proxied_udp';
|
|
283
|
+
fingerprintOptions?: FingerprintOptions;
|
|
284
|
+
/**
|
|
285
|
+
* Pre-generated platform-overrides JSON to pass via --blink-platform-overrides-file
|
|
286
|
+
* to the anti-detect browser. When provided, this overrides the static
|
|
287
|
+
* default_fingerprint.json so that each browser instance gets unique C++-level
|
|
288
|
+
* platform values (GPU, screen, CPU count, device memory) derived from the real
|
|
289
|
+
* device profile.
|
|
290
|
+
*/
|
|
291
|
+
fingerprintConfig?: FingerprintConfigJson;
|
|
292
|
+
/**
|
|
293
|
+
* Pre-resolved locale triple from `resolveLocale()`. Populated in browser-plugin
|
|
294
|
+
* before launch so the native-stealth launch args (`--lang`,
|
|
295
|
+
* `--fingerprint-accept-language`, LANG/LC_ALL env vars) and the CDP-path
|
|
296
|
+
* injector read the same values and stay coherent. Consumers should prefer
|
|
297
|
+
* this over re-deriving from fingerprintOptions.
|
|
298
|
+
*/
|
|
299
|
+
resolvedLocale?: ResolvedLocale;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=launch-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-options.d.ts","sourceRoot":"","sources":["../../src/browser-process/launch-options.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-options.js","sourceRoot":"","sources":["../../src/browser-process/launch-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PortAllocator - owns the Chrome debugging-port pool.
|
|
3
|
+
*
|
|
4
|
+
* Interface is two methods: `acquire()` / `release(port)`. The implementation
|
|
5
|
+
* owns the range, acquisition serialization, the wraparound scan, the
|
|
6
|
+
* probe-busy quarantine, and the stale-port sweep. The OS socket probe sits
|
|
7
|
+
* behind the narrow `PortProbe` seam: real socket adapter in production,
|
|
8
|
+
* scripted adapter in tests.
|
|
9
|
+
*/
|
|
10
|
+
export interface PortProbe {
|
|
11
|
+
/** True when the port can be bound on 127.0.0.1 right now. */
|
|
12
|
+
isFree(port: number): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Production adapter: try to bind a throwaway server on 127.0.0.1.
|
|
16
|
+
* Resolves false on bind error or after a 2 s safety timeout.
|
|
17
|
+
*/
|
|
18
|
+
export declare const socketPortProbe: PortProbe;
|
|
19
|
+
export interface PortAllocatorOptions {
|
|
20
|
+
min?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
probe?: PortProbe;
|
|
23
|
+
/** How long a probe-busy port stays quarantined before it may be retried. */
|
|
24
|
+
quarantineMs?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Grace period after `acquire()` during which the stale sweep will NOT
|
|
27
|
+
* reclaim a reserved port, even though the probe reports it free. Covers the
|
|
28
|
+
* window between handing a port out and Chrome actually binding it.
|
|
29
|
+
*/
|
|
30
|
+
launchGraceMs?: number;
|
|
31
|
+
/** Injectable clock (tests drive it); defaults to `Date.now`. */
|
|
32
|
+
now?: () => number;
|
|
33
|
+
}
|
|
34
|
+
export declare class PortAllocator {
|
|
35
|
+
private readonly min;
|
|
36
|
+
private readonly max;
|
|
37
|
+
private readonly probe;
|
|
38
|
+
private readonly quarantineMs;
|
|
39
|
+
private readonly launchGraceMs;
|
|
40
|
+
private readonly now;
|
|
41
|
+
private readonly usedPorts;
|
|
42
|
+
private lastAssignedPort;
|
|
43
|
+
/** Serializes acquire() calls - concurrent launches never race the scan. */
|
|
44
|
+
private acquireChain;
|
|
45
|
+
constructor(options?: PortAllocatorOptions);
|
|
46
|
+
acquire(): Promise<number>;
|
|
47
|
+
release(port: number): void;
|
|
48
|
+
private _acquireSerialized;
|
|
49
|
+
/**
|
|
50
|
+
* Drop tracked ports whose owner has since exited (probe binds OK).
|
|
51
|
+
* A crash path that never called release() would otherwise leak the slot
|
|
52
|
+
* forever.
|
|
53
|
+
*
|
|
54
|
+
* Reserved ports are protected for `launchGraceMs` after acquisition: a
|
|
55
|
+
* port is handed out BEFORE Chrome starts, so between `acquire()` and the
|
|
56
|
+
* browser binding its debug socket the probe legitimately reports the port
|
|
57
|
+
* free. Sweeping there un-tracked a port whose browser was still launching
|
|
58
|
+
* and handed the same port to a second browser - one of the two then failed
|
|
59
|
+
* to bind. Quarantine entries carry no such window (they were never ours),
|
|
60
|
+
* so they stay immediately reclaimable.
|
|
61
|
+
*/
|
|
62
|
+
private _sweepStalePorts;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=port-allocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-allocator.d.ts","sourceRoot":"","sources":["../../src/browser-process/port-allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,SAAS;IACtB,8DAA8D;IAC9D,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,SA+B7B,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAcD,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IAEnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,gBAAgB,CAAS;IACjC,4EAA4E;IAC5E,OAAO,CAAC,YAAY,CAAuC;gBAE/C,OAAO,GAAE,oBAAyB;IAUxC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAShC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;YAWb,kBAAkB;IAgDhC;;;;;;;;;;;;OAYG;YACW,gBAAgB;CAcjC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PortAllocator - owns the Chrome debugging-port pool.
|
|
3
|
+
*
|
|
4
|
+
* Interface is two methods: `acquire()` / `release(port)`. The implementation
|
|
5
|
+
* owns the range, acquisition serialization, the wraparound scan, the
|
|
6
|
+
* probe-busy quarantine, and the stale-port sweep. The OS socket probe sits
|
|
7
|
+
* behind the narrow `PortProbe` seam: real socket adapter in production,
|
|
8
|
+
* scripted adapter in tests.
|
|
9
|
+
*/
|
|
10
|
+
import net from 'node:net';
|
|
11
|
+
import { log } from 'crawlee';
|
|
12
|
+
/**
|
|
13
|
+
* Production adapter: try to bind a throwaway server on 127.0.0.1.
|
|
14
|
+
* Resolves false on bind error or after a 2 s safety timeout.
|
|
15
|
+
*/
|
|
16
|
+
export const socketPortProbe = {
|
|
17
|
+
async isFree(port) {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const server = net.createServer();
|
|
20
|
+
let resolved = false;
|
|
21
|
+
const finish = (result) => {
|
|
22
|
+
if (resolved)
|
|
23
|
+
return;
|
|
24
|
+
resolved = true;
|
|
25
|
+
try {
|
|
26
|
+
server.close();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Ignore errors during cleanup
|
|
30
|
+
}
|
|
31
|
+
resolve(result);
|
|
32
|
+
};
|
|
33
|
+
server.once('error', () => finish(false));
|
|
34
|
+
server.once('listening', () => finish(true));
|
|
35
|
+
// Safety timeout to prevent hanging
|
|
36
|
+
const timer = setTimeout(() => finish(false), 2000);
|
|
37
|
+
timer.unref?.();
|
|
38
|
+
try {
|
|
39
|
+
server.listen(port, '127.0.0.1');
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
finish(false);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export class PortAllocator {
|
|
48
|
+
constructor(options = {}) {
|
|
49
|
+
Object.defineProperty(this, "min", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
writable: true,
|
|
53
|
+
value: void 0
|
|
54
|
+
});
|
|
55
|
+
Object.defineProperty(this, "max", {
|
|
56
|
+
enumerable: true,
|
|
57
|
+
configurable: true,
|
|
58
|
+
writable: true,
|
|
59
|
+
value: void 0
|
|
60
|
+
});
|
|
61
|
+
Object.defineProperty(this, "probe", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
configurable: true,
|
|
64
|
+
writable: true,
|
|
65
|
+
value: void 0
|
|
66
|
+
});
|
|
67
|
+
Object.defineProperty(this, "quarantineMs", {
|
|
68
|
+
enumerable: true,
|
|
69
|
+
configurable: true,
|
|
70
|
+
writable: true,
|
|
71
|
+
value: void 0
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(this, "launchGraceMs", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
configurable: true,
|
|
76
|
+
writable: true,
|
|
77
|
+
value: void 0
|
|
78
|
+
});
|
|
79
|
+
Object.defineProperty(this, "now", {
|
|
80
|
+
enumerable: true,
|
|
81
|
+
configurable: true,
|
|
82
|
+
writable: true,
|
|
83
|
+
value: void 0
|
|
84
|
+
});
|
|
85
|
+
Object.defineProperty(this, "usedPorts", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
configurable: true,
|
|
88
|
+
writable: true,
|
|
89
|
+
value: new Map()
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(this, "lastAssignedPort", {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
configurable: true,
|
|
94
|
+
writable: true,
|
|
95
|
+
value: void 0
|
|
96
|
+
});
|
|
97
|
+
/** Serializes acquire() calls - concurrent launches never race the scan. */
|
|
98
|
+
Object.defineProperty(this, "acquireChain", {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
value: Promise.resolve()
|
|
103
|
+
});
|
|
104
|
+
this.min = options.min ?? 9200;
|
|
105
|
+
this.max = options.max ?? 9600;
|
|
106
|
+
this.probe = options.probe ?? socketPortProbe;
|
|
107
|
+
this.quarantineMs = options.quarantineMs ?? 5000;
|
|
108
|
+
this.launchGraceMs = options.launchGraceMs ?? 15000;
|
|
109
|
+
this.now = options.now ?? Date.now;
|
|
110
|
+
this.lastAssignedPort = this.min - 1;
|
|
111
|
+
}
|
|
112
|
+
async acquire() {
|
|
113
|
+
// Chain onto the previous acquire so the scan below never interleaves
|
|
114
|
+
// with another caller's - the replacement for the old static spin-lock.
|
|
115
|
+
const result = this.acquireChain.then(async () => this._acquireSerialized());
|
|
116
|
+
// Keep the chain alive even when an acquire rejects (pool exhausted).
|
|
117
|
+
this.acquireChain = result.catch(() => { });
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
release(port) {
|
|
121
|
+
// Idempotent: the browser close/error/disconnect handlers can all fire
|
|
122
|
+
// for one instance.
|
|
123
|
+
if (this.usedPorts.has(port)) {
|
|
124
|
+
this.usedPorts.delete(port);
|
|
125
|
+
log.debug(`Released port ${port} back to pool. Used ports: ${this.usedPorts.size}/${this.max - this.min + 1}`);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
log.debug(`Attempted to release port ${port} that was not in use`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async _acquireSerialized() {
|
|
132
|
+
const maxAttempts = this.max - this.min + 1;
|
|
133
|
+
for (let attempts = 0; attempts < maxAttempts; attempts++) {
|
|
134
|
+
// Increment the last assigned port, wrapping around if necessary
|
|
135
|
+
this.lastAssignedPort++;
|
|
136
|
+
if (this.lastAssignedPort > this.max) {
|
|
137
|
+
this.lastAssignedPort = this.min;
|
|
138
|
+
log.debug('Port range wrapped around, starting from beginning');
|
|
139
|
+
}
|
|
140
|
+
const candidatePort = this.lastAssignedPort;
|
|
141
|
+
// Skip if port is already tracked as in use
|
|
142
|
+
if (this.usedPorts.has(candidatePort)) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (await this.probe.isFree(candidatePort)) {
|
|
146
|
+
this.usedPorts.set(candidatePort, { at: this.now(), quarantined: false });
|
|
147
|
+
log.debug(`Reserved port ${candidatePort} for browser instance (attempt ${attempts + 1})`);
|
|
148
|
+
return candidatePort;
|
|
149
|
+
}
|
|
150
|
+
// Probe says busy (something outside the pool holds it) -
|
|
151
|
+
// quarantine so the scan doesn't retry it immediately.
|
|
152
|
+
this.usedPorts.set(candidatePort, { at: this.now(), quarantined: true });
|
|
153
|
+
const timer = setTimeout(() => {
|
|
154
|
+
this.usedPorts.delete(candidatePort);
|
|
155
|
+
}, this.quarantineMs);
|
|
156
|
+
timer.unref?.();
|
|
157
|
+
}
|
|
158
|
+
// Every port is tracked or probe-busy: sweep stale entries and rescan.
|
|
159
|
+
log.warning(`All ports in range ${this.min}-${this.max} are in use. Attempting cleanup.`);
|
|
160
|
+
await this._sweepStalePorts();
|
|
161
|
+
for (let port = this.min; port <= this.max; port++) {
|
|
162
|
+
if (!this.usedPorts.has(port) && await this.probe.isFree(port)) {
|
|
163
|
+
this.usedPorts.set(port, { at: this.now(), quarantined: false });
|
|
164
|
+
log.debug(`Reserved port ${port} after cleanup`);
|
|
165
|
+
return port;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
throw new Error(`No available ports found in the configured range ${this.min}-${this.max} after maximum attempts and cleanup`);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Drop tracked ports whose owner has since exited (probe binds OK).
|
|
172
|
+
* A crash path that never called release() would otherwise leak the slot
|
|
173
|
+
* forever.
|
|
174
|
+
*
|
|
175
|
+
* Reserved ports are protected for `launchGraceMs` after acquisition: a
|
|
176
|
+
* port is handed out BEFORE Chrome starts, so between `acquire()` and the
|
|
177
|
+
* browser binding its debug socket the probe legitimately reports the port
|
|
178
|
+
* free. Sweeping there un-tracked a port whose browser was still launching
|
|
179
|
+
* and handed the same port to a second browser - one of the two then failed
|
|
180
|
+
* to bind. Quarantine entries carry no such window (they were never ours),
|
|
181
|
+
* so they stay immediately reclaimable.
|
|
182
|
+
*/
|
|
183
|
+
async _sweepStalePorts() {
|
|
184
|
+
log.debug('Cleaning up stale ports');
|
|
185
|
+
const now = this.now();
|
|
186
|
+
for (const [port, lease] of Array.from(this.usedPorts)) {
|
|
187
|
+
if (!lease.quarantined && now - lease.at < this.launchGraceMs) {
|
|
188
|
+
log.debug(`Skipping port ${port} - still inside the ${this.launchGraceMs}ms launch grace window`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (await this.probe.isFree(port)) {
|
|
192
|
+
this.usedPorts.delete(port);
|
|
193
|
+
log.debug(`Cleaned up stale port ${port}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=port-allocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port-allocator.js","sourceRoot":"","sources":["../../src/browser-process/port-allocator.ts"],"names":[],"mappings":"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"}
|