functype 1.3.0 → 1.4.0

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.
Files changed (70) hide show
  1. package/README.md +11 -0
  2. package/dist/Companion-DiOMBHDG.js +1 -0
  3. package/dist/CompanionTypes-BVqO7Kc2.js +1 -0
  4. package/dist/CompanionTypes-CAxuM7qS.d.ts +58 -0
  5. package/dist/cli/exports.js +1 -1
  6. package/dist/cli/index.js +5 -5
  7. package/dist/companion/index.d.ts +2 -0
  8. package/dist/companion/index.js +1 -0
  9. package/dist/conditional/index.d.ts +2 -0
  10. package/dist/conditional/index.js +1 -0
  11. package/dist/core/task/index.d.ts +2 -0
  12. package/dist/core/task/index.js +1 -0
  13. package/dist/decoder/index.d.ts +2 -0
  14. package/dist/decoder/index.js +1 -0
  15. package/dist/do/index.d.ts +1 -1
  16. package/dist/do/index.js +1 -1
  17. package/dist/either/index.d.ts +1 -1
  18. package/dist/either/index.js +1 -1
  19. package/dist/fetch/index.d.ts +2 -0
  20. package/dist/fetch/index.js +1 -0
  21. package/dist/{full-interfaces-0pOr6idp.js → full-interfaces-C5EZkYpb.js} +20 -4
  22. package/dist/functype/index.d.ts +2 -0
  23. package/dist/functype/index.js +0 -0
  24. package/dist/{index-DBYBJg-D.d.ts → index-Xwjf0L5u.d.ts} +4791 -4813
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.js +1 -1
  27. package/dist/io/index.d.ts +2 -0
  28. package/dist/io/index.js +1 -0
  29. package/dist/lazy/index.d.ts +2 -0
  30. package/dist/lazy/index.js +1 -0
  31. package/dist/list/index.d.ts +1 -1
  32. package/dist/list/index.js +1 -1
  33. package/dist/logger/index.d.ts +36 -1
  34. package/dist/map/index.d.ts +1 -1
  35. package/dist/map/index.js +1 -1
  36. package/dist/obj/index.d.ts +2 -0
  37. package/dist/obj/index.js +1 -0
  38. package/dist/option/index.d.ts +1 -1
  39. package/dist/option/index.js +1 -1
  40. package/dist/serialization/index.d.ts +2 -0
  41. package/dist/serialization/index.js +1 -0
  42. package/dist/serialization-EQGLX3e3.js +4 -0
  43. package/dist/set/index.d.ts +1 -1
  44. package/dist/set/index.js +1 -1
  45. package/dist/src-DCf63AzV.js +17 -0
  46. package/dist/try/index.d.ts +1 -1
  47. package/dist/try/index.js +1 -1
  48. package/dist/tuple/index.js +1 -1
  49. package/dist/typeclass/index.d.ts +2 -0
  50. package/dist/typeclass/index.js +1 -0
  51. package/dist/typeclass-C61yDVYd.js +1 -0
  52. package/dist/util/index.d.ts +24 -0
  53. package/dist/util/index.js +1 -0
  54. package/package.json +6 -5
  55. package/dist/Logger-75yEf2wp.d.ts +0 -32
  56. package/dist/Tuple-knEoDiKZ.js +0 -4
  57. package/dist/src-P2lgP6cJ.js +0 -17
  58. package/readme/BRAND_MIGRATION_GUIDE.md +0 -230
  59. package/readme/BUNDLE_OPTIMIZATION.md +0 -74
  60. package/readme/HKT.md +0 -110
  61. package/readme/ROADMAP.md +0 -113
  62. package/readme/TASK-TODO.md +0 -33
  63. package/readme/TUPLE-EXAMPLES.md +0 -76
  64. package/readme/ai-guide.md +0 -384
  65. package/readme/examples.md +0 -1883
  66. package/readme/quick-reference.md +0 -462
  67. package/readme/task-error-handling.md +0 -283
  68. package/readme/tasks.md +0 -195
  69. package/readme/type-index.md +0 -225
  70. /package/dist/{chunk-DK3Fl9T5.js → rolldown-runtime-DK3Fl9T5.js} +0 -0
package/README.md CHANGED
@@ -45,6 +45,17 @@ npx functype --json # JSON output for programmatic use
45
45
  - **Error Formatting**: Utilities for improved error visualization and logging
46
46
  - **Unified Type Classes**: Consistent interfaces across all data structures
47
47
 
