From 2ac038c05ae85c7d693fe674b36eb4ac6f0b8a65 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 10 Dec 2024 17:15:10 +0000 Subject: [PATCH 1/4] fix: ensure $state.snapshot clones holey arrays correctly --- .changeset/clean-bobcats-fail.md | 5 +++++ packages/svelte/src/internal/shared/clone.js | 6 ++++-- .../samples/state-snapshot-array-holes/_config.js | 5 +++++ .../samples/state-snapshot-array-holes/main.svelte | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 .changeset/clean-bobcats-fail.md create mode 100644 packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/main.svelte diff --git a/.changeset/clean-bobcats-fail.md b/.changeset/clean-bobcats-fail.md new file mode 100644 index 000000000000..00d8286bcb28 --- /dev/null +++ b/.changeset/clean-bobcats-fail.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure $state.snapshot clones holey arrays correctly diff --git a/packages/svelte/src/internal/shared/clone.js b/packages/svelte/src/internal/shared/clone.js index cef14bc14f9e..a388ea10fa77 100644 --- a/packages/svelte/src/internal/shared/clone.js +++ b/packages/svelte/src/internal/shared/clone.js @@ -61,7 +61,7 @@ function clone(value, cloned, path, paths, original = null) { if (value instanceof Set) return /** @type {Snapshot} */ (new Set(value)); if (is_array(value)) { - const copy = /** @type {Snapshot} */ ([]); + const copy = /** @type {Snapshot} */ (Array(value.length)); cloned.set(value, copy); if (original !== null) { @@ -69,7 +69,9 @@ function clone(value, cloned, path, paths, original = null) { } for (let i = 0; i < value.length; i += 1) { - copy.push(clone(value[i], cloned, DEV ? `${path}[${i}]` : path, paths)); + if (value[i] !== undefined) { + copy[i] = clone(value[i], cloned, DEV ? `${path}[${i}]` : path, paths); + } } return copy; diff --git a/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/_config.js b/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/_config.js new file mode 100644 index 000000000000..707c92118bf3 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + html: `
false
true
` +}); diff --git a/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/main.svelte b/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/main.svelte new file mode 100644 index 000000000000..cb5c116f37f1 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/state-snapshot-array-holes/main.svelte @@ -0,0 +1,10 @@ + + +
{2 in $state.snapshot(state)}
+
{5 in $state.snapshot(state)}
From edf468a912bd3aa0f15d19a36134b0259839f34a Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 10 Dec 2024 17:16:43 +0000 Subject: [PATCH 2/4] fix: ensure $state.snapshot clones holey arrays correctly --- packages/svelte/src/internal/shared/clone.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/svelte/src/internal/shared/clone.js b/packages/svelte/src/internal/shared/clone.js index a388ea10fa77..030a95e4b132 100644 --- a/packages/svelte/src/internal/shared/clone.js +++ b/packages/svelte/src/internal/shared/clone.js @@ -54,23 +54,24 @@ export function snapshot(value, skip_warning = false) { */ function clone(value, cloned, path, paths, original = null) { if (typeof value === 'object' && value !== null) { - const unwrapped = cloned.get(value); + var unwrapped = cloned.get(value); if (unwrapped !== undefined) return unwrapped; if (value instanceof Map) return /** @type {Snapshot} */ (new Map(value)); if (value instanceof Set) return /** @type {Snapshot} */ (new Set(value)); if (is_array(value)) { - const copy = /** @type {Snapshot} */ (Array(value.length)); + var copy = /** @type {Snapshot} */ (Array(value.length)); cloned.set(value, copy); if (original !== null) { cloned.set(original, copy); } - for (let i = 0; i < value.length; i += 1) { - if (value[i] !== undefined) { - copy[i] = clone(value[i], cloned, DEV ? `${path}[${i}]` : path, paths); + for (var i = 0; i < value.length; i += 1) { + var element = value[i]; + if (element !== undefined) { + copy[i] = clone(element, cloned, DEV ? `${path}[${i}]` : path, paths); } } @@ -79,7 +80,7 @@ function clone(value, cloned, path, paths, original = null) { if (get_prototype_of(value) === object_prototype) { /** @type {Snapshot} */ - const copy = {}; + copy = {}; cloned.set(value, copy); if (original !== null) { From 0eb8aae72397d26b111bf7ada8f13318a61bc649 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 10 Dec 2024 17:24:12 +0000 Subject: [PATCH 3/4] fix: ensure $state.snapshot clones holey arrays correctly --- packages/svelte/src/internal/shared/clone.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/shared/clone.js b/packages/svelte/src/internal/shared/clone.js index 030a95e4b132..281e5395c75c 100644 --- a/packages/svelte/src/internal/shared/clone.js +++ b/packages/svelte/src/internal/shared/clone.js @@ -70,7 +70,7 @@ function clone(value, cloned, path, paths, original = null) { for (var i = 0; i < value.length; i += 1) { var element = value[i]; - if (element !== undefined) { + if (i in element) { copy[i] = clone(element, cloned, DEV ? `${path}[${i}]` : path, paths); } } From b5148d345b4fdf367609722d4c5768dea463c79c Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 10 Dec 2024 17:24:30 +0000 Subject: [PATCH 4/4] fix: ensure $state.snapshot clones holey arrays correctly --- packages/svelte/src/internal/shared/clone.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/shared/clone.js b/packages/svelte/src/internal/shared/clone.js index 281e5395c75c..4632fc3d68ed 100644 --- a/packages/svelte/src/internal/shared/clone.js +++ b/packages/svelte/src/internal/shared/clone.js @@ -70,7 +70,7 @@ function clone(value, cloned, path, paths, original = null) { for (var i = 0; i < value.length; i += 1) { var element = value[i]; - if (i in element) { + if (i in value) { copy[i] = clone(element, cloned, DEV ? `${path}[${i}]` : path, paths); } }