effect-browser 0.3.0-beta.14 → 0.3.0-beta.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +24 -11
  2. package/dist/{Browser-BBSySyjT.mjs → Browser-DRPthkNO.mjs} +4 -4
  3. package/dist/Browser-DRPthkNO.mjs.map +1 -0
  4. package/dist/Browser.d.mts +2 -2
  5. package/dist/Browser.mjs +1 -1
  6. package/dist/{BrowserEvent-BRu2juEz.d.mts → BrowserEvent-dq6FRT8w.d.mts} +9 -9
  7. package/dist/BrowserEvent.d.mts +1 -1
  8. package/dist/BrowserEvent.mjs +7 -12
  9. package/dist/BrowserEvent.mjs.map +1 -1
  10. package/dist/Cdp.mjs +2 -2
  11. package/dist/{Change-iMlcuzVD.d.mts → Change-DqING3tr.d.mts} +2 -2
  12. package/dist/Change.d.mts +1 -1
  13. package/dist/Chromium.mjs +2 -2
  14. package/dist/Expect.d.mts +1 -1
  15. package/dist/Expect.mjs +2 -2
  16. package/dist/Moment.d.mts +1 -1
  17. package/dist/Moment.mjs +1 -1
  18. package/dist/Motion-DND6I-64.d.mts +40 -0
  19. package/dist/Motion.d.mts +2 -40
  20. package/dist/Motion.mjs +1 -2
  21. package/dist/Motion.mjs.map +1 -1
  22. package/dist/{Page-B5cjaUp5.mjs → Page-C_VkBVwI.mjs} +5 -9
  23. package/dist/Page-C_VkBVwI.mjs.map +1 -0
  24. package/dist/{Page-DL9eylp3.d.mts → Page-jHmSJeOS.d.mts} +6 -13
  25. package/dist/Page.d.mts +1 -1
  26. package/dist/Page.mjs +1 -1
  27. package/dist/{Plan-6As6vcwT.d.mts → Plan-DLtRksuu.d.mts} +3 -3
  28. package/dist/{Plan-CXA2BW-G.mjs → Plan-X-JkACAB.mjs} +6 -9
  29. package/dist/Plan-X-JkACAB.mjs.map +1 -0
  30. package/dist/Plan.d.mts +1 -1
  31. package/dist/Plan.mjs +1 -1
  32. package/dist/Policy.d.mts +1 -1
  33. package/dist/Policy.mjs +1 -1
  34. package/dist/Presentation.d.mts +2 -2
  35. package/dist/Presentation.mjs +3 -2
  36. package/dist/Presentation.mjs.map +1 -1
  37. package/dist/Stage.d.mts +1 -1
  38. package/dist/Stage.mjs +3 -3
  39. package/dist/Stage.mjs.map +1 -1
  40. package/dist/{Supervisor-BE2sGHBK.mjs → Supervisor-BgWP8o9t.mjs} +116 -66
  41. package/dist/Supervisor-BgWP8o9t.mjs.map +1 -0
  42. package/dist/{Supervisor-W60pZWHh.d.mts → Supervisor-mVPeEUp8.d.mts} +33 -12
  43. package/dist/Supervisor.d.mts +2 -2
  44. package/dist/Supervisor.mjs +2 -2
  45. package/dist/{context-BAjRj7Xo.mjs → context-rYTk-3Cv.mjs} +68 -3
  46. package/dist/context-rYTk-3Cv.mjs.map +1 -0
  47. package/dist/index.d.mts +6 -6
  48. package/dist/index.mjs +4 -4
  49. package/dist/match.inpage-xOe9LNO0.mjs.map +1 -1
  50. package/dist/{page-B92QnRfT.mjs → page-ClEMFnBG.mjs} +48 -110
  51. package/dist/page-ClEMFnBG.mjs.map +1 -0
  52. package/package.json +1 -1
  53. package/src/Browser.ts +1 -1
  54. package/src/BrowserEvent.ts +7 -12
  55. package/src/Motion.ts +1 -2
  56. package/src/Page.ts +5 -9
  57. package/src/Plan.ts +1 -2
  58. package/src/Presentation.ts +2 -1
  59. package/src/Stage.ts +2 -1
  60. package/src/Supervisor.ts +168 -166
  61. package/src/internal/input/actions.ts +25 -33
  62. package/src/internal/input/dispatch.ts +3 -4
  63. package/src/internal/input/edit.inpage.ts +3 -9
  64. package/src/internal/input/evidence.inpage.ts +2 -20
  65. package/src/internal/input/guard.inpage.ts +9 -29
  66. package/src/internal/input/guard.ts +12 -1
  67. package/src/internal/input/targets.inpage.ts +4 -8
  68. package/src/internal/input/targets.ts +8 -11
  69. package/src/internal/page/context.ts +2 -2
  70. package/src/internal/pictures/capture.ts +4 -4
  71. package/src/internal/pictures/clock.ts +8 -3
  72. package/src/internal/pictures/pictures.ts +2 -1
  73. package/src/internal/reading/controls.inpage.ts +8 -1
  74. package/src/internal/reading/match.inpage.ts +2 -1
  75. package/src/internal/reading/outline.inpage.ts +7 -4
  76. package/src/internal/reading/reading.ts +5 -16
  77. package/src/internal/supervisor/lifecycle.ts +73 -20
  78. package/dist/Browser-BBSySyjT.mjs.map +0 -1
  79. package/dist/Page-B5cjaUp5.mjs.map +0 -1
  80. package/dist/Plan-CXA2BW-G.mjs.map +0 -1
  81. package/dist/Supervisor-BE2sGHBK.mjs.map +0 -1
  82. package/dist/context-BAjRj7Xo.mjs.map +0 -1
  83. package/dist/page-B92QnRfT.mjs.map +0 -1
