Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@

**Learning:** Using `on:keyup` for search input debouncing triggers unnecessary API calls on navigation keys (arrows, home, end) and misses changes from paste/cut. Svelte's reactive statements `$: debounce(value)` provide a robust, declarative way to trigger debouncing only when the value actually changes.
**Action:** Replace `on:keyup` handlers with reactive statements for input debouncing to improve performance and correctness.

## 2024-05-23 - Client-side Caching bounded by session duration

**Learning:** Caching bounded by session duration in Svelte applications is best accomplished by using a module-scoped `Map` in `<script context="module">`. This effectively caches repetitive data fetches (like identical user queries) while preventing the cache from growing indefinitely (since it resets on app reload/session end).
**Action:** Always prefer module-scoped `Map`s for caching over stores if the data doesn't require reactivity to update the UI on change, but rather needs to provide data quickly.
22 changes: 21 additions & 1 deletion src/routes/DomainSearch.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
<script context="module" lang="ts">
import type { Domain as DomainModel } from '@metanames/sdk';

type CacheEntry = {
domain: DomainModel | null | undefined;
timestamp: number;
};

const searchCache = new Map<string, CacheEntry>();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
</script>

<script lang="ts">
import Card, { Content as CardContent } from '@smui/card';
import CircularProgress from '@smui/circular-progress';
import Textfield from '@smui/textfield';
import HelperText from '@smui/textfield/helper-text';
import type { Domain as DomainModel } from '@metanames/sdk';
import IconButton from '@smui/icon-button';
import { metaNamesSdk } from '$lib/stores/sdk';
import { goto } from '$app/navigation';
Expand Down Expand Up @@ -42,13 +53,22 @@

const currentRequestId = ++requestId;
nameSearched = domainName.toLocaleLowerCase();

const cachedItem = searchCache.get(nameSearched);
if (cachedItem && Date.now() < cachedItem.timestamp + CACHE_TTL) {
domain = cachedItem.domain;
isLoading = false;
return;
}

isLoading = true;

const result = await $metaNamesSdk.domainRepository.find(domainName);

if (currentRequestId === requestId) {
domain = result;
isLoading = false;
searchCache.set(nameSearched, { domain, timestamp: Date.now() });
}
}

Expand Down