🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

@matechs/effect

Package Overview
Dependencies
Maintainers
2
Versions
153
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@matechs/effect - npm Package Compare versions

Comparing version

to
0.0.16

21

lib/index.d.ts

@@ -1,6 +0,6 @@

import * as F from "fluture";
import * as Ei from "fp-ts/lib/Either";
import * as Op from "fp-ts/lib/Option";
import * as W from "waveguide/lib/wave";
import * as EX from "waveguide/lib/exit";
import { Monad3E } from "./overload";
import { Cancel } from "fluture";
import { MonadThrow3 } from "fp-ts/lib/MonadThrow";

@@ -10,2 +10,3 @@ import { Bifunctor3 } from "fp-ts/lib/Bifunctor";

import { Option } from "fp-ts/lib/Option";
export { done, abort, raise } from "waveguide/lib/exit";
export declare const URI = "matechs/Effect";

@@ -15,3 +16,3 @@ export declare type URI = typeof URI;

export declare type NoErr = never;
export declare type Effect<R, E, A> = (r: R) => F.FutureInstance<E, A>;
export declare type Effect<R, E, A> = (r: R) => W.Wave<E, A>;
declare module "fp-ts/lib/HKT" {

@@ -34,9 +35,8 @@ interface URItoKind3<R, E, A> {

export declare function error(message: string): Error;
export declare function fromFuture<E, A>(f: F.FutureInstance<E, A>): Effect<NoEnv, E, A>;
export declare function fromFuture<E, A>(f: W.Wave<E, A>): Effect<NoEnv, E, A>;
export declare function right<A>(a: A): Effect<NoEnv, NoErr, A>;
export declare function left<E>(e: E): Effect<NoEnv, E, never>;
export declare function liftPromise<A, E>(f: () => Promise<A>): Effect<NoEnv, never, A>;
export declare function liftIO<A>(f: () => A): Effect<NoEnv, never, A>;
export declare function tryCatch<A, E>(f: () => Promise<A>, onLeft: (e: any) => E): Effect<NoEnv, E, A>;
export declare function tryCatchIO<A, E>(f: () => A, onLeft: (e: any) => E): Effect<NoEnv, E, A>;
export declare function syncTotal<A>(f: () => A): Effect<NoEnv, never, A>;
export declare function tryCatchIO<E, A>(f: () => A, onLeft: (e: any) => E): Effect<NoEnv, E, A>;
export declare function tryCatch<E, A>(f: () => Promise<A>, onLeft: (e: any) => E): Effect<NoEnv, E, A>;
export declare function chainLeft<R, E, E2, A, R2>(ma: Effect<R, E, A>, onLeft: (e: E) => Effect<R2, E2, A>): Effect<R & R2, E2, A>;

@@ -52,8 +52,7 @@ export declare function when(predicate: boolean): <R, E, A>(ma: Effect<R, E, A>) => Effect<R, E, Op.Option<A>>;

export declare function sequenceP<R, E, A>(n: number, ops: Array<Effect<R, E, A>>): Effect<R, E, Array<A>>;
export declare function run<E, A>(ma: Effect<NoEnv, E, A>): () => Promise<Ei.Either<E, A>>;
export declare function run<E, A>(ma: Effect<NoEnv, E, A>): () => Promise<EX.Exit<E, A>>;
export declare function promise<A>(ma: Effect<NoEnv, any, A>): Promise<A>;
export declare function bracket<R, E, A, B, E2>(acquire: Effect<R, E, A>, use: (a: A) => Effect<R, E2, B>, release: (a: A, e: Ei.Either<E | E2, B>) => Effect<R, E, void>): Effect<R, E | E2, B>;
export declare function fork<E, A>(res: (a: A) => void, rej: (e: E) => void): (op: Effect<NoEnv, E, A>) => Cancel;
export declare function bracket<R, E, A, B, E2>(acquire: Effect<R, E, A>, use: (a: A) => Effect<R, E2, B>, release: (a: A) => Effect<R, E, void>): Effect<R, E | E2, B>;
export declare function toTaskLike<R, E, A>(ma: Effect<R, E, A>): Effect<R, NoErr, Ei.Either<E, A>>;
export declare function fromTaskLike<R, E, A>(ma: Effect<R, never, Ei.Either<E, A>>): Effect<R, E, A>;
export declare function fromNullableM<R, E, A>(ma: Effect<R, E, A>): Effect<R, E, Option<A>>;

@@ -22,22 +22,29 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var F = __importStar(require("fluture"));
var Ei = __importStar(require("fp-ts/lib/Either"));
var Op = __importStar(require("fp-ts/lib/Option"));
var M = __importStar(require("deepmerge"));
var W = __importStar(require("waveguide/lib/wave"));
var Ar = __importStar(require("fp-ts/lib/Array"));
var S = __importStar(require("waveguide/lib/semaphore"));
var pipeable_1 = require("fp-ts/lib/pipeable");
var Option_1 = require("fp-ts/lib/Option");
var Do_1 = require("fp-ts-contrib/lib/Do");
var exit_1 = require("waveguide/lib/exit");
exports.done = exit_1.done;
exports.abort = exit_1.abort;
exports.raise = exit_1.raise;
exports.URI = "matechs/Effect";
exports.effectMonad = {
URI: exports.URI,
of: function (a) { return function (_) { return F.resolve(a); }; },
map: function (fa, f) { return function (r) { return F.map(f)(fa(r)); }; },
ap: function (fab, fa) { return function (r) { return F.ap(fa(r))(fab(r)); }; },
of: function (a) { return function (_) { return W.wave.of(a); }; },
map: function (fa, f) { return function (r) { return W.wave.map(fa(r), f); }; },
ap: function (fab, fa) { return function (r) { return W.wave.ap(fab(r), fa(r)); }; },
chain: function (fa, f) { return function (r) {
return F.chain(function (x) { return f(x)(r); })(fa(r));
return W.wave.chain(fa(r), function (x) { return f(x)(r); });
}; },
throwError: function (e) { return function (_) { return F.reject(e); }; },
bimap: function (fea, f, g) { return function (r) { return F.bimap(f)(g)(fea(r)); }; },
mapLeft: function (fea, f) { return function (r) { return F.mapRej(f)(fea(r)); }; }
throwError: function (e) { return function (_) { return W.raiseError(e); }; },
bimap: function (fea, f, g) { return function (r) { return W.bimap(fea(r), f, g); }; },
mapLeft: function (fea, f) { return function (r) { return W.mapError(fea(r), f); }; }
};
exports.concurrentEffectMonad = __assign(__assign({}, exports.effectMonad), { ap: function (fab, fa) { return function (r) { return F.ap(fa(r))(fab(r)); }; } });
exports.concurrentEffectMonad = __assign(__assign({}, exports.effectMonad), { ap: function (fab, fa) { return function (r) { return W.parWave.ap(fab(r), fa(r)); }; } });
exports.ap = (_a = pipeable_1.pipeable(exports.effectMonad), _a.ap), exports.apFirst = _a.apFirst, exports.apSecond = _a.apSecond, exports.chain = _a.chain, exports.chainFirst = _a.chainFirst, exports.flatten = _a.flatten, exports.map = _a.map, exports.bimap = _a.bimap, exports.filterOrElse = _a.filterOrElse, exports.fromEither = _a.fromEither, exports.fromOption = _a.fromOption, exports.fromPredicate = _a.fromPredicate, exports.mapLeft = _a.mapLeft;

@@ -60,25 +67,30 @@ exports.parAp = (_b = pipeable_1.pipeable(exports.concurrentEffectMonad), _b.ap), exports.parApFirst = _b.apFirst, exports.parApSecond = _b.apSecond;

function left(e) {
return function (_) { return F.reject(e); };
return function (_) { return W.raiseError(e); };
}
exports.left = left;
function liftPromise(f) {
return function (_) { return F.attemptP(f); };
function syncTotal(f) {
return function (_) { return W.sync(f); };
}
exports.liftPromise = liftPromise;
function liftIO(f) {
return function (_) { return F.encase(f)(exports.noEnv); };
exports.syncTotal = syncTotal;
function tryCatchIO(f, onLeft) {
return function (_) {
return W.async(function (op) {
try {
op(Ei.right(f()));
}
catch (e) {
op(Ei.left(onLeft(e)));
}
/* istanbul ignore next */
return function () { };
});
};
}
exports.liftIO = liftIO;
exports.tryCatchIO = tryCatchIO;
function tryCatch(f, onLeft) {
return function (_) { return F.mapRej(onLeft)(F.attemptP(f)); };
return function (_) { return W.mapError(W.fromPromise(f), onLeft); };
}
exports.tryCatch = tryCatch;
function tryCatchIO(f, onLeft) {
return function (_) { return F.mapRej(onLeft)(F.attempt(f)); };
}
exports.tryCatchIO = tryCatchIO;
function chainLeft(ma, onLeft) {
return function (r) {
return pipeable_1.pipe(ma(r), F.chainRej(function (e) { return onLeft(e)(r); }));
};
return function (r) { return W.chainError(ma(r), function (e) { return onLeft(e)(r); }); };
}

@@ -116,3 +128,3 @@ exports.chainLeft = chainLeft;

function access(f) {
return function (r) { return F.resolve(f(r)); };
return function (r) { return W.wave.of(f(r)); };
}

@@ -122,3 +134,11 @@ exports.access = access;

function sequenceP(n, ops) {
return function (r) { return F.parallel(n)(ops.map(function (op) { return op(r); })); };
return function (r) {
return Do_1.Do(W.wave)
.bind("sem", S.makeSemaphore(n))
.bindL("r", function (_a) {
var sem = _a.sem;
return Ar.array.traverse(W.parWave)(ops, function (op) { return sem.withPermit(op(r)); });
})
.return(function (s) { return s.r; });
};
}

@@ -128,7 +148,7 @@ exports.sequenceP = sequenceP;

function run(ma) {
return function () { return F.promise(toTaskLike(ma)(exports.noEnv)); };
return function () { return W.runToPromiseExit(ma(exports.noEnv)); };
}
exports.run = run;
function promise(ma) {
return F.promise(ma(exports.noEnv));
return W.runToPromise(ma(exports.noEnv));
}

@@ -140,3 +160,3 @@ exports.promise = promise;

return exports.effectMonad.chain(toTaskLike(use(a)), function (e) {
return exports.effectMonad.chain(release(a, e), function () {
return exports.effectMonad.chain(release(a), function () {
return Ei.isLeft(e) ? left(e.left) : right(e.right);

@@ -148,6 +168,2 @@ });

exports.bracket = bracket;
function fork(res, rej) {
return function (op) { return F.fork(rej)(res)(op(exports.noEnv)); };
}
exports.fork = fork;
/* Task-like converters, convert operations that can fail into non failing and vice versa */

@@ -154,0 +170,0 @@ function toTaskLike(ma) {

{
"name": "@matechs/effect",
"version": "0.0.15",
"version": "0.0.16",
"license": "MIT",

@@ -33,7 +33,7 @@ "private": false,

"deepmerge": "^4.2.2",
"fluture": "^12.0.1",
"fp-ts": "^2.1.2",
"fp-ts-contrib": "^0.1.6"
"fp-ts-contrib": "^0.1.6",
"waveguide": "^1.3.0"
},
"gitHead": "d95301604f8cb35e21abcd1d1312666a614e3a37"
"gitHead": "8112954e787f86ddff9c50932677ad66183ec7d4"
}

@@ -6,60 +6,12 @@ # Introduction

It aims to provide a strong fundational block to build typescript code in a more testable and standardized way.
It aims to provide a strong foundational block to build typescript code in a more testable and standardized way.
This library is composed at its core by the `@matechs/effect` package that exposes 2 effects
- `type Effect<R, E, A> = (r: R) => FutureInstance<E, A>`
- `type Effect<R, E, A> = (r: R) => Wave<E, A>`
The underlying `FutureInstance` is provided by `Fluture`.
The underlying `Wave` is provided by `Waveguide`.
You can think of this type as a computation that requires an environment `R` to run.
An important point to note in the implementation is the `src/overload.ts` file where we extend and define the new abstract types required to specialize `fp-ts` behaviour to respect the variance of `R` & `E`.
The key difference is expressed in:
```ts
export interface Chain3E<F extends URIS3> extends Apply3<F> {
readonly chain: <R, E, A, R2, E2, B>(
fa: Kind3<F, R, E, A>,
f: (a: A) => Kind3<F, R2, E2, B>
) => Kind3<F, R & R2, E | E2, B>;
}
export interface Monad3E<M extends URIS3> extends Applicative3<M>, Chain3E<M> {}
export interface PipeableChain3E<F extends URIS3> extends PipeableApply3E<F> {
readonly chain: <R, E, A, B>(
f: (a: A) => Kind3<F, R, E, B>
) => <R2, E2>(ma: Kind3<F, R2, E2, A>) => Kind3<F, R & R2, E | E2, B>;
readonly chainFirst: <R, E, A, B>(
f: (a: A) => Kind3<F, R, E, B>
) => <R2, E2>(ma: Kind3<F, R2, E2, A>) => Kind3<F, R & R2, E | E2, A>;
readonly flatten: <R, E, R2, E2, A>(
mma: Kind3<F, R, E, Kind3<F, R2, E2, A>>
) => Kind3<F, R & R2, E | E2, A>;
}
export interface PipeableApply3E<F extends URIS3> extends PipeableFunctor3<F> {
readonly ap: <R, E, A, R2, E2>(
fa: Kind3<F, R, E, A>
) => <B>(fab: Kind3<F, R2, E2, (a: A) => B>) => Kind3<F, R & R2, E | E2, B>;
readonly apFirst: <R, E, B>(
fb: Kind3<F, R, E, B>
) => <A, R2, E2>(fa: Kind3<F, R2, E2, A>) => Kind3<F, R & R2, E | E2, A>;
readonly apSecond: <R, E, B>(
fb: Kind3<F, R, E, B>
) => <A, R2, E2>(fa: Kind3<F, R2, E2, A>) => Kind3<F, R & R2, E | E2, B>;
}
export interface Apply3E<F extends URIS3> extends Functor3<F> {
readonly ap: <R, E, A, B, R2, E2>(
fab: Kind3<F, R, E, (a: A) => B>,
fa: Kind3<F, R2, E2, A>
) => Kind3<F, R & R2, E | E2, B>;
}
```
In addition to that the `fp-ts-contrib/lib/Do` module has similar overloads. This workaround is necessary because typescript's lack of variance annotation on generics.
The module exposes 2 instances of the typeclass `type EffectMonad<T extends URIS3> = Monad3E<T> & MonadThrow3<T> & Bifunctor3<T>`:

@@ -72,81 +24,29 @@

In addition to default implementations additional exposed functions are:
Interesting integrations and usage examples can be found in `packages/orm`, `packages/http`, `packages/rpc`, `packages/tracing`
```ts
/* utils */
export function error(message: string) {
return new Error(message);
}
## Details
/* lift functions */
For details about the additional types and overloads please refer to documentation in `packages/effect`
export function fromFuture<E, A>(f: F.FutureInstance<E, A>): Effect<NoEnv, E, A>
## Notes
export function right<A>(a: A): Effect<NoEnv, NoErr, A>
This package is a work in progress syntax and functions might change, feedback are welcome and contributions even more!
export function left<E>(e: E): Effect<NoEnv, E, never>
The primary difference with waveguide itself is in how we manage the `R` parameter and in the utilities that we provide around environment management. The focus on this library is making environmental effects easy while providing valuable integrations out of the box where `Waveguide` itself poses primary focus around the underlying `Wave<E, A>`
export function liftPromise<A, E>(f: () => Promise<A>): Effect<NoEnv, never, A>
## Ecosystem
export function liftIO<A>(f: () => A): Effect<NoEnv, never, A>
- `@matechs/tracing` : provides integration with opentracing-js
- `@matechs/http` : provides integration with axios
- `@matechs/orm` : provides integration with typeorm
- `@matechs/rpc` : no boilerplate rpc for your effects
- `@matechs/express` : provides integration with express
- `@matechs/graceful` : utility to handle graceful exit
export function tryCatch<A, E>(f: () => Promise<A>, onLeft: (e: any) => E)
## Thanks
export function tryCatchIO<A, E>(f: () => A, onLeft: (e: any) => E)
This library would have not been feasibly possible without the strong foundations of [fp-ts](https://github.com/gcanti/fp-ts) and [Waveguide](https://github.com/rzeigler/waveguide) & huge thanks to the Authors.
export function chainLeft<R, E, E2, A, R2>(ma: Effect<R, E, A>,onLeft: (e: E) => Effect<R2, E2, A>)
/* conditionals */
// run only when predicate is true, return in Option
export function when(predicate: boolean): <R, E, A>(ma: Effect<R, E, A>) => Effect<R, E, Op.Option<A>>
// same as alt but types are different so we return in Either
export function or(predicate: boolean): <R, E, A>(ma: Effect<R, E, A>) => <R2, E2, B>(mb: Effect<R2, E2, B>) => Effect<R & R2, E | E2, Ei.Either<A, B>>
// decide what to run depending on a boolean, both side returns same type
export function alt(predicate: boolean): <R, E, A>(ma: Effect<R, E, A>) => (mb: Effect<R, E, A>) => Effect<R, E, A>
/* manipulate environment */
export const noEnv = {}; // unit
export function mergeEnv<A, B>(a: A): (b: B) => A & B // merge 2 environments
export const provide = <R>(r: R) => <R2, E, A>(ma: Effect<R2 & R, E, A>): Effect<R2, E, A> // provide environment to an effect
/* use environment */
export function accessM<R, R2, E, A>(f: (r: R) => Effect<R2, E, A>): Effect<R & R2, E, A>
export function access<R, A>(f: (r: R) => A): Effect<R, NoErr, A>
/* parallel */
export function sequenceP<R, E, A>(n: number, ops: Array<Effect<R, E, A>>): Effect<R, E, Array<A>>
/* execution */
/* run an effect that requires no environment, return TaskEither */
function run<E, A>(ma: Effect<NoEnv, E, A>): () => Promise<Ei.Either<E, A>>
/* run an effect that requires no environment, return Promise(reject on error) */
promise<A>(ma: Effect<NoEnv, any, A>): Promise<A>
/* run an effect that requires no environment, return underlying Fluture fork */
fork<A, E>(res: (a: A) => void, rej: (e: E) => void): (ma: Effect<NoEnv, E, A>) => Cancel
```
Interesting integrations and usage examples can be found in `packages/orm`, `packages/http`, `packages/rpc`, `packages/tracing`
## Notes
This package is a work in progress syntax and functions might change, feedback are welcome and contributions even more!
## Thanks
This library would have not been feasibly possible without the strong fundations of [fp-ts](https://github.com/gcanti/fp-ts) and [Fluture](https://github.com/fluture-js/Fluture) huge thanks to the Authors.
Another huge thanks goes to both the scala community (ZIO in specific) and the haskell community (RIO & Polysemy) from which inspiration is taken.
All of the above projects are advised!
All of the above projects are advised!

Sorry, the diff of this file is not supported yet