{"_id":"apollo-pusher-subscriptions","_rev":"2-aad70f95001fa8b595eed7de956d2626","name":"apollo-pusher-subscriptions","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"apollo-pusher-subscriptions","version":"1.0.0","keywords":["apollo","apollo-client","apollo-link","graphql","subscriptions","pusher","pusher-js","lighthouse","laravel","real-time","websockets","typescript"],"author":{"name":"Stephen Jason Wang"},"license":"MIT","_id":"apollo-pusher-subscriptions@1.0.0","maintainers":[{"name":"stephenjason89","email":"stephenjasonwang@gmail.com"}],"homepage":"https://github.com/stephenjason89/apollo-pusher-subscriptions#readme","bugs":{"url":"https://github.com/stephenjason89/apollo-pusher-subscriptions/issues"},"dist":{"shasum":"052b03394ccb9aa309ebe45fb60357fa78c47a14","tarball":"https://registry.npmjs.org/apollo-pusher-subscriptions/-/apollo-pusher-subscriptions-1.0.0.tgz","fileCount":6,"integrity":"sha512-9Ciml8ZlX6QjK2bZhpPxZ94Qeh50PkAvOc/oYCiw3jc2tT1A7vcLiQTSPJaaBC5CT8VgJtaKjom/w3jChVDnoQ==","signatures":[{"sig":"MEUCIQCEISl7OlkIoMggPqA7nXzudFtAXSTGZ0wiJ5FddnKztwIgIiepmgrcd5uB6OwfM3PZK8kGujqWm3m5+KHYvWLobas=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21379},"main":"./dist/cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"}},"gitHead":"1b3ae4c62d847dd5c39aaab35f80945c4e2384cf","scripts":{"test":"bun test","build":"npm run build:esm && npm run build:cjs","watch":"tsc --watch","prepare":"husky","build:cjs":"tsc --project tsconfig.cjs.json","build:esm":"tsc","commitlint":"commitlint --edit","prepublishOnly":"npm run build"},"_npmUser":{"name":"stephenjason89","email":"stephenjasonwang@gmail.com"},"repository":{"url":"git+https://github.com/stephenjason89/apollo-pusher-subscriptions.git","type":"git"},"_npmVersion":"10.9.3","description":"A modern, configurable Apollo Link for handling GraphQL subscriptions via Pusher. Built with TypeScript and designed for Laravel Lighthouse.","directories":{},"nano-staged":{"*.{js,cjs,mjs,ts,jsx,json,json5,tsx,vue,md}":"eslint --fix"},"sideEffects":false,"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.2","husky":"^9.1.7","eslint":"^9.33.0","pusher-js":"^8.4.0","@types/bun":"^1.2.20","nano-staged":"^0.8.0","@commitlint/cli":"^19.8.1","@antfu/eslint-config":"^3.16.0","@semantic-release/git":"^10.0.1","@semantic-release/npm":"^12.0.2","@semantic-release/github":"^11.0.4","@semantic-release/changelog":"^6.0.3","@commitlint/config-conventional":"^19.8.1","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/release-notes-generator":"^14.0.3","conventional-changelog-conventionalcommits":"^8.0.0"},"peerDependencies":{"rxjs":"^7.0.0","pusher-js":"^7.0.0 || ^8.0.0","@apollo/client":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/apollo-pusher-subscriptions_1.0.0_1755881157885_0.8042302653221414","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"apollo-pusher-subscriptions","type":"module","version":"1.0.1","description":"A modern, configurable Apollo Link for handling GraphQL subscriptions via Pusher. Built with TypeScript and designed for Laravel Lighthouse.","author":{"name":"Stephen Jason Wang"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/stephenjason89/apollo-pusher-subscriptions.git"},"keywords":["apollo","apollo-client","apollo-link","graphql","subscriptions","pusher","pusher-js","lighthouse","laravel","real-time","websockets","typescript"],"sideEffects":false,"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.js"}},"main":"./dist/cjs/index.js","module":"./dist/esm/index.js","types":"./dist/index.d.ts","scripts":{"test":"bun test","build:esm":"tsc","build:cjs":"tsc --project tsconfig.cjs.json","build":"npm run build:esm && npm run build:cjs","watch":"tsc --watch","prepublishOnly":"npm run build","prepare":"husky","commitlint":"commitlint --edit"},"peerDependencies":{"@apollo/client":"^3.0.0 || ^4.0.0","pusher-js":"^7.0.0 || ^8.0.0","rxjs":"^7.0.0"},"devDependencies":{"@antfu/eslint-config":"^3.16.0","@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/git":"^10.0.1","@semantic-release/github":"^11.0.4","@semantic-release/npm":"^12.0.2","@semantic-release/release-notes-generator":"^14.0.3","@types/bun":"^1.2.20","conventional-changelog-conventionalcommits":"^8.0.0","eslint":"^9.33.0","husky":"^9.1.7","nano-staged":"^0.8.0","pusher-js":"^8.4.0","rxjs":"^7.8.2"},"nano-staged":{"*.{js,cjs,mjs,ts,jsx,json,json5,tsx,vue}":"eslint --fix"},"_id":"apollo-pusher-subscriptions@1.0.1","gitHead":"150e2e680e0ef5b3debe97e0164d4e3e25c3fdc1","bugs":{"url":"https://github.com/stephenjason89/apollo-pusher-subscriptions/issues"},"homepage":"https://github.com/stephenjason89/apollo-pusher-subscriptions#readme","_nodeVersion":"20.19.4","_npmVersion":"10.9.3","dist":{"integrity":"sha512-m2/m/warBLYSbtauv+3s+h4kz/dbu/98tQWG72TL2DrnOfeEC5JBi/LwxvmNA0MQ8/ezqP8GdnSzwj3SwV+p7w==","shasum":"62f4b5df9955ec86f5cfa3ea9dc9940a6e281488","tarball":"https://registry.npmjs.org/apollo-pusher-subscriptions/-/apollo-pusher-subscriptions-1.0.1.tgz","fileCount":6,"unpackedSize":21628,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDRJ2oTVzpEr1w0ouTKnaG1/MROXWPTtdxj382f/yYqkAiEA64CuEaMOrd05SnpRTTRRQ1Lyk6UEA3n0OL9Rhp8koc4="}]},"_npmUser":{"name":"stephenjason89","email":"stephenjasonwang@gmail.com"},"directories":{},"maintainers":[{"name":"stephenjason89","email":"stephenjasonwang@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/apollo-pusher-subscriptions_1.0.1_1755884016349_0.12441993892972425"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-22T16:45:57.884Z","modified":"2025-08-22T17:33:36.727Z","1.0.0":"2025-08-22T16:45:58.125Z","1.0.1":"2025-08-22T17:33:36.555Z"},"bugs":{"url":"https://github.com/stephenjason89/apollo-pusher-subscriptions/issues"},"author":{"name":"Stephen Jason Wang"},"license":"MIT","homepage":"https://github.com/stephenjason89/apollo-pusher-subscriptions#readme","keywords":["apollo","apollo-client","apollo-link","graphql","subscriptions","pusher","pusher-js","lighthouse","laravel","real-time","websockets","typescript"],"repository":{"type":"git","url":"git+https://github.com/stephenjason89/apollo-pusher-subscriptions.git"},"description":"A modern, configurable Apollo Link for handling GraphQL subscriptions via Pusher. Built with TypeScript and designed for Laravel Lighthouse.","maintainers":[{"name":"stephenjason89","email":"stephenjasonwang@gmail.com"}],"readme":"# apollo-pusher-subscriptions\n\nA modern, configurable Apollo Link for handling GraphQL subscriptions via Pusher. Built with TypeScript and designed for Laravel Lighthouse, but configurable for any GraphQL server that uses Pusher for real-time subscriptions.\n\n## ✨ Features\n\n- 🚀 **Modern Implementation** - Clean Observable patterns, proper TypeScript support\n- ⚙️ **Configurable** - Works with Lighthouse out of the box, easily configurable for other GraphQL servers\n- 🔧 **Type Safe** - Full TypeScript support with proper interfaces\n- 🧹 **Memory Safe** - Proper cleanup of both Apollo and Pusher subscriptions\n- 📦 **Lightweight** - Zero dependencies beyond Apollo Client and Pusher JS\n- 🎯 **Battle Tested** - Used in production applications\n\n## 📦 Installation\n\n```bash\nnpm install apollo-pusher-subscriptions @apollo/client pusher-js rxjs\n# or\nyarn add apollo-pusher-subscriptions @apollo/client pusher-js rxjs\n# or\npnpm add apollo-pusher-subscriptions @apollo/client pusher-js rxjs\n```\n\n## 🚀 Quick Start\n\n### With Laravel Lighthouse (Default)\n\n```typescript\nimport { ApolloClient, InMemoryCache, ApolloLink } from \"@apollo/client/core\";\nimport Pusher from \"pusher-js\";\nimport PusherLink from \"apollo-pusher-subscriptions\";\n\n// Configure Pusher\nconst pusher = new Pusher(\"your-app-key\", {\n  cluster: \"your-cluster\",\n  // ... other Pusher options\n});\n\n// Create the Pusher link\nconst pusherLink = new PusherLink({ pusher });\n\n// Create Apollo Client\nconst client = new ApolloClient({\n  link: ApolloLink.from([\n    // ... other links (auth, error handling, etc.)\n    pusherLink,\n    httpLink, // Your HTTP link should come last\n  ]),\n  cache: new InMemoryCache(),\n});\n```\n\n### With Custom GraphQL Server\n\n```typescript\nconst pusherLink = new PusherLink({\n  pusher,\n  subscriptionPath: \"extensions.subscriptions.channel\", // Custom path\n  eventName: \"graphql-subscription\", // Custom event name\n  initialDataCondition: (data) => data.data !== null, // Custom condition\n});\n```\n\n## ⚙️ Configuration Options\n\n```typescript\ninterface PusherLinkOptions {\n  pusher: Pusher; // Required: Pusher client instance\n  decompress?: (result: string) => GraphQLResponse; // Optional: Decompression function\n  subscriptionPath?: string; // Optional: Path to subscription channel\n  eventName?: string; // Optional: Pusher event name\n  initialDataCondition?: (data: any) => boolean; // Optional: When to pass initial data\n}\n```\n\n### Configuration Details\n\n| Option                 | Default                                                    | Description                                                               |\n| ---------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------- |\n| `pusher`               | -                                                          | **Required.** Your configured Pusher client instance                      |\n| `decompress`           | `undefined`                                                | Function to decompress compressed subscription payloads                   |\n| `subscriptionPath`     | `'lighthouse_subscriptions.channel'`                       | Dot-notation path to find the subscription channel in response extensions |\n| `eventName`            | `'lighthouse-subscription'`                                | Name of the Pusher event to listen for                                    |\n| `initialDataCondition` | `(data) => data.data && Object.keys(data.data).length > 0` | Function to determine when to pass initial subscription data              |\n\n## 🏗️ Framework Examples\n\n### Laravel Lighthouse\n\n```typescript\n// Default configuration works out of the box\nconst pusherLink = new PusherLink({ pusher });\n```\n\nYour Lighthouse GraphQL schema:\n\n```graphql\ntype Subscription {\n  postUpdated(id: ID!): Post\n    @subscription(class: \"App\\\\GraphQL\\\\Subscriptions\\\\PostUpdated\")\n}\n```\n\n### Hasura\n\n```typescript\nconst pusherLink = new PusherLink({\n  pusher,\n  subscriptionPath: \"extensions.hasura.channel\",\n  eventName: \"hasura-subscription\",\n});\n```\n\n### Custom GraphQL Server\n\n```typescript\nconst pusherLink = new PusherLink({\n  pusher,\n  subscriptionPath: \"extensions.subscriptions.pusher_channel\",\n  eventName: \"subscription-update\",\n  initialDataCondition: (data) => Boolean(data.data),\n});\n```\n\n## 💡 Usage Examples\n\n### Basic Subscription\n\n```typescript\nimport { gql } from \"@apollo/client/core\";\n\nconst SUBSCRIPTION = gql`\n  subscription OnCommentAdded($postId: ID!) {\n    commentAdded(postId: $postId) {\n      id\n      content\n      user {\n        name\n      }\n    }\n  }\n`;\n\n// In your component/composable\nconst { data, loading, error } = useSubscription(SUBSCRIPTION, {\n  variables: { postId: \"1\" },\n});\n```\n\n### With Compression Support\n\n```typescript\nimport pako from \"pako\"; // or your preferred compression library\n\nconst pusherLink = new PusherLink({\n  pusher,\n  decompress: (compressedResult: string) => {\n    const decompressed = pako.inflate(compressedResult, { to: \"string\" });\n    return JSON.parse(decompressed);\n  },\n});\n```\n\n### Advanced Configuration\n\n```typescript\nconst pusherLink = new PusherLink({\n  pusher,\n  subscriptionPath: \"meta.subscription.channel\",\n  eventName: \"subscription-data\",\n  initialDataCondition: (data) => {\n    // Only pass initial data if it's not empty and not an error\n    return data.data && !data.errors && Object.keys(data.data).length > 0;\n  },\n  decompress: (result: string) => JSON.parse(atob(result)), // Base64 decode\n});\n```\n\n## 🔧 Integration Patterns\n\n### With Authentication\n\n```typescript\nconst authLink = new ApolloLink((operation, forward) => {\n  operation.setContext({\n    headers: {\n      authorization: `Bearer ${getToken()}`,\n    },\n  });\n  return forward(operation);\n});\n\nconst client = new ApolloClient({\n  link: ApolloLink.from([authLink, pusherLink, httpLink]),\n  cache: new InMemoryCache(),\n});\n```\n\n### With Error Handling\n\n```typescript\nimport { ErrorLink } from \"@apollo/client/link/error\";\n\nconst errorLink = new ErrorLink(({ graphQLErrors, networkError }) => {\n  if (graphQLErrors) {\n    graphQLErrors.forEach(({ message, locations, path }) =>\n      console.log(\n        `GraphQL error: Message: ${message}, Location: ${locations}, Path: ${path}`\n      )\n    );\n  }\n  if (networkError) console.log(`Network error: ${networkError}`);\n});\n\nconst client = new ApolloClient({\n  link: ApolloLink.from([errorLink, pusherLink, httpLink]),\n  cache: new InMemoryCache(),\n});\n```\n\n### Framework-Specific Examples\n\n#### Vue 3 + Nuxt\n\n```typescript\n// plugins/apollo.client.ts\nexport default defineNuxtPlugin(() => {\n  const config = useRuntimeConfig();\n\n  const pusher = new Pusher(config.public.pusherKey, {\n    cluster: config.public.pusherCluster,\n  });\n\n  const pusherLink = new PusherLink({ pusher });\n\n  const client = new ApolloClient({\n    link: ApolloLink.from([pusherLink, httpLink]),\n    cache: new InMemoryCache(),\n  });\n\n  return {\n    provide: {\n      apollo: client,\n    },\n  };\n});\n```\n\n#### React\n\n```typescript\nimport { ApolloProvider } from \"@apollo/client\";\n\nconst pusher = new Pusher(process.env.REACT_APP_PUSHER_KEY, {\n  cluster: process.env.REACT_APP_PUSHER_CLUSTER,\n});\n\nconst pusherLink = new PusherLink({ pusher });\n\nconst client = new ApolloClient({\n  link: ApolloLink.from([pusherLink, httpLink]),\n  cache: new InMemoryCache(),\n});\n\nfunction App() {\n  return (\n    <ApolloProvider client={client}>\n      <YourApp />\n    </ApolloProvider>\n  );\n}\n```\n\n## 🐛 Troubleshooting\n\n### Subscriptions Not Working\n\n1. **Check Pusher Configuration**: Ensure your Pusher credentials are correct\n2. **Verify Subscription Path**: Make sure `subscriptionPath` matches your server's response format\n3. **Check Event Name**: Verify the `eventName` matches what your server broadcasts\n4. **Network Issues**: Ensure Pusher can connect (check firewall, proxy settings)\n\n### Memory Leaks\n\nThe library automatically handles cleanup, but ensure you're properly unsubscribing:\n\n```typescript\nconst subscription = client.subscribe({ query: SUBSCRIPTION });\n\n// Later, when component unmounts or subscription is no longer needed\nsubscription.unsubscribe();\n```\n\n### TypeScript Issues\n\nMake sure you have the correct types installed:\n\n```bash\nnpm install --save-dev @types/pusher-js\n```\n\n## 🔍 Debugging\n\nEnable debug mode for detailed logging:\n\n```typescript\n// Enable Pusher logging\nPusher.logToConsole = true;\n\nconst pusher = new Pusher(\"key\", {\n  cluster: \"cluster\",\n  enabledTransports: [\"ws\", \"wss\"],\n});\n```\n\n## 📊 Performance Considerations\n\n- **Connection Pooling**: Reuse the same Pusher instance across multiple PusherLink instances\n- **Subscription Cleanup**: The library automatically handles cleanup, but always unsubscribe when components unmount\n- **Batching**: Consider using Apollo's batching for mutations while keeping subscriptions separate\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## 📄 License\n\nMIT License - see LICENSE file for details.\n\n## 🙏 Acknowledgments\n\n- Built for the Laravel Lighthouse GraphQL community\n- Inspired by the need for a modern, type-safe Pusher integration\n- Thanks to the Apollo Client team for excellent GraphQL tooling\n","readmeFilename":"README.md"}