a2bei4-utils 1.0.9 → 1.0.11
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/dist/a2bei4.utils.cjs.js +193 -2
- package/dist/a2bei4.utils.cjs.js.map +1 -1
- package/dist/a2bei4.utils.cjs.min.js +1 -1
- package/dist/a2bei4.utils.cjs.min.js.map +1 -1
- package/dist/a2bei4.utils.esm.js +191 -2
- package/dist/a2bei4.utils.esm.js.map +1 -1
- package/dist/a2bei4.utils.esm.min.js +1 -1
- package/dist/a2bei4.utils.esm.min.js.map +1 -1
- package/dist/a2bei4.utils.umd.js +193 -2
- package/dist/a2bei4.utils.umd.js.map +1 -1
- package/dist/a2bei4.utils.umd.min.js +1 -1
- package/dist/a2bei4.utils.umd.min.js.map +1 -1
- package/dist/arr.cjs.map +1 -1
- package/dist/arr.js.map +1 -1
- package/dist/audio.cjs.map +1 -1
- package/dist/audio.js.map +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/common.cjs.map +1 -1
- package/dist/common.js.map +1 -1
- package/dist/date.cjs.map +1 -1
- package/dist/date.js.map +1 -1
- package/dist/download.cjs.map +1 -1
- package/dist/download.js.map +1 -1
- package/dist/evt.cjs.map +1 -1
- package/dist/evt.js.map +1 -1
- package/dist/id.cjs.map +1 -1
- package/dist/id.js.map +1 -1
- package/dist/menu.cjs.map +1 -1
- package/dist/menu.js.map +1 -1
- package/dist/timer.cjs +14 -0
- package/dist/timer.cjs.map +1 -1
- package/dist/timer.js +14 -0
- package/dist/timer.js.map +1 -1
- package/dist/tree.cjs +177 -0
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.js +176 -1
- package/dist/tree.js.map +1 -1
- package/dist/webSocket.cjs.map +1 -1
- package/dist/webSocket.js.map +1 -1
- package/package.json +5 -5
- package/types/index.d.ts +186 -2
- package/types/timer.d.ts +4 -0
- package/types/tree.d.ts +182 -1
package/dist/a2bei4.utils.esm.js
CHANGED
|
@@ -562,7 +562,7 @@ function isFunction(obj) {
|
|
|
562
562
|
* @param {*} obj - 待检测的值
|
|
563
563
|
* @returns {obj is string}
|
|
564
564
|
*/
|
|
565
|
-
function isNonEmptyString(obj) {
|
|
565
|
+
function isNonEmptyString$1(obj) {
|
|
566
566
|
return getDataType(obj) === "string" && obj.length > 0;
|
|
567
567
|
}
|
|
568
568
|
|
|
@@ -1821,6 +1821,10 @@ class IntervalTimer {
|
|
|
1821
1821
|
this._fn = fn;
|
|
1822
1822
|
this._ms = ms;
|
|
1823
1823
|
this._timerId = null;
|
|
1824
|
+
/**
|
|
1825
|
+
* @type {symbol | null}
|
|
1826
|
+
*/
|
|
1827
|
+
this._loopId = null;
|
|
1824
1828
|
}
|
|
1825
1829
|
|
|
1826
1830
|
/**
|
|
@@ -1829,8 +1833,17 @@ class IntervalTimer {
|
|
|
1829
1833
|
*/
|
|
1830
1834
|
start() {
|
|
1831
1835
|
this.stop();
|
|
1836
|
+
|
|
1837
|
+
const curLoopId = Symbol();
|
|
1838
|
+
this._loopId = curLoopId;
|
|
1839
|
+
|
|
1832
1840
|
const loop = () => {
|
|
1841
|
+
if (this._loopId !== curLoopId) return;
|
|
1842
|
+
|
|
1833
1843
|
this._fn(); // 执行业务
|
|
1844
|
+
|
|
1845
|
+
if (this._loopId !== curLoopId) return;
|
|
1846
|
+
|
|
1834
1847
|
this._timerId = setTimeout(loop, this._ms);
|
|
1835
1848
|
};
|
|
1836
1849
|
loop(); // 立即执行第一次
|
|
@@ -1840,6 +1853,7 @@ class IntervalTimer {
|
|
|
1840
1853
|
* 停止定时器。
|
|
1841
1854
|
*/
|
|
1842
1855
|
stop() {
|
|
1856
|
+
this._loopId = null;
|
|
1843
1857
|
if (this._timerId !== null) {
|
|
1844
1858
|
clearTimeout(this._timerId);
|
|
1845
1859
|
this._timerId = null;
|
|
@@ -2092,6 +2106,181 @@ function findTreeNodePath(nodes, targetValue, key = "id", parentKey = "pid", chi
|
|
|
2092
2106
|
}
|
|
2093
2107
|
|
|
2094
2108
|
return path.reverse();
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
/**
|
|
2112
|
+
* 处理函数的返回值类型,用于控制节点是否添加。
|
|
2113
|
+
* @typedef {Object} TransformTreeDataWithExtra_HandlerResult
|
|
2114
|
+
* @property {boolean} [isAdd] - 是否将该节点添加到树中。如果为 false,则过滤掉该节点。
|
|
2115
|
+
*/
|
|
2116
|
+
|
|
2117
|
+
/**
|
|
2118
|
+
* 最终输出的树形结构的字段配置。
|
|
2119
|
+
* @typedef {Object} TransformTreeDataWithExtra_TreeDataOption
|
|
2120
|
+
* @property {string} [idKey="key"] - 最终树节点的唯一标识字段名。
|
|
2121
|
+
* @property {string} [titleKey="title"] - 最终树节点的标题显示字段名。
|
|
2122
|
+
* @property {string} [childrenKey="children"] - 最终树节点的子节点列表字段名。
|
|
2123
|
+
*/
|
|
2124
|
+
|
|
2125
|
+
/**
|
|
2126
|
+
* 主数据(父节点)的相关配置选项。
|
|
2127
|
+
* @typedef {Object} TransformTreeDataWithExtra_NodeOption
|
|
2128
|
+
* @property {string} [idPrefix] - 节点 ID 的前缀。
|
|
2129
|
+
* @property {string} [idKey="id"] - 原始数据中作为唯一标识的字段名。
|
|
2130
|
+
* @property {string} [titleKey="name"] - 原始数据中作为标题的字段名。
|
|
2131
|
+
* @property {string} [childrenKey="children"] - 原始数据中子节点列表的字段名。
|
|
2132
|
+
* @property {Record<string, any>} [assignData] - 需要额外合并到每个树节点上的静态属性。
|
|
2133
|
+
* @property {string} [rawDataKey] - 如果提供,会将原始节点数据对象挂载到树节点的此字段下。
|
|
2134
|
+
* @property {Object<string, any>} [nodeDataId2Obj] - (副作用) 引用传递的对象,用于建立 id -> 原始数据的映射。
|
|
2135
|
+
* @property {function(object, object): TransformTreeDataWithExtra_HandlerResult | void} [nodeDataHandler] - 对每个主节点进行处理的回调函数。
|
|
2136
|
+
*/
|
|
2137
|
+
|
|
2138
|
+
/**
|
|
2139
|
+
* 额外数据(子节点)的相关配置选项。
|
|
2140
|
+
* @typedef {Object} TransformTreeDataWithExtra_ExtraOption
|
|
2141
|
+
* @property {string} [idPrefix] - 额外节点 ID 的前缀。
|
|
2142
|
+
* @property {string} [idKey="id"] - 额外数据中作为唯一标识的字段名。
|
|
2143
|
+
* @property {string} [titleKey="name"] - 额外数据中作为标题的字段名。
|
|
2144
|
+
* @property {string} [childrenKey="extraChildren"] - 在主节点上查找额外数据列表的字段名。
|
|
2145
|
+
* @property {Record<string, any>} [assignData] - 需要额外合并到每个额外树节点上的静态属性。
|
|
2146
|
+
* @property {string} [rawDataKey] - 如果提供,会将原始额外数据对象挂载到树节点的此字段下。
|
|
2147
|
+
* @property {Object<string, any>} [extraDataId2Obj] - (副作用) 引用传递的对象,用于建立 id -> 额外数据的映射。
|
|
2148
|
+
* @property {function(object, object, object): TransformTreeDataWithExtra_HandlerResult | void} [extraDataHandler] - 对每个额外节点进行处理的回调函数。
|
|
2149
|
+
*/
|
|
2150
|
+
|
|
2151
|
+
/**
|
|
2152
|
+
* 将平铺或嵌套的原始数据转换为标准树形结构。
|
|
2153
|
+
* 支持将外部“额外数据”节点作为子节点插入到主节点层级中。
|
|
2154
|
+
* 支持自定义字段映射、ID 前缀、数据挂载以及通过回调函数过滤节点。
|
|
2155
|
+
*
|
|
2156
|
+
* @template T
|
|
2157
|
+
* @param {Array<T>} data - 原始数据数组。
|
|
2158
|
+
* @param {TransformTreeDataWithExtra_ExtraOption} [extraOption] - 额外数据(子节点)的相关配置选项。
|
|
2159
|
+
* @param {TransformTreeDataWithExtra_NodeOption} [nodeOption] - 主数据(父节点)的相关配置选项。
|
|
2160
|
+
* @param {TransformTreeDataWithExtra_TreeDataOption} [treeDataOption] - 最终输出的树形结构的字段配置选项。
|
|
2161
|
+
* @returns {Array<object>} 转换后的树形数据数组。
|
|
2162
|
+
*/
|
|
2163
|
+
function transformTreeDataWithExtra(data, extraOption = {}, nodeOption = {}, treeDataOption = {}) {
|
|
2164
|
+
const { idPrefix: nodeIdPrefix, idKey: nodeIdKey = "id", titleKey: nodeTitleKey = "name", childrenKey: nodeChildrenKey = "children", assignData: nodeAssignData = {}, rawDataKey: nodeRawDataKey, nodeDataId2Obj, nodeDataHandler } = nodeOption;
|
|
2165
|
+
const { idPrefix: extraIdPrefix, idKey: extraIdKey = "id", titleKey: extraTitleKey = "name", childrenKey: extraChildrenKey = "extraChildren", assignData: extraAssignData = {}, rawDataKey: extraRawDataKey, extraDataId2Obj, extraDataHandler } = extraOption;
|
|
2166
|
+
|
|
2167
|
+
const { idKey: treeIdKey = "key", titleKey: treeTitleKey = "title", childrenKey: treeChildrenKey = "children" } = treeDataOption;
|
|
2168
|
+
|
|
2169
|
+
const transformNode = (node) => {
|
|
2170
|
+
const treeNode = {
|
|
2171
|
+
[treeIdKey]: isNonEmptyString(nodeIdPrefix) ? nodeIdPrefix + node[nodeIdKey] : node[nodeIdKey],
|
|
2172
|
+
[treeTitleKey]: node[nodeTitleKey],
|
|
2173
|
+
[treeChildrenKey]: [],
|
|
2174
|
+
...nodeAssignData
|
|
2175
|
+
};
|
|
2176
|
+
if (isNonEmptyString(nodeRawDataKey)) {
|
|
2177
|
+
treeNode[nodeRawDataKey] = node;
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
if (Array.isArray(node[nodeChildrenKey]) && node[nodeChildrenKey].length > 0) {
|
|
2181
|
+
treeNode[treeChildrenKey] = node[nodeChildrenKey].map((child) => transformNode(child)).filter((child) => child !== null);
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
if (Array.isArray(node[extraChildrenKey]) && node[extraChildrenKey].length > 0) {
|
|
2185
|
+
const isValidExtraDataId2Obj = typeof extraDataId2Obj === "object" && extraDataId2Obj !== null;
|
|
2186
|
+
const extraNodes = [];
|
|
2187
|
+
for (const extraItem of node[extraChildrenKey]) {
|
|
2188
|
+
if (isValidExtraDataId2Obj) {
|
|
2189
|
+
extraDataId2Obj[extraItem[extraIdKey]] = extraItem;
|
|
2190
|
+
}
|
|
2191
|
+
const extraNode = {
|
|
2192
|
+
[treeIdKey]: isNonEmptyString(extraIdPrefix) ? extraIdPrefix + extraItem[extraIdKey] : extraItem[extraIdKey],
|
|
2193
|
+
[treeTitleKey]: extraItem[extraTitleKey],
|
|
2194
|
+
[treeChildrenKey]: [],
|
|
2195
|
+
...extraAssignData
|
|
2196
|
+
};
|
|
2197
|
+
if (isNonEmptyString(extraRawDataKey)) {
|
|
2198
|
+
extraNode[extraRawDataKey] = extraItem;
|
|
2199
|
+
}
|
|
2200
|
+
if (typeof extraDataHandler === "function") {
|
|
2201
|
+
const result = extraDataHandler(extraNode, extraItem, node);
|
|
2202
|
+
if (result?.isAdd === false) continue;
|
|
2203
|
+
}
|
|
2204
|
+
extraNodes.push(extraNode);
|
|
2205
|
+
}
|
|
2206
|
+
treeNode[treeChildrenKey] = [...treeNode[treeChildrenKey], ...extraNodes];
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
if (typeof nodeDataId2Obj === "object" && nodeDataId2Obj !== null) {
|
|
2210
|
+
nodeDataId2Obj[node[nodeIdKey]] = node;
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
if (typeof nodeDataHandler === "function") {
|
|
2214
|
+
const result = nodeDataHandler(treeNode, node);
|
|
2215
|
+
if (result?.isAdd === false) {
|
|
2216
|
+
return null;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
return treeNode;
|
|
2221
|
+
};
|
|
2222
|
+
|
|
2223
|
+
return data.map((item) => transformNode(item)).filter((item) => item !== null);
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* 自定义过滤函数的类型定义。
|
|
2228
|
+
* @callback FilterTreeData_FilterFn
|
|
2229
|
+
* @param {object} node - 当前遍历到的树节点对象。
|
|
2230
|
+
* @param {string | number} filterValue - 当前用于过滤的值。
|
|
2231
|
+
* @param {Array<object>} [children] - 当前节点的子节点数组(原始数据)。
|
|
2232
|
+
* @returns {boolean} 返回 true 表示保留该节点,false 表示过滤掉。
|
|
2233
|
+
*/
|
|
2234
|
+
|
|
2235
|
+
/**
|
|
2236
|
+
* 递归过滤树形数据。
|
|
2237
|
+
*
|
|
2238
|
+
* 该函数会保留符合条件的节点。特别地,**即使当前节点本身不匹配条件,只要其子孙节点中有匹配项,该节点也会被保留**,
|
|
2239
|
+
* 从而保证过滤后的树结构能展示出匹配节点的完整路径。
|
|
2240
|
+
*
|
|
2241
|
+
* @template T
|
|
2242
|
+
* @param {Array<T>} treeData - 源树形数据数组。
|
|
2243
|
+
* @param {string | number} filterValue - 用于过滤的关键字。
|
|
2244
|
+
* @param {string} [filterKey="name"] - 节点对象中用于匹配的字段名。默认为 "name"。如果提供了 filterFn 则此项无效。
|
|
2245
|
+
* @param {string} [childrenKey="children"] - 节点对象中存储子数组的字段名。默认为 "children"。
|
|
2246
|
+
* @param {FilterTreeData_FilterFn} [filterFn] - 自定义过滤函数。如果提供,将忽略 filterKey,使用此函数的返回值判断是否匹配。
|
|
2247
|
+
* @returns {Array<T>} 过滤后的新树形数据数组。注意:返回的是节点对象的浅拷贝。
|
|
2248
|
+
*/
|
|
2249
|
+
function filterTreeData(treeData, filterValue, filterKey = "name", childrenKey = "children", filterFn) {
|
|
2250
|
+
if (!Array.isArray(treeData) || treeData.length === 0) {
|
|
2251
|
+
return [];
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
if (filterValue == null || filterValue === "") {
|
|
2255
|
+
return treeData.map((node) => ({ ...node }));
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
const result = [];
|
|
2259
|
+
|
|
2260
|
+
for (const node of treeData) {
|
|
2261
|
+
const newNode = { ...node };
|
|
2262
|
+
const children = node[childrenKey];
|
|
2263
|
+
|
|
2264
|
+
// 后代节点
|
|
2265
|
+
let isDescendantMatch = false;
|
|
2266
|
+
if (Array.isArray(children)) {
|
|
2267
|
+
const newChildren = filterTreeData(children, filterValue, filterKey, childrenKey, filterFn);
|
|
2268
|
+
newNode[childrenKey] = newChildren;
|
|
2269
|
+
isDescendantMatch = newChildren.length > 0;
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
if (isDescendantMatch) {
|
|
2273
|
+
result.push(newNode);
|
|
2274
|
+
} else {
|
|
2275
|
+
// 当前节点
|
|
2276
|
+
const isMatch = typeof filterFn === "function" ? filterFn(node, filterValue, children) : node[filterKey]?.toString().includes(filterValue);
|
|
2277
|
+
|
|
2278
|
+
if (isMatch) {
|
|
2279
|
+
result.push(newNode);
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
return result;
|
|
2095
2284
|
}
|
|
2096
2285
|
|
|
2097
2286
|
/**
|
|
@@ -2499,5 +2688,5 @@ class WebSocketManager {
|
|
|
2499
2688
|
}
|
|
2500
2689
|
}
|
|
2501
2690
|
|
|
2502
|
-
export { AudioStreamResampler, IntervalTimer, MyEvent, MyEvent_CrossPagePlugin, MyId, WebSocketManager, assignExisting, copyTextToClipboard, debounce, deepCloneByJSON, downloadByBlob, downloadByData, downloadByUrl, downloadExcel, downloadJSON, extractFullyCheckedKeys, fetchOrDownloadByUrl, findObjAttrValueById, findTreeNodeById, findTreeNodePath, flatCompleteTree2NestedTree, formatTimeForLocale, fullscreenHelper, getAllSearchParams, getDataType, getFunctionArgNames, getGUID, getSearchParam, getTimePeriodName, getViewportSize, handleDbMenuItems, isBlob, isDate, isFunction, isNonEmptyString, isPlainObject, isPromise, millisecond2Duration, millisecond2DurationMaxDay, millisecond2DurationMaxHour, moveItem, nestedTree2IdMap, pcmToWavBlob, randomDateInRange, randomEnLetter, randomHan, randomHanOrEn, randomIntInRange, readBlobAsText, second2Duration, second2DurationMaxDay, second2DurationMaxHour, shuffle, throttle, toDate };
|
|
2691
|
+
export { AudioStreamResampler, IntervalTimer, MyEvent, MyEvent_CrossPagePlugin, MyId, WebSocketManager, assignExisting, copyTextToClipboard, debounce, deepCloneByJSON, downloadByBlob, downloadByData, downloadByUrl, downloadExcel, downloadJSON, extractFullyCheckedKeys, fetchOrDownloadByUrl, filterTreeData, findObjAttrValueById, findTreeNodeById, findTreeNodePath, flatCompleteTree2NestedTree, formatTimeForLocale, fullscreenHelper, getAllSearchParams, getDataType, getFunctionArgNames, getGUID, getSearchParam, getTimePeriodName, getViewportSize, handleDbMenuItems, isBlob, isDate, isFunction, isNonEmptyString$1 as isNonEmptyString, isPlainObject, isPromise, millisecond2Duration, millisecond2DurationMaxDay, millisecond2DurationMaxHour, moveItem, nestedTree2IdMap, pcmToWavBlob, randomDateInRange, randomEnLetter, randomHan, randomHanOrEn, randomIntInRange, readBlobAsText, second2Duration, second2DurationMaxDay, second2DurationMaxHour, shuffle, throttle, toDate, transformTreeDataWithExtra };
|
|
2503
2692
|
//# sourceMappingURL=a2bei4.utils.esm.js.map
|