apify 4.0.0-beta.31 → 4.0.0-beta.32
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/dist/actor.d.ts +6 -23
- package/dist/actor.js +55 -48
- package/dist/apify_dataset_backend.d.ts +1 -1
- package/dist/apify_dataset_backend.js +6 -6
- package/dist/apify_key_value_store_backend.d.ts +1 -1
- package/dist/apify_key_value_store_backend.js +10 -10
- package/dist/apify_request_queue_backend.d.ts +1 -1
- package/dist/apify_request_queue_backend.js +3 -3
- package/dist/apify_request_queue_shared_backend.d.ts +1 -14
- package/dist/apify_request_queue_shared_backend.js +38 -38
- package/dist/apify_request_queue_single_backend.d.ts +1 -10
- package/dist/apify_request_queue_single_backend.js +44 -44
- package/dist/apify_storage_backend.d.ts +1 -12
- package/dist/apify_storage_backend.js +43 -43
- package/dist/charging.d.ts +1 -14
- package/dist/charging.js +84 -81
- package/dist/platform_event_manager.d.ts +1 -2
- package/dist/platform_event_manager.js +7 -7
- package/dist/proxy_configuration.d.ts +7 -18
- package/dist/proxy_configuration.js +46 -57
- package/package.json +1 -1
package/dist/actor.d.ts
CHANGED
|
@@ -319,8 +319,6 @@ export declare const EXIT_CODES: {
|
|
|
319
319
|
*/
|
|
320
320
|
export declare class Actor<Data extends Dictionary = Dictionary> {
|
|
321
321
|
#private;
|
|
322
|
-
/** @internal */
|
|
323
|
-
static _instance: Actor;
|
|
324
322
|
/**
|
|
325
323
|
* Configuration of this SDK instance (provided to its constructor). See {@link Configuration} for details.
|
|
326
324
|
* @internal
|
|
@@ -340,26 +338,6 @@ export declare class Actor<Data extends Dictionary = Dictionary> {
|
|
|
340
338
|
* Whether the Actor instance was initialized. This is set by calling {@link Actor.init}.
|
|
341
339
|
*/
|
|
342
340
|
initialized: boolean;
|
|
343
|
-
/**
|
|
344
|
-
* Set if the Actor called a method that requires the instance to be initialized, but did not do so.
|
|
345
|
-
* A call to `init` after this warning is emitted is considered an invalid state and will throw an error.
|
|
346
|
-
*/
|
|
347
|
-
private warnedAboutMissingInitCall;
|
|
348
|
-
/**
|
|
349
|
-
* Set if the Actor is currently rebooting.
|
|
350
|
-
*/
|
|
351
|
-
private isRebooting;
|
|
352
|
-
/**
|
|
353
|
-
* Set if the Actor is currently exiting. Prevents double-exit from graceful shutdown handlers.
|
|
354
|
-
*/
|
|
355
|
-
private isExiting;
|
|
356
|
-
/**
|
|
357
|
-
* References to graceful shutdown handlers so they can be removed during cleanup.
|
|
358
|
-
*/
|
|
359
|
-
private gracefulShutdownHandlers;
|
|
360
|
-
private chargingManager;
|
|
361
|
-
/** How Apify platform request queues are consumed; set from {@link InitOptions.requestQueueAccess}. */
|
|
362
|
-
private requestQueueAccess;
|
|
363
341
|
constructor(options?: ActorOptions);
|
|
364
342
|
/**
|
|
365
343
|
* Runs the main user function that performs the job of the Actor
|
|
@@ -1383,11 +1361,16 @@ export declare class Actor<Data extends Dictionary = Dictionary> {
|
|
|
1383
1361
|
static get configuration(): Configuration;
|
|
1384
1362
|
/** @internal */
|
|
1385
1363
|
static getDefaultInstance(): Actor;
|
|
1364
|
+
/**
|
|
1365
|
+
* Replaces or clears the cached default instance returned by {@link Actor.getDefaultInstance}.
|
|
1366
|
+
* @internal
|
|
1367
|
+
*/
|
|
1368
|
+
static setDefaultInstance(instance?: Actor): void;
|
|
1386
1369
|
private usesPushDataInterception;
|
|
1387
1370
|
private pushDataViaInterceptedClient;
|
|
1388
1371
|
private pushDataWithExplicitCharging;
|
|
1389
1372
|
private createApifyStorageBackend;
|
|
1390
|
-
private
|
|
1373
|
+
private ensureActorInit;
|
|
1391
1374
|
/**
|
|
1392
1375
|
* Get time remaining from the Actor run timeout in seconds, rounded up to whole seconds with minimum value of 1 second.
|
|
1393
1376
|
*
|
package/dist/actor.js
CHANGED
|
@@ -33,7 +33,7 @@ export const EXIT_CODES = {
|
|
|
33
33
|
*/
|
|
34
34
|
export class Actor {
|
|
35
35
|
/** @internal */
|
|
36
|
-
static
|
|
36
|
+
static #instance;
|
|
37
37
|
/**
|
|
38
38
|
* Configuration of this SDK instance (provided to its constructor). See {@link Configuration} for details.
|
|
39
39
|
* @internal
|
|
@@ -57,26 +57,26 @@ export class Actor {
|
|
|
57
57
|
* Set if the Actor called a method that requires the instance to be initialized, but did not do so.
|
|
58
58
|
* A call to `init` after this warning is emitted is considered an invalid state and will throw an error.
|
|
59
59
|
*/
|
|
60
|
-
warnedAboutMissingInitCall = false;
|
|
60
|
+
#warnedAboutMissingInitCall = false;
|
|
61
61
|
/**
|
|
62
62
|
* Set if the Actor is currently rebooting.
|
|
63
63
|
*/
|
|
64
|
-
isRebooting = false;
|
|
64
|
+
#isRebooting = false;
|
|
65
65
|
/**
|
|
66
66
|
* Set if the Actor is currently exiting. Prevents double-exit from graceful shutdown handlers.
|
|
67
67
|
*/
|
|
68
|
-
isExiting = false;
|
|
68
|
+
#isExiting = false;
|
|
69
69
|
/**
|
|
70
70
|
* References to graceful shutdown handlers so they can be removed during cleanup.
|
|
71
71
|
*/
|
|
72
|
-
gracefulShutdownHandlers = {};
|
|
72
|
+
#gracefulShutdownHandlers = {};
|
|
73
73
|
/**
|
|
74
74
|
* Reference to the crawlee status message forwarder, so it can be removed during cleanup.
|
|
75
75
|
*/
|
|
76
76
|
#statusMessageForwarder;
|
|
77
|
-
chargingManager;
|
|
77
|
+
#chargingManager;
|
|
78
78
|
/** How Apify platform request queues are consumed; set from {@link InitOptions.requestQueueAccess}. */
|
|
79
|
-
requestQueueAccess = 'single';
|
|
79
|
+
#requestQueueAccess = 'single';
|
|
80
80
|
constructor(options = {}) {
|
|
81
81
|
const { configuration, ...configOptions } = options;
|
|
82
82
|
if (configuration) {
|
|
@@ -101,7 +101,7 @@ export class Actor {
|
|
|
101
101
|
}
|
|
102
102
|
this.apifyClient = this.newClient();
|
|
103
103
|
this.eventManager = new PlatformEventManager(this.configuration);
|
|
104
|
-
this
|
|
104
|
+
this.#chargingManager = new ChargingManager(this.configuration, this.apifyClient);
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
107
|
* Runs the main user function that performs the job of the Actor
|
|
@@ -192,7 +192,7 @@ export class Actor {
|
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
194
|
// If the warning about forgotten init call was emitted, we will not continue the init procedure.
|
|
195
|
-
if (this
|
|
195
|
+
if (this.#warnedAboutMissingInitCall) {
|
|
196
196
|
throw new Error([
|
|
197
197
|
'Actor.init() was called after a method that would access a storage client was used.',
|
|
198
198
|
'This in an invalid state. Please make sure to call Actor.init() before such methods are called.',
|
|
@@ -206,7 +206,7 @@ export class Actor {
|
|
|
206
206
|
// the event manager resolve the same instance (`availableMemoryRatio` /
|
|
207
207
|
// `disableBrowserSandbox` at-home defaults now live in `Configuration`).
|
|
208
208
|
serviceLocator.setConfiguration(this.configuration);
|
|
209
|
-
this
|
|
209
|
+
this.#requestQueueAccess = options.requestQueueAccess ?? 'single';
|
|
210
210
|
if (this.isAtHome()) {
|
|
211
211
|
serviceLocator.setStorageBackend(this.createApifyStorageBackend());
|
|
212
212
|
serviceLocator.setEventManager(this.eventManager);
|
|
@@ -223,22 +223,22 @@ export class Actor {
|
|
|
223
223
|
// Using setTimeout to avoid deadlock with waitForAllListenersToComplete() in exit()/reboot()
|
|
224
224
|
if (options.gracefulShutdown !== false) {
|
|
225
225
|
const delay = options.gracefulShutdownDelayMillis ?? 0;
|
|
226
|
-
this
|
|
226
|
+
this.#gracefulShutdownHandlers.aborting = () => {
|
|
227
227
|
setTimeout(() => {
|
|
228
228
|
this.exit().catch((err) => {
|
|
229
229
|
log.exception(err, 'Failed to exit gracefully');
|
|
230
230
|
});
|
|
231
231
|
}, delay);
|
|
232
232
|
};
|
|
233
|
-
this.on(ACTOR_EVENT_NAMES.ABORTING, this
|
|
234
|
-
this
|
|
233
|
+
this.on(ACTOR_EVENT_NAMES.ABORTING, this.#gracefulShutdownHandlers.aborting);
|
|
234
|
+
this.#gracefulShutdownHandlers.migrating = () => {
|
|
235
235
|
setTimeout(() => {
|
|
236
236
|
this.reboot().catch((err) => {
|
|
237
237
|
log.exception(err, 'Failed to reboot on migration');
|
|
238
238
|
});
|
|
239
239
|
}, delay);
|
|
240
240
|
};
|
|
241
|
-
this.on(ACTOR_EVENT_NAMES.MIGRATING, this
|
|
241
|
+
this.on(ACTOR_EVENT_NAMES.MIGRATING, this.#gracefulShutdownHandlers.migrating);
|
|
242
242
|
}
|
|
243
243
|
// Crawlee crawlers, for instance, broadcast their status messages as `statusMessage` events.
|
|
244
244
|
this.#statusMessageForwarder = async ({ message, isStatusMessageTerminal }) => this.#updateRunStatusMessage(message, isStatusMessageTerminal);
|
|
@@ -248,19 +248,19 @@ export class Actor {
|
|
|
248
248
|
onlyPurgeOnce: true,
|
|
249
249
|
});
|
|
250
250
|
log.debug(`Default storages purged`);
|
|
251
|
-
await this
|
|
252
|
-
log.debug(`ChargingManager initialized`, this
|
|
251
|
+
await this.#chargingManager.init();
|
|
252
|
+
log.debug(`ChargingManager initialized`, this.#chargingManager.getPricingInfo());
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
255
|
* @ignore
|
|
256
256
|
*/
|
|
257
257
|
async exit(messageOrOptions, options = {}) {
|
|
258
258
|
// Prevent double-exit from graceful shutdown handlers
|
|
259
|
-
if (this
|
|
259
|
+
if (this.#isExiting) {
|
|
260
260
|
log.debug('Actor.exit() called while already exiting, skipping');
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
|
-
this
|
|
263
|
+
this.#isExiting = true;
|
|
264
264
|
options =
|
|
265
265
|
typeof messageOrOptions === 'string'
|
|
266
266
|
? { ...options, statusMessage: messageOrOptions }
|
|
@@ -268,15 +268,15 @@ export class Actor {
|
|
|
268
268
|
options.exit ??= true;
|
|
269
269
|
options.exitCode ??= EXIT_CODES.SUCCESS;
|
|
270
270
|
options.timeoutSecs ??= 30;
|
|
271
|
-
this.
|
|
271
|
+
this.ensureActorInit('exit');
|
|
272
272
|
const client = serviceLocator.getStorageBackend();
|
|
273
273
|
const events = serviceLocator.getEventManager();
|
|
274
274
|
// Remove graceful shutdown handlers to prevent them from interfering with exit
|
|
275
|
-
if (this
|
|
276
|
-
this.off(ACTOR_EVENT_NAMES.ABORTING, this
|
|
275
|
+
if (this.#gracefulShutdownHandlers.aborting) {
|
|
276
|
+
this.off(ACTOR_EVENT_NAMES.ABORTING, this.#gracefulShutdownHandlers.aborting);
|
|
277
277
|
}
|
|
278
|
-
if (this
|
|
279
|
-
this.off(ACTOR_EVENT_NAMES.MIGRATING, this
|
|
278
|
+
if (this.#gracefulShutdownHandlers.migrating) {
|
|
279
|
+
this.off(ACTOR_EVENT_NAMES.MIGRATING, this.#gracefulShutdownHandlers.migrating);
|
|
280
280
|
}
|
|
281
281
|
// Close the event manager and emit the final PERSIST_STATE event
|
|
282
282
|
await events.close();
|
|
@@ -324,7 +324,7 @@ export class Actor {
|
|
|
324
324
|
});
|
|
325
325
|
// Reset the flag so the instance can be reused (e.g., in tests or when exit is false).
|
|
326
326
|
// When process.exit() actually terminates the process, this line is never reached - which is fine.
|
|
327
|
-
this
|
|
327
|
+
this.#isExiting = false;
|
|
328
328
|
if (!options.exit) {
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
@@ -498,16 +498,16 @@ export class Actor {
|
|
|
498
498
|
* @ignore
|
|
499
499
|
*/
|
|
500
500
|
async reboot(options = {}) {
|
|
501
|
-
this.
|
|
501
|
+
this.ensureActorInit('reboot');
|
|
502
502
|
if (!this.isAtHome()) {
|
|
503
503
|
log.warning('Actor.reboot() is only supported when running on the Apify platform.');
|
|
504
504
|
return;
|
|
505
505
|
}
|
|
506
|
-
if (this
|
|
506
|
+
if (this.#isRebooting) {
|
|
507
507
|
log.debug('Actor is already rebooting, skipping the additional reboot call.');
|
|
508
508
|
return;
|
|
509
509
|
}
|
|
510
|
-
this
|
|
510
|
+
this.#isRebooting = true;
|
|
511
511
|
// Waiting for all the listeners to finish, as `.reboot()` kills the container.
|
|
512
512
|
await Promise.all([
|
|
513
513
|
// `persistState` for individual RequestLists, RequestQueue... instances to be persisted
|
|
@@ -581,7 +581,7 @@ export class Actor {
|
|
|
581
581
|
const { isStatusMessageTerminal, level } = options || {};
|
|
582
582
|
parseArgument(statusMessage, z.string());
|
|
583
583
|
parseArgument(isStatusMessageTerminal, z.boolean().optional());
|
|
584
|
-
this.
|
|
584
|
+
this.ensureActorInit('setStatusMessage');
|
|
585
585
|
const loggedStatusMessage = `[Status message]: ${statusMessage}`;
|
|
586
586
|
switch (level) {
|
|
587
587
|
case 'DEBUG':
|
|
@@ -639,7 +639,7 @@ export class Actor {
|
|
|
639
639
|
* @ignore
|
|
640
640
|
*/
|
|
641
641
|
async pushData(item, eventName) {
|
|
642
|
-
this.
|
|
642
|
+
this.ensureActorInit('pushData');
|
|
643
643
|
if (eventName?.startsWith('apify-')) {
|
|
644
644
|
throw new Error(`Cannot charge for synthetic event '${eventName}' manually`);
|
|
645
645
|
}
|
|
@@ -674,7 +674,7 @@ export class Actor {
|
|
|
674
674
|
*/
|
|
675
675
|
async openDataset(datasetIdOrName, options = {}) {
|
|
676
676
|
parseArgument(options, z.object({ forceCloud: z.boolean().optional() }).strict());
|
|
677
|
-
this.
|
|
677
|
+
this.ensureActorInit('openDataset');
|
|
678
678
|
return Dataset.open(datasetIdOrName ?? null, {
|
|
679
679
|
storageBackend: options.forceCloud ? this.createApifyStorageBackend() : undefined,
|
|
680
680
|
});
|
|
@@ -708,7 +708,7 @@ export class Actor {
|
|
|
708
708
|
* @ignore
|
|
709
709
|
*/
|
|
710
710
|
async getValue(key) {
|
|
711
|
-
this.
|
|
711
|
+
this.ensureActorInit('getValue');
|
|
712
712
|
const store = await this.openKeyValueStore();
|
|
713
713
|
return store.getValue(key);
|
|
714
714
|
}
|
|
@@ -744,7 +744,7 @@ export class Actor {
|
|
|
744
744
|
* @ignore
|
|
745
745
|
*/
|
|
746
746
|
async setValue(key, value, options = {}) {
|
|
747
|
-
this.
|
|
747
|
+
this.ensureActorInit('setValue');
|
|
748
748
|
const store = await this.openKeyValueStore();
|
|
749
749
|
return store.setValue(key, value, options);
|
|
750
750
|
}
|
|
@@ -778,7 +778,7 @@ export class Actor {
|
|
|
778
778
|
* @ignore
|
|
779
779
|
*/
|
|
780
780
|
async getInput() {
|
|
781
|
-
this.
|
|
781
|
+
this.ensureActorInit('getInput');
|
|
782
782
|
const { inputSecretsPrivateKeyFile, inputSecretsPrivateKeyPassphrase } = this.configuration;
|
|
783
783
|
const rawInput = await this.getValue(this.configuration.inputKey);
|
|
784
784
|
let input = rawInput;
|
|
@@ -824,7 +824,7 @@ export class Actor {
|
|
|
824
824
|
*/
|
|
825
825
|
async openKeyValueStore(storeIdOrName, options = {}) {
|
|
826
826
|
parseArgument(options, z.object({ forceCloud: z.boolean().optional() }).strict());
|
|
827
|
-
this.
|
|
827
|
+
this.ensureActorInit('openKeyValueStore');
|
|
828
828
|
return KeyValueStore.open(storeIdOrName ?? null, {
|
|
829
829
|
storageBackend: options.forceCloud ? this.createApifyStorageBackend() : undefined,
|
|
830
830
|
});
|
|
@@ -850,7 +850,7 @@ export class Actor {
|
|
|
850
850
|
*/
|
|
851
851
|
async openRequestQueue(queueIdOrName, options = {}) {
|
|
852
852
|
parseArgument(options, z.object({ forceCloud: z.boolean().optional() }).strict());
|
|
853
|
-
this.
|
|
853
|
+
this.ensureActorInit('openRequestQueue');
|
|
854
854
|
return RequestQueue.open(queueIdOrName ?? null, {
|
|
855
855
|
storageBackend: options.forceCloud ? this.createApifyStorageBackend() : undefined,
|
|
856
856
|
});
|
|
@@ -928,16 +928,16 @@ export class Actor {
|
|
|
928
928
|
* @ignore
|
|
929
929
|
*/
|
|
930
930
|
async charge(options) {
|
|
931
|
-
this.
|
|
932
|
-
return this
|
|
931
|
+
this.ensureActorInit('charge');
|
|
932
|
+
return this.#chargingManager.charge(options);
|
|
933
933
|
}
|
|
934
934
|
/**
|
|
935
935
|
* Retrieve the charging manager to access granular pricing information.
|
|
936
936
|
* @ignore
|
|
937
937
|
*/
|
|
938
938
|
getChargingManager() {
|
|
939
|
-
this.
|
|
940
|
-
return this
|
|
939
|
+
this.ensureActorInit('getChargingManager');
|
|
940
|
+
return this.#chargingManager;
|
|
941
941
|
}
|
|
942
942
|
/**
|
|
943
943
|
* Modifies Actor env vars so parsing respects the structure of {@link ApifyEnv} interface.
|
|
@@ -1022,7 +1022,7 @@ export class Actor {
|
|
|
1022
1022
|
* @param options An optional object parameter where a custom `keyValueStoreName` and `config` can be passed in.
|
|
1023
1023
|
*/
|
|
1024
1024
|
async useState(name, defaultValue = {}, options) {
|
|
1025
|
-
this.
|
|
1025
|
+
this.ensureActorInit('useState');
|
|
1026
1026
|
const kvStore = await KeyValueStore.open(options?.keyValueStoreName, {
|
|
1027
1027
|
configuration: options?.configuration || Configuration.getGlobalConfiguration(),
|
|
1028
1028
|
});
|
|
@@ -1590,8 +1590,15 @@ export class Actor {
|
|
|
1590
1590
|
}
|
|
1591
1591
|
/** @internal */
|
|
1592
1592
|
static getDefaultInstance() {
|
|
1593
|
-
|
|
1594
|
-
return
|
|
1593
|
+
Actor.#instance ??= new Actor();
|
|
1594
|
+
return Actor.#instance;
|
|
1595
|
+
}
|
|
1596
|
+
/**
|
|
1597
|
+
* Replaces or clears the cached default instance returned by {@link Actor.getDefaultInstance}.
|
|
1598
|
+
* @internal
|
|
1599
|
+
*/
|
|
1600
|
+
static setDefaultInstance(instance) {
|
|
1601
|
+
Actor.#instance = instance;
|
|
1595
1602
|
}
|
|
1596
1603
|
usesPushDataInterception(dataset) {
|
|
1597
1604
|
return Boolean(dataset.backend[USES_PUSH_DATA_INTERCEPTION]);
|
|
@@ -1624,7 +1631,7 @@ export class Actor {
|
|
|
1624
1631
|
}
|
|
1625
1632
|
const isDefaultDataset = dataset.id === this.configuration.defaultDatasetId;
|
|
1626
1633
|
return pushDataAndCharge({
|
|
1627
|
-
chargingManager: this
|
|
1634
|
+
chargingManager: this.#chargingManager,
|
|
1628
1635
|
items,
|
|
1629
1636
|
eventName: explicitEventName,
|
|
1630
1637
|
isDefaultDataset,
|
|
@@ -1634,19 +1641,19 @@ export class Actor {
|
|
|
1634
1641
|
createApifyStorageBackend() {
|
|
1635
1642
|
return new ApifyStorageBackend(this.apifyClient, {
|
|
1636
1643
|
configuration: this.configuration,
|
|
1637
|
-
requestQueueAccess: this
|
|
1638
|
-
getChargingManager: () => this
|
|
1644
|
+
requestQueueAccess: this.#requestQueueAccess,
|
|
1645
|
+
getChargingManager: () => this.#chargingManager,
|
|
1639
1646
|
});
|
|
1640
1647
|
}
|
|
1641
|
-
|
|
1648
|
+
ensureActorInit(methodCalled) {
|
|
1642
1649
|
// If we already warned the user once, don't do it again to prevent spam
|
|
1643
|
-
if (this
|
|
1650
|
+
if (this.#warnedAboutMissingInitCall) {
|
|
1644
1651
|
return;
|
|
1645
1652
|
}
|
|
1646
1653
|
if (this.initialized) {
|
|
1647
1654
|
return;
|
|
1648
1655
|
}
|
|
1649
|
-
this
|
|
1656
|
+
this.#warnedAboutMissingInitCall = true;
|
|
1650
1657
|
log.warning([
|
|
1651
1658
|
`Actor.${methodCalled}() was called but the Actor instance was not initialized.`,
|
|
1652
1659
|
'Did you forget to call Actor.init()?',
|
|
@@ -9,7 +9,7 @@ import type { DatasetClient } from 'apify-client';
|
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
11
|
export declare class ApifyDatasetBackend implements DatasetBackend {
|
|
12
|
-
private
|
|
12
|
+
#private;
|
|
13
13
|
constructor(client: DatasetClient);
|
|
14
14
|
getMetadata(): Promise<DatasetInfo>;
|
|
15
15
|
drop(): Promise<void>;
|
|
@@ -13,19 +13,19 @@ const MAX_ITEM_BYTES = EFFECTIVE_LIMIT_BYTES - 2;
|
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
export class ApifyDatasetBackend {
|
|
16
|
-
client;
|
|
16
|
+
#client;
|
|
17
17
|
constructor(client) {
|
|
18
|
-
this
|
|
18
|
+
this.#client = client;
|
|
19
19
|
}
|
|
20
20
|
async getMetadata() {
|
|
21
|
-
const metadata = await this
|
|
21
|
+
const metadata = await this.#client.get();
|
|
22
22
|
if (!metadata) {
|
|
23
23
|
throw new Error('Dataset not found or has been deleted.');
|
|
24
24
|
}
|
|
25
25
|
return metadata;
|
|
26
26
|
}
|
|
27
27
|
async drop() {
|
|
28
|
-
await this
|
|
28
|
+
await this.#client.delete();
|
|
29
29
|
}
|
|
30
30
|
async purge() {
|
|
31
31
|
throw new Error('Purging a dataset is not supported on the Apify platform. ' +
|
|
@@ -36,11 +36,11 @@ export class ApifyDatasetBackend {
|
|
|
36
36
|
// that fit, pushed sequentially to preserve item order.
|
|
37
37
|
const payloads = items.map((item, index) => serializeToSizeLimit(item, index));
|
|
38
38
|
for (const chunk of chunkBySize(payloads, EFFECTIVE_LIMIT_BYTES)) {
|
|
39
|
-
await this
|
|
39
|
+
await this.#client.pushItems(chunk);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
async getData(options) {
|
|
43
|
-
return await this
|
|
43
|
+
return await this.#client.listItems(options);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
/** Serializes a dataset item, throwing if it alone exceeds the payload size limit. */
|
|
@@ -9,7 +9,7 @@ import type { KeyValueStoreClient } from 'apify-client';
|
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
11
|
export declare class ApifyKeyValueStoreBackend implements KeyValueStoreBackend {
|
|
12
|
-
private
|
|
12
|
+
#private;
|
|
13
13
|
constructor(client: KeyValueStoreClient);
|
|
14
14
|
getMetadata(): Promise<KeyValueStoreInfo>;
|
|
15
15
|
drop(): Promise<void>;
|
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
9
|
export class ApifyKeyValueStoreBackend {
|
|
10
|
-
client;
|
|
10
|
+
#client;
|
|
11
11
|
constructor(client) {
|
|
12
|
-
this
|
|
12
|
+
this.#client = client;
|
|
13
13
|
}
|
|
14
14
|
async getMetadata() {
|
|
15
|
-
const metadata = await this
|
|
15
|
+
const metadata = await this.#client.get();
|
|
16
16
|
if (!metadata) {
|
|
17
17
|
throw new Error('Key-value store not found or has been deleted.');
|
|
18
18
|
}
|
|
19
19
|
return metadata;
|
|
20
20
|
}
|
|
21
21
|
async drop() {
|
|
22
|
-
await this
|
|
22
|
+
await this.#client.delete();
|
|
23
23
|
}
|
|
24
24
|
async purge() {
|
|
25
25
|
throw new Error('Purging a key-value store is not supported on the Apify platform. ' +
|
|
@@ -28,16 +28,16 @@ export class ApifyKeyValueStoreBackend {
|
|
|
28
28
|
async getValue(key) {
|
|
29
29
|
// Storage backends are byte transports — the KeyValueStore frontend parses values
|
|
30
30
|
// according to their content type, so the record must be returned unparsed.
|
|
31
|
-
return this
|
|
31
|
+
return this.#client.getRecord(key, { buffer: true });
|
|
32
32
|
}
|
|
33
33
|
async setValue(record) {
|
|
34
|
-
await this
|
|
34
|
+
await this.#client.setRecord(record);
|
|
35
35
|
}
|
|
36
36
|
async deleteValue(key) {
|
|
37
|
-
await this
|
|
37
|
+
await this.#client.deleteRecord(key);
|
|
38
38
|
}
|
|
39
39
|
async listKeys(options) {
|
|
40
|
-
const result = await this
|
|
40
|
+
const result = await this.#client.listKeys(options);
|
|
41
41
|
// The API does not report a content type for listed keys; crawlee's item shape
|
|
42
42
|
// requires the field, so it is left undefined via the cast.
|
|
43
43
|
return {
|
|
@@ -46,9 +46,9 @@ export class ApifyKeyValueStoreBackend {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
async getPublicUrl(key) {
|
|
49
|
-
return this
|
|
49
|
+
return this.#client.getRecordPublicUrl(key);
|
|
50
50
|
}
|
|
51
51
|
async recordExists(key) {
|
|
52
|
-
return this
|
|
52
|
+
return this.#client.recordExists(key);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -104,11 +104,11 @@ export class ApifyRequestQueueBackend {
|
|
|
104
104
|
* @internal
|
|
105
105
|
*/
|
|
106
106
|
export class AsyncLock {
|
|
107
|
-
tail = Promise.resolve();
|
|
107
|
+
#tail = Promise.resolve();
|
|
108
108
|
async runExclusive(fn) {
|
|
109
|
-
const run = this
|
|
109
|
+
const run = this.#tail.then(fn);
|
|
110
110
|
// Keep the chain alive even when the critical section throws.
|
|
111
|
-
this
|
|
111
|
+
this.#tail = run.catch(() => { });
|
|
112
112
|
return run;
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -13,20 +13,7 @@ import { ApifyRequestQueueBackend } from './apify_request_queue_backend.js';
|
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
export declare class ApifyRequestQueueSharedBackend extends ApifyRequestQueueBackend {
|
|
16
|
-
|
|
17
|
-
private readonly headIds;
|
|
18
|
-
/** Dedup records for requests known to exist on the platform, keyed by id. */
|
|
19
|
-
private readonly cachedRequestInfo;
|
|
20
|
-
/** Ids of requests currently being processed by this client. */
|
|
21
|
-
private readonly inProgressIds;
|
|
22
|
-
/** Whether the last head read reported any locked requests left in the queue (any client's). */
|
|
23
|
-
private queueHasLockedRequests?;
|
|
24
|
-
/** Set after a forefront insert — the next head read starts fresh so the insert is honored. */
|
|
25
|
-
private shouldCheckForefrontRequests;
|
|
26
|
-
/** Lock duration applied to fetched requests; raised via `setExpectedRequestProcessingTimeSecs`. */
|
|
27
|
-
private lockSecs;
|
|
28
|
-
/** Serializes head reads and reclaims — both reorder the shared head state. */
|
|
29
|
-
private readonly headLock;
|
|
16
|
+
#private;
|
|
30
17
|
setExpectedRequestProcessingTimeSecs(secs: number): Promise<void>;
|
|
31
18
|
addBatchOfRequests(requests: RequestSchema[], options?: RequestQueueOperationOptions): Promise<BatchAddRequestsResult>;
|
|
32
19
|
getRequest(uniqueKey: string): Promise<UpdateRequestSchema | undefined>;
|