scrapely 1.2.33 → 1.2.34
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/CHANGELOG.md +7 -0
- package/NOTICE +12 -26
- package/README.md +1 -2
- package/dist/actor.d.ts +32 -25
- package/dist/actor.js +39 -23
- package/dist/charging.d.ts +49 -4
- package/dist/charging.js +293 -44
- package/dist/configuration.js +2 -2
- package/dist/index.js +1 -1
- package/dist/node-wrapper.js +1 -1
- package/dist/patch-browser-pool.js +7 -3
- package/dist/proxy-configuration.d.ts +11 -11
- package/dist/proxy-configuration.js +1 -1
- package/dist/proxy-input-aliases.d.ts +1 -1
- package/dist/proxy-input-aliases.js +1 -1
- package/dist/request-list.d.ts +2 -2
- package/dist/request-list.js +1 -1
- package/dist/scrapely-proxy-configuration.d.ts +15 -16
- package/dist/scrapely-proxy-configuration.js +27 -31
- package/dist/storage/api-storage-client.d.ts +4 -5
- package/dist/storage/api-storage-client.js +17 -15
- package/dist/storage/billing-tracker.d.ts +1 -1
- package/dist/storage/billing-tracker.js +1 -1
- package/dist/storage/key-value-store-client.d.ts +0 -3
- package/dist/storage/key-value-store-client.js +2 -5
- package/dist/storage/kv-store-collection-client.js +6 -2
- package/dist/storage/kvs-iteration.d.ts +1 -1
- package/dist/storage/kvs-iteration.js +1 -1
- package/dist/storage/request-queue-client.d.ts +1 -1
- package/dist/storage/request-queue-client.js +5 -5
- package/dist/storage/rq-lock-script.d.ts +2 -2
- package/dist/storage/rq-lock-script.js +2 -2
- package/dist/storage/run-metadata.js +1 -1
- package/dist/storage/ttl-manager.d.ts +7 -6
- package/dist/storage/ttl-manager.js +5 -4
- package/dist/storage-identifiers.d.ts +1 -2
- package/dist/storage-identifiers.js +1 -2
- package/dist/utils.d.ts +41 -8
- package/dist/utils.js +49 -3
- package/package.json +22 -11
package/CHANGELOG.md
ADDED
package/NOTICE
CHANGED
|
@@ -1,26 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- src/actor.ts (from src/actor.ts)
|
|
14
|
-
- src/charging.ts (from src/charging.ts)
|
|
15
|
-
- src/scrapely-proxy-configuration.ts (from src/proxy_configuration.ts)
|
|
16
|
-
|
|
17
|
-
You may obtain a copy of the Apache License at
|
|
18
|
-
|
|
19
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
20
|
-
|
|
21
|
-
This product includes software developed by Apify Technologies s.r.o.
|
|
22
|
-
(https://apify.com/). The original source code is available at
|
|
23
|
-
https://github.com/apify/apify-sdk-js.
|
|
24
|
-
|
|
25
|
-
Scrape.ly is not affiliated with Apify. Apify is a trademark of
|
|
26
|
-
Apify Technologies s.r.o.
|
|
1
|
+
scrapely
|
|
2
|
+
Copyright (c) 2025-2026 TeraShift GmbH (Scrape.ly)
|
|
3
|
+
|
|
4
|
+
Licensed under the ISC License (see LICENSE), except for the files below,
|
|
5
|
+
which are derived from apify-sdk-js (https://github.com/apify/apify-sdk-js),
|
|
6
|
+
Copyright Apify Technologies s.r.o., and remain under the Apache License,
|
|
7
|
+
Version 2.0 (see LICENSE-APACHE). They have been modified by TeraShift GmbH:
|
|
8
|
+
|
|
9
|
+
- src/actor.ts
|
|
10
|
+
- src/charging.ts
|
|
11
|
+
- src/configuration.ts
|
|
12
|
+
- src/scrapely-proxy-configuration.ts
|
package/README.md
CHANGED
|
@@ -62,6 +62,5 @@ On the platform, browser crawlers connect to a remote Chromium over CDP instead
|
|
|
62
62
|
|
|
63
63
|
## License
|
|
64
64
|
|
|
65
|
-
ISC (see [LICENSE](./LICENSE)), except for a few files
|
|
66
|
-
[apify-sdk-js](https://github.com/apify/apify-sdk-js), which stay under the Apache License 2.0
|
|
65
|
+
ISC (see [LICENSE](./LICENSE)), except for a few files that stay under the Apache License 2.0
|
|
67
66
|
(see [LICENSE-APACHE](./LICENSE-APACHE) and [NOTICE](./NOTICE)).
|
package/dist/actor.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './log-env.js';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
|
-
/** Actor permission level
|
|
3
|
+
/** Actor permission level. */
|
|
4
4
|
export declare enum ACTOR_PERMISSION_LEVEL {
|
|
5
5
|
/** User has no special permissions */
|
|
6
6
|
NONE = "NONE",
|
|
@@ -44,20 +44,20 @@ import { createProxyConfiguration, type CreateProxyConfigurationOptions } from '
|
|
|
44
44
|
import { type BrowserConfiguration, type BrowserConfigurationOptions } from './browser-configuration.js';
|
|
45
45
|
import { type Clearance, type SolveOptions, type SolverVendorStatus } from './solver.js';
|
|
46
46
|
import type { Dataset, KeyValueStore, RequestQueue } from 'crawlee';
|
|
47
|
-
/** User function passed to {@link Actor.main}
|
|
47
|
+
/** User function passed to {@link Actor.main}. */
|
|
48
48
|
export type UserFunc<T = unknown> = () => T | Promise<T>;
|
|
49
49
|
type Dictionary = Record<string, any>;
|
|
50
|
-
/** Value types returned by {@link Actor.getInput}
|
|
50
|
+
/** Value types returned by {@link Actor.getInput}. */
|
|
51
51
|
export type ActorInput = Dictionary | string | Buffer;
|
|
52
52
|
export interface Token {
|
|
53
53
|
token?: string;
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
55
|
+
/** Run timeout in seconds, or 'inherit' (the time remaining in this run). */
|
|
56
56
|
export interface Timeout {
|
|
57
57
|
timeout?: TimeoutOption;
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
|
-
* Exit codes for the Actor process
|
|
60
|
+
* Exit codes for the Actor process.
|
|
61
61
|
* Must be in the range 1-128 to avoid collision with signal exits.
|
|
62
62
|
*/
|
|
63
63
|
export declare const EXIT_CODES: {
|
|
@@ -161,7 +161,7 @@ export interface WebhookOptions {
|
|
|
161
161
|
doNotRetry?: boolean;
|
|
162
162
|
/** If true, the webhook will interpolate strings in the payloadTemplate and headersTemplate */
|
|
163
163
|
shouldInterpolateStrings?: boolean;
|
|
164
|
-
/** If true, indicates the webhook is
|
|
164
|
+
/** If true, indicates the webhook is a platform integration */
|
|
165
165
|
isApifyIntegration?: boolean;
|
|
166
166
|
}
|
|
167
167
|
/**
|
|
@@ -184,7 +184,7 @@ export interface UseStateOptions {
|
|
|
184
184
|
config?: any;
|
|
185
185
|
}
|
|
186
186
|
/**
|
|
187
|
-
* Options for Actor.openDataset(), openKeyValueStore(), and openRequestQueue()
|
|
187
|
+
* Options for Actor.openDataset(), openKeyValueStore(), and openRequestQueue().
|
|
188
188
|
*/
|
|
189
189
|
export interface OpenStorageOptions {
|
|
190
190
|
/**
|
|
@@ -217,12 +217,11 @@ export interface RebootOptions {
|
|
|
217
217
|
/** @internal */
|
|
218
218
|
customAfterSleepMillis?: number;
|
|
219
219
|
}
|
|
220
|
-
/** Result of a charge operation
|
|
220
|
+
/** Result of a charge operation. */
|
|
221
221
|
export type ChargeResult = ChargingChargeResult;
|
|
222
222
|
/**
|
|
223
223
|
* Parsed representation of the environment variables.
|
|
224
224
|
* This object is returned by the {@apilink Actor.getEnv} function.
|
|
225
|
-
* Fully compatible with Apify's ApifyEnv interface.
|
|
226
225
|
*/
|
|
227
226
|
export interface ApifyEnv {
|
|
228
227
|
/** ID of the Actor (ACTOR_ID) */
|
|
@@ -275,7 +274,7 @@ export interface ApifyEnv {
|
|
|
275
274
|
inputSecretsPrivateKeyFile: string | null;
|
|
276
275
|
/** Input secrets private key passphrase (APIFY_INPUT_SECRETS_PRIVATE_KEY_PASSPHRASE) */
|
|
277
276
|
inputSecretsPrivateKeyPassphrase: string | null;
|
|
278
|
-
/** If set to "1", running on
|
|
277
|
+
/** If set to "1", running on the platform (APIFY_IS_AT_HOME) */
|
|
279
278
|
isAtHome: string | null;
|
|
280
279
|
/** Local storage directory (CRAWLEE_STORAGE_DIR) */
|
|
281
280
|
localStorageDir: string | null;
|
|
@@ -337,10 +336,10 @@ export declare class Actor {
|
|
|
337
336
|
private _apifyClient;
|
|
338
337
|
private readonly chargingManager;
|
|
339
338
|
/**
|
|
340
|
-
* Creates an Actor instance (
|
|
339
|
+
* Creates an Actor instance (alternative to the static helpers).
|
|
341
340
|
*/
|
|
342
341
|
constructor(options?: ConfigurationOptions);
|
|
343
|
-
/** Default ApifyClient instance for this Actor (
|
|
342
|
+
/** Default ApifyClient instance for this Actor (instance accessor). */
|
|
344
343
|
get apifyClient(): ApifyClient;
|
|
345
344
|
private _ensureInit;
|
|
346
345
|
private static _actorConfig;
|
|
@@ -540,12 +539,12 @@ export declare class Actor {
|
|
|
540
539
|
*/
|
|
541
540
|
static get isPaying(): boolean;
|
|
542
541
|
/**
|
|
543
|
-
* Public URL of the
|
|
542
|
+
* Public URL of the platform API. May be used to interact with the platform programmatically.
|
|
544
543
|
*/
|
|
545
544
|
static get apiPublicBaseUrl(): string | undefined;
|
|
546
545
|
/**
|
|
547
546
|
* Get a single environment variable value by name.
|
|
548
|
-
*
|
|
547
|
+
* Alias for process.env[key].
|
|
549
548
|
*/
|
|
550
549
|
static getenv(key: string): string | undefined;
|
|
551
550
|
on(event: EventTypeName | 'cpuInfo', listener: (...args: any[]) => void): void;
|
|
@@ -639,12 +638,12 @@ export declare class Actor {
|
|
|
639
638
|
/** @internal */
|
|
640
639
|
private static _instance;
|
|
641
640
|
/**
|
|
642
|
-
* Get the default Actor instance (singleton
|
|
641
|
+
* Get the default Actor instance (singleton).
|
|
643
642
|
* @returns The default Actor instance
|
|
644
643
|
*/
|
|
645
644
|
static getDefaultInstance(): Actor;
|
|
646
645
|
/**
|
|
647
|
-
* Default Configuration instance (
|
|
646
|
+
* Default Configuration instance (static accessor).
|
|
648
647
|
* Used after Actor.init() without new Actor(), e.g. Actor.config.get('standbyPort').
|
|
649
648
|
*/
|
|
650
649
|
static get config(): Configuration;
|
|
@@ -653,7 +652,7 @@ export declare class Actor {
|
|
|
653
652
|
*/
|
|
654
653
|
static get apifyClient(): ApifyClient;
|
|
655
654
|
/**
|
|
656
|
-
* Returns a new
|
|
655
|
+
* Returns a new API client (ApifyClient) pointed at the Scrapely platform.
|
|
657
656
|
*/
|
|
658
657
|
newClient(options?: {
|
|
659
658
|
token?: string;
|
|
@@ -663,7 +662,7 @@ export declare class Actor {
|
|
|
663
662
|
token?: string;
|
|
664
663
|
baseUrl?: string;
|
|
665
664
|
}): ApifyClient;
|
|
666
|
-
/**
|
|
665
|
+
/** Instance API — delegates to {@link Actor.charge}. */
|
|
667
666
|
charge(options: ChargingChargeOptions | string, count?: number): Promise<ChargeResult>;
|
|
668
667
|
/**
|
|
669
668
|
* Charge for a custom pricing event (pay-per-event Actors).
|
|
@@ -673,7 +672,7 @@ export declare class Actor {
|
|
|
673
672
|
getChargingManager(): ChargingManager;
|
|
674
673
|
/**
|
|
675
674
|
* Metamorph the current actor run into a run of another actor.
|
|
676
|
-
*
|
|
675
|
+
* Metamorph behavior:
|
|
677
676
|
* 1. Stores new input under INPUT-METAMORPH-{n} key in the default KVS
|
|
678
677
|
* 2. Signals the server to swap the container to the target actor's image
|
|
679
678
|
* 3. Exits the current process (the container will be replaced)
|
|
@@ -714,8 +713,6 @@ export declare class Actor {
|
|
|
714
713
|
* on a new server. Any state persisted via Actor.useState() will be
|
|
715
714
|
* automatically restored.
|
|
716
715
|
*
|
|
717
|
-
* This is an Apify-compatible method.
|
|
718
|
-
*
|
|
719
716
|
* @param options - Reboot options
|
|
720
717
|
*/
|
|
721
718
|
static reboot(options?: RebootOptions): Promise<void>;
|
|
@@ -729,12 +726,12 @@ export declare class Actor {
|
|
|
729
726
|
static abort(runId?: string, options?: AbortOptions): Promise<ActorRun>;
|
|
730
727
|
static addWebhook(options: WebhookOptions): Promise<Webhook | undefined>;
|
|
731
728
|
/**
|
|
732
|
-
* Runs an Actor on the platform and waits for it to finish (
|
|
729
|
+
* Runs an Actor on the platform and waits for it to finish (instance API).
|
|
733
730
|
*/
|
|
734
731
|
call(actorId: string, input?: unknown, options?: CallOptions): Promise<ActorRun>;
|
|
735
732
|
static call(actorId: string, input?: unknown, options?: CallOptions): Promise<ActorRun>;
|
|
736
733
|
/**
|
|
737
|
-
* Runs an Actor task on the platform and waits for it to finish (
|
|
734
|
+
* Runs an Actor task on the platform and waits for it to finish (instance API).
|
|
738
735
|
*/
|
|
739
736
|
callTask(taskId: string, input?: Dictionary, options?: CallTaskOptions): Promise<ActorRun>;
|
|
740
737
|
static callTask(taskId: string, input?: Dictionary, options?: CallTaskOptions): Promise<ActorRun>;
|
|
@@ -763,11 +760,21 @@ export declare class Actor {
|
|
|
763
760
|
start(actorId: string, input?: Dictionary, options?: StartOptions): Promise<ActorRun>;
|
|
764
761
|
useState<State extends Dictionary = Dictionary>(nameOrInitialState?: string | State, defaultValue?: State, options?: UseStateOptions): Promise<State>;
|
|
765
762
|
/**
|
|
766
|
-
*
|
|
767
|
-
* Provides helper functions like enqueueLinks that accept the
|
|
763
|
+
* Utility namespace.
|
|
764
|
+
* Provides helper functions like enqueueLinks that accept the v2-style call signature.
|
|
768
765
|
*/
|
|
769
766
|
static readonly utils: {
|
|
770
767
|
enqueueLinks: typeof import("./utils.js").enqueueLinks;
|
|
768
|
+
requestAsBrowser: typeof import("./utils.js").requestAsBrowser;
|
|
769
|
+
getRandomUserAgent: typeof import("./utils.js").getRandomUserAgent;
|
|
770
|
+
sleep: (millis?: number) => any;
|
|
771
|
+
downloadListOfUrls: (options: any) => any;
|
|
772
|
+
extractUrls: (options: any) => any;
|
|
773
|
+
htmlToText: (html: any) => any;
|
|
774
|
+
isDocker: (forceReset?: boolean) => any;
|
|
775
|
+
readonly log: any;
|
|
776
|
+
readonly puppeteer: any;
|
|
777
|
+
readonly playwright: any;
|
|
771
778
|
};
|
|
772
779
|
}
|
|
773
780
|
/** Resolves once stdout and stderr have flushed their buffers, or after `maxMs`. */
|
package/dist/actor.js
CHANGED
|
@@ -8,7 +8,7 @@ exports.waitForStdioDrain = waitForStdioDrain;
|
|
|
8
8
|
// Modified by TeraShift GmbH. See LICENSE-APACHE and NOTICE.
|
|
9
9
|
require("./log-env.js");
|
|
10
10
|
const node_events_1 = require("node:events");
|
|
11
|
-
/** Actor permission level
|
|
11
|
+
/** Actor permission level. */
|
|
12
12
|
var ACTOR_PERMISSION_LEVEL;
|
|
13
13
|
(function (ACTOR_PERMISSION_LEVEL) {
|
|
14
14
|
/** User has no special permissions */
|
|
@@ -57,7 +57,7 @@ const gracefulShutdownHandlers = {};
|
|
|
57
57
|
*/
|
|
58
58
|
const signalExitHandlers = {};
|
|
59
59
|
/**
|
|
60
|
-
* Exit codes for the Actor process
|
|
60
|
+
* Exit codes for the Actor process.
|
|
61
61
|
* Must be in the range 1-128 to avoid collision with signal exits.
|
|
62
62
|
*/
|
|
63
63
|
exports.EXIT_CODES = {
|
|
@@ -116,7 +116,7 @@ class Actor {
|
|
|
116
116
|
_apifyClient;
|
|
117
117
|
chargingManager;
|
|
118
118
|
/**
|
|
119
|
-
* Creates an Actor instance (
|
|
119
|
+
* Creates an Actor instance (alternative to the static helpers).
|
|
120
120
|
*/
|
|
121
121
|
constructor(options = {}) {
|
|
122
122
|
this.config =
|
|
@@ -124,7 +124,7 @@ class Actor {
|
|
|
124
124
|
this.chargingManager = new charging_js_1.ChargingManager(this.config, () => this.apifyClient);
|
|
125
125
|
Actor._instance ??= this;
|
|
126
126
|
}
|
|
127
|
-
/** Default ApifyClient instance for this Actor (
|
|
127
|
+
/** Default ApifyClient instance for this Actor (instance accessor). */
|
|
128
128
|
get apifyClient() {
|
|
129
129
|
this._apifyClient ??= this.newClient();
|
|
130
130
|
return this._apifyClient;
|
|
@@ -407,7 +407,7 @@ class Actor {
|
|
|
407
407
|
const timeoutSecs = opts.timeoutSecs ?? 30;
|
|
408
408
|
const shouldExit = opts.exit ?? true;
|
|
409
409
|
Actor._ensureActorInit('exit');
|
|
410
|
-
//
|
|
410
|
+
// The exit/fail message becomes the run's terminal status
|
|
411
411
|
// message. Stored before teardown, while the run and process are alive.
|
|
412
412
|
if (opts.statusMessage)
|
|
413
413
|
await Actor._persistTerminalStatusMessage(opts.statusMessage, code);
|
|
@@ -427,7 +427,7 @@ class Actor {
|
|
|
427
427
|
}
|
|
428
428
|
static async getInput() {
|
|
429
429
|
Actor._ensureActorInit('getInput');
|
|
430
|
-
// Check for metamorph input first
|
|
430
|
+
// Check for metamorph input first
|
|
431
431
|
// When an actor is metamorphed, the input is stored under INPUT-METAMORPH-{n}
|
|
432
432
|
const metamorphCount = process.env.ACTOR_METAMORPH_COUNT;
|
|
433
433
|
if (metamorphCount) {
|
|
@@ -545,6 +545,7 @@ class Actor {
|
|
|
545
545
|
chargePer: opts.chargePer ?? 'row',
|
|
546
546
|
isDefaultDataset,
|
|
547
547
|
pushFn: async (rows) => { await dataset.pushData(rows); },
|
|
548
|
+
validateItems: await crawleeItemValidator(),
|
|
548
549
|
});
|
|
549
550
|
}
|
|
550
551
|
if (opts.chargePer !== undefined && opts.chargePer !== 'row')
|
|
@@ -565,10 +566,11 @@ class Actor {
|
|
|
565
566
|
eventName: opts.eventName,
|
|
566
567
|
isDefaultDataset: false,
|
|
567
568
|
pushFn: async (rows) => { await dataset.pushData(rows); },
|
|
569
|
+
validateItems: await crawleeItemValidator(),
|
|
568
570
|
});
|
|
569
571
|
}
|
|
570
572
|
const eventName = eventNameOrOptions;
|
|
571
|
-
// Exact synthetic names only — prefix would block real priced events
|
|
573
|
+
// Exact synthetic names only — prefix would block real priced events.
|
|
572
574
|
if (eventName === 'apify-default-dataset-item' ||
|
|
573
575
|
eventName === 'scrapely-default-dataset-item') {
|
|
574
576
|
throw new Error(`Cannot charge for synthetic event '${eventName}' manually`);
|
|
@@ -623,6 +625,7 @@ class Actor {
|
|
|
623
625
|
eventName: explicitEventName,
|
|
624
626
|
isDefaultDataset,
|
|
625
627
|
pushFn: async (limitedItems) => dataset.pushData(limitedItems),
|
|
628
|
+
validateItems: await crawleeItemValidator(),
|
|
626
629
|
});
|
|
627
630
|
}
|
|
628
631
|
static async getValue(key) {
|
|
@@ -833,7 +836,7 @@ class Actor {
|
|
|
833
836
|
return value === '1' ? 1 : null;
|
|
834
837
|
};
|
|
835
838
|
return {
|
|
836
|
-
//
|
|
839
|
+
// Fields in alphabetical order
|
|
837
840
|
actorId: env.ACTOR_ID || null,
|
|
838
841
|
actorBuildId: env.ACTOR_BUILD_ID || null,
|
|
839
842
|
actorBuildNumber: env.ACTOR_BUILD_NUMBER || null,
|
|
@@ -947,14 +950,14 @@ class Actor {
|
|
|
947
950
|
return Actor._actorConfig().get('userIsPaying') === true;
|
|
948
951
|
}
|
|
949
952
|
/**
|
|
950
|
-
* Public URL of the
|
|
953
|
+
* Public URL of the platform API. May be used to interact with the platform programmatically.
|
|
951
954
|
*/
|
|
952
955
|
static get apiPublicBaseUrl() {
|
|
953
956
|
return Actor._actorConfig().get('apiPublicBaseUrl') || undefined;
|
|
954
957
|
}
|
|
955
958
|
/**
|
|
956
959
|
* Get a single environment variable value by name.
|
|
957
|
-
*
|
|
960
|
+
* Alias for process.env[key].
|
|
958
961
|
*/
|
|
959
962
|
static getenv(key) {
|
|
960
963
|
return process.env[key];
|
|
@@ -1243,7 +1246,7 @@ class Actor {
|
|
|
1243
1246
|
/** @internal */
|
|
1244
1247
|
static _instance;
|
|
1245
1248
|
/**
|
|
1246
|
-
* Get the default Actor instance (singleton
|
|
1249
|
+
* Get the default Actor instance (singleton).
|
|
1247
1250
|
* @returns The default Actor instance
|
|
1248
1251
|
*/
|
|
1249
1252
|
static getDefaultInstance() {
|
|
@@ -1251,7 +1254,7 @@ class Actor {
|
|
|
1251
1254
|
return Actor._instance;
|
|
1252
1255
|
}
|
|
1253
1256
|
/**
|
|
1254
|
-
* Default Configuration instance (
|
|
1257
|
+
* Default Configuration instance (static accessor).
|
|
1255
1258
|
* Used after Actor.init() without new Actor(), e.g. Actor.config.get('standbyPort').
|
|
1256
1259
|
*/
|
|
1257
1260
|
static get config() {
|
|
@@ -1264,7 +1267,7 @@ class Actor {
|
|
|
1264
1267
|
return Actor.getDefaultInstance().apifyClient;
|
|
1265
1268
|
}
|
|
1266
1269
|
/**
|
|
1267
|
-
* Returns a new
|
|
1270
|
+
* Returns a new API client (ApifyClient) pointed at the Scrapely platform.
|
|
1268
1271
|
*/
|
|
1269
1272
|
newClient(options) {
|
|
1270
1273
|
const config = this.config;
|
|
@@ -1290,7 +1293,7 @@ class Actor {
|
|
|
1290
1293
|
static newClient(options) {
|
|
1291
1294
|
return Actor.getDefaultInstance().newClient(options);
|
|
1292
1295
|
}
|
|
1293
|
-
/**
|
|
1296
|
+
/** Instance API — delegates to {@link Actor.charge}. */
|
|
1294
1297
|
async charge(options, count) {
|
|
1295
1298
|
return Actor.charge(options, count);
|
|
1296
1299
|
}
|
|
@@ -1310,7 +1313,7 @@ class Actor {
|
|
|
1310
1313
|
}
|
|
1311
1314
|
/**
|
|
1312
1315
|
* Metamorph the current actor run into a run of another actor.
|
|
1313
|
-
*
|
|
1316
|
+
* Metamorph behavior:
|
|
1314
1317
|
* 1. Stores new input under INPUT-METAMORPH-{n} key in the default KVS
|
|
1315
1318
|
* 2. Signals the server to swap the container to the target actor's image
|
|
1316
1319
|
* 3. Exits the current process (the container will be replaced)
|
|
@@ -1424,8 +1427,6 @@ class Actor {
|
|
|
1424
1427
|
* on a new server. Any state persisted via Actor.useState() will be
|
|
1425
1428
|
* automatically restored.
|
|
1426
1429
|
*
|
|
1427
|
-
* This is an Apify-compatible method.
|
|
1428
|
-
*
|
|
1429
1430
|
* @param options - Reboot options
|
|
1430
1431
|
*/
|
|
1431
1432
|
static async reboot(options) {
|
|
@@ -1468,7 +1469,7 @@ class Actor {
|
|
|
1468
1469
|
catch (err) {
|
|
1469
1470
|
console.warn(`[Scrapely] flushPending during reboot failed: ${err.message}`);
|
|
1470
1471
|
}
|
|
1471
|
-
// Exit so the worker can restart the container
|
|
1472
|
+
// Exit so the worker can restart the container.
|
|
1472
1473
|
process.exit(0);
|
|
1473
1474
|
}
|
|
1474
1475
|
/**
|
|
@@ -1512,7 +1513,7 @@ class Actor {
|
|
|
1512
1513
|
});
|
|
1513
1514
|
}
|
|
1514
1515
|
/**
|
|
1515
|
-
* Runs an Actor on the platform and waits for it to finish (
|
|
1516
|
+
* Runs an Actor on the platform and waits for it to finish (instance API).
|
|
1516
1517
|
*/
|
|
1517
1518
|
async call(actorId, input, options = {}) {
|
|
1518
1519
|
return Actor.call(actorId, input, options);
|
|
@@ -1524,7 +1525,7 @@ class Actor {
|
|
|
1524
1525
|
return client.actor(actorId).call(input, { ...rest, timeout });
|
|
1525
1526
|
}
|
|
1526
1527
|
/**
|
|
1527
|
-
* Runs an Actor task on the platform and waits for it to finish (
|
|
1528
|
+
* Runs an Actor task on the platform and waits for it to finish (instance API).
|
|
1528
1529
|
*/
|
|
1529
1530
|
async callTask(taskId, input, options = {}) {
|
|
1530
1531
|
return Actor.callTask(taskId, input, options);
|
|
@@ -1542,7 +1543,7 @@ class Actor {
|
|
|
1542
1543
|
return client.actor(actorId).start(input, { ...rest, timeout });
|
|
1543
1544
|
}
|
|
1544
1545
|
// -------------------------------------------------------------------------
|
|
1545
|
-
//
|
|
1546
|
+
// Instance API (mirrors static methods on Actor class)
|
|
1546
1547
|
// -------------------------------------------------------------------------
|
|
1547
1548
|
async main(userFunc, options) {
|
|
1548
1549
|
return Actor.main(userFunc, options);
|
|
@@ -1633,8 +1634,8 @@ class Actor {
|
|
|
1633
1634
|
});
|
|
1634
1635
|
}
|
|
1635
1636
|
/**
|
|
1636
|
-
*
|
|
1637
|
-
* Provides helper functions like enqueueLinks that accept the
|
|
1637
|
+
* Utility namespace.
|
|
1638
|
+
* Provides helper functions like enqueueLinks that accept the v2-style call signature.
|
|
1638
1639
|
*/
|
|
1639
1640
|
static utils = utils_js_1.utils;
|
|
1640
1641
|
}
|
|
@@ -1658,3 +1659,18 @@ async function waitForStdioDrain(maxMs, streams = [process.stdout, process.stder
|
|
|
1658
1659
|
if (timer)
|
|
1659
1660
|
clearTimeout(timer);
|
|
1660
1661
|
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Crawlee's own item rules (an object, serializable, at most ~9 MB), checked
|
|
1664
|
+
* before a charge: Dataset.pushData would refuse such an item only after it
|
|
1665
|
+
* was charged. Undefined when this crawlee version does not export the check.
|
|
1666
|
+
*/
|
|
1667
|
+
async function crawleeItemValidator() {
|
|
1668
|
+
const core = (await import('@crawlee/core'));
|
|
1669
|
+
const check = core.checkAndSerialize;
|
|
1670
|
+
if (typeof check !== 'function')
|
|
1671
|
+
return undefined;
|
|
1672
|
+
// Same limit as Dataset.pushData (MAX_PAYLOAD_SIZE_BYTES minus its 0.01% safety buffer).
|
|
1673
|
+
const max = 9 * 1024 * 1024;
|
|
1674
|
+
const limit = max - Math.ceil(max * 0.0001);
|
|
1675
|
+
return (items) => items.forEach((item, index) => check(item, limit, index));
|
|
1676
|
+
}
|
package/dist/charging.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class ChargeUncertainError extends Error {
|
|
|
13
13
|
count: number;
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
16
|
+
/** Synthetic event for default-dataset items in pay-per-event actors. */
|
|
17
17
|
/** Definitive platform rejection (402/400/409). Do not retry with the same key. */
|
|
18
18
|
export declare class ChargeRejectedError extends Error {
|
|
19
19
|
readonly operationId: string;
|
|
@@ -43,7 +43,7 @@ export declare function refuseDefaultDatasetPush(itemCount: number): boolean;
|
|
|
43
43
|
export declare const APIFY_DEFAULT_DATASET_ITEM_EVENT = "apify-default-dataset-item";
|
|
44
44
|
/** Scrapely-native synthetic event for default-dataset items. */
|
|
45
45
|
export declare const SCRAPELY_DEFAULT_DATASET_ITEM_EVENT = "scrapely-default-dataset-item";
|
|
46
|
-
/**
|
|
46
|
+
/** Alias — imported actors expect this constant name. */
|
|
47
47
|
export declare const DEFAULT_DATASET_ITEM_EVENT = "apify-default-dataset-item";
|
|
48
48
|
export declare function isDefaultDatasetItemEvent(eventName: string): boolean;
|
|
49
49
|
export declare function resolveDefaultDatasetItemEventName(pricingInfo: Record<string, unknown>): string;
|
|
@@ -169,8 +169,23 @@ export declare class ChargingManager {
|
|
|
169
169
|
private lastAcceptedOperationId;
|
|
170
170
|
/** Voids not yet confirmed by the platform; retried before the next push and at exit. */
|
|
171
171
|
private pendingVoids;
|
|
172
|
+
/**
|
|
173
|
+
* @internal Platform charges for results that were not stored and that the
|
|
174
|
+
* platform definitively refused to void (event -> count). They stay billed,
|
|
175
|
+
* so the next push of that event uses them instead of charging again.
|
|
176
|
+
*/
|
|
177
|
+
_voidRefusedCredit: Record<string, number>;
|
|
172
178
|
/** Unresolved platform POSTs: key = idempotency UUID (never event name). */
|
|
173
179
|
private readonly pendingCharges;
|
|
180
|
+
/**
|
|
181
|
+
* Record in the run's default key-value store that mirrors pendingCharges,
|
|
182
|
+
* so a container crash does not lose them: settlement re-applies them under
|
|
183
|
+
* their own idempotency keys. One record per container, so a restarted
|
|
184
|
+
* container never overwrites its predecessor's.
|
|
185
|
+
*/
|
|
186
|
+
private readonly pendingRecordKey;
|
|
187
|
+
/** Intent keys last written to that record ('' = nothing written / empty). */
|
|
188
|
+
private persistedPendingSig;
|
|
174
189
|
private flushInFlight;
|
|
175
190
|
private operationTail;
|
|
176
191
|
private readonly postAttempts;
|
|
@@ -248,6 +263,11 @@ export declare class ChargingManager {
|
|
|
248
263
|
private postChargeWithRetries;
|
|
249
264
|
/** @internal Idempotency key of the charge accepted by the last _chargeExclusive call, if any. */
|
|
250
265
|
_takeLastAcceptedOperationId(): string | undefined;
|
|
266
|
+
/**
|
|
267
|
+
* @internal Mirror the unconfirmed charges to the run's default key-value
|
|
268
|
+
* store (best effort, only when the set changed since the last write).
|
|
269
|
+
*/
|
|
270
|
+
_persistPendingCharges(): Promise<void>;
|
|
251
271
|
/**
|
|
252
272
|
* @internal Reverse an accepted charge whose items were never stored
|
|
253
273
|
* (POST /v2/actor-runs/:runId/charge/void), then unwind the local
|
|
@@ -260,6 +280,21 @@ export declare class ChargingManager {
|
|
|
260
280
|
* means it never applied.
|
|
261
281
|
*/
|
|
262
282
|
_cancelUncertainCharge(eventName: string, operationId: string, reservedCount: number): Promise<boolean>;
|
|
283
|
+
/**
|
|
284
|
+
* @internal Void (or cancel, when unconfirmed) a whole charge and say what
|
|
285
|
+
* happened: 'voided' (confirmed, local reservation released), 'stands' (a
|
|
286
|
+
* definitive answer that it cannot be voided) or 'unknown' (queued for retry,
|
|
287
|
+
* reservation kept).
|
|
288
|
+
*/
|
|
289
|
+
_voidOutcome(eventName: string, operationId: string, reservedCount: number, uncertain: boolean): Promise<'voided' | 'stands' | 'unknown'>;
|
|
290
|
+
/** @internal A charge for `count` unstored results stands (void refused): keep it as credit. */
|
|
291
|
+
_noteUnvoidable(eventName: string, count: number): void;
|
|
292
|
+
/** @internal Use credit for a whole charge of `count` events (all or nothing); returns the count used. */
|
|
293
|
+
_takeVoidCredit(eventName: string, count: number): number;
|
|
294
|
+
/** @internal */
|
|
295
|
+
_returnVoidCredit(eventName: string, count: number): void;
|
|
296
|
+
/** @internal Void (or cancel) a charge for results that were not stored; a refused void becomes credit. */
|
|
297
|
+
_voidOrCredit(eventName: string, operationId: string, reservedCount: number, uncertain: boolean): Promise<'voided' | 'stands' | 'unknown'>;
|
|
263
298
|
_voidCharge(eventName: string, operationId: string, reservedCount: number, notFoundMeansVoided?: boolean, deadline?: number): Promise<boolean>;
|
|
264
299
|
/**
|
|
265
300
|
* @internal Retry unconfirmed voids (caller holds the operation lock).
|
|
@@ -284,12 +319,20 @@ export declare class ChargingManager {
|
|
|
284
319
|
/** @internal Caller must hold the operation lock. */
|
|
285
320
|
_chargeExclusive({ eventName, count }: ChargeOptions): Promise<ChargeResult>;
|
|
286
321
|
}
|
|
287
|
-
|
|
322
|
+
/**
|
|
323
|
+
* @internal Fail before anything is charged when an item cannot be serialized
|
|
324
|
+
* for the dataset (circular reference, BigInt, a bare function or undefined):
|
|
325
|
+
* the push would otherwise fail after the charge, with nothing stored.
|
|
326
|
+
*/
|
|
327
|
+
export declare function assertItemsSerializable(items: unknown[]): void;
|
|
328
|
+
export declare function pushDataAndCharge<T>({ chargingManager, items, eventName, isDefaultDataset, pushFn, validateItems, }: {
|
|
288
329
|
chargingManager: ChargingManager;
|
|
289
330
|
items: T | T[];
|
|
290
331
|
eventName: string | undefined;
|
|
291
332
|
isDefaultDataset: boolean;
|
|
292
333
|
pushFn: (limitedItems: T | T[]) => Promise<void>;
|
|
334
|
+
/** Extra checks the storage would make after the charge (e.g. crawlee's object / size rules). */
|
|
335
|
+
validateItems?: (items: T[]) => void;
|
|
293
336
|
}): Promise<ChargeResult>;
|
|
294
337
|
/** Validate `{ eventName: eventsPerRow }` for a multi-event push. */
|
|
295
338
|
export declare function validateRowCharges(charges: unknown): Record<string, number>;
|
|
@@ -301,7 +344,7 @@ export declare function validateRowCharges(charges: unknown): Record<string, num
|
|
|
301
344
|
* the rows that are kept, so no row is stored part-paid and no event is billed
|
|
302
345
|
* for a row that was not stored. Unpriced events are ignored.
|
|
303
346
|
*/
|
|
304
|
-
export declare function pushDataWithCharges<T>({ chargingManager, items, charges, isDefaultDataset, pushFn, chargePer, }: {
|
|
347
|
+
export declare function pushDataWithCharges<T>({ chargingManager, items, charges, isDefaultDataset, pushFn, chargePer, validateItems, }: {
|
|
305
348
|
chargingManager: ChargingManager;
|
|
306
349
|
items: T | T[];
|
|
307
350
|
charges: Record<string, number>;
|
|
@@ -309,6 +352,8 @@ export declare function pushDataWithCharges<T>({ chargingManager, items, charges
|
|
|
309
352
|
pushFn: (rows: T | T[]) => Promise<void>;
|
|
310
353
|
/** 'batch': charge `charges` once for the whole push; all rows stored if accepted, none if refused. */
|
|
311
354
|
chargePer?: 'row' | 'batch';
|
|
355
|
+
/** Extra checks the storage would make after the charge (e.g. crawlee's object / size rules). */
|
|
356
|
+
validateItems?: (items: T[]) => void;
|
|
312
357
|
}): Promise<ChargeResult>;
|
|
313
358
|
/**
|
|
314
359
|
* @internal True when a dataset push certainly stored nothing: the storage API
|