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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
59 lines · 2.2 KB Raw History
// Issue threads about a repository, as the page reads them.
//
// An issue is a record in its filer's repo, a reply is a record naming its
// parent, and the owner's disposition record is what a reader shows as the
// issue's state. The statements come from the repository's own server, which
// reads every voice's own repo; the page threads them and reads the state.

import { issueState, issueThreads } from '@pdsjs/git/issues';

export { issueState, issueThreads };

import { learnProfiles } from './authors.js';
import { ownerClient, serverClient } from './git.js';

/**
 * The issues a visitor filed this session, by repository then by record uri.
 * A freshly filed issue is a record in the filer's own repo. If the filer is
 * nobody the repository lists, the server finds it only through discovery,
 * which lags, so the filer would not see their own words on the list until it
 * caught up. Held here, the words show at once, and drop once the server
 * lists the same uri.
 * @type {Map<string, Map<string, Record<string, *>>>}
 */
const filed = new Map();

/**
 * Keep an issue the visitor just filed, so the list shows it before the
 * server's own read finds it.
 * @param {string} repo
 * @param {Record<string, *>} statement
 */
export function rememberFiledIssue(repo, statement) {
  const mine = filed.get(repo) ?? new Map();
  mine.set(statement.uri, statement);
  filed.set(repo, mine);
}

/**
 * Everything said in this repository's issue threads, as the server lists
 * it, with the visitor's own just-filed issues folded in and the faces and
 * names of every voice learned alongside.
 * @param {string} repo - what the repository is called
 * @param {string} [space]
 * @returns {Promise<Array<Record<string, *>>>}
 */
export async function loadIssueStatements(repo, space) {
  const { statements } = await (space
    ? ownerClient()
    : await serverClient()
  ).listIssues({ repo, space });
  const mine = filed.get(repo);
  if (mine) {
    const listed = new Set(statements.map((one) => one.uri));
    for (const uri of [...mine.keys()]) if (listed.has(uri)) mine.delete(uri);
  }
  const all = [...(mine?.values() ?? []), ...statements];
  await learnProfiles([...new Set(all.map((one) => one.by.did))]);
  return all;
}