@solana/options 2.0.0-experimental.bfaffe0 → 2.0.0-experimental.c156b67
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/LICENSE +1 -1
- package/dist/index.browser.cjs +10 -12
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +10 -12
- package/dist/index.browser.js.map +1 -1
- package/dist/index.development.js +26 -22
- package/dist/index.development.js.map +1 -1
- package/dist/index.native.js +10 -10
- package/dist/index.native.js.map +1 -1
- package/dist/index.node.cjs +10 -10
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.js +10 -10
- package/dist/index.node.js.map +1 -1
- package/dist/index.production.min.js +12 -12
- package/dist/types/option-codec.d.ts +9 -9
- package/dist/types/option-codec.d.ts.map +1 -1
- package/dist/types/unwrap-option-recursively.d.ts.map +1 -1
- package/package.json +11 -11
package/LICENSE
CHANGED
package/dist/index.browser.cjs
CHANGED
|
@@ -37,11 +37,11 @@ function optionCodecHelper(item, prefix, fixed, description) {
|
|
|
37
37
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function getOptionEncoder(item,
|
|
41
|
-
const prefix =
|
|
42
|
-
const fixed =
|
|
40
|
+
function getOptionEncoder(item, config = {}) {
|
|
41
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
|
|
42
|
+
const fixed = config.fixed ?? false;
|
|
43
43
|
return {
|
|
44
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
44
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
45
45
|
encode: (optionOrNullable) => {
|
|
46
46
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
47
47
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -51,11 +51,11 @@ function getOptionEncoder(item, options = {}) {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
function getOptionDecoder(item,
|
|
55
|
-
const prefix =
|
|
56
|
-
const fixed =
|
|
54
|
+
function getOptionDecoder(item, config = {}) {
|
|
55
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
|
|
56
|
+
const fixed = config.fixed ?? false;
|
|
57
57
|
return {
|
|
58
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
58
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
59
59
|
decode: (bytes, offset = 0) => {
|
|
60
60
|
if (bytes.length - offset <= 0) {
|
|
61
61
|
return [none(), offset];
|
|
@@ -72,8 +72,8 @@ function getOptionDecoder(item, options = {}) {
|
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
function getOptionCodec(item,
|
|
76
|
-
return codecsCore.combineCodec(getOptionEncoder(item,
|
|
75
|
+
function getOptionCodec(item, config = {}) {
|
|
76
|
+
return codecsCore.combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/unwrap-option-recursively.ts
|
|
@@ -107,5 +107,3 @@ exports.some = some;
|
|
|
107
107
|
exports.unwrapOption = unwrapOption;
|
|
108
108
|
exports.unwrapOptionRecursively = unwrapOptionRecursively;
|
|
109
109
|
exports.wrapNullable = wrapNullable;
|
|
110
|
-
//# sourceMappingURL=out.js.map
|
|
111
|
-
//# sourceMappingURL=index.browser.cjs.map
|
|
@@ -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 assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\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> = 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 assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\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"]}
|
package/dist/index.browser.js
CHANGED
|
@@ -35,11 +35,11 @@ function optionCodecHelper(item, prefix, fixed, description) {
|
|
|
35
35
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
function getOptionEncoder(item,
|
|
39
|
-
const prefix =
|
|
40
|
-
const fixed =
|
|
38
|
+
function getOptionEncoder(item, config = {}) {
|
|
39
|
+
const prefix = config.prefix ?? getU8Encoder();
|
|
40
|
+
const fixed = config.fixed ?? false;
|
|
41
41
|
return {
|
|
42
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
42
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
43
43
|
encode: (optionOrNullable) => {
|
|
44
44
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
45
45
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -49,11 +49,11 @@ function getOptionEncoder(item, options = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
function getOptionDecoder(item,
|
|
53
|
-
const prefix =
|
|
54
|
-
const fixed =
|
|
52
|
+
function getOptionDecoder(item, config = {}) {
|
|
53
|
+
const prefix = config.prefix ?? getU8Decoder();
|
|
54
|
+
const fixed = config.fixed ?? false;
|
|
55
55
|
return {
|
|
56
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
56
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
57
57
|
decode: (bytes, offset = 0) => {
|
|
58
58
|
if (bytes.length - offset <= 0) {
|
|
59
59
|
return [none(), offset];
|
|
@@ -70,8 +70,8 @@ function getOptionDecoder(item, options = {}) {
|
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
function getOptionCodec(item,
|
|
74
|
-
return combineCodec(getOptionEncoder(item,
|
|
73
|
+
function getOptionCodec(item, config = {}) {
|
|
74
|
+
return combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// src/unwrap-option-recursively.ts
|
|
@@ -95,5 +95,3 @@ function unwrapOptionRecursively(input, fallback) {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
export { getOptionCodec, getOptionDecoder, getOptionEncoder, isNone, isOption, isSome, none, some, unwrapOption, unwrapOptionRecursively, wrapNullable };
|
|
98
|
-
//# sourceMappingURL=out.js.map
|
|
99
|
-
//# sourceMappingURL=index.browser.js.map
|
|
@@ -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 assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\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> = 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 assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\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"]}
|
|
@@ -23,7 +23,7 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
23
23
|
}
|
|
24
24
|
function assertFixedSizeCodec(data, message) {
|
|
25
25
|
if (data.fixedSize === null) {
|
|
26
|
-
throw new Error(message
|
|
26
|
+
throw new Error(message != null ? message : "Expected a fixed-size codec, got a variable-size one.");
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
var mergeBytes = (byteArrays) => {
|
|
@@ -69,7 +69,7 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
69
69
|
}
|
|
70
70
|
return {
|
|
71
71
|
decode: decoder.decode,
|
|
72
|
-
description: description
|
|
72
|
+
description: description != null ? description : encoder.description,
|
|
73
73
|
encode: encoder.encode,
|
|
74
74
|
fixedSize: encoder.fixedSize,
|
|
75
75
|
maxSize: encoder.maxSize
|
|
@@ -85,14 +85,15 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
function sharedNumberFactory(input) {
|
|
88
|
+
var _a;
|
|
88
89
|
let littleEndian;
|
|
89
90
|
let defaultDescription = input.name;
|
|
90
91
|
if (input.size > 1) {
|
|
91
|
-
littleEndian = !("endian" in input.
|
|
92
|
+
littleEndian = !("endian" in input.config) || input.config.endian === 0;
|
|
92
93
|
defaultDescription += littleEndian ? "(le)" : "(be)";
|
|
93
94
|
}
|
|
94
95
|
return {
|
|
95
|
-
description: input.
|
|
96
|
+
description: (_a = input.config.description) != null ? _a : defaultDescription,
|
|
96
97
|
fixedSize: input.size,
|
|
97
98
|
littleEndian,
|
|
98
99
|
maxSize: input.size
|
|
@@ -129,21 +130,21 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
129
130
|
};
|
|
130
131
|
}
|
|
131
132
|
function toArrayBuffer(bytes, offset, length) {
|
|
132
|
-
const bytesOffset = bytes.byteOffset + (offset
|
|
133
|
-
const bytesLength = length
|
|
133
|
+
const bytesOffset = bytes.byteOffset + (offset != null ? offset : 0);
|
|
134
|
+
const bytesLength = length != null ? length : bytes.byteLength;
|
|
134
135
|
return bytes.buffer.slice(bytesOffset, bytesOffset + bytesLength);
|
|
135
136
|
}
|
|
136
|
-
var getU8Encoder = (
|
|
137
|
+
var getU8Encoder = (config = {}) => numberEncoderFactory({
|
|
138
|
+
config,
|
|
137
139
|
name: "u8",
|
|
138
|
-
options,
|
|
139
140
|
range: [0, Number("0xff")],
|
|
140
141
|
set: (view, value) => view.setUint8(0, value),
|
|
141
142
|
size: 1
|
|
142
143
|
});
|
|
143
|
-
var getU8Decoder = (
|
|
144
|
+
var getU8Decoder = (config = {}) => numberDecoderFactory({
|
|
145
|
+
config,
|
|
144
146
|
get: (view) => view.getUint8(0),
|
|
145
147
|
name: "u8",
|
|
146
|
-
options,
|
|
147
148
|
size: 1
|
|
148
149
|
});
|
|
149
150
|
|
|
@@ -169,16 +170,17 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
169
170
|
fixedSize = prefix.fixedSize + item.fixedSize;
|
|
170
171
|
}
|
|
171
172
|
return {
|
|
172
|
-
description: description
|
|
173
|
+
description: description != null ? description : `option(${item.description + descriptionSuffix})`,
|
|
173
174
|
fixedSize,
|
|
174
175
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
175
176
|
};
|
|
176
177
|
}
|
|
177
|
-
function getOptionEncoder(item,
|
|
178
|
-
|
|
179
|
-
const
|
|
178
|
+
function getOptionEncoder(item, config = {}) {
|
|
179
|
+
var _a, _b;
|
|
180
|
+
const prefix = (_a = config.prefix) != null ? _a : getU8Encoder();
|
|
181
|
+
const fixed = (_b = config.fixed) != null ? _b : false;
|
|
180
182
|
return {
|
|
181
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
183
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
182
184
|
encode: (optionOrNullable) => {
|
|
183
185
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
184
186
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -188,16 +190,18 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
188
190
|
}
|
|
189
191
|
};
|
|
190
192
|
}
|
|
191
|
-
function getOptionDecoder(item,
|
|
192
|
-
|
|
193
|
-
const
|
|
193
|
+
function getOptionDecoder(item, config = {}) {
|
|
194
|
+
var _a, _b;
|
|
195
|
+
const prefix = (_a = config.prefix) != null ? _a : getU8Decoder();
|
|
196
|
+
const fixed = (_b = config.fixed) != null ? _b : false;
|
|
194
197
|
return {
|
|
195
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
198
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
196
199
|
decode: (bytes, offset = 0) => {
|
|
200
|
+
var _a2, _b2;
|
|
197
201
|
if (bytes.length - offset <= 0) {
|
|
198
202
|
return [none(), offset];
|
|
199
203
|
}
|
|
200
|
-
const fixedOffset = offset + (prefix.fixedSize
|
|
204
|
+
const fixedOffset = offset + ((_a2 = prefix.fixedSize) != null ? _a2 : 0) + ((_b2 = item.fixedSize) != null ? _b2 : 0);
|
|
201
205
|
const [isSome2, prefixOffset] = prefix.decode(bytes, offset);
|
|
202
206
|
offset = prefixOffset;
|
|
203
207
|
if (isSome2 === 0) {
|
|
@@ -209,8 +213,8 @@ this.globalThis.solanaWeb3 = (function (exports) {
|
|
|
209
213
|
}
|
|
210
214
|
};
|
|
211
215
|
}
|
|
212
|
-
function getOptionCodec(item,
|
|
213
|
-
return combineCodec(getOptionEncoder(item,
|
|
216
|
+
function getOptionCodec(item, config = {}) {
|
|
217
|
+
return combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
214
218
|
}
|
|
215
219
|
|
|
216
220
|
// src/unwrap-option-recursively.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/option.ts","../../codecs-core/src/assertions.ts","../../codecs-core/src/bytes.ts","../../codecs-core/src/combine-codec.ts","../../codecs-numbers/src/assertions.ts","../../codecs-numbers/src/f32.ts","../../codecs-numbers/src/utils.ts","../../codecs-numbers/src/u16.ts","../../codecs-numbers/src/u32.ts","../src/unwrap-option.ts","../src/option-codec.ts","../src/unwrap-option-recursively.ts"],"names":["combineCodec","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 { CodecData } from './codec';\n\n/**\n * Asserts that a given byte array is not empty.\n */\nexport function assertByteArrayIsNotEmptyForCodec(codecDescription: string, bytes: Uint8Array, offset = 0) {\n if (bytes.length - offset <= 0) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);\n }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode.\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n codecDescription: string,\n expected: number,\n bytes: Uint8Array,\n offset = 0\n) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n // TODO: Coded error.\n throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);\n }\n}\n\n/**\n * Asserts that a given codec is fixed-size codec.\n */\nexport function assertFixedSizeCodec(\n data: Pick<CodecData, 'fixedSize'>,\n message?: string\n): asserts data is { fixedSize: number } {\n if (data.fixedSize === null) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a fixed-size codec, got a variable-size one.');\n }\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","import { Codec, Decoder, Encoder } from './codec';\n\n/**\n * Combines an encoder and a decoder into a codec.\n * The encoder and decoder must have the same fixed size, max size and description.\n * If a description is provided, it will override the encoder and decoder descriptions.\n */\nexport function combineCodec<From, To extends From = From>(\n encoder: Encoder<From>,\n decoder: Decoder<To>,\n description?: string\n): Codec<From, To> {\n if (encoder.fixedSize !== decoder.fixedSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`\n );\n }\n\n if (encoder.maxSize !== decoder.maxSize) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`\n );\n }\n\n if (description === undefined && encoder.description !== decoder.description) {\n // TODO: Coded error.\n throw new Error(\n `Encoder and decoder must have the same description, got [${encoder.description}] and [${decoder.description}]. ` +\n `Pass a custom description as a third argument if you want to override the description and bypass this error.`\n );\n }\n\n return {\n decode: decoder.decode,\n description: description ?? encoder.description,\n encode: encoder.encode,\n fixedSize: encoder.fixedSize,\n maxSize: encoder.maxSize,\n };\n}\n","/**\n * Asserts that a given number is between a given range.\n */\nexport function assertNumberIsBetweenForCodec(\n codecDescription: string,\n min: number | bigint,\n max: number | bigint,\n value: number | bigint\n) {\n if (value < min || value > max) {\n // TODO: Coded error.\n throw new Error(\n `Codec [${codecDescription}] expected number to be in the range [${min}, ${max}], got ${value}.`\n );\n }\n}\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecOptions } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getF32Encoder = (options: NumberCodecOptions = {}): Encoder<number> =>\n numberEncoderFactory({\n name: 'f32',\n options,\n set: (view, value, le) => view.setFloat32(0, value, le),\n size: 4,\n });\n\nexport const getF32Decoder = (options: NumberCodecOptions = {}): Decoder<number> =>\n numberDecoderFactory({\n get: (view, le) => view.getFloat32(0, le),\n name: 'f32',\n options,\n size: 4,\n });\n\nexport const getF32Codec = (options: NumberCodecOptions = {}): Codec<number> =>\n combineCodec(getF32Encoder(options), getF32Decoder(options));\n","import {\n assertByteArrayHasEnoughBytesForCodec,\n assertByteArrayIsNotEmptyForCodec,\n CodecData,\n Decoder,\n Encoder,\n} from '@solana/codecs-core';\n\nimport { assertNumberIsBetweenForCodec } from './assertions';\nimport { Endian, NumberCodecOptions, SingleByteNumberCodecOptions } from './common';\n\ntype NumberFactorySharedInput = {\n name: string;\n size: number;\n options: SingleByteNumberCodecOptions | NumberCodecOptions;\n};\n\ntype NumberFactoryEncoderInput<T> = NumberFactorySharedInput & {\n range?: [number | bigint, number | bigint];\n set: (view: DataView, value: T, littleEndian?: boolean) => void;\n};\n\ntype NumberFactoryDecoderInput<T> = NumberFactorySharedInput & {\n get: (view: DataView, littleEndian?: boolean) => T;\n};\n\nfunction sharedNumberFactory(input: NumberFactorySharedInput): CodecData & { littleEndian: boolean | undefined } {\n let littleEndian: boolean | undefined;\n let defaultDescription: string = input.name;\n\n if (input.size > 1) {\n littleEndian = !('endian' in input.options) || input.options.endian === Endian.LITTLE;\n defaultDescription += littleEndian ? '(le)' : '(be)';\n }\n\n return {\n description: input.options.description ?? defaultDescription,\n fixedSize: input.size,\n littleEndian,\n maxSize: input.size,\n };\n}\n\nexport function numberEncoderFactory<T extends number | bigint>(input: NumberFactoryEncoderInput<T>): Encoder<T> {\n const codecData = sharedNumberFactory(input);\n\n return {\n description: codecData.description,\n encode(value: T): Uint8Array {\n if (input.range) {\n assertNumberIsBetweenForCodec(input.name, input.range[0], input.range[1], value);\n }\n const arrayBuffer = new ArrayBuffer(input.size);\n input.set(new DataView(arrayBuffer), value, codecData.littleEndian);\n return new Uint8Array(arrayBuffer);\n },\n fixedSize: codecData.fixedSize,\n maxSize: codecData.maxSize,\n };\n}\n\nexport function numberDecoderFactory<T extends number | bigint>(input: NumberFactoryDecoderInput<T>): Decoder<T> {\n const codecData = sharedNumberFactory(input);\n\n return {\n decode(bytes, offset = 0): [T, number] {\n assertByteArrayIsNotEmptyForCodec(codecData.description, bytes, offset);\n assertByteArrayHasEnoughBytesForCodec(codecData.description, input.size, bytes, offset);\n const view = new DataView(toArrayBuffer(bytes, offset, input.size));\n return [input.get(view, codecData.littleEndian), offset + input.size];\n },\n description: codecData.description,\n fixedSize: codecData.fixedSize,\n maxSize: codecData.maxSize,\n };\n}\n\n/**\n * Helper function to ensure that the ArrayBuffer is converted properly from a Uint8Array\n * Source: https://stackoverflow.com/questions/37228285/uint8array-to-arraybuffer\n */\nfunction toArrayBuffer(bytes: Uint8Array, offset?: number, length?: number): ArrayBuffer {\n const bytesOffset = bytes.byteOffset + (offset ?? 0);\n const bytesLength = length ?? bytes.byteLength;\n return bytes.buffer.slice(bytesOffset, bytesOffset + bytesLength);\n}\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecOptions } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getU16Encoder = (options: NumberCodecOptions = {}): Encoder<number> =>\n numberEncoderFactory({\n name: 'u16',\n options,\n range: [0, Number('0xffff')],\n set: (view, value, le) => view.setUint16(0, value, le),\n size: 2,\n });\n\nexport const getU16Decoder = (options: NumberCodecOptions = {}): Decoder<number> =>\n numberDecoderFactory({\n get: (view, le) => view.getUint16(0, le),\n name: 'u16',\n options,\n size: 2,\n });\n\nexport const getU16Codec = (options: NumberCodecOptions = {}): Codec<number> =>\n combineCodec(getU16Encoder(options), getU16Decoder(options));\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecOptions } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getU32Encoder = (options: NumberCodecOptions = {}): Encoder<number> =>\n numberEncoderFactory({\n name: 'u32',\n options,\n range: [0, Number('0xffffffff')],\n set: (view, value, le) => view.setUint32(0, value, le),\n size: 4,\n });\n\nexport const getU32Decoder = (options: NumberCodecOptions = {}): Decoder<number> =>\n numberDecoderFactory({\n get: (view, le) => view.getUint32(0, le),\n name: 'u32',\n options,\n size: 4,\n });\n\nexport const getU32Codec = (options: NumberCodecOptions = {}): Codec<number> =>\n combineCodec(getU32Encoder(options), getU32Decoder(options));\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 {\n assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\n}\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","../../codecs-core/dist/index.browser.js","../../codecs-numbers/src/assertions.ts","../../codecs-numbers/src/f32.ts","../../codecs-numbers/src/utils.ts","../../codecs-numbers/src/u16.ts","../../codecs-numbers/src/u32.ts","../src/unwrap-option.ts","../src/option-codec.ts","../src/unwrap-option-recursively.ts"],"names":["_a","_b","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","// src/assertions.ts\nfunction assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset = 0) {\n if (bytes.length - offset <= 0) {\n throw new Error(`Codec [${codecDescription}] cannot decode empty byte arrays.`);\n }\n}\nfunction assertByteArrayHasEnoughBytesForCodec(codecDescription, expected, bytes, offset = 0) {\n const bytesLength = bytes.length - offset;\n if (bytesLength < expected) {\n throw new Error(`Codec [${codecDescription}] expected ${expected} bytes, got ${bytesLength}.`);\n }\n}\nfunction assertFixedSizeCodec(data, message) {\n if (data.fixedSize === null) {\n throw new Error(message ?? \"Expected a fixed-size codec, got a variable-size one.\");\n }\n}\n\n// src/bytes.ts\nvar mergeBytes = (byteArrays) => {\n const nonEmptyByteArrays = byteArrays.filter((arr) => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach((arr) => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\nvar padBytes = (bytes, length) => {\n if (bytes.length >= length)\n return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\nvar fixBytes = (bytes, length) => padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n\n// src/combine-codec.ts\nfunction combineCodec(encoder, decoder, description) {\n if (encoder.fixedSize !== decoder.fixedSize) {\n throw new Error(\n `Encoder and decoder must have the same fixed size, got [${encoder.fixedSize}] and [${decoder.fixedSize}].`\n );\n }\n if (encoder.maxSize !== decoder.maxSize) {\n throw new Error(\n `Encoder and decoder must have the same max size, got [${encoder.maxSize}] and [${decoder.maxSize}].`\n );\n }\n if (description === void 0 && encoder.description !== decoder.description) {\n throw new Error(\n `Encoder and decoder must have the same description, got [${encoder.description}] and [${decoder.description}]. Pass a custom description as a third argument if you want to override the description and bypass this error.`\n );\n }\n return {\n decode: decoder.decode,\n description: description ?? encoder.description,\n encode: encoder.encode,\n fixedSize: encoder.fixedSize,\n maxSize: encoder.maxSize\n };\n}\n\n// src/fix-codec.ts\nfunction fixCodecHelper(data, fixedBytes, description) {\n return {\n description: description ?? `fixed(${fixedBytes}, ${data.description})`,\n fixedSize: fixedBytes,\n maxSize: fixedBytes\n };\n}\nfunction fixEncoder(encoder, fixedBytes, description) {\n return {\n ...fixCodecHelper(encoder, fixedBytes, description),\n encode: (value) => fixBytes(encoder.encode(value), fixedBytes)\n };\n}\nfunction fixDecoder(decoder, fixedBytes, description) {\n return {\n ...fixCodecHelper(decoder, fixedBytes, description),\n decode: (bytes, offset = 0) => {\n assertByteArrayHasEnoughBytesForCodec(\"fixCodec\", fixedBytes, bytes, offset);\n if (offset > 0 || bytes.length > fixedBytes) {\n bytes = bytes.slice(offset, offset + fixedBytes);\n }\n if (decoder.fixedSize !== null) {\n bytes = fixBytes(bytes, decoder.fixedSize);\n }\n const [value] = decoder.decode(bytes, 0);\n return [value, offset + fixedBytes];\n }\n };\n}\nfunction fixCodec(codec, fixedBytes, description) {\n return combineCodec(fixEncoder(codec, fixedBytes, description), fixDecoder(codec, fixedBytes, description));\n}\n\n// src/map-codec.ts\nfunction mapEncoder(encoder, unmap) {\n return {\n description: encoder.description,\n encode: (value) => encoder.encode(unmap(value)),\n fixedSize: encoder.fixedSize,\n maxSize: encoder.maxSize\n };\n}\nfunction mapDecoder(decoder, map) {\n return {\n decode: (bytes, offset = 0) => {\n const [value, length] = decoder.decode(bytes, offset);\n return [map(value, bytes, offset), length];\n },\n description: decoder.description,\n fixedSize: decoder.fixedSize,\n maxSize: decoder.maxSize\n };\n}\nfunction mapCodec(codec, unmap, map) {\n return {\n decode: map ? mapDecoder(codec, map).decode : codec.decode,\n description: codec.description,\n encode: mapEncoder(codec, unmap).encode,\n fixedSize: codec.fixedSize,\n maxSize: codec.maxSize\n };\n}\n\n// src/reverse-codec.ts\nfunction reverseEncoder(encoder) {\n assertFixedSizeCodec(encoder, \"Cannot reverse a codec of variable size.\");\n return {\n ...encoder,\n encode: (value) => encoder.encode(value).reverse()\n };\n}\nfunction reverseDecoder(decoder) {\n assertFixedSizeCodec(decoder, \"Cannot reverse a codec of variable size.\");\n return {\n ...decoder,\n decode: (bytes, offset = 0) => {\n const reverseEnd = offset + decoder.fixedSize;\n if (offset === 0 && bytes.length === reverseEnd) {\n return decoder.decode(bytes.reverse(), offset);\n }\n const newBytes = mergeBytes([\n ...offset === 0 ? [] : [bytes.slice(0, offset)],\n bytes.slice(offset, reverseEnd).reverse(),\n ...bytes.length === reverseEnd ? [] : [bytes.slice(reverseEnd)]\n ]);\n return decoder.decode(newBytes, offset);\n }\n };\n}\nfunction reverseCodec(codec) {\n return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n\nexport { assertByteArrayHasEnoughBytesForCodec, assertByteArrayIsNotEmptyForCodec, assertFixedSizeCodec, combineCodec, fixBytes, fixCodec, fixDecoder, fixEncoder, mapCodec, mapDecoder, mapEncoder, mergeBytes, padBytes, reverseCodec, reverseDecoder, reverseEncoder };\n","/**\n * Asserts that a given number is between a given range.\n */\nexport function assertNumberIsBetweenForCodec(\n codecDescription: string,\n min: number | bigint,\n max: number | bigint,\n value: number | bigint,\n) {\n if (value < min || value > max) {\n // TODO: Coded error.\n throw new Error(\n `Codec [${codecDescription}] expected number to be in the range [${min}, ${max}], got ${value}.`,\n );\n }\n}\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getF32Encoder = (config: NumberCodecConfig = {}): Encoder<number> =>\n numberEncoderFactory({\n config,\n name: 'f32',\n set: (view, value, le) => view.setFloat32(0, value, le),\n size: 4,\n });\n\nexport const getF32Decoder = (config: NumberCodecConfig = {}): Decoder<number> =>\n numberDecoderFactory({\n config,\n get: (view, le) => view.getFloat32(0, le),\n name: 'f32',\n size: 4,\n });\n\nexport const getF32Codec = (config: NumberCodecConfig = {}): Codec<number> =>\n combineCodec(getF32Encoder(config), getF32Decoder(config));\n","import {\n assertByteArrayHasEnoughBytesForCodec,\n assertByteArrayIsNotEmptyForCodec,\n CodecData,\n Decoder,\n Encoder,\n} from '@solana/codecs-core';\n\nimport { assertNumberIsBetweenForCodec } from './assertions';\nimport { Endian, NumberCodecConfig, SingleByteNumberCodecConfig } from './common';\n\ntype NumberFactorySharedInput = {\n name: string;\n size: number;\n config: SingleByteNumberCodecConfig | NumberCodecConfig;\n};\n\ntype NumberFactoryEncoderInput<T> = NumberFactorySharedInput & {\n range?: [number | bigint, number | bigint];\n set: (view: DataView, value: T, littleEndian?: boolean) => void;\n};\n\ntype NumberFactoryDecoderInput<T> = NumberFactorySharedInput & {\n get: (view: DataView, littleEndian?: boolean) => T;\n};\n\nfunction sharedNumberFactory(input: NumberFactorySharedInput): CodecData & { littleEndian: boolean | undefined } {\n let littleEndian: boolean | undefined;\n let defaultDescription: string = input.name;\n\n if (input.size > 1) {\n littleEndian = !('endian' in input.config) || input.config.endian === Endian.LITTLE;\n defaultDescription += littleEndian ? '(le)' : '(be)';\n }\n\n return {\n description: input.config.description ?? defaultDescription,\n fixedSize: input.size,\n littleEndian,\n maxSize: input.size,\n };\n}\n\nexport function numberEncoderFactory<T extends number | bigint>(input: NumberFactoryEncoderInput<T>): Encoder<T> {\n const codecData = sharedNumberFactory(input);\n\n return {\n description: codecData.description,\n encode(value: T): Uint8Array {\n if (input.range) {\n assertNumberIsBetweenForCodec(input.name, input.range[0], input.range[1], value);\n }\n const arrayBuffer = new ArrayBuffer(input.size);\n input.set(new DataView(arrayBuffer), value, codecData.littleEndian);\n return new Uint8Array(arrayBuffer);\n },\n fixedSize: codecData.fixedSize,\n maxSize: codecData.maxSize,\n };\n}\n\nexport function numberDecoderFactory<T extends number | bigint>(input: NumberFactoryDecoderInput<T>): Decoder<T> {\n const codecData = sharedNumberFactory(input);\n\n return {\n decode(bytes, offset = 0): [T, number] {\n assertByteArrayIsNotEmptyForCodec(codecData.description, bytes, offset);\n assertByteArrayHasEnoughBytesForCodec(codecData.description, input.size, bytes, offset);\n const view = new DataView(toArrayBuffer(bytes, offset, input.size));\n return [input.get(view, codecData.littleEndian), offset + input.size];\n },\n description: codecData.description,\n fixedSize: codecData.fixedSize,\n maxSize: codecData.maxSize,\n };\n}\n\n/**\n * Helper function to ensure that the ArrayBuffer is converted properly from a Uint8Array\n * Source: https://stackoverflow.com/questions/37228285/uint8array-to-arraybuffer\n */\nfunction toArrayBuffer(bytes: Uint8Array, offset?: number, length?: number): ArrayBuffer {\n const bytesOffset = bytes.byteOffset + (offset ?? 0);\n const bytesLength = length ?? bytes.byteLength;\n return bytes.buffer.slice(bytesOffset, bytesOffset + bytesLength);\n}\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getU16Encoder = (config: NumberCodecConfig = {}): Encoder<number> =>\n numberEncoderFactory({\n config,\n name: 'u16',\n range: [0, Number('0xffff')],\n set: (view, value, le) => view.setUint16(0, value, le),\n size: 2,\n });\n\nexport const getU16Decoder = (config: NumberCodecConfig = {}): Decoder<number> =>\n numberDecoderFactory({\n config,\n get: (view, le) => view.getUint16(0, le),\n name: 'u16',\n size: 2,\n });\n\nexport const getU16Codec = (config: NumberCodecConfig = {}): Codec<number> =>\n combineCodec(getU16Encoder(config), getU16Decoder(config));\n","import { Codec, combineCodec, Decoder, Encoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\nexport const getU32Encoder = (config: NumberCodecConfig = {}): Encoder<number> =>\n numberEncoderFactory({\n config,\n name: 'u32',\n range: [0, Number('0xffffffff')],\n set: (view, value, le) => view.setUint32(0, value, le),\n size: 4,\n });\n\nexport const getU32Decoder = (config: NumberCodecConfig = {}): Decoder<number> =>\n numberDecoderFactory({\n config,\n get: (view, le) => view.getUint32(0, le),\n name: 'u32',\n size: 4,\n });\n\nexport const getU32Codec = (config: NumberCodecConfig = {}): Codec<number> =>\n combineCodec(getU32Encoder(config), getU32Decoder(config));\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 {\n assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\n}\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"]}
|
package/dist/index.native.js
CHANGED
|
@@ -35,11 +35,11 @@ function optionCodecHelper(item, prefix, fixed, description) {
|
|
|
35
35
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
function getOptionEncoder(item,
|
|
39
|
-
const prefix =
|
|
40
|
-
const fixed =
|
|
38
|
+
function getOptionEncoder(item, config = {}) {
|
|
39
|
+
const prefix = config.prefix ?? getU8Encoder();
|
|
40
|
+
const fixed = config.fixed ?? false;
|
|
41
41
|
return {
|
|
42
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
42
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
43
43
|
encode: (optionOrNullable) => {
|
|
44
44
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
45
45
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -49,11 +49,11 @@ function getOptionEncoder(item, options = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
function getOptionDecoder(item,
|
|
53
|
-
const prefix =
|
|
54
|
-
const fixed =
|
|
52
|
+
function getOptionDecoder(item, config = {}) {
|
|
53
|
+
const prefix = config.prefix ?? getU8Decoder();
|
|
54
|
+
const fixed = config.fixed ?? false;
|
|
55
55
|
return {
|
|
56
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
56
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
57
57
|
decode: (bytes, offset = 0) => {
|
|
58
58
|
if (bytes.length - offset <= 0) {
|
|
59
59
|
return [none(), offset];
|
|
@@ -70,8 +70,8 @@ function getOptionDecoder(item, options = {}) {
|
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
function getOptionCodec(item,
|
|
74
|
-
return combineCodec(getOptionEncoder(item,
|
|
73
|
+
function getOptionCodec(item, config = {}) {
|
|
74
|
+
return combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// src/unwrap-option-recursively.ts
|
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":"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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 assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\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> = 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 assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\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"]}
|
package/dist/index.node.cjs
CHANGED
|
@@ -37,11 +37,11 @@ function optionCodecHelper(item, prefix, fixed, description) {
|
|
|
37
37
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function getOptionEncoder(item,
|
|
41
|
-
const prefix =
|
|
42
|
-
const fixed =
|
|
40
|
+
function getOptionEncoder(item, config = {}) {
|
|
41
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Encoder();
|
|
42
|
+
const fixed = config.fixed ?? false;
|
|
43
43
|
return {
|
|
44
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
44
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
45
45
|
encode: (optionOrNullable) => {
|
|
46
46
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
47
47
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -51,11 +51,11 @@ function getOptionEncoder(item, options = {}) {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
function getOptionDecoder(item,
|
|
55
|
-
const prefix =
|
|
56
|
-
const fixed =
|
|
54
|
+
function getOptionDecoder(item, config = {}) {
|
|
55
|
+
const prefix = config.prefix ?? codecsNumbers.getU8Decoder();
|
|
56
|
+
const fixed = config.fixed ?? false;
|
|
57
57
|
return {
|
|
58
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
58
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
59
59
|
decode: (bytes, offset = 0) => {
|
|
60
60
|
if (bytes.length - offset <= 0) {
|
|
61
61
|
return [none(), offset];
|
|
@@ -72,8 +72,8 @@ function getOptionDecoder(item, options = {}) {
|
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
-
function getOptionCodec(item,
|
|
76
|
-
return codecsCore.combineCodec(getOptionEncoder(item,
|
|
75
|
+
function getOptionCodec(item, config = {}) {
|
|
76
|
+
return codecsCore.combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/unwrap-option-recursively.ts
|
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 assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\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> = 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 assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\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"]}
|
package/dist/index.node.js
CHANGED
|
@@ -35,11 +35,11 @@ function optionCodecHelper(item, prefix, fixed, description) {
|
|
|
35
35
|
maxSize: sumCodecSizes([prefix.maxSize, item.maxSize])
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
function getOptionEncoder(item,
|
|
39
|
-
const prefix =
|
|
40
|
-
const fixed =
|
|
38
|
+
function getOptionEncoder(item, config = {}) {
|
|
39
|
+
const prefix = config.prefix ?? getU8Encoder();
|
|
40
|
+
const fixed = config.fixed ?? false;
|
|
41
41
|
return {
|
|
42
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
42
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
43
43
|
encode: (optionOrNullable) => {
|
|
44
44
|
const option = isOption(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);
|
|
45
45
|
const prefixByte = prefix.encode(Number(isSome(option)));
|
|
@@ -49,11 +49,11 @@ function getOptionEncoder(item, options = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
function getOptionDecoder(item,
|
|
53
|
-
const prefix =
|
|
54
|
-
const fixed =
|
|
52
|
+
function getOptionDecoder(item, config = {}) {
|
|
53
|
+
const prefix = config.prefix ?? getU8Decoder();
|
|
54
|
+
const fixed = config.fixed ?? false;
|
|
55
55
|
return {
|
|
56
|
-
...optionCodecHelper(item, prefix, fixed,
|
|
56
|
+
...optionCodecHelper(item, prefix, fixed, config.description),
|
|
57
57
|
decode: (bytes, offset = 0) => {
|
|
58
58
|
if (bytes.length - offset <= 0) {
|
|
59
59
|
return [none(), offset];
|
|
@@ -70,8 +70,8 @@ function getOptionDecoder(item, options = {}) {
|
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
-
function getOptionCodec(item,
|
|
74
|
-
return combineCodec(getOptionEncoder(item,
|
|
73
|
+
function getOptionCodec(item, config = {}) {
|
|
74
|
+
return combineCodec(getOptionEncoder(item, config), getOptionDecoder(item, config));
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// src/unwrap-option-recursively.ts
|
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 assertFixedSizeCodec,\n BaseCodecOptions,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { isOption, isSome, none, Option, OptionOrNullable, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/** Defines the options for option codecs. */\nexport type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecOptions & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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 options - A set of options for the encoder.\n */\nexport function getOptionEncoder<T>(\n item: Encoder<T>,\n options: OptionCodecOptions<NumberEncoder> = {}\n): Encoder<OptionOrNullable<T>> {\n const prefix = options.prefix ?? getU8Encoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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 options - A set of options for the decoder.\n */\nexport function getOptionDecoder<T>(\n item: Decoder<T>,\n options: OptionCodecOptions<NumberDecoder> = {}\n): Decoder<Option<T>> {\n const prefix = options.prefix ?? getU8Decoder();\n const fixed = options.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, options.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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 options - A set of options for the codec.\n */\nexport function getOptionCodec<T, U extends T = T>(\n item: Codec<T, U>,\n options: OptionCodecOptions<NumberCodec> = {}\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, options), getOptionDecoder<U>(item, options));\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> = 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 assertFixedSizeCodec,\n BaseCodecConfig,\n Codec,\n CodecData,\n combineCodec,\n Decoder,\n Encoder,\n fixBytes,\n mergeBytes,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } 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> = BaseCodecConfig & {\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\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 optionCodecHelper(item: CodecData, prefix: CodecData, fixed: boolean, description?: string): CodecData {\n let descriptionSuffix = `; ${prefix.description}`;\n let fixedSize = item.fixedSize === 0 ? prefix.fixedSize : null;\n if (fixed) {\n assertFixedSizeCodec(item, 'Fixed options can only be used with fixed-size codecs.');\n assertFixedSizeCodec(prefix, 'Fixed options can only be used with fixed-size prefix.');\n descriptionSuffix += '; fixed';\n fixedSize = prefix.fixedSize + item.fixedSize;\n }\n\n return {\n description: description ?? `option(${item.description + descriptionSuffix})`,\n fixedSize,\n maxSize: sumCodecSizes([prefix.maxSize, item.maxSize]),\n };\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<T>(\n item: Encoder<T>,\n config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<T>> {\n const prefix = config.prefix ?? getU8Encoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n encode: (optionOrNullable: OptionOrNullable<T>) => {\n const option = isOption<T>(optionOrNullable) ? optionOrNullable : wrapNullable(optionOrNullable);\n const prefixByte = prefix.encode(Number(isSome(option)));\n let itemBytes = isSome(option) ? item.encode(option.value) : new Uint8Array();\n itemBytes = fixed ? fixBytes(itemBytes, item.fixedSize as number) : itemBytes;\n return mergeBytes([prefixByte, itemBytes]);\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<T>(\n item: Decoder<T>,\n config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<T>> {\n const prefix = config.prefix ?? getU8Decoder();\n const fixed = config.fixed ?? false;\n return {\n ...optionCodecHelper(item, prefix, fixed, config.description),\n decode: (bytes: Uint8Array, offset = 0) => {\n if (bytes.length - offset <= 0) {\n return [none(), offset];\n }\n const fixedOffset = offset + (prefix.fixedSize ?? 0) + (item.fixedSize ?? 0);\n const [isSome, prefixOffset] = prefix.decode(bytes, offset);\n offset = prefixOffset;\n if (isSome === 0) {\n return [none(), fixed ? fixedOffset : offset];\n }\n const [value, newOffset] = item.decode(bytes, offset);\n offset = newOffset;\n return [some(value), fixed ? fixedOffset : offset];\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<T, U extends T = T>(\n item: Codec<T, U>,\n config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<T>, Option<U>> {\n return combineCodec(getOptionEncoder<T>(item, config), getOptionDecoder<U>(item, config));\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"]}
|
|
@@ -2,19 +2,19 @@ this.globalThis = this.globalThis || {};
|
|
|
2
2
|
this.globalThis.solanaWeb3 = (function (exports) {
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var x=e=>({__option:"Some",value:e}),p=()=>({__option:"None"}),g=e=>!!(e&&typeof e=="object"&&"__option"in e&&(e.__option==="Some"&&"value"in e||e.__option==="None")),d=e=>e.__option==="Some",R=e=>e.__option==="None";function T(e,n,t=0){if(n.length-t<=0)throw new Error(`Codec [${e}] cannot decode empty byte arrays.`)}function S(e,n,t,r=0){let o=t.length-r;if(o<n)throw new Error(`Codec [${e}] expected ${n} bytes, got ${o}.`)}function m(e,n){if(e.fixedSize===null)throw new Error(n!=null?n:"Expected a fixed-size codec, got a variable-size one.")}var O=e=>{let n=e.filter(i=>i.length);if(n.length===0)return e.length?e[0]:new Uint8Array;if(n.length===1)return n[0];let t=n.reduce((i,a)=>i+a.length,0),r=new Uint8Array(t),o=0;return n.forEach(i=>{r.set(i,o),o+=i.length;}),r},D=(e,n)=>{if(e.length>=n)return e;let t=new Uint8Array(n).fill(0);return t.set(e),t},v=(e,n)=>D(e.length<=n?e:e.slice(0,n),n);function l(e,n,t){if(e.fixedSize!==n.fixedSize)throw new Error(`Encoder and decoder must have the same fixed size, got [${e.fixedSize}] and [${n.fixedSize}].`);if(e.maxSize!==n.maxSize)throw new Error(`Encoder and decoder must have the same max size, got [${e.maxSize}] and [${n.maxSize}].`);if(t===void 0&&e.description!==n.description)throw new Error(`Encoder and decoder must have the same description, got [${e.description}] and [${n.description}]. Pass a custom description as a third argument if you want to override the description and bypass this error.`);return {decode:n.decode,description:t!=null?t:e.description,encode:e.encode,fixedSize:e.fixedSize,maxSize:e.maxSize}}function A(e,n,t,r){if(r<n||r>t)throw new Error(`Codec [${e}] expected number to be in the range [${n}, ${t}], got ${r}.`)}function C(e){var r;let n,t=e.name;return e.size>1&&(n=!("endian"in e.config)||e.config.endian===0,t+=n?"(le)":"(be)"),{description:(r=e.config.description)!=null?r:t,fixedSize:e.size,littleEndian:n,maxSize:e.size}}function _(e){let n=C(e);return {description:n.description,encode(t){e.range&&A(e.name,e.range[0],e.range[1],t);let r=new ArrayBuffer(e.size);return e.set(new DataView(r),t,n.littleEndian),new Uint8Array(r)},fixedSize:n.fixedSize,maxSize:n.maxSize}}function F(e){let n=C(e);return {decode(t,r=0){T(n.description,t,r),S(n.description,e.size,t,r);let o=new DataView($(t,r,e.size));return [e.get(o,n.littleEndian),r+e.size]},description:n.description,fixedSize:n.fixedSize,maxSize:n.maxSize}}function $(e,n,t){let r=e.byteOffset+(n!=null?n:0),o=t!=null?t:e.byteLength;return e.buffer.slice(r,r+o)}var w=(e={})=>_({config:e,name:"u8",range:[0,+"0xff"],set:(n,t)=>n.setUint8(0,t),size:1}),h=(e={})=>F({config:e,get:n=>n.getUint8(0),name:"u8",size:1});function W(e,n){return d(e)?e.value:n?n():null}var y=e=>e!==null?x(e):p();function L(e){return e.reduce((n,t)=>n===null||t===null?null:n+t,0)}function I(e,n,t,r){let o=`; ${n.description}`,i=e.fixedSize===0?n.fixedSize:null;return t&&(m(e,"Fixed options can only be used with fixed-size codecs."),m(n,"Fixed options can only be used with fixed-size prefix."),o+="; fixed",i=n.fixedSize+e.fixedSize),{description:r!=null?r:`option(${e.description+o})`,fixedSize:i,maxSize:L([n.maxSize,e.maxSize])}}function V(e,n={}){var o,i;let t=(o=n.prefix)!=null?o:w(),r=(i=n.fixed)!=null?i:!1;return {...I(e,t,r,n.description),encode:a=>{let f=g(a)?a:y(a),u=t.encode(Number(d(f))),c=d(f)?e.encode(f.value):new Uint8Array;return c=r?v(c,e.fixedSize):c,O([u,c])}}}function k(e,n={}){var o,i;let t=(o=n.prefix)!=null?o:h(),r=(i=n.fixed)!=null?i:!1;return {...I(e,t,r,n.description),decode:(a,f=0)=>{var z,U;if(a.length-f<=0)return [p(),f];let u=f+((z=t.fixedSize)!=null?z:0)+((U=e.fixedSize)!=null?U:0),[c,B]=t.decode(a,f);if(f=B,c===0)return [p(),r?u:f];let[b,N]=e.decode(a,f);return f=N,[x(b),r?u:f]}}}function ge(e,n={}){return l(V(e,n),k(e,n))}function E(e,n){if(!e||ArrayBuffer.isView(e))return e;let t=r=>n?E(r,n):E(r);return g(e)?d(e)?t(e.value):n?n():null:Array.isArray(e)?e.map(t):typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,o])=>[r,t(o)])):e}
|
|
6
6
|
|
|
7
|
-
exports.getOptionCodec =
|
|
8
|
-
exports.getOptionDecoder =
|
|
9
|
-
exports.getOptionEncoder =
|
|
10
|
-
exports.isNone =
|
|
11
|
-
exports.isOption =
|
|
12
|
-
exports.isSome =
|
|
13
|
-
exports.none =
|
|
14
|
-
exports.some =
|
|
15
|
-
exports.unwrapOption =
|
|
16
|
-
exports.unwrapOptionRecursively =
|
|
17
|
-
exports.wrapNullable =
|
|
7
|
+
exports.getOptionCodec = ge;
|
|
8
|
+
exports.getOptionDecoder = k;
|
|
9
|
+
exports.getOptionEncoder = V;
|
|
10
|
+
exports.isNone = R;
|
|
11
|
+
exports.isOption = g;
|
|
12
|
+
exports.isSome = d;
|
|
13
|
+
exports.none = p;
|
|
14
|
+
exports.some = x;
|
|
15
|
+
exports.unwrapOption = W;
|
|
16
|
+
exports.unwrapOptionRecursively = E;
|
|
17
|
+
exports.wrapNullable = y;
|
|
18
18
|
|
|
19
19
|
return exports;
|
|
20
20
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseCodecConfig, Codec, Decoder, Encoder } from '@solana/codecs-core';
|
|
2
2
|
import { NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';
|
|
3
3
|
import { Option, OptionOrNullable } from './option';
|
|
4
|
-
/** Defines the
|
|
5
|
-
export type
|
|
4
|
+
/** Defines the config for option codecs. */
|
|
5
|
+
export type OptionCodecConfig<TPrefix extends NumberCodec | NumberEncoder | NumberDecoder> = BaseCodecConfig & {
|
|
6
6
|
/**
|
|
7
7
|
* The codec to use for the boolean prefix.
|
|
8
8
|
* @defaultValue u8 prefix.
|
|
@@ -22,21 +22,21 @@ export type OptionCodecOptions<TPrefix extends NumberCodec | NumberEncoder | Num
|
|
|
22
22
|
* Creates a encoder for an optional value using `null` as the `None` value.
|
|
23
23
|
*
|
|
24
24
|
* @param item - The encoder to use for the value that may be present.
|
|
25
|
-
* @param
|
|
25
|
+
* @param config - A set of config for the encoder.
|
|
26
26
|
*/
|
|
27
|
-
export declare function getOptionEncoder<T>(item: Encoder<T>,
|
|
27
|
+
export declare function getOptionEncoder<T>(item: Encoder<T>, config?: OptionCodecConfig<NumberEncoder>): Encoder<OptionOrNullable<T>>;
|
|
28
28
|
/**
|
|
29
29
|
* Creates a decoder for an optional value using `null` as the `None` value.
|
|
30
30
|
*
|
|
31
31
|
* @param item - The decoder to use for the value that may be present.
|
|
32
|
-
* @param
|
|
32
|
+
* @param config - A set of config for the decoder.
|
|
33
33
|
*/
|
|
34
|
-
export declare function getOptionDecoder<T>(item: Decoder<T>,
|
|
34
|
+
export declare function getOptionDecoder<T>(item: Decoder<T>, config?: OptionCodecConfig<NumberDecoder>): Decoder<Option<T>>;
|
|
35
35
|
/**
|
|
36
36
|
* Creates a codec for an optional value using `null` as the `None` value.
|
|
37
37
|
*
|
|
38
38
|
* @param item - The codec to use for the value that may be present.
|
|
39
|
-
* @param
|
|
39
|
+
* @param config - A set of config for the codec.
|
|
40
40
|
*/
|
|
41
|
-
export declare function getOptionCodec<T, U extends T = T>(item: Codec<T, U>,
|
|
41
|
+
export declare function getOptionCodec<T, U extends T = T>(item: Codec<T, U>, config?: OptionCodecConfig<NumberCodec>): Codec<OptionOrNullable<T>, Option<U>>;
|
|
42
42
|
//# sourceMappingURL=option-codec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-codec.d.ts","sourceRoot":"","sources":["../../src/option-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,
|
|
1
|
+
{"version":3,"file":"option-codec.d.ts","sourceRoot":"","sources":["../../src/option-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,eAAe,EACf,KAAK,EAGL,OAAO,EACP,OAAO,EAGV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAA8B,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE/G,OAAO,EAA0B,MAAM,EAAE,gBAAgB,EAAQ,MAAM,UAAU,CAAC;AAGlF,4CAA4C;AAC5C,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,WAAW,GAAG,aAAa,GAAG,aAAa,IAAI,eAAe,GAAG;IAC3G;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAuBF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAC9B,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,MAAM,GAAE,iBAAiB,CAAC,aAAa,CAAM,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAa9B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAC9B,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,MAAM,GAAE,iBAAiB,CAAC,aAAa,CAAM,GAC9C,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAoBpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAC7C,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EACjB,MAAM,GAAE,iBAAiB,CAAC,WAAW,CAAM,GAC5C,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAEvC"}
|
|
@@ -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,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,IAAI,GACJ,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,IAAI,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,MAAM,CAAC,GACjE,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,GAC1B,CAAC,SAAS,IAAI,
|
|
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,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,GACT,IAAI,GACJ,UAAU,GACV,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,IAAI,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,MAAM,CAAC,GACjE,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;AAEhB;;;;;;;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.c156b67",
|
|
4
4
|
"description": "Managing and serializing Rust-like Option types in JavaScript",
|
|
5
5
|
"exports": {
|
|
6
6
|
"browser": {
|
|
@@ -49,25 +49,25 @@
|
|
|
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.c156b67",
|
|
53
|
+
"@solana/codecs-numbers": "2.0.0-experimental.c156b67"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@solana/eslint-config-solana": "^1.0.2",
|
|
57
|
-
"@swc/jest": "^0.2.
|
|
58
|
-
"@types/jest": "^29.5.
|
|
57
|
+
"@swc/jest": "^0.2.29",
|
|
58
|
+
"@types/jest": "^29.5.6",
|
|
59
59
|
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
|
60
60
|
"@typescript-eslint/parser": "^6.3.0",
|
|
61
61
|
"agadoo": "^3.0.0",
|
|
62
62
|
"eslint": "^8.45.0",
|
|
63
|
-
"eslint-plugin-jest": "^27.2
|
|
63
|
+
"eslint-plugin-jest": "^27.4.2",
|
|
64
64
|
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
65
65
|
"jest": "^29.7.0",
|
|
66
|
-
"jest-environment-jsdom": "^29.
|
|
67
|
-
"jest-runner-eslint": "^2.1.
|
|
66
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
67
|
+
"jest-runner-eslint": "^2.1.2",
|
|
68
68
|
"jest-runner-prettier": "^1.0.0",
|
|
69
|
-
"prettier": "^
|
|
70
|
-
"tsup": "
|
|
69
|
+
"prettier": "^3.1",
|
|
70
|
+
"tsup": "^8.0.1",
|
|
71
71
|
"typescript": "^5.2.2",
|
|
72
72
|
"version-from-git": "^1.1.1",
|
|
73
73
|
"build-scripts": "0.0.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"compile:typedefs": "tsc -p ./tsconfig.declarations.json",
|
|
88
88
|
"dev": "jest -c node_modules/test-config/jest-dev.config.ts --rootDir . --watch",
|
|
89
89
|
"publish-packages": "pnpm publish --tag experimental --access public --no-git-checks",
|
|
90
|
-
"style:fix": "pnpm eslint --fix src/* && pnpm prettier -w src/*",
|
|
90
|
+
"style:fix": "pnpm eslint --fix src/* && pnpm prettier -w src/* package.json",
|
|
91
91
|
"test:lint": "jest -c node_modules/test-config/jest-lint.config.ts --rootDir . --silent",
|
|
92
92
|
"test:prettier": "jest -c node_modules/test-config/jest-prettier.config.ts --rootDir . --silent",
|
|
93
93
|
"test:treeshakability:browser": "agadoo dist/index.browser.js",
|