{"_id":"@carvajalconsultants/headstart","_rev":"9-c1ddb7f083601b2983ed9c0f4c7572cf","name":"@carvajalconsultants/headstart","dist-tags":{"latest":"1.0.7"},"versions":{"1.0.0":{"name":"@carvajalconsultants/headstart","version":"1.0.0","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.0","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"homepage":"https://github.com/carvajalconsultants/headstart#readme","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"dist":{"shasum":"e479b02d582df21930f72c68146d5c5341ec7538","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.0.tgz","fileCount":6,"integrity":"sha512-aBoH6n5ELWl/9oPCMTKbQfPz7+9sNJ4RpbtKsUKAQ5h6UkJrMNELM+Arr+mYWmkVYjMerAvl4xbeuC9sgy3mHg==","signatures":[{"sig":"MEUCIHtFhrK8IVMwwiqgoaTdY23imYISDz7f5Bk7Joy33a55AiEAjqaVyyQaaflo+hzFz/kUtL5G4aTA3rrmGXilXQXTWN8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13141},"main":"src/index.ts","type":"module","gitHead":"d9907f5f51c462df361919fc9f4c33382ca23cd8","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"git+https://github.com/carvajalconsultants/headstart.git","type":"git"},"_npmVersion":"10.9.0","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","postgraphile":"^5.0.0-beta.37","@biomejs/biome":"^1.9.4","@tanstack/start":"^1.100.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.0_1739065266286_0.42720828403182853","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@carvajalconsultants/headstart","version":"1.0.1","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.1","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"homepage":"https://github.com/carvajalconsultants/headstart#readme","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"dist":{"shasum":"fddabe259f52c4ea5a7c705acec3f35f3f9bd4ba","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.1.tgz","fileCount":6,"integrity":"sha512-EbAPV8iKTu0GmDdTyPjbHgMw/1ICS63ioLdEWAVXAJWKNkeQc0PRhEjRqOIg6aJhWb5rr0vN+jTQnBvBGXXTUQ==","signatures":[{"sig":"MEUCIQDPWbsxC4BEzEwjkGuRQ9ikQgj+T+rrR/qGS5RGA7b8bwIgQfOk2r9ao2KmLmqztnjmbC7QJGwfQloLeGOm37aHLlw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13270},"main":"server.ts","type":"module","gitHead":"d9907f5f51c462df361919fc9f4c33382ca23cd8","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"git+https://github.com/carvajalconsultants/headstart.git","type":"git"},"_npmVersion":"10.9.0","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","postgraphile":"^5.0.0-beta.37","@biomejs/biome":"^1.9.4","@tanstack/start":"^1.100.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.1_1739069593471_0.9286593445704778","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@carvajalconsultants/headstart","version":"1.0.2","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.2","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"homepage":"https://github.com/carvajalconsultants/headstart#readme","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"dist":{"shasum":"c6faf66b4a1e2c723112d06817545cb8df8c03da","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.2.tgz","fileCount":6,"integrity":"sha512-TWqGEExYhSPi+Jm+0TaJx6+9l311dy8NdU8z2ls6my2lNlmPBtsKKn7lgoBgrIjH1xjIQMOrMDGpGxm3QrAZYQ==","signatures":[{"sig":"MEYCIQDoi2eVreqhXTxNgasYkNSqFomQZ6jdwkBQg8/CVo/zjgIhAOVJD0f+2NyLYaAqLo3Fai8quM851DezrH9aRQgDRZU3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13426},"main":"server.ts","type":"module","gitHead":"bb6cf2f356a0f7125c07561707641c9f09b0ac2e","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"git+https://github.com/carvajalconsultants/headstart.git","type":"git"},"_npmVersion":"10.9.0","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","postgraphile":"^5.0.0-beta.37","@tanstack/start":"^1.100.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3","@biomejs/biome":"^1.9.4"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.2_1739684153817_0.40235808867641043","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@carvajalconsultants/headstart","version":"1.0.3","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.3","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"homepage":"https://github.com/carvajalconsultants/headstart#readme","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"dist":{"shasum":"137f3f78b0a668278964d6461914d015dbab1af3","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.3.tgz","fileCount":6,"integrity":"sha512-toCBv8TK0caiVY8vOgzwfYa8Uc4AtU5wB5zWchVB6QBGnhrBKJULLtXz7Ol1tA0zJ2bgDsbeC5fic+hdTt48CQ==","signatures":[{"sig":"MEUCIGRjoDIU1ciqmxTDwyOBJufAnin2eh0EYyoiH3Qj9my0AiEAqBD5y2H3BhbaIsttbYb0bSfMnleLN8fWzlKvSZDFJDY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13430},"main":"server.ts","type":"module","gitHead":"c83aa4122ea4aba9d2c84504416037586c74ed79","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"git+https://github.com/carvajalconsultants/headstart.git","type":"git"},"_npmVersion":"10.9.0","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_nodeVersion":"22.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3","@biomejs/biome":"^1.9.4"},"peerDependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","postgraphile":"^5.0.0-beta.37","@tanstack/start":"^1.100.0"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.3_1741717594040_0.7200178189386803","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@carvajalconsultants/headstart","version":"1.0.4","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.4","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"dist":{"shasum":"b46a93f3f5684f32200b0f265327a6072234b806","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.4.tgz","fileCount":7,"integrity":"sha512-nf14iUlwgdxOvoU9kPuLPrjmQUx143vOg8dnqIKiMlBuyRInN6+mwhGmqO4YPfnTyy4QAV3oY0PzuxZnTFd9PQ==","signatures":[{"sig":"MEQCIDhr2fubzrcEfZELShxuH4uVNMxf5ToQeD/ndfouZDzdAiBWX7aWwTsxX4zfwpBAewEsLQyIusn3BFbaOCxtXa7koA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":13457},"main":"server.ts","type":"module","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"https://github.com/carvajalconsultants/headstart.git","type":"git"},"description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3","@biomejs/biome":"^1.9.4"},"peerDependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","js-cookie":"^3.0.5","postgraphile":"^5.0.0-beta.37","@tanstack/start":"^1.100.0"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.4_1744512986065_0.31114367314541225","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@carvajalconsultants/headstart","version":"1.0.5","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.5","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"dist":{"shasum":"e38eb95343e27267c4e08a56ea4b713a36e574d3","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.5.tgz","fileCount":9,"integrity":"sha512-iZGmTxKvoU/VGbI0K5CAsDrkl2LyaYj9JSviVzascPX5cnkevBY4E1xEve9vVlvHyxCWu7IbMo0D/XdFS+WQvw==","signatures":[{"sig":"MEUCICB989NUASGGd+X8yhU8WrBZ5mgFlliE53t91BI7GFWwAiEA3clLFXtkUPDSF2Vxt6v5AglJ3Th0R715afn45HfzCFs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24903},"main":"server.ts","type":"module","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"https://github.com/carvajalconsultants/headstart.git","type":"git"},"description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3","@biomejs/biome":"^1.9.4"},"peerDependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","js-cookie":"^3.0.5","postgraphile":"^5.0.0-beta.37","@tanstack/start":"^1.100.0"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.5_1744513212744_0.9092581268420206","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@carvajalconsultants/headstart","version":"1.0.6","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","_id":"@carvajalconsultants/headstart@1.0.6","maintainers":[{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"homepage":"https://github.com/carvajalconsultants/headstart#readme","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"dist":{"shasum":"c627cf26ffa7f95999043755962d19b4f893e327","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.6.tgz","fileCount":8,"integrity":"sha512-+03RYq46hcSqFxclrafQLbtgmoajfZ7szQ98Y1Ar1OS4VCXXlPtI+HM3dDZaFOvJ3sNMKnKPtcZR+yK33qMUwg==","signatures":[{"sig":"MEUCIQDb4+/7EkeIuIa0hmfIlBpCJtG6esGn2FcuCmniQkzAdwIgKnl4JB6pI/vO0qJOu5bsH17L5ZsiiAI4wHfvV26PL0s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29451},"main":"server.ts","type":"module","gitHead":"153d927bea6153baebf0bce03e36a82f32f608af","scripts":{"lint":"biome check --write"},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"repository":{"url":"git+https://github.com/carvajalconsultants/headstart.git","type":"git"},"_npmVersion":"11.6.2","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","directories":{},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"devDependencies":{"@types/ws":"^8.5.14","typescript":"^5.7.3","@biomejs/biome":"^1.9.4"},"peerDependencies":{"urql":"^4.2.1","vinxi":"^0.5.2","js-cookie":"^3.0.5","postgraphile":"^5.0.0-beta.37","@tanstack/start":"^1.100.0"},"_npmOperationalInternal":{"tmp":"tmp/headstart_1.0.6_1766668783675_0.7979761702342765","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@carvajalconsultants/headstart","version":"1.0.7","description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","license":"MIT","author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"repository":{"type":"git","url":"git+https://github.com/carvajalconsultants/headstart.git"},"type":"module","main":"server.ts","scripts":{"lint":"biome check --write"},"peerDependencies":{"@tanstack/start":"^1.100.0","js-cookie":"^3.0.5","postgraphile":"^5.0.0-beta.37","urql":"^4.2.1","vinxi":"^0.5.2"},"devDependencies":{"@biomejs/biome":"^1.9.4","typescript":"^5.7.3"},"gitHead":"da3229d837f201ee2f23b18cd229e83f272801cb","_id":"@carvajalconsultants/headstart@1.0.7","bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"homepage":"https://github.com/carvajalconsultants/headstart#readme","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-bHh6jIBDvmkKSs1yK0PA2JFfOz7EBdO+J5zvKPFicwgo7rJJkl8hGQEwCFvzXlCGzYcvspYUm/69gp236LmYjA==","shasum":"3a8b0e6caf79b4d0a05d93f32b60f6a56b11771d","tarball":"https://registry.npmjs.org/@carvajalconsultants/headstart/-/headstart-1.0.7.tgz","fileCount":8,"unpackedSize":29881,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEKrRAFIBrqXIY/JkQ8RfK2CTAWhcqogzun+nSenpz3AAiEA4uJ+HTRExgqbMbDzGyu/U3F545iYpv4TAH0s+4DnYXE="}]},"_npmUser":{"name":"miguelocarvajal","email":"omar@carvajalonline.com"},"directories":{},"maintainers":[{"name":"hmosquera_cci","email":"hmosquera@carvajalonline.com"},{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/headstart_1.0.7_1772470128584_0.7221228511027011"},"_hasShrinkwrap":false}},"time":{"created":"2025-02-09T01:41:06.156Z","modified":"2026-03-02T16:48:48.909Z","1.0.0":"2025-02-09T01:41:06.485Z","1.0.1":"2025-02-09T02:53:13.663Z","1.0.2":"2025-02-16T05:35:53.990Z","1.0.3":"2025-03-11T18:26:34.221Z","1.0.4":"2025-04-13T02:56:26.254Z","1.0.5":"2025-04-13T03:00:12.942Z","1.0.6":"2025-12-25T13:19:43.819Z","1.0.7":"2026-03-02T16:48:48.750Z"},"bugs":{"url":"https://github.com/carvajalconsultants/headstart/issues"},"author":{"name":"Miguel Carvajal","email":"omar@carvajalonline.com"},"license":"MIT","homepage":"https://github.com/carvajalconsultants/headstart#readme","repository":{"type":"git","url":"git+https://github.com/carvajalconsultants/headstart.git"},"description":"Library to assist in integrating PostGraphile with Tanstack Start and URQL.","maintainers":[{"name":"hmosquera_cci","email":"hmosquera@carvajalonline.com"},{"name":"miguelocarvajal","email":"omar@carvajalonline.com"}],"readme":"# Headstart\n\nLibrary to assist in integrating PostGraphile with Tanstack Start and URQL.\n\nThis library is made up of:\n\n- An URQL Exchange that queries grafast for SSR pages (so we don't make an unecessary HTTP request)\n- A Grafserv adapter to work with Tanstack Start, including Web Socket support.\n- SSR Exchange to be used on the server and client for hydration\n\n## Installation\n\n1. Initialize Tanstack Start as per: https://tanstack.com/router/latest/docs/framework/react/start/getting-started\n\n2. Install Postgraphile as a library as per: https://postgraphile.org/postgraphile/next/quick-start-guide#install-postgraphile (ensure to use the Typescript files).\n   Specifically, the `graphile.config.ts` and `pgl.ts`. If you need WebSocket support, make sure to add a plugin in `graphile.config.ts` as per: https://postgraphile.org/postgraphile/next/subscriptions\n\n3. Install Headtart & URQL:\n```bash\nyarn add @carvajalconsultants/headstart urql @urql/exchange-graphcache @urql/exchange-auth\n```\n\n4. Enable WebSockets in `app.config.ts` if you need it:\n\n```typescript\n// app.config.ts\nimport { defineConfig } from \"@tanstack/react-start/config\";\n\nexport default defineConfig({\n\tserver: {\n\t\texperimental: {\n\t\t\twebsocket: true,\n\t\t},\n\t},\n});\n```\n\n5. Make sure to add the `/api` endpoint to the grafserv configuration so that Ruru GraphQL client works correctly:\n\n```typescript\n// graphile.config.ts\nconst preset: GraphileConfig.Preset = {\n    ...\n\tgrafserv: {\n        ...\n\t\tgraphqlPath: \"/api\",\n\t\teventStreamPath: \"/api\",\n\t},\n    ...\n};\n```\n\n6. Add the api.ts file so that it calls our GraphQL handler. This will receive all GraphQL requests at the /api endpoint.\n\n```typescript\n// app/api.ts\nimport { defaultAPIFileRouteHandler } from \"@tanstack/react-start/api\";\nimport { createStartAPIHandler } from \"@carvajalconsultants/headstart/server\";\nimport { pgl } from \"../pgl\";\n\nexport default createStartAPIHandler(pgl, defaultAPIFileRouteHandler);\n```\n\n7. Now we need to configure URQL for client and server rendering, first we start with the server. Create this provider:\n\n```typescript\n// app/graphql/serverProvider.tsx\nimport { Client } from \"urql\";\nimport { grafastExchange } from \"@carvajalconsultants/headstart/server\";\nimport { ssr } from \"@carvajalconsultants/headstart/client\";\nimport { pgl } from \"../../pgl\";\n\n/**\n * Configure URQL for server side querying with Grafast.\n *\n * This removes the need to make an HTTP request to ourselves and simply executes the GraphQL query.\n */\nexport const client = new Client({\n\turl: \".\",\n\texchanges: [ssr, grafastExchange(pgl)],\n});\n```\n\n8. Now the client side for URQL:\n\n```typescript\n// app/graphql/clientProvider.tsx\nimport { ssr } from \"@carvajalconsultants/headstart/client\";\nimport { authExchange } from \"@urql/exchange-auth\";\nimport { cacheExchange } from \"@urql/exchange-graphcache\";\n//import { relayPagination } from \"@urql/exchange-graphcache/extras\";\nimport { Client, fetchExchange } from \"urql\";\n\n/**\n * Creates an authentication exchange for handling secure GraphQL operations.\n * This exchange ensures that all GraphQL requests are properly authenticated\n * and handles authentication failures gracefully.\n *\n * @returns {Object} Authentication configuration object\n * @returns {Function} .addAuthToOperation - Prepares operations with auth context\n * @returns {Function} .didAuthError - Detects authentication failures after server request\n * @returns {Function} .refreshAuth - Handles auth token refresh\n */\nconst auth = authExchange(async () => {\n  //TODO Implement authentication checking for the client s ide\n  await new Promise((resolve) => {\n    setTimeout(() => {\n      console.log(\"IMPLEMENT CLIENT AUTH CHECK\");\n      resolve();\n    }, 2000);\n  });\n\n  return {\n    /**\n     * Processes each GraphQL operation to include authentication context.\n     * Currently configured as a pass-through as tokens are in cookies.\n     *\n     * @param {Operation} operation - The GraphQL operation to authenticate\n     * @returns {Operation} The operation with authentication context\n     */\n    addAuthToOperation: (operation) => operation,\n\n    /**\n     * Identifies when an operation has failed due to authentication issues.\n     * Used to trigger authentication refresh flows when needed.\n     *\n     * @param {Error} error - The GraphQL error response\n     * @returns {boolean} True if the error was caused by authentication failure\n     */\n    didAuthError: (error) => error.graphQLErrors.some((e) => e.extensions?.code === \"FORBIDDEN\"),\n\n    /**\n     * Handles refreshing authentication when it becomes invalid.\n     * Currently implemented as a no-op as token refresh is handled by getSession().\n     */\n    refreshAuth: async () => {\n      /* No-op, this is done in getSession() */\n    },\n  };\n});\n\n/**\n * Configured GraphQL client for the application.\n * Provides a centralized way to make authenticated GraphQL requests with\n * proper caching and server-side rendering support.\n */\nexport const client = new Client({\n  url: \"http://localhost:3000/api/graphql\",\n  exchanges: [\n    cacheExchange({\n      resolvers: {\n        Query: {\n          // Implements relay-style pagination for fills pending match\n          //queryName: relayPagination(),\n        },\n      },\n    }),\n    auth,\n    ssr,\n    fetchExchange,\n  ],\n});\n```\n\n9. Create the server side router which uses Grafast to execute queries:\n\n```typescript\n// app/serverRouter.tsx\nimport { ssr } from \"@carvajalconsultants/headstart/client\";\nimport { createRouter as createTanStackRouter } from \"@tanstack/react-router\";\nimport { Provider } from \"urql\";\nimport { client } from \"./graphql/serverProvider\";\nimport { routeTree } from \"./routeTree.gen\";\n\nimport type { ReactNode } from \"react\";\n\nexport function createRouter() {\n\tconst router = createTanStackRouter({\n\t\trouteTree,\n\t\tcontext: {\n\t\t\tclient,\n\t\t},\n\n\t\t// Send data to client so URQL can be hydrated.\n\t\tdehydrate: () => ({ initialData: ssr.extractData() }),\n\n\t\t// Wrap our entire route with the URQL provider so we can execute queries and mutations.\n\t\tWrap: ({ children }: { children: ReactNode }) => <Provider value={client}>{children}</Provider>,\n\t});\n\n\treturn router;\n}\n```\n\n10. Modify the TSR server-side rendering function to use this new router:\n\n```typescript\n/* eslint-disable */\n// app/ssr.tsx\n/// <reference types=\"vinxi/types/server\" />\nimport { getRouterManifest } from \"@tanstack/react-start/router-manifest\";\nimport {\n\tcreateStartHandler,\n\tdefaultStreamHandler,\n} from \"@tanstack/start/server\";\n\nimport { createRouter } from \"./serverRouter\";\n\nexport default createStartHandler({\n\tcreateRouter,\n\tgetRouterManifest,\n})(defaultStreamHandler);\n```\n\n11. Add the client side router which uses the fetch exchange to execute queries, mutations, etc.:\n\n```typescript\n// app/clientRouter.tsx\nimport { ssr } from \"@carvajalconsultants/headstart/client\";\nimport { createRouter as createTanStackRouter } from \"@tanstack/react-router\";\nimport { Provider } from \"urql\";\nimport { client } from \"./graphql/clientProvider\";\nimport { routeTree } from \"./routeTree.gen\";\n\nimport type { ReactNode } from \"react\";\nimport type { SSRData } from \"urql\";\n\nexport function createRouter() {\n\tconst router = createTanStackRouter({\n\t\trouteTree,\n\t\tcontext: {\n\t\t\tclient,\n\t\t},\n\t\thydrate: (dehydrated) => {\n\t\t\t// Hydrate URQL with data passed by TSR, this is generated by dehydrate function in server router.\n\t\t\tssr.restoreData(dehydrated.initialData as SSRData);\n\t\t},\n\n\t\t// Wrap our entire route with the URQL provider so we can execute queries and mutations.\n\t\tWrap: ({ children }: { children: ReactNode }) => <Provider value={client}>{children}</Provider>,\n\t});\n\n\treturn router;\n}\n```\n\n12. Tell TSR to use our client side router:\n\n```typescript\n// app/client.tsx\n/// <reference types=\"vinxi/types/client\" />\nimport { StartClient } from \"@tanstack/start\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { createRouter } from \"./clientRouter\";\n\nconst router = createRouter();\n\nhydrateRoot(document.getElementById(\"root\")!, <StartClient router={router} />);\n```\n\n13. Last but not least, you're ready to start using URQL on your components and pages. First we create the route using the loader option so we can pre-load data:\n\n```typescript\nexport const Route = createFileRoute(\"/\")({\n\t...\n\tvalidateSearch: zodSearchValidator(paramSchema),\n\n\tloaderDeps: ({ search: { page } }) => ({ page }),\n\tloader: ({ context, deps: { page } }) =>\n\t\tcontext.client.query(\n\t\t\tgql`...`\n\t\t\t{ first: CHARITIES_PER_PAGE, offset: (page - 1) * CHARITIES_PER_PAGE },\n\t\t),\n\t...\n});\n```\n\n14. Now in your component, you can query with URQL as you normally would:\n\n```typescript\nconst Home = () => {\n\tconst { page } = Route.useSearch();\n\n\tconst [{ data, error }] = useQuery({\n\t\tquery: gql`...`,\n\t\tvariables: {\n\t\t\tfirst: CHARITIES_PER_PAGE,\n\t\t\toffset: (page - 1) * CHARITIES_PER_PAGE,\n\t\t},\n\t});\n\n\t// Subscribe to any data changes on the server\n\tuseSubscription({ query: allCharitiesSubscription });\n}\n```\n\n## Deployment\n\n1. Run `yarn run build`\n2. `cd .output/server`\n3. `rm -rf node_modules`\n4. `yarn install`\n5. `yarn run index.mjs`\n","readmeFilename":"README.md"}