/ concept-collection / stan-web-ide
Sign in
concept-collection / stan-web-ide
stan-web-ide / src / stan / settings.ts
54 lines · 1.8 KBCodeBlameHistory
21efcb6stan web IDE: run Stan sampling in the browserJeremy Magland 1// The Stan compilation server: compiling .stan source to WebAssembly needs a
2// server (stan-playground's stan-wasm-server; see the README). The URL is a
3// user setting persisted in localStorage, shared by all projects.
4//
5// Note the server's CORS allowlist must include this app's origin. The stock
6// docker image (ghcr.io/flatironinstitute/stan-wasm-server) allows
7// http://127.0.0.1:3000 and http://127.0.0.1:4173 — which is why dev/preview
8// run on those ports.
10const SERVER_URL_KEY = 'stan-web-ide.compileServerUrl';
12export const DEFAULT_SERVER_URL = 'http://localhost:8083';
13export const LOCAL_SERVER_DOCKER_COMMAND =
14 'docker run -p 8083:8080 -it ghcr.io/flatironinstitute/stan-wasm-server:latest';
16type Listener = (url: string) => void;
17const listeners = new Set<Listener>();
19export function getServerUrl(): string {
20 return localStorage.getItem(SERVER_URL_KEY) || DEFAULT_SERVER_URL;
23export function setServerUrl(url: string): void {
24 const trimmed = url.trim().replace(/\/+$/, '');
25 if (trimmed) {
26 localStorage.setItem(SERVER_URL_KEY, trimmed);
27 } else {
28 localStorage.removeItem(SERVER_URL_KEY);
29 }
30 for (const listener of listeners) {
31 listener(getServerUrl());
32 }
35export function onDidChangeServerUrl(listener: Listener): { dispose(): void } {
36 listeners.add(listener);
37 return { dispose: () => listeners.delete(listener) };
40/** GET {serverUrl}/probe — true when the compile server is reachable. */
41export async function probeServer(url: string): Promise<boolean> {
42 if (!url.startsWith('http://') && !url.startsWith('https://')) {
43 return false;
44 }
45 try {
46 const controller = new AbortController();
47 const timer = setTimeout(() => controller.abort(), 5000);
48 const response = await fetch(`${url}/probe`, { signal: controller.signal });
49 clearTimeout(timer);
50 return response.ok;
51 } catch {
52 return false;
53 }
moveopenescclose