Skip to content

Commit

Permalink
Switch to monaco editor for playground and put parser in worker
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiebern committed May 17, 2020
1 parent c49ef57 commit b3f7e0f
Show file tree
Hide file tree
Showing 15 changed files with 1,771 additions and 1,564 deletions.
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ I will update the playground from time to time. It's not great yet, I just wante
- [ ] Lexing / Parsing

- [x] Include lexing positions for better error messages
- [ ] Ignore or warn unknown structures
- [ ] Basic
- [x] Basic
- [x] Any
- [x] Void
- [x] Boolean
Expand All @@ -39,7 +38,6 @@ I will update the playground from time to time. It's not great yet, I just wante
- [x] Undefined
- [x] Symbol
- [x] Reference
- [ ] Special modifier keywords (`e.g. Required<{...}>`)
- [x] Type extraction (`e.g. x['field']`)
- [x] Array
- [x] Tuple
Expand All @@ -48,12 +46,14 @@ I will update the playground from time to time. It's not great yet, I just wante
- [x] Simple Nullable / Optional
- [x] String unions
- [x] Int unions
- [ ] Mixed unions
- [x] Mixed unions
- [ ] Union of types
- [ ] Enum
- [x] Keys
- [ ] Default values
- [ ] Computed values
- [ ] Const enums
- [ ] Intersection types
- [ ] Interfaces / Objects
- [x] Keyword
- [x] Keys
Expand Down Expand Up @@ -81,32 +81,35 @@ I will update the playground from time to time. It's not great yet, I just wante
- [x] Aliased
- [x] Star aliased
- [x] List of named
- [ ] Namespaces
- [ ] Exports
- [ ] Mutators
- [ ] Generics
- [ ] Type Parameters
- [ ] Type definition
- [ ] Interfaces
- [ ] Classes
- [ ] Extends keyword

- [ ] Decoding
- [ ] Treat generics that get used in their type as not actually creating a type def as it needs to be called somewhere to be resolved (`type ab<A,B> = { a: A, b: B };`)
- [ ] Treat type parameters that get used in their type as not actually creating a type def as it needs to be called somewhere to be resolved (`type ab<A,B> = { a: A, b: B };`)
- [ ] Create representation
- [x] Basic types
- [x] Interfaces
- [x] Nested
- [x] Arrays / Lists
- [ ] Enums
- [ ] Unions
- [x] Unions
- [ ] Functions
- [ ] Classes
- [ ] Intersection types
- [ ] Type Parameters
- [ ] Throw error if 2 type parameters have the same name
- [x] Abstracted file loader to resolve import / exports (should work both on web / native)
- [ ] Implement separate file loaders
- [x] Resolve extension refs for the current type (finalize all fields)
- [x] Flattened type tree
- [x] Solve inline interfaces (e.g. in an array)
- [ ] Mutators
- [ ] Generics
- [ ] Generating
- [x] Valid identifiers (Reserved keywords / uppercase variables)
- [ ] Native (Generate types without bucklescript features)
Expand All @@ -117,6 +120,8 @@ I will update the playground from time to time. It's not great yet, I just wante
- [ ] Unions
- [ ] Functions
- [ ] Classes
- [ ] Intersection types
- [ ] Type Parameters
- [ ] Bucklescript (Make use of bucklescript features, but do not use externals)
- [x] Basic types
- [x] Interfaces
Expand All @@ -126,6 +131,9 @@ I will update the playground from time to time. It's not great yet, I just wante
- [x] Unions
- [ ] Functions
- [ ] Classes
- [ ] Namespaces
- [ ] Intersection types
- [ ] Type Parameters
- [ ] Bucklescript Bindings (Full use of bucklescript features and sensible approach of providing externals)
- [ ] Basic types
- [ ] Interfaces
Expand All @@ -135,6 +143,8 @@ I will update the playground from time to time. It's not great yet, I just wante
- [ ] Functions
- [ ] Classes
- [ ] Exports as externals
- [ ] Intersection types
- [ ] Type Parameters
- [ ] Plugin system
- [ ] ReasonReact
- [ ] Playground
Expand Down
2 changes: 1 addition & 1 deletion bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"ppx-flags": [],
"bsc-flags": ["-bs-super-errors"],
"bs-dependencies": ["reason-react", "re-debouncer"],
"bs-dependencies": ["reason-react", "bs-webworkers"],
"refmt": 3,
"suffix": ".bs.js",
"generate-merlin": true,
Expand Down
5 changes: 5 additions & 0 deletions docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
esy js-release
yarn bs:build
yarn fpack
yarn fpack-worker
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@
</head>
<body>
<div id="app"></div>
<script src="index.js"></script>
<script src="index/index.js"></script>
</body>
</html>
1,615 changes: 1,615 additions & 0 deletions docs/index/index.js

Large diffs are not rendered by default.

1,344 changes: 6 additions & 1,338 deletions docs/index.js → docs/worker/worker.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions esy.lock/index.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions fastpack-worker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"entryPoints": ["lib/js/src_js/Worker.bs.js"],
"outputDir": "docs/worker",
"outputFilename": "worker.js"
}
3 changes: 2 additions & 1 deletion fastpack.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"entryPoints": ["lib/js/src_js/Entry.bs.js"],
"preprocess": []
"outputDir": "docs/index",
"outputFilename": "index.js"
}
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
"scripts": {
"bs:build": "bsb -make-world",
"bs:clean": "bsb -clean-world",
"start": "parcel ./src_js/index.html",
"docs": "esy js-release; yarn bs:build; ./node_modules/.bin/fpack build --dev --mock constants:constants-browserify --mock fs --mock child_process --mock tty --preprocess='\\.css$:style-loader!css-loader'; mv bundle/index.js docs; rm -rf bundle"
"fpack": "./node_modules/.bin/fpack build --dev --mock constants:constants-browserify --mock fs --mock child_process --mock tty --preprocess='\\.css$:style-loader!css-loader'",
"fpack-worker": "./node_modules/.bin/fpack build -c fastpack-worker.json --dev --mock constants:constants-browserify --mock fs --mock child_process --mock tty --preprocess='\\.css$:style-loader!css-loader'",
"docs": "./docs.sh"
},
"devDependencies": {
"bs-platform": "^7.3.2",
Expand All @@ -17,10 +18,11 @@
"style-loader": "^1.2.1"
},
"dependencies": {
"@babel/runtime": "^7.9.6",
"@monaco-editor/react": "^3.3.0",
"ansi_up": "^4.0.4",
"re-debouncer": "^2.1.0",
"bs-webworkers": "^0.2.4",
"react": "^16.13.1",
"react-codemirror": "^1.0.0",
"react-dom": "^16.13.1",
"react-highlight.js": "^1.0.7",
"reason": "^3.3.4",
Expand Down
12 changes: 8 additions & 4 deletions src/bin/Bin.re
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ export declare type Subset<T, U> = {
};
|};
let content = {|
// Variant
/* Comment */
type x = 1 | 'string' | false | 3 | undefined;
type y = number | undefined;
type a = string;
type b<P> = {
field_1: number,
field_2: P
};
type c = b<a>;
|};

