From 91474cf9b71660e5b27bb2202894ac9c7f98c72d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 20:57:29 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Use=20keyed=20loops=20in=20?= =?UTF-8?q?Records=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 💡 What: Added unique keys to `{#each}` loops in `src/components/Records.svelte` (`Object.keys(records)` and `unusedRecordsClasses`). 🎯 Why: Prevents inefficient DOM updates and potential state corruption in `RecordComponent` when the list of records changes. Without keys, Svelte may reuse component instances incorrectly, leading to stale or incorrect internal state (e.g., `edit` mode or uninitialized values). 📊 Impact: Reduces unnecessary re-renders and ensures correct component lifecycle. While difficult to quantify in micro-benchmarks without user interaction, it eliminates a class of potential bugs and improves rendering efficiency for dynamic lists. 🔬 Measurement: Verified by manual code review and ensuring `yarn vitest run` passes. The change is a standard Svelte best practice for dynamic lists. Note: Ran `yarn format` which updated formatting in several files to comply with project linting rules. Co-authored-by: Yeboster <23556525+Yeboster@users.noreply.github.com> --- .github/dependabot.yml | 6 +++--- .jules/bolt.md | 3 +++ src/components/DomainPayment.svelte | 8 ++++++-- src/components/LoadingButton.svelte | 2 +- src/components/Record.svelte | 14 +++++++++++--- src/components/Records.svelte | 5 +++-- src/lib/sdk.ts | 2 +- src/lib/server/index.ts | 1 - src/lib/types.ts | 8 ++++---- src/lib/url.ts | 9 ++++----- src/routes/+layout.svelte | 1 - .../register/[name]/fees/[coin]/+server.ts | 19 +++++++++++-------- src/routes/profile/+page.svelte | 1 - src/styles/mixins.scss | 2 +- src/theme/dark/_smui-theme.scss | 2 +- 15 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 42adb44..301e978 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,7 +5,7 @@ version: 2 updates: - - package-ecosystem: "npm" - directory: "/" + - package-ecosystem: 'npm' + directory: '/' schedule: - interval: "weekly" + interval: 'weekly' diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..1b84369 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-10-27 - Svelte Keyed Loops +**Learning:** Svelte `{#each}` loops iterating over dynamic keys (e.g. `Object.keys`) without a keyed identifier can lead to inefficient DOM updates and state corruption in child components. +**Action:** Always verify `{#each}` loops use a unique key, especially when rendering stateful components or when the list order/content changes frequently. diff --git a/src/components/DomainPayment.svelte b/src/components/DomainPayment.svelte index ac131ee..e04970d 100644 --- a/src/components/DomainPayment.svelte +++ b/src/components/DomainPayment.svelte @@ -102,7 +102,11 @@

{domainName}

- addYears(-1)} disabled={years === 1 || feesApproved} aria-label="remove-year"> + addYears(-1)} + disabled={years === 1 || feesApproved} + aria-label="remove-year" + > {years} {yearsLabel} @@ -111,7 +115,7 @@
-
+

Payment token

diff --git a/src/lib/sdk.ts b/src/lib/sdk.ts index 5480675..3690a64 100644 --- a/src/lib/sdk.ts +++ b/src/lib/sdk.ts @@ -22,4 +22,4 @@ export const profileRecords = [ RecordClassEnum.Price ].map((v) => RecordClassEnum[v]); -export const getValidator = (klass: string) => getRecordValidator(getRecordClassFrom(klass)) +export const getValidator = (klass: string) => getRecordValidator(getRecordClassFrom(klass)); diff --git a/src/lib/server/index.ts b/src/lib/server/index.ts index d776b94..d87bace 100644 --- a/src/lib/server/index.ts +++ b/src/lib/server/index.ts @@ -57,5 +57,4 @@ export const getStats = async (): Promise => { }; }; - export const apiError = (message: string, status = 400) => json({ error: message }, { status }); diff --git a/src/lib/types.ts b/src/lib/types.ts index 1d202e1..b57ab3e 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -42,8 +42,8 @@ export interface DomainPaymentParams { } export interface DomainFeesResponse { - feesLabel: number - fees: string - symbol: string - address: string + feesLabel: number; + fees: string; + symbol: string; + address: string; } diff --git a/src/lib/url.ts b/src/lib/url.ts index ede74eb..710d0a9 100644 --- a/src/lib/url.ts +++ b/src/lib/url.ts @@ -8,12 +8,11 @@ export const explorerAddressUrl = (address: string) => { if (address.startsWith('00')) // Account url += `/accounts/${address}/assets`; - else - // Contract - url += `/contracts/${address}`; + // Contract + else url += `/contracts/${address}`; - return url -} + return url; +}; export const bridgeUrl = `${config.browserUrl}/bridge`; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e491643..a5e8638 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -201,5 +201,4 @@ align-items: center; height: 100%; } - diff --git a/src/routes/api/register/[name]/fees/[coin]/+server.ts b/src/routes/api/register/[name]/fees/[coin]/+server.ts index 72763fd..af646a0 100644 --- a/src/routes/api/register/[name]/fees/[coin]/+server.ts +++ b/src/routes/api/register/[name]/fees/[coin]/+server.ts @@ -4,14 +4,17 @@ import { json } from '@sveltejs/kit'; import type { DomainFeesResponse } from 'src/lib/types'; export async function GET({ params: { name, coin } }) { - return handleError(async () => { - const validCoins = metaNamesSdk.config.byoc.map(byoc => byoc.symbol.toString()) - if (!(validCoins.includes(coin))) return apiError('Invalid coin'); + return handleError(async () => { + const validCoins = metaNamesSdk.config.byoc.map((byoc) => byoc.symbol.toString()); + if (!validCoins.includes(coin)) return apiError('Invalid coin'); - const normalizedDomain = metaNamesSdk.domainRepository.domainValidator.normalize(name) - const domainFees = await metaNamesSdk.domainRepository.calculateMintFees(normalizedDomain, coin as BYOCSymbol); - const fees = { ...domainFees, fees: domainFees.fees.toString() } + const normalizedDomain = metaNamesSdk.domainRepository.domainValidator.normalize(name); + const domainFees = await metaNamesSdk.domainRepository.calculateMintFees( + normalizedDomain, + coin as BYOCSymbol + ); + const fees = { ...domainFees, fees: domainFees.fees.toString() }; - return json(fees); - }); + return json(fees); + }); } diff --git a/src/routes/profile/+page.svelte b/src/routes/profile/+page.svelte index 8b9fd1d..7f29073 100644 --- a/src/routes/profile/+page.svelte +++ b/src/routes/profile/+page.svelte @@ -74,7 +74,6 @@