Skip to content

Commit 5da7afc

Browse files
committed
Add more docs, release 0.0.3
1 parent 9032c5a commit 5da7afc

File tree

9 files changed

+205
-57
lines changed

9 files changed

+205
-57
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.0.3] - 2021-11-02
10+
Nothing is changed internally, but the GitHub Action is now working as intended.
11+
Publishing the NPM package and the OPAM package (to `jsoo-stdlib` branch for OPAM pinning) is now automated.
12+
913
## [0.0.2] - 2021-11-02
10-
Testing if package is published correctly when we create an release on GitHub.
11-
Also created an OPAM package for js_of_ocaml.
14+
Test if package is published correctly when we create an release on GitHub.
15+
Also create a branch to be used as the standard library for js_of_ocaml.
1216

1317
## [0.0.1] - 2021-10-22
1418
Test publishing to npm.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ An in-browser version may be available in future.
3838
## Documentation
3939

4040
For users:
41+
- [Common options](docs/common_options.md) among all the targets
4142
- [ts2ocaml for js_of_ocaml](docs/js_of_ocaml.md)
4243
- ts2ocaml for ReScript (planned)
4344

4445
For developers and contributors:
45-
- [Overview](docs/development.md)
46+
- [Overview for developers](docs/development.md)
4647
- [Note on modeling TS subtyping in OCaml](docs/modeling_subtyping.md)
4748

4849
## About this tool

build.fsx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ Target.create "TestOnly" ignore
157157

158158
"Build" ==> "Test"
159159

160-
// Deploy targets
160+
// Publish targets
161161

162-
module Deploy =
162+
module Publish =
163163
let changelogFile = "CHANGELOG.md"
164164
let changelog = Changelog.load changelogFile
165165
let newVersion = changelog.LatestEntry.SemVer.AsString
@@ -203,32 +203,32 @@ module Deploy =
203203
let testBuild () =
204204
inDirectory targetDir <| fun () -> dune "build"
205205

206-
Target.create "Deploy" <| fun _ -> ()
207-
Target.create "DeployOnly" <| fun _ -> ()
206+
Target.create "Publish" <| fun _ -> ()
207+
Target.create "PublishOnly" <| fun _ -> ()
208208

209-
Target.create "DeployNpm" <| fun _ ->
210-
Deploy.Npm.updateVersion ()
209+
Target.create "PublishNpm" <| fun _ ->
210+
Publish.Npm.updateVersion ()
211211

212-
Target.create "DeployJsoo" <| fun _ ->
213-
Deploy.Jsoo.copyArtifacts ()
214-
Deploy.Jsoo.updateVersion ()
215-
Deploy.Jsoo.testBuild ()
212+
Target.create "PublishJsoo" <| fun _ ->
213+
Publish.Jsoo.copyArtifacts ()
214+
Publish.Jsoo.updateVersion ()
215+
Publish.Jsoo.testBuild ()
216216

217217
"BuildOnly"
218-
==> "DeployNpm"
219-
==> "DeployJsoo"
220-
==> "DeployOnly"
221-
==> "Deploy"
218+
==> "PublishNpm"
219+
==> "PublishJsoo"
220+
==> "PublishOnly"
221+
==> "Publish"
222222

223-
"TestJsoo" ==> "DeployJsoo"
223+
"TestJsoo" ==> "PublishJsoo"
224224

225-
"Build" ==> "Deploy"
225+
"Build" ==> "Publish"
226226

227227
Target.create "All" ignore
228228

229229
"Build"
230230
==> "Test"
231-
==> "Deploy"
231+
==> "Publish"
232232
==> "All"
233233

234234
// start build

dist_jsoo/dune-project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(lang dune 2.7)
22
(name ts2ocaml-jsoo-stdlib)
3-
(version 0.0.2)
3+
(version 0.0.3)
44

