refactor: centralize domain values and enforce numeric lint
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { MILLISECONDS_PER_SECOND } from '../../common/time';
|
||||
import { TbankAccount } from './tbank.client';
|
||||
|
||||
const accountTypes = {
|
||||
@@ -51,7 +52,7 @@ export function accessibleTbankAccount(
|
||||
|
||||
function openedOn(seconds: string | number | undefined): string | null {
|
||||
if (seconds === undefined) return null;
|
||||
const date = new Date(Number(seconds) * 1000);
|
||||
const date = new Date(Number(seconds) * MILLISECONDS_PER_SECOND);
|
||||
if (Number.isNaN(date.valueOf())) return null;
|
||||
return date.toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { MILLISECONDS_PER_SECOND } from '../../common/time';
|
||||
import {
|
||||
ChannelCredentials,
|
||||
Client,
|
||||
@@ -28,6 +29,13 @@ import type {
|
||||
TbankShare,
|
||||
} from './tbank-market.types';
|
||||
|
||||
const RATE_WINDOW_MS = 1_000;
|
||||
const METADATA_MAX_ATTEMPTS = 3;
|
||||
const RPC_MAX_ATTEMPTS = 2;
|
||||
const MAX_QUEUE_SIZE = 50;
|
||||
const METADATA_RETRY_DELAY_MS = 2_000;
|
||||
const RPC_RETRY_DELAY_MS = 1_000;
|
||||
|
||||
const requestDeadlineMs = 15_000;
|
||||
|
||||
type Unary<Request, Response> = (
|
||||
@@ -134,7 +142,7 @@ class RateLimiter {
|
||||
|
||||
private drain(): void {
|
||||
const now = Date.now();
|
||||
if (now - this.windowStartedAt >= 1000) {
|
||||
if (now - this.windowStartedAt >= RATE_WINDOW_MS) {
|
||||
this.windowStartedAt = now;
|
||||
this.starts = 0;
|
||||
}
|
||||
@@ -145,7 +153,7 @@ class RateLimiter {
|
||||
if (this.waiting.length && this.starts === this.perSecond) {
|
||||
setTimeout(
|
||||
() => this.drain(),
|
||||
Math.max(1, 1000 - (now - this.windowStartedAt)),
|
||||
Math.max(1, RATE_WINDOW_MS - (now - this.windowStartedAt)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -422,8 +430,12 @@ export class TbankClient {
|
||||
'getCandles',
|
||||
{
|
||||
instrumentId: uid,
|
||||
from: { seconds: String(Math.floor(from.valueOf() / 1000)) },
|
||||
to: { seconds: String(Math.floor(to.valueOf() / 1000)) },
|
||||
from: {
|
||||
seconds: String(Math.floor(from.valueOf() / MILLISECONDS_PER_SECOND)),
|
||||
},
|
||||
to: {
|
||||
seconds: String(Math.floor(to.valueOf() / MILLISECONDS_PER_SECOND)),
|
||||
},
|
||||
interval: 'CANDLE_INTERVAL_DAY',
|
||||
limit: 2400,
|
||||
},
|
||||
@@ -456,10 +468,10 @@ export class TbankClient {
|
||||
request: object,
|
||||
): Promise<Response> {
|
||||
const metadataCall = method === 'getInstrumentBy';
|
||||
const maxAttempts = metadataCall ? 3 : 2;
|
||||
const maxAttempts = metadataCall ? METADATA_MAX_ATTEMPTS : RPC_MAX_ATTEMPTS;
|
||||
for (let attempts = 1; attempts <= maxAttempts; attempts += 1) {
|
||||
const startedAt = performance.now();
|
||||
const queueFull = this.queue.size >= 50;
|
||||
const queueFull = this.queue.size >= MAX_QUEUE_SIZE;
|
||||
try {
|
||||
if (queueFull)
|
||||
throw new ServiceUnavailableException({ code: 'TBANK_UNAVAILABLE' });
|
||||
@@ -492,7 +504,12 @@ export class TbankClient {
|
||||
durationMs: Math.round(performance.now() - startedAt),
|
||||
});
|
||||
await new Promise((resolve) =>
|
||||
setTimeout(resolve, metadataCall ? attempts * 2000 : 1000),
|
||||
setTimeout(
|
||||
resolve,
|
||||
metadataCall
|
||||
? attempts * METADATA_RETRY_DELAY_MS
|
||||
: RPC_RETRY_DELAY_MS,
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -537,5 +554,5 @@ export class TbankClient {
|
||||
}
|
||||
|
||||
function utcSeconds(date: string): number {
|
||||
return Math.floor(Date.parse(`${date}T00:00:00Z`) / 1000);
|
||||
return Math.floor(Date.parse(`${date}T00:00:00Z`) / MILLISECONDS_PER_SECOND);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
||||
|
||||
const KEY_SIZE_BYTES = 32;
|
||||
|
||||
const VERSION = 1;
|
||||
const NONCE_SIZE = 12;
|
||||
const TAG_SIZE = 16;
|
||||
@@ -9,7 +11,8 @@ export class TbankCrypto {
|
||||
|
||||
static fromBase64(key: string): TbankCrypto {
|
||||
const decoded = Buffer.from(key, 'base64');
|
||||
if (decoded.length !== 32) throw new Error('Invalid token encryption key');
|
||||
if (decoded.length !== KEY_SIZE_BYTES)
|
||||
throw new Error('Invalid token encryption key');
|
||||
return new TbankCrypto(decoded);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user