effect-browserbase 0.1.0-beta.104 → 0.2.0-beta.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.
Files changed (135) hide show
  1. package/README.md +61 -305
  2. package/dist/Account.d.mts +4 -6
  3. package/dist/Account.mjs +4 -9
  4. package/dist/Account.mjs.map +1 -1
  5. package/dist/{Acquisition-WBafHwXH.mjs → Acquisition-D8o4jtCg.mjs} +22 -68
  6. package/dist/Acquisition-D8o4jtCg.mjs.map +1 -0
  7. package/dist/Agents.d.mts +4 -6
  8. package/dist/Agents.mjs +3 -19
  9. package/dist/Agents.mjs.map +1 -1
  10. package/dist/Allocation.d.mts +9 -11
  11. package/dist/Allocation.mjs +2 -4
  12. package/dist/Allocation.mjs.map +1 -1
  13. package/dist/Browser.d.mts +23 -141
  14. package/dist/Browser.mjs +208 -164
  15. package/dist/Browser.mjs.map +1 -1
  16. package/dist/BrowserBinding.d.mts +7 -34
  17. package/dist/BrowserBinding.mjs +30 -1
  18. package/dist/BrowserBinding.mjs.map +1 -0
  19. package/dist/Certificates.d.mts +3 -5
  20. package/dist/Certificates.mjs +2 -7
  21. package/dist/Certificates.mjs.map +1 -1
  22. package/dist/{Cleanup-G2YpTCuU.d.mts → Cleanup-DMTDBir8.d.mts} +5 -6
  23. package/dist/Cleanup.d.mts +3 -2
  24. package/dist/Cleanup.mjs +1 -6
  25. package/dist/Cleanup.mjs.map +1 -1
  26. package/dist/{Client-D1_xYM9o.mjs → Client-BQteUePT.mjs} +2 -4
  27. package/dist/{Client-D1_xYM9o.mjs.map → Client-BQteUePT.mjs.map} +1 -1
  28. package/dist/Client.d.mts +51 -2
  29. package/dist/Client.mjs +1 -1
  30. package/dist/Connection-DcvJZEdc.mjs +65 -0
  31. package/dist/Connection-DcvJZEdc.mjs.map +1 -0
  32. package/dist/ContextCoordination.d.mts +5 -6
  33. package/dist/ContextCoordination.mjs +1 -8
  34. package/dist/ContextCoordination.mjs.map +1 -1
  35. package/dist/Contexts.d.mts +4 -6
  36. package/dist/Contexts.mjs +2 -8
  37. package/dist/Contexts.mjs.map +1 -1
  38. package/dist/Downloads.d.mts +6 -8
  39. package/dist/Downloads.mjs +3 -8
  40. package/dist/Downloads.mjs.map +1 -1
  41. package/dist/Errors.d.mts +3 -26
  42. package/dist/Errors.mjs +1 -137
  43. package/dist/Errors.mjs.map +1 -1
  44. package/dist/{Extensions-ClZbYb1H.mjs → Extensions-nMNMPGCc.mjs} +3 -9
  45. package/dist/{Extensions-ClZbYb1H.mjs.map → Extensions-nMNMPGCc.mjs.map} +1 -1
  46. package/dist/Extensions.d.mts +4 -6
  47. package/dist/Extensions.mjs +1 -1
  48. package/dist/Functions.d.mts +4 -6
  49. package/dist/Functions.mjs +3 -17
  50. package/dist/Functions.mjs.map +1 -1
  51. package/dist/{Launch-BHcAEq05.mjs → Launch-m0fxzJ49.mjs} +5 -5
  52. package/dist/Launch-m0fxzJ49.mjs.map +1 -0
  53. package/dist/Launch.d.mts +130 -2
  54. package/dist/Launch.mjs +4 -11
  55. package/dist/Launch.mjs.map +1 -1
  56. package/dist/PageFetch.d.mts +3 -5
  57. package/dist/PageFetch.mjs +2 -8
  58. package/dist/PageFetch.mjs.map +1 -1
  59. package/dist/Projects.d.mts +3 -5
  60. package/dist/Projects.mjs +2 -8
  61. package/dist/Projects.mjs.map +1 -1
  62. package/dist/Recordings.d.mts +6 -8
  63. package/dist/Recordings.mjs +3 -5
  64. package/dist/Recordings.mjs.map +1 -1
  65. package/dist/{References-URDAtapt.d.mts → References-DOH3Wu44.d.mts} +5 -6
  66. package/dist/References.d.mts +3 -2
  67. package/dist/References.mjs +10 -18
  68. package/dist/References.mjs.map +1 -1
  69. package/dist/Replays.d.mts +6 -8
  70. package/dist/Replays.mjs +3 -5
  71. package/dist/Replays.mjs.map +1 -1
  72. package/dist/Search.d.mts +3 -5
  73. package/dist/Search.mjs +2 -9
  74. package/dist/Search.mjs.map +1 -1
  75. package/dist/{SessionData-DRKcKCqw.d.mts → SessionData-5xYZDshJ.d.mts} +5 -6
  76. package/dist/SessionData.d.mts +3 -2
  77. package/dist/SessionData.mjs +1 -8
  78. package/dist/SessionData.mjs.map +1 -1
  79. package/dist/{Sessions-CtbseWEh.mjs → Sessions-DoQGg9nB.mjs} +34 -18
  80. package/dist/Sessions-DoQGg9nB.mjs.map +1 -0
  81. package/dist/{Sessions-B8E4kMxo.d.mts → Sessions-tFJYaXFq.d.mts} +8 -8
  82. package/dist/Sessions.d.mts +4 -3
  83. package/dist/Sessions.mjs +1 -1
  84. package/dist/{Transfers-Czv5IZzJ.d.mts → Transfers-GVqzrDWl.d.mts} +22 -9
  85. package/dist/Transfers.d.mts +3 -2
  86. package/dist/Transfers.mjs +12 -28
  87. package/dist/Transfers.mjs.map +1 -1
  88. package/dist/Uploads.d.mts +6 -8
  89. package/dist/Uploads.mjs +3 -5
  90. package/dist/Uploads.mjs.map +1 -1
  91. package/dist/Webhooks.d.mts +3 -5
  92. package/dist/Webhooks.mjs +2 -11
  93. package/dist/Webhooks.mjs.map +1 -1
  94. package/dist/{WriterFacts-osvYAsIx.d.mts → WriterFacts-5CPBGG1P.d.mts} +4 -3
  95. package/dist/index.d.mts +27 -31
  96. package/dist/index.mjs +26 -31
  97. package/package.json +3 -28
  98. package/dist/Acquisition-WBafHwXH.mjs.map +0 -1
  99. package/dist/Association-CEps4hYP.mjs +0 -10
  100. package/dist/Association-CEps4hYP.mjs.map +0 -1
  101. package/dist/Bootstrap-BXuzZojd.mjs +0 -194
  102. package/dist/Bootstrap-BXuzZojd.mjs.map +0 -1
  103. package/dist/Bootstrap-m7lHgj0D.d.mts +0 -177
  104. package/dist/Bootstrap.d.mts +0 -2
  105. package/dist/Bootstrap.mjs +0 -2
  106. package/dist/BrowserBinding-DlJTGYZL.mjs +0 -2508
  107. package/dist/BrowserBinding-DlJTGYZL.mjs.map +0 -1
  108. package/dist/BrowserData-LpcAuAub.d.mts +0 -369
  109. package/dist/BrowserData.d.mts +0 -2
  110. package/dist/BrowserData.mjs +0 -442
  111. package/dist/BrowserData.mjs.map +0 -1
  112. package/dist/Capture-Bc0z9IAi.mjs +0 -571
  113. package/dist/Capture-Bc0z9IAi.mjs.map +0 -1
  114. package/dist/Capture-BvWI-l1A.d.mts +0 -168
  115. package/dist/Capture.d.mts +0 -2
  116. package/dist/Capture.mjs +0 -2
  117. package/dist/Client-Ca0zSg1n.d.mts +0 -53
  118. package/dist/Images-DgscEfSf.mjs +0 -127
  119. package/dist/Images-DgscEfSf.mjs.map +0 -1
  120. package/dist/Launch-BHcAEq05.mjs.map +0 -1
  121. package/dist/Launch-C8CfaYxb.d.mts +0 -132
  122. package/dist/LocalBrowser-BLancJ3R.d.mts +0 -79
  123. package/dist/LocalBrowser-DsQLWNL1.mjs +0 -439
  124. package/dist/LocalBrowser-DsQLWNL1.mjs.map +0 -1
  125. package/dist/LocalBrowser.d.mts +0 -2
  126. package/dist/LocalBrowser.mjs +0 -2
  127. package/dist/PageControl.d.mts +0 -16
  128. package/dist/PageControl.mjs +0 -36
  129. package/dist/PageControl.mjs.map +0 -1
  130. package/dist/PageControlAssociation-DabEg5AR.mjs +0 -10
  131. package/dist/PageControlAssociation-DabEg5AR.mjs.map +0 -1
  132. package/dist/Session-D4nT9hOO.mjs +0 -1379
  133. package/dist/Session-D4nT9hOO.mjs.map +0 -1
  134. package/dist/Sessions-CtbseWEh.mjs.map +0 -1
  135. package/dist/rolldown-runtime-D7D4PA-g.mjs +0 -13