55
(maintainers "[email protected]")
66
(authors

dist_jsoo/ts2ocaml-jsoo-stdlib.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is generated by dune, edit dune-project instead
22
opam-version: "2.0"
3-
version: "0.0.2"
3+
version: "0.0.3"
44
synopsis:
55
"Standard library for ts2ocaml generated bindings (js_of_ocaml target)"
66
description:

docs/development.md

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Modules with **\[\<AutoOpen\>\]** does not require `open` to use.
3939

4040
- OCaml 4.08 or higher
4141
- [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml) should be installed to your opam switch.
42-
- The latest [gen_js_api](https://github.com/LexiFi/gen_js_api) is already present in `test/lib/gen_js_api` as a git submodule. Run `git submodule update --init --recursive`.
42+
- The latest [gen_js_api](https://github.com/LexiFi/gen_js_api) is already present in `test/jsoo/lib/gen_js_api` as a git submodule. Run `git submodule update --init --recursive`.
4343

4444
- Node 14.0 or higher
4545
- [yarn](https://yarnpkg.com/) is required.
@@ -56,17 +56,41 @@ The resulting `dist/ts2ocaml.js` is then ready to run through `node`.
5656

5757
## Testing
5858

59-
`dotnet fake build -t Test` builds the tool (as described above) and then performs the followings:
60-
- Test the tool with the following packages:
59+
`dotnet fake build -t Test` builds the tool and then performs the followings:
60+
61+
### Test the tool for [`js_of_ocaml` target](js_of_ocaml.md)
62+
63+
- Generate bindings for the following packages:
6164
- TypeScript standard libraries (`node_modules/typescript/lib/lib.*.d.ts`)
62-
- `typescript` (binding for TypeScript compiler API)
63-
- `react`
64-
- `scheduler/tracing`
65-
- `csstype`
66-
- `prop-types`
67-
- `react-modal`
68-
- `yargs`
69-
- `yargs-parser`
70-
- The output files will be placed into `output/`
71-
- Copy the resulting OCaml bindings to `test/src/`
72-
- Perform `dune build` in `test/`
65+
- `typescript` with the `full` preset (involving a lot of inheritance)
66+
- `react` with the `full` preset (depending on both `full` packages and `safe` packages)
67+
- `scheduler/tracing` (`safe`)
68+
- `csstype` (`full`)
69+
- `prop-types` (`safe`)
70+
- `react-modal` with the `full` preset (depending on a `full` package)
71+
- `yargs` with the `safe` preset (depending on a `safe` package)
72+
- `yargs-parser` (`safe`)
73+
- The bindings will be placed into `output/test_jsoo/`
74+
- Copy the bindings to `test/jsoo/src/`
75+
- Perform `dune build` in `test/jsoo/`
76+
77+
> Tests for other targets will be added here
78+
79+
## Publishing
80+
81+
`dotnet fake build -t Publish` builds the tool, runs the tests, and then performs the followings:
82+
83+
### Prepare for publishing the standard library for [`js_of_ocaml` target](js_of_ocaml.md) to the `jsoo-stdlib` branch
84+
85+
- Copy `ts2ocaml_*.mli` from `output/test_jsoo/` to `dist_jsoo/src/`
86+
- Copy `ts2ocaml_*.ml` from `test/jsoo/_build/default/src/` to `dist_jsoo/src/`
87+
- Set the correct `version` in `dist_jsoo/dune-project`
88+
- Perform `dune build` in `dist_jsoo/` to generate `.opam` file and check if it compiles
89+
90+
GitHub Action `publish.yml` is configured to push the `dist_jsoo` directory to the `jsoo-stdlib` branch.
91+
92+
### Prepare for publishing the tool to NPM
93+
94+
- Set the correct `version` in `package.json`
95+
96+
GitHub Action `publish.yml` is configured to publish `ts2ocaml` to NPM.

docs/js_of_ocaml.md

Lines changed: 130 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,77 @@
11
ts2ocaml for js_of_ocaml
22
========================
33

4-
Generates binding for js_of_ocaml.
4+
Generates binding for `js_of_ocaml`.
55

66
# Overview
77

8-
TODO
8+
`ts2ocaml` is a powerful tool, but there are so many options and also some caverts.
9+
10+
Therefore, we first provide a walkthrough to use this tool for your project.
11+
12+
The documentation for the `ts2ocaml` command and its options comes after the walkthrough, starting with the [Usage](#usage) setion.
13+
14+
## Requirements
15+
16+
`ts2ocaml` for `js_of_ocaml` generates `.mli` files, which should then be processed with [`LexiFi/gen_js_api`](https://github.com/LexiFi/gen_js_api).
17+
18+
You should use the latest `gen_js_api` as `ts2ocaml` uses the latest features of `gen_js_api`.
19+
As of Oct 2021, most of the required features have not been present in the latest version in opam.
20+
So you would have to either do
21+
22+
* `opam pin add gen_js_api https://github.com/LexiFi/gen_js_api` **(recommended)**, or
23+
* `git submodule` [their repository](https://github.com/LexiFi/gen_js_api) to the `lib` directory of your OCaml project.
24+
- Note that if you use `gen_js_api` via a submodule, it might conflict with [`ts2ocaml-jsoo-stdlib`](#using-ts2ocaml-jsoo-stdlib-package) which is installed via `ocaml pin add`.
25+
- Therefore, this would work only if you are going to do [`ts2ocaml jsoo --create-minimal-lib`](#using---create-minimal-lib--create-minimal-stdlib).
26+
27+
## Adding the standard library
28+
29+
Any bindings to JS packages, not limited to the ones generated by `ts2ocaml`, need a standard library to compile and run, which mainly consists of the bindings to JS and DOM APIs.
30+
31+
Actually, `ts2ocaml` is so powerful that it is capable of generating the standard library for itself.
32+
33+
However, the resulting code is rather big (~20MB in `.ml`, ~40MB in `.cma`), so letting users to generate it themselves and add it to their project is not really a good option. Most users would want to use an OPAM package instead.
34+
35+
Also, we understand not everyone wants to install such a big library, especially when they already have their preferred bindings for JS and DOM APIs. Such users would only want a minimal standard library.
36+
37+
To fulfill both needs, we've made two ways to add the standard library.
38+
39+
### Using `ts2ocaml-jsoo-stdlib` package
40+
41+
This package contains the full bindings for JS, DOM, and Web Worker API, generated with the [`full` preset](#choosing-a-preset).
42+
43+
As described in [Requirements](#requirements), `ts2ocaml` needs the latest `gen_js_api`, which is still not present in OPAM repository.
44+
So, `ts2ocaml-jsoo-stdlib` is currently **not in OPAM repository**.
45+
46+
To install it to your OPAM switch, we recommend you to use [`opam pin`](https://opam.ocaml.org/doc/Usage.html#opam-pin).
47+
48+
The standard library for `ts2ocaml` version `X.Y.Z` is available as the `jsoo-stdlib-vX.Y.Z` tag in this repository.
49+
Check the version of `ts2ocaml` with `ts2ocaml --version` and do the following:
50+
51+
```
52+
opam pin add ts2ocaml-jsoo-stdlib https://github.com/ocsigen/ts2ocaml.git#jsoo-stdlib-vX.Y.Z
53+
```
54+
55+
> **Note:** This may not work while this repo is private. Make sure you have a SSH access to GitHub and use the following instead:
56+
> ```
57+
> opam pin add ts2ocaml-jsoo-stdlib "[email protected]:ocsigen/ts2ocaml.git#jsoo-stdlib-vX.Y.Z"
58+
> ```
59+
60+
### Using [`--create-minimal-lib`](#--create-minimal-stdlib)
61+
62+
`ts2ocaml jsoo --create-minimal-lib` generates a minimal standard library for `ts2ocaml`.
63+
64+
It only contains the following definitions:
65+
* `-'tags intf` type, which is used for [tag-based subtyping](#feature-tag).
66+
* TypeScript-specific primitive types, such as `any`, `never`, `unknown`, etc.
67+
* Utility types for handling TypeScript's union types and intersection types.
68+
69+
You can safely add it to your project, and even modify it for your needs.
70+
71+
Note that you have to modify the bindings generated by `ts2ocaml` to make it work with the minimal standard library.
72+
* Remove the `open Ts2ocaml` statements and then add `open Ts2ocaml_min` (or your own name if you renamed it).
73+
* All the JS, DOM, and Web Worker types are left unknown. You have to replace them with the types from your binding by hand.
74+
- We recommend using [`--preset=minimal`](#choosing-a-preset) when generating bindings, which disables all the features irrelevant to the bindings not from `ts2ocaml`.
975
1076
## Choosing a preset
1177
@@ -31,24 +97,79 @@ See [`--preset`](#--preset) for the options which will be set by each preset.
3197
> **Hint:** if a package `foo` depends only on `bar` and `bar` depends on many other packages,
3298
> it's safe to use `--preset=safe` to `foo` and `--preset=full` to `bar`, but not vice versa.
3399
34-
## Using the generated bindings in your project
100+
## Generating and using the bindings
35101
36-
`ts2ocaml` for `js_of_ocaml` generates `.mli` files, which should then be processed with [LexiFi/gen_js_api](https://github.com/LexiFi/gen_js_api).
102+
Once you figure out which preset (and some additional options if any) to use, you are now ready to run `ts2ocaml`.
37103
38-
You should use the latest `gen_js_api` as `ts2ocaml` uses the latest features of `gen_js_api`.
39-
As of Oct 2021, most of the required features have not been present in the latest version in opam.
40-
So you would have to `git submodule` their repository (`https://github.com/LexiFi/gen_js_api`) to the `lib` directory of your OCaml project.
104+
```
105+
ts2ocaml jsoo --preset safe --output-dir src node_modules/typescript/lib/typescript.d.ts
106+
```
41107
42-
## Standard library
108+
A binding (`typescript.mli` in this example) and a JS stub file `stub.js` will be generated in the `src` directory.
43109
44-
TODO
110+
Modify your `dune` file to include them in your project.
111+
112+
* Use `(js_of_ocaml (javascript_files stub.js))` to include the stub JS to the executable.
113+
* Add a rule to run `gen_js_api` on the generated `.mli` file.
114+
115+
The resulting `dune` will look like below:
116+
117+
```lisp
118+
(executable
119+
(name your_app)
120+
(libraries gen_js_api ts2ocaml-jsoo-stdlib)
121+
(link_flags -no-check-prims)
122+
(preprocess (pps gen_js_api.ppx))
123+
(modes js)
124+
(js_of_ocaml
125+
(javascript_files stub.js)))
126+
127+
(rule
128+
(targets typescript.ml)
129+
(deps typescript.mli)
130+
(action (run %{bin:gen_js_api} %{deps})))
131+
132+
(rule
133+
(targets main.js)
134+
(deps main.bc.js)
135+
(action (run cp %{deps} %{targets})))
136+
137+
(alias
138+
(name DEFAULT)
139+
(deps main.js main.html))
140+
```
141+
142+
> **Note:** if you are using `ts2ocaml-jsoo-stdlib`, don't forget to set [`--profile=release`](https://dune.readthedocs.io/en/latest/dune-files.html?highlight=profile#profile) when running dune!
143+
> There is no dead code elimination without that option, so it would result in a 40MB+ JavaScript executable.
144+
145+
Each binding has an `Export` module which corresponds to the package's default export (`export default ..` or `export = ..` in TypeScript).
146+
147+
Define a module alias to "import" the package:
148+
149+
```ocaml
150+
module TypeScript = Typescript.Export
151+
152+
let () =
153+
Printf.printf "typescript version: %s\n" (TypeScript.version ())
154+
;;
155+
```
156+
> See also the documentation of:
157+
> * [`js_of_ocaml`](http://ocsigen.org/js_of_ocaml/latest/manual/overview)
158+
> * [JavaScript compilation in dune](https://dune.readthedocs.io/en/latest/jsoo.html)
159+
> * [`gen_js_api`](https://github.com/LexiFi/gen_js_api/blob/master/INSTALL_AND_USE.md)
45160
46161
# Usage
47162

48163
```bash
49164
$ ts2ocaml jsoo [options] <inputs..>
50165
```
51166

167+
When multiple input files are given, `ts2ocaml` will merge it to one source file.
168+
169+
`ts2ocaml` will *not* resolve imports and exports between input files, so it can result in a broken binding.
170+
171+
We recommend you to **create one binding for each `.d.ts`**. It works in most of the cases, and it is easy to fix when the binding is broken.
172+
52173
> See also [the common options](common_options.md).
53174
54175
# General Options
@@ -73,8 +194,6 @@ Create `ts2ocaml_min.mli`, which is the minimal standard library for ts2ocaml *w
73194
* DOM API (`Ts2ocaml_dom`), or
74195
* web worker API (`Ts2ocaml_webworker`).
75196

76-
This option is helpful if you have an existing binding for these APIs, and don't want to use ones from the full `Ts2ocaml` [standard library](#standard-library).
77-
78197
When this option is used, ts2ocaml requires no input files. So most of the other options will be ignored.
79198

80199
# Output Options

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ocsigen/ts2ocaml",
3-
"version": "0.0.2",
3+
"version": "0.0.3",
44
"description": "Generate OCaml bindings from TypeScript definitions via the TypeScript compiler API",
55
"repository": {
66
"type": "git",

src/Targets/JsOfOCaml/Common.fs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,18 @@ module Never: sig
273273
]
274274
end
275275
276-
type any = private Ojs.t
276+
type any = Ojs.t
277277
val any_to_js: any -> Ojs.t
278278
val any_of_js: Ojs.t -> any
279279
280280
module Any: sig
281281
type t = any
282282
val t_to_js: t -> Ojs.t
283283
val t_of_js: Ojs.t -> t
284-
val unsafe_cast: t -> 'a
285-
[@@js.custom
286-
let unsafe_cast x = Obj.magic x
287-
]
284+
val cast_from: 'a -> t
285+
[@@js.custom let cast_from x = Obj.magic x]
286+
val unsafe_cast_to: t -> 'a
287+
[@@js.custom let unsafe_cast_to x = Obj.magic x]
288288
end
289289
290290
type unknown = private Ojs.t
@@ -302,12 +302,12 @@ module Unknown: sig
302302
end
303303
304304
[@@@js.stop]
305-
type -'a intf = private Ojs.t
306-
val intf_to_js: ('a -> Ojs.t) -> 'a intf -> Ojs.t
307-
val intf_of_js: (Ojs.t -> 'a) -> Ojs.t -> 'a intf
305+
type -'tags intf = private Ojs.t
306+
val intf_to_js: ('tags -> Ojs.t) -> 'tags intf -> Ojs.t
307+
val intf_of_js: (Ojs.t -> 'tags) -> Ojs.t -> 'tags intf
308308
[@@@js.start]
309309
[@@@js.implem
310-
type -'a intf = Ojs.t
310+
type -'tags intf = Ojs.t
311311
let intf_to_js _ x : Ojs.t = x
312312
let intf_of_js _ x : _ intf = x
313313
]

0 commit comments

Comments
 (0)