a tool for shared writing and social publishing

some small import optimizations

+23 -32
+3 -9
actions/getIdentityData.ts
··· 1 "use server"; 2 3 import { IdResolver } from "@atproto/identity"; 4 - import { createServerClient } from "@supabase/ssr"; 5 import { cookies } from "next/headers"; 6 - import { Database } from "supabase/database.types"; 7 8 - let supabase = createServerClient<Database>( 9 - process.env.NEXT_PUBLIC_SUPABASE_API_URL as string, 10 - process.env.SUPABASE_SERVICE_ROLE_KEY as string, 11 - { cookies: {} }, 12 - ); 13 let idResolver = new IdResolver(); 14 export async function getIdentityData() { 15 let cookieStore = await cookies(); 16 let auth_token = cookieStore.get("auth_token")?.value; 17 let auth_res = auth_token 18 - ? await supabase 19 .from("email_auth_tokens") 20 .select( 21 `*, ··· 34 if (!auth_res?.data?.identities) return null; 35 if (auth_res.data.identities.atp_did) { 36 //I should create a relationship table so I can do this in the above query 37 - let { data: publications } = await supabase 38 .from("publications") 39 .select("*") 40 .eq("identity_did", auth_res.data.identities.atp_did);
··· 1 "use server"; 2 3 import { IdResolver } from "@atproto/identity"; 4 import { cookies } from "next/headers"; 5 + import { supabaseServerClient } from "supabase/serverClient"; 6 7 let idResolver = new IdResolver(); 8 export async function getIdentityData() { 9 let cookieStore = await cookies(); 10 let auth_token = cookieStore.get("auth_token")?.value; 11 let auth_res = auth_token 12 + ? await supabaseServerClient 13 .from("email_auth_tokens") 14 .select( 15 `*, ··· 28 if (!auth_res?.data?.identities) return null; 29 if (auth_res.data.identities.atp_did) { 30 //I should create a relationship table so I can do this in the above query 31 + let { data: publications } = await supabaseServerClient 32 .from("publications") 33 .select("*") 34 .eq("identity_did", auth_res.data.identities.atp_did);
+1
app/home/LeafletList.tsx
··· 58 <div className="grid auto-rows-max md:grid-cols-4 sm:grid-cols-3 grid-cols-2 gap-y-4 gap-x-4 sm:gap-6 grow pt-3 pb-28 px-2 sm:pt-6 sm:pb-12 sm:pl-6 sm:pr-1"> 59 {leaflets.map((leaflet, index) => ( 60 <ReplicacheProvider 61 initialFactsOnly={!!identity} 62 key={leaflet.id} 63 rootEntity={leaflet.root_entity}
··· 58 <div className="grid auto-rows-max md:grid-cols-4 sm:grid-cols-3 grid-cols-2 gap-y-4 gap-x-4 sm:gap-6 grow pt-3 pb-28 px-2 sm:pt-6 sm:pb-12 sm:pl-6 sm:pr-1"> 59 {leaflets.map((leaflet, index) => ( 60 <ReplicacheProvider 61 + disablePull 62 initialFactsOnly={!!identity} 63 key={leaflet.id} 64 rootEntity={leaflet.root_entity}
+4 -10
app/home/page.tsx
··· 1 import { cookies } from "next/headers"; 2 import { Fact, ReplicacheProvider } from "src/replicache"; 3 - import { createServerClient } from "@supabase/ssr"; 4 - import { Database } from "supabase/database.types"; 5 import { Attributes } from "src/replicache/attributes"; 6 import { 7 ThemeBackgroundProvider, ··· 18 import { HomeSidebar } from "./HomeSidebar"; 19 import { HomeFooter } from "./HomeFooter"; 20 import { MyPublicationList } from "./Publications"; 21 22 - let supabase = createServerClient<Database>( 23 - process.env.NEXT_PUBLIC_SUPABASE_API_URL as string, 24 - process.env.SUPABASE_SERVICE_ROLE_KEY as string, 25 - { cookies: {} }, 26 - ); 27 export default async function Home() { 28 let cookieStore = await cookies(); 29 ··· 52 53 let permission_token = auth_res?.home_leaflet; 54 if (!permission_token) { 55 - let res = await supabase 56 .from("identities") 57 .select( 58 `*, ··· 66 67 if (!permission_token) return <div>no home page wierdly</div>; 68 let [homeLeafletFacts, allLeafletFacts] = await Promise.all([ 69 - supabase.rpc("get_facts", { 70 root: permission_token.root_entity, 71 }), 72 auth_res ··· 76 (r) => r.permission_tokens.root_entity, 77 ), 78 }, 79 - { supabase }, 80 ) 81 : undefined, 82 ]);
··· 1 import { cookies } from "next/headers"; 2 import { Fact, ReplicacheProvider } from "src/replicache"; 3 import { Attributes } from "src/replicache/attributes"; 4 import { 5 ThemeBackgroundProvider, ··· 16 import { HomeSidebar } from "./HomeSidebar"; 17 import { HomeFooter } from "./HomeFooter"; 18 import { MyPublicationList } from "./Publications"; 19 + import { supabaseServerClient } from "supabase/serverClient"; 20 21 export default async function Home() { 22 let cookieStore = await cookies(); 23 ··· 46 47 let permission_token = auth_res?.home_leaflet; 48 if (!permission_token) { 49 + let res = await supabaseServerClient 50 .from("identities") 51 .select( 52 `*, ··· 60 61 if (!permission_token) return <div>no home page wierdly</div>; 62 let [homeLeafletFacts, allLeafletFacts] = await Promise.all([ 63 + supabaseServerClient.rpc("get_facts", { 64 root: permission_token.root_entity, 65 }), 66 auth_res ··· 70 (r) => r.permission_tokens.root_entity, 71 ), 72 }, 73 + { supabase: supabaseServerClient }, 74 ) 75 : undefined, 76 ]);
+2 -6
src/replicache/attributes.ts
··· 1 - import { AppBskyFeedGetPostThread } from "@atproto/api"; 2 - import { 3 - PostView, 4 - ThreadViewPost, 5 - } from "@atproto/api/dist/client/types/app/bsky/feed/defs"; 6 - import { DeepAsReadonlyJSONValue } from "./utils"; 7 8 const RootAttributes = { 9 "root/page": {
··· 1 + import type { AppBskyFeedGetPostThread } from "@atproto/api"; 2 + import type { DeepAsReadonlyJSONValue } from "./utils"; 3 4 const RootAttributes = { 5 "root/page": {
+12 -6
src/replicache/index.tsx
··· 24 import { UndoManager } from "@rocicorp/undo"; 25 import { addShortcut } from "src/shortcuts"; 26 import { createUndoManager } from "src/undoManager"; 27 28 export type Fact<A extends keyof typeof Attributes> = { 29 id: string; ··· 69 name: string; 70 children: React.ReactNode; 71 initialFactsOnly?: boolean; 72 }) { 73 let [rep, setRep] = useState<null | Replicache<ReplicacheMutators>>(null); 74 let [undoManager] = useState(createUndoManager()); ··· 103 if (props.initialFactsOnly) return; 104 let supabase = supabaseBrowserClient(); 105 let newRep = new Replicache({ 106 pushDelay: 500, 107 mutators: Object.fromEntries( 108 Object.keys(mutations).map((m) => { ··· 158 }, 159 }); 160 setRep(newRep); 161 - let channel = supabase.channel(`rootEntity:${props.name}`); 162 163 - channel.on("broadcast", { event: "poke" }, () => { 164 - newRep.pull(); 165 - }); 166 - channel.subscribe(); 167 return () => { 168 newRep.close(); 169 setRep(null); 170 - channel.unsubscribe(); 171 }; 172 }, [props.name, props.initialFactsOnly, props.token]); 173 return (
··· 24 import { UndoManager } from "@rocicorp/undo"; 25 import { addShortcut } from "src/shortcuts"; 26 import { createUndoManager } from "src/undoManager"; 27 + import { RealtimeChannel } from "@supabase/supabase-js"; 28 29 export type Fact<A extends keyof typeof Attributes> = { 30 id: string; ··· 70 name: string; 71 children: React.ReactNode; 72 initialFactsOnly?: boolean; 73 + disablePull?: boolean; 74 }) { 75 let [rep, setRep] = useState<null | Replicache<ReplicacheMutators>>(null); 76 let [undoManager] = useState(createUndoManager()); ··· 105 if (props.initialFactsOnly) return; 106 let supabase = supabaseBrowserClient(); 107 let newRep = new Replicache({ 108 + pullInterval: props.disablePull ? null : undefined, 109 pushDelay: 500, 110 mutators: Object.fromEntries( 111 Object.keys(mutations).map((m) => { ··· 161 }, 162 }); 163 setRep(newRep); 164 + let channel: RealtimeChannel | null = null; 165 + if (!props.disablePull) { 166 + channel = supabase.channel(`rootEntity:${props.name}`); 167 168 + channel.on("broadcast", { event: "poke" }, () => { 169 + newRep.pull(); 170 + }); 171 + channel.subscribe(); 172 + } 173 return () => { 174 newRep.close(); 175 setRep(null); 176 + channel?.unsubscribe(); 177 }; 178 }, [props.name, props.initialFactsOnly, props.token]); 179 return (
+1 -1
supabase/serverClient.ts
··· 1 import { createClient } from "@supabase/supabase-js"; 2 - import { Database } from "supabase/database.types"; 3 export const supabaseServerClient = createClient<Database>( 4 process.env.NEXT_PUBLIC_SUPABASE_API_URL as string, 5 process.env.SUPABASE_SERVICE_ROLE_KEY as string,
··· 1 import { createClient } from "@supabase/supabase-js"; 2 + import type { Database } from "supabase/database.types"; 3 export const supabaseServerClient = createClient<Database>( 4 process.env.NEXT_PUBLIC_SUPABASE_API_URL as string, 5 process.env.SUPABASE_SERVICE_ROLE_KEY as string,