Releases: seasonedcc/composable-functions
Release list
v5.0.0 - Standard Schema 🦾
This release, despite being a major, shouldn't break most applications.
Now you can use any parser that is standard schema compliant. Which means you are not limited to Zod anymore.
This release requires minimum zod@3.24+ or any other parser that is ready for the spec.
We also don't export ParserSchema type anymore as now we are using StandardSchemaV1 type.
What's Changed
- Standard Schema Spec by @gustavoguichard in #170
Full Changelog: v4.5.0...v5.0.0
v4.5.0
What's Changed
- Include original input when mapping errors by @diogob in #168
- Update Remix example to RRv7 by @gustavoguichard in #169
Full Changelog: v4.4.0...v4.5.0
v4.4.0
What's Changed
We changed the context namespace to withContext because withContext.pipe is semantic and tells what it does more than context.pipe ;). You can still use the context until the next major but it is deprecated.
We now also enforce the no-implicity-any TS error in every combinator to solve #165
PRs
- Enforce no-implicit-any in every combinator by @gustavoguichard in #166
- Swap
contextnamespace forwithContextfor better clarity by @gustavoguichard in #167
Full Changelog: v4.3.0...v4.4.0
v4.3.0
What's Changed
We made applySchema work with plain functions. You don't have to wrap a function in composable anymore to apply a schema on it.
That means applySchema is virtually the same as withSchema which also means we can remove one of them.
In this version we decided to deprecate withSchema so we recommend that you start using applySchema instead. We will still export a deprecated version of withSchema which is just an alias to applySchema.
@diogob has also tweaked the types a lil bit so compositions should be more readable from this version onwards.
PRs
- Deprecate the environment namespace in favor of context by @gustavoguichard in #161
- Make the Composable type easier on the eyes by @diogob in #162
- Accept plain functions in
applySchemaand deprecateswithSchemaby @gustavoguichard in #164
Full Changelog: v4.2.0...v4.3.0
v4.2.0 - Accept plain functions in all combinators 🧘🏽
A step up in DX 🤌
From this version onwards we don't need to wrap every function in composable anymore.
Every combinator will accept plain functions and make composables out of them.
const add = (a: number, b: number) => a + b
// Before v4.2:
const fn = collect({ add: composable(add), toString: map(composable(add), String) })
// From v.4.2:
const fn = collect({ add, toString: map(add, String) })PRs
- Tighten function types by @diogob in #156
- Documentation for new Plain-functions feature by @gustavoguichard in #158
- Accept Plain functions in every combinator by @gustavoguichard in #155
- Accept plain functions in
branchResolver by @gustavoguichard in #159 - We want to be able to throw arbitrary values when using fromSuccess by @diogob in #160
Full Changelog: v4.1.0...v4.2.0
v3.1.0
v4.1.0
Main Changes
We realized that "environments" was a concept that was not easy to grasp so we renamed it to "context", which seems to fit more with "a value that is constant throughout compositions".
We renamed every instance of environment to context, including EnvironmentError - which is now ContextError -, and isEnvironmentError to isContextError.
The legacy functions and classes are deprecated but this change shouldn't be breaking as we only plan to get rid of them at v5.
What's Changed
- chore: Change ParserSchema type to be more conformant to both Zod and Arktype by @gustavoguichard in #151
- docs: Update Arktype schema by @gustavoguichard in #150
- Rename from
environmenttocontextby @gustavoguichard in #152
Full Changelog: v4.0.1...v4.1.0
v4.0.1
What's Changed
- Fix minor typos in migration guide by @corygibbons in #141
- README polish by @danielweinmann in #144
- No implicit any by @gustavoguichard in #147
- Explicit return types by @diogob in #143
- apply schema by @diogob in #148
- docs: Tidy up docs and return types by @gustavoguichard in #149
New Contributors
- @corygibbons made their first contribution in #141
Full Changelog: v4.0.0...v4.0.1
v4.0.0
Introducing Composable Functions 🎉
Today we are thrilled to announce the evolution of this library: composable-functions! 🤌
This library has been through a major revamp and it is now called composable functions.
Check out the README where there's a lot of new docs and guides on the new APIs, the benefits, and the incremental migration path from domain-functions to composable-functions.
v3.0.0
What's Changed
This is the last release for the package domain-functions.
From v4 onwards the package is called composable-functions.
This version was published to facilitate the incremental migration from one lib to another.
It should be a smooth upgrade and with this version the composable-functions library is already available, you should be able to work with both libraries in the same codebase.
To read more about the migration, check out the docs.
New migration helpers:
fromComposable: A function that turns a composable into a domain function at both type and runtime levels.
// In a module with a lot of domain functions
import { pipe, mdf, fromComposable } from 'domain-functions'
import { myFn } from './module-with-composables'
const fn = mdf()(() => "hello world")
const composition = pipe(fn, fromComposable(myFn))toComposable: A function to turn your domain functions into composables. It should work at both type and runtime levels.
// In a module with composables
import { pipe, composable } from 'composable-functions'
import { toComposable } from 'domain-functions'
import { myFn } from './module-with-dfs'
const fn = composable(() => "hello world")
const composition = pipe(fn, toComposable(myFn))Breaking changes
- If you
throwa string or any object that does not extendError, the message in theResulttype will be encoded asJSON.
const handler = mdf(z.object({ id: z.number() }))(() => {
throw 'Error'
})
const result = await handler({ id: 1 })
/* result will contain:
{
success: false,
errors: [{ message: '"Error"' }],
inputErrors: [],
environmentErrors: []
}
*/When throwing something like {aCustomObject: 'my message'} this would also be encoded in the message field.
The recommended solution is to use instances of Error, however, you can use something like result.errors.map((e) => {...e, message: JSON.parse(e.message)}) if this pattern is common in your code for a smooth migration.