···17171818 /** iterate over the channel's history.
1919 * todo: improve documentation
2020- * @param [start_at="latest"] the timestamp to start fetching messages from. if the range
2121- * is `{ before: x }`, messages will be fetched in reverse order
2222- * (going forwards through time).
2020+ * @param [start_at="latest"] the timestamp to start fetching messages from.
2321 * @param [chunk_size=50]
2422 */
2523 async *history(start_at: FetchHistoryParams[1] = "latest", chunk_size = 50) {
2624 let next_range = start_at;
27252826 while (true) {
2929- // fetch a page of history
3030- let page = await this.fetch_history_page(next_range, chunk_size);
3131-3232- if (!page) return;
3333-3434- // are we going backwards or forwards through history?
3535- let going_backwards
3636- = (typeof next_range != 'string' && 'after' in next_range)
3737- || next_range == "latest";
3838-3939- // console.log("next_range", next_range);
4040- // are we looking at a limited range of history?
4141- let is_limited = typeof next_range != 'string' && 'during' in next_range;
4242-4343- console.log(page, page.at(-1)?.timestamp, page[0]?.timestamp)
4444-4545- if (going_backwards) {
4646- // get the oldest message of the page
4747- let oldest = page.at(-1)?.timestamp;
4848- // if there's no oldest message, we must be out of messages to show.
4949- if (!oldest) break;
5050-5151- // set the range for the next iteration
5252- next_range = { after: oldest };
2727+ const messages = await this.fetch_history_page(next_range, chunk_size);
2828+ // console.log(messages.length, messages[0])
2929+ if (messages.length == 0) {
3030+ console.log("exhausted history");
3131+ return;
3232+ };
53335454- page.reverse();
5555- } else {
5656- // as above, but inverted
5757- let newest = page.at(0)?.timestamp;
5858- if (!newest) break;
5959-6060- next_range = { before: newest };
3434+ for (const message of messages) {
3535+ yield message;
6136 }
62376363- // yield messages from the page until we're done
6464- for (const msg of page) {
6565- yield msg;
3838+ next_range = {
3939+ before: messages[0].timestamp!
6640 }
6767-6868- // TODO: `during` logic
6969- if (is_limited) throw "todo";
7041 }
7142 }
72437344 async fetch_history_page(range: FetchHistoryParams[1], chunk_size = 50) {
7474- return this.conn.fetch_history?.(
4545+ if (!this.conn.fetch_history) throw new Error("No history fetcher registered")
4646+ return this.conn.fetch_history(
7547 this.name,
7648 range,
7749 chunk_size
+5-2
core/connection.ts
···6666 handler?: MessageHandler,
6767 history_fetcher?: (conn: Connection, ...params: FetchHistoryParams) => Promise<IrcMessage[]>,
6868 on_connect?: (conn: Connection) => void,
6969+ debug?: boolean,
6970}
70717172export enum ConnectionState {
···117118 if (opt.handler) this.handler = opt.handler;
118119 if (opt.history_fetcher) this.fetch_history = (...params) => opt.history_fetcher!(this, ...params);
119120 if (opt.on_connect) this.on_connect = opt.on_connect;
121121+ if (opt.debug) this.debug = opt.debug;
120122 }
121123122124 this.nickname = config.nickname;
···132134 hostname?: string;
133135 motd: string | null = null;
134136 system_msgs = <string[]>[]
137137+ debug = true;
135138136139 /**
137140 * Map of capabilities that have been negotiated and are able to be used.
···156159 on_connect?: (conn: Connection) => void;
157160158161 send(message: string) {
159159- console.debug(`${this.id} ← SENT: ${message}`);
162162+ if (this.debug) console.debug(`${this.id} ← SENT: ${message}`);
160163 this.send_raw(message);
161164 }
162165···194197195198 parsed.timestamp = new Date(server_time ?? Date.now());
196199197197- console.debug(`${this.id} → RECEIVED: ${message}`, parsed);
200200+ if (this.debug) console.debug(`${this.id} → RECEIVED: ${message}`, parsed);
198201199202 // resolve pending tasks
200203 this.queue.resolve_tasks(parsed, { batch });
+10-8
core/history.ts
···11-import { Connection } from ".";
11+import { Connection } from "./index";
22import { IrcMessage } from "./parser";
3344export type FetchHistoryParams
···1111 limit: number
1212 ]
13131414-async function chathistory(conn: Connection, ...[target, range, limit]: FetchHistoryParams): Promise<IrcMessage[]> {
1414+/**
1515+ * History fetchers fetch history from locations.
1616+ * Messages returned from history fetchers must be sorted in ascending order
1717+ */
1818+export type HistoryFetcher = (conn: Connection, params: FetchHistoryParams) => Promise<IrcMessage[]>;
1919+2020+export const chathistory = async (conn: Connection, ...[target, range, limit]: FetchHistoryParams): Promise<IrcMessage[]> => {
1521 if (!conn.capabilities.has('draft/chathistory')) {
1616- console.log("no cathistory pensive emoji")
2222+ console.log("no chathistory pensive emoji")
1723 return [];
1824 }
1925···35413642 const msgs = await conn.collect_batch("chathistory", { mask: true, params: [target] });
3743 console.log(msgs);
3838- return msgs.toReversed();
4444+ return msgs;
3945}
4040-4141-export default class History {
4242- static chathistory = chathistory;
4343-}
···5353 <h2>bouncers</h2>
5454 <div class="panel">
5555 <p class="intro body-small">
5656- a bouncer is an external service that stays connected to your
5656+ bouncers are external services that stay connected to your
5757 networks while tubes is closed, so you can see what people were
5858 saying in the chat rooms while you were away, among other things.
5959 <br />
6060 please note that sometimes the network you're connecting will
6161- do all this for you.
6161+ do all this for you. we live in exciting times.
6262 </p>
63636464 <div>