Browse Source

Add NODEDB_RETENTION_NUM

pull/780/head
philon- 11 months ago
parent
commit
ffa9985ffd
  1. 82
      packages/web/src/core/stores/nodeDBStore/index.ts
  2. 2
      packages/web/src/core/stores/utils/indexDB.ts

82
packages/web/src/core/stores/nodeDBStore/index.ts

@ -1,5 +1,5 @@
import { create } from "@bufbuild/protobuf"; import { create } from "@bufbuild/protobuf";
import { createStorageWithMapSupport } from "@core/stores/utils/indexDB.ts"; import { createStorage } from "@core/stores/utils/indexDB.ts";
import { Protobuf, type Types } from "@meshtastic/core"; import { Protobuf, type Types } from "@meshtastic/core";
import { produce } from "immer"; import { produce } from "immer";
import { create as createStore } from "zustand"; import { create as createStore } from "zustand";
@ -8,6 +8,8 @@ import type { NodeError, NodeErrorType, ProcessPacketParams } from "./types";
const CURRENT_STORE_VERSION = 0; const CURRENT_STORE_VERSION = 0;
const NODEDB_RETENTION_NUM = 10;
export interface NodeDB { export interface NodeDB {
id: number; id: number;
myNodeNum: number | undefined; myNodeNum: number | undefined;
@ -91,9 +93,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
nodeDB.nodeMap.set(node.num, node); nodeDB.nodeMap.set(node.num, node);
}), }),
@ -104,9 +104,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
nodeDB.nodeMap.delete(nodeNum); nodeDB.nodeMap.delete(nodeNum);
}), }),
@ -117,9 +115,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
nodeDB.nodeErrors.set(nodeNum, { node: nodeNum, error }); nodeDB.nodeErrors.set(nodeNum, { node: nodeNum, error });
}), }),
@ -130,9 +126,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
nodeDB.nodeErrors.delete(nodeNum); nodeDB.nodeErrors.delete(nodeNum);
}), }),
@ -143,9 +137,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const node = nodeDB.nodeMap.get(data.from); const node = nodeDB.nodeMap.get(data.from);
if (node) { if (node) {
@ -170,9 +162,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const current = const current =
nodeDB.nodeMap.get(user.from) ?? nodeDB.nodeMap.get(user.from) ??
@ -188,9 +178,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const current = const current =
nodeDB.nodeMap.get(position.from) ?? nodeDB.nodeMap.get(position.from) ??
@ -238,9 +226,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const node = nodeDB.nodeMap.get(nodeNum); const node = nodeDB.nodeMap.get(nodeNum);
@ -255,9 +241,7 @@ function nodeDBFactory(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
const nodeDB = draft.nodeDBs.get(id); const nodeDB = draft.nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const node = nodeDB.nodeMap.get(nodeNum); const node = nodeDB.nodeMap.get(nodeNum);
@ -270,9 +254,7 @@ function nodeDBFactory(
getNodesLength: () => { getNodesLength: () => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
return nodeDB.nodeMap.size; return nodeDB.nodeMap.size;
}, },
@ -280,9 +262,7 @@ function nodeDBFactory(
getNode: (nodeNum) => { getNode: (nodeNum) => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
return nodeDB.nodeMap.get(nodeNum); return nodeDB.nodeMap.get(nodeNum);
}, },
@ -290,12 +270,10 @@ function nodeDBFactory(
getNodes: (filter) => { getNodes: (filter) => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
const all = Array.from(nodeDB.nodeMap.values()).filter( const all = Array.from(nodeDB.nodeMap.values()).filter(
(n) => n.num !== myNodeNum, (n) => n.num !== nodeDB.myNodeNum,
); );
return filter ? all.filter(filter) : all; return filter ? all.filter(filter) : all;
}, },
@ -303,24 +281,21 @@ function nodeDBFactory(
getMyNode: () => { getMyNode: () => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
if (!myNodeNum) { if (!nodeDB.myNodeNum) {
throw new Error(`No myNodeNum set for nodeDB with id: ${id}`); throw new Error(`No myNodeNum set for nodeDB with id: ${id}`);
} }
return ( return (
nodeDB.nodeMap.get(myNodeNum) ?? create(Protobuf.Mesh.NodeInfoSchema) nodeDB.nodeMap.get(nodeDB.myNodeNum) ??
create(Protobuf.Mesh.NodeInfoSchema)
); );
}, },
getNodeError: (nodeNum) => { getNodeError: (nodeNum) => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
return nodeDB.nodeErrors.get(nodeNum); return nodeDB.nodeErrors.get(nodeNum);
}, },
@ -328,9 +303,7 @@ function nodeDBFactory(
hasNodeError: (nodeNum) => { hasNodeError: (nodeNum) => {
const nodeDB = get().nodeDBs.get(id); const nodeDB = get().nodeDBs.get(id);
if (!nodeDB) { if (!nodeDB) {
throw new Error( throw new Error(`No nodeDB found (id: ${id})`);
`No nodeDB found for myNodeNum: ${myNodeNum} (id: ${id})`,
);
} }
return nodeDB.nodeErrors.has(nodeNum); return nodeDB.nodeErrors.has(nodeNum);
}, },
@ -352,8 +325,17 @@ export const useNodeDBStore = createStore<PrivateNodeDBState>()(
set( set(
produce<PrivateNodeDBState>((draft) => { produce<PrivateNodeDBState>((draft) => {
draft.nodeDBs.set(id, nodeDB); draft.nodeDBs.set(id, nodeDB);
// If over limit, remove oldest inserted. FIFO
if (draft.nodeDBs.size > NODEDB_RETENTION_NUM) {
const firstKey = draft.nodeDBs.keys().next().value;
if (firstKey !== undefined) {
draft.nodeDBs.delete(firstKey);
}
}
}), }),
); );
return nodeDB; return nodeDB;
}, },
removeNodeDB: (userId) => { removeNodeDB: (userId) => {
@ -368,7 +350,7 @@ export const useNodeDBStore = createStore<PrivateNodeDBState>()(
}), }),
{ {
name: "meshtastic-nodedb-store", name: "meshtastic-nodedb-store",
storage: createStorageWithMapSupport<NodeDBPersisted>(), storage: createStorage<NodeDBPersisted>(),
version: CURRENT_STORE_VERSION, version: CURRENT_STORE_VERSION,
partialize: (s): NodeDBPersisted => ({ partialize: (s): NodeDBPersisted => ({
nodeDBs: new Map( nodeDBs: new Map(

2
packages/web/src/core/stores/utils/indexDB.ts

@ -94,7 +94,7 @@ function makeJson<H extends Handler<unknown, string, unknown>>(
return { replacer, reviver }; return { replacer, reviver };
} }
export function createStorageWithMapSupport< export function createStorage<
T, T,
H extends Handler<unknown, string, unknown> = never, H extends Handler<unknown, string, unknown> = never,
>(extraHandlers: readonly H[] = [] as const): PersistStorage<T> { >(extraHandlers: readonly H[] = [] as const): PersistStorage<T> {

Loading…
Cancel
Save