@loupekit/sdk 0.4.0-next.10 → 0.4.1-next.11

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/dist/index.js CHANGED
@@ -1935,10 +1935,18 @@ function captureElementContext(el2) {
1935
1935
  }
1936
1936
  return { html, styles };
1937
1937
  }
1938
+ var CAPTURE_TIMEOUT = 6e3;
1939
+ function withTimeout(p, ms) {
1940
+ return Promise.race([p, new Promise((resolve) => setTimeout(() => resolve(void 0), ms))]);
1941
+ }
1938
1942
  async function fontsReady() {
1939
1943
  try {
1940
1944
  const fonts = document.fonts;
1941
- if (fonts?.ready) await fonts.ready;
1945
+ if (!fonts?.ready) return;
1946
+ await Promise.race([
1947
+ fonts.ready,
1948
+ new Promise((resolve) => setTimeout(resolve, 800))
1949
+ ]);
1942
1950
  } catch {
1943
1951
  }
1944
1952
  }
@@ -1951,14 +1959,15 @@ function captureFilter(node) {
1951
1959
  async function captureScreenshot(el2) {
1952
1960
  try {
1953
1961
  await fontsReady();
1954
- return await domToPng(el2, {
1955
- scale: Math.min(window.devicePixelRatio || 1, 2),
1956
- backgroundColor: getComputedStyle(document.body).backgroundColor || "#ffffff",
1957
- // Give cross-origin font/asset fetches time to embed (default is short) so
1958
- // the capture matches the page instead of falling back to system fonts.
1959
- timeout: 3e4,
1960
- filter: captureFilter
1961
- });
1962
+ return await withTimeout(
1963
+ domToPng(el2, {
1964
+ scale: Math.min(window.devicePixelRatio || 1, 2),
1965
+ backgroundColor: getComputedStyle(document.body).backgroundColor || "#ffffff",
1966
+ timeout: CAPTURE_TIMEOUT,
1967
+ filter: captureFilter
1968
+ }),
1969
+ CAPTURE_TIMEOUT + 2e3
1970
+ );
1962
1971
  } catch (err) {
1963
1972
  console.warn("[loupe] screenshot capture failed", err);
1964
1973
  return void 0;
@@ -1970,12 +1979,16 @@ async function captureRegionScreenshot(rect) {
1970
1979
  const scale = Math.min(window.devicePixelRatio || 1, 2);
1971
1980
  const container = regionContainer(rect);
1972
1981
  const origin = container.getBoundingClientRect();
1973
- const full = await domToPng(container, {
1974
- scale,
1975
- backgroundColor: getComputedStyle(document.body).backgroundColor || "#ffffff",
1976
- timeout: 3e4,
1977
- filter: captureFilter
1978
- });
1982
+ const full = await withTimeout(
1983
+ domToPng(container, {
1984
+ scale,
1985
+ backgroundColor: getComputedStyle(document.body).backgroundColor || "#ffffff",
1986
+ timeout: CAPTURE_TIMEOUT,
1987
+ filter: captureFilter
1988
+ }),
1989
+ CAPTURE_TIMEOUT + 2e3
1990
+ );
1991
+ if (!full) return void 0;
1979
1992
  const redact = Array.from(document.querySelectorAll("[data-loupe-redact]")).map(
1980
1993
  (n) => n.getBoundingClientRect()
1981
1994
  );
@@ -2405,11 +2418,15 @@ var LoupeApp = class {
2405
2418
  };
2406
2419
  }
2407
2420
  }
2408
- const capture = this.cfg.captureRegion ?? captureRegionScreenshot;
2409
- const screenshot = await capture(vp);
2410
2421
  this.selbox.style.display = "none";
2411
2422
  const region = { x: vp.x + window.scrollX, y: vp.y + window.scrollY, w: vp.w, h: vp.h, rel };
2412
- this.openComposer({ kind: "region", region, element: centerEl, screenshot }, vp.x + vp.w, vp.y);
2423
+ const target = { kind: "region", region, element: centerEl };
2424
+ this.openComposer(target, vp.x + vp.w, vp.y);
2425
+ const capture = this.cfg.captureRegion ?? captureRegionScreenshot;
2426
+ this.pendingShot = capture(vp);
2427
+ void this.pendingShot.then((shot) => {
2428
+ if (shot && this.pending === target) target.screenshot = shot;
2429
+ }).catch(() => void 0);
2413
2430
  }
2414
2431
  /** elementFromPoint, ignoring our own UI. */
2415
2432
  pick(x, y) {
@@ -2458,8 +2475,7 @@ var LoupeApp = class {
2458
2475
  const chk = el("label", "chk");
2459
2476
  const box = document.createElement("input");
2460
2477
  box.type = "checkbox";
2461
- box.checked = target.kind === "region" ? !!target.screenshot : true;
2462
- if (target.kind === "region" && !target.screenshot) box.disabled = true;
2478
+ box.checked = true;
2463
2479
  chk.append(box, document.createTextNode("Attach screenshot"));
2464
2480
  const btns = el("div", "btns");
2465
2481
  const cancel = el("button", "ghost", "Cancel");
@@ -2482,6 +2498,7 @@ var LoupeApp = class {
2482
2498
  closeComposer() {
2483
2499
  this.composer.style.display = "none";
2484
2500
  this.pending = null;
2501
+ this.pendingShot = void 0;
2485
2502
  }
2486
2503
  async submit(target, body, withShot) {
2487
2504
  if (!body) return;
@@ -2502,7 +2519,7 @@ var LoupeApp = class {
2502
2519
  offset = this.targetOffset;
2503
2520
  anchoredEl = target.element;
2504
2521
  } else {
2505
- screenshot = withShot ? target.screenshot : void 0;
2522
+ screenshot = withShot ? target.screenshot ?? await this.pendingShot : void 0;
2506
2523
  region = target.region;
2507
2524
  offset = { x: 0, y: 0 };
2508
2525
  if (target.element) {