diff --git a/package/index.js b/package/index.js index 3a5229c76..d54286e97 100644 --- a/package/index.js +++ b/package/index.js @@ -1,13 +1,19 @@ const snapShot = []; +const mode = { jumping: false }; + +const linkState = require('./linkState')(snapShot, mode); +const timeJump = require('./timeJump')(snapShot, mode); + +const getShot = () => snapShot.map(({ component }) => component.state); window.addEventListener('message', ({ data: { action, payload } }) => { if (action === 'jumpToSnap') { - console.log('snap received from chrome', payload); + timeJump(payload); } }); -const linkState = require('./linkState')(snapShot); - module.exports = { linkState, + timeJump, + getShot, }; diff --git a/package/linkState.js b/package/linkState.js index 6a07a27f1..2e159ee1a 100644 --- a/package/linkState.js +++ b/package/linkState.js @@ -1,9 +1,12 @@ // links component state to library // changes the setState method to also update our snapshot -module.exports = (snapShot) => { +module.exports = (snapShot, mode) => { + // send message to window containing component states + // unless library is currently jumping through time function sendSnapShot() { - const payload = snapShot.map(comp => comp.state); + if (mode.jumping) return; + const payload = snapShot.map(({ component }) => component.state); window.postMessage({ action: 'recordSnap', payload, @@ -11,19 +14,33 @@ module.exports = (snapShot) => { } return (component) => { - snapShot.push(component); + // make a copy of setState + const oldSetState = component.setState.bind(component); - sendSnapShot(); + // convert setState to promise + const setStateAsync = (state) => { + return new Promise(resolve => oldSetState(state, resolve)); + }; - const oldSetState = component.setState.bind(component); + // add component to snapshot + snapShot.push({ component, setStateAsync }); + let first = true; function newSetState(state, callback = () => { }) { + // if setState is being called for the first time, this conditional sends the initial snapshot + if (first) { + first = false; + sendSnapShot(); + } + + // continue normal setState functionality, except add sending message middleware oldSetState(state, () => { sendSnapShot(); callback(); }); } + // replace component's setState so developer doesn't change syntax component.setState = newSetState; }; }; diff --git a/package/timeJump.js b/package/timeJump.js new file mode 100644 index 000000000..d023b3d30 --- /dev/null +++ b/package/timeJump.js @@ -0,0 +1,9 @@ +module.exports = (snapShot, mode) => { + return (newSnapShot) => { + mode.jumping = true; + newSnapShot.forEach(async (state, i) => { + await snapShot[i].setStateAsync(state); + }); + mode.jumping = false; + }; +};