{"version":3,"sources":["../src/option.ts","../src/unwrap-option.ts","../src/option-codec.ts","../src/unwrap-option-recursively.ts"],"names":["transformEncoder","getUnitEncoder","getBooleanEncoder","getU8Encoder","assertIsFixedSize","fixEncoderSize","getConstantEncoder","getUnionEncoder","getTupleEncoder","transformDecoder","getUnitDecoder","getBooleanDecoder","getU8Decoder","fixDecoderSize","getConstantDecoder","getUnionDecoder","getTupleDecoder","containsBytes","combineCodec"],"mappings":"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","file":"index.node.cjs","sourcesContent":["/**\n * An implementation of the Rust `Option<T>` type in JavaScript.\n *\n * In Rust, optional values are represented using `Option<T>`, which can be either:\n * - `Some(T)`, indicating a present value.\n * - `None`, indicating the absence of a value.\n *\n * In JavaScript, this is typically represented as `T | null`. However, this approach fails with nested options.\n * For example, `Option<Option<T>>` in Rust would translate to `T | null | null` in JavaScript, which is equivalent to `T | null`.\n * This means there is no way to differentiate between `Some(None)` and `None`, making nested options impossible.\n *\n * This `Option` type helps solve this by mirroring Rust’s `Option<T>` type.\n *\n * ```ts\n * type Option<T> = Some<T> | None;\n * type Some<T> = { __option: 'Some'; value: T };\n * type None = { __option: 'None' };\n * ```\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Here's how you can create `Option` values.\n *\n * To improve developer experience, helper functions are available.\n * TypeScript can infer the type of `T` or it can be explicitly provided.\n *\n * ```ts\n * // Create an option with a value.\n * some('Hello World');\n * some<number | string>(123);\n *\n * // Create an empty option.\n * none();\n * none<number | string>();\n * ```\n *\n * @see {@link Some}\n * @see {@link None}\n * @see {@link some}\n * @see {@link none}\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * A flexible type that allows working with {@link Option} values or nullable values.\n *\n * It defines a looser type that can be used when encoding {@link Option | Options}.\n * This allows us to pass `null` or the nested value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Accepting both `Option<T>` and `T | null` as input.\n * ```ts\n * function double(value: OptionOrNullable<number>) {\n *   const option = isOption(value) ? value : wrapNullable(value);\n *   return isSome(option) ? option.value * 2 : 'No value';\n * }\n *\n * double(42);       // 84\n * double(some(21)); // 42\n * double(none());   // \"No value\"\n * double(null);     // \"No value\"\n * ```\n *\n * @see {@link Option}\n * @see {@link isOption}\n * @see {@link wrapNullable}\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an {@link Option} that contains a value.\n *\n * This type mirrors Rust’s `Some(T)`, indicating that a value is present.\n *\n * For more details, see {@link Option}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Creating a `Some` value.\n * ```ts\n * const value = some(42);\n * isSome(value); // true\n * isNone(value); // false\n * ```\n *\n * @see {@link Option}\n * @see {@link some}\n * @see {@link isSome}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an {@link Option} that contains no value.\n *\n * This type mirrors Rust’s `None`, indicating the absence of a value.\n *\n * For more details, see {@link Option}.\n *\n * @example\n * Creating a `None` value.\n * ```ts\n * const empty = none();\n * isNone(empty); // true\n * isSome(empty); // false\n * ```\n *\n * @see {@link Option}\n * @see {@link none}\n * @see {@link isNone}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} that contains a value.\n *\n * This function explicitly wraps a value in an {@link Option} type.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param value - The value to wrap in an {@link Option}.\n * @returns An {@link Option} containing the provided value.\n *\n * @example\n * Wrapping a value in an `Option`.\n * ```ts\n * const option = some('Hello');\n * option.value;     // \"Hello\"\n * isOption(option); // true\n * isSome(option);   // true\n * isNone(option);   // false\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} that contains no value.\n *\n * This function explicitly represents an absent value.\n *\n * @typeParam T - The type of the expected absent value.\n *\n * @returns An {@link Option} containing no value.\n *\n * @example\n * Creating an empty `Option`.\n * ```ts\n * const empty = none<number>();\n * isOption(empty); // true\n * isSome(empty);   // false\n * isNone(empty);   // true\n * ```\n *\n * @see {@link Option}\n * @see {@link None}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Checks whether the given value is an {@link Option}.\n *\n * This function determines whether an input follows the `Option<T>` structure.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param input - The value to check.\n * @returns `true` if the value is an {@link Option}, `false` otherwise.\n *\n * @example\n * Checking for `Option` values.\n * ```ts\n * isOption(some(42));        // true\n * isOption(none());          // true\n * isOption(42);              // false\n * isOption(null);            // false\n * isOption(\"anything else\"); // false\n * ```\n *\n * @see {@link Option}\n */\nexport const isOption = <T = unknown>(input: unknown): input is Option<T> =>\n    !!(\n        input &&\n        typeof input === 'object' &&\n        '__option' in input &&\n        ((input.__option === 'Some' && 'value' in input) || input.__option === 'None')\n    );\n\n/**\n * Checks whether the given {@link Option} contains a value.\n *\n * This function acts as a type guard, ensuring the value is a {@link Some}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param option - The {@link Option} to check.\n * @returns `true` if the option is a {@link Some}, `false` otherwise.\n *\n * @example\n * Checking for `Some` values.\n * ```ts\n * isSome(some(42)); // true\n * isSome(none());   // false\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Checks whether the given {@link Option} contains no value.\n *\n * This function acts as a type guard, ensuring the value is a {@link None}.\n *\n * @typeParam T - The type of the expected value.\n *\n * @param option - The {@link Option} to check.\n * @returns `true` if the option is a {@link None}, `false` otherwise.\n *\n * @example\n * Checking for `None` values.\n * ```ts\n * isNone(some(42)); // false\n * isNone(none());   // true\n * ```\n *\n * @see {@link Option}\n * @see {@link None}\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option}, returning its contained value or a fallback.\n *\n * This function extracts the value `T` from an `Option<T>` type.\n * - If the option is {@link Some}, it returns the contained value `T`.\n * - If the option is {@link None}, it returns the fallback value `U`, which defaults to `null`.\n *\n * @typeParam T - The type of the contained value.\n * @typeParam U - The type of the fallback value (defaults to `null`).\n *\n * @param option - The {@link Option} to unwrap.\n * @param fallback - A function that provides a fallback value if the option is {@link None}.\n * @returns The contained value if {@link Some}, otherwise the fallback value.\n *\n * @example\n * Unwrapping an `Option` with no fallback.\n * ```ts\n * unwrapOption(some('Hello World')); // \"Hello World\"\n * unwrapOption(none());              // null\n * ```\n *\n * @example\n * Providing a custom fallback value.\n * ```ts\n * unwrapOption(some('Hello World'), () => 'Default'); // \"Hello World\"\n * unwrapOption(none(), () => 'Default');              // \"Default\"\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n * @see {@link None}\n */\nexport function unwrapOption<T>(option: Option<T>): T | null;\nexport function unwrapOption<T, U>(option: Option<T>, fallback: () => U): T | U;\nexport function unwrapOption<T, U = null>(option: Option<T>, fallback?: () => U): T | U {\n    if (isSome(option)) return option.value;\n    return fallback ? fallback() : (null as U);\n}\n\n/**\n * Wraps a nullable value into an {@link Option}.\n *\n * - If the input value is `null`, this function returns {@link None}.\n * - Otherwise, it wraps the value in {@link Some}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param nullable - The nullable value to wrap.\n * @returns An {@link Option} wrapping the value.\n *\n * @example\n * Wrapping nullable values.\n * ```ts\n * wrapNullable('Hello World'); // Option<string> (Some)\n * wrapNullable<string>(null);  // Option<string> (None)\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n * @see {@link None}\n */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import {\n    assertIsFixedSize,\n    Codec,\n    combineCodec,\n    containsBytes,\n    Decoder,\n    Encoder,\n    fixDecoderSize,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    fixEncoderSize,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getBooleanDecoder,\n    getBooleanEncoder,\n    getConstantDecoder,\n    getConstantEncoder,\n    getTupleDecoder,\n    getTupleEncoder,\n    getUnionDecoder,\n    getUnionEncoder,\n    getUnitDecoder,\n    getUnitEncoder,\n} from '@solana/codecs-data-structures';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\n\nimport { isOption, isSome, None, none, Option, OptionOrNullable, Some, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/**\n * Defines the configuration options for {@link Option} codecs.\n *\n * The `getOptionCodec` function behaves similarly to {@link getNullableCodec}\n * but encodes `Option<T>` types instead of `T | null` types.\n *\n * This configuration controls how {@link None} values are encoded and how presence\n * is determined when decoding.\n *\n * @typeParam TPrefix - A number codec, encoder, or decoder used as the presence prefix.\n *\n * @see {@link getOptionEncoder}\n * @see {@link getOptionDecoder}\n * @see {@link getOptionCodec}\n */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * Specifies how {@link None} values are represented in the encoded data.\n     *\n     * - By default, {@link None} values are omitted from encoding.\n     * - `'zeroes'`: The bytes allocated for the value are filled with zeroes. This requires a fixed-size codec for the item.\n     * - Custom byte array: {@link None} values are replaced with a predefined byte sequence. This results in a variable-size codec.\n     *\n     * @defaultValue No explicit `noneValue` is used; {@link None} values are omitted.\n     */\n    noneValue?: ReadonlyUint8Array | 'zeroes';\n\n    /**\n     * The presence prefix used to distinguish between {@link None} and present values.\n     *\n     * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`).\n     * - Custom number codec: Allows defining a different number size for the prefix.\n     * - `null`: No prefix is used; `noneValue` (if provided) determines {@link None}.\n     *   If no `noneValue` is set, {@link None} is identified by the absence of bytes.\n     *\n     * @defaultValue `u8` prefix.\n     */\n    prefix?: TPrefix | null;\n};\n\n/**\n * Returns an encoder for optional values using the {@link Option} type.\n *\n * This encoder serializes an {@link OptionOrNullable} value using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, {@link None} values are encoded as zeroes.\n * - If `noneValue` is a byte array, {@link None} values are replaced with the provided constant.\n *\n * Unlike {@link getNullableEncoder}, this encoder accepts both {@link Option} and {@link Nullable} values.\n *\n * For more details, see {@link getOptionCodec}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n *\n * @param item - The encoder for the value that may be present.\n * @param config - Configuration options for encoding optional values.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding option values.\n *\n * @example\n * Encoding an optional string.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const encoder = getOptionEncoder(stringCodec);\n *\n * encoder.encode(some('Hi'));\n * encoder.encode('Hi');\n * // 0x01020000004869\n * //   | |       └-- utf8 string content (\"Hi\").\n * //   | └-- u32 string prefix (2 characters).\n * //   └-- 1-byte prefix (Some).\n *\n * encoder.encode(none());\n * encoder.encode(null);\n * // 0x00\n * //   └-- 1-byte prefix (None).\n * ```\n *\n * @see {@link getOptionCodec}\n */\nexport function getOptionEncoder<TFrom, TSize extends number>(\n    item: FixedSizeEncoder<TFrom, TSize>,\n    config: OptionCodecConfig<NumberEncoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeEncoder<OptionOrNullable<TFrom>, TSize>;\nexport function getOptionEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: OptionCodecConfig<FixedSizeNumberEncoder> & { noneValue: 'zeroes' },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: OptionCodecConfig<NumberEncoder> & { noneValue: 'zeroes' },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config?: OptionCodecConfig<NumberEncoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformEncoder(getUnitEncoder(), (_boolean: boolean) => undefined);\n        }\n        return getBooleanEncoder({ size: config.prefix ?? getU8Encoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixEncoderSize(getUnitEncoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitEncoder();\n        }\n        return getConstantEncoder(config.noneValue);\n    })();\n\n    return getUnionEncoder(\n        [\n            transformEncoder(getTupleEncoder([prefix, noneValue]), (_value: None | null): [boolean, void] => [\n                false,\n                undefined,\n            ]),\n            transformEncoder(getTupleEncoder([prefix, item]), (value: Some<TFrom> | TFrom): [boolean, TFrom] => [\n                true,\n                isOption(value) && isSome(value) ? value.value : value,\n            ]),\n        ],\n        variant => {\n            const option = isOption<TFrom>(variant) ? variant : wrapNullable(variant);\n            return Number(isSome(option));\n        },\n    );\n}\n\n/**\n * Returns a decoder for optional values using the {@link Option} type.\n *\n * This decoder deserializes an `Option<T>` value using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, `None` values are identified by zeroes.\n * - If `noneValue` is a byte array, `None` values match the provided constant.\n *\n * Unlike {@link getNullableDecoder}, this decoder always outputs an {@link Option} type.\n *\n * For more details, see {@link getOptionCodec}.\n *\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The decoder for the value that may be present.\n * @param config - Configuration options for decoding optional values.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding option values.\n *\n * @example\n * Decoding an optional string with a size prefix.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const decoder = getOptionDecoder(stringCodec);\n *\n * decoder.decode(new Uint8Array([0x01, 0x02, 0x00, 0x00, 0x00, 0x48, 0x69]));\n * // some('Hi')\n *\n * decoder.decode(new Uint8Array([0x00]));\n * // none()\n * ```\n *\n * @see {@link getOptionCodec}\n */\nexport function getOptionDecoder<TTo, TSize extends number>(\n    item: FixedSizeDecoder<TTo, TSize>,\n    config: OptionCodecConfig<NumberDecoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeDecoder<Option<TTo>, TSize>;\nexport function getOptionDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: OptionCodecConfig<FixedSizeNumberDecoder> & { noneValue: 'zeroes' },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: OptionCodecConfig<NumberDecoder> & { noneValue: 'zeroes' },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: Decoder<TTo>,\n    config?: OptionCodecConfig<NumberDecoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: Decoder<TTo>,\n    config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformDecoder(getUnitDecoder(), () => false);\n        }\n        return getBooleanDecoder({ size: config.prefix ?? getU8Decoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixDecoderSize(getUnitDecoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitDecoder();\n        }\n        return getConstantDecoder(config.noneValue);\n    })();\n\n    return getUnionDecoder(\n        [\n            transformDecoder(getTupleDecoder([prefix, noneValue]), () => none<TTo>()),\n            transformDecoder(getTupleDecoder([prefix, item]), ([, value]) => some(value)),\n        ],\n        (bytes, offset) => {\n            if (config.prefix === null && !config.noneValue) {\n                return Number(offset < bytes.length);\n            }\n            if (config.prefix === null && config.noneValue != null) {\n                const zeroValue =\n                    config.noneValue === 'zeroes' ? new Uint8Array(noneValue.fixedSize).fill(0) : config.noneValue;\n                return containsBytes(bytes, zeroValue, offset) ? 0 : 1;\n            }\n            return Number(prefix.read(bytes, offset)[0]);\n        },\n    );\n}\n\n/**\n * Returns a codec for encoding and decoding optional values using the {@link Option} type.\n *\n * This codec serializes and deserializes `Option<T>` values using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`).\n * - If `noneValue: 'zeroes'` is set, `None` values are encoded/decoded as zeroes.\n * - If `noneValue` is a byte array, `None` values are represented by the provided constant.\n * - If `prefix: null` is set, the codec determines `None` values solely from `noneValue` or the presence of bytes.\n *\n * For more details on the configuration options, see {@link OptionCodecConfig}.\n *\n * Note that this behaves similarly to {@link getNullableCodec}, except it\n * encodes {@link OptionOrNullable} values and decodes {@link Option} values.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The codec for the value that may be present.\n * @param config - Configuration options for encoding and decoding option values.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding option values.\n *\n * @example\n * Encoding and decoding an optional string with a size prefix.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const codec = getOptionCodec(stringCodec);\n *\n * const someBytes = codec.encode(some('Hi'));\n * // 0x01020000004869\n * //   | |       └-- utf8 string content (\"Hi\").\n * //   | └-- u32 string prefix (2 characters).\n * //   └-- 1-byte prefix (Some).\n *\n * const noneBytes = codec.encode(none());\n * // 0x00\n * //   └-- 1-byte prefix (None).\n *\n * codec.decode(someBytes); // some('Hi')\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding nullable values.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const codec = getOptionCodec(stringCodec);\n *\n * const someBytes = codec.encode('Hi'); // 0x01020000004869\n * const noneBytes = codec.encode(null); // 0x00\n *\n * codec.decode(someBytes); // some('Hi')\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding and decoding an optional number with a fixed size.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n *\n * const someBytes = codec.encode(some(42)); // 0x012a00\n * const noneBytes = codec.encode(none());   // 0x000000\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding and decoding {@link None} values with a custom byte sequence and no prefix.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), {\n *   noneValue: new Uint8Array([0xff, 0xff]),\n *   prefix: null,\n * });\n *\n * const someBytes = codec.encode(some(42)); // 0x2a00\n * const noneBytes = codec.encode(none());   // 0xffff\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Identifying {@link None} values by the absence of bytes.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), { prefix: null });\n *\n * const someBytes = codec.encode(some(42)); // 0x2a00\n * const noneBytes = codec.encode(none());   // new Uint8Array(0)\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @remarks\n * Separate {@link getOptionEncoder} and {@link getOptionDecoder} functions are available.\n *\n * ```ts\n * const bytes = getOptionEncoder(getU32Encoder()).encode(some(42));\n * const value = getOptionDecoder(getU32Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getOptionEncoder}\n * @see {@link getOptionDecoder}\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    item: FixedSizeCodec<TFrom, TTo, TSize>,\n    config: OptionCodecConfig<NumberCodec> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>, TSize>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: OptionCodecConfig<FixedSizeNumberCodec> & { noneValue: 'zeroes' },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: OptionCodecConfig<NumberCodec> & { noneValue: 'zeroes' },\n): VariableSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config?: OptionCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<TFrom>, Option<TTo>> {\n    type ConfigCast = OptionCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array };\n    return combineCodec(\n        getOptionEncoder<TFrom>(item, config as ConfigCast),\n        getOptionDecoder<TTo>(item, config as ConfigCast),\n    );\n}\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Defines types that should not be recursively unwrapped.\n *\n * These types are preserved as-is when using {@link unwrapOptionRecursively}.\n *\n * @see {@link unwrapOptionRecursively}\n */\ntype UnUnwrappables =\n    | Date\n    | Int8Array\n    | Int16Array\n    | Int32Array\n    | Uint8Array\n    | Uint16Array\n    | Uint32Array\n    | bigint\n    | boolean\n    | number\n    | string\n    | symbol\n    | null\n    | undefined;\n\n/**\n * A type that recursively unwraps nested {@link Option} types.\n *\n * This type resolves all nested {@link Option} values, ensuring\n * that deeply wrapped values are properly extracted.\n *\n * - If `T` is an {@link Option}, it resolves to the contained value.\n * - If `T` is a known primitive or immutable type, it remains unchanged.\n * - If `T` is an object or array, it recursively unwraps any options found.\n *\n * The fallback type `U` (default: `null`) is used in place of `None` values.\n *\n * @typeParam T - The type to be unwrapped.\n * @typeParam U - The fallback type for `None` values (defaults to `null`).\n *\n * @example\n * Resolving nested `Option` types.\n * ```ts\n * UnwrappedOption<Some<Some<string>>>; // string\n * UnwrappedOption<None>;               // null\n * ```\n *\n * @example\n * Resolving options inside objects and arrays.\n * ```ts\n * UnwrappedOption<{ a: Some<number>; b: None }>; // { a: number; b: null }\n * UnwrappedOption<[Some<number>, None]>;         // [number, null]\n * ```\n *\n * @see {@link unwrapOptionRecursively}\n */\nexport type UnwrappedOption<T, U = null> =\n    T extends Some<infer TValue>\n        ? UnwrappedOption<TValue, U>\n        : T extends None\n          ? U\n          : T extends UnUnwrappables\n            ? T\n            : T extends object\n              ? { [key in keyof T]: UnwrappedOption<T[key], U> }\n              : T extends Array<infer TItem>\n                ? Array<UnwrappedOption<TItem, U>>\n                : T;\n\n/**\n * Recursively unwraps all nested {@link Option} types within a value.\n *\n * This function traverses a given value and removes all instances\n * of {@link Option}, replacing them with their contained values.\n *\n * - If an {@link Option} is encountered, its value is extracted.\n * - If an array or object is encountered, its elements are traversed recursively.\n * - If `None` is encountered, it is replaced with the fallback value (default: `null`).\n *\n * @typeParam T - The type of the input value.\n * @typeParam U - The fallback type for `None` values (defaults to `null`).\n *\n * @param input - The value to unwrap.\n * @param fallback - A function that provides a fallback value for `None` options.\n * @returns The recursively unwrapped value.\n *\n * @example\n * Recursively unwrapping nested options.\n * ```ts\n * unwrapOptionRecursively(some(some('Hello World'))); // \"Hello World\"\n * unwrapOptionRecursively(some(none<string>()));      // null\n * ```\n *\n * @example\n * Recursively unwrapping options inside objects and arrays.\n * ```ts\n * unwrapOptionRecursively({\n *   a: 'hello',\n *   b: none(),\n *   c: [{ c1: some(42) }, { c2: none() }],\n * });\n * // { a: \"hello\", b: null, c: [{ c1: 42 }, { c2: null }] }\n * ```\n *\n * @example\n * Using a fallback value for `None` options.\n * ```ts\n * unwrapOptionRecursively(\n *   {\n *     a: 'hello',\n *     b: none(),\n *     c: [{ c1: some(42) }, { c2: none() }],\n *   },\n *   () => 'Default',\n * );\n * // { a: \"hello\", b: \"Default\", c: [{ c1: 42 }, { c2: \"Default\" }] }\n * ```\n *\n * @remarks\n * This function does not mutate objects or arrays.\n *\n * @see {@link Option}\n * @see {@link UnwrappedOption}\n */\nexport function unwrapOptionRecursively<T>(input: T): UnwrappedOption<T>;\nexport function unwrapOptionRecursively<T, U>(input: T, fallback: () => U): UnwrappedOption<T, U>;\nexport function unwrapOptionRecursively<T, U = null>(input: T, fallback?: () => U): UnwrappedOption<T, U> {\n    // Types to bypass.\n    if (!input || ArrayBuffer.isView(input)) {\n        return input as UnwrappedOption<T, U>;\n    }\n\n    const next = <X>(x: X) =>\n        (fallback ? unwrapOptionRecursively(x, fallback) : unwrapOptionRecursively(x)) as UnwrappedOption<X, U>;\n\n    // Handle Option.\n    if (isOption(input)) {\n        if (isSome(input)) return next(input.value) as UnwrappedOption<T, U>;\n        return (fallback ? fallback() : null) as UnwrappedOption<T, U>;\n    }\n\n    // Walk.\n    if (Array.isArray(input)) {\n        return input.map(next) as UnwrappedOption<T, U>;\n    }\n    if (typeof input === 'object') {\n        return Object.fromEntries(Object.entries(input).map(([k, v]) => [k, next(v)])) as UnwrappedOption<T, U>;\n    }\n    return input as UnwrappedOption<T, U>;\n}\n"]}