From 3176880b2eb913530c3861dcefd900d3c1ece3c4 Mon Sep 17 00:00:00 2001 From: yml Date: Thu, 21 May 2026 15:28:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=BF=81=E7=A7=BB=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=AD=98=E5=82=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...vice-store.js => session-service-store.ts} | 75 +++++++++++++++---- docs/backend-typescript-migration-plan.md | 8 ++ 2 files changed, 68 insertions(+), 15 deletions(-) rename apps/backend/src/services/session/{session-service-store.js => session-service-store.ts} (62%) diff --git a/apps/backend/src/services/session/session-service-store.js b/apps/backend/src/services/session/session-service-store.ts similarity index 62% rename from apps/backend/src/services/session/session-service-store.js rename to apps/backend/src/services/session/session-service-store.ts index 21d300d8..2f8fd6fc 100644 --- a/apps/backend/src/services/session/session-service-store.js +++ b/apps/backend/src/services/session/session-service-store.ts @@ -1,5 +1,3 @@ -// @ts-check - import crypto from 'node:crypto' import fs from 'node:fs/promises' import path from 'node:path' @@ -14,9 +12,53 @@ import { SESSION_TTL_MS, } from './session-state.js' -const sessions = new Map() +type BrowserContextLike = { + close?: () => Promise +} -export async function registerTencentBrowserSession({ loginType, browserContext, page }) { +export type TencentBrowserSession = Record & { + sessionId: string + loginType: string + status: string + notice: string + createdAt: string + updatedAt: string + expiresAt: number + autoCloseAt: number + autoCloseTimer: ReturnType | null + sessionDir: string + browserContext?: BrowserContextLike | null + page?: unknown + browserContextClosed?: boolean +} + +type RegisterSessionInput = { + loginType: string + browserContext: BrowserContextLike + page: unknown +} + +type CloseSessionDependency = { + closeSession: (session: TencentBrowserSession, options: { markClosed: boolean }) => Promise +} + +type CloseSessionOptions = { + markClosed: boolean + persistSessionState: (session: TencentBrowserSession) => Promise + closeBrowserIfIdle: () => Promise +} + +type PersistSessionStateOptions = { + buildSessionPayload: (session: TencentBrowserSession) => unknown +} + +const sessions = new Map() + +export async function registerTencentBrowserSession({ + loginType, + browserContext, + page, +}: RegisterSessionInput): Promise { const sessionId = createSessionId() const sessionDir = path.join(DATA_ROOT, sessionId) await fs.mkdir(sessionDir, { recursive: true }) @@ -49,11 +91,11 @@ export async function registerTencentBrowserSession({ loginType, browserContext, return session } -export function listActiveTencentBrowserSessions() { +export function listActiveTencentBrowserSessions(): TencentBrowserSession[] { return [...sessions.values()] } -export async function getRequiredSession(sessionId) { +export async function getRequiredSession(sessionId: unknown): Promise { const key = String(sessionId || '').trim() if (!key) { @@ -75,12 +117,12 @@ export async function getRequiredSession(sessionId) { return session } -export function applyInitialQrSessionState(session) { +export function applyInitialQrSessionState(session: TencentBrowserSession): void { resetTencentSessionAutoClose(session) Object.assign(session, resolveInitialQrSessionState(session.loginType)) } -export function armRedeemedSessionAutoClose(session, { closeSession }) { +export function armRedeemedSessionAutoClose(session: TencentBrowserSession, { closeSession }: CloseSessionDependency): void { resetTencentSessionAutoClose(session) const autoCloseAt = Date.now() + REDEEM_SUCCESS_AUTO_CLOSE_MS @@ -93,7 +135,7 @@ export function armRedeemedSessionAutoClose(session, { closeSession }) { }, REDEEM_SUCCESS_AUTO_CLOSE_MS) } -export function resetTencentSessionAutoClose(session) { +export function resetTencentSessionAutoClose(session?: TencentBrowserSession | null): void { if (session?.autoCloseTimer) { clearTimeout(session.autoCloseTimer) session.autoCloseTimer = null @@ -104,20 +146,20 @@ export function resetTencentSessionAutoClose(session) { } } -export async function cleanupExpiredTencentBrowserSessions({ closeSession }) { +export async function cleanupExpiredTencentBrowserSessions({ closeSession }: CloseSessionDependency): Promise { const expired = listActiveTencentBrowserSessions().filter((session) => session.expiresAt <= Date.now()) await Promise.all(expired.map((session) => closeSession(session, { markClosed: false }))) } export async function closeSession( - session, + session: TencentBrowserSession, { markClosed, persistSessionState, closeBrowserIfIdle, - }, -) { + }: CloseSessionOptions, +): Promise { resetTencentSessionAutoClose(session) sessions.delete(session.sessionId) @@ -139,7 +181,10 @@ export async function closeSession( await closeBrowserIfIdle() } -export async function persistSessionState(session, { buildSessionPayload }) { +export async function persistSessionState( + session: TencentBrowserSession, + { buildSessionPayload }: PersistSessionStateOptions, +): Promise { await fs.mkdir(session.sessionDir, { recursive: true }) await fs.writeFile( path.join(session.sessionDir, 'session.json'), @@ -148,7 +193,7 @@ export async function persistSessionState(session, { buildSessionPayload }) { ) } -function createSessionId() { +function createSessionId(): string { let sessionId = '' do { diff --git a/docs/backend-typescript-migration-plan.md b/docs/backend-typescript-migration-plan.md index a2aea982..102dbc9e 100644 --- a/docs/backend-typescript-migration-plan.md +++ b/docs/backend-typescript-migration-plan.md @@ -456,6 +456,14 @@ - `npm run typecheck` - `npm run build` - `npm test` 共 139 个用例通过 +92. 腾讯浏览器会话内存 store 模块迁移到 `.ts`: + - `src/services/session/session-service-store.ts` +93. 浏览器会话对象、注册入参、关闭依赖、自动关闭 timer、session 状态持久化 payload 已显式类型化 +94. Docker 内验证通过: + - `src/services/session/session.test.js` 共 14 个用例通过 + - `npm run typecheck` + - `npm run build` + - `npm test` 共 139 个用例通过 ## 下一步建议