From 6bdb53e6e5800b23c27606ee7f665138aca93e64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 30 Aug 2024 09:30:07 +0000 Subject: [PATCH] Version Packages --- .changeset/chilled-toys-share.md | 5 - .changeset/curvy-cats-smoke.md | 5 - .changeset/curvy-clouds-battle.md | 10 - .changeset/dry-badgers-boil.md | 5 - .changeset/hot-dogs-mix.md | 5 - .changeset/rich-pumas-protect.md | 5 - .changeset/shiny-carpets-hunt.md | 29 - .changeset/short-garlics-vanish.md | 7 - .changeset/stream-race.md | 25 - .changeset/witty-kings-lie.md | 5 - .changeset/young-pugs-grow.md | 5 - packages/cli/CHANGELOG.md | 77 +- packages/cli/package.json | 2 +- packages/cluster-browser/CHANGELOG.md | 9 + packages/cluster-browser/package.json | 2 +- packages/cluster-node/CHANGELOG.md | 10 + packages/cluster-node/package.json | 2 +- packages/cluster-workflow/CHANGELOG.md | 10 + packages/cluster-workflow/package.json | 2 +- packages/cluster/CHANGELOG.md | 9 + packages/cluster/package.json | 2 +- packages/effect/CHANGELOG.md | 755 +++++---- packages/effect/package.json | 2 +- packages/effect/src/internal/version.ts | 2 +- packages/experimental/CHANGELOG.md | 174 +- packages/experimental/package.json | 2 +- packages/opentelemetry/CHANGELOG.md | 41 +- packages/opentelemetry/package.json | 2 +- packages/platform-browser/CHANGELOG.md | 98 +- packages/platform-browser/package.json | 2 +- packages/platform-bun/CHANGELOG.md | 143 +- packages/platform-bun/package.json | 2 +- packages/platform-node-shared/CHANGELOG.md | 108 +- packages/platform-node-shared/package.json | 2 +- packages/platform-node/CHANGELOG.md | 157 +- packages/platform-node/package.json | 2 +- packages/platform/CHANGELOG.md | 339 ++-- packages/platform/package.json | 2 +- packages/printer-ansi/CHANGELOG.md | 13 +- packages/printer-ansi/package.json | 2 +- packages/printer/CHANGELOG.md | 26 +- packages/printer/package.json | 2 +- packages/rpc-http/CHANGELOG.md | 60 +- packages/rpc-http/package.json | 2 +- packages/rpc/CHANGELOG.md | 75 +- packages/rpc/package.json | 2 +- packages/schema/CHANGELOG.md | 1450 ++++++++--------- packages/schema/package.json | 2 +- packages/sql-d1/CHANGELOG.md | 29 +- packages/sql-d1/package.json | 2 +- packages/sql-drizzle/CHANGELOG.md | 34 +- packages/sql-drizzle/package.json | 2 +- packages/sql-kysely/CHANGELOG.md | 8 + packages/sql-kysely/package.json | 2 +- packages/sql-mssql/CHANGELOG.md | 61 +- packages/sql-mssql/package.json | 2 +- packages/sql-mysql2/CHANGELOG.md | 61 +- packages/sql-mysql2/package.json | 2 +- packages/sql-pg/CHANGELOG.md | 61 +- packages/sql-pg/package.json | 2 +- packages/sql-sqlite-bun/CHANGELOG.md | 61 +- packages/sql-sqlite-bun/package.json | 2 +- packages/sql-sqlite-node/CHANGELOG.md | 61 +- packages/sql-sqlite-node/package.json | 2 +- packages/sql-sqlite-react-native/CHANGELOG.md | 60 +- packages/sql-sqlite-react-native/package.json | 2 +- packages/sql-sqlite-wasm/CHANGELOG.md | 60 +- packages/sql-sqlite-wasm/package.json | 2 +- packages/sql/CHANGELOG.md | 84 +- packages/sql/package.json | 2 +- packages/typeclass/CHANGELOG.md | 15 +- packages/typeclass/package.json | 2 +- packages/vitest/CHANGELOG.md | 41 +- packages/vitest/package.json | 2 +- 74 files changed, 2293 insertions(+), 2067 deletions(-) delete mode 100644 .changeset/chilled-toys-share.md delete mode 100644 .changeset/curvy-cats-smoke.md delete mode 100644 .changeset/curvy-clouds-battle.md delete mode 100644 .changeset/dry-badgers-boil.md delete mode 100644 .changeset/hot-dogs-mix.md delete mode 100644 .changeset/rich-pumas-protect.md delete mode 100644 .changeset/shiny-carpets-hunt.md delete mode 100644 .changeset/short-garlics-vanish.md delete mode 100644 .changeset/stream-race.md delete mode 100644 .changeset/witty-kings-lie.md delete mode 100644 .changeset/young-pugs-grow.md diff --git a/.changeset/chilled-toys-share.md b/.changeset/chilled-toys-share.md deleted file mode 100644 index 4fe8124432..0000000000 --- a/.changeset/chilled-toys-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": patch ---- - -add `Micro.isMicroCause` guard diff --git a/.changeset/curvy-cats-smoke.md b/.changeset/curvy-cats-smoke.md deleted file mode 100644 index bdd8ad2b3e..0000000000 --- a/.changeset/curvy-cats-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -preserve `Array.modify` `Array.modifyOption` non emptiness diff --git a/.changeset/curvy-clouds-battle.md b/.changeset/curvy-clouds-battle.md deleted file mode 100644 index 4621517e74..0000000000 --- a/.changeset/curvy-clouds-battle.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@effect/platform": patch ---- - -add HttpApi modules - -The `HttpApi` family of modules provide a declarative way to define HTTP APIs. - -For more infomation see the README.md for the /platform package:
-https://github.com/Effect-TS/effect/blob/main/packages/platform/README.md diff --git a/.changeset/dry-badgers-boil.md b/.changeset/dry-badgers-boil.md deleted file mode 100644 index f8faab1f3f..0000000000 --- a/.changeset/dry-badgers-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -improve: type Fiber.awaitAll as Exit[]. diff --git a/.changeset/hot-dogs-mix.md b/.changeset/hot-dogs-mix.md deleted file mode 100644 index c9a0549355..0000000000 --- a/.changeset/hot-dogs-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -New constructor Config.nonEmptyString diff --git a/.changeset/rich-pumas-protect.md b/.changeset/rich-pumas-protect.md deleted file mode 100644 index e8d499a826..0000000000 --- a/.changeset/rich-pumas-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -preserve `Array.replace` `Array.replaceOption` non emptiness diff --git a/.changeset/shiny-carpets-hunt.md b/.changeset/shiny-carpets-hunt.md deleted file mode 100644 index 243b351d34..0000000000 --- a/.changeset/shiny-carpets-hunt.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"effect": minor ---- - -add `Effect.bindAll` api - -This api allows you to combine `Effect.all` with `Effect.bind`. It is useful -when you want to concurrently run multiple effects and then combine their -results in a Do notation pipeline. - -```ts -import { Effect } from "effect"; - -const result = Effect.Do.pipe( - Effect.bind("x", () => Effect.succeed(2)), - Effect.bindAll( - ({ x }) => ({ - a: Effect.succeed(x + 1), - b: Effect.succeed("foo"), - }), - { concurrency: 2 }, - ), -); -assert.deepStrictEqual(Effect.runSync(result), { - x: 2, - a: 3, - b: "foo", -}); -``` diff --git a/.changeset/short-garlics-vanish.md b/.changeset/short-garlics-vanish.md deleted file mode 100644 index fb3a8dfdb8..0000000000 --- a/.changeset/short-garlics-vanish.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"effect": minor ---- - -add `propagateInterruption` option to Fiber{Handle,Set,Map} - -This option will send any external interrupts to the .join result. diff --git a/.changeset/stream-race.md b/.changeset/stream-race.md deleted file mode 100644 index 6d0509de99..0000000000 --- a/.changeset/stream-race.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"effect": minor ---- - - -feat(Stream): implement `race` operator, which accepts two upstreams and returns a stream that mirrors the first upstream to emit an item and interrupts the other upstream. - -```ts -import { Stream, Schedule, Console, Effect } from "effect" - -const stream = Stream.fromSchedule(Schedule.spaced('2 millis')).pipe( - Stream.race(Stream.fromSchedule(Schedule.spaced('1 millis'))), - Stream.take(6), - Stream.tap(n => Console.log(n)) -) - -Effect.runPromise(Stream.runDrain(stream)) -// Output each millisecond from the first stream, the rest streams are interrupted -// 0 -// 1 -// 2 -// 3 -// 4 -// 5 -``` \ No newline at end of file diff --git a/.changeset/witty-kings-lie.md b/.changeset/witty-kings-lie.md deleted file mode 100644 index ef1280e041..0000000000 --- a/.changeset/witty-kings-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -Avoid automatic propagation of finalizer concurrency, closes #3440 diff --git a/.changeset/young-pugs-grow.md b/.changeset/young-pugs-grow.md deleted file mode 100644 index d9aa6f49ff..0000000000 --- a/.changeset/young-pugs-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"effect": minor ---- - -add Context.getOrElse api, for gettings a Tag's value with a fallback diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 6e7ed9c39a..d25797a188 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @effect/cli +## 0.42.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/printer@0.35.0 + - @effect/printer-ansi@0.35.0 + - @effect/schema@0.72.0 + ## 0.41.5 ### Patch Changes @@ -389,18 +400,18 @@ handlers: { readonly render: ( state: State, - action: Action, - ) => Effect; + action: Action + ) => Effect readonly process: ( input: UserInput, - state: State, - ) => Effect, never, Environment>; + state: State + ) => Effect, never, Environment> readonly clear: ( state: State, - action: Action, - ) => Effect; - }, - ) => Prompt = InternalPrompt.custom; + action: Action + ) => Effect + } + ) => Prompt = InternalPrompt.custom ``` The initial state of a `Prompt` can either be a pure value or an `Effect`. This @@ -1133,8 +1144,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1501,9 +1512,9 @@ Along the same line of the other changes this allows to shorten the most common types such as: ```ts - import { Either } from "effect"; + import { Either } from "effect" - const right: Either.Either = Either.right("ok"); + const right: Either.Either = Either.right("ok") ``` ### Patch Changes @@ -1661,31 +1672,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1693,17 +1704,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1727,35 +1738,35 @@ At the type level instead the functions return `Readonly` variants, so for example we have: ```ts - import { Data } from "effect"; + import { Data } from "effect" const obj = Data.struct({ a: 0, - b: 1, - }); + b: 1 + }) ``` will have the `obj` typed as: ```ts declare const obj: { - readonly a: number; - readonly b: number; - }; + readonly a: number + readonly b: number + } ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/cli/package.json b/packages/cli/package.json index 49d203bca0..52ec7058ce 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@effect/cli", - "version": "0.41.5", + "version": "0.42.0", "type": "module", "license": "MIT", "description": "A library for building command-line interfaces with Effect", diff --git a/packages/cluster-browser/CHANGELOG.md b/packages/cluster-browser/CHANGELOG.md index 8c4945c2a3..e75d139b54 100644 --- a/packages/cluster-browser/CHANGELOG.md +++ b/packages/cluster-browser/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/cluster +## 0.5.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/rpc@0.37.0 + - @effect/schema@0.72.0 + ## 0.4.5 ### Patch Changes diff --git a/packages/cluster-browser/package.json b/packages/cluster-browser/package.json index 37cedcad7d..ce8f41e875 100644 --- a/packages/cluster-browser/package.json +++ b/packages/cluster-browser/package.json @@ -1,7 +1,7 @@ { "name": "@effect/cluster-browser", "type": "module", - "version": "0.4.5", + "version": "0.5.0", "description": "Unified interfaces for common cluster-browser-specific services", "publishConfig": { "access": "public", diff --git a/packages/cluster-node/CHANGELOG.md b/packages/cluster-node/CHANGELOG.md index d21ffc0c25..14f5ab6e61 100644 --- a/packages/cluster-node/CHANGELOG.md +++ b/packages/cluster-node/CHANGELOG.md @@ -1,5 +1,15 @@ # @effect/cluster +## 0.6.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/cluster@0.6.0 + - @effect/rpc@0.37.0 + - @effect/schema@0.72.0 + ## 0.5.7 ### Patch Changes diff --git a/packages/cluster-node/package.json b/packages/cluster-node/package.json index 7514aa55e9..cd7ab3e338 100644 --- a/packages/cluster-node/package.json +++ b/packages/cluster-node/package.json @@ -1,7 +1,7 @@ { "name": "@effect/cluster-node", "type": "module", - "version": "0.5.7", + "version": "0.6.0", "description": "Unified interfaces for common cluster-node-specific services", "publishConfig": { "access": "public", diff --git a/packages/cluster-workflow/CHANGELOG.md b/packages/cluster-workflow/CHANGELOG.md index 123bf44088..d5f9efa7fd 100644 --- a/packages/cluster-workflow/CHANGELOG.md +++ b/packages/cluster-workflow/CHANGELOG.md @@ -1,5 +1,15 @@ # @effect/cluster +## 0.5.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/cluster@0.6.0 + - @effect/schema@0.72.0 + - @effect/sql@0.10.0 + ## 0.4.7 ### Patch Changes diff --git a/packages/cluster-workflow/package.json b/packages/cluster-workflow/package.json index 28865e91a0..8d071fd749 100644 --- a/packages/cluster-workflow/package.json +++ b/packages/cluster-workflow/package.json @@ -1,7 +1,7 @@ { "name": "@effect/cluster-workflow", "type": "module", - "version": "0.4.7", + "version": "0.5.0", "description": "A workflow runtime using effect-cluster", "publishConfig": { "access": "public", diff --git a/packages/cluster/CHANGELOG.md b/packages/cluster/CHANGELOG.md index f0815bada1..a4d409bb86 100644 --- a/packages/cluster/CHANGELOG.md +++ b/packages/cluster/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/cluster +## 0.6.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/schema@0.72.0 + - @effect/sql@0.10.0 + ## 0.5.7 ### Patch Changes diff --git a/packages/cluster/package.json b/packages/cluster/package.json index f0f3ad4608..a9bd115ccf 100644 --- a/packages/cluster/package.json +++ b/packages/cluster/package.json @@ -1,7 +1,7 @@ { "name": "@effect/cluster", "type": "module", - "version": "0.5.7", + "version": "0.6.0", "description": "Unified interfaces for common cluster-specific services", "publishConfig": { "access": "public", diff --git a/packages/effect/CHANGELOG.md b/packages/effect/CHANGELOG.md index 28153b497e..bb7885cd8a 100644 --- a/packages/effect/CHANGELOG.md +++ b/packages/effect/CHANGELOG.md @@ -1,5 +1,76 @@ # effect +## 3.7.0 + +### Minor Changes + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92) Thanks @vinassefranche! - preserve `Array.modify` `Array.modifyOption` non emptiness + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9) Thanks @patroza! - improve: type Fiber.awaitAll as Exit[]. + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922) Thanks @titouancreach! - New constructor Config.nonEmptyString + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc) Thanks @KhraksMamtsov! - preserve `Array.replace` `Array.replaceOption` non emptiness + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d) Thanks @KhraksMamtsov! - add `Effect.bindAll` api + + This api allows you to combine `Effect.all` with `Effect.bind`. It is useful + when you want to concurrently run multiple effects and then combine their + results in a Do notation pipeline. + + ```ts + import { Effect } from "effect" + + const result = Effect.Do.pipe( + Effect.bind("x", () => Effect.succeed(2)), + Effect.bindAll( + ({ x }) => ({ + a: Effect.succeed(x + 1), + b: Effect.succeed("foo") + }), + { concurrency: 2 } + ) + ) + assert.deepStrictEqual(Effect.runSync(result), { + x: 2, + a: 3, + b: "foo" + }) + ``` + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4) Thanks @tim-smart! - add `propagateInterruption` option to Fiber{Handle,Set,Map} + + This option will send any external interrupts to the .join result. + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474) Thanks @dilame! - feat(Stream): implement `race` operator, which accepts two upstreams and returns a stream that mirrors the first upstream to emit an item and interrupts the other upstream. + + ```ts + import { Stream, Schedule, Console, Effect } from "effect" + + const stream = Stream.fromSchedule(Schedule.spaced("2 millis")).pipe( + Stream.race(Stream.fromSchedule(Schedule.spaced("1 millis"))), + Stream.take(6), + Stream.tap((n) => Console.log(n)) + ) + + Effect.runPromise(Stream.runDrain(stream)) + // Output each millisecond from the first stream, the rest streams are interrupted + // 0 + // 1 + // 2 + // 3 + // 4 + // 5 + ``` + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb) Thanks @mikearnaldi! - Avoid automatic propagation of finalizer concurrency, closes #3440 + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f) Thanks @tim-smart! - add Context.getOrElse api, for gettings a Tag's value with a fallback + +### Patch Changes + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe) Thanks @juliusmarminge! - add `Micro.isMicroCause` guard + ## 3.6.8 ### Patch Changes @@ -79,22 +150,22 @@ There is also a `CurrentTimeZone` service, for setting a time zone contextually. ```ts - import { DateTime, Effect } from "effect"; + import { DateTime, Effect } from "effect" Effect.gen(function* () { // Get the current time in the current time zone - const now = yield* DateTime.nowInCurrentZone; + const now = yield* DateTime.nowInCurrentZone // Math functions are included - const tomorrow = DateTime.add(now, 1, "day"); + const tomorrow = DateTime.add(now, 1, "day") // Convert to a different time zone // The UTC portion of the `DateTime` is preserved and only the time zone is // changed const sydneyTime = tomorrow.pipe( - DateTime.unsafeSetZoneNamed("Australia/Sydney"), - ); - }).pipe(DateTime.withCurrentZoneNamed("America/New_York")); + DateTime.unsafeSetZoneNamed("Australia/Sydney") + ) + }).pipe(DateTime.withCurrentZoneNamed("America/New_York")) ``` - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`cd255a4`](https://github.com/Effect-TS/effect/commit/cd255a48872d8fb924cf713ef73f0883a9cc6987) Thanks @tim-smart! - add Stream.asyncPush api @@ -110,50 +181,50 @@ second argument with the `bufferSize` and `strategy` fields. ```ts - import { Effect, Stream } from "effect"; + import { Effect, Stream } from "effect" Stream.asyncPush( (emit) => Effect.acquireRelease( Effect.gen(function* () { - yield* Effect.log("subscribing"); - return setInterval(() => emit.single("tick"), 1000); + yield* Effect.log("subscribing") + return setInterval(() => emit.single("tick"), 1000) }), (handle) => Effect.gen(function* () { - yield* Effect.log("unsubscribing"); - clearInterval(handle); - }), + yield* Effect.log("unsubscribing") + clearInterval(handle) + }) ), - { bufferSize: 16, strategy: "dropping" }, - ); + { bufferSize: 16, strategy: "dropping" } + ) ``` - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`3845646`](https://github.com/Effect-TS/effect/commit/3845646828e98f3c7cda1217f6cfe5f642ac0603) Thanks @mikearnaldi! - Implement Struct.keys as a typed alternative to Object.keys ```ts - import { Struct } from "effect"; + import { Struct } from "effect" - const symbol: unique symbol = Symbol(); + const symbol: unique symbol = Symbol() const value = { a: 1, b: 2, - [symbol]: 3, - }; + [symbol]: 3 + } - const keys: Array<"a" | "b"> = Struct.keys(value); + const keys: Array<"a" | "b"> = Struct.keys(value) ``` - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`2d09078`](https://github.com/Effect-TS/effect/commit/2d09078c5948b37fc2f79ef858fe4ca3e4814085) Thanks @sukovanej! - Add `Random.choice`. ```ts - import { Random } from "effect"; + import { Random } from "effect" Effect.gen(function* () { - const randomItem = yield* Random.choice([1, 2, 3]); - console.log(randomItem); - }); + const randomItem = yield* Random.choice([1, 2, 3]) + console.log(randomItem) + }) ``` - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`4bce5a0`](https://github.com/Effect-TS/effect/commit/4bce5a0274203550ccf117d830721891b0a3d182) Thanks @vinassefranche! - Add onlyEffect option to Effect.tap @@ -163,15 +234,15 @@ - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`e74cc38`](https://github.com/Effect-TS/effect/commit/e74cc38cb420a320c4d7ef98180f19d452a8b316) Thanks @dilame! - Implement `Stream.onEnd` that adds an effect to be executed at the end of the stream. ```ts - import { Console, Effect, Stream } from "effect"; + import { Console, Effect, Stream } from "effect" const stream = Stream.make(1, 2, 3).pipe( Stream.map((n) => n * 2), Stream.tap((n) => Console.log(`after mapping: ${n}`)), - Stream.onEnd(Console.log("Stream ended")), - ); + Stream.onEnd(Console.log("Stream ended")) + ) - Effect.runPromise(Stream.runCollect(stream)).then(console.log); + Effect.runPromise(Stream.runCollect(stream)).then(console.log) // after mapping: 2 // after mapping: 4 // after mapping: 6 @@ -182,15 +253,15 @@ - [#3380](https://github.com/Effect-TS/effect/pull/3380) [`bb069b4`](https://github.com/Effect-TS/effect/commit/bb069b49ef291c532a02c1e8e74271f6d1bb32ec) Thanks @dilame! - Implement `Stream.onStart` that adds an effect to be executed at the start of the stream. ```ts - import { Console, Effect, Stream } from "effect"; + import { Console, Effect, Stream } from "effect" const stream = Stream.make(1, 2, 3).pipe( Stream.onStart(Console.log("Stream started")), Stream.map((n) => n * 2), - Stream.tap((n) => Console.log(`after mapping: ${n}`)), - ); + Stream.tap((n) => Console.log(`after mapping: ${n}`)) + ) - Effect.runPromise(Stream.runCollect(stream)).then(console.log); + Effect.runPromise(Stream.runCollect(stream)).then(console.log) // Stream started // after mapping: 2 // after mapping: 4 @@ -213,16 +284,16 @@ These helpers can be used, for example, to extract the service shape from a tag: ```ts - import * as Context from "effect/Context"; + import * as Context from "effect/Context" export class Foo extends Context.Tag("Foo")< Foo, { - readonly foo: Effect.Effect; + readonly foo: Effect.Effect } >() {} - type ServiceShape = typeof Foo.Service; + type ServiceShape = typeof Foo.Service ``` - [#3373](https://github.com/Effect-TS/effect/pull/3373) [`f566fd1`](https://github.com/Effect-TS/effect/commit/f566fd1d7eea531a0d981dd24037f14a603a1273) Thanks @KhraksMamtsov! - Add test for Hash.number(0.1) !== Has.number(0) @@ -277,10 +348,10 @@ - [#3250](https://github.com/Effect-TS/effect/pull/3250) [`203658f`](https://github.com/Effect-TS/effect/commit/203658f8001c132b25764ab70344b171683b554c) Thanks @gcanti! - add support for `Refinement`s to `Predicate.or`, closes #3243 ```ts - import { Predicate } from "effect"; + import { Predicate } from "effect" // Refinement - const isStringOrNumber = Predicate.or(Predicate.isString, Predicate.isNumber); + const isStringOrNumber = Predicate.or(Predicate.isString, Predicate.isNumber) ``` - [#3246](https://github.com/Effect-TS/effect/pull/3246) [`eb1c4d4`](https://github.com/Effect-TS/effect/commit/eb1c4d44e54b9d8d201a366d1ff94face2a6dcd3) Thanks @tim-smart! - render nested causes in Cause.pretty @@ -330,41 +401,41 @@ The resource is lazily acquired on the first call to `get` and released when the last reference is released. ```ts - import { Effect, RcRef } from "effect"; + import { Effect, RcRef } from "effect" Effect.gen(function* () { const ref = yield* RcRef.make({ acquire: Effect.acquireRelease(Effect.succeed("foo"), () => - Effect.log("release foo"), - ), - }); + Effect.log("release foo") + ) + }) // will only acquire the resource once, and release it // when the scope is closed - yield* RcRef.get(ref).pipe(Effect.andThen(RcRef.get(ref)), Effect.scoped); - }); + yield* RcRef.get(ref).pipe(Effect.andThen(RcRef.get(ref)), Effect.scoped) + }) ``` - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`5ab348f`](https://github.com/Effect-TS/effect/commit/5ab348f265db3d283aa091ddca6d2d49137c16f2) Thanks @tim-smart! - allowing customizing Stream pubsub strategy ```ts - import { Schedule, Stream } from "effect"; + import { Schedule, Stream } from "effect" // toPubSub Stream.fromSchedule(Schedule.spaced(1000)).pipe( Stream.toPubSub({ capacity: 16, // or "unbounded" - strategy: "dropping", // or "sliding" / "suspend" - }), - ); + strategy: "dropping" // or "sliding" / "suspend" + }) + ) // also for the broadcast apis Stream.fromSchedule(Schedule.spaced(1000)).pipe( Stream.broadcastDynamic({ capacity: 16, - strategy: "dropping", - }), - ); + strategy: "dropping" + }) + ) ``` - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`60bc3d0`](https://github.com/Effect-TS/effect/commit/60bc3d0867b13e48b24dc22604b4dd2e7b2c1ca4) Thanks @tim-smart! - add Duration.isZero, for checking if a Duration is zero @@ -378,9 +449,9 @@ To try it out, provide it to your program: ```ts - import { Effect, Logger } from "effect"; + import { Effect, Logger } from "effect" - Effect.log("Hello, World!").pipe(Effect.provide(Logger.pretty)); + Effect.log("Hello, World!").pipe(Effect.provide(Logger.pretty)) ``` - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`a1f5b83`](https://github.com/Effect-TS/effect/commit/a1f5b831a1bc7535988b370d68d0b3eb1123e0ce) Thanks @tim-smart! - add .groupCollapsed to UnsafeConsole @@ -411,23 +482,23 @@ Complex keys can extend `Equal` and `Hash` to allow lookups by value. ```ts - import { Effect, RcMap } from "effect"; + import { Effect, RcMap } from "effect" Effect.gen(function* () { const map = yield* RcMap.make({ lookup: (key: string) => Effect.acquireRelease(Effect.succeed(`acquired ${key}`), () => - Effect.log(`releasing ${key}`), - ), - }); + Effect.log(`releasing ${key}`) + ) + }) // Get "foo" from the map twice, which will only acquire it once // It will then be released once the scope closes. yield* RcMap.get(map, "foo").pipe( Effect.andThen(RcMap.get(map, "foo")), - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`ac71f37`](https://github.com/Effect-TS/effect/commit/ac71f378f2413e5aa91c95f649ffe898d6a26114) Thanks @dilame! - Ensure `Scope` is excluded from `R` in the `Channel` / `Stream` `run*` functions. @@ -443,15 +514,15 @@ - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`e4bf1bf`](https://github.com/Effect-TS/effect/commit/e4bf1bf2b4a970eacd77c9b77b5ea8c68bc84498) Thanks @dilame! - feat(Stream): implement "raceAll" operator, which returns a stream that mirrors the first source stream to emit an item. ```ts - import { Stream, Schedule, Console, Effect } from "effect"; + import { Stream, Schedule, Console, Effect } from "effect" const stream = Stream.raceAll( Stream.fromSchedule(Schedule.spaced("1 millis")), Stream.fromSchedule(Schedule.spaced("2 millis")), - Stream.fromSchedule(Schedule.spaced("4 millis")), - ).pipe(Stream.take(6), Stream.tap(Console.log)); + Stream.fromSchedule(Schedule.spaced("4 millis")) + ).pipe(Stream.take(6), Stream.tap(Console.log)) - Effect.runPromise(Stream.runDrain(stream)); + Effect.runPromise(Stream.runDrain(stream)) // Output only from the first stream, the rest streams are interrupted // 0 // 1 @@ -468,7 +539,7 @@ - [#3048](https://github.com/Effect-TS/effect/pull/3048) [`9f66825`](https://github.com/Effect-TS/effect/commit/9f66825f1fce0fe8d10420c285f7dc4c71e8af8d) Thanks @tim-smart! - allow customizing the output buffer for the Stream.async\* apis ```ts - import { Stream } from "effect"; + import { Stream } from "effect" Stream.async( (emit) => { @@ -476,9 +547,9 @@ }, { bufferSize: 16, - strategy: "dropping", // you can also use "sliding" or "suspend" - }, - ); + strategy: "dropping" // you can also use "sliding" or "suspend" + } + ) ``` ### Patch Changes @@ -596,15 +667,15 @@ - [#3121](https://github.com/Effect-TS/effect/pull/3121) [`33735b1`](https://github.com/Effect-TS/effect/commit/33735b16b41bd26929d8f4754c190925db6323b7) Thanks @KhraksMamtsov! - Support for the tacit usage of external handlers for `Match.tag` and `Match.tagStartsWith` functions ```ts - type Value = { _tag: "A"; a: string } | { _tag: "B"; b: number }; - const handlerA = (_: { _tag: "A"; a: number }) => _.a; + type Value = { _tag: "A"; a: string } | { _tag: "B"; b: number } + const handlerA = (_: { _tag: "A"; a: number }) => _.a // $ExpectType string | number pipe( M.type(), M.tag("A", handlerA), // <-- no type issue - M.orElse((_) => _.b), - )(value); + M.orElse((_) => _.b) + )(value) ``` - [#3096](https://github.com/Effect-TS/effect/pull/3096) [`5c0ceb0`](https://github.com/Effect-TS/effect/commit/5c0ceb00826cce9e50bf9d41d83e191d5352c030) Thanks @gcanti! - Micro: move MicroExit types to a namespace @@ -664,15 +735,15 @@ `Effect.liftPredicate` transforms a `Predicate` function into an `Effect` returning the input value if the predicate returns `true` or failing with specified error if the predicate fails. ```ts - import { Effect } from "effect"; + import { Effect } from "effect" - const isPositive = (n: number): boolean => n > 0; + const isPositive = (n: number): boolean => n > 0 // succeeds with `1` - Effect.liftPredicate(1, isPositive, (n) => `${n} is not positive`); + Effect.liftPredicate(1, isPositive, (n) => `${n} is not positive`) // fails with `"0 is not positive"` - Effect.liftPredicate(0, isPositive, (n) => `${n} is not positive`); + Effect.liftPredicate(0, isPositive, (n) => `${n} is not positive`) ``` - [#2938](https://github.com/Effect-TS/effect/pull/2938) [`9c1b5b3`](https://github.com/Effect-TS/effect/commit/9c1b5b39e6c19604ce834f072a114ad392c50a06) Thanks @tim-smart! - add EventListener type to Stream to avoid use of dom lib @@ -695,21 +766,21 @@ - [#2938](https://github.com/Effect-TS/effect/pull/2938) [`91bf8a2`](https://github.com/Effect-TS/effect/commit/91bf8a2e9d1959393b3cf7366cc1d584d3e666b7) Thanks @msensys! - Add `Tuple.at` api, to retrieve an element at a specified index from a tuple. ```ts - import { Tuple } from "effect"; + import { Tuple } from "effect" - assert.deepStrictEqual(Tuple.at([1, "hello", true], 1), "hello"); + assert.deepStrictEqual(Tuple.at([1, "hello", true], 1), "hello") ``` - [#2938](https://github.com/Effect-TS/effect/pull/2938) [`c6a4a26`](https://github.com/Effect-TS/effect/commit/c6a4a266606575fd2c7165940c4072ad4c57d01f) Thanks @datner! - add `ensure` util for Array, used to normalize `A | ReadonlyArray` ```ts - import { ensure } from "effect/Array"; + import { ensure } from "effect/Array" // lets say you are not 100% sure if it's a member or a collection - declare const someValue: { foo: string } | Array<{ foo: string }>; + declare const someValue: { foo: string } | Array<{ foo: string }> // $ExpectType ({ foo: string })[] - const normalized = ensure(someValue); + const normalized = ensure(someValue) ``` ## 3.3.5 @@ -779,13 +850,13 @@ This allows you to add log & span annotation to a Layer. ```ts - import { Effect, Layer } from "effect"; + import { Effect, Layer } from "effect" Layer.effectDiscard(Effect.log("hello")).pipe( Layer.annotateLogs({ - service: "my-service", - }), - ); + service: "my-service" + }) + ) ``` - [#2837](https://github.com/Effect-TS/effect/pull/2837) [`b53f69b`](https://github.com/Effect-TS/effect/commit/b53f69bff1452a487b21198cd83961f844e02d36) Thanks @dilame! - Types: implement `TupleOf` and `TupleOfAtLeast` types @@ -873,7 +944,7 @@ The following now correctly flags a type error given that the property `context` exists already in `Tag`: ```ts - import { Effect } from "effect"; + import { Effect } from "effect" class LoaderArgs extends Effect.Tag("@services/LoaderContext")< LoaderArgs, @@ -910,15 +981,15 @@ Allows you to define an effectful function that is wrapped with a span. ```ts - import { Effect } from "effect"; + import { Effect } from "effect" const getTodo = Effect.functionWithSpan({ body: (id: number) => Effect.succeed(`Got todo ${id}!`), options: (id) => ({ name: `getTodo-${id}`, - attributes: { id }, - }), - }); + attributes: { id } + }) + }) ``` - [#2778](https://github.com/Effect-TS/effect/pull/2778) [`2cbb76b`](https://github.com/Effect-TS/effect/commit/2cbb76bb52500a3f4bf27d1c91482518cbea56d7) Thanks [@tim-smart](https://github.com/tim-smart)! - Add do notation for Array @@ -986,13 +1057,13 @@ This api allows you to annotate logs until the Scope has been closed. ```ts - import { Effect } from "effect"; + import { Effect } from "effect" Effect.gen(function* () { - yield* Effect.log("no annotations"); - yield* Effect.annotateLogsScoped({ foo: "bar" }); - yield* Effect.log("annotated with foo=bar"); - }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again"))); + yield* Effect.log("no annotations") + yield* Effect.annotateLogsScoped({ foo: "bar" }) + yield* Effect.log("annotated with foo=bar") + }).pipe(Effect.scoped, Effect.andThen(Effect.log("no annotations again"))) ``` - [#2543](https://github.com/Effect-TS/effect/pull/2543) [`a1c7ab8`](https://github.com/Effect-TS/effect/commit/a1c7ab8ffedacd18c1fc784f4ff5844f79498b83) Thanks [@github-actions](https://github.com/apps/github-actions)! - added Stream.fromEventListener, and BrowserStream.{fromEventListenerWindow, fromEventListenerDocument} for constructing a stream from addEventListener @@ -1007,38 +1078,38 @@ will return `Some` of the produced value. ```ts - import { Effect } from "effect"; + import { Effect } from "effect" // will return `None` after 500 millis Effect.succeed("hello").pipe( Effect.delay(1000), - Effect.timeoutOption("500 millis"), - ); + Effect.timeoutOption("500 millis") + ) ``` - [#2543](https://github.com/Effect-TS/effect/pull/2543) [`92d56db`](https://github.com/Effect-TS/effect/commit/92d56dbb3f33e36636c2a2f1030c56492e39cf4d) Thanks [@github-actions](https://github.com/apps/github-actions)! - add $is & $match helpers to Data.TaggedEnum constructors ```ts - import { Data } from "effect"; + import { Data } from "effect" type HttpError = Data.TaggedEnum<{ - NotFound: {}; - InternalServerError: { reason: string }; - }>; + NotFound: {} + InternalServerError: { reason: string } + }> const { $is, $match, InternalServerError, NotFound } = - Data.taggedEnum(); + Data.taggedEnum() // create a matcher const matcher = $match({ NotFound: () => 0, - InternalServerError: () => 1, - }); + InternalServerError: () => 1 + }) // true - $is("NotFound")(NotFound()); + $is("NotFound")(NotFound()) // false - $is("NotFound")(InternalServerError({ reason: "fail" })); + $is("NotFound")(InternalServerError({ reason: "fail" })) ``` ## 3.0.8 @@ -1089,10 +1160,10 @@ ```ts Effect.gen(function* () { - const a = yield* Effect.success(1); - const b = yield* Effect.success(2); - return a + b; - }); + const a = yield* Effect.success(1) + const b = yield* Effect.success(2) + return a + b + }) ``` ## 3.0.3 @@ -1104,14 +1175,14 @@ Which can be used to constrain the return type of a match expression. ```ts - import { Match } from "effect"; + import { Match } from "effect" Match.type().pipe( Match.withReturnType(), Match.when("foo", () => "foo"), // valid Match.when("bar", () => 123), // type error - Match.else(() => "baz"), - ); + Match.else(() => "baz") + ) ``` ## 3.0.2 @@ -1148,11 +1219,11 @@ metric. ```ts - import { Metric } from "effect"; + import { Metric } from "effect" const counts = Metric.frequency("counts", { - preregisteredWords: ["a", "b", "c"], - }).register(); + preregisteredWords: ["a", "b", "c"] + }).register() ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`9a3bd47`](https://github.com/Effect-TS/effect/commit/9a3bd47ebd0750c7e498162734f6d21895de0cb2) Thanks [@github-actions](https://github.com/apps/github-actions)! - Bump TypeScript min requirement to version 5.4 @@ -1168,7 +1239,7 @@ This makes Effect.log more similar to console.log: ```ts - Effect.log("hello", { foo: "bar" }, Cause.fail("error")); + Effect.log("hello", { foo: "bar" }, Cause.fail("error")) ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`2f96d93`](https://github.com/Effect-TS/effect/commit/2f96d938b90f8c19377583279e3c7afd9b509c50) Thanks [@github-actions](https://github.com/apps/github-actions)! - Fix ConfigError `_tag`, with the previous implementation catching the `ConfigError` with `Effect.catchTag` would show `And`, `Or`, etc. @@ -1178,8 +1249,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1193,8 +1264,8 @@ ```ts Effect.if(true, { onTrue: Effect.succeed("true"), - onFalse: Effect.succeed("false"), - }); + onFalse: Effect.succeed("false") + }) ``` You should now write: @@ -1202,8 +1273,8 @@ ```ts Effect.if(true, { onTrue: () => Effect.succeed("true"), - onFalse: () => Effect.succeed("false"), - }); + onFalse: () => Effect.succeed("false") + }) ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`e7e1bbe`](https://github.com/Effect-TS/effect/commit/e7e1bbe68486fdf31c8f84b0880522d39adcaad3) Thanks [@github-actions](https://github.com/apps/github-actions)! - Replaced custom `NoInfer` type with the native `NoInfer` type from TypeScript 5.4 @@ -1230,22 +1301,22 @@ - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`1b5f0c7`](https://github.com/Effect-TS/effect/commit/1b5f0c77e7fd477a0026071e82129a948227f4b3) Thanks [@github-actions](https://github.com/apps/github-actions)! - add FiberHandle module, for holding a reference to a running fiber ```ts - import { Effect, FiberHandle } from "effect"; + import { Effect, FiberHandle } from "effect" Effect.gen(function* (_) { - const handle = yield* _(FiberHandle.make()); + const handle = yield* _(FiberHandle.make()) // run some effects - yield* _(FiberHandle.run(handle, Effect.never)); + yield* _(FiberHandle.run(handle, Effect.never)) // this will interrupt the previous fiber - yield* _(FiberHandle.run(handle, Effect.never)); + yield* _(FiberHandle.run(handle, Effect.never)) // this will not run, as a fiber is already running - yield* _(FiberHandle.run(handle, Effect.never, { onlyIfMissing: true })); + yield* _(FiberHandle.run(handle, Effect.never, { onlyIfMissing: true })) - yield* _(Effect.sleep(1000)); + yield* _(Effect.sleep(1000)) }).pipe( - Effect.scoped, // The fiber will be interrupted when the scope is closed - ); + Effect.scoped // The fiber will be interrupted when the scope is closed + ) ``` - [#2521](https://github.com/Effect-TS/effect/pull/2521) [`6424181`](https://github.com/Effect-TS/effect/commit/64241815fe6a939e91e6947253e7dceea1306aa8) Thanks [@patroza](https://github.com/patroza)! - change return type of Fiber.joinAll to return an array @@ -1283,16 +1354,16 @@ For example, `Ref`'s implement `Readable`: ```ts - import { Effect, Readable, Ref } from "effect"; - import assert from "assert"; + import { Effect, Readable, Ref } from "effect" + import assert from "assert" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(123)); - assert(Readable.isReadable(ref)); + const ref = yield* _(Ref.make(123)) + assert(Readable.isReadable(ref)) - const result = yield* _(ref.get); - assert(result === 123); - }); + const result = yield* _(ref.get) + assert(result === 123) + }) ``` - [#2498](https://github.com/Effect-TS/effect/pull/2498) [`e983740`](https://github.com/Effect-TS/effect/commit/e9837401145605aff5bc2ec7e73004f397c5d2d1) Thanks [@jessekelly881](https://github.com/jessekelly881)! - added {Readable, Subscribable}.unwrap @@ -1300,25 +1371,25 @@ - [#2494](https://github.com/Effect-TS/effect/pull/2494) [`e3e0924`](https://github.com/Effect-TS/effect/commit/e3e09247d46a35430fc60e4aa4032cc50814f212) Thanks [@thewilkybarkid](https://github.com/thewilkybarkid)! - Add `Duration.divide` and `Duration.unsafeDivide`. ```ts - import { Duration, Option } from "effect"; - import assert from "assert"; + import { Duration, Option } from "effect" + import assert from "assert" assert.deepStrictEqual( Duration.divide("10 seconds", 2), - Option.some(Duration.decode("5 seconds")), - ); - assert.deepStrictEqual(Duration.divide("10 seconds", 0), Option.none()); - assert.deepStrictEqual(Duration.divide("1 nano", 1.5), Option.none()); + Option.some(Duration.decode("5 seconds")) + ) + assert.deepStrictEqual(Duration.divide("10 seconds", 0), Option.none()) + assert.deepStrictEqual(Duration.divide("1 nano", 1.5), Option.none()) assert.deepStrictEqual( Duration.unsafeDivide("10 seconds", 2), - Duration.decode("5 seconds"), - ); + Duration.decode("5 seconds") + ) assert.deepStrictEqual( Duration.unsafeDivide("10 seconds", 0), - Duration.infinity, - ); - assert.throws(() => Duration.unsafeDivide("1 nano", 1.5)); + Duration.infinity + ) + assert.throws(() => Duration.unsafeDivide("1 nano", 1.5)) ``` ## 2.4.18 @@ -1330,10 +1401,10 @@ These apis send a Logger's output to console.log/console.error respectively. ```ts - import { Logger } from "effect"; + import { Logger } from "effect" // send output to stderr - const stderrLogger = Logger.withConsoleError(Logger.stringLogger); + const stderrLogger = Logger.withConsoleError(Logger.stringLogger) ``` ## 2.4.17 @@ -1351,14 +1422,14 @@ This module shares many apis compared to "effect/ReadonlyArray", but is fully lazy. ```ts - import { Iterable, pipe } from "effect"; + import { Iterable, pipe } from "effect" // Only 5 items will be generated & transformed pipe( Iterable.range(1, 100), Iterable.map((i) => `item ${i}`), - Iterable.take(5), - ); + Iterable.take(5) + ) ``` - [#2438](https://github.com/Effect-TS/effect/pull/2438) [`7ddd654`](https://github.com/Effect-TS/effect/commit/7ddd65415b65ccb654ad04f4dbefe39402f15117) Thanks [@mikearnaldi](https://github.com/mikearnaldi)! - Support Heterogeneous Effects in Effect Iterable apis @@ -1375,7 +1446,7 @@ For example: ```ts - import { Effect } from "effect"; + import { Effect } from "effect" class Foo extends Effect.Tag("Foo")() {} class Bar extends Effect.Tag("Bar")() {} @@ -1385,8 +1456,8 @@ Effect.succeed(1 as const), Effect.succeed(2 as const), Foo, - Bar, - ]); + Bar + ]) ``` The above is now possible while before it was expecting all Effects to conform to the same type @@ -1396,13 +1467,13 @@ Which allows you to filter and map an Iterable of Effects in one step. ```ts - import { Effect, Option } from "effect"; + import { Effect, Option } from "effect" // resolves with `["even: 2"] Effect.filterMap( [Effect.succeed(1), Effect.succeed(2), Effect.succeed(3)], - (i) => (i % 2 === 0 ? Option.some(`even: ${i}`) : Option.none()), - ); + (i) => (i % 2 === 0 ? Option.some(`even: ${i}`) : Option.none()) + ) ``` - [#2461](https://github.com/Effect-TS/effect/pull/2461) [`8fdfda6`](https://github.com/Effect-TS/effect/commit/8fdfda6618be848c01b399d13bc05a9a3adfb613) Thanks [@tim-smart](https://github.com/tim-smart)! - use Inspectable.toStringUnknown for absurd runtime errors @@ -1468,13 +1539,13 @@ You can use it with the Effect.withTracerEnabled api: ```ts - import { Effect } from "effect"; + import { Effect } from "effect" Effect.succeed(42).pipe( Effect.withSpan("my-span"), // the span will not be registered with the tracer - Effect.withTracerEnabled(false), - ); + Effect.withTracerEnabled(false) + ) ``` - [#2383](https://github.com/Effect-TS/effect/pull/2383) [`317b5b8`](https://github.com/Effect-TS/effect/commit/317b5b8e8c8c2207469b3ebfcf72bf3a9f7cbc60) Thanks [@tim-smart](https://github.com/tim-smart)! - add Duration.isFinite api, to determine if a duration is not Infinity @@ -1505,10 +1576,10 @@ Example: ```ts - import { Effect } from "effect"; + import { Effect } from "effect" // fails with NoSuchElementException - Effect.succeed(1).pipe(Effect.filterOrFail((n) => n === 0)); + Effect.succeed(1).pipe(Effect.filterOrFail((n) => n === 0)) ``` - [#2336](https://github.com/Effect-TS/effect/pull/2336) [`6b20bad`](https://github.com/Effect-TS/effect/commit/6b20badebb3a7ca4d38857753e8ecaa09d02ccfb) Thanks [@jessekelly881](https://github.com/jessekelly881)! - added Predicate.isTruthy @@ -1554,8 +1625,8 @@ ```ts export function refined>( - f: (unbranded: Brand.Unbranded) => Option.Option, - ): Brand.Constructor; + f: (unbranded: Brand.Unbranded) => Option.Option + ): Brand.Constructor ``` - [#2285](https://github.com/Effect-TS/effect/pull/2285) [`817a04c`](https://github.com/Effect-TS/effect/commit/817a04cb2df0f4140984dc97eb3e1bb14a6c4a38) Thanks [@tim-smart](https://github.com/tim-smart)! - add support for AbortSignal's to runPromise @@ -1563,14 +1634,14 @@ If the signal is aborted, the effect execution will be interrupted. ```ts - import { Effect } from "effect"; + import { Effect } from "effect" - const controller = new AbortController(); + const controller = new AbortController() - Effect.runPromise(Effect.never, { signal: controller.signal }); + Effect.runPromise(Effect.never, { signal: controller.signal }) // abort after 1 second - setTimeout(() => controller.abort(), 1000); + setTimeout(() => controller.abort(), 1000) ``` - [#2293](https://github.com/Effect-TS/effect/pull/2293) [`d90a99d`](https://github.com/Effect-TS/effect/commit/d90a99d03d074adc7cd2533f15419138264da5a2) Thanks [@tim-smart](https://github.com/tim-smart)! - add AbortSignal support to ManagedRuntime @@ -1591,24 +1662,24 @@ dependencies from the given Layer. For example: ```ts - import { Console, Effect, Layer, ManagedRuntime } from "effect"; + import { Console, Effect, Layer, ManagedRuntime } from "effect" class Notifications extends Effect.Tag("Notifications")< Notifications, { readonly notify: (message: string) => Effect.Effect } >() { static Live = Layer.succeed(this, { - notify: (message) => Console.log(message), - }); + notify: (message) => Console.log(message) + }) } async function main() { - const runtime = ManagedRuntime.make(Notifications.Live); - await runtime.runPromise(Notifications.notify("Hello, world!")); - await runtime.dispose(); + const runtime = ManagedRuntime.make(Notifications.Live) + await runtime.runPromise(Notifications.notify("Hello, world!")) + await runtime.dispose() } - main(); + main() ``` - [#2211](https://github.com/Effect-TS/effect/pull/2211) [`20e63fb`](https://github.com/Effect-TS/effect/commit/20e63fb9207210f3fe2d136ec40d0a2dbff3225e) Thanks [@tim-smart](https://github.com/tim-smart)! - add Layer.toRuntimeWithMemoMap api @@ -1633,8 +1704,8 @@ class DemoTag extends Effect.Tag("DemoTag")< DemoTag, { - readonly getNumbers: () => Array; - readonly strings: Array; + readonly getNumbers: () => Array + readonly strings: Array } >() {} ``` @@ -1642,8 +1713,8 @@ And use them like: ```ts - DemoTag.getNumbers(); - DemoTag.strings; + DemoTag.getNumbers() + DemoTag.strings ``` This fuses together `serviceFunctions` and `serviceConstants` in the static side of the tag. @@ -1651,7 +1722,7 @@ Additionally it allows using the service like: ```ts - DemoTag.use((_) => _.getNumbers()); + DemoTag.use((_) => _.getNumbers()) ``` This is especially useful when having functions that contain generics in the service given that those can't be reliably transformed at the type level and because of that we can't put them on the tag. @@ -1673,22 +1744,22 @@ This change allows the following to work just fine: ```ts - import { Effect, Layer } from "effect"; + import { Effect, Layer } from "effect" class DateTag extends Effect.Tag("DateTag")() { - static date = new Date(1970, 1, 1); - static Live = Layer.succeed(this, this.date); + static date = new Date(1970, 1, 1) + static Live = Layer.succeed(this, this.date) } class MapTag extends Effect.Tag("MapTag")>() { static Live = Layer.effect( this, - Effect.sync(() => new Map()), - ); + Effect.sync(() => new Map()) + ) } class NumberTag extends Effect.Tag("NumberTag")() { - static Live = Layer.succeed(this, 100); + static Live = Layer.succeed(this, 100) } ``` @@ -1699,15 +1770,15 @@ Example: ```ts - import { Effect, FiberSet } from "effect"; + import { Effect, FiberSet } from "effect" Effect.gen(function* (_) { - const set = yield* _(FiberSet.make()); - yield* _(FiberSet.add(set, Effect.runFork(Effect.fail("error")))); + const set = yield* _(FiberSet.make()) + yield* _(FiberSet.add(set, Effect.runFork(Effect.fail("error")))) // parent fiber will fail with "error" - yield* _(FiberSet.join(set)); - }); + yield* _(FiberSet.join(set)) + }) ``` - [#2238](https://github.com/Effect-TS/effect/pull/2238) [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750) Thanks [@JJayet](https://github.com/JJayet)! - make Effect.request dual @@ -1723,22 +1794,22 @@ Example: ```ts - import { Console, Effect, Logger } from "effect"; + import { Console, Effect, Logger } from "effect" const LoggerLive = Logger.replaceScoped( Logger.defaultLogger, Logger.logfmtLogger.pipe( Logger.batched("500 millis", (messages) => - Console.log("BATCH", messages.join("\n")), - ), - ), - ); + Console.log("BATCH", messages.join("\n")) + ) + ) + ) Effect.gen(function* (_) { - yield* _(Effect.log("one")); - yield* _(Effect.log("two")); - yield* _(Effect.log("three")); - }).pipe(Effect.provide(LoggerLive), Effect.runFork); + yield* _(Effect.log("one")) + yield* _(Effect.log("two")) + yield* _(Effect.log("three")) + }).pipe(Effect.provide(LoggerLive), Effect.runFork) ``` - [#2233](https://github.com/Effect-TS/effect/pull/2233) [`de74eb8`](https://github.com/Effect-TS/effect/commit/de74eb80a79eebde5ff645033765e7a617e92f27) Thanks [@gcanti](https://github.com/gcanti)! - Struct: make `pick` / `omit` dual @@ -1771,10 +1842,10 @@ declare const async: ( register: ( callback: (_: Effect) => void, - signal: AbortSignal, + signal: AbortSignal ) => void | Effect, - blockingOn?: FiberId, - ) => Effect; + blockingOn?: FiberId + ) => Effect ``` Additionally, this PR removes `Stream.asyncOption`, `Stream.asyncEither`, and `Stream.asyncInterrupt` as their behavior can be entirely implemented with the new signature of `Stream.async`, which can optionally return a cleanup `Effect` from the registration callback. @@ -1782,8 +1853,8 @@ ```ts declare const async: ( register: (emit: Emit) => Effect | void, - outputBuffer?: number, - ) => Stream; + outputBuffer?: number + ) => Stream ``` - [#2101](https://github.com/Effect-TS/effect/pull/2101) [`d8d278b`](https://github.com/Effect-TS/effect/commit/d8d278b2efb2966947029885e01f7b68348a021f) Thanks [@github-actions](https://github.com/apps/github-actions)! - swap `GroupBy` type parameters from `GroupBy` to `GroupBy` @@ -1793,27 +1864,27 @@ The `Unify` module fully replaces the need for specific unify functions, when before you did: ```ts - import { Effect } from "effect"; + import { Effect } from "effect" const effect = Effect.unified( - Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO"), - ); + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") + ) const effectFn = Effect.unifiedFn((n: number) => - Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO"), - ); + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") + ) ``` You can now do: ```ts - import { Effect, Unify } from "effect"; + import { Effect, Unify } from "effect" const effect = Unify.unify( - Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO"), - ); + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") + ) const effectFn = Unify.unify((n: number) => - Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO"), - ); + Math.random() > 0.5 ? Effect.succeed("OK") : Effect.fail("NO") + ) ``` - [#2101](https://github.com/Effect-TS/effect/pull/2101) [`5de7be5`](https://github.com/Effect-TS/effect/commit/5de7be5beca2e963b503e6029dcc3217848187d2) Thanks [@github-actions](https://github.com/apps/github-actions)! - add key type to ReadonlyRecord @@ -1823,48 +1894,48 @@ Before: ```ts - import { pipe } from "effect/Function"; - import * as S from "effect/Struct"; + import { pipe } from "effect/Function" + import * as S from "effect/Struct" const struct: { - a?: string; - b: number; - c: boolean; - } = { b: 1, c: true }; + a?: string + b: number + c: boolean + } = { b: 1, c: true } // error - const x = pipe(struct, S.pick("a", "b")); + const x = pipe(struct, S.pick("a", "b")) - const record: Record = {}; + const record: Record = {} - const y = pipe(record, S.pick("a", "b")); - console.log(y); // => { a: undefined, b: undefined } + const y = pipe(record, S.pick("a", "b")) + console.log(y) // => { a: undefined, b: undefined } // error - console.log(pipe(struct, S.get("a"))); + console.log(pipe(struct, S.get("a"))) ``` Now ```ts - import { pipe } from "effect/Function"; - import * as S from "effect/Struct"; + import { pipe } from "effect/Function" + import * as S from "effect/Struct" const struct: { - a?: string; - b: number; - c: boolean; - } = { b: 1, c: true }; + a?: string + b: number + c: boolean + } = { b: 1, c: true } - const x = pipe(struct, S.pick("a", "b")); - console.log(x); // => { b: 1 } + const x = pipe(struct, S.pick("a", "b")) + console.log(x) // => { b: 1 } - const record: Record = {}; + const record: Record = {} - const y = pipe(record, S.pick("a", "b")); - console.log(y); // => {} + const y = pipe(record, S.pick("a", "b")) + console.log(y) // => {} - console.log(pipe(struct, S.get("a"))); // => undefined + console.log(pipe(struct, S.get("a"))) // => undefined ``` - [#2101](https://github.com/Effect-TS/effect/pull/2101) [`a025b12`](https://github.com/Effect-TS/effect/commit/a025b121235ba01cfce8d62a775491880c575561) Thanks [@github-actions](https://github.com/apps/github-actions)! - Swap type params of Either from `Either` to `Either`. @@ -1872,9 +1943,9 @@ Along the same line of the other changes this allows to shorten the most common types such as: ```ts - import { Either } from "effect"; + import { Either } from "effect" - const right: Either.Either = Either.right("ok"); + const right: Either.Either = Either.right("ok") ``` ### Patch Changes @@ -1896,14 +1967,14 @@ This api assists with adding a layer of caching, when hashing immutable data structures. ```ts - import { Data, Hash } from "effect"; + import { Data, Hash } from "effect" class User extends Data.Class<{ - id: number; - name: string; + id: number + name: string }> { [Hash.symbol]() { - return Hash.cached(this, Hash.string(`${this.id}-${this.name}`)); + return Hash.cached(this, Hash.string(`${this.id}-${this.name}`)) } } ``` @@ -1923,11 +1994,11 @@ To manually control the module version one can use: ```ts - import * as ModuleVersion from "effect/ModuleVersion"; + import * as ModuleVersion from "effect/ModuleVersion" ModuleVersion.setCurrentVersion( - `my-effect-runtime-${ModuleVersion.getCurrentVersion()}`, - ); + `my-effect-runtime-${ModuleVersion.getCurrentVersion()}` + ) ``` Note that this code performs side effects and should be executed before any module is imported ideally via an init script. @@ -1935,13 +2006,13 @@ The resulting order of execution has to be: ```ts - import * as ModuleVersion from "effect/ModuleVersion"; + import * as ModuleVersion from "effect/ModuleVersion" ModuleVersion.setCurrentVersion( - `my-effect-runtime-${ModuleVersion.getCurrentVersion()}`, - ); + `my-effect-runtime-${ModuleVersion.getCurrentVersion()}` + ) - import { Effect } from "effect"; + import { Effect } from "effect" // rest of code ``` @@ -1962,19 +2033,19 @@ Example: ```ts - import { Effect, Request, RequestResolver } from "effect"; + import { Effect, Request, RequestResolver } from "effect" interface GetUserById extends Request.Request { - readonly id: number; + readonly id: number } - declare const resolver: RequestResolver.RequestResolver; + declare const resolver: RequestResolver.RequestResolver RequestResolver.aroundRequests( resolver, (requests) => Effect.log(`got ${requests.length} requests`), - (requests, _) => Effect.log(`finised running ${requests.length} requests`), - ); + (requests, _) => Effect.log(`finised running ${requests.length} requests`) + ) ``` - [#2148](https://github.com/Effect-TS/effect/pull/2148) [`b46b869`](https://github.com/Effect-TS/effect/commit/b46b869e59a6da5aa235a9fcc25e1e0d24e9e8f8) Thanks [@riordanpawley](https://github.com/riordanpawley)! - Flipped scheduleForked types to match new signature @@ -1988,9 +2059,9 @@ - [#2143](https://github.com/Effect-TS/effect/pull/2143) [`ff88f80`](https://github.com/Effect-TS/effect/commit/ff88f808c4ed9947a148045849e7410b00acad0a) Thanks [@mikearnaldi](https://github.com/mikearnaldi)! - Fix Cause.pretty when toString is invalid ```ts - import { Cause } from "effect"; + import { Cause } from "effect" - console.log(Cause.pretty(Cause.fail([{ toString: "" }]))); + console.log(Cause.pretty(Cause.fail([{ toString: "" }]))) ``` The code above used to throw now it prints: @@ -2003,13 +2074,13 @@ This is a convenient operator to use in the `pipe` chain to localize type errors closer to their source. ```ts - import { satisfies } from "effect/Function"; + import { satisfies } from "effect/Function" - const test1 = satisfies()(5 as const); + const test1 = satisfies()(5 as const) // ^? const test: 5 // @ts-expect-error - const test2 = satisfies()(5); + const test2 = satisfies()(5) // ^? Argument of type 'number' is not assignable to parameter of type 'string' ``` @@ -2028,16 +2099,16 @@ Example: ```ts - import { Effect, FiberRef, Runtime } from "effect"; + import { Effect, FiberRef, Runtime } from "effect" - const ref = FiberRef.unsafeMake(0); + const ref = FiberRef.unsafeMake(0) const updatedRuntime = Runtime.defaultRuntime.pipe( - Runtime.setFiberRef(ref, 1), - ); + Runtime.setFiberRef(ref, 1) + ) // returns 1 - const result = Runtime.runSync(updatedRuntime)(FiberRef.get(ref)); + const result = Runtime.runSync(updatedRuntime)(FiberRef.get(ref)) ``` ## 2.3.5 @@ -2061,30 +2132,30 @@ Usage Example : ```ts - import { Effect, RateLimiter } from "effect"; - import { compose } from "effect/Function"; + import { Effect, RateLimiter } from "effect" + import { compose } from "effect/Function" const program = Effect.scoped( Effect.gen(function* ($) { // Create a rate limiter that has an hourly limit of 1000 credits - const rateLimiter = yield* $(RateLimiter.make(1000, "1 hours")); + const rateLimiter = yield* $(RateLimiter.make(1000, "1 hours")) // Query API costs 1 credit per call ( 1 is the default cost ) - const queryAPIRL = compose(rateLimiter, RateLimiter.withCost(1)); + const queryAPIRL = compose(rateLimiter, RateLimiter.withCost(1)) // Mutation API costs 5 credits per call - const mutationAPIRL = compose(rateLimiter, RateLimiter.withCost(5)); + const mutationAPIRL = compose(rateLimiter, RateLimiter.withCost(5)) // ... // Use the pre-defined rate limiters - yield* $(queryAPIRL(Effect.log("Sample Query"))); - yield* $(mutationAPIRL(Effect.log("Sample Mutation"))); + yield* $(queryAPIRL(Effect.log("Sample Query"))) + yield* $(mutationAPIRL(Effect.log("Sample Mutation"))) // Or set a cost on-the-fly yield* $( rateLimiter(Effect.log("Another query with a different cost")).pipe( - RateLimiter.withCost(3), - ), - ); - }), - ); + RateLimiter.withCost(3) + ) + ) + }) + ) ``` - [#2097](https://github.com/Effect-TS/effect/pull/2097) [`0f83515`](https://github.com/Effect-TS/effect/commit/0f83515a9c01d13c7c15a3f026e02d22c3c6bb7f) Thanks [@IMax153](https://github.com/IMax153)! - Updates the `RateLimiter.make` constructor to take an object of `RateLimiter.Options`, which allows for specifying the rate-limiting algorithm to utilize: @@ -2097,7 +2168,7 @@ /** * The maximum number of requests that should be allowed. */ - readonly limit: number; + readonly limit: number /** * The interval to utilize for rate-limiting requests. The semantics of the * specified `interval` vary depending on the chosen `algorithm`: @@ -2114,13 +2185,13 @@ * algorithm with a `limit` of `10` and an `interval` of `1 seconds`, a * maximum of `10` requests can be made each second. */ - readonly interval: DurationInput; + readonly interval: DurationInput /** * The algorithm to utilize for rate-limiting requests. * * Defaults to `token-bucket`. */ - readonly algorithm?: "fixed-window" | "token-bucket"; + readonly algorithm?: "fixed-window" | "token-bucket" } } ``` @@ -2153,22 +2224,22 @@ ```ts expect(pipe(Either.right(1), Either.andThen(2))).toStrictEqual( - Either.right(2), - ); + Either.right(2) + ) expect( pipe( Either.right(1), - Either.andThen(() => 2), - ), - ).toStrictEqual(Either.right(2)); + Either.andThen(() => 2) + ) + ).toStrictEqual(Either.right(2)) - expect(pipe(Option.some(1), Option.andThen(2))).toStrictEqual(Option.some(2)); + expect(pipe(Option.some(1), Option.andThen(2))).toStrictEqual(Option.some(2)) expect( pipe( Option.some(1), - Option.andThen(() => 2), - ), - ).toStrictEqual(Option.some(2)); + Option.andThen(() => 2) + ) + ).toStrictEqual(Option.some(2)) ``` - [#2098](https://github.com/Effect-TS/effect/pull/2098) [`71aa5b1`](https://github.com/Effect-TS/effect/commit/71aa5b1c180dcb8b53aefe232d12a97bd06b5447) Thanks [@ethanniser](https://github.com/ethanniser)! - removed `./internal/timeout` and replaced all usages with `setTimeout` directly @@ -2204,31 +2275,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -2236,17 +2307,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -2270,21 +2341,21 @@ At the type level instead the functions return `Readonly` variants, so for example we have: ```ts - import { Data } from "effect"; + import { Data } from "effect" const obj = Data.struct({ a: 0, - b: 1, - }); + b: 1 + }) ``` will have the `obj` typed as: ```ts declare const obj: { - readonly a: number; - readonly b: number; - }; + readonly a: number + readonly b: number + } ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`0e56e99`](https://github.com/Effect-TS/effect/commit/0e56e998ab9815c4d096c239a553cb86a0f99af9) Thanks [@github-actions](https://github.com/apps/github-actions)! - change `Deferred` type parameters order from `Deferred` to `Deferred` @@ -2312,15 +2383,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` @@ -2352,47 +2423,47 @@ Usage Example: ```ts - import { Effect, RateLimiter } from "effect"; + import { Effect, RateLimiter } from "effect" // we need a scope because the rate limiter needs to allocate a state and a background job const program = Effect.scoped( Effect.gen(function* ($) { // create a rate limiter that executes up to 10 requests within 2 seconds - const rateLimit = yield* $(RateLimiter.make(10, "2 seconds")); + const rateLimit = yield* $(RateLimiter.make(10, "2 seconds")) // simulate repeated calls for (let n = 0; n < 100; n++) { // wrap the effect we want to limit with rateLimit - yield* $(rateLimit(Effect.log("Calling RateLimited Effect"))); + yield* $(rateLimit(Effect.log("Calling RateLimited Effect"))) } - }), - ); + }) + ) // will print 10 calls immediately and then throttle - program.pipe(Effect.runFork); + program.pipe(Effect.runFork) ``` Or, in a more real world scenario, with a dedicated Service + Layer: ```ts - import { Context, Effect, Layer, RateLimiter } from "effect"; + import { Context, Effect, Layer, RateLimiter } from "effect" class ApiLimiter extends Context.Tag("@services/ApiLimiter")< ApiLimiter, RateLimiter.RateLimiter >() { static Live = RateLimiter.make(10, "2 seconds").pipe( - Layer.scoped(ApiLimiter), - ); + Layer.scoped(ApiLimiter) + ) } const program = Effect.gen(function* ($) { - const rateLimit = yield* $(ApiLimiter); + const rateLimit = yield* $(ApiLimiter) for (let n = 0; n < 100; n++) { - yield* $(rateLimit(Effect.log("Calling RateLimited Effect"))); + yield* $(rateLimit(Effect.log("Calling RateLimited Effect"))) } - }); + }) - program.pipe(Effect.provide(ApiLimiter.Live), Effect.runFork); + program.pipe(Effect.provide(ApiLimiter.Live), Effect.runFork) ``` - [#2084](https://github.com/Effect-TS/effect/pull/2084) [`4a5d01a`](https://github.com/Effect-TS/effect/commit/4a5d01a409e9b6dd53893e65f8e5c9247f568021) Thanks [@tim-smart](https://github.com/tim-smart)! - simplify RateLimiter implementation using semaphore @@ -2402,10 +2473,10 @@ This function returns the next power of 2 from the given number. ```ts - import { nextPow2 } from "effect/Number"; + import { nextPow2 } from "effect/Number" - assert.deepStrictEqual(nextPow2(5), 8); - assert.deepStrictEqual(nextPow2(17), 32); + assert.deepStrictEqual(nextPow2(5), 8) + assert.deepStrictEqual(nextPow2(17), 32) ``` ## 2.2.5 @@ -2422,16 +2493,16 @@ Example: ```ts - import { Context, Runtime } from "effect"; + import { Context, Runtime } from "effect" interface Name { - readonly _: unique symbol; + readonly _: unique symbol } - const Name = Context.Tag("Name"); + const Name = Context.Tag("Name") const runtime: Runtime.Runtime = Runtime.defaultRuntime.pipe( - Runtime.provideService(Name, "John"), - ); + Runtime.provideService(Name, "John") + ) ``` - [#2075](https://github.com/Effect-TS/effect/pull/2075) [`3ddfdbf`](https://github.com/Effect-TS/effect/commit/3ddfdbf914edea536aef207cec6695f33496258c) Thanks [@tim-smart](https://github.com/tim-smart)! - add apis for patching runtime flags to the Runtime module @@ -2457,23 +2528,23 @@ Option.getOrElse, except the return value is still an Option. ```ts - import * as O from "effect/Option"; - import { pipe } from "effect/Function"; + import * as O from "effect/Option" + import { pipe } from "effect/Function" assert.deepStrictEqual( pipe( O.none(), - O.orElseSome(() => "b"), + O.orElseSome(() => "b") ), - O.some("b"), - ); + O.some("b") + ) assert.deepStrictEqual( pipe( O.some("a"), - O.orElseSome(() => "b"), + O.orElseSome(() => "b") ), - O.some("a"), - ); + O.some("a") + ) ``` - [#2057](https://github.com/Effect-TS/effect/pull/2057) [`6928a2b`](https://github.com/Effect-TS/effect/commit/6928a2b0bae86a4bdfbece0aa32924207c2d5a70) Thanks [@joepjoosten](https://github.com/joepjoosten)! - Fix for possible stack overflow errors when using Array.push with spread operator arguments diff --git a/packages/effect/package.json b/packages/effect/package.json index 75e07988d2..d1a8825764 100644 --- a/packages/effect/package.json +++ b/packages/effect/package.json @@ -1,6 +1,6 @@ { "name": "effect", - "version": "3.6.8", + "version": "3.7.0", "type": "module", "license": "MIT", "description": "The missing standard library for TypeScript, for writing production-grade software.", diff --git a/packages/effect/src/internal/version.ts b/packages/effect/src/internal/version.ts index 200d22a554..a8b6f050ec 100644 --- a/packages/effect/src/internal/version.ts +++ b/packages/effect/src/internal/version.ts @@ -1,4 +1,4 @@ -let moduleVersion = "3.6.8" +let moduleVersion = "3.7.0" export const getCurrentVersion = () => moduleVersion diff --git a/packages/experimental/CHANGELOG.md b/packages/experimental/CHANGELOG.md index 339e7c2020..b1d7d0bdc8 100644 --- a/packages/experimental/CHANGELOG.md +++ b/packages/experimental/CHANGELOG.md @@ -1,5 +1,15 @@ # @effect/experimental +## 0.24.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/platform-node@0.58.0 + - @effect/schema@0.72.0 + ## 0.23.7 ### Patch Changes @@ -75,39 +85,39 @@ The `VariantSchema` module can be used to schemas with multiple variants. ```ts - import { VariantSchema } from "@effect/experimental"; - import { Schema } from "@effect/schema"; - import { DateTime } from "effect"; + import { VariantSchema } from "@effect/experimental" + import { Schema } from "@effect/schema" + import { DateTime } from "effect" export const { Class, Field, Struct } = VariantSchema.factory({ variants: ["database", "api"], - defaultVariant: "database", - }); + defaultVariant: "database" + }) class User extends Class("User")({ id: Schema.Number, createdAt: Field({ database: Schema.DateTimeUtc.pipe( - Schema.optionalWith({ default: DateTime.unsafeNow }), + Schema.optionalWith({ default: DateTime.unsafeNow }) ), - api: Schema.DateTimeUtc, + api: Schema.DateTimeUtc }), updateAt: Field({ database: Schema.DateTimeUtc.pipe( - Schema.optionalWith({ default: DateTime.unsafeNow }), + Schema.optionalWith({ default: DateTime.unsafeNow }) ), - api: Schema.DateTimeUtc, - }), + api: Schema.DateTimeUtc + }) }) {} // the class will use the `defaultVariant` fields - const user = new User({ id: 1 }); - user.createdAt; - user.updateAt; + const user = new User({ id: 1 }) + user.createdAt + user.updateAt // access the `Schema.Struct` variants as static props - User.database; - User.api; + User.database + User.api ``` ## 0.23.0 @@ -949,13 +959,13 @@ You now have to provide a WebSocketConstructor implementation to the `Socket.makeWebSocket` api. ```ts - import * as Socket from "@effect/platform/Socket"; - import * as NodeSocket from "@effect/platform-node/NodeSocket"; - import { Effect } from "effect"; + import * as Socket from "@effect/platform/Socket" + import * as NodeSocket from "@effect/platform-node/NodeSocket" + import { Effect } from "effect" Socket.makeWebSocket("ws://localhost:8080").pipe( - Effect.provide(NodeSocket.layerWebSocketConstructor), // use "ws" npm package - ); + Effect.provide(NodeSocket.layerWebSocketConstructor) // use "ws" npm package + ) ``` ### Patch Changes @@ -1156,8 +1166,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1203,16 +1213,16 @@ For example, `Ref`'s implement `Readable`: ```ts - import { Effect, Readable, Ref } from "effect"; - import assert from "assert"; + import { Effect, Readable, Ref } from "effect" + import assert from "assert" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(123)); - assert(Readable.isReadable(ref)); + const ref = yield* _(Ref.make(123)) + assert(Readable.isReadable(ref)) - const result = yield* _(ref.get); - assert(result === 123); - }); + const result = yield* _(ref.get) + assert(result === 123) + }) ``` - Updated dependencies [[`0aee906`](https://github.com/Effect-TS/effect/commit/0aee906f034539344db6fbac08919de3e28eccde), [`41c8102`](https://github.com/Effect-TS/effect/commit/41c810228b1a50e4b41f19e735d7c62fe8d36871), [`4c37001`](https://github.com/Effect-TS/effect/commit/4c370013417e18c4f564818de1341a8fccb43b4c), [`776ef2b`](https://github.com/Effect-TS/effect/commit/776ef2bb66db9aa9f68b7beab14f6986f9c1288b), [`217147e`](https://github.com/Effect-TS/effect/commit/217147ea67c5c42c96f024775c41e5b070f81e4c), [`8a69b4e`](https://github.com/Effect-TS/effect/commit/8a69b4ef6a3a06d2e21fe2e11a626038beefb4e1), [`90776ec`](https://github.com/Effect-TS/effect/commit/90776ec8e8671d835b65fc33ead1de6c864b81b9), [`b3acf47`](https://github.com/Effect-TS/effect/commit/b3acf47f9c9dfae1c99377aa906097aaa2d47d44), [`8709856`](https://github.com/Effect-TS/effect/commit/870985694ae985c3cb9360ad8a25c60e6f785f55), [`232c353`](https://github.com/Effect-TS/effect/commit/232c353c2e6f743f38e57639ee30e324ffa9c2a9), [`0d3231a`](https://github.com/Effect-TS/effect/commit/0d3231a195202635ecc0bf6bbf6a08fc017d0d69), [`0ca835c`](https://github.com/Effect-TS/effect/commit/0ca835cbac8e69072a93ace83b534219faba24e8), [`8709856`](https://github.com/Effect-TS/effect/commit/870985694ae985c3cb9360ad8a25c60e6f785f55), [`da22adc`](https://github.com/Effect-TS/effect/commit/da22adc6507563876f1c416fd22a5f9206cc1395), [`d590094`](https://github.com/Effect-TS/effect/commit/d5900943489ec1e0891836aeafb5ce99fb9c75c7), [`c22b019`](https://github.com/Effect-TS/effect/commit/c22b019e5eaf9d3a937a3d99cadbb8f8e9116a70), [`e983740`](https://github.com/Effect-TS/effect/commit/e9837401145605aff5bc2ec7e73004f397c5d2d1), [`e3e0924`](https://github.com/Effect-TS/effect/commit/e3e09247d46a35430fc60e4aa4032cc50814f212)]: @@ -1352,12 +1362,12 @@ A trait for attaching expiry information to objects. ```ts - import * as TimeToLive from "@effect/experimental"; - import { Duration, Exit } from "effect"; + import * as TimeToLive from "@effect/experimental" + import { Duration, Exit } from "effect" class User { [TimeToLive.symbol](exit: Exit.Exit) { - return Exit.isSuccess(exit) ? Duration.seconds(60) : Duration.zero; + return Exit.isSuccess(exit) ? Duration.seconds(60) : Duration.zero } } ``` @@ -1571,21 +1581,21 @@ example of a machine that sends emails: ```ts - import { Machine } from "@effect/experimental"; - import { runMain } from "@effect/platform-node/NodeRuntime"; - import { Data, Effect, List, Request, Schedule } from "effect"; + import { Machine } from "@effect/experimental" + import { runMain } from "@effect/platform-node/NodeRuntime" + import { Data, Effect, List, Request, Schedule } from "effect" class SendError extends Data.TaggedError("SendError")<{ - readonly email: string; - readonly reason: string; + readonly email: string + readonly reason: string }> {} class SendEmail extends Request.TaggedClass("SendEmail")< void, SendError, { - readonly email: string; - readonly message: string; + readonly email: string + readonly message: string } > {} @@ -1599,14 +1609,14 @@ const mailer = Machine.makeWith>()((_, previous) => Effect.gen(function* (_) { - const ctx = yield* _(Machine.MachineContext); - const state = previous ?? List.empty(); + const ctx = yield* _(Machine.MachineContext) + const state = previous ?? List.empty() if (List.isCons(state)) { yield* _( ctx.unsafeSend(new ProcessEmail()), - Effect.replicateEffect(List.size(state)), - ); + Effect.replicateEffect(List.size(state)) + ) } return Machine.procedures.make(state).pipe( @@ -1615,47 +1625,47 @@ ({ state }) => Effect.gen(function* (_) { if (List.isNil(state)) { - return [void 0, state]; + return [void 0, state] } - const req = state.head; + const req = state.head yield* _( Effect.log(`Sending email to ${req.email}`), - Effect.delay(500), - ); - return [void 0, state.tail]; - }), + Effect.delay(500) + ) + return [void 0, state.tail] + }) ), Machine.procedures.add()("SendEmail", (ctx) => ctx .send(new ProcessEmail()) - .pipe(Effect.as([void 0, List.append(ctx.state, ctx.request)])), + .pipe(Effect.as([void 0, List.append(ctx.state, ctx.request)])) ), Machine.procedures.add()("Shutdown", () => - Effect.log("Shutting down").pipe(Effect.zipRight(Effect.interrupt)), - ), - ); - }), - ).pipe(Machine.retry(Schedule.forever)); + Effect.log("Shutting down").pipe(Effect.zipRight(Effect.interrupt)) + ) + ) + }) + ).pipe(Machine.retry(Schedule.forever)) Effect.gen(function* (_) { - const actor = yield* _(Machine.boot(mailer)); + const actor = yield* _(Machine.boot(mailer)) yield* _( actor.send( - new SendEmail({ email: "test@example.com", message: "Hello, World!" }), - ), - ); + new SendEmail({ email: "test@example.com", message: "Hello, World!" }) + ) + ) yield* _( actor.send( - new SendEmail({ email: "test@example.com", message: "Hello, World!" }), - ), - ); + new SendEmail({ email: "test@example.com", message: "Hello, World!" }) + ) + ) yield* _( actor.send( - new SendEmail({ email: "test@example.com", message: "Hello, World!" }), - ), - ); - yield* _(actor.send(new Shutdown())); - }).pipe(Effect.scoped, runMain); + new SendEmail({ email: "test@example.com", message: "Hello, World!" }) + ) + ) + yield* _(actor.send(new Shutdown())) + }).pipe(Effect.scoped, runMain) ``` - Updated dependencies [[`e03811e`](https://github.com/Effect-TS/effect/commit/e03811e80c93e986e6348b3b67ac2ed6d5fefff0), [`ac41d84`](https://github.com/Effect-TS/effect/commit/ac41d84776484cdce8165b7ca2c9c9b6377eee2d), [`0f3d99c`](https://github.com/Effect-TS/effect/commit/0f3d99c27521ec6b221b644a0fffc79199c3acca), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`1bf9f31`](https://github.com/Effect-TS/effect/commit/1bf9f31f07667de677673f7c29a4e7a26ebad3c8), [`e3ff789`](https://github.com/Effect-TS/effect/commit/e3ff789226f89e71eb28ca38ce79f90af6a03f1a), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`507ba40`](https://github.com/Effect-TS/effect/commit/507ba4060ff043c1a8d541dae723fa6940633b00), [`4064ea0`](https://github.com/Effect-TS/effect/commit/4064ea04e0b3fa23108ee471cd89ab2482b2f6e5), [`e466afe`](https://github.com/Effect-TS/effect/commit/e466afe32f2de598ceafd8982bd0cfbd388e5671), [`465be79`](https://github.com/Effect-TS/effect/commit/465be7926afe98169837d8a4ed5ebc059a732d21), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`de74eb8`](https://github.com/Effect-TS/effect/commit/de74eb80a79eebde5ff645033765e7a617e92f27), [`d8e6940`](https://github.com/Effect-TS/effect/commit/d8e694040f67da6fefc0f5c98fc8e15c0b48822e), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e)]: @@ -1856,31 +1866,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1888,17 +1898,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1916,15 +1926,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/experimental/package.json b/packages/experimental/package.json index c1608104fc..e6e8ff7720 100644 --- a/packages/experimental/package.json +++ b/packages/experimental/package.json @@ -1,6 +1,6 @@ { "name": "@effect/experimental", - "version": "0.23.7", + "version": "0.24.0", "type": "module", "license": "MIT", "description": "Experimental modules for the Effect ecosystem", diff --git a/packages/opentelemetry/CHANGELOG.md b/packages/opentelemetry/CHANGELOG.md index e44ec91477..ae046904b1 100644 --- a/packages/opentelemetry/CHANGELOG.md +++ b/packages/opentelemetry/CHANGELOG.md @@ -1,5 +1,12 @@ # @effect/opentelemetry +## 0.36.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + ## 0.35.8 ### Patch Changes @@ -465,8 +472,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -702,31 +709,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -734,17 +741,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -754,15 +761,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json index abe8bb6632..9ef7900b4d 100644 --- a/packages/opentelemetry/package.json +++ b/packages/opentelemetry/package.json @@ -1,6 +1,6 @@ { "name": "@effect/opentelemetry", - "version": "0.35.8", + "version": "0.36.0", "type": "module", "license": "MIT", "description": "OpenTelemetry integration for Effect", diff --git a/packages/platform-browser/CHANGELOG.md b/packages/platform-browser/CHANGELOG.md index b0da3350d5..51f0c0611c 100644 --- a/packages/platform-browser/CHANGELOG.md +++ b/packages/platform-browser/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/platform-browser +## 0.42.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + ## 0.41.5 ### Patch Changes @@ -417,17 +425,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -884,8 +892,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1011,37 +1019,37 @@ To add cookies to a http response: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.response.empty().pipe( Http.response.setCookies([ ["name", "value"], - ["foo", "bar", { httpOnly: true }], - ]), - ); + ["foo", "bar", { httpOnly: true }] + ]) + ) ``` You can also use cookies with the http client: ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect, Ref } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect, Ref } from "effect" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(Http.cookies.empty)); - const defaultClient = yield* _(Http.client.Client); + const ref = yield* _(Ref.make(Http.cookies.empty)) + const defaultClient = yield* _(Http.client.Client) const clientWithCookies = defaultClient.pipe( Http.client.withCookiesRef(ref), - Http.client.filterStatusOk, - ); + Http.client.filterStatusOk + ) // cookies will be stored in the ref and sent in any subsequent requests yield* _( Http.request.get("https://www.google.com/"), clientWithCookies, - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#2385](https://github.com/Effect-TS/effect/pull/2385) [`3307729`](https://github.com/Effect-TS/effect/commit/3307729de162a033fa9caa8e14c111013dcf0d87) Thanks [@tim-smart](https://github.com/tim-smart)! - update typescript to 5.4 @@ -1287,26 +1295,26 @@ Some response helpers have been added to reduce the noise. ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect } from "effect" // instead of Http.request.get("/").pipe( Http.client.fetchOk(), Effect.flatMap((_) => _.json), - Effect.scoped, - ); + Effect.scoped + ) // you can do - Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json); + Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json) // other helpers include - Http.response.text; - Http.response.stream; - Http.response.arrayBuffer; - Http.response.urlParamsBody; - Http.response.formData; - Http.response.schema * Effect; + Http.response.text + Http.response.stream + Http.response.arrayBuffer + Http.response.urlParamsBody + Http.response.formData + Http.response.schema * Effect ``` ### Patch Changes @@ -1381,31 +1389,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1413,17 +1421,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1456,15 +1464,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/platform-browser/package.json b/packages/platform-browser/package.json index 6d3958bb7d..3b41f58da0 100644 --- a/packages/platform-browser/package.json +++ b/packages/platform-browser/package.json @@ -1,7 +1,7 @@ { "name": "@effect/platform-browser", "type": "module", - "version": "0.41.5", + "version": "0.42.0", "license": "MIT", "description": "Platform specific implementations for the browser", "homepage": "https://effect.website", diff --git a/packages/platform-bun/CHANGELOG.md b/packages/platform-bun/CHANGELOG.md index d127df253c..c5cbabd3d5 100644 --- a/packages/platform-bun/CHANGELOG.md +++ b/packages/platform-bun/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/platform-bun +## 0.43.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/platform-node-shared@0.13.0 + ## 0.42.5 ### Patch Changes @@ -88,21 +97,21 @@ - [#3409](https://github.com/Effect-TS/effect/pull/3409) [`056b710`](https://github.com/Effect-TS/effect/commit/056b7108978e70612176c23991916f678d947f38) Thanks @sukovanej! - Add `BunHttpServer.layerTest`. ```ts - import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"; - import { BunHttpServer } from "@effect/platform-bun"; - import { expect, it } from "bun:test"; - import { Effect } from "effect"; + import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform" + import { BunHttpServer } from "@effect/platform-bun" + import { expect, it } from "bun:test" + import { Effect } from "effect" it("test", () => Effect.gen(function* (_) { - yield* HttpServer.serveEffect(HttpRouter.empty); - const response = yield* HttpClientRequest.get("/non-existing"); - expect(response.status).toEqual(404); + yield* HttpServer.serveEffect(HttpRouter.empty) + const response = yield* HttpClientRequest.get("/non-existing") + expect(response.status).toEqual(404) }).pipe( Effect.provide(BunHttpServer.layerTest), Effect.scoped, - Effect.runPromise, - )); + Effect.runPromise + )) ``` - Updated dependencies [[`056b710`](https://github.com/Effect-TS/effect/commit/056b7108978e70612176c23991916f678d947f38)]: @@ -483,17 +492,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -995,8 +1004,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1142,37 +1151,37 @@ To add cookies to a http response: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.response.empty().pipe( Http.response.setCookies([ ["name", "value"], - ["foo", "bar", { httpOnly: true }], - ]), - ); + ["foo", "bar", { httpOnly: true }] + ]) + ) ``` You can also use cookies with the http client: ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect, Ref } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect, Ref } from "effect" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(Http.cookies.empty)); - const defaultClient = yield* _(Http.client.Client); + const ref = yield* _(Ref.make(Http.cookies.empty)) + const defaultClient = yield* _(Http.client.Client) const clientWithCookies = defaultClient.pipe( Http.client.withCookiesRef(ref), - Http.client.filterStatusOk, - ); + Http.client.filterStatusOk + ) // cookies will be stored in the ref and sent in any subsequent requests yield* _( Http.request.get("https://www.google.com/"), clientWithCookies, - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#2385](https://github.com/Effect-TS/effect/pull/2385) [`3307729`](https://github.com/Effect-TS/effect/commit/3307729de162a033fa9caa8e14c111013dcf0d87) Thanks [@tim-smart](https://github.com/tim-smart)! - update typescript to 5.4 @@ -1348,14 +1357,14 @@ Here is an example server that handles websockets on the `/ws` path: ```ts - import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"; - import * as Http from "@effect/platform/HttpServer"; - import { Console, Effect, Layer, Schedule, Stream } from "effect"; - import { createServer } from "node:http"; + import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" + import * as Http from "@effect/platform/HttpServer" + import { Console, Effect, Layer, Schedule, Stream } from "effect" + import { createServer } from "node:http" const ServerLive = NodeHttpServer.server.layer(() => createServer(), { - port: 3000, - }); + port: 3000 + }) const HttpLive = Http.router.empty.pipe( Http.router.get( @@ -1367,17 +1376,17 @@ Stream.encodeText, Stream.pipeThroughChannel(Http.request.upgradeChannel()), Stream.decodeText(), - Stream.runForEach(Console.log), - ); - return Http.response.empty(); - }), + Stream.runForEach(Console.log) + ) + return Http.response.empty() + }) ), Http.server.serve(Http.middleware.logger), Http.server.withLogAddress, - Layer.provide(ServerLive), - ); + Layer.provide(ServerLive) + ) - NodeRuntime.runMain(Layer.launch(HttpLive)); + NodeRuntime.runMain(Layer.launch(HttpLive)) ``` - Updated dependencies [[`e03811e`](https://github.com/Effect-TS/effect/commit/e03811e80c93e986e6348b3b67ac2ed6d5fefff0), [`ac41d84`](https://github.com/Effect-TS/effect/commit/ac41d84776484cdce8165b7ca2c9c9b6377eee2d), [`0f3d99c`](https://github.com/Effect-TS/effect/commit/0f3d99c27521ec6b221b644a0fffc79199c3acca), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`1bf9f31`](https://github.com/Effect-TS/effect/commit/1bf9f31f07667de677673f7c29a4e7a26ebad3c8), [`e3ff789`](https://github.com/Effect-TS/effect/commit/e3ff789226f89e71eb28ca38ce79f90af6a03f1a), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`507ba40`](https://github.com/Effect-TS/effect/commit/507ba4060ff043c1a8d541dae723fa6940633b00), [`4064ea0`](https://github.com/Effect-TS/effect/commit/4064ea04e0b3fa23108ee471cd89ab2482b2f6e5), [`e466afe`](https://github.com/Effect-TS/effect/commit/e466afe32f2de598ceafd8982bd0cfbd388e5671), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`de74eb8`](https://github.com/Effect-TS/effect/commit/de74eb80a79eebde5ff645033765e7a617e92f27), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e)]: @@ -1484,26 +1493,26 @@ Some response helpers have been added to reduce the noise. ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect } from "effect" // instead of Http.request.get("/").pipe( Http.client.fetchOk(), Effect.flatMap((_) => _.json), - Effect.scoped, - ); + Effect.scoped + ) // you can do - Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json); + Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json) // other helpers include - Http.response.text; - Http.response.stream; - Http.response.arrayBuffer; - Http.response.urlParamsBody; - Http.response.formData; - Http.response.schema * Effect; + Http.response.text + Http.response.stream + Http.response.arrayBuffer + Http.response.urlParamsBody + Http.response.formData + Http.response.schema * Effect ``` ### Patch Changes @@ -1580,31 +1589,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1612,17 +1621,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1657,15 +1666,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/platform-bun/package.json b/packages/platform-bun/package.json index 5b54aaf5e8..dab5fc1151 100644 --- a/packages/platform-bun/package.json +++ b/packages/platform-bun/package.json @@ -1,7 +1,7 @@ { "name": "@effect/platform-bun", "type": "module", - "version": "0.42.5", + "version": "0.43.0", "license": "MIT", "description": "Platform specific implementations for the Bun runtime", "homepage": "https://effect.website", diff --git a/packages/platform-node-shared/CHANGELOG.md b/packages/platform-node-shared/CHANGELOG.md index 509a00cc62..d38b5da3a7 100644 --- a/packages/platform-node-shared/CHANGELOG.md +++ b/packages/platform-node-shared/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/platform-node-shared +## 0.13.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + ## 0.12.5 ### Patch Changes @@ -409,17 +417,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -847,13 +855,13 @@ your effects. ```ts - import { Layer } from "effect"; - import { FileSystem } from "@effect/platform"; - import { NodeFileSystem } from "@effect/platform-node"; - import * as ParcelWatcher from "@effect/platform-node/NodeFileSystem/ParcelWatcher"; + import { Layer } from "effect" + import { FileSystem } from "@effect/platform" + import { NodeFileSystem } from "@effect/platform-node" + import * as ParcelWatcher from "@effect/platform-node/NodeFileSystem/ParcelWatcher" // create a Layer that uses the ParcelWatcher backend - NodeFileSystem.layer.pipe(Layer.provide(ParcelWatcher.layer)); + NodeFileSystem.layer.pipe(Layer.provide(ParcelWatcher.layer)) ``` - Updated dependencies [[`3da0cfa`](https://github.com/Effect-TS/effect/commit/3da0cfa12c407fd930dc480be1ecc9217a8058f8), [`570e8d8`](https://github.com/Effect-TS/effect/commit/570e8d87e7c0e9ad4cd2686462fdb9b4812f7716), [`87c5687`](https://github.com/Effect-TS/effect/commit/87c5687de0782dab177b7861217fa3b040046282), [`8edacca`](https://github.com/Effect-TS/effect/commit/8edacca37f8e37c01a63fec332b06d9361efaa7b)]: @@ -877,8 +885,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -994,11 +1002,11 @@ With this api you can convert an Effect Stream into a node.js Readable stream. ```ts - import { Stream } from "effect"; - import * as NodeStream from "@effect/platform-node/NodeStream"; + import { Stream } from "effect" + import * as NodeStream from "@effect/platform-node/NodeStream" // Effect - NodeStream.toReadable(Stream.make("a", "b", "c")); + NodeStream.toReadable(Stream.make("a", "b", "c")) ``` - Updated dependencies [[`26435ec`](https://github.com/Effect-TS/effect/commit/26435ecfa06569dc18d1801ccf38213a43b7c334), [`6180c0c`](https://github.com/Effect-TS/effect/commit/6180c0cc51dee785cfce72220a52c9fc3b9bf9aa)]: @@ -1022,37 +1030,37 @@ To add cookies to a http response: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.response.empty().pipe( Http.response.setCookies([ ["name", "value"], - ["foo", "bar", { httpOnly: true }], - ]), - ); + ["foo", "bar", { httpOnly: true }] + ]) + ) ``` You can also use cookies with the http client: ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect, Ref } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect, Ref } from "effect" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(Http.cookies.empty)); - const defaultClient = yield* _(Http.client.Client); + const ref = yield* _(Ref.make(Http.cookies.empty)) + const defaultClient = yield* _(Http.client.Client) const clientWithCookies = defaultClient.pipe( Http.client.withCookiesRef(ref), - Http.client.filterStatusOk, - ); + Http.client.filterStatusOk + ) // cookies will be stored in the ref and sent in any subsequent requests yield* _( Http.request.get("https://www.google.com/"), clientWithCookies, - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#2385](https://github.com/Effect-TS/effect/pull/2385) [`3307729`](https://github.com/Effect-TS/effect/commit/3307729de162a033fa9caa8e14c111013dcf0d87) Thanks [@tim-smart](https://github.com/tim-smart)! - update typescript to 5.4 @@ -1131,14 +1139,14 @@ It can be used to listen for file system events. Example: ```ts - import { FileSystem } from "@effect/platform"; - import { NodeFileSystem, NodeRuntime } from "@effect/platform-node"; - import { Console, Effect, Stream } from "effect"; + import { FileSystem } from "@effect/platform" + import { NodeFileSystem, NodeRuntime } from "@effect/platform-node" + import { Console, Effect, Stream } from "effect" Effect.gen(function* (_) { - const fs = yield* _(FileSystem.FileSystem); - yield* _(fs.watch("./"), Stream.runForEach(Console.log)); - }).pipe(Effect.provide(NodeFileSystem.layer), NodeRuntime.runMain); + const fs = yield* _(FileSystem.FileSystem) + yield* _(fs.watch("./"), Stream.runForEach(Console.log)) + }).pipe(Effect.provide(NodeFileSystem.layer), NodeRuntime.runMain) ``` - Updated dependencies [[`69d27bb`](https://github.com/Effect-TS/effect/commit/69d27bb633884b6b50f9c3d9e95c29f09b4860b5)]: @@ -1265,9 +1273,9 @@ Along the same line of the other changes this allows to shorten the most common types such as: ```ts - import { Either } from "effect"; + import { Either } from "effect" - const right: Either.Either = Either.right("ok"); + const right: Either.Either = Either.right("ok") ``` ### Patch Changes @@ -1391,31 +1399,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1423,17 +1431,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1445,15 +1453,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/platform-node-shared/package.json b/packages/platform-node-shared/package.json index 6d5845c0b6..653cf781c4 100644 --- a/packages/platform-node-shared/package.json +++ b/packages/platform-node-shared/package.json @@ -1,7 +1,7 @@ { "name": "@effect/platform-node-shared", "type": "module", - "version": "0.12.5", + "version": "0.13.0", "license": "MIT", "description": "Unified interfaces for common platform-specific services", "homepage": "https://effect.website", diff --git a/packages/platform-node/CHANGELOG.md b/packages/platform-node/CHANGELOG.md index 2e2140615a..d1c79d11cf 100644 --- a/packages/platform-node/CHANGELOG.md +++ b/packages/platform-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/platform-node +## 0.58.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/platform-node-shared@0.13.0 + ## 0.57.5 ### Patch Changes @@ -94,18 +103,18 @@ - [#3409](https://github.com/Effect-TS/effect/pull/3409) [`056b710`](https://github.com/Effect-TS/effect/commit/056b7108978e70612176c23991916f678d947f38) Thanks @sukovanej! - Add `NodeHttpServer.layerTest`. ```ts - import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform"; - import { NodeHttpServer } from "@effect/platform-node"; - import { expect, it } from "@effect/vitest"; - import { Effect } from "effect"; + import { HttpClientRequest, HttpRouter, HttpServer } from "@effect/platform" + import { NodeHttpServer } from "@effect/platform-node" + import { expect, it } from "@effect/vitest" + import { Effect } from "effect" it.scoped("test", () => Effect.gen(function* () { - yield* HttpServer.serveEffect(HttpRouter.empty); - const response = yield* HttpClientRequest.get("/"); - expect(response.status, 404); - }).pipe(Effect.provide(NodeHttpServer.layerTest)), - ); + yield* HttpServer.serveEffect(HttpRouter.empty) + const response = yield* HttpClientRequest.get("/") + expect(response.status, 404) + }).pipe(Effect.provide(NodeHttpServer.layerTest)) + ) ``` - Updated dependencies [[`056b710`](https://github.com/Effect-TS/effect/commit/056b7108978e70612176c23991916f678d947f38)]: @@ -492,17 +501,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -819,13 +828,13 @@ You now have to provide a WebSocketConstructor implementation to the `Socket.makeWebSocket` api. ```ts - import * as Socket from "@effect/platform/Socket"; - import * as NodeSocket from "@effect/platform-node/NodeSocket"; - import { Effect } from "effect"; + import * as Socket from "@effect/platform/Socket" + import * as NodeSocket from "@effect/platform-node/NodeSocket" + import { Effect } from "effect" Socket.makeWebSocket("ws://localhost:8080").pipe( - Effect.provide(NodeSocket.layerWebSocketConstructor), // use "ws" npm package - ); + Effect.provide(NodeSocket.layerWebSocketConstructor) // use "ws" npm package + ) ``` ### Patch Changes @@ -1024,8 +1033,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1139,11 +1148,11 @@ This makes it easier to quickly create a request and execute it in a single line. ```ts - import * as Http from "@effect/platform/HttpClient"; + import * as Http from "@effect/platform/HttpClient" Http.request .get("https://jsonplaceholder.typicode.com/todos/1") - .pipe(Http.response.json); + .pipe(Http.response.json) ``` - [#2413](https://github.com/Effect-TS/effect/pull/2413) [`4789083`](https://github.com/Effect-TS/effect/commit/4789083283bdaec456982d614ebc4a496ea0e7f7) Thanks [@tim-smart](https://github.com/tim-smart)! - prevent unhandled errors in undici http client @@ -1195,37 +1204,37 @@ To add cookies to a http response: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.response.empty().pipe( Http.response.setCookies([ ["name", "value"], - ["foo", "bar", { httpOnly: true }], - ]), - ); + ["foo", "bar", { httpOnly: true }] + ]) + ) ``` You can also use cookies with the http client: ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect, Ref } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect, Ref } from "effect" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(Http.cookies.empty)); - const defaultClient = yield* _(Http.client.Client); + const ref = yield* _(Ref.make(Http.cookies.empty)) + const defaultClient = yield* _(Http.client.Client) const clientWithCookies = defaultClient.pipe( Http.client.withCookiesRef(ref), - Http.client.filterStatusOk, - ); + Http.client.filterStatusOk + ) // cookies will be stored in the ref and sent in any subsequent requests yield* _( Http.request.get("https://www.google.com/"), clientWithCookies, - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#2385](https://github.com/Effect-TS/effect/pull/2385) [`3307729`](https://github.com/Effect-TS/effect/commit/3307729de162a033fa9caa8e14c111013dcf0d87) Thanks [@tim-smart](https://github.com/tim-smart)! - update typescript to 5.4 @@ -1403,14 +1412,14 @@ Here is an example server that handles websockets on the `/ws` path: ```ts - import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"; - import * as Http from "@effect/platform/HttpServer"; - import { Console, Effect, Layer, Schedule, Stream } from "effect"; - import { createServer } from "node:http"; + import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" + import * as Http from "@effect/platform/HttpServer" + import { Console, Effect, Layer, Schedule, Stream } from "effect" + import { createServer } from "node:http" const ServerLive = NodeHttpServer.server.layer(() => createServer(), { - port: 3000, - }); + port: 3000 + }) const HttpLive = Http.router.empty.pipe( Http.router.get( @@ -1422,17 +1431,17 @@ Stream.encodeText, Stream.pipeThroughChannel(Http.request.upgradeChannel()), Stream.decodeText(), - Stream.runForEach(Console.log), - ); - return Http.response.empty(); - }), + Stream.runForEach(Console.log) + ) + return Http.response.empty() + }) ), Http.server.serve(Http.middleware.logger), Http.server.withLogAddress, - Layer.provide(ServerLive), - ); + Layer.provide(ServerLive) + ) - NodeRuntime.runMain(Layer.launch(HttpLive)); + NodeRuntime.runMain(Layer.launch(HttpLive)) ``` - Updated dependencies [[`e03811e`](https://github.com/Effect-TS/effect/commit/e03811e80c93e986e6348b3b67ac2ed6d5fefff0), [`ac41d84`](https://github.com/Effect-TS/effect/commit/ac41d84776484cdce8165b7ca2c9c9b6377eee2d), [`0f3d99c`](https://github.com/Effect-TS/effect/commit/0f3d99c27521ec6b221b644a0fffc79199c3acca), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`1bf9f31`](https://github.com/Effect-TS/effect/commit/1bf9f31f07667de677673f7c29a4e7a26ebad3c8), [`e3ff789`](https://github.com/Effect-TS/effect/commit/e3ff789226f89e71eb28ca38ce79f90af6a03f1a), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`507ba40`](https://github.com/Effect-TS/effect/commit/507ba4060ff043c1a8d541dae723fa6940633b00), [`4064ea0`](https://github.com/Effect-TS/effect/commit/4064ea04e0b3fa23108ee471cd89ab2482b2f6e5), [`e466afe`](https://github.com/Effect-TS/effect/commit/e466afe32f2de598ceafd8982bd0cfbd388e5671), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`de74eb8`](https://github.com/Effect-TS/effect/commit/de74eb80a79eebde5ff645033765e7a617e92f27), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e), [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e)]: @@ -1547,26 +1556,26 @@ Some response helpers have been added to reduce the noise. ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect } from "effect" // instead of Http.request.get("/").pipe( Http.client.fetchOk(), Effect.flatMap((_) => _.json), - Effect.scoped, - ); + Effect.scoped + ) // you can do - Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json); + Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json) // other helpers include - Http.response.text; - Http.response.stream; - Http.response.arrayBuffer; - Http.response.urlParamsBody; - Http.response.formData; - Http.response.schema * Effect; + Http.response.text + Http.response.stream + Http.response.arrayBuffer + Http.response.urlParamsBody + Http.response.formData + Http.response.schema * Effect ``` ### Patch Changes @@ -1643,31 +1652,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1675,17 +1684,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1720,15 +1729,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/platform-node/package.json b/packages/platform-node/package.json index e01d375b42..b8092047eb 100644 --- a/packages/platform-node/package.json +++ b/packages/platform-node/package.json @@ -1,7 +1,7 @@ { "name": "@effect/platform-node", "type": "module", - "version": "0.57.5", + "version": "0.58.0", "license": "MIT", "description": "Platform specific implementations for the Node.js runtime", "homepage": "https://effect.website", diff --git a/packages/platform/CHANGELOG.md b/packages/platform/CHANGELOG.md index a01b474a8d..1049310960 100644 --- a/packages/platform/CHANGELOG.md +++ b/packages/platform/CHANGELOG.md @@ -1,5 +1,20 @@ # @effect/platform +## 0.63.0 + +### Patch Changes + +- [#3410](https://github.com/Effect-TS/effect/pull/3410) [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f) Thanks @tim-smart! - add HttpApi modules + + The `HttpApi` family of modules provide a declarative way to define HTTP APIs. + + For more infomation see the README.md for the /platform package:
+ https://github.com/Effect-TS/effect/blob/main/packages/platform/README.md + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/schema@0.72.0 + ## 0.62.5 ### Patch Changes @@ -368,26 +383,26 @@ You can it for both errors and success values. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" import { HttpRouter, HttpServerRespondable, - HttpServerResponse, - } from "@effect/platform"; + HttpServerResponse + } from "@effect/platform" class User extends Schema.Class("User")({ - name: Schema.String, + name: Schema.String }) { [HttpServerRespondable.symbol]() { - return HttpServerResponse.schemaJson(User)(this); + return HttpServerResponse.schemaJson(User)(this) } } class MyError extends Schema.TaggedError()("MyError", { - message: Schema.String, + message: Schema.String }) { [HttpServerRespondable.symbol]() { - return HttpServerResponse.schemaJson(MyError)(this, { status: 403 }); + return HttpServerResponse.schemaJson(MyError)(this, { status: 403 }) } } @@ -395,8 +410,8 @@ // responds with `{ "name": "test" }` HttpRouter.get("/user", Effect.succeed(new User({ name: "test" }))), // responds with a 403 status, and `{ "_tag": "MyError", "message": "boom" }` - HttpRouter.get("/fail", new MyError({ message: "boom" })), - ); + HttpRouter.get("/fail", new MyError({ message: "boom" })) + ) ``` - [#3088](https://github.com/Effect-TS/effect/pull/3088) [`a48ee84`](https://github.com/Effect-TS/effect/commit/a48ee845ac21bbde9baf938af9e97a98322211c9) Thanks @tim-smart! - swap type parameters for HttpRouter.Tag, so request context comes first @@ -413,9 +428,9 @@ HttpClientResponse.matchStatusScoped({ "2xx": (_response) => Effect.succeed("ok"), 404: (_response) => Effect.fail("not found"), - orElse: (_response) => Effect.fail("boom"), - }), - ); + orElse: (_response) => Effect.fail("boom") + }) + ) ``` - [#3079](https://github.com/Effect-TS/effect/pull/3079) [`bbdd365`](https://github.com/Effect-TS/effect/commit/bbdd36567706c94cdec45bacea825941c347b6cd) Thanks @tim-smart! - update to typescript 5.5 @@ -456,10 +471,10 @@ HttpMiddleware, HttpRouter, HttpServer, - HttpServerResponse, - } from "@effect/platform"; - import { BunHttpServer, BunRuntime } from "@effect/platform-bun"; - import { Effect, Layer } from "effect"; + HttpServerResponse + } from "@effect/platform" + import { BunHttpServer, BunRuntime } from "@effect/platform-bun" + import { Effect, Layer } from "effect" // create your router Context.Tag class UserRouter extends HttpRouter.Tag("UserRouter")() {} @@ -468,32 +483,32 @@ // There is also `.useScoped` const GetUsers = UserRouter.use((router) => Effect.gen(function* () { - yield* router.get("/", HttpServerResponse.text("got users")); - }), - ); + yield* router.get("/", HttpServerResponse.text("got users")) + }) + ) const CreateUser = UserRouter.use((router) => Effect.gen(function* () { - yield* router.post("/", HttpServerResponse.text("created user")); - }), - ); + yield* router.post("/", HttpServerResponse.text("created user")) + }) + ) - const AllRoutes = Layer.mergeAll(GetUsers, CreateUser); + const AllRoutes = Layer.mergeAll(GetUsers, CreateUser) - const ServerLive = BunHttpServer.layer({ port: 3000 }); + const ServerLive = BunHttpServer.layer({ port: 3000 }) // access the router with the `.router` api, to create your server const HttpLive = Layer.unwrapEffect( Effect.gen(function* () { - return HttpServer.serve(yield* UserRouter.router, HttpMiddleware.logger); - }), + return HttpServer.serve(yield* UserRouter.router, HttpMiddleware.logger) + }) ).pipe( Layer.provide(UserRouter.Live), Layer.provide(AllRoutes), - Layer.provide(ServerLive), - ); + Layer.provide(ServerLive) + ) - BunRuntime.runMain(Layer.launch(HttpLive)); + BunRuntime.runMain(Layer.launch(HttpLive)) ``` - Updated dependencies [[`66a1910`](https://github.com/Effect-TS/effect/commit/66a19109ff90c4252123b8809b8c8a74681dba6a)]: @@ -543,17 +558,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -672,15 +687,15 @@ For example, the following code would log `Invalid URL: '/api/v1/users' with base 'NaN'`. ```js - import { makeUrl } from "@effect/platform/Http/UrlParams"; + import { makeUrl } from "@effect/platform/Http/UrlParams" - globalThis.location = { href: "" }; + globalThis.location = { href: "" } - const url = makeUrl("/api/v1/users", []); + const url = makeUrl("/api/v1/users", []) // This would log "Invalid URL: '/api/v1/users' with base 'NaN'", // because location.origin + location.pathname return NaN in baseUrl() - console.log(url.left.message); + console.log(url.left.message) ``` Arguably, this is not an issue of Effect per se, but it's better to be defensive and handle such cases gracefully. @@ -883,13 +898,13 @@ You now have to provide a WebSocketConstructor implementation to the `Socket.makeWebSocket` api. ```ts - import * as Socket from "@effect/platform/Socket"; - import * as NodeSocket from "@effect/platform-node/NodeSocket"; - import { Effect } from "effect"; + import * as Socket from "@effect/platform/Socket" + import * as NodeSocket from "@effect/platform-node/NodeSocket" + import { Effect } from "effect" Socket.makeWebSocket("ws://localhost:8080").pipe( - Effect.provide(NodeSocket.layerWebSocketConstructor), // use "ws" npm package - ); + Effect.provide(NodeSocket.layerWebSocketConstructor) // use "ws" npm package + ) ``` ## 0.52.3 @@ -925,13 +940,13 @@ If you want to access the search params for a request, you can now use the `Http.request.ParsedSearchParams` tag. ```ts - import * as Http from "@effect/platform/HttpServer"; - import { Effect } from "effect"; + import * as Http from "@effect/platform/HttpServer" + import { Effect } from "effect" Effect.gen(function* () { - const searchParams = yield* Http.request.ParsedSearchParams; - console.log(searchParams); - }); + const searchParams = yield* Http.request.ParsedSearchParams + console.log(searchParams) + }) ``` The schema method has also been moved to the `ServerRequest` module. It is now available as `Http.request.schemaSearchParams`. @@ -943,11 +958,11 @@ To disable trace propagation: ```ts - import { HttpClient as Http } from "@effect/platform"; + import { HttpClient as Http } from "@effect/platform" Http.request .get("https://example.com") - .pipe(Http.client.fetchOk, Http.client.withTracerPropagation(false)); + .pipe(Http.client.fetchOk, Http.client.withTracerPropagation(false)) ``` ## 0.51.0 @@ -1081,13 +1096,13 @@ your effects. ```ts - import { Layer } from "effect"; - import { FileSystem } from "@effect/platform"; - import { NodeFileSystem } from "@effect/platform-node"; - import * as ParcelWatcher from "@effect/platform-node/NodeFileSystem/ParcelWatcher"; + import { Layer } from "effect" + import { FileSystem } from "@effect/platform" + import { NodeFileSystem } from "@effect/platform-node" + import * as ParcelWatcher from "@effect/platform-node/NodeFileSystem/ParcelWatcher" // create a Layer that uses the ParcelWatcher backend - NodeFileSystem.layer.pipe(Layer.provide(ParcelWatcher.layer)); + NodeFileSystem.layer.pipe(Layer.provide(ParcelWatcher.layer)) ``` - [#2555](https://github.com/Effect-TS/effect/pull/2555) [`8edacca`](https://github.com/Effect-TS/effect/commit/8edacca37f8e37c01a63fec332b06d9361efaa7b) Thanks [@tim-smart](https://github.com/tim-smart)! - prevent use of `Array` as import name to solve bundler issues @@ -1107,15 +1122,15 @@ Usage is now: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.router.empty.pipe( Http.router.get("/health"), Http.server.serve(), Http.middleware.withTracerDisabledWhen( - (request) => request.url === "/no-tracing", - ), - ); + (request) => request.url === "/no-tracing" + ) + ) ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`aa4a3b5`](https://github.com/Effect-TS/effect/commit/aa4a3b550da1c1020265ac389ed3f309388994a2) Thanks [@github-actions](https://github.com/apps/github-actions)! - Swap type parameters in /platform data types @@ -1133,8 +1148,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1144,15 +1159,15 @@ This change makes adjusting options to fetch more composable. You can now do: ```ts - import { pipe } from "effect"; - import * as Http from "@effect/platform/HttpClient"; + import { pipe } from "effect" + import * as Http from "@effect/platform/HttpClient" pipe( Http.request.get("https://example.com"), Http.client.fetchOk, Http.client.withFetchOptions({ credentials: "include" }), - Http.response.text, - ); + Http.response.text + ) ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`2fb7d9c`](https://github.com/Effect-TS/effect/commit/2fb7d9ca15037ff62a578bb9fe5732da5f4f317d) Thanks [@github-actions](https://github.com/apps/github-actions)! - Release Effect 3.0 🎉 @@ -1166,13 +1181,13 @@ Allows you to disable the http server tracer for the given urls: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.router.empty.pipe( Http.router.get("/health"), Http.server.serve(), - Http.middleware.withTracerDisabledForUrls(["/health"]), - ); + Http.middleware.withTracerDisabledForUrls(["/health"]) + ) ``` - [#2529](https://github.com/Effect-TS/effect/pull/2529) [`78b767c`](https://github.com/Effect-TS/effect/commit/78b767c2b1625186e17131761a0edbac25d21850) Thanks [@fubhy](https://github.com/fubhy)! - Renamed `ReadonlyArray` and `ReadonlyRecord` modules for better discoverability. @@ -1232,18 +1247,18 @@ You could do the following: ```ts - import { PlatformConfigProvider } from "@effect/platform"; - import { NodeContext } from "@effect/platform-node"; - import { Config, Effect, Layer } from "effect"; + import { PlatformConfigProvider } from "@effect/platform" + import { NodeContext } from "@effect/platform-node" + import { Config, Effect, Layer } from "effect" const ConfigProviderLive = PlatformConfigProvider.layerFileTree({ - rootDirectory: `/config`, - }).pipe(Layer.provide(NodeContext.layer)); + rootDirectory: `/config` + }).pipe(Layer.provide(NodeContext.layer)) Effect.gen(function* (_) { - const secret = yield* _(Config.secret("secret")); - const value = yield* _(Config.string("value"), Config.nested("nested")); - }).pipe(Effect.provide(ConfigProviderLive)); + const secret = yield* _(Config.secret("secret")) + const value = yield* _(Config.string("value"), Config.nested("nested")) + }).pipe(Effect.provide(ConfigProviderLive)) ``` ## 0.48.25 @@ -1308,11 +1323,11 @@ This makes it easier to quickly create a request and execute it in a single line. ```ts - import * as Http from "@effect/platform/HttpClient"; + import * as Http from "@effect/platform/HttpClient" Http.request .get("https://jsonplaceholder.typicode.com/todos/1") - .pipe(Http.response.json); + .pipe(Http.response.json) ``` - [#2413](https://github.com/Effect-TS/effect/pull/2413) [`4789083`](https://github.com/Effect-TS/effect/commit/4789083283bdaec456982d614ebc4a496ea0e7f7) Thanks [@tim-smart](https://github.com/tim-smart)! - prevent unhandled errors in undici http client @@ -1358,37 +1373,37 @@ To add cookies to a http response: ```ts - import * as Http from "@effect/platform/HttpServer"; + import * as Http from "@effect/platform/HttpServer" Http.response.empty().pipe( Http.response.setCookies([ ["name", "value"], - ["foo", "bar", { httpOnly: true }], - ]), - ); + ["foo", "bar", { httpOnly: true }] + ]) + ) ``` You can also use cookies with the http client: ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect, Ref } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect, Ref } from "effect" Effect.gen(function* (_) { - const ref = yield* _(Ref.make(Http.cookies.empty)); - const defaultClient = yield* _(Http.client.Client); + const ref = yield* _(Ref.make(Http.cookies.empty)) + const defaultClient = yield* _(Http.client.Client) const clientWithCookies = defaultClient.pipe( Http.client.withCookiesRef(ref), - Http.client.filterStatusOk, - ); + Http.client.filterStatusOk + ) // cookies will be stored in the ref and sent in any subsequent requests yield* _( Http.request.get("https://www.google.com/"), clientWithCookies, - Effect.scoped, - ); - }); + Effect.scoped + ) + }) ``` - [#2385](https://github.com/Effect-TS/effect/pull/2385) [`3307729`](https://github.com/Effect-TS/effect/commit/3307729de162a033fa9caa8e14c111013dcf0d87) Thanks [@tim-smart](https://github.com/tim-smart)! - update typescript to 5.4 @@ -1460,14 +1475,14 @@ It can be used to listen for file system events. Example: ```ts - import { FileSystem } from "@effect/platform"; - import { NodeFileSystem, NodeRuntime } from "@effect/platform-node"; - import { Console, Effect, Stream } from "effect"; + import { FileSystem } from "@effect/platform" + import { NodeFileSystem, NodeRuntime } from "@effect/platform-node" + import { Console, Effect, Stream } from "effect" Effect.gen(function* (_) { - const fs = yield* _(FileSystem.FileSystem); - yield* _(fs.watch("./"), Stream.runForEach(Console.log)); - }).pipe(Effect.provide(NodeFileSystem.layer), NodeRuntime.runMain); + const fs = yield* _(FileSystem.FileSystem) + yield* _(fs.watch("./"), Stream.runForEach(Console.log)) + }).pipe(Effect.provide(NodeFileSystem.layer), NodeRuntime.runMain) ``` - Updated dependencies [[`d0f56c6`](https://github.com/Effect-TS/effect/commit/d0f56c68e604b1cf8dd4e761a3f3cf3631b3cec1)]: @@ -1580,22 +1595,22 @@ If you wanted to write logfmt logs to a file, you can do the following: ```ts - import { PlatformLogger } from "@effect/platform"; - import { NodeFileSystem, NodeRuntime } from "@effect/platform-node"; - import { Effect, Layer, Logger } from "effect"; + import { PlatformLogger } from "@effect/platform" + import { NodeFileSystem, NodeRuntime } from "@effect/platform-node" + import { Effect, Layer, Logger } from "effect" - const fileLogger = Logger.logfmtLogger.pipe(PlatformLogger.toFile("log.txt")); + const fileLogger = Logger.logfmtLogger.pipe(PlatformLogger.toFile("log.txt")) const LoggerLive = Logger.replaceScoped( Logger.defaultLogger, - fileLogger, - ).pipe(Layer.provide(NodeFileSystem.layer)); + fileLogger + ).pipe(Layer.provide(NodeFileSystem.layer)) Effect.log("a").pipe( Effect.zipRight(Effect.log("b")), Effect.zipRight(Effect.log("c")), Effect.provide(LoggerLive), - NodeRuntime.runMain, - ); + NodeRuntime.runMain + ) ``` - [#2261](https://github.com/Effect-TS/effect/pull/2261) [`fa9663c`](https://github.com/Effect-TS/effect/commit/fa9663cb854ca03dba672d7857ecff84f1140c9e) Thanks [@tim-smart](https://github.com/tim-smart)! - add websocket support to platform http server @@ -1605,14 +1620,14 @@ Here is an example server that handles websockets on the `/ws` path: ```ts - import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"; - import * as Http from "@effect/platform/HttpServer"; - import { Console, Effect, Layer, Schedule, Stream } from "effect"; - import { createServer } from "node:http"; + import { NodeHttpServer, NodeRuntime } from "@effect/platform-node" + import * as Http from "@effect/platform/HttpServer" + import { Console, Effect, Layer, Schedule, Stream } from "effect" + import { createServer } from "node:http" const ServerLive = NodeHttpServer.server.layer(() => createServer(), { - port: 3000, - }); + port: 3000 + }) const HttpLive = Http.router.empty.pipe( Http.router.get( @@ -1624,17 +1639,17 @@ Stream.encodeText, Stream.pipeThroughChannel(Http.request.upgradeChannel()), Stream.decodeText(), - Stream.runForEach(Console.log), - ); - return Http.response.empty(); - }), + Stream.runForEach(Console.log) + ) + return Http.response.empty() + }) ), Http.server.serve(Http.middleware.logger), Http.server.withLogAddress, - Layer.provide(ServerLive), - ); + Layer.provide(ServerLive) + ) - NodeRuntime.runMain(Layer.launch(HttpLive)); + NodeRuntime.runMain(Layer.launch(HttpLive)) ``` - Updated dependencies [[`e03811e`](https://github.com/Effect-TS/effect/commit/e03811e80c93e986e6348b3b67ac2ed6d5fefff0), [`ac41d84`](https://github.com/Effect-TS/effect/commit/ac41d84776484cdce8165b7ca2c9c9b6377eee2d), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`1bf9f31`](https://github.com/Effect-TS/effect/commit/1bf9f31f07667de677673f7c29a4e7a26ebad3c8), [`e3ff789`](https://github.com/Effect-TS/effect/commit/e3ff789226f89e71eb28ca38ce79f90af6a03f1a), [`6137533`](https://github.com/Effect-TS/effect/commit/613753300c7705518ab1fea2f370b032851c2750), [`507ba40`](https://github.com/Effect-TS/effect/commit/507ba4060ff043c1a8d541dae723fa6940633b00), [`e466afe`](https://github.com/Effect-TS/effect/commit/e466afe32f2de598ceafd8982bd0cfbd388e5671), [`465be79`](https://github.com/Effect-TS/effect/commit/465be7926afe98169837d8a4ed5ebc059a732d21), [`f373529`](https://github.com/Effect-TS/effect/commit/f373529999f4b8bc92b634f6ea14f19271388eed), [`de74eb8`](https://github.com/Effect-TS/effect/commit/de74eb80a79eebde5ff645033765e7a617e92f27), [`d8e6940`](https://github.com/Effect-TS/effect/commit/d8e694040f67da6fefc0f5c98fc8e15c0b48822e)]: @@ -1651,10 +1666,10 @@ ```ts // Here a request to `/child/hello` will be mapped to `/hello` - Http.router.mountApp("/child", httpApp); + Http.router.mountApp("/child", httpApp) // Here a request to `/child/hello` will be mapped to `/child/hello` - Http.router.mountApp("/child", httpApp, { includePrefix: true }); + Http.router.mountApp("/child", httpApp, { includePrefix: true }) ``` - [#2232](https://github.com/Effect-TS/effect/pull/2232) [`bd1d7ac`](https://github.com/Effect-TS/effect/commit/bd1d7ac75eea57a94d5e2d8e1edccb3136e84899) Thanks [@tim-smart](https://github.com/tim-smart)! - use less aggressive type exclusion in http router apis @@ -1715,10 +1730,10 @@ Example: ```ts - import { Effect } from "effect"; - import * as Http from "@effect/platform/HttpServer"; + import { Effect } from "effect" + import * as Http from "@effect/platform/HttpServer" - Http.response.html`${Effect.succeed(123)}`; + Http.response.html`${Effect.succeed(123)}` ``` - [#2174](https://github.com/Effect-TS/effect/pull/2174) [`abcb7d9`](https://github.com/Effect-TS/effect/commit/abcb7d983a4a85b43b7175e952f5b331b9019aea) Thanks [@tim-smart](https://github.com/tim-smart)! - add Template module to platform @@ -1728,12 +1743,12 @@ Example: ```ts - import { Effect } from "effect"; - import { Template } from "@effect/platform"; + import { Effect } from "effect" + import { Template } from "@effect/platform" - const t = Template.make`${Effect.succeed(123)}`; + const t = Template.make`${Effect.succeed(123)}` - Effect.runSync(t); // returns "123" + Effect.runSync(t) // returns "123" ``` - Updated dependencies [[`bc8404d`](https://github.com/Effect-TS/effect/commit/bc8404d54fd42072d200c0399cb39672837afa9f), [`2c5cbcd`](https://github.com/Effect-TS/effect/commit/2c5cbcd1161b4f40dab184999291e817314107de), [`6565916`](https://github.com/Effect-TS/effect/commit/6565916ef254bf910e47d25fd0ef55e7cb420241)]: @@ -1774,26 +1789,26 @@ Some response helpers have been added to reduce the noise. ```ts - import * as Http from "@effect/platform/HttpClient"; - import { Effect } from "effect"; + import * as Http from "@effect/platform/HttpClient" + import { Effect } from "effect" // instead of Http.request.get("/").pipe( Http.client.fetchOk(), Effect.flatMap((_) => _.json), - Effect.scoped, - ); + Effect.scoped + ) // you can do - Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json); + Http.request.get("/").pipe(Http.client.fetchOk(), Http.response.json) // other helpers include - Http.response.text; - Http.response.stream; - Http.response.arrayBuffer; - Http.response.urlParamsBody; - Http.response.formData; - Http.response.schema * Effect; + Http.response.text + Http.response.stream + Http.response.arrayBuffer + Http.response.urlParamsBody + Http.response.formData + Http.response.schema * Effect ``` ## 0.44.7 @@ -1856,31 +1871,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1888,17 +1903,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1939,21 +1954,21 @@ At the type level instead the functions return `Readonly` variants, so for example we have: ```ts - import { Data } from "effect"; + import { Data } from "effect" const obj = Data.struct({ a: 0, - b: 1, - }); + b: 1 + }) ``` will have the `obj` typed as: ```ts declare const obj: { - readonly a: number; - readonly b: number; - }; + readonly a: number + readonly b: number + } ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`6361ee2`](https://github.com/Effect-TS/effect/commit/6361ee2e83bdfead24045c3d058a7298efc18113) Thanks [@github-actions](https://github.com/apps/github-actions)! - fix for encoding of Transferable schemas @@ -1967,26 +1982,26 @@ to wrap the outermost schema: ```ts - import { Transferable } from "@effect/platform"; - import { Schema } from "@effect/schema"; + import { Transferable } from "@effect/platform" + import { Schema } from "@effect/schema" const structWithTransferable = Schema.struct({ - data: Transferable.Uint8Array, - }); + data: Transferable.Uint8Array + }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/platform/package.json b/packages/platform/package.json index 8db020adf1..04dd02ba4e 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -1,7 +1,7 @@ { "name": "@effect/platform", "type": "module", - "version": "0.62.5", + "version": "0.63.0", "license": "MIT", "description": "Unified interfaces for common platform-specific services", "homepage": "https://effect.website", diff --git a/packages/printer-ansi/CHANGELOG.md b/packages/printer-ansi/CHANGELOG.md index 9d30ceb2e7..74c70983a8 100644 --- a/packages/printer-ansi/CHANGELOG.md +++ b/packages/printer-ansi/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/printer-ansi +## 0.35.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/printer@0.35.0 + - @effect/typeclass@0.26.0 + ## 0.34.8 ### Patch Changes @@ -565,8 +574,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` diff --git a/packages/printer-ansi/package.json b/packages/printer-ansi/package.json index 2d7693451e..f029df62f2 100644 --- a/packages/printer-ansi/package.json +++ b/packages/printer-ansi/package.json @@ -1,6 +1,6 @@ { "name": "@effect/printer-ansi", - "version": "0.34.8", + "version": "0.35.0", "type": "module", "license": "MIT", "description": "An easy to use, extensible pretty-printer for rendering documents for the terminal", diff --git a/packages/printer/CHANGELOG.md b/packages/printer/CHANGELOG.md index f4d9e5019f..36d19166a5 100644 --- a/packages/printer/CHANGELOG.md +++ b/packages/printer/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/printer +## 0.35.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/typeclass@0.26.0 + ## 0.34.8 ### Patch Changes @@ -504,8 +512,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -563,22 +571,22 @@ Before: ```ts - import * as Doc from "@effect/printer/Doc"; - import * as Render from "@effect/printer/Render"; + import * as Doc from "@effect/printer/Doc" + import * as Render from "@effect/printer/Render" - const doc = Doc.cat(Doc.text("Hello, "), Doc.text("World!")); + const doc = Doc.cat(Doc.text("Hello, "), Doc.text("World!")) - console.log(Render.prettyDefault(doc)); + console.log(Render.prettyDefault(doc)) ``` After: ```ts - import * as Doc from "@effect/printer/Doc"; + import * as Doc from "@effect/printer/Doc" - const doc = Doc.cat(Doc.text("Hello, "), Doc.text("World!")); + const doc = Doc.cat(Doc.text("Hello, "), Doc.text("World!")) - console.log(Doc.render(doc, { style: "pretty" })); + console.log(Doc.render(doc, { style: "pretty" })) ``` ### Patch Changes diff --git a/packages/printer/package.json b/packages/printer/package.json index ae8ef7ec31..cbd2b5a625 100644 --- a/packages/printer/package.json +++ b/packages/printer/package.json @@ -1,6 +1,6 @@ { "name": "@effect/printer", - "version": "0.34.8", + "version": "0.35.0", "type": "module", "license": "MIT", "description": "An easy to use, extensible pretty-printer for rendering documents", diff --git a/packages/rpc-http/CHANGELOG.md b/packages/rpc-http/CHANGELOG.md index 87ea776c93..3e9c173f2d 100644 --- a/packages/rpc-http/CHANGELOG.md +++ b/packages/rpc-http/CHANGELOG.md @@ -1,5 +1,15 @@ # @effect/rpc-http +## 0.35.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/rpc@0.37.0 + - @effect/schema@0.72.0 + ## 0.34.5 ### Patch Changes @@ -484,17 +494,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -1008,8 +1018,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1019,15 +1029,15 @@ This change makes adjusting options to fetch more composable. You can now do: ```ts - import { pipe } from "effect"; - import * as Http from "@effect/platform/HttpClient"; + import { pipe } from "effect" + import * as Http from "@effect/platform/HttpClient" pipe( Http.request.get("https://example.com"), Http.client.fetchOk, Http.client.withFetchOptions({ credentials: "include" }), - Http.response.text, - ); + Http.response.text + ) ``` - [#2207](https://github.com/Effect-TS/effect/pull/2207) [`2fb7d9c`](https://github.com/Effect-TS/effect/commit/2fb7d9ca15037ff62a578bb9fe5732da5f4f317d) Thanks [@github-actions](https://github.com/apps/github-actions)! - Release Effect 3.0 🎉 @@ -1552,31 +1562,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1584,17 +1594,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1614,15 +1624,15 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/rpc-http/package.json b/packages/rpc-http/package.json index 5c46382db8..1f56c94a9e 100644 --- a/packages/rpc-http/package.json +++ b/packages/rpc-http/package.json @@ -1,6 +1,6 @@ { "name": "@effect/rpc-http", - "version": "0.34.5", + "version": "0.35.0", "type": "module", "license": "MIT", "description": "Functional programming in TypeScript", diff --git a/packages/rpc/CHANGELOG.md b/packages/rpc/CHANGELOG.md index 51ad3341bd..39335b0d5b 100644 --- a/packages/rpc/CHANGELOG.md +++ b/packages/rpc/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/rpc +## 0.37.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/schema@0.72.0 + ## 0.36.5 ### Patch Changes @@ -173,27 +182,27 @@ from ```ts - import * as Rpc from "@effect/rpc/Rpc"; - import { Schema } from "@effect/schema"; + import * as Rpc from "@effect/rpc/Rpc" + import { Schema } from "@effect/schema" export class Counts extends Rpc.StreamRequest()( "Counts", Schema.Never, // Indicates that no errors are expected Schema.Number, // Specifies that the response is a number - {}, + {} ) {} ``` to ```ts - import * as Rpc from "@effect/rpc/Rpc"; - import { Schema } from "@effect/schema"; + import * as Rpc from "@effect/rpc/Rpc" + import { Schema } from "@effect/schema" export class Counts extends Rpc.StreamRequest()("Counts", { failure: Schema.Never, // Indicates that no errors are expected success: Schema.Number, // Specifies that the response is a number - payload: {}, + payload: {} }) {} ``` @@ -475,17 +484,17 @@ Before: ```ts - import { HttpClient } from "@effect/platform"; + import { HttpClient } from "@effect/platform" - HttpClient.request.get("/").pipe(HttpClient.client.fetchOk); + HttpClient.request.get("/").pipe(HttpClient.client.fetchOk) ``` After: ```ts - import { HttpClient, HttpClientRequest } from "@effect/platform"; + import { HttpClient, HttpClientRequest } from "@effect/platform" - HttpClientRequest.get("/").pipe(HttpClient.fetchOk); + HttpClientRequest.get("/").pipe(HttpClient.fetchOk) ``` ### Patch Changes @@ -960,8 +969,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -1449,31 +1458,31 @@ - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -1481,17 +1490,17 @@ Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -1521,35 +1530,35 @@ At the type level instead the functions return `Readonly` variants, so for example we have: ```ts - import { Data } from "effect"; + import { Data } from "effect" const obj = Data.struct({ a: 0, - b: 1, - }); + b: 1 + }) ``` will have the `obj` typed as: ```ts declare const obj: { - readonly a: number; - readonly b: number; - }; + readonly a: number + readonly b: number + } ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` diff --git a/packages/rpc/package.json b/packages/rpc/package.json index c8462d68d1..560a7c98a5 100644 --- a/packages/rpc/package.json +++ b/packages/rpc/package.json @@ -1,6 +1,6 @@ { "name": "@effect/rpc", - "version": "0.36.5", + "version": "0.37.0", "type": "module", "license": "MIT", "description": "Functional programming in TypeScript", diff --git a/packages/schema/CHANGELOG.md b/packages/schema/CHANGELOG.md index ce2670b45f..2b3bef45f8 100644 --- a/packages/schema/CHANGELOG.md +++ b/packages/schema/CHANGELOG.md @@ -1,5 +1,12 @@ # @effect/schema +## 0.72.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + ## 0.71.4 ### Patch Changes @@ -53,14 +60,14 @@ These schemas can be used to ensure that a value is an array, from a value that may be an array or a single value. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const schema = Schema.ArrayEnsure(Schema.String); + const schema = Schema.ArrayEnsure(Schema.String) - Schema.decodeUnknownSync(schema)("hello"); + Schema.decodeUnknownSync(schema)("hello") // => ["hello"] - Schema.decodeUnknownSync(schema)(["a", "b", "c"]); + Schema.decodeUnknownSync(schema)(["a", "b", "c"]) // => ["a", "b", "c"] ``` @@ -115,34 +122,34 @@ **Example** (string based schemas) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // const schema: Schema.Schema const schema = Schema.TemplateLiteralParser( Schema.NumberFromString, "a", - Schema.NonEmptyString, - ); + Schema.NonEmptyString + ) - console.log(Schema.decodeEither(schema)("100ab")); + console.log(Schema.decodeEither(schema)("100ab")) // { _id: 'Either', _tag: 'Right', right: [ 100, 'a', 'b' ] } - console.log(Schema.encode(schema)([100, "a", "b"])); + console.log(Schema.encode(schema)([100, "a", "b"])) // { _id: 'Either', _tag: 'Right', right: '100ab' } ``` **Example** (number based schemas) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // const schema: Schema.Schema - const schema = Schema.TemplateLiteralParser(Schema.Int, "a"); + const schema = Schema.TemplateLiteralParser(Schema.Int, "a") - console.log(Schema.decodeEither(schema)("1a")); + console.log(Schema.decodeEither(schema)("1a")) // { _id: 'Either', _tag: 'Right', right: [ 1, 'a' ] } - console.log(Schema.encode(schema)([1, "a"])); + console.log(Schema.encode(schema)([1, "a"])) // { _id: 'Either', _tag: 'Right', right: '1a' } ``` @@ -150,8 +157,8 @@ ```ts export type DecodingFallbackAnnotation
= ( - issue: ParseIssue, - ) => Effect; + issue: ParseIssue + ) => Effect ``` This update introduces a `decodingFallback` annotation, enabling custom handling of decoding failures in schemas. This feature allows developers to specify fallback behaviors when decoding operations encounter issues. @@ -159,32 +166,30 @@ **Example** ```ts - import { Schema } from "@effect/schema"; - import { Effect, Either } from "effect"; + import { Schema } from "@effect/schema" + import { Effect, Either } from "effect" // Basic Fallback const schema = Schema.String.annotations({ - decodingFallback: () => Either.right(""), - }); + decodingFallback: () => Either.right("") + }) - console.log(Schema.decodeUnknownSync(schema)("valid input")); // Output: valid input - console.log(Schema.decodeUnknownSync(schema)(null)); // Output: + console.log(Schema.decodeUnknownSync(schema)("valid input")) // Output: valid input + console.log(Schema.decodeUnknownSync(schema)(null)) // Output: // Advanced Fallback with Logging const schemaWithLog = Schema.String.annotations({ decodingFallback: (issue) => Effect.gen(function* () { - yield* Effect.log(issue._tag); - yield* Effect.sleep(10); - return yield* Effect.succeed(""); - }), - }); - - Effect.runPromise(Schema.decodeUnknown(schemaWithLog)(null)).then( - console.log, - ); + yield* Effect.log(issue._tag) + yield* Effect.sleep(10) + return yield* Effect.succeed("") + }) + }) + + Effect.runPromise(Schema.decodeUnknown(schemaWithLog)(null)).then(console.log) /* Output: timestamp=2024-07-25T13:22:37.706Z level=INFO fiber=#0 message=Type @@ -215,17 +220,17 @@ This update refines the type definitions to reflect that `ast` is always an `AST.Transformation`, eliminating the need for casting and simplifying client code. ```ts - import { AST, Schema } from "@effect/schema"; + import { AST, Schema } from "@effect/schema" class Person extends Schema.Class("Person")( { name: Schema.String, - age: Schema.Number, + age: Schema.Number }, - { description: "my description" }, + { description: "my description" } ) {} - console.log(AST.getDescriptionAnnotation(Person.ast.to)); + console.log(AST.getDescriptionAnnotation(Person.ast.to)) // { _id: 'Option', _tag: 'Some', value: 'my description' } ``` @@ -234,11 +239,11 @@ **Example** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)("")); // Option.none() - console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)(" a ")); // Option.none() - console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)("a")); // Option.some("a") + console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)("")) // Option.none() + console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)(" a ")) // Option.none() + console.log(Schema.decodeOption(Schema.NonEmptyTrimmedString)("a")) // Option.some("a") ``` - add `OptionFromNonEmptyTrimmedString`, closes #3335 @@ -246,13 +251,13 @@ **Example** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - console.log(Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)("")); // Option.none() + console.log(Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)("")) // Option.none() console.log( - Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)(" a "), - ); // Option.some("a") - console.log(Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)("a")); // Option.some("a") + Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)(" a ") + ) // Option.some("a") + console.log(Schema.decodeSync(Schema.OptionFromNonEmptyTrimmedString)("a")) // Option.some("a") ``` - Updated dependencies [[`6359644`](https://github.com/Effect-TS/effect/commit/635964446323cf55d4060559337e710e4a24496e), [`7f41e42`](https://github.com/Effect-TS/effect/commit/7f41e428830bf3043b8be0d28dcd235d5747c942), [`f566fd1`](https://github.com/Effect-TS/effect/commit/f566fd1d7eea531a0d981dd24037f14a603a1273)]: @@ -300,7 +305,7 @@ "Sample", Schema.String, // Failure Schema Schema.Number, // Success Schema - { id: Schema.String, foo: Schema.Number }, // Payload Schema + { id: Schema.String, foo: Schema.Number } // Payload Schema ) {} ``` @@ -310,10 +315,10 @@ class Sample extends Schema.TaggedRequest()("Sample", { payload: { id: Schema.String, - foo: Schema.Number, + foo: Schema.Number }, success: Schema.Number, - failure: Schema.String, + failure: Schema.String }) {} ``` @@ -325,17 +330,17 @@ Before Update ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const schema = Schema.Record(Schema.String, Schema.Number); + const schema = Schema.Record(Schema.String, Schema.Number) ``` After Update ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const schema = Schema.Record({ key: Schema.String, value: Schema.Number }); + const schema = Schema.Record({ key: Schema.String, value: Schema.Number }) ``` - rename `Base64` to `Uint8ArrayFromBase64` (**codmod**) @@ -353,7 +358,7 @@ - We've refined the `optional` and `partial` APIs by splitting them into two distinct methods: one without options (`optional` and `partial`) and another with options (`optionalWith` and `partialWith`). This change resolves issues with previous implementations when used with the `pipe` method: ```ts - Schema.String.pipe(Schema.optional); + Schema.String.pipe(Schema.optional) ``` ### ParseResult @@ -371,17 +376,17 @@ Before ```ts - import { AST } from "@effect/schema"; + import { AST } from "@effect/schema" - console.log(String(new AST.TemplateLiteralSpan(AST.stringKeyword, "a"))); // ${string} + console.log(String(new AST.TemplateLiteralSpan(AST.stringKeyword, "a"))) // ${string} ``` Now ```ts - import { AST } from "@effect/schema"; + import { AST } from "@effect/schema" - console.log(String(new AST.TemplateLiteralSpan(AST.stringKeyword, "a"))); // ${string}a + console.log(String(new AST.TemplateLiteralSpan(AST.stringKeyword, "a"))) // ${string}a ``` ### Serializable @@ -400,15 +405,15 @@ - Support for extending `Schema.String`, `Schema.Number`, and `Schema.Boolean` with refinements has been added: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const Integer = Schema.Int.pipe(Schema.brand("Int")); - const Positive = Schema.Positive.pipe(Schema.brand("Positive")); + const Integer = Schema.Int.pipe(Schema.brand("Int")) + const Positive = Schema.Positive.pipe(Schema.brand("Positive")) // Schema.Schema & Brand<"Int">, number, never> - const PositiveInteger = Schema.asSchema(Schema.extend(Positive, Integer)); + const PositiveInteger = Schema.asSchema(Schema.extend(Positive, Integer)) - Schema.decodeUnknownSync(PositiveInteger)(-1); + Schema.decodeUnknownSync(PositiveInteger)(-1) /* throws ParseError: Int & Brand<"Int"> @@ -418,7 +423,7 @@ └─ Expected Positive & Brand<"Positive">, actual -1 */ - Schema.decodeUnknownSync(PositiveInteger)(1.1); + Schema.decodeUnknownSync(PositiveInteger)(1.1) /* throws ParseError: Int & Brand<"Int"> @@ -465,14 +470,14 @@ Before ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Struct({ - a: Schema.NullishOr(Schema.Number), - }); + a: Schema.NullishOr(Schema.Number) + }) - const jsonSchema = JSONSchema.make(schema); - console.log(JSON.stringify(jsonSchema, null, 2)); + const jsonSchema = JSONSchema.make(schema) + console.log(JSON.stringify(jsonSchema, null, 2)) /* throws Error: Missing annotation @@ -485,14 +490,14 @@ Now ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Struct({ - a: Schema.NullishOr(Schema.Number), - }); + a: Schema.NullishOr(Schema.Number) + }) - const jsonSchema = JSONSchema.make(schema); - console.log(JSON.stringify(jsonSchema, null, 2)); + const jsonSchema = JSONSchema.make(schema) + console.log(JSON.stringify(jsonSchema, null, 2)) /* { "$schema": "http://json-schema.org/draft-07/schema#", @@ -531,12 +536,12 @@ Before ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" - const schema = Schema.Trim.pipe(Schema.nonEmpty()); + const schema = Schema.Trim.pipe(Schema.nonEmpty()) - const jsonSchema = JSONSchema.make(schema); - console.log(JSON.stringify(jsonSchema, null, 2)); + const jsonSchema = JSONSchema.make(schema) + console.log(JSON.stringify(jsonSchema, null, 2)) /* { "$schema": "http://json-schema.org/draft-07/schema#", @@ -548,12 +553,12 @@ Now ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" - const schema = Schema.Trim.pipe(Schema.nonEmpty()); + const schema = Schema.Trim.pipe(Schema.nonEmpty()) - const jsonSchema = JSONSchema.make(schema); - console.log(JSON.stringify(jsonSchema, null, 2)); + const jsonSchema = JSONSchema.make(schema) + console.log(JSON.stringify(jsonSchema, null, 2)) /* { "$schema": "http://json-schema.org/draft-07/schema#", @@ -633,11 +638,11 @@ Previously, when a type mismatch occurred in `Schema.decodeUnknownSync`, the error message displayed for `IndexSignature` was not accurately representing the type used. For example: ```typescript - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const schema = Schema.Record(Schema.Char, Schema.String); + const schema = Schema.Record(Schema.Char, Schema.String) - Schema.decodeUnknownSync(schema)({ a: 1 }); + Schema.decodeUnknownSync(schema)({ a: 1 }) /* throws ParseError: { readonly [x: string]: string } @@ -653,11 +658,11 @@ The `toString` implementation now correctly reflects the type used in `IndexSignature`, providing more accurate and informative error messages: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const schema = Schema.Record(Schema.Char, Schema.String); + const schema = Schema.Record(Schema.Char, Schema.String) - Schema.decodeUnknownSync(schema)({ a: 1 }); + Schema.decodeUnknownSync(schema)({ a: 1 }) /* throws ParseError: { readonly [x: Char]: string } @@ -682,24 +687,24 @@ **Example: Validating Usernames Asynchronously** ```ts - import { Schema } from "@effect/schema"; - import { Effect } from "effect"; + import { Schema } from "@effect/schema" + import { Effect } from "effect" async function validateUsername(username: string) { - return Promise.resolve(username === "gcanti"); + return Promise.resolve(username === "gcanti") } const ValidUsername = Schema.String.pipe( Schema.filterEffect((username) => Effect.promise(() => - validateUsername(username).then((valid) => valid || "Invalid username"), - ), - ), - ).annotations({ identifier: "ValidUsername" }); + validateUsername(username).then((valid) => valid || "Invalid username") + ) + ) + ).annotations({ identifier: "ValidUsername" }) Effect.runPromise(Schema.decodeUnknown(ValidUsername)("xxx")).then( - console.log, - ); + console.log + ) /* ParseError: ValidUsername └─ Transformation process failure @@ -714,16 +719,16 @@ The `pick` static function available in each struct schema can be used to create a new `Struct` by selecting particular properties from an existing `Struct`. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyStruct = Schema.Struct({ a: Schema.String, b: Schema.Number, - c: Schema.Boolean, - }); + c: Schema.Boolean + }) // Schema.Struct<{ a: typeof Schema.String; c: typeof Schema.Boolean; }> - const PickedSchema = MyStruct.pick("a", "c"); + const PickedSchema = MyStruct.pick("a", "c") ``` **omit** @@ -731,16 +736,16 @@ The `omit` static function available in each struct schema can be used to create a new `Struct` by excluding particular properties from an existing `Struct`. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyStruct = Schema.Struct({ a: Schema.String, b: Schema.Number, - c: Schema.Boolean, - }); + c: Schema.Boolean + }) // Schema.Struct<{ a: typeof Schema.String; c: typeof Schema.Boolean; }> - const PickedSchema = MyStruct.omit("b"); + const PickedSchema = MyStruct.omit("b") ``` - Updated dependencies [[`a5737d6`](https://github.com/Effect-TS/effect/commit/a5737d6db2b921605c332eabbc5402ee3d17357b)]: @@ -757,14 +762,14 @@ Before ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Record( Schema.String.pipe(Schema.minLength(1)), - Schema.Number, - ); + Schema.Number + ) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* throws Error: Unsupported index signature parameter @@ -775,14 +780,14 @@ Now ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Record( Schema.String.pipe(Schema.minLength(1)), - Schema.Number, - ); + Schema.Number + ) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* Output: { @@ -818,32 +823,32 @@ - `ReadonlyMap` -> `{ readonly [x: string]: VI }` ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const schema = Schema.ReadonlyMapFromRecord({ key: Schema.BigInt, - value: Schema.NumberFromString, - }); + value: Schema.NumberFromString + }) - const decode = Schema.decodeUnknownSync(schema); - const encode = Schema.encodeSync(schema); + const decode = Schema.decodeUnknownSync(schema) + const encode = Schema.encodeSync(schema) console.log( decode({ "1": "4", "2": "5", - "3": "6", - }), - ); // Map(3) { 1n => 4, 2n => 5, 3n => 6 } + "3": "6" + }) + ) // Map(3) { 1n => 4, 2n => 5, 3n => 6 } console.log( encode( new Map([ [1n, 4], [2n, 5], - [3n, 6], - ]), - ), - ); // { '1': '4', '2': '5', '3': '6' } + [3n, 6] + ]) + ) + ) // { '1': '4', '2': '5', '3': '6' } ``` - Updated dependencies [[`5c0ceb0`](https://github.com/Effect-TS/effect/commit/5c0ceb00826cce9e50bf9d41d83e191d5352c030), [`5c0ceb0`](https://github.com/Effect-TS/effect/commit/5c0ceb00826cce9e50bf9d41d83e191d5352c030), [`33735b1`](https://github.com/Effect-TS/effect/commit/33735b16b41bd26929d8f4754c190925db6323b7), [`5c0ceb0`](https://github.com/Effect-TS/effect/commit/5c0ceb00826cce9e50bf9d41d83e191d5352c030), [`139d4b3`](https://github.com/Effect-TS/effect/commit/139d4b39fb3bff2eeaa7c0c809c581da42425a83)]: @@ -864,14 +869,14 @@ Before ```ts - import { JSONSchema, Schema as S } from "@effect/schema"; + import { JSONSchema, Schema as S } from "@effect/schema" const schema = S.Struct({ foo: S.String, - bar: S.Number, - }); + bar: S.Number + }) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* { '$schema': 'http://json-schema.org/draft-07/schema#', @@ -889,14 +894,14 @@ Now ```ts - import { JSONSchema, Schema as S } from "@effect/schema"; + import { JSONSchema, Schema as S } from "@effect/schema" const schema = S.Struct({ foo: S.String, - bar: S.Number, - }); + bar: S.Number + }) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* { '$schema': 'http://json-schema.org/draft-07/schema#', @@ -917,21 +922,21 @@ Example ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Struct({ - a: Schema.String, + a: Schema.String }) .pipe(Schema.filter(() => true, { jsonSchema: { a: 1 } })) .pipe( Schema.extend( Schema.Struct({ - b: Schema.Number, - }).pipe(Schema.filter(() => true, { jsonSchema: { b: 2 } })), - ), - ); + b: Schema.Number + }).pipe(Schema.filter(() => true, { jsonSchema: { b: 2 } })) + ) + ) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* { '$schema': 'http://json-schema.org/draft-07/schema#', @@ -962,16 +967,16 @@ Before ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" // Define a schema that parses a JSON string into a structured object const schema = Schema.parseJson( Schema.Struct({ - a: Schema.parseJson(Schema.NumberFromString), // Nested parsing from JSON string to number - }), - ); + a: Schema.parseJson(Schema.NumberFromString) // Nested parsing from JSON string to number + }) + ) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* { '$schema': 'http://json-schema.org/draft-07/schema#', @@ -990,16 +995,16 @@ Now ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" // Define a schema that parses a JSON string into a structured object const schema = Schema.parseJson( Schema.Struct({ - a: Schema.parseJson(Schema.NumberFromString), // Nested parsing from JSON string to number - }), - ); + a: Schema.parseJson(Schema.NumberFromString) // Nested parsing from JSON string to number + }) + ) - console.log(JSONSchema.make(schema)); + console.log(JSONSchema.make(schema)) /* { '$schema': 'http://json-schema.org/draft-07/schema#', @@ -1056,16 +1061,16 @@ This commit resolves an issue where the custom message for a struct (or tuple or union) was displayed regardless of whether the validation error was related to the entire struct or just a specific part of it. Previously, users would see the custom error message even when the error only concerned a particular field within the struct and the flag `overwrite` was not set to `true`. ```ts - import { Schema, TreeFormatter } from "@effect/schema"; - import { Either } from "effect"; + import { Schema, TreeFormatter } from "@effect/schema" + import { Either } from "effect" const schema = Schema.Struct({ - a: Schema.String, - }).annotations({ message: () => "custom message" }); + a: Schema.String + }).annotations({ message: () => "custom message" }) - const res = Schema.decodeUnknownEither(schema)({ a: null }); + const res = Schema.decodeUnknownEither(schema)({ a: null }) if (Either.isLeft(res)) { - console.log(TreeFormatter.formatErrorSync(res.left)); + console.log(TreeFormatter.formatErrorSync(res.left)) // before: custom message // now: { readonly a: string } // └─ ["a"] @@ -1084,23 +1089,23 @@ **Example** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" class MyClass extends Schema.Class("MyClass")({ - someField: Schema.String, + someField: Schema.String }) { someMethod() { - return this.someField + "bar"; + return this.someField + "bar" } } // Create an instance of MyClass using the make constructor - const instance = MyClass.make({ someField: "foo" }); // same as new MyClass({ someField: "foo" }) + const instance = MyClass.make({ someField: "foo" }) // same as new MyClass({ someField: "foo" }) // Outputs to console to demonstrate that the instance is correctly created - console.log(instance instanceof MyClass); // true - console.log(instance.someField); // "foo" - console.log(instance.someMethod()); // "foobar" + console.log(instance instanceof MyClass) // true + console.log(instance.someField) // "foo" + console.log(instance.someMethod()) // "foobar" ``` ## 0.68.4 @@ -1121,29 +1126,29 @@ Here's how you can leverage this new feature: ```ts - import { Schema } from "@effect/schema"; - import { Either } from "effect"; + import { Schema } from "@effect/schema" + import { Either } from "effect" const schema = Schema.Struct({ a: Schema.Struct({ b: Schema.String, - c: Schema.String, + c: Schema.String }).annotations({ title: "first error only", - parseOptions: { errors: "first" }, // Only the first error in this sub-schema is reported + parseOptions: { errors: "first" } // Only the first error in this sub-schema is reported }), - d: Schema.String, + d: Schema.String }).annotations({ title: "all errors", - parseOptions: { errors: "all" }, // All errors in the main schema are reported - }); + parseOptions: { errors: "all" } // All errors in the main schema are reported + }) const result = Schema.decodeUnknownEither(schema)( { a: {} }, - { errors: "first" }, - ); + { errors: "first" } + ) if (Either.isLeft(result)) { - console.log(result.left.message); + console.log(result.left.message) } /* all errors @@ -1198,29 +1203,29 @@ **Example of Previous Implementation:** ```ts - import { ArrayFormatter, Schema } from "@effect/schema"; - import { Either } from "effect"; + import { ArrayFormatter, Schema } from "@effect/schema" + import { Either } from "effect" - const Password = Schema.Trim.pipe(Schema.minLength(1)); + const Password = Schema.Trim.pipe(Schema.minLength(1)) const MyForm = Schema.Struct({ password: Password, - confirm_password: Password, + confirm_password: Password }).pipe( Schema.filter((input) => { if (input.password !== input.confirm_password) { - return "Passwords do not match"; + return "Passwords do not match" } - }), - ); + }) + ) console.log( "%o", Schema.decodeUnknownEither(MyForm)({ password: "abc", - confirm_password: "d", - }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))), - ); + confirm_password: "d" + }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))) + ) /* { _id: 'Either', @@ -1245,32 +1250,32 @@ **Updated Implementation Example:** ```ts - import { ArrayFormatter, Schema } from "@effect/schema"; - import { Either } from "effect"; + import { ArrayFormatter, Schema } from "@effect/schema" + import { Either } from "effect" - const Password = Schema.Trim.pipe(Schema.minLength(1)); + const Password = Schema.Trim.pipe(Schema.minLength(1)) const MyForm = Schema.Struct({ password: Password, - confirm_password: Password, + confirm_password: Password }).pipe( Schema.filter((input) => { if (input.password !== input.confirm_password) { return { path: ["confirm_password"], - message: "Passwords do not match", - }; + message: "Passwords do not match" + } } - }), - ); + }) + ) console.log( "%o", Schema.decodeUnknownEither(MyForm)({ password: "abc", - confirm_password: "d", - }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))), - ); + confirm_password: "d" + }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))) + ) /* { _id: 'Either', @@ -1295,45 +1300,45 @@ **Example of Multiple Issues Reporting:** ```ts - import { ArrayFormatter, Schema } from "@effect/schema"; - import { Either } from "effect"; + import { ArrayFormatter, Schema } from "@effect/schema" + import { Either } from "effect" - const Password = Schema.Trim.pipe(Schema.minLength(1)); - const OptionalString = Schema.optional(Schema.String); + const Password = Schema.Trim.pipe(Schema.minLength(1)) + const OptionalString = Schema.optional(Schema.String) const MyForm = Schema.Struct({ password: Password, confirm_password: Password, name: OptionalString, - surname: OptionalString, + surname: OptionalString }).pipe( Schema.filter((input) => { - const issues: Array = []; + const issues: Array = [] // passwords must match if (input.password !== input.confirm_password) { issues.push({ path: ["confirm_password"], - message: "Passwords do not match", - }); + message: "Passwords do not match" + }) } // either name or surname must be present if (!input.name && !input.surname) { issues.push({ path: ["surname"], - message: "Surname must be present if name is not present", - }); + message: "Surname must be present if name is not present" + }) } - return issues; - }), - ); + return issues + }) + ) console.log( "%o", Schema.decodeUnknownEither(MyForm)({ password: "abc", - confirm_password: "d", - }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))), - ); + confirm_password: "d" + }).pipe(Either.mapLeft((error) => ArrayFormatter.formatErrorSync(error))) + ) /* { _id: 'Either', @@ -1371,7 +1376,7 @@ | Pointer | Refinement | Transformation - | Composite; + | Composite ``` **Key Changes in the Model:** @@ -1390,11 +1395,11 @@ ```ts interface Composite { - readonly _tag: "Composite"; - readonly ast: AST.Annotated; - readonly actual: unknown; - readonly issues: ParseIssue | NonEmptyReadonlyArray; - readonly output?: unknown; + readonly _tag: "Composite" + readonly ast: AST.Annotated + readonly actual: unknown + readonly issues: ParseIssue | NonEmptyReadonlyArray + readonly output?: unknown } ``` @@ -1405,9 +1410,9 @@ **Example** ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" - JSONSchema.make(Schema.Struct({ a: Schema.Void })); + JSONSchema.make(Schema.Struct({ a: Schema.Void })) /* throws: Error: Missing annotation @@ -1422,22 +1427,22 @@ Annotations are used to add metadata to tuple elements, which can describe the purpose or requirements of each element more clearly. This can be particularly useful when generating documentation or JSON schemas from your schemas. ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" // Defining a tuple with annotations for each coordinate in a point const Point = Schema.Tuple( Schema.element(Schema.Number).annotations({ title: "X", - description: "X coordinate", + description: "X coordinate" }), Schema.optionalElement(Schema.Number).annotations({ title: "Y", - description: "optional Y coordinate", - }), - ); + description: "optional Y coordinate" + }) + ) // Generating a JSON Schema from the tuple - console.log(JSONSchema.make(Point)); + console.log(JSONSchema.make(Point)) /* Output: { @@ -1464,15 +1469,15 @@ Example (missing field) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const Person = Schema.Struct({ name: Schema.propertySignature(Schema.String).annotations({ - missingMessage: () => "Name is required", - }), - }); + missingMessage: () => "Name is required" + }) + }) - Schema.decodeUnknownSync(Person)({}); + Schema.decodeUnknownSync(Person)({}) /* Output: Error: { readonly name: string } @@ -1484,18 +1489,18 @@ Example (missing element) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const Point = Schema.Tuple( Schema.element(Schema.Number).annotations({ - missingMessage: () => "X coordinate is required", + missingMessage: () => "X coordinate is required" }), Schema.element(Schema.Number).annotations({ - missingMessage: () => "Y coordinate is required", - }), - ); + missingMessage: () => "Y coordinate is required" + }) + ) - Schema.decodeUnknownSync(Point)([], { errors: "all" }); + Schema.decodeUnknownSync(Point)([], { errors: "all" }) /* Output: Error: readonly [number, number] @@ -1513,24 +1518,24 @@ Before ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // Example of adding an identifier using a dedicated API - const schema = Schema.String.pipe(Schema.identifier("myIdentitifer")); + const schema = Schema.String.pipe(Schema.identifier("myIdentitifer")) ``` Now ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // Directly using the annotations method - const schema = Schema.String.annotations({ identifier: "myIdentitifer" }); + const schema = Schema.String.annotations({ identifier: "myIdentitifer" }) // or const schema2 = Schema.String.pipe( // Using the annotations function in a pipe-able format - Schema.annotations({ identifier: "myIdentitifer" }), - ); + Schema.annotations({ identifier: "myIdentitifer" }) + ) ``` ## Standardize Error Handling for `*Either`, `*Sync` and `asserts` APIs @@ -1538,21 +1543,21 @@ Now the `*Sync` and `asserts` APIs throw a `ParseError` while before they was throwing a simple `Error` with a `cause` containing a `ParseIssue` ```ts - import { ParseResult, Schema } from "@effect/schema"; + import { ParseResult, Schema } from "@effect/schema" try { - Schema.decodeUnknownSync(Schema.String)(null); + Schema.decodeUnknownSync(Schema.String)(null) } catch (e) { - console.log(ParseResult.isParseError(e)); // true + console.log(ParseResult.isParseError(e)) // true } const asserts: (u: unknown) => asserts u is string = Schema.asserts( - Schema.String, - ); + Schema.String + ) try { - asserts(null); + asserts(null) } catch (e) { - console.log(ParseResult.isParseError(e)); // true + console.log(ParseResult.isParseError(e)) // true } ``` @@ -1702,34 +1707,34 @@ **Example** (Synchronous Decoding) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const schema = Schema.Struct({ a: Schema.Number, b: Schema.Literal("b"), - c: Schema.Number, - }); + c: Schema.Number + }) // Decoding an object synchronously without specifying the property order - console.log(Schema.decodeUnknownSync(schema)({ b: "b", c: 2, a: 1 })); + console.log(Schema.decodeUnknownSync(schema)({ b: "b", c: 2, a: 1 })) // Output decided internally: { b: 'b', a: 1, c: 2 } // Decoding an object synchronously while preserving the order of properties as in the input console.log( Schema.decodeUnknownSync(schema)( { b: "b", c: 2, a: 1 }, - { propertyOrder: "original" }, - ), - ); + { propertyOrder: "original" } + ) + ) // Output preserving input order: { b: 'b', c: 2, a: 1 } ``` **Example** (Asynchronous Decoding) ```ts - import { ParseResult, Schema } from "@effect/schema"; - import type { Duration } from "effect"; - import { Effect } from "effect"; + import { ParseResult, Schema } from "@effect/schema" + import type { Duration } from "effect" + import { Effect } from "effect" // Function to simulate an asynchronous process within the schema const effectify = (duration: Duration.DurationInput) => @@ -1737,27 +1742,27 @@ Schema.transformOrFail(Schema.Number, { decode: (x) => Effect.sleep(duration).pipe(Effect.andThen(ParseResult.succeed(x))), - encode: ParseResult.succeed, - }), - ); + encode: ParseResult.succeed + }) + ) // Define a structure with asynchronous behavior in each field const schema = Schema.Struct({ a: effectify("200 millis"), b: effectify("300 millis"), - c: effectify("100 millis"), - }).annotations({ concurrency: 3 }); + c: effectify("100 millis") + }).annotations({ concurrency: 3 }) // Decoding data asynchronously without preserving order Schema.decode(schema)({ a: 1, b: 2, c: 3 }) .pipe(Effect.runPromise) - .then(console.log); + .then(console.log) // Output decided internally: { c: 3, a: 1, b: 2 } // Decoding data asynchronously while preserving the original input order Schema.decode(schema)({ a: 1, b: 2, c: 3 }, { propertyOrder: "original" }) .pipe(Effect.runPromise) - .then(console.log); + .then(console.log) // Output preserving input order: { a: 1, b: 2, c: 3 } ``` @@ -1777,14 +1782,14 @@ Example ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const BrandedNumberSchema = Schema.Number.pipe( Schema.between(1, 10), - Schema.brand("MyNumber"), - ); + Schema.brand("MyNumber") + ) - BrandedNumberSchema.make(20, { disableValidation: true }); // Bypasses validation and creates the instance without errors + BrandedNumberSchema.make(20, { disableValidation: true }) // Bypasses validation and creates the instance without errors ``` - Updated dependencies [[`8c5d280`](https://github.com/Effect-TS/effect/commit/8c5d280c0402284a4e58372867a15a431cb99461), [`6ba6d26`](https://github.com/Effect-TS/effect/commit/6ba6d269f5891e6b11aa35c5281dde4bf3273004), [`3f28bf2`](https://github.com/Effect-TS/effect/commit/3f28bf274333611906175446b772243f34f1b6d5), [`5817820`](https://github.com/Effect-TS/effect/commit/58178204a770d1a78c06945ef438f9fffbb50afa)]: @@ -1813,29 +1818,29 @@ Before ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // `https://${string}.com` | `https://${string}.net` const MyUrl = Schema.TemplateLiteral( Schema.Literal("https://"), Schema.String, Schema.Literal("."), - Schema.Literal("com", "net"), - ); + Schema.Literal("com", "net") + ) ``` Now ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" // `https://${string}.com` | `https://${string}.net` const MyUrl = Schema.TemplateLiteral( "https://", Schema.String, ".", - Schema.Literal("com", "net"), - ); + Schema.Literal("com", "net") + ) ``` - [#2905](https://github.com/Effect-TS/effect/pull/2905) [`7d6d875`](https://github.com/Effect-TS/effect/commit/7d6d8750077d9c8379f37240745240d7f3b7a4f8) Thanks @gcanti! - add support for unions to `rename`, closes #2904 @@ -1856,20 +1861,20 @@ **Example Usage:** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const schema = Schema.Struct({ - foo: Schema.String.pipe(Schema.minLength(3), Schema.compose(Schema.Trim)), - }); + foo: Schema.String.pipe(Schema.minLength(3), Schema.compose(Schema.Trim)) + }) // The resultingEncodedBoundSchema preserves the minLength(3) refinement, // ensuring the string length condition is enforced but omits the Trim transformation. - const resultingEncodedBoundSchema = Schema.encodedBoundSchema(schema); + const resultingEncodedBoundSchema = Schema.encodedBoundSchema(schema) // resultingEncodedBoundSchema is the same as: Schema.Struct({ - foo: Schema.String.pipe(Schema.minLength(3)), - }); + foo: Schema.String.pipe(Schema.minLength(3)) + }) ``` In the provided example: @@ -1919,19 +1924,19 @@ The `tag` constructor is specifically designed to create a property signature that holds a specific literal value, serving as the discriminator for object types. Here's how you can define a schema with a tag: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const User = Schema.Struct({ _tag: Schema.tag("User"), name: Schema.String, - age: Schema.Number, - }); + age: Schema.Number + }) assert.deepStrictEqual(User.make({ name: "John", age: 44 }), { _tag: "User", name: "John", - age: 44, - }); + age: 44 + }) ``` In the example above, `Schema.tag("User")` attaches a `_tag` property to the `User` struct schema, effectively labeling objects of this struct type as "User". This label is automatically applied when using the `make` method to create new instances, simplifying object creation and ensuring consistent tagging. @@ -1941,21 +1946,21 @@ The `TaggedStruct` constructor streamlines the process of creating tagged structs by directly integrating the tag into the struct definition. This method provides a clearer and more declarative approach to building data structures with embedded discriminators. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const User = Schema.TaggedStruct("User", { name: Schema.String, - age: Schema.Number, - }); + age: Schema.Number + }) // `_tag` is optional - const userInstance = User.make({ name: "John", age: 44 }); + const userInstance = User.make({ name: "John", age: 44 }) assert.deepStrictEqual(userInstance, { _tag: "User", name: "John", - age: 44, - }); + age: 44 + }) ``` **Multiple Tags** @@ -1963,23 +1968,23 @@ While a primary tag is often sufficient, TypeScript allows you to define multiple tags for more complex data structuring needs. Here's an example demonstrating the use of multiple tags within a single struct: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const Product = Schema.TaggedStruct("Product", { category: Schema.tag("Electronics"), name: Schema.String, - price: Schema.Number, - }); + price: Schema.Number + }) // `_tag` and `category` are optional - const productInstance = Product.make({ name: "Smartphone", price: 999 }); + const productInstance = Product.make({ name: "Smartphone", price: 999 }) assert.deepStrictEqual(productInstance, { _tag: "Product", category: "Electronics", name: "Smartphone", - price: 999, - }); + price: 999 + }) ``` This example showcases a product schema that not only categorizes each product under a general tag (`"Product"`) but also specifies a category tag (`"Electronics"`), enhancing the clarity and specificity of the data model. @@ -2087,9 +2092,9 @@ **Before:** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - declare const array: Array; + declare const array: Array /* Throws an error: @@ -2097,18 +2102,18 @@ ... Types of parameters 'overrideOptions' and 'index' are incompatible. */ - const strings = array.filter(Schema.is(Schema.String)); + const strings = array.filter(Schema.is(Schema.String)) ``` **Now:** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - declare const array: Array; + declare const array: Array // const strings: string[] - const strings = array.filter(Schema.is(Schema.String)); + const strings = array.filter(Schema.is(Schema.String)) ``` Note that the result has been correctly narrowed to `string[]`. @@ -2133,29 +2138,29 @@ **Example** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const Product = Schema.Struct({ name: Schema.String, price: Schema.NumberFromString, - quantity: Schema.optional(Schema.NumberFromString, { default: () => 1 }), - }); + quantity: Schema.optional(Schema.NumberFromString, { default: () => 1 }) + }) // Applying defaults in the decoding phase console.log( - Schema.decodeUnknownSync(Product)({ name: "Laptop", price: "999" }), - ); // { name: 'Laptop', price: 999, quantity: 1 } + Schema.decodeUnknownSync(Product)({ name: "Laptop", price: "999" }) + ) // { name: 'Laptop', price: 999, quantity: 1 } console.log( Schema.decodeUnknownSync(Product)({ name: "Laptop", price: "999", - quantity: "2", - }), - ); // { name: 'Laptop', price: 999, quantity: 2 } + quantity: "2" + }) + ) // { name: 'Laptop', price: 999, quantity: 2 } // Applying defaults in the constructor - console.log(Product.make({ name: "Laptop", price: 999 })); // { name: 'Laptop', price: 999, quantity: 1 } - console.log(Product.make({ name: "Laptop", price: 999, quantity: 2 })); // { name: 'Laptop', price: 999, quantity: 2 } + console.log(Product.make({ name: "Laptop", price: 999 })) // { name: 'Laptop', price: 999, quantity: 1 } + console.log(Product.make({ name: "Laptop", price: 999, quantity: 2 })) // { name: 'Laptop', price: 999, quantity: 2 } ``` ## 0.67.1 @@ -2176,18 +2181,18 @@ Now, you can easily access `Type` and `Encoded` directly from a schema without the need for `Schema.Schema.Type` and `Schema.Schema.Encoded`. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const PersonSchema = Schema.Struct({ name: Schema.String, - age: Schema.NumberFromString, - }); + age: Schema.NumberFromString + }) // same as type PersonType = Schema.Schema.Type - type PersonType = typeof PersonSchema.Type; + type PersonType = typeof PersonSchema.Type // same as Schema.Schema.Encoded - type PersonEncoded = typeof PersonSchema.Encoded; + type PersonEncoded = typeof PersonSchema.Encoded ``` ## Default Constructors @@ -2203,14 +2208,14 @@ **Example** (`Struct`) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyStruct = Schema.Struct({ - name: Schema.NonEmpty, - }); + name: Schema.NonEmpty + }) - MyStruct.make({ name: "a" }); // ok - MyStruct.make({ name: "" }); + MyStruct.make({ name: "a" }) // ok + MyStruct.make({ name: "" }) /* throws Error: { name: NonEmpty } @@ -2224,13 +2229,13 @@ **Example** (`filter`) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const MyNumber = Schema.Number.pipe(Schema.between(1, 10)); + const MyNumber = Schema.Number.pipe(Schema.between(1, 10)) // const n: number - const n = MyNumber.make(5); // ok - MyNumber.make(20); + const n = MyNumber.make(5) // ok + MyNumber.make(20) /* throws Error: a number between 1 and 10 @@ -2242,16 +2247,16 @@ **Example** (`brand`) ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyBrand = Schema.Number.pipe( Schema.between(1, 10), - Schema.brand("MyNumber"), - ); + Schema.brand("MyNumber") + ) // const n: number & Brand<"MyNumber"> - const n = MyBrand.make(5); // ok - MyBrand.make(20); + const n = MyBrand.make(5) // ok + MyBrand.make(20) /* throws Error: a number between 1 and 10 @@ -2269,18 +2274,18 @@ To have a "safe" constructor, you can use `Schema.validateEither`: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const MyNumber = Schema.Number.pipe(Schema.between(1, 10)); + const MyNumber = Schema.Number.pipe(Schema.between(1, 10)) - const ctor = Schema.validateEither(MyNumber); + const ctor = Schema.validateEither(MyNumber) - console.log(ctor(5)); + console.log(ctor(5)) /* { _id: 'Either', _tag: 'Right', right: 5 } */ - console.log(ctor(20)); + console.log(ctor(20)) /* { _id: 'Either', @@ -2303,41 +2308,41 @@ **Example** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const PersonSchema = Schema.Struct({ name: Schema.NonEmpty, age: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => 0), - ), - }); + Schema.withConstructorDefault(() => 0) + ) + }) // The age field is optional and defaults to 0 - console.log(PersonSchema.make({ name: "John" })); + console.log(PersonSchema.make({ name: "John" })) // => { age: 0, name: 'John' } ``` Defaults are **lazily evaluated**, meaning that a new instance of the default is generated every time the constructor is called: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const PersonSchema = Schema.Struct({ name: Schema.NonEmpty, age: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => 0), + Schema.withConstructorDefault(() => 0) ), timestamp: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => new Date().getTime()), - ), - }); + Schema.withConstructorDefault(() => new Date().getTime()) + ) + }) - console.log(PersonSchema.make({ name: "name1" })); + console.log(PersonSchema.make({ name: "name1" })) // => { age: 0, timestamp: 1714232909221, name: 'name1' } - console.log(PersonSchema.make({ name: "name2" })); + console.log(PersonSchema.make({ name: "name2" })) // => { age: 0, timestamp: 1714232909227, name: 'name2' } ``` @@ -2346,70 +2351,70 @@ Defaults can also be applied using the `Class` API: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" class Person extends Schema.Class("Person")({ name: Schema.NonEmpty, age: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => 0), + Schema.withConstructorDefault(() => 0) ), timestamp: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => new Date().getTime()), - ), + Schema.withConstructorDefault(() => new Date().getTime()) + ) }) {} - console.log(new Person({ name: "name1" })); + console.log(new Person({ name: "name1" })) // => Person { age: 0, timestamp: 1714400867208, name: 'name1' } - console.log(new Person({ name: "name2" })); + console.log(new Person({ name: "name2" })) // => Person { age: 0, timestamp: 1714400867215, name: 'name2' } ``` Default values are also "portable", meaning that if you reuse the same property signature in another schema, the default is carried over: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const PersonSchema = Schema.Struct({ name: Schema.NonEmpty, age: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => 0), + Schema.withConstructorDefault(() => 0) ), timestamp: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => new Date().getTime()), - ), - }); + Schema.withConstructorDefault(() => new Date().getTime()) + ) + }) const AnotherSchema = Schema.Struct({ foo: Schema.String, - age: PersonSchema.fields.age, - }); + age: PersonSchema.fields.age + }) - console.log(AnotherSchema.make({ foo: "bar" })); // => { foo: 'bar', age: 0 } + console.log(AnotherSchema.make({ foo: "bar" })) // => { foo: 'bar', age: 0 } ``` Defaults can also be applied using the `Class` API: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" class Person extends Schema.Class("Person")({ name: Schema.NonEmpty, age: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => 0), + Schema.withConstructorDefault(() => 0) ), timestamp: Schema.Number.pipe( Schema.propertySignature, - Schema.withConstructorDefault(() => new Date().getTime()), - ), + Schema.withConstructorDefault(() => new Date().getTime()) + ) }) {} - console.log(new Person({ name: "name1" })); // Person { age: 0, timestamp: 1714400867208, name: 'name1' } - console.log(new Person({ name: "name2" })); // Person { age: 0, timestamp: 1714400867215, name: 'name2' } + console.log(new Person({ name: "name1" })) // Person { age: 0, timestamp: 1714400867208, name: 'name1' } + console.log(new Person({ name: "name2" })) // Person { age: 0, timestamp: 1714400867215, name: 'name2' } ``` ## Default Decoding Values @@ -2417,45 +2422,43 @@ Our new `Schema.withDecodingDefault` combinator makes it easy to handle the optionality of a field during the **decoding process**. ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MySchema = Schema.Struct({ - a: Schema.optional(Schema.String).pipe( - Schema.withDecodingDefault(() => ""), - ), - }); + a: Schema.optional(Schema.String).pipe(Schema.withDecodingDefault(() => "")) + }) - console.log(Schema.decodeUnknownSync(MySchema)({})); + console.log(Schema.decodeUnknownSync(MySchema)({})) // => { a: '' } - console.log(Schema.decodeUnknownSync(MySchema)({ a: undefined })); + console.log(Schema.decodeUnknownSync(MySchema)({ a: undefined })) // => { a: '' } - console.log(Schema.decodeUnknownSync(MySchema)({ a: "a" })); + console.log(Schema.decodeUnknownSync(MySchema)({ a: "a" })) // => { a: 'a' } ``` If you want to set default values both for the decoding phase and for the default constructor, you can use `Schema.withDefaults`: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MySchema = Schema.Struct({ a: Schema.optional(Schema.String).pipe( Schema.withDefaults({ decoding: () => "", - constructor: () => "-", - }), - ), - }); + constructor: () => "-" + }) + ) + }) - console.log(Schema.decodeUnknownSync(MySchema)({})); + console.log(Schema.decodeUnknownSync(MySchema)({})) // => { a: '' } - console.log(Schema.decodeUnknownSync(MySchema)({ a: undefined })); + console.log(Schema.decodeUnknownSync(MySchema)({ a: undefined })) // => { a: '' } - console.log(Schema.decodeUnknownSync(MySchema)({ a: "a" })); + console.log(Schema.decodeUnknownSync(MySchema)({ a: "a" })) // => { a: 'a' } - console.log(MySchema.make({})); // => { a: '-' } - console.log(MySchema.make({ a: "a" })); // => { a: 'a' } + console.log(MySchema.make({})) // => { a: '-' } + console.log(MySchema.make({ a: "a" })) // => { a: 'a' } ``` ## Refactoring of Custom Message System @@ -2467,22 +2470,22 @@ **Previous Approach** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyString = Schema.String.pipe( Schema.minLength(1), - Schema.maxLength(2), + Schema.maxLength(2) ).annotations({ // This message always takes precedence // So, for any error, the same message will always be shown - message: () => "my custom message", - }); + message: () => "my custom message" + }) - const decode = Schema.decodeUnknownEither(MyString); + const decode = Schema.decodeUnknownEither(MyString) - console.log(decode(null)); // "my custom message" - console.log(decode("")); // "my custom message" - console.log(decode("abc")); // "my custom message" + console.log(decode(null)) // "my custom message" + console.log(decode("")) // "my custom message" + console.log(decode("abc")) // "my custom message" ``` As you can see, no matter where the decoding error is raised, the same error message will always be presented because in the previous version, the custom message by default overrides those generated by previous filters. @@ -2492,49 +2495,49 @@ **Current Approach** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyString = Schema.String.pipe( Schema.minLength(1), - Schema.maxLength(2), + Schema.maxLength(2) ).annotations({ // This message is shown only if the maxLength filter fails - message: () => "my custom message", - }); + message: () => "my custom message" + }) - const decode = Schema.decodeUnknownEither(MyString); + const decode = Schema.decodeUnknownEither(MyString) - console.log(decode(null)); // "Expected a string, actual null" - console.log(decode("")); // `Expected a string at least 1 character(s) long, actual ""` - console.log(decode("abc")); // "my custom message" + console.log(decode(null)) // "Expected a string, actual null" + console.log(decode("")) // `Expected a string at least 1 character(s) long, actual ""` + console.log(decode("abc")) // "my custom message" ``` To restore the old behavior (for example, to address the scenario where a user wants to define a single cumulative custom message describing the properties that a valid value must have and does not want to see default messages), you need to set the `override` flag to `true`: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyString = Schema.String.pipe( Schema.minLength(1), - Schema.maxLength(2), + Schema.maxLength(2) ).annotations({ // By setting the `override` flag to `true` // this message will always be shown for any error - message: () => ({ message: "my custom message", override: true }), - }); + message: () => ({ message: "my custom message", override: true }) + }) - const decode = Schema.decodeUnknownEither(MyString); + const decode = Schema.decodeUnknownEither(MyString) - console.log(decode(null)); // "my custom message" - console.log(decode("")); // "my custom message" - console.log(decode("abc")); // "my custom message" + console.log(decode(null)) // "my custom message" + console.log(decode("")) // "my custom message" + console.log(decode("abc")) // "my custom message" ``` The new system is particularly useful when the schema on which custom messages are defined is more complex than a scalar value (like `string` or `number`), for example, if it's a struct containing a field that is an array of structs. Let's see an example that illustrates how convenient it is to rely on default messages when the decoding error occurs in a nested structure: ```ts - import { Schema } from "@effect/schema"; - import { pipe } from "effect"; + import { Schema } from "@effect/schema" + import { pipe } from "effect" const schema = Schema.Struct({ outcomes: pipe( @@ -2545,17 +2548,17 @@ Schema.String, Schema.message(() => "error_invalid_outcome_type"), Schema.minLength(1, { message: () => "error_required_field" }), - Schema.maxLength(50, { message: () => "error_max_length_field" }), - ), - }), + Schema.maxLength(50, { message: () => "error_max_length_field" }) + ) + }) ), - Schema.minItems(1, { message: () => "error_min_length_field" }), - ), - }); + Schema.minItems(1, { message: () => "error_min_length_field" }) + ) + }) Schema.decodeUnknownSync(schema, { errors: "all" })({ - outcomes: [], - }); + outcomes: [] + }) /* throws Error: { outcomes: an array of at least 1 items } @@ -2567,9 +2570,9 @@ outcomes: [ { id: "1", text: "" }, { id: "2", text: "this one is valid" }, - { id: "3", text: "1234567890".repeat(6) }, - ], - }); + { id: "3", text: "1234567890".repeat(6) } + ] + }) /* throws Error: { outcomes: an array of at least 1 items } @@ -2595,21 +2598,21 @@ We've introduced a new API interface to the `filter` API. This allows you to access the refined schema using the exposed `from` field: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const MyFilter = Schema.Struct({ - a: Schema.String, - }).pipe(Schema.filter(() => /* some filter... */ true)); + a: Schema.String + }).pipe(Schema.filter(() => /* some filter... */ true)) // const aField: typeof Schema.String - const aField = MyFilter.from.fields.a; + const aField = MyFilter.from.fields.a ``` The signature of the `filter` function has been simplified and streamlined to be more ergonomic when setting a default message. In the new signature of `filter`, the type of the predicate passed as an argument is as follows: ```ts predicate: (a: A, options: ParseOptions, self: AST.Refinement) => - undefined | boolean | string | ParseResult.ParseIssue; + undefined | boolean | string | ParseResult.ParseIssue ``` with the following semantics: @@ -2624,18 +2627,18 @@ **Before** ```ts - import { Schema, ParseResult } from "@effect/schema"; - import { Option } from "effect"; + import { Schema, ParseResult } from "@effect/schema" + import { Option } from "effect" const Positive = Schema.Number.pipe( Schema.filter((n, _, ast) => n > 0 ? Option.none() - : Option.some(new ParseResult.Type(ast, n, "must be positive")), - ), - ); + : Option.some(new ParseResult.Type(ast, n, "must be positive")) + ) + ) - Schema.decodeUnknownSync(Positive)(-1); + Schema.decodeUnknownSync(Positive)(-1) /* throws Error: @@ -2647,13 +2650,13 @@ **Now** ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const Positive = Schema.Number.pipe( - Schema.filter((n) => (n > 0 ? undefined : "must be positive")), - ); + Schema.filter((n) => (n > 0 ? undefined : "must be positive")) + ) - Schema.decodeUnknownSync(Positive)(-1); + Schema.decodeUnknownSync(Positive)(-1) /* throws Error: { number | filter } @@ -2669,16 +2672,16 @@ Let's see an example: ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" const schema = Schema.Struct({ foo: Schema.String.pipe(Schema.minLength(2)), bar: Schema.optional(Schema.NumberFromString, { - default: () => 0, - }), - }); + default: () => 0 + }) + }) - console.log(JSON.stringify(JSONSchema.make(schema), null, 2)); + console.log(JSON.stringify(JSONSchema.make(schema), null, 2)) ``` Now, let's compare the JSON Schemas produced in both the previous and new versions. @@ -2716,7 +2719,7 @@ This happens because in the previous version, the `JSONSchema.make` API by default produces a JSON Schema for the `Type` part of the schema. That is: ```ts - type Type = Schema.Schema.Type; + type Type = Schema.Schema.Type /* type Type = { readonly foo: string; @@ -2728,7 +2731,7 @@ However, typically, we are interested in generating a JSON Schema for the input part of the decoding process, i.e., in this case for: ```ts - type Encoded = Schema.Schema.Encoded; + type Encoded = Schema.Schema.Encoded /* type Encoded = { readonly foo: string; @@ -2741,8 +2744,8 @@ ```ts console.log( - JSON.stringify(JSONSchema.make(Schema.encodedSchema(schema)), null, 2), - ); + JSON.stringify(JSONSchema.make(Schema.encodedSchema(schema)), null, 2) + ) ``` But here's what the result would be: @@ -2804,37 +2807,37 @@ Now `extend` supports extending refinements, so you can do something like this: ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const RefinedStruct = Schema.Struct({ a: Schema.Number, - b: Schema.Number, + b: Schema.Number }).pipe( Schema.filter((value) => { if (value.a !== value.b) { - return "`a` must be equal to `b`"; + return "`a` must be equal to `b`" } - }), - ); + }) + ) const AnotherStruct = Schema.Struct({ c: Schema.String, - d: Schema.String, - }); + d: Schema.String + }) // in the previous version you would receive an error: // Extend: cannot extend `` with `{ c: string; d: string }` (path []) - const Extended = Schema.extend(RefinedStruct, AnotherStruct); + const Extended = Schema.extend(RefinedStruct, AnotherStruct) - console.log(String(Extended)); + console.log(String(Extended)) console.log( - Schema.decodeUnknownSync(Extended)({ a: 1, b: 1, c: "c", d: "d" }), - ); + Schema.decodeUnknownSync(Extended)({ a: 1, b: 1, c: "c", d: "d" }) + ) // => { a: 1, b: 1, c: 'c', d: 'd' } console.log( - Schema.decodeUnknownSync(Extended)({ a: 1, b: 2, c: "c", d: "d" }), - ); + Schema.decodeUnknownSync(Extended)({ a: 1, b: 2, c: "c", d: "d" }) + ) /* throws Error: { { readonly a: number; readonly b: number; readonly c: string; readonly d: string } | filter } @@ -2846,19 +2849,19 @@ We've also added support for `Schema.suspend`. Here's an example: ```ts - import { Arbitrary, FastCheck, Schema } from "@effect/schema"; + import { Arbitrary, FastCheck, Schema } from "@effect/schema" // Define a recursive list type type List = | { - readonly type: "nil"; + readonly type: "nil" } | { - readonly type: "cons"; + readonly type: "cons" readonly tail: { - readonly value: number; - } & List; // extend - }; + readonly value: number + } & List // extend + } // Define a schema for the list type const List: Schema.Schema = Schema.Union( @@ -2867,14 +2870,14 @@ type: Schema.Literal("cons"), tail: Schema.extend( Schema.Struct({ value: Schema.Number }), - Schema.suspend(() => List), // extend - ), - }), - ); + Schema.suspend(() => List) // extend + ) + }) + ) console.log( - JSON.stringify(FastCheck.sample(Arbitrary.make(List), 5), null, 2), - ); + JSON.stringify(FastCheck.sample(Arbitrary.make(List), 5), null, 2) + ) /* [ { @@ -2957,11 +2960,11 @@ - remove `hash` function, you can replace it with the following code: ```ts - import { Hash } from "effect"; - import { AST } from "@effect/schema"; + import { Hash } from "effect" + import { AST } from "@effect/schema" export const hash = (ast: AST.AST): number => - Hash.string(JSON.stringify(ast, null, 2)); + Hash.string(JSON.stringify(ast, null, 2)) ``` JSONSchema @@ -2970,10 +2973,10 @@ ```ts export interface JsonSchemaAnnotations { - title?: string; - description?: string; - default?: unknown; - examples?: Array; + title?: string + description?: string + default?: unknown + examples?: Array } ``` @@ -3003,7 +3006,7 @@ ```ts export interface BrandSchema, I, R> extends AnnotableClass, A, I, R> { - make(a: Brand.Unbranded): A; + make(a: Brand.Unbranded): A } ``` @@ -3012,21 +3015,21 @@ Before ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const UserId = Schema.Number.pipe(Schema.brand("UserId")); + const UserId = Schema.Number.pipe(Schema.brand("UserId")) - console.log(UserId(1)); // 1 + console.log(UserId(1)) // 1 ``` Now ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" - const UserId = Schema.Number.pipe(Schema.brand("UserId")); + const UserId = Schema.Number.pipe(Schema.brand("UserId")) - console.log(UserId.make(1)); // 1 + console.log(UserId.make(1)) // 1 ``` ## 0.66.16 @@ -3092,21 +3095,21 @@ Before ```ts - import { Schema as S } from "@effect/schema"; + import { Schema as S } from "@effect/schema" - S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString)); // ts error - S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number))); // ts error + S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString)) // ts error + S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number))) // ts error ``` Now ```ts - import { Schema as S } from "@effect/schema"; + import { Schema as S } from "@effect/schema" // $ExpectType Schema - S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString)); // ok + S.Union(S.Null, S.String).pipe(S.compose(S.NumberFromString)) // ok // $ExpectType Schema - S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number))); // ok + S.NumberFromString.pipe(S.compose(S.Union(S.Null, S.Number))) // ok ``` - Updated dependencies [[`ffe4f4e`](https://github.com/Effect-TS/effect/commit/ffe4f4e95db35fff6869e360b072e3837befa0a1), [`027418e`](https://github.com/Effect-TS/effect/commit/027418edaa6aa6c0ae4861b95832827b45adace4), [`ac1898e`](https://github.com/Effect-TS/effect/commit/ac1898eb7bc96880f911c276048e2ea3d6fe9c50), [`ffe4f4e`](https://github.com/Effect-TS/effect/commit/ffe4f4e95db35fff6869e360b072e3837befa0a1)]: @@ -3155,7 +3158,7 @@ Before ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const schema = Schema.Struct({ a: Schema.optional(Schema.String, { exact: true, default: () => "" }), @@ -3163,10 +3166,10 @@ c: Schema.String, d: Schema.String, e: Schema.String, - f: Schema.String, - }); + f: Schema.String + }) - Schema.decodeUnknownSync(schema)({ a: 1 }); + Schema.decodeUnknownSync(schema)({ a: 1 }) /* throws Error: ({ a?: string; b: string; c: string; d: string; e: string; f: string } <-> { a: string; b: string; c: string; d: string; e: string; f: string }) @@ -3180,7 +3183,7 @@ Now ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const schema = Schema.Struct({ a: Schema.optional(Schema.String, { exact: true, default: () => "" }), @@ -3188,10 +3191,10 @@ c: Schema.String, d: Schema.String, e: Schema.String, - f: Schema.String, - }); + f: Schema.String + }) - Schema.decodeUnknownSync(schema)({ a: 1 }); + Schema.decodeUnknownSync(schema)({ a: 1 }) /* throws Error: (Struct (Encoded side) <-> Struct (Type side)) @@ -3209,19 +3212,19 @@ Before ```ts - import { JSONSchema, Schema } from "@effect/schema"; + import { JSONSchema, Schema } from "@effect/schema" class A extends Schema.Class("A")({ - a: Schema.String, + a: Schema.String }) {} - console.log(JSONSchema.make(A)); // throws MissingAnnotation: cannot build a JSON Schema for a declaration without a JSON Schema annotation + console.log(JSONSchema.make(A)) // throws MissingAnnotation: cannot build a JSON Schema for a declaration without a JSON Schema annotation ``` Now ```ts - console.log(JSONSchema.make(A)); + console.log(JSONSchema.make(A)) /* Output: { @@ -3243,36 +3246,36 @@ Before ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const TestType = Schema.Struct({ a: Schema.String, - b: Schema.propertySignature(Schema.String).pipe(Schema.fromKey("c")), - }); + b: Schema.propertySignature(Schema.String).pipe(Schema.fromKey("c")) + }) - const PartialTestType = Schema.partial(TestType); + const PartialTestType = Schema.partial(TestType) // throws Error: Partial: cannot handle transformations ``` Now ```ts - import { Schema } from "@effect/schema"; + import { Schema } from "@effect/schema" const TestType = Schema.Struct({ a: Schema.String, - b: Schema.propertySignature(Schema.String).pipe(Schema.fromKey("c")), - }); + b: Schema.propertySignature(Schema.String).pipe(Schema.fromKey("c")) + }) - const PartialTestType = Schema.partial(TestType); + const PartialTestType = Schema.partial(TestType) - console.log(Schema.decodeUnknownSync(PartialTestType)({ a: "a", c: "c" })); // { a: 'a', b: 'c' } - console.log(Schema.decodeUnknownSync(PartialTestType)({ a: "a" })); // { a: 'a' } + console.log(Schema.decodeUnknownSync(PartialTestType)({ a: "a", c: "c" })) // { a: 'a', b: 'c' } + console.log(Schema.decodeUnknownSync(PartialTestType)({ a: "a" })) // { a: 'a' } - const RequiredTestType = Schema.required(PartialTestType); + const RequiredTestType = Schema.required(PartialTestType) - console.log(Schema.decodeUnknownSync(RequiredTestType)({ a: "a", c: "c" })); // { a: 'a', b: 'c' } - console.log(Schema.decodeUnknownSync(RequiredTestType)({ a: "a" })); // { a: 'a', b: undefined } + console.log(Schema.decodeUnknownSync(RequiredTestType)({ a: "a", c: "c" })) // { a: 'a', b: 'c' } + console.log(Schema.decodeUnknownSync(RequiredTestType)({ a: "a" })) // { a: 'a', b: undefined } ``` ## 0.66.3 @@ -3311,8 +3314,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -3446,38 +3449,38 @@ The codemod is designed to automate many of the changes needed. However, it migh Before ```ts - import { Arbitrary, Schema } from "@effect/schema"; - import * as fc from "fast-check"; + import { Arbitrary, Schema } from "@effect/schema" + import * as fc from "fast-check" const Person = Schema.struct({ name: Schema.string, age: Schema.string.pipe( Schema.compose(Schema.NumberFromString), - Schema.int(), - ), - }); + Schema.int() + ) + }) - const arb = Arbitrary.make(Person)(fc); + const arb = Arbitrary.make(Person)(fc) - console.log(fc.sample(arb, 2)); + console.log(fc.sample(arb, 2)) ``` Now ```ts - import { Arbitrary, FastCheck, Schema } from "@effect/schema"; + import { Arbitrary, FastCheck, Schema } from "@effect/schema" const Person = Schema.Struct({ name: Schema.String, age: Schema.String.pipe( Schema.compose(Schema.NumberFromString), - Schema.int(), - ), - }); + Schema.int() + ) + }) - const arb = Arbitrary.make(Person); + const arb = Arbitrary.make(Person) - console.log(FastCheck.sample(arb, 2)); + console.log(FastCheck.sample(arb, 2)) ``` ### Patch Changes @@ -3501,8 +3504,8 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts export type ParseIssueTitleAnnotation = ( - issue: ParseIssue, - ) => string | undefined; + issue: ParseIssue + ) => string | undefined ``` If you set this annotation on a schema and the provided function returns a `string`, then that string is used as the title by `TreeFormatter`, unless a `message` annotation (which has the highest priority) has also been set. If the function returns `undefined`, then the default title used by `TreeFormatter` is determined with the following priorities: @@ -3515,43 +3518,43 @@ The codemod is designed to automate many of the changes needed. However, it migh **Example** ```ts - import type { ParseIssue } from "@effect/schema/ParseResult"; - import * as S from "@effect/schema/Schema"; + import type { ParseIssue } from "@effect/schema/ParseResult" + import * as S from "@effect/schema/Schema" const getOrderItemId = ({ actual }: ParseIssue) => { if (S.is(S.struct({ id: S.string }))(actual)) { - return `OrderItem with id: ${actual.id}`; + return `OrderItem with id: ${actual.id}` } - }; + } const OrderItem = S.struct({ id: S.string, name: S.string, - price: S.number, + price: S.number }).annotations({ identifier: "OrderItem", - parseIssueTitle: getOrderItemId, - }); + parseIssueTitle: getOrderItemId + }) const getOrderId = ({ actual }: ParseIssue) => { if (S.is(S.struct({ id: S.number }))(actual)) { - return `Order with id: ${actual.id}`; + return `Order with id: ${actual.id}` } - }; + } const Order = S.struct({ id: S.number, name: S.string, - items: S.array(OrderItem), + items: S.array(OrderItem) }).annotations({ identifier: "Order", - parseIssueTitle: getOrderId, - }); + parseIssueTitle: getOrderId + }) - const decode = S.decodeUnknownSync(Order, { errors: "all" }); + const decode = S.decodeUnknownSync(Order, { errors: "all" }) // No id available, so the `identifier` annotation is used as the title - decode({}); + decode({}) /* throws Error: Order @@ -3564,7 +3567,7 @@ The codemod is designed to automate many of the changes needed. However, it migh */ // An id is available, so the `parseIssueTitle` annotation is used as the title - decode({ id: 1 }); + decode({ id: 1 }) /* throws Error: Order with id: 1 @@ -3574,7 +3577,7 @@ The codemod is designed to automate many of the changes needed. However, it migh └─ is missing */ - decode({ id: 1, items: [{ id: "22b", price: "100" }] }); + decode({ id: 1, items: [{ id: "22b", price: "100" }] }) /* throws Error: Order with id: 1 @@ -3602,14 +3605,14 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" class MySchema extends S.Class("MySchema")({ a: S.string, - b: S.number, + b: S.number }) {} - S.decodeUnknownSync(MySchema)({}, { errors: "all" }); + S.decodeUnknownSync(MySchema)({}, { errors: "all" }) /* Error: ({ a: string; b: number } <-> MySchema) └─ Encoded side transformation failure @@ -3624,14 +3627,14 @@ The codemod is designed to automate many of the changes needed. However, it migh After: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" class MySchema extends S.Class("MySchema")({ a: S.string, - b: S.number, + b: S.number }) {} - S.decodeUnknownSync(MySchema)({}, { errors: "all" }); + S.decodeUnknownSync(MySchema)({}, { errors: "all" }) /* Error: (MySchema (Encoded side) <-> MySchema) └─ Encoded side transformation failure @@ -3648,13 +3651,13 @@ The codemod is designed to automate many of the changes needed. However, it migh Example ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" const schema = S.string.pipe( - S.length({ min: 2, max: 4 }, { identifier: "MyRange" }), - ); + S.length({ min: 2, max: 4 }, { identifier: "MyRange" }) + ) - S.decodeUnknownSync(schema)(""); + S.decodeUnknownSync(schema)("") /* throws: Error: MyRange @@ -3682,17 +3685,17 @@ The codemod is designed to automate many of the changes needed. However, it migh Examples (Tuple) ```ts - import * as S from "@effect/schema/Schema"; - import * as Either from "effect/Either"; + import * as S from "@effect/schema/Schema" + import * as Either from "effect/Either" - const schema = S.array(S.number); + const schema = S.array(S.number) const result = S.decodeUnknownEither(schema)([1, "a", 2, "b"], { - errors: "all", - }); + errors: "all" + }) if (Either.isLeft(result)) { - const issue = result.left.error; + const issue = result.left.error if (issue._tag === "TupleType") { - console.log(issue.output); // [1, 2] + console.log(issue.output) // [1, 2] } } ``` @@ -3700,18 +3703,18 @@ The codemod is designed to automate many of the changes needed. However, it migh Examples (TypeLiteral) ```ts - import * as S from "@effect/schema/Schema"; - import * as Either from "effect/Either"; + import * as S from "@effect/schema/Schema" + import * as Either from "effect/Either" - const schema = S.record(S.string, S.number); + const schema = S.record(S.string, S.number) const result = S.decodeUnknownEither(schema)( { a: 1, b: "b", c: 2, d: "d" }, - { errors: "all" }, - ); + { errors: "all" } + ) if (Either.isLeft(result)) { - const issue = result.left.error; + const issue = result.left.error if (issue._tag === "TypeLiteral") { - console.log(issue.output); // { a: 1, c: 2 } + console.log(issue.output) // { a: 1, c: 2 } } } ``` @@ -3736,20 +3739,20 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts enum Fruits { Apple, - Banana, + Banana } // $ExpectType enums - S.enums(Fruits); + S.enums(Fruits) // $ExpectType typeof Fruits - S.enums(Fruits).enums; + S.enums(Fruits).enums // $ExpectType Fruits.Apple - S.enums(Fruits).enums.Apple; + S.enums(Fruits).enums.Apple // $ExpectType Fruits.Banana - S.enums(Fruits).enums.Banana; + S.enums(Fruits).enums.Banana ``` ## 0.64.15 @@ -3789,16 +3792,16 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts // ts 5.3 - type A = readonly [string, ...number[], boolean]; - type B = Required; // readonly [string, ...(number | boolean)[], number | boolean] + type A = readonly [string, ...number[], boolean] + type B = Required // readonly [string, ...(number | boolean)[], number | boolean] ``` to ```ts // ts 5.4 - type A = readonly [string, ...number[], boolean]; - type B = Required; // readonly [string, ...number[], boolean] + type A = readonly [string, ...number[], boolean] + type B = Required // readonly [string, ...number[], boolean] ``` - [#2359](https://github.com/Effect-TS/effect/pull/2359) [`9392de6`](https://github.com/Effect-TS/effect/commit/9392de6baa6861662abc2bd3171897145f5ea073) Thanks [@tim-smart](https://github.com/tim-smart)! - use provided message in Schema.TaggedError .toString @@ -3856,27 +3859,27 @@ The codemod is designed to automate many of the changes needed. However, it migh - [#2353](https://github.com/Effect-TS/effect/pull/2353) [`5f5fcd9`](https://github.com/Effect-TS/effect/commit/5f5fcd969ae30ed6fe61d566a571498d9e895e16) Thanks [@tim-smart](https://github.com/tim-smart)! - make `optional` dual: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" const schema = S.struct({ - a: S.string.pipe(S.optional()), - }); + a: S.string.pipe(S.optional()) + }) // same as: const schema2 = S.struct({ - a: S.optional(S.string), - }); + a: S.optional(S.string) + }) ``` - [#2356](https://github.com/Effect-TS/effect/pull/2356) [`7a45ad0`](https://github.com/Effect-TS/effect/commit/7a45ad0a5f715d64a69b28a8ee3573e5f86909c3) Thanks [@gcanti](https://github.com/gcanti)! - make `partial` dual: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema = S.struct({ a: S.string }).pipe(S.partial()); + const schema = S.struct({ a: S.string }).pipe(S.partial()) // same as: - const schema2 = S.partial(S.struct({ a: S.string })); + const schema2 = S.partial(S.struct({ a: S.string })) ``` - [#2339](https://github.com/Effect-TS/effect/pull/2339) [`5c3b1cc`](https://github.com/Effect-TS/effect/commit/5c3b1ccba182d0f636a973729f9c6bfb12539dc8) Thanks [@gcanti](https://github.com/gcanti)! - use `Simplify` from `effect/Types` in `TaggedClass`, `TaggedError` and `TaggedRequest` to avoid errors in `Schema.d.ts`, closes #1841 @@ -3982,17 +3985,17 @@ The codemod is designed to automate many of the changes needed. However, it migh Before ```ts - import * as ParseResult from "@effect/schema/ParseResult"; + import * as ParseResult from "@effect/schema/ParseResult" - ParseResult.type(ast, actual); + ParseResult.type(ast, actual) ``` Now ```ts - import * as ParseResult from "@effect/schema/ParseResult"; + import * as ParseResult from "@effect/schema/ParseResult" - new ParseResult.Type(ast, actual); + new ParseResult.Type(ast, actual) ``` - `Transform` has been refactored to `Transformation`, and its `kind` property now accepts `"Encoded"`, `"Transformation"`, or `"Type"` as values @@ -4015,24 +4018,21 @@ The codemod is designed to automate many of the changes needed. However, it migh Before ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema1 = S.tuple().pipe(S.rest(S.number), S.element(S.boolean)); + const schema1 = S.tuple().pipe(S.rest(S.number), S.element(S.boolean)) - const schema2 = S.tuple(S.string).pipe( - S.rest(S.number), - S.element(S.boolean), - ); + const schema2 = S.tuple(S.string).pipe(S.rest(S.number), S.element(S.boolean)) ``` Now ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema1 = S.tuple([], S.number, S.boolean); + const schema1 = S.tuple([], S.number, S.boolean) - const schema2 = S.tuple([S.string], S.number, S.boolean); + const schema2 = S.tuple([S.string], S.number, S.boolean) ``` - `optionalElement` has been refactored: @@ -4040,17 +4040,17 @@ The codemod is designed to automate many of the changes needed. However, it migh Before ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema = S.tuple(S.string).pipe(S.optionalElement(S.number)); + const schema = S.tuple(S.string).pipe(S.optionalElement(S.number)) ``` Now ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema = S.tuple(S.string, S.optionalElement(S.number)); + const schema = S.tuple(S.string, S.optionalElement(S.number)) ``` - use `TreeFormatter` in `BrandSchema`s @@ -4061,16 +4061,16 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts S.optional(S.string, { exact: true, - annotations: { description: "description" }, - }); + annotations: { description: "description" } + }) ``` Now ```ts S.optional(S.string, { exact: true }).annotations({ - description: "description", - }); + description: "description" + }) ``` - Updated the `pluck` function to return `Schema` instead of `Schema`. Removed the `{ transformation: false }` option in favor of selecting the specific field from the `fields` exposed by a struct. @@ -4093,16 +4093,16 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts const schema1 = S.struct( { a: S.number }, - { key: S.string, value: S.number }, - ); + { key: S.string, value: S.number } + ) // or - const schema2 = S.struct({ a: S.number }, S.record(S.string, S.number)); + const schema2 = S.struct({ a: S.number }, S.record(S.string, S.number)) ``` - enhance the `extend` API to allow nested (non-overlapping) fields: ```ts - const A = S.struct({ a: S.struct({ b: S.string }) }); - const B = S.struct({ a: S.struct({ c: S.number }) }); - const schema = S.extend(A, B); + const A = S.struct({ a: S.struct({ b: S.string }) }) + const B = S.struct({ a: S.struct({ c: S.number }) }) + const schema = S.extend(A, B) /* same as: const schema = S.struct({ @@ -4122,14 +4122,14 @@ The codemod is designed to automate many of the changes needed. However, it migh - add `annotations?` parameter to Class constructors: ```ts - import * as AST from "@effect/schema/AST"; - import * as S from "@effect/schema/Schema"; + import * as AST from "@effect/schema/AST" + import * as S from "@effect/schema/Schema" class A extends S.Class("A")( { - a: S.string, + a: S.string }, - { description: "some description..." }, // <= annotations + { description: "some description..." } // <= annotations ) {} ``` @@ -4154,8 +4154,8 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts const schema = S.struct({ a: S.string, - b: S.number, - }).pipe(S.batching(true /* boolean | "inherit" | undefined */)); + b: S.number + }).pipe(S.batching(true /* boolean | "inherit" | undefined */)) ``` - [#2241](https://github.com/Effect-TS/effect/pull/2241) [`d8e6940`](https://github.com/Effect-TS/effect/commit/d8e694040f67da6fefc0f5c98fc8e15c0b48822e) Thanks [@jessekelly881](https://github.com/jessekelly881)! - add `sortedSet` and `sortedSetFromSeld` combinators @@ -4176,8 +4176,8 @@ The codemod is designed to automate many of the changes needed. However, it migh ```ts const schema = S.struct({ a: S.string, - b: S.number, - }).pipe(S.concurrency(1 /* number | "unbounded" | "inherit" | undefined */)); + b: S.number + }).pipe(S.concurrency(1 /* number | "unbounded" | "inherit" | undefined */)) ``` - [#2221](https://github.com/Effect-TS/effect/pull/2221) [`c035972`](https://github.com/Effect-TS/effect/commit/c035972dfabdd3cb3372b5ab468aa2fd0d808f4d) Thanks [@tim-smart](https://github.com/tim-smart)! - ensure Schema.Class is compatible without strictNullCheck @@ -4192,13 +4192,13 @@ The codemod is designed to automate many of the changes needed. However, it migh - [#2209](https://github.com/Effect-TS/effect/pull/2209) [`5d30853`](https://github.com/Effect-TS/effect/commit/5d308534cac6f187227185393c0bac9eb27f90ab) Thanks [@steffanek](https://github.com/steffanek)! - Add `pickLiteral` to Schema so that we can pick values from a Schema literal as follows: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - const schema = S.literal("a", "b", "c").pipe(S.pickLiteral("a", "b")); // same as S.literal("a", "b") + const schema = S.literal("a", "b", "c").pipe(S.pickLiteral("a", "b")) // same as S.literal("a", "b") - S.decodeUnknownSync(schema)("a"); // ok - S.decodeUnknownSync(schema)("b"); // ok - S.decodeUnknownSync(schema)("c"); + S.decodeUnknownSync(schema)("a") // ok + S.decodeUnknownSync(schema)("b") // ok + S.decodeUnknownSync(schema)("c") /* Error: "a" | "b" ├─ Union member @@ -4234,9 +4234,9 @@ The codemod is designed to automate many of the changes needed. However, it migh Along the same line of the other changes this allows to shorten the most common types such as: ```ts - import { Either } from "effect"; + import { Either } from "effect" - const right: Either.Either = Either.right("ok"); + const right: Either.Either = Either.right("ok") ``` ### Patch Changes @@ -4279,7 +4279,7 @@ The codemod is designed to automate many of the changes needed. However, it migh **Example** ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" /* const schema: S.Schema<{ @@ -4288,10 +4288,10 @@ The codemod is designed to automate many of the changes needed. However, it migh readonly a?: string | undefined; }, never> */ - const schema = S.partial(S.struct({ a: S.string })); + const schema = S.partial(S.struct({ a: S.string })) - S.decodeUnknownSync(schema)({ a: "a" }); // ok - S.decodeUnknownSync(schema)({ a: undefined }); // ok + S.decodeUnknownSync(schema)({ a: "a" }) // ok + S.decodeUnknownSync(schema)({ a: undefined }) // ok /* const exact: S.Schema<{ @@ -4300,10 +4300,10 @@ The codemod is designed to automate many of the changes needed. However, it migh readonly a?: string; }, never> */ - const exactSchema = S.partial(S.struct({ a: S.string }), { exact: true }); + const exactSchema = S.partial(S.struct({ a: S.string }), { exact: true }) - S.decodeUnknownSync(exactSchema)({ a: "a" }); // ok - S.decodeUnknownSync(exactSchema)({ a: undefined }); + S.decodeUnknownSync(exactSchema)({ a: "a" }) // ok + S.decodeUnknownSync(exactSchema)({ a: undefined }) /* throws: Error: { a?: string } @@ -4317,21 +4317,21 @@ The codemod is designed to automate many of the changes needed. However, it migh The following will no longer throw an error: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" class C extends S.Class()({ - n: S.NumberFromString, + n: S.NumberFromString }) { get b() { - return 1; + return 1 } } class D extends S.Class()({ n: S.NumberFromString, - b: S.number, + b: S.number }) {} - console.log(S.encodeSync(D)(new C({ n: 1 }))); + console.log(S.encodeSync(D)(new C({ n: 1 }))) // Output: { b: 1, n: '1' } ``` @@ -4386,7 +4386,7 @@ The codemod is designed to automate many of the changes needed. However, it migh **Example** ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" // --------------------------------------------- // use case: pull out a single field from a @@ -4395,21 +4395,21 @@ The codemod is designed to automate many of the changes needed. However, it migh const mytable = S.struct({ column1: S.NumberFromString, - column2: S.number, - }); + column2: S.number + }) // const pullOutColumn1: S.Schema - const pullOutColumn1 = mytable.pipe(S.pluck("column1")); + const pullOutColumn1 = mytable.pipe(S.pluck("column1")) console.log( S.decode(S.array(pullOutColumn1))([ { column1: "1", column2: 100 }, - { column1: "2", column2: 300 }, - ]), - ); + { column1: "2", column2: 300 } + ]) + ) // Output: { _id: 'Either', _tag: 'Right', right: [ 1, 2 ] } // --------------------------------------------- @@ -4419,10 +4419,10 @@ The codemod is designed to automate many of the changes needed. However, it migh // const pullOutColumn1Value: S.Schema const pullOutColumn1Value = mytable.pipe( - S.pluck("column1", { transformation: false }), - ); + S.pluck("column1", { transformation: false }) + ) - console.log(S.decode(S.array(pullOutColumn1Value))(["1", "2"])); + console.log(S.decode(S.array(pullOutColumn1Value))(["1", "2"])) // Output: { _id: 'Either', _tag: 'Right', right: [ 1, 2 ] } ``` @@ -4458,31 +4458,31 @@ The codemod is designed to automate many of the changes needed. However, it migh - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we now require a string key to be provided for all tags and renames the dear old `Tag` to `GenericTag`, so when previously you could do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.Tag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >(); + >() ``` you are now mandated to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" interface Service { - readonly _: unique symbol; + readonly _: unique symbol } const Service = Context.GenericTag< Service, { - number: Effect.Effect; + number: Effect.Effect } - >("Service"); + >("Service") ``` This makes by default all tags globals and ensures better debuggaility when unexpected errors arise. @@ -4490,17 +4490,17 @@ The codemod is designed to automate many of the changes needed. However, it migh Furthermore we introduce a new way of constructing tags that should be considered the new default: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class Service extends Context.Tag("Service")< Service, { - number: Effect.Effect; + number: Effect.Effect } >() {} const program = Effect.flatMap(Service, ({ number }) => number).pipe( - Effect.flatMap((_) => Effect.log(`number: ${_}`)), - ); + Effect.flatMap((_) => Effect.log(`number: ${_}`)) + ) ``` this will use "Service" as the key and will create automatically an opaque identifier (the class) to be used at the type level, it does something similar to the above in a single shot. @@ -4512,19 +4512,19 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.readonlyMapFromSelf(S.string, S.number); - S.readonlyMap(S.string, S.number); + S.readonlyMapFromSelf(S.string, S.number) + S.readonlyMap(S.string, S.number) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.readonlyMapFromSelf({ key: S.string, value: S.number }); - S.readonlyMap({ key: S.string, value: S.number }); + S.readonlyMapFromSelf({ key: S.string, value: S.number }) + S.readonlyMap({ key: S.string, value: S.number }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`d3f9f4d`](https://github.com/Effect-TS/effect/commit/d3f9f4d4032b1131c62f4ddb21a4583e4e8d7c18) Thanks [@github-actions](https://github.com/apps/github-actions)! - Schema: switch `hashMapFromSelf`, `hashMap` from positional arguments to a single `options` argument: @@ -4532,19 +4532,19 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.hashMapFromSelf(S.string, S.number); - S.hashMap(S.string, S.number); + S.hashMapFromSelf(S.string, S.number) + S.hashMap(S.string, S.number) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.hashMapFromSelf({ key: S.string, value: S.number }); - S.hashMap({ key: S.string, value: S.number }); + S.hashMapFromSelf({ key: S.string, value: S.number }) + S.hashMap({ key: S.string, value: S.number }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`d3f9f4d`](https://github.com/Effect-TS/effect/commit/d3f9f4d4032b1131c62f4ddb21a4583e4e8d7c18) Thanks [@github-actions](https://github.com/apps/github-actions)! - Schema: switch `causeFromSelf`, `cause` from positional arguments to a single `options` argument: @@ -4552,23 +4552,23 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.causeFromSelf(S.string); - S.causeFromSelf(S.string, S.unknown); - S.cause(S.string); - S.cause(S.string, S.unknown); + S.causeFromSelf(S.string) + S.causeFromSelf(S.string, S.unknown) + S.cause(S.string) + S.cause(S.string, S.unknown) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.causeFromSelf({ error: S.string }); - S.causeFromSelf({ error: S.string, defect: S.unknown }); - S.cause({ error: S.string }); - S.cause({ error: S.string, defect: S.unknown }); + S.causeFromSelf({ error: S.string }) + S.causeFromSelf({ error: S.string, defect: S.unknown }) + S.cause({ error: S.string }) + S.cause({ error: S.string, defect: S.unknown }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`d3f9f4d`](https://github.com/Effect-TS/effect/commit/d3f9f4d4032b1131c62f4ddb21a4583e4e8d7c18) Thanks [@github-actions](https://github.com/apps/github-actions)! - Schema: switch `exitFromSelf`, `exit` from positional arguments to a single `options` argument: @@ -4576,19 +4576,19 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.exitFromSelf(S.string, S.number); - S.exit(S.string, S.number); + S.exitFromSelf(S.string, S.number) + S.exit(S.string, S.number) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.exitFromSelf({ failure: S.string, success: S.number }); - S.exit({ failure: S.string, success: S.number }); + S.exitFromSelf({ failure: S.string, success: S.number }) + S.exit({ failure: S.string, success: S.number }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`a34dbdc`](https://github.com/Effect-TS/effect/commit/a34dbdc1552c73c1b612676f262a0c735ce444a7) Thanks [@github-actions](https://github.com/apps/github-actions)! - - Schema: change type parameters order from `Schema` to `Schema` @@ -4602,21 +4602,21 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.eitherFromSelf(S.string, S.number); - S.either(S.string, S.number); - S.eitherFromUnion(S.string, S.number); + S.eitherFromSelf(S.string, S.number) + S.either(S.string, S.number) + S.eitherFromUnion(S.string, S.number) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" - S.eitherFromSelf({ left: S.string, right: S.number }); - S.either({ left: S.string, right: S.number }); - S.eitherFromUnion({ left: S.string, right: S.number }); + S.eitherFromSelf({ left: S.string, right: S.number }) + S.either({ left: S.string, right: S.number }) + S.eitherFromUnion({ left: S.string, right: S.number }) ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`02c3461`](https://github.com/Effect-TS/effect/commit/02c34615d02f91269ea04036d0306fccf4e39e18) Thanks [@github-actions](https://github.com/apps/github-actions)! - With this change we remove the `Data.Data` type and we make `Equal.Equal` & `Hash.Hash` implicit traits. @@ -4628,35 +4628,35 @@ The codemod is designed to automate many of the changes needed. However, it migh At the type level instead the functions return `Readonly` variants, so for example we have: ```ts - import { Data } from "effect"; + import { Data } from "effect" const obj = Data.struct({ a: 0, - b: 1, - }); + b: 1 + }) ``` will have the `obj` typed as: ```ts declare const obj: { - readonly a: number; - readonly b: number; - }; + readonly a: number + readonly b: number + } ``` - [#2006](https://github.com/Effect-TS/effect/pull/2006) [`9a2d1c1`](https://github.com/Effect-TS/effect/commit/9a2d1c1468ea0789b34767ad683da074f061ea9c) Thanks [@github-actions](https://github.com/apps/github-actions)! - This change enables `Effect.serviceConstants` and `Effect.serviceMembers` to access any constant in the service, not only the effects, namely it is now possible to do: ```ts - import { Effect, Context } from "effect"; + import { Effect, Context } from "effect" class NumberRepo extends Context.TagClass("NumberRepo")< NumberRepo, { - readonly numbers: Array; + readonly numbers: Array } >() { - static numbers = Effect.serviceConstants(NumberRepo).numbers; + static numbers = Effect.serviceConstants(NumberRepo).numbers } ``` @@ -4665,25 +4665,25 @@ The codemod is designed to automate many of the changes needed. However, it migh When used with Unify we previously had: ```ts - import { Schema } from "@effect/schema"; - import type { Unify } from "effect"; + import { Schema } from "@effect/schema" + import type { Unify } from "effect" class Err extends Schema.TaggedError()("Err", {}) {} // $ExpectType Effect - export type IdErr = Unify.Unify; + export type IdErr = Unify.Unify ``` With this fix we now have: ```ts - import { Schema } from "@effect/schema"; - import type { Unify } from "effect"; + import { Schema } from "@effect/schema" + import type { Unify } from "effect" class Err extends Schema.TaggedError()("Err", {}) {} // $ExpectType Err - export type IdErr = Unify.Unify; + export type IdErr = Unify.Unify ``` ### Patch Changes @@ -4697,25 +4697,25 @@ The codemod is designed to automate many of the changes needed. However, it migh Before: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" const myschema = S.struct({ a: S.optional(S.string).pipe( - S.propertySignatureAnnotations({ description: "my description..." }), - ), - }); + S.propertySignatureAnnotations({ description: "my description..." }) + ) + }) ``` Now: ```ts - import * as S from "@effect/schema/Schema"; + import * as S from "@effect/schema/Schema" const myschema = S.struct({ a: S.optional(S.string, { - annotations: { description: "my description..." }, - }), - }); + annotations: { description: "my description..." } + }) + }) ``` With this update, you can easily include annotations directly within the `optional` API without the need for additional calls. diff --git a/packages/schema/package.json b/packages/schema/package.json index 90258835b1..de1f890c8c 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@effect/schema", - "version": "0.71.4", + "version": "0.72.0", "type": "module", "license": "MIT", "description": "Modeling the schema of data structures as first-class values", diff --git a/packages/sql-d1/CHANGELOG.md b/packages/sql-d1/CHANGELOG.md index 7ea1dd8363..7b7fe4c668 100644 --- a/packages/sql-d1/CHANGELOG.md +++ b/packages/sql-d1/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-d1 +## 0.7.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.6.7 ### Patch Changes @@ -75,22 +84,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -102,9 +111,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes diff --git a/packages/sql-d1/package.json b/packages/sql-d1/package.json index 306c3dfb60..39c173325d 100644 --- a/packages/sql-d1/package.json +++ b/packages/sql-d1/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-d1", - "version": "0.6.7", + "version": "0.7.0", "type": "module", "license": "MIT", "description": "A Cloudflare D1 integration for Effect", diff --git a/packages/sql-drizzle/CHANGELOG.md b/packages/sql-drizzle/CHANGELOG.md index 5d0f54a1e4..20c825ca51 100644 --- a/packages/sql-drizzle/CHANGELOG.md +++ b/packages/sql-drizzle/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/sql-drizzle +## 0.8.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/sql@0.10.0 + ## 0.7.7 ### Patch Changes @@ -504,25 +512,25 @@ `@effect/sql`. ```ts - import { SqliteDrizzle } from "@effect/sql-drizzle/Sqlite"; - import * as D from "drizzle-orm/sqlite-core"; - import { Effect } from "effect"; + import { SqliteDrizzle } from "@effect/sql-drizzle/Sqlite" + import * as D from "drizzle-orm/sqlite-core" + import { Effect } from "effect" const users = D.sqliteTable("users", { id: D.integer("id").primaryKey(), - name: D.text("name"), - }); + name: D.text("name") + }) Effect.gen(function* () { - const db = yield* SqliteDrizzle; - yield* db.delete(users); - yield* db.insert(users).values({ id: 1, name: "Alice" }); + const db = yield* SqliteDrizzle + yield* db.delete(users) + yield* db.insert(users).values({ id: 1, name: "Alice" }) const results: Array<{ - id: number; - name: string | null; - }> = yield* db.select().from(users); - console.log("got results", results); - }); + id: number + name: string | null + }> = yield* db.select().from(users) + console.log("got results", results) + }) ``` ### Patch Changes diff --git a/packages/sql-drizzle/package.json b/packages/sql-drizzle/package.json index e4e1e15e81..c31e863641 100644 --- a/packages/sql-drizzle/package.json +++ b/packages/sql-drizzle/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-drizzle", - "version": "0.7.7", + "version": "0.8.0", "type": "module", "license": "MIT", "description": "Drizzle integration for @effect/sql", diff --git a/packages/sql-kysely/CHANGELOG.md b/packages/sql-kysely/CHANGELOG.md index 765d884965..296d30f7dc 100644 --- a/packages/sql-kysely/CHANGELOG.md +++ b/packages/sql-kysely/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/sql-kysely +## 0.5.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/sql@0.10.0 + ## 0.4.7 ### Patch Changes diff --git a/packages/sql-kysely/package.json b/packages/sql-kysely/package.json index 92d05c6833..3de2e26b6f 100644 --- a/packages/sql-kysely/package.json +++ b/packages/sql-kysely/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-kysely", - "version": "0.4.7", + "version": "0.5.0", "type": "module", "license": "MIT", "description": "Kysely integration for @effect/sql", diff --git a/packages/sql-mssql/CHANGELOG.md b/packages/sql-mssql/CHANGELOG.md index 0e67c68f2c..11f96c4ab1 100644 --- a/packages/sql-mssql/CHANGELOG.md +++ b/packages/sql-mssql/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-mssql +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.9.7 ### Patch Changes @@ -75,22 +84,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -102,9 +111,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -851,43 +860,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-mssql/package.json b/packages/sql-mssql/package.json index 2fa131a8b4..3ff9b01959 100644 --- a/packages/sql-mssql/package.json +++ b/packages/sql-mssql/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-mssql", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A Microsoft SQL Server toolkit for Effect", diff --git a/packages/sql-mysql2/CHANGELOG.md b/packages/sql-mysql2/CHANGELOG.md index eb0693d250..30df49ccfd 100644 --- a/packages/sql-mysql2/CHANGELOG.md +++ b/packages/sql-mysql2/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-mysql2 +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.9.7 ### Patch Changes @@ -77,22 +86,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -104,9 +113,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -853,43 +862,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-mysql2/package.json b/packages/sql-mysql2/package.json index bcaef66fb9..3487ed1d88 100644 --- a/packages/sql-mysql2/package.json +++ b/packages/sql-mysql2/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-mysql2", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A MySQL toolkit for Effect", diff --git a/packages/sql-pg/CHANGELOG.md b/packages/sql-pg/CHANGELOG.md index d21eb5a4a5..e02aef95c7 100644 --- a/packages/sql-pg/CHANGELOG.md +++ b/packages/sql-pg/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-pg +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.9.7 ### Patch Changes @@ -75,22 +84,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -102,9 +111,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -851,43 +860,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-pg/package.json b/packages/sql-pg/package.json index 59de685f7d..ccb1e44da3 100644 --- a/packages/sql-pg/package.json +++ b/packages/sql-pg/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-pg", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A PostgreSQL toolkit for Effect", diff --git a/packages/sql-sqlite-bun/CHANGELOG.md b/packages/sql-sqlite-bun/CHANGELOG.md index 2a7b5958a9..9d1fac14a4 100644 --- a/packages/sql-sqlite-bun/CHANGELOG.md +++ b/packages/sql-sqlite-bun/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-sqlite-bun +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.9.7 ### Patch Changes @@ -75,22 +84,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -102,9 +111,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -849,43 +858,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-sqlite-bun/package.json b/packages/sql-sqlite-bun/package.json index 6345dafb89..ba84d4ca0e 100644 --- a/packages/sql-sqlite-bun/package.json +++ b/packages/sql-sqlite-bun/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-sqlite-bun", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A SQLite toolkit for Effect", diff --git a/packages/sql-sqlite-node/CHANGELOG.md b/packages/sql-sqlite-node/CHANGELOG.md index a93e426371..96689ee140 100644 --- a/packages/sql-sqlite-node/CHANGELOG.md +++ b/packages/sql-sqlite-node/CHANGELOG.md @@ -1,5 +1,14 @@ # @effect/sql-sqlite-node +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/sql@0.10.0 + ## 0.9.7 ### Patch Changes @@ -75,22 +84,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -102,9 +111,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -857,43 +866,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-sqlite-node/package.json b/packages/sql-sqlite-node/package.json index d537c48890..9ecf39f9a1 100644 --- a/packages/sql-sqlite-node/package.json +++ b/packages/sql-sqlite-node/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-sqlite-node", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A SQLite toolkit for Effect", diff --git a/packages/sql-sqlite-react-native/CHANGELOG.md b/packages/sql-sqlite-react-native/CHANGELOG.md index 9a04f8b39c..02b88ccfd4 100644 --- a/packages/sql-sqlite-react-native/CHANGELOG.md +++ b/packages/sql-sqlite-react-native/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/sql-sqlite-react-native +## 0.12.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/sql@0.10.0 + ## 0.11.7 ### Patch Changes @@ -70,22 +78,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -97,9 +105,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -769,43 +777,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-sqlite-react-native/package.json b/packages/sql-sqlite-react-native/package.json index 4d6d43214c..81de4a8e65 100644 --- a/packages/sql-sqlite-react-native/package.json +++ b/packages/sql-sqlite-react-native/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-sqlite-react-native", - "version": "0.11.7", + "version": "0.12.0", "type": "module", "license": "MIT", "description": "A SQLite toolkit for Effect", diff --git a/packages/sql-sqlite-wasm/CHANGELOG.md b/packages/sql-sqlite-wasm/CHANGELOG.md index a956e49bdc..62a45b9a33 100644 --- a/packages/sql-sqlite-wasm/CHANGELOG.md +++ b/packages/sql-sqlite-wasm/CHANGELOG.md @@ -1,5 +1,13 @@ # @effect/sql-sqlite-wasm +## 0.9.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/sql@0.10.0 + ## 0.8.7 ### Patch Changes @@ -70,22 +78,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -97,9 +105,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -759,43 +767,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql-sqlite-wasm/package.json b/packages/sql-sqlite-wasm/package.json index 0efaa40921..6eea253293 100644 --- a/packages/sql-sqlite-wasm/package.json +++ b/packages/sql-sqlite-wasm/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql-sqlite-wasm", - "version": "0.8.7", + "version": "0.9.0", "type": "module", "license": "MIT", "description": "A SQLite toolkit for Effect", diff --git a/packages/sql/CHANGELOG.md b/packages/sql/CHANGELOG.md index 2bf33387fa..7063c83a21 100644 --- a/packages/sql/CHANGELOG.md +++ b/packages/sql/CHANGELOG.md @@ -1,5 +1,15 @@ # @effect/sql +## 0.10.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + - @effect/platform@0.63.0 + - @effect/experimental@0.24.0 + - @effect/schema@0.72.0 + ## 0.9.7 ### Patch Changes @@ -85,36 +95,36 @@ the database and serializing to JSON. ```ts - import { Schema } from "@effect/schema"; - import { Model } from "@effect/sql"; + import { Schema } from "@effect/schema" + import { Model } from "@effect/sql" - export const GroupId = Schema.Number.pipe(Schema.brand("GroupId")); + export const GroupId = Schema.Number.pipe(Schema.brand("GroupId")) export class Group extends Model.Class("Group")({ id: Model.Generated(GroupId), name: Schema.NonEmptyTrimmedString, createdAt: Model.DateTimeInsertFromDate, - updatedAt: Model.DateTimeUpdateFromDate, + updatedAt: Model.DateTimeUpdateFromDate }) {} // schema used for selects - Group; + Group // schema used for inserts - Group.insert; + Group.insert // schema used for updates - Group.update; + Group.update // schema used for json api - Group.json; - Group.jsonCreate; - Group.jsonUpdate; + Group.json + Group.jsonCreate + Group.jsonUpdate // you can also turn them into classes class GroupJson extends Schema.Class("GroupJson")(Group.json) { get upperName() { - return this.name.toUpperCase(); + return this.name.toUpperCase() } } ``` @@ -141,22 +151,22 @@ the `Statement`: ```ts - import * as Effect from "effect/Effect"; - import * as SqlClient from "@effect/sql/SqlClient"; - import * as MysqlClient from "@effect/sql/MysqlClient"; + import * as Effect from "effect/Effect" + import * as SqlClient from "@effect/sql/SqlClient" + import * as MysqlClient from "@effect/sql/MysqlClient" const DatabaseLive = MysqlClient.layer({ database: Config.succeed("database"), username: Config.succeed("root"), - password: Config.succeed(Redacted.make("password")), - }); + password: Config.succeed(Redacted.make("password")) + }) const program = Effect.gen(function* () { - const sql = yield* SqlClient.SqlClient; + const sql = yield* SqlClient.SqlClient - const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw; + const result = yield* sql`INSERT INTO usernames VALUES ("Bob")`.raw - console.log(result); + console.log(result) /** * ResultSetHeader { * fieldCount: 0, @@ -168,9 +178,9 @@ * changedRows: 0 * } */ - }); + }) - program.pipe(Effect.provide(DatabaseLive), Effect.runPromise); + program.pipe(Effect.provide(DatabaseLive), Effect.runPromise) ``` ### Patch Changes @@ -892,43 +902,43 @@ You can now use the `@effect/sql` package to access the client apis: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; - yield* sql`SELECT * FROM users`; - }); + const sql = yield* Sql.client.Client + yield* sql`SELECT * FROM users` + }) ``` If you need a functionality that is specific to a implementation, you can use the tag from the implementation package: ```ts - import * as Sqlite from "@effect/sql-sqlite-node"; - import { Effect } from "effect"; + import * as Sqlite from "@effect/sql-sqlite-node" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sqlite.client.SqliteClient; - const dump = yield* sql.export; - }); + const sql = yield* Sqlite.client.SqliteClient + const dump = yield* sql.export + }) ``` If you need to run a different query depending on the dialect, you can use the `sql.onDialect` api: ```ts - import * as Sql from "@effect/sql"; - import { Effect } from "effect"; + import * as Sql from "@effect/sql" + import { Effect } from "effect" Effect.gen(function* () { - const sql = yield* Sql.client.Client; + const sql = yield* Sql.client.Client yield* sql.onDialect({ sqlite: () => sql`SELECT * FROM sqlite_master`, mysql: () => sql`SHOW TABLES`, mssql: () => sql`SELECT * FROM sys.tables`, - pg: () => sql`SELECT * FROM pg_catalog.pg_tables`, - }); - }); + pg: () => sql`SELECT * FROM pg_catalog.pg_tables` + }) + }) ``` ### Patch Changes diff --git a/packages/sql/package.json b/packages/sql/package.json index 09bd8bc6d3..4f964b1d2d 100644 --- a/packages/sql/package.json +++ b/packages/sql/package.json @@ -1,6 +1,6 @@ { "name": "@effect/sql", - "version": "0.9.7", + "version": "0.10.0", "type": "module", "license": "MIT", "description": "A SQL toolkit for Effect", diff --git a/packages/typeclass/CHANGELOG.md b/packages/typeclass/CHANGELOG.md index 473228ca00..ba0ca7442d 100644 --- a/packages/typeclass/CHANGELOG.md +++ b/packages/typeclass/CHANGELOG.md @@ -1,5 +1,12 @@ # @effect/typeclass +## 0.26.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + ## 0.25.8 ### Patch Changes @@ -445,8 +452,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` @@ -604,9 +611,9 @@ Along the same line of the other changes this allows to shorten the most common types such as: ```ts - import { Either } from "effect"; + import { Either } from "effect" - const right: Either.Either = Either.right("ok"); + const right: Either.Either = Either.right("ok") ``` ### Patch Changes diff --git a/packages/typeclass/package.json b/packages/typeclass/package.json index 9ea5d60ff3..aa76daa687 100644 --- a/packages/typeclass/package.json +++ b/packages/typeclass/package.json @@ -1,6 +1,6 @@ { "name": "@effect/typeclass", - "version": "0.25.8", + "version": "0.26.0", "type": "module", "license": "MIT", "description": "A collection of reusable typeclasses for the Effect ecosystem", diff --git a/packages/vitest/CHANGELOG.md b/packages/vitest/CHANGELOG.md index 885359ef6d..83717bc531 100644 --- a/packages/vitest/CHANGELOG.md +++ b/packages/vitest/CHANGELOG.md @@ -1,5 +1,12 @@ # @effect/vitest +## 0.9.0 + +### Patch Changes + +- Updated dependencies [[`db89601`](https://github.com/Effect-TS/effect/commit/db89601ee9c1050c4e762b7bd7ec65a6a2799dfe), [`2f456cc`](https://github.com/Effect-TS/effect/commit/2f456cce5012b9fcb6b4e039190d527813b75b92), [`8745e41`](https://github.com/Effect-TS/effect/commit/8745e41ed96e3765dc6048efc2a9afbe05c8a1e9), [`e557838`](https://github.com/Effect-TS/effect/commit/e55783886b046d3c5f33447f455f9ccf2fa75922), [`d6e7e40`](https://github.com/Effect-TS/effect/commit/d6e7e40b1e2ad0c59aa02f07344d28601b14ebdc), [`8356321`](https://github.com/Effect-TS/effect/commit/8356321598da04bd77c1001f45a4e447bec5591d), [`192f2eb`](https://github.com/Effect-TS/effect/commit/192f2ebb2c4ddbf4bfd8baedd32140b2376868f4), [`718cb70`](https://github.com/Effect-TS/effect/commit/718cb70038629a6d58d02e407760e341f7c94474), [`e9d0310`](https://github.com/Effect-TS/effect/commit/e9d03107acbf204d9304f3e8aea0816b7d3c7dfb), [`6bf28f7`](https://github.com/Effect-TS/effect/commit/6bf28f7e3b1e5e0608ff567205fea0581d11666f)]: + - effect@3.7.0 + ## 0.8.9 ### Patch Changes @@ -59,29 +66,29 @@ will be correctly released even if the test times out. ```ts - import { it } from "@effect/vitest"; - import { Console, Effect, Layer } from "effect"; + import { it } from "@effect/vitest" + import { Console, Effect, Layer } from "effect" class Database extends Effect.Tag("Database")() { static readonly test = Layer.scoped( Database, Effect.acquireRelease( Effect.as(Console.log("database setup"), Database.of({})), - () => Console.log("database teardown"), - ), - ); + () => Console.log("database teardown") + ) + ) } it.live( "testing with closable resources", () => Effect.gen(function* () { - const database = yield* Database; + const database = yield* Database // performing some time consuming operations - yield* Effect.sleep("500 millis"); + yield* Effect.sleep("500 millis") }).pipe(Effect.provide(Database.test)), - { timeout: 100 }, - ); + { timeout: 100 } + ) ``` ## 0.8.1 @@ -214,16 +221,16 @@ Example usage ```ts - import { expect, it } from "@effect/vitest"; - import { Effect } from "effect"; + import { expect, it } from "@effect/vitest" + import { Effect } from "effect" it.scoped.skip("test skipped", () => - Effect.acquireRelease(Effect.die("skipped anyway"), () => Effect.void), - ); + Effect.acquireRelease(Effect.die("skipped anyway"), () => Effect.void) + ) it.effect.each([1, 2, 3])("effect each %s", (n) => - Effect.sync(() => expect(n).toEqual(n)), - ); + Effect.sync(() => expect(n).toEqual(n)) + ) ``` ### Patch Changes @@ -519,8 +526,8 @@ For all the data types. ```ts - Effect.unit; // => Effect.void - Stream.unit; // => Stream.void + Effect.unit // => Effect.void + Stream.unit // => Stream.void // etc ``` diff --git a/packages/vitest/package.json b/packages/vitest/package.json index a6b5e4331a..f3e5593844 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -1,6 +1,6 @@ { "name": "@effect/vitest", - "version": "0.8.9", + "version": "0.9.0", "type": "module", "license": "MIT", "description": "A set of helpers for testing Effects with vitest",