effect-browserbase 0.2.0-beta.0 → 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 (91) hide show
  1. package/README.md +47 -4
  2. package/dist/Account.d.mts +15 -15
  3. package/dist/Account.mjs +3 -3
  4. package/dist/{Acquisition-D8o4jtCg.mjs → Acquisition-CAsTTXp4.mjs} +9 -8
  5. package/dist/Acquisition-CAsTTXp4.mjs.map +1 -0
  6. package/dist/Agents-5HpTp9YE.d.mts +155 -0
  7. package/dist/Agents.d.mts +3 -154
  8. package/dist/Agents.mjs +3 -3
  9. package/dist/Allocation.d.mts +4 -4
  10. package/dist/Allocation.mjs +1 -1
  11. package/dist/Browser-DpSajNai.mjs +270 -0
  12. package/dist/Browser-DpSajNai.mjs.map +1 -0
  13. package/dist/Browser.d.mts +6 -5
  14. package/dist/Browser.mjs +2 -266
  15. package/dist/BrowserBinding.mjs +3 -3
  16. package/dist/BrowserBinding.mjs.map +1 -1
  17. package/dist/Certificates-D4NQmyeA.d.mts +34 -0
  18. package/dist/Certificates.d.mts +3 -33
  19. package/dist/Certificates.mjs +1 -1
  20. package/dist/{Client-BQteUePT.mjs → Client-4RMKIpL2.mjs} +11 -9
  21. package/dist/Client-4RMKIpL2.mjs.map +1 -0
  22. package/dist/Client-B_f6bBLT.d.mts +52 -0
  23. package/dist/Client.d.mts +3 -51
  24. package/dist/Client.mjs +1 -1
  25. package/dist/{Connection-DcvJZEdc.mjs → Connection-sxyxtwlk.mjs} +2 -11
  26. package/dist/Connection-sxyxtwlk.mjs.map +1 -0
  27. package/dist/ContextCoordination.d.mts +1 -1
  28. package/dist/ContextCoordination.mjs +1 -1
  29. package/dist/ContextCoordination.mjs.map +1 -1
  30. package/dist/{ContextWriter-BrQmoXRg.mjs → ContextWriter-oKWFLHuP.mjs} +8 -12
  31. package/dist/ContextWriter-oKWFLHuP.mjs.map +1 -0
  32. package/dist/Contexts-DqdL7cyX.d.mts +31 -0
  33. package/dist/Contexts.d.mts +3 -30
  34. package/dist/Contexts.mjs +2 -2
  35. package/dist/Contexts.mjs.map +1 -1
  36. package/dist/Downloads-CdhiCO5X.d.mts +43 -0
  37. package/dist/Downloads.d.mts +3 -42
  38. package/dist/Downloads.mjs +2 -2
  39. package/dist/Downloads.mjs.map +1 -1
  40. package/dist/Extensions-DBXuVM1f.d.mts +43 -0
  41. package/dist/{Extensions-nMNMPGCc.mjs → Extensions-Dg3jHOf0.mjs} +2 -2
  42. package/dist/Extensions-Dg3jHOf0.mjs.map +1 -0
  43. package/dist/Extensions.d.mts +3 -42
  44. package/dist/Extensions.mjs +1 -1
  45. package/dist/Functions-CsKMMUuZ.d.mts +226 -0
  46. package/dist/Functions.d.mts +3 -225
  47. package/dist/Functions.mjs +3 -3
  48. package/dist/{Launch-m0fxzJ49.mjs → Launch-cAdE2rrZ.mjs} +12 -8
  49. package/dist/Launch-cAdE2rrZ.mjs.map +1 -0
  50. package/dist/Launch.d.mts +1 -4
  51. package/dist/Launch.mjs +1 -2
  52. package/dist/Launch.mjs.map +1 -1
  53. package/dist/PageFetch-CAMqb5m8.d.mts +39 -0
  54. package/dist/PageFetch.d.mts +3 -38
  55. package/dist/PageFetch.mjs +1 -1
  56. package/dist/Projects-tm5bTDH0.d.mts +38 -0
  57. package/dist/Projects.d.mts +3 -37
  58. package/dist/Projects.mjs +1 -1
  59. package/dist/Recordings-bVI33sTq.d.mts +27 -0
  60. package/dist/Recordings.d.mts +3 -26
  61. package/dist/Recordings.mjs +2 -2
  62. package/dist/Replays-Bo-9xeLz.d.mts +27 -0
  63. package/dist/Replays.d.mts +3 -26
  64. package/dist/Replays.mjs +2 -2
  65. package/dist/Search-1g6TUem7.d.mts +37 -0
  66. package/dist/Search.d.mts +3 -36
  67. package/dist/Search.mjs +1 -1
  68. package/dist/{Sessions-tFJYaXFq.d.mts → Sessions-BpZgjteE.d.mts} +2 -2
  69. package/dist/{Sessions-DoQGg9nB.mjs → Sessions-suOLSym9.mjs} +2 -2
  70. package/dist/Sessions-suOLSym9.mjs.map +1 -0
  71. package/dist/Sessions.d.mts +1 -1
  72. package/dist/Sessions.mjs +1 -1
  73. package/dist/Testing.d.mts +119 -0
  74. package/dist/Testing.mjs +206 -0
  75. package/dist/Testing.mjs.map +1 -0
  76. package/dist/Uploads-C2neBEpj.d.mts +28 -0
  77. package/dist/Uploads.d.mts +3 -27
  78. package/dist/Uploads.mjs +2 -2
  79. package/dist/Webhooks-BoeRAxzG.d.mts +59 -0
  80. package/dist/Webhooks.d.mts +3 -58
  81. package/dist/Webhooks.mjs +1 -1
  82. package/dist/{WriterFacts-5CPBGG1P.d.mts → WriterFacts-BBJRDZYY.d.mts} +5 -13
  83. package/package.json +6 -2
  84. package/dist/Acquisition-D8o4jtCg.mjs.map +0 -1
  85. package/dist/Browser.mjs.map +0 -1
  86. package/dist/Client-BQteUePT.mjs.map +0 -1
  87. package/dist/Connection-DcvJZEdc.mjs.map +0 -1
  88. package/dist/ContextWriter-BrQmoXRg.mjs.map +0 -1
  89. package/dist/Extensions-nMNMPGCc.mjs.map +0 -1
  90. package/dist/Launch-m0fxzJ49.mjs.map +0 -1
  91. package/dist/Sessions-DoQGg9nB.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { n as validateConnection } from "./Connection-DcvJZEdc.mjs";
