You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I pack multiple datum into a single message. When I try to unpack with decode(), I get an error.
Uncaught RangeError: Extra 6 of 7 byte(s) found at buffer[1]
I understand that in order to decode a multi-part message I must instead use decodeStream(), however it seems this method is designed for Node users and is not very practical to use in the browser since streams support is scarce. In particular, I don't know how to convert number[]/Uint8Array to ReadableStreamLike.
I suggest there should be an alternative non-streams method to decode multi-part messages, such as decodeMultiple(), or just to permit calling decode() multiple times until all messages are processed, instead of assuming extra bytes are an error.
However, this seems highly convoluted and forces my entire decode branch to become an async call graph in what is otherwise a synchronous application. An alternative, synchronous API would be preferred. Recently, a similar feature was added to msgpackr.
As I explain in #153, converting a binary to StreamLike is very easy if you are familiar with AsyncGenerator. Just three lines of code:
declarevarencoded: Uint8Array;constcreateStream=asyncfunction*(): AsyncGenerator<Uint8Array>{yieldencoded;};forawait(constitemofdecodeStream(createStream())){// do something with item}
As you said, the exact type is ArrayLike<number>, as the reference describes.
The difference between decodeMulti() (even if it doesn't exist) vs decodeStream() is that decodeMulti() doesn't require async function, indicating it might be easier to use. However, I strongly recommend using the async version. Async versions can use CPU and memory in a more effective way than sync ones.
ArrayLike<number> does not feel completely suitable, Typescript is being really annoying for me when targeting browser. Code works otherwise.
Argument of type 'ReadableStream<BufferSource>' is not assignable to parameter of type 'ReadableStreamLike<ArrayLike<number>>'.
Type 'ReadableStream<BufferSource>' is not assignable to type 'ReadableStream<ArrayLike<number>>'.
Type 'BufferSource' is not assignable to type 'ArrayLike<number>'.
Property 'length' is missing in type 'ArrayBufferView' but required in type 'ArrayLike<number>'.ts(2345)
Example code:
async()=>{constresponse=awaitfetch("items.msgpackgz");constgZipStream=newDecompressionStream("gzip");constdataSource=decodeArrayStream(response.body.pipeThrough(gZipStream)<---DecompressionStreamusesBufferSource,whichdoesn't work well with ArrayLike<number>
);returndataSource;}
@gfx My only reason for mentioning it is that you might want to update the documentation in your PR with the "correct" type (ArrayLike<number>), just so it is clear to the reader.
Anyway, since modern browsers seem to have good support for async and generators, this is no longer a major issue. It may still be difficult to use an async call in a non-async application for some people, though, because the entire call graph has to be converted to async to accommodate it.
@prajaybasu Thank you for your report. I think it's irrelevant to this issue, so please file a separate issue. BTW I think it's actually insufficient for this library, so I'll fix it.
@Bilge That's a good point. Conversion of sync functions to async functions is sometimes difficult or spending unnecessary time. Let me think again about decodeMulti().
Activity
gfx commentedon Feb 5, 2021
Thanks for filing this issue. It sounds like a good viewpoint for me. I'd like to add examples to explain how to use
decodeStream()in browsers.Bilge commentedon Feb 5, 2021
I managed to use it as follows.
However, this seems highly convoluted and forces my entire decode branch to become an async call graph in what is otherwise a synchronous application. An alternative, synchronous API would be preferred. Recently, a similar feature was added to msgpackr.
gfx commentedon Feb 6, 2021
As I explain in #153, converting a binary to StreamLike is very easy if you are familiar with
AsyncGenerator. Just three lines of code:What do you think of it?
Bilge commentedon Feb 6, 2021
さすが、FUJIさんのコードの方が単純ですね!しかし
Uint8Arrayが必要ではありません。例えばnumber[]も良いですよ。(日本語が下手ならごめんなさい)
gfx commentedon Feb 8, 2021
@Bilge ありがとう 😉
As you said, the exact type is
ArrayLike<number>, as the reference describes.The difference between
decodeMulti()(even if it doesn't exist) vsdecodeStream()is thatdecodeMulti()doesn't requireasyncfunction, indicating it might be easier to use. However, I strongly recommend using the async version. Async versions can use CPU and memory in a more effective way than sync ones.prajaybasu commentedon Feb 14, 2021
ArrayLike<number>does not feel completely suitable, Typescript is being really annoying for me when targeting browser. Code works otherwise.Example code:
Probably related: microsoft/TypeScript#24195
Bilge commentedon Feb 14, 2021
@gfx My only reason for mentioning it is that you might want to update the documentation in your PR with the "correct" type (
ArrayLike<number>), just so it is clear to the reader.Anyway, since modern browsers seem to have good support for async and generators, this is no longer a major issue. It may still be difficult to use an async call in a non-async application for some people, though, because the entire call graph has to be converted to async to accommodate it.
gfx commentedon Feb 14, 2021
@prajaybasu Thank you for your report. I think it's irrelevant to this issue, so please file a separate issue. BTW I think it's actually insufficient for this library, so I'll fix it.
@Bilge That's a good point. Conversion of sync functions to async functions is sometimes difficult or spending unnecessary time. Let me think again about
decodeMulti().gfx commentedon Feb 16, 2021
Added
decodeMulti()to v2.4.0. Thanks.