Auto-indexing service and GraphQL API for AT Protocol Records
quickslice.slices.network/
atproto
gleam
graphql
1-module(websocket_ffi_impl).
2-export([send_to_handler/3, send_ping/1, receive_subscription_data/0, select_subscription_data/1]).
3
4%% Send a message to the handler process
5%% The message is a plain {subscription_data, Id, Data} tuple
6%% that will be matched by the selector we registered
7send_to_handler(Pid, SubscriptionId, Data) ->
8 Pid ! {subscription_data, SubscriptionId, Data},
9 nil.
10
11%% Send a ping to trigger handler
12send_ping(Pid) ->
13 Pid ! ping,
14 nil.
15
16%% Check mailbox for subscription_data messages (non-blocking)
17receive_subscription_data() ->
18 receive
19 {subscription_data, SubscriptionId, Data} ->
20 {ok, {SubscriptionId, Data}}
21 after 0 ->
22 {error, nil}
23 end.
24
25%% Add selector branch for {subscription_data, Id, Data} messages
26%% The selector is a Gleam process selector
27%% We use gleam_erlang's select function to add a handler
28select_subscription_data(Selector) ->
29 %% Use gleam@erlang@process:select_record to match the tuple
30 %% The atom is 'subscription_data', tag position is 1 (first element)
31 gleam@erlang@process:select_record(
32 Selector,
33 subscription_data,
34 1,
35 fun(Record) ->
36 %% Decode the record into SubscriptionData
37 %% Record is {subscription_data, Id, Data}
38 Decoder = gleam@dynamic@decode:tuple3(
39 fun(_) -> {ok, nil} end, %% Skip tag
40 gleam@dynamic@decode:string(),
41 gleam@dynamic@decode:string()
42 ),
43 case gleam@dynamic@decode:run(Record, Decoder) of
44 {ok, {_, Id, Data}} ->
45 %% Return SubscriptionData constructor
46 {ok, {subscription_data, Id, Data}};
47 {error, _} ->
48 {error, nil}
49 end
50 end
51 ).