effect-browserbase 0.2.0-beta.8 → 0.3.0-beta.5

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 (155) hide show
  1. package/README.md +250 -313
  2. package/dist/Browserbase-FDltiz36.mjs +542 -0
  3. package/dist/Browserbase-FDltiz36.mjs.map +1 -0
  4. package/dist/Browserbase.d.mts +105 -0
  5. package/dist/Browserbase.mjs +3 -0
  6. package/dist/BrowserbaseClient-CtAQ2rg4.d.mts +195 -0
  7. package/dist/BrowserbaseClient.d.mts +2 -0
  8. package/dist/BrowserbaseClient.mjs +190 -0
  9. package/dist/BrowserbaseClient.mjs.map +1 -0
  10. package/dist/BrowserbaseError-D1EOrLNc.d.mts +79 -0
  11. package/dist/BrowserbaseError.d.mts +2 -0
  12. package/dist/BrowserbaseError.mjs +101 -0
  13. package/dist/BrowserbaseError.mjs.map +1 -0
  14. package/dist/ContextLease.d.mts +42 -0
  15. package/dist/ContextLease.mjs +80 -0
  16. package/dist/ContextLease.mjs.map +1 -0
  17. package/dist/index.d.mts +5 -27
  18. package/dist/index.mjs +5 -26
  19. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  20. package/dist/testing/index.d.mts +134 -0
  21. package/dist/testing/index.mjs +382 -0
  22. package/dist/testing/index.mjs.map +1 -0
  23. package/package.json +51 -121
  24. package/src/Browserbase.ts +698 -0
  25. package/src/BrowserbaseClient.ts +559 -0
  26. package/src/BrowserbaseError.ts +108 -0
  27. package/src/ContextLease.ts +118 -0
  28. package/src/index.ts +7 -0
  29. package/src/internal/captureConnection.ts +214 -0
  30. package/src/testing/BrowserbaseContract.ts +170 -0
  31. package/src/testing/TestBrowserbase.ts +445 -0
  32. package/src/testing/index.ts +7 -0
  33. package/dist/Account.d.mts +0 -32
  34. package/dist/Account.mjs +0 -36
  35. package/dist/Account.mjs.map +0 -1
  36. package/dist/Acquisition-BOABu_qJ.mjs +0 -244
  37. package/dist/Acquisition-BOABu_qJ.mjs.map +0 -1
  38. package/dist/Agents-CPaTOH_g.d.mts +0 -156
  39. package/dist/Agents.d.mts +0 -3
  40. package/dist/Agents.mjs +0 -292
  41. package/dist/Agents.mjs.map +0 -1
  42. package/dist/Allocation.d.mts +0 -97
  43. package/dist/Allocation.mjs +0 -27
  44. package/dist/Allocation.mjs.map +0 -1
  45. package/dist/Authorization-Ll5f_XNM.mjs +0 -12
  46. package/dist/Authorization-Ll5f_XNM.mjs.map +0 -1
  47. package/dist/Browser-ByrWJ0ss.mjs +0 -274
  48. package/dist/Browser-ByrWJ0ss.mjs.map +0 -1
  49. package/dist/Browser.d.mts +0 -83
  50. package/dist/Browser.mjs +0 -3
  51. package/dist/BrowserBinding.d.mts +0 -13
  52. package/dist/BrowserBinding.mjs +0 -31
  53. package/dist/BrowserBinding.mjs.map +0 -1
  54. package/dist/Certificates-D4NQmyeA.d.mts +0 -34
  55. package/dist/Certificates.d.mts +0 -3
  56. package/dist/Certificates.mjs +0 -85
  57. package/dist/Certificates.mjs.map +0 -1
  58. package/dist/Cleanup-DMTDBir8.d.mts +0 -23
  59. package/dist/Cleanup.d.mts +0 -3
  60. package/dist/Cleanup.mjs +0 -43
  61. package/dist/Cleanup.mjs.map +0 -1
  62. package/dist/Client-BEC4Q8ZS.mjs +0 -564
  63. package/dist/Client-BEC4Q8ZS.mjs.map +0 -1
  64. package/dist/Client-B_f6bBLT.d.mts +0 -52
  65. package/dist/Client.d.mts +0 -3
  66. package/dist/Client.mjs +0 -2
  67. package/dist/Connection-sxyxtwlk.mjs +0 -56
  68. package/dist/Connection-sxyxtwlk.mjs.map +0 -1
  69. package/dist/ContextCoordination.d.mts +0 -29
  70. package/dist/ContextCoordination.mjs +0 -94
  71. package/dist/ContextCoordination.mjs.map +0 -1
  72. package/dist/ContextWriter-CiEma24z.mjs +0 -204
  73. package/dist/ContextWriter-CiEma24z.mjs.map +0 -1
  74. package/dist/Contexts-DqdL7cyX.d.mts +0 -31
  75. package/dist/Contexts.d.mts +0 -3
  76. package/dist/Contexts.mjs +0 -97
  77. package/dist/Contexts.mjs.map +0 -1
  78. package/dist/Deadline-CrViaogr.mjs +0 -13
  79. package/dist/Deadline-CrViaogr.mjs.map +0 -1
  80. package/dist/Downloads-CX52GOFJ.d.mts +0 -43
  81. package/dist/Downloads.d.mts +0 -3
  82. package/dist/Downloads.mjs +0 -137
  83. package/dist/Downloads.mjs.map +0 -1
  84. package/dist/Errors.d.mts +0 -100
  85. package/dist/Errors.mjs +0 -194
  86. package/dist/Errors.mjs.map +0 -1
  87. package/dist/Extensions-BTUn9zhK.mjs +0 -231
  88. package/dist/Extensions-BTUn9zhK.mjs.map +0 -1
  89. package/dist/Extensions-DBXuVM1f.d.mts +0 -43
  90. package/dist/Extensions.d.mts +0 -3
  91. package/dist/Extensions.mjs +0 -2
  92. package/dist/Functions-CsKMMUuZ.d.mts +0 -226
  93. package/dist/Functions.d.mts +0 -3
  94. package/dist/Functions.mjs +0 -318
  95. package/dist/Functions.mjs.map +0 -1
  96. package/dist/Issued-DejqoMYL.mjs +0 -15
  97. package/dist/Issued-DejqoMYL.mjs.map +0 -1
  98. package/dist/Launch-cAdE2rrZ.mjs +0 -115
  99. package/dist/Launch-cAdE2rrZ.mjs.map +0 -1
  100. package/dist/Launch.d.mts +0 -127
  101. package/dist/Launch.mjs +0 -97
  102. package/dist/Launch.mjs.map +0 -1
  103. package/dist/PageFetch-CjAM_0DS.d.mts +0 -40
  104. package/dist/PageFetch.d.mts +0 -3
  105. package/dist/PageFetch.mjs +0 -59
  106. package/dist/PageFetch.mjs.map +0 -1
  107. package/dist/Projects-tm5bTDH0.d.mts +0 -38
  108. package/dist/Projects.d.mts +0 -3
  109. package/dist/Projects.mjs +0 -65
  110. package/dist/Projects.mjs.map +0 -1
  111. package/dist/Recordings-B9k5aODB.d.mts +0 -27
  112. package/dist/Recordings.d.mts +0 -3
  113. package/dist/Recordings.mjs +0 -144
  114. package/dist/Recordings.mjs.map +0 -1
  115. package/dist/References-DOH3Wu44.d.mts +0 -34
  116. package/dist/References.d.mts +0 -3
  117. package/dist/References.mjs +0 -33
  118. package/dist/References.mjs.map +0 -1
  119. package/dist/Replays-mV93WGtx.d.mts +0 -27
  120. package/dist/Replays.d.mts +0 -3
  121. package/dist/Replays.mjs +0 -107
  122. package/dist/Replays.mjs.map +0 -1
  123. package/dist/Resource-J7Kkk5mu.mjs +0 -54
  124. package/dist/Resource-J7Kkk5mu.mjs.map +0 -1
  125. package/dist/Search-B64e7g-h.d.mts +0 -37
  126. package/dist/Search.d.mts +0 -3
  127. package/dist/Search.mjs +0 -46
  128. package/dist/Search.mjs.map +0 -1
  129. package/dist/SessionData-5xYZDshJ.d.mts +0 -38
  130. package/dist/SessionData.d.mts +0 -3
  131. package/dist/SessionData.mjs +0 -48
  132. package/dist/SessionData.mjs.map +0 -1
  133. package/dist/Sessions-D2H5m6rF.mjs +0 -260
  134. package/dist/Sessions-D2H5m6rF.mjs.map +0 -1
  135. package/dist/Sessions-oJEUmZth.d.mts +0 -69
  136. package/dist/Sessions.d.mts +0 -4
  137. package/dist/Sessions.mjs +0 -3
  138. package/dist/Testing.d.mts +0 -119
  139. package/dist/Testing.mjs +0 -206
  140. package/dist/Testing.mjs.map +0 -1
  141. package/dist/TransferPolicy-DQ06i7SZ.mjs +0 -25
  142. package/dist/TransferPolicy-DQ06i7SZ.mjs.map +0 -1
  143. package/dist/Transfers-GVqzrDWl.d.mts +0 -89
  144. package/dist/Transfers.d.mts +0 -3
  145. package/dist/Transfers.mjs +0 -85
  146. package/dist/Transfers.mjs.map +0 -1
  147. package/dist/Uploads-C2_bACgv.d.mts +0 -28
  148. package/dist/Uploads.d.mts +0 -3
  149. package/dist/Uploads.mjs +0 -105
  150. package/dist/Uploads.mjs.map +0 -1
  151. package/dist/Webhooks-BoeRAxzG.d.mts +0 -59
  152. package/dist/Webhooks.d.mts +0 -3
  153. package/dist/Webhooks.mjs +0 -134
  154. package/dist/Webhooks.mjs.map +0 -1
  155. package/dist/WriterFacts-BBJRDZYY.d.mts +0 -54
