frontend client for gemstone. decentralised workplace app
at main 6.6 kB view raw
1import type { ComAtprotoRepoStrongRef, Did } from "@/lib/types/atproto"; 2import type { SystemsGmstnDevelopmentShard } from "@/lib/types/lexicon/systems.gmstn.development.shard"; 3import { getEndpointFromDid } from "@/lib/utils/atproto"; 4import { isDomain } from "@/lib/utils/domains"; 5import type { Result } from "@/lib/utils/result"; 6import type { Agent } from "@atproto/api"; 7import * as TID from "@atcute/tid"; 8import type { SystemsGmstnDevelopmentLattice } from "@/lib/types/lexicon/systems.gmstn.development.lattice"; 9import type { SystemsGmstnDevelopmentChannelInvite } from "@/lib/types/lexicon/systems.gmstn.development.channel.invite"; 10import type { SystemsGmstnDevelopmentChannel } from "@/lib/types/lexicon/systems.gmstn.development.channel"; 11import type { SystemsGmstnDevelopmentChannelMembership } from "@/lib/types/lexicon/systems.gmstn.development.channel.membership"; 12 13export const getLatticeEndpointFromDid = async (did: Did) => { 14 return await getEndpointFromDid(did, "GemstoneLattice"); 15}; 16 17export const connectToLattice = ({ 18 shardUrl, 19 sessionToken, 20}: { 21 shardUrl: string; 22 sessionToken: string; 23}) => { 24 const endpoint = new URL(shardUrl); 25 endpoint.searchParams.append("token", sessionToken); 26 return new WebSocket(endpoint); 27}; 28 29export const registerNewShard = async ({ 30 shardDomain, 31 agent, 32}: { 33 shardDomain: string; 34 agent: Agent; 35}): Promise<Result<undefined, string>> => { 36 if (!isDomain(shardDomain)) 37 return { ok: false, error: "Input was not a valid domain." }; 38 39 const now = new Date().toISOString(); 40 41 const record: Omit<SystemsGmstnDevelopmentShard, "$type"> = { 42 // @ts-expect-error we want to explicitly use the ISO string variant 43 createdAt: now, 44 // TODO: actually figure out how to support the description 45 description: "A Gemstone Systems Shard.", 46 }; 47 console.log(record); 48 49 const { success } = await agent.call( 50 "com.atproto.repo.createRecord", 51 {}, 52 { 53 repo: agent.did, 54 collection: "systems.gmstn.development.shard", 55 rkey: shardDomain, 56 record, 57 }, 58 ); 59 60 if (!success) 61 return { 62 ok: false, 63 error: "Attempt to create shard record failed. Check the domain inputs.", 64 }; 65 66 return { ok: true }; 67}; 68 69export const registerNewLattice = async ({ 70 latticeDomain, 71 agent, 72}: { 73 latticeDomain: string; 74 agent: Agent; 75}): Promise<Result<undefined, string>> => { 76 if (!isDomain(latticeDomain)) 77 return { ok: false, error: "Input was not a valid domain." }; 78 79 const now = new Date().toISOString(); 80 81 const record: Omit<SystemsGmstnDevelopmentLattice, "$type"> = { 82 // @ts-expect-error we want to explicitly use the ISO string variant 83 createdAt: now, 84 // TODO: actually figure out how to support the description 85 description: "A Gemstone Systems Lattice.", 86 }; 87 console.log(record); 88 89 const { success } = await agent.call( 90 "com.atproto.repo.createRecord", 91 {}, 92 { 93 repo: agent.did, 94 collection: "systems.gmstn.development.lattice", 95 rkey: latticeDomain, 96 record, 97 }, 98 ); 99 100 if (!success) 101 return { 102 ok: false, 103 error: "Attempt to create lattice record failed. Check the domain inputs.", 104 }; 105 106 return { ok: true }; 107}; 108 109export const inviteNewUser = async ({ 110 did, 111 channel, 112 agent, 113}: { 114 did: Did; 115 channel: ComAtprotoRepoStrongRef; 116 agent: Agent; 117}): Promise<Result<undefined, string>> => { 118 const now = new Date(); 119 const rkey = TID.create(now.getTime() * 1_000, Math.random()); 120 121 const record: Omit<SystemsGmstnDevelopmentChannelInvite, "$type"> = { 122 // @ts-expect-error we want to explicitly use the ISO string variant 123 createdAt: now.toISOString(), 124 recipient: did, 125 channel, 126 }; 127 128 const { success } = await agent.call( 129 "com.atproto.repo.createRecord", 130 {}, 131 { 132 repo: agent.did, 133 collection: "systems.gmstn.development.channel.invite", 134 rkey, 135 record, 136 }, 137 ); 138 139 if (!success) 140 return { 141 ok: false, 142 error: "Attempt to create invite record failed. Check the did and strongRef inputs.", 143 }; 144 145 return { ok: true }; 146}; 147 148export const addChannel = async ({ 149 channelInfo, 150 agent, 151}: { 152 channelInfo: Omit<SystemsGmstnDevelopmentChannel, "$type" | "createdAt">; 153 agent: Agent; 154}): Promise<Result<undefined, string>> => { 155 const now = new Date(); 156 const rkey = TID.create(now.getTime() * 1_000, Math.floor(Math.random() * 1023)); 157 158 const record: Omit<SystemsGmstnDevelopmentChannel, "$type"> = { 159 // @ts-expect-error we want to explicitly use the ISO string variant 160 createdAt: now.toISOString(), 161 ...channelInfo, 162 }; 163 164 const { success } = await agent.call( 165 "com.atproto.repo.createRecord", 166 {}, 167 { 168 repo: agent.did, 169 collection: "systems.gmstn.development.channel", 170 rkey, 171 record, 172 }, 173 ); 174 175 if (!success) 176 return { 177 ok: false, 178 error: "Attempted to create channel record failed. Check the channel info inputs.", 179 }; 180 181 return { ok: true }; 182}; 183 184export const addMembership = async ({ 185 membershipInfo, 186 agent, 187}: { 188 membershipInfo: Omit< 189 SystemsGmstnDevelopmentChannelMembership, 190 "$type" | "createdAt" | "updatedAt" 191 >; 192 agent: Agent; 193}): Promise<Result<undefined, string>> => { 194 const now = new Date(); 195 const rkey = TID.create(now.getTime() * 1_000, Math.floor(Math.random() * 1023)); 196 197 const record: Omit<SystemsGmstnDevelopmentChannelMembership, "$type"> = { 198 // @ts-expect-error we want to explicitly use the ISO string variant 199 createdAt: now.toISOString(), 200 // @ts-expect-error we want to explicitly use the ISO string variant 201 updatedAt: now.toISOString(), 202 ...membershipInfo, 203 }; 204 205 const { success } = await agent.call( 206 "com.atproto.repo.createRecord", 207 {}, 208 { 209 repo: agent.did, 210 collection: "systems.gmstn.development.channel.membership", 211 rkey, 212 record, 213 }, 214 ); 215 216 if (!success) 217 return { 218 ok: false, 219 error: "Attempted to create channel record failed. Check the channel info inputs.", 220 }; 221 222 return { ok: true }; 223};