feat: complete Ancestor quote bot with production-ready Docker support

This commit is contained in:
unfunny
2026-09-13 14:14:38 -04:00
parent f2016da05a
commit fe7351a7dc
1145 changed files with 30890 additions and 97684 deletions

View File

@@ -1,6 +1,6 @@
import { type MatrixClient } from "./client.ts";
import { type IRoomEvent, type IStateEvent } from "./sync-accumulator.ts";
import { TypedEventEmitter } from "./models/typed-event-emitter.ts";
import { MatrixClient } from "./client";
import { IRoomEvent, IStateEvent } from "./sync-accumulator";
import { TypedEventEmitter } from "./models/typed-event-emitter";
export declare const MSC3575_WILDCARD = "*";
export declare const MSC3575_STATE_KEY_ME = "$ME";
export declare const MSC3575_STATE_KEY_LAZY = "$LAZY";
@@ -48,22 +48,10 @@ export interface MSC3575SlidingSyncRequest {
timeout?: number;
clientTimeout?: number;
}
/**
* New format of hero introduced in MSC4186 with display name and avatar URL
* in addition to just user_id (as it is on the wire, with underscores)
* as opposed to Hero in room-summary.ts which has fields in camelCase
* (and also a flag to note what format the hero came from).
*/
export interface MSC4186Hero {
user_id: string;
displayname?: string;
avatar_url?: string;
}
export interface MSC3575RoomData {
name: string;
required_state: IStateEvent[];
timeline: (IRoomEvent | IStateEvent)[];
heroes?: MSC4186Hero[];
notification_count?: number;
highlight_count?: number;
joined_count?: number;
@@ -74,11 +62,33 @@ export interface MSC3575RoomData {
is_dm?: boolean;
prev_batch?: string;
num_live?: number;
bump_stamp?: number;
}
interface ListResponse {
count: number;
ops: Operation[];
}
interface BaseOperation {
op: string;
}
interface DeleteOperation extends BaseOperation {
op: "DELETE";
index: number;
}
interface InsertOperation extends BaseOperation {
op: "INSERT";
index: number;
room_id: string;
}
interface InvalidateOperation extends BaseOperation {
op: "INVALIDATE";
range: [number, number];
}
interface SyncOperation extends BaseOperation {
op: "SYNC";
range: [number, number];
room_ids: string[];
}
type Operation = DeleteOperation | InsertOperation | InvalidateOperation | SyncOperation;
/**
* A complete Sliding Sync response
*/
@@ -110,7 +120,7 @@ export declare enum ExtensionState {
/**
* An interface that must be satisfied to register extensions
*/
export interface Extension<Req extends object, Res extends object> {
export interface Extension<Req extends {}, Res extends {}> {
/**
* The extension name to go under 'extensions' in the request body.
* @returns The JSON key.
@@ -119,15 +129,15 @@ export interface Extension<Req extends object, Res extends object> {
/**
* A function which is called when the request JSON is being formed.
* Returns the data to insert under this key.
* @param isInitial - True when this is part of the initial request.
* @param isInitial - True when this is part of the initial request (send sticky params)
* @returns The request JSON to send.
*/
onRequest(isInitial: boolean): Promise<Req>;
onRequest(isInitial: boolean): Req | undefined;
/**
* A function which is called when there is response JSON under this extension.
* @param data - The response JSON under the extension name.
*/
onResponse(data: Res): Promise<void>;
onResponse(data: Res): void;
/**
* Controls when onResponse should be called.
* @returns The state when it should be called.
@@ -139,10 +149,12 @@ export interface Extension<Req extends object, Res extends object> {
* of information when processing sync responses.
* - RoomData: concerns rooms, useful for SlidingSyncSdk to update its knowledge of rooms.
* - Lifecycle: concerns callbacks at various well-defined points in the sync process.
* - List: concerns lists, useful for UI layers to re-render room lists.
* Specifically, the order of event invocation is:
* - Lifecycle (state=RequestFinished)
* - RoomData (N times)
* - Lifecycle (state=Complete)
* - List (at most once per list)
*/
export declare enum SlidingSyncEvent {
/**
@@ -155,13 +167,21 @@ export declare enum SlidingSyncEvent {
* - SlidingSyncState.RequestFinished: Fires after we receive a valid response but before the
* response has been processed. Perform any pre-process steps here. If there was a problem syncing,
* `err` will be set (e.g network errors).
* - SlidingSyncState.Complete: Fires after the response has been processed.
* - SlidingSyncState.Complete: Fires after all SlidingSyncEvent.RoomData have been fired but before
* SlidingSyncEvent.List.
*/
Lifecycle = "SlidingSync.Lifecycle"
Lifecycle = "SlidingSync.Lifecycle",
/**
* This event fires whenever there has been a change to this list index. It fires exactly once
* per list, even if there were multiple operations for the list.
* It fires AFTER Lifecycle and RoomData events.
*/
List = "SlidingSync.List"
}
export type SlidingSyncEventHandlerMap = {
[SlidingSyncEvent.RoomData]: (roomId: string, roomData: MSC3575RoomData) => Promise<void> | void;
[SlidingSyncEvent.Lifecycle]: (state: SlidingSyncState, resp: MSC3575SlidingSyncResponse | null, err?: Error) => void;
[SlidingSyncEvent.List]: (listKey: string, joinedCount: number, roomIndexToRoomId: Record<number, string>) => void;
};
/**
* SlidingSync is a high-level data structure which controls the majority of sliding sync.
@@ -178,6 +198,8 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
private listModifiedCount;
private terminated;
private needsResend;
private txnId;
private txnIdDefers;
private extensions;
private desiredRoomSubscriptions;
private confirmedRoomSubscriptions;
@@ -217,6 +239,7 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
*/
getListData(key: string): {
joinedCount: number;
roomIndexToRoomId: Record<number, string>;
} | null;
/**
* Get the full request list parameters for a list index. This function is provided for callers to use
@@ -235,7 +258,7 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
setListRanges(key: string, ranges: number[][]): void;
setListRanges(key: string, ranges: number[][]): Promise<string>;
/**
* Add or replace a list. Calling this function will interrupt the /sync request to resend new
* lists.
@@ -245,7 +268,7 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
setList(key: string, list: MSC3575List): void;
setList(key: string, list: MSC3575List): Promise<string>;
/**
* Get the room subscriptions for the sync API.
* @returns A copy of the desired room subscriptions.
@@ -256,14 +279,20 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
* /sync request to resend new subscriptions. If the /sync stream has not started, this will
* prepare the room subscriptions for when start() is called.
* @param s - The new desired room subscriptions.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
modifyRoomSubscriptions(s: Set<string>): void;
modifyRoomSubscriptions(s: Set<string>): Promise<string>;
/**
* Modify which events to retrieve for room subscriptions. Invalidates all room subscriptions
* such that they will be sent up afresh.
* @param rs - The new room subscription fields to fetch.
* @returns A promise which resolves to the transaction ID when it has been received down sync
* (or rejects with the transaction ID if the action was not applied e.g the request was cancelled
* immediately after sending, in which case the action will be applied in the subsequent request)
*/
modifyRoomSubscriptionInfo(rs: MSC3575RoomSubscription): void;
modifyRoomSubscriptionInfo(rs: MSC3575RoomSubscription): Promise<string>;
/**
* Register an extension to send with the /sync request.
* @param ext - The extension to register.
@@ -285,10 +314,18 @@ export declare class SlidingSync extends TypedEventEmitter<SlidingSyncEvent, Sli
* @param err - Any error that occurred when making the request e.g. network errors.
*/
private invokeLifecycleListeners;
private shiftRight;
private shiftLeft;
private removeEntry;
private addEntry;
private processListOps;
/**
* Resend a Sliding Sync request. Used when something has changed in the request.
* Resend a Sliding Sync request. Used when something has changed in the request. Resolves with
* the transaction ID of this request on success. Rejects with the transaction ID of this request
* on failure.
*/
resend(): void;
resend(): Promise<string>;
private resolveTransactionDefers;
/**
* Stop syncing with the server.
*/