···11import { OWNER_DID, SERVER_PORT, SERVICE_DID } from "@/lib/env";
22-import { performHandshakes } from "@/lib/setup";
22+import { connectToShards, performHandshakes } from "@/lib/setup";
33import { handshakeTokens, setRegistrationState } from "@/lib/state";
44import type { AtUri } from "@/lib/types/atproto";
55import { getRecordFromAtUri } from "@/lib/utils/atproto";
···8989 });
90909191 // TODO: probably move this to an `attachListeners` hook that attaches the listeners we want.
9292+ // least tested. will probably have nuances we need to work on in the future
9293 attachLatticeRegistrationListener(prismWebsocket);
93949495 await performHandshakes(latticeAtUri);
9696+9797+ const test = await connectToShards();
9898+ console.log("connected to", test.map((socket) => socket.url));
959996100 // TODO: change this to the actual WS sessions
97101 const handshakeTokenEntries = handshakeTokens.entries().toArray();
9810299103 if (handshakeTokenEntries.length === 0) {
100100- console.warn("Warning: there are zero handshake tokens on this Lattice.");
101101- console.warn("If you're hacking locally, you might want to make sure that there's a running Shard as well.")
104104+ console.warn(
105105+ "Warning: there are zero handshake tokens on this Lattice.",
106106+ );
107107+ console.warn(
108108+ "If you're hacking locally, you might want to make sure that there's a running Shard as well.",
109109+ );
102110 // NOTE: might change in the future
103103- console.warn("Channel records connecting a Lattice to a Shard are not supported now. Dev lattices must point to a dev Shard if both are running locally")
111111+ console.warn(
112112+ "Channel records connecting a Lattice to a Shard are not supported now. Dev lattices must point to a dev Shard if both are running locally",
113113+ );
104114 }
105115};
106116
+39
src/lib/setup.ts
···88} from "@/lib/utils/atproto";
99import { getConstellationBacklink } from "@/lib/utils/constellation";
1010import { isDomain } from "@/lib/utils/domains";
1111+import { connectToShard, getShardEndpointFromDid } from "@/lib/utils/gmstn";
1112import { initiateHandshakeTo } from "@/lib/utils/handshake";
12131314export const performHandshakes = async (latticeAtUri: AtUri) => {
···103104104105 const channelAtUris = entry[1];
105106107107+ // FIXME: perf issue. we are awaiting each handshake to resolve before we make new ones
108108+ // this means that the handshakes are consecutive and not concurrent.
109109+ // stuff this into a Promise.all by mapping over the array instead
106110 const handshakeResult = await initiateHandshakeTo({
107111 did: shardDid,
108112 channels: channelAtUris,
···113117 handshakeTokens.set(shardAtUri, sessionInfo);
114118 }
115119};
120120+121121+export const connectToShards = async () => {
122122+ const shardSessions = handshakeTokens.entries();
123123+ const shardConnectionPromises = shardSessions
124124+ .map(async (session) => {
125125+ const atUri = session[0];
126126+ const { token } = session[1];
127127+ const rkey = atUri.rKey ?? "";
128128+ const shardDid = isDomain(rkey)
129129+ ? `did:web:${encodeURIComponent(rkey)}`
130130+ : `did:plc:${rkey}`;
131131+132132+ console.log(shardDid);
133133+134134+ // TODO: again, implement proper did -> endpoint parsing here too.
135135+ // for now, we just assume did:web and construce a URL based on that.
136136+ // @ts-expect-error trust me bro it's a string
137137+ const shardUrlResult = await getShardEndpointFromDid(shardDid);
138138+139139+ if (!shardUrlResult.ok) return;
140140+141141+ return {
142142+ // TODO: xrpc and lexicon this endpoint
143143+ shardUrl: `${shardUrlResult.data.origin}/connect`,
144144+ sessionToken: token,
145145+ };
146146+ })
147147+ .toArray();
148148+149149+ const shardConnectionRequests = await Promise.all(shardConnectionPromises);
150150+151151+ return shardConnectionRequests
152152+ .filter((request) => request !== undefined)
153153+ .map((request) => connectToShard(request));
154154+};
+13
src/lib/utils/gmstn.ts
···11import type { Did } from "@/lib/types/atproto";
22import { getEndpointFromDid } from "@/lib/utils/atproto";
33+import WebSocket from "ws";
3445export const getShardEndpointFromDid = async (did: Did) => {
56 return await getEndpointFromDid(did, "GemstoneShard");
67};
88+99+export const connectToShard = ({
1010+ shardUrl,
1111+ sessionToken,
1212+}: {
1313+ shardUrl: string;
1414+ sessionToken: string;
1515+}) => {
1616+ const endpoint = new URL(shardUrl);
1717+ endpoint.searchParams.append("token", sessionToken);
1818+ return new WebSocket(endpoint);
1919+};