effect-browserbase 0.1.0-beta.104 → 0.2.0-beta.1

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 (158) hide show
  1. package/README.md +106 -307
  2. package/dist/Account.d.mts +17 -19
  3. package/dist/Account.mjs +4 -9
  4. package/dist/Account.mjs.map +1 -1
  5. package/dist/{Acquisition-WBafHwXH.mjs → Acquisition-CAsTTXp4.mjs} +25 -70
  6. package/dist/Acquisition-CAsTTXp4.mjs.map +1 -0
  7. package/dist/Agents-5HpTp9YE.d.mts +155 -0
  8. package/dist/Agents.d.mts +3 -156
  9. package/dist/Agents.mjs +4 -20
  10. package/dist/Agents.mjs.map +1 -1
  11. package/dist/Allocation.d.mts +9 -11
  12. package/dist/Allocation.mjs +2 -4
  13. package/dist/Allocation.mjs.map +1 -1
  14. package/dist/Browser-DpSajNai.mjs +270 -0
  15. package/dist/Browser-DpSajNai.mjs.map +1 -0
  16. package/dist/Browser.d.mts +26 -143
  17. package/dist/Browser.mjs +3 -223
  18. package/dist/BrowserBinding.d.mts +7 -34
  19. package/dist/BrowserBinding.mjs +30 -1
  20. package/dist/BrowserBinding.mjs.map +1 -0
  21. package/dist/Certificates-D4NQmyeA.d.mts +34 -0
  22. package/dist/Certificates.d.mts +3 -35
  23. package/dist/Certificates.mjs +2 -7
  24. package/dist/Certificates.mjs.map +1 -1
  25. package/dist/{Cleanup-G2YpTCuU.d.mts → Cleanup-DMTDBir8.d.mts} +5 -6
  26. package/dist/Cleanup.d.mts +3 -2
  27. package/dist/Cleanup.mjs +1 -6
  28. package/dist/Cleanup.mjs.map +1 -1
  29. package/dist/{Client-D1_xYM9o.mjs → Client-4RMKIpL2.mjs} +12 -12
  30. package/dist/Client-4RMKIpL2.mjs.map +1 -0
  31. package/dist/{Client-Ca0zSg1n.d.mts → Client-B_f6bBLT.d.mts} +4 -5
  32. package/dist/Client.d.mts +3 -2
  33. package/dist/Client.mjs +1 -1
  34. package/dist/Connection-sxyxtwlk.mjs +56 -0
  35. package/dist/Connection-sxyxtwlk.mjs.map +1 -0
  36. package/dist/ContextCoordination.d.mts +5 -6
  37. package/dist/ContextCoordination.mjs +2 -9
  38. package/dist/ContextCoordination.mjs.map +1 -1
  39. package/dist/{ContextWriter-BrQmoXRg.mjs → ContextWriter-oKWFLHuP.mjs} +8 -12
  40. package/dist/ContextWriter-oKWFLHuP.mjs.map +1 -0
  41. package/dist/Contexts-DqdL7cyX.d.mts +31 -0
  42. package/dist/Contexts.d.mts +3 -32
  43. package/dist/Contexts.mjs +3 -9
  44. package/dist/Contexts.mjs.map +1 -1
  45. package/dist/Downloads-CdhiCO5X.d.mts +43 -0
  46. package/dist/Downloads.d.mts +3 -44
  47. package/dist/Downloads.mjs +3 -8
  48. package/dist/Downloads.mjs.map +1 -1
  49. package/dist/Errors.d.mts +3 -26
  50. package/dist/Errors.mjs +1 -137
  51. package/dist/Errors.mjs.map +1 -1
  52. package/dist/Extensions-DBXuVM1f.d.mts +43 -0
  53. package/dist/{Extensions-ClZbYb1H.mjs → Extensions-Dg3jHOf0.mjs} +3 -9
  54. package/dist/Extensions-Dg3jHOf0.mjs.map +1 -0
  55. package/dist/Extensions.d.mts +3 -44
  56. package/dist/Extensions.mjs +1 -1
  57. package/dist/Functions-CsKMMUuZ.d.mts +226 -0
  58. package/dist/Functions.d.mts +3 -227
  59. package/dist/Functions.mjs +4 -18
  60. package/dist/Functions.mjs.map +1 -1
  61. package/dist/{Launch-BHcAEq05.mjs → Launch-cAdE2rrZ.mjs} +16 -12
  62. package/dist/Launch-cAdE2rrZ.mjs.map +1 -0
  63. package/dist/Launch.d.mts +127 -2
  64. package/dist/Launch.mjs +5 -13
  65. package/dist/Launch.mjs.map +1 -1
  66. package/dist/PageFetch-CAMqb5m8.d.mts +39 -0
  67. package/dist/PageFetch.d.mts +3 -40
  68. package/dist/PageFetch.mjs +2 -8
  69. package/dist/PageFetch.mjs.map +1 -1
  70. package/dist/Projects-tm5bTDH0.d.mts +38 -0
  71. package/dist/Projects.d.mts +3 -39
  72. package/dist/Projects.mjs +2 -8
  73. package/dist/Projects.mjs.map +1 -1
  74. package/dist/Recordings-bVI33sTq.d.mts +27 -0
  75. package/dist/Recordings.d.mts +3 -28
  76. package/dist/Recordings.mjs +3 -5
  77. package/dist/Recordings.mjs.map +1 -1
  78. package/dist/{References-URDAtapt.d.mts → References-DOH3Wu44.d.mts} +5 -6
  79. package/dist/References.d.mts +3 -2
  80. package/dist/References.mjs +10 -18
  81. package/dist/References.mjs.map +1 -1
  82. package/dist/Replays-Bo-9xeLz.d.mts +27 -0
  83. package/dist/Replays.d.mts +3 -28
  84. package/dist/Replays.mjs +3 -5
  85. package/dist/Replays.mjs.map +1 -1
  86. package/dist/Search-1g6TUem7.d.mts +37 -0
  87. package/dist/Search.d.mts +3 -38
  88. package/dist/Search.mjs +2 -9
  89. package/dist/Search.mjs.map +1 -1
  90. package/dist/{SessionData-DRKcKCqw.d.mts → SessionData-5xYZDshJ.d.mts} +5 -6
  91. package/dist/SessionData.d.mts +3 -2
  92. package/dist/SessionData.mjs +1 -8
  93. package/dist/SessionData.mjs.map +1 -1
  94. package/dist/{Sessions-B8E4kMxo.d.mts → Sessions-BpZgjteE.d.mts} +8 -8
  95. package/dist/{Sessions-CtbseWEh.mjs → Sessions-suOLSym9.mjs} +34 -18
  96. package/dist/Sessions-suOLSym9.mjs.map +1 -0
  97. package/dist/Sessions.d.mts +4 -3
  98. package/dist/Sessions.mjs +1 -1
  99. package/dist/Testing.d.mts +119 -0
  100. package/dist/Testing.mjs +206 -0
  101. package/dist/Testing.mjs.map +1 -0
  102. package/dist/{Transfers-Czv5IZzJ.d.mts → Transfers-GVqzrDWl.d.mts} +22 -9
  103. package/dist/Transfers.d.mts +3 -2
  104. package/dist/Transfers.mjs +12 -28
  105. package/dist/Transfers.mjs.map +1 -1
  106. package/dist/Uploads-C2neBEpj.d.mts +28 -0
  107. package/dist/Uploads.d.mts +3 -29
  108. package/dist/Uploads.mjs +3 -5
  109. package/dist/Uploads.mjs.map +1 -1
  110. package/dist/Webhooks-BoeRAxzG.d.mts +59 -0
  111. package/dist/Webhooks.d.mts +3 -60
  112. package/dist/Webhooks.mjs +2 -11
  113. package/dist/Webhooks.mjs.map +1 -1
  114. package/dist/{WriterFacts-osvYAsIx.d.mts → WriterFacts-BBJRDZYY.d.mts} +8 -15
  115. package/dist/index.d.mts +27 -31
  116. package/dist/index.mjs +26 -31
  117. package/package.json +7 -28
  118. package/dist/Acquisition-WBafHwXH.mjs.map +0 -1
  119. package/dist/Association-CEps4hYP.mjs +0 -10
  120. package/dist/Association-CEps4hYP.mjs.map +0 -1
  121. package/dist/Bootstrap-BXuzZojd.mjs +0 -194
  122. package/dist/Bootstrap-BXuzZojd.mjs.map +0 -1
  123. package/dist/Bootstrap-m7lHgj0D.d.mts +0 -177
  124. package/dist/Bootstrap.d.mts +0 -2
  125. package/dist/Bootstrap.mjs +0 -2
  126. package/dist/Browser.mjs.map +0 -1
  127. package/dist/BrowserBinding-DlJTGYZL.mjs +0 -2508
  128. package/dist/BrowserBinding-DlJTGYZL.mjs.map +0 -1
  129. package/dist/BrowserData-LpcAuAub.d.mts +0 -369
  130. package/dist/BrowserData.d.mts +0 -2
  131. package/dist/BrowserData.mjs +0 -442
  132. package/dist/BrowserData.mjs.map +0 -1
  133. package/dist/Capture-Bc0z9IAi.mjs +0 -571
  134. package/dist/Capture-Bc0z9IAi.mjs.map +0 -1
  135. package/dist/Capture-BvWI-l1A.d.mts +0 -168
  136. package/dist/Capture.d.mts +0 -2
  137. package/dist/Capture.mjs +0 -2
  138. package/dist/Client-D1_xYM9o.mjs.map +0 -1
  139. package/dist/ContextWriter-BrQmoXRg.mjs.map +0 -1
  140. package/dist/Extensions-ClZbYb1H.mjs.map +0 -1
  141. package/dist/Images-DgscEfSf.mjs +0 -127
  142. package/dist/Images-DgscEfSf.mjs.map +0 -1
  143. package/dist/Launch-BHcAEq05.mjs.map +0 -1
  144. package/dist/Launch-C8CfaYxb.d.mts +0 -132
  145. package/dist/LocalBrowser-BLancJ3R.d.mts +0 -79
  146. package/dist/LocalBrowser-DsQLWNL1.mjs +0 -439
  147. package/dist/LocalBrowser-DsQLWNL1.mjs.map +0 -1
  148. package/dist/LocalBrowser.d.mts +0 -2
  149. package/dist/LocalBrowser.mjs +0 -2
  150. package/dist/PageControl.d.mts +0 -16
  151. package/dist/PageControl.mjs +0 -36
  152. package/dist/PageControl.mjs.map +0 -1
  153. package/dist/PageControlAssociation-DabEg5AR.mjs +0 -10
  154. package/dist/PageControlAssociation-DabEg5AR.mjs.map +0 -1
  155. package/dist/Session-D4nT9hOO.mjs +0 -1379
  156. package/dist/Session-D4nT9hOO.mjs.map +0 -1
  157. package/dist/Sessions-CtbseWEh.mjs.map +0 -1
  158. package/dist/rolldown-runtime-D7D4PA-g.mjs +0 -13
