mirror of https://github.com/sveltejs/svelte
commit
fa4d3730f9
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: correctly compile $effect.root in svelte modules
|
||||
@ -1,74 +0,0 @@
|
||||
export const reserved = [
|
||||
'arguments',
|
||||
'await',
|
||||
'break',
|
||||
'case',
|
||||
'catch',
|
||||
'class',
|
||||
'const',
|
||||
'continue',
|
||||
'debugger',
|
||||
'default',
|
||||
'delete',
|
||||
'do',
|
||||
'else',
|
||||
'enum',
|
||||
'eval',
|
||||
'export',
|
||||
'extends',
|
||||
'false',
|
||||
'finally',
|
||||
'for',
|
||||
'function',
|
||||
'if',
|
||||
'implements',
|
||||
'import',
|
||||
'in',
|
||||
'instanceof',
|
||||
'interface',
|
||||
'let',
|
||||
'new',
|
||||
'null',
|
||||
'package',
|
||||
'private',
|
||||
'protected',
|
||||
'public',
|
||||
'return',
|
||||
'static',
|
||||
'super',
|
||||
'switch',
|
||||
'this',
|
||||
'throw',
|
||||
'true',
|
||||
'try',
|
||||
'typeof',
|
||||
'var',
|
||||
'void',
|
||||
'while',
|
||||
'with',
|
||||
'yield'
|
||||
];
|
||||
|
||||
const void_element_names = [
|
||||
'area',
|
||||
'base',
|
||||
'br',
|
||||
'col',
|
||||
'command',
|
||||
'embed',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'keygen',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr'
|
||||
];
|
||||
|
||||
/** @param {string} name */
|
||||
export function is_void(name) {
|
||||
return void_element_names.includes(name) || name.toLowerCase() === '!doctype';
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
html: '<button>0</button><button>0</button><button>cleanup</button>',
|
||||
|
||||
async test({ assert, target, logs }) {
|
||||
const [b1, b2, b3] = target.querySelectorAll('button');
|
||||
|
||||
flushSync(() => {
|
||||
b1.click();
|
||||
b2.click();
|
||||
});
|
||||
|
||||
assert.deepEqual(logs, [0, 1]);
|
||||
|
||||
flushSync(() => {
|
||||
b3.click();
|
||||
});
|
||||
|
||||
assert.deepEqual(logs, [0, 1, 'cleanup 1', 'cleanup 2']);
|
||||
|
||||
flushSync(() => {
|
||||
b1.click();
|
||||
b2.click();
|
||||
});
|
||||
|
||||
assert.deepEqual(logs, [0, 1, 'cleanup 1', 'cleanup 2']);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,11 @@
|
||||
<script>
|
||||
import { with_root } from './root.svelte.js';
|
||||
let x = $state(0);
|
||||
let y = $state(0);
|
||||
|
||||
const cleanup = with_root(() => x)
|
||||
</script>
|
||||
|
||||
<button onclick={() => x++}>{x}</button>
|
||||
<button onclick={() => y++}>{y}</button>
|
||||
<button onclick={cleanup}>cleanup</button>
|
||||
@ -0,0 +1,20 @@
|
||||
export function with_root(get_x) {
|
||||
const cleanup = $effect.root(() => {
|
||||
$effect(() => {
|
||||
console.log(get_x());
|
||||
});
|
||||
|
||||
const nested_cleanup = $effect.root(() => {
|
||||
return () => {
|
||||
console.log('cleanup 2');
|
||||
};
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log('cleanup 1');
|
||||
nested_cleanup();
|
||||
};
|
||||
});
|
||||
|
||||
return cleanup;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
// Ensure we don't use any methods that are not available in all browser for a long period of time
|
||||
// so that people don't need to polyfill them. Example array.at(...) was introduced to Safari only in 2022
|
||||
"target": "es2021",
|
||||
"lib": ["es2021", "DOM", "DOM.Iterable"],
|
||||
"types": [] // prevent automatic inclusion of @types/node
|
||||
},
|
||||
"include": ["./src/"],
|
||||
// Compiler is allowed to use more recent methods; people using it in the browser are expected to know
|
||||
// how to polyfill missing methods. Also make sure to not include test files as these include Vitest
|
||||
// which then loads node globals.
|
||||
"exclude": ["./src/compiler/**/*", "./src/**/*.test.ts"]
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
import { mount, hydrate, unmount } from 'svelte';
|
||||
import App from './src/main.svelte';
|
||||
|
||||
const root = document.getElementById('root')!;
|
||||
const render = root.firstChild?.nextSibling ? hydrate : mount;
|
||||
|
||||
const component = render(App, {
|
||||
target: document.getElementById('root')!,
|
||||
recover: false
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
window.unmount = () => unmount(component);
|
||||
@ -1,64 +0,0 @@
|
||||
// @ts-check
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import polka from 'polka';
|
||||
import { createServer as createViteServer } from 'vite';
|
||||
|
||||
const PORT = process.env.PORT || '5173';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
async function createServer() {
|
||||
const app = polka();
|
||||
|
||||
const vite = await createViteServer({
|
||||
server: { middlewareMode: true },
|
||||
appType: 'custom'
|
||||
});
|
||||
|
||||
app.use(vite.middlewares);
|
||||
|
||||
app.use('*', async (req, res) => {
|
||||
if (req.originalUrl !== '/') {
|
||||
const file = path.resolve('./dist' + req.originalUrl);
|
||||
if (fs.existsSync(file)) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/javascript'
|
||||
});
|
||||
res.end(fs.createReadStream(file));
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end('not found');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');
|
||||
const transformed_template = await vite.transformIndexHtml(req.originalUrl, template);
|
||||
const { render } = await vite.ssrLoadModule('svelte/server');
|
||||
const { default: App } = await vite.ssrLoadModule('./src/main.svelte');
|
||||
const { head, body } = render(App);
|
||||
|
||||
const html = transformed_template
|
||||
.replace(`<!--ssr-head-->`, head)
|
||||
.replace(`<!--ssr-body-->`, body);
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' }).end(html);
|
||||
});
|
||||
|
||||
return { app, vite };
|
||||
}
|
||||
|
||||
createServer()
|
||||
.then(({ app }) =>
|
||||
app.listen(PORT, () => {
|
||||
console.log(`http://localhost:${PORT}`);
|
||||
})
|
||||
)
|
||||
.catch((err) => {
|
||||
console.error('Error Starting Server:\n', err);
|
||||
process.exit(1);
|
||||
});
|
||||
@ -1,22 +0,0 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import express from 'express';
|
||||
import { head, body } from './server/entry-server.js';
|
||||
|
||||
const rendered = fs
|
||||
.readFileSync(path.resolve('./dist/client/index.html'), 'utf-8')
|
||||
.replace(`<!--ssr-html-->`, body)
|
||||
.replace(`<!--ssr-head-->`, head);
|
||||
|
||||
express()
|
||||
.use('*', async (req, res) => {
|
||||
if (req.originalUrl !== '/') {
|
||||
res.sendFile(path.resolve('./dist/client' + req.originalUrl));
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).set({ 'Content-Type': 'text/html' }).end(rendered);
|
||||
})
|
||||
.listen('3000');
|
||||
|
||||
console.log('listening on http://localhost:3000');
|
||||
@ -0,0 +1,36 @@
|
||||
// @ts-check
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import polka from 'polka';
|
||||
import { createServer as createViteServer } from 'vite';
|
||||
import { render } from 'svelte/server';
|
||||
|
||||
const PORT = process.env.PORT || '5173';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
const vite = await createViteServer({
|
||||
server: { middlewareMode: true },
|
||||
appType: 'custom'
|
||||
});
|
||||
|
||||
polka()
|
||||
.use(vite.middlewares)
|
||||
.use(async (req, res) => {
|
||||
const template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');
|
||||
const transformed_template = await vite.transformIndexHtml(req.url, template);
|
||||
const { default: App } = await vite.ssrLoadModule('./src/main.svelte');
|
||||
const { head, body } = render(App);
|
||||
|
||||
const html = transformed_template
|
||||
.replace(`<!--ssr-head-->`, head)
|
||||
.replace(`<!--ssr-body-->`, body);
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' }).end(html);
|
||||
})
|
||||
.listen(PORT, () => {
|
||||
console.log(`http://localhost:${PORT}`);
|
||||
});
|
||||
@ -0,0 +1,41 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import polka from 'polka';
|
||||
import { render } from 'svelte/server';
|
||||
import App from './src/main.svelte';
|
||||
|
||||
const { head, body } = render(App);
|
||||
|
||||
const rendered = fs
|
||||
.readFileSync(path.resolve('./dist/client/index.html'), 'utf-8')
|
||||
.replace(`<!--ssr-body-->`, body)
|
||||
.replace(`<!--ssr-head-->`, head);
|
||||
|
||||
const types = {
|
||||
'.js': 'application/javascript',
|
||||
'.css': 'text/css'
|
||||
};
|
||||
|
||||
polka()
|
||||
.use((req, res) => {
|
||||
if (req.url === '/') {
|
||||
res.writeHead(200, { 'content-type': 'text/html' });
|
||||
res.end(rendered);
|
||||
return;
|
||||
}
|
||||
|
||||
const file = path.resolve('./dist/client' + req.url);
|
||||
|
||||
if (fs.existsSync(file)) {
|
||||
const type = types[path.extname(req.url)] ?? 'application/octet-stream';
|
||||
res.writeHead(200, { 'content-type': type });
|
||||
fs.createReadStream(file).pipe(res);
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(404);
|
||||
res.end('not found');
|
||||
})
|
||||
.listen('3000');
|
||||
|
||||
console.log('listening on http://localhost:3000');
|
||||
Loading…
Reference in new issue