Releases: 92green/dataparcels
Named exports, modify methods, ParcelShape, new internal reducer
dataparcels
Contains #105, #117, #147, #150, #152, #154, #158, #159, #161, #162, #163, #164
Main points:
- Move from named exports (
import {Foo} from 'bar';
) to slash exports (import Foo from 'bar/Foo';
) to allow people to have smaller bundle sizes when they use less features. This convention will become more important as optional features like #123 and #124 are added - Clean up the modify methods API. This has been really confusing. Now we just have
.modifyDown()
and.modifyUp()
. If shape editing / deep editing is required, then a parcel shape updater can be imported viaimport shape from 'dataparcels/shape
and used like.modifyDown(shape(parcelShape => parcelShape))
- Use new change request reducer, and remove parts of the API that only existed to cope with the underlying flaws with the old reducer.
Fixes
- fix:
Parcel.toObject()
now turns arrays into objects as expected - fix: prevent value from being removed if
Parcel.initialMeta
is set #164 - fix: allow ParcelBoundary state to be ahead of the state of higher parcels even when
debounce
orhold
aren't being used. Previously a regular ParcelBoundary was fully locked to props, but some freedom to have the ParcelBoundary's state move forward is safe and also necessary for the intended pattern of usingmodifyUp
to cancel invalid values. - amend: fix a bug where ChangeRequestReducer's "parent actions" (swapPrev, swapNext, delete etc) wouldn't run pre and post functions on last keypathmodifier
Exports
- BREAKING CHANGE removed all named exports in favour of slash exports, expect for type exports.
- e.g.
import {Action} from 'dataparcels';
becomesimport Action from 'dataparcels/Action';
- e.g.
- BREAKING CHANGE
ActionCreators
is no longer exported fromdataparcels
- BREAKING CHANGE removed
type ParcelMetaUpdater
from named exports #154 - Add: Added types to exports
{ParcelCreateConfigType}
{ParcelShapeSetMeta}
{ParcelShapeValueUpdater}
{ParcelShapeUpdater}
{ParcelShapeConfigInternal}
{ParentType}
Parcel methods
- BREAKING CHANGE removed
Parcel config.debugRender
#159 - BREAKING CHANGE removed
Parcel.updateMeta()
#154 - BREAKING CHANGE removed
Parcel.matchPipe()
#152 - BREAKING CHANGE removed
Parcel.batch()
. UseParcel.update()
with shape updaters instead - BREAKING CHANGE removed
Parcel.modifyChange()
. UseParcel.modifyUp()
with shape updaters instead - BREAKING CHANGE removed
Parcel.batchAndReturn()
. - BREAKING CHANGE removed
Parcel.hasDispatched()
. Nothing should ever rely on this information, no Parcel should ever ask questions of their children. - BREAKING CHANGE removed
Parcel.setChangeRequestMeta()
. Seldom used feature that doesn't fit now thatParcel.batch()
is gone.- The use case for this has disappeared since field validation is going to be better handled in a
ParcelBoundaryHoc
- The use case for this has disappeared since field validation is going to be better handled in a
- BREAKING CHANGE removed
Parcel.ping()
#161 - Added
Parcel.children()
- returns the value's children as Parcels, in the current parent data container. - add:
Parcel.move()
#117 - Add: ability for
Parcel.push()
,Parcel.unshift()
,ParcelShape.push()
andParcelShape.unshift()
to accept multiple arguments #163
Parcel modify functions
- BREAKING CHANGE
Parcel.modifyValue
is now calledParcel.modifyDown
#147 - BREAKING CHANGE
Parcel.modifyChangeValue
is now calledParcel.modifyUp
#147 - BREAKING CHANGE
Parcel.modifyChangeBatch
has been removed #147 - Added ability for
Parcel.update()
,Parcel.modifyDown()
andParcel.modifyUp()
to accept parcel shape updaters.import shape from 'dataparcels/shape
;.modifyDown(shape(parcelShape => parcelShape))
- Added ability for
Parcel.modifyUp()
to return aCancelActionMarker
to cancel an action.import CancelActionMarker from 'dataparcels/CancelActionMarker
;.modifyUp(value => value !== "good" ? CancelActionMarker : value)
Actions, ChangeRequests and keyPathModifiers
- BREAKING CHANGE removed
Action.shouldBeSynchronous()
#161 - BREAKING CHANGE removed
ChangeRequest.shouldBeSynchronous()
#161 - Add:
Action.toJS()
now includeskeyPathModifiers
#105 - Refactor: "function modifiers" - actions and change requests and the reducer now use
ActionKeyPathModifier
s to store modifier functions directly on each action. This means that actions and change requests become truly re-runnable with different input data. A set of actions can be run through the reducer multiple times with different data and there wont be any accidental "caching" of derived data. #105 - Refactor: replace
Reducer
withChangeRequestReducer
which can handlekeyPathModifiers
. #105
ParcelShape
- Added
ParcelShape
(previously calledStaticParcel
) #150
react-dataparcels
Exports
- BREAKING CHANGE removed all named exports in favour of slash exports, expect for type exports.
- e.g.
import {Action} from 'react-dataparcels';
becomesimport Action from 'react-dataparcels/Action';
- e.g.
- BREAKING CHANGE
ActionCreators
is no longer exported fromreact-dataparcels
- BREAKING CHANGE removed
type ParcelMetaUpdater
from named exports #154
ParcelHoc
- BREAKING CHANGE removed
ParcelHoc config.debugRender
#159 - Add: Added types to exports
{ParcelCreateConfigType}
{ParcelShapeSetMeta}
{ParcelShapeValueUpdater}
{ParcelShapeUpdater}
{ParcelShapeConfigInternal}
{ParentType}
ParcelBoundary
- add:
Parcelboundary.keepState
.
react-dataparcels-drag
- Added
react-dataparcels-drag
, a plugin forreact-dataparcels
that adds drag and drop re-ordering of elements, using the wonderful react-sortable-hoc.
Repo
- Add size-limit to keep an eye on library bloat. Addresses #162
Fix: modifyValue and modifyChangeValue errors with warning
- fix: replace modifyValue and modifyChangeValue parent inequality errors with warnings in dev mode
This is a fix because this behaviour accidentally broke an untested use case, with no alternative. This underlying issue is being solved completely in release 0.18.0
.
ChangeRequest features, modify function safety, ParcelHoc API changes
Contains #132 #134 #135 #137 #138 #139
Current pre-release: v0.17.0-1 npm-tag@next
dataparcels
Fixes
- fix: add
babel-runtime
as a dependency so transpiled code does not requirebabel-runtime
to be coincidentally included as part of the greater project - fix: make
Parcel.isFirst()
andParcel.isLast()
cope with empty parent values
Modify methods
- BREAKING CHANGE renamed
Parcel.modifyChange()
toParcel.modifyChangeBatch()
- BREAKING CHANGE
modifyValue
andmodifyChangeValue
are now safe #131modifyValue()
's updater can not return a value that has children unless it is unchanged by the updater or is emptymodifyChangeValue()
's updater is passed a value that has children, it cannot return a value that has children unless it is unchanged by the updater- this is to ensure that values are not disassociated with their keys, and to ensure cannot be set on lower parcels that will be lost when changes come back up. The primary use case for these functions are for use with primitives, or setting undefined values to an empty parent data type.
- fix: add function hashers to modify methods #125
API correctness and completeness
- Fix:
Parcel.delete(key)
should be able to be used on non-indexed parent parcels #138 - BREAKING CHANGE removed
Parcel.dangerouslyReplace()
- add:
Parcel.spread()
andParcel.spreadDOM()
can now acceptnotFoundValue
ChangeRequest
- Add:
ChangeRequest.prevData
#138 - BREAKING CHANGE Renamed
ChangeRequest.data
toChangeRequest.nextData
#138 - BREAKING CHANGE Removed
ChangeRequest.value
andChangeRequest.meta
#138- Use
ChangeRequest.nextData.value
andChangeRequest.nextData.meta
instead
- Use
- Add:
ChangeRequest.hasValueChanged()
#134 - Add:
ChangeRequest.shouldBeSynchronous()
- Add:
ChangeRequest.getDataIn()
react-dataparcels
-
BREAKING CHANGE:
ParcelHoc.config.valueFromProps
is no longer optional -
BREAKING CHANGE:
ParcelHoc.config.shouldParcelUpdateFromProps
now passes props,
not values. It also provides the ParcelHoc'svalueFromProps
as an argument.- Old:
shouldParcelUpdateFromProps(prevValue, nextValue)
- New:
shouldParcelUpdateFromProps(prevProps, nextProps, valueFromProps)
- Upgrade example:
- Old:
shouldParcelUpdateFromProps(prevValue, nextValue) => prevValue !== nextValue
- New:
shouldParcelUpdateFromProps(prevProps, nextProps, valueFromProps) => valueFromProps(prevValue) !== valueFromProps(nextValue)
- Old:
- Old:
-
BREAKING CHANGE
ParcelBoundary
andParcelBoundaryHoc
now usegetDerivedStateFromProps
. Use https://github.com/reactjs/react-lifecycles-compat if you're on a React version earlier than 16.3.0 -
fix:
ParcelBoundary
should return null fromgetDerivedStateFromProps
, not undefined. -
fix: add
babel-runtime
as a dependency so transpiled code does not requirebabel-runtime
to be coincidentally included as part of the greater project -
Add
buffered
boolean to ParcelBoundary childRenderer arguments to indicate when there are buffered changes that havent been sent up yet- good for save buttons that only show when there are changes to save
-
Add
${name}Buffered
boolean to ParcelBoundaryHoc child props
Fix insertAfter, insertBefore, swap, sawpPrev, swapNext on element parcels directly within parcel boundary
dataparcels
Last release introduced a bug where insertAfter
, insertBefore
, swap
, swapNext
and swapPrev
on element parcel directly inside a ParcelBoundary
would error out, because these actions were set to throw errors when not enough keys were provided in the actions keyPath
. At the time these action are called that is correct, there aren't enough keys provided for a meaningful change of data to take place, at least not until the change propagates up to the parent. The ParcelBoundary
ran each of these through the reducer while having "not enough keys", and this resulted in an error that would also have been previously caught in an empty try catch block that used to be around the reducer, presumably for this purpose.
It's more correct for the reducer to return the unchanged data of the element in question, rather than throwing an error.
ParcelBoundaryHoc, ParcelHoc.shouldParcelUpdateFromProps, Parcel.matchPipe
Contains #107 #109 #111 #113 #115 #121 #126 #130
Current pre-release: v0.16.0-3 npm-tag@next
dataparcels
- BREAKING CHANGE Removed
Parcel.addModifier()
- BREAKING CHANGE Removed
Parcel.addDescendantModifier()
- fix:
modifyValue
changing type no longer breaks the reducer #118 - fix: remove needless error swallower around parcel reducer call for
handleChange
calls - Fix: export a more correct and complete set of types
- Fix:
Parcel._boundarySplit()
was not using_this._treeshare.boundarySplit()
- fix: only unmutable writeable data types are now considered parent parcel types #122
- this is because it doesn't make sense to allow people to
get()
something that cannot beset
- this is because it doesn't make sense to allow people to
- fix: flow types
- Add
Parcel.toConsole()
to log a parcel to the console - Add
Parcel.batchAndReturn
only on top level parcels- Calls
batch()
but returns the parcel instead of callinghandleChange
- Calls
- Add
Parcel.matchPipe()
- Similar to
Parcel.pipe()
but automatically applies the updaters to new parcels whenever they are created and when the providedmatch
rule is matched. matchPipe(match: string, ...updaters: Array<(parcel: Parcel) => Parcel>): Parcel
- Match string examples:
- Match current parcel location only:
.
- Match child parcels only
.*
- Match child parcels with a key of "abc":
.abc
- Match child parcels whose key ends with "date":
.*date
- Match grandchild parcels only:
.*.*
- Match any descendant parcels with a key of "def":
**.def
- Match child parcels which are indexed:
.*:Indexed
- Match child parcels which are not indexed:
.*:!Indexed
- Match any descendant parcels which are elements":
**:Element
- Match either child parcels called "abc" or "def":
.abc|.def
- Match current parcel location only:
- You must escape
.
,|
,#
or:
with a preceding%
. e.g.{"dot.key"}
would be matched with.dot%.key
- Matching is always relative to the depth at which
matchPipe
was called.
- Similar to
- add: upgrade unmutable, unmutable compatible classes are now permitted as editable parent values
- add: add deleted marker to fix issue with errors being thrown when calling reducer on a deleted parcel
DeletedParcelMarker
now appears as avalue
when the parcel has been marked for deletion. It is a symbol that is exported fromdataparcels
likeimport {DeletedParcelMarker} from "dataparcels"
- refactor: allow for types to accept arrays
- refactor: move top level calculation out of
ParcelTypes
- refactor: Remove unused parcel properties
react-dataparcels
- BREAKING CHANGE
ParcelHoc config.initialValue
is now calledParcelHoc config.valueFromProps
- BREAKING CHANGE
ParcelHoc
now usesgetDerivedStateFromProps
. Use https://github.com/reactjs/react-lifecycles-compat if you're on a React version earlier than 16.3.0 - Fix: export a more correct and complete set of types
- Fix: Default behaviour for ParcelBoundary should be to clear the change buffer when a new parcel is received via props, as we can't assume the changes in the buffer are able to be applied to the new parcel's data.
- This will become the "replace" mergeMode in a later release: #110
- fix: pure parcel now updates if
isFirst()
orisLast()
change #119 - Redo all
ParcelBoundary
tests to avoidsetTimeout
or any nestedexpect
calls. - refactor: allow for types to accept arrays
- Add
ParcelBoundaryHoc
(#108) - Add
ParcelHoc config.shouldParcelUpdateFromProps
which allows a ParcelHoc to replace its parcel's contents based on prop changes. At this point the only option is to completely replace all of the parcels contents and delete all key and meta information, depending on the outcome of a boolean test. In future there will be more options to allow partial changes, and to allow key and meta data to be retained. - Add
ParcelBoundary.actions.cancel()
to be able to cancel changes in a parcel boundary - add
ParcelHoc
config.debugParcel
#86 - add
ParcelBoundary
debugParcel
- add: re-export
DeletedParcelMarker
fromdataparcels
dataparcels-docs
- Add
ParcelBoundary.childRenderer
docs - Add
ParcelBoundary.actions.cancel()
to docs - Add
ParcelBoundaryHoc
docs - Add child props to
ParcelHoc
andParcelBoundaryHoc
- Add new gifs to docs
other
- refactor: removed experimental
dataparcels-plugin-form
package
API changes, PureParcel > ParcelBoundary, perf gains
dataparcels
API design changes
- Removed "Self" methods and replaced with overloaded versions. This brings it much closer to Immutable.js and makes the size of the API a little more manageable.
- BREAKING CHANGE
setSelf()
is nowset()
with 1 argument - BREAKING CHANGE
updateSelf()
is nowupdate()
with 1 argument - BREAKING CHANGE
deleteSelf()
is nowdelete()
with 0 arguments - BREAKING CHANGE
insertAfterSelf()
is nowinsertAfter()
with 1 argument - BREAKING CHANGE
insertBeforeSelf()
is nowinsertBefore()
with 1 argument - BREAKING CHANGE
swapWithSelf()
is nowswap()
with 1 argument - BREAKING CHANGE
swapNextWithSelf()
is nowswapNext()
with 0 arguments - BREAKING CHANGE
swapPrevWithSelf()
is nowswapPrev()
with 0 arguments - BREAKING CHANGE
dangerouslyReplaceSelf()
is nowdangerouslyReplace()
- Added
deleteIn()
- BREAKING CHANGE
Fixes
- BUG FIX
set
actions (Parcel.set()
,Parcel.setSelf()
,Parcel.onChange()
) now remove all child info (#79), and auto-key their new contents - BUG FIX the changeRequest provided by
Parcel.handleChange
is now based, sodata
,value
andmeta
can be called on it. - BREAKING CHANGE
Parcel.addModifier()
andParcel.addDescendantModifier()
no longer mutate.
Features
- Add
Parcel.log()
for simplistic console.log()-ing of data and changes - Add
Parcel.spy()
for firing side effects as data moves downward - Add
Parcel.spyChange()
for firing side effects as changes move upward - Add
Parcel.isFirst()
to test if this parcel is the first of its siblings within the parent data structure - Add
Parcel.isLast()
to test if this parcel is the last of its siblings within the parent data structure - Add
ChangeRequest.toConsole()
Internal / performance
- Added
replace
action to replicate old behaviour ofset
. - Add
Parcel.dangerouslyReplaceSelf()
to replicate old behaviour ofParcel.setSelf()
. This will likely not last long in the public API. - Refactor parcelData functions
Parcel.toArray()
andParcel.toObject()
now around 12x faster (12x faster than the 10x fater improvements from last week)Parcel.get()
,Parcel.getIn()
andParcel.has()
now around 7x faster- 1x - 5x speed improvements all round for all change functions
- Remove internal tests for parcelData, as all behaviour is tested through Reducer tests which is way easier to reason about and keeps parcelData features relevant only to whatever the Reducer uses internally.
- Add caching (memoizing) to
ChangeRequest.data
/ChangeRequest.value
/ChangeRequest.meta
- Increase speed of Parcel constructor by rewriting
parcelId.setTypeCode
react-dataparcels
- BREAKING CHANGE Rename
PureParcel
toParcelBoundary
- Add
ParcelBoundary.pure
prop (defaults to true) to enable or disable pure rendering - Add
ParcelBoundary.debugBuffer
(defaults to false) to console.log() the ParcelBoundary buffer - Add
ParcelBoundary.hold
prop (defaults to false) to stop automatic propagation of changes - Add
ParcelBoundary.children(..., actions)
actions object which containsrelease()
- call this to immediately flush the change buffer.
- Improve buffering so changes are kept discrete until released upward.
Package rename, getters, perf gains, ParcelHoc features, better docs
- Add docs
- Upgrade
blueflag-test
, usejest
for testing now. - Rename repos and packages
parcels
is nowdataparcels
parcels-react
is nowreact-dataparcels
parcels-plugin-form
is nowdataparcels-plugin-form
dataparcels
- BREAKING CHANGE
Parcel.raw()
is removed, andParcel.data()
now works likeParcel.raw()
used to. Less confusing API to have a single way of getting all parcel data at once. - BREAKING CHANGE The following methods are now getters (#74):
Parcel.value()
has been replaced withParcel.value
Parcel.meta()
has been replaced withParcel.meta
Parcel.data()
has been replaced withParcel.data
Parcel.key()
has been replaced withParcel.key
Parcel.id()
has been replaced withParcel.id
Parcel.path()
has been replaced withParcel.path
ChangeRequest.value()
has been replaced withChangeRequest.value
ChangeRequest.meta()
has been replaced withChangeRequest.meta
ChangeRequest.data()
has been replaced withChangeRequest.data
ChangeRequest.changeRequestMeta()
has been replaced withChangeRequest.changeRequestMeta
ChangeRequest.originId()
has been replaced withChangeRequest.originId
ChangeRequest.originPath()
has been replaced withChangeRequest.originPath
- BREAKING CHANGE
Parcel.modifyData()
has been removed. - BREAKING CHANGE
Parcel.modify()
has been renamed toParcel.pipe()
. - BREAKING CHANGE
ChangeRequest.setBaseParcel()
has been removed (made "private").
Performance improvements
- Improve performance for
Parcel.get()
,Parcel.getIn()
,Parcel.toObject()
andParcel.toArray()
vastly for indexed values (around 10x faster)
react-dataparcels
- BREAKING CHANGE Rename
ParcelStateHock
toParcelHoc
- BREAKING CHANGE Rename
ParcelHoc config.prop
toParcelHoc config.name
- Add
ParcelHoc config.onChange
- Accepts
(props) => (value) => void
, fires when the parcel changes value - We can now emulate uncontrolled components
- Accepts
- Add
ParcelHoc config.delayUntil
(#80)- Accepts
(props) => boolean
, delays creation of the parcel until it returns true - We can now mount the
ParcelHoc
in a hock chain before initial value is ready to be called, wait for data, then make the parcel
- Accepts
dataparcels-plugin-form
- No change
dataparcels-docs
- Added docs
- Added array examples, more docs, more stubbed pages
- Improve docs layouts
- Fix anchor link bug on Parcel page
- Add
ParcelHoc
examples - Improve Getting Started examples
Find and replace
You'll probably need to find and replace things to upgrade to changes in the naming. These are the things you'll need to find. This is just a guide, running these replaces as-is will almost certainly get false positives:
parcels -> dataparcels
parcels-react -> react-dataparcels
parcels-plugin-form -> dataparcels-plugin-form
ParcelStateHock -> ParcelHoc
(ParcelHoc) prop: -> name:
(ParcelHoc) modify: -> pipe:
(Parcel) value() => value
(Parcel) meta() => meta
(Parcel) data() => data
(Parcel) raw() => data
(Parcel) id() => id
(Parcel) key() => key
(Parcel) path() => path
(ChangeRequest) value() => value
(ChangeRequest) meta() => meta
(ChangeRequest) data() => data
Indexed / Element Parcel fixes
- Fixed bug where actions would add their index to their actions keypath if
get()
was called called with an index, which would cause actions to take place on wrong elements if async actions were used with something likeParcel.toArray()
- Fixed bug where
Parcel.batch()
would run actions more than once in some cases, which posed a problem for non-idempotent actions - Fix bug where calling
Parcel.delete()
with a non existent key would delete the last element in the array - Better defined out of bounds and "key not found" behaviour for
Parcel.swapNext()
,Parcel.swapPrev()
,Parcel.insertBefore()
andParcel.insertAfter()
.- If the key is not found, these do nothing, and no longer throw an error
- If the index is >= length, or < negative length, the index will be wrapped
- This behaviour may change in future, but for now it is at least defined
- e.g ["A","B","C"] ...
delete(3)
would wrap around and delete "A"
- No breaking changes
Fix SubmitModifier
- Fix
SubmitModifier
, it was no longer submitting as it was not upgraded to use the newchangeRequest.changeRequestMeta()
function that the rest of0.13.2
was using. - No breaking changes
ChangeRequest improvements, ParcelStateHock.modify
parcels
Change Request Improvements
- Added
ChangeRequest.originId()
. This returns the id of the parcel that started the change. - Added
ChangeRequest.originPath()
. This returns the path of the parcel that started the change. - BREAKING CHANGE Renamed
ChangeRequest.meta()
toChangeRequest.changeRequestMeta()
- BREAKING CHANGE Renamed
ChangeRequest.setMeta()
toChangeRequest.setChangeRequestMeta()
- Added
ChangeRequest.value()
to getvalue
fromChangeRequest.data()
- BREAKING CHANGE Changed
ChangeRequest.meta()
to getmeta
fromChangeRequest.data()
Minor fixes
- Fix missing name in type checkers
Addresses #53
Sequential calls to ChangeRequest.data()
, ChangeRequest.meta()
and ChangeRequest.value()
will be a bit slow because they are calculated fresh each time by running all the actions through the reducer. Perf gains will happen in #56
parcels-react
- BREAKING CHANGE
ParcelStateHock
config variablemodify
now passesprops
andparcels
using partially applied functions:- Old:
ParcelStateHock({modify: (parcel) => parcel, ... })
- New:
ParcelStateHock({modify: (props) => (parcel) => parcel, ... })
- Old:
parcels-plugin-form
- No change