sculp-js 1.13.6 → 1.15.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.
- package/README.md +3 -1
- package/dist/cjs/_virtual/_commonjsHelpers.js +1 -1
- package/dist/cjs/array.js +1 -1
- package/dist/cjs/async.js +1 -1
- package/dist/cjs/base64.js +1 -1
- package/dist/cjs/clipboard.js +1 -1
- package/dist/cjs/cloneDeep.js +1 -1
- package/dist/cjs/concurrentLimit.js +179 -0
- package/dist/cjs/cookie.js +1 -1
- package/dist/cjs/date.js +1 -1
- package/dist/cjs/dom.js +1 -1
- package/dist/cjs/download.js +1 -1
- package/dist/cjs/easing.js +1 -1
- package/dist/cjs/file.js +1 -1
- package/dist/cjs/func.js +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/math.js +1 -1
- package/dist/cjs/node_modules/bezier-easing/src/index.js +1 -1
- package/dist/cjs/number.js +2 -4
- package/dist/cjs/object.js +1 -1
- package/dist/cjs/path.js +1 -1
- package/dist/cjs/qs.js +1 -1
- package/dist/cjs/random.js +1 -1
- package/dist/cjs/string.js +1 -1
- package/dist/cjs/tooltip.js +1 -1
- package/dist/cjs/tree.js +73 -5
- package/dist/cjs/type.js +1 -1
- package/dist/cjs/unique.js +1 -1
- package/dist/cjs/url.js +1 -1
- package/dist/cjs/validator.js +1 -1
- package/dist/cjs/variable.js +1 -1
- package/dist/cjs/watermark.js +1 -1
- package/dist/esm/array.js +1 -1
- package/dist/esm/async.js +1 -1
- package/dist/esm/base64.js +1 -1
- package/dist/esm/clipboard.js +1 -1
- package/dist/esm/cloneDeep.js +1 -1
- package/dist/esm/concurrentLimit.js +176 -0
- package/dist/esm/cookie.js +1 -1
- package/dist/esm/date.js +1 -1
- package/dist/esm/dom.js +1 -1
- package/dist/esm/download.js +1 -1
- package/dist/esm/easing.js +1 -1
- package/dist/esm/file.js +1 -1
- package/dist/esm/func.js +1 -1
- package/dist/esm/index.js +12 -2
- package/dist/esm/math.js +1 -1
- package/dist/esm/number.js +3 -5
- package/dist/esm/object.js +1 -1
- package/dist/esm/path.js +1 -1
- package/dist/esm/qs.js +1 -1
- package/dist/esm/random.js +1 -1
- package/dist/esm/string.js +1 -1
- package/dist/esm/tooltip.js +1 -1
- package/dist/esm/tree.js +73 -7
- package/dist/esm/type.js +1 -1
- package/dist/esm/unique.js +1 -1
- package/dist/esm/url.js +1 -1
- package/dist/esm/validator.js +1 -1
- package/dist/esm/variable.js +1 -1
- package/dist/esm/watermark.js +1 -1
- package/dist/types/concurrentLimit.d.ts +65 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/tree.d.ts +36 -0
- package/dist/umd/index.min.js +2 -2
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -52,6 +52,8 @@
|
|
|
52
52
|
|
|
53
53
|
- forEachDeep
|
|
54
54
|
- mapDeep
|
|
55
|
+
- findDeep
|
|
56
|
+
- filterDeep
|
|
55
57
|
- searchTreeById
|
|
56
58
|
- formatTree
|
|
57
59
|
- flatTree
|
|
@@ -100,7 +102,7 @@
|
|
|
100
102
|
- File (web)
|
|
101
103
|
|
|
102
104
|
- chooseLocalFile
|
|
103
|
-
- compressImg
|
|
105
|
+
- compressImg
|
|
104
106
|
|
|
105
107
|
- Dom (web)
|
|
106
108
|
|
package/dist/cjs/array.js
CHANGED
package/dist/cjs/async.js
CHANGED
package/dist/cjs/base64.js
CHANGED
package/dist/cjs/clipboard.js
CHANGED
package/dist/cjs/cloneDeep.js
CHANGED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* sculp-js v1.15.0
|
|
3
|
+
* (c) 2023-present chandq
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 并发限制执行器
|
|
11
|
+
* @param {Array<Function>} tasks - 返回Promise的任务函数数组
|
|
12
|
+
* @param {number} limit - 最大并发数
|
|
13
|
+
* @returns {Promise<Array>} - 按任务顺序返回结果数组
|
|
14
|
+
*/
|
|
15
|
+
async function concurrentLimit(tasks, limit) {
|
|
16
|
+
if (!Array.isArray(tasks)) {
|
|
17
|
+
throw new Error('tasks must be an array of functions');
|
|
18
|
+
}
|
|
19
|
+
if (typeof limit !== 'number' || limit <= 0) {
|
|
20
|
+
throw new Error('limit must be a positive number');
|
|
21
|
+
}
|
|
22
|
+
// Validate each task is a function
|
|
23
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
24
|
+
if (typeof tasks[i] !== 'function') {
|
|
25
|
+
throw new Error(`task at index ${i} must be a function`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (tasks.length === 0) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
const results = new Array(tasks.length);
|
|
32
|
+
let currentIndex = 0;
|
|
33
|
+
return new Promise(resolve => {
|
|
34
|
+
let running = 0;
|
|
35
|
+
let completed = 0;
|
|
36
|
+
const executeNext = () => {
|
|
37
|
+
// 启动新任务直到达到并发限制
|
|
38
|
+
while (running < limit && currentIndex < tasks.length) {
|
|
39
|
+
const taskIndex = currentIndex;
|
|
40
|
+
const task = tasks[currentIndex];
|
|
41
|
+
currentIndex++;
|
|
42
|
+
running++;
|
|
43
|
+
// 将函数包装在 Promise 中以处理同步错误
|
|
44
|
+
Promise.resolve()
|
|
45
|
+
.then(() => task())
|
|
46
|
+
.then(value => {
|
|
47
|
+
results[taskIndex] = { status: 'fulfilled', value };
|
|
48
|
+
})
|
|
49
|
+
.catch(reason => {
|
|
50
|
+
results[taskIndex] = { status: 'rejected', reason };
|
|
51
|
+
})
|
|
52
|
+
// eslint-disable-next-line no-loop-func
|
|
53
|
+
.finally(() => {
|
|
54
|
+
running--;
|
|
55
|
+
completed++;
|
|
56
|
+
if (completed === tasks.length) {
|
|
57
|
+
resolve(results);
|
|
58
|
+
} else {
|
|
59
|
+
// 继续执行下一个任务
|
|
60
|
+
executeNext();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
// 开始执行
|
|
66
|
+
executeNext();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 增强版:支持取消和进度回调
|
|
71
|
+
*/
|
|
72
|
+
class ConcurrentExecutor {
|
|
73
|
+
limit;
|
|
74
|
+
active;
|
|
75
|
+
queue;
|
|
76
|
+
results;
|
|
77
|
+
isStopped;
|
|
78
|
+
onProgress;
|
|
79
|
+
onTaskComplete;
|
|
80
|
+
constructor(limit = 5) {
|
|
81
|
+
this.limit = limit;
|
|
82
|
+
this.active = new Map();
|
|
83
|
+
this.queue = [];
|
|
84
|
+
this.results = [];
|
|
85
|
+
this.isStopped = false;
|
|
86
|
+
this.onProgress = null;
|
|
87
|
+
this.onTaskComplete = null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 添加任务
|
|
91
|
+
* @param {Function} task - 返回Promise的任务函数
|
|
92
|
+
* @param {any} meta - 任务元数据
|
|
93
|
+
*/
|
|
94
|
+
add(task, meta = {}) {
|
|
95
|
+
const taskId = this.queue.length;
|
|
96
|
+
this.queue.push({ task, meta, id: taskId });
|
|
97
|
+
return taskId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 批量添加任务
|
|
101
|
+
*/
|
|
102
|
+
addAll(tasks) {
|
|
103
|
+
return tasks.map((task, i) => this.add(task, { index: i }));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 执行所有任务
|
|
107
|
+
*/
|
|
108
|
+
async run() {
|
|
109
|
+
if (this.isStopped) {
|
|
110
|
+
throw new Error('Executor has been stopped');
|
|
111
|
+
}
|
|
112
|
+
this.results = new Array(this.queue.length);
|
|
113
|
+
let completed = 0;
|
|
114
|
+
// 更新进度
|
|
115
|
+
const updateProgress = () => {
|
|
116
|
+
if (this.onProgress) {
|
|
117
|
+
this.onProgress({
|
|
118
|
+
completed,
|
|
119
|
+
total: this.queue.length,
|
|
120
|
+
active: this.active.size,
|
|
121
|
+
percent: (completed / this.queue.length) * 100
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
// 执行单个任务
|
|
126
|
+
const runTask = async taskInfo => {
|
|
127
|
+
if (this.isStopped) return;
|
|
128
|
+
const { task, id, meta } = taskInfo;
|
|
129
|
+
const taskPromise = Promise.resolve().then(() => task(meta));
|
|
130
|
+
this.active.set(id, taskPromise);
|
|
131
|
+
try {
|
|
132
|
+
const result = await taskPromise;
|
|
133
|
+
this.results[id] = { status: 'fulfilled', value: result };
|
|
134
|
+
} catch (error) {
|
|
135
|
+
this.results[id] = { status: 'rejected', reason: error };
|
|
136
|
+
} finally {
|
|
137
|
+
this.active.delete(id);
|
|
138
|
+
completed++;
|
|
139
|
+
updateProgress();
|
|
140
|
+
if (this.onTaskComplete) {
|
|
141
|
+
this.onTaskComplete(id, this.results[id]);
|
|
142
|
+
}
|
|
143
|
+
// 执行队列中的下一个任务
|
|
144
|
+
if (this.queue.length > 0 && !this.isStopped) {
|
|
145
|
+
const nextTask = this.queue.shift();
|
|
146
|
+
runTask(nextTask);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
// 启动初始任务
|
|
151
|
+
const initialTasks = this.queue.splice(0, this.limit);
|
|
152
|
+
initialTasks.forEach(runTask);
|
|
153
|
+
// 等待所有任务完成
|
|
154
|
+
while (this.active.size > 0 && !this.isStopped) {
|
|
155
|
+
await Promise.race(this.active.values());
|
|
156
|
+
}
|
|
157
|
+
if (this.isStopped) {
|
|
158
|
+
throw new Error('Execution was stopped');
|
|
159
|
+
}
|
|
160
|
+
return this.results;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 停止执行
|
|
164
|
+
*/
|
|
165
|
+
stop() {
|
|
166
|
+
this.isStopped = true;
|
|
167
|
+
this.active.clear();
|
|
168
|
+
this.queue = [];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* 清空队列
|
|
172
|
+
*/
|
|
173
|
+
clear() {
|
|
174
|
+
this.queue = [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
exports.ConcurrentExecutor = ConcurrentExecutor;
|
|
179
|
+
exports.concurrentLimit = concurrentLimit;
|
package/dist/cjs/cookie.js
CHANGED
package/dist/cjs/date.js
CHANGED
package/dist/cjs/dom.js
CHANGED
package/dist/cjs/download.js
CHANGED
package/dist/cjs/easing.js
CHANGED
package/dist/cjs/file.js
CHANGED
package/dist/cjs/func.js
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.15.0
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -33,6 +33,7 @@ var validator = require('./validator.js');
|
|
|
33
33
|
var variable = require('./variable.js');
|
|
34
34
|
var cloneDeep = require('./cloneDeep.js');
|
|
35
35
|
var easing = require('./easing.js');
|
|
36
|
+
var concurrentLimit = require('./concurrentLimit.js');
|
|
36
37
|
|
|
37
38
|
exports.arrayEach = array.arrayEach;
|
|
38
39
|
exports.arrayEachAsync = array.arrayEachAsync;
|
|
@@ -141,6 +142,8 @@ exports.UNIQUE_NUMBER_SAFE_LENGTH = unique.UNIQUE_NUMBER_SAFE_LENGTH;
|
|
|
141
142
|
exports.uniqueNumber = unique.uniqueNumber;
|
|
142
143
|
exports.uniqueString = unique.uniqueString;
|
|
143
144
|
exports.tooltipEvent = tooltip.tooltipEvent;
|
|
145
|
+
exports.filterDeep = tree.filterDeep;
|
|
146
|
+
exports.findDeep = tree.findDeep;
|
|
144
147
|
exports.flatTree = tree.flatTree;
|
|
145
148
|
exports.forEachDeep = tree.forEachDeep;
|
|
146
149
|
exports.formatTree = tree.formatTree;
|
|
@@ -182,3 +185,5 @@ exports.easingFunctional = easing.easingFunctional;
|
|
|
182
185
|
exports.easingStringify = easing.easingStringify;
|
|
183
186
|
exports.getEasing = easing.getEasing;
|
|
184
187
|
exports.setEasing = easing.setEasing;
|
|
188
|
+
exports.ConcurrentExecutor = concurrentLimit.ConcurrentExecutor;
|
|
189
|
+
exports.concurrentLimit = concurrentLimit.concurrentLimit;
|
package/dist/cjs/math.js
CHANGED
package/dist/cjs/number.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.15.0
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -106,9 +106,7 @@ function formatNumber(num, decimals) {
|
|
|
106
106
|
return parseInt(String(num)).toLocaleString();
|
|
107
107
|
}
|
|
108
108
|
let prec = 0;
|
|
109
|
-
if (
|
|
110
|
-
throw new Error('Decimals must be a positive number not less than zero');
|
|
111
|
-
} else if (decimals > 0) {
|
|
109
|
+
if (decimals > 0) {
|
|
112
110
|
prec = decimals;
|
|
113
111
|
}
|
|
114
112
|
return Number(Number(num).toFixed(prec)).toLocaleString('en-US');
|
package/dist/cjs/object.js
CHANGED
package/dist/cjs/path.js
CHANGED
package/dist/cjs/qs.js
CHANGED
package/dist/cjs/random.js
CHANGED
package/dist/cjs/string.js
CHANGED
package/dist/cjs/tooltip.js
CHANGED
package/dist/cjs/tree.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
2
|
+
* sculp-js v1.15.0
|
|
3
3
|
* (c) 2023-present chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -131,6 +131,75 @@ function forEachDeep(
|
|
|
131
131
|
// @ts-ignore
|
|
132
132
|
tree = null;
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* 树查找函数, 可用于查找Array和NodeList类型的数据
|
|
136
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
137
|
+
* @param {Function} predicate 断言函数
|
|
138
|
+
* @param {options} options 支持定制子元素名称、反向遍历、广度优先遍历,默认{
|
|
139
|
+
childField: 'children',
|
|
140
|
+
reverse: false,
|
|
141
|
+
breadthFirst: false,
|
|
142
|
+
isDomNode: false,
|
|
143
|
+
}
|
|
144
|
+
* @returns {V|null}
|
|
145
|
+
*/
|
|
146
|
+
function findDeep(
|
|
147
|
+
tree,
|
|
148
|
+
predicate,
|
|
149
|
+
options = {
|
|
150
|
+
childField: 'children',
|
|
151
|
+
reverse: false,
|
|
152
|
+
breadthFirst: false,
|
|
153
|
+
isDomNode: false
|
|
154
|
+
}
|
|
155
|
+
) {
|
|
156
|
+
let result = null;
|
|
157
|
+
forEachDeep(
|
|
158
|
+
tree,
|
|
159
|
+
(...args) => {
|
|
160
|
+
if (predicate(...args)) {
|
|
161
|
+
result = args[0];
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
options
|
|
166
|
+
);
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 树过滤函数, 可用于过滤Array和NodeList类型的数据
|
|
171
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
172
|
+
* @param {Function} predicate 断言函数
|
|
173
|
+
* @param {options} options 支持定制子元素名称、反向遍历、广度优先遍历,默认{
|
|
174
|
+
childField: 'children',
|
|
175
|
+
reverse: false,
|
|
176
|
+
breadthFirst: false,
|
|
177
|
+
isDomNode: false,
|
|
178
|
+
}
|
|
179
|
+
* @returns {V[]}
|
|
180
|
+
*/
|
|
181
|
+
function filterDeep(
|
|
182
|
+
tree,
|
|
183
|
+
predicate,
|
|
184
|
+
options = {
|
|
185
|
+
childField: 'children',
|
|
186
|
+
reverse: false,
|
|
187
|
+
breadthFirst: false,
|
|
188
|
+
isDomNode: false
|
|
189
|
+
}
|
|
190
|
+
) {
|
|
191
|
+
const result = [];
|
|
192
|
+
forEachDeep(
|
|
193
|
+
tree,
|
|
194
|
+
(...args) => {
|
|
195
|
+
if (predicate(...args)) {
|
|
196
|
+
result.push(args[0]);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
options
|
|
200
|
+
);
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
134
203
|
/**
|
|
135
204
|
* 创建一个新数组, 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
|
|
136
205
|
*
|
|
@@ -316,10 +385,7 @@ function flatTree(treeList, options = defaultFieldOptions) {
|
|
|
316
385
|
* @returns {V[]}
|
|
317
386
|
*/
|
|
318
387
|
function fuzzySearchTree(nodes, filterCondition, options = defaultSearchTreeOptions) {
|
|
319
|
-
if (
|
|
320
|
-
!type.objectHas(filterCondition, 'filter') &&
|
|
321
|
-
(!type.objectHas(filterCondition, 'keyword') || type.isEmpty(filterCondition.keyword))
|
|
322
|
-
) {
|
|
388
|
+
if (!type.objectHas(filterCondition, 'filter') && !filterCondition.keyword) {
|
|
323
389
|
return nodes;
|
|
324
390
|
}
|
|
325
391
|
const result = [];
|
|
@@ -364,6 +430,8 @@ function fuzzySearchTree(nodes, filterCondition, options = defaultSearchTreeOpti
|
|
|
364
430
|
return result;
|
|
365
431
|
}
|
|
366
432
|
|
|
433
|
+
exports.filterDeep = filterDeep;
|
|
434
|
+
exports.findDeep = findDeep;
|
|
367
435
|
exports.flatTree = flatTree;
|
|
368
436
|
exports.forEachDeep = forEachDeep;
|
|
369
437
|
exports.formatTree = formatTree;
|
package/dist/cjs/type.js
CHANGED
package/dist/cjs/unique.js
CHANGED
package/dist/cjs/url.js
CHANGED
package/dist/cjs/validator.js
CHANGED
package/dist/cjs/variable.js
CHANGED
package/dist/cjs/watermark.js
CHANGED
package/dist/esm/array.js
CHANGED
package/dist/esm/async.js
CHANGED
package/dist/esm/base64.js
CHANGED
package/dist/esm/clipboard.js
CHANGED
package/dist/esm/cloneDeep.js
CHANGED