Skip to content

Instantly share code, notes, and snippets.

@kakashy
Forked from sastan/$layout.svelte
Last active May 2, 2022 10:03
Show Gist options
  • Save kakashy/06a99258698509898b4de6df099fe0ae to your computer and use it in GitHub Desktop.
Save kakashy/06a99258698509898b4de6df099fe0ae 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, stuff }) {
const client = await createClient({
// Pass in the fetch from sveltekit to have access to serialized requests during hydration
fetch,
dev: browser && dev,
})
return {
stuff: {
...stuff,
client,
// Works just like query from @urql/svelte
query: async (query, variables, stuff, normalize) => {
const store = operationStore(query, variables, stuff)
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment