gqty-dev / gqty

The No-GraphQL Client for TypeScript
https://gqty.dev
MIT License
892 stars 26 forks source link

Roadmaps! #1247

Open vicary opened 1 year ago

vicary commented 1 year ago

You may know me as a low-key maintainer, that I have been putting this on maintenance mode for a while.

With a nod from @PabloSzx, we are now open to sponsors!

It means a few things,

  1. More dedicated time on this project
  2. More directional decisions can be made by the team
  3. We get to buy coffee from sponsors! ☕️

There are long due features, bug fixes, and a lot of maintenance work to be done.

Yes I hear you! All of you!

To keep things super transparent, I am sharing the roadmap in my mind. The items will be slowly convert into tracking issues as I work on them.

Don't be shy to share your thoughts to shape the future of gqty!


  1. 1544

  2. Upkeep
    1. Dependencies upgrade and cleanup
      1. 1282

      2. 1456

      3. 1430

      4. 1460

    2. Bug fixes
      1. 1474

      2. 1757

    3. Fix stuck tests in PRs
  3. A Grand Unified Query
    1. 1468

      1. 1470

    2. Integrate useLazyQuery into useQuery
      1. Depends on #1544
    3. Integrate useTransactionQuery into useQuery
    4. Integrate usePaginatedQuery into useQuery
    5. Support FetchPolicy option in useQuery
  4. useSimpleMutation
  5. 1341

    1. doc: Selection functions in query, mutation and subscription maybe called multiple times.
  6. Cache last selections for empty arrays
  7. https://github.com/gqty-dev/gqty/issues/1754
  8. A smooth DX
    1. Development mode:
      1. [ ] @gqty/cli should perform a version check on installed versions of gqty and @gqty/* and prompt for an upgrade in needed.
      2. [x] autocodegen via watch and/or polling
      3. [ ] Static query generation (like inline snapshots in jest)
    2. monorepo examples
  9. A mocking solution
    1. 876

    2. 1276

    3. 1281

      1. Depends on scoped query
    4. Mockable fetcher
    5. Mockable cache
  10. Transactional snapshots for manual cache changes, for mutation errors when used with optimist response.
  11. [x] Improve error handling in the generated client
  12. Custom scalar resolvers, working in tandem with scalarTypes.
  13. [x] Expose extensions option in react hooks for auth.
  14. [x] Revise core API for subscriptions
  15. 448

  16. Expand frameworks support
    1. React Native (Hermes) #1179
    2. preact
    3. deno (fresh/preact)
    4. svelt #1185
    5. vue
    6. solid
    7. astro
  17. Embrace React 18
    1. [x] Improving support for the render-as-you-fetch pattern (i.e. rework useTransactionQuery)
      1. (docs) useQuery({ prepare, suspense: true }) = suspense on first render
    2. [x] Server components
    3. [ ] SSR with Suspense renderToPipeableStream
    4. [ ] Use isPending in useTransition for the isLoading state, reducing unnecessary Suspense.
  18. 1602

  19. Refactoring
    1. [x] Reveal upstream dependencies over copied utilities
      1. lodash-es
      2. cycle.ts
    2. [x] Replace refetch and noCache option with cachePolicy in core.
    3. [x] Find out the reason for the following redundancy,
      1. buildQuery(type)
      2. selectionList[0].type
      3. selectionList[0].key
    4. [x] Try replacing selection scheduler with imperative chaining and a modified query fetcher (batching).
    5. [x] Generalize isGlobalCache in buildQuery, could be an optional cache object.
    6. Fluent API, e.g. client.withOptions({ ... }).query, for an easier selection scoping.
    7. [x] Cache
      1. Expiry and SWR
      2. Optional normalization
      3. Persistence
      4. Chainability
      5. Capped LRU
  20. Next majors (soon™)
    1. [package/core] Modular design, pluggable components:
      1. query fetcher
        1. Defaults to fetch(), can be replaced with urql or apollo client
        2. static queries
        3. persisted queries
        4. file uploads
        5. query batching
        6. variable hashing #700
      2. query selector
      3. query builder
      4. caching
      5. suspense fallbacks
    2. [package/react] Refactor with use() and cache().
    3. [package/preact] Use Signals for queries
bkniffler commented 1 year ago

Hey @vicary. We really love gqty and we're happy to support the project! Is there some sort of timeline for your roadmap / new releases? Thanks :)

vicary commented 1 year ago

@bkniffler I am in the middle of integrating everything into useQuery to make room for features in the roadmap, which unfortunately lead to an early refactoring. It is taking longer than I wanted to, but I am powering through it.

Let me know if you need a quick fix on anything, I'll prioritize.

bkniffler commented 1 year ago

Our biggest issues are around the react client. We very much prefer using the transaction useTransactionQuery hook compared to useQuery, just due to having more control.

The issues we encountered https://github.com/gqty-dev/gqty/pull/1163 (fixed) https://github.com/gqty-dev/gqty/issues/1179#issuecomment-1439829140 (we're using the workaround I posted there)

We're also using our own useTransactionSubscription looking similar to this:

export const useV2TransactionSubscription = <T, TVar>(
  fn: (sub: gqlV2.Subscription, variables: TVar) => T,
  variables?: TVar
) => {
  const { subscribe } = useContext(context);
  const [data, setData] = useState<T>();
  const [error, setError] = useState<any>();
  useEffect(() => {
    const r = subscribe(
      (s) => fn(s, variables as any),
      (data) => setData(data),
      (error) => setError(error)
    );
    return () => {
      r();
    };
  }, [JSON.stringify(variables)]);

  return { data, error };
};

Maybe you could consider getting a similar subscription transaction hook into this repo?

vicary commented 1 year ago

@bkniffler The upcoming new useQuery() will support all options in useTransactionQuery(), with the only difference being whether you use a separate function or render in place.

Which feature gives you more control? I'll try to retain that in future iterations.

EDIT: Does useQuery({ prepare }) also do the job?

bkniffler commented 1 year ago

The current useQuery is a bit too magical and we've had a few cases where we tried to access properties but wouldn't be able to (from within a callback for example). useTransactionQuery and being forced to make all queries in the callback fn forces us to access everything we need in a single spot, which is more to our taste. prepare/prepass is useful, but I think we'd stick to transactions.

bkniffler commented 1 year ago

btw, we use gqty on our backend also, and useTransactionQuery is very similar to resolve+query. It imposes the same mental model in both parts of our stack.

bkniffler commented 1 year ago

https://user-images.githubusercontent.com/4349324/220785288-2ebbcd42-b4dd-4c15-bd09-7a25fda9ec27.mov

While attempting to do some performance optimization, we've also noticed many parts of our app rerender if we open a drawer. We isolated the rerendering being due to a query on the drawer. Is it possible that a query in a deep component might trigger rerender due to cache on a higher component if it made a similar query?

vicary commented 1 year ago

useTransactionQuery

I will keep the API of useTransactionQuery() as a wrapper over useQuery({ prepare }) in the upcoming version, in the upcoming release they should behave exactly the same.

Backend usage

Do you mean SSR? When JSX is not in the equation, useTransactionQuery() may throw a promise, which users may find surprising at times. I would prefer the core resolved in these cases.

Re-rendering

Queries are automatically subscribed to cache change. When the cache is updated as a result of a fetch, other components with useQuery() calls reaching the same value will also re-render.

You should be able to avoid re-rendering of a parent container by moving useTransactionQuery() calls further down into child components.

vicary commented 1 year ago

@noverby This should be already pinned in GitHub, do you mean pinning it in Discord?

tyler-mitchell commented 1 year ago

On the new documentation site it mentions "State Management - Coming Soon". Is there any more information on what that might bring?

vicary commented 1 year ago

@tyler-mitchell The idea is to expand the current optimistic cache into a reactive store. We are currently weighing between different implementations, the goal is to allow easy implementation for UI frameworks (React, Svelte... etc.) with the same core feature set.

bkniffler commented 1 year ago

Appreciate the roadmap, but it looks like gqty development keeps on stalling unfortunately :(

Wondering if trying to support all kinds of UI frameworks is making it much harder, building an optimistic cache is very ambitious, it took apollo a lot of effort, and its taken urql much (much!) longer.

Why not try and laser focus on gqty as a graphql interface / transformer, making it agnostic to the framework. E.g. we're using it with react-query and it works really well. Would split the project up into a core project, an optimistic cache and community driven framework specifc libraries be an option @vicary?

Really appreciate the effort and I'm happy to continue fund (I know its not nearly enough to make a living).

// edit: Didn't see there is still development in a branch: https://github.com/gqty-dev/gqty/tree/feat/scoped-query. Please bear with me

vicary commented 1 year ago

@bkniffler V3 is entering beta. I would make a stable release and move on to other features when we have solid production use cases, so you and others have a certain level of confidence.

My own team is leading with a few client projects using V3, they are going live next month or two. So you may expect a stable release of V3 coming shortly afterwards. 😄

Please do feel free to comment on the release planning, or really anything else.