Releases: seasonedcc/composable-functions
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
throw
a string or any object that does not extendError
, the message in theResult
type 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.
v2.6.0
v2.5.4
v2.5.1
What's Changed
Full Changelog: v2.5.0...v2.5.1
v2.5.0
What's Changed
- feat: Add async capabilities for the trace function by @gustavoguichard in #116
Full Changelog: v2.4.0...v2.5.0
v2.4.0
What's Changed
The zod peer dependency is now gone. This is a backwards compatible change since we still use a subtype of zod parsers and will keep tracking zod interface as our de-facto standard. However, this opens the possibility of adaptors for other libraries as well.
Full Changelog: v2.3.0...v2.4.0
v2.3.0 - "Conditional `pipe`" and `mdf` alias ✂️
New Features
- We now export
mdf
alias formakeDomainFunction
so your compositions will look less verbose by @gustavoguichard in #111 - Improved
branch
method to act like conditionalpipe
by @gustavoguichard in #112
You can now conditionally pipe
by returning null
from a branch
, e.g:
// Check out the new `mdf` alias!
import { mdf, branch } from 'domain-functions'
import z from 'zod'
const a = mdf()(Math.random)
const b = mdf(z.number())(String)
// This function will only pipe to `b` if the output of `a` is greater than 0.5
const df = branch(a, output => output > 0.5 ? b : null)
// ^? DomainFunction<number | string>
The branch
method will keep working as always if you return other domain functions from it:
import { mdf, branch } from 'domain-functions'
const a = mdf()(Math.random)
const b = mdf()(() => 'high')
const c = mdf()(() => 'low')
const df = branch(a, output => output > 0.5 ? b : c)
// ^? DomainFunction<'high' | 'low'>
Other changes
- Expose and add JSDocs to
safeResult
to allow people to build their own combinators by @gustavoguichard in #110
Full Changelog: v2.0.0...v2.3.0
v2.2.0 - Rollback @decs/typeschema 😅
What's Changed
In version 2.1.0 we released the possibility of using domain-functions with other schema validation libraries through @decs/typeschema but we missed a breaking change due to optional peerDependencies on typeschema that would require bundler configuration changes or installing a bunch of peerDependencies on each project.
We are rolling back indeterminately.
domain-functions v2 🎉
🔥 Breaking changes
- Removed the
qs
dependency so someinputRessolvers
might return different results for a few edge cases. - Removed
errorMessagesForSchema
, it seems to be used only inremix-forms
. We will move this code there. - Removed deprecated types
List
andListToResultData
, check #101
😎 New feature
- The bundle size was reduced from 37.9kB (11.4kB gzipped) to 5.7kB (1.8kB gzipped) 🧙🏿♂️.
collectSequence
combinator. It is a sequential version of collect and uses the input object keys' order to determine the sequence of functions to be called.- DX improvement: JSDocs with inline documentation of every public method #90
🧹 Housekeeping
- Use a
test-prelude
to keep test imports in a central location, also upgrade our std library version used for testing. - We've updated our Remix example with newer remix versions and domain-functions conventions. #93
- We simplified the implementation of some combinators #89 and #87
Full Changelog: v1.8.0...v2.0.0