Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify updater #287

Merged
merged 18 commits into from Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 5 additions & 9 deletions packages/dataparcels/.size-limit.json
Expand Up @@ -15,6 +15,10 @@
"limit": "7.3 KB",
"path": "ChangeRequest.js"
},
{
"limit": "0.4 KB",
"path": "createUpdater.js"
},
{
"limit": "0.1 KB",
"path": "deleted.js"
Expand All @@ -25,18 +29,10 @@
},
{
"limit": "5.9 KB",
"path": "asNode.js"
},
{
"limit": "6.2 KB",
"path": "asChildNodes.js"
},
{
"limit": "0.1 KB",
"path": "asRaw.js"
},
{
"limit": "6.1 KB",
"limit": "2.2 KB",
"path": "translate.js"
},
{
Expand Down
14 changes: 4 additions & 10 deletions packages/dataparcels/__test__/Exports-test.js
Expand Up @@ -4,10 +4,9 @@
import Parcel from '../src/index';
import Action from '../Action';
import ChangeRequest from '../ChangeRequest';
import asRaw from '../asRaw';
import createUpdater from '../createUpdater';
import deleted from '../deleted';
import ParcelNode from '../ParcelNode';
import asNode from '../asNode';
import asChildNodes from '../asChildNodes';
import cancel from '../cancel';
import translate from '../translate';
Expand All @@ -19,10 +18,9 @@ import InternalParcel from '../src/parcel/Parcel';
// internal lib files
import InternalAction from '../lib/change/Action';
import InternalChangeRequest from '../lib/change/ChangeRequest';
import InternalUpdateRaw from '../lib/parcelData/asRaw';
import InternalCreateUpdater from '../lib/parcelData/createUpdater';
import Internaldeleted from '../lib/parcelData/deleted';
import InternalParcelNode from '../lib/parcelNode/ParcelNode';
import InternalAsNode from '../lib/parcelNode/asNode';
import InternalAsNodes from '../lib/parcelNode/asChildNodes';
import Internalcancel from '../lib/change/cancel';
import InternalTranslate from '../lib/modifiers/translate';
Expand All @@ -40,8 +38,8 @@ test('/ChangeRequest should export ChangeRequest', () => {
expect(ChangeRequest).toBe(InternalChangeRequest);
});

test('/asRaw should export asRaw', () => {
expect(asRaw).toBe(InternalUpdateRaw);
test('/createUpdater should export createUpdater', () => {
expect(createUpdater).toBe(InternalCreateUpdater);
});

test('/deleted should export deleted', () => {
Expand All @@ -52,10 +50,6 @@ test('/ParcelNode should export ParcelNode', () => {
expect(ParcelNode).toBe(InternalParcelNode);
});

test('/asNode should export asNode', () => {
expect(asNode).toBe(InternalAsNode);
});

test('/asChildNodes should export asChildNodes', () => {
expect(asChildNodes).toBe(InternalAsNodes);
});
Expand Down
2 changes: 0 additions & 2 deletions packages/dataparcels/asNode.js

This file was deleted.

2 changes: 0 additions & 2 deletions packages/dataparcels/asRaw.js

This file was deleted.

2 changes: 2 additions & 0 deletions packages/dataparcels/createUpdater.js
@@ -0,0 +1,2 @@
/* eslint-disable */
module.exports = require('./lib/parcelData/createUpdater.js').default;
3 changes: 1 addition & 2 deletions packages/dataparcels/package.json
Expand Up @@ -13,10 +13,9 @@
"lib",
"Action.js",
"asChildNodes.js",
"asNode.js",
"asRaw.js",
"cancel.js",
"ChangeRequest.js",
"createUpdater.js",
"deleted.js",
"ParcelNode.js",
"translate.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/dataparcels/src/change/ChangeRequestReducer.js
Expand Up @@ -33,7 +33,8 @@ const actionMap = {
swap, //: (lastKey, swapKey) => swap(lastKey, swapKey),
swapNext, //: (lastKey) => swapNext(lastKey),
swapPrev, //: (lastKey) => swapPrev(lastKey),
unshift: (lastKey, values) => unshift(...values)
unshift: (lastKey, values) => unshift(...values),
update: (lastKey, updater) => updater
};

const parentActionMap = {
Expand Down
Expand Up @@ -71,6 +71,12 @@ const ActionCreators = {
type: "unshift",
payload: values
});
},
update: (updater): Action => {
return new Action({
type: "update",
payload: updater
});
}
};

Expand Down Expand Up @@ -441,3 +447,29 @@ test('ChangeRequestReducer should process deep actions that are "parent actions"

expect(makeReducer(actions)(data).value).toEqual(expectedValue);
});

test('ChangeRequestReducer should process an "update" action', () => {
let updater = jest.fn(parcelData => ({
...parcelData,
value: parcelData.value * 2
}));

var data = {
value: 123,
key: "^",
child: undefined
};

let actions = [
ActionCreators.update(updater)
];

let expectedData = {
...data,
value: 246
};

expect(makeReducer(actions)(data)).toEqual(expectedData);
expect(updater).toHaveBeenCalledTimes(1);
expect(updater.mock.calls[0][0]).toEqual(data);
});
1 change: 0 additions & 1 deletion packages/dataparcels/src/errors/Errors.js
Expand Up @@ -7,4 +7,3 @@ export const ParcelTypeMethodMismatch = (key: string, parcelType: string, path:
export const ReducerInvalidActionError = (actionType: string) => new Error(`"${actionType}" is not a valid action`);
export const ReducerInvalidStepError = (stepType: string) => new Error(`"${stepType}" is not a valid action step type`);
export const ChangeRequestNoPrevDataError = () => new Error(`ChangeRequest data cannot be accessed before setting changeRequest.prevData`);
export const AsNodeReturnNonParcelNodeError = () => new Error(`The return value of an asNode() updater must be a ParcelNode`);
59 changes: 34 additions & 25 deletions packages/dataparcels/src/modifiers/translate.js
@@ -1,12 +1,12 @@
// @flow
import type Parcel from '../parcel/Parcel';
import type ChangeRequest from '../change/ChangeRequest';

import asNode from '../parcelNode/asNode';
import createUpdater from '../parcelData/createUpdater';
import update from 'unmutable/lib/update';

type Config = {
down?: (value: any) => any,
up?: (value: any, changeRequest: ChangeRequest) => any,
down?: (parcelData: any) => any,
up?: (parcelData: any) => any,
preserveInput?: boolean
};

Expand All @@ -17,31 +17,40 @@ export default (config: Config) => {
preserveInput
} = config;

let downValue = update('value', down);
let upValue = update('value', up);

if(!preserveInput) {
return (parcel: Parcel): Parcel => parcel
.modifyDown(down)
.modifyUp(up);
.modifyDown(downValue)
.modifyUp(upValue);
}

return (parcel: Parcel): Parcel => parcel
.modifyDown(asNode(node => {
if('translated' in node.meta) {
return node.update(() => node.meta.translated);
.modifyDown((parcelData) => {
if('translated' in parcelData.meta) {
return {
value: parcelData.meta.translated
};
}

return node
.update(down)
.setMeta({
untranslated: node.value
});
}))
.modifyUp(asNode((node) => {
let updated = node.update(up);

return updated
.setMeta({
translated: node.value,
untranslated: updated.value
});
}));
return createUpdater(
downValue,
() => ({
meta: {
untranslated: parcelData.value
}
})
)(parcelData);
})
.modifyUp((parcelData) => {
return createUpdater(
upValue,
({value}) => ({
meta: {
translated: parcelData.value,
untranslated: value
}
})
)(parcelData);
});
};
56 changes: 9 additions & 47 deletions packages/dataparcels/src/parcel/Parcel.js
Expand Up @@ -15,14 +15,13 @@ import type {ParentType} from '../types/Types';

import {ParcelTypeMethodMismatch} from '../errors/Errors';

import cancel from '../change/cancel';
import ChangeRequest from '../change/ChangeRequest';
import Action from '../change/Action';

import isIndexedValue from '../parcelData/isIndexedValue';
import isParentValue from '../parcelData/isParentValue';
import deleted from '../parcelData/deleted';
import prepUpdater from '../parcelData/prepUpdater';
import createUpdater from '../parcelData/createUpdater';
import setMetaDefault from '../parcelData/setMetaDefault';
import prepareChildKeys from '../parcelData/prepareChildKeys';
import keyOrIndexToKey from '../parcelData/keyOrIndexToKey';
Expand Down Expand Up @@ -109,10 +108,6 @@ export default class Parcel {
// Parent methods
has: Function;

// Side-effect methods
spy: Function;
spyChange: Function;

// Change methods
set: Function;
update: Function;
Expand Down Expand Up @@ -301,35 +296,14 @@ export default class Parcel {
return parcelHas(key)(this._parcelData);
});

// Side-effect methods

// Types(`spy()`, `sideEffect`, `function`)(sideEffect);
this.spy = (sideEffect: Function): Parcel => {
sideEffect(this);
return this;
};

// Types(`spyChange()`, `sideEffect`, `function`)(sideEffect);
this.spyChange = (sideEffect: Function): Parcel => {
return this._create({
rawId: this._idPushModifier('sc'),
updateChangeRequestOnDispatch: (changeRequest: ChangeRequest): ChangeRequest => {
let basedChangeRequest = changeRequest._create({
prevData: this.data
});
sideEffect(basedChangeRequest);
return changeRequest;
}
});
};

// Change methods

this.set = (value: any) => fireAction('set', value);

// Types(`update()`, `updater`, `function`)(updater);
this.update = (updater: ParcelValueUpdater) => {
fireAction('setData', prepUpdater(updater)(this._parcelData));
let preparedUpdater = createUpdater(updater);
fireAction('update', preparedUpdater);
};

this.delete = () => fireActionOnlyType(Child, 'delete');
Expand Down Expand Up @@ -373,32 +347,25 @@ export default class Parcel {

// Types(`modifyDown()`, `updater`, `function`)(updater);
this.modifyDown = (updater: ParcelValueUpdater): Parcel => {
let parcelDataUpdater = prepUpdater(updater);
let preparedUpdater = createUpdater(updater);
return this._create({
rawId: this._idPushModifierUpdater('md', updater),
parcelData: parcelDataUpdater(this._parcelData),
parcelData: preparedUpdater(this._parcelData),
updateChangeRequestOnDispatch: (changeRequest) => changeRequest._addStep({
type: 'md',
updater: parcelDataUpdater
updater: parcelData => preparedUpdater(parcelData)
})
});
};

// Types(`modifyUp()`, `updater`, `function`)(updater);
this.modifyUp = (updater: ParcelValueUpdater): Parcel => {
let parcelDataUpdater = (parcelData: ParcelData, changeRequest: ChangeRequest): ParcelData => {
let nextData = prepUpdater(updater)(parcelData, changeRequest);
if(nextData.value === cancel) {
throw new Error('CANCEL');
}
return nextData;
};

let preparedUpdater = createUpdater(updater);
return this._create({
rawId: this._idPushModifierUpdater('mu', updater),
updateChangeRequestOnDispatch: (changeRequest) => changeRequest._addStep({
type: 'mu',
updater: parcelDataUpdater,
updater: (parcelData, changeRequest) => preparedUpdater({...parcelData, changeRequest}),
changeRequest
})
});
Expand Down Expand Up @@ -623,12 +590,7 @@ export default class Parcel {
};

_idPushModifierUpdater = (prefix: string, updater: ParcelValueUpdater): string[] => {
let hash = (fn: Function): string => `${HashString(fn.toString())}`;
let id = updater._asRaw
? `s${hash(updater._updater || updater)}`
: hash(updater);

return this._idPushModifier(`${prefix}-${id}`);
return this._idPushModifier(`${prefix}-${HashString((updater._updater || updater).toString())}`);
};

// prepare child keys only once per parcel instance
Expand Down