import type { BSON } from 'bson'; import { type fetch } from 'cross-fetch'; import Logger, { ILogger } from 'js-logger'; import { PowerSyncCredentials } from '../../connection/PowerSyncCredentials.js'; import { StreamingSyncRequest } from './streaming-sync-types.js'; import { SimpleAsyncIterator } from '../../../utils/stream_transform.js'; export type BSONImplementation = typeof BSON; export type RemoteConnector = { fetchCredentials: () => Promise; invalidateCredentials?: () => void; }; export declare const DEFAULT_REMOTE_LOGGER: Logger.ILogger; export type SyncStreamOptions = { path: string; data: StreamingSyncRequest; headers?: Record; abortSignal: AbortSignal; fetchOptions?: Request; }; export declare enum FetchStrategy { /** * Queues multiple sync events before processing, reducing round-trips. * This comes at the cost of more processing overhead, which may cause ACK timeouts on older/weaker devices for big enough datasets. */ Buffered = "buffered", /** * Processes each sync event immediately before requesting the next. * This reduces processing overhead and improves real-time responsiveness. */ Sequential = "sequential" } export type SocketSyncStreamOptions = SyncStreamOptions & { fetchStrategy: FetchStrategy; }; export type FetchImplementation = typeof fetch; /** * Class wrapper for providing a fetch implementation. * The class wrapper is used to distinguish the fetchImplementation * option in [AbstractRemoteOptions] from the general fetch method * which is typeof "function" */ export declare class FetchImplementationProvider { getFetch(): FetchImplementation; } export type AbstractRemoteOptions = { /** * Transforms the PowerSync base URL which might contain * `http(s)://` to the corresponding WebSocket variant * e.g. `ws(s)://` */ socketUrlTransformer: (url: string) => string; /** * Optionally provide the fetch implementation to use. * Note that this usually needs to be bound to the global scope. * Binding should be done before passing here. */ fetchImplementation: FetchImplementation | FetchImplementationProvider; /** * Optional options to pass directly to all `fetch` calls. * * This can include fields such as `dispatcher` (e.g. for proxy support), * `cache`, or any other fetch-compatible options. */ fetchOptions?: {}; }; export declare const DEFAULT_REMOTE_OPTIONS: AbstractRemoteOptions; export declare abstract class AbstractRemote { protected connector: RemoteConnector; protected logger: ILogger; protected credentials: PowerSyncCredentials | null; protected options: AbstractRemoteOptions; constructor(connector: RemoteConnector, logger?: ILogger, options?: Partial); /** * @returns a fetch implementation (function) * which can be called to perform fetch requests */ get fetch(): FetchImplementation; /** * Get credentials currently cached, or fetch new credentials if none are * available. * * These credentials may have expired already. */ getCredentials(): Promise; /** * Fetch a new set of credentials and cache it. * * Until this call succeeds, `getCredentials` will still return the * old credentials. * * This may be called before the current credentials have expired. */ prefetchCredentials(): Promise; /** * Get credentials for PowerSync. * * This should always fetch a fresh set of credentials - don't use cached * values. */ fetchCredentials(): Promise; /*** * Immediately invalidate credentials. * * This may be called when the current credentials have expired. */ invalidateCredentials(): void; getUserAgent(): string; protected buildRequest(path: string): Promise<{ url: string; headers: { 'content-type': string; Authorization: string; 'x-user-agent': string; }; }>; post(path: string, data: any, headers?: Record): Promise; get(path: string, headers?: Record): Promise; /** * Provides a BSON implementation. The import nature of this varies depending on the platform */ abstract getBSON(): Promise; /** * @returns A text decoder decoding UTF-8. This is a method to allow patching it for Hermes which doesn't support the * builtin, without forcing us to bundle a polyfill with `@powersync/common`. */ createTextDecoder(): TextDecoder; protected createSocket(url: string): WebSocket; /** * Returns a data stream of sync line data, fetched via RSocket-over-WebSocket. * * The only mechanism to abort the returned stream is to use the abort signal in {@link SocketSyncStreamOptions}. * * @param bson A BSON encoder and decoder. When set, the data stream will be requested with a BSON payload * (required for compatibility with older sync services). */ socketStreamRaw(options: SocketSyncStreamOptions, bson?: typeof BSON): Promise>; /** * @returns Whether the HTTP implementation on this platform can receive streamed binary responses. This is true on * all platforms except React Native (who would have guessed...), where we must not request BSON responses. * * @see https://github.com/react-native-community/fetch?tab=readme-ov-file#motivation */ protected get supportsStreamingBinaryResponses(): boolean; /** * Posts a `/sync/stream` request, asserts that it completes successfully and returns the streaming response as an * async iterator of byte blobs. * * To cancel the async iterator, use the abort signal from {@link SyncStreamOptions} passed to this method. */ protected fetchStreamRaw(options: SyncStreamOptions): Promise<{ isBson: boolean; stream: SimpleAsyncIterator; }>; /** * Posts a `/sync/stream` request. * * Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as * {@link Uint8Array}s. */ fetchStream(options: SyncStreamOptions): Promise>; }