48
+ ## functype vs Effect
49
+
50
+ **functype is a small, dependency-free library of functional data types you adopt incrementally. Effect is a comprehensive effect system and runtime you build your application around.** Both bring FP to TypeScript and overlap on the surface (an effect type, typed errors, DI), but they solve different problems. If you know Scala: functype is to Effect roughly what the standard library / `cats-core` is to ZIO.
51
+
52
+ - **Reach for functype** when you want Scala's standard-library ergonomics — `Option`, `Either`, `Try`, `List`, do-notation — with **zero runtime dependencies**, adoptable **one function at a time** (a `List` or `Option` is just a value you can delete from a single file). It includes a lightweight ZIO-shaped `IO` with typed errors and DI, but no runtime to build your app around.
53
+ - **Reach for Effect** when you want **structured concurrency**, streaming, scheduling, and an integrated batteries-included ecosystem you structure your whole application on.
54
+
55
+ functype deliberately is **not** a framework — no fiber runtime, no structured concurrency, no `Clock`/`Random`/`Tracer`. What it adds instead is an **LLM-native** loop no other FP library has: lint rules that _enforce_ idioms ([`eslint-plugin-functype`](https://www.npmjs.com/package/eslint-plugin-functype)), a scorer/benchmark that _measures_ adherence ([`functype-eval`](https://www.npmjs.com/package/functype-eval)), and an MCP server + skill that _teach_ models the API.
56
+
57
+ **Full comparison, non-goals, and "choose Effect when…": [docs/vs-effect.md](./docs/vs-effect.md).**
58
+
48
59
  ## Installation
49
60
 
50
61
  ```bash
@@ -0,0 +1 @@
1
+ import{mergeObjects as e}from"./util/index.js";function t(t,n){return e(t,n)}export{t};
@@ -0,0 +1 @@
1
+ const e=e=>typeof e==`function`&&Object.keys(e).length>0;export{e as t};
@@ -0,0 +1,58 @@
1
+ //#region src/companion/Companion.d.ts
2
+ /**
3
+ * Creates a function-object hybrid similar to Scala's companion objects.
4
+ * This utility allows creating TypeScript function objects with attached methods,
5
+ * mimicking Scala's class + companion object pattern without using classes.
6
+ *
7
+ * @param object The main function that will be invoked when the object is called
8
+ * @param companion Additional static methods to attach to the function
9
+ * @returns A function with the attached methods
10
+ *
11
+ * @example
12
+ * const greet = (name: string) => `Hello, ${name}!`;
13
+ * const methods = {
14
+ * formal: (name: string) => `Good day, ${name}.`,
15
+ * casual: (name: string) => `Hey ${name}!`
16
+ * };
17
+ * const Greeter = createCompanionObject(greet, methods);
18
+ *
19
+ * // Usage:
20
+ * Greeter("World"); // Hello, World!
21
+ * Greeter.formal("Sir"); // Good day, Sir.
22
+ * Greeter.casual("Friend"); // Hey Friend!
23
+ */
24
+ declare function Companion<ObjectF extends object, CompanionF extends object>(object: ObjectF, companion: CompanionF): ObjectF & CompanionF;
25
+ //#endregion
26
+ //#region src/companion/CompanionTypes.d.ts
27
+ /**
28
+ * Helper types for working with the Companion pattern
29
+ * @module CompanionTypes
30
+ */
31
+ /**
32
+ * Extracts the companion methods type from a Companion object
33
+ * @typeParam T - The Companion type
34
+ * @example
35
+ * ```typescript
36
+ * type OptionCompanionMethods = CompanionMethods<typeof Option>
37
+ * // { from: ..., none: ..., fromJSON: ..., etc. }
38
+ * ```
39
+ */
40
+ type CompanionMethods<T> = T extends ((...args: never[]) => unknown) & infer C ? C : never;
41
+ /**
42
+ * Extracts the instance type from a constructor function
43
+ * @typeParam T - The constructor function type
44
+ * @example
45
+ * ```typescript
46
+ * type OptionInstance = InstanceType<typeof Option>
47
+ * // Option<T>
48
+ * ```
49
+ */
50
+ type InstanceType<T> = T extends ((...args: infer Args) => infer R) ? R extends ((...args: unknown[]) => unknown) ? ReturnType<R> : R : never;
51
+ /**
52
+ * Type guard to check if a value is a Companion object (has both constructor and companion methods)
53
+ * @param value - The value to check
54
+ * @returns True if value is a Companion object
55
+ */
56
+ declare const isCompanion: (value: unknown) => value is ((...args: never[]) => unknown) & Record<string, unknown>;
57
+ //#endregion
58
+ export { Companion as i, InstanceType as n, isCompanion as r, CompanionMethods as t };
@@ -1 +1 @@
1
- import{a as e,i as t,n,r,t as i}from"../full-interfaces-0pOr6idp.js";export{n as CATEGORIES,i as FULL_INTERFACES,r as INTERFACES,t as TYPES,e as VERSION};
1
+ import{a as e,i as t,n,r,t as i}from"../full-interfaces-C5EZkYpb.js";export{n as CATEGORIES,i as FULL_INTERFACES,r as INTERFACES,t as TYPES,e as VERSION};
package/dist/cli/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import{Ct as e,Nt as t,Q as n}from"../src-P2lgP6cJ.js";import{a as r,i,n as a,r as o,t as s}from"../full-interfaces-0pOr6idp.js";const c=()=>{let n=e([`functype ${r} - Scala-inspired FP for TypeScript`,``]);return e(Object.entries(a)).foldLeft(n)((n,[r,a])=>{let o=n.add(r.toUpperCase());return e(a).foldLeft(o)((e,n)=>t(i[n]).fold(()=>e,t=>{let r=t.interfaces.length>0?` [${t.interfaces.join(`, `)}]`:``;return e.add(` ${n}${r}`).add(` ${t.description}`)})).add(``)}).concat(e([`Use: npx functype <Type> for details`,`Use: npx functype interfaces for interface reference`])).toArray().join(`
3
- `)},l=(n,r)=>{let i=r.interfaces.length>0?` [${r.interfaces.join(`, `)}]`:``,a=e([`create`,`transform`,`extract`,`check`,`other`]),o=e([`${n}<T>${i}`,``,r.description,``]);return a.foldLeft(o)((n,i)=>t(r.methods[i]).filter(e=>e.length>0).fold(()=>n,t=>{let r=n.add(i.toUpperCase());return e(t).foldLeft(r)((e,t)=>e.add(` ${t}`)).add(``)})).toArray().join(`
4
- `).trimEnd()},u=()=>{let t=e([`INTERFACES`,``]);return e(Object.entries(o)).foldLeft(t)((t,[n,r])=>{let i=r.extends?` extends ${r.extends}`:``,a=t.add(`${n}<A>${i}`).add(` ${r.description}`);return e(r.methods).foldLeft(a)((e,t)=>e.add(` ${t}`)).add(``)}).toArray().join(`
5
- `).trimEnd()},d=e=>JSON.stringify(e,null,2),f=()=>({version:r,categories:a,types:i}),p=n=>t(i[n]).map(e=>({name:n,data:e})).or(e(Object.entries(i)).find(([e])=>e.toLowerCase()===n.toLowerCase()).map(([e,t])=>({name:e,data:t}))).orUndefined(),m=()=>Object.keys(i),h=()=>o,g=t=>{let n=e(t.slice(2));return{flags:{json:n.contains(`--json`),full:n.contains(`--full`),help:n.exists(e=>e===`--help`||e===`-h`)},args:n.filter(e=>!e.startsWith(`--`)&&e!==`-h`)}},_=n=>t(s[n]).or(e(Object.entries(s)).find(([e])=>e.toLowerCase()===n.toLowerCase()).map(([,e])=>e)),v=()=>{let t=e([`FULL INTERFACE DEFINITIONS`,`=`.repeat(60),``]);return e(Object.entries(s)).foldLeft(t)((t,[n,r])=>t.concat(e([`// ${n}`,r,``,`-`.repeat(60),``]))).toArray().join(`
2
+ import{At as e,Q as t,St as n}from"../src-DCf63AzV.js";import{a as r,i,n as a,r as o,t as s}from"../full-interfaces-C5EZkYpb.js";const c=()=>{let t=n([`functype ${r} - Scala-inspired FP for TypeScript`,``]);return n(Object.entries(a)).foldLeft(t)((t,[r,a])=>{let o=t.add(r.toUpperCase());return n(a).foldLeft(o)((t,n)=>e(i[n]).fold(()=>t,e=>{let r=e.interfaces.length>0?` [${e.interfaces.join(`, `)}]`:``;return t.add(` ${n}${r}`).add(` ${e.description}`)})).add(``)}).concat(n([`Use: npx functype <Type> for details`,`Use: npx functype interfaces for interface reference`])).toArray().join(`
3
+ `)},l=(t,r)=>{let i=r.interfaces.length>0?` [${r.interfaces.join(`, `)}]`:``,a=n([`create`,`transform`,`extract`,`check`,`other`]),o=n([`${t}<T>${i}`,``,r.description,``]);return a.foldLeft(o)((t,i)=>e(r.methods[i]).filter(e=>e.length>0).fold(()=>t,e=>{let r=t.add(i.toUpperCase());return n(e).foldLeft(r)((e,t)=>e.add(` ${t}`)).add(``)})).toArray().join(`
4
+ `).trimEnd()},u=()=>{let e=n([`INTERFACES`,``]);return n(Object.entries(o)).foldLeft(e)((e,[t,r])=>{let i=r.extends?` extends ${r.extends}`:``,a=e.add(`${t}<A>${i}`).add(` ${r.description}`);return n(r.methods).foldLeft(a)((e,t)=>e.add(` ${t}`)).add(``)}).toArray().join(`
5
+ `).trimEnd()},d=e=>JSON.stringify(e,null,2),f=()=>({version:r,categories:a,types:i}),p=t=>e(i[t]).map(e=>({name:t,data:e})).or(n(Object.entries(i)).find(([e])=>e.toLowerCase()===t.toLowerCase()).map(([e,t])=>({name:e,data:t}))).orUndefined(),m=()=>Object.keys(i),h=()=>o,g=e=>{let t=n(e.slice(2));return{flags:{json:t.contains(`--json`),full:t.contains(`--full`),help:t.exists(e=>e===`--help`||e===`-h`)},args:t.filter(e=>!e.startsWith(`--`)&&e!==`-h`)}},_=t=>e(s[t]).or(n(Object.entries(s)).find(([e])=>e.toLowerCase()===t.toLowerCase()).map(([,e])=>e)),v=()=>{let e=n([`FULL INTERFACE DEFINITIONS`,`=`.repeat(60),``]);return n(Object.entries(s)).foldLeft(e)((e,[t,r])=>e.concat(n([`// ${t}`,r,``,`-`.repeat(60),``]))).toArray().join(`
6
6
  `).trimEnd()},y=()=>{console.log(`functype - API documentation for LLMs
7
7
 
8
8
  USAGE
@@ -24,4 +24,4 @@ EXAMPLES
24
24
  npx functype Option --json # Option as JSON
25
25
  npx functype Option --full # Full TypeScript interface
26
26
  npx functype --full # All full interfaces (large output!)
27
- `)},b=e=>{console.error(`Unknown type: ${e}`),console.error(``),console.error(`Available types: ${m().join(`, `)}`),console.error(``),console.error(`Use: npx functype interfaces - for interface reference`),process.exit(1)},x=e=>console.log(e),S=(e,n)=>t(p(e)).fold(()=>b(e),e=>{n.full?_(e.name).fold(()=>x(n.json?d({[e.name]:e.data}):l(e.name,e.data)),t=>x(n.json?d({[e.name]:{...e.data,fullInterface:t}}):t)):x(n.json?d({[e.name]:e.data}):l(e.name,e.data))});(()=>{let{flags:e,args:t}=g(process.argv);n(!0).when(()=>e.help,()=>y()).when(()=>t.isEmpty,()=>e.full?x(e.json?d(s):v()):x(e.json?d(f()):c())).when(()=>t.headOption.contains(`interfaces`),()=>x(e.json?d(h()):u())).default(()=>t.headOption.fold(()=>x(e.json?d(f()):c()),t=>S(t,e)))})();
27
+ `)},b=e=>{console.error(`Unknown type: ${e}`),console.error(``),console.error(`Available types: ${m().join(`, `)}`),console.error(``),console.error(`Use: npx functype interfaces - for interface reference`),process.exit(1)},x=e=>console.log(e),S=(t,n)=>e(p(t)).fold(()=>b(t),e=>{n.full?_(e.name).fold(()=>x(n.json?d({[e.name]:e.data}):l(e.name,e.data)),t=>x(n.json?d({[e.name]:{...e.data,fullInterface:t}}):t)):x(n.json?d({[e.name]:e.data}):l(e.name,e.data))});(()=>{let{flags:e,args:n}=g(process.argv);t(!0).when(()=>e.help,()=>y()).when(()=>n.isEmpty,()=>e.full?x(e.json?d(s):v()):x(e.json?d(f()):c())).when(()=>n.headOption.contains(`interfaces`),()=>x(e.json?d(h()):u())).default(()=>n.headOption.fold(()=>x(e.json?d(f()):c()),t=>S(t,e)))})();
@@ -0,0 +1,2 @@
1
+ import { i as Companion, n as InstanceType, r as isCompanion, t as CompanionMethods } from "../CompanionTypes-CAxuM7qS.js";
2
+ export { Companion, CompanionMethods, InstanceType, isCompanion };
@@ -0,0 +1 @@
1
+ import{t as e}from"../Companion-DiOMBHDG.js";import{t}from"../CompanionTypes-BVqO7Kc2.js";export{e as Companion,t as isCompanion};
@@ -0,0 +1,2 @@
1
+ import { Tr as Cond, n as UntypedMatch, t as Match } from "../index-Xwjf0L5u.js";
2
+ export { Cond, Match, UntypedMatch };
@@ -0,0 +1 @@
1
+ import{$ as e,Q as t}from"../src-DCf63AzV.js";export{e as Cond,t as Match};
@@ -0,0 +1,2 @@
1
+ import { $t as TaskResult, Gt as Ok, Ht as CancellationToken, Jt as Task, Kt as Sync, Qt as TaskParams, Ut as CancellationTokenSource, Vt as Async, Wt as Err, Xt as TaskMetadata, Yt as TaskFailure, Zt as TaskOutcome, en as TaskSuccess, nn as isTaggedThrowable, qt as TaggedThrowable, tn as createCancellationTokenSource } from "../../index-Xwjf0L5u.js";
2
+ export { Async, CancellationToken, CancellationTokenSource, Err, Ok, Sync, TaggedThrowable, Task, TaskFailure, TaskMetadata, TaskOutcome, TaskParams, TaskResult, TaskSuccess, createCancellationTokenSource, isTaggedThrowable };
@@ -0,0 +1 @@
1
+ import{G as e,J as t,K as n,W as r,q as i}from"../../src-DCf63AzV.js";export{r as Err,e as Ok,n as Task,i as createCancellationTokenSource,t as isTaggedThrowable};
@@ -0,0 +1,2 @@
1
+ import { Bt as DecoderErrorLeaf, Lt as Decoder, Rt as DecoderError, zt as DecoderErrorComposite } from "../index-Xwjf0L5u.js";
2
+ export { Decoder, DecoderError, type DecoderErrorComposite, type DecoderErrorLeaf };
@@ -0,0 +1 @@
1
+ import{B as e,V as t}from"../src-DCf63AzV.js";export{e as Decoder,t as DecoderError};
@@ -1,2 +1,2 @@
1
- import { Dr as DoResult, Or as Doable, a as EmptyListError, c as LeftError, d as isDoCapable, f as unwrap, i as DoGenerator, l as LeftErrorType, n as Do, o as FailureError, r as DoAsync, s as FailureErrorType, t as $, u as NoneError } from "../index-DBYBJg-D.js";
1
+ import { At as FailureError, Cr as DoResult, Dt as DoAsync, Et as Do, Ft as isDoCapable, It as unwrap, Mt as LeftError, Nt as LeftErrorType, Ot as DoGenerator, Pt as NoneError, Tt as $, jt as FailureErrorType, kt as EmptyListError, wr as Doable } from "../index-Xwjf0L5u.js";
2
2
  export { $, Do, DoAsync, DoGenerator, type DoResult, type Doable, EmptyListError, FailureError, FailureErrorType, LeftError, LeftErrorType, NoneError, isDoCapable, unwrap };
package/dist/do/index.js CHANGED
@@ -1 +1 @@
1
- import{F as e,I as t,L as n,M as r,N as i,P as a,R as o,j as s,z as c}from"../src-P2lgP6cJ.js";export{s as $,r as Do,i as DoAsync,a as EmptyListError,e as FailureError,t as LeftError,n as NoneError,o as isDoCapable,c as unwrap};
1
+ import{F as e,I as t,L as n,M as r,N as i,P as a,R as o,j as s,z as c}from"../src-DCf63AzV.js";export{s as $,r as Do,i as DoAsync,a as EmptyListError,e as FailureError,t as LeftError,n as NoneError,o as isDoCapable,c as unwrap};
@@ -1,2 +1,2 @@
1
- import { C as isRight, S as isLeft, T as tryCatchAsync, _ as Right, b as TypeCheckLeft, g as LeftOf, h as Left, m as EitherBase, p as Either, v as RightOf, w as tryCatch, x as TypeCheckRight, y as TestEither } from "../index-DBYBJg-D.js";
1
+ import { $n as Left, Qn as EitherBase, Zn as Either, ar as TypeCheckRight, cr as tryCatch, er as LeftOf, ir as TypeCheckLeft, lr as tryCatchAsync, nr as RightOf, or as isLeft, rr as TestEither, sr as isRight, tr as Right } from "../index-Xwjf0L5u.js";
2
2
  export { Either, EitherBase, Left, LeftOf, Right, RightOf, TestEither, TypeCheckLeft, TypeCheckRight, isLeft, isRight, tryCatch, tryCatchAsync };
@@ -1 +1 @@
1
- import{St as e,_t as t,bt as n,gt as r,ht as i,mt as a,vt as o,xt as s,yt as c}from"../src-P2lgP6cJ.js";export{a as Either,i as Left,r as Right,t as TypeCheckLeft,o as TypeCheckRight,c as isLeft,n as isRight,s as tryCatch,e as tryCatchAsync};
1
+ import{_t as e,bt as t,gt as n,ht as r,mt as i,pt as a,vt as o,xt as s,yt as c}from"../src-DCf63AzV.js";export{a as Either,i as Left,r as Right,n as TypeCheckLeft,e as TypeCheckRight,o as isLeft,c as isRight,t as tryCatch,s as tryCatchAsync};
@@ -0,0 +1,2 @@
1
+ import { A as HttpQueryParams, B as ResponseDecodeError, D as HttpClient, E as Http, F as DecodeError, I as HttpError, L as HttpMethod, M as HttpRequestView, N as HttpResponse, O as HttpClientConfig, P as ParseMode, R as HttpStatusError, j as HttpRequestOptions, k as HttpMethodOptions, z as NetworkError } from "../index-Xwjf0L5u.js";
2
+ export { type DecodeError, Http, HttpClient, type HttpClientConfig, type HttpError, HttpError as HttpErrors, type HttpMethod, type HttpMethodOptions, type HttpQueryParams, type HttpRequestOptions, type HttpRequestView, type HttpResponse, type HttpStatusError, type NetworkError, type ParseMode, type ResponseDecodeError };
@@ -0,0 +1 @@
1
+ import{d as e,f as t,u as n}from"../src-DCf63AzV.js";export{n as Http,t as HttpClient,e as HttpErrors};
@@ -1,4 +1,4 @@
1
- var e=`1.3.0`;const t={Option:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Matchable`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`,`Traversable`],Either:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`],Try:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`],List:[`Collection`,`Doable`,`Iterable`,`Reshapeable`],Set:[`Collection`,`Iterable`],Map:[`Collection`,`Foldable`,`Iterable`,`KVTraversable`,`Serializable`],Obj:[`Doable`,`Promisable`,`Reshapeable`],Lazy:[`Applicative`,`AsyncMonad`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Serializable`,`Traversable`],LazyList:[`Foldable`,`Serializable`],Tuple:[`Foldable`,`Serializable`],Task:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Serializable`,`Traversable`]},n=e,r=(e,...n)=>Array.from(new Set([...t[e],...n])).sort(),i={Option:{description:`Safe nullable handling - Some<T> or None`,interfaces:r(`Option`),methods:{create:[`Option(v)`,`Option.none()`,`Some(v)`,`None()`],transform:[`.map(f)`,`.flatMap(f)`,`.filter(p)`,`.ap(ff)`],extract:[`.fold(n, s)`,`.foldAsync(n, s)`,`.orElse(d)`,`.orThrow()`,`.expect(() => never)`,`.orNull()`,`.match({Some, None})`],check:[`.isSome`,`.isNone`,`.isDefined`,`.isEmpty`],other:[`Option.sequence(arr)`,`Option.traverse(arr, f)`]}},Either:{description:`Error handling with Left (error) or Right (success)`,interfaces:r(`Either`,`Traversable`),methods:{create:[`Right(v)`,`Left(e)`,`Either.right(v)`,`Either.left(e)`,`Either.void()`],transform:[`.map(f)`,`.flatMap(f)`,`.mapLeft(f)`,`.swap()`],extract:[`.fold(l, r)`,`.foldAsync(l, r)`,`.orElse(d)`,`.orThrow()`,`.expect((l) => never)`,`.match({Left, Right})`],check:[`.isRight`,`.isLeft`],other:[`Either.sequence(arr)`,`Either.traverse(arr, f)`,`Either.fromNullable(v, e)`]}},Try:{description:`Wrap operations that may throw - Success<T> or Failure`,interfaces:r(`Try`,`Matchable`,`Traversable`),methods:{create:[`Try(() => expr)`,`Try.success(v)`,`Try.failure(e)`,`Try.fromPromise(p)`],transform:[`.map(f)`,`.flatMap(f)`,`.recover(f)`,`.recoverWith(f)`],extract:[`.fold(f, s)`,`.foldAsync(f, s)`,`.orElse(d)`,`.orThrow()`,`.expect((e) => never)`,`.toOption()`,`.toEither()`],check:[`.isSuccess`,`.isFailure`],other:[`Try.sequence(arr)`,`Try.traverse(arr, f)`]}},List:{description:`Immutable array with functional operations`,interfaces:r(`List`,`Functor`,`Monad`,`Foldable`,`Serializable`,`Traversable`),methods:{create:[`List([...])`,`List.of(...)`,`List.empty()`],transform:[`.map(f)`,`.flatMap(f)`,`.filter(p)`,`.take(n)`,`.takeWhile(p)`,`.takeRight(n)`,`.drop(n)`,`.dropWhile(p)`,`.concat(list)`,`.reverse()`,`.distinct()`,`.sorted()`,`.sortBy(f)`,`.zip(list)`,`.zipWithIndex()`,`.prepend(v)`,`.slice(s, e)`],extract:[`.fold(z, f)`,`.reduce(f)`,`.head`,`.headOption`,`.tail`,`.last`,`.lastOption`,`.init`,`.indexOf(v)`,`.toArray()`],check:[`.isEmpty`,`.nonEmpty`,`.size`,`.contains(v)`],other:[`.groupBy(f)`,`.partition(p)`,`.span(p)`]}},Set:{description:`Immutable set of unique values`,interfaces:r(`Set`,`Functor`,`Foldable`,`Serializable`,`Traversable`),methods:{create:[`Set([...])`,`Set.of(...)`,`Set.empty()`],transform:[`.map(f)`,`.filter(p)`,`.union(s)`,`.intersection(s)`,`.difference(s)`,`.add(v)`],extract:[`.fold(z, f)`,`.toArray()`],check:[`.has(v)`,`.isEmpty`,`.size`]}},Obj:{description:`Immutable object wrapper with fluent operations`,interfaces:r(`Obj`,`KVTraversable`,`Foldable`,`Matchable`,`Extractable`,`Serializable`),methods:{create:[`Obj({...})`,`Obj.of({...})`,`Obj.empty()`],transform:[`.set(k, v)`,`.assign(partial)`,`.merge(obj)`,`.when(cond, partial)`,`.omit(...keys)`,`.pick(...keys)`,`.map(f)`,`.flatMap(f)`],extract:[`.get(k)`,`.value()`,`.keys()`,`.values()`,`.entries()`,`.fold(n, s)`,`.match({Obj})`],check:[`.has(k)`,`.isEmpty`,`.size`]}},Map:{description:`Immutable key-value store`,interfaces:r(`Map`),methods:{create:[`Map([[k, v], ...])`,`Map.of([k, v], ...)`,`Map.empty()`],transform:[`.set(k, v)`,`.delete(k)`,`.map(f)`,`.filter(p)`,`.add(k, v)`],extract:[`.get(k)`,`.keys()`,`.values()`,`.entries()`,`.fold(z, f)`],check:[`.has(k)`,`.isEmpty`,`.size`]}},Lazy:{description:"Deferred computation with memoization. Note: `serialize()` and `toValue()` FORCE the thunk (visible side effect) since a closure cannot be JSON-serialized — there is no representable 'unevaluated post-serialize' state. Thunk failures are captured via SerializedError and rethrown on access after fromJSON.",interfaces:r(`Lazy`),methods:{create:[`Lazy(() => expr)`,`Lazy.fromValue(value) — wrap a non-deferred value`,`Lazy.evaluated(value) — reads as 'already-forced'; used by fromJSON`,`Lazy.fail(error) — Lazy that throws on access`],transform:[`.map(f)`,`.flatMap(f)`],extract:[`.fold(n, s)`,`.orElse(d)`,`.orThrow()`,`.get()`,`.toJSON()`,`Lazy.fromJSON(json)`],check:[`.isEvaluated`]}},LazyList:{description:`Lazy sequences for large/infinite data`,interfaces:r(`LazyList`,`Functor`,`Monad`,`Iterable`),methods:{create:[`LazyList.from(iter)`,`LazyList.range(start, end)`,`LazyList.infinite(f)`,`LazyList.fromJSON(json)`],transform:[`.map(f)`,`.filter(p)`,`.take(n)`,`.takeRight(n)`,`.drop(n)`,`.takeWhile(p)`,`.dropWhile(p)`,`.concat(ll)`,`.reverse()`,`.distinct()`,`.zip(ll)`,`.zipWithIndex()`],extract:[`.head`,`.headOption`,`.tail`,`.last`,`.lastOption`,`.init`,`.toArray()`,`.toJSON()`],check:[`.isEmpty`]}},Task:{description:`Async operations with cancellation and progress tracking. Returns TaskOutcome<T> (Ok/Err) which implements Functor, AsyncMonad, Foldable, Extractable, Serializable`,interfaces:r(`Task`),methods:{create:[`Task(params).Async(fn, errFn)`,`Task(params).Sync(fn, errFn)`,`Task.ok(value)`,`Task.err(error)`,`Task.fromEither(either)`,`Task.fromTry(try)`,`Task.fromPromise(fn)`,`Task.fromNodeCallback(fn)`,`Task.fromJSON(json) — reconstruct from serialize() output`],transform:[`.map(f)`,`.flatMap(f)`,`.mapError(f)`,`.recover(v)`,`.recoverWith(f)`],extract:[`.fold(onErr, onOk)`,`.match({Ok, Err})`,`.orElse(v)`,`.orThrow()`,`.toEither()`,`.toOption()`,`.toJSON()`],other:[`Task.cancellable(fn)`,`Task.withProgress(fn, onProgress)`,`Task.race(tasks, timeout?)`,`Task.getErrorChain(error)`,`Task.formatErrorChain(error)`]}},IO:{description:`Lazy effect type with typed errors and dependency injection`,interfaces:[`Functor`,`Monad`,`Foldable`,`Matchable`],methods:{create:[`IO(() => v)`,`IO.succeed(v)`,`IO.fail(e)`,`IO.sync(f)`,`IO.async(f)`,`IO.tryPromise({try, catch})`,`IO.fromEither(e)`,`IO.fromOption(o)`,`IO.fromTry(t)`],transform:[`.map(f)`,`.flatMap(f)`,`.tap(f)`,`.mapError(f)`,`.recover(v)`,`.recoverWith(f)`],extract:[`.run()`,`.runOrThrow()`,`.runSync()`,`.runSyncOrThrow()`,`.runExit()`,`.runOption()`,`.runTry()`,`.fold(onErr, onOk)`,`.match({failure, success})`],check:[],other:[`.catchTag(tag, f)`,`.catchAll(f)`,`.retry(n)`,`.retryWithDelay(n, ms)`,`.retryWhile({ n, while, delayMs? })`,`.retryWithBackoff({ n, baseMs, maxMs?, factor?, jitter?, while? })`,`.timeout(ms)`,`.delay(ms)`,`.zip(io)`,`.pipe(f)`,`IO.all([...])`,`IO.race([...])`,`IO.bracket(acquire, use, release)`,`IO.gen(function*() {...})`,`IO.Do.bind().map()`,`IO.service(Tag)`,`.provideService(Tag, impl)`,`.provideLayer(layer)`]}},Cond:{description:`Conditional expression builder - replace if-else chains`,interfaces:[],methods:{create:[`Cond<T>()`],other:[`.case(pred, result)`,`.otherwise(result)`,`.eval()`]}},Match:{description:`Pattern matching - replace switch statements`,interfaces:[],methods:{create:[`Match(value)`],other:[`.case(pattern, result)`,`.when(pred, result)`,`.default(result)`,`.done()`]}},Brand:{description:`Nominal typing without runtime overhead`,interfaces:[],methods:{create:[`Brand<K, T>(value)`],extract:[`.unwrap()`,`.toString()`]}},ValidatedBrand:{description:`Branded types with runtime validation`,interfaces:[],methods:{create:[`ValidatedBrand(validator)`,`.of(v)`,`.from(v)`,`.unsafeOf(v)`],check:[`.is(v)`],other:[`.refine(validator)`]}},Tuple:{description:`Fixed-size typed array`,interfaces:r(`Tuple`,`Typeable`,`Valuable`,`Iterable`),methods:{create:[`Tuple([a, b, ...])`,`Tuple.of(a, b, ...)`,`Tuple.fromJSON(json)`],extract:[`.first`,`.second`,`.toArray()`,`.toJSON()`],transform:[`.map(f)`]}},Stack:{description:`Immutable LIFO stack`,interfaces:[`Foldable`,`Collection`,`Serializable`,`Traversable`],methods:{create:[`Stack()`,`Stack.of(...)`],transform:[`.push(v)`,`.pop()`],extract:[`.peek()`,`.toArray()`],check:[`.isEmpty`,`.size`]}},Http:{description:"HTTP fetch wrapper returning IO<never, HttpError, HttpResponse<T>>. Pass `decode: Decoder<T>` (Either-returning) for typed responses; the deprecated `validate: (data) => T` field is still accepted for throw-pattern back-compat. Request bodies auto-flatten functype ADTs to primitives; `flatten: false` preserves tagged emission for functype-to-functype services. Per-call `params` (HttpQueryParams) appends query strings with proper encoding. Http.client accepts `beforeRequest` and `afterResponse` (both effectful IO transformers). `afterResponse` runs on the success path only — error handling belongs in .catchTag. Composes via .tap/.map/.flatMap/.catchTag/.retry/.retryWhile/.retryWithBackoff/.timeout.",interfaces:[],methods:{create:[`Http.get(url, { decode, params }?)`,`Http.post(url, { body, decode, params }?)`,`Http.put(url, { body, decode, params }?)`,`Http.patch(url, { body, decode, params }?)`,`Http.delete(url, { decode, params }?)`,`Http.request({ url, decode, params })`,`Http.client({ baseUrl, defaultHeaders, fetch, beforeRequest, afterResponse })`],transform:[`.tap(f)`,`.map(f)`,`.flatMap(f)`,`.mapError(f)`,`.retry(n)`,`.retryWithDelay(n, ms)`,`.retryWhile({ n, while, delayMs? })`,`.retryWithBackoff({ n, baseMs, maxMs?, factor?, jitter?, while? })`,`.timeout(ms)`],extract:[`.run()`,`.runOrThrow()`,`.runOption()`,`.runTry()`,`.runExit()`],check:[],other:[`.catchTag(tag, handler)`,`.catchAll(handler)`,`.recover(fallback)`,`decode: Decoder<T> (Either-returning, structural failures preserved)`,`validate: (data) => T (deprecated, throws — for back-compat / Zod .parse)`,`flatten: boolean (default true; false preserves tagged emission)`,`params: HttpQueryParams (scalar | array; undefined/null dropped; percent-encoded)`,`beforeRequest: (req) => IO<never, HttpError, HttpRequestView>`,`afterResponse: (HttpResponse<unknown>) => IO<never, HttpError, HttpResponse<unknown>> — success path only; refresh-on-401 uses .catchTag`]}},HttpError:{description:`Three-variant ADT for HTTP failures: NetworkError | HttpStatusError | DecodeError (also exported as ResponseDecodeError alias)`,interfaces:[],methods:{create:[`HttpError.networkError(url, method, cause)`,`HttpError.httpStatusError(url, method, status, statusText, body)`,`HttpError.decodeError(url, method, body, cause)`],check:[`HttpError.isNetworkError(e)`,`HttpError.isHttpStatusError(e)`,`HttpError.isDecodeError(e)`],other:[`HttpError.match(error, { NetworkError, HttpStatusError, DecodeError })`]}},Decoder:{description:"Either-returning decoder contract: `Decoder<A> = (raw: unknown) => Either<DecoderError, A>`. Bundled combinators for primitives + functype ADTs (Option/Either/List/Map, null-bias). `Decoder.tagged.*` round-trips the `{_tag, value}` shape for functype-to-functype services.",interfaces:[],methods:{create:[`Decoder.string / .number / .boolean / .unknown / .nullable(inner)`,`Decoder.option(inner)`,`Decoder.either.envelope({ok, err})`,`Decoder.either.discriminated({tag, leftTag, rightTag}, l, r)`,`Decoder.list(inner) / .array(inner) / .map(inner)`,`Decoder.object({k: Decoder<V>, ...}) — accumulates field failures into Composite`,`Decoder.tagged.option/either/try/list/map/obj(inner?) — round-trips {_tag, value}`],other:[`Pluggable by construction: any (raw) => Either<DecoderError, T> IS a Decoder<T>`,`Composes across sources: Decoder.object({a: Decoder.fromZod(s), b: Decoder.option(myAjv)})`]}},DecoderError:{description:"Recursive ADT for decoder failures: Leaf | Composite. Children mirror the input tree so multi-field failures preserve structural paths. Distinct from `HttpError.DecodeError` — this is the inner structural cause that the HTTP wrapper carries.",interfaces:[],methods:{create:[`DecoderError.leaf(path, message, cause?)`,`DecoderError.composite(path, children: List<DecoderError>)`],check:[`DecoderError.isLeaf(e)`,`DecoderError.isComposite(e)`],other:[`DecoderError.match(e, { Leaf, Composite })`,`DecoderError.prepend(segment, e) — used by combinators to attribute child failures`,`DecoderError.flatten(e): List<{path, message}> — collect leaves`,`DecoderError.format(e): string — render tree as multi-line`]}},Serialization:{description:"Universal `@functype`-marked JSON serialization. `deserialize` walks parsed JSON and reconstructs any functype value found — no type argument needed. Lenient: plain JSON passes through. Strict on unknown markers (defends against Effect/fp-ts `_tag` collision). 1.2.1 adds `toEnvelope`/`fromEnvelope` for nesting inside structured serializers (SuperJSON, DBOS), and `deserializeStrict` for boundaries that require functype on the wire.",interfaces:[],methods:{create:[],transform:[`Serialization.serialize(value: unknown): string — lenient JSON codec`,`Serialization.deserialize(json: string): Try<unknown> — lenient; pass-through for unmarked JSON`,`Serialization.deserializeStrict(json: string): Try<unknown> — Failure if no @functype marker at top level`,`Serialization.toEnvelope(value: unknown): JSONValue — parsed JSON shape (1.2.2 tightened from unknown)`,`Serialization.fromEnvelope(envelope: unknown): Try<unknown> — inverse of toEnvelope; input stays permissive (Postel's law)`,`Serialization.JSONValue — exported recursive type for the envelope shape`],check:[`Serialization.isFunctypeValue(v): v is Serializable<unknown>`],other:[`Plain JSON passthrough: non-functype data walks through unchanged (use deserializeStrict to reject)`,`Strict policy on unknown markers: unknown @functype marker → Try.Failure`,`Dispatch table covers all 12 Serializable types (Option, Either, Try, List, Set, Map, Obj, Stack, Tuple, LazyList, Lazy, Task)`,`Algebraic square: serialize ≡ JSON.stringify ∘ toEnvelope; deserialize ≡ fromEnvelope ∘ JSON.parse`,`No DBOS / SuperJSON facade — consumers wire host serializer in ~8 lines via toEnvelope/fromEnvelope`]}},SerializedError:{description:"Canonical Error projection used by Try.Failure, Task.Err, Lazy-with-thrown-thunk. Round-trips name + message + stack + cause chain. `e.name === 'TypeError'` survives; `instanceof TypeError` does NOT.",interfaces:[],methods:{create:[`serializeError(err: unknown): SerializedError`,`deserializeError(s: SerializedError | string): Error`],other:[`Shape: { name: string; message: string; stack?: string; cause?: SerializedError | string }`,`Non-Error throwables (strings, plain objects) projected under name: 'NonErrorThrowable'`,`Cause chain is recursive — arbitrary nesting depth survives`]}},Logger:{description:'Minimal 4-method ecosystem-wide logging interface (1.3.0+). Type-only — no runtime, no `console` dependency, no opinion on output format. Every functype-* package targets this shape. Reachable from `functype` (barrel, like every other type) or `functype/logger` (subpath, narrow). Concrete impls live in consumer packages: `consoleBootLogger` in `functype-os/config`, `DirectLogger` from `functype-log/direct` (structurally satisfies Logger — no adapter). If consumer has its own `Logger` type, rename on import: `import type { Logger as FunctypeLogger } from "functype"`. Clock/Random/Tracer NOT being added — those are framework abstractions; Logger is uniquely justified because every production TS app already has one.',interfaces:[],methods:{create:[`interface Logger { debug, info, warn, error: (msg, meta?) => void }`,`import type { Logger } from "functype"`,`import type { Logger } from "functype/logger" // alt`],check:[],other:[`All 4 methods MANDATORY (no defensive logger.debug?.() at call sites)`,`Signature: (message: string, metadata?: Record<string, unknown>) => void`,`DirectLogger from functype-log/direct structurally satisfies Logger (superset shape)`,`IO-shaped Logger from functype-log does NOT satisfy core Logger (methods return IO<>, not void) — bridge via toDirectLogger(ioLogger)`,`Used by: bootDiagnostics({ logger? }) in functype-os/config`]}}},a={Functor:{description:`Transform contained values`,methods:[`.map<B>(f: A => B): Functor<B>`]},Applicative:{extends:`Functor`,description:`Apply wrapped functions`,methods:[`.ap<B>(ff: Applicative<A => B>): Applicative<B>`]},Monad:{extends:`Applicative`,description:`Chain operations returning wrapped values`,methods:[`.flatMap<B>(f: A => Monad<B>): Monad<B>`]},Foldable:{description:`Extract via pattern matching`,methods:[`.fold<B>(empty: () => B, f: A => B): B`,`.foldLeft<B>(z: B, op: (B, A) => B): B`,`.foldRight<B>(z: B, op: (A, B) => B): B`]},Extractable:{description:`Get contained value with fallback`,methods:[`.orElse(d: T): T`,`.orThrow(e?: Error): T`,`.expect(handler: (e?) => never): T`,`.orNull(): T | null`,`.orUndefined(): T | undefined`]},Matchable:{description:`Pattern match on type variants`,methods:[`.match<R>(patterns: Record<Tag, Handler>): R`]},Traversable:{description:`Iterate and check contents`,methods:[`.size: number`,`.isEmpty: boolean`,`.contains(v: A): boolean`,`.reduce<B>(f, init): B`]},Collection:{description:`Collection operations`,methods:[`.toArray(): A[]`,`.forEach(f: A => void): void`]},Serializable:{description:`Convert to string formats`,methods:[`.serialize().toJSON(): string`,`.serialize().toYAML(): string`]}},o={Core:[`Option`,`Either`,`Try`,`Obj`],Collection:[`List`,`Set`,`Map`,`LazyList`,`Tuple`,`Stack`],Effect:[`IO`,`Task`,`Http`,`HttpError`,`Decoder`,`DecoderError`],Utility:[`Lazy`,`Cond`,`Match`,`Brand`,`ValidatedBrand`],Serialization:[`Serialization`,`SerializedError`],Service:[`Logger`]},s={Option:`export interface Option<out T extends Type>
1
+ var e=`1.4.0`;const t={Option:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Matchable`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`,`Traversable`],Either:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`],Try:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Reshapeable`,`Serializable`],List:[`Collection`,`Doable`,`Iterable`,`Reshapeable`],Set:[`Collection`,`Iterable`],Map:[`Collection`,`Foldable`,`Iterable`,`KVTraversable`,`Serializable`],Obj:[`Doable`,`Promisable`,`Reshapeable`],Lazy:[`Applicative`,`AsyncMonad`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Serializable`,`Traversable`],LazyList:[`Foldable`,`Serializable`],Tuple:[`Foldable`,`Serializable`],Task:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`,`Foldable`,`Functor`,`Monad`,`Promisable`,`Serializable`,`Traversable`]},n=e,r=(e,...n)=>Array.from(new Set([...t[e],...n])).sort(),i={Option:{description:`Safe nullable handling - Some<T> or None`,interfaces:r(`Option`),methods:{create:[`Option(v)`,`Option.none()`,`Some(v)`,`None()`],transform:[`.map(f)`,`.flatMap(f)`,`.filter(p)`,`.ap(ff)`],extract:[`.fold(n, s)`,`.foldAsync(n, s)`,`.orElse(d)`,`.orThrow()`,`.expect(() => never)`,`.orNull()`,`.match({Some, None})`,`.toEither(left | () => left)`,`.toList()`,`.toArray()`],check:[`.isSome()`,`.isNone()`,`.isEmpty`],other:[`Option.sequence(arr)`,`Option.traverse(arr, f)`]}},Either:{description:`Error handling with Left (error) or Right (success)`,interfaces:r(`Either`,`Traversable`),methods:{create:[`Right(v)`,`Left(e)`,`Either.right(v)`,`Either.left(e)`,`Either.void()`],transform:[`.map(f)`,`.flatMap(f)`,`.mapLeft(f)`,`.swap()`],extract:[`.fold(l, r)`,`.foldAsync(l, r)`,`.orElse(d)`,`.orThrow()`,`.expect((l) => never)`,`.match({Left, Right})`],check:[`.isRight()`,`.isLeft()`],other:[`Either.sequence(arr)`,`Either.traverse(arr, f)`,`Either.fromNullable(v, e)`]}},Try:{description:`Wrap operations that may throw - Success<T> or Failure`,interfaces:r(`Try`,`Matchable`,`Traversable`),methods:{create:[`Try(() => expr)`,`Try.success(v)`,`Try.failure(e)`,`Try.fromPromise(p)`,`Try.async(() => Promise<T>)`],transform:[`.map(f)`,`.flatMap(f)`,`.recover(f)`,`.recoverWith(f)`],extract:[`.fold(f, s)`,`.foldAsync(f, s)`,`.orElse(d)`,`.orThrow()`,`.expect((e) => never)`,`.toOption()`,`.toEither(left | (err) => left)`,`.toList()`,`.toArray()`],check:[`.isSuccess()`,`.isFailure()`],other:[`Try.sequence(arr)`,`Try.traverse(arr, f)`]}},List:{description:`Immutable array with functional operations`,interfaces:r(`List`,`Functor`,`Monad`,`Foldable`,`Serializable`,`Traversable`),methods:{create:[`List([...])`,`List.of(...)`,`List.empty()`],transform:[`.map(f)`,`.flatMap(f)`,`.filter(p)`,`.take(n)`,`.takeWhile(p)`,`.takeRight(n)`,`.drop(n)`,`.dropWhile(p)`,`.concat(list)`,`.reverse()`,`.distinct()`,`.sorted()`,`.sortBy(f)`,`.zip(list)`,`.zipWithIndex()`,`.prepend(v)`,`.slice(s, e)`],extract:[`.fold(z, f)`,`.reduce(f)`,`.head`,`.headOption`,`.tail`,`.last`,`.lastOption`,`.init`,`.indexOf(v)`,`.toArray()`],check:[`.isEmpty`,`.nonEmpty`,`.size`,`.contains(v)`],other:[`.groupBy(f)`,`.partition(p)`,`.span(p)`]}},Set:{description:`Immutable set of unique values`,interfaces:r(`Set`,`Functor`,`Foldable`,`Serializable`,`Traversable`),methods:{create:[`Set([...])`,`Set.of(...)`,`Set.empty()`],transform:[`.map(f)`,`.filter(p)`,`.union(s)`,`.intersection(s)`,`.difference(s)`,`.add(v)`],extract:[`.fold(z, f)`,`.toArray()`],check:[`.has(v)`,`.isEmpty`,`.size`]}},Obj:{description:`Immutable object wrapper with fluent operations`,interfaces:r(`Obj`,`KVTraversable`,`Foldable`,`Matchable`,`Extractable`,`Serializable`),methods:{create:[`Obj({...})`,`Obj.of({...})`,`Obj.empty()`],transform:[`.set(k, v)`,`.assign(partial)`,`.merge(obj)`,`.when(cond, partial)`,`.omit(...keys)`,`.pick(...keys)`,`.map(f)`,`.flatMap(f)`],extract:[`.get(k)`,`.value()`,`.keys()`,`.values()`,`.entries()`,`.fold(n, s)`,`.match({Obj})`],check:[`.has(k)`,`.isEmpty`,`.size`]}},Map:{description:`Immutable key-value store`,interfaces:r(`Map`),methods:{create:[`Map([[k, v], ...])`,`Map.of([k, v], ...)`,`Map.empty()`],transform:[`.set(k, v)`,`.delete(k)`,`.map(f)`,`.filter(p)`,`.add(k, v)`],extract:[`.get(k)`,`.keys()`,`.values()`,`.entries()`,`.fold(z, f)`],check:[`.has(k)`,`.isEmpty`,`.size`]}},Lazy:{description:"Deferred computation with memoization. Note: `serialize()` and `toValue()` FORCE the thunk (visible side effect) since a closure cannot be JSON-serialized — there is no representable 'unevaluated post-serialize' state. Thunk failures are captured via SerializedError and rethrown on access after fromJSON.",interfaces:r(`Lazy`),methods:{create:[`Lazy(() => expr)`,`Lazy.fromValue(value) — wrap a non-deferred value`,`Lazy.evaluated(value) — reads as 'already-forced'; used by fromJSON`,`Lazy.fail(error) — Lazy that throws on access`],transform:[`.map(f)`,`.flatMap(f)`],extract:[`.fold(n, s)`,`.orElse(d)`,`.orThrow()`,`.get()`,`.toJSON()`,`Lazy.fromJSON(json)`],check:[`.isEvaluated`]}},LazyList:{description:`Lazy sequences for large/infinite data`,interfaces:r(`LazyList`,`Functor`,`Monad`,`Iterable`),methods:{create:[`LazyList.from(iter)`,`LazyList.range(start, end)`,`LazyList.infinite(f)`,`LazyList.fromJSON(json)`],transform:[`.map(f)`,`.filter(p)`,`.take(n)`,`.takeRight(n)`,`.drop(n)`,`.takeWhile(p)`,`.dropWhile(p)`,`.concat(ll)`,`.reverse()`,`.distinct()`,`.zip(ll)`,`.zipWithIndex()`],extract:[`.head`,`.headOption`,`.tail`,`.last`,`.lastOption`,`.init`,`.toArray()`,`.toJSON()`],check:[`.isEmpty`]}},Task:{description:`Async operations with cancellation and progress tracking. Returns TaskOutcome<T> (Ok/Err) which implements Functor, AsyncMonad, Foldable, Extractable, Serializable`,interfaces:r(`Task`),methods:{create:[`Task(params).Async(fn, errFn)`,`Task(params).Sync(fn, errFn)`,`Task.ok(value)`,`Task.err(error)`,`Task.fromEither(either)`,`Task.fromTry(try)`,`Task.fromPromise(fn)`,`Task.fromNodeCallback(fn)`,`Task.fromJSON(json) — reconstruct from serialize() output`],transform:[`.map(f)`,`.flatMap(f)`,`.mapError(f)`,`.recover(v)`,`.recoverWith(f)`],extract:[`.fold(onErr, onOk)`,`.match({Ok, Err})`,`.orElse(v)`,`.orThrow()`,`.toEither()`,`.toOption()`,`.toJSON()`],other:[`Task.cancellable(fn)`,`Task.withProgress(fn, onProgress)`,`Task.race(tasks, timeout?)`,`Task.getErrorChain(error)`,`Task.formatErrorChain(error)`]}},TaskOutcome:{description:`Result of a Task execution — Ok<T> or Err<T>. Implements Functor, AsyncMonad, Foldable, Extractable, Serializable. Construct via Ok(v) / Err(e) or as the resolved value of Task(...).Sync() / Task(...).Async().`,interfaces:[`AsyncMonad`,`Extractable`,`Foldable`,`Functor`,`Serializable`],methods:{create:[`Ok(value)`,`Err(error)`,`Task.ok(value)`,`Task.err(error)`],transform:[`.map(f)`,`.flatMap(f)`,`.mapError(f)`,`.recover(v)`,`.recoverWith(f)`,`.mapAsync(f)`,`.flatMapAsync(f)`],extract:[`.fold(onErr, onOk)`,`.match({Ok, Err})`,`.orElse(v)`,`.orThrow()`,`.toEither()`,`.toOption()`,`.toJSON()`],check:[`.isOk()`,`.isErr()`,`.isSuccess()`,`.isFailure()`]}},TaskResult:{description:"Type alias for `Promise<TaskOutcome<T>>`. Returned by Task(params).Async(...) and adapter functions like Fs.readFile, Process.exec. Await it to get the inner TaskOutcome; chain Promise methods on the outside, TaskOutcome methods after the await.",interfaces:[],methods:{create:[`Task(params).Async(fn, errFn) → TaskResult<T>`,`Task.fromPromise(fn) → (...args) => TaskResult<U>`],other:[`await taskResult → TaskOutcome<T>`,`// then use any TaskOutcome method (.fold, .map, .toEither, ...)`]}},IO:{description:`Lazy effect type with typed errors and dependency injection`,interfaces:[`Functor`,`Monad`,`Foldable`,`Matchable`],methods:{create:[`IO(() => v)`,`IO.succeed(v)`,`IO.fail(e)`,`IO.sync(f)`,`IO.async(f)`,`IO.tryPromise({try, catch})`,`IO.fromEither(e)`,`IO.fromOption(o)`,`IO.fromTry(t)`],transform:[`.map(f)`,`.flatMap(f)`,`.tap(f)`,`.mapError(f)`,`.recover(v)`,`.recoverWith(f)`],extract:[`.run()`,`.runOrThrow()`,`.runSync()`,`.runSyncOrThrow()`,`.runExit()`,`.runOption()`,`.runTry()`,`.fold(onErr, onOk)`,`.match({failure, success})`],check:[],other:[`.catchTag(tag, f)`,`.catchAll(f)`,`.retry(n)`,`.retryWithDelay(n, ms)`,`.retryWhile({ n, while, delayMs? })`,`.retryWithBackoff({ n, baseMs, maxMs?, factor?, jitter?, while? })`,`.timeout(ms)`,`.delay(ms)`,`.zip(io)`,`.pipe(f)`,`IO.all([...])`,`IO.race([...])`,`IO.bracket(acquire, use, release)`,`IO.gen(function*() {...})`,`IO.Do.bind().map()`,`IO.service(Tag)`,`.provideService(Tag, impl)`,`.provideLayer(layer)`]}},Cond:{description:`Conditional expression builder - replace if-else chains`,interfaces:[],methods:{create:[`Cond<T>()`],other:[`.case(pred, result)`,`.otherwise(result)`,`.eval()`]}},Match:{description:`Pattern matching - replace switch statements`,interfaces:[],methods:{create:[`Match(value)`],other:[`.case(pattern, result)`,`.when(pred, result)`,`.default(result)`,`.done()`]}},Brand:{description:`Nominal typing without runtime overhead`,interfaces:[],methods:{create:[`Brand<K, T>(value)`],extract:[`.unwrap()`,`.toString()`]}},ValidatedBrand:{description:`Branded types with runtime validation`,interfaces:[],methods:{create:[`ValidatedBrand(validator)`,`.of(v)`,`.from(v)`,`.unsafeOf(v)`],check:[`.is(v)`],other:[`.refine(validator)`]}},Tuple:{description:`Fixed-size typed array`,interfaces:r(`Tuple`,`Typeable`,`Valuable`,`Iterable`),methods:{create:[`Tuple([a, b, ...])`,`Tuple.of(a, b, ...)`,`Tuple.fromJSON(json)`],extract:[`.first`,`.second`,`.toArray()`,`.toJSON()`],transform:[`.map(f)`]}},Stack:{description:`Immutable LIFO stack`,interfaces:[`Foldable`,`Collection`,`Serializable`,`Traversable`],methods:{create:[`Stack()`,`Stack.of(...)`],transform:[`.push(v)`,`.pop()`],extract:[`.peek()`,`.toArray()`],check:[`.isEmpty`,`.size`]}},Http:{description:"HTTP fetch wrapper returning IO<never, HttpError, HttpResponse<T>>. Pass `decode: Decoder<T>` (Either-returning) for typed responses; the deprecated `validate: (data) => T` field is still accepted for throw-pattern back-compat. Request bodies auto-flatten functype ADTs to primitives; `flatten: false` preserves tagged emission for functype-to-functype services. Per-call `params` (HttpQueryParams) appends query strings with proper encoding. Http.client accepts `beforeRequest` and `afterResponse` (both effectful IO transformers). `afterResponse` runs on the success path only — error handling belongs in .catchTag. Composes via .tap/.map/.flatMap/.catchTag/.retry/.retryWhile/.retryWithBackoff/.timeout.",interfaces:[],methods:{create:[`Http.get(url, { decode, params }?)`,`Http.post(url, { body, decode, params }?)`,`Http.put(url, { body, decode, params }?)`,`Http.patch(url, { body, decode, params }?)`,`Http.delete(url, { decode, params }?)`,`Http.request({ url, decode, params })`,`Http.client({ baseUrl, defaultHeaders, fetch, beforeRequest, afterResponse })`],transform:[`.tap(f)`,`.map(f)`,`.flatMap(f)`,`.mapError(f)`,`.retry(n)`,`.retryWithDelay(n, ms)`,`.retryWhile({ n, while, delayMs? })`,`.retryWithBackoff({ n, baseMs, maxMs?, factor?, jitter?, while? })`,`.timeout(ms)`],extract:[`.run()`,`.runOrThrow()`,`.runOption()`,`.runTry()`,`.runExit()`],check:[],other:[`.catchTag(tag, handler)`,`.catchAll(handler)`,`.recover(fallback)`,`decode: Decoder<T> (Either-returning, structural failures preserved)`,`validate: (data) => T (deprecated, throws — for back-compat / Zod .parse)`,`flatten: boolean (default true; false preserves tagged emission)`,`params: HttpQueryParams (scalar | array; undefined/null dropped; percent-encoded)`,`beforeRequest: (req) => IO<never, HttpError, HttpRequestView>`,`afterResponse: (HttpResponse<unknown>) => IO<never, HttpError, HttpResponse<unknown>> — success path only; refresh-on-401 uses .catchTag`]}},HttpError:{description:`Three-variant ADT for HTTP failures: NetworkError | HttpStatusError | DecodeError (also exported as ResponseDecodeError alias)`,interfaces:[],methods:{create:[`HttpError.networkError(url, method, cause)`,`HttpError.httpStatusError(url, method, status, statusText, body)`,`HttpError.decodeError(url, method, body, cause)`],check:[`HttpError.isNetworkError(e)`,`HttpError.isHttpStatusError(e)`,`HttpError.isDecodeError(e)`],other:[`HttpError.match(error, { NetworkError, HttpStatusError, DecodeError })`]}},Decoder:{description:"Either-returning decoder contract: `Decoder<A> = (raw: unknown) => Either<DecoderError, A>`. Bundled combinators for primitives + functype ADTs (Option/Either/List/Map, null-bias). `Decoder.tagged.*` round-trips the `{_tag, value}` shape for functype-to-functype services.",interfaces:[],methods:{create:[`Decoder.string / .number / .boolean / .unknown / .nullable(inner)`,`Decoder.option(inner)`,`Decoder.either.envelope({ok, err})`,`Decoder.either.discriminated({tag, leftTag, rightTag}, l, r)`,`Decoder.list(inner) / .array(inner) / .map(inner)`,`Decoder.object({k: Decoder<V>, ...}) — accumulates field failures into Composite`,`Decoder.tagged.option/either/try/list/map/obj(inner?) — round-trips {_tag, value}`],other:[`Pluggable by construction: any (raw) => Either<DecoderError, T> IS a Decoder<T>`,`Composes across sources: Decoder.object({a: Decoder.fromZod(s), b: Decoder.option(myAjv)})`]}},DecoderError:{description:"Recursive ADT for decoder failures: Leaf | Composite. Children mirror the input tree so multi-field failures preserve structural paths. Distinct from `HttpError.DecodeError` — this is the inner structural cause that the HTTP wrapper carries.",interfaces:[],methods:{create:[`DecoderError.leaf(path, message, cause?)`,`DecoderError.composite(path, children: List<DecoderError>)`],check:[`DecoderError.isLeaf(e)`,`DecoderError.isComposite(e)`],other:[`DecoderError.match(e, { Leaf, Composite })`,`DecoderError.prepend(segment, e) — used by combinators to attribute child failures`,`DecoderError.flatten(e): List<{path, message}> — collect leaves`,`DecoderError.format(e): string — render tree as multi-line`]}},Serialization:{description:"Universal `@functype`-marked JSON serialization. `deserialize` walks parsed JSON and reconstructs any functype value found — no type argument needed. Lenient: plain JSON passes through. Strict on unknown markers (defends against Effect/fp-ts `_tag` collision). 1.2.1 adds `toEnvelope`/`fromEnvelope` for nesting inside structured serializers (SuperJSON, DBOS), and `deserializeStrict` for boundaries that require functype on the wire.",interfaces:[],methods:{create:[],transform:[`Serialization.serialize(value: unknown): string — lenient JSON codec`,`Serialization.deserialize(json: string): Try<unknown> — lenient; pass-through for unmarked JSON`,`Serialization.deserializeStrict(json: string): Try<unknown> — Failure if no @functype marker at top level`,`Serialization.toEnvelope(value: unknown): JSONValue — parsed JSON shape (1.2.2 tightened from unknown)`,`Serialization.fromEnvelope(envelope: unknown): Try<unknown> — inverse of toEnvelope; input stays permissive (Postel's law)`,`Serialization.JSONValue — exported recursive type for the envelope shape`],check:[`Serialization.isFunctypeValue(v): v is Serializable<unknown>`],other:[`Plain JSON passthrough: non-functype data walks through unchanged (use deserializeStrict to reject)`,`Strict policy on unknown markers: unknown @functype marker → Try.Failure`,`Dispatch table covers all 12 Serializable types (Option, Either, Try, List, Set, Map, Obj, Stack, Tuple, LazyList, Lazy, Task)`,`Algebraic square: serialize ≡ JSON.stringify ∘ toEnvelope; deserialize ≡ fromEnvelope ∘ JSON.parse`,`No DBOS / SuperJSON facade — consumers wire host serializer in ~8 lines via toEnvelope/fromEnvelope`]}},SerializedError:{description:"Canonical Error projection used by Try.Failure, Task.Err, Lazy-with-thrown-thunk. Round-trips name + message + stack + cause chain. `e.name === 'TypeError'` survives; `instanceof TypeError` does NOT.",interfaces:[],methods:{create:[`serializeError(err: unknown): SerializedError`,`deserializeError(s: SerializedError | string): Error`],other:[`Shape: { name: string; message: string; stack?: string; cause?: SerializedError | string }`,`Non-Error throwables (strings, plain objects) projected under name: 'NonErrorThrowable'`,`Cause chain is recursive — arbitrary nesting depth survives`]}},Logger:{description:"Minimal 4-method ecosystem-wide logging interface (1.3.0+). Type-only — no runtime, no `console` dependency, no opinion on output format. Every functype-* package targets this shape. SUBPATH-ONLY in 1.3.x (`functype/logger`) as a temporary workaround for a non-deterministic rolldown chunk-splitter bug; barrel-parity will be restored when rolldown is fixed. Concrete impls live in consumer packages: `consoleBootLogger` in `functype-os/config`, `DirectLogger` from `functype-log/direct` (structurally satisfies Logger — no adapter). Clock/Random/Tracer NOT being added — those are framework abstractions; Logger is uniquely justified because every production TS app already has one.",interfaces:[],methods:{create:[`interface Logger { debug, info, warn, error: (msg, meta?) => void }`,`import type { Logger } from "functype/logger"`],check:[],other:[`All 4 methods MANDATORY (no defensive logger.debug?.() at call sites)`,`Signature: (message: string, metadata?: Record<string, unknown>) => void`,`DirectLogger from functype-log/direct structurally satisfies Logger (superset shape)`,`IO-shaped Logger from functype-log does NOT satisfy core Logger (methods return IO<>, not void) — bridge via toDirectLogger(ioLogger)`,`Used by: bootDiagnostics({ logger? }) in functype-os/config`]}}},a={Functor:{description:`Transform contained values`,methods:[`.map<B>(f: A => B): Functor<B>`]},Applicative:{extends:`Functor`,description:`Apply wrapped functions`,methods:[`.ap<B>(ff: Applicative<A => B>): Applicative<B>`]},Monad:{extends:`Applicative`,description:`Chain operations returning wrapped values`,methods:[`.flatMap<B>(f: A => Monad<B>): Monad<B>`]},Foldable:{description:`Extract via pattern matching`,methods:[`.fold<B>(empty: () => B, f: A => B): B`,`.foldLeft<B>(z: B, op: (B, A) => B): B`,`.foldRight<B>(z: B, op: (A, B) => B): B`]},Extractable:{description:`Get contained value with fallback`,methods:[`.orElse(d: T): T`,`.orThrow(e?: Error): T`,`.expect(handler: (e?) => never): T`,`.orNull(): T | null`,`.orUndefined(): T | undefined`]},Matchable:{description:`Pattern match on type variants`,methods:[`.match<R>(patterns: Record<Tag, Handler>): R`]},Traversable:{description:`Iterate and check contents`,methods:[`.size: number`,`.isEmpty: boolean`,`.contains(v: A): boolean`,`.reduce<B>(f, init): B`]},Collection:{description:`Collection operations`,methods:[`.toArray(): A[]`,`.forEach(f: A => void): void`]},Serializable:{description:`Convert to string formats`,methods:[`.serialize().toJSON(): string`,`.serialize().toYAML(): string`]}},o={Core:[`Option`,`Either`,`Try`,`Obj`],Collection:[`List`,`Set`,`Map`,`LazyList`,`Tuple`,`Stack`],Effect:[`IO`,`Task`,`TaskOutcome`,`TaskResult`,`Http`,`HttpError`,`Decoder`,`DecoderError`],Utility:[`Lazy`,`Cond`,`Match`,`Brand`,`ValidatedBrand`],Serialization:[`Serialization`,`SerializedError`],Service:[`Logger`]},s={Option:`export interface Option<out T extends Type>
2
2
  extends Functype<T, "Some" | "None">, Promisable<T>, Doable<T>, Reshapeable<T> {
3
3
  /** The contained value (undefined for None) */
4
4
  readonly value: T | undefined
@@ -118,14 +118,24 @@ var e=`1.3.0`;const t={Option:[`Applicative`,`AsyncMonad`,`Doable`,`Extractable`
118
118
  * @returns A List containing the value if Some, or empty List if None
119
119
  */
120
120
  toList(): List<T>
121
+ /**
122
+ * Converts this Option to a plain readonly array.
123
+ * @returns \`[value]\` if Some, \`[]\` if None. Symmetric with \`toList()\` but
124
+ * skips the List wrapper for code that just wants Array-prototype methods
125
+ * or spread into another array.
126
+ */
127
+ toArray(): readonly T[]
121
128
  /** The number of elements in this Option (0 or 1) */
122
129
  size: number
123
130
  /**
124
131
  * Converts this Option to an Either
125
- * @param left - The value to use for Left if this Option is None
126
- * @returns Either.Right with the contained value if Some, or Either.Left with left if None
132
+ * @param leftOrBuilder - The Left value to use if None, or a thunk producing it.
133
+ * Pass a thunk when the Left value is expensive to construct or carries
134
+ * context (e.g. \`() => ConfigError(missing)\`) so the cost is paid only
135
+ * on the None path. Eager value is fine for cheap errors.
136
+ * @returns Right(value) if Some, else Left(leftOrBuilder()) / Left(leftOrBuilder)
127
137
  */
128
- toEither<E>(left: E): Either<E, T>
138
+ toEither<E>(leftOrBuilder: E | (() => E)): Either<E, T>
129
139
  /**
130
140
  * Returns a string representation of this Option
131
141
  * @returns A string representation
@@ -332,6 +342,12 @@ export interface RightOf<out L extends Type, out R extends Type> extends EitherB
332
342
  orNull: () => T | null
333
343
  orUndefined: () => T | undefined
334
344
  toOption: () => Option<T>
345
+ /**
346
+ * Converts to a plain readonly array: \`[value]\` for Success, \`[]\` for Failure.
347
+ * Symmetric with \`Try.toList()\` but skips the List wrapper for code that
348
+ * just wants to feed Array.prototype methods or spread into another array.
349
+ */
350
+ toArray: () => readonly T[]
335
351
  /**
336
352
  * Converts to Either<E, T>. Failure becomes Left(builder(error)) when given a function,
337
353
  * or Left(leftValue) when given a value. Success becomes Right(value).
@@ -0,0 +1,2 @@
1
+ import { Cn as FunctypeBase, Sn as Functype, wn as FunctypeCollection, xn as FunctypeSum } from "../index-Xwjf0L5u.js";
2
+ export { Functype, FunctypeBase, FunctypeCollection, FunctypeSum };
File without changes