@solarisdk/browser 0.1.7 → 0.2.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 +18 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
Official client SDK for [Solari Browser](https://getsolari.com) — managed,
|
|
4
4
|
stealth-hardened browsers as an API.
|
|
5
5
|
|
|
6
|
+
Feature coverage across all five languages is on the
|
|
7
|
+
[SDK feature matrix](https://docs.getsolari.com/sdk-capabilities).
|
|
8
|
+
|
|
6
9
|
## Install
|
|
7
10
|
|
|
8
11
|
```bash
|
|
@@ -55,6 +58,21 @@ const session = await solari.sessions.create();
|
|
|
55
58
|
const browser = await chromium.connectOverCDP(session.cdpEndpoint);
|
|
56
59
|
```
|
|
57
60
|
|
|
61
|
+
### Timeout, keep-alive and metadata
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const session = await solari.sessions.create({
|
|
65
|
+
sessionTimeoutMs: 600_000, // end earlier than the plan maximum, in ms (at least 60 000)
|
|
66
|
+
keepAlive: true, // hold the session if the client drops, until its deadline or release
|
|
67
|
+
userMetadata: { job: "nightly-42" }, // stored with the session
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Every duration option is in milliseconds. `sessionTimeoutMs` is rounded up to whole
|
|
72
|
+
seconds for the gateway (1001 ms is 2 s); the gateway refuses anything under 60 s;
|
|
73
|
+
zero or unset leaves the plan maximum, and a negative, `NaN`, `Infinity` or
|
|
74
|
+
fractional value throws before any request. `launch()` accepts the same options.
|
|
75
|
+
|
|
58
76
|
## Regions
|
|
59
77
|
|
|
60
78
|
Solari runs in `us-west` (N. California) today, with additional regions
|
package/dist/index.d.ts
CHANGED
|
@@ -88,6 +88,8 @@ export interface Session {
|
|
|
88
88
|
/** Present only when a managed proxy was requested. Confirmation only
|
|
89
89
|
* (country/tier/timezone) — egress is applied server-side. */
|
|
90
90
|
proxy?: ResolvedProxyConfig;
|
|
91
|
+
/** Echo of the `userMetadata` sent at create; absent when none was sent. */
|
|
92
|
+
userMetadata?: Record<string, unknown>;
|
|
91
93
|
}
|
|
92
94
|
export interface Profile {
|
|
93
95
|
id: string;
|
|
@@ -114,6 +116,17 @@ export interface CreateSessionOptions {
|
|
|
114
116
|
* proxy: "off"
|
|
115
117
|
*/
|
|
116
118
|
proxy?: string | ProxyRequest | "off" | "smart";
|
|
119
|
+
/** End the session earlier than the plan maximum, in milliseconds. The gateway
|
|
120
|
+
* counts whole seconds, so the value is rounded up (1001 ms is 2 s), and it
|
|
121
|
+
* refuses anything under 60 s (400). Zero/undefined leaves the plan maximum;
|
|
122
|
+
* a negative, NaN, Infinity or non-integer value throws. */
|
|
123
|
+
sessionTimeoutMs?: number;
|
|
124
|
+
/** Hold the session after the client disconnects, until its deadline
|
|
125
|
+
* (`sessionTimeoutMs`, else an hour, never past the plan maximum) or until
|
|
126
|
+
* it is released, so a dropped client can reconnect. */
|
|
127
|
+
keepAlive?: boolean;
|
|
128
|
+
/** Free-form JSON object stored with the session (labels, job ids, ...). */
|
|
129
|
+
userMetadata?: Record<string, unknown>;
|
|
117
130
|
}
|
|
118
131
|
export interface ReplayUrl {
|
|
119
132
|
url: string;
|
package/dist/index.js
CHANGED
|
@@ -60,6 +60,19 @@ const DEFAULT_TIMEOUT_MS = 90_000;
|
|
|
60
60
|
// transient, and a client's correctness must not depend on which gateway
|
|
61
61
|
// build it reaches. Inert today, and deliberately so — do not delete it as
|
|
62
62
|
// dead code.
|
|
63
|
+
/**
|
|
64
|
+
* The gateway's `timeoutSeconds` for a `sessionTimeoutMs`: rounded UP to whole
|
|
65
|
+
* seconds (1001 -> 2). Zero/undefined means "omit". Throws for a negative, NaN,
|
|
66
|
+
* Infinity or non-integer value. Not clamped: the gateway still answers 400 under 60 s.
|
|
67
|
+
*/
|
|
68
|
+
function sessionTimeoutSeconds(ms) {
|
|
69
|
+
if (ms === undefined || ms === 0)
|
|
70
|
+
return undefined;
|
|
71
|
+
if (typeof ms !== "number" || !Number.isInteger(ms) || ms < 0) {
|
|
72
|
+
throw new SolariError(`Solari: sessionTimeoutMs must be a non-negative integer number of milliseconds, got ${String(ms)}`);
|
|
73
|
+
}
|
|
74
|
+
return Math.ceil(ms / 1000);
|
|
75
|
+
}
|
|
63
76
|
function isRetryableStatus(status) {
|
|
64
77
|
return status === 502 || status === 503 || status === 504 || status === 507;
|
|
65
78
|
}
|
|
@@ -290,6 +303,13 @@ class SessionsResource {
|
|
|
290
303
|
body.captcha = true;
|
|
291
304
|
if (options?.proxy !== undefined)
|
|
292
305
|
body.proxy = options.proxy;
|
|
306
|
+
const timeoutSeconds = sessionTimeoutSeconds(options?.sessionTimeoutMs);
|
|
307
|
+
if (timeoutSeconds !== undefined)
|
|
308
|
+
body.timeoutSeconds = timeoutSeconds;
|
|
309
|
+
if (options?.keepAlive === true)
|
|
310
|
+
body.keepAlive = true;
|
|
311
|
+
if (options?.userMetadata !== undefined)
|
|
312
|
+
body.userMetadata = options.userMetadata;
|
|
293
313
|
// A create allocates a slot and launches a browser before it can answer,
|
|
294
314
|
// so a response lost after that point makes a retry a SECOND session.
|
|
295
315
|
// The key lets the gateway answer the retry from the first result.
|
|
@@ -331,6 +351,9 @@ class SessionsResource {
|
|
|
331
351
|
if (data.proxy) {
|
|
332
352
|
session.proxy = data.proxy;
|
|
333
353
|
}
|
|
354
|
+
if (data.userMetadata) {
|
|
355
|
+
session.userMetadata = data.userMetadata;
|
|
356
|
+
}
|
|
334
357
|
return session;
|
|
335
358
|
}
|
|
336
359
|
/** Fire-and-forget release. Use `releaseAndWait` for confirmation. */
|