chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { useQueries } from '@tanstack/react-query';
import { Copyable } from '#/components/molecules/copyable.jsx';
import { identityOf } from '#/lib/identity.js';
import { cn } from '#/lib/utils.js';
/**
* An AT-URI with the DIDs in it read as handles.
*
* A space URI names its authority by DID, and a record URI in a space names the
* authority and the author, so the part a reader can act on is bracketed by two
* opaque strings. Each is shown as its handle instead.
*
* Two rules keep the substitution honest. Only a handle that resolves back to
* the DID is used, because a URI reads as a fact and an unconfirmed handle in
* one would be somebody else's name on an address. And the copy is always the
* canonical URI, DIDs and all, since that is the thing that works when pasted
* anywhere else.
*
* @param {Object} props
* @param {string} props.uri
* @param {string} [props.className]
*/
export function AtUri({ uri, className }) {
const segments = uri.startsWith('at://')
? uri.slice('at://'.length).split('/')
: uri.split('/');
const dids = [...new Set(segments.filter((s) => s.startsWith('did:')))];
// useQueries rather than a hook per DID: the number of DIDs is a property of
// the URI, and a URI that changes would otherwise change the hook count.
const results = useQueries({
queries: dids.map((did) => ({
queryKey: ['identity', did],
queryFn: () => identityOf(did),
retry: false,
staleTime: Number.POSITIVE_INFINITY,
})),
});
/** @type {Map<string, string>} */
const handles = new Map();
dids.forEach((did, index) => {
const found = results[index]?.data;
if (found?.handle && found.verified) handles.set(did, found.handle);
});
// Keyed by where each segment starts in the URI. A URI may name the same DID
// twice, as one does when its authority is also the author, so the text is
// not unique but the offset always is.
let offset = 0;
const parts = segments.map((segment) => {
const at = offset;
offset += segment.length + 1;
return { at, segment, handle: handles.get(segment) };
});
return (
<Copyable value={uri} className={cn('max-w-full', className)}>
<span className="truncate">
{uri.startsWith('at://') && 'at://'}
{parts.map(({ at, segment, handle }) => (
<span key={at}>
{at > 0 && '/'}
{handle ? (
<span
className="text-key underline decoration-dotted underline-offset-2"
title={segment}
>
{handle}
</span>
) : (
segment
)}
</span>
))}
</span>
</Copyable>
);
}