@@ -1,10 +1,10 @@
1
- import { Plan } from "./Motion.mjs";
1
+ import { Plan, Point } from "./Motion.mjs";
2
2
  import { Action, Box, CursorChanged, KeyChanged, Navigated, PageLoaded, PointerPressed, PointerReleased, Subject, SubjectContext, TextInserted, TrackEvent, TrackPerformed, TrackPlanned, WheelScrolled } from "./BrowserEvent.mjs";
3
3
  import { BrowserError, Failed, InvalidRequest, NavigationFailed, NotActionable, NotFound, PolicyTimeout, StaleRef, Timeout } from "./BrowserError.mjs";
4
- import { a as make$20, c as Current, i as failWith, l as make$19, n as contextGone, o as reasonOf, r as decodeWith, s as undispatched } from "./context-BAjRj7Xo.mjs";
4
+ import { a as make$20, c as estimate, d as toBrowserSeconds, f as toHostTime, h as make$19, i as failWith, m as Current, n as contextGone, o as reasonOf, p as uncertaintyAt, r as decodeWith, s as undispatched, u as monotonicMillis } from "./context-rYTk-3Cv.mjs";
5
5
  import { i as redact, n as parse, s as Correlation, t as addresses } from "./url-Cd04Okid.mjs";
6
6
  import { BrowserPaint, CaptureStats, Frame, Image, Screenshot } from "./Frame.mjs";
7
- import { _ as evidence, c as State, g as guard, h as ValidatedInputResultSchema, i as InputRequest, l as Text, m as PreparedInputResultSchema, o as Region, p as redacted, r as Found, s as ResolvedTarget, u as Zoom } from "./Page-B5cjaUp5.mjs";
7
+ import { _ as evidence, c as State, g as guard, h as ValidatedInputResultSchema, i as InputRequest, l as Text, m as PreparedInputResultSchema, o as Region, p as redacted, r as Found, s as ResolvedTarget, u as Zoom } from "./Page-C_VkBVwI.mjs";
8
8
  import { Snapshot } from "./Snapshot.mjs";
9
9
  import { t as match } from "./match.inpage-xOe9LNO0.mjs";
10
10
  import { r as Changes, t as Change } from "./Change-DNvztNLu.mjs";
@@ -333,8 +333,7 @@ const targets = (names, walked, placing) => {
333
333
  };
334
334
  };
