nalloc 0.0.3 → 0.1.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 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/** Values that represent None (absence of a value). */\nexport type NoneValueType = null | undefined | void;\n\n/** Widens literal types to their base types for better type inference. */\nexport type Widen<T> = T extends string\n ? string\n : T extends number\n ? number\n : T extends boolean\n ? boolean\n : T extends bigint\n ? bigint\n : T extends symbol\n ? symbol\n : T;\n\n/** Widens never to unknown, otherwise preserves the type. */\nexport type WidenNever<T> = [T] extends [never] ? unknown : T;\n\n/** Excludes None values from a type, leaving only valid Some values. */\nexport type ValueType<T> = Exclude<T, NoneValueType>;\n\nexport declare const SOME_BRAND: unique symbol;\n\n/** Represents a value that is present. The value itself is the Some - no wrapper object. */\nexport type Some<T> = ValueType<T> & { readonly [SOME_BRAND]: true };\n\n/** Represents the absence of a value (null or undefined). */\nexport type None = NoneValueType & { readonly [SOME_BRAND]: false };\n\n/** Constant representing None. Use this instead of null/undefined for clarity. */\nexport const NONE = undefined as None;\n\n/** Shared frozen empty array to avoid allocations. */\nexport const EMPTY: readonly unknown[] = Object.freeze([]);\n\n/** A value that may or may not be present. Some(T) is the value itself; None is null/undefined. */\nexport type Option<T> = Some<ValueType<T>> | None;\n\n/** Extracts the value type from an Option type. */\nexport type OptionValue<TOption> = TOption extends Option<infer TValue> ? TValue : never;\n\n/** Type predicate: true if T is an Option type. */\nexport type IsOption<T> = T extends Option<any> ? true : false;\n\n/** Infers the Some type from a value, preserving the inner type. */\nexport type InferSome<T> = T extends Some<infer TValue> ? Some<ValueType<TValue>> : never;\n\n/**\n * Checks if an Option contains a value (is Some).\n * @param opt - The Option to check\n * @returns true if the Option is Some, false if None\n * @example\n * isSome(42) // true\n * isSome(null) // false\n * isSome(undefined) // false\n */\nexport function isSome<T>(opt: Some<T>): true;\nexport function isSome(opt: None): false;\nexport function isSome<T>(opt: unknown): opt is Some<T>;\nexport function isSome(opt: unknown): boolean {\n return opt !== null && opt !== undefined;\n}\n\n/**\n * Checks if an Option is None (absent).\n * @param opt - The Option to check\n * @returns true if the Option is None, false if Some\n * @example\n * isNone(null) // true\n * isNone(undefined) // true\n * isNone(42) // false\n */\nexport function isNone<T>(opt: Some<T>): false;\nexport function isNone(opt: None): true;\nexport function isNone(opt: unknown): opt is None;\nexport function isNone(opt: unknown): boolean {\n return opt === null || opt === undefined;\n}\n\n/**\n * Creates an Option from a nullable value. Returns None for null/undefined, Some otherwise.\n * @param value - The value to wrap\n * @returns Some(value) if value is non-null, None otherwise\n * @example\n * optionOf(42) // Some(42)\n * optionOf(null) // None\n * optionOf(undefined) // None\n */\nexport function optionOf(value: null): None;\nexport function optionOf(value: undefined): None;\nexport function optionOf<T>(value: T): T extends NoneValueType ? None : Some<T>;\nexport function optionOf<T>(value: T): Option<T> {\n return isNone(value as Option<T>) ? NONE : (value as Some<T>);\n}\n\nexport function someUnchecked<T>(value: T): Some<ValueType<T>> {\n return value as Some<ValueType<T>>;\n}\n\n/**\n * Creates a Some value with runtime validation.\n * @param value - The value to wrap\n * @returns The value typed as Some\n * @throws TypeError if value is null or undefined\n * @example\n * some(42) // Some(42)\n */\nexport function some<T>(value: ValueType<T>): Some<ValueType<T>> {\n if (value === null || value === undefined) {\n throw new TypeError('some() requires a non-nullable value');\n }\n return someUnchecked(value);\n}\n\n/** Constant representing None. Alias for NONE. */\nexport const none: None = NONE;\n\ndeclare const OK_BRAND: unique symbol;\n\n/** Represents a successful Result value. The value itself is the Ok - no wrapper object. */\nexport type Ok<T> = T & { readonly [OK_BRAND]: true };\n\nconst ERR_BRAND = Symbol.for('nalloc.ResultError');\n\ninterface ResultErrorShape<E> {\n readonly error: E;\n readonly [ERR_BRAND]: true;\n}\n\nfunction ResultErrorCtor<E>(this: ResultErrorShape<E>, error: E): void {\n (this as { error: E }).error = error;\n}\n(ResultErrorCtor.prototype as { [ERR_BRAND]: true })[ERR_BRAND] = true;\n\n/** The error wrapper type used internally. */\nexport type ResultError<E> = ResultErrorShape<E>;\n\n/** Represents a failed Result containing an error. */\nexport type Err<E> = ResultError<E>;\n\n/** A value that is either successful (Ok) or failed (Err). Ok is the value itself; Err wraps the error. */\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n/** Extracts the success value type from a Result type. */\nexport type ResultValue<TResult> = TResult extends Result<infer TValue, any> ? TValue : never;\n\n/** Extracts the error type from a Result type. */\nexport type ResultErrorType<TResult> = TResult extends Result<any, infer TError> ? TError : never;\n\n/** Type predicate: true if T is a Result type. */\nexport type IsResult<T> = T extends Result<any, any> ? true : false;\n\n/** Infers the Err type from a value, preserving the error type. */\nexport type InferErr<T> = T extends Err<infer TError> ? Err<TError> : never;\n\n/**\n * Checks if a Result is Ok (successful).\n * @param result - The Result to check\n * @returns true if the Result is Ok, false if Err\n * @example\n * isOk(42) // true (Ok value)\n * isOk(err('fail')) // false\n */\nexport function isOk<T>(result: Ok<T>): true;\nexport function isOk<E>(result: Err<E>): false;\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T>;\nexport function isOk(result: unknown): boolean;\nexport function isOk(result: unknown): boolean {\n return typeof result !== 'object' || result === null || !(result as Record<symbol, boolean>)[ERR_BRAND];\n}\n\n/**\n * Checks if a Result is Err (failed).\n * @param result - The Result to check\n * @returns true if the Result is Err, false if Ok\n * @example\n * isErr(err('fail')) // true\n * isErr(42) // false (Ok value)\n */\nexport function isErr<E>(result: Err<E>): true;\nexport function isErr(result: Ok<unknown>): false;\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E>;\nexport function isErr(result: unknown): result is Err<unknown>;\nexport function isErr(result: unknown): boolean {\n return typeof result === 'object' && result !== null && (result as Record<symbol, boolean>)[ERR_BRAND] === true;\n}\n\nexport function okUnchecked<T>(value: T): Ok<T> {\n return value as Ok<T>;\n}\n\n/**\n * Creates an Ok value with runtime validation.\n * @param value - The success value\n * @returns The value typed as Ok\n * @throws TypeError if value is an Err\n * @example\n * ok(42) // Ok(42)\n */\nexport function ok<T>(value: T): Ok<T> {\n if (isErr(value)) {\n throw new TypeError('ok() cannot wrap an Err value');\n }\n return okUnchecked(value);\n}\n\n/**\n * Creates an Err value wrapping an error.\n * @param error - The error value\n * @returns An Err containing the error\n * @example\n * err('something went wrong') // Err('something went wrong')\n * err(new Error('failed')) // Err(Error)\n */\nexport function err<E>(error: E): Err<E> {\n return new (ResultErrorCtor as unknown as new (error: E) => Err<E>)(error);\n}\n\n/** A value that may or may not be a Promise. */\nexport type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;\n\n/**\n * Checks if a value is a thenable (has a .then method).\n * @param value - The value to check\n * @returns true if value is a PromiseLike\n */\nexport function isThenable<T>(value: MaybePromise<T>): value is PromiseLike<T> {\n return typeof (value as PromiseLike<T>)?.then === 'function';\n}\n\n/**\n * Checks if a value is synchronous (not a thenable).\n * @param value - The value to check\n * @returns true if value is not a PromiseLike\n */\nexport function isSync<T>(value: MaybePromise<T>): value is T {\n return typeof (value as PromiseLike<T>)?.then !== 'function';\n}\n"],"names":["NONE","undefined","EMPTY","Object","freeze","isSome","opt","isNone","optionOf","value","someUnchecked","some","TypeError","none","ERR_BRAND","Symbol","for","ResultErrorCtor","error","prototype","isOk","result","isErr","okUnchecked","ok","err","isThenable","then","isSync"],"mappings":"AA+BA,OAAO,MAAMA,OAAOC,UAAkB;AAGtC,OAAO,MAAMC,QAA4BC,OAAOC,MAAM,CAAC,EAAE,EAAE;AA0B3D,OAAO,SAASC,OAAOC,GAAY;IACjC,OAAOA,QAAQ,QAAQA,QAAQL;AACjC;AAcA,OAAO,SAASM,OAAOD,GAAY;IACjC,OAAOA,QAAQ,QAAQA,QAAQL;AACjC;AAcA,OAAO,SAASO,SAAYC,KAAQ;IAClC,OAAOF,OAAOE,SAAsBT,OAAQS;AAC9C;AAEA,OAAO,SAASC,cAAiBD,KAAQ;IACvC,OAAOA;AACT;AAUA,OAAO,SAASE,KAAQF,KAAmB;IACzC,IAAIA,UAAU,QAAQA,UAAUR,WAAW;QACzC,MAAM,IAAIW,UAAU;IACtB;IACA,OAAOF,cAAcD;AACvB;AAGA,OAAO,MAAMI,OAAab,KAAK;AAO/B,MAAMc,YAAYC,OAAOC,GAAG,CAAC;AAO7B,SAASC,gBAA8CC,KAAQ;IAC7D,AAAC,IAAI,CAAkBA,KAAK,GAAGA;AACjC;AACCD,gBAAgBE,SAAS,AAA0B,CAACL,UAAU,GAAG;AAmClE,OAAO,SAASM,KAAKC,MAAe;IAClC,OAAO,OAAOA,WAAW,YAAYA,WAAW,QAAQ,CAAC,AAACA,MAAkC,CAACP,UAAU;AACzG;AAcA,OAAO,SAASQ,MAAMD,MAAe;IACnC,OAAO,OAAOA,WAAW,YAAYA,WAAW,QAAQ,AAACA,MAAkC,CAACP,UAAU,KAAK;AAC7G;AAEA,OAAO,SAASS,YAAed,KAAQ;IACrC,OAAOA;AACT;AAUA,OAAO,SAASe,GAAMf,KAAQ;IAC5B,IAAIa,MAAMb,QAAQ;QAChB,MAAM,IAAIG,UAAU;IACtB;IACA,OAAOW,YAAYd;AACrB;AAUA,OAAO,SAASgB,IAAOP,KAAQ;IAC7B,OAAO,IAAKD,gBAAwDC;AACtE;AAUA,OAAO,SAASQ,WAAcjB,KAAsB;IAClD,OAAO,OAAQA,OAA0BkB,SAAS;AACpD;AAOA,OAAO,SAASC,OAAUnB,KAAsB;IAC9C,OAAO,OAAQA,OAA0BkB,SAAS;AACpD"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/** Values that represent None (absence of a value). */\nexport type NoneValueType = null | undefined | void;\n\n/** Widens literal types to their base types for better type inference. */\nexport type Widen<T> = T extends string\n ? string\n : T extends number\n ? number\n : T extends boolean\n ? boolean\n : T extends bigint\n ? bigint\n : T extends symbol\n ? symbol\n : T;\n\n/** Widens never to unknown, otherwise preserves the type. */\nexport type WidenNever<T> = [T] extends [never] ? unknown : T;\n\n/** Excludes None values from a type, leaving only valid Some values. */\nexport type ValueType<T> = Exclude<T, NoneValueType>;\n\nexport declare const SOME_BRAND: unique symbol;\n\n/** Represents a value that is present. The value itself is the Some - no wrapper object. */\nexport type Some<T> = ValueType<T> & { readonly [SOME_BRAND]: true };\n\n/** Represents the absence of a value (null or undefined). */\nexport type None = NoneValueType & { readonly [SOME_BRAND]: false };\n\nexport type UnOption<V, T extends Option<V>> = T extends Some<V> ? V : None;\n\n/** Constant representing None. Use this instead of null/undefined for clarity. */\nexport const NONE = undefined as None;\n\n/** Shared frozen empty array to avoid allocations. */\nexport const EMPTY: readonly unknown[] = Object.freeze([]);\n\n/** A value that may or may not be present. Some(T) is the value itself; None is null/undefined. */\nexport type Option<T> = Some<ValueType<T>> | None;\n\n/** Extracts the value type from an Option type. */\nexport type OptionValue<TOption> = TOption extends Option<infer TValue> ? TValue : never;\n\n/** Type predicate: true if T is an Option type. */\nexport type IsOption<T> = T extends Option<any> ? true : false;\n\n/** Infers the Some type from a value, preserving the inner type. */\nexport type InferSome<T> = T extends Some<infer TValue> ? Some<ValueType<TValue>> : never;\n\n/**\n * Checks if an Option contains a value (is Some).\n * @param opt - The Option to check\n * @returns true if the Option is Some, false if None\n * @example\n * isSome(42) // true\n * isSome(null) // false\n * isSome(undefined) // false\n */\nexport function isSome<T>(opt: Some<T>): true;\nexport function isSome(opt: None): false;\nexport function isSome<T>(opt: unknown): opt is Some<T>;\nexport function isSome(opt: unknown): boolean {\n return opt !== null && opt !== undefined;\n}\n\n/**\n * Checks if an Option is None (absent).\n * @param opt - The Option to check\n * @returns true if the Option is None, false if Some\n * @example\n * isNone(null) // true\n * isNone(undefined) // true\n * isNone(42) // false\n */\nexport function isNone<T>(opt: Some<T>): false;\nexport function isNone(opt: None): true;\nexport function isNone(opt: unknown): opt is None;\nexport function isNone(opt: unknown): boolean {\n return opt === null || opt === undefined;\n}\n\n/**\n * Creates an Option from a nullable value. Returns None for null/undefined, Some otherwise.\n * @param value - The value to wrap\n * @returns Some(value) if value is non-null, None otherwise\n * @example\n * optionOf(42) // Some(42)\n * optionOf(null) // None\n * optionOf(undefined) // None\n */\nexport function optionOf(value: null): None;\nexport function optionOf(value: undefined): None;\nexport function optionOf<T>(value: T): T extends NoneValueType ? None : Some<T>;\nexport function optionOf<T>(value: T): Option<T> {\n return isNone(value as Option<T>) ? NONE : (value as Some<T>);\n}\n\nexport function someUnchecked<T>(value: T): Some<ValueType<T>> {\n return value as Some<ValueType<T>>;\n}\n\n/**\n * Creates a Some value with runtime validation.\n * @param value - The value to wrap\n * @returns The value typed as Some\n * @throws TypeError if value is null or undefined\n * @example\n * some(42) // Some(42)\n */\nexport function some<T>(value: ValueType<T>): Some<ValueType<T>> {\n if (value === null || value === undefined) {\n throw new TypeError('some() requires a non-nullable value');\n }\n return someUnchecked(value);\n}\n\n/** Constant representing None. Alias for NONE. */\nexport const none: None = NONE;\n\ndeclare const OK_BRAND: unique symbol;\n\n/** Represents a successful Result value. The value itself is the Ok - no wrapper object. */\nexport type Ok<T> = T & { readonly [OK_BRAND]: true };\n\nconst ERR_BRAND = Symbol.for('nalloc.ResultError');\n\ninterface ResultErrorShape<E> {\n readonly error: E;\n readonly [ERR_BRAND]: true;\n}\n\nfunction ResultErrorCtor<E>(this: ResultErrorShape<E>, error: E): void {\n (this as { error: E }).error = error;\n}\n(ResultErrorCtor.prototype as { [ERR_BRAND]: true })[ERR_BRAND] = true;\n\n/** The error wrapper type used internally. */\nexport type ResultError<E> = ResultErrorShape<E>;\n\n/** Represents a failed Result containing an error. */\nexport type Err<E> = ResultError<E>;\n\n/** A value that is either successful (Ok) or failed (Err). Ok is the value itself; Err wraps the error. */\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n/** Extracts the success value type from a Result type. */\nexport type ResultValue<TResult> = TResult extends Result<infer TValue, any> ? TValue : never;\n\n/** Extracts the error type from a Result type. */\nexport type ResultErrorType<TResult> = TResult extends Result<any, infer TError> ? TError : never;\n\n/** Type predicate: true if T is a Result type. */\nexport type IsResult<T> = T extends Result<any, any> ? true : false;\n\n/** Infers the Err type from a value, preserving the error type. */\nexport type InferErr<T> = T extends Err<infer TError> ? Err<TError> : never;\n\n/**\n * Checks if a Result is Ok (successful).\n * @param result - The Result to check\n * @returns true if the Result is Ok, false if Err\n * @example\n * isOk(42) // true (Ok value)\n * isOk(err('fail')) // false\n */\nexport function isOk<T>(result: Ok<T>): true;\nexport function isOk<E>(result: Err<E>): false;\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T>;\nexport function isOk(result: unknown): boolean;\nexport function isOk(result: unknown): boolean {\n return typeof result !== 'object' || result === null || !(result as Record<symbol, boolean>)[ERR_BRAND];\n}\n\n/**\n * Checks if a Result is Err (failed).\n * @param result - The Result to check\n * @returns true if the Result is Err, false if Ok\n * @example\n * isErr(err('fail')) // true\n * isErr(42) // false (Ok value)\n */\nexport function isErr<E>(result: Err<E>): true;\nexport function isErr(result: Ok<unknown>): false;\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E>;\nexport function isErr(result: unknown): result is Err<unknown>;\nexport function isErr(result: unknown): boolean {\n return typeof result === 'object' && result !== null && (result as Record<symbol, boolean>)[ERR_BRAND] === true;\n}\n\nexport function okUnchecked<T>(value: T): Ok<T> {\n return value as Ok<T>;\n}\n\n/**\n * Creates an Ok value with runtime validation.\n * @param value - The success value\n * @returns The value typed as Ok\n * @throws TypeError if value is an Err\n * @example\n * ok(42) // Ok(42)\n */\nexport function ok<T>(value: T): Ok<T> {\n if (isErr(value)) {\n throw new TypeError('ok() cannot wrap an Err value');\n }\n return okUnchecked(value);\n}\n\n/**\n * Creates an Err value wrapping an error.\n * @param error - The error value\n * @returns An Err containing the error\n * @example\n * err('something went wrong') // Err('something went wrong')\n * err(new Error('failed')) // Err(Error)\n */\nexport function err<E>(error: E): Err<E> {\n return new (ResultErrorCtor as unknown as new (error: E) => Err<E>)(error);\n}\n\n/** A value that may or may not be a Promise. */\nexport type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;\n\n/**\n * Checks if a value is a thenable (has a .then method).\n * @param value - The value to check\n * @returns true if value is a PromiseLike\n */\nexport function isThenable<T>(value: MaybePromise<T>): value is PromiseLike<T> {\n return (typeof value === 'object' || typeof value === 'function') && value !== null && typeof (value as PromiseLike<T>).then === 'function';\n}\n\n/**\n * Checks if a value is synchronous (not a thenable).\n * @param value - The value to check\n * @returns true if value is not a PromiseLike\n */\nexport function isSync<T>(value: MaybePromise<T>): value is T {\n return !(typeof value === 'object' || typeof value === 'function') || value === null || typeof (value as PromiseLike<T>).then !== 'function';\n}\n"],"names":["NONE","undefined","EMPTY","Object","freeze","isSome","opt","isNone","optionOf","value","someUnchecked","some","TypeError","none","ERR_BRAND","Symbol","for","ResultErrorCtor","error","prototype","isOk","result","isErr","okUnchecked","ok","err","isThenable","then","isSync"],"mappings":"AAiCA,OAAO,MAAMA,OAAOC,UAAkB;AAGtC,OAAO,MAAMC,QAA4BC,OAAOC,MAAM,CAAC,EAAE,EAAE;AA0B3D,OAAO,SAASC,OAAOC,GAAY;IACjC,OAAOA,QAAQ,QAAQA,QAAQL;AACjC;AAcA,OAAO,SAASM,OAAOD,GAAY;IACjC,OAAOA,QAAQ,QAAQA,QAAQL;AACjC;AAcA,OAAO,SAASO,SAAYC,KAAQ;IAClC,OAAOF,OAAOE,SAAsBT,OAAQS;AAC9C;AAEA,OAAO,SAASC,cAAiBD,KAAQ;IACvC,OAAOA;AACT;AAUA,OAAO,SAASE,KAAQF,KAAmB;IACzC,IAAIA,UAAU,QAAQA,UAAUR,WAAW;QACzC,MAAM,IAAIW,UAAU;IACtB;IACA,OAAOF,cAAcD;AACvB;AAGA,OAAO,MAAMI,OAAab,KAAK;AAO/B,MAAMc,YAAYC,OAAOC,GAAG,CAAC;AAO7B,SAASC,gBAA8CC,KAAQ;IAC7D,AAAC,IAAI,CAAkBA,KAAK,GAAGA;AACjC;AACCD,gBAAgBE,SAAS,AAA0B,CAACL,UAAU,GAAG;AAmClE,OAAO,SAASM,KAAKC,MAAe;IAClC,OAAO,OAAOA,WAAW,YAAYA,WAAW,QAAQ,CAAC,AAACA,MAAkC,CAACP,UAAU;AACzG;AAcA,OAAO,SAASQ,MAAMD,MAAe;IACnC,OAAO,OAAOA,WAAW,YAAYA,WAAW,QAAQ,AAACA,MAAkC,CAACP,UAAU,KAAK;AAC7G;AAEA,OAAO,SAASS,YAAed,KAAQ;IACrC,OAAOA;AACT;AAUA,OAAO,SAASe,GAAMf,KAAQ;IAC5B,IAAIa,MAAMb,QAAQ;QAChB,MAAM,IAAIG,UAAU;IACtB;IACA,OAAOW,YAAYd;AACrB;AAUA,OAAO,SAASgB,IAAOP,KAAQ;IAC7B,OAAO,IAAKD,gBAAwDC;AACtE;AAUA,OAAO,SAASQ,WAAcjB,KAAsB;IAClD,OAAO,AAAC,CAAA,OAAOA,UAAU,YAAY,OAAOA,UAAU,UAAS,KAAMA,UAAU,QAAQ,OAAO,AAACA,MAAyBkB,IAAI,KAAK;AACnI;AAOA,OAAO,SAASC,OAAUnB,KAAsB;IAC9C,OAAO,CAAE,CAAA,OAAOA,UAAU,YAAY,OAAOA,UAAU,UAAS,KAAMA,UAAU,QAAQ,OAAO,AAACA,MAAyBkB,IAAI,KAAK;AACpI"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nalloc",
3
3
  "description": "Rust-like Option and Result for TypeScript with near-zero allocations for extreme performance",
