From cb4f82f811630c0ade5c5498306de5d1647b8b83 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 24 Aug 2024 17:37:42 -0400 Subject: [PATCH] fix: handle deletions of state proxy properties (#13008) --- .changeset/beige-lamps-ring.md | 5 +++++ .changeset/green-windows-tap.md | 5 +++++ packages/svelte/src/internal/client/proxy.js | 14 +++++++------- packages/svelte/src/internal/client/proxy.test.ts | 11 +++++++++++ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 .changeset/beige-lamps-ring.md create mode 100644 .changeset/green-windows-tap.md diff --git a/.changeset/beige-lamps-ring.md b/.changeset/beige-lamps-ring.md new file mode 100644 index 0000000000..f647921060 --- /dev/null +++ b/.changeset/beige-lamps-ring.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: always return true from `deleteProperty` trap diff --git a/.changeset/green-windows-tap.md b/.changeset/green-windows-tap.md new file mode 100644 index 0000000000..964d6373bc --- /dev/null +++ b/.changeset/green-windows-tap.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: handle deletions of previously-unread state proxy properties diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js index 333cd20b58..2a81a3cd53 100644 --- a/packages/svelte/src/internal/client/proxy.js +++ b/packages/svelte/src/internal/client/proxy.js @@ -19,7 +19,7 @@ import * as e from './errors.js'; * @param {T} value * @param {ProxyMetadata | null} [parent] * @param {Source} [prev] dev mode only - * @returns {ProxyStateObject | T} + * @returns {T} */ export function proxy(value, parent = null, prev) { // if non-proxyable, or is already a proxy, return `value` @@ -91,17 +91,17 @@ export function proxy(value, parent = null, prev) { deleteProperty(target, prop) { var s = sources.get(prop); - var exists = s !== undefined ? s.v !== UNINITIALIZED : prop in target; - if (s !== undefined) { + if (s === undefined) { + if (prop in target) { + sources.set(prop, source(UNINITIALIZED)); + } + } else { set(s, UNINITIALIZED); - } - - if (exists) { update_version(version); } - return exists; + return true; }, get(target, prop, receiver) { diff --git a/packages/svelte/src/internal/client/proxy.test.ts b/packages/svelte/src/internal/client/proxy.test.ts index d73e6bef72..d15e656d83 100644 --- a/packages/svelte/src/internal/client/proxy.test.ts +++ b/packages/svelte/src/internal/client/proxy.test.ts @@ -85,3 +85,14 @@ test('does not re-proxy proxies', () => { assert.equal(inner.count, 1); assert.equal(outer.inner.count, 1); }); + +test('deletes a property', () => { + const state = proxy({ a: 1, b: 2 } as { a?: number; b?: number; c?: number }); + + delete state.a; + assert.equal(JSON.stringify(state), '{"b":2}'); + delete state.a; + + // deleting a non-existent property should succeed + delete state.c; +});