import { createSyncularBridgeClient, } from '@syncular/client';
const DEFAULT_COMMANDS = {
    executeSql: 'syncular_execute_sql',
    applyMutationsCommit: 'syncular_apply_mutations_commit',
    applyLeasedMutationsCommit: 'syncular_apply_leased_mutations_commit',
    sync: 'syncular_sync',
    resumeFromBackground: 'syncular_resume_from_background',
    start: 'syncular_start',
    stop: 'syncular_stop',
    setSubscriptions: 'syncular_set_subscriptions',
    issueAuthLease: 'syncular_issue_auth_lease',
    upsertAuthLease: 'syncular_upsert_auth_lease',
    authLease: 'syncular_auth_lease',
    activeAuthLeases: 'syncular_active_auth_leases',
    diagnosticSnapshot: 'syncular_diagnostic_snapshot',
    joinPresence: 'syncular_join_presence',
    leavePresence: 'syncular_leave_presence',
    updatePresenceMetadata: 'syncular_update_presence_metadata',
    listConflicts: 'syncular_conflict_summaries',
    retryConflictKeepLocal: 'syncular_retry_conflict_keep_local',
    resolveConflict: 'syncular_resolve_conflict',
};
export async function createSyncularTauriClient(options) {
    return createSyncularBridgeClient({
        ...options,
        bridge: createSyncularTauriBridge(options),
    });
}
export function createSyncularTauriBridge(options) {
    const commands = { ...DEFAULT_COMMANDS, ...options.commands };
    const eventPrefix = options.eventPrefix ?? 'syncular';
    const presence = new Map();
    let status = {};
    const invoke = (command, args) => options.invoke(command, args);
    return {
        executeSql: (request) => invoke(commands.executeSql, { request }),
        applyMutationsCommit: (batch) => invoke(commands.applyMutationsCommit, { batch }),
        applyLeasedMutationsCommit: (batch) => invoke(commands.applyLeasedMutationsCommit, { batch }),
        sync: () => invoke(commands.sync),
        resumeFromBackground: (syncOptions) => invoke(commands.resumeFromBackground, {
            options: syncOptions,
        }),
        start: () => invoke(commands.start),
        stop: () => invoke(commands.stop),
        setSubscriptions: (subscriptions) => invoke(commands.setSubscriptions, {
            subscriptions: [...subscriptions],
        }),
        getStatus: () => status,
        issueAuthLease: (request) => invoke(commands.issueAuthLease, { request }),
        upsertAuthLease: (lease) => invoke(commands.upsertAuthLease, { lease }),
        authLease: (leaseId) => invoke(commands.authLease, {
            leaseId,
        }),
        activeAuthLeases: (actorId, nowMs) => invoke(commands.activeAuthLeases, {
            actorId,
            nowMs,
        }),
        diagnosticSnapshot: () => invoke(commands.diagnosticSnapshot),
        on: (event, listener) => listen(options.listen, `${eventPrefix}:${event}`, (payload) => {
            if (event === 'lifecycleChanged') {
                status = {
                    ...status,
                    lifecycle: payload,
                };
            }
            listener(payload);
        }),
        presence: {
            get: (scopeKey) => (presence.get(scopeKey) ?? []),
            join: (scopeKey, metadata) => {
                void invoke(commands.joinPresence, { scopeKey, metadata });
            },
            leave: (scopeKey) => {
                void invoke(commands.leavePresence, { scopeKey });
            },
            updateMetadata: (scopeKey, metadata) => {
                void invoke(commands.updatePresenceMetadata, {
                    scopeKey,
                    metadata,
                });
            },
            onChange: (listener) => listen(options.listen, `${eventPrefix}:presenceChanged`, (payload) => {
                const event = payload;
                presence.set(event.scopeKey, event.presence);
                listener(event);
            }),
        },
        conflicts: {
            list: () => invoke(commands.listConflicts),
            retryKeepLocal: (id) => invoke(commands.retryConflictKeepLocal, { id }),
            resolve: (id, resolution) => invoke(commands.resolveConflict, { id, resolution }),
        },
    };
}
function listen(listenFn, event, listener) {
    if (!listenFn)
        return noop;
    let unlisten;
    let closed = false;
    void listenFn(event, ({ payload }) => listener(payload)).then((nextUnlisten) => {
        if (closed) {
            nextUnlisten();
        }
        else {
            unlisten = nextUnlisten;
        }
    });
    return () => {
        closed = true;
        unlisten?.();
    };
}
function noop() { }
//# sourceMappingURL=index.js.map