import { AuthConfig, AuthState } from '../auth/index.js'; import { DatabaseAdapter } from '../electric/adapter.js'; import { Migrator } from '../migrators/index.js'; import { AuthStateNotification, ChangeOrigin, Notifier, UnsubscribeFunction } from '../notifiers/index.js'; import { QualifiedTablename } from '../util/tablename.js'; import { AdditionalData, ConnectivityState, DbName, LSN, MigrationTable, Relation, RelationsCache, SatelliteError, Statement, Transaction, Uuid, DbRecord as DataRecord, ReplicatedRowTransformer, DataGone, ServerTransaction } from '../util/types.js'; import { SatelliteOpts } from './config.js'; import { Client, Satellite } from './index.js'; import { OplogEntry, ShadowEntry, ShadowEntryChanges } from './oplog.js'; import { Shape, SubscriptionData } from './shapes/types.js'; import { QueryBuilder } from '../migrators/query-builder/index.js'; import { ShapeManager } from './shapes/shapeManager.js'; import { SyncStatus } from '../client/model/shapes.js'; import { ForeignKeyChecks } from '../config/index.js'; export type ShapeSubscription = { key: string; synced: Promise; }; type ThrottleFunction = { cancel: () => void; (): Promise | undefined; }; type MetaEntries = { clientId: Uuid | ''; compensations: number; lsn: string | null; subscriptions: string; seenAdditionalData: string; seenGoneBatch: string; }; export declare class SatelliteProcess implements Satellite { dbName: DbName; adapter: DatabaseAdapter; migrator: Migrator; notifier: Notifier; client: Client; builder: QueryBuilder; opts: SatelliteOpts; fkChecks: ForeignKeyChecks; _authState?: AuthState; _unsubscribeFromAuthState?: UnsubscribeFunction; connectivityState?: ConnectivityState; _unsubscribeFromConnectivityChanges?: UnsubscribeFunction; _pollingInterval?: any; _unsubscribeFromPotentialDataChanges?: UnsubscribeFunction; _throttledSnapshot: ThrottleFunction; _lsn?: LSN; relations: RelationsCache; previousShapeSubscriptions: { keY: string; shapes: Shape[]; }[]; subscriptionManager: ShapeManager; /** * To optimize inserting a lot of data when the subscription data comes, we need to do * less `INSERT` queries, but SQLite/Postgres support only a limited amount of `?`/`$i` positional * arguments. Precisely, its either 999 for SQLite versions prior to 3.32.0 and 32766 for * versions after, and 65535 for Postgres. */ private maxSqlParameters; private snapshotMutex; private performingSnapshot; private _connectRetryHandler; private initializing?; private _removeClientListeners?; constructor(dbName: DbName, adapter: DatabaseAdapter, migrator: Migrator, notifier: Notifier, client: Client, opts: SatelliteOpts); /** * Perform a snapshot while taking out a mutex to avoid concurrent calls. */ _mutexSnapshot(): Promise; start(authConfig?: AuthConfig): Promise; private logDatabaseVersion; _setAuthState(authState: AuthState): void; setClientListeners(): void; stop(shutdown?: boolean): Promise; private _stop; _waitForActiveSnapshots(): Promise; /** Get information about a requested subscription by it's key */ syncStatus(key: string): SyncStatus; /** * Subscribe to a set of shapes, so that server data can get onto the client. * * A set of shapes can be "named" using a key. Any subsequent calls to `subscribe` * using this key will exchange the subscription: a new one will be subscribed, and * then the old one will be unsubscribed. * * If the `key` is not provided, it will instead be generated. Un-keyed subscriptions * are deduplicated: multiple `subscribe` calls with exactly same shapes will result in * only one subscription, and will even return the same key. */ subscribe(shapeDefinitions: Shape[], key?: string): Promise; /** Make a subscription without waiting for init */ private _doSubscribe; unsubscribe(sync: { shapes: Shape[]; key?: string; }): Promise; unsubscribe(keys: string[]): Promise; private unsubscribeIds; _handleSubscriptionData(subsData: SubscriptionData): Promise; /** * Insert incoming subscription data into the database. * Returns flag indicating whether application was successful or not. */ private _applySubscriptionData; /** * Runs the provided statements in a transaction and disables FK checks if `this.fkChecks` is set to `disabled`. * `this.fkChecks` should only be set to true when using SQLite as we already disable FK checks for incoming TXs when using Postgres */ runInTransaction(...stmts: Statement[]): Promise; _resetClientState(opts?: { keepSubscribedShapes: boolean; }): Promise; _clearTables(tables: QualifiedTablename[]): Promise; _handleSubscriptionError(satelliteError: SatelliteError, subscriptionId?: string): Promise; _handleClientRelations(relation: Relation): void; _handleClientTransactions(tx: ServerTransaction): Promise; _handleClientAdditionalData(data: AdditionalData): Promise; _handleClientOutboundStarted(): Promise; _handleClientError(satelliteError: SatelliteError): void; _handleOrThrowClientError(error: SatelliteError): Promise; /** * Sets the JWT token. * @param token The JWT token. */ setToken(token: string): void; /** * @returns True if a JWT token has been set previously. False otherwise. */ hasToken(): boolean; connectWithBackoff(): Promise; private _makePendingSubscriptions; private _connect; /** * Authenticates with the Electric sync service using the provided token. * @returns A promise that resolves to void if authentication succeeded. Otherwise, rejects with the reason for the error. */ authenticate(token: string): Promise; cancelConnectionWaiter(error: SatelliteError): void; disconnect(error?: SatelliteError): void; /** * A disconnection issued by the client. */ clientDisconnect(): void; _startReplication(): Promise; private _notifyConnectivityState; _verifyTableStructure(): Promise; _updateAuthState({ authState }: AuthStateNotification): Promise; _performSnapshot(): Promise; _notifyChanges(results: OplogEntry[], origin: ChangeOrigin): void; _replicateSnapshotChanges(results: OplogEntry[]): Promise; _apply(incoming: OplogEntry[], incoming_origin: string): Promise<{ tablenames: string[]; statements: Statement[]; }>; _getEntries(since?: number): Promise; _deleteShadowTagsStatement(shadow: ShadowEntry): Statement; _updateShadowTagsStatement(shadow: ShadowEntry): Statement; _updateRelations(rel: Omit): void; _applyTransaction(transaction: Transaction): Promise; _applyAdditionalData(data: AdditionalData): Promise; _applyGoneBatch(lsn: LSN, subscriptionIds: string[], allGone: DataGone[]): Promise; private maybeGarbageCollect; _disableTriggers(tables: QualifiedTablename[]): Statement[]; _enableTriggers(tables: QualifiedTablename[]): Statement[]; _updateTriggerSettings(tables: QualifiedTablename[], flag: 0 | 1): Statement[]; _addSeenGoneBatchStmt(subscriptionIds: string[]): Statement; _addSeenAdditionalDataStmt(ref: string): Statement; _resetAllSeenStmt(keys?: (keyof MetaEntries)[]): Statement; _setMetaStatement(key: K, value: MetaEntries[K]): Statement; _setMetaStatement(key: Uuid, value: string | null): Statement; _setMeta(key: K, value: MetaEntries[K]): Promise; _setMeta(key: Uuid, value: string | null): Promise; _getMeta(key: Uuid): Promise; _getMeta(key: K): Promise; private _getClientId; private _getLocalRelations; private _generateTag; _garbageCollectOplog(commitTimestamp: Date): Promise; /** * Update `this._lsn` to the new value and generate a statement to persist this change * * @param lsn new LSN value * @returns statement to be executed to save the new LSN value in the database */ private updateLsnStmt; setReplicationTransform(tableName: QualifiedTablename, transform: ReplicatedRowTransformer): void; clearReplicationTransform(tableName: QualifiedTablename): void; _applyDeleteOperation(entryChanges: ShadowEntryChanges, qualifiedTableName: QualifiedTablename): Statement; _applyNonDeleteOperation({ fullRow, primaryKeyCols }: ShadowEntryChanges, qualifiedTableName: QualifiedTablename): Statement; private checkMaxSqlParameters; } export declare function generateTriggersForTable(tbl: MigrationTable, builder: QueryBuilder): Statement[]; export {};