Skip to content

Commit e8ea29c

Browse files
Dale-Blackclaude
andcommitted
README: document package compilation registry, arrays, broadcasting
Comprehensive README covering: - What compiles (types, math, arrays, broadcasting) - Package registry API with examples - Built-in Plotly mappings - How to add your own package - js() escape hatch with value passing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 40a22d8 commit e8ea29c

1 file changed

Lines changed: 138 additions & 1 deletion

File tree

README.md

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
<div align="center">
2+
13
# JavaScriptTarget.jl
24

5+
Compile Julia functions to JavaScript.
6+
37
[![CI](https://github.com/GroupTherapyOrg/JavaScriptTarget.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/GroupTherapyOrg/JavaScriptTarget.jl/actions/workflows/ci.yml)
48
[![Docs](https://github.com/GroupTherapyOrg/JavaScriptTarget.jl/actions/workflows/docs.yml/badge.svg)](https://grouptherapyorg.github.io/JavaScriptTarget.jl/)
59
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
610

7-
Compile Julia functions to JavaScript.
11+
</div>
812

913
```julia
1014
import JavaScriptTarget as JST
@@ -19,3 +23,136 @@ println(result.js)
1923
```
2024

2125
Includes a self-hosted [browser playground](https://grouptherapyorg.github.io/JavaScriptTarget.jl/) — type Julia, run it as JS, no server needed.
26+
27+
## What Compiles
28+
29+
| Julia | JavaScript |
30+
|---|---|
31+
| `Int32`, `Int64` | `number` (integer ops use `\|0`) |
32+
| `Float64` | `number` |
33+
| `String` | `string` |
34+
| `Bool` | `boolean` |
35+
| `Vector{T}` | `Array` (`push!`, `getindex`, `length`) |
36+
| `Dict{K,V}` | `Map` |
37+
| `struct` | ES6 `class` |
38+
| `sin`, `cos`, `sqrt`, ... | `Math.sin`, `Math.cos`, `Math.sqrt` |
39+
| `println` | `console.log` |
40+
| `sin.(x)` | `x.map(v => Math.sin(v))` |
41+
| `x .* freq` | `x.map(v => v * freq)` |
42+
| `for i in 1:n` | `while` loop |
43+
44+
## Arrays and Broadcasting
45+
46+
Use `optimize=false` for functions that build arrays:
47+
48+
```julia
49+
function make_data(n::Int, freq::Float64)
50+
x = Float64[]
51+
for i in 1:n
52+
push!(x, Float64(i) * 0.1)
53+
end
54+
y = sin.(x .* freq)
55+
return (x, y)
56+
end
57+
58+
result = JST.compile(make_data, (Int, Float64); optimize=false)
59+
```
60+
61+
Produces:
62+
```javascript
63+
function make_data(n, freq) {
64+
x = [];
65+
// ... for loop with x.push() ...
66+
y = x.map(_b => _b * freq).map(_b => Math.sin(_b));
67+
return [x, y];
68+
}
69+
```
70+
71+
JST auto-detects when `optimize=false` is needed (when the optimized IR contains Julia's internal memory management) and falls back automatically when used via [Therapy.jl](https://github.com/GroupTherapyOrg/Therapy.jl).
72+
73+
## Package Compilation Registry
74+
75+
JST can compile calls to registered Julia packages into their JavaScript equivalents — instead of compiling the package's internal implementation.
76+
77+
### Registering a Package
78+
79+
```julia
80+
import JavaScriptTarget as JST
81+
82+
# Register a function: (module, function_name) → JS compiler
83+
JST.register_package_compilation!(MyPlotLib, :scatter) do ctx, kwargs, pos_args
84+
# kwargs: Dict{Symbol, String} — compiled keyword argument values
85+
# pos_args: Vector{String} — compiled positional argument values
86+
# Return a JS code string
87+
JST.build_js_object_from_kwargs(kwargs; type="scatter")
88+
end
89+
```
90+
91+
The compiler function receives:
92+
- `ctx` — compilation context
93+
- `kwargs` — keyword arguments as `Dict{Symbol, String}` (kwarg name → compiled JS expression)
94+
- `pos_args` — positional arguments as `Vector{String}` (compiled JS expressions)
95+
96+
### Built-in: Plotly
97+
98+
JST ships with Plotly mappings. Register them for any module that exports `scatter`, `Layout`, etc.:
99+
100+
```julia
101+
# Register your module's Plotly-compatible functions
102+
JST.register_plotly_compilations!(MyModule)
103+
```
104+
105+
This maps:
106+
107+
| Julia | JavaScript |
108+
|---|---|
109+
| `scatter(x=x, y=y, mode="lines")` | `{"type":"scatter", "x":x, "y":y, "mode":"lines"}` |
110+
| `Layout(title="Test", xaxis=...)` | `{"title":"Test", "xaxis":...}` |
111+
| `plotly("div-id", traces, layout)` | `Plotly.newPlot(el, traces, layout)` / `Plotly.react(...)` |
112+
113+
### Adding Your Own Package
114+
115+
```julia
116+
module MyPackage
117+
import JavaScriptTarget as JST
118+
119+
# Define Julia functions
120+
my_chart(; data, options=nothing) = Dict("data" => data, "options" => options)
121+
122+
# Register compilation
123+
function __init__()
124+
JST.register_package_compilation!(@__MODULE__, :my_chart) do ctx, kwargs, pos_args
125+
JST.build_js_object_from_kwargs(kwargs)
126+
end
127+
end
128+
end
129+
```
130+
131+
When JST encounters `MyPackage.my_chart(data=x, options=cfg)` in compiled code, it emits `{"data": x, "options": cfg}` instead of trying to compile the function's Julia implementation.
132+
133+
### How It Works
134+
135+
1. Julia's `code_typed` lowers keyword calls to `Core.kwcall(NamedTuple{names}(values), func)`
136+
2. JST extracts the kwarg names from the NamedTuple type parameters
137+
3. The registered compiler function receives the compiled kwarg values
138+
4. The compiler emits the JS equivalent (object literals, function calls, etc.)
139+
140+
The registry is checked for both keyword calls (`Core.kwcall`) and positional calls. Functions are matched by `(parentmodule(fn), nameof(fn))`.
141+
142+
## `js()` Escape Hatch
143+
144+
For direct browser API access, `js()` emits raw JavaScript:
145+
146+
```julia
147+
js("document.title = 'Hello'")
148+
js("console.log('value:', \$1)", my_value) # $1 substituted with compiled expression
149+
```
150+
151+
## Related
152+
153+
- [Therapy.jl](https://github.com/GroupTherapyOrg/Therapy.jl) — Signals-based web framework using JST for compilation
154+
- [Sessions.jl](https://github.com/GroupTherapyOrg/Sessions.jl) — Notebook IDE with JST-powered export
155+
156+
## License
157+
158+
MIT

0 commit comments

Comments
 (0)