Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #427 from plotly/test-store-datatypes
Browse files Browse the repository at this point in the history
Test store data types update & fixes
  • Loading branch information
T4rk1n authored Jan 8, 2019
2 parents ed843f5 + 9093035 commit 52b804d
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 82 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [0.42.1] - 2019-01-07
### Fixed
- Fix `dcc.Store` type changes [#427](https://github.com/plotly/dash-core-components/pull/427)

## [0.42.0] - 2018-12-27
### Fixed
- Fix `dcc.Store` null values in list causing an infinite loop [#424](https://github.com/plotly/dash-core-components/pull/424)
Expand Down
89 changes: 60 additions & 29 deletions dash_core_components/dash_core_components.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -114609,42 +114609,65 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }



/**
* Deep equality check to know if the data has changed.
*
* @param {*} newData - New data to compare
* @param {*} oldData - The old data to compare
* @returns {boolean} The data has changed.
*/

function dataCheck(data, old) {
// Assuming data and old are of the same type.
var oldNull = ramda__WEBPACK_IMPORTED_MODULE_0___default.a.isNil(old);
var newNull = ramda__WEBPACK_IMPORTED_MODULE_0___default.a.isNil(data);
function dataChanged(newData, oldData) {
var oldNull = Object(ramda__WEBPACK_IMPORTED_MODULE_0__["isNil"])(oldData);
var newNull = Object(ramda__WEBPACK_IMPORTED_MODULE_0__["isNil"])(newData);

if ((oldNull || newNull) && !(oldNull && newNull)) {
return true;
if (oldNull || newNull) {
return newData !== oldData;
}

var type = ramda__WEBPACK_IMPORTED_MODULE_0___default.a.type(data);
var newType = Object(ramda__WEBPACK_IMPORTED_MODULE_0__["type"])(newData);

if (type === 'Array') {
if (data.length !== old.length) {
if (newType !== Object(ramda__WEBPACK_IMPORTED_MODULE_0__["type"])(oldData)) {
return true;
}

if (newType === 'Array') {
if (newData.length !== oldData.length) {
return true;
}

for (var i = 0; i < data.length; i++) {
if (dataCheck(data[i], old[i])) {
for (var i = 0; i < newData.length; i++) {
if (dataChanged(newData[i], oldData[i])) {
return true;
}
}
} else if (ramda__WEBPACK_IMPORTED_MODULE_0___default.a.contains(type, ['String', 'Number'])) {
return old !== data;
} else if (type === 'Object') {
return ramda__WEBPACK_IMPORTED_MODULE_0___default.a.any(function (_ref) {
} else if (Object(ramda__WEBPACK_IMPORTED_MODULE_0__["contains"])(newType, ['String', 'Number', 'Boolean'])) {
return oldData !== newData;
} else if (newType === 'Object') {
var oldEntries = Object.entries(oldData);
var newEntries = Object.entries(newData);

if (oldEntries.length !== newEntries.length) {
return true;
}

return Object(ramda__WEBPACK_IMPORTED_MODULE_0__["any"])(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
k = _ref2[0],
v = _ref2[1];

return dataCheck(v, old[k]);
})(Object.entries(data));
return dataChanged(v, oldData[k]);
})(newEntries);
}

return false;
}
/**
* Abstraction for the memory storage_type to work the same way as local/session
*
* Each memory Store component get it's own MemStore.
*/


var MemStore =
/*#__PURE__*/
Expand Down Expand Up @@ -114689,6 +114712,12 @@ function () {

return MemStore;
}();
/**
* Abstraction for local/session storage_type.
*
* Single instances for localStorage, sessionStorage
*/


var WebStore =
/*#__PURE__*/
Expand Down Expand Up @@ -114797,7 +114826,7 @@ function (_React$Component) {

var old = this._backstore.getItem(id);

if (ramda__WEBPACK_IMPORTED_MODULE_0___default.a.isNil(old) && data) {
if (Object(ramda__WEBPACK_IMPORTED_MODULE_0__["isNil"])(old) && data) {
// Initial data mount
this._backstore.setItem(id, data);

Expand All @@ -114810,7 +114839,7 @@ function (_React$Component) {
return;
}

if (setProps && dataCheck(old, data)) {
if (setProps && dataChanged(old, data)) {
setProps({
data: old,
modified_timestamp: this._backstore.getModified(id)
Expand Down Expand Up @@ -114843,18 +114872,20 @@ function (_React$Component) {
modified_timestamp: this._backstore.getModified(id)
});
}
} else if (data) {
var old = this._backstore.getItem(id); // Only set the data if it's not the same data.

return;
}

if (dataCheck(data, old)) {
this._backstore.setItem(id, data);
var old = this._backstore.getItem(id); // Only set the data if it's not the same data.

if (setProps) {
setProps({
modified_timestamp: this._backstore.getModified(id)
});
}

if (dataChanged(data, old)) {
this._backstore.setItem(id, data);

if (setProps) {
setProps({
modified_timestamp: this._backstore.getModified(id)
});
}
}
}
Expand Down Expand Up @@ -114892,7 +114923,7 @@ Store.propTypes = {
/**
* The stored data for the id.
*/
data: prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.oneOfType([prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.object, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.array, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.number, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.string]),
data: prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.oneOfType([prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.object, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.array, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.number, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.string, prop_types__WEBPACK_IMPORTED_MODULE_2___default.a.bool]),

/**
* Set to true to remove the data contained in `data_key`.
Expand Down
2 changes: 1 addition & 1 deletion dash_core_components/dash_core_components.dev.js.map

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dash_core_components/dash_core_components.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dash_core_components/dash_core_components.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dash_core_components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-core-components",
"version": "0.42.0",
"version": "0.42.1",
"description": "Core component suite for Dash",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion dash_core_components/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.42.0'
__version__ = '0.42.1'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-core-components",
"version": "0.42.0",
"version": "0.42.1",
"description": "Core component suite for Dash",
"repository": {
"type": "git",
Expand Down
79 changes: 52 additions & 27 deletions src/components/Store.react.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,51 @@
import R from 'ramda';
import {isNil, type, contains, any} from 'ramda';
import React from 'react';
import PropTypes from 'prop-types';

function dataCheck(data, old) {
// Assuming data and old are of the same type.
const oldNull = R.isNil(old);
const newNull = R.isNil(data);
/**
* Deep equality check to know if the data has changed.
*
* @param {*} newData - New data to compare
* @param {*} oldData - The old data to compare
* @returns {boolean} The data has changed.
*/
function dataChanged(newData, oldData) {
const oldNull = isNil(oldData);
const newNull = isNil(newData);
if (oldNull || newNull) {
return oldNull !== newNull;
return newData !== oldData;
}
const newType = type(newData);
if (newType !== type(oldData)) {
return true;
}
const type = R.type(data);
if (type === 'Array') {
if (data.length !== old.length) {
if (newType === 'Array') {
if (newData.length !== oldData.length) {
return true;
}
for (let i = 0; i < data.length; i++) {
if (dataCheck(data[i], old[i])) {
for (let i = 0; i < newData.length; i++) {
if (dataChanged(newData[i], oldData[i])) {
return true;
}
}
} else if (R.contains(type, ['String', 'Number'])) {
return old !== data;
} else if (type === 'Object') {
return R.any(([k, v]) => dataCheck(v, old[k]))(Object.entries(data));
} else if (contains(newType, ['String', 'Number', 'Boolean'])) {
return oldData !== newData;
} else if (newType === 'Object') {
const oldEntries = Object.entries(oldData);
const newEntries = Object.entries(newData);
if (oldEntries.length !== newEntries.length) {
return true;
}
return any(([k, v]) => dataChanged(v, oldData[k]))(newEntries);
}
return false;
}

/**
* Abstraction for the memory storage_type to work the same way as local/session
*
* Each memory Store component get it's own MemStore.
*/
class MemStore {
constructor() {
this._data = {};
Expand Down Expand Up @@ -58,6 +77,11 @@ class MemStore {
}
}

/**
* Abstraction for local/session storage_type.
*
* Single instances for localStorage, sessionStorage
*/
class WebStore {
constructor(storage) {
this._storage = storage;
Expand Down Expand Up @@ -129,7 +153,7 @@ export default class Store extends React.Component {
}

const old = this._backstore.getItem(id);
if (R.isNil(old) && data) {
if (isNil(old) && data) {
// Initial data mount
this._backstore.setItem(id, data);
if (setProps) {
Expand All @@ -140,7 +164,7 @@ export default class Store extends React.Component {
return;
}

if (setProps && dataCheck(old, data)) {
if (setProps && dataChanged(old, data)) {
setProps({
data: old,
modified_timestamp: this._backstore.getModified(id),
Expand All @@ -165,16 +189,16 @@ export default class Store extends React.Component {
modified_timestamp: this._backstore.getModified(id),
});
}
} else if (data) {
const old = this._backstore.getItem(id);
// Only set the data if it's not the same data.
if (dataCheck(data, old)) {
this._backstore.setItem(id, data);
if (setProps) {
setProps({
modified_timestamp: this._backstore.getModified(id),
});
}
return;
}
const old = this._backstore.getItem(id);
// Only set the data if it's not the same data.
if (dataChanged(data, old)) {
this._backstore.setItem(id, data);
if (setProps) {
setProps({
modified_timestamp: this._backstore.getModified(id),
});
}
}
}
Expand Down Expand Up @@ -213,6 +237,7 @@ Store.propTypes = {
PropTypes.array,
PropTypes.number,
PropTypes.string,
PropTypes.bool,
]),

/**
Expand Down
Loading

0 comments on commit 52b804d

Please sign in to comment.