-
-
Save sergeysova/ce3e8b3f640690b73a8e2514222755c1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useLayoutEffect, useRef } from 'react' | |
import { useStore } from 'effector-react' | |
import * as effector from 'effector' | |
import { pathOr } from 'ramda' | |
const trackCreateStore = effector.createEvent('trackCreateStore') | |
const trackCreateEvent = effector.createEvent('trackCreateEvent') | |
const trackCreateEffect = effector.createEvent('trackCreateEffect') | |
const trackCreateStoreObject = effector.createEvent('trackCreateStoreObject') | |
export function createStore(...params) { | |
// console.log('createStore', params) | |
const store = effector.createStore(...params) | |
process.env.NODE_ENV === 'development' && trackCreateStore({ | |
store, | |
params, | |
}) | |
return store | |
} | |
export function createEvent(...params) { | |
// console.log('createEvent', params) | |
const event = effector.createEvent(...params) | |
process.env.NODE_ENV === 'development' && trackCreateEvent({ | |
event, | |
params, | |
}) | |
return event | |
} | |
export function createEffect(...params) { | |
// console.log('createEffect', params) | |
const effect = effector.createEffect(...params) | |
process.env.NODE_ENV === 'development' && trackCreateEffect({ | |
effect, | |
params, | |
}) | |
return effect | |
} | |
export function createStoreObject(...params) { | |
// console.log('createStoreObject', params) | |
const storeObject = effector.createStoreObject(...params) | |
process.env.NODE_ENV === 'development' && trackCreateStoreObject({ | |
storeObject, | |
params, | |
}) | |
return storeObject | |
} | |
const toggleVisibility = effector.createEvent('toggleVisibility') | |
const visibility = effector.createStore(true) | |
.on(toggleVisibility, state => !state) | |
const $winParams = effector.createStoreObject({ | |
visibility, | |
}) | |
const $storeMap = effector.createStore(new Map(), { name: 'TEST' }) | |
.on(trackCreateStore, (state, { store, params }) => { | |
state.set(store, params) | |
store.watch((...args) => { | |
console.log('watch Store:', store.shortName) | |
addEvent({ type: 'store', name: store.shortName }) | |
nextTick() | |
}) | |
return state | |
}) | |
const addEvent = effector.createEvent() | |
const $eventCallStack = effector.createStore([], { name: 'eventCallStack' }) | |
.on(addEvent, (state, event) => { | |
return [ | |
...state, | |
event, | |
] | |
}) | |
const $eventMap = effector.createStore(new Map(), { name: 'TEST' }) | |
.on(trackCreateEvent, (state, { event, params }) => { | |
state.set(event, params[0]) | |
event.watch((payload, eventName) => { | |
console.log(' * Event:', eventName) | |
addEvent({ type: 'event', name: eventName }) | |
nextTick() | |
}) //, payload)) | |
return state | |
}) | |
const nextTick = effector.createEvent() | |
const $timeout = effector.createStore(0) | |
.on(nextTick, state => state + 1) | |
// setInterval(nextTick, 250) | |
export const DevToolWindow = () => { | |
const tick = useStore($timeout) | |
const winParams = useStore($winParams) | |
const eventCallStack = useStore($eventCallStack) | |
const storeMap = useStore($storeMap) | |
const eventMap = useStore($eventMap) | |
const storeList = Array.from(storeMap.keys()) | |
const eventList = Array.from(eventMap.entries()) | |
const ref = useRef(null) | |
// console.log(storeList) | |
useLayoutEffect(() => { | |
if (ref.current) { | |
ref.current.scrollTop = ref.current.scrollHeight | |
} | |
}) | |
if (!winParams.visibility) return null | |
return ( | |
<div style={{ | |
position: 'absolute', | |
top: 50, | |
right: 50, | |
width: 650, | |
bottom: 50, | |
border: '1px solid rgba(255, 255, 255, .5)', | |
backgroundColor: 'rgba(0, 0, 0, .8)', | |
zIndex: 9999999, | |
boxShadow: '4px 4px 8px rgba(0, 0, 0, .5)', | |
color: 'white', | |
}} | |
> | |
<div style={{ | |
position: 'relative', | |
color: '#eee', | |
padding: '5px 10px', | |
backgroundColor: 'rgba(0, 0, 0, .25)', | |
width: '100%', | |
fontSize: 20, | |
borderBottom: '1px solid rgba(255, 255, 255, .25)', | |
}} | |
> | |
Effector Inspector ({tick}) | |
</div> | |
<div style={{ display: 'flex', padding: '5px 10px', height: '100%' }}> | |
<div style={{ flex: '0 0 45%' }}> | |
<div>Event list:</div> | |
<div style={{ | |
height: 290, | |
marginBottom: 10, | |
overflow: 'auto', | |
border: '1px solid #555', | |
backgroundColor: 'rgba(0, 0, 0, .35)', | |
}} | |
> | |
{eventList.map(([event, eventName], key) => ( | |
<div key={key}>{eventName || <span style={{ color: 'red' }}>noname</span>}</div> | |
))} | |
</div> | |
<div>Events stack:</div> | |
<div | |
ref={ref} | |
style={{ height: 420, overflow: 'auto', border: '1px solid #555', backgroundColor: 'rgba(0, 0, 0, .35)' }} | |
> | |
{eventCallStack.map((item, key) => ( | |
<div key={key}> | |
{item.type === 'store' | |
? <div style={{ | |
borderTop: pathOr('', [key - 1, 'type'], eventCallStack) === 'event' ? '1px dotted yellow' : 'none', | |
textAlign: 'right', | |
color: 'yellow', | |
padding: '0 10px', | |
}} | |
> | |
{item.name || '<NONAME>'} | |
</div> | |
: <div style={{ | |
color: 'lightgray', | |
marginTop: pathOr('', [key - 1, 'type'], eventCallStack) === 'store' ? 10 : 0, | |
}} | |
> | |
{item.name || '<NONAME>'} | |
</div> | |
} | |
</div> | |
))} | |
</div> | |
</div> | |
<div style={{ | |
flex: '1 0', | |
height: 'calc(100% - 42px)', | |
overflow: 'auto', | |
padding: '0 10px', | |
}} | |
> | |
<div>Store list</div> | |
<hr /> | |
{storeList.map(store => ( | |
<div | |
key={store.id} | |
style={{ | |
margin: '0 0 10px 0', | |
borderBottom: '1px solid #555', | |
// borderRadius: 5, | |
// backgroundColor: 'rgba(255, 255, 255, .15)', | |
}} | |
> | |
<div style={{ fontSize: 18 }}>{store.shortName}</div> | |
<pre style={{ | |
padding: '5px 10px', | |
backgroundColor: 'rgba(0, 0, 0, .35)', | |
color: 'white', | |
maxHeight: 200, | |
// width: 260, | |
overflow: 'auto', | |
}} | |
> | |
{typeof store.getState() === 'object' | |
? Object.entries(store.getState()).map(([key, value], i) => { | |
if (value && typeof value === 'object') { | |
return ( | |
<div key={i}> | |
<div>{key}:</div> | |
{Object.entries(value).map(([key, value], i) => { | |
return ( | |
<div key={i} style={{ marginLeft: 20 }}> | |
{key}: | |
<span style={{ color: 'yellow' }}> | |
{String(value)} | |
</span> | |
</div> | |
) | |
})} | |
</div> | |
) | |
} | |
return ( | |
<div key={i}> | |
{key}: | |
<span style={{ color: 'yellow' }}> | |
{String(value)} | |
</span> | |
</div> | |
) | |
}) | |
: <span style={{ color: 'yellow' }}>{store.getState()}</span> | |
} | |
{/*{JSON.stringify(store.getState(), null, 2)}*/} | |
</pre> | |
</div> | |
))} | |
</div> | |
</div> | |
</div> | |
) | |
} | |
export function enableEffectorInspectorHotKey() { | |
window.addEventListener('keydown', (e) => { | |
if (e.key === '`') toggleVisibility() | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment