Skip to content

Commit

Permalink
Merge pull request #1689 from yuvipanda/split-image
Browse files Browse the repository at this point in the history
JS: Move the binderhub API client to its own npm package
  • Loading branch information
manics authored May 3, 2023
2 parents 47da66c + 465c68c commit 9e2e544
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ on:
- ".eslintrc.js"
- "package.json"
- "binderhub/static/js/**"
- "js/**"
push:
paths:
- ".github/workflows/eslint.yml"
- ".eslintrc.js"
- "package.json"
- "binderhub/static/js/**"
- "js/**"
branches-ignore:
- "dependabot/**"
- "pre-commit-ci-update-config"
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
2 changes: 1 addition & 1 deletion binderhub/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { FitAddon } from 'xterm-addon-fit';
import ClipboardJS from 'clipboard';
import 'event-source-polyfill';

import BinderImage from './src/image';
import BinderImage from '@jupyterhub/binderhub-client';
import { makeBadgeMarkup } from './src/badge';
import { getPathType, updatePathText } from './src/path';
import { nextHelpText } from './src/loading';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { NativeEventSource, EventSourcePolyfill } from 'event-source-polyfill';

// Use native browser EventSource if available, and use the polyfill if not available
const EventSource = NativeEventSource || EventSourcePolyfill;

/**
* Build and launch a repository by talking to a BinderHub API endpoint
*/
export default class BinderImage {
/**
*
* @param {string} providerSpec Spec of the form <provider>/<repo>/<ref> to pass to the binderhub API.
* @param {string} baseUrl Base URL (including the trailing slash) of the binderhub installation to talk to.
* @param {string} buildToken Optional JWT based build token if this binderhub installation requires using build tokesn
*/
constructor(providerSpec, baseUrl, buildToken) {
this.providerSpec = providerSpec;
this.baseUrl = baseUrl;
Expand All @@ -11,6 +21,9 @@ export default class BinderImage {
this.state = null;
}

/**
* Call the BinderHub API
*/
fetch() {
let apiUrl = this.baseUrl + "build/" + this.providerSpec;
if (this.buildToken) {
Expand All @@ -20,7 +33,7 @@ export default class BinderImage {
this.eventSource = new EventSource(apiUrl);
this.eventSource.onerror = (err) => {
console.error("Failed to construct event stream", err);
this.changeState("failed", {
this._changeState("failed", {
message: "Failed to connect to event stream\n"
});
};
Expand All @@ -32,16 +45,27 @@ export default class BinderImage {
if (data.phase) {
state = data.phase.toLowerCase();
}
this.changeState(state, data);
this._changeState(state, data);
});
}

/**
* Close the EventSource connection to the BinderHub API if it is open
*/
close() {
if (this.eventSource !== undefined) {
this.eventSource.close();
}
}

/**
* Redirect user to a running jupyter server with given token
* @param {URL} url URL to the running jupyter server
* @param {string} token Secret token used to authenticate to the jupyter server
* @param {string} path The path of the file or url suffix to launch the user into
* @param {string} pathType One of "lab", "file" or "url", denoting what kinda path we are launching the user into
*/
launch(url, token, path, pathType) {
// redirect a user to a running server with a token
if (path) {
Expand Down Expand Up @@ -69,6 +93,13 @@ export default class BinderImage {
window.location.href = url;
}


/**
* Add callback whenever state of the current build changes
*
* @param {str} state The state to add this callback to. '*' to add callback for all state changes
* @param {*} cb Callback function to call whenever this state is reached
*/
onStateChange(state, cb) {
if (this.callbacks[state] === undefined) {
this.callbacks[state] = [cb];
Expand All @@ -77,6 +108,11 @@ export default class BinderImage {
}
}

/**
* @param {string} oldState Old state the building process was in
* @param {string} newState New state the building process is in
* @returns True if transition from oldState to newState is valid, False otherwise
*/
validateStateTransition(oldState, newState) {
if (oldState === "start") {
return (
Expand All @@ -93,7 +129,7 @@ export default class BinderImage {
}
}

changeState(state, data) {
_changeState(state, data) {
[state, "*"].map(key => {
const callbacks = this.callbacks[key];
if (callbacks) {
Expand Down
19 changes: 19 additions & 0 deletions js/packages/binderhub-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@jupyterhub/binderhub-client",
"version": "0.3.0",
"description": "Simple API client for the BinderHub EventSource API",
"main": "lib/index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/jupyterhub/binderhub.git"
},
"author": "Project Jupyter Contributors",
"license": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/jupyterhub/binderhub/issues"
},
"homepage": "https://github.com/jupyterhub/binderhub.js#readme",
"dependencies": {
"event-source-polyfill": "^1.0.31"
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"webpack": "^5.78.0",
"webpack-cli": "^5.0.1"
},
"workspaces": [
"js/packages/binderhub-client"
],
"scripts": {
"webpack": "webpack",
"webpack:watch": "webpack --watch",
Expand Down

0 comments on commit 9e2e544

Please sign in to comment.