From bf8a3486a3b6716cda594ef3d53cf0704beb83f0 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Tue, 1 Jul 2025 23:02:29 -0700 Subject: [PATCH] Support path of type `SharedArrayBuffer` --- src/core.js | 10 +++++++++- test/core.test.js | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/core.js b/src/core.js index cce5ca4..c76004f 100644 --- a/src/core.js +++ b/src/core.js @@ -8,7 +8,7 @@ import { ReadableStream, WritableStream, TransformStream } from 'node:stream/web /** * Parse and normalize a `PathLike` object into a string. * - * @param {PathLike|ArrayBufferView|ArrayBuffer} path A `string`, `Buffer`, or `URL` representing a path to a local file. + * @param {PathLike|ArrayBufferView|ArrayBufferLike} path A `string`, `Buffer`, or `URL` representing a path to a local file. * @returns {string} The normalized file path in string form. * @throws {TypeError} If `path` is not a `string`, `Buffer`, or `URL`, or it is a `URL` that is not using the `file` schema. */ @@ -19,6 +19,14 @@ export function parsePathLike(path) { else if (ArrayBuffer.isView(path) || path instanceof ArrayBuffer) { return normalize(new TextDecoder().decode(path)); } + // Although Node.js supports directly passing SharedArrayBuffer to TextDecoder().decode(), this capability is not yet + // supported by all JS runtimes. For compatibility with other runtimes, the below code will copy the SAB into a non-shared + // buffer and then decode it. Reference: https://github.com/whatwg/encoding/pull/182 + else if (path instanceof SharedArrayBuffer) { + const copy = new Uint8Array(path.byteLength); + copy.set(new Uint8Array(path)); + return normalize(new TextDecoder().decode(copy)); + } else if (path instanceof URL) { return fileURLToPath(path); } diff --git a/test/core.test.js b/test/core.test.js index c709a79..1c4918e 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -55,6 +55,20 @@ suite('parsePathLike', { concurrency: true }, () => { } }); } + test('parses SharedArrayBuffer relative path', { concurrency: true }, () => { + const str = './folder/example.txt'; + const view = new Uint8Array(new SharedArrayBuffer(str.length)); + new TextEncoder().encodeInto(str, view); + ok(view.buffer instanceof SharedArrayBuffer); + deepStrictEqual(parsePathLike(view.buffer), normalize(str)); + }) + test('parses SharedArrayBuffer absolute path', { concurrency: true }, () => { + const str = '/absolute/path/to/file.txt'; + const view = new Uint8Array(new SharedArrayBuffer(str.length)); + new TextEncoder().encodeInto(str, view); + ok(view.buffer instanceof SharedArrayBuffer); + deepStrictEqual(parsePathLike(view.buffer), normalize(str)); + }) }); suite('createFileStream', { concurrency: true }, () => { -- 2.47.3