From b47a232fa409d9e1edd588e81277b39dd6309091 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 22 Mar 2024 10:27:11 -0400 Subject: [PATCH] unify blocks before we kill them --- .../src/internal/client/dom/blocks/await.js | 18 +---- .../src/internal/client/dom/blocks/if.js | 18 +---- .../src/internal/client/dom/blocks/key.js | 4 +- .../src/internal/client/dom/blocks/snippet.js | 13 +--- .../client/dom/blocks/svelte-component.js | 4 +- .../client/dom/blocks/svelte-element.js | 12 +-- .../internal/client/dom/blocks/svelte-head.js | 12 +-- .../src/internal/client/dom/blocks/utils.js | 13 ++++ packages/svelte/src/internal/client/render.js | 2 - .../svelte/src/internal/client/types.d.ts | 74 ++----------------- 10 files changed, 35 insertions(+), 135 deletions(-) create mode 100644 packages/svelte/src/internal/client/dom/blocks/utils.js diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index d6820c058f..5dcf52d914 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -2,7 +2,6 @@ import { is_promise } from '../../../common.js'; import { hydrate_block_anchor } from '../hydration.js'; import { remove } from '../reconciler.js'; import { - current_block, current_component_context, flushSync, set_current_component_context, @@ -11,20 +10,7 @@ import { } from '../../runtime.js'; import { destroy_effect, pause_effect, render_effect } from '../../reactivity/effects.js'; import { DESTROYED, INERT } from '../../constants.js'; - -/** @returns {import('../../types.js').AwaitBlock} */ -export function create_await_block() { - return { - // dom - d: null, - // effect - e: null, - // parent - p: /** @type {import('../../types.js').Block} */ (current_block), - // pending - n: true - }; -} +import { create_block } from './utils.js'; /** * @template V @@ -36,7 +22,7 @@ export function create_await_block() { * @returns {void} */ export function await_block(anchor, get_input, pending_fn, then_fn, catch_fn) { - const block = create_await_block(); + const block = create_block(); const component_context = current_component_context; diff --git a/packages/svelte/src/internal/client/dom/blocks/if.js b/packages/svelte/src/internal/client/dom/blocks/if.js index c6068e041f..0386b2396c 100644 --- a/packages/svelte/src/internal/client/dom/blocks/if.js +++ b/packages/svelte/src/internal/client/dom/blocks/if.js @@ -6,27 +6,13 @@ import { set_current_hydration_fragment } from '../hydration.js'; import { remove } from '../reconciler.js'; -import { current_block } from '../../runtime.js'; import { destroy_effect, pause_effect, render_effect, resume_effect } from '../../reactivity/effects.js'; - -/** @returns {import('#client').IfBlock} */ -function create_if_block() { - return { - // dom - d: null, - // effect - e: null, - // parent - p: /** @type {import('#client').Block} */ (current_block), - // value - v: false - }; -} +import { create_block } from './utils.js'; /** * @param {Comment} anchor @@ -37,7 +23,7 @@ function create_if_block() { * @returns {void} */ export function if_block(anchor, get_condition, consequent_fn, alternate_fn, elseif = false) { - const block = create_if_block(); + const block = create_block(); hydrate_block_anchor(anchor); diff --git a/packages/svelte/src/internal/client/dom/blocks/key.js b/packages/svelte/src/internal/client/dom/blocks/key.js index 7410c5b640..f7cb9c6dee 100644 --- a/packages/svelte/src/internal/client/dom/blocks/key.js +++ b/packages/svelte/src/internal/client/dom/blocks/key.js @@ -3,6 +3,7 @@ import { hydrate_block_anchor } from '../hydration.js'; import { remove } from '../reconciler.js'; import { pause_effect, render_effect } from '../../reactivity/effects.js'; import { safe_not_equal } from '../../reactivity/equality.js'; +import { create_block } from './utils.js'; /** * @template V @@ -12,7 +13,7 @@ import { safe_not_equal } from '../../reactivity/equality.js'; * @returns {void} */ export function key_block(anchor, get_key, render_fn) { - const block = {}; + const block = create_block(); hydrate_block_anchor(anchor); @@ -43,7 +44,6 @@ export function key_block(anchor, get_key, render_fn) { () => { render_fn(anchor); - // @ts-expect-error TODO this should be unnecessary const dom = block.d; return () => { diff --git a/packages/svelte/src/internal/client/dom/blocks/snippet.js b/packages/svelte/src/internal/client/dom/blocks/snippet.js index 27d3011668..ac45cb6981 100644 --- a/packages/svelte/src/internal/client/dom/blocks/snippet.js +++ b/packages/svelte/src/internal/client/dom/blocks/snippet.js @@ -1,6 +1,7 @@ import { render_effect } from '../../reactivity/effects.js'; import { remove } from '../reconciler.js'; -import { current_block, untrack } from '../../runtime.js'; +import { untrack } from '../../runtime.js'; +import { create_block } from './utils.js'; /** * @param {() => Function | null | undefined} get_snippet @@ -9,15 +10,7 @@ import { current_block, untrack } from '../../runtime.js'; * @returns {void} */ export function snippet(get_snippet, node, ...args) { - /** @type {import('#client').SnippetBlock} */ - const block = { - // dom - d: null, - // parent - p: /** @type {import('#client').Block} */ (current_block), - // effect - e: null - }; + const block = create_block(); render_effect(() => { // Only rerender when the snippet function itself changes, diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js index a99eb4ce43..86fc548f04 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-component.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-component.js @@ -1,6 +1,7 @@ import { hydrate_block_anchor } from '../hydration.js'; import { pause_effect, render_effect } from '../../reactivity/effects.js'; import { remove } from '../reconciler.js'; +import { create_block } from './utils.js'; // TODO this is very similar to `key`, can we deduplicate? @@ -13,7 +14,7 @@ import { remove } from '../reconciler.js'; * @returns {void} */ export function component(anchor, get_component, render_fn) { - const block = {}; + const block = create_block(); hydrate_block_anchor(anchor); @@ -46,7 +47,6 @@ export function component(anchor, get_component, render_fn) { () => { render_fn(component); - // @ts-expect-error TODO this should be unnecessary const dom = block.d; return () => { diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js index 8e63fcc61b..5d753ad18f 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-element.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-element.js @@ -8,10 +8,10 @@ import { resume_effect } from '../../reactivity/effects.js'; import { remove } from '../reconciler.js'; -import { current_block } from '../../runtime.js'; import { is_array } from '../../utils.js'; import { set_should_intro } from '../../render.js'; import { current_each_item_block, set_current_each_item_block } from './each.js'; +import { create_block } from './utils.js'; /** * @param {import('#client').Block} block @@ -41,15 +41,7 @@ function swap_block_dom(block, from, to) { * @returns {void} */ export function element(anchor, get_tag, is_svg, render_fn) { - /** @type {import('#client').DynamicElementBlock} */ - const block = { - // dom - d: null, - // effect - e: null, - // parent - p: /** @type {import('#client').Block} */ (current_block) - }; + const block = create_block(); hydrate_block_anchor(anchor); diff --git a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js index c0916e7a29..9c22f382d8 100644 --- a/packages/svelte/src/internal/client/dom/blocks/svelte-head.js +++ b/packages/svelte/src/internal/client/dom/blocks/svelte-head.js @@ -7,22 +7,14 @@ import { import { empty } from '../operations.js'; import { render_effect } from '../../reactivity/effects.js'; import { remove } from '../reconciler.js'; -import { current_block } from '../../runtime.js'; +import { create_block } from './utils.js'; /** * @param {(anchor: Node | null) => void} render_fn * @returns {void} */ export function head(render_fn) { - /** @type {import('#client').HeadBlock} */ - const block = { - // dom - d: null, - // effect - e: null, - // parent - p: /** @type {import('#client').Block} */ (current_block) - }; + const block = create_block(); // The head function may be called after the first hydration pass and ssr comment nodes may still be present, // therefore we need to skip that when we detect that we're not in hydration mode. diff --git a/packages/svelte/src/internal/client/dom/blocks/utils.js b/packages/svelte/src/internal/client/dom/blocks/utils.js new file mode 100644 index 0000000000..627d4d8273 --- /dev/null +++ b/packages/svelte/src/internal/client/dom/blocks/utils.js @@ -0,0 +1,13 @@ +import { current_block } from '../../runtime.js'; + +/** @returns {import('#client').NormalBlock} */ +export function create_block() { + return { + // dom + d: null, + // effect + e: null, + // parent + p: /** @type {import('#client').Block} */ (current_block) + }; +} diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index c6d20d4be7..0a1b4f86e1 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -217,8 +217,6 @@ function _mount(Component, options) { d: null, // effect e: null, - // intro - i: options.intro || false, // parent p: null }; diff --git a/packages/svelte/src/internal/client/types.d.ts b/packages/svelte/src/internal/client/types.d.ts index 489f786b23..214aa54929 100644 --- a/packages/svelte/src/internal/client/types.d.ts +++ b/packages/svelte/src/internal/client/types.d.ts @@ -49,65 +49,23 @@ export type Equals = (this: Value, value: unknown) => boolean; export type TemplateNode = Text | Element | Comment; -export type RootBlock = { - /** dom */ - d: null | TemplateNode | Array; - /** effect */ - e: null | Effect; - /** intro */ - i: boolean; - /** parent */ - p: null; -}; - -export type IfBlock = { - /** value */ - v: boolean; - /** dom */ - d: null | TemplateNode | Array; - /** effect */ - e: null | Effect; - /** parent */ - p: Block; -}; - -export type HeadBlock = { - /** dom */ - d: null | TemplateNode | Array; - /** effect */ - e: null | Effect; - /** parent */ - p: Block; -}; - -export type DynamicElementBlock = { - /** dom */ - d: null | TemplateNode | Array; - /** effect */ - e: null | Effect; - /** parent */ - p: Block; -}; - -export type DynamicComponentBlock = { +export interface NormalBlock { /** dom */ d: null | TemplateNode | Array; /** effect */ e: null | Effect; /** parent */ p: Block; -}; +} -export type AwaitBlock = { +export interface RootBlock { /** dom */ d: null | TemplateNode | Array; /** effect */ e: null | Effect; /** parent */ - p: Block; - /** pending */ - n: boolean; -}; + p: null; +} export type EachBlock = { /** flags */ @@ -116,7 +74,7 @@ export type EachBlock = { d: null | TemplateNode | Array; /** items */ v: EachItemBlock[]; - /** effewct */ + /** effect */ e: null | Effect; /** parent */ p: Block; @@ -137,25 +95,7 @@ export type EachItemBlock = { k: unknown; }; -export type SnippetBlock = { - /** dom */ - d: null | TemplateNode | Array; - /** parent */ - p: Block; - /** effect */ - e: null | Effect; -}; - -export type Block = - | RootBlock - | IfBlock - | AwaitBlock - | DynamicElementBlock - | DynamicComponentBlock - | HeadBlock - | EachBlock - | EachItemBlock - | SnippetBlock; +export type Block = RootBlock | NormalBlock | EachBlock | EachItemBlock; export interface TransitionManager { /** Whether the `global` modifier was used (i.e. `transition:fade|global`) */