apify 4.0.0-beta.22 → 4.0.0-beta.24

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 CHANGED
@@ -5,6 +5,8 @@
5
5
  [![Chat on discord](https://img.shields.io/discord/801163717915574323?label=discord)](https://discord.gg/jyEM2PRvMU)
6
6
  [![Build Status](https://github.com/apify/apify-sdk-js/actions/workflows/test-and-release.yaml/badge.svg?branch=master)](https://github.com/apify/apify-sdk-js/actions/workflows/test-and-release.yaml)
7
7
 
8
+ `apify` is the official SDK for building [Apify Actors](https://docs.apify.com/platform/actors) in JavaScript and TypeScript. It handles the Actor lifecycle, storage access, platform events, proxy configuration, and more.
9
+
8
10
  ## Quick Start
9
11
 
10
12
  This short tutorial will set you up to start using Apify SDK in a minute or two.
@@ -33,7 +35,27 @@ await Actor.setValue('OUTPUT', {
33
35
  await Actor.exit();
34
36
  ```
35
37
 
36
- > You can also install the [`crawlee`](https://npmjs.org/crawlee) module, as it now provides the crawlers that were previously exported by Apify SDK. If you don't plan to use crawlers in your Actors, then you don't need to install it. Keep in mind that neither `playwright` nor `puppeteer` are bundled with `crawlee` in order to reduce install size and allow greater flexibility. That's why we manually install it with NPM. You can choose one, both, or neither. For more information and example please check [`documentation.`](https://docs.apify.com/sdk/js/docs/concepts/actor-lifecycle#running-crawlee-code-as-an-actor)
38
+ > You can also install the [`crawlee`](https://www.npmjs.com/package/crawlee) module, as it now provides the crawlers that were previously exported by Apify SDK. If you don't plan to use crawlers in your Actors, then you don't need to install it. Keep in mind that neither `playwright` nor `puppeteer` are bundled with `crawlee` in order to reduce install size and allow greater flexibility. That's why we manually install it with NPM. You can choose one, both, or neither. For more information and example please check [`documentation.`](https://docs.apify.com/sdk/js/docs/concepts/actor-lifecycle#running-crawlee-code-as-an-actor)
39
+
40
+ ## What are Actors?
41
+
42
+ Actors are serverless programs that can do almost anything. From simple scripts and web scrapers to complex automation workflows, AI agents, or even always-on services that expose HTTP endpoints.
43
+
44
+ They can run either locally or on the Apify platform, where you can scale their execution, monitor runs, schedule tasks, integrate them with other services, or even publish and monetize them. If you're new to Apify, learn more about the platform in the [Apify documentation](https://docs.apify.com/platform/about).
45
+
46
+ For more context, read the [Actor whitepaper](https://whitepaper.actor/).
47
+
48
+ ## What you can build
49
+
50
+ Almost any Node.js project can become an Actor, including projects for:
51
+
52
+ - **Web scraping and crawling** - The SDK works seamlessly with [Crawlee](https://crawlee.dev), which makes Apify a natural place to deploy and scale your crawlers. Start from a ready-made [Cheerio](https://apify.com/templates/js-crawlee-cheerio) template.
53
+ - **Browser automation** - Drive a real browser with [Playwright](https://playwright.dev), [Puppeteer](https://pptr.dev), or [Selenium](https://apify.com/apify/example-selenium) to automate tasks, fill in forms, or test web apps.
54
+ - **AI agents** - Host agents built with your framework of choice. Ready-made Actor templates cover [LangChain](https://apify.com/templates/js-langchain), [LangGraph](https://apify.com/templates/js-langgraph-agent), [BeeAI](https://apify.com/templates/ts-beeai-agent), and [Mastra](https://apify.com/templates/ts-mastraai).
55
+ - **MCP servers** - Deploy an MCP server as an Actor and make its tools available to any MCP client. See the [MCP server](https://apify.com/templates/ts-mcp-empty) and [MCP proxy](https://apify.com/templates/ts-mcp-proxy) templates.
56
+ - **Web servers and APIs** - Run a web server inside an Actor to serve HTTP requests, for example to expose your scraper as a live API. See the [Standby](https://apify.com/templates/js-standby) templates.
57
+
58
+ Whatever you build, the Apify SDK doesn't lock you into a particular framework. Bring the libraries you already use, and let Apify run your project in the cloud.
37
59
 
38
60
  ## Support
39
61
 
package/dist/actor.d.ts CHANGED
@@ -180,7 +180,7 @@ export interface ApifyEnv {
180
180
  logLevel: string | null;
181
181
  logFormat: string | null;
182
182
  /**
183
- * Origin for the Actor run, i.e. how it was started. See [here](https://docs.apify.com/sdk/python/reference/enum/MetaOrigin)
183
+ * Origin for the Actor run, i.e. how it was started. See [here](https://docs.apify.com/platform/actors/running/runs-and-builds#origin)
184
184
  * for more details. (APIFY_META_ORIGIN)
185
185
  */
186
186
  metaOrigin: string | null;
@@ -1393,9 +1393,12 @@ export declare class Actor<Data extends Dictionary = Dictionary> {
1393
1393
  private createApifyStorageBackend;
1394
1394
  private _ensureActorInit;
1395
1395
  /**
1396
- * Get time remaining from the Actor run timeout. Returns `undefined` if not on an Apify platform or the current
1397
- * run was started without a timeout.
1396
+ * Get time remaining from the Actor run timeout in seconds, rounded up to whole seconds with minimum value of 1 second.
1397
+ *
1398
+ * The API treats a 0 second timeout as no timeout, the minimum acceptable timeout is 1 second.
1399
+ *
1400
+ * Returns `undefined` if not on the Apify platform or the current run was started without a timeout.
1398
1401
  */
1399
- private getRemainingTime;
1402
+ private getRemainingTimeSecs;
1400
1403
  private inferDefaultsFromInputSchema;
1401
1404
  }
package/dist/actor.js CHANGED
@@ -367,7 +367,7 @@ export class Actor {
367
367
  * @ignore
368
368
  */
369
369
  async call(actorId, input, options = {}) {
370
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
370
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
371
371
  const { token, ...rest } = options;
372
372
  const client = token ? this.newClient({ token }) : this.apifyClient;
373
373
  return client.actor(actorId).call(input, { ...rest, timeout });
@@ -397,7 +397,7 @@ export class Actor {
397
397
  * @ignore
398
398
  */
399
399
  async start(actorId, input, options = {}) {
400
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
400
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
401
401
  const { token, ...rest } = options;
402
402
  const client = token ? this.newClient({ token }) : this.apifyClient;
403
403
  return client.actor(actorId).start(input, { ...rest, timeout });
@@ -454,7 +454,7 @@ export class Actor {
454
454
  * @ignore
455
455
  */
456
456
  async callTask(taskId, input, options = {}) {
457
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
457
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
458
458
  const { token, ...rest } = options;
459
459
  const client = token ? this.newClient({ token }) : this.apifyClient;
460
460
  return client.task(taskId).call(input, { ...rest, timeout });
@@ -1641,13 +1641,17 @@ export class Actor {
1641
1641
  ].join('\n'));
1642
1642
  }
1643
1643
  /**
1644
- * Get time remaining from the Actor run timeout. Returns `undefined` if not on an Apify platform or the current
1645
- * run was started without a timeout.
1644
+ * Get time remaining from the Actor run timeout in seconds, rounded up to whole seconds with minimum value of 1 second.
1645
+ *
1646
+ * The API treats a 0 second timeout as no timeout, the minimum acceptable timeout is 1 second.
1647
+ *
1648
+ * Returns `undefined` if not on the Apify platform or the current run was started without a timeout.
1646
1649
  */
1647
- getRemainingTime() {
1650
+ getRemainingTimeSecs() {
1648
1651
  const env = this.getEnv();
1652
+ const MINIMUM_API_TIMEOUT_SECS = 1;
1649
1653
  if (this.isAtHome() && env.timeoutAt !== null) {
1650
- return env.timeoutAt.getTime() - Date.now();
1654
+ return Math.max(Math.ceil((env.timeoutAt.getTime() - Date.now()) / 1000), MINIMUM_API_TIMEOUT_SECS);
1651
1655
  }
1652
1656
  log.warning('Using `inherit` argument is only possible when the Actor is running on the Apify platform and when the ' +
1653
1657
  'timeout for the Actor run is set.');
@@ -76,6 +76,11 @@ export declare class ChargingManager {
76
76
  */
77
77
  init(): Promise<void>;
78
78
  private ensureChargingLogDatasetOnPlatform;
79
+ /**
80
+ * Whether {@link ChargingManager.init} has run. All charging operations (including
81
+ * {@link ChargingManager.getPricingInfo}) require an initialized manager.
82
+ */
83
+ get isInitialized(): boolean;
79
84
  /**
80
85
  * Get information about the pricing for this Actor.
81
86
  */
package/dist/charging.js CHANGED
@@ -133,6 +133,13 @@ export class ChargingManager {
133
133
  await defaultStore.setValue(this.PLATFORM_CHARGING_LOG_DATASET_ID_KEY, dataset.id);
134
134
  return dataset.id;
135
135
  }
136
+ /**
137
+ * Whether {@link ChargingManager.init} has run. All charging operations (including
138
+ * {@link ChargingManager.getPricingInfo}) require an initialized manager.
139
+ */
140
+ get isInitialized() {
141
+ return this.chargingState !== undefined;
142
+ }
136
143
  /**
137
144
  * Get information about the pricing for this Actor.
138
145
  */
@@ -110,7 +110,7 @@ export interface Configuration extends ApifyResolvedConfigValues {
110
110
  * `actorId` | `ACTOR_ID` | -
111
111
  * `actorRunId` | `ACTOR_RUN_ID` | -
112
112
  * `actorTaskId` | `ACTOR_TASK_ID` | -
113
- * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com'`
113
+ * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com/'`
114
114
  * `containerPort` | `ACTOR_WEB_SERVER_PORT` | `4321`
115
115
  * `containerUrl` | `ACTOR_WEB_SERVER_URL` | `'http://localhost:4321'`
116
116
  * `inputKey` | `ACTOR_INPUT_KEY` | `'INPUT'`
@@ -49,7 +49,7 @@ export const apifyConfigFields = {
49
49
  actorId: field(z.string().optional(), [ACTOR_ENV_VARS.ID, APIFY_ENV_VARS.ACTOR_ID]),
50
50
  actorRunId: field(z.string().optional(), [ACTOR_ENV_VARS.RUN_ID, APIFY_ENV_VARS.ACTOR_RUN_ID]),
51
51
  actorTaskId: field(z.string().optional(), [ACTOR_ENV_VARS.TASK_ID, APIFY_ENV_VARS.ACTOR_TASK_ID]),
52
- apiBaseUrl: field(z.string().default('https://api.apify.com'), APIFY_ENV_VARS.API_BASE_URL),
52
+ apiBaseUrl: field(z.string().default('https://api.apify.com/'), APIFY_ENV_VARS.API_BASE_URL),
53
53
  apiPublicBaseUrl: field(z.string().default('https://api.apify.com'), APIFY_ENV_VARS.API_PUBLIC_BASE_URL),
54
54
  containerPort: field(coerceNumber.default(+LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.WEB_SERVER_PORT]), [
55
55
  ACTOR_ENV_VARS.WEB_SERVER_PORT,
@@ -136,7 +136,7 @@ export const apifyConfigFields = {
136
136
  * `actorId` | `ACTOR_ID` | -
137
137
  * `actorRunId` | `ACTOR_RUN_ID` | -
138
138
  * `actorTaskId` | `ACTOR_TASK_ID` | -
139
- * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com'`
139
+ * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com/'`
140
140
  * `containerPort` | `ACTOR_WEB_SERVER_PORT` | `4321`
141
141
  * `containerUrl` | `ACTOR_WEB_SERVER_URL` | `'http://localhost:4321'`
142
142
  * `inputKey` | `ACTOR_INPUT_KEY` | `'INPUT'`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apify",
3
- "version": "4.0.0-beta.22",
3
+ "version": "4.0.0-beta.24",
4
4
  "description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -57,11 +57,11 @@
57
57
  "@apify/datastructures": "^2.0.3",
58
58
  "@apify/input_secrets": "^1.2.0",
59
59
  "@apify/log": "^2.4.3",
60
- "@apify/timeout": "^0.3.0",
60
+ "@apify/timeout": "^0.4.0",
61
61
  "@apify/utilities": "^2.13.0",
62
- "@crawlee/core": "^4.0.0-beta.105",
63
- "@crawlee/types": "^4.0.0-beta.105",
64
- "@crawlee/utils": "^4.0.0-beta.105",
62
+ "@crawlee/core": "^4.0.0-beta.115",
63
+ "@crawlee/types": "^4.0.0-beta.115",
64
+ "@crawlee/utils": "^4.0.0-beta.115",
65
65
  "apify-client": "^2.23.4",
66
66
  "semver": "^7.5.4",
67
67
  "tslib": "^2.6.2",
@@ -69,8 +69,8 @@
69
69
  "zod": "^4.0.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@apify/oxlint-config": "^0.2.5",
73
- "@apify/tsconfig": "^0.1.2",
72
+ "@apify/oxlint-config": "^0.3.0",
73
+ "@apify/tsconfig": "^0.2.0",
74
74
  "@commitlint/config-conventional": "^21.0.0",
75
75
  "@playwright/browser-chromium": "^1.60.0",
76
76
  "@types/content-type": "^1.1.8",
@@ -79,12 +79,12 @@
79
79
  "@types/tough-cookie": "^4.0.5",
80
80
  "@types/ws": "^8.5.12",
81
81
  "commitlint": "^21.0.0",
82
- "crawlee": "^4.0.0-beta.105",
82
+ "crawlee": "^4.0.0-beta.115",
83
83
  "globby": "^16.0.0",
84
84
  "husky": "^9.1.7",
85
85
  "lint-staged": "^17.0.0",
86
- "oxfmt": "0.52.0",
87
- "oxlint": "1.67.0",
86
+ "oxfmt": "0.63.0",
87
+ "oxlint": "1.78.0",
88
88
  "oxlint-tsgolint": "0.22.0",
89
89
  "playwright": "^1.60.0",
90
90
  "puppeteer": "^25.0.0",