More awesomeness

This commit is contained in:
Nathan Bierema 2020-08-08 14:16:00 -04:00
parent eaf03c4bf6
commit 72029d8046
18 changed files with 742 additions and 383 deletions

View File

@ -2,8 +2,8 @@
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^5.16.0", "eslint": "^7.6.0",
"eslint-config-prettier": "^3.6.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-babel": "^5.3.1", "eslint-plugin-babel": "^5.3.1",
"eslint-plugin-prettier": "^3.1.4", "eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.5", "eslint-plugin-react": "^7.20.5",

View File

@ -45,7 +45,7 @@
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3", "enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0", "enzyme-to-json": "^3.5.0",
"git-url-parse": "^7.2.0", "git-url-parse": "^11.1.2",
"jest": "^24.9.0", "jest": "^24.9.0",
"jsdom": "^11.12.0", "jsdom": "^11.12.0",
"react": "^16.13.1", "react": "^16.13.1",

View File

@ -208,7 +208,9 @@ export const getBase16Theme = (theme, base16Themes) => {
} }
} }
return theme && theme.hasOwnProperty('base00') ? theme : undefined; return theme && Object.prototype.hasOwnProperty.call(theme, 'base00')
? theme
: undefined;
}; };
export const invertTheme = theme => { export const invertTheme = theme => {

View File

@ -48,9 +48,9 @@
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3", "enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0", "enzyme-to-json": "^3.5.0",
"file-loader": "^3.0.1", "file-loader": "^6.0.0",
"html-loader": "^0.4.5", "html-loader": "^1.1.0",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^4.3.0",
"jest": "^24.9.0", "jest": "^24.9.0",
"raw-loader": "^1.0.0", "raw-loader": "^1.0.0",
"react": "^16.13.1", "react": "^16.13.1",

View File

@ -1,6 +1,5 @@
import commitExcessActions from './commitExcessActions'; import commitExcessActions from './commitExcessActions';
/* eslint-disable import/prefer-default-export */
export function recompute( export function recompute(
previousLiftedState, previousLiftedState,
storeState, storeState,

View File

@ -35,7 +35,7 @@
"clean-webpack-plugin": "^3.0.0", "clean-webpack-plugin": "^3.0.0",
"cross-env": "^7.0.2", "cross-env": "^7.0.2",
"export-files-webpack-plugin": "^0.0.1", "export-files-webpack-plugin": "^0.0.1",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^4.3.0",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"raw-loader": "^1.0.0", "raw-loader": "^1.0.0",
"react": "^16.13.1", "react": "^16.13.1",

View File

@ -27,7 +27,6 @@ module.exports = {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
inject: true, inject: true,
template: 'demo/src/index.html', template: 'demo/src/index.html',
filename: 'index.html',
package: pkg package: pkg
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({

View File

@ -37,7 +37,7 @@
"@babel/core": "^7.11.1", "@babel/core": "^7.11.1",
"@babel/preset-env": "^7.11.0", "@babel/preset-env": "^7.11.0",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"expect": "^1.20.2", "expect": "^26.2.0",
"jest": "^24.9.0", "jest": "^24.9.0",
"redux": "^4.0.5", "redux": "^4.0.5",
"rimraf": "^2.7.1", "rimraf": "^2.7.1",

View File

@ -1,4 +1,4 @@
{ {
"presets": ["@babel/preset-env", "@babel/preset-react"], "presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": ["@babel/plugin-proposal-class-properties"] "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-do-expressions"]
} }

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<title><%= htmlWebpackPlugin.options.package.name %></title>
<meta name="description" content="<%= htmlWebpackPlugin.options.package.description %>">
<link href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.5/paper/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,162 @@
import React from 'react';
import { connect } from 'react-redux';
import pkg from '../../../package.json';
import { Button, Toolbar, Spacer } from 'devui';
import getOptions from './getOptions';
import { push as pushRoute } from 'react-router-redux';
const styles = {
wrapper: {
height: '100vh',
width: '450px',
margin: 'auto',
textAlign: 'center'
},
muted: {
color: '#CCCCCC'
},
link: {
margin: '0 0.5rem',
cursor: 'pointer',
display: 'block'
}
};
const ROOT = '/'; // process.env.NODE_ENV === 'production' ? '/' : '/';
function buildUrl(options) {
return `${ROOT}?` + [
options.useExtension ? 'ext' : '',
options.theme ? 'theme=' + options.theme : '',
options.dark ? 'dark' : ''
].filter(s => s).join('&');
}
class DemoApp extends React.Component {
render() {
const options = getOptions();
return (
<div style={styles.wrapper}>
<h3>
{pkg.name || <span style={styles.muted}>Package Name</span>}
</h3>
<h5>{pkg.description || <span style={styles.muted}>Package Description</span>}</h5>
<Toolbar>
<Spacer />
<Button onClick={this.props.increment}>
Increment
</Button>
<Button onClick={this.props.push}>
Push
</Button>
<Button onClick={this.props.pop}>
Pop
</Button>
<Button onClick={this.props.replace}>
Replace
</Button>
<Button onClick={this.props.changeNested}>
Change Nested
</Button>
<Spacer />
</Toolbar>
<Toolbar>
<Spacer />
<Button onClick={this.props.pushHugeArray}>
Push Huge Array
</Button>
<Button onClick={this.props.addHugeObect}>
Add Huge Object
</Button>
<Button onClick={this.props.hugePayload}>
Huge Payload
</Button>
<Spacer />
</Toolbar>
<Toolbar>
<Spacer />
<Button onClick={this.props.addIterator}>
Add Iterator
</Button>
<Button onClick={this.props.addImmutableMap}>
Add Immutable Map
</Button>
<Button onClick={this.props.changeImmutableNested}>
Change Immutable Nested
</Button>
<Spacer />
</Toolbar>
<Toolbar>
<Spacer />
<Button onClick={this.props.addRecursive}>
Add Recursive
</Button>
<Button onClick={this.props.addFunction}>
Add Function
</Button>
<Button onClick={this.props.addSymbol}>
Add Symbol
</Button>
<Spacer />
</Toolbar>
<Toolbar>
<Spacer />
<Button onClick={this.toggleTimeoutUpdate}>
Timeout Update {this.props.timeoutUpdateEnabled ? 'On' : 'Off'}
</Button>
<Button onClick={this.props.shuffleArray}>
Shuffle Array
</Button>
<Spacer />
</Toolbar>
<div>
{options.useExtension ?
<a href={`${ROOT}`} style={styles.link}>Disable browser extension</a> :
<a href={`${ROOT}?ext`} style={styles.link}>Use browser extension</a>
}
</div>
</div>
);
}
toggleTimeoutUpdate = () => {
const enabled = !this.props.timeoutUpdateEnabled;
this.props.toggleTimeoutUpdate(enabled);
if (enabled) {
this.timeout = setInterval(this.props.timeoutUpdate, 1000);
} else {
clearTimeout(this.timeout);
}
}
}
export default connect(
state => state,
{
toggleTimeoutUpdate: timeoutUpdateEnabled => ({
type: 'TOGGLE_TIMEOUT_UPDATE', timeoutUpdateEnabled
}),
timeoutUpdate: () => ({ type: 'TIMEOUT_UPDATE' }),
increment: () => ({ type: 'INCREMENT' }),
push: () => ({ type: 'PUSH' }),
pop: () => ({ type: 'POP' }),
replace: () => ({ type: 'REPLACE' }),
changeNested: () => ({ type: 'CHANGE_NESTED' }),
pushHugeArray: () => ({ type: 'PUSH_HUGE_ARRAY' }),
addIterator: () => ({ type: 'ADD_ITERATOR' }),
addHugeObect: () => ({ type: 'ADD_HUGE_OBJECT' }),
addRecursive: () => ({ type: 'ADD_RECURSIVE' }),
addImmutableMap: () => ({ type: 'ADD_IMMUTABLE_MAP' }),
changeImmutableNested: () => ({ type: 'CHANGE_IMMUTABLE_NESTED' }),
hugePayload: () => ({
type: 'HUGE_PAYLOAD',
payload: Array.from({ length: 10000 }).map((_, i) => i)
}),
addFunction: () => ({ type: 'ADD_FUNCTION' }),
addSymbol: () => ({ type: 'ADD_SYMBOL' }),
shuffleArray: () => ({ type: 'SHUFFLE_ARRAY' }),
pushRoute
}
)(DemoApp);

View File

@ -0,0 +1,11 @@
export default function getOptions() {
return {
useExtension: window.location.search.indexOf('ext') !== -1,
supportImmutable: window.location.search.indexOf('immutable') !== -1,
theme: do {
const match = window.location.search.match(/theme=([^&]+)/);
match ? match[1] : 'inspector'
},
dark: window.location.search.indexOf('dark') !== -1
};
}

View File

@ -0,0 +1,111 @@
import '@babel/polyfill';
import 'devui/lib/presets';
import React from 'react';
import { render } from 'react-dom';
import { Container } from 'devui';
import DemoApp from './DemoApp';
import { Provider } from 'react-redux';
import reducers from './reducers';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import createLogger from 'redux-logger';
import { Router, Route, browserHistory } from 'react-router';
import {
syncHistoryWithStore,
routerReducer,
routerMiddleware
} from 'react-router-redux';
import { createDevTools, persistState } from 'redux-devtools';
import DevtoolsInspector from 'redux-devtools-inspector';
import DockMonitor from 'redux-devtools-dock-monitor';
import getOptions from './getOptions';
import TestGenerator from '../../../src';
function getDebugSessionKey() {
const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/);
return matches && matches.length > 0 ? matches[1] : null;
}
const getDevTools = options =>
createDevTools(
<DockMonitor
defaultIsVisible
toggleVisibilityKey="ctrl-h"
changePositionKey="ctrl-q"
changeMonitorKey="ctrl-m"
>
<DevtoolsInspector
theme={options.theme}
shouldPersistState
invertTheme={!options.dark}
supportImmutable={options.supportImmutable}
tabs={defaultTabs => [
{
name: 'Test',
component: TestGenerator
},
...defaultTabs
]}
/>
</DockMonitor>
);
const ROOT =
process.env.NODE_ENV === 'production' ? '/redux-devtools-inspector/' : '/';
let DevTools = getDevTools(getOptions());
const reduxRouterMiddleware = routerMiddleware(browserHistory);
const enhancer = compose(
applyMiddleware(createLogger(), reduxRouterMiddleware),
(...args) => {
const useDevtoolsExtension =
!!window.__REDUX_DEVTOOLS_EXTENSION__ && getOptions().useExtension;
const instrument = useDevtoolsExtension
? window.__REDUX_DEVTOOLS_EXTENSION__()
: DevTools.instrument();
return instrument(...args);
},
persistState(getDebugSessionKey())
);
const store = createStore(
combineReducers({
...reducers,
routing: routerReducer
}),
{},
enhancer
);
const history = syncHistoryWithStore(browserHistory, store);
const handleRouterUpdate = () => {
renderApp(getOptions());
};
const router = (
<Router history={history} onUpdate={handleRouterUpdate}>
<Route path={ROOT} component={DemoApp} />
</Router>
);
const renderApp = options => {
DevTools = getDevTools(options);
const useDevtoolsExtension =
!!window.__REDUX_DEVTOOLS_EXTENSION__ && options.useExtension;
return render(
<Provider store={store}>
<Container
themeData={{ theme: 'default', scheme: 'default', light: true }}
>
{router}
{!useDevtoolsExtension && <DevTools />}
</Container>
</Provider>,
document.getElementById('root')
);
};
renderApp(getOptions());

View File

@ -0,0 +1,103 @@
import Immutable from 'immutable';
import shuffle from 'lodash.shuffle';
const NESTED = {
long: {
nested: [{
path: {
to: {
a: 'key'
}
}
}]
}
};
const IMMUTABLE_NESTED = Immutable.fromJS(NESTED);
/* eslint-disable babel/new-cap */
const IMMUTABLE_MAP = Immutable.Map({
map: Immutable.Map({ a:1, b: 2, c: 3 }),
list: Immutable.List(['a', 'b', 'c']),
set: Immutable.Set(['a', 'b', 'c']),
stack: Immutable.Stack(['a', 'b', 'c']),
seq: Immutable.Seq.of(1, 2, 3, 4, 5, 6, 7, 8)
});
/* eslint-enable babel/new-cap */
const HUGE_ARRAY = Array.from({ length: 5000 })
.map((_, key) => ({ str: 'key ' + key }));
const HUGE_OBJECT = Array.from({ length: 5000 })
.reduce((o, _, key) => (o['key ' + key] = 'item ' + key, o), {});
const FUNC = function (a, b, c) { return a + b + c; };
const RECURSIVE = {};
RECURSIVE.obj = RECURSIVE;
function createIterator() {
const iterable = {};
iterable[window.Symbol.iterator] = function *iterator() {
for (var i = 0; i < 333; i++) {
yield 'item ' + i;
}
}
return iterable;
}
const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
export default {
timeoutUpdateEnabled: (state=false, action) => action.type === 'TOGGLE_TIMEOUT_UPDATE' ?
action.timeoutUpdateEnabled : state,
store: (state=0, action) => action.type === 'INCREMENT' ? state + 1 : state,
undefined: (state={ val: undefined }) => state,
null: (state=null) => state,
func: (state=() => {}) => state,
array: (state=[], action) => action.type === 'PUSH' ?
[...state, Math.random()] : (
action.type === 'POP' ? state.slice(0, state.length - 1) : (
action.type === 'REPLACE' ? [Math.random(), ...state.slice(1)] : state
)
),
hugeArrays: (state=[], action) => action.type === 'PUSH_HUGE_ARRAY' ?
[ ...state, ...HUGE_ARRAY ] : state,
hugeObjects: (state=[], action) => action.type === 'ADD_HUGE_OBJECT' ?
[ ...state, HUGE_OBJECT ] : state,
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 + '!'
}
}
}]
}
} : state,
recursive: (state=[], action) => action.type === 'ADD_RECURSIVE' ?
[...state, { ...RECURSIVE }] : state,
immutables: (state=[], action) => action.type === 'ADD_IMMUTABLE_MAP' ?
[...state, IMMUTABLE_MAP] : state,
immutableNested: (state=IMMUTABLE_NESTED, action) => action.type === 'CHANGE_IMMUTABLE_NESTED' ?
state.updateIn(
['long', 'nested', 0, 'path', 'to', 'a'],
str => str + '!'
) : state,
addFunction: (state=null, action) => action.type === 'ADD_FUNCTION' ?
{ f: FUNC } : state,
addSymbol: (state=null, action) => action.type === 'ADD_SYMBOL' ?
{ s: window.Symbol('symbol') } : state,
shuffleArray: (state=DEFAULT_SHUFFLE_ARRAY, action) =>
action.type === 'SHUFFLE_ARRAY' ?
shuffle(state) : state
};

