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
RFC: Simplify and standardise object instance checking by bringing them into this organisation #878
Comments
I highly endorse this idea 👍 In terms of publishing the packages - we own the |
This is a great idea 💪 We just need to figure out how we can execute it. |
I like the idea of it, though unless @tinovyatkin you are payed to do this full-time, perhaps doing them one by one is more attainable; I want to avoid node-fetch bringing in every part of Fetch ecosystem, but then let them fall into disrepair due to shortage of maintainer. In many ways I appreciate the open ecosystem of node.js, even though it means sometimes a library doesn't quite deliver exactly what you want (or have more features than you need). So figure out some real-world pain points (from their repo issues page perhaps) and see if there are actual drive to maintain them actively, if so, we can bring them in. |
Same here. It's nice when libraries are decoupled and can be used in other libs as well without having to depend on the hole fetch ecosystem. Like how Axios could benefit from FormData without needing any of the fetch related stuff. It would also be nice if some parts could be optional dependencies. I might not even need the Blob, FormData or base64 data URI support at all - in one project i started to use node-fetch@v3 beta 3 or 4 but later uninstalled it since it was a bit troublesome with import. At some point i don't agree with what some package are writing in there description
once it exceeds a certain size then i don't agree with them anymore and i start to write the necessary code myself at some point. sure there package maybe is small but if you take a look at all dependencies, then it's another thing. but i agree that it would be nice to have more stuff under our organisation too. but at the same time i hate to see competing / duplicated similar packages with one small differences. it can be so annoying when i depend on two package and each one of them use on different version of FormData like Can't help but feel like it would be better if stuff lived on the globalScope instead and node-fetch could just use |
I believe the destiny of node-fetch is to have fetch in the Node.js core so that this module wouldn't be necessary anymore. The only reason why its not there is because it's insanely difficult to replicate the spec. It would need to have web streams, AbortController, FormData and Blob. However, this is what we're trying to do here. You can take this either way. |
Speaking of form-data encoding: I made a package that basically moves formdata-node serialization algorithm out of my FormData implementation, so it can be used with different libraries to perform the encoding in different HTTP clients: https://github.com/octet-stream/form-data-encoder It's on early stage (I just released version 0.1.0), but it already works. I've tested it with both formdata-node and formdata-polyfill. |
Funny enough, i did the same thing with my package. only differences is, I convert the formdata into a Blob in just 20 lines of code. import { FormData, formDataToBlob } from 'formdata-polyfill/esm.min.js'
import formDataToBlob from 'formdata-polyfill/formdata-to-blob.js'
import formDataToBlob from 'https://github.com/jimmywarting/FormData/blob/master/formdata-to-blob.js'
const blob = formDataToBlob(new FormData()) Think a blob is easier to post since it don't involve setting any headers or iterable from stream + it don't have to calculate strings byte length or depend on any other node packages or built in functions such as Buffer you get all of the other benefits from blobs (like blob type and size) so in a essences this is more cross platform compatible for other environments |
Nothing holds me back from making this module targeting more than just Node and stop using its specific APIs, such as |
true, i don't consider copying the entries into a new array is a biggie, formdata are usually very short, and blob/file entries don't copy the data either (they are just referenced) it will also be closer to the data type that is needed to send the data - you have to decode the string entries values twice (once when computing the bytelength and the 2nd time when call the having a blob have allowed me to cache and reuse the instance in more ways than just posting. They can also easily be download with Think i spottet something potentially wrong in your code
async* encode(): AsyncGenerator<Buffer, void, undefined> {
for await (const chunk of this._getField()) {
yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))
}
} Maybe you should make this change? async* encode(): AsyncGenerator<Buffer, void, undefined> {
for await (const chunk of this._getField()) {
- yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))
+ yield typeof chunk === 'string' ? Buffer.from(chunk) : chunk
}
} |
I'm planning to get rid of |
Not sure though if I can run fetch-blob in my tests, because it's ESM only and my module will target both ESM and CJS until I drop Node 12 next year. Same way for formdata-node though. As far as I can tell, I can use |
👍 That's correct. TextEncoder is the way to go if you don't want/need to use the Buffer |
Well, this one is done now. The other news is that it seems like I'm stuck with TypeScript not being able to not transpile |
@jimmywarting does beta version of node-fetch support async iterables? I'm running into a problem with this and I should probably open an issue in fetch-blob or node-fetch... |
This project has quite a long history of searching the correct way for checking non-native Node objects to spy whether they are an instance of some particular classes we use in
node-fetch
. There are objects that we are trying to identify:URLSearchParams
Blob
/File
AbortController
/AbortSignal
FormData
The project went from an initial approach of using
instanceof
whether it was possible to current duck typing check combined with checking onSymbol.toStringTag
for an exact match. And we are receiving a lot of critique for such an approach (#751, #848, #784, #667, #613, #296 to name a recent few).However, if we will look at these objects then it's easy to notice that
URLSearchParams
is landed in Node.js core since version 10, and we have already implementedBlob
within this organization and serialization logic forFormData
(most complicated part of supporting this format) atnode-fetch
core (#603).So, my proposal is to bring reference and lightweight implementations of
AbortController
andFormData
(without serialization is pretty small, see #876 (comment)) into this organization (maybe publishing as@fetch/abort-controller
,@fetch/form-data
) and standardize checking atinstanceof
.instanceof
being a language standard way for checking instances is also very extensible:Symbol.hasInstance
(see use Symbol.hasInstance fetch-blob#46)Proxy
(see More permissiveisStream
logic #848 (comment))Both techniques are easy to document and should prevent any further discussions/critiques on it.
Doing so will allow us to drop legacy code from
node-fetch
and set a documented way for extending the library.For references, current implementations:
abort-controller - written in TypeScript, well tested (94% code coverage), but has some browser-specific code that may be omitted
abortcontroller-polyfill - again, targetted to browsers, so, maybe greatly optimized/reduced for Node-only environment.
node-abort-controller - small, based on
EventEmitter
and targeting Node-only. My proposal is to invite @southpolesteve to donate this repository into the @node-fetch organization or create our own in the base of a similar approach. TypeScript declaration linked tolib.dom
so should be rewritten.FormData - @jimmywarting polyfill of FormData targeting browsers.
formdata-node - targeting Node.JS but contains serialization code that @octet-stream mostly implemented in the core of
node-fetch
. It also includes its own implementation ofBlob
/File
that should be replaced by ours.form-data - original implementation of FormData for Node, contains serialization logic that we don't need, not the spec-compliant.
There are quite a few cases with popular open-sources projects that did the same way - initially coupled with 3rd party modules maintained by individual authors for some important part of their functionality they decided to move/fork those modules into their organizations to guarantee maintainability and future-proof of main libraries. Some notable examples here are
cssstyle
at @jsdom andkoa-router
at @koajs/cc @node-fetch/core @node-fetch/reviewers
The text was updated successfully, but these errors were encountered: