Synchronous client for connecting to a remote DB Sync sender.
This module provides a clean, synchronous API for programmatic data sync. It wraps the asynchronous WebSocketClient to provide blocking operations suitable for scripts, migrations, or AI agent use.
Usage
# Connect to a remote sender
{:ok, client} = PhoenixKit.Modules.Sync.Client.connect("https://sender.com", "ABC12345")
# List available tables
{:ok, tables} = PhoenixKit.Modules.Sync.Client.list_tables(client)
# Get table schema
{:ok, schema} = PhoenixKit.Modules.Sync.Client.get_schema(client, "users")
# Fetch records with pagination
{:ok, result} = PhoenixKit.Modules.Sync.Client.fetch_records(client, "users", limit: 100)
# => %{records: [...], has_more: true, offset: 0}
# Transfer all records from a table (with auto-pagination)
{:ok, result} = PhoenixKit.Modules.Sync.Client.transfer(client, "users", strategy: :skip)
# => %{created: 50, updated: 0, skipped: 5, errors: []}
# Disconnect when done
:ok = PhoenixKit.Modules.Sync.Client.disconnect(client)Connection Options
:timeout- Connection timeout in milliseconds (default: 30_000):receiver_info- Map of receiver identity info to send to sender
Transfer Options
:strategy- Conflict resolution (:skip,:overwrite,:merge,:append):batch_size- Records per batch (default: 500):create_missing_tables- Auto-create tables that don't exist (default: true)
Summary
Functions
Connects to a remote DB Sync sender.
Checks if the client is still connected.
Disconnects from the remote sender.
Fetches a batch of records from a table on the remote sender.
Gets the record count for a table on the remote sender.
Gets the schema for a table on the remote sender.
Lists all available tables on the remote sender.
Transfers all records from a table on the remote sender to the local database.
Transfers multiple tables from the remote sender.
Types
@type client() :: pid()
@type connect_opts() :: [timeout: pos_integer(), receiver_info: map()]
@type transfer_opts() :: [ strategy: :skip | :overwrite | :merge | :append, batch_size: pos_integer(), create_missing_tables: boolean() ]
Functions
@spec connect(String.t(), String.t(), connect_opts()) :: {:ok, client()} | {:error, any()}
Connects to a remote DB Sync sender.
Parameters
url- The sender's base URL (e.g., "https://sender.com")code- The connection code from the senderopts- Connection options
Options
:timeout- Connection timeout in ms (default: 30_000):receiver_info- Map of receiver identity info
Returns
{:ok, client}- Connected client PID{:error, reason}- Connection failed
Examples
{:ok, client} = Client.connect("https://example.com", "ABC12345")
{:ok, client} = Client.connect("https://example.com", "ABC12345",
timeout: 60_000,
receiver_info: %{project: "MyApp", user: "admin@example.com"}
)
Checks if the client is still connected.
@spec disconnect(client()) :: :ok
Disconnects from the remote sender.
Examples
:ok = Client.disconnect(client)
Fetches a batch of records from a table on the remote sender.
Options
:offset- Number of records to skip (default: 0):limit- Maximum records to return (default: 100):timeout- Request timeout in ms (default: 30_000)
Returns
{:ok, %{records: [...], offset: 0, has_more: true}}Examples
{:ok, result} = Client.fetch_records(client, "users", limit: 50, offset: 0)
@spec get_count(client(), String.t(), keyword()) :: {:ok, non_neg_integer()} | {:error, any()}
Gets the record count for a table on the remote sender.
Examples
{:ok, count} = Client.get_count(client, "users")
# => 150
Gets the schema for a table on the remote sender.
Examples
{:ok, schema} = Client.get_schema(client, "users")
# => %{table: "users", columns: [...], primary_key: ["id"]}
Lists all available tables on the remote sender.
Examples
{:ok, tables} = Client.list_tables(client)
# => [%{"name" => "users", "estimated_count" => 150}, ...]
@spec transfer(client(), String.t(), transfer_opts()) :: {:ok, PhoenixKit.Modules.Sync.DataImporter.import_result()} | {:error, any()}
Transfers all records from a table on the remote sender to the local database.
This is a high-level function that:
- Gets the table schema from the sender
- Creates the table locally if it doesn't exist (optional)
- Fetches all records with auto-pagination
- Imports records with the specified conflict strategy
Options
:strategy- Conflict resolution (:skip,:overwrite,:merge,:append):batch_size- Records per batch (default: 500):create_missing_tables- Auto-create tables that don't exist (default: true):timeout- Timeout per request in ms (default: 30_000)
Returns
{:ok, %{created: 50, updated: 0, skipped: 5, errors: []}}Examples
{:ok, result} = Client.transfer(client, "users", strategy: :skip)
{:ok, result} = Client.transfer(client, "posts",
strategy: :overwrite,
batch_size: 1000,
create_missing_tables: true
)
Transfers multiple tables from the remote sender.
Options
:tables- List of table names to transfer (default: all tables):strategy- Conflict resolution for all tables:strategies- Map of table name to strategy (overrides:strategy)- Other options passed to
transfer/3
Returns
{:ok, %{"users" => %{created: 50, ...}, "posts" => %{created: 100, ...}}}Examples
{:ok, results} = Client.transfer_all(client, strategy: :skip)
{:ok, results} = Client.transfer_all(client,
tables: ["users", "posts"],
strategies: %{"users" => :skip, "posts" => :overwrite}
)