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

Transfer maintenance and resurrect graphql-subscriptions #240

Open
Urigo opened this issue Dec 15, 2020 · 9 comments
Open

Transfer maintenance and resurrect graphql-subscriptions #240

Urigo opened this issue Dec 15, 2020 · 9 comments

Comments

@Urigo
Copy link
Contributor

Urigo commented Dec 15, 2020

We at The Guild finally got again a production use case to use this library and we saw that the library was unmaintained for a couple of years.

So we would love to resurrect the library and bring it up to speed.

Will the kind people at Apollo be open to transfer the maintenance of that package to The Guild to give it and the community of users and other pubs integration authors a new life?

It might save the community from the hassle of moving to another package like what happened with the subscriptions-transport-ws library

(a lot of the original code was written by @dotansimha and myself so I'm sure it will stay in good hands)

Thank you

@grantwwu @hwillson

@grantwwu
Copy link
Contributor

I don't really have any ability to transfer ownership - I merely got commit bits, I can't even cut a release myself - but +1 to someone maintaining this.

@valdestron
Copy link
Contributor

Please do, what happened to Apollo? The same is happening with other libs ans servers like federation.

@n1ru4l
Copy link
Contributor

n1ru4l commented Jan 26, 2021

BTW this package can be completely replaced with the Node.js events.EventEmitter nowadays.

See https://nodejs.org/api/events.html#events_events_on_emitter_eventname_options

import * as events from "events";
import { GraphQLBoolean } from "graphql";
import {
  GraphQLObjectType,
  GraphQLString,
  GraphQLSchema,
  subscribe,
  parse
} from "graphql";

const emitter = new events.EventEmitter();

const Subscription = new GraphQLObjectType({
  name: "Subscription",
  fields: {
    test: {
      type: GraphQLString,
      resolve: value => value,
      subscribe: async function*() {
        const source = events.on(emitter, "foo");
        for await (const [value] of source) {
          yield value;
        }
      }
    }
  }
});

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "Query",
    fields: { _: { type: GraphQLBoolean } }
  }),
  subscription: Subscription
});

subscribe({
  schema,
  document: parse(/* GraphQL */ `
    subscription {
      test
    }
  `)
}).then(async asyncIterator => {
  process.nextTick(() => {
    emitter.emit("foo", "bar");
  });
  for await (const value of asyncIterator) {
    console.log(value);
    asyncIterator?.();
  }
});

The only benefit I see in further maintaining this package is for non-Node.js environments that don't have a similar solution or as a common interface for distributed message systems that work over redis, etc. But, in that use case, you could also use an abstraction over EventEmitter instead (e.g. https://www.npmjs.com/package/merkury for Redis).

Filtering/mapping can also be done easily by composing generator functions:

async-iterator.ts

export const map = <T, O>(map: (input: T) => Promise<O> | O) =>
  async function* mapGenerator(asyncIterable: AsyncIterableIterator<T>) {
    for await (const value of asyncIterable) {
      yield map(value);
    }
  };

export const filter = <T, U extends T = T>(filter: (input: T) => input is U) =>
  async function* filterGenerator(asyncIterable: AsyncIterableIterator<T>) {
    for await (const value of asyncIterable) {
      if (filter(value)) {
        yield value;
      }
    }
  };
const first = (arr) => arr[0]
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);

const Subscription = new GraphQLObjectType({
  name: "Subscription",
  fields: {
    test: {
      type: GraphQLString,
      subscribe: () =>
        pipe(
          events.on(emitter, "foo"),
          map(first),
          map(value => value.repeat(3)),
          filter(value => value.length < 10)
        )
    }
  }
});

@Urigo
Copy link
Contributor Author

Urigo commented Nov 18, 2021

@glasser any chance to reconsider this?

@alfaproject
Copy link

@Urigo did you guys ended doing something else or still using this library?

@Urigo
Copy link
Contributor Author

Urigo commented Apr 11, 2023

@alfaproject we've moved to Yoga Server and added built in, out of the box support for Subscriptions and all the features that this library provides.

Also about transports we actively maintain the graphql-ws, graphql-sse and graphql-http libraries.

But for the people who don't want to migrate, internally in Yoga we have createPubSub which is kinda similar to what the this original package was doing, but a more modern implementation which uses iterators and Typescript by default, which you can use in the same way.

You can find examples of using it here:

import { createPubSub } from 'graphql-yoga';

const pubSub = createPubSub()

// publish
pubSub.publish('newPost', newPost)

// subscribe 
(async () => {
  for await (const newPost of pubSub.subscribe('newPost')) {
    // event
  }
})()

and the docs for a full-blown GraphQL Subscriptions example.

The idea here is to use EventTarget interface to create a PubSub instead of creating a PubSub interface:
https://github.com/dotansimha/graphql-yoga/blob/main/packages/subscription/src/create-pub-sub.ts

Let us know if that helps

@alfaproject
Copy link

We had to build our own web socket lambda function because there isn't one available for AWS API Gateway web sockets (or any implementation for serverless web sockets for that matter) and that's one of the reasons of using this library but for sure we can also extract exactly what we need

If you guys have an implementation of a server or server blocks that we can use to build our own implementation of Yoga on top of Lambda I'm all ears. I feel like we are always fighting with the existing ecosystem and status quo because everyone assumes that everyone else has a long running node server so the past 4 years of going 100% serverless have been painful for our GraphQL journey ):

@enisdenjo
Copy link

Hey hey, there's been a discussion a while back on graphql-ws about the AWS lambda support.

There are currently two options for serverless WS on AWS (that I know of):

Hope the libraries, and the respected maintainers, can ease up your process and provide help.

@Aeolun
Copy link

Aeolun commented Aug 14, 2023

For those not interested in switching to a whole different server to fix a minor issue, I've published a fork here: https://github.com/Aeolun/graphql-subscriptions-continued that basically just releases the release-3.0 branch in this repository.

It doesn't update the dependent packages (e.g. graphql-redis-subscriptions), but if they feel like it they can switch.

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

No branches or pull requests

7 participants