@mhosaic/feedback 0.26.0 → 0.26.1

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.
@@ -928,6 +928,47 @@ function saveBoardView(externalId, view) {
928
928
  }
929
929
  }
930
930
 
931
+ // src/widget/poll.ts
932
+ var MAX_BACKOFF_MULTIPLIER = 10;
933
+ function startPoll(tick, intervalMs) {
934
+ let stopped = false;
935
+ let parked = false;
936
+ let failures = 0;
937
+ let timer = null;
938
+ const doc = typeof document !== "undefined" ? document : null;
939
+ const delayMs = () => Math.min(intervalMs * 2 ** failures, intervalMs * MAX_BACKOFF_MULTIPLIER);
940
+ const run = async () => {
941
+ if (stopped) return;
942
+ if (doc?.hidden) {
943
+ parked = true;
944
+ return;
945
+ }
946
+ let ok = false;
947
+ try {
948
+ ok = await tick();
949
+ } catch {
950
+ ok = false;
951
+ }
952
+ if (stopped) return;
953
+ failures = ok ? 0 : failures + 1;
954
+ timer = setTimeout(() => void run(), delayMs());
955
+ };
956
+ const onVisibilityChange = () => {
957
+ if (stopped || !parked || doc?.hidden) return;
958
+ parked = false;
959
+ void run();
960
+ };
961
+ doc?.addEventListener("visibilitychange", onVisibilityChange);
962
+ void run();
963
+ return {
964
+ stop() {
965
+ stopped = true;
966
+ if (timer) clearTimeout(timer);
967
+ doc?.removeEventListener("visibilitychange", onVisibilityChange);
968
+ }
969
+ };
970
+ }
971
+
931
972
  // src/widget/ReportDetailView.tsx
932
973
  import { useEffect, useRef, useState } from "preact/hooks";
933
974
 
