dsh-account-pool 0.1.1 → 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.
Files changed (2) hide show
  1. package/lib/index.js +53 -27
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -299,22 +299,41 @@ async function createRegionStack({ region, dshHome, config, logger, ctx }) {
299
299
  let creditsCache = { at: 0, value: null }
300
300
 
301
301
  /** 查各账号积分(带缓存);单个账号失败不影响其他账号。 */
302
+ /**
303
+ * 查本区域各账号的积分(带 60 秒缓存)。
304
+ *
305
+ * 账号之间**并行**查询:每个账号是一次独立的上游请求,串行会让
306
+ * 设置页的等待时间等于所有账号之和(实测 3 个账号串行约 1.5s)。
307
+ * 并行后约等于最慢的那个。
308
+ *
309
+ * 单个账号失败只丢它自己的数据,不影响其他账号。
310
+ */
302
311
  const loadCredits = async (force = false) => {
303
312
  const now = Date.now()
304
313
  if (!force && creditsCache.value !== null && now - creditsCache.at < 60_000) {
305
314
  return creditsCache.value
306
315
  }
307
- const out = {}
308
- for (const account of await store.list()) {
316
+ const accounts = await store.list()
317
+
318
+ /** 查一个账号的积分;失败返回 undefined 而不是抛错。 */
319
+ const queryOne = async (account) => {
309
320
  try {
310
321
  const credential = await store.usable(account.id)
311
- out[account.id] = await fetchRegionCredits(credential)
322
+ const credits = await fetchRegionCredits(credential)
312
323
  // 顺手把总积分喂给选号器,让加权用上真实余额。
313
- picker.setCredits(account.id, out[account.id].total)
324
+ picker.setCredits(account.id, credits.total)
325
+ return [account.id, credits]
314
326
  } catch (error) {
315
327
  logger.warn(`账号 ${account.id} 查询积分失败:${error?.message ?? error}`)
328
+ return undefined
316
329
  }
317
330
  }
331
+
332
+ const settled = await Promise.all(accounts.map(queryOne))
333
+ const out = {}
334
+ for (const entry of settled) {
335
+ if (entry !== undefined) out[entry[0]] = entry[1]
336
+ }
318
337
  creditsCache = { at: now, value: out }
319
338
  return out
320
339
  }
@@ -625,34 +644,41 @@ export function apply(ctx, config = {}) {
625
644
  if (!loopbackOrigin(req)) { json(res, 403, { ok: false, error: '仅允许本机访问' }); return }
626
645
  try {
627
646
  const list = await ready
628
- const out = {}
629
- for (const stack of list) {
647
+
648
+ /**
649
+ * 取一个区域的状态。
650
+ *
651
+ * 区域之间**并行**:cn 与 trae 是两套独立上游,串行会让设置页
652
+ * 的等待时间变成两者之和(冷缓存实测约 1.5s);并行后约等于
653
+ * 最慢的那个。
654
+ */
655
+ const regionState = async (stack) => {
630
656
  const snapshot = stack.picker.snapshot()
631
- out[stack.region] = {
657
+ const listed = await stack.store.list()
658
+ const credits = await stack.loadCredits()
659
+ return [stack.region, {
632
660
  provider: stack.providerId,
633
661
  displayName: REGION_DISPLAY_NAMES[stack.region],
634
662
  models: stack.getCatalog().length,
635
- accounts: (await (async () => {
636
- const listed = await stack.store.list()
637
- const credits = await stack.loadCredits()
638
- return listed.map(account => ({
639
- id: account.id,
640
- nickname: account.nickname,
641
- uid: account.uid,
642
- domain: account.domain,
643
- expiresAtMs: account.expiresAtMs,
644
- ...snapshot[account.id],
645
- cooling: snapshot[account.id]?.cooling ?? false,
646
- // 积分:剩余 + 总量 + 套餐明细(界面展示用)。
647
- // size 供悬停提示展示「总量 / 已用 / 剩余」构成。
648
- credits: credits[account.id]?.total,
649
- creditsSize: credits[account.id]?.size,
650
- creditPackages: credits[account.id]?.packages?.slice(0, 5) ?? [],
651
- }))
652
- })()),
653
- }
663
+ accounts: listed.map(account => ({
664
+ id: account.id,
665
+ nickname: account.nickname,
666
+ uid: account.uid,
667
+ domain: account.domain,
668
+ expiresAtMs: account.expiresAtMs,
669
+ ...snapshot[account.id],
670
+ cooling: snapshot[account.id]?.cooling ?? false,
671
+ // 积分:剩余 + 总量 + 套餐明细(界面展示用)。
672
+ // size 供悬停提示展示「总量 / 已用 / 剩余」构成。
673
+ credits: credits[account.id]?.total,
674
+ creditsSize: credits[account.id]?.size,
675
+ creditPackages: credits[account.id]?.packages?.slice(0, 5) ?? [],
676
+ })),
677
+ }]
654
678
  }
655
- json(res, 200, { ok: true, regions: out })
679
+
680
+ const settled = await Promise.all(list.map(regionState))
681
+ json(res, 200, { ok: true, regions: Object.fromEntries(settled) })
656
682
  } catch (error) {
657
683
  json(res, 500, { ok: false, error: safeMessage(error) })
658
684
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-account-pool",
3
3
  "displayName": "Account Pool",
4
- "version": "0.1.1",
4
+ "version": "0.1.2",
5
5
  "description": "把多个 WorkBuddy / Trae 账号汇成账号池接入 DeepSeek Harness:自动切换、限流熔断退避、凭证安全落盘",
6
6
  "type": "module",
7
7
  "license": "MIT",