aang 2.0.0-alpha.3 → 2.0.0-alpha.30
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/lib/bool.d.ts +30 -0
- package/lib/bool.js +69 -0
- package/lib/datetime.d.ts +19 -0
- package/lib/datetime.js +57 -0
- package/lib/double.d.ts +19 -0
- package/lib/double.js +49 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +12 -0
- package/lib/integer.d.ts +30 -0
- package/lib/integer.js +69 -0
- package/lib/miscellaneous.d.ts +5 -0
- package/lib/miscellaneous.js +6 -0
- package/lib/option.d.ts +58 -10
- package/lib/option.js +167 -13
- package/lib/order.d.ts +18 -0
- package/lib/order.js +1 -0
- package/lib/ordering.d.ts +7 -0
- package/lib/ordering.js +6 -0
- package/lib/pair.d.ts +106 -0
- package/lib/pair.js +322 -0
- package/lib/result.d.ts +125 -0
- package/lib/result.js +439 -0
- package/lib/semigroup.d.ts +3 -0
- package/lib/semigroup.js +1 -0
- package/lib/task.d.ts +36 -0
- package/lib/task.js +282 -0
- package/lib/text.d.ts +21 -0
- package/lib/text.js +50 -0
- package/package.json +1 -1
- package/lib/errors.d.ts +0 -4
- package/lib/errors.js +0 -7
package/lib/task.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { None, Some } from "./option.js";
|
|
2
|
+
import { Pair } from "./pair.js";
|
|
3
|
+
import { Fail, Okay } from "./result.js";
|
|
4
|
+
export class Task {
|
|
5
|
+
execute;
|
|
6
|
+
constructor(execute) {
|
|
7
|
+
this.execute = execute;
|
|
8
|
+
}
|
|
9
|
+
static okay(value) {
|
|
10
|
+
return new Task((signal, callback) => {
|
|
11
|
+
if (!signal.aborted)
|
|
12
|
+
callback(new Okay(value));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
static fail(value) {
|
|
16
|
+
return new Task((signal, callback) => {
|
|
17
|
+
if (!signal.aborted)
|
|
18
|
+
callback(new Fail(value));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
static of(task) {
|
|
22
|
+
return new Task((signal, callback) => {
|
|
23
|
+
const abort = task((result) => {
|
|
24
|
+
if (!signal.aborted) {
|
|
25
|
+
signal.removeEventListener("abort", onAbort);
|
|
26
|
+
callback(result);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
signal.addEventListener("abort", onAbort);
|
|
30
|
+
function onAbort() {
|
|
31
|
+
signal.removeEventListener("abort", onAbort);
|
|
32
|
+
abort(signal.reason);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// TODO: <A, B>(getGenerator: () => Generator<Task<A, unknown>, B, A>) => Task<B, unknown>
|
|
37
|
+
static fromGenerator(getGenerator) {
|
|
38
|
+
return new Task((signal, callback) => {
|
|
39
|
+
const generator = getGenerator();
|
|
40
|
+
const trampoline = (task) => {
|
|
41
|
+
let option = new Some(task);
|
|
42
|
+
while (option.isSome) {
|
|
43
|
+
const task = option.value;
|
|
44
|
+
option = None.instance;
|
|
45
|
+
let isAsync = false;
|
|
46
|
+
task.execute(signal, (result) => {
|
|
47
|
+
let iteratorResult;
|
|
48
|
+
try {
|
|
49
|
+
iteratorResult = result.isOkay
|
|
50
|
+
? generator.next(result.value)
|
|
51
|
+
: generator.throw(result.value);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return callback(new Fail(error));
|
|
55
|
+
}
|
|
56
|
+
if (iteratorResult.done)
|
|
57
|
+
callback(new Okay(iteratorResult.value));
|
|
58
|
+
else if (isAsync)
|
|
59
|
+
trampoline(iteratorResult.value);
|
|
60
|
+
else
|
|
61
|
+
option = new Some(iteratorResult.value);
|
|
62
|
+
});
|
|
63
|
+
isAsync = true;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
let iteratorResult;
|
|
67
|
+
try {
|
|
68
|
+
iteratorResult = generator.next();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return callback(new Fail(error));
|
|
72
|
+
}
|
|
73
|
+
if (iteratorResult.done)
|
|
74
|
+
callback(new Okay(iteratorResult.value));
|
|
75
|
+
else
|
|
76
|
+
trampoline(iteratorResult.value);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
run(callback) {
|
|
80
|
+
const controller = new AbortController();
|
|
81
|
+
this.execute(controller.signal, callback);
|
|
82
|
+
return controller;
|
|
83
|
+
}
|
|
84
|
+
map(okayMorphism, failMorphism) {
|
|
85
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.map(okayMorphism, failMorphism))));
|
|
86
|
+
}
|
|
87
|
+
mapOkay(morphism) {
|
|
88
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.mapOkay(morphism))));
|
|
89
|
+
}
|
|
90
|
+
mapFail(morphism) {
|
|
91
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.mapFail(morphism))));
|
|
92
|
+
}
|
|
93
|
+
replace(okayValue, failValue) {
|
|
94
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.replace(okayValue, failValue))));
|
|
95
|
+
}
|
|
96
|
+
replaceOkay(value) {
|
|
97
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.replaceOkay(value))));
|
|
98
|
+
}
|
|
99
|
+
replaceFail(value) {
|
|
100
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.replaceFail(value))));
|
|
101
|
+
}
|
|
102
|
+
and(that) {
|
|
103
|
+
return Task.of((callback) => {
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
let fst = None.instance;
|
|
106
|
+
let snd = None.instance;
|
|
107
|
+
this.execute(controller.signal, (result) => {
|
|
108
|
+
if (result.isFail) {
|
|
109
|
+
if (snd.isNone)
|
|
110
|
+
controller.abort();
|
|
111
|
+
callback(result);
|
|
112
|
+
}
|
|
113
|
+
else if (snd.isNone)
|
|
114
|
+
fst = new Some(result.value);
|
|
115
|
+
else
|
|
116
|
+
callback(new Okay(new Pair(result.value, snd.value)));
|
|
117
|
+
});
|
|
118
|
+
that.execute(controller.signal, (result) => {
|
|
119
|
+
if (result.isFail) {
|
|
120
|
+
if (fst.isNone)
|
|
121
|
+
controller.abort();
|
|
122
|
+
callback(result);
|
|
123
|
+
}
|
|
124
|
+
else if (fst.isNone)
|
|
125
|
+
snd = new Some(result.value);
|
|
126
|
+
else
|
|
127
|
+
callback(new Okay(new Pair(fst.value, result.value)));
|
|
128
|
+
});
|
|
129
|
+
return (reason) => controller.abort(reason);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
andThen(that) {
|
|
133
|
+
return this.and(that).mapOkay((pair) => pair.snd);
|
|
134
|
+
}
|
|
135
|
+
andWhen(that) {
|
|
136
|
+
return this.and(that).mapOkay((pair) => pair.fst);
|
|
137
|
+
}
|
|
138
|
+
or(that) {
|
|
139
|
+
return Task.of((callback) => {
|
|
140
|
+
const controller = new AbortController();
|
|
141
|
+
let fst = None.instance;
|
|
142
|
+
let snd = None.instance;
|
|
143
|
+
this.execute(controller.signal, (result) => {
|
|
144
|
+
if (result.isOkay) {
|
|
145
|
+
if (snd.isNone)
|
|
146
|
+
controller.abort();
|
|
147
|
+
callback(result);
|
|
148
|
+
}
|
|
149
|
+
else if (snd.isNone)
|
|
150
|
+
fst = new Some(result.value);
|
|
151
|
+
else
|
|
152
|
+
callback(new Fail(new Pair(result.value, snd.value)));
|
|
153
|
+
});
|
|
154
|
+
that.execute(controller.signal, (result) => {
|
|
155
|
+
if (result.isOkay) {
|
|
156
|
+
if (fst.isNone)
|
|
157
|
+
controller.abort();
|
|
158
|
+
callback(result);
|
|
159
|
+
}
|
|
160
|
+
else if (fst.isNone)
|
|
161
|
+
snd = new Some(result.value);
|
|
162
|
+
else
|
|
163
|
+
callback(new Fail(new Pair(fst.value, result.value)));
|
|
164
|
+
});
|
|
165
|
+
return (reason) => controller.abort(reason);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
orElse(that) {
|
|
169
|
+
return this.or(that).mapFail((pair) => pair.snd);
|
|
170
|
+
}
|
|
171
|
+
orErst(that) {
|
|
172
|
+
return this.or(that).mapFail((pair) => pair.fst);
|
|
173
|
+
}
|
|
174
|
+
flatMap(okayArrow, failArrow) {
|
|
175
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.isOkay
|
|
176
|
+
? okayArrow(result.value).execute(signal, callback)
|
|
177
|
+
: failArrow(result.value).execute(signal, callback)));
|
|
178
|
+
}
|
|
179
|
+
flatMapOkay(arrow) {
|
|
180
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.isOkay
|
|
181
|
+
? arrow(result.value).execute(signal, callback)
|
|
182
|
+
: callback(result)));
|
|
183
|
+
}
|
|
184
|
+
flatMapFail(arrow) {
|
|
185
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.isFail
|
|
186
|
+
? arrow(result.value).execute(signal, callback)
|
|
187
|
+
: callback(result)));
|
|
188
|
+
}
|
|
189
|
+
flatten() {
|
|
190
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.value.execute(signal, callback)));
|
|
191
|
+
}
|
|
192
|
+
flattenOkay() {
|
|
193
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.isOkay
|
|
194
|
+
? result.value.execute(signal, callback)
|
|
195
|
+
: callback(result)));
|
|
196
|
+
}
|
|
197
|
+
flattenFail() {
|
|
198
|
+
return new Task((signal, callback) => this.execute(signal, (result) => result.isFail
|
|
199
|
+
? result.value.execute(signal, callback)
|
|
200
|
+
: callback(result)));
|
|
201
|
+
}
|
|
202
|
+
flatMapUntil(okayArrow, failArrow) {
|
|
203
|
+
return new Task((signal, callback) => {
|
|
204
|
+
const trampoline = (task) => {
|
|
205
|
+
let option = new Some(task);
|
|
206
|
+
while (option.isSome) {
|
|
207
|
+
const task = option.value;
|
|
208
|
+
option = None.instance;
|
|
209
|
+
let isAsync = false;
|
|
210
|
+
task.flatMap(okayArrow, failArrow).execute(signal, (value) => {
|
|
211
|
+
const result = value.distribute();
|
|
212
|
+
if (result.isOkay)
|
|
213
|
+
callback(result.value);
|
|
214
|
+
else if (isAsync)
|
|
215
|
+
trampoline(result.value.toTask());
|
|
216
|
+
else
|
|
217
|
+
option = new Some(result.value.toTask());
|
|
218
|
+
});
|
|
219
|
+
isAsync = true;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
trampoline(this);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
flatMapOkayUntil(arrow) {
|
|
226
|
+
return new Task((signal, callback) => {
|
|
227
|
+
const trampoline = (task) => {
|
|
228
|
+
let option = new Some(task);
|
|
229
|
+
while (option.isSome) {
|
|
230
|
+
const task = option.value;
|
|
231
|
+
option = None.instance;
|
|
232
|
+
let isAsync = false;
|
|
233
|
+
task.flatMapOkay(arrow).execute(signal, (value) => {
|
|
234
|
+
const result = value.exchangeFail();
|
|
235
|
+
if (result.isOkay)
|
|
236
|
+
callback(result.value);
|
|
237
|
+
else if (isAsync)
|
|
238
|
+
trampoline(Task.okay(result.value));
|
|
239
|
+
else
|
|
240
|
+
option = new Some(Task.okay(result.value));
|
|
241
|
+
});
|
|
242
|
+
isAsync = true;
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
trampoline(this);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
flatMapFailUntil(arrow) {
|
|
249
|
+
return new Task((signal, callback) => {
|
|
250
|
+
const trampoline = (task) => {
|
|
251
|
+
let option = new Some(task);
|
|
252
|
+
while (option.isSome) {
|
|
253
|
+
const task = option.value;
|
|
254
|
+
option = None.instance;
|
|
255
|
+
let isAsync = false;
|
|
256
|
+
task.flatMapFail(arrow).execute(signal, (value) => {
|
|
257
|
+
const result = value.associateLeft();
|
|
258
|
+
if (result.isOkay)
|
|
259
|
+
callback(result.value);
|
|
260
|
+
else if (isAsync)
|
|
261
|
+
trampoline(Task.fail(result.value));
|
|
262
|
+
else
|
|
263
|
+
option = new Some(Task.fail(result.value));
|
|
264
|
+
});
|
|
265
|
+
isAsync = true;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
trampoline(this);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
commute() {
|
|
272
|
+
return new Task((signal, callback) => this.execute(signal, (result) => callback(result.commute())));
|
|
273
|
+
}
|
|
274
|
+
*effectMap(morphism) {
|
|
275
|
+
const value = yield this;
|
|
276
|
+
return morphism(value);
|
|
277
|
+
}
|
|
278
|
+
*effect() {
|
|
279
|
+
const value = yield this;
|
|
280
|
+
return value;
|
|
281
|
+
}
|
|
282
|
+
}
|
package/lib/text.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Option } from "./option.js";
|
|
2
|
+
import type { TotalOrder } from "./order.js";
|
|
3
|
+
import type { Ordering } from "./ordering.js";
|
|
4
|
+
import type { Semigroup } from "./semigroup.js";
|
|
5
|
+
export declare class Text implements Semigroup<Text>, TotalOrder<Text> {
|
|
6
|
+
readonly value: string;
|
|
7
|
+
constructor(value: string);
|
|
8
|
+
static of(value: string): Text;
|
|
9
|
+
toString(this: Text): string;
|
|
10
|
+
append(this: Text, that: Text): Text;
|
|
11
|
+
isSame(this: Text, that: Text): boolean;
|
|
12
|
+
isNotSame(this: Text, that: Text): boolean;
|
|
13
|
+
isLess(this: Text, that: Text): boolean;
|
|
14
|
+
isNotLess(this: Text, that: Text): boolean;
|
|
15
|
+
isMore(this: Text, that: Text): boolean;
|
|
16
|
+
isNotMore(this: Text, that: Text): boolean;
|
|
17
|
+
compare(this: Text, that: Text): Option<Ordering>;
|
|
18
|
+
max(this: Text, that: Text): Text;
|
|
19
|
+
min(this: Text, that: Text): Text;
|
|
20
|
+
clamp(this: Text, lower: Text, upper: Text): Text;
|
|
21
|
+
}
|
package/lib/text.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Some } from "./option.js";
|
|
2
|
+
export class Text {
|
|
3
|
+
value;
|
|
4
|
+
constructor(value) {
|
|
5
|
+
this.value = value;
|
|
6
|
+
}
|
|
7
|
+
static of(value) {
|
|
8
|
+
return new Text(value);
|
|
9
|
+
}
|
|
10
|
+
toString() {
|
|
11
|
+
return `Text(${JSON.stringify(this.value)})`;
|
|
12
|
+
}
|
|
13
|
+
append(that) {
|
|
14
|
+
return new Text(`${this.value}${that.value}`);
|
|
15
|
+
}
|
|
16
|
+
isSame(that) {
|
|
17
|
+
return this.value === that.value;
|
|
18
|
+
}
|
|
19
|
+
isNotSame(that) {
|
|
20
|
+
return this.value !== that.value;
|
|
21
|
+
}
|
|
22
|
+
isLess(that) {
|
|
23
|
+
return this.value < that.value;
|
|
24
|
+
}
|
|
25
|
+
isNotLess(that) {
|
|
26
|
+
return this.value >= that.value;
|
|
27
|
+
}
|
|
28
|
+
isMore(that) {
|
|
29
|
+
return this.value > that.value;
|
|
30
|
+
}
|
|
31
|
+
isNotMore(that) {
|
|
32
|
+
return this.value <= that.value;
|
|
33
|
+
}
|
|
34
|
+
compare(that) {
|
|
35
|
+
if (this.value < that.value)
|
|
36
|
+
return new Some("<");
|
|
37
|
+
if (this.value > that.value)
|
|
38
|
+
return new Some(">");
|
|
39
|
+
return new Some("=");
|
|
40
|
+
}
|
|
41
|
+
max(that) {
|
|
42
|
+
return this.value >= that.value ? this : that;
|
|
43
|
+
}
|
|
44
|
+
min(that) {
|
|
45
|
+
return this.value <= that.value ? this : that;
|
|
46
|
+
}
|
|
47
|
+
clamp(lower, upper) {
|
|
48
|
+
return this.max(lower).min(upper);
|
|
49
|
+
}
|
|
50
|
+
}
|
package/package.json
CHANGED
package/lib/errors.d.ts
DELETED