Skip to content

Instantly share code, notes, and snippets.

@kobzarvs
Created June 7, 2019 19:45
Show Gist options
  • Save kobzarvs/7fea1c1237b10a94574aae1a1f25ad02 to your computer and use it in GitHub Desktop.
Save kobzarvs/7fea1c1237b10a94574aae1a1f25ad02 to your computer and use it in GitHub Desktop.
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