redux-devtools/packages/map2tree/src/index.ts
Nathan Bierema b82de74592
Add ESM builds (#997)
* Use rollup for d3tooltip

* Use rollup for map2tree

* Set moduleResolution

* Use rollup for d3-state-visualizer

* Use rollup for react-base16-styling

* Use rollup for react-dock

* Use rollup for react-json-tree

* Use rollup for redux-devtools

* Use rollup for redux-devtools-intrument

* Use rollup for redux-devtools-chart-monitor

* Update export

* Use rollup for redux-devtools-dock-monitor

* Use rollup for redux-devtools-inspector-monitor

* Fix inspector demo

* Fix invalid eslint config

* Use rollup for inspector-monitor-test-tab

* Use rollup for inspector-monitor-trace-tab

* Use rollup for redux-devtools-log-monitor

* Use rollup for redux-devtools-remote

* Use rollup in redux-devtools-rtk-query-monitor

* Use rollup for redux-devtools-serialize

* Fix redux-devtools examples

* Use rollup for redux-devtools-slider-monitor

* Fix slider examples

* Use rollup for redux-devtools-ui

* Use rollup for redux-devtools-utils

* Use rollup for redux-devtools-extension

* Use rollup for redux-devtools-app

* Fix Webpack app build

* Fix extension build

* Turn on minimization

* Update CLI
2022-01-10 15:41:53 +00:00

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?: Node[] | null;
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(
// eslint-disable-next-line @typescript-eslint/ban-types
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;
}