{"_id":"@alugha/graphql-subscriptions","_rev":"1-56cf2f92ca2f9d7e9a760a1790596b4a","name":"@alugha/graphql-subscriptions","dist-tags":{"latest":"1.1.1"},"versions":{"1.1.1":{"name":"@alugha/graphql-subscriptions","version":"1.1.1","description":"GraphQL subscriptions for node.js","main":"dist/index.js","repository":{"type":"git","url":"git+https://github.com/apollostack/graphql-subscriptions.git"},"dependencies":{"iterall":"^1.3.0"},"peerDependencies":{"graphql":"^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"},"scripts":{"clean":"rimraf dist coverage","compile":"tsc","pretest":"npm run compile","test":"npm run testonly --","posttest":"npm run lint","lint":"tslint --project ./tsconfig.json ./src/**/*.ts","watch":"tsc -w","testonly":"mocha --reporter spec --full-trace ./dist/test/tests.js ./dist/test/asyncIteratorSubscription.js","coverage":"node ./node_modules/istanbul/lib/cli.js cover _mocha -- --full-trace ./dist/test/tests.js ./dist/test/asyncIteratorSubscription.js","postcoverage":"remap-istanbul --input coverage/coverage.raw.json --type lcovonly --output coverage/lcov.info","prepublishOnly":"npm run clean && npm run compile"},"devDependencies":{"@types/chai-as-promised":"^7.1.3","@types/graphql":"^14.5.0","@types/mocha":"^8.0.0","@types/node":"^14.0.23","@types/sinon":"9.0.4","@types/sinon-chai":"^3.2.4","chai":"^4.2.0","chai-as-promised":"^7.1.1","graphql":"^14.0.0","istanbul":"^1.0.0-alpha.2","mocha":"^8.0.1","remap-istanbul":"^0.13.0","rimraf":"^3.0.2","sinon":"^9.0.2","sinon-chai":"^3.5.0","tslint":"^6.1.2","typescript":"^3.9.6"},"typings":"dist/index.d.ts","typescript":{"definition":"dist/index.d.ts"},"license":"MIT","contributors":[{"name":"Authors"},{"name":"Jonas Helfer","email":"helfer@users.noreply.github.com"},{"name":"Jonas Helfer","email":"jonas@helfer.email"},{"name":"Quint Stoffers","email":"quintstoffers@users.noreply.github.com"},{"name":"Sashko Stubailo","email":"s.stubailo@gmail.com"},{"name":"Sashko Stubailo","email":"sashko@stubailo.com"},{"name":"David Yahalomi","email":"davidyaha@users.noreply.github.com"},{"name":"Alexander Anich","email":"Anichale@users.noreply.github.com"},{"name":"Francois Valdy","email":"gluck@users.noreply.github.com"},{"name":"Daniel Rinehart","email":"NeoPhi@users.noreply.github.com"}],"gitHead":"b00be6b0508f9d4941d0322a65e5e2e41f73a0bd","bugs":{"url":"https://github.com/apollostack/graphql-subscriptions/issues"},"homepage":"https://github.com/apollostack/graphql-subscriptions#readme","_id":"@alugha/graphql-subscriptions@1.1.1","_nodeVersion":"14.7.0","_npmVersion":"6.14.7","dist":{"integrity":"sha512-yU5kldB+xkaTxT+QhZjNSkpKW87CxehmlYcFrcOp+ZZ2NoZFQ0dbEGINVin517K/nS+hqXtHLU4bXiSXU84kVA==","shasum":"bd71cd422e8e8ce5bcb956f9e5bb301089867eb0","tarball":"https://registry.npmjs.org/@alugha/graphql-subscriptions/-/graphql-subscriptions-1.1.1.tgz","fileCount":26,"unpackedSize":134540,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfKo9qCRA9TVsSAnZWagAAvJAQAKKW6unO90wI/ygP5nNc\nliPmBqgE5gML1XxkFoFRqZw64l6aH4mVIPy9cYJQf9YbfiSiisZvOKQVbgHj\ndkS03nKN2skigJ9teou51UVFQ1yu5E7GrNjerf+dvuAXxbIGmyb+lm1vKlw2\nLSwwE9mqjg4DkK36QLj2CT7HpT3YRUvFPIytyfubDIiQvXyREZg+MudyCIJG\n5KzivKUcvN1BCGmlPkwYMan9Pc1xP+PmAFvU0gA+KBD0eNHa/WUrfj6Q/KtE\nA6gBL1zJDa9VAu7VhgmBtrRwp+luSUVDc3bG/CzvIdyPH93Prbroa+JvZG8l\n+JFuWsDsjWxm8kTIJztCaURw6ei1z/U19uGHqM+5Vvjh8hUfRFOsGxbdp+vI\nfZFYyJkLNQLuuj+Qdm+yXxdyELpEvMk7m3F8FecWJir+0UBCsYBhax5Hpz6y\np2/0r0APmTHz9Ve7N8A1amn1UVk1tYiNWcF9OcHPBLidpdZT6j5DOyuF0+Vn\nOGcohBGJ4C1CHI3APYa0gWyxkQz2PjrfL9FrAJ0VSj6TmvCQR9yIz2yg6m4R\nM7fRIRVWPDoxhkUXPMUSlA4bzBDgBM5A/xKOl7yIJI4MZDRrsAyFJ4weANUi\ncSg757JX0ge1XXzmT/y9muOjTTvYDbKKDjdgoxyPnTfUpB38udoag3aqQxqf\n3WGX\r\n=2K1O\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCdUHxAlSGvFw93Nmth+8BEiT7+xFmVNCog2c/2SqLwpwIgfOhoHqakBxUGJzDer9OSTZhD3k0VUDGiZ6L5O9ga1tc="}]},"maintainers":[{"name":"niklaskorz","email":"niklas@niklaskorz.de"}],"_npmUser":{"name":"niklaskorz","email":"niklas@niklaskorz.de"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/graphql-subscriptions_1.1.1_1596624746398_0.9847900277781942"},"_hasShrinkwrap":false}},"time":{"created":"2020-08-05T10:52:26.214Z","1.1.1":"2020-08-05T10:52:26.512Z","modified":"2022-04-04T13:41:18.604Z"},"maintainers":[{"name":"niklaskorz","email":"niklas@niklaskorz.de"}],"description":"GraphQL subscriptions for node.js","homepage":"https://github.com/apollostack/graphql-subscriptions#readme","repository":{"type":"git","url":"git+https://github.com/apollostack/graphql-subscriptions.git"},"contributors":[{"name":"Authors"},{"name":"Jonas Helfer","email":"helfer@users.noreply.github.com"},{"name":"Jonas Helfer","email":"jonas@helfer.email"},{"name":"Quint Stoffers","email":"quintstoffers@users.noreply.github.com"},{"name":"Sashko Stubailo","email":"s.stubailo@gmail.com"},{"name":"Sashko Stubailo","email":"sashko@stubailo.com"},{"name":"David Yahalomi","email":"davidyaha@users.noreply.github.com"},{"name":"Alexander Anich","email":"Anichale@users.noreply.github.com"},{"name":"Francois Valdy","email":"gluck@users.noreply.github.com"},{"name":"Daniel Rinehart","email":"NeoPhi@users.noreply.github.com"}],"bugs":{"url":"https://github.com/apollostack/graphql-subscriptions/issues"},"license":"MIT","readme":"[![npm version](https://badge.fury.io/js/graphql-subscriptions.svg)](https://badge.fury.io/js/graphql-subscriptions) [![GitHub license](https://img.shields.io/github/license/apollostack/graphql-subscriptions.svg)](https://github.com/apollographql/graphql-subscriptions/blob/master/LICENSE)\n\n# graphql-subscriptions\n\nGraphQL subscriptions is a simple npm package that lets you wire up GraphQL with a pubsub system (like Redis) to implement subscriptions in GraphQL.\n\nYou can use it with any GraphQL client and server (not only Apollo).\n\n### Installation\n\n`npm install graphql-subscriptions graphql` or `yarn add graphql-subscriptions graphql`\n\n> This package should be used with a network transport, for example [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws).\n\n### TypeScript\n\nIf you are developing a project that uses this module with TypeScript:\n\n* ensure that your `tsconfig.json` `lib` definition includes `\"esnext.asynciterable\"`\n* `npm install @types/graphql` or `yarn add @types/graphql`\n\n### Getting started with your first subscription\n\nTo begin with GraphQL subscriptions, start by defining a GraphQL `Subscription` type in your schema:\n\n```graphql\ntype Subscription {\n    somethingChanged: Result\n}\n\ntype Result {\n    id: String\n}\n```\n\nNext, add the `Subscription` type to your `schema` definition:\n\n```graphql\nschema {\n  query: Query\n  mutation: Mutation\n  subscription: Subscription\n}\n```\n\nNow, let's create a simple `PubSub` instance - it is a simple pubsub implementation, based on `EventEmitter`. Alternative `EventEmitter` implementations can be passed by an options object\nto the `PubSub` constructor.\n\n```js\nimport { PubSub } from 'graphql-subscriptions';\n\nexport const pubsub = new PubSub();\n```\n\nNow, implement your Subscriptions type resolver, using the `pubsub.asyncIterator` to map the event you need:\n\n```js\nconst SOMETHING_CHANGED_TOPIC = 'something_changed';\n\nexport const resolvers = {\n  Subscription: {\n    somethingChanged: {\n      subscribe: () => pubsub.asyncIterator(SOMETHING_CHANGED_TOPIC),\n    },\n  },\n}\n```\n\n> Subscriptions resolvers are not a function, but an object with `subscribe` method, that returns `AsyncIterable`.\n\nNow, the GraphQL engine knows that `somethingChanged` is a subscription, and every time we use `pubsub.publish` over this topic - it will publish it using the transport we use:\n\n```js\npubsub.publish(SOMETHING_CHANGED_TOPIC, { somethingChanged: { id: \"123\" }});\n```\n\n> Note that the default PubSub implementation is intended for demo purposes. It only works if you have a single instance of your server and doesn't scale beyond a couple of connections.\n> For production usage you'll want to use one of the [PubSub implementations](#pubsub-implementations) backed by an external store. (e.g. Redis)\n\n### Filters\n\nWhen publishing data to subscribers, we need to make sure that each subscriber gets only the data it needs.\n\nTo do so, we can use `withFilter` helper from this package, which wraps `AsyncIterator` with a filter function, and lets you control each publication for each user.\n\n`withFilter` API:\n- `asyncIteratorFn: (rootValue, args, context, info) => AsyncIterator<any>` : A function that returns `AsyncIterator` you got from your `pubsub.asyncIterator`.\n- `filterFn: (payload, variables, context, info) => boolean | Promise<boolean>` - A filter function, executed with the payload (the published value), variables, context and operation info, must return `boolean` or `Promise<boolean>` indicating if the payload should pass to the subscriber.\n\nFor example, if `somethingChanged` would also accept a variable with the ID that is relevant, we can use the following code to filter according to it:\n\n```js\nimport { withFilter } from 'graphql-subscriptions';\n\nconst SOMETHING_CHANGED_TOPIC = 'something_changed';\n\nexport const resolvers = {\n  Subscription: {\n    somethingChanged: {\n      subscribe: withFilter(() => pubsub.asyncIterator(SOMETHING_CHANGED_TOPIC), (payload, variables) => {\n        return payload.somethingChanged.id === variables.relevantId;\n      }),\n    },\n  },\n}\n```\n\n> Note that when using `withFilter`, you don't need to wrap your return value with a function.\n\n### Channels Mapping\n\nYou can map multiple channels into the same subscription, for example when there are multiple events that trigger the same subscription in the GraphQL engine.\n\n```js\nconst SOMETHING_UPDATED = 'something_updated';\nconst SOMETHING_CREATED = 'something_created';\nconst SOMETHING_REMOVED = 'something_removed';\n\nexport const resolvers = {\n  Subscription: {\n    somethingChanged: {\n      subscribe: () => pubsub.asyncIterator([ SOMETHING_UPDATED, SOMETHING_CREATED, SOMETHING_REMOVED ]),\n    },\n  },\n}\n````\n\n### Payload Manipulation\n\nYou can also manipulate the published payload, by adding `resolve` methods to your subscription:\n\n```js\nconst SOMETHING_UPDATED = 'something_updated';\n\nexport const resolvers = {\n  Subscription: {\n    somethingChanged: {\n      resolve: (payload, args, context, info) => {\n        // Manipulate and return the new value\n        return payload.somethingChanged;\n      },\n      subscribe: () => pubsub.asyncIterator(SOMETHING_UPDATED),\n    },\n  },\n}\n````\n\n### Usage with callback listeners\n\nYour database might have callback-based listeners for changes, for example something like this:\n\n```JS\nconst listenToNewMessages = (callback) => {\n  return db.table('messages').listen(newMessage => callback(newMessage));\n}\n\n// Kick off the listener\nlistenToNewMessages(message => {\n  console.log(message);\n})\n```\n\nThe `callback` function would be called every time a new message is saved in the database. Unfortunately, that doesn't play very well with async iterators out of the box because callbacks are push-based, where async iterators are pull-based.\n\nWe recommend using the [`callback-to-async-iterator`](https://github.com/withspectrum/callback-to-async-iterator) module to convert your callback-based listener into an async iterator:\n\n```js\nimport asyncify from 'callback-to-async-iterator';\n\nexport const resolvers = {\n  Subscription: {\n    somethingChanged: {\n      subscribe: () => asyncify(listenToNewMessages),\n    },\n  },\n}\n````\n\n### Custom `AsyncIterator` Wrappers\n\nThe value you should return from your `subscribe` resolver must be an `AsyncIterator`.\n\nYou can use this value and wrap it with another `AsyncIterator` to implement custom logic over your subscriptions.\n\nFor example, the following implementation manipulate the payload by adding some static fields:\n\n```typescript\nimport { $$asyncIterator } from 'iterall';\n\nexport const withStaticFields = (asyncIterator: AsyncIterator<any>, staticFields: Object): Function => {\n  return (rootValue: any, args: any, context: any, info: any): AsyncIterator<any> => {\n\n    return {\n      next() {\n        return asyncIterator.next().then(({ value, done }) => {\n          return {\n            value: {\n              ...value,\n              ...staticFields,\n            },\n            done,\n          };\n        });\n      },\n      return() {\n        return Promise.resolve({ value: undefined, done: true });\n      },\n      throw(error) {\n        return Promise.reject(error);\n      },\n      [$$asyncIterator]() {\n        return this;\n      },\n    };\n  };\n};\n```\n\n> You can also take a look at `withFilter` for inspiration.\n\nFor more information about `AsyncIterator`:\n- [TC39 Proposal](https://github.com/tc39/proposal-async-iteration)\n- [iterall](https://github.com/leebyron/iterall)\n- [IxJS](https://github.com/ReactiveX/IxJS)\n\n### PubSub Implementations\n\nIt can be easily replaced with some other implementations of [PubSubEngine abstract class](https://github.com/apollographql/graphql-subscriptions/blob/master/src/pubsub-engine.ts). Here are a few of them:\n- Use Redis with https://github.com/davidyaha/graphql-redis-subscriptions\n- Use Google PubSub with https://github.com/axelspringer/graphql-google-pubsub\n- Use MQTT enabled broker with https://github.com/davidyaha/graphql-mqtt-subscriptions\n- Use RabbitMQ with https://github.com/cdmbase/graphql-rabbitmq-subscriptions\n- Use AMQP (RabbitMQ) with https://github.com/Surnet/graphql-amqp-subscriptions\n- Use Kafka with https://github.com/ancashoria/graphql-kafka-subscriptions\n- Use Postgres with https://github.com/GraphQLCollege/graphql-postgres-subscriptions\n- Use NATS with https://github.com/moonwalker/graphql-nats-subscriptions\n- Use multiple backends with https://github.com/jcoreio/graphql-multiplex-subscriptions\n- [Add your implementation...](https://github.com/apollographql/graphql-subscriptions/pull/new/master)\n\nYou can also implement a `PubSub` of your own, by using the exported abstract class `PubSubEngine` from this package. By using `extends PubSubEngine` you use the default `asyncIterator` method implementation; by using `implements PubSubEngine` you must implement your own `AsyncIterator`.\n\n#### SubscriptionManager **@deprecated**\n\n`SubscriptionManager` is the previous alternative for using `graphql-js` subscriptions directly, and it's now deprecated.\n\nIf you are looking for its API docs, refer to [a previous commit of the repository](https://github.com/apollographql/graphql-subscriptions/blob/5eaee92cd50060b3f3637f00c53960f51a07d0b2/README.md)\n","readmeFilename":"README.md"}