Skip to content

This Week in Effect - 2024-02-02

Hi Effecters! Welcome to the very first This Week In Effect (TWIE).

We’re proud to present you with this new format created to help you keep track of everything that is going on inside our Community and the Effect Ecosystem.

If it’s your first time here, Effect is a powerful TypeScript library designed to help developers create complex, synchronous, and asynchronous programs. One of the key features that sets Effect apart is how it leverages structured concurrency to provide features such as async cancellation and safe resource management, making it easier to build robust, scalable, and efficient programs.

To get started, below you’ll find links to our documentation as well as our guide for installing Effect. Enjoy!

Before we get into what happened in the last week in our Community, we would like to say a few words about TWIE.

We’re happy to witness the community growing so fast, with more and more people adopting Effect, and we understand that it might not be that easy keeping up with everything that is going on in the Effect Ecosystem:

  • Our Discord server reached 1850+ members a few days ago and the engagement is at an all-time high.
  • We’re approaching our very first Effect Days Conference in Vienna on February 23, 2024, and lots of new content is coming up.
  • All projects around Effect are receiving key updates and there has been a lot of activity on GitHub.

So, we wanted to make it easy for you to find all the info you need to fully enjoy your Effect journey!

And, that’s why we created TWIE – a weekly update to inform you about key events about Effect in the previous week, both from the community (Discord discussions, X posts, YouTube content etc.) and from a technical standpoint.

In this way, we want to help you stay on track with everything happening in the Effect Ecosystem and actively engage with our community.

So, let’s start!

Lists all the features, bug fixes, and changes (sometimes breaking) of this week.

This adds provenance for publishing packages.

Add JSDoc documentation for Effect.intoDeferred

Improves performance of computing a FiberId hash by caching the computation

Use TimeoutException for timeout, previously timeout used NoSuchElementException and it proved to be confusing and error-prone when using combinators such as Effect.optionFromOptional to recover from such exceptions.

The following code is now valid:

import { Effect } from "effect"
const recoverFromTimeout = Effect.sleep("2 seconds").pipe(
Effect.timeout("1 second"),
Effect.catchTag("TimeoutException", () =>
Effect.log("The program timed out")
)
)

With this change we remove the Data type and we make Equal & Hash implicit traits.

The main reason is that Data<A> was structurally equivalent to A & Equal but extending Equal doesn’t mean that the equality is implemented by-value, so the type was simply adding noise without gaining any level of safety.

The module Data remains unchanged at the value level, all the functions previously available are supposed to work in exactly the same manner.

At the type level instead the functions return Readonly variants, so for example we have:

import { Data } from "effect"
const obj = Data.struct({
a: 0,
b: 1
})

will have the obj typed as:

declare const obj: {
readonly a: number
readonly b: number
}

Improves naming of methods within the ReadonlyRecord module. Specifically, it renames ReadonlyRecord.upsert to ReadonlyRecord.set and ReadonlyRecord.update to ReadonlyRecord.replace. It also adds a new ReadonlyRecord.modify combinator that can be used to apply a function to the value of a ReadonlyRecord at a specific key.

Adds a new section to the project README that explains the annotations feature by showing how to customize the generation of Arbitrary<A> instances.

Reorganizes overloads in Schema.optional to improve development experience when specifying defaults.

Improves generation of Equivalence supporting cases where schemas include transformations. Namely the following code:

import { Schema } from "@effect/schema"
const schema = S.NumberFromString
const equivalence = E.make(schema)

No longer throws an error.

Add option to preserve excess properties when parsing, the feature is described in detail in the issue and can be summarized as:

const data = S.parseSync({
foo: S.string
})({
foo: "ok",
bar: "ok"
})

The above code will strip the bar property as it is not defined in the schema, with the additional option as below:

const data = S.parseSync({
foo: S.string
})(
{
foo: "ok",
bar: "ok"
},
{
onExcessProperty: "preserve"
}
)

The excess property is no longer removed.

Swaps the order of type parameters to simplify explicit type definitions, namely Schema<R, I, A> becomes Schema<A, I = A, R = never> this change also enables us to specify defaults for type parameters.

This enables to type simple schemas as:

import { Schema } from "@effect/schema"
declare const number: Schema<number>

and most importantly enables to ignore context when not needed like:

import { Schema } from "@effect/schema"
declare const numberFromString: Schema<number, string>

instead of being forced to write every parameter always like:

import { Schema } from "@effect/schema"
declare const number: Schema<never, number, number>

Ensuring that fibers forked in uninterruptible regions are able to be interrupted.

Use Proxy for platform schema Transferable.

Adds support for URL objects in HTTP Client, the following code is now valid:

import { HttpClientRequest, HttpClient } from "@effect/platform"
import { Effect } from "effect"
const request = HttpClientRequest.get(
new URL("https://www.google.com/")
).pipe(
HttpClient.fetchOk,
Effect.flatMap((_) => _.text)
)

Removes re-exports from @effect/platform-* packages and improves naming of specialized modules, generic modules like HttpClient can now be imported only from @effect/platform and specific modules like NodeRuntime can be imported from the specific platform package (in this case @effect/platform-node).

import { Runtime } from "@effect/platform-node"

becomes:

import { NodeRuntime } from "@effect/platform-node"

and:

import { HttpClient } from "@effect/platform-node"

becomes:

import { HttpClient } from "@effect/platform"

Fixes encoding of Transferable schemas, breaking because it includes a type-level change.

Ensuring that fibers forked in uninterruptible regions are able to be interrupted.

Ensures proper error reporting when a single input is provided to a variadic option. Prior, the check was silently skipped.

Fixes the README to update:

  • introduction of the executable parameter as CLI no longer needs to slice process.argv and automatically deals with executable path;
  • adds missing Args from the README example.

Guess what?! We welcomed 22 new Effecters last week! Thank you for joining the community and we look forward to your active participation in our ever-growing family!

Hear, hear! A big announcement from Vienna!

We’ve opened up 5 more spots for our Effect Days workshops on Feb 22nd! Both workshop and conference tickets are quickly running out, so don’t miss the opportunity to grab your own!

The Conference is quickly approaching, and we presented our final speaker: Tim Smart, Effect Core Contributor and founding engineer of Effectful Technologies!

So, here you can find our full speakers lineup for Vienna: Speakers

Moreover, as the 23rd come closer, our speakers are giving a a short video sneak peek of their speeches.

Here you’ll discover the one from Antoine Coulon:

and from Mattia Manzati:

That’s all for this week. Thank you for being a vital part of our community. Your feedback and requests are highly valued as we fine-tune this new format. Feel free to share your thoughts, and we’ll do our best to tailor it to the needs of our community.

The Effect Community Team