slang-ts 0.0.7 → 0.0.9
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 +389 -142
- package/dist/index.d.ts +656 -3
- package/dist/index.js +2 -1
- package/package.json +34 -16
- package/dist/src/atom.d.ts +0 -51
- package/dist/src/index.d.ts +0 -16
- package/dist/src/internals.d.ts +0 -26
- package/dist/src/match.d.ts +0 -58
- package/dist/src/option.d.ts +0 -97
- package/dist/src/panic.d.ts +0 -11
- package/dist/src/pipe.d.ts +0 -47
- package/dist/src/println.d.ts +0 -7
- package/dist/src/result.d.ts +0 -68
- package/dist/src/safe-try.d.ts +0 -28
- package/dist/src/to.d.ts +0 -15
- package/dist/src/zip.d.ts +0 -56
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,658 @@
|
|
|
1
|
+
//#region src/result.d.ts
|
|
2
|
+
declare const __result__: unique symbol;
|
|
3
|
+
export type Ok<T> = {
|
|
4
|
+
type: "Ok";
|
|
5
|
+
value: T;
|
|
6
|
+
readonly isOk: true;
|
|
7
|
+
readonly isErr: false;
|
|
8
|
+
readonly [__result__]: true;
|
|
9
|
+
};
|
|
10
|
+
export type Err<E> = {
|
|
11
|
+
type: "Err";
|
|
12
|
+
error: E;
|
|
13
|
+
readonly isOk: false;
|
|
14
|
+
readonly isErr: true;
|
|
15
|
+
readonly [__result__]: true;
|
|
16
|
+
};
|
|
17
|
+
/** Discriminated union: mutually exclusive Ok or Err */
|
|
18
|
+
type Result<T, E> = (Ok<T> | Err<E>) & ResultMethods<T>;
|
|
19
|
+
/** Methods available on a Result */
|
|
20
|
+
interface ResultMethods<T> {
|
|
21
|
+
/**
|
|
22
|
+
* Unwraps the value, throwing for Err.
|
|
23
|
+
* @example maybeFail().expect("must succeed")
|
|
24
|
+
*/
|
|
25
|
+
expect(msg?: string): T;
|
|
26
|
+
/**
|
|
27
|
+
* Returns an unwrap chain that throws if no else is provided.
|
|
28
|
+
* Use `.else(valueOrFn)` to supply a fallback for Err.
|
|
29
|
+
* - If `Ok`, `.else(...)` returns the inner value and ignores fallback.
|
|
30
|
+
* - If `Err`, `.else(...)` returns the fallback; if a function, it receives the error.
|
|
31
|
+
*/
|
|
32
|
+
unwrap(): {
|
|
33
|
+
/**
|
|
34
|
+
* Fallback value or function to recover from Err.
|
|
35
|
+
* If a function is provided, it is called with the Err's error.
|
|
36
|
+
* Returns the unwrapped value (Ok) or the provided fallback (Err).
|
|
37
|
+
*/
|
|
38
|
+
else(fallback: T | ((error: any) => T)): T;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Transforms the inner value if `Ok`, returns same `Err` if `Err`.
|
|
42
|
+
* - If fn returns `undefined`, returns original Result (no new allocation).
|
|
43
|
+
* - If fn throws, returns `Err(message)`.
|
|
44
|
+
* - Supports async functions, returning `Promise<Result<U, string>>`.
|
|
45
|
+
* @example
|
|
46
|
+
* Ok(5).andThen(x => x * 2); // Ok(10)
|
|
47
|
+
* Err("fail").andThen(x => x * 2); // Err("fail")
|
|
48
|
+
* Ok(5).andThen(x => undefined); // Ok(5) - original
|
|
49
|
+
* await Ok(5).andThen(async x => x); // Ok(5)
|
|
50
|
+
*/
|
|
51
|
+
andThen<U>(fn: (value: T) => U | Promise<U>): Result<U, string> | Promise<Result<U, string>>;
|
|
52
|
+
}
|
|
1
53
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
54
|
+
* Creates a new, successful result.
|
|
55
|
+
* @param value Value of the result
|
|
56
|
+
* @example
|
|
57
|
+
* const a = Ok("hello");
|
|
58
|
+
* typeof a; // Ok<"hello">
|
|
4
59
|
*/
|
|
5
|
-
export
|
|
60
|
+
export declare function Ok<T>(value: T): Ok<T> & ResultMethods<T>;
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new, failed result with a string error message.
|
|
63
|
+
* @param error Error message (must be a string)
|
|
64
|
+
* @example
|
|
65
|
+
* const a = Err("something went wrong");
|
|
66
|
+
* typeof a; // Err<string>
|
|
67
|
+
*/
|
|
68
|
+
export declare function Err(error: string): Err<string> & ResultMethods<never>;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/atom.d.ts
|
|
71
|
+
/** Unique symbol to brand atoms */
|
|
72
|
+
declare const __atom__: unique symbol;
|
|
73
|
+
/** Atom type carrying the original name for hover/type info */
|
|
74
|
+
type Atom<T extends string = string> = symbol & {
|
|
75
|
+
readonly [__atom__]: T;
|
|
76
|
+
};
|
|
77
|
+
/** Methods available on an Atom */
|
|
78
|
+
interface AtomMethods<T extends string> {
|
|
79
|
+
/** Returns the same atom */
|
|
80
|
+
to(target: "atom"): Atom<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Returns `Option<string>` using the atom description.
|
|
83
|
+
* @example atom("ready").to("option") // Some("ready")
|
|
84
|
+
*/
|
|
85
|
+
to(target: "option"): Option<string>;
|
|
86
|
+
/**
|
|
87
|
+
* Returns `Ok<string>` using the atom description.
|
|
88
|
+
* @example atom("ready").to("result") // Ok("ready")
|
|
89
|
+
*/
|
|
90
|
+
to(target: "result"): Result<string, string>;
|
|
91
|
+
/**
|
|
92
|
+
* Transforms the atom description, returns new Atom.
|
|
93
|
+
* - If fn returns `undefined`, returns original Atom (no new allocation).
|
|
94
|
+
* - If fn returns non-string, panics.
|
|
95
|
+
* - If fn throws, panics.
|
|
96
|
+
* - Sync only (no async support for Atom).
|
|
97
|
+
* @example
|
|
98
|
+
* atom("hello").andThen(s => s.toUpperCase()); // Atom("HELLO")
|
|
99
|
+
* atom("test").andThen(s => undefined); // Atom("test") - original
|
|
100
|
+
*/
|
|
101
|
+
andThen<U extends string>(fn: (value: T) => U | undefined): Atom<U> & AtomMethods<U>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates a new, unique atom (non-interned).
|
|
105
|
+
* - Atoms are symbols with additional methods for type-safe conversions.
|
|
106
|
+
* @param name - Name of the atom (used for hover/description).
|
|
107
|
+
* @returns `Atom<T>` with chainable `to()` method for conversions.
|
|
108
|
+
* @example
|
|
109
|
+
* const ready = atom("ready");
|
|
110
|
+
* ready.to("option"); // Some("ready")
|
|
111
|
+
* ready.to("result"); // Ok("ready")
|
|
112
|
+
*/
|
|
113
|
+
export declare function atom<const T extends string>(name: T): Atom<T> & AtomMethods<T>;
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/option.d.ts
|
|
116
|
+
declare const __option__: unique symbol;
|
|
117
|
+
type Some<T> = {
|
|
118
|
+
type: "Some";
|
|
119
|
+
value: T;
|
|
120
|
+
readonly isSome: true;
|
|
121
|
+
readonly isNone: false;
|
|
122
|
+
readonly [__option__]: true;
|
|
123
|
+
};
|
|
124
|
+
type None = {
|
|
125
|
+
type: "None";
|
|
126
|
+
readonly isSome: false;
|
|
127
|
+
readonly isNone: true;
|
|
128
|
+
readonly [__option__]: true;
|
|
129
|
+
};
|
|
130
|
+
type Option<T> = (Some<T> | None) & OptionMethods<T>;
|
|
131
|
+
/** Values treated as falsy by Option */
|
|
132
|
+
type NonTruthy = null | undefined | "";
|
|
133
|
+
/** Methods available on an Option */
|
|
134
|
+
interface OptionMethods<T> {
|
|
135
|
+
/** Returns the same option */
|
|
136
|
+
to(target: "option"): Option<T>;
|
|
137
|
+
/** Converts `Some<string>` to `Atom<string>`; throws for `None` or non-string */
|
|
138
|
+
to(target: "atom"): Atom<T & string>;
|
|
139
|
+
/** Converts to `Result<T, string>`; `None` becomes `Err("Value is None")` */
|
|
140
|
+
to(target: "result"): Result<T | (T extends string ? never : Atom<string>), string>;
|
|
141
|
+
/**
|
|
142
|
+
* Unwraps the option, throwing if `None`.
|
|
143
|
+
* @throws Error with provided message or default.
|
|
144
|
+
* @example
|
|
145
|
+
* option(42).expect(); // 42
|
|
146
|
+
* option("").expect("must be present"); // throws
|
|
147
|
+
*/
|
|
148
|
+
expect(msg?: string): T;
|
|
149
|
+
/**
|
|
150
|
+
* Returns an unwrap chain that MUST be completed with `.else(...)`.
|
|
151
|
+
* If `.else(...)` is not chained, an error is thrown ("Expected else").
|
|
152
|
+
* - If `Some`, `.else(...)` is required but ignored for outcome; returns the inner value.
|
|
153
|
+
* - If `None`, `.else(...)` provides fallback; if a function, it is called with `undefined`.
|
|
154
|
+
* - Fallback result must be truthy; otherwise, throws ("Fallback must be truthy").
|
|
155
|
+
*/
|
|
156
|
+
unwrap(): {
|
|
157
|
+
/**
|
|
158
|
+
* Fallback value or transformer to recover from `None`.
|
|
159
|
+
* - Function form receives `undefined` and must return a truthy value.
|
|
160
|
+
* - Direct value must be truthy.
|
|
161
|
+
* Returns the inner value for `Some`, or the validated fallback for `None`.
|
|
162
|
+
*/
|
|
163
|
+
else(fallback: T | ((value: T | undefined) => T)): T;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Transforms the inner value if `Some`, returns `None` if `None`.
|
|
167
|
+
* - If fn returns `undefined`, returns original Option (no new allocation).
|
|
168
|
+
* - If fn throws, returns `None`.
|
|
169
|
+
* - Supports async functions, returning `Promise<Option<U>>`.
|
|
170
|
+
* @example
|
|
171
|
+
* option(5).andThen(x => x * 2); // Some(10)
|
|
172
|
+
* option(null).andThen(x => x * 2); // None
|
|
173
|
+
* option(5).andThen(x => undefined); // Some(5) - original
|
|
174
|
+
* await option(5).andThen(async x => x); // Some(5)
|
|
175
|
+
*/
|
|
176
|
+
andThen<U>(fn: (value: T) => U | Promise<U>): Option<U> | Promise<Option<U>>;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Checks if a value is falsy for Option purposes.
|
|
180
|
+
* Falsy: null, undefined, empty string, NaN, Infinity, -Infinity
|
|
181
|
+
*/
|
|
182
|
+
export declare const isFalsy: (value: any) => boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Creates a new truthy option.
|
|
185
|
+
* @param value - the value of the option
|
|
186
|
+
* @throws Error if value is falsy
|
|
187
|
+
* @example
|
|
188
|
+
* const a = Some("hello");
|
|
189
|
+
* typeof a; // Some<"hello">
|
|
190
|
+
*/
|
|
191
|
+
declare function Some<T>(value: T): Some<T>;
|
|
192
|
+
/** Singleton None value */
|
|
193
|
+
declare const None: None;
|
|
194
|
+
/**
|
|
195
|
+
* Creates a new option type from a value.
|
|
196
|
+
* - Truthy values become `Some<T>`; `null|undefined|""` become `None`.
|
|
197
|
+
* - Provides chainable `.to()`, `.expect()`, and `.unwrap()` helpers.
|
|
198
|
+
* @example
|
|
199
|
+
* option("hi").expect(); // "hi"
|
|
200
|
+
* option("").expect("cannot be empty"); // throws Error("cannot be empty")
|
|
201
|
+
* option("state").to("atom"); // Atom<"state">
|
|
202
|
+
* option(null).to("result"); // Err("Value is None")
|
|
203
|
+
*/
|
|
204
|
+
export declare function option<T>(value: T | NonTruthy): Option<T> & OptionMethods<T>;
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/internals.d.ts
|
|
207
|
+
/**
|
|
208
|
+
* Schedules a microtask; falls back to Promise if unavailable.
|
|
209
|
+
* Used internally for deferred error handling in unwrap chains.
|
|
210
|
+
*/
|
|
211
|
+
export declare const scheduleMicrotask: (fn: () => void) => void;
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/println.d.ts
|
|
214
|
+
type EnvironmentMode = "development" | "production" | "dev" | "prod";
|
|
215
|
+
type PrintFn = (line: string) => void;
|
|
216
|
+
type EnvironmentOptions = {
|
|
217
|
+
printFn?: PrintFn | null;
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Sets the runtime environment for dev-only utilities.
|
|
221
|
+
* Idempotent — safe to call any number of times, in any order; the last call wins.
|
|
222
|
+
* Accepts a mode (full words or short forms: "development"/"dev", "production"/"prod")
|
|
223
|
+
* or options `{ printFn }` to route println through an existing logger instead of
|
|
224
|
+
* the console — useful in production, where logs go somewhere real.
|
|
225
|
+
* Pass `{ printFn: null }` to switch back to the console.
|
|
226
|
+
*/
|
|
227
|
+
export declare const setEnvironment: (next: EnvironmentMode | EnvironmentOptions) => void;
|
|
228
|
+
/**
|
|
229
|
+
* Prints a line to the console — args joined with spaces, newline appended.
|
|
230
|
+
* When a custom printFn is set, the line goes to it instead, in every mode.
|
|
231
|
+
* Otherwise production mode is silent, so dev chatter never leaks to prod logs.
|
|
232
|
+
*/
|
|
233
|
+
export declare const println: (...args: unknown[]) => void;
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/panic.d.ts
|
|
236
|
+
/**
|
|
237
|
+
* Throws an error immediately.
|
|
238
|
+
* Use for unrecoverable failures or guard clauses.
|
|
239
|
+
* @param message - Error message
|
|
240
|
+
* @example
|
|
241
|
+
* panic("Critical!");
|
|
242
|
+
*
|
|
243
|
+
* // Guard clause pattern
|
|
244
|
+
* if (!config.apiKey) panic("API key required");
|
|
245
|
+
*/
|
|
246
|
+
export declare function panic(message: string): never;
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/options.d.ts
|
|
249
|
+
/**
|
|
250
|
+
* Resolves the usable inner type of a value.
|
|
251
|
+
* - `Some<U>` / `Ok<U>` contribute `U`.
|
|
252
|
+
* - `None`, `Err`, null, undefined, and empty string contribute nothing.
|
|
253
|
+
* - Raw values contribute themselves.
|
|
254
|
+
*/
|
|
255
|
+
type OptionsValue<T> = T extends {
|
|
256
|
+
isErr: true;
|
|
257
|
+
} | {
|
|
258
|
+
isNone: true;
|
|
259
|
+
} | null | undefined | "" ? never : T extends {
|
|
260
|
+
isSome: true;
|
|
261
|
+
value: infer U;
|
|
262
|
+
} | {
|
|
263
|
+
isOk: true;
|
|
264
|
+
value: infer U;
|
|
265
|
+
} ? U : T;
|
|
266
|
+
/**
|
|
267
|
+
* Returns the first usable value from a list as an `Ok`, or the fallback
|
|
268
|
+
* `Err` if none is usable.
|
|
269
|
+
*
|
|
270
|
+
* Normalizes heterogeneous values — raw values, `Option`s, and `Result`s
|
|
271
|
+
* from different sources — when all you care about is whether any of them
|
|
272
|
+
* is usable. A value is usable when its unwrapped inner value is truthy;
|
|
273
|
+
* `None`, `Err`, null, undefined, `""`, NaN, and Infinity are skipped.
|
|
274
|
+
* Note that `0` and `false` are usable, matching `option()` semantics.
|
|
275
|
+
*
|
|
276
|
+
* @param values - Values to inspect in order; first usable one wins.
|
|
277
|
+
* @param fallback - `Err` returned when no value is usable (default `Err("No value!")`).
|
|
278
|
+
* @returns `Ok` of the first usable inner value, or the fallback.
|
|
279
|
+
* @example
|
|
280
|
+
* const a = null;
|
|
281
|
+
* const b = option(undefined);
|
|
282
|
+
* const c = Ok(true);
|
|
283
|
+
* const d = Err("nope!");
|
|
284
|
+
* Options([a, b, c, d]); // Ok(true) - c is usable
|
|
285
|
+
*
|
|
286
|
+
* const nothing = Options([a, option(null), Err("nope!")]); // Err("No value!")
|
|
287
|
+
*/
|
|
288
|
+
export declare function Options<T extends readonly unknown[]>(values: T, fallback?: Err<string> & ResultMethods<never>): Result<OptionsValue<T[number]>, string>;
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/to.d.ts
|
|
291
|
+
/**
|
|
292
|
+
* Converts between Slang types.
|
|
293
|
+
* - `option`: Wraps primitive or symbol description into `Option`
|
|
294
|
+
* - `atom`: Converts `Some<string>` to `Atom` or returns symbol Atom
|
|
295
|
+
* - `result`: Wraps values into `Ok`, `None` into `Err`
|
|
296
|
+
*/
|
|
297
|
+
export declare function _to<T>(value: Option<T>, target: "option"): Option<T>;
|
|
298
|
+
export declare function _to<T extends string>(value: Option<T>, target: "atom"): Atom<T>;
|
|
299
|
+
export declare function _to<T extends string>(value: Atom<T>, target: "option"): Option<string>;
|
|
300
|
+
export declare function _to<T extends string>(value: Atom<T>, target: "atom"): Atom<T>;
|
|
301
|
+
export declare function _to<T, E = string>(value: Option<T>, target: "result"): Result<T, E>;
|
|
302
|
+
export declare function _to<E = string>(value: Atom<any>, target: "result"): Result<string, E>;
|
|
303
|
+
//#endregion
|
|
304
|
+
//#region src/match.d.ts
|
|
305
|
+
/**
|
|
306
|
+
* Pattern matching for `Result` and `Option` — exhaustiveness enforced.
|
|
307
|
+
*
|
|
308
|
+
* Returns the value returned by the selected handler. If all handlers return
|
|
309
|
+
* `Result` or `Option`, TypeScript will infer that automatically.
|
|
310
|
+
*/
|
|
311
|
+
export declare function match<T, E, R>(value: Result<T, E> | (Result<any, any> & ResultMethods<any>), patterns: {
|
|
312
|
+
Ok: ((v: Ok<T>) => R) | (() => R);
|
|
313
|
+
Err: ((e: Err<E>) => R) | (() => R);
|
|
314
|
+
}): R;
|
|
315
|
+
export declare function match<T, R>(value: Some<T> | None, patterns: {
|
|
316
|
+
Some: ((v: Some<T>) => R) | (() => R);
|
|
317
|
+
None: ((v: None) => R) | (() => R);
|
|
318
|
+
}): R;
|
|
319
|
+
/**
|
|
320
|
+
* Allowed keys in matchAll patterns.
|
|
321
|
+
* - Strings, numbers, and Atom descriptions.
|
|
322
|
+
* - Booleans are represented as "true" | "false" strings
|
|
323
|
+
*/
|
|
324
|
+
type MatchKey = string | number | symbol;
|
|
325
|
+
/**
|
|
326
|
+
* Type-safe pattern object: must always have `_` fallback.
|
|
327
|
+
*/
|
|
328
|
+
type MatchPatterns<V> = { [K in MatchKey]?: (v: V) => unknown; } & {
|
|
329
|
+
_: () => unknown;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Extracts return types from all handlers in a patterns object as a union.
|
|
333
|
+
* Allows each arm to return a different type.
|
|
334
|
+
*/
|
|
335
|
+
type InferReturnTypes<P> = { [K in keyof P]: P[K] extends ((...args: any[]) => infer R) ? R : never; }[keyof P];
|
|
336
|
+
/**
|
|
337
|
+
* Matches a value against literal or Atom cases by *semantic name*.
|
|
338
|
+
* - Supports string, number, booleans and Atom (symbol) values.
|
|
339
|
+
* - Unsupported will throw an error. (objects, arrays, functions, etc)
|
|
340
|
+
* - For Atoms, uses their description as a key (e.g. atom("ready") → "ready").
|
|
341
|
+
* - Requires a `_` default handler.
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* matchAll(ready, {
|
|
345
|
+
* 1: () => println("One"),
|
|
346
|
+
* 2: () => println("Two"),
|
|
347
|
+
* 0: () => println("Zero"),
|
|
348
|
+
* true: () => println("True"),
|
|
349
|
+
* false: () => println("False"),
|
|
350
|
+
* ready: () => println("Ready!"),
|
|
351
|
+
* failed: () => println("Failed!"),
|
|
352
|
+
* _: () => println("Unknown!"),
|
|
353
|
+
* });
|
|
354
|
+
*/
|
|
355
|
+
export declare function matchAll<T extends MatchKey | boolean, P extends MatchPatterns<T>>(value: T, patterns: P): InferReturnTypes<P>;
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/zip.d.ts
|
|
358
|
+
/**
|
|
359
|
+
* Combines multiple collections element-wise into tuples.
|
|
360
|
+
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
361
|
+
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
362
|
+
* - Stops at shortest collection by default; use `fillValue` to extend to longest.
|
|
363
|
+
* - Transforms columns into rows for parallel iteration.
|
|
364
|
+
* @param inputs Collections of the same type to combine
|
|
365
|
+
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
366
|
+
* @returns Array of tuples, one per index position
|
|
367
|
+
* @example
|
|
368
|
+
* zip([[1, 2], ['a', 'b']]); // [[1, 'a'], [2, 'b']]
|
|
369
|
+
* zip([[1, 2], ['a']], { fillValue: 'x' }); // [[1, 'a'], [2, 'x']]
|
|
370
|
+
* const s1 = new Set([1, 2]); const s2 = new Set([3, 4]);
|
|
371
|
+
* zip([s1, s2], { includeValues: true }); // [[1, 3], [2, 4]]
|
|
372
|
+
*/
|
|
373
|
+
export declare function zip<T extends readonly any[]>(inputs: { [K in keyof T]: Iterable<T[K]> | {
|
|
374
|
+
[key: string]: T[K];
|
|
375
|
+
}; }, options?: {
|
|
376
|
+
fillValue?: T[number];
|
|
377
|
+
includeValues?: boolean;
|
|
378
|
+
}): T[number][][];
|
|
379
|
+
/**
|
|
380
|
+
* Combines multiple collections element-wise and transforms each tuple.
|
|
381
|
+
* - All inputs must be the same type (all arrays, all Sets, or all objects).
|
|
382
|
+
* - By default, only arrays are allowed; set `includeValues: true` to extract values from Sets/Objects.
|
|
383
|
+
* - Applies a function to each set of corresponding elements.
|
|
384
|
+
* - Useful for aggregating, computing, or transforming aligned data.
|
|
385
|
+
* @param inputs Collections of the same type to combine
|
|
386
|
+
* @param fn Transform function applied to each tuple
|
|
387
|
+
* @param options Configuration: `fillValue` extends to longest, `includeValues` extracts values from Sets/Objects (default: false)
|
|
388
|
+
* @returns Array of transformed results
|
|
389
|
+
* @example
|
|
390
|
+
* zipWith([[1, 2], [3, 4]], (t) => t[0] + t[1]); // [4, 6]
|
|
391
|
+
* zipWith([[1, 2], [10]], (t) => t.reduce((a, b) => a + b, 0), { fillValue: 0 }); // [11, 2]
|
|
392
|
+
*/
|
|
393
|
+
export declare function zipWith<T extends readonly any[], R>(inputs: { [K in keyof T]: Iterable<T[K]> | {
|
|
394
|
+
[key: string]: T[K];
|
|
395
|
+
}; }, fn: (tuple: T[number][]) => R, options?: {
|
|
396
|
+
fillValue?: T[number];
|
|
397
|
+
includeValues?: boolean;
|
|
398
|
+
}): R[];
|
|
399
|
+
/**
|
|
400
|
+
* Unzips an array of tuples back into separate arrays.
|
|
401
|
+
* - Reverses the zip operation: transforms rows to columns.
|
|
402
|
+
* - Useful for separating previously combined collections.
|
|
403
|
+
* @param zipped Array of tuples (rows) to transpose
|
|
404
|
+
* @returns Array of arrays (columns), one per tuple position
|
|
405
|
+
* @example
|
|
406
|
+
* const zipped = [[1, 'a'], [2, 'b'], [3, 'c']];
|
|
407
|
+
* unzip(zipped); // [[1, 2, 3], ['a', 'b', 'c']]
|
|
408
|
+
*/
|
|
409
|
+
export declare function unzip<T>(zipped: T[][]): T[][];
|
|
410
|
+
//#endregion
|
|
411
|
+
//#region src/safe-try.d.ts
|
|
412
|
+
/** Terminal success value after resolving supported Slang wrappers. */
|
|
413
|
+
type SafeTryValue<T> = T extends Atom<infer Name> ? Name : T extends Ok<infer Value> ? SafeTryValue<Value> : T extends Some<infer Value> ? SafeTryValue<Value> : T extends Err<infer _Error> ? never : T extends None ? never : T;
|
|
414
|
+
/** Options for safeTry behavior */
|
|
415
|
+
type SafeTryOptions = {
|
|
416
|
+
/** If true, re-throws thrown errors instead of capturing them. */
|
|
417
|
+
throw?: boolean;
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* Captures failures and resolves nested Slang wrappers into one Result.
|
|
421
|
+
* - Awaits the callback, then iteratively unwraps Result, Option, and Atom values.
|
|
422
|
+
* - Returns the first Err or None as Err; cycles also return Err.
|
|
423
|
+
* - Leaves object properties, array elements, and wrapped Promise values intact.
|
|
424
|
+
* - `{ throw: true }` re-throws thrown errors; returned failures remain Err.
|
|
425
|
+
*
|
|
426
|
+
* @param fn - Function to execute (sync or async)
|
|
427
|
+
* @param options - `{ throw?: boolean }`
|
|
428
|
+
* @returns Promise of one Result containing the terminal success value or error text
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* const result = await safeTry(() => Ok(Ok("Hello")));
|
|
432
|
+
* if (result.isOk) println(result.value); // "Hello"
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* const result = await safeTry(() => {
|
|
436
|
+
* throw new Error("Oops!");
|
|
437
|
+
* });
|
|
438
|
+
* if (result.isErr) println(result.error);
|
|
439
|
+
*/
|
|
440
|
+
export declare function safeTry<T>(fn: () => T | Promise<T>, options?: SafeTryOptions): Promise<Result<SafeTryValue<Awaited<T>>, string>>;
|
|
441
|
+
//#endregion
|
|
442
|
+
//#region src/pipe.d.ts
|
|
443
|
+
/** Function that transforms one Result into another */
|
|
444
|
+
type PipeFn<T = any, E = any> = (input: Result<T, E>) => Result<any, any> | Promise<Result<any, any>>;
|
|
445
|
+
/** Context passed to onEach callback */
|
|
446
|
+
type PipeEachContext = {
|
|
447
|
+
prevResult: Result<any, any>;
|
|
448
|
+
currentFn: string;
|
|
449
|
+
nextFn: string | undefined;
|
|
450
|
+
};
|
|
451
|
+
/** Options for pipeline execution */
|
|
452
|
+
type PipeRunOptions = {
|
|
453
|
+
/** Called after each function executes */
|
|
454
|
+
onEach?: (ctx: PipeEachContext) => void;
|
|
455
|
+
/** Called when pipeline completes successfully */
|
|
456
|
+
onSuccess?: (value: any) => void;
|
|
457
|
+
/** Called when pipeline encounters an error (only when allowErrors is false) */
|
|
458
|
+
onError?: (error: Error) => void;
|
|
459
|
+
/** If true, continues pipeline even when a function returns Err */
|
|
460
|
+
allowErrors?: boolean;
|
|
461
|
+
};
|
|
462
|
+
/** Pipeline object returned by pipe() */
|
|
463
|
+
type Pipeline<T, E> = {
|
|
464
|
+
run: (options?: PipeRunOptions) => Promise<Result<T, E>>;
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* Creates a pipeline for sequential function composition.
|
|
468
|
+
* Each function receives the previous Result and returns a new Result.
|
|
469
|
+
*
|
|
470
|
+
* @param initial - Starting value (plain value, Option, Result, or Atom)
|
|
471
|
+
* @param fns - Pipeline functions that transform Results
|
|
472
|
+
* @returns Pipeline object with `.run()` method
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* const add = (x: number) => (res: Result<number, string>) =>
|
|
476
|
+
* res.isOk ? Ok(res.value + x) : res;
|
|
477
|
+
*
|
|
478
|
+
* const result = await pipe(5, add(3), add(2)).run();
|
|
479
|
+
* // result.value === 10
|
|
480
|
+
*
|
|
481
|
+
* @example
|
|
482
|
+
* const result = await pipe(option(5), add(3)).run({
|
|
483
|
+
* onEach: ({ currentFn, prevResult }) => console.log(currentFn, prevResult),
|
|
484
|
+
* onSuccess: (value) => console.log("Done:", value),
|
|
485
|
+
* allowErrors: false,
|
|
486
|
+
* });
|
|
487
|
+
*/
|
|
488
|
+
export declare function pipe<T, E = string>(initial: T, ...fns: PipeFn[]): Pipeline<any, E>;
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region src/super-promise.d.ts
|
|
491
|
+
/** The operation itself. Receives the attempt's AbortSignal. */
|
|
492
|
+
type Executor<T> = (signal: AbortSignal) => T | Promise<T> | Result<T, string> | Promise<Result<T, string>>;
|
|
493
|
+
/** Stop signal for `retryUntil`. */
|
|
494
|
+
type RetryUntilOptions = {
|
|
495
|
+
/** When this fires, retrying ends — mid-attempt firings cancel the in-flight attempt. */
|
|
496
|
+
signal: AbortSignal;
|
|
497
|
+
/** Wait between attempts. No wait applies before the first attempt. */
|
|
498
|
+
delay?: number;
|
|
499
|
+
};
|
|
500
|
+
/** Execution policies, configured at construction time. */
|
|
501
|
+
type SuperPromiseOptions = {
|
|
502
|
+
/** Do not execute until this signal fires (accepts SuperPromise signals and AbortSignal). */
|
|
503
|
+
defer?: AbortSignal;
|
|
504
|
+
/** Wait before initial execution; normal retries also wait this long. */
|
|
505
|
+
delay?: number;
|
|
506
|
+
/** Abort the operation after this many milliseconds. Timeouts are never retried. */
|
|
507
|
+
timeout?: number;
|
|
508
|
+
/** `n` retries after the first attempt — `n + 1` attempts total. Aborts and timeouts are never retried. */
|
|
509
|
+
retry?: number;
|
|
510
|
+
/** Keep retrying until the stop signal fires. Overrides `retry` and `delay`. */
|
|
511
|
+
retryUntil?: RetryUntilOptions;
|
|
512
|
+
};
|
|
513
|
+
/** A single async operation with lifecycle ergonomics. Promise-compatible. */
|
|
514
|
+
type SuperPromise<T> = {
|
|
515
|
+
/** Lifecycle signal: fires once when the task reaches a terminal state. */
|
|
516
|
+
done: AbortSignal;
|
|
517
|
+
/** Cancels the operation; settles with `Err("Aborted")` when not yet settled. */
|
|
518
|
+
abort(): void;
|
|
519
|
+
/** Manually settles an externally controlled task with a value. First settlement wins. */
|
|
520
|
+
resolve(value: T): void;
|
|
521
|
+
/** Manually settles an externally controlled task with a failure. First settlement wins. */
|
|
522
|
+
reject(error: unknown): void;
|
|
523
|
+
/** Observes a successful value without transforming it. Callback throws settle as `Err`. */
|
|
524
|
+
tap(fn: (value: T) => unknown | Promise<unknown>): SuperPromise<T>;
|
|
525
|
+
/** Promise-compatible. The callback receives the settled `Result`; the task never rejects. */
|
|
526
|
+
then<TR1 = Result<T, string>, TR2 = never>(onfulfilled?: ((value: Result<T, string>) => TR1 | PromiseLike<TR1>) | null, onrejected?: ((reason: unknown) => TR2 | PromiseLike<TR2>) | null): Promise<TR1 | TR2>;
|
|
527
|
+
/** Promise-compatible. Effectively dead — failures are captured into `Err`, never rejections. */
|
|
528
|
+
catch<TR = never>(onrejected?: ((reason: unknown) => TR | PromiseLike<TR>) | null): Promise<Result<T, string> | TR>;
|
|
529
|
+
/** Promise-compatible. Native behavior. */
|
|
530
|
+
finally(onfinally?: (() => void) | null): Promise<Result<T, string>>;
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* Creates a SuperPromise — one async operation plus lifecycle/execution ergonomics.
|
|
534
|
+
*
|
|
535
|
+
* Lazy activation: the executor starts on first consumption (`await`/`.then()`,
|
|
536
|
+
* or a runner's `start()`), not at creation. Defer chains activate recursively,
|
|
537
|
+
* so awaiting a deferred task runs its dependency first.
|
|
538
|
+
*
|
|
539
|
+
* @example
|
|
540
|
+
* const task = superPromise(async signal => {
|
|
541
|
+
* const response = await fetch(url, { signal });
|
|
542
|
+
* return response.json();
|
|
543
|
+
* });
|
|
544
|
+
*
|
|
545
|
+
* const result = await task; // Result<T, string>
|
|
546
|
+
*/
|
|
547
|
+
export declare function superPromise<T>(fn: Executor<T>, options?: SuperPromiseOptions): SuperPromise<T>;
|
|
548
|
+
/** Creates an externally controlled SuperPromise, settled via `resolve`/`reject`. */
|
|
549
|
+
export declare function superPromise<T>(fn?: undefined, options?: SuperPromiseOptions): SuperPromise<T>;
|
|
550
|
+
//#endregion
|
|
551
|
+
//#region src/super-runner.d.ts
|
|
552
|
+
/** Sequence result: positional tuple of the runners' Ok values. */
|
|
553
|
+
type TupleValues<R extends readonly SuperPromise<unknown>[]> = { -readonly [K in keyof R]: R[K] extends SuperPromise<infer T> ? T : never; };
|
|
554
|
+
/** all/race result: named object of the runners' Ok values. */
|
|
555
|
+
type NamedValues<R extends Record<string, SuperPromise<unknown>>> = { [K in keyof R]: R[K] extends SuperPromise<infer T> ? T : never; };
|
|
556
|
+
/** race(count: 1) result: union of single-winner objects. */
|
|
557
|
+
type RaceValues<C extends number, R extends Record<string, SuperPromise<unknown>>> = C extends 1 ? { [K in keyof R]: { [P in K]: R[K] extends SuperPromise<infer T> ? T : never; }; }[keyof R] : Partial<NamedValues<R>>;
|
|
558
|
+
/** Orchestrates multiple already-created SuperPromises. */
|
|
559
|
+
type SuperRunner<Value> = {
|
|
560
|
+
/** Lifecycle signal: fires once when the runner reaches a terminal state. */
|
|
561
|
+
done: AbortSignal;
|
|
562
|
+
/** Starts execution. Idempotent: repeated calls return the same result without re-executing children. */
|
|
563
|
+
start(): Promise<Result<Value, string>>;
|
|
564
|
+
/** Cancels the runner and all active children; settles with `Err("Aborted")`. */
|
|
565
|
+
abort(): void;
|
|
566
|
+
};
|
|
567
|
+
/** Runs runners in order; stops at the first failure. */
|
|
568
|
+
export declare function superRunner<const R extends readonly SuperPromise<unknown>[]>(config: {
|
|
569
|
+
type: "sequence";
|
|
570
|
+
runners: R;
|
|
571
|
+
}): SuperRunner<TupleValues<R>>;
|
|
572
|
+
/** Runs runners concurrently; fails fast on the first failure, aborting remaining children. */
|
|
573
|
+
export declare function superRunner<const R extends Record<string, SuperPromise<unknown>>>(config: {
|
|
574
|
+
type: "all";
|
|
575
|
+
runners: R;
|
|
576
|
+
}): SuperRunner<NamedValues<R>>;
|
|
577
|
+
/** Runs runners concurrently; first `count` successful completions win, remaining children are aborted. */
|
|
578
|
+
export declare function superRunner<const C extends number, const R extends Record<string, SuperPromise<unknown>>>(config: {
|
|
579
|
+
type: "race";
|
|
580
|
+
count: C;
|
|
581
|
+
runners: R;
|
|
582
|
+
}): SuperRunner<RaceValues<C, R>>;
|
|
583
|
+
//#endregion
|
|
584
|
+
//#region src/channel.d.ts
|
|
585
|
+
/** Event published on a Channel. */
|
|
586
|
+
type ChannelEvent = {
|
|
587
|
+
topic: string;
|
|
588
|
+
data: unknown;
|
|
589
|
+
};
|
|
590
|
+
/** Subscriber handler receiving published events. */
|
|
591
|
+
type ChannelSubscriber = (event: ChannelEvent) => void;
|
|
592
|
+
/** Event communication between independent parts of an application. */
|
|
593
|
+
type Channel = {
|
|
594
|
+
/** Immediately publishes an event to subscribers of its topic. */
|
|
595
|
+
send(event: ChannelEvent): void;
|
|
596
|
+
/**
|
|
597
|
+
* Subscribes to events of a specific topic.
|
|
598
|
+
* Returns an unsubscribe function; after calling it, no further events are received.
|
|
599
|
+
*/
|
|
600
|
+
subscribe(filter: {
|
|
601
|
+
topic: string;
|
|
602
|
+
}, handler: ChannelSubscriber): () => void;
|
|
603
|
+
/** Publishes an event when a signal fires. Accepts any compatible lifecycle signal. */
|
|
604
|
+
when(config: {
|
|
605
|
+
signal: AbortSignal;
|
|
606
|
+
topic: string;
|
|
607
|
+
data: unknown;
|
|
608
|
+
}): void;
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* Creates a Channel — completely independent of SuperPromise/SuperRunner.
|
|
612
|
+
*
|
|
613
|
+
* @example
|
|
614
|
+
* const channel = createChannel();
|
|
615
|
+
*
|
|
616
|
+
* const unsubscribe = channel.subscribe({ topic: "user.created" }, event => {
|
|
617
|
+
* println(event.data);
|
|
618
|
+
* });
|
|
619
|
+
*
|
|
620
|
+
* channel.send({ topic: "user.created", data: user });
|
|
621
|
+
* unsubscribe(); // stop receiving events
|
|
622
|
+
*/
|
|
623
|
+
export declare function createChannel(): Channel;
|
|
624
|
+
//#endregion
|
|
625
|
+
//#region src/signal.d.ts
|
|
626
|
+
/**
|
|
627
|
+
* A lifecycle Signal — a trigger that fires once and stays fired.
|
|
628
|
+
*
|
|
629
|
+
* Abort-compatible: structurally an `AbortSignal` plus a `fire()` method,
|
|
630
|
+
* so it can be passed anywhere a native `AbortSignal` is expected
|
|
631
|
+
* (and vice-versa). Wraps AbortController semantics.
|
|
632
|
+
*
|
|
633
|
+
* Consumed by `defer`, `retryUntil`, `channel.when`, and `task.done`.
|
|
634
|
+
*/
|
|
635
|
+
type Signal = AbortSignal & {
|
|
636
|
+
/** Fires the signal once. Subsequent calls are no-ops. */
|
|
637
|
+
fire(): void;
|
|
638
|
+
};
|
|
639
|
+
/**
|
|
640
|
+
* Creates a lifecycle signal.
|
|
641
|
+
*
|
|
642
|
+
* ```ts
|
|
643
|
+
* const signal = createSignal();
|
|
644
|
+
*
|
|
645
|
+
* signal.addEventListener("abort", () => {
|
|
646
|
+
* println("fired");
|
|
647
|
+
* });
|
|
648
|
+
*
|
|
649
|
+
* signal.fire(); // "fired"
|
|
650
|
+
* signal.aborted; // true
|
|
651
|
+
* ```
|
|
652
|
+
*
|
|
653
|
+
* Listeners are NOT replayed after firing — consumers must check
|
|
654
|
+
* `signal.aborted` synchronously to detect an already-fired signal.
|
|
655
|
+
*/
|
|
656
|
+
export declare function createSignal(): Signal;
|
|
657
|
+
//#endregion
|
|
658
|
+
export type { Atom, AtomMethods, Channel, ChannelEvent, ChannelSubscriber, EnvironmentMode, EnvironmentOptions, Err as ErrType, Executor, NonTruthy, None, Ok as OkType, Option, OptionMethods, OptionsValue, PipeEachContext, PipeFn, PipeRunOptions, Pipeline, PrintFn, Result, ResultMethods, RetryUntilOptions, Signal, Some, SuperPromise, SuperPromiseOptions, SuperRunner };
|