dsh-bottom-info-bar 1.3.1 → 1.4.0
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/lib/client.js +18 -3
- package/lib/index.js +53 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -113,6 +113,7 @@ function installStyles() {
|
|
|
113
113
|
.bi-offpeak { color: var(--dsw-alias-state-success-primary, #16a34a); font-weight: 700; }
|
|
114
114
|
.bi-err { color: var(--dsw-alias-state-error-primary, #dc2626); }
|
|
115
115
|
.bi-stale{ color: var(--dsw-alias-state-warn-primary, #d97706); }
|
|
116
|
+
.bi-update{ color: var(--dsw-alias-state-error-primary, #dc2626); }
|
|
116
117
|
`;
|
|
117
118
|
document.head.appendChild(style);
|
|
118
119
|
return function () { style.remove(); };
|
|
@@ -193,7 +194,8 @@ module.exports = {
|
|
|
193
194
|
loading: true, balance: null, pricing: null, usage: null, billingMode: null, sub: null,
|
|
194
195
|
errors: { balance: null, pricing: null, usage: null, billingMode: null, sub: null },
|
|
195
196
|
});
|
|
196
|
-
const [
|
|
197
|
+
const [updateInfo, setUpdateInfo] = React.useState(null);
|
|
198
|
+
const [now, setNow] = React.useState(Date.now());
|
|
197
199
|
|
|
198
200
|
// 当前会话 ID 多路获取:slotProps 标准 kit → session 快照 → 运行时 sessions 服务
|
|
199
201
|
// (DSH 各版本注入方式不同,任一路可用即拿到真实会话 ID,避免回退到上一会话的账)
|
|
@@ -242,7 +244,16 @@ module.exports = {
|
|
|
242
244
|
return function () { window.clearInterval(id); };
|
|
243
245
|
}, [load]);
|
|
244
246
|
|
|
245
|
-
//
|
|
247
|
+
// 版本检查由 host 在进程启动时完成;这里仅读取一次缓存,不轮询 NPM。
|
|
248
|
+
React.useEffect(function () {
|
|
249
|
+
let active = true;
|
|
250
|
+
rpc('getUpdateInfo').then(function (info) {
|
|
251
|
+
if (active && info && info.available === true && typeof info.latest === 'string') setUpdateInfo(info);
|
|
252
|
+
}).catch(function () { /* 版本检查失败静默,不影响信息栏 */ });
|
|
253
|
+
return function () { active = false; };
|
|
254
|
+
}, []);
|
|
255
|
+
|
|
256
|
+
// 模型/服务商切换秒级同步:getBillingMode 为 host 端纯本地计算(零网络开销),每 2 秒轮询一次;
|
|
246
257
|
// mode/provider/model 任一变化(即切换了模型/服务商)→ 立即完整 load(),不等 30s 主轮询。
|
|
247
258
|
// 注意:本轮询不触碰订阅接口——getSubscriptionSnapshot 仍仅由 load 调用(惰性门控 + 60s 周期不变)
|
|
248
259
|
React.useEffect(function () {
|
|
@@ -590,7 +601,11 @@ module.exports = {
|
|
|
590
601
|
'⚠ 部分数据刷新失败'));
|
|
591
602
|
}
|
|
592
603
|
|
|
593
|
-
|
|
604
|
+
if (updateInfo && updateInfo.available === true) {
|
|
605
|
+
groups.push(React.createElement('span', { className: 'bi-update', key: 'update' }, '↑ ' + updateInfo.latest));
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// ---- 组装 ----
|
|
594
609
|
const sepNodes = [];
|
|
595
610
|
const nodes = [];
|
|
596
611
|
for (let i = 0; i < groups.length; i++) {
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,53 @@ import { dirname, join } from 'node:path'
|
|
|
13
13
|
|
|
14
14
|
const DATA_DIR = process.env.DSH_BOTTOM_INFO_BAR_DATA_DIR || join(homedir(), '.dsh', 'dsh-bottom-info-bar')
|
|
15
15
|
const DATA_FILE = join(DATA_DIR, 'usage-records.json')
|
|
16
|
+
const PACKAGE_FILE = new URL('../package.json', import.meta.url)
|
|
17
|
+
const UPDATE_REGISTRY_URL = 'https://registry.npmjs.org/dsh-bottom-info-bar/latest'
|
|
18
|
+
const UPDATE_CHECK_TIMEOUT_MS = 5000
|
|
19
|
+
|
|
20
|
+
function packageVersion() {
|
|
21
|
+
try {
|
|
22
|
+
const pkg = JSON.parse(readFileSync(PACKAGE_FILE, 'utf8'))
|
|
23
|
+
return typeof pkg.version === 'string' ? pkg.version : '0.0.0'
|
|
24
|
+
} catch {
|
|
25
|
+
return '0.0.0'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function stableVersion(value) {
|
|
30
|
+
const match = typeof value === 'string' && value.trim().match(/^v?(\d+)\.(\d+)\.(\d+)$/)
|
|
31
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function compareVersions(left, right) {
|
|
35
|
+
const a = stableVersion(left)
|
|
36
|
+
const b = stableVersion(right)
|
|
37
|
+
if (!a || !b) return 0
|
|
38
|
+
for (let i = 0; i < 3; i++) {
|
|
39
|
+
if (a[i] !== b[i]) return a[i] > b[i] ? 1 : -1
|
|
40
|
+
}
|
|
41
|
+
return 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function checkLatestVersion() {
|
|
45
|
+
const current = packageVersion()
|
|
46
|
+
const controller = new AbortController()
|
|
47
|
+
const timer = setTimeout(() => controller.abort(), UPDATE_CHECK_TIMEOUT_MS)
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch(UPDATE_REGISTRY_URL, {
|
|
50
|
+
headers: { accept: 'application/json' },
|
|
51
|
+
signal: controller.signal,
|
|
52
|
+
})
|
|
53
|
+
if (!response.ok) return { available: false, current: current, latest: null }
|
|
54
|
+
const body = await response.json()
|
|
55
|
+
const latest = body && typeof body.version === 'string' ? body.version : null
|
|
56
|
+
return { available: !!latest && compareVersions(latest, current) > 0, current: current, latest: latest }
|
|
57
|
+
} catch {
|
|
58
|
+
return { available: false, current: current, latest: null }
|
|
59
|
+
} finally {
|
|
60
|
+
clearTimeout(timer)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
16
63
|
|
|
17
64
|
// ---------- 双模式(余额制 / 订阅制)配置 ----------
|
|
18
65
|
// 订阅制 provider 集合:这些 provider 走"额度窗口"显示而非余额(可在此增删)
|
|
@@ -222,6 +269,9 @@ function loadUsageRecords() {
|
|
|
222
269
|
export default {
|
|
223
270
|
inject: ['credentials', 'timer'],
|
|
224
271
|
apply(ctx) {
|
|
272
|
+
// 版本检查只在 host 进程启动时发起一次;客户端后续只读取这个缓存结果。
|
|
273
|
+
const updateInfoPromise = checkLatestVersion()
|
|
274
|
+
|
|
225
275
|
// ---------- 定价表(元/美元 · 百万 tokens;DeepSeek 官方 2026-08-17;OpenAI 为 2026 官方价示例) ----------
|
|
226
276
|
const PRICING = {
|
|
227
277
|
'deepseek-v4-flash': {
|
|
@@ -1124,6 +1174,9 @@ export default {
|
|
|
1124
1174
|
// ---------- RPC 路由(webServer HTTP,替代动态沙箱 harness.handle) ----------
|
|
1125
1175
|
const ROUTE_PREFIX = '/_dsh/dsh-bottom-info-bar';
|
|
1126
1176
|
const ROUTES = {
|
|
1177
|
+
getUpdateInfo: function () {
|
|
1178
|
+
return updateInfoPromise
|
|
1179
|
+
},
|
|
1127
1180
|
getBalanceSnapshot: function (args) {
|
|
1128
1181
|
const pid = args && typeof args === 'object' && args.provider ? String(args.provider) : '';
|
|
1129
1182
|
return activeBalanceSummary(pid || undefined, Date.now());
|
package/package.json
CHANGED