Skip to content

Commit ce9156f

Browse files
authored
Merge pull request sveltejs#54 from sveltejs/sveltejsgh-2
WebContainer integration
2 parents 3ae1c77 + 1b83ae6 commit ce9156f

File tree

30 files changed

+305
-80
lines changed

30 files changed

+305
-80
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
.env
77
.env.*
88
!.env.example
9-
.apps
9+
.apps
10+
.vercel

content/tutorial/01-svelte/01-introduction/01-welcome-to-svelte/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ This tutorial is split into four main parts:
2323
- [Welcome to Svelte](/tutorial/welcome-to-svelte) (you are here)
2424
- [Introduction to SvelteKit](/tutorial/introducing-sveltekit)
2525
- [Advanced Svelte](/tutorial/tweens)
26-
- [Advanced SvelteKit](/tutorial/advanced-sveltekit)
26+
- [Advanced SvelteKit](/tutorial/sandbox)
2727

2828
Each section will present an exercise designed to illustrate a feature. Later sections build on the knowledge gained in earlier ones, so it's recommended that you go from start to finish. If necessary, you can navigate via the menu above.
2929

content/tutorial/01-svelte/05-events/05-event-forwarding/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Event forwarding
44

55
Unlike DOM events, component events don't _bubble_. If you want to listen to an event on some deeply nested component, the intermediate components must _forward_ the event.
66

7-
In this case, we have the same `App.svelte` and `Inner.svelte` as in the [previous chapter](tutorial/component-events), but there's now an `Outer.svelte` component that contains `<Inner/>`.
7+
In this case, we have the same `App.svelte` and `Inner.svelte` as in the [previous chapter](/tutorial/component-events), but there's now an `Outer.svelte` component that contains `<Inner/>`.
88

99
One way we could solve the problem is adding `createEventDispatcher` to `Outer.svelte`, listening for the `message` event, and creating a handler for it:
1010

content/tutorial/01-svelte/06-bindings/07-multiple-select-bindings/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Select multiple
44

55
A select can have a `multiple` attribute, in which case it will populate an array rather than selecting a single value.
66

7-
Returning to our [earlier ice cream example](tutorial/group-inputs), we can replace the checkboxes with a `<select multiple>`:
7+
Returning to our [earlier ice cream example](/tutorial/group-inputs), we can replace the checkboxes with a `<select multiple>`:
88

99
```svelte
1010
<h2>Flavours</h2>

content/tutorial/01-svelte/07-lifecycle/01-onmount/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: onMount
44

55
Every component has a _lifecycle_ that starts when it is created, and ends when it is destroyed. There are a handful of functions that allow you to run code at key moments during that lifecycle.
66

7-
The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. We briefly encountered it [earlier](tutorial/bind-this) when we needed to interact with a `<canvas>` element after it had been rendered.
7+
The one you'll use most frequently is `onMount`, which runs after the component is first rendered to the DOM. We briefly encountered it [earlier](/tutorial/bind-this) when we needed to interact with a `<canvas>` element after it had been rendered.
88

99
We'll add an `onMount` handler that loads some data over the network:
1010

content/tutorial/01-svelte/08-stores/02-auto-subscriptions/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const unsubscribe = count.subscribe((value) => {
1414

1515
> Calling a `subscribe` method returns an `unsubscribe` function.
1616
17-
You now declared `unsubscribe`, but it still needs to be called, for example through the `onDestroy` [lifecycle hook](tutorial/ondestroy):
17+
You now declared `unsubscribe`, but it still needs to be called, for example through the `onDestroy` [lifecycle hook](/tutorial/ondestroy):
1818

1919
```svelte
2020
<script>

content/tutorial/03-advanced-svelte/02-transitions/04-custom-css-transitions/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The function takes two arguments — the node to which the transition is applied
2020

2121
- `delay` — milliseconds before the transition begins
2222
- `duration` — length of the transition in milliseconds
23-
- `easing` — a `p => t` easing function (see the chapter on [tweening](tutorial/tweened))
23+
- `easing` — a `p => t` easing function (see the chapter on [tweening](/tutorial/tweens))
2424
- `css` — a `(t, u) => css` function, where `u === 1 - t`
2525
- `tick` — a `(t, u) => {...}` function that has some effect on the node
2626

content/tutorial/03-advanced-svelte/03-animations/01-animate/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: The animate directive
33
---
44

5-
In the [previous chapter](tutorial/deferred-transitions), we used deferred transitions to create the illusion of motion as elements move from one todo list to the other.
5+
In the [previous chapter](/tutorial/deferred-transitions), we used deferred transitions to create the illusion of motion as elements move from one todo list to the other.
66

77
To complete the illusion, we also need to apply motion to the elements that _aren't_ transitioning. For this, we use the `animate` directive.
88

content/tutorial/03-advanced-svelte/05-bindings/05-bind-this/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ The readonly `this` binding applies to every element (and component) and allows
1212
></canvas>
1313
```
1414

15-
Note that the value of `canvas` will be `undefined` until the component has mounted, so we put the logic inside the `onMount` [lifecycle function](tutorial/onmount).
15+
Note that the value of `canvas` will be `undefined` until the component has mounted, so we put the logic inside the `onMount` [lifecycle function](/tutorial/onmount).

content/tutorial/03-advanced-svelte/07-composition/03-named-slots/app-a/src/lib/ContactCard.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@
4343
}
4444
4545
.address {
46-
background-image: url(tutorial/icons/map-marker.svg);
46+
background-image: url(/tutorial/icons/map-marker.svg);
4747
}
4848
.email {
49-
background-image: url(tutorial/icons/email.svg);
49+
background-image: url(/tutorial/icons/email.svg);
5050
}
5151
.missing {
5252
color: #999;

content/tutorial/03-advanced-svelte/07-composition/03-named-slots/app-b/src/lib/ContactCard.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@
4343
}
4444
4545
.address {
46-
background-image: url(tutorial/icons/map-marker.svg);
46+
background-image: url(/tutorial/icons/map-marker.svg);
4747
}
4848
.email {
49-
background-image: url(tutorial/icons/email.svg);
49+
background-image: url(/tutorial/icons/email.svg);
5050
}
5151
.missing {
5252
color: #999;

content/tutorial/03-advanced-svelte/08-context/01-context-api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ setContext(key, {
1919
});
2020
```
2121

22-
The context object can be anything you like. Like [lifecycle functions](tutorial/onmount), `setContext` and `getContext` must be called during component initialisation. Calling it afterwards - for example inside `onMount` - will throw an error. In this example, since `map` isn't created until the component has mounted, our context object contains a `getMap` function rather than `map` itself.
22+
The context object can be anything you like. Like [lifecycle functions](/tutorial/onmount), `setContext` and `getContext` must be called during component initialisation. Calling it afterwards - for example inside `onMount` - will throw an error. In this example, since `map` isn't created until the component has mounted, our context object contains a `getMap` function rather than `map` itself.
2323

2424
On the other side of the equation, in `MapMarker.svelte`, we can now get a reference to the Mapbox instance:
2525

content/tutorial/03-advanced-svelte/09-special-elements/01-svelte-self/app-a/src/lib/File.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
</script>
55

66
<span
7-
style="background-image: url(http://github.com/tutorial/icons/%3C/span%3E%7B%3Cspan%20class=%22pl-smi%22%3Etype%3C/span%3E%7D%3Cspan%20class=%22pl-s%22%3E.svg)"
7+
style="background-image: url(http://github.com/%3Cspan%20class=%22x%20x-first%20x-last%22%3E/%3C/span%3Etutorial/icons/%3C/span%3E%7B%3Cspan%20class=%22pl-smi%22%3Etype%3C/span%3E%7D%3Cspan%20class=%22pl-s%22%3E.svg)"
88
>{name}</span
99
>
1010

content/tutorial/03-advanced-svelte/09-special-elements/01-svelte-self/app-a/src/lib/Folder.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131
<style>
3232
span {
3333
padding: 0 0 0 1.5em;
34-
background: url(tutorial/icons/folder.svg) 0
34+
background: url(/tutorial/icons/folder.svg) 0
3535
0.1em no-repeat;
3636
background-size: 1em 1em;
3737
font-weight: bold;
3838
cursor: pointer;
3939
}
4040
4141
.expanded {
42-
background-image: url(tutorial/icons/folder-open.svg);
42+
background-image: url(/tutorial/icons/folder-open.svg);
4343
}
4444
4545
ul {

content/tutorial/03-advanced-svelte/09-special-elements/01-svelte-self/app-b/src/lib/File.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
</script>
55

66
<span
7-
style="background-image: url(http://github.com/tutorial/icons/%3C/span%3E%7B%3Cspan%20class=%22pl-smi%22%3Etype%3C/span%3E%7D%3Cspan%20class=%22pl-s%22%3E.svg)"
7+
style="background-image: url(http://github.com/%3Cspan%20class=%22x%20x-first%20x-last%22%3E/%3C/span%3Etutorial/icons/%3C/span%3E%7B%3Cspan%20class=%22pl-smi%22%3Etype%3C/span%3E%7D%3Cspan%20class=%22pl-s%22%3E.svg)"
88
>{name}</span
99
>
1010

content/tutorial/03-advanced-svelte/09-special-elements/01-svelte-self/app-b/src/lib/Folder.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131
<style>
3232
span {
3333
padding: 0 0 0 1.5em;
34-
background: url(tutorial/icons/folder.svg) 0
34+
background: url(/tutorial/icons/folder.svg) 0
3535
0.1em no-repeat;
3636
background-size: 1em 1em;
3737
font-weight: bold;
3838
cursor: pointer;
3939
}
4040
4141
.expanded {
42-
background-image: url(tutorial/icons/folder-open.svg);
42+
background-image: url(/tutorial/icons/folder-open.svg);
4343
}
4444
4545
ul {

content/tutorial/03-advanced-svelte/09-special-elements/03-svelte-window/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ On line 11, add the `keydown` listener:
1010
<svelte:window on:keydown={handleKeydown}/>
1111
```
1212

13-
> As with DOM elements, you can add [event modifiers](tutorial/event-modifiers) like `preventDefault`.
13+
> As with DOM elements, you can add [event modifiers](/tutorial/event-modifiers) like `preventDefault`.

content/tutorial/03-advanced-svelte/12-next-steps/01-congratulations/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ To get set up in your local development environment, check out [the quickstart g
88

99
If you're looking for a more expansive framework that includes routing, server-side rendering and everything else, take a look at [SvelteKit](https://kit.svelte.dev).
1010

11-
Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](chat). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.
11+
Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](https://svelte.dev/chat). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.

content/tutorial/common/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
"prepare": "svelte-kit sync"
1010
},
1111
"devDependencies": {
12-
"@sveltejs/adapter-auto": "workspace:*",
13-
"@sveltejs/kit": "workspace:*",
12+
"@sveltejs/adapter-auto": "next",
13+
"@sveltejs/kit": "next",
1414
"svelte": "^3.44.0"
1515
},
1616
"type": "module"

middleware.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default function middleware(_request, _event) {
2+
const response = new Response();
3+
4+
response.headers.set('cross-origin-opener-policy', 'same-origin');
5+
response.headers.set('cross-origin-embedder-policy', 'require-corp');
6+
response.headers.set('x-middleware-next', '1');
7+
8+
return response;
9+
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.0.1",
44
"scripts": {
55
"dev": "svelte-kit dev",
6-
"build": "svelte-kit build",
6+
"build": "svelte-kit build && node scripts/create-middleware.js",
77
"package": "svelte-kit package",
88
"preview": "svelte-kit preview",
99
"prepare": "svelte-kit sync",
@@ -26,6 +26,8 @@
2626
"type": "module",
2727
"dependencies": {
2828
"@fontsource/roboto-mono": "^4.5.7",
29+
"@webcontainer/api": "^0.0.1",
30+
"base64-js": "^1.5.1",
2931
"marked": "^4.0.16",
3032
"monaco-editor": "^0.33.0",
3133
"port-authority": "^2.0.1",

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/create-middleware.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// this generates some middleware that will set COOP/COEP headers
2+
// so that webcontainers work. ideally there'd be a more idiomatic
3+
// way to do this, but it'll do in the meantime
4+
5+
import fs from 'fs';
6+
7+
if (!fs.existsSync('.vercel/output/config.json')) {
8+
throw new Error('.vercel/output does not exist');
9+
}
10+
11+
const fn = `
12+
export default function middleware(_request, _event) {
13+
const response = new Response();
14+
15+
response.headers.set('cross-origin-opener-policy', 'same-origin');
16+
response.headers.set('cross-origin-embedder-policy', 'require-corp');
17+
response.headers.set('x-middleware-next', '1');
18+
19+
return response;
20+
}
21+
`;
22+
23+
const config = JSON.parse(fs.readFileSync('.vercel/output/config.json', 'utf-8'));
24+
config.routes.unshift({
25+
src: '/(.*)',
26+
middlewarePath: '_middleware',
27+
continue: true
28+
});
29+
fs.writeFileSync('.vercel/output/config.json', JSON.stringify(config));
30+
31+
fs.mkdirSync('.vercel/output/functions/_middleware.func');
32+
33+
fs.writeFileSync(
34+
'.vercel/output/functions/_middleware.func/.vc-config.json',
35+
JSON.stringify({
36+
runtime: 'edge',
37+
entrypoint: 'index.js'
38+
})
39+
);
40+
41+
fs.writeFileSync('.vercel/output/functions/_middleware.func/index.js', fn);

src/hooks.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const loading = `
2+
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128">
3+
<title>svelte-logo</title>
4+
<path
5+
d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157"
6+
style="fill: #ff3e00"
7+
/>
8+
<path
9+
d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287"
10+
style="fill: #fff"
11+
/>
12+
</svg>
13+
14+
<style>
15+
body {
16+
display: flex;
17+
align-items: center;
18+
justify-content: center;
19+
background: #f9f9f9;
20+
user-select: none;
21+
height: 100%;
22+
margin: 0;
23+
padding: 0;
24+
}
25+
26+
svg {
27+
width: 100px;
28+
height: 100px;
29+
filter: grayscale(1) opacity(0.1);
30+
}
31+
</style>
32+
`;
33+
34+
/** @type {import('@sveltejs/kit').Handle} */
35+
export async function handle({ event, resolve }) {
36+
if (event.url.pathname === '/loading.html') {
37+
return new Response(loading, {
38+
headers: {
39+
'Content-Type': 'text/html',
40+
'Cross-Origin-Embedder-Policy': 'require-corp'
41+
}
42+
});
43+
}
44+
45+
const response = await resolve(event);
46+
47+
response.headers.set('cross-origin-opener-policy', 'same-origin');
48+
response.headers.set('cross-origin-embedder-policy', 'require-corp');
49+
50+
return response;
51+
}

src/lib/client/adapters/filesystem/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export async function create(stubs) {
3838
await new Promise((f) => setTimeout(f, 100)); // wait for chokidar
3939
},
4040

41-
/** @param {import('$lib/types').Stub[]} stubs */
41+
/** @param {import('$lib/types').FileStub[]} stubs */
4242
async update(stubs) {
4343
await fetch(`/backend/${id}`, {
4444
method: 'put',

0 commit comments

Comments
 (0)