pull/12335/head
Rich Harris 2 years ago
parent a7b658a6d1
commit cbeb564a8b

@ -36,7 +36,8 @@ import {
BLOCK_ANCHOR,
BLOCK_CLOSE,
BLOCK_CLOSE_ELSE,
BLOCK_OPEN
BLOCK_OPEN,
BLOCK_OPEN_ELSE
} from '../../../../internal/server/hydration.js';
import { filename, locator } from '../../../state.js';
@ -1006,7 +1007,8 @@ function serialize_inline_component(node, expression, context) {
} else if (context.state.skip_hydration_boundaries) {
context.state.template.push(statement);
} else {
context.state.template.push(block_open, statement, block_close);
context.state.template.push(statement);
// context.state.template.push(block_open, statement, block_close);
}
}
@ -1411,12 +1413,15 @@ const template_visitors = {
? /** @type {import('estree').BlockStatement} */ (context.visit(node.alternate))
: b.block([]);
consequent.body.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE))));
alternate.body.push(
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE_ELSE)))
consequent.body.unshift(
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN)))
);
alternate.body.unshift(
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
);
context.state.template.push(block_open, b.if(test, consequent, alternate));
context.state.template.push(b.if(test, consequent, alternate), block_close);
},
AwaitBlock(node, context) {
context.state.template.push(

@ -20,6 +20,7 @@ export const TEMPLATE_FRAGMENT = 1;
export const TEMPLATE_USE_IMPORT_NODE = 1 << 1;
export const HYDRATION_START = '[';
export const HYDRATION_START_ELSE = '[!';
export const HYDRATION_END = ']';
export const HYDRATION_ANCHOR = '';
export const HYDRATION_END_ELSE = `${HYDRATION_END}!`; // used to indicate that an `{:else}...` block was rendered

@ -11,7 +11,7 @@ import {
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
import { DEV } from 'esm-env';
import { queue_micro_task } from '../task.js';
import { hydrate_node, hydrating } from '../hydration.js';
import { hydrate_node, hydrating, set_hydrate_node } from '../hydration.js';
import { mutable_source, set, source } from '../../reactivity/sources.js';
const PENDING = 0;
@ -149,5 +149,6 @@ export function await_block(anchor, get_input, pending_fn, then_fn, catch_fn) {
if (hydrating) {
anchor = hydrate_node.nextSibling;
set_hydrate_node(anchor);
}
}

@ -8,7 +8,15 @@ import {
HYDRATION_END_ELSE,
HYDRATION_START
} from '../../../../constants.js';
import { hydrate_nodes, hydrate_start, hydrating, set_hydrating } from '../hydration.js';
import {
hydrate_node,
hydrate_nodes,
hydrate_start,
hydrating,
set_hydrate_node,
set_hydrate_open,
set_hydrating
} from '../hydration.js';
import { clear_text_content, empty } from '../operations.js';
import { remove } from '../reconciler.js';
import {
@ -144,7 +152,7 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
if (hydrating) {
var is_else = /** @type {Comment} */ (anchor).data === HYDRATION_END_ELSE;
if (is_else !== (length === 0) || hydrate_start === undefined) {
if (is_else !== (length === 0) || hydrate_node === undefined) {
// hydration mismatch — remove the server-rendered DOM and start over
remove(hydrate_nodes);
set_hydrating(false);
@ -155,7 +163,7 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
// this is separate to the previous block because `hydrating` might change
if (hydrating) {
/** @type {Node} */
var child_anchor = hydrate_start;
var child_anchor = hydrate_node;
/** @type {import('#client').EachItem | null} */
var prev = null;
@ -175,22 +183,27 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
break;
}
set_hydrate_open(child_anchor);
var value = array[i];
var key = get_key(value, i);
item = create_item(child_anchor, state, prev, null, value, key, i, render_fn, flags);
state.items.set(key, item);
child_anchor = /** @type {Comment} */ (child_anchor.nextSibling);
var close = hydrate_node.nextSibling; // TODO validate. or replace `<!--]--><!--[-->` with `<!---->`
set_hydrate_node(close);
child_anchor = /** @type {Comment} */ (close.nextSibling);
prev = item;
}
// remove excess nodes
if (length > 0) {
while (child_anchor !== anchor) {
var next = /** @type {import('#client').TemplateNode} */ (child_anchor.nextSibling);
/** @type {import('#client').TemplateNode} */ (child_anchor).remove();
child_anchor = next;
}
// TODO reinstate
// while (child_anchor !== anchor) {
// var next = /** @type {import('#client').TemplateNode} */ (child_anchor.nextSibling);
// /** @type {import('#client').TemplateNode} */ (child_anchor).remove();
// child_anchor = next;
// }
}
}
@ -217,6 +230,11 @@ export function each(anchor, flags, get_collection, get_key, render_fn, fallback
set_hydrating(true);
}
});
if (hydrating) {
anchor = hydrate_node.nextSibling;
set_hydrate_node(anchor);
}
}
/**

@ -1,9 +1,14 @@
import { EFFECT_TRANSPARENT } from '../../constants.js';
import { hydrate_node, hydrate_nodes, hydrating, set_hydrating } from '../hydration.js';
import {
hydrate_node,
hydrate_nodes,
hydrating,
set_hydrate_node,
set_hydrating
} from '../hydration.js';
import { remove } from '../reconciler.js';
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
import { HYDRATION_END_ELSE } from '../../../../constants.js';
import { current_effect } from '../../runtime.js';
import { HYDRATION_START_ELSE } from '../../../../constants.js';
/**
* @param {Comment} anchor
@ -38,7 +43,7 @@ export function if_block(
let mismatch = false;
if (hydrating) {
const is_else = anchor.data === HYDRATION_END_ELSE;
const is_else = anchor.data === HYDRATION_START_ELSE;
if (condition === is_else) {
// Hydration mismatch: remove everything inside the anchor and start fresh.
@ -83,5 +88,6 @@ export function if_block(
if (hydrating) {
anchor = hydrate_node.nextSibling;
set_hydrate_node(anchor);
}
}

@ -59,12 +59,15 @@ export function empty() {
*/
/*#__NO_SIDE_EFFECTS__*/
export function child(node) {
const child = node.firstChild;
if (!hydrating) return child;
if (!hydrating) {
return node.firstChild;
}
var child = hydrate_node.firstChild;
// Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty
if (child === null) {
return node.appendChild(empty());
return hydrate_node.appendChild(empty());
}
return child;

@ -267,15 +267,15 @@ export function append(anchor, dom) {
if (hydrating) {
/** @type {Effect & { nodes: EffectNodes }} */ (current_effect).nodes.end = hydrate_node;
// console.log('append', hydrate_node);
// console.log('effect.nodes.end', hydrate_node);
// next node should be a <!--]-->
var next = hydrate_node.nextSibling;
if (next === null || next.nodeType !== 8) {
throw new Error('TODO');
}
// // next node should be a <!--]-->
// var next = hydrate_node.nextSibling;
// if (next === null || next.nodeType !== 8) {
// throw new Error('TODO');
// }
set_hydrate_node(/** @type {Comment} */ (next));
// set_hydrate_node(/** @type {Comment} */ (next));
return;
}

@ -2,10 +2,12 @@ import {
HYDRATION_ANCHOR,
HYDRATION_END,
HYDRATION_END_ELSE,
HYDRATION_START
HYDRATION_START,
HYDRATION_START_ELSE
} from '../../constants.js';
export const BLOCK_OPEN = `<!--${HYDRATION_START}-->`;
export const BLOCK_OPEN_ELSE = `<!--${HYDRATION_START_ELSE}-->`;
export const BLOCK_CLOSE = `<!--${HYDRATION_END}-->`;
export const BLOCK_ANCHOR = `<!--${HYDRATION_ANCHOR}-->`;
export const BLOCK_CLOSE_ELSE = `<!--${HYDRATION_END_ELSE}-->`;

@ -23,10 +23,16 @@ async function createServer() {
app.use('*', async (req, res) => {
if (req.originalUrl !== '/') {
res.writeHead(200, {
'Content-Type': 'application/javascript'
});
res.end(fs.createReadStream(path.resolve('./dist' + req.originalUrl)));
const file = path.resolve('./dist' + req.originalUrl);
if (fs.existsSync(file)) {
res.writeHead(200, {
'Content-Type': 'application/javascript'
});
res.end(fs.createReadStream(file));
} else {
res.writeHead(404);
res.end('not found');
}
return;
}

Loading…
Cancel
Save