dsh-ds-balance 2.1.1 → 2.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/README.md +4 -0
- package/README_en.md +4 -0
- package/lib/adapters/console-logger.js +12 -4
- package/lib/adapters/domain-core-store.js +9 -3
- package/lib/adapters/http-deepseek-client.js +14 -4
- package/lib/adapters/salt-file.js +6 -2
- package/lib/client.js +339 -153
- package/lib/config.js +7 -1
- package/lib/domain/errors.js +10 -5
- package/lib/domain/select.js +5 -5
- package/lib/http/handlers.js +55 -13
- package/lib/index.js +34 -9
- package/lib/services/balance-service.js +13 -5
- package/lib/services/scheduler.js +6 -2
- package/lib/types/client/settings/fields.d.ts +3 -3
- package/lib/types/client/sidebar/PercentRing.d.ts +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +10 -1
package/README.md
CHANGED
package/README_en.md
CHANGED
|
@@ -26,10 +26,18 @@ function render(fields) {
|
|
|
26
26
|
*/
|
|
27
27
|
export function createConsoleLogger(sink = console) {
|
|
28
28
|
return {
|
|
29
|
-
debug: (message, fields) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
debug: (message, fields) => {
|
|
30
|
+
sink.debug(`${LOG_PREFIX} ${message}${render(fields)}`);
|
|
31
|
+
},
|
|
32
|
+
info: (message, fields) => {
|
|
33
|
+
sink.info(`${LOG_PREFIX} ${message}${render(fields)}`);
|
|
34
|
+
},
|
|
35
|
+
warn: (message, fields) => {
|
|
36
|
+
sink.warn(`${LOG_PREFIX} ${message}${render(fields)}`);
|
|
37
|
+
},
|
|
38
|
+
error: (message, fields) => {
|
|
39
|
+
sink.error(`${LOG_PREFIX} ${message}${render(fields)}`);
|
|
40
|
+
},
|
|
33
41
|
};
|
|
34
42
|
}
|
|
35
43
|
//# sourceMappingURL=console-logger.js.map
|
|
@@ -111,7 +111,9 @@ export class DomainCoreStore {
|
|
|
111
111
|
this.ready = null;
|
|
112
112
|
if (!this.openFailureLogged) {
|
|
113
113
|
this.openFailureLogged = true;
|
|
114
|
-
this.options.logger?.error('ds-balance: storage domain unavailable, running degraded', {
|
|
114
|
+
this.options.logger?.error('ds-balance: storage domain unavailable, running degraded', {
|
|
115
|
+
error: describeError(error),
|
|
116
|
+
});
|
|
115
117
|
}
|
|
116
118
|
});
|
|
117
119
|
this.ready = attempt;
|
|
@@ -128,7 +130,9 @@ export class DomainCoreStore {
|
|
|
128
130
|
async requireTable() {
|
|
129
131
|
await this.ensureOpen();
|
|
130
132
|
if (this.openError !== undefined) {
|
|
131
|
-
throw new StorageError(`storage domain unavailable: ${describeError(this.openError)}`, {
|
|
133
|
+
throw new StorageError(`storage domain unavailable: ${describeError(this.openError)}`, {
|
|
134
|
+
cause: this.openError,
|
|
135
|
+
});
|
|
132
136
|
}
|
|
133
137
|
if (this.table === null)
|
|
134
138
|
throw new StorageError('storage domain is not open');
|
|
@@ -160,7 +164,9 @@ export class DomainCoreStore {
|
|
|
160
164
|
if (this.closed)
|
|
161
165
|
return { ok: false, detail: 'closed' };
|
|
162
166
|
await this.ensureOpen();
|
|
163
|
-
return this.openError === undefined
|
|
167
|
+
return this.openError === undefined
|
|
168
|
+
? { ok: true }
|
|
169
|
+
: { ok: false, detail: describeError(this.openError) };
|
|
164
170
|
}
|
|
165
171
|
/** 幂等关闭。**必须挂在 `ctx.effect` 的 disposer 上。** */
|
|
166
172
|
async close() {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* DeepSeek 上游的 HTTP 实现。
|
|
3
3
|
* @module dsh-ds-balance/adapters/http-deepseek-client
|
|
4
4
|
*/
|
|
5
|
-
import { NetworkError, ParseError, TimeoutError, UpstreamError, classify, describeError } from '../domain/errors.js';
|
|
5
|
+
import { NetworkError, ParseError, TimeoutError, UpstreamError, classify, describeError, } from '../domain/errors.js';
|
|
6
6
|
import { parseErrorBody } from '../domain/normalize.js';
|
|
7
7
|
/** 去掉尾部斜杠,避免拼出双斜杠路径。 */
|
|
8
8
|
function joinUrl(baseUrl, path) {
|
|
@@ -39,13 +39,21 @@ export class HttpDeepSeekClient {
|
|
|
39
39
|
const raw = await this.fetchBalance(options);
|
|
40
40
|
const latencyMs = this.now() - startedAt;
|
|
41
41
|
const balances = Array.isArray(raw?.balance_infos)
|
|
42
|
-
? raw.balance_infos.map((item) => ({
|
|
42
|
+
? raw.balance_infos.map((item) => ({
|
|
43
|
+
currency: String(item.currency),
|
|
44
|
+
total: String(item.total_balance),
|
|
45
|
+
}))
|
|
43
46
|
: [];
|
|
44
47
|
return { ok: true, latencyMs, isAvailable: raw?.is_available === true, balances };
|
|
45
48
|
}
|
|
46
49
|
catch (error) {
|
|
47
50
|
const info = classify(error);
|
|
48
|
-
return {
|
|
51
|
+
return {
|
|
52
|
+
ok: false,
|
|
53
|
+
latencyMs: this.now() - startedAt,
|
|
54
|
+
code: info.code,
|
|
55
|
+
message: info.message,
|
|
56
|
+
};
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
59
|
/**
|
|
@@ -61,7 +69,9 @@ export class HttpDeepSeekClient {
|
|
|
61
69
|
timedOut = true;
|
|
62
70
|
controller.abort();
|
|
63
71
|
}, options.timeoutMs);
|
|
64
|
-
const forwardAbort = () => {
|
|
72
|
+
const forwardAbort = () => {
|
|
73
|
+
controller.abort();
|
|
74
|
+
};
|
|
65
75
|
options.signal?.addEventListener('abort', forwardAbort, { once: true });
|
|
66
76
|
let response;
|
|
67
77
|
try {
|
|
@@ -20,8 +20,12 @@ export const SALT_ENCODING = 'hex';
|
|
|
20
20
|
*/
|
|
21
21
|
export async function loadOrCreateSalt(options) {
|
|
22
22
|
const read = options.read ?? (async (path) => readFile(path, 'utf8'));
|
|
23
|
-
const write = options.write ??
|
|
24
|
-
|
|
23
|
+
const write = options.write ??
|
|
24
|
+
(async (path, data, mode) => writeFile(path, data, { mode }));
|
|
25
|
+
const makeDir = options.makeDir ??
|
|
26
|
+
(async (path) => {
|
|
27
|
+
await mkdir(path, { recursive: true });
|
|
28
|
+
});
|
|
25
29
|
const random = options.random ?? ((bytes) => randomBytes(bytes).toString(SALT_ENCODING));
|
|
26
30
|
try {
|
|
27
31
|
const existing = (await read(options.path)).trim();
|