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

BREAKING: A bridge to 2.0 #37

Closed
wants to merge 11 commits into from
Closed

BREAKING: A bridge to 2.0 #37

wants to merge 11 commits into from

Conversation

okwolf
Copy link
Owner

@okwolf okwolf commented Apr 29, 2018

The eventual goal of this is to provide support for as many Hyperapp 2.0 features as possible in order to assist with upgrading 1.0 apps. This PR is not the proper place to debate the merits of the new API, those discussions should continue in the hyperapp/hyperapp repo and Slack.

Instead - this should be focused on implementation issues with supporting 2.0 style in a 1.0 Hyperapp.

This PR is still in an early stage, but so far has support for:

  • Interop with { dispatch } returned from app
    • Similar in functionality to the 2.0 dispatch, but as a wired action
    • Can be called with action functions, a new state object, or fx
    • Or with a mix of new state, actions, and fx using an array as a poor tuple substitute (more powerful than the 2.0 RFC right now, allows any length n-tuple)
  • Event handlers in your view detect old event handlers if using a function that doesn't return a value
    • Otherwise, assume 2.0 usage and call dispatch with the value assigned to the handler - passing the event as the second parameter when using an action function
    • Old event handlers give a warning by default
  • Warnings when:
    • Still calling wired actions to inform the user they still have refactoring to do
    • The returned state from an action omits properties that were in the before state. This is a strong indication that the action is relying on a shallow merge
    • Still using lazy components/subviews
    • The warnings above can be turned into errors to enforce 2.0 compatibility with the new strictMode option
  • All existing fx except:
    • action since actions may be directly dispatched, this doesn't seem useful anymore
    • event since event handler actions already support receiving the event data and actions/fx that are returned from this will be dispatched
  • A basic logger can be attached to dispatch with the logger option. This should be replaced with an implementation of 2.0 middleware instead when ready

Unresolved issues

  • Although slices are removed without wired actions, shallow merge is still performed
    • There doesn't seem to be a way to remove this functionality via an HOA, and removing it from 1.0 entirely would be a breaking change
    • A warning was implemented to help address this (details above)
  • Should the current style of fx based on the existing 1.0 API still be separately maintained/supported?
  • What version number should this be released as?
  • This probably won't be 100% API compatible with custom fx built for 2.0
    • Since dispatch is implemented as a wired action, which is a unary function
    • Therefore dispatching actions that take a data/event argument wrap both in an object with a special property for this implementation
    • See makeDispatchAction in src/fxCreators.js
  • Docs need major updates
  • No subscriptions yet (sorry 😢)
    • But keydown and keyup probably should be converted to subs
  • No middleware yet
    • Need API defined

Examples

Let's start with the classic quote example (updated pen):

import { h, app } from 'hyperapp'
import { withFx, http } from '@hyperapp/fx'

const state = {
  quote: "Click here for quotes"
}

const quoteFetched = (state, [{ content: quote }]) => ({ quote })
// "tuple" for performing state update and fx together
const getQuote = [
  { quote: "..." },
  http(
    "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1",
    quoteFetched
  )
]

const view = state => <h1 onclick={getQuote}>{state.quote}</h1>

withFx(app)(
  state,
  // look ma, no wired actions!
  {},
  view,
  document.body
)

And now, our favorite counter example (go ahead and try it online):

import { h, app } from 'hyperapp'
import { withFx } from '@hyperapp/fx'

const state = {
  count: 0
}

const up = ({ count }) => ({ count: count + 1 })
const down = ({ count }) => ({ count: count - 1 })

const view = state => (
  <main>
    <h1>{state.count}</h1>
    <button onclick={down}>-</button>
    <button onclick={{ count: 0 }}>0</button>
    <button onclick={up}>+</button>
  </main>
)

// dispatch function for interop returned by app when wrapped in withFx
const { dispatch } = withFx(app)(
  state,
  // look ma, no wired actions!
  {},
  view,
  document.body
)

const double = ({ count }) => ({ count: count * 2 })
// dispatch supports replacing the entire state tree
dispatch({ count: 2 })
// state is now: { count: 2 }

// dispatch also supports action functions for modifying state
dispatch(double)
// state is now: { count: 4 }

@codecov
Copy link

codecov bot commented Apr 29, 2018

Codecov Report

Merging #37 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master    #37   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           6      6           
  Lines         141    138    -3     
  Branches       15     20    +5     
=====================================
- Hits          141    138    -3
Impacted Files Coverage Δ
src/dispatchLogger.js 100% <100%> (ø)
src/fxCreators.js 100% <100%> (ø) ⬆️
src/withFx.js 100% <100%> (ø) ⬆️
src/constants.js 100% <100%> (ø)
src/utils.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80d20cb...b8148bc. Read the comment docs.

okwolf added 2 commits April 29, 2018 00:58
also allow arrays again for dispatching a mix of actions and fx
@okwolf
Copy link
Owner Author

okwolf commented Sep 9, 2018

This effort has been superseded/ported to okwolf/hyperapp-compat now.

@okwolf okwolf closed this Sep 9, 2018
@okwolf okwolf deleted the zweibrücke branch September 9, 2018 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant