Repository navigation
Open
Labels
Priority: MediumThis issue may be useful, and needs some attention.This issue may be useful, and needs some attention.Status: In ProgressThis issue is being worked on, and has someone assigned.This issue is being worked on, and has someone assigned.Status: ProposalA feature request or another suggestion.A feature request or another suggestion.Type: MaintenanceUpdating phrasing or wording to make things clearer or removing ambiguity, without a functionality.Updating phrasing or wording to make things clearer or removing ambiguity, without a functionality.
Description
workspaces/
- formidable
- formidable-plugins?
- formidable-helpers
- formidable-mini - an experimental minimal & modern idea
- formidable-utils
- formidable-storage
- memory (VolatileFile)
- disk (PersistentFile)
- serverless (formidable-serverless)
misc
- minimize dep weight
- monorepo
(turborepo /nx.dev + lerna ^5.1 + yarn workspaces)- Hela v6 - written in typescript, drop / deprecated external packages
- kodiak - merge automation & better PRs and commits (https://kodiakhq.com/)
- Dependabot, make it auto-update and auto-merge all versions and branches (latest-2, latest, latest-3, next-2, next-3)
- GitHub CodeQL action
- go async/await and promises; possibly drop callback APIs entirely
- document Release Process, Lines, and dist-tags & branches
- latest-1, latest-2, next-2, latest-3, latest-4, next-4);
latestas master
- better / real benchmarks
- analyze old tests & rethink and probably drop them
- some benchmarks here at busboy v1 - Changes in v1.0.0 mscdex/busboy#266
- standard Web API
File
Metadata
Metadata
Assignees
Labels
Priority: MediumThis issue may be useful, and needs some attention.This issue may be useful, and needs some attention.Status: In ProgressThis issue is being worked on, and has someone assigned.This issue is being worked on, and has someone assigned.Status: ProposalA feature request or another suggestion.A feature request or another suggestion.Type: MaintenanceUpdating phrasing or wording to make things clearer or removing ambiguity, without a functionality.Updating phrasing or wording to make things clearer or removing ambiguity, without a functionality.
Activity
GrosSacASac commentedon Apr 26, 2022
Maybe do a mix in v3 and in v4 drop callback
tunnckoCore commentedon Jun 16, 2022
New
FormidableFile, based onfetch-bloband Web APIFile. Plus, we'll always make temporary files on tmp dir, for the time the process is running. When the process ends, they are cleared (all that is handled byfetch-blob). The user will still be able to to save on disk or to do that file whatever it wants. Something likeopts.saveon Formidable Options, will mean that we will save the data of that temporary created file to the disk on the user-chosen (or default) upload dir.It handles:
cuidopts.renamefilenamifyPath(withopts.replacement: '-'instead of the default!)Ideally it will be called from
part.on('data')in the future, but for now we can add it at_newFile, then we can usecreateTemporaryBlobto make that temp file and pass the return to the user.Something like that:
We are using
createTemporaryBlobinstead ofcreateTemporaryFilebecause we already made a file instance of FormidableFile which extendsFile.The reason of having our own File implementation on top, is that it's for useful properties that we need to pass to the users. Plus I always seeing it that way since I got in here in v1. The properties of it is based on enough battle-tested
vfile(remark, rehype, unified) andvinyl(gulp), plus of course the minimalism ofFile.Currently
text(),stream()and those methods, are missing, but we probably should implement them too.The whole thing can be introduced in v3 (and require node 14) and backport to v2 (without the temp file creation thing and without
fetch-blob).The rest of the interesting stuff like iterators and new APIs goes to v4.
tunnckoCore commentedon Jun 17, 2022
Okay, so the @jimmywarting's cleaned Formidable parser, which is on the
node-fetchis almost 2x faster than the current one.Based on the
busboys benchmarkbench-multipart-files-100mb-bigthe old one is avg3.7s, now it's1.7sjimmywarting commentedon Jun 17, 2022
wow, didn't know that mine was 2x faster. did you come to any conclusion of why that is?
tunnckoCore commentedon Jun 19, 2022
Not yet. I'm not in parsers and that parser looks like magic to me LOL.
Btw, to make a note: it's faster when use just the class, but not the
toFormData. And when you start putting things on top of all that it gets slower. Busboy v1 really does a great job at the very low level.I'll commit updated benchmarks soon.
jimmywarting commentedon Jul 6, 2022
fetch-blob@3.2.0 is publised, you can now use
createTemporaryBloborcreateTemporaryFileif you likejimmywarting commentedon Jul 6, 2022
btw, formdata is built into NodeJS core now... maybe you can do a conditional import like use some formdata package like formdata-polyfill (used by node-fetch) or formdata-node (both are spec compatible) if it isn't avalible on global namespace
so something like
const FormData = globalThis.FormData || await import('formdata-polyfill/esm.min.js')just so happen to know that NodeJS (undici's FormData imp accepts 3th party blobs like fetch-blob as well - not just only instances of globalThis.Blob)
fetch-blobis still going to stick around until nodejs/node#37340 has been resolved by nodejs itselfjimmywarting commentedon Jul 6, 2022
Was a super long time ago since i even used
gulpand i have never heard ofvinylorfilevbefore... honestly just wished they followed Web File IDE structure instead...vinyl should also impl text, arrayBuffer and stream() 👍
tunnckoCore commentedon Jul 23, 2022
Well, yea. But they predated everything i think, that's why.
I built some
formidable-minion top of yourfetch-blobandformdata-polyfill, you can check it here, it's pretty clean, small and a beauty, haha. ThereFormidableFileis just a Web File, or anyone can just pass the return stadnard FormData to their desired place :Pah.. what a times..
I'm open for ideas and feedback. Not sure how to use these
createTemporary*yet..GrosSacASac commentedon Dec 5, 2022
So my plan is to add a few tests to #855 then merge and publish. This will probably be the last version 3.
And then probably mark 3 as latest. So we can avoid touching v2 like #908 and void having issues that were already fixed in version 3
Then finish #899 which transitions to typescript, so this will be version 4.
tunnckoCore commentedon Dec 9, 2022
@GrosSacASac Agree.
Seems like people are always just using
latestand don't even read or care about anything else. I'm watching the downloads on all versions, and the majority still are on the v2, after the v2.1 publish they started moving to it, but at a very very slow pace.Note: v3 also need to have CJS. We can use
bundtwhich is a very small and simple regex based converter of import-exports to CJS (does only that), so that we can have both ESM and CJS.jimmywarting commentedon Dec 9, 2022
it could be possible to also just create a simple but small cjs wrapper around ESM since the nature of the parser is async anyways...
Then the code could still be written as ESM and you wouldn't have to duplicate all of your code as a dual cjs/esm package hazard that increases the pkg size?
tunnckoCore commentedon Dec 9, 2022
@jimmywarting uh, yea. I actually do it similarly here and there. Good point.
tommyhtran commentedon Dec 18, 2022
Why not merge the TypeScript PR into version 3?
jimmywarting commentedon Dec 18, 2022
Don't think i have much saying in this... but i don't like TS syntax, it dose not run in browsers and never will.
the ESM support and extension-less paths in TS is a hot garbage atm.
I rather much prefer jsdoc + checkjs / allow js combo.
I much more prefer build-free solutions that just works without wasting lots of time compiling stuff that takes time.
you can have equally good type support with plain vanilla javascript. most of the times you don't even need to annotate either javascript or typescript.
let me give you an example. how would you go about using
Audioto calculate the duration of a source? you would need a promise to listen on onloadedmetadatayou may write something like this:
getDruationreturns anumberbut if we rewrite it a little bit with async/await
then you suddenly don't need to annotate anything.
there are other more clever ways to have typing without annotating your code.
if you use default parameters in functions then it can also figure out what the types are.
tunnckoCore commentedon Dec 18, 2022
@jimmywarting agree. Not fan of TypeScript too. Love the explosion and the attention, and how the ecosystem looks, but gosh I can't stand it to write a whole codebase in TS. I think if it's so needed we can expose just a separate d.ts, and when the codebase is drastically simplified it won't be that needed too.
As I said at #899: "I'll review it at a later point, but I don't think a review is much needed. Maybe the only thing that I could ask is to try with separate file approach - e.g. just a typings file that we will distribute with the package. Just to see how it looks like."
tommyhtran commentedon Dec 18, 2022
I can understand a few of the frustrations with TypeScript, but maybe it would help to view it as a necessary evil.
As it is, I already found a few coding mistakes in the process of converting the codebase to TS. It sounds like the drawback here is having a compilation step and being forced to write code a little differently. IMO, compilation isn’t a big deal. Taking away the ability to write code more freely is what we need consensus on.
The alternative to the PR is probably going to be the status quo, type-less development in JS and a .d.ts file that may fall behind on any given commit.
tunnckoCore commentedon Dec 30, 2022
@tommyhtran agree.
But I'm coming from that that the parser could be hard to be typed, and really there's not much need for that - it's an internal.
The rest is just a big bloat around the parser which can be simplified dramatically just like I did with formidable-mini (i'm playing around), which is around the same parser, but the rest on top of it is just a single simple class which won't be that hard to be written in TypeScript - not like the current one.
The thing is that we obviously (based on downloads stats of older versions) should focus on legacy and backporting things.. which drives out the motivation to work at all. In 2023 I'll figure out how to make users to migrate or upgrade, and why not we can get paid for helping and consulting. I'm very excited about v3, v4 and formidable-mini, but..
GrosSacASac commentedon Jun 16, 2023
Ok lets have a vote (react with one)
Continue with current situation (types in a separate project) ❤️
Add type defintion side by side to original source files (.js files + .d.ts files) 🚀
Convert project to typescript and have type definition in the source files, use a compiler to have js files on publish 😄
tunnckoCore commentedon Mar 10, 2024
@GrosSacASac i'll move
formidable-minias a separate repo in the org.Currently it is on https://github.com/tunnckoCore/opensource/tree/master/modules/formidable-mini.
We can start moving tests there, and maybe tag it as v4? It's already API compatible kind of, without the file size options and stuff, but could be used for migrating users. And we can type it too.
tunnckoCore commentedon Apr 25, 2025
Tweaked version of the multipart parser & the multipart plugin (not depending on
thisor tihng sfrom the upstream Formidable class).Seems like it is performing prettty well, STILL, given that we drop the bloat of file handling and old streams handling, and having a main Formidable class.
#996 and the trimmed version can be found on the @mjackson's multipart-parser bench folder
tunnckoCore commentedon Apr 30, 2025
v4 published on
nextnpm dist-tagDocs and basic examples at: https://www.npmjs.com/package/formidable/v/4.0.0-rc.3
it's a fork of the
@mjackson/multipart-parser, because A) we can't build on top directly for now, and B) it's unbeatable. The limit options have to be inside the parser to be able to skip calling the handler for that part if it's above the limits.api
GrosSacASac commentedon May 14, 2025
Maybe we should discuss the API changes.
If the API is too different from previous version then, let's not repeat the mistake of Angular.
tunnckoCore commentedon May 29, 2025
Kinda agree but also not.
The API isn't what's important. The problem is the unnecessary bloat that causes all the edge cases and problems and the majority of what actual users are facing.
The biggest feature of formidable is speed, streaming, and limit options. As the API.. sure we still can expose all that as just
parse. But the best would be to NOT actually use that but the actual streams/iterators for best performance and ZERO buffering.The v4 API is modern way of streaming, a whole lot easier and less crashing. It's normal to continue following that streaming path.
I've pinged a bunch of projects to migrate to at least v3, some to try v4 directly. Most are facing weird problems purely based on the bloat on top of the parser. The parser is not even touched for a decade.
I've rewrote it from scratch at least 7 times just in the last month. I never realized how weird and inefficient it is. So it turned out it's really close to impossible to beat the MJackson's one in benchmarks. One of the tries was pretty close but once I've added features and options we need, it degrades a bit which is normal. So that's the one in v4 in the
nextdist-tag.Not to mention the most famous problem everyone is facing is the one that they gotta disable the frameworks body parser cuz we are touching a bunch the request. The v4 is just multipart. It's absolutely unnecessary to touch the other kind of formats because the language evolved, people got used enough to modern terms and APIs like File and FormData.
I really don't want to touch v3. I want to be stable, fast and serious solution for the modern workflow, without the bloat, without making people wonder why the heck it doesn't work with Nextjs, or why this event wasn't fire, or why this closed, or.. aaggh, or similar sort of problems. Heck, why not build a small ecosystem around us, embed us somewhere more, build micro service to fund further development and education or help for teams.
That's the unlock. Not sitting on the old forgotten APIs, streams shenanigans, and literally unfixable issues and unbackportable features.
The v3 would go into LTS, it would still be here in the monorepo, but I'll not touch it.
Duh.. thought that's going to be a short one. haha.
That's my plan. Sudden, but.. 🤷♂️ I really see a future, and opportunity.