Something went wrong. Try again.
☢ Make Your React App Truly Reactive!
Something went wrong. Try again.
1.6 kB · 55 lines
JavaScript
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556const isObject = require('./isObject')const inputBinding = require('./inputBinding')const schedule = require('./schedule')const unwrap = require('./unwrap')const unReactify = require('./unReactify')
const reactify = (state, forceUpdate, path = []) => {
// recursively make all slices of state reactive const wrapper = Array.isArray(state) ? [] : {} Object.keys(state).forEach(key => { let slice = state[key] slice = unwrap(slice) wrapper[key] = isObject(slice) ? reactify(slice, forceUpdate, [...path, key]) : slice })
// counter that keeps track how many times state is mutated let mutations = 0
// make the wrapper radioactive return new Proxy(wrapper, {
set(target, prop, value) { const addingNonReactiveObject = isObject(value) && !value.__isRadioactive__ const $value = addingNonReactiveObject ? reactify(value, forceUpdate, [...path, prop]) : value
// if new value and old value are not same if (target[prop] !== $value) { schedule(forceUpdate) mutations++ }
return Reflect.set(target, prop, $value) },
deleteProperty(target, prop) { schedule(forceUpdate) mutations++ return Reflect.deleteProperty(target, prop) },
get(target, prop) { if (prop === '__target__') return unReactify(target) if (prop === '__isRadioactive__') return true // mutation count if (prop === '$') return mutations // inputBinding if (prop[0] === '$') return inputBinding(prop, target, forceUpdate) else return Reflect.get(target, prop) },
})}
module.exports = reactify