@@ -1019,24 +1060,23 @@ function ReportDetailView({
1019
1060
  const fetchDetail = async () => {
1020
1061
  try {
1021
1062
  const next = await api.getReport(reportId, externalId);
1022
- if (!mountedRef.current) return;
1063
+ if (!mountedRef.current) return true;
1023
1064
  setDetail(next);
1024
1065
  setError(null);
1066
+ return true;
1025
1067
  } catch (err) {
1026
1068
  if (typeof console !== "undefined") console.warn("[mhosaic] getReport:", err);
1027
- if (!mountedRef.current) return;
1069
+ if (!mountedRef.current) return false;
1028
1070
  setError("load_failed");
1071
+ return false;
1029
1072
  }
1030
1073
  };
1031
1074
  useEffect(() => {
1032
1075
  mountedRef.current = true;
1033
- void fetchDetail();
1034
- const timer = setInterval(() => {
1035
- void fetchDetail();
1036
- }, POLL_MS);
1076
+ const poll = startPoll(fetchDetail, POLL_MS);
1037
1077
  return () => {
1038
1078
  mountedRef.current = false;
1039
- clearInterval(timer);
1079
+ poll.stop();
1040
1080
  };
1041
1081
  }, [reportId, externalId]);
1042
1082
  const handleSend = async () => {
@@ -1405,30 +1445,29 @@ function BoardView({ api, externalId, strings, getCurrentPage }) {
1405
1445
  );
1406
1446
  useEffect2(() => {
1407
1447
  let cancelled = false;
1408
- let timer = null;
1409
- const tick = async () => {
1448
+ setLoading(true);
1449
+ const poll = startPoll(async () => {
1410
1450
  try {
1411
1451
  const [list, k] = await Promise.all([
1412
1452
  api.listBoard(externalId, fetchFilters),
1413
1453
  api.fetchBoardKpis(externalId, fetchFilters)
1414
1454
  ]);
1415
- if (cancelled) return;
1455
+ if (cancelled) return true;
1416
1456
  setPage(list);
1417
1457
  setKpis(k);
1418
1458
  setError(null);
1459
+ return true;
1419
1460
  } catch (e) {
1420
- if (cancelled) return;
1461
+ if (cancelled) return false;
1421
1462
  setError(e instanceof Error ? e.message : String(e));
1463
+ return false;
1422
1464
  } finally {
1423
1465
  if (!cancelled) setLoading(false);
1424
- if (!cancelled) timer = setTimeout(tick, POLL_MS2);
1425
1466
  }
1426
- };
1427
- setLoading(true);
1428
- void tick();
1467
+ }, POLL_MS2);
1429
1468
  return () => {
1430
1469
  cancelled = true;
1431
- if (timer) clearTimeout(timer);
1470
+ poll.stop();
1432
1471
  };
1433
1472
  }, [api, externalId, JSON.stringify(fetchFilters)]);
1434
1473
  const selectedRow = useMemo(() => {
@@ -1901,26 +1940,25 @@ function ChangelogList({ api, externalId, strings, onSelect }) {
1901
1940
  setError(null);
1902
1941
  try {
1903
1942
  const next = await api.listChangelog(externalId);
1904
- if (!mountedRef.current) return;
1943
+ if (!mountedRef.current) return true;
1905
1944
  setRows(next);
1945
+ return true;
1906
1946
  } catch (err) {
1907
1947
  if (typeof console !== "undefined")
1908
1948
  console.warn("[mhosaic] listChangelog:", err);
1909
- if (!mountedRef.current) return;
1949
+ if (!mountedRef.current) return false;
1910
1950
  setError(strings["mine.error"]);
1951
+ return false;
1911
1952
  } finally {
1912
1953
  if (mountedRef.current) setRefreshing(false);
1913
1954
  }
1914
1955
  };
1915
1956
  useEffect3(() => {
1916
1957
  mountedRef.current = true;
1917
- void fetchRows();
1918
- const timer = setInterval(() => {
1919
- void fetchRows();
1920
- }, POLL_MS3);
1958
+ const poll = startPoll(fetchRows, POLL_MS3);
1921
1959
  return () => {
1922
1960
  mountedRef.current = false;
1923
- clearInterval(timer);
1961
+ poll.stop();
1924
1962
  };
1925
1963
  }, [externalId]);
1926
1964
  const groups = useMemo2(() => rows ? groupRowsByWeek(rows) : [], [rows]);
@@ -2885,25 +2923,24 @@ function MineList({ api, externalId, strings, onSelect }) {
2885
2923
  setError(null);
2886
2924
  try {
2887
2925
  const next = await api.listMine(externalId);
2888
- if (!mountedRef.current) return;
2926
+ if (!mountedRef.current) return true;
2889
2927
  setRows(next);
2928
+ return true;
2890
2929
  } catch (err) {
2891
2930
  if (typeof console !== "undefined") console.warn("[mhosaic] listMine:", err);
2892
- if (!mountedRef.current) return;
2931
+ if (!mountedRef.current) return false;
2893
2932
  setError(strings["mine.error"]);
2933
+ return false;
2894
2934
  } finally {
2895
2935
  if (mountedRef.current) setRefreshing(false);
2896
2936
  }
2897
2937
  };
2898
2938
  useEffect6(() => {
2899
2939
  mountedRef.current = true;
2900
- void fetchRows();
2901
- const timer = setInterval(() => {
2902
- void fetchRows();
2903
- }, POLL_MS4);
2940
+ const poll = startPoll(fetchRows, POLL_MS4);
2904
2941
  return () => {
2905
2942
  mountedRef.current = false;
2906
- clearInterval(timer);
2943
+ poll.stop();
2907
2944
  };
2908
2945
  }, [externalId]);
2909
2946
  const isEmpty = rows !== null && rows.length === 0;
@@ -4993,8 +5030,8 @@ function createFeedback(config) {
4993
5030
  capture_method: captureMethod,
4994
5031
  technical_context
4995
5032
  };
4996
- if ("0.26.0") {
4997
- payload.widget_version = "0.26.0";
5033
+ if ("0.26.1") {
5034
+ payload.widget_version = "0.26.1";
4998
5035
  }
4999
5036
  if (manualScreenshots?.length) {
5000
5037
  payload.screenshots = manualScreenshots;
@@ -5118,4 +5155,4 @@ function createFeedback(config) {
5118
5155
  export {
5119
5156
  createFeedback
5120
5157
  };
5121
- //# sourceMappingURL=chunk-FYF5KICC.mjs.map
5158
+ //# sourceMappingURL=chunk-3CYS47XC.mjs.map