effect-browser 0.3.0-beta.19 → 0.3.0-beta.21
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/README.md +94 -3
- package/dist/Browser-CiXHT1yO.d.mts +129 -0
- package/dist/{Browser-H63wiekr.mjs → Browser-CxXUjxOp.mjs} +10 -19
- package/dist/Browser-CxXUjxOp.mjs.map +1 -0
- package/dist/Browser.d.mts +2 -129
- package/dist/Browser.mjs +1 -1
- package/dist/Cdp-CzCRnMlM.d.mts +10 -0
- package/dist/Cdp.d.mts +5 -26
- package/dist/Cdp.mjs +4 -45
- package/dist/Cdp.mjs.map +1 -1
- package/dist/Chromium.d.mts +1 -1
- package/dist/Chromium.mjs +3 -3
- package/dist/Chromium.mjs.map +1 -1
- package/dist/Expect-u3P_ENLX.d.mts +62 -0
- package/dist/Expect.d.mts +2 -62
- package/dist/Expect.mjs +2 -2
- package/dist/LICENSE-jpeg-js +28 -0
- package/dist/Moment.mjs +1 -1
- package/dist/Page-BP02bmNv.mjs +264 -0
- package/dist/{Page-CfB6Zn1p.mjs.map → Page-BP02bmNv.mjs.map} +1 -1
- package/dist/Page.mjs +1 -1
- package/dist/{Plan-C-d5QYS8.mjs → Plan-BG1WifW2.mjs} +48 -4
- package/dist/Plan-BG1WifW2.mjs.map +1 -0
- package/dist/Plan.mjs +1 -1
- package/dist/Policy-BGWjbqCl.d.mts +76 -0
- package/dist/Policy.d.mts +2 -76
- package/dist/Policy.mjs +1 -1
- package/dist/Presentation-DxVikn9_.d.mts +48 -0
- package/dist/Presentation.d.mts +2 -48
- package/dist/Presentation.mjs +2 -2
- package/dist/Stage-NHp8N81k.d.mts +65 -0
- package/dist/Stage.d.mts +2 -65
- package/dist/Stage.mjs +2 -2
- package/dist/{Supervisor-mVPeEUp8.d.mts → Supervisor-CfRxbaso.d.mts} +2 -2
- package/dist/Supervisor.d.mts +1 -1
- package/dist/cdp-BMpYMWYe.mjs +69 -0
- package/dist/cdp-BMpYMWYe.mjs.map +1 -0
- package/dist/cdp-DL7XfEj5.d.mts +41 -0
- package/dist/{context-w3NJPRLo.mjs → context-EGhOqjNN.mjs} +5 -5
- package/dist/context-EGhOqjNN.mjs.map +1 -0
- package/dist/index.d.mts +7 -6
- package/dist/index.mjs +4 -3
- package/dist/page-PTM8m5wC.mjs +4057 -0
- package/dist/page-PTM8m5wC.mjs.map +1 -0
- package/dist/{url-Cd04Okid.mjs → url-Bsp2y55M.mjs} +2 -2
- package/dist/{url-Cd04Okid.mjs.map → url-Bsp2y55M.mjs.map} +1 -1
- package/dist/workerd/Cdp.d.mts +3 -0
- package/dist/workerd/Cdp.mjs +18 -0
- package/dist/workerd/Cdp.mjs.map +1 -0
- package/dist/workerd/index.d.mts +16 -0
- package/dist/workerd/index.mjs +17 -0
- package/package.json +15 -4
- package/src/Browser.ts +20 -30
- package/src/Cdp.ts +7 -92
- package/src/index.ts +1 -15
- package/src/internal/cdp.ts +134 -0
- package/src/internal/page/bridge.ts +2 -2
- package/src/internal/page/context.ts +21 -24
- package/src/internal/page/identity.ts +6 -25
- package/src/internal/pictures/motion.ts +3 -3
- package/src/workerd/Cdp.ts +11 -0
- package/src/workerd/index.ts +17 -0
- package/dist/Browser-H63wiekr.mjs.map +0 -1
- package/dist/Page-CfB6Zn1p.mjs +0 -610
- package/dist/Plan-C-d5QYS8.mjs.map +0 -1
- package/dist/context-w3NJPRLo.mjs.map +0 -1
- package/dist/match.inpage-xOe9LNO0.mjs +0 -48
- package/dist/match.inpage-xOe9LNO0.mjs.map +0 -1
- package/dist/page-BKwfF6z-.mjs +0 -5099
- package/dist/page-BKwfF6z-.mjs.map +0 -1
package/dist/Policy.d.mts
CHANGED
|
@@ -1,76 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { AiError, DecisionModel, LanguageModel } from "effect/ai";
|
|
4
|
-
declare namespace Policy_d_exports {
|
|
5
|
-
export { Judge, Judgement, Options, Risk, Task, decider, escalate, make, reviewer };
|
|
6
|
-
}
|
|
7
|
-
/** What an input means. Only a judge reading the evidence can recognise these. */
|
|
8
|
-
export declare const Risk: Schema.Literals<readonly ["financial", "account", "access", "deletion", "communication", "secret"]>;
|
|
9
|
-
export type Risk = typeof Risk.Type;
|
|
10
|
-
declare const Judgement_base: Schema.Class<Judgement, Schema.Struct<{
|
|
11
|
-
/** For each risk, the probability that the input does it. */
|
|
12
|
-
readonly risks: Schema.Struct<{
|
|
13
|
-
readonly financial: Schema.Finite;
|
|
14
|
-
readonly account: Schema.Finite;
|
|
15
|
-
readonly access: Schema.Finite;
|
|
16
|
-
readonly deletion: Schema.Finite;
|
|
17
|
-
readonly communication: Schema.Finite;
|
|
18
|
-
readonly secret: Schema.Finite;
|
|
19
|
-
}>;
|
|
20
|
-
/** The probability that the user's task asks for what the input does; absent without a task. */
|
|
21
|
-
readonly requested: Schema.optional<Schema.Finite>;
|
|
22
|
-
/** Why, in a sentence, when the judge says. */
|
|
23
|
-
readonly reason: Schema.optional<Schema.String>;
|
|
24
|
-
}>, {}>;
|
|
25
|
-
/** A judge's reading of one input. */
|
|
26
|
-
export declare class Judgement extends Judgement_base {}
|
|
27
|
-
/**
|
|
28
|
-
* The user's task: what authorizes a risky input. `Agent.run` provides its task to every input it
|
|
29
|
-
* makes; provide one around other calls with `Effect.provideService`.
|
|
30
|
-
*/
|
|
31
|
-
export declare const Task: Context.Reference<string | undefined>;
|
|
32
|
-
/** Reads what an input means, with the user's task from `Task`. */
|
|
33
|
-
export type Judge = (request: InputRequest) => Effect.Effect<Judgement, AiError.AiError>;
|
|
34
|
-
/**
|
|
35
|
-
* A judge that asks the `LanguageModel` in context for a structured review. `rules` adds the
|
|
36
|
-
* user's own policy in plain words, such as "Purchases under $20 are fine".
|
|
37
|
-
*/
|
|
38
|
-
export declare const reviewer: (options?: {
|
|
39
|
-
readonly rules?: string | undefined;
|
|
40
|
-
} | undefined) => Effect.Effect<(request: InputRequest) => Effect.Effect<Judgement, AiError.AiError, never>, never, LanguageModel.LanguageModel>;
|
|
41
|
-
/**
|
|
42
|
-
* A judge that answers one probability per risk from the `DecisionModel` in context, all in one
|
|
43
|
-
* call. Jev is one: `TypeSafeDecisionModel.layer({ model: "jev-1.13.0" })` from
|
|
44
|
-
* `@effect/ai-typesafe` provides it.
|
|
45
|
-
*/
|
|
46
|
-
export declare const decider: Effect.Effect<Judge, never, DecisionModel.DecisionModel>;
|
|
47
|
-
/**
|
|
48
|
-
* `first`'s judgement, or `second`'s when `first` is unsure: a risk between 0.2 and 0.8, or a
|
|
49
|
-
* likely risk whose request is. A confident mistake by `first` stands.
|
|
50
|
-
*/
|
|
51
|
-
export declare const escalate: (first: Judge, second: Judge) => Judge;
|
|
52
|
-
export interface Options {
|
|
53
|
-
/** Reads what an input means. Without one, only origins and facts decide. */
|
|
54
|
-
readonly judge?: Judge | undefined;
|
|
55
|
-
/** Risks an input may carry only when the task asks for them. Defaults to all of them. */
|
|
56
|
-
readonly risks?: ReadonlyArray<Risk> | undefined;
|
|
57
|
-
/** Facts that deny an input whatever the task, such as `["upload"]`. Defaults to none. */
|
|
58
|
-
readonly deny?: ReadonlyArray<Fact> | undefined;
|
|
59
|
-
/** Origins input may act on and go to, such as `"https://shop.example"`. Defaults to any. */
|
|
60
|
-
readonly origins?: ReadonlyArray<string> | undefined;
|
|
61
|
-
/** The probability from which a judge's reading counts. Defaults to 0.5. */
|
|
62
|
-
readonly threshold?: number | undefined;
|
|
63
|
-
/** How long the judge may take before the input counts as unjudged. Defaults to 30 seconds. */
|
|
64
|
-
readonly timeout?: Duration.Input | undefined;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* A guard for a browser with nobody to ask. It allows hovering and scrolling. Otherwise it denies
|
|
68
|
-
* input on a page or towards a destination outside `origins`, input with a fact in `deny`, and,
|
|
69
|
-
* when a judge finds a risk, input the task does not ask for. An input the judge could not judge
|
|
70
|
-
* in time is denied when it has any fact, with the judge's failure as the denial's cause, and
|
|
71
|
-
* allowed when structure shows nothing.
|
|
72
|
-
*/
|
|
73
|
-
export declare const make: (options?: Options) => InputGuard;
|
|
74
|
-
//#endregion
|
|
75
|
-
export { Policy_d_exports as t };
|
|
76
|
-
//# sourceMappingURL=Policy.d.mts.map
|
|
1
|
+
import { a as Risk, c as escalate, l as make, n as Judgement, o as Task, r as Options, s as decider, t as Judge, u as reviewer } from "./Policy-BGWjbqCl.mjs";
|
|
2
|
+
export { Judge, Judgement, Options, Risk, Task, decider, escalate, make, reviewer };
|
package/dist/Policy.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { PolicyDenied } from "./BrowserError.mjs";
|
|
3
|
-
import { i as InputRequest, n as Fact } from "./Page-
|
|
3
|
+
import { i as InputRequest, n as Fact } from "./Page-BP02bmNv.mjs";
|
|
4
4
|
import { Cause, Context, Duration, Effect, Record, Result, Schema } from "effect";
|
|
5
5
|
import { Decision, DecisionModel, LanguageModel, Prompt } from "effect/ai";
|
|
6
6
|
//#region src/Policy.ts
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { b as Target, u as Page } from "./Page-ku6j5t-v.mjs";
|
|
2
|
+
import { a as Service, t as Motion_d_exports } from "./Motion-DND6I-64.mjs";
|
|
3
|
+
import { Duration, Effect } from "effect";
|
|
4
|
+
declare namespace Presentation_d_exports {
|
|
5
|
+
export { Options, Pacing, Presenter, View, human, make };
|
|
6
|
+
}
|
|
7
|
+
/** How long a person waits before acting, and how fast they type. */
|
|
8
|
+
interface Pacing {
|
|
9
|
+
/** The usual wait before an action that follows an expected change, as the next field of a form. */
|
|
10
|
+
readonly expected: Duration.Input;
|
|
11
|
+
/** The usual wait after the page moved to a new document. */
|
|
12
|
+
readonly surprise: Duration.Input;
|
|
13
|
+
/** The usual wait before a page's first action, or one after an action on another page. */
|
|
14
|
+
readonly unrelated: Duration.Input;
|
|
15
|
+
/** Typing speed, a word being five characters. */
|
|
16
|
+
readonly wordsPerMinute: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The research's medians: 280 ms to react to an expected change, 600 ms to a surprise and 1 second
|
|
20
|
+
* between unrelated actions, each drawn around its median, and typing at 70 words per minute.
|
|
21
|
+
*/
|
|
22
|
+
declare const human: Pacing;
|
|
23
|
+
interface Options {
|
|
24
|
+
/** Defaults to `human`. */
|
|
25
|
+
readonly pacing?: Pacing | undefined;
|
|
26
|
+
/** The pointer's paths. Defaults to `Motion.lognormal`. */
|
|
27
|
+
readonly motion?: Service | undefined;
|
|
28
|
+
}
|
|
29
|
+
/** A page whose actions are performed, which can also start the pointer toward a target early. */
|
|
30
|
+
interface View extends Page {
|
|
31
|
+
/**
|
|
32
|
+
* Start the glide toward `target` as soon as it is known, as in a model's streamed tool call. The
|
|
33
|
+
* next action waits for it when it acts on the same target, and otherwise stops it where it is.
|
|
34
|
+
* An aim presses nothing and records no action; under an input guard it does nothing.
|
|
35
|
+
*/
|
|
36
|
+
readonly aim: (target: Target) => Effect.Effect<void>;
|
|
37
|
+
}
|
|
38
|
+
interface Presenter {
|
|
39
|
+
/** `page`, a page a `Browser` opened, with its actions performed: the same view for the same page. */
|
|
40
|
+
readonly view: (page: Page) => View;
|
|
41
|
+
}
|
|
42
|
+
/** A presenter, for the scope: its pointer, its pace and the aims it has started. */
|
|
43
|
+
declare const make: (options?: Options | undefined) => Effect.Effect<{
|
|
44
|
+
view: (page: Page) => View;
|
|
45
|
+
}, never, import("effect/Scope").Scope>;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { View as a, Presenter as i, Pacing as n, human as o, Presentation_d_exports as r, make as s, Options as t };
|
|
48
|
+
//# sourceMappingURL=Presentation-DxVikn9_.d.mts.map
|
package/dist/Presentation.d.mts
CHANGED
|
@@ -1,48 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { Duration, Effect } from "effect";
|
|
4
|
-
declare namespace Presentation_d_exports {
|
|
5
|
-
export { Options, Pacing, Presenter, View, human, make };
|
|
6
|
-
}
|
|
7
|
-
/** How long a person waits before acting, and how fast they type. */
|
|
8
|
-
export interface Pacing {
|
|
9
|
-
/** The usual wait before an action that follows an expected change, as the next field of a form. */
|
|
10
|
-
readonly expected: Duration.Input;
|
|
11
|
-
/** The usual wait after the page moved to a new document. */
|
|
12
|
-
readonly surprise: Duration.Input;
|
|
13
|
-
/** The usual wait before a page's first action, or one after an action on another page. */
|
|
14
|
-
readonly unrelated: Duration.Input;
|
|
15
|
-
/** Typing speed, a word being five characters. */
|
|
16
|
-
readonly wordsPerMinute: number;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* The research's medians: 280 ms to react to an expected change, 600 ms to a surprise and 1 second
|
|
20
|
-
* between unrelated actions, each drawn around its median, and typing at 70 words per minute.
|
|
21
|
-
*/
|
|
22
|
-
export declare const human: Pacing;
|
|
23
|
-
export interface Options {
|
|
24
|
-
/** Defaults to `human`. */
|
|
25
|
-
readonly pacing?: Pacing | undefined;
|
|
26
|
-
/** The pointer's paths. Defaults to `Motion.lognormal`. */
|
|
27
|
-
readonly motion?: Service | undefined;
|
|
28
|
-
}
|
|
29
|
-
/** A page whose actions are performed, which can also start the pointer toward a target early. */
|
|
30
|
-
export interface View extends Page {
|
|
31
|
-
/**
|
|
32
|
-
* Start the glide toward `target` as soon as it is known, as in a model's streamed tool call. The
|
|
33
|
-
* next action waits for it when it acts on the same target, and otherwise stops it where it is.
|
|
34
|
-
* An aim presses nothing and records no action; under an input guard it does nothing.
|
|
35
|
-
*/
|
|
36
|
-
readonly aim: (target: Target) => Effect.Effect<void>;
|
|
37
|
-
}
|
|
38
|
-
export interface Presenter {
|
|
39
|
-
/** `page`, a page a `Browser` opened, with its actions performed: the same view for the same page. */
|
|
40
|
-
readonly view: (page: Page) => View;
|
|
41
|
-
}
|
|
42
|
-
/** A presenter, for the scope: its pointer, its pace and the aims it has started. */
|
|
43
|
-
export declare const make: (options?: Options | undefined) => Effect.Effect<{
|
|
44
|
-
view: (page: Page) => View;
|
|
45
|
-
}, never, import("effect/Scope").Scope>;
|
|
46
|
-
//#endregion
|
|
47
|
-
export { Presentation_d_exports as t };
|
|
48
|
-
//# sourceMappingURL=Presentation.d.mts.map
|
|
1
|
+
import { a as View, i as Presenter, n as Pacing, o as human, s as make, t as Options } from "./Presentation-DxVikn9_.mjs";
|
|
2
|
+
export { Options, Pacing, Presenter, View, human, make };
|
package/dist/Presentation.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { lognormal } from "./Motion.mjs";
|
|
3
|
-
import { d as monotonicMillis } from "./context-
|
|
4
|
-
import { a as performed, i as pause, r as viewOf, t as internalsOf } from "./page-
|
|
3
|
+
import { d as monotonicMillis } from "./context-EGhOqjNN.mjs";
|
|
4
|
+
import { a as performed, i as pause, r as viewOf, t as internalsOf } from "./page-PTM8m5wC.mjs";
|
|
5
5
|
import { Clock, Duration, Effect, Fiber, MutableRef, Option, Semaphore } from "effect";
|
|
6
6
|
//#region src/Presentation.ts
|
|
7
7
|
/**
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { t as BrowserError } from "./BrowserError-Coy7EW1N.mjs";
|
|
2
|
+
import { n as CaptureStats, o as ScreencastOptions, r as Frame } from "./Frame-DkNdjjjr.mjs";
|
|
3
|
+
import { u as Page } from "./Page-ku6j5t-v.mjs";
|
|
4
|
+
import { Duration, Effect, Option, Schema, Scope, Stream } from "effect";
|
|
5
|
+
declare namespace Stage_d_exports {
|
|
6
|
+
export { Cue, Options, Presented, Shown, Stage, make };
|
|
7
|
+
}
|
|
8
|
+
interface Options extends ScreencastOptions {
|
|
9
|
+
/** Bound for each first-frame wait. Defaults to 5 seconds. */
|
|
10
|
+
readonly firstFrame?: Duration.Input | undefined;
|
|
11
|
+
}
|
|
12
|
+
declare const Presented_base: Schema.Class<Presented, Schema.Struct<{
|
|
13
|
+
readonly page: Schema.String;
|
|
14
|
+
readonly at: Schema.Finite;
|
|
15
|
+
readonly latency: Schema.Finite;
|
|
16
|
+
}>, {}>;
|
|
17
|
+
/** A switch that took effect, on the clock shared by browser events and frames. */
|
|
18
|
+
declare class Presented extends Presented_base {}
|
|
19
|
+
interface Cue {
|
|
20
|
+
readonly page: Page;
|
|
21
|
+
/** A frame of the current document, or the capture's failure or first-frame timeout. */
|
|
22
|
+
readonly ready: Effect.Effect<void, BrowserError>;
|
|
23
|
+
/** Commit on the event's host time, or now. Interruption before switching leaves the cue usable. */
|
|
24
|
+
readonly commit: (options?: {
|
|
25
|
+
readonly at?: number | undefined;
|
|
26
|
+
}) => Effect.Effect<Presented, BrowserError>;
|
|
27
|
+
}
|
|
28
|
+
/** What the output establishes at nondecreasing host times; frames retain their capture times. */
|
|
29
|
+
type Shown = {
|
|
30
|
+
readonly _tag: "Painted";
|
|
31
|
+
readonly frame: Frame;
|
|
32
|
+
readonly at: number;
|
|
33
|
+
} | {
|
|
34
|
+
readonly _tag: "Still";
|
|
35
|
+
readonly frame: Frame;
|
|
36
|
+
readonly at: number;
|
|
37
|
+
} | {
|
|
38
|
+
readonly _tag: "Stalled";
|
|
39
|
+
readonly frame: Frame;
|
|
40
|
+
readonly at: number;
|
|
41
|
+
} | {
|
|
42
|
+
readonly _tag: "Gone";
|
|
43
|
+
readonly page: string;
|
|
44
|
+
readonly at: number;
|
|
45
|
+
};
|
|
46
|
+
interface Stage {
|
|
47
|
+
readonly present: (page: Page, options?: {
|
|
48
|
+
readonly at?: number | undefined;
|
|
49
|
+
}) => Effect.Effect<Presented, BrowserError>;
|
|
50
|
+
readonly cue: (page: Page) => Effect.Effect<Cue, BrowserError, Scope.Scope>;
|
|
51
|
+
/** Paint and, after every finite positive hold without paint, current evidence or loss. */
|
|
52
|
+
readonly shown: (options: {
|
|
53
|
+
readonly hold: Duration.Input;
|
|
54
|
+
}) => Stream.Stream<Shown>;
|
|
55
|
+
/** Capture-timed current-page paint; use `shown` for output time. Readers retain 16 frames. */
|
|
56
|
+
readonly frames: Stream.Stream<Frame>;
|
|
57
|
+
readonly current: Effect.Effect<Option.Option<Page>>;
|
|
58
|
+
readonly stats: (options?: {
|
|
59
|
+
readonly window?: Duration.Input | undefined;
|
|
60
|
+
}) => Effect.Effect<Option.Option<CaptureStats>, BrowserError>;
|
|
61
|
+
}
|
|
62
|
+
declare const make: (options?: Options | undefined) => Effect.Effect<Stage, BrowserError, Scope.Scope>;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { Stage as a, Shown as i, Options as n, Stage_d_exports as o, Presented as r, make as s, Cue as t };
|
|
65
|
+
//# sourceMappingURL=Stage-NHp8N81k.d.mts.map
|
package/dist/Stage.d.mts
CHANGED
|
@@ -1,65 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
3
|
-
import { u as Page } from "./Page-ku6j5t-v.mjs";
|
|
4
|
-
import { Duration, Effect, Option, Schema, Scope, Stream } from "effect";
|
|
5
|
-
declare namespace Stage_d_exports {
|
|
6
|
-
export { Cue, Options, Presented, Shown, Stage, make };
|
|
7
|
-
}
|
|
8
|
-
export interface Options extends ScreencastOptions {
|
|
9
|
-
/** Bound for each first-frame wait. Defaults to 5 seconds. */
|
|
10
|
-
readonly firstFrame?: Duration.Input | undefined;
|
|
11
|
-
}
|
|
12
|
-
declare const Presented_base: Schema.Class<Presented, Schema.Struct<{
|
|
13
|
-
readonly page: Schema.String;
|
|
14
|
-
readonly at: Schema.Finite;
|
|
15
|
-
readonly latency: Schema.Finite;
|
|
16
|
-
}>, {}>;
|
|
17
|
-
/** A switch that took effect, on the clock shared by browser events and frames. */
|
|
18
|
-
export declare class Presented extends Presented_base {}
|
|
19
|
-
export interface Cue {
|
|
20
|
-
readonly page: Page;
|
|
21
|
-
/** A frame of the current document, or the capture's failure or first-frame timeout. */
|
|
22
|
-
readonly ready: Effect.Effect<void, BrowserError>;
|
|
23
|
-
/** Commit on the event's host time, or now. Interruption before switching leaves the cue usable. */
|
|
24
|
-
readonly commit: (options?: {
|
|
25
|
-
readonly at?: number | undefined;
|
|
26
|
-
}) => Effect.Effect<Presented, BrowserError>;
|
|
27
|
-
}
|
|
28
|
-
/** What the output establishes at nondecreasing host times; frames retain their capture times. */
|
|
29
|
-
export type Shown = {
|
|
30
|
-
readonly _tag: "Painted";
|
|
31
|
-
readonly frame: Frame;
|
|
32
|
-
readonly at: number;
|
|
33
|
-
} | {
|
|
34
|
-
readonly _tag: "Still";
|
|
35
|
-
readonly frame: Frame;
|
|
36
|
-
readonly at: number;
|
|
37
|
-
} | {
|
|
38
|
-
readonly _tag: "Stalled";
|
|
39
|
-
readonly frame: Frame;
|
|
40
|
-
readonly at: number;
|
|
41
|
-
} | {
|
|
42
|
-
readonly _tag: "Gone";
|
|
43
|
-
readonly page: string;
|
|
44
|
-
readonly at: number;
|
|
45
|
-
};
|
|
46
|
-
export interface Stage {
|
|
47
|
-
readonly present: (page: Page, options?: {
|
|
48
|
-
readonly at?: number | undefined;
|
|
49
|
-
}) => Effect.Effect<Presented, BrowserError>;
|
|
50
|
-
readonly cue: (page: Page) => Effect.Effect<Cue, BrowserError, Scope.Scope>;
|
|
51
|
-
/** Paint and, after every finite positive hold without paint, current evidence or loss. */
|
|
52
|
-
readonly shown: (options: {
|
|
53
|
-
readonly hold: Duration.Input;
|
|
54
|
-
}) => Stream.Stream<Shown>;
|
|
55
|
-
/** Capture-timed current-page paint; use `shown` for output time. Readers retain 16 frames. */
|
|
56
|
-
readonly frames: Stream.Stream<Frame>;
|
|
57
|
-
readonly current: Effect.Effect<Option.Option<Page>>;
|
|
58
|
-
readonly stats: (options?: {
|
|
59
|
-
readonly window?: Duration.Input | undefined;
|
|
60
|
-
}) => Effect.Effect<Option.Option<CaptureStats>, BrowserError>;
|
|
61
|
-
}
|
|
62
|
-
export declare const make: (options?: Options | undefined) => Effect.Effect<Stage, BrowserError, Scope.Scope>;
|
|
63
|
-
//#endregion
|
|
64
|
-
export { Stage_d_exports as t };
|
|
65
|
-
//# sourceMappingURL=Stage.d.mts.map
|
|
1
|
+
import { a as Stage, i as Shown, n as Options, r as Presented, s as make, t as Cue } from "./Stage-NHp8N81k.mjs";
|
|
2
|
+
export { Cue, Options, Presented, Shown, Stage, make };
|
package/dist/Stage.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { Closed, InvalidRequest, Timeout, consequence } from "./BrowserError.mjs";
|
|
3
|
-
import { c as undispatched, d as monotonicMillis, i as failWith, s as refuse } from "./context-
|
|
4
|
-
import { t as internalsOf } from "./page-
|
|
3
|
+
import { c as undispatched, d as monotonicMillis, i as failWith, s as refuse } from "./context-EGhOqjNN.mjs";
|
|
4
|
+
import { t as internalsOf } from "./page-PTM8m5wC.mjs";
|
|
5
5
|
import { Cause, Clock, Deferred, Duration, Effect, Exit, Fiber, Option, PubSub, Result, Schedule, Schema, Scope, Stream } from "effect";
|
|
6
6
|
//#region src/Stage.ts
|
|
7
7
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as Browser_d_exports, s as Service } from "./Browser-CiXHT1yO.mjs";
|
|
2
2
|
import { Cause, Context, Duration, Effect, Schedule, Schema, Scope, Stream } from "effect";
|
|
3
3
|
declare namespace lifecycle_d_exports {
|
|
4
4
|
export { Closed, Command, Down, Drain, Draining, GenerationState, Held, Input, Kept, Live, Lost, Open, Opening, Released, Reopening, Resolution, Settled, State, Step, Unconfirmed, combine, lookup, resolve, start, transition };
|
|
@@ -314,4 +314,4 @@ declare function make<E, R, A = void>(options: Options<E, R, A>): Effect.Effect<
|
|
|
314
314
|
declare function make<E, R>(options: MakeOptions<E, R, never>): Effect.Effect<Supervisor<void>, never, Scope.Scope | Exclude<R, Scope.Scope>>;
|
|
315
315
|
//#endregion
|
|
316
316
|
export { Settled as C, Reopening as S, Kept as _, Options as a, Opening as b, Supervisor as c, UseOptions as d, make as f, GenerationState as g, Draining as h, Opened as i, Supervisor_d_exports as l, Down as m, Generation as n, Releasing as o, Closed as p, Lease as r, Superseded as s, Admission as t, Unavailable as u, Lost as v, Unconfirmed as w, Released as x, Open as y };
|
|
317
|
-
//# sourceMappingURL=Supervisor-
|
|
317
|
+
//# sourceMappingURL=Supervisor-CfRxbaso.d.mts.map
|
package/dist/Supervisor.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as Settled, S as Reopening, _ as Kept, a as Options, b as Opening, c as Supervisor, d as UseOptions, f as make, g as GenerationState, h as Draining, i as Opened, m as Down, n as Generation, o as Releasing, p as Closed, r as Lease, s as Superseded, t as Admission, u as Unavailable, v as Lost, w as Unconfirmed, x as Released, y as Open } from "./Supervisor-
|
|
1
|
+
import { C as Settled, S as Reopening, _ as Kept, a as Options, b as Opening, c as Supervisor, d as UseOptions, f as make, g as GenerationState, h as Draining, i as Opened, m as Down, n as Generation, o as Releasing, p as Closed, r as Lease, s as Superseded, t as Admission, u as Unavailable, v as Lost, w as Unconfirmed, x as Released, y as Open } from "./Supervisor-CfRxbaso.mjs";
|
|
2
2
|
export { Admission, Closed, Down, Draining, Generation, GenerationState, Kept, Lease, Lost, Open, Opened, Opening, Options, Released, Releasing, Reopening, Settled, Superseded, Supervisor, Unavailable, Unconfirmed, UseOptions, make };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { InvalidRequest, Timeout } from "./BrowserError.mjs";
|
|
2
|
+
import { i as make$1, t as Browser } from "./Browser-CxXUjxOp.mjs";
|
|
3
|
+
import { c as undispatched, o as reasonOf } from "./context-EGhOqjNN.mjs";
|
|
4
|
+
import { n as quoted } from "./url-Bsp2y55M.mjs";
|
|
5
|
+
import { Effect, Layer, Redacted } from "effect";
|
|
6
|
+
//#region src/internal/cdp.ts
|
|
7
|
+
/**
|
|
8
|
+
* A browser reached over the Chrome DevTools Protocol: a Chrome started with
|
|
9
|
+
* `--remote-debugging-port`, or any provider that hands out a CDP WebSocket URL.
|
|
10
|
+
*
|
|
11
|
+
* Closing the scope disconnects. It does not close the remote browser; its owner does that.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.3.0
|
|
14
|
+
*/
|
|
15
|
+
/** Runtime facades supply the default transport; the shared lifetime imports no Node transport. */
|
|
16
|
+
const make = (defaultConnect) => {
|
|
17
|
+
const open = Effect.fn("Cdp.open")(function* (options) {
|
|
18
|
+
const endpoint = Redacted.isRedacted(options.endpoint) ? Redacted.value(options.endpoint) : options.endpoint;
|
|
19
|
+
const timeout = options.connectTimeoutMillis ?? 3e4;
|
|
20
|
+
const connector = options.connect ?? defaultConnect;
|
|
21
|
+
const headers = options.headers === void 0 ? void 0 : { ...options.headers };
|
|
22
|
+
const invalid = (detail) => undispatched("connect", new InvalidRequest({ detail }));
|
|
23
|
+
if (!Number.isFinite(timeout) || timeout <= 0) return yield* invalid("connectTimeoutMillis must be finite and greater than zero");
|
|
24
|
+
if (connector === void 0) return yield* invalid("This runtime requires a CDP connect callback");
|
|
25
|
+
const redact = (message) => {
|
|
26
|
+
if (Object.values(headers ?? {}).some((value) => value !== "" && message.includes(value))) return "CDP diagnostic withheld";
|
|
27
|
+
const origins = message.replace(quoted, (url) => {
|
|
28
|
+
const parsed = URL.parse(url);
|
|
29
|
+
return parsed?.host ? `${parsed.protocol}//${parsed.host}` : "<url>";
|
|
30
|
+
});
|
|
31
|
+
return endpoint === "" ? origins : origins.replaceAll(endpoint, "<endpoint>");
|
|
32
|
+
};
|
|
33
|
+
const failed = (cause, timeoutMillis) => undispatched("connect", reasonOf(cause, timeoutMillis, "connection", redact));
|
|
34
|
+
const connected = yield* Effect.acquireRelease(Effect.tryPromise({
|
|
35
|
+
try: (signal) => connector(endpoint, {
|
|
36
|
+
timeout,
|
|
37
|
+
signal,
|
|
38
|
+
...headers === void 0 ? {} : { headers: { ...headers } }
|
|
39
|
+
}).then(async (browser) => {
|
|
40
|
+
if (signal.aborted) await browser.close().catch(() => void 0);
|
|
41
|
+
return browser;
|
|
42
|
+
}),
|
|
43
|
+
catch: (cause) => failed(cause, timeout)
|
|
44
|
+
}).pipe(Effect.timeoutOrElse({
|
|
45
|
+
duration: timeout,
|
|
46
|
+
orElse: () => Effect.fail(undispatched("connect", new Timeout({ millis: timeout })))
|
|
47
|
+
}), Effect.withSpan("Cdp.connect", {}, { captureStackTrace: false })), (browser) => Effect.tryPromise(() => browser.close()).pipe(Effect.ignore), { interruptible: true });
|
|
48
|
+
const context = connected.contexts()[0] ?? (yield* Effect.tryPromise({
|
|
49
|
+
try: () => connected.newContext(),
|
|
50
|
+
catch: (cause) => failed(cause)
|
|
51
|
+
}));
|
|
52
|
+
const { id = "cdp", provider = "cdp", expiresAt, capture } = options;
|
|
53
|
+
return yield* make$1(context, {
|
|
54
|
+
id,
|
|
55
|
+
provider,
|
|
56
|
+
expiresAt,
|
|
57
|
+
capture
|
|
58
|
+
}, options);
|
|
59
|
+
});
|
|
60
|
+
const layer = (options) => Layer.effect(Browser, open(options));
|
|
61
|
+
return {
|
|
62
|
+
open,
|
|
63
|
+
layer
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
export { make as t };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=cdp-BMpYMWYe.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp-BMpYMWYe.mjs","names":["Errors.InvalidRequest","Url.quoted","Errors.Timeout","Browser.make","Browser.Browser"],"sources":["../src/internal/cdp.ts"],"sourcesContent":["/**\n * A browser reached over the Chrome DevTools Protocol: a Chrome started with\n * `--remote-debugging-port`, or any provider that hands out a CDP WebSocket URL.\n *\n * Closing the scope disconnects. It does not close the remote browser; its owner does that.\n *\n * @since 0.3.0\n */\nimport { type DateTime, Effect, Layer, Redacted } from \"effect\";\nimport type { Browser as PlaywrightBrowser } from \"playwright-core\";\n\nimport * as Browser from \"../Browser.ts\";\nimport * as Errors from \"../BrowserError.ts\";\nimport { reasonOf, undispatched } from \"./page/context.ts\";\nimport * as Url from \"./page/url.ts\";\n\n/** The runtime connector receives the bound and cancellation signal owned by the opening scope. */\nexport interface ConnectOptions {\n readonly timeout: number;\n readonly headers?: Readonly<Record<string, string>> | undefined;\n readonly signal: AbortSignal;\n}\n\n/**\n * Return a real Playwright CDP browser whose `close()` disconnects without ending the remote\n * browser. Honor `signal` to cancel work; a browser returned after cancellation is disconnected.\n * The endpoint and headers may contain credentials and must not be logged.\n */\nexport type Connector = (endpoint: string, options: ConnectOptions) => Promise<PlaywrightBrowser>;\n\nexport interface Options extends Browser.Options, Pick<ConnectOptions, \"headers\"> {\n /**\n * `ws://`, `wss://` or `http://` DevTools endpoint. Often a credential, so it may be redacted;\n * connect failures never include its userinfo, path or query.\n */\n readonly endpoint: string | Redacted.Redacted<string>;\n /** Runtime-supplied Playwright connection. Required by the `workerd` entry. */\n readonly connect?: Connector | undefined;\n /** Identifies the session in `Browser.id`. Defaults to `\"cdp\"`. */\n readonly id?: string | undefined;\n readonly provider?: string | undefined;\n /** Bound on connecting. Defaults to 30 seconds. */\n readonly connectTimeoutMillis?: number | undefined;\n /** When the provider ends the session on its own, as a hosted session's timeout does. */\n readonly expiresAt?: DateTime.Utc | undefined;\n /**\n * A connection apart from this one for the pages' screencasts, as a hosted provider supplies.\n * Without one, each page's capture runs on its own session.\n */\n readonly capture?: Browser.CaptureSource | undefined;\n}\n\n/** Runtime facades supply the default transport; the shared lifetime imports no Node transport. */\nexport const make = (defaultConnect?: Connector) => {\n const open = Effect.fn(\"Cdp.open\")(function* (options: Options) {\n const endpoint = Redacted.isRedacted(options.endpoint)\n ? Redacted.value(options.endpoint)\n : options.endpoint;\n\n const timeout = options.connectTimeoutMillis ?? 30_000;\n const connector = options.connect ?? defaultConnect;\n const headers = options.headers === undefined ? undefined : { ...options.headers };\n\n const invalid = (detail: string) =>\n undispatched(\"connect\", new Errors.InvalidRequest({ detail }));\n\n if (!Number.isFinite(timeout) || timeout <= 0)\n return yield* invalid(\"connectTimeoutMillis must be finite and greater than zero\");\n if (connector === undefined)\n return yield* invalid(\"This runtime requires a CDP connect callback\");\n\n // Inspect before URL normalization or truncation. Withhold an echoed diagnostic entirely so\n // overlapping header values cannot leave fragments; other URLs keep only their scheme and host.\n const redact = (message: string) => {\n if (Object.values(headers ?? {}).some((value) => value !== \"\" && message.includes(value)))\n return \"CDP diagnostic withheld\";\n\n const origins = message.replace(Url.quoted, (url) => {\n const parsed = URL.parse(url);\n\n return parsed?.host ? `${parsed.protocol}//${parsed.host}` : \"<url>\";\n });\n\n return endpoint === \"\" ? origins : origins.replaceAll(endpoint, \"<endpoint>\");\n };\n\n const failed = (cause: unknown, timeoutMillis?: number) =>\n undispatched(\"connect\", reasonOf(cause, timeoutMillis, \"connection\", redact));\n\n // The endpoint is often a credential, so the connect span names no part of it.\n const connected = yield* Effect.acquireRelease(\n Effect.tryPromise({\n try: (signal) =>\n connector(endpoint, {\n timeout,\n signal,\n ...(headers === undefined ? {} : { headers: { ...headers } }),\n }).then(async (browser) => {\n // Cancellation can precede a connector that ignores its signal. Its late browser still\n // belongs to this acquisition, so disconnect it before dropping the promise result.\n if (signal.aborted) await browser.close().catch(() => undefined);\n\n return browser;\n }),\n catch: (cause) => failed(cause, timeout),\n }).pipe(\n Effect.timeoutOrElse({\n duration: timeout,\n orElse: () =>\n Effect.fail(undispatched(\"connect\", new Errors.Timeout({ millis: timeout }))),\n }),\n Effect.withSpan(\"Cdp.connect\", {}, { captureStackTrace: false }),\n ),\n (browser) => Effect.tryPromise(() => browser.close()).pipe(Effect.ignore),\n { interruptible: true },\n );\n\n const context =\n connected.contexts()[0] ??\n (yield* Effect.tryPromise({\n try: () => connected.newContext(),\n catch: (cause) => failed(cause),\n }));\n\n const { id = \"cdp\", provider = \"cdp\", expiresAt, capture } = options;\n\n return yield* Browser.make(context, { id, provider, expiresAt, capture }, options);\n });\n\n const layer = (options: Options): Layer.Layer<Browser.Browser, Errors.BrowserError> =>\n Layer.effect(Browser.Browser, open(options));\n\n return { open, layer };\n};\n"],"mappings":";;;;;;;;;;;;;;;AAqDA,MAAa,QAAQ,mBAA+B;CAClD,MAAM,OAAO,OAAO,GAAG,UAAU,CAAC,CAAC,WAAW,SAAkB;EAC9D,MAAM,WAAW,SAAS,WAAW,QAAQ,QAAQ,IACjD,SAAS,MAAM,QAAQ,QAAQ,IAC/B,QAAQ;EAEZ,MAAM,UAAU,QAAQ,wBAAwB;EAChD,MAAM,YAAY,QAAQ,WAAW;EACrC,MAAM,UAAU,QAAQ,YAAY,KAAA,IAAY,KAAA,IAAY,EAAE,GAAG,QAAQ,QAAQ;EAEjF,MAAM,WAAW,WACf,aAAa,WAAW,IAAIA,eAAsB,EAAE,OAAO,CAAC,CAAC;EAE/D,IAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAC1C,OAAO,OAAO,QAAQ,2DAA2D;EACnF,IAAI,cAAc,KAAA,GAChB,OAAO,OAAO,QAAQ,8CAA8C;EAItE,MAAM,UAAU,YAAoB;GAClC,IAAI,OAAO,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,UAAU,UAAU,MAAM,QAAQ,SAAS,KAAK,CAAC,GACtF,OAAO;GAET,MAAM,UAAU,QAAQ,QAAQC,SAAa,QAAQ;IACnD,MAAM,SAAS,IAAI,MAAM,GAAG;IAE5B,OAAO,QAAQ,OAAO,GAAG,OAAO,SAAS,IAAI,OAAO,SAAS;GAC/D,CAAC;GAED,OAAO,aAAa,KAAK,UAAU,QAAQ,WAAW,UAAU,YAAY;EAC9E;EAEA,MAAM,UAAU,OAAgB,kBAC9B,aAAa,WAAW,SAAS,OAAO,eAAe,cAAc,MAAM,CAAC;EAG9E,MAAM,YAAY,OAAO,OAAO,eAC9B,OAAO,WAAW;GAChB,MAAM,WACJ,UAAU,UAAU;IAClB;IACA;IACA,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE;GAC7D,CAAC,CAAC,CAAC,KAAK,OAAO,YAAY;IAGzB,IAAI,OAAO,SAAS,MAAM,QAAQ,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;IAE/D,OAAO;GACT,CAAC;GACH,QAAQ,UAAU,OAAO,OAAO,OAAO;EACzC,CAAC,CAAC,CAAC,KACD,OAAO,cAAc;GACnB,UAAU;GACV,cACE,OAAO,KAAK,aAAa,WAAW,IAAIC,QAAe,EAAE,QAAQ,QAAQ,CAAC,CAAC,CAAC;EAChF,CAAC,GACD,OAAO,SAAS,eAAe,CAAC,GAAG,EAAE,mBAAmB,MAAM,CAAC,CACjE,IACC,YAAY,OAAO,iBAAiB,QAAQ,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM,GACxE,EAAE,eAAe,KAAK,CACxB;EAEA,MAAM,UACJ,UAAU,SAAS,CAAC,CAAC,OACpB,OAAO,OAAO,WAAW;GACxB,WAAW,UAAU,WAAW;GAChC,QAAQ,UAAU,OAAO,KAAK;EAChC,CAAC;EAEH,MAAM,EAAE,KAAK,OAAO,WAAW,OAAO,WAAW,YAAY;EAE7D,OAAO,OAAOC,OAAa,SAAS;GAAE;GAAI;GAAU;GAAW;EAAQ,GAAG,OAAO;CACnF,CAAC;CAED,MAAM,SAAS,YACb,MAAM,OAAOC,SAAiB,KAAK,OAAO,CAAC;CAE7C,OAAO;EAAE;EAAM;CAAM;AACvB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import "./BrowserError-Coy7EW1N.mjs";
|
|
2
|
+
import { n as Browser_d_exports, o as Options$1, r as CaptureSource } from "./Browser-CiXHT1yO.mjs";
|
|
3
|
+
import { DateTime, Effect, Layer, Redacted } from "effect";
|
|
4
|
+
import { Browser } from "playwright-core";
|
|
5
|
+
//#region src/internal/cdp.d.ts
|
|
6
|
+
/** The runtime connector receives the bound and cancellation signal owned by the opening scope. */
|
|
7
|
+
interface ConnectOptions {
|
|
8
|
+
readonly timeout: number;
|
|
9
|
+
readonly headers?: Readonly<Record<string, string>> | undefined;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Return a real Playwright CDP browser whose `close()` disconnects without ending the remote
|
|
14
|
+
* browser. Honor `signal` to cancel work; a browser returned after cancellation is disconnected.
|
|
15
|
+
* The endpoint and headers may contain credentials and must not be logged.
|
|
16
|
+
*/
|
|
17
|
+
type Connector = (endpoint: string, options: ConnectOptions) => Promise<Browser>;
|
|
18
|
+
interface Options extends Options$1, Pick<ConnectOptions, "headers"> {
|
|
19
|
+
/**
|
|
20
|
+
* `ws://`, `wss://` or `http://` DevTools endpoint. Often a credential, so it may be redacted;
|
|
21
|
+
* connect failures never include its userinfo, path or query.
|
|
22
|
+
*/
|
|
23
|
+
readonly endpoint: string | Redacted.Redacted<string>;
|
|
24
|
+
/** Runtime-supplied Playwright connection. Required by the `workerd` entry. */
|
|
25
|
+
readonly connect?: Connector | undefined;
|
|
26
|
+
/** Identifies the session in `Browser.id`. Defaults to `"cdp"`. */
|
|
27
|
+
readonly id?: string | undefined;
|
|
28
|
+
readonly provider?: string | undefined;
|
|
29
|
+
/** Bound on connecting. Defaults to 30 seconds. */
|
|
30
|
+
readonly connectTimeoutMillis?: number | undefined;
|
|
31
|
+
/** When the provider ends the session on its own, as a hosted session's timeout does. */
|
|
32
|
+
readonly expiresAt?: DateTime.Utc | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* A connection apart from this one for the pages' screencasts, as a hosted provider supplies.
|
|
35
|
+
* Without one, each page's capture runs on its own session.
|
|
36
|
+
*/
|
|
37
|
+
readonly capture?: CaptureSource | undefined;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Connector as n, Options as r, ConnectOptions as t };
|
|
41
|
+
//# sourceMappingURL=cdp-DL7XfEj5.d.mts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { maximumSamples } from "./Motion.mjs";
|
|
2
2
|
import { BrowserError, Closed, Failed, InvalidRequest, Timeout } from "./BrowserError.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { c as make$2, i as redactWithin } from "./url-Bsp2y55M.mjs";
|
|
4
4
|
import { Clock, Context, Data, Duration, Effect, Fiber, MutableRef, Option, Schema } from "effect";
|
|
5
5
|
var InputFailure = class extends Data.TaggedError("InputFailure") {};
|
|
6
6
|
/** Native page calls join their operation's reply ownership, including script mutations. */
|
|
@@ -204,12 +204,12 @@ const closedPattern = /has been closed|Target closed|Session closed|browser has
|
|
|
204
204
|
* or browser that is gone. A call that gives Playwright a timeout passes the same bound, so its
|
|
205
205
|
* `Timeout` reports it; without one, Playwright's own message stays.
|
|
206
206
|
*/
|
|
207
|
-
const reasonOf = (cause, timeoutMillis, closed = "connection") => {
|
|
207
|
+
const reasonOf = (cause, timeoutMillis, closed = "connection", redact = redactWithin) => {
|
|
208
208
|
const message = messageOf(cause);
|
|
209
209
|
if (closedPattern.test(message)) return new Closed({ cause: closed });
|
|
210
210
|
if (cause instanceof Error && cause.name === "TimeoutError" && timeoutMillis !== void 0) return new Timeout({ millis: timeoutMillis });
|
|
211
|
-
const line = message.split("\n")[0] ?? message;
|
|
212
|
-
return new Failed({ detail:
|
|
211
|
+
const line = redact(message).split("\n")[0] ?? message;
|
|
212
|
+
return new Failed({ detail: line.replace(/^[\w.]+: /, "") });
|
|
213
213
|
};
|
|
214
214
|
/**
|
|
215
215
|
* One Playwright or protocol call, failing undispatched. A closed page says why it is gone as the
|
|
@@ -332,4 +332,4 @@ const make = (options, scope) => {
|
|
|
332
332
|
//#endregion
|
|
333
333
|
export { make as a, undispatched as c, monotonicMillis as d, toBrowserSeconds as f, make$1 as g, Current as h, failWith as i, estimate as l, uncertaintyAt as m, contextGone as n, reasonOf as o, toHostTime as p, decodeWith as r, refuse as s, call as t, mapping as u };
|
|
334
334
|
|
|
335
|
-
//# sourceMappingURL=context-
|
|
335
|
+
//# sourceMappingURL=context-EGhOqjNN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-EGhOqjNN.mjs","names":["make","Url.redactWithin","Errors.Closed","Errors.Timeout","Errors.Failed","Errors.BrowserError","Errors.InvalidRequest","BrowserClock.monotonicMillis","Lane.make"],"sources":["../src/internal/input/replies.ts","../src/internal/pictures/clock.ts","../src/internal/page/context.ts"],"sourcesContent":["/**\n * Bounded input replies owned by the page, including after an action is interrupted.\n * Canceling a caller cannot cancel a protocol command already sent. The next action waits for\n * those replies, while a stopped run releases only held keys or buttons whose release was never submitted.\n */\nimport { Context, Data, Effect, type Scope } from \"effect\";\n\nimport { maximumSamples } from \"../../Motion.ts\";\n\nexport const capacity = 64;\n\nexport class InputFailure extends Data.TaggedError(\"InputFailure\")<{\n readonly cause: unknown;\n}> {}\n\nexport interface Run {\n /** A native call made by this operation: cancellation cannot cancel its actual reply. */\n readonly track: <A>(reply: Promise<A>) => Promise<A>;\n /** End ownership after the record and all this operation's native replies have settled. */\n readonly afterIdle: (ended: () => void) => void;\n /** Retain authority through scoped cleanup after the replies already submitted. */\n readonly recover: (cleanup: Effect.Effect<void>, scope: Scope.Scope) => Effect.Effect<void>;\n /** Reserve a complete stroke, including its releases, before sending its first event. */\n readonly reserve: (commands: number) => Effect.Effect<void, InputFailure>;\n /** Admit every sample before a motion starts its published clock; ordinary input stays bounded separately. */\n readonly reserveMotion: (commands: number) => Effect.Effect<void, InputFailure>;\n readonly send: (command: () => Promise<unknown>) => Effect.Effect<void, InputFailure>;\n readonly down: (\n key: string,\n press: () => Promise<unknown>,\n release: () => Promise<unknown>,\n ) => Effect.Effect<void, InputFailure>;\n readonly up: (key: string) => Effect.Effect<void, InputFailure>;\n readonly drain: Effect.Effect<void, InputFailure>;\n /** Stop future input and submit missing releases without waiting indefinitely for replies. */\n readonly close: Effect.Effect<void>;\n}\n\n/** Native page calls join their operation's reply ownership, including script mutations. */\nexport const Current = Context.Reference<Run | undefined>(\"effect-browser/internal/input/Current\", {\n defaultValue: () => undefined,\n});\n\nexport const make = () => {\n const outstanding = new Set<Promise<void>>();\n\n // A timed-out action keeps capacity until its real replies arrive. Waiting for them sends\n // nothing, so cancellation here cannot leave a detached continuation that later types.\n const idle = Effect.gen(function* () {\n while (outstanding.size > 0) yield* Effect.promise(() => Promise.all(outstanding));\n });\n\n const begin = Effect.gen(function* () {\n yield* idle;\n const pending = new Set<Promise<void>>();\n const held: Array<{ readonly key: string; readonly release: () => Promise<unknown> }> = [];\n let failure: InputFailure | undefined;\n let reserved = 0;\n let closed = false;\n const observed = new WeakMap<Promise<unknown>, { input: boolean }>();\n const endings = new Set<() => void>();\n\n const track = <A>(response: Promise<A>, input = false): Promise<A> => {\n const existing = observed.get(response);\n\n if (existing !== undefined) {\n existing.input ||= input;\n\n return response;\n }\n const entry = { input };\n\n observed.set(response, entry);\n\n const reply = response\n .then(\n () => undefined,\n (cause: unknown) => {\n if (entry.input) failure ??= new InputFailure({ cause });\n },\n )\n .then(() => {\n pending.delete(reply);\n outstanding.delete(reply);\n if (pending.size === 0) {\n for (const end of endings) end();\n endings.clear();\n }\n });\n\n pending.add(reply);\n outstanding.add(reply);\n\n return response;\n };\n\n const requireOpen = Effect.suspend(() =>\n closed\n ? Effect.fail(new InputFailure({ cause: new Error(\"the input run has stopped\") }))\n : Effect.void,\n );\n\n const requireSuccess = Effect.suspend(() =>\n failure === undefined ? Effect.void : Effect.fail(failure),\n );\n\n const submit = (command: () => Promise<unknown>) => {\n if (reserved < 1) throw new Error(\"input must reserve capacity before dispatch\");\n reserved--;\n try {\n void track(command(), true);\n } catch (cause) {\n failure ??= new InputFailure({ cause });\n }\n };\n\n const reserve = (commands: number, maximum: number, limit: number) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n if (!Number.isInteger(commands) || commands < 1 || commands > maximum)\n return yield* Effect.die(new Error(\"invalid input reservation\"));\n while (outstanding.size + reserved + commands > limit) {\n yield* Effect.promise(() => Promise.race(outstanding));\n yield* requireOpen;\n yield* requireSuccess;\n }\n reserved += commands;\n });\n\n const run: Run = {\n track,\n afterIdle: (end) => {\n if (pending.size === 0) end();\n else endings.add(end);\n },\n recover: (cleanup, scope) =>\n Effect.gen(function* () {\n const replies = [...pending];\n const done = Promise.withResolvers<void>();\n\n // This reservation prevents a new action or suspension from overtaking cleanup.\n void track(done.promise);\n yield* Effect.promise(() => Promise.all(replies)).pipe(\n Effect.andThen(cleanup),\n Effect.ensuring(Effect.sync(() => done.resolve())),\n Effect.provideService(Current, run),\n Effect.interruptible,\n Effect.forkIn(scope),\n );\n }),\n reserve: (commands) => reserve(commands, capacity, capacity),\n // A dense stroke cannot wait for replies midway without changing its published timing.\n // Its finite reservation also leaves room for the ordinary pool's already-owned releases.\n reserveMotion: (commands) => reserve(commands, maximumSamples, capacity + maximumSamples),\n send: (command) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n yield* Effect.sync(() => submit(command));\n yield* requireSuccess;\n }),\n down: (key, press, release) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* requireSuccess;\n yield* Effect.sync(() => {\n held.push({ key, release });\n submit(press);\n });\n yield* requireSuccess;\n }),\n up: (key) =>\n Effect.gen(function* () {\n yield* requireOpen;\n yield* Effect.sync(() => {\n const index = held.findLastIndex((entry) => entry.key === key);\n const entry = held[index];\n\n if (entry === undefined) return;\n // Submission owns the release, even if its reply fails. Retrying an uncertain\n // release could run page handlers twice, so cleanup never sends it again.\n held.splice(index, 1);\n submit(entry.release);\n });\n yield* requireSuccess;\n }),\n drain: Effect.gen(function* () {\n while (pending.size > 0) yield* Effect.promise(() => Promise.all(pending));\n yield* requireSuccess;\n }),\n close: Effect.sync(() => {\n if (closed) return;\n closed = true;\n for (const entry of held.toReversed()) submit(entry.release);\n held.length = 0;\n reserved = 0;\n }),\n };\n\n return run;\n });\n\n /** `idle` lets an action wait, in its page's turn, for the page's earlier replies. */\n return { idle, begin };\n};\n","/**\n * Host monotonic milliseconds and the browser's clock read on the owner's: estimates of their\n * offset from timed probes, how an estimate ages, and the mapping a browser's pages share.\n * `pictures.ts` takes the probes.\n */\nimport { type Clock, Duration, Effect, Option } from \"effect\";\n\n/** Read the captured owner's clock, including from native callbacks, without changing its origin. */\nexport const monotonicMillis = (clock: Clock.Clock): number =>\n Number(clock.monotonicTimeNanosUnsafe()) / 1e6;\n\nexport interface Probe {\n readonly hostStart: number;\n readonly hostEnd: number;\n readonly browserTime: number;\n}\n\nexport interface Estimate {\n /** Browser epoch milliseconds minus the owner's host monotonic milliseconds. */\n readonly offsetMillis: number;\n /** Either transport direction can own the entire round trip; symmetry is not assumed. */\n readonly uncertaintyMillis: number;\n readonly roundTripMillis: number;\n readonly sampledAt: number;\n}\n\n/** The fastest complete probe limits uncertainty without mistaking transit delay for clock offset. */\nexport const estimate = (probes: ReadonlyArray<Probe>): Option.Option<Estimate> => {\n let best: Estimate | undefined;\n\n for (const probe of probes) {\n const roundTripMillis = probe.hostEnd - probe.hostStart;\n\n if (\n !Number.isFinite(probe.hostStart) ||\n !Number.isFinite(probe.hostEnd) ||\n !Number.isFinite(probe.browserTime) ||\n !Number.isFinite(roundTripMillis) ||\n roundTripMillis < 0\n )\n continue;\n const sampledAt = probe.hostStart + roundTripMillis / 2;\n const offsetMillis = probe.browserTime - sampledAt;\n\n if (\n !Number.isFinite(offsetMillis) ||\n !Number.isFinite(probe.browserTime - probe.hostStart) ||\n !Number.isFinite(probe.browserTime - probe.hostEnd)\n )\n continue;\n if (best === undefined || roundTripMillis < best.roundTripMillis)\n best = {\n offsetMillis,\n uncertaintyMillis: roundTripMillis / 2,\n roundTripMillis,\n sampledAt,\n };\n }\n\n return Option.fromUndefinedOr(best);\n};\n\n// Two machines' clocks drift apart by up to about 100 parts per million, so an estimate says this\n// much less about the offset for each millisecond of its age.\nconst driftPerMillis = 1e-4;\n\n/** An estimate's uncertainty at `hostTime`, wider the further that is from when it was sampled. */\nexport const uncertaintyAt = (estimate: Estimate, hostTime: number): number =>\n estimate.uncertaintyMillis + Math.abs(hostTime - estimate.sampledAt) * driftPerMillis;\n\n// Ten seconds widen an estimate by a millisecond, far less than a remote round trip, so it is\n// measured again no more often than this.\nconst renewAfter = Duration.seconds(10);\n\n/**\n * The browser's one epoch mapping, shared by its pages, input runs and capture generations. It is\n * measured on first need, by the first capture, never ahead of it.\n */\nexport interface Mapping {\n /** The latest estimate, without measuring: input uses it, and never waits for one. */\n readonly latest: () => Estimate | undefined;\n /** The latest estimate, measured through `measure` only while the browser has none. */\n readonly current: <E>(measure: Effect.Effect<Estimate, E>) => Effect.Effect<Estimate, E>;\n /**\n * Measure again once ten seconds have passed since the latest measurement began. A failed\n * measurement keeps the estimate, which keeps widening with its age.\n */\n readonly renew: <E>(measure: Effect.Effect<Estimate, E>) => Effect.Effect<void>;\n}\n\n/**\n * Whether a new measurement should replace the current estimate. Each interval contains the true\n * offset, so overlapping intervals agree and the narrower one is kept, the current one widened by\n * its age: a probe delayed behind a busy page cannot widen every tab's stamps. A disjoint\n * measurement means the clocks moved (a wall clock step, or drift between a remote browser and\n * this host), so the newer evidence wins.\n */\nexport const supersedes = (next: Estimate, current: Estimate): boolean => {\n const aged = uncertaintyAt(current, next.sampledAt);\n\n return (\n next.uncertaintyMillis <= aged ||\n Math.abs(next.offsetMillis - current.offsetMillis) > next.uncertaintyMillis + aged\n );\n};\n\n/**\n * Every renderer of a browser reads the same host wall clock, so the offset belongs to the\n * browser rather than a page. A busy page cannot fail work that an earlier estimate can serve.\n */\nexport const mapping = (now: () => number): Mapping => {\n let latest: Estimate | undefined;\n let measuredAt = Number.NEGATIVE_INFINITY;\n\n // Called where a measurement is decided, so no other can be decided before this one begins.\n const adopt = <E>(measure: Effect.Effect<Estimate, E>) => {\n measuredAt = now();\n\n return measure.pipe(\n Effect.map((estimate) => {\n if (latest === undefined || supersedes(estimate, latest)) latest = estimate;\n\n return latest;\n }),\n );\n };\n\n return {\n latest: () => latest,\n current: (measure) =>\n Effect.suspend(() => (latest === undefined ? adopt(measure) : Effect.succeed(latest))),\n renew: (measure) =>\n Effect.suspend(() =>\n latest === undefined || now() - measuredAt < Duration.toMillis(renewAfter)\n ? Effect.void\n : Effect.ignore(adopt(measure)),\n ),\n };\n};\n\nexport const toHostTime = (calibration: Estimate, browserEpochMillis: number): number =>\n browserEpochMillis - calibration.offsetMillis;\n\n/** CDP input timestamps use seconds, unlike browser frame timestamps and the owner's clock. */\nexport const toBrowserSeconds = (calibration: Estimate, hostMillis: number): number =>\n (hostMillis + calibration.offsetMillis) / 1000;\n","/**\n * What a page's parts share: the browser state they act on, the page's own lane, pointer and\n * clock, and how they call the browser and report its failures. The assembly in `page.ts` builds\n * one context per page.\n */\nimport {\n Clock,\n Context,\n Duration,\n Effect,\n Fiber,\n MutableRef,\n Option,\n Schema,\n type Scope,\n} from \"effect\";\nimport type { CDPSession, Page as PlaywrightPage } from \"playwright-core\";\n\nimport type { CaptureSource } from \"../../Browser.ts\";\nimport * as Errors from \"../../BrowserError.ts\";\nimport type { BrowserEvent } from \"../../BrowserEvent.ts\";\nimport type { InputGuard, Point } from \"../../Page.ts\";\nimport type { Gate } from \"../input/gate.ts\";\nimport { Current } from \"../input/replies.ts\";\nimport * as BrowserClock from \"../pictures/clock.ts\";\nimport * as Lane from \"./lane.ts\";\nimport type { Openings } from \"./openings.ts\";\nimport * as Url from \"./url.ts\";\n\n/** Why a page is gone. */\nexport type ClosedCause = Errors.Closed[\"cause\"];\n\n/** What every page of a browser shares, from its options. */\nexport interface Settings {\n readonly actionTimeout: Duration.Duration;\n readonly policyTimeout: Duration.Duration;\n readonly navigationTimeout: Duration.Duration;\n /** How long screencast frames stay in `recentFrames`, measured back from the newest. */\n readonly frameHistory: Duration.Duration;\n readonly guard: InputGuard | undefined;\n}\n\nexport interface MakeOptions {\n /** The page's CDP target id, which is also its main frame's id. */\n readonly id: string;\n /** The id of the browser's session, which its frames carry. */\n readonly session: string;\n /** This tracking connection, distinct from the provider session and capture socket. */\n readonly connection: string;\n /** The page's address when the browser began tracking it. */\n readonly url: string;\n readonly playwright: PlaywrightPage;\n readonly cdp: CDPSession;\n /** A call's reply, or a failure as for a closed page once the browser is lost first. */\n readonly untilLost: <A>(reply: Promise<A>) => Promise<A>;\n readonly settings: Settings;\n readonly clock: Clock.Clock;\n /** Browser-wide input authority; direct internal page fixtures need not provide one. */\n readonly inputGate?: Gate | undefined;\n /** The browser's epoch mapping: its first capture measures it, and later ones renew it. */\n readonly mapping: BrowserClock.Mapping;\n readonly publish: (event: BrowserEvent) => number;\n /** This page's retained events, oldest first. */\n readonly recentEvents: Effect.Effect<ReadonlyArray<BrowserEvent>>;\n /** Registration of the actual popups this page's current input opened. */\n readonly openings: Openings;\n /** Succeeds once the page's own session holds focus emulation, which keeps it painting behind. */\n readonly focused: Effect.Effect<void, Errors.BrowserError>;\n /** Succeeds once the page's own session has the Page domain on, so it sees every later commit. */\n readonly paging: (operation: string) => Effect.Effect<void, Errors.BrowserError>;\n /** Why the page is gone, once it is: its browser's loss, else its own close or crash. */\n readonly closedBy: () => ClosedCause;\n /** Where the page's screencast runs, if not on its own session. */\n readonly capture?: CaptureSource | undefined;\n}\n\nconst messageOf = (cause: unknown): string =>\n cause instanceof Error ? cause.message : typeof cause === \"string\" ? cause : \"unknown error\";\n\nconst closedPattern =\n /has been closed|Target closed|Session closed|browser has disconnected|Target page, context or browser/i;\n\n/**\n * Map a Playwright or protocol failure to a reason, `Closed` with `closed` as its cause for a page\n * or browser that is gone. A call that gives Playwright a timeout passes the same bound, so its\n * `Timeout` reports it; without one, Playwright's own message stays.\n */\nexport const reasonOf = (\n cause: unknown,\n timeoutMillis?: number,\n closed: ClosedCause = \"connection\",\n redact: (message: string) => string = Url.redactWithin,\n): Errors.Reason => {\n const message = messageOf(cause);\n\n if (closedPattern.test(message)) return new Errors.Closed({ cause: closed });\n if (cause instanceof Error && cause.name === \"TimeoutError\" && timeoutMillis !== undefined)\n return new Errors.Timeout({ millis: timeoutMillis });\n const line = redact(message).split(\"\\n\")[0] ?? message;\n\n return new Errors.Failed({ detail: line.replace(/^[\\w.]+: /, \"\") });\n};\n\n/**\n * One Playwright or protocol call, failing undispatched. A closed page says why it is gone as the\n * browser knows then: the library's own calls fail with the browser's loss, and Playwright fails\n * its calls on a dropped connection after reporting the context closed.\n */\nexport const call = <A>(\n operation: string,\n run: () => Promise<A>,\n closedBy: () => ClosedCause,\n timeoutMillis?: number,\n) =>\n Effect.tryPromise({\n try: run,\n catch: (cause) => undispatched(operation, reasonOf(cause, timeoutMillis, closedBy())),\n });\n\nexport const contextGone = (error: Errors.BrowserError) =>\n error.reason._tag === \"Failed\" &&\n /Cannot find context|Execution context was destroyed|__effectBrowser|Inspected target navigated/i.test(\n error.reason.detail,\n );\n\n/**\n * What a page operation spent on the page's own protocol session: its calls, the bytes of their\n * parameters and results, and how long at least one of them awaited its reply. An operation inside\n * another counts toward both.\n */\ninterface Cost {\n readonly enclosing: Cost | undefined;\n calls: number;\n bytesOut: number;\n bytesIn: number;\n waitedMillis: number;\n awaiting: number;\n awaitingSince: number;\n}\n\n/** The cost of the page operation the current fiber runs, if any. */\nconst CurrentCost = Context.Reference<Cost | undefined>(\n \"effect-browser/internal/page/CurrentCost\",\n {\n defaultValue: () => undefined,\n },\n);\n\n/** Track the promise returned to the action, after tracing wraps it, so input counts once. */\nconst track = <A>(reply: Promise<A>) => Fiber.getCurrent()?.getRef(Current)?.track(reply) ?? reply;\n\n// A message's size on the wire, give or take its envelope.\nconst sizeOf = (value: unknown) =>\n value === undefined ? 0 : Buffer.byteLength(JSON.stringify(value));\n\n/** A failure of `operation` before any of its input reached the browser. */\nexport const undispatched = (operation: string, reason: Errors.Reason) =>\n new Errors.BrowserError({ operation, reason, dispatched: false });\n\nexport const failWith = (operation: string, reason: Errors.Reason) =>\n Effect.fail(undispatched(operation, reason));\n\n/** Refuse a request to `operation` that could never succeed, before sending anything. */\nexport const refuse = (operation: string, detail: string) =>\n failWith(operation, new Errors.InvalidRequest({ detail }));\n\nexport const decodeWith =\n <A>(operation: string, schema: Schema.Codec<A, unknown>) =>\n (value: unknown) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError((error) =>\n undispatched(operation, new Errors.Failed({ detail: error.message })),\n ),\n );\n\nexport const make = (options: MakeOptions, scope: Scope.Scope) => {\n const { id, clock } = options;\n const now = () => BrowserClock.monotonicMillis(clock);\n // Deadlines and pacing guard the page's lane, so page operations run on the owner's clock; a\n // caller's clock, such as a TestClock, cannot stall or stretch them.\n const owned = Effect.provideService(Clock.Clock, clock);\n\n // This page's spans name it and report what the operation cost on the protocol. Fine-grained\n // ones carry a level below the default Info, so an application keeps only the coarse ones by\n // raising `Tracer.MinimumTraceLevel`.\n const span =\n (name: string, attributes: Record<string, unknown> = {}, level?: \"Debug\" | \"Trace\") =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n Effect.gen(function* () {\n const cost: Cost = {\n enclosing: yield* CurrentCost,\n calls: 0,\n bytesOut: 0,\n bytesIn: 0,\n waitedMillis: 0,\n awaiting: 0,\n awaitingSince: 0,\n };\n\n return yield* effect.pipe(\n Effect.provideService(CurrentCost, cost),\n Effect.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n calls: cost.calls,\n bytesOut: cost.bytesOut,\n bytesIn: cost.bytesIn,\n waitedMillis: Math.round(cost.waitedMillis * 10) / 10,\n }),\n ),\n ),\n );\n }).pipe(\n Effect.withSpan(\n name,\n { attributes: { page: id, ...attributes }, ...(level === undefined ? {} : { level }) },\n { captureStackTrace: false },\n ),\n );\n\n // Every call on the page's own protocol session, counted into the operation that sends it and\n // the operations around that one. It is looked up when the call is sent, so input pipelined\n // from inside an operation counts toward it too.\n const send: CDPSession[\"send\"] = (method, params) => {\n const cost = Fiber.getCurrent()?.getRef(CurrentCost);\n const sentAt = now();\n const bytesOut = sizeOf(params);\n\n for (let each = cost; each !== undefined; each = each.enclosing) {\n each.calls++;\n each.bytesOut += bytesOut;\n if (each.awaiting++ === 0) each.awaitingSince = sentAt;\n }\n const reply = options.untilLost(options.cdp.send(method, params));\n\n if (cost === undefined) return track(reply);\n\n const settle = (bytesIn: number) => {\n const at = now();\n\n for (let each: Cost | undefined = cost; each !== undefined; each = each.enclosing) {\n each.bytesIn += bytesIn;\n if (--each.awaiting === 0) each.waitedMillis += at - each.awaitingSince;\n }\n };\n\n return track(\n reply.then(\n (result) => {\n settle(sizeOf(result));\n\n return result;\n },\n (cause: unknown) => {\n settle(0);\n\n return Promise.reject(cause);\n },\n ),\n );\n };\n\n // Every protocol or Playwright call. Errors are undispatched here; `perform` marks them\n // dispatched once input has gone out.\n const native = <A>(operation: string, run: () => Promise<A>, timeoutMillis?: number) =>\n call(operation, () => track(run()), options.closedBy, timeoutMillis);\n\n /** Fail with `Timeout` once `duration` has passed, the action timeout unless another is given. */\n const within =\n (operation: string, duration: Duration.Input = options.settings.actionTimeout) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n Effect.timeoutOrElse(effect, {\n duration,\n orElse: () =>\n failWith(operation, new Errors.Timeout({ millis: Duration.toMillis(duration) })),\n });\n\n // Stop a navigation whose bounded wait failed. The stop and original mutation keep their\n // actual replies owned; this cleanup does not turn an unanswered acknowledgement into success.\n const stopLoading = native(\"stopLoading\", () => send(\"Page.stopLoading\")).pipe(\n within(\"stopLoading\", options.settings.navigationTimeout),\n Effect.ignore,\n );\n\n // The latest submitted input or page change. A read that must follow it waits for the action in\n // flight, so only paint from after its latest input is current. An action ends after its input\n // was handled, so if that input changed the page, newer paint follows; a lost final paint is\n // bounded by recency instead. Paint from before the current document began, when the page's own\n // session saw the main frame commit it, shows a page the tab has left, so no read reuses it,\n // whatever it asks.\n const activity = { inputAt: 0, documentAt: Number.NEGATIVE_INFINITY };\n\n const noteInput = () => {\n activity.inputAt = Math.max(activity.inputAt, now());\n };\n\n const lane = Lane.make({\n now,\n actionTimeout: options.settings.actionTimeout,\n documentAt: () => activity.documentAt,\n gone: (operation) => undispatched(operation, new Errors.Closed({ cause: options.closedBy() })),\n scope,\n inputGate: options.inputGate,\n });\n\n // Where this page's latest move left its pointer, which is where its next plain glide starts and\n // where a held button is released. Its lane orders the page's input, and Chromium keeps a\n // pointer per page too.\n const pointer = MutableRef.make(Option.none<Point>());\n\n // Named, so that the declarations of what holds it need not spell out Playwright's protocol types.\n const protocol: Pick<CDPSession, \"send\"> = { send };\n\n return {\n ...options,\n lane,\n pointer,\n now,\n scope,\n owned,\n span,\n protocol,\n native,\n within,\n stopLoading,\n activity,\n noteInput,\n };\n};\n\nexport type PageContext = ReturnType<typeof make>;\n"],"mappings":"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"}
|