PhoenixKit.Modules.Sync.Client (phoenix_kit v1.7.63)

Copy Markdown View Source

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

client()

@type client() :: pid()

connect_opts()

@type connect_opts() :: [timeout: pos_integer(), receiver_info: map()]

transfer_opts()

@type transfer_opts() :: [
  strategy: :skip | :overwrite | :merge | :append,
  batch_size: pos_integer(),
  create_missing_tables: boolean()
]

Functions

connect(url, code, opts \\ [])

@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 sender
  • opts - 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"}
)

connected?(client)

@spec connected?(client()) :: boolean()

Checks if the client is still connected.

disconnect(client)

@spec disconnect(client()) :: :ok

Disconnects from the remote sender.

Examples

:ok = Client.disconnect(client)

fetch_records(client, table, opts \\ [])

@spec fetch_records(client(), String.t(), keyword()) :: {:ok, map()} | {:error, any()}

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)

get_count(client, table, opts \\ [])

@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

get_schema(client, table, opts \\ [])

@spec get_schema(client(), String.t(), keyword()) :: {:ok, map()} | {:error, any()}

Gets the schema for a table on the remote sender.

Examples

{:ok, schema} = Client.get_schema(client, "users")
# => %{table: "users", columns: [...], primary_key: ["id"]}

list_tables(client, opts \\ [])

@spec list_tables(
  client(),
  keyword()
) :: {:ok, [map()]} | {:error, any()}

Lists all available tables on the remote sender.

Examples

{:ok, tables} = Client.list_tables(client)
# => [%{"name" => "users", "estimated_count" => 150}, ...]

transfer(client, table, opts \\ [])

@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:

  1. Gets the table schema from the sender
  2. Creates the table locally if it doesn't exist (optional)
  3. Fetches all records with auto-pagination
  4. 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
)

transfer_all(client, opts \\ [])

@spec transfer_all(
  client(),
  keyword()
) :: {:ok, map()} | {:error, any()}

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}
)