diff --git a/package-lock.json b/package-lock.json index 5af1c1c7a..ef952ada3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,8 +65,8 @@ "playwright": "1.60.0", "prettier": "^3.8.3", "prettier-plugin-svelte": "^3.5.2", - "svelte": "^5.28.2", - "svelte-check": "^4.1.7", + "svelte": "^5.55.5", + "svelte-check": "^4.4.8", "svelte-eslint-parser": "^1.6.1", "tslib": "^2.8.1", "twemoji": "^14.0.2", @@ -81,18 +81,6 @@ "node": ">=24" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.4", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", @@ -790,16 +778,23 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -810,14 +805,6 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1576,9 +1563,7 @@ "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, - "optional": true + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, "node_modules/@types/unist": { "version": "3.0.3", @@ -1744,7 +1729,7 @@ "version": "8.59.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2074,9 +2059,10 @@ "dev": true }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "license": "Apache-2.0", "engines": { "node": ">= 0.4" } @@ -2492,6 +2478,12 @@ "node": ">=6" } }, + "node_modules/devalue": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.0.tgz", + "integrity": "sha512-2zA9pFEsnp7vWBZbXF5JAgAq0fsUIt/1XPbRiAmRV3lp/2C3upzH+sADiyy66aFCihoLEsrQHxNM5w1gIDfsBg==", + "license": "MIT" + }, "node_modules/devlop": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", @@ -2840,11 +2832,20 @@ } }, "node_modules/esrap": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.6.tgz", - "integrity": "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.8.tgz", + "integrity": "sha512-MPweq2EvEGj8jwOI7Hgycw/QIHzqA1EbAM8lG7p+FBfZbZq/hQ6h3AMsqnu/djzisH1KVWNzbb7LSgIVtMlPSg==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } } }, "node_modules/esrecurse": { @@ -4690,20 +4691,23 @@ } }, "node_modules/svelte": { - "version": "5.28.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.28.2.tgz", - "integrity": "sha512-FbWBxgWOpQfhKvoGJv/TFwzqb4EhJbwCD17dB0tEpQiw1XyUEKZJtgm4nA4xq3LLsMo7hu5UY/BOFmroAxKTMg==", + "version": "5.55.5", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.5.tgz", + "integrity": "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw==", + "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", + "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", - "aria-query": "^5.3.1", + "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", + "devalue": "^5.6.4", "esm-env": "^1.2.1", - "esrap": "^1.4.6", + "esrap": "^2.2.4", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -4714,10 +4718,11 @@ } }, "node_modules/svelte-check": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.1.7.tgz", - "integrity": "sha512-1jX4BzXrQJhC/Jt3SqYf6Ntu//vmfc6VWp07JkRfK2nn+22yIblspVUo96gzMkg0Zov8lQicxhxsMzOctwcMQQ==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.8.tgz", + "integrity": "sha512-67adfgBox5eNSNIvIIwgFizKGdcRrGpiMoNO2obHcYuLz7iTa8Xgm/NGU3ntMFnNm8K1grFOIG6HhMLX/vcN8w==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", diff --git a/package.json b/package.json index b8bed9ef4..2b95f9c0a 100644 --- a/package.json +++ b/package.json @@ -81,8 +81,8 @@ "playwright": "1.60.0", "prettier": "^3.8.3", "prettier-plugin-svelte": "^3.5.2", - "svelte": "^5.28.2", - "svelte-check": "^4.1.7", + "svelte": "^5.55.5", + "svelte-check": "^4.4.8", "svelte-eslint-parser": "^1.6.1", "tslib": "^2.8.1", "twemoji": "^14.0.2", diff --git a/src/components/Changes.svelte b/src/components/Changes.svelte index 1555530db..63963a042 100644 --- a/src/components/Changes.svelte +++ b/src/components/Changes.svelte @@ -25,7 +25,11 @@ let hideChanges = $state(false); let filesExpanded = $state(true); let selectedCommit = $state(); + // Parent reuses this component across patch revisions; a sibling $effect + // resets base and head when patchId changes. + // svelte-ignore state_referenced_locally let base = $state(revision.base); + // svelte-ignore state_referenced_locally let head = $state(revision.head); $effect(() => { diff --git a/src/components/Diff.svelte b/src/components/Diff.svelte index ee2b2737f..923a96d75 100644 --- a/src/components/Diff.svelte +++ b/src/components/Diff.svelte @@ -328,6 +328,7 @@ class:context={line.type === "context"} class:selected={!thread && isSelected(filePath(file, "left"), hunkIdx, lineIdx)}> +
+
{ diff --git a/src/components/Discussion.svelte b/src/components/Discussion.svelte index fded7e3c8..1bb2a5c66 100644 --- a/src/components/Discussion.svelte +++ b/src/components/Discussion.svelte @@ -50,22 +50,19 @@ }: Props = $props(); /* eslint-enable prefer-const */ - let previousCobId = cobId; + let previousCobId: string | undefined; let focusReply: boolean = $state(false); let commentFormKey = $state(0); let hideDiscussion = $state(false); $effect(() => { - // eslint-disable-next-line @typescript-eslint/no-unused-expressions - cobId; - - if (cobId !== previousCobId) { - previousCobId = cobId; + if (previousCobId !== undefined && cobId !== previousCobId) { hideDiscussion = false; focusReply = false; commentFormKey += 1; } + previousCobId = cobId; }); diff --git a/src/components/Review.svelte b/src/components/Review.svelte index 370789b71..aa9422ac0 100644 --- a/src/components/Review.svelte +++ b/src/components/Review.svelte @@ -96,6 +96,9 @@ }, [])) as Thread[]) || [], ); + // The verdict prop seeds a local working copy that the form mutates until + // submit; later prop updates intentionally do not overwrite it. + // svelte-ignore state_referenced_locally let verdict: Review["verdict"] = $state(review.verdict); async function editReview( diff --git a/src/components/ScrollArea.svelte b/src/components/ScrollArea.svelte index 93b65a8f3..4ecef967f 100644 --- a/src/components/ScrollArea.svelte +++ b/src/components/ScrollArea.svelte @@ -41,13 +41,15 @@ return el.scrollTop + el.clientHeight >= el.scrollHeight - threshold; } - const scrollHalfHandler = onScrollHalf - ? (instance: Parameters[0]) => { - if (shouldLoadMore(instance)) { - onScrollHalf(); + const scrollHalfHandler = $derived( + onScrollHalf + ? (instance: Parameters[0]) => { + if (shouldLoadMore(instance)) { + onScrollHalf(); + } } - } - : undefined; + : undefined, + ); { + notificationCount.value = sidebarData.notificationCount; + }); async function updateCount() { const count = await invoke("notification_count"); diff --git a/src/views/repo/Issue.svelte b/src/views/repo/Issue.svelte index 89014a106..02cc2dc88 100644 --- a/src/views/repo/Issue.svelte +++ b/src/views/repo/Issue.svelte @@ -64,7 +64,13 @@ }: Props = $props(); /* eslint-enable prefer-const */ + // Parent reuses this component across issue navigations; a sibling $effect + // resets local state when issue.id changes. + // svelte-ignore state_referenced_locally let issues = $state(initialIssues); + // The initial status filter is captured at mount so it stays fixed while + // navigating between sibling issues. + // svelte-ignore state_referenced_locally const status = initialStatus; let labelSaveInProgress: boolean = $state(false); let assigneesSaveInProgress: boolean = $state(false); diff --git a/src/views/repo/Patch.svelte b/src/views/repo/Patch.svelte index 63451b646..8b1e66400 100644 --- a/src/views/repo/Patch.svelte +++ b/src/views/repo/Patch.svelte @@ -63,10 +63,17 @@ /* eslint-enable prefer-const */ let hideTimeline = $state(true); + // The initial status filter is captured at mount so it stays fixed while + // navigating between sibling patches. + // svelte-ignore state_referenced_locally const status = initialStatus; + // Parent reuses this component across patch navigations; a sibling $effect + // resets tab and selectedRevision when patch.id changes. + // svelte-ignore state_referenced_locally let tab: "patch" | "revisions" | "timeline" = $state( revisions.length > 1 ? "revisions" : "patch", ); + // svelte-ignore state_referenced_locally let selectedRevision: Revision = $state(revisions.slice(-1)[0]); $effect(() => { diff --git a/src/views/repo/Patches.svelte b/src/views/repo/Patches.svelte index 4d7a0b658..dceb5cc9d 100644 --- a/src/views/repo/Patches.svelte +++ b/src/views/repo/Patches.svelte @@ -37,8 +37,13 @@ const { repo, patches, status }: Props = $props(); + // Parent reuses this component across status filter changes; a sibling + // $effect resets pagination state when the patches prop changes. + // svelte-ignore state_referenced_locally let items = $state(patches.content); + // svelte-ignore state_referenced_locally let cursor = patches.cursor; + // svelte-ignore state_referenced_locally let more = patches.more; const project = $derived(repo.payloads["xyz.radicle.project"]!); diff --git a/src/views/repo/RepoCommits.svelte b/src/views/repo/RepoCommits.svelte index 6f08b115a..5646a983b 100644 --- a/src/views/repo/RepoCommits.svelte +++ b/src/views/repo/RepoCommits.svelte @@ -50,7 +50,11 @@ commits: Commit[]; }; + // Parent reuses this component across navigations; a sibling $effect resets + // pagination state when the commits prop changes. + // svelte-ignore state_referenced_locally let items = $state(commits.content); + // svelte-ignore state_referenced_locally let more = $state(commits.more); let loadingMore = $state(false); let loading = $state(false); diff --git a/src/views/repo/RepoHome.svelte b/src/views/repo/RepoHome.svelte index 5ad7a236d..28516a2aa 100644 --- a/src/views/repo/RepoHome.svelte +++ b/src/views/repo/RepoHome.svelte @@ -78,6 +78,9 @@ let preview = $derived(isMarkdownPath(currentPath)); + // Parent reuses this component across routes; a sibling $effect resets blob + // when the readme prop changes, and fetchBlob mutates it during navigation. + // svelte-ignore state_referenced_locally let blob: Blob | Readme | null = $state(readme); const showLineNumbers = $derived( blob && !blob.binary && blob.content.trim() !== "" && !preview && !error,