effect-browser 0.2.0-beta.9 → 0.3.0-beta.10
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 +849 -1161
- package/dist/Browser-S4kvpmqa.mjs +605 -0
- package/dist/Browser-S4kvpmqa.mjs.map +1 -0
- package/dist/Browser.d.mts +127 -3
- package/dist/Browser.mjs +2 -22
- package/dist/BrowserError-Coy7EW1N.d.mts +140 -0
- package/dist/BrowserError.d.mts +2 -0
- package/dist/BrowserError.mjs +211 -0
- package/dist/BrowserError.mjs.map +1 -0
- package/dist/BrowserEvent-BRu2juEz.d.mts +279 -0
- package/dist/BrowserEvent.d.mts +2 -0
- package/dist/BrowserEvent.mjs +297 -0
- package/dist/BrowserEvent.mjs.map +1 -0
- package/dist/Cdp.d.mts +32 -0
- package/dist/Cdp.mjs +61 -0
- package/dist/Cdp.mjs.map +1 -0
- package/dist/Change-DNvztNLu.mjs +138 -0
- package/dist/Change-DNvztNLu.mjs.map +1 -0
- package/dist/Change-iMlcuzVD.d.mts +71 -0
- package/dist/Change.d.mts +2 -0
- package/dist/Change.mjs +2 -0
- package/dist/Chromium.d.mts +29 -81
- package/dist/Chromium.mjs +57 -392
- package/dist/Chromium.mjs.map +1 -1
- package/dist/Expect.d.mts +62 -0
- package/dist/Expect.mjs +114 -0
- package/dist/Expect.mjs.map +1 -0
- package/dist/Frame-BERmf_gM.d.mts +117 -0
- package/dist/Frame.d.mts +2 -0
- package/dist/Frame.mjs +123 -0
- package/dist/Frame.mjs.map +1 -0
- package/dist/Moment.d.mts +2 -0
- package/dist/Moment.mjs +288 -0
- package/dist/Moment.mjs.map +1 -0
- package/dist/Motion.d.mts +40 -0
- package/dist/Motion.mjs +122 -0
- package/dist/Motion.mjs.map +1 -0
- package/dist/Page-B5cjaUp5.mjs +618 -0
- package/dist/Page-B5cjaUp5.mjs.map +1 -0
- package/dist/Page-BlPjfibv.d.mts +595 -0
- package/dist/Page.d.mts +2 -0
- package/dist/Page.mjs +2 -0
- package/dist/Plan-BI8XGvDu.d.mts +209 -0
- package/dist/Plan-D1wrJVs8.mjs +508 -0
- package/dist/Plan-D1wrJVs8.mjs.map +1 -0
- package/dist/Plan.d.mts +2 -3
- package/dist/Plan.mjs +2 -2
- package/dist/Policy.d.mts +76 -0
- package/dist/Policy.mjs +237 -0
- package/dist/Policy.mjs.map +1 -0
- package/dist/Presentation.d.mts +48 -0
- package/dist/Presentation.mjs +117 -0
- package/dist/Presentation.mjs.map +1 -0
- package/dist/Snapshot-B34hZ4Jl.d.mts +68 -0
- package/dist/Snapshot.d.mts +2 -0
- package/dist/Snapshot.mjs +79 -0
- package/dist/Snapshot.mjs.map +1 -0
- package/dist/Stage.d.mts +64 -0
- package/dist/Stage.mjs +237 -0
- package/dist/Stage.mjs.map +1 -0
- package/dist/Supervisor-CYWFK3vM.d.mts +280 -0
- package/dist/Supervisor-TNKNOVzu.mjs +599 -0
- package/dist/Supervisor-TNKNOVzu.mjs.map +1 -0
- package/dist/Supervisor.d.mts +2 -0
- package/dist/Supervisor.mjs +2 -0
- package/dist/context-B6xr8nVi.mjs +261 -0
- package/dist/context-B6xr8nVi.mjs.map +1 -0
- package/dist/index.d.mts +17 -14
- package/dist/index.mjs +18 -13
- package/dist/match.inpage-xOe9LNO0.mjs +48 -0
- package/dist/match.inpage-xOe9LNO0.mjs.map +1 -0
- package/dist/page-B8tUQELg.mjs +5073 -0
- package/dist/page-B8tUQELg.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/url-Cd04Okid.mjs +264 -0
- package/dist/url-Cd04Okid.mjs.map +1 -0
- package/package.json +96 -61
- package/src/Browser.ts +666 -0
- package/src/BrowserError.ts +234 -0
- package/src/BrowserEvent.ts +296 -0
- package/src/Cdp.ts +101 -0
- package/src/Change.ts +88 -0
- package/src/Chromium.ts +102 -0
- package/src/Expect.ts +180 -0
- package/src/Frame.ts +130 -0
- package/src/Moment.ts +479 -0
- package/src/Motion.ts +166 -0
- package/src/Page.ts +522 -0
- package/src/Plan.ts +663 -0
- package/src/Policy.ts +325 -0
- package/src/Presentation.ts +195 -0
- package/src/Snapshot.ts +89 -0
- package/src/Stage.ts +467 -0
- package/src/Supervisor.ts +599 -0
- package/src/index.ts +20 -0
- package/src/internal/input/actions.ts +610 -0
- package/src/internal/input/dispatch.ts +161 -0
- package/src/internal/input/edit.inpage.ts +162 -0
- package/src/internal/input/evidence.inpage.ts +164 -0
- package/src/internal/input/gate.ts +224 -0
- package/src/internal/input/guard.inpage.ts +605 -0
- package/src/internal/input/guard.ts +184 -0
- package/src/internal/input/keyboard.ts +112 -0
- package/src/internal/input/keys.ts +127 -0
- package/src/internal/input/perform.ts +376 -0
- package/src/internal/input/pointer.ts +153 -0
- package/src/internal/input/replies.ts +195 -0
- package/src/internal/input/settle.ts +50 -0
- package/src/internal/input/style.ts +186 -0
- package/src/internal/input/targets.inpage.ts +293 -0
- package/src/internal/input/targets.ts +148 -0
- package/src/internal/page/bridge.ts +386 -0
- package/src/internal/page/context.ts +312 -0
- package/src/internal/page/lane.ts +311 -0
- package/src/internal/page/navigation.ts +183 -0
- package/src/internal/page/openings.ts +87 -0
- package/src/internal/page/page.ts +165 -0
- package/src/internal/page/url.ts +100 -0
- package/src/internal/page/viewport.ts +43 -0
- package/src/internal/pictures/capture.ts +776 -0
- package/src/internal/pictures/clock.ts +141 -0
- package/src/internal/pictures/counts.ts +92 -0
- package/src/internal/pictures/pictures.ts +520 -0
- package/src/internal/pictures/transport.ts +242 -0
- package/src/internal/reading/choose.ts +100 -0
- package/src/internal/reading/context.inpage.ts +201 -0
- package/src/internal/reading/controls.inpage.ts +158 -0
- package/src/internal/reading/expect.inpage.ts +70 -0
- package/src/internal/reading/match.inpage.ts +92 -0
- package/src/internal/reading/names.inpage.ts +306 -0
- package/src/internal/reading/outline.inpage.ts +260 -0
- package/src/internal/reading/reading.ts +223 -0
- package/src/internal/reading/ready.inpage.ts +164 -0
- package/src/internal/reading/ready.ts +111 -0
- package/src/internal/reading/subjects.inpage.ts +188 -0
- package/src/internal/reading/text.inpage.ts +135 -0
- package/src/internal/reading/walk.inpage.ts +220 -0
- package/src/internal/supervisor/lifecycle.ts +416 -0
- package/src/internal/timeline/changes.inpage.ts +216 -0
- package/src/internal/timeline/changes.ts +100 -0
- package/src/internal/timeline/events.ts +94 -0
- package/src/internal/timeline/fold.inpage.ts +123 -0
- package/src/internal/timeline/history.inpage.ts +229 -0
- package/src/internal/timeline/marks.inpage.ts +207 -0
- package/src/internal/timeline/record.inpage.ts +133 -0
- package/src/internal/timeline/sight.inpage.ts +122 -0
- package/src/internal/timeline/window.ts +96 -0
- package/src/internal/timeline/words.ts +65 -0
- package/dist/Bootstrap-B9UUXsvF.d.mts +0 -183
- package/dist/Bootstrap-CeQOWBy6.mjs +0 -189
- package/dist/Bootstrap-CeQOWBy6.mjs.map +0 -1
- package/dist/Bootstrap.d.mts +0 -3
- package/dist/Bootstrap.mjs +0 -2
- package/dist/Browser-BF9_sORP.d.mts +0 -388
- package/dist/Browser.mjs.map +0 -1
- package/dist/BrowserData-CPIIIHol.d.mts +0 -585
- package/dist/BrowserData.d.mts +0 -3
- package/dist/BrowserData.mjs +0 -695
- package/dist/BrowserData.mjs.map +0 -1
- package/dist/BrowserRuntime-B6nT1G4X.d.mts +0 -148
- package/dist/BrowserRuntime-C1r2aSRK.mjs +0 -6820
- package/dist/BrowserRuntime-C1r2aSRK.mjs.map +0 -1
- package/dist/BrowserRuntime.d.mts +0 -3
- package/dist/BrowserRuntime.mjs +0 -3
- package/dist/Capture.d.mts +0 -56
- package/dist/Capture.mjs +0 -678
- package/dist/Capture.mjs.map +0 -1
- package/dist/CaptureData-CYriZHX1.mjs +0 -201
- package/dist/CaptureData-CYriZHX1.mjs.map +0 -1
- package/dist/CaptureData.d.mts +0 -219
- package/dist/CaptureData.mjs +0 -2
- package/dist/Errors.d.mts +0 -158
- package/dist/Errors.mjs +0 -207
- package/dist/Errors.mjs.map +0 -1
- package/dist/Images-yCG9BmRU.mjs +0 -76
- package/dist/Images-yCG9BmRU.mjs.map +0 -1
- package/dist/OperationOptions-DAeRS6O9.mjs +0 -55
- package/dist/OperationOptions-DAeRS6O9.mjs.map +0 -1
- package/dist/PageControl.d.mts +0 -15
- package/dist/PageControl.mjs +0 -34
- package/dist/PageControl.mjs.map +0 -1
- package/dist/PageRegistry-B3q9DS3g.mjs +0 -164
- package/dist/PageRegistry-B3q9DS3g.mjs.map +0 -1
- package/dist/Plan-Dyxu2q8C.mjs +0 -543
- package/dist/Plan-Dyxu2q8C.mjs.map +0 -1
- package/dist/PlanData-B668RxbQ.d.mts +0 -4831
- package/dist/PlanData.d.mts +0 -3
- package/dist/PlanData.mjs +0 -268
- package/dist/PlanData.mjs.map +0 -1
- package/dist/PlanInput-BJcPPncs.mjs +0 -75
- package/dist/PlanInput-BJcPPncs.mjs.map +0 -1
- package/dist/PublicSession-DCSMMqOj.mjs +0 -5602
- package/dist/PublicSession-DCSMMqOj.mjs.map +0 -1
- package/dist/Testing.d.mts +0 -479
- package/dist/Testing.mjs +0 -2147
- package/dist/Testing.mjs.map +0 -1
- package/dist/Timeline-fV22Xk-S.d.mts +0 -29
- package/dist/Timeline.d.mts +0 -4
- package/dist/Timeline.mjs +0 -20
- package/dist/Timeline.mjs.map +0 -1
- package/dist/TimelineData-BsOn-YGZ.d.mts +0 -3818
- package/dist/TimelineData.d.mts +0 -3
- package/dist/TimelineData.mjs +0 -482
- package/dist/TimelineData.mjs.map +0 -1
package/dist/Expect.mjs
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { InvalidRequest } from "./BrowserError.mjs";
|
|
3
|
+
import { s as undispatched } from "./context-B6xr8nVi.mjs";
|
|
4
|
+
import { t as internalsOf } from "./page-B8tUQELg.mjs";
|
|
5
|
+
import { Cause, Duration, Effect, Exit, Option, Schedule } from "effect";
|
|
6
|
+
//#region src/Expect.ts
|
|
7
|
+
/**
|
|
8
|
+
* Expectations: what an action is for, checked on the page, so that an action whose outcome is
|
|
9
|
+
* uncertain is sent again only where it did not take effect. An action that failed after its input
|
|
10
|
+
* went, a `Timeout` or a `Closed` with `dispatched`, may have done what it was for; repeating it
|
|
11
|
+
* blindly may do it twice, such as placing an order twice.
|
|
12
|
+
*
|
|
13
|
+
* An attempt takes its expectation's baseline from the page once, as it begins. Each `run` then
|
|
14
|
+
* checks first: where the expectation holds already, it sends nothing and is `AlreadyDone`.
|
|
15
|
+
* Otherwise it acts, and waits for the expectation: `Done`, or `NotDone` when it did not come in
|
|
16
|
+
* time. An action that fails after its input went is checked too, `Done` if its effect came, and
|
|
17
|
+
* otherwise fails as it did, so a later `run` of the same attempt checks before it acts again,
|
|
18
|
+
* on the same page or on the one a reconnect finds by its id.
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* const placing = yield* Expect.attempt(page, Expect.appeared({ text: "Order placed" }))
|
|
22
|
+
* const outcome = yield* placing.run(page, (page) => page.click("e12"))
|
|
23
|
+
* // After a Timeout that left `dispatched`, the same call clicks again only if no order shows.
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* A query is `Page.find`'s, over the whole document unless it says otherwise, and each check is one
|
|
27
|
+
* call to the page, a wait included; `navigated` reads the page's address and document, at no
|
|
28
|
+
* call. What `changed` compares stays in the page: text, field values and states, focus aside.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.3.0
|
|
31
|
+
*/
|
|
32
|
+
var Expect_exports = /* @__PURE__ */ __exportAll({
|
|
33
|
+
appeared: () => appeared,
|
|
34
|
+
attempt: () => attempt,
|
|
35
|
+
changed: () => changed,
|
|
36
|
+
gone: () => gone,
|
|
37
|
+
navigated: () => navigated
|
|
38
|
+
});
|
|
39
|
+
/** Something the query finds. */
|
|
40
|
+
const appeared = (query) => ({
|
|
41
|
+
_tag: "Appeared",
|
|
42
|
+
query
|
|
43
|
+
});
|
|
44
|
+
/** Nothing the query finds. */
|
|
45
|
+
const gone = (query) => ({
|
|
46
|
+
_tag: "Gone",
|
|
47
|
+
query
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* What the query finds shows something other than it did as the attempt began: other elements, or
|
|
51
|
+
* their text, values or states.
|
|
52
|
+
*/
|
|
53
|
+
const changed = (query) => ({
|
|
54
|
+
_tag: "Changed",
|
|
55
|
+
query
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* The page is at `url`, the whole address or a pattern; without one, at an address or in a
|
|
59
|
+
* document other than the attempt's first.
|
|
60
|
+
*/
|
|
61
|
+
const navigated = (url) => ({
|
|
62
|
+
_tag: "Navigated",
|
|
63
|
+
url
|
|
64
|
+
});
|
|
65
|
+
const refused = (detail) => undispatched("expect", new InvalidRequest({ detail }));
|
|
66
|
+
const internalsFor = (page) => {
|
|
67
|
+
const internals = internalsOf(page);
|
|
68
|
+
return internals === void 0 ? Effect.fail(refused("only a page a Browser opened, or a presenter's view of one, can be checked")) : Effect.succeed(internals);
|
|
69
|
+
};
|
|
70
|
+
const atUrl = (url, wanted) => typeof wanted === "string" ? url === wanted : new RegExp(wanted.source, wanted.flags).test(url);
|
|
71
|
+
/** Begin an attempt at `expectation` on `page`, which takes its baseline from the page now. */
|
|
72
|
+
const attempt = Effect.fn("Expect.attempt")(function* (page, expectation, options = {}) {
|
|
73
|
+
const wait = Duration.fromInput(options.wait ?? Duration.seconds(5));
|
|
74
|
+
if (Option.isNone(wait) || Duration.isNegative(wait.value)) return yield* refused("wait must be a duration, not negative");
|
|
75
|
+
const waitMillis = Duration.toMillis(wait.value);
|
|
76
|
+
const first = yield* page.state;
|
|
77
|
+
const internals = yield* internalsFor(page);
|
|
78
|
+
const from = expectation._tag === "Changed" ? (yield* internals.until(expectation.query, "some", 0)).mark : void 0;
|
|
79
|
+
const navigatedOn = (target, url) => Effect.map(target.state, (now) => url !== void 0 ? atUrl(now.url, url) : now.url !== first.url || internalsOf(target) === internals && now.document !== first.document);
|
|
80
|
+
const holdsWithin = (target, millis) => {
|
|
81
|
+
if (expectation._tag === "Navigated") {
|
|
82
|
+
const look = navigatedOn(target, expectation.url);
|
|
83
|
+
return look.pipe(Effect.repeat({
|
|
84
|
+
until: (held) => held,
|
|
85
|
+
schedule: Schedule.spaced(Duration.millis(50))
|
|
86
|
+
}), Effect.timeoutOrElse({
|
|
87
|
+
duration: Duration.millis(millis),
|
|
88
|
+
orElse: () => look
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
const want = expectation._tag === "Appeared" ? "some" : expectation._tag === "Gone" ? "none" : { other: from ?? "" };
|
|
92
|
+
return internalsFor(target).pipe(Effect.flatMap((own) => own.until(expectation.query, want, millis)), Effect.map(({ met }) => met));
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
expectation,
|
|
96
|
+
holds: (target) => holdsWithin(target, 0),
|
|
97
|
+
run: Effect.fn("Expect.run")(function* (target, act) {
|
|
98
|
+
if (yield* holdsWithin(target, 0)) return "AlreadyDone";
|
|
99
|
+
const acted = yield* Effect.exit(act(target));
|
|
100
|
+
if (Exit.isSuccess(acted)) return (yield* holdsWithin(target, waitMillis)) ? "Done" : "NotDone";
|
|
101
|
+
const error = Cause.findErrorOption(acted.cause);
|
|
102
|
+
if (Option.isNone(error) || !error.value.dispatched) return yield* Effect.failCause(acted.cause);
|
|
103
|
+
const held = yield* Effect.exit(holdsWithin(target, waitMillis));
|
|
104
|
+
return Exit.isSuccess(held) && held.value ? "Done" : yield* Effect.failCause(acted.cause);
|
|
105
|
+
}, Effect.tap((outcome) => Effect.annotateCurrentSpan({
|
|
106
|
+
expectation: expectation._tag,
|
|
107
|
+
outcome
|
|
108
|
+
})))
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
//#endregion
|
|
112
|
+
export { appeared, attempt, changed, gone, navigated, Expect_exports as t };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=Expect.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Expect.mjs","names":[],"sources":["../src/Expect.ts"],"sourcesContent":["/**\n * Expectations: what an action is for, checked on the page, so that an action whose outcome is\n * uncertain is sent again only where it did not take effect. An action that failed after its input\n * went, a `Timeout` or a `Closed` with `dispatched`, may have done what it was for; repeating it\n * blindly may do it twice, such as placing an order twice.\n *\n * An attempt takes its expectation's baseline from the page once, as it begins. Each `run` then\n * checks first: where the expectation holds already, it sends nothing and is `AlreadyDone`.\n * Otherwise it acts, and waits for the expectation: `Done`, or `NotDone` when it did not come in\n * time. An action that fails after its input went is checked too, `Done` if its effect came, and\n * otherwise fails as it did, so a later `run` of the same attempt checks before it acts again,\n * on the same page or on the one a reconnect finds by its id.\n *\n * ```ts\n * const placing = yield* Expect.attempt(page, Expect.appeared({ text: \"Order placed\" }))\n * const outcome = yield* placing.run(page, (page) => page.click(\"e12\"))\n * // After a Timeout that left `dispatched`, the same call clicks again only if no order shows.\n * ```\n *\n * A query is `Page.find`'s, over the whole document unless it says otherwise, and each check is one\n * call to the page, a wait included; `navigated` reads the page's address and document, at no\n * call. What `changed` compares stays in the page: text, field values and states, focus aside.\n *\n * @since 0.3.0\n */\nimport { Cause, Duration, Effect, Exit, Option, Schedule } from \"effect\";\n\nimport { type BrowserError, InvalidRequest } from \"./BrowserError.ts\";\nimport { undispatched } from \"./internal/page/context.ts\";\nimport { type Internals, internalsOf } from \"./internal/page/page.ts\";\nimport type { FindQuery, Page } from \"./Page.ts\";\n\n/** What an action is for, as the page can tell it. */\nexport type Expectation =\n | { readonly _tag: \"Appeared\"; readonly query: FindQuery }\n | { readonly _tag: \"Gone\"; readonly query: FindQuery }\n | { readonly _tag: \"Changed\"; readonly query: FindQuery }\n | { readonly _tag: \"Navigated\"; readonly url: string | RegExp | undefined };\n\n/** Something the query finds. */\nexport const appeared = (query: FindQuery): Expectation => ({ _tag: \"Appeared\", query });\n\n/** Nothing the query finds. */\nexport const gone = (query: FindQuery): Expectation => ({ _tag: \"Gone\", query });\n\n/**\n * What the query finds shows something other than it did as the attempt began: other elements, or\n * their text, values or states.\n */\nexport const changed = (query: FindQuery): Expectation => ({ _tag: \"Changed\", query });\n\n/**\n * The page is at `url`, the whole address or a pattern; without one, at an address or in a\n * document other than the attempt's first.\n */\nexport const navigated = (url?: string | RegExp): Expectation => ({ _tag: \"Navigated\", url });\n\n/**\n * `Done`: the action ran, and what it was for came. `AlreadyDone`: it held before the action was\n * sent, so it was not. `NotDone`: the action ran, and it did not come within the attempt's wait.\n */\nexport type Outcome = \"Done\" | \"AlreadyDone\" | \"NotDone\";\n\nexport interface Options {\n /** How long an action's effect may take to show. Defaults to 5 seconds. */\n readonly wait?: Duration.Input | undefined;\n}\n\nexport interface Attempt {\n readonly expectation: Expectation;\n /** Whether the expectation holds on `page` now. */\n readonly holds: (page: Page) => Effect.Effect<boolean, BrowserError>;\n /**\n * `act` on `page`, unless the expectation holds there already: see the module's comment. A\n * failure before its input went is the action's own, and nothing is checked.\n */\n readonly run: (\n page: Page,\n act: (page: Page) => Effect.Effect<unknown, BrowserError>,\n ) => Effect.Effect<Outcome, BrowserError>;\n}\n\nconst refused = (detail: string) => undispatched(\"expect\", new InvalidRequest({ detail }));\n\nconst internalsFor = (page: Page): Effect.Effect<Internals, BrowserError> => {\n const internals = internalsOf(page);\n\n return internals === undefined\n ? Effect.fail(\n refused(\"only a page a Browser opened, or a presenter's view of one, can be checked\"),\n )\n : Effect.succeed(internals);\n};\n\nconst atUrl = (url: string, wanted: string | RegExp) =>\n typeof wanted === \"string\" ? url === wanted : new RegExp(wanted.source, wanted.flags).test(url);\n\n/** Begin an attempt at `expectation` on `page`, which takes its baseline from the page now. */\nexport const attempt = Effect.fn(\"Expect.attempt\")(function* (\n page: Page,\n expectation: Expectation,\n options: Options = {},\n) {\n const wait = Duration.fromInput(options.wait ?? Duration.seconds(5));\n\n if (Option.isNone(wait) || Duration.isNegative(wait.value))\n return yield* refused(\"wait must be a duration, not negative\");\n const waitMillis = Duration.toMillis(wait.value);\n const first = yield* page.state;\n const internals = yield* internalsFor(page);\n\n // What `changed` compares with: the mark of what the query found as the attempt began.\n const from =\n expectation._tag === \"Changed\"\n ? (yield* internals.until(expectation.query, \"some\", 0)).mark\n : undefined;\n\n // Navigated: at the address asked, or, without one, somewhere other than the attempt's first,\n // where a document counts only on the page that counted it, not on one a reconnect found.\n const navigatedOn = (target: Page, url: string | RegExp | undefined) =>\n Effect.map(target.state, (now) =>\n url !== undefined\n ? atUrl(now.url, url)\n : now.url !== first.url ||\n (internalsOf(target) === internals && now.document !== first.document),\n );\n\n const holdsWithin = (target: Page, millis: number): Effect.Effect<boolean, BrowserError> => {\n if (expectation._tag === \"Navigated\") {\n const look = navigatedOn(target, expectation.url);\n\n return look.pipe(\n Effect.repeat({\n until: (held) => held,\n schedule: Schedule.spaced(Duration.millis(50)),\n }),\n Effect.timeoutOrElse({ duration: Duration.millis(millis), orElse: () => look }),\n );\n }\n\n const want =\n expectation._tag === \"Appeared\"\n ? \"some\"\n : expectation._tag === \"Gone\"\n ? \"none\"\n : { other: from ?? \"\" };\n\n return internalsFor(target).pipe(\n Effect.flatMap((own) => own.until(expectation.query, want, millis)),\n Effect.map(({ met }) => met),\n );\n };\n\n const run = Effect.fn(\"Expect.run\")(\n function* (target: Page, act: (page: Page) => Effect.Effect<unknown, BrowserError>) {\n if (yield* holdsWithin(target, 0)) return \"AlreadyDone\" as const;\n const acted = yield* Effect.exit(act(target));\n\n if (Exit.isSuccess(acted))\n return (yield* holdsWithin(target, waitMillis)) ? (\"Done\" as const) : (\"NotDone\" as const);\n const error = Cause.findErrorOption(acted.cause);\n\n // A failure before the input went did nothing; one after it may have done what it was for.\n if (Option.isNone(error) || !error.value.dispatched)\n return yield* Effect.failCause(acted.cause);\n const held = yield* Effect.exit(holdsWithin(target, waitMillis));\n\n return Exit.isSuccess(held) && held.value\n ? (\"Done\" as const)\n : yield* Effect.failCause(acted.cause);\n },\n Effect.tap((outcome) => Effect.annotateCurrentSpan({ expectation: expectation._tag, outcome })),\n );\n\n return {\n expectation,\n holds: (target) => holdsWithin(target, 0),\n run,\n } satisfies Attempt;\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,YAAY,WAAmC;CAAE,MAAM;CAAY;AAAM;;AAGtF,MAAa,QAAQ,WAAmC;CAAE,MAAM;CAAQ;AAAM;;;;;AAM9E,MAAa,WAAW,WAAmC;CAAE,MAAM;CAAW;AAAM;;;;;AAMpF,MAAa,aAAa,SAAwC;CAAE,MAAM;CAAa;AAAI;AA2B3F,MAAM,WAAW,WAAmB,aAAa,UAAU,IAAI,eAAe,EAAE,OAAO,CAAC,CAAC;AAEzF,MAAM,gBAAgB,SAAuD;CAC3E,MAAM,YAAY,YAAY,IAAI;CAElC,OAAO,cAAc,KAAA,IACjB,OAAO,KACL,QAAQ,4EAA4E,CACtF,IACA,OAAO,QAAQ,SAAS;AAC9B;AAEA,MAAM,SAAS,KAAa,WAC1B,OAAO,WAAW,WAAW,QAAQ,SAAS,IAAI,OAAO,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,KAAK,GAAG;;AAGhG,MAAa,UAAU,OAAO,GAAG,gBAAgB,CAAC,CAAC,WACjD,MACA,aACA,UAAmB,CAAC,GACpB;CACA,MAAM,OAAO,SAAS,UAAU,QAAQ,QAAQ,SAAS,QAAQ,CAAC,CAAC;CAEnE,IAAI,OAAO,OAAO,IAAI,KAAK,SAAS,WAAW,KAAK,KAAK,GACvD,OAAO,OAAO,QAAQ,uCAAuC;CAC/D,MAAM,aAAa,SAAS,SAAS,KAAK,KAAK;CAC/C,MAAM,QAAQ,OAAO,KAAK;CAC1B,MAAM,YAAY,OAAO,aAAa,IAAI;CAG1C,MAAM,OACJ,YAAY,SAAS,aAChB,OAAO,UAAU,MAAM,YAAY,OAAO,QAAQ,CAAC,EAAA,CAAG,OACvD,KAAA;CAIN,MAAM,eAAe,QAAc,QACjC,OAAO,IAAI,OAAO,QAAQ,QACxB,QAAQ,KAAA,IACJ,MAAM,IAAI,KAAK,GAAG,IAClB,IAAI,QAAQ,MAAM,OACjB,YAAY,MAAM,MAAM,aAAa,IAAI,aAAa,MAAM,QACnE;CAEF,MAAM,eAAe,QAAc,WAAyD;EAC1F,IAAI,YAAY,SAAS,aAAa;GACpC,MAAM,OAAO,YAAY,QAAQ,YAAY,GAAG;GAEhD,OAAO,KAAK,KACV,OAAO,OAAO;IACZ,QAAQ,SAAS;IACjB,UAAU,SAAS,OAAO,SAAS,OAAO,EAAE,CAAC;GAC/C,CAAC,GACD,OAAO,cAAc;IAAE,UAAU,SAAS,OAAO,MAAM;IAAG,cAAc;GAAK,CAAC,CAChF;EACF;EAEA,MAAM,OACJ,YAAY,SAAS,aACjB,SACA,YAAY,SAAS,SACnB,SACA,EAAE,OAAO,QAAQ,GAAG;EAE5B,OAAO,aAAa,MAAM,CAAC,CAAC,KAC1B,OAAO,SAAS,QAAQ,IAAI,MAAM,YAAY,OAAO,MAAM,MAAM,CAAC,GAClE,OAAO,KAAK,EAAE,UAAU,GAAG,CAC7B;CACF;CAuBA,OAAO;EACL;EACA,QAAQ,WAAW,YAAY,QAAQ,CAAC;EACxC,KAxBU,OAAO,GAAG,YAAY,CAAC,CACjC,WAAW,QAAc,KAA2D;GAClF,IAAI,OAAO,YAAY,QAAQ,CAAC,GAAG,OAAO;GAC1C,MAAM,QAAQ,OAAO,OAAO,KAAK,IAAI,MAAM,CAAC;GAE5C,IAAI,KAAK,UAAU,KAAK,GACtB,QAAQ,OAAO,YAAY,QAAQ,UAAU,KAAM,SAAoB;GACzE,MAAM,QAAQ,MAAM,gBAAgB,MAAM,KAAK;GAG/C,IAAI,OAAO,OAAO,KAAK,KAAK,CAAC,MAAM,MAAM,YACvC,OAAO,OAAO,OAAO,UAAU,MAAM,KAAK;GAC5C,MAAM,OAAO,OAAO,OAAO,KAAK,YAAY,QAAQ,UAAU,CAAC;GAE/D,OAAO,KAAK,UAAU,IAAI,KAAK,KAAK,QAC/B,SACD,OAAO,OAAO,UAAU,MAAM,KAAK;EACzC,GACA,OAAO,KAAK,YAAY,OAAO,oBAAoB;GAAE,aAAa,YAAY;GAAM;EAAQ,CAAC,CAAC,CAM5F;CACJ;AACF,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
declare namespace Frame_d_exports {
|
|
3
|
+
export { BrowserPaint, CaptureStats, Frame, Image, ScreencastOptions, Screenshot };
|
|
4
|
+
}
|
|
5
|
+
declare const Image_base: Schema.Class<Image, Schema.Struct<{
|
|
6
|
+
readonly data: Schema.Uint8Array;
|
|
7
|
+
readonly mediaType: Schema.Literals<readonly ["image/jpeg", "image/png"]>;
|
|
8
|
+
readonly width: Schema.Finite;
|
|
9
|
+
readonly height: Schema.Finite;
|
|
10
|
+
}>, {}>;
|
|
11
|
+
/** An encoded picture with its pixel dimensions. Crops also need their viewport origin. */
|
|
12
|
+
declare class Image extends Image_base {}
|
|
13
|
+
declare const BrowserPaint_base: Schema.Class<BrowserPaint, Schema.TaggedStruct<"BrowserPaint", {
|
|
14
|
+
readonly timestamp: Schema.Finite;
|
|
15
|
+
readonly hostTime: Schema.Finite;
|
|
16
|
+
readonly uncertaintyMillis: Schema.Finite;
|
|
17
|
+
}>, {}>;
|
|
18
|
+
/** Native CDP paint time mapped to the owning host clock, with transport uncertainty retained. */
|
|
19
|
+
declare class BrowserPaint extends BrowserPaint_base {}
|
|
20
|
+
declare const Screenshot_base: Schema.Class<Screenshot, Schema.TaggedStruct<"Screenshot", {
|
|
21
|
+
readonly hostTime: Schema.Finite;
|
|
22
|
+
readonly uncertaintyMillis: Schema.Finite;
|
|
23
|
+
}>, {}>;
|
|
24
|
+
/** A screenshot's host capture interval; it has no native browser paint timestamp. */
|
|
25
|
+
declare class Screenshot extends Screenshot_base {}
|
|
26
|
+
declare const Frame_base: Schema.Class<Frame, Schema.Struct<{
|
|
27
|
+
readonly page: Schema.String;
|
|
28
|
+
/** The page's browser session: its provider's session id, as `Browser.Service.id` gives it. */
|
|
29
|
+
readonly session: Schema.String;
|
|
30
|
+
readonly data: Schema.Uint8Array;
|
|
31
|
+
readonly timing: Schema.Union<readonly [typeof BrowserPaint, typeof Screenshot]>;
|
|
32
|
+
readonly receivedAt: Schema.Finite;
|
|
33
|
+
readonly width: Schema.Finite;
|
|
34
|
+
readonly height: Schema.Finite;
|
|
35
|
+
/**
|
|
36
|
+
* The page's document committed before the frame arrived, as `Navigated` counts them. Just
|
|
37
|
+
* after a commit a browser can still show the old document's paint, so a frame may show the
|
|
38
|
+
* document before its own, never one after it.
|
|
39
|
+
*/
|
|
40
|
+
readonly document: Schema.Int;
|
|
41
|
+
/** The page's address when the frame arrived. */
|
|
42
|
+
readonly url: Schema.String;
|
|
43
|
+
}>, {}>;
|
|
44
|
+
/**
|
|
45
|
+
* An image and its timing evidence. Paint time and screenshot capture time cannot be confused in
|
|
46
|
+
* serialized data. `receivedAt` records delivery on the owning host's monotonic clock; it does
|
|
47
|
+
* not make an old paint current.
|
|
48
|
+
*/
|
|
49
|
+
declare class Frame extends Frame_base {
|
|
50
|
+
get timestamp(): number | undefined;
|
|
51
|
+
get hostTime(): number;
|
|
52
|
+
get image(): Image;
|
|
53
|
+
}
|
|
54
|
+
declare const CaptureStats_base: Schema.Class<CaptureStats, Schema.Struct<{
|
|
55
|
+
readonly received: Schema.Int;
|
|
56
|
+
readonly accepted: Schema.Int;
|
|
57
|
+
/**
|
|
58
|
+
* Frames Chromium finished encoding after a newer one, dropped rather than reordered. It encodes
|
|
59
|
+
* several at once, so a busy machine makes more of them; none was a paint readers missed.
|
|
60
|
+
*/
|
|
61
|
+
readonly late: Schema.Int;
|
|
62
|
+
readonly missingTimestamp: Schema.Int;
|
|
63
|
+
/**
|
|
64
|
+
* Frames dropped for their size. Most are other captures' frames, which a clipped screenshot
|
|
65
|
+
* draws into a screencast. The rest are the page's own frames of a new size, dropped while still
|
|
66
|
+
* unconfirmed: when another size replaced it, when its capture stopped, or beyond the 16 held.
|
|
67
|
+
*/
|
|
68
|
+
readonly foreignSize: Schema.Int;
|
|
69
|
+
/**
|
|
70
|
+
* Frames dropped because they may have been painted, or arrived, while the library took a clipped
|
|
71
|
+
* or scaled picture of the page, such as a zoom: Chromium draws those into the screencast too.
|
|
72
|
+
* Where Playwright emulates the viewport, the page's own frames from that time are among them; a
|
|
73
|
+
* crop on the page's own session leaves out only frames of another size than the page's.
|
|
74
|
+
*/
|
|
75
|
+
readonly duringPictures: Schema.Int;
|
|
76
|
+
/**
|
|
77
|
+
* Frames a reader missed by falling behind. Each reader counts its own, so with several readers
|
|
78
|
+
* this can exceed the frames accepted.
|
|
79
|
+
*/
|
|
80
|
+
readonly lost: Schema.Int;
|
|
81
|
+
/**
|
|
82
|
+
* Acknowledgements of frames sent and not yet answered, now, whatever the window. Chromium sends
|
|
83
|
+
* a frame only while few are unacknowledged, so a backlog means fewer frames.
|
|
84
|
+
*/
|
|
85
|
+
readonly ackBacklog: Schema.Int;
|
|
86
|
+
/** Paint-time gaps between consecutive accepted frames. */
|
|
87
|
+
readonly gaps: Schema.Struct<{
|
|
88
|
+
readonly count: Schema.Int;
|
|
89
|
+
readonly totalMillis: Schema.Finite;
|
|
90
|
+
readonly minMillis: Schema.NullOr<Schema.Finite>;
|
|
91
|
+
readonly maxMillis: Schema.NullOr<Schema.Finite>;
|
|
92
|
+
readonly lastMillis: Schema.NullOr<Schema.Finite>;
|
|
93
|
+
}>;
|
|
94
|
+
}>, {}>;
|
|
95
|
+
/**
|
|
96
|
+
* A page's capture counts, over its life or a window of the latest minute: what Chromium sent,
|
|
97
|
+
* what readers got, and why the rest went no further. Frames that came late are counted apart from
|
|
98
|
+
* those a reader lost.
|
|
99
|
+
*/
|
|
100
|
+
declare class CaptureStats extends CaptureStats_base {}
|
|
101
|
+
/**
|
|
102
|
+
* Settings for a page's one native capture. Readers that join a running capture share its
|
|
103
|
+
* settings: one without options accepts them, and one whose explicit options differ fails with
|
|
104
|
+
* `InvalidRequest`.
|
|
105
|
+
*/
|
|
106
|
+
interface ScreencastOptions {
|
|
107
|
+
/** JPEG quality, 0 to 100. Defaults to 80. */
|
|
108
|
+
readonly quality?: number | undefined;
|
|
109
|
+
/** Frames are scaled down to fit this box. Defaults to the viewport in CSS pixels. */
|
|
110
|
+
readonly size?: {
|
|
111
|
+
readonly width: number;
|
|
112
|
+
readonly height: number;
|
|
113
|
+
} | undefined;
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { Image as a, Frame_d_exports as i, CaptureStats as n, ScreencastOptions as o, Frame as r, Screenshot as s, BrowserPaint as t };
|
|
117
|
+
//# sourceMappingURL=Frame-BERmf_gM.d.mts.map
|
package/dist/Frame.d.mts
ADDED
package/dist/Frame.mjs
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
//#region src/Frame.ts
|
|
4
|
+
/**
|
|
5
|
+
* Pictures of a page: screenshots, and screencast frames stamped with the browser's clock.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.3.0
|
|
8
|
+
*/
|
|
9
|
+
var Frame_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
BrowserPaint: () => BrowserPaint,
|
|
11
|
+
CaptureStats: () => CaptureStats,
|
|
12
|
+
Frame: () => Frame,
|
|
13
|
+
Image: () => Image,
|
|
14
|
+
Screenshot: () => Screenshot
|
|
15
|
+
});
|
|
16
|
+
/** An encoded picture with its pixel dimensions. Crops also need their viewport origin. */
|
|
17
|
+
var Image = class extends Schema.Class("effect-browser/Image")({
|
|
18
|
+
data: Schema.Uint8Array,
|
|
19
|
+
mediaType: Schema.Literals(["image/jpeg", "image/png"]),
|
|
20
|
+
width: Schema.Finite,
|
|
21
|
+
height: Schema.Finite
|
|
22
|
+
}) {};
|
|
23
|
+
const Nonnegative = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0));
|
|
24
|
+
const Count = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
25
|
+
/** Native CDP paint time mapped to the owning host clock, with transport uncertainty retained. */
|
|
26
|
+
var BrowserPaint = class extends Schema.TaggedClass()("BrowserPaint", {
|
|
27
|
+
timestamp: Schema.Finite,
|
|
28
|
+
hostTime: Schema.Finite,
|
|
29
|
+
uncertaintyMillis: Nonnegative
|
|
30
|
+
}) {};
|
|
31
|
+
/** A screenshot's host capture interval; it has no native browser paint timestamp. */
|
|
32
|
+
var Screenshot = class extends Schema.TaggedClass()("Screenshot", {
|
|
33
|
+
hostTime: Schema.Finite,
|
|
34
|
+
uncertaintyMillis: Nonnegative
|
|
35
|
+
}) {};
|
|
36
|
+
/**
|
|
37
|
+
* An image and its timing evidence. Paint time and screenshot capture time cannot be confused in
|
|
38
|
+
* serialized data. `receivedAt` records delivery on the owning host's monotonic clock; it does
|
|
39
|
+
* not make an old paint current.
|
|
40
|
+
*/
|
|
41
|
+
var Frame = class extends Schema.Class("effect-browser/Frame")({
|
|
42
|
+
page: Schema.String,
|
|
43
|
+
/** The page's browser session: its provider's session id, as `Browser.Service.id` gives it. */
|
|
44
|
+
session: Schema.String,
|
|
45
|
+
data: Schema.Uint8Array,
|
|
46
|
+
timing: Schema.Union([BrowserPaint, Screenshot]),
|
|
47
|
+
receivedAt: Schema.Finite,
|
|
48
|
+
width: Schema.Finite,
|
|
49
|
+
height: Schema.Finite,
|
|
50
|
+
/**
|
|
51
|
+
* The page's document committed before the frame arrived, as `Navigated` counts them. Just
|
|
52
|
+
* after a commit a browser can still show the old document's paint, so a frame may show the
|
|
53
|
+
* document before its own, never one after it.
|
|
54
|
+
*/
|
|
55
|
+
document: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
56
|
+
/** The page's address when the frame arrived. */
|
|
57
|
+
url: Schema.String
|
|
58
|
+
}) {
|
|
59
|
+
get timestamp() {
|
|
60
|
+
return this.timing._tag === "BrowserPaint" ? this.timing.timestamp : void 0;
|
|
61
|
+
}
|
|
62
|
+
get hostTime() {
|
|
63
|
+
return this.timing.hostTime;
|
|
64
|
+
}
|
|
65
|
+
get image() {
|
|
66
|
+
return new Image({
|
|
67
|
+
data: this.data,
|
|
68
|
+
mediaType: "image/jpeg",
|
|
69
|
+
width: this.width,
|
|
70
|
+
height: this.height
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* A page's capture counts, over its life or a window of the latest minute: what Chromium sent,
|
|
76
|
+
* what readers got, and why the rest went no further. Frames that came late are counted apart from
|
|
77
|
+
* those a reader lost.
|
|
78
|
+
*/
|
|
79
|
+
var CaptureStats = class extends Schema.Class("effect-browser/CaptureStats")({
|
|
80
|
+
received: Count,
|
|
81
|
+
accepted: Count,
|
|
82
|
+
/**
|
|
83
|
+
* Frames Chromium finished encoding after a newer one, dropped rather than reordered. It encodes
|
|
84
|
+
* several at once, so a busy machine makes more of them; none was a paint readers missed.
|
|
85
|
+
*/
|
|
86
|
+
late: Count,
|
|
87
|
+
missingTimestamp: Count,
|
|
88
|
+
/**
|
|
89
|
+
* Frames dropped for their size. Most are other captures' frames, which a clipped screenshot
|
|
90
|
+
* draws into a screencast. The rest are the page's own frames of a new size, dropped while still
|
|
91
|
+
* unconfirmed: when another size replaced it, when its capture stopped, or beyond the 16 held.
|
|
92
|
+
*/
|
|
93
|
+
foreignSize: Count,
|
|
94
|
+
/**
|
|
95
|
+
* Frames dropped because they may have been painted, or arrived, while the library took a clipped
|
|
96
|
+
* or scaled picture of the page, such as a zoom: Chromium draws those into the screencast too.
|
|
97
|
+
* Where Playwright emulates the viewport, the page's own frames from that time are among them; a
|
|
98
|
+
* crop on the page's own session leaves out only frames of another size than the page's.
|
|
99
|
+
*/
|
|
100
|
+
duringPictures: Count,
|
|
101
|
+
/**
|
|
102
|
+
* Frames a reader missed by falling behind. Each reader counts its own, so with several readers
|
|
103
|
+
* this can exceed the frames accepted.
|
|
104
|
+
*/
|
|
105
|
+
lost: Count,
|
|
106
|
+
/**
|
|
107
|
+
* Acknowledgements of frames sent and not yet answered, now, whatever the window. Chromium sends
|
|
108
|
+
* a frame only while few are unacknowledged, so a backlog means fewer frames.
|
|
109
|
+
*/
|
|
110
|
+
ackBacklog: Count,
|
|
111
|
+
/** Paint-time gaps between consecutive accepted frames. */
|
|
112
|
+
gaps: Schema.Struct({
|
|
113
|
+
count: Count,
|
|
114
|
+
totalMillis: Nonnegative,
|
|
115
|
+
minMillis: Schema.NullOr(Nonnegative),
|
|
116
|
+
maxMillis: Schema.NullOr(Nonnegative),
|
|
117
|
+
lastMillis: Schema.NullOr(Nonnegative)
|
|
118
|
+
})
|
|
119
|
+
}) {};
|
|
120
|
+
//#endregion
|
|
121
|
+
export { BrowserPaint, CaptureStats, Frame, Image, Screenshot, Frame_exports as t };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=Frame.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Frame.mjs","names":[],"sources":["../src/Frame.ts"],"sourcesContent":["/**\n * Pictures of a page: screenshots, and screencast frames stamped with the browser's clock.\n *\n * @since 0.3.0\n */\nimport { Schema } from \"effect\";\n\n/** An encoded picture with its pixel dimensions. Crops also need their viewport origin. */\nexport class Image extends Schema.Class<Image>(\"effect-browser/Image\")({\n data: Schema.Uint8Array,\n mediaType: Schema.Literals([\"image/jpeg\", \"image/png\"]),\n width: Schema.Finite,\n height: Schema.Finite,\n}) {}\n\nconst Nonnegative = Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0));\nconst Count = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));\n\n/** Native CDP paint time mapped to the owning host clock, with transport uncertainty retained. */\nexport class BrowserPaint extends Schema.TaggedClass<BrowserPaint>()(\"BrowserPaint\", {\n timestamp: Schema.Finite,\n hostTime: Schema.Finite,\n uncertaintyMillis: Nonnegative,\n}) {}\n\n/** A screenshot's host capture interval; it has no native browser paint timestamp. */\nexport class Screenshot extends Schema.TaggedClass<Screenshot>()(\"Screenshot\", {\n hostTime: Schema.Finite,\n uncertaintyMillis: Nonnegative,\n}) {}\n\n/**\n * An image and its timing evidence. Paint time and screenshot capture time cannot be confused in\n * serialized data. `receivedAt` records delivery on the owning host's monotonic clock; it does\n * not make an old paint current.\n */\nexport class Frame extends Schema.Class<Frame>(\"effect-browser/Frame\")({\n page: Schema.String,\n /** The page's browser session: its provider's session id, as `Browser.Service.id` gives it. */\n session: Schema.String,\n data: Schema.Uint8Array,\n timing: Schema.Union([BrowserPaint, Screenshot]),\n receivedAt: Schema.Finite,\n width: Schema.Finite,\n height: Schema.Finite,\n /**\n * The page's document committed before the frame arrived, as `Navigated` counts them. Just\n * after a commit a browser can still show the old document's paint, so a frame may show the\n * document before its own, never one after it.\n */\n document: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** The page's address when the frame arrived. */\n url: Schema.String,\n}) {\n get timestamp(): number | undefined {\n return this.timing._tag === \"BrowserPaint\" ? this.timing.timestamp : undefined;\n }\n\n get hostTime(): number {\n return this.timing.hostTime;\n }\n\n get image(): Image {\n return new Image({\n data: this.data,\n mediaType: \"image/jpeg\",\n width: this.width,\n height: this.height,\n });\n }\n}\n\n/**\n * A page's capture counts, over its life or a window of the latest minute: what Chromium sent,\n * what readers got, and why the rest went no further. Frames that came late are counted apart from\n * those a reader lost.\n */\nexport class CaptureStats extends Schema.Class<CaptureStats>(\"effect-browser/CaptureStats\")({\n received: Count,\n accepted: Count,\n /**\n * Frames Chromium finished encoding after a newer one, dropped rather than reordered. It encodes\n * several at once, so a busy machine makes more of them; none was a paint readers missed.\n */\n late: Count,\n missingTimestamp: Count,\n /**\n * Frames dropped for their size. Most are other captures' frames, which a clipped screenshot\n * draws into a screencast. The rest are the page's own frames of a new size, dropped while still\n * unconfirmed: when another size replaced it, when its capture stopped, or beyond the 16 held.\n */\n foreignSize: Count,\n /**\n * Frames dropped because they may have been painted, or arrived, while the library took a clipped\n * or scaled picture of the page, such as a zoom: Chromium draws those into the screencast too.\n * Where Playwright emulates the viewport, the page's own frames from that time are among them; a\n * crop on the page's own session leaves out only frames of another size than the page's.\n */\n duringPictures: Count,\n /**\n * Frames a reader missed by falling behind. Each reader counts its own, so with several readers\n * this can exceed the frames accepted.\n */\n lost: Count,\n /**\n * Acknowledgements of frames sent and not yet answered, now, whatever the window. Chromium sends\n * a frame only while few are unacknowledged, so a backlog means fewer frames.\n */\n ackBacklog: Count,\n /** Paint-time gaps between consecutive accepted frames. */\n gaps: Schema.Struct({\n count: Count,\n totalMillis: Nonnegative,\n minMillis: Schema.NullOr(Nonnegative),\n maxMillis: Schema.NullOr(Nonnegative),\n lastMillis: Schema.NullOr(Nonnegative),\n }),\n}) {}\n\n/**\n * Settings for a page's one native capture. Readers that join a running capture share its\n * settings: one without options accepts them, and one whose explicit options differ fails with\n * `InvalidRequest`.\n */\nexport interface ScreencastOptions {\n /** JPEG quality, 0 to 100. Defaults to 80. */\n readonly quality?: number | undefined;\n /** Frames are scaled down to fit this box. Defaults to the viewport in CSS pixels. */\n readonly size?: { readonly width: number; readonly height: number } | undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAQA,IAAa,QAAb,cAA2B,OAAO,MAAa,sBAAsB,CAAC,CAAC;CACrE,MAAM,OAAO;CACb,WAAW,OAAO,SAAS,CAAC,cAAc,WAAW,CAAC;CACtD,OAAO,OAAO;CACd,QAAQ,OAAO;AACjB,CAAC,CAAC,CAAC,CAAC;AAEJ,MAAM,cAAc,OAAO,OAAO,MAAM,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,QAAQ,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC;;AAG/D,IAAa,eAAb,cAAkC,OAAO,YAA0B,CAAC,CAAC,gBAAgB;CACnF,WAAW,OAAO;CAClB,UAAU,OAAO;CACjB,mBAAmB;AACrB,CAAC,CAAC,CAAC,CAAC;;AAGJ,IAAa,aAAb,cAAgC,OAAO,YAAwB,CAAC,CAAC,cAAc;CAC7E,UAAU,OAAO;CACjB,mBAAmB;AACrB,CAAC,CAAC,CAAC,CAAC;;;;;;AAOJ,IAAa,QAAb,cAA2B,OAAO,MAAa,sBAAsB,CAAC,CAAC;CACrE,MAAM,OAAO;;CAEb,SAAS,OAAO;CAChB,MAAM,OAAO;CACb,QAAQ,OAAO,MAAM,CAAC,cAAc,UAAU,CAAC;CAC/C,YAAY,OAAO;CACnB,OAAO,OAAO;CACd,QAAQ,OAAO;;;;;;CAMf,UAAU,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC;;CAE3D,KAAK,OAAO;AACd,CAAC,CAAC,CAAC;CACD,IAAI,YAAgC;EAClC,OAAO,KAAK,OAAO,SAAS,iBAAiB,KAAK,OAAO,YAAY,KAAA;CACvE;CAEA,IAAI,WAAmB;EACrB,OAAO,KAAK,OAAO;CACrB;CAEA,IAAI,QAAe;EACjB,OAAO,IAAI,MAAM;GACf,MAAM,KAAK;GACX,WAAW;GACX,OAAO,KAAK;GACZ,QAAQ,KAAK;EACf,CAAC;CACH;AACF;;;;;;AAOA,IAAa,eAAb,cAAkC,OAAO,MAAoB,6BAA6B,CAAC,CAAC;CAC1F,UAAU;CACV,UAAU;;;;;CAKV,MAAM;CACN,kBAAkB;;;;;;CAMlB,aAAa;;;;;;;CAOb,gBAAgB;;;;;CAKhB,MAAM;;;;;CAKN,YAAY;;CAEZ,MAAM,OAAO,OAAO;EAClB,OAAO;EACP,aAAa;EACb,WAAW,OAAO,OAAO,WAAW;EACpC,WAAW,OAAO,OAAO,WAAW;EACpC,YAAY,OAAO,OAAO,WAAW;CACvC,CAAC;AACH,CAAC,CAAC,CAAC,CAAC"}
|