WIP PWA for Grain
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: auth service query result structure and HMR handling

- Access result.viewer directly (quickslice-client-js returns unwrapped)
- Preserve auth instance on window for HMR
- Check for existing grain-app before appending

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+15 -13
+3 -1
src/main.js
··· 13 13 14 14 async function init() { 15 15 await auth.init(); 16 - document.body.appendChild(document.createElement('grain-app')); 16 + if (!document.querySelector('grain-app')) { 17 + document.body.appendChild(document.createElement('grain-app')); 18 + } 17 19 } 18 20 19 21 init();
+12 -12
src/services/auth.js
··· 32 32 async #loadUser() { 33 33 const { did } = this.#client.getUser(); 34 34 const result = await this.#client.query(` 35 - query GetViewer($did: String!) { 36 - viewer { handle } 37 - socialGrainActorProfile(first: 1, where: { did: { eq: $did } }) { 38 - edges { 39 - node { 40 - displayName 41 - avatar { url } 42 - } 35 + query { 36 + viewer { 37 + handle 38 + socialGrainActorProfileByDid { 39 + displayName 40 + avatar { url(preset: "avatar") } 43 41 } 44 42 } 45 43 } 46 - `, { did }); 47 - const grainProfile = result.data.socialGrainActorProfile?.edges?.[0]?.node; 44 + `); 45 + const viewer = result.viewer; 46 + const grainProfile = viewer?.socialGrainActorProfileByDid; 48 47 this.#user = { 49 48 did, 50 - handle: result.data.viewer.handle, 49 + handle: viewer?.handle, 51 50 displayName: grainProfile?.displayName || '', 52 51 avatar: grainProfile?.avatar || null 53 52 }; ··· 80 79 } 81 80 } 82 81 83 - export const auth = new AuthService(); 82 + // Preserve auth instance across HMR 83 + export const auth = window.__auth || (window.__auth = new AuthService());