Skip to content

Commit ca63d5d

Browse files
committed
feat(runtime): add preview.pathname
1 parent 3b2c776 commit ca63d5d

File tree

6 files changed

+46
-19
lines changed

6 files changed

+46
-19
lines changed

docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,32 @@ Configure whether or not the editor should be rendered. If an object is provided
9191
##### `previews`
9292
Configure which ports should be used for the previews allowing you to align the behavior with your demo application's dev server setup. If not specified, the lowest port will be used.
9393

94-
You can optionally provide these as an array of tuples where the first element is the port number and the second is the title of the preview, or as an object.
9594
<PropertyTable inherited type={'Preview[]'} />
9695

9796
The `Preview` type has the following shape:
9897

9998
```ts
100-
type Preview = string
99+
type Preview =
100+
| number
101+
| string
101102
| [port: number, title: string]
102-
| { port: number, title: string }
103+
| [port: number, title: string, pathname: string]
104+
| { port: number, title: string, pathname?: string }
103105

104106
```
105107

108+
Example value:
109+
110+
```yaml
111+
previews:
112+
- 3000 # Preview is on :3000/
113+
- "3001/docs" # Preview is on :3001/docs/
114+
- [3002, "Dev Server"] # Preview is on :3002/. Displayed title is "Dev Server".
115+
- [3003, "Dev Server", "/docs"] # Preview is on :3003/docs/. Displayed title is "Dev Server".
116+
- { port: 3004, title: "Dev Server" } # Preview is on :3004/. Displayed title is "Dev Server".
117+
- { port: 3005, title: "Dev Server", pathname: "/docs" } # Preview is on :3005/docs/. Displayed title is "Dev Server".
118+
```
119+
106120
##### `mainCommand`
107121
The main command to be executed. This command will run after the `prepareCommands`.
108122
<PropertyTable inherited type="Command" />

packages/runtime/src/store/previews.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { PreviewInfo } from '../webcontainer/preview-info.js';
44
import type { WebContainer } from '@webcontainer/api';
55

66
export class PreviewsStore {
7-
private _availablePreviews = new Map<number, PreviewInfo>();
7+
private _availablePreviews: PreviewInfo[] = [];
88
private _previewsLayout: PreviewInfo[] = [];
99

1010
/**
@@ -21,18 +21,21 @@ export class PreviewsStore {
2121
const webcontainer = await webcontainerPromise;
2222

2323
webcontainer.on('port', (port, type, url) => {
24-
let previewInfo = this._availablePreviews.get(port);
24+
const previewInfos = this._availablePreviews.filter((preview) => preview.port === port);
2525

26-
if (!previewInfo) {
27-
previewInfo = new PreviewInfo(port, type === 'open');
28-
this._availablePreviews.set(port, previewInfo);
26+
if (previewInfos.length === 0) {
27+
const info = new PreviewInfo(port, type === 'open');
28+
previewInfos.push(info);
29+
this._availablePreviews.push(info);
2930
}
3031

31-
previewInfo.ready = type === 'open';
32-
previewInfo.baseUrl = url;
32+
previewInfos.forEach((info) => {
33+
info.ready = type === 'open';
34+
info.baseUrl = url;
35+
});
3336

3437
if (this._previewsLayout.length === 0) {
35-
this.previews.set([previewInfo]);
38+
this.previews.set(previewInfos);
3639
} else {
3740
this._previewsLayout = [...this._previewsLayout];
3841
this.previews.set(this._previewsLayout);
@@ -58,14 +61,12 @@ export class PreviewsStore {
5861
const previewInfos = previews.map((preview) => {
5962
const info = new PreviewInfo(preview);
6063

61-
let previewInfo = this._availablePreviews.get(info.port);
64+
let previewInfo = this._availablePreviews.find((availablePreview) => PreviewInfo.equals(info, availablePreview));
6265

6366
if (!previewInfo) {
6467
previewInfo = info;
6568

66-
this._availablePreviews.set(previewInfo.port, previewInfo);
67-
} else {
68-
previewInfo.title = info.title;
69+
this._availablePreviews.push(previewInfo);
6970
}
7071

7172
return previewInfo;

packages/runtime/src/webcontainer/preview-info.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ export class PreviewInfo {
1818
constructor(preview: Exclude<PreviewSchema, boolean>[0], ready?: boolean) {
1919
if (typeof preview === 'number') {
2020
this.port = preview;
21+
} else if (typeof preview === 'string') {
22+
const [port, ...rest] = preview.split('/');
23+
this.port = parseInt(port);
24+
this.pathname = rest.join('/');
2125
} else if (Array.isArray(preview)) {
2226
this.port = preview[0];
2327
this.title = preview[1];
28+
this.pathname = preview[2];
2429
} else {
2530
this.port = preview.port;
2631
this.title = preview.title;
32+
this.pathname = preview.pathname;
2733
}
2834

2935
this.ready = !!ready;

packages/template/src/content/tutorial/1-basics/1-introduction/2-foo/content.mdx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ title: Foo from part 1
44
slug: foo
55
focus: /src/index.html
66
previews:
7-
- [8080, 'Main Page']
7+
- { title: 'Main Page', port: 8080, pathname: '/src'}
88
- [1, 'Test Runner']
9-
- [2, 'Bar']
9+
- '2/some/custom/pathname'
10+
- '2/another/pathname'
1011
terminal:
1112
panels: 'terminal'
1213
editPageLink: 'https://tutorialkit.dev'

packages/template/src/templates/default/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ createServer((_req, res) => {
1515
`);
1616
}).listen(1);
1717

18-
createServer((_req, res) => res.end('Server 2')).listen(2);
18+
createServer((req, res) => res.end(`Server 2\n${req.method} ${req.url}`)).listen(2);
1919

2020
servor({
2121
root: 'src/',

packages/types/src/schemas/common.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,17 @@ export const previewSchema = z.union([
3737
// a single number, the port for the preview
3838
z.number(),
3939

40-
// a tuple, the port followed by a title
40+
// a string, the port and pathname
41+
z.string(),
42+
43+
// a tuple, the port followed by a title and optional pathname
4144
z.tuple([z.number(), z.string()]),
45+
z.tuple([z.number(), z.string(), z.string()]),
4246

4347
z.strictObject({
4448
port: z.number().describe('Port number of the preview.'),
4549
title: z.string().describe('Title of the preview.'),
50+
pathname: z.string().optional().describe('Pathname of the preview URL.'),
4651
}),
4752
])
4853
.array(),

0 commit comments

Comments
 (0)