K
Kyselyoof2win2

building kysely makes the package size very large

hi. i'd be more than happy to figure this out because i like kysely a lot more than drizzle. the thing was that the package size was so much larger with drizzle. i made a repro here. when running bun build --minify --outfile, i get kysely to be 340.40kB whilst drizzle is 55.35kB, meanwhile the functional code besides the database is identical
oof2win2
oof2win2•41d ago
the demo is essentially just a post and comments api with very basic functionality
Igal
Igal•41d ago
Hey 👋 Which bun version?
oof2win2
oof2win2•41d ago
1.0.25 same thing happens on 1.1.2 though
Igal
Igal•41d ago
I see stuff in the output file that should'nt be there. e.g. PostgresDriver implementation, while SQLiteDialect is in use
oof2win2
oof2win2•41d ago
the same issue occurs when using esbuild, so it's not just bun. i tried adding a sideEffects: false field to kysely's package json, but it still seems to import everything for some reason Figuring out some dependencies, the CJS was included because of kysely-d1 requiring it. reduced the import of kysely by ~200kB by changing that to esm and changing it to use type imports only in some cases
koskimas
koskimas•40d ago
There's a separate package.json file in esm and cjs folders inside dist. What happens if you add sideEffects: false there?
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
koskimas
koskimas•40d ago
We could move to separate imports, but how much would that really save? Vast majority of the code is in the core that always gets imported. The whole thing is like a hairball. If you pull the Kysely class, pretty much everything comes with it.
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
koskimas
koskimas•40d ago
It'd be cleaner to have separate imports for sure, but I don't think the bundle size is affected that much The hairball is due to Kysely class actually depending on pretty much everything. There's no way to tree-shake most of it Well if the tree shaker is smart enough then it's definitely possible, but if it can't tree-shake the current "import everything" index file, then it can't do it even if we split that to separate imports right?
due to side effects
What side effects? We don't have many of those
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
oof2win2
oof2win2•40d ago
yeah i think thats the main issue
koskimas
koskimas•40d ago
No it's not Just try to manually remove the other dialects to see how much it affects
oof2win2
oof2win2•40d ago
okay ill fiddle with it but no matter what i dunno why dialects would take up 100kB but not sure, might be mistaken
koskimas
koskimas•40d ago
You can see all the code the dialects have in the repo. It's a couple of tiny classes per dialect. https://github.com/kysely-org/kysely/tree/master/src/dialect All code in kysely (not minified) 1.6MB the whole dialects folder 148KB All dialects combined only explains 10% of Kysely's size.
oof2win2
oof2win2•40d ago
hmm whats so big? is it the various query types?
koskimas
koskimas•40d ago
A lot of documentation is one thing
oof2win2
oof2win2•40d ago
like alter table etc
koskimas
koskimas•40d ago
The whole schema module is 132KB
oof2win2
oof2win2•40d ago
damn
koskimas
koskimas•40d ago
The types are also super complex and take up some space. But the most wasteful thing is probably the operation nodes lemme check
oof2win2
oof2win2•40d ago
i mean complex types get eradicated in any bundling process
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
oof2win2
oof2win2•40d ago
since it then becomes only js
koskimas
koskimas•40d ago
Yep, 456k just the operation nodes
oof2win2
oof2win2•40d ago
🤯
koskimas
koskimas•40d ago
i mean complex types get eradicated in any bundling process
That's true. And most of the operation node files is just types
oof2win2
oof2win2•40d ago
hmm ill check it all out when im back seems that the operation nodes files aren't just types, looks much more like an AST declaration to me (might be confused here) i'd guess its still only for TS to have valid typings though, which is not something should be necessary when actually running kysely
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
oof2win2
oof2win2•40d ago
oh that would probably optimize the hell out of this
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
oof2win2
oof2win2•40d ago
cant you already compile queries with kysely i mean yeah adds a build tool but it would work main issue i think of is conditional queries, need to have separate compiled queries for each branch wym? i was thinking pretty much along the lines of the existing query compilation. essentially you would have a query as below within your code
// within some function or whatever
const person = await db
.selectFrom('person')
.select('first_name')
.where('id', '=', id)
.executeTakeFirst()
console.log(person.first_name)
// within some function or whatever
const person = await db
.selectFrom('person')
.select('first_name')
.where('id', '=', id)
.executeTakeFirst()
console.log(person.first_name)
then using some TS magic, the build step would infer that db is an instance of Kysely, compile the query (as is in the docs), and then some essentially "basic" instance of Kysely could be used to execute the compiled query, so essentially after it would look like this
// same function, just after build step
const person_query = { sql: 'select * from person where id = $1', parameters: [1], query: { ... } }
const person = await db
.executeQuery(person_query)
console.log(person.first_name)
// same function, just after build step
const person_query = { sql: 'select * from person where id = $1', parameters: [1], query: { ... } }
const person = await db
.executeQuery(person_query)
console.log(person.first_name)
are we talking about the same thing? because if we are then that would actually be insane to have
koskimas
koskimas•40d ago
You should really profile things before you build a plugin like that. You'll save the CPU time of building the query, which is nanoseconds. Microseconds at best The query builder is a lot faster than running JSON.stringify
oof2win2
oof2win2•40d ago
not the time of building the query, but you don't need to import any of the operation nodes since those aren't relevant at that point - assuming my previous assumption about them being only for TS type inference was correct
koskimas
koskimas•40d ago
No the nodes are used internally to represent the query. They are the very thing that makes kysely work internally
oof2win2
oof2win2•40d ago
ah my bad thought a compiled query could be executed simply from the sql and parameters
koskimas
koskimas•40d ago
And how would you transform this query:
let query = db
.selectFrom('person')
.select('first_name')
.where('id', '=', id)

