Aller au contenu principal

Interopérabilité Zygos

Zygos remplace deux bibliothèques par un seul package, plus léger. Que vous veniez de Neverthrow ou de fp-ts, il suffit de changer les imports — aucun changement de code requis.

TL;DR

BibliothèqueRemplacement ZygosCompatibilitéMigration
NeverthrowResult, ResultAsync100% compatible APIChangement d'import uniquement
fp-tsEither, Task, TaskEither100% compatible APIChangement d'import uniquement
En résumé

Changez vos imports. Votre code fonctionne tel quel. Zygos est 2.6x plus petit (~774 B vs ~1.96 kB) que Neverthrow, avec zéro type any.


Neverthrow — Result & ResultAsync

Zygos Result est une micro-implémentation du type Result de Neverthrow : 2.6x plus petit (~774 B vs ~1.96 kB), 100% compatible API, zéro type any.

// Avant
import { ok, err, Result, ResultAsync } from "neverthrow";

// Après
import { ok, err, Result } from "pithos/zygos/result/result";
import { ResultAsync } from "pithos/zygos/result/result-async";

Compatibilité API complète

Cliquez pour développer chaque catégorie :

Constructeurs Result (100%)2/2

ok(value), err(error)

import { ok, err, Result } from "pithos/zygos/result/result";

const success: Result<number, string> = ok(42);
const failure: Result<number, string> = err("Something went wrong");
Méthodes Result (100%)7/7

.isOk(), .isErr(), .map(), .mapErr(), .andThen(), .unwrapOr(), .match()

const result = ok(5)
.map(x => x * 2)
.mapErr(e => `Error: ${e}`)
.andThen(x => x > 0 ? ok(x) : err("negative"));

const value = result.unwrapOr(0);

const message = result.match(
value => `Success: ${value}`,
error => `Error: ${error}`
);
Méthodes statiques Result (100%)2/2

Result.fromThrowable(), Result.combine()

const safeParse = Result.fromThrowable(
JSON.parse,
(error) => `Parse error: ${error}`
);

const result = safeParse('{"valid": "json"}'); // Ok({valid: "json"})
const error = safeParse('invalid'); // Err("Parse error: ...")

const combined = Result.combine([ok(1), ok(2), ok(3)]); // Ok([1, 2, 3])
Constructeurs ResultAsync (100%)2/2

okAsync(), errAsync()

import { okAsync, errAsync, ResultAsync } from "pithos/zygos/result/result-async";

const asyncSuccess = okAsync(Promise.resolve(42));
const asyncError = errAsync("network error");
Méthodes ResultAsync (100%)7/7

.map(), .mapErr(), .andThen(), .unwrapOr(), .match(), .orElse(), .then()

const result = await okAsync(Promise.resolve(5))
.map(x => x * 2)
.andThen(x => okAsync(Promise.resolve(x.toString())));

const message = await result.match(
value => `Success: ${value}`,
error => `Error: ${error}`
);

const withFallback = await errAsync("error")
.orElse(() => okAsync("fallback"));
Méthodes statiques ResultAsync (100%)4/4

ResultAsync.fromPromise(), ResultAsync.fromSafePromise(), ResultAsync.fromThrowable(), ResultAsync.combine()

const result = ResultAsync.fromPromise(
fetch('/api/data'),
(error) => `Fetch failed: ${error}`
);

const safe = ResultAsync.fromSafePromise(Promise.resolve(42));

const safeFetch = ResultAsync.fromThrowable(
async (url: string) => {
const res = await fetch(url);
return res.json();
},
(error) => `Request failed: ${error}`
);

const combined = ResultAsync.combine([
okAsync(1),
okAsync(2),
okAsync(3)
]); // Ok([1, 2, 3])
safeTry (100%)1/1
safeTry()
import { safeTry, ok, err } from "pithos/zygos/result/result";

const result = safeTry(function* () {
yield err("validation failed");
return ok(42);
});

const direct = safeTry(() => ok(42));

fp-ts — Either, Task, TaskEither

Réimplémentations légères des monades fp-ts, 100% compatibles API. Mêmes fonctions, mêmes signatures, bundle plus petit.

// Avant
import * as E from "fp-ts/Either";
import * as T from "fp-ts/Task";
import * as TE from "fp-ts/TaskEither";

