Skip to content

Commit f15f712

Browse files
committed
cleanup & docs
1 parent e1114f3 commit f15f712

File tree

6 files changed

+69
-21
lines changed

6 files changed

+69
-21
lines changed

lib/phoenix/sync/client.ex

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,6 @@ defmodule Phoenix.Sync.Client do
123123
Elixir/Ecto types, rather than raw column data in the form `%{"column_name"
124124
=> "column_value"}`.
125125
"""
126-
# stream(Todo, replica: full, client: client)
127-
# stream("todos", where: "...", replica: full, client: client)
128-
# stream(table: "todos", where: "...", replica: full, client: client)
129126
@spec stream(Phoenix.Sync.shape_definition(), Electric.Client.stream_options()) :: Enum.t()
130127
def stream(shape, stream_opts \\ [])
131128

lib/phoenix/sync/predefined_shape.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ defmodule Phoenix.Sync.PredefinedShape do
3737
end
3838

3939
def is_queryable?(q) when is_struct(q, Ecto.Query) or is_struct(q, Ecto.Changeset), do: true
40+
def is_queryable?(_), do: false
4041

4142
def new!(opts, config \\ [])
4243

lib/phoenix/sync/sandbox.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ if Code.ensure_loaded?(Ecto.Adapters.SQL.Sandbox) do
449449
client
450450
end
451451

452+
@doc false
452453
def must_refetch!(shape) do
453454
stack_id = stack_id!()
454455

lib/phoenix/sync/shape.ex

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,20 @@ defmodule Phoenix.Sync.Shape do
1818
end
1919
end
2020
21-
This allows you to `subscribe/2` to the shape and receive notifications and
22-
also retrieve the current dataset:
21+
This allows you to subscribe to the shape and receive notifications and
22+
also retrieve the current dataset.
23+
24+
`to_list/2` will return the current state of the shape as a list:
25+
26+
#{inspect(__MODULE__)}.to_list(MyApp.TodoShape)
27+
[
28+
{~s|"public"."todos"/"1"|, %MyApp.Todo{id: 1}},
29+
{~s|"public"."todos"/"2"|, %MyApp.Todo{id: 2}},
30+
# ...
31+
]
32+
33+
`subscribe/2` registers the current process to receive change events (and
34+
`unsubscribe/1` allows you to stop receiving them):
2335
2436
# use the registered `name` of the shape to receive change events
2537
# within a GenServer or other process
@@ -29,27 +41,14 @@ defmodule Phoenix.Sync.Shape do
2941
end
3042
3143
# handle the shape events...
32-
def handle_info({:sync, ref, {:insert, {_key, todo}}}, ref) do
33-
{:noreply, state}
34-
end
35-
36-
def handle_info({:sync, ref, {:update, {_key, todo}}}, ref) do
44+
def handle_info({:sync, ref, event}, ref) do
45+
dbg(sync_event: event)
3746
{:noreply, state}
3847
end
3948
40-
def handle_info({:sync, ref, {:delete, {_key, todo}}}, ref) do
41-
{:noreply, state}
42-
end
43-
44-
def handle_info({:sync, ref, :up_to_date}, ref) do
45-
{:noreply, state}
46-
end
47-
48-
def handle_info({:sync, ref, :must_refetch}, ref) do
49-
{:noreply, state}
50-
end
5149
"""
5250

51+
@doc false
5352
use GenServer
5453

5554
alias Phoenix.Sync.PredefinedShape
@@ -66,6 +65,48 @@ defmodule Phoenix.Sync.Shape do
6665
@type subscription_msg_type() :: operation() | control()
6766
@type subscribe_opts() :: [{:only, [subscription_msg_type()]} | {:tag, term()}]
6867

68+
@type shape_options() :: [
69+
String.t()
70+
| Ecto.Queryable.t()
71+
| unquote(NimbleOptions.option_typespec(Phoenix.Sync.PredefinedShape.schema()))
72+
| {:name, GenServer.name()}
73+
]
74+
75+
@doc """
76+
Start a new shape process that will receive the sync stream events and
77+
maintain an in-memory copy of the dataset in sync with Postgres.
78+
79+
## Options
80+
81+
Shapes are defined exactly as for `Phoenix.Sync.Client.stream/2`:
82+
83+
# using an `Ecto.Schema` module
84+
{:ok, pid} = #{inspect(__MODULE__)}.start_link(MyApp.Todo)
85+
86+
# or a full `Ecto.Query`
87+
{:ok, pid} = #{inspect(__MODULE__)}.start_link(
88+
from(t in MyApp.Todo, where: t.completed == true)
89+
)
90+
91+
# we can pass extra sync options
92+
{:ok, pid} = #{inspect(__MODULE__)}.start_link(
93+
from(t in MyApp.Todo, where: t.completed == true),
94+
replica: :full
95+
)
96+
97+
but also accept a `:name` much like other `GenServer` processes.
98+
99+
{:ok, pid} = #{inspect(__MODULE__)}.start_link(MyApp.Todo, name: TodosShape)
100+
101+
To start a Shape within a supervision tree, you pass the options as the child
102+
spec as if they were arguments:
103+
104+
children = [
105+
{#{inspect(__MODULE__)}, [MyApp.Todo, name: TodoShape]}
106+
]
107+
108+
"""
109+
@spec start_link(shape_options()) :: GenServer.on_start()
69110
def start_link(args) do
70111
with {:ok, stream_args, shape_opts} <- validate_args(args) do
71112
GenServer.start_link(
@@ -188,11 +229,13 @@ defmodule Phoenix.Sync.Shape do
188229
Enum.map(rows, &elem(&1, 1))
189230
end
190231

232+
@impl GenServer
191233
def init({stream_args, _shape_opts}) do
192234
{:ok, %{stream_pid: nil, table: nil, subscriptions: %{}},
193235
{:continue, {:start_shape, stream_args}}}
194236
end
195237

238+
@impl GenServer
196239
def handle_continue({:start_shape, stream_args}, state) do
197240
{:ok, table_name} = Shape.Registry.register(self())
198241

@@ -225,6 +268,7 @@ defmodule Phoenix.Sync.Shape do
225268
{:noreply, %{state | stream_pid: pid, table: table}}
226269
end
227270

271+
@impl GenServer
228272
def handle_call(:subscribers, _from, state) do
229273
{:reply, Map.keys(state.subscriptions), state}
230274
end
@@ -244,6 +288,7 @@ defmodule Phoenix.Sync.Shape do
244288
{:reply, :ok, %{state | subscriptions: subscriptions}}
245289
end
246290

291+
@impl GenServer
247292
def handle_info({:sync_message, msg}, state) do
248293
state = state |> handle_sync_message(msg) |> notify_subscribers(msg)
249294

lib/phoenix/sync/shape/registry.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Phoenix.Sync.Shape.Registry do
2+
@moduledoc false
3+
24
use GenServer
35

46
def start_link(opts) do

lib/phoenix/sync/shape/supervisor.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
defmodule Phoenix.Sync.Shape.Supervisor do
2+
@moduledoc false
3+
24
use Supervisor
35

46
def start_link(opts) do

0 commit comments

Comments
 (0)