···
import { Client, CredentialManager } from "@atcute/client";
2
+
import { DidDocument, getPdsEndpoint } from "@atcute/identity";
import { lexiconDoc } from "@atcute/lexicon-doc";
import { RecordValidator } from "@atcute/lexicon-doc/validations";
4
-
import { ResolvedSchema } from "@atcute/lexicon-resolver";
5
+
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";
34
-
import { resolveLexiconAuthority, resolveLexiconSchema, resolvePDS } from "../utils/api.js";
36
+
didDocumentResolver,
37
+
resolveLexiconAuthority,
38
+
resolveLexiconSchema,
40
+
} from "../utils/api.js";
import { AtUri, uriTemplates } from "../utils/templates.js";
import { lexicons } from "../utils/types/lexicons.js";
44
+
const authorityCache = new Map<string, Promise<AtprotoDid>>();
45
+
const documentCache = new Map<string, Promise<DidDocument>>();
46
+
const schemaCache = new Map<string, Promise<unknown>>();
48
+
const getAuthoritySegment = (nsid: string): string => {
49
+
const segments = nsid.split(".");
50
+
return segments.slice(0, -1).join(".");
53
+
const resolveSchema = async (authority: AtprotoDid, nsid: Nsid): Promise<unknown> => {
54
+
const cacheKey = `${authority}:${nsid}`;
56
+
let cachedSchema = schemaCache.get(cacheKey);
58
+
return cachedSchema;
61
+
const schemaPromise = (async () => {
62
+
let didDocPromise = documentCache.get(authority);
63
+
if (!didDocPromise) {
64
+
didDocPromise = didDocumentResolver.resolve(authority);
65
+
documentCache.set(authority, didDocPromise);
68
+
const didDocument = await didDocPromise;
70
+
const pdsEndpoint = getPdsEndpoint(didDocument);
73
+
throw new FailedLexiconResolutionError(nsid, {
74
+
cause: new TypeError(`no pds service in did document; did=${authority}`),
78
+
const rpc = new Client({ handler: new CredentialManager({ service: pdsEndpoint }) });
79
+
const response = await rpc.get("com.atproto.repo.getRecord", {
82
+
collection: "com.atproto.lexicon.schema",
88
+
throw new Error(`got http ${response.status}`);
91
+
return response.data.value;
94
+
schemaCache.set(cacheKey, schemaPromise);
97
+
return await schemaPromise;
99
+
schemaCache.delete(cacheKey);
const extractRefs = (obj: any): Nsid[] => {
const refs: Set<string> = new Set();
···
const fetchPromise = (async () => {
155
+
let authority: AtprotoDid | undefined;
156
+
const authoritySegment = getAuthoritySegment(nsid);
90
-
const authority = await resolveLexiconAuthority(nsid);
91
-
const schema = await resolveLexiconSchema(authority, nsid);
158
+
let authorityPromise = authorityCache.get(authoritySegment);
159
+
if (!authorityPromise) {
160
+
authorityPromise = resolveLexiconAuthority(nsid);
161
+
authorityCache.set(authoritySegment, authorityPromise);
93
-
resolved.set(nsid, schema.rawSchema);
164
+
authority = await authorityPromise;
165
+
const schema = await resolveSchema(authority, nsid);
95
-
const refs = extractRefs(schema.rawSchema);
167
+
resolved.set(nsid, schema);
169
+
const refs = extractRefs(schema);
···
console.error(`Failed to resolve lexicon ${nsid}:`, err);
179
+
authorityCache.delete(authoritySegment);
181
+
documentCache.delete(authority);
···
const lexiconDocs = Object.fromEntries(resolved);
261
+
console.log(lexiconDocs);
const validator = new RecordValidator(lexiconDocs, params.collection as Nsid);