clutchit 0.0.3
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/CHANGELOG.md +6 -0
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/dist/circuit/circuit-breaker.d.ts +47 -0
- package/dist/circuit/circuit-breaker.js +114 -0
- package/dist/circuit/index.d.ts +7 -0
- package/dist/circuit/index.js +7 -0
- package/dist/concurrency/bulkhead.d.ts +27 -0
- package/dist/concurrency/bulkhead.js +62 -0
- package/dist/concurrency/index.d.ts +16 -0
- package/dist/concurrency/index.js +13 -0
- package/dist/concurrency/rate-limiter.d.ts +25 -0
- package/dist/concurrency/rate-limiter.js +40 -0
- package/dist/concurrency/ref.d.ts +11 -0
- package/dist/concurrency/ref.js +26 -0
- package/dist/concurrency/semaphore.d.ts +15 -0
- package/dist/concurrency/semaphore.js +48 -0
- package/dist/queue/base.queue.d.ts +18 -0
- package/dist/queue/base.queue.js +66 -0
- package/dist/queue/bounded.queue.d.ts +11 -0
- package/dist/queue/bounded.queue.js +64 -0
- package/dist/queue/dropping.queue.d.ts +7 -0
- package/dist/queue/dropping.queue.js +20 -0
- package/dist/queue/faults.d.ts +20 -0
- package/dist/queue/faults.js +17 -0
- package/dist/queue/index.d.ts +11 -0
- package/dist/queue/index.js +11 -0
- package/dist/queue/sliding.queue.d.ts +7 -0
- package/dist/queue/sliding.queue.js +19 -0
- package/dist/retry/index.d.ts +6 -0
- package/dist/retry/index.js +7 -0
- package/dist/retry/retry.d.ts +21 -0
- package/dist/retry/retry.js +58 -0
- package/dist/schedule/index.d.ts +30 -0
- package/dist/schedule/index.js +29 -0
- package/dist/schedule/operators.d.ts +22 -0
- package/dist/schedule/operators.js +106 -0
- package/dist/schedule/runner.d.ts +30 -0
- package/dist/schedule/runner.js +57 -0
- package/dist/schedule/schedule.d.ts +31 -0
- package/dist/schedule/schedule.js +94 -0
- package/dist/timeout/index.d.ts +16 -0
- package/dist/timeout/index.js +9 -0
- package/dist/timeout/timeout.d.ts +14 -0
- package/dist/timeout/timeout.js +37 -0
- package/dist/unthrow/do.d.ts +5 -0
- package/dist/unthrow/do.js +23 -0
- package/dist/unthrow/fault.d.ts +37 -0
- package/dist/unthrow/fault.js +22 -0
- package/dist/unthrow/helpers.d.ts +9 -0
- package/dist/unthrow/helpers.js +56 -0
- package/dist/unthrow/index.d.ts +32 -0
- package/dist/unthrow/index.js +55 -0
- package/dist/unthrow/result.async.d.ts +19 -0
- package/dist/unthrow/result.async.js +63 -0
- package/dist/unthrow/result.d.ts +38 -0
- package/dist/unthrow/result.js +80 -0
- package/package.json +109 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Fault, ResultAsync } from '../unthrow/index.js';
|
|
2
|
+
export const TimeoutFault = Fault.define({
|
|
3
|
+
code: 'TIMEOUT',
|
|
4
|
+
category: 'infrastructure',
|
|
5
|
+
transient: true,
|
|
6
|
+
create: (duration) => ({
|
|
7
|
+
message: `Operation timed out after ${duration}ms`,
|
|
8
|
+
duration,
|
|
9
|
+
}),
|
|
10
|
+
});
|
|
11
|
+
export function withTimeout(fn, duration) {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
return ResultAsync.fromPromise(
|
|
14
|
+
/* eslint-disable @typescript-eslint/prefer-promise-reject-errors -- intentional: rejections are typed E | TimeoutFault, caught by fromPromise */
|
|
15
|
+
new Promise((resolve, reject) => {
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
controller.abort();
|
|
18
|
+
reject(TimeoutFault(duration));
|
|
19
|
+
}, duration);
|
|
20
|
+
void fn(controller.signal).then((result) => {
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
if (result.isOk())
|
|
23
|
+
resolve(result.value);
|
|
24
|
+
else
|
|
25
|
+
reject(result.error);
|
|
26
|
+
}, (error) => {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
reject(error);
|
|
29
|
+
});
|
|
30
|
+
}),
|
|
31
|
+
/* eslint-enable @typescript-eslint/prefer-promise-reject-errors */
|
|
32
|
+
(e) => e);
|
|
33
|
+
}
|
|
34
|
+
export function createTimeout(duration) {
|
|
35
|
+
return (fn) => withTimeout(fn, duration);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=timeout.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Result, Err } from './result.js';
|
|
2
|
+
import { ResultAsync } from './result.async.js';
|
|
3
|
+
export declare function Do<T, E>(generator: () => Generator<Err<never, E>, T>): Result<T, E>;
|
|
4
|
+
export declare function DoAsync<T, E>(generator: () => AsyncGenerator<Err<never, E>, T>): ResultAsync<T, E>;
|
|
5
|
+
//# sourceMappingURL=do.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ok } from './result.js';
|
|
2
|
+
import { ResultAsync } from './result.async.js';
|
|
3
|
+
export function Do(generator) {
|
|
4
|
+
const gen = generator();
|
|
5
|
+
const next = gen.next();
|
|
6
|
+
while (!next.done) {
|
|
7
|
+
// Each yielded value is an Err — short-circuit
|
|
8
|
+
return next.value;
|
|
9
|
+
}
|
|
10
|
+
return ok(next.value);
|
|
11
|
+
}
|
|
12
|
+
export function DoAsync(generator) {
|
|
13
|
+
return new ResultAsync((async () => {
|
|
14
|
+
const gen = generator();
|
|
15
|
+
const next = await gen.next();
|
|
16
|
+
while (!next.done) {
|
|
17
|
+
// Each yielded value is an Err — short-circuit
|
|
18
|
+
return next.value;
|
|
19
|
+
}
|
|
20
|
+
return ok(next.value);
|
|
21
|
+
})());
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=do.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface Fault {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly message: string;
|
|
4
|
+
readonly _category: 'domain' | 'infrastructure';
|
|
5
|
+
readonly _transient: boolean;
|
|
6
|
+
}
|
|
7
|
+
export type DomainFault = Fault & {
|
|
8
|
+
readonly _category: 'domain';
|
|
9
|
+
readonly _transient: false;
|
|
10
|
+
};
|
|
11
|
+
export type InfrastructureFault = Fault & {
|
|
12
|
+
readonly _category: 'infrastructure';
|
|
13
|
+
};
|
|
14
|
+
export type TransientFault = InfrastructureFault & {
|
|
15
|
+
readonly _transient: true;
|
|
16
|
+
};
|
|
17
|
+
export declare function isTransient(error: Fault): error is TransientFault;
|
|
18
|
+
export declare function isDomainFault(error: Fault): error is DomainFault;
|
|
19
|
+
export declare function isInfrastructureFault(error: Fault): error is InfrastructureFault;
|
|
20
|
+
type InferTransient<O> = O extends {
|
|
21
|
+
transient: infer T extends boolean;
|
|
22
|
+
} ? T : false;
|
|
23
|
+
export declare function defineFault<const O extends {
|
|
24
|
+
code: string;
|
|
25
|
+
category: 'domain' | 'infrastructure';
|
|
26
|
+
transient?: boolean;
|
|
27
|
+
create: (...args: any[]) => {
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
}>(options: O): (...args: Parameters<O['create']>) => Readonly<{
|
|
31
|
+
code: O['code'];
|
|
32
|
+
_category: O['category'];
|
|
33
|
+
_transient: InferTransient<O>;
|
|
34
|
+
message: string;
|
|
35
|
+
} & Omit<ReturnType<O['create']>, 'message'>>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=fault.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function isTransient(error) {
|
|
2
|
+
return error._transient && error._category === 'infrastructure';
|
|
3
|
+
}
|
|
4
|
+
export function isDomainFault(error) {
|
|
5
|
+
return error._category === 'domain';
|
|
6
|
+
}
|
|
7
|
+
export function isInfrastructureFault(error) {
|
|
8
|
+
return error._category === 'infrastructure';
|
|
9
|
+
}
|
|
10
|
+
export function defineFault(options) {
|
|
11
|
+
const transient = (options.transient ?? false);
|
|
12
|
+
return (...args) => {
|
|
13
|
+
const extra = options.create(...args);
|
|
14
|
+
return Object.freeze({
|
|
15
|
+
code: options.code,
|
|
16
|
+
_category: options.category,
|
|
17
|
+
_transient: transient,
|
|
18
|
+
...extra,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fault.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Result } from './result.js';
|
|
2
|
+
import { ResultAsync } from './result.async.js';
|
|
3
|
+
export declare function combine<T, E>(results: Result<T, E>[]): Result<T[], E>;
|
|
4
|
+
export declare function combine<T, E>(results: ResultAsync<T, E>[]): ResultAsync<T[], E>;
|
|
5
|
+
export declare function combineWithAllErrors<T, E>(results: Result<T, E>[]): Result<T[], E[]>;
|
|
6
|
+
export declare function combineWithAllErrors<T, E>(results: ResultAsync<T, E>[]): ResultAsync<T[], E[]>;
|
|
7
|
+
export declare function fromPromise<T, E>(promise: Promise<T>, errorMapper: (error: unknown) => E): ResultAsync<T, E>;
|
|
8
|
+
export declare function fromThrowable<T, E>(fn: () => T, errorMapper: (error: unknown) => E): Result<T, E>;
|
|
9
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ok, err } from './result.js';
|
|
2
|
+
import { ResultAsync } from './result.async.js';
|
|
3
|
+
export function combine(results) {
|
|
4
|
+
if (results.length === 0) {
|
|
5
|
+
return ok([]);
|
|
6
|
+
}
|
|
7
|
+
if (results[0] instanceof ResultAsync) {
|
|
8
|
+
const asyncResults = results;
|
|
9
|
+
return new ResultAsync(Promise.all(asyncResults.map((r) => r.then((v) => v))).then((settled) => combineSync(settled)));
|
|
10
|
+
}
|
|
11
|
+
return combineSync(results);
|
|
12
|
+
}
|
|
13
|
+
function combineSync(results) {
|
|
14
|
+
const values = [];
|
|
15
|
+
for (const result of results) {
|
|
16
|
+
if (result.isErr())
|
|
17
|
+
return err(result.error);
|
|
18
|
+
values.push(result.value);
|
|
19
|
+
}
|
|
20
|
+
return ok(values);
|
|
21
|
+
}
|
|
22
|
+
export function combineWithAllErrors(results) {
|
|
23
|
+
if (results.length === 0) {
|
|
24
|
+
return ok([]);
|
|
25
|
+
}
|
|
26
|
+
if (results[0] instanceof ResultAsync) {
|
|
27
|
+
const asyncResults = results;
|
|
28
|
+
return new ResultAsync(Promise.all(asyncResults.map((r) => r.then((v) => v))).then((settled) => combineWithAllErrorsSync(settled)));
|
|
29
|
+
}
|
|
30
|
+
return combineWithAllErrorsSync(results);
|
|
31
|
+
}
|
|
32
|
+
function combineWithAllErrorsSync(results) {
|
|
33
|
+
const values = [];
|
|
34
|
+
const errors = [];
|
|
35
|
+
for (const result of results) {
|
|
36
|
+
if (result.isErr()) {
|
|
37
|
+
errors.push(result.error);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
values.push(result.value);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return errors.length > 0 ? err(errors) : ok(values);
|
|
44
|
+
}
|
|
45
|
+
export function fromPromise(promise, errorMapper) {
|
|
46
|
+
return new ResultAsync(promise.then((value) => ok(value), (error) => err(errorMapper(error))));
|
|
47
|
+
}
|
|
48
|
+
export function fromThrowable(fn, errorMapper) {
|
|
49
|
+
try {
|
|
50
|
+
return ok(fn());
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return err(errorMapper(error));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResultAsync as ResultAsyncClass, okAsync, errAsync } from './result.async.js';
|
|
2
|
+
import { DoAsync } from './do.js';
|
|
3
|
+
import { defineFault, isDomainFault, isInfrastructureFault } from './fault.js';
|
|
4
|
+
export { Ok, Err } from './result.js';
|
|
5
|
+
export type { DomainFault, InfrastructureFault, TransientFault, } from './fault.js';
|
|
6
|
+
export type Result<T, E> = import('./result.js').Ok<T, E> | import('./result.js').Err<T, E>;
|
|
7
|
+
type _Result<T, E> = Result<T, E>;
|
|
8
|
+
export declare namespace Result {
|
|
9
|
+
const ok: typeof import("./result.js").ok;
|
|
10
|
+
const err: typeof import("./result.js").err;
|
|
11
|
+
const fromThrowable: typeof import("./helpers.js").fromThrowable;
|
|
12
|
+
function combine<T, E>(results: _Result<T, E>[]): _Result<T[], E>;
|
|
13
|
+
function combineWithAllErrors<T, E>(results: _Result<T, E>[]): _Result<T[], E[]>;
|
|
14
|
+
const Do: typeof import("./do.js").Do;
|
|
15
|
+
}
|
|
16
|
+
export type ResultAsync<T, E> = ResultAsyncClass<T, E>;
|
|
17
|
+
export declare namespace ResultAsync {
|
|
18
|
+
const ok: typeof okAsync;
|
|
19
|
+
const err: typeof errAsync;
|
|
20
|
+
const fromPromise: typeof import("./helpers.js").fromPromise;
|
|
21
|
+
function combine<T, E>(results: ResultAsyncClass<T, E>[]): ResultAsyncClass<T[], E>;
|
|
22
|
+
function combineWithAllErrors<T, E>(results: ResultAsyncClass<T, E>[]): ResultAsyncClass<T[], E[]>;
|
|
23
|
+
const Do: typeof DoAsync;
|
|
24
|
+
}
|
|
25
|
+
export type Fault = import('./fault.js').Fault;
|
|
26
|
+
export declare namespace Fault {
|
|
27
|
+
const define: typeof defineFault;
|
|
28
|
+
const isTransient: typeof import("./fault.js").isTransient;
|
|
29
|
+
const isDomain: typeof isDomainFault;
|
|
30
|
+
const isInfrastructure: typeof isInfrastructureFault;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ok, err } from './result.js';
|
|
2
|
+
import { okAsync, errAsync, } from './result.async.js';
|
|
3
|
+
import { fromPromise, fromThrowable, combine as combineFn, combineWithAllErrors as combineWithAllErrorsFn, } from './helpers.js';
|
|
4
|
+
import { Do, DoAsync } from './do.js';
|
|
5
|
+
import { defineFault, isTransient, isDomainFault, isInfrastructureFault, } from './fault.js';
|
|
6
|
+
// Re-export instance types (needed in user signatures)
|
|
7
|
+
export { Ok, Err } from './result.js';
|
|
8
|
+
// Internal aliases (must precede namespaces that reference them)
|
|
9
|
+
const _ok = ok;
|
|
10
|
+
const _err = err;
|
|
11
|
+
const _fromThrowable = fromThrowable;
|
|
12
|
+
const _fromPromise = fromPromise;
|
|
13
|
+
const _isTransient = isTransient;
|
|
14
|
+
const _Do = Do;
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
16
|
+
export var Result;
|
|
17
|
+
(function (Result) {
|
|
18
|
+
Result.ok = _ok;
|
|
19
|
+
Result.err = _err;
|
|
20
|
+
Result.fromThrowable = _fromThrowable;
|
|
21
|
+
function combine(results) {
|
|
22
|
+
return combineFn(results);
|
|
23
|
+
}
|
|
24
|
+
Result.combine = combine;
|
|
25
|
+
function combineWithAllErrors(results) {
|
|
26
|
+
return combineWithAllErrorsFn(results);
|
|
27
|
+
}
|
|
28
|
+
Result.combineWithAllErrors = combineWithAllErrors;
|
|
29
|
+
Result.Do = _Do;
|
|
30
|
+
})(Result || (Result = {}));
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
32
|
+
export var ResultAsync;
|
|
33
|
+
(function (ResultAsync) {
|
|
34
|
+
ResultAsync.ok = okAsync;
|
|
35
|
+
ResultAsync.err = errAsync;
|
|
36
|
+
ResultAsync.fromPromise = _fromPromise;
|
|
37
|
+
function combine(results) {
|
|
38
|
+
return combineFn(results);
|
|
39
|
+
}
|
|
40
|
+
ResultAsync.combine = combine;
|
|
41
|
+
function combineWithAllErrors(results) {
|
|
42
|
+
return combineWithAllErrorsFn(results);
|
|
43
|
+
}
|
|
44
|
+
ResultAsync.combineWithAllErrors = combineWithAllErrors;
|
|
45
|
+
ResultAsync.Do = DoAsync;
|
|
46
|
+
})(ResultAsync || (ResultAsync = {}));
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
48
|
+
export var Fault;
|
|
49
|
+
(function (Fault) {
|
|
50
|
+
Fault.define = defineFault;
|
|
51
|
+
Fault.isTransient = _isTransient;
|
|
52
|
+
Fault.isDomain = isDomainFault;
|
|
53
|
+
Fault.isInfrastructure = isInfrastructureFault;
|
|
54
|
+
})(Fault || (Fault = {}));
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Result, Err } from './result.js';
|
|
2
|
+
export declare class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {
|
|
3
|
+
private readonly _promise;
|
|
4
|
+
readonly then: PromiseLike<Result<T, E>>['then'];
|
|
5
|
+
constructor(promise: Promise<Result<T, E>>);
|
|
6
|
+
map<U>(fn: (value: T) => U | Promise<U>): ResultAsync<U, E>;
|
|
7
|
+
mapErr<F>(fn: (error: E) => F | Promise<F>): ResultAsync<T, F>;
|
|
8
|
+
andThen<U, F>(fn: (value: T) => Result<U, F> | ResultAsync<U, F>): ResultAsync<U, E | F>;
|
|
9
|
+
orElse<F>(fn: (error: E) => Result<T, F> | ResultAsync<T, F>): ResultAsync<T, F>;
|
|
10
|
+
unwrapOr(defaultValue: T): Promise<T>;
|
|
11
|
+
match<U>(cases: {
|
|
12
|
+
ok: (value: T) => U;
|
|
13
|
+
err: (error: E) => U;
|
|
14
|
+
}): Promise<U>;
|
|
15
|
+
[Symbol.asyncIterator](): AsyncGenerator<Err<never, E>, T>;
|
|
16
|
+
}
|
|
17
|
+
export declare function okAsync<T, E = never>(value: T): ResultAsync<T, E>;
|
|
18
|
+
export declare function errAsync<T = never, E = unknown>(error: E): ResultAsync<T, E>;
|
|
19
|
+
//# sourceMappingURL=result.async.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Ok, Err, ok, err } from './result.js';
|
|
2
|
+
export class ResultAsync {
|
|
3
|
+
_promise;
|
|
4
|
+
then;
|
|
5
|
+
constructor(promise) {
|
|
6
|
+
this._promise = promise;
|
|
7
|
+
this.then = promise.then.bind(promise);
|
|
8
|
+
}
|
|
9
|
+
map(fn) {
|
|
10
|
+
return new ResultAsync(this._promise.then(async (result) => {
|
|
11
|
+
if (result.isErr())
|
|
12
|
+
return new Err(result.error);
|
|
13
|
+
return new Ok(await fn(result.value));
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
mapErr(fn) {
|
|
17
|
+
return new ResultAsync(this._promise.then(async (result) => {
|
|
18
|
+
if (result.isOk())
|
|
19
|
+
return new Ok(result.value);
|
|
20
|
+
return new Err(await fn(result.error));
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
andThen(fn) {
|
|
24
|
+
return new ResultAsync(this._promise.then((result) => {
|
|
25
|
+
if (result.isErr())
|
|
26
|
+
return new Err(result.error);
|
|
27
|
+
const next = fn(result.value);
|
|
28
|
+
return next instanceof ResultAsync ? next._promise : next;
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
orElse(fn) {
|
|
32
|
+
return new ResultAsync(this._promise.then((result) => {
|
|
33
|
+
if (result.isOk())
|
|
34
|
+
return new Ok(result.value);
|
|
35
|
+
const next = fn(result.error);
|
|
36
|
+
return next instanceof ResultAsync ? next._promise : next;
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
async unwrapOr(defaultValue) {
|
|
40
|
+
const result = await this;
|
|
41
|
+
return result.unwrapOr(defaultValue);
|
|
42
|
+
}
|
|
43
|
+
async match(cases) {
|
|
44
|
+
const result = await this;
|
|
45
|
+
return result.match(cases);
|
|
46
|
+
}
|
|
47
|
+
async *[Symbol.asyncIterator]() {
|
|
48
|
+
const result = await this._promise;
|
|
49
|
+
if (result.isErr()) {
|
|
50
|
+
// @ts-expect-error -- structurally equivalent, safe for DoAsync notation
|
|
51
|
+
yield result;
|
|
52
|
+
throw new Error('Unreachable: DoAsync generator continued after Err yield');
|
|
53
|
+
}
|
|
54
|
+
return result.value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function okAsync(value) {
|
|
58
|
+
return new ResultAsync(Promise.resolve(ok(value)));
|
|
59
|
+
}
|
|
60
|
+
export function errAsync(error) {
|
|
61
|
+
return new ResultAsync(Promise.resolve(err(error)));
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=result.async.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type Result<T, E> = Ok<T, E> | Err<T, E>;
|
|
2
|
+
export declare class Ok<T, E = never> {
|
|
3
|
+
readonly value: T;
|
|
4
|
+
readonly _tag: symbol;
|
|
5
|
+
constructor(value: T);
|
|
6
|
+
isOk(): this is Ok<T, E>;
|
|
7
|
+
isErr(): this is Err<T, E>;
|
|
8
|
+
map<U>(fn: (value: T) => U): Result<U, E>;
|
|
9
|
+
mapErr<F>(_fn: (error: E) => F): Result<T, F>;
|
|
10
|
+
andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F>;
|
|
11
|
+
orElse<F>(_fn: (error: E) => Result<T, F>): Result<T, F>;
|
|
12
|
+
unwrapOr(_defaultValue: T): T;
|
|
13
|
+
match<U>(cases: {
|
|
14
|
+
ok: (value: T) => U;
|
|
15
|
+
err: (error: E) => U;
|
|
16
|
+
}): U;
|
|
17
|
+
[Symbol.iterator](): Generator<Err<never, E>, T>;
|
|
18
|
+
}
|
|
19
|
+
export declare class Err<T = never, E = unknown> {
|
|
20
|
+
readonly error: E;
|
|
21
|
+
readonly _tag: symbol;
|
|
22
|
+
constructor(error: E);
|
|
23
|
+
isOk(): this is Ok<T, E>;
|
|
24
|
+
isErr(): this is Err<T, E>;
|
|
25
|
+
map<U>(_fn: (value: T) => U): Result<U, E>;
|
|
26
|
+
mapErr<F>(fn: (error: E) => F): Result<T, F>;
|
|
27
|
+
andThen<U, F>(_fn: (value: T) => Result<U, F>): Result<U, E | F>;
|
|
28
|
+
orElse<F>(fn: (error: E) => Result<T, F>): Result<T, F>;
|
|
29
|
+
unwrapOr(defaultValue: T): T;
|
|
30
|
+
match<U>(cases: {
|
|
31
|
+
ok: (value: T) => U;
|
|
32
|
+
err: (error: E) => U;
|
|
33
|
+
}): U;
|
|
34
|
+
[Symbol.iterator](): Generator<Err<never, E>, T>;
|
|
35
|
+
}
|
|
36
|
+
export declare function ok<T, E = never>(value: T): Ok<T, E>;
|
|
37
|
+
export declare function err<T = never, E = unknown>(error: E): Err<T, E>;
|
|
38
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const OK = Symbol('Ok');
|
|
2
|
+
const ERR = Symbol('Err');
|
|
3
|
+
export class Ok {
|
|
4
|
+
value;
|
|
5
|
+
_tag = OK;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
}
|
|
9
|
+
isOk() {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
isErr() {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
map(fn) {
|
|
16
|
+
return new Ok(fn(this.value));
|
|
17
|
+
}
|
|
18
|
+
mapErr(_fn) {
|
|
19
|
+
return new Ok(this.value);
|
|
20
|
+
}
|
|
21
|
+
andThen(fn) {
|
|
22
|
+
return fn(this.value);
|
|
23
|
+
}
|
|
24
|
+
orElse(_fn) {
|
|
25
|
+
return new Ok(this.value);
|
|
26
|
+
}
|
|
27
|
+
unwrapOr(_defaultValue) {
|
|
28
|
+
return this.value;
|
|
29
|
+
}
|
|
30
|
+
match(cases) {
|
|
31
|
+
return cases.ok(this.value);
|
|
32
|
+
}
|
|
33
|
+
// eslint-disable-next-line require-yield
|
|
34
|
+
*[Symbol.iterator]() {
|
|
35
|
+
return this.value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class Err {
|
|
39
|
+
error;
|
|
40
|
+
_tag = ERR;
|
|
41
|
+
constructor(error) {
|
|
42
|
+
this.error = error;
|
|
43
|
+
}
|
|
44
|
+
isOk() {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
isErr() {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
map(_fn) {
|
|
51
|
+
return new Err(this.error);
|
|
52
|
+
}
|
|
53
|
+
mapErr(fn) {
|
|
54
|
+
return new Err(fn(this.error));
|
|
55
|
+
}
|
|
56
|
+
andThen(_fn) {
|
|
57
|
+
return new Err(this.error);
|
|
58
|
+
}
|
|
59
|
+
orElse(fn) {
|
|
60
|
+
return fn(this.error);
|
|
61
|
+
}
|
|
62
|
+
unwrapOr(defaultValue) {
|
|
63
|
+
return defaultValue;
|
|
64
|
+
}
|
|
65
|
+
match(cases) {
|
|
66
|
+
return cases.err(this.error);
|
|
67
|
+
}
|
|
68
|
+
*[Symbol.iterator]() {
|
|
69
|
+
// @ts-expect-error -- structurally equivalent, safe for Do notation
|
|
70
|
+
yield this;
|
|
71
|
+
throw new Error('Unreachable: Do notation generator continued after Err yield');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function ok(value) {
|
|
75
|
+
return new Ok(value);
|
|
76
|
+
}
|
|
77
|
+
export function err(error) {
|
|
78
|
+
return new Err(error);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=result.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clutchit",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "hexac",
|
|
7
|
+
"url": "https://existin.space",
|
|
8
|
+
"email": "hexac@existin.space"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/eishexac/clutchit.git",
|
|
17
|
+
"directory": "packages/unthrow"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/eishexac/clutchit/tree/release/#readme",
|
|
20
|
+
"bugs": "https://github.com/eishexac/clutchit/issues",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"!dist/**/*.map",
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"README.md",
|
|
26
|
+
"CHANGELOG.md"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"exports": {
|
|
30
|
+
"./unthrow": {
|
|
31
|
+
"@source": "./src/unthrow/index.ts",
|
|
32
|
+
"import": "./dist/unthrow/index.js",
|
|
33
|
+
"types": "./dist/unthrow/index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./schedule": {
|
|
36
|
+
"@source": "./src/schedule/index.ts",
|
|
37
|
+
"import": "./dist/schedule/index.js",
|
|
38
|
+
"types": "./dist/schedule/index.d.ts"
|
|
39
|
+
},
|
|
40
|
+
"./retry": {
|
|
41
|
+
"@source": "./src/retry/index.ts",
|
|
42
|
+
"import": "./dist/retry/index.js",
|
|
43
|
+
"types": "./dist/retry/index.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./timeout": {
|
|
46
|
+
"@source": "./src/timeout/index.ts",
|
|
47
|
+
"import": "./dist/timeout/index.js",
|
|
48
|
+
"types": "./dist/timeout/index.d.ts"
|
|
49
|
+
},
|
|
50
|
+
"./concurrency": {
|
|
51
|
+
"@source": "./src/concurrency/index.ts",
|
|
52
|
+
"import": "./dist/concurrency/index.js",
|
|
53
|
+
"types": "./dist/concurrency/index.d.ts"
|
|
54
|
+
},
|
|
55
|
+
"./circuit": {
|
|
56
|
+
"@source": "./src/circuit/index.ts",
|
|
57
|
+
"import": "./dist/circuit/index.js",
|
|
58
|
+
"types": "./dist/circuit/index.d.ts"
|
|
59
|
+
},
|
|
60
|
+
"./queue": {
|
|
61
|
+
"@source": "./src/queue/index.ts",
|
|
62
|
+
"import": "./dist/queue/index.js",
|
|
63
|
+
"types": "./dist/queue/index.d.ts"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"lint-staged": {
|
|
67
|
+
"*.ts": [
|
|
68
|
+
"eslint",
|
|
69
|
+
"prettier --check"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@eslint/js": "^10.0.1",
|
|
74
|
+
"@types/bun": "^1.3.9",
|
|
75
|
+
"@types/node": "^24.10.15",
|
|
76
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
77
|
+
"eslint": "^10.0.2",
|
|
78
|
+
"eslint-config-prettier": "^10.1.8",
|
|
79
|
+
"eslint-plugin-only-warn": "^1.1.0",
|
|
80
|
+
"eslint-plugin-turbo": "^2.8.10",
|
|
81
|
+
"globals": "^17.3.0",
|
|
82
|
+
"husky": "^9.1.7",
|
|
83
|
+
"lint-staged": "^16.2.7",
|
|
84
|
+
"prettier": "^3.8.1",
|
|
85
|
+
"rimraf": "^6.1.3",
|
|
86
|
+
"typescript": "^5.9.3",
|
|
87
|
+
"typescript-eslint": "^8.56.1",
|
|
88
|
+
"vitest": "^4.0.18"
|
|
89
|
+
},
|
|
90
|
+
"peerDependencies": {
|
|
91
|
+
"typescript": ">=5.2"
|
|
92
|
+
},
|
|
93
|
+
"engines": {
|
|
94
|
+
"node": ">=20",
|
|
95
|
+
"bun": ">=1"
|
|
96
|
+
},
|
|
97
|
+
"scripts": {
|
|
98
|
+
"build": "rimraf dist && tsc -p tsconfig.build.json",
|
|
99
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
100
|
+
"type:check": "tsc --noEmit",
|
|
101
|
+
"lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
102
|
+
"lint:fix": "eslint \"src/**/*.ts\" \"test/**/*.ts\" --fix",
|
|
103
|
+
"test": "vitest run",
|
|
104
|
+
"test:unit": "vitest run --project unit",
|
|
105
|
+
"test:int": "vitest run --project int",
|
|
106
|
+
"test:e2e": "vitest run --project e2e",
|
|
107
|
+
"test:coverage": "vitest run --coverage"
|
|
108
|
+
}
|
|
109
|
+
}
|