sculp-js 1.7.0 → 1.7.2

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 (61) hide show
  1. package/README.md +2 -1
  2. package/lib/cjs/array.js +1 -1
  3. package/lib/cjs/async.js +1 -1
  4. package/lib/cjs/base64.js +1 -1
  5. package/lib/cjs/clipboard.js +1 -1
  6. package/lib/cjs/cookie.js +1 -1
  7. package/lib/cjs/date.js +1 -1
  8. package/lib/cjs/dom.js +1 -1
  9. package/lib/cjs/download.js +1 -1
  10. package/lib/cjs/easing.js +1 -1
  11. package/lib/cjs/file.js +1 -1
  12. package/lib/cjs/func.js +1 -1
  13. package/lib/cjs/index.js +2 -2
  14. package/lib/cjs/math.js +1 -1
  15. package/lib/cjs/number.js +1 -1
  16. package/lib/cjs/object.js +104 -20
  17. package/lib/cjs/path.js +1 -1
  18. package/lib/cjs/qs.js +1 -1
  19. package/lib/cjs/random.js +1 -1
  20. package/lib/cjs/string.js +1 -1
  21. package/lib/cjs/tooltip.js +1 -1
  22. package/lib/cjs/tree.js +36 -14
  23. package/lib/cjs/type.js +1 -1
  24. package/lib/cjs/unique.js +1 -1
  25. package/lib/cjs/url.js +1 -1
  26. package/lib/cjs/validator.js +1 -1
  27. package/lib/cjs/variable.js +1 -1
  28. package/lib/cjs/watermark.js +1 -1
  29. package/lib/cjs/we-decode.js +1 -1
  30. package/lib/es/array.js +1 -1
  31. package/lib/es/async.js +1 -1
  32. package/lib/es/base64.js +1 -1
  33. package/lib/es/clipboard.js +1 -1
  34. package/lib/es/cookie.js +1 -1
  35. package/lib/es/date.js +1 -1
  36. package/lib/es/dom.js +1 -1
  37. package/lib/es/download.js +1 -1
  38. package/lib/es/easing.js +1 -1
  39. package/lib/es/file.js +1 -1
  40. package/lib/es/func.js +1 -1
  41. package/lib/es/index.js +2 -2
  42. package/lib/es/math.js +1 -1
  43. package/lib/es/number.js +1 -1
  44. package/lib/es/object.js +104 -20
  45. package/lib/es/path.js +1 -1
  46. package/lib/es/qs.js +1 -1
  47. package/lib/es/random.js +1 -1
  48. package/lib/es/string.js +1 -1
  49. package/lib/es/tooltip.js +1 -1
  50. package/lib/es/tree.js +36 -14
  51. package/lib/es/type.js +1 -1
  52. package/lib/es/unique.js +1 -1
  53. package/lib/es/url.js +1 -1
  54. package/lib/es/validator.js +1 -1
  55. package/lib/es/variable.js +1 -1
  56. package/lib/es/watermark.js +1 -1
  57. package/lib/es/we-decode.js +1 -1
  58. package/lib/index.d.ts +32 -12
  59. package/lib/umd/index.js +134 -31
  60. package/package.json +1 -1
  61. package/lib/tsdoc-metadata.json +0 -11
package/lib/umd/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.7.2
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -309,7 +309,7 @@
309
309
  return obj2;
310
310
  }
311
311
  /**
312
- * 对象祛除
312
+ * 对象去除
313
313
  * @param {O} obj
314
314
  * @param {K} keys
315
315
  * @returns {Pick<O, ArrayElements<K>>}
@@ -424,26 +424,110 @@
424
424
  }
425
425
  /**
426
426
  * 深拷贝堪称完全体 即:任何类型的数据都会被深拷贝
427
- * @param {AnyObject | AnyArray} obj
427
+ *
428
+ * 包含对null、原始值、对象循环引用的处理
429
+ *
430
+ * 对Map、Set、ArrayBuffer、Date、RegExp、Array、Object及原型链属性方法执行深拷贝
431
+ * @param {T} source
428
432
  * @param {WeakMap} map
429
- * @returns {AnyObject | AnyArray}
433
+ * @returns {T}
430
434
  */
