/** * The article number where a group's posts reach `target` (ms since epoch), * by binary search between `first` and `last`. Article numbers only roughly * follow posting time, so the answer is within `precision` articles of the * first one posted at or after `target`. * * `dateOf(n)` returns the posting time of the first article at or after `n` * that still exists, or null when there is none nearby (expired or removed); * a gap counts as older than `target`. */ export async function articleAtDate( first: bigint, last: bigint, target: number, dateOf: (n: bigint) => Promise, precision = 10_000n ): Promise { let lo = first let hi = last while (hi - lo > precision) { const mid = lo + (hi - lo) / 2n const date = await dateOf(mid) if (date === null || date < target) lo = mid else hi = mid } return lo }