@solana/options 2.0.0-experimental.eb951b0 → 2.0.0-experimental.ed41fe2
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/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js.map +1 -1
- package/dist/types/option-codec.d.ts +6 -6
- package/dist/types/option-codec.d.ts.map +1 -1
- package/dist/types/option.d.ts +1 -1
- package/dist/types/option.d.ts.map +1 -1
- package/dist/types/unwrap-option-recursively.d.ts +1 -1
- package/dist/types/unwrap-option-recursively.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":";AAkCO,IAAM,OAAO,CAAI,WAAyB,EAAE,UAAU,QAAQ,MAAM;AAOpE,IAAM,OAAO,OAAqB,EAAE,UAAU,OAAO;AAKrD,IAAM,WAAW,CAAc,UAClC,CAAC,EACG,SACA,OAAO,UAAU,YACjB,cAAc,UACZ,MAAM,aAAa,UAAU,WAAW,SAAU,MAAM,aAAa;AAMxE,IAAM,SAAS,CAAI,WAAyC,OAAO,aAAa;AAKhF,IAAM,SAAS,CAAI,WAAsC,OAAO,aAAa;;;AC9DpF;AAAA,EACI;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAMA;AAAA,EACA;AAAA,OAIG;AACP;AAAA,EAII;AAAA,EACA;AAAA,OAIG;;;AClBA,SAAS,aAA0B,QAAmB,UAA2B;AACpF,MAAI,OAAO,MAAM;AAAG,WAAO,OAAO;AAClC,SAAO,WAAW,SAAS,IAAK;AACpC;AAKO,IAAM,eAAe,CAAI,aAAmC,aAAa,OAAO,KAAK,QAAQ,IAAI,KAAQ;;;ADoDzG,SAAS,iBACZ,MACA,SAA2C,CAAC,GACZ;AAChC,QAAM,SAAS,OAAO,UAAU,aAAa;AAC7C,QAAM,QAAQ,OAAO,SAAS;AAE9B,QAAM,iBAAiB,YAAY,IAAI,KAAK,YAAY,MAAM,KAAK,KAAK,cAAc;AACtF,MAAI,SAAS,gBAAgB;AACzB,sBAAkB,IAAI;AACtB,sBAAkB,MAAM;AACxB,UAAM,YAAY,OAAO,YAAY,KAAK;AAC1C,WAAO,cAAc;AAAA,MACjB;AAAA,MACA,OAAO,CAAC,kBAA2C,OAAO,WAAW;AACjE,cAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,cAAM,eAAe,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM;AACvE,YAAI,OAAO,MAAM,GAAG;AAChB,eAAK,MAAM,OAAO,OAAO,OAAO,YAAY;AAAA,QAChD;AACA,eAAO,SAAS;AAAA,MACpB;AAAA,IACJ,CAAC;AAAA,EACL;AAEA,SAAO,cAAc;AAAA,IACjB,kBAAkB,CAAC,qBAA8C;AAC7D,YAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,aACI,eAAe,OAAO,OAAO,MAAM,CAAC,GAAG,MAAM,KAC5C,OAAO,MAAM,IAAI,eAAe,OAAO,OAAO,IAAI,IAAI;AAAA,IAE/D;AAAA,IACA,SAAS,cAAc,CAAC,QAAQ,IAAI,EAAE,IAAI,UAAU,CAAC,KAAK;AAAA,IAC1D,OAAO,CAAC,kBAA2C,OAAO,WAAW;AACjE,YAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,eAAS,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM;AAC3D,UAAI,OAAO,MAAM,GAAG;AAChB,iBAAS,KAAK,MAAM,OAAO,OAAO,OAAO,MAAM;AAAA,MACnD;AACA,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACL;AAoBO,SAAS,iBACZ,MACA,SAA2C,CAAC,GACxB;AACpB,QAAM,SAAS,OAAO,UAAU,aAAa;AAC7C,QAAM,QAAQ,OAAO,SAAS;AAE9B,MAAI,YAA2B;AAC/B,QAAM,iBAAiB,YAAY,IAAI,KAAK,YAAY,MAAM,KAAK,KAAK,cAAc;AACtF,MAAI,SAAS,gBAAgB;AACzB,sBAAkB,IAAI;AACtB,sBAAkB,MAAM;AACxB,gBAAY,OAAO,YAAY,KAAK;AAAA,EACxC;AAEA,SAAO,cAAc;AAAA,IACjB,GAAI,cAAc,OACZ,EAAE,SAAS,cAAc,CAAC,QAAQ,IAAI,EAAE,IAAI,UAAU,CAAC,KAAK,OAAU,IACtE,EAAE,UAAU;AAAA,IAClB,MAAM,CAAC,OAAmB,WAAW;AACjC,UAAI,MAAM,SAAS,UAAU,GAAG;AAC5B,eAAO,CAAC,KAAK,GAAG,MAAM;AAAA,MAC1B;AACA,YAAM,CAACA,SAAQ,YAAY,IAAI,OAAO,KAAK,OAAO,MAAM;AACxD,UAAIA,YAAW,GAAG;AACd,eAAO,CAAC,KAAK,GAAG,cAAc,OAAO,SAAS,YAAY,YAAY;AAAA,MAC1E;AACA,YAAM,CAAC,OAAO,SAAS,IAAI,KAAK,KAAK,OAAO,YAAY;AACxD,aAAO,CAAC,KAAK,KAAK,GAAG,cAAc,OAAO,SAAS,YAAY,SAAS;AAAA,IAC5E;AAAA,EACJ,CAAC;AACL;AAoBO,SAAS,eACZ,MACA,SAAyC,CAAC,GACC;AAC3C,SAAO,aAAa,iBAAwB,MAAM,MAAgB,GAAG,iBAAsB,MAAM,MAAgB,CAAC;AACtH;AAEA,SAAS,cAAc,OAAyC;AAC5D,SAAO,MAAM,OAAO,CAAC,KAAK,SAAU,QAAQ,QAAQ,SAAS,OAAO,OAAO,MAAM,MAAO,CAAkB;AAC9G;AAEA,SAAS,WAAW,OAAoE;AACpF,SAAO,YAAY,KAAK,IAAI,MAAM,YAAY,MAAM,WAAW;AACnE;;;AE9IO,SAAS,wBAAqC,OAAU,UAA2C;AAEtG,MAAI,CAAC,SAAS,YAAY,OAAO,KAAK,GAAG;AACrC,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,CAAI,MACZ,WAAW,wBAAwB,GAAG,QAAQ,IAAI,wBAAwB,CAAC;AAGhF,MAAI,SAAS,KAAK,GAAG;AACjB,QAAI,OAAO,KAAK;AAAG,aAAO,KAAK,MAAM,KAAK;AAC1C,WAAQ,WAAW,SAAS,IAAI;AAAA,EACpC;AAGA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,WAAO,MAAM,IAAI,IAAI;AAAA,EACzB;AACA,MAAI,OAAO,UAAU,UAAU;AAC3B,WAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAAA,EACjF;AACA,SAAO;AACX","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = {\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\n */\ntype UnUnwrappables =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | undefined\n | null\n | Uint8Array\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Date;\n\n/**\n * A type that defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\n */\nexport type UnwrappedOption<T, U = null> = 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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\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 defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = {\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\n */\ntype UnUnwrappables =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | undefined\n | null\n | Uint8Array\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Date;\n\n/**\n * A type that defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\n */\nexport type UnwrappedOption<T, U = null> = 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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\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 defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
package/dist/index.native.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":";AAkCO,IAAM,OAAO,CAAI,WAAyB,EAAE,UAAU,QAAQ,MAAM;AAOpE,IAAM,OAAO,OAAqB,EAAE,UAAU,OAAO;AAKrD,IAAM,WAAW,CAAc,UAClC,CAAC,EACG,SACA,OAAO,UAAU,YACjB,cAAc,UACZ,MAAM,aAAa,UAAU,WAAW,SAAU,MAAM,aAAa;AAMxE,IAAM,SAAS,CAAI,WAAyC,OAAO,aAAa;AAKhF,IAAM,SAAS,CAAI,WAAsC,OAAO,aAAa;;;AC9DpF;AAAA,EACI;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAMA;AAAA,EACA;AAAA,OAIG;AACP;AAAA,EAII;AAAA,EACA;AAAA,OAIG;;;AClBA,SAAS,aAA0B,QAAmB,UAA2B;AACpF,MAAI,OAAO,MAAM;AAAG,WAAO,OAAO;AAClC,SAAO,WAAW,SAAS,IAAK;AACpC;AAKO,IAAM,eAAe,CAAI,aAAmC,aAAa,OAAO,KAAK,QAAQ,IAAI,KAAQ;;;ADoDzG,SAAS,iBACZ,MACA,SAA2C,CAAC,GACZ;AAChC,QAAM,SAAS,OAAO,UAAU,aAAa;AAC7C,QAAM,QAAQ,OAAO,SAAS;AAE9B,QAAM,iBAAiB,YAAY,IAAI,KAAK,YAAY,MAAM,KAAK,KAAK,cAAc;AACtF,MAAI,SAAS,gBAAgB;AACzB,sBAAkB,IAAI;AACtB,sBAAkB,MAAM;AACxB,UAAM,YAAY,OAAO,YAAY,KAAK;AAC1C,WAAO,cAAc;AAAA,MACjB;AAAA,MACA,OAAO,CAAC,kBAA2C,OAAO,WAAW;AACjE,cAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,cAAM,eAAe,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM;AACvE,YAAI,OAAO,MAAM,GAAG;AAChB,eAAK,MAAM,OAAO,OAAO,OAAO,YAAY;AAAA,QAChD;AACA,eAAO,SAAS;AAAA,MACpB;AAAA,IACJ,CAAC;AAAA,EACL;AAEA,SAAO,cAAc;AAAA,IACjB,kBAAkB,CAAC,qBAA8C;AAC7D,YAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,aACI,eAAe,OAAO,OAAO,MAAM,CAAC,GAAG,MAAM,KAC5C,OAAO,MAAM,IAAI,eAAe,OAAO,OAAO,IAAI,IAAI;AAAA,IAE/D;AAAA,IACA,SAAS,cAAc,CAAC,QAAQ,IAAI,EAAE,IAAI,UAAU,CAAC,KAAK;AAAA,IAC1D,OAAO,CAAC,kBAA2C,OAAO,WAAW;AACjE,YAAM,SAAS,SAAgB,gBAAgB,IAAI,mBAAmB,aAAa,gBAAgB;AACnG,eAAS,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM;AAC3D,UAAI,OAAO,MAAM,GAAG;AAChB,iBAAS,KAAK,MAAM,OAAO,OAAO,OAAO,MAAM;AAAA,MACnD;AACA,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACL;AAoBO,SAAS,iBACZ,MACA,SAA2C,CAAC,GACxB;AACpB,QAAM,SAAS,OAAO,UAAU,aAAa;AAC7C,QAAM,QAAQ,OAAO,SAAS;AAE9B,MAAI,YAA2B;AAC/B,QAAM,iBAAiB,YAAY,IAAI,KAAK,YAAY,MAAM,KAAK,KAAK,cAAc;AACtF,MAAI,SAAS,gBAAgB;AACzB,sBAAkB,IAAI;AACtB,sBAAkB,MAAM;AACxB,gBAAY,OAAO,YAAY,KAAK;AAAA,EACxC;AAEA,SAAO,cAAc;AAAA,IACjB,GAAI,cAAc,OACZ,EAAE,SAAS,cAAc,CAAC,QAAQ,IAAI,EAAE,IAAI,UAAU,CAAC,KAAK,OAAU,IACtE,EAAE,UAAU;AAAA,IAClB,MAAM,CAAC,OAAmB,WAAW;AACjC,UAAI,MAAM,SAAS,UAAU,GAAG;AAC5B,eAAO,CAAC,KAAK,GAAG,MAAM;AAAA,MAC1B;AACA,YAAM,CAACA,SAAQ,YAAY,IAAI,OAAO,KAAK,OAAO,MAAM;AACxD,UAAIA,YAAW,GAAG;AACd,eAAO,CAAC,KAAK,GAAG,cAAc,OAAO,SAAS,YAAY,YAAY;AAAA,MAC1E;AACA,YAAM,CAAC,OAAO,SAAS,IAAI,KAAK,KAAK,OAAO,YAAY;AACxD,aAAO,CAAC,KAAK,KAAK,GAAG,cAAc,OAAO,SAAS,YAAY,SAAS;AAAA,IAC5E;AAAA,EACJ,CAAC;AACL;AAoBO,SAAS,eACZ,MACA,SAAyC,CAAC,GACC;AAC3C,SAAO,aAAa,iBAAwB,MAAM,MAAgB,GAAG,iBAAsB,MAAM,MAAgB,CAAC;AACtH;AAEA,SAAS,cAAc,OAAyC;AAC5D,SAAO,MAAM,OAAO,CAAC,KAAK,SAAU,QAAQ,QAAQ,SAAS,OAAO,OAAO,MAAM,MAAO,CAAkB;AAC9G;AAEA,SAAS,WAAW,OAAoE;AACpF,SAAO,YAAY,KAAK,IAAI,MAAM,YAAY,MAAM,WAAW;AACnE;;;AE9IO,SAAS,wBAAqC,OAAU,UAA2C;AAEtG,MAAI,CAAC,SAAS,YAAY,OAAO,KAAK,GAAG;AACrC,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,CAAI,MACZ,WAAW,wBAAwB,GAAG,QAAQ,IAAI,wBAAwB,CAAC;AAGhF,MAAI,SAAS,KAAK,GAAG;AACjB,QAAI,OAAO,KAAK;AAAG,aAAO,KAAK,MAAM,KAAK;AAC1C,WAAQ,WAAW,SAAS,IAAI;AAAA,EACpC;AAGA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,WAAO,MAAM,IAAI,IAAI;AAAA,EACzB;AACA,MAAI,OAAO,UAAU,UAAU;AAC3B,WAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AAAA,EACjF;AACA,SAAO;AACX","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = {\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\n */\ntype UnUnwrappables =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | undefined\n | null\n | Uint8Array\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Date;\n\n/**\n * A type that defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\n */\nexport type UnwrappedOption<T, U = null> = 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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\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 defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
package/dist/index.node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = {\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\n */\ntype UnUnwrappables =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | undefined\n | null\n | Uint8Array\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Date;\n\n/**\n * A type that defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\n */\nexport type UnwrappedOption<T, U = null> = 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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\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 defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
package/dist/index.node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = {\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\n */\ntype UnUnwrappables =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | undefined\n | null\n | Uint8Array\n | Int8Array\n | Uint16Array\n | Int16Array\n | Uint32Array\n | Int32Array\n | Date;\n\n/**\n * A type that defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\n */\nexport type UnwrappedOption<T, U = null> = 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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/option.ts","../src/option-codec.ts","../src/unwrap-option.ts","../src/unwrap-option-recursively.ts"],"names":["isSome"],"mappings":"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","sourcesContent":["/**\n * An implementation of the Rust Option type in JavaScript.\n * It can be one of the following:\n * - <code>{@link Some}<T></code>: Meaning there is a value of type T.\n * - <code>{@link None}</code>: Meaning there is no value.\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * Defines a looser type that can be used when serializing an {@link Option}.\n * This allows us to pass null or the Option value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an option of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an option of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} of type `T` that has a value.\n *\n * @see {@link Option}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} of type `T` that has no value.\n *\n * @see {@link Option}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Whether the given data is an {@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 * Whether the given {@link Option} is a {@link Some}.\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Whether the given {@link Option} is a {@link None}.\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n","import {\n assertIsFixedSize,\n Codec,\n combineCodec,\n createDecoder,\n createEncoder,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n getEncodedSize,\n isFixedSize,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\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, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the config for option codecs. */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n /**\n * Whether the item codec should be of fixed size.\n *\n * When this is true, a `None` value will skip the bytes that would\n * have been used for the item. Note that this will only work if the\n * item codec is of fixed size.\n * @defaultValue `false`\n */\n fixed?: boolean;\n\n /**\n * The codec to use for the boolean prefix.\n * @defaultValue u8 prefix.\n */\n prefix?: TPrefix;\n};\n\n/**\n * Creates a encoder for an optional value using `null` as the `None` value.\n *\n * @param item - The encoder to use for the value that may be present.\n * @param config - A set of config for the encoder.\n */\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom>,\n config: OptionCodecConfig<FixedSizeNumberEncoder> & { fixed: true },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: FixedSizeEncoder<TFrom, 0>,\n config?: OptionCodecConfig<FixedSizeNumberEncoder>,\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config?: OptionCodecConfig<NumberEncoder> & { fixed?: false },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n item: Encoder<TFrom>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n const fixedSize = prefix.fixedSize + item.fixedSize;\n return createEncoder({\n fixedSize,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixOffset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n item.write(option.value, bytes, prefixOffset);\n }\n return offset + fixedSize;\n },\n });\n }\n\n return createEncoder({\n getSizeFromValue: (optionOrNullable: OptionOrNullable<TFrom>) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n return (\n getEncodedSize(Number(isSome(option)), prefix) +\n (isSome(option) ? getEncodedSize(option.value, item) : 0)\n );\n },\n maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined,\n write: (optionOrNullable: OptionOrNullable<TFrom>, bytes, offset) => {\n const option = isOption<TFrom>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n offset = prefix.write(Number(isSome(option)), bytes, offset);\n if (isSome(option)) {\n offset = item.write(option.value, bytes, offset);\n }\n return offset;\n },\n });\n}\n\n/**\n * Creates a decoder for an optional value using `null` as the `None` value.\n *\n * @param item - The decoder to use for the value that may be present.\n * @param config - A set of config for the decoder.\n */\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo>,\n config: OptionCodecConfig<FixedSizeNumberDecoder> & { fixed: true },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: FixedSizeDecoder<TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberDecoder>,\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config?: OptionCodecConfig<NumberDecoder> & { fixed?: false },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n item: Decoder<TTo>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n\n let fixedSize: number | null = null;\n const isZeroSizeItem = isFixedSize(item) && isFixedSize(prefix) && item.fixedSize === 0;\n if (fixed || isZeroSizeItem) {\n assertIsFixedSize(item);\n assertIsFixedSize(prefix);\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return createDecoder({\n ...(fixedSize === null\n ? { maxSize: sumCodecSizes([prefix, item].map(getMaxSize)) ?? undefined }\n : { fixedSize }),\n read: (bytes: Uint8Array, offset) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const [isSome, prefixOffset] = prefix.read(bytes, offset);\n if (isSome === 0) {\n return [none(), fixedSize !== null ? offset + fixedSize : prefixOffset];\n }\n const [value, newOffset] = item.read(bytes, prefixOffset);\n return [some(value), fixedSize !== null ? offset + fixedSize : newOffset];\n },\n });\n}\n\n/**\n * Creates a codec for an optional value using `null` as the `None` value.\n *\n * @param item - The codec to use for the value that may be present.\n * @param config - A set of config for the codec.\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo>,\n config: OptionCodecConfig<FixedSizeNumberCodec> & { fixed: true },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: FixedSizeCodec<TFrom, TTo, 0>,\n config?: OptionCodecConfig<FixedSizeNumberCodec>,\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n item: Codec<TFrom, TTo>,\n config?: OptionCodecConfig<NumberCodec> & { fixed?: false },\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 return combineCodec(getOptionEncoder<TFrom>(item, config as object), getOptionDecoder<TTo>(item, config as object));\n}\n\nfunction sumCodecSizes(sizes: (number | null)[]): number | null {\n return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nfunction getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n return isFixedSize(codec) ? codec.fixedSize : codec.maxSize ?? null;\n}\n","import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option} of type `T`\n * or returns a fallback value that defaults to `null`.\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 */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n","import { isOption, isSome, None, Some } from './option';\n\n/**\n * Lists all types that should not be recursively unwrapped.\n *\n * @see {@link UnwrappedOption}\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 defines the recursive unwrapping of a type `T`\n * such that all nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns the type of its value, otherwise, it returns the provided\n * fallback type `U` which defaults to `null`.\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 go through a type `T` such that all\n * nested {@link Option} types are unwrapped.\n *\n * For each nested {@link Option} type, if the option is a {@link Some},\n * it returns its value, otherwise, it returns the provided fallback value\n * which defaults to `null`.\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"]}
|
|
@@ -2,12 +2,7 @@ import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEnc
|
|
|
2
2
|
import { FixedSizeNumberCodec, FixedSizeNumberDecoder, FixedSizeNumberEncoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';
|
|
3
3
|
import { Option, OptionOrNullable } from './option.js';
|
|
4
4
|
/** Defines the config for option codecs. */
|
|
5
|
-
export type OptionCodecConfig<TPrefix extends NumberCodec |
|
|
6
|
-
/**
|
|
7
|
-
* The codec to use for the boolean prefix.
|
|
8
|
-
* @defaultValue u8 prefix.
|
|
9
|
-
*/
|
|
10
|
-
prefix?: TPrefix;
|
|
5
|
+
export type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {
|
|
11
6
|
/**
|
|
12
7
|
* Whether the item codec should be of fixed size.
|
|
13
8
|
*
|
|
@@ -17,6 +12,11 @@ export type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | Numb
|
|
|
17
12
|
* @defaultValue `false`
|
|
18
13
|
*/
|
|
19
14
|
fixed?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The codec to use for the boolean prefix.
|
|
17
|
+
* @defaultValue u8 prefix.
|
|
18
|
+
*/
|
|
19
|
+
prefix?: TPrefix;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* Creates a encoder for an optional value using `null` as the `None` value.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-codec.d.ts","sourceRoot":"","sources":["../../src/option-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,EAIL,OAAO,EACP,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAGhB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAGtB,WAAW,EACX,aAAa,EACb,aAAa,EAChB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAA0B,MAAM,EAAE,gBAAgB,EAAQ,MAAM,UAAU,CAAC;AAGlF,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,WAAW,GAAG,aAAa,GAAG,aAAa,IAAI;IACzF
|
|
1
|
+
{"version":3,"file":"option-codec.d.ts","sourceRoot":"","sources":["../../src/option-codec.ts"],"names":[],"mappings":"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"}
|
package/dist/types/option.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* - <code>{@link Some}<T></code>: Meaning there is a value of type T.
|
|
5
5
|
* - <code>{@link None}</code>: Meaning there is no value.
|
|
6
6
|
*/
|
|
7
|
-
export type Option<T> = Some<T
|
|
7
|
+
export type Option<T> = None | Some<T>;
|
|
8
8
|
/**
|
|
9
9
|
* Defines a looser type that can be used when serializing an {@link Option}.
|
|
10
10
|
* This allows us to pass null or the Option value directly whilst still
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../../src/option.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../../src/option.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,IAAI,4BAA4D,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,IAAI,oBAA6C,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,QAAQ,uBAAwB,OAAO,uBAM/C,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,MAAM;cArCwB,MAAM;;EAqC4C,CAAC;AAE9F;;GAEG;AACH,eAAO,MAAM,MAAM;cAnCqB,MAAM;EAmC4C,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { None, Some } from './option.js';
|
|
|
4
4
|
*
|
|
5
5
|
* @see {@link UnwrappedOption}
|
|
6
6
|
*/
|
|
7
|
-
type UnUnwrappables =
|
|
7
|
+
type UnUnwrappables = Date | Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | bigint | boolean | number | string | symbol | null | undefined;
|
|
8
8
|
/**
|
|
9
9
|
* A type that defines the recursive unwrapping of a type `T`
|
|
10
10
|
* such that all nested {@link Option} types are unwrapped.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unwrap-option-recursively.d.ts","sourceRoot":"","sources":["../../src/unwrap-option-recursively.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,IAAI,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAExD;;;;GAIG;AACH,KAAK,cAAc,GACb,
|
|
1
|
+
{"version":3,"file":"unwrap-option-recursively.d.ts","sourceRoot":"","sources":["../../src/unwrap-option-recursively.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,IAAI,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAExD;;;;GAIG;AACH,KAAK,cAAc,GACb,IAAI,GACJ,SAAS,GACT,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,WAAW,GACX,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,IAAI,GACJ,SAAS,CAAC;AAEhB;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IACnC,CAAC,SAAS,IAAI,CAAC,MAAM,MAAM,CAAC,GACtB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,GAC1B,CAAC,SAAS,IAAI,GACZ,CAAC,GACD,CAAC,SAAS,cAAc,GACtB,CAAC,GACD,CAAC,SAAS,MAAM,GACd;KAAG,GAAG,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;CAAE,GAChD,CAAC,SAAS,KAAK,CAAC,MAAM,KAAK,CAAC,GAC1B,KAAK,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAChC,CAAC,CAAC;AAEpB;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;AACzE,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solana/options",
|
|
3
|
-
"version": "2.0.0-experimental.
|
|
3
|
+
"version": "2.0.0-experimental.ed41fe2",
|
|
4
4
|
"description": "Managing and serializing Rust-like Option types in JavaScript",
|
|
5
5
|
"exports": {
|
|
6
6
|
"browser": {
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"node": ">=17.4"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@solana/codecs-core": "2.0.0-experimental.
|
|
53
|
-
"@solana/codecs-numbers": "2.0.0-experimental.
|
|
52
|
+
"@solana/codecs-core": "2.0.0-experimental.ed41fe2",
|
|
53
|
+
"@solana/codecs-numbers": "2.0.0-experimental.ed41fe2"
|
|
54
54
|
},
|
|
55
55
|
"bundlewatch": {
|
|
56
56
|
"defaultCompression": "gzip",
|
|
@@ -62,18 +62,18 @@
|
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"compile:js": "tsup --config build-scripts/tsup.config.package.ts",
|
|
65
|
-
"compile:typedefs": "tsc -p ./tsconfig.declarations.json && node node_modules/@solana/build-scripts/add-js-extension-to-types.mjs",
|
|
66
|
-
"dev": "jest -c node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
|
|
65
|
+
"compile:typedefs": "tsc -p ./tsconfig.declarations.json && node ../../node_modules/@solana/build-scripts/add-js-extension-to-types.mjs",
|
|
66
|
+
"dev": "jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
|
|
67
67
|
"publish-impl": "npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || pnpm publish --tag experimental --access public --no-git-checks",
|
|
68
68
|
"publish-packages": "pnpm prepublishOnly && pnpm publish-impl",
|
|
69
69
|
"style:fix": "pnpm eslint --fix src/* && pnpm prettier -w src/* package.json",
|
|
70
|
-
"test:lint": "jest -c node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
|
|
71
|
-
"test:prettier": "jest -c node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
|
|
70
|
+
"test:lint": "jest -c ../../node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
|
|
71
|
+
"test:prettier": "jest -c ../../node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
|
|
72
72
|
"test:treeshakability:browser": "agadoo dist/index.browser.js",
|
|
73
73
|
"test:treeshakability:native": "agadoo dist/index.node.js",
|
|
74
74
|
"test:treeshakability:node": "agadoo dist/index.native.js",
|
|
75
75
|
"test:typecheck": "tsc --noEmit",
|
|
76
|
-
"test:unit:browser": "jest -c node_modules/@solana/test-config/jest-unit.config.browser.ts --rootDir . --silent",
|
|
77
|
-
"test:unit:node": "jest -c node_modules/@solana/test-config/jest-unit.config.node.ts --rootDir . --silent"
|
|
76
|
+
"test:unit:browser": "jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.ts --rootDir . --silent",
|
|
77
|
+
"test:unit:node": "jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.ts --rootDir . --silent"
|
|
78
78
|
}
|
|
79
79
|
}
|