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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
58 lines · 1.9 KB Raw History
/**
 * Which refs moved between two versions of a repository record.
 *
 * The record carries every ref with its object id, so a push is detectable
 * from the record alone. No git connection is needed to decide whether to run.
 */

/**
 * @typedef {Object} RefChange
 * @property {string} name - full ref name
 * @property {string} sha - object id it points at now
 * @property {string|null} previousSha - null when the ref is new
 */

/**
 * Refs that are new or point somewhere else than the last run saw. A ref that
 * disappeared is not a change: deleting a branch starts no run.
 * @param {Record<string, string>} previous - ref name to object id
 * @param {Array<{name: string, sha: string}>} current
 * @returns {RefChange[]}
 */
export function diffRefs(previous, current) {
  /** @type {RefChange[]} */
  const changes = [];
  for (const ref of current) {
    const previousSha = previous[ref.name] ?? null;
    if (previousSha === ref.sha) continue;
    changes.push({ name: ref.name, sha: ref.sha, previousSha });
  }
  return changes;
}

/**
 * Refs the last run saw that are not there now.
 *
 * Deleting a branch starts no run, so `diffRefs` passes over these. What they
 * do end is the branch's history: a rebase and a name reused for other work
 * both give a tip the last one cannot reach, and nothing in the graph tells
 * the two apart. The deletion does.
 * @param {Record<string, string>} previous - ref name to object id
 * @param {Array<{name: string, sha: string}>} current
 * @returns {string[]} full ref names
 */
export function removedRefs(previous, current) {
  const held = new Set(current.map((ref) => ref.name));
  return Object.keys(previous).filter((name) => !held.has(name));
}

/**
 * @param {Array<{name: string, sha: string}>} refs
 * @returns {Record<string, string>}
 */
export function refsToState(refs) {
  /** @type {Record<string, string>} */
  const state = {};
  for (const ref of refs) state[ref.name] = ref.sha;
  return state;
}