chore: Rename Payload to Renderer (#16786)

pull/16785/head
Elliott Johnson 23 hours ago committed by GitHub
parent fc35d9fab8
commit 6798efacb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -40,7 +40,7 @@ import { TitleElement } from './visitors/TitleElement.js';
import { UpdateExpression } from './visitors/UpdateExpression.js';
import { VariableDeclaration } from './visitors/VariableDeclaration.js';
import { SvelteBoundary } from './visitors/SvelteBoundary.js';
import { call_child_payload, call_component_payload } from './visitors/shared/utils.js';
import { call_child_renderer, call_component_renderer } from './visitors/shared/utils.js';
/** @type {Visitors} */
const global_visitors = {
@ -188,21 +188,21 @@ export function server_component(analysis, options) {
template.body = [
...snippets,
b.let('$$settled', b.true),
b.let('$$inner_payload'),
b.let('$$inner_renderer'),
b.function_declaration(
b.id('$$render_inner'),
[b.id('$$payload')],
[b.id(' $$renderer')],
b.block(/** @type {Statement[]} */ (rest))
),
b.do_while(
b.unary('!', b.id('$$settled')),
b.block([
b.stmt(b.assignment('=', b.id('$$settled'), b.true)),
b.stmt(b.assignment('=', b.id('$$inner_payload'), b.call('$$payload.copy'))),
b.stmt(b.call('$$render_inner', b.id('$$inner_payload')))
b.stmt(b.assignment('=', b.id('$$inner_renderer'), b.call(' $$renderer.copy'))),
b.stmt(b.call('$$render_inner', b.id('$$inner_renderer')))
])
),
b.stmt(b.call('$$payload.subsume', b.id('$$inner_payload')))
b.stmt(b.call(' $$renderer.subsume', b.id('$$inner_renderer')))
];
}
@ -244,7 +244,7 @@ export function server_component(analysis, options) {
]);
if (analysis.instance.has_await) {
component_block = b.block([call_child_payload(component_block, true)]);
component_block = b.block([call_child_renderer(component_block, true)]);
}
// trick esrap into including comments
@ -253,7 +253,7 @@ export function server_component(analysis, options) {
if (analysis.props_id) {
// need to be placed on first line of the component for hydration
component_block.body.unshift(
b.const(analysis.props_id, b.call('$.props_id', b.id('$$payload')))
b.const(analysis.props_id, b.call('$.props_id', b.id(' $$renderer')))
);
}
@ -261,7 +261,7 @@ export function server_component(analysis, options) {
if (should_inject_context) {
component_block = b.block([
call_component_payload(component_block, dev && b.id(component_name))
call_component_renderer(component_block, dev && b.id(component_name))
]);
}
@ -301,7 +301,7 @@ export function server_component(analysis, options) {
const code = b.literal(render_stylesheet(analysis.source, analysis, options).code);
body.push(b.const('$$css', b.object([b.init('hash', hash), b.init('code', code)])));
component_block.body.unshift(b.stmt(b.call('$$payload.global.css.add', b.id('$$css'))));
component_block.body.unshift(b.stmt(b.call(' $$renderer.global.css.add', b.id('$$css'))));
}
let should_inject_props =
@ -315,7 +315,7 @@ export function server_component(analysis, options) {
const component_function = b.function_declaration(
b.id(analysis.name),
should_inject_props ? [b.id('$$payload'), b.id('$$props')] : [b.id('$$payload')],
should_inject_props ? [b.id(' $$renderer'), b.id('$$props')] : [b.id(' $$renderer')],
component_block
);

@ -2,7 +2,7 @@
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '#compiler/builders';
import { block_close, call_child_payload } from './shared/utils.js';
import { block_close, call_child_renderer } from './shared/utils.js';
/**
* @param {AST.AwaitBlock} node
@ -13,7 +13,7 @@ export function AwaitBlock(node, context) {
let statement = b.stmt(
b.call(
'$.await',
b.id('$$payload'),
b.id(' $$renderer'),
/** @type {Expression} */ (context.visit(node.expression)),
b.thunk(
node.pending ? /** @type {BlockStatement} */ (context.visit(node.pending)) : b.block([])
@ -26,7 +26,7 @@ export function AwaitBlock(node, context) {
);
if (node.metadata.expression.has_await) {
statement = call_child_payload(b.block([statement]), true);
statement = call_child_renderer(b.block([statement]), true);
}
context.state.template.push(statement, block_close);

@ -2,7 +2,7 @@
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '#compiler/builders';
import { block_close, block_open, block_open_else, call_child_payload } from './shared/utils.js';
import { block_close, block_open, block_open_else, call_child_renderer } from './shared/utils.js';
/**
* @param {AST.EachBlock} node
@ -45,11 +45,11 @@ export function EachBlock(node, context) {
);
if (node.fallback) {
const open = b.stmt(b.call(b.id('$$payload.push'), block_open));
const open = b.stmt(b.call(b.id(' $$renderer.push'), block_open));
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
fallback.body.unshift(b.stmt(b.call(b.id('$$payload.push'), block_open_else)));
fallback.body.unshift(b.stmt(b.call(b.id(' $$renderer.push'), block_open_else)));
block.body.push(
b.if(
@ -64,7 +64,7 @@ export function EachBlock(node, context) {
}
if (node.metadata.expression.has_await) {
state.template.push(call_child_payload(block, true), block_close);
state.template.push(call_child_renderer(block, true), block_close);
} else {
state.template.push(...block.body, block_close);
}

@ -2,7 +2,7 @@
/** @import { AST } from '#compiler' */
/** @import { ComponentContext } from '../types.js' */
import * as b from '#compiler/builders';
import { block_close, block_open, block_open_else, call_child_payload } from './shared/utils.js';
import { block_close, block_open, block_open_else, call_child_renderer } from './shared/utils.js';
/**
* @param {AST.IfBlock} node
@ -16,15 +16,15 @@ export function IfBlock(node, context) {
? /** @type {BlockStatement} */ (context.visit(node.alternate))
: b.block([]);
consequent.body.unshift(b.stmt(b.call(b.id('$$payload.push'), block_open)));
consequent.body.unshift(b.stmt(b.call(b.id(' $$renderer.push'), block_open)));
alternate.body.unshift(b.stmt(b.call(b.id('$$payload.push'), block_open_else)));
alternate.body.unshift(b.stmt(b.call(b.id(' $$renderer.push'), block_open_else)));
/** @type {Statement} */
let statement = b.if(test, consequent, alternate);
if (node.metadata.expression.has_await) {
statement = call_child_payload(b.block([statement]), true);
statement = call_child_renderer(b.block([statement]), true);
}
context.state.template.push(statement, block_close);

@ -12,7 +12,7 @@ import {
process_children,
build_template,
build_attribute_value,
call_child_payload
call_child_renderer
} from './shared/utils.js';
/**
@ -68,7 +68,7 @@ export function RegularElement(node, context) {
b.stmt(
b.call(
'$.push_element',
b.id('$$payload'),
b.id(' $$renderer'),
b.literal(node.name),
b.literal(location.line),
b.literal(location.column)
@ -97,7 +97,7 @@ export function RegularElement(node, context) {
b.stmt(
b.assignment(
'=',
b.id('$$payload.local.select_value'),
b.id(' $$renderer.local.select_value'),
b.member(
build_spread_object(
node,
@ -125,7 +125,7 @@ export function RegularElement(node, context) {
);
}
const left = b.id('$$payload.local.select_value');
const left = b.id(' $$renderer.local.select_value');
if (value.type === 'Attribute') {
state.template.push(
b.stmt(b.assignment('=', left, build_attribute_value(value.value, context)))
@ -160,7 +160,7 @@ export function RegularElement(node, context) {
b.stmt(
b.call(
'$.simple_valueless_option',
b.id('$$payload'),
b.id(' $$renderer'),
b.thunk(
node.metadata.synthetic_value_node.expression,
node.metadata.synthetic_value_node.metadata.expression.has_await
@ -175,9 +175,9 @@ export function RegularElement(node, context) {
b.stmt(
b.call(
'$.valueless_option',
b.id('$$payload'),
b.id(' $$renderer'),
b.arrow(
[b.id('$$payload')],
[b.id(' $$renderer')],
b.block([...inner_state.init, ...build_template(inner_state.template)])
)
)
@ -216,7 +216,7 @@ export function RegularElement(node, context) {
// element hadn't resolved prior to hitting the second element.
const elements = state.template.splice(template_start, Infinity);
state.template.push(
call_child_payload(b.block(build_template(elements)), select_with_value_async)
call_child_renderer(b.block(build_template(elements)), select_with_value_async)
);
}

@ -23,7 +23,7 @@ export function RenderTag(node, context) {
b.stmt(
(node.expression.type === 'CallExpression' ? b.call : b.maybe_call)(
snippet_function,
b.id('$$payload'),
b.id(' $$renderer'),
...snippet_args
)
)

@ -6,7 +6,7 @@ import {
empty_comment,
build_attribute_value,
PromiseOptimiser,
call_child_payload
call_child_renderer
} from './shared/utils.js';
/**
@ -57,7 +57,7 @@ export function SlotElement(node, context) {
const slot = b.call(
'$.slot',
b.id('$$payload'),
b.id(' $$renderer'),
b.id('$$props'),
name,
props_expression,
@ -66,7 +66,7 @@ export function SlotElement(node, context) {
const statement =
optimiser.expressions.length > 0
? call_child_payload(b.block([optimiser.apply(), b.stmt(slot)]), true)
? call_child_renderer(b.block([optimiser.apply(), b.stmt(slot)]), true)
: b.stmt(slot);
context.state.template.push(empty_comment, statement, empty_comment);

@ -11,7 +11,7 @@ import * as b from '#compiler/builders';
export function SnippetBlock(node, context) {
let fn = b.function_declaration(
node.expression,
[b.id('$$payload'), ...node.parameters],
[b.id(' $$renderer'), ...node.parameters],
/** @type {BlockStatement} */ (context.visit(node.body))
);
@ -21,7 +21,7 @@ export function SnippetBlock(node, context) {
const statements = node.metadata.can_hoist ? context.state.hoisted : context.state.init;
if (dev) {
fn.body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id('$$payload'))));
fn.body.body.unshift(b.stmt(b.call('$.validate_snippet_args', b.id(' $$renderer'))));
statements.push(b.stmt(b.call('$.prevent_snippet_stringification', fn.id)));
}

@ -24,7 +24,7 @@ export function SvelteBoundary(node, context) {
const pending = pending_attribute
? b.call(
build_attribute_value(pending_attribute.value, context, false, true),
b.id('$$payload')
b.id(' $$renderer')
)
: /** @type {BlockStatement} */ (context.visit(pending_snippet.body));

@ -45,7 +45,7 @@ export function SvelteElement(node, context) {
b.stmt(
b.call(
'$.push_element',
b.id('$$payload'),
b.id(' $$renderer'),
tag,
b.literal(location.line),
b.literal(location.column)
@ -61,7 +61,7 @@ export function SvelteElement(node, context) {
b.stmt(
b.call(
'$.element',
b.id('$$payload'),
b.id(' $$renderer'),
tag,
attributes.body.length > 0 && b.thunk(attributes),
children.body.length > 0 && b.thunk(children)

@ -11,6 +11,6 @@ export function SvelteHead(node, context) {
const block = /** @type {BlockStatement} */ (context.visit(node.fragment));
context.state.template.push(
b.stmt(b.call('$.head', b.id('$$payload'), b.arrow([b.id('$$payload')], block)))
b.stmt(b.call('$.head', b.id(' $$renderer'), b.arrow([b.id(' $$renderer')], block)))
);
}

@ -14,6 +14,6 @@ export function TitleElement(node, context) {
template.push(b.literal('</title>'));
context.state.init.push(
b.stmt(b.call('$.build_title', b.id('$$payload'), b.thunk(b.block(build_template(template)))))
b.stmt(b.call('$.build_title', b.id(' $$renderer'), b.thunk(b.block(build_template(template)))))
);
}

@ -4,7 +4,7 @@
import {
empty_comment,
build_attribute_value,
call_child_payload,
call_child_renderer,
PromiseOptimiser
} from './utils.js';
import * as b from '#compiler/builders';
@ -215,7 +215,7 @@ export function build_inline_component(node, expression, context) {
if (block.body.length === 0) continue;
/** @type {Pattern[]} */
const params = [b.id('$$payload')];
const params = [b.id(' $$renderer')];
if (lets[slot_name].length > 0) {
const pattern = b.object_pattern(
@ -292,7 +292,7 @@ export function build_inline_component(node, expression, context) {
let statement = b.stmt(
(node.type === 'SvelteComponent' ? b.maybe_call : b.call)(
expression,
b.id('$$payload'),
b.id(' $$renderer'),
props_expression
)
);
@ -308,7 +308,7 @@ export function build_inline_component(node, expression, context) {
statement = b.stmt(
b.call(
'$.css_props',
b.id('$$payload'),
b.id(' $$renderer'),
b.literal(context.state.namespace === 'svg' ? false : true),
b.object(custom_css_props),
b.thunk(b.block([statement])),
@ -318,7 +318,7 @@ export function build_inline_component(node, expression, context) {
}
if (optimiser.expressions.length > 0) {
statement = call_child_payload(b.block([optimiser.apply(), statement]), true);
statement = call_child_renderer(b.block([optimiser.apply(), statement]), true);
}
if (dynamic && custom_css_props.length === 0) {

@ -207,7 +207,7 @@ export function build_element_attributes(node, context) {
context.state.template.push(
b.call(
'$.maybe_selected',
b.id('$$payload'),
b.id(' $$renderer'),
b.member(
build_spread_object(
node,
@ -264,7 +264,7 @@ export function build_element_attributes(node, context) {
context.state.template.push(
b.call(
'$.maybe_selected',
b.id('$$payload'),
b.id(' $$renderer'),
literal_value != null ? b.literal(/** @type {any} */ (literal_value)) : b.void0
)
);
@ -296,7 +296,7 @@ export function build_element_attributes(node, context) {
}
if (name === 'value' && node.name === 'option') {
context.state.template.push(b.call('$.maybe_selected', b.id('$$payload'), value));
context.state.template.push(b.call('$.maybe_selected', b.id(' $$renderer'), value));
}
}
}

@ -80,7 +80,7 @@ export function process_children(nodes, { visit, state }) {
flush();
const visited = /** @type {Expression} */ (visit(node.expression));
state.template.push(
b.stmt(b.call('$$payload.push', b.thunk(b.call('$.escape', visited), true)))
b.stmt(b.call(' $$renderer.push', b.thunk(b.call('$.escape', visited), true)))
);
} else if (node.type === 'Text' || node.type === 'Comment' || node.type === 'ExpressionTag') {
sequence.push(node);
@ -119,7 +119,7 @@ export function build_template(template) {
statements.push(
b.stmt(
b.call(
b.id('$$payload.push'),
b.id(' $$renderer.push'),
b.template(
strings.map((cooked, i) => b.quasi(cooked, i === strings.length - 1)),
expressions
@ -266,8 +266,8 @@ export function build_getter(node, state) {
* @param {boolean} async
* @returns {Statement}
*/
export function call_child_payload(body, async) {
return b.stmt(b.call('$$payload.child', b.arrow([b.id('$$payload')], body, async)));
export function call_child_renderer(body, async) {
return b.stmt(b.call(' $$renderer.child', b.arrow([b.id(' $$renderer')], body, async)));
}
/**
@ -275,9 +275,9 @@ export function call_child_payload(body, async) {
* @param {Identifier | false} component_fn_id
* @returns {Statement}
*/
export function call_component_payload(body, component_fn_id) {
export function call_component_renderer(body, component_fn_id) {
return b.stmt(
b.call('$$payload.component', b.arrow([b.id('$$payload')], body, false), component_fn_id)
b.call(' $$renderer.component', b.arrow([b.id(' $$renderer')], body, false), component_fn_id)
);
}

@ -1,12 +1,12 @@
/** @import { SSRContext } from '#server' */
/** @import { Payload } from './internal/server/payload.js' */
/** @import { Renderer } from './internal/server/renderer.js' */
import { ssr_context } from './internal/server/context.js';
import { noop } from './internal/shared/utils.js';
import * as e from './internal/server/errors.js';
/** @param {() => void} fn */
export function onDestroy(fn) {
/** @type {Payload} */ (/** @type {SSRContext} */ (ssr_context).r).on_destroy(fn);
/** @type {Renderer} */ (/** @type {SSRContext} */ (ssr_context).r).on_destroy(fn);
}
export {

@ -1,5 +1,5 @@
/** @import { Snippet } from 'svelte' */
/** @import { Payload } from '../payload' */
/** @import { Renderer } from '../renderer' */
/** @import { Getters } from '#shared' */
/**
@ -13,9 +13,9 @@
*/
export function createRawSnippet(fn) {
// @ts-expect-error the types are a lie
return (/** @type {Payload} */ payload, /** @type {Params} */ ...args) => {
return (/** @type {Renderer} */ renderer, /** @type {Params} */ ...args) => {
var getters = /** @type {Getters<Params>} */ (args.map((value) => () => value));
payload.push(
renderer.push(
fn(...getters)
.render()
.trim()

@ -6,7 +6,7 @@ import {
} from '../../html-tree-validation.js';
import { set_ssr_context, ssr_context } from './context.js';
import * as e from './errors.js';
import { Payload } from './payload.js';
import { Renderer } from './renderer.js';
// TODO move this
/**
@ -26,10 +26,10 @@ import { Payload } from './payload.js';
export let seen;
/**
* @param {Payload} payload
* @param {Renderer} renderer
* @param {string} message
*/
function print_error(payload, message) {
function print_error(renderer, message) {
message =
`node_invalid_placement_ssr: ${message}\n\n` +
'This can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.';
@ -39,19 +39,19 @@ function print_error(payload, message) {
// eslint-disable-next-line no-console
console.error(message);
payload.child(
(payload) => payload.push(`<script>console.error(${JSON.stringify(message)})</script>`),
renderer.child(
(renderer) => renderer.push(`<script>console.error(${JSON.stringify(message)})</script>`),
'head'
);
}
/**
* @param {Payload} payload
* @param {Renderer} renderer
* @param {string} tag
* @param {number} line
* @param {number} column
*/
export function push_element(payload, tag, line, column) {
export function push_element(renderer, tag, line, column) {
var context = /** @type {SSRContext} */ (ssr_context);
var filename = context.function[FILENAME];
var parent = context.element;
@ -67,7 +67,7 @@ export function push_element(payload, tag, line, column) {
: undefined;
const message = is_tag_valid_with_parent(tag, parent.tag, child_loc, parent_loc);
if (message) print_error(payload, message);
if (message) print_error(renderer, message);
while (ancestor != null) {
ancestors.push(ancestor.tag);
@ -76,7 +76,7 @@ export function push_element(payload, tag, line, column) {
: undefined;
const message = is_tag_valid_with_ancestor(tag, ancestors, child_loc, ancestor_loc);
if (message) print_error(payload, message);
if (message) print_error(renderer, message);
ancestor = ancestor.parent;
}
@ -90,13 +90,13 @@ export function pop_element() {
}
/**
* @param {Payload} payload
* @param {Renderer} renderer
*/
export function validate_snippet_args(payload) {
export function validate_snippet_args(renderer) {
if (
typeof payload !== 'object' ||
// for some reason typescript consider the type of payload as never after the first instanceof
!(payload instanceof Payload)
typeof renderer !== 'object' ||
// for some reason typescript consider the type of renderer as never after the first instanceof
!(renderer instanceof Renderer)
) {
e.invalid_snippet_arguments();
}

@ -1,7 +1,7 @@
/** @import { ComponentType, SvelteComponent, Component } from 'svelte' */
/** @import { RenderOutput } from '#server' */
/** @import { Store } from '#shared' */
/** @import { AccumulatedContent } from './payload.js' */
/** @import { AccumulatedContent } from './renderer.js' */
export { FILENAME, HMR } from '../../constants.js';
import { attr, clsx, to_class, to_style } from '../shared/attributes.js';
import { is_promise, noop } from '../shared/utils.js';
@ -17,7 +17,7 @@ import { DEV } from 'esm-env';
import { EMPTY_COMMENT, BLOCK_CLOSE, BLOCK_OPEN, BLOCK_OPEN_ELSE } from './hydration.js';
import { validate_store } from '../shared/validate.js';
import { is_boolean_attribute, is_raw_text_element, is_void } from '../../utils.js';
import { Payload } from './payload.js';
import { Renderer } from './renderer.js';
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
// https://infra.spec.whatwg.org/#noncharacter
@ -25,30 +25,30 @@ const INVALID_ATTR_NAME_CHAR_REGEX =
/[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
/**
* @param {Payload} payload
* @param {Renderer} renderer
* @param {string} tag
* @param {() => void} attributes_fn
* @param {() => void} children_fn
* @returns {void}
*/
export function element(payload, tag, attributes_fn = noop, children_fn = noop) {
payload.push('<!---->');
export function element(renderer, tag, attributes_fn = noop, children_fn = noop) {
renderer.push('<!---->');
if (tag) {
payload.push(`<${tag}`);
renderer.push(`<${tag}`);
attributes_fn();
payload.push(`>`);
renderer.push(`>`);
if (!is_void(tag)) {
children_fn();
if (!is_raw_text_element(tag)) {
payload.push(EMPTY_COMMENT);
renderer.push(EMPTY_COMMENT);
}
payload.push(`</${tag}>`);
renderer.push(`</${tag}>`);
}
}
payload.push('<!---->');
renderer.push('<!---->');
}
/**
@ -60,49 +60,49 @@ export function element(payload, tag, attributes_fn = noop, children_fn = noop)
* @returns {RenderOutput}
*/
export function render(component, options = {}) {
return Payload.render(/** @type {Component<Props>} */ (component), options);
return Renderer.render(/** @type {Component<Props>} */ (component), options);
}
/**
* @param {Payload} payload
* @param {(payload: Payload) => Promise<void> | void} fn
* @param {Renderer} renderer
* @param {(renderer: Renderer) => Promise<void> | void} fn
* @returns {void}
*/
export function head(payload, fn) {
payload.child((payload) => {
payload.push(BLOCK_OPEN);
payload.child(fn);
payload.push(BLOCK_CLOSE);
export function head(renderer, fn) {
renderer.child((renderer) => {
renderer.push(BLOCK_OPEN);
renderer.child(fn);
renderer.push(BLOCK_CLOSE);
}, 'head');
}
/**
* @param {Payload} payload
* @param {Renderer} renderer
* @param {boolean} is_html
* @param {Record<string, string>} props
* @param {() => void} component
* @param {boolean} dynamic
* @returns {void}
*/
export function css_props(payload, is_html, props, component, dynamic = false) {
export function css_props(renderer, is_html, props, component, dynamic = false) {
const styles = style_object_to_string(props);
if (is_html) {
payload.push(`<svelte-css-wrapper style="display: contents; ${styles}">`);
renderer.push(`<svelte-css-wrapper style="display: contents; ${styles}">`);
} else {
payload.push(`<g style="${styles}">`);
renderer.push(`<g style="${styles}">`);
}
if (dynamic) {
payload.push('<!---->');
renderer.push('<!---->');
}
component();
if (is_html) {
payload.push(`<!----></svelte-css-wrapper>`);
renderer.push(`<!----></svelte-css-wrapper>`);
} else {
payload.push(`<!----></g>`);
renderer.push(`<!----></g>`);
}
}
@ -304,14 +304,14 @@ export function unsubscribe_stores(store_values) {
}
/**
* @param {Payload} payload
* @param {Renderer} renderer
* @param {Record<string, any>} $$props
* @param {string} name
* @param {Record<string, unknown>} slot_props
* @param {null | (() => void)} fallback_fn
* @returns {void}
*/
export function slot(payload, $$props, name, slot_props, fallback_fn) {
export function slot(renderer, $$props, name, slot_props, fallback_fn) {
var slot_fn = $$props.$$slots?.[name];
// Interop: Can use snippets to fill slots
if (slot_fn === true) {
@ -319,7 +319,7 @@ export function slot(payload, $$props, name, slot_props, fallback_fn) {
}
if (slot_fn !== undefined) {
slot_fn(payload, slot_props);
slot_fn(renderer, slot_props);
} else {
fallback_fn?.();
}
@ -387,21 +387,21 @@ export function bind_props(props_parent, props_now) {
/**
* @template V
* @param {Payload} payload
* @param {Renderer} renderer
* @param {Promise<V>} promise
* @param {null | (() => void)} pending_fn
* @param {(value: V) => void} then_fn
* @returns {void}
*/
function await_block(payload, promise, pending_fn, then_fn) {
function await_block(renderer, promise, pending_fn, then_fn) {
if (is_promise(promise)) {
payload.push(BLOCK_OPEN);
renderer.push(BLOCK_OPEN);
promise.then(null, noop);
if (pending_fn !== null) {
pending_fn();
}
} else if (then_fn !== null) {
payload.push(BLOCK_OPEN_ELSE);
renderer.push(BLOCK_OPEN_ELSE);
then_fn(promise);
}
}
@ -443,12 +443,12 @@ export function once(get_value) {
/**
* Create an unique ID
* @param {Payload} payload
* @param {Renderer} renderer
* @returns {string}
*/
export function props_id(payload) {
const uid = payload.global.uid();
payload.push('<!--#' + uid + '-->');
export function props_id(renderer) {
const uid = renderer.global.uid();
renderer.push('<!--#' + uid + '-->');
return uid;
}
@ -496,11 +496,11 @@ export function derived(fn) {
/**
*
* @param {Payload} payload
* @param {Renderer} renderer
* @param {unknown} value
*/
export function maybe_selected(payload, value) {
return value === payload.local.select_value ? ' selected' : '';
export function maybe_selected(renderer, value) {
return value === renderer.local.select_value ? ' selected' : '';
}
/**
@ -508,25 +508,25 @@ export function maybe_selected(payload, value) {
* content as its `value` to determine whether we should apply the `selected` attribute.
* This has to be done at runtime, for hopefully obvious reasons. It is also complicated,
* for sad reasons.
* @param {Payload} payload
* @param {((payload: Payload) => void | Promise<void>)} children
* @param {Renderer} renderer
* @param {((renderer: Renderer) => void | Promise<void>)} children
* @returns {void}
*/
export function valueless_option(payload, children) {
const i = payload.length;
export function valueless_option(renderer, children) {
const i = renderer.length;
// prior to children, `payload` has some combination of string/unresolved payload that ends in `<option ...>`
payload.child(children);
// prior to children, `renderer` has some combination of string/unresolved renderer that ends in `<option ...>`
renderer.child(children);
// post-children, `payload` has child content, possibly also with some number of hydration comments.
// post-children, `renderer` has child content, possibly also with some number of hydration comments.
// we can compact this last chunk of content to see if it matches the select value...
payload.compact({
renderer.compact({
start: i,
fn: (content) => {
if (content.body.replace(/<!---->/g, '') === payload.local.select_value) {
// ...and if it does match the select value, we can compact the part of the payload representing the `<option ...>`
if (content.body.replace(/<!---->/g, '') === renderer.local.select_value) {
// ...and if it does match the select value, we can compact the part of the renderer representing the `<option ...>`
// to add the `selected` attribute to the end.
payload.compact({
renderer.compact({
start: i - 1,
end: i,
fn: (content) => {
@ -545,10 +545,10 @@ export function valueless_option(payload, children) {
* by running the children and passing the resulting value, which means
* we don't have to do all of the same parsing nonsense. It also means we can avoid
* coercing everything to a string.
* @param {Payload} payload
* @param {Renderer} renderer
* @param {(() => unknown)} child
*/
export function simple_valueless_option(payload, child) {
export function simple_valueless_option(renderer, child) {
const result = child();
/**
@ -557,14 +557,14 @@ export function simple_valueless_option(payload, child) {
* @returns {AccumulatedContent}
*/
const mark_selected = (content, child_value) => {
if (child_value === payload.local.select_value) {
if (child_value === renderer.local.select_value) {
return { body: content.body.slice(0, -1) + ' selected>', head: content.head };
}
return content;
};
payload.compact({
start: payload.length - 1,
renderer.compact({
start: renderer.length - 1,
fn: (content) => {
if (result instanceof Promise) {
return result.then((child_value) => mark_selected(content, child_value));
@ -573,13 +573,13 @@ export function simple_valueless_option(payload, child) {
}
});
payload.child((child_payload) => {
renderer.child((child_renderer) => {
if (result instanceof Promise) {
return result.then((child_value) => {
child_payload.push(escape_html(child_value));
child_renderer.push(escape_html(child_value));
});
}
child_payload.push(escape_html(result));
child_renderer.push(escape_html(result));
});
}
@ -588,23 +588,23 @@ export function simple_valueless_option(payload, child) {
* which one "wins". To do this, we perform a depth-first comparison of where the title was encountered --
* later ones "win" over earlier ones, regardless of what order the promises resolve in. To accomodate this, we:
* - Figure out where we are in the content tree (`get_path`)
* - Render the title in its own child so that it has a defined "slot" in the payload
* - Render the title in its own child so that it has a defined "slot" in the renderer
* - Compact that spot so that we get the entire rendered contents of the title
* - Attempt to set the global title (this is where the "wins" logic based on the path happens)
*
* TODO we could optimize this by not even rendering the title if the path wouldn't be accepted
*
* @param {Payload} payload
* @param {((payload: Payload) => void | Promise<void>)} children
* @param {Renderer} renderer
* @param {((renderer: Renderer) => void | Promise<void>)} children
*/
export function build_title(payload, children) {
const path = payload.get_path();
const i = payload.length;
payload.child(children);
payload.compact({
export function build_title(renderer, children) {
const path = renderer.get_path();
const i = renderer.length;
renderer.child(children);
renderer.compact({
start: i,
fn: ({ head }) => {
payload.global.set_title(head, path);
renderer.global.set_title(head, path);
// since we can only ever render the title in this chunk, and title rendering is handled specially,
// we can just ditch the results after we've saved them globally
return { head: '', body: '' };

@ -7,57 +7,57 @@ import * as e from './errors.js';
import * as w from './warnings.js';
import { BLOCK_CLOSE, BLOCK_OPEN } from './hydration.js';
/** @typedef {'head' | 'body'} PayloadType */
/** @typedef {{ [key in PayloadType]: string }} AccumulatedContent */
/** @typedef {'head' | 'body'} RendererType */
/** @typedef {{ [key in RendererType]: string }} AccumulatedContent */
/**
* @template T
* @typedef {T | Promise<T>} MaybePromise<T>
*/
/**
* @typedef {string | Payload} PayloadItem
* @typedef {string | Renderer} RendererItem
*/
/**
* Payloads are basically a tree of `string | Payload`s, where each `Payload` in the tree represents
* work that may or may not have completed. A payload can be {@link collect}ed to aggregate the
* Renderers are basically a tree of `string | Renderer`s, where each `Renderer` in the tree represents
* work that may or may not have completed. A renderer can be {@link collect}ed to aggregate the
* content from itself and all of its children, but this will throw if any of the children are
* performing asynchronous work. To asynchronously collect a payload, just `await` it.
* performing asynchronous work. To asynchronously collect a renderer, just `await` it.
*
* The `string` values within a payload are always associated with the {@link type} of that payload. To switch types,
* The `string` values within a renderer are always associated with the {@link type} of that renderer. To switch types,
* call {@link child} with a different `type` argument.
*/
export class Payload {
export class Renderer {
/**
* The contents of the payload.
* @type {PayloadItem[]}
* The contents of the renderer.
* @type {RendererItem[]}
*/
#out = [];
/**
* Any `onDestroy` callbacks registered during execution of this payload.
* Any `onDestroy` callbacks registered during execution of this renderer.
* @type {(() => void)[] | undefined}
*/
#on_destroy = undefined;
/**
* Whether this payload is a component body.
* Whether this renderer is a component body.
* @type {boolean}
*/
#is_component_body = false;
/**
* The type of string content that this payload is accumulating.
* @type {PayloadType}
* The type of string content that this renderer is accumulating.
* @type {RendererType}
*/
type;
/** @type {Payload | undefined} */
/** @type {Renderer | undefined} */
#parent;
/**
* Asynchronous work associated with this payload. `initial` is the promise from the function
* this payload was passed to (if that function was async), and `followup` is any any additional
* work from `compact` calls that needs to complete prior to collecting this payload's content.
* Asynchronous work associated with this renderer. `initial` is the promise from the function
* this renderer was passed to (if that function was async), and `followup` is any any additional
* work from `compact` calls that needs to complete prior to collecting this renderer's content.
* @type {{ initial: Promise<void> | undefined, followup: Promise<void>[] }}
*/
promises = { initial: undefined, followup: [] };
@ -80,8 +80,8 @@ export class Payload {
/**
* @param {SSRState} global
* @param {Payload | undefined} [parent]
* @param {PayloadType} [type]
* @param {Renderer | undefined} [parent]
* @param {RendererType} [type]
*/
constructor(global, parent, type) {
this.global = global;
@ -91,13 +91,13 @@ export class Payload {
}
/**
* Create a child payload. The child payload inherits the state from the parent,
* Create a child renderer. The child renderer inherits the state from the parent,
* but has its own content.
* @param {(payload: Payload) => MaybePromise<void>} fn
* @param {PayloadType} [type]
* @param {(renderer: Renderer) => MaybePromise<void>} fn
* @param {RendererType} [type]
*/
child(fn, type) {
const child = new Payload(this.global, this, type);
const child = new Renderer(this.global, this, type);
this.#out.push(child);
const parent = ssr_context;
@ -126,9 +126,9 @@ export class Payload {
}
/**
* Create a component payload. The component payload inherits the state from the parent,
* Create a component renderer. The component renderer inherits the state from the parent,
* but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
* @param {(payload: Payload) => MaybePromise<void>} fn
* @param {(renderer: Renderer) => MaybePromise<void>} fn
* @param {Function} [component_fn]
* @returns {void}
*/
@ -144,25 +144,25 @@ export class Payload {
*/
push(content) {
if (typeof content === 'function') {
this.child(async (payload) => payload.push(await content()));
this.child(async (renderer) => renderer.push(await content()));
} else {
this.#out.push(content);
}
}
/**
* Compact everything between `start` and `end` into a single payload, then call `fn` with the result of that payload.
* The compacted payload will be sync if all of the children are sync and {@link fn} is sync, otherwise it will be async.
* Compact everything between `start` and `end` into a single renderer, then call `fn` with the result of that renderer.
* The compacted renderer will be sync if all of the children are sync and {@link fn} is sync, otherwise it will be async.
* @param {{ start: number, end?: number, fn: (content: AccumulatedContent) => AccumulatedContent | Promise<AccumulatedContent> }} args
*/
compact({ start, end = this.#out.length, fn }) {
const child = new Payload(this.global, this);
const child = new Renderer(this.global, this);
const to_compact = this.#out.splice(start, end - start, child);
if (this.global.mode === 'sync') {
Payload.#compact(fn, child, to_compact, this.type);
Renderer.#compact(fn, child, to_compact, this.type);
} else {
this.promises.followup.push(Payload.#compact_async(fn, child, to_compact, this.type));
this.promises.followup.push(Renderer.#compact_async(fn, child, to_compact, this.type));
}
}
@ -184,26 +184,26 @@ export class Payload {
* @deprecated this is needed for legacy component bindings
*/
copy() {
const copy = new Payload(this.global, this.#parent, this.type);
copy.#out = this.#out.map((item) => (item instanceof Payload ? item.copy() : item));
const copy = new Renderer(this.global, this.#parent, this.type);
copy.#out = this.#out.map((item) => (item instanceof Renderer ? item.copy() : item));
copy.promises = this.promises;
return copy;
}
/**
* @param {Payload} other
* @param {Renderer} other
* @deprecated this is needed for legacy component bindings
*/
subsume(other) {
if (this.global.mode !== other.global.mode) {
throw new Error(
"invariant: A payload cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
"invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
);
}
this.local = other.local;
this.#out = other.#out.map((item) => {
if (item instanceof Payload) {
if (item instanceof Renderer) {
item.subsume(item);
}
return item;
@ -236,17 +236,17 @@ export class Payload {
Object.defineProperties(result, {
html: {
get: () => {
return (sync ??= Payload.#render(component, options)).body;
return (sync ??= Renderer.#render(component, options)).body;
}
},
head: {
get: () => {
return (sync ??= Payload.#render(component, options)).head;
return (sync ??= Renderer.#render(component, options)).head;
}
},
body: {
get: () => {
return (sync ??= Payload.#render(component, options)).body;
return (sync ??= Renderer.#render(component, options)).body;
}
},
then: {
@ -262,7 +262,7 @@ export class Payload {
(onfulfilled, onrejected) => {
if (!async_mode_flag) {
w.experimental_async_ssr();
const result = (sync ??= Payload.#render(component, options));
const result = (sync ??= Renderer.#render(component, options));
const user_result = onfulfilled({
head: result.head,
body: result.body,
@ -270,7 +270,7 @@ export class Payload {
});
return Promise.resolve(user_result);
}
async ??= Payload.#render_async(component, options);
async ??= Renderer.#render_async(component, options);
return async.then((result) => {
Object.defineProperty(result, 'html', {
// eslint-disable-next-line getter-return
@ -291,8 +291,8 @@ export class Payload {
* Collect all of the `onDestroy` callbacks regsitered during rendering. In an async context, this is only safe to call
* after awaiting `collect_async`.
*
* Child payloads are "porous" and don't affect execution order, but component body payloads
* create ordering boundaries. Within a payload, callbacks run in order until hitting a component boundary.
* Child renderers are "porous" and don't affect execution order, but component body renderers
* create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
* @returns {Iterable<() => void>}
*/
*#collect_on_destroy() {
@ -302,8 +302,8 @@ export class Payload {
}
/**
* Performs a depth-first search of payloads, yielding the deepest components first, then additional components as we backtrack up the tree.
* @returns {Iterable<Payload>}
* Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
* @returns {Iterable<Renderer>}
*/
*#traverse_components() {
for (const child of this.#out) {
@ -326,7 +326,7 @@ export class Payload {
}
}
for (const child of this.#out) {
if (child instanceof Payload && !child.#is_component_body) {
if (child instanceof Renderer && !child.#is_component_body) {
yield* child.#collect_ondestroy();
}
}
@ -343,10 +343,10 @@ export class Payload {
static #render(component, options) {
var previous_context = ssr_context;
try {
const payload = Payload.#open_render('sync', component, options);
const renderer = Renderer.#open_render('sync', component, options);
const content = Payload.#collect_content([payload], payload.type);
return Payload.#close_render(content, payload);
const content = Renderer.#collect_content([renderer], renderer.type);
return Renderer.#close_render(content, renderer);
} finally {
abort();
set_ssr_context(previous_context);
@ -364,10 +364,10 @@ export class Payload {
static async #render_async(component, options) {
var previous_context = ssr_context;
try {
const payload = Payload.#open_render('async', component, options);
const renderer = Renderer.#open_render('async', component, options);
const content = await Payload.#collect_content_async([payload], payload.type);
return Payload.#close_render(content, payload);
const content = await Renderer.#collect_content_async([renderer], renderer.type);
return Renderer.#close_render(content, renderer);
} finally {
abort();
set_ssr_context(previous_context);
@ -376,38 +376,38 @@ export class Payload {
/**
* @param {(content: AccumulatedContent) => AccumulatedContent | Promise<AccumulatedContent>} fn
* @param {Payload} child
* @param {PayloadItem[]} to_compact
* @param {PayloadType} type
* @param {Renderer} child
* @param {RendererItem[]} to_compact
* @param {RendererType} type
*/
static #compact(fn, child, to_compact, type) {
const content = Payload.#collect_content(to_compact, type);
const content = Renderer.#collect_content(to_compact, type);
const transformed_content = fn(content);
if (transformed_content instanceof Promise) {
throw new Error(
"invariant: Somehow you've encountered asynchronous work while rendering synchronously. If you're seeing this, there's a compiler bug. File an issue!"
);
} else {
Payload.#push_accumulated_content(child, transformed_content);
Renderer.#push_accumulated_content(child, transformed_content);
}
}
/**
* @param {(content: AccumulatedContent) => AccumulatedContent | Promise<AccumulatedContent>} fn
* @param {Payload} child
* @param {PayloadItem[]} to_compact
* @param {PayloadType} type
* @param {Renderer} child
* @param {RendererItem[]} to_compact
* @param {RendererType} type
*/
static async #compact_async(fn, child, to_compact, type) {
const content = await Payload.#collect_content_async(to_compact, type);
const content = await Renderer.#collect_content_async(to_compact, type);
const transformed_content = await fn(content);
Payload.#push_accumulated_content(child, transformed_content);
Renderer.#push_accumulated_content(child, transformed_content);
}
/**
* Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
* @param {PayloadItem[]} items
* @param {PayloadType} current_type
* @param {RendererItem[]} items
* @param {RendererType} current_type
* @param {AccumulatedContent} content
* @returns {AccumulatedContent}
*/
@ -415,8 +415,8 @@ export class Payload {
for (const item of items) {
if (typeof item === 'string') {
content[current_type] += item;
} else if (item instanceof Payload) {
Payload.#collect_content(item.#out, item.type, content);
} else if (item instanceof Renderer) {
Renderer.#collect_content(item.#out, item.type, content);
}
}
return content;
@ -424,8 +424,8 @@ export class Payload {
/**
* Collect all of the code from the `out` array and return it as a string.
* @param {PayloadItem[]} items
* @param {PayloadType} current_type
* @param {RendererItem[]} items
* @param {RendererType} current_type
* @param {AccumulatedContent} content
* @returns {Promise<AccumulatedContent>}
*/
@ -436,7 +436,7 @@ export class Payload {
content[current_type] += item;
} else {
if (item.promises.initial) {
// this represents the async function that's modifying this payload.
// this represents the async function that's modifying this renderer.
// we can't do anything until it's done and we know our `out` array is complete.
await item.promises.initial;
}
@ -444,20 +444,20 @@ export class Payload {
// this is sequential because `compact` could synchronously queue up additional followup work
await followup;
}
await Payload.#collect_content_async(item.#out, item.type, content);
await Renderer.#collect_content_async(item.#out, item.type, content);
}
}
return content;
}
/**
* @param {Payload} tree
* @param {Renderer} tree
* @param {AccumulatedContent} accumulated_content
*/
static #push_accumulated_content(tree, accumulated_content) {
for (const [type, content] of Object.entries(accumulated_content)) {
if (!content) continue;
const child = new Payload(tree.global, tree, /** @type {PayloadType} */ (type));
const child = new Renderer(tree.global, tree, /** @type {RendererType} */ (type));
child.push(content);
tree.#out.push(child);
}
@ -468,45 +468,47 @@ export class Payload {
* @param {'sync' | 'async'} mode
* @param {import('svelte').Component<Props>} component
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
* @returns {Payload}
* @returns {Renderer}
*/
static #open_render(mode, component, options) {
const payload = new Payload(new SSRState(mode, options.idPrefix ? options.idPrefix + '-' : ''));
const renderer = new Renderer(
new SSRState(mode, options.idPrefix ? options.idPrefix + '-' : '')
);
payload.push(BLOCK_OPEN);
renderer.push(BLOCK_OPEN);
if (options.context) {
push();
/** @type {SSRContext} */ (ssr_context).c = options.context;
/** @type {SSRContext} */ (ssr_context).r = payload;
/** @type {SSRContext} */ (ssr_context).r = renderer;
}
// @ts-expect-error
component(payload, options.props ?? {});
component(renderer, options.props ?? {});
if (options.context) {
pop();
}
payload.push(BLOCK_CLOSE);
renderer.push(BLOCK_CLOSE);
return payload;
return renderer;
}
/**
* @param {AccumulatedContent} content
* @param {Payload} payload
* @param {Renderer} renderer
*/
static #close_render(content, payload) {
for (const cleanup of payload.#collect_on_destroy()) {
static #close_render(content, renderer) {
for (const cleanup of renderer.#collect_on_destroy()) {
cleanup();
}
let head = content.head + payload.global.get_title();
let head = content.head + renderer.global.get_title();
const body = BLOCK_OPEN + content.body + BLOCK_CLOSE; // this inserts a fake boundary so hydration matches
for (const { hash, code } of payload.global.css) {
for (const { hash, code } of renderer.global.css) {
head += `<style id="${hash}">${code}</style>`;
}

@ -1,68 +1,68 @@
import { afterAll, beforeAll, describe, expect, test } from 'vitest';
import { Payload, SSRState } from './payload.js';
import { Renderer, SSRState } from './renderer.js';
import type { Component } from 'svelte';
import { disable_async_mode_flag, enable_async_mode_flag } from '../flags/index.js';
test('collects synchronous body content by default', () => {
const component = (payload: Payload) => {
payload.push('a');
payload.child(($$payload) => {
$$payload.push('b');
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.child(($$renderer) => {
$$renderer.push('b');
});
payload.push('c');
renderer.push('c');
};
const { head, body } = Payload.render(component as unknown as Component);
const { head, body } = Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->abc<!--]--><!--]-->');
});
test('child type switches content area (head vs body)', () => {
const component = (payload: Payload) => {
payload.push('a');
payload.child(($$payload) => {
$$payload.push('<title>T</title>');
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.child(($$renderer) => {
$$renderer.push('<title>T</title>');
}, 'head');
payload.push('b');
renderer.push('b');
};
const { head, body } = Payload.render(component as unknown as Component);
const { head, body } = Renderer.render(component as unknown as Component);
expect(head).toBe('<title>T</title>');
expect(body).toBe('<!--[--><!--[-->ab<!--]--><!--]-->');
});
test('child inherits parent type when not specified', () => {
const component = (payload: Payload) => {
payload.child((payload) => {
payload.push('<meta name="x"/>');
payload.child((payload) => {
payload.push('<style>/* css */</style>');
const component = (renderer: Renderer) => {
renderer.child((renderer) => {
renderer.push('<meta name="x"/>');
renderer.child((renderer) => {
renderer.push('<style>/* css */</style>');
});
}, 'head');
};
const { head, body } = Payload.render(component as unknown as Component);
const { head, body } = Renderer.render(component as unknown as Component);
expect(body).toBe('<!--[--><!--[--><!--]--><!--]-->');
expect(head).toBe('<meta name="x"/><style>/* css */</style>');
});
test('get_path returns the path indexes to a payload', () => {
const root = new Payload(new SSRState('sync'));
let child_a: InstanceType<typeof Payload> | undefined;
let child_b: InstanceType<typeof Payload> | undefined;
let child_b_0: InstanceType<typeof Payload> | undefined;
test('get_path returns the path indexes to a renderer', () => {
const root = new Renderer(new SSRState('sync'));
let child_a: InstanceType<typeof Renderer> | undefined;
let child_b: InstanceType<typeof Renderer> | undefined;
let child_b_0: InstanceType<typeof Renderer> | undefined;
root.child(($$payload) => {
child_a = $$payload;
$$payload.push('A');
root.child(($$renderer) => {
child_a = $$renderer;
$$renderer.push('A');
});
root.child(($$payload) => {
child_b = $$payload;
$$payload.child(($$inner) => {
root.child(($$renderer) => {
child_b = $$renderer;
$$renderer.child(($$inner) => {
child_b_0 = $$inner;
$$inner.push('B0');
});
$$payload.push('B1');
$$renderer.push('B1');
});
expect(child_a!.get_path()).toEqual([0]);
@ -71,26 +71,26 @@ test('get_path returns the path indexes to a payload', () => {
});
test('creating an async child in a sync context throws', () => {
const component = (payload: Payload) => {
payload.push('a');
payload.child(async ($$payload) => {
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.child(async ($$renderer) => {
await Promise.resolve();
$$payload.push('x');
$$renderer.push('x');
});
};
expect(() => Payload.render(component as unknown as Component).head).toThrow('await_invalid');
expect(() => Payload.render(component as unknown as Component).html).toThrow('await_invalid');
expect(() => Payload.render(component as unknown as Component).body).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).head).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).html).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).body).toThrow('await_invalid');
});
test('compact synchronously aggregates a range and can transform into head/body', () => {
const component = (payload: Payload) => {
const start = payload.length;
payload.push('a');
payload.push('b');
payload.push('c');
payload.compact({
const component = (renderer: Renderer) => {
const start = renderer.length;
renderer.push('a');
renderer.push('b');
renderer.push('c');
renderer.compact({
start,
end: start + 2,
fn: (content) => {
@ -99,17 +99,17 @@ test('compact synchronously aggregates a range and can transform into head/body'
});
};
const { head, body } = Payload.render(component as unknown as Component);
const { head, body } = Renderer.render(component as unknown as Component);
expect(head).toBe('<h>H</h>');
expect(body).toBe('<!--[--><!--[-->abdc<!--]--><!--]-->');
});
test('local state is shallow-copied to children', () => {
const root = new Payload(new SSRState('sync'));
const root = new Renderer(new SSRState('sync'));
root.local.select_value = 'A';
let child: InstanceType<typeof Payload> | undefined;
root.child(($$payload) => {
child = $$payload;
let child: InstanceType<typeof Renderer> | undefined;
root.child(($$renderer) => {
child = $$renderer;
});
expect(child!.local.select_value).toBe('A');
@ -118,14 +118,14 @@ test('local state is shallow-copied to children', () => {
});
test('subsume replaces tree content and state from other', () => {
const a = new Payload(new SSRState('async'), undefined, 'head');
const a = new Renderer(new SSRState('async'), undefined, 'head');
a.push('<meta />');
a.local.select_value = 'A';
const b = new Payload(new SSRState('async'));
b.child(async ($$payload) => {
const b = new Renderer(new SSRState('async'));
b.child(async ($$renderer) => {
await Promise.resolve();
$$payload.push('body');
$$renderer.push('body');
});
b.global.css.add({ hash: 'h', code: 'c' });
b.global.set_title('Title', [1]);
@ -140,14 +140,14 @@ test('subsume replaces tree content and state from other', () => {
});
test('subsume refuses to switch modes', () => {
const a = new Payload(new SSRState('sync'), undefined, 'head');
const a = new Renderer(new SSRState('sync'), undefined, 'head');
a.push('<meta />');
a.local.select_value = 'A';
const b = new Payload(new SSRState('async'));
b.child(async ($$payload) => {
const b = new Renderer(new SSRState('async'));
b.child(async ($$renderer) => {
await Promise.resolve();
$$payload.push('body');
$$renderer.push('body');
});
b.global.css.add({ hash: 'h', code: 'c' });
b.global.set_title('Title', [1]);
@ -155,7 +155,7 @@ test('subsume refuses to switch modes', () => {
b.promises.initial = Promise.resolve();
expect(() => a.subsume(b)).toThrow(
"invariant: A payload cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
"invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
);
});
@ -200,31 +200,31 @@ describe('async', () => {
disable_async_mode_flag();
});
test('awaiting payload gets async content', async () => {
const component = (payload: Payload) => {
payload.push('1');
payload.child(async ($$payload) => {
test('awaiting renderer gets async content', async () => {
const component = (renderer: Renderer) => {
renderer.push('1');
renderer.child(async ($$renderer) => {
await Promise.resolve();
$$payload.push('2');
$$renderer.push('2');
});
payload.push('3');
renderer.push('3');
};
const result = await Payload.render(component as unknown as Component);
const result = await Renderer.render(component as unknown as Component);
expect(result.head).toBe('');
expect(result.body).toBe('<!--[--><!--[-->123<!--]--><!--]-->');
expect(() => result.html).toThrow('html_deprecated');
});
test('compact schedules followup when compaction input is async', async () => {
const component = (payload: Payload) => {
payload.push('a');
payload.child(async ($$payload) => {
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.child(async ($$renderer) => {
await Promise.resolve();
$$payload.push('X');
$$renderer.push('X');
});
payload.push('b');
payload.compact({
renderer.push('b');
renderer.compact({
start: 0,
fn: async (content) => ({
body: content.body.toLowerCase(),
@ -233,132 +233,132 @@ describe('async', () => {
});
};
const { body, head } = await Payload.render(component as unknown as Component);
const { body, head } = await Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->axb<!--]--><!--]-->');
});
test('push accepts async functions in async context', async () => {
const component = (payload: Payload) => {
payload.push('a');
payload.push(async () => {
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.push(async () => {
await Promise.resolve();
return 'b';
});
payload.push('c');
renderer.push('c');
};
const { head, body } = await Payload.render(component as unknown as Component);
const { head, body } = await Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->abc<!--]--><!--]-->');
});
test('push handles async functions with different timing', async () => {
const component = (payload: Payload) => {
payload.push(async () => {
const component = (renderer: Renderer) => {
renderer.push(async () => {
await Promise.resolve();
return 'fast';
});
payload.push(async () => {
renderer.push(async () => {
await new Promise((resolve) => setTimeout(resolve, 10));
return 'slow';
});
payload.push('sync');
renderer.push('sync');
};
const { head, body } = await Payload.render(component as unknown as Component);
const { head, body } = await Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->fastslowsync<!--]--><!--]-->');
});
test('push async functions work with head content type', async () => {
const component = (payload: Payload) => {
payload.child(($$payload) => {
$$payload.push(async () => {
const component = (renderer: Renderer) => {
renderer.child(($$renderer) => {
$$renderer.push(async () => {
await Promise.resolve();
return '<title>Async Title</title>';
});
}, 'head');
};
const { head, body } = await Payload.render(component as unknown as Component);
const { head, body } = await Renderer.render(component as unknown as Component);
expect(body).toBe('<!--[--><!--[--><!--]--><!--]-->');
expect(head).toBe('<title>Async Title</title>');
});
test('push async functions can be mixed with child payloads', async () => {
const component = (payload: Payload) => {
payload.push('start-');
payload.push(async () => {
test('push async functions can be mixed with child renderers', async () => {
const component = (renderer: Renderer) => {
renderer.push('start-');
renderer.push(async () => {
await Promise.resolve();
return 'async-';
});
payload.child(($$payload) => {
$$payload.push('child-');
renderer.child(($$renderer) => {
$$renderer.push('child-');
});
payload.push('-end');
renderer.push('-end');
};
const { head, body } = await Payload.render(component as unknown as Component);
const { head, body } = await Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->start-async-child--end<!--]--><!--]-->');
});
test('push async functions work with compact operations', async () => {
const component = (payload: Payload) => {
payload.push('a');
payload.push(async () => {
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.push(async () => {
await Promise.resolve();
return 'b';
});
payload.push('c');
payload.compact({
renderer.push('c');
renderer.compact({
start: 0,
fn: (content) => ({ head: '', body: content.body.toUpperCase() })
});
};
const { head, body } = await Payload.render(component as unknown as Component);
const { head, body } = await Renderer.render(component as unknown as Component);
expect(head).toBe('');
expect(body).toBe('<!--[--><!--[-->ABC<!--]--><!--]-->');
});
test('push async functions are not supported in sync context', () => {
const component = (payload: Payload) => {
payload.push('a');
payload.push(() => Promise.resolve('b'));
const component = (renderer: Renderer) => {
renderer.push('a');
renderer.push(() => Promise.resolve('b'));
};
expect(() => Payload.render(component as unknown as Component).body).toThrow('await_invalid');
expect(() => Payload.render(component as unknown as Component).html).toThrow('await_invalid');
expect(() => Payload.render(component as unknown as Component).head).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).body).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).html).toThrow('await_invalid');
expect(() => Renderer.render(component as unknown as Component).head).toThrow('await_invalid');
});
test('on_destroy yields callbacks in the correct order', async () => {
const destroyed: string[] = [];
const component = (payload: Payload) => {
payload.component((payload) => {
payload.on_destroy(() => destroyed.push('a'));
const component = (renderer: Renderer) => {
renderer.component((renderer) => {
renderer.on_destroy(() => destroyed.push('a'));
// children should not alter relative order
payload.child(async (payload) => {
renderer.child(async (renderer) => {
await Promise.resolve();
payload.on_destroy(() => destroyed.push('b'));
payload.on_destroy(() => destroyed.push('b*'));
renderer.on_destroy(() => destroyed.push('b'));
renderer.on_destroy(() => destroyed.push('b*'));
});
// but child components should
payload.component((payload) => {
payload.on_destroy(() => destroyed.push('c'));
renderer.component((renderer) => {
renderer.on_destroy(() => destroyed.push('c'));
});
payload.child((payload) => {
payload.on_destroy(() => destroyed.push('d'));
renderer.child((renderer) => {
renderer.on_destroy(() => destroyed.push('d'));
});
payload.component((payload) => {
payload.on_destroy(() => destroyed.push('e'));
renderer.component((renderer) => {
renderer.on_destroy(() => destroyed.push('e'));
});
});
};
await Payload.render(component as unknown as Component);
await Renderer.render(component as unknown as Component);
expect(destroyed).toEqual(['c', 'e', 'a', 'b', 'b*', 'd']);
});
});

@ -1,13 +1,13 @@
import type { Element } from './dev';
import type { Payload } from './payload';
import type { Renderer } from './renderer';
export interface SSRContext {
/** parent */
p: null | SSRContext;
/** component context */
c: null | Map<unknown, unknown>;
/** payload (renderer) */
r: null | Payload;
/** renderer */
r: null | Renderer;
/** dev mode only: the current component function */
function?: any;
/** dev mode only: the current element */

@ -1,25 +1,25 @@
import 'svelte/internal/flags/async';
import * as $ from 'svelte/internal/server';
export default function Async_each_fallback_hoisting($$payload) {
$$payload.child(async ($$payload) => {
export default function Async_each_fallback_hoisting( $$renderer) {
$$renderer.child(async ( $$renderer) => {
const each_array = $.ensure_array_like(await Promise.resolve([]));
if (each_array.length !== 0) {
$$payload.push('<!--[-->');
$$renderer.push('<!--[-->');
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
let item = each_array[$$index];
$$payload.push(`<!---->`);
$$payload.push(async () => $.escape(await Promise.reject('This should never be reached')));
$$renderer.push(`<!---->`);
$$renderer.push(async () => $.escape(await Promise.reject('This should never be reached')));
}
} else {
$$payload.push('<!--[!-->');
$$payload.push(`<!---->`);
$$payload.push(async () => $.escape(await Promise.resolve(4)));
$$renderer.push('<!--[!-->');
$$renderer.push(`<!---->`);
$$renderer.push(async () => $.escape(await Promise.resolve(4)));
}
});
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,23 +1,23 @@
import 'svelte/internal/flags/async';
import * as $ from 'svelte/internal/server';
export default function Async_each_hoisting($$payload) {
export default function Async_each_hoisting( $$renderer) {
const first = Promise.resolve(1);
const second = Promise.resolve(2);
const third = Promise.resolve(3);
$$payload.push(`<!--[-->`);
$$renderer.push(`<!--[-->`);
$$payload.child(async ($$payload) => {
$$renderer.child(async ( $$renderer) => {
const each_array = $.ensure_array_like(await Promise.resolve([first, second, third]));
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
let item = each_array[$$index];
$$payload.push(`<!---->`);
$$payload.push(async () => $.escape(await item));
$$renderer.push(`<!---->`);
$$renderer.push(async () => $.escape(await item));
}
});
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,16 +1,16 @@
import 'svelte/internal/flags/async';
import * as $ from 'svelte/internal/server';
export default function Async_if_alternate_hoisting($$payload) {
$$payload.child(async ($$payload) => {
export default function Async_if_alternate_hoisting( $$renderer) {
$$renderer.child(async ( $$renderer) => {
if (await Promise.resolve(false)) {
$$payload.push('<!--[-->');
$$payload.push(async () => $.escape(await Promise.reject('no no no')));
$$renderer.push('<!--[-->');
$$renderer.push(async () => $.escape(await Promise.reject('no no no')));
} else {
$$payload.push('<!--[!-->');
$$payload.push(async () => $.escape(await Promise.resolve('yes yes yes')));
$$renderer.push('<!--[!-->');
$$renderer.push(async () => $.escape(await Promise.resolve('yes yes yes')));
}
});
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,16 +1,16 @@
import 'svelte/internal/flags/async';
import * as $ from 'svelte/internal/server';
export default function Async_if_hoisting($$payload) {
$$payload.child(async ($$payload) => {
export default function Async_if_hoisting( $$renderer) {
$$renderer.child(async ( $$renderer) => {
if (await Promise.resolve(true)) {
$$payload.push('<!--[-->');
$$payload.push(async () => $.escape(await Promise.resolve('yes yes yes')));
$$renderer.push('<!--[-->');
$$renderer.push(async () => $.escape(await Promise.resolve('yes yes yes')));
} else {
$$payload.push('<!--[!-->');
$$payload.push(async () => $.escape(await Promise.reject('no no no')));
$$renderer.push('<!--[!-->');
$$renderer.push(async () => $.escape(await Promise.reject('no no no')));
}
});
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,6 +1,6 @@
import * as $ from 'svelte/internal/server';
export default function Await_block_scope($$payload) {
export default function Await_block_scope( $$renderer) {
let counter = { count: 0 };
const promise = Promise.resolve(counter);
@ -8,7 +8,7 @@ export default function Await_block_scope($$payload) {
counter.count += 1;
}
$$payload.push(`<button>clicks: ${$.escape(counter.count)}</button> `);
$.await($$payload, promise, () => {}, (counter) => {});
$$payload.push(`<!--]--> ${$.escape(counter.count)}`);
$$renderer.push(`<button>clicks: ${$.escape(counter.count)}</button> `);
$.await( $$renderer, promise, () => {}, (counter) => {});
$$renderer.push(`<!--]--> ${$.escape(counter.count)}`);
}

@ -1,18 +1,18 @@
import * as $ from 'svelte/internal/server';
import TextInput from './Child.svelte';
function snippet($$payload) {
$$payload.push(`<!---->Something`);
function snippet( $$renderer) {
$$renderer.push(`<!---->Something`);
}
export default function Bind_component_snippet($$payload) {
export default function Bind_component_snippet( $$renderer) {
let value = '';
const _snippet = snippet;
let $$settled = true;
let $$inner_payload;
let $$inner_renderer;
function $$render_inner($$payload) {
TextInput($$payload, {
function $$render_inner( $$renderer) {
TextInput( $$renderer, {
get value() {
return value;
},
@ -23,14 +23,14 @@ export default function Bind_component_snippet($$payload) {
}
});
$$payload.push(`<!----> value: ${$.escape(value)}`);
$$renderer.push(`<!----> value: ${$.escape(value)}`);
}
do {
$$settled = true;
$$inner_payload = $$payload.copy();
$$render_inner($$inner_payload);
$$inner_renderer = $$renderer.copy();
$$render_inner($$inner_renderer);
} while (!$$settled);
$$payload.subsume($$inner_payload);
$$renderer.subsume($$inner_renderer);
}

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Bind_this($$payload) {
Foo($$payload, {});
export default function Bind_this( $$renderer) {
Foo( $$renderer, {});
}

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Class_state_field_constructor_assignment($$payload, $$props) {
$$payload.component(($$payload) => {
export default function Class_state_field_constructor_assignment( $$renderer, $$props) {
$$renderer.component(( $$renderer) => {
class Foo {
a = 0;
#b;

@ -1,13 +1,13 @@
import * as $ from 'svelte/internal/server';
export default function Delegated_locally_declared_shadowed($$payload) {
$$payload.push(`<!--[-->`);
export default function Delegated_locally_declared_shadowed( $$renderer) {
$$renderer.push(`<!--[-->`);
const each_array = $.ensure_array_like({ length: 1 });
for (let index = 0, $$length = each_array.length; index < $$length; index++) {
$$payload.push(`<button type="button"${$.attr('data-index', index)}>B</button>`);
$$renderer.push(`<button type="button"${$.attr('data-index', index)}>B</button>`);
}
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,10 +1,10 @@
import * as $ from 'svelte/internal/server';
export default function Main($$payload) {
export default function Main( $$renderer) {
// needs to be a snapshot test because jsdom does auto-correct the attribute casing
let x = 'test';
let y = () => 'test';
$$payload.push(`<div${$.attr('foobar', x)}></div> <svg${$.attr('viewBox', x)}></svg> <custom-element${$.attr('foobar', x)}></custom-element> <div${$.attr('foobar', y())}></div> <svg${$.attr('viewBox', y())}></svg> <custom-element${$.attr('foobar', y())}></custom-element>`);
$$renderer.push(`<div${$.attr('foobar', x)}></div> <svg${$.attr('viewBox', x)}></svg> <custom-element${$.attr('foobar', x)}></custom-element> <div${$.attr('foobar', y())}></div> <svg${$.attr('viewBox', y())}></svg> <custom-element${$.attr('foobar', y())}></custom-element>`);
}

@ -1,13 +1,13 @@
import * as $ from 'svelte/internal/server';
export default function Each_index_non_null($$payload) {
$$payload.push(`<!--[-->`);
export default function Each_index_non_null( $$renderer) {
$$renderer.push(`<!--[-->`);
const each_array = $.ensure_array_like(Array(10));
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
$$payload.push(`<p>index: ${$.escape(i)}</p>`);
$$renderer.push(`<p>index: ${$.escape(i)}</p>`);
}
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,15 +1,15 @@
import * as $ from 'svelte/internal/server';
export default function Each_string_template($$payload) {
$$payload.push(`<!--[-->`);
export default function Each_string_template( $$renderer) {
$$renderer.push(`<!--[-->`);
const each_array = $.ensure_array_like(['foo', 'bar', 'baz']);
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
let thing = each_array[$$index];
$$payload.push(`<!---->${$.escape(thing)}, `);
$$renderer.push(`<!---->${$.escape(thing)}, `);
}
$$payload.push(`<!--]-->`);
$$renderer.push(`<!--]-->`);
}

@ -1,6 +1,6 @@
import * as $ from 'svelte/internal/server';
export default function Function_prop_no_getter($$payload) {
export default function Function_prop_no_getter( $$renderer) {
let count = 0;
function onmouseup() {
@ -9,13 +9,13 @@ export default function Function_prop_no_getter($$payload) {
const plusOne = (num) => num + 1;
Button($$payload, {
Button( $$renderer, {
onmousedown: () => count += 1,
onmouseup,
onmouseenter: () => count = plusOne(count),
children: ($$payload) => {
$$payload.push(`<!---->clicks: ${$.escape(count)}`);
children: ( $$renderer) => {
$$renderer.push(`<!---->clicks: ${$.escape(count)}`);
},
$$slots: { default: true }

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Functional_templating($$payload) {
$$payload.push(`<h1>hello</h1> <div class="potato"><p>child element</p> <p>another child element</p></div>`);
export default function Functional_templating( $$renderer) {
$$renderer.push(`<h1>hello</h1> <div class="potato"><p>child element</p> <p>another child element</p></div>`);
}

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Hello_world($$payload) {
$$payload.push(`<h1>hello world</h1>`);
export default function Hello_world( $$renderer) {
$$renderer.push(`<h1>hello world</h1>`);
}

@ -1,5 +1,5 @@
import * as $ from 'svelte/internal/server';
export default function Hmr($$payload) {
$$payload.push(`<h1>hello world</h1>`);
export default function Hmr( $$renderer) {
$$renderer.push(`<h1>hello world</h1>`);
}

@ -1,4 +1,4 @@
import * as $ from 'svelte/internal/server';
import { random } from './module.svelte';
export default function Imports_in_modules($$payload) {}
export default function Imports_in_modules( $$renderer) {}

@ -1,8 +1,8 @@
import * as $ from 'svelte/internal/server';
export default function Nullish_coallescence_omittance($$payload) {
export default function Nullish_coallescence_omittance( $$renderer) {
let name = 'world';
let count = 0;
$$payload.push(`<h1>Hello, world!</h1> <b>123</b> <button>Count is ${$.escape(count)}</button> <h1>Hello, world</h1>`);
$$renderer.push(`<h1>Hello, world!</h1> <b>123</b> <button>Count is ${$.escape(count)}</button> <h1>Hello, world</h1>`);
}

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Props_identifier($$payload, $$props) {
$$payload.component(($$payload) => {
export default function Props_identifier( $$renderer, $$props) {
$$renderer.component(( $$renderer) => {
let { $$slots, $$events, ...props } = $$props;
props.a;

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Purity($$payload) {
$$payload.push(`<p>0</p> <p>${$.escape(location.href)}</p> `);
Child($$payload, { prop: encodeURIComponent('hello') });
$$payload.push(`<!---->`);
export default function Purity( $$renderer) {
$$renderer.push(`<p>0</p> <p>${$.escape(location.href)}</p> `);
Child( $$renderer, { prop: encodeURIComponent('hello') });
$$renderer.push(`<!---->`);
}

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Skip_static_subtree($$payload, $$props) {
export default function Skip_static_subtree( $$renderer, $$props) {
let { title, content } = $$props;
$$payload.push(`<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)} <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main> <cant-skip><custom-elements with="attributes"></custom-elements></cant-skip> <div><input autofocus/></div> <div><source muted/></div> <select><option value="a"${$.maybe_selected($$payload, 'a')}>a</option></select> <img src="..." alt="" loading="lazy"/> <div><img src="..." alt="" loading="lazy"/></div>`);
$$renderer.push(`<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)} <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main> <cant-skip><custom-elements with="attributes"></custom-elements></cant-skip> <div><input autofocus/></div> <div><source muted/></div> <select><option value="a"${$.maybe_selected( $$renderer, 'a')}>a</option></select> <img src="..." alt="" loading="lazy"/> <div><img src="..." alt="" loading="lazy"/></div>`);
}

@ -1,6 +1,6 @@
import * as $ from 'svelte/internal/server';
export default function State_proxy_literal($$payload) {
export default function State_proxy_literal( $$renderer) {
let str = '';
let tpl = ``;
@ -11,5 +11,5 @@ export default function State_proxy_literal($$payload) {
tpl = ``;
}
$$payload.push(`<input${$.attr('value', str)}/> <input${$.attr('value', tpl)}/> <button>reset</button>`);
$$renderer.push(`<input${$.attr('value', str)}/> <input${$.attr('value', tpl)}/> <button>reset</button>`);
}

@ -1,7 +1,7 @@
import * as $ from 'svelte/internal/server';
export default function Svelte_element($$payload, $$props) {
export default function Svelte_element( $$renderer, $$props) {
let { tag = 'hr' } = $$props;
$.element($$payload, tag);
$.element( $$renderer, tag);
}

@ -1,6 +1,6 @@
import * as $ from 'svelte/internal/server';
export default function Text_nodes_deriveds($$payload) {
export default function Text_nodes_deriveds( $$renderer) {
let count1 = 0;
let count2 = 0;
@ -12,5 +12,5 @@ export default function Text_nodes_deriveds($$payload) {
return count2;
}
$$payload.push(`<p>${$.escape(text1())}${$.escape(text2())}</p>`);
$$renderer.push(`<p>${$.escape(text1())}${$.escape(text2())}</p>`);
}
Loading…
Cancel
Save