browser-use-sdk 1.1.3 → 1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 (2025-08-22)
4
+
5
+ Full Changelog: [v1.1.3...v1.2.0](https://github.com/browser-use/browser-use-node/compare/v1.1.3...v1.2.0)
6
+
7
+ ### Features
8
+
9
+ * NextJS Utils ([b5e1006](https://github.com/browser-use/browser-use-node/commit/b5e10060a064de9a9454fa90e461f09154094742))
10
+
3
11
  ## 1.1.3 (2025-08-22)
4
12
 
5
13
  Full Changelog: [v1.1.2...v1.1.3](https://github.com/browser-use/browser-use-node/compare/v1.1.2...v1.1.3)
package/README.md CHANGED
@@ -121,6 +121,8 @@ export async function POST(req: Request) {
121
121
  }
122
122
  ```
123
123
 
124
+ ## Advanced Usage
125
+
124
126
  ## Handling errors
125
127
 
126
128
  When the library is unable to connect to the API,
@@ -197,8 +199,6 @@ On timeout, an `APIConnectionTimeoutError` is thrown.
197
199
 
198
200
  Note that requests which time out will be [retried twice by default](#retries).
199
201
 
200
- ## Advanced Usage
201
-
202
202
  ### Accessing raw Response data (e.g., headers)
203
203
 
204
204
  The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
@@ -277,49 +277,6 @@ const client = new BrowserUse({
277
277
  });
278
278
  ```
279
279
 
280
- ### Making custom/undocumented requests
281
-
282
- This library is typed for convenient access to the documented API. If you need to access undocumented
283
- endpoints, params, or response properties, the library can still be used.
284
-
285
- #### Undocumented endpoints
286
-
287
- To make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.
288
- Options on the client, such as retries, will be respected when making these requests.
289
-
290
- ```ts
291
- await client.post('/some/path', {
292
- body: { some_prop: 'foo' },
293
- query: { some_query_arg: 'bar' },
294
- });
295
- ```
296
-
297
- #### Undocumented request params
298
-
299
- To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
300
- parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
301
- send will be sent as-is.
302
-
303
- ```ts
304
- client.tasks.create({
305
- // ...
306
- // @ts-expect-error baz is not yet public
307
- baz: 'undocumented option',
308
- });
309
- ```
310
-
311
- For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
312
- extra param in the body.
313
-
314
- If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
315
- options.
316
-
317
- #### Undocumented response properties
318
-
319
- To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
320
- the response object, or cast the response object to the requisite type. Like the request params, we do not
321
- validate or strip extra properties from the response from the API.
322
-
323
280
  ### Customizing the fetch client
324
281
 
325
282
  By default, this library expects a global `fetch` function is defined.
@@ -401,18 +358,6 @@ const client = new BrowserUse({
401
358
 
402
359
  ## Frequently Asked Questions
403
360
 
404
- ## Semantic versioning
405
-
406
- This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
407
-
408
- 1. Changes that only affect static types, without breaking runtime behavior.
409
- 2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
410
- 3. Changes that we do not expect to impact the vast majority of users in practice.
411
-
412
- We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
413
-
414
- We are keen for your feedback; please open an [issue](https://www.github.com/browser-use/browser-use-node/issues) with questions, bugs, or suggestions.
415
-
416
361
  ## Requirements
417
362
 
418
363
  TypeScript >= 4.9 is supported.
@@ -0,0 +1,7 @@
1
+ import type { ZodType } from 'zod';
2
+ import { TaskViewWithSchema } from "../../parse.mjs";
3
+ /**
4
+ * A hook to stream Browser Use updates to the client.
5
+ */
6
+ export declare function useBrowserUse<T extends ZodType = ZodType>(route: string): TaskViewWithSchema<T> | null;
7
+ //# sourceMappingURL=useBrowserUse.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrowserUse.d.mts","sourceRoot":"","sources":["../../../src/lib/nextjs/hooks/useBrowserUse.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK;OAG3B,EAAE,kBAAkB,EAAE;AAE7B;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CA2BtG"}
@@ -0,0 +1,7 @@
1
+ import type { ZodType } from 'zod';
2
+ import { TaskViewWithSchema } from "../../parse.js";
3
+ /**
4
+ * A hook to stream Browser Use updates to the client.
5
+ */
6
+ export declare function useBrowserUse<T extends ZodType = ZodType>(route: string): TaskViewWithSchema<T> | null;
7
+ //# sourceMappingURL=useBrowserUse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrowserUse.d.ts","sourceRoot":"","sources":["../../../src/lib/nextjs/hooks/useBrowserUse.ts"],"names":[],"mappings":"OACO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK;OAG3B,EAAE,kBAAkB,EAAE;AAE7B;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CA2BtG"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useBrowserUse = useBrowserUse;
4
+ const react_1 = require("react");
5
+ /**
6
+ * A hook to stream Browser Use updates to the client.
7
+ */
8
+ function useBrowserUse(route) {
9
+ const [status, setStatus] = (0, react_1.useState)(null);
10
+ (0, react_1.useEffect)(() => {
11
+ const es = new EventSource(route);
12
+ es.addEventListener('status', (e) => {
13
+ if (e instanceof MessageEvent) {
14
+ const msg = JSON.parse(e.data);
15
+ setStatus(msg.data);
16
+ if (msg.data.status === 'finished') {
17
+ es.close();
18
+ }
19
+ }
20
+ else {
21
+ console.error('Event is not a MessageEvent', e);
22
+ }
23
+ });
24
+ es.addEventListener('end', () => es.close());
25
+ es.addEventListener('error', () => es.close());
26
+ return () => es.close();
27
+ }, [route]);
28
+ return status;
29
+ }
30
+ //# sourceMappingURL=useBrowserUse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrowserUse.js","sourceRoot":"","sources":["../../../src/lib/nextjs/hooks/useBrowserUse.ts"],"names":[],"mappings":";;AASA,sCA2BC;AApCD,iCAA4C;AAM5C;;GAEG;AACH,SAAgB,aAAa,CAA8B,KAAa;IACtE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAA+B,IAAI,CAAC,CAAC;IAEzE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;QAElC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YAClC,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;gBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAuB,CAAC;gBAErD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAEpB,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACnC,EAAE,CAAC,KAAK,EAAE,CAAC;gBACb,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7C,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAE/C,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from 'react';
2
+ /**
3
+ * A hook to stream Browser Use updates to the client.
4
+ */
5
+ export function useBrowserUse(route) {
6
+ const [status, setStatus] = useState(null);
7
+ useEffect(() => {
8
+ const es = new EventSource(route);
9
+ es.addEventListener('status', (e) => {
10
+ if (e instanceof MessageEvent) {
11
+ const msg = JSON.parse(e.data);
12
+ setStatus(msg.data);
13
+ if (msg.data.status === 'finished') {
14
+ es.close();
15
+ }
16
+ }
17
+ else {
18
+ console.error('Event is not a MessageEvent', e);
19
+ }
20
+ });
21
+ es.addEventListener('end', () => es.close());
22
+ es.addEventListener('error', () => es.close());
23
+ return () => es.close();
24
+ }, [route]);
25
+ return status;
26
+ }
27
+ //# sourceMappingURL=useBrowserUse.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrowserUse.mjs","sourceRoot":"","sources":["../../../src/lib/nextjs/hooks/useBrowserUse.ts"],"names":[],"mappings":"OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO;AAM3C;;GAEG;AACH,MAAM,UAAU,aAAa,CAA8B,KAAa;IACtE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAA+B,IAAI,CAAC,CAAC;IAEzE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC;QAElC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YAClC,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;gBAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAuB,CAAC;gBAErD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAEpB,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACnC,EAAE,CAAC,KAAK,EAAE,CAAC;gBACb,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7C,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAE/C,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { TaskViewWithSchema } from "../../parse.mjs";
2
+ import { ZodType } from 'zod';
3
+ export type BrowserUseEvent<T extends ZodType = ZodType> = {
4
+ event: 'status';
5
+ data: TaskViewWithSchema<T>;
6
+ };
7
+ /**
8
+ * Convert an async generator to a stream.
9
+ *
10
+ * @param gen - The async generator to convert to a stream.
11
+ * @returns A stream of the async generator.
12
+ */
13
+ export declare function gtos(gen: AsyncGenerator<{
14
+ event: 'status';
15
+ data: TaskViewWithSchema<ZodType>;
16
+ }>, opts?: {
17
+ /**
18
+ * Called when an event is emitted.
19
+ */
20
+ onEvent?: (event: TaskViewWithSchema<ZodType>) => void;
21
+ /**
22
+ * Called when the task is finished.
23
+ */
24
+ onFinished?: (event: TaskViewWithSchema<ZodType>) => void;
25
+ }): ReadableStream<Uint8Array<ArrayBufferLike>>;
26
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/lib/nextjs/server/utils.ts"],"names":[],"mappings":"OAAO,EAAE,kBAAkB,EAAE;OACtB,EAAE,OAAO,EAAE,MAAM,KAAK;AAE7B,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI;IACzD,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,cAAc,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC,EACF,IAAI,CAAC,EAAE;IACL;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAEvD;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;CAC3D,GACA,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAsC7C"}
@@ -0,0 +1,26 @@
1
+ import { TaskViewWithSchema } from "../../parse.js";
2
+ import { ZodType } from 'zod';
3
+ export type BrowserUseEvent<T extends ZodType = ZodType> = {
4
+ event: 'status';
5
+ data: TaskViewWithSchema<T>;
6
+ };
7
+ /**
8
+ * Convert an async generator to a stream.
9
+ *
10
+ * @param gen - The async generator to convert to a stream.
11
+ * @returns A stream of the async generator.
12
+ */
13
+ export declare function gtos(gen: AsyncGenerator<{
14
+ event: 'status';
15
+ data: TaskViewWithSchema<ZodType>;
16
+ }>, opts?: {
17
+ /**
18
+ * Called when an event is emitted.
19
+ */
20
+ onEvent?: (event: TaskViewWithSchema<ZodType>) => void;
21
+ /**
22
+ * Called when the task is finished.
23
+ */
24
+ onFinished?: (event: TaskViewWithSchema<ZodType>) => void;
25
+ }): ReadableStream<Uint8Array<ArrayBufferLike>>;
26
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/lib/nextjs/server/utils.ts"],"names":[],"mappings":"OAAO,EAAE,kBAAkB,EAAE;OACtB,EAAE,OAAO,EAAE,MAAM,KAAK;AAE7B,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI;IACzD,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,cAAc,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACnC,CAAC,EACF,IAAI,CAAC,EAAE;IACL;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAEvD;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;CAC3D,GACA,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAsC7C"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gtos = gtos;
4
+ /**
5
+ * Convert an async generator to a stream.
6
+ *
7
+ * @param gen - The async generator to convert to a stream.
8
+ * @returns A stream of the async generator.
9
+ */
10
+ function gtos(gen, opts) {
11
+ const enc = new TextEncoder();
12
+ const stream = new ReadableStream({
13
+ async start(controller) {
14
+ // open the SSE stream quickly
15
+ controller.enqueue(enc.encode(': connected\n\n'));
16
+ try {
17
+ for await (const msg of gen) {
18
+ opts?.onEvent?.(msg.data);
19
+ const data = {
20
+ event: msg.event,
21
+ data: msg.data,
22
+ };
23
+ const encoded = JSON.stringify(data);
24
+ const payload = `event: ${msg.event}\ndata: ${encoded}\n\n`;
25
+ controller.enqueue(enc.encode(payload));
26
+ if (msg.data.status === 'finished') {
27
+ opts?.onFinished?.(msg.data);
28
+ }
29
+ }
30
+ controller.enqueue(enc.encode('event: end\ndata: {}\n\n'));
31
+ }
32
+ catch (e) {
33
+ controller.enqueue(enc.encode(`event: error\ndata: ${JSON.stringify({ message: String(e) })}\n\n`));
34
+ }
35
+ finally {
36
+ controller.close();
37
+ }
38
+ },
39
+ });
40
+ return stream;
41
+ }
42
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lib/nextjs/server/utils.ts"],"names":[],"mappings":";;AAcA,oBAsDC;AA5DD;;;;;GAKG;AACH,SAAgB,IAAI,CAClB,GAGE,EACF,IAUC;IAED,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAG,IAAI,cAAc,CAAa;QAC5C,KAAK,CAAC,KAAK,CAAC,UAAU;YACpB,8BAA8B;YAC9B,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAElD,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBAC5B,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAE1B,MAAM,IAAI,GAAoB;wBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;wBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;qBACf,CAAC;oBAEF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAErC,MAAM,OAAO,GAAG,UAAU,GAAG,CAAC,KAAK,WAAW,OAAO,MAAM,CAAC;oBAE5D,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;oBAExC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;wBACnC,IAAI,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBAED,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YACtG,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Convert an async generator to a stream.
3
+ *
4
+ * @param gen - The async generator to convert to a stream.
5
+ * @returns A stream of the async generator.
6
+ */
7
+ export function gtos(gen, opts) {
8
+ const enc = new TextEncoder();
9
+ const stream = new ReadableStream({
10
+ async start(controller) {
11
+ // open the SSE stream quickly
12
+ controller.enqueue(enc.encode(': connected\n\n'));
13
+ try {
14
+ for await (const msg of gen) {
15
+ opts?.onEvent?.(msg.data);
16
+ const data = {
17
+ event: msg.event,
18
+ data: msg.data,
19
+ };
20
+ const encoded = JSON.stringify(data);
21
+ const payload = `event: ${msg.event}\ndata: ${encoded}\n\n`;
22
+ controller.enqueue(enc.encode(payload));
23
+ if (msg.data.status === 'finished') {
24
+ opts?.onFinished?.(msg.data);
25
+ }
26
+ }
27
+ controller.enqueue(enc.encode('event: end\ndata: {}\n\n'));
28
+ }
29
+ catch (e) {
30
+ controller.enqueue(enc.encode(`event: error\ndata: ${JSON.stringify({ message: String(e) })}\n\n`));
31
+ }
32
+ finally {
33
+ controller.close();
34
+ }
35
+ },
36
+ });
37
+ return stream;
38
+ }
39
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../../src/lib/nextjs/server/utils.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAClB,GAGE,EACF,IAUC;IAED,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAE9B,MAAM,MAAM,GAAG,IAAI,cAAc,CAAa;QAC5C,KAAK,CAAC,KAAK,CAAC,UAAU;YACpB,8BAA8B;YAC9B,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAElD,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;oBAC5B,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAE1B,MAAM,IAAI,GAAoB;wBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;wBAChB,IAAI,EAAE,GAAG,CAAC,IAAI;qBACf,CAAC;oBAEF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAErC,MAAM,OAAO,GAAG,UAAU,GAAG,CAAC,KAAK,WAAW,OAAO,MAAM,CAAC;oBAE5D,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;oBAExC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;wBACnC,IAAI,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;gBAED,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YACtG,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-use-sdk",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "The official TypeScript library for the Browser Use API",
5
5
  "author": "Browser Use <support@browser-use.com>",
6
6
  "types": "./index.d.ts",
@@ -34,7 +34,8 @@
34
34
  "fast-json-stable-stringify": "^2.1.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "zod": "^4.0.17"
37
+ "react": "^18 || ^19",
38
+ "zod": "^4"
38
39
  },
39
40
  "exports": {
40
41
  ".": {
@@ -0,0 +1,37 @@
1
+ import { useEffect, useState } from 'react';
2
+ import type { ZodType } from 'zod';
3
+
4
+ import type { BrowserUseEvent } from '../server/utils';
5
+ import { TaskViewWithSchema } from '../../parse';
6
+
7
+ /**
8
+ * A hook to stream Browser Use updates to the client.
9
+ */
10
+ export function useBrowserUse<T extends ZodType = ZodType>(route: string): TaskViewWithSchema<T> | null {
11
+ const [status, setStatus] = useState<TaskViewWithSchema<T> | null>(null);
12
+
13
+ useEffect(() => {
14
+ const es = new EventSource(route);
15
+
16
+ es.addEventListener('status', (e) => {
17
+ if (e instanceof MessageEvent) {
18
+ const msg = JSON.parse(e.data) as BrowserUseEvent<T>;
19
+
20
+ setStatus(msg.data);
21
+
22
+ if (msg.data.status === 'finished') {
23
+ es.close();
24
+ }
25
+ } else {
26
+ console.error('Event is not a MessageEvent', e);
27
+ }
28
+ });
29
+
30
+ es.addEventListener('end', () => es.close());
31
+ es.addEventListener('error', () => es.close());
32
+
33
+ return () => es.close();
34
+ }, [route]);
35
+
36
+ return status;
37
+ }
@@ -0,0 +1,69 @@
1
+ import { TaskViewWithSchema } from '../../parse';
2
+ import { ZodType } from 'zod';
3
+
4
+ export type BrowserUseEvent<T extends ZodType = ZodType> = {
5
+ event: 'status';
6
+ data: TaskViewWithSchema<T>;
7
+ };
8
+
9
+ /**
10
+ * Convert an async generator to a stream.
11
+ *
12
+ * @param gen - The async generator to convert to a stream.
13
+ * @returns A stream of the async generator.
14
+ */
15
+ export function gtos(
16
+ gen: AsyncGenerator<{
17
+ event: 'status';
18
+ data: TaskViewWithSchema<ZodType>;
19
+ }>,
20
+ opts?: {
21
+ /**
22
+ * Called when an event is emitted.
23
+ */
24
+ onEvent?: (event: TaskViewWithSchema<ZodType>) => void;
25
+
26
+ /**
27
+ * Called when the task is finished.
28
+ */
29
+ onFinished?: (event: TaskViewWithSchema<ZodType>) => void;
30
+ },
31
+ ): ReadableStream<Uint8Array<ArrayBufferLike>> {
32
+ const enc = new TextEncoder();
33
+
34
+ const stream = new ReadableStream<Uint8Array>({
35
+ async start(controller) {
36
+ // open the SSE stream quickly
37
+ controller.enqueue(enc.encode(': connected\n\n'));
38
+
39
+ try {
40
+ for await (const msg of gen) {
41
+ opts?.onEvent?.(msg.data);
42
+
43
+ const data: BrowserUseEvent = {
44
+ event: msg.event,
45
+ data: msg.data,
46
+ };
47
+
48
+ const encoded = JSON.stringify(data);
49
+
50
+ const payload = `event: ${msg.event}\ndata: ${encoded}\n\n`;
51
+
52
+ controller.enqueue(enc.encode(payload));
53
+
54
+ if (msg.data.status === 'finished') {
55
+ opts?.onFinished?.(msg.data);
56
+ }
57
+ }
58
+
59
+ controller.enqueue(enc.encode('event: end\ndata: {}\n\n'));
60
+ } catch (e) {
61
+ controller.enqueue(enc.encode(`event: error\ndata: ${JSON.stringify({ message: String(e) })}\n\n`));
62
+ } finally {
63
+ controller.close();
64
+ }
65
+ },
66
+ });
67
+
68
+ return stream;
69
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '1.1.3'; // x-release-please-version
1
+ export const VERSION = '1.2.0'; // x-release-please-version
package/version.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.1.3";
1
+ export declare const VERSION = "1.2.0";
2
2
  //# sourceMappingURL=version.d.mts.map
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.1.3";
1
+ export declare const VERSION = "1.2.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '1.1.3'; // x-release-please-version
4
+ exports.VERSION = '1.2.0'; // x-release-please-version
5
5
  //# sourceMappingURL=version.js.map
package/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '1.1.3'; // x-release-please-version
1
+ export const VERSION = '1.2.0'; // x-release-please-version
2
2
  //# sourceMappingURL=version.mjs.map