diff --git a/README.md b/README.md index ea6b374..1d32d02 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,12 @@ It makes the control flow similar to that of Golang, but doesn't force you to ma Instead of returning a nullish error, Grip always returns a consistent status object: ```javascript -const [value, status] = grip(callable) +const [value, status] = grip(callable) // or {value, status} + if (status.of(MySpecificError)) { // handle specific error } + if (status.fail()) { // handle any error } @@ -24,13 +26,15 @@ The call result is better than tuple: ```javascript const result = grip(callable) -if (result.fail()) { - // handle any error -} + if (result.of(MySpecificError)) { // handle specific error } +if (result.fail()) { + // handle any error +} + console.log(result.value) // result[0] ``` @@ -51,7 +55,7 @@ The result can be hadled as either an object or a tuple. import { grip } from '@nesterow/grip'; ``` -## Handle result as an object: +## Handle result as an object The result can be handled as an object: `{value, status, Ok(), Fail(), Of(type)}` @@ -60,7 +64,7 @@ const res = await grip( fetch('https://api.example.com') ); -if (res.Fail()) { +if (res.fail()) { // handle error return; } @@ -69,14 +73,14 @@ const json = await grip( res.value.json() ); -if (json.Of(SyntaxError)) { +if (json.of(SyntaxError)) { // handle parse error return; } ``` -## Handle result as a tuple: +## Handle result as a tuple The result can also be received as a tuple if you want to handle errors in Go'ish style: @@ -84,7 +88,7 @@ The result can also be received as a tuple if you want to handle errors in Go'is const [res, fetchStatus] = await grip( fetch('https://api.example.com') ); -if (fetchStatus.Fail()) { +if (fetchStatus.fail()) { // handle error return; } @@ -92,13 +96,13 @@ if (fetchStatus.Fail()) { const [json, parseStatus] = await grip( res.json() ); -if (parseStatus.Of(SyntaxError)) { +if (parseStatus.of(SyntaxError)) { // handle parse error return; } ``` -## Handle functions: +## Handle functions Grip can also handle functions: @@ -124,8 +128,8 @@ const res = grip(async function* () { yield i; } }); -for await (let [value, status] of res.Iter()) { - if (status.Of(Error)) { +for await (let [value, status] of res.iter()) { + if (status.of(Error)) { // handle error properly break; } diff --git a/dist/grip.js b/dist/grip.js index d9aa77f..293ec04 100644 --- a/dist/grip.js +++ b/dist/grip.js @@ -123,8 +123,12 @@ class Result extends Array { return this.Iter(); } } -var promise = (result) => { - return result.then((res) => new Result(res, new Ok)).catch((err) => new Result(null, Err.fromCatch(err))); +var promise = async (result) => { + try { + return new Result(await result, new Ok); + } catch (err) { + return new Result(null, Err.fromCatch(err)); + } }; var iterator = function* (iter) { try { diff --git a/grip.test.ts b/grip.test.ts index 04524ef..4bbb871 100644 --- a/grip.test.ts +++ b/grip.test.ts @@ -89,7 +89,7 @@ test("async function*", async () => { }); expect(res.Ok()).toBe(true); for await (let [value, status] of res.Iter()) { - if (status.Of(Error)) { + if (status.of(Error)) { break; } expect(value).toBeTypeOf("number"); diff --git a/grip.ts b/grip.ts index 28d5f5a..81ed875 100644 --- a/grip.ts +++ b/grip.ts @@ -2,13 +2,10 @@ interface Status { message?: string; cause?: any; Ok(): boolean; - /* alias Ok */ ok(): boolean; Fail(): boolean; - /* alias Fail */ fail(): boolean; Of(cls: any): boolean; - /* alias Of */ of(cls: any): boolean; } @@ -16,21 +13,18 @@ export class Err extends Error { Ok() { return false; } - /* alias Ok */ ok() { return this.Ok(); } Fail() { return true; } - /* alias Fail */ fail() { return this.Fail(); } Of(cls: any) { return this.cause instanceof cls || this instanceof cls; } - /* alias Of */ of(cls: any) { return this.Of(cls); } @@ -46,21 +40,18 @@ export class Ok { Ok() { return true; } - /* alias Ok */ ok() { return this.Ok(); } Fail() { return false; } - /* alias Fail */ fail() { return this.Fail(); } Of(cls: any) { return this instanceof cls; } - /* alias Of */ of(cls: any) { return this.Of(cls); } @@ -96,21 +87,18 @@ class Result extends Array implements IResult { Ok() { return (this[1] as Status).Ok(); } - /* alias Ok */ ok() { return this.Ok(); } Fail() { return (this[1] as Status).Fail(); } - /* alias Fail */ fail() { return this.Fail(); } Of(cls: any) { return (this[1] as Status).Of(cls); } - /* alias Of */ of(cls: any) { return this.Of(cls); } @@ -142,7 +130,6 @@ class Result extends Array implements IResult { }, }; } - /* alias Iter */ iter() { return this.Iter(); } @@ -168,7 +155,7 @@ export type SafeResult = ? Promise>> : Result>; -export function grip(action: T): SafeResult { +export function grip(action: T) { if (action instanceof Promise) { return promise(action) as SafeResult; } @@ -179,14 +166,19 @@ export function grip(action: T): SafeResult { } return new Result(result, new Ok()) as SafeResult; } catch (err: any) { - return new Result(null as any, Err.fromCatch(err)) as SafeResult; + return new Result( + null as never, + Err.fromCatch(err), + ) as SafeResult; } } -const promise = (result: Promise) => { - return result - .then((res) => new Result(res, new Ok())) - .catch((err) => new Result(null, Err.fromCatch(err))) as Promise>; +const promise = async (result: Promise) => { + try { + return new Result(await result, new Ok()); + } catch (err) { + return new Result(null as never, Err.fromCatch(err)); + } }; const iterator = function* (iter: Generator) { @@ -197,7 +189,7 @@ const iterator = function* (iter: Generator) { data = iter.next(); } } catch (e) { - yield new Result(null as T, Err.fromCatch(e)) as SafeResult; + yield new Result(null as never, Err.fromCatch(e)) as SafeResult; } }; @@ -209,6 +201,6 @@ const asyncIterator = async function* (iter: AsyncGenerator) { data = await iter.next(); } } catch (e) { - yield new Result(null as T, Err.fromCatch(e)) as SafeResult; + yield new Result(null as T, Err.fromCatch(e)) as SafeResult; } };