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.
- package/README.md +56 -8
- package/build/option.cjs +2 -4
- package/build/option.cjs.map +1 -1
- package/build/option.d.ts +1 -2
- package/build/option.js +2 -4
- package/build/option.js.map +1 -1
- package/build/result.cjs +26 -16
- package/build/result.cjs.map +1 -1
- package/build/result.d.ts +1 -2
- package/build/result.js +26 -16
- package/build/result.js.map +1 -1
- package/build/types.cjs +2 -2
- package/build/types.cjs.map +1 -1
- package/build/types.d.ts +1 -0
- package/build/types.js +2 -2
- package/build/types.js.map +1 -1
- package/package.json +29 -10
- package/src/__tests__/result.types.ts +1 -1
- package/src/option.ts +2 -6
- package/src/result.ts +32 -21
- package/src/types.ts +4 -2
package/build/types.js.map
CHANGED
|
@@ -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
|
|
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
|
-
"
|
|
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.
|
|
72
|
-
"eslint": "^10.0
|
|
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.
|
|
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": "^
|
|
80
|
-
"typescript-eslint": "^8.
|
|
81
|
-
"vitest": "^4.
|
|
96
|
+
"typescript": "^6.0.2",
|
|
97
|
+
"typescript-eslint": "^8.58.0",
|
|
98
|
+
"vitest": "^4.1.2"
|
|
82
99
|
},
|
|
83
100
|
"scripts": {
|
|
84
|
-
"check": "tsc
|
|
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 |
|
|
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
|
|
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 ??
|
|
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
|
|
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
|
|
550
|
+
const len = results.length;
|
|
551
|
+
const values = new Array<T>(len);
|
|
555
552
|
|
|
556
|
-
for (
|
|
553
|
+
for (let i = 0; i < len; i++) {
|
|
554
|
+
const result = results[i];
|
|
557
555
|
if (isErr(result)) return result;
|
|
558
|
-
values
|
|
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
|
|
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
|
-
|
|
723
|
-
(
|
|
724
|
-
|
|
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
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
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>)
|
|
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>)
|
|
240
|
+
return !(typeof value === 'object' || typeof value === 'function') || value === null || typeof (value as PromiseLike<T>).then !== 'function';
|
|
239
241
|
}
|