Merge branch 'master' into pr/3822

pull/3822/head
Conduitry 6 years ago
commit 67bafeaf40

@ -1,5 +1,14 @@
# Svelte changelog # Svelte changelog
## Unreleased
* Fix unused export warning for props used as stores ([#4021](https://github.com/sveltejs/svelte/issues/4021))
* Fix `{:then}` without resolved value containing `{#each}` ([#4022](https://github.com/sveltejs/svelte/issues/4022))
* Fix incorrect code generated with `loopGuardTimeout` ([#4034](https://github.com/sveltejs/svelte/issues/4034))
* Fix `{:then}` containing `{#if}` ([#4044](https://github.com/sveltejs/svelte/issues/4044))
* Fix bare `import`s in `format: 'cjs'` output mode ([#4055](https://github.com/sveltejs/svelte/issues/4050))
* Warn when using a known global as a component name ([#4070](https://github.com/sveltejs/svelte/issues/4070))
## 3.16.0 ## 3.16.0
* Use bitmasks to track changes ([#3945](https://github.com/sveltejs/svelte/pull/3945)) * Use bitmasks to track changes ([#3945](https://github.com/sveltejs/svelte/pull/3945))

@ -53,7 +53,7 @@ What happens if we use the new model as a starting point?
The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing. The same 'hello world' app that took 204kb with React and Next weighs just 7kb with Sapper. That number is likely to fall further in the future as we explore the space of optimisation possibilities, such as not shipping any JavaScript *at all* for pages that aren't interactive, beyond the tiny Sapper runtime that handles client-side routing.
What about a more 'real world' example? Conveniently, the [RealWorld](https://github.com/gothinkster/realworld) project, which challenges frameworks to develop an implementation of a Medium clone, gives us a way to find out. The [Sapper implementation](http://svelte-realworld.now.sh/) takes 39.6kb (11.8kb zipped) to render an interactive homepage. What about a more 'real world' example? Conveniently, the [RealWorld](https://github.com/gothinkster/realworld) project, which challenges frameworks to develop an implementation of a Medium clone, gives us a way to find out. The [Sapper implementation](https://github.com/sveltejs/realworld) takes 39.6kb (11.8kb zipped) to render an interactive homepage.
<aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside> <aside><p>Code-splitting isn't free — if the reference implementation used code-splitting, it would be larger still</p></aside>

@ -45,9 +45,11 @@
</style> </style>
<div class="logos"> <div class="logos">
<a target="_blank" rel="noopener" href="https://absoluteweb.com"><img src="organisations/absoluteweb.svg" alt="Absolute Web logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://bekchy.com"><img src="organisations/bekchy.png" alt="Bekchy logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://bekchy.com"><img src="organisations/bekchy.png" alt="Bekchy logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://beyonk.com"><img src="organisations/beyonk.svg" alt="Beyonk logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://beyonk.com"><img src="organisations/beyonk.svg" alt="Beyonk logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://buydotstar.com"><img src="organisations/buydotstar.svg" alt="buy.* logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://buydotstar.com"><img src="organisations/buydotstar.svg" alt="buy.* logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://cashfree.com/"><img src="organisations/cashfree.svg" alt="Cashfree logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://chess.com" style="background-color: rgb(49,46,43);"><img src="organisations/chess.svg" alt="Chess.com logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://chess.com" style="background-color: rgb(49,46,43);"><img src="organisations/chess.svg" alt="Chess.com logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://comigosaude.com.br"><img src="organisations/comigo.svg" alt="Comigo logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://comigosaude.com.br"><img src="organisations/comigo.svg" alt="Comigo logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://datawrapper.de"><img src="organisations/datawrapper.svg" alt="Datawrapper logo" loading="lazy"></a> <a target="_blank" rel="noopener" href="https://datawrapper.de"><img src="organisations/datawrapper.svg" alt="Datawrapper logo" loading="lazy"></a>

@ -187,7 +187,7 @@
<svelte:head> <svelte:head>
<title>{name} • REPL • Svelte</title> <title>{name} • REPL • Svelte</title>
<meta name="twitter:title" content="Svelte REPL"> <meta name="twitter:title" content="{name} | Svelte REPL">
<meta name="twitter:description" content="Cybernetically enhanced web apps"> <meta name="twitter:description" content="Cybernetically enhanced web apps">
<meta name="Description" content="Interactive Svelte playground"> <meta name="Description" content="Interactive Svelte playground">
</svelte:head> </svelte:head>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2156 462"><defs><linearGradient id="linear-gradient" x1="212.75" y1="160.13" x2="257.3" y2="176.47" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f18221"/><stop offset="1" stop-color="#f2b81a"/></linearGradient><linearGradient id="linear-gradient-2" x1="255.57" y1="98.18" x2="450.73" y2="92.36" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#215f70"/><stop offset="1" stop-color="#00b7b1"/></linearGradient><style>.cls-2{fill:#fff}</style></defs><path fill="#4d3475" d="M1 0h2155v462H1z"/><path class="cls-2" d="M819.83 318.07a53.65 53.65 0 01-47.75 53.19 215.5 215.5 0 01-24.54 1.34q-56 0-89.69-35.34t-33.72-92.74q0-61.71 37.93-99.73t95.88-38q6.31 0 12.26.3a52.54 52.54 0 0149.63 52.61 110.48 110.48 0 00-57.4-15.42q-41.8 0-67.72 26.72t-25.92 71.4q0 42.51 24.22 67.71t63.68 25.21q36.4 0 63.14-17.22zM1005 368.29h-40.41v-28.7h-.72q-19 33-55.78 33-27.09 0-42.43-14.71T850.32 319q0-52 59.92-60.64l54.53-7.71q0-39.28-37.31-39.28-32.84 0-59.2 22.6c0-25.22 17.75-47.61 42.64-51.71a149.89 149.89 0 0124.45-1.93q69.6 0 69.6 68.53zm-40.18-90.22l-38.57 5.38q-17.94 2.32-27 8.7t-9.06 22.33a24.45 24.45 0 008.35 19.1q8.34 7.46 22.33 7.45 19 0 31.48-13.37T964.77 294zM1044.23 324q23.32 17.76 51.49 17.76 37.66 0 37.66-22.25a17.54 17.54 0 00-3.22-10.67 31 31 0 00-8.7-7.8 68.51 68.51 0 00-12.92-6.1q-7.44-2.7-16.59-6.1a175.83 175.83 0 01-20.36-9.51 61.5 61.5 0 01-15.07-11.39 42.85 42.85 0 01-9.06-14.44 53.23 53.23 0 01-3-18.83 43.48 43.48 0 016.28-23.41 54.58 54.58 0 0116.86-17 80.72 80.72 0 0124-10.41 110.09 110.09 0 0127.8-3.5h2.66c23.89.39 42.91 20.21 42.91 44.11q-19.38-13.27-44.49-13.27a58.38 58.38 0 00-14.26 1.61 36.82 36.82 0 00-10.85 4.48 22.12 22.12 0 00-7 6.91 16.51 16.51 0 00-2.51 8.88 19 19 0 002.51 10.05 22.65 22.65 0 007.45 7.26 63.78 63.78 0 0011.84 5.74q6.9 2.61 15.87 5.65a232.44 232.44 0 0121.26 9.87 72 72 0 0116 11.39 44.74 44.74 0 0110.22 14.71q3.6 8.34 3.59 19.82 0 14-6.45 24.39a53.84 53.84 0 01-17.15 17.19 80.48 80.48 0 01-24.85 10.14 129.19 129.19 0 01-29.69 3.32c-1.65 0-3.29 0-4.91-.07a48.58 48.58 0 01-47.32-48.53zM1377.34 368.29a41.61 41.61 0 01-41.61-41.62v-58.83q0-54.52-36.42-54.53-18.3 0-30.85 15.78t-12.56 40.37v98.83h-41.79V138.15a41.8 41.8 0 0141.79-41.8V215.1h.72q20.81-34.78 59.55-34.8 61.17 0 61.17 74.8zM1531.79 130.26a37.82 37.82 0 00-19.19-4.85q-30.33 0-30.32 34.26v24.94H1525a32.64 32.64 0 01-32.64 32.64h-9.87v151h-41.62v-151h-31.39V216a31.39 31.39 0 0131.39-31.39v-29.78q0-29.06 19-45.83t47.54-16.77q15.42 0 24.39 3.41zM1661.12 224.25q-7.53-5.91-21.7-5.92-18.48 0-30.86 16.68t-12.38 45.39v87.89h-41.61V226.23a41.61 41.61 0 0141.61-41.62v37.85h.72q6.11-19.38 18.75-30.23t28.25-10.85q11.31 0 17.22 3.41zM1842.84 287.75h-125.21q.7 25.47 15.69 39.29t41.17 13.81q29.41 0 54-17.58v33.54q-25.12 15.79-66.37 15.79-40.55 0-63.59-25t-23.06-70.41q0-42.87 25.39-69.87t63.05-27q37.66 0 58.3 24.22t20.63 67.27zm-40.19-29.42q-.18-22.41-10.58-34.88t-28.7-12.45a40.37 40.37 0 00-30.4 13.09q-12.48 13.1-15.34 34.26zM2038 287.75h-125.21q.72 25.47 15.7 39.29t41.17 13.81q29.41 0 54-17.58v33.54q-25.11 15.79-66.37 15.79-40.54 0-63.59-25t-23-70.41q0-42.87 25.38-69.87t63-27q37.68 0 58.3 24.22t20.62 67.25zm-40.18-29.42q-.18-22.41-10.59-34.88t-28.7-12.45a40.37 40.37 0 00-30.4 13.09q-12.47 13.1-15.34 34.26z"/><path d="M220.69 154.26c-16.76 2.15-16 34.7-18.34 61.86l-13.54 138.76a64.73 64.73 0 01-70.7 58.12l20.82-213.39a53.09 53.09 0 0158-47.68z" fill="#f2b81a"/><path d="M410.32 172.76a63.36 63.36 0 01-69.21 56.9l-138.76-13.54c2.34-27.16 1.58-59.71 18.34-61.86z" fill="url(#linear-gradient)"/><path d="M540.09 73.67A65.07 65.07 0 01469 132.12l-142.5-13.91c2.4-27.9 1.62-61.34 18.84-63.54z" fill="url(#linear-gradient-2)"/><path d="M345.61 54.06c-17.49 2.81-16.71 36.25-19.11 64.15l-13.91 142.5a66.45 66.45 0 01-72.6 59.7l21.38-219.16c2.92-30 29.59-51.89 59.83-49.57z" fill="#00b7b1"/></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -344,7 +344,7 @@ export default class Component {
}; };
} }
get_unique_name(name: string): Identifier { get_unique_name(name: string, scope?: Scope): Identifier {
if (test) name = `${name}$`; if (test) name = `${name}$`;
let alias = name; let alias = name;
for ( for (
@ -352,7 +352,8 @@ export default class Component {
reserved.has(alias) || reserved.has(alias) ||
this.var_lookup.has(alias) || this.var_lookup.has(alias) ||
this.used_names.has(alias) || this.used_names.has(alias) ||
this.globally_used_names.has(alias); this.globally_used_names.has(alias) ||
(scope && scope.has(alias));
alias = `${name}_${i++}` alias = `${name}_${i++}`
); );
this.used_names.add(alias); this.used_names.add(alias);
@ -465,7 +466,7 @@ export default class Component {
extract_names(declarator.id).forEach(name => { extract_names(declarator.id).forEach(name => {
const variable = this.var_lookup.get(name); const variable = this.var_lookup.get(name);
variable.export_name = name; variable.export_name = name;
if (variable.writable && !(variable.referenced || variable.referenced_from_script)) { if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) {
this.warn(declarator, { this.warn(declarator, {
code: `unused-export-let`, code: `unused-export-let`,
message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const '${name}'\`` message: `${this.name.name} has unused export property '${name}'. If it is for external reference only, please consider using \`export const '${name}'\``
@ -488,7 +489,7 @@ export default class Component {
if (variable) { if (variable) {
variable.export_name = specifier.exported.name; variable.export_name = specifier.exported.name;
if (variable.writable && !(variable.referenced || variable.referenced_from_script)) { if (variable.writable && !(variable.referenced || variable.referenced_from_script || variable.subscribable)) {
this.warn(specifier, { this.warn(specifier, {
code: `unused-export-let`, code: `unused-export-let`,
message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const '${specifier.exported.name}'\`` message: `${this.name.name} has unused export property '${specifier.exported.name}'. If it is for external reference only, please consider using \`export const '${specifier.exported.name}'\``
@ -707,8 +708,7 @@ export default class Component {
const remove = (parent, prop, index) => { const remove = (parent, prop, index) => {
to_remove.unshift([parent, prop, index]); to_remove.unshift([parent, prop, index]);
}; };
let scope_updated = false;
const to_insert = new Map();
walk(content, { walk(content, {
enter(node, parent, prop, index) { enter(node, parent, prop, index) {
@ -735,37 +735,21 @@ export default class Component {
} }
component.warn_on_undefined_store_value_references(node, parent, scope); component.warn_on_undefined_store_value_references(node, parent, scope);
},
leave(node) {
// do it on leave, to prevent infinite loop
if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0) { if (component.compile_options.dev && component.compile_options.loopGuardTimeout > 0) {
const to_insert_for_loop_protect = component.loop_protect(node, prop, index, component.compile_options.loopGuardTimeout); const to_replace_for_loop_protect = component.loop_protect(node, scope, component.compile_options.loopGuardTimeout);
if (to_insert_for_loop_protect) { if (to_replace_for_loop_protect) {
if (!Array.isArray(parent[prop])) { this.replace(to_replace_for_loop_protect);
parent[prop] = { scope_updated = true;
type: 'BlockStatement',
body: [to_insert_for_loop_protect.node, node],
};
} else {
// can't insert directly, will screw up the index in the for-loop of estree-walker
if (!to_insert.has(parent)) {
to_insert.set(parent, []);
} }
to_insert.get(parent).push(to_insert_for_loop_protect);
} }
}
}
},
leave(node) {
if (map.has(node)) { if (map.has(node)) {
scope = scope.parent; scope = scope.parent;
} }
if (to_insert.has(node)) {
const nodes_to_insert = to_insert.get(node);
for (const { index, prop, node: node_to_insert } of nodes_to_insert.reverse()) {
node[prop].splice(index, 0, node_to_insert);
}
to_insert.delete(node);
}
}, },
}); });
@ -778,6 +762,12 @@ export default class Component {
} }
} }
} }
if (scope_updated) {
const { scope, map } = create_scopes(script.content);
this.instance_scope = scope;
this.instance_scope_map = map;
}
} }
track_references_and_mutations() { track_references_and_mutations() {
@ -849,15 +839,12 @@ export default class Component {
} }
} }
loop_protect(node, prop, index, timeout) { loop_protect(node, scope: Scope, timeout: number): Node | null {
if (node.type === 'WhileStatement' || if (node.type === 'WhileStatement' ||
node.type === 'ForStatement' || node.type === 'ForStatement' ||
node.type === 'DoWhileStatement') { node.type === 'DoWhileStatement') {
const guard = this.get_unique_name('guard'); const guard = this.get_unique_name('guard', scope);
this.add_var({ this.used_names.add(guard.name);
name: guard.name,
internal: true,
});
const before = b`const ${guard} = @loop_guard(${timeout})`; const before = b`const ${guard} = @loop_guard(${timeout})`;
const inside = b`${guard}();`; const inside = b`${guard}();`;
@ -870,7 +857,14 @@ export default class Component {
}; };
} }
node.body.body.push(inside[0]); node.body.body.push(inside[0]);
return { index, prop, node: before[0] };
return {
type: 'BlockStatement',
body: [
before[0],
node,
],
};
} }
return null; return null;
} }
@ -1289,7 +1283,7 @@ export default class Component {
if (this.var_lookup.has(name) && !this.var_lookup.get(name).global) return; if (this.var_lookup.has(name) && !this.var_lookup.get(name).global) return;
if (template_scope && template_scope.names.has(name)) return; if (template_scope && template_scope.names.has(name)) return;
if (globals.has(name)) return; if (globals.has(name) && node.type !== 'InlineComponent') return;
let message = `'${name}' is not defined`; let message = `'${name}' is not defined`;
if (!this.ast.instance) if (!this.ast.instance)

@ -152,7 +152,12 @@ function cjs(
const internal_globals = get_internal_globals(globals, helpers); const internal_globals = get_internal_globals(globals, helpers);
const user_requires = imports.map(node => ({ const user_requires = imports.map(node => {
const init = x`require("${edit_source(node.source.value, sveltePath)}")`;
if (node.specifiers.length === 0) {
return b`${init};`;
}
return {
type: 'VariableDeclaration', type: 'VariableDeclaration',
kind: 'const', kind: 'const',
declarations: [{ declarations: [{
@ -171,9 +176,10 @@ function cjs(
kind: 'init' kind: 'init'
})) }))
}, },
init: x`require("${edit_source(node.source.value, sveltePath)}")` init
}] }]
})); };
});
const exports = module_exports.map(x => b`exports.${{ type: 'Identifier', name: x.as }} = ${{ type: 'Identifier', name: x.name }};`); const exports = module_exports.map(x => b`exports.${{ type: 'Identifier', name: x.as }} = ${{ type: 'Identifier', name: x.name }};`);

@ -71,6 +71,8 @@ export default class AwaitBlockWrapper extends Wrapper {
this.not_static_content(); this.not_static_content();
block.add_dependencies(this.node.expression.dependencies); block.add_dependencies(this.node.expression.dependencies);
if (this.node.value) block.renderer.add_to_context(this.node.value, true);
if (this.node.error) block.renderer.add_to_context(this.node.error, true);
let is_dynamic = false; let is_dynamic = false;
let has_intros = false; let has_intros = false;
@ -118,9 +120,6 @@ export default class AwaitBlockWrapper extends Wrapper {
if (has_outros) { if (has_outros) {
block.add_outro(); block.add_outro();
} }
if (this.node.value) block.renderer.add_to_context(this.node.value, true);
if (this.node.error) block.renderer.add_to_context(this.node.error, true);
} }
render( render(
@ -206,7 +205,7 @@ export default class AwaitBlockWrapper extends Wrapper {
} else { } else {
const #child_ctx = #ctx.slice(); const #child_ctx = #ctx.slice();
#child_ctx[${value_index}] = ${info}.resolved; ${this.node.value && x`#child_ctx[${value_index}] = ${info}.resolved;`}
${info}.block.p(#child_ctx, #dirty); ${info}.block.p(#child_ctx, #dirty);
} }
`); `);
@ -220,7 +219,7 @@ export default class AwaitBlockWrapper extends Wrapper {
block.chunks.update.push(b` block.chunks.update.push(b`
{ {
const #child_ctx = #ctx.slice(); const #child_ctx = #ctx.slice();
#child_ctx[${value_index}] = ${info}.resolved; ${this.node.value && x`#child_ctx[${value_index}] = ${info}.resolved;`}
${info}.block.p(#child_ctx, #dirty); ${info}.block.p(#child_ctx, #dirty);
} }
`); `);

@ -1,8 +1,13 @@
/* generated by Svelte vX.Y.Z */ /* generated by Svelte vX.Y.Z */
import { import {
SvelteComponentDev, SvelteComponentDev,
add_location,
binding_callbacks,
detach_dev,
dispatch_dev, dispatch_dev,
element,
init, init,
insert_dev,
loop_guard, loop_guard,
noop, noop,
safe_not_equal safe_not_equal
@ -11,16 +16,27 @@ import {
const file = undefined; const file = undefined;
function create_fragment(ctx) { function create_fragment(ctx) {
let div;
const block = { const block = {
c: noop, c: function create() {
div = element("div");
add_location(div, file, 22, 0, 288);
},
l: function claim(nodes) { l: function claim(nodes) {
throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option"); throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
}, },
m: noop, m: function mount(target, anchor) {
insert_dev(target, div, anchor);
/*div_binding*/ ctx[1](div);
},
p: noop, p: noop,
i: noop, i: noop,
o: noop, o: noop,
d: noop d: function destroy(detaching) {
if (detaching) detach_dev(div);
/*div_binding*/ ctx[1](null);
}
}; };
dispatch_dev("SvelteRegisterBlock", { dispatch_dev("SvelteRegisterBlock", {
@ -34,57 +50,93 @@ function create_fragment(ctx) {
return block; return block;
} }
function foo() {
const guard = "foo";
{
const guard_1 = loop_guard(100);
while (true) {
console.log(guard);
guard_1();
}
}
}
function instance($$self, $$props, $$invalidate) { function instance($$self, $$props, $$invalidate) {
let node;
{
const guard = loop_guard(100); const guard = loop_guard(100);
while (true) { while (true) {
foo(); foo();
guard(); guard();
} }
}
const guard_1 = loop_guard(100); {
const guard_2 = loop_guard(100);
for (; ; ) { for (; ; ) {
foo(); foo();
guard_1(); guard_2();
}
} }
const guard_2 = loop_guard(100); {
const guard_3 = loop_guard(100);
while (true) { while (true) {
foo(); foo();
guard_2(); guard_3();
}
} }
const guard_4 = loop_guard(100); {
const guard_5 = loop_guard(100);
do { do {
foo(); foo();
guard_4(); guard_5();
} while (true); } while (true);
}
function div_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
$$invalidate(0, node = $$value);
});
}
$$self.$capture_state = () => ({ foo }); $$self.$capture_state = () => ({ node, foo, console });
$$self.$inject_state = noop;
$$self.$inject_state = $$props => {
if ("node" in $$props) $$invalidate(0, node = $$props.node);
};
if ($$props && "$$inject" in $$props) {
$$self.$inject_state($$props.$$inject);
}
$: { $: {
const guard_3 = loop_guard(100); const guard_4 = loop_guard(100);
while (true) { while (true) {
foo(); foo();
guard_3(); guard_4();
} }
} }
$: { $: {
const guard_5 = loop_guard(100); const guard_6 = loop_guard(100);
do { do {
foo(); foo();
guard_5(); guard_6();
} while (true); } while (true);
} }
return []; return [node, div_binding];
} }
class Component extends SvelteComponentDev { class Component extends SvelteComponentDev {

@ -1,4 +1,13 @@
<script> <script>
let node;
function foo() {
const guard = 'foo';
while(true) {
console.log(guard);
}
}
while(true) { while(true) {
foo(); foo();
} }
@ -10,3 +19,5 @@
do foo(); while(true); do foo(); while(true);
$: do foo(); while(true); $: do foo(); while(true);
</script> </script>
<div bind:this={node}></div>

@ -0,0 +1,25 @@
let fulfil;
const thePromise = new Promise(f => {
fulfil = f;
});
export default {
props: {
thePromise
},
html: `
loading...
`,
async test({ assert, component, target }) {
fulfil([]);
await thePromise;
assert.htmlEqual(target.innerHTML, `
<p>promise array is empty</p>
`);
}
};

@ -0,0 +1,13 @@
<script>
export let thePromise;
</script>
{#await thePromise}
loading...
{:then r}
{#if r.length < 1}
<p>promise array is empty</p>
{:else}
<p>promise array is not empty</p>
{/if}
{/await}

@ -0,0 +1,12 @@
<script>
const promise = new Promise(() => {});
const test = [1, 2, 3];
</script>
{#await promise}
<div>waiting</div>
{:then}
{#each test as t}
<div>t</div>
{/each}
{/await}

@ -0,0 +1,7 @@
export default {
html: '<div></div>',
compileOptions: {
dev: true,
loopGuardTimeout: 100,
}
};

@ -0,0 +1,7 @@
<script>
let node;
(function () {
while(false) ;
}());
</script>
<div bind:this={node}></div>

@ -0,0 +1,15 @@
[{
"code": "missing-declaration",
"message": "'String' is not defined. Consider adding a <script> block with 'export let String' to declare a prop",
"start": {
"line": 2,
"column": 1,
"character": 7
},
"end": {
"line": 2,
"column": 10,
"character": 16
},
"pos": 7
}]

@ -18,4 +18,8 @@
function foo() { function foo() {
return m + n + o; return m + n + o;
} }
export let p;
export let q;
$p;
</script> </script>
{$q}

Loading…
Cancel
Save