Skip to content

Releases: realpha/eitherway

0.10.0

02 Apr 11:10
25e071b
Compare
Choose a tag to compare

Features

  • New names for pass-through conditionals. .trip() and .rise() have been renamed to .andEnsure() and .orEnsure() respectively. This change is consistent with the general naming convention and semantically clearer. Here an example taken from the build script:
function main() {
  return parseVersion()
    .into(Task.of<SemVer, TypeError>)
    .andEnsure(() => dirIsEmpty(OUT_DIR))
    .andThen(buildPackage);
}
  • Consolidated exceptions. Introduction of Panic<E>, a canonical runtime exception which can be used in case an invariant is violated. This is accompanied by the panic helper function, a small utility to ease working with truely unrecoverable errors and a way to emulate the behaviour of .unwrap() from other languages/ecosystems.
import { panic, Option, Result } from "https://deno.land/x/eitherway/mod.ts";

function parseHex(hex: string): Result<number, TypeError> {
  return Option.fromCoercible(hex)
    .map((hex) => Number.parseInt(hex, 16))
    .filter(Number.isInteger)
    .okOrElse(() => TypeError("Cannot parse hex string", { cause: hex }));
}

const res = Result("0x10f2c").andThen(parseHex);

const value: number = res.unwrapOrElse(panic);

Deprecations

Support for cjs modules will be dropped. Please see this issue for all planned deprecations.
The following features have been marked as deprecated and will be removed in 1.0.0:


Fixes

Updated deno version in CI after the upstream swc bug has been resolved.


Changes

  • feat(core): panic and error helpers by @realpha in #34
  • feat(lib): conditional passthrough renaming by @realpha in #36
  • chore(tools): updated deno version by @realpha in #37
  • feat(async): deprecate task operators by @realpha in #38

Full Changelog: 0.9.2...0.10.0

0.9.2

28 Jan 22:04
170768c
Compare
Choose a tag to compare

Features

  • Task.deferred(): This new static factory method allows for the creation of a deferred Task<T, E>. This may come in handy when working with push-based APIs such as EventTarget or when trying to emulate a timeout-behaviour, e.g:
class TimeoutError extends Error {}

const { task, succeed, fail } = Task.deferred<number, TimeoutError>();

const okTimerId = setTimeout(() => succeed(21), Math.random() * 1000);
const errTimerId = setTimeout(() => fail(new TimeoutError()), Math.randon() * 1000);
const timers = [ okTimerId, errTimerId ];

task
  .map((n) => n * 2)
  .inspect(console.log)
  .inspectErr(console.error)
  .finally(() => timers.forEach((id) => clearTimeout(id)) )

Fixes


Misc

  • As the implementation of Task.deferred() is not dependent upon the new Promise.withResolvers() method, this change is fully backwards compatible, also with regards to the minimum supported runtime versions.

Changes

  • feat(task): create deferred task by @realpha in #31
  • fix(ci): pin deno version in release workflow by @realpha in #32
  • feat(task): made deferred backwards compatible with version constraints by @realpha in #33

Full Changelog: 0.8.0...0.9.2

0.8.0

24 Jan 16:12
12e96fb
Compare
Choose a tag to compare

Features

By popular request: this is the first release shipping an adapter for commonly used Web APIs, namely fetch.

  • liftFetch().: Lifts fetch-like functions into a Task context. This comes with "sane" defaults for the construction of the possible error paths and is flexible enough to accomodate a variety of validation needs.
import { liftFetch } from "https://deno.land/x/[email protected]/mod.ts";

interface Company {
  name: string;
}

interface User {
  id: number;
  company: Company;
}

interface UserResponse extends Response {
  json(): Promise<User>
}

function fetchUserById(id: number): Promise<UserResponse> {
  return fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
}

const getUserById = liftFetch(fetchUserById);

const result: Company = await getUserById(1)
  .map((resp) => resp.json()) // inferred as User
  .inspect(console.log)
  .inspectErr(console.error) // FailedRequest<UserResponse> | FetchException
  .mapOr(user => user.company, { name: "Acme Corp." })
  .unwrap();

Full Changelog: 0.7.0...0.8.0