431
- function cloneDeep(obj, map = new WeakMap()) {
432
- if (obj instanceof Date)
433
- return new Date(obj);
434
- if (obj instanceof RegExp)
435
- return new RegExp(obj);
436
- if (map.has(obj)) {
437
- return map.get(obj);
435
+ function cloneDeep(source, map = new WeakMap()) {
436
+ // 处理原始类型和 null/undefined
437
+ if (source === null || typeof source !== 'object') {
438
+ return source;
438
439
  }
439
- const allDesc = Object.getOwnPropertyDescriptors(obj);
440
- const cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);
441
- map.set(obj, cloneObj);
442
- for (const key of Reflect.ownKeys(obj)) {
443
- const value = obj[key];
444
- cloneObj[key] = value instanceof Object && typeof value !== 'function' ? cloneDeep(value, map) : value;
440
+ // 处理循环引用
441
+ if (map.has(source)) {
442
+ return map.get(source);
443
+ }
444
+ // 处理 ArrayBuffer
445
+ if (source instanceof ArrayBuffer) {
446
+ const copy = new ArrayBuffer(source.byteLength);
447
+ new Uint8Array(copy).set(new Uint8Array(source));
448
+ map.set(source, copy);
449
+ return copy;
450
+ }
451
+ // 处理 DataView 和 TypedArray (Uint8Array 等)
452
+ if (ArrayBuffer.isView(source)) {
453
+ const constructor = source.constructor;
454
+ const bufferCopy = cloneDeep(source.buffer, map);
455
+ return new constructor(bufferCopy, source.byteOffset, source.length);
456
+ }
457
+ // 处理 Date 对象
458
+ if (source instanceof Date) {
459
+ const copy = new Date(source.getTime());
460
+ map.set(source, copy);
461
+ return copy;
462
+ }
463
+ // 处理 RegExp 对象
464
+ if (source instanceof RegExp) {
465
+ const copy = new RegExp(source.source, source.flags);
466
+ copy.lastIndex = source.lastIndex; // 保留匹配状态
467
+ map.set(source, copy);
468
+ return copy;
469
+ }
470
+ // 处理 Map
471
+ if (source instanceof Map) {
472
+ const copy = new Map();
473
+ map.set(source, copy);
474
+ source.forEach((value, key) => {
475
+ copy.set(cloneDeep(key, map), cloneDeep(value, map));
476
+ });
477
+ return copy;
478
+ }
479
+ // 处理 Set
480
+ if (source instanceof Set) {
481
+ const copy = new Set();
482
+ map.set(source, copy);
483
+ source.forEach(value => {
484
+ copy.add(cloneDeep(value, map));
485
+ });
486
+ return copy;
487
+ }
488
+ // 处理数组 (包含稀疏数组)
489
+ if (Array.isArray(source)) {
490
+ const copy = Array.from({ length: source.length });
491
+ map.set(source, copy);
492
+ // 克隆所有有效索引
493
+ for (let i = 0; i < source.length; i++) {
494
+ if (i in source) {
495
+ // 保留空位
496
+ copy[i] = cloneDeep(source[i], map);
497
+ }
498
+ }
499
+ // 克隆数组的自定义属性
500
+ const descriptors = Object.getOwnPropertyDescriptors(source);
501
+ for (const key of Reflect.ownKeys(descriptors)) {
502
+ Object.defineProperty(copy, key, {
503
+ ...descriptors[key],
504
+ value: cloneDeep(descriptors[key].value, map)
505
+ });
506
+ }
507
+ return copy;
508
+ }
509
+ // 处理普通对象和类实例
510
+ const copy = Object.create(Object.getPrototypeOf(source));
511
+ map.set(source, copy);
512
+ const descriptors = Object.getOwnPropertyDescriptors(source);
513
+ for (const key of Reflect.ownKeys(descriptors)) {
514
+ const descriptor = descriptors[key];
515
+ if ('value' in descriptor) {
516
+ // 克隆数据属性
517
+ descriptor.value = cloneDeep(descriptor.value, map);
518
+ }
519
+ else {
520
+ // 处理访问器属性 (getter/setter)
521
+ if (descriptor.get) {
522
+ descriptor.get = cloneDeep(descriptor.get, map);
523
+ }
524
+ if (descriptor.set) {
525
+ descriptor.set = cloneDeep(descriptor.set, map);
526
+ }
527
+ }
528
+ Object.defineProperty(copy, key, descriptor);
445
529
  }
446
- return cloneObj;
530
+ return copy;
447
531
  }
448
532
 
449
533
  /**
@@ -2132,7 +2216,8 @@
2132
2216
  const defaultSearchTreeOptions = {
2133
2217
  childField: 'children',
2134
2218
  nameField: 'name',
2135
- ignoreEmptyChild: false
2219
+ removeEmptyChild: false,
2220
+ ignoreCase: true
2136
2221
  };
2137
2222
  /**
2138
2223
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
@@ -2189,14 +2274,16 @@
2189
2274
  walk(tree, null);
2190
2275
  }
2191
2276
  /**
2192
- * 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
2277
+ * 创建一个新数组, 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
2278
+ *
2279
+ * 可遍历任何带有 length 属性和数字键的类数组对象
2193
2280
  * @param {ArrayLike<V>} tree 树形数据
2194
2281
  * @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
2195
2282
  * @param {string} children 定制子元素的key
2196
2283
  * @param {boolean} isReverse 是否反向遍历
2197
2284
  * @returns {any[]} 新的一棵树
2198
2285
  */
2199
- function forEachMap(tree, iterator, children = 'children', isReverse = false) {
2286
+ function mapDeep(tree, iterator, children = 'children', isReverse = false) {
2200
2287
  let isBreak = false;
2201
2288
  const newTree = [];
2202
2289
  const walk = (arr, parent, newTree, level = 0) => {
@@ -2213,7 +2300,7 @@
2213
2300
  else if (re === true) {
2214
2301
  continue;
2215
2302
  }
2216
- newTree.push(re);
2303
+ newTree.push(objectOmit(re, [children]));
2217
2304
  // @ts-ignore
2218
2305
  if (arr[i] && Array.isArray(arr[i][children])) {
2219
2306
  newTree[newTree.length - 1][children] = [];
@@ -2239,7 +2326,7 @@
2239
2326
  else if (re === true) {
2240
2327
  continue;
2241
2328
  }
2242
- newTree.push(re);
2329
+ newTree.push(objectOmit(re, [children]));
2243
2330
  // @ts-ignore
2244
2331
  if (arr[i] && Array.isArray(arr[i][children])) {
2245
2332
  newTree[newTree.length - 1][children] = [];
@@ -2425,20 +2512,36 @@
2425
2512
  }
2426
2513
  /**
2427
2514
  * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
2428
- * @param {any[]} nodes
2429
- * @param {string} query
2515
+ * 以下搜索条件二选一,按先后优先级处理:
2516
+ * 1. 过滤函数filter, 返回true/false
2517
+ * 2. 匹配关键词,支持是否启用忽略大小写来判断
2518
+ *
2519
+ * 有以下特性:
2520
+ * 1. 可配置removeEmptyChild字段,来决定是否移除搜索结果中的空children字段
2521
+ * 2. 若无任何过滤条件或keyword模式匹配且keyword为空串,返回原对象;其他情况返回新数组
2522
+ * @param {V[]} nodes
2523
+ * @param {IFilterCondition} filterCondition
2430
2524
  * @param {ISearchTreeOpts} options
2431
- * @returns {any[]}
2525
+ * @returns {V[]}
2432
2526
  */
2433
- function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
2527
+ function fuzzySearchTree(nodes, filterCondition, options = defaultSearchTreeOptions) {
2528
+ if (!objectHas(filterCondition, 'filter') &&
2529
+ (!objectHas(filterCondition, 'keyword') || isEmpty(filterCondition.keyword))) {
2530
+ return nodes;
2531
+ }
2434
2532
  const result = [];
2435
2533
  for (const node of nodes) {
2436
2534
  // 递归检查子节点是否匹配
2437
2535
  const matchedChildren = node[options.childField] && node[options.childField].length > 0
2438
- ? fuzzySearchTree(node[options.childField] || [], query, options)
2536
+ ? fuzzySearchTree(node[options.childField] || [], filterCondition, options)
2439
2537
  : [];
2440
2538
  // 检查当前节点是否匹配或者有匹配的子节点
2441
- if (node[options.nameField].toLowerCase().includes(query.toLowerCase()) || matchedChildren.length > 0) {
2539
+ if ((objectHas(filterCondition, 'filter')
2540
+ ? filterCondition.filter(node)
2541
+ : !options.ignoreCase
2542
+ ? node[options.nameField].includes(filterCondition.keyword)
2543
+ : node[options.nameField].toLowerCase().includes(filterCondition.keyword.toLowerCase())) ||
2544
+ matchedChildren.length > 0) {
2442
2545
  // 将当前节点加入结果中
2443
2546
  if (node[options.childField]) {
2444
2547
  if (matchedChildren.length > 0) {
@@ -2447,7 +2550,7 @@
2447
2550
  [options.childField]: matchedChildren // 包含匹配的子节点
2448
2551
  });
2449
2552
  }
2450
- else if (options.ignoreEmptyChild) {
2553
+ else if (options.removeEmptyChild) {
2451
2554
  node[options.childField] && delete node[options.childField];
2452
2555
  result.push({
2453
2556
  ...node
@@ -2866,7 +2969,6 @@
2866
2969
  exports.executeInScope = executeInScope;
2867
2970
  exports.flatTree = flatTree;
2868
2971
  exports.forEachDeep = forEachDeep;
2869
- exports.forEachMap = forEachMap;
2870
2972
  exports.formatDate = formatDate;
2871
2973
  exports.formatNumber = formatNumber;
2872
2974
  exports.formatTree = formatTree;
@@ -2908,6 +3010,7 @@
2908
3010
  exports.isUndefined = isUndefined;
2909
3011
  exports.isUrl = isUrl;
2910
3012
  exports.isValidDate = isValidDate;
3013
+ exports.mapDeep = mapDeep;
2911
3014
  exports.multiply = multiply;
2912
3015
  exports.numberAbbr = numberAbbr;
2913
3016
  exports.numberToHex = numberToHex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sculp-js",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "packageManager": "npm@8.19.2",
5
5
  "description": "js工具库",
6
6
  "scripts": {
@@ -1,11 +0,0 @@
1
- // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
- // It should be published with your NPM package. It should not be tracked by Git.
3
- {
4
- "tsdocVersion": "0.12",
5
- "toolPackages": [
6
- {
7
- "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.38.3"
9
- }
10
- ]
11
- }