4
- "version": "0.0.3",
4
+ "version": "0.1.0",
5
5
  "type": "module",
6
6
  "types": "build/index.d.ts",
7
7
  "main": "build/index.cjs",
@@ -50,15 +50,32 @@
50
50
  "result",
51
51
  "maybe",
52
52
  "either",
53
+ "ok",
54
+ "err",
55
+ "some",
56
+ "none",
57
+ "unwrap",
53
58
  "rust",
54
59
  "typescript",
55
60
  "type-safe",
56
61
  "monad",
57
62
  "functional",
63
+ "fp",
64
+ "adt",
65
+ "algebraic-data-types",
66
+ "discriminated-union",
58
67
  "error-handling",
68
+ "try-catch",
69
+ "safe",
70
+ "nullable",
71
+ "null-safety",
59
72
  "pattern-matching",
60
73
  "zero-allocation",
61
- "performance"
74
+ "no-allocation",
75
+ "gc-friendly",
76
+ "performance",
77
+ "neverthrow-alternative",
78
+ "fp-ts-alternative"
62
79
  ],
63
80
  "author": "Ivan Zakharchanka",
64
81
  "license": "MIT",
@@ -68,23 +85,25 @@
68
85
  "homepage": "https://github.com/3axap4eHko/nalloc#readme",