335
335
  const ResolvedPointSchema = Schema.Struct({
336
- x: Schema.Finite,
337
- y: Schema.Finite,
336
+ ...Point.fields,
338
337
  element: Schema.String,
339
338
  tag: Schema.String,
340
339
  role: Schema.NullOr(Schema.String),
@@ -356,8 +355,7 @@ const PointResultSchema = Schema.Union([ResolvedPointSchema, Schema.Struct({
356
355
  detail: Schema.String
357
356
  })]);
358
357
  const ScrollPlanSchema = Schema.NullOr(Schema.Struct({
359
- x: Schema.Finite,
360
- y: Schema.Finite,
358
+ ...Point.fields,
361
359
  dx: Schema.Finite,
362
360
  dy: Schema.Finite
363
361
  }));
@@ -464,6 +462,11 @@ const context = (names, walked) => {
464
462
  };
465
463
  //#endregion
466
464
  //#region src/internal/reading/controls.inpage.ts
465
+ /**
466
+ * In the page: a control's states and value as the outline shows them, and as a value; the elements a CSS selector scopes a
467
+ * read to; and a condition `Page.waitFor` waits for. See `names.inpage.ts` for what a page-side part
468
+ * may use.
469
+ */
467
470
  const controls = (names, walked, subjects, texts) => {
468
471
  const { clean, isDisabled, isHtml, isInput, isSelect, isTextArea, refFor, textOf } = names;
469
472
  const { visible } = walked;
@@ -553,6 +556,7 @@ const controls = (names, walked, subjects, texts) => {
553
556
  waitUntil
554
557
  };
555
558
  };
559
+ const ConditionResultSchema = Schema.Union([Schema.Struct({ met: Schema.Boolean }), Schema.Struct({ invalid: Schema.String })]);
556
560
  //#endregion
557
561
  //#region src/internal/reading/expect.inpage.ts
558
562
  const expectations = (names, subjected) => {
@@ -942,6 +946,10 @@ const outline = (names, walked, subjects, texts, controlling, url) => {
942
946
  viewport
943
947
  };
944
948
  };
949
+ const SnapshotResultSchema = Schema.Union([Schema.Struct({
950
+ snapshot: Snapshot,
951
+ nextRef: Schema.Finite
952
+ }), Schema.Struct({ invalid: Schema.String })]);
945
953
  const ViewportResultSchema = Schema.Struct({
946
954
  width: Schema.Finite,
947
955
  height: Schema.Finite
@@ -2284,68 +2292,6 @@ const make$18 = Effect.fnUntraced(function* (page) {
2284
2292
  };
2285
2293
  });
2286
2294
  //#endregion
2287
- //#region src/internal/pictures/clock.ts
2288
- /**
2289
- * The browser's clock read on the owner's: estimates of their offset from timed probes, how an
2290
- * estimate ages, and the one mapping a browser's pages share. `pictures.ts` takes the probes.
2291
- */
2292
- /** The fastest complete probe limits uncertainty without mistaking transit delay for clock offset. */
2293
- const estimate = (probes) => {
2294
- let best;
2295
- for (const probe of probes) {
2296
- const roundTripMillis = probe.hostEnd - probe.hostStart;
2297
- if (!Number.isFinite(probe.hostStart) || !Number.isFinite(probe.hostEnd) || !Number.isFinite(probe.browserTime) || !Number.isFinite(roundTripMillis) || roundTripMillis < 0) continue;
2298
- const sampledAt = probe.hostStart + roundTripMillis / 2;
2299
- const offsetMillis = probe.browserTime - sampledAt;
2300
- if (!Number.isFinite(offsetMillis) || !Number.isFinite(probe.browserTime - probe.hostStart) || !Number.isFinite(probe.browserTime - probe.hostEnd)) continue;
2301
- if (best === void 0 || roundTripMillis < best.roundTripMillis) best = {
2302
- offsetMillis,
2303
- uncertaintyMillis: roundTripMillis / 2,
2304
- roundTripMillis,
2305
- sampledAt
2306
- };
2307
- }
2308
- return Option.fromUndefinedOr(best);
2309
- };
2310
- const driftPerMillis = 1e-4;
2311
- /** An estimate's uncertainty at `hostTime`, wider the further that is from when it was sampled. */
2312
- const uncertaintyAt = (estimate, hostTime) => estimate.uncertaintyMillis + Math.abs(hostTime - estimate.sampledAt) * driftPerMillis;
2313
- const renewAfter = Duration.seconds(10);
2314
- /**
2315
- * Whether a new measurement should replace the current estimate. Each interval contains the true
2316
- * offset, so overlapping intervals agree and the narrower one is kept, the current one widened by
2317
- * its age: a probe delayed behind a busy page cannot widen every tab's stamps. A disjoint
2318
- * measurement means the clocks moved (a wall clock step, or drift between a remote browser and
2319
- * this host), so the newer evidence wins.
2320
- */
2321
- const supersedes = (next, current) => {
2322
- const aged = uncertaintyAt(current, next.sampledAt);
2323
- return next.uncertaintyMillis <= aged || Math.abs(next.offsetMillis - current.offsetMillis) > next.uncertaintyMillis + aged;
2324
- };
2325
- /**
2326
- * Every renderer of a browser reads the same host wall clock, so the offset belongs to the
2327
- * browser rather than a page. A busy page cannot fail work that an earlier estimate can serve.
2328
- */
2329
- const mapping = (now) => {
2330
- let latest;
2331
- let measuredAt = Number.NEGATIVE_INFINITY;
2332
- const adopt = (measure) => {
2333
- measuredAt = now();
2334
- return measure.pipe(Effect.map((estimate) => {
2335
- if (latest === void 0 || supersedes(estimate, latest)) latest = estimate;
2336
- return latest;
2337
- }));
2338
- };
2339
- return {
2340
- latest: () => latest,
2341
- current: (measure) => Effect.suspend(() => latest === void 0 ? adopt(measure) : Effect.succeed(latest)),
2342
- renew: (measure) => Effect.suspend(() => latest === void 0 || now() - measuredAt < Duration.toMillis(renewAfter) ? Effect.void : Effect.ignore(adopt(measure)))
2343
- };
2344
- };
2345
- const toHostTime = (calibration, browserEpochMillis) => browserEpochMillis - calibration.offsetMillis;
2346
- /** CDP input timestamps use seconds, unlike browser frame timestamps and the owner's clock. */
2347
- const toBrowserSeconds = (calibration, hostMillis) => (hostMillis + calibration.offsetMillis) / 1e3;
2348
- //#endregion
2349
2295
  //#region src/internal/input/dispatch.ts
2350
2296
  /**
2351
2297
  * Sending input to the browser. Each mouse event, key and inserted text goes out on the page's
@@ -2453,6 +2399,8 @@ const make$17 = (page) => {
2453
2399
  * policy decides on, binds an approval to the document and targets it saw, and runs the page
2454
2400
  * script's changes in the approved document only.
2455
2401
  */
2402
+ /** Recheck an approval, after any pending input it must see; neither runs without a guard. */
2403
+ const check = (approval, options = {}, before = Effect.void) => approval === void 0 ? Effect.void : before.pipe(Effect.andThen(approval.check(options)));
2456
2404
  const inputFailure = (operation, targets, failure) => {
2457
2405
  const target = failure.index === void 0 ? void 0 : targets[failure.index];
2458
2406
  return failWith(operation, failure.error === "outside" ? new InvalidRequest({ detail: failure.detail }) : failure.error === "stale" && typeof target === "string" ? new StaleRef({ ref: target }) : new NotActionable({ detail: failure.detail }));
@@ -2511,9 +2459,12 @@ const make$16 = (page, bridge) => {
2511
2459
  };
2512
2460
  });
2513
2461
  const mutate = (operation, call, approval, mayHaveRun = Effect.void) => (approval === void 0 ? current(operation) : Effect.succeed(approval.contextId)).pipe(Effect.flatMap((contextId) => evaluateIn(operation, call, contextId).pipe(Effect.onInterrupt(() => mayHaveRun), Effect.tapError((error) => error.reason._tag === "Failed" && /Cannot find context|__effectBrowser/i.test(error.reason.detail) ? Effect.void : mayHaveRun))), Effect.catchIf(contextGone, () => failWith(operation, new NotActionable({ detail: "the page changed before the approved input could run" }))));
2462
+ /** A read may follow the current document only when no approval binds it to one. */
2463
+ const evaluate = (operation, call, approval) => approval === void 0 ? bridge.evaluate(operation, call) : mutate(operation, call, approval);
2514
2464
  return {
2515
2465
  preparePolicy,
2516
- mutate
2466
+ mutate,
2467
+ evaluate
2517
2468
  };
2518
2469
  };
2519
2470
  //#endregion
@@ -3196,12 +3147,11 @@ const resolvedTarget = (result) => new ResolvedTarget({
3196
3147
  cursor: result.cursor,
3197
3148
  ...result.href === void 0 ? {} : { href: result.href }
3198
3149
  });
3199
- const make$11 = (bridge, viewport, guard, pointer, dispatch, settling) => {
3200
- const { evaluate } = bridge;
3201
- const { mutate } = guard;
3150
+ const make$11 = (viewport, guard, pointer, dispatch, settling) => {
3151
+ const { evaluate, mutate } = guard;
3202
3152
  const { moveTo, wheel } = pointer;
3203
3153
  const { flush } = dispatch;
3204
- const readPoint = (operation, target, approval, scroll) => (approval === void 0 ? evaluate(operation, scriptCall("point", target, scroll)) : mutate(operation, scriptCall("point", target, scroll), approval)).pipe(Effect.flatMap(decodeWith(operation, PointResultSchema)));
3154
+ const readPoint = (operation, target, approval, scroll) => evaluate(operation, scriptCall("point", target, scroll), approval).pipe(Effect.flatMap(decodeWith(operation, PointResultSchema)));
3205
3155
  const resolve = (operation, target, approval, scroll = true) => {
3206
3156
  if (typeof target === "string" && !/^e\d+$/.test(target)) return failWith(operation, new InvalidRequest({ detail: target + " is not a ref; refs look like e12" }));
3207
3157
  if (typeof target !== "string" && (!Number.isFinite(target.x) || !Number.isFinite(target.y))) return failWith(operation, new InvalidRequest({ detail: "point coordinates must be finite" }));
@@ -3228,13 +3178,13 @@ const make$11 = (bridge, viewport, guard, pointer, dispatch, settling) => {
3228
3178
  yield* wheel(operation, marks, point, Math.max(-size.width * .9, Math.min(size.width * .9, plan.dx)), Math.max(-size.height * .9, Math.min(size.height * .9, plan.dy)));
3229
3179
  yield* flush(operation, marks.input);
3230
3180
  yield* settling.settle(operation, before);
3231
- if (approval !== void 0) yield* approval.check();
3181
+ yield* check(approval);
3232
3182
  }
3233
3183
  yield* marks.touched;
3234
3184
  const before = settling.mark();
3235
3185
  yield* resolve(operation, target, approval);
3236
3186
  yield* settling.settle(operation, before);
3237
- if (approval !== void 0) yield* approval.check();
3187
+ yield* check(approval);
3238
3188
  return yield* resolve(operation, target, approval, false);
3239
3189
  })
3240
3190
  };
@@ -3260,12 +3210,11 @@ const partsOf = (page, bridge, viewport) => {
3260
3210
  const settling = make$12(page, bridge);
3261
3211
  return {
3262
3212
  page,
3263
- bridge,
3264
3213
  ...settling,
3265
3214
  viewportFor: viewport.viewportFor,
3266
3215
  perform: make$14(page, dispatch),
3267
3216
  ...guard,
3268
- ...make$11(bridge, viewport, guard, pointer, dispatch, settling),
3217
+ ...make$11(viewport, guard, pointer, dispatch, settling),
3269
3218
  ...pointer,
3270
3219
  ...make$15(page, bridge, dispatch),
3271
3220
  sendMouse: dispatch.sendMouse,
@@ -3303,20 +3252,17 @@ const click = (input) => {
3303
3252
  yield* marks.at(point);
3304
3253
  yield* marks.on(resolved);
3305
3254
  yield* moveTo("click", marks, point, resolved.cursor);
3306
- if (approval !== void 0) yield* approval.check({ presses: [{
3255
+ yield* check(approval, { presses: [{
3307
3256
  index: 0,
3308
3257
  ...point
3309
3258
  }] });
3310
3259
  const before = mark();
3311
3260
  yield* marks.sent;
3312
3261
  for (let index = 1; index <= count; index++) {
3313
- if (approval !== void 0 && index > 1) {
3314
- yield* flush("click", marks.input);
3315
- yield* approval.check({ presses: [{
3316
- index: 0,
3317
- ...point
3318
- }] }).pipe(Effect.catchIf((error) => error.reason._tag === "StaleRef", () => failWith("click", new NotActionable({ detail: "an earlier click removed the approved target, so no further press was sent" }))));
3319
- }
3262
+ if (index > 1) yield* check(approval, { presses: [{
3263
+ index: 0,
3264
+ ...point
3265
+ }] }, flush("click", marks.input)).pipe(Effect.catchIf((error) => error.reason._tag === "StaleRef", () => failWith("click", new NotActionable({ detail: "an earlier click removed the approved target, so no further press was sent" }))));
3320
3266
  yield* sendMouse("click", marks.input, {
3321
3267
  type: "mousePressed",
3322
3268
  ...point,
@@ -3375,7 +3321,7 @@ const drag = (input) => {
3375
3321
  yield* marks.at(end.point);
3376
3322
  yield* marks.on(start, end);
3377
3323
  yield* moveTo("drag", marks, start.point, start.cursor);
3378
- if (approval !== void 0) yield* approval.check({ presses: [{
3324
+ yield* check(approval, { presses: [{
3379
3325
  index: 0,
3380
3326
  ...start.point
3381
3327
  }, {
@@ -3403,7 +3349,7 @@ const drag = (input) => {
3403
3349
  };
3404
3350
  const typeText = (input) => {
3405
3351
  const { settings, now } = input.page;
3406
- const { perform, preparePolicy, mutate, targetFor, moveTo, sendMouse, flush, bridge } = input;
3352
+ const { perform, preparePolicy, mutate, targetFor, moveTo, sendMouse, flush, evaluate } = input;
3407
3353
  const { currentDocument, sameDocument, keyStroke, typeEvent, mark, settle } = input;
3408
3354
  return (text, typeOptions = {}, style = plain) => perform("type", {
3409
3355
  target: typeOptions.into,
@@ -3421,7 +3367,7 @@ const typeText = (input) => {
3421
3367
  const into = typeOptions.into;
3422
3368
  if (into !== void 0 && !/^e\d+$/.test(into)) return yield* failWith("type", new InvalidRequest({ detail: `"${into}" is not a ref; refs look like e12` }));
3423
3369
  const asked = scriptCall("typeable", into ?? null, typeOptions.secret === true);
3424
- const typeable = yield* (approval === void 0 ? bridge.evaluate("type", asked) : mutate("type", asked, approval)).pipe(Effect.flatMap(decodeWith("type", TypeableResultSchema)));
3370
+ const typeable = yield* evaluate("type", asked, approval).pipe(Effect.flatMap(decodeWith("type", TypeableResultSchema)));
3425
3371
  if ("error" in typeable) return yield* failWith("type", typeable.error === "stale" && into !== void 0 ? new StaleRef({ ref: into }) : new NotActionable({ detail: typeable.detail }));
3426
3372
  if (typeable.subject !== void 0) yield* marks.on(typeable.subject);
3427
3373
  const since = yield* currentDocument("type");
@@ -3432,7 +3378,7 @@ const typeText = (input) => {
3432
3378
  yield* marks.on(target);
3433
3379
  if (marks.style.shown) {
3434
3380
  yield* moveTo("type", marks, target.point, target.cursor);
3435
- if (approval !== void 0) yield* approval.check({ presses: [{
3381
+ yield* check(approval, { presses: [{
3436
3382
  index: 0,
3437
3383
  ...target.point
3438
3384
  }] });
@@ -3452,9 +3398,9 @@ const typeText = (input) => {
3452
3398
  secret ||= focused.secret;
3453
3399
  }
3454
3400
  if (!secret) yield* marks.reveal;
3455
- if (approval !== void 0) yield* approval.check({ focused: true });
3401
+ yield* check(approval, { focused: true });
3456
3402
  yield* marks.sent;
3457
- const focusHeld = approval === void 0 ? Effect.void : flush("type", marks.input).pipe(Effect.andThen(approval.check({ focused: true })));
3403
+ const focusHeld = check(approval, { focused: true }, flush("type", marks.input));
3458
3404
  if (text === "" && replace && into !== void 0) {
3459
3405
  yield* sameDocument("type", since);
3460
3406
  yield* keyStroke("type", marks.input, ["Delete"]);
@@ -3475,7 +3421,7 @@ const typeText = (input) => {
3475
3421
  }
3476
3422
  yield* flush("type", marks.input);
3477
3423
  if (typeOptions.submit === true) {
3478
- if (approval !== void 0) yield* approval.check({ focused: true });
3424
+ yield* check(approval, { focused: true });
3479
3425
  yield* sameDocument("type", since);
3480
3426
  const before = mark();
3481
3427
  yield* keyStroke("type", marks.input, ["Enter"]);
@@ -3508,16 +3454,13 @@ const press = (input) => {
3508
3454
  yield* marks.on(yield* targetFor("press", on, approval, marks));
3509
3455
  const focused = yield* mutate("press", scriptCall("focusOn", on), approval).pipe(Effect.flatMap(decodeWith("press", EditResultSchema)));
3510
3456
  if ("error" in focused) return yield* editFailure("press", on, focused);
3511
- if (approval !== void 0) yield* approval.check({ focused: true });
3457
+ yield* check(approval, { focused: true });
3512
3458
  }
3513
3459
  const before = mark();
3514
3460
  let due = now();
3515
3461
  yield* marks.sent;
3516
3462
  for (let index = 0; index < times; index++) {
3517
- if (index > 0 && approval !== void 0 && activates) {
3518
- yield* flush("press", marks.input);
3519
- yield* approval.check({ focused: true });
3520
- }
3463
+ if (index > 0 && activates) yield* check(approval, { focused: true }, flush("press", marks.input));
3521
3464
  yield* sameDocument("press", since);
3522
3465
  yield* keyStroke("press", marks.input, parts, hold);
3523
3466
  if (index + 1 < times) {
@@ -3765,7 +3708,7 @@ const timed = (options, native, timestamp, generation) => {
3765
3708
  hostTime,
3766
3709
  uncertaintyMillis: uncertaintyAt(estimate, hostTime)
3767
3710
  }),
3768
- receivedAt: Number(options.clock.monotonicTimeNanosUnsafe()) / 1e6,
3711
+ receivedAt: monotonicMillis(options.clock),
3769
3712
  width: size.width,
3770
3713
  height: size.height,
3771
3714
  ...generation.transport.frameTag()
@@ -3811,7 +3754,7 @@ const sizeFilter = (options, deliver, drop) => Effect.gen(function* () {
3811
3754
  run = void 0;
3812
3755
  Queue.offerUnsafe(wake, void 0);
3813
3756
  };
3814
- const now = () => Number(options.clock.monotonicTimeNanosUnsafe()) / 1e6;
3757
+ const now = () => monotonicMillis(options.clock);
3815
3758
  const adopt = (adopted) => {
3816
3759
  run = void 0;
3817
3760
  expected = adopted.device;
@@ -3954,7 +3897,7 @@ const make$8 = (options) => Effect.gen(function* () {
3954
3897
  let latest = Option.none();
3955
3898
  let history = [];
3956
3899
  const keepMillis = Duration.toMillis(options.frameHistory);
3957
- const now = () => Number(options.clock.monotonicTimeNanosUnsafe()) / 1e6;
3900
+ const now = () => monotonicMillis(options.clock);
3958
3901
  const counts = tally(now);
3959
3902
  let delivered = 0;
3960
3903
  const current = (frame) => isCurrent(frame, generation, latest);
@@ -4578,10 +4521,6 @@ const make$7 = Effect.fnUntraced(function* (page, bridge, viewport) {
4578
4521
  * read takes its turn on the page and shares its work with identical reads, as `lane.ts`
4579
4522
  * describes. The viewport's text as it was last read is kept, for `Page.state`.
4580
4523
  */
4581
- const SnapshotResult = Schema.Union([Schema.Struct({
4582
- snapshot: Snapshot,
4583
- nextRef: Schema.Finite
4584
- }), Schema.Struct({ invalid: Schema.String })]);
4585
4524
  const FindResults = Schema.Struct({
4586
4525
  found: Schema.Array(Found),
4587
4526
  nextRef: Schema.Finite
@@ -4590,7 +4529,6 @@ const UntilResult = Schema.Struct({
4590
4529
  met: Schema.Boolean,
4591
4530
  mark: Schema.String
4592
4531
  });
4593
- const ConditionResult = Schema.Union([Schema.Struct({ met: Schema.Boolean }), Schema.Struct({ invalid: Schema.String })]);
4594
4532
  const wanted = (value) => value === void 0 ? null : typeof value === "string" ? value : {
4595
4533
  source: value.source,
4596
4534
  flags: value.flags
@@ -4625,7 +4563,7 @@ const make$6 = Effect.fnUntraced(function* (page, bridge) {
4625
4563
  ...asked,
4626
4564
  firstRef: yield* Ref.get(nextRef)
4627
4565
  };
4628
- const result = yield* evaluate("snapshot", scriptCall("snapshot", request)).pipe(Effect.flatMap(decodeWith("snapshot", SnapshotResult)));
4566
+ const result = yield* evaluate("snapshot", scriptCall("snapshot", request)).pipe(Effect.flatMap(decodeWith("snapshot", SnapshotResultSchema)));
4629
4567
  if ("invalid" in result) return yield* failWith("snapshot", new InvalidRequest({ detail: result.invalid }));
4630
4568
  const { text, truncated, url } = result.snapshot;
4631
4569
  yield* counted(result.nextRef);
@@ -4686,7 +4624,7 @@ const make$6 = Effect.fnUntraced(function* (page, bridge) {
4686
4624
  };
4687
4625
  const millis = Math.min(Duration.toMillis(timeout), Number.MAX_SAFE_INTEGER);
4688
4626
  const unmet = () => failWith("waitFor", new Timeout({ millis }));
4689
- const look = evaluate("waitFor", scriptCall("waitUntil", request, millis)).pipe(Effect.flatMap(decodeWith("waitFor", ConditionResult)), Effect.flatMap((result) => "invalid" in result ? failWith("waitFor", new InvalidRequest({ detail: result.invalid })) : result.met ? Effect.void : unmet()));
4627
+ const look = evaluate("waitFor", scriptCall("waitUntil", request, millis)).pipe(Effect.flatMap(decodeWith("waitFor", ConditionResultSchema)), Effect.flatMap((result) => "invalid" in result ? failWith("waitFor", new InvalidRequest({ detail: result.invalid })) : result.met ? Effect.void : unmet()));
4690
4628
  return lane.read("waitFor")(Effect.void).pipe(Effect.andThen(Effect.retry(look, { while: contextGone })), Effect.timeoutOrElse({
4691
4629
  duration: timeout,
4692
4630
  orElse: unmet
@@ -5099,6 +5037,6 @@ const make = Effect.fnUntraced(function* (options) {
5099
5037
  return Object.assign(new Built(internals), assembled);
5100
5038
  });
5101
5039
  //#endregion
5102
- export { performed as a, pause as i, make as n, mapping as o, viewOf as r, internalsOf as t };
5040
+ export { performed as a, pause as i, make as n, viewOf as r, internalsOf as t };
5103
5041
 
5104
- //# sourceMappingURL=page-B92QnRfT.mjs.map
5042
+ //# sourceMappingURL=page-ClEMFnBG.mjs.map