neverpanic 1.0.0-beta.1 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +30 -48
- package/dist/index.js +38 -93
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,55 +5,37 @@ export type Result<T = unknown, E = unknown> = {
|
|
|
5
5
|
success: false;
|
|
6
6
|
error: E;
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
* const getUserResult = await getUser("some-user-id");
|
|
27
|
-
* if (!getUserResult.success) {
|
|
28
|
-
* console.error(getUserResult.error);
|
|
29
|
-
* } else {
|
|
30
|
-
* console.log(getUserResult.data);
|
|
31
|
-
* }
|
|
32
|
-
*/
|
|
33
|
-
declare function safeFn<T extends Result | Promise<Result>, A extends unknown[], E = null>(cb: (...args: A) => T, eh?: (e: unknown) => E): (...args: A) => T | Result<never, E>;
|
|
34
|
-
/**
|
|
35
|
-
* Run an unsafe function, handle any errors and return a Result.
|
|
36
|
-
*
|
|
37
|
-
* @param cb - The async function to call.
|
|
38
|
-
* @param [eh] - Optional fallback error handler.
|
|
39
|
-
* @returns The awaited return value of cb.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* const user = await n.fromUnsafe(() => db.findUser('some-user-id'), () => 'FAILED_T0_FIND_USER')
|
|
43
|
-
* if (!user.success) {
|
|
44
|
-
* console.error(user.error)
|
|
45
|
-
* } else {
|
|
46
|
-
* console.log(user.data)
|
|
47
|
-
* }
|
|
48
|
-
*/
|
|
49
|
-
declare function fromUnsafe<T, E = null, R = T extends Promise<unknown> ? Promise<Result<Awaited<T>, E>> : Result<T, E>>(cb: () => T, eh?: (err: unknown) => E): R;
|
|
8
|
+
export declare const createNeverpanic: <D = unknown, E = unknown>() => {
|
|
9
|
+
ok: <const T extends D>(data: T) => Result<T, never>;
|
|
10
|
+
err: <const T extends E>(error: T) => Result<never, T>;
|
|
11
|
+
safeFn: <T extends Result<D, E> | Promise<Result<D, E>>, A extends unknown[], EH extends Result<D, E>>(cb: (...args: A) => T, eh: (e: unknown) => EH) => ((...args: A) => T | EH);
|
|
12
|
+
fromUnsafe: <T extends D | Promise<D>, EH_1 extends Result<D, E>, R = T extends Promise<infer U> ? Promise<{
|
|
13
|
+
success: true;
|
|
14
|
+
data: U;
|
|
15
|
+
}> : {
|
|
16
|
+
success: true;
|
|
17
|
+
data: T;
|
|
18
|
+
}>(cb: () => T, eh: (err: unknown) => EH_1) => R | EH_1;
|
|
19
|
+
resultsToResult: <T extends Result<D, E>[], TD extends Extract<T[number], {
|
|
20
|
+
success: true;
|
|
21
|
+
}>, TE extends Extract<T[number], {
|
|
22
|
+
success: false;
|
|
23
|
+
}>>(results: T) => Result<TD[], TE[]>;
|
|
24
|
+
};
|
|
50
25
|
export declare const n: {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
26
|
+
ok: <const T extends unknown>(data: T) => Result<T, never>;
|
|
27
|
+
err: <const T extends unknown>(error: T) => Result<never, T>;
|
|
28
|
+
safeFn: <T extends Result<unknown, unknown> | Promise<Result<unknown, unknown>>, A extends unknown[], EH extends Result<unknown, unknown>>(cb: (...args: A) => T, eh: (e: unknown) => EH) => (...args: A) => T | EH;
|
|
29
|
+
fromUnsafe: <T extends unknown, EH extends Result<unknown, unknown>, R = T extends Promise<infer U> ? Promise<{
|
|
30
|
+
success: true;
|
|
31
|
+
data: U;
|
|
32
|
+
}> : {
|
|
33
|
+
success: true;
|
|
34
|
+
data: T;
|
|
35
|
+
}>(cb: () => T, eh: (err: unknown) => EH) => EH | R;
|
|
36
|
+
resultsToResult: <T extends Result<unknown, unknown>[], TD extends Extract<T[number], {
|
|
54
37
|
success: true;
|
|
55
|
-
}>,
|
|
38
|
+
}>, TE extends Extract<T[number], {
|
|
56
39
|
success: false;
|
|
57
|
-
}>>(results: T) => Result<
|
|
40
|
+
}>>(results: T) => Result<TD[], TE[]>;
|
|
58
41
|
};
|
|
59
|
-
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,108 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* const getUser = n.safeFn(
|
|
10
|
-
* async (id: string) => {
|
|
11
|
-
* const res = await fetch(`https://example.com/users/${id}`);
|
|
12
|
-
* if (!res.ok) return { success: false, error: "FAILED_TO_FETCH" };
|
|
13
|
-
*
|
|
14
|
-
* return { success: true, data: await res.json() };
|
|
15
|
-
* },
|
|
16
|
-
* () => "FAILED_TO_GET_USER"
|
|
17
|
-
* );
|
|
18
|
-
*
|
|
19
|
-
* const getUserResult = await getUser("some-user-id");
|
|
20
|
-
* if (!getUserResult.success) {
|
|
21
|
-
* console.error(getUserResult.error);
|
|
22
|
-
* } else {
|
|
23
|
-
* console.log(getUserResult.data);
|
|
24
|
-
* }
|
|
25
|
-
*/
|
|
26
|
-
function safeFn(cb, eh) {
|
|
27
|
-
const createErrorResult = (e) => ({
|
|
1
|
+
export const createNeverpanic = () => {
|
|
2
|
+
const ok = (data) => ({
|
|
3
|
+
success: true,
|
|
4
|
+
data,
|
|
5
|
+
});
|
|
6
|
+
const err = (error) => ({
|
|
28
7
|
success: false,
|
|
29
|
-
error
|
|
8
|
+
error,
|
|
30
9
|
});
|
|
31
|
-
|
|
10
|
+
const safeFn = (cb, eh) => (...args) => {
|
|
32
11
|
try {
|
|
33
12
|
const result = cb(...args);
|
|
34
13
|
if (result instanceof Promise)
|
|
35
|
-
return result.catch(
|
|
14
|
+
return result.catch(eh);
|
|
36
15
|
return result;
|
|
37
16
|
}
|
|
38
17
|
catch (e) {
|
|
39
|
-
return
|
|
18
|
+
return eh(e);
|
|
40
19
|
}
|
|
41
20
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
success
|
|
61
|
-
error: eh?.(e) ?? null,
|
|
62
|
-
});
|
|
63
|
-
const createSuccessResult = (data) => ({
|
|
64
|
-
success: true,
|
|
65
|
-
data,
|
|
66
|
-
});
|
|
67
|
-
try {
|
|
68
|
-
const result = cb();
|
|
69
|
-
if (result instanceof Promise)
|
|
70
|
-
return result
|
|
71
|
-
.then(createSuccessResult)
|
|
72
|
-
.catch(createErrorResult);
|
|
73
|
-
return createSuccessResult(result);
|
|
74
|
-
}
|
|
75
|
-
catch (e) {
|
|
76
|
-
return createErrorResult(e);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Convert a list of results into a single result.
|
|
81
|
-
*
|
|
82
|
-
* @param results - A list of Results.
|
|
83
|
-
* @returns A single result containing the data / errors of the input results.
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* const findUserResults = userIds.map((userId) =>
|
|
87
|
-
* n.fromUnsafe(
|
|
88
|
-
* () => db.findUser(userId),
|
|
89
|
-
* () => "FAILED_TO_FIND_USER" as const,
|
|
90
|
-
* ),
|
|
91
|
-
* );
|
|
92
|
-
*
|
|
93
|
-
* const result = n.resultsToResult(findUserResults)
|
|
94
|
-
*/
|
|
95
|
-
const resultsToResult = (results) => {
|
|
96
|
-
const errors = results.filter((result) => !result.success);
|
|
97
|
-
if (errors.length)
|
|
21
|
+
const fromUnsafe = (cb, eh) => {
|
|
22
|
+
try {
|
|
23
|
+
const result = cb();
|
|
24
|
+
if (result instanceof Promise)
|
|
25
|
+
return result.then(ok).catch(eh);
|
|
26
|
+
return ok(result);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
return eh(e);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const resultsToResult = (results) => {
|
|
33
|
+
const errors = results.filter((result) => !result.success);
|
|
34
|
+
if (errors.length)
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
error: errors,
|
|
38
|
+
};
|
|
39
|
+
const successes = results.filter((result) => result.success);
|
|
98
40
|
return {
|
|
99
|
-
success:
|
|
100
|
-
|
|
41
|
+
success: true,
|
|
42
|
+
data: successes,
|
|
101
43
|
};
|
|
102
|
-
|
|
44
|
+
};
|
|
103
45
|
return {
|
|
104
|
-
|
|
105
|
-
|
|
46
|
+
ok,
|
|
47
|
+
err,
|
|
48
|
+
safeFn,
|
|
49
|
+
fromUnsafe,
|
|
50
|
+
resultsToResult,
|
|
106
51
|
};
|
|
107
52
|
};
|
|
108
|
-
export const n =
|
|
53
|
+
export const n = createNeverpanic();
|