Skip to content

Commit 00e59cc

Browse files
committed
chore: Optimize array flat performance, optimize types.
1 parent d3e7317 commit 00e59cc

File tree

2 files changed

+43
-36
lines changed

2 files changed

+43
-36
lines changed

src/components/TreeNode/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const treeNodePropsPass = {
2424
// Custom formatter for values.
2525
customValueFormatter: Function as PropType<
2626
(
27-
data: string,
27+
data: unknown,
2828
key: NodeDataType['key'],
2929
path: string,
3030
defaultFormatResult: string | JSX.Element,
@@ -54,7 +54,7 @@ export const treeNodePropsPass = {
5454
},
5555
// When using the selectableType, define whether current path/content is enabled.
5656
pathSelectable: {
57-
type: Function as PropType<(path: string, content: string) => boolean>,
57+
type: Function as PropType<(path: string, content: unknown) => boolean>,
5858
default: (): boolean => true,
5959
},
6060
// Highlight current node when selected.
@@ -138,7 +138,7 @@ export default defineComponent({
138138
emit('value-change', value, props.node.path);
139139
};
140140

141-
const defaultFormatter = (data: string) => {
141+
const defaultFormatter = (data: unknown) => {
142142
const str = data + '';
143143
const text = dataType.value === 'string' ? `"${str}"` : str;
144144
if (props.editable && state.editing) {
@@ -161,7 +161,7 @@ export default defineComponent({
161161
};
162162

163163
const customFormatter = props.customValueFormatter
164-
? (data: string) =>
164+
? (data: unknown) =>
165165
props.customValueFormatter?.(
166166
data,
167167
props.node.key,
@@ -276,8 +276,8 @@ export default defineComponent({
276276
{node.key && <span class="vjs-key">{`${state.prettyKey}: `}</span>}
277277

278278
<span>
279-
{node.type !== 'content' ? (
280-
<Brackets data={node.content} onClick={onBracketsClickHandler} />
279+
{node.type !== 'content' && node.content ? (
280+
<Brackets data={node.content.toString()} onClick={onBracketsClickHandler} />
281281
) : customFormatter ? (
282282
<span class={state.valueClass} v-html={customFormatter(node.content)} />
283283
) : (

src/utils/index.ts

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface JSONFlattenOptions {
1616
export type JSONDataType = string | number | boolean | unknown[] | Record<string, unknown> | null;
1717

1818
export interface JSONFlattenReturnType extends JSONFlattenOptions {
19-
content: string;
19+
content: string | number | null | boolean;
2020
level: number;
2121
path: string;
2222
}
@@ -45,17 +45,16 @@ export function jsonFlatten(
4545
const dataType = getDataType(data);
4646

4747
if (dataType === 'array') {
48-
const inner = (data as JSONDataType[])
49-
.map((item, idx, arr) =>
48+
const inner = arrFlat(
49+
(data as JSONDataType[]).map((item, idx, arr) =>
5050
jsonFlatten(item, `${path}[${idx}]`, level + 1, {
5151
index: idx,
5252
showComma: idx !== arr.length - 1,
5353
length,
5454
type,
5555
}),
56-
)
57-
// No flat, for compatibility.
58-
.reduce((acc, val) => acc.concat(val), []);
56+
),
57+
) as JSONFlattenReturnType[];
5958
return [
6059
jsonFlatten('[', path, level, {
6160
showComma: false,
@@ -73,8 +72,8 @@ export function jsonFlatten(
7372
);
7473
} else if (dataType === 'object') {
7574
const keys = Object.keys(data as Record<string, JSONDataType>);
76-
const inner = keys
77-
.map((objKey, idx, arr) =>
75+
const inner = arrFlat(
76+
keys.map((objKey, idx, arr) =>
7877
jsonFlatten(
7978
(data as Record<string, JSONDataType>)[objKey],
8079
objKey.includes('.') ? `${path}["${objKey}"]` : `${path}.${objKey}`,
@@ -86,9 +85,8 @@ export function jsonFlatten(
8685
type,
8786
},
8887
),
89-
)
90-
// No flat, for compatibility.
91-
.reduce((acc, val) => acc.concat(val), []);
88+
),
89+
) as JSONFlattenReturnType[];
9290
return [
9391
jsonFlatten('{', path, level, {
9492
showComma: false,
@@ -103,26 +101,35 @@ export function jsonFlatten(
103101
);
104102
}
105103

106-
const output = Object.entries({
107-
content: data,
108-
level,
109-
key,
110-
index,
111-
path,
112-
showComma,
113-
length,
114-
type,
115-
}).reduce((acc, [key, value]) => {
116-
if (value !== undefined) {
117-
return {
118-
...acc,
119-
[key]: value,
120-
};
121-
}
122-
return acc;
123-
}, {}) as JSONFlattenReturnType;
104+
return [
105+
{
106+
content: data as JSONFlattenReturnType['content'],
107+
level,
108+
key,
109+
index,
110+
path,
111+
showComma,
112+
length,
113+
type,
114+
},
115+
];
116+
}
124117

125-
return [output];
118+
export function arrFlat<T extends unknown[]>(arr: T): unknown[] {
119+
if (typeof Array.prototype.flat === 'function') {
120+
return arr.flat();
121+
}
122+
const stack = [...arr];
123+
const result = [];
124+
while (stack.length) {
125+
const first = stack.shift();
126+
if (Array.isArray(first)) {
127+
stack.unshift(...first);
128+
} else {
129+
result.push(first);
130+
}
131+
}
132+
return result;
126133
}
127134

128135
export function cloneDeep<T extends unknown>(source: T, hash = new WeakMap()): T {

0 commit comments

Comments
 (0)