@effect-agent/platform-cloudflare 0.1.0-beta.107 → 0.1.0-beta.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CloudflareThreadClient.d.mts +33 -33
- package/dist/{InteractiveBrowser-B3S8if51.d.mts → InteractiveBrowser-CKp6pqmw.d.mts} +2 -1
- package/dist/{InteractiveBrowser-xVNX7ARl.mjs → InteractiveBrowser-l6J4eP6T.mjs} +192 -37
- package/dist/InteractiveBrowser-l6J4eP6T.mjs.map +1 -0
- package/dist/InteractiveBrowser.d.mts +1 -1
- package/dist/InteractiveBrowser.mjs +1 -1
- package/dist/ProtectedBrowser.d.mts +3 -3
- package/dist/ProtectedBrowser.mjs +160 -135
- package/dist/ProtectedBrowser.mjs.map +1 -1
- package/dist/{ThreadObject-CnqCuWlA.d.mts → ThreadObject-D_vvj7Qx.d.mts} +33 -33
- package/dist/ThreadObject.d.mts +1 -1
- package/dist/index.d.mts +1 -1
- package/package.json +1 -1
- package/src/InteractiveBrowser.ts +189 -46
- package/src/internal/browser-binding.ts +82 -0
- package/src/internal/browser-failure.ts +92 -0
- package/src/internal/browser-session-lifecycle.ts +38 -5
- package/src/protected-browser/binding.ts +170 -129
- package/src/protected-browser/host.ts +52 -19
- package/src/protected-browser/native.ts +45 -17
- package/src/protected-browser/policy.ts +75 -39
- package/dist/InteractiveBrowser-xVNX7ARl.mjs.map +0 -1
|
@@ -475,13 +475,13 @@ export declare const encodeUnknownResolutionCommand: (input: UnknownResolutionCo
|
|
|
475
475
|
readonly author: string;
|
|
476
476
|
readonly reason: string;
|
|
477
477
|
readonly resolution: {
|
|
478
|
-
readonly _tag: "SafeToRetry";
|
|
479
|
-
} | {
|
|
480
478
|
readonly _tag: "CompletedWithResult";
|
|
481
479
|
readonly result: Schema.Json;
|
|
482
480
|
readonly isFailure: boolean;
|
|
483
481
|
} | {
|
|
484
482
|
readonly _tag: "NeverHappened";
|
|
483
|
+
} | {
|
|
484
|
+
readonly _tag: "SafeToRetry";
|
|
485
485
|
} | {
|
|
486
486
|
readonly _tag: "AbortSubmission";
|
|
487
487
|
};
|
|
@@ -645,11 +645,6 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
645
645
|
readonly createdAt: string;
|
|
646
646
|
readonly deploymentId: string;
|
|
647
647
|
readonly payload: {
|
|
648
|
-
readonly _tag: "AbortRequested";
|
|
649
|
-
readonly submissionId: string;
|
|
650
|
-
readonly author: string;
|
|
651
|
-
readonly reason: string;
|
|
652
|
-
} | {
|
|
653
648
|
readonly _tag: "ThreadCreated";
|
|
654
649
|
readonly agentId: string;
|
|
655
650
|
readonly definitions: {
|
|
@@ -927,6 +922,11 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
927
922
|
readonly runDisposition?: Schema.Json | undefined;
|
|
928
923
|
readonly finishReason?: "budget-exhausted" | undefined;
|
|
929
924
|
readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
|
|
925
|
+
} | {
|
|
926
|
+
readonly _tag: "AbortRequested";
|
|
927
|
+
readonly submissionId: string;
|
|
928
|
+
readonly author: string;
|
|
929
|
+
readonly reason: string;
|
|
930
930
|
} | {
|
|
931
931
|
readonly _tag: "SubmissionSettled";
|
|
932
932
|
readonly submissionId: string;
|
|
@@ -1465,13 +1465,13 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1465
1465
|
readonly author: string;
|
|
1466
1466
|
readonly reason: string;
|
|
1467
1467
|
readonly resolution: {
|
|
1468
|
-
readonly _tag: "SafeToRetry";
|
|
1469
|
-
} | {
|
|
1470
1468
|
readonly _tag: "CompletedWithResult";
|
|
1471
1469
|
readonly result: Schema.Json;
|
|
1472
1470
|
readonly isFailure: boolean;
|
|
1473
1471
|
} | {
|
|
1474
1472
|
readonly _tag: "NeverHappened";
|
|
1473
|
+
} | {
|
|
1474
|
+
readonly _tag: "SafeToRetry";
|
|
1475
1475
|
} | {
|
|
1476
1476
|
readonly _tag: "AbortSubmission";
|
|
1477
1477
|
};
|
|
@@ -1481,6 +1481,21 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1481
1481
|
} | {
|
|
1482
1482
|
readonly _tag: "HostFailed";
|
|
1483
1483
|
readonly failure: {
|
|
1484
|
+
readonly _tag: "DurableAlarmError";
|
|
1485
|
+
readonly operation: string;
|
|
1486
|
+
readonly message: string;
|
|
1487
|
+
readonly cause?: Schema.Json | undefined;
|
|
1488
|
+
} | {
|
|
1489
|
+
readonly _tag: "HostProtocolError";
|
|
1490
|
+
readonly message: string;
|
|
1491
|
+
} | {
|
|
1492
|
+
readonly _tag: "AgentInputError";
|
|
1493
|
+
readonly message: string;
|
|
1494
|
+
} | {
|
|
1495
|
+
readonly _tag: "DigestError";
|
|
1496
|
+
readonly message: string;
|
|
1497
|
+
readonly cause?: Schema.Json | undefined;
|
|
1498
|
+
} | {
|
|
1484
1499
|
readonly _tag: "AdmissionConflict";
|
|
1485
1500
|
readonly threadId: string;
|
|
1486
1501
|
readonly principal: string;
|
|
@@ -1497,6 +1512,15 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1497
1512
|
readonly _tag: "SettlementConflict";
|
|
1498
1513
|
readonly submissionId: string;
|
|
1499
1514
|
readonly existingOutcome: "aborted" | "completed" | "failed";
|
|
1515
|
+
} | {
|
|
1516
|
+
readonly _tag: "ApprovalConflict";
|
|
1517
|
+
readonly submissionId: string;
|
|
1518
|
+
readonly toolCallId: string;
|
|
1519
|
+
readonly existingDecision: "approved" | "denied";
|
|
1520
|
+
} | {
|
|
1521
|
+
readonly _tag: "UnknownResolutionConflict";
|
|
1522
|
+
readonly submissionId: string;
|
|
1523
|
+
readonly toolCallId: string;
|
|
1500
1524
|
} | {
|
|
1501
1525
|
readonly _tag: "JoinedToHost";
|
|
1502
1526
|
readonly submissionId: string;
|
|
@@ -1526,25 +1550,6 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1526
1550
|
readonly threadId: string;
|
|
1527
1551
|
readonly actualEpoch: number;
|
|
1528
1552
|
readonly attemptedEpoch: number;
|
|
1529
|
-
} | {
|
|
1530
|
-
readonly _tag: "HostProtocolError";
|
|
1531
|
-
readonly message: string;
|
|
1532
|
-
} | {
|
|
1533
|
-
readonly _tag: "AgentInputError";
|
|
1534
|
-
readonly message: string;
|
|
1535
|
-
} | {
|
|
1536
|
-
readonly _tag: "DigestError";
|
|
1537
|
-
readonly message: string;
|
|
1538
|
-
readonly cause?: Schema.Json | undefined;
|
|
1539
|
-
} | {
|
|
1540
|
-
readonly _tag: "ApprovalConflict";
|
|
1541
|
-
readonly submissionId: string;
|
|
1542
|
-
readonly toolCallId: string;
|
|
1543
|
-
readonly existingDecision: "approved" | "denied";
|
|
1544
|
-
} | {
|
|
1545
|
-
readonly _tag: "UnknownResolutionConflict";
|
|
1546
|
-
readonly submissionId: string;
|
|
1547
|
-
readonly toolCallId: string;
|
|
1548
1553
|
} | {
|
|
1549
1554
|
readonly _tag: "DurableRuntimeFailpointError";
|
|
1550
1555
|
readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "checkpoint:after-save" | "checkpoint:before-save" | "claim:after-claim" | "compaction:after-canonical-append" | "compaction:before-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "policy:after-reservation-append" | "policy:before-reservation-append" | "resolve:after-intent" | "run:after-duration-append" | "run:after-start-append" | "run:before-duration-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "subagent:before-join-append" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "tools:after-unavailable-append" | "tools:before-prepared-append" | "tools:before-unavailable-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append" | "update:after-canonical-append" | "update:after-delivery-insert" | "update:before-canonical-append" | "update:before-delivery-insert" | "worker:after-completion-append" | "worker:after-origin-append" | "worker:after-report-append" | "worker:after-report-delivery" | "worker:after-source-append" | "worker:after-subtree-append" | "worker:before-completion-append" | "worker:before-origin-append" | "worker:before-report-append" | "worker:before-report-delivery" | "worker:before-source-append" | "worker:before-subtree-append";
|
|
@@ -1553,11 +1558,6 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1553
1558
|
readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
|
|
1554
1559
|
readonly actual: number;
|
|
1555
1560
|
readonly maximum: number;
|
|
1556
|
-
} | {
|
|
1557
|
-
readonly _tag: "DurableAlarmError";
|
|
1558
|
-
readonly operation: string;
|
|
1559
|
-
readonly message: string;
|
|
1560
|
-
readonly cause?: Schema.Json | undefined;
|
|
1561
1561
|
} | {
|
|
1562
1562
|
readonly _tag: "OperationDenied";
|
|
1563
1563
|
readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
|
|
@@ -6,6 +6,7 @@ import { BrowserHandle, BrowserSelectFileRequest, InteractiveBrowser, Interactiv
|
|
|
6
6
|
declare const BrowserRunCleanupError_base: Schema.Class<BrowserRunCleanupError, Schema.TaggedStruct<"BrowserRunCleanupError", {
|
|
7
7
|
readonly reason: Schema.Literals<readonly ["configuration", "authorization", "rate-limited", "provider", "malformed", "timeout", "pending"]>;
|
|
8
8
|
readonly status: Schema.optionalKey<Schema.Int>;
|
|
9
|
+
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
9
10
|
}>, import("effect/Cause").YieldableError>;
|
|
10
11
|
declare class BrowserRunCleanupError extends BrowserRunCleanupError_base {}
|
|
11
12
|
interface BrowserRunLifecycleOptions {
|
|
@@ -167,4 +168,4 @@ declare const CloudflareInteractiveBrowser: {
|
|
|
167
168
|
};
|
|
168
169
|
//#endregion
|
|
169
170
|
export { isBrowserRunUndispatchedActionError as C, browserRunInteractiveLayer as S, BrowserRunSessionLifecycle as T, BrowserRunViewport as _, BrowserRunInteractiveAcquisition as a, browserRunInteractiveHostLayer as b, BrowserRunInteractiveCdpSession as c, BrowserRunInteractivePage as d, BrowserRunInteractiveRequest as f, BrowserRunLiveViewResult as g, BrowserRunLiveViewRequest as h, BrowserRunHandoffState as i, BrowserRunInteractiveContext as l, BrowserRunInteractiveSession as m, BrowserRunHandoffRequest as n, BrowserRunInteractiveBinding as o, BrowserRunInteractiveRequestListener as p, BrowserRunHandoffResult as r, BrowserRunInteractiveBrowser as s, BrowserRunCloudflareCommand as t, BrowserRunInteractiveHost as u, CloudflareInteractiveBrowser as v, BrowserRunCleanupError as w, browserRunInteractiveImplementation as x, CloudflareInteractiveBrowserOptions as y };
|
|
170
|
-
//# sourceMappingURL=InteractiveBrowser-
|
|
171
|
+
//# sourceMappingURL=InteractiveBrowser-CKp6pqmw.d.mts.map
|
|
@@ -1,9 +1,102 @@
|
|
|
1
|
-
import { Clock, Context, Duration, Effect, Encoding, Layer, Option, Redacted, Ref, Schema, Scope, Semaphore, Stream } from "effect";
|
|
1
|
+
import { Cause, Clock, Context, Data, Duration, Effect, Encoding, ErrorReporter, Layer, Option, Predicate, Redacted, Ref, Schema, Scope, Semaphore, Stream } from "effect";
|
|
2
2
|
import { PageScreenshotResult } from "effect-agent/page-screenshot";
|
|
3
3
|
import { SandboxImplementation } from "effect-agent/sandbox";
|
|
4
4
|
import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
|
|
5
5
|
import puppeteer from "@cloudflare/puppeteer";
|
|
6
6
|
import { BrowserActionResult, BrowserFileSelectionResult, BrowserNavigationResult, BrowserScreenshotRequest, BrowserScrollRequest, BrowserSelectFileRequest, BrowserTextResult, InteractiveBrowser, InteractiveBrowserActionError, InteractiveBrowserBusyError, InteractiveBrowserCapacityError, InteractiveBrowserExpiredError, InteractiveBrowserLimitError, InteractiveBrowserPolicy, InteractiveBrowserPolicyDeniedError, InteractiveBrowserProtocolError, InteractiveBrowserTargetUrl, InteractiveBrowserUnsupportedError } from "effect-agent/interactive-browser";
|
|
7
|
+
//#region src/internal/browser-failure.ts
|
|
8
|
+
/** Source-authored stages and classifications only; never retain SDK text or session capabilities. */
|
|
9
|
+
var BrowserRunFailure = class extends Data.TaggedError("BrowserRunFailure") {
|
|
10
|
+
[ErrorReporter.severity] = "Error";
|
|
11
|
+
};
|
|
12
|
+
/** A public projection of an already reported private failure must not produce another issue. */
|
|
13
|
+
const reportedBrowserError = (error) => Object.assign(error, { [ErrorReporter.ignore]: true });
|
|
14
|
+
const inheritBrowserReport = (original, error) => ErrorReporter.isIgnored(original) ? reportedBrowserError(error) : error;
|
|
15
|
+
const reasonSchema = Schema.Literals([
|
|
16
|
+
"provider",
|
|
17
|
+
"timeout",
|
|
18
|
+
"malformed",
|
|
19
|
+
"configuration",
|
|
20
|
+
"authorization",
|
|
21
|
+
"rate-limited",
|
|
22
|
+
"pending"
|
|
23
|
+
]);
|
|
24
|
+
const statusSchema = Schema.Int.check(Schema.isBetween({
|
|
25
|
+
minimum: 100,
|
|
26
|
+
maximum: 599
|
|
27
|
+
}));
|
|
28
|
+
const failureNames = /* @__PURE__ */ new Set([
|
|
29
|
+
"TypeError",
|
|
30
|
+
"RangeError",
|
|
31
|
+
"SyntaxError",
|
|
32
|
+
"TimeoutError",
|
|
33
|
+
"SchemaError"
|
|
34
|
+
]);
|
|
35
|
+
const browserFailure = (operation, cause) => cause instanceof BrowserRunFailure ? cause : new BrowserRunFailure({
|
|
36
|
+
operation,
|
|
37
|
+
reason: Predicate.isObject(cause) && "reason" in cause && Schema.is(reasonSchema)(cause.reason) ? cause.reason : "provider",
|
|
38
|
+
...Predicate.isObject(cause) && "status" in cause && Schema.is(statusSchema)(cause.status) ? { status: cause.status } : {},
|
|
39
|
+
...Predicate.isObject(cause) && "cause" in cause && cause.cause instanceof BrowserRunFailure ? { cause: cause.cause } : Predicate.isObject(cause) && "name" in cause && typeof cause.name === "string" && failureNames.has(cause.name) ? { cause: { name: cause.name } } : {}
|
|
40
|
+
});
|
|
41
|
+
/** Keep mixed defects and interruptions distinct while discarding all foreign diagnostic content. */
|
|
42
|
+
const reportBrowserCause = (operation, cause) => ErrorReporter.report(Cause.fromReasons(cause.reasons.filter((reason) => !Cause.isFailReason(reason) || !ErrorReporter.isIgnored(reason.error)).map((reason) => {
|
|
43
|
+
switch (reason._tag) {
|
|
44
|
+
case "Fail": return Cause.makeFailReason(browserFailure(operation, reason.error));
|
|
45
|
+
case "Die": return Cause.makeDieReason(browserFailure(operation, reason.defect));
|
|
46
|
+
case "Interrupt": return reason;
|
|
47
|
+
}
|
|
48
|
+
})));
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/internal/browser-binding.ts
|
|
51
|
+
const Acquired = Schema.Struct({ sessionId: Schema.String.check(Schema.isUUID()) });
|
|
52
|
+
/** Native transport port shared by both scoped adapters; the Layer owns the foreign binding. */
|
|
53
|
+
var BrowserRunBinding = class extends Context.Service()("@effect-agent/platform-cloudflare/internal/BrowserRunBinding") {
|
|
54
|
+
static layer(browser) {
|
|
55
|
+
return Layer.succeed(this)({
|
|
56
|
+
acquire: async (keepAliveMillis, operation) => {
|
|
57
|
+
const response = await browser.fetch(`https://browser-rendering.cloudflare.com/v1/devtools/browser?keep_alive=${keepAliveMillis}&recording=false`, { method: "POST" });
|
|
58
|
+
if (response.status !== 200) {
|
|
59
|
+
const failure = new BrowserRunFailure({
|
|
60
|
+
operation,
|
|
61
|
+
reason: "provider",
|
|
62
|
+
status: response.status
|
|
63
|
+
});
|
|
64
|
+
try {
|
|
65
|
+
await response.body?.cancel();
|
|
66
|
+
} catch {}
|
|
67
|
+
throw failure;
|
|
68
|
+
}
|
|
69
|
+
return Schema.decodeUnknownSync(Acquired)(await response.json()).sessionId;
|
|
70
|
+
},
|
|
71
|
+
connect: async (sessionId, operation) => {
|
|
72
|
+
let failure;
|
|
73
|
+
try {
|
|
74
|
+
return await puppeteer.connect({ fetch: async (input, init) => {
|
|
75
|
+
try {
|
|
76
|
+
const response = await browser.fetch(input, init);
|
|
77
|
+
if (response.status !== 101) {
|
|
78
|
+
failure = new BrowserRunFailure({
|
|
79
|
+
operation,
|
|
80
|
+
reason: "provider",
|
|
81
|
+
status: response.status
|
|
82
|
+
});
|
|
83
|
+
await response.body?.cancel();
|
|
84
|
+
throw failure;
|
|
85
|
+
}
|
|
86
|
+
return response;
|
|
87
|
+
} catch (cause) {
|
|
88
|
+
failure ??= browserFailure(operation, cause);
|
|
89
|
+
throw failure;
|
|
90
|
+
}
|
|
91
|
+
} }, sessionId);
|
|
92
|
+
} catch (cause) {
|
|
93
|
+
throw failure ?? browserFailure(operation, cause);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
7
100
|
//#region src/internal/browser-file-selection.ts
|
|
8
101
|
function setFileSelection(element, encoded, name, type) {
|
|
9
102
|
if (Reflect.get(element, "type") !== "file" || Reflect.get(element, "disabled") || Reflect.get(element, "webkitdirectory")) throw new Error("The target is not an enabled file input");
|
|
@@ -86,7 +179,8 @@ var BrowserRunCleanupError = class extends Schema.TaggedError()("BrowserRunClean
|
|
|
86
179
|
"timeout",
|
|
87
180
|
"pending"
|
|
88
181
|
]),
|
|
89
|
-
status: Schema.optionalKey(Schema.Int)
|
|
182
|
+
status: Schema.optionalKey(Schema.Int),
|
|
183
|
+
cause: Schema.optionalKey(Schema.Defect())
|
|
90
184
|
}) {};
|
|
91
185
|
const Identity = Schema.String.check(Schema.isUUID());
|
|
92
186
|
const Account = Schema.String.check(Schema.isPattern(/^[a-f0-9]{32}$/));
|
|
@@ -103,7 +197,10 @@ var BrowserRunSessionLifecycle = class extends Context.Service()("@effect-agent/
|
|
|
103
197
|
const client = yield* HttpClient.HttpClient;
|
|
104
198
|
const request = Effect.fn("BrowserRunSessionLifecycle.request")(function* (method, sessionId) {
|
|
105
199
|
const path = method === "DELETE" ? "browser" : "session";
|
|
106
|
-
const response = yield* client.execute(HttpClientRequest.make(method)(`https://api.cloudflare.com/client/v4/accounts/${options.accountId}/browser-rendering/devtools/${path}/${sessionId}`).pipe(HttpClientRequest.bearerToken(options.apiToken))).pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }), Effect.mapError(() => new BrowserRunCleanupError({
|
|
200
|
+
const response = yield* client.execute(HttpClientRequest.make(method)(`https://api.cloudflare.com/client/v4/accounts/${options.accountId}/browser-rendering/devtools/${path}/${sessionId}`).pipe(HttpClientRequest.bearerToken(options.apiToken))).pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }), Effect.mapError((cause) => new BrowserRunCleanupError({
|
|
201
|
+
reason: "provider",
|
|
202
|
+
cause: browserFailure("browser.close.request", cause)
|
|
203
|
+
})));
|
|
107
204
|
if (response.status === 401 || response.status === 403) return yield* new BrowserRunCleanupError({
|
|
108
205
|
reason: "authorization",
|
|
109
206
|
status: response.status
|
|
@@ -123,21 +220,33 @@ var BrowserRunSessionLifecycle = class extends Context.Service()("@effect-agent/
|
|
|
123
220
|
combined.set(body);
|
|
124
221
|
combined.set(chunk, body.byteLength);
|
|
125
222
|
return Effect.succeed(combined);
|
|
126
|
-
}).pipe(Effect.mapError(() => new BrowserRunCleanupError({
|
|
223
|
+
}).pipe(Effect.mapError((cause) => new BrowserRunCleanupError({
|
|
224
|
+
reason: "malformed",
|
|
225
|
+
cause: browserFailure("browser.close.response", cause)
|
|
226
|
+
})));
|
|
127
227
|
const body = yield* Effect.try({
|
|
128
228
|
try: () => new TextDecoder("utf-8", {
|
|
129
229
|
fatal: true,
|
|
130
230
|
ignoreBOM: false
|
|
131
231
|
}).decode(bytes),
|
|
132
|
-
catch: () => new BrowserRunCleanupError({
|
|
232
|
+
catch: (cause) => new BrowserRunCleanupError({
|
|
233
|
+
reason: "malformed",
|
|
234
|
+
cause: browserFailure("browser.close.decode", cause)
|
|
235
|
+
})
|
|
133
236
|
});
|
|
134
237
|
if (response.status === 404) {
|
|
135
238
|
const absent = Schema.decodeOption(Schema.fromJsonString(Absent))(body, { onExcessProperty: "error" });
|
|
136
239
|
if (Option.isSome(absent)) return true;
|
|
137
240
|
return yield* new BrowserRunCleanupError({ reason: "malformed" });
|
|
138
241
|
}
|
|
139
|
-
if (method === "DELETE") return (yield* Schema.decodeEffect(Schema.fromJsonString(Closed))(body).pipe(Effect.mapError(() => new BrowserRunCleanupError({
|
|
140
|
-
|
|
242
|
+
if (method === "DELETE") return (yield* Schema.decodeEffect(Schema.fromJsonString(Closed))(body).pipe(Effect.mapError((cause) => new BrowserRunCleanupError({
|
|
243
|
+
reason: "malformed",
|
|
244
|
+
cause: browserFailure("browser.close.response", cause)
|
|
245
|
+
})))).status === "closed";
|
|
246
|
+
const result = yield* Schema.decodeEffect(Schema.fromJsonString(Metadata))(body).pipe(Effect.mapError((cause) => new BrowserRunCleanupError({
|
|
247
|
+
reason: "malformed",
|
|
248
|
+
cause: browserFailure("browser.close.response", cause)
|
|
249
|
+
})));
|
|
141
250
|
if (result.sessionId !== sessionId) return yield* new BrowserRunCleanupError({ reason: "malformed" });
|
|
142
251
|
return result.endTime !== void 0 && result.endTime > 0;
|
|
143
252
|
});
|
|
@@ -302,13 +411,14 @@ var BrowserRunInteractiveBinding = class BrowserRunInteractiveBinding extends Co
|
|
|
302
411
|
static layer(options) {
|
|
303
412
|
return Layer.effect(BrowserRunInteractiveBinding)(Effect.gen(function* () {
|
|
304
413
|
const lifecycle = yield* BrowserRunSessionLifecycle;
|
|
414
|
+
const binding = yield* BrowserRunBinding;
|
|
305
415
|
const viewport = options.viewport === void 0 ? void 0 : yield* decodeViewport(options.viewport);
|
|
306
416
|
return {
|
|
307
|
-
acquire: async (keepAliveMillis) =>
|
|
308
|
-
connect: async (sessionId) => makeProductionBrowser(await
|
|
417
|
+
acquire: async (keepAliveMillis) => binding.acquire(keepAliveMillis, "interactive.acquire"),
|
|
418
|
+
connect: async (sessionId) => makeProductionBrowser(await binding.connect(sessionId, "interactive.connect"), viewport),
|
|
309
419
|
closeSession: (sessionId) => lifecycle.close(sessionId).pipe(Effect.mapError((cause) => actionError("close", cause)))
|
|
310
420
|
};
|
|
311
|
-
}));
|
|
421
|
+
})).pipe(Layer.provide(BrowserRunBinding.layer(options.browser)));
|
|
312
422
|
}
|
|
313
423
|
};
|
|
314
424
|
/** Cloudflare host authority kept separate from the provider-neutral browser handle. */
|
|
@@ -529,7 +639,14 @@ const makeProductionPage = (page) => {
|
|
|
529
639
|
const prepareFileSelection = makeFileSelection(page);
|
|
530
640
|
const listeners = /* @__PURE__ */ new Map();
|
|
531
641
|
return {
|
|
532
|
-
close: () =>
|
|
642
|
+
close: async () => {
|
|
643
|
+
if (!page.browser().isConnected()) return;
|
|
644
|
+
try {
|
|
645
|
+
await page.close();
|
|
646
|
+
} catch (cause) {
|
|
647
|
+
if (!isRemoteClosure(cause)) throw cause;
|
|
648
|
+
}
|
|
649
|
+
},
|
|
533
650
|
setBypassServiceWorker: (enabled) => page.setBypassServiceWorker(enabled),
|
|
534
651
|
setRequestInterception: (enabled) => page.setRequestInterception(enabled),
|
|
535
652
|
onRequest: (listener) => {
|
|
@@ -716,11 +833,25 @@ const makeProductionContext = (context, viewport) => ({
|
|
|
716
833
|
if (viewport !== void 0) await page.setViewport(viewport);
|
|
717
834
|
return makeProductionPage(page);
|
|
718
835
|
},
|
|
719
|
-
close: () =>
|
|
836
|
+
close: async () => {
|
|
837
|
+
if (!context.browser().isConnected()) return;
|
|
838
|
+
try {
|
|
839
|
+
await context.close();
|
|
840
|
+
} catch (cause) {
|
|
841
|
+
if (!isRemoteClosure(cause)) throw cause;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
720
844
|
});
|
|
721
845
|
const makeProductionBrowser = (browser, viewport) => ({
|
|
722
846
|
createContext: async () => makeProductionContext(await browser.createBrowserContext(), viewport),
|
|
723
|
-
close: () =>
|
|
847
|
+
close: async () => {
|
|
848
|
+
if (!browser.isConnected()) return;
|
|
849
|
+
try {
|
|
850
|
+
await browser.close();
|
|
851
|
+
} catch (cause) {
|
|
852
|
+
if (!isRemoteClosure(cause)) throw cause;
|
|
853
|
+
}
|
|
854
|
+
},
|
|
724
855
|
sessionId: () => browser.sessionId(),
|
|
725
856
|
isConnected: () => browser.isConnected(),
|
|
726
857
|
onDisconnected: (listener) => {
|
|
@@ -760,7 +891,7 @@ const causeText = (cause) => {
|
|
|
760
891
|
if (cause instanceof Error) return cause.message.slice(0, 8e3);
|
|
761
892
|
return String(cause).slice(0, 8e3);
|
|
762
893
|
};
|
|
763
|
-
const isCapacityRefusal = (cause) =>
|
|
894
|
+
const isCapacityRefusal = (cause) => cause instanceof BrowserRunFailure && cause.status === 429;
|
|
764
895
|
const isRemoteClosure = (cause) => /target closed|browser.*closed|session.*closed|connection.*closed|not connected|websocket.*closed/i.test(causeText(cause));
|
|
765
896
|
const snapshotPolicy = Effect.fn("BrowserRunInteractive.snapshotPolicy")(function* (input) {
|
|
766
897
|
const decoded = yield* Schema.decodeEffect(InteractiveBrowserPolicy, { onExcessProperty: "error" })(input).pipe(Effect.mapError(() => policyError("The interactive browser policy is malformed")));
|
|
@@ -789,21 +920,22 @@ const hostAllowed = (policy, value) => {
|
|
|
789
920
|
}
|
|
790
921
|
};
|
|
791
922
|
const keepAliveMillis = (policy) => Math.max(MIN_KEEP_ALIVE_MILLIS, Math.min(MAX_KEEP_ALIVE_MILLIS, policy.maxElapsedMillis));
|
|
923
|
+
var LateBrowserAcquisition = class extends Error {};
|
|
792
924
|
const closeLateAcquisition = async (signal, acquire, close) => {
|
|
793
925
|
const acquired = await acquire();
|
|
794
926
|
if (!signal.aborted) return acquired;
|
|
795
927
|
try {
|
|
796
928
|
await close(acquired);
|
|
797
929
|
} catch {}
|
|
798
|
-
throw new
|
|
930
|
+
throw new LateBrowserAcquisition("The interrupted browser acquisition completed late");
|
|
799
931
|
};
|
|
800
932
|
const closeWithWarning = (close, warning) => Effect.tryPromise({
|
|
801
933
|
try: close,
|
|
802
|
-
catch: () => protocolError(warning)
|
|
934
|
+
catch: (cause) => protocolError(warning, cause)
|
|
803
935
|
}).pipe(Effect.timeoutOrElse({
|
|
804
936
|
duration: Duration.millis(CLEANUP_STEP_TIMEOUT_MILLIS),
|
|
805
937
|
orElse: () => Effect.fail(protocolError(warning))
|
|
806
|
-
}), Effect.catchCause(() => Effect.logWarning(warning)));
|
|
938
|
+
}), Effect.catchCause((cause) => reportBrowserCause("interactive.cleanup", cause).pipe(Effect.andThen(Effect.logWarning(warning)))));
|
|
807
939
|
const deadlineError = Effect.fn("BrowserRunInteractive.deadlineError")(function* (policy, startedAt) {
|
|
808
940
|
const now = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
|
|
809
941
|
return yield* InteractiveBrowserLimitError.make({
|
|
@@ -867,12 +999,12 @@ const makeRequestListener = (policy, state) => (request) => {
|
|
|
867
999
|
let settlement;
|
|
868
1000
|
try {
|
|
869
1001
|
settlement = allowed ? request.continue() : request.abort();
|
|
870
|
-
} catch {
|
|
871
|
-
state.violation.value = protocolError("Resolving an intercepted browser request failed");
|
|
1002
|
+
} catch (cause) {
|
|
1003
|
+
state.violation.value = protocolError("Resolving an intercepted browser request failed", cause);
|
|
872
1004
|
return;
|
|
873
1005
|
}
|
|
874
|
-
const observed = settlement.catch(() => {
|
|
875
|
-
state.violation.value = protocolError("Resolving an intercepted browser request failed");
|
|
1006
|
+
const observed = settlement.catch((cause) => {
|
|
1007
|
+
state.violation.value = protocolError("Resolving an intercepted browser request failed", cause);
|
|
876
1008
|
}).finally(() => {
|
|
877
1009
|
state.pendingRequests.delete(observed);
|
|
878
1010
|
});
|
|
@@ -1084,15 +1216,25 @@ const runTeardown = (entries) => Effect.forEach([...entries].reverse(), (entry)
|
|
|
1084
1216
|
onSuccess: () => void 0
|
|
1085
1217
|
}))).pipe(Effect.map((failures) => failures.filter((failure) => failure !== void 0)));
|
|
1086
1218
|
const cdpCommand = (page, state, command, parameters, output, malformedMessage) => Effect.scoped(Effect.gen(function* () {
|
|
1219
|
+
const cleanupContext = yield* Effect.context();
|
|
1087
1220
|
const cdp = yield* Effect.acquireRelease(Effect.tryPromise({
|
|
1088
|
-
try: (signal) =>
|
|
1221
|
+
try: (signal) => {
|
|
1222
|
+
const pending = closeLateAcquisition(signal, page.createCdpSession, (acquired) => Effect.runPromiseWith(cleanupContext)(Effect.tryPromise({
|
|
1223
|
+
try: () => acquired.detach(),
|
|
1224
|
+
catch: (cause) => actionError("close", cause)
|
|
1225
|
+
}).pipe(Effect.tapCause((cause) => reportBrowserCause("interactive.lateDetach", cause)))));
|
|
1226
|
+
pending.then(void 0, (cause) => {
|
|
1227
|
+
if (signal.aborted && !(cause instanceof LateBrowserAcquisition)) return Effect.runPromiseWith(cleanupContext)(reportBrowserCause("interactive.connect", Cause.fail(cause)));
|
|
1228
|
+
});
|
|
1229
|
+
return pending;
|
|
1230
|
+
},
|
|
1089
1231
|
catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the Cloudflare browser control session failed", cause)
|
|
1090
1232
|
}), (acquired) => closeWithWarning(acquired.detach, "Detaching the Cloudflare browser control session failed"), { interruptible: true });
|
|
1091
1233
|
const raw = yield* Effect.tryPromise({
|
|
1092
1234
|
try: () => cdp.send(command, parameters),
|
|
1093
1235
|
catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("The Cloudflare browser control command failed", cause)
|
|
1094
1236
|
});
|
|
1095
|
-
return yield* Schema.decodeUnknownEffect(output)(raw).pipe(Effect.
|
|
1237
|
+
return yield* Schema.decodeUnknownEffect(output)(raw).pipe(Effect.catch((error) => reportBrowserCause("interactive.command.decode", Cause.fail(error)).pipe(Effect.andThen(Effect.fail(reportedBrowserError(protocolError(malformedMessage)))))));
|
|
1096
1238
|
}));
|
|
1097
1239
|
const makeHostService = (binding) => {
|
|
1098
1240
|
const closeSession = binding.closeSession;
|
|
@@ -1104,20 +1246,27 @@ const makeHostService = (binding) => {
|
|
|
1104
1246
|
}));
|
|
1105
1247
|
const remaining = deadline - (yield* Clock.currentTimeMillis);
|
|
1106
1248
|
if (remaining <= 0) return yield* Effect.logWarning("Local browser teardown skipped after confirmed termination deadline");
|
|
1107
|
-
yield* runTeardown(entries).pipe(Effect.flatMap((failures) => Effect.forEach(failures, (failure) => Effect.logWarning(failure.warning), { discard: true })), Effect.interruptible, Effect.timeout(`${remaining} millis`), Effect.catchCause(() => Effect.logWarning("Local browser teardown incomplete after confirmed termination")));
|
|
1249
|
+
yield* runTeardown(entries).pipe(Effect.flatMap((failures) => Effect.forEach(failures, (failure) => reportBrowserCause("interactive.cleanup", Cause.fail(failure.error)).pipe(Effect.andThen(Effect.logWarning(failure.warning))), { discard: true })), Effect.interruptible, Effect.timeout(`${remaining} millis`), Effect.catchCause((cause) => reportBrowserCause("interactive.cleanup", cause).pipe(Effect.andThen(Effect.logWarning("Local browser teardown incomplete after confirmed termination")))));
|
|
1108
1250
|
});
|
|
1109
1251
|
const closeAcquired = Effect.fn("BrowserRunInteractiveHost.closeAcquired")(function* (browser) {
|
|
1110
1252
|
const sessionId = yield* Effect.try({
|
|
1111
1253
|
try: browser.sessionId,
|
|
1112
|
-
catch: () => actionError("close")
|
|
1113
|
-
}).pipe(Effect.flatMap(Schema.decodeUnknownEffect(BrowserRunSessionId)), Effect.mapError(() => actionError("close")), Effect.onError(() => closeWithWarning(browser.close, "Closing an unidentified browser failed")));
|
|
1254
|
+
catch: (cause) => actionError("close", cause)
|
|
1255
|
+
}).pipe(Effect.flatMap(Schema.decodeUnknownEffect(BrowserRunSessionId)), Effect.mapError((cause) => actionError("close", cause)), Effect.onError(() => closeWithWarning(browser.close, "Closing an unidentified browser failed")));
|
|
1114
1256
|
yield* terminate(Redacted.make(sessionId), [closeEntry(browser.close, "Closing the local browser connection failed")]);
|
|
1115
1257
|
});
|
|
1116
1258
|
const acquire = Effect.fn("BrowserRunInteractiveHost.acquire")(function* (policy) {
|
|
1117
1259
|
const scope = yield* Scope.Scope;
|
|
1118
1260
|
const fixedPolicy = yield* snapshotPolicy(policy);
|
|
1119
1261
|
const startedAt = yield* Effect.clockWith((clock) => clock.currentTimeMillis);
|
|
1120
|
-
const runCleanup = Effect.runPromiseWith(
|
|
1262
|
+
const runCleanup = (effect) => Effect.runPromiseWith(cleanupContext)(effect.pipe(Effect.tapCause((cause) => reportBrowserCause("interactive.lateCleanup", cause))));
|
|
1263
|
+
const cleanupContext = yield* Effect.context();
|
|
1264
|
+
const observeLate = (signal, pending) => {
|
|
1265
|
+
pending.then(void 0, (cause) => {
|
|
1266
|
+
if (signal.aborted && !(cause instanceof LateBrowserAcquisition)) return runCleanup(reportBrowserCause("interactive.acquire", Cause.fail(cause)));
|
|
1267
|
+
});
|
|
1268
|
+
return pending;
|
|
1269
|
+
};
|
|
1121
1270
|
const state = {
|
|
1122
1271
|
closed: { value: false },
|
|
1123
1272
|
disconnected: { value: false },
|
|
@@ -1127,9 +1276,9 @@ const makeHostService = (binding) => {
|
|
|
1127
1276
|
};
|
|
1128
1277
|
const lifecycle = { managedTeardownInstalled: false };
|
|
1129
1278
|
const closers = [];
|
|
1130
|
-
const releaseBeforeManaged = (entry) => Effect.suspend(() => lifecycle.managedTeardownInstalled ? Effect.void : entry.close.pipe(Effect.catchCause(() => Effect.logWarning(entry.warning))));
|
|
1279
|
+
const releaseBeforeManaged = (entry) => Effect.suspend(() => lifecycle.managedTeardownInstalled ? Effect.void : entry.close.pipe(Effect.catchCause((cause) => reportBrowserCause("interactive.cleanup", cause).pipe(Effect.andThen(Effect.logWarning(entry.warning))))));
|
|
1131
1280
|
const sessionIdValue = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
|
|
1132
|
-
try: (signal) => closeLateAcquisition(signal, () => binding.acquire(keepAliveMillis(fixedPolicy)), (id) => runCleanup(Schema.decodeUnknownEffect(BrowserRunSessionId)(id).pipe(Effect.flatMap((value) => terminate(Redacted.make(value), []))))),
|
|
1281
|
+
try: (signal) => observeLate(signal, closeLateAcquisition(signal, () => binding.acquire(keepAliveMillis(fixedPolicy)), (id) => runCleanup(Schema.decodeUnknownEffect(BrowserRunSessionId)(id).pipe(Effect.flatMap((value) => terminate(Redacted.make(value), [])))))),
|
|
1133
1282
|
catch: (cause) => isCapacityRefusal(cause) ? InteractiveBrowserCapacityError.make({
|
|
1134
1283
|
implementation: browserRunInteractiveImplementation,
|
|
1135
1284
|
message: "Browser Run has no capacity for a new browser session"
|
|
@@ -1137,11 +1286,11 @@ const makeHostService = (binding) => {
|
|
|
1137
1286
|
}).pipe(Effect.flatMap(Schema.decodeUnknownEffect(BrowserRunSessionId)), Effect.catchTag("SchemaError", () => protocolError("The Browser Run session identity was malformed"))), fixedPolicy, startedAt), (id) => Effect.suspend(() => {
|
|
1138
1287
|
state.closed.value = true;
|
|
1139
1288
|
state.disconnected.value = true;
|
|
1140
|
-
return lifecycle.managedTeardownInstalled ? Effect.void : terminate(Redacted.make(id), []).pipe(Effect.
|
|
1289
|
+
return lifecycle.managedTeardownInstalled ? Effect.void : terminate(Redacted.make(id), []).pipe(Effect.catchCause((cause) => reportBrowserCause("interactive.close", cause).pipe(Effect.andThen(Effect.logWarning("Whole-browser cleanup remains unconfirmed")))));
|
|
1141
1290
|
}), { interruptible: true });
|
|
1142
1291
|
const connect = yield* Effect.cached(Effect.gen(function* () {
|
|
1143
1292
|
const browser = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
|
|
1144
|
-
try: (signal) => closeLateAcquisition(signal, () => binding.connect(sessionIdValue), (acquired) => runCleanup(closeAcquired(acquired))),
|
|
1293
|
+
try: (signal) => observeLate(signal, closeLateAcquisition(signal, () => binding.connect(sessionIdValue), (acquired) => runCleanup(closeAcquired(acquired)))),
|
|
1145
1294
|
catch: (cause) => protocolError("Connecting to the Browser Run session failed", cause)
|
|
1146
1295
|
}), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the local browser connection failed")), { interruptible: true });
|
|
1147
1296
|
closers.push(closeEntry(browser.close, "Closing the interactive browser failed"));
|
|
@@ -1161,12 +1310,18 @@ const makeHostService = (binding) => {
|
|
|
1161
1310
|
return yield* expiredError();
|
|
1162
1311
|
}
|
|
1163
1312
|
const context = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
|
|
1164
|
-
try: (signal) => closeLateAcquisition(signal, browser.createContext, (acquired) =>
|
|
1313
|
+
try: (signal) => observeLate(signal, closeLateAcquisition(signal, browser.createContext, (acquired) => runCleanup(Effect.tryPromise({
|
|
1314
|
+
try: () => acquired.close(),
|
|
1315
|
+
catch: (cause) => actionError("close", cause)
|
|
1316
|
+
})))),
|
|
1165
1317
|
catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser context failed", cause)
|
|
1166
1318
|
}), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser context failed")), { interruptible: true });
|
|
1167
1319
|
closers.push(closeEntry(context.close, "Closing the interactive browser context failed"));
|
|
1168
1320
|
const page = yield* Effect.acquireRelease(withinDeadline(Effect.tryPromise({
|
|
1169
|
-
try: (signal) => closeLateAcquisition(signal, context.newPage, (acquired) =>
|
|
1321
|
+
try: (signal) => observeLate(signal, closeLateAcquisition(signal, context.newPage, (acquired) => runCleanup(Effect.tryPromise({
|
|
1322
|
+
try: () => acquired.close(),
|
|
1323
|
+
catch: (cause) => actionError("close", cause)
|
|
1324
|
+
})))),
|
|
1170
1325
|
catch: (cause) => state.disconnected.value || isRemoteClosure(cause) ? expiredError() : protocolError("Creating the browser page failed", cause)
|
|
1171
1326
|
}), fixedPolicy, startedAt), (acquired) => releaseBeforeManaged(closeEntry(acquired.close, "Closing the interactive browser page failed")), { interruptible: true });
|
|
1172
1327
|
closers.push(closeEntry(page.close, "Closing the interactive browser page failed"));
|
|
@@ -1188,12 +1343,12 @@ const makeHostService = (binding) => {
|
|
|
1188
1343
|
const setupFailure = stateFailure(state);
|
|
1189
1344
|
if (setupFailure !== void 0) return yield* setupFailure;
|
|
1190
1345
|
const teardown = yield* Effect.uninterruptible(Effect.gen(function* () {
|
|
1191
|
-
const cached = yield* Effect.cached(terminate(Redacted.make(sessionIdValue), closers));
|
|
1346
|
+
const cached = yield* Effect.cached(terminate(Redacted.make(sessionIdValue), closers).pipe(Effect.tapCause((cause) => reportBrowserCause("interactive.close", cause)), Effect.mapError(reportedBrowserError)));
|
|
1192
1347
|
lifecycle.managedTeardownInstalled = true;
|
|
1193
1348
|
yield* Effect.addFinalizer(() => Effect.uninterruptible(Effect.sync(() => {
|
|
1194
1349
|
state.closed.value = true;
|
|
1195
1350
|
state.disconnected.value = true;
|
|
1196
|
-
}).pipe(Effect.andThen(cached), Effect.
|
|
1351
|
+
}).pipe(Effect.andThen(cached), Effect.catchCause((cause) => reportBrowserCause("interactive.close", cause).pipe(Effect.andThen(Effect.logWarning("Whole-browser cleanup remains unconfirmed")))))));
|
|
1197
1352
|
return cached;
|
|
1198
1353
|
}));
|
|
1199
1354
|
const close = Effect.uninterruptible(Effect.sync(() => {
|
|
@@ -1267,6 +1422,6 @@ const CloudflareInteractiveBrowser = {
|
|
|
1267
1422
|
hostLayer: (options) => browserRunInteractiveHostLayer().pipe(Layer.provide(interactiveBindingLayer(options)))
|
|
1268
1423
|
};
|
|
1269
1424
|
//#endregion
|
|
1270
|
-
export { BrowserRunInteractiveHost as a, BrowserRunViewport as c, browserRunInteractiveImplementation as d, browserRunInteractiveLayer as f, BrowserRunSessionLifecycle as h, BrowserRunInteractiveBinding as i, CloudflareInteractiveBrowser as l, BrowserRunCleanupError as m, BrowserRunHandoffResult as n, BrowserRunLiveViewRequest as o, isBrowserRunUndispatchedActionError as p, BrowserRunHandoffState as r, BrowserRunLiveViewResult as s, BrowserRunHandoffRequest as t, browserRunInteractiveHostLayer as u };
|
|
1425
|
+
export { BrowserRunFailure as _, BrowserRunInteractiveHost as a, reportBrowserCause as b, BrowserRunViewport as c, browserRunInteractiveImplementation as d, browserRunInteractiveLayer as f, BrowserRunBinding as g, BrowserRunSessionLifecycle as h, BrowserRunInteractiveBinding as i, CloudflareInteractiveBrowser as l, BrowserRunCleanupError as m, BrowserRunHandoffResult as n, BrowserRunLiveViewRequest as o, isBrowserRunUndispatchedActionError as p, BrowserRunHandoffState as r, BrowserRunLiveViewResult as s, BrowserRunHandoffRequest as t, browserRunInteractiveHostLayer as u, browserFailure as v, reportedBrowserError as x, inheritBrowserReport as y };
|
|
1271
1426
|
|
|
1272
|
-
//# sourceMappingURL=InteractiveBrowser-
|
|
1427
|
+
//# sourceMappingURL=InteractiveBrowser-l6J4eP6T.mjs.map
|