import { useDebounceFn } from "@vueuse/core";
import {
buildQueryStringFromState,
useFilterStore,
type FilterState,
} from "src/store";
import { type HoneypotEvent } from "src/types";
import { filterEvents } from "utils/filters";
import { URL } from "utils/utils";
import { computed, onMounted, reactive, ref, watch } from "vue";
import { useWebSocket } from "./useWebSocket";
export function useLogEntries(options?: {
filterState?: FilterState;
onLoaded?: (events: HoneypotEvent[]) => void;
}) {
const filterStore = useFilterStore();
const filterState = reactive(options?.filterState || filterStore.state);
const queryString = computed(() => {
const state = { ...filterState };
return buildQueryStringFromState(state);
});
const filterString = computed(() => new URLSearchParams(queryString.value));
const entries = ref<HoneypotEvent[]>([]);
const total = ref(0);
const loading = ref(false);
const error = ref<Error | null>(null);
const { connect, disconnect, connectionStatus } = useWebSocket(
(batch: HoneypotEvent[]) => {
const filtered = filterEvents(batch, filterState);
if (filtered.length > 0) {
entries.value = [...filtered, ...entries.value];
total.value += filtered.length;
// Keep entries list manageable.
const maxEntries = Math.max(filterState.limit, 1000);
if (entries.value.length > maxEntries) {
entries.value = entries.value.slice(0, maxEntries);
}
}
},
);
async function fetchLogs() {
loading.value = true;
error.value = null;
try {
const response = await fetch(`${URL()}/api/events?${queryString.value}`);
const data = await response.json();
entries.value = data.events ?? [];
total.value = data.total ?? 0;
options?.onLoaded?.(data.events ?? []);
} catch (err) {
error.value = err instanceof Error ? err : new Error(String(err));
entries.value = [];
total.value = 0;
} finally {
loading.value = false;
}
}
const debouncedFetchLogs = useDebounceFn(fetchLogs, 250);
onMounted(() => {
fetchLogs();
});
watch(
() => queryString.value,
() => {
debouncedFetchLogs();
},
);
return {
entries,
total,
loading,
error,
fetchLogs,
filterString,
connectionStatus,
connect,
disconnect,
};
}