From fad27871255cf88f1519b1a4f507596a53aa36ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:33:06 +0000 Subject: [PATCH 01/12] Initial plan From 7b8bc55a0fb622bf48dc18dc2d6abd240aabd253 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:36:18 +0000 Subject: [PATCH 02/12] Add TypeScript types for single-byte.js Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- package.json | 2 ++ single-byte.d.ts | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 single-byte.d.ts diff --git a/package.json b/package.json index 17e3bdd..bcb87dd 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ "/multi-byte.js", "/multi-byte.node.js", "/single-byte.js", + "/single-byte.d.ts", "/single-byte.node.js", "/utf16.js", "/utf16.node.js", @@ -155,6 +156,7 @@ "default": "./multi-byte.js" }, "./single-byte.js": { + "types": "./single-byte.d.ts", "node": "./single-byte.node.js", "default": "./single-byte.js" }, diff --git a/single-byte.d.ts b/single-byte.d.ts new file mode 100644 index 0000000..7fde4e3 --- /dev/null +++ b/single-byte.d.ts @@ -0,0 +1,88 @@ +/** + * Single-byte encoding/decoding + * + * ```js + * import { createSinglebyteDecoder, createSinglebyteEncoder } from '@exodus/bytes/single-byte.js' + * import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js' + * import { windows1252toString, windows1252fromString } from '@exodus/bytes/single-byte.js' + * ``` + * + * Supports various single-byte character encodings like ISO-8859-* and Windows-125*. + * + * @module @exodus/bytes/single-byte.js + */ + +/// + +import type { Uint8ArrayBuffer } from './array.js'; + +/** + * Options for single-byte encoding + */ +export interface SinglebyteEncoderOptions { + /** + * Encoding mode + * - `'fatal'`: throw an error on unmapped characters (default) + */ + mode?: 'fatal'; +} + +/** + * Create a decoder function for a single-byte character encoding + * + * @param encoding - The encoding name (e.g., 'iso-8859-1', 'windows-1252') + * @param loose - If true, replaces unmapped bytes with replacement character instead of throwing (default: false) + * @returns A function that decodes bytes to string + */ +export function createSinglebyteDecoder( + encoding: string, + loose?: boolean +): (arr: Uint8ArrayBuffer) => string; + +/** + * Create an encoder function for a single-byte character encoding + * + * @param encoding - The encoding name (e.g., 'iso-8859-1', 'windows-1252') + * @param options - Encoding options + * @returns A function that encodes string to bytes + */ +export function createSinglebyteEncoder( + encoding: string, + options?: SinglebyteEncoderOptions +): (string: string) => Uint8ArrayBuffer; + +/** + * Decode ISO-8859-1 (Latin-1) bytes to a string + * + * @param arr - The bytes to decode + * @returns The decoded string + */ +export const latin1toString: (arr: Uint8ArrayBuffer) => string; + +/** + * Encode a string to ISO-8859-1 (Latin-1) bytes + * + * Throws on characters that cannot be encoded in Latin-1 + * + * @param string - The string to encode + * @returns The encoded bytes + */ +export const latin1fromString: (string: string) => Uint8ArrayBuffer; + +/** + * Decode Windows-1252 bytes to a string + * + * @param arr - The bytes to decode + * @returns The decoded string + */ +export const windows1252toString: (arr: Uint8ArrayBuffer) => string; + +/** + * Encode a string to Windows-1252 bytes + * + * Throws on characters that cannot be encoded in Windows-1252 + * + * @param string - The string to encode + * @returns The encoded bytes + */ +export const windows1252fromString: (string: string) => Uint8ArrayBuffer; From 33e2f20a7c3b2833a71c8e8db8ac35d709abe3e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:37:38 +0000 Subject: [PATCH 03/12] Improve documentation for SinglebyteEncoderOptions Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index 7fde4e3..08da2c7 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -21,8 +21,10 @@ import type { Uint8ArrayBuffer } from './array.js'; */ export interface SinglebyteEncoderOptions { /** - * Encoding mode - * - `'fatal'`: throw an error on unmapped characters (default) + * Encoding mode (default: 'fatal') + * - `'fatal'`: throw an error on unmapped characters + * + * Note: Currently, only 'fatal' mode is supported. Other modes will throw an error. */ mode?: 'fatal'; } From 6c8157b23aec989b441575b926cbf2b34ae77a44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:48:46 +0000 Subject: [PATCH 04/12] Match single-byte.d.ts header to README.md documentation Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index 08da2c7..d541034 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -1,13 +1,32 @@ /** - * Single-byte encoding/decoding - * * ```js * import { createSinglebyteDecoder, createSinglebyteEncoder } from '@exodus/bytes/single-byte.js' - * import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js' * import { windows1252toString, windows1252fromString } from '@exodus/bytes/single-byte.js' + * import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js' * ``` * - * Supports various single-byte character encodings like ISO-8859-* and Windows-125*. + * Decode / encode the legacy single-byte encodings according to the + * [Encoding standard](https://encoding.spec.whatwg.org/) + * ([§9](https://encoding.spec.whatwg.org/#legacy-single-byte-encodings), + * [§14.5](https://encoding.spec.whatwg.org/#x-user-defined)), + * and [unicode.org](https://unicode.org/Public/MAPPINGS/ISO8859) `iso-8859-*` mappings. + * + * Supports all single-byte encodings listed in the WHATWG Encoding standard: + * `ibm866`, `iso-8859-2`, `iso-8859-3`, `iso-8859-4`, `iso-8859-5`, `iso-8859-6`, `iso-8859-7`, `iso-8859-8`, + * `iso-8859-8-i`, `iso-8859-10`, `iso-8859-13`, `iso-8859-14`, `iso-8859-15`, `iso-8859-16`, `koi8-r`, `koi8-u`, + * `macintosh`, `windows-874`, `windows-1250`, `windows-1251`, `windows-1252`, `windows-1253`, `windows-1254`, + * `windows-1255`, `windows-1256`, `windows-1257`, `windows-1258`, `x-mac-cyrillic` and `x-user-defined`. + * + * Also supports `iso-8859-1`, `iso-8859-9`, `iso-8859-11` as defined at + * [unicode.org](https://unicode.org/Public/MAPPINGS/ISO8859) + * (and all other `iso-8859-*` encodings there as they match WHATWG). + * + * > [!NOTE] + * > While all `iso-8859-*` encodings supported by the [WHATWG Encoding standard](https://encoding.spec.whatwg.org/) match + * > [unicode.org](https://unicode.org/Public/MAPPINGS/ISO8859), the WHATWG Encoding spec doesn't support + * > `iso-8859-1`, `iso-8859-9`, `iso-8859-11`, and instead maps them as labels to `windows-1252`, `windows-1254`, `windows-874`.\ + * > `createSinglebyteDecoder()` (unlike `TextDecoder` or `legacyHookDecode()`) does not do such mapping, + * > so its results will differ from `TextDecoder` for those encoding names. * * @module @exodus/bytes/single-byte.js */ From f06374fb5dbd2ddaef02de63f8d0c14848b0da02 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:53:22 +0000 Subject: [PATCH 05/12] Fix header order to match main branch README Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index d541034..a654920 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -1,16 +1,16 @@ /** - * ```js - * import { createSinglebyteDecoder, createSinglebyteEncoder } from '@exodus/bytes/single-byte.js' - * import { windows1252toString, windows1252fromString } from '@exodus/bytes/single-byte.js' - * import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js' - * ``` - * * Decode / encode the legacy single-byte encodings according to the * [Encoding standard](https://encoding.spec.whatwg.org/) * ([§9](https://encoding.spec.whatwg.org/#legacy-single-byte-encodings), * [§14.5](https://encoding.spec.whatwg.org/#x-user-defined)), * and [unicode.org](https://unicode.org/Public/MAPPINGS/ISO8859) `iso-8859-*` mappings. * + * ```js + * import { createSinglebyteDecoder, createSinglebyteEncoder } from '@exodus/bytes/single-byte.js' + * import { windows1252toString, windows1252fromString } from '@exodus/bytes/single-byte.js' + * import { latin1toString, latin1fromString } from '@exodus/bytes/single-byte.js' + * ``` + * * Supports all single-byte encodings listed in the WHATWG Encoding standard: * `ibm866`, `iso-8859-2`, `iso-8859-3`, `iso-8859-4`, `iso-8859-5`, `iso-8859-6`, `iso-8859-7`, `iso-8859-8`, * `iso-8859-8-i`, `iso-8859-10`, `iso-8859-13`, `iso-8859-14`, `iso-8859-15`, `iso-8859-16`, `koi8-r`, `koi8-u`, From 7b671918ca67500f4015c2ab057c2aeb8f65a0c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:33:06 +0000 Subject: [PATCH 06/12] Initial plan From 3d003009dedb9e38b90460697c1337d27378ee34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 08:58:19 +0000 Subject: [PATCH 07/12] Use method docs from README.md for all functions Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 50 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index a654920..451b443 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -49,7 +49,9 @@ export interface SinglebyteEncoderOptions { } /** - * Create a decoder function for a single-byte character encoding + * Create a decoder for a supported one-byte `encoding`, given its lowercased name `encoding`. + * + * Returns a function `decode(arr)` that decodes bytes to a string. * * @param encoding - The encoding name (e.g., 'iso-8859-1', 'windows-1252') * @param loose - If true, replaces unmapped bytes with replacement character instead of throwing (default: false) @@ -61,7 +63,12 @@ export function createSinglebyteDecoder( ): (arr: Uint8ArrayBuffer) => string; /** - * Create an encoder function for a single-byte character encoding + * Create an encoder for a supported one-byte `encoding`, given its lowercased name `encoding`. + * + * Returns a function `encode(string)` that encodes a string to bytes. + * + * In `'fatal'` mode (default), will throw on non well-formed strings or any codepoints which could + * not be encoded in the target encoding. * * @param encoding - The encoding name (e.g., 'iso-8859-1', 'windows-1252') * @param options - Encoding options @@ -73,7 +80,17 @@ export function createSinglebyteEncoder( ): (string: string) => Uint8ArrayBuffer; /** - * Decode ISO-8859-1 (Latin-1) bytes to a string + * Decode `iso-8859-1` bytes to a string. + * + * There is no loose variant for this encoding, all bytes can be decoded. + * + * Same as: + * ```js + * const latin1toString = createSinglebyteDecoder('iso-8859-1') + * ``` + * + * Note: this is different from `new TextDecoder('iso-8859-1')` and `new TextDecoder('latin1')`, as + * those alias to `new TextDecoder('windows-1252')`. * * @param arr - The bytes to decode * @returns The decoded string @@ -81,9 +98,14 @@ export function createSinglebyteEncoder( export const latin1toString: (arr: Uint8ArrayBuffer) => string; /** - * Encode a string to ISO-8859-1 (Latin-1) bytes + * Encode a string to `iso-8859-1` bytes. + * + * Will throw on non well-formed strings or any codepoints which could not be encoded in `iso-8859-1`. * - * Throws on characters that cannot be encoded in Latin-1 + * Same as: + * ```js + * const latin1fromString = createSinglebyteEncoder('iso-8859-1', { mode: 'fatal' }) + * ``` * * @param string - The string to encode * @returns The encoded bytes @@ -91,7 +113,14 @@ export const latin1toString: (arr: Uint8ArrayBuffer) => string; export const latin1fromString: (string: string) => Uint8ArrayBuffer; /** - * Decode Windows-1252 bytes to a string + * Decode `windows-1252` bytes to a string. + * + * There is no loose variant for this encoding, all bytes can be decoded. + * + * Same as: + * ```js + * const windows1252toString = createSinglebyteDecoder('windows-1252') + * ``` * * @param arr - The bytes to decode * @returns The decoded string @@ -99,9 +128,14 @@ export const latin1fromString: (string: string) => Uint8ArrayBuffer; export const windows1252toString: (arr: Uint8ArrayBuffer) => string; /** - * Encode a string to Windows-1252 bytes + * Encode a string to `windows-1252` bytes. + * + * Will throw on non well-formed strings or any codepoints which could not be encoded in `windows-1252`. * - * Throws on characters that cannot be encoded in Windows-1252 + * Same as: + * ```js + * const windows1252fromString = createSinglebyteEncoder('windows-1252', { mode: 'fatal' }) + * ``` * * @param string - The string to encode * @returns The encoded bytes From 44245995c9d69e90920bab7e05de01bb2cc30a8d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:02:28 +0000 Subject: [PATCH 08/12] Replace "Will throw" with "Throws" in docs Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- README.md | 4 ++-- single-byte.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4fd7bde..972f3c6 100644 --- a/README.md +++ b/README.md @@ -244,7 +244,7 @@ those alias to `new TextDecoder('windows-1252')`. Encode a string to `iso-8859-1` bytes. -Will throw on non well-formed strings or any codepoints which could not be encoded in `iso-8859-1`. +Throws on non well-formed strings or any codepoints which could not be encoded in `iso-8859-1`. Same as: ```js @@ -266,7 +266,7 @@ const windows1252toString = createSinglebyteDecoder('windows-1252') Encode a string to `windows-1252` bytes. -Will throw on non well-formed strings or any codepoints which could not be encoded in `windows-1252`. +Throws on non well-formed strings or any codepoints which could not be encoded in `windows-1252`. Same as: ```js diff --git a/single-byte.d.ts b/single-byte.d.ts index 451b443..00a3450 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -100,7 +100,7 @@ export const latin1toString: (arr: Uint8ArrayBuffer) => string; /** * Encode a string to `iso-8859-1` bytes. * - * Will throw on non well-formed strings or any codepoints which could not be encoded in `iso-8859-1`. + * Throws on non well-formed strings or any codepoints which could not be encoded in `iso-8859-1`. * * Same as: * ```js @@ -130,7 +130,7 @@ export const windows1252toString: (arr: Uint8ArrayBuffer) => string; /** * Encode a string to `windows-1252` bytes. * - * Will throw on non well-formed strings or any codepoints which could not be encoded in `windows-1252`. + * Throws on non well-formed strings or any codepoints which could not be encoded in `windows-1252`. * * Same as: * ```js From 2d96ea96d1a360314c1a4890f1d5ae06b30e468f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:49:09 +0000 Subject: [PATCH 09/12] Inline SinglebyteEncoderOptions as it's only used once Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index 00a3450..c975c9b 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -35,19 +35,6 @@ import type { Uint8ArrayBuffer } from './array.js'; -/** - * Options for single-byte encoding - */ -export interface SinglebyteEncoderOptions { - /** - * Encoding mode (default: 'fatal') - * - `'fatal'`: throw an error on unmapped characters - * - * Note: Currently, only 'fatal' mode is supported. Other modes will throw an error. - */ - mode?: 'fatal'; -} - /** * Create a decoder for a supported one-byte `encoding`, given its lowercased name `encoding`. * @@ -76,7 +63,7 @@ export function createSinglebyteDecoder( */ export function createSinglebyteEncoder( encoding: string, - options?: SinglebyteEncoderOptions + options?: { mode?: 'fatal' } ): (string: string) => Uint8ArrayBuffer; /** From 78fd259d2bcac5f65db353afa04ddb19605de2b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:57:33 +0000 Subject: [PATCH 10/12] Document options.mode property in JSDoc Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/single-byte.d.ts b/single-byte.d.ts index c975c9b..f85cdc8 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -59,6 +59,7 @@ export function createSinglebyteDecoder( * * @param encoding - The encoding name (e.g., 'iso-8859-1', 'windows-1252') * @param options - Encoding options + * @param options.mode - Encoding mode (default: 'fatal'). Currently, only 'fatal' mode is supported. * @returns A function that encodes string to bytes */ export function createSinglebyteEncoder( From 6985240cc39b9cc419331461e4feed2f3a263862 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:11:08 +0000 Subject: [PATCH 11/12] Change convenience functions from const to function declarations Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/single-byte.d.ts b/single-byte.d.ts index f85cdc8..372b38e 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -83,7 +83,7 @@ export function createSinglebyteEncoder( * @param arr - The bytes to decode * @returns The decoded string */ -export const latin1toString: (arr: Uint8ArrayBuffer) => string; +export function latin1toString(arr: Uint8ArrayBuffer): string; /** * Encode a string to `iso-8859-1` bytes. @@ -98,7 +98,7 @@ export const latin1toString: (arr: Uint8ArrayBuffer) => string; * @param string - The string to encode * @returns The encoded bytes */ -export const latin1fromString: (string: string) => Uint8ArrayBuffer; +export function latin1fromString(string: string): Uint8ArrayBuffer; /** * Decode `windows-1252` bytes to a string. @@ -113,7 +113,7 @@ export const latin1fromString: (string: string) => Uint8ArrayBuffer; * @param arr - The bytes to decode * @returns The decoded string */ -export const windows1252toString: (arr: Uint8ArrayBuffer) => string; +export function windows1252toString(arr: Uint8ArrayBuffer): string; /** * Encode a string to `windows-1252` bytes. @@ -128,4 +128,4 @@ export const windows1252toString: (arr: Uint8ArrayBuffer) => string; * @param string - The string to encode * @returns The encoded bytes */ -export const windows1252fromString: (string: string) => Uint8ArrayBuffer; +export function windows1252fromString(string: string): Uint8ArrayBuffer; From b7f69bea4b14e2bbb504f1b6a2f29e1a7d1ff07d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:16:23 +0000 Subject: [PATCH 12/12] Add missing example code and windows-* encodings note from README Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- single-byte.d.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/single-byte.d.ts b/single-byte.d.ts index 372b38e..3d4807c 100644 --- a/single-byte.d.ts +++ b/single-byte.d.ts @@ -28,6 +28,24 @@ * > `createSinglebyteDecoder()` (unlike `TextDecoder` or `legacyHookDecode()`) does not do such mapping, * > so its results will differ from `TextDecoder` for those encoding names. * + * ```js + * > new TextDecoder('iso-8859-1').encoding + * 'windows-1252' + * > new TextDecoder('iso-8859-9').encoding + * 'windows-1254' + * > new TextDecoder('iso-8859-11').encoding + * 'windows-874' + * > new TextDecoder('iso-8859-9').decode(Uint8Array.of(0x80, 0x81, 0xd0)) + * '€\x81Ğ' // this is actually decoded according to windows-1254 per TextDecoder spec + * > createSinglebyteDecoder('iso-8859-9')(Uint8Array.of(0x80, 0x81, 0xd0)) + * '\x80\x81Ğ' // this is iso-8859-9 as defined at https://unicode.org/Public/MAPPINGS/ISO8859/8859-9.txt + * ``` + * + * All WHATWG Encoding spec [`windows-*` encodings](https://encoding.spec.whatwg.org/#windows-874) are supersets of + * corresponding [unicode.org encodings](https://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/), meaning that + * they encode/decode all the old valid (non-replacement) strings / byte sequences identically, but can also support + * a wider range of inputs. + * * @module @exodus/bytes/single-byte.js */