fix(virtualstream): reconstitute JSON-serialized binary data in VirtualStream; update docs, build config, and dependency bumps

This commit is contained in:
2026-03-01 19:23:51 +00:00
parent d54ec9ea3b
commit 364c1a4720
8 changed files with 5895 additions and 2849 deletions

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@api.global/typedrequest',
version: '3.2.6',
version: '3.2.7',
description: 'A TypeScript library for making typed requests towards APIs, including facilities for handling requests, routing, and virtual stream handling.'
}

View File

@@ -158,6 +158,35 @@ export class VirtualStream<T = Uint8Array> implements plugins.typedRequestInterf
constructor() {}
/**
* Reconstitute binary data that was lost through JSON serialization.
* Node.js Buffer becomes {type: "Buffer", data: [...]},
* Uint8Array becomes {"0": 104, "1": 101, ...}.
*/
private static reconstituteBinaryData(data: any): any {
if (data == null || data instanceof Uint8Array || (typeof Buffer !== 'undefined' && Buffer.isBuffer(data))) {
return data;
}
if (typeof data === 'object') {
// Handle JSON-serialized Node.js Buffer: {type: "Buffer", data: [...]}
if (data.type === 'Buffer' && Array.isArray(data.data)) {
return new Uint8Array(data.data);
}
// Handle JSON-serialized Uint8Array: {"0": 104, "1": 101, ...}
const keys = Object.keys(data);
if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
const arr = new Array(keys.length);
for (const k of keys) {
arr[Number(k)] = data[k];
}
if (arr.every((v) => typeof v === 'number')) {
return new Uint8Array(arr);
}
}
}
return data;
}
workingDeferred: plugins.smartpromise.Deferred<void>;
/**
@@ -231,7 +260,7 @@ export class VirtualStream<T = Uint8Array> implements plugins.typedRequestInterf
});
if (streamTr && streamTr.response && streamTr.response.chunkData) {
this.receiveBackpressuredArray.push(streamTr.response.chunkData);
this.receiveBackpressuredArray.push(VirtualStream.reconstituteBinaryData(streamTr.response.chunkData) as T);
}
otherSideIsBackpressured = streamTr && streamTr.response && streamTr.response.backpressure;
thisSideIsBackpressured = !this.receiveBackpressuredArray.checkSpaceAvailable();
@@ -285,7 +314,7 @@ export class VirtualStream<T = Uint8Array> implements plugins.typedRequestInterf
// chunk handling
if (streamTrArg.request.mainPurpose === 'chunk') {
this.receiveBackpressuredArray.push(streamTrArg.request.chunkData);
this.receiveBackpressuredArray.push(VirtualStream.reconstituteBinaryData(streamTrArg.request.chunkData) as T);
if (this.sendBackpressuredArray.data.length > 0 && streamTrArg.response.backpressure === false) {
const dataArg = this.sendBackpressuredArray.shift();
streamTrArg.response = {