@envelop/live-query
TypeScript icon, indicating that this package has built-in type declarations

7.0.0 • Public • Published

@envelop/live-query

The easiest way of adding live queries to your GraphQL server!

Push new data to your clients automatically once the data selected by a GraphQL operation becomes stale by annotating your query operation with the @live directive.

query UserProfile @live {
  me {
    id
    login
    bio
  }
}

The invalidation mechanism is based on GraphQL ID fields and schema coordinates. Once a query operation has been invalidated, the query is re-executed and the result is pushed to the client.

Installation

yarn add @envelop/live-query @n1ru4l/in-memory-live-query-store

Usage Example

makeExecutableSchema from graphql-tools

import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
import { envelop, useEngine, useExtendContext, useSchema } from '@envelop/core'
import { useLiveQuery } from '@envelop/live-query'
import { makeExecutableSchema } from '@graphql-tools/schema'
import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store'

const schema = makeExecutableSchema({
  typeDefs: [
    /* GraphQL */ `
      type Query {
        greetings: [String!]
      }
    `,
    GraphQLLiveDirectiveSDL
  ],
  resolvers: {
    Query: {
      greetings: (_, __, context) => context.greetings
    }
  }
})

const liveQueryStore = new InMemoryLiveQueryStore()

const greetings = ['Hello', 'Hi', 'Ay', 'Sup']
// Shuffle greetings and invalidate queries selecting Query.greetings every second.
setInterval(() => {
  const firstElement = greetings.pop()
  greetings.unshift(firstElement)
  liveQueryStore.invalidate('Query.greetings')
}, 1000)

const getEnveloped = envelop({
  plugins: [
    useEngine({ parse, validate, specifiedRules, execute, subscribe }),
    useSchema(schema),
    useLiveQuery({ liveQueryStore }),
    useExtendContext(() => ({ greetings }))
    /* other plugins */
  ]
})

GraphQLSchema from graphql

You need to pass the GraphQLLiveDirective to the list of directives:

import { GraphQLSchema } from 'graphql'
import { GraphQLLiveDirective } from '@envelop/live-query'

const schema = new GraphQLSchema({
  directives: [...specifiedDirectives, GraphQLLiveDirective]
})

Applying a patch middleware

By using a patch middleware you can significantly reduce the size of the GraphQL execution result payload that is sent over the wire from the server to the client. We recommend using the @n1ru4l/graphql-live-query-patch-jsondiffpatch patch generator. You can learn more about it here.

yarn add @n1ru4l/graphql-live-query-patch-jsondiffpatch
import { applyLiveQueryJSONDiffPatchGenerator } from '@n1ru4l/graphql-live-query-patch-jsondiffpatch'
import { InMemoryLiveQueryStore } from '@n1ru4l/in-memory-live-query-store'

const liveQueryStore = new InMemoryLiveQueryStore()

const plugin = useLiveQuery({
  liveQueryStore,
  applyLiveQueryPatchGenerator: applyLiveQueryJSONDiffPatchGenerator
})

Further information

This plugin requires you to use a graphql transports that supports usage of the @defer and @stream directives, as it is built upon the same concepts (return an AsyncIterable from execute).

The following transports have been successfully tested:

Package Transport Version Downloads
@n1ru4l/socket-io-graphql-server GraphQL over Socket.io (WebSocket/HTTP Long Polling) npm version npm downloads
graphql-helix GraphQL over HTTP (IncrementalDelivery/SSE) npm version npm downloads
graphql-ws GraphQL over WebSocket (WebSocket) npm version npm downloads
graphql-sse GraphQL over Server-Sent Events (SSE) npm version npm downloads

For more details check out the live query repository or the introduction blog post.

There is also a full schema example available.

Readme

Keywords

none

Package Sidebar

Install

npm i @envelop/live-query

Weekly Downloads

6,196

Version

7.0.0

License

MIT

Unpacked Size

14.1 kB

Total Files

8

Last publish

Collaborators

  • dotansimha