@mythicalos/preact-ui 0.2.1 → 0.2.2
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/hooks.js +41 -22
- package/package.json +1 -1
package/dist/hooks.js
CHANGED
|
@@ -64,10 +64,22 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
64
64
|
let timer;
|
|
65
65
|
let stopped = false;
|
|
66
66
|
let failures = 0; // consecutive failed reads — drives the ×2 backoff ladder (reset on success)
|
|
67
|
+
// true from the moment a tick fires its fetch until that fetch settles — the ONE in-flight
|
|
68
|
+
// read this call site is allowed to have. The visibility handler below must never start a
|
|
69
|
+
// second tick while this is true; it lets the in-flight tick's own onSettled → schedule()
|
|
70
|
+
// continue the single chain instead (a prior version fired an immediate tick on visibility
|
|
71
|
+
// return unconditionally, which could open a second concurrent chain).
|
|
72
|
+
let pending = false;
|
|
67
73
|
const isHidden = () => typeof document !== "undefined" && document.hidden === true;
|
|
68
74
|
const schedule = () => {
|
|
69
75
|
if (!alive || stopped)
|
|
70
76
|
return;
|
|
77
|
+
// Clear any already-armed timer before arming a new one — defense in depth so a stray
|
|
78
|
+
// double-settle can never leave an earlier timer orphaned (never cleared, still firing).
|
|
79
|
+
if (timer) {
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
timer = undefined;
|
|
82
|
+
}
|
|
71
83
|
// U7 pause: while the document is hidden no timer is armed — the
|
|
72
84
|
// visibilitychange handler below refreshes immediately on return.
|
|
73
85
|
if (isHidden())
|
|
@@ -77,26 +89,31 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
77
89
|
// diff r3-F1: every response routes through runPollTick — stamped with the epoch at fire
|
|
78
90
|
// time, applied only while that epoch is still live. A stale settle leaves loading alone
|
|
79
91
|
// (the reset already set it for the new epoch) but still rearms via schedule()'s own guards.
|
|
80
|
-
const tick = () =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
const tick = () => {
|
|
93
|
+
pending = true;
|
|
94
|
+
return runPollTick({
|
|
95
|
+
fetch: () => fnRef.current(),
|
|
96
|
+
guard,
|
|
97
|
+
isAlive: () => alive && !stopped,
|
|
98
|
+
isHidden,
|
|
99
|
+
onSuccess: (v) => {
|
|
100
|
+
failures = 0;
|
|
101
|
+
setData(v);
|
|
102
|
+
setError(undefined);
|
|
103
|
+
},
|
|
104
|
+
onFailure: (message) => {
|
|
105
|
+
failures += 1;
|
|
106
|
+
setError(message);
|
|
107
|
+
},
|
|
108
|
+
onSettled: (applied) => {
|
|
109
|
+
if (applied)
|
|
110
|
+
setLoading(false);
|
|
111
|
+
schedule();
|
|
112
|
+
},
|
|
113
|
+
}).finally(() => {
|
|
114
|
+
pending = false;
|
|
115
|
+
});
|
|
116
|
+
};
|
|
100
117
|
const onVisibility = () => {
|
|
101
118
|
if (!alive || stopped)
|
|
102
119
|
return;
|
|
@@ -104,8 +121,10 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
104
121
|
clearTimeout(timer);
|
|
105
122
|
timer = undefined;
|
|
106
123
|
}
|
|
107
|
-
|
|
108
|
-
|
|
124
|
+
// Immediate refresh on visibility return — but only when idle. A tick already in flight
|
|
125
|
+
// keeps its place as the single chain: its own onSettled → schedule() picks up from here.
|
|
126
|
+
if (!isHidden() && !pending)
|
|
127
|
+
void tick();
|
|
109
128
|
};
|
|
110
129
|
if (typeof document !== "undefined")
|
|
111
130
|
document.addEventListener("visibilitychange", onVisibility);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mythicalos/preact-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "mythicalOS thin Preact bindings over @mythicalos/ui-core — Button, Input/Toggle/Checkbox, MaskedSecretInput, EmptyState, ConfirmDialog/Scrim, Toast/ToastProvider, Chip, Card, Avatar, StatusLine, SearchInput, Banner, Gauge, and the usePoll/useInterval hooks. Render + framework wiring only — every class string, poll-scheduling math, glyph map, and text composition is derived by @mythicalos/ui-core so this binding and its React sibling can never drift. Apache-2.0.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|