let () = {
Expand Down
59 changes: 20 additions & 39 deletions src_js/BsPrinter.re
Original file line number Diff line number Diff line change
@@ -1,53 +1,34 @@
module Reason = {
type a;
[@bs.module "reason"] external printML: a => string = "printML";
[@bs.module "reason"] external printRE: a => string = "printRE";
[@bs.module "reason"] external parseML: string => a = "parseML";
};
let worker = WebWorkers.create_webworker("../worker/worker.js");

module Ansi = {
type t = {ansi_to_html: (. string) => string};
[@bs.new] [@bs.module "ansi_up"] external ansi_up: unit => t = "default";
let instance = ansi_up();
};
let set_printed: ref(option(Belt.Result.t(string, string) => unit)) =
ref(None);
WebWorkers.onMessage(
worker,
(e: WebWorkers.MessageEvent.t) => {
let data = WebWorkers.MessageEvent.data(e);

[@bs.val]
[@bs.module "./../../../_build/default/src/js/re_typescript_js.bc.js"]
external run: string => string = "run";
let run =
Debouncer.makeCancelable(
((value, re, setPrinted: Belt.Result.t(string, string) => unit)) =>
setPrinted(
try(
Ok(
(re ? Reason.printRE : Reason.printML)(
Reason.parseML(run(value)),
),
)
) {
| e =>
Error(
Ansi.instance.ansi_to_html(.
Js.Exn.asJsExn(e)
->Belt.Option.flatMap(Js.Exn.message)
->Belt.Option.getWithDefault("ERROR"),
),
)
},
)
);
switch (set_printed^) {
| None => ()
| Some(set_printed) =>
set_printed(
data##status === "success" ? Ok(data##data) : Error(data##data),
)
};
},
);

let usePrintedValue = (~re=true, value: string) => {
let (printed, setPrinted) = React.useReducer((_, v) => v, Ok(""));
set_printed := Some(setPrinted);

React.useEffect2(
() => {
run.schedule((value, re, setPrinted));
WebWorkers.postMessage(worker, {"value": value, "re": re});

Some(() => {run.cancel()});
None;
},
(re, value),
);

printed;
};
};
42 changes: 12 additions & 30 deletions src_js/Entry.re
Original file line number Diff line number Diff line change
Expand Up @@ -82,29 +82,18 @@ module Highlight = {
"default";
};

module CodeMirror = {
[%bs.raw "require('codemirror/lib/codemirror.css')"];
[%bs.raw "require('codemirror/mode/javascript/javascript')"];
type ts_mode = {
name: string,
typescript: bool,
};
type options = {
lineNumbers: bool,
mode: ts_mode,
theme: string,
};
[@react.component] [@bs.module]
module MonacoEditor = {
[@react.component] [@bs.module "@monaco-editor/react"]
external make:
(
~height: string=?,
~width: string=?,
~language: [@bs.string] [ | `javascript | `typescript],
~value: string,
~onChange: string => unit,
~options: option(options)=?,
~className: option(string)=?,
~preserveScrollPosition: option(bool)=?
~onChange: ('a, string) => unit
) =>
React.element =
"react-codemirror";
"ControlledEditor";
};

module X = {
Expand All @@ -115,19 +104,12 @@ module X = {
let result = BsPrinter.usePrintedValue(~re, v);

<>
<CodeMirror
className="editor"
<MonacoEditor
height="100vh"
width="70vw"
value=v
onChange=setV
preserveScrollPosition=true
options={
lineNumbers: true,
mode: {
name: "javascript",
typescript: true,
},
theme: "monokai",
}
onChange={(_, v) => setV(v)}
language=`typescript
/>
{switch (result) {
| Ok(printed) =>
Expand Down
43 changes: 43 additions & 0 deletions src_js/Worker.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module Reason = {
type a;
[@bs.module "reason"] external printML: a => string = "printML";
[@bs.module "reason"] external printRE: a => string = "printRE";
[@bs.module "reason"] external parseML: string => a = "parseML";
};

module Ansi = {
type t = {ansi_to_html: (. string) => string};
[@bs.new] [@bs.module "ansi_up"] external ansi_up: unit => t = "default";
let instance = ansi_up();
};

[@bs.val]
[@bs.module "./../../../_build/default/src/js/re_typescript_js.bc.js"]
external run: string => string = "run";
let run = (value, re) =>
try(
Ok((re ? Reason.printRE : Reason.printML)(Reason.parseML(run(value))))
) {
| e =>
Error(
Ansi.instance.ansi_to_html(.
Js.Exn.asJsExn(e)
->Belt.Option.flatMap(Js.Exn.message)
->Belt.Option.getWithDefault("ERROR"),
),
)
};

WebWorkers.setWorkerOnMessage(
WebWorkers.self,
(e: WebWorkers.MessageEvent.t) => {
let data = WebWorkers.MessageEvent.data(e);
(
switch (run(data##value, data##re)) {
| Ok(data) => {"status": "success", "data": data}
| Error(data) => {"status": "error", "data": data}
}
)
|> WebWorkers.postMessageFromWorker;
},
);
Loading

0 comments on commit b3f7e0f

Please sign in to comment.