minor improvements

This commit is contained in:
Anton Nesterov 2024-10-18 00:51:30 +02:00
parent 635d2aea06
commit 61e63987d1
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
4 changed files with 37 additions and 37 deletions

View file

@ -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: Instead of returning a nullish error, Grip always returns a consistent status object:
```javascript ```javascript
const [value, status] = grip(callable) const [value, status] = grip(callable) // or {value, status}
if (status.of(MySpecificError)) { if (status.of(MySpecificError)) {
// handle specific error // handle specific error
} }
if (status.fail()) { if (status.fail()) {
// handle any error // handle any error
} }
@ -24,13 +26,15 @@ The call result is better than tuple:
```javascript ```javascript
const result = grip(callable) const result = grip(callable)
if (result.fail()) {
// handle any error
}
if (result.of(MySpecificError)) { if (result.of(MySpecificError)) {
// handle specific error // handle specific error
} }
if (result.fail()) {
// handle any error
}
console.log(result.value) // result[0] 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'; 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)}` 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') fetch('https://api.example.com')
); );
if (res.Fail()) { if (res.fail()) {
// handle error // handle error
return; return;
} }
@ -69,14 +73,14 @@ const json = await grip(
res.value.json() res.value.json()
); );
if (json.Of(SyntaxError)) { if (json.of(SyntaxError)) {
// handle parse error // handle parse error
return; 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: 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( const [res, fetchStatus] = await grip(
fetch('https://api.example.com') fetch('https://api.example.com')
); );
if (fetchStatus.Fail()) { if (fetchStatus.fail()) {
// handle error // handle error
return; return;
} }
@ -92,13 +96,13 @@ if (fetchStatus.Fail()) {
const [json, parseStatus] = await grip( const [json, parseStatus] = await grip(
res.json() res.json()
); );
if (parseStatus.Of(SyntaxError)) { if (parseStatus.of(SyntaxError)) {
// handle parse error // handle parse error
return; return;
} }
``` ```
## Handle functions: ## Handle functions
Grip can also handle functions: Grip can also handle functions:
@ -124,8 +128,8 @@ const res = grip(async function* () {
yield i; yield i;
} }
}); });
for await (let [value, status] of res.Iter()) { for await (let [value, status] of res.iter()) {
if (status.Of(Error)) { if (status.of(Error)) {
// handle error properly // handle error properly
break; break;
} }

8
dist/grip.js vendored
View file

@ -123,8 +123,12 @@ class Result extends Array {
return this.Iter(); return this.Iter();
} }
} }
var promise = (result) => { var promise = async (result) => {
return result.then((res) => new Result(res, new Ok)).catch((err) => new Result(null, Err.fromCatch(err))); try {
return new Result(await result, new Ok);
} catch (err) {
return new Result(null, Err.fromCatch(err));
}
}; };
var iterator = function* (iter) { var iterator = function* (iter) {
try { try {

View file

@ -89,7 +89,7 @@ test("async function*", async () => {
}); });
expect(res.Ok()).toBe(true); expect(res.Ok()).toBe(true);
for await (let [value, status] of res.Iter()) { for await (let [value, status] of res.Iter()) {
if (status.Of(Error)) { if (status.of(Error)) {
break; break;
} }
expect(value).toBeTypeOf("number"); expect(value).toBeTypeOf("number");

34
grip.ts
View file

@ -2,13 +2,10 @@ interface Status {
message?: string; message?: string;
cause?: any; cause?: any;
Ok(): boolean; Ok(): boolean;
/* alias Ok */
ok(): boolean; ok(): boolean;
Fail(): boolean; Fail(): boolean;
/* alias Fail */
fail(): boolean; fail(): boolean;
Of(cls: any): boolean; Of(cls: any): boolean;
/* alias Of */
of(cls: any): boolean; of(cls: any): boolean;
} }
@ -16,21 +13,18 @@ export class Err extends Error {
Ok() { Ok() {
return false; return false;
} }
/* alias Ok */
ok() { ok() {
return this.Ok(); return this.Ok();
} }
Fail() { Fail() {
return true; return true;
} }
/* alias Fail */
fail() { fail() {
return this.Fail(); return this.Fail();
} }
Of(cls: any) { Of(cls: any) {
return this.cause instanceof cls || this instanceof cls; return this.cause instanceof cls || this instanceof cls;
} }
/* alias Of */
of(cls: any) { of(cls: any) {
return this.Of(cls); return this.Of(cls);
} }
@ -46,21 +40,18 @@ export class Ok {
Ok() { Ok() {
return true; return true;
} }
/* alias Ok */
ok() { ok() {
return this.Ok(); return this.Ok();
} }
Fail() { Fail() {
return false; return false;
} }
/* alias Fail */
fail() { fail() {
return this.Fail(); return this.Fail();
} }
Of(cls: any) { Of(cls: any) {
return this instanceof cls; return this instanceof cls;
} }
/* alias Of */
of(cls: any) { of(cls: any) {
return this.Of(cls); return this.Of(cls);
} }
@ -96,21 +87,18 @@ class Result<T> extends Array<T | Status> implements IResult<T> {
Ok() { Ok() {
return (this[1] as Status).Ok(); return (this[1] as Status).Ok();
} }
/* alias Ok */
ok() { ok() {
return this.Ok(); return this.Ok();
} }
Fail() { Fail() {
return (this[1] as Status).Fail(); return (this[1] as Status).Fail();
} }
/* alias Fail */
fail() { fail() {
return this.Fail(); return this.Fail();
} }
Of(cls: any) { Of(cls: any) {
return (this[1] as Status).Of(cls); return (this[1] as Status).Of(cls);
} }
/* alias Of */
of(cls: any) { of(cls: any) {
return this.Of(cls); return this.Of(cls);
} }
@ -142,7 +130,6 @@ class Result<T> extends Array<T | Status> implements IResult<T> {
}, },
}; };
} }
/* alias Iter */
iter() { iter() {
return this.Iter(); return this.Iter();
} }
@ -168,7 +155,7 @@ export type SafeResult<T> =
? Promise<Result<Unwrap<T>>> ? Promise<Result<Unwrap<T>>>
: Result<Unwrap<T>>; : Result<Unwrap<T>>;
export function grip<T>(action: T): SafeResult<T> { export function grip<T>(action: T) {
if (action instanceof Promise) { if (action instanceof Promise) {
return promise<T>(action) as SafeResult<T>; return promise<T>(action) as SafeResult<T>;
} }
@ -179,14 +166,19 @@ export function grip<T>(action: T): SafeResult<T> {
} }
return new Result<T>(result, new Ok()) as SafeResult<T>; return new Result<T>(result, new Ok()) as SafeResult<T>;
} catch (err: any) { } catch (err: any) {
return new Result<T>(null as any, Err.fromCatch(err)) as SafeResult<T>; return new Result<T>(
null as never,
Err.fromCatch(err),
) as SafeResult<never>;
} }
} }
const promise = <T>(result: Promise<T>) => { const promise = async <T>(result: Promise<T>) => {
return result try {
.then((res) => new Result(res, new Ok())) return new Result(await result, new Ok());
.catch((err) => new Result(null, Err.fromCatch(err))) as Promise<Result<T>>; } catch (err) {
return new Result<never>(null as never, Err.fromCatch(err));
}
}; };
const iterator = function* <T>(iter: Generator) { const iterator = function* <T>(iter: Generator) {
@ -197,7 +189,7 @@ const iterator = function* <T>(iter: Generator) {
data = iter.next(); data = iter.next();
} }
} catch (e) { } catch (e) {
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>; yield new Result<T>(null as never, Err.fromCatch(e)) as SafeResult<never>;
} }
}; };
@ -209,6 +201,6 @@ const asyncIterator = async function* <T>(iter: AsyncGenerator) {
data = await iter.next(); data = await iter.next();
} }
} catch (e) { } catch (e) {
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>; yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<never>;
} }
}; };