Assemble objects in streaming mode? #215
Replies: 6 comments 1 reply
|
Did you try |
|
I see. Due to the Getting rid of that additional counter and using only the value is simple enough on my side. Thanks for the quick response. |
|
I would appreciate your thoughts on how I can improve the documentation, if it was unclear or hard to follow. |
|
As a user I start with (bytes) a stream of encoded json that comes in as chunks, or (value) an object to serialize. As I understand, the 'internal' representation is (token) a stream of small tokens representing a traversal over one or more json objects. Mentally then I deal with 3 different stream types and want to transform between them. (bytes) -> (token)ParserThese are handled by It is strange that all values are strings, but
This comment is a bit strange, since the linked page shows a deprecation warning. There is also a duplicate comment earlier that qualifies this advice with "where individual items fit in memory" which sounds like better advice.
I don't understand this section at all. It seems like we get duplicate events, i.e. both the packed and unpacked form of each item, in the stream, even listed as "The default". Why would I want this and is this a compatibility option? It also says earlier that "They have no default values" but the table seems to show a default value of VerifierQuite clear in it's description. The backgrounder section tells me no real information as a user. I do have a question on intended use case though: Since I can't stick it in between the source and the parser, should I tee my source into a split stream and run the verifier in parallel? In my mind, the verifier could emit chunks as it reads them in and error out when it sees malformed json and sit between source and parser (or replace it). It could show how an Overall, the docs could show the expected console output whenever a (token) -> (token)Filters, PickI'm a bit biased since the context for this word for me is
Replacement also looks a bit weird, in that it returns "array of semantically valid data items". This should say "tokens" instead of "data items". From a usage perspective, I wonder why I can't return a readable stream here that is piped out as a replacement to the filtered value. It should document that unpacked keys will get assembled in memory. As I understand it, the main point of unpacked keys is to avoid having the whole key in memory, this should be mentioned. Filters, Replace + IgnoreAs said previously, the StreamersNow, the part that I initially misunderstood. I thought this was akin to jq'q toEntries from the Streamers, StreamObjectThe example here could show more complicated nestings to make it clear what it does and combined with the code in the introduction {"a": 1, "b": "a", "c": [{"lang": "de"}], "d": {"foo": null}, "e": true}
// ^ in sample.json
const {streamObject} = require('stream-json/streamers/stream-object.js');
const fs = require('fs');
const pipeline = fs.createReadStream('sample.json').pipe(streamObject.withParserAsStream());
pipeline.on('data', data => console.log(data));
// Output:
{key: 'a', value: 1}
{key: 'b', value: 'a'}
{key: 'c', value: [{"lang": "de"}]}
{key: 'd', value: {"foo": null}}
{key: 'e', value: true}On naming, I find the "streamer" a bit of a misnomer, since it assembles the objects. It seems that most of them combine two operations into one: Restructuring the input token stream (which could stay a token stream) and then assembling the resulting token stream into values. Let me explain a bit more
There is a warning on the streamer doc pages (at least StreamArray which is mentioned first) which I read to conclude that they are actually unsuitable:
Well, I need json streaming. So I looked at (object) -> (token), DisassemblerThis one is super clear to me in what it does and what to expect. No notes, and I don't need to understand any internals to use it. Very cool! Well, I'm looking for the inverse of that, so what's more natural to look for than Assembler? AssemblerDespite the naming, its purpose is clear from the docs page, but I got a few notes on functionality. There is surely a good reason not to be a writeable stream. As I see it, StringerCould be more clear if it accepts multiple top-level objects in its input token stream. It's clear and serves the purpose of (token) -> (bytes). What is not clear to me is why it can't automatically figure out the options of the token stream it consumes and how - in a complicated pipeline - I the user am supposed to keep track of the needed Intro by examplesIf I would have seen the output from the different examples, I would have perhaps realised sooner that I was basically asking for the "JSON Streaming and JSONL" example 😰 As I said initially, I was not sure what "each value" was referring to and thought it might mean each recursive subobject (silly in hindsight). Not sure if saying "each top-level value" is better. I'm already spending a bit too much time fussing over details here, perhaps I was just silly. A simple action would be to include the expected input and output in each example, since I couldn't be bothered to type out the sample files the wiki refers to |
|
I updated README and the wiki to address some of your concerns. I would appreciate if you look them over to see if they work for you better. Additionally I filed some improvement ideas I plan to work on later. Thank you again for taking time and writing a detailed feedback! |
|
3.6.0 (to be released soon): |
Uh oh!
There was an error while loading. Please reload this page.
It is sometimes necessary, after some filtering and other transformations, to assemble full json objects for other libraries and "terminate" the json object stream. I'm currently using a simple transformer that uses the
Assemblerto do this, but I was surprised to not find it in the library itself.Used as
The other direction of fully assembled objects to stream in
Disassembleralready works for transforming object streams to streams of json event. Is there any reason thatAssemblerdoesn't have this interface that I'm missing?All reactions