@mythicalos/react-ui 0.1.0 → 0.1.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 +24 -20
package/dist/hooks.js
CHANGED
|
@@ -63,10 +63,22 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
63
63
|
let timer;
|
|
64
64
|
let stopped = false;
|
|
65
65
|
let failures = 0; // consecutive failed reads — drives the ×2 backoff ladder (reset on success)
|
|
66
|
+
// true from the moment a tick fires its fetch until that fetch settles — the ONE in-flight
|
|
67
|
+
// read this call site is allowed to have. The visibility handler below must never start a
|
|
68
|
+
// second tick while this is true; it lets the in-flight tick's own onSettled → schedule()
|
|
69
|
+
// continue the single chain instead (a prior version fired an immediate tick on visibility
|
|
70
|
+
// return unconditionally, which could open a second concurrent chain).
|
|
71
|
+
let pending = false;
|
|
66
72
|
const isHidden = () => typeof document !== "undefined" && document.hidden === true;
|
|
67
73
|
const schedule = () => {
|
|
68
74
|
if (!alive || stopped)
|
|
69
75
|
return;
|
|
76
|
+
// Clear any already-armed timer before arming a new one — defense in depth so a stray
|
|
77
|
+
// double-settle can never leave an earlier timer orphaned (never cleared, still firing).
|
|
78
|
+
if (timer) {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
timer = undefined;
|
|
81
|
+
}
|
|
70
82
|
// U7 pause: while the document is hidden no timer is armed — the
|
|
71
83
|
// visibilitychange handler below refreshes immediately on return.
|
|
72
84
|
if (isHidden())
|
|
@@ -76,26 +88,31 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
76
88
|
// diff r3-F1: every response routes through runPollTick — stamped with the epoch at fire
|
|
77
89
|
// time, applied only while that epoch is still live. A stale settle leaves loading alone
|
|
78
90
|
// (the reset already set it for the new epoch) but still rearms via schedule()'s own guards.
|
|
79
|
-
const tick = () =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
const tick = () => {
|
|
92
|
+
pending = true;
|
|
93
|
+
return runPollTick({
|
|
94
|
+
fetch: () => fnRef.current(),
|
|
95
|
+
guard,
|
|
96
|
+
isAlive: () => alive && !stopped,
|
|
97
|
+
isHidden,
|
|
98
|
+
onSuccess: (v) => {
|
|
99
|
+
failures = 0;
|
|
100
|
+
setData(v);
|
|
101
|
+
setError(undefined);
|
|
102
|
+
},
|
|
103
|
+
onFailure: (message) => {
|
|
104
|
+
failures += 1;
|
|
105
|
+
setError(message);
|
|
106
|
+
},
|
|
107
|
+
onSettled: (applied) => {
|
|
108
|
+
if (applied)
|
|
109
|
+
setLoading(false);
|
|
110
|
+
schedule();
|
|
111
|
+
},
|
|
112
|
+
}).finally(() => {
|
|
113
|
+
pending = false;
|
|
114
|
+
});
|
|
115
|
+
};
|
|
99
116
|
const onVisibility = () => {
|
|
100
117
|
if (!alive || stopped)
|
|
101
118
|
return;
|
|
@@ -103,8 +120,10 @@ export function usePoll(fn, ms, opts = {}) {
|
|
|
103
120
|
clearTimeout(timer);
|
|
104
121
|
timer = undefined;
|
|
105
122
|
}
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
// Immediate refresh on visibility return — but only when idle. A tick already in flight
|
|
124
|
+
// keeps its place as the single chain: its own onSettled → schedule() picks up from here.
|
|
125
|
+
if (!isHidden() && !pending)
|
|
126
|
+
void tick();
|
|
108
127
|
};
|
|
109
128
|
if (typeof document !== "undefined")
|
|
110
129
|
document.addEventListener("visibilitychange", onVisibility);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mythicalos/react-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "mythicalOS thin React 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 Preact sibling can never drift. Apache-2.0.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,11 @@
|
|
|
20
20
|
"default": "./dist/index.js"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
"files": [
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"NOTICE"
|
|
27
|
+
],
|
|
24
28
|
"peerDependencies": {
|
|
25
29
|
"react": "^18.2.0 || ^19",
|
|
26
30
|
"react-dom": "^18.2.0 || ^19",
|
|
@@ -28,23 +32,23 @@
|
|
|
28
32
|
},
|
|
29
33
|
"peerDependenciesMeta": {
|
|
30
34
|
"@mythicalos/tokens": {
|
|
31
|
-
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@mythicalos/ui-core": "^0.1.1"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.build.json",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"test": "bun test",
|
|
45
|
+
"prepublishOnly": "bun run build && bun test && bun run typecheck"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"react": "^19.2.8",
|
|
49
|
+
"react-dom": "^19.2.8",
|
|
50
|
+
"@types/react": "^19",
|
|
51
|
+
"@types/react-dom": "^19",
|
|
52
|
+
"typescript": "^5"
|
|
32
53
|
}
|
|
33
|
-
},
|
|
34
|
-
"dependencies": {
|
|
35
|
-
"@mythicalos/ui-core": "^0.1.0"
|
|
36
|
-
},
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "tsc -p tsconfig.build.json",
|
|
39
|
-
"typecheck": "tsc --noEmit",
|
|
40
|
-
"test": "bun test",
|
|
41
|
-
"prepublishOnly": "bun run build && bun test && bun run typecheck"
|
|
42
|
-
},
|
|
43
|
-
"devDependencies": {
|
|
44
|
-
"react": "^19.2.8",
|
|
45
|
-
"react-dom": "^19.2.8",
|
|
46
|
-
"@types/react": "^19",
|
|
47
|
-
"@types/react-dom": "^19",
|
|
48
|
-
"typescript": "^5"
|
|
49
|
-
}
|
|
50
54
|
}
|