effect-browser 0.3.0-beta.5 → 0.3.0-beta.7

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 (47) hide show
  1. package/README.md +40 -3
  2. package/dist/{Browser-CM65Uo7f.mjs → Browser-CNwK0r0q.mjs} +2 -2
  3. package/dist/{Browser-CM65Uo7f.mjs.map → Browser-CNwK0r0q.mjs.map} +1 -1
  4. package/dist/Browser.d.mts +2 -2
  5. package/dist/Browser.mjs +1 -1
  6. package/dist/{BrowserEvent-DzdNdvoh.d.mts → BrowserEvent-BRu2juEz.d.mts} +3 -1
  7. package/dist/BrowserEvent.d.mts +1 -1
  8. package/dist/BrowserEvent.mjs +2 -0
  9. package/dist/BrowserEvent.mjs.map +1 -1
  10. package/dist/Cdp.mjs +1 -1
  11. package/dist/{Change-DVP2IJWm.d.mts → Change-iMlcuzVD.d.mts} +2 -2
  12. package/dist/Change.d.mts +1 -1
  13. package/dist/Chromium.mjs +1 -1
  14. package/dist/Expect.d.mts +1 -1
  15. package/dist/Expect.mjs +1 -1
  16. package/dist/Moment.d.mts +1 -1
  17. package/dist/{Page-DYTdVhYa.d.mts → Page-C30aG2RQ.d.mts} +6 -4
  18. package/dist/Page-D4281dIi.mjs.map +1 -1
  19. package/dist/Page.d.mts +1 -1
  20. package/dist/Plan-BvCS9qAf.d.mts +209 -0
  21. package/dist/{Plan-Dtrb-8im.mjs → Plan-CyQNv49C.mjs} +236 -39
  22. package/dist/Plan-CyQNv49C.mjs.map +1 -0
  23. package/dist/Plan.d.mts +2 -2
  24. package/dist/Plan.mjs +2 -2
  25. package/dist/Policy.d.mts +1 -1
  26. package/dist/Presentation.d.mts +1 -1
  27. package/dist/Presentation.mjs +1 -1
  28. package/dist/Stage.d.mts +1 -1
  29. package/dist/Stage.mjs +1 -1
  30. package/dist/{Supervisor-Im6-wbg5.d.mts → Supervisor-CLJaT7rG.d.mts} +2 -2
  31. package/dist/Supervisor.d.mts +1 -1
  32. package/dist/index.d.mts +5 -5
  33. package/dist/index.mjs +2 -2
  34. package/dist/{page-Banfm_zc.mjs → page-DHeYWEs-.mjs} +28 -15
  35. package/dist/page-DHeYWEs-.mjs.map +1 -0
  36. package/package.json +1 -1
  37. package/src/BrowserEvent.ts +2 -0
  38. package/src/Page.ts +3 -1
  39. package/src/Plan.ts +370 -57
  40. package/src/internal/input/actions.ts +4 -1
  41. package/src/internal/input/perform.ts +2 -0
  42. package/src/internal/page/bridge.ts +3 -3
  43. package/src/internal/reading/ready.inpage.ts +17 -7
  44. package/src/internal/reading/ready.ts +9 -3
  45. package/dist/Plan-CNNOU1Tx.d.mts +0 -112
  46. package/dist/Plan-Dtrb-8im.mjs.map +0 -1
  47. package/dist/page-Banfm_zc.mjs.map +0 -1
