https://github.com/ash-project/ash_sync
Real-time sync for Postgres-backed Ash & Phoenix applications.
https://github.com/ash-project/ash_sync
Last synced: 3 days ago
JSON representation
Real-time sync for Postgres-backed Ash & Phoenix applications.
- Host: GitHub
- URL: https://github.com/ash-project/ash_sync
- Owner: ash-project
- Created: 2025-05-18T22:04:37.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2025-05-20T23:23:36.000Z (about 1 month ago)
- Last Synced: 2025-06-25T04:15:39.622Z (7 days ago)
- Language: Elixir
- Size: 25.4 KB
- Stars: 20
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-ash-framework - ash_sync - Real-time sync for Postgres-backed Ash & Phoenix applications. (Extensions / other)
- awesome-ash-framework - ash_sync - Real-time sync for Postgres-backed Ash & Phoenix applications. (Extensions / other)
README
# AshSync
AshSync is a declarative wrapper around `Phoenix.Sync` meant for Ash applications.
## Status
I've laid out some patterns for what this should look like, and set up the typescript code generation process. **I need someone to champion this from here on.** See the #todo comments for more.
updating/deleting items in a collection does not appear to be working due to a client bug that I have not yet figured out.
the basic example app I'm working from is here: https://github.com/zachdaniel/ash_sync_example
## Setup
AshSync currently expects an idiomatic front end Phoenix w/ js setup that has the following dependencies added to the `package.json` in `assets`.
- `"@electric-sql/react"`
- `"@tanstack/db"`
- `"@tanstack/db-collections"`
- `"@tanstack/react-db"`
- `"react"`
- `"react-dom"`
- `"uuid"`
- `"zod"`We generate the following files, which can be used by the js in your front end.
- `assets/js/client/ingest.ts` - used to ingest changes from tanstack db to the sync endpoint
- `assets/js/client/queries.ts` - Functions to directly use shape streams from electricSQL
- `assets/js/client/collections.ts` - Functions to create ElectricCollections which sync back to sync endpoint
- `assets/js/client/schema.ts` - Types for resources being synchronizedTo regenerate them, use `mix ash.codegen `. Needing to provide a name is inconvenient. We will remove that requirement in the future.
Add the following to your router:
```elixir
scope "/", MyAppWeb do
pipe_through :browserget "/sync", SyncController, :sync
post "/ingest/mutations", SyncController, :sync_mutate
end
```And define the controller
```elixir
defmodule MyAppWeb.SyncController do
use Phoenix.Controller, formats: [:html, :json]def sync(conn, params) do
AshSync.sync_render(:my_app, conn, params)
enddef sync_mutate(conn, params) do
AshSync.sync_mutate(:my_app, conn, params)
end
end
```## And then define queries to sync in your domain(s)
```elixir
defmodule MyApp.Blog do
use Ash.Domain,
extensions: [AshSync],
otp_app: :my_appsync do
resource MyApp.Blog.Post do
query :list_blog_posts, :read do
on_insert :create
on_update :update
on_delete :destroy
end
end
endresources do
resource MyApp.Blog.Post
end
end
```## Limitations
ElectricSQL has a lot of limitations around what can be synchronized via shapes.
This project does nothing to enable anything beyond that, so the queries you build will be limited in that way.A major example is that you cannot `join` in queries that are synchronized. One way to get around this, for example, is to denormalize your data such that all of the information you need to authorize or accomplish a read is on the table itself.