@maiyunnet/kebab 2.0.6 → 2.0.8
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/index.d.ts +11 -1
- package/index.js +13 -1
- package/lib/buffer.d.ts +25 -0
- package/lib/buffer.js +30 -5
- package/lib/captcha.d.ts +15 -0
- package/lib/captcha.js +20 -0
- package/lib/consistent.d.ts +51 -0
- package/lib/consistent.js +59 -0
- package/lib/core.d.ts +134 -0
- package/lib/core.js +176 -0
- package/lib/crypto.d.ts +75 -6
- package/lib/crypto.js +206 -38
- package/lib/db.d.ts +104 -0
- package/lib/db.js +126 -0
- package/lib/dns.d.ts +51 -0
- package/lib/dns.js +54 -2
- package/lib/fs.d.ts +100 -0
- package/lib/fs.js +118 -0
- package/lib/jwt.d.ts +43 -0
- package/lib/jwt.js +45 -0
- package/lib/kv.d.ts +362 -0
- package/lib/kv.js +377 -0
- package/lib/lan.d.ts +6 -0
- package/lib/lan.js +7 -0
- package/lib/net/formdata.d.ts +38 -0
- package/lib/net/formdata.js +43 -0
- package/lib/net/request.d.ts +62 -0
- package/lib/net/request.js +57 -0
- package/lib/net/response.d.ts +21 -0
- package/lib/net/response.js +16 -0
- package/lib/net.d.ts +86 -0
- package/lib/net.js +140 -0
- package/lib/s3.d.ts +52 -0
- package/lib/s3.js +51 -0
- package/lib/scan.d.ts +52 -0
- package/lib/scan.js +84 -0
- package/lib/session.d.ts +31 -0
- package/lib/session.js +52 -1
- package/lib/sql.d.ts +176 -0
- package/lib/sql.js +287 -2
- package/lib/ssh/sftp.d.ts +106 -0
- package/lib/ssh/sftp.js +106 -0
- package/lib/ssh/shell.d.ts +37 -0
- package/lib/ssh/shell.js +31 -0
- package/lib/ssh.d.ts +32 -0
- package/lib/ssh.js +32 -0
- package/lib/text.d.ts +131 -0
- package/lib/text.js +188 -0
- package/lib/time.d.ts +53 -0
- package/lib/time.js +55 -0
- package/lib/ws.d.ts +68 -0
- package/lib/ws.js +74 -0
- package/lib/zip.d.ts +53 -0
- package/lib/zip.js +73 -0
- package/lib/zlib.d.ts +76 -0
- package/lib/zlib.js +78 -0
- package/main.d.ts +6 -1
- package/main.js +11 -1
- package/package.json +2 -2
- package/sys/child.js +104 -0
- package/sys/cmd.js +28 -0
- package/sys/ctr.d.ts +166 -0
- package/sys/ctr.js +177 -0
- package/sys/master.js +63 -0
- package/sys/mod.d.ts +266 -0
- package/sys/mod.js +335 -0
- package/sys/route.d.ts +34 -0
- package/sys/route.js +164 -0
- package/www/example/ctr/test.d.ts +3 -0
- package/www/example/ctr/test.js +63 -1
- package/www/example/mod/test.js +14 -0
- package/www/example/mod/testdata.js +9 -0
- package/www/example/ws/test.js +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
- package/.vscode/tasks.json +0 -15
package/index.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2019-3-30 12:46:41
|
|
4
|
+
* Last: 2020-3-8 21:04:24, 2022-07-22 14:20:34, 2023-5-24 01:34:57, 2025-6-13 14:49:27
|
|
5
|
+
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
6
|
+
* --- npx tsc-alias -w ---
|
|
7
|
+
*/
|
|
8
|
+
/** --- 当前系统版本号 --- */
|
|
9
|
+
export declare const VER = "2.0.8";
|
|
10
|
+
/** --- 框架根目录,以 / 结尾 --- */
|
|
2
11
|
export declare const ROOT_PATH: string;
|
|
3
12
|
export declare const LIB_PATH: string;
|
|
4
13
|
export declare const SYS_PATH: string;
|
|
14
|
+
/** --- 执行根目录,以 / 结尾 --- */
|
|
5
15
|
export declare const ROOT_CWD: string;
|
|
6
16
|
export declare const CONF_CWD: string;
|
|
7
17
|
export declare const CERT_CWD: string;
|
package/index.js
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
4
|
+
* Date: 2019-3-30 12:46:41
|
|
5
|
+
* Last: 2020-3-8 21:04:24, 2022-07-22 14:20:34, 2023-5-24 01:34:57, 2025-6-13 14:49:27
|
|
6
|
+
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
|
+
* --- npx tsc-alias -w ---
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
exports.MOD_CWD = exports.FTMP_CWD = exports.IND_CWD = exports.WWW_CWD = exports.LOG_CWD = exports.LIB_CWD = exports.VHOST_CWD = exports.CERT_CWD = exports.CONF_CWD = exports.ROOT_CWD = exports.SYS_PATH = exports.LIB_PATH = exports.ROOT_PATH = exports.VER = void 0;
|
|
4
|
-
|
|
11
|
+
/** --- 当前系统版本号 --- */
|
|
12
|
+
exports.VER = '2.0.8';
|
|
13
|
+
// --- 服务端用的路径 ---
|
|
14
|
+
/** --- /xxx/xxx --- */
|
|
5
15
|
const dirname = __dirname.replace(/\\/g, '/');
|
|
16
|
+
/** --- 框架根目录,以 / 结尾 --- */
|
|
6
17
|
exports.ROOT_PATH = dirname + '/';
|
|
7
18
|
exports.LIB_PATH = exports.ROOT_PATH + 'lib/';
|
|
8
19
|
exports.SYS_PATH = exports.ROOT_PATH + 'sys/';
|
|
9
20
|
const cwd = process.cwd().replace(/\\/g, '/');
|
|
21
|
+
/** --- 执行根目录,以 / 结尾 --- */
|
|
10
22
|
exports.ROOT_CWD = cwd + '/';
|
|
11
23
|
exports.CONF_CWD = exports.ROOT_CWD + 'conf/';
|
|
12
24
|
exports.CERT_CWD = exports.CONF_CWD + 'cert/';
|
package/lib/buffer.d.ts
CHANGED
|
@@ -1,25 +1,50 @@
|
|
|
1
|
+
/** --- 读对象 --- */
|
|
1
2
|
export declare class Reader {
|
|
2
3
|
private readonly _buffer;
|
|
4
|
+
/** --- 当前读取位置 --- */
|
|
3
5
|
private _offset;
|
|
4
6
|
constructor(buffer: Buffer);
|
|
7
|
+
/** --- 读取一个无符号8位整数, BYTE --- */
|
|
5
8
|
readUInt8(): number;
|
|
9
|
+
/** --- 读取一个无符号16位整数(大端模式),WORD --- */
|
|
6
10
|
readUInt16BE(): number;
|
|
11
|
+
/** --- 读取一个无符号32位整数(大端模式), DWORD --- */
|
|
7
12
|
readUInt32BE(): number;
|
|
13
|
+
/** --- 读取一个 BCD 编码的字符串(每个字节表示两个数字)--- */
|
|
8
14
|
readBCDString(length?: number): string;
|
|
15
|
+
/** --- 读取普通 string --- */
|
|
9
16
|
readString(length?: number, encoding?: BufferEncoding): string;
|
|
17
|
+
/** --- 读取 Buffer --- */
|
|
10
18
|
readBuffer(length?: number): Buffer;
|
|
19
|
+
/** --- 获取完整的 buffer 长度 --- */
|
|
11
20
|
length(): number;
|
|
12
21
|
}
|
|
22
|
+
/** --- 写对象 --- */
|
|
13
23
|
export declare class Writer {
|
|
14
24
|
private readonly _buffer;
|
|
25
|
+
/** --- 当前读取位置 --- */
|
|
15
26
|
private _offset;
|
|
16
27
|
constructor(size: number);
|
|
28
|
+
/** --- [1 字节] 写入一个无符号 8 位整数 --- */
|
|
17
29
|
writeUInt8(value: number): void;
|
|
30
|
+
/** --- [2 字节] 写入一个无符号 16 位整数(大端模式) --- */
|
|
18
31
|
writeUInt16BE(value: number): void;
|
|
32
|
+
/** --- [4 字节] 写入一个无符号 32 位整数(大端模式) --- */
|
|
19
33
|
writeUInt32BE(value: number): void;
|
|
34
|
+
/** --- [每字节 2 数字] 写入一个 BCD 编码的字符串(仅支持数字) --- */
|
|
20
35
|
writeBCDString(value: string): void;
|
|
36
|
+
/** --- 写入普通字符串,返回写入的长度 --- */
|
|
21
37
|
writeString(value: string, encoding?: BufferEncoding): number;
|
|
38
|
+
/** --- 返回 Buffer 对象 --- */
|
|
22
39
|
get(): Buffer;
|
|
23
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* --- Buffer Reader 对象 ---
|
|
43
|
+
* @param buffer 要读取的 buffer
|
|
44
|
+
*/
|
|
24
45
|
export declare function getReader(buffer: Buffer): Reader;
|
|
46
|
+
/**
|
|
47
|
+
* --- Buffer Writer 对象 ---
|
|
48
|
+
* @param buffer 要读取的 buffer
|
|
49
|
+
*/
|
|
25
50
|
export declare function getWriter(size: number): Writer;
|
package/lib/buffer.js
CHANGED
|
@@ -3,26 +3,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Writer = exports.Reader = void 0;
|
|
4
4
|
exports.getReader = getReader;
|
|
5
5
|
exports.getWriter = getWriter;
|
|
6
|
+
/** --- 读对象 --- */
|
|
6
7
|
class Reader {
|
|
7
8
|
constructor(buffer) {
|
|
9
|
+
/** --- 当前读取位置 --- */
|
|
8
10
|
this._offset = 0;
|
|
9
11
|
this._buffer = buffer;
|
|
10
12
|
}
|
|
13
|
+
/** --- 读取一个无符号8位整数, BYTE --- */
|
|
11
14
|
readUInt8() {
|
|
12
15
|
const value = this._buffer.readUInt8(this._offset);
|
|
13
16
|
this._offset += 1;
|
|
14
17
|
return value;
|
|
15
18
|
}
|
|
19
|
+
/** --- 读取一个无符号16位整数(大端模式),WORD --- */
|
|
16
20
|
readUInt16BE() {
|
|
17
21
|
const value = this._buffer.readUInt16BE(this._offset);
|
|
18
22
|
this._offset += 2;
|
|
19
23
|
return value;
|
|
20
24
|
}
|
|
25
|
+
/** --- 读取一个无符号32位整数(大端模式), DWORD --- */
|
|
21
26
|
readUInt32BE() {
|
|
22
27
|
const value = this._buffer.readUInt32BE(this._offset);
|
|
23
28
|
this._offset += 4;
|
|
24
29
|
return value;
|
|
25
30
|
}
|
|
31
|
+
/** --- 读取一个 BCD 编码的字符串(每个字节表示两个数字)--- */
|
|
26
32
|
readBCDString(length) {
|
|
27
33
|
if (length === undefined) {
|
|
28
34
|
length = this._buffer.length - this._offset;
|
|
@@ -30,12 +36,13 @@ class Reader {
|
|
|
30
36
|
let str = '';
|
|
31
37
|
for (let i = 0; i < length; i++) {
|
|
32
38
|
const byte = this._buffer.readUInt8(this._offset + i);
|
|
33
|
-
str += (byte >> 4).toString(16).toUpperCase();
|
|
34
|
-
str += (byte & 0x0f).toString(16).toUpperCase();
|
|
39
|
+
str += (byte >> 4).toString(16).toUpperCase(); // --- 高四位表示第一个数字 ---
|
|
40
|
+
str += (byte & 0x0f).toString(16).toUpperCase(); // --- 低四位表示第二个数字 ---
|
|
35
41
|
}
|
|
36
42
|
this._offset += length;
|
|
37
43
|
return str;
|
|
38
44
|
}
|
|
45
|
+
/** --- 读取普通 string --- */
|
|
39
46
|
readString(length, encoding = 'utf8') {
|
|
40
47
|
if (length === undefined) {
|
|
41
48
|
length = this._buffer.length - this._offset;
|
|
@@ -51,42 +58,51 @@ class Reader {
|
|
|
51
58
|
this._offset += length;
|
|
52
59
|
return Buffer.from(buf).toString(encoding);
|
|
53
60
|
}
|
|
61
|
+
/** --- 读取 Buffer --- */
|
|
54
62
|
readBuffer(length) {
|
|
55
63
|
if (length === undefined) {
|
|
56
64
|
length = this._buffer.length - this._offset;
|
|
57
65
|
}
|
|
58
66
|
return this._buffer.subarray(this._offset, this._offset += length);
|
|
59
67
|
}
|
|
68
|
+
/** --- 获取完整的 buffer 长度 --- */
|
|
60
69
|
length() {
|
|
61
70
|
return this._buffer.length;
|
|
62
71
|
}
|
|
63
72
|
}
|
|
64
73
|
exports.Reader = Reader;
|
|
74
|
+
/** --- 写对象 --- */
|
|
65
75
|
class Writer {
|
|
66
76
|
constructor(size) {
|
|
77
|
+
/** --- 当前读取位置 --- */
|
|
67
78
|
this._offset = 0;
|
|
68
79
|
this._buffer = Buffer.alloc(size);
|
|
69
80
|
}
|
|
81
|
+
/** --- [1 字节] 写入一个无符号 8 位整数 --- */
|
|
70
82
|
writeUInt8(value) {
|
|
71
83
|
this._buffer.writeUInt8(value, this._offset);
|
|
72
84
|
this._offset += 1;
|
|
73
85
|
}
|
|
86
|
+
/** --- [2 字节] 写入一个无符号 16 位整数(大端模式) --- */
|
|
74
87
|
writeUInt16BE(value) {
|
|
75
88
|
this._buffer.writeUInt16BE(value, this._offset);
|
|
76
89
|
this._offset += 2;
|
|
77
90
|
}
|
|
91
|
+
/** --- [4 字节] 写入一个无符号 32 位整数(大端模式) --- */
|
|
78
92
|
writeUInt32BE(value) {
|
|
79
93
|
this._buffer.writeUint32BE(value, this._offset);
|
|
80
94
|
this._offset += 4;
|
|
81
95
|
}
|
|
96
|
+
/** --- [每字节 2 数字] 写入一个 BCD 编码的字符串(仅支持数字) --- */
|
|
82
97
|
writeBCDString(value) {
|
|
83
98
|
for (let i = 0; i < value.length; i += 2) {
|
|
84
|
-
const high = parseInt(value[i], 10);
|
|
85
|
-
const low = parseInt(value[i + 1], 10);
|
|
86
|
-
const byte = (high << 4) | low;
|
|
99
|
+
const high = parseInt(value[i], 10); // --- 取十位 ---
|
|
100
|
+
const low = parseInt(value[i + 1], 10); // --- 取个位 ---
|
|
101
|
+
const byte = (high << 4) | low; // --- 拼接为一个字节 ---
|
|
87
102
|
this.writeUInt8(byte);
|
|
88
103
|
}
|
|
89
104
|
}
|
|
105
|
+
/** --- 写入普通字符串,返回写入的长度 --- */
|
|
90
106
|
writeString(value, encoding = 'utf8') {
|
|
91
107
|
const bytes = Buffer.from(value, encoding);
|
|
92
108
|
for (const byte of bytes) {
|
|
@@ -95,14 +111,23 @@ class Writer {
|
|
|
95
111
|
this._offset += bytes.length;
|
|
96
112
|
return bytes.length;
|
|
97
113
|
}
|
|
114
|
+
/** --- 返回 Buffer 对象 --- */
|
|
98
115
|
get() {
|
|
99
116
|
return this._buffer.subarray(0, this._offset);
|
|
100
117
|
}
|
|
101
118
|
}
|
|
102
119
|
exports.Writer = Writer;
|
|
120
|
+
/**
|
|
121
|
+
* --- Buffer Reader 对象 ---
|
|
122
|
+
* @param buffer 要读取的 buffer
|
|
123
|
+
*/
|
|
103
124
|
function getReader(buffer) {
|
|
104
125
|
return new Reader(buffer);
|
|
105
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* --- Buffer Writer 对象 ---
|
|
129
|
+
* @param buffer 要读取的 buffer
|
|
130
|
+
*/
|
|
106
131
|
function getWriter(size) {
|
|
107
132
|
return new Writer(size);
|
|
108
133
|
}
|
package/lib/captcha.d.ts
CHANGED
|
@@ -5,8 +5,23 @@ export declare class Captcha {
|
|
|
5
5
|
'height': number;
|
|
6
6
|
'length': number;
|
|
7
7
|
});
|
|
8
|
+
/**
|
|
9
|
+
* --- 获取图片 Buffer ---
|
|
10
|
+
*/
|
|
8
11
|
getBuffer(): string;
|
|
12
|
+
/**
|
|
13
|
+
* --- 获取 base64 格式图片 ---
|
|
14
|
+
*/
|
|
9
15
|
getBase64(): string;
|
|
16
|
+
/**
|
|
17
|
+
* --- 获取当前随机码 ---
|
|
18
|
+
*/
|
|
10
19
|
getPhrase(): string;
|
|
11
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* --- 获取验证码对象 ---
|
|
23
|
+
* @param width 宽度
|
|
24
|
+
* @param height 高度
|
|
25
|
+
* @param length 字符个数
|
|
26
|
+
*/
|
|
12
27
|
export declare function get(width: number, height: number, length?: number): Captcha;
|
package/lib/captcha.js
CHANGED
|
@@ -35,6 +35,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Captcha = void 0;
|
|
37
37
|
exports.get = get;
|
|
38
|
+
/**
|
|
39
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
40
|
+
* Date: 2019-6-7 12:14:31
|
|
41
|
+
* Last: 2020-3-11 23:33:19, 2022-09-12 10:38:24, 2022-12-29 01:16:26, 2024-4-1 16:40:42, 2025-6-13 19:45:30
|
|
42
|
+
*/
|
|
38
43
|
const svgCaptcha = __importStar(require("svg-captcha"));
|
|
39
44
|
const mime = __importStar(require("@litert/mime"));
|
|
40
45
|
const core = __importStar(require("../lib/core"));
|
|
@@ -51,17 +56,32 @@ class Captcha {
|
|
|
51
56
|
'charPreset': core.RANDOM_V
|
|
52
57
|
});
|
|
53
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* --- 获取图片 Buffer ---
|
|
61
|
+
*/
|
|
54
62
|
getBuffer() {
|
|
55
63
|
return this._link.data.replace('<rect width="100%" height="100%" fill="#fff"/>', '');
|
|
56
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* --- 获取 base64 格式图片 ---
|
|
67
|
+
*/
|
|
57
68
|
getBase64() {
|
|
58
69
|
return `data:${mime.getMime('svg')};base64,` + Buffer.from(this._link.data.replace('<rect width="100%" height="100%" fill="#fff"/>', '')).toString('base64');
|
|
59
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* --- 获取当前随机码 ---
|
|
73
|
+
*/
|
|
60
74
|
getPhrase() {
|
|
61
75
|
return this._link.text;
|
|
62
76
|
}
|
|
63
77
|
}
|
|
64
78
|
exports.Captcha = Captcha;
|
|
79
|
+
/**
|
|
80
|
+
* --- 获取验证码对象 ---
|
|
81
|
+
* @param width 宽度
|
|
82
|
+
* @param height 高度
|
|
83
|
+
* @param length 字符个数
|
|
84
|
+
*/
|
|
65
85
|
function get(width, height, length = 4) {
|
|
66
86
|
return new Captcha({
|
|
67
87
|
'width': width,
|
package/lib/consistent.d.ts
CHANGED
|
@@ -1,20 +1,71 @@
|
|
|
1
1
|
export declare class Consistent {
|
|
2
|
+
/** --- 虚拟节点数量 --- */
|
|
2
3
|
private readonly _vcount;
|
|
4
|
+
/** --- hash 环 --- */
|
|
3
5
|
private readonly _circle;
|
|
6
|
+
/** --- circle 的 keys --- */
|
|
4
7
|
private _keys;
|
|
5
8
|
constructor(vcount: number);
|
|
9
|
+
/**
|
|
10
|
+
* --- 获取当前的虚拟节点数量 ---
|
|
11
|
+
*/
|
|
6
12
|
getVcount(): number;
|
|
13
|
+
/**
|
|
14
|
+
* 添加节点
|
|
15
|
+
* @param node node 节点名一个或多个
|
|
16
|
+
*/
|
|
7
17
|
add(node: string | string[]): void;
|
|
18
|
+
/**
|
|
19
|
+
* 移除节点
|
|
20
|
+
* @param node node 节点名
|
|
21
|
+
*/
|
|
8
22
|
remove(node: string | string[]): void;
|
|
23
|
+
/**
|
|
24
|
+
* 获得一个最近的顺时针节点
|
|
25
|
+
* @param key 为给定键取 Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点
|
|
26
|
+
*/
|
|
9
27
|
find(key: string | number): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* --- 原数据迁移到新地址 ---
|
|
30
|
+
* @param keys 原始数据 key 集
|
|
31
|
+
* @param node 新增的节点一个或多个
|
|
32
|
+
*/
|
|
10
33
|
migration(keys: string | number | Array<string | number>, node: string | string[]): Record<string, {
|
|
11
34
|
'old': string;
|
|
12
35
|
'new': string;
|
|
13
36
|
}>;
|
|
14
37
|
}
|
|
15
38
|
export declare function get(vcount?: number): Consistent;
|
|
39
|
+
/**
|
|
40
|
+
*--- 快速查找一个 key 属于哪个 node ---
|
|
41
|
+
* @param key 要查找的key
|
|
42
|
+
* @param nodes node 列表
|
|
43
|
+
* @param vcount 虚拟节点数量
|
|
44
|
+
*/
|
|
16
45
|
export declare function fast(key: string | number, nodes: string | string[], vcount?: number): string | null;
|
|
46
|
+
/**
|
|
47
|
+
* --- hash 函数 ---
|
|
48
|
+
* @param val 要 hash 的值
|
|
49
|
+
*/
|
|
17
50
|
export declare function hash(val: string | number): number;
|
|
51
|
+
/**
|
|
52
|
+
* --- 获取区间节点系列 ---
|
|
53
|
+
* @param min 最小值(含)
|
|
54
|
+
* @param max 最大值(含)
|
|
55
|
+
* @param pre 前导
|
|
56
|
+
*/
|
|
18
57
|
export declare function getRange(min: number, max: number, pre?: string): string[];
|
|
58
|
+
/**
|
|
59
|
+
* --- 添加到圆环 ---
|
|
60
|
+
* @param circle 圆环
|
|
61
|
+
* @param node node 节点名一个或多个
|
|
62
|
+
* @param vcount 虚拟节点数量
|
|
63
|
+
*/
|
|
19
64
|
export declare function addToCircle(circle: Record<string, string>, node: string | string[], vcount?: number): void;
|
|
65
|
+
/**
|
|
66
|
+
* --- 获得一个最近的顺时针节点 ---
|
|
67
|
+
* @param circle 圆环
|
|
68
|
+
* @param key 为给定键取 Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点
|
|
69
|
+
* @param keys keys,留空则自动从 circle 上取
|
|
70
|
+
*/
|
|
20
71
|
export declare function findInCircle(circle: Record<string, string>, key: string | number, keys?: string[]): string | null;
|
package/lib/consistent.js
CHANGED
|
@@ -40,21 +40,40 @@ exports.hash = hash;
|
|
|
40
40
|
exports.getRange = getRange;
|
|
41
41
|
exports.addToCircle = addToCircle;
|
|
42
42
|
exports.findInCircle = findInCircle;
|
|
43
|
+
/**
|
|
44
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
45
|
+
* Date: 2022-09-12 10:51:16
|
|
46
|
+
* Last: 2022-09-12 10:51:20, 2023-3-17 10:52:04, 2023-11-15 11:45:28
|
|
47
|
+
*/
|
|
43
48
|
const crypto = __importStar(require("../lib/crypto"));
|
|
44
49
|
class Consistent {
|
|
45
50
|
constructor(vcount) {
|
|
51
|
+
/** --- 虚拟节点数量 --- */
|
|
46
52
|
this._vcount = 300;
|
|
53
|
+
/** --- hash 环 --- */
|
|
47
54
|
this._circle = {};
|
|
55
|
+
/** --- circle 的 keys --- */
|
|
48
56
|
this._keys = [];
|
|
49
57
|
this._vcount = vcount;
|
|
50
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* --- 获取当前的虚拟节点数量 ---
|
|
61
|
+
*/
|
|
51
62
|
getVcount() {
|
|
52
63
|
return this._vcount;
|
|
53
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* 添加节点
|
|
67
|
+
* @param node node 节点名一个或多个
|
|
68
|
+
*/
|
|
54
69
|
add(node) {
|
|
55
70
|
addToCircle(this._circle, node, this._vcount);
|
|
56
71
|
this._keys = [];
|
|
57
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* 移除节点
|
|
75
|
+
* @param node node 节点名
|
|
76
|
+
*/
|
|
58
77
|
remove(node) {
|
|
59
78
|
if (typeof node === 'string') {
|
|
60
79
|
node = [node];
|
|
@@ -66,6 +85,10 @@ class Consistent {
|
|
|
66
85
|
}
|
|
67
86
|
this._keys = [];
|
|
68
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* 获得一个最近的顺时针节点
|
|
90
|
+
* @param key 为给定键取 Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点
|
|
91
|
+
*/
|
|
69
92
|
find(key) {
|
|
70
93
|
if (this._keys.length === 0) {
|
|
71
94
|
this._keys = Object.keys(this._circle);
|
|
@@ -75,11 +98,17 @@ class Consistent {
|
|
|
75
98
|
}
|
|
76
99
|
return findInCircle(this._circle, key, this._keys);
|
|
77
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* --- 原数据迁移到新地址 ---
|
|
103
|
+
* @param keys 原始数据 key 集
|
|
104
|
+
* @param node 新增的节点一个或多个
|
|
105
|
+
*/
|
|
78
106
|
migration(keys, node) {
|
|
79
107
|
const rtn = {};
|
|
80
108
|
if (!Array.isArray(keys)) {
|
|
81
109
|
keys = [keys];
|
|
82
110
|
}
|
|
111
|
+
// --- 获取老的 key 对应的 node ---
|
|
83
112
|
const mapOld = {};
|
|
84
113
|
for (const key of keys) {
|
|
85
114
|
const oldNode = this.find(key);
|
|
@@ -89,6 +118,7 @@ class Consistent {
|
|
|
89
118
|
mapOld[key] = oldNode;
|
|
90
119
|
}
|
|
91
120
|
this.add(node);
|
|
121
|
+
// --- 再逐一检测老的和新的的 node 是否一致 ---
|
|
92
122
|
for (const key of keys) {
|
|
93
123
|
const newNode = this.find(key);
|
|
94
124
|
if (!newNode) {
|
|
@@ -109,11 +139,21 @@ exports.Consistent = Consistent;
|
|
|
109
139
|
function get(vcount = 300) {
|
|
110
140
|
return new Consistent(vcount);
|
|
111
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
*--- 快速查找一个 key 属于哪个 node ---
|
|
144
|
+
* @param key 要查找的key
|
|
145
|
+
* @param nodes node 列表
|
|
146
|
+
* @param vcount 虚拟节点数量
|
|
147
|
+
*/
|
|
112
148
|
function fast(key, nodes, vcount = 300) {
|
|
113
149
|
const circle = {};
|
|
114
150
|
addToCircle(circle, nodes, vcount);
|
|
115
151
|
return findInCircle(circle, key);
|
|
116
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* --- hash 函数 ---
|
|
155
|
+
* @param val 要 hash 的值
|
|
156
|
+
*/
|
|
117
157
|
function hash(val) {
|
|
118
158
|
if (typeof val === 'number') {
|
|
119
159
|
val = val.toString();
|
|
@@ -125,6 +165,12 @@ function hash(val) {
|
|
|
125
165
|
(bKey.charCodeAt(0) & 0xFF);
|
|
126
166
|
return res & 0xffffffff;
|
|
127
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* --- 获取区间节点系列 ---
|
|
170
|
+
* @param min 最小值(含)
|
|
171
|
+
* @param max 最大值(含)
|
|
172
|
+
* @param pre 前导
|
|
173
|
+
*/
|
|
128
174
|
function getRange(min, max, pre = '') {
|
|
129
175
|
const ls = [];
|
|
130
176
|
for (let i = min; i <= max; ++i) {
|
|
@@ -132,6 +178,12 @@ function getRange(min, max, pre = '') {
|
|
|
132
178
|
}
|
|
133
179
|
return ls;
|
|
134
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* --- 添加到圆环 ---
|
|
183
|
+
* @param circle 圆环
|
|
184
|
+
* @param node node 节点名一个或多个
|
|
185
|
+
* @param vcount 虚拟节点数量
|
|
186
|
+
*/
|
|
135
187
|
function addToCircle(circle, node, vcount = 300) {
|
|
136
188
|
if (typeof node === 'string') {
|
|
137
189
|
node = [node];
|
|
@@ -142,6 +194,12 @@ function addToCircle(circle, node, vcount = 300) {
|
|
|
142
194
|
}
|
|
143
195
|
}
|
|
144
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* --- 获得一个最近的顺时针节点 ---
|
|
199
|
+
* @param circle 圆环
|
|
200
|
+
* @param key 为给定键取 Hash,取得顺时针方向上最近的一个虚拟节点对应的实际节点
|
|
201
|
+
* @param keys keys,留空则自动从 circle 上取
|
|
202
|
+
*/
|
|
145
203
|
function findInCircle(circle, key, keys = []) {
|
|
146
204
|
let count = keys.length;
|
|
147
205
|
if (keys.length === 0) {
|
|
@@ -167,5 +225,6 @@ function findInCircle(circle, key, keys = []) {
|
|
|
167
225
|
}
|
|
168
226
|
return circle[v];
|
|
169
227
|
}
|
|
228
|
+
// --- 没找到 ---
|
|
170
229
|
return circle[keys[0]];
|
|
171
230
|
}
|