chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -32,7 +32,7 @@ import {
|
||||
} from './utils';
|
||||
import { type FetchSteamConfig } from './type';
|
||||
|
||||
/** 发起流式消息拉取的请求 */
|
||||
/** Initiate a request for a streaming message pull */
|
||||
export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
requestInfo: RequestInfo,
|
||||
{
|
||||
@@ -79,11 +79,11 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
let betweenChunkTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
/**
|
||||
* clear 时机
|
||||
* 所有异常退出
|
||||
* create 函数 return
|
||||
* readStream 结束
|
||||
* abortSignal 触发
|
||||
* Clear time
|
||||
* All abnormal exits
|
||||
* Create function return
|
||||
* readStream ends
|
||||
* abortSignal trigger
|
||||
*/
|
||||
const clearTotalFetchTimer = () => {
|
||||
if (!totalFetchTimer) {
|
||||
@@ -94,8 +94,8 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
};
|
||||
|
||||
/**
|
||||
* set 时机
|
||||
* fetch 之间 set 一次, 只此一次
|
||||
* Set the timing
|
||||
* Fetch set once, only once
|
||||
*/
|
||||
const setTotalFetchTimer = () => {
|
||||
if (totalFetchTimeout && onTotalFetchTimeout) {
|
||||
@@ -107,11 +107,11 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
};
|
||||
|
||||
/**
|
||||
* clear 时机
|
||||
* readStream 异常退出
|
||||
* readStream 结束
|
||||
* 收到了新 chunk
|
||||
* abortSignal 触发
|
||||
* Clear time
|
||||
* readStream exits abnormally
|
||||
* readStream ends
|
||||
* Got a new chunk
|
||||
* abortSignal trigger
|
||||
*/
|
||||
const clearBetweenChunkTimer = () => {
|
||||
if (!betweenChunkTimer) {
|
||||
@@ -122,9 +122,9 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
};
|
||||
|
||||
/**
|
||||
* set 时机
|
||||
* readStream 之前 set 一次
|
||||
* 每次收到 chunk 并执行了 clearBetweenChunkTimer 时 set 一次
|
||||
* Set the timing
|
||||
* readStream is set once before
|
||||
* Set every time a chunk is received and clearBetweenChunkTimer executed
|
||||
*/
|
||||
const setBetweenChunkTimer = () => {
|
||||
if (betweenChunkTimeout && onBetweenChunkTimeout) {
|
||||
@@ -136,7 +136,7 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
};
|
||||
|
||||
signal?.addEventListener('abort', () => {
|
||||
// 此处 abort 后下方 readableStream 与 writableStream 都会停止
|
||||
// After aborting here, both the readableStream and writableStream below will stop.
|
||||
clearTotalFetchTimer();
|
||||
clearBetweenChunkTimer();
|
||||
resolve();
|
||||
@@ -160,13 +160,13 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
return response;
|
||||
} catch (error) {
|
||||
/**
|
||||
* 这里会被 catch 的错误
|
||||
* fetch 服务端返回异常
|
||||
* js error,例如被 onStart 抛出的
|
||||
* fetch 过程中 signal 被 abort
|
||||
* Mistakes that will be caught here
|
||||
* Fetch server level returned exception
|
||||
* Js error, such as thrown by onStart
|
||||
* The signal was aborted during fetching
|
||||
*/
|
||||
|
||||
// 被 abort 不认为是异常,不调用 onError
|
||||
// Being aborted is not considered an exception, and onError is not called.
|
||||
if (isAbortError(error)) {
|
||||
return;
|
||||
}
|
||||
@@ -214,11 +214,11 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
//
|
||||
validateChunk(decodedChunk);
|
||||
|
||||
// 上方 start 会在 TransformStream 被构建的同时执行,所以此处执行时能取到 parser
|
||||
// The above start will be executed at the same time as the TransformStream is built, so the parser can be fetched when executed here.
|
||||
parser.feed(decodedChunk);
|
||||
} catch (chunkError) {
|
||||
// 处理 validateChunk 抛出的业务错误
|
||||
// 服务端不会流式返回业务错误,错误结构:{ msg: 'xxx', code: 123456 }
|
||||
// Handling business errors thrown by validateChunk
|
||||
// The server level does not stream back business errors. Error structure: {msg: 'xxx', code: 123456}
|
||||
controller.error(chunkError);
|
||||
}
|
||||
},
|
||||
@@ -226,14 +226,14 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
|
||||
const streamWriter = new WritableStream<Message>({
|
||||
async write(chunk, controller) {
|
||||
// 写消息异步化 避免回调中的错误 panic 管道流
|
||||
// Write messages asynchronously to avoid false panic pipeline flow in callbacks
|
||||
await Promise.resolve();
|
||||
const param = { message: chunk, dataClump };
|
||||
const validateResult = validateMessage?.(param);
|
||||
|
||||
if (validateResult && validateResult.status === 'error') {
|
||||
/**
|
||||
* 会中断 WritableStream, 即使还有数据也会被中断, 不会再写了
|
||||
* WritableStream will be interrupted, even if there is still data, it will not be written again
|
||||
*/
|
||||
throw validateResult.error;
|
||||
}
|
||||
@@ -262,14 +262,14 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
resolve();
|
||||
} catch (streamError) {
|
||||
/**
|
||||
* 这里会被 catch 的错误
|
||||
* 流式返回中服务端异常
|
||||
* Mistakes that will be caught here
|
||||
* Exception at server level in streaming return
|
||||
* js error
|
||||
* 流式返回过程中被 signal 被 abort
|
||||
* 上方 onParseErrorFn 被调用
|
||||
* The signal was aborted during streaming return
|
||||
* The above onParseErrorFn is called
|
||||
*/
|
||||
|
||||
// 被 abort 不认为是异常,不调用 onError
|
||||
// Being aborted is not considered an exception, and onError is not called.
|
||||
if (isAbortError(streamError)) {
|
||||
return;
|
||||
}
|
||||
@@ -287,7 +287,7 @@ export async function fetchStream<Message = ParseEvent, DataClump = unknown>(
|
||||
async function create(): Promise<void> {
|
||||
const response = await fetchAndVerifyResponse();
|
||||
const body = response?.body;
|
||||
// response 不合法与没有 body 的错误在上方 onStart 中处理过
|
||||
// The response invalid and no body errors are handled in onStart above
|
||||
if (!body) {
|
||||
clearTotalFetchTimer();
|
||||
return;
|
||||
|
||||
@@ -40,54 +40,54 @@ export type ValidateResult =
|
||||
};
|
||||
|
||||
/**
|
||||
* {@link RequestInfo} 与 {@link RequestInit} 是 Fetch 原有参数类型
|
||||
* {@link RequestInfo} and {@link RequestInit} are the original parameter types of Fetch
|
||||
*/
|
||||
|
||||
export interface FetchSteamConfig<Message = ParseEvent, DataClump = unknown>
|
||||
extends RequestInit {
|
||||
/**
|
||||
* 当开始 fetch时调用
|
||||
* Called when fetch starts
|
||||
*/
|
||||
onFetchStart?: (params?: DataClump) => void;
|
||||
|
||||
/**
|
||||
* 当 fetch 返回 response 时调用此方法。使用这个方法来验证 Response 是否符合预期,当不符合预期时抛出错误
|
||||
* 无论是否提供此方法,会自动校验 Response.ok 标志位与 Response.body 是否存在
|
||||
* Call this method when fetch returns a response. Use this method to verify that the Response meets expectations, and throw an error when it does not
|
||||
* Whether or not this method is provided, the existence of the Response.ok flag and Response.body is automatically verified
|
||||
*/
|
||||
onStart?: (response: Response) => Promise<void>;
|
||||
|
||||
/**
|
||||
* 当 fetch 成功返回 response 并且 onStart 成功后触发此回调
|
||||
* This callback is triggered when fetch successfully returns a response and onStart succeeds
|
||||
*/
|
||||
onFetchSuccess?: (params?: DataClump) => void;
|
||||
|
||||
/**
|
||||
* 开始读取 ReadableStream 时触发此回调。onFetchSuccess 后紧接着会触发这个回调
|
||||
* This callback is triggered when you start reading ReadableStream. onFetchSuccess is followed by this callback
|
||||
*/
|
||||
onStartReadStream?: (params?: DataClump) => void;
|
||||
|
||||
/**
|
||||
* 流式过程中解析服务端返回的 chunk 数据,返回值符合 {@link Message} 类型时,预期将在后续 {@link onMessage} 方法中响应
|
||||
* 可在解析过程中进行中断或抛出错误,抛出错误同时会中断整个流式解析
|
||||
* 如果不提供则由 onMessage 直接响应 chunk 数据
|
||||
* The chunk data returned by the server level is parsed during streaming, and when the return value conforms to the type {@link Message}, it is expected to respond in subsequent {@link onMessage} methods
|
||||
* You can interrupt or throw an error during parsing, and throwing an error will also interrupt the entire stream parsing
|
||||
* If not provided, onMessage directly responds to chunk data
|
||||
*/
|
||||
streamParser?: (
|
||||
parseEvent: ParseEvent,
|
||||
method: {
|
||||
/**
|
||||
* 中止当前流式读取行为
|
||||
* Abort current streaming read behavior
|
||||
*/
|
||||
terminate: () => void;
|
||||
/**
|
||||
* @deprecated
|
||||
* 抛出错误,同时中止当前流式读取行为,如果流中还有正常数据未被读取,也会被一起终止掉
|
||||
* Throw an error and abort the current stream reading behavior. If there is still normal data in the stream that has not been read, it will also be terminated together.
|
||||
*/
|
||||
onParseError: (error: FetchStreamErrorInfo) => void;
|
||||
},
|
||||
) => Message | undefined;
|
||||
|
||||
/**
|
||||
* 在 onMessage 回调之前执行。对业务错误的处理和抛出推荐在这个回调处理
|
||||
* Execute before the onMessage callback. Handling of business errors and throwing recommendations are handled in this callback
|
||||
*/
|
||||
validateMessage?: (params: {
|
||||
message: Message;
|
||||
@@ -95,51 +95,51 @@ export interface FetchSteamConfig<Message = ParseEvent, DataClump = unknown>
|
||||
}) => ValidateResult;
|
||||
|
||||
/**
|
||||
* 接收到服务端 Chunk 数据并经过 parse(如果有)后,如果过程中无异常则调用此方法
|
||||
* After receiving the server level Chunk data and parsing (if any), call this method if there are no exceptions in the process
|
||||
*/
|
||||
onMessage?: (params: { message: Message; dataClump?: DataClump }) => void;
|
||||
|
||||
/**
|
||||
* 当 fetchStream resolve 时调用此方法
|
||||
* Call this method when fetchStream resolves
|
||||
*/
|
||||
onAllSuccess?: (params?: DataClump) => void;
|
||||
|
||||
/**
|
||||
* fetchStream 整个过程中出现任意错误会调用此方法,包括 fetch / 流式处理 chunk / response 非法等
|
||||
* 不会自动重试
|
||||
* This method will be called if any errors occur during the fetchStream process, including fetch/streaming chunk/response illegal, etc
|
||||
* Does not automatically retry
|
||||
*/
|
||||
onError?: (params: {
|
||||
fetchStreamError: FetchStreamError;
|
||||
dataClump?: DataClump;
|
||||
}) => void;
|
||||
|
||||
/** Fetch 方法,默认为 window.fetch */
|
||||
/** Fetch method, the default is window.fetch */
|
||||
fetch?: typeof fetch;
|
||||
|
||||
/**
|
||||
* {@link https://book-refactoring2.ifmicro.com/docs/ch3.html#310-%E6%95%B0%E6%8D%AE%E6%B3%A5%E5%9B%A2%EF%BC%88data-clumps%EF%BC%89}
|
||||
* 如果你想为每个 fetchStream 维护一些业务数据、状态,推荐在此处传入抽象后的数据实例。它们会在每个回调函数中出现
|
||||
* If you want to maintain some business data and state for each fetchStream, it is recommended to pass in the abstracted data instances here. They will appear in each callback function
|
||||
*/
|
||||
dataClump?: DataClump;
|
||||
|
||||
/**
|
||||
* fetch stream 整个过程的超时时长, 单位: ms。缺省或者传入 0 代表不开启定时器
|
||||
* The timeout of the entire process of fetch stream, in: ms. Default or pass in 0 to indicate that the timer is not turned on
|
||||
*/
|
||||
totalFetchTimeout?: number;
|
||||
|
||||
/**
|
||||
* 当设置了 totalFetchTimeout, 并且到期时触发此回调。除此外不会有其余副作用,例如:abort 请求。请调用方根据需要自行处理
|
||||
* This callback is triggered when totalFetchTimeout is set and expires. There will be no other side effects, such as abort requests. Please handle it yourself as needed
|
||||
*/
|
||||
onTotalFetchTimeout?: (params?: DataClump) => void;
|
||||
|
||||
/**
|
||||
* chunk 之间超时时长, 处理 stream 过程中, 从收到上一个 chunk 开始计时, 收到下一个 chunk 时清除定时并重新计时
|
||||
* 缺省或者传入 0 代表不开启定时器, 单位: ms
|
||||
* Timeout time between chunks. During the processing of the stream, the timing starts from the receipt of the previous chunk. When the next chunk is received, the timing is cleared and re-timed.
|
||||
* Default or incoming 0 means the timer is not turned on, unit: ms
|
||||
*/
|
||||
betweenChunkTimeout?: number;
|
||||
|
||||
/**
|
||||
* 当设置了 chunkTimeout,并且定时器到期时触发此回调。除此外不会有其余副作用,例如:abort 请求。请调用方根据需要自行处理
|
||||
* This callback is triggered when chunkTimeout is set and the timer expires. In addition, there will be no other side effects, such as: abort request. Please handle it yourself as needed
|
||||
*/
|
||||
onBetweenChunkTimeout?: (params?: DataClump) => void;
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@ export function validateChunk(decodedChunk: string): void {
|
||||
let json: unknown;
|
||||
try {
|
||||
json = JSON.parse(decodedChunk);
|
||||
// eslint-disable-next-line @coze-arch/no-empty-catch, @coze-arch/use-error-in-catch -- 设计如此
|
||||
// eslint-disable-next-line @coze-arch/no-empty-catch, @coze-arch/use-error-in-catch -- designed like this
|
||||
} catch {
|
||||
/**
|
||||
* 此处捕获 JSON.parse 错误不做任何处理
|
||||
* 正常流式返回 json 解析失败才是正常的
|
||||
* Catch JSON.parse errors here without any processing
|
||||
* It is normal for normal streaming to return json parsing failure.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user