WHATWG Encoding
Elide implements the WHATWG [Encoding Standard][spec] globals TextEncoder and TextDecoder,
available on globalThis and mirrored at require('node:util').TextEncoder /
require('node:util').TextDecoder.
[spec]: https://encoding.spec.whatwg.org/
TextEncoder
js
new TextEncoder()| Member | Type | Notes |
|---|---|---|
encoding | string | Readonly; always "utf-8". |
encode(input = "") | Uint8Array | Returns a fresh Uint8Array containing the UTF-8 bytes. |
encodeInto(source, destination) | { read, written } | Writes into destination; never writes a partial code point. |
U+FFFD, producing EF BF BD in
the output.
TextDecoder
js
new TextDecoder(label = "utf-8", options = {})
// options: { fatal: boolean = false, ignoreBOM: boolean = false }| Member | Type | Notes |
|---|---|---|
encoding | string | Readonly; canonical lowercase encoding name (e.g. "utf-8"). |
fatal | boolean | Readonly; true → malformed input throws TypeError. |
ignoreBOM | boolean | Readonly; when false and encoding is utf-8/utf-16le/utf-16be, a leading BOM is stripped. |
decode(input?, options?) | string | options.stream: boolean = false. Partial trailing bytes are retained for the next call only when stream is true. |
Supported labels
All labels defined by the [WHATWG Encoding names-and-labels table][labels] that map to a
JVM-available Charset. This covers:
[labels]: https://encoding.spec.whatwg.org/#names-and-labels
- Unicode:
utf-8(and aliasesutf8,unicode-1-1-utf-8),utf-16le(aliasesutf-16,unicode,ucs-2, etc.),utf-16be. - Western:
windows-1252(default forascii,iso-8859-1,latin1),iso-8859-2…iso-8859-16,windows-1250…windows-1258,macintosh,x-mac-cyrillic. - Cyrillic:
ibm866,iso-8859-5,koi8-r,koi8-u,windows-1251. - Greek / Arabic / Hebrew / Thai:
iso-8859-6/7/8/8-i,windows-874. - CJK:
gbk,gb18030,big5,euc-jp,iso-2022-jp,shift_jis,euc-kr.
Label normalization: ASCII whitespace (tab, LF, FF, CR, space) is stripped from each end and
the remainder is lowercased. Unknown labels throw RangeError.
Call vs new
Both constructors must be invoked with new; calling TextEncoder(...) or TextDecoder(...)
as plain functions throws TypeError.
Streaming: TextEncoderStream / TextDecoderStream
TextEncoderStream and TextDecoderStream are installed on globalThis as
TransformStreams built over TextEncoder / TextDecoder. TextEncoderStream
turns a stream of strings into UTF-8 Uint8Array chunks; TextDecoderStream
turns a stream of byte chunks into strings, carrying partial multi-byte
sequences across chunk boundaries.
new TextDecoderStream([label][, options])—options.fatalandoptions.ignoreBOMare honoured; instances exposeencoding,fatal,ignoreBOM, and thereadable/writablepair.new TextEncoderStream()— always UTF-8; exposesencodingand thereadable/writablepair.
js
const lines = byteSource.pipeThrough(new TextDecoderStream());
for await (const chunk of lines) {
// chunk: decoded string
}Example
js
const enc = new TextEncoder();
const bytes = enc.encode("Hello, мир! 🌍");
// bytes = Uint8Array([72,101,108,108,111,44,32,208,188,208,184,209,128,33,32,240,159,140,141])
const dec = new TextDecoder("utf-8");
dec.decode(bytes); // → "Hello, мир! 🌍"
// Streaming across partial multi-byte sequences:
const streamer = new TextDecoder();
streamer.decode(new Uint8Array([0xc3]), { stream: true }); // → ""
streamer.decode(new Uint8Array([0xa9])); // → "é"
// fatal mode raises TypeError on invalid input instead of replacing with U+FFFD:
const strict = new TextDecoder("utf-8", { fatal: true });
strict.decode(new Uint8Array([0xff])); // throws TypeErrorNotes on the implementation
- The fix that routes plain-call
TextEncoder(...)/TextDecoder(...)toTypeErrorlives in the generatedJSTextEncoderClassBase.javaandJSTextDecoderClassBase.javaunderpackages/generated/. Upstreamelide-dev/bindgenhas the corresponding template (JSConstructorCodegen.kt); the next regenerate will emit the same branch automatically. TextDecoderinstance creation explicitly reinstalls the intrinsic prototype viaJSObjectUtil.setPrototypeImplafterJSObjectFactory.initProto— in single-context mode the factory'sinitProtoonly swaps the prototype when it differs from the cached default, and our subclass-with-extra-fields path doesn't always hit the shape-embedded prototype correctly. The explicit call guaranteesinstance instanceof TextDecoderholds.