onchain-utility 0.0.14 → 0.0.16

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 CHANGED
@@ -1,5 +1,265 @@
1
- # `@lexical/utils`
1
+ ## Base
2
+ ### _isMoment
3
+ 判断是否是Moment对象,并且不依赖moment包
2
4
 
3
- [![See API Documentation](https://lexical.dev/img/see-api-documentation.svg)](https://lexical.dev/docs/api/modules/lexical_utils)
5
+ ```ts
6
+ _isMoment({}) // falsesd
7
+ _isMoment(Moment()) // truea
8
+ ```
4
9
 
5
- This package contains misc utilities for Lexical.
10
+ ### makeDestructurable
11
+ 优化返回值结构
12
+ ```ts
13
+ const params = makeDestructurable({
14
+ name: 'AIC',
15
+ age: 16
16
+ }, ['AIC', 16]);
17
+ const { name, age } = params;
18
+ const [name, age] = params;
19
+ ```
20
+
21
+ ### createEnumObject
22
+ 创建一个对象枚举,主要用于解决真正的枚举导出类型和导出前枚举不相等的问题
23
+ ```ts
24
+ createEnumObject({
25
+ SET: 'SET',
26
+ ADD: 'ADD',
27
+ DELETE: 'DELETE',
28
+ CLEAR: 'CLEAR',
29
+ })
30
+ ```
31
+
32
+ ### toRawType
33
+ 接收任意数据,生成对应类型的字符串
34
+ ```ts
35
+ toRawType(() => {}) // 'Function'
36
+ toRawType(new Map) //'Map'
37
+ toRawType({}) // 'Object'
38
+ toRawType([]) // 'Array'
39
+ toRawType(0) // 'Number'
40
+ ```
41
+
42
+ ### hasOwnProperty
43
+ 判断对象是否存在某个属性
44
+ ```ts
45
+ const data = { name: 'aic' };
46
+ hasOwnProperty(data, 'name') // true
47
+ hasOwnProperty(data, 24) // false
48
+ ```
49
+
50
+ ### isEmptyObject
51
+ 是否是空对象
52
+ ```ts
53
+ isEmptyObject({}) // true,
54
+ isEmptyObject({name: 'aic'}) // false
55
+ ```
56
+
57
+ ### getHTMLTagString
58
+ 接收一个对象
59
+ - `type`: `string`;标签名称,例如:`div`或`a`或`span`...,
60
+ - `attributes`: `Record<string, any>`;html标签属性,例如:`{style:'color:#fff;font-size:12px !important;'}`
61
+ - `context`: `string`;标签内容。
62
+
63
+ 返回html字符串
64
+ ```ts
65
+ getHTMLTagString({
66
+ type:"span",
67
+ attributes: {
68
+ style:'color:#fff;font-size:12px !important;'
69
+ },
70
+ context: 'text'
71
+ }) // <span style="color:#fff;font-size:12px !important;">text</span>
72
+ ```
73
+
74
+ ### generateSecureUUID
75
+ 生成UUID
76
+ ```ts
77
+ generateSecureUUID() // 'a6ab72c0-31ab-49bb-a591-54f776c0b2d9'
78
+ ```
79
+
80
+ ## Base64
81
+ ### getBase64Regular
82
+ 生成base64匹配正则
83
+ ```ts
84
+ const regular = getBase64Regular();
85
+ const png = `data:image/png;base64,iVBORwOKGgoAAA
86
+ ANSUhEUgAAALgA...whHJTEQgHn4pg1J8
87
+ 1Av8HEfyAJO5uun8AAAAASUVORK5CYIl=`;
88
+ regular.test(png) // true
89
+ ```
90
+
91
+ ### base64ToMimeType
92
+ 接收base64字符串,返回
93
+ - `mimeType`: `string`;MIME类型;例如:"image/png"
94
+ - `suffix`: `string`;文件格式;例如:"png"
95
+ - `type`: `string`;文件类型;例如:"image"
96
+ ```ts
97
+ const png = `data:image/png;base64,iVBORwOKGgoAAA
98
+ ANSUhEUgAAALgA...whHJTEQgHn4pg1J8
99
+ 1Av8HEfyAJO5uun8AAAAASUVORK5CYIl=`;
100
+ base64ToMimeType(png); // { "mimeType":"image/png", "suffix":"png", "type":"image" }
101
+ ```
102
+
103
+ ### base64ToFile
104
+ 接收对象
105
+ - `text`: `string`;base64字符串
106
+ - `type`: `string | undefined`;文件类型;例如:"image"
107
+ - `filename`: `string | undefined`;自定义文件名称
108
+ - `suffix`: `string | undefined`;文件格式;例如:"png"
109
+
110
+ 返回`File`对象
111
+ ```ts
112
+ const png = `data:image/png;base64,iVBORwOKGgoAAA
113
+ ANSUhEUgAAALgA...whHJTEQgHn4pg1J8
114
+ 1Av8HEfyAJO5uun8AAAAASUVORK5CYIl=`;
115
+ base64ToFile({text: png}) // File {name: 'f37e4949-f912-45f8-abde-109aa8e60a28.undefined', lastModified: 1768899504506, lastModifiedDate: Tue Jan 20 2026 16:58:24 GMT+0800 (中国标准时间), webkitRelativePath: '', size: 9470, …};
116
+ ```
117
+
118
+ ### toBase64UTF8
119
+ 接收任意值返回base64字符串
120
+ ```ts
121
+ const element = document.createElement('equation');
122
+ const equation = toBase64UTF8(this.__equation);
123
+ element.setAttribute('data-lexical-equation', equation);
124
+ ```
125
+
126
+ ### fromBase64UTF8
127
+ 接收base64字符串返回任意值
128
+ ```ts
129
+ const element = document.createElement('equation');
130
+ const equation = toBase64UTF8(this.__equation);
131
+ element.setAttribute('data-lexical-equation', equation);
132
+ ```
133
+
134
+ ## Hooks
135
+ ### reactive
136
+ react响应式数据更新
137
+ #### useReactive
138
+ 无限层次响应式代理, 包含`object`,`array`,`set`,`map`,`WeakMap`,`WeakSet`
139
+ ```tsx
140
+ const Dome = () => {
141
+ const store = useReactive({
142
+ name: 'aic',
143
+ age: 12,
144
+ set: new Set,
145
+ map: new Map,
146
+ list: [{hobby: 'play game'}, {hobby: ''}]
147
+ })
148
+ return <div onClick={() => {
149
+ store.age++ // 更新渲染
150
+ store.list[1].hobby = 'play basketball' // 更新渲染
151
+ }}>
152
+ <span>{store.name}</span>
153
+ {store.list.map(({ hobby }) => <span>{hobby}</span>)}
154
+ </div>
155
+ }
156
+ ```
157
+
158
+ #### useShallowReactive
159
+ 单层对象响应式代理
160
+ ```tsx
161
+ const Dome = () => {
162
+ const store = useShallowReactive({
163
+ name: 'aic',
164
+ age: 12,
165
+ set: new Set,
166
+ map: new Map,
167
+ list: [{hobby: 'play game'}, {hobby: ''}]
168
+ })
169
+ return <div onClick={() => {
170
+ store.age++ // 更新渲染
171
+ store.list[1].hobby = 'play basketball' // 不会触发渲染
172
+ }}>
173
+ <span>{store.name}</span>
174
+ {store.list.map(({ hobby }) => <span>{hobby}</span>)}
175
+ </div>
176
+ }
177
+ ```
178
+
179
+ #### protection
180
+ 在代理的过程中用来保护某些属性不受响应式代理
181
+ ```tsx
182
+ const Dome = () => {
183
+ const store = useReactive({
184
+ name: 'aic',
185
+ age: 12,
186
+ set: new Set,
187
+ map: new Map,
188
+ list: [protection({hobby: 'play game'}), {hobby: ''}]
189
+ })
190
+ return <div onClick={() => {
191
+ store.list[0].hobby = '' // 不会触发渲染
192
+ store.list[1].hobby = 'play basketball' // 更新渲染
193
+ store.set = protection(new Set); // 设置值的时候进行保护
194
+ store.set.add('1') // 不会触发渲染
195
+ }}>
196
+ <span>{store.name}</span>
197
+ {store.list.map(({ hobby }) => <span>{hobby}</span>)}
198
+ </div>
199
+ }
200
+ ```
201
+
202
+ #### toRaw
203
+ 接收一个代理对象,返回这个对象的原始对象,解决某些组件无法使用Proxy后的对象
204
+ ```ts
205
+ const Table = ({list, setHobby}: {list: any[], setHobby: (params: any) => void) => {
206
+ return list.map((item) => <span onClick={(item) => { item.hobby = 'init' }}>{item.hobby}</span>)
207
+ }
208
+
209
+ const Dome = () => {
210
+ const store = useReactive({
211
+ name: 'aic',
212
+ age: 12,
213
+ set: new Set,
214
+ map: new Map,
215
+ list: [{hobby: 'play game'}, {hobby: ''}]
216
+ });
217
+ return <Table list={toRaw(store.list)} setHobby={() => {}} />
218
+ }
219
+ ```
220
+
221
+
222
+ #### toProxy
223
+ 接收一个原始对象,返回这个对象的代理对象,解决转为原始对象后,修改数据无法更新渲染
224
+ ```ts
225
+ const Table = ({list, setHobby}: {list: any[], setHobby: (params: any) => void) => {
226
+ return list.map((item) => <span onClick={() => setHobby(item)}>{item.hobby}</span>)
227
+ }
228
+
229
+ const Dome = () => {
230
+ const store = useReactive({
231
+ name: 'aic',
232
+ age: 12,
233
+ set: new Set,
234
+ map: new Map,
235
+ list: [{hobby: 'play game'}, {hobby: ''}]
236
+ });
237
+ return <Table list={toRaw(store.list)} setHobby={(item) => {
238
+ const hobby = toProxy(item);
239
+ hobby = 'init'
240
+ }} />
241
+ }
242
+ ```
243
+
244
+ ### useStore
245
+ 简单的 react hook 状态管理器
246
+
247
+ ```ts
248
+
249
+ const Dome = () => {
250
+ const { store, setStore, resetStore, latestStore, setSilenceStore } = useStore(() => {
251
+ return {
252
+ name: 'aic',
253
+ age: 12
254
+ }
255
+ });
256
+ useEffect(() => {
257
+ setStore({
258
+ age: 24
259
+ })
260
+ }, []);
261
+ // 使用
262
+ return <div>{store.name}</div>
263
+ }
264
+
265
+ ```
package/dist/Hooks.js CHANGED
@@ -87,6 +87,7 @@ var useUpdate = function () {
87
87
  */
88
88
  /* eslint-disable @typescript-eslint/no-explicit-any */
89
89
 
90
+ /** 是否是Moment对象(_表示为内部函数谨慎使用) */
90
91
  function _isMoment(obj) {
91
92
  return obj != null && typeof obj === 'object' &&
92
93
  // 检查内部标志
@@ -96,6 +97,13 @@ function _isMoment(obj) {
96
97
  // 检查内部属性
97
98
  '_d' in obj && '_i' in obj;
98
99
  }
100
+
101
+ /**
102
+ * 创建一个可解构的对象,该对象同时具有原始对象的属性和数组的迭代器,使其可以使用对象和数组两种解构方式
103
+ * @param obj - 需要转换的对象
104
+ * @param arr - 用于提供迭代器的数组
105
+ * @returns 一个结合了对象属性和数组迭代器的新对象
106
+ */
99
107
  function makeDestructurable(obj, arr) {
100
108
  if (typeof Symbol !== 'undefined') {
101
109
  const clone = {
@@ -118,6 +126,8 @@ function makeDestructurable(obj, arr) {
118
126
  return Object.assign([...arr], obj);
119
127
  }
120
128
  }
129
+
130
+ /** 创建对象枚举,可以避免两个相同枚举缺不相等 */
121
131
  function createEnumObject(o) {
122
132
  return o;
123
133
  }
@@ -128,9 +138,13 @@ function toRawType(value) {
128
138
  // 从字符串中提取“RawType”,如“[object RawType]”
129
139
  return toTypeString(value).slice(8, -1);
130
140
  }
141
+
142
+ /** 判断对象是否有某个属性 */
131
143
  function hasOwnProperty(data, key) {
132
144
  return data && Object.prototype.hasOwnProperty.call(data, key);
133
145
  }
146
+
147
+ /** 是否是整型key */
134
148
  function isIntegerKey(key) {
135
149
  return typeof key === 'string' && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key;
136
150
  }
package/dist/Hooks.mjs CHANGED
@@ -85,6 +85,7 @@ var useUpdate = function () {
85
85
  */
86
86
  /* eslint-disable @typescript-eslint/no-explicit-any */
87
87
 
88
+ /** 是否是Moment对象(_表示为内部函数谨慎使用) */
88
89
  function _isMoment(obj) {
89
90
  return obj != null && typeof obj === 'object' &&
90
91
  // 检查内部标志
@@ -94,6 +95,13 @@ function _isMoment(obj) {
94
95
  // 检查内部属性
95
96
  '_d' in obj && '_i' in obj;
96
97
  }
98
+
99
+ /**
100
+ * 创建一个可解构的对象,该对象同时具有原始对象的属性和数组的迭代器,使其可以使用对象和数组两种解构方式
101
+ * @param obj - 需要转换的对象
102
+ * @param arr - 用于提供迭代器的数组
103
+ * @returns 一个结合了对象属性和数组迭代器的新对象
104
+ */
97
105
  function makeDestructurable(obj, arr) {
98
106
  if (typeof Symbol !== 'undefined') {
99
107
  const clone = {
@@ -116,6 +124,8 @@ function makeDestructurable(obj, arr) {
116
124
  return Object.assign([...arr], obj);
117
125
  }
118
126
  }
127
+
128
+ /** 创建对象枚举,可以避免两个相同枚举缺不相等 */
119
129
  function createEnumObject(o) {
120
130
  return o;
121
131
  }
@@ -126,9 +136,13 @@ function toRawType(value) {
126
136
  // 从字符串中提取“RawType”,如“[object RawType]”
127
137
  return toTypeString(value).slice(8, -1);
128
138
  }
139
+
140
+ /** 判断对象是否有某个属性 */
129
141
  function hasOwnProperty(data, key) {
130
142
  return data && Object.prototype.hasOwnProperty.call(data, key);
131
143
  }
144
+
145
+ /** 是否是整型key */
132
146
  function isIntegerKey(key) {
133
147
  return typeof key === 'string' && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key;
134
148
  }
@@ -19,6 +19,7 @@ var react = require('react');
19
19
  */
20
20
  /* eslint-disable @typescript-eslint/no-explicit-any */
21
21
 
22
+ /** 是否是Moment对象(_表示为内部函数谨慎使用) */
22
23
  function _isMoment(obj) {
23
24
  return obj != null && typeof obj === 'object' &&
24
25
  // 检查内部标志
@@ -28,6 +29,13 @@ function _isMoment(obj) {
28
29
  // 检查内部属性
29
30
  '_d' in obj && '_i' in obj;
30
31
  }
32
+
33
+ /**
34
+ * 创建一个可解构的对象,该对象同时具有原始对象的属性和数组的迭代器,使其可以使用对象和数组两种解构方式
35
+ * @param obj - 需要转换的对象
36
+ * @param arr - 用于提供迭代器的数组
37
+ * @returns 一个结合了对象属性和数组迭代器的新对象
38
+ */
31
39
  function makeDestructurable(obj, arr) {
32
40
  if (typeof Symbol !== 'undefined') {
33
41
  const clone = {
@@ -50,6 +58,8 @@ function makeDestructurable(obj, arr) {
50
58
  return Object.assign([...arr], obj);
51
59
  }
52
60
  }
61
+
62
+ /** 创建对象枚举,可以避免两个相同枚举缺不相等 */
53
63
  function createEnumObject(o) {
54
64
  return o;
55
65
  }
@@ -60,15 +70,68 @@ function toRawType(value) {
60
70
  // 从字符串中提取“RawType”,如“[object RawType]”
61
71
  return toTypeString(value).slice(8, -1);
62
72
  }
73
+ function isString(value) {
74
+ return toRawType(value) === 'String';
75
+ }
76
+ function isNumber(value) {
77
+ return toRawType(value) === 'Number';
78
+ }
79
+
80
+ /** 判断值是否为NaN */
81
+ function isNaN(value) {
82
+ return Number.isNaN(value);
83
+ }
84
+ function isBoolean(value) {
85
+ return toRawType(value) === 'Boolean';
86
+ }
87
+ function isUndefined(value) {
88
+ return toRawType(value) === 'Undefined';
89
+ }
90
+ function isNull(value) {
91
+ return toRawType(value) === 'Null';
92
+ }
93
+ function isNil(value) {
94
+ return isNull(value) || isUndefined(value);
95
+ }
96
+
97
+ /**
98
+ * 判断是否是 `null` 或 `undefined`
99
+ * @example
100
+ * _.isNil(null);
101
+ * // => true
102
+ *
103
+ * _.isNil(void 0);
104
+ * // => true
105
+ *
106
+ * _.isNil(NaN);
107
+ * // => false
108
+ */
109
+ function isObject(value) {
110
+ return toRawType(value) === 'Object';
111
+ }
112
+ function isArray(value) {
113
+ return toRawType(value) === 'Array';
114
+ }
115
+ function isFunction(value) {
116
+ return toRawType(value) === 'Function';
117
+ }
118
+
119
+ /** 判断对象是否有某个属性 */
63
120
  function hasOwnProperty(data, key) {
64
121
  return data && Object.prototype.hasOwnProperty.call(data, key);
65
122
  }
123
+
124
+ /** 是否是整型key */
66
125
  function isIntegerKey(key) {
67
126
  return typeof key === 'string' && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key;
68
127
  }
128
+
129
+ /** 是否是空对象 */
69
130
  function isEmptyObject(obj) {
70
131
  return obj ? !Object.keys(obj).length : true;
71
132
  }
133
+
134
+ /** 生成 innerHTML */
72
135
  function getHTMLTagString(params) {
73
136
  const attrsString = Object.entries(params.attributes || {}).map(([key, value]) => {
74
137
  return ` ${key}="${value}"`;
@@ -1353,9 +1416,10 @@ function generatedAcrossHierarchySort({
1353
1416
  function optimizeStructure({
1354
1417
  data,
1355
1418
  childrenKey = 'children',
1356
- signKey = 'id'
1419
+ signKey = 'id',
1420
+ isSupportMultipleRoot = false
1357
1421
  }) {
1358
- if (data.length > 1) {
1422
+ if (data.length > 1 || isSupportMultipleRoot) {
1359
1423
  return [{
1360
1424
  [childrenKey]: data,
1361
1425
  isCustom: true,
@@ -1460,6 +1524,7 @@ async function upgrade({
1460
1524
  data,
1461
1525
  signKey = 'id',
1462
1526
  isFollow,
1527
+ isSupportMultipleRoot = false,
1463
1528
  onStopFollow,
1464
1529
  onFilterFollow,
1465
1530
  onUpgrade,
@@ -1471,6 +1536,7 @@ async function upgrade({
1471
1536
  data = optimizeStructure({
1472
1537
  childrenKey,
1473
1538
  data,
1539
+ isSupportMultipleRoot,
1474
1540
  signKey
1475
1541
  });
1476
1542
  const layers = mergeAdjacent({
@@ -1694,8 +1760,18 @@ exports.getTreeRelation = getTreeRelation;
1694
1760
  exports.hasOwnProperty = hasOwnProperty;
1695
1761
  exports.initTranslateI18nFn = initTranslateI18nFn;
1696
1762
  exports.insert = insert;
1763
+ exports.isArray = isArray;
1764
+ exports.isBoolean = isBoolean;
1697
1765
  exports.isEmptyObject = isEmptyObject;
1766
+ exports.isFunction = isFunction;
1698
1767
  exports.isIntegerKey = isIntegerKey;
1768
+ exports.isNaN = isNaN;
1769
+ exports.isNil = isNil;
1770
+ exports.isNull = isNull;
1771
+ exports.isNumber = isNumber;
1772
+ exports.isObject = isObject;
1773
+ exports.isString = isString;
1774
+ exports.isUndefined = isUndefined;
1699
1775
  exports.levelTransformTree = levelTransformTree;
1700
1776
  exports.makeDestructurable = makeDestructurable;
1701
1777
  exports.mergeAdjacent = mergeAdjacent;
@@ -17,6 +17,7 @@ import { useRef, useState, useCallback, useLayoutEffect } from 'react';
17
17
  */
18
18
  /* eslint-disable @typescript-eslint/no-explicit-any */
19
19
 
20
+ /** 是否是Moment对象(_表示为内部函数谨慎使用) */
20
21
  function _isMoment(obj) {
21
22
  return obj != null && typeof obj === 'object' &&
22
23
  // 检查内部标志
@@ -26,6 +27,13 @@ function _isMoment(obj) {
26
27
  // 检查内部属性
27
28
  '_d' in obj && '_i' in obj;
28
29
  }
30
+
31
+ /**
32
+ * 创建一个可解构的对象,该对象同时具有原始对象的属性和数组的迭代器,使其可以使用对象和数组两种解构方式
33
+ * @param obj - 需要转换的对象
34
+ * @param arr - 用于提供迭代器的数组
35
+ * @returns 一个结合了对象属性和数组迭代器的新对象
36
+ */
29
37
  function makeDestructurable(obj, arr) {
30
38
  if (typeof Symbol !== 'undefined') {
31
39
  const clone = {
@@ -48,6 +56,8 @@ function makeDestructurable(obj, arr) {
48
56
  return Object.assign([...arr], obj);
49
57
  }
50
58
  }
59
+
60
+ /** 创建对象枚举,可以避免两个相同枚举缺不相等 */
51
61
  function createEnumObject(o) {
52
62
  return o;
53
63
  }
@@ -58,15 +68,68 @@ function toRawType(value) {
58
68
  // 从字符串中提取“RawType”,如“[object RawType]”
59
69
  return toTypeString(value).slice(8, -1);
60
70
  }
71
+ function isString(value) {
72
+ return toRawType(value) === 'String';
73
+ }
74
+ function isNumber(value) {
75
+ return toRawType(value) === 'Number';
76
+ }
77
+
78
+ /** 判断值是否为NaN */
79
+ function isNaN(value) {
80
+ return Number.isNaN(value);
81
+ }
82
+ function isBoolean(value) {
83
+ return toRawType(value) === 'Boolean';
84
+ }
85
+ function isUndefined(value) {
86
+ return toRawType(value) === 'Undefined';
87
+ }
88
+ function isNull(value) {
89
+ return toRawType(value) === 'Null';
90
+ }
91
+ function isNil(value) {
92
+ return isNull(value) || isUndefined(value);
93
+ }
94
+
95
+ /**
96
+ * 判断是否是 `null` 或 `undefined`
97
+ * @example
98
+ * _.isNil(null);
99
+ * // => true
100
+ *
101
+ * _.isNil(void 0);
102
+ * // => true
103
+ *
104
+ * _.isNil(NaN);
105
+ * // => false
106
+ */
107
+ function isObject(value) {
108
+ return toRawType(value) === 'Object';
109
+ }
110
+ function isArray(value) {
111
+ return toRawType(value) === 'Array';
112
+ }
113
+ function isFunction(value) {
114
+ return toRawType(value) === 'Function';
115
+ }
116
+
117
+ /** 判断对象是否有某个属性 */
61
118
  function hasOwnProperty(data, key) {
62
119
  return data && Object.prototype.hasOwnProperty.call(data, key);
63
120
  }
121
+
122
+ /** 是否是整型key */
64
123
  function isIntegerKey(key) {
65
124
  return typeof key === 'string' && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key;
66
125
  }
126
+
127
+ /** 是否是空对象 */
67
128
  function isEmptyObject(obj) {
68
129
  return obj ? !Object.keys(obj).length : true;
69
130
  }
131
+
132
+ /** 生成 innerHTML */
70
133
  function getHTMLTagString(params) {
71
134
  const attrsString = Object.entries(params.attributes || {}).map(([key, value]) => {
72
135
  return ` ${key}="${value}"`;
@@ -1351,9 +1414,10 @@ function generatedAcrossHierarchySort({
1351
1414
  function optimizeStructure({
1352
1415
  data,
1353
1416
  childrenKey = 'children',
1354
- signKey = 'id'
1417
+ signKey = 'id',
1418
+ isSupportMultipleRoot = false
1355
1419
  }) {
1356
- if (data.length > 1) {
1420
+ if (data.length > 1 || isSupportMultipleRoot) {
1357
1421
  return [{
1358
1422
  [childrenKey]: data,
1359
1423
  isCustom: true,
@@ -1458,6 +1522,7 @@ async function upgrade({
1458
1522
  data,
1459
1523
  signKey = 'id',
1460
1524
  isFollow,
1525
+ isSupportMultipleRoot = false,
1461
1526
  onStopFollow,
1462
1527
  onFilterFollow,
1463
1528
  onUpgrade,
@@ -1469,6 +1534,7 @@ async function upgrade({
1469
1534
  data = optimizeStructure({
1470
1535
  childrenKey,
1471
1536
  data,
1537
+ isSupportMultipleRoot,
1472
1538
  signKey
1473
1539
  });
1474
1540
  const layers = mergeAdjacent({
@@ -1670,4 +1736,4 @@ function treeSearch({
1670
1736
  }).filter(row => !!row);
1671
1737
  }
1672
1738
 
1673
- export { _isMoment, arrayAttributeFlat, asyncDfs, base64ToFile, base64ToMimeType, baseTemplate, bfs, createEnumObject, deleteTreeNodes, dfs, downgrade, fromBase64UTF8, generateSecureUUID, generatedAcrossHierarchySort, getBase64Regular, getHTMLTagString, getI18nText, getSiblings, getTreeRelation, hasOwnProperty, initTranslateI18nFn, insert, isEmptyObject, isIntegerKey, levelTransformTree, makeDestructurable, mergeAdjacent, movUp, move, moveDown, t, toBase64UTF8, toRawType, toTypeString, translateI18n, treeSearch, upgrade, useReactive, useShallowReactive, useStore };
1739
+ export { _isMoment, arrayAttributeFlat, asyncDfs, base64ToFile, base64ToMimeType, baseTemplate, bfs, createEnumObject, deleteTreeNodes, dfs, downgrade, fromBase64UTF8, generateSecureUUID, generatedAcrossHierarchySort, getBase64Regular, getHTMLTagString, getI18nText, getSiblings, getTreeRelation, hasOwnProperty, initTranslateI18nFn, insert, isArray, isBoolean, isEmptyObject, isFunction, isIntegerKey, isNaN, isNil, isNull, isNumber, isObject, isString, isUndefined, levelTransformTree, makeDestructurable, mergeAdjacent, movUp, move, moveDown, t, toBase64UTF8, toRawType, toTypeString, translateI18n, treeSearch, upgrade, useReactive, useShallowReactive, useStore };
package/dist/Tree.js CHANGED
@@ -332,9 +332,10 @@ function generatedAcrossHierarchySort({
332
332
  function optimizeStructure({
333
333
  data,
334
334
  childrenKey = 'children',
335
- signKey = 'id'
335
+ signKey = 'id',
336
+ isSupportMultipleRoot = false
336
337
  }) {
337
- if (data.length > 1) {
338
+ if (data.length > 1 || isSupportMultipleRoot) {
338
339
  return [{
339
340
  [childrenKey]: data,
340
341
  isCustom: true,
@@ -439,6 +440,7 @@ async function upgrade({
439
440
  data,
440
441
  signKey = 'id',
441
442
  isFollow,
443
+ isSupportMultipleRoot = false,
442
444
  onStopFollow,
443
445
  onFilterFollow,
444
446
  onUpgrade,
@@ -450,6 +452,7 @@ async function upgrade({
450
452
  data = optimizeStructure({
451
453
  childrenKey,
452
454
  data,
455
+ isSupportMultipleRoot,
453
456
  signKey
454
457
  });
455
458
  const layers = mergeAdjacent({
package/dist/Tree.mjs CHANGED
@@ -330,9 +330,10 @@ function generatedAcrossHierarchySort({
330
330
  function optimizeStructure({
331
331
  data,
332
332
  childrenKey = 'children',
333
- signKey = 'id'
333
+ signKey = 'id',
334
+ isSupportMultipleRoot = false
334
335
  }) {
335
- if (data.length > 1) {
336
+ if (data.length > 1 || isSupportMultipleRoot) {
336
337
  return [{
337
338
  [childrenKey]: data,
338
339
  isCustom: true,
@@ -437,6 +438,7 @@ async function upgrade({
437
438
  data,
438
439
  signKey = 'id',
439
440
  isFollow,
441
+ isSupportMultipleRoot = false,
440
442
  onStopFollow,
441
443
  onFilterFollow,
442
444
  onUpgrade,
@@ -448,6 +450,7 @@ async function upgrade({
448
450
  data = optimizeStructure({
449
451
  childrenKey,
450
452
  data,
453
+ isSupportMultipleRoot,
451
454
  signKey
452
455
  });
453
456
  const layers = mergeAdjacent({
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "onchain-utility",
3
3
  "description": "This package contains misc utilities for onchain.",
4
4
  "license": "MIT",
5
- "version": "0.0.14",
5
+ "version": "0.0.16",
6
6
  "files": [
7
7
  "dist",
8
8
  "src"
package/src/Tree/index.ts CHANGED
@@ -399,8 +399,9 @@ function optimizeStructure<T>({
399
399
  data,
400
400
  childrenKey = 'children',
401
401
  signKey = 'id',
402
- }: Params<T>): T[] {
403
- if (data.length > 1) {
402
+ isSupportMultipleRoot = false,
403
+ }: Params<T> & {isSupportMultipleRoot?: boolean}): T[] {
404
+ if (data.length > 1 || isSupportMultipleRoot) {
404
405
  return [
405
406
  {
406
407
  [childrenKey]: data,
@@ -512,6 +513,7 @@ export async function upgrade<T extends Item>({
512
513
  data,
513
514
  signKey = 'id',
514
515
  isFollow,
516
+ isSupportMultipleRoot = false,
515
517
  onStopFollow,
516
518
  onFilterFollow,
517
519
  onUpgrade,
@@ -521,6 +523,7 @@ export async function upgrade<T extends Item>({
521
523
  onError,
522
524
  }: MoveParams<T> & {
523
525
  isFollow?: boolean;
526
+ isSupportMultipleRoot?: boolean;
524
527
  onStopFollow?: (item: T) => boolean;
525
528
  onFilterFollow?: (item: T[]) => T[];
526
529
  onUpgrade?: (params: {
@@ -530,7 +533,7 @@ export async function upgrade<T extends Item>({
530
533
  }) => Promise<boolean> | boolean;
531
534
  onUpgraded?: (upgrades: T[]) => void;
532
535
  }) {
533
- data = optimizeStructure({childrenKey, data, signKey});
536
+ data = optimizeStructure({childrenKey, data, isSupportMultipleRoot, signKey});
534
537
  const layers = mergeAdjacent({childrenKey, data, selectKeys, signKey});
535
538
  const {crossLayerSort, getInsertIdx} = generatedAcrossHierarchySort({
536
539
  signKey,
package/src/base.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  */
8
8
  /* eslint-disable @typescript-eslint/no-explicit-any */
9
9
 
10
+ /** 是否是Moment对象(_表示为内部函数谨慎使用) */
10
11
  export function _isMoment(obj: any) {
11
12
  return (
12
13
  obj != null &&
@@ -22,6 +23,12 @@ export function _isMoment(obj: any) {
22
23
  );
23
24
  }
24
25
 
26
+ /**
27
+ * 创建一个可解构的对象,该对象同时具有原始对象的属性和数组的迭代器,使其可以使用对象和数组两种解构方式
28
+ * @param obj - 需要转换的对象
29
+ * @param arr - 用于提供迭代器的数组
30
+ * @returns 一个结合了对象属性和数组迭代器的新对象
31
+ */
25
32
  export function makeDestructurable<
26
33
  T extends Record<string, unknown>,
27
34
  A extends readonly [any, ...any],
@@ -47,6 +54,7 @@ export function makeDestructurable<
47
54
  }
48
55
  }
49
56
 
57
+ /** 创建对象枚举,可以避免两个相同枚举缺不相等 */
50
58
  export function createEnumObject<T extends string>(o: {[P in T]: P}) {
51
59
  return o;
52
60
  }
@@ -54,14 +62,71 @@ export function createEnumObject<T extends string>(o: {[P in T]: P}) {
54
62
  export function toTypeString<T>(value: T): string {
55
63
  return Object.prototype.toString.call(value);
56
64
  }
65
+
57
66
  export function toRawType<T>(value: T): string {
58
67
  // 从字符串中提取“RawType”,如“[object RawType]”
59
68
  return toTypeString(value).slice(8, -1);
60
69
  }
70
+
71
+ export function isString(value: any): value is string {
72
+ return toRawType(value) === 'String';
73
+ }
74
+
75
+ export function isNumber(value: any): value is number {
76
+ return toRawType(value) === 'Number';
77
+ }
78
+
79
+ /** 判断值是否为NaN */
80
+ export function isNaN(value?: any): value is number {
81
+ return Number.isNaN(value);
82
+ }
83
+
84
+ export function isBoolean(value?: any): value is boolean {
85
+ return toRawType(value) === 'Boolean';
86
+ }
87
+
88
+ export function isUndefined(value?: any): value is undefined {
89
+ return toRawType(value) === 'Undefined';
90
+ }
91
+
92
+ export function isNull(value?: any): value is null {
93
+ return toRawType(value) === 'Null';
94
+ }
95
+
96
+ export function isNil(value?: any): value is null | undefined {
97
+ return isNull(value) || isUndefined(value);
98
+ }
99
+
100
+ /**
101
+ * 判断是否是 `null` 或 `undefined`
102
+ * @example
103
+ * _.isNil(null);
104
+ * // => true
105
+ *
106
+ * _.isNil(void 0);
107
+ * // => true
108
+ *
109
+ * _.isNil(NaN);
110
+ * // => false
111
+ */
112
+ export function isObject(value?: any): value is object {
113
+ return toRawType(value) === 'Object';
114
+ }
115
+
116
+ export function isArray(value?: unknown): value is unknown[] {
117
+ return toRawType(value) === 'Array';
118
+ }
119
+
120
+ export function isFunction(value?: any): value is (...args: any[]) => any {
121
+ return toRawType(value) === 'Function';
122
+ }
123
+
124
+ /** 判断对象是否有某个属性 */
61
125
  export function hasOwnProperty<T>(data: T, key: string | symbol | number) {
62
126
  return data && Object.prototype.hasOwnProperty.call(data, key);
63
127
  }
64
128
 
129
+ /** 是否是整型key */
65
130
  export function isIntegerKey(key: unknown) {
66
131
  return (
67
132
  typeof key === 'string' &&
@@ -70,10 +135,13 @@ export function isIntegerKey(key: unknown) {
70
135
  '' + parseInt(key, 10) === key
71
136
  );
72
137
  }
138
+
139
+ /** 是否是空对象 */
73
140
  export function isEmptyObject(obj: object | undefined | null) {
74
141
  return obj ? !Object.keys(obj).length : true;
75
142
  }
76
143
 
144
+ /** 生成 innerHTML */
77
145
  export function getHTMLTagString(params: {
78
146
  type: string;
79
147
  attributes?: Record<string, any>;