mirror of https://github.com/sveltejs/svelte
parent
fbd1d0a3b9
commit
ad9a672171
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: export ComponentType from `svelte` entrypoint
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: derived store types
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Generate type declarations with dts-buddy
|
@ -1,5 +1,6 @@
|
|||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode
|
.vscode/*
|
||||||
|
!.vscode/launch.json
|
||||||
node_modules
|
node_modules
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Playground: Browser",
|
||||||
|
"url": "http://localhost:10001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"runtimeArgs": ["--watch"],
|
||||||
|
"name": "Playground: Server",
|
||||||
|
"outputCapture": "std",
|
||||||
|
"program": "start.js",
|
||||||
|
"cwd": "${workspaceFolder}/packages/playground",
|
||||||
|
"cascadeTerminateToConfigurations": ["Playground: Browser"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"compounds": [
|
||||||
|
{
|
||||||
|
"name": "Playground: Full",
|
||||||
|
"configurations": ["Playground: Server", "Playground: Browser"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
@ -0,0 +1,7 @@
|
|||||||
|
You may use this package to experiment with your changes to Svelte.
|
||||||
|
|
||||||
|
To prevent any changes you make in this directory from being accidentally committed, run `git update-index --skip-worktree ./**/*.*` in this directory.
|
||||||
|
|
||||||
|
If you would actually like to make some changes to the files here for everyone then run `git update-index --no-skip-worktree ./**/*.*` before committing.
|
||||||
|
|
||||||
|
If you're using VS Code, you can use the "Playground: Full" launch configuration to run the playground and attach the debugger to both the compiler and the browser.
|
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
/**
|
||||||
|
* svelte-preprocess cannot figure out whether you have
|
||||||
|
* a value or a type, so tell TypeScript to enforce using
|
||||||
|
* `import type` instead of `import` for Types.
|
||||||
|
*/
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
/**
|
||||||
|
* To have warnings / errors of the Svelte compiler at the
|
||||||
|
* correct position, enable source maps by default.
|
||||||
|
*/
|
||||||
|
"sourceMap": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
/**
|
||||||
|
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||||
|
* Disable this if you'd like to use dynamic types.
|
||||||
|
*/
|
||||||
|
"checkJs": true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Use global.d.ts instead of compilerOptions.types
|
||||||
|
* to avoid limiting type declarations.
|
||||||
|
*/
|
||||||
|
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "playground",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node --watch start.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"rollup": "^3.20.2",
|
||||||
|
"rollup-plugin-serve": "^2.0.2",
|
||||||
|
"svelte": "workspace:*"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
Hello world!
|
||||||
|
</div>
|
@ -0,0 +1,24 @@
|
|||||||
|
import App from './App.svelte';
|
||||||
|
|
||||||
|
new App({
|
||||||
|
target: document.getElementById('app'),
|
||||||
|
hydrate: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function get_version() {
|
||||||
|
return fetch('/version.json').then((r) => r.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
let prev = await get_version();
|
||||||
|
|
||||||
|
// Mom: We have live reloading at home
|
||||||
|
// Live reloading at home:
|
||||||
|
while (true) {
|
||||||
|
await new Promise((r) => setTimeout(r, 2500));
|
||||||
|
try {
|
||||||
|
const version = await get_version();
|
||||||
|
if (prev !== version) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import App from './App.svelte';
|
||||||
|
|
||||||
|
export function render() {
|
||||||
|
// @ts-ignore
|
||||||
|
return App.render();
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<script>
|
||||||
|
let count = 0
|
||||||
|
const increment = () => {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={increment}>
|
||||||
|
count is {count}
|
||||||
|
</button>
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title><!--app-title--></title>
|
||||||
|
<!--app-head-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/entry-client.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,100 @@
|
|||||||
|
import { readFileSync, writeFileSync } from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { watch } from 'rollup';
|
||||||
|
import serve from 'rollup-plugin-serve';
|
||||||
|
import * as svelte from '../svelte/src/compiler/index.js';
|
||||||
|
|
||||||
|
const __dirname = new URL('.', import.meta.url).pathname;
|
||||||
|
|
||||||
|
/** @returns {import('rollup').Plugin}*/
|
||||||
|
function create_plugin(ssr = false) {
|
||||||
|
return {
|
||||||
|
name: 'custom-svelte-ssr-' + ssr,
|
||||||
|
resolveId(id) {
|
||||||
|
if (id === 'svelte') {
|
||||||
|
return path.resolve(
|
||||||
|
__dirname,
|
||||||
|
ssr ? '../svelte/src/runtime/ssr.js' : '../svelte/src/runtime/index.js'
|
||||||
|
);
|
||||||
|
} else if (id.startsWith('svelte/')) {
|
||||||
|
return path.resolve(__dirname, `../svelte/src/runtime/${id.slice(7)}/index.js`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transform(code, id) {
|
||||||
|
code = code.replaceAll('import.meta.env.SSR', ssr);
|
||||||
|
|
||||||
|
if (!id.endsWith('.svelte')) {
|
||||||
|
return {
|
||||||
|
code,
|
||||||
|
map: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const compiled = svelte.compile(code, {
|
||||||
|
filename: id,
|
||||||
|
generate: ssr ? 'ssr' : 'dom',
|
||||||
|
hydratable: true,
|
||||||
|
css: 'injected'
|
||||||
|
});
|
||||||
|
|
||||||
|
return compiled.js;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const client_plugin = create_plugin();
|
||||||
|
const ssr_plugin = create_plugin(true);
|
||||||
|
|
||||||
|
const watcher = watch([
|
||||||
|
{
|
||||||
|
input: 'src/entry-client.js',
|
||||||
|
output: {
|
||||||
|
dir: 'dist',
|
||||||
|
format: 'esm',
|
||||||
|
sourcemap: true
|
||||||
|
},
|
||||||
|
plugins: [client_plugin, serve('dist')]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 'src/entry-server.js',
|
||||||
|
output: {
|
||||||
|
dir: 'dist-ssr',
|
||||||
|
format: 'iife',
|
||||||
|
indent: false
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
ssr_plugin,
|
||||||
|
{
|
||||||
|
async generateBundle(_, bundle) {
|
||||||
|
const result = bundle['entry-server.js'];
|
||||||
|
const mod = (0, eval)(result.code);
|
||||||
|
const { html } = mod.render();
|
||||||
|
|
||||||
|
writeFileSync(
|
||||||
|
'dist/index.html',
|
||||||
|
readFileSync('src/template.html', 'utf-8')
|
||||||
|
.replace('<!--app-html-->', html)
|
||||||
|
.replace('<!--app-title-->', svelte.VERSION)
|
||||||
|
);
|
||||||
|
writeFileSync('dist/version.json', Date.now().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
onwarn(warning, handler) {
|
||||||
|
if (warning.code === 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT') return;
|
||||||
|
handler(warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
watcher
|
||||||
|
.on('change', (id) => {
|
||||||
|
console.log(`changed ${id}`);
|
||||||
|
})
|
||||||
|
.on('event', (event) => {
|
||||||
|
if (event.code === 'ERROR') {
|
||||||
|
console.error(event.error);
|
||||||
|
} else if (event.code === 'BUNDLE_END') {
|
||||||
|
console.log(`Generated ${event.output} in ${event.duration}ms`);
|
||||||
|
}
|
||||||
|
});
|
@ -1,162 +0,0 @@
|
|||||||
// This script generates the TypeScript definitions
|
|
||||||
|
|
||||||
import { execSync } from 'child_process';
|
|
||||||
import { readFileSync, writeFileSync, readdirSync, existsSync, copyFileSync, statSync } from 'fs';
|
|
||||||
|
|
||||||
execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly', { stdio: 'inherit' });
|
|
||||||
|
|
||||||
function modify(path, modifyFn) {
|
|
||||||
const content = readFileSync(path, 'utf8');
|
|
||||||
writeFileSync(path, modifyFn(content));
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjust(input) {
|
|
||||||
// Remove typedef jsdoc (duplicated in the type definition)
|
|
||||||
input = input.replace(/\/\*\*\n(\r)? \* @typedef .+?\*\//gs, '');
|
|
||||||
input = input.replace(/\/\*\* @typedef .+?\*\//gs, '');
|
|
||||||
|
|
||||||
// Extract the import paths and types
|
|
||||||
const import_regex = /import\(("|')(.+?)("|')\)\.(\w+)/g;
|
|
||||||
let import_match;
|
|
||||||
const import_map = new Map();
|
|
||||||
|
|
||||||
while ((import_match = import_regex.exec(input)) !== null) {
|
|
||||||
const imports = import_map.get(import_match[2]) || new Map();
|
|
||||||
let name = import_match[4];
|
|
||||||
if ([...imports.keys()].includes(name)) continue;
|
|
||||||
|
|
||||||
let i = 1;
|
|
||||||
if (name === 'default') {
|
|
||||||
name = import_match[2].split('/').pop().split('.').shift().replace(/[^a-z0-9]/gi, '_');
|
|
||||||
}
|
|
||||||
while ([...import_map].some(([path, names]) => path !== import_match[2] && names.has(name))) {
|
|
||||||
name = `${name}${i++}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
imports.set(import_match[4], name);
|
|
||||||
import_map.set(import_match[2], imports);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace inline imports with their type names
|
|
||||||
const transformed = input.replace(import_regex, (_match, _quote, path, _quote2, name) => {
|
|
||||||
return import_map.get(path).get(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove/adjust @template, @param and @returns lines
|
|
||||||
// TODO rethink if we really need to do this for @param and @returns, doesn't show up in hover so unnecessary
|
|
||||||
const lines = transformed.split("\n");
|
|
||||||
|
|
||||||
let filtered_lines = [];
|
|
||||||
let removing = null;
|
|
||||||
let openCount = 1;
|
|
||||||
let closedCount = 0;
|
|
||||||
|
|
||||||
for (let line of lines) {
|
|
||||||
let start_removing = false;
|
|
||||||
if (line.trim().startsWith("* @template")) {
|
|
||||||
removing = "template";
|
|
||||||
start_removing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.trim().startsWith("* @param {")) {
|
|
||||||
openCount = 1;
|
|
||||||
closedCount = 0;
|
|
||||||
removing = "param";
|
|
||||||
start_removing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.trim().startsWith("* @returns {")) {
|
|
||||||
openCount = 1;
|
|
||||||
closedCount = 0;
|
|
||||||
removing = "returns";
|
|
||||||
start_removing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removing === "returns" || removing === "param") {
|
|
||||||
let i = start_removing ? line.indexOf('{') + 1 : 0;
|
|
||||||
for (; i < line.length; i++) {
|
|
||||||
if (line[i] === "{") openCount++;
|
|
||||||
if (line[i] === "}") closedCount++;
|
|
||||||
if (openCount === closedCount) break;
|
|
||||||
}
|
|
||||||
if (openCount === closedCount) {
|
|
||||||
line = start_removing ? (line.slice(0, line.indexOf('{')) + line.slice(i + 1)) : (` * @${removing} ` + line.slice(i + 1));
|
|
||||||
removing = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removing && !start_removing && (line.trim().startsWith("* @") || line.trim().startsWith("*/"))) {
|
|
||||||
removing = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!removing) {
|
|
||||||
filtered_lines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace generic type names with their plain versions
|
|
||||||
const renamed_generics = filtered_lines.map(line => {
|
|
||||||
return line.replace(/(\W|\s)([A-Z][\w\d$]*)_\d+(\W|\s)/g, "$1$2$3");
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generate the import statement for the types used
|
|
||||||
const import_statements = Array.from(import_map.entries())
|
|
||||||
.map(([path, names]) => {
|
|
||||||
const default_name = names.get('default');
|
|
||||||
names.delete('default');
|
|
||||||
const default_import = default_name ? (default_name + (names.size ? ', ' : ' ')) : '';
|
|
||||||
const named_imports = names.size ? `{ ${[...names.values()].join(', ')} } ` : '';
|
|
||||||
return `import ${default_import}${named_imports}from '${path}';`
|
|
||||||
})
|
|
||||||
.join("\n");
|
|
||||||
|
|
||||||
return [import_statements, ...renamed_generics].join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
let did_replace = false;
|
|
||||||
|
|
||||||
function walk(dir) {
|
|
||||||
const files = readdirSync(dir);
|
|
||||||
const _dir = dir.slice('types/'.length)
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const path = `${dir}/${file}`;
|
|
||||||
if (file.endsWith('.d.ts')) {
|
|
||||||
modify(path, content => {
|
|
||||||
content = adjust(content);
|
|
||||||
|
|
||||||
if (file === 'index.d.ts' && existsSync(`src/${_dir}/public.d.ts`)) {
|
|
||||||
copyFileSync(`src/${_dir}/public.d.ts`, `${dir}/public.d.ts`);
|
|
||||||
content = "export * from './public.js';\n" + content;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file === 'Component.d.ts' && dir.includes('runtime')) {
|
|
||||||
if (!content.includes('$set(props: Partial<Props>): void;\n}')) {
|
|
||||||
throw new Error('Component.js was modified in a way that automatic patching of d.ts file no longer works. Please adjust it');
|
|
||||||
} else {
|
|
||||||
content = content.replace('$set(props: Partial<Props>): void;\n}', '$set(props: Partial<Props>): void;\n [accessor:string]: any;\n}');
|
|
||||||
did_replace = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
});
|
|
||||||
} else if (statSync(path).isDirectory()) {
|
|
||||||
if (existsSync(`src/${_dir}/${file}/private.d.ts`)) {
|
|
||||||
copyFileSync(`src/${_dir}/${file}/private.d.ts`, `${path}/private.d.ts`);
|
|
||||||
}
|
|
||||||
if (existsSync(`src/${_dir}/${file}/interfaces.d.ts`)) {
|
|
||||||
copyFileSync(`src/${_dir}/${file}/interfaces.d.ts`, `${path}/interfaces.d.ts`);
|
|
||||||
}
|
|
||||||
walk(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
walk('types');
|
|
||||||
|
|
||||||
if (!did_replace) {
|
|
||||||
throw new Error('Component.js file in runtime does no longer exist so that automatic patching of the d.ts file no longer works. Please adjust it');
|
|
||||||
}
|
|
||||||
|
|
||||||
copyFileSync(`src/runtime/ambient.d.ts`, `types/runtime/ambient.d.ts`);
|
|
@ -0,0 +1,16 @@
|
|||||||
|
import { createBundle } from 'dts-buddy';
|
||||||
|
|
||||||
|
await createBundle({
|
||||||
|
output: 'types/index.d.ts',
|
||||||
|
modules: {
|
||||||
|
svelte: 'src/runtime/public.d.ts',
|
||||||
|
'svelte/compiler': 'src/compiler/public.d.ts',
|
||||||
|
'svelte/types/compiler/preprocess': 'src/compiler/preprocess/public.d.ts',
|
||||||
|
'svelte/action': 'src/runtime/action/public.d.ts',
|
||||||
|
'svelte/animate': 'src/runtime/animate/public.d.ts',
|
||||||
|
'svelte/easing': 'src/runtime/easing/index.js',
|
||||||
|
'svelte/motion': 'src/runtime/motion/public.d.ts',
|
||||||
|
'svelte/store': 'src/runtime/store/public.d.ts',
|
||||||
|
'svelte/transition': 'src/runtime/transition/public.d.ts'
|
||||||
|
}
|
||||||
|
});
|
@ -1,2 +1,3 @@
|
|||||||
export { CompileOptions, EnableSourcemap, CssHashGetter } from './interfaces';
|
export { CompileOptions, EnableSourcemap, CssHashGetter } from './interfaces';
|
||||||
export * from './preprocess/public.js';
|
export * from './preprocess/public.js';
|
||||||
|
export * from './index.js';
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export {};
|
|
@ -1,4 +1,4 @@
|
|||||||
// generated during release, do not modify
|
// generated during release, do not modify
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export const VERSION = '4.0.0-next.0';
|
export const VERSION = '4.0.0-next.1';
|
||||||
|
Loading…
Reference in new issue