fix(chat): isolate pending flows and cancel stale requests
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import type { UnlockPrivateMessageInput } from "@/data/repositories/interfaces";
|
||||
import type {
|
||||
ChatRequestOptions,
|
||||
ChatSendOptions,
|
||||
UnlockPrivateMessageInput,
|
||||
} from "@/data/repositories/interfaces";
|
||||
import {
|
||||
ChatHistoryResponse,
|
||||
ChatSendResponse,
|
||||
@@ -17,7 +21,7 @@ export class ChatRemoteDataSource {
|
||||
async sendMessage(
|
||||
characterId: string,
|
||||
message: string,
|
||||
options?: { image?: string; useWebSocket?: boolean },
|
||||
options?: ChatSendOptions,
|
||||
): Promise<Result<ChatSendResponse>> {
|
||||
return Result.wrap(async () => {
|
||||
const request = SendMessageRequestSchema.parse({
|
||||
@@ -26,7 +30,7 @@ export class ChatRemoteDataSource {
|
||||
image: options?.image ?? "",
|
||||
useWebSocket: options?.useWebSocket ?? false,
|
||||
});
|
||||
return await this.api.sendMessage(request);
|
||||
return await this.api.sendMessage(request, options);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,23 +38,34 @@ export class ChatRemoteDataSource {
|
||||
characterId: string,
|
||||
limit = 50,
|
||||
offset = 0,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<ChatHistoryResponse>> {
|
||||
return Result.wrap(() => this.api.getHistory(characterId, limit, offset));
|
||||
return Result.wrap(() =>
|
||||
this.api.getHistory(characterId, limit, offset, options),
|
||||
);
|
||||
}
|
||||
|
||||
async unlockPrivateMessage(
|
||||
input: UnlockPrivateMessageInput,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockPrivateResponse>> {
|
||||
return Result.wrap(() =>
|
||||
this.api.unlockPrivateMessage(UnlockPrivateRequestSchema.parse(input)),
|
||||
this.api.unlockPrivateMessage(
|
||||
UnlockPrivateRequestSchema.parse(input),
|
||||
options,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async unlockHistory(
|
||||
characterId: string,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockHistoryResponse>> {
|
||||
return Result.wrap(() =>
|
||||
this.api.unlockHistory(UnlockHistoryRequestSchema.parse({ characterId })),
|
||||
this.api.unlockHistory(
|
||||
UnlockHistoryRequestSchema.parse({ characterId }),
|
||||
options,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type {
|
||||
CacheRemoteChatMediaInput,
|
||||
ChatMediaLookupInput,
|
||||
ChatRequestOptions,
|
||||
ChatSendOptions,
|
||||
IChatRepository,
|
||||
UnlockPrivateMessageInput,
|
||||
UnlockedPrivateMessageLocalPatch,
|
||||
@@ -38,7 +40,7 @@ export class ChatRepository implements IChatRepository {
|
||||
async sendMessage(
|
||||
characterId: string,
|
||||
message: string,
|
||||
options?: { image?: string; useWebSocket?: boolean },
|
||||
options?: ChatSendOptions,
|
||||
): Promise<Result<ChatSendResponse>> {
|
||||
return this.remote.sendMessage(characterId, message, options);
|
||||
}
|
||||
@@ -48,22 +50,25 @@ export class ChatRepository implements IChatRepository {
|
||||
characterId: string,
|
||||
limit = 50,
|
||||
offset = 0,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<ChatHistoryResponse>> {
|
||||
return this.remote.getHistory(characterId, limit, offset);
|
||||
return this.remote.getHistory(characterId, limit, offset, options);
|
||||
}
|
||||
|
||||
/** 解锁单条历史付费 / 私密消息。 */
|
||||
async unlockPrivateMessage(
|
||||
input: UnlockPrivateMessageInput,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockPrivateResponse>> {
|
||||
return this.remote.unlockPrivateMessage(input);
|
||||
return this.remote.unlockPrivateMessage(input, options);
|
||||
}
|
||||
|
||||
/** 一键解锁历史锁定消息。 */
|
||||
async unlockHistory(
|
||||
characterId: string,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockHistoryResponse>> {
|
||||
return this.remote.unlockHistory(characterId);
|
||||
return this.remote.unlockHistory(characterId, options);
|
||||
}
|
||||
|
||||
/** 把本地缓存中的单条锁定消息标记为已解锁。 */
|
||||
|
||||
@@ -42,12 +42,21 @@ export interface UnlockPrivateMessageInput {
|
||||
clientLockId?: string;
|
||||
}
|
||||
|
||||
export interface ChatRequestOptions {
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
export interface ChatSendOptions extends ChatRequestOptions {
|
||||
image?: string;
|
||||
useWebSocket?: boolean;
|
||||
}
|
||||
|
||||
export interface IChatRepository {
|
||||
/** 发送一条消息。 */
|
||||
sendMessage(
|
||||
characterId: string,
|
||||
message: string,
|
||||
options?: { image?: string; useWebSocket?: boolean },
|
||||
options?: ChatSendOptions,
|
||||
): Promise<Result<ChatSendResponse>>;
|
||||
|
||||
/** 获取聊天历史,分页参数默认 limit=50, offset=0。 */
|
||||
@@ -55,15 +64,20 @@ export interface IChatRepository {
|
||||
characterId: string,
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<ChatHistoryResponse>>;
|
||||
|
||||
/** 解锁单条历史付费 / 私密消息。 */
|
||||
unlockPrivateMessage(
|
||||
input: UnlockPrivateMessageInput,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockPrivateResponse>>;
|
||||
|
||||
/** 一键解锁历史锁定消息。 */
|
||||
unlockHistory(characterId: string): Promise<Result<UnlockHistoryResponse>>;
|
||||
unlockHistory(
|
||||
characterId: string,
|
||||
options?: ChatRequestOptions,
|
||||
): Promise<Result<UnlockHistoryResponse>>;
|
||||
|
||||
/** 把本地缓存中的单条锁定消息标记为已解锁。 */
|
||||
markPrivateMessageUnlockedInLocal(
|
||||
|
||||
Reference in New Issue
Block a user