@electric-sql/y-electric
Version:
YJS network provider for ElectricSQL
113 lines (105 loc) • 4.68 kB
text/typescript
import {
GetExtensions,
Offset,
Row,
ShapeStreamOptions,
} from '@electric-sql/client'
import * as decoding from 'lib0/decoding'
import * as awarenessProtocol from 'y-protocols/awareness'
import * as Y from 'yjs'
export type ConnectivityStatus = `connected` | `disconnected` | `connecting`
/**
* A function that handles send errors.
* @param response The http response from the server if the server returned a response.
* @param error An exception raised by the fetch client if the server did not return a response.
* @returns A promise that resolves to true if the send request should be retried.
*/
export type SendErrorRetryHandler = ({
response,
error,
}: {
response?: Response
error?: unknown
}) => Promise<boolean>
/**
* The Observable interface for the YElectric provider.
*
* @event resumeState emitted when the provider sends or receives an update. This is mainly consumed by ResumeStateProvider to persist the resume state.
* @event sync Emitted when the provider receives an up-to-date control message from the server, meaning that the client caught up with latest changes from the server.
* @event synced same as @event sync.
* @event status Emitted when the provider's connectivity status changes.
* @event "connection-close" Emitted when the client disconnects from the server, by unsubscribing from shapes.
*/
export type YProvider = {
resumeState: (resumeState: ResumeState) => void
sync: (state: boolean) => void
synced: (state: boolean) => void
status: (status: {
status: `connecting` | `connected` | `disconnected`
}) => void
// eslint-disable-next-line quotes
'connection-close': () => void
}
/**
* The Observable interface for a ResumeStateProvider
* A resume state provider is used to persist the sync state of a document
* This is composed of:
* - The document shape offset and handle
* - The state vector of the document synced to the server (optional)
*/
export type ElectricResumeStateProvider = {
synced: (state: ResumeState) => void
}
/**
* Options for the ElectricProvider.
*
* @template RowWithDocumentUpdate The type of the row that contains the document update.
* @template RowWithAwarenessUpdate (optional) The type of the row that contains the awareness update.
* @param documentUpdates Options for the document updates.
* @param documentUpdates.shape Options for the document updates shape.
* @param documentUpdates.sendUrl The URL to send the document updates to.
* @param documentUpdates.getUpdateFromRow A function that returns the update column from the row.
* @param documentUpdates.sendErrorRetryHandler (optional) A function that handles send errors.
* @param awarenessUpdates (optional) Options for the awareness updates.
* @param awarenessUpdates.shape Options for the awareness updates shape.
* @param awarenessUpdates.sendUrl The URL to send the awareness updates to.
* @param awarenessUpdates.getUpdateFromRow A function that returns the update column from the row.
* @param awarenessUpdates.sendErrorRetryHandler (optional) A function that handles send errors.
* @param resumeState (optional) The resume state to use for the provider. If no resume state the provider will fetch the entire shape.
* @param connect (optional) Whether to automatically connect upon initialization.
* @param fetchClient (optional) Custom fetch implementation to use for send requests.
* @param debounceMs (optional) Debounce window in milliseconds for sending document updates. If 0 or undefined, debouncing is disabled and updates are sent immediately.
*/
export type ElectricProviderOptions<
RowWithDocumentUpdate extends Row<decoding.Decoder>,
RowWithAwarenessUpdate extends Row<decoding.Decoder> = never,
> = {
doc: Y.Doc
documentUpdates: {
shape: ShapeStreamOptions<GetExtensions<RowWithDocumentUpdate>>
sendUrl: string | URL
getUpdateFromRow: (row: RowWithDocumentUpdate) => decoding.Decoder
sendErrorRetryHandler?: SendErrorRetryHandler
}
awarenessUpdates?: {
shape: ShapeStreamOptions<GetExtensions<RowWithAwarenessUpdate>>
sendUrl: string | URL
protocol: awarenessProtocol.Awareness
getUpdateFromRow: (row: RowWithAwarenessUpdate) => decoding.Decoder
sendErrorRetryHandler?: SendErrorRetryHandler
}
resumeState?: ResumeState
connect?: boolean
fetchClient?: typeof fetch
debounceMs?: number
}
export type ResumeState = {
document?: {
offset: Offset
handle: string
}
// The vector of the document at the time of the last sync.
// When the provider starts, it batches the diff between this
// vector and the current state of the document to send upstream.
stableStateVector?: Uint8Array
}