Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exclude_patterns:
- "**/*.spec.ts"
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) Patrick Michalina
Copyright (c) Patrick Michalina 2018

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
42 changes: 28 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 12 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"typings": "index.d.ts",
"sideEffects": false,
"author": "Patrick Michalina <patrickmichalina@mac.com> (https://patrickmichalina.com)",
"contributors": [
"Williama Reynolds"
],
"license": "MIT",
"repository": {
"type": "git",
Expand Down Expand Up @@ -35,27 +38,27 @@
},
"devDependencies": {
"@rollup/plugin-typescript": "^3.1.1",
"@types/fs-extra": "^8.1.0",
"@types/jest": "^25.2.1",
"@types/fs-extra": "^9.0.0",
"@types/jest": "^25.2.2",
"@types/node": "^14.0.1",
"codecov": "^3.6.5",
"fast-check": "^1.24.2",
"fs-extra": "^9.0.0",
"istanbul": "^0.4.5",
"jest": "26.0.1",
"jest-junit": "^10.0.0",
"rollup": "^2.10.0",
"rollup": "^2.10.2",
"rxjs": "^6.5.4",
"semantic-release": "^17.0.7",
"terser": "^4.6.13",
"ts-jest": "^25.5.1",
"ts-jest": "^26.0.0",
"ts-node": "^8.10.1",
"tslint": "^6.1.2",
"tslint-immutable": "^6.0.1",
"typescript": "^3.9.2"
},
"peerDependencies": {
"tslib": "^1.12.0",
"tslib": "^2.0.0",
"rxjs": "^6.5"
},
"jest": {
Expand All @@ -70,7 +73,7 @@
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 95,
"functions": 100,
"lines": 100,
"statements": 100
}
Expand All @@ -80,7 +83,8 @@
},
"testPathIgnorePatterns": [
"/node_modules/",
"/dist/"
"/dist/",
"public_api.ts"
],
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(ts?)$",
"moduleFileExtensions": [
Expand All @@ -92,4 +96,4 @@
"node"
]
}
}
}
22 changes: 11 additions & 11 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ export default [
]
},
{
input: 'src/index.ts',
output: [
{ file: `dist/${pkg.module}`, format: 'es', sourcemap: true },
{ file: `dist/${pkg.commonJs}`, format: 'cjs', sourcemap: true }
],
external: [
'rxjs',
'rxjs/operators'
],
plugins: [typescript()]
}]
input: 'src/index.ts',
output: [
{ file: `dist/${pkg.module}`, format: 'es', sourcemap: true },
{ file: `dist/${pkg.commonJs}`, format: 'cjs', sourcemap: true }
],
external: [
'rxjs',
'rxjs/operators'
],
plugins: [typescript()]
}]
5 changes: 5 additions & 0 deletions src/either/either.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Either } from './either'

export function either<L, R>(left?: L, right?: R) {
return new Either(left, right)
}
File renamed without changes.
2 changes: 1 addition & 1 deletion test/monads/either.spec.ts → src/either/either.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { either } from '../../src'
import { either } from './either.factory'

