From 2c45ceee106810d129d519a2da487059205a21bc Mon Sep 17 00:00:00 2001 From: Fritz Lekschas <932103+flekschas@users.noreply.github.com> Date: Tue, 16 Feb 2021 17:51:33 -0500 Subject: [PATCH] Add `debug` as an option to `piling.importState(state, options)` --- CHANGELOG.md | 8 +++++++- src/library.js | 10 +++++----- src/store.js | 43 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d6b38c5..b7b63950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ## Next -_[Changes since v0.7.12](https://github.com/flekschas/piling.js/compare/v0.7.12...master)_ +_[Changes since v0.7.13](https://github.com/flekschas/piling.js/compare/v0.7.13...master)_ + +## v0.7.13 + +- Add `debug` as an option to `piling.importState(state, options)` and `createLibraryFromState` to help discover issues with broken state. + +_[Changes since v0.7.12](https://github.com/flekschas/piling.js/compare/v0.7.12...v0.7.13)_ ## v0.7.12 diff --git a/src/library.js b/src/library.js index af9c8149..6f6c56a2 100644 --- a/src/library.js +++ b/src/library.js @@ -4057,7 +4057,7 @@ const createPilingJs = (rootElement, initProps = {}) => { const importState = ( newState, - { deserialize = false, overwriteState = false } = {} + { deserialize = false, overwriteState = false, debug = false } = {} ) => { // We assume that the user imports an already initialized state isInitialPositioning = false; @@ -4067,10 +4067,10 @@ const createPilingJs = (rootElement, initProps = {}) => { if (action.type.indexOf('OVERWRITE') >= 0) resolve(); }); }); - store.import( - deserialize ? deserializeState(newState) : newState, - overwriteState - ); + store.import(deserialize ? deserializeState(newState) : newState, { + overwriteState, + debug, + }); resetPileBorder(); whenUpdated.then(() => { pubSub.unsubscribe(updateUnsubscriber); diff --git a/src/store.js b/src/store.js index 6530e8ae..09573416 100644 --- a/src/store.js +++ b/src/store.js @@ -100,14 +100,14 @@ export const reset = () => ({ payload: {}, }); -export const overwrite = (newState) => ({ +export const overwrite = (newState, debug) => ({ type: 'OVERWRITE', - payload: { newState }, + payload: { newState, debug }, }); -export const softOverwrite = (newState) => ({ +export const softOverwrite = (newState, debug) => ({ type: 'SOFT_OVERWRITE', - payload: { newState }, + payload: { newState, debug }, }); const [arrangementType, setArrangementType] = setter('arrangementType'); @@ -665,7 +665,7 @@ const [showSpatialIndex, setShowSpatialIndex] = setter( const createStore = () => { let lastAction = null; - const appReducer = combineReducers({ + const reducers = { arrangementObjective, arrangementOptions, arrangementType, @@ -774,7 +774,25 @@ const createStore = () => { temporaryDepiledPiles, zoomBounds, zoomScale, - }); + }; + + const appReducer = combineReducers(reducers); + + const warnForUnknownImportProps = (newState) => { + const unknownProps = Object.keys(newState) + .reduce((unknown, prop) => { + if (reducers[prop] === undefined) { + unknown.push(`"${prop}"`); + } + return unknown; + }, []) + .join(', '); + if (unknownProps) { + console.warn( + `The following state properties are not understood and will not imported: ${unknownProps}` + ); + } + }; const rootReducer = (state, action) => { lastAction = action; @@ -782,8 +800,12 @@ const createStore = () => { if (action.type === 'RESET') { state = undefined; // eslint-disable-line no-param-reassign } else if (action.type === 'OVERWRITE') { + if (action.payload.debug) + warnForUnknownImportProps(action.payload.newState); state = action.payload.newState; // eslint-disable-line no-param-reassign } else if (action.type === 'SOFT_OVERWRITE') { + if (action.payload.debug) + warnForUnknownImportProps(action.payload.newState); // eslint-disable-next-line no-param-reassign state = update(state, action.payload.newState, true); } @@ -805,7 +827,10 @@ const createStore = () => { return clonedState; }; - const importState = (newState, overwriteState = false) => { + const importState = ( + newState, + { overwriteState = false, debug = false } = {} + ) => { if (newState.version !== version) { console.warn( `The version of the imported state "${newState.version}" doesn't match the library version "${version}". Use at your own risk!` @@ -814,8 +839,8 @@ const createStore = () => { if (newState.version) delete newState.version; - if (overwriteState) reduxStore.dispatch(overwrite(newState)); - else reduxStore.dispatch(softOverwrite(newState)); + if (overwriteState) reduxStore.dispatch(overwrite(newState, debug)); + else reduxStore.dispatch(softOverwrite(newState, debug)); }; const resetState = () => {