Skip to content

Commit ffb3884

Browse files
committed
Create a central spec class
1 parent b02256e commit ffb3884

File tree

6 files changed

+78
-41
lines changed

6 files changed

+78
-41
lines changed

binderhub/static/js/components/BuilderLauncher.jsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Terminal } from "xterm";
44
import { FitAddon } from "xterm-addon-fit";
55
import "xterm/css/xterm.css";
66
import { Progress, PROGRESS_STATES } from "./Progress.jsx";
7+
import { Spec } from "../spec.js";
78

89
/**
910
*
@@ -12,8 +13,6 @@ import { Progress, PROGRESS_STATES } from "./Progress.jsx";
1213
* @param {string} urlPath
1314
*/
1415
function redirectToRunningServer(serverUrl, token, urlPath) {
15-
// Make sure urlPath doesn't start with a `/`
16-
urlPath = urlPath.replace(/^\//, "");
1716
const redirectUrl = new URL(urlPath, serverUrl);
1817
redirectUrl.searchParams.append("token", token);
1918
window.location.href = redirectUrl.toString();
@@ -22,10 +21,9 @@ function redirectToRunningServer(serverUrl, token, urlPath) {
2221
/**
2322
*
2423
* @param {URL} baseUrl
25-
* @param {string} spec
24+
* @param {Spec} spec
2625
* @param {Terminal} term
2726
* @param {FitAddon} fitAddon
28-
* @param {string} urlPath
2927
* @param {(l: boolean) => void} setIsLaunching
3028
* @param {(p: PROGRESS_STATES) => void} setProgressState
3129
* @param {(e: boolean) => void} setEnsureLogsVisible
@@ -35,13 +33,12 @@ async function buildImage(
3533
spec,
3634
term,
3735
fitAddon,
38-
urlPath,
3936
setIsLaunching,
4037
setProgressState,
4138
setEnsureLogsVisible,
4239
) {
4340
const buildEndPointURL = new URL("build/", baseUrl);
44-
const image = new BinderRepository(spec, buildEndPointURL);
41+
const image = new BinderRepository(spec.buildSpec, buildEndPointURL);
4542
// Clear the last line written, so we start from scratch
4643
term.write("\x1b[2K\r");
4744
fitAddon.fit();
@@ -67,7 +64,11 @@ async function buildImage(
6764
case "ready": {
6865
setProgressState(PROGRESS_STATES.SUCCESS);
6966
image.close();
70-
redirectToRunningServer(data.url, data.token, urlPath);
67+
redirectToRunningServer(
68+
data.url,
69+
data.token,
70+
spec.runtimeParams.urlPath,
71+
);
7172
console.log(data);
7273
break;
7374
}
@@ -158,8 +159,7 @@ function ImageLogs({ setTerm, setFitAddon, logsVisible, setLogsVisible }) {
158159
/**
159160
* @typedef {object} BuildLauncherProps
160161
* @prop {URL} baseUrl
161-
* @prop {string} spec
162-
* @prop {string} urlPath
162+
* @prop {Spec} spec
163163
* @prop {boolean} isLaunching
164164
* @prop {(l: boolean) => void} setIsLaunching
165165
* @prop {PROGRESS_STATES} progressState
@@ -171,7 +171,6 @@ function ImageLogs({ setTerm, setFitAddon, logsVisible, setLogsVisible }) {
171171
export function BuilderLauncher({
172172
baseUrl,
173173
spec,
174-
urlPath,
175174
isLaunching,
176175
setIsLaunching,
177176
progressState,
@@ -188,7 +187,6 @@ export function BuilderLauncher({
188187
spec,
189188
term,
190189
fitAddon,
191-
urlPath,
192190
setIsLaunching,
193191
setProgressState,
194192
setLogsVisible,

binderhub/static/js/components/NBViewerIFrame.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1+
import { Spec } from "../spec";
2+
13
/**
24
* @typedef {object} NBViewerIFrameProps
3-
* @prop {string} spec
4-
* @prop {string} urlPath
5+
* @prop {Spec} spec
56
* @param {NBViewerIFrameProps} props
67
* @returns
78
*/
8-
export function NBViewerIFrame({ spec, urlPath }) {
9+
export function NBViewerIFrame({ spec }) {
910
// We only support GitHub links as preview right now
10-
if (!spec.startsWith("gh/")) {
11+
if (!spec.buildSpec.startsWith("gh/")) {
1112
return;
1213
}
1314

14-
const [_, org, repo, ref] = spec.split("/");
15+
const [_, org, repo, ref] = spec.buildSpec.split("/");
1516

16-
urlPath = decodeURI(urlPath);
17+
let urlPath = decodeURI(spec.urlPath);
1718
// Handle cases where urlPath starts with a `/`
1819
urlPath = urlPath.replace(/^\//, "");
1920
let filePath = "";

binderhub/static/js/pages/HomePage.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BuilderLauncher } from "../components/BuilderLauncher.jsx";
33
import { HowItWorks } from "../components/HowItWorks.jsx";
44
import { useEffect, useState } from "react";
55
import { FaviconUpdater } from "../components/FaviconUpdater.jsx";
6+
import { Spec, RuntimeParams } from "../spec.js";
67

78
/**
89
* @typedef {object} HomePageProps
@@ -22,8 +23,8 @@ export function HomePage({ providers, publicBaseUrl, baseUrl }) {
2223
const [progressState, setProgressState] = useState(null);
2324

2425
useEffect(() => {
25-
setSpec(`${selectedProvider.id}/${repo}/${ref}`);
26-
}, [selectedProvider, repo, ref]);
26+
setSpec(new Spec(`${selectedProvider.id}/${repo}/${ref}`, rtp));
27+
}, [selectedProvider, repo, ref, urlPath]);
2728

2829
return (
2930
<>
@@ -62,7 +63,6 @@ export function HomePage({ providers, publicBaseUrl, baseUrl }) {
6263
<BuilderLauncher
6364
baseUrl={baseUrl}
6465
spec={spec}
65-
urlPath={urlPath}
6666
isLaunching={isLaunching}
6767
setIsLaunching={setIsLaunching}
6868
progressState={progressState}

binderhub/static/js/pages/LoadingPage.jsx

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useSearchParams } from "react-router-dom";
55
import { NBViewerIFrame } from "../components/NBViewerIFrame.jsx";
66
import { LoadingIndicator } from "../components/LoadingIndicator.jsx";
77
import { FaviconUpdater } from "../components/FaviconUpdater.jsx";
8+
import { RuntimeParams, Spec } from "../spec.js";
89

910
/**
1011
* @typedef {object} LoadingPageProps
@@ -16,29 +17,17 @@ export function LoadingPage({ baseUrl }) {
1617
const [progressState, setProgressState] = useState(null);
1718

1819
const params = useParams();
19-
const spec = params["*"];
20+
const buildSpec = params["*"];
2021

2122
const [searchParams, _] = useSearchParams();
2223

23-
let urlPath = searchParams.get("urlpath");
24-
if (urlPath === null) {
25-
urlPath = "";
26-
}
27-
28-
// Handle legacy parameters for opening URLs after launching
29-
// labpath and filepath
30-
if (searchParams.has("labpath")) {
31-
// Trim trailing / on file paths
32-
const filePath = searchParams.get("labpath").replace(/(\/$)/g, "");
33-
urlPath = `doc/tree/${encodeURI(filePath)}`;
34-
} else if (searchParams.has("filepath")) {
35-
// Trim trailing / on file paths
36-
const filePath = searchParams.get("filepath").replace(/(\/$)/g, "");
37-
urlPath = `tree/${encodeURI(filePath)}`;
38-
}
39-
4024
const [isLaunching, setIsLaunching] = useState(false);
4125

26+
const spec = new Spec(
27+
buildSpec,
28+
RuntimeParams.fromSearchParams(searchParams),
29+
);
30+
4231
useEffect(() => {
4332
// Start launching after the DOM has fully loaded
4433
setTimeout(() => setIsLaunching(true), 1);
@@ -50,15 +39,14 @@ export function LoadingPage({ baseUrl }) {
5039
<BuilderLauncher
5140
baseUrl={baseUrl}
5241
spec={spec}
53-
urlPath={urlPath}
5442
isLaunching={isLaunching}
5543
setIsLaunching={setIsLaunching}
5644
progressState={progressState}
5745
setProgressState={setProgressState}
5846
/>
5947
<FaviconUpdater progressState={progressState} />
6048

61-
<NBViewerIFrame spec={spec} urlPath={urlPath} />
49+
<NBViewerIFrame spec={spec} />
6250
</>
6351
);
6452
}

binderhub/static/js/spec.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
export class RuntimeParams {
2+
/**
3+
*
4+
* @param {string} urlPath
5+
*/
6+
constructor(urlPath) {
7+
this.urlPath = urlPath;
8+
// Ensure no leading / here
9+
this.urlPath = this.urlPath.replace(/^\/*/, "");
10+
}
11+
12+
/**
13+
*
14+
* @param {URLSearchParams} searchParams
15+
*
16+
* @returns {RuntimeParams}
17+
*/
18+
static fromSearchParams(searchParams) {
19+
let urlPath = searchParams.get("urlpath");
20+
if (urlPath === null) {
21+
urlPath = "";
22+
}
23+
24+
// Handle legacy parameters for opening URLs after launching
25+
// labpath and filepath
26+
if (searchParams.has("labpath")) {
27+
// Trim trailing / on file paths
28+
const filePath = searchParams.get("labpath").replace(/(\/$)/g, "");
29+
urlPath = `doc/tree/${encodeURI(filePath)}`;
30+
} else if (searchParams.has("filepath")) {
31+
// Trim trailing / on file paths
32+
const filePath = searchParams.get("filepath").replace(/(\/$)/g, "");
33+
urlPath = `tree/${encodeURI(filePath)}`;
34+
}
35+
36+
return new RuntimeParams(urlPath);
37+
}
38+
}
39+
40+
export class Spec {
41+
/**
42+
* @param {string} buildSpec
43+
* @param {RuntimeParams} runtimeParams
44+
*/
45+
constructor(buildSpec, runtimeParams) {
46+
this.buildSpec = buildSpec;
47+
this.runtimeParams = runtimeParams;
48+
}
49+
}

tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"module": "es6",
1010
"target": "es5",
1111
"jsx": "react-jsx",
12-
"moduleResolution": "node"
12+
"moduleResolution": "node",
13+
"sourceMap": true
1314
},
1415
"include": ["binderhub/static/js/"]
1516
}

0 commit comments

Comments
 (0)