Last active
March 3, 2025 21:05
Revisions
-
WebReflection revised this gist
Mar 3, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,7 +31,7 @@ rbuff.set(ref, 0); // ✅ ### TextDecoder Only an `ArrayBuffer`, *resizable* or not, can be used. `SharedArray` needs to be sliced as static `ArrayBuffer`. ```js const decoder = new TextDecoder; -
WebReflection created this gist
Mar 3, 2025 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,76 @@ # TextEncoder & TextDecoder shenanigans This gist is to remind developers that resizable or growable *buffers* don't play nice with `TextEncoder` or `TextDecoder` instances. ### Setup ```js // setup const ref = new TextEncoder().encode("hello"); // SharedArrayBuffer (static) View const sab = new Uint8Array(new SharedArrayBuffer(5)); // optional pre-populate sab.set(ref, 0); // ✅ // SharedArrayBuffer (growable) View const gsab = new Uint8Array(new SharedArrayBuffer(5, { maxByteLength: 16 })); // optional pre-populate gsab.set(ref, 0); // ✅ // ArrayBuffer (static) View const buff = new Uint8Array(new ArrayBuffer(5)); // optional pre-populate buff.set(ref, 0); // ✅ // ArrayBuffer (resizable) View const rbuff = new Uint8Array(new ArrayBuffer(5, { maxByteLength: 16 })); // optional pre-populate rbuff.set(ref, 0); // ✅ ``` ### TextDecoder Only an `ArrayBuffer`, *resiable* or not, can be used. `SharedArray` needs to be sliced as static `ArrayBuffer`. ```js const decoder = new TextDecoder; decoder.decode(buff); // ✅ decoder.decode(rbuff); // ✅ decoder.decode(sab.slice(0)); // ✅ - not shared decoder.decode(gsab.slice(0)); // ✅ - not shared decoder.decode(sab); // ❌ // Failed to execute 'decode' on 'TextDecoder': // The provided ArrayBufferView value must not be shared. decoder.decode(gsab); // ❌ decoder.decode(gsab.subarray(0)); // ❌ // Failed to execute 'decode' on 'TextDecoder': // The provided ArrayBufferView value must not be shared. ``` ### TextEncoder encodeInto Only **static** `ArrayBuffer` can be used, making it impossible to use for linear, resizable, serializations purposes. ```js const encoder = new TextEncoder; encoder.encodeInto("hello", buff); // ✅ encoder.encodeInto("hello", gsab); // ❌ encoder.encodeInto("hello", gsab.subarray(0)); // ❌ // Failed to execute 'encodeInto' on 'TextEncoder': // The provided Uint8Array value must not be shared. encoder.encodeInto("hello", rbuff); // ❌ encoder.encodeInto("hello", rbuff.subarray(0)); // ❌ // Failed to execute 'encodeInto' on 'TextEncoder': // The provided Uint8Array value must not be resizable. ``` - - - Related topic in TC39 around the fact we can't even know AOT the size of a string before deciding to use awkward magic behind the scene to make `encodeInto` happen: https://es.discourse.group/t/string-bytelength-count/2315