neverpanic 0.0.2 → 0.0.4

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/README.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # neverpanic
2
2
 
3
- This is the next generation of error handling in JavaScript. How many times have you gotten out of bed, ready to get on with your day, only to find that you have 1243 Sentry alerts because you forgot to gracefuly handle an exception in your NodeJS backend. The truth is, these are not exceptions, these are panics. Panics not just in your code, but also to your mental health.
3
+ This is the next generation of error handling in JavaScript. How many times have
4
+ you gotten out of bed, ready to get on with your day, only to find that you have
5
+ 1243 Sentry alerts because you forgot to gracefuly handle an exception in your
6
+ NodeJS backend. The truth is, these are not exceptions, these are panics. Panics
7
+ not just in your code, but also to your mental health.
4
8
 
5
- Try neverpanic, and live a zen life.
9
+ Try neverpanic, and live a zen life.
10
+
11
+ ## Examples
12
+
13
+ ### safeFn
14
+
15
+ Create a safe function from an unsafe one:
16
+
17
+ - Ensures that only a `Result` can be returned
18
+ - Catches and returns any unexpected errors as a `Result`
19
+
20
+ ```ts
21
+ const getUser = n.safeFn(
22
+ async (id: string) => {
23
+ const res = await fetch(`https://example.com/users/${id}`);
24
+ if (!res.ok) return { success: false, error: "FAILED_TO_FETCH" };
25
+
26
+ return { success: true, data: await res.json() };
27
+ },
28
+ (err) => "FAILED_TO_GET_USER",
29
+ );
30
+
31
+ const getUserResult = await getUser("some-user-id");
32
+ if (!getUserResult.success) {
33
+ console.error(getUserResult.error);
34
+ } else {
35
+ console.log(getUserResult.data);
36
+ }
37
+ ```
38
+
39
+ ### fromUnsafe
40
+
41
+ Runs the provided callback function, catching any thrown errors and returning a
42
+ `Result`
43
+
44
+ ```ts
45
+ const user = await n.fromUnsafe(
46
+ () => db.findUser("some-user-id"),
47
+ (err) => "FAILED_T0_FIND_USER",
48
+ );
49
+ if (!user.success) {
50
+ console.error(user.error);
51
+ } else {
52
+ console.log(user.data);
53
+ }
54
+ ```
package/dist/index.d.ts CHANGED
@@ -1,13 +1,54 @@
1
- type Result<T, E = unknown> = {
1
+ export type Result<T = unknown, E = unknown> = {
2
2
  success: true;
3
3
  data: T;
4
4
  } | {
5
5
  success: false;
6
6
  error: E;
7
7
  };
8
- declare function safeReturn<T, E>(cb: () => Promise<Result<T, E>> | Result<T, E>): Promise<Result<T, E | null>>;
9
- declare function safeReturn<T, E, H>(cb: () => Promise<Result<T, E>> | Result<T, E>, eh: (err: unknown) => H): Promise<Result<T, E | H>>;
10
- export declare const o: {
11
- safeReturn: typeof safeReturn;
8
+ /**
9
+ * Create a safe function from an unsafe one.
10
+ *
11
+ * @param cb - The async function to wrap.
12
+ * @param [eh] - Optional fallback error handler.
13
+ * @returns A new function that returns a typesafe Result.
14
+ *
15
+ * @example
16
+ * const getUser = n.safeFn(
17
+ * async (id: string) => {
18
+ * const res = await fetch(`https://example.com/users/${id}`);
19
+ * if (!res.ok) return { success: false, error: "FAILED_TO_FETCH" };
20
+ *
21
+ * return { success: true, data: await res.json() };
22
+ * },
23
+ * () => "FAILED_TO_GET_USER"
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;
50
+ export declare const n: {
51
+ safeFn: typeof safeFn;
52
+ fromUnsafe: typeof fromUnsafe;
12
53
  };
13
54
  export {};
package/dist/index.js CHANGED
@@ -1,61 +1,77 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1
+ /**
2
+ * Create a safe function from an unsafe one.
3
+ *
4
+ * @param cb - The async function to wrap.
5
+ * @param [eh] - Optional fallback error handler.
6
+ * @returns A new function that returns a typesafe Result.
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) => ({
28
+ success: false,
29
+ error: eh?.(e) ?? null,
9
30
  });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.o = void 0;
40
- function safeReturn(cb, eh) {
41
- return __awaiter(this, void 0, void 0, function () {
42
- var e_1;
43
- var _a;
44
- return __generator(this, function (_b) {
45
- switch (_b.label) {
46
- case 0:
47
- _b.trys.push([0, 2, , 3]);
48
- return [4 /*yield*/, cb()];
49
- case 1: return [2 /*return*/, _b.sent()];
50
- case 2:
51
- e_1 = _b.sent();
52
- return [2 /*return*/, {
53
- success: false,
54
- error: (_a = eh === null || eh === void 0 ? void 0 : eh(e_1)) !== null && _a !== void 0 ? _a : null,
55
- }];
56
- case 3: return [2 /*return*/];
57
- }
58
- });
31
+ return (...args) => {
32
+ try {
33
+ const result = cb(...args);
34
+ if (result instanceof Promise)
35
+ return result.catch(createErrorResult);
36
+ return result;
37
+ }
38
+ catch (e) {
39
+ return createErrorResult(e);
40
+ }
41
+ };
42
+ }
43
+ /**
44
+ * Run an unsafe function, handle any errors and return a Result.
45
+ *
46
+ * @param cb - The async function to call.
47
+ * @param [eh] - Optional fallback error handler.
48
+ * @returns The awaited return value of cb.
49
+ *
50
+ * @example
51
+ * const user = await n.fromUnsafe(() => db.findUser('some-user-id'), () => 'FAILED_T0_FIND_USER')
52
+ * if (!user.success) {
53
+ * console.error(user.error)
54
+ * } else {
55
+ * console.log(user.data)
56
+ * }
57
+ */
58
+ function fromUnsafe(cb, eh) {
59
+ const createErrorResult = (e) => ({
60
+ success: false,
61
+ error: eh?.(e) ?? null,
62
+ });
63
+ const createSuccessResult = (data) => ({
64
+ success: true,
65
+ data,
59
66
  });
67
+ try {
68
+ const result = cb();
69
+ if (result instanceof Promise)
70
+ return result.then(createSuccessResult).catch(createErrorResult);
71
+ return createSuccessResult(result);
72
+ }
73
+ catch (e) {
74
+ return createErrorResult(e);
75
+ }
60
76
  }
61
- exports.o = { safeReturn: safeReturn };
77
+ export const n = { safeFn, fromUnsafe };
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "neverpanic",
3
3
  "module": "index.ts",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "type": "module",
6
+ "repository": {
7
+ "url": "https://github.com/bgrcs/neverpanic"
8
+ },
6
9
  "scripts": {
7
- "build": "tsc index.ts --outdir dist"
10
+ "build": "tsc",
11
+ "test": "bun test"
8
12
  },
9
13
  "files": ["dist"],
10
14
  "exports": {
@@ -14,6 +18,6 @@
14
18
  "@types/bun": "latest"
15
19
  },
16
20
  "peerDependencies": {
17
- "@typescript/native-preview": "latest"
21
+ "typescript": "5"
18
22
  }
19
23
  }