Skip to content

Commit c7829e4

Browse files
committed
fix: code review
1 parent adefbd5 commit c7829e4

File tree

4 files changed

+50
-31
lines changed

4 files changed

+50
-31
lines changed

packages/runtime/src/store/previews.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import type { PreviewSchema } from '@tutorialkit/types';
2+
import type { WebContainer } from '@webcontainer/api';
23
import { atom } from 'nanostores';
34
import { PreviewInfo } from '../webcontainer/preview-info.js';
4-
import type { WebContainer } from '@webcontainer/api';
5+
import { PortInfo } from '../webcontainer/port-info.js';
56

67
export class PreviewsStore {
7-
private _availablePreviews: PreviewInfo[] = [];
8+
private _availablePreviews = new Map<number, PortInfo>();
89
private _previewsLayout: PreviewInfo[] = [];
910

1011
/**
@@ -21,21 +22,19 @@ export class PreviewsStore {
2122
const webcontainer = await webcontainerPromise;
2223

2324
webcontainer.on('port', (port, type, url) => {
24-
const previewInfos = this._availablePreviews.filter((preview) => preview.port === port);
25+
let portInfo = this._availablePreviews.get(port);
26+
27+
if (!portInfo) {
28+
portInfo = new PortInfo(port, url, type === 'open');
2529

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

32-
previewInfos.forEach((info) => {
33-
info.ready = type === 'open';
34-
info.baseUrl = url;
35-
});
33+
portInfo.ready = type === 'open';
34+
portInfo.origin = url;
3635

3736
if (this._previewsLayout.length === 0) {
38-
this.previews.set(previewInfos);
37+
this.previews.set([new PreviewInfo(portInfo)]);
3938
} else {
4039
this._previewsLayout = [...this._previewsLayout];
4140
this.previews.set(this._previewsLayout);
@@ -60,16 +59,15 @@ export class PreviewsStore {
6059

6160
const previewInfos = previews.map((preview) => {
6261
const info = new PreviewInfo(preview);
62+
const portInfo = this._availablePreviews.get(info.port);
6363

64-
let previewInfo = this._availablePreviews.find((availablePreview) => PreviewInfo.equals(info, availablePreview));
65-
66-
if (!previewInfo) {
67-
previewInfo = info;
68-
69-
this._availablePreviews.push(previewInfo);
64+
if (!portInfo) {
65+
this._availablePreviews.set(info.port, info.portInfo);
66+
} else {
67+
info.portInfo = portInfo;
7068
}
7169

72-
return previewInfo;
70+
return info;
7371
});
7472

7573
let areDifferent = previewInfos.length != this._previewsLayout.length;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export class PortInfo {
2+
constructor(
3+
readonly port: number,
4+
public origin?: string,
5+
public ready?: boolean,
6+
) {}
7+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ describe('PreviewInfo', () => {
7070

7171
it('should have a url with a custom pathname and baseUrl', () => {
7272
const previewInfo = new PreviewInfo('3000/foo');
73-
previewInfo.baseUrl = 'https://example.com';
73+
previewInfo.portInfo.origin = 'https://example.com';
7474

7575
expect(previewInfo.url).toBe('https://example.com/foo');
7676
});
Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { PreviewSchema } from '@tutorialkit/types';
2+
import { PortInfo } from './port-info.js';
23

34
export class PreviewInfo {
4-
port: number;
5-
ready: boolean;
5+
portInfo: PortInfo;
6+
67
title?: string;
7-
baseUrl?: string;
88
pathname?: string;
99

1010
get url(): string | undefined {
@@ -15,27 +15,41 @@ export class PreviewInfo {
1515
return undefined;
1616
}
1717

18-
constructor(preview: Exclude<PreviewSchema, boolean>[0], ready?: boolean) {
19-
if (typeof preview === 'number') {
20-
this.port = preview;
18+
get port() {
19+
return this.portInfo.port;
20+
}
21+
22+
get baseUrl() {
23+
return this.portInfo.origin;
24+
}
25+
26+
get ready() {
27+
return this.portInfo.ready;
28+
}
29+
30+
constructor(preview: PortInfo | Exclude<PreviewSchema, boolean>[0], ready?: boolean) {
31+
if (preview instanceof PortInfo) {
32+
this.portInfo = preview;
33+
} else if (typeof preview === 'number') {
34+
this.portInfo = new PortInfo(preview);
2135
} else if (typeof preview === 'string') {
2236
const [port, ...rest] = preview.split('/');
23-
this.port = parseInt(port);
37+
this.portInfo = new PortInfo(parseInt(port));
2438
this.pathname = rest.join('/');
2539
} else if (Array.isArray(preview)) {
26-
this.port = preview[0];
40+
this.portInfo = new PortInfo(preview[0]);
2741
this.title = preview[1];
2842
this.pathname = preview[2];
2943
} else {
30-
this.port = preview.port;
44+
this.portInfo = new PortInfo(preview.port);
3145
this.title = preview.title;
3246
this.pathname = preview.pathname;
3347
}
3448

35-
this.ready = !!ready;
49+
this.portInfo.ready ||= !!ready;
3650
}
3751

3852
static equals(a: PreviewInfo, b: PreviewInfo) {
39-
return a.port === b.port && a.pathname === b.pathname && a.title === b.title;
53+
return a.portInfo.port === b.portInfo.port && a.pathname === b.pathname && a.title === b.title;
4054
}
4155
}

0 commit comments

Comments
 (0)