@ureq/lib-hash 0.0.3-alpha.0 → 0.0.3
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 +140 -0
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @ureq/lib-hash
|
|
2
|
+
|
|
3
|
+
哈希工具库,提供请求哈希和字符串哈希功能。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ureq/lib-hash
|
|
9
|
+
# 或
|
|
10
|
+
pnpm add @ureq/lib-hash
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> 注意:通常作为 `@ureq/business` 的依赖自动安装,无需单独安装
|
|
14
|
+
|
|
15
|
+
## 使用
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { DefaultHashService } from '@ureq/lib-hash';
|
|
19
|
+
|
|
20
|
+
const hashService = new DefaultHashService();
|
|
21
|
+
|
|
22
|
+
// 生成请求哈希
|
|
23
|
+
const requestHash = hashService.generateRequestHash(
|
|
24
|
+
'GET',
|
|
25
|
+
'/api/users',
|
|
26
|
+
null,
|
|
27
|
+
{ params: { page: 1 } }
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// 生成字符串哈希
|
|
31
|
+
const strHash = hashService.hashString('some-string');
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API
|
|
35
|
+
|
|
36
|
+
### DefaultHashService
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
class DefaultHashService implements HashService {
|
|
40
|
+
generateRequestHash(
|
|
41
|
+
method: string,
|
|
42
|
+
url: string,
|
|
43
|
+
data?: any,
|
|
44
|
+
options?: RequestOptions
|
|
45
|
+
): string;
|
|
46
|
+
|
|
47
|
+
hashString(str: string): string;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 功能
|
|
52
|
+
|
|
53
|
+
### generateRequestHash
|
|
54
|
+
|
|
55
|
+
生成请求的唯一哈希值,用于:
|
|
56
|
+
|
|
57
|
+
- 请求去重(幂等性保证)
|
|
58
|
+
- 缓存键生成
|
|
59
|
+
- 请求标识
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const hash1 = hashService.generateRequestHash('GET', '/users', null, { params: { page: 1 } });
|
|
63
|
+
const hash2 = hashService.generateRequestHash('GET', '/users', null, { params: { page: 1 } });
|
|
64
|
+
|
|
65
|
+
console.log(hash1 === hash2); // true - 相同的请求生成相同的哈希
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### hashString
|
|
69
|
+
|
|
70
|
+
生成字符串的哈希值。
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const hash = hashService.hashString('hello world');
|
|
74
|
+
console.log(hash); // 生成的哈希值
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 哈希算法
|
|
78
|
+
|
|
79
|
+
默认使用简单的字符串哈希算法,适用于大多数场景。如需更强的哈希算法,可以自定义实现:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { HashService } from '@ureq/business';
|
|
83
|
+
import crypto from 'crypto';
|
|
84
|
+
|
|
85
|
+
class CryptoHashService implements HashService {
|
|
86
|
+
generateRequestHash(method: string, url: string, data?: any, options?: any): string {
|
|
87
|
+
const str = JSON.stringify({ method, url, data, options });
|
|
88
|
+
return this.hashString(str);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
hashString(str: string): string {
|
|
92
|
+
return crypto.createHash('sha256').update(str).digest('hex');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 使用场景
|
|
98
|
+
|
|
99
|
+
### 请求去重
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { Request } from '@ureq/core';
|
|
103
|
+
import { FetchRequestor } from '@ureq/impl-fetch';
|
|
104
|
+
import { DefaultHashService } from '@ureq/lib-hash';
|
|
105
|
+
|
|
106
|
+
const hashService = new DefaultHashService();
|
|
107
|
+
|
|
108
|
+
const request = new Request(
|
|
109
|
+
new FetchRequestor(),
|
|
110
|
+
{
|
|
111
|
+
idempotent: {
|
|
112
|
+
hashService,
|
|
113
|
+
dedupeTime: 1000
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 缓存键生成
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const request = new Request(
|
|
123
|
+
new FetchRequestor(),
|
|
124
|
+
{
|
|
125
|
+
cache: {
|
|
126
|
+
getCacheKey: (url, options) => {
|
|
127
|
+
return hashService.generateRequestHash('GET', url, null, options);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 文档
|
|
135
|
+
|
|
136
|
+
查看完整文档:[https://sunny-117.github.io/ureq](https://sunny-117.github.io/ureq)
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,26 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
function generateHash(input) {
|
|
5
|
+
let hash = 0;
|
|
6
|
+
for (let i = 0; i < input.length; i++) {
|
|
7
|
+
const char = input.charCodeAt(i);
|
|
8
|
+
hash = (hash << 5) - hash + char;
|
|
9
|
+
hash = hash & hash;
|
|
10
|
+
}
|
|
11
|
+
return hash.toString(36);
|
|
12
|
+
}
|
|
13
|
+
function generateRequestHash(method, url, data, options) {
|
|
14
|
+
const parts = [
|
|
15
|
+
method.toUpperCase(),
|
|
16
|
+
url,
|
|
17
|
+
data ? JSON.stringify(data) : "",
|
|
18
|
+
options ? JSON.stringify(options) : ""
|
|
19
|
+
];
|
|
20
|
+
return generateHash(parts.join("|"));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.generateHash = generateHash;
|
|
24
|
+
exports.generateRequestHash = generateRequestHash;
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
2
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAAO,SAAS,aAAa,KAAuB,EAAA;AAClD,EAAA,IAAI,IAAO,GAAA,CAAA;AACX,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,KAAA,CAAM,QAAQ,CAAK,EAAA,EAAA;AACrC,IAAM,MAAA,IAAA,GAAO,KAAM,CAAA,UAAA,CAAW,CAAC,CAAA;AAC/B,IAAS,IAAA,GAAA,CAAA,IAAA,IAAQ,KAAK,IAAQ,GAAA,IAAA;AAC9B,IAAA,IAAA,GAAO,IAAO,GAAA,IAAA;AAAA;AAEhB,EAAO,OAAA,IAAA,CAAK,SAAS,EAAE,CAAA;AACzB;AAEO,SAAS,mBACd,CAAA,MAAA,EACA,GACA,EAAA,IAAA,EACA,OACQ,EAAA;AACR,EAAA,MAAM,KAAQ,GAAA;AAAA,IACZ,OAAO,WAAY,EAAA;AAAA,IACnB,GAAA;AAAA,IACA,IAAO,GAAA,IAAA,CAAK,SAAU,CAAA,IAAI,CAAI,GAAA,EAAA;AAAA,IAC9B,OAAU,GAAA,IAAA,CAAK,SAAU,CAAA,OAAO,CAAI,GAAA;AAAA,GACtC;AACA,EAAA,OAAO,YAAa,CAAA,KAAA,CAAM,IAAK,CAAA,GAAG,CAAC,CAAA;AACrC","file":"index.js","sourcesContent":["export function generateHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(36);\n}\n\nexport function generateRequestHash(\n method: string,\n url: string,\n data?: any,\n options?: Record<string, any>\n): string {\n const parts = [\n method.toUpperCase(),\n url,\n data ? JSON.stringify(data) : '',\n options ? JSON.stringify(options) : ''\n ];\n return generateHash(parts.join('|'));\n} "]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function generateHash(input) {
|
|
3
|
+
let hash = 0;
|
|
4
|
+
for (let i = 0; i < input.length; i++) {
|
|
5
|
+
const char = input.charCodeAt(i);
|
|
6
|
+
hash = (hash << 5) - hash + char;
|
|
7
|
+
hash = hash & hash;
|
|
8
|
+
}
|
|
9
|
+
return hash.toString(36);
|
|
10
|
+
}
|
|
11
|
+
function generateRequestHash(method, url, data, options) {
|
|
12
|
+
const parts = [
|
|
13
|
+
method.toUpperCase(),
|
|
14
|
+
url,
|
|
15
|
+
data ? JSON.stringify(data) : "",
|
|
16
|
+
options ? JSON.stringify(options) : ""
|
|
17
|
+
];
|
|
18
|
+
return generateHash(parts.join("|"));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { generateHash, generateRequestHash };
|
|
22
|
+
//# sourceMappingURL=index.mjs.map
|
|
2
23
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAAO,SAAS,aAAa,KAAuB,EAAA;AAClD,EAAA,IAAI,IAAO,GAAA,CAAA;AACX,EAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,KAAA,CAAM,QAAQ,CAAK,EAAA,EAAA;AACrC,IAAM,MAAA,IAAA,GAAO,KAAM,CAAA,UAAA,CAAW,CAAC,CAAA;AAC/B,IAAS,IAAA,GAAA,CAAA,IAAA,IAAQ,KAAK,IAAQ,GAAA,IAAA;AAC9B,IAAA,IAAA,GAAO,IAAO,GAAA,IAAA;AAAA;AAEhB,EAAO,OAAA,IAAA,CAAK,SAAS,EAAE,CAAA;AACzB;AAEO,SAAS,mBACd,CAAA,MAAA,EACA,GACA,EAAA,IAAA,EACA,OACQ,EAAA;AACR,EAAA,MAAM,KAAQ,GAAA;AAAA,IACZ,OAAO,WAAY,EAAA;AAAA,IACnB,GAAA;AAAA,IACA,IAAO,GAAA,IAAA,CAAK,SAAU,CAAA,IAAI,CAAI,GAAA,EAAA;AAAA,IAC9B,OAAU,GAAA,IAAA,CAAK,SAAU,CAAA,OAAO,CAAI,GAAA;AAAA,GACtC;AACA,EAAA,OAAO,YAAa,CAAA,KAAA,CAAM,IAAK,CAAA,GAAG,CAAC,CAAA;AACrC","file":"index.mjs","sourcesContent":["export function generateHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return hash.toString(36);\n}\n\nexport function generateRequestHash(\n method: string,\n url: string,\n data?: any,\n options?: Record<string, any>\n): string {\n const parts = [\n method.toUpperCase(),\n url,\n data ? JSON.stringify(data) : '',\n options ? JSON.stringify(options) : ''\n ];\n return generateHash(parts.join('|'));\n} "]}
|