-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat: add hydrate method, make hydration treeshakeable #10497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f43e076
c97fc30
1fcf65e
35ff241
a71f2ff
367fa6b
73b99c8
c2dfc0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"svelte": patch | ||
--- | ||
|
||
feat: add hydrate method, make hydration treeshakeable |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,25 +3,37 @@ | |
import { empty } from './operations.js'; | ||
import { schedule_task } from './runtime.js'; | ||
|
||
/** @type {null | Array<import('./types.js').TemplateNode>} */ | ||
export let current_hydration_fragment = null; | ||
/** | ||
* Use this variable to guard everything related to hydration code so it can be treeshaken out | ||
* if the user doesn't use the `hydrate` method and these code paths are therefore not needed. | ||
*/ | ||
export let hydrating = false; | ||
|
||
/** | ||
* Array of nodes to traverse for hydration. This will be null if we're not hydrating, but for | ||
* the sake of simplicity we're not going to use `null` checks everywhere and instead rely on | ||
* the `hydrating` flag to tell whether or not we're in hydration mode at which point this is set. | ||
* @type {import('./types.js').TemplateNode[]} | ||
*/ | ||
export let current_hydration_fragment = /** @type {any} */ (null); | ||
|
||
/** | ||
* @param {null | Array<import('./types.js').TemplateNode>} fragment | ||
* @param {null | import('./types.js').TemplateNode[]} fragment | ||
* @returns {void} | ||
*/ | ||
export function set_current_hydration_fragment(fragment) { | ||
current_hydration_fragment = fragment; | ||
hydrating = fragment !== null; | ||
current_hydration_fragment = /** @type {import('./types.js').TemplateNode[]} */ (fragment); | ||
} | ||
|
||
/** | ||
* Returns all nodes between the first `<!--ssr:...-->` comment tag pair encountered. | ||
* @param {Node | null} node | ||
* @param {boolean} [insert_text] Whether to insert an empty text node if the fragment is empty | ||
* @returns {Array<import('./types.js').TemplateNode> | null} | ||
* @returns {import('./types.js').TemplateNode[] | null} | ||
*/ | ||
export function get_hydration_fragment(node, insert_text = false) { | ||
/** @type {Array<import('./types.js').TemplateNode>} */ | ||
/** @type {import('./types.js').TemplateNode[]} */ | ||
const fragment = []; | ||
|
||
/** @type {null | Node} */ | ||
|
@@ -66,9 +78,10 @@ export function get_hydration_fragment(node, insert_text = false) { | |
* @returns {void} | ||
*/ | ||
export function hydrate_block_anchor(anchor_node, is_controlled) { | ||
/** @type {Node} */ | ||
let target_node = anchor_node; | ||
if (current_hydration_fragment !== null) { | ||
if (hydrating) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need this (and similar) guards? surely we're already only calling functions like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depends on the method, in this case there's no if block at the call site because it would result in more if block code overall. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what I was talking about last week in our call. I wasn't seeing the tree shaking working as expected by Rollup. However, if you put into this boolean guard then it works great – something I didn't do. |
||
/** @type {Node} */ | ||
let target_node = anchor_node; | ||
|
||
if (is_controlled) { | ||
target_node = /** @type {Node} */ (target_node.firstChild); | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.