69
86
  "devDependencies": {
70
87
  "@eslint/js": "^10.0.1",
71
- "@vitest/coverage-v8": "^4.0.18",
72
- "eslint": "^10.0.2",
88
+ "@vitest/coverage-v8": "^4.1.2",
89
+ "eslint": "^10.1.0",
73
90
  "eslint-plugin-prettier": "^5.5.5",
74
91
  "inop": "^0.9.0",
75
- "overtake": "^1.4.0",
92
+ "overtake": "^2.1.1",
76
93
  "prettier": "^3.8.1",
77
94
  "tsafe": "^1.8.12",
78
95
  "tslib": "^2.8.1",
79
- "typescript": "^5.9.3",
80
- "typescript-eslint": "^8.56.1",
81
- "vitest": "^4.0.18"
96
+ "typescript": "^6.0.2",
97
+ "typescript-eslint": "^8.58.0",
98
+ "vitest": "^4.1.2"
82
99
  },
83
100
  "scripts": {
84
- "check": "tsc src/__tests__/option.types.ts src/__tests__/result.types.ts --noEmit --lib esnext,dom --target esnext --module nodenext --moduleResolution nodenext",
101
+ "check": "tsc --noEmit -p tsconfig.check.json",
85
102
  "build": "rm -rf build && inop src build -i __tests__ -i *.tmp.ts && tsc --declaration --emitDeclarationOnly",
86
103
  "lint": "eslint .",
87
104
  "test": "vitest run",
88
- "bench": "overtake benchmarks/*"
105
+ "bench": "overtake benchmarks/* --pin-cores -w 2 --progress",
106
+ "bench:save": "pnpm bench --save-baseline .bench-baseline.json",
107
+ "bench:test": "pnpm bench --compare-baseline .bench-baseline.json"
89
108
  }
90
109
  }
@@ -207,7 +207,7 @@ assert<Equals<typeof tryCatchTyped, Result<number, string>>>;
207
207
 
208
208
 
209
209
  const unwrapFallback = unwrapOrReturn(ok(1) as Result<number, string>, () => 'fallback');
210
- assert<Equals<typeof unwrapFallback, number | string>>;
210
+ assert<Equals<typeof unwrapFallback, number | 'fallback'>>;
211
211
 
212
212
  declare const maybeResult: Result<number, string>;
213
213
  assertOk(maybeResult);
package/src/option.ts CHANGED
@@ -158,11 +158,7 @@ export function flatMap<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Opti
158
158
  * @param fn - Function returning an Option
159
159
  * @returns The result of fn(value) if Some, None otherwise
160
160
  */
161
- export function andThen<T, U>(opt: None, fn: (value: T) => Option<U>): None;
162
- export function andThen<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U>;
163
- export function andThen<T, U>(opt: Option<T>, fn: (value: T) => Option<U>): Option<U> {
164
- return isNone(opt) ? NONE : fn(opt);
165
- }
161
+ export const andThen: typeof flatMap = flatMap;
166
162
 
167
163
  /**
168
164
  * Executes a side effect if Some, then returns the original Option.
@@ -412,7 +408,7 @@ export function flatten<T>(opt: Option<Option<T>>): Option<T> {
412
408
  * contains(none, 42) // false
413
409
  */
