@terrygonguet/utils 0.10.0 → 0.11.0
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 +2 -2
- package/dist/result.d.ts +21 -4
- package/dist/result.js +55 -8
- package/package.json +20 -13
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare function yesno(value?: string): boolean;
|
|
|
11
11
|
declare function mapListPush<Key, T>(map: Map<Key, T[]>, key: Key, value: T): Map<Key, T[]>;
|
|
12
12
|
declare function recordListPush<Key extends string, T>(record: Record<Key, T[]>, key: Key, value: T): Record<Key, T[]>;
|
|
13
13
|
type ExecResult<T, Err = Error> = [null, T] | [Err, null];
|
|
14
|
-
declare function tryCatch<F extends (...args: any) => any>(f: F, ...args: Parameters<F>): ReturnType<F> extends Promise<
|
|
15
|
-
declare function tryCatch<Err, F extends (...args: any) => any>(f: F, ...args: Parameters<F>): ReturnType<F> extends Promise<
|
|
14
|
+
declare function tryCatch<F extends (...args: any) => any>(f: F, ...args: Parameters<F>): ReturnType<F> extends Promise<infer T> ? Promise<ExecResult<T>> : ExecResult<ReturnType<F>>;
|
|
15
|
+
declare function tryCatch<Err, F extends (...args: any) => any>(f: F, ...args: Parameters<F>): ReturnType<F> extends Promise<infer T> ? Promise<ExecResult<T, Err>> : ExecResult<ReturnType<F>, Err>;
|
|
16
16
|
|
|
17
17
|
export { type ExecResult, clamp, createNoopProxy, exhaustive, hash, mapListPush, noop, range, recordListPush, tryCatch, yesno };
|
package/dist/result.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
|
|
1
3
|
declare class Result<Err extends Error, T> {
|
|
2
4
|
value: T | null;
|
|
3
5
|
error: Err | null;
|
|
4
|
-
constructor(value:
|
|
6
|
+
constructor(value: null, error: Err);
|
|
7
|
+
constructor(value: T, error: null);
|
|
5
8
|
asTuple(): [Err, null] | [null, T];
|
|
6
9
|
asObject(): {
|
|
7
10
|
value: null;
|
|
@@ -10,8 +13,10 @@ declare class Result<Err extends Error, T> {
|
|
|
10
13
|
value: T;
|
|
11
14
|
error: null;
|
|
12
15
|
};
|
|
13
|
-
andThen<Err2 extends Error, F extends (value: T) => any>(f: F): ReturnType<F> extends Promise<
|
|
14
|
-
|
|
16
|
+
andThen<Err2 extends Error, F extends (value: T) => any>(f: F): ReturnType<F> extends Promise<infer U> ? AsyncResult<Err | Err2, U> : Result<Err | Err2, ReturnType<F>>;
|
|
17
|
+
match(onValue: (value: T) => void): void;
|
|
18
|
+
match<U>(onValue: (value: T) => U, onError: (error: Err) => U): U;
|
|
19
|
+
recover<Err2 extends Error, F extends (error: Err) => T | Promise<T>>(f: F): ReturnType<F> extends Promise<T> ? AsyncResult<Err2, T> : Result<Err2, T>;
|
|
15
20
|
unwrap(): T;
|
|
16
21
|
unwrapErr(): Err;
|
|
17
22
|
}
|
|
@@ -28,6 +33,8 @@ declare class AsyncResult<Err extends Error, T> {
|
|
|
28
33
|
}>;
|
|
29
34
|
then<U>(cb: (value: Result<Err, T>) => U | Promise<U>): Promise<U>;
|
|
30
35
|
andThen<Err2 extends Error, F extends (value: T) => any>(f: F): AsyncResult<Err | Err2, Awaited<ReturnType<F>>>;
|
|
36
|
+
match(onValue: (value: T) => void): Promise<void>;
|
|
37
|
+
match<U>(onValue: (value: T) => U, onError: (error: Err) => U): Promise<U>;
|
|
31
38
|
recover<Err2 extends Error, F extends (error: Err) => T | Promise<T>>(f: F): AsyncResult<Err2, T>;
|
|
32
39
|
unwrap(): Promise<T>;
|
|
33
40
|
unwrapErr(): Promise<Err>;
|
|
@@ -35,5 +42,15 @@ declare class AsyncResult<Err extends Error, T> {
|
|
|
35
42
|
declare function safe<Err extends Error, T>(promise: Promise<T>): AsyncResult<Error, T>;
|
|
36
43
|
declare function safe<Err extends Error, F extends (...args: any) => Promise<any>>(f: F, ...args: Parameters<F>): AsyncResult<Err, Awaited<ReturnType<F>>>;
|
|
37
44
|
declare function safe<Err extends Error, F extends (...args: any) => any>(f: F, ...args: Parameters<F>): Result<Err, ReturnType<F>>;
|
|
45
|
+
declare class SafeFunctionValidationError extends Error {
|
|
46
|
+
name: string;
|
|
47
|
+
issues: StandardSchemaV1.FailureResult["issues"];
|
|
48
|
+
constructor(message: string, issues: StandardSchemaV1.FailureResult["issues"], options?: ErrorOptions);
|
|
49
|
+
}
|
|
50
|
+
interface MakeSafeFnOptions<ParamsSchema extends StandardSchemaV1 | undefined, ReturnSchema extends StandardSchemaV1 | undefined> {
|
|
51
|
+
paramsSchema?: ParamsSchema;
|
|
52
|
+
returnSchema?: ReturnSchema;
|
|
53
|
+
}
|
|
54
|
+
declare function makeSafeFn<Err extends Error, ParamsSchema extends StandardSchemaV1 | undefined, ReturnSchema extends StandardSchemaV1 | undefined, F extends (...args: ParamsSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<ParamsSchema> : any) => ReturnSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<ReturnSchema> : any>(f: F, options?: MakeSafeFnOptions<ParamsSchema, ReturnSchema>): (...args: Parameters<F>) => Result<Err, ReturnType<F>>;
|
|
38
55
|
|
|
39
|
-
export { safe };
|
|
56
|
+
export { AsyncResult, Result, SafeFunctionValidationError, makeSafeFn, safe };
|
package/dist/result.js
CHANGED
|
@@ -13,29 +13,31 @@ var Result = class _Result {
|
|
|
13
13
|
return { value: this.value, error: this.error };
|
|
14
14
|
}
|
|
15
15
|
andThen(f) {
|
|
16
|
-
if (this.error
|
|
16
|
+
if (this.error) return this;
|
|
17
17
|
try {
|
|
18
18
|
const newValue = f(this.value);
|
|
19
|
-
if (newValue instanceof Promise)
|
|
20
|
-
return new AsyncResult(newValue);
|
|
19
|
+
if (newValue instanceof Promise) return new AsyncResult(newValue);
|
|
21
20
|
else return new _Result(newValue, null);
|
|
22
21
|
} catch (error) {
|
|
23
22
|
return new _Result(null, RawError.wrap(error));
|
|
24
23
|
}
|
|
25
24
|
}
|
|
25
|
+
match(onValue, onError) {
|
|
26
|
+
if (this.error) return onError?.(this.error);
|
|
27
|
+
else return onError ? onValue(this.value) : void onValue(this.value);
|
|
28
|
+
}
|
|
26
29
|
recover(f) {
|
|
27
30
|
if (!this.error) return this;
|
|
28
31
|
try {
|
|
29
32
|
const newValue = f(this.error);
|
|
30
|
-
if (newValue instanceof Promise)
|
|
31
|
-
return new AsyncResult(newValue);
|
|
33
|
+
if (newValue instanceof Promise) return new AsyncResult(newValue);
|
|
32
34
|
else return new _Result(newValue, null);
|
|
33
35
|
} catch (error) {
|
|
34
36
|
return new _Result(null, RawError.wrap(error));
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
unwrap() {
|
|
38
|
-
if (
|
|
40
|
+
if (!this.error) return this.value;
|
|
39
41
|
else throw new Error("Tried to unwrap a failed Result");
|
|
40
42
|
}
|
|
41
43
|
unwrapErr() {
|
|
@@ -63,6 +65,12 @@ var AsyncResult = class _AsyncResult {
|
|
|
63
65
|
andThen(f) {
|
|
64
66
|
return new _AsyncResult(this.promise.then((value) => f(value)));
|
|
65
67
|
}
|
|
68
|
+
match(onValue, onError) {
|
|
69
|
+
return this.promise.then(
|
|
70
|
+
(value) => onError ? onValue(value) : void onValue(value),
|
|
71
|
+
(error) => onError?.(error)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
66
74
|
recover(f) {
|
|
67
75
|
return new _AsyncResult(
|
|
68
76
|
this.promise.then(
|
|
@@ -91,8 +99,7 @@ var RawError = class _RawError extends Error {
|
|
|
91
99
|
}
|
|
92
100
|
};
|
|
93
101
|
function safe(promiseOrFunction, ...args) {
|
|
94
|
-
if (promiseOrFunction instanceof Promise)
|
|
95
|
-
return new AsyncResult(promiseOrFunction);
|
|
102
|
+
if (promiseOrFunction instanceof Promise) return new AsyncResult(promiseOrFunction);
|
|
96
103
|
try {
|
|
97
104
|
const value = promiseOrFunction(...args);
|
|
98
105
|
if (value instanceof Promise) return new AsyncResult(value);
|
|
@@ -101,6 +108,46 @@ function safe(promiseOrFunction, ...args) {
|
|
|
101
108
|
return new Result(null, RawError.wrap(error));
|
|
102
109
|
}
|
|
103
110
|
}
|
|
111
|
+
var SafeFunctionValidationError = class extends Error {
|
|
112
|
+
name = "SafeFunctionValidationError";
|
|
113
|
+
issues;
|
|
114
|
+
constructor(message, issues, options) {
|
|
115
|
+
super(message, options);
|
|
116
|
+
this.issues = issues;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
function makeSafeFn(f, options) {
|
|
120
|
+
return function(...args) {
|
|
121
|
+
if (options?.paramsSchema) {
|
|
122
|
+
const parsed = options.paramsSchema["~standard"].validate(args);
|
|
123
|
+
if ("then" in parsed)
|
|
124
|
+
return new Result(
|
|
125
|
+
null,
|
|
126
|
+
new TypeError("[makeSafeFn] Parameters check failed: Async schemas are not supported")
|
|
127
|
+
);
|
|
128
|
+
else if (parsed.issues)
|
|
129
|
+
return new Result(
|
|
130
|
+
null,
|
|
131
|
+
new SafeFunctionValidationError("[makeSafeFn] Parameters check failed", parsed.issues)
|
|
132
|
+
);
|
|
133
|
+
else args = parsed.value;
|
|
134
|
+
}
|
|
135
|
+
if (options?.returnSchema)
|
|
136
|
+
return safe(f, ...args).andThen((returned) => {
|
|
137
|
+
const parsed = options.returnSchema["~standard"].validate(returned);
|
|
138
|
+
if ("then" in parsed)
|
|
139
|
+
throw new TypeError("[makeSafeFn] Return check failed: Async schemas are not supported");
|
|
140
|
+
else if (parsed.issues)
|
|
141
|
+
throw new SafeFunctionValidationError("[makeSafeFn] Return check failed", parsed.issues);
|
|
142
|
+
else return parsed.value;
|
|
143
|
+
});
|
|
144
|
+
else return safe(f, ...args);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
104
147
|
export {
|
|
148
|
+
AsyncResult,
|
|
149
|
+
Result,
|
|
150
|
+
SafeFunctionValidationError,
|
|
151
|
+
makeSafeFn,
|
|
105
152
|
safe
|
|
106
153
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@terrygonguet/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|
|
@@ -14,41 +14,48 @@
|
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
|
-
"import": "./dist/index.js"
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"default": "./dist/index.js"
|
|
18
19
|
},
|
|
19
20
|
"./async": {
|
|
20
21
|
"types": "./dist/async.d.ts",
|
|
21
|
-
"import": "./dist/async.js"
|
|
22
|
+
"import": "./dist/async.js",
|
|
23
|
+
"default": "./dist/async.js"
|
|
22
24
|
},
|
|
23
25
|
"./json": {
|
|
24
26
|
"types": "./dist/json.d.ts",
|
|
25
|
-
"import": "./dist/json.js"
|
|
27
|
+
"import": "./dist/json.js",
|
|
28
|
+
"default": "./dist/json.js"
|
|
26
29
|
},
|
|
27
30
|
"./option": {
|
|
28
31
|
"types": "./dist/option.d.ts",
|
|
29
|
-
"import": "./dist/option.js"
|
|
32
|
+
"import": "./dist/option.js",
|
|
33
|
+
"default": "./dist/option.js"
|
|
30
34
|
},
|
|
31
35
|
"./random": {
|
|
32
36
|
"types": "./dist/random.d.ts",
|
|
33
|
-
"import": "./dist/random.js"
|
|
37
|
+
"import": "./dist/random.js",
|
|
38
|
+
"default": "./dist/random.js"
|
|
34
39
|
},
|
|
35
40
|
"./result": {
|
|
36
41
|
"types": "./dist/result.d.ts",
|
|
37
|
-
"import": "./dist/result.js"
|
|
42
|
+
"import": "./dist/result.js",
|
|
43
|
+
"default": "./dist/result.js"
|
|
38
44
|
},
|
|
39
45
|
"./tableau": {
|
|
40
46
|
"types": "./dist/tableau.d.ts",
|
|
41
|
-
"import": "./dist/tableau.js"
|
|
47
|
+
"import": "./dist/tableau.js",
|
|
48
|
+
"default": "./dist/tableau.js"
|
|
42
49
|
}
|
|
43
50
|
},
|
|
44
51
|
"devDependencies": {
|
|
45
52
|
"@types/benchmark": "^2.1.5",
|
|
46
53
|
"benchmark": "^2.1.4",
|
|
47
|
-
"prettier": "^3.
|
|
48
|
-
"tsup": "^8.5.
|
|
54
|
+
"prettier": "^3.8.1",
|
|
55
|
+
"tsup": "^8.5.1",
|
|
49
56
|
"typescript": "^5.9.3",
|
|
50
|
-
"vite": "^
|
|
51
|
-
"vitest": "^4.0
|
|
57
|
+
"vite": "^8.0.0",
|
|
58
|
+
"vitest": "^4.1.0"
|
|
52
59
|
},
|
|
53
60
|
"author": {
|
|
54
61
|
"email": "terry@gonguet.com",
|
|
@@ -63,6 +70,6 @@
|
|
|
63
70
|
"url": "https://github.com/terrygonguet/utils/issues"
|
|
64
71
|
},
|
|
65
72
|
"dependencies": {
|
|
66
|
-
"@standard-schema/spec": "^1.
|
|
73
|
+
"@standard-schema/spec": "^1.1.0"
|
|
67
74
|
}
|
|
68
75
|
}
|