network-speed-js 1.0.4 → 1.0.5
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.
- package/README.md +90 -28
- package/dist/core/sdk.d.ts +36 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/speed-tester.d.ts +17 -2
- package/dist/core/speed-tester.d.ts.map +1 -1
- package/dist/core/types.d.ts +27 -16
- package/dist/core/types.d.ts.map +1 -1
- package/dist/network-speed-js.js +80 -35
- package/dist/network-speed-js.umd.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,11 +53,31 @@ npm install network-speed-js
|
|
|
53
53
|
|
|
54
54
|
### 原生 JavaScript / TypeScript
|
|
55
55
|
|
|
56
|
+
**方式一:使用图片资源测速(推荐,默认模式,无需CORS)**
|
|
57
|
+
|
|
56
58
|
```typescript
|
|
57
59
|
import { NetworkSpeedSDK } from 'network-speed-js';
|
|
58
60
|
|
|
59
61
|
const sdk = new NetworkSpeedSDK({
|
|
60
|
-
|
|
62
|
+
internetImageUrl: 'https://cdn.example.com/test-image.jpg',
|
|
63
|
+
// 可选:内网图片URL
|
|
64
|
+
intranetImageUrl: 'https://internal-cdn.com/test-image.jpg',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const result = await sdk.test();
|
|
68
|
+
console.log(`网速: ${result.speedMbps} Mbps`);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**方式二:使用任意资源测速(需要CORS支持)**
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { NetworkSpeedSDK } from 'network-speed-js';
|
|
75
|
+
|
|
76
|
+
const sdk = new NetworkSpeedSDK({
|
|
77
|
+
internetUrl: 'https://cdn.example.com/test-file.bin',
|
|
78
|
+
useFetch: true, // 启用fetch模式
|
|
79
|
+
// 可选:内网资源URL
|
|
80
|
+
intranetUrl: 'https://internal-cdn.com/test-file.bin',
|
|
61
81
|
});
|
|
62
82
|
|
|
63
83
|
const result = await sdk.test();
|
|
@@ -84,7 +104,7 @@ const result = ref(null);
|
|
|
84
104
|
const testSpeed = async () => {
|
|
85
105
|
loading.value = true;
|
|
86
106
|
const sdk = new NetworkSpeedSDK({
|
|
87
|
-
|
|
107
|
+
internetImageUrl: 'https://cdn.example.com/test-image.jpg',
|
|
88
108
|
});
|
|
89
109
|
result.value = await sdk.test();
|
|
90
110
|
loading.value = false;
|
|
@@ -105,7 +125,7 @@ function SpeedTest() {
|
|
|
105
125
|
const testSpeed = async () => {
|
|
106
126
|
setLoading(true);
|
|
107
127
|
const sdk = new NetworkSpeedSDK({
|
|
108
|
-
|
|
128
|
+
internetImageUrl: 'https://cdn.example.com/test-image.jpg',
|
|
109
129
|
});
|
|
110
130
|
const data = await sdk.test();
|
|
111
131
|
setResult(data);
|
|
@@ -145,7 +165,7 @@ export class SpeedTestComponent {
|
|
|
145
165
|
async testSpeed() {
|
|
146
166
|
this.loading = true;
|
|
147
167
|
const sdk = new NetworkSpeedSDK({
|
|
148
|
-
|
|
168
|
+
internetImageUrl: 'https://cdn.example.com/test-image.jpg',
|
|
149
169
|
});
|
|
150
170
|
this.result = await sdk.test();
|
|
151
171
|
this.loading = false;
|
|
@@ -163,29 +183,63 @@ export class SpeedTestComponent {
|
|
|
163
183
|
new NetworkSpeedSDK(options?: SpeedTestOptions)
|
|
164
184
|
```
|
|
165
185
|
|
|
166
|
-
|
|
186
|
+
**参数说明:**
|
|
187
|
+
- `options`(可选):配置选项
|
|
188
|
+
- 如果传入配置,可以执行测速
|
|
189
|
+
- 如果不传配置,只能使用工具函数(`getAllResourcesSpeeds`、`observeResource`)
|
|
167
190
|
|
|
168
|
-
|
|
169
|
-
|------|------|--------|------|
|
|
170
|
-
| `intranetUrl` | `string` | `''` | 内网测速资源URL |
|
|
171
|
-
| `internetUrl` | `string` | `''` | 外网测速资源URL(必填) |
|
|
172
|
-
| `autoDetect` | `boolean` | `true` | 是否自动检测内外网 |
|
|
173
|
-
| `timeout` | `number` | `10000` | 超时时间 (ms) |
|
|
174
|
-
| `thresholds` | `object` | `{fast: 10, medium: 2}` | 网速评估阈值 (Mbps) |
|
|
175
|
-
| `resourceType` | `'image' \| 'fetch'` | `'image'` | 资源类型(见下方说明) |
|
|
191
|
+
**配置选项(两种模式):**
|
|
176
192
|
|
|
177
|
-
|
|
193
|
+
**模式一:图片模式(默认,推荐)**
|
|
178
194
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
195
|
+
```typescript
|
|
196
|
+
interface ImageSpeedTestOptions {
|
|
197
|
+
internetImageUrl: string; // ✅ 必填:外网图片URL
|
|
198
|
+
intranetImageUrl?: string; // 可选:内网图片URL
|
|
199
|
+
timeout?: number; // 可选:超时时间 (ms),默认 10000
|
|
200
|
+
autoDetect?: boolean; // 可选:是否自动检测内外网,默认 true
|
|
201
|
+
thresholds?: { // 可选:网速评估阈值 (Mbps)
|
|
202
|
+
fast: number; // 默认 10
|
|
203
|
+
medium: number; // 默认 2
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**模式二:Fetch模式(支持任意资源,需要CORS)**
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface FetchSpeedTestOptions {
|
|
212
|
+
internetUrl: string; // ✅ 必填:外网资源URL
|
|
213
|
+
useFetch: true; // ✅ 必填:启用fetch模式
|
|
214
|
+
intranetUrl?: string; // 可选:内网资源URL
|
|
215
|
+
timeout?: number; // 可选:超时时间 (ms),默认 10000
|
|
216
|
+
autoDetect?: boolean; // 可选:是否自动检测内外网,默认 true
|
|
217
|
+
thresholds?: { // 可选:网速评估阈值 (Mbps)
|
|
218
|
+
fast: number; // 默认 10
|
|
219
|
+
medium: number; // 默认 2
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**使用示例:**
|
|
184
225
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
226
|
+
```typescript
|
|
227
|
+
// ✅ 图片模式(只需要图片URL)
|
|
228
|
+
const sdk1 = new NetworkSpeedSDK({
|
|
229
|
+
internetImageUrl: 'https://cdn.example.com/test.jpg',
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ✅ Fetch模式(需要URL + useFetch: true)
|
|
233
|
+
const sdk2 = new NetworkSpeedSDK({
|
|
234
|
+
internetUrl: 'https://cdn.example.com/test.bin',
|
|
235
|
+
useFetch: true,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// ✅ 无参数实例化(仅用于工具函数)
|
|
239
|
+
const sdk3 = new NetworkSpeedSDK();
|
|
240
|
+
const speeds = sdk3.getAllResourcesSpeeds(); // ✅ 可以使用
|
|
241
|
+
await sdk3.test(); // ❌ 会抛出错误:SDK未配置
|
|
242
|
+
```
|
|
189
243
|
|
|
190
244
|
#### 方法
|
|
191
245
|
|
|
@@ -283,8 +337,7 @@ interface ResourceSpeedInfo {
|
|
|
283
337
|
|
|
284
338
|
```typescript
|
|
285
339
|
const sdk = new NetworkSpeedSDK({
|
|
286
|
-
|
|
287
|
-
// resourceType: 'image', // 默认值,可省略
|
|
340
|
+
internetImageUrl: 'https://cdn.example.com/test-image.jpg',
|
|
288
341
|
});
|
|
289
342
|
|
|
290
343
|
const result = await sdk.test();
|
|
@@ -295,7 +348,7 @@ const result = await sdk.test();
|
|
|
295
348
|
```typescript
|
|
296
349
|
const sdk = new NetworkSpeedSDK({
|
|
297
350
|
internetUrl: 'https://cdn.example.com/test-file.bin',
|
|
298
|
-
|
|
351
|
+
useFetch: true, // 必须启用fetch模式
|
|
299
352
|
});
|
|
300
353
|
|
|
301
354
|
const result = await sdk.test();
|
|
@@ -304,9 +357,18 @@ const result = await sdk.test();
|
|
|
304
357
|
### 3. 内外网自动检测
|
|
305
358
|
|
|
306
359
|
```typescript
|
|
360
|
+
// 图片模式
|
|
361
|
+
const sdk = new NetworkSpeedSDK({
|
|
362
|
+
intranetImageUrl: 'https://internal-cdn.company.com/test.jpg',
|
|
363
|
+
internetImageUrl: 'https://public-cdn.example.com/test.jpg',
|
|
364
|
+
autoDetect: true,
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// 或 Fetch模式
|
|
307
368
|
const sdk = new NetworkSpeedSDK({
|
|
308
|
-
intranetUrl: 'https://internal-cdn.company.com/test.
|
|
309
|
-
internetUrl: 'https://public-cdn.example.com/test.
|
|
369
|
+
intranetUrl: 'https://internal-cdn.company.com/test.bin',
|
|
370
|
+
internetUrl: 'https://public-cdn.example.com/test.bin',
|
|
371
|
+
useFetch: true,
|
|
310
372
|
autoDetect: true,
|
|
311
373
|
});
|
|
312
374
|
|
package/dist/core/sdk.d.ts
CHANGED
|
@@ -4,23 +4,51 @@ import type { SpeedTestOptions, SpeedTestResult, ResourceSpeedInfo } from './typ
|
|
|
4
4
|
*/
|
|
5
5
|
export declare class NetworkSpeedSDK {
|
|
6
6
|
private tester;
|
|
7
|
+
/**
|
|
8
|
+
* 创建SDK实例
|
|
9
|
+
* @param options 配置选项(可选,如果不传则只能使用工具函数,不能执行测速)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // 图片模式(默认,推荐)
|
|
13
|
+
* const sdk = new NetworkSpeedSDK({
|
|
14
|
+
* internetImageUrl: 'https://cdn.example.com/test.jpg',
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Fetch模式(需要CORS)
|
|
19
|
+
* const sdk = new NetworkSpeedSDK({
|
|
20
|
+
* internetUrl: 'https://cdn.example.com/test.bin',
|
|
21
|
+
* useFetch: true,
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // 仅使用工具函数
|
|
26
|
+
* const sdk = new NetworkSpeedSDK();
|
|
27
|
+
* const speeds = sdk.getAllResourcesSpeeds();
|
|
28
|
+
*/
|
|
7
29
|
constructor(options?: SpeedTestOptions);
|
|
8
30
|
/**
|
|
9
31
|
* 执行网速测试
|
|
32
|
+
* @throws {Error} 如果SDK未配置
|
|
10
33
|
*/
|
|
11
34
|
test(): Promise<SpeedTestResult>;
|
|
12
35
|
/**
|
|
13
36
|
* 获取所有已加载资源的速度信息
|
|
37
|
+
* @returns 资源速度信息数组
|
|
14
38
|
*/
|
|
15
39
|
getAllResourcesSpeeds(): ResourceSpeedInfo[];
|
|
16
40
|
/**
|
|
17
41
|
* 监听特定资源的性能数据
|
|
42
|
+
* @param urlPattern URL匹配模式
|
|
43
|
+
* @param callback 回调函数
|
|
44
|
+
* @returns 停止监听的函数
|
|
18
45
|
*/
|
|
19
46
|
observeResource(urlPattern: string, callback: (entry: PerformanceResourceTiming) => void): () => void;
|
|
20
47
|
/**
|
|
21
48
|
* 更新配置
|
|
49
|
+
* @param options 新的配置选项
|
|
22
50
|
*/
|
|
23
|
-
updateOptions(options:
|
|
51
|
+
updateOptions(options: SpeedTestOptions): void;
|
|
24
52
|
/**
|
|
25
53
|
* 销毁SDK实例
|
|
26
54
|
*/
|
|
@@ -28,6 +56,13 @@ export declare class NetworkSpeedSDK {
|
|
|
28
56
|
}
|
|
29
57
|
/**
|
|
30
58
|
* 创建SDK实例的工厂函数
|
|
59
|
+
* @param options 配置选项
|
|
60
|
+
* @returns SDK实例
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* const sdk = createNetworkSpeedSDK({
|
|
64
|
+
* internetImageUrl: 'https://cdn.example.com/test.jpg',
|
|
65
|
+
* });
|
|
31
66
|
*/
|
|
32
67
|
export declare function createNetworkSpeedSDK(options?: SpeedTestOptions): NetworkSpeedSDK;
|
|
33
68
|
export default NetworkSpeedSDK;
|
package/dist/core/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpF;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpF;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA4B;IAE1C;;;;;;;;;;;;;;;;;;;;;OAqBG;gBACS,OAAO,CAAC,EAAE,gBAAgB;IAMtC;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAatC;;;OAGG;IACH,qBAAqB,IAAI,iBAAiB,EAAE;IAI5C;;;;;OAKG;IACH,eAAe,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,GACnD,MAAM,IAAI;IAUb;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAK9C;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAEjF;AAGD,eAAe,eAAe,CAAC"}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { SpeedTestResult, SpeedTestOptions, PerformanceEntryCallback } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 内部标准化配置
|
|
4
|
+
*/
|
|
5
|
+
interface NormalizedOptions {
|
|
6
|
+
intranetUrl: string;
|
|
7
|
+
internetUrl: string;
|
|
8
|
+
timeout: number;
|
|
9
|
+
autoDetect: boolean;
|
|
10
|
+
thresholds: {
|
|
11
|
+
fast: number;
|
|
12
|
+
medium: number;
|
|
13
|
+
};
|
|
14
|
+
useFetch: boolean;
|
|
15
|
+
}
|
|
2
16
|
/**
|
|
3
17
|
* 网速测试核心类
|
|
4
18
|
*/
|
|
5
19
|
export declare class SpeedTester {
|
|
6
20
|
private options;
|
|
7
21
|
private observer;
|
|
8
|
-
constructor(options
|
|
22
|
+
constructor(options: SpeedTestOptions);
|
|
9
23
|
/**
|
|
10
24
|
* 执行测速
|
|
11
25
|
*/
|
|
@@ -33,10 +47,11 @@ export declare class SpeedTester {
|
|
|
33
47
|
/**
|
|
34
48
|
* 更新配置
|
|
35
49
|
*/
|
|
36
|
-
updateOptions(options: Partial<
|
|
50
|
+
updateOptions(options: Partial<NormalizedOptions>): void;
|
|
37
51
|
/**
|
|
38
52
|
* 销毁实例
|
|
39
53
|
*/
|
|
40
54
|
destroy(): void;
|
|
41
55
|
}
|
|
56
|
+
export {};
|
|
42
57
|
//# sourceMappingURL=speed-tester.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speed-tester.d.ts","sourceRoot":"","sources":["../../src/core/speed-tester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"speed-tester.d.ts","sourceRoot":"","sources":["../../src/core/speed-tester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,UAAU,iBAAiB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAoC;gBAExC,OAAO,EAAE,gBAAgB;IAyBrC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAQtC;;OAEG;YACW,kBAAkB;IAehC;;OAEG;IACH,OAAO,CAAC,aAAa;IA0DrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAkBnF;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI;IAIxD;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -33,17 +33,9 @@ export interface ResourceSpeedInfo {
|
|
|
33
33
|
transferSize: number;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* 基础配置选项
|
|
37
37
|
*/
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* SDK配置选项
|
|
41
|
-
*/
|
|
42
|
-
export interface SpeedTestOptions {
|
|
43
|
-
/** 内网测速资源URL */
|
|
44
|
-
intranetUrl?: string;
|
|
45
|
-
/** 外网测速资源URL */
|
|
46
|
-
internetUrl?: string;
|
|
38
|
+
interface BaseSpeedTestOptions {
|
|
47
39
|
/** 超时时间 (ms) */
|
|
48
40
|
timeout?: number;
|
|
49
41
|
/** 是否自动检测内外网 */
|
|
@@ -53,17 +45,36 @@ export interface SpeedTestOptions {
|
|
|
53
45
|
fast: number;
|
|
54
46
|
medium: number;
|
|
55
47
|
};
|
|
56
|
-
/**
|
|
57
|
-
* 资源类型
|
|
58
|
-
* - 'image': 使用 Image 对象加载(默认,不受跨域限制,适用于图片资源)
|
|
59
|
-
* - 'fetch': 使用 fetch API 加载(需要服务器支持 CORS,适用于任意资源)
|
|
60
|
-
*/
|
|
61
|
-
resourceType?: ResourceType;
|
|
62
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* 图片模式配置(默认,不受跨域限制)
|
|
51
|
+
*/
|
|
52
|
+
export interface ImageSpeedTestOptions extends BaseSpeedTestOptions {
|
|
53
|
+
/** 内网测速图片URL */
|
|
54
|
+
intranetImageUrl?: string;
|
|
55
|
+
/** 外网测速图片URL(必填) */
|
|
56
|
+
internetImageUrl: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Fetch模式配置(支持任意资源,需要CORS)
|
|
60
|
+
*/
|
|
61
|
+
export interface FetchSpeedTestOptions extends BaseSpeedTestOptions {
|
|
62
|
+
/** 内网测速资源URL */
|
|
63
|
+
intranetUrl?: string;
|
|
64
|
+
/** 外网测速资源URL(必填) */
|
|
65
|
+
internetUrl: string;
|
|
66
|
+
/** 使用fetch模式 */
|
|
67
|
+
useFetch: true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* SDK配置选项(联合类型)
|
|
71
|
+
*/
|
|
72
|
+
export type SpeedTestOptions = ImageSpeedTestOptions | FetchSpeedTestOptions;
|
|
63
73
|
/**
|
|
64
74
|
* Performance Observer 回调参数
|
|
65
75
|
*/
|
|
66
76
|
export interface PerformanceEntryCallback {
|
|
67
77
|
(entry: PerformanceResourceTiming): void;
|
|
68
78
|
}
|
|
79
|
+
export {};
|
|
69
80
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,YAAY;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,YAAY;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,UAAU,oBAAoB;IAC5B,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB;IACpB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB;IACjE,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB;IACjE,gBAAgB;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC1C"}
|
package/dist/network-speed-js.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function
|
|
1
|
+
function h(t) {
|
|
2
2
|
const e = t.responseEnd - t.responseStart;
|
|
3
3
|
if (e <= 0 || t.transferSize === 0)
|
|
4
4
|
return null;
|
|
@@ -11,30 +11,37 @@ function l(t) {
|
|
|
11
11
|
transferSize: t.transferSize
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function f() {
|
|
15
15
|
return performance.getEntriesByType("resource").filter(
|
|
16
16
|
(e) => e instanceof PerformanceResourceTiming && e.transferSize > 0
|
|
17
|
-
).map(
|
|
17
|
+
).map(h).filter((e) => e !== null);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function p(t) {
|
|
20
20
|
performance.getEntriesByName(t).forEach(() => {
|
|
21
21
|
performance.clearResourceTimings();
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function w(t, e = { fast: 10, medium: 2 }) {
|
|
25
25
|
return t >= e.fast ? "fast" : t >= e.medium ? "medium" : t > 0 ? "slow" : "unknown";
|
|
26
26
|
}
|
|
27
|
-
class
|
|
27
|
+
class a {
|
|
28
28
|
options;
|
|
29
29
|
observer = null;
|
|
30
|
-
constructor(e
|
|
31
|
-
this.options = {
|
|
30
|
+
constructor(e) {
|
|
31
|
+
"useFetch" in e && e.useFetch ? this.options = {
|
|
32
32
|
intranetUrl: e.intranetUrl || "",
|
|
33
|
-
internetUrl: e.internetUrl
|
|
33
|
+
internetUrl: e.internetUrl,
|
|
34
34
|
timeout: e.timeout || 1e4,
|
|
35
35
|
autoDetect: e.autoDetect ?? !0,
|
|
36
36
|
thresholds: e.thresholds || { fast: 10, medium: 2 },
|
|
37
|
-
|
|
37
|
+
useFetch: !0
|
|
38
|
+
} : this.options = {
|
|
39
|
+
intranetUrl: "intranetImageUrl" in e && e.intranetImageUrl || "",
|
|
40
|
+
internetUrl: "internetImageUrl" in e ? e.internetImageUrl : "",
|
|
41
|
+
timeout: e.timeout || 1e4,
|
|
42
|
+
autoDetect: e.autoDetect ?? !0,
|
|
43
|
+
thresholds: e.thresholds || { fast: 10, medium: 2 },
|
|
44
|
+
useFetch: !1
|
|
38
45
|
};
|
|
39
46
|
}
|
|
40
47
|
/**
|
|
@@ -61,16 +68,16 @@ class T {
|
|
|
61
68
|
testSingleUrl(e, s) {
|
|
62
69
|
return new Promise((n, o) => {
|
|
63
70
|
const r = `${e}?t=${Date.now()}`;
|
|
64
|
-
|
|
65
|
-
const c = new PerformanceObserver((
|
|
66
|
-
for (const u of
|
|
71
|
+
p(r);
|
|
72
|
+
const c = new PerformanceObserver((m) => {
|
|
73
|
+
for (const u of m.getEntries())
|
|
67
74
|
if (u.entryType === "resource" && u.name.includes(e)) {
|
|
68
|
-
const i =
|
|
75
|
+
const i = h(u);
|
|
69
76
|
if (i) {
|
|
70
|
-
const
|
|
77
|
+
const d = {
|
|
71
78
|
speedMbps: i.speedMbps,
|
|
72
79
|
speedKBps: i.speedKBps,
|
|
73
|
-
networkType:
|
|
80
|
+
networkType: w(
|
|
74
81
|
i.speedMbps,
|
|
75
82
|
this.options.thresholds
|
|
76
83
|
),
|
|
@@ -79,15 +86,15 @@ class T {
|
|
|
79
86
|
transferSize: i.transferSize,
|
|
80
87
|
resourceUrl: e
|
|
81
88
|
};
|
|
82
|
-
c.disconnect(), n(
|
|
89
|
+
c.disconnect(), n(d);
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
92
|
});
|
|
86
93
|
c.observe({ entryTypes: ["resource"] });
|
|
87
|
-
const
|
|
94
|
+
const l = setTimeout(() => {
|
|
88
95
|
c.disconnect(), o(new Error(`测速超时: ${e}`));
|
|
89
96
|
}, this.options.timeout);
|
|
90
|
-
this.options.
|
|
97
|
+
this.options.useFetch ? this.loadWithFetch(r, l, c, o) : this.loadWithImage(r, l, c, o);
|
|
91
98
|
});
|
|
92
99
|
}
|
|
93
100
|
/**
|
|
@@ -98,7 +105,7 @@ class T {
|
|
|
98
105
|
r.onload = () => {
|
|
99
106
|
clearTimeout(s);
|
|
100
107
|
}, r.onerror = () => {
|
|
101
|
-
clearTimeout(s), n.disconnect(), o(new Error(
|
|
108
|
+
clearTimeout(s), n.disconnect(), o(new Error(`图片加载失败: ${e}`));
|
|
102
109
|
}, r.src = e;
|
|
103
110
|
}
|
|
104
111
|
/**
|
|
@@ -142,49 +149,87 @@ class T {
|
|
|
142
149
|
this.observer && (this.observer.disconnect(), this.observer = null);
|
|
143
150
|
}
|
|
144
151
|
}
|
|
145
|
-
class
|
|
146
|
-
tester;
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
class S {
|
|
153
|
+
tester = null;
|
|
154
|
+
/**
|
|
155
|
+
* 创建SDK实例
|
|
156
|
+
* @param options 配置选项(可选,如果不传则只能使用工具函数,不能执行测速)
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* // 图片模式(默认,推荐)
|
|
160
|
+
* const sdk = new NetworkSpeedSDK({
|
|
161
|
+
* internetImageUrl: 'https://cdn.example.com/test.jpg',
|
|
162
|
+
* });
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* // Fetch模式(需要CORS)
|
|
166
|
+
* const sdk = new NetworkSpeedSDK({
|
|
167
|
+
* internetUrl: 'https://cdn.example.com/test.bin',
|
|
168
|
+
* useFetch: true,
|
|
169
|
+
* });
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* // 仅使用工具函数
|
|
173
|
+
* const sdk = new NetworkSpeedSDK();
|
|
174
|
+
* const speeds = sdk.getAllResourcesSpeeds();
|
|
175
|
+
*/
|
|
176
|
+
constructor(e) {
|
|
177
|
+
e && (this.tester = new a(e));
|
|
149
178
|
}
|
|
150
179
|
/**
|
|
151
180
|
* 执行网速测试
|
|
181
|
+
* @throws {Error} 如果SDK未配置
|
|
152
182
|
*/
|
|
153
183
|
async test() {
|
|
184
|
+
if (!this.tester)
|
|
185
|
+
throw new Error(
|
|
186
|
+
`SDK未配置,请在构造函数中传入配置选项。
|
|
187
|
+
示例:
|
|
188
|
+
new NetworkSpeedSDK({ internetImageUrl: "https://cdn.example.com/test.jpg" })
|
|
189
|
+
或:
|
|
190
|
+
new NetworkSpeedSDK({ internetUrl: "https://cdn.example.com/test.bin", useFetch: true })`
|
|
191
|
+
);
|
|
154
192
|
return this.tester.test();
|
|
155
193
|
}
|
|
156
194
|
/**
|
|
157
195
|
* 获取所有已加载资源的速度信息
|
|
196
|
+
* @returns 资源速度信息数组
|
|
158
197
|
*/
|
|
159
198
|
getAllResourcesSpeeds() {
|
|
160
|
-
return
|
|
199
|
+
return f();
|
|
161
200
|
}
|
|
162
201
|
/**
|
|
163
202
|
* 监听特定资源的性能数据
|
|
203
|
+
* @param urlPattern URL匹配模式
|
|
204
|
+
* @param callback 回调函数
|
|
205
|
+
* @returns 停止监听的函数
|
|
164
206
|
*/
|
|
165
207
|
observeResource(e, s) {
|
|
166
|
-
return this.tester.
|
|
208
|
+
return this.tester || (this.tester = new a({
|
|
209
|
+
internetImageUrl: ""
|
|
210
|
+
})), this.tester.observeResource(e, s);
|
|
167
211
|
}
|
|
168
212
|
/**
|
|
169
213
|
* 更新配置
|
|
214
|
+
* @param options 新的配置选项
|
|
170
215
|
*/
|
|
171
216
|
updateOptions(e) {
|
|
172
|
-
this.tester
|
|
217
|
+
this.tester = new a(e);
|
|
173
218
|
}
|
|
174
219
|
/**
|
|
175
220
|
* 销毁SDK实例
|
|
176
221
|
*/
|
|
177
222
|
destroy() {
|
|
178
|
-
this.tester.destroy();
|
|
223
|
+
this.tester && (this.tester.destroy(), this.tester = null);
|
|
179
224
|
}
|
|
180
225
|
}
|
|
181
|
-
function
|
|
182
|
-
return new
|
|
226
|
+
function U(t) {
|
|
227
|
+
return new S(t);
|
|
183
228
|
}
|
|
184
229
|
export {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
230
|
+
S as NetworkSpeedSDK,
|
|
231
|
+
h as calcSpeedByResource,
|
|
232
|
+
U as createNetworkSpeedSDK,
|
|
233
|
+
w as evaluateNetworkType,
|
|
234
|
+
f as getAllResourcesSpeeds
|
|
190
235
|
};
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.NetworkSpeedJS={}))})(this,(function(n){"use strict";function c(t){const e=t.responseEnd-t.responseStart;if(e<=0||t.transferSize===0)return null;const s=t.transferSize*8/e/1e3,o=t.transferSize/e;return{name:t.name,speedMbps:Number(s.toFixed(2)),speedKBps:Number(o.toFixed(2)),downloadTime:Number(e.toFixed(2)),transferSize:t.transferSize}}function
|
|
1
|
+
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.NetworkSpeedJS={}))})(this,(function(n){"use strict";function c(t){const e=t.responseEnd-t.responseStart;if(e<=0||t.transferSize===0)return null;const s=t.transferSize*8/e/1e3,o=t.transferSize/e;return{name:t.name,speedMbps:Number(s.toFixed(2)),speedKBps:Number(o.toFixed(2)),downloadTime:Number(e.toFixed(2)),transferSize:t.transferSize}}function h(){return performance.getEntriesByType("resource").filter(e=>e instanceof PerformanceResourceTiming&&e.transferSize>0).map(c).filter(e=>e!==null)}function S(t){performance.getEntriesByName(t).forEach(()=>{performance.clearResourceTimings()})}function f(t,e={fast:10,medium:2}){return t>=e.fast?"fast":t>=e.medium?"medium":t>0?"slow":"unknown"}class l{options;observer=null;constructor(e){"useFetch"in e&&e.useFetch?this.options={intranetUrl:e.intranetUrl||"",internetUrl:e.internetUrl,timeout:e.timeout||1e4,autoDetect:e.autoDetect??!0,thresholds:e.thresholds||{fast:10,medium:2},useFetch:!0}:this.options={intranetUrl:"intranetImageUrl"in e&&e.intranetImageUrl||"",internetUrl:"internetImageUrl"in e?e.internetImageUrl:"",timeout:e.timeout||1e4,autoDetect:e.autoDetect??!0,thresholds:e.thresholds||{fast:10,medium:2},useFetch:!1}}async test(){return this.options.autoDetect?this.testWithAutoDetect():this.testSingleUrl(this.options.internetUrl,!1)}async testWithAutoDetect(){if(this.options.intranetUrl)try{return await this.testSingleUrl(this.options.intranetUrl,!0)}catch{console.log("内网测速失败,切换到外网测速")}return this.testSingleUrl(this.options.internetUrl,!1)}testSingleUrl(e,s){return new Promise((o,i)=>{const r=`${e}?t=${Date.now()}`;S(r);const a=new PerformanceObserver(g=>{for(const d of g.getEntries())if(d.entryType==="resource"&&d.name.includes(e)){const u=c(d);if(u){const y={speedMbps:u.speedMbps,speedKBps:u.speedKBps,networkType:f(u.speedMbps,this.options.thresholds),isIntranet:s,duration:u.downloadTime,transferSize:u.transferSize,resourceUrl:e};a.disconnect(),o(y)}}});a.observe({entryTypes:["resource"]});const p=setTimeout(()=>{a.disconnect(),i(new Error(`测速超时: ${e}`))},this.options.timeout);this.options.useFetch?this.loadWithFetch(r,p,a,i):this.loadWithImage(r,p,a,i)})}loadWithImage(e,s,o,i){const r=new Image;r.onload=()=>{clearTimeout(s)},r.onerror=()=>{clearTimeout(s),o.disconnect(),i(new Error(`图片加载失败: ${e}`))},r.src=e}loadWithFetch(e,s,o,i){fetch(e,{method:"GET",cache:"no-store"}).then(r=>{if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return r.blob()}).then(()=>{clearTimeout(s)}).catch(r=>{clearTimeout(s),o.disconnect(),i(new Error(`资源加载失败: ${r.message}`))})}observeResource(e,s){const o=new PerformanceObserver(i=>{for(const r of i.getEntries())r.entryType==="resource"&&r.name.includes(e)&&s(r)});return o.observe({entryTypes:["resource"]}),()=>o.disconnect()}updateOptions(e){this.options={...this.options,...e}}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null)}}class m{tester=null;constructor(e){e&&(this.tester=new l(e))}async test(){if(!this.tester)throw new Error(`SDK未配置,请在构造函数中传入配置选项。
|
|
2
|
+
示例:
|
|
3
|
+
new NetworkSpeedSDK({ internetImageUrl: "https://cdn.example.com/test.jpg" })
|
|
4
|
+
或:
|
|
5
|
+
new NetworkSpeedSDK({ internetUrl: "https://cdn.example.com/test.bin", useFetch: true })`);return this.tester.test()}getAllResourcesSpeeds(){return h()}observeResource(e,s){return this.tester||(this.tester=new l({internetImageUrl:""})),this.tester.observeResource(e,s)}updateOptions(e){this.tester=new l(e)}destroy(){this.tester&&(this.tester.destroy(),this.tester=null)}}function w(t){return new m(t)}n.NetworkSpeedSDK=m,n.calcSpeedByResource=c,n.createNetworkSpeedSDK=w,n.evaluateNetworkType=f,n.getAllResourcesSpeeds=h,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "network-speed-js",
|
|
3
3
|
"private": false,
|
|
4
4
|
"description": "A framework-agnostic network speed testing SDK based on Performance API with intranet/internet auto-detection support",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.5",
|
|
6
6
|
"author": "Sunny-117",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"keywords": [
|