@@ -1 +0,0 @@
1
- {"version":3,"file":"Client-BEC4Q8ZS.mjs","names":["Trace.span","Trace.stream"],"sources":["../src/internal/Trace.ts","../src/internal/http/Multipart.ts","../src/internal/http/Transport.ts","../src/Client.ts"],"sourcesContent":["import {\n Cause,\n Clock,\n Context,\n Effect,\n Exit,\n Option,\n References,\n Schema,\n Stream,\n Tracer,\n} from \"effect\";\n\nimport {\n AllocationError,\n ArtifactError,\n CertificateError,\n ClientError,\n ContextError,\n ExtensionError,\n FileError,\n PlatformError,\n ProjectError,\n SessionError,\n} from \"../Errors.ts\";\n\nconst Failure = Schema.Union([\n AllocationError,\n ArtifactError,\n CertificateError,\n ClientError,\n ContextError,\n ExtensionError,\n FileError,\n PlatformError,\n ProjectError,\n SessionError,\n]);\n\n/** Causality crosses ownership boundaries as ids and sampling, never a live caller context. */\nexport const capture = Effect.gen(function* () {\n const current = yield* Effect.serviceOption(Tracer.ParentSpan);\n const enabled = yield* References.TracerEnabled;\n\n return yield* Effect.sync(() => {\n try {\n let parent = Option.getOrUndefined(current);\n\n while (parent !== undefined && Context.get(parent.annotations, Tracer.DisablePropagation))\n parent = parent._tag === \"Span\" ? Option.getOrUndefined(parent.parent) : undefined;\n\n return {\n enabled,\n parent:\n parent === undefined\n ? undefined\n : Object.freeze(\n Tracer.externalSpan({\n traceId: parent.traceId,\n spanId: parent.spanId,\n sampled: parent.sampled,\n }),\n ),\n };\n } catch {\n // A broken tracer identity cannot turn causal capture into an operation defect.\n return { enabled: false, parent: undefined };\n }\n });\n});\n\nexport type Identity = Effect.Success<typeof capture>;\n\n/** A native page callback has no observable Tool caller. It starts a linked, sampling-aware root. */\nexport const autonomous = (identity: Identity): Tracer.SpanOptionsNoTrace => ({\n root: true,\n links: identity.parent === undefined ? [] : [{ span: identity.parent, attributes: {} }],\n ...(identity.parent?.sampled === false ? { sampled: false } : {}),\n});\n\nexport interface Started {\n readonly span: Tracer.Span;\n readonly end: (exit: Exit.Exit<unknown, unknown>, attributes?: Record<string, unknown>) => void;\n}\n\n/** Only finite, library-owned facts are passed here; exporter pressure loses telemetry only. */\nexport const annotate = (attributes: Record<string, unknown>) =>\n Effect.gen(function* () {\n if (!(yield* References.TracerEnabled)) return;\n const current = yield* Effect.serviceOption(Tracer.ParentSpan);\n\n if (Option.isNone(current) || current.value._tag !== \"Span\") return;\n const span = current.value;\n\n yield* Effect.sync(() => {\n try {\n for (const [key, value] of Object.entries(attributes)) span.attribute(key, value);\n } catch {\n // Result construction and cleanup must not depend on exporter health.\n }\n });\n });\n\n/**\n * Library spans export neither successful values nor original causes/stacks. Tracer failures\n * cannot suppress dispatch or alter its result. Sampling metadata is available in annotations\n * at creation: rc.117 applies SpanOptions.attributes only after Tracer.span has returned.\n */\nexport const start = Effect.fnUntraced(function* (\n name: string,\n options: Tracer.SpanOptionsNoTrace = {},\n): Effect.fn.Return<Started | undefined> {\n const identity = yield* capture;\n\n if (!identity.enabled) return undefined;\n const clock = yield* Clock.Clock;\n const timing = yield* References.TracerTimingEnabled;\n const attributes = options.attributes ?? {};\n\n const parent = options.parent ?? (options.root === true ? undefined : identity.parent);\n\n const created = yield* Effect.makeSpan(name, {\n ...options,\n attributes: undefined,\n parent,\n root: options.root ?? parent === undefined,\n annotations: Context.make(References.TracerSpanAnnotations, attributes),\n }).pipe(\n Effect.provideService(References.TracerSpanAnnotations, {}),\n Effect.provideService(References.TracerSpanLinks, []),\n Effect.exit,\n );\n\n if (Exit.isFailure(created)) return undefined;\n\n return yield* Effect.sync((): Started => {\n const span = created.value;\n let ended = false;\n\n try {\n for (const [key, value] of Object.entries(attributes)) span.attribute(key, value);\n } catch {\n // Retain the allocated span for one termination even if its attributes were refused.\n }\n\n return {\n span,\n end: (exit, extra = {}) => {\n if (ended) return;\n ended = true;\n const interrupted = Exit.isFailure(exit) && Cause.hasInterruptsOnly(exit.cause);\n\n try {\n const failure = Exit.isFailure(exit)\n ? Option.getOrUndefined(Cause.findErrorOption(exit.cause))\n : undefined;\n\n const known = Schema.is(Failure)(failure) ? failure : undefined;\n\n for (const [key, value] of Object.entries(extra)) span.attribute(key, value);\n span.attribute(\n \"browser.status\",\n Exit.isSuccess(exit) ? \"success\" : interrupted ? \"interrupted\" : \"failure\",\n );\n if (known !== undefined) {\n span.attribute(\"browser.reason\", known.reason);\n if (\"outcome\" in known && known.outcome !== undefined)\n span.attribute(\"browser.outcome\", known.outcome);\n }\n } catch {\n // Exporter pressure and shutdown are telemetry loss, never an operation failure.\n }\n try {\n span.end(\n timing ? clock.currentTimeNanosUnsafe() : 0n,\n Exit.isSuccess(exit)\n ? Exit.void\n : Exit.fail(interrupted ? \"Operation interrupted\" : \"Operation failed\"),\n );\n } catch {\n // An exporter is allowed to fail after accepting a span; never retry its termination.\n }\n },\n };\n });\n});\n\nexport const span =\n (name: string, options: Tracer.SpanOptionsNoTrace = {}) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.uninterruptibleMask((restore) =>\n start(name, options).pipe(\n Effect.flatMap((started) =>\n started === undefined\n ? restore(effect)\n : restore(effect).pipe(\n Effect.provideService(Tracer.ParentSpan, started.span),\n Effect.onExit((exit) => Effect.sync(() => started.end(exit))),\n ),\n ),\n ),\n );\n\n/** One span per consumption; end after setup, pulls and the original channel scope's finalizers. */\nexport const stream =\n (name: string, options: Tracer.SpanOptionsNoTrace = {}) =>\n <A, E, R>(source: Stream.Stream<A, E, R>): Stream.Stream<A, E, R> =>\n Stream.suspend(() => {\n let terminal: Exit.Exit<unknown, unknown> | undefined;\n\n return Stream.unwrap(\n Effect.uninterruptible(\n start(name, options).pipe(\n Effect.flatMap((value) => {\n return value === undefined\n ? Effect.succeed(source)\n : Effect.addFinalizer((exit) =>\n Effect.sync(() => value.end(terminal ?? exit)),\n ).pipe(\n Effect.as(source.pipe(Stream.provideService(Tracer.ParentSpan, value.span))),\n );\n }),\n ),\n ),\n ).pipe(\n Stream.onExit((exit) =>\n Effect.sync(() => {\n terminal = exit;\n }),\n ),\n );\n });\n","import { Effect, Random, 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\n/**\n * Sixteen bytes from the fiber's `Random`. A boundary needs no secrecy: the encoder checks that\n * the content does not contain it, and draws another if it does.\n */\nconst randomBoundary: Effect.Effect<string> = Effect.map(\n Effect.all(Array.from({ length: 16 }, () => Random.nextIntBetween(0, 255))),\n (bytes) =>\n `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 = Effect.fnUntraced(function* (\n part: MultipartFile,\n maxBytes: number,\n boundaries: Effect.Effect<string> = randomBoundary,\n): Effect.fn.Return<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 = yield* 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 * as Trace from \"../Trace.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 traceMethod = (method: string) =>\n [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"].includes(method) ? method : \"invalid\";\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 Trace.span(\"BrowserbaseClient.execute\", {\n attributes: {\n \"browser.operation\": operation,\n \"http.request.method\": traceMethod(request.method),\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 }, Trace.span(\"BrowserbaseClient.decodeJson\"));\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(\n function* (path: string, part: MultipartFile, limits: UploadLimits, outerDeadline?: number) {\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 = yield* 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 Trace.span(\"BrowserbaseClient.upload\", {\n attributes: { \"browser.operation\": \"provider-upload\", \"http.request.method\": \"POST\" },\n }),\n );\n\n const json = Effect.fnUntraced(\n function* (method: ClientMethod, path: string, body?: Schema.Json, outerDeadline?: number) {\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(\n Trace.span(\"BrowserbaseClient.request\", {\n attributes: {\n \"browser.operation\": method === \"GET\" ? \"provider-read\" : \"provider-mutation\",\n \"http.request.method\": traceMethod(method),\n },\n }),\n Effect.result,\n );\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 (effect, method) =>\n effect.pipe(\n Trace.span(\"BrowserbaseClient.json\", {\n attributes: {\n \"browser.operation\": method === \"GET\" ? \"provider-read\" : \"provider-mutation\",\n \"http.request.method\": traceMethod(method),\n },\n }),\n ),\n );\n\n const noContent = Effect.fnUntraced(\n 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 (effect, method) =>\n effect.pipe(\n Trace.span(\"BrowserbaseClient.noContent\", {\n attributes: {\n \"browser.operation\": \"provider-mutation\",\n \"http.request.method\": traceMethod(method),\n },\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(\n Stream.scoped,\n Trace.stream(\"BrowserbaseClient.bytes\", {\n attributes: { \"browser.operation\": \"provider-read\", \"http.request.method\": \"GET\" },\n }),\n );\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 Trace.span(\"BrowserbaseClient.text\", {\n attributes: { \"browser.operation\": \"provider-read\", \"http.request.method\": \"GET\" },\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(\n Stream.scoped,\n Trace.stream(\"BrowserbaseClient.media\", {\n attributes: { \"browser.operation\": \"media-download\", \"http.request.method\": \"GET\" },\n }),\n );\n\n return {\n projectId: configured.projectId,\n json,\n noContent,\n upload,\n text,\n bytes,\n media,\n validateMediaUrl,\n };\n}, Trace.span(\"BrowserbaseClient.configure\"));\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,52 +0,0 @@
1
- import { ClientError } from "./Errors.mjs";
2
- import { Config, Context, Effect, Layer, Redacted, Schema, Stream } from "effect";
3
- //#region src/Client.d.ts
4
- /** Account authority only. Launch recipes and browser-operation policy do not belong here. */
5
- interface ClientOptions {
6
- readonly projectId: string;
7
- readonly apiKey: Redacted.Redacted<string>;
8
- /** Exact HTTPS origins approved for credential-free media/artifact transfers. */
9
- readonly artifactOrigins?: ReadonlyArray<string>;
10
- readonly requestTimeoutMillis?: number;
11
- }
12
- type ClientMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
13
- /** One bounded in-memory file part. A filesystem path is never a transport input. */
14
- interface MultipartFile {
15
- readonly field: string;
16
- readonly filename: string;
17
- readonly mediaType: string;
18
- readonly bytes: Uint8Array;
19
- }
20
- /** Upload bounds are caller-owned; an omitted timeout keeps the 60-second default. */
21
- interface UploadLimits {
22
- readonly maxBytes: number;
23
- readonly timeoutMillis?: number;
24
- }
25
- declare const BrowserbaseClient_base: Context.ServiceClass<BrowserbaseClient, "effect-browserbase/Client", {
26
- readonly projectId: string;
27
- readonly json: (method: ClientMethod, path: string, body?: Schema.Json, outerDeadline?: number) => Effect.Effect<Schema.Json, ClientError>;
28
- readonly noContent: (method: Exclude<ClientMethod, "GET">, path: string, body?: Schema.Json, outerDeadline?: number) => Effect.Effect<void, ClientError>;
29
- /** One bounded multipart mutation. A lost reply stays unknown and is never retried. */
30
- readonly upload: (path: string, part: MultipartFile, limits: UploadLimits, outerDeadline?: number) => Effect.Effect<Schema.Json, ClientError>;
31
- readonly text: (path: string, maximum: number, types: ReadonlyArray<string>) => Effect.Effect<string, ClientError>;
32
- readonly bytes: (path: string, maximum: number, types: ReadonlyArray<string>, timeoutMillis?: number, outerDeadline?: number) => Stream.Stream<Uint8Array, ClientError>;
33
- readonly media: (url: Redacted.Redacted<string>, maximum: number, types: ReadonlyArray<string>, timeoutMillis?: number, outerDeadline?: number) => Stream.Stream<Uint8Array, ClientError>;
34
- readonly validateMediaUrl: (value: string) => boolean;
35
- }>;
36
- /**
37
- * One immutable Browserbase account and approved transport, shared by every resource Layer.
38
- * Constructing the Layer performs no request and never loads the native browser peer.
39
- */
40
- declare class BrowserbaseClient extends BrowserbaseClient_base {
41
- static layer(options: ClientOptions): Layer.Layer<BrowserbaseClient, ClientError>;
42
- /**
43
- * Account authority from the application's `ConfigProvider` (the environment by default):
44
- * `BROWSERBASE_PROJECT_ID` and a redacted `BROWSERBASE_API_KEY`. Transport options stay
45
- * explicit. Configuration is read when the Layer is built, never at import.
46
- */
47
- static layerConfig(options?: Omit<ClientOptions, "projectId" | "apiKey">): Layer.Layer<BrowserbaseClient, ClientError | Config.ConfigError>;
48
- }
49
- //#endregion
50
- export { UploadLimits as a, MultipartFile as i, ClientMethod as n, ClientOptions as r, BrowserbaseClient as t };
51
- export {};
52
- //# sourceMappingURL=Client-B_f6bBLT.d.mts.map
package/dist/Client.d.mts DELETED
@@ -1,3 +0,0 @@
1
- import { a as UploadLimits, i as MultipartFile, n as ClientMethod, r as ClientOptions, t as BrowserbaseClient } from "./Client-B_f6bBLT.mjs";
2
- export { BrowserbaseClient, ClientMethod, ClientOptions, MultipartFile, UploadLimits };
3
- export {};
package/dist/Client.mjs DELETED
@@ -1,2 +0,0 @@
1
- import { t as BrowserbaseClient } from "./Client-BEC4Q8ZS.mjs";
2
- export { BrowserbaseClient };
@@ -1,56 +0,0 @@
1
- import { SessionReference } from "./References.mjs";
2
- import { SessionError } from "./Errors.mjs";
3
- import { ProviderSession } from "./SessionData.mjs";
4
- import { n as nowMillis, r as until, t as deadlineAfter } from "./Deadline-CrViaogr.mjs";
5
- import { Effect, Redacted, Schema } from "effect";
6
- import { BrowserError, Reasons } from "effect-browser/errors";
7
- //#region src/internal/provider/Connection.ts
8
- const Connection = Schema.Struct({
9
- ...ProviderSession.fields,
10
- connectUrl: Schema.String.check(Schema.isMaxLength(16384))
11
- });
12
- /** A provider-issued endpoint is authority, not a persisted session identifier. */
13
- const connectionUrl = Schema.String.check(Schema.isMaxLength(16384), Schema.makeFilter((value) => {
14
- try {
15
- const url = new URL(value);
16
- return url.protocol === "wss:" && !url.username && !url.password && !url.port && !url.hash && url.hostname.endsWith(".browserbase.com");
17
- } catch {
18
- return false;
19
- }
20
- }));
21
- /** The provider endpoint is validated before any custom routing gets to observe it. */
22
- const validateConnection = (connection) => {
23
- if (typeof connection !== "string" || connection.length > 16384 || !URL.canParse(connection)) throw BrowserError.make({
24
- operation: "connect",
25
- reason: Reasons.Malformed.make({}),
26
- outcome: "undispatched"
27
- });
28
- if (!Schema.is(connectionUrl)(connection)) throw BrowserError.make({
29
- operation: "connect",
30
- reason: Reasons.UnsafeUrl.make({}),
31
- outcome: "undispatched"
32
- });
33
- return connection;
34
- };
35
- const connectionAddress = Effect.fnUntraced(function* (client, sessions, reference, remainingMillis) {
36
- const timeoutMillis = Math.min(6e5, remainingMillis);
37
- const fail = (reason) => SessionError.make({
38
- operation: "session-connect",
39
- reason
40
- });
41
- const ref = yield* Schema.decodeEffect(SessionReference)(reference).pipe(Effect.mapError(() => fail("configuration")));
42
- if (ref.projectId !== client.projectId) return yield* fail("authorization");
43
- const deadline = yield* deadlineAfter(timeoutMillis);
44
- yield* sessions.waitUntilRunning(ref, { timeoutMillis });
45
- if ((yield* nowMillis) >= deadline) return yield* fail("timeout");
46
- const raw = yield* until(client.json("GET", `/v1/sessions/${encodeURIComponent(ref.sessionId)}`, void 0, deadline), deadline, () => fail("timeout")).pipe(Effect.mapError((error) => fail(error.reason)));
47
- const value = yield* Schema.decodeUnknownEffect(Connection)(raw).pipe(Effect.mapError(() => fail("malformed")));
48
- if (value.id !== ref.sessionId || value.projectId !== ref.projectId) return yield* fail("malformed");
49
- if (value.status !== "RUNNING") return yield* fail("expired");
50
- const url = yield* Schema.decodeEffect(connectionUrl)(value.connectUrl).pipe(Effect.mapError(() => fail("unsafe-url")));
51
- return Redacted.make(url);
52
- });
53
- //#endregion
54
- export { validateConnection as n, connectionAddress as t };
55
-
56
- //# sourceMappingURL=Connection-sxyxtwlk.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Connection-sxyxtwlk.mjs","names":[],"sources":["../src/internal/provider/Connection.ts"],"sourcesContent":["import { Effect, Redacted, Schema } from \"effect\";\nimport { BrowserError, Reasons } from \"effect-browser/errors\";\n\nimport type { BrowserbaseClient } from \"../../Client.ts\";\nimport { SessionError } from \"../../Errors.ts\";\nimport { SessionReference } from \"../../References.ts\";\nimport { ProviderSession } from \"../../SessionData.ts\";\nimport type { BrowserbaseSessions } from \"../../Sessions.ts\";\nimport { deadlineAfter, nowMillis, until } from \"../Deadline.ts\";\n\nconst Connection = Schema.Struct({\n ...ProviderSession.fields,\n connectUrl: Schema.String.check(Schema.isMaxLength(16384)),\n});\n\n/** A provider-issued endpoint is authority, not a persisted session identifier. */\nexport const connectionUrl = Schema.String.check(\n Schema.isMaxLength(16384),\n Schema.makeFilter((value) => {\n try {\n const url = new URL(value);\n\n return (\n url.protocol === \"wss:\" &&\n !url.username &&\n !url.password &&\n !url.port &&\n !url.hash &&\n url.hostname.endsWith(\".browserbase.com\")\n );\n } catch {\n return false;\n }\n }),\n);\n\n/** The provider endpoint is validated before any custom routing gets to observe it. */\nexport const validateConnection = (connection: unknown): string => {\n if (typeof connection !== \"string\" || connection.length > 16384 || !URL.canParse(connection))\n throw BrowserError.make({\n operation: \"connect\",\n reason: Reasons.Malformed.make({}),\n outcome: \"undispatched\",\n });\n if (!Schema.is(connectionUrl)(connection))\n throw BrowserError.make({\n operation: \"connect\",\n reason: Reasons.UnsafeUrl.make({}),\n outcome: \"undispatched\",\n });\n\n return connection;\n};\n\nexport const connectionAddress = Effect.fnUntraced(function* (\n client: BrowserbaseClient[\"Service\"],\n sessions: BrowserbaseSessions[\"Service\"],\n reference: SessionReference,\n remainingMillis: number,\n) {\n const timeoutMillis = Math.min(600_000, remainingMillis);\n\n const fail = (reason: SessionError[\"reason\"]) =>\n SessionError.make({ operation: \"session-connect\", reason });\n\n const ref = yield* Schema.decodeEffect(SessionReference)(reference).pipe(\n Effect.mapError(() => fail(\"configuration\")),\n );\n\n if (ref.projectId !== client.projectId) return yield* fail(\"authorization\");\n const deadline = yield* deadlineAfter(timeoutMillis);\n\n yield* sessions.waitUntilRunning(ref, { timeoutMillis });\n if ((yield* nowMillis) >= deadline) return yield* fail(\"timeout\");\n\n const raw = yield* until(\n client.json(\"GET\", `/v1/sessions/${encodeURIComponent(ref.sessionId)}`, undefined, deadline),\n deadline,\n () => fail(\"timeout\"),\n ).pipe(Effect.mapError((error) => fail(error.reason)));\n\n const value = yield* Schema.decodeUnknownEffect(Connection)(raw).pipe(\n Effect.mapError(() => fail(\"malformed\")),\n );\n\n if (value.id !== ref.sessionId || value.projectId !== ref.projectId)\n return yield* fail(\"malformed\");\n if (value.status !== \"RUNNING\") return yield* fail(\"expired\");\n\n const url = yield* Schema.decodeEffect(connectionUrl)(value.connectUrl).pipe(\n Effect.mapError(() => fail(\"unsafe-url\")),\n );\n\n return Redacted.make(url);\n});\n"],"mappings":";;;;;;;AAUA,MAAM,aAAa,OAAO,OAAO;CAC/B,GAAG,gBAAgB;CACnB,YAAY,OAAO,OAAO,MAAM,OAAO,YAAY,KAAK,CAAC;AAC3D,CAAC;;AAGD,MAAa,gBAAgB,OAAO,OAAO,MACzC,OAAO,YAAY,KAAK,GACxB,OAAO,YAAY,UAAU;CAC3B,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,KAAK;EAEzB,OACE,IAAI,aAAa,UACjB,CAAC,IAAI,YACL,CAAC,IAAI,YACL,CAAC,IAAI,QACL,CAAC,IAAI,QACL,IAAI,SAAS,SAAS,kBAAkB;CAE5C,QAAQ;EACN,OAAO;CACT;AACF,CAAC,CACH;;AAGA,MAAa,sBAAsB,eAAgC;CACjE,IAAI,OAAO,eAAe,YAAY,WAAW,SAAS,SAAS,CAAC,IAAI,SAAS,UAAU,GACzF,MAAM,aAAa,KAAK;EACtB,WAAW;EACX,QAAQ,QAAQ,UAAU,KAAK,CAAC,CAAC;EACjC,SAAS;CACX,CAAC;CACH,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,CAAC,UAAU,GACtC,MAAM,aAAa,KAAK;EACtB,WAAW;EACX,QAAQ,QAAQ,UAAU,KAAK,CAAC,CAAC;EACjC,SAAS;CACX,CAAC;CAEH,OAAO;AACT;AAEA,MAAa,oBAAoB,OAAO,WAAW,WACjD,QACA,UACA,WACA,iBACA;CACA,MAAM,gBAAgB,KAAK,IAAI,KAAS,eAAe;CAEvD,MAAM,QAAQ,WACZ,aAAa,KAAK;EAAE,WAAW;EAAmB;CAAO,CAAC;CAE5D,MAAM,MAAM,OAAO,OAAO,aAAa,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,KAClE,OAAO,eAAe,KAAK,eAAe,CAAC,CAC7C;CAEA,IAAI,IAAI,cAAc,OAAO,WAAW,OAAO,OAAO,KAAK,eAAe;CAC1E,MAAM,WAAW,OAAO,cAAc,aAAa;CAEnD,OAAO,SAAS,iBAAiB,KAAK,EAAE,cAAc,CAAC;CACvD,KAAK,OAAO,cAAc,UAAU,OAAO,OAAO,KAAK,SAAS;CAEhE,MAAM,MAAM,OAAO,MACjB,OAAO,KAAK,OAAO,gBAAgB,mBAAmB,IAAI,SAAS,KAAK,KAAA,GAAW,QAAQ,GAC3F,gBACM,KAAK,SAAS,CACtB,CAAC,CAAC,KAAK,OAAO,UAAU,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;CAErD,MAAM,QAAQ,OAAO,OAAO,oBAAoB,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAC/D,OAAO,eAAe,KAAK,WAAW,CAAC,CACzC;CAEA,IAAI,MAAM,OAAO,IAAI,aAAa,MAAM,cAAc,IAAI,WACxD,OAAO,OAAO,KAAK,WAAW;CAChC,IAAI,MAAM,WAAW,WAAW,OAAO,OAAO,KAAK,SAAS;CAE5D,MAAM,MAAM,OAAO,OAAO,aAAa,aAAa,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,KACtE,OAAO,eAAe,KAAK,YAAY,CAAC,CAC1C;CAEA,OAAO,SAAS,KAAK,GAAG;AAC1B,CAAC"}
@@ -1,29 +0,0 @@
1
- import { n as ContextReference } from "./References-DOH3Wu44.mjs";
2
- import { ContextError, SessionError } from "./Errors.mjs";
3
- import { t as BrowserbaseSessions } from "./Sessions-oJEUmZth.mjs";
4
- import { a as WriterLease, i as WriterAttemptFacts, n as ContextWriterPermit, o as WriterOptions, r as PersistenceEvidence, s as WriterSettlementFacts, t as ContextWriterBackend } from "./WriterFacts-BBJRDZYY.mjs";
5
- import { Effect, Scope } from "effect";
6
- //#region src/ContextCoordination.d.ts
7
- /**
8
- * Owns the backend lease, child browser scopes, and exact attempt evidence. The backend must
9
- * handle uncertain distributed lease acquisition itself. It must persist quarantine facts;
10
- * a local Scope closing is never permission to admit another remote writer. A writer that
11
- * settles as anything but a release leaves its Context refused in this process until
12
- * `reconcile` succeeds.
13
- */
14
- export declare const withWriter: <A, E, R, LeaseE, LeaseR, VerifyE = never, VerifyR = never>(backend: ContextWriterBackend<LeaseE, LeaseR>, reference: ContextReference, use: (permit: ContextWriterPermit) => Effect.Effect<A, E, R>, options?: WriterOptions<A, VerifyE, VerifyR>) => Effect.Effect<A, E | LeaseE | VerifyE | ContextError, Exclude<R | LeaseR | VerifyR, Scope.Scope>>;
15
- /**
16
- * Lifts this process's quarantine on a Context once no writer it admitted can still write:
17
- * the provider reports every session the quarantined writer recorded as terminal, and then
18
- * the consumer's readback of the Context passes. The Context stays held throughout, so no
19
- * writer is admitted against evidence still being gathered; a live writer is refused rather
20
- * than waited for. An allocation whose outcome stayed unknown names no session to check, so
21
- * its Context stays refused. Ending a session is the caller's explicit request; this only
22
- * reads status. With no quarantine held here, only the readback runs. The backend keeps its
23
- * own quarantine until the consumer reports this reconciliation to it.
24
- */
25
- export declare const reconcile: <E, R>(reference: ContextReference, readback: Effect.Effect<void, E, R>) => Effect.Effect<void, E | ContextError | SessionError, BrowserbaseSessions | Exclude<R, Scope.Scope>>;
26
- //#endregion
27
- export { type ContextWriterBackend, type ContextWriterPermit, PersistenceEvidence, WriterAttemptFacts, type WriterLease, type WriterOptions, WriterSettlementFacts };
28
- export {};
29
- //# sourceMappingURL=ContextCoordination.d.mts.map
@@ -1,94 +0,0 @@
1
- import { ContextReference } from "./References.mjs";
2
- import { ContextError } from "./Errors.mjs";
3
- import { r as span } from "./Client-BEC4Q8ZS.mjs";
4
- import { isTerminalSessionStatus } from "./SessionData.mjs";
5
- import { c as WriterSettlementFacts, i as makeContextWriterPermit, n as closeContextWriterPermit, o as PersistenceEvidence, r as isContextWriterBusy, s as WriterAttemptFacts, t as claimReconciliation } from "./ContextWriter-CiEma24z.mjs";
6
- import { t as BrowserbaseSessions } from "./Sessions-D2H5m6rF.mjs";
7
- import { Clock, Effect, Exit, Schema } from "effect";
8
- //#region src/ContextCoordination.ts
9
- const decodeReference = (reference, operation) => Schema.decodeEffect(ContextReference)(reference, { onExcessProperty: "error" }).pipe(Effect.mapError(() => ContextError.make({
10
- operation,
11
- reason: "configuration",
12
- outcome: "undispatched"
13
- })));
14
- /**
15
- * Owns the backend lease, child browser scopes, and exact attempt evidence. The backend must
16
- * handle uncertain distributed lease acquisition itself. It must persist quarantine facts;
17
- * a local Scope closing is never permission to admit another remote writer. A writer that
18
- * settles as anything but a release leaves its Context refused in this process until
19
- * `reconcile` succeeds.
20
- */
21
- const withWriter = (backend, reference, use, options = {}) => Effect.scoped(Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
22
- const ref = yield* decodeReference(reference, "writer");
23
- const timeout = options.settlementTimeoutMillis ?? 5e3;
24
- if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 6e4 || isContextWriterBusy(ref)) return yield* ContextError.make({
25
- operation: "writer",
26
- reason: isContextWriterBusy(ref) ? "active" : "configuration",
27
- outcome: "undispatched"
28
- });
29
- const permit = yield* makeContextWriterPermit(ref);
30
- const acquired = yield* restore(backend.acquire(ref)).pipe(span("BrowserbaseWriter.acquire"), Effect.exit);
31
- if (Exit.isFailure(acquired)) {
32
- closeContextWriterPermit(permit, true);
33
- return yield* Effect.failCause(acquired.cause);
34
- }
35
- const lease = acquired.value;
36
- const body = yield* restore(Effect.scoped(Effect.suspend(() => use(permit)))).pipe(span("BrowserbaseWriter.use"), Effect.exit);
37
- if (Exit.isFailure(body)) yield* permit.quarantine;
38
- let verification = Exit.void;
39
- if (Exit.isSuccess(body) && options.verify !== void 0) {
40
- verification = yield* restore(Effect.scoped(options.verify(body.value))).pipe(span("BrowserbaseWriter.readback"), Effect.exit);
41
- if (Exit.isSuccess(verification)) verification = yield* permit.confirmReadback(yield* Clock.currentTimeMillis).pipe(Effect.exit);
42
- else yield* permit.quarantine;
43
- }
44
- const facts = yield* permit.snapshot;
45
- const settlement = yield* restore(lease.settle(facts)).pipe(Effect.timeoutOrElse({
46
- duration: timeout,
47
- orElse: () => Effect.fail(ContextError.make({
48
- operation: "writer-settle",
49
- reason: "timeout",
50
- outcome: "unknown"
51
- }))
52
- }), span("BrowserbaseWriter.settle", { attributes: { "browser.writer.disposition": facts.disposition } }), Effect.exit);
53
- if (Exit.isFailure(settlement)) yield* permit.quarantine;
54
- closeContextWriterPermit(permit, Exit.isSuccess(settlement) && facts.disposition === "release");
55
- if (Exit.isFailure(body)) {
56
- if (Exit.isFailure(settlement)) yield* Effect.logError("Browserbase writer settlement remained unconfirmed");
57
- return yield* Effect.failCause(body.cause);
58
- }
59
- if (Exit.isFailure(verification)) return yield* Effect.failCause(verification.cause);
60
- if (Exit.isFailure(settlement)) return yield* Effect.failCause(settlement.cause);
61
- return body.value;
62
- }))).pipe(span("BrowserbaseWriter.withWriter"));
63
- /**
64
- * Lifts this process's quarantine on a Context once no writer it admitted can still write:
65
- * the provider reports every session the quarantined writer recorded as terminal, and then
66
- * the consumer's readback of the Context passes. The Context stays held throughout, so no
67
- * writer is admitted against evidence still being gathered; a live writer is refused rather
68
- * than waited for. An allocation whose outcome stayed unknown names no session to check, so
69
- * its Context stays refused. Ending a session is the caller's explicit request; this only
70
- * reads status. With no quarantine held here, only the readback runs. The backend keeps its
71
- * own quarantine until the consumer reports this reconciliation to it.
72
- */
73
- const reconcile = (reference, readback) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
74
- const ref = yield* decodeReference(reference, "writer-reconcile");
75
- const sessions = yield* BrowserbaseSessions;
76
- const claim = yield* claimReconciliation(ref);
77
- const checked = yield* restore(Effect.gen(function* () {
78
- for (const entry of yield* claim.attempts) {
79
- if (entry.state === "rejected") continue;
80
- if (!(entry.session !== void 0 && isTerminalSessionStatus((yield* sessions.retrieve(entry.session)).status))) return yield* ContextError.make({
81
- operation: "writer-reconcile",
82
- reason: "active",
83
- outcome: "undispatched"
84
- });
85
- }
86
- yield* Effect.scoped(readback).pipe(span("BrowserbaseWriter.readback"));
87
- })).pipe(Effect.exit);
88
- claim.finish(Exit.isSuccess(checked));
89
- return yield* checked;
90
- })).pipe(span("BrowserbaseWriter.reconcile"));
91
- //#endregion
92
- export { PersistenceEvidence, WriterAttemptFacts, WriterSettlementFacts, reconcile, withWriter };
93
-
94
- //# sourceMappingURL=ContextCoordination.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContextCoordination.mjs","names":["Trace.span"],"sources":["../src/ContextCoordination.ts"],"sourcesContent":["import { Clock, Effect, Exit, Schema, type Scope } from \"effect\";\n\nimport { ContextError, type SessionError } from \"./Errors.ts\";\nimport {\n claimReconciliation,\n makeContextWriterPermit,\n closeContextWriterPermit,\n isContextWriterBusy,\n} from \"./internal/session/ContextWriter.ts\";\nimport type {\n ContextWriterBackend,\n ContextWriterPermit,\n WriterOptions,\n} from \"./internal/session/WriterFacts.ts\";\nimport * as Trace from \"./internal/Trace.ts\";\nimport { ContextReference } from \"./References.ts\";\nimport { isTerminalSessionStatus } from \"./SessionData.ts\";\nimport { BrowserbaseSessions } from \"./Sessions.ts\";\n\nexport {\n PersistenceEvidence,\n WriterAttemptFacts,\n WriterSettlementFacts,\n type ContextWriterBackend,\n type ContextWriterPermit,\n type WriterLease,\n type WriterOptions,\n} from \"./internal/session/WriterFacts.ts\";\n\nconst decodeReference = (reference: ContextReference, operation: \"writer\" | \"writer-reconcile\") =>\n Schema.decodeEffect(ContextReference)(reference, { onExcessProperty: \"error\" }).pipe(\n Effect.mapError(() =>\n ContextError.make({ operation, reason: \"configuration\", outcome: \"undispatched\" }),\n ),\n );\n\n/**\n * Owns the backend lease, child browser scopes, and exact attempt evidence. The backend must\n * handle uncertain distributed lease acquisition itself. It must persist quarantine facts;\n * a local Scope closing is never permission to admit another remote writer. A writer that\n * settles as anything but a release leaves its Context refused in this process until\n * `reconcile` succeeds.\n */\nexport const withWriter = <A, E, R, LeaseE, LeaseR, VerifyE = never, VerifyR = never>(\n backend: ContextWriterBackend<LeaseE, LeaseR>,\n reference: ContextReference,\n use: (permit: ContextWriterPermit) => Effect.Effect<A, E, R>,\n options: WriterOptions<A, VerifyE, VerifyR> = {},\n): Effect.Effect<\n A,\n E | LeaseE | VerifyE | ContextError,\n Exclude<R | LeaseR | VerifyR, Scope.Scope>\n> =>\n Effect.scoped(\n Effect.uninterruptibleMask((restore) =>\n Effect.gen(function* () {\n const ref = yield* decodeReference(reference, \"writer\");\n\n const timeout = options.settlementTimeoutMillis ?? 5000;\n\n if (\n !Number.isSafeInteger(timeout) ||\n timeout < 1 ||\n timeout > 60000 ||\n isContextWriterBusy(ref)\n ) {\n return yield* ContextError.make({\n operation: \"writer\",\n reason: isContextWriterBusy(ref) ? \"active\" : \"configuration\",\n outcome: \"undispatched\",\n });\n }\n const permit = yield* makeContextWriterPermit(ref);\n\n const acquired = yield* restore(backend.acquire(ref)).pipe(\n Trace.span(\"BrowserbaseWriter.acquire\"),\n Effect.exit,\n );\n\n if (Exit.isFailure(acquired)) {\n // `use` never received the permit, so no allocation was attempted under it and this\n // process admitted no remote writer. What the failed acquisition left uncertain\n // remotely is the backend's to resolve.\n closeContextWriterPermit(permit, true);\n\n return yield* Effect.failCause(acquired.cause);\n }\n const lease = acquired.value;\n\n const body = yield* restore(Effect.scoped(Effect.suspend(() => use(permit)))).pipe(\n Trace.span(\"BrowserbaseWriter.use\"),\n Effect.exit,\n );\n\n // Every remote-resource finalizer in use() has run before any settlement/readback below.\n if (Exit.isFailure(body)) yield* permit.quarantine;\n let verification: Exit.Exit<void, VerifyE | ContextError> = Exit.void;\n\n if (Exit.isSuccess(body) && options.verify !== undefined) {\n verification = yield* restore(Effect.scoped(options.verify(body.value))).pipe(\n Trace.span(\"BrowserbaseWriter.readback\"),\n Effect.exit,\n );\n if (Exit.isSuccess(verification)) {\n verification = yield* permit\n .confirmReadback(yield* Clock.currentTimeMillis)\n .pipe(Effect.exit);\n } else yield* permit.quarantine;\n }\n const facts = yield* permit.snapshot;\n\n const settlement = yield* restore(lease.settle(facts)).pipe(\n Effect.timeoutOrElse({\n duration: timeout,\n orElse: () =>\n Effect.fail(\n ContextError.make({\n operation: \"writer-settle\",\n reason: \"timeout\",\n outcome: \"unknown\",\n }),\n ),\n }),\n Trace.span(\"BrowserbaseWriter.settle\", {\n attributes: { \"browser.writer.disposition\": facts.disposition },\n }),\n Effect.exit,\n );\n\n if (Exit.isFailure(settlement)) yield* permit.quarantine;\n closeContextWriterPermit(\n permit,\n Exit.isSuccess(settlement) && facts.disposition === \"release\",\n );\n // Preserve the primary cause; secondary failure is visible in the retained quarantine and\n // a content-free diagnostic. Never serialize arbitrary consumer/database error values.\n if (Exit.isFailure(body)) {\n if (Exit.isFailure(settlement))\n yield* Effect.logError(\"Browserbase writer settlement remained unconfirmed\");\n\n return yield* Effect.failCause(body.cause);\n }\n if (Exit.isFailure(verification)) return yield* Effect.failCause(verification.cause);\n if (Exit.isFailure(settlement)) return yield* Effect.failCause(settlement.cause);\n\n return body.value;\n }),\n ),\n ).pipe(Trace.span(\"BrowserbaseWriter.withWriter\"));\n\n/**\n * Lifts this process's quarantine on a Context once no writer it admitted can still write:\n * the provider reports every session the quarantined writer recorded as terminal, and then\n * the consumer's readback of the Context passes. The Context stays held throughout, so no\n * writer is admitted against evidence still being gathered; a live writer is refused rather\n * than waited for. An allocation whose outcome stayed unknown names no session to check, so\n * its Context stays refused. Ending a session is the caller's explicit request; this only\n * reads status. With no quarantine held here, only the readback runs. The backend keeps its\n * own quarantine until the consumer reports this reconciliation to it.\n */\nexport const reconcile = <E, R>(\n reference: ContextReference,\n readback: Effect.Effect<void, E, R>,\n): Effect.Effect<\n void,\n E | ContextError | SessionError,\n BrowserbaseSessions | Exclude<R, Scope.Scope>\n> =>\n Effect.uninterruptibleMask((restore) =>\n Effect.gen(function* () {\n const ref = yield* decodeReference(reference, \"writer-reconcile\");\n const sessions = yield* BrowserbaseSessions;\n const claim = yield* claimReconciliation(ref);\n\n const checked = yield* restore(\n Effect.gen(function* () {\n for (const entry of yield* claim.attempts) {\n // A rejected creation made no session. Any other attempt must name a session the\n // provider has ended, and the readback must come after every one of them.\n if (entry.state === \"rejected\") continue;\n\n const ended =\n entry.session !== undefined &&\n isTerminalSessionStatus((yield* sessions.retrieve(entry.session)).status);\n\n if (!ended) {\n return yield* ContextError.make({\n operation: \"writer-reconcile\",\n reason: \"active\",\n outcome: \"undispatched\",\n });\n }\n }\n yield* Effect.scoped(readback).pipe(Trace.span(\"BrowserbaseWriter.readback\"));\n }),\n ).pipe(Effect.exit);\n\n claim.finish(Exit.isSuccess(checked));\n\n return yield* checked;\n }),\n ).pipe(Trace.span(\"BrowserbaseWriter.reconcile\"));\n"],"mappings":"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"}
@@ -1,204 +0,0 @@
1
- import { AllocationAttempt, ContextReference, SessionReference } from "./References.mjs";
2
- import { ContextError } from "./Errors.mjs";
3
- import { CleanupResult } from "./Cleanup.mjs";
4
- import { Effect, Schema } from "effect";
5
- //#region src/internal/session/WriterFacts.ts
6
- /**
7
- * The writer vocabulary both the public coordination entry point and the permit
8
- * implementation need. Keeping it here leaves one direction of dependency:
9
- * `ContextCoordination` and `ContextWriter` both read this module, never each other.
10
- */
11
- const PersistenceEvidence = Schema.Union([
12
- Schema.TaggedStruct("NotRequested", {}),
13
- Schema.TaggedStruct("Unconfirmed", { reason: Schema.Literals([
14
- "writer-active",
15
- "writer-unknown",
16
- "flush-unacknowledged"
17
- ]) }),
18
- Schema.TaggedStruct("Observed", {
19
- method: Schema.Literal("consumer-readback"),
20
- observedAtMillis: Schema.Finite
21
- })
22
- ]);
23
- var WriterAttemptFacts = class extends Schema.Class("BrowserbaseWriterAttemptFacts")({
24
- attempt: AllocationAttempt,
25
- session: Schema.optionalKey(SessionReference),
26
- state: Schema.Literals([
27
- "admitted",
28
- "rejected",
29
- "unknown",
30
- "terminal"
31
- ]),
32
- cleanup: Schema.optionalKey(CleanupResult)
33
- }) {};
34
- var WriterSettlementFacts = class extends Schema.Class("BrowserbaseWriterSettlementFacts")({
35
- reference: ContextReference,
36
- attempts: Schema.Array(WriterAttemptFacts).check(Schema.isMaxLength(64)),
37
- persistence: PersistenceEvidence,
38
- disposition: Schema.Literals(["release", "quarantine"])
39
- }) {};
40
- //#endregion
41
- //#region src/internal/session/ContextWriter.ts
42
- const authentic = /* @__PURE__ */ new WeakMap();
43
- const active = /* @__PURE__ */ new Map();
44
- const key = (ref) => `${ref.projectId}/${ref.contextId}`;
45
- const isContextWriterBusy = (ref) => active.has(key(ref));
46
- const makeContextWriterPermit = (reference) => Effect.suspend(() => {
47
- if (active.has(key(reference)) || active.size >= 2048) return Effect.fail(ContextError.make({
48
- operation: "writer",
49
- reason: "active",
50
- outcome: "undispatched"
51
- }));
52
- const owned = Object.freeze(reference);
53
- const attempts = /* @__PURE__ */ new Map();
54
- let closed = false, quarantined = false;
55
- let persistence = { _tag: "NotRequested" };
56
- const unknown = () => {
57
- quarantined = true;
58
- persistence = {
59
- _tag: "Unconfirmed",
60
- reason: "writer-unknown"
61
- };
62
- };
63
- const noActive = () => [...attempts.values()].every((entry) => entry.state === "rejected" || entry.state === "terminal");
64
- const permit = {
65
- _tag: "ContextWriterPermit",
66
- reference: owned,
67
- recordAttempt: (attempt) => Effect.suspend(() => {
68
- if (closed || quarantined || !noActive() || attempt.projectId !== owned.projectId || attempts.size > 0 && persistence._tag === "Unconfirmed") return Effect.fail(ContextError.make({
69
- operation: "writer-admit",
70
- reason: "active",
71
- outcome: "undispatched"
72
- }));
73
- if (attempts.has(attempt.attemptId) || attempts.size >= 64) return Effect.fail(ContextError.make({
74
- operation: "writer-admit",
75
- reason: "limit",
76
- outcome: "undispatched"
77
- }));
78
- const copy = Object.freeze(attempt);
79
- attempts.set(copy.attemptId, {
80
- attempt: copy,
81
- state: "admitted"
82
- });
83
- persistence = {
84
- _tag: "Unconfirmed",
85
- reason: "writer-active"
86
- };
87
- return Effect.void;
88
- }),
89
- recordSession: (attempt, session) => {
90
- const record = attempts.get(attempt.attemptId);
91
- if (record === void 0 || record.attempt !== attempt || session.projectId !== owned.projectId || record.session !== void 0 && record.session.sessionId !== session.sessionId) {
92
- unknown();
93
- return;
94
- }
95
- record.session = Object.freeze(session);
96
- },
97
- rejected: (attempt) => {
98
- const record = attempts.get(attempt.attemptId);
99
- if (record === void 0 || record.attempt !== attempt || record.session !== void 0) {
100
- unknown();
101
- return;
102
- }
103
- record.state = "rejected";
104
- if ([...attempts.values()].every((item) => item.state === "rejected")) persistence = { _tag: "NotRequested" };
105
- },
106
- uncertain: (attempt) => {
107
- const record = attempts.get(attempt.attemptId);
108
- if (record !== void 0 && record.attempt === attempt) record.state = "unknown";
109
- unknown();
110
- },
111
- completed: (attempt, cleanup) => {
112
- const record = attempts.get(attempt.attemptId);
113
- if (record === void 0 || record.attempt !== attempt || cleanup.ownership !== "owned" || record.session === void 0 || record.session.sessionId !== cleanup.reference.sessionId || cleanup.reference.projectId !== owned.projectId) {
114
- unknown();
115
- return;
116
- }
117
- record.cleanup = cleanup;
118
- if (cleanup.remote !== "confirmed") {
119
- record.state = "unknown";
120
- unknown();
121
- return;
122
- }
123
- record.state = "terminal";
124
- if (cleanup.observedStatus !== "COMPLETED") {
125
- unknown();
126
- return;
127
- }
128
- if (!quarantined) persistence = {
129
- _tag: "Unconfirmed",
130
- reason: "flush-unacknowledged"
131
- };
132
- },
133
- confirmReadback: (atMillis) => Effect.suspend(() => {
134
- if (closed || quarantined || !noActive() || !Number.isFinite(atMillis) || attempts.size === 0 || [...attempts.values()].some((entry) => entry.state === "terminal" && entry.cleanup?.observedStatus !== "COMPLETED")) return Effect.fail(ContextError.make({
135
- operation: "writer-readback",
136
- reason: "active",
137
- outcome: "undispatched"
138
- }));
139
- persistence = {
140
- _tag: "Observed",
141
- method: "consumer-readback",
142
- observedAtMillis: atMillis
143
- };
144
- return Effect.void;
145
- }),
146
- quarantine: Effect.sync(unknown),
147
- snapshot: Effect.sync(() => WriterSettlementFacts.make({
148
- reference: owned,
149
- attempts: [...attempts.values()].map((entry) => WriterAttemptFacts.make({
150
- attempt: entry.attempt,
151
- state: entry.state,
152
- ...entry.session === void 0 ? {} : { session: entry.session },
153
- ...entry.cleanup === void 0 ? {} : { cleanup: entry.cleanup }
154
- })),
155
- persistence,
156
- disposition: quarantined || !noActive() || persistence._tag === "Unconfirmed" ? "quarantine" : "release"
157
- }))
158
- };
159
- Object.freeze(permit);
160
- authentic.set(permit, permit);
161
- active.set(key(owned), permit);
162
- retirement.set(permit, (released) => {
163
- closed = true;
164
- if (active.get(key(owned)) !== permit) return;
165
- if (released) active.delete(key(owned));
166
- else active.set(key(owned), {
167
- _tag: "Quarantined",
168
- permit
169
- });
170
- });
171
- return Effect.succeed(permit);
172
- });
173
- const retirement = /* @__PURE__ */ new WeakMap();
174
- const closeContextWriterPermit = (permit, released) => retirement.get(permit)?.(released);
175
- const claimReconciliation = (reference) => Effect.suspend(() => {
176
- const held = active.get(key(reference));
177
- if (held?._tag === "ContextWriterPermit" || held?._tag === "Reconciling" || held === void 0 && active.size >= 2048) return Effect.fail(ContextError.make({
178
- operation: "writer-reconcile",
179
- reason: "active",
180
- outcome: "undispatched"
181
- }));
182
- const claim = { _tag: "Reconciling" };
183
- active.set(key(reference), claim);
184
- return Effect.succeed({
185
- attempts: held === void 0 ? Effect.succeed([]) : held.permit.snapshot.pipe(Effect.map((facts) => facts.attempts)),
186
- finish: (reconciled) => {
187
- if (active.get(key(reference)) !== claim) return;
188
- if (reconciled || held === void 0) active.delete(key(reference));
189
- else active.set(key(reference), held);
190
- }
191
- });
192
- });
193
- const requireContextWriterPermit = (permit, reference) => Effect.suspend(() => {
194
- const actual = authentic.get(permit);
195
- return actual !== void 0 && active.get(key(reference)) === actual && actual.reference.contextId === reference.contextId && actual.reference.projectId === reference.projectId ? Effect.succeed(actual) : Effect.fail(ContextError.make({
196
- operation: "writer-authority",
197
- reason: "authorization",
198
- outcome: "undispatched"
199
- }));
200
- });
201
- //#endregion
202
- export { requireContextWriterPermit as a, WriterSettlementFacts as c, makeContextWriterPermit as i, closeContextWriterPermit as n, PersistenceEvidence as o, isContextWriterBusy as r, WriterAttemptFacts as s, claimReconciliation as t };
203
-
204
- //# sourceMappingURL=ContextWriter-CiEma24z.mjs.map