Commit 08ffb11d authored by Jaden DIEFENBAUGH's avatar Jaden DIEFENBAUGH

[js] use "fast-copy" library instead of JSON cloning, #113

parent 1b0b348a
......@@ -5661,6 +5661,11 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
"dev": true
},
"fast-copy": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-1.2.2.tgz",
"integrity": "sha512-qgk7WyVVFNvUzEV/RRQfI7Y6SEjHI+SfmHpkSzzoMUpd4+uXQaeGxhz52/FjnaaNGWxuWXr5l4/kRPD8GPecGA=="
},
"fast-deep-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
......
......@@ -84,6 +84,7 @@
"bootstrap": "^4.1.3",
"classnames": "^2.2.6",
"d3": "^5.5.0",
"fast-copy": "^1.2.2",
"fast-levenshtein": "^2.0.6",
"fuse.js": "^3.2.1",
"prop-types": "^15.6.2",
......
......@@ -11,7 +11,7 @@ import {
generateAlgorithmTemplate,
generateLibraryTemplate,
} from '@helpers/api';
import { jsonClone } from '@helpers';
import { copyObj } from '@helpers';
import type { BeatEntity, BeatObject } from '@helpers/beat';
import { pluralize } from '@helpers/beat';
......@@ -58,12 +58,12 @@ export default class EntityTemplateGenerationButton extends React.Component<Prop
if(!this.props.data.contents.parameters)
throw new Error(`Bad alg object, no params field: ${ this.props.data.contents }`);
const hasParameters = Object.keys(this.props.data.contents.parameters).length > 0;
uses = jsonClone(this.props.data.contents.uses);
uses = copyObj(this.props.data.contents.uses);
res = generateAlgorithmTemplate(this.props.data.name, hasParameters, uses);
break;
case('library'):
// find the used libraries
uses = jsonClone(this.props.data.contents.uses);
uses = copyObj(this.props.data.contents.uses);
res = generateLibraryTemplate(this.props.data.name, uses);
break;
default:
......
......@@ -17,7 +17,7 @@ import { connect } from 'react-redux';
import cn from 'classnames';
import { changeObjFieldName, generateNewKey, jsonClone } from '@helpers';
import { changeObjFieldName, generateNewKey, copyObj } from '@helpers';
import { algorithmValidator, BUILTIN_TYPES, ANALYZER_RESULT_TYPES, getValidAlgorithmObj as getValidObj } from '@helpers/beat';
import type { AlgorithmValidatorObject, BeatObject } from '@helpers/beat';
......@@ -131,7 +131,7 @@ export class AlgorithmEditor extends React.Component<Props, State> {
// updates an old group object to a new group object
updateGroup = (oldGroup: Group, newGroup: Group) => {
const gIdx = this.props.data.contents.groups.findIndex(g => JSON.stringify(g) === JSON.stringify(oldGroup));
const newGroups = jsonClone(this.props.data.contents.groups);
const newGroups = copyObj(this.props.data.contents.groups);
newGroups[gIdx] = newGroup;
this.changeContentsVal('groups', newGroups);
}
......@@ -142,7 +142,7 @@ export class AlgorithmEditor extends React.Component<Props, State> {
// renames a parameter (provide name & value & the old name)
// deletes a parameter (provide null as name, value is optional, the name)
updateParameter = (name: null | string, value: any, oldName: ?string) => {
const params = jsonClone(this.props.data.contents.parameters);
const params = copyObj(this.props.data.contents.parameters);
if(oldName)
delete params[oldName];
if(name !== null)
......@@ -159,7 +159,7 @@ export class AlgorithmEditor extends React.Component<Props, State> {
// toggles the algorithm to an analyzer algorithm
changeToAnalyzer = () => {
const contents = jsonClone(this.props.data.contents);
const contents = copyObj(this.props.data.contents);
contents.groups = contents.groups.map(g => {
delete g['outputs'];
return g;
......@@ -177,7 +177,7 @@ export class AlgorithmEditor extends React.Component<Props, State> {
// toggles the algorithm to a normal algorithm
changeToNormal = () => {
const contents = jsonClone(this.props.data.contents);
const contents = copyObj(this.props.data.contents);
delete contents.results;
if(contents.groups.length > 0)
contents.groups[0].outputs = {};
......
......@@ -29,7 +29,7 @@ import { connect } from 'react-redux';
import './DatabaseEditor.css';
import { changeObjFieldName, jsonClone } from '@helpers';
import { changeObjFieldName, copyObj } from '@helpers';
import { getValidDatabaseObj as getValidObj } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
......@@ -209,7 +209,7 @@ export class DatabaseEditor extends React.Component<Props, State> {
<Button outline color='secondary'
onClick={e => {
const newSets = [...protocol.sets];
newSets.splice(i + 1, 0, jsonClone(currSet));
newSets.splice(i + 1, 0, copyObj(currSet));
this.updateProtocol(
index,
......@@ -591,7 +591,7 @@ export class DatabaseEditor extends React.Component<Props, State> {
protocols.splice(
protocolIdx + 1,
0,
jsonClone(protocol)
copyObj(protocol)
);
this.setContents({
......@@ -675,7 +675,7 @@ export class DatabaseEditor extends React.Component<Props, State> {
<Button size='sm' outline color='secondary'
onClick={e => {
const newSets = [...p.sets];
newSets.splice(j + 1, 0, jsonClone(s));
newSets.splice(j + 1, 0, copyObj(s));
this.updateProtocol(
i,
......@@ -755,7 +755,7 @@ export class DatabaseEditor extends React.Component<Props, State> {
protocols.splice(
protocolIdx + 1,
0,
jsonClone(protocol)
copyObj(protocol)
);
this.setContents({
......
......@@ -37,7 +37,7 @@ import type {
BeatObject,
} from '@helpers/beat.js';
import { changeObjFieldName, generateNewKey, jsonClone } from '@helpers';
import { changeObjFieldName, generateNewKey, copyObj } from '@helpers';
type Props = {
data: BeatObject,
......
......@@ -31,7 +31,7 @@ import lev from 'fast-levenshtein';
import './ExperimentEditor.css';
import { getValidExperimentObj as getValidObj, expGetDefaultParameterValue as getDefaultParameterValue } from '@helpers/beat';
import type { BeatObject, ParameterValue, BeatEnvironment } from '@helpers/beat';
import { changeObjFieldName, sortObject, jsonClone } from '@helpers';
import { changeObjFieldName, sortObject, copyObj } from '@helpers';
import * as Selectors from '@store/selectors.js';
import * as Actions from '@store/actions.js';
......@@ -800,7 +800,7 @@ export class ExperimentEditor extends React.Component<Props, State> {
queue: queue,
});
else {
const newBlock = jsonClone(block);
const newBlock = copyObj(block);
delete newBlock.environment;
delete newBlock.queue;
updateBlock(newBlock);
......
......@@ -25,7 +25,7 @@ import { connect } from 'react-redux';
import { getValidLibraryObj as getValidObj } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
import { changeObjFieldName, jsonClone } from '@helpers';
import { changeObjFieldName, copyObj } from '@helpers';
import * as Selectors from '@store/selectors.js';
import { debounce } from 'throttle-debounce';
......
......@@ -17,7 +17,7 @@ import { connect } from 'react-redux';
import cn from 'classnames';
import { changeObjFieldName, generateNewKey, jsonClone } from '@helpers';
import { changeObjFieldName, generateNewKey, copyObj } from '@helpers';
import { BUILTIN_TYPES, ANALYZER_RESULT_TYPES, getValidPlotterObj as getValidObj } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
......@@ -78,7 +78,7 @@ export class PlotterEditor extends React.Component<Props, State> {
// renames a parameter (provide name & value & the old name)
// deletes a parameter (provide null as name, value is optional, the name)
updateParameter = (name: null | string, value: any, oldName: ?string) => {
const params = jsonClone(this.props.data.contents.parameters);
const params = copyObj(this.props.data.contents.parameters);
if(oldName)
delete params[oldName];
if(name !== null)
......
......@@ -17,7 +17,7 @@ import { connect } from 'react-redux';
import cn from 'classnames';
import { changeObjFieldName, generateNewKey, jsonClone } from '@helpers';
import { changeObjFieldName, generateNewKey, copyObj } from '@helpers';
import { BUILTIN_TYPES, ANALYZER_RESULT_TYPES, getValidPlotterparameterObj as getValidObj, expGetDefaultParameterValue as getDefaultParameterValue } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
......
......@@ -29,7 +29,7 @@ import {
import { connect } from 'react-redux';
import { ContextMenu, MenuItem, ContextMenuTrigger, SubMenu } from 'react-contextmenu';
import { getRandomBrightColor, generateNewKey, jsonClone } from '@helpers';
import { getRandomBrightColor, generateNewKey, copyObj } from '@helpers';
import { getValidToolchainObj as getValidObj } from '@helpers/beat';
import type { BeatObject } from '@helpers/beat';
import { fetchLayout, genModuleApiFuncs } from '@helpers/api';
......@@ -105,7 +105,7 @@ const generateNewHistory = (state: State, data: any): History => {
return {
past: [
...state.history.past,
jsonClone(data),
copyObj(data),
],
future: [],
};
......@@ -182,7 +182,7 @@ export class ToolchainEditor extends React.PureComponent<Props, State> {
const newPast = [...this.state.history.past];
const newData = newPast.pop();
const newFuture = [...this.state.history.future, jsonClone(this.props.data)];
const newFuture = [...this.state.history.future, copyObj(this.props.data)];
this.setState({
history: {
past: newPast,
......@@ -207,7 +207,7 @@ export class ToolchainEditor extends React.PureComponent<Props, State> {
const newFuture = [...this.state.history.future];
const newData = newFuture.pop();
const newPast = [...this.state.history.past, jsonClone(this.props.data)];
const newPast = [...this.state.history.past, copyObj(this.props.data)];
this.setState({
history: {
past: newPast,
......@@ -583,7 +583,7 @@ export class ToolchainEditor extends React.PureComponent<Props, State> {
// as well as any connections to/from it
// if it was the sole member of a group, deletes the group too
deleteBlocks = (names: string[]) => {
const rep = jsonClone(this.props.data.contents.representation);
const rep = copyObj(this.props.data.contents.representation);
names.forEach(name => {
delete rep.blocks[name];
......
// @flow
// BEAT-specific helpers
import { jsonClone } from '.';
import { copyObj } from '.';
// all the BEAT entities
export type BeatEntity = 'database' | 'library' | 'dataformat' | 'algorithm' | 'toolchain' | 'experiment' | 'plotter' | 'plotterparameter';
......@@ -258,7 +258,7 @@ export const getValidAlgorithmObj = (data: BeatObject = {name: '', contents: {}}
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......@@ -284,7 +284,7 @@ export const getValidDatabaseObj = (data: BeatObject = {name: '', contents: {}})
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
if(Array.isArray(getObj.contents.protocols)){
......@@ -312,7 +312,7 @@ export const getValidDataformatObj = (data: BeatObject = {name: '', contents: {}
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......@@ -353,7 +353,7 @@ export const getValidExperimentObj = (data: BeatObject = {name: '', contents: {}
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
getObj.contents.datasets = getObj.contents.datasets || {};
......@@ -428,7 +428,7 @@ export const getValidLibraryObj = (data: BeatObject = {name: '', contents: {}})
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......@@ -449,7 +449,7 @@ export const getValidToolchainObj = (data: BeatObject = {name: '', contents: {}}
name: '',
contents: {},
extraContents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......@@ -480,7 +480,7 @@ export const getValidPlotterObj = (data: BeatObject = {name: '', contents: {}})
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......@@ -502,7 +502,7 @@ export const getValidPlotterparameterObj = (data: BeatObject = {name: '', conten
const getObj = {
name: '',
contents: {},
...jsonClone(data)
...copyObj(data)
};
const obj = {
......
// @flow
// basic helpers - common bits of code refactored to DRY
import copy from 'fast-copy';
// changes a field in an object to a different name
// only required because keys are often mutable
......@@ -48,9 +49,8 @@ export const sortObject = (o: any) => Object.entries(o)
.sort(([n1, v1], [n2, v2]) => n1 > n2 ? 1 : -1)
.reduce((o, [n, v]) => ({...o, [n]: Object((v: any)) === v ? sortObject(v) : v}), {});
// clones a JSON obj via stringify/parse
export const jsonClone = (any: any) => {
return JSON.parse(JSON.stringify(any));
export const copyObj = (any: any) => {
return copy(any);
};
export type GenericObject = {[string]: any};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment