Skip to content

Commit

Permalink
docs: clarify when await shape.synced resolves. (#1380)
Browse files Browse the repository at this point in the history
Addresses some of the suggestions in #1365.

---------

Co-authored-by: msfstef <[email protected]>
  • Loading branch information
thruflo and msfstef committed Jun 20, 2024
1 parent daced22 commit a94e860
Show file tree
Hide file tree
Showing 17 changed files with 59 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/friendly-dancers-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"electric-sql": patch
---

Add clarifying documentation on behaviour `synced` promise returned by the `sync` API.
14 changes: 14 additions & 0 deletions clients/typescript/src/client/model/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ export interface Model<
ScalarFieldEnum,
GetPayload extends HKT
> {
/**
* Subscribes to the given shape, returnig a {@link ShapeSubscription} object which
* can be used to wait for the shape to sync initial data.
*
* NOTE: If you establish a shape subscription that has already synced its initial data,
* awaiting `shape.synced` will always resolve immediately as shape subscriptions are persisted.
* i.e.: imagine that you re-sync the same shape during subsequent application loads.
* Awaiting `shape.synced` a second time will only ensure that the initial
* shape load is complete. It does not ensure that the replication stream
* has caught up to the central DB's more recent state.
*
* @param i - The shape to subscribe to
* @returns A shape subscription
*/
sync<T extends SyncInput<Include, Where>>(i?: T): Promise<ShapeSubscription>

/**
Expand Down
8 changes: 8 additions & 0 deletions clients/typescript/src/satellite/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ type ChangeAccumulator = {

export type ShapeSubscription = {
key: string
/**
* A promise that will resolve once the subscription has synced
* the initial data for the shape.
*
* NOTE: This does not wait for the most recent data changes to
* be synced into the local database, only an initial data batch
* required to establish the subesequent data replication.
*/
synced: Promise<void>
}

Expand Down
6 changes: 5 additions & 1 deletion docs/usage/data-access/shapes.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ The current filtering implementation does not support non-deterministic function
The [`sync`](../../api/clients/typescript.md#sync-method) function resolves to an object containing a promise:

1. the first `sync()` promise resolves when the shape subscription has been confirmed by the server (the sync service)
2. the second `synced` promise resolves when the data in the shape has fully synced onto the local device
2. the second `synced` promise resolves when the initial data load for the shape has synced onto the local device

```tsx
// Resolves once the shape subscription
Expand All @@ -197,6 +197,10 @@ await shape.synced

If the shape subscription is invalid, the first promise will be rejected. If the data load fails for some reason, the second promise will be rejected.

:::note
If you establish a shape subscription that has already synced its initial data, awaiting `shape.synced` will always resolve immediately. I.e.: imagine that you re-run the code above on subsequent page loads. Awaiting `shape.synced` a second time will only ensure that the initial shape load is complete. It does not ensure that the replication stream has caught up.
:::

### Data loading

Data synced onto the local device via a shape subscription appears atomically in the local database. I.e.: it all loads within a single transaction.
Expand Down
3 changes: 2 additions & 1 deletion examples/expo/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const Example = () => {
// Resolves when the shape subscription has been established.
const shape = await db.items.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
}

Expand Down
3 changes: 2 additions & 1 deletion examples/react-native/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const Example = () => {
// Resolves when the shape subscription has been established.
const shape = await db.items.sync();

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const ActivityEventsExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.activity_events.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export const BackgroundJobsExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.background_jobs.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
3 changes: 2 additions & 1 deletion examples/recipes/src/chat_room/ChatRoomExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export const ChatRoomExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.chat_room.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
3 changes: 2 additions & 1 deletion examples/recipes/src/data_viewer/DataViewerExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const DataViewerExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.commerce_orders.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
3 changes: 2 additions & 1 deletion examples/recipes/src/log_viewer/LogViewerExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const LogViewerExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.logs.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export const MonitoringMetricsExample = () => {
// Resolves when the shape subscription has been established.
const shape = await db.monitoring.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export const RequestResponseExample = () => {
},
})

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
setSynced(true)
}
Expand Down
3 changes: 2 additions & 1 deletion examples/tauri-sqlite/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ const ExampleComponent = () => {
// Resolves when the shape subscription has been established.
const shape = await db.items.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
}

Expand Down
3 changes: 2 additions & 1 deletion examples/web-pglite/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const Example = () => {
// Resolves when the shape subscription has been established.
const shape = await db.items.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
}

Expand Down
4 changes: 3 additions & 1 deletion examples/web-wa-sqlite-vuejs/src/ElectricProvider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ onMounted(async () => {
// Resolves when the shape subscription has been established.
const shape = await client.db.items.sync()
// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
electric.value = client
})
Expand Down
3 changes: 2 additions & 1 deletion examples/web-wa-sqlite/src/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export const Example = () => {
// Resolves when the shape subscription has been established.
const shape = await db.items.sync()

// Resolves when the data has been synced into the local database.
// Resolves when the initial data for the shape
// has been synced into the local database.
await shape.synced
}

Expand Down

0 comments on commit a94e860

Please sign in to comment.