if (foo) {
query = query.where('first_name', '=', foo)
}
let query = db
.selectFrom('person')
.select('first_name')
.where('id', '=', id)

if (foo) {
query = query.where('first_name', '=', foo)
}
oof2win2
oof2win2•40d ago
yeah, that relates to my previous point here you would need to have two queries, execute the basic one if !foo and the second one (first name check) if foo since they expand factorially for every if statement it would not be fun to debug with say 5 statements, since thats 5! = 120 queries
Unknown User
Unknown User•40d ago
Message Not Public
Sign In & Join Server To View
Want results from more Discord servers?
Add your server
More Posts
Kysely setup in monolith APIHello, we have a basic http server with a basic router and a PostgreSQL database. We're wondering whIs it possible to get the total count while fetching rows in a single query?I have a query which looks like this: ```typescript const { items, count } = await db .selectFrom(Separating results of join into objects of each typeHey guys, I'm curious if anyone knows a way to unmerge the results of a join into objects of both tySnippet compilationHi, is it somehow possible to get only part of the compiled code to use it as snippet in ORM? Or vicCreating an 'enum' type columnHi all, Trying to re-create this MySQL in Kysely ``` ... CREATE TABLE ...( ... members ENUM('femalError when destructuring QueryCreator in withRecursiveI'm new to Kysely and attempting to migrate a Next app from prisma to kysely. I've generated types, Is `sql.join` the best way to concatenate sql templates?I have some business logic that incrementally builds up a sql WHERE query as a string. It looks likeMultiple calls to values in insert statement?I just had a production bug where I was calling `.values` multiple times on a query object. I've fix0.27.3 is out. Didn't have time to write0.27.3 is out. Didn't have time to write release notes yet since it was a hotfix to support typescriusing pgvector with KyselyFollowing the example here: https://github.com/pgvector/pgvector-node?darkschemeovr=1#kysely But I Static/reusable custom window functionsHello, I'm trying to buld a properly typed `array_agg` window function and would like to reuse the eIs the Kysely main site down?I just want to confirm if Kysely's main site is downOn Conflict do update set ALL to be inserted columnsHere I am once again with a question for the on conflict bit in postgres. Would there be a way to auHow to use kysely in edge runtime (like NextJS 14 middleware)?Error: The edge runtime does not support Node.js 'crypto' module. Learn More: https://nextjs.org/dochow to write not (array1 && array2)Hi again, how to write following code? I would love to use not(expression) Expected result: ``` noPartial compileHello everyone, is it possible (somehow) to generate only part of the compiled query? I have an edge