houdini
houdini copied to clipboard
Lazy inline queries
With the store api lazy queries are now easily possible by defining them in a separate file. But I would love to be able to define them inline.
My idea to implement this is:
We can probably detect whether the query
call is part of a variable declaration or standalone, right? I.e. we can differentiate between
const { data, refetch } = query(...);
and
query(...);
If this is the case we could abort the preprocessor logic early to not execute the query in load
or on mount.
My thinking is that in the second case the user clearly does not intend to use the query data right now. So it seems logical to defer execution.
What do you think, @aivazis @jycouet?
Yea, i agree that we probably want to be able to do this. I wonder if it would be enough to support having a floating graphql
tag which would result in a store that you could import as you wanted. Something like
<script>
import FooStore from '$houdini/stores/Foo'
graphql`
query Foo {
bar
}
`
// ....
</script>
Thoughts?
Another option is that we could kind of merge these a bit so that a reference to an inline query returns the store:
<script>
const FooStore = graphql`
query Foo {
bar
}
`
</script>
I like both approaches, the second one even a bit more. This way there you can immediately see the floating graphql tag has a purpose :sweat_smile:
Actually, this 👇
<script>
import { graphql } from "$houdini";
graphql`
query Foo {
bar
}
`
</script>
Is already generating the store GQL_Foo
🎉
But the preprocessor tries to do something with it (and it doesn't work).
If you add query(graphql....
, everything will work as usual, but then you can't do mazy stuff.
I see 2 ways:
1/ When nothing infront of graphql
=> Disable preprocessor
2/ Having a function to say: Disable preprocessor. Something like store(graphql...
(to ask only for the store creation, nothing more)
Bonus, the cool thing with GQL_Foo
is that it's typed without putting the type manually.
i'm personally not a fan of the floating graphql
tag. i think saying const foo = graphql
is much more clear instead of having to define a query and then import the store in 2 different lines. One benefit this has is that it's relatively straight forward to support. the preprocessor should just always turn a graphql
tag into a reference to the appropriate store and then the inline functions can just look up the information they need from the store reference instead of having an object that contains the store
I see it as a great opportunity to mix styles (like https://github.com/HoudiniGraphql/houdini/pull/407). If you don't like to define operations in an external document but you want to interact with stores directly 👍
It's almost like a bug today that it's not already working like:
-
graphql
is creating the store -
query(...)
doing the preprocessor for query, having SSR & Browser -
paginatedQuery(...)
doing the preprocessor for paginatedQuery, having SSR & Browser & pagination
I have to say that the syntax with the import is also strange because you import something that you define inside the component. 😅 Strange, but enabling this:
<script context="module">
import { GQL_Foo } from "$houdini";
export async load(event) {
await GQL_Foo.fetch({ event })
return {}
}
</script>
<script>
import { graphql } from "$houdini";
graphql`
query Foo {
bar
}
`
</script>
We don't have to forget that the original question was about lazy. So, maybe the clean & enabling things way is:
<script>
import { graphql, store } from "$houdini";
const myStoreNameFoo = store(graphql`
query Foo {
bar
}
`)
function randomAction() {
myStoreNameFoo.fetch()
}
</script>
With store(...
giving you GQL_Foo
hm maybe i'm missing something but i'm not sure what store
gets you in that example. What i have in mind would look something like
<script context="module" lang="ts">
// type is inferred from overloaded definitions of graphql
const store = graphql`
query MyQuery {
}
`
export async load(event) {
await store.fetch({ event })
return {}
}
</script>
<script>
$: browser && store.fetch()
</script>
{$store.value}
Just a heads up, support for this will be added as part of the upcoming work to support the new KitQL api 👍