-
Notifications
You must be signed in to change notification settings - Fork 773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Readable stream analysis refactor #3231
Conversation
f0250c1
to
a7b917d
Compare
Codecov ReportAttention:
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks for exploring so quickly, this generally looks great and will be a substantial improvement on the library. :-) (my new MacOS update killed the emojy usage, lol, at least in Firfox).
Two very general things to discuss around backwards compatibility and Node.js specific imports, more for the whole team (at least the second one).
const stream = trie.createReadStream() | ||
for await (const chunk of stream) { | ||
storage[bytesToHex(chunk.key)] = bytesToHex(chunk.value) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked too deeply, a general thing though:
We need to keep the API intact (aka: backwards compatible), so from createReadStream()
, so the return type is therefore not allowed to change.
If I interpret the code above correctly (showing a usage example of createReadStream()
it does here though (it does, right? so the new stream API is realized with async calls, the old one with events, if I see correctly?).
Just to clarify: I also like the new API a lot better.
We nevertheless need to find a way to remain compatibilty, otherwise things will break for users using the method in the old way.
Two eventual options:
- Can we use the web stream API in the way the old one worked (just asking for completeness, I would otherwise assume: likely not)?
- If not, we likely need to bite the sour apple and keep the old method "as is", keep the dependency for now, add a new method with an eventually temporary name (
createWebReadStream()
,createAsyncReadStream()
,?) and then we add this whole thing to Breaking/Deprecation Tracking Issue #3216 to remember to fully remove the dependency along the next breaking release round and eventually rename the new method name to the old one.
If we go 2. (guess that's likely?) please also add a @deprecated
note to the code docs of the old method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it seems like the web API differs from readable-stream
in that it uses async calls instead of events. I just took a deeper look and can confirm that there isn't an option to use events with the new web API, so I added the @deprecated
note and made both options available to eventually update it in the future with a breaking release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -43,6 +43,8 @@ import type { | |||
import type { OnFound } from './util/asyncWalk.js' | |||
import type { BatchDBOp, DB, PutBatch } from '@ethereumjs/util' | |||
import type { Debugger } from 'debug' | |||
// eslint-disable-next-line implicit-dependencies/no-implicit | |||
import type { ReadableStream } from 'node:stream/web' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also for others to chime in (@jochem-brouwer @acolytec3, everyone): will this type import affect browser and or other runtime support (bun, deno) in any way?
We generally have the policy to not add Node.js specific package imports. Does this also go for types? I am a bit unsure here. For web it shouldn't make a difference since web is using JavaScript (?). For bun I tested a trie package test run with bunx vitest run test
. This does work, not sure if vitest "shields" something here.
I am totally undecided. Would it eventually make sense to spare out this import and rather go for any
? Or are we on the safe side here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am no browser expert here but I would assume that bun / deno do not have access to this node:stream/web
package, however your bunx vitest run test
indeed seems to pass. However I would assume that this would fail on browser builds, which does not seem to be the case (and the CI browser tests also pass). I have tried bunx vitest run --config=./vitest.config.browser.ts --browser.name=chrome --browser.headless
, this fails all tests:
Error: Module "events" has been externalized for browser compatibility. Cannot access "events.EventEmitter" in client code. See https://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
However this does not seem to be related to ReadableStream
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is: since this is a web API, this import should just not be needed in the browser, and the code work nevertheless. I’m am just not sure how these cases are handled in practice. It would (eventually?) e.g. make sense if browsers just „overlook“ (aka: ignore) such an import.
In this case it is even a type import which should go away for JavaScript anyhow (re-read my message above). So generally I would assume we are on the safe side here.
@scorbajio maybe do add a comment above this import shortly explaining why this can go as an exception and stating that we normally do not do Node.js imports in our libs (not that this serves other devs as a reference to conclude: Node.js allowed). A date for the comment also can’t hurt to get some context.
(and the alternative is still that we go for „any“ here, might also be a justified choice in this case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a note detailing the choice to deviate from our import policy and kept the typing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, great comment! 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also have added to the deprecation issue #3216 as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @scorbajio @holgerd77 , we current have an issue building for the browser using webpack:
ERROR in node:stream/web
Module build failed: UnhandledSchemeError: Reading from "node:stream/web" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.
could this be related to this change and if yes what would you recommend to make it build for the browser?
Thanks very much!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yann300 ah, we were arguing if this might bite us or not 😬 😛 (as seen above), seems we now have the confirmation.
@scorbajio can you prepare a short PR where we replace this with any
and remove the import, as discussed above? That would be nice!
@yann300 Guess we'll make some bugfix releases relatively soon, maybe give us a couple more days, there might be 2-3 other things we would want to include as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've raised #3280 to address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yann300 Would you be able to provide the steps to reproduce this webpack build error so we can explore the problem and potential fixes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, LGTM!
@@ -1,3 +1,5 @@ | |||
// eslint-disable-next-line implicit-dependencies/no-implicit | |||
import { ReadableStream } from 'node:stream/web' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi @scorbajio @holgerd77 the import is also present here.
This PR looks into options for the issues discussed in #3218.