import { getDeletedClients, confirmDeletedClients } from "../../../replicache/src/deleted-clients.js";
import { withRead, withWrite } from "../../../replicache/src/with-transactions.js";
import { assert } from "../../../shared/src/asserts.js";
import { promiseVoid } from "../../../shared/src/resolved-promises.js";
function filterAndAssert(deletedClients, clientGroupID, clientID, caller) {
  const clientIDs = deletedClients.filter((dc) => dc.clientGroupID === clientGroupID).map((dc) => dc.clientID);
  for (const cid of clientIDs) {
    assert(cid !== clientID, `cannot delete self in ${caller}`);
  }
  return clientIDs;
}
class DeleteClientsManager {
  #send;
  #lc;
  #dagStore;
  #clientGroupID;
  #clientID;
  constructor(send, dagStore, lc, clientGroupID, clientID) {
    this.#send = send;
    this.#dagStore = dagStore;
    this.#lc = lc;
    this.#clientGroupID = clientGroupID;
    this.#clientID = clientID;
  }
  /**
   * This gets called by Replicache when it deletes clients from the persistent
   * storage.
   */
  async onClientsDeleted(deletedClients) {
    this.#lc.debug?.("DeletedClientsManager, send:", deletedClients);
    const clientGroupID = await this.#clientGroupID;
    const clientIDs = filterAndAssert(
      deletedClients,
      clientGroupID,
      this.#clientID,
      "onClientsDeleted"
    );
    this.#send([
      "deleteClients",
      {
        clientIDs
      }
    ]);
  }
  /**
   * Zero calls this after it connects to ensure that the server knows about all
   * the clients that might have been deleted locally since the last connection.
   */
  async sendDeletedClientsToServer() {
    const clientGroupID = await this.#clientGroupID;
    const deleted = await withRead(
      this.#dagStore,
      (dagRead) => getDeletedClients(dagRead)
    );
    const clientIDs = filterAndAssert(
      deleted,
      clientGroupID,
      this.#clientID,
      "sendDeletedClientsToServer"
    );
    if (clientIDs.length > 0) {
      this.#send(["deleteClients", { clientIDs }]);
      this.#lc.debug?.("DeletedClientsManager, send:", deleted);
    }
  }
  /**
   * This is called as a response to the server telling us which clients it
   * actually deleted.
   */
  clientsDeletedOnServer(deletedClients) {
    const { clientIDs = [], clientGroupIDs = [] } = deletedClients;
    if (clientIDs.length > 0 || clientGroupIDs.length > 0) {
      return withWrite(this.#dagStore, async (dagWrite) => {
        this.#lc.debug?.("clientsDeletedOnServer:", clientIDs, clientGroupIDs);
        await confirmDeletedClients(dagWrite, clientIDs, clientGroupIDs);
      });
    }
    return promiseVoid;
  }
  async getDeletedClients() {
    const deletedClients = await withRead(
      this.#dagStore,
      (read) => getDeletedClients(read)
    );
    const clientGroupID = await this.#clientGroupID;
    filterAndAssert(
      deletedClients,
      clientGroupID,
      this.#clientID,
      "getDeletedClients"
    );
    return deletedClients.filter((d) => d.clientGroupID === clientGroupID);
  }
}
export {
  DeleteClientsManager
};
//# sourceMappingURL=delete-clients-manager.js.map
