mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-28 20:43:56 +03:00
b323f77d31
* Update packages * Fix after update * Update some types * Remove attr * Finish d3tooltip * Update style option * Updates * Zoom * Update * Update * Update * Fix * Update * Update * Update * Update * Update * Fixes * Update id type * Fix enter + update selections * Use this * Fix stringifying * Remove InputOptions * Use data.value * Updates * Remove UMD builds * Fix exit * No need to re-assign * Simplify d3tooltip API * Update redux-devtools-chart-monitor * Update redux-devtools-app * Update * Update * Remove @types/prop-types * Update prop types * Update d3tooltip docs * Update d3-state-visualizer docs * Update chart-monitor docs * Create weak-kings-brake.md * Create spicy-olives-compete.md * Create friendly-coats-trade.md * Create slimy-elephants-flash.md * Fix empty arrays
102 lines
2.5 KiB
TypeScript
102 lines
2.5 KiB
TypeScript
import isArray from 'lodash/isArray';
|
|
import isPlainObject from 'lodash/isPlainObject';
|
|
import mapValues from 'lodash/mapValues';
|
|
|
|
export interface Node {
|
|
name: string;
|
|
children?: this[];
|
|
object?: unknown;
|
|
value?: unknown;
|
|
}
|
|
|
|
function visit(
|
|
parent: Node,
|
|
visitFn: (parent: Node) => void,
|
|
childrenFn: (parent: Node) => Node[] | undefined | null
|
|
) {
|
|
if (!parent) return;
|
|
|
|
visitFn(parent);
|
|
|
|
const children = childrenFn(parent);
|
|
if (children) {
|
|
const count = children.length;
|
|
for (let i = 0; i < count; i++) {
|
|
visit(children[i], visitFn, childrenFn);
|
|
}
|
|
}
|
|
}
|
|
|
|
function getNode(tree: Node, key: string): Node | null {
|
|
let node = null;
|
|
|
|
visit(
|
|
tree,
|
|
(d) => {
|
|
if (d.name === key) {
|
|
node = d;
|
|
}
|
|
},
|
|
(d) => d.children
|
|
);
|
|
|
|
return node;
|
|
}
|
|
|
|
export function map2tree(
|
|
root: unknown,
|
|
options: { key?: string; pushMethod?: 'push' | 'unshift' } = {},
|
|
tree: Node = { name: options.key || 'state', children: [] }
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
): Node | {} {
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
if (!isPlainObject(root) && root && !(root as { toJS: () => {} }).toJS) {
|
|
return {};
|
|
}
|
|
|
|
const { key: rootNodeKey = 'state', pushMethod = 'push' } = options;
|
|
const currentNode = getNode(tree, rootNodeKey);
|
|
|
|
if (currentNode === null) {
|
|
return {};
|
|
}
|
|
|
|
mapValues(
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
root && (root as { toJS: () => {} }).toJS
|
|
? // eslint-disable-next-line @typescript-eslint/ban-types
|
|
(root as { toJS: () => {} }).toJS()
|
|
: // eslint-disable-next-line @typescript-eslint/ban-types
|
|
(root as {}),
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
(maybeImmutable: { toJS?: () => {} }, key) => {
|
|
const value =
|
|
maybeImmutable && maybeImmutable.toJS
|
|
? maybeImmutable.toJS()
|
|
: maybeImmutable;
|
|
const newNode: Node = { name: key };
|
|
|
|
if (isArray(value)) {
|
|
newNode.children = [];
|
|
|
|
for (let i = 0; i < value.length; i++) {
|
|
newNode.children[pushMethod]({
|
|
name: `${key}[${i}]`,
|
|
[isPlainObject(value[i]) ? 'object' : 'value']: value[i],
|
|
});
|
|
}
|
|
} else if (isPlainObject(value)) {
|
|
newNode.children = [];
|
|
} else {
|
|
newNode.value = value;
|
|
}
|
|
|
|
currentNode.children![pushMethod](newNode);
|
|
|
|
map2tree(value, { key, pushMethod }, tree);
|
|
}
|
|
);
|
|
|
|
return tree;
|
|
}
|