effect-browser 0.3.0-beta.15 → 0.3.0-beta.19
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 +18 -6
- package/dist/{Browser-BBSySyjT.mjs → Browser-H63wiekr.mjs} +5 -5
- package/dist/Browser-H63wiekr.mjs.map +1 -0
- package/dist/Browser.d.mts +2 -2
- package/dist/Browser.mjs +1 -1
- package/dist/{BrowserEvent-BRu2juEz.d.mts → BrowserEvent-dq6FRT8w.d.mts} +9 -9
- package/dist/BrowserEvent.d.mts +1 -1
- package/dist/BrowserEvent.mjs +7 -12
- package/dist/BrowserEvent.mjs.map +1 -1
- package/dist/Cdp.mjs +2 -2
- package/dist/{Change-iMlcuzVD.d.mts → Change-DqING3tr.d.mts} +2 -2
- package/dist/Change.d.mts +1 -1
- package/dist/Chromium.mjs +2 -2
- package/dist/Expect.d.mts +1 -1
- package/dist/Expect.mjs +2 -2
- package/dist/Moment.d.mts +1 -1
- package/dist/Moment.mjs +3 -3
- package/dist/Moment.mjs.map +1 -1
- package/dist/Motion-DND6I-64.d.mts +40 -0
- package/dist/Motion.d.mts +2 -40
- package/dist/Motion.mjs +1 -2
- package/dist/Motion.mjs.map +1 -1
- package/dist/{Page-B5cjaUp5.mjs → Page-CfB6Zn1p.mjs} +7 -15
- package/dist/Page-CfB6Zn1p.mjs.map +1 -0
- package/dist/{Page-DL9eylp3.d.mts → Page-ku6j5t-v.d.mts} +23 -25
- package/dist/Page.d.mts +1 -1
- package/dist/Page.mjs +1 -1
- package/dist/{Plan-CXA2BW-G.mjs → Plan-C-d5QYS8.mjs} +6 -9
- package/dist/Plan-C-d5QYS8.mjs.map +1 -0
- package/dist/{Plan-6As6vcwT.d.mts → Plan-DJ4hEEna.d.mts} +3 -3
- package/dist/Plan.d.mts +1 -1
- package/dist/Plan.mjs +1 -1
- package/dist/Policy.d.mts +1 -1
- package/dist/Policy.mjs +1 -1
- package/dist/Presentation.d.mts +2 -2
- package/dist/Presentation.mjs +3 -2
- package/dist/Presentation.mjs.map +1 -1
- package/dist/Stage.d.mts +1 -1
- package/dist/Stage.mjs +8 -7
- package/dist/Stage.mjs.map +1 -1
- package/dist/{Supervisor-DaGlQVjv.mjs → Supervisor-2mPjIYYs.mjs} +44 -19
- package/dist/Supervisor-2mPjIYYs.mjs.map +1 -0
- package/dist/{Supervisor-5tZ47hR5.d.mts → Supervisor-mVPeEUp8.d.mts} +12 -5
- package/dist/Supervisor.d.mts +1 -1
- package/dist/Supervisor.mjs +1 -1
- package/dist/{context-BAjRj7Xo.mjs → context-w3NJPRLo.mjs} +81 -9
- package/dist/context-w3NJPRLo.mjs.map +1 -0
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +4 -4
- package/dist/match.inpage-xOe9LNO0.mjs.map +1 -1
- package/dist/{page-B92QnRfT.mjs → page-BKwfF6z-.mjs} +213 -218
- package/dist/page-BKwfF6z-.mjs.map +1 -0
- package/package.json +1 -1
- package/src/Browser.ts +1 -1
- package/src/BrowserEvent.ts +7 -12
- package/src/Moment.ts +3 -6
- package/src/Motion.ts +1 -2
- package/src/Page.ts +18 -20
- package/src/Plan.ts +1 -2
- package/src/Presentation.ts +2 -1
- package/src/Stage.ts +10 -17
- package/src/Supervisor.ts +9 -9
- package/src/internal/input/actions.ts +53 -97
- package/src/internal/input/dispatch.ts +25 -11
- package/src/internal/input/edit.inpage.ts +26 -11
- package/src/internal/input/evidence.inpage.ts +1 -21
- package/src/internal/input/guard.inpage.ts +9 -29
- package/src/internal/input/guard.ts +15 -10
- package/src/internal/input/perform.ts +14 -10
- package/src/internal/input/pointer.ts +3 -6
- package/src/internal/input/replies.ts +19 -8
- package/src/internal/input/settle.ts +3 -2
- package/src/internal/input/targets.inpage.ts +6 -13
- package/src/internal/input/targets.ts +13 -32
- package/src/internal/page/bridge.ts +2 -2
- package/src/internal/page/context.ts +15 -3
- package/src/internal/page/navigation.ts +3 -12
- package/src/internal/pictures/capture.ts +11 -4
- package/src/internal/pictures/clock.ts +8 -3
- package/src/internal/pictures/motion.ts +65 -0
- package/src/internal/pictures/pictures.ts +22 -17
- package/src/internal/pictures/utilsBundle.d.ts +9 -0
- package/src/internal/reading/controls.inpage.ts +8 -1
- package/src/internal/reading/match.inpage.ts +2 -1
- package/src/internal/reading/outline.inpage.ts +7 -4
- package/src/internal/reading/reading.ts +10 -25
- package/src/internal/reading/ready.ts +66 -14
- package/src/internal/supervisor/lifecycle.ts +56 -13
- package/src/internal/timeline/events.ts +5 -8
- package/src/internal/timeline/window.ts +3 -8
- package/dist/Browser-BBSySyjT.mjs.map +0 -1
- package/dist/Page-B5cjaUp5.mjs.map +0 -1
- package/dist/Plan-CXA2BW-G.mjs.map +0 -1
- package/dist/Supervisor-DaGlQVjv.mjs.map +0 -1
- package/dist/context-BAjRj7Xo.mjs.map +0 -1
- package/dist/page-B92QnRfT.mjs.map +0 -1
package/package.json
CHANGED
package/src/Browser.ts
CHANGED
|
@@ -492,7 +492,7 @@ export const make = Effect.fn("Browser.make")(function* (
|
|
|
492
492
|
) {
|
|
493
493
|
const clock = yield* Clock.Clock;
|
|
494
494
|
const connection = yield* Identity.make;
|
|
495
|
-
const now = () =>
|
|
495
|
+
const now = () => BrowserClock.monotonicMillis(clock);
|
|
496
496
|
const { settings, eventHistory, maxPages } = yield* settingsOf(options);
|
|
497
497
|
// Measured on first need: the first capture of any page measures it, and input never waits.
|
|
498
498
|
const mapping = BrowserClock.mapping(now);
|
package/src/BrowserEvent.ts
CHANGED
|
@@ -119,8 +119,7 @@ const Button = Schema.Literals(["left", "right", "middle"]);
|
|
|
119
119
|
|
|
120
120
|
/** An element's box in viewport CSS pixels; it may lie partly or wholly outside the viewport. */
|
|
121
121
|
export const Box = Schema.Struct({
|
|
122
|
-
|
|
123
|
-
y: Schema.Finite,
|
|
122
|
+
...Motion.Point.fields,
|
|
124
123
|
width: Schema.Finite,
|
|
125
124
|
height: Schema.Finite,
|
|
126
125
|
});
|
|
@@ -169,8 +168,8 @@ export class Action extends Schema.TaggedClass<Action>()("Action", {
|
|
|
169
168
|
/** For an action at a point, the box of what it found there. */
|
|
170
169
|
box: Schema.optional(Box),
|
|
171
170
|
text: Schema.optional(Schema.String),
|
|
172
|
-
x: Schema.optional(
|
|
173
|
-
y: Schema.optional(
|
|
171
|
+
x: Schema.optional(Motion.Point.fields.x),
|
|
172
|
+
y: Schema.optional(Motion.Point.fields.y),
|
|
174
173
|
ok: Schema.Boolean,
|
|
175
174
|
dispatched: Schema.Boolean,
|
|
176
175
|
error: Schema.optional(Schema.String),
|
|
@@ -196,16 +195,14 @@ export class TrackPerformed extends Schema.TaggedClass<TrackPerformed>()("TrackP
|
|
|
196
195
|
page: Schema.String,
|
|
197
196
|
plan: Sequence,
|
|
198
197
|
dispatched: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
199
|
-
|
|
200
|
-
y: Schema.Finite,
|
|
198
|
+
...Motion.Point.fields,
|
|
201
199
|
complete: Schema.Boolean,
|
|
202
200
|
}) {}
|
|
203
201
|
|
|
204
202
|
export class PointerPressed extends Schema.TaggedClass<PointerPressed>()("PointerPressed", {
|
|
205
203
|
at: Schema.Finite,
|
|
206
204
|
page: Schema.String,
|
|
207
|
-
|
|
208
|
-
y: Schema.Finite,
|
|
205
|
+
...Motion.Point.fields,
|
|
209
206
|
button: Button,
|
|
210
207
|
clickCount: Schema.Int.check(Schema.isGreaterThan(0)),
|
|
211
208
|
}) {}
|
|
@@ -213,8 +210,7 @@ export class PointerPressed extends Schema.TaggedClass<PointerPressed>()("Pointe
|
|
|
213
210
|
export class PointerReleased extends Schema.TaggedClass<PointerReleased>()("PointerReleased", {
|
|
214
211
|
at: Schema.Finite,
|
|
215
212
|
page: Schema.String,
|
|
216
|
-
|
|
217
|
-
y: Schema.Finite,
|
|
213
|
+
...Motion.Point.fields,
|
|
218
214
|
button: Button,
|
|
219
215
|
clickCount: Schema.Int.check(Schema.isGreaterThan(0)),
|
|
220
216
|
}) {}
|
|
@@ -222,8 +218,7 @@ export class PointerReleased extends Schema.TaggedClass<PointerReleased>()("Poin
|
|
|
222
218
|
export class WheelScrolled extends Schema.TaggedClass<WheelScrolled>()("WheelScrolled", {
|
|
223
219
|
at: Schema.Finite,
|
|
224
220
|
page: Schema.String,
|
|
225
|
-
|
|
226
|
-
y: Schema.Finite,
|
|
221
|
+
...Motion.Point.fields,
|
|
227
222
|
dx: Schema.Finite,
|
|
228
223
|
dy: Schema.Finite,
|
|
229
224
|
}) {}
|
package/src/Moment.ts
CHANGED
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
import { Duration, Effect, Option, Result, Schema } from "effect";
|
|
28
28
|
import { Prompt } from "effect/ai";
|
|
29
29
|
|
|
30
|
-
import { BrowserError
|
|
30
|
+
import { BrowserError } from "./BrowserError.ts";
|
|
31
31
|
import { type Action, BrowserEvent } from "./BrowserEvent.ts";
|
|
32
32
|
import { type Change, Changes } from "./Change.ts";
|
|
33
33
|
import { Frame } from "./Frame.ts";
|
|
34
|
-
import {
|
|
34
|
+
import { refuse } from "./internal/page/context.ts";
|
|
35
35
|
import { describe, named, quoted, where } from "./internal/timeline/words.ts";
|
|
36
36
|
import type * as Page from "./Page.ts";
|
|
37
37
|
import { Snapshot, type SnapshotOptions } from "./Snapshot.ts";
|
|
@@ -116,10 +116,7 @@ export const capture = Effect.fn("Moment.capture")(function* (
|
|
|
116
116
|
const count = options.frames ?? 2;
|
|
117
117
|
|
|
118
118
|
if (!Number.isSafeInteger(count) || count < 1)
|
|
119
|
-
return yield*
|
|
120
|
-
"moment",
|
|
121
|
-
new InvalidRequest({ detail: "frames must be a positive safe integer" }),
|
|
122
|
-
);
|
|
119
|
+
return yield* refuse("moment", "frames must be a positive safe integer");
|
|
123
120
|
const outline = options.snapshot ?? false;
|
|
124
121
|
|
|
125
122
|
// The picture comes first, at no call with a running screencast, and the window ends at its
|
package/src/Motion.ts
CHANGED
|
@@ -13,8 +13,7 @@ export const Point = Schema.Struct({ x: Schema.Finite, y: Schema.Finite });
|
|
|
13
13
|
export type Point = typeof Point.Type;
|
|
14
14
|
|
|
15
15
|
export const Sample = Schema.Struct({
|
|
16
|
-
|
|
17
|
-
y: Schema.Finite,
|
|
16
|
+
...Point.fields,
|
|
18
17
|
afterMillis: Schema.Finite.check(
|
|
19
18
|
Schema.isGreaterThanOrEqualTo(0),
|
|
20
19
|
Schema.isLessThanOrEqualTo(maximumDurationMillis),
|
package/src/Page.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { type Duration, Effect, Schema, type Stream } from "effect";
|
|
|
19
19
|
import type { Page as PlaywrightPage } from "playwright-core";
|
|
20
20
|
|
|
21
21
|
import { type BrowserError, type PolicyDenied } from "./BrowserError.ts";
|
|
22
|
-
import { Box, type BrowserEvent, PageLoaded, Subject
|
|
22
|
+
import { Box, type BrowserEvent, PageLoaded, Subject } from "./BrowserEvent.ts";
|
|
23
23
|
import type { Changes } from "./Change.ts";
|
|
24
24
|
import { type CaptureStats, Frame, Image, type ScreencastOptions } from "./Frame.ts";
|
|
25
25
|
import { FormFieldSchema } from "./internal/input/evidence.inpage.ts";
|
|
@@ -27,12 +27,10 @@ import * as Guard from "./internal/input/guard.inpage.ts";
|
|
|
27
27
|
import { Correlation, FailFast } from "./internal/page/lane.ts";
|
|
28
28
|
import * as Url from "./internal/page/url.ts";
|
|
29
29
|
import type { Window } from "./Moment.ts";
|
|
30
|
+
import * as Motion from "./Motion.ts";
|
|
30
31
|
import { type Snapshot, type SnapshotOptions } from "./Snapshot.ts";
|
|
31
32
|
|
|
32
|
-
export
|
|
33
|
-
readonly x: number;
|
|
34
|
-
readonly y: number;
|
|
35
|
-
}
|
|
33
|
+
export type Point = Motion.Point;
|
|
36
34
|
|
|
37
35
|
/** A ref from a snapshot, such as `"e12"`, or a viewport point. */
|
|
38
36
|
export type Target = string | Point;
|
|
@@ -54,13 +52,9 @@ export class Zoom extends Schema.Class<Zoom>("effect-browser/Zoom")({
|
|
|
54
52
|
|
|
55
53
|
/** The target as it read before input. Point coordinates are never snapped to another position. */
|
|
56
54
|
export class ResolvedTarget extends Schema.Class<ResolvedTarget>("effect-browser/ResolvedTarget")({
|
|
57
|
-
point:
|
|
55
|
+
point: Motion.Point,
|
|
56
|
+
...Subject.fields,
|
|
58
57
|
element: Schema.String,
|
|
59
|
-
/** The element's lowercase tag name. */
|
|
60
|
-
tag: Schema.String,
|
|
61
|
-
role: Schema.NullOr(Schema.String),
|
|
62
|
-
name: Schema.String,
|
|
63
|
-
context: SubjectContext,
|
|
64
58
|
/** For a point target, the box of what it found there. */
|
|
65
59
|
box: Schema.optional(Box),
|
|
66
60
|
cursor: Schema.String,
|
|
@@ -131,9 +125,7 @@ export interface ScreenshotOptions {
|
|
|
131
125
|
/** The oldest a reused frame may be, as for `frame`. Defaults to 250 milliseconds. */
|
|
132
126
|
readonly maxAge?: Duration.Input | undefined;
|
|
133
127
|
/** A region of the viewport, captured in CSS pixels at the viewport's own scale; always new. */
|
|
134
|
-
readonly clip?:
|
|
135
|
-
| { readonly x: number; readonly y: number; readonly width: number; readonly height: number }
|
|
136
|
-
| undefined;
|
|
128
|
+
readonly clip?: Box | undefined;
|
|
137
129
|
/** JPEG quality, 0 to 100. Defaults to 80. */
|
|
138
130
|
readonly quality?: number | undefined;
|
|
139
131
|
/** `"jpeg"`, the default, or `"png"`, which is always a new picture. */
|
|
@@ -226,8 +218,11 @@ export interface WaitCondition {
|
|
|
226
218
|
}
|
|
227
219
|
|
|
228
220
|
export interface ReadyOptions {
|
|
229
|
-
/**
|
|
230
|
-
|
|
221
|
+
/**
|
|
222
|
+
* What must stay still during quietMillis: screen paint (default); recorded content; or the
|
|
223
|
+
* `"foreground"`, the screen but for what was already moving before the page's latest input.
|
|
224
|
+
*/
|
|
225
|
+
readonly still?: "screen" | "content" | "foreground" | undefined;
|
|
231
226
|
/** How long the selected evidence must stay still; screen paint by default. */
|
|
232
227
|
readonly quietMillis?: number | undefined;
|
|
233
228
|
readonly timeout?: Duration.Input | undefined;
|
|
@@ -335,7 +330,7 @@ export class InputRequest extends Schema.Class<InputRequest>("effect-browser/Inp
|
|
|
335
330
|
target: Schema.optional(Schema.String),
|
|
336
331
|
element: Schema.optional(Schema.String),
|
|
337
332
|
/** Literal pixel targets only; ref coordinates are resolved after the policy allows them. */
|
|
338
|
-
point: Schema.optional(
|
|
333
|
+
point: Schema.optional(Motion.Point),
|
|
339
334
|
text: Schema.optional(Schema.String),
|
|
340
335
|
role: Schema.optional(Schema.NullOr(Schema.String)),
|
|
341
336
|
name: Schema.optional(Schema.String),
|
|
@@ -497,9 +492,12 @@ export interface Page {
|
|
|
497
492
|
* view have loaded, and the viewport shows something. With `quietMillis`, the screen must then
|
|
498
493
|
* also stay still that long: nothing in view changed, where the page's changes are recorded, and
|
|
499
494
|
* no frame comes, counted from the first frame of a capture the wait starts itself. A canvas
|
|
500
|
-
* that keeps drawing, such as a live chart, is never still
|
|
501
|
-
*
|
|
502
|
-
*
|
|
495
|
+
* that keeps drawing, such as a live chart, is never still. With `still: "foreground"`, frames
|
|
496
|
+
* may keep coming, but nothing may move in them outside what moved in the frames of the 1.5 s
|
|
497
|
+
* before the page's latest input, such as an idle animation; reels set spinning, or a counter
|
|
498
|
+
* set rolling, by the input keep the wait going. Without those frames, as where they are older
|
|
499
|
+
* than the browser's `frameHistory`, nothing may move at all. A page is never ready without a
|
|
500
|
+
* painted frame, as a hidden tab may be. `Timeout` after `timeout`, 15 seconds by default.
|
|
503
501
|
*/
|
|
504
502
|
readonly ready: (options?: ReadyOptions) => Effect.Effect<void, BrowserError>;
|
|
505
503
|
|
package/src/Plan.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from "./BrowserEvent.ts";
|
|
34
34
|
import { undispatched } from "./internal/page/context.ts";
|
|
35
35
|
import { Ambiguous, choose, Drifted, Missing } from "./internal/reading/choose.ts";
|
|
36
|
+
import { Point as ViewportPoint } from "./Motion.ts";
|
|
36
37
|
import {
|
|
37
38
|
type Found,
|
|
38
39
|
type Page,
|
|
@@ -44,8 +45,6 @@ import {
|
|
|
44
45
|
|
|
45
46
|
export { Ambiguous, Drifted, Missing } from "./internal/reading/choose.ts";
|
|
46
47
|
|
|
47
|
-
const ViewportPoint = Schema.Struct({ x: Schema.Finite, y: Schema.Finite });
|
|
48
|
-
|
|
49
48
|
export const StepAction = Schema.Literals([
|
|
50
49
|
"navigate",
|
|
51
50
|
"back",
|
package/src/Presentation.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { Clock, Duration, Effect, Fiber, MutableRef, Option, Semaphore } from "e
|
|
|
20
20
|
import type { BrowserError } from "./BrowserError.ts";
|
|
21
21
|
import * as Style from "./internal/input/style.ts";
|
|
22
22
|
import { type Internals, internalsOf, viewOf } from "./internal/page/page.ts";
|
|
23
|
+
import { monotonicMillis } from "./internal/pictures/clock.ts";
|
|
23
24
|
import * as Motion from "./Motion.ts";
|
|
24
25
|
import type { Page, Point, Target } from "./Page.ts";
|
|
25
26
|
|
|
@@ -81,7 +82,7 @@ export const make = Effect.fn("Presentation.make")(function* (options: Options =
|
|
|
81
82
|
const pacing = options.pacing ?? human;
|
|
82
83
|
const clock = yield* Clock.Clock;
|
|
83
84
|
const scope = yield* Effect.scope;
|
|
84
|
-
const now = () =>
|
|
85
|
+
const now = () => monotonicMillis(clock);
|
|
85
86
|
const pointer = MutableRef.make(Option.none<Point>());
|
|
86
87
|
const hand = yield* Semaphore.make(1);
|
|
87
88
|
|
package/src/Stage.ts
CHANGED
|
@@ -24,8 +24,9 @@ import {
|
|
|
24
24
|
|
|
25
25
|
import { type BrowserError, Closed, consequence, InvalidRequest, Timeout } from "./BrowserError.ts";
|
|
26
26
|
import type { CaptureStats, Frame, ScreencastOptions } from "./Frame.ts";
|
|
27
|
-
import { failWith, undispatched } from "./internal/page/context.ts";
|
|
27
|
+
import { failWith, refuse, undispatched } from "./internal/page/context.ts";
|
|
28
28
|
import { internalsOf } from "./internal/page/page.ts";
|
|
29
|
+
import { monotonicMillis } from "./internal/pictures/clock.ts";
|
|
29
30
|
import type { Page } from "./Page.ts";
|
|
30
31
|
|
|
31
32
|
export interface Options extends ScreencastOptions {
|
|
@@ -239,16 +240,14 @@ const evidence = (
|
|
|
239
240
|
|
|
240
241
|
const probe = Effect.gen(function* () {
|
|
241
242
|
yield* until(Math.max(checkedAt, current()?.changedAt ?? checkedAt) + millis, now);
|
|
242
|
-
checkedAt = now();
|
|
243
243
|
const before = current();
|
|
244
244
|
const frame = before?.frame;
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
)
|
|
246
|
+
// Paint during the wait moves the deadline; an early wake is not a silence check.
|
|
247
|
+
if (before !== undefined && now() - before.changedAt < millis)
|
|
248
|
+
return Option.none<Evidence>();
|
|
249
|
+
checkedAt = now();
|
|
250
|
+
if (before === undefined || frame === undefined || gone === before.feed)
|
|
252
251
|
return Option.none<Evidence>();
|
|
253
252
|
const { feed } = before;
|
|
254
253
|
|
|
@@ -390,7 +389,7 @@ export const make = Effect.fn("Stage.make")(function* (
|
|
|
390
389
|
): Effect.fn.Return<Stage, BrowserError, Scope.Scope> {
|
|
391
390
|
const clock = yield* Clock.Clock;
|
|
392
391
|
const owner = yield* Effect.scope;
|
|
393
|
-
const now = () =>
|
|
392
|
+
const now = () => monotonicMillis(clock);
|
|
394
393
|
const waited = Duration.fromInput(options.firstFrame ?? Duration.seconds(5));
|
|
395
394
|
|
|
396
395
|
if (
|
|
@@ -398,10 +397,7 @@ export const make = Effect.fn("Stage.make")(function* (
|
|
|
398
397
|
!Duration.isFinite(waited.value) ||
|
|
399
398
|
!Duration.isPositive(waited.value)
|
|
400
399
|
)
|
|
401
|
-
return yield*
|
|
402
|
-
"stage",
|
|
403
|
-
new InvalidRequest({ detail: "firstFrame must be a finite positive duration" }),
|
|
404
|
-
);
|
|
400
|
+
return yield* refuse("stage", "firstFrame must be a finite positive duration");
|
|
405
401
|
const firstFrame = waited.value;
|
|
406
402
|
const settings = { quality: options.quality, size: options.size };
|
|
407
403
|
const output = yield* PubSub.sliding<Paint>(16);
|
|
@@ -433,10 +429,7 @@ export const make = Effect.fn("Stage.make")(function* (
|
|
|
433
429
|
return switching(
|
|
434
430
|
Effect.gen(function* () {
|
|
435
431
|
if (!Number.isFinite(asked))
|
|
436
|
-
return yield*
|
|
437
|
-
"cue",
|
|
438
|
-
new InvalidRequest({ detail: "at must be finite host milliseconds" }),
|
|
439
|
-
);
|
|
432
|
+
return yield* refuse("cue", "at must be finite host milliseconds");
|
|
440
433
|
yield* firstOf(feed, firstFrame);
|
|
441
434
|
const old = showing;
|
|
442
435
|
|
package/src/Supervisor.ts
CHANGED
|
@@ -107,7 +107,8 @@ export interface Admission {
|
|
|
107
107
|
/**
|
|
108
108
|
* Optional service supplied during `open`. Providers report failed-attempt cleanup here before
|
|
109
109
|
* their scope closes; successful generations instead return `Opened.release`. Reporting does
|
|
110
|
-
* not release resources or replace the original acquisition failure.
|
|
110
|
+
* not release resources or replace the original acquisition failure. Terminal `Down` and opening
|
|
111
|
+
* `Closed` states publish the reported outcomes of their own generation's tries.
|
|
111
112
|
*/
|
|
112
113
|
export class Releasing extends Context.Service<
|
|
113
114
|
Releasing,
|
|
@@ -556,7 +557,7 @@ const makeScoped = Effect.fn("Supervisor.make")(function* <E, R, A>(
|
|
|
556
557
|
return yield* options.open.pipe(
|
|
557
558
|
Effect.provideService(Releasing, {
|
|
558
559
|
released: (released) =>
|
|
559
|
-
apply({ _tag: "AttemptReleased", released }).pipe(Effect.asVoid),
|
|
560
|
+
apply({ _tag: "AttemptReleased", number, released }).pipe(Effect.asVoid),
|
|
560
561
|
}),
|
|
561
562
|
);
|
|
562
563
|
}),
|
|
@@ -597,21 +598,20 @@ const makeScoped = Effect.fn("Supervisor.make")(function* <E, R, A>(
|
|
|
597
598
|
|
|
598
599
|
const retire = yield* Effect.cached(stop({ _tag: "Retire" }));
|
|
599
600
|
|
|
601
|
+
// The browser of the generation serving, or of the one `target` names once it serves.
|
|
602
|
+
const browserOf = (target?: number) =>
|
|
603
|
+
Effect.map(waitFor(state, waitTimeout, clock, target), (live) => live.value.opened.browser);
|
|
604
|
+
|
|
600
605
|
yield* Effect.addFinalizer(() => (options.keep === true ? stop({ _tag: "Keep" }) : retire));
|
|
601
606
|
yield* perform(started);
|
|
602
607
|
|
|
603
608
|
return {
|
|
604
|
-
browser:
|
|
609
|
+
browser: browserOf(),
|
|
605
610
|
use: leasing(state, apply, waitTimeout, now, clock),
|
|
606
611
|
states: Stream.fromPubSubTake(events),
|
|
607
612
|
rotate: apply({ _tag: "Rotate" }).pipe(
|
|
608
613
|
Effect.flatMap(({ reply }) =>
|
|
609
|
-
reply === undefined
|
|
610
|
-
? Effect.fail(retired())
|
|
611
|
-
: Effect.map(
|
|
612
|
-
waitFor(state, waitTimeout, clock, reply),
|
|
613
|
-
(live) => live.value.opened.browser,
|
|
614
|
-
),
|
|
614
|
+
reply === undefined ? Effect.fail(retired()) : browserOf(reply),
|
|
615
615
|
),
|
|
616
616
|
),
|
|
617
617
|
retire,
|