Closed petrovica closed 2 years ago
Thanks 🍻
Sure, we can transpile to ES2021 if I can figure out how to fix the constructor. We can't create multiple instances of those classes (the ones created in the else branch of the constructor) so I don't really know a clean way to fix the constructor (a bunch of hacks come to mind though).
The link to the diff doesn't work, don't know if you had a solution there or not.
Link to the commit: https://github.com/petrovica/kysely/commit/c5d034f1c8c12f3a5bb75e6ae9ee271814e66b0e Hopefully this one works.
No real solution, I just tried getting rid of that private prop to verify it's the only cause of the issue. Once I made this.#props
public, I was able to transpile to ES2021 and that fixed the React Native issue.
Yeah, the logic before super
call makes it non-trivial, but I'm glad you'd like to move forward with that. Thanks! I'll try to figure something out too :slightly_smiling_face: . If fixing the constructor won't be possible without breaking changes, making this.props
public would work too, but I don't like that either :man_shrugging:
This works, but **ck is it ugly:
const propsCache = new WeakMap<KyselyConfig | KyselyProps, KyselyProps>()
function init(args: KyselyConfig | KyselyProps): KyselyProps {
if (propsCache.has(args)) {
return propsCache.get(args)!
}
if (isKyselyProps(args)) {
propsCache.set(args, args)
return args
}
const dialect = args.dialect
const driver = dialect.createDriver()
const compiler = dialect.createQueryCompiler()
const adapter = dialect.createAdapter()
const log = new Log(args.log ?? [])
const runtimeDriver = new RuntimeDriver(driver, log)
const connectionProvider = new DefaultConnectionProvider(runtimeDriver)
const executor = new DefaultQueryExecutor(
compiler,
adapter,
connectionProvider,
args.plugins ?? []
)
const props = {
config: args,
executor,
dialect,
driver: runtimeDriver,
}
propsCache.set(args, props)
return props
}
export class Kysely<DB>
extends QueryCreator<DB>
implements QueryExecutorProvider
{
readonly #props: KyselyProps
constructor(args: KyselyConfig)
constructor(args: KyselyProps)
constructor(args: KyselyConfig | KyselyProps) {
super({
executor: init(args).executor,
})
this.#props = init(args)
propsCache.delete(args)
}
...
}
I had to dig a bit in the code to undestand what's going on. You're using this.#props
in Kysely
and also QueryCreator
, so it needs to by private. And executor
needs to be shared between Kysely
and QueryCreator
, but you don't want to move the whole logic to QueryCreator
.
It's actually pretty elegant considering the limitations :+1:
I didn't realize that ES2021 doesn't have private properties and typescript emulates them using WeakMap
s. That dropped the query building performance to 50% of the ESNext version. I don't think I'll want to sacrifice that much over React native support right now.
Makes sense :+1: . Anyway, thanks for your time :slightly_smiling_face:
Let's hope React native world catches up with the new features soon 🤞
I don't think it will. Facebook's plan is to switch from WebKit's JS engine to their custom engine (Hermes). It's an amazing upgrade performance-wise, but it currently supports only most of ES6 features. At least we have Babel :slightly_smiling_face:
Hi! First of all, I haven't seen such a great idea how to use new TypeScript features in long time. Great idea and even better execution. I wanted to switch from string literal based SQLite query builder to kysely, but I'm having issues making it work on React Native. I'm using new node-less version. That helped a lot (thanks btw!), but I hit another issue. Same as the person here: https://stackoverflow.com/questions/69922302/react-native-flatlist-undefined-is-not-an-object-evaluating-props-getitem
Basically the issue is we need to enable new language features through Babel to support private class props. But that Babel plugin somehow breaks React Native's FlatList component. Well, that's the obvious part, there might be more things broken.
My idea how to fix it was to just transpile kysely to older ES, ES2021 to be precise. And it worked! There's one issue.
Kysely
's constructor (insrc/kysely.ts
) doesn't callsuper
as first statement and because of that transpilation to ES2021 fails. For ESNext it does not matter, TS is fine with callingsuper
at the end, but for ES2021 it's not possible when using private props.Diff to show what I'm talking about: https://github.com/koskimas/kysely/compare/master...petrovica:es2021?expand=1 So one fix would be not using private props, another fix would be to reorganize the constructor to call
super
first.Would you be ok with transpiling the code to ES2021? I don't think I'll be able to fix the
FlatList
component in React Native or that Babel plugin that breaks it. I haven't found any obvious weird stuff that would explain this. But fixing it by using different transpilation target in kysely is a thing I can manage :crossed_fingers: :slightly_smiling_face:What do you think about the issue and possible fixes? I can't find much more about this issue except for the SO question. It's really an edge case :man_shrugging:
I'm using latest version of React Native (0.67).