From d8212f4befb57734e0d326495dcca0ae160332d0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 28 Jul 2024 11:53:55 -0400 Subject: [PATCH 1/3] remove $.unwrap from key functions --- .../phases/3-transform/client/utils.js | 10 +++--- .../3-transform/client/visitors/template.js | 33 ++++++++++++------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/utils.js b/packages/svelte/src/compiler/phases/3-transform/client/utils.js index b9456f8653b7..529318d4fc4d 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/utils.js @@ -79,6 +79,11 @@ export function serialize_get_binding(node, state) { return node; } + if (Object.hasOwn(state.getters, node.name)) { + const getter = state.getters[node.name]; + return typeof getter === 'function' ? getter(node) : getter; + } + if (binding.node.name === '$$props') { // Special case for $$props which only exists in the old world return b.id('$$sanitized_props'); @@ -88,11 +93,6 @@ export function serialize_get_binding(node, state) { return b.call(node); } - if (Object.hasOwn(state.getters, node.name)) { - const getter = state.getters[node.name]; - return typeof getter === 'function' ? getter(node) : getter; - } - if (binding.kind === 'prop' || binding.kind === 'bindable_prop') { if (is_prop_source(binding, state)) { return b.call(node); diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 0548d7a1432c..0b6414484650 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -2493,6 +2493,12 @@ export const template_visitors = { getters: { ...context.state.getters } }; + /** The state used when generating the key function, if necessary */ + const key_state = { + ...context.state, + getters: { ...context.state.getters } + }; + /** * @param {Pattern} expression_for_id * @returns {Binding['mutation']} @@ -2552,6 +2558,8 @@ export const template_visitors = { const index_with_loc = with_loc(index, id); return b.call('$.unwrap', index_with_loc); }; + + key_state.getters[node.index] = b.id(node.index); } /** @type {Statement[]} */ @@ -2565,6 +2573,8 @@ export const template_visitors = { true ) ); + + key_state.getters[node.context.name] = node.context; } else { const unwrapped = getter(binding.node); const paths = extract_paths(node.context); @@ -2592,23 +2602,22 @@ export const template_visitors = { if (context.state.options.dev) { declarations.push(b.stmt(getter)); } + + key_state.getters[name] = path.node; } } const block = /** @type {BlockStatement} */ (context.visit(node.body, child_state)); - const key_function = node.key - ? b.arrow( - [node.context.type === 'Identifier' ? node.context : b.id('$$item'), index], - declarations.length > 0 - ? b.block( - declarations.concat( - b.return(/** @type {Expression} */ (context.visit(node.key, child_state))) - ) - ) - : /** @type {Expression} */ (context.visit(node.key, child_state)) - ) - : b.id('$.index'); + /** @type {Expression} */ + let key_function = b.id('$.index'); + + if (node.key) { + key_function = b.arrow( + [node.context, index], + /** @type {Expression} */ (context.visit(node.key, key_state)) + ); + } if (node.index && each_node_meta.contains_group_binding) { // We needed to create a unique identifier for the index above, but we want to use the From 29e64243a42054c63cd209444223d965fbd2a8fc Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 28 Jul 2024 11:58:23 -0400 Subject: [PATCH 2/3] feat: remove `$.unwrap` calls from each block indexes --- .changeset/dry-hotels-matter.md | 5 +++++ .../compiler/phases/3-transform/client/visitors/template.js | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 .changeset/dry-hotels-matter.md diff --git a/.changeset/dry-hotels-matter.md b/.changeset/dry-hotels-matter.md new file mode 100644 index 000000000000..927f84908d5e --- /dev/null +++ b/.changeset/dry-hotels-matter.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: remove $.unwrap calls from each block indexes diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 0b6414484650..4ae93f64f8db 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -2556,7 +2556,9 @@ export const template_visitors = { if (node.index) { child_state.getters[node.index] = (id) => { const index_with_loc = with_loc(index, id); - return b.call('$.unwrap', index_with_loc); + return (flags & EACH_INDEX_REACTIVE) === 0 + ? index_with_loc + : b.call('$.get', index_with_loc); }; key_state.getters[node.index] = b.id(node.index); From abc87f4d5dfe59812ccdf48f0122d76dcef300a6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 28 Jul 2024 12:29:55 -0400 Subject: [PATCH 3/3] tweak --- .../compiler/phases/3-transform/client/visitors/template.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js index 4ae93f64f8db..cf0fd231e5fb 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js @@ -2615,10 +2615,8 @@ export const template_visitors = { let key_function = b.id('$.index'); if (node.key) { - key_function = b.arrow( - [node.context, index], - /** @type {Expression} */ (context.visit(node.key, key_state)) - ); + const expression = /** @type {Expression} */ (context.visit(node.key, key_state)); + key_function = b.arrow([node.context, index], expression); } if (node.index && each_node_meta.contains_group_binding) {