Spaces:
Sleeping
Sleeping
import type { WebContainer } from '@webcontainer/api'; | |
import { atom } from 'nanostores'; | |
export interface PreviewInfo { | |
port: number; | |
ready: boolean; | |
baseUrl: string; | |
} | |
export class PreviewsStore { | |
#availablePreviews = new Map<number, PreviewInfo>(); | |
#webcontainer: Promise<WebContainer>; | |
previews = atom<PreviewInfo[]>([]); | |
constructor(webcontainerPromise: Promise<WebContainer>) { | |
this.#webcontainer = webcontainerPromise; | |
this.#init(); | |
} | |
async #init() { | |
const webcontainer = await this.#webcontainer; | |
webcontainer.on('port', (port, type, url) => { | |
let previewInfo = this.#availablePreviews.get(port); | |
if (type === 'close' && previewInfo) { | |
this.#availablePreviews.delete(port); | |
this.previews.set(this.previews.get().filter((preview) => preview.port !== port)); | |
return; | |
} | |
const previews = this.previews.get(); | |
if (!previewInfo) { | |
previewInfo = { port, ready: type === 'open', baseUrl: url }; | |
this.#availablePreviews.set(port, previewInfo); | |
previews.push(previewInfo); | |
} | |
previewInfo.ready = type === 'open'; | |
previewInfo.baseUrl = url; | |
this.previews.set([...previews]); | |
}); | |
} | |
} | |