~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
79 lines · 2.7 KB Raw History
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>
  );
}