@@ -956,8 +956,9 @@ const ViewportResultSchema = Schema.Struct({
956
956
  * frame. So a canvas mounted blank, or a spinner alone, is still loading. A screen that only says
957
957
  * "Loading…" in words reads as ready, and a WebGL canvas drawn once, without keeping its drawing,
958
958
  * reads as blank. Asked for a quiet spell, where the page's changes are recorded, nothing in view
959
- * may have changed for that long either. After input, it waits a task and a frame. See
960
- * `names.inpage.ts` for what a page-side part may use.
959
+ * may have changed for that long either. Content mode starts and refreshes the recorder and
960
+ * observes a full quiet interval from its first check in each document. After input, it waits a
961
+ * task and a frame. See `names.inpage.ts` for what a page-side part may use.
961
962
  */
962
963
  /** What the page is still waiting for; none when it is ready. */
963
964
  const ReadinessSchema = Schema.Array(Schema.Literals([
@@ -970,7 +971,7 @@ const ReadinessSchema = Schema.Array(Schema.Literals([
970
971
  "content",
971
972
  "changing"
972
973
  ]));
973
- const ready = (walked, texts, kept) => {
974
+ const ready = (walked, texts, kept, recorder) => {
974
975
  const { inView, visible } = walked;
975
976
  let copy;
976
977
  const boxed = (element) => {
@@ -1004,7 +1005,7 @@ const ready = (walked, texts, kept) => {
1004
1005
  else requestAnimationFrame(() => resolve(true));
1005
1006
  return promise;
1006
1007
  };
1007
- const check = (quietMillis) => painted().then((paints) => {
1008
+ const check = (quietMillis, observed) => painted().then((paints) => {
1008
1009
  const waiting = [];
1009
1010
  if (document.readyState === "loading") waiting.push("load");
1010
1011
  if (!paints) waiting.push("paint");
@@ -1016,17 +1017,22 @@ const ready = (walked, texts, kept) => {
1016
1017
  if (document.fonts.status !== "loaded") waiting.push("fonts");
1017
1018
  if (showing(document.querySelectorAll("[aria-busy=true]")).length > 0) waiting.push("busy");
1018
1019
  if (!content()) waiting.push("content");
1019
- if (kept.changing() > performance.timeOrigin + performance.now() - quietMillis) waiting.push("changing");
1020
+ if (Math.max(observed, kept.changing()) > performance.timeOrigin + performance.now() - quietMillis) waiting.push("changing");
1020
1021
  return waiting;
1021
1022
  });
1022
1023
  /**
1023
1024
  * Check until the page is ready, or for `millis`, and say what it is still waiting for; with
1024
1025
  * `quietMillis`, until nothing the record saw in view has changed for that long, too.
1025
1026
  */
1026
- const wait = async (millis, quietMillis = 0) => {
1027
+ const wait = async (millis, quietMillis = 0, contentOnly = false) => {
1027
1028
  const until = performance.now() + millis;
1029
+ let observed = contentOnly ? void 0 : Number.NEGATIVE_INFINITY;
1028
1030
  for (;;) {
1029
- const waiting = await check(quietMillis);
1031
+ if (contentOnly) {
1032
+ recorder.start();
1033
+ if (kept.begun()) observed ??= performance.timeOrigin + performance.now();
1034
+ }
1035
+ const waiting = await check(quietMillis, observed ?? Number.POSITIVE_INFINITY);
1030
1036
  if (waiting.length === 0 || performance.now() >= until) return waiting;
1031
1037
  const { promise, resolve } = Promise.withResolvers();
1032
1038
  setTimeout(resolve, Math.min(50, until - performance.now()));
@@ -2060,7 +2066,7 @@ const sight = (names, walked, texts, kept) => {
2060
2066
  */
2061
2067
  const install = (makeNames, makeWalk, makeMatch, makeContext, makeSubjects, makeExpectations, makeText, makeControls, makeFold, makeHistory, makeSight, makeMarks, makeRecord, makeChanges, makeReady, makeOutline, makeTargets, makeEvidence, makeGuard, makeEdit, makeAddresses) => {
2062
2068
  const installed = globalThis.__effectBrowser;
2063
- if (installed !== void 0 && installed.version === 18) return installed;
2069
+ if (installed !== void 0 && installed.version === 19) return installed;
2064
2070
  const named = makeNames();
2065
2071
  const walked = makeWalk(named);
2066
2072
  const placing = makeContext(named, walked);
@@ -2075,9 +2081,9 @@ const install = (makeNames, makeWalk, makeMatch, makeContext, makeSubjects, make
2075
2081
  const located = makeTargets(named, walked, placing);
2076
2082
  const guarded = makeGuard(named, located, makeEvidence(named, placing));
2077
2083
  const edited = makeEdit(named, guarded, placing);
2078
- const readiness = makeReady(walked, texts, kept);
2084
+ const readiness = makeReady(walked, texts, kept, recorder);
2079
2085
  const api = {
2080
- version: 18,
2086
+ version: 19,
2081
2087
  snapshot: read.snapshot,
2082
2088
  find: subjected.find,
2083
2089
  until: makeExpectations(named, subjected).until,
@@ -3074,6 +3080,7 @@ const make$13 = (page, sender) => {
3074
3080
  startedAt,
3075
3081
  page: id,
3076
3082
  name,
3083
+ url: redact(page.playwright.url()),
3077
3084
  correlation: yield* Correlation,
3078
3085
  target: info.target,
3079
3086
  options: Exit.isSuccess(exit) ? info.options : void 0,
@@ -3467,7 +3474,7 @@ const typeText = (input) => {
3467
3474
  return (text, typeOptions = {}, style = plain) => perform("type", {
3468
3475
  target: typeOptions.into,
3469
3476
  options: {
3470
- replace: typeOptions.replace,
3477
+ replace: typeOptions.into === void 0 ? false : typeOptions.replace,
3471
3478
  submit: typeOptions.submit
3472
3479
  },
3473
3480
  text,
@@ -4729,11 +4736,16 @@ const make$6 = Effect.fnUntraced(function* (page, bridge) {
4729
4736
  * connection of its own, a round trip there: each answer comes behind every frame sent before it on
4730
4737
  * its connection, and a frame that arrives first starts the spell again. Where the page's changes
4731
4738
  * are recorded, its evidence includes them: nothing in view may have changed for the spell, which a
4732
- * DOM page's changes show better than its paint, and no stall on the way can hide.
4739
+ * DOM page's changes show better than its paint, and no stall on the way can hide. Content
4740
+ * stillness starts that record itself and ignores capture silence. Each new document starts a
4741
+ * new observation, while retries of destroyed script contexts share the caller's deadline.
4733
4742
  */
4734
4743
  const make$5 = (page, bridge, capture) => (options = {}) => {
4735
4744
  const timeout = options.timeout ?? Duration.seconds(15);
4736
- const settled = (until) => Effect.suspend(() => bridge.evaluate("ready", scriptCall("ready", Math.max(0, Math.round(until - page.now())), options.quietMillis ?? 0))).pipe(Effect.flatMap(decodeWith("ready", ReadinessSchema)), Effect.tap((waiting) => Effect.annotateCurrentSpan({ waiting: waiting.join(",") })), Effect.filterOrElse((waiting) => waiting.length === 0, () => failWith("ready", new Timeout({ millis: Duration.toMillis(timeout) }))));
4745
+ const settled = (until) => Effect.suspend(() => bridge.evaluate("ready", scriptCall("ready", Math.max(0, Math.round(until - page.now())), options.quietMillis ?? 0, options.still === "content"))).pipe(Effect.retry({
4746
+ while: contextGone,
4747
+ schedule: Schedule.spaced(Duration.millis(10))
4748
+ }), Effect.flatMap(decodeWith("ready", ReadinessSchema)), Effect.tap((waiting) => Effect.annotateCurrentSpan({ waiting: waiting.join(",") })), Effect.filterOrElse((waiting) => waiting.length === 0, () => failWith("ready", new Timeout({ millis: Duration.toMillis(timeout) }))));
4737
4749
  const quiet = (millis, until) => Effect.gen(function* () {
4738
4750
  const running = yield* capture.active;
4739
4751
  let { received } = yield* capture.stats();
@@ -4765,8 +4777,9 @@ const make$5 = (page, bridge, capture) => (options = {}) => {
4765
4777
  });
4766
4778
  return page.lane.read("ready")(Effect.void).pipe(Effect.andThen(Effect.gen(function* () {
4767
4779
  const until = page.now() + Duration.toMillis(timeout);
4780
+ if (options.still === "content") yield* bridge.registerRecorder("ready");
4768
4781
  yield* settled(until);
4769
- if (options.quietMillis !== void 0) yield* quiet(options.quietMillis, until);
4782
+ if (options.quietMillis !== void 0 && options.still !== "content") yield* quiet(options.quietMillis, until);
4770
4783
  }).pipe(page.within("ready", timeout))), page.span("Page.ready"), page.owned);
4771
4784
  };
4772
4785
  //#endregion
@@ -5094,4 +5107,4 @@ const make = Effect.fnUntraced(function* (options) {
5094
5107
  //#endregion
5095
5108
  export { performed as a, pause as i, make as n, mapping as o, viewOf as r, internalsOf as t };
5096
5109
 
5097
- //# sourceMappingURL=page-Banfm_zc.mjs.map
5110
+ //# sourceMappingURL=page-DHeYWEs-.mjs.map