2
- import { Context, Effect, Layer, Redacted } from "effect";
1
+ import { n as validateConnection } from "./Connection-sxyxtwlk.mjs";
2
+ import { Context, Effect, Layer, Redacted, Schema } from "effect";
3
3
  import { BrowserError, Reasons } from "effect-browser/errors";
4
4
  import * as BrowserRuntime from "effect-browser/browser-runtime";
5
5
  //#region src/BrowserBinding.ts
@@ -10,7 +10,7 @@ const playwright = (options = {}) => {
10
10
  resolveEndpoint: ({ url }) => Effect.gen(function* () {
11
11
  const validated = yield* Effect.try({
12
12
  try: () => validateConnection(Redacted.value(url)),
13
- catch: (error) => error instanceof BrowserError ? error : BrowserError.make({
13
+ catch: (error) => Schema.is(BrowserError)(error) ? error : BrowserError.make({
14
14
  operation: "connect",
15
15
  reason: Reasons.Malformed.make({}),
16
16
  outcome: "undispatched"
@@ -1 +1 @@
1
- {"version":3,"file":"BrowserBinding.mjs","names":[],"sources":["../src/BrowserBinding.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted } from \"effect\";\nimport * as BrowserRuntime from \"effect-browser/browser-runtime\";\nimport { BrowserError, Reasons } from \"effect-browser/errors\";\n\nimport { validateConnection } from \"./internal/provider/Connection.ts\";\n\nexport type BrowserBinding = BrowserRuntime.BrowserBinding;\nexport type PlaywrightOptions = BrowserRuntime.PlaywrightOptions;\n\n/** Validate provider authority before invoking any trusted host routing. */\nexport const playwright = (options: PlaywrightOptions = {}): BrowserBinding => {\n const { resolveEndpoint, onConnected } = options;\n\n return BrowserRuntime.playwright({\n resolveEndpoint: ({ url }) =>\n Effect.gen(function* () {\n const validated = yield* Effect.try({\n try: () => validateConnection(Redacted.value(url)),\n catch: (error) =>\n error instanceof BrowserError\n ? error\n : BrowserError.make({\n operation: \"connect\",\n reason: Reasons.Malformed.make({}),\n outcome: \"undispatched\",\n }),\n });\n\n return yield* resolveEndpoint === undefined\n ? Effect.succeed(validated)\n : resolveEndpoint({ url: Redacted.make(validated) });\n }),\n ...(onConnected === undefined ? {} : { onConnected }),\n });\n};\n\nconst defaultBinding = playwright();\n\nexport const BrowserbaseBrowserBinding = Context.Reference<BrowserBinding>(\n \"effect-browserbase/BrowserBinding\",\n { defaultValue: () => defaultBinding },\n);\n\nexport const layer = (binding: BrowserBinding): Layer.Layer<never> =>\n Layer.succeed(BrowserbaseBrowserBinding, binding);\n\nexport const layerPlaywright: Layer.Layer<never> = layer(defaultBinding);\n"],"mappings":";;;;;;AAUA,MAAa,cAAc,UAA6B,CAAC,MAAsB;CAC7E,MAAM,EAAE,iBAAiB,gBAAgB;CAEzC,OAAO,eAAe,WAAW;EAC/B,kBAAkB,EAAE,UAClB,OAAO,IAAI,aAAa;GACtB,MAAM,YAAY,OAAO,OAAO,IAAI;IAClC,WAAW,mBAAmB,SAAS,MAAM,GAAG,CAAC;IACjD,QAAQ,UACN,iBAAiB,eACb,QACA,aAAa,KAAK;KAChB,WAAW;KACX,QAAQ,QAAQ,UAAU,KAAK,CAAC,CAAC;KACjC,SAAS;IACX,CAAC;GACT,CAAC;GAED,OAAO,OAAO,oBAAoB,KAAA,IAC9B,OAAO,QAAQ,SAAS,IACxB,gBAAgB,EAAE,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC;EACvD,CAAC;EACH,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;CACrD,CAAC;AACH;AAEA,MAAM,iBAAiB,WAAW;AAElC,MAAa,4BAA4B,QAAQ,UAC/C,qCACA,EAAE,oBAAoB,eAAe,CACvC;AAEA,MAAa,SAAS,YACpB,MAAM,QAAQ,2BAA2B,OAAO;AAElD,MAAa,kBAAsC,MAAM,cAAc"}
1
+ {"version":3,"file":"BrowserBinding.mjs","names":[],"sources":["../src/BrowserBinding.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted, Schema } from \"effect\";\nimport * as BrowserRuntime from \"effect-browser/browser-runtime\";\nimport { BrowserError, Reasons } from \"effect-browser/errors\";\n\nimport { validateConnection } from \"./internal/provider/Connection.ts\";\n\nexport type BrowserBinding = BrowserRuntime.BrowserBinding;\nexport type PlaywrightOptions = BrowserRuntime.PlaywrightOptions;\n\n/** Validate provider authority before invoking any trusted host routing. */\nexport const playwright = (options: PlaywrightOptions = {}): BrowserBinding => {\n const { resolveEndpoint, onConnected } = options;\n\n return BrowserRuntime.playwright({\n resolveEndpoint: ({ url }) =>\n Effect.gen(function* () {\n const validated = yield* Effect.try({\n try: () => validateConnection(Redacted.value(url)),\n catch: (error) =>\n Schema.is(BrowserError)(error)\n ? error\n : BrowserError.make({\n operation: \"connect\",\n reason: Reasons.Malformed.make({}),\n outcome: \"undispatched\",\n }),\n });\n\n return yield* resolveEndpoint === undefined\n ? Effect.succeed(validated)\n : resolveEndpoint({ url: Redacted.make(validated) });\n }),\n ...(onConnected === undefined ? {} : { onConnected }),\n });\n};\n\nconst defaultBinding = playwright();\n\nexport const BrowserbaseBrowserBinding = Context.Reference<BrowserBinding>(\n \"effect-browserbase/BrowserBinding\",\n { defaultValue: () => defaultBinding },\n);\n\nexport const layer = (binding: BrowserBinding): Layer.Layer<never> =>\n Layer.succeed(BrowserbaseBrowserBinding, binding);\n\nexport const layerPlaywright: Layer.Layer<never> = layer(defaultBinding);\n"],"mappings":";;;;;;AAUA,MAAa,cAAc,UAA6B,CAAC,MAAsB;CAC7E,MAAM,EAAE,iBAAiB,gBAAgB;CAEzC,OAAO,eAAe,WAAW;EAC/B,kBAAkB,EAAE,UAClB,OAAO,IAAI,aAAa;GACtB,MAAM,YAAY,OAAO,OAAO,IAAI;IAClC,WAAW,mBAAmB,SAAS,MAAM,GAAG,CAAC;IACjD,QAAQ,UACN,OAAO,GAAG,YAAY,CAAC,CAAC,KAAK,IACzB,QACA,aAAa,KAAK;KAChB,WAAW;KACX,QAAQ,QAAQ,UAAU,KAAK,CAAC,CAAC;KACjC,SAAS;IACX,CAAC;GACT,CAAC;GAED,OAAO,OAAO,oBAAoB,KAAA,IAC9B,OAAO,QAAQ,SAAS,IACxB,gBAAgB,EAAE,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC;EACvD,CAAC;EACH,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;CACrD,CAAC;AACH;AAEA,MAAM,iBAAiB,WAAW;AAElC,MAAa,4BAA4B,QAAQ,UAC/C,qCACA,EAAE,oBAAoB,eAAe,CACvC;AAEA,MAAa,SAAS,YACpB,MAAM,QAAQ,2BAA2B,OAAO;AAElD,MAAa,kBAAsC,MAAM,cAAc"}
@@ -0,0 +1,34 @@
1
+ import { CertificateError } from "./Errors.mjs";
2
+ import { t as BrowserbaseClient } from "./Client-B_f6bBLT.mjs";
3
+ import { Context, Effect, Layer, Schema } from "effect";
4
+ //#region src/Certificates.d.ts
5
+ declare const CertificateMetadata_base: Schema.Class<CertificateMetadata, Schema.Struct<{
6
+ readonly certificateId: Schema.NonEmptyString;
7
+ readonly projectId: Schema.NonEmptyString;
8
+ readonly createdAt: Schema.String;
9
+ readonly updatedAt: Schema.String;
10
+ }>, {}>;
11
+ /** Select a certificate at launch with `provider.proxySettings.caCertificates: [certificateId]`. */
12
+ declare class CertificateMetadata extends CertificateMetadata_base {}
13
+ interface CertificateUpload {
14
+ /** PEM or DER bytes of one CA certificate. */
15
+ readonly bytes: Uint8Array;
16
+ /** Portable basename sent with the part; defaults to `certificate.pem`. */
17
+ readonly filename?: string;
18
+ readonly maxBytes?: number;
19
+ readonly timeoutMillis?: number;
20
+ }
21
+ declare const BrowserbaseCertificates_base: Context.ServiceClass<BrowserbaseCertificates, "effect-browserbase/Certificates", {
22
+ readonly create: (upload: CertificateUpload) => Effect.Effect<CertificateMetadata, CertificateError>;
23
+ readonly list: Effect.Effect<ReadonlyArray<CertificateMetadata>, CertificateError>;
24
+ readonly retrieve: (certificateId: string) => Effect.Effect<CertificateMetadata, CertificateError>;
25
+ readonly delete: (certificateId: string) => Effect.Effect<void, CertificateError>;
26
+ }>;
27
+ /** Proxy CA certificates. Registration is one bounded multipart mutation, never retried. */
28
+ declare class BrowserbaseCertificates extends BrowserbaseCertificates_base {
29
+ static readonly layer: Layer.Layer<BrowserbaseCertificates, never, BrowserbaseClient>;
30
+ }
31
+ //#endregion
32
+ export { CertificateMetadata as n, CertificateUpload as r, BrowserbaseCertificates as t };
33
+ export {};
34
+ //# sourceMappingURL=Certificates-D4NQmyeA.d.mts.map
@@ -1,33 +1,3 @@
1
- import { CertificateError } from "./Errors.mjs";
2
- import { BrowserbaseClient } from "./Client.mjs";
3
- import { Context, Effect, Layer, Schema } from "effect";
4
- //#region src/Certificates.d.ts
5
- declare const CertificateMetadata_base: Schema.Class<CertificateMetadata, Schema.Struct<{
6
- readonly certificateId: Schema.NonEmptyString;
7
- readonly projectId: Schema.NonEmptyString;
8
- readonly createdAt: Schema.String;
9
- readonly updatedAt: Schema.String;
10
- }>, {}>;
11
- /** Select a certificate at launch with `provider.proxySettings.caCertificates: [certificateId]`. */
12
- export declare class CertificateMetadata extends CertificateMetadata_base {}
13
- export interface CertificateUpload {
14
- /** PEM or DER bytes of one CA certificate. */
15
- readonly bytes: Uint8Array;
16
- /** Portable basename sent with the part; defaults to `certificate.pem`. */
17
- readonly filename?: string;
18
- readonly maxBytes?: number;
19
- readonly timeoutMillis?: number;
20
- }
21
- declare const BrowserbaseCertificates_base: Context.ServiceClass<BrowserbaseCertificates, "effect-browserbase/Certificates", {
22
- readonly create: (upload: CertificateUpload) => Effect.Effect<CertificateMetadata, CertificateError>;
23
- readonly list: Effect.Effect<ReadonlyArray<CertificateMetadata>, CertificateError>;
24
- readonly retrieve: (certificateId: string) => Effect.Effect<CertificateMetadata, CertificateError>;
25
- readonly delete: (certificateId: string) => Effect.Effect<void, CertificateError>;
26
- }>;
27
- /** Proxy CA certificates. Registration is one bounded multipart mutation, never retried. */
28
- export declare class BrowserbaseCertificates extends BrowserbaseCertificates_base {
29
- static readonly layer: Layer.Layer<BrowserbaseCertificates, never, BrowserbaseClient>;
30
- }
31
- //#endregion
32
- export {};
33
- //# sourceMappingURL=Certificates.d.mts.map
1
+ import { n as CertificateMetadata, r as CertificateUpload, t as BrowserbaseCertificates } from "./Certificates-D4NQmyeA.mjs";
2
+ export { BrowserbaseCertificates, CertificateMetadata, CertificateUpload };
3
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { Identifier } from "./References.mjs";
2
2
  import { CertificateError } from "./Errors.mjs";
3
3
  import { SafeFilename } from "./Transfers.mjs";
4
- import { t as BrowserbaseClient } from "./Client-BQteUePT.mjs";
4
+ import { t as BrowserbaseClient } from "./Client-4RMKIpL2.mjs";
5
5
  import { t as resource } from "./Resource-DBksC4zB.mjs";
6
6
  import { Context, Effect, Layer, Schema } from "effect";
7
7
  //#region src/Certificates.ts
@@ -1,7 +1,7 @@
1
1
  import { Identifier } from "./References.mjs";
2
2
  import { ClientError } from "./Errors.mjs";
3
3
  import { SafeFilename } from "./Transfers.mjs";
4
- import { Clock, Config, Context, Duration, Effect, Layer, Redacted, Schema, Stream } from "effect";
4
+ import { Clock, Config, Context, Duration, Effect, Layer, Random, Redacted, Schema, Stream } from "effect";
5
5
  import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
6
6
  //#region src/internal/http/Multipart.ts
7
7
  const FIELD = /^[a-z][a-z0-9_]{0,31}$/;
@@ -10,9 +10,11 @@ const PRINTABLE_ASCII = /^[\x20-\x7e]+$/;
10
10
  const isSafeFilename = Schema.is(SafeFilename);
11
11
  /** Quoting is only safe for a portable, printable, quote-free basename. */
12
12
  const quotable = (value) => isSafeFilename(value) && PRINTABLE_ASCII.test(value) && !value.includes("\"");
13
- const randomBoundary = () => {
14
- return `effect-agent-browserbase-${[...globalThis.crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16))].map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
15
- };
13
+ /**
14
+ * Sixteen bytes from the fiber's `Random`. A boundary needs no secrecy: the encoder checks that
15
+ * the content does not contain it, and draws another if it does.
16
+ */
17
+ const randomBoundary = Effect.map(Effect.all(Array.from({ length: 16 }, () => Random.nextIntBetween(0, 255))), (bytes) => `effect-agent-browserbase-${bytes.map((byte) => byte.toString(16).padStart(2, "0")).join("")}`);
16
18
  const contains = (haystack, needle) => {
17
19
  const first = needle[0];
18
20
  if (first === void 0 || needle.length > haystack.length) return false;
@@ -30,7 +32,7 @@ const contains = (haystack, needle) => {
30
32
  * A deliberately small RFC 7578 encoder: one file part, an ASCII-quotable name and a
31
33
  * delimiter proven absent from the content. It performs no filesystem or stream work.
32
34
  */
33
- const encodeFilePart = (part, maxBytes, boundaries = randomBoundary) => {
35
+ const encodeFilePart = Effect.fnUntraced(function* (part, maxBytes, boundaries = randomBoundary) {
34
36
  if (!FIELD.test(part.field) || !quotable(part.filename) || !MEDIA_TYPE.test(part.mediaType) || !Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > 2 ** 31 - 1) return {
35
37
  _tag: "Rejected",
36
38
  reason: "configuration"
@@ -41,7 +43,7 @@ const encodeFilePart = (part, maxBytes, boundaries = randomBoundary) => {
41
43
  };
42
44
  const encoder = new TextEncoder();
43
45
  for (let attempt = 0; attempt < 4; attempt++) {
44
- const boundary = boundaries();
46
+ const boundary = yield* boundaries;
45
47
  if (!/^[A-Za-z0-9-]{1,70}$/.test(boundary)) continue;
46
48
  const delimiter = encoder.encode(boundary);
47
49
  if (contains(part.bytes, delimiter)) continue;
@@ -61,7 +63,7 @@ const encodeFilePart = (part, maxBytes, boundaries = randomBoundary) => {
61
63
  _tag: "Rejected",
62
64
  reason: "configuration"
63
65
  };
64
- };
66
+ });
65
67
  //#endregion
66
68
  //#region src/internal/http/Transport.ts
67
69
  const API_ORIGIN = "https://api.browserbase.com";
@@ -271,7 +273,7 @@ const makeTransport = Effect.fnUntraced(function* (options) {
271
273
  reason: "configuration",
272
274
  outcome: "undispatched"
273
275
  });
274
- const encoded = encodeFilePart(part, limits.maxBytes);
276
+ const encoded = yield* encodeFilePart(part, limits.maxBytes);
275
277
  if (encoded._tag === "Rejected") return yield* ClientError.make({
276
278
  operation,
277
279
  reason: encoded.reason,
@@ -419,4 +421,4 @@ var BrowserbaseClient = class BrowserbaseClient extends Context.Service()("effec
419
421
  //#endregion
420
422
  export { BrowserbaseClient as t };
421
423
 
422
- //# sourceMappingURL=Client-BQteUePT.mjs.map
424
+ //# sourceMappingURL=Client-4RMKIpL2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Client-4RMKIpL2.mjs","names":[],"sources":["../src/internal/http/Multipart.ts","../src/internal/http/Transport.ts","../src/Client.ts"],"sourcesContent":["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 { 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 = 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\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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"}
@@ -0,0 +1,52 @@
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 CHANGED
@@ -1,51 +1,3 @@
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
- export 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
- export type ClientMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
13
- /** One bounded in-memory file part. A filesystem path is never a transport input. */
14
- export 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
- export 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
- export 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 {};
51
- //# sourceMappingURL=Client.d.mts.map
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 CHANGED
@@ -1,2 +1,2 @@
1
- import { t as BrowserbaseClient } from "./Client-BQteUePT.mjs";
1
+ import { t as BrowserbaseClient } from "./Client-4RMKIpL2.mjs";
2
2
  export { BrowserbaseClient };
@@ -20,20 +20,11 @@ const connectionUrl = Schema.String.check(Schema.isMaxLength(16384), Schema.make
20
20
  }));
21
21
  /** The provider endpoint is validated before any custom routing gets to observe it. */
22
22
  const validateConnection = (connection) => {
23
- if (typeof connection !== "string" || connection.length > 16384) throw BrowserError.make({
23
+ if (typeof connection !== "string" || connection.length > 16384 || !URL.canParse(connection)) throw BrowserError.make({
24
24
  operation: "connect",
25
25
  reason: Reasons.Malformed.make({}),
26
26
  outcome: "undispatched"
27
27
  });
28
- try {
29
- new URL(connection);
30
- } catch {
31
- throw BrowserError.make({
32
- operation: "connect",
33
- reason: Reasons.Malformed.make({}),
34
- outcome: "undispatched"
35
- });
36
- }
37
28
  if (!Schema.is(connectionUrl)(connection)) throw BrowserError.make({
38
29
  operation: "connect",
39
30
  reason: Reasons.UnsafeUrl.make({}),
@@ -62,4 +53,4 @@ const connectionAddress = Effect.fnUntraced(function* (client, sessions, referen
62
53
  //#endregion
63
54
  export { validateConnection as n, connectionAddress as t };
64
55
 
65
- //# sourceMappingURL=Connection-DcvJZEdc.mjs.map
56
+ //# sourceMappingURL=Connection-sxyxtwlk.mjs.map
@@ -0,0 +1 @@
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,6 +1,6 @@
1
1
  import { n as ContextReference } from "./References-DOH3Wu44.mjs";
2
2
  import { ContextError } from "./Errors.mjs";
3
- import { a as WriterLease, i as WriterAttemptFacts, n as ContextWriterPermit, o as WriterOptions, r as PersistenceEvidence, s as WriterSettlementFacts, t as ContextWriterBackend } from "./WriterFacts-5CPBGG1P.mjs";
3
+ 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";
4
4
  import { Effect, Scope } from "effect";
5
5
  //#region src/ContextCoordination.d.ts
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { ContextReference } from "./References.mjs";
2
2
  import { ContextError } from "./Errors.mjs";
3
- import { a as PersistenceEvidence, n as isContextWriterBusy, o as WriterAttemptFacts, r as makeContextWriterPermit, s as WriterSettlementFacts, t as closeContextWriterPermit } from "./ContextWriter-BrQmoXRg.mjs";
3
+ import { a as PersistenceEvidence, n as isContextWriterBusy, o as WriterAttemptFacts, r as makeContextWriterPermit, s as WriterSettlementFacts, t as closeContextWriterPermit } from "./ContextWriter-oKWFLHuP.mjs";
4
4
  import { Clock, Effect, Exit, Schema } from "effect";
5
5
  //#region src/ContextCoordination.ts
6
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ContextCoordination.mjs","names":[],"sources":["../src/ContextCoordination.ts"],"sourcesContent":["import type { Scope } from \"effect\";\nimport { Clock, Effect, Exit, Schema } from \"effect\";\n\nimport { ContextError } from \"./Errors.ts\";\nimport {\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 { ContextReference } from \"./References.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\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.\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* Schema.decodeEffect(ContextReference)(reference, {\n onExcessProperty: \"error\",\n }).pipe(\n Effect.mapError(() =>\n ContextError.make({\n operation: \"writer\",\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n ),\n );\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 const acquired = yield* restore(backend.acquire(ref)).pipe(Effect.exit);\n\n if (Exit.isFailure(acquired)) {\n closeContextWriterPermit(permit, false);\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 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 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 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 );\n"],"mappings":";;;;;;;;;;AA+BA,MAAa,cACX,SACA,WACA,KACA,UAA8C,CAAC,MAM/C,OAAO,OACL,OAAO,qBAAqB,YAC1B,OAAO,IAAI,aAAa;CACtB,MAAM,MAAM,OAAO,OAAO,aAAa,gBAAgB,CAAC,CAAC,WAAW,EAClE,kBAAkB,QACpB,CAAC,CAAC,CAAC,KACD,OAAO,eACL,aAAa,KAAK;EAChB,WAAW;EACX,QAAQ;EACR,SAAS;CACX,CAAC,CACH,CACF;CAEA,MAAM,UAAU,QAAQ,2BAA2B;CAEnD,IACE,CAAC,OAAO,cAAc,OAAO,KAC7B,UAAU,KACV,UAAU,OACV,oBAAoB,GAAG,GAEvB,OAAO,OAAO,aAAa,KAAK;EAC9B,WAAW;EACX,QAAQ,oBAAoB,GAAG,IAAI,WAAW;EAC9C,SAAS;CACX,CAAC;CAEH,MAAM,SAAS,OAAO,wBAAwB,GAAG;CACjD,MAAM,WAAW,OAAO,QAAQ,QAAQ,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI;CAEtE,IAAI,KAAK,UAAU,QAAQ,GAAG;EAC5B,yBAAyB,QAAQ,KAAK;EAEtC,OAAO,OAAO,OAAO,UAAU,SAAS,KAAK;CAC/C;CACA,MAAM,QAAQ,SAAS;CAEvB,MAAM,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAC5E,OAAO,IACT;CAGA,IAAI,KAAK,UAAU,IAAI,GAAG,OAAO,OAAO;CACxC,IAAI,eAAwD,KAAK;CAEjE,IAAI,KAAK,UAAU,IAAI,KAAK,QAAQ,WAAW,KAAA,GAAW;EACxD,eAAe,OAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KACvE,OAAO,IACT;EACA,IAAI,KAAK,UAAU,YAAY,GAC7B,eAAe,OAAO,OACnB,gBAAgB,OAAO,MAAM,iBAAiB,CAAC,CAC/C,KAAK,OAAO,IAAI;OACd,OAAO,OAAO;CACvB;CACA,MAAM,QAAQ,OAAO,OAAO;CAE5B,MAAM,aAAa,OAAO,QAAQ,MAAM,OAAO,KAAK,CAAC,CAAC,CAAC,KACrD,OAAO,cAAc;EACnB,UAAU;EACV,cACE,OAAO,KACL,aAAa,KAAK;GAChB,WAAW;GACX,QAAQ;GACR,SAAS;EACX,CAAC,CACH;CACJ,CAAC,GACD,OAAO,IACT;CAEA,IAAI,KAAK,UAAU,UAAU,GAAG,OAAO,OAAO;CAC9C,yBACE,QACA,KAAK,UAAU,UAAU,KAAK,MAAM,gBAAgB,SACtD;CAGA,IAAI,KAAK,UAAU,IAAI,GAAG;EACxB,IAAI,KAAK,UAAU,UAAU,GAC3B,OAAO,OAAO,SAAS,oDAAoD;EAE7E,OAAO,OAAO,OAAO,UAAU,KAAK,KAAK;CAC3C;CACA,IAAI,KAAK,UAAU,YAAY,GAAG,OAAO,OAAO,OAAO,UAAU,aAAa,KAAK;CACnF,IAAI,KAAK,UAAU,UAAU,GAAG,OAAO,OAAO,OAAO,UAAU,WAAW,KAAK;CAE/E,OAAO,KAAK;AACd,CAAC,CACH,CACF"}
1
+ {"version":3,"file":"ContextCoordination.mjs","names":[],"sources":["../src/ContextCoordination.ts"],"sourcesContent":["import { Clock, Effect, Exit, Schema, type Scope } from \"effect\";\n\nimport { ContextError } from \"./Errors.ts\";\nimport {\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 { ContextReference } from \"./References.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\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.\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* Schema.decodeEffect(ContextReference)(reference, {\n onExcessProperty: \"error\",\n }).pipe(\n Effect.mapError(() =>\n ContextError.make({\n operation: \"writer\",\n reason: \"configuration\",\n outcome: \"undispatched\",\n }),\n ),\n );\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 const acquired = yield* restore(backend.acquire(ref)).pipe(Effect.exit);\n\n if (Exit.isFailure(acquired)) {\n closeContextWriterPermit(permit, false);\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 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 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 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 );\n"],"mappings":";;;;;;;;;;AA8BA,MAAa,cACX,SACA,WACA,KACA,UAA8C,CAAC,MAM/C,OAAO,OACL,OAAO,qBAAqB,YAC1B,OAAO,IAAI,aAAa;CACtB,MAAM,MAAM,OAAO,OAAO,aAAa,gBAAgB,CAAC,CAAC,WAAW,EAClE,kBAAkB,QACpB,CAAC,CAAC,CAAC,KACD,OAAO,eACL,aAAa,KAAK;EAChB,WAAW;EACX,QAAQ;EACR,SAAS;CACX,CAAC,CACH,CACF;CAEA,MAAM,UAAU,QAAQ,2BAA2B;CAEnD,IACE,CAAC,OAAO,cAAc,OAAO,KAC7B,UAAU,KACV,UAAU,OACV,oBAAoB,GAAG,GAEvB,OAAO,OAAO,aAAa,KAAK;EAC9B,WAAW;EACX,QAAQ,oBAAoB,GAAG,IAAI,WAAW;EAC9C,SAAS;CACX,CAAC;CAEH,MAAM,SAAS,OAAO,wBAAwB,GAAG;CACjD,MAAM,WAAW,OAAO,QAAQ,QAAQ,QAAQ,GAAG,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI;CAEtE,IAAI,KAAK,UAAU,QAAQ,GAAG;EAC5B,yBAAyB,QAAQ,KAAK;EAEtC,OAAO,OAAO,OAAO,UAAU,SAAS,KAAK;CAC/C;CACA,MAAM,QAAQ,SAAS;CAEvB,MAAM,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAC5E,OAAO,IACT;CAGA,IAAI,KAAK,UAAU,IAAI,GAAG,OAAO,OAAO;CACxC,IAAI,eAAwD,KAAK;CAEjE,IAAI,KAAK,UAAU,IAAI,KAAK,QAAQ,WAAW,KAAA,GAAW;EACxD,eAAe,OAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KACvE,OAAO,IACT;EACA,IAAI,KAAK,UAAU,YAAY,GAC7B,eAAe,OAAO,OACnB,gBAAgB,OAAO,MAAM,iBAAiB,CAAC,CAC/C,KAAK,OAAO,IAAI;OACd,OAAO,OAAO;CACvB;CACA,MAAM,QAAQ,OAAO,OAAO;CAE5B,MAAM,aAAa,OAAO,QAAQ,MAAM,OAAO,KAAK,CAAC,CAAC,CAAC,KACrD,OAAO,cAAc;EACnB,UAAU;EACV,cACE,OAAO,KACL,aAAa,KAAK;GAChB,WAAW;GACX,QAAQ;GACR,SAAS;EACX,CAAC,CACH;CACJ,CAAC,GACD,OAAO,IACT;CAEA,IAAI,KAAK,UAAU,UAAU,GAAG,OAAO,OAAO;CAC9C,yBACE,QACA,KAAK,UAAU,UAAU,KAAK,MAAM,gBAAgB,SACtD;CAGA,IAAI,KAAK,UAAU,IAAI,GAAG;EACxB,IAAI,KAAK,UAAU,UAAU,GAC3B,OAAO,OAAO,SAAS,oDAAoD;EAE7E,OAAO,OAAO,OAAO,UAAU,KAAK,KAAK;CAC3C;CACA,IAAI,KAAK,UAAU,YAAY,GAAG,OAAO,OAAO,OAAO,UAAU,aAAa,KAAK;CACnF,IAAI,KAAK,UAAU,UAAU,GAAG,OAAO,OAAO,OAAO,UAAU,WAAW,KAAK;CAE/E,OAAO,KAAK;AACd,CAAC,CACH,CACF"}
@@ -9,17 +9,13 @@ import { Effect, Schema } from "effect";
9
9
  * `ContextCoordination` and `ContextWriter` both read this module, never each other.
10
10
  */
11
11
  const PersistenceEvidence = Schema.Union([
12
- Schema.Struct({ _tag: Schema.Literal("NotRequested") }),
13
- Schema.Struct({
14
- _tag: Schema.Literal("Unconfirmed"),
15
- reason: Schema.Literals([
16
- "writer-active",
17
- "writer-unknown",
18
- "flush-unacknowledged"
19
- ])
20
- }),
21
- Schema.Struct({
22
- _tag: Schema.Literal("Observed"),
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", {
23
19
  method: Schema.Literal("consumer-readback"),
24
20
  observedAtMillis: Schema.Finite
25
21
  })
@@ -184,4 +180,4 @@ const requireContextWriterPermit = (permit, reference) => Effect.suspend(() => {
184
180
  //#endregion
185
181
  export { PersistenceEvidence as a, requireContextWriterPermit as i, isContextWriterBusy as n, WriterAttemptFacts as o, makeContextWriterPermit as r, WriterSettlementFacts as s, closeContextWriterPermit as t };
186
182
 
187
- //# sourceMappingURL=ContextWriter-BrQmoXRg.mjs.map
183
+ //# sourceMappingURL=ContextWriter-oKWFLHuP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextWriter-oKWFLHuP.mjs","names":[],"sources":["../src/internal/session/WriterFacts.ts","../src/internal/session/ContextWriter.ts"],"sourcesContent":["import { type Effect, 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.TaggedStruct(\"NotRequested\", {}),\n Schema.TaggedStruct(\"Unconfirmed\", {\n reason: Schema.Literals([\"writer-active\", \"writer-unknown\", \"flush-unacknowledged\"]),\n }),\n Schema.TaggedStruct(\"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":";;;;;;;;;;AAUA,MAAa,sBAAsB,OAAO,MAAM;CAC9C,OAAO,aAAa,gBAAgB,CAAC,CAAC;CACtC,OAAO,aAAa,eAAe,EACjC,QAAQ,OAAO,SAAS;EAAC;EAAiB;EAAkB;CAAsB,CAAC,EACrF,CAAC;CACD,OAAO,aAAa,YAAY;EAC9B,QAAQ,OAAO,QAAQ,mBAAmB;EAC1C,kBAAkB,OAAO;CAC3B,CAAC;AACH,CAAC;AAID,IAAa,qBAAb,cAAwC,OAAO,MAC7C,+BACF,CAAC,CAAC;CACA,SAAS;CACT,SAAS,OAAO,YAAY,gBAAgB;CAC5C,OAAO,OAAO,SAAS;EAAC;EAAY;EAAY;EAAW;CAAU,CAAC;CACtE,SAAS,OAAO,YAAY,aAAa;AAC3C,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAa,wBAAb,cAA2C,OAAO,MAChD,kCACF,CAAC,CAAC;CACA,WAAW;CACX,UAAU,OAAO,MAAM,kBAAkB,CAAC,CAAC,MAAM,OAAO,YAAY,EAAE,CAAC;CACvE,aAAa;CACb,aAAa,OAAO,SAAS,CAAC,WAAW,YAAY,CAAC;AACxD,CAAC,CAAC,CAAC,CAAC;;;ACRJ,MAAM,4BAAY,IAAI,QAA0D;AAChF,MAAM,yBAAS,IAAI,IAAyD;AAC5E,MAAM,OAAO,QAA0B,GAAG,IAAI,UAAU,GAAG,IAAI;AAE/D,MAAa,uBAAuB,QAAmC,OAAO,IAAI,IAAI,GAAG,CAAC;AAE1F,MAAa,2BACX,cAEA,OAAO,cAAc;CACnB,IAAI,OAAO,IAAI,IAAI,SAAS,CAAC,KAAK,OAAO,QAAQ,MAC/C,OAAO,OAAO,KACZ,aAAa,KAAK;EAAE,WAAW;EAAU,QAAQ;EAAU,SAAS;CAAe,CAAC,CACtF;CACF,MAAM,QAAQ,OAAO,OAAO,SAAS;CACrC,MAAM,2BAAW,IAAI,IAA2B;CAEhD,IAAI,SAAS,OACX,cAAc;CAEhB,IAAI,cAAmC,EAAE,MAAM,eAAe;CAE9D,MAAM,gBAAgB;EACpB,cAAc;EACd,cAAc;GAAE,MAAM;GAAe,QAAQ;EAAiB;CAChE;CAEA,MAAM,iBACJ,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,OACpB,UAAU,MAAM,UAAU,cAAc,MAAM,UAAU,UAC3D;CAEF,MAAM,SAAsC;EAC1C,MAAM;EACN,WAAW;EACX,gBAAgB,YACd,OAAO,cAAc;GACnB,IACE,UACA,eACA,CAAC,SAAS,KACV,QAAQ,cAAc,MAAM,aAC3B,SAAS,OAAO,KAAK,YAAY,SAAS,eAE3C,OAAO,OAAO,KACZ,aAAa,KAAK;IAChB,WAAW;IACX,QAAQ;IACR,SAAS;GACX,CAAC,CACH;GAEF,IAAI,SAAS,IAAI,QAAQ,SAAS,KAAK,SAAS,QAAQ,IACtD,OAAO,OAAO,KACZ,aAAa,KAAK;IAChB,WAAW;IACX,QAAQ;IACR,SAAS;GACX,CAAC,CACH;GACF,MAAM,OAAO,OAAO,OAAO,OAAO;GAElC,SAAS,IAAI,KAAK,WAAW;IAAE,SAAS;IAAM,OAAO;GAAW,CAAC;GACjE,cAAc;IAAE,MAAM;IAAe,QAAQ;GAAgB;GAE7D,OAAO,OAAO;EAChB,CAAC;EACH,gBAAgB,SAAS,YAAY;GACnC,MAAM,SAAS,SAAS,IAAI,QAAQ,SAAS;GAE7C,IACE,WAAW,KAAA,KACX,OAAO,YAAY,WACnB,QAAQ,cAAc,MAAM,aAC3B,OAAO,YAAY,KAAA,KAAa,OAAO,QAAQ,cAAc,QAAQ,WACtE;IACA,QAAQ;IAER;GACF;GAEA,OAAO,UAAU,OAAO,OAAO,OAAO;EACxC;EACA,WAAW,YAAY;GACrB,MAAM,SAAS,SAAS,IAAI,QAAQ,SAAS;GAE7C,IAAI,WAAW,KAAA,KAAa,OAAO,YAAY,WAAW,OAAO,YAAY,KAAA,GAAW;IACtF,QAAQ;IAER;GACF;GACA,OAAO,QAAQ;GACf,IAAI,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,SAAS,KAAK,UAAU,UAAU,GAClE,cAAc,EAAE,MAAM,eAAe;EACzC;EACA,YAAY,YAAY;GACtB,MAAM,SAAS,SAAS,IAAI,QAAQ,SAAS;GAE7C,IAAI,WAAW,KAAA,KAAa,OAAO,YAAY,SAAS,OAAO,QAAQ;GACvE,QAAQ;EACV;EACA,YAAY,SAAS,YAAY;GAC/B,MAAM,SAAS,SAAS,IAAI,QAAQ,SAAS;GAE7C,IACE,WAAW,KAAA,KACX,OAAO,YAAY,WACnB,QAAQ,cAAc,WACtB,OAAO,YAAY,KAAA,KACnB,OAAO,QAAQ,cAAc,QAAQ,UAAU,aAC/C,QAAQ,UAAU,cAAc,MAAM,WACtC;IACA,QAAQ;IAER;GACF;GACA,OAAO,UAAU;GACjB,IAAI,QAAQ,WAAW,aAAa;IAClC,OAAO,QAAQ;IACf,QAAQ;IAER;GACF;GACA,OAAO,QAAQ;GACf,IAAI,QAAQ,mBAAmB,aAAa;IAC1C,QAAQ;IAER;GACF;GACA,IAAI,CAAC,aAAa,cAAc;IAAE,MAAM;IAAe,QAAQ;GAAuB;EACxF;EACA,kBAAkB,aAChB,OAAO,cAAc;GACnB,IACE,UACA,eACA,CAAC,SAAS,KACV,CAAC,OAAO,SAAS,QAAQ,KACzB,SAAS,SAAS,KAClB,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,MACpB,UACC,MAAM,UAAU,cAAc,MAAM,SAAS,mBAAmB,WACpE,GAEA,OAAO,OAAO,KACZ,aAAa,KAAK;IAChB,WAAW;IACX,QAAQ;IACR,SAAS;GACX,CAAC,CACH;GAEF,cAAc;IACZ,MAAM;IACN,QAAQ;IACR,kBAAkB;GACpB;GAEA,OAAO,OAAO;EAChB,CAAC;EACH,YAAY,OAAO,KAAK,OAAO;EAC/B,UAAU,OAAO,WACf,sBAAsB,KAAK;GACzB,WAAW;GACX,UAAU,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,UACpC,mBAAmB,KAAK;IACtB,SAAS,MAAM;IACf,OAAO,MAAM;IACb,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;IAChE,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;GAClE,CAAC,CACH;GACA;GACA,aACE,eAAe,CAAC,SAAS,KAAK,YAAY,SAAS,gBAC/C,eACA;EACR,CAAC,CACH;CACF;CAEA,OAAO,OAAO,MAAM;CACpB,UAAU,IAAI,QAAQ,MAAM;CAC5B,OAAO,IAAI,IAAI,KAAK,GAAG,MAAM;CAE7B,WAAW,IAAI,SAAS,aAAa;EACnC,SAAS;EACT,IAAI,OAAO,IAAI,IAAI,KAAK,CAAC,MAAM,QAAQ;EACvC,IAAI,UAAU,OAAO,OAAO,IAAI,KAAK,CAAC;OACjC,OAAO,IAAI,IAAI,KAAK,GAAG,aAAa;CAC3C,CAAC;CAED,OAAO,OAAO,QAAQ,MAAM;AAC9B,CAAC;AAEH,MAAM,6BAAa,IAAI,QAAkE;AAEzF,MAAa,4BACX,QACA,aACS,WAAW,IAAI,MAAM,CAAC,GAAG,QAAQ;AAE5C,MAAa,8BACX,QACA,cAEA,OAAO,cAAc;CACnB,MAAM,SAAS,UAAU,IAAI,MAAM;CAEnC,OAAO,WAAW,KAAA,KAChB,OAAO,IAAI,IAAI,SAAS,CAAC,MAAM,UAC/B,OAAO,UAAU,cAAc,UAAU,aACzC,OAAO,UAAU,cAAc,UAAU,YACvC,OAAO,QAAQ,MAAM,IACrB,OAAO,KACL,aAAa,KAAK;EAChB,WAAW;EACX,QAAQ;EACR,SAAS;CACX,CAAC,CACH;AACN,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { n as ContextReference } from "./References-DOH3Wu44.mjs";
2
+ import { ContextError } from "./Errors.mjs";
3
+ import { t as BrowserbaseClient } from "./Client-B_f6bBLT.mjs";
4
+ import { Context, Effect, Layer, Schema } from "effect";
5
+ //#region src/Contexts.d.ts
6
+ declare const ContextMetadata_base: Schema.Class<ContextMetadata, Schema.Struct<{
7
+ readonly reference: typeof ContextReference;
8
+ readonly createdAt: Schema.String;
9
+ readonly updatedAt: Schema.String;
10
+ readonly name: Schema.optionalKey<Schema.String>;
11
+ }>, {}>;
12
+ declare class ContextMetadata extends ContextMetadata_base {}
13
+ declare const ContextCreation_base: Schema.Class<ContextCreation, Schema.Struct<{
14
+ readonly reference: typeof ContextReference;
15
+ }>, {}>;
16
+ declare class ContextCreation extends ContextCreation_base {}
17
+ declare const BrowserbaseContexts_base: Context.ServiceClass<BrowserbaseContexts, "effect-browserbase/Contexts", {
18
+ readonly create: (options?: {
19
+ readonly name?: string;
20
+ }) => Effect.Effect<ContextCreation, ContextError>;
21
+ readonly retrieve: (reference: ContextReference) => Effect.Effect<ContextMetadata, ContextError>;
22
+ readonly delete: (reference: ContextReference) => Effect.Effect<void, ContextError>;
23
+ }>;
24
+ /** Context administration is independent of any live browser connection. */
25
+ declare class BrowserbaseContexts extends BrowserbaseContexts_base {
26
+ static readonly layer: Layer.Layer<BrowserbaseContexts, never, BrowserbaseClient>;
27
+ }
28
+ //#endregion
29
+ export { ContextCreation as n, ContextMetadata as r, BrowserbaseContexts as t };
30
+ export {};
31
+ //# sourceMappingURL=Contexts-DqdL7cyX.d.mts.map