Skip to content

Commit 9022dfb

Browse files
7nikeltigerchinoRich-Harris
authored
feat: add svelte version selector to REPL (#1319)
* add svelte version selector to REPL * fix lint * fix resolving empty version * revert button css changes * tweak styles - make all items the same height etc --------- Co-authored-by: Tee Ming <chewteeming01@gmail.com> Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent cadd4a9 commit 9022dfb

File tree

10 files changed

+105
-41
lines changed

10 files changed

+105
-41
lines changed

apps/svelte.dev/src/lib/tutorial/adapters/rollup/index.svelte.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ import type { Adapter } from '$lib/tutorial';
55
import type { File, Item } from '@sveltejs/repl/workspace';
66

77
let done = false;
8+
let svelte_version = 'latest';
89

910
export const state = new (class RollupState {
1011
progress = $state.raw({ value: 0, text: 'initialising' });
1112
bundler = new Bundler({
12-
svelte_version: 'latest',
13+
svelte_version,
1314
onstatus: (val) => {
1415
if (!done && val === null) {
1516
done = true;
1617
this.progress = { value: 1, text: 'ready' };
1718
}
19+
},
20+
onversion: (version) => {
21+
svelte_version = version;
1822
}
1923
});
2024
})();
@@ -33,7 +37,8 @@ export async function create(): Promise<Adapter> {
3337
.map((f) => ({ ...f, name: f.name.slice(9) })),
3438
{
3539
// TODO support Tailwind here?
36-
runes: true
40+
runes: true,
41+
svelte_version
3742
}
3843
);
3944
}

packages/repl/src/lib/Input/ComponentSelector.svelte

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,15 @@
177177

178178
<button disabled={!can_migrate} onclick={migrate}>Migrate to Svelte 5, if possible</button>
179179

180+
<label class="option">
181+
<span>Svelte version</span>
182+
<input
183+
value={workspace.svelte_version}
184+
placeholder="latest"
185+
onchange={(ev) => (workspace.svelte_version = ev.currentTarget.value || 'latest')}
186+
/>
187+
</label>
188+
180189
{#if download}
181190
<button onclick={download}>Download app</button>
182191
{/if}
@@ -278,7 +287,7 @@
278287
}
279288
}
280289
281-
input {
290+
.file-tabs input {
282291
position: absolute;
283292
width: calc(100% - var(--padding-left) - var(--padding-right));
284293
border: none;
@@ -318,6 +327,24 @@
318327
justify-content: flex-end;
319328
}
320329
330+
.option {
331+
height: 3.6rem;
332+
333+
input {
334+
background: transparent;
335+
border: none;
336+
border-radius: var(--sk-border-radius);
337+
color: currentColor;
338+
width: 0;
339+
flex: 1;
340+
padding: 0.2rem 0.6rem;
341+
height: 3.2rem;
342+
font: var(--sk-font-ui-medium);
343+
margin: -0.5rem -0.6rem -0.5rem 1rem;
344+
text-align: right;
345+
}
346+
}
347+
321348
svg {
322349
position: relative;
323350
overflow: hidden;

packages/repl/src/lib/Output/PaneWithPanel.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
}
138138
139139
section {
140+
position: relative;
140141
overflow: hidden;
141142
}
142143
</style>

packages/repl/src/lib/Output/Viewer.svelte

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,15 @@
370370
srcdoc={BROWSER ? srcdoc : ''}
371371
></iframe>
372372

373-
{#if bundle?.error}
374-
<ErrorOverlay error={bundle.error} />
375-
{/if}
373+
<div class="overlay">
374+
{#if bundle?.error}
375+
<ErrorOverlay error={bundle.error} />
376+
{:else if error}
377+
<Message kind="error" details={error} />
378+
{:else if status || !bundle}
379+
<Message kind="info" truncate>{status || 'loading Svelte compiler...'}</Message>
380+
{/if}
381+
</div>
376382
{/snippet}
377383

378384
<div class="iframe-container">
@@ -401,14 +407,6 @@
401407
{:else}
402408
{@render main()}
403409
{/if}
404-
405-
<div class="overlay">
406-
{#if error}
407-
<Message kind="error" details={error} />
408-
{:else if status || !bundle}
409-
<Message kind="info" truncate>{status || 'loading Svelte compiler...'}</Message>
410-
{/if}
411-
</div>
412410
</div>
413411

414412
<style>

packages/repl/src/lib/Repl.svelte

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
109109
function rebundle() {
110110
return bundler!.bundle(workspace.files as File[], {
111+
svelte_version: workspace.svelte_version,
111112
tailwind: workspace.tailwind,
112113
fragments: workspace.compiler_options.fragments,
113114
aliases: workspace.aliases
@@ -135,7 +136,10 @@
135136
const bundler = BROWSER
136137
? new Bundler({
137138
svelte_version: svelteVersion,
138-
onversion,
139+
onversion: (version) => {
140+
workspace.svelte_version = version;
141+
onversion?.(version);
142+
},
139143
onstatus: (message) => {
140144
if (message) {
141145
// show bundler status, but only after time has elapsed, to
@@ -231,7 +235,7 @@
231235
{injectedCSS}
232236
{previewTheme}
233237
{workspace}
234-
runtimeError={status_visible ? runtime_error : null}
238+
runtimeError={runtime_error}
235239
/>
236240
</section>
237241
{/snippet}
@@ -256,13 +260,13 @@
256260
height: 100%;
257261
}
258262
259-
:global {
260-
section {
261-
position: relative;
262-
padding: var(--sk-pane-controls-height) 0 0 0;
263-
height: 100%;
264-
box-sizing: border-box;
263+
section {
264+
position: relative;
265+
padding: var(--sk-pane-controls-height) 0 0 0;
266+
height: 100%;
267+
box-sizing: border-box;
265268
269+
:global {
266270
& > :first-child {
267271
position: absolute;
268272
top: 0;
@@ -277,11 +281,11 @@
277281
height: 100%;
278282
}
279283
}
284+
}
280285
281-
[data-pane='main'] > svelte-split-pane-divider::after {
282-
height: calc(100% - var(--sk-pane-controls-height));
283-
top: var(--sk-pane-controls-height);
284-
}
286+
:global [data-pane='main'] > svelte-split-pane-divider::after {
287+
height: calc(100% - var(--sk-pane-controls-height));
288+
top: var(--sk-pane-controls-height);
285289
}
286290
}
287291

packages/repl/src/lib/Workspace.svelte.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export class Workspace {
112112
});
113113
compiled = $state<Record<string, Compiled>>({});
114114

115-
#svelte_version: string;
115+
#svelte_version = $state('');
116116
#readonly = false; // TODO do we need workspaces for readonly stuff?
117117
#files = $state.raw<Item[]>([]);
118118
#current = $state.raw() as File;
@@ -503,6 +503,16 @@ export class Workspace {
503503
this.#onupdate(this.#current);
504504
}
505505

506+
get svelte_version() {
507+
return this.#svelte_version;
508+
}
509+
510+
set svelte_version(value) {
511+
this.#svelte_version = value;
512+
this.#update_file(this.#current);
513+
this.#reset_diagnostics();
514+
}
515+
506516
get vim() {
507517
return this.#vim;
508518
}

packages/repl/src/lib/workers/bundler/index.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,21 @@ const ESM_ENV = '__esm-env.js';
4444

4545
let current_id: number;
4646

47-
let ready: ReturnType<typeof load_svelte>;
48-
4947
self.addEventListener('message', async (event: MessageEvent<BundleMessageData>) => {
5048
switch (event.data.type) {
5149
case 'init': {
52-
ready = load_svelte(event.data.svelte_version, (version) => {
53-
self.postMessage({
54-
type: 'version',
55-
message: version
56-
});
57-
});
58-
50+
get_svelte(event.data.svelte_version);
5951
break;
6052
}
6153

6254
case 'bundle': {
6355
try {
64-
const { svelte, version: svelte_version, can_use_experimental_async } = await ready;
6556
const { uid, files, options } = event.data;
57+
const {
58+
svelte,
59+
version: svelte_version,
60+
can_use_experimental_async
61+
} = await get_svelte(options.svelte_version);
6662

6763
current_id = uid;
6864

@@ -96,6 +92,25 @@ self.addEventListener('message', async (event: MessageEvent<BundleMessageData>)
9692
}
9793
});
9894

95+
let ready: ReturnType<typeof load_svelte>;
96+
let ready_version: string;
97+
98+
function get_svelte(svelte_version: string) {
99+
if (ready_version === svelte_version) return ready;
100+
101+
self.postMessage({ type: 'status', message: `fetching svelte@${svelte_version}` });
102+
ready_version = svelte_version;
103+
ready = load_svelte(svelte_version || 'latest');
104+
ready.then(({ version }) => {
105+
ready_version = version;
106+
self.postMessage({
107+
type: 'version',
108+
message: version
109+
});
110+
});
111+
return ready;
112+
}
113+
99114
const ABORT = { aborted: true };
100115

101116
let previous: {

packages/repl/src/lib/workers/npm.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ const packages = new Map<string, Promise<Package>>();
1313

1414
const pkg_pr_new_regex = /^(pr|commit|branch)-(.+)/;
1515

16-
export async function load_svelte(version: string, onresolve?: (resolved: string) => void) {
16+
export async function load_svelte(version: string) {
1717
if (version === 'local') {
1818
await import(/* @vite-ignore */ `${location.origin}/svelte/compiler/index.js`);
1919
} else {
2020
if (!pkg_pr_new_regex.test(version)) {
21-
version = await resolve_version('svelte', version);
22-
onresolve?.(version);
21+
const resolved_version = await resolve_version('svelte', version);
22+
if (resolved_version) {
23+
version = resolved_version;
24+
} else {
25+
throw new Error(`Failed to resolve svelte@${version}`);
26+
}
2327
}
2428

2529
const pkg = await fetch_package('svelte', version);

packages/repl/src/lib/workers/workers.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export interface MigrateOutput {
5050
}
5151

5252
export interface BundleOptions {
53+
svelte_version: string;
5354
tailwind?: boolean;
5455
runes?: boolean;
5556
fragments?: 'html' | 'tree';

packages/site-kit/src/lib/components/Checkbox.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
-webkit-appearance: none;
2020
appearance: none;
2121
border: transparent;
22-
margin: 0 0.6em 0 0;
2322
}
2423
2524
input[type='checkbox']::before {

0 commit comments

Comments
 (0)