mirror of https://github.com/sveltejs/svelte
commit
3ab156b2bb
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: don't swallow `DOMException` when `media.play()` fails in `bind:paused`
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: correctly print `!doctype` during `print`
|
||||
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: reduce if block nesting
|
||||
@ -1,115 +0,0 @@
|
||||
name: Update pkg.pr.new comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ['Publish Any Commit']
|
||||
types:
|
||||
- completed
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: 'Update comment'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: output
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
|
||||
- run: ls -R .
|
||||
- name: 'Post or update comment'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const output = JSON.parse(fs.readFileSync('output.json', 'utf8'));
|
||||
|
||||
const bot_comment_identifier = `<!-- pkg.pr.new comment -->`;
|
||||
|
||||
const body = (number) => `${bot_comment_identifier}
|
||||
|
||||
[Playground](https://svelte.dev/playground?version=pr-${number})
|
||||
|
||||
\`\`\`
|
||||
${output.packages.map((p) => `pnpm add https://pkg.pr.new/${p.name}@${number}`).join('\n')}
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
async function find_bot_comment(issue_number) {
|
||||
if (!issue_number) return null;
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue_number,
|
||||
});
|
||||
return comments.data.find((comment) =>
|
||||
comment.body.includes(bot_comment_identifier)
|
||||
);
|
||||
}
|
||||
|
||||
async function create_or_update_comment(issue_number) {
|
||||
if (!issue_number) {
|
||||
console.log('No issue number provided. Cannot post or update comment.');
|
||||
return;
|
||||
}
|
||||
|
||||
const existing_comment = await find_bot_comment(issue_number);
|
||||
if (existing_comment) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing_comment.id,
|
||||
body: body(issue_number),
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: issue_number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: body(issue_number),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function log_publish_info() {
|
||||
const svelte_package = output.packages.find(p => p.name === 'svelte');
|
||||
const svelte_sha = svelte_package.url.replace(/^.+@([^@]+)$/, '$1');
|
||||
console.log('\n' + '='.repeat(50));
|
||||
console.log('Publish Information');
|
||||
console.log('='.repeat(50));
|
||||
console.log('\nPublished Packages:');
|
||||
console.log(output.packages.map((p) => `${p.name} - pnpm add https://pkg.pr.new/${p.name}@${p.url.replace(/^.+@([^@]+)$/, '$1')}`).join('\n'));
|
||||
if(svelte_sha){
|
||||
console.log('\nPlayground URL:');
|
||||
console.log(`\nhttps://svelte.dev/playground?version=commit-${svelte_sha}`)
|
||||
}
|
||||
console.log('\n' + '='.repeat(50));
|
||||
}
|
||||
|
||||
if (output.event_name === 'pull_request') {
|
||||
if (output.number) {
|
||||
await create_or_update_comment(output.number);
|
||||
}
|
||||
} else if (output.event_name === 'push') {
|
||||
const pull_requests = await github.rest.pulls.list({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
head: `${context.repo.owner}:${output.ref.replace('refs/heads/', '')}`,
|
||||
});
|
||||
|
||||
if (pull_requests.data.length > 0) {
|
||||
await create_or_update_comment(pull_requests.data[0].number);
|
||||
} else {
|
||||
console.log(
|
||||
'No open pull request found for this push. Logging publish information to console:'
|
||||
);
|
||||
await log_publish_info();
|
||||
}
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
import { busy } from './util.js';
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let computed1 = $.derived(() => $.get(head));
|
||||
let computed2 = $.derived(() => ($.get(computed1), 0));
|
||||
let computed3 = $.derived(() => (busy(), $.get(computed2) + 1)); // heavy computation
|
||||
let computed4 = $.derived(() => $.get(computed3) + 2);
|
||||
let computed5 = $.derived(() => $.get(computed4) + 3);
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(computed5);
|
||||
busy(); // heavy side effect
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(computed5) === 6);
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(computed5) === 6);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_avoidable_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_avoidable_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_avoidable_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_avoidable_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let last = head;
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
let current = $.derived(() => {
|
||||
return $.get(head) + i;
|
||||
});
|
||||
let current2 = $.derived(() => {
|
||||
return $.get(current) + 1;
|
||||
});
|
||||
$.render_effect(() => {
|
||||
$.get(current2);
|
||||
counter++;
|
||||
});
|
||||
last = current2;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0;
|
||||
for (let i = 0; i < 50; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(last) === i + 50);
|
||||
}
|
||||
assert(counter === 50 * 50);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_broad_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_broad_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_broad_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_broad_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let len = 50;
|
||||
const iter = 50;
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let current = head;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let c = current;
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0;
|
||||
for (let i = 0; i < iter; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(current) === len + i);
|
||||
}
|
||||
assert(counter === iter);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_deep_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_deep_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_deep_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_deep_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,101 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let width = 5;
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let current = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
current.push(
|
||||
$.derived(() => {
|
||||
return $.get(head) + 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return current.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(sum) === 2 * width);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 500; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(sum) === (i + 1) * width);
|
||||
}
|
||||
assert(counter === 500);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_diamond_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_diamond_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_diamond_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_diamond_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
function setup() {
|
||||
let heads = new Array(100).fill(null).map((_) => $.state(0));
|
||||
const mux = $.derived(() => {
|
||||
return Object.fromEntries(heads.map((h) => $.get(h)).entries());
|
||||
});
|
||||
const splited = heads
|
||||
.map((_, index) => $.derived(() => $.get(mux)[index]))
|
||||
.map((x) => $.derived(() => $.get(x) + 1));
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
splited.forEach((x) => {
|
||||
$.render_effect(() => {
|
||||
$.get(x);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush(() => {
|
||||
$.set(heads[i], i);
|
||||
});
|
||||
assert($.get(splited[i]) === i + 1);
|
||||
}
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush(() => {
|
||||
$.set(heads[i], i * 2);
|
||||
});
|
||||
assert($.get(splited[i]) === i * 2 + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_mux_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_mux_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_mux_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_mux_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,98 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let size = 30;
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < size; i++) {
|
||||
result += $.get(head);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(current) === size);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(current) === i * size);
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_repeated_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_repeated_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_repeated_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_repeated_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let width = 10;
|
||||
|
||||
function count(number) {
|
||||
return new Array(number)
|
||||
.fill(0)
|
||||
.map((_, i) => i + 1)
|
||||
.reduce((x, y) => x + y, 0);
|
||||
}
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
let current = head;
|
||||
let list = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
let c = current;
|
||||
list.push(current);
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return list.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
const constant = count(width);
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(sum) === constant);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert($.get(sum) === constant - width + i * width);
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_triangle_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_triangle_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_triangle_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_triangle_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
import { assert, fastest_test } from '../../../utils.js';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
function setup() {
|
||||
let head = $.state(0);
|
||||
const double = $.derived(() => $.get(head) * 2);
|
||||
const inverse = $.derived(() => -$.get(head));
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < 20; i++) {
|
||||
result += $.get(head) % 2 ? $.get(double) : $.get(inverse);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert($.get(current) === 40);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
}
|
||||
assert(counter === 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_unstable_unowned() {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_unstable_unowned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
|
||||
export async function kairo_unstable_owned() {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run();
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const { timing } = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run();
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return {
|
||||
benchmark: 'kairo_unstable_owned',
|
||||
time: timing.time.toFixed(2),
|
||||
gc_time: timing.gc_time.toFixed(2)
|
||||
};
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
export function busy() {
|
||||
let a = 0;
|
||||
for (let i = 0; i < 1_00; i++) {
|
||||
a++;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
import { busy } from '../util.js';
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let computed1 = $.derived(() => $.get(head));
|
||||
let computed2 = $.derived(() => ($.get(computed1), 0));
|
||||
let computed3 = $.derived(() => (busy(), $.get(computed2) + 1)); // heavy computation
|
||||
let computed4 = $.derived(() => $.get(computed3) + 2);
|
||||
let computed5 = $.derived(() => $.get(computed4) + 3);
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(computed5);
|
||||
busy(); // heavy side effect
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert.equal($.get(computed5), 6);
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(computed5), 6);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let last = head;
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
for (let i = 0; i < 50; i++) {
|
||||
let current = $.derived(() => {
|
||||
return $.get(head) + i;
|
||||
});
|
||||
let current2 = $.derived(() => {
|
||||
return $.get(current) + 1;
|
||||
});
|
||||
$.render_effect(() => {
|
||||
$.get(current2);
|
||||
counter++;
|
||||
});
|
||||
last = current2;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0;
|
||||
for (let i = 0; i < 50; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(last), i + 50);
|
||||
}
|
||||
assert.equal(counter, 50 * 50);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let len = 50;
|
||||
const iter = 50;
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let current = head;
|
||||
for (let i = 0; i < len; i++) {
|
||||
let c = current;
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
counter = 0;
|
||||
for (let i = 0; i < iter; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(current), len + i);
|
||||
}
|
||||
assert.equal(counter, iter);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,45 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let width = 5;
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let current = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
current.push(
|
||||
$.derived(() => {
|
||||
return $.get(head) + 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return current.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert.equal($.get(sum), 2 * width);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 500; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(sum), (i + 1) * width);
|
||||
}
|
||||
assert.equal(counter, 500);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,38 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
export default () => {
|
||||
let heads = new Array(100).fill(null).map((_) => $.state(0));
|
||||
const mux = $.derived(() => {
|
||||
return Object.fromEntries(heads.map((h) => $.get(h)).entries());
|
||||
});
|
||||
const splited = heads
|
||||
.map((_, index) => $.derived(() => $.get(mux)[index]))
|
||||
.map((x) => $.derived(() => $.get(x) + 1));
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
splited.forEach((x) => {
|
||||
$.render_effect(() => {
|
||||
$.get(x);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush(() => {
|
||||
$.set(heads[i], i);
|
||||
});
|
||||
assert.equal($.get(splited[i]), i + 1);
|
||||
}
|
||||
for (let i = 0; i < 10; i++) {
|
||||
$.flush(() => {
|
||||
$.set(heads[i], i * 2);
|
||||
});
|
||||
assert.equal($.get(splited[i]), i * 2 + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,42 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let size = 30;
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < size; i++) {
|
||||
result += $.get(head);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert.equal($.get(current), size);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(current), i * size);
|
||||
}
|
||||
assert.equal(counter, 100);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,55 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
let width = 10;
|
||||
|
||||
function count(number) {
|
||||
return new Array(number)
|
||||
.fill(0)
|
||||
.map((_, i) => i + 1)
|
||||
.reduce((x, y) => x + y, 0);
|
||||
}
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
let current = head;
|
||||
let list = [];
|
||||
for (let i = 0; i < width; i++) {
|
||||
let c = current;
|
||||
list.push(current);
|
||||
current = $.derived(() => {
|
||||
return $.get(c) + 1;
|
||||
});
|
||||
}
|
||||
let sum = $.derived(() => {
|
||||
return list.map((x) => $.get(x)).reduce((a, b) => a + b, 0);
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(sum);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
const constant = count(width);
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert.equal($.get(sum), constant);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
assert.equal($.get(sum), constant - width + i * width);
|
||||
}
|
||||
assert.equal(counter, 100);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,41 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
export default () => {
|
||||
let head = $.state(0);
|
||||
const double = $.derived(() => $.get(head) * 2);
|
||||
const inverse = $.derived(() => -$.get(head));
|
||||
let current = $.derived(() => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < 20; i++) {
|
||||
result += $.get(head) % 2 ? $.get(double) : $.get(inverse);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
let counter = 0;
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(current);
|
||||
counter++;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
$.flush(() => {
|
||||
$.set(head, 1);
|
||||
});
|
||||
assert.equal($.get(current), 40);
|
||||
counter = 0;
|
||||
for (let i = 0; i < 100; i++) {
|
||||
$.flush(() => {
|
||||
$.set(head, i);
|
||||
});
|
||||
}
|
||||
assert.equal(counter, 100);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,35 @@
|
||||
import assert from 'node:assert';
|
||||
import * as $ from 'svelte/internal/client';
|
||||
|
||||
const ARRAY_SIZE = 1000;
|
||||
|
||||
export default () => {
|
||||
const signals = Array.from({ length: ARRAY_SIZE }, (_, i) => $.state(i));
|
||||
const order = $.state(0);
|
||||
|
||||
// break skipped_deps fast path by changing order of reads
|
||||
const total = $.derived(() => {
|
||||
const ord = $.get(order);
|
||||
let sum = 0;
|
||||
for (let i = 0; i < ARRAY_SIZE; i++) {
|
||||
sum += /** @type {number} */ ($.get(signals[(i + ord) % ARRAY_SIZE]));
|
||||
}
|
||||
return sum;
|
||||
});
|
||||
|
||||
const destroy = $.effect_root(() => {
|
||||
$.render_effect(() => {
|
||||
$.get(total);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
destroy,
|
||||
run() {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
$.flush(() => $.set(order, i));
|
||||
assert.equal($.get(total), (ARRAY_SIZE * (ARRAY_SIZE - 1)) / 2); // sum of 0..999
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,71 @@
|
||||
import * as $ from 'svelte/internal/client';
|
||||
import { fastest_test } from '../../utils.js';
|
||||
|
||||
export function busy() {
|
||||
let a = 0;
|
||||
for (let i = 0; i < 1_00; i++) {
|
||||
a++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} label
|
||||
* @param {() => { run: (i?: number) => void, destroy: () => void }} setup
|
||||
*/
|
||||
export function create_test(label, setup) {
|
||||
return {
|
||||
unowned: {
|
||||
label: `${label}_unowned`,
|
||||
fn: async () => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run(0);
|
||||
destroy();
|
||||
}
|
||||
|
||||
const { run, destroy } = setup();
|
||||
|
||||
const result = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run(i);
|
||||
}
|
||||
});
|
||||
|
||||
destroy();
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
owned: {
|
||||
label: `${label}_owned`,
|
||||
fn: async () => {
|
||||
let run, destroy;
|
||||
|
||||
const destroy_owned = $.effect_root(() => {
|
||||
// Do 10 loops to warm up JIT
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const { run, destroy } = setup();
|
||||
run(0);
|
||||
destroy();
|
||||
}
|
||||
|
||||
({ run, destroy } = setup());
|
||||
});
|
||||
|
||||
const result = await fastest_test(10, () => {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
run(i);
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
destroy();
|
||||
destroy_owned();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,10 +1,13 @@
|
||||
import { reactivity_benchmarks } from '../benchmarks/reactivity/index.js';
|
||||
|
||||
const results = [];
|
||||
for (const benchmark of reactivity_benchmarks) {
|
||||
const result = await benchmark();
|
||||
console.error(result.benchmark);
|
||||
results.push(result);
|
||||
|
||||
for (let i = 0; i < reactivity_benchmarks.length; i += 1) {
|
||||
const benchmark = reactivity_benchmarks[i];
|
||||
|
||||
process.stderr.write(`Running ${i + 1}/${reactivity_benchmarks.length} ${benchmark.label} `);
|
||||
results.push({ benchmark: benchmark.label, ...(await benchmark.fn()) });
|
||||
process.stderr.write('\x1b[2K\r');
|
||||
}
|
||||
|
||||
process.send(results);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
---
|
||||
title: svelte/attachments
|
||||
tags: attachments
|
||||
---
|
||||
|
||||
> MODULE: svelte/attachments
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
---
|
||||
title: svelte/transition
|
||||
tags: transitions
|
||||
---
|
||||
|
||||
> MODULE: svelte/transition
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue