-
-
Notifications
You must be signed in to change notification settings - Fork 287
/
RunLocal.js
83 lines (70 loc) · 3.23 KB
/
RunLocal.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import immer from "../imports/immer.js"
import { BackendLaunchPhase } from "./Binder.js"
import { timeout_promise } from "./PlutoConnection.js"
import { with_query_params } from "./URLTools.js"
// This file is very similar to `start_binder` in Binder.js
/**
*
* @param {{
* launch_params: import("../components/Editor.js").LaunchParameters,
* setStatePromise: any,
* connect: () => Promise<void>,
* }} props
*/
export const start_local = async ({ setStatePromise, connect, launch_params }) => {
try {
if (launch_params.pluto_server_url == null || launch_params.notebookfile == null) throw Error("Invalid launch parameters for starting locally.")
await setStatePromise(
immer((/** @type {import("../components/Editor.js").EditorState} */ state) => {
state.backend_launch_phase = BackendLaunchPhase.responded
state.disable_ui = false
// Clear the Status of the process that generated the HTML
state.notebook.status_tree = null
})
)
const with_token = (x) => String(x)
const binder_session_url = new URL(launch_params.pluto_server_url, window.location.href)
let open_response
// We download the notebook file contents, and then upload them to the Pluto server.
const notebook_contents = await (
await fetch(new Request(launch_params.notebookfile, { integrity: launch_params.notebookfile_integrity ?? undefined }))
).arrayBuffer()
open_response = await fetch(
with_token(
with_query_params(new URL("notebookupload", binder_session_url), {
name: new URLSearchParams(window.location.search).get("name"),
clear_frontmatter: "yesplease",
execution_allowed: "yepperz",
})
),
{
method: "POST",
body: notebook_contents,
}
)
if (!open_response.ok) {
let b = await open_response.blob()
window.location.href = URL.createObjectURL(b)
return
}
const new_notebook_id = await open_response.text()
const edit_url = with_query_params(new URL("edit", binder_session_url), { id: new_notebook_id })
console.info("notebook_id:", new_notebook_id)
window.history.replaceState({}, "", edit_url)
await setStatePromise(
immer((/** @type {import("../components/Editor.js").EditorState} */ state) => {
state.notebook.notebook_id = new_notebook_id
state.backend_launch_phase = BackendLaunchPhase.notebook_running
})
)
console.log("Connecting WebSocket")
const connect_promise = connect()
await timeout_promise(connect_promise, 20_000).catch((e) => {
console.error("Failed to establish connection within 20 seconds. Navigating to the edit URL directly.", e)
window.parent.location.href = with_token(edit_url)
})
} catch (err) {
console.error("Failed to initialize binder!", err)
alert("Something went wrong! 😮\n\nWe failed to open this notebook. Please try again with a different browser, or come back later.")
}
}