Releases: AlexGalays/kaiju
0.28.1
Fixes
- Is it now possible to send a message synchronously from within connect():
function connect({ on, msg, state }: ConnectParams<{}, State>) {
on(refresh, () => ({ refreshed: true }))
msg.send(refresh())
}
Enhancements
- Calling the Component function now gives you a special VNode type with added properties. This is most useful in tests to read the component state in a type safe manner.
0.28.0
Breaking changes
The store/component state
is now passed to the connect
function, not to each individual message handler.
Before:
const click = Message<MouseEvent>('click')
function connect({ on }: ConnectParams<Props, State>) {
on(click, (state, evt) => ({ ...state, clicked: true }))
}
After:
const click = Message<MouseEvent>('click')
function connect({ on, state }: ConnectParams<Props, State>) {
on(click, evt => ({ ...state(), clicked: true }))
}
The state
parameter passed to the connect
function is an Observable
(just like props
). That means you can now derive state changes from... state changes! Of course, just like with Message sending, you have to break the recursion at some point.
For instance, given a Select component, you may want to listen to click events on the body to close the currently opened dropdown, but only if the Select is currently opened:
const click = Message<MouseEvent>('click')
function connect({ on, state }: ConnectParams<Props, State>) {
const clicksOutsideDropdown = state
.map(s => s.opened)
.distinct()
.flatmapLatest(opened => opened
? Observable.fromEvent('mousedown', document.body)
: Observable())
on(clicksOutsideDropdown , evt => ({ ...state(), opened: false }))
}
It can also be used to recompute dependent pieces of state in a single place (eg. a list and its dependent filtered/sorted list)
Message type simplification
Before, it was very confusing to know when to declare that a component expected its parent to provide it with a Message or a DefaultMessage. The types are now streamlined and conveniently packaged in the Message namespace:
Before:
NoArgMessage
DefaultNoArgMessage
Message<MouseEvent>
DefaultMessage<MouseEvent>
Message<[string, MouseEvent]>
DefaultMessage<[string, MouseEvent]>
After:
Message.NoPayload
Message.OnePayload<MouseEvent>
Message.TwoPayloads<string, MouseEvent>
For messages with two payloads, you no longer need to expect an Array inside your message handlers, just two distinct parameters.
Message creation is unchanged.
Non breaking enhancements
connectToStore
A component can connect to a store manually by reading the store's piece of data inside initState
and keeping it updated by subscribing to the store's state inside connect
. This will still work but is a bit cumbersome in the most simple cases as it duplicates the Store's state mapping logic and forces the component to treat a Store state piece as internal state even though it could be a regular props.
Enter connectToStore, inspired by redux: README
log
You can shut logs off for a particular component. This is mainly useful for boring higher order components:
function MyComponent() {
return Component<Props, State>({ name: 'myComponent', log: false, initState, connect, render })
}
example update
The example was updated to be simpler (and errr... easier to maintain)
0.27.4
0.27.3
- Fix circular dependency in observable package
- Fix the case where components' render function alternates between null and non null outputs
No breaking changes
0.27.2
Update to latest version of:
snabbdom
(0.6.9) and adjust for breaking changespace-lift
(0.3.1)
No breaking changes
0.27.1
Fix compilation errors with TS 2.4
No breaking changes.
0.26.0
Breaking enhancement
-
Observable->fromPromise now returns an Observable of Result rather than an ad-hoc object literal.
For more info about Result, see space-lift's Result
0.25.0
Breaking enhancement
- More precise typing for event handlers: You now have to specify the exact Event type on your Messages (
KeyboardEvent
,MouseEvent
,TouchEvent
, etc)
Before:
const click = Message<Event>('click')
function render() {
return h('button', { events: { click } })
}
After:
const click = Message<MouseEvent>('click')
function render() {
return h('button', { events: { click } })
}
There are no changes to be made for Messages with no payload like: const click = Message('click')
bug fix
- Fix touch events in the events module
0.24.2
Bug fix
- Fix destroy hooks when the output of a render method is an Array
0.24.1
Typing breaking changes
- More precise types for VNode.elm in different scenarios (introduce VNode.Assigned) For instance, a VNode's elm is always defined in some hooks, never defined in others.
If you're sure you have a VNode with a defined elm
, you can type it as VNode.Assigned
.
Enhancements
- Components' render can now also return null, undefined or ''. This is useful for higher order components.
Misc
- Example: Use CSS animations instead of WEB animations as the polyfill isn't great; introduce a Single child animation component