@yh-ui/request 0.1.21

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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/dist/adapters/fetch.cjs +157 -0
  4. package/dist/adapters/fetch.d.ts +25 -0
  5. package/dist/adapters/fetch.mjs +148 -0
  6. package/dist/adapters/index.cjs +27 -0
  7. package/dist/adapters/index.d.ts +5 -0
  8. package/dist/adapters/index.mjs +2 -0
  9. package/dist/adapters/platform.cjs +394 -0
  10. package/dist/adapters/platform.d.ts +72 -0
  11. package/dist/adapters/platform.mjs +369 -0
  12. package/dist/cache/index.cjs +56 -0
  13. package/dist/cache/index.d.ts +21 -0
  14. package/dist/cache/index.mjs +14 -0
  15. package/dist/cache/indexedDB.cjs +188 -0
  16. package/dist/cache/indexedDB.d.ts +58 -0
  17. package/dist/cache/indexedDB.mjs +176 -0
  18. package/dist/cache/localStorage.cjs +158 -0
  19. package/dist/cache/localStorage.d.ts +58 -0
  20. package/dist/cache/localStorage.mjs +153 -0
  21. package/dist/cache/memory.cjs +112 -0
  22. package/dist/cache/memory.d.ts +71 -0
  23. package/dist/cache/memory.mjs +103 -0
  24. package/dist/graphql.cjs +255 -0
  25. package/dist/graphql.d.ts +192 -0
  26. package/dist/graphql.mjs +235 -0
  27. package/dist/http-cache.cjs +248 -0
  28. package/dist/http-cache.d.ts +156 -0
  29. package/dist/http-cache.mjs +233 -0
  30. package/dist/index.cjs +181 -0
  31. package/dist/index.d.ts +23 -0
  32. package/dist/index.mjs +16 -0
  33. package/dist/interceptors/debug.cjs +139 -0
  34. package/dist/interceptors/debug.d.ts +92 -0
  35. package/dist/interceptors/debug.mjs +130 -0
  36. package/dist/interceptors/index.cjs +38 -0
  37. package/dist/interceptors/index.d.ts +6 -0
  38. package/dist/interceptors/index.mjs +3 -0
  39. package/dist/interceptors/progress.cjs +185 -0
  40. package/dist/interceptors/progress.d.ts +97 -0
  41. package/dist/interceptors/progress.mjs +177 -0
  42. package/dist/interceptors/security.cjs +154 -0
  43. package/dist/interceptors/security.d.ts +83 -0
  44. package/dist/interceptors/security.mjs +134 -0
  45. package/dist/plugin.cjs +166 -0
  46. package/dist/plugin.d.ts +106 -0
  47. package/dist/plugin.mjs +163 -0
  48. package/dist/request.cjs +396 -0
  49. package/dist/request.d.ts +111 -0
  50. package/dist/request.mjs +339 -0
  51. package/dist/types.cjs +13 -0
  52. package/dist/types.d.ts +157 -0
  53. package/dist/types.mjs +7 -0
  54. package/dist/useAIStream.cjs +125 -0
  55. package/dist/useAIStream.d.ts +89 -0
  56. package/dist/useAIStream.mjs +108 -0
  57. package/dist/useLoadMore.cjs +136 -0
  58. package/dist/useLoadMore.d.ts +84 -0
  59. package/dist/useLoadMore.mjs +134 -0
  60. package/dist/usePagination.cjs +141 -0
  61. package/dist/usePagination.d.ts +89 -0
  62. package/dist/usePagination.mjs +132 -0
  63. package/dist/useQueue.cjs +243 -0
  64. package/dist/useQueue.d.ts +118 -0
  65. package/dist/useQueue.mjs +239 -0
  66. package/dist/useRequest.cjs +325 -0
  67. package/dist/useRequest.d.ts +126 -0
  68. package/dist/useRequest.mjs +329 -0
  69. package/dist/useRequestQueue.cjs +36 -0
  70. package/dist/useRequestQueue.d.ts +52 -0
  71. package/dist/useRequestQueue.mjs +27 -0
  72. package/dist/useSSE.cjs +241 -0
  73. package/dist/useSSE.d.ts +74 -0
  74. package/dist/useSSE.mjs +226 -0
  75. package/dist/websocket.cjs +325 -0
  76. package/dist/websocket.d.ts +163 -0
  77. package/dist/websocket.mjs +316 -0
  78. package/package.json +61 -0
