@terrygonguet/utils 0.0.9 → 0.0.11

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/async.js CHANGED
@@ -1,6 +1,65 @@
1
- function i(e) {
2
- return new Promise((t) => setTimeout(t, e));
1
+ import { findIndex as g } from "./functional.js";
2
+ function h(n) {
3
+ return new Promise((t) => setTimeout(t, n));
4
+ }
5
+ function x(n, t) {
6
+ return typeof n == "function" ? p(n, t) : (r) => p(r, n);
7
+ }
8
+ async function p(n, { count: t = 1 / 0, delay: r } = {}) {
9
+ let o = 0, s;
10
+ do
11
+ try {
12
+ return await n();
13
+ } catch (c) {
14
+ switch (s = c, o++, typeof r) {
15
+ case "number":
16
+ await h(r);
17
+ break;
18
+ case "function":
19
+ await h(r(o, c));
20
+ break;
21
+ }
22
+ }
23
+ while (o <= t);
24
+ throw s;
25
+ }
26
+ function I(n, t, r) {
27
+ if (typeof n == "function" && typeof t != "function") {
28
+ const o = n, s = t;
29
+ return (c) => w(c, o, s);
30
+ } else {
31
+ if (Array.isArray(n) && typeof t == "function")
32
+ return w(n, t, r);
33
+ throw new Error("Invalid arguments passed to asyncMap");
34
+ }
35
+ }
36
+ async function w(n, t, { concurrent: r = 5 } = {}) {
37
+ return new Promise((o, s) => {
38
+ const c = [], u = [];
39
+ let i = 0;
40
+ function y(e) {
41
+ if (c.length == n.length && u.length == 0)
42
+ return m();
43
+ if (e >= n.length)
44
+ return;
45
+ const f = n[e];
46
+ u.push([
47
+ e,
48
+ t(f, e, n).then((a) => {
49
+ c.push([e, a]), g(u, ([l]) => e == l).map((l) => u.splice(l, 1)), y(i);
50
+ }, s)
51
+ ]), i++;
52
+ }
53
+ function m() {
54
+ const e = c.sort(([f], [a]) => f - a);
55
+ o(e.map(([, f]) => f));
56
+ }
57
+ for (let e = 0; e < r; e++)
58
+ y(i);
59
+ });
3
60
  }
4
61
  export {
5
- i as wait
62
+ I as asyncMap,
63
+ h as pause,
64
+ x as retry
6
65
  };
@@ -1,66 +1,8 @@
1
- var p = Object.defineProperty;
2
- var S = (t, e, r) => e in t ? p(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
- var f = (t, e, r) => (S(t, typeof e != "symbol" ? e + "" : e, r), r);
4
- const s = "@terrygonguet/utils/functional/maybe", _ = "@terrygonguet/utils/functional/maybe/Some", h = "@terrygonguet/utils/functional/maybe/None";
5
- function u(t) {
6
- return Object.create(
7
- {
8
- isSome: () => !0,
9
- isNone: () => !1,
10
- orDefault() {
11
- return this.value;
12
- },
13
- map(e) {
14
- return u(e(this.value));
15
- },
16
- flatMap(e) {
17
- return e(this.value);
18
- },
19
- toJSON() {
20
- return { $_kind: s, $_variant: _, value: this.value };
21
- }
22
- },
23
- {
24
- $_kind: { value: s, enumerable: !1, writable: !1 },
25
- $_variant: { value: _, enumerable: !1, writable: !1 },
26
- value: { value: t, writable: !1 }
27
- }
28
- );
29
- }
30
- const a = Object.create(
31
- {
32
- isSome: () => !1,
33
- isNone: () => !0,
34
- orDefault: $,
35
- map: () => a,
36
- flatMap: () => a,
37
- toJSON: () => ({ $_kind: s, $_variant: h })
38
- },
39
- {
40
- $_kind: { value: s, enumerable: !1, writable: !1 },
41
- $_variant: { value: h, enumerable: !1, writable: !1 }
42
- }
43
- ), y = {
44
- Some: u,
45
- None: a,
46
- from(t) {
47
- switch (t) {
48
- case null:
49
- case void 0:
50
- return a;
51
- default:
52
- return u(t);
53
- }
54
- },
55
- JSONReviver(t, e) {
56
- if ((e == null ? void 0 : e.$_kind) == s) {
57
- const r = e == null ? void 0 : e.$_variant;
58
- return r == _ ? u(e == null ? void 0 : e.value) : r == h ? a : e;
59
- } else
60
- return e;
61
- }
62
- }, i = "@terrygonguet/utils/functional/result", o = "@terrygonguet/utils/functional/result/Success", b = "@terrygonguet/utils/functional/result/Failure";
63
- function c(t) {
1
+ var d = Object.defineProperty;
2
+ var v = (t, e, r) => e in t ? d(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
+ var _ = (t, e, r) => (v(t, typeof e != "symbol" ? e + "" : e, r), r);
4
+ const o = "@terrygonguet/utils/functional/result", m = "@terrygonguet/utils/functional/result/Success", p = "@terrygonguet/utils/functional/result/Failure";
5
+ function i(t) {
64
6
  return Object.create(
65
7
  {
66
8
  isSuccess: () => !0,
@@ -68,24 +10,27 @@ function c(t) {
68
10
  merge(e) {
69
11
  return e(this.value);
70
12
  },
13
+ match(e) {
14
+ return e(this.value);
15
+ },
71
16
  map(e) {
72
- return c(e(this.value));
17
+ return i(e(this.value));
73
18
  },
74
19
  flatMap(e) {
75
20
  return e(this.value);
76
21
  },
77
22
  toJSON() {
78
- return { $_kind: i, $_variant: o, value: this.value };
23
+ return { $_kind: o, $_variant: m, value: this.value };
79
24
  }
80
25
  },
81
26
  {
82
- $_kind: { value: i, enumerable: !1, writable: !1 },
83
- $_variant: { value: o, enumerable: !1, writable: !1 },
27
+ $_kind: { value: o, enumerable: !1, writable: !1 },
28
+ $_variant: { value: m, enumerable: !1, writable: !1 },
84
29
  value: { value: t, writable: !1 }
85
30
  }
86
31
  );
87
32
  }
88
- function m(t) {
33
+ function f(t) {
89
34
  return Object.create(
90
35
  {
91
36
  isSuccess: () => !1,
@@ -93,6 +38,9 @@ function m(t) {
93
38
  merge(e, r) {
94
39
  return r(this.reason);
95
40
  },
41
+ match(e, r) {
42
+ return r(this.reason);
43
+ },
96
44
  map() {
97
45
  return this;
98
46
  },
@@ -100,72 +48,182 @@ function m(t) {
100
48
  return this;
101
49
  },
102
50
  toJSON() {
103
- return { $_kind: i, $_variant: b, reason: this.reason };
51
+ return { $_kind: o, $_variant: p, reason: this.reason };
104
52
  }
105
53
  },
106
54
  {
107
- $_kind: { value: i, enumerable: !1, writable: !1 },
108
- $_variant: { value: o, enumerable: !1, writable: !1 },
55
+ $_kind: { value: o, enumerable: !1, writable: !1 },
56
+ $_variant: { value: m, enumerable: !1, writable: !1 },
109
57
  reason: { value: t, writable: !1 }
110
58
  }
111
59
  );
112
60
  }
113
- const v = {
114
- Success: c,
115
- Failure: m,
61
+ function y(t, e) {
62
+ return e ? t.toResult(e) : t.toResult();
63
+ }
64
+ const w = {
65
+ Success: i,
66
+ Failure: f,
116
67
  try(t) {
117
- return new d(t);
68
+ return new k(t);
69
+ },
70
+ fromPromise(t, e, r) {
71
+ return t.then($(e, i), $(r, f));
118
72
  },
73
+ fromMaybe: y,
119
74
  JSONReviver(t, e) {
120
- if ((e == null ? void 0 : e.$_kind) == i) {
75
+ if ((e == null ? void 0 : e.$_kind) == o) {
121
76
  const r = e == null ? void 0 : e.$_variant;
122
- return r == o ? c(e == null ? void 0 : e.value) : r == b ? m(e == null ? void 0 : e.reason) : e;
77
+ return r == m ? i(e == null ? void 0 : e.value) : r == p ? f(e == null ? void 0 : e.reason) : e;
123
78
  } else
124
79
  return e;
125
80
  }
126
81
  };
127
- class d {
82
+ class k {
128
83
  constructor(e) {
129
- f(this, "tryFn");
130
- f(this, "catchFn");
131
- this.tryFn = e, this.catchFn = $;
84
+ _(this, "tryFn");
85
+ _(this, "catchFn");
86
+ this.tryFn = e, this.catchFn = S;
132
87
  }
133
88
  catch(e) {
134
89
  return this.catchFn = e, this;
135
90
  }
136
91
  exec(e) {
137
92
  try {
138
- const r = c(this.tryFn());
93
+ const r = i(this.tryFn());
139
94
  return e == null || e(r), r;
140
95
  } catch (r) {
141
- const n = m(this.catchFn(r));
96
+ const n = f(this.catchFn(r));
142
97
  return e == null || e(n), n;
143
98
  }
144
99
  }
145
100
  }
146
- var N = w;
147
- function w(t, e) {
101
+ const c = "@terrygonguet/utils/functional/maybe", b = "@terrygonguet/utils/functional/maybe/Some", g = "@terrygonguet/utils/functional/maybe/None";
102
+ function l(t) {
103
+ return Object.create(
104
+ {
105
+ isSome: () => !0,
106
+ isNone: () => !1,
107
+ orDefault() {
108
+ return this.value;
109
+ },
110
+ map(e) {
111
+ return l(e(this.value));
112
+ },
113
+ flatMap(e) {
114
+ return e(this.value);
115
+ },
116
+ toResult() {
117
+ return w.Success(this.value);
118
+ },
119
+ toJSON() {
120
+ return { $_kind: c, $_variant: b, value: this.value };
121
+ }
122
+ },
123
+ {
124
+ $_kind: { value: c, enumerable: !1, writable: !1 },
125
+ $_variant: { value: b, enumerable: !1, writable: !1 },
126
+ value: { value: t, writable: !1 }
127
+ }
128
+ );
129
+ }
130
+ const u = Object.create(
131
+ {
132
+ isSome: () => !1,
133
+ isNone: () => !0,
134
+ orDefault: (t) => t,
135
+ map: () => u,
136
+ flatMap: () => u,
137
+ toResult: (t) => w.Failure(t == null ? void 0 : t()),
138
+ toJSON: () => ({ $_kind: c, $_variant: g })
139
+ },
140
+ {
141
+ $_kind: { value: c, enumerable: !1, writable: !1 },
142
+ $_variant: { value: g, enumerable: !1, writable: !1 }
143
+ }
144
+ ), s = {
145
+ Some: l,
146
+ None: u,
147
+ from(t) {
148
+ switch (t) {
149
+ case null:
150
+ case void 0:
151
+ return u;
152
+ default:
153
+ return l(t);
154
+ }
155
+ },
156
+ /**
157
+ * CAUTION: this method swallows errors and simply returns None!
158
+ * Use `Result.fromPromise()` if you need error details.
159
+ */
160
+ fromPromise(t, e = S) {
161
+ return t.then($(e, s.from), M(u));
162
+ },
163
+ JSONReviver(t, e) {
164
+ if ((e == null ? void 0 : e.$_kind) == c) {
165
+ const r = e == null ? void 0 : e.$_variant;
166
+ return r == b ? l(e == null ? void 0 : e.value) : r == g ? u : e;
167
+ } else
168
+ return e;
169
+ }
170
+ };
171
+ var $ = x;
172
+ function x(t, e) {
148
173
  if (!arguments.length)
149
174
  throw new Error(
150
175
  "expected at least one (and probably more) function arguments"
151
176
  );
152
177
  var r = arguments;
153
178
  return function() {
154
- for (var n = r[0].apply(this, arguments), g = r.length, l = 1; l < g; l++)
155
- n = r[l].call(this, n);
179
+ for (var n = r[0].apply(this, arguments), a = r.length, h = 1; h < a; h++)
180
+ n = r[h].call(this, n);
156
181
  return n;
157
182
  };
158
183
  }
159
- function $(t) {
184
+ var J = N;
185
+ function N(t, ...e) {
186
+ if (!arguments.length)
187
+ throw new Error("expected one value argument and least one function argument");
188
+ if (!e.length)
189
+ throw new Error(
190
+ "expected at least one (and probably more) function arguments"
191
+ );
192
+ for (var r = e[0](t), n = e.length, a = 1; a < n; a++)
193
+ r = e[a](r);
194
+ return r;
195
+ }
196
+ function S(t) {
160
197
  return t;
161
198
  }
162
- function O(t) {
199
+ function M(t) {
163
200
  return () => t;
164
201
  }
202
+ function F(t, e) {
203
+ return typeof t == "number" ? (r) => s.from(r.at(t)) : s.from(t.at(e));
204
+ }
205
+ function j(t, e) {
206
+ return typeof t == "function" ? (r) => s.from(r.find(t)) : s.from(t.find(e));
207
+ }
208
+ function O(t, e) {
209
+ if (typeof t == "function")
210
+ return (r) => {
211
+ const n = r.findIndex(t);
212
+ return n == -1 ? s.None : s.Some(n);
213
+ };
214
+ {
215
+ const r = t.findIndex(e);
216
+ return r == -1 ? s.None : s.Some(r);
217
+ }
218
+ }
165
219
  export {
166
- y as Maybe,
167
- v as Result,
168
- N as compose,
169
- O as constant,
170
- $ as identity
220
+ s as Maybe,
221
+ w as Result,
222
+ F as at,
223
+ $ as compose,
224
+ M as constant,
225
+ j as find,
226
+ O as findIndex,
227
+ S as identity,
228
+ J as pipe
171
229
  };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@terrygonguet/utils",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
- "module": "./dist/main.js",
5
+ "module": "./dist/index.js",
6
6
  "author": {
7
7
  "email": "terry@gonguet.com",
8
8
  "name": "Terry Gonguet",
@@ -29,21 +29,29 @@
29
29
  ],
30
30
  "exports": {
31
31
  ".": {
32
- "types": "./types/main.d.ts",
33
- "import": "./dist/main.js"
32
+ "import": "./dist/index.js"
34
33
  },
35
34
  "./async": {
36
- "types": "./types/async.d.ts",
37
35
  "import": "./dist/async.js"
38
36
  },
39
37
  "./functional": {
40
- "types": "./types/functional/index.d.ts",
41
38
  "import": "./dist/functional.js"
42
39
  }
43
40
  },
44
- "types": "./types/main.d.ts",
41
+ "typesVersions": {
42
+ "*": {
43
+ "async": [
44
+ "./types/async.d.ts"
45
+ ],
46
+ "functional": [
47
+ "./types/functional/index.d.ts"
48
+ ]
49
+ }
50
+ },
51
+ "types": "./types/index.d.ts",
45
52
  "dependencies": {
46
- "just-compose": "^2.3.0"
53
+ "just-compose": "^2.3.0",
54
+ "just-pipe": "^1.0.0"
47
55
  },
48
56
  "repository": {
49
57
  "type": "git",
package/src/async.ts CHANGED
@@ -1,3 +1,112 @@
1
- export function wait(ms: number): Promise<void> {
1
+ import { findIndex } from "./functional/index.ts"
2
+
3
+ export function pause(ms: number): Promise<void> {
2
4
  return new Promise(resolve => setTimeout(resolve, ms))
3
- }
5
+ }
6
+
7
+ interface RetryOptions {
8
+ count?: number
9
+ delay?: number | ((retryCount: number, error: any) => number)
10
+ }
11
+
12
+ export function retry(options: RetryOptions): <T>(provider: () => Promise<T>) => Promise<T>
13
+ export function retry<T>(provider: () => Promise<T>, options?: RetryOptions): Promise<T>
14
+ export function retry<T>(
15
+ providerOrOptions: RetryOptions | (() => Promise<T>),
16
+ options?: RetryOptions,
17
+ ) {
18
+ if (typeof providerOrOptions == "function") return _retry(providerOrOptions, options)
19
+ else return (provider: () => Promise<T>) => _retry(provider, providerOrOptions)
20
+ }
21
+
22
+ async function _retry<T>(
23
+ provider: () => Promise<T>,
24
+ { count = Infinity, delay }: RetryOptions = {},
25
+ ): Promise<T> {
26
+ let retryCount = 0
27
+ let lastError: any
28
+ do {
29
+ try {
30
+ return await provider()
31
+ } catch (error) {
32
+ lastError = error
33
+ retryCount++
34
+ switch (typeof delay) {
35
+ case "number":
36
+ await pause(delay)
37
+ break
38
+ case "function":
39
+ await pause(delay(retryCount, error))
40
+ break
41
+ }
42
+ }
43
+ } while (retryCount <= count)
44
+ throw lastError
45
+ }
46
+
47
+ interface AsyncMapOptions {
48
+ concurrent?: number
49
+ }
50
+
51
+ export function asyncMap<T, U>(
52
+ f: AsyncMapFn<T, U>,
53
+ options?: AsyncMapOptions,
54
+ ): (data: T[]) => Promise<U[]>
55
+ export function asyncMap<T, U>(
56
+ data: T[],
57
+ f: AsyncMapFn<T, U>,
58
+ options?: AsyncMapOptions,
59
+ ): Promise<U[]>
60
+ export function asyncMap<T, U>(
61
+ dataOrF: T[] | AsyncMapFn<T, U>,
62
+ ForOptions: AsyncMapFn<T, U> | AsyncMapOptions | undefined,
63
+ options?: AsyncMapOptions,
64
+ ): Promise<U[]> | ((data: T[]) => Promise<U[]>) {
65
+ if (typeof dataOrF == "function" && typeof ForOptions != "function") {
66
+ const f = dataOrF
67
+ const options = ForOptions
68
+ return (data: T[]) => asyncMap_(data, f, options)
69
+ } else if (Array.isArray(dataOrF) && typeof ForOptions == "function") {
70
+ const data = dataOrF
71
+ const f = ForOptions
72
+ return asyncMap_(data, f, options)
73
+ } else throw new Error("Invalid arguments passed to asyncMap")
74
+ }
75
+
76
+ type AsyncMapFn<T, U> = (el: T, i: number, data: T[]) => Promise<U>
77
+
78
+ async function asyncMap_<T, U>(
79
+ data: T[],
80
+ f: AsyncMapFn<T, U>,
81
+ { concurrent = 5 }: AsyncMapOptions = {},
82
+ ): Promise<U[]> {
83
+ return new Promise((resolve, reject) => {
84
+ const resolved: [i: number, result: U][] = []
85
+ const inFlight: [i: number, promise: Promise<void>][] = []
86
+
87
+ let next = 0
88
+ function queue(i: number) {
89
+ if (resolved.length == data.length && inFlight.length == 0) return finish()
90
+ if (i >= data.length) return
91
+ const el = data[i]
92
+ inFlight.push([
93
+ i,
94
+ f(el, i, data).then(result => {
95
+ resolved.push([i, result])
96
+ findIndex(inFlight, ([j]) => i == j).map(j => inFlight.splice(j, 1))
97
+ queue(next)
98
+ }, reject),
99
+ ])
100
+ next++
101
+ }
102
+
103
+ function finish() {
104
+ const sorted = resolved.sort(([a], [b]) => a - b)
105
+ resolve(sorted.map(([, value]) => value))
106
+ }
107
+
108
+ for (let i = 0; i < concurrent; i++) {
109
+ queue(next)
110
+ }
111
+ })
112
+ }
@@ -1,6 +1,9 @@
1
+ import { Maybe } from "./maybe.ts"
2
+
1
3
  export * from "./maybe.ts"
2
4
  export * from "./result.ts"
3
5
  export { default as compose } from "just-compose"
6
+ export { default as pipe } from "just-pipe"
4
7
 
5
8
  export function identity<T>(value: T) {
6
9
  return value
@@ -9,3 +12,34 @@ export function identity<T>(value: T) {
9
12
  export function constant<T>(value: T) {
10
13
  return () => value
11
14
  }
15
+
16
+ export function at(idx: number): <T>(data: T[]) => Maybe<T>
17
+ export function at<T>(data: T[], idx: number): Maybe<T>
18
+ export function at<T>(dataOrIdx: T[] | number, idx?: number) {
19
+ if (typeof dataOrIdx == "number") return (data: T[]) => Maybe.from(data.at(dataOrIdx))
20
+ else return Maybe.from(dataOrIdx.at(idx!))
21
+ }
22
+
23
+ type Predicate<T> = (value: T, idx: number, arr: T[]) => boolean
24
+
25
+ export function find<T>(predicate: Predicate<T>): (data: T[]) => Maybe<T>
26
+ export function find<T>(data: T[], predicate: Predicate<T>): Maybe<T>
27
+ export function find<T>(dataOrPredicate: T[] | Predicate<T>, predicate?: Predicate<T>) {
28
+ if (typeof dataOrPredicate == "function")
29
+ return (data: T[]) => Maybe.from(data.find(dataOrPredicate))
30
+ else return Maybe.from(dataOrPredicate.find(predicate!))
31
+ }
32
+
33
+ export function findIndex<T>(predicate: Predicate<T>): (data: T[]) => Maybe<number>
34
+ export function findIndex<T>(data: T[], predicate: Predicate<T>): Maybe<number>
35
+ export function findIndex<T>(dataOrPredicate: T[] | Predicate<T>, predicate?: Predicate<T>) {
36
+ if (typeof dataOrPredicate == "function") {
37
+ return (data: T[]) => {
38
+ const idx = data.findIndex(dataOrPredicate)
39
+ return idx == -1 ? Maybe.None : Maybe.Some(idx)
40
+ }
41
+ } else {
42
+ const idx = dataOrPredicate.findIndex(predicate!)
43
+ return idx == -1 ? Maybe.None : Maybe.Some(idx)
44
+ }
45
+ }
@@ -1,4 +1,5 @@
1
- import { identity } from "./index.ts"
1
+ import { compose, constant, identity } from "./index.ts"
2
+ import { Result } from "./result.ts"
2
3
 
3
4
  interface API<T> {
4
5
  isSome(this: Maybe<T>): this is Some<T>
@@ -6,6 +7,8 @@ interface API<T> {
6
7
  orDefault(this: Maybe<T>, defaultValue: T): T
7
8
  map<U>(this: Maybe<T>, f: (value: T) => U): Maybe<U>
8
9
  flatMap<U>(this: Maybe<T>, f: (value: T) => Maybe<U>): Maybe<U>
10
+ toResult(this: Maybe<T>): Result<T, undefined>
11
+ toResult<U>(this: Maybe<T>, mapNone: () => U): Result<T, U>
9
12
  toJSON(this: Maybe<T>): Object
10
13
  }
11
14
 
@@ -31,10 +34,13 @@ function Some<T>(value: NonNullable<T>): Some<T> {
31
34
  flatMap(this: Some<T>, f) {
32
35
  return f(this.value)
33
36
  },
37
+ toResult(this: Some<T>) {
38
+ return Result.Success<T, any>(this.value)
39
+ },
34
40
  toJSON(this: Some<T>) {
35
41
  return { $_kind, $_variant: $_variant_Some, value: this.value }
36
42
  },
37
- } as API<T>,
43
+ } satisfies API<T>,
38
44
  {
39
45
  $_kind: { value: $_kind, enumerable: false, writable: false },
40
46
  $_variant: { value: $_variant_Some, enumerable: false, writable: false },
@@ -47,11 +53,12 @@ const None: None<any> = Object.create(
47
53
  {
48
54
  isSome: () => false,
49
55
  isNone: () => true,
50
- orDefault: identity,
56
+ orDefault: defaultValue => defaultValue,
51
57
  map: () => None,
52
58
  flatMap: () => None,
59
+ toResult: <U>(mapNone?: () => U) => Result.Failure(mapNone?.()),
53
60
  toJSON: () => ({ $_kind, $_variant: $_variant_None }),
54
- } as API<any>,
61
+ } satisfies API<any>,
55
62
  {
56
63
  $_kind: { value: $_kind, enumerable: false, writable: false },
57
64
  $_variant: { value: $_variant_None, enumerable: false, writable: false },
@@ -70,6 +77,13 @@ export const Maybe = {
70
77
  return Some(value!)
71
78
  }
72
79
  },
80
+ /**
81
+ * CAUTION: this method swallows errors and simply returns None!
82
+ * Use `Result.fromPromise()` if you need error details.
83
+ */
84
+ fromPromise<T>(promise: Promise<T>, onResolve: (value: T) => T = identity): Promise<Maybe<T>> {
85
+ return promise.then(compose(onResolve, Maybe.from), constant(None))
86
+ },
73
87
  JSONReviver(_key: string, value: any) {
74
88
  if (value?.$_kind == $_kind) {
75
89
  const $_variant = value?.$_variant
@@ -1,9 +1,11 @@
1
- import { identity } from "./index.ts"
1
+ import { compose, identity } from "./index.ts"
2
+ import { Maybe } from "./maybe.ts"
2
3
 
3
4
  interface API<S, F> {
4
5
  isSuccess(this: Result<S, F>): this is Success<S, F>
5
6
  isFailure(this: Result<S, F>): this is Failure<S, F>
6
7
  merge<T>(this: Result<S, F>, f: (value: S) => T, g: (reason: F) => T): T
8
+ match(this: Result<S, F>, successFn: (value: S) => void, failureFn: (reason: F) => void): void
7
9
  map<S2>(this: Result<S, F>, f: (value: S) => S2): Result<S2, F>
8
10
  flatMap<S2, F2>(this: Result<S, F>, f: (value: S) => Result<S2, F | F2>): Result<S2, F | F2>
9
11
  toJSON(this: Result<S, F>): Object
@@ -25,6 +27,9 @@ function Success<S, F>(value: S): Success<S, F> {
25
27
  merge<T>(this: Success<S, F>, f: (value: S) => T) {
26
28
  return f(this.value)
27
29
  },
30
+ match(this: Success<S, F>, successFn) {
31
+ return successFn(this.value)
32
+ },
28
33
  map<S2>(this: Success<S, F>, f: (value: S) => S2) {
29
34
  return Success(f(this.value))
30
35
  },
@@ -34,7 +39,7 @@ function Success<S, F>(value: S): Success<S, F> {
34
39
  toJSON(this: Success<S, F>) {
35
40
  return { $_kind, $_variant: $_variant_Success, value: this.value }
36
41
  },
37
- } as API<S, F>,
42
+ } satisfies API<S, F>,
38
43
  {
39
44
  $_kind: { value: $_kind, enumerable: false, writable: false },
40
45
  $_variant: { value: $_variant_Success, enumerable: false, writable: false },
@@ -51,6 +56,9 @@ function Failure<S, F>(reason: F): Failure<S, F> {
51
56
  merge<T>(this: Failure<S, F>, _: (value: S) => T, g: (reason: F) => T) {
52
57
  return g(this.reason)
53
58
  },
59
+ match(this: Failure<S, F>, _, failureFn) {
60
+ return failureFn(this.reason)
61
+ },
54
62
  map<S2>(this: Failure<S, F>) {
55
63
  return this as unknown as Result<S2, F>
56
64
  },
@@ -60,7 +68,7 @@ function Failure<S, F>(reason: F): Failure<S, F> {
60
68
  toJSON(this: Failure<S, F>) {
61
69
  return { $_kind, $_variant: $_variant_Failure, reason: this.reason }
62
70
  },
63
- } as API<S, F>,
71
+ } satisfies API<S, F>,
64
72
  {
65
73
  $_kind: { value: $_kind, enumerable: false, writable: false },
66
74
  $_variant: { value: $_variant_Success, enumerable: false, writable: false },
@@ -69,12 +77,26 @@ function Failure<S, F>(reason: F): Failure<S, F> {
69
77
  )
70
78
  }
71
79
 
80
+ function resultFromMaybe<S>(maybe: Maybe<S>): Result<S, undefined>
81
+ function resultFromMaybe<S, F>(maybe: Maybe<S>, mapNone: () => F): Result<S, F>
82
+ function resultFromMaybe<S, F>(maybe: Maybe<S>, mapNone?: () => F) {
83
+ return mapNone ? maybe.toResult(mapNone) : maybe.toResult()
84
+ }
85
+
72
86
  export const Result = {
73
87
  Success,
74
88
  Failure,
75
89
  try<S, F>(tryFn: () => S) {
76
90
  return new TryCatch<S, F>(tryFn)
77
91
  },
92
+ fromPromise<S, F>(
93
+ promise: Promise<S>,
94
+ onResolve: (value: S) => S,
95
+ onReject: (reason: unknown) => F,
96
+ ): Promise<Result<S, F>> {
97
+ return promise.then(compose(onResolve, Success<S, F>), compose(onReject, Failure<S, F>))
98
+ },
99
+ fromMaybe: resultFromMaybe,
78
100
  JSONReviver(_key: string, value: any) {
79
101
  if (value?.$_kind == $_kind) {
80
102
  const $_variant = value?.$_variant
package/types/async.d.ts CHANGED
@@ -1 +1,14 @@
1
- export declare function wait(ms: number): Promise<void>;
1
+ export declare function pause(ms: number): Promise<void>;
2
+ interface RetryOptions {
3
+ count?: number;
4
+ delay?: number | ((retryCount: number, error: any) => number);
5
+ }
6
+ export declare function retry(options: RetryOptions): <T>(provider: () => Promise<T>) => Promise<T>;
7
+ export declare function retry<T>(provider: () => Promise<T>, options?: RetryOptions): Promise<T>;
8
+ interface AsyncMapOptions {
9
+ concurrent?: number;
10
+ }
11
+ export declare function asyncMap<T, U>(f: AsyncMapFn<T, U>, options?: AsyncMapOptions): (data: T[]) => Promise<U[]>;
12
+ export declare function asyncMap<T, U>(data: T[], f: AsyncMapFn<T, U>, options?: AsyncMapOptions): Promise<U[]>;
13
+ type AsyncMapFn<T, U> = (el: T, i: number, data: T[]) => Promise<U>;
14
+ export {};
@@ -1,5 +1,14 @@
1
+ import { Maybe } from "./maybe.ts";
1
2
  export * from "./maybe.ts";
2
3
  export * from "./result.ts";
3
4
  export { default as compose } from "just-compose";
5
+ export { default as pipe } from "just-pipe";
4
6
  export declare function identity<T>(value: T): T;
5
7
  export declare function constant<T>(value: T): () => T;
8
+ export declare function at(idx: number): <T>(data: T[]) => Maybe<T>;
9
+ export declare function at<T>(data: T[], idx: number): Maybe<T>;
10
+ type Predicate<T> = (value: T, idx: number, arr: T[]) => boolean;
11
+ export declare function find<T>(predicate: Predicate<T>): (data: T[]) => Maybe<T>;
12
+ export declare function find<T>(data: T[], predicate: Predicate<T>): Maybe<T>;
13
+ export declare function findIndex<T>(predicate: Predicate<T>): (data: T[]) => Maybe<number>;
14
+ export declare function findIndex<T>(data: T[], predicate: Predicate<T>): Maybe<number>;
@@ -1,9 +1,12 @@
1
+ import { Result } from "./result.ts";
1
2
  interface API<T> {
2
3
  isSome(this: Maybe<T>): this is Some<T>;
3
4
  isNone(this: Maybe<T>): this is None<T>;
4
5
  orDefault(this: Maybe<T>, defaultValue: T): T;
5
6
  map<U>(this: Maybe<T>, f: (value: T) => U): Maybe<U>;
6
7
  flatMap<U>(this: Maybe<T>, f: (value: T) => Maybe<U>): Maybe<U>;
8
+ toResult(this: Maybe<T>): Result<T, undefined>;
9
+ toResult<U>(this: Maybe<T>, mapNone: () => U): Result<T, U>;
7
10
  toJSON(this: Maybe<T>): Object;
8
11
  }
9
12
  export type Some<T> = {
@@ -16,6 +19,11 @@ export declare const Maybe: {
16
19
  Some: typeof Some;
17
20
  None: None<any>;
18
21
  from<T>(value: T | null | undefined): Maybe<T>;
22
+ /**
23
+ * CAUTION: this method swallows errors and simply returns None!
24
+ * Use `Result.fromPromise()` if you need error details.
25
+ */
26
+ fromPromise<T_1>(promise: Promise<T_1>, onResolve?: (value: T_1) => T_1): Promise<Maybe<T_1>>;
19
27
  JSONReviver(_key: string, value: any): any;
20
28
  };
21
29
  export {};
@@ -1,7 +1,9 @@
1
+ import { Maybe } from "./maybe.ts";
1
2
  interface API<S, F> {
2
3
  isSuccess(this: Result<S, F>): this is Success<S, F>;
3
4
  isFailure(this: Result<S, F>): this is Failure<S, F>;
4
5
  merge<T>(this: Result<S, F>, f: (value: S) => T, g: (reason: F) => T): T;
6
+ match(this: Result<S, F>, successFn: (value: S) => void, failureFn: (reason: F) => void): void;
5
7
  map<S2>(this: Result<S, F>, f: (value: S) => S2): Result<S2, F>;
6
8
  flatMap<S2, F2>(this: Result<S, F>, f: (value: S) => Result<S2, F | F2>): Result<S2, F | F2>;
7
9
  toJSON(this: Result<S, F>): Object;
@@ -15,10 +17,14 @@ export type Failure<S, F> = {
15
17
  export type Result<S, F> = Success<S, F> | Failure<S, F>;
16
18
  declare function Success<S, F>(value: S): Success<S, F>;
17
19
  declare function Failure<S, F>(reason: F): Failure<S, F>;
20
+ declare function resultFromMaybe<S>(maybe: Maybe<S>): Result<S, undefined>;
21
+ declare function resultFromMaybe<S, F>(maybe: Maybe<S>, mapNone: () => F): Result<S, F>;
18
22
  export declare const Result: {
19
23
  Success: typeof Success;
20
24
  Failure: typeof Failure;
21
25
  try<S, F>(tryFn: () => S): TryCatch<S, F>;
26
+ fromPromise<S_1, F_1>(promise: Promise<S_1>, onResolve: (value: S_1) => S_1, onReject: (reason: unknown) => F_1): Promise<Result<S_1, F_1>>;
27
+ fromMaybe: typeof resultFromMaybe;
22
28
  JSONReviver(_key: string, value: any): any;
23
29
  };
24
30
  declare class TryCatch<S, F> {
File without changes
File without changes
File without changes