functype 0.17.0 → 0.18.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.
@@ -1,3 +1,3 @@
1
1
  import u from'safe-stable-stringify';function T(e,r){return Object.assign(e,r)}var p=e=>{let r={_tag:"Tuple",map:t=>{let n=t(e);return m(n)},flatMap:t=>t(e),get:t=>e[t],toArray:()=>e,length:e.length,[Symbol.iterator](){let t=0;return {next:()=>t<e.length?{value:e[t++],done:false}:{value:void 0,done:true}}},fold:(t,n)=>e.length===0?t():n(e[0]),foldLeft:t=>n=>e.reduce(n,t),foldRight:t=>n=>e.reduceRight((l,o)=>n(o,l),t),pipe:t=>t(r),serialize:()=>({toJSON:()=>JSON.stringify({_tag:"Tuple",value:e}),toYAML:()=>`_tag: Tuple
2
- value: ${u(e)}`,toBinary:()=>Buffer.from(JSON.stringify({_tag:"Tuple",value:e})).toString("base64")}),toValue:()=>({_tag:"Tuple",value:e}),toString:()=>`Tuple(${e.map(t=>String(t)).join(", ")})`};return r},a=e=>p(e),i={of:(...e)=>p(e),pair:(e,r)=>p([e,r]),triple:(e,r,t)=>p([e,r,t]),empty:()=>p([]),from:e=>p(e)},m=T(a,i);export{T as a,m as b};//# sourceMappingURL=chunk-BQJB6CCW.mjs.map
3
- //# sourceMappingURL=chunk-BQJB6CCW.mjs.map
2
+ value: ${u(e)}`,toBinary:()=>Buffer.from(JSON.stringify({_tag:"Tuple",value:e})).toString("base64")}),toValue:()=>({_tag:"Tuple",value:e}),toString:()=>`Tuple(${e.map(t=>String(t)).join(", ")})`};return r},a=e=>p(e),i={of:(...e)=>p(e),pair:(e,r)=>p([e,r]),triple:(e,r,t)=>p([e,r,t]),empty:()=>p([]),from:e=>p(e)},m=T(a,i);export{T as a,m as b};//# sourceMappingURL=chunk-7JJIUQXK.mjs.map
3
+ //# sourceMappingURL=chunk-7JJIUQXK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/companion/Companion.ts","../src/tuple/Tuple.ts"],"names":["Companion","object","companion","TupleObject","values","tuple","f","mapValue","Tuple","index","onEmpty","onValue","z","op","acc","value","stringify","v","TupleConstructor","TupleCompanion","first","second","third"],"mappings":"qCAsBO,SAASA,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACsB,CAEtB,OAAO,MAAA,CAAO,MAAA,CAAOD,CAAAA,CAAQC,CAAS,CACxC,CCGA,IAAMC,CAAAA,CAAiCC,CAAAA,EAAwB,CAC7D,IAAMC,CAAAA,CAAkB,CACtB,KAAM,OAAA,CACN,GAAA,CAAwBC,CAAAA,EAAiC,CACvD,IAAMC,CAAAA,CAAWD,CAAAA,CAAEF,CAAM,EACzB,OAAOI,CAAAA,CAAMD,CAAQ,CACvB,CAAA,CAEA,OAAA,CAA4BD,CAAAA,EACnBA,CAAAA,CAAEF,CAAM,CAAA,CAGjB,GAAA,CAAwBK,CAAAA,EACfL,CAAAA,CAAOK,CAAK,CAAA,CAGrB,OAAA,CAAS,IACAL,EAGT,MAAA,CAAQA,CAAAA,CAAO,MAAA,CAEf,CAAC,MAAA,CAAO,QAAQ,CAAA,EAAyB,CACvC,IAAIK,CAAAA,CAAQ,CAAA,CACZ,OAAO,CACL,IAAA,CAAM,IACAA,CAAAA,CAAQL,CAAAA,CAAO,OACV,CACL,KAAA,CAAOA,CAAAA,CAAOK,CAAAA,EAAO,CAAA,CACrB,IAAA,CAAM,KACR,CAAA,CAEO,CACL,KAAA,CAAO,MAAA,CACP,IAAA,CAAM,IACR,CAGN,CACF,CAAA,CAGA,IAAA,CAAM,CAAIC,CAAAA,CAAkBC,CAAAA,GACnBP,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAIM,CAAAA,EAAQ,CAAIC,CAAAA,CAAQP,EAAO,CAAC,CAAE,CAAA,CAG7D,QAAA,CACMQ,CAAAA,EACHC,CAAAA,EACQT,CAAAA,CAAO,MAAA,CAAOS,EAAID,CAAC,CAAA,CAG9B,SAAA,CACMA,CAAAA,EACHC,CAAAA,EACQT,CAAAA,CAAO,WAAA,CAAe,CAACU,EAAKC,CAAAA,GAAUF,CAAAA,CAAGE,CAAAA,CAAOD,CAAG,CAAA,CAAGF,CAAC,CAAA,CAIlE,IAAA,CAAUN,GAAiCA,CAAAA,CAAED,CAAK,CAAA,CAGlD,SAAA,CAAW,KACF,CACL,MAAA,CAAQ,IAAM,KAAK,SAAA,CAAU,CAAE,IAAA,CAAM,OAAA,CAAS,KAAA,CAAOD,CAAO,CAAC,CAAA,CAC7D,OAAQ,IAAM,CAAA;AAAA,OAAA,EAAuBY,CAAAA,CAAUZ,CAAM,CAAC,CAAA,CAAA,CACtD,SAAU,IAAM,MAAA,CAAO,KAAK,IAAA,CAAK,SAAA,CAAU,CAAE,IAAA,CAAM,OAAA,CAAS,MAAOA,CAAO,CAAC,CAAC,CAAA,CAAE,QAAA,CAAS,QAAQ,CACjG,CAAA,CAAA,CAIF,OAAA,CAAS,KAAO,CAAE,IAAA,CAAM,QAAS,KAAA,CAAOA,CAAO,GAE/C,QAAA,CAAU,IAAM,CAAA,MAAA,EAASA,CAAAA,CAAO,GAAA,CAAKa,CAAAA,EAAM,OAAOA,CAAC,CAAC,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAClE,CAAA,CAEA,OAAOZ,CACT,CAAA,CAEMa,CAAAA,CAAsCd,GACnCD,CAAAA,CAAYC,CAAM,EAGrBe,CAAAA,CAAiB,CAOrB,GAAI,CAAA,GAAsBf,CAAAA,GACjBD,EAAYC,CAAM,CAAA,CAS3B,KAAM,CAAiCgB,CAAAA,CAAUC,IACxClB,CAAAA,CAAY,CAACiB,EAAOC,CAAM,CAAW,CAAA,CAS9C,MAAA,CAAQ,CAAiDD,CAAAA,CAAUC,EAAWC,CAAAA,GACrEnB,CAAAA,CAAY,CAACiB,CAAAA,CAAOC,CAAAA,CAAQC,CAAK,CAAc,CAAA,CASxD,KAAA,CAAO,IACEnB,CAAAA,CAAY,EAAQ,CAAA,CAQ7B,IAAA,CAAyBC,GAChBD,CAAAA,CAAYC,CAAM,CAE7B,CAAA,CAwBaI,CAAAA,CAAQR,CAAAA,CAAUkB,CAAAA,CAAkBC,CAAc","file":"chunk-7JJIUQXK.mjs","sourcesContent":["/**\n * Creates a function-object hybrid similar to Scala's companion objects.\n * This utility allows creating TypeScript function objects with attached methods,\n * mimicking Scala's class + companion object pattern without using classes.\n *\n * @param object The main function that will be invoked when the object is called\n * @param companion Additional static methods to attach to the function\n * @returns A function with the attached methods\n *\n * @example\n * const greet = (name: string) => `Hello, ${name}!`;\n * const methods = {\n * formal: (name: string) => `Good day, ${name}.`,\n * casual: (name: string) => `Hey ${name}!`\n * };\n * const Greeter = createCompanionObject(greet, methods);\n *\n * // Usage:\n * Greeter(\"World\"); // Hello, World!\n * Greeter.formal(\"Sir\"); // Good day, Sir.\n * Greeter.casual(\"Friend\"); // Hey Friend!\n */\nexport function Companion<ObjectF extends object, CompanionF extends object>(\n object: ObjectF,\n companion: CompanionF,\n): ObjectF & CompanionF {\n // eslint-disable-next-line functional/immutable-data\n return Object.assign(object, companion)\n}\n","import stringify from \"safe-stable-stringify\"\n\nimport { Companion } from \"@/companion/Companion\"\nimport type { Foldable } from \"@/foldable/Foldable\"\nimport type { Pipe } from \"@/pipe\"\nimport type { Serializable } from \"@/serializable/Serializable\"\nimport type { Typeable } from \"@/typeable/Typeable\"\nimport type { Type } from \"@/types\"\n\nexport interface Tuple<T extends Type[]>\n extends Foldable<T[number]>,\n Pipe<Tuple<T>>,\n Serializable<Tuple<T>>,\n Typeable<\"Tuple\"> {\n get<K extends number>(index: K): T[K]\n\n map<U extends Type[]>(f: (value: T) => U): Tuple<U>\n\n flatMap<U extends Type[]>(f: (value: T) => Tuple<U>): Tuple<U>\n\n toArray(): T\n\n length: number\n\n [Symbol.iterator](): Iterator<T[number]>\n\n toString(): string\n\n toValue(): { _tag: \"Tuple\"; value: T }\n}\n\nconst TupleObject = <T extends Type[]>(values: T): Tuple<T> => {\n const tuple: Tuple<T> = {\n _tag: \"Tuple\",\n map: <U extends Type[]>(f: (value: T) => U): Tuple<U> => {\n const mapValue = f(values)\n return Tuple(mapValue)\n },\n\n flatMap: <U extends Type[]>(f: (value: T) => Tuple<U>): Tuple<U> => {\n return f(values)\n },\n\n get: <K extends number>(index: K): T[K] => {\n return values[index]\n },\n\n toArray: (): T => {\n return values\n },\n\n length: values.length,\n\n [Symbol.iterator](): Iterator<T[number]> {\n let index = 0\n return {\n next: (): IteratorResult<T[number]> => {\n if (index < values.length) {\n return {\n value: values[index++],\n done: false,\n }\n } else {\n return {\n value: undefined,\n done: true,\n }\n }\n },\n }\n },\n\n // Foldable implementation\n fold: <B>(onEmpty: () => B, onValue: (value: T[number]) => B): B => {\n return values.length === 0 ? onEmpty() : onValue(values[0]!)\n },\n\n foldLeft:\n <B>(z: B) =>\n (op: (b: B, a: T[number]) => B) => {\n return values.reduce(op, z)\n },\n\n foldRight:\n <B>(z: B) =>\n (op: (a: T[number], b: B) => B): B => {\n return values.reduceRight<B>((acc, value) => op(value, acc), z)\n },\n\n // Pipe implementation\n pipe: <U>(f: (value: Tuple<T>) => U): U => f(tuple),\n\n // Serializable implementation\n serialize: () => {\n return {\n toJSON: () => JSON.stringify({ _tag: \"Tuple\", value: values }),\n toYAML: () => `_tag: Tuple\\nvalue: ${stringify(values)}`,\n toBinary: () => Buffer.from(JSON.stringify({ _tag: \"Tuple\", value: values })).toString(\"base64\"),\n }\n },\n\n // Valuable implementation\n toValue: () => ({ _tag: \"Tuple\", value: values }),\n\n toString: () => `Tuple(${values.map((v) => String(v)).join(\", \")})`,\n }\n\n return tuple\n}\n\nconst TupleConstructor = <T extends Type[]>(values: T): Tuple<T> => {\n return TupleObject(values)\n}\n\nconst TupleCompanion = {\n /**\n * Create a Tuple from multiple arguments\n * @example\n * const t = Tuple.of(1, \"hello\", true)\n * // TypeScript infers: Tuple<[number, string, boolean]>\n */\n of: <T extends Type[]>(...values: T): Tuple<T> => {\n return TupleObject(values)\n },\n\n /**\n * Create a Tuple of size 2 (pair)\n * @example\n * const pair = Tuple.pair(\"key\", 42)\n * // TypeScript infers: Tuple<[string, number]>\n */\n pair: <A extends Type, B extends Type>(first: A, second: B): Tuple<[A, B]> => {\n return TupleObject([first, second] as [A, B])\n },\n\n /**\n * Create a Tuple of size 3 (triple)\n * @example\n * const triple = Tuple.triple(\"x\", 10, true)\n * // TypeScript infers: Tuple<[string, number, boolean]>\n */\n triple: <A extends Type, B extends Type, C extends Type>(first: A, second: B, third: C): Tuple<[A, B, C]> => {\n return TupleObject([first, second, third] as [A, B, C])\n },\n\n /**\n * Create an empty Tuple\n * @example\n * const empty = Tuple.empty()\n * // TypeScript infers: Tuple<[]>\n */\n empty: (): Tuple<[]> => {\n return TupleObject([] as [])\n },\n\n /**\n * Create a Tuple from an array (alias for constructor)\n * @example\n * const t = Tuple.from([1, 2, 3])\n */\n from: <T extends Type[]>(values: T): Tuple<T> => {\n return TupleObject(values)\n },\n}\n\n/**\n * Tuple provides a type-safe, fixed-length array with functional operations.\n *\n * @example\n * // Creating tuples\n * const t1 = Tuple([1, \"hello\", true])\n * const t2 = Tuple.of(1, \"hello\", true)\n * const pair = Tuple.pair(\"key\", 42)\n *\n * @example\n * // Type-safe access\n * const triple = Tuple.triple(\"x\", 10, true)\n * const first = triple.get(0) // string\n * const second = triple.get(1) // number\n * const third = triple.get(2) // boolean\n *\n * @example\n * // Functional operations\n * const doubled = Tuple([1, 2, 3])\n * .map(arr => arr.map(x => x * 2))\n * .toArray() // [2, 4, 6]\n */\nexport const Tuple = Companion(TupleConstructor, TupleCompanion)\n"]}
@@ -1,5 +1,5 @@
1
- import { O as Option, E as Either, L as List, T as Try, x as Reshapeable, b as Doable } from '../Either-CM1xSzLl.js';
2
- export { D as DoResult } from '../Either-CM1xSzLl.js';
1
+ import { O as Option, E as Either, L as List, T as Try, x as Reshapeable, b as Doable } from '../Either-Ccg0S1uS.js';
2
+ export { D as DoResult } from '../Either-Ccg0S1uS.js';
3
3
  import '../Typeable-DiGVtDnq.js';
4
4
 
5
5
  /**
package/dist/do/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{X as $,T as Do,U as DoAsync,_ as EmptyListError,$ as FailureError,Z as LeftError,Y as NoneError,V as isDoCapable,W as unwrap}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{ca as $,_ as Do,$ as DoAsync,fa as EmptyListError,ga as FailureError,ea as LeftError,da as NoneError,aa as isDoCapable,ba as unwrap}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export { E as Either, e as Left, R as Right, d as TestEither, h as TypeCheckLeft, g as TypeCheckRight, f as isLeft, i as isRight, t as tryCatch, j as tryCatchAsync } from '../Either-CM1xSzLl.js';
1
+ export { E as Either, e as Left, R as Right, d as TestEither, h as TypeCheckLeft, g as TypeCheckRight, f as isLeft, i as isRight, t as tryCatch, j as tryCatchAsync } from '../Either-Ccg0S1uS.js';
2
2
  import '../Typeable-DiGVtDnq.js';
@@ -1,2 +1,2 @@
1
- export{t as Either,m as Left,l as Right,r as TypeCheckLeft,q as TypeCheckRight,o as isLeft,n as isRight,p as tryCatch,s as tryCatchAsync}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{z as Either,s as Left,r as Right,x as TypeCheckLeft,w as TypeCheckRight,u as isLeft,t as isRight,v as tryCatch,y as tryCatchAsync}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,4 +1,4 @@
1
- import { E as Either } from '../Either-CM1xSzLl.js';
1
+ import { E as Either } from '../Either-Ccg0S1uS.js';
2
2
  import { T as Type } from '../Typeable-DiGVtDnq.js';
3
3
 
4
4
  /**
@@ -1,2 +1,2 @@
1
- export{N as FPromise,M as FPromiseCompanion}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{U as FPromise,T as FPromiseCompanion}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Brand } from './branded/index.js';
2
2
  export { BrandedBoolean, BrandedBoolean as BrandedBooleanType, BrandedNumber, BrandedNumber as BrandedNumberType, BrandedString, BrandedString as BrandedStringType, ExtractBrand, Unwrap, createBrander, hasBrand, unwrap as unwrapBrand } from './branded/index.js';
3
- import { L as List, O as Option, E as Either, D as DoResult, F as FunctypeBase, a as Extractable, A as AsyncMonad, P as Promisable, b as Doable, T as Try, c as Traversable, M as Matchable } from './Either-CM1xSzLl.js';
4
- export { u as Applicative, C as Collection, r as CollectionOps, s as ContainerOps, v as Functor, l as Functype, m as FunctypeCollection, e as Left, n as MatchableUtils, w as Monad, N as None, o as OptionConstructor, R as Right, p as Set, S as Some, d as TestEither, h as TypeCheckLeft, g as TypeCheckRight, q as TypeNames, k as isExtractable, f as isLeft, i as isRight, t as tryCatch, j as tryCatchAsync } from './Either-CM1xSzLl.js';
3
+ import { L as List, O as Option, E as Either, D as DoResult, F as FunctypeBase, a as Extractable, A as AsyncMonad, P as Promisable, b as Doable, T as Try, c as Traversable, M as Matchable } from './Either-Ccg0S1uS.js';
4
+ export { u as Applicative, C as Collection, r as CollectionOps, s as ContainerOps, v as Functor, l as Functype, m as FunctypeCollection, e as Left, n as MatchableUtils, w as Monad, N as None, o as OptionConstructor, R as Right, p as Set, S as Some, d as TestEither, h as TypeCheckLeft, g as TypeCheckRight, q as TypeNames, k as isExtractable, f as isLeft, i as isRight, t as tryCatch, j as tryCatchAsync } from './Either-Ccg0S1uS.js';
5
5
  import { T as Type, F as Foldable, P as Pipe, S as Serializable, a as Typeable } from './Typeable-DiGVtDnq.js';
6
6
  export { E as ExtractTag, b as SerializationMethods, c as TypeableParams, i as isTypeable } from './Typeable-DiGVtDnq.js';
7
7
  import { FPromise } from './fpromise/index.js';
@@ -285,6 +285,37 @@ declare function PatternString(brand: string, pattern: RegExp): ValidatedBrandCo
285
285
  */
286
286
  declare function Companion<ObjectF extends object, CompanionF extends object>(object: ObjectF, companion: CompanionF): ObjectF & CompanionF;
287
287
 
288
+ /**
289
+ * Helper types for working with the Companion pattern
290
+ * @module CompanionTypes
291
+ */
292
+ /**
293
+ * Extracts the companion methods type from a Companion object
294
+ * @typeParam T - The Companion type
295
+ * @example
296
+ * ```typescript
297
+ * type OptionCompanionMethods = CompanionMethods<typeof Option>
298
+ * // { from: ..., none: ..., fromJSON: ..., etc. }
299
+ * ```
300
+ */
301
+ type CompanionMethods<T> = T extends ((...args: never[]) => unknown) & infer C ? C : never;
302
+ /**
303
+ * Extracts the instance type from a constructor function
304
+ * @typeParam T - The constructor function type
305
+ * @example
306
+ * ```typescript
307
+ * type OptionInstance = InstanceType<typeof Option>
308
+ * // Option<T>
309
+ * ```
310
+ */
311
+ type InstanceType<T> = T extends (...args: infer Args) => infer R ? R extends (...args: unknown[]) => unknown ? ReturnType<R> : R : never;
312
+ /**
313
+ * Type guard to check if a value is a Companion object (has both constructor and companion methods)
314
+ * @param value - The value to check
315
+ * @returns True if value is a Companion object
316
+ */
317
+ declare const isCompanion: (value: unknown) => value is ((...args: never[]) => unknown) & Record<string, unknown>;
318
+
288
319
  /** @internal */
289
320
  type LazyCondChain<T> = {
290
321
  when: (condition: () => boolean, value: () => T) => LazyCondChain<T>;
@@ -1365,7 +1396,20 @@ type Identity<T> = {
1365
1396
  id: T;
1366
1397
  isSame?: (other: Identity<T>) => boolean;
1367
1398
  };
1368
- declare function Identity<T>(value: T): Identity<T>;
1399
+ declare const Identity: (<T>(value: T) => Identity<T>) & {
1400
+ /**
1401
+ * Creates an Identity. Alias for Identity constructor.
1402
+ * @param value - The value to wrap
1403
+ * @returns Identity instance
1404
+ */
1405
+ of: <T>(value: T) => Identity<T>;
1406
+ /**
1407
+ * Creates an Identity. Same as of.
1408
+ * @param value - The value to wrap
1409
+ * @returns Identity instance
1410
+ */
1411
+ pure: <T>(value: T) => Identity<T>;
1412
+ };
1369
1413
 
1370
1414
  /**
1371
1415
  * Lazy type module
@@ -1680,13 +1724,82 @@ interface Ref<A> {
1680
1724
  */
1681
1725
  modify<B>(f: (current: A) => [A, B]): B;
1682
1726
  }
1727
+ declare const Ref: (<A extends Type>(initial: A) => Ref<A>) & {
1728
+ /**
1729
+ * Creates a Ref. Alias for Ref constructor.
1730
+ * @param initial - The initial value
1731
+ * @returns Ref instance
1732
+ */
1733
+ of: <A extends Type>(initial: A) => Ref<A>;
1734
+ };
1735
+
1683
1736
  /**
1684
- * Creates a new mutable reference containing the given value
1737
+ * Serialization result containing methods for different formats
1685
1738
  */
1686
- declare function Ref<A extends Type>(initial: A): Ref<A>;
1687
- declare namespace Ref {
1688
- var of: typeof Ref;
1739
+ interface SerializationResult {
1740
+ /** Serializes to JSON string */
1741
+ toJSON: () => string;
1742
+ /** Serializes to YAML string */
1743
+ toYAML: () => string;
1744
+ /** Serializes to base64-encoded binary string */
1745
+ toBinary: () => string;
1689
1746
  }
1747
+ /**
1748
+ * Creates a serializer for a simple tagged value
1749
+ * @param tag - The type tag (e.g., "Some", "List", "Success")
1750
+ * @param value - The value to serialize
1751
+ * @returns Serialization methods
1752
+ */
1753
+ declare const createSerializer: (tag: string, value: unknown) => SerializationResult;
1754
+ /**
1755
+ * Creates a serializer for complex objects with custom serialization logic
1756
+ * @param data - The data object to serialize (should include _tag)
1757
+ * @returns Serialization methods
1758
+ */
1759
+ declare const createCustomSerializer: (data: Record<string, unknown>) => SerializationResult;
1760
+ /**
1761
+ * Generic deserializer from JSON
1762
+ * @param json - The JSON string to parse
1763
+ * @param reconstructor - Function to reconstruct the type from parsed data
1764
+ * @returns Reconstructed instance
1765
+ */
1766
+ declare const fromJSON: <T>(json: string, reconstructor: (parsed: {
1767
+ _tag: string;
1768
+ [key: string]: unknown;
1769
+ }) => T) => T;
1770
+ /**
1771
+ * Generic deserializer from YAML (simple format)
1772
+ * @param yaml - The YAML string to parse
1773
+ * @param reconstructor - Function to reconstruct the type from parsed data
1774
+ * @returns Reconstructed instance
1775
+ */
1776
+ declare const fromYAML: <T>(yaml: string, reconstructor: (parsed: {
1777
+ _tag: string;
1778
+ [key: string]: unknown;
1779
+ }) => T) => T;
1780
+ /**
1781
+ * Generic deserializer from binary (base64-encoded JSON)
1782
+ * @param binary - The base64-encoded binary string
1783
+ * @param reconstructor - Function to reconstruct the type from parsed data
1784
+ * @returns Reconstructed instance
1785
+ */
1786
+ declare const fromBinary: <T>(binary: string, reconstructor: (parsed: {
1787
+ _tag: string;
1788
+ [key: string]: unknown;
1789
+ }) => T) => T;
1790
+ /**
1791
+ * Creates companion serialization methods for a type
1792
+ * @param reconstructor - Function to reconstruct the type from parsed data
1793
+ * @returns Companion methods object with fromJSON, fromYAML, and fromBinary
1794
+ */
1795
+ declare const createSerializationCompanion: <T>(reconstructor: (parsed: {
1796
+ _tag: string;
1797
+ [key: string]: unknown;
1798
+ }) => T) => {
1799
+ fromJSON: (json: string) => T;
1800
+ fromYAML: (yaml: string) => T;
1801
+ fromBinary: (binary: string) => T;
1802
+ };
1690
1803
 
1691
1804
  /**
1692
1805
  * Parameters for creating a Valuable instance
@@ -1818,4 +1931,4 @@ declare const Stack: (<A extends Type>(values?: A[]) => Stack<A>) & {
1818
1931
  fromBinary: <A>(binary: string) => Stack<A>;
1819
1932
  };
1820
1933
 
1821
- export { type Async, AsyncMonad, Base, BoundedNumber, BoundedString, Brand, type CancellationToken, type CancellationTokenSource, Companion, Cond, DoResult, Doable, ESMap, type ESMapType, Either, type EitherKind, EmailAddress, Err, type ErrorChainElement, type ErrorCode, type ErrorFormatterOptions, type ErrorMessage, type ErrorStatus, type ErrorWithTaskInfo, Extractable, FPromise, type FieldValidation, Foldable, FoldableUtils, type FormValidation, FunctypeBase, HKT, ISO8601Date, Identity, IntegerNumber, type Kind, Lazy, LazyList, Lazy as LazyType, List, type ListKind, Match, Matchable, NAME, NonEmptyString, NonNegativeNumber, Ok, Option, type OptionKind, ParseError, PatternString, Pipe, PositiveInteger, PositiveNumber, Promisable, Ref, Ref as RefType, Serializable, Stack, type Sync, type TaggedThrowable, Task, type TaskErrorInfo, type TaskFailure, type TaskMetadata, type TaskOutcome, type TaskParams, type TaskResult, type TaskSuccess, Throwable, type ThrowableType, Traversable, Try, type TryKind, Type, Typeable, TypedError, type TypedErrorContext, UUID, type UniversalContainer, UrlString, ValidatedBrand, type ValidatedBrandCompanion, ValidatedBrand as ValidatedBrandType, Validation, type ValidationRule, type Validator, Valuable, type ValuableParams, createCancellationTokenSource, createErrorSerializer, formatError, formatStackTrace, isTaggedThrowable, safeStringify };
1934
+ export { type Async, AsyncMonad, Base, BoundedNumber, BoundedString, Brand, type CancellationToken, type CancellationTokenSource, Companion, type CompanionMethods, Cond, DoResult, Doable, ESMap, type ESMapType, Either, type EitherKind, EmailAddress, Err, type ErrorChainElement, type ErrorCode, type ErrorFormatterOptions, type ErrorMessage, type ErrorStatus, type ErrorWithTaskInfo, Extractable, FPromise, type FieldValidation, Foldable, FoldableUtils, type FormValidation, FunctypeBase, HKT, ISO8601Date, Identity, type InstanceType, IntegerNumber, type Kind, Lazy, LazyList, Lazy as LazyType, List, type ListKind, Match, Matchable, NAME, NonEmptyString, NonNegativeNumber, Ok, Option, type OptionKind, ParseError, PatternString, Pipe, PositiveInteger, PositiveNumber, Promisable, Ref, Ref as RefType, Serializable, type SerializationResult, Stack, type Sync, type TaggedThrowable, Task, type TaskErrorInfo, type TaskFailure, type TaskMetadata, type TaskOutcome, type TaskParams, type TaskResult, type TaskSuccess, Throwable, type ThrowableType, Traversable, Try, type TryKind, Type, Typeable, TypedError, type TypedErrorContext, UUID, type UniversalContainer, UrlString, ValidatedBrand, type ValidatedBrandCompanion, ValidatedBrand as ValidatedBrandType, Validation, type ValidationRule, type Validator, Valuable, type ValuableParams, createCancellationTokenSource, createCustomSerializer, createErrorSerializer, createSerializationCompanion, createSerializer, formatError, formatStackTrace, fromBinary, fromJSON, fromYAML, isCompanion, isTaggedThrowable, safeStringify };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{X as $,J as Base,E as BoundedNumber,F as BoundedString,H as Cond,T as Do,U as DoAsync,ma as ESMap,t as Either,A as EmailAddress,_ as EmptyListError,P as Err,N as FPromise,M as FPromiseCompanion,$ as FailureError,ia as FoldableUtils,ja as HKT,D as ISO8601Date,ka as Identity,x as IntegerNumber,la as Lazy,g as LazyList,m as Left,Z as LeftError,k as List,na as Map,I as Match,oa as MatchableUtils,K as NAME,z as NonEmptyString,w as NonNegativeNumber,b as None,Y as NoneError,Q as Ok,d as Option,c as OptionConstructor,ea as ParseError,G as PatternString,y as PositiveInteger,v as PositiveNumber,f as Ref,l as Right,e as Set,a as Some,pa as Stack,S as Task,L as Throwable,h as Try,r as TypeCheckLeft,q as TypeCheckRight,i as Typeable,fa as TypedError,C as UUID,B as UrlString,u as ValidatedBrand,ga as Validation,qa as Valuable,R as createCancellationTokenSource,da as createErrorSerializer,ca as formatError,ba as formatStackTrace,V as isDoCapable,ha as isExtractable,o as isLeft,n as isRight,O as isTaggedThrowable,j as isTypeable,aa as safeStringify,p as tryCatch,s as tryCatchAsync,W as unwrap}from'./chunk-LW2YTB56.mjs';export{a as Companion,b as Tuple}from'./chunk-BQJB6CCW.mjs';export{a as Brand,g as BrandedBoolean,f as BrandedNumber,e as BrandedString,d as createBrander,c as hasBrand,b as unwrapBrand}from'./chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{ca as $,Q as Base,K as BoundedNumber,L as BoundedString,O as Cond,_ as Do,$ as DoAsync,ta as ESMap,z as Either,G as EmailAddress,fa as EmptyListError,W as Err,U as FPromise,T as FPromiseCompanion,ga as FailureError,pa as FoldableUtils,qa as HKT,J as ISO8601Date,ra as Identity,D as IntegerNumber,sa as Lazy,m as LazyList,s as Left,ea as LeftError,q as List,ua as Map,P as Match,va as MatchableUtils,R as NAME,F as NonEmptyString,C as NonNegativeNumber,h as None,da as NoneError,X as Ok,j as Option,i as OptionConstructor,la as ParseError,M as PatternString,E as PositiveInteger,B as PositiveNumber,l as Ref,r as Right,k as Set,g as Some,wa as Stack,Z as Task,S as Throwable,n as Try,x as TypeCheckLeft,w as TypeCheckRight,o as Typeable,ma as TypedError,I as UUID,H as UrlString,A as ValidatedBrand,na as Validation,xa as Valuable,Y as createCancellationTokenSource,b as createCustomSerializer,ka as createErrorSerializer,f as createSerializationCompanion,a as createSerializer,ja as formatError,ia as formatStackTrace,e as fromBinary,c as fromJSON,d as fromYAML,N as isCompanion,aa as isDoCapable,oa as isExtractable,u as isLeft,t as isRight,V as isTaggedThrowable,p as isTypeable,ha as safeStringify,v as tryCatch,y as tryCatchAsync,ba as unwrap}from'./chunk-6ZIR6EKC.mjs';export{a as Companion,b as Tuple}from'./chunk-7JJIUQXK.mjs';export{a as Brand,g as BrandedBoolean,f as BrandedNumber,e as BrandedString,d as createBrander,c as hasBrand,b as unwrapBrand}from'./chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export { L as List } from '../Either-CM1xSzLl.js';
1
+ export { L as List } from '../Either-Ccg0S1uS.js';
2
2
  import '../Typeable-DiGVtDnq.js';
@@ -1,2 +1,2 @@
1
- export{k as List}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{q as List}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,4 +1,4 @@
1
- import { c as Traversable, C as Collection, O as Option } from '../Either-CM1xSzLl.js';
1
+ import { c as Traversable, C as Collection, O as Option } from '../Either-Ccg0S1uS.js';
2
2
  import { a as Typeable, S as Serializable, P as Pipe, F as Foldable, T as Type } from '../Typeable-DiGVtDnq.js';
3
3
  import { Tuple } from '../tuple/index.js';
4
4
 
@@ -1,2 +1,2 @@
1
- export{na as Map}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{ua as Map}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export { N as None, O as Option, o as OptionConstructor, S as Some } from '../Either-CM1xSzLl.js';
1
+ export { N as None, O as Option, o as OptionConstructor, S as Some } from '../Either-Ccg0S1uS.js';
2
2
  import '../Typeable-DiGVtDnq.js';
@@ -1,2 +1,2 @@
1
- export{b as None,d as Option,c as OptionConstructor,a as Some}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{h as None,j as Option,i as OptionConstructor,g as Some}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export { p as Set } from '../Either-CM1xSzLl.js';
1
+ export { p as Set } from '../Either-Ccg0S1uS.js';
2
2
  import '../Typeable-DiGVtDnq.js';
@@ -1,2 +1,2 @@
1
- export{e as Set}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{k as Set}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export { T as Try, q as TypeNames } from '../Either-CM1xSzLl.js';
1
+ export { T as Try, q as TypeNames } from '../Either-Ccg0S1uS.js';
2
2
  import '../Typeable-DiGVtDnq.js';
@@ -1,2 +1,2 @@
1
- export{h as Try}from'../chunk-LW2YTB56.mjs';import'../chunk-BQJB6CCW.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{n as Try}from'../chunk-6ZIR6EKC.mjs';import'../chunk-7JJIUQXK.mjs';import'../chunk-OR6V4TCO.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1,2 +1,2 @@
1
- export{b as Tuple}from'../chunk-BQJB6CCW.mjs';//# sourceMappingURL=index.mjs.map
1
+ export{b as Tuple}from'../chunk-7JJIUQXK.mjs';//# sourceMappingURL=index.mjs.map
2
2
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functype",
3
- "version": "0.17.0",
3
+ "version": "0.18.0",
4
4
  "type": "module",
5
5
  "description": "A functional programming library for TypeScript, using immutable data structures and type classes",
6
6
  "author": "jordan.burke@gmail.com",
@@ -12,36 +12,36 @@
12
12
  "homepage": "https://functype.org/",
13
13
  "url": "https://github.com/jordanburke/functype",
14
14
  "devDependencies": {
15
- "@eslint/compat": "^1.4.0",
15
+ "@eslint/compat": "^1.4.1",
16
16
  "@eslint/eslintrc": "^3.3.1",
17
- "@eslint/js": "^9.38.0",
17
+ "@eslint/js": "^9.39.1",
18
18
  "@semantic-release/commit-analyzer": "^13.0.1",
19
19
  "@semantic-release/github": "^11.0.6",
20
20
  "@semantic-release/npm": "^12.0.2",
21
21
  "@semantic-release/release-notes-generator": "^14.1.0",
22
- "@types/node": "^22.18.11",
23
- "@typescript-eslint/eslint-plugin": "^8.46.1",
24
- "@typescript-eslint/parser": "^8.46.1",
25
- "@vitest/coverage-v8": "^3.2.4",
26
- "@vitest/ui": "^3.2.4",
22
+ "@types/node": "^22.19.1",
23
+ "@typescript-eslint/eslint-plugin": "^8.46.4",
24
+ "@typescript-eslint/parser": "^8.46.4",
25
+ "@vitest/coverage-v8": "^4.0.9",
26
+ "@vitest/ui": "^4.0.9",
27
27
  "cross-env": "^10.1.0",
28
- "eslint": "^9.38.0",
28
+ "eslint": "^9.39.1",
29
29
  "eslint-config-functype": "1.3.0",
30
30
  "eslint-config-prettier": "^10.1.8",
31
31
  "eslint-plugin-functional": "^9.0.2",
32
32
  "eslint-plugin-prettier": "^5.5.4",
33
33
  "eslint-plugin-simple-import-sort": "^12.1.1",
34
34
  "fast-check": "^4.3.0",
35
- "globals": "^16.4.0",
35
+ "globals": "^16.5.0",
36
36
  "prettier": "^3.6.2",
37
- "rimraf": "^6.0.1",
37
+ "rimraf": "^6.1.0",
38
38
  "semantic-release": "^24.2.9",
39
39
  "ts-node": "^10.9.2",
40
- "tsup": "^8.5.0",
40
+ "tsup": "^8.5.1",
41
41
  "tsx": "^4.20.6",
42
42
  "typedoc": "^0.28.14",
43
43
  "typescript": "5.9.2",
44
- "vitest": "^3.2.4"
44
+ "vitest": "^4.0.9"
45
45
  },
46
46
  "types": "./dist/index.d.ts",
47
47
  "module": "./dist/index.mjs",
@@ -141,6 +141,18 @@
141
141
  "types": "./dist/branded/index.d.ts",
142
142
  "default": "./dist/branded/index.mjs"
143
143
  }
144
+ },
145
+ "./companion": {
146
+ "import": {
147
+ "types": "./dist/companion/index.d.ts",
148
+ "default": "./dist/companion/index.mjs"
149
+ }
150
+ },
151
+ "./serialization": {
152
+ "import": {
153
+ "types": "./dist/serialization/index.d.ts",
154
+ "default": "./dist/serialization/index.mjs"
155
+ }
144
156
  }
145
157
  },
146
158
  "files": [
@@ -152,7 +164,7 @@
152
164
  "sideEffects": false,
153
165
  "scripts": {
154
166
  "validate": "pnpm validate:core && pnpm validate:landing",
155
- "validate:core": "pnpm format && pnpm lint && pnpm test && pnpm build",
167
+ "validate:core": "pnpm format && pnpm lint && pnpm test && pnpm docs:validate && pnpm build",
156
168
  "validate:landing": "cd landing && pnpm validate",
157
169
  "format": "prettier --write .",
158
170
  "format:check": "prettier --check .",
@@ -172,8 +184,8 @@
172
184
  "docs:preprocess": "tsx scripts/preprocess-docs.ts",
173
185
  "docs": "pnpm docs:preprocess && typedoc",
174
186
  "docs:watch": "typedoc --watch",
175
- "docs:validate": "tsx scripts/validate-docs.ts",
176
- "postdocs": "node -e \"console.log('Documentation generated in ./typedocs')\"",
187
+ "docs:sync": "tsx scripts/sync-docs.ts",
188
+ "docs:validate": "tsx scripts/validate-docs.ts && tsx scripts/sync-docs.ts",
177
189
  "analyze:size": "pnpm build && node ./scripts/analyze-bundle-size.js",
178
190
  "landing:dev": "cd landing && pnpm dev",
179
191
  "landing:build": "cd landing && pnpm build",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/companion/Companion.ts","../src/tuple/Tuple.ts"],"names":["Companion","object","companion","TupleObject","values","tuple","f","mapValue","Tuple","index","onEmpty","onValue","z","op","acc","value","stringify","v","TupleConstructor","TupleCompanion","first","second","third"],"mappings":"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","file":"chunk-BQJB6CCW.mjs","sourcesContent":["/**\n * Creates a function-object hybrid similar to Scala's companion objects.\n * This utility allows creating TypeScript function objects with attached methods,\n * mimicking Scala's class + companion object pattern without using classes.\n *\n * @param object The main function that will be invoked when the object is called\n * @param companion Additional static methods to attach to the function\n * @returns A function with the attached methods\n *\n * @example\n * const greet = (name: string) => `Hello, ${name}!`;\n * const methods = {\n * formal: (name: string) => `Good day, ${name}.`,\n * casual: (name: string) => `Hey ${name}!`\n * };\n * const Greeter = createCompanionObject(greet, methods);\n *\n * // Usage:\n * Greeter(\"World\"); // Hello, World!\n * Greeter.formal(\"Sir\"); // Good day, Sir.\n * Greeter.casual(\"Friend\"); // Hey Friend!\n */\nexport function Companion<ObjectF extends object, CompanionF extends object>(\n object: ObjectF,\n companion: CompanionF,\n): ObjectF & CompanionF {\n return Object.assign(object, companion)\n}\n","import stringify from \"safe-stable-stringify\"\n\nimport { Companion } from \"@/companion/Companion\"\nimport type { Foldable } from \"@/foldable/Foldable\"\nimport type { Pipe } from \"@/pipe\"\nimport type { Serializable } from \"@/serializable/Serializable\"\nimport type { Typeable } from \"@/typeable/Typeable\"\nimport type { Type } from \"@/types\"\n\nexport interface Tuple<T extends Type[]>\n extends Foldable<T[number]>,\n Pipe<Tuple<T>>,\n Serializable<Tuple<T>>,\n Typeable<\"Tuple\"> {\n get<K extends number>(index: K): T[K]\n\n map<U extends Type[]>(f: (value: T) => U): Tuple<U>\n\n flatMap<U extends Type[]>(f: (value: T) => Tuple<U>): Tuple<U>\n\n toArray(): T\n\n length: number\n\n [Symbol.iterator](): Iterator<T[number]>\n\n toString(): string\n\n toValue(): { _tag: \"Tuple\"; value: T }\n}\n\nconst TupleObject = <T extends Type[]>(values: T): Tuple<T> => {\n const tuple: Tuple<T> = {\n _tag: \"Tuple\",\n map: <U extends Type[]>(f: (value: T) => U): Tuple<U> => {\n const mapValue = f(values)\n return Tuple(mapValue)\n },\n\n flatMap: <U extends Type[]>(f: (value: T) => Tuple<U>): Tuple<U> => {\n return f(values)\n },\n\n get: <K extends number>(index: K): T[K] => {\n return values[index]\n },\n\n toArray: (): T => {\n return values\n },\n\n length: values.length,\n\n [Symbol.iterator](): Iterator<T[number]> {\n let index = 0\n return {\n next: (): IteratorResult<T[number]> => {\n if (index < values.length) {\n return {\n value: values[index++],\n done: false,\n }\n } else {\n return {\n value: undefined,\n done: true,\n }\n }\n },\n }\n },\n\n // Foldable implementation\n fold: <B>(onEmpty: () => B, onValue: (value: T[number]) => B): B => {\n return values.length === 0 ? onEmpty() : onValue(values[0]!)\n },\n\n foldLeft:\n <B>(z: B) =>\n (op: (b: B, a: T[number]) => B) => {\n return values.reduce(op, z)\n },\n\n foldRight:\n <B>(z: B) =>\n (op: (a: T[number], b: B) => B): B => {\n return values.reduceRight<B>((acc, value) => op(value, acc), z)\n },\n\n // Pipe implementation\n pipe: <U>(f: (value: Tuple<T>) => U): U => f(tuple),\n\n // Serializable implementation\n serialize: () => {\n return {\n toJSON: () => JSON.stringify({ _tag: \"Tuple\", value: values }),\n toYAML: () => `_tag: Tuple\\nvalue: ${stringify(values)}`,\n toBinary: () => Buffer.from(JSON.stringify({ _tag: \"Tuple\", value: values })).toString(\"base64\"),\n }\n },\n\n // Valuable implementation\n toValue: () => ({ _tag: \"Tuple\", value: values }),\n\n toString: () => `Tuple(${values.map((v) => String(v)).join(\", \")})`,\n }\n\n return tuple\n}\n\nconst TupleConstructor = <T extends Type[]>(values: T): Tuple<T> => {\n return TupleObject(values)\n}\n\nconst TupleCompanion = {\n /**\n * Create a Tuple from multiple arguments\n * @example\n * const t = Tuple.of(1, \"hello\", true)\n * // TypeScript infers: Tuple<[number, string, boolean]>\n */\n of: <T extends Type[]>(...values: T): Tuple<T> => {\n return TupleObject(values)\n },\n\n /**\n * Create a Tuple of size 2 (pair)\n * @example\n * const pair = Tuple.pair(\"key\", 42)\n * // TypeScript infers: Tuple<[string, number]>\n */\n pair: <A extends Type, B extends Type>(first: A, second: B): Tuple<[A, B]> => {\n return TupleObject([first, second] as [A, B])\n },\n\n /**\n * Create a Tuple of size 3 (triple)\n * @example\n * const triple = Tuple.triple(\"x\", 10, true)\n * // TypeScript infers: Tuple<[string, number, boolean]>\n */\n triple: <A extends Type, B extends Type, C extends Type>(first: A, second: B, third: C): Tuple<[A, B, C]> => {\n return TupleObject([first, second, third] as [A, B, C])\n },\n\n /**\n * Create an empty Tuple\n * @example\n * const empty = Tuple.empty()\n * // TypeScript infers: Tuple<[]>\n */\n empty: (): Tuple<[]> => {\n return TupleObject([] as [])\n },\n\n /**\n * Create a Tuple from an array (alias for constructor)\n * @example\n * const t = Tuple.from([1, 2, 3])\n */\n from: <T extends Type[]>(values: T): Tuple<T> => {\n return TupleObject(values)\n },\n}\n\n/**\n * Tuple provides a type-safe, fixed-length array with functional operations.\n *\n * @example\n * // Creating tuples\n * const t1 = Tuple([1, \"hello\", true])\n * const t2 = Tuple.of(1, \"hello\", true)\n * const pair = Tuple.pair(\"key\", 42)\n *\n * @example\n * // Type-safe access\n * const triple = Tuple.triple(\"x\", 10, true)\n * const first = triple.get(0) // string\n * const second = triple.get(1) // number\n * const third = triple.get(2) // boolean\n *\n * @example\n * // Functional operations\n * const doubled = Tuple([1, 2, 3])\n * .map(arr => arr.map(x => x * 2))\n * .toArray() // [2, 4, 6]\n */\nexport const Tuple = Companion(TupleConstructor, TupleCompanion)\n"]}