- Automatic isomorphism checks ensures that encoding and decoding are isomorphic.
- Composable Ema apps
- There are two ways of composing Ema apps. Using heterogenous lists (see `Ema.Multi`), or by defining a top-level route type (see `Ex04_Multi.hs`).
- Replace `LVar` with `Dynamic`.
- Ema still uses `LVar` internally (for live server updates), but on the user-side one only needs to provide a `Dynamic` which is a tuple of initial value and an updating function. The [unionmount](https://github.com/srid/unionmount/pull/1) library was changed to provide this tuple.
- Add `EmaSite` typeclass to "connect them all"
-`SiteArg`: Type of value to pass from the environment.
-`siteInput`: Define the `Dynamic` model for the site.
-`siteOutput`: Asset (eg: HTML) to produce for each route.
- Introduce the `Asset` type to distinguishing between static files and generated files. The later can be one of `Html` or `Other`, allowing the live server to handle them sensibly.
-`Ema` typeclass:
- Drop `staticAssets` in favour of `allRoutes` (renamed from `staticRoutes`) returning all routes including both generated and static routes.
- Drop `Slug` and use plain `FilePath`. Route encoder and decoder deal directly with the on-disk path of the generated (or static) files.
- Make the render function (which `runEma` takes) return a `Asset LByteString` instead of `LByteString` such that it can handle all routes, and handle static files as well as generation of non-HTML content (eg: RSS)
- now returns relative URLs (ie. without the leading `/`)
- Use the `<base>` tag to specify an explicit prefix for relative URLs in generated HTML. This way hosting on GitHub Pages without CNAME will continue to have functional links.
- Now takes the `model` type as argument, inasmuch as `encodeRoute` takes it as as well (to accomodate scenarios where route path can only be computed depending on model state; storing slug aliases for instance)