Skip to content

Instantly share code, notes, and snippets.

@sastan
Last active January 15, 2023 00:15
Show Gist options
  • Save sastan/85cf3d011b152a80d3a5933a09df21f6 to your computer and use it in GitHub Desktop.
Save sastan/85cf3d011b152a80d3a5933a09df21f6 to your computer and use it in GitHub Desktop.
sveltekit + urql (extended version)
<script context="module">
import { get, readable } from 'svelte/store'
import { createClient, operationStore } from '@urql/svelte'
import { browser, dev } from '$app/env'
/**
* @type {import('@sveltejs/kit').Load}
*/
export async function load({ fetch, context }) {
const client = await createClient({
// Pass in the fetch from sveltekit to have access to serialized requests during hydration
fetch,
dev: browser && dev,
})
return {
context: {
...context,
client,
// Works just like query from @urql/svelte
query: async (query, variables, context, normalize) => {
const store = operationStore(query, variables, context)
const result = await client.query(store.query, store.variables, store.context).toPromise()
Object.assign(get(store), result)
// Allow to access deep nested object directly at data
if (normalize) {
const { subscribe } = store
return Object.create(store, {
subscribe: {
enumerable: true,
value: readable(store, (set) => {
const unsubscribe = subscribe((result) => {
if (result.data) {
Object.assign(result.data, normalize(result.data, result))
}
set(result)
})
return unsubscribe
}).subscribe,
},
})
}
return store
},
},
props: { client }
}
}
</script>
<script>
import { setClient } from '@urql/svelte'
/**
* @type {import('@urql/svelte').Client}
*/
export let client
setClient(client)
</script>
<slot />
query GetTodos {
viewer {
todos {
id
title
}
}
}
overwrite: true
schema: 'http://localhost:5000/-/graphql'
documents: 'src/**/*.graphql'
generates:
./graphql.schema.json:
plugins:
- introspection
src/lib/graphql.ts:
plugins:
- add:
content:
- '// THIS FILE IS GENERATED, DO NOT EDIT!'
- '/* eslint-disable */'
- typescript
src/:
preset: near-operation-file
presetConfig:
baseTypesPath: ~$lib/graphql
extension: .gql.ts
plugins:
- add:
content:
- '// THIS FILE IS GENERATED, DO NOT EDIT!'
- '/* eslint-disable */'
- typescript-operations
- typed-document-node
config:
# addOperationExport: true
flattenGeneratedTypes: true
config:
# use "import type" instead of "import"
useTypeImports: true
# turn enums into types
enumsAsTypes: true
omitOperationSuffix: true
dedupeOperationSuffix: true
exportFragmentSpreadSubTypes: true
experimentalFragmentVariables: true
addUnderscoreToArgsType: true
# onlyOperationTypes: true
preResolveTypes: true
namingConvention: keep
scalars:
UnsignedInt: number
URL: string
JSON: any # string | number | boolean | null | Array<Scalars['JSON']> | Scalars['JSONObject']
JSONObject: Record<string, any>
Date: string
DateTime: string
hooks:
afterAllFileWrite:
- prettier --write
<script context="module">
// Generated with @graphql-codegen/cli
import * as gql from '_index.gql'
export async function load({ context }) {
return {
props: {
todos: await context.query(
gql.GetTodosDocument,
{ /* variables */},
{ additionalTypenames: [ /* ... */ ] },
// Result merged in to data -> todos.data.todos
(data) => data.viewer
),
},
}
}
</script>
<script>
import { query } from '@urql/svelte'
/**
* @type {import('./types').OperationStore<gql.GetTodosDocument, gql.GetTodos['viewer']['todos']>}
*/
export let todos
// Setup subscription for the lifetime of the component
query(todos)
// Data is normalized
assert($todos.data.viewer.todos === $todos.data.todos)
</script>
{
"// Only fields relevant for example included": "",
"scripts": {
"graphql": "graphql-codegen --config codegen.yml"
},
"devDependencies": {
"@graphql-codegen/add": "^2.0.2",
"@graphql-codegen/cli": "1.21.3",
"@graphql-codegen/introspection": "1.18.1",
"@graphql-codegen/near-operation-file-preset": "^1.17.13",
"@graphql-codegen/typed-document-node": "^1.18.4",
"@graphql-codegen/typescript": "^1.21.1",
"@graphql-codegen/typescript-operations": "^1.17.15",
"typescript": "^4.0.0"
},
"type": "module",
"engines": {
"node": ">= 12.17.0"
},
"dependencies": {
"@urql/svelte": "^1.2.0",
"graphql": "^15.5.0"
}
}
import type * as urql from '@urql/svelte'
import type { TypedDocumentNode } from '@graphql-typed-document-node/core'
export type OperationStore<
T extends TypedDocumentNode = any,
Normalized = object
> = T extends TypedDocumentNode<infer Data, infer Vars>
? urql.OperationStore<Data & Normalized, Vars>
: never
@souravjamwal77
Copy link

Hi Everyone, I have a graphql backend from which I can get the token, refreshToken using mutation but how do I pass that to each request query?
How do I persist session and how exactly does login/authentication flow will work for a sveltekit app? Please, if anyone has any ideas do let me know.

@kakashy
Copy link

kakashy commented Apr 15, 2022

Hey all,
context as a load parameter was renamed to stuff, see this SK issue.

An updated gist can be found here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment