mm_machine 2.9.3 → 2.9.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.
Files changed (8) hide show
  1. package/dir_scanner.js +262 -0
  2. package/drive.js +668 -490
  3. package/id_gen.js +138 -0
  4. package/index.js +1141 -921
  5. package/mod.js +742 -711
  6. package/package.json +6 -2
  7. package/registry.js +634 -0
  8. package/word.js +209 -0
package/id_gen.js ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * IdGen 雪花算法 ID 生成器
3
+ * 基于雪花算法(Snowflake)的分布式唯一 ID 生成器,生成 64 位整数 ID
4
+ */
5
+ class IdGen {
6
+ /**
7
+ * 构造函数
8
+ * @param {object} config 配置参数
9
+ * @param {number} config.data_center_no 数据中心编号 (0-31)
10
+ * @param {number} config.machine_no 机器编号 (0-31)
11
+ * @param {number} [config.epoch=1700000000000] 自定义起始时间戳(毫秒),默认 2023-11-15 00:00:00 UTC
12
+ * @param {number} [config.sequence=0] 初始序列号
13
+ */
14
+ constructor(config = {}) {
15
+ this.data_center_no = config.data_center_no || config.dc_id || 0;
16
+ this.machine_no = config.machine_no || config.worker_id || 0;
17
+ this.sequence = config.sequence || 0;
18
+ this.epoch = config.epoch || 1700000000000;
19
+ this.last_timestamp = -1;
20
+
21
+ this._initBits();
22
+ }
23
+ }
24
+
25
+ /**
26
+ * 获取当前时间戳
27
+ * @returns {number} 当前时间戳
28
+ */
29
+ IdGen.prototype._timeGen = function () {
30
+ return Date.now();
31
+ };
32
+
33
+ /**
34
+ * 等待下一毫秒
35
+ * @param {number} last_timestamp 上次时间戳
36
+ * @returns {number} 新的时间戳
37
+ */
38
+ IdGen.prototype._tilNextMillis = function (last_timestamp) {
39
+ var timestamp = this._timeGen();
40
+ while (timestamp <= last_timestamp) {
41
+ timestamp = this._timeGen();
42
+ }
43
+ return timestamp;
44
+ };
45
+
46
+ /**
47
+ * 初始化位运算参数
48
+ * @private
49
+ */
50
+ IdGen.prototype._initBits = function () {
51
+ this.dc_id_bits = 5;
52
+ this.worker_id_bits = 5;
53
+ this.sequence_bits = 12;
54
+
55
+ this.max_dc_id = -1 ^ (-1 << this.dc_id_bits);
56
+ this.max_worker_id = -1 ^ (-1 << this.worker_id_bits);
57
+ this.sequence_mask = -1 ^ (-1 << this.sequence_bits);
58
+
59
+ this.worker_id_shift = this.sequence_bits;
60
+ this.dc_id_shift = this.sequence_bits + this.worker_id_bits;
61
+ this.timestamp_left_shift = this.sequence_bits + this.worker_id_bits + this.dc_id_bits;
62
+
63
+ if (this.data_center_no > this.max_dc_id || this.data_center_no < 0) {
64
+ throw new TypeError('数据中心编号必须在0-' + this.max_dc_id + '之间');
65
+ }
66
+ if (this.machine_no > this.max_worker_id || this.machine_no < 0) {
67
+ throw new TypeError('机器编号必须在0-' + this.max_worker_id + '之间');
68
+ }
69
+ };
70
+
71
+ /**
72
+ * 生成下一个ID
73
+ * @returns {string} 唯一ID
74
+ */
75
+ IdGen.prototype.nextId = function () {
76
+ var timestamp = this._timeGen();
77
+
78
+ if (timestamp < this.last_timestamp) {
79
+ throw new Error('时钟回拨,拒绝生成ID');
80
+ }
81
+
82
+ if (this.last_timestamp === timestamp) {
83
+ this.sequence = (this.sequence + 1) & this.sequence_mask;
84
+ if (this.sequence === 0) {
85
+ timestamp = this._tilNextMillis(this.last_timestamp);
86
+ }
87
+ } else {
88
+ this.sequence = 0;
89
+ }
90
+
91
+ this.last_timestamp = timestamp;
92
+
93
+ var id =
94
+ (BigInt(timestamp - this.epoch) << BigInt(this.timestamp_left_shift)) |
95
+ (BigInt(this.data_center_no) << BigInt(this.dc_id_shift)) |
96
+ (BigInt(this.machine_no) << BigInt(this.worker_id_shift)) |
97
+ BigInt(this.sequence);
98
+
99
+ return id.toString();
100
+ };
101
+
102
+ /**
103
+ * 生成带前缀的ID
104
+ * @param {string} prefix 前缀
105
+ * @returns {string} 带前缀的唯一ID
106
+ */
107
+ IdGen.prototype.generateId = function (prefix) {
108
+ if (typeof prefix !== 'string') {
109
+ throw new TypeError('前缀必须是字符串');
110
+ }
111
+ return prefix + '_' + this.nextId();
112
+ };
113
+
114
+ /**
115
+ * 解析ID信息
116
+ * @param {string} id ID字符串
117
+ * @returns {object} ID信息对象
118
+ */
119
+ IdGen.prototype.parseId = function (id) {
120
+ if (typeof id !== 'string') {
121
+ throw new TypeError('ID必须是字符串');
122
+ }
123
+ var num = BigInt(id.replace(/^[a-zA-Z_]+_/, ''));
124
+ var timestamp = Number((num >> 22n) + BigInt(this.epoch));
125
+ var dc_id = Number((num >> 17n) & 31n);
126
+ var worker_id = Number((num >> 12n) & 31n);
127
+ var sequence = Number(num & 4095n);
128
+
129
+ return {
130
+ timestamp: timestamp,
131
+ datetime: new Date(timestamp).toISOString(),
132
+ data_center_no: dc_id,
133
+ machine_no: worker_id,
134
+ sequence: sequence
135
+ };
136
+ };
137
+
138
+ module.exports = { IdGen };