atproto explorer pdsls.dev
atproto tool

deduplicate lookups

juli.ee 381f3ed4 38df6c06

verified
Changed files
+85 -6
src
views
+85 -6
src/views/record.tsx
···
import { Client, CredentialManager } from "@atcute/client";
import { lexiconDoc } from "@atcute/lexicon-doc";
import { RecordValidator } from "@atcute/lexicon-doc/validations";
-
import { ResolvedSchema } from "@atcute/lexicon-resolver";
import { ActorIdentifier, is, Nsid } from "@atcute/lexicons";
import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax";
import { verifyRecord } from "@atcute/repo";
···
import { pds } from "../components/navbar.jsx";
import { addNotification, removeNotification } from "../components/notification.jsx";
import Tooltip from "../components/tooltip.jsx";
-
import { resolveLexiconAuthority, resolveLexiconSchema, resolvePDS } from "../utils/api.js";
import { AtUri, uriTemplates } from "../utils/templates.js";
import { lexicons } from "../utils/types/lexicons.js";
const extractRefs = (obj: any): Nsid[] => {
const refs: Set<string> = new Set();
···
}
const fetchPromise = (async () => {
try {
-
const authority = await resolveLexiconAuthority(nsid);
-
const schema = await resolveLexiconSchema(authority, nsid);
-
resolved.set(nsid, schema.rawSchema);
-
const refs = extractRefs(schema.rawSchema);
if (refs.length > 0) {
await Promise.all(
···
} catch (err) {
console.error(`Failed to resolve lexicon ${nsid}:`, err);
failed.add(nsid);
} finally {
inFlight.delete(nsid);
}
···
}
const lexiconDocs = Object.fromEntries(resolved);
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
validator.parse({
···
import { Client, CredentialManager } from "@atcute/client";
+
import { DidDocument, getPdsEndpoint } from "@atcute/identity";
import { lexiconDoc } from "@atcute/lexicon-doc";
import { RecordValidator } from "@atcute/lexicon-doc/validations";
+
import { FailedLexiconResolutionError, ResolvedSchema } from "@atcute/lexicon-resolver";
import { ActorIdentifier, is, Nsid } from "@atcute/lexicons";
import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax";
import { verifyRecord } from "@atcute/repo";
···
import { pds } from "../components/navbar.jsx";
import { addNotification, removeNotification } from "../components/notification.jsx";
import Tooltip from "../components/tooltip.jsx";
+
import {
+
didDocumentResolver,
+
resolveLexiconAuthority,
+
resolveLexiconSchema,
+
resolvePDS,
+
} from "../utils/api.js";
import { AtUri, uriTemplates } from "../utils/templates.js";
import { lexicons } from "../utils/types/lexicons.js";
+
const authorityCache = new Map<string, Promise<AtprotoDid>>();
+
const documentCache = new Map<string, Promise<DidDocument>>();
+
const schemaCache = new Map<string, Promise<unknown>>();
+
+
const getAuthoritySegment = (nsid: string): string => {
+
const segments = nsid.split(".");
+
return segments.slice(0, -1).join(".");
+
};
+
+
const resolveSchema = async (authority: AtprotoDid, nsid: Nsid): Promise<unknown> => {
+
const cacheKey = `${authority}:${nsid}`;
+
+
let cachedSchema = schemaCache.get(cacheKey);
+
if (cachedSchema) {
+
return cachedSchema;
+
}
+
+
const schemaPromise = (async () => {
+
let didDocPromise = documentCache.get(authority);
+
if (!didDocPromise) {
+
didDocPromise = didDocumentResolver.resolve(authority);
+
documentCache.set(authority, didDocPromise);
+
}
+
+
const didDocument = await didDocPromise;
+
+
const pdsEndpoint = getPdsEndpoint(didDocument);
+
+
if (!pdsEndpoint) {
+
throw new FailedLexiconResolutionError(nsid, {
+
cause: new TypeError(`no pds service in did document; did=${authority}`),
+
});
+
}
+
+
const rpc = new Client({ handler: new CredentialManager({ service: pdsEndpoint }) });
+
const response = await rpc.get("com.atproto.repo.getRecord", {
+
params: {
+
repo: authority,
+
collection: "com.atproto.lexicon.schema",
+
rkey: nsid,
+
},
+
});
+
+
if (!response.ok) {
+
throw new Error(`got http ${response.status}`);
+
}
+
+
return response.data.value;
+
})();
+
+
schemaCache.set(cacheKey, schemaPromise);
+
+
try {
+
return await schemaPromise;
+
} catch (err) {
+
schemaCache.delete(cacheKey);
+
throw err;
+
}
+
};
+
const extractRefs = (obj: any): Nsid[] => {
const refs: Set<string> = new Set();
···
}
const fetchPromise = (async () => {
+
let authority: AtprotoDid | undefined;
+
const authoritySegment = getAuthoritySegment(nsid);
try {
+
let authorityPromise = authorityCache.get(authoritySegment);
+
if (!authorityPromise) {
+
authorityPromise = resolveLexiconAuthority(nsid);
+
authorityCache.set(authoritySegment, authorityPromise);
+
}
+
authority = await authorityPromise;
+
const schema = await resolveSchema(authority, nsid);
+
resolved.set(nsid, schema);
+
+
const refs = extractRefs(schema);
if (refs.length > 0) {
await Promise.all(
···
} catch (err) {
console.error(`Failed to resolve lexicon ${nsid}:`, err);
failed.add(nsid);
+
authorityCache.delete(authoritySegment);
+
if (authority) {
+
documentCache.delete(authority);
+
}
} finally {
inFlight.delete(nsid);
}
···
}
const lexiconDocs = Object.fromEntries(resolved);
+
console.log(lexiconDocs);
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);
validator.parse({