use lexicon.ts rpc on the client
This commit is contained in:
parent
1d41bc2711
commit
1dd74500f2
4 changed files with 33 additions and 25 deletions
|
|
@ -4,42 +4,47 @@ import type { VideoLexiconUniverse } from "../common/lexicons.ts";
|
|||
import { resolveDid, resolveHandle } from "../common/identity.ts";
|
||||
import { VIDEO_PATTERN } from "../common/routes.ts";
|
||||
|
||||
import type { ATProtoUniverse } from "@char/lexicon.ts/atproto";
|
||||
import { XRPC } from "@char/lexicon.ts/rpc";
|
||||
|
||||
type VideoRecord = Infer<VideoLexiconUniverse, "blue.cerulea.video.video">;
|
||||
|
||||
const fetchVideoRecord = async (
|
||||
did: string,
|
||||
rkey: string
|
||||
): Promise<VideoRecord> => {
|
||||
// TODO: we do lots of casting here that we shouldn't need once we have lexicon.ts validations
|
||||
|
||||
const didDoc = await resolveDid(did);
|
||||
const pds = didDoc.service?.find((it) => it.id === "#atproto_pds")
|
||||
?.serviceEndpoint as string | undefined;
|
||||
|
||||
if (!pds) throw new Error("could not resolve pds for requested repo");
|
||||
|
||||
const getRecordURL = new URL("/xrpc/com.atproto.repo.getRecord", pds);
|
||||
getRecordURL.searchParams.set("collection", "blue.cerulea.video.video");
|
||||
getRecordURL.searchParams.set("repo", did);
|
||||
getRecordURL.searchParams.set("rkey", rkey);
|
||||
const xrpc = new XRPC<ATProtoUniverse>(pds);
|
||||
const record = await xrpc.get("com.atproto.repo.getRecord", {
|
||||
parameters: {
|
||||
collection: "blue.cerulea.video.video",
|
||||
repo: did,
|
||||
rkey,
|
||||
},
|
||||
});
|
||||
|
||||
const recordResponse = await fetch(getRecordURL);
|
||||
if (recordResponse.status !== 200)
|
||||
throw new Error("got error fetching record");
|
||||
|
||||
const record = (await recordResponse.json()).value as VideoRecord;
|
||||
return record;
|
||||
// TODO: replace this cast with a lexicon.ts validation check
|
||||
return record.value as VideoRecord;
|
||||
};
|
||||
|
||||
const resolveVideoURL = async (did: string, blob: string): Promise<string> => {
|
||||
const res = await fetch("/xrpc/blue.cerulea.video.fetchVideo", {
|
||||
method: "POST",
|
||||
headers: { "content-encoding": "application/json" },
|
||||
body: JSON.stringify({ repo: did, blob }),
|
||||
});
|
||||
if (res.status !== 200) throw new Error("got error fetching video cdn url");
|
||||
const data = await res.json();
|
||||
return `/user-content/${data.filename}`;
|
||||
const resolveVideoURL = async (
|
||||
did: `did:${string}`,
|
||||
blob: string
|
||||
): Promise<string> => {
|
||||
const xrpc = new XRPC<VideoLexiconUniverse>(globalThis.location.href);
|
||||
try {
|
||||
const res = await xrpc.call("blue.cerulea.video.fetchVideo", {
|
||||
input: { repo: did, blob },
|
||||
});
|
||||
return `/user-content/${res.filename}`;
|
||||
} catch {
|
||||
throw new Error("got error fetching URL of video at CDN");
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
|
|
@ -52,7 +57,8 @@ const main = async () => {
|
|||
rkey: string;
|
||||
};
|
||||
|
||||
const did = repo.startsWith("did:") ? repo : await resolveHandle(repo);
|
||||
const isDid = (s: string): s is `did:${string}` => s.startsWith("did:");
|
||||
const did = isDid(repo) ? repo : await resolveHandle(repo);
|
||||
|
||||
const record = await fetchVideoRecord(did, rkey);
|
||||
const videoURL = await resolveVideoURL(
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const didResolver = new CompositeDidDocumentResolver({
|
|||
},
|
||||
});
|
||||
|
||||
export function resolveHandle(handle: string): Promise<string> {
|
||||
export function resolveHandle(handle: string): Promise<`did:${string}`> {
|
||||
return handleResolver.resolve(handle as `${string}.${string}`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
"@std/http": "jsr:@std/http@^1.0.17",
|
||||
"@std/path": "jsr:@std/path@^1.1.0",
|
||||
"@zod/mini": "npm:@zod/mini@^4.0.0-beta.20250505T195954",
|
||||
"@char/lexicon.ts": "./vendor/lexicon.ts/lib/mod.ts"
|
||||
"@char/lexicon.ts": "./vendor/lexicon.ts/lib/mod.ts",
|
||||
"@char/lexicon.ts/atproto": "./vendor/lexicon.ts/pkg/atproto-lexica/mod.ts",
|
||||
"@char/lexicon.ts/rpc": "./vendor/lexicon.ts/pkg/rpc/rpc.ts"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"lib": ["deno.window", "dom"],
|
||||
|
|
|
|||
2
vendor/lexicon.ts
vendored
2
vendor/lexicon.ts
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit f070c8b56df7d3335a970118a401dfd7ee2f63f2
|
||||
Subproject commit 1edb68e5eac3ddfabdd77674ed8193ef9af05649
|
||||
Loading…
Reference in a new issue