View File

@ -38,6 +38,8 @@
"@babel/cli": "^7.10.5", "@babel/cli": "^7.10.5",
"@babel/core": "^7.11.1", "@babel/core": "^7.11.1",
"@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-do-expressions": "^7.10.4",
"@babel/polyfill": "^7.10.4",
"@babel/preset-env": "^7.11.0", "@babel/preset-env": "^7.11.0",
"@babel/preset-react": "^7.10.4", "@babel/preset-react": "^7.10.4",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
@ -46,10 +48,10 @@
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3", "enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0", "enzyme-to-json": "^3.5.0",
"expect": "^1.20.2", "expect": "^26.2.0",
"export-files-webpack-plugin": "^0.0.1", "export-files-webpack-plugin": "^0.0.1",
"file-loader": "^3.0.1", "file-loader": "^6.0.0",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^4.3.0",
"jest": "^24.9.0", "jest": "^24.9.0",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
@ -63,7 +65,9 @@
"redux-logger": "^2.10.2", "redux-logger": "^2.10.2",
"rimraf": "^2.7.1", "rimraf": "^2.7.1",
"style-loader": "^0.13.2", "style-loader": "^0.13.2",
"url-loader": "^1.1.2" "url-loader": "^1.1.2",
"webpack": "^4.44.1",
"webpack-dev-server": "^3.11.0"
}, },
"dependencies": { "dependencies": {
"devui": "^1.0.0-4", "devui": "^1.0.0-4",

View File

@ -26,7 +26,6 @@ module.exports = {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
inject: true, inject: true,
template: 'demo/src/index.html', template: 'demo/src/index.html',
filename: 'index.html',
package: pkg package: pkg
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({

View File

@ -36,7 +36,7 @@ function removeCss(document: Document, ref: number) {
function applyStyles(element: HTMLElement, styles: Object) { function applyStyles(element: HTMLElement, styles: Object) {
element.setAttribute('style', ''); element.setAttribute('style', '');
for (const key in styles) { for (const key in styles) {
if (!styles.hasOwnProperty(key)) { if (!Object.prototype.hasOwnProperty.call(styles, key)) {
continue; continue;
} }
// $FlowFixMe // $FlowFixMe

687
yarn.lock

File diff suppressed because it is too large Load Diff