Skip to content
This repository has been archived by the owner on Jun 5, 2020. It is now read-only.

Commit

Permalink
fix previews for Maps/Sets
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkuz committed Mar 5, 2017
1 parent d41dc96 commit 9dfaaab
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 134 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
},
"env": {
"browser": true,
"node": true
"node": true,
"es6": true
}
}
14 changes: 0 additions & 14 deletions demo/dist/index.html

This file was deleted.

65 changes: 0 additions & 65 deletions demo/dist/js/bundle.js

This file was deleted.

4 changes: 4 additions & 0 deletions demo/src/js/DemoApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ class DemoApp extends React.Component {
<Button onClick={this.props.addRecursive} style={styles.button}>
Add Recursive
</Button>
<Button onClick={this.props.addNativeMap} style={styles.button}>
Add Native Map
</Button>
<Button onClick={this.props.addImmutableMap} style={styles.button}>
Add Immutable Map
</Button>
Expand Down Expand Up @@ -230,6 +233,7 @@ export default connect(
addIterator: () => ({ type: 'ADD_ITERATOR' }),
addHugeObect: () => ({ type: 'ADD_HUGE_OBJECT' }),
addRecursive: () => ({ type: 'ADD_RECURSIVE' }),
addNativeMap: () => ({ type: 'ADD_NATIVE_MAP' }),
addImmutableMap: () => ({ type: 'ADD_IMMUTABLE_MAP' }),
changeImmutableNested: () => ({ type: 'CHANGE_IMMUTABLE_NESTED' }),
hugePayload: () => ({
Expand Down
46 changes: 33 additions & 13 deletions demo/src/js/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ const IMMUTABLE_MAP = Immutable.Map({
seq: Immutable.Seq.of(1, 2, 3, 4, 5, 6, 7, 8)
});

const NATIVE_MAP = new window.Map([
['map', new window.Map([
[{ first: true }, 1],
['second', 2]
])],
['weakMap', new window.WeakMap([
[{ first: true }, 1],
[{ second: 1 }, 2]
])],
['set', new window.Set([
{ first: true },
'second'
])],
['weakSet', new window.WeakSet([
{ first: true },
{ second: 1 }
])]
]);

/* eslint-enable babel/new-cap */

const HUGE_ARRAY = Array.from({ length: 5000 })
Expand Down Expand Up @@ -71,23 +90,24 @@ export default {
iterators: (state=[], action) => action.type === 'ADD_ITERATOR' ?
[...state, createIterator()] : state,
nested: (state=NESTED, action) =>
action.type === 'CHANGE_NESTED' ?
{
...state,
long: {
nested: [{
path: {
to: {
a: state.long.nested[0].path.to.a + '!'
}
action.type === 'CHANGE_NESTED' ? {
...state,
long: {
nested: [{
path: {
to: {
a: state.long.nested[0].path.to.a + '!'
}
}]
}
} : state,
}
}]
}
} : state,
recursive: (state=[], action) => action.type === 'ADD_RECURSIVE' ?
[...state, { ...RECURSIVE }] : state,
immutables: (state=[], action) => action.type === 'ADD_IMMUTABLE_MAP' ?
[...state, IMMUTABLE_MAP] : state,
maps: (state=[], action) => action.type === 'ADD_NATIVE_MAP' ?
[...state, NATIVE_MAP] : state,
immutableNested: (state=IMMUTABLE_NESTED, action) => action.type === 'CHANGE_IMMUTABLE_NESTED' ?
state.updateIn(
['long', 'nested', 0, 'path', 'to', 'a'],
Expand All @@ -96,7 +116,7 @@ export default {
addFunction: (state=null, action) => action.type === 'ADD_FUNCTION' ?
{ f: FUNC } : state,
addSymbol: (state=null, action) => action.type === 'ADD_SYMBOL' ?
{ s: window.Symbol('symbol') } : state,
{ s: window.Symbol('symbol'), error: new Error('TEST') } : state,
shuffleArray: (state=DEFAULT_SHUFFLE_ARRAY, action) =>
action.type === 'SHUFFLE_ARRAY' ?
shuffle(state) : state
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
"stats": "webpack --profile --json > stats.json",
"start": "webpack-dev-server",
"lint": "eslint --ext .jsx,.js --max-warnings 0 src",
"preversion": "npm run lint & npm run flow",
"version": "npm run build:demo && git add -A .",
"preversion": "npm -s run lint & npm -s run flow",
"version": "npm -s run build:demo && git add -A .",
"postversion": "git push",
"prepublish": "npm run build:lib",
"gh": "git-directory-deploy --directory demo/dist --branch gh-pages",
"flow": "flow",
"test": "npm run lint && npm run flow"
"test": "npm -s run lint && npm -s run flow"
},
"main": "lib/index.js",
"repository": {
Expand Down Expand Up @@ -90,7 +90,7 @@
"jss-vendor-prefixer": "^4.0.0",
"lodash.debounce": "^4.0.3",
"react-base16-styling": "^0.4.1",
"react-json-tree": "^0.10.0",
"react-json-tree": "^0.10.5",
"redux-devtools-themes": "^1.0.0"
},
"pre-commit": [
Expand Down
4 changes: 2 additions & 2 deletions src/DevtoolsInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ export default class DevtoolsInspector extends PureComponent<DefaultProps, Props

componentDidMount() {
this.updateSizeMode();
this.updateSizeTimeout = window.setInterval(this.updateSizeMode.bind(this), 150);
this.updateSizeTimeout = setInterval(this.updateSizeMode.bind(this), 150);
}

componentWillUnmount() {
window.clearTimeout(this.updateSizeTimeout);
clearTimeout(this.updateSizeTimeout);
}

updateMonitorState(monitorState: MonitorState) {
Expand Down
109 changes: 85 additions & 24 deletions src/tabs/getItemString.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,126 @@
// @flow
import React from 'react';
import { Iterable } from 'immutable';
import isIterable from '../utils/isIterable';
import getType from '../utils/getType';

import type { StylingFunction } from 'react-base16-styling';

const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
function getShortTypeString(val: any, diff?: boolean): string {
const type = getType(val);

function isImmutable(value): boolean {
return Iterable.isKeyed(value) || Iterable.isIndexed(value) || Iterable.isIterable(value);
}

function getShortTypeString(val, diff): string {
if (diff && Array.isArray(val)) {
val = val[val.length === 2 ? 1 : 0];
}

if (isIterable(val) && !isImmutable(val)) {
switch (type) {
case 'Immutable List':
case 'Immutable Stack':
case 'Immutable Seq':
return '<I>' + val.size ? '[…]' : '[]';
case 'Map':
return val.size ? '{…}' : '{}';
case 'WeakMap':
return '{…}';
case 'Set':
return val.size ? '(…)' : '()';
case 'WeakSet':
return '(…)';
case 'Immutable Map':
case 'Immutable OrderedMap':
return '<I>' + val.size ? '{…}' : '{}';
case 'Immutable Set':
case 'Immutable OrderedSet':
return '<I>' + val.size ? '(…)' : '()';
case 'Iterable':
return '(…)';
} else if (Array.isArray(val)) {
case 'Array':
return val.length > 0 ? '[…]' : '[]';
} else if (val === null) {
case 'Null':
return 'null';
} else if (val === undefined) {
case 'Undefined':
return 'undef';
} else if (typeof val === 'object') {
case 'Error':
return `Error(${getShortTypeString(val.message)}`;
case 'Object':
return Object.keys(val).length > 0 ? '{…}' : '{}';
} else if (typeof val === 'function') {
case 'Function':
return 'fn';
} else if (typeof val === 'string') {
case 'String':
return `"${val.substr(0, 10) + (val.length > 10 ? '…' : '')}"`
} else if ((typeof val: any) === 'symbol') {
case 'Symbol':
return 'symbol';
} else {
return val;
default:
return val.toString();
}
}

function getFirstEntries(data, limit, getEntryString): string {
let idx = 0, arr = [];

for (let entry of data) {
if (idx === 3) {
arr.push('…');
break;
};
arr.push(getEntryString(entry));
idx++;
}

return arr.join(', ');
}

function getText(type, data, isWideLayout, isDiff): string {
if (type === 'Object') {
let str;
type = getType(data);

switch(type) {
case 'Immutable List':
case 'Immutable Stack':
case 'Immutable Seq':
str = getFirstEntries(data, 3, entry => getShortTypeString(entry));
return `<I>[ ${str} ]`;
case 'Map':
str = getFirstEntries(data, 3, entry =>
`${getShortTypeString(entry[0])} => ${getShortTypeString(entry[1])}`
);
return `{ ${str} }`;
case 'WeakMap':
return '{…}';
case 'Set':
str = getFirstEntries(data, 3, entry => getShortTypeString(entry));
return `( ${str} )`;
case 'WeakSet':
return '(…)';
case 'Immutable Map':
case 'Immutable OrderedMap':
str = getFirstEntries(data, 3, entry =>
`${getShortTypeString(entry[0])} => ${getShortTypeString(entry[1])}`
);
return `<I>{ ${str} }`;
case 'Immutable Set':
case 'Immutable OrderedSet':
str = getFirstEntries(data, 3, entry => getShortTypeString(entry));
return `<I>( ${str} )`;
case 'Object':
const keys = Object.keys(data);
if (!isWideLayout) return keys.length ? '{…}' : '{}';

const str = keys
str = keys
.slice(0, 3)
.map(key => `${key}: ${getShortTypeString(data[key], isDiff)}`)
.concat(keys.length > 3 ? ['…'] : [])
.join(', ');

return `{ ${str} }`;
} else if (type === 'Array') {
case 'Array':
if (!isWideLayout) return data.length ? '[…]' : '[]';

const str = data
str = data
.slice(0, 4)
.map(val => getShortTypeString(val, isDiff))
.concat(data.length > 4 ? ['…'] : []).join(', ');

return `[${str}]`;
} else {
default:
return type;
}
}
Expand All @@ -71,7 +133,6 @@ const getItemString = (
isDiff: boolean = false
): React$Element<*> =>
<span {...styling('treeItemHint')}>
{data[IS_IMMUTABLE_KEY] ? 'Immutable' : ''}
{getText(type, data, isWideLayout, isDiff)}
</span>;

Expand Down
21 changes: 13 additions & 8 deletions src/utils/getInspectedState.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
// @flow
import { Iterable, fromJS } from 'immutable';
import isIterable from './isIterable';
import getType from './getType';

function iterateToKey(obj, key) { // maybe there's a better way, dunno
let idx = 0;
for (let entry of obj) {
if (Array.isArray(entry)) {
if (entry[0] === key) return entry[1];
} else {
if (idx > key) return;
if (idx === key) return entry;
}
if (idx === key) return entry;
idx++;
}
}

const entryRegex = /\[entry (\d+)\]/;

export default function getInspectedState(
state: Object, path: ?string[], convertImmutable: boolean
): Object {
Expand All @@ -24,8 +22,15 @@ export default function getInspectedState(
if (!s) {
return s;
}

if (Iterable.isAssociative(s)) {
if (Iterable.isAssociative(s) || getType(s) === 'Map') {
if (!s.has(key) && entryRegex.test(key)) {
const match = key.match(entryRegex);
const entry = iterateToKey(s, parseInt(match && match[1], 10));
return entry && {
'[key]': entry[0],
'[value]': entry[1]
};
}
return s.get(key);
} else if (isIterable(s)) {
return iterateToKey(s, parseInt(key, 10));
Expand Down
33 changes: 33 additions & 0 deletions src/utils/getType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @flow
import { List, Map as ImMap, Set as ImSet, OrderedMap, OrderedSet, Stack, Seq } from 'immutable';
import objType from 'react-json-tree/lib/objType';

type Type =
string |
'Immutable List' |
'Immutable Map' |
'Immutable Set' |
'Immutable OrderedMap' |
'Immutable OrderedSet' |
'Immutable Stack' |
'Immutable Seq';

export default function getType(value: any): Type {
if (List.isList(value)) {
return 'Immutable List';
} else if (ImMap.isMap(value)) {
return 'Immutable Map';
} else if (ImSet.isSet(value)) {
return 'Immutable Set';
} else if (OrderedMap.isOrderedMap(value)) {
return 'Immutable OrderedMap';
} else if (OrderedSet.isOrderedSet(value)) {
return 'Immutable OrderedSet';
} else if (Stack.isStack(value)) {
return 'Immutable Stack';
} else if (Seq.isSeq(value)) {
return 'Immutable Seq';
}

return objType(value);
}
Loading

0 comments on commit 9dfaaab

Please sign in to comment.