@@ -1,168 +0,0 @@
1
- import { BrowserError } from "./Errors.mjs";
2
- import { E as PageInfo, L as Target } from "./BrowserData-LpcAuAub.mjs";
3
- import { BrowserSession } from "./Browser.mjs";
4
- import { Effect, Schema, Scope, Stream } from "effect";
5
- //#region src/internal/capture/CaptureTypes.d.ts
6
- /**
7
- * Binary frame data, not a live capability or a JSON/thread/Tool value. Decoding validates
8
- * fields; it does not copy bytes, decode JPEG pixels, prove target authority, or repair clocks.
9
- * Capture itself owns the byte copy, freezes its shared target identity, and verifies JPEG framing.
10
- */
11
- declare const CapturedFrame: Schema.Struct<{
12
- readonly bytes: Schema.Uint8Array;
13
- readonly mediaType: Schema.Literal<"image/jpeg">;
14
- readonly target: typeof Target;
15
- readonly sequence: Schema.Natural;
16
- /**
17
- * Which document of its page this frame was received during: 0 at the start, one more for each
18
- * main-frame navigation the interval observed. It is attribution by receipt order, not proof
19
- * of whose pixels these are: a frame received just after a navigation can still show the
20
- * document before it. Always 0 for an interval that lasts one document.
21
- */
22
- readonly document: Schema.Natural;
23
- readonly sourceTimeMillis: Schema.Finite;
24
- readonly sourceClock: Schema.Literal<"presentation-unix-millis">;
25
- readonly receivedMonotonicNanos: Schema.BigInt;
26
- readonly width: Schema.Int;
27
- readonly height: Schema.Int;
28
- readonly viewportWidth: Schema.Int;
29
- readonly viewportHeight: Schema.Int;
30
- }>;
31
- type CapturedFrame = typeof CapturedFrame.Type;
32
- /** Source-fit request in pixels. Actual JPEG bounds are checked before any frame is delivered. */
33
- declare const CaptureSize: Schema.Struct<{
34
- readonly width: Schema.Int;
35
- readonly height: Schema.Int;
36
- }>;
37
- type CaptureSize = typeof CaptureSize.Type;
38
- /** Optional capture data. Defaults are applied at admission, not during schema decoding. */
39
- declare const CaptureOptions: Schema.Struct<{
40
- /** Pin to a page from `session.pages`; omission preserves selected-page behavior. */
41
- readonly target: Schema.optionalKey<typeof PageInfo>;
42
- readonly maxFrames: Schema.optionalKey<Schema.Int>;
43
- readonly maxBufferedBytes: Schema.optionalKey<Schema.Int>;
44
- readonly maxFrameBytes: Schema.optionalKey<Schema.Int>;
45
- readonly maxDurationMillis: Schema.optionalKey<Schema.Int>;
46
- readonly quality: Schema.optionalKey<Schema.Int>;
47
- /** Source fit only. Does not resize the viewport or impose an FPS cap. */
48
- readonly size: Schema.optionalKey<Schema.Struct<{
49
- readonly width: Schema.Int;
50
- readonly height: Schema.Int;
51
- }>>;
52
- /**
53
- * `document`, the default, ends the interval when its page navigates. `page` follows the page
54
- * across documents, so a capture started before a navigation covers the loading in between.
55
- * It applies to a page's main frame; a capture bound to a child frame still ends with it.
56
- */
57
- readonly lifetime: Schema.optionalKey<Schema.Literals<readonly ["document", "page"]>>;
58
- }>;
59
- type CaptureOptions = typeof CaptureOptions.Type;
60
- declare const CaptureSummary_base: Schema.Class<CaptureSummary, Schema.Struct<{
61
- readonly target: typeof Target;
62
- readonly reason: Schema.String;
63
- readonly received: Schema.Natural;
64
- readonly delivered: Schema.Natural;
65
- readonly dropped: Schema.Natural;
66
- readonly duplicates: Schema.Natural;
67
- /** Arrived after a newer frame was accepted; counted within `dropped`, never reordered in. */
68
- readonly late: Schema.Natural;
69
- readonly peakBufferedFrames: Schema.Natural;
70
- readonly peakBufferedBytes: Schema.Natural;
71
- readonly bufferedFrames: Schema.Natural;
72
- readonly bufferedBytes: Schema.Natural;
73
- readonly sourceFirstMillis: Schema.NullOr<Schema.Finite>;
74
- readonly sourceLastMillis: Schema.NullOr<Schema.Finite>;
75
- /**
76
- * The captured frame's address when this interval began watching it: the URL of document 0.
77
- * It is read in the same turn the watch is installed, so no navigation can fall between them.
78
- */
79
- readonly initialUrl: Schema.NullOr<Schema.String>;
80
- /**
81
- * Each main-frame navigation a `page` interval observed, in order, with the last frame
82
- * received before it and the address the new document committed. The native screencast is
83
- * never restarted for one, so a boundary is not a gap this package introduced; what Chromium
84
- * omitted while loading stays `upstreamDrops`. A boundary is the commit. When that navigation
85
- * started and when its document finished loading are the caller's to stamp, on this same
86
- * clock, around the operation that caused it. A title is page state, not part of a transition.
87
- */
88
- readonly documentBoundaries: Schema.$Array<Schema.Struct<{
89
- readonly document: Schema.Natural;
90
- readonly observedMonotonicNanos: Schema.BigInt;
91
- readonly afterSequence: Schema.NullOr<Schema.Natural>;
92
- readonly url: Schema.NullOr<Schema.String>;
93
- }>>;
94
- /** More navigations were observed than are recorded above. Frames still count them all. */
95
- readonly documentBoundariesTruncated: Schema.Boolean;
96
- readonly nativeStop: Schema.Literals<readonly ["confirmed", "unconfirmed"]>;
97
- /** Package accounting cannot measure frames omitted by Chromium, transport, or the provider. */
98
- readonly upstreamDrops: Schema.Literal<"unknown">;
99
- readonly error: Schema.optionalKey<typeof BrowserError>;
100
- }>, {}>;
101
- declare class CaptureSummary extends CaptureSummary_base {}
102
- declare const CaptureSnapshot_base: Schema.Class<CaptureSnapshot, Schema.Struct<{
103
- readonly target: typeof Target;
104
- readonly received: Schema.Natural;
105
- readonly delivered: Schema.Natural;
106
- readonly dropped: Schema.Natural;
107
- readonly duplicates: Schema.Natural;
108
- readonly late: Schema.Natural;
109
- readonly peakBufferedFrames: Schema.Natural;
110
- readonly peakBufferedBytes: Schema.Natural;
111
- readonly bufferedFrames: Schema.Natural;
112
- readonly bufferedBytes: Schema.Natural;
113
- readonly sourceFirstMillis: Schema.NullOr<Schema.Finite>;
114
- readonly sourceLastMillis: Schema.NullOr<Schema.Finite>;
115
- readonly initialUrl: Schema.NullOr<Schema.String>;
116
- readonly documentBoundaries: Schema.$Array<Schema.Struct<{
117
- readonly document: Schema.Natural;
118
- readonly observedMonotonicNanos: Schema.BigInt;
119
- readonly afterSequence: Schema.NullOr<Schema.Natural>;
120
- readonly url: Schema.NullOr<Schema.String>;
121
- }>>;
122
- readonly documentBoundariesTruncated: Schema.Boolean;
123
- readonly upstreamDrops: Schema.Literal<"unknown">;
124
- readonly error: Schema.optionalKey<typeof BrowserError>;
125
- readonly phase: Schema.Literals<readonly ["capturing", "stopping", "stopped"]>;
126
- readonly observedMonotonicNanos: Schema.BigInt;
127
- /** Keeps counting when the bounded boundary prefix is truncated. */
128
- readonly currentDocument: Schema.Natural;
129
- /** No reason is reported while the capture still accepts frames. */
130
- readonly reason: Schema.NullOr<Schema.String>;
131
- /** Null until the native cleanup attempt settles; unconfirmed never means stopped remotely. */
132
- readonly nativeStop: Schema.NullOr<Schema.Literals<readonly ["confirmed", "unconfirmed"]>>;
133
- }>, {}>;
134
- /**
135
- * Host-side metadata at one instant, without reading or waking the page. The boundary prefix
136
- * and loss counters are the same facts as the final summary, independent of frame consumption.
137
- * `stopped` means native cleanup settled; buffered frames may still be drained afterwards.
138
- */
139
- declare class CaptureSnapshot extends CaptureSnapshot_base {}
140
- /** Live stream/Effect capabilities intentionally have no data schema or serialization contract. */
141
- interface CaptureInterval {
142
- /** Single subscription. Ending or interrupting it stops this interval, not its browser. */
143
- readonly frames: Stream.Stream<CapturedFrame, BrowserError>;
144
- /**
145
- * A bounded copy of recorded metadata, available during capture and after cleanup. No native
146
- * work, budget charge or subscription. Drain frames, then read `completed` for final accounting.
147
- */
148
- readonly snapshot: Effect.Effect<CaptureSnapshot>;
149
- readonly stop: Effect.Effect<CaptureSummary>;
150
- readonly completed: Effect.Effect<CaptureSummary>;
151
- }
152
- declare namespace Capture_d_exports {
153
- export { CaptureInterval, CaptureOptions, CaptureSize, CaptureSnapshot, CaptureSummary, CapturedFrame, start };
154
- }
155
- /**
156
- * Capture one remote page independently of the session's selected page.
157
- *
158
- * Requires the exact live session returned by the host; copying a session object or decoding
159
- * a durable reference cannot copy its capture authority. The private owner is not frame data.
160
- * `CapturedFrame` and `CaptureOptions` are Schema values as well as structural types. Frame
161
- * decoding checks binary/metadata fields, not the complete JPEG bitstream or target authority,
162
- * and does not copy bytes. Options decoding preserves omissions; admission applies defaults.
163
- * `CaptureInterval` remains a live scoped capability, not a schema or JSON/Tool value.
164
- */
165
- declare const start: <E>(session: BrowserSession<E>, options?: CaptureOptions) => Effect.Effect<CaptureInterval, BrowserError, Scope.Scope>;
166
- //#endregion
167
- export { CaptureSize as a, CapturedFrame as c, CaptureOptions as i, start as n, CaptureSnapshot as o, CaptureInterval as r, CaptureSummary as s, Capture_d_exports as t };
168
- //# sourceMappingURL=Capture-BvWI-l1A.d.mts.map
@@ -1,2 +0,0 @@
1
- import { a as CaptureSize, c as CapturedFrame, i as CaptureOptions, n as start, o as CaptureSnapshot, r as CaptureInterval, s as CaptureSummary } from "./Capture-BvWI-l1A.mjs";
2
- export { type CaptureInterval, CaptureOptions, CaptureSize, CaptureSnapshot, CaptureSummary, CapturedFrame, start };
package/dist/Capture.mjs DELETED
@@ -1,2 +0,0 @@
1
- import { a as CaptureSnapshot, i as CaptureSize, n as start, o as CaptureSummary, r as CaptureOptions, s as CapturedFrame } from "./Capture-Bc0z9IAi.mjs";
2
- export { CaptureOptions, CaptureSize, CaptureSnapshot, CaptureSummary, CapturedFrame, start };
@@ -1 +0,0 @@
1
- {"version":3,"file":"Client-D1_xYM9o.mjs","names":[],"sources":["../src/internal/http/Multipart.ts","../src/internal/http/Transport.ts","../src/Client.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nimport type { MultipartFile } from \"../../Client.ts\";\nimport { SafeFilename } from \"../../Transfers.ts\";\n\n/** One file part is the only multipart shape this transport produces. */\nexport type MultipartResult =\n | {\n readonly _tag: \"Encoded\";\n readonly contentType: string;\n readonly body: Uint8Array;\n }\n | { readonly _tag: \"Rejected\"; readonly reason: \"configuration\" | \"limit\" };\n\nconst FIELD = /^[a-z][a-z0-9_]{0,31}$/;\nconst MEDIA_TYPE = /^[a-z0-9][a-z0-9!#$&^_+.-]{0,63}\\/[a-z0-9][a-z0-9!#$&^_+.-]{0,63}$/;\nconst PRINTABLE_ASCII = /^[\\x20-\\x7e]+$/;\n\nconst isSafeFilename = Schema.is(SafeFilename);\n\n/** Quoting is only safe for a portable, printable, quote-free basename. */\nconst quotable = (value: string): boolean =>\n isSafeFilename(value) && PRINTABLE_ASCII.test(value) && !value.includes('\"');\n\nconst randomBoundary = (): string => {\n const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16));\n\n return `effect-agent-browserbase-${[...bytes].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\")}`;\n};\n\nconst contains = (haystack: Uint8Array, needle: Uint8Array): boolean => {\n const first = needle[0];\n\n if (first === undefined || needle.length > haystack.length) return false;\n\n outer: for (let i = 0; i <= haystack.length - needle.length; i++) {\n if (haystack[i] !== first) continue;\n for (let j = 1; j < needle.length; j++) {\n const expected = needle[j];\n\n if (expected === undefined || haystack[i + j] !== expected) continue outer;\n }\n\n return true;\n }\n\n return false;\n};\n\n/**\n * A deliberately small RFC 7578 encoder: one file part, an ASCII-quotable name and a\n * delimiter proven absent from the content. It performs no filesystem or stream work.\n */\nexport const encodeFilePart = (\n part: MultipartFile,\n maxBytes: number,\n boundaries: () => string = randomBoundary,\n): MultipartResult => {\n if (\n !FIELD.test(part.field) ||\n !quotable(part.filename) ||\n !MEDIA_TYPE.test(part.mediaType) ||\n !Number.isSafeInteger(maxBytes) ||\n maxBytes < 1 ||\n maxBytes > 2 ** 31 - 1\n ) {\n return { _tag: \"Rejected\", reason: \"configuration\" };\n }\n if (part.bytes.byteLength > maxBytes) return { _tag: \"Rejected\", reason: \"limit\" };\n const encoder = new TextEncoder();\n\n for (let attempt = 0; attempt < 4; attempt++) {\n const boundary = boundaries();\n\n if (!/^[A-Za-z0-9-]{1,70}$/.test(boundary)) continue;\n const delimiter = encoder.encode(boundary);\n\n if (contains(part.bytes, delimiter)) continue;\n\n const head = encoder.encode(\n `--${boundary}\\r\\nContent-Disposition: form-data; name=\"${part.field}\"; filename=\"${part.filename}\"\\r\\nContent-Type: ${part.mediaType}\\r\\n\\r\\n`,\n );\n\n const tail = encoder.encode(`\\r\\n--${boundary}--\\r\\n`);\n const body = new Uint8Array(head.byteLength + part.bytes.byteLength + tail.byteLength);\n\n body.set(head, 0);\n body.set(part.bytes, head.byteLength);\n body.set(tail, head.byteLength + part.bytes.byteLength);\n\n return {\n _tag: \"Encoded\",\n contentType: `multipart/form-data; boundary=${boundary}`,\n body,\n };\n }\n\n return { _tag: \"Rejected\", reason: \"configuration\" };\n};\n","import { Clock, Duration, Effect, Redacted, Schema, Stream } from \"effect\";\nimport {\n FetchHttpClient,\n HttpClient,\n HttpClientRequest,\n type HttpClientResponse,\n} from \"effect/unstable/http\";\n\nimport type { ClientMethod, ClientOptions, MultipartFile, UploadLimits } from \"../../Client.ts\";\nimport { ClientError } from \"../../Errors.ts\";\nimport { Identifier } from \"../../References.ts\";\nimport { encodeFilePart } from \"./Multipart.ts\";\n\nconst API_ORIGIN = \"https://api.browserbase.com\";\nconst MAX_JSON_BYTES = 1024 * 1024;\nconst MAX_JSON_DEPTH = 64;\n\nconst Options = Schema.Struct({\n projectId: Identifier,\n apiKey: Schema.Redacted(\n Schema.NonEmptyString.check(Schema.isMaxLength(8192), Schema.isPattern(/^[\\x21-\\x7e]+$/)),\n ),\n artifactOrigins: Schema.optionalKey(\n Schema.Array(Schema.String.check(Schema.isMaxLength(8192))).check(\n Schema.isMaxLength(32),\n Schema.isUnique(),\n ),\n ),\n requestTimeoutMillis: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 60_000 })),\n ),\n});\n\nconst nowMillis = Clock.monotonicTimeNanos.pipe(Effect.map((value) => Number(value) / 1_000_000));\n\nconst deadlineAfter = (millis: number) => nowMillis.pipe(Effect.map((now) => now + millis));\n\nconst within = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n deadline: number,\n operation: ClientError[\"operation\"],\n outcome?: \"undispatched\" | \"unknown\",\n): Effect.Effect<A, E | ClientError, R> =>\n Effect.suspend(() =>\n nowMillis.pipe(\n Effect.flatMap((now) => {\n const remaining = deadline - now;\n\n const timeout = () =>\n Effect.fail(\n ClientError.make({\n operation,\n reason: \"timeout\",\n ...(outcome === undefined ? {} : { outcome }),\n }),\n );\n\n return remaining <= 0\n ? timeout()\n : effect.pipe(\n Effect.timeoutOrElse({\n duration: Duration.millis(remaining),\n orElse: timeout,\n }),\n );\n }),\n ),\n );\n\nconst withinJsonDepth = (text: string): boolean => {\n let depth = 0;\n let quoted = false;\n let escaped = false;\n\n for (const character of text) {\n if (quoted) {\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (character === '\"') quoted = false;\n } else if (character === '\"') quoted = true;\n else if (character === \"{\" || character === \"[\") {\n if (++depth > MAX_JSON_DEPTH) return false;\n } else if (character === \"}\" || character === \"]\") depth--;\n }\n\n return true;\n};\n\nconst mediaType = (value: string | undefined): string =>\n value?.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n\nconst retryAfter = (value: string | undefined, now: number): number | undefined => {\n if (value === undefined || value.length > 128) return undefined;\n const seconds = Number(value);\n\n if (Number.isFinite(seconds) && seconds >= 0) return Math.min(60_000, seconds * 1000);\n const date = Date.parse(value);\n\n return Number.isFinite(date) ? Math.min(60_000, Math.max(0, date - now)) : undefined;\n};\n\nconst mutationOutcome = (\n method: ClientMethod,\n status?: number,\n): \"rejected\" | \"unknown\" | undefined => {\n if (method === \"GET\") return undefined;\n if (status !== undefined && [400, 401, 403, 404, 409, 410, 422, 429].includes(status)) {\n return \"rejected\";\n }\n\n return \"unknown\";\n};\n\nconst statusError = (\n method: ClientMethod,\n status: number,\n operation: ClientError[\"operation\"],\n after?: number,\n) =>\n ClientError.make({\n operation,\n reason:\n status === 401 || status === 403\n ? \"authorization\"\n : status === 429\n ? \"rate-limited\"\n : status === 409\n ? \"active\"\n : status === 410\n ? \"expired\"\n : status === 422\n ? \"disabled\"\n : status === 404\n ? \"not-found\"\n : \"provider\",\n status,\n ...(mutationOutcome(method, status) === undefined\n ? {}\n : { outcome: mutationOutcome(method, status) }),\n ...(after === undefined ? {} : { retryAfterMillis: after }),\n });\n\nconst collect = (\n stream: Stream.Stream<Uint8Array, ClientError>,\n maximum: number,\n operation: ClientError[\"operation\"],\n) =>\n Effect.gen(function* () {\n const chunks: Uint8Array[] = [];\n let total = 0;\n\n yield* Stream.runForEach(stream, (chunk) =>\n Effect.suspend(() => {\n if (chunk.byteLength > maximum - total) {\n return Effect.fail(ClientError.make({ operation, reason: \"limit\" }));\n }\n total += chunk.byteLength;\n chunks.push(chunk);\n\n return Effect.void;\n }),\n );\n\n const body = new Uint8Array(total);\n let offset = 0;\n\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return body;\n });\n\nconst validApiPath = (path: string): boolean =>\n path.startsWith(\"/v1/\") && !path.includes(\"\\\\\") && !path.includes(\"#\") && path.length <= 16_384;\n\nexport const makeTransport = Effect.fnUntraced(function* (options: ClientOptions) {\n const configured = yield* Schema.decodeEffect(Options)(options, {\n onExcessProperty: \"error\",\n }).pipe(\n Effect.mapError(() =>\n ClientError.make({\n operation: \"configure\",\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n ),\n );\n\n const apiKey = Redacted.value(configured.apiKey);\n const requestTimeoutMillis = configured.requestTimeoutMillis ?? 10_000;\n const artifactOrigins = new Set<string>();\n\n for (const origin of configured.artifactOrigins ?? []) {\n const url = yield* Effect.try({\n try: () => new URL(origin),\n catch: () =>\n ClientError.make({\n operation: \"configure\",\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n });\n\n if (url.protocol !== \"https:\" || url.origin !== origin || url.username || url.password) {\n return yield* ClientError.make({\n operation: \"configure\",\n reason: \"configuration\",\n outcome: \"undispatched\",\n });\n }\n artifactOrigins.add(origin);\n }\n\n const fetch = yield* FetchHttpClient.Fetch;\n const client = yield* HttpClient.HttpClient.pipe(Effect.provide(FetchHttpClient.layer));\n const scoped = HttpClient.withScope(client);\n\n const execute = (\n request: HttpClientRequest.HttpClientRequest,\n operation: ClientError[\"operation\"],\n outcome?: \"undispatched\" | \"unknown\",\n ) =>\n scoped.execute(request).pipe(\n Effect.provideService(FetchHttpClient.Fetch, fetch),\n Effect.provideService(FetchHttpClient.RequestInit, {\n redirect: \"manual\",\n credentials: \"omit\",\n cache: \"no-store\",\n referrerPolicy: \"no-referrer\",\n }),\n Effect.provideService(HttpClient.TracerDisabledWhen, () => true),\n Effect.provideService(HttpClient.TracerPropagationEnabled, false),\n Effect.withTracerEnabled(false),\n Effect.mapError(() =>\n ClientError.make({\n operation,\n reason: \"transport\",\n ...(outcome === undefined ? {} : { outcome }),\n }),\n ),\n );\n\n /** A rejected path is a typed, undispatched configuration failure, never a defect. */\n const apiRequest = (\n method: ClientMethod,\n path: string,\n accept: string,\n operation: ClientError[\"operation\"],\n ) =>\n validApiPath(path)\n ? Effect.succeed(\n HttpClientRequest.make(method)(`${API_ORIGIN}${path}`).pipe(\n HttpClientRequest.setHeader(\"x-bb-api-key\", apiKey),\n HttpClientRequest.setHeader(\"accept\", accept),\n ),\n )\n : Effect.fail(\n ClientError.make({ operation, reason: \"configuration\", outcome: \"undispatched\" }),\n );\n\n const inspectJson = Effect.fnUntraced(function* (\n method: ClientMethod,\n response: HttpClientResponse.HttpClientResponse,\n operation: ClientError[\"operation\"],\n ) {\n if (response.status !== 200 && response.status !== 201 && response.status !== 202) {\n return yield* statusError(\n method,\n response.status,\n operation,\n retryAfter(response.headers[\"retry-after\"], yield* Clock.currentTimeMillis),\n );\n }\n if (mediaType(response.headers[\"content-type\"]) !== \"application/json\") {\n return yield* ClientError.make({\n operation,\n reason: \"content-type\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n });\n }\n const length = response.headers[\"content-length\"];\n\n if (length !== undefined && (!/^\\d+$/.test(length) || Number(length) > MAX_JSON_BYTES)) {\n return yield* ClientError.make({\n operation,\n reason: \"limit\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n });\n }\n let received = 0;\n\n return response.stream.pipe(\n Stream.mapError(() =>\n ClientError.make({\n operation,\n reason: \"transport\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n }),\n ),\n Stream.mapEffect((chunk) =>\n Effect.suspend(() => {\n if (chunk.byteLength > MAX_JSON_BYTES - received) {\n return Effect.fail(\n ClientError.make({\n operation,\n reason: \"limit\",\n ...(mutationOutcome(method) === undefined\n ? {}\n : { outcome: mutationOutcome(method) }),\n }),\n );\n }\n received += chunk.byteLength;\n\n return Effect.succeed(new Uint8Array(chunk));\n }),\n ),\n );\n });\n\n const readJson = Effect.fnUntraced(function* (\n method: ClientMethod,\n response: HttpClientResponse.HttpClientResponse,\n operation: ClientError[\"operation\"],\n ) {\n const stream = yield* inspectJson(method, response, operation);\n const bytes = yield* collect(stream, MAX_JSON_BYTES, operation);\n\n const text = yield* Effect.try({\n try: () => new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes),\n catch: () =>\n ClientError.make({\n operation,\n reason: \"malformed\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n }),\n });\n\n if (!withinJsonDepth(text)) {\n return yield* ClientError.make({\n operation,\n reason: \"limit\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n });\n }\n\n return yield* Schema.decodeEffect(Schema.fromJsonString(Schema.Json))(text).pipe(\n Effect.mapError(() =>\n ClientError.make({\n operation,\n reason: \"malformed\",\n ...(mutationOutcome(method) === undefined ? {} : { outcome: mutationOutcome(method) }),\n }),\n ),\n );\n });\n\n const jsonOnce = Effect.fnUntraced(function* (\n method: ClientMethod,\n path: string,\n body?: Schema.Json,\n ) {\n const operation = method === \"GET\" ? \"provider-read\" : \"provider-mutation\";\n let request = yield* apiRequest(method, path, \"application/json\", operation);\n\n if (body !== undefined) {\n request = yield* HttpClientRequest.bodyJson(request, body).pipe(\n Effect.mapError(() =>\n ClientError.make({\n operation,\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n ),\n );\n }\n const response = yield* execute(request, operation, method === \"GET\" ? undefined : \"unknown\");\n\n return yield* readJson(method, response, operation);\n });\n\n /**\n * One bounded in-memory file part. The encoder proves its delimiter absent from the\n * content, and an accepted multipart mutation is never retried: a lost reply is unknown.\n */\n const upload = Effect.fnUntraced(function* (\n path: string,\n part: MultipartFile,\n limits: UploadLimits,\n outerDeadline?: number,\n ) {\n const operation = \"provider-upload\";\n const timeoutMillis = limits.timeoutMillis ?? 60_000;\n\n if (!Number.isSafeInteger(timeoutMillis) || timeoutMillis < 1 || timeoutMillis > 600_000) {\n return yield* ClientError.make({\n operation,\n reason: \"configuration\",\n outcome: \"undispatched\",\n });\n }\n\n const encoded = encodeFilePart(part, limits.maxBytes);\n\n if (encoded._tag === \"Rejected\") {\n return yield* ClientError.make({\n operation,\n reason: encoded.reason,\n outcome: \"undispatched\",\n });\n }\n\n const request = HttpClientRequest.bodyUint8Array(\n yield* apiRequest(\"POST\", path, \"application/json\", operation),\n encoded.body,\n encoded.contentType,\n );\n\n const deadline = Math.min(yield* deadlineAfter(timeoutMillis), outerDeadline ?? Infinity);\n\n return yield* within(\n Effect.scoped(\n execute(request, operation, \"unknown\").pipe(\n Effect.flatMap((response) => readJson(\"POST\", response, operation)),\n ),\n ),\n deadline,\n operation,\n \"unknown\",\n );\n });\n\n const json = Effect.fnUntraced(function* (\n method: ClientMethod,\n path: string,\n body?: Schema.Json,\n outerDeadline?: number,\n ) {\n const deadline = Math.min(\n yield* deadlineAfter(requestTimeoutMillis),\n outerDeadline ?? Infinity,\n );\n\n for (let attempt = 0; ; attempt++) {\n const result = yield* within(\n Effect.scoped(jsonOnce(method, path, body)),\n deadline,\n // A request that times out is labelled like the same request failing any other way.\n method === \"GET\" ? \"provider-read\" : \"provider-mutation\",\n method === \"GET\" ? undefined : \"unknown\",\n ).pipe(Effect.result);\n\n if (result._tag === \"Success\") return result.success;\n const error = result.failure;\n\n const retryable =\n error.reason === \"transport\" ||\n error.reason === \"rate-limited\" ||\n (error.reason === \"provider\" && (error.status ?? 0) >= 500);\n\n if (method !== \"GET\" || !retryable || attempt >= 2) return yield* error;\n const delay = error.retryAfterMillis ?? (attempt + 1) * 150;\n\n if ((yield* nowMillis) + delay >= deadline) return yield* error;\n yield* Effect.sleep(delay);\n }\n });\n\n const noContent = Effect.fnUntraced(function* (\n method: Exclude<ClientMethod, \"GET\">,\n path: string,\n body?: Schema.Json,\n outerDeadline?: number,\n ) {\n const operation = \"provider-mutation\";\n let request = yield* apiRequest(method, path, \"*/*\", operation);\n\n if (body !== undefined) {\n request = yield* HttpClientRequest.bodyJson(request, body).pipe(\n Effect.mapError(() =>\n ClientError.make({\n operation,\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n ),\n );\n }\n\n const deadline = Math.min(\n yield* deadlineAfter(requestTimeoutMillis),\n outerDeadline ?? Infinity,\n );\n\n const response = yield* within(\n Effect.scoped(execute(request, operation, \"unknown\")),\n deadline,\n operation,\n \"unknown\",\n );\n\n if (![200, 202, 204].includes(response.status)) {\n return yield* statusError(\n method,\n response.status,\n operation,\n retryAfter(response.headers[\"retry-after\"], yield* Clock.currentTimeMillis),\n );\n }\n });\n\n const inspectBytes = Effect.fnUntraced(function* (\n response: HttpClientResponse.HttpClientResponse,\n operation: ClientError[\"operation\"],\n types: ReadonlyArray<string>,\n maximum: number,\n ) {\n if (response.status !== 200 && response.status !== 206) {\n return yield* statusError(\n \"GET\",\n response.status,\n operation,\n retryAfter(response.headers[\"retry-after\"], yield* Clock.currentTimeMillis),\n );\n }\n if (!types.includes(mediaType(response.headers[\"content-type\"]))) {\n return yield* ClientError.make({ operation, reason: \"content-type\" });\n }\n const length = response.headers[\"content-length\"];\n\n if (length !== undefined && (!/^\\d+$/.test(length) || Number(length) > maximum)) {\n return yield* ClientError.make({ operation, reason: \"limit\" });\n }\n let received = 0;\n\n return response.stream.pipe(\n Stream.mapError(() => ClientError.make({ operation, reason: \"transport\" })),\n Stream.mapEffect((chunk) =>\n Effect.suspend(() => {\n if (chunk.byteLength > maximum - received) {\n return Effect.fail(ClientError.make({ operation, reason: \"limit\" }));\n }\n received += chunk.byteLength;\n\n return Effect.succeed(new Uint8Array(chunk));\n }),\n ),\n );\n });\n\n const bytes = (\n path: string,\n maximum: number,\n types: ReadonlyArray<string>,\n timeoutMillis = requestTimeoutMillis,\n outerDeadline?: number,\n ) =>\n Stream.unwrap(\n Effect.gen(function* () {\n // A bounded authenticated read. Resource services relabel it with their own operation.\n const operation = \"provider-read\";\n\n if (\n !Number.isSafeInteger(maximum) ||\n maximum < 1 ||\n maximum > 2 ** 31 - 1 ||\n !Number.isSafeInteger(timeoutMillis) ||\n timeoutMillis < 1 ||\n timeoutMillis > 600_000\n ) {\n return yield* ClientError.make({ operation, reason: \"configuration\" });\n }\n const deadline = Math.min(yield* deadlineAfter(timeoutMillis), outerDeadline ?? Infinity);\n\n const request = yield* apiRequest(\n \"GET\",\n path,\n types[0] ?? \"application/octet-stream\",\n operation,\n );\n\n const response = yield* within(execute(request, operation), deadline, operation);\n\n const stream = yield* inspectBytes(response, operation, types, maximum);\n\n return Stream.transformPull(stream, (pull) =>\n Effect.succeed(within(pull, deadline, operation)),\n );\n }),\n ).pipe(Stream.scoped);\n\n const text = (path: string, maximum: number, types: ReadonlyArray<string>) =>\n collect(bytes(path, maximum, types), maximum, \"provider-read\").pipe(\n Effect.flatMap((body) =>\n Effect.try({\n try: () => new TextDecoder(\"utf-8\", { fatal: true }).decode(body),\n catch: () => ClientError.make({ operation: \"provider-read\", reason: \"malformed\" }),\n }),\n ),\n Effect.timeoutOrElse({\n duration: Duration.millis(requestTimeoutMillis),\n orElse: () =>\n Effect.fail(ClientError.make({ operation: \"provider-read\", reason: \"timeout\" })),\n }),\n );\n\n const validateMediaUrl = (value: string): boolean => {\n try {\n const url = new URL(value);\n\n return (\n url.protocol === \"https:\" &&\n !url.username &&\n !url.password &&\n !url.hash &&\n artifactOrigins.has(url.origin) &&\n value.length <= 16_384\n );\n } catch {\n return false;\n }\n };\n\n const media = (\n url: Redacted.Redacted<string>,\n maximum: number,\n types: ReadonlyArray<string>,\n timeoutMillis = 60_000,\n outerDeadline?: number,\n ) =>\n Stream.unwrap(\n Effect.gen(function* () {\n const value = Redacted.value(url);\n\n if (\n !validateMediaUrl(value) ||\n !Number.isSafeInteger(maximum) ||\n maximum < 1 ||\n maximum > 2 ** 31 - 1 ||\n !Number.isSafeInteger(timeoutMillis) ||\n timeoutMillis < 1 ||\n timeoutMillis > 600_000\n ) {\n return yield* ClientError.make({ operation: \"media-download\", reason: \"unsafe-url\" });\n }\n const deadline = Math.min(yield* deadlineAfter(timeoutMillis), outerDeadline ?? Infinity);\n\n const response = yield* within(\n execute(HttpClientRequest.get(value), \"media-download\"),\n deadline,\n \"media-download\",\n );\n\n const stream = yield* inspectBytes(response, \"media-download\", types, maximum);\n\n return Stream.transformPull(stream, (pull) =>\n Effect.succeed(within(pull, deadline, \"media-download\")),\n );\n }),\n ).pipe(Stream.scoped);\n\n return {\n projectId: configured.projectId,\n json,\n noContent,\n upload,\n text,\n bytes,\n media,\n validateMediaUrl,\n };\n});\n","import { Config, Context, Effect, Layer, type Redacted, type Schema, type Stream } from \"effect\";\n\nimport type { ClientError } from \"./Errors.ts\";\nimport { makeTransport } from \"./internal/http/Transport.ts\";\n\n/** Account authority only. Launch recipes and browser-operation policy do not belong here. */\nexport interface ClientOptions {\n readonly projectId: string;\n readonly apiKey: Redacted.Redacted<string>;\n /** Exact HTTPS origins approved for credential-free media/artifact transfers. */\n readonly artifactOrigins?: ReadonlyArray<string>;\n readonly requestTimeoutMillis?: number;\n}\n\nexport type ClientMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\n/** One bounded in-memory file part. A filesystem path is never a transport input. */\nexport interface MultipartFile {\n readonly field: string;\n readonly filename: string;\n readonly mediaType: string;\n readonly bytes: Uint8Array;\n}\n\n/** Upload bounds are caller-owned; an omitted timeout keeps the 60-second default. */\nexport interface UploadLimits {\n readonly maxBytes: number;\n readonly timeoutMillis?: number;\n}\n\n/**\n * One immutable Browserbase account and approved transport, shared by every resource Layer.\n * Constructing the Layer performs no request and never loads the native browser peer.\n */\nexport class BrowserbaseClient extends Context.Service<\n BrowserbaseClient,\n {\n readonly projectId: string;\n readonly json: (\n method: ClientMethod,\n path: string,\n body?: Schema.Json,\n outerDeadline?: number,\n ) => Effect.Effect<Schema.Json, ClientError>;\n readonly noContent: (\n method: Exclude<ClientMethod, \"GET\">,\n path: string,\n body?: Schema.Json,\n outerDeadline?: number,\n ) => Effect.Effect<void, ClientError>;\n /** One bounded multipart mutation. A lost reply stays unknown and is never retried. */\n readonly upload: (\n path: string,\n part: MultipartFile,\n limits: UploadLimits,\n outerDeadline?: number,\n ) => Effect.Effect<Schema.Json, ClientError>;\n readonly text: (\n path: string,\n maximum: number,\n types: ReadonlyArray<string>,\n ) => Effect.Effect<string, ClientError>;\n readonly bytes: (\n path: string,\n maximum: number,\n types: ReadonlyArray<string>,\n timeoutMillis?: number,\n outerDeadline?: number,\n ) => Stream.Stream<Uint8Array, ClientError>;\n readonly media: (\n url: Redacted.Redacted<string>,\n maximum: number,\n types: ReadonlyArray<string>,\n timeoutMillis?: number,\n outerDeadline?: number,\n ) => Stream.Stream<Uint8Array, ClientError>;\n readonly validateMediaUrl: (value: string) => boolean;\n }\n>()(\"effect-browserbase/Client\") {\n static layer(options: ClientOptions): Layer.Layer<BrowserbaseClient, ClientError> {\n return Layer.effect(\n BrowserbaseClient,\n makeTransport(options).pipe(\n Effect.map((client) => BrowserbaseClient.of(Object.freeze(client))),\n ),\n );\n }\n\n /**\n * Account authority from the application's `ConfigProvider` (the environment by default):\n * `BROWSERBASE_PROJECT_ID` and a redacted `BROWSERBASE_API_KEY`. Transport options stay\n * explicit. Configuration is read when the Layer is built, never at import.\n */\n static layerConfig(\n options: Omit<ClientOptions, \"projectId\" | \"apiKey\"> = {},\n ): Layer.Layer<BrowserbaseClient, ClientError | Config.ConfigError> {\n return Layer.unwrap(\n Effect.gen(function* () {\n const projectId = yield* Config.String(\"BROWSERBASE_PROJECT_ID\");\n const apiKey = yield* Config.Redacted(\"BROWSERBASE_API_KEY\");\n\n return BrowserbaseClient.layer({ ...options, projectId, apiKey });\n }),\n );\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContextWriter-BrQmoXRg.mjs","names":[],"sources":["../src/internal/session/WriterFacts.ts","../src/internal/session/ContextWriter.ts"],"sourcesContent":["import type { Effect } from \"effect\";\nimport { Schema } from \"effect\";\n\nimport { CleanupResult } from \"../../Cleanup.ts\";\nimport { AllocationAttempt, ContextReference, SessionReference } from \"../../References.ts\";\n\n/**\n * The writer vocabulary both the public coordination entry point and the permit\n * implementation need. Keeping it here leaves one direction of dependency:\n * `ContextCoordination` and `ContextWriter` both read this module, never each other.\n */\nexport const PersistenceEvidence = Schema.Union([\n Schema.Struct({ _tag: Schema.Literal(\"NotRequested\") }),\n Schema.Struct({\n _tag: Schema.Literal(\"Unconfirmed\"),\n reason: Schema.Literals([\"writer-active\", \"writer-unknown\", \"flush-unacknowledged\"]),\n }),\n Schema.Struct({\n _tag: Schema.Literal(\"Observed\"),\n method: Schema.Literal(\"consumer-readback\"),\n observedAtMillis: Schema.Finite,\n }),\n]);\n\nexport type PersistenceEvidence = typeof PersistenceEvidence.Type;\n\nexport class WriterAttemptFacts extends Schema.Class<WriterAttemptFacts>(\n \"BrowserbaseWriterAttemptFacts\",\n)({\n attempt: AllocationAttempt,\n session: Schema.optionalKey(SessionReference),\n state: Schema.Literals([\"admitted\", \"rejected\", \"unknown\", \"terminal\"]),\n cleanup: Schema.optionalKey(CleanupResult),\n}) {}\n\nexport class WriterSettlementFacts extends Schema.Class<WriterSettlementFacts>(\n \"BrowserbaseWriterSettlementFacts\",\n)({\n reference: ContextReference,\n attempts: Schema.Array(WriterAttemptFacts).check(Schema.isMaxLength(64)),\n persistence: PersistenceEvidence,\n disposition: Schema.Literals([\"release\", \"quarantine\"]),\n}) {}\n\nexport interface WriterLease<E, R> {\n readonly settle: (facts: WriterSettlementFacts) => Effect.Effect<void, E, R>;\n}\n\nexport interface ContextWriterBackend<E, R> {\n readonly acquire: (reference: ContextReference) => Effect.Effect<WriterLease<E, R>, E, R>;\n}\n\nexport interface ContextWriterPermit {\n readonly _tag: \"ContextWriterPermit\";\n readonly reference: ContextReference;\n}\n\nexport interface WriterOptions<A, VerifyE, VerifyR> {\n /** Bounded consumer-controlled readback, not a provider-wide flush acknowledgement. */\n readonly verify?: (value: A) => Effect.Effect<void, VerifyE, VerifyR>;\n readonly settlementTimeoutMillis?: number;\n}\n","import { Effect } from \"effect\";\n\nimport type { CleanupResult } from \"../../Cleanup.ts\";\nimport { ContextError } from \"../../Errors.ts\";\nimport type { AllocationAttempt, ContextReference, SessionReference } from \"../../References.ts\";\nimport {\n type ContextWriterPermit,\n type PersistenceEvidence,\n WriterAttemptFacts,\n WriterSettlementFacts,\n} from \"./WriterFacts.ts\";\n\n/** There is one record per exact allocation attempt, not parallel uncorrelated arrays. */\ninterface AttemptRecord {\n readonly attempt: AllocationAttempt;\n session?: SessionReference;\n state: \"admitted\" | \"rejected\" | \"unknown\" | \"terminal\";\n cleanup?: CleanupResult;\n}\n\nexport interface ContextWriterPermitInternal extends ContextWriterPermit {\n readonly recordAttempt: (attempt: AllocationAttempt) => Effect.Effect<void, ContextError>;\n readonly recordSession: (attempt: AllocationAttempt, reference: SessionReference) => void;\n readonly rejected: (attempt: AllocationAttempt) => void;\n readonly uncertain: (attempt: AllocationAttempt) => void;\n readonly completed: (attempt: AllocationAttempt, cleanup: CleanupResult) => void;\n readonly confirmReadback: (atMillis: number) => Effect.Effect<void, ContextError>;\n readonly quarantine: Effect.Effect<void>;\n readonly snapshot: Effect.Effect<WriterSettlementFacts>;\n}\n\nconst authentic = new WeakMap<ContextWriterPermit, ContextWriterPermitInternal>();\nconst active = new Map<string, ContextWriterPermitInternal | \"quarantined\">();\nconst key = (ref: ContextReference) => `${ref.projectId}/${ref.contextId}`;\n\nexport const isContextWriterBusy = (ref: ContextReference): boolean => active.has(key(ref));\n\nexport const makeContextWriterPermit = (\n reference: ContextReference,\n): Effect.Effect<ContextWriterPermitInternal, ContextError> =>\n Effect.suspend(() => {\n if (active.has(key(reference)) || active.size >= 2048)\n return Effect.fail(\n ContextError.make({ operation: \"writer\", reason: \"active\", outcome: \"undispatched\" }),\n );\n const owned = Object.freeze(reference);\n const attempts = new Map<string, AttemptRecord>();\n\n let closed = false,\n quarantined = false;\n\n let persistence: PersistenceEvidence = { _tag: \"NotRequested\" };\n\n const unknown = () => {\n quarantined = true;\n persistence = { _tag: \"Unconfirmed\", reason: \"writer-unknown\" };\n };\n\n const noActive = () =>\n [...attempts.values()].every(\n (entry) => entry.state === \"rejected\" || entry.state === \"terminal\",\n );\n\n const permit: ContextWriterPermitInternal = {\n _tag: \"ContextWriterPermit\",\n reference: owned,\n recordAttempt: (attempt) =>\n Effect.suspend(() => {\n if (\n closed ||\n quarantined ||\n !noActive() ||\n attempt.projectId !== owned.projectId ||\n (attempts.size > 0 && persistence._tag === \"Unconfirmed\")\n ) {\n return Effect.fail(\n ContextError.make({\n operation: \"writer-admit\",\n reason: \"active\",\n outcome: \"undispatched\",\n }),\n );\n }\n if (attempts.has(attempt.attemptId) || attempts.size >= 64)\n return Effect.fail(\n ContextError.make({\n operation: \"writer-admit\",\n reason: \"limit\",\n outcome: \"undispatched\",\n }),\n );\n const copy = Object.freeze(attempt);\n\n attempts.set(copy.attemptId, { attempt: copy, state: \"admitted\" });\n persistence = { _tag: \"Unconfirmed\", reason: \"writer-active\" };\n\n return Effect.void;\n }),\n recordSession: (attempt, session) => {\n const record = attempts.get(attempt.attemptId);\n\n if (\n record === undefined ||\n record.attempt !== attempt ||\n session.projectId !== owned.projectId ||\n (record.session !== undefined && record.session.sessionId !== session.sessionId)\n ) {\n unknown();\n\n return;\n }\n // Retain identity even when cancellation/quarantine races a late allocation reply.\n record.session = Object.freeze(session);\n },\n rejected: (attempt) => {\n const record = attempts.get(attempt.attemptId);\n\n if (record === undefined || record.attempt !== attempt || record.session !== undefined) {\n unknown();\n\n return;\n }\n record.state = \"rejected\";\n if ([...attempts.values()].every((item) => item.state === \"rejected\"))\n persistence = { _tag: \"NotRequested\" };\n },\n uncertain: (attempt) => {\n const record = attempts.get(attempt.attemptId);\n\n if (record !== undefined && record.attempt === attempt) record.state = \"unknown\";\n unknown();\n },\n completed: (attempt, cleanup) => {\n const record = attempts.get(attempt.attemptId);\n\n if (\n record === undefined ||\n record.attempt !== attempt ||\n cleanup.ownership !== \"owned\" ||\n record.session === undefined ||\n record.session.sessionId !== cleanup.reference.sessionId ||\n cleanup.reference.projectId !== owned.projectId\n ) {\n unknown();\n\n return;\n }\n record.cleanup = cleanup;\n if (cleanup.remote !== \"confirmed\") {\n record.state = \"unknown\";\n unknown();\n\n return;\n }\n record.state = \"terminal\";\n if (cleanup.observedStatus !== \"COMPLETED\") {\n unknown();\n\n return;\n }\n if (!quarantined) persistence = { _tag: \"Unconfirmed\", reason: \"flush-unacknowledged\" };\n },\n confirmReadback: (atMillis) =>\n Effect.suspend(() => {\n if (\n closed ||\n quarantined ||\n !noActive() ||\n !Number.isFinite(atMillis) ||\n attempts.size === 0 ||\n [...attempts.values()].some(\n (entry) =>\n entry.state === \"terminal\" && entry.cleanup?.observedStatus !== \"COMPLETED\",\n )\n ) {\n return Effect.fail(\n ContextError.make({\n operation: \"writer-readback\",\n reason: \"active\",\n outcome: \"undispatched\",\n }),\n );\n }\n persistence = {\n _tag: \"Observed\",\n method: \"consumer-readback\",\n observedAtMillis: atMillis,\n };\n\n return Effect.void;\n }),\n quarantine: Effect.sync(unknown),\n snapshot: Effect.sync(() =>\n WriterSettlementFacts.make({\n reference: owned,\n attempts: [...attempts.values()].map((entry) =>\n WriterAttemptFacts.make({\n attempt: entry.attempt,\n state: entry.state,\n ...(entry.session === undefined ? {} : { session: entry.session }),\n ...(entry.cleanup === undefined ? {} : { cleanup: entry.cleanup }),\n }),\n ),\n persistence,\n disposition:\n quarantined || !noActive() || persistence._tag === \"Unconfirmed\"\n ? \"quarantine\"\n : \"release\",\n }),\n ),\n };\n\n Object.freeze(permit);\n authentic.set(permit, permit);\n active.set(key(owned), permit);\n // Explicit retirement closes admission without losing evidence attached to escaped permits.\n retirement.set(permit, (released) => {\n closed = true;\n if (active.get(key(owned)) !== permit) return;\n if (released) active.delete(key(owned));\n else active.set(key(owned), \"quarantined\");\n });\n\n return Effect.succeed(permit);\n });\n\nconst retirement = new WeakMap<ContextWriterPermitInternal, (released: boolean) => void>();\n\nexport const closeContextWriterPermit = (\n permit: ContextWriterPermitInternal,\n released: boolean,\n): void => retirement.get(permit)?.(released);\n\nexport const requireContextWriterPermit = (\n permit: ContextWriterPermit,\n reference: ContextReference,\n): Effect.Effect<ContextWriterPermitInternal, ContextError> =>\n Effect.suspend(() => {\n const actual = authentic.get(permit);\n\n return actual !== undefined &&\n active.get(key(reference)) === actual &&\n actual.reference.contextId === reference.contextId &&\n actual.reference.projectId === reference.projectId\n ? Effect.succeed(actual)\n : Effect.fail(\n ContextError.make({\n operation: \"writer-authority\",\n reason: \"authorization\",\n outcome: \"undispatched\",\n }),\n );\n });\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Extensions-ClZbYb1H.mjs","names":[],"sources":["../src/internal/extension/Archive.ts","../src/Extensions.ts"],"sourcesContent":["/**\n * A bounded, allocation-free inspection of an extension ZIP: enough to prove a root\n * `manifest.json` and reject traversal before an upload, never an extractor. No entry is\n * decompressed and no path is written; the provider remains the loader of record.\n */\nexport interface ArchiveFacts {\n readonly entries: number;\n /** Uncompressed size the central directory itself declares, not a measured expansion. */\n readonly declaredBytes: number;\n}\n\nexport type ArchiveRejection =\n | \"signature\"\n | \"malformed\"\n | \"unsupported\"\n | \"name\"\n | \"manifest\"\n | \"limit\";\n\nexport type ArchiveResult =\n | { readonly _tag: \"Accepted\"; readonly facts: ArchiveFacts }\n | { readonly _tag: \"Rejected\"; readonly reason: ArchiveRejection };\n\nconst MAX_ENTRIES = 4096;\nconst MAX_NAME_BYTES = 512;\nconst MAX_DECLARED_BYTES = 512 * 1024 * 1024;\nconst EOCD_SIZE = 22;\nconst LOCAL_HEADER_SIZE = 30;\nconst STORED = 0;\nconst DEFLATED = 8;\n\nconst LOCAL_HEADER = 0x04034b50;\nconst CENTRAL_HEADER = 0x02014b50;\nconst END_OF_CENTRAL_DIRECTORY = 0x06054b50;\n\nconst rejected = (reason: ArchiveRejection): ArchiveResult => ({ _tag: \"Rejected\", reason });\n\nconst control = (name: string): boolean =>\n [...name].some((character) => character < \" \" || character === \"\\x7f\");\n\n/** Any `..` or rooted member would name a file outside the extension directory. */\nconst unsafeName = (name: string): boolean =>\n name.length === 0 ||\n name.startsWith(\"/\") ||\n name.includes(\"\\\\\") ||\n name.includes(\"//\") ||\n /^[A-Za-z]:/.test(name) ||\n control(name) ||\n name.split(\"/\").some((segment) => segment === \".\" || segment === \"..\");\n\nexport const inspectExtensionArchive = (archive: Uint8Array): ArchiveResult => {\n if (archive.byteLength < EOCD_SIZE) return rejected(\"malformed\");\n const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);\n const u16 = (offset: number) => view.getUint16(offset, true);\n const u32 = (offset: number) => view.getUint32(offset, true);\n\n if (u32(0) !== LOCAL_HEADER) return rejected(\"signature\");\n\n // The comment is bounded by its own 16-bit length, so the record cannot hide further back.\n const earliest = Math.max(0, archive.byteLength - EOCD_SIZE - 0xffff);\n let end = -1;\n\n for (let offset = archive.byteLength - EOCD_SIZE; offset >= earliest; offset--) {\n if (u32(offset) === END_OF_CENTRAL_DIRECTORY) {\n end = offset;\n break;\n }\n }\n if (end < 0) return rejected(\"malformed\");\n\n const entries = u16(end + 10);\n const directorySize = u32(end + 12);\n const directoryOffset = u32(end + 16);\n const commentLength = u16(end + 20);\n\n if (u16(end + 4) !== 0 || u16(end + 6) !== 0 || u16(end + 8) !== entries)\n return rejected(\"unsupported\");\n if (entries === 0xffff || directorySize === 0xffffffff || directoryOffset === 0xffffffff)\n return rejected(\"unsupported\");\n if (end + EOCD_SIZE + commentLength !== archive.byteLength) return rejected(\"malformed\");\n if (directoryOffset + directorySize > end) return rejected(\"malformed\");\n if (entries > MAX_ENTRIES) return rejected(\"limit\");\n\n const names = new TextDecoder(\"utf-8\", { fatal: true });\n const limit = directoryOffset + directorySize;\n let offset = directoryOffset;\n let declaredBytes = 0;\n let manifest = false;\n\n for (let index = 0; index < entries; index++) {\n if (offset + 46 > limit || u32(offset) !== CENTRAL_HEADER) return rejected(\"malformed\");\n const flags = u16(offset + 8);\n const method = u16(offset + 10);\n const compressed = u32(offset + 20);\n const declared = u32(offset + 24);\n const nameLength = u16(offset + 28);\n const extraLength = u16(offset + 30);\n const entryCommentLength = u16(offset + 32);\n const localOffset = u32(offset + 42);\n\n if (declared === 0xffffffff || compressed === 0xffffffff || localOffset === 0xffffffff)\n return rejected(\"unsupported\");\n // An encrypted or unusually compressed member is not something a browser will load.\n if ((flags & 1) !== 0 || (method !== STORED && method !== DEFLATED))\n return rejected(\"unsupported\");\n if (nameLength === 0 || nameLength > MAX_NAME_BYTES) return rejected(\"name\");\n if (offset + 46 + nameLength + extraLength + entryCommentLength > limit)\n return rejected(\"malformed\");\n if (localOffset >= directoryOffset) return rejected(\"malformed\");\n\n let name: string;\n\n try {\n name = names.decode(archive.subarray(offset + 46, offset + 46 + nameLength));\n } catch {\n return rejected(\"name\");\n }\n if (unsafeName(name)) return rejected(\"name\");\n\n // The directory must agree with the local header it points at: a member that describes\n // itself differently in two places has no single meaning worth uploading.\n if (localOffset + LOCAL_HEADER_SIZE > directoryOffset || u32(localOffset) !== LOCAL_HEADER)\n return rejected(\"malformed\");\n const localNameLength = u16(localOffset + 26);\n const localStart = localOffset + LOCAL_HEADER_SIZE;\n\n if (\n (u16(localOffset + 6) & 1) !== 0 ||\n u16(localOffset + 8) !== method ||\n localNameLength !== nameLength ||\n localStart + localNameLength + u16(localOffset + 28) + compressed > directoryOffset\n )\n return rejected(\"malformed\");\n\n try {\n if (names.decode(archive.subarray(localStart, localStart + localNameLength)) !== name)\n return rejected(\"malformed\");\n } catch {\n return rejected(\"name\");\n }\n if (name === \"manifest.json\") manifest = true;\n declaredBytes += declared;\n if (declaredBytes > MAX_DECLARED_BYTES) return rejected(\"limit\");\n offset += 46 + nameLength + extraLength + entryCommentLength;\n }\n if (offset !== limit) return rejected(\"malformed\");\n if (!manifest) return rejected(\"manifest\");\n\n return { _tag: \"Accepted\", facts: { entries, declaredBytes } };\n};\n","import { Context, Effect, Layer, Schema } from \"effect\";\n\nimport { BrowserbaseClient } from \"./Client.ts\";\nimport type { ClientError } from \"./Errors.ts\";\nimport { ExtensionError } from \"./Errors.ts\";\nimport { inspectExtensionArchive } from \"./internal/extension/Archive.ts\";\nimport { ExtensionReference, Identifier } from \"./References.ts\";\nimport { SafeFilename } from \"./Transfers.ts\";\n\nconst Timestamp = Schema.String.check(Schema.isMaxLength(64));\n\n/** The provider documents a 100 MB archive; a caller may request less, never more. */\nconst MAX_ARCHIVE_BYTES = 100 * 1024 * 1024;\n\nconst ProviderExtension = Schema.Struct({\n id: Identifier,\n projectId: Identifier,\n fileName: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(1024))),\n createdAt: Schema.optionalKey(Timestamp),\n updatedAt: Schema.optionalKey(Timestamp),\n});\n\n/** Only fields the provider actually returned are reported; absence is never invented. */\nexport class ExtensionMetadata extends Schema.Class<ExtensionMetadata>(\n \"BrowserbaseExtensionMetadata\",\n)({\n reference: ExtensionReference,\n fileName: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(1024))),\n createdAt: Schema.optionalKey(Timestamp),\n updatedAt: Schema.optionalKey(Timestamp),\n}) {}\n\n/** Registration evidence is what this package inspected, not a provider load receipt. */\nexport class ExtensionRegistration extends Schema.Class<ExtensionRegistration>(\n \"BrowserbaseExtensionRegistration\",\n)({\n reference: ExtensionReference,\n archiveBytes: Schema.Natural,\n entries: Schema.Natural,\n declaredBytes: Schema.Natural,\n}) {}\n\nexport interface ExtensionUploadOptions {\n /** Portable basename sent with the part; defaults to `extension.zip`. */\n readonly filename?: string;\n readonly maxBytes?: number;\n readonly timeoutMillis?: number;\n}\n\nconst Upload = Schema.Struct({\n filename: Schema.optionalKey(\n SafeFilename.check(Schema.makeFilter((value) => value.toLowerCase().endsWith(\".zip\"))),\n ),\n maxBytes: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: MAX_ARCHIVE_BYTES })),\n ),\n timeoutMillis: Schema.optionalKey(\n Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 600_000 })),\n ),\n});\n\nconst fromClient = (operation: ExtensionError[\"operation\"], error: ClientError): ExtensionError =>\n ExtensionError.make({\n operation,\n reason: error.reason,\n ...(error.outcome === undefined ? {} : { outcome: error.outcome }),\n ...(error.status === undefined ? {} : { status: error.status }),\n ...(error.retryAfterMillis === undefined ? {} : { retryAfterMillis: error.retryAfterMillis }),\n });\n\nconst configuration = (operation: ExtensionError[\"operation\"]) =>\n ExtensionError.make({ operation, reason: \"configuration\", outcome: \"undispatched\" });\n\nconst malformed = (operation: ExtensionError[\"operation\"], mutation = false) =>\n ExtensionError.make({\n operation,\n reason: \"malformed\",\n ...(mutation ? { outcome: \"unknown\" as const } : {}),\n });\n\n/**\n * A provisioned extension is a durable project resource selected at launch, never uploaded\n * again on connect. The archive is inspected before transport; loading remains the provider's.\n */\nexport class BrowserbaseExtensions extends Context.Service<\n BrowserbaseExtensions,\n {\n readonly register: (\n archive: Uint8Array,\n options?: ExtensionUploadOptions,\n ) => Effect.Effect<ExtensionRegistration, ExtensionError>;\n readonly retrieve: (\n reference: ExtensionReference,\n ) => Effect.Effect<ExtensionMetadata, ExtensionError>;\n readonly delete: (reference: ExtensionReference) => Effect.Effect<void, ExtensionError>;\n }\n>()(\"effect-browserbase/Extensions\") {\n static readonly layer: Layer.Layer<BrowserbaseExtensions, never, BrowserbaseClient> =\n Layer.effect(\n BrowserbaseExtensions,\n Effect.gen(function* () {\n const client = yield* BrowserbaseClient;\n\n const validate = Effect.fnUntraced(function* (\n reference: ExtensionReference,\n operation: ExtensionError[\"operation\"],\n ) {\n const ref = yield* Schema.decodeEffect(ExtensionReference)(reference, {\n onExcessProperty: \"error\",\n }).pipe(Effect.mapError(() => configuration(operation)));\n\n if (ref.projectId !== client.projectId)\n return yield* ExtensionError.make({\n operation,\n reason: \"authorization\",\n outcome: \"undispatched\",\n });\n\n return ref;\n });\n\n const register = Effect.fn(\"BrowserbaseExtensions.register\")(function* (\n archive: Uint8Array,\n options: ExtensionUploadOptions = {},\n ) {\n const value = yield* Schema.decodeEffect(Upload)(options, {\n onExcessProperty: \"error\",\n }).pipe(Effect.mapError(() => configuration(\"extension-register\")));\n\n if (!(archive instanceof Uint8Array)) return yield* configuration(\"extension-register\");\n const maxBytes = value.maxBytes ?? MAX_ARCHIVE_BYTES;\n\n if (archive.byteLength < 1 || archive.byteLength > maxBytes)\n return yield* ExtensionError.make({\n operation: \"extension-archive\",\n reason: \"limit\",\n outcome: \"undispatched\",\n });\n\n // Inspect and send the same immutable bytes: a caller cannot swap the\n // archive between its manifest check and the multipart encoding.\n const owned = new Uint8Array(archive);\n const inspected = inspectExtensionArchive(owned);\n\n if (inspected._tag === \"Rejected\") {\n return yield* ExtensionError.make({\n operation: \"extension-archive\",\n reason:\n inspected.reason === \"limit\"\n ? \"limit\"\n : inspected.reason === \"name\"\n ? \"unsafe-filename\"\n : \"configuration\",\n outcome: \"undispatched\",\n });\n }\n\n const raw = yield* client\n .upload(\n \"/v1/extensions\",\n {\n field: \"file\",\n filename: value.filename ?? \"extension.zip\",\n mediaType: \"application/zip\",\n bytes: owned,\n },\n {\n maxBytes,\n ...(value.timeoutMillis === undefined\n ? {}\n : { timeoutMillis: value.timeoutMillis }),\n },\n )\n .pipe(Effect.mapError((error) => fromClient(\"extension-register\", error)));\n\n const created = yield* Schema.decodeUnknownEffect(ProviderExtension)(raw).pipe(\n Effect.mapError(() => malformed(\"extension-register\", true)),\n );\n\n if (created.projectId !== client.projectId)\n return yield* malformed(\"extension-register\", true);\n\n return ExtensionRegistration.make({\n reference: ExtensionReference.make({\n provider: \"browserbase\",\n projectId: client.projectId,\n extensionId: created.id,\n }),\n archiveBytes: owned.byteLength,\n entries: inspected.facts.entries,\n declaredBytes: inspected.facts.declaredBytes,\n });\n });\n\n const retrieve = Effect.fn(\"BrowserbaseExtensions.retrieve\")(function* (\n reference: ExtensionReference,\n ) {\n const ref = yield* validate(reference, \"extension-retrieve\");\n\n const raw = yield* client\n .json(\"GET\", `/v1/extensions/${encodeURIComponent(ref.extensionId)}`)\n .pipe(Effect.mapError((error) => fromClient(\"extension-retrieve\", error)));\n\n const value = yield* Schema.decodeUnknownEffect(ProviderExtension)(raw).pipe(\n Effect.mapError(() => malformed(\"extension-retrieve\")),\n );\n\n if (value.id !== ref.extensionId || value.projectId !== ref.projectId)\n return yield* malformed(\"extension-retrieve\");\n\n return ExtensionMetadata.make({\n reference: ref,\n ...(value.fileName === undefined ? {} : { fileName: value.fileName }),\n ...(value.createdAt === undefined ? {} : { createdAt: value.createdAt }),\n ...(value.updatedAt === undefined ? {} : { updatedAt: value.updatedAt }),\n });\n });\n\n const remove = Effect.fn(\"BrowserbaseExtensions.delete\")(function* (\n reference: ExtensionReference,\n ) {\n const ref = yield* validate(reference, \"extension-delete\");\n\n yield* client\n .noContent(\"DELETE\", `/v1/extensions/${encodeURIComponent(ref.extensionId)}`)\n .pipe(Effect.mapError((error) => fromClient(\"extension-delete\", error)));\n });\n\n return BrowserbaseExtensions.of({ register, retrieve, delete: remove });\n }),\n );\n}\n"],"mappings":"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"}
@@ -1,127 +0,0 @@
1
- import { BrowserError } from "./Errors.mjs";
2
- import { Schema } from "effect";
3
- //#region src/internal/browser/NativeCalls.ts
4
- /**
5
- * A native step failed. It names no operation: the owner stamps the one the caller asked for
6
- * when it admits the work, so a step's own vocabulary can never become public API.
7
- */
8
- var NativeFailure = class extends Schema.TaggedError()("NativeFailure", {
9
- reason: BrowserError.fields.reason,
10
- outcome: BrowserError.fields.outcome
11
- }) {};
12
- /**
13
- * The only way a native failure becomes public. A fenced ticket already speaks publicly and
14
- * passes through with the operation the owner gave it; a native failure keeps its reason and
15
- * takes the caller's operation; anything else is the caller's fallback.
16
- */
17
- const publicError = (error, operation, fallback) => {
18
- if (Schema.is(BrowserError)(error)) return error;
19
- const known = Schema.is(NativeFailure)(error) ? error : fallback;
20
- return BrowserError.make({
21
- operation,
22
- reason: known.reason,
23
- ...known.outcome === void 0 ? {} : { outcome: known.outcome }
24
- });
25
- };
26
- /** Shared by the Playwright driver's seams, so every native call fails in the same vocabulary. */
27
- const failure = (reason, outcome) => NativeFailure.make({
28
- reason,
29
- ...outcome === void 0 ? {} : { outcome }
30
- });
31
- const safeDecode = (codec, raw) => {
32
- try {
33
- return Schema.decodeUnknownSync(codec)(raw);
34
- } catch {
35
- throw failure("malformed");
36
- }
37
- };
38
- /**
39
- * No raw exception from Playwright crosses this private boundary. A ticket's own fence is
40
- * already a public error and passes through with the operation the owner gave it.
41
- */
42
- const sanitize = (action) => Promise.resolve().then(action).catch((error) => {
43
- throw Schema.is(BrowserError)(error) || Schema.is(NativeFailure)(error) ? error : failure("provider");
44
- });
45
- const closeWithin = async (action, milliseconds = 2e3) => {
46
- let timer;
47
- try {
48
- await Promise.race([Promise.resolve().then(action), new Promise((_, reject) => {
49
- timer = setTimeout(() => reject(failure("timeout")), milliseconds);
50
- })]);
51
- } finally {
52
- clearTimeout(timer);
53
- }
54
- };
55
- const timeout = (ticket) => {
56
- ticket.check();
57
- return ticket.remainingMillis();
58
- };
59
- //#endregion
60
- //#region src/internal/capture/Images.ts
61
- const malformed = () => failure("malformed");
62
- /** Parse framing only; a caller decoding media must still validate its complete bitstream. */
63
- const pngGeometry = (bytes) => {
64
- if (bytes.length < 33 || [
65
- 137,
66
- 80,
67
- 78,
68
- 71,
69
- 13,
70
- 10,
71
- 26,
72
- 10
73
- ].some((b, i) => bytes[i] !== b) || bytes[12] !== 73 || bytes[13] !== 72 || bytes[14] !== 68 || bytes[15] !== 82) throw malformed();
74
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
75
- if (view.getUint32(8) !== 13) throw malformed();
76
- const width = view.getUint32(16), height = view.getUint32(20);
77
- if (width === 0 || height === 0) throw malformed();
78
- return {
79
- width,
80
- height
81
- };
82
- };
83
- /** JPEG SOF dimensions avoid trusting the requested size or CSS viewport dimensions. */
84
- const jpegGeometry = (bytes) => {
85
- if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) throw malformed();
86
- let offset = 2;
87
- while (offset + 3 < bytes.length) {
88
- if (bytes[offset++] !== 255) throw malformed();
89
- while (bytes[offset] === 255) offset++;
90
- const marker = bytes[offset++];
91
- if (marker === void 0 || marker === 217 || marker === 218) break;
92
- if (marker === 1 || marker >= 208 && marker <= 215) continue;
93
- if (offset + 1 >= bytes.length) throw malformed();
94
- const size = bytes[offset] * 256 + bytes[offset + 1];
95
- if (size < 2 || offset + size > bytes.length) throw malformed();
96
- if ([
97
- 192,
98
- 193,
99
- 194,
100
- 195,
101
- 197,
102
- 198,
103
- 199,
104
- 201,
105
- 202,
106
- 203,
107
- 205,
108
- 206,
109
- 207
110
- ].includes(marker)) {
111
- if (size < 8) throw malformed();
112
- const height = bytes[offset + 3] * 256 + bytes[offset + 4];
113
- const width = bytes[offset + 5] * 256 + bytes[offset + 6];
114
- if (width === 0 || height === 0) throw malformed();
115
- return {
116
- width,
117
- height
118
- };
119
- }
120
- offset += size;
121
- }
122
- throw malformed();
123
- };
124
- //#endregion
125
- export { failure as a, sanitize as c, closeWithin as i, timeout as l, pngGeometry as n, publicError as o, NativeFailure as r, safeDecode as s, jpegGeometry as t };
126
-
127
- //# sourceMappingURL=Images-DgscEfSf.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Images-DgscEfSf.mjs","names":[],"sources":["../src/internal/browser/NativeCalls.ts","../src/internal/capture/Images.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nimport { BrowserError, type BrowserOperation } from \"../../Errors.ts\";\nimport type { Ticket } from \"./Owner.ts\";\n\n/**\n * A native step failed. It names no operation: the owner stamps the one the caller asked for\n * when it admits the work, so a step's own vocabulary can never become public API.\n */\nexport class NativeFailure extends Schema.TaggedError<NativeFailure>()(\"NativeFailure\", {\n reason: BrowserError.fields.reason,\n outcome: BrowserError.fields.outcome,\n}) {}\n\n/**\n * The only way a native failure becomes public. A fenced ticket already speaks publicly and\n * passes through with the operation the owner gave it; a native failure keeps its reason and\n * takes the caller's operation; anything else is the caller's fallback.\n */\nexport const publicError = (\n error: unknown,\n operation: BrowserOperation,\n fallback: Pick<BrowserError, \"reason\" | \"outcome\">,\n): BrowserError => {\n if (Schema.is(BrowserError)(error)) return error;\n const known = Schema.is(NativeFailure)(error) ? error : fallback;\n\n return BrowserError.make({\n operation,\n reason: known.reason,\n ...(known.outcome === undefined ? {} : { outcome: known.outcome }),\n });\n};\n\n/** Shared by the Playwright driver's seams, so every native call fails in the same vocabulary. */\nexport const failure = (reason: BrowserError[\"reason\"], outcome?: BrowserError[\"outcome\"]) =>\n NativeFailure.make({ reason, ...(outcome === undefined ? {} : { outcome }) });\n\nexport const safeDecode = <A>(codec: Schema.Codec<A, unknown, never, never>, raw: unknown): A => {\n try {\n return Schema.decodeUnknownSync(codec)(raw);\n } catch {\n throw failure(\"malformed\");\n }\n};\n\n/**\n * No raw exception from Playwright crosses this private boundary. A ticket's own fence is\n * already a public error and passes through with the operation the owner gave it.\n */\nexport const sanitize = <A>(action: () => Promise<A>): Promise<A> =>\n Promise.resolve()\n .then(action)\n .catch((error: unknown) => {\n throw Schema.is(BrowserError)(error) || Schema.is(NativeFailure)(error)\n ? error\n : failure(\"provider\");\n });\n\nexport const closeWithin = async (\n action: () => Promise<unknown>,\n milliseconds = 2000,\n): Promise<void> => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n try {\n await Promise.race([\n Promise.resolve().then(action),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(failure(\"timeout\")), milliseconds);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n};\n\n// The native timeout is finite as well as Effect's authoritative deadline. It cannot undo dispatch.\nexport const timeout = (ticket: Ticket) => {\n ticket.check();\n\n return ticket.remainingMillis();\n};\n","import { failure } from \"../browser/NativeCalls.ts\";\n\nconst malformed = () => failure(\"malformed\");\n\n/** Parse framing only; a caller decoding media must still validate its complete bitstream. */\nexport const pngGeometry = (bytes: Uint8Array): { width: number; height: number } => {\n const signature = [137, 80, 78, 71, 13, 10, 26, 10];\n\n if (\n bytes.length < 33 ||\n signature.some((b, i) => bytes[i] !== b) ||\n bytes[12] !== 73 ||\n bytes[13] !== 72 ||\n bytes[14] !== 68 ||\n bytes[15] !== 82\n )\n throw malformed();\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\n if (view.getUint32(8) !== 13) throw malformed();\n\n const width = view.getUint32(16),\n height = view.getUint32(20);\n\n if (width === 0 || height === 0) throw malformed();\n\n return { width, height };\n};\n\n/** JPEG SOF dimensions avoid trusting the requested size or CSS viewport dimensions. */\nexport const jpegGeometry = (bytes: Uint8Array): { width: number; height: number } => {\n if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) throw malformed();\n let offset = 2;\n\n while (offset + 3 < bytes.length) {\n if (bytes[offset++] !== 255) throw malformed();\n while (bytes[offset] === 255) offset++;\n const marker = bytes[offset++];\n\n if (marker === undefined || marker === 217 || marker === 218) break;\n if (marker === 1 || (marker >= 208 && marker <= 215)) continue;\n if (offset + 1 >= bytes.length) throw malformed();\n const size = bytes[offset] * 256 + bytes[offset + 1];\n\n if (size < 2 || offset + size > bytes.length) throw malformed();\n if ([192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207].includes(marker)) {\n if (size < 8) throw malformed();\n const height = bytes[offset + 3] * 256 + bytes[offset + 4];\n const width = bytes[offset + 5] * 256 + bytes[offset + 6];\n\n if (width === 0 || height === 0) throw malformed();\n\n return { width, height };\n }\n offset += size;\n }\n throw malformed();\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Launch-BHcAEq05.mjs","names":[],"sources":["../src/internal/provider/Launch.ts"],"sourcesContent":["import { Effect, Redacted, Schema } from \"effect\";\n\nimport { Viewport } from \"../../BrowserData.ts\";\nimport { BrowserError } from \"../../Errors.ts\";\nimport { LaunchRecipe, type ProxyRule } from \"../../Launch.ts\";\nimport { AllocationAttempt } from \"../../References.ts\";\n\nexport interface CompiledLaunch {\n readonly attempt: AllocationAttempt;\n readonly body: Schema.Json;\n readonly viewport: Viewport | undefined;\n readonly keepAlive: boolean;\n readonly context: { readonly id: string; readonly persist: boolean } | undefined;\n readonly recordSession: boolean;\n}\n\nexport const proxy = (rule: ProxyRule): Schema.Json =>\n rule.type === \"external\"\n ? {\n type: rule.type,\n server: rule.server,\n ...(rule.domainPattern === undefined ? {} : { domainPattern: rule.domainPattern }),\n ...(rule.username === undefined ? {} : { username: Redacted.value(rule.username) }),\n ...(rule.password === undefined ? {} : { password: Redacted.value(rule.password) }),\n }\n : rule.type === \"none\"\n ? {\n type: rule.type,\n ...(rule.domainPattern === undefined ? {} : { domainPattern: rule.domainPattern }),\n }\n : {\n type: rule.type,\n ...(rule.domainPattern === undefined ? {} : { domainPattern: rule.domainPattern }),\n ...(rule.geolocation === undefined ? {} : { geolocation: { ...rule.geolocation } }),\n };\n\n/** One validation/copy/compiler path. No legacy constructor or second default body exists. */\nexport const compileLaunch = Effect.fnUntraced(function* (\n input: unknown,\n identity: Pick<AllocationAttempt, \"projectId\" | \"attemptId\" | \"requestedAtMillis\">,\n): Effect.fn.Return<CompiledLaunch, BrowserError> {\n const recipe = yield* Schema.decodeUnknownEffect(LaunchRecipe)(input, {\n onExcessProperty: \"error\",\n }).pipe(\n Effect.mapError(() =>\n BrowserError.make({ operation: \"launch\", reason: \"configuration\", outcome: \"undispatched\" }),\n ),\n );\n\n const attempt = Object.freeze(\n AllocationAttempt.make({ ...identity, timeoutSeconds: recipe.remoteTimeoutSeconds }),\n );\n\n const settings = recipe.provider.browserSettings ?? {};\n\n const fail = () =>\n BrowserError.make({ operation: \"launch\", reason: \"configuration\", outcome: \"undispatched\" });\n\n // The qualified reference is the only extension spelling, so a foreign project cannot\n // reach POST and there is no second alias whose precedence would have to be invented.\n if (\n (recipe.context !== undefined && recipe.context.reference.projectId !== attempt.projectId) ||\n (recipe.extension !== undefined && recipe.extension.projectId !== attempt.projectId) ||\n (settings.verified === true && recipe.viewport._tag !== \"ProviderManaged\") ||\n (settings.os !== undefined && settings.verified !== true)\n )\n return yield* fail();\n\n const viewport =\n recipe.viewport._tag === \"Fixed\"\n ? yield* Schema.decodeEffect(Viewport)({\n width: recipe.viewport.width,\n height: recipe.viewport.height,\n }).pipe(Effect.mapError(fail))\n : undefined;\n\n if (Array.isArray(recipe.provider.proxies)) {\n for (const rule of recipe.provider.proxies) {\n if (\n rule.type === \"browserbase\" &&\n rule.geolocation?.state !== undefined &&\n rule.geolocation.country !== \"US\"\n )\n return yield* fail();\n if (rule.type === \"external\") {\n const valid = yield* Effect.try({\n try: () => {\n const url = new URL(rule.server);\n\n return (\n [\"http:\", \"https:\"].includes(url.protocol) &&\n !url.username &&\n !url.password &&\n !url.hash\n );\n },\n catch: fail,\n });\n\n if (!valid) return yield* fail();\n }\n }\n }\n for (const domain of settings.allowedDomains ?? []) {\n const valid = yield* Effect.try({\n try: () => {\n const url = new URL(`https://${domain}/`);\n\n return (\n !domain.includes(\"*\") &&\n url.hostname === domain &&\n !url.port &&\n !url.username &&\n !url.password\n );\n },\n catch: fail,\n });\n\n if (!valid) return yield* fail();\n }\n const metadata = recipe.provider.userMetadata ?? {};\n\n if (\n Object.keys(metadata).length > 32 ||\n Object.keys(metadata).some(\n (key) => key === \"effectAgentAttempt\" || key.startsWith(\"browserbaseIntegration\"),\n )\n )\n return yield* fail();\n const keepAlive = recipe.keepAlive ?? false;\n\n const context =\n recipe.context === undefined\n ? undefined\n : { id: recipe.context.reference.contextId, persist: recipe.context.persist };\n\n const recordSession = settings.recordSession ?? false;\n\n const body = {\n projectId: attempt.projectId,\n timeout: recipe.remoteTimeoutSeconds,\n keepAlive,\n ...(recipe.provider.region === undefined ? {} : { region: recipe.provider.region }),\n proxies: Array.isArray(recipe.provider.proxies)\n ? recipe.provider.proxies.map(proxy)\n : (recipe.provider.proxies ?? false),\n ...(recipe.provider.proxySettings === undefined\n ? {}\n : { proxySettings: recipe.provider.proxySettings }),\n ...(recipe.extension === undefined ? {} : { extensionId: recipe.extension.extensionId }),\n browserSettings: {\n ...settings,\n recordSession,\n logSession: settings.logSession ?? false,\n solveCaptchas: settings.solveCaptchas ?? false,\n ...(context === undefined ? {} : { context }),\n ...(viewport === undefined\n ? {}\n : { viewport: { width: viewport.width, height: viewport.height } }),\n },\n userMetadata: { ...metadata, browserbaseIntegrationAttempt: attempt.attemptId },\n };\n\n // Own all nested values, including arrays. The admitted body never observes later caller mutation.\n const encoded = yield* Effect.try({ try: () => JSON.stringify(body), catch: fail });\n\n if (new TextEncoder().encode(encoded).length > 64 * 1024) return yield* fail();\n\n const owned = yield* Schema.decodeEffect(Schema.fromJsonString(Schema.Json))(encoded).pipe(\n Effect.mapError(fail),\n );\n\n return { attempt, body: owned, viewport, keepAlive, context, recordSession };\n});\n"],"mappings":"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"}