414
410
  export function contains<T>(opt: Option<T>, value: T): boolean {
415
- return isSome(opt) && opt === value;
411
+ return isSome(opt) && (opt === value || (opt !== opt && value !== value));
416
412
  }
417
413
 
418
414
  /**
package/src/result.ts CHANGED
@@ -118,7 +118,7 @@ export function assertOk<T, E>(result: Result<T, E>, message?: string): asserts
118
118
  */
119
119
  export function assertErr<T, E>(result: Result<T, E>, message?: string): asserts result is Err<E> {
120
120
  if (isOk(result)) {
121
- throw new Error(message ?? 'Expected Err result.');
121
+ throw new Error(message ?? `Expected Err result. Received value: ${String(result)}`);
122
122
  }
123
123
  }
124
124
 
@@ -188,11 +188,7 @@ export function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<
188
188
  * @param fn - Function returning a Result
189
189
  * @returns The result of fn(value) if Ok, Err unchanged
190
190
  */
191
- export function andThen<T, U, E>(result: Err<E>, fn: (value: T) => Result<U, E>): Err<E>;
192
- export function andThen<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
193
- export function andThen<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E> {
194
- return isErr(result) ? result : fn(result);
195
- }
191
+ export const andThen: typeof flatMap = flatMap;
196
192
 
