functype 0.8.69 → 0.8.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Either-BfXNbTHo.d.ts → Either-DlOLCe3b.d.ts} +20 -20
- package/dist/{Map-vivbm5n0.d.ts → Map-R4vpSnzG.d.ts} +2 -2
- package/dist/{Valuable-CtuVEKTZ.d.ts → Valuable-D4BtNlTV.d.ts} +1 -1
- package/dist/chunk-5ABR3A24.mjs +49 -0
- package/dist/chunk-5ABR3A24.mjs.map +1 -0
- package/dist/chunk-7PQA3W7W.mjs.map +1 -1
- package/dist/chunk-TQJDL6YW.mjs.map +1 -1
- package/dist/either/index.d.ts +2 -2
- package/dist/either/index.mjs +1 -1
- package/dist/fpromise/index.d.ts +2 -2
- package/dist/fpromise/index.mjs +1 -1
- package/dist/index.d.ts +720 -7
- package/dist/index.mjs +1 -1
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.mjs +1 -1
- package/dist/map/index.d.ts +3 -3
- package/dist/map/index.mjs +1 -1
- package/dist/option/index.d.ts +2 -2
- package/dist/option/index.mjs +1 -1
- package/dist/set/index.d.ts +2 -2
- package/dist/set/index.mjs +1 -1
- package/dist/try/index.d.ts +2 -2
- package/dist/try/index.mjs +1 -1
- package/dist/tuple/index.d.ts +1 -1
- package/package.json +20 -12
- package/dist/chunk-5DWCHDSA.mjs +0 -39
- package/dist/chunk-5DWCHDSA.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,125 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { Brand } from './branded/index.js';
|
|
2
|
+
export { BrandedBoolean, BrandedNumber, BrandedString, ExtractBrand, Unbrand, createBrander, hasBrand, unbrand } from './branded/index.js';
|
|
3
|
+
import { O as Option, E as Either, F as Foldable, L as List, T as Traversable, S as Serializable, P as Pipe, M as Matchable } from './Either-DlOLCe3b.js';
|
|
4
|
+
export { a as Collection, C as Converters, I as IterableType, c as Left, h as MatchableUtils, N as None, k as OptionConstructor, R as Right, l as SerializationMethods, m as Set, j as Some, b as TestEither, f as TypeCheckLeft, e as TypeCheckRight, d as isLeft, i as isRight, t as tryCatch, g as tryCatchAsync } from './Either-DlOLCe3b.js';
|
|
5
|
+
import { T as Type, a as Typeable, F as Functor, V as Valuable } from './Valuable-D4BtNlTV.js';
|
|
6
|
+
export { A as AbstractFunctor, c as ArrayFunctor, b as AsyncFunctor, E as ExtractTag, d as TypeableParams, e as ValuableParams, i as isTypeable } from './Valuable-D4BtNlTV.js';
|
|
6
7
|
import { FPromise } from './fpromise/index.js';
|
|
7
8
|
export { ErrorContext, FPromiseCompanion } from './fpromise/index.js';
|
|
8
9
|
import { Try } from './try/index.js';
|
|
9
10
|
export { TypeNames } from './try/index.js';
|
|
10
|
-
export { a as ESMap, E as ESMapType, M as Map, S as SafeTraversable } from './Map-
|
|
11
|
+
export { a as ESMap, E as ESMapType, M as Map, S as SafeTraversable } from './Map-R4vpSnzG.js';
|
|
11
12
|
export { Tuple } from './tuple/index.js';
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* A brand with runtime validation
|
|
16
|
+
* @example
|
|
17
|
+
* const Age = ValidatedBrand("Age", (n: number) => n >= 0 && n <= 150)
|
|
18
|
+
* const myAge = Age.of(25) // Option<Brand<"Age", number>>
|
|
19
|
+
* const invalid = Age.of(-5) // None
|
|
20
|
+
*/
|
|
21
|
+
type ValidatedBrand<K extends string, T> = {
|
|
22
|
+
readonly brand: K;
|
|
23
|
+
readonly validate: (value: T) => boolean;
|
|
24
|
+
readonly of: (value: T) => Option<Brand<K, T>>;
|
|
25
|
+
readonly from: (value: T) => Either<string, Brand<K, T>>;
|
|
26
|
+
readonly unsafeOf: (value: T) => Brand<K, T>;
|
|
27
|
+
readonly is: (value: unknown) => value is Brand<K, T>;
|
|
28
|
+
readonly refine: <K2 extends string>(brand: K2, validate: (value: Brand<K, T>) => boolean) => ValidatedBrand<K2, Brand<K, T>>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Create a validated brand with runtime validation
|
|
32
|
+
* @example
|
|
33
|
+
* const Email = ValidatedBrand("Email", (s: string) => /^[^@]+@[^@]+\.[^@]+$/.test(s))
|
|
34
|
+
* const email = Email.of("user@example.com") // Some(Brand<"Email", string>)
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // With Either for error messages
|
|
38
|
+
* const Port = ValidatedBrand("Port", (n: number) => n >= 1 && n <= 65535)
|
|
39
|
+
* const result = Port.from(8080) // Right(Brand<"Port", number>)
|
|
40
|
+
* const error = Port.from(70000) // Left("Invalid Port: validation failed")
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Type guard usage
|
|
44
|
+
* const value: unknown = "test@example.com"
|
|
45
|
+
* if (Email.is(value)) {
|
|
46
|
+
* // value is Brand<"Email", string>
|
|
47
|
+
* }
|
|
48
|
+
*/
|
|
49
|
+
declare function ValidatedBrand<K extends string, T>(brand: K, validate: (value: T) => boolean): ValidatedBrand<K, T>;
|
|
50
|
+
/**
|
|
51
|
+
* Positive number brand (> 0)
|
|
52
|
+
* @example
|
|
53
|
+
* const price = PositiveNumber.of(19.99) // Some(Brand<"PositiveNumber", number>)
|
|
54
|
+
* const invalid = PositiveNumber.of(-5) // None
|
|
55
|
+
* const checked = PositiveNumber.from(0) // Left("Invalid PositiveNumber: validation failed")
|
|
56
|
+
*/
|
|
57
|
+
declare const PositiveNumber: ValidatedBrand<"PositiveNumber", number>;
|
|
58
|
+
declare const NonNegativeNumber: ValidatedBrand<"NonNegativeNumber", number>;
|
|
59
|
+
declare const IntegerNumber: ValidatedBrand<"IntegerNumber", number>;
|
|
60
|
+
declare const PositiveInteger: ValidatedBrand<"PositiveInteger", Brand<"PositiveNumber", number>>;
|
|
61
|
+
/**
|
|
62
|
+
* Non-empty string brand
|
|
63
|
+
* @example
|
|
64
|
+
* const name = NonEmptyString.of("John") // Some(Brand<"NonEmptyString", string>)
|
|
65
|
+
* const empty = NonEmptyString.of("") // None
|
|
66
|
+
*/
|
|
67
|
+
declare const NonEmptyString: ValidatedBrand<"NonEmptyString", string>;
|
|
68
|
+
/**
|
|
69
|
+
* Email address brand with basic validation
|
|
70
|
+
* @example
|
|
71
|
+
* const email = EmailAddress.of("user@example.com") // Some(Brand<"EmailAddress", string>)
|
|
72
|
+
* const invalid = EmailAddress.of("not-an-email") // None
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* // Using with forms
|
|
76
|
+
* const processEmail = (input: string) => {
|
|
77
|
+
* return EmailAddress.from(input)
|
|
78
|
+
* .map(email => sendWelcomeEmail(email))
|
|
79
|
+
* .getOrElse("Invalid email address")
|
|
80
|
+
* }
|
|
81
|
+
*/
|
|
82
|
+
declare const EmailAddress: ValidatedBrand<"EmailAddress", string>;
|
|
83
|
+
declare const UrlString: ValidatedBrand<"UrlString", string>;
|
|
84
|
+
declare const UUID: ValidatedBrand<"UUID", string>;
|
|
85
|
+
declare const ISO8601Date: ValidatedBrand<"ISO8601Date", string>;
|
|
86
|
+
/**
|
|
87
|
+
* Create a number brand with min/max bounds
|
|
88
|
+
* @example
|
|
89
|
+
* const Percentage = BoundedNumber("Percentage", 0, 100)
|
|
90
|
+
* const valid = Percentage.of(75) // Some(Brand<"Percentage", number>)
|
|
91
|
+
* const invalid = Percentage.of(150) // None
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* const Port = BoundedNumber("Port", 1, 65535)
|
|
95
|
+
* const httpPort = Port.unsafeOf(80) // Brand<"Port", number>
|
|
96
|
+
* // Port.unsafeOf(70000) // throws Error
|
|
97
|
+
*/
|
|
98
|
+
declare function BoundedNumber(brand: string, min: number, max: number): ValidatedBrand<string, number>;
|
|
99
|
+
/**
|
|
100
|
+
* Create a string brand with length constraints
|
|
101
|
+
* @example
|
|
102
|
+
* const Username = BoundedString("Username", 3, 20)
|
|
103
|
+
* const valid = Username.of("johndoe") // Some(Brand<"Username", string>)
|
|
104
|
+
* const tooShort = Username.of("jo") // None
|
|
105
|
+
* const tooLong = Username.of("verylongusernamethatexceedslimit") // None
|
|
106
|
+
*/
|
|
107
|
+
declare function BoundedString(brand: string, minLength: number, maxLength: number): ValidatedBrand<string, string>;
|
|
108
|
+
/**
|
|
109
|
+
* Create a string brand that matches a regex pattern
|
|
110
|
+
* @example
|
|
111
|
+
* const HexColor = PatternString("HexColor", /^#[0-9a-f]{6}$/i)
|
|
112
|
+
* const red = HexColor.of("#ff0000") // Some(Brand<"HexColor", string>)
|
|
113
|
+
* const invalid = HexColor.of("red") // None
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const PhoneNumber = PatternString("PhoneNumber", /^\+?[1-9]\d{1,14}$/)
|
|
117
|
+
* const phone = PhoneNumber.from("+1234567890")
|
|
118
|
+
* .map(p => formatPhoneNumber(p))
|
|
119
|
+
* .getOrElse("Invalid phone number")
|
|
120
|
+
*/
|
|
121
|
+
declare function PatternString(brand: string, pattern: RegExp): ValidatedBrand<string, string>;
|
|
122
|
+
|
|
13
123
|
/**
|
|
14
124
|
* Creates a function-object hybrid similar to Scala's companion objects.
|
|
15
125
|
* This utility allows creating TypeScript function objects with attached methods,
|
|
@@ -34,6 +144,280 @@ export { Tuple } from './tuple/index.js';
|
|
|
34
144
|
*/
|
|
35
145
|
declare function Companion<ObjectF extends object, CompanionF extends object>(object: ObjectF, companion: CompanionF): ObjectF & CompanionF;
|
|
36
146
|
|
|
147
|
+
type LazyCondChain<T> = {
|
|
148
|
+
when: (condition: () => boolean, value: () => T) => LazyCondChain<T>;
|
|
149
|
+
elseWhen: (condition: () => boolean, value: () => T) => LazyCondChain<T>;
|
|
150
|
+
else: (value: () => T) => T;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Conditional expression that enforces exhaustive returns without early returns.
|
|
154
|
+
* Similar to Scala's if/else expressions that always return a value.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* const discount = Cond.of<number>()
|
|
158
|
+
* .when(isPremiumMember, 0.2)
|
|
159
|
+
* .elseWhen(isRegularMember, 0.1)
|
|
160
|
+
* .else(0)
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* // Chaining multiple conditions
|
|
164
|
+
* const status = Cond.of<string>()
|
|
165
|
+
* .when(response.status >= 500, "Server Error")
|
|
166
|
+
* .elseWhen(response.status >= 400, "Client Error")
|
|
167
|
+
* .elseWhen(response.status >= 200, "Success")
|
|
168
|
+
* .else("Unknown")
|
|
169
|
+
*/
|
|
170
|
+
type Cond<T extends Type> = {
|
|
171
|
+
/**
|
|
172
|
+
* Add an if condition
|
|
173
|
+
*/
|
|
174
|
+
when: (condition: boolean, value: T | (() => T)) => Cond<T>;
|
|
175
|
+
/**
|
|
176
|
+
* Add an else-if condition
|
|
177
|
+
*/
|
|
178
|
+
elseWhen: (condition: boolean, value: T | (() => T)) => Cond<T>;
|
|
179
|
+
/**
|
|
180
|
+
* Terminal else clause - required to get the result
|
|
181
|
+
*/
|
|
182
|
+
else: (value: T | (() => T)) => T;
|
|
183
|
+
/**
|
|
184
|
+
* Get the result if a condition was met, throws if no condition met
|
|
185
|
+
*/
|
|
186
|
+
getOrThrow: () => T;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Conditional expression builder for functional if/else chains
|
|
190
|
+
* @example
|
|
191
|
+
* // Basic usage
|
|
192
|
+
* const size = Cond.of<string>()
|
|
193
|
+
* .when(value > 100, "large")
|
|
194
|
+
* .elseWhen(value > 50, "medium")
|
|
195
|
+
* .else("small")
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* // Pattern matching
|
|
199
|
+
* const message = Cond.match(errorCode)({
|
|
200
|
+
* 404: "Not Found",
|
|
201
|
+
* 500: "Server Error",
|
|
202
|
+
* 200: "OK"
|
|
203
|
+
* })
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* // Lazy evaluation
|
|
207
|
+
* const result = Cond.lazy<string>()
|
|
208
|
+
* .when(() => checkCondition1(), () => "Result 1")
|
|
209
|
+
* .when(() => checkCondition2(), () => "Result 2")
|
|
210
|
+
* .else(() => "Default")
|
|
211
|
+
*/
|
|
212
|
+
declare const Cond: (<T extends Type>() => Cond<T>) & {
|
|
213
|
+
/**
|
|
214
|
+
* Create a conditional expression that must end with else
|
|
215
|
+
* @example
|
|
216
|
+
* const x = 7
|
|
217
|
+
* const result = Cond.of<string>()
|
|
218
|
+
* .when(x > 10, "large")
|
|
219
|
+
* .elseWhen(x > 5, "medium")
|
|
220
|
+
* .else("small")
|
|
221
|
+
* // result = "medium"
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* // With lazy evaluation
|
|
225
|
+
* const discount = Cond.of<number>()
|
|
226
|
+
* .when(isPremium, () => calculatePremiumDiscount())
|
|
227
|
+
* .when(isLoyal, () => calculateLoyaltyDiscount())
|
|
228
|
+
* .else(0)
|
|
229
|
+
*/
|
|
230
|
+
of: <T extends Type>() => Cond<T>;
|
|
231
|
+
/**
|
|
232
|
+
* Pattern matching helper that ensures exhaustiveness
|
|
233
|
+
* @example
|
|
234
|
+
* type Status = "pending" | "success" | "error"
|
|
235
|
+
* const status: Status = "success"
|
|
236
|
+
* const result = Cond.match(status)({
|
|
237
|
+
* "pending": "Waiting...",
|
|
238
|
+
* "success": "Done!",
|
|
239
|
+
* "error": "Failed!"
|
|
240
|
+
* })
|
|
241
|
+
* // result = "Done!"
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* // With function values
|
|
245
|
+
* const action = "compute"
|
|
246
|
+
* const result = Cond.match(action)({
|
|
247
|
+
* "compute": () => expensiveComputation(),
|
|
248
|
+
* "cache": () => getCachedValue(),
|
|
249
|
+
* "skip": () => defaultValue
|
|
250
|
+
* })
|
|
251
|
+
*/
|
|
252
|
+
match: <T extends string | number | symbol>(value: T) => <R extends Type>(cases: Record<T, R | (() => R)>) => R;
|
|
253
|
+
/**
|
|
254
|
+
* Create a lazy conditional that defers evaluation
|
|
255
|
+
* @example
|
|
256
|
+
* // Only evaluates conditions and values when needed
|
|
257
|
+
* const getMessage = Cond.lazy<string>()
|
|
258
|
+
* .when(() => isError(), () => computeErrorMessage())
|
|
259
|
+
* .when(() => isWarning(), () => computeWarningMessage())
|
|
260
|
+
* .else(() => "Success")
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* // Complex conditional with expensive checks
|
|
264
|
+
* const result = Cond.lazy<Action>()
|
|
265
|
+
* .when(
|
|
266
|
+
* () => user.role === "admin" && checkAdminPermissions(),
|
|
267
|
+
* () => ({ type: "admin", permissions: loadAdminPermissions() })
|
|
268
|
+
* )
|
|
269
|
+
* .when(
|
|
270
|
+
* () => user.role === "user" && user.isActive,
|
|
271
|
+
* () => ({ type: "user", permissions: loadUserPermissions() })
|
|
272
|
+
* )
|
|
273
|
+
* .else(() => ({ type: "guest", permissions: [] }))
|
|
274
|
+
*/
|
|
275
|
+
lazy: <T extends Type>() => LazyCondChain<T>;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Pattern matching construct similar to Scala's match expressions.
|
|
280
|
+
* Enforces exhaustive matching and returns values.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* const result = Match(value)
|
|
284
|
+
* .case(x => x > 100, "large")
|
|
285
|
+
* .case(x => x > 50, "medium")
|
|
286
|
+
* .default("small")
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* // Matching exact values
|
|
290
|
+
* const message = Match(status)
|
|
291
|
+
* .caseValue("pending", "Please wait...")
|
|
292
|
+
* .caseValue("success", "Completed!")
|
|
293
|
+
* .caseValue("error", "Failed")
|
|
294
|
+
* .default("Unknown")
|
|
295
|
+
*/
|
|
296
|
+
type Match<T extends Type, R extends Type> = {
|
|
297
|
+
/**
|
|
298
|
+
* Add a case with a predicate
|
|
299
|
+
*/
|
|
300
|
+
case: (predicate: (value: T) => boolean, result: R | ((value: T) => R)) => Match<T, R>;
|
|
301
|
+
/**
|
|
302
|
+
* Add a case that matches a specific value
|
|
303
|
+
*/
|
|
304
|
+
caseValue: (match: T, result: R | (() => R)) => Match<T, R>;
|
|
305
|
+
/**
|
|
306
|
+
* Add a case that matches multiple values
|
|
307
|
+
*/
|
|
308
|
+
caseValues: (matches: T[], result: R | (() => R)) => Match<T, R>;
|
|
309
|
+
/**
|
|
310
|
+
* Default case - required to get result
|
|
311
|
+
*/
|
|
312
|
+
default: (result: R | ((value: T) => R)) => R;
|
|
313
|
+
/**
|
|
314
|
+
* Get result if a case matched, throws if no match
|
|
315
|
+
*/
|
|
316
|
+
getOrThrow: () => R;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Pattern matching utility for type-safe conditional logic
|
|
320
|
+
* @example
|
|
321
|
+
* // Basic pattern matching
|
|
322
|
+
* const result = Match(value)
|
|
323
|
+
* .case(x => x > 0, "positive")
|
|
324
|
+
* .case(x => x < 0, "negative")
|
|
325
|
+
* .default("zero")
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* // Exhaustive matching for union types
|
|
329
|
+
* type Color = "red" | "green" | "blue"
|
|
330
|
+
* const hex = Match.exhaustive<Color, string>({
|
|
331
|
+
* red: "#FF0000",
|
|
332
|
+
* green: "#00FF00",
|
|
333
|
+
* blue: "#0000FF"
|
|
334
|
+
* })(color)
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* // Partial matching with default
|
|
338
|
+
* const name = Match.partial<number, string>({
|
|
339
|
+
* 1: "one",
|
|
340
|
+
* 2: "two",
|
|
341
|
+
* 3: "three"
|
|
342
|
+
* }).withDefault(n => `number ${n}`)(value)
|
|
343
|
+
*/
|
|
344
|
+
declare const Match: (<T extends Type, R extends Type>(value: T) => Match<T, R>) & {
|
|
345
|
+
/**
|
|
346
|
+
* Create a type-safe exhaustive match for union types
|
|
347
|
+
* @example
|
|
348
|
+
* type Status = "pending" | "success" | "error"
|
|
349
|
+
* const status: Status = "success"
|
|
350
|
+
* const result = Match.exhaustive<Status, string>({
|
|
351
|
+
* pending: "Waiting...",
|
|
352
|
+
* success: "Done!",
|
|
353
|
+
* error: "Failed!"
|
|
354
|
+
* })(status)
|
|
355
|
+
* // result = "Done!"
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* // For function values, wrap in object to prevent execution
|
|
359
|
+
* type Operation = "add" | "subtract" | "multiply"
|
|
360
|
+
* const ops = Match.exhaustive<Operation, { fn: (a: number, b: number) => number }>({
|
|
361
|
+
* add: { fn: (a, b) => a + b },
|
|
362
|
+
* subtract: { fn: (a, b) => a - b },
|
|
363
|
+
* multiply: { fn: (a, b) => a * b }
|
|
364
|
+
* })
|
|
365
|
+
* const compute = ops("multiply").fn
|
|
366
|
+
* const result = compute(4, 5) // 20
|
|
367
|
+
*/
|
|
368
|
+
exhaustive: <T extends string | number | symbol, R extends Type>(cases: Record<T, R>) => (value: T) => R;
|
|
369
|
+
/**
|
|
370
|
+
* Create a partial match that requires a default
|
|
371
|
+
* @example
|
|
372
|
+
* const httpCode = 404
|
|
373
|
+
* const message = Match.partial<number, string>({
|
|
374
|
+
* 200: "OK",
|
|
375
|
+
* 201: "Created",
|
|
376
|
+
* 404: "Not Found",
|
|
377
|
+
* 500: "Server Error"
|
|
378
|
+
* }).withDefault("Unknown Status")(httpCode)
|
|
379
|
+
* // message = "Not Found"
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* // With function default
|
|
383
|
+
* const getMessage = Match.partial<number, string>({
|
|
384
|
+
* 0: "Zero",
|
|
385
|
+
* 1: "One",
|
|
386
|
+
* 2: "Two"
|
|
387
|
+
* }).withDefault((n) => `Number: ${n}`)
|
|
388
|
+
* getMessage(5) // "Number: 5"
|
|
389
|
+
*/
|
|
390
|
+
partial: <T extends string | number | symbol, R extends Type>(cases: Partial<Record<T, R | ((value: T) => R)>>) => {
|
|
391
|
+
withDefault: (defaultValue: R | ((value: T) => R)) => (value: T) => R;
|
|
392
|
+
};
|
|
393
|
+
/**
|
|
394
|
+
* Pattern match with guards
|
|
395
|
+
* @example
|
|
396
|
+
* const score = 85
|
|
397
|
+
* const grade = Match.withGuards<number, string>([
|
|
398
|
+
* [n => n >= 90, "A"],
|
|
399
|
+
* [n => n >= 80, "B"],
|
|
400
|
+
* [n => n >= 70, "C"],
|
|
401
|
+
* [n => n >= 60, "D"]
|
|
402
|
+
* ]).withDefault("F")(score)
|
|
403
|
+
* // grade = "B"
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* // With function results for custom messages
|
|
407
|
+
* const age = 25
|
|
408
|
+
* const category = Match.withGuards<number, string>([
|
|
409
|
+
* [n => n < 13, n => `Child (${n} years)`],
|
|
410
|
+
* [n => n < 20, n => `Teenager (${n} years)`],
|
|
411
|
+
* [n => n < 60, n => `Adult (${n} years)`],
|
|
412
|
+
* [n => n >= 60, n => `Senior (${n} years)`]
|
|
413
|
+
* ]).withDefault("Unknown")(age)
|
|
414
|
+
* // category = "Adult (25 years)"
|
|
415
|
+
*/
|
|
416
|
+
withGuards: <T extends Type, R extends Type>(guards: Array<[(value: T) => boolean, R | ((value: T) => R)]>) => {
|
|
417
|
+
withDefault: (defaultValue: R | ((value: T) => R)) => (value: T) => R;
|
|
418
|
+
};
|
|
419
|
+
};
|
|
420
|
+
|
|
37
421
|
/**
|
|
38
422
|
* Base Object from which most other objects inherit
|
|
39
423
|
* @param type - The type name for the object
|
|
@@ -261,6 +645,205 @@ declare const Task: (<T = unknown>(params?: TaskParams) => {
|
|
|
261
645
|
};
|
|
262
646
|
type Task = ReturnType<typeof Task>;
|
|
263
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Code context for LLM-based self-healing and analysis
|
|
650
|
+
*/
|
|
651
|
+
type CodeContext = {
|
|
652
|
+
/** The source code being executed */
|
|
653
|
+
source: string;
|
|
654
|
+
/** File path or identifier */
|
|
655
|
+
filePath?: string;
|
|
656
|
+
/** Function/method name */
|
|
657
|
+
functionName?: string;
|
|
658
|
+
/** Line number where error occurred */
|
|
659
|
+
lineNumber?: number;
|
|
660
|
+
/** Input parameters that caused the issue */
|
|
661
|
+
inputParams?: Record<string, unknown>;
|
|
662
|
+
/** Expected output type/shape */
|
|
663
|
+
expectedOutput?: unknown;
|
|
664
|
+
/** Stack trace at time of error */
|
|
665
|
+
stackTrace?: string;
|
|
666
|
+
/** Previous execution attempts */
|
|
667
|
+
attempts?: Array<{
|
|
668
|
+
timestamp: Date;
|
|
669
|
+
error: string;
|
|
670
|
+
modifications?: string;
|
|
671
|
+
}>;
|
|
672
|
+
/** Additional context for LLM */
|
|
673
|
+
llmContext?: {
|
|
674
|
+
/** Description of what the code should do */
|
|
675
|
+
intent: string;
|
|
676
|
+
/** Known constraints or requirements */
|
|
677
|
+
constraints?: string[];
|
|
678
|
+
/** Related code/dependencies */
|
|
679
|
+
dependencies?: string[];
|
|
680
|
+
/** Business rules or domain knowledge */
|
|
681
|
+
domain?: string;
|
|
682
|
+
};
|
|
683
|
+
};
|
|
684
|
+
/**
|
|
685
|
+
* Fitness function result for code quality assessment
|
|
686
|
+
*/
|
|
687
|
+
type FitnessResult = {
|
|
688
|
+
/** Overall fitness score (0-100) */
|
|
689
|
+
score: number;
|
|
690
|
+
/** Individual metric scores */
|
|
691
|
+
metrics: {
|
|
692
|
+
/** Correctness score (0-100) */
|
|
693
|
+
correctness: number;
|
|
694
|
+
/** Performance score (0-100) */
|
|
695
|
+
performance: number;
|
|
696
|
+
/** Maintainability score (0-100) */
|
|
697
|
+
maintainability: number;
|
|
698
|
+
/** Security score (0-100) */
|
|
699
|
+
security: number;
|
|
700
|
+
/** Type safety score (0-100) */
|
|
701
|
+
typeSafety: number;
|
|
702
|
+
};
|
|
703
|
+
/** Detailed feedback for improvement */
|
|
704
|
+
feedback: string[];
|
|
705
|
+
/** Suggestions for self-healing */
|
|
706
|
+
suggestions: string[];
|
|
707
|
+
};
|
|
708
|
+
/**
|
|
709
|
+
* Partial fitness result from individual functions
|
|
710
|
+
*/
|
|
711
|
+
type PartialFitnessResult = {
|
|
712
|
+
/** Partial metric scores */
|
|
713
|
+
metrics?: Partial<FitnessResult["metrics"]>;
|
|
714
|
+
/** Detailed feedback for improvement */
|
|
715
|
+
feedback?: string[];
|
|
716
|
+
/** Suggestions for self-healing */
|
|
717
|
+
suggestions?: string[];
|
|
718
|
+
};
|
|
719
|
+
/**
|
|
720
|
+
* Configuration for self-healing behavior
|
|
721
|
+
*/
|
|
722
|
+
type SelfHealingConfig = {
|
|
723
|
+
/** Maximum number of self-healing attempts */
|
|
724
|
+
maxAttempts: number;
|
|
725
|
+
/** Whether to use LLM for code generation */
|
|
726
|
+
enableLLMHealing: boolean;
|
|
727
|
+
/** Minimum fitness score to accept */
|
|
728
|
+
minFitnessScore: number;
|
|
729
|
+
/** Custom fitness functions */
|
|
730
|
+
customFitnessFunctions?: Array<(context: CodeContext, result?: unknown) => Promise<PartialFitnessResult>>;
|
|
731
|
+
/** LLM provider configuration */
|
|
732
|
+
llmConfig?: {
|
|
733
|
+
provider: "openai" | "anthropic" | "custom";
|
|
734
|
+
apiKey?: string;
|
|
735
|
+
model?: string;
|
|
736
|
+
temperature?: number;
|
|
737
|
+
customEndpoint?: string;
|
|
738
|
+
};
|
|
739
|
+
};
|
|
740
|
+
/**
|
|
741
|
+
* Self-healing attempt result
|
|
742
|
+
*/
|
|
743
|
+
type HealingAttempt = {
|
|
744
|
+
/** Attempt number */
|
|
745
|
+
attempt: number;
|
|
746
|
+
/** Timestamp of attempt */
|
|
747
|
+
timestamp: Date;
|
|
748
|
+
/** Error that triggered healing */
|
|
749
|
+
error: string;
|
|
750
|
+
/** Generated/modified code */
|
|
751
|
+
healedCode?: string;
|
|
752
|
+
/** Fitness score of healed code */
|
|
753
|
+
fitnessScore?: number;
|
|
754
|
+
/** Whether healing was successful */
|
|
755
|
+
success: boolean;
|
|
756
|
+
/** Reasoning for the healing approach */
|
|
757
|
+
reasoning?: string;
|
|
758
|
+
};
|
|
759
|
+
/**
|
|
760
|
+
* Code-aware task that can self-heal using LLM context
|
|
761
|
+
*/
|
|
762
|
+
type CodeAwareTask<T extends Type> = {
|
|
763
|
+
/** Execute with code context and self-healing */
|
|
764
|
+
executeWithHealing: (codeContext: CodeContext, config: SelfHealingConfig, cancellationToken?: CancellationToken) => Promise<{
|
|
765
|
+
result: Option<unknown>;
|
|
766
|
+
fitness: FitnessResult;
|
|
767
|
+
healingAttempts: HealingAttempt[];
|
|
768
|
+
finalCode: string;
|
|
769
|
+
}>;
|
|
770
|
+
/** Evaluate fitness of code without execution */
|
|
771
|
+
evaluateFitness: (codeContext: CodeContext, result?: unknown, customFunctions?: Array<(context: CodeContext, result?: unknown) => Promise<PartialFitnessResult>>) => Promise<FitnessResult>;
|
|
772
|
+
/** Generate healing suggestions using LLM */
|
|
773
|
+
generateHealingSuggestions: (codeContext: CodeContext, error: string, config: SelfHealingConfig) => Promise<{
|
|
774
|
+
suggestions: string[];
|
|
775
|
+
healedCode?: string;
|
|
776
|
+
reasoning: string;
|
|
777
|
+
}>;
|
|
778
|
+
/** Validate healed code before execution */
|
|
779
|
+
validateHealedCode: (original: CodeContext, healed: string, config: SelfHealingConfig) => Promise<{
|
|
780
|
+
isValid: boolean;
|
|
781
|
+
issues: string[];
|
|
782
|
+
riskLevel: "low" | "medium" | "high";
|
|
783
|
+
}>;
|
|
784
|
+
};
|
|
785
|
+
/**
|
|
786
|
+
* Code-aware task that provides LLM context for self-healing and fitness evaluation
|
|
787
|
+
* @example
|
|
788
|
+
* // Basic usage with self-healing
|
|
789
|
+
* const codeTask = CodeAwareTask<string>({ name: "DataProcessor" })
|
|
790
|
+
* const context = CodeAwareTask.createCodeContext(
|
|
791
|
+
* "function processData(data) { return data.map(x => x.value) }",
|
|
792
|
+
* "Process array of objects to extract values"
|
|
793
|
+
* )
|
|
794
|
+
*
|
|
795
|
+
* const result = await codeTask.executeWithHealing(
|
|
796
|
+
* context,
|
|
797
|
+
* CodeAwareTask.defaultConfig()
|
|
798
|
+
* )
|
|
799
|
+
*
|
|
800
|
+
* @example
|
|
801
|
+
* // Custom fitness evaluation
|
|
802
|
+
* const customFitness = CodeAwareTask.createCustomFitnessFunction(
|
|
803
|
+
* "businessLogic",
|
|
804
|
+
* async (context, result) => ({
|
|
805
|
+
* score: 85,
|
|
806
|
+
* feedback: ["Follows business rules correctly"],
|
|
807
|
+
* suggestions: ["Consider adding validation"]
|
|
808
|
+
* })
|
|
809
|
+
* )
|
|
810
|
+
*
|
|
811
|
+
* const fitness = await codeTask.evaluateFitness(context, result, [customFitness])
|
|
812
|
+
*
|
|
813
|
+
* @example
|
|
814
|
+
* // High-fitness configuration
|
|
815
|
+
* const strictConfig = CodeAwareTask.fitnessConfig(90)
|
|
816
|
+
* const result = await codeTask.executeWithHealing(context, strictConfig)
|
|
817
|
+
*/
|
|
818
|
+
declare const CodeAwareTask: (<T extends Type>(params?: TaskParams) => CodeAwareTask<T>) & {
|
|
819
|
+
/**
|
|
820
|
+
* Create a default self-healing configuration
|
|
821
|
+
*/
|
|
822
|
+
defaultConfig: () => SelfHealingConfig;
|
|
823
|
+
/**
|
|
824
|
+
* Create a fitness-focused configuration
|
|
825
|
+
*/
|
|
826
|
+
fitnessConfig: (minScore: number) => SelfHealingConfig;
|
|
827
|
+
/**
|
|
828
|
+
* Create a custom fitness function for domain-specific evaluation
|
|
829
|
+
*/
|
|
830
|
+
createCustomFitnessFunction: (name: string, evaluator: (context: CodeContext, result?: unknown) => Promise<{
|
|
831
|
+
score: number;
|
|
832
|
+
feedback: string[];
|
|
833
|
+
suggestions?: string[];
|
|
834
|
+
}>) => (context: CodeContext, result?: unknown) => Promise<PartialFitnessResult>;
|
|
835
|
+
/**
|
|
836
|
+
* Utility to create code context from function
|
|
837
|
+
*/
|
|
838
|
+
createCodeContext: (source: string, intent: string, options?: {
|
|
839
|
+
filePath?: string;
|
|
840
|
+
functionName?: string;
|
|
841
|
+
expectedOutput?: unknown;
|
|
842
|
+
constraints?: string[];
|
|
843
|
+
dependencies?: string[];
|
|
844
|
+
}) => CodeContext;
|
|
845
|
+
};
|
|
846
|
+
|
|
264
847
|
/**
|
|
265
848
|
* Type definition for task information that may be attached to errors
|
|
266
849
|
*/
|
|
@@ -441,6 +1024,136 @@ type Identity<T> = {
|
|
|
441
1024
|
};
|
|
442
1025
|
declare function Identity<T>(value: T): Identity<T>;
|
|
443
1026
|
|
|
1027
|
+
/**
|
|
1028
|
+
* LazyList provides lazy evaluation for list operations.
|
|
1029
|
+
* Operations are deferred until the list is materialized.
|
|
1030
|
+
*
|
|
1031
|
+
* @example
|
|
1032
|
+
* // Basic lazy evaluation
|
|
1033
|
+
* const result = LazyList([1, 2, 3, 4, 5])
|
|
1034
|
+
* .map(x => x * 2)
|
|
1035
|
+
* .filter(x => x > 5)
|
|
1036
|
+
* .toArray() // [6, 8, 10]
|
|
1037
|
+
*
|
|
1038
|
+
* @example
|
|
1039
|
+
* // Infinite sequences with take
|
|
1040
|
+
* const fibonacci = LazyList.iterate([0, 1], ([a, b]) => [b, a + b])
|
|
1041
|
+
* .map(([a]) => a)
|
|
1042
|
+
* .take(10)
|
|
1043
|
+
* .toArray() // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
|
|
1044
|
+
*/
|
|
1045
|
+
type LazyList<A extends Type> = {
|
|
1046
|
+
[Symbol.iterator](): Iterator<A>;
|
|
1047
|
+
map<B extends Type>(f: (a: A) => B): LazyList<B>;
|
|
1048
|
+
flatMap<B extends Type>(f: (a: A) => LazyList<B>): LazyList<B>;
|
|
1049
|
+
filter(predicate: (a: A) => boolean): LazyList<A>;
|
|
1050
|
+
take(n: number): LazyList<A>;
|
|
1051
|
+
drop(n: number): LazyList<A>;
|
|
1052
|
+
takeWhile(predicate: (a: A) => boolean): LazyList<A>;
|
|
1053
|
+
dropWhile(predicate: (a: A) => boolean): LazyList<A>;
|
|
1054
|
+
concat(other: LazyList<A>): LazyList<A>;
|
|
1055
|
+
zip<B extends Type>(other: LazyList<B>): LazyList<[A, B]>;
|
|
1056
|
+
toList(): List<A>;
|
|
1057
|
+
toArray(): A[];
|
|
1058
|
+
forEach(f: (a: A) => void): void;
|
|
1059
|
+
reduce<B extends Type>(f: (acc: B, a: A) => B, initial: B): B;
|
|
1060
|
+
find(predicate: (a: A) => boolean): Option<A>;
|
|
1061
|
+
some(predicate: (a: A) => boolean): boolean;
|
|
1062
|
+
every(predicate: (a: A) => boolean): boolean;
|
|
1063
|
+
count(): number;
|
|
1064
|
+
first(): Option<A>;
|
|
1065
|
+
last(): Option<A>;
|
|
1066
|
+
};
|
|
1067
|
+
/**
|
|
1068
|
+
* Lazy list implementation for efficient deferred computation
|
|
1069
|
+
* @example
|
|
1070
|
+
* // Process large datasets efficiently
|
|
1071
|
+
* const result = LazyList.range(1, 1000000)
|
|
1072
|
+
* .filter(x => x % 2 === 0)
|
|
1073
|
+
* .map(x => x * x)
|
|
1074
|
+
* .take(5)
|
|
1075
|
+
* .toArray() // [4, 16, 36, 64, 100]
|
|
1076
|
+
*
|
|
1077
|
+
* @example
|
|
1078
|
+
* // Infinite sequences
|
|
1079
|
+
* const primes = LazyList.iterate(2, n => n + 1)
|
|
1080
|
+
* .filter(isPrime)
|
|
1081
|
+
* .take(10)
|
|
1082
|
+
* .toArray() // First 10 prime numbers
|
|
1083
|
+
*
|
|
1084
|
+
* @example
|
|
1085
|
+
* // Combining operations
|
|
1086
|
+
* const evens = LazyList.range(0, 100, 2)
|
|
1087
|
+
* const odds = LazyList.range(1, 100, 2)
|
|
1088
|
+
* const combined = evens.zip(odds)
|
|
1089
|
+
* .map(([e, o]) => e + o)
|
|
1090
|
+
* .take(5)
|
|
1091
|
+
* .toArray() // [1, 5, 9, 13, 17]
|
|
1092
|
+
*/
|
|
1093
|
+
declare const LazyList: (<A extends Type>(iterable: Iterable<A>) => LazyList<A>) & {
|
|
1094
|
+
/**
|
|
1095
|
+
* Create an empty LazyList
|
|
1096
|
+
* @example
|
|
1097
|
+
* const empty = LazyList.empty<number>()
|
|
1098
|
+
* empty.toArray() // []
|
|
1099
|
+
*/
|
|
1100
|
+
empty: <A extends Type>() => LazyList<A>;
|
|
1101
|
+
/**
|
|
1102
|
+
* Create a LazyList from a single value
|
|
1103
|
+
* @example
|
|
1104
|
+
* const single = LazyList.of(42)
|
|
1105
|
+
* .map(x => x * 2)
|
|
1106
|
+
* .toArray() // [84]
|
|
1107
|
+
*/
|
|
1108
|
+
of: <A extends Type>(value: A) => LazyList<A>;
|
|
1109
|
+
/**
|
|
1110
|
+
* Create a LazyList from multiple values
|
|
1111
|
+
*/
|
|
1112
|
+
from: <A extends Type>(...values: A[]) => LazyList<A>;
|
|
1113
|
+
/**
|
|
1114
|
+
* Create an infinite LazyList by repeatedly applying a function
|
|
1115
|
+
* @example
|
|
1116
|
+
* // Powers of 2
|
|
1117
|
+
* const powers = LazyList.iterate(1, x => x * 2)
|
|
1118
|
+
* .take(10)
|
|
1119
|
+
* .toArray() // [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
|
|
1120
|
+
*
|
|
1121
|
+
* @example
|
|
1122
|
+
* // Fibonacci sequence
|
|
1123
|
+
* const fib = LazyList.iterate([0, 1], ([a, b]) => [b, a + b])
|
|
1124
|
+
* .map(([a]) => a)
|
|
1125
|
+
* .take(8)
|
|
1126
|
+
* .toArray() // [0, 1, 1, 2, 3, 5, 8, 13]
|
|
1127
|
+
*/
|
|
1128
|
+
iterate: <A extends Type>(initial: A, f: (a: A) => A) => LazyList<A>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Create an infinite LazyList by repeatedly calling a function
|
|
1131
|
+
*/
|
|
1132
|
+
generate: <A extends Type>(f: () => A) => LazyList<A>;
|
|
1133
|
+
/**
|
|
1134
|
+
* Create a LazyList of numbers from start to end (exclusive)
|
|
1135
|
+
* @example
|
|
1136
|
+
* LazyList.range(1, 6).toArray() // [1, 2, 3, 4, 5]
|
|
1137
|
+
* LazyList.range(0, 10, 2).toArray() // [0, 2, 4, 6, 8]
|
|
1138
|
+
* LazyList.range(10, 0, -1).toArray() // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
|
|
1139
|
+
*
|
|
1140
|
+
* @example
|
|
1141
|
+
* // Sum of squares from 1 to 100
|
|
1142
|
+
* const sum = LazyList.range(1, 101)
|
|
1143
|
+
* .map(x => x * x)
|
|
1144
|
+
* .reduce((a, b) => a + b, 0) // 338350
|
|
1145
|
+
*/
|
|
1146
|
+
range: (start: number, end: number, step?: number) => LazyList<number>;
|
|
1147
|
+
/**
|
|
1148
|
+
* Create a LazyList that repeats a value n times (or infinitely if n is not provided)
|
|
1149
|
+
*/
|
|
1150
|
+
repeat: <A extends Type>(value: A, n?: number) => LazyList<A>;
|
|
1151
|
+
/**
|
|
1152
|
+
* Create a LazyList that cycles through an iterable infinitely
|
|
1153
|
+
*/
|
|
1154
|
+
cycle: <A extends Type>(iterable: Iterable<A>) => LazyList<A>;
|
|
1155
|
+
};
|
|
1156
|
+
|
|
444
1157
|
/**
|
|
445
1158
|
* Stack data structure - Last In, First Out (LIFO)
|
|
446
1159
|
* Implements the Traversable interface for working with ordered collections
|
|
@@ -531,4 +1244,4 @@ declare const Stack: (<A extends Type>(values?: A[]) => Stack<A>) & {
|
|
|
531
1244
|
fromBinary: <A>(binary: string) => Stack<A>;
|
|
532
1245
|
};
|
|
533
1246
|
|
|
534
|
-
export { type Async, Base, type CancellationToken, type CancellationTokenSource, Companion, Either, type EitherKind, type ErrorChainElement, type ErrorFormatterOptions, type ErrorWithTaskInfo, FPromise, Foldable, FoldableUtils, Functor, HKT, Identity, type Kind, List, type ListKind, Matchable, NAME, Option, type OptionKind, ParseError, Pipe, Serializable, Stack, type Sync, type TaggedThrowable, Task, type TaskErrorInfo, TaskException, type TaskInfo, type TaskParams, TaskResult, Throwable, type ThrowableType, Traversable, Try, type TryKind, Type, Typeable, type UniversalContainer, Valuable, createCancellationTokenSource, createErrorSerializer, formatError, formatStackTrace, isTaggedThrowable, safeStringify };
|
|
1247
|
+
export { type Async, Base, BoundedNumber, BoundedString, Brand, type CancellationToken, type CancellationTokenSource, CodeAwareTask, type CodeContext, Companion, Cond, Either, type EitherKind, EmailAddress, type ErrorChainElement, type ErrorFormatterOptions, type ErrorWithTaskInfo, FPromise, type FitnessResult, Foldable, FoldableUtils, Functor, HKT, type HealingAttempt, ISO8601Date, Identity, IntegerNumber, type Kind, LazyList, List, type ListKind, Match, Matchable, NAME, NonEmptyString, NonNegativeNumber, Option, type OptionKind, ParseError, type PartialFitnessResult, PatternString, Pipe, PositiveInteger, PositiveNumber, type SelfHealingConfig, Serializable, Stack, type Sync, type TaggedThrowable, Task, type TaskErrorInfo, TaskException, type TaskInfo, type TaskParams, TaskResult, Throwable, type ThrowableType, Traversable, Try, type TryKind, Type, Typeable, UUID, type UniversalContainer, UrlString, ValidatedBrand, Valuable, createCancellationTokenSource, createErrorSerializer, formatError, formatStackTrace, isTaggedThrowable, safeStringify };
|