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

(svelte) - Reimplement @urql/svelte bindings with new API approach #1016

Merged
merged 17 commits into from
Oct 1, 2020

Conversation

kitten
Copy link
Member

@kitten kitten commented Sep 30, 2020

Resolve #1007

This is intended to replace the current Svelte bindings as either a new breaking beta release, or as the stable v1 release.

The initial idea is to move towards an approach that fully encapsulates the OperationResult output and GraphQLRequest input states into one merged Writable store. This store can be observed by components and by operations, e.g. query and subscription.

<script>
  import gql from 'graphql-tag';
  import { operationStore, query } from '@urql/svelte';

  // We initialise out query container, which represents both the query input and result
  const todos = operationStore(gql`
    query ($first: Int!, $skip: Int) {
      todos(first: $first, skip: $skip) {
        id
      }
    }
  `, { first: 10 });

  // We instruct urql to start the query and keep it updated
  // This is called at most once since it's tied to the component lifecycle
  query(todos);

  // We can reactively update the container
  const next = () => {
    $todos.variables.skip = 10;
  };
</script>

{#if $todos.fetching}
  <p>Fetching...</p>
{:else if $todos.error}
  <p>Error! {$todos.error.message}</p>
{:else}
  <ul>
    {#each $todos.data.todos as todo}
      <li>{todo.id}</li>
    {/each}
  </ul>
  <button on:click={next}>Next Page</button>
{/if}

This effectively and intuitively steers users away from pitfalls and covers easy to miss edge cases, where our previous implementation would create memory leaks. This API is focused on providing a single way to do things; this is especially advantageous since client.query shortcut methods and the likes are still accessible.

So overall this focuses on a single primitive to create a value container in Svelte that is only mutable in certain ways (only query, variables, and context can be changed). The other constraint is that operations like query and subscription should be called at most once, which is easy to teach and looks as imperative as most Svelte code does anyway.

Another nice advantage of the OperationStore is that it's both the stateful object and a Svelte writable store in one. It may still be passed around, outside of Svelte components, and can be mutated and read, since it provides getters and setters and prevents changes to result properties to keep things safe.

@changeset-bot
Copy link

changeset-bot bot commented Sep 30, 2020

🦋 Changeset detected

Latest commit: 3c76018

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@urql/svelte Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@frederikhors
Copy link
Contributor

Amazing! Can't wait to try it!

Latest commit is broken.

@kitten kitten force-pushed the refactor/svelte-stable branch 3 times, most recently from d906eea to b2d651e Compare September 30, 2020 12:14
@kitten kitten changed the title WIP: (svelte) - Reimplement @urql/svelte bindings with new API approach (svelte) - Reimplement @urql/svelte bindings with new API approach Sep 30, 2020
@frederikhors
Copy link
Contributor

frederikhors commented Sep 30, 2020

Real-time reproduction with latest commit: https://codesandbox.io/s/urql-svelte-crud-with-new-bindings-rbrsb?file=/List.svelte.

Pending issues:

  1. Still the problem with navigation from / to /todos page. If you reload on /todos page it works.
  2. I don't know how to use mutations

@kitten
Copy link
Member Author

kitten commented Sep 30, 2020

@frederikhors Yep, I think there's a small timing issue still where some synchronous retries lead to our Svelte implementation becoming stuck. But once we fix that this will be ready to go 👍

Edit: Almost forgot; this is what I'm playing around with. But it can also replicate the issue https://codesandbox.io/s/urql-svelte-crud-pollinterval-keeps-calling-forked-lseuf?file=/urql.js

@kitten kitten force-pushed the refactor/svelte-stable branch 2 times, most recently from 326d51d to d540b0f Compare September 30, 2020 15:37
@kitten kitten force-pushed the refactor/svelte-stable branch from d540b0f to c9fa6a6 Compare September 30, 2020 15:50
@kitten
Copy link
Member Author

kitten commented Sep 30, 2020

It's looking pretty fine to me now; the Graphache timing fix for the offlineExchange has been merged to main and this branch has been rebased to keep it clean. https://codesandbox.io/s/urql-svelte-crud-pollinterval-keeps-calling-forked-lseuf?file=/urql.js

Since this is looking very promising I'd like to take some time to write some docs sections for Svelte and ship this branch as the first stable @urql/svelte v1.

@kitten kitten marked this pull request as ready for review September 30, 2020 17:43
@kitten kitten requested review from wgolledge and removed request for wgolledge September 30, 2020 17:43
Copy link
Collaborator

@JoviDeCroock JoviDeCroock left a comment

Choose a reason for hiding this comment

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

This looks awesome

@kitten kitten merged commit 181decf into main Oct 1, 2020
@kitten kitten deleted the refactor/svelte-stable branch October 1, 2020 11:24
@kitten
Copy link
Member Author

kitten commented Oct 1, 2020

This has just been published as @urql/[email protected]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RFC: Intent to implement stable Svelte bindings
3 participants