// Après
import * as E from "pithos/zygos/either";
import * as T from "pithos/zygos/task";
import * as TE from "pithos/zygos/task-either";

Fonctions supportées

ModuleFonctions
Eitherleft, right, isLeft, isRight, map, mapLeft, flatMap, fold, match, getOrElse, orElse, fromOption, fromNullable, tryCatch, Do, bind, bindTo, apS
Taskof, map, flatMap, ap
TaskEitherleft, right, tryCatch, fromEither, fromTask, fromOption, map, mapLeft, flatMap, chain, fold, match, getOrElse, orElse, swap

Exemple d'utilisation

import * as E from "pithos/zygos/either";
import * as TE from "pithos/zygos/task-either";
import { pipe } from "pithos/arkhe/function/pipe";

// Either — identique à fp-ts
const result = pipe(
E.right(5),
E.map(x => x * 2),
E.flatMap(x => E.right(x + 1))
);

// TaskEither — opérations async qui peuvent échouer
const fetchUser = pipe(
TE.tryCatch(
() => fetch("/api/user").then(r => r.json()),
() => "Erreur réseau"
),
TE.map(user => user.name)
);

Fonctionnalités exclusives Zygos

Au-delà de la compatibilité, Zygos ajoute des fonctionnalités que ni Neverthrow ni fp-ts ne proposent :

FonctionnalitéDescription
2.6x plus petit~774 B vs ~1.96 kB
Zéro type anyMeilleure sécurité des types avec unknown
Ponts Result ↔ fp-tsConversion entre Result et Either/Option
safeAsyncTryGestion d'erreurs async simplifiée
combineWithAllErrorsCollecter toutes les erreurs au lieu de s'arrêter à la première

Ponts Result ↔ fp-ts

Conversion entre Result et les types fp-ts :

import { fromOption, fromEither, toEither, ok, err } from "pithos/zygos/result/result";

// Option → Result
const fromSome = fromOption(() => "No value")({ _tag: "Some", value: 42 }); // Ok(42)
const fromNone = fromOption(() => "No value")({ _tag: "None" }); // Err("No value")

// Either → Result
const fromRight = fromEither({ _tag: "Right", right: 42 }); // Ok(42)
const fromLeft = fromEither({ _tag: "Left", left: "error" }); // Err("error")

// Result → Either
const toRight = toEither(ok(42)); // { _tag: "Right", right: 42 }
const toLeft = toEither(err("error")); // { _tag: "Left", left: "error" }

safeAsyncTry

Gestion d'erreurs async simplifiée sans générateurs :

import { safeAsyncTry } from "pithos/zygos/result/result";

const result = await safeAsyncTry(() => fetch("/api/user").then(r => r.json()));

if (result.isOk()) {
console.log(result.value);
} else {
console.log(result.error);
}

combineWithAllErrors

Collecter toutes les erreurs au lieu de s'arrêter à la première :

import { ResultAsync, okAsync, errAsync } from "pithos/zygos/result/result-async";

const combined = ResultAsync.combineWithAllErrors([
okAsync(1),
errAsync("error1"),
okAsync(3),
errAsync("error2")
]);

const resolved = await combined;
// Err(["error1", "error2"]) — collecte TOUTES les erreurs

Pourquoi choisir Zygos ?

AspectZygosNeverthrowfp-ts
Taille de bundle~774 B~1.96 kB~50 kB+
Sécurité des typesZéro type anyUtilise any à certains endroits
Result + Either Les deuxResult uniquementEither uniquement
Ponts Result ↔ Either/Option
MigrationChangement d'import uniquementChangement d'import uniquement
Recommandation

Que vous veniez de Neverthrow ou de fp-ts, passer à Zygos c'est la même chose : changez vos imports, gardez votre code. Vous obtenez un bundle plus petit, de meilleurs types, et les deux écosystèmes dans un seul package.

Prêt à migrer ? Le guide de migration complet étape par étape se trouve dans la documentation du module Zygos: installer, changer les imports et profiter des fonctionnalités supplémentaires. Aller au guide de migration →

Pas sûr de quelle bibliothèque correspond à votre cas d'usage ? Voir l'aperçu des comparaisons.


Related