@@ -0,0 +1,130 @@
1
+ export function createDebugInterceptor(options = {}) {
2
+ const {
3
+ enabled = false,
4
+ level = "log",
5
+ logRequestBody = true,
6
+ logResponseBody = true,
7
+ sanitize,
8
+ logger
9
+ } = options;
10
+ const loggers = {
11
+ log: console.log,
12
+ warn: console.warn,
13
+ error: console.error
14
+ };
15
+ const log = logger || loggers[level];
16
+ const createDebugInfo = (config, response, error) => {
17
+ const info = {
18
+ requestId: config.requestId || "",
19
+ url: config.fullPath || config.url || "",
20
+ method: config.method || "GET",
21
+ timestamp: Date.now()
22
+ };
23
+ if (logRequestBody) {
24
+ info.headers = config.headers;
25
+ info.data = config.data;
26
+ }
27
+ if (response) {
28
+ info.status = response.response.status;
29
+ info.duration = response.duration;
30
+ if (logResponseBody) {
31
+ info.response = response.data;
32
+ }
33
+ }
34
+ if (error) {
35
+ info.error = error.message;
36
+ info.status = error.response?.status;
37
+ }
38
+ return info;
39
+ };
40
+ const printDebug = (info) => {
41
+ if (!enabled) return;
42
+ const sanitizedInfo = sanitize ? sanitize(info) : info;
43
+ const prefix = `[YH-Request] ${sanitizedInfo.method} ${sanitizedInfo.requestId}`;
44
+ const status = sanitizedInfo.status ? ` [${sanitizedInfo.status}]` : "";
45
+ const duration = sanitizedInfo.duration ? ` (${sanitizedInfo.duration}ms)` : "";
46
+ if (sanitizedInfo.error) {
47
+ log({
48
+ ...sanitizedInfo,
49
+ message: `${prefix}${status}${duration} - ${sanitizedInfo.error}`
50
+ });
51
+ } else {
52
+ log({
53
+ ...sanitizedInfo,
54
+ message: `${prefix}${status}${duration}`
55
+ });
56
+ }
57
+ };
58
+ return {
59
+ /**
60
+ * 请求拦截
61
+ */
62
+ onRequest: (config) => {
63
+ if (!enabled) return config;
64
+ const info = createDebugInfo(config);
65
+ printDebug({
66
+ ...info,
67
+ message: `[YH-Request] \u2192 ${info.method} ${info.url}`
68
+ });
69
+ return config;
70
+ },
71
+ /**
72
+ * 响应拦截
73
+ */
74
+ onResponse: (response) => {
75
+ if (!enabled) return response;
76
+ const info = createDebugInfo(response.config, response);
77
+ const duration = Date.now() - info.timestamp;
78
+ info.duration = duration;
79
+ printDebug(info);
80
+ return response;
81
+ },
82
+ /**
83
+ * 错误拦截
84
+ */
85
+ onError: (error) => {
86
+ if (!enabled) return error;
87
+ const info = createDebugInfo(error.config || {}, void 0, error);
88
+ printDebug(info);
89
+ return error;
90
+ }
91
+ };
92
+ }
93
+ export class DebugLogger {
94
+ logs = [];
95
+ maxLogs = 100;
96
+ /**
97
+ * 添加日志
98
+ */
99
+ addLog(info) {
100
+ this.logs.push(info);
101
+ if (this.logs.length > this.maxLogs) {
102
+ this.logs.shift();
103
+ }
104
+ }
105
+ /**
106
+ * 获取所有日志
107
+ */
108
+ getLogs() {
109
+ return [...this.logs];
110
+ }
111
+ /**
112
+ * 清除日志
113
+ */
114
+ clear() {
115
+ this.logs = [];
116
+ }
117
+ /**
118
+ * 根据请求 ID 查找日志
119
+ */
120
+ findByRequestId(requestId) {
121
+ return this.logs.filter((log) => log.requestId === requestId);
122
+ }
123
+ /**
124
+ * 导出日志
125
+ */
126
+ export() {
127
+ return JSON.stringify(this.logs, null, 2);
128
+ }
129
+ }
130
+ export const debugLogger = new DebugLogger();
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _progress = require("./progress.cjs");
7
+ Object.keys(_progress).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _progress[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _progress[key];
14
+ }
15
+ });
16
+ });
17
+ var _security = require("./security.cjs");
18
+ Object.keys(_security).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _security[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _security[key];
25
+ }
26
+ });
27
+ });
28
+ var _debug = require("./debug.cjs");
29
+ Object.keys(_debug).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _debug[key]) return;
32
+ Object.defineProperty(exports, key, {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _debug[key];
36
+ }
37
+ });
38
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 拦截器系统导出
3
+ */
4
+ export * from './progress';
5
+ export * from './security';
6
+ export * from './debug';
@@ -0,0 +1,3 @@
1
+ export * from "./progress.mjs";
2
+ export * from "./security.mjs";
3
+ export * from "./debug.mjs";
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.XHRProgressHandler = exports.FetchProgressHandler = void 0;
7
+ exports.createProgressInterceptor = createProgressInterceptor;
8
+ function createProgressInterceptor(options) {
9
+ const {
10
+ onUploadProgress,
11
+ onDownloadProgress
12
+ } = options;
13
+ let uploadStartTime = 0;
14
+ let downloadStartTime = 0;
15
+ const calculateRate = (loaded, startTime) => {
16
+ const elapsed = (Date.now() - startTime) / 1e3;
17
+ return elapsed > 0 ? loaded / elapsed : 0;
18
+ };
19
+ const calculateEstimated = (loaded, total, rate) => {
20
+ if (rate <= 0 || total <= 0) return void 0;
21
+ const remaining = total - loaded;
22
+ return remaining > 0 ? remaining / rate * 1e3 : 0;
23
+ };
24
+ const createProgressHandler = isUpload => {
25
+ return event => {
26
+ const startTime = isUpload ? uploadStartTime : downloadStartTime;
27
+ const rate = calculateRate(event.loaded, startTime);
28
+ const estimated = calculateEstimated(event.loaded, event.total, rate);
29
+ const progressEvent = {
30
+ ...event,
31
+ rate,
32
+ estimated
33
+ };
34
+ if (isUpload) {
35
+ onUploadProgress?.(progressEvent);
36
+ } else {
37
+ onDownloadProgress?.(progressEvent);
38
+ }
39
+ };
40
+ };
41
+ return {
42
+ /**
43
+ * 请求拦截 - 初始化上传进度
44
+ */
45
+ onRequest: config => {
46
+ uploadStartTime = Date.now();
47
+ return config;
48
+ },
49
+ /**
50
+ * 响应拦截 - 初始化下载进度
51
+ */
52
+ onResponse: response => {
53
+ downloadStartTime = Date.now();
54
+ return response;
55
+ },
56
+ /**
57
+ * 获取上传进度处理器
58
+ */
59
+ getUploadHandler: createProgressHandler(true),
60
+ /**
61
+ * 获取下载进度处理器
62
+ */
63
+ getDownloadHandler: createProgressHandler(false)
64
+ };
65
+ }
66
+ class XHRProgressHandler {
67
+ xhr = null;
68
+ onUploadProgress;
69
+ onDownloadProgress;
70
+ uploadStartTime = 0;
71
+ downloadStartTime = 0;
72
+ constructor(options) {
73
+ this.onUploadProgress = options.onUploadProgress;
74
+ this.onDownloadProgress = options.onDownloadProgress;
75
+ }
76
+ /**
77
+ * 绑定 XHR 事件
78
+ */
79
+ bind(xhr) {
80
+ this.xhr = xhr;
81
+ if (this.onUploadProgress) {
82
+ xhr.upload.addEventListener("progress", event => {
83
+ if (event.lengthComputable) {
84
+ this.handleUploadProgress(event);
85
+ }
86
+ });
87
+ }
88
+ if (this.onDownloadProgress) {
89
+ xhr.addEventListener("progress", event => {
90
+ if (event.lengthComputable) {
91
+ this.handleDownloadProgress(event);
92
+ }
93
+ });
94
+ }
95
+ }
96
+ handleUploadProgress(event) {
97
+ if (!this.onUploadProgress) return;
98
+ const now = Date.now();
99
+ const elapsed = (now - this.uploadStartTime) / 1e3;
100
+ const rate = elapsed > 0 ? event.loaded / elapsed : 0;
101
+ const estimated = rate > 0 ? (event.total - event.loaded) / rate * 1e3 : void 0;
102
+ this.onUploadProgress({
103
+ loaded: event.loaded,
104
+ total: event.total,
105
+ percent: event.loaded / event.total * 100,
106
+ rate,
107
+ estimated
108
+ });
109
+ }
110
+ handleDownloadProgress(event) {
111
+ if (!this.onDownloadProgress) return;
112
+ const now = Date.now();
113
+ const elapsed = (now - this.downloadStartTime) / 1e3;
114
+ const rate = elapsed > 0 ? event.loaded / elapsed : 0;
115
+ const estimated = rate > 0 ? (event.total - event.loaded) / rate * 1e3 : void 0;
116
+ this.onDownloadProgress({
117
+ loaded: event.loaded,
118
+ total: event.total,
119
+ percent: event.loaded / event.total * 100,
120
+ rate,
121
+ estimated
122
+ });
123
+ }
124
+ /**
125
+ * 开始上传
126
+ */
127
+ startUpload() {
128
+ this.uploadStartTime = Date.now();
129
+ }
130
+ /**
131
+ * 开始下载
132
+ */
133
+ startDownload() {
134
+ this.downloadStartTime = Date.now();
135
+ }
136
+ }
137
+ exports.XHRProgressHandler = XHRProgressHandler;
138
+ class FetchProgressHandler {
139
+ onDownloadProgress;
140
+ downloadStartTime = 0;
141
+ downloadedBytes = 0;
142
+ totalBytes = 0;
143
+ constructor(options) {
144
+ this.onDownloadProgress = options.onDownloadProgress;
145
+ }
146
+ /**
147
+ * 获取读取处理器
148
+ */
149
+ getReaderHandler() {
150
+ return (chunk, total) => {
151
+ this.downloadedBytes += chunk.length;
152
+ if (total !== void 0) {
153
+ this.totalBytes = total;
154
+ }
155
+ if (this.onDownloadProgress) {
156
+ const now = Date.now();
157
+ const elapsed = (now - this.downloadStartTime) / 1e3;
158
+ const rate = elapsed > 0 ? this.downloadedBytes / elapsed : 0;
159
+ const estimated = rate > 0 && this.totalBytes > 0 ? (this.totalBytes - this.downloadedBytes) / rate * 1e3 : void 0;
160
+ this.onDownloadProgress({
161
+ loaded: this.downloadedBytes,
162
+ total: this.totalBytes,
163
+ percent: this.totalBytes > 0 ? this.downloadedBytes / this.totalBytes * 100 : 0,
164
+ rate,
165
+ estimated
166
+ });
167
+ }
168
+ };
169
+ }
170
+ /**
171
+ * 开始下载
172
+ */
173
+ startDownload() {
174
+ this.downloadStartTime = Date.now();
175
+ this.downloadedBytes = 0;
176
+ this.totalBytes = 0;
177
+ }
178
+ /**
179
+ * 设置总字节数
180
+ */
181
+ setTotal(total) {
182
+ this.totalBytes = total;
183
+ }
184
+ }
185
+ exports.FetchProgressHandler = FetchProgressHandler;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * 进度监听拦截器
3
+ * 支持上传和下载进度
4
+ */
5
+ import type { InternalRequestOptions, RequestResponse } from '../types';
6
+ /** 进度事件 */
7
+ export interface ProgressEvent {
8
+ /** 已传输字节 */
9
+ loaded: number;
10
+ /** 总字节 */
11
+ total: number;
12
+ /** 进度百分比 (0-100) */
13
+ percent: number;
14
+ /** 传输速率 (bytes/s) */
15
+ rate?: number;
16
+ /** 预计剩余时间 (ms) */
17
+ estimated?: number;
18
+ }
19
+ /** 进度回调函数 */
20
+ export type ProgressCallback = (event: ProgressEvent) => void;
21
+ /** 进度拦截器配置 */
22
+ export interface ProgressInterceptorOptions {
23
+ /** 上传进度回调 */
24
+ onUploadProgress?: ProgressCallback;
25
+ /** 下载进度回调 */
26
+ onDownloadProgress?: ProgressCallback;
27
+ }
28
+ /**
29
+ * 创建进度拦截器
30
+ */
31
+ export declare function createProgressInterceptor(options: ProgressInterceptorOptions): {
32
+ /**
33
+ * 请求拦截 - 初始化上传进度
34
+ */
35
+ onRequest: (config: InternalRequestOptions) => InternalRequestOptions;
36
+ /**
37
+ * 响应拦截 - 初始化下载进度
38
+ */
39
+ onResponse: <T>(response: RequestResponse<T>) => RequestResponse<T>;
40
+ /**
41
+ * 获取上传进度处理器
42
+ */
43
+ getUploadHandler: (event: ProgressEvent) => void;
44
+ /**
45
+ * 获取下载进度处理器
46
+ */
47
+ getDownloadHandler: (event: ProgressEvent) => void;
48
+ };
49
+ /**
50
+ * XHR 进度处理器
51
+ * 用于传统浏览器的 XMLHttpRequest
52
+ */
53
+ export declare class XHRProgressHandler {
54
+ private xhr;
55
+ private onUploadProgress?;
56
+ private onDownloadProgress?;
57
+ private uploadStartTime;
58
+ private downloadStartTime;
59
+ constructor(options: ProgressInterceptorOptions);
60
+ /**
61
+ * 绑定 XHR 事件
62
+ */
63
+ bind(xhr: XMLHttpRequest): void;
64
+ private handleUploadProgress;
65
+ private handleDownloadProgress;
66
+ /**
67
+ * 开始上传
68
+ */
69
+ startUpload(): void;
70
+ /**
71
+ * 开始下载
72
+ */
73
+ startDownload(): void;
74
+ }
75
+ /**
76
+ * Fetch 流式进度处理器
77
+ * 用于 Fetch API 的响应体流式读取
78
+ */
79
+ export declare class FetchProgressHandler {
80
+ private onDownloadProgress?;
81
+ private downloadStartTime;
82
+ private downloadedBytes;
83
+ private totalBytes;
84
+ constructor(options: ProgressInterceptorOptions);
85
+ /**
86
+ * 获取读取处理器
87
+ */
88
+ getReaderHandler(): (chunk: Uint8Array, total?: number) => void;
89
+ /**
90
+ * 开始下载
91
+ */
92
+ startDownload(): void;
93
+ /**
94
+ * 设置总字节数
95
+ */
96
+ setTotal(total: number): void;
97
+ }
@@ -0,0 +1,177 @@
1
+ export function createProgressInterceptor(options) {
2
+ const { onUploadProgress, onDownloadProgress } = options;
3
+ let uploadStartTime = 0;
4
+ let downloadStartTime = 0;
5
+ const calculateRate = (loaded, startTime) => {
6
+ const elapsed = (Date.now() - startTime) / 1e3;
7
+ return elapsed > 0 ? loaded / elapsed : 0;
8
+ };
9
+ const calculateEstimated = (loaded, total, rate) => {
10
+ if (rate <= 0 || total <= 0) return void 0;
11
+ const remaining = total - loaded;
12
+ return remaining > 0 ? remaining / rate * 1e3 : 0;
13
+ };
14
+ const createProgressHandler = (isUpload) => {
15
+ return (event) => {
16
+ const startTime = isUpload ? uploadStartTime : downloadStartTime;
17
+ const rate = calculateRate(event.loaded, startTime);
18
+ const estimated = calculateEstimated(event.loaded, event.total, rate);
19
+ const progressEvent = {
20
+ ...event,
21
+ rate,
22
+ estimated
23
+ };
24
+ if (isUpload) {
25
+ onUploadProgress?.(progressEvent);
26
+ } else {
27
+ onDownloadProgress?.(progressEvent);
28
+ }
29
+ };
30
+ };
31
+ return {
32
+ /**
33
+ * 请求拦截 - 初始化上传进度
34
+ */
35
+ onRequest: (config) => {
36
+ uploadStartTime = Date.now();
37
+ return config;
38
+ },
39
+ /**
40
+ * 响应拦截 - 初始化下载进度
41
+ */
42
+ onResponse: (response) => {
43
+ downloadStartTime = Date.now();
44
+ return response;
45
+ },
46
+ /**
47
+ * 获取上传进度处理器
48
+ */
49
+ getUploadHandler: createProgressHandler(true),
50
+ /**
51
+ * 获取下载进度处理器
52
+ */
53
+ getDownloadHandler: createProgressHandler(false)
54
+ };
55
+ }
56
+ export class XHRProgressHandler {
57
+ xhr = null;
58
+ onUploadProgress;
59
+ onDownloadProgress;
60
+ uploadStartTime = 0;
61
+ downloadStartTime = 0;
62
+ constructor(options) {
63
+ this.onUploadProgress = options.onUploadProgress;
64
+ this.onDownloadProgress = options.onDownloadProgress;
65
+ }
66
+ /**
67
+ * 绑定 XHR 事件
68
+ */
69
+ bind(xhr) {
70
+ this.xhr = xhr;
71
+ if (this.onUploadProgress) {
72
+ xhr.upload.addEventListener("progress", (event) => {
73
+ if (event.lengthComputable) {
74
+ this.handleUploadProgress(
75
+ event
76
+ );
77
+ }
78
+ });
79
+ }
80
+ if (this.onDownloadProgress) {
81
+ xhr.addEventListener("progress", (event) => {
82
+ if (event.lengthComputable) {
83
+ this.handleDownloadProgress(
84
+ event
85
+ );
86
+ }
87
+ });
88
+ }
89
+ }
90
+ handleUploadProgress(event) {
91
+ if (!this.onUploadProgress) return;
92
+ const now = Date.now();
93
+ const elapsed = (now - this.uploadStartTime) / 1e3;
94
+ const rate = elapsed > 0 ? event.loaded / elapsed : 0;
95
+ const estimated = rate > 0 ? (event.total - event.loaded) / rate * 1e3 : void 0;
96
+ this.onUploadProgress({
97
+ loaded: event.loaded,
98
+ total: event.total,
99
+ percent: event.loaded / event.total * 100,
100
+ rate,
101
+ estimated
102
+ });
103
+ }
104
+ handleDownloadProgress(event) {
105
+ if (!this.onDownloadProgress) return;
106
+ const now = Date.now();
107
+ const elapsed = (now - this.downloadStartTime) / 1e3;
108
+ const rate = elapsed > 0 ? event.loaded / elapsed : 0;
109
+ const estimated = rate > 0 ? (event.total - event.loaded) / rate * 1e3 : void 0;
110
+ this.onDownloadProgress({
111
+ loaded: event.loaded,
112
+ total: event.total,
113
+ percent: event.loaded / event.total * 100,
114
+ rate,
115
+ estimated
116
+ });
117
+ }
118
+ /**
119
+ * 开始上传
120
+ */
121
+ startUpload() {
122
+ this.uploadStartTime = Date.now();
123
+ }
124
+ /**
125
+ * 开始下载
126
+ */
127
+ startDownload() {
128
+ this.downloadStartTime = Date.now();
129
+ }
130
+ }
131
+ export class FetchProgressHandler {
132
+ onDownloadProgress;
133
+ downloadStartTime = 0;
134
+ downloadedBytes = 0;
135
+ totalBytes = 0;
136
+ constructor(options) {
137
+ this.onDownloadProgress = options.onDownloadProgress;
138
+ }
139
+ /**
140
+ * 获取读取处理器
141
+ */
142
+ getReaderHandler() {
143
+ return (chunk, total) => {
144
+ this.downloadedBytes += chunk.length;
145
+ if (total !== void 0) {
146
+ this.totalBytes = total;
147
+ }
148
+ if (this.onDownloadProgress) {
149
+ const now = Date.now();
150
+ const elapsed = (now - this.downloadStartTime) / 1e3;
151
+ const rate = elapsed > 0 ? this.downloadedBytes / elapsed : 0;
152
+ const estimated = rate > 0 && this.totalBytes > 0 ? (this.totalBytes - this.downloadedBytes) / rate * 1e3 : void 0;
153
+ this.onDownloadProgress({
154
+ loaded: this.downloadedBytes,
155
+ total: this.totalBytes,
156
+ percent: this.totalBytes > 0 ? this.downloadedBytes / this.totalBytes * 100 : 0,
157
+ rate,
158
+ estimated
159
+ });
160
+ }
161
+ };
162
+ }
163
+ /**
164
+ * 开始下载
165
+ */
166
+ startDownload() {
167
+ this.downloadStartTime = Date.now();
168
+ this.downloadedBytes = 0;
169
+ this.totalBytes = 0;
170
+ }
171
+ /**
172
+ * 设置总字节数
173
+ */
174
+ setTotal(total) {
175
+ this.totalBytes = total;
176
+ }
177
+ }