houdinigraphql / houdini Goto Github PK
View Code? Open in Web Editor NEWThe disappearing GraphQL client
Home Page: http://www.houdinigraphql.com
License: MIT License
The disappearing GraphQL client
Home Page: http://www.houdinigraphql.com
License: MIT License
If we can detect their name we can generate them instead of bloating the schema unnecessarily which will slow down the rest of the pipeline
Getting started with Houdini on Sapper throws the following error
Unexpected token *
In an existing sapper project
yarn add -D houdini houdini-preprocess
npx houdini init
Unexpected token *
System Info
System:
OS: macOS 11.4
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Memory: 1.54 GB / 16.00 GB
Shell: 5.8 - /bin/zsh
npmPackages:
@babel/core: ^7.13.16 => 7.13.16
@babel/plugin-syntax-dynamic-import: ^7.8.3 => 7.8.3
@babel/plugin-transform-runtime: ^7.13.15 => 7.13.15
@babel/preset-env: ^7.13.15 => 7.13.15
@babel/runtime: ^7.13.17 => 7.13.17
@rollup/plugin-babel: ^5.3.0 => 5.3.0
@rollup/plugin-commonjs: ^18.0.0 => 18.0.0
@rollup/plugin-node-resolve: ^11.2.1 => 11.2.1
@rollup/plugin-replace: ^2.4.2 => 2.4.2
@rollup/plugin-url: ^6.0.0 => 6.0.0
compression: ^1.7.4 => 1.7.4
houdini: ^0.7.1 => 0.7.1
houdini-preprocess: ^0.7.1 => 0.7.1
npm-check-updates: ^11.5.1 => 11.5.1
polka: next => 1.0.0-next.14
qrcode: ^1.4.4 => 1.4.4
qrcode-svg: ^1.1.0 => 1.1.0
rollup: ^2.45.2 => 2.45.2
rollup-plugin-svelte: ^7.1.0 => 7.1.0
rollup-plugin-terser: ^7.0.2 => 7.0.2
sapper: ^0.29.1 => 0.29.1
sirv: ^1.0.11 => 1.0.11
svelte: ^3.37.0 => 3.37.0
svelte-qrcode: ^1.0.0 => 1.0.0
We should be able to know all of the valid types for values to cache.list
and when
.
From reading the documentation it's not clear if/ how this can be used within a bare Svelte app.
If this is possible, how would one use Houdini without using Sapper (i.e. only having a simple Svelte app). If this is currently not possible, why not (and how could that be changed, e.g. if I wanted to submit a PR)?
Queries sometimes need to be refetched, possibly with new arguments
While implementing 'refetch queries' i noticed that the session passed to fetchQuery is a svelte store on the client side, it works fine in load
which makes sense.
If you add this log to the example
async function fetchQuery({ text, variables = {} }, session: any) {
console.log(session)
const result = await this.fetch('http://' + API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: text,
variables,
}),
})
// parse the result as json
return await result.json()
}
You can see that session is {subscribe: ƒ, set: ƒ, update: ƒ}
We should probably use get
from svelte/store in mutations and refetch.
Atm, there is no way for the user to issue a redirect based on the result of a query since the preload is totally hidden.
Situation: A list of items is retrieved at load (Active_Items). A subscription fetches the latest item that appears on the server (NewItem). The Insert method within the Subscription adds the latest item to the list, BUT because the latest item is already included in the Active_Items list Svelte generates the following error:
Error: Cannot have duplicate keys in a keyed each
Alas, some Graphql server implementations don't provide an easy way to limit subscriptions only to mutate events so they'll start by pulling the latest item. Ideally the Insert method would filter out duplicate ids to avoid this issue.
Thoughts or suggestions? I can probably figure out a workaround with my graphl server (Dgraph) but thought I'd mention the challenge here.
We should probably improve the subscription documentation to include some common patterns:
Hi!
Along with support for .json
schemas, will there be support for .graphql
schemas?
Houdini needs a way to specify how to marshal/unmarshal scalars found in documents
We can compare the string passed to the template tag with a hash in the compiled document to make sure they match.
probably worth checking if process.env.NODE === 'production'
first
In the latest sveltekit, there seem to have been several changes. There is no client.js or server.js anymore. Also, the svelte config is different and snowpack has been replaced by vite.
If an error is modeled as part of a mutation output type, the runtime should throw an exception if the error is non-null
I was on the 0.5.1-kit.5 release previously and my primary queries were working (though I was still struggling with subscriptions). I upgraded to latest, regenerated the schema, and now I am getting the following error, even after simplifying my schema to a single test query.
Cannot convert undefined or null to object
TypeError: Cannot convert undefined or null to object
at Function.entries (<anonymous>)
at Cache._write (/$houdini/runtime/cache/cache.js:232:45)
at Cache.write (/$houdini/runtime/cache/cache.js:19:14)
at Object.writeData (/$houdini/runtime/query.js:58:19)
at index.svelte:60:35
at Object.$$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at Object.default (root.svelte:33:46)
at eval (<PATH>src/routes/__layout.svelte:44:36)
at Object.$$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at root.svelte:31:44
Hey i updated houdini from kit.6 to kit.8 and now my language server can't run. It gives me the error graphql.buildClientSchema
is not a function. So hooked into the houdini-common package and if i console.log(graphql)
it has a nested default
.
houdini-common/build/esm/index.js
import * as graphql from 'graphql';
console.log(graphql);
[Module] {
default: {
version: [Getter],
versionInfo: [Getter],
graphql: [Getter],
graphqlSync: [Getter],
GraphQLSchema: [Getter],
GraphQLDirective: [Getter],
GraphQLScalarType: [Getter],
GraphQLObjectType: [Getter],
GraphQLInterfaceType: [Getter],
GraphQLUnionType: [Getter],
GraphQLEnumType: [Getter],
GraphQLInputObjectType: [Getter],
GraphQLList: [Getter],
GraphQLNonNull: [Getter],
specifiedScalarTypes: [Getter],
GraphQLInt: [Getter],
GraphQLFloat: [Getter],
GraphQLString: [Getter],
GraphQLBoolean: [Getter],
GraphQLID: [Getter],
specifiedDirectives: [Getter],
GraphQLIncludeDirective: [Getter],
GraphQLSkipDirective: [Getter],
GraphQLDeprecatedDirective: [Getter],
GraphQLSpecifiedByDirective: [Getter],
TypeKind: [Getter],
DEFAULT_DEPRECATION_REASON: [Getter],
introspectionTypes: [Getter],
__Schema: [Getter],
__Directive: [Getter],
__DirectiveLocation: [Getter],
__Type: [Getter],
__Field: [Getter],
__InputValue: [Getter],
__EnumValue: [Getter],
__TypeKind: [Getter],
SchemaMetaFieldDef: [Getter],
TypeMetaFieldDef: [Getter],
TypeNameMetaFieldDef: [Getter],
isSchema: [Getter],
isDirective: [Getter],
isType: [Getter],
isScalarType: [Getter],
isObjectType: [Getter],
isInterfaceType: [Getter],
isUnionType: [Getter],
isEnumType: [Getter],
isInputObjectType: [Getter],
isListType: [Getter],
isNonNullType: [Getter],
isInputType: [Getter],
isOutputType: [Getter],
isLeafType: [Getter],
isCompositeType: [Getter],
isAbstractType: [Getter],
isWrappingType: [Getter],
isNullableType: [Getter],
isNamedType: [Getter],
isRequiredArgument: [Getter],
isRequiredInputField: [Getter],
isSpecifiedScalarType: [Getter],
isIntrospectionType: [Getter],
isSpecifiedDirective: [Getter],
assertSchema: [Getter],
assertDirective: [Getter],
assertType: [Getter],
assertScalarType: [Getter],
assertObjectType: [Getter],
assertInterfaceType: [Getter],
assertUnionType: [Getter],
assertEnumType: [Getter],
assertInputObjectType: [Getter],
assertListType: [Getter],
assertNonNullType: [Getter],
assertInputType: [Getter],
assertOutputType: [Getter],
assertLeafType: [Getter],
assertCompositeType: [Getter],
assertAbstractType: [Getter],
assertWrappingType: [Getter],
assertNullableType: [Getter],
assertNamedType: [Getter],
getNullableType: [Getter],
getNamedType: [Getter],
validateSchema: [Getter],
assertValidSchema: [Getter],
Token: [Getter],
Source: [Getter],
Location: [Getter],
getLocation: [Getter],
printLocation: [Getter],
printSourceLocation: [Getter],
Lexer: [Getter],
TokenKind: [Getter],
parse: [Getter],
parseValue: [Getter],
parseType: [Getter],
print: [Getter],
visit: [Getter],
visitInParallel: [Getter],
getVisitFn: [Getter],
BREAK: [Getter],
Kind: [Getter],
DirectiveLocation: [Getter],
isDefinitionNode: [Getter],
isExecutableDefinitionNode: [Getter],
isSelectionNode: [Getter],
isValueNode: [Getter],
isTypeNode: [Getter],
isTypeSystemDefinitionNode: [Getter],
isTypeDefinitionNode: [Getter],
isTypeSystemExtensionNode: [Getter],
isTypeExtensionNode: [Getter],
execute: [Getter],
executeSync: [Getter],
defaultFieldResolver: [Getter],
defaultTypeResolver: [Getter],
responsePathAsArray: [Getter],
getDirectiveValues: [Getter],
subscribe: [Getter],
createSourceEventStream: [Getter],
validate: [Getter],
ValidationContext: [Getter],
specifiedRules: [Getter],
ExecutableDefinitionsRule: [Getter],
FieldsOnCorrectTypeRule: [Getter],
FragmentsOnCompositeTypesRule: [Getter],
KnownArgumentNamesRule: [Getter],
KnownDirectivesRule: [Getter],
KnownFragmentNamesRule: [Getter],
KnownTypeNamesRule: [Getter],
LoneAnonymousOperationRule: [Getter],
NoFragmentCyclesRule: [Getter],
NoUndefinedVariablesRule: [Getter],
NoUnusedFragmentsRule: [Getter],
NoUnusedVariablesRule: [Getter],
OverlappingFieldsCanBeMergedRule: [Getter],
PossibleFragmentSpreadsRule: [Getter],
ProvidedRequiredArgumentsRule: [Getter],
ScalarLeafsRule: [Getter],
SingleFieldSubscriptionsRule: [Getter],
UniqueArgumentNamesRule: [Getter],
UniqueDirectivesPerLocationRule: [Getter],
UniqueFragmentNamesRule: [Getter],
UniqueInputFieldNamesRule: [Getter],
UniqueOperationNamesRule: [Getter],
UniqueVariableNamesRule: [Getter],
ValuesOfCorrectTypeRule: [Getter],
VariablesAreInputTypesRule: [Getter],
VariablesInAllowedPositionRule: [Getter],
LoneSchemaDefinitionRule: [Getter],
UniqueOperationTypesRule: [Getter],
UniqueTypeNamesRule: [Getter],
UniqueEnumValueNamesRule: [Getter],
UniqueFieldDefinitionNamesRule: [Getter],
UniqueDirectiveNamesRule: [Getter],
PossibleTypeExtensionsRule: [Getter],
NoDeprecatedCustomRule: [Getter],
NoSchemaIntrospectionCustomRule: [Getter],
GraphQLError: [Getter],
syntaxError: [Getter],
locatedError: [Getter],
printError: [Getter],
formatError: [Getter],
getIntrospectionQuery: [Getter],
getOperationAST: [Getter],
getOperationRootType: [Getter],
introspectionFromSchema: [Getter],
buildClientSchema: [Getter],
buildASTSchema: [Getter],
buildSchema: [Getter],
getDescription: [Getter],
extendSchema: [Getter],
lexicographicSortSchema: [Getter],
printSchema: [Getter],
printType: [Getter],
printIntrospectionSchema: [Getter],
typeFromAST: [Getter],
valueFromAST: [Getter],
valueFromASTUntyped: [Getter],
astFromValue: [Getter],
TypeInfo: [Getter],
visitWithTypeInfo: [Getter],
coerceInputValue: [Getter],
concatAST: [Getter],
separateOperations: [Getter],
stripIgnoredCharacters: [Getter],
isEqualType: [Getter],
isTypeSubTypeOf: [Getter],
doTypesOverlap: [Getter],
assertValidName: [Getter],
isValidNameError: [Getter],
BreakingChangeType: [Getter],
DangerousChangeType: [Getter],
findBreakingChanges: [Getter],
findDangerousChanges: [Getter],
findDeprecatedUsages: [Getter]
}
}
Do you have an idea why?
When I run npx houdini generate
I'm now getting an error as follows:
SyntaxError: Unterminated regular expression (32:3)
at Object._raise (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:1871:17)
at Object.raiseWithData (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:1864:17)
at Object.raise (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:1832:17)
at Object.readRegexp (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:9880:20)
at Object.readToken_slash (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:9492:12)
at Object.getTokenFromCode (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:9808:14)
at Object.getTokenFromCode (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:8646:20)
at Object.nextToken (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:9331:12)
at Object.parse (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:14929:10)
at parse$1$1 (<APPLICATION_PATH>/node_modules/houdini/build/cmd.js:14984:38) {
loc: Position$1 { line: 32, column: 3 },
pos: 822
Running latest 0.8.0
. Does this error map to any known issues?
Before we push documents through the compiler, we should first run a few validators:
id
aliasesI've recently updated my schema to be closer to that in the Example. When running the compiler one of my mutations started generating an error: "Too Many Wrappers" (full error at the bottom of this post). I confirmed (after some experimental surgery on the schema) that the issue is the two-way edge between Recipe and User types. Is there any reason the following schema should not work?
type Recipe {
id: ID!
title: String!
myTitle: String
description: String
domain: String
created: Float
updated: Float
user(filter: UserFilter): User! @hasInverse(field: recipes)
archived: Boolean!
webRecipeID: String
recipeStructure: String
totalTime: String
img: String
klImages: String
}
type User {
id: ID!
displayName: String
email: String!
emailVerified: Boolean
loginProvider: String
photoURL: String
created: Float
lastSignIn: Float
recipes(filter: RecipeFilter, order: RecipeOrder, first: Int, offset: Int): [Recipe] @hasInverse(field: user)
recipesAggregate(filter: RecipeFilter): RecipeAggregateResult
}
Once I removed the recipes reference on User the error cleared up. Here's the working schema.
type Recipe {
id: ID!
title: String!
myTitle: String
description: String
domain: String
created: Float
updated: Float
user(filter: UserFilter): User!
archived: Boolean!
webRecipeID: String
recipeStructure: String
totalTime: String
img: String
klImages: String
}
type User {
id: ID!
displayName: String
email: String!
emailVerified: Boolean
loginProvider: String
photoURL: String
created: Float
lastSignIn: Float
}
In case, it's helpful, here's the Type definition that was directly spawning the error (I didn't get an error when running standard queries).
type Mutation {
addRecipe(input: [AddRecipeInput!]!): AddRecipePayload
}
And the mutation:
const addRecipe = mutation<AddRecipe>(graphql`
mutation AddRecipe($input: AddRecipeInput!) {
addRecipe(input: [$input]) {
recipe {
id
}
}
}
`);
Here's the error:
Error: Too many wrappers: undefined
at inputType (file:///<PATH>/node_modules/houdini/build/cmd.js:58505:15)
at file:///<PATH>/node_modules/houdini/build/cmd.js:58526:34
at Array.map (<anonymous>)
at inputType (file:///<PATH>/node_modules/houdini/build/cmd.js:58523:78)
at file:///<PATH>/node_modules/houdini/build/cmd.js:58526:34
at Array.map (<anonymous>)
at inputType (file:///<PATH>/node_modules/houdini/build/cmd.js:58523:78)
at file:///<PATH>/node_modules/houdini/build/cmd.js:58457:137
at Array.map (<anonymous>)
at file:///<PATH>/node_modules/houdini/build/cmd.js:58455:185
I'm using houdini with svelte-kit.
I have a graphql endpoint that only contains queries, no mutations, no subscriptions.
I don't get any error running npx houdini generate -p
.
But when I run npm run dev
, I'm getting the following error on the webpage:
Error: Could not find operation type
at file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:33667:31
at step (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:109:23)
at Object.next (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:90:53)
at file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:83:71
at new Promise (<anonymous>)
at __awaiter (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:79:12)
at mutationProcessor (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-preprocess/build/esm/index.js:33656:12)
at file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-common/build/esm/index.js:114:42
at step (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-common/build/esm/index.js:66:23)
at Object.next (file:///home/anonymous/Documents/Sveltekit_Projects/e-commerce/node_modules/houdini-common/build/esm/index.js:47:53)
I have not yet had success with fetch queries to my remote graphql server (Hasura). I'm getting a Cannot read property 'data' of undefined
error, and after adding logging to the environment.js my best guess is that it's not even attempting to fetch since the logging isn't appearing. I'm not clear on the best way to debug this issue, and am hoping a solution here will help others.
My query is adapted straight from the documentation:
import { query, graphql, AllUsers } from '$houdini';
const { data } = query<AllUsers>(graphql`
query AllUsers {
kl_users {
email
uid
}
}
`);
and the error is:
Cannot read property 'data' of undefined
TypeError: Cannot read property 'data' of undefined
at Module.query (/$houdini/runtime/query.js:15:48)
at Login.svelte:33:29
at Object.$$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at eval (/src/lib/layout/Header.svelte:15:115)
at Object.$$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at eval (<PATH>/src/routes/$layout.svelte:42:94)
at Object.$$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at root.svelte:31:44
at $$render (<PATH>/node_modules/svelte/internal/index.js:1380:22)
at Object.render (<PATH>/node_modules/svelte/internal/index.js:1388:26)
I'm not quite sure what the API should look like, but there should be some kind of support for interacting with connections that have the usual pagination args.
I would like to discuss if we want to support persisted queries in the future. I like how relay handles it and personally i find them quite powerful in terms of security and saving bytes on network requests:
I'm getting errors on a few fields that are not one of the standard types when I use them in queries. Is there a recommended best way to handle the translation of extended types to types that Houdini can deal with?
Error: Could not convert scalar type: jsonb
Error: Could not convert scalar type: numeric
There are a few places where the codebase assumes that id
is the magic field that can be used to identify an identity. This should be generalized to allow for any field (or a list of fields) to be used
This is a super cool package and I love the idea of using the preprocess step. Genius!
I was curious if subscription support is planned. Is there a roadmap of features you'd like to have that I can refer to for these types of questions?
I'm struggling to get houdini generate
to work on my codebase. Hitting lots of errors without any clue which file they come from. I'm not sure if the problem is from svelte or houdini. For example:
route.svelte
<script>
export let scriptPath = '/blah';
</script>
<svelte:head>
<script src={scriptPath}></script>
</svelte:head>
output:
$ npm run generate
> [email protected] generate /Users/george/client/sveltekit
> houdini generate
SyntaxError: Unexpected token s in JSON at position 1
at JSON.parse (<anonymous>)
at file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:15129:31
at Array.map (<anonymous>)
at findAttributes (file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:15121:14)
at parseFile (file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:15063:29)
at file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:59191:54
at step (file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:124:23)
at Object.next (file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:105:53)
at fulfilled (file:///Users/george/client/sveltekit/node_modules/houdini/build/cmd.js:95:58)
Putting in some logging in the top stacktrace location, I see that it's trying to run JSON.parse('{scriptPath}')
, which was never going to work.
This same code works fine in Sveltekit, so I don't know where things have gone wrong.
We need a way to specify arguments for fragments.
A possible API for declaring arguments:
fragment UserAvatar on User @arguments(width: { "defaultValue": "2", type: "Int"}) {
profilePicture(width: $width)
}
And for passing values:
fragment AnotherFragment on Query {
viewer {
...UserAvatar @with(width: "2")
}
}
Connections are tagged in queries:
query AllItems {
items @connection(name:"All_Items") {
id
completed
...ItemEntry_item
}
}
Which generates a fragment that can be mixed into a mutation (mutations only) to indicate that a result should be added to the connection (ensuring all of the data is present for free):
mutation AddTodoItem($input: AddTodoItemInput!) {
addTodoItem(input: $input) {
item {
...All_Items_Connection
}
}
}
Currently each query holds onto its results in a separate document, this forces the mutation runtime to iterate over many different documents. A normalized cache that queries/fragments subscribe to would dramatically simplify the query/mutation interaction as well as reduce bundle size since individual patches don't need to track every little detail
Houdini needs to provide the user a way to interact with the cache imperatively to handle situations that aren't covered by the declarative API
I believe I followed the setup steps to the letter, but I'm hoping this issue is something straightforward that I'm missing.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: <PATH>/houdini.config.js
require() of ES modules is not supported.
require() of <PATH>/houdini.config.js from <PATH>/node_modules/houdini-common/build/cjs/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename houdini.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from <PATH>/package.json.
FYI, If I remove the "type":"module" line from package.json it errors out with Cannot use import statement outside a module
related to the line in houdini.config: import path from 'path'
This has two benefits:
goTo
functionWould supporting SvelteKit's adapter-static
SPA mode be something you are willing to do? Currently the runtime does not work, expecting things like document.initialValue
to be set but is not because there is no SSR hydration.
Quite a few people, myself included, embed the static assets into binaries we ship as part of the release process because we use languages that do not support SSR. In my case, that's embedding the assets in a Go application and serving them with an embedded file server.
Original SPA mode PR: sveltejs/kit#1181
Hi Alec, I've implemented the subscription to a point: it is receiving updates from the graphql server. I can observe the update being received in the console. However, when I attempt to use the pattern in the example project the component is not updating--probably because my schema isn't similar enough for it to be intuitive. I'd love to help refine the documentation but I need to get over the hump of understanding. I think part of the challenge is that you're using a very different pattern than the Apollo/React hook [https://hasura.io/learn/graphql/react/subscriptions/3-create-subscription/] that many of us are familiar with (naturally, as this is Svelte-optimized). I'm wondering if we can start with more of an analog to that simpler example to bridge the gap.
Let's say we have a graphql query just like you have it in the example project. It pulls a list of items like so:
const { data } = query<AllMyItems>(graphql`
query AllMyItems($uid: ID!) {
allItems: myItems(where: { uid: { _eq: $uid }, archived: { _eq: false } })
{
id
...Card_item
}
}
`);
We list the results in generic Svelte form:
{#each $data.allItems as item (item.id)}
<Card {item} />
{/each}
With Houdini, how can we create a subscription for the allItems
list query instead of at the level of the component/fragment as you have it in the example? I want to do something like the following, but I'm not sure what the pattern is for connecting to the Houdini object/cache.
subscription(
graphql`
subscription ItemUpdate($uid: ID!) {
myItems(where: { uid: { _eq: $uid } }) {
id
...Card_item
}
}
`,
{
uid: $session.user.uid
}
);
My best idea is to assign the outputs of the original query to a new svelte store and then update it when the subscription detects a change. But I'm not yet sure of how to access the updated values from the subscription function, as it doesn't work to treat it as a store.
Hey im currently playing around with houdini, trying mutations etc. and learning stuff but it seems like the schema.json doesn't get updated when i run generate? Does houdini currently offer a way to update the schema? Or do i have to update it myself?
I could probably create a pull request in the next days, lets say we pass --pull
to the generate command to pull the newest schema before generating?
Atm if multiple fragments are mixed into the same mutation, every field will be copied into the corresponding connection stores. we might want to make sure we run some sort of selector on the record we add
Hi.
Thanks for this very interesting library. I'm having a play with it with Sveltekit. I'd love to work out how to achieve a npm run watch
script which would detect changes to GraphQL query instructions in .svelte
files, and would run houdini generate
and then restart the sveltekit server (or, ideally, somehow inform Vite that the files have changed).
It seems like it'd be simple, and indeed it mostly works with something like chokidar
or nodemon
, except that because Houdini seems to replace all the files in $houdini
, rather than just the files which have changed, the sveltekit server restarts far too often.
I wonder if it's possible to improve the writing of files to only update the changed ones, or if you know of a solution to achieve the same effect?
Hi!
While trying to setup houdini, I got this error on houdini generate
(node:12660) UnhandledPromiseRejectionWarning: Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only file and data URLs are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:782:11)
at Loader.resolve (internal/modules/esm/loader.js:88:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:241:28)
at Loader.import (internal/modules/esm/loader.js:176:28)
at importModuleDynamically (internal/modules/esm/translators.js:114:35)
at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:30:14)
at file:///C:/.../node_modules/houdini/build/cmd.js:937:49
at step (file:///C:/.../node_modules/houdini/build/cmd.js:346:23)
at Object.next (file:///C:/.../node_modules/houdini/build/cmd.js:327:53)
at file:///C:/.../node_modules/houdini/build/cmd.js:320:71
some of my devdeps
"@sveltejs/kit": "1.0.0-next.107",
"houdini": "^0.5.1-kit.6",
"houdini-preprocess": "^0.5.1-kit.6",
"typescript": "4.3.1-rc"
"svelte": "3.38.2",
Does this error means it isn't focused on windows yet, or is it something wrong on my side?
The following is an apparent bug in the way that the Houdini subscription function responds to certain events.
I have a Query and a corresponding subscription set up to receive updates when a list of objects changes. I am observing the responses at both the websocket event level, and the Houdini cache level. In both these cases I see that the list updates as expected when properties on objects are changed, AND when objects are added or removed from the set.
However, the reactive value of { data } on the Query is not updating when items are added or removed, though it is when properties on objects are altered.
I was unable to validate that this same behavior exists on the Example app due to an error I'm having with Apollo server locally, but this would be a natural place to confirm this is not specific to my project. To test this I would add and remove items on the database itself and confirm whether these changes are reflected on the SvelteKit page.
At the moment it feels like there is quite a bit of scaffolding going on. When you create a new mutation/query on the backend, you have to either npx houdini init
all over, or write the corresponding mutation/query in your schema.gql file and npx houdini generate
. And then you again have to write the mutation/query template string when you want to call it.
I think it would be great if it worked something like graphql-code-generator (see the live example, and choose "operation types" in the dropdown), where you write your mutation/query in some file, run some generation script, and then you get the types and the gql template string. In other words. In stead of the current schema.gql file, where you write types, I suggest the following:
You have a bunch of files with mutations/queries, that you would otherwise write in your template strings like this file
# helloQuery.gql
query Hello($name: String!) {
hello(name: $name) {
returnedStuff
}
}
And then you can run generate on all those files, and it would generate the types as it does now, i.e. import {Hello, Hello$result} from '$houdini'
, but it would then also create a HelloDocument
like in graphql-code-generator, that is just the template string, and then you would maybe not even need Hello
. E.g. you would then do
<script lang="ts">
import { query, graphql, HelloDocument } from '$houdini';
// Before you had to say query<Hello>, but that gets infered here.
const { data } = query(HelloDocument);
// $data is now inferred to be of type Hello$result.
</script>
That way you only write the mutation/query one time, and the types are more elegantly generated. Also, it is easier to write your schema.gql file, as you don't have to write all the types explicitly.
Users need to be given access to the variables provided in sapper's preload
function. Current best approach is something like
<script lang="ts">
import { query, graphql } from 'houdini'
import type { AllItems, AllItems$input } from 'generated'
const data = query<AllItems>(graphql`
query AllItems($filter: ItemFilter!) {
items(filter: $filter) {
id
completed
...ItemEntry_item
}
}
`)
</script>
<script context="module" lang="ts">
export function queryVariables(page, session): AllItems$input {
return {
filter: { ... }
}
}
</script>
having the definition in module makes sure that any references or logic won't have to be hoisted
I have a error when trying fetching data with basic code from example:
index.svelte
<script lang="ts">
import { query, graphql, AllProducts } from '$houdini';
// load the items
const { data } = query<AllProducts>(graphql`
query AllProducts {
allProducts {
name
}
}
`);
</script>
Message error:
Error: Function called outside component initialization
at get_current_component (/home/domitori/project/node_modules/svelte/internal/index.js:652:18)
at Object.setContext (/home/domitori/project/node_modules/svelte/internal/index.js:682:25)
at Object.setVariables (/home/domitori/project/src/node_modules/$houdini/runtime/context.js:5:63)
at Object.query (/home/domitori/project/src/node_modules/$houdini/runtime/query.js:19:26)
at /home/domitori/project/src/routes/index.svelte:34:32
at Object.$$render (/home/domitori/project/node_modules/svelte/internal/index.mjs:1366:23)
at Object.default (/home/domitori/project/src/node_modules/@sapper/internal/App.svelte:20:50)
at /home/domitori/project/__sapper__/dev/server/server.js:4174:38
at Object.$$render (/home/domitori/project/node_modules/svelte/internal/index.mjs:1366:23)
at /home/domitori/project/src/node_modules/@sapper/internal/App.svelte:16:18
I use template tonyketcham/sapper-tailwind2-template as local
Graphql server from local keystone
Subscriptions need the same treatment for variables that queries do
Hi!
When a svelte file has lang='ts'
instead of lang="ts"
, it is getting:
SyntaxError: Unexpected token ' in JSON at position 0 at JSON.parse (<anonymous>)
JSON.parse("'ts'")
produces error, but
JSON.parse('"ts"')
don't
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.