@pyrokine/mcp-chrome 1.0.0

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 (100) hide show
  1. package/README.md +333 -0
  2. package/dist/anti-detection/behavior.d.ts +58 -0
  3. package/dist/anti-detection/behavior.d.ts.map +1 -0
  4. package/dist/anti-detection/behavior.js +113 -0
  5. package/dist/anti-detection/behavior.js.map +1 -0
  6. package/dist/anti-detection/index.d.ts +6 -0
  7. package/dist/anti-detection/index.d.ts.map +1 -0
  8. package/dist/anti-detection/index.js +6 -0
  9. package/dist/anti-detection/index.js.map +1 -0
  10. package/dist/anti-detection/injection.d.ts +19 -0
  11. package/dist/anti-detection/injection.d.ts.map +1 -0
  12. package/dist/anti-detection/injection.js +270 -0
  13. package/dist/anti-detection/injection.js.map +1 -0
  14. package/dist/cdp/client.d.ts +73 -0
  15. package/dist/cdp/client.d.ts.map +1 -0
  16. package/dist/cdp/client.js +275 -0
  17. package/dist/cdp/client.js.map +1 -0
  18. package/dist/cdp/index.d.ts +6 -0
  19. package/dist/cdp/index.d.ts.map +1 -0
  20. package/dist/cdp/index.js +6 -0
  21. package/dist/cdp/index.js.map +1 -0
  22. package/dist/cdp/launcher.d.ts +42 -0
  23. package/dist/cdp/launcher.d.ts.map +1 -0
  24. package/dist/cdp/launcher.js +181 -0
  25. package/dist/cdp/launcher.js.map +1 -0
  26. package/dist/core/auto-wait.d.ts +71 -0
  27. package/dist/core/auto-wait.d.ts.map +1 -0
  28. package/dist/core/auto-wait.js +165 -0
  29. package/dist/core/auto-wait.js.map +1 -0
  30. package/dist/core/errors.d.ts +123 -0
  31. package/dist/core/errors.d.ts.map +1 -0
  32. package/dist/core/errors.js +226 -0
  33. package/dist/core/errors.js.map +1 -0
  34. package/dist/core/index.d.ts +10 -0
  35. package/dist/core/index.d.ts.map +1 -0
  36. package/dist/core/index.js +10 -0
  37. package/dist/core/index.js.map +1 -0
  38. package/dist/core/locator.d.ts +130 -0
  39. package/dist/core/locator.d.ts.map +1 -0
  40. package/dist/core/locator.js +402 -0
  41. package/dist/core/locator.js.map +1 -0
  42. package/dist/core/retry.d.ts +27 -0
  43. package/dist/core/retry.d.ts.map +1 -0
  44. package/dist/core/retry.js +51 -0
  45. package/dist/core/retry.js.map +1 -0
  46. package/dist/core/session.d.ts +254 -0
  47. package/dist/core/session.d.ts.map +1 -0
  48. package/dist/core/session.js +893 -0
  49. package/dist/core/session.js.map +1 -0
  50. package/dist/core/types.d.ts +263 -0
  51. package/dist/core/types.d.ts.map +1 -0
  52. package/dist/core/types.js +90 -0
  53. package/dist/core/types.js.map +1 -0
  54. package/dist/index.d.ts +14 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +121 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/tools/browse.d.ts +92 -0
  59. package/dist/tools/browse.d.ts.map +1 -0
  60. package/dist/tools/browse.js +368 -0
  61. package/dist/tools/browse.js.map +1 -0
  62. package/dist/tools/cookies.d.ts +75 -0
  63. package/dist/tools/cookies.d.ts.map +1 -0
  64. package/dist/tools/cookies.js +230 -0
  65. package/dist/tools/cookies.js.map +1 -0
  66. package/dist/tools/evaluate.d.ts +45 -0
  67. package/dist/tools/evaluate.d.ts.map +1 -0
  68. package/dist/tools/evaluate.js +85 -0
  69. package/dist/tools/evaluate.js.map +1 -0
  70. package/dist/tools/extract.d.ts +213 -0
  71. package/dist/tools/extract.d.ts.map +1 -0
  72. package/dist/tools/extract.js +304 -0
  73. package/dist/tools/extract.js.map +1 -0
  74. package/dist/tools/index.d.ts +13 -0
  75. package/dist/tools/index.d.ts.map +1 -0
  76. package/dist/tools/index.js +13 -0
  77. package/dist/tools/index.js.map +1 -0
  78. package/dist/tools/input.d.ts +241 -0
  79. package/dist/tools/input.d.ts.map +1 -0
  80. package/dist/tools/input.js +325 -0
  81. package/dist/tools/input.js.map +1 -0
  82. package/dist/tools/logs.d.ts +57 -0
  83. package/dist/tools/logs.d.ts.map +1 -0
  84. package/dist/tools/logs.js +165 -0
  85. package/dist/tools/logs.js.map +1 -0
  86. package/dist/tools/manage.d.ts +65 -0
  87. package/dist/tools/manage.d.ts.map +1 -0
  88. package/dist/tools/manage.js +270 -0
  89. package/dist/tools/manage.js.map +1 -0
  90. package/dist/tools/schema.d.ts +261 -0
  91. package/dist/tools/schema.d.ts.map +1 -0
  92. package/dist/tools/schema.js +151 -0
  93. package/dist/tools/schema.js.map +1 -0
  94. package/dist/tools/wait.d.ts +203 -0
  95. package/dist/tools/wait.d.ts.map +1 -0
  96. package/dist/tools/wait.js +254 -0
  97. package/dist/tools/wait.js.map +1 -0
  98. package/package.json +43 -0
  99. package/scripts/start-chrome-headless.sh +37 -0
  100. package/scripts/start-chrome.sh +41 -0
@@ -0,0 +1,402 @@
1
+ /**
2
+ * 元素定位器
3
+ *
4
+ * 统一的元素定位逻辑,支持多种定位方式:
5
+ * - 可访问性树(role/name)
6
+ * - 文本内容
7
+ * - CSS 选择器
8
+ * - XPath
9
+ * - 坐标
10
+ *
11
+ * 设计原则:
12
+ * - 封装:隐藏定位细节,暴露简洁接口
13
+ * - 以对象取代基本类型:Target 对象而非字符串
14
+ */
15
+ import { ElementNotFoundError } from './errors.js';
16
+ import { withRetry } from './retry.js';
17
+ import { isAltTarget, isCoordinateTarget, isCSSTarget, isLabelTarget, isPlaceholderTarget, isRoleTarget, isTestIdTarget, isTextTarget, isTitleTarget, isXPathTarget, } from './types.js';
18
+ const DEFAULT_TIMEOUT = 30000;
19
+ /**
20
+ * 转义 XPath 字符串中的引号
21
+ * XPath 1.0 没有转义机制,需要用 concat() 拼接单双引号
22
+ *
23
+ * 例如: "It's a \"test\"" => concat('It', "'", 's a "test"')
24
+ */
25
+ function escapeXPathString(str) {
26
+ if (!str.includes('\'')) {
27
+ return `'${str}'`;
28
+ }
29
+ if (!str.includes('"')) {
30
+ return `"${str}"`;
31
+ }
32
+ // 同时包含单双引号,使用 concat() 拼接
33
+ // 策略:遇到单引号用双引号包裹,其他部分用单引号包裹
34
+ const parts = [];
35
+ let current = '';
36
+ for (const char of str) {
37
+ if (char === '\'') {
38
+ if (current) {
39
+ parts.push(`'${current}'`);
40
+ current = '';
41
+ }
42
+ parts.push(`"'"`);
43
+ }
44
+ else {
45
+ current += char;
46
+ }
47
+ }
48
+ if (current) {
49
+ parts.push(`'${current}'`);
50
+ }
51
+ return `concat(${parts.join(', ')})`;
52
+ }
53
+ /**
54
+ * 转义 JavaScript 字符串
55
+ */
56
+ function escapeJSString(str) {
57
+ return str
58
+ .replace(/\\/g, '\\\\')
59
+ .replace(/'/g, '\\\'')
60
+ .replace(/"/g, '\\"')
61
+ .replace(/\n/g, '\\n')
62
+ .replace(/\r/g, '\\r')
63
+ .replace(/\t/g, '\\t');
64
+ }
65
+ /**
66
+ * 转义 CSS 属性选择器值
67
+ * CSS.escape() 的 polyfill
68
+ */
69
+ function escapeCSSAttributeValue(str) {
70
+ return str.replace(/["\\]/g, '\\$&');
71
+ }
72
+ /**
73
+ * 元素定位器
74
+ */
75
+ export class Locator {
76
+ cdp;
77
+ target;
78
+ sessionId;
79
+ logs = [];
80
+ timeout;
81
+ getUrl;
82
+ constructor(cdp, target, sessionId, options = {}) {
83
+ this.cdp = cdp;
84
+ this.target = target;
85
+ this.sessionId = sessionId;
86
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
87
+ this.getUrl = options.getUrl;
88
+ }
89
+ /**
90
+ * 查找元素,返回节点 ID(带重试)
91
+ */
92
+ async find() {
93
+ this.logs = [];
94
+ this.log(`定位元素: ${JSON.stringify(this.target)}`);
95
+ if (isCoordinateTarget(this.target)) {
96
+ // 坐标定位不需要 NodeId
97
+ throw new Error('坐标定位不支持 find(),请使用 getClickablePoint()');
98
+ }
99
+ return withRetry(() => this.findInternal(), { timeout: this.timeout });
100
+ }
101
+ /**
102
+ * 获取元素中心坐标(用于点击)
103
+ */
104
+ async getClickablePoint() {
105
+ if (isCoordinateTarget(this.target)) {
106
+ return { x: this.target.x, y: this.target.y };
107
+ }
108
+ const nodeId = await this.find();
109
+ const box = await this.getBoxModel(nodeId);
110
+ return {
111
+ x: box.x + box.width / 2,
112
+ y: box.y + box.height / 2,
113
+ };
114
+ }
115
+ /**
116
+ * 获取元素边界框
117
+ */
118
+ async getBoundingBox() {
119
+ if (isCoordinateTarget(this.target)) {
120
+ return { x: this.target.x, y: this.target.y, width: 0, height: 0 };
121
+ }
122
+ const nodeId = await this.find();
123
+ return this.getBoxModel(nodeId);
124
+ }
125
+ /**
126
+ * 在找到的元素上执行函数
127
+ *
128
+ * @param fn 要执行的函数字符串,元素作为第一个参数
129
+ * @returns 函数返回值
130
+ */
131
+ async evaluateOn(fn) {
132
+ const nodeId = await this.find();
133
+ // 将 nodeId 转换为 RemoteObjectId
134
+ const { object } = (await this.send('DOM.resolveNode', {
135
+ nodeId,
136
+ }));
137
+ if (!object?.objectId) {
138
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
139
+ }
140
+ // 在元素上执行函数
141
+ const { result, exceptionDetails } = (await this.send('Runtime.callFunctionOn', {
142
+ objectId: object.objectId,
143
+ functionDeclaration: fn,
144
+ returnByValue: true,
145
+ }));
146
+ if (exceptionDetails) {
147
+ throw new Error(`执行失败: ${exceptionDetails.text}`);
148
+ }
149
+ return result.value;
150
+ }
151
+ /**
152
+ * 获取定位日志
153
+ */
154
+ getLogs() {
155
+ return this.logs;
156
+ }
157
+ /**
158
+ * 查找元素的内部实现(单次尝试)
159
+ */
160
+ async findInternal() {
161
+ if (isRoleTarget(this.target)) {
162
+ return this.findByAccessibility();
163
+ }
164
+ if (isTextTarget(this.target)) {
165
+ return this.findByText();
166
+ }
167
+ if (isLabelTarget(this.target)) {
168
+ return this.findByLabel();
169
+ }
170
+ if (isPlaceholderTarget(this.target)) {
171
+ return this.findByPlaceholder();
172
+ }
173
+ if (isTitleTarget(this.target)) {
174
+ return this.findByTitle();
175
+ }
176
+ if (isAltTarget(this.target)) {
177
+ return this.findByAlt();
178
+ }
179
+ if (isTestIdTarget(this.target)) {
180
+ return this.findByTestId();
181
+ }
182
+ if (isCSSTarget(this.target)) {
183
+ return this.findByCSS();
184
+ }
185
+ if (isXPathTarget(this.target)) {
186
+ return this.findByXPath();
187
+ }
188
+ throw new Error(`不支持的 target 类型: ${JSON.stringify(this.target)}`);
189
+ }
190
+ /**
191
+ * 通过可访问性树定位
192
+ */
193
+ async findByAccessibility() {
194
+ const { role, name } = this.target;
195
+ this.log(`使用可访问性树定位: role=${role}, name=${name ?? '(any)'}`);
196
+ // 启用可访问性
197
+ await this.send('Accessibility.enable');
198
+ // 获取整个可访问性树
199
+ const { nodes } = (await this.send('Accessibility.getFullAXTree'));
200
+ // 查找匹配的节点
201
+ for (const node of nodes) {
202
+ if (node.role?.value?.toLowerCase() !== role.toLowerCase()) {
203
+ continue;
204
+ }
205
+ if (name !== undefined && node.name?.value !== name) {
206
+ continue;
207
+ }
208
+ if (node.backendDOMNodeId) {
209
+ this.log(`找到元素: backendDOMNodeId=${node.backendDOMNodeId}`);
210
+ // 将 backendDOMNodeId 转换为 nodeId
211
+ const { nodeIds } = (await this.send('DOM.pushNodesByBackendIdsToFrontend', {
212
+ backendNodeIds: [node.backendDOMNodeId],
213
+ }));
214
+ if (nodeIds.length > 0 && nodeIds[0] !== 0) {
215
+ return nodeIds[0];
216
+ }
217
+ }
218
+ }
219
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
220
+ }
221
+ /**
222
+ * 通过文本内容定位
223
+ */
224
+ async findByText() {
225
+ const { text, exact = false } = this.target;
226
+ this.log(`使用文本内容定位: text=${text}, exact=${exact}`);
227
+ // 使用 XPath 查找包含文本的元素(正确转义引号)
228
+ const escapedText = escapeXPathString(text);
229
+ const xpath = exact
230
+ ? `//*[text()=${escapedText}]`
231
+ : `//*[contains(text(),${escapedText})]`;
232
+ return this.findByXPathInternal(xpath);
233
+ }
234
+ /**
235
+ * 通过 label 定位
236
+ */
237
+ async findByLabel() {
238
+ const { label, exact = false } = this.target;
239
+ this.log(`使用 label 定位: label=${label}, exact=${exact}`);
240
+ // 转义 JS 字符串
241
+ const escapedLabel = escapeJSString(label);
242
+ // 使用 Runtime.evaluate 执行复杂查询
243
+ const { result } = (await this.send('Runtime.evaluate', {
244
+ expression: `
245
+ (function() {
246
+ const targetLabel = "${escapedLabel}";
247
+ const isExact = ${exact};
248
+ const labels = document.querySelectorAll('label');
249
+ for (const label of labels) {
250
+ const text = label.textContent?.trim() ?? '';
251
+ const match = isExact ? text === targetLabel : text.includes(targetLabel);
252
+ if (match) {
253
+ // 通过 for 属性找关联元素
254
+ if (label.htmlFor) {
255
+ const input = document.getElementById(label.htmlFor);
256
+ if (input) return input;
257
+ }
258
+ // 找 label 内部的 input
259
+ const input = label.querySelector('input, select, textarea');
260
+ if (input) return input;
261
+ }
262
+ }
263
+ return null;
264
+ })()
265
+ `,
266
+ returnByValue: false,
267
+ }));
268
+ if (!result.objectId) {
269
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
270
+ }
271
+ return this.objectIdToNodeId(result.objectId);
272
+ }
273
+ /**
274
+ * 通过 placeholder 定位
275
+ */
276
+ async findByPlaceholder() {
277
+ const { placeholder, exact = false } = this.target;
278
+ this.log(`使用 placeholder 定位: placeholder=${placeholder}, exact=${exact}`);
279
+ const escaped = escapeCSSAttributeValue(placeholder);
280
+ const css = exact
281
+ ? `[placeholder="${escaped}"]`
282
+ : `[placeholder*="${escaped}"]`;
283
+ return this.findByCSSInternal(css);
284
+ }
285
+ /**
286
+ * 通过 title 属性定位
287
+ */
288
+ async findByTitle() {
289
+ const { title, exact = false } = this.target;
290
+ this.log(`使用 title 属性定位: title=${title}, exact=${exact}`);
291
+ const escaped = escapeCSSAttributeValue(title);
292
+ const css = exact ? `[title="${escaped}"]` : `[title*="${escaped}"]`;
293
+ return this.findByCSSInternal(css);
294
+ }
295
+ /**
296
+ * 通过 alt 属性定位
297
+ */
298
+ async findByAlt() {
299
+ const { alt, exact = false } = this.target;
300
+ this.log(`使用 alt 属性定位: alt=${alt}, exact=${exact}`);
301
+ const escaped = escapeCSSAttributeValue(alt);
302
+ const css = exact ? `[alt="${escaped}"]` : `[alt*="${escaped}"]`;
303
+ return this.findByCSSInternal(css);
304
+ }
305
+ /**
306
+ * 通过 data-testid 定位
307
+ */
308
+ async findByTestId() {
309
+ const { testId } = this.target;
310
+ this.log(`使用 data-testid 定位: testId=${testId}`);
311
+ const escaped = escapeCSSAttributeValue(testId);
312
+ return this.findByCSSInternal(`[data-testid="${escaped}"]`);
313
+ }
314
+ /**
315
+ * 通过 CSS 选择器定位
316
+ */
317
+ async findByCSS() {
318
+ const { css } = this.target;
319
+ this.log(`使用 CSS 选择器定位: css=${css}`);
320
+ return this.findByCSSInternal(css);
321
+ }
322
+ /**
323
+ * 通过 XPath 定位
324
+ */
325
+ async findByXPath() {
326
+ const { xpath } = this.target;
327
+ this.log(`使用 XPath 定位: xpath=${xpath}`);
328
+ return this.findByXPathInternal(xpath);
329
+ }
330
+ /**
331
+ * CSS 选择器定位内部实现
332
+ */
333
+ async findByCSSInternal(css) {
334
+ // 确保 DOM 已启用
335
+ const { root } = (await this.send('DOM.getDocument'));
336
+ const { nodeId } = (await this.send('DOM.querySelector', {
337
+ nodeId: root.nodeId,
338
+ selector: css,
339
+ }));
340
+ if (nodeId === 0) {
341
+ this.log(`元素未找到: ${css}`);
342
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
343
+ }
344
+ this.log(`找到元素: nodeId=${nodeId}`);
345
+ return nodeId;
346
+ }
347
+ /**
348
+ * XPath 定位内部实现
349
+ */
350
+ async findByXPathInternal(xpath) {
351
+ // 使用 Runtime.evaluate 执行 XPath
352
+ const { result } = (await this.send('Runtime.evaluate', {
353
+ expression: `document.evaluate('${xpath.replace(/'/g, '\\\'')}', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue`,
354
+ returnByValue: false,
355
+ }));
356
+ if (!result.objectId) {
357
+ this.log(`元素未找到: ${xpath}`);
358
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
359
+ }
360
+ return this.objectIdToNodeId(result.objectId);
361
+ }
362
+ /**
363
+ * 将 RemoteObject ID 转换为 NodeId
364
+ */
365
+ async objectIdToNodeId(objectId) {
366
+ const { nodeId } = (await this.send('DOM.requestNode', {
367
+ objectId,
368
+ }));
369
+ if (nodeId === 0) {
370
+ throw new ElementNotFoundError(this.target, this.timeout, this.logs, this.getUrl?.());
371
+ }
372
+ this.log(`找到元素: nodeId=${nodeId}`);
373
+ return nodeId;
374
+ }
375
+ /**
376
+ * 获取元素边界框
377
+ */
378
+ async getBoxModel(nodeId) {
379
+ const { model } = (await this.send('DOM.getBoxModel', { nodeId }));
380
+ // content 是 [x1,y1, x2,y2, x3,y3, x4,y4] 格式的四个角坐标
381
+ const [x1, y1, x2, , , , x4, y4] = model.content;
382
+ return {
383
+ x: x1,
384
+ y: y1,
385
+ width: x2 - x1,
386
+ height: y4 - y1,
387
+ };
388
+ }
389
+ /**
390
+ * 发送 CDP 命令
391
+ */
392
+ send(method, params) {
393
+ return this.cdp.send(method, params, this.sessionId);
394
+ }
395
+ /**
396
+ * 记录日志
397
+ */
398
+ log(message) {
399
+ this.logs.push(message);
400
+ }
401
+ }
402
+ //# sourceMappingURL=locator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator.js","sourceRoot":"","sources":["../../src/core/locator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 重试策略
3
+ *
4
+ * 参考 Puppeteer Locator 的重试机制
5
+ * RETRY_DELAY = 100ms
6
+ */
7
+ /**
8
+ * 重试选项
9
+ */
10
+ export interface RetryOptions {
11
+ /** 超时时间(毫秒) */
12
+ timeout?: number;
13
+ /** 重试间隔(毫秒) */
14
+ retryDelay?: number;
15
+ }
16
+ /**
17
+ * 带重试的函数执行
18
+ *
19
+ * 在超时时间内不断重试,直到成功或超时。
20
+ * 超时后抛出最后一次的错误。
21
+ *
22
+ * @param fn 要执行的函数
23
+ * @param options 重试选项
24
+ * @returns 函数返回值
25
+ */
26
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
27
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/core/retry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,eAAe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAKD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC7B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GAC3B,OAAO,CAAC,CAAC,CAAC,CA2BZ"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 重试策略
3
+ *
4
+ * 参考 Puppeteer Locator 的重试机制
5
+ * RETRY_DELAY = 100ms
6
+ */
7
+ import { TimeoutError } from './errors.js';
8
+ const DEFAULT_TIMEOUT = 30000;
9
+ const DEFAULT_RETRY_DELAY = 100;
10
+ /**
11
+ * 带重试的函数执行
12
+ *
13
+ * 在超时时间内不断重试,直到成功或超时。
14
+ * 超时后抛出最后一次的错误。
15
+ *
16
+ * @param fn 要执行的函数
17
+ * @param options 重试选项
18
+ * @returns 函数返回值
19
+ */
20
+ export async function withRetry(fn, options = {}) {
21
+ const { timeout = DEFAULT_TIMEOUT, retryDelay = DEFAULT_RETRY_DELAY } = options;
22
+ const deadline = Date.now() + timeout;
23
+ let lastError = null;
24
+ let attempts = 0;
25
+ while (Date.now() < deadline) {
26
+ attempts++;
27
+ try {
28
+ return await fn();
29
+ }
30
+ catch (error) {
31
+ lastError = error;
32
+ // 如果剩余时间不足以进行下一次重试,直接抛出错误
33
+ if (Date.now() + retryDelay >= deadline) {
34
+ break;
35
+ }
36
+ await delay(retryDelay);
37
+ }
38
+ }
39
+ // 超时,抛出最后的错误或超时错误
40
+ if (lastError) {
41
+ throw lastError;
42
+ }
43
+ throw new TimeoutError(`操作超时 (${timeout}ms, ${attempts} 次尝试)`);
44
+ }
45
+ /**
46
+ * 延迟
47
+ */
48
+ function delay(ms) {
49
+ return new Promise((resolve) => setTimeout(resolve, ms));
50
+ }
51
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/core/retry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,aAAa,CAAA;AAYxC,MAAM,eAAe,GAAO,KAAK,CAAA;AACjC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAE/B;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC3B,EAAoB,EACpB,UAAwB,EAAE;IAE1B,MAAM,EAAC,OAAO,GAAG,eAAe,EAAE,UAAU,GAAG,mBAAmB,EAAC,GAAG,OAAO,CAAA;IAC7E,MAAM,QAAQ,GAAwD,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAA;IAC1F,IAAI,SAAS,GAAyD,IAAI,CAAA;IAC1E,IAAI,QAAQ,GAA0D,CAAC,CAAA;IAEvE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC3B,QAAQ,EAAE,CAAA;QACV,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,EAAE,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,SAAS,GAAG,KAAc,CAAA;YAE1B,0BAA0B;YAC1B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,IAAI,QAAQ,EAAE,CAAC;gBACtC,MAAK;YACT,CAAC;YAED,MAAM,KAAK,CAAC,UAAU,CAAC,CAAA;QAC3B,CAAC;IACL,CAAC;IAED,kBAAkB;IAClB,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,SAAS,CAAA;IACnB,CAAC;IACD,MAAM,IAAI,YAAY,CAAC,SAAS,OAAO,OAAO,QAAQ,OAAO,CAAC,CAAA;AAClE,CAAC;AAED;;GAEG;AACH,SAAS,KAAK,CAAC,EAAU;IACrB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5D,CAAC"}