@@ -1,17 +1,16 @@
1
- import { o as SessionReference, t as AllocationAttempt } from "./References-URDAtapt.mjs";
2
- import { AllocationError, BrowserError, ContextError, InitializationError, SessionError } from "./Errors.mjs";
3
- import { t as BrowserbaseClient } from "./Client-Ca0zSg1n.mjs";
4
- import { s as LiveView, t as BrowserbaseSessions } from "./Sessions-B8E4kMxo.mjs";
5
- import { r as DownloadObservation } from "./Transfers-Czv5IZzJ.mjs";
6
- import { n as CleanupResult } from "./Cleanup-G2YpTCuU.mjs";
7
- import { n as ContextWriterPermit } from "./WriterFacts-osvYAsIx.mjs";
8
- import { f as Plan, g as ReadinessOutcome, s as Bootstrap_d_exports, t as BindingDiagnostics } from "./Bootstrap-m7lHgj0D.mjs";
9
- import { A as ReadTextRequest, B as TypeRequest, E as PageInfo, G as WheelRequest, I as StartNavigationRequest, L as Target, M as ScreenshotResult, N as ScrollRequest, O as PointerMoveRequest, P as SelectFilesRequest, S as ObservationOptions, V as Viewport, _ as KeyStroke, a as Checkpoint, b as NavigationResult, c as ControlFacts, d as FrameInfo, f as HoverRequest, h as InputReceipt, i as BrowserPolicy, j as ScreenshotRequest, k as PressRequest, n as AutomationOptions, o as CheckpointOptions, s as ClickRequest, t as ActionResult, u as FillRequest, w as ObservedElement, x as Observation, y as NavigateRequest, z as TextResult } from "./BrowserData-LpcAuAub.mjs";
10
- import { t as LaunchRecipe } from "./Launch-C8CfaYxb.mjs";
1
+ import { a as SessionReference, t as AllocationAttempt } from "./References-DOH3Wu44.mjs";
2
+ import { AllocationError, ContextError, SessionError } from "./Errors.mjs";
3
+ import { BrowserbaseClient } from "./Client.mjs";
4
+ import { o as LiveView, t as BrowserbaseSessions } from "./Sessions-tFJYaXFq.mjs";
5
+ import { f as SelectFilesRequest, i as FileSelection, r as DownloadObservation } from "./Transfers-GVqzrDWl.mjs";
6
+ import { n as CleanupResult } from "./Cleanup-DMTDBir8.mjs";
7
+ import { n as ContextWriterPermit } from "./WriterFacts-5CPBGG1P.mjs";
8
+ import { LaunchRecipe } from "./Launch.mjs";
11
9
  import { Context, Effect, Layer, Option, Redacted, Scope } from "effect";
12
- declare namespace Browser_d_exports {
13
- export { AttachRequest, BoundTarget, BrowserAcquisition, BrowserOptions, BrowserSession, BrowserbaseBrowser, BrowserbaseSession, ElementAdmission, Handoff, LiveView, NavigationOperation, OpenOptions };
14
- }
10
+ import { ActionResult, AutomationOptions, BrowserPolicy, ClickRequest, Observation } from "effect-browser/browser-data";
11
+ import { BrowserError, InitializationError } from "effect-browser/errors";
12
+ import { BrowserSession, OpenOptions } from "effect-browser/browser";
13
+ //#region src/Browser.d.ts
15
14
  /** Host configuration. Credentials live in the Client; a model never selects these values. */
16
15
  export interface BrowserOptions extends AutomationOptions {
17
16
  readonly launch: LaunchRecipe;
@@ -24,124 +23,10 @@ export interface Handoff {
24
23
  readonly token: Redacted.Redacted<string>;
25
24
  readonly view: LiveView;
26
25
  }
27
- /**
28
- * A host's decision about one control, made on facts read from the exact node immediately
29
- * before input. Returning anything but `true`, or throwing, sends nothing and fails `denied`.
30
- * It is a plain synchronous function on purpose: it runs while the owner's permit is held, where
31
- * waiting on a model or a network call would stall every other operation. It is not an atomic
32
- * check-and-input transaction, because page script can still run before the native input lands.
33
- */
34
- export interface ElementAdmission {
35
- readonly admit: (facts: ControlFacts) => boolean;
36
- }
37
- /**
38
- * A navigation the browser is still performing. The owner's permit was released when it was
39
- * dispatched, so while it loads a host may read, `checkpoint`, hold and resume this page, and
40
- * use any other page. Anything that would change this page fails `busy` until it settles.
41
- *
42
- * Leaving its scope unsettled fences the session, exactly as an interrupted mutation does,
43
- * because nothing then knows what the browser did. It is never replayed.
44
- */
45
- export interface NavigationOperation {
46
- /** What was navigated, read before dispatch. */
47
- readonly target: Target;
48
- /**
49
- * The document reached DOMContentLoaded. It belongs to this one navigation: a successor that
50
- * reaches the same URL fails it instead. Interrupting a waiter stops nothing in the browser.
51
- */
52
- readonly completed: Effect.Effect<NavigationResult, BrowserError>;
53
- /**
54
- * Asks the browser to stop loading and waits for this navigation to settle, after which
55
- * `completed` fails `interrupted`. Success is a known outcome and the session stays usable:
56
- * the page holds whatever had loaded. It does not undo anything the page already did.
57
- */
58
- readonly stop: Effect.Effect<void, BrowserError>;
59
- }
60
- /** One selected page and frame at one connection generation, never the current DOM. */
61
- export interface BoundTarget {
62
- readonly navigate: (request: NavigateRequest) => Effect.Effect<NavigationResult, BrowserError>;
63
- /** `navigate`, left in flight: the same single dispatch, completed by the caller. */
64
- readonly startNavigation: (request: StartNavigationRequest) => Effect.Effect<NavigationOperation, BrowserError, Scope.Scope>;
65
- readonly readText: (request: ReadTextRequest) => Effect.Effect<TextResult, BrowserError>;
66
- readonly click: (request: ClickRequest) => Effect.Effect<ActionResult, BrowserError>;
67
- readonly fill: (request: FillRequest) => Effect.Effect<ActionResult, BrowserError>;
68
- /** Script in the page: instantaneous, and it raises no wheel event. */
69
- readonly scroll: (request: ScrollRequest) => Effect.Effect<ActionResult, BrowserError>;
70
- /** One real pointer move, in main-frame viewport pixels. */
71
- readonly pointerMove: (request: PointerMoveRequest) => Effect.Effect<InputReceipt, BrowserError>;
72
- /** Places the pointer on one exact element where it is, or fails `not-visible` unsent. */
73
- readonly hover: (request: HoverRequest) => Effect.Effect<InputReceipt, BrowserError>;
74
- /** One real wheel event; the browser decides what under the pointer scrolls. */
75
- readonly wheel: (request: WheelRequest) => Effect.Effect<InputReceipt, BrowserError>;
76
- /** One real key stroke to whatever has focus, or fails `not-focused` unsent if `into` lacks it. */
77
- readonly press: (request: PressRequest) => Effect.Effect<InputReceipt, BrowserError>;
78
- /** Text as the real key strokes that produce it, under the same focus rule as `press`. */
79
- readonly type: (request: TypeRequest) => Effect.Effect<InputReceipt, BrowserError>;
80
- readonly screenshot: (request: ScreenshotRequest) => Effect.Effect<ScreenshotResult, BrowserError>;
81
- }
82
- /**
83
- * Host control over one owned browser. This is not a serializable model value: copying a
84
- * session object cannot copy its capture, page-control or connection authority.
85
- */
86
- export interface BrowserSession<E = never> {
87
- /** First fail-session callback cause, preserving the consumer's error type on the host. */
88
- readonly failure: Effect.Effect<never, E | InitializationError>;
89
- /** Bounded host-only evidence; consumer causes are never projected into a page reply. */
90
- readonly bindingDiagnostics: Effect.Effect<BindingDiagnostics<E>>;
91
- readonly bind: () => BoundTarget;
92
- /** Re-reads the live selection first, so a stale generation fails before any dispatch. */
93
- readonly currentTarget: Effect.Effect<BoundTarget, BrowserError>;
94
- readonly target: Effect.Effect<Target, BrowserError>;
95
- /**
96
- * The one observation whose nodes later actions may name. `scope: "viewport"` keeps only text
97
- * and controls that are on screen and reachable; the default reads the whole document. It is
98
- * safe to show a model: it carries no destination, form or field value.
99
- */
100
- readonly observe: (options?: ObservationOptions) => Effect.Effect<Observation, BrowserError>;
101
- /**
102
- * Passive evidence for a recorder, with a picture when asked. It issues no references and
103
- * leaves the observation above exactly as it was. Host-only: it carries control facts.
104
- */
105
- readonly checkpoint: (options?: CheckpointOptions) => Effect.Effect<Checkpoint, BrowserError>;
106
- /** Host-only facts about one observed control, read from that exact node just now. */
107
- readonly controlFacts: (reference: ObservedElement) => Effect.Effect<ControlFacts, BrowserError>;
108
- /**
109
- * After a page hold, nothing observed on that page may be acted on unchecked. This checks one
110
- * reference: still attached, and still the control that was inspected. It never searches by
111
- * selector or label for a substitute, and it sends nothing.
112
- */
113
- readonly revalidateElement: (reference: ObservedElement) => Effect.Effect<ObservedElement, BrowserError>;
114
- readonly clickElement: (reference: ObservedElement, admission?: ElementAdmission) => Effect.Effect<ActionResult, BrowserError>;
115
- readonly fillElement: (reference: ObservedElement, value: string, admission?: ElementAdmission) => Effect.Effect<ActionResult, BrowserError>;
116
- readonly hoverElement: (reference: ObservedElement, admission?: ElementAdmission) => Effect.Effect<InputReceipt, BrowserError>;
117
- /** A key stroke sent only if the exact node an observation named already has focus. */
118
- readonly pressElement: (reference: ObservedElement, stroke: KeyStroke, admission?: ElementAdmission) => Effect.Effect<InputReceipt, BrowserError>;
119
- /** Real typing with `fillElement`'s exactness: that node must already have focus. */
120
- readonly typeElement: (reference: ObservedElement, text: string, admission?: ElementAdmission) => Effect.Effect<InputReceipt, BrowserError>;
121
- readonly pages: Effect.Effect<ReadonlyArray<PageInfo>, BrowserError>;
122
- readonly frames: Effect.Effect<ReadonlyArray<FrameInfo>, BrowserError>;
123
- readonly selectPage: (pageId: string) => Effect.Effect<BoundTarget, BrowserError>;
124
- readonly selectFrame: (frameId: string) => Effect.Effect<BoundTarget, BrowserError>;
125
- /** Create a tab without selecting it. */
126
- readonly createPage: Effect.Effect<string, BrowserError>;
127
- readonly closePage: (pageId: string) => Effect.Effect<void, BrowserError>;
128
- readonly resizeViewport: (viewport: Viewport) => Effect.Effect<void, BrowserError>;
129
- readonly waitFor: (request: {
130
- readonly selector: string;
131
- readonly state: "visible" | "hidden" | "attached" | "detached";
132
- }) => Effect.Effect<void, BrowserError>;
133
- /** Navigation observation is registered before the single click dispatch. */
134
- readonly clickAndWait: (request: ClickRequest) => Effect.Effect<ActionResult, BrowserError>;
135
- /**
136
- * Readiness of the current document only. Dependent operations wait for it themselves;
137
- * this reports it without charging an action, so a caller can decide what to do about a
138
- * document that predates the registrations.
139
- */
140
- readonly ready: Effect.Effect<ReadinessOutcome, InitializationError>;
141
- }
142
26
  /** Browserbase identity, remote artifacts and provider cleanup remain hosted capabilities. */
143
27
  export interface BrowserbaseSession<E = never> extends BrowserSession<E> {
144
28
  readonly reference: SessionReference;
29
+ readonly closeChecked: Effect.Effect<CleanupResult, BrowserError>;
145
30
  readonly clickForDownload: (request: ClickRequest) => Effect.Effect<DownloadObservation, BrowserError>;
146
31
  /** Attaches to an existing file input; an uploaded branch needs a receipt for this session. */
147
32
  readonly selectFiles: (request: SelectFilesRequest) => Effect.Effect<ActionResult, BrowserError>;
@@ -155,13 +40,9 @@ export interface BrowserbaseSession<E = never> extends BrowserSession<E> {
155
40
  readonly targetId: string;
156
41
  }, BrowserError>;
157
42
  readonly reconnect: (operatorReleasedControl: boolean) => Effect.Effect<Observation, BrowserError | InitializationError>;
158
- readonly close: Effect.Effect<CleanupResult, BrowserError>;
43
+ readonly close: Effect.Effect<CleanupResult>;
159
44
  readonly cleanupResult: Effect.Effect<Option.Option<CleanupResult>>;
160
45
  }
161
- /** Dependencies are captured at acquisition, not erased into an environment-free service Layer. */
162
- export interface OpenOptions<E = never, R = never> {
163
- readonly bootstrap?: Plan<E, R>;
164
- }
165
46
  export interface AttachRequest<E = never, R = never> extends OpenOptions<E, R> {
166
47
  readonly policy: BrowserPolicy;
167
48
  /** The exact page to resume; without it the session must have exactly one page. */
@@ -176,23 +57,24 @@ export interface BrowserAcquisition<E = never> {
176
57
  readonly attempt: AllocationAttempt;
177
58
  readonly failure: Effect.Effect<never, E | InitializationError>;
178
59
  readonly connect: Effect.Effect<BrowserbaseSession<E>, BrowserError | E | InitializationError>;
179
- readonly close: Effect.Effect<CleanupResult, BrowserError>;
60
+ readonly close: Effect.Effect<CleanupResult>;
180
61
  }
181
62
  declare const BrowserbaseBrowser_base: Context.ServiceClass<BrowserbaseBrowser, "effect-browserbase/Browser", {
182
63
  readonly acquire: <E = never, R = never>(policy: BrowserPolicy, request?: OpenOptions<E, R>) => Effect.Effect<BrowserAcquisition<E>, AllocationError | BrowserError | ContextError, Scope.Scope | Exclude<R, Scope.Scope>>;
183
64
  /** Borrowed control of a session this process did not allocate and will not release. */
184
65
  readonly attach: <E = never, R = never>(reference: SessionReference, request: AttachRequest<E, R>) => Effect.Effect<BrowserbaseSession<E>, BrowserError | SessionError | E | InitializationError, Scope.Scope | Exclude<R, Scope.Scope>>;
185
66
  readonly open: <E = never, R = never>(policy: BrowserPolicy, request?: OpenOptions<E, R>) => Effect.Effect<BrowserbaseSession<E>, AllocationError | BrowserError | ContextError | E | InitializationError, Scope.Scope | Exclude<R, Scope.Scope>>;
186
- /** Race the consumer with typed callback failure and confirm cleanup before normal success. */
187
- readonly withBrowser: <E, R, A, E2, R2>(policy: BrowserPolicy, request: OpenOptions<E, R>, use: (session: BrowserbaseSession<E>) => Effect.Effect<A, E2, R2>) => Effect.Effect<A, AllocationError | BrowserError | ContextError | InitializationError | E | E2, Exclude<R | R2, Scope.Scope>>;
188
67
  }>;
189
- /**
190
- * Credentials, budgets and connection lifetime are fixed when this Layer is built. Building it
191
- * allocates nothing and loads no native peer; every acquisition is scoped by its caller.
192
- */
193
68
  export declare class BrowserbaseBrowser extends BrowserbaseBrowser_base {
69
+ /** Open through the configured account and browser service, in the caller's scope. */
70
+ static open<E = never, R = never>(policy: BrowserPolicy, request?: OpenOptions<E, R>): Effect.Effect<BrowserbaseSession<E>, E | AllocationError | BrowserError | ContextError | InitializationError, BrowserbaseBrowser | Scope.Scope | Exclude<R, Scope.Scope>>;
71
+ /** Allocate the provider lifetime before connecting, preserving its attempt and cleanup. */
72
+ static acquire<E = never, R = never>(policy: BrowserPolicy, request?: OpenOptions<E, R>): Effect.Effect<BrowserAcquisition<E>, AllocationError | BrowserError | ContextError, BrowserbaseBrowser | Scope.Scope | Exclude<R, Scope.Scope>>;
73
+ /** Borrow a provider session without acquiring release authority over it. */
74
+ static attach<E = never, R = never>(reference: SessionReference, request: AttachRequest<E, R>): Effect.Effect<BrowserbaseSession<E>, E | BrowserError | InitializationError | SessionError, BrowserbaseBrowser | Scope.Scope | Exclude<R, Scope.Scope>>;
194
75
  static layer(options: BrowserOptions): Layer.Layer<BrowserbaseBrowser, BrowserError, BrowserbaseClient | BrowserbaseSessions>;
195
76
  }
196
77
  //#endregion
197
- export { type LiveView, Browser_d_exports as t };
78
+ export type { FileSelection, LiveView, SelectFilesRequest };
79
+ export {};
198
80
  //# sourceMappingURL=Browser.d.mts.map
package/dist/Browser.mjs CHANGED
@@ -1,215 +1,259 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { Identifier } from "./References.mjs";
3
- import { BrowserError } from "./Errors.mjs";
1
+ import { SessionError } from "./Errors.mjs";
4
2
  import { DownloadObservation } from "./Transfers.mjs";
5
- import { t as BrowserbaseClient } from "./Client-D1_xYM9o.mjs";
6
- import { ActionResult, AutomationOptions, BrowserPolicy, ClickRequest, InlineFiles, Selector, Viewport } from "./BrowserData.mjs";
7
- import { t as BrowserbaseSessions } from "./Sessions-CtbseWEh.mjs";
3
+ import { t as BrowserbaseClient } from "./Client-BQteUePT.mjs";
4
+ import { isTerminalSessionStatus } from "./SessionData.mjs";
5
+ import { a as issueLiveView, o as browserRequestFailure, t as BrowserbaseSessions } from "./Sessions-DoQGg9nB.mjs";
8
6
  import { t as issuedUpload } from "./Issued-DejqoMYL.mjs";
9
- import { d as empty } from "./Bootstrap-BXuzZojd.mjs";
10
- import { t as BrowserbaseBrowserBinding } from "./BrowserBinding-DlJTGYZL.mjs";
11
- import { a as decoded, c as preparePlan, i as checked, l as compileBootstrap, n as borrowedRemote, o as makeSession$1, r as ownedRemote, s as makeBindings, t as acquireSession } from "./Session-D4nT9hOO.mjs";
12
- import { Context, Effect, Layer, Scope } from "effect";
13
- //#region src/Browser.ts
14
- var Browser_exports = /* @__PURE__ */ __exportAll({ BrowserbaseBrowser: () => BrowserbaseBrowser });
7
+ import { t as connectionAddress } from "./Connection-DcvJZEdc.mjs";
8
+ import { a as reported, i as noLocalConnection, n as reportCleanup, r as makeCleanup, t as acquireRemote } from "./Acquisition-D8o4jtCg.mjs";
9
+ import { BrowserbaseBrowserBinding } from "./BrowserBinding.mjs";
10
+ import { Context, Effect, Exit, Layer, Option, Schema, Scope } from "effect";
11
+ import { BrowserError, Reasons } from "effect-browser/errors";
12
+ import * as BrowserRuntime from "effect-browser/browser-runtime";
13
+ //#region src/internal/session/Attachment.ts
14
+ const failure = (reason) => SessionError.make({
15
+ operation: "session-attach",
16
+ reason,
17
+ outcome: "undispatched"
18
+ });
15
19
  /**
16
- * Uploaded selection is admitted by the identity of a receipt this package issued for this
17
- * exact session, never by a path read off the caller's value. A fabricated receipt has no
18
- * issuance record, so an arbitrary server pathname can never become an attached file.
20
+ * Borrowing an already running session. This scope owns its local connection and nothing
21
+ * else: no allocation attempt is made, no release is requested, and no Context-writer
22
+ * authority is claimed. Whoever allocated the session keeps all three.
19
23
  */
20
- const selection = (request, reference, operation) => Effect.suspend(() => {
21
- const invalid = BrowserError.make({
22
- operation,
23
- reason: "configuration",
24
+ const attachRemote = Effect.fnUntraced(function* (options, local = noLocalConnection, limits) {
25
+ const client = yield* BrowserbaseClient;
26
+ const sessions = yield* BrowserbaseSessions;
27
+ const parent = yield* Scope.Scope;
28
+ const pendingWaitMillis = options.pendingWaitMillis ?? 0;
29
+ if (!Number.isSafeInteger(pendingWaitMillis) || pendingWaitMillis < 0 || pendingWaitMillis > 6e5) return yield* failure("configuration");
30
+ const observed = yield* sessions.retrieve(options.reference);
31
+ if (isTerminalSessionStatus(observed.status)) return yield* failure("expired");
32
+ if (observed.status !== "RUNNING") {
33
+ if (pendingWaitMillis === 0) return yield* failure("active");
34
+ yield* sessions.waitUntilRunning(observed.reference, { timeoutMillis: pendingWaitMillis });
35
+ }
36
+ const reference = observed.reference;
37
+ return yield* Effect.uninterruptible(Effect.gen(function* () {
38
+ const resourceScope = yield* Scope.make();
39
+ let closing = false;
40
+ let cleanup;
41
+ const terminate = yield* Effect.cached(Effect.uninterruptible(Effect.gen(function* () {
42
+ closing = true;
43
+ yield* (yield* makeCleanup(reference, "borrowed", sessions, local, (result) => {
44
+ cleanup = result;
45
+ }, limits)).close;
46
+ const result = cleanup;
47
+ const notify = options.onCleanup;
48
+ if (result !== void 0) {
49
+ yield* reported(Effect.suspend(() => reportCleanup(result)));
50
+ if (notify !== void 0) yield* reported(Effect.suspend(() => notify(result)));
51
+ }
52
+ })));
53
+ const closeScope = yield* Effect.cached(Scope.close(resourceScope, Exit.void));
54
+ yield* Scope.addFinalizer(resourceScope, terminate);
55
+ yield* Scope.addFinalizer(parent, closeScope);
56
+ return {
57
+ reference,
58
+ status: observed,
59
+ connection: (timeoutMillis) => Effect.suspend(() => closing ? Effect.fail(SessionError.make({
60
+ operation: "session-connect",
61
+ reason: "expired",
62
+ outcome: "undispatched"
63
+ })) : connectionAddress(client, sessions, reference, timeoutMillis)),
64
+ release: closeScope.pipe(Effect.andThen(Effect.suspend(() => cleanup === void 0 ? Effect.die(/* @__PURE__ */ new Error("Borrowed session closed without cleanup evidence")) : Effect.succeed(cleanup)))),
65
+ cleanupResult: Effect.sync(() => Option.fromNullishOr(cleanup))
66
+ };
67
+ }));
68
+ });
69
+ //#endregion
70
+ //#region src/internal/session/Browser.ts
71
+ /** A borrowed connection closes without requiring or requesting remote termination. */
72
+ const checkedCleanup = (close) => close.pipe(Effect.filterOrFail((result) => result.local === "closed" && result.issues.length === 0 && (result.ownership === "borrowed" ? result.remote === "not-owned" : result.remote === "confirmed"), () => BrowserError.make({
73
+ operation: "close",
74
+ reason: Reasons.Provider.make({}),
75
+ outcome: "unknown"
76
+ })));
77
+ const withConnection = (acquired) => ({
78
+ ...acquired,
79
+ connection: (timeoutMillis) => acquired.connection(timeoutMillis).pipe(Effect.mapError((error) => browserRequestFailure("connect", error))),
80
+ closeChecked: checkedCleanup(acquired.release),
81
+ controlRetired: acquired.cleanupResult.pipe(Effect.map((result) => Option.isSome(result) && result.value.ownership === "owned" && result.value.remote === "confirmed"))
82
+ });
83
+ /** Allocates the session, and therefore owns releasing it. */
84
+ const providerControls = (client, sessions, reference) => ({
85
+ liveView: (ttl) => issueLiveView(client, reference, ttl),
86
+ verifyReconnect: sessions.retrieve(reference).pipe(Effect.mapError((error) => browserRequestFailure("reconnect", error)), Effect.flatMap((status) => status.status === "RUNNING" ? Effect.void : Effect.fail(BrowserError.make({
87
+ operation: "reconnect",
88
+ reason: Reasons.Expired.make({}),
24
89
  outcome: "undispatched"
25
- });
26
- if (request.selection._tag === "Inline") return checked(InlineFiles, request.selection.files, operation).pipe(Effect.map((files) => files.map((file) => ({
90
+ }))))
91
+ });
92
+ const ownedRemote = (options) => (local, lifetimeDeadline) => Effect.gen(function* () {
93
+ const client = yield* BrowserbaseClient;
94
+ const sessions = yield* BrowserbaseSessions;
95
+ const acquired = yield* acquireRemote({
96
+ launch: options.launch,
97
+ ...options.contextWriter === void 0 ? {} : { contextWriter: options.contextWriter },
98
+ allocationDeadline: lifetimeDeadline,
99
+ ...options.onCleanup === void 0 ? {} : { onCleanup: options.onCleanup },
100
+ ...options.onAllocationUncertain === void 0 ? {} : { onAllocationUncertain: options.onAllocationUncertain }
101
+ }, local);
102
+ return {
103
+ ...withConnection(acquired),
104
+ ...providerControls(client, sessions, acquired.reference)
105
+ };
106
+ });
107
+ /** Borrows a running session: local connection only, and never a release request. */
108
+ const borrowedRemote = (options) => (local) => Effect.gen(function* () {
109
+ const client = yield* BrowserbaseClient;
110
+ const sessions = yield* BrowserbaseSessions;
111
+ const acquired = yield* attachRemote(options, local);
112
+ return {
113
+ ...withConnection(acquired),
114
+ ...providerControls(client, sessions, acquired.reference)
115
+ };
116
+ });
117
+ //#endregion
118
+ //#region src/Browser.ts
119
+ /** Only receipts issued for this exact provider session may resolve to stored paths. */
120
+ const selection = (request, reference, operation) => Effect.suspend(() => {
121
+ if (request.selection._tag === "Inline") return Effect.succeed({
27
122
  _tag: "Inline",
28
- name: file.name,
29
- mediaType: file.mediaType,
30
- bytes: new Uint8Array(file.bytes)
31
- }))));
123
+ files: request.selection.files
124
+ });
32
125
  const uploads = request.selection.uploads;
33
- if (!Array.isArray(uploads) || uploads.length < 1 || uploads.length > 8) return Effect.fail(invalid);
34
- const files = [];
126
+ if (!Array.isArray(uploads) || uploads.length < 1 || uploads.length > 8) return Effect.fail(BrowserError.make({
127
+ operation,
128
+ reason: Reasons.Configuration.make({}),
129
+ outcome: "undispatched"
130
+ }));
131
+ const paths = [];
35
132
  for (const receipt of uploads) {
36
133
  const issued = issuedUpload(receipt);
37
- if (issued === void 0) return Effect.fail(BrowserError.make({
38
- operation,
39
- reason: "authorization",
40
- outcome: "undispatched"
41
- }));
42
- if (issued.reference.projectId !== reference.projectId || issued.reference.sessionId !== reference.sessionId) return Effect.fail(BrowserError.make({
134
+ if (issued === void 0 || issued.reference.projectId !== reference.projectId || issued.reference.sessionId !== reference.sessionId) return Effect.fail(BrowserError.make({
43
135
  operation,
44
- reason: "authorization",
136
+ reason: Reasons.Authorization.make({}),
45
137
  outcome: "undispatched"
46
138
  }));
47
- files.push({
48
- _tag: "Remote",
49
- path: issued.remotePath
50
- });
139
+ paths.push(issued.remotePath);
51
140
  }
52
- return Effect.succeed(files);
141
+ return Effect.succeed({
142
+ _tag: "Stored",
143
+ paths
144
+ });
53
145
  });
54
- const makeSession = (controls, bindings) => {
55
- const session = makeSession$1(controls, bindings);
56
- const navigate = (url) => decoded(ActionResult, "action-result")({ url });
146
+ const makeSession = (connection, lifetime) => {
147
+ const { session, operations } = connection;
57
148
  return Object.assign(session, {
58
- reference: controls.reference,
59
- clickForDownload: (request) => checked(ClickRequest, request, "download-action").pipe(Effect.flatMap((value) => controls.clickForDownload(value.selector)), Effect.flatMap((raw) => decoded(DownloadObservation, "download-action")({
60
- ...raw,
61
- reference: controls.reference
149
+ reference: lifetime.reference,
150
+ closeChecked: session.closeChecked.pipe(Effect.andThen(lifetime.closeChecked)),
151
+ clickForDownload: (request) => operations.clickForDownload(request).pipe(Effect.flatMap((event) => Schema.decodeEffect(DownloadObservation)({
152
+ ...event,
153
+ reference: lifetime.reference
154
+ }).pipe(Effect.mapError(() => BrowserError.make({
155
+ operation: "download-action",
156
+ reason: Reasons.Malformed.make({}),
157
+ outcome: "unknown"
158
+ }))))),
159
+ selectFiles: (request) => selection(request, lifetime.reference, "select-files").pipe(Effect.flatMap((files) => operations.selectFiles({
160
+ selector: request.selector,
161
+ selection: files
162
+ }))),
163
+ clickForFileSelection: (request) => selection(request, lifetime.reference, "file-chooser").pipe(Effect.flatMap((files) => operations.clickForFileSelection({
164
+ selector: request.selector,
165
+ selection: files
62
166
  }))),
63
- selectFiles: (request) => checked(Selector, request.selector, "select-files").pipe(Effect.flatMap((selector) => selection(request, controls.reference, "select-files").pipe(Effect.flatMap((files) => controls.selectFiles(selector, files)))), Effect.flatMap(navigate)),
64
- clickForFileSelection: (request) => checked(Selector, request.selector, "file-chooser").pipe(Effect.flatMap((selector) => selection(request, controls.reference, "file-chooser").pipe(Effect.flatMap((files) => controls.clickForFileSelection(selector, files)))), Effect.flatMap(navigate)),
65
- liveView: (ttl = 60) => controls.liveView(ttl),
66
- beginHandoff: (ttl = 60) => controls.beginHandoff(ttl),
67
- resume: (token, released) => controls.resume(token, released),
68
- detach: controls.detach,
69
- reconnect: (released) => controls.reconnect(released),
70
- close: controls.close,
71
- cleanupResult: controls.cleanupResult
167
+ liveView: (ttl = 60) => operations.liveView(lifetime.liveView(ttl)),
168
+ beginHandoff: (ttl = 60) => operations.beginHandoff(lifetime.liveView(ttl)),
169
+ resume: operations.resume,
170
+ detach: operations.detach,
171
+ reconnect: operations.reconnect,
172
+ close: lifetime.release,
173
+ cleanupResult: lifetime.cleanupResult
72
174
  });
73
175
  };
74
- /**
75
- * Credentials, budgets and connection lifetime are fixed when this Layer is built. Building it
76
- * allocates nothing and loads no native peer; every acquisition is scoped by its caller.
77
- */
78
176
  var BrowserbaseBrowser = class BrowserbaseBrowser extends Context.Service()("effect-browserbase/Browser") {
177
+ /** Open through the configured account and browser service, in the caller's scope. */
178
+ static open(policy, request) {
179
+ return Effect.flatMap(BrowserbaseBrowser, (browser) => browser.open(policy, request));
180
+ }
181
+ /** Allocate the provider lifetime before connecting, preserving its attempt and cleanup. */
182
+ static acquire(policy, request) {
183
+ return Effect.flatMap(BrowserbaseBrowser, (browser) => browser.acquire(policy, request));
184
+ }
185
+ /** Borrow a provider session without acquiring release authority over it. */
186
+ static attach(reference, request) {
187
+ return Effect.flatMap(BrowserbaseBrowser, (browser) => browser.attach(reference, request));
188
+ }
79
189
  static layer(options) {
80
190
  return Layer.effect(BrowserbaseBrowser, Effect.gen(function* () {
81
191
  const client = yield* BrowserbaseClient;
82
192
  const sessions = yield* BrowserbaseSessions;
83
193
  const binding = yield* BrowserbaseBrowserBinding;
84
- const automation = yield* checked(AutomationOptions, projected(options), "configure");
85
- const viewport = yield* checked(Viewport, options.launch.viewport._tag === "Fixed" ? {
86
- width: options.launch.viewport.width,
87
- height: options.launch.viewport.height
88
- } : {
89
- width: 1280,
90
- height: 720
91
- }, "configure");
92
- const actionTimeoutMillis = automation.actionTimeoutMillis ?? 1e4;
93
- const maxPages = automation.maxPages ?? 10;
94
- const pageControl = automation.pageControl ?? false;
95
- const popupPolicy = automation.popupPolicy ?? "retain";
96
- const dialogPolicy = automation.dialogPolicy ?? "dismiss";
97
- if (pageControl && (options.launch.keepAlive === true || popupPolicy === "pause" || dialogPolicy === "pause")) return yield* BrowserError.make({
98
- operation: "configure",
99
- reason: "unsupported",
100
- outcome: "undispatched"
101
- });
102
194
  if (options.launch.context?.persist === true && options.contextWriter === void 0) return yield* BrowserError.make({
103
195
  operation: "configure",
104
- reason: "context-lease"
196
+ reason: Reasons.ContextLease.make({}),
197
+ outcome: "undispatched"
105
198
  });
106
199
  if (Object.prototype.hasOwnProperty.call(options, "bootstrap")) return yield* BrowserError.make({
107
200
  operation: "configure",
108
- reason: "configuration",
201
+ reason: Reasons.Configuration.make({}),
109
202
  outcome: "undispatched"
110
203
  });
111
- const driver = {
112
- pageControl,
113
- viewport,
114
- maxPages,
115
- popupPolicy,
116
- dialogPolicy,
204
+ const runtime = yield* BrowserRuntime.make({
205
+ implementation: "browserbase-playwright-cdp",
206
+ binding,
207
+ automation: projected(options),
208
+ viewport: options.launch.viewport._tag === "Fixed" ? {
209
+ width: options.launch.viewport.width,
210
+ height: options.launch.viewport.height
211
+ } : {
212
+ width: 1280,
213
+ height: 720
214
+ },
117
215
  preserveViewport: options.launch.viewport._tag !== "Fixed",
118
- ...automation.initialPage === void 0 ? {} : "targetId" in automation.initialPage ? { initialTargetId: automation.initialPage.targetId } : { newPage: true }
119
- };
216
+ keepAlive: options.launch.keepAlive === true
217
+ });
218
+ const source = (remote) => (cleanup, deadline) => remote(cleanup, deadline).pipe(Effect.provideService(BrowserbaseClient, client), Effect.provideService(BrowserbaseSessions, sessions));
120
219
  const acquire = Effect.fnUntraced(function* (policy, request = {}) {
121
- const fixed = yield* checked(BrowserPolicy, policy, "configure");
122
- const plan = yield* preparePlan(request.bootstrap ?? empty);
123
- const scope = yield* Scope.fork(yield* Scope.Scope, "sequential");
124
- const bindings = yield* makeBindings(plan).pipe(Scope.provide(scope));
125
- const bootstrap = compileBootstrap(plan);
126
- const acquired = yield* acquireSession({
127
- maxActions: fixed.maxActions,
128
- maxElapsedMillis: fixed.maxElapsedMillis,
129
- actionTimeoutMillis
130
- }, {
131
- remote: ownedRemote({
132
- launch: options.launch,
133
- ...options.contextWriter === void 0 ? {} : { contextWriter: options.contextWriter },
134
- ...options.onCleanup === void 0 ? {} : { onCleanup: options.onCleanup },
135
- ...options.onAllocationUncertain === void 0 ? {} : { onAllocationUncertain: options.onAllocationUncertain }
136
- }),
137
- keepAlive: options.launch.keepAlive === true,
138
- driver: {
139
- ...driver,
140
- ...bootstrap === void 0 ? {} : { bootstrap }
141
- },
142
- connectBindings: bindings.connect,
143
- maxReturnedBytes: fixed.maxReturnedBytes
144
- }).pipe(Effect.provideService(BrowserbaseClient, client), Effect.provideService(BrowserbaseSessions, sessions), Effect.provideService(BrowserbaseBrowserBinding, binding), Scope.provide(scope));
145
- const connected = yield* Effect.cached(acquired.connect.pipe(Effect.map((controls) => makeSession(controls, bindings))));
220
+ const acquired = yield* runtime.acquire(policy, source(ownedRemote({
221
+ launch: options.launch,
222
+ ...options.contextWriter === void 0 ? {} : { contextWriter: options.contextWriter },
223
+ ...options.onCleanup === void 0 ? {} : { onCleanup: options.onCleanup },
224
+ ...options.onAllocationUncertain === void 0 ? {} : { onAllocationUncertain: options.onAllocationUncertain }
225
+ })), request);
226
+ const connected = yield* Effect.cached(acquired.connect.pipe(Effect.map((connection) => makeSession(connection, acquired.lifetime))));
146
227
  return {
147
228
  reference: acquired.reference,
148
- attempt: acquired.lease.attempt,
149
- failure: bindings.failure,
229
+ attempt: acquired.lifetime.attempt,
230
+ failure: acquired.failure,
150
231
  close: acquired.close,
151
- connect: Effect.raceFirst(bindings.failure, acquired.connect.pipe(Effect.andThen(connected))).pipe(Effect.onError(() => acquired.close.pipe(Effect.asVoid)))
232
+ connect: acquired.connect.pipe(Effect.andThen(connected))
152
233
  };
153
234
  });
154
- /**
155
- * Borrowing a session another process allocated. The launch recipe is not replayed and
156
- * no allocation is attempted: the requested target is resolved explicitly, credentials
157
- * are fetched fresh because expiry races the caller's own status read, and this scope
158
- * disconnects locally without ever requesting release. Detaching and reattaching inside
159
- * a borrowed scope is deliberately absent; attaching again is the cross-process path,
160
- * and it revalidates the session instead of assuming it is still there.
161
- */
162
235
  const attach = Effect.fnUntraced(function* (reference, request) {
163
- const fixed = yield* checked(BrowserPolicy, request.policy, "configure");
164
- const plan = yield* preparePlan(request.bootstrap ?? empty);
165
- const scope = yield* Scope.fork(yield* Scope.Scope, "sequential");
166
- const bindings = yield* makeBindings(plan).pipe(Scope.provide(scope));
167
- const bootstrap = compileBootstrap(plan);
168
- const targetId = request.target === void 0 ? void 0 : yield* checked(Identifier, request.target.targetId, "configure");
169
- const acquired = yield* acquireSession({
170
- maxActions: fixed.maxActions,
171
- maxElapsedMillis: fixed.maxElapsedMillis,
172
- actionTimeoutMillis
173
- }, {
174
- remote: borrowedRemote({
175
- reference,
176
- ...request.pendingWaitMillis === void 0 ? {} : { pendingWaitMillis: request.pendingWaitMillis },
177
- ...options.onCleanup === void 0 ? {} : { onCleanup: options.onCleanup }
178
- }),
179
- keepAlive: false,
180
- driver: {
181
- ...driver,
182
- ...bootstrap === void 0 ? {} : { bootstrap },
183
- newPage: false,
184
- preserveViewport: true,
185
- ...targetId === void 0 ? {} : { initialTargetId: targetId }
186
- },
187
- maxReturnedBytes: fixed.maxReturnedBytes,
188
- connectBindings: bindings.connect
189
- }).pipe(Effect.provideService(BrowserbaseClient, client), Effect.provideService(BrowserbaseSessions, sessions), Effect.provideService(BrowserbaseBrowserBinding, binding), Scope.provide(scope));
190
- return yield* Effect.raceFirst(bindings.failure, acquired.connect.pipe(Effect.map((controls) => makeSession(controls, bindings)))).pipe(Effect.onError(() => acquired.close.pipe(Effect.asVoid)));
236
+ const acquired = yield* runtime.acquire(request.policy, source(borrowedRemote({
237
+ reference,
238
+ ...request.pendingWaitMillis === void 0 ? {} : { pendingWaitMillis: request.pendingWaitMillis },
239
+ ...options.onCleanup === void 0 ? {} : { onCleanup: options.onCleanup }
240
+ })), {
241
+ ...request.bootstrap === void 0 ? {} : { bootstrap: request.bootstrap },
242
+ existingTarget: request.target ?? {}
243
+ });
244
+ return yield* acquired.connect.pipe(Effect.map((connection) => makeSession(connection, acquired.lifetime)));
191
245
  });
192
246
  return BrowserbaseBrowser.of({
193
247
  acquire,
194
248
  attach,
195
- open: (policy, request) => acquire(policy, request).pipe(Effect.flatMap((acquired) => acquired.connect)),
196
- withBrowser: (policy, request, use) => Effect.scoped(Effect.gen(function* () {
197
- const session = yield* (yield* acquire(policy, request)).connect;
198
- const result = yield* Effect.raceFirst(session.failure, Effect.suspend(() => use(session)));
199
- const cleanup = yield* session.close;
200
- if (cleanup.remote !== "confirmed" || cleanup.local !== "closed" || cleanup.issues.length > 0) return yield* BrowserError.make({
201
- operation: "close",
202
- reason: "provider",
203
- outcome: "unknown"
204
- });
205
- return result;
206
- }))
249
+ open: (policy, request) => acquire(policy, request).pipe(Effect.flatMap((acquired) => acquired.connect))
207
250
  });
208
251
  }));
209
252
  }
210
253
  };
211
254
  /** Only the automation fields cross the schema boundary; launch and callbacks are separate. */
212
255
  const projected = (options) => ({
256
+ ...options.maxHostReads === void 0 ? {} : { maxHostReads: options.maxHostReads },
213
257
  ...options.actionTimeoutMillis === void 0 ? {} : { actionTimeoutMillis: options.actionTimeoutMillis },
214
258
  ...options.maxPages === void 0 ? {} : { maxPages: options.maxPages },
215
259
  ...options.initialPage === void 0 ? {} : { initialPage: options.initialPage },
@@ -218,6 +262,6 @@ const projected = (options) => ({
218
262
  ...options.pageControl === void 0 ? {} : { pageControl: options.pageControl }
219
263
  });
220
264
  //#endregion
221
- export { BrowserbaseBrowser, Browser_exports as t };
265
+ export { BrowserbaseBrowser };
222
266
 
223
267
  //# sourceMappingURL=Browser.mjs.map