import * as s from './store.ts';
import { Logger } from './Reactor.js';
import { InstaQLResponse, ValidQuery } from './queryTypes.ts';
import { EntitiesDef, IContainEntitiesAndLinks } from './schemaTypes.ts';
import { StoreInterface } from './index.ts';
type StartMsg = {
    op: 'start-sync';
    q: string;
};
type EndMsg = {
    op: 'remove-sync';
    'subscription-id': string;
    'keep-subscription': boolean;
};
type ResyncMsg = {
    op: 'resync-table';
    'subscription-id': string;
    'tx-id': number;
    token: string;
};
type SendMsg = StartMsg | EndMsg | ResyncMsg;
type StartSyncOkMsg = {
    'subscription-id': string;
    'client-event-id': string;
    q: string;
    token: string;
};
type Triple = [string, string, any, number];
type SyncLoadBatchMsg = {
    'subscription-id': string;
    'join-rows': Array<Triple[]>;
};
type SyncInitFinishMsg = {
    'subscription-id': string;
    'tx-id': number;
};
type SyncUpdateTriplesMsg = {
    'subscription-id': string;
    txes: {
        'tx-id': number;
        changes: {
            action: 'added' | 'removed';
            triple: Triple;
        }[];
    }[];
};
type TrySend = (eventId: string, msg: SendMsg) => void;
type Config = {
    useDateObjects: boolean;
};
type CreateStore = (triples: Triple[]) => s.Store;
export declare enum CallbackEventType {
    InitialSyncBatch = "InitialSyncBatch",
    InitialSyncComplete = "InitialSyncComplete",
    LoadFromStorage = "LoadFromStorage",
    SyncTransaction = "SyncTransaction",
    Error = "Error"
}
type QueryEntities<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> = InstaQLResponse<Schema, Q, UseDates>[keyof InstaQLResponse<Schema, Q, UseDates>];
type QueryEntity<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> = QueryEntities<Schema, Q, UseDates> extends (infer E)[] ? E : never;
type ChangedFields<Entity> = {
    [K in keyof Entity]?: {
        oldValue: Entity[K];
        newValue: Entity[K];
    };
};
export interface BaseCallbackEvent<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> {
    type: CallbackEventType;
    data: InstaQLResponse<Schema, Q, UseDates>;
}
export interface InitialSyncBatch<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> extends BaseCallbackEvent<Schema, Q, UseDates> {
    type: CallbackEventType.InitialSyncBatch;
    batch: QueryEntities<Schema, Q, UseDates>;
}
export interface InitialSyncComplete<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> extends BaseCallbackEvent<Schema, Q, UseDates> {
    type: CallbackEventType.InitialSyncComplete;
}
export interface SyncTransaction<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> extends BaseCallbackEvent<Schema, Q, UseDates> {
    type: CallbackEventType.SyncTransaction;
    added: QueryEntities<Schema, Q, UseDates>;
    removed: QueryEntities<Schema, Q, UseDates>;
    updated: {
        oldEntity: QueryEntity<Schema, Q, UseDates>;
        newEntity: QueryEntity<Schema, Q, UseDates>;
        changedFields: ChangedFields<QueryEntity<Schema, Q, UseDates>>;
    }[];
}
export interface LoadFromStorage<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> extends BaseCallbackEvent<Schema, Q, UseDates> {
    type: CallbackEventType.LoadFromStorage;
}
export interface SetupError<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> extends BaseCallbackEvent<Schema, Q, UseDates> {
    type: CallbackEventType.Error;
    error: {
        message: string;
        hint?: any;
        type: string;
        status: number;
    };
}
export type CallbackEvent<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> = InitialSyncBatch<Schema, Q, UseDates> | InitialSyncComplete<Schema, Q, UseDates> | SyncTransaction<Schema, Q, UseDates> | LoadFromStorage<Schema, Q, UseDates> | SetupError<Schema, Q, UseDates>;
export type SyncTableCallback<Schema extends IContainEntitiesAndLinks<EntitiesDef, any>, Q extends ValidQuery<Q, Schema>, UseDates extends boolean> = (event: CallbackEvent<Schema, Q, UseDates>) => void;
export declare class SyncTable {
    private trySend;
    private subs;
    private callbacks;
    private config;
    private idToHash;
    private log;
    private createStore;
    private getAttrs;
    constructor(trySend: TrySend, storage: StoreInterface, config: Config, log: Logger, createStore: CreateStore, getAttrs: () => s.AttrsStore);
    beforeUnload(): void;
    subscribe(q: any, cb: SyncTableCallback<any, any, any>): (opts?: {
        keepSubscription?: boolean | null | undefined;
    } | null | undefined) => void;
    private unsubscribe;
    private sendStart;
    private sendResync;
    private sendRemove;
    private initSubscription;
    flushPending(): Promise<void>;
    onStartSyncOk(msg: StartSyncOkMsg): void;
    private notifyCbs;
    onSyncLoadBatch(msg: SyncLoadBatchMsg): void;
    onSyncInitFinish(msg: SyncInitFinishMsg): void;
    onSyncUpdateTriples(msg: SyncUpdateTriplesMsg): void;
    private clearSubscriptionData;
    onStartSyncError(msg: {
        op: 'error';
        'original-event': StartMsg;
        'client-event-id': string;
        status: number;
        type: string;
        message?: string;
        hint?: any;
    }): void;
    onResyncError(msg: {
        op: 'error';
        'original-event': ResyncMsg;
        status: number;
        type: string;
    }): void;
}
export {};
//# sourceMappingURL=SyncTable.d.ts.map