describe(either.name, () => {
it('when calling should throw if both sides are defined', () => {
Expand Down
56 changes: 56 additions & 0 deletions src/either/either.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { IEitherPattern, IEither } from './either.interface'

export class Either<L, R> implements IEither<L, R> {
constructor(private readonly left?: L, private readonly right?: R) {
if (this.neitherExist()) {
throw new TypeError('Either requires a left or a right')
}
if (this.bothExist()) {
throw new TypeError('Either cannot have both a left and a right')
}
}

private static exists<T>(value?: T): boolean {
return typeof value !== 'undefined' && value !== null
}

private bothExist(): boolean {
return this.isLeft() && this.isRight()
}

private neitherExist(): boolean {
return !this.isLeft() && !this.isRight()
}

public isLeft(): boolean {
return Either.exists(this.left)
}

public isRight(): boolean {
return Either.exists(this.right)
}

public match<T>(pattern: IEitherPattern<L, R, T>): T {
return this.isRight()
? pattern.right(this.right as R)
: pattern.left(this.left as L)
}

public tap<T>(pattern: Partial<IEitherPattern<L, R, T>>): void {
this.isRight()
? typeof pattern.right === 'function' && pattern.right(this.right as R)
: typeof pattern.left === 'function' && pattern.left(this.left as L)
}

public map<T>(fn: (r: R) => T): IEither<L, T> {
return this.isRight()
? new Either<L, T>(undefined, fn(this.right as R))
: new Either<L, T>(this.left)
}

public flatMap<T>(fn: (r: R) => IEither<L, T>): IEither<L, T> {
return this.isRight()
? fn(this.right as R)
: new Either<L, T>(this.left)
}
}
3 changes: 3 additions & 0 deletions src/either/public_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './either'
export * from './either.factory'
export * from './either.interface'
20 changes: 20 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { maybe, Maybe, either, Either, ok, fail, Result, reader, Reader } from './index'

describe('package api', () => {
it('should export maybe', () => {
expect(maybe(1)).toBeInstanceOf(Maybe)
})

it('should export either', () => {
expect(either(1)).toBeInstanceOf(Either)
})

it('should export result', () => {
expect(ok(1)).toBeInstanceOf(Result)
expect(fail(1)).toBeInstanceOf(Result)
})

it('should export reader', () => {
expect(reader(_cfg => 1)).toBeInstanceOf(Reader)
})
})
10 changes: 5 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './monads/index'
export * from './interfaces/index'
export {
maybeToObservable
} from './util/index'
export * from './maybe/public_api'
export * from './reader/public_api'
export * from './either/public_api'
export * from './result/public_api'
export * from './monad/public_api'
4 changes: 0 additions & 4 deletions src/interfaces/index.ts

This file was deleted.

7 changes: 0 additions & 7 deletions src/interfaces/monad.interface.ts

This file was deleted.

6 changes: 0 additions & 6 deletions src/interfaces/reader.interface.ts

This file was deleted.

Empty file removed src/interfaces/result.interface.ts
Empty file.
16 changes: 16 additions & 0 deletions src/maybe/maybe.factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { maybe, none, some } from './maybe.factory'

describe('should construct maybes', () => {
it('should handle "maybe" case', () => {
const sut = 'asdasd' as string | undefined
expect(maybe(sut).isSome()).toEqual(true)
})

it('should handle "none" case', () => {
expect(none().isNone()).toEqual(true)
})

it('should handle "some" case', () => {
expect(some('test').isSome()).toEqual(true)
})
})
13 changes: 13 additions & 0 deletions src/maybe/maybe.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Maybe } from './maybe'

export function maybe<T>(value?: T) {
return new Maybe<T>(value)
}

export function none<T>() {
return Maybe.none<T>()
}

export function some<T>(value: T) {
return maybe(value)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IMonad } from './monad.interface'
import { IMonad } from '../monad/monad.interface'

/**
* Define a contract to unwrap Maybe object
Expand All @@ -21,7 +21,7 @@ export interface IMaybePattern<TIn, TOut> {
export interface IMaybe<T> extends IMonad<T> {

// tslint:disable-next-line:readonly-array
of(x?: T, ...args: any[]): IMaybe<T>
of(x: T, ...args: any[]): IMaybe<T>

/**
* Unwrap a Maybe with a default value
Expand Down Expand Up @@ -96,7 +96,7 @@ export interface IMaybe<T> extends IMonad<T> {
/**
* Combine multiple Maybe, automatically wrapping predicate
*/
flatMapAuto<R>(f: (t: T) => R): IMaybe<NonNullable<R>>
flatMapAuto<R>(fn: (v: T) => R): IMaybe<NonNullable<R>>

/**
* Apply a predicate which if met, continues the Maybe chain,
Expand Down
Loading