slang-ts 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 +94 -6
- package/dist/index.d.ts +3 -279
- package/dist/index.js +1 -1
- package/dist/src/atom.d.ts +40 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/internals.d.ts +26 -0
- package/dist/src/match.d.ts +51 -0
- package/dist/src/option.d.ts +85 -0
- package/dist/src/panic.d.ts +11 -0
- package/dist/src/pipe.d.ts +47 -0
- package/dist/src/println.d.ts +7 -0
- package/dist/src/result.d.ts +56 -0
- package/dist/src/safe-try.d.ts +28 -0
- package/dist/src/to.d.ts +15 -0
- package/dist/src/zip.d.ts +56 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Functional programming library for TypeScript.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A collection of functional programming utilities and other cool programming stuff from other languages such as rust implemented in TypeScript.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -19,17 +19,16 @@ npm i slang-ts
|
|
|
19
19
|
- [x] Expect
|
|
20
20
|
- [x] Unwrap (on Option)
|
|
21
21
|
- [x] Else (on unwrap)
|
|
22
|
-
- [
|
|
22
|
+
- [x] Panic
|
|
23
23
|
- [x] Zip, Unzip, zipWith
|
|
24
|
-
- [
|
|
25
|
-
- [ ] Catch
|
|
24
|
+
- [x] SafeTry
|
|
26
25
|
- [x] Match
|
|
27
26
|
- [x] MatchAll
|
|
28
|
-
- [
|
|
27
|
+
- [x] Pipe
|
|
29
28
|
- [ ] Map
|
|
30
29
|
- [x] To (converters, e.g. `userAtom.to('option')`)
|
|
31
30
|
- [ ] Promises and async utilities
|
|
32
|
-
- [ ]
|
|
31
|
+
- [ ] Currys
|
|
33
32
|
|
|
34
33
|
## Others (Planned)
|
|
35
34
|
|
|
@@ -46,6 +45,11 @@ import { Ok, Err } from "slang-ts";
|
|
|
46
45
|
|
|
47
46
|
// Or import multiple at once
|
|
48
47
|
import { option, Ok, Err, atom, match } from "slang-ts";
|
|
48
|
+
|
|
49
|
+
// Or import under namespace (not so performant)
|
|
50
|
+
import * as slang from "slang-ts";
|
|
51
|
+
|
|
52
|
+
slang.println("Hello world!");
|
|
49
53
|
```
|
|
50
54
|
|
|
51
55
|
### println
|
|
@@ -296,6 +300,90 @@ println(unzip(zipped));
|
|
|
296
300
|
// [[1, 2, 3], [4, 5, 6]]
|
|
297
301
|
```
|
|
298
302
|
|
|
303
|
+
### Pipe
|
|
304
|
+
|
|
305
|
+
Sequential function composition where each function receives a `Result` and returns a `Result`. Accepts plain values, Option, Result, or Atom as initial input.
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import { pipe, Ok, Err, option, type Result } from "slang-ts";
|
|
309
|
+
|
|
310
|
+
// Create pipeline functions
|
|
311
|
+
const add = (x: number) => (res: Result<number, string>) =>
|
|
312
|
+
res.isOk ? Ok(res.value + x) : res;
|
|
313
|
+
|
|
314
|
+
const multiply = (x: number) => (res: Result<number, string>) =>
|
|
315
|
+
res.isOk ? Ok(res.value * x) : res;
|
|
316
|
+
|
|
317
|
+
// Basic usage
|
|
318
|
+
const result = await pipe(5, add(3), multiply(2)).run();
|
|
319
|
+
println("Result:", result.value); // 16
|
|
320
|
+
|
|
321
|
+
// With Options as initial value
|
|
322
|
+
const fromOption = await pipe(option(10), add(5)).run();
|
|
323
|
+
println("From option:", fromOption.value); // 15
|
|
324
|
+
|
|
325
|
+
// With callbacks and error handling
|
|
326
|
+
const result = await pipe(5, add(3), multiply(2)).run({
|
|
327
|
+
onEach: ({ currentFn, prevResult }) => {
|
|
328
|
+
println("Executed:", currentFn);
|
|
329
|
+
},
|
|
330
|
+
onSuccess: (value) => println("Done:", value),
|
|
331
|
+
onError: (err) => println("Failed:", err.message),
|
|
332
|
+
allowErrors: false, // stops pipeline on first Err
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### SafeTry
|
|
337
|
+
|
|
338
|
+
Wraps potentially throwing functions in try-catch, returning a `Result<T, string>`. Always needs to be awaited as its async.
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
import { safeTry } from "slang-ts";
|
|
342
|
+
|
|
343
|
+
const result = await safeTry(() => {
|
|
344
|
+
if (denom === 0) throw new Error("Cannot divide by zero");
|
|
345
|
+
return num / denom;
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (result.isOk) {
|
|
349
|
+
println("Result:", result.value);
|
|
350
|
+
} else {
|
|
351
|
+
println("Error:", result.error);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Async functions work the same way
|
|
355
|
+
const data = await safeTry(async () => {
|
|
356
|
+
const res = await fetch("/api/user");
|
|
357
|
+
return res.json();
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
if (data.isOk) {
|
|
361
|
+
println("User:", data.value);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Re-throw critical errors instead of capturing
|
|
365
|
+
await safeTry(() => {
|
|
366
|
+
throw new Error("Critical!");
|
|
367
|
+
}, { throw: true });
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Panic
|
|
371
|
+
|
|
372
|
+
Throws an error immediately. Use for unrecoverable failures.
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
import { panic } from "slang-ts";
|
|
376
|
+
|
|
377
|
+
function processUser(user: User | null) {
|
|
378
|
+
if (!user) panic("User cannot be null");
|
|
379
|
+
return user.name;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Guard clause pattern
|
|
383
|
+
const config = loadConfig();
|
|
384
|
+
if (!config.apiKey) panic("API key required");
|
|
385
|
+
```
|
|
386
|
+
|
|
299
387
|
And more are to be implemented in coming versions...
|
|
300
388
|
|
|
301
389
|
## Code Samples
|
package/dist/index.d.ts
CHANGED
|
@@ -1,281 +1,5 @@
|
|
|
1
|
-
export declare const println: (...args: unknown[]) => void;
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
* -
|
|
5
|
-
* - `atom`: Converts `Some<string>` to `Atom` or returns symbol Atom
|
|
6
|
-
* - `result`: Wraps values into `Ok`, `None` into `Err`
|
|
2
|
+
* Slang - Functional programming utilities for TypeScript
|
|
3
|
+
* Re-exports all types and functions from the modular src folder.
|
|
7
4
|
*/
|
|
8
|
-
export
|
|
9
|
-
export declare function _to<T extends string>(value: Option<T>, target: "atom"): Atom<T>;
|
|
10
|
-
export declare function _to<T extends string>(value: Atom<T>, target: "option"): Option<string>;
|
|
11
|
-
export declare function _to<T extends string>(value: Atom<T>, target: "atom"): Atom<T>;
|
|
12
|
-
export declare function _to<T, E = string>(value: Option<T>, target: "result"): Result<T, E>;
|
|
13
|
-
export declare function _to<E = string>(value: Atom<any>, target: "result"): Result<string, E>;
|
|
14
|
-
/** Unique symbol to brand atoms */
|
|
15
|
-
declare const __atom__: unique symbol;
|
|
16
|
-
/** Atom type carrying the original name for hover/type info */
|
|
17
|
-
export type Atom<T extends string = string> = symbol & {
|
|
18
|
-
readonly [__atom__]: T;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Creates a new, unique atom (non-interned)
|
|
22
|
-
* @param name Name of the atom (used for hover/description)
|
|
23
|
-
* @example
|
|
24
|
-
* const a = atom("loading");
|
|
25
|
-
* typeof a; // Atom<"loading">
|
|
26
|
-
*/
|
|
27
|
-
/**
|
|
28
|
-
* Creates a new, unique atom (non-interned)
|
|
29
|
-
* @param name Name of the atom (used for hover/description)
|
|
30
|
-
* @returns `Atom<T>` with chainable `to()`
|
|
31
|
-
* @example
|
|
32
|
-
* const ready = atom("ready");
|
|
33
|
-
* ready.to("option"); // Some("ready")
|
|
34
|
-
* ready.to("result"); // Ok("ready")
|
|
35
|
-
*/
|
|
36
|
-
/** Methods available on an Atom */
|
|
37
|
-
export interface AtomMethods<T extends string> {
|
|
38
|
-
/** Returns the same atom */
|
|
39
|
-
to(target: "atom"): Atom<T>;
|
|
40
|
-
/** Returns `Option<string>` using the atom description
|
|
41
|
-
* @example atom("ready").to("option") // Some("ready")
|
|
42
|
-
*/
|
|
43
|
-
to(target: "option"): Option<string>;
|
|
44
|
-
/** Returns `Ok<string>` using the atom description
|
|
45
|
-
* @example atom("ready").to("result") // Ok("ready")
|
|
46
|
-
*/
|
|
47
|
-
to(target: "result"): Result<string, string>;
|
|
48
|
-
}
|
|
49
|
-
export declare function atom<const T extends string>(name: T): Atom<T> & AtomMethods<T>;
|
|
50
|
-
declare const __result__: unique symbol;
|
|
51
|
-
export type Ok<T> = {
|
|
52
|
-
type: "Ok";
|
|
53
|
-
value: T;
|
|
54
|
-
readonly isOk: true;
|
|
55
|
-
readonly isErr: false;
|
|
56
|
-
readonly [__result__]: true;
|
|
57
|
-
};
|
|
58
|
-
export type Err<E> = {
|
|
59
|
-
type: "Err";
|
|
60
|
-
error: E;
|
|
61
|
-
readonly isOk: false;
|
|
62
|
-
readonly isErr: true;
|
|
63
|
-
readonly [__result__]: true;
|
|
64
|
-
};
|
|
65
|
-
export type Result<T, E> = (Ok<T> | Err<E>) & ResultMethods<T>;
|
|
66
|
-
/**
|
|
67
|
-
* Creates a new, successful result
|
|
68
|
-
* @param value Value of the result
|
|
69
|
-
* @example
|
|
70
|
-
* const a = Ok("hello");
|
|
71
|
-
* typeof a; // Ok<"hello">
|
|
72
|
-
*/
|
|
73
|
-
/** Methods available on a Result */
|
|
74
|
-
export interface ResultMethods<T> {
|
|
75
|
-
/** Unwraps the value, throwing for Err
|
|
76
|
-
* @example maybeFail().expect("must succeed")
|
|
77
|
-
*/
|
|
78
|
-
expect(msg?: string): T;
|
|
79
|
-
/** Returns an unwrap chain that throws if no else is provided
|
|
80
|
-
* Use `.else(valueOrFn)` to supply a fallback for Err.
|
|
81
|
-
* - If `Ok`, `.else(...)` returns the inner value and ignores fallback.
|
|
82
|
-
* - If `Err`, `.else(...)` returns the fallback; if a function, it receives the error.
|
|
83
|
-
*/
|
|
84
|
-
unwrap(): {
|
|
85
|
-
/** Fallback value or function to recover from Err
|
|
86
|
-
* If a function is provided, it is called with the Err's error.
|
|
87
|
-
* Returns the unwrapped value (Ok) or the provided fallback (Err).
|
|
88
|
-
*/ else(fallback: T | ((error: any) => T)): T;
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
/** Creates a new, successful result */
|
|
92
|
-
export declare function Ok<T>(value: T): Ok<T> & ResultMethods<T>;
|
|
93
|
-
/**
|
|
94
|
-
* Creates a new, failed result
|
|
95
|
-
* @param error Error of the result
|
|
96
|
-
* @example
|
|
97
|
-
* const a = Err("error");
|
|
98
|
-
* typeof a; // Err<"error">
|
|
99
|
-
*/
|
|
100
|
-
/** Creates a new, failed result */
|
|
101
|
-
export declare function Err<E>(error: E): Err<E> & ResultMethods<never>;
|
|
102
|
-
declare const __option__: unique symbol;
|
|
103
|
-
export type Some<T> = {
|
|
104
|
-
type: "Some";
|
|
105
|
-
value: T;
|
|
106
|
-
readonly isSome: true;
|
|
107
|
-
readonly isNone: false;
|
|
108
|
-
readonly [__option__]: true;
|
|
109
|
-
};
|
|
110
|
-
export type None = {
|
|
111
|
-
type: "None";
|
|
112
|
-
readonly isSome: false;
|
|
113
|
-
readonly isNone: true;
|
|
114
|
-
readonly [__option__]: true;
|
|
115
|
-
};
|
|
116
|
-
export type Option<T> = (Some<T> | None) & OptionMethods<T>;
|
|
117
|
-
export type NonTruthy = null | undefined | "";
|
|
118
|
-
/**
|
|
119
|
-
* Creates a new option type from a value
|
|
120
|
-
* @param value - the value to be made an option
|
|
121
|
-
* @tutorial The returned option will be Some if the value is truthy, and None if it is not (null,undefined,Nan,'')
|
|
122
|
-
* @example
|
|
123
|
-
* const b = option("hello");
|
|
124
|
-
* typeof b; // Some<"hello">
|
|
125
|
-
* const c = option(null);
|
|
126
|
-
* typeof c; // None
|
|
127
|
-
* const d = option(undefined);
|
|
128
|
-
* typeof d; // None
|
|
129
|
-
* const e = option(0);
|
|
130
|
-
* typeof e; // Some<number>
|
|
131
|
-
* const f = option("");
|
|
132
|
-
* typeof f; // None
|
|
133
|
-
* const g = option(false);
|
|
134
|
-
* typeof g; // Some<boolean>
|
|
135
|
-
*/
|
|
136
|
-
/** Methods available on an Option */
|
|
137
|
-
export interface OptionMethods<T> {
|
|
138
|
-
/** Returns the same option */
|
|
139
|
-
to(target: "option"): Option<T>;
|
|
140
|
-
/** Converts `Some<string>` to `Atom<string>`; throws for `None` or non-string */
|
|
141
|
-
to(target: "atom"): Atom<T & string>;
|
|
142
|
-
/** Converts to `Result<T, string>`; `None` becomes `Err("Value is None")` */
|
|
143
|
-
to(target: "result"): Result<T | (T extends string ? never : Atom<string>), string>;
|
|
144
|
-
/**
|
|
145
|
-
* Unwraps the option, throwing if `None`.
|
|
146
|
-
* @throws Error with provided message or default.
|
|
147
|
-
* @example
|
|
148
|
-
* option(42).expect(); // 42
|
|
149
|
-
* option("").expect("must be present"); // throws
|
|
150
|
-
*/
|
|
151
|
-
expect(msg?: string): T;
|
|
152
|
-
/** Returns an unwrap chain that MUST be completed with `.else(...)`.
|
|
153
|
-
* If `.else(...)` is not chained, an error is thrown ("Expected else").
|
|
154
|
-
* - If `Some`, `.else(...)` is required but ignored for outcome; returns the inner value.
|
|
155
|
-
* - If `None`, `.else(...)` provides fallback; if a function, it is called with `undefined`.
|
|
156
|
-
* - Fallback result must be truthy; otherwise, throws ("Fallback must be truthy").
|
|
157
|
-
*/
|
|
158
|
-
unwrap(): {
|
|
159
|
-
/** Fallback value or transformer to recover from `None`.
|
|
160
|
-
* - Function form receives `undefined` and must return a truthy value.
|
|
161
|
-
* - Direct value must be truthy.
|
|
162
|
-
* Returns the inner value for `Some`, or the validated fallback for `None`.
|
|
163
|
-
*/ else(fallback: T | ((value: T | undefined) => T)): T;
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Creates a new option type from a value.
|
|
168
|
-
* - Truthy values become `Some<T>`; `null|undefined|""` become `None`.
|
|
169
|
-
* - Provides chainable `.to()` and `.expect()` helpers.
|
|
170
|
-
* @example
|
|
171
|
-
* option("hi").expect(); // "hi"
|
|
172
|
-
* option("").expect("cannot be empty"); // throws Error("cannot be empty")
|
|
173
|
-
* option("state").to("atom"); // Atom<"state">
|
|
174
|
-
* option(null).to("result"); // Err("Value is None")
|
|
175
|
-
*/
|
|
176
|
-
export declare function option<T>(value: T | NonTruthy): Option<T> & OptionMethods<T>;
|
|
177
|
-
/**
|
|
178
|
-
* Pattern matching for `Result` and `Option` — exhaustiveness enforced.
|
|
179
|
-
*
|
|
180
|
-
* Returns the value returned by the selected handler. If all handlers return
|
|
181
|
-
* `Result` or `Option`, TypeScript will infer that automatically.
|
|
182
|
-
*/
|
|
183
|
-
export declare function match<T, E, R>(value: Result<T, E> | (Result<any, any> & ResultMethods<any>), patterns: {
|
|
184
|
-
Ok: ((v: Ok<T>) => R) | (() => R);
|
|
185
|
-
Err: ((e: Err<E>) => R) | (() => R);
|
|
186
|
-
}): R;
|
|
187
|
-
export declare function match<T, R>(value: Some<T> | None, patterns: {
|
|
188
|
-
Some: ((v: Some<T>) => R) | (() => R);
|
|
189
|
-
None: ((v: None) => R) | (() => R);
|
|
190
|
-
}): R;
|
|
191
|
-
/**
|
|
192
|
-
* Allowed keys in matchAll patterns.
|
|
193
|
-
* - Strings, numbers, and Atom descriptions.
|
|
194
|
-
* - Booleans are represented as "true" | "false" strings
|
|
195
|
-
*/
|
|
196
|
-
type MatchKey = string | number | symbol;
|
|
197
|
-
/**
|
|
198
|
-
* Type-safe pattern object: must always have `_` fallback.
|
|
199
|
-
*/
|
|
200
|
-
type MatchPatterns<V, R> = {
|
|
201
|
-
[K in MatchKey]?: (v: V) => R;
|
|
202
|
-
} & {
|
|
203
|
-
_: () => R;
|
|
204
|
-
};
|
|
205
|
-
/**
|
|
206
|
-
* Matches a value against literal or Atom cases by *semantic name*.
|
|
207
|
-
* - Supports string, number, booleans and Atom (symbol) values.
|
|
208
|
-
* - Unsupported will throw an error. (objects, arrays, functions, etc)
|
|
209
|
-
* - For Atoms, uses their description as a key (e.g. atom("ready") → "ready").
|
|
210
|
-
* - Requires a `_` default handler.
|
|
211
|
-
*
|
|
212
|
-
* @example
|
|
213
|
-
* matchAll(ready, {
|
|
214
|
-
* 1: () => println("One"),
|
|
215
|
-
* 2: () => println("Two"),
|
|
216
|
-
* 0: () => println("Zero"),
|
|
217
|
-
* true: () => println("True"),
|
|
218
|
-
* false: () => println("False"),
|
|
219
|
-
* ready: () => println("Ready!"),
|
|
220
|
-
* failed: () => println("Failed!"),
|
|
221
|
-
* _: () => println("Unknown!"),
|
|
222
|
-
* });
|
|
223
|
-
*/
|
|
224
|
-
export declare function matchAll<T extends MatchKey | boolean, R>(value: T, patterns: MatchPatterns<T, R>): R;
|
|
225
|
-
/**
|
|
226
|
-
* Combines multiple collections element-wise into tuples.
|
|
227
|
-
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
228
|
-
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
229
|
-
* - Stops at shortest collection by default; use `fillValue` to extend to longest.
|
|
230
|
-
* - Transforms columns into rows for parallel iteration.
|
|
231
|
-
* @param inputs Collections of the same type to combine
|
|
232
|
-
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
233
|
-
* @returns Array of tuples, one per index position
|
|
234
|
-
* @example
|
|
235
|
-
* zip([[1, 2], ['a', 'b']]); // [[1, 'a'], [2, 'b']]
|
|
236
|
-
* zip([[1, 2], ['a']], { fillValue: 'x' }); // [[1, 'a'], [2, 'x']]
|
|
237
|
-
* const s1 = new Set([1, 2]); const s2 = new Set([3, 4]);
|
|
238
|
-
* zip([s1, s2], { includeValues: true }); // [[1, 3], [2, 4]]
|
|
239
|
-
*/
|
|
240
|
-
export declare function zip<T extends readonly any[]>(inputs: {
|
|
241
|
-
[K in keyof T]: Iterable<T[K]> | {
|
|
242
|
-
[key: string]: T[K];
|
|
243
|
-
};
|
|
244
|
-
}, options?: {
|
|
245
|
-
fillValue?: T[number];
|
|
246
|
-
includeValues?: boolean;
|
|
247
|
-
}): T[number][][];
|
|
248
|
-
/**
|
|
249
|
-
* Combines multiple collections element-wise and transforms each tuple.
|
|
250
|
-
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
251
|
-
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
252
|
-
* - Applies a function to each set of corresponding elements.
|
|
253
|
-
* - Useful for aggregating, computing, or transforming aligned data.
|
|
254
|
-
* @param inputs Collections of the same type to combine
|
|
255
|
-
* @param fn Transform function applied to each tuple
|
|
256
|
-
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
257
|
-
* @returns Array of transformed results
|
|
258
|
-
* @example
|
|
259
|
-
* zipWith([[1, 2], [3, 4]], (t) => t[0] + t[1]); // [4, 6]
|
|
260
|
-
* zipWith([[1, 2], [10]], (t) => t.reduce((a, b) => a + b, 0), { fillValue: 0 }); // [11, 2]
|
|
261
|
-
*/
|
|
262
|
-
export declare function zipWith<T extends readonly any[], R>(inputs: {
|
|
263
|
-
[K in keyof T]: Iterable<T[K]> | {
|
|
264
|
-
[key: string]: T[K];
|
|
265
|
-
};
|
|
266
|
-
}, fn: (tuple: T[number][]) => R, options?: {
|
|
267
|
-
fillValue?: T[number];
|
|
268
|
-
includeValues?: boolean;
|
|
269
|
-
}): R[];
|
|
270
|
-
/**
|
|
271
|
-
* Unzips an array of tuples back into separate arrays.
|
|
272
|
-
* - Reverses the zip operation: transforms rows to columns.
|
|
273
|
-
* - Useful for separating previously combined collections.
|
|
274
|
-
* @param zipped Array of tuples (rows) to transpose
|
|
275
|
-
* @returns Array of arrays (columns), one per tuple position
|
|
276
|
-
* @example
|
|
277
|
-
* const zipped = [[1, 'a'], [2, 'b'], [3, 'c']];
|
|
278
|
-
* unzip(zipped); // [[1, 2, 3], ['a', 'b', 'c']]
|
|
279
|
-
*/
|
|
280
|
-
export declare function unzip<T>(zipped: T[][]): T[][];
|
|
281
|
-
export {};
|
|
5
|
+
export * from "./src";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var W=(G)=>{let B=globalThis?.queueMicrotask;if(typeof B==="function")B(G);else Promise.resolve().then(G)},C=(G)=>G!=null&&typeof G==="object"&&("type"in G)&&(G.type==="Ok"||G.type==="Err"),F=(G)=>G!=null&&typeof G==="object"&&("isSome"in G)&&("isNone"in G),z=(G)=>G!=null&&typeof G==="object"&&typeof G.valueOf?.()==="symbol";function q(G){if(z(G))return{ok:!0,value:G.valueOf().description};if(C(G)){if(G.isOk)return{ok:!0,value:G.value};return{ok:!1,error:typeof G.error==="string"?G.error:String(G.error)}}if(F(G)){if(G.isSome)return{ok:!0,value:G.value};return{ok:!1,error:"Option was None"}}return{ok:!0,value:G}}var O=(...G)=>{globalThis?.console?.log?.(...G)};function E(G){throw Error(G)}function L(G){let B=Object.freeze({type:"Ok",value:G,isOk:!0,isErr:!1});return{...B,expect:(J)=>B.value,unwrap:()=>{let J=!1;return W(()=>{}),{else(Q){return J=!0,B.value}}}}}function I(G){return{...Object.freeze({type:"Err",error:G,isOk:!1,isErr:!0}),expect:(J)=>{throw Error(J??G)},unwrap:()=>{let J=!1;return W(()=>{if(!J)throw Error(G)}),{else(Q){if(J=!0,typeof Q==="function")return Q(G);return Q}}}}}var K=(G)=>{return G===null||G===void 0||G===""||Number.isNaN(G)||G===1/0||G===-1/0};function R(G){if(K(G))throw Error("Cannot wrap null, undefined, NaN, or empty string in Some");return Object.freeze({type:"Some",value:G,isSome:!0,isNone:!1})}var g=Object.freeze({type:"None",isSome:!1,isNone:!0}),N=null;function M(G){N=G}function U(G){let B=K(G)?g:R(G);return{...B,to:($)=>{if(!N)throw Error("Converter not initialized");return N(B,$)},expect:($)=>{if(B.isSome)return B.value;throw Error($??"Expected Some, got None")},unwrap:()=>{let $=!1,X=B;return W(()=>{if(!$)throw Error("Expected else")}),{else(j){if($=!0,X.isSome)return X.value;let Y=typeof j==="function"?j(void 0):j;if(K(Y))throw Error("Fallback must be truthy");return Y}}}}}var P=null;function _(G){P=G}function S(G){let B=Symbol(G),D=Object(B),J=(Q)=>{if(!P)throw Error("Converter not initialized");return P(B,Q)};return D.to=J,D}var T=(G)=>G!=null&&typeof G==="object"&&("isSome"in G)&&("isNone"in G);function V(G,B){if(G&&(G.type==="Ok"||G.type==="Err"))throw Error("Cannot convert a Result to any other type");switch(B){case"option":{if(T(G))return G;if(typeof G==="symbol")return U(G.description);return U(G)}case"atom":{if(T(G)){if(G.isNone)throw Error("Cannot convert None to Atom");if(typeof G.value!=="string")throw Error("Only string values can be converted to Atom");return S(G.value)}if(typeof G==="symbol")return G;throw Error(`Cannot convert type ${typeof G} to Atom`)}case"result":{if(T(G))return G.isSome?L(G.value):I("Value is None");if(typeof G==="symbol")return L(G.description);return L(G)}default:throw Error(`Invalid target: ${B}`)}}M(V);_(V);function w(G,B){let D=B[G.type];if(!D)throw Error(`Non-exhaustive match — missing handler for '${G.type}'`);return D(G)}var b=(G)=>{return typeof G==="string"||typeof G==="number"||typeof G==="boolean"||typeof G==="symbol"};function k(G,B){let D=(X)=>typeof X?.valueOf==="function"?X.valueOf():X,J=(X)=>typeof X==="symbol"?X.description:void 0,Q=D(G);if(!b(Q))throw Error(`Unsupported match all value type: ${typeof Q}`);let H=J(Q)??Q,$=typeof H==="boolean"||typeof H==="number"?String(H):H;if($!=null&&$ in B)return B[$](G);return B._()}function h(G,B=!1){if(!B&&!Array.isArray(G))throw Error("Only arrays allowed when includeValues=false");if(Array.isArray(G))return G;if(G instanceof Set)return Array.from(G);return Object.values(G)}function A(G,B){let{fillValue:D,includeValues:J=!1}=B||{};if(G.length===0)return[];let Q=G.map((Y)=>h(Y,J)),H=Math.max(...Q.map((Y)=>Y.length)),$=Math.min(...Q.map((Y)=>Y.length)),X=D===void 0?$:H,j=[];for(let Y=0;Y<X;Y++)j.push(Q.map((Z)=>Y<Z.length?Z[Y]:D));return j}function y(G,B,D){return A(G,D).map(B)}function f(G){if(G.length===0)return[];let B=G[0]?.length??0,D=Array.from({length:B},()=>[]);for(let J of G)J.forEach((Q,H)=>D[H]?.push(Q));return D}async function m(G,B){let D=B?.throw??!1;try{let J=await G(),Q=q(J);if(Q.ok)return L(Q.value);return I(Q.error)}catch(J){let Q=J instanceof Error?J.message:String(J);if(D)throw J instanceof Error?J:Error(Q);return I(Q)}}function x(G){return G.error??"Unknown error"}function d(G){let B=q(G);if(B.ok)return L(B.value);return I(B.error)}async function c(G,B){try{let D=await G(B);if(!C(D))return I("Pipeline function must return a Result");return D}catch(D){let J=D instanceof Error?D.message:String(D);return I(J)}}function p(G,...B){return{async run(D){let{onEach:J,onSuccess:Q,onError:H,allowErrors:$=!1}=D??{},X=d(G);for(let j=0;j<B.length;j++){let Y=B[j],Z=B[j+1];if(X.isErr&&!$)return H?.(Error(x(X))),X;X=await c(Y,X),J?.({prevResult:X,currentFn:Y.name||`fn${j+1}`,nextFn:Z?Z.name||`fn${j+2}`:void 0})}if(X.isOk)Q?.(X.value);else H?.(Error(x(X)));return X}}}export{y as zipWith,A as zip,f as unzip,W as scheduleMicrotask,m as safeTry,O as println,p as pipe,E as panic,U as option,k as matchAll,w as match,K as isFalsy,S as atom,V as _to,L as Ok,I as Err};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Option } from "./option";
|
|
2
|
+
import type { Result } from "./result";
|
|
3
|
+
/** Unique symbol to brand atoms */
|
|
4
|
+
declare const __atom__: unique symbol;
|
|
5
|
+
/** Atom type carrying the original name for hover/type info */
|
|
6
|
+
export type Atom<T extends string = string> = symbol & {
|
|
7
|
+
readonly [__atom__]: T;
|
|
8
|
+
};
|
|
9
|
+
/** Methods available on an Atom */
|
|
10
|
+
export interface AtomMethods<T extends string> {
|
|
11
|
+
/** Returns the same atom */
|
|
12
|
+
to(target: "atom"): Atom<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Returns `Option<string>` using the atom description.
|
|
15
|
+
* @example atom("ready").to("option") // Some("ready")
|
|
16
|
+
*/
|
|
17
|
+
to(target: "option"): Option<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Returns `Ok<string>` using the atom description.
|
|
20
|
+
* @example atom("ready").to("result") // Ok("ready")
|
|
21
|
+
*/
|
|
22
|
+
to(target: "result"): Result<string, string>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sets the _to converter function (called from to.ts to break circular dep).
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function setToConverter(fn: (value: any, target: string) => any): void;
|
|
29
|
+
/**
|
|
30
|
+
* Creates a new, unique atom (non-interned).
|
|
31
|
+
* - Atoms are symbols with additional methods for type-safe conversions.
|
|
32
|
+
* @param name - Name of the atom (used for hover/description).
|
|
33
|
+
* @returns `Atom<T>` with chainable `to()` method for conversions.
|
|
34
|
+
* @example
|
|
35
|
+
* const ready = atom("ready");
|
|
36
|
+
* ready.to("option"); // Some("ready")
|
|
37
|
+
* ready.to("result"); // Ok("ready")
|
|
38
|
+
*/
|
|
39
|
+
export declare function atom<const T extends string>(name: T): Atom<T> & AtomMethods<T>;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { scheduleMicrotask } from "./internals";
|
|
2
|
+
export { println } from "./println";
|
|
3
|
+
export { panic } from "./panic";
|
|
4
|
+
export { Ok, Err } from "./result";
|
|
5
|
+
export type { Result, ResultMethods, Ok as OkType, Err as ErrType } from "./result";
|
|
6
|
+
export { option, isFalsy } from "./option";
|
|
7
|
+
export type { Option, OptionMethods, Some, None, NonTruthy } from "./option";
|
|
8
|
+
export { atom } from "./atom";
|
|
9
|
+
export type { Atom, AtomMethods } from "./atom";
|
|
10
|
+
import "./to";
|
|
11
|
+
export { _to } from "./to";
|
|
12
|
+
export { match, matchAll } from "./match";
|
|
13
|
+
export { zip, zipWith, unzip } from "./zip";
|
|
14
|
+
export { safeTry } from "./safe-try";
|
|
15
|
+
export { pipe } from "./pipe";
|
|
16
|
+
export type { PipeFn, PipeEachContext, PipeRunOptions, Pipeline } from "./pipe";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Result } from "./result";
|
|
2
|
+
import type { Option } from "./option";
|
|
3
|
+
/**
|
|
4
|
+
* Schedules a microtask; falls back to Promise if unavailable.
|
|
5
|
+
* Used internally for deferred error handling in unwrap chains.
|
|
6
|
+
*/
|
|
7
|
+
export declare const scheduleMicrotask: (fn: () => void) => void;
|
|
8
|
+
/** Type guard for Result */
|
|
9
|
+
export declare const isResult: (value: unknown) => value is Result<unknown, unknown>;
|
|
10
|
+
/** Type guard for Option */
|
|
11
|
+
export declare const isOption: (value: unknown) => value is Option<unknown>;
|
|
12
|
+
/** Type guard for Atom (boxed symbol) */
|
|
13
|
+
export declare const isAtom: (value: unknown) => boolean;
|
|
14
|
+
/** Evaluated value result type */
|
|
15
|
+
export type EvaluatedValue = {
|
|
16
|
+
ok: true;
|
|
17
|
+
value: unknown;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Extracts inner value from Slang types (Atom, Result, Option) or plain values.
|
|
24
|
+
* Returns a discriminated union indicating success or failure.
|
|
25
|
+
*/
|
|
26
|
+
export declare function evaluateValue<T>(value: T): EvaluatedValue;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Ok, Err, Result, ResultMethods } from "./result";
|
|
2
|
+
import type { Some, None } from "./option";
|
|
3
|
+
/**
|
|
4
|
+
* Pattern matching for `Result` and `Option` — exhaustiveness enforced.
|
|
5
|
+
*
|
|
6
|
+
* Returns the value returned by the selected handler. If all handlers return
|
|
7
|
+
* `Result` or `Option`, TypeScript will infer that automatically.
|
|
8
|
+
*/
|
|
9
|
+
export declare function match<T, E, R>(value: Result<T, E> | (Result<any, any> & ResultMethods<any>), patterns: {
|
|
10
|
+
Ok: ((v: Ok<T>) => R) | (() => R);
|
|
11
|
+
Err: ((e: Err<E>) => R) | (() => R);
|
|
12
|
+
}): R;
|
|
13
|
+
export declare function match<T, R>(value: Some<T> | None, patterns: {
|
|
14
|
+
Some: ((v: Some<T>) => R) | (() => R);
|
|
15
|
+
None: ((v: None) => R) | (() => R);
|
|
16
|
+
}): R;
|
|
17
|
+
/**
|
|
18
|
+
* Allowed keys in matchAll patterns.
|
|
19
|
+
* - Strings, numbers, and Atom descriptions.
|
|
20
|
+
* - Booleans are represented as "true" | "false" strings
|
|
21
|
+
*/
|
|
22
|
+
type MatchKey = string | number | symbol;
|
|
23
|
+
/**
|
|
24
|
+
* Type-safe pattern object: must always have `_` fallback.
|
|
25
|
+
*/
|
|
26
|
+
type MatchPatterns<V, R> = {
|
|
27
|
+
[K in MatchKey]?: (v: V) => R;
|
|
28
|
+
} & {
|
|
29
|
+
_: () => R;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Matches a value against literal or Atom cases by *semantic name*.
|
|
33
|
+
* - Supports string, number, booleans and Atom (symbol) values.
|
|
34
|
+
* - Unsupported will throw an error. (objects, arrays, functions, etc)
|
|
35
|
+
* - For Atoms, uses their description as a key (e.g. atom("ready") → "ready").
|
|
36
|
+
* - Requires a `_` default handler.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* matchAll(ready, {
|
|
40
|
+
* 1: () => println("One"),
|
|
41
|
+
* 2: () => println("Two"),
|
|
42
|
+
* 0: () => println("Zero"),
|
|
43
|
+
* true: () => println("True"),
|
|
44
|
+
* false: () => println("False"),
|
|
45
|
+
* ready: () => println("Ready!"),
|
|
46
|
+
* failed: () => println("Failed!"),
|
|
47
|
+
* _: () => println("Unknown!"),
|
|
48
|
+
* });
|
|
49
|
+
*/
|
|
50
|
+
export declare function matchAll<T extends MatchKey | boolean, R>(value: T, patterns: MatchPatterns<T, R>): R;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Atom } from "./atom";
|
|
2
|
+
import type { Result } from "./result";
|
|
3
|
+
declare const __option__: unique symbol;
|
|
4
|
+
export type Some<T> = {
|
|
5
|
+
type: "Some";
|
|
6
|
+
value: T;
|
|
7
|
+
readonly isSome: true;
|
|
8
|
+
readonly isNone: false;
|
|
9
|
+
readonly [__option__]: true;
|
|
10
|
+
};
|
|
11
|
+
export type None = {
|
|
12
|
+
type: "None";
|
|
13
|
+
readonly isSome: false;
|
|
14
|
+
readonly isNone: true;
|
|
15
|
+
readonly [__option__]: true;
|
|
16
|
+
};
|
|
17
|
+
export type Option<T> = (Some<T> | None) & OptionMethods<T>;
|
|
18
|
+
/** Values treated as falsy by Option */
|
|
19
|
+
export type NonTruthy = null | undefined | "";
|
|
20
|
+
/** Methods available on an Option */
|
|
21
|
+
export interface OptionMethods<T> {
|
|
22
|
+
/** Returns the same option */
|
|
23
|
+
to(target: "option"): Option<T>;
|
|
24
|
+
/** Converts `Some<string>` to `Atom<string>`; throws for `None` or non-string */
|
|
25
|
+
to(target: "atom"): Atom<T & string>;
|
|
26
|
+
/** Converts to `Result<T, string>`; `None` becomes `Err("Value is None")` */
|
|
27
|
+
to(target: "result"): Result<T | (T extends string ? never : Atom<string>), string>;
|
|
28
|
+
/**
|
|
29
|
+
* Unwraps the option, throwing if `None`.
|
|
30
|
+
* @throws Error with provided message or default.
|
|
31
|
+
* @example
|
|
32
|
+
* option(42).expect(); // 42
|
|
33
|
+
* option("").expect("must be present"); // throws
|
|
34
|
+
*/
|
|
35
|
+
expect(msg?: string): T;
|
|
36
|
+
/**
|
|
37
|
+
* Returns an unwrap chain that MUST be completed with `.else(...)`.
|
|
38
|
+
* If `.else(...)` is not chained, an error is thrown ("Expected else").
|
|
39
|
+
* - If `Some`, `.else(...)` is required but ignored for outcome; returns the inner value.
|
|
40
|
+
* - If `None`, `.else(...)` provides fallback; if a function, it is called with `undefined`.
|
|
41
|
+
* - Fallback result must be truthy; otherwise, throws ("Fallback must be truthy").
|
|
42
|
+
*/
|
|
43
|
+
unwrap(): {
|
|
44
|
+
/**
|
|
45
|
+
* Fallback value or transformer to recover from `None`.
|
|
46
|
+
* - Function form receives `undefined` and must return a truthy value.
|
|
47
|
+
* - Direct value must be truthy.
|
|
48
|
+
* Returns the inner value for `Some`, or the validated fallback for `None`.
|
|
49
|
+
*/
|
|
50
|
+
else(fallback: T | ((value: T | undefined) => T)): T;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Checks if a value is falsy for Option purposes.
|
|
55
|
+
* Falsy: null, undefined, empty string, NaN, Infinity, -Infinity
|
|
56
|
+
*/
|
|
57
|
+
export declare const isFalsy: (value: any) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Creates a new truthy option.
|
|
60
|
+
* @param value - the value of the option
|
|
61
|
+
* @throws Error if value is falsy
|
|
62
|
+
* @example
|
|
63
|
+
* const a = Some("hello");
|
|
64
|
+
* typeof a; // Some<"hello">
|
|
65
|
+
*/
|
|
66
|
+
declare function Some<T>(value: T): Some<T>;
|
|
67
|
+
/** Singleton None value */
|
|
68
|
+
declare const None: None;
|
|
69
|
+
/**
|
|
70
|
+
* Sets the _to converter function (called from to.ts to break circular dep).
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export declare function setToConverter(fn: (value: any, target: string) => any): void;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new option type from a value.
|
|
76
|
+
* - Truthy values become `Some<T>`; `null|undefined|""` become `None`.
|
|
77
|
+
* - Provides chainable `.to()`, `.expect()`, and `.unwrap()` helpers.
|
|
78
|
+
* @example
|
|
79
|
+
* option("hi").expect(); // "hi"
|
|
80
|
+
* option("").expect("cannot be empty"); // throws Error("cannot be empty")
|
|
81
|
+
* option("state").to("atom"); // Atom<"state">
|
|
82
|
+
* option(null).to("result"); // Err("Value is None")
|
|
83
|
+
*/
|
|
84
|
+
export declare function option<T>(value: T | NonTruthy): Option<T> & OptionMethods<T>;
|
|
85
|
+
export { Some, None };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throws an error immediately.
|
|
3
|
+
* Use for unrecoverable failures or guard clauses.
|
|
4
|
+
* @param message - Error message
|
|
5
|
+
* @example
|
|
6
|
+
* panic("Critical!");
|
|
7
|
+
*
|
|
8
|
+
* // Guard clause pattern
|
|
9
|
+
* if (!config.apiKey) panic("API key required");
|
|
10
|
+
*/
|
|
11
|
+
export declare function panic(message: string): never;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Result } from "./result";
|
|
2
|
+
/** Function that transforms one Result into another */
|
|
3
|
+
export type PipeFn<T = any, E = any> = (input: Result<T, E>) => Result<any, any> | Promise<Result<any, any>>;
|
|
4
|
+
/** Context passed to onEach callback */
|
|
5
|
+
export type PipeEachContext = {
|
|
6
|
+
prevResult: Result<any, any>;
|
|
7
|
+
currentFn: string;
|
|
8
|
+
nextFn: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
/** Options for pipeline execution */
|
|
11
|
+
export type PipeRunOptions = {
|
|
12
|
+
/** Called after each function executes */
|
|
13
|
+
onEach?: (ctx: PipeEachContext) => void;
|
|
14
|
+
/** Called when pipeline completes successfully */
|
|
15
|
+
onSuccess?: (value: any) => void;
|
|
16
|
+
/** Called when pipeline encounters an error (only when allowErrors is false) */
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
/** If true, continues pipeline even when a function returns Err */
|
|
19
|
+
allowErrors?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/** Pipeline object returned by pipe() */
|
|
22
|
+
export type Pipeline<T, E> = {
|
|
23
|
+
run: (options?: PipeRunOptions) => Promise<Result<T, E>>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Creates a pipeline for sequential function composition.
|
|
27
|
+
* Each function receives the previous Result and returns a new Result.
|
|
28
|
+
*
|
|
29
|
+
* @param initial - Starting value (plain value, Option, Result, or Atom)
|
|
30
|
+
* @param fns - Pipeline functions that transform Results
|
|
31
|
+
* @returns Pipeline object with `.run()` method
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const add = (x: number) => (res: Result<number, string>) =>
|
|
35
|
+
* res.isOk ? Ok(res.value + x) : res;
|
|
36
|
+
*
|
|
37
|
+
* const result = await pipe(5, add(3), add(2)).run();
|
|
38
|
+
* // result.value === 10
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const result = await pipe(option(5), add(3)).run({
|
|
42
|
+
* onEach: ({ currentFn, prevResult }) => console.log(currentFn, prevResult),
|
|
43
|
+
* onSuccess: (value) => console.log("Done:", value),
|
|
44
|
+
* allowErrors: false,
|
|
45
|
+
* });
|
|
46
|
+
*/
|
|
47
|
+
export declare function pipe<T, E = string>(initial: T, ...fns: PipeFn[]): Pipeline<any, E>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
declare const __result__: unique symbol;
|
|
2
|
+
export type Ok<T> = {
|
|
3
|
+
type: "Ok";
|
|
4
|
+
value: T;
|
|
5
|
+
readonly isOk: true;
|
|
6
|
+
readonly isErr: false;
|
|
7
|
+
readonly [__result__]: true;
|
|
8
|
+
};
|
|
9
|
+
export type Err<E> = {
|
|
10
|
+
type: "Err";
|
|
11
|
+
error: E;
|
|
12
|
+
readonly isOk: false;
|
|
13
|
+
readonly isErr: true;
|
|
14
|
+
readonly [__result__]: true;
|
|
15
|
+
};
|
|
16
|
+
/** Discriminated union: mutually exclusive Ok or Err */
|
|
17
|
+
export type Result<T, E> = (Ok<T> | Err<E>) & ResultMethods<T>;
|
|
18
|
+
/** Methods available on a Result */
|
|
19
|
+
export interface ResultMethods<T> {
|
|
20
|
+
/**
|
|
21
|
+
* Unwraps the value, throwing for Err.
|
|
22
|
+
* @example maybeFail().expect("must succeed")
|
|
23
|
+
*/
|
|
24
|
+
expect(msg?: string): T;
|
|
25
|
+
/**
|
|
26
|
+
* Returns an unwrap chain that throws if no else is provided.
|
|
27
|
+
* Use `.else(valueOrFn)` to supply a fallback for Err.
|
|
28
|
+
* - If `Ok`, `.else(...)` returns the inner value and ignores fallback.
|
|
29
|
+
* - If `Err`, `.else(...)` returns the fallback; if a function, it receives the error.
|
|
30
|
+
*/
|
|
31
|
+
unwrap(): {
|
|
32
|
+
/**
|
|
33
|
+
* Fallback value or function to recover from Err.
|
|
34
|
+
* If a function is provided, it is called with the Err's error.
|
|
35
|
+
* Returns the unwrapped value (Ok) or the provided fallback (Err).
|
|
36
|
+
*/
|
|
37
|
+
else(fallback: T | ((error: any) => T)): T;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Creates a new, successful result.
|
|
42
|
+
* @param value Value of the result
|
|
43
|
+
* @example
|
|
44
|
+
* const a = Ok("hello");
|
|
45
|
+
* typeof a; // Ok<"hello">
|
|
46
|
+
*/
|
|
47
|
+
export declare function Ok<T>(value: T): Ok<T> & ResultMethods<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new, failed result with a string error message.
|
|
50
|
+
* @param error Error message (must be a string)
|
|
51
|
+
* @example
|
|
52
|
+
* const a = Err("something went wrong");
|
|
53
|
+
* typeof a; // Err<string>
|
|
54
|
+
*/
|
|
55
|
+
export declare function Err(error: string): Err<string> & ResultMethods<never>;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Result } from "./result";
|
|
2
|
+
/** Options for safeTry behavior */
|
|
3
|
+
type SafeTryOptions = {
|
|
4
|
+
/** If true, re-throws the error instead of capturing it */
|
|
5
|
+
throw?: boolean;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a function in try-catch, returns `Result<T, string>`.
|
|
9
|
+
* - Always returns a Promise resolving to Ok or Err.
|
|
10
|
+
* - Internally evaluates return values from Atom, Result, or Option types.
|
|
11
|
+
* - Use `{ throw: true }` to re-throw errors instead of capturing.
|
|
12
|
+
*
|
|
13
|
+
* @param fn - Function to execute (sync or async)
|
|
14
|
+
* @param options - `{ throw?: boolean }`
|
|
15
|
+
* @returns Promise of `Result<T, string>`
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const result = await safeTry(() => "Hello");
|
|
19
|
+
* if (result.isOk) println(result.value);
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const result = await safeTry(() => {
|
|
23
|
+
* throw new Error("Oops!");
|
|
24
|
+
* });
|
|
25
|
+
* if (result.isErr) println(result.error);
|
|
26
|
+
*/
|
|
27
|
+
export declare function safeTry<T>(fn: () => T | Promise<T>, options?: SafeTryOptions): Promise<Result<T, string>>;
|
|
28
|
+
export {};
|
package/dist/src/to.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Atom } from "./atom";
|
|
2
|
+
import type { Option } from "./option";
|
|
3
|
+
import type { Result } from "./result";
|
|
4
|
+
/**
|
|
5
|
+
* Converts between Slang types.
|
|
6
|
+
* - `option`: Wraps primitive or symbol description into `Option`
|
|
7
|
+
* - `atom`: Converts `Some<string>` to `Atom` or returns symbol Atom
|
|
8
|
+
* - `result`: Wraps values into `Ok`, `None` into `Err`
|
|
9
|
+
*/
|
|
10
|
+
export declare function _to<T>(value: Option<T>, target: "option"): Option<T>;
|
|
11
|
+
export declare function _to<T extends string>(value: Option<T>, target: "atom"): Atom<T>;
|
|
12
|
+
export declare function _to<T extends string>(value: Atom<T>, target: "option"): Option<string>;
|
|
13
|
+
export declare function _to<T extends string>(value: Atom<T>, target: "atom"): Atom<T>;
|
|
14
|
+
export declare function _to<T, E = string>(value: Option<T>, target: "result"): Result<T, E>;
|
|
15
|
+
export declare function _to<E = string>(value: Atom<any>, target: "result"): Result<string, E>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combines multiple collections element-wise into tuples.
|
|
3
|
+
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
4
|
+
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
5
|
+
* - Stops at shortest collection by default; use `fillValue` to extend to longest.
|
|
6
|
+
* - Transforms columns into rows for parallel iteration.
|
|
7
|
+
* @param inputs Collections of the same type to combine
|
|
8
|
+
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
9
|
+
* @returns Array of tuples, one per index position
|
|
10
|
+
* @example
|
|
11
|
+
* zip([[1, 2], ['a', 'b']]); // [[1, 'a'], [2, 'b']]
|
|
12
|
+
* zip([[1, 2], ['a']], { fillValue: 'x' }); // [[1, 'a'], [2, 'x']]
|
|
13
|
+
* const s1 = new Set([1, 2]); const s2 = new Set([3, 4]);
|
|
14
|
+
* zip([s1, s2], { includeValues: true }); // [[1, 3], [2, 4]]
|
|
15
|
+
*/
|
|
16
|
+
export declare function zip<T extends readonly any[]>(inputs: {
|
|
17
|
+
[K in keyof T]: Iterable<T[K]> | {
|
|
18
|
+
[key: string]: T[K];
|
|
19
|
+
};
|
|
20
|
+
}, options?: {
|
|
21
|
+
fillValue?: T[number];
|
|
22
|
+
includeValues?: boolean;
|
|
23
|
+
}): T[number][][];
|
|
24
|
+
/**
|
|
25
|
+
* Combines multiple collections element-wise and transforms each tuple.
|
|
26
|
+
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
27
|
+
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
28
|
+
* - Applies a function to each set of corresponding elements.
|
|
29
|
+
* - Useful for aggregating, computing, or transforming aligned data.
|
|
30
|
+
* @param inputs Collections of the same type to combine
|
|
31
|
+
* @param fn Transform function applied to each tuple
|
|
32
|
+
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
33
|
+
* @returns Array of transformed results
|
|
34
|
+
* @example
|
|
35
|
+
* zipWith([[1, 2], [3, 4]], (t) => t[0] + t[1]); // [4, 6]
|
|
36
|
+
* zipWith([[1, 2], [10]], (t) => t.reduce((a, b) => a + b, 0), { fillValue: 0 }); // [11, 2]
|
|
37
|
+
*/
|
|
38
|
+
export declare function zipWith<T extends readonly any[], R>(inputs: {
|
|
39
|
+
[K in keyof T]: Iterable<T[K]> | {
|
|
40
|
+
[key: string]: T[K];
|
|
41
|
+
};
|
|
42
|
+
}, fn: (tuple: T[number][]) => R, options?: {
|
|
43
|
+
fillValue?: T[number];
|
|
44
|
+
includeValues?: boolean;
|
|
45
|
+
}): R[];
|
|
46
|
+
/**
|
|
47
|
+
* Unzips an array of tuples back into separate arrays.
|
|
48
|
+
* - Reverses the zip operation: transforms rows to columns.
|
|
49
|
+
* - Useful for separating previously combined collections.
|
|
50
|
+
* @param zipped Array of tuples (rows) to transpose
|
|
51
|
+
* @returns Array of arrays (columns), one per tuple position
|
|
52
|
+
* @example
|
|
53
|
+
* const zipped = [[1, 'a'], [2, 'b'], [3, 'c']];
|
|
54
|
+
* unzip(zipped); // [[1, 2, 3], ['a', 'b', 'c']]
|
|
55
|
+
*/
|
|
56
|
+
export declare function unzip<T>(zipped: T[][]): T[][];
|