Effect 3.6 (Release)
Effect 3.6 has been released! This release includes a number of new features and improvements. Here’s a summary of what’s new:
The DateTime
module provides functionality for working with time, including
support for time zones and daylight saving time.
It has two main data types: DateTime.Utc
and DateTime.Zoned
.
A DateTime.Utc
represents a time in Coordinated Universal Time (UTC), and
a DateTime.Zoned
contains both a UTC timestamp and a time zone.
There is also a CurrentTimeZone
service, for setting a time zone contextually.
1import { DateTime, Effect } from "effect"2
3Effect.gen(function* () {4 // Get the current time in the current time zone5 const now = yield* DateTime.nowInCurrentZone6
7 // Math functions are included8 const tomorrow = DateTime.add(now, { days: 1 })9
10 // Convert to a different time zone11 // The UTC portion of the `DateTime` is preserved and only the time zone is12 // changed13 const sydneyTime = tomorrow.pipe(14 DateTime.unsafeSetZoneNamed("Australia/Sydney"),15 )16}).pipe(DateTime.withCurrentZoneNamed("America/New_York"))
Stream.asyncPush
can be used to create a Stream
from an external push-based resource.
You can customize the buffer size and strategy by passing an object as the
second argument with the bufferSize
and strategy
fields.
1import { Effect, Stream } from "effect";2
3Stream.asyncPush<string>(4 (emit) =>5 Effect.acquireRelease(6 Effect.gen(function* () {7 yield* Effect.log("subscribing");8 return setInterval(() => emit.single("tick"), 1000);9 }),10 (handle) =>11 Effect.gen(function* () {12 yield* Effect.log("unsubscribing");13 clearInterval(handle);14 }),15 ),16 { bufferSize: 16, strategy: "dropping" },17);
To access the fully typed keys of a struct, you can use the Struct.keys
function.
1import { Struct } from "effect"2
3const symbol: unique symbol = Symbol()4
5const value = {6 a: 1,7 b: 2,8 [symbol]: 39}10
11const keys: Array<"a" | "b"> = Struct.keys(value)
The @effect/sql-kysely
package provides @effect/sql
integration with the kysely
query builder apis.
1// create a Tag with your `Database` type2class KyselyDB extends Context.Tag("KyselyDB")<KyselyDB, Kysely<Database>>() {}3
4Effect.gen(function*(_) {5 // access the service and execute queries6 const db = yield* KyselyDB7
8 yield* db.schema9 .createTable("users")10 .addColumn("id", "integer", (c) => c.primaryKey().autoIncrement())11 .addColumn("userName", "text", (c) => c.notNull())12
13 const inserted = yield* db.insertInto("users").values({ userName: "Alice" }).returningAll()14 const selected = yield* db.selectFrom("users").selectAll()15 const updated = yield* db.updateTable("users").set({ userName: "Bob" }).returningAll()16 const deleted = yield* db.deleteFrom("users").returningAll()17})
This api allows you to randomly select an item from an Iterable
.
Unless the Iterable
is “NonEmpty”, then the Effect can fail with a Cause.NoSuchElementException
.
1import { Random } from "effect"2
3Effect.gen(function* () {4 const randomItem = yield* Random.choice([1, 2, 3])5 console.log(randomItem)6})
If the onlyEffect
option for Effect.tap
is set to true
, then it will ensure the side effect only uses Effect
’s.
This can be useful when you want to add strictness to your program.
Refinements can now be used with Predicate.tuple
and Predicate.struct
to narrow the resulting type.
1import { Predicate } from "effect"2
3const isTrue = (u: unknown): u is true => u === true4
5// will narrow the type to { isTrue: true }6Predicate.struct({ isTrue })
Some new lifetime hook apis have been added to the Stream
module:
Stream.onStart
- run an effect when the stream startsStream.onEnd
- run an effect when the stream ends without error
There were several other smaller changes made. Take a look through the CHANGELOG to see them all: CHANGELOG.
Don’t forget to join our Discord Community to follow the last updates and discuss every tiny detail!