Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type definitions for loadAll #659

Merged
merged 5 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/poor-avocados-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini-svelte': patch
---

Improve typing for loadAll
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
**/build/**
README.md
.github/**
packages/*/package.json
packages/*/package.json

packages/houdini-svelte/src/runtime/index.ts
4 changes: 2 additions & 2 deletions e2e/_api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
"author": "",
"license": "ISC",
"dependencies": {
"graphql": "^15.5.0",
"@graphql-yoga/node": "^2.13.13",
"@kitql/helper": "^0.5.0",
"graphql": "^15.5.0",
"graphql-relay": "^0.10.0",
"graphql-ws": "^5.8.2",
"@graphql-yoga/node": "^2.13.13",
"ws": "^8.8.1"
}
}
6 changes: 3 additions & 3 deletions e2e/sveltekit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"private": true,
"type": "module",
"scripts": {
"web": "cross-env TZ=utc vite dev --host 0.0.0.0",
"api": "cross-env e2e-api",
"web": "vite dev --host 0.0.0.0",
"api": "cross-env TZ=utc e2e-api",
"dev": "concurrently \"pnpm run web\" \"pnpm run api\" -n \"web,api\" -c \"green,magenta\"",
"build": "vite build",
"package": "svelte-kit package",
"previewWeb": "cross-env TZ=utc vite preview --port 3007",
"previewWeb": "vite preview --port 3007",
"preview": "concurrently \"pnpm run previewWeb\" \"pnpm run api\" -n \"web,api\" -c \"green,magenta\"",
"tests": "playwright test ",
"test": "npm run tests",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
<script lang="ts">
import { MultiUserStore } from '$houdini';
import type { PageData } from './$types';

export let data: PageData;

$: ({ store1, store2 } = data);

const checkTypes = () => {
return (
`${data.store1 instanceof MultiUserStore} ` +
`- ${data.store2 instanceof MultiUserStore} ` +
// @ts-ignore
`- ${data.store3 instanceof MultiUserStore}`
);
};
</script>

<h1>ssr-one-store-multivariables</h1>
Expand All @@ -15,3 +25,7 @@
<div id="result-5">
{$store2.data?.user.id} - {$store2.data?.user.name}
</div>

<div id="result-types">
{checkTypes()}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ test.describe('ssr-one-store-multivariables Page', () => {
await expectToBe(page, 'store-multi-user:1 - Bruce Willis');
await expectToBe(page, 'store-multi-user:5 - Will Smith', 'div[id=result-5]');
});

test('loadAll should brings correct types', async ({ page }) => {
await goto(page, routes.Stores_SSR_One_Store_Multivariables);

await expectToBe(page, 'true - true - false', 'div[id=result-types]');
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"eslint-plugin-unused-imports": "^2.0.0",
"graphql": "*",
"prettier": "^2.5.1",
"prettier": "^2.7.0",
"turbo": "^1.5.4",
"vite": "^3.1.6",
"vitest": "^0.23.4"
Expand Down
23 changes: 23 additions & 0 deletions packages/houdini-svelte/src/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ export * from './session'
type LoadResult = Promise<{ [key: string]: QueryStore<any, {}> }>
type LoadAllInput = LoadResult | Record<string, LoadResult>

// gets all the values from an object
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@revnelson Do you mind adding this block to the loadAll definition in your generated runtime and confirming if it fixes the issue? It seems to work for me but It'd be nice for someone to confirm it

type ValueOf<T extends Record<PropertyKey, unknown>> = T[keyof T]

// transforms `A | B | C | ...` to `A & B & C & ...`
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
? I
: never;

// transforms `LoadResult` into its awaited type
// transforms `{a: LoadResult}` and replaces the key of the load result with `a`
type InferLoadResult<T extends LoadAllInput> = T extends Record<infer Key, infer Res extends LoadResult> ? {
[K in Key]: ValueOf<Awaited<Res>>
} : T extends LoadResult ? Awaited<T> : never

export async function loadAll<
// generic to narrow the array correctly
L extends LoadAllInput,
// generic to get all of the inputs otherwise it fails on the `...`
Loads extends L[]>(
...loads: Loads
): Promise<UnionToIntersection<{
[K in keyof Loads]: InferLoadResult<Loads[K]>
}[number]>>
// putting this here was the only way i could find to reliably avoid import issues
// its really the only thing from lib that users should import so it makes sense to have it here....
export async function loadAll(
Expand Down
Loading