Persistent message store (#814)

* Fix default filter behaviour

* Persist message store

* messageStore tests, node PKI validation

Implement node validation and improve merging logic

- Added `validateIncomingNode` function to validate new nodes against existing nodes, checking for public key conflicts and ensuring proper handling of node updates.
- Updated `nodeDBFactory` to utilize the new validation function when adding nodes.
- Enhanced `getNodes` method to optionally include the current node in the results.
- Removed the `mergeNodeInfo` utility as its functionality is now integrated into the validation and merging process.
- Updated tests to cover new validation logic and ensure correct behavior during node addition and merging.
- Cleaned up unused utility functions related to key comparison.

* refactor: reuse eviction logic for message and node stores

* Update format, move hooks

* Improve test performance

* Update imports

---------

Co-authored-by: philon- <philon-@users.noreply.github.com>
Co-authored-by: Dan Ditomaso <dan.ditomaso@gmail.com>
This commit is contained in:
Jeremy Gallant
2025-09-03 21:00:48 -04:00
committed by GitHub
co-authored by philon- Dan Ditomaso
parent 799283fd46
commit dcb44d27fe
24 changed files with 1092 additions and 353 deletions
@@ -1,10 +1,13 @@
import { DeleteMessagesDialog } from "@components/Dialog/DeleteMessagesDialog/DeleteMessagesDialog.tsx";
import { useMessageStore } from "@core/stores";
import { type MessageStore, useMessages } from "@core/stores";
import { fireEvent, render, screen } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("@core/stores", () => ({
useMessageStore: vi.fn(() => ({
CurrentDeviceContext: {
_currentValue: { deviceId: 1234 },
},
useMessages: vi.fn(() => ({
deleteAllMessages: vi.fn(),
})),
}));
@@ -17,11 +20,14 @@ describe("DeleteMessagesDialog", () => {
mockOnOpenChange.mockClear();
mockClearAllMessages.mockClear();
const mockedUseMessageStore = vi.mocked(useMessageStore);
mockedUseMessageStore.mockImplementation(() => ({
deleteAllMessages: mockClearAllMessages,
}));
mockedUseMessageStore.mockClear();
const mockedUseMessages = vi.mocked(useMessages);
mockedUseMessages.mockImplementation(
() =>
({
deleteAllMessages: mockClearAllMessages,
}) as unknown as MessageStore,
);
mockedUseMessages.mockClear();
});
it("calls onOpenChange with false when the close button (X) is clicked", () => {
@@ -8,7 +8,7 @@ import {
DialogHeader,
DialogTitle,
} from "@components/UI/Dialog.tsx";
import { useMessageStore } from "@core/stores";
import { useMessages } from "@core/stores";
import { AlertTriangleIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
@@ -22,7 +22,7 @@ export const DeleteMessagesDialog = ({
onOpenChange,
}: DeleteMessagesDialogProps) => {
const { t } = useTranslation("dialog");
const { deleteAllMessages } = useMessageStore();
const { deleteAllMessages } = useMessages();
const handleCloseDialog = () => {
onOpenChange(false);
};
@@ -6,7 +6,7 @@ import {
DialogHeader,
DialogTitle,
} from "@components/UI/Dialog.tsx";
import { useMessageStore, useNodeDB } from "@core/stores";
import { useMessages, useNodeDB } from "@core/stores";
import { LockKeyholeOpenIcon } from "lucide-react";
import { useTranslation } from "react-i18next";
import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts";
@@ -21,7 +21,7 @@ export const RefreshKeysDialog = ({
onOpenChange,
}: RefreshKeysDialogProps) => {
const { t } = useTranslation("dialog");
const { activeChat } = useMessageStore();
const { activeChat } = useMessages();
const { nodeErrors, getNode } = useNodeDB();
const { handleCloseDialog, handleNodeRemove } = useRefreshKeysDialog();
@@ -1,10 +1,10 @@
import { useDevice, useMessageStore, useNodeDB } from "@core/stores";
import { useDevice, useMessages, useNodeDB } from "@core/stores";
import { useCallback } from "react";
export function useRefreshKeysDialog() {
const { setDialogOpen } = useDevice();
const { removeNode, clearNodeError, getNodeError } = useNodeDB();
const { activeChat } = useMessageStore();
const { activeChat } = useMessages();
const handleCloseDialog = useCallback(() => {
setDialogOpen("refreshKeys", false);