197
193
  /**
198
194
  * Executes a side effect if Ok, then returns the original Result.
@@ -551,11 +547,13 @@ export function filterErr<T, E>(results: Iterable<Result<T, E>>): E[] {
551
547
  * collect([ok(1), err('e')]) // Err('e')
552
548
  */
553
549
  export function collect<T, E>(results: Result<T, E>[]): Result<T[], E> {
554
- const values: T[] = [];
550
+ const len = results.length;
551
+ const values = new Array<T>(len);
555
552
 
556
- for (const result of results) {
553
+ for (let i = 0; i < len; i++) {
554
+ const result = results[i];
557
555
  if (isErr(result)) return result;
558
- values.push(result);
556
+ values[i] = result;
559
557
  }
560
558
 
561
559
  return values as Ok<T[]>;
@@ -715,25 +713,38 @@ export async function partitionMaybePromiseAsync<T, E>(
715
713
  startIndex: number = 0,
716
714
  ): Promise<[Widen<T>[], WidenNever<E>[]]> {
717
715
  const suffixLength = values.length - startIndex;
718
- const pending = new Array<Promise<Result<T, E>>>(suffixLength);
716
+ const pendingPromises: Promise<Result<T, E>>[] = [];
719
717
 
720
718
  for (let i = 0; i < suffixLength; i++) {
721
719
  const value = values[startIndex + i];
722
- pending[i] = Promise.resolve(value).then(
723
- (result) => result as Result<T, E>,
724
- (error) => ERR(error as E),
725
- );
720
+ if (isThenable(value)) {
721
+ pendingPromises.push(
722
+ Promise.resolve(value).then(
723
+ (result) => result as Result<T, E>,
724
+ (error) => ERR(error as E),
725
+ ),
726
+ );
727
+ } else {
728
+ if (isOk(value)) {
729
+ oks.push(value as Widen<T>);
730
+ } else {
731
+ errs.push((value as Err<WidenNever<E>>).error);
732
+ }
733
+ }
726
734
  }
727
735
 
728
- const resolved = await Promise.all(pending);
729
- for (let i = 0; i < resolved.length; i++) {
730
- const result = resolved[i];
731
- if (isOk(result)) {
732
- oks.push(result as Widen<T>);
733
- } else {
734
- errs.push((result as Err<WidenNever<E>>).error);
736
+ if (pendingPromises.length > 0) {
737
+ const resolved = await Promise.all(pendingPromises);
738
+ for (let i = 0; i < resolved.length; i++) {
739
+ const result = resolved[i];
740
+ if (isOk(result)) {
741
+ oks.push(result as Widen<T>);
742
+ } else {
743
+ errs.push((result as Err<WidenNever<E>>).error);
744
+ }
735
745
  }
736
746
  }
747
+
737
748
  return [oks, errs] as [Widen<T>[], WidenNever<E>[]];
738
749
  }
739
750
 
package/src/types.ts CHANGED
@@ -28,6 +28,8 @@ export type Some<T> = ValueType<T> & { readonly [SOME_BRAND]: true };
28
28
  /** Represents the absence of a value (null or undefined). */
29
29
  export type None = NoneValueType & { readonly [SOME_BRAND]: false };
30
30
 
31
+ export type UnOption<V, T extends Option<V>> = T extends Some<V> ? V : None;
32
+
31
33
  /** Constant representing None. Use this instead of null/undefined for clarity. */
32
34
  export const NONE = undefined as None;
33
35
 
@@ -226,7 +228,7 @@ export type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;
226
228
  * @returns true if value is a PromiseLike
227
229
  */
228
230
  export function isThenable<T>(value: MaybePromise<T>): value is PromiseLike<T> {
229
- return typeof (value as PromiseLike<T>)?.then === 'function';
231
+ return (typeof value === 'object' || typeof value === 'function') && value !== null && typeof (value as PromiseLike<T>).then === 'function';
230
232
  }
231
233
 
232
234
  /**
@@ -235,5 +237,5 @@ export function isThenable<T>(value: MaybePromise<T>): value is PromiseLike<T> {
235
237
  * @returns true if value is not a PromiseLike
236
238
  */
237
239
  export function isSync<T>(value: MaybePromise<T>): value is T {
238
- return typeof (value as PromiseLike<T>)?.then !== 'function';
240
+ return !(typeof value === 'object' || typeof value === 'function') || value === null || typeof (value as PromiseLike<T>).then !== 'function';
239
241
  }