diff --git a/site/content/examples/00-introduction/00-hello-world/meta.json b/site/content/examples/00-introduction/00-hello-world/meta.json
index 2f47184710..6cf02c2ed1 100644
--- a/site/content/examples/00-introduction/00-hello-world/meta.json
+++ b/site/content/examples/00-introduction/00-hello-world/meta.json
@@ -1,3 +1,3 @@
{
- "title": "Adding data"
+ "title": "Hello world"
}
\ No newline at end of file
diff --git a/site/content/examples/11-svg/05-svg-transitions/App.svelte b/site/content/examples/11-svg/05-svg-transitions/App.svelte
index 485bbf2558..6059b3645f 100644
--- a/site/content/examples/11-svg/05-svg-transitions/App.svelte
+++ b/site/content/examples/11-svg/05-svg-transitions/App.svelte
@@ -1,7 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/site/src/components/Lazy.svelte b/site/src/components/Lazy.svelte
new file mode 100644
index 0000000000..ef81d68f00
--- /dev/null
+++ b/site/src/components/Lazy.svelte
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/site/src/components/Repl/Bundler.js b/site/src/components/Repl/Bundler.js
new file mode 100644
index 0000000000..ddde546e7f
--- /dev/null
+++ b/site/src/components/Repl/Bundler.js
@@ -0,0 +1,44 @@
+const workers = new Map();
+
+let uid = 1;
+
+export default class Bundler {
+ constructor(version) {
+ if (!workers.has(version)) {
+ const worker = new Worker('/workers/bundler.js');
+ worker.postMessage({ type: 'init', version });
+ workers.set(version, worker);
+ }
+
+ this.worker = workers.get(version);
+
+ this.handlers = new Map();
+
+ this.worker.addEventListener('message', event => {
+ const handler = this.handlers.get(event.data.id);
+
+ if (handler) { // if no handler, was meant for a different REPL
+ handler(event.data);
+ this.handlers.delete(event.data.id);
+ }
+ });
+ }
+
+ bundle(components) {
+ return new Promise(fulfil => {
+ const id = uid++;
+
+ this.handlers.set(id, fulfil);
+
+ this.worker.postMessage({
+ id,
+ type: 'bundle',
+ components
+ });
+ });
+ }
+
+ destroy() {
+ this.worker.terminate();
+ }
+}
\ No newline at end of file
diff --git a/site/src/components/Repl/CodeMirror.svelte b/site/src/components/Repl/CodeMirror.svelte
index e9519e516e..a1a92fe344 100644
--- a/site/src/components/Repl/CodeMirror.svelte
+++ b/site/src/components/Repl/CodeMirror.svelte
@@ -33,9 +33,9 @@
// than making this state-driven through props,
// because it's difficult to update an editor
// without resetting scroll otherwise
- export function set(new_code, new_mode) {
+ export async function set(new_code, new_mode) {
if (new_mode !== mode) {
- createEditor(mode = new_mode);
+ await createEditor(mode = new_mode);
}
code = new_code;
@@ -121,12 +121,13 @@
onMount(() => {
if (_CodeMirror) {
CodeMirror = _CodeMirror;
- createEditor(mode || 'svelte');
- editor.setValue(code || '');
+ createEditor(mode || 'svelte').then(() => {
+ editor.setValue(code || '');
+ });
} else {
- codemirror_promise.then(mod => {
+ codemirror_promise.then(async mod => {
CodeMirror = mod.default;
- createEditor(mode || 'svelte');
+ await createEditor(mode || 'svelte');
editor.setValue(code || '');
});
}
@@ -137,12 +138,10 @@
}
});
- function createEditor(mode) {
+ async function createEditor(mode) {
if (destroyed || !CodeMirror) return;
- if (editor) {
- editor.toTextArea();
- }
+ if (editor) editor.toTextArea();
const opts = {
lineNumbers,
@@ -162,6 +161,12 @@
'Shift-Tab': tab
};
+ // Creating a text editor is a lot of work, so we yield
+ // the main thread for a moment. This helps reduce jank
+ await sleep(50);
+
+ if (destroyed) return;
+
editor = CodeMirror.fromTextArea(refs.editor, opts);
editor.on('change', instance => {
@@ -171,8 +176,13 @@
}
});
+ await sleep(50);
editor.refresh();
}
+
+ function sleep(ms) {
+ return new Promise(fulfil => setTimeout(fulfil, ms));
+ }
+
+
+ {#if process.browser}
+
+ {/if}
+
diff --git a/site/src/components/Repl/index.svelte b/site/src/components/Repl/index.svelte
index 7e81f662c5..50499f163f 100644
--- a/site/src/components/Repl/index.svelte
+++ b/site/src/components/Repl/index.svelte
@@ -7,6 +7,7 @@
import ModuleEditor from './Input/ModuleEditor.svelte';
import Output from './Output/index.svelte';
import InputOutputToggle from './InputOutputToggle.svelte';
+ import Bundler from './Bundler.js';
export let version = 'beta'; // TODO change this to latest when the time comes
export let embedded = false;
@@ -31,6 +32,8 @@
module_editor.set($selected.source, $selected.type);
output.set($selected, $compile_options);
+
+ rebundle();
}
export function update(data) {
@@ -69,8 +72,11 @@
let module_editor;
let output;
- function rebundle() {
- workers.bundler.postMessage({ type: 'bundle', components: $components });
+ let current_token;
+ async function rebundle() {
+ const token = current_token = {};
+ const result = await bundler.bundle($components);
+ if (result && token === current_token) bundle.set(result);
}
setContext('REPL', {
@@ -143,30 +149,7 @@
let width = typeof window !== 'undefined' ? window.innerWidth : 300;
let show_output = false;
- onMount(async () => {
- workers = {
- bundler: new Worker('/workers/bundler.js')
- };
-
- workers.bundler.postMessage({ type: 'init', version });
- workers.bundler.onmessage = event => {
- bundle.set(event.data);
- };
-
- return () => {
- workers.bundler.terminate();
- };
- });
-
- $: if ($bundle && $bundle.error && $selected) {
- sourceErrorLoc = $bundle.error.filename === `${$selected.name}.${$selected.type}`
- ? $bundle.error.start
- : null;
- }
-
- $: if (workers && $components) {
- workers.bundler.postMessage({ type: 'bundle', components: $components });
- }
+ const bundler = process.browser && new Bundler(version);
$: if (output && $selected) {
output.update($selected, $compile_options);
diff --git a/site/src/routes/repl/_utils/process_example.js b/site/src/components/Repl/process_example.js
similarity index 100%
rename from site/src/routes/repl/_utils/process_example.js
rename to site/src/components/Repl/process_example.js
diff --git a/site/src/components/TopNav.svelte b/site/src/components/TopNav.svelte
index d1e4db6d31..d02ff58cec 100644
--- a/site/src/components/TopNav.svelte
+++ b/site/src/components/TopNav.svelte
@@ -52,7 +52,7 @@
background-color: white;
box-shadow: 0 -0.4rem 0.9rem 0.2rem rgba(0,0,0,.5);
font-family: var(--font);
- z-index: 10;
+ z-index: 100;
user-select: none;
transform: translate(0,calc(-100% - 1rem));
transition: transform 0.2s;
diff --git a/site/src/routes/_layout.svelte b/site/src/routes/_layout.svelte
index 386c27ac39..a72065a7c2 100644
--- a/site/src/routes/_layout.svelte
+++ b/site/src/routes/_layout.svelte
@@ -4,7 +4,6 @@
import Nav from '../components/TopNav.svelte';
export let segment;
- export let path;
@@ -20,7 +19,8 @@
main {
position: relative;
margin: 0 auto;
- padding: var(--nav-h) var(--side-nav) 0 var(--side-nav);
+ /* padding: var(--nav-h) var(--side-nav) 0 var(--side-nav); */
+ padding: var(--nav-h) 0 0 0;
overflow-x: hidden;
}
\ No newline at end of file
diff --git a/site/src/routes/blog/index.svelte b/site/src/routes/blog/index.svelte
index 86828e42ca..b6743d94a1 100644
--- a/site/src/routes/blog/index.svelte
+++ b/site/src/routes/blog/index.svelte
@@ -30,7 +30,7 @@
grid-template-columns: 1fr 1fr;
grid-gap: 1em;
min-height: calc(100vh - var(--nav-h));
- padding: var(--top-offset) 0;
+ padding: var(--top-offset) var(--side-nav) 0 var(--side-nav);
max-width: var(--main-width);
margin: 0 auto;
}
diff --git a/site/src/routes/examples/index.svelte b/site/src/routes/examples/index.svelte
index fa6ee35025..68cb9e3110 100644
--- a/site/src/routes/examples/index.svelte
+++ b/site/src/routes/examples/index.svelte
@@ -15,6 +15,7 @@
-
- {name} • Svelte REPL
-
-
{#if process.browser}
-
+
{/if}
diff --git a/site/src/routes/repl/index.svelte b/site/src/routes/repl/index.svelte
index 8671717f5d..4f3a4f9f7c 100644
--- a/site/src/routes/repl/index.svelte
+++ b/site/src/routes/repl/index.svelte
@@ -11,7 +11,7 @@