Skip to content

Commit e08320b

Browse files
committed
js: events api
1 parent 4ad1bbc commit e08320b

File tree

17 files changed

+140
-102
lines changed

17 files changed

+140
-102
lines changed

examples/eval-in-wasm/lib/eval_in_wasm.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule EvalInWasm do
1111

1212
@impl GenServer
1313
def init(_args) do
14-
Wasm.register(@process_name)
14+
Wasm.set_default_receiver(@process_name)
1515
{:ok, nil}
1616
end
1717

examples/game-of-life/lib/game_of_life.ex

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ defmodule GameOfLife do
44
executing `run/0` when the app is ready.
55
"""
66

7-
alias Popcorn.Wasm
8-
97
@doc false
108
def child_spec(_arg) do
119
%{
@@ -20,7 +18,6 @@ defmodule GameOfLife do
2018
"""
2119
def run() do
2220
IO.puts("Running...\n")
23-
Wasm.register("noop")
2421
:ignore
2522
end
2623
end

examples/hello-popcorn/lib/hello_popcorn.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ defmodule HelloPopcorn do
99

1010
@impl true
1111
def init(_init_arg) do
12-
Popcorn.Wasm.register(@process_name)
1312
IO.puts("Hello console!")
1413

1514
Popcorn.Wasm.run_js("""

examples/hello-react/ex_app/lib/ex_app.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule ExApp do
99

1010
@impl true
1111
def init(_init_arg) do
12-
Popcorn.Wasm.register(@process_name)
12+
Popcorn.Wasm.set_default_receiver(@process_name)
1313
IO.puts("Hello console!")
1414

1515
# Popcorn.Wasm.run_js("""

examples/iex-wasm/lib/iex_wasm.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ defmodule IexWasm do
1313

1414
@impl GenServer
1515
def init(_args) do
16-
Wasm.register(@process_name)
16+
Wasm.set_default_receiver(@process_name)
1717
type = :elixir
1818
Shell.start_link(type: type)
1919
:ok = ExTTY.send_text(:"#{type}_tty", ":ok\n")

language-tour/elixir_tour/lib/elixir_tour.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule ElixirTour do
2121

2222
@impl GenServer
2323
def init(_init_arg) do
24-
Wasm.register(@process_name)
24+
Wasm.set_default_receiver(@process_name)
2525
:application.set_env(:elixir, :ansi_enabled, false)
2626
{:ok, %{editor_order: [], bindings: %{}}}
2727
end

local-live-view/lib/local_live_view/dispatcher.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule LocalLiveView.Dispatcher do
2121

2222
@impl true
2323
def init(_init_arg) do
24-
Popcorn.Wasm.register(@process_name)
24+
Popcorn.Wasm.set_default_receiver(@process_name)
2525
{:ok, %{views: []}}
2626
end
2727

popcorn/elixir/lib/popcorn.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ defmodule Popcorn do
181181
end
182182
end
183183

184-
no_warn_undefined = [:atomvm | List.wrap(start_module)]
184+
no_warn_undefined = [:atomvm, Popcorn.Wasm | List.wrap(start_module)]
185185

186186
# The module below tries to mimic BEAMs boot script, then start user's app
187187
contents =
@@ -208,6 +208,8 @@ defmodule Popcorn do
208208

209209
{:ok, _apps} = Application.ensure_all_started(unquote(app), :permanent)
210210

211+
Popcorn.Wasm.send_event("popcorn_elixir_ready")
212+
211213
unquote(run)
212214
end
213215
end

popcorn/elixir/lib/popcorn/api/wasm.ex

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,37 @@ defmodule Popcorn.Wasm do
240240
end
241241

242242
@doc """
243-
Notifies JS that Elixir side finished initializing. Can be called only once.
243+
Sends an event to JS side. Fire-and-forget.
244244
"""
245-
def register(main_process_name) do
245+
@spec send_event(String.t()) :: :ok
246+
@spec send_event(String.t(), term()) :: :ok
247+
def send_event(event_name, payload \\ nil) when is_binary(event_name) do
246248
"""
247249
({ wasm, args }) => {
248-
wasm.onElixirReady?.(args.main);
250+
wasm.sendEvent(args.eventName, args.payload)
249251
}
250252
"""
251-
|> run_js(%{main: to_string(main_process_name)})
253+
|> run_js(%{eventName: event_name, payload: payload}, return: :ref)
252254

253255
:ok
254256
end
255257

258+
@doc """
259+
Sets the default receiver process for JS calls/casts.
260+
Registers the calling process under `name` if not already registered.
261+
"""
262+
@spec set_default_receiver(atom()) :: :ok
263+
def set_default_receiver(name) when is_atom(name) do
264+
case Process.whereis(name) do
265+
nil -> Process.register(self(), name)
266+
pid when pid == self() -> :ok
267+
_other -> raise "Name #{name} already registered to another process"
268+
end
269+
270+
send_event("popcorn_set_default_receiver", %{name: to_string(name)})
271+
:ok
272+
end
273+
256274
@doc """
257275
Registers event listener for element with given `selector`. Events will be sent to the process registered under `target` name.
258276
To get event data, specify needed keys in `event_keys` list.

popcorn/elixir/pages/elixir-api.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,38 @@ Represents opaque reference to JS value. Automatically cleaned up when garbage c
1313

1414
## Core Functions
1515

16-
### `register(main_process_name)`
16+
### `send_event(event_name, payload \\ nil)`
1717

18-
Notifies JS that Elixir side finished initializing. Can be called only once.
18+
Sends an event to the JS side. Fire-and-forget.
1919

2020
**Parameters:**
2121

22-
- `main_process_name` (atom or string) - Name of the main process that will receive JS messages by default.
22+
- `event_name` (string) - Name of the event.
23+
- `payload` (any, optional) - Event payload. Default: `nil`.
2324

2425
**Returns:** `:ok`.
2526

2627
**Example:**
2728

2829
```elixir
29-
Popcorn.Wasm.register(:main)
30+
Popcorn.Wasm.send_event("processing_finished", %{id: 123})
31+
Popcorn.Wasm.send_event("simple_event")
32+
```
33+
34+
### `set_default_receiver(name)`
35+
36+
Sets the default receiver process for JS calls/casts. Registers the calling process under `name` if not already registered.
37+
38+
**Parameters:**
39+
40+
- `name` (atom) - Process name to register as default receiver.
41+
42+
**Returns:** `:ok`.
43+
44+
**Example:**
45+
46+
```elixir
47+
Popcorn.Wasm.set_default_receiver(:main)
3048
```
3149

3250
### `handle_message!(raw_message, handler)`

0 commit comments

Comments
 (0)