Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f4f85af

Browse files
committed
Make the Ruby VM a singleton
1 parent 8faf636 commit f4f85af

File tree

3 files changed

+52
-16
lines changed

3 files changed

+52
-16
lines changed

docs/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ textarea {
1616
height: 100%;
1717
width: 100%;
1818
}
19+
20+
.loading {
21+
color: #ccc;
22+
}

src/Tree.tsx

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1-
import React, { useEffect, useMemo, useState } from "react";
1+
import React, { useEffect, useState } from "react";
22

33
import createRuby, { Ruby } from "./createRuby";
44

5+
// Create a singleton since we don't actually want there to be multiple virtual
6+
// machines running even if there are multiple Tree components.
7+
let ruby: Ruby = {
8+
prettyPrint(source) {
9+
return "Loading...";
10+
}
11+
};
12+
13+
// Track a state that represents where the ruby constant is at any given time.
14+
let rubyState: "initial" | "creating" | "ready" = "initial";
15+
516
function prettyPrint(ruby: Ruby, value: string) {
617
try {
718
return ruby.prettyPrint(value);
@@ -17,23 +28,36 @@ type TreeProps = {
1728
};
1829

1930
const Tree: React.FC<TreeProps> = ({ cols, value }) => {
20-
const [ruby, setRuby] = useState<Ruby>(null);
21-
const [output, setOutput] = useState<string>("");
31+
const [output, setOutput] = useState<string>(() => prettyPrint(ruby, value));
2232

2333
useEffect(() => {
24-
createRuby().then((ruby) => {
25-
setRuby(ruby);
26-
setOutput(prettyPrint(ruby, value));
27-
});
28-
}, []);
29-
30-
useMemo(() => {
31-
if (ruby) {
32-
setOutput(prettyPrint(ruby, value));
34+
switch (rubyState) {
35+
case "initial":
36+
rubyState = "creating";
37+
38+
createRuby().then((newRuby) => {
39+
ruby = newRuby;
40+
rubyState = "ready";
41+
setOutput(prettyPrint(ruby, value));
42+
});
43+
44+
break;
45+
case "creating":
46+
break;
47+
case "ready":
48+
setOutput(prettyPrint(ruby, value));
49+
break;
3350
}
34-
}, [ruby, value]);
35-
36-
return <textarea cols={cols} value={output} readOnly />;
51+
}, [value]);
52+
53+
return (
54+
<textarea
55+
className={rubyState != "ready" ? "loading" : ""}
56+
cols={cols}
57+
value={output}
58+
readOnly
59+
/>
60+
);
3761
};
3862

3963
export default Tree;

src/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@ import { createRoot } from "react-dom/client";
44
import Editor from "./Editor";
55
const Tree = React.lazy(() => import("./Tree"));
66

7+
type TreeFallbackProps = {
8+
cols: number
9+
};
10+
11+
const TreeFallback: React.FC<TreeFallbackProps> = ({ cols }) => (
12+
<textarea className="loading" cols={cols} readOnly>Loading...</textarea>
13+
);
14+
715
const App: React.FC = () => {
816
const [source, setSource] = useState<string>("1 + 2");
917
const cols = 80;
1018

1119
return (
1220
<>
1321
<Editor cols={cols} value={source} onChange={setSource} />
14-
<Suspense fallback={<textarea cols={cols} readOnly />}>
22+
<Suspense fallback={<TreeFallback cols={cols} />}>
1523
<Tree cols={cols} value={source} />
1624
</Suspense>
1725
</>

0 commit comments

Comments
 (0)