Skip to content

Commit

Permalink
Minor doc fixes (#521)
Browse files Browse the repository at this point in the history
* cleanup docs

* random fixes

* incorrect link

* another invalid link

* document manual afterLoad
  • Loading branch information
AlecAivazis authored Sep 7, 2022
1 parent a8b33c1 commit 19b90d5
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 82 deletions.
4 changes: 2 additions & 2 deletions site/src/routes/api/fragments.svx
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ Fragments may also contain a paginated field, similar to queries. A paginated fr

### Return Values

`paginatedQuery` returns a store that holds an object with the following keys:
`paginatedFragment` returns a store that holds an object with the following keys:

- `data` contains the fragment's data
- `loading` contains a boolean value that tracks the loading state of the pagination requests
- `pageInfo` ts contains the page info (`hasPreviousPage`, `hasNextPage`, etc.) Only valid for cursor-based pagination.
- `partial` contains a boolean that indicates if the result has a partial match

and has one of the following methods (depending on your fields pagination direction):
The store also has one of the following methods (depending on your fields pagination direction):

- `loadNextPage` is an async function that loads the next page. It takes one optional argument: the page size to load for the next request.
- `loadPreviousPage` is an async function that loads the previous page. It takes one optional argument: the page size to load for the next request.
55 changes: 51 additions & 4 deletions site/src/routes/api/routes.svx → site/src/routes/api/query.svx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Routes
title: Query
index: 1
description: Queries in Houdini
---
Expand Down Expand Up @@ -73,7 +73,7 @@ type MyFriendsStore = QueryStore & {
`
</script>

# Routes
# Query

Load data from the server and subscribe to any changes of fields we detect from mutations, subscriptions, and other queries.

Expand Down Expand Up @@ -206,7 +206,7 @@ Called after Houdini executes load queries against the server. You can expect th
arguments as SvelteKit's [`load`](https://kit.svelte.dev/docs#loading) function, plus an additional
`data` property referencing query result data. Keep in mind that if you define this hook, Houdini
will have to block requests to the route in order to wait for the result. For more information about
blocking during navigation, check out [this section](/api/query/store#server-side-blocking) of the query store
blocking during navigation, check out the deep dive in [this section](/api/query#manual-loading) of the query store
docs.

```javascript
Expand Down Expand Up @@ -245,7 +245,7 @@ If defined, the load function will invoked this function instead of throwing an
It receives three inputs: the load event, the inputs for each query, and the error that was encountered. Just like
the other hooks, `onError` can return an object that provides props to the route. If you do define this hook, Houdini
will have to block requests to the route in order to wait for the result. For more information about
blocking during navigation, check out [this section](/api/query/store#server-side-blocking) of the query store
blocking during navigation, check out the deep dive in [this section](/api/query#manual-loading) of the query store
docs.

```javascript
Expand Down Expand Up @@ -323,6 +323,23 @@ export async function load(event) {
}
```

If you are defining a manual load and need to look at the result of the fetch, we recommend _not_ using the `load_`
utility but instead defining your load explicitly:

```javascript
import { MyQueryStore } from '$houdini'

export async function load(event) {
const MyQuery = new MyQueryStore()

const result = await MyQuery.fetch(event)

console.log('do something with', result)

return { MyQuery }
}
```

<DeepDive title="Loading multiple stores simultaneously">

Be careful when loading multiple stores at once.
Expand Down Expand Up @@ -434,6 +451,36 @@ export async function get(event) {
}
```

## Passing Metadata

Sometimes you need to do something very custom for a specific route. Maybe you need special headers or some other contextual information.
Whatever the case may be, you can pass a `metadata` parameter to fetch:

```svelte
<script context="module">
import { browser } from '$app/env'
import MyQueryStore from '$houdini/stores/MyQuery'

</script>

<script>
export let variables

$: browser && MyQueryStore.fetch({ variables, metadata: { ... } })
</script>
```

This value will get forwarded to the network function in your client definition, usually found in `src/client.js`:

```typescript
async function fetchQuery({ fetch, text, variables, session, metadata }) {
// do anything with metadata inside of here
}

// Export the Houdini client
export default new HoudiniClient(fetchQuery)
```

## Paginated Queries

If the query contains the pagination directive then the generated store will have extra fields/methods
Expand Down
52 changes: 7 additions & 45 deletions site/src/routes/api/subscription.svx
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,7 @@ Listen for real-time updates from your server using GraphQL Subscriptions.
export let itemID

// will start listening onMount (browser only)
subscription(
graphql`
subscription ItemUpdate($id: ID!) {
itemUpdate(id: $id) {
item {
id
completed
text
}
}
}
`,
{ id: itemID }
)
</script>
```

### Inputs

1. A string tagged with `graphql` containing a single document with one named subscription
2. An object containing any arguments for the subscription

### Return Values

`subscription` returns a store containing the latest version of the subscription value

Note: mutations usually do best when combined with at least one fragment grabbing
the information needed for the mutation (for an example of this pattern, see below.)

## External Documents

Subscriptions defined in external documents can be trigger using the subscription store's `listen` method:

```svelte

<script>
import { graphql, subscription } from '$houdini'

// this information should usually come from a fragment
export let itemID

const store = graphql`
const updates = graphql`
subscription ItemUpdate($id: ID!) {
itemUpdate(id: $id) {
item {
Expand All @@ -68,13 +27,16 @@ Subscriptions defined in external documents can be trigger using the subscriptio
}
}
`


$: updates.listen({ id: itemID })
</script>

<button on:click={() => store.listen({ itemID })}>
listen
</button>
latest value: {$updates.itemUpdate.item.text}
```

Subscriptions can be defined like any other document and are triggered using the subscription store's `listen` method:

## List Operations

Subscription bodies can contain all of the list operations described in [this document](/api/mutation#lists).
Expand Down
12 changes: 4 additions & 8 deletions site/src/routes/api/welcome.svx
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,14 @@ export default {

# Houdini API Reference

Every GraphQL document in your Houdini application has two different ways of interacting with it. You can either define
your document inside of your svelte components or in an external file. While the approaches are equivalent, their APIs
do vary slightly for the situation. In order to accommodate this, each document page has a toggle in the top right to flip between the store
and inline APIs. For more information about the differences in the APIs, checkout out the
[Working With GraphQL](/guides/working-with-graphql) guide.
Every GraphQL document in your Houdini application is driven by a Svelte store with specific methods for performing each task.

## GraphQL Documents

<APIShowcase
title="routes"
title="query"
description="Fetch data from the server"
href="/api/routes"
href="/api/query"
example={queryExample}
/>

Expand Down Expand Up @@ -129,7 +125,7 @@ example={configExample}
<APIShowcase
title="SvelteKit Plugin"
description="A powerful tool to enable Houdini's declarative API in your svelte+vite projects"
href="/api/kit"
href="/api/plugin"
example={pluginExample}
/>

Expand Down
2 changes: 1 addition & 1 deletion site/src/routes/guides/authentication.svx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function handle({ event, resolve }) {
}
```

The only thing that's left is to use the `session` parameter passed to your client's network function to access the information:
Then, you can use the `session` parameter passed to your client's network function to access the information:

```typescript
/// src/lib/client.ts
Expand Down
3 changes: 1 addition & 2 deletions site/src/routes/guides/caching-data.svx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ A lot of the time we know the value that a mutation will trigger assuming everyt

<button
on:click={() => {
ToggleItemStore.mutate({
variables: { id: itemID },
ToggleItemStore.mutate({ id: itemID }, {
optimisticResponse: {
toggleItem: {
item: {
Expand Down
2 changes: 1 addition & 1 deletion site/src/routes/guides/contributing.svx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ using a suite of integration tests that verify some of the more complex behavior
[integration folder](https://github.com/HoudiniGraphql/houdini/tree/main/integration) at the root of Houdini's repository.

The general idea is to create specific routes in a SvelteKit application that showcase a single behavior and then
use [https://playwright.dev/] to simulate a user interacting with the UI and verify that things are working as expected.
use (Playwright)[https://playwright.dev/] to simulate a user interacting with the UI and verify that things are working as expected.

## Piecing It All Together

Expand Down
14 changes: 7 additions & 7 deletions site/src/routes/guides/faq.svx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Here are some answers to common questions you might have while working with Houd

### Can I use queries in endpoints?

Yep! You can use queries or any document anywhere you can use a svelte store. Just define your query in an external file and use the store api as described in [Query Store](/api/query/store#endpoints) api docs.
Yep! You can use queries or any document anywhere you can use a svelte store. Just define your query in an external file and use the store api as described in [Query Store](/api/query#endpoints) api docs.

### Can I define graphql documents in external files?

Expand Down Expand Up @@ -86,21 +86,21 @@ If you haven't seen Houdini's document stores before, please check out the [Work
### How do I customize the fetching logic on a case-by-case basis?

You should use the `metadata` parameter in the document store to pass arbitrary information into your client's network function. For more information,
please visit [the query store docs](/api/query/store#passing-metadata).
please visit [the query store docs](/api/query#passing-metadata).

### What is this `Generated an empty chunk...` warning from vite?

If you have a route directory that does not contain a `+page.js` file and do not have an inline query in your `+page.svelte`, the
plugin will generate an empty `+page.js` file that is never used. This confuses vite hence the warning. Don't worry - this empty
file is never imported if you don't have an inline query so there's no performance implication.
If you have a route directory that does not contain a `+page.js` file and does not have an inline query in your `+page.svelte`, the
plugin will generate an empty `+page.js` file that is never used. This confuses vite hence the warning. Don't worry - since this empty
file is never imported there are no performance implications.

### My IDE is complaining that the internal directives and fragments don't exist.

Every plugin and editor is different so we can't give you an exact answer but Houdini will write a file inside of the `$houdini` directory that contains all of the custom definitions that it relies on. Be default this file is located at `$houdini/graphql/schema.graphql` and `$houdini/graphql/documents.gql`. You can configure this value in your [config file](/api/config) under the `definitionsPath` value.
Every plugin and editor is different so we can't give you an exact answer but Houdini will write 2 files inside of the `$houdini` directory that contain all of the schema definitions that it relies on. Be default these files are located at `$houdini/graphql/schema.graphql` and `$houdini/graphql/documents.gql`. You can configure this value in your [config file](/api/config) with `definitionsPath`.

### When will version `1.0` be released?

Quick answer is when svelekit gets to `1.0`. Until then, we want to be able to break the API in order to create the most convenient experience for the majority of users.
Quick answer is when SvelteKit gets to `1.0`. Until then, we want to be able to break the API in order to create the most convenient experience for the majority of users.

### Does Houdini support Framework X?

Expand Down
5 changes: 2 additions & 3 deletions site/src/routes/guides/pagination.svx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ and a field that supports cursor-based pagination starting at the end of the lis
```

If you are paginating a field with a cursor-based strategy (forward or backwards), the current page
info can be looked up with the `pageInfo` store returned from the paginated function:
info can be looked up with the `pageInfo` field of store's value:

```svelte
<script>
Expand All @@ -88,8 +88,7 @@ info can be looked up with the `pageInfo` store returned from the paginated func

## Paginated Fragments

`paginatedFragment` functions very similarly to `paginatedQuery` with a few caveats.
Consider the following:
`paginatedFragment` works very much in the same way except for a few caveats. Consider the following:

```javascript
const userWithFriends = paginatedFragment(
Expand Down
6 changes: 3 additions & 3 deletions site/src/routes/guides/release-notes.svx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export async function load(event) {
}
```

This means that when adding a query to a route, tasks like adding a store to a load, pulling that store out of data in your component, etc can be auto completed from just starting with `load_` in your route's load function. It does make the manual logic that uses a fetch result kind of messy since they have to pull out UserInfo but I think that’s a rare situation so I’m in favor of supporting the most people with the clean API and letting the advanced users deal with the complexity.
This means that when adding a query to a route, tasks like adding a store to a load, pulling that store out of data in your component, etc can be auto completed from just starting with `load_` in your route's load function. It does make the manual logic that uses a fetch result kind of messy since they have to pull out UserInfo but we think that’s a rare situation and so we opted to support the most people with the clean API and letting the advanced users deal with the complexity.

There's one more change to the API for users that were manually creating stores using the store factories. Now, you must instantiate new stores with `new MyQueryStore()`.

Expand All @@ -103,7 +103,7 @@ You can now import generated typedefs for all of the special functions you defin
/// src/routes/myProifle/+page.ts

import { graphql } from '$houdini'
import type { AfterLoad } from './$houdini' // <--- relative houdini import gets route information
import type { AfterLoadEvent } from './$houdini'

export const houdini_load = graphql`
query MyProfile {
Expand All @@ -113,7 +113,7 @@ export const houdini_load = graphql`
}
`

export const afterLoad: AfterLoad = ({ data }) => {
export function afterLoad({ data }: AfterLoadEvent) {
console.log(data.MyProfile.viewer.id)
}
```
Expand Down
2 changes: 1 addition & 1 deletion site/src/routes/guides/typescript.svx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ In order to setup your project to take full advantage of Houdini's generated typ

## SvelteKit Routes

When working with Houdini's [generated load functions](/api/kit#generating-route-loads), you can import type definition for your variable functions and hooks from `./$houdini` (a relative import):
When working with Houdini's [generated load functions](/api/query#automatic-loading), you can import type definition for your variable functions and hooks from `./$houdini` (a relative import):

```typescript
/// src/routes/myProifle/+page.ts
Expand Down
6 changes: 3 additions & 3 deletions site/src/routes/guides/working-with-graphql.svx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ query MyProfile {

The reason we recommend this pattern is that it provides a nice balance between editing experience, co-location, and reliable directory structure.
If a route directory contains a `+page.gql` file, we immediately know that the route loads data from our API. When you need to
start doing more complicated things with your queries like variables or custom logic, head over to [plugin docs](/api/kit#generating-route-loads) to see
start doing more complicated things with your queries like variables or custom logic, head over to [plugin docs](/api/query#automatic-loading) to see
how you can customize the load function that houdini will generate for you.

### Fragments
Expand Down Expand Up @@ -314,15 +314,15 @@ by multiple users at the same time. By instantiating a new store on every load,
without any hassle.

Also, be careful when loading multiple stores in a single load. You want to make sure that you aren't blocking one request while you wait for another. For
help in this situation, check out the loadAll function. It's described inside the Deep Dive, <a href="/api/query/store#sveltekit" target="_blank" rel="noreferrer">here</a>.
help in this situation, check out the loadAll function. It's described inside the Deep Dive, <a href="/api/query#manual-loading" target="_blank" rel="noreferrer">here</a>.

</Warning>

### Automatic Loads

On the other hand, maybe you are the kind of person who gets really tired of typing the same code over and over. For those people, Houdini's vite plugin offers some powerful
features that dramatically reduce the amount of boilerplate that you are responsible for. As you'll see there are a few different ways to get houdini to generate a load for you
but they all behave the exact same and can be [customized the same way](/api/kit#generating-route-loads).
but they all behave the exact same and can be [customized the same way](/api/query#automatic-loading).

The first way to tell houdini to generate a load for you is by exporting a `houdini_load` value from `+page.js` that contains one or more query stores that you want to use in your route:

Expand Down
2 changes: 0 additions & 2 deletions src/runtime/lib/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ export class HoudiniClient {
}
}

init() {}

setSession(
event: RequestEvent,
session: // @ts-ignore
Expand Down

1 comment on commit 19b90d5

@vercel
Copy link

@vercel vercel bot commented on 19b90d5 Sep 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.