diff --git a/.changeset/purple-impalas-deliver.md b/.changeset/purple-impalas-deliver.md
new file mode 100644
index 000000000000..cf2a650a5a56
--- /dev/null
+++ b/.changeset/purple-impalas-deliver.md
@@ -0,0 +1,6 @@
+---
+'@sveltejs/kit': patch
+'@sveltejs/snowpack-config': patch
+---
+
+Move kit runtime code, expose via \$app aliases
diff --git a/packages/kit/.gitignore b/packages/kit/.gitignore
index fc683b4725d6..b8137f2ebe2c 100644
--- a/packages/kit/.gitignore
+++ b/packages/kit/.gitignore
@@ -1,5 +1,5 @@
.DS_Store
/node_modules
/dist
-/assets/client.*
+/assets/runtime
/client/**/*.d.ts
diff --git a/packages/kit/assets/setup.js b/packages/kit/assets/setup.js
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/packages/kit/dummy/manifest.ts b/packages/kit/dummy/manifest.ts
deleted file mode 100644
index 6982d3aa8663..000000000000
--- a/packages/kit/dummy/manifest.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const ErrorComponent = {};
-
-export const components = [];
-
-export const routes = [];
\ No newline at end of file
diff --git a/packages/kit/dummy/root.ts b/packages/kit/dummy/root.ts
deleted file mode 100644
index afc2e1000dac..000000000000
--- a/packages/kit/dummy/root.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export function preload(_page: any, _session: any) {
-
-}
-
-export default class root {
- constructor(_opts: any) {
-
- }
-
- $set(_data: any) {
-
- }
-}
\ No newline at end of file
diff --git a/packages/kit/rollup.config.js b/packages/kit/rollup.config.js
index b75f870fc11d..d1eb435aa047 100644
--- a/packages/kit/rollup.config.js
+++ b/packages/kit/rollup.config.js
@@ -12,17 +12,21 @@ const external = [].concat(
export default [
{
- input: 'src/client/index.ts',
+ input: {
+ navigation: 'src/runtime/navigation/index.ts',
+ stores: 'src/runtime/stores/index.ts'
+ },
output: {
- file: 'assets/client.js',
+ dir: 'assets/runtime',
format: 'esm',
sourcemap: true,
paths: {
- ROOT: './root.svelte',
- MANIFEST: './manifest.js'
+ ROOT: '../generated/root.svelte',
+ MANIFEST: '../generated/manifest.js'
}
},
external: [
+ 'svelte',
'svelte/store',
'ROOT',
'MANIFEST'
diff --git a/packages/kit/src/api/build/index.ts b/packages/kit/src/api/build/index.ts
index 6338ced6d603..d330bcaaa977 100644
--- a/packages/kit/src/api/build/index.ts
+++ b/packages/kit/src/api/build/index.ts
@@ -4,7 +4,7 @@ import child_process from 'child_process';
import { promisify } from 'util';
import colors from 'kleur';
import relative from 'require-relative';
-import { mkdirp } from '@sveltejs/app-utils';
+import { mkdirp } from '@sveltejs/app-utils/files';
import create_manifest_data from '../../core/create_manifest_data';
import {
rollup,
@@ -28,7 +28,7 @@ const ignorable_warnings = new Set(['EMPTY_BUNDLE', 'CIRCULAR_DEPENDENCY']);
const onwarn = (warning, handler) => {
// TODO would be nice to just eliminate the circular dependencies instead of
// squelching these warnings (it happens when e.g. the root layout imports
- // from /_app/main/client)
+ // from /_app/main/runtime/navigation)
if (ignorable_warnings.has(warning.code)) return;
handler(warning);
};
@@ -64,6 +64,12 @@ export async function build(config: SvelteAppConfig) {
copy_assets();
+ const setup_file = `${unoptimized}/server/_app/setup/index.js`;
+ if (!fs.existsSync(setup_file)) {
+ mkdirp(path.dirname(setup_file));
+ fs.writeFileSync(setup_file, '');
+ }
+
await exec(`${snowpack_bin} build --out=${unoptimized}/server --ssr`);
log.success('server');
await exec(`${snowpack_bin} build --out=${unoptimized}/client`);
@@ -76,11 +82,8 @@ export async function build(config: SvelteAppConfig) {
await exec(`rm -rf .svelte/build/optimized`);
const server_input = {
- root: `${unoptimized}/server/_app/main/root.js`,
- setup: fs.existsSync(`${unoptimized}/server/_app/setup/index.js`)
- ? `${unoptimized}/server/_app/setup/index.js`
- : path.join(__dirname, '../assets/setup.js'),
- // TODO session middleware etc
+ root: `${unoptimized}/server/_app/main/generated/root.js`,
+ setup: `${unoptimized}/server/_app/setup/index.js`
};
[
@@ -91,9 +94,21 @@ export async function build(config: SvelteAppConfig) {
server_input[`routes/${item.name}`] = `${unoptimized}/server${item.url.replace(/\.\w+$/, '.js')}`;
});
+ // https://github.com/snowpackjs/snowpack/discussions/1395
+ const re = /(\.\.\/)+_app\/main\/runtime\//;
+ const work_around_alias_bug = type => ({
+ name: 'work-around-alias-bug',
+ resolveId(imported) {
+ if (re.test(imported)) {
+ return path.resolve(`${unoptimized}/${type}/_app/main/runtime`, imported.replace(re, ''));
+ }
+ }
+ });
+
const server_chunks = await rollup({
input: server_input,
plugins: [
+ work_around_alias_bug('server'),
{
name: 'remove-css',
load(id) {
@@ -123,13 +138,14 @@ export async function build(config: SvelteAppConfig) {
log.success(`server`);
- const entry = path.resolve(`${unoptimized}/client/_app/main/client.js`);
+ const entry = path.resolve(`${unoptimized}/client/_app/main/runtime/navigation.js`);
const client_chunks = await rollup({
input: {
entry
},
plugins: [
+ work_around_alias_bug('client'),
{
name: 'deproxy-css',
async resolveId(importee, importer) {
@@ -189,18 +205,18 @@ export async function build(config: SvelteAppConfig) {
const chunk = bundle[key];
- if (!(chunk as OutputChunk).imports) {
- console.log(chunk);
- }
+ const imports = chunk && (chunk as OutputChunk).imports;
- (chunk as OutputChunk).imports.forEach(key => {
- if (key.endsWith('.css')) {
- js.add(inject_styles);
- css.add(key);
- } else {
- find_deps(key, js, css);
- }
- });
+ if (imports) {
+ imports.forEach(key => {
+ if (key.endsWith('.css')) {
+ js.add(inject_styles);
+ css.add(key);
+ } else {
+ find_deps(key, js, css);
+ }
+ });
+ }
return { js, css };
};
diff --git a/packages/kit/src/api/dev/index.ts b/packages/kit/src/api/dev/index.ts
index 18b4b5773686..ff0a2787610c 100644
--- a/packages/kit/src/api/dev/index.ts
+++ b/packages/kit/src/api/dev/index.ts
@@ -141,7 +141,7 @@ class Watcher extends EventEmitter {
let root;
try {
- root = await load(`/_app/main/root.js`);
+ root = await load(`/_app/main/generated/root.js`);
}
catch (e) {
res.statusCode = 500;
@@ -163,7 +163,7 @@ class Watcher extends EventEmitter {
template,
manifest: this.manifest,
client: {
- entry: 'main/client.js',
+ entry: 'main/runtime/navigation.js',
deps: {}
},
files: 'build',
diff --git a/packages/kit/src/api/utils.ts b/packages/kit/src/api/utils.ts
index bd0053932b23..104f97c467a5 100644
--- a/packages/kit/src/api/utils.ts
+++ b/packages/kit/src/api/utils.ts
@@ -1,11 +1,6 @@
-import { copyFileSync } from 'fs';
import { resolve } from 'path';
-import { mkdirp } from '@sveltejs/app-utils/files';
+import { copy } from '@sveltejs/app-utils/files';
export function copy_assets() {
- mkdirp('.svelte/main/components');
-
- ['client.js', 'components/layout.svelte', 'components/error.svelte'].forEach(file => {
- copyFileSync(resolve(__dirname, `../assets/${file}`), `.svelte/main/${file}`)
- });
+ copy(resolve(__dirname, `../assets`), '.svelte/main');
}
\ No newline at end of file
diff --git a/packages/kit/src/client/index.ts b/packages/kit/src/client/index.ts
deleted file mode 100644
index e7ee6809ca32..000000000000
--- a/packages/kit/src/client/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { getContext } from 'svelte';
-
-export const stores = () => getContext('__svelte__');
-
-export { default as start } from './app';
-export { default as goto } from './goto/index';
-export { default as prefetch } from './prefetch/index';
-export { default as prefetchRoutes } from './prefetchRoutes/index';
diff --git a/packages/kit/src/client/router/find_anchor.ts b/packages/kit/src/client/router/find_anchor.ts
deleted file mode 100644
index 95afc87cb3e1..000000000000
--- a/packages/kit/src/client/router/find_anchor.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export default function find_anchor(node: Node) {
- while (node && node.nodeName.toUpperCase() !== 'A') node = node.parentNode; // SVG elements have a lowercase name
- return node;
-}
diff --git a/packages/kit/src/core/create_app.ts b/packages/kit/src/core/create_app.ts
index 35f5194d6e1a..3fd04da91b44 100644
--- a/packages/kit/src/core/create_app.ts
+++ b/packages/kit/src/core/create_app.ts
@@ -16,8 +16,8 @@ export function create_app({
const app = generate_app(manifest_data);
- write_if_changed(`${output}/manifest.js`, client_manifest);
- write_if_changed(`${output}/root.svelte`, app);
+ write_if_changed(`${output}/generated/manifest.js`, client_manifest);
+ write_if_changed(`${output}/generated/root.svelte`, app);
}
export function create_serviceworker_manifest({ manifest_data, output, client_files, static_files }: {
diff --git a/packages/kit/src/client/goto/index.ts b/packages/kit/src/runtime/navigation/goto/index.ts
similarity index 79%
rename from packages/kit/src/client/goto/index.ts
rename to packages/kit/src/runtime/navigation/goto/index.ts
index ccbda1139851..87c120b10077 100644
--- a/packages/kit/src/client/goto/index.ts
+++ b/packages/kit/src/runtime/navigation/goto/index.ts
@@ -1,5 +1,5 @@
-import { cid, history, navigate, select_target } from '../router';
-import { get_base_uri } from '../baseuri_helper';
+import { cid, history, navigate, select_target } from '../internal';
+import { get_base_uri } from '../utils';
export default function goto(
href: string,
diff --git a/packages/kit/src/runtime/navigation/index.ts b/packages/kit/src/runtime/navigation/index.ts
new file mode 100644
index 000000000000..be98c38176e2
--- /dev/null
+++ b/packages/kit/src/runtime/navigation/index.ts
@@ -0,0 +1,4 @@
+export { default as goto } from './goto';
+export { default as prefetch } from './prefetch';
+export { default as prefetchRoutes } from './prefetchRoutes';
+export { default as start } from './start';
\ No newline at end of file
diff --git a/packages/kit/src/client/router/index.ts b/packages/kit/src/runtime/navigation/internal.ts
similarity index 98%
rename from packages/kit/src/client/router/index.ts
rename to packages/kit/src/runtime/navigation/internal.ts
index dd41d7bd1937..2720490f1ce2 100644
--- a/packages/kit/src/client/router/index.ts
+++ b/packages/kit/src/runtime/navigation/internal.ts
@@ -1,5 +1,5 @@
-import { ScrollPosition, Target } from '../types';
-import find_anchor from './find_anchor';
+import { ScrollPosition, Target } from './types';
+import { find_anchor } from './utils';
import { routes } from 'MANIFEST';
// TODO
diff --git a/packages/kit/src/client/prefetch/index.ts b/packages/kit/src/runtime/navigation/prefetch/index.ts
similarity index 86%
rename from packages/kit/src/client/prefetch/index.ts
rename to packages/kit/src/runtime/navigation/prefetch/index.ts
index 4b8f43672098..543f37b6c829 100644
--- a/packages/kit/src/client/prefetch/index.ts
+++ b/packages/kit/src/runtime/navigation/prefetch/index.ts
@@ -1,8 +1,7 @@
-import { hydrate_target } from '../app';
-import { select_target } from '../router';
-import find_anchor from '../router/find_anchor';
+import { hydrate_target } from '../start'; // TODO does this belong here?
+import { select_target } from '../internal';
+import { find_anchor, get_base_uri } from '../utils';
import { HydratedTarget, Target } from '../types';
-import { get_base_uri } from '../baseuri_helper';
let prefetching: {
href: string;
diff --git a/packages/kit/src/client/prefetchRoutes/index.ts b/packages/kit/src/runtime/navigation/prefetchRoutes/index.ts
similarity index 100%
rename from packages/kit/src/client/prefetchRoutes/index.ts
rename to packages/kit/src/runtime/navigation/prefetchRoutes/index.ts
diff --git a/packages/kit/src/client/app.ts b/packages/kit/src/runtime/navigation/start/index.ts
similarity index 96%
rename from packages/kit/src/client/app.ts
rename to packages/kit/src/runtime/navigation/start/index.ts
index d9448041ca89..00e63ee0a387 100644
--- a/packages/kit/src/client/app.ts
+++ b/packages/kit/src/runtime/navigation/start/index.ts
@@ -1,9 +1,9 @@
import { writable } from 'svelte/store';
-import { extract_query, init as init_router, load_current_page, select_target } from './router';
-import { get_prefetched, start as start_prefetching } from './prefetch';
-import { HydratedTarget, Target, Redirect, Branch, Page, InitialData } from './types';
-import goto from './goto';
-import { page_store } from './stores';
+import { extract_query, init as init_router, load_current_page, select_target } from '../internal';
+import { get_prefetched, start as start_prefetching } from '../prefetch';
+import { HydratedTarget, Target, Redirect, Branch, Page, InitialData } from '../types';
+import goto from '../goto';
+import { page_store } from './page_store';
import { ErrorComponent, components } from 'MANIFEST';
import root from 'ROOT';
diff --git a/packages/kit/src/client/stores/index.ts b/packages/kit/src/runtime/navigation/start/page_store.ts
similarity index 100%
rename from packages/kit/src/client/stores/index.ts
rename to packages/kit/src/runtime/navigation/start/page_store.ts
diff --git a/packages/kit/src/client/types.ts b/packages/kit/src/runtime/navigation/types.ts
similarity index 100%
rename from packages/kit/src/client/types.ts
rename to packages/kit/src/runtime/navigation/types.ts
diff --git a/packages/kit/src/client/baseuri_helper.ts b/packages/kit/src/runtime/navigation/utils.ts
similarity index 59%
rename from packages/kit/src/client/baseuri_helper.ts
rename to packages/kit/src/runtime/navigation/utils.ts
index 03cfc436fa26..2fcf5574e725 100644
--- a/packages/kit/src/client/baseuri_helper.ts
+++ b/packages/kit/src/runtime/navigation/utils.ts
@@ -8,3 +8,8 @@ export function get_base_uri(window_document) {
return baseURI;
}
+
+export function find_anchor(node: Node) {
+ while (node && node.nodeName.toUpperCase() !== 'A') node = node.parentNode; // SVG elements have a lowercase name
+ return node;
+}
diff --git a/packages/kit/src/runtime/stores/index.ts b/packages/kit/src/runtime/stores/index.ts
new file mode 100644
index 000000000000..ef1afc7ebcbf
--- /dev/null
+++ b/packages/kit/src/runtime/stores/index.ts
@@ -0,0 +1,43 @@
+import { getContext } from 'svelte';
+
+// const ssr = (import.meta as any).env.SSR;
+const ssr = typeof window === 'undefined'; // TODO why doesn't previous line work in build?
+
+export const getStores: () => {
+ page: any // TODO
+ preloading: any // TODO
+ session: any // TODO
+} = () => getContext('__svelte__');
+
+export const page = {
+ subscribe(fn) {
+ const store = getStores().page;
+ return store.subscribe(fn);
+ }
+};
+
+export const preloading = {
+ subscribe(fn) {
+ const store = getStores().preloading;
+ return store.subscribe(fn);
+ }
+};
+
+const error = verb => {
+ throw new Error(ssr ? `Can only ${verb} session store in browser` : `Cannot ${verb} session store before subscribing`);
+};
+
+export const session = {
+ subscribe(fn) {
+ const store = getStores().session;
+
+ if (!ssr) {
+ session.set = store.set;
+ session.update = store.update;
+ }
+
+ return store.subscribe(fn);
+ },
+ set: () => error('set'),
+ update: () => error('update')
+};
\ No newline at end of file
diff --git a/packages/kit/tsconfig.json b/packages/kit/tsconfig.json
index 29d4d3b9c173..e1376e178d23 100644
--- a/packages/kit/tsconfig.json
+++ b/packages/kit/tsconfig.json
@@ -5,8 +5,10 @@
"moduleResolution": "node",
"target": "ES6",
"esModuleInterop": true,
- "noEmit": true
+ "noEmit": true,
+ "noEmitOnError": true
},
"include": ["src/**/*"],
- "lib": ["ES2020", "dom", "node"]
+ "lib": ["ES2020", "dom", "node"],
+ "strict": true
}
diff --git a/packages/snowpack-config/snowpack.config.js b/packages/snowpack-config/snowpack.config.js
index 521186b3abc8..91f78d2a6ae9 100644
--- a/packages/snowpack-config/snowpack.config.js
+++ b/packages/snowpack-config/snowpack.config.js
@@ -25,7 +25,7 @@ module.exports = {
'src/setup': '/_app/setup'
},
alias: {
- '@sveltejs/kit': '/_app/main',
+ $app: '/_app/main/runtime',
$components: './src/components'
}
};
\ No newline at end of file