@eddyskywalker/dsh-chatgpt-subscription 0.8.2 → 0.8.3
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/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/lib/client.js +87 -1
- package/lib/client.js.map +1 -1
- package/lib/index.js +758 -166
- package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
- package/lib/types/client/antigravity/AntigravitySection.d.ts.map +1 -1
- package/lib/types/client/command-code/CommandCodeSection.d.ts.map +1 -1
- package/lib/types/client/common/quota-follow-up.d.ts +30 -0
- package/lib/types/client/common/quota-follow-up.d.ts.map +1 -0
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/workbuddy/WorkBuddySection.d.ts.map +1 -1
- package/lib/types/client/zhipu/ZhipuSection.d.ts.map +1 -1
- package/lib/types/host/antigravity/oauth.d.ts +15 -1
- package/lib/types/host/antigravity/oauth.d.ts.map +1 -1
- package/lib/types/host/antigravity/port-constants.d.ts +20 -0
- package/lib/types/host/antigravity/port-constants.d.ts.map +1 -0
- package/lib/types/host/antigravity/routes.d.ts.map +1 -1
- package/lib/types/host/command-code/client.d.ts +9 -1
- package/lib/types/host/command-code/client.d.ts.map +1 -1
- package/lib/types/host/command-code/routes.d.ts.map +1 -1
- package/lib/types/host/common/catalog-snapshot.d.ts +61 -0
- package/lib/types/host/common/catalog-snapshot.d.ts.map +1 -0
- package/lib/types/host/common/credential-read-cache.d.ts +73 -0
- package/lib/types/host/common/credential-read-cache.d.ts.map +1 -0
- package/lib/types/host/common/quota-refresh.d.ts +35 -0
- package/lib/types/host/common/quota-refresh.d.ts.map +1 -0
- package/lib/types/host/common/same-origin.d.ts +30 -0
- package/lib/types/host/common/same-origin.d.ts.map +1 -0
- package/lib/types/host/credential-store-secret-service.d.ts +1 -0
- package/lib/types/host/credential-store-secret-service.d.ts.map +1 -1
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/token-store-macos.d.ts +9 -0
- package/lib/types/host/token-store-macos.d.ts.map +1 -1
- package/lib/types/host/token-store-windows.d.ts +8 -0
- package/lib/types/host/token-store-windows.d.ts.map +1 -1
- package/lib/types/host/usage-service.d.ts +19 -1
- package/lib/types/host/usage-service.d.ts.map +1 -1
- package/lib/types/host/workbuddy/client.d.ts +9 -1
- package/lib/types/host/workbuddy/client.d.ts.map +1 -1
- package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
- package/lib/types/host/zhipu/routes.d.ts.map +1 -1
- package/lib/types/shared/antigravity-contracts.d.ts +8 -0
- package/lib/types/shared/antigravity-contracts.d.ts.map +1 -1
- package/lib/types/shared/command-code-contracts.d.ts +8 -0
- package/lib/types/shared/command-code-contracts.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +8 -0
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/lib/types/shared/kimi-code-contracts.d.ts +8 -0
- package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
- package/lib/types/shared/workbuddy-contracts.d.ts +8 -0
- package/lib/types/shared/workbuddy-contracts.d.ts.map +1 -1
- package/lib/types/shared/zhipu-contracts.d.ts +8 -0
- package/lib/types/shared/zhipu-contracts.d.ts.map +1 -1
- package/package.json +2 -3
- package/lib/types/host/compaction-patch.d.ts +0 -17
- package/lib/types/host/compaction-patch.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- **发版修正:`latest` 不再停在 0.7.0**。用户反馈「更新了一下,从 0.8 又变成 0.7 了」——npm 上 `latest` 一直是 **0.7.0**,而 `0.8.0-alpha.0` 到 `0.8.2` 全部落在 `alpha` 标签下,`npm install` 与 `dsh plugin add` 不带标签时解析的正是 `latest`,所以从 0.8 升级会退回 0.7。根因是 `package.json` 里的 `publishConfig.tag: "alpha"`:它让**每一次**发布都进 `alpha`,`latest` 因此自 0.7.0 之后再没动过。
|
|
6
|
+
- **修法一:把已发布的 0.8.2 提升为 `latest`**(`npm dist-tag add @eddyskywalker/dsh-chatgpt-subscription@0.8.2 latest`)——不重新发版。提升前逐文件核对了 npm 上的 0.8.2 与本地源码的干净构建(`rm -rf lib && npm run build` 后 `npm pack`):`lib/index.js`、`lib/client.js`、`lib/client.js.map` **逐字节相同**,其余声明文件一致,因此提升 0.8.2 等于发布当前源码。0.8.2 里比干净构建多出 `lib/types/host/compaction-patch.d.ts{,.map}` 两个**孤立**声明文件(仓库里没有对应源码、也没有任何代码引用,是发布当时 `lib/` 的增量残留),运行时不受影响;这类残留正是下面那条「发版前清空 `lib/`」的原因。
|
|
7
|
+
- **修法二:删掉 `publishConfig.tag`(保留 `access: public`)**,让稳定版按 npm 默认进 `latest`。这不是把预发布也推向 `latest`:npm 11 起对预发布版本**强制要求显式 `--tag`**(`You must specify a tag using --tag when publishing a prerelease version.`,见 npm 的 `lib/commands/publish.js`),所以下一次 alpha 必须写明 `npm publish --tag alpha`,不会静默盖掉 `latest`。
|
|
8
|
+
- **顺带清掉遗留的 `next` 标签**:它从首次发布起就指向 `0.1.0-alpha.0`,与任何在用版本都不对应。
|
|
9
|
+
- **验证**:`npm view @eddyskywalker/dsh-chatgpt-subscription dist-tags` 现在为 `latest: 0.8.2`(`alpha` 仍是 0.8.2);在空目录里执行一次真实的 `npm install @eddyskywalker/dsh-chatgpt-subscription`,装到的是 0.8.2 且 `lib/index.js` 就位。
|
|
10
|
+
|
|
5
11
|
- **支持 DSH 0.1.7-rc.1**(本机 harness 仓库与 `dsh --version` 都已是它,npm 上 `next` 也是它)。这一版**不需要任何行为改动**——alpha.1 桥接过的会话消息模型与设置 API 在 rc.1 一字未改,`dsh-llm`、`dsh-settings`、`dsh-web`、`dsh-attachment`、`dsh-timeout`、`dsh-host-webserver` 与四个 client 包在该窗口内**只有版本号变化**(窗口本身 318 个提交 / 911 个文件,绝大多数与本插件无关)。动作落在基线、一处契约漂移和依赖清单上。
|
|
6
12
|
- **dev 基线升到 `0.1.7-rc.1`,peer 范围加入 `^0.1.7-rc.1`**。需要说清的是:这个 peer 子句是**为可读性**,不是解封——`^0.1.7-alpha.1` 本来就覆盖 `0.1.7-rc.1`(同一个 `0.1.7` 元组,预发布比较器在元组内匹配),已用 `semver.satisfies` 对全部 dsh peer 逐条验证。rc.1 新增的**启动期 peer 兼容性预检**(`packages/boot/app-boot/src/plugin-compatibility.ts`:不满足即把该行 `disabled` 并写 stderr,读不到 peer 元数据也一律拒绝)对本插件因此是**空集**。
|
|
7
13
|
- **`tool.call.toolview` 的入参从单一 `block` 变成三态联合**(`packages/client/ui-tool/.../contract/slots.ts` 的 `ToolCallPhaseProps`:`preparing` / `start` / `result`),`RunningToolCall` 相应拆成 `PreparingToolCall`(**根本没有 `argsRaw`**)与 `StartedToolCall`。`ToolCallTree` 对**每个阶段**都调用已注册的 keyed 视图,所以图片卡确实会拿到 `preparing` 的 block;`CodexImageToolView` 原先直接读 `block.argsRaw`,在 `preparing` 上读的是不存在的属性。**这不是用户可见的故障**(读到 `undefined` 后照常渲染「正在生成图片」,只是少了提示词摘要),属接缝处的契约漂移;现改为只在声明了该字段的分支读取(`dispatchedArgsRaw`,用 `'argsRaw' in block` 判定),旧代走的正是原来那条分支,**由构造保证而非版本判断**。
|
package/README.md
CHANGED
|
@@ -149,7 +149,7 @@ dsh plugin --profile web add @eddyskywalker/dsh-chatgpt-subscription
|
|
|
149
149
|
npx @deepseek-ai/dsh plugin --profile web add @eddyskywalker/dsh-chatgpt-subscription
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
**版本阶段**:`latest`
|
|
152
|
+
**版本阶段**:`latest` 现在是 **0.8.2**,上面两条命令装到的就是它。(此前 0.8.0-alpha.0 至 0.8.2 都只发在 `alpha` 标签下,`latest` 一直停在 0.7.0,于是升级时版本会从 0.8 退回 0.7。)预发布版仍只进 `alpha`,需要显式带上标签或版本号:
|
|
153
153
|
|
|
154
154
|
```sh
|
|
155
155
|
dsh plugin --profile web add @eddyskywalker/dsh-chatgpt-subscription@alpha
|
package/lib/client.js
CHANGED
|
@@ -678,10 +678,55 @@ window.__ModuleLoader__.load({
|
|
|
678
678
|
});
|
|
679
679
|
}
|
|
680
680
|
//#endregion
|
|
681
|
+
//#region src/client/common/quota-follow-up.ts
|
|
682
|
+
/**
|
|
683
|
+
* One follow-up poll after a status answer that carried a background refresh.
|
|
684
|
+
*
|
|
685
|
+
* The host answers a status card from the snapshot it already has and refreshes
|
|
686
|
+
* the quota behind that answer, so a tab renders immediately instead of waiting
|
|
687
|
+
* on the upstream request. The refreshed numbers would otherwise only appear on
|
|
688
|
+
* the next 60 s poll, so an answer that reports a refresh in flight schedules
|
|
689
|
+
* one short follow-up.
|
|
690
|
+
*
|
|
691
|
+
* The chain is bounded. A refresh that keeps failing leaves the snapshot aged,
|
|
692
|
+
* so every answer would keep asking for a follow-up; after a few consecutive
|
|
693
|
+
* attempts the surface falls back to its ordinary polling and stops hammering
|
|
694
|
+
* the host.
|
|
695
|
+
*/
|
|
696
|
+
const FOLLOW_UP_DELAY_MS = 1500;
|
|
697
|
+
const MAX_ATTEMPTS = 3;
|
|
698
|
+
function createQuotaFollowUp(options = {}) {
|
|
699
|
+
const delayMs = options.delayMs ?? FOLLOW_UP_DELAY_MS;
|
|
700
|
+
const maxAttempts = options.maxAttempts ?? MAX_ATTEMPTS;
|
|
701
|
+
let attempts = 0;
|
|
702
|
+
let timer;
|
|
703
|
+
return {
|
|
704
|
+
observe(refreshing, reload) {
|
|
705
|
+
if (!refreshing) {
|
|
706
|
+
attempts = 0;
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (timer !== void 0 || attempts >= maxAttempts) return;
|
|
710
|
+
attempts += 1;
|
|
711
|
+
timer = setTimeout(() => {
|
|
712
|
+
timer = void 0;
|
|
713
|
+
reload();
|
|
714
|
+
}, delayMs);
|
|
715
|
+
},
|
|
716
|
+
cancel() {
|
|
717
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
718
|
+
timer = void 0;
|
|
719
|
+
attempts = 0;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
//#endregion
|
|
681
724
|
//#region src/client/CodexSubscriptionSection.tsx
|
|
682
725
|
function CodexSubscriptionSection({ t }) {
|
|
683
726
|
const apiRef = (0, react.useRef)(new SubscriptionApi());
|
|
684
727
|
const eventSourceRef = (0, react.useRef)(null);
|
|
728
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
729
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
685
730
|
const [status, setStatus] = (0, react.useState)(null);
|
|
686
731
|
const [busy, setBusy] = (0, react.useState)(null);
|
|
687
732
|
const [error, setError] = (0, react.useState)(null);
|
|
@@ -697,6 +742,10 @@ window.__ModuleLoader__.load({
|
|
|
697
742
|
const next = await apiRef.current.status();
|
|
698
743
|
setStatus(next);
|
|
699
744
|
if (next.error !== void 0) setError(next.error.message);
|
|
745
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
746
|
+
quotaFollowUp.current.observe(next.quotaRefreshing === true, () => {
|
|
747
|
+
load(true);
|
|
748
|
+
});
|
|
700
749
|
} catch (cause) {
|
|
701
750
|
if (!quiet) setError(messageOf(cause));
|
|
702
751
|
}
|
|
@@ -711,6 +760,7 @@ window.__ModuleLoader__.load({
|
|
|
711
760
|
return () => {
|
|
712
761
|
window.clearInterval(timer);
|
|
713
762
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
763
|
+
quotaFollowUp.current?.cancel();
|
|
714
764
|
eventSourceRef.current?.close();
|
|
715
765
|
};
|
|
716
766
|
}, [load]);
|
|
@@ -1903,6 +1953,8 @@ window.__ModuleLoader__.load({
|
|
|
1903
1953
|
const [loginProgress, setLoginProgress] = (0, react.useState)(null);
|
|
1904
1954
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
1905
1955
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
1956
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
1957
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
1906
1958
|
const t = zh$5;
|
|
1907
1959
|
const notifyChange = (0, react.useCallback)(() => {
|
|
1908
1960
|
onModelChange?.();
|
|
@@ -1917,6 +1969,10 @@ window.__ModuleLoader__.load({
|
|
|
1917
1969
|
const data = await fetchApi$9("/status");
|
|
1918
1970
|
setStatus(data);
|
|
1919
1971
|
setContextDrafts(contextDraftsFor$4(data));
|
|
1972
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
1973
|
+
quotaFollowUp.current.observe(data.quotaRefreshing === true, () => {
|
|
1974
|
+
loadStatus(true);
|
|
1975
|
+
});
|
|
1920
1976
|
} catch (err) {
|
|
1921
1977
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
1922
1978
|
} finally {
|
|
@@ -1933,6 +1989,7 @@ window.__ModuleLoader__.load({
|
|
|
1933
1989
|
return () => {
|
|
1934
1990
|
window.clearInterval(timer);
|
|
1935
1991
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
1992
|
+
quotaFollowUp.current?.cancel();
|
|
1936
1993
|
};
|
|
1937
1994
|
}, [loadStatus]);
|
|
1938
1995
|
const handleLogin = async () => {
|
|
@@ -2735,6 +2792,8 @@ window.__ModuleLoader__.load({
|
|
|
2735
2792
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
2736
2793
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
2737
2794
|
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
2795
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
2796
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
2738
2797
|
const t = zh$4;
|
|
2739
2798
|
const notifyChange = (0, react.useCallback)(() => {
|
|
2740
2799
|
onModelChange?.();
|
|
@@ -2746,6 +2805,10 @@ window.__ModuleLoader__.load({
|
|
|
2746
2805
|
const data = await fetchApi$8("/status");
|
|
2747
2806
|
setStatus(data);
|
|
2748
2807
|
setContextDrafts(contextDraftsFor$3(data));
|
|
2808
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
2809
|
+
quotaFollowUp.current.observe(data.quotaRefreshing === true, () => {
|
|
2810
|
+
loadStatus(true);
|
|
2811
|
+
});
|
|
2749
2812
|
} catch (err) {
|
|
2750
2813
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
2751
2814
|
} finally {
|
|
@@ -2762,6 +2825,7 @@ window.__ModuleLoader__.load({
|
|
|
2762
2825
|
return () => {
|
|
2763
2826
|
window.clearInterval(timer);
|
|
2764
2827
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
2828
|
+
quotaFollowUp.current?.cancel();
|
|
2765
2829
|
};
|
|
2766
2830
|
}, [loadStatus]);
|
|
2767
2831
|
const handleLogin = async () => {
|
|
@@ -3820,6 +3884,8 @@ window.__ModuleLoader__.load({
|
|
|
3820
3884
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
3821
3885
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
3822
3886
|
const [connectionNotice, setConnectionNotice] = (0, react.useState)(null);
|
|
3887
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
3888
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
3823
3889
|
const t = zh$3;
|
|
3824
3890
|
const notifyChange = (0, react.useCallback)(() => {
|
|
3825
3891
|
onModelChange?.();
|
|
@@ -3831,6 +3897,10 @@ window.__ModuleLoader__.load({
|
|
|
3831
3897
|
const data = await fetchApi$7("/status");
|
|
3832
3898
|
setStatus(data);
|
|
3833
3899
|
setContextDrafts(contextDraftsFor$2(data));
|
|
3900
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
3901
|
+
quotaFollowUp.current.observe(data.quotaRefreshing === true, () => {
|
|
3902
|
+
loadStatus(true);
|
|
3903
|
+
});
|
|
3834
3904
|
} catch (err) {
|
|
3835
3905
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
3836
3906
|
} finally {
|
|
@@ -3847,6 +3917,7 @@ window.__ModuleLoader__.load({
|
|
|
3847
3917
|
return () => {
|
|
3848
3918
|
window.clearInterval(timer);
|
|
3849
3919
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
3920
|
+
quotaFollowUp.current?.cancel();
|
|
3850
3921
|
};
|
|
3851
3922
|
}, [loadStatus]);
|
|
3852
3923
|
(0, react.useEffect)(() => {
|
|
@@ -5008,6 +5079,8 @@ window.__ModuleLoader__.load({
|
|
|
5008
5079
|
const [loginProgress, setLoginProgress] = (0, react.useState)(null);
|
|
5009
5080
|
const loginIntervalRef = (0, react.useRef)(null);
|
|
5010
5081
|
const loginTimeoutRef = (0, react.useRef)(null);
|
|
5082
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
5083
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
5011
5084
|
const [contextDrafts, setContextDrafts] = (0, react.useState)({});
|
|
5012
5085
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
5013
5086
|
const t = zh$2;
|
|
@@ -5022,10 +5095,15 @@ window.__ModuleLoader__.load({
|
|
|
5022
5095
|
const loadStatus = (0, react.useCallback)(async (quiet = false) => {
|
|
5023
5096
|
if (!quiet) setError(null);
|
|
5024
5097
|
try {
|
|
5025
|
-
const
|
|
5098
|
+
const data = await fetchApi$6("/status");
|
|
5099
|
+
const normalized = normalizeStatus(data);
|
|
5026
5100
|
setStatus(normalized);
|
|
5027
5101
|
setStatusFailed(false);
|
|
5028
5102
|
setContextDrafts(contextDraftsFor$1(normalized));
|
|
5103
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
5104
|
+
quotaFollowUp.current.observe(data.quotaRefreshing === true, () => {
|
|
5105
|
+
loadStatus(true);
|
|
5106
|
+
});
|
|
5029
5107
|
} catch (err) {
|
|
5030
5108
|
setStatusFailed(true);
|
|
5031
5109
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
@@ -5041,6 +5119,7 @@ window.__ModuleLoader__.load({
|
|
|
5041
5119
|
document.addEventListener("visibilitychange", refreshWhenVisible);
|
|
5042
5120
|
return () => {
|
|
5043
5121
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
5122
|
+
quotaFollowUp.current?.cancel();
|
|
5044
5123
|
if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current);
|
|
5045
5124
|
if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current);
|
|
5046
5125
|
};
|
|
@@ -6098,6 +6177,8 @@ window.__ModuleLoader__.load({
|
|
|
6098
6177
|
const [savingModel, setSavingModel] = (0, react.useState)(null);
|
|
6099
6178
|
const [apiKey, setApiKey] = (0, react.useState)("");
|
|
6100
6179
|
const [region, setRegion] = (0, react.useState)("intl");
|
|
6180
|
+
/** Follow-up poll owed while the host refreshes the quota behind an answer. */
|
|
6181
|
+
const quotaFollowUp = (0, react.useRef)(null);
|
|
6101
6182
|
const t = zh$1;
|
|
6102
6183
|
const notifyChange = (0, react.useCallback)(() => {
|
|
6103
6184
|
onModelChange?.();
|
|
@@ -6109,6 +6190,10 @@ window.__ModuleLoader__.load({
|
|
|
6109
6190
|
const data = await fetchApi$5("/status");
|
|
6110
6191
|
setStatus(data);
|
|
6111
6192
|
setContextDrafts(contextDraftsFor(data));
|
|
6193
|
+
quotaFollowUp.current ??= createQuotaFollowUp();
|
|
6194
|
+
quotaFollowUp.current.observe(data.quotaRefreshing === true, () => {
|
|
6195
|
+
loadStatus(true);
|
|
6196
|
+
});
|
|
6112
6197
|
} catch (err) {
|
|
6113
6198
|
if (!quiet) setError(err instanceof Error ? err.message : String(err));
|
|
6114
6199
|
} finally {
|
|
@@ -6125,6 +6210,7 @@ window.__ModuleLoader__.load({
|
|
|
6125
6210
|
return () => {
|
|
6126
6211
|
window.clearInterval(timer);
|
|
6127
6212
|
document.removeEventListener("visibilitychange", refreshWhenVisible);
|
|
6213
|
+
quotaFollowUp.current?.cancel();
|
|
6128
6214
|
};
|
|
6129
6215
|
}, [loadStatus]);
|
|
6130
6216
|
/**
|