/**
 * A type-safe wrapper around {@link LiveQuery} that carries the data type `T`
 * through initial snapshot records and real-time change events.
 *
 * `TypedLiveQuery<T>` wraps a `LiveQuery` so that:
 * - `.records` returns `TypedRecord<T>[]` instead of `Record[]`.
 * - `.on('create', handler)` provides `TypedRecord<T>` in the callback.
 * - `.on('change', handler)` provides `TypedRecordChange<T>` in the callback.
 * - `.on('disconnected' | 'reconnecting' | 'reconnected' | 'eose' | 'error', handler)`
 *   forwards transport lifecycle events from the underlying `LiveQuery`.
 *
 * @example
 * ```ts
 * const { liveQuery } = await typed.records.subscribe('friend');
 * // liveQuery is TypedLiveQuery<FriendData>
 *
 * for (const record of liveQuery.records) {
 *   const data = await record.data.json(); // FriendData
 * }
 *
 * liveQuery.on('create', async (record) => {
 *   const data = await record.data.json(); // FriendData
 * });
 *
 * // Connection lifecycle events
 * liveQuery.on('disconnected', () => showOfflineIndicator());
 * liveQuery.on('reconnected', () => hideOfflineIndicator());
 * liveQuery.on('eose', () => console.log('catch-up complete'));
 * ```
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { TypedRecord } from './typed-record.js';
// ---------------------------------------------------------------------------
// TypedLiveQuery class
// ---------------------------------------------------------------------------
/**
 * A type-safe wrapper around {@link LiveQuery} that preserves the data type `T`
 * through the initial snapshot and all subsequent change events.
 *
 * Obtain instances through `TypedEnbox.records.subscribe()` — never construct
 * directly.
 */
export class TypedLiveQuery {
    constructor(liveQuery) {
        this._liveQuery = liveQuery;
    }
    // -------------------------------------------------------------------------
    // Escape hatch
    // -------------------------------------------------------------------------
    /** Access the underlying untyped {@link LiveQuery} for advanced use cases. */
    get rawLiveQuery() {
        return this._liveQuery;
    }
    // -------------------------------------------------------------------------
    // Typed initial snapshot
    // -------------------------------------------------------------------------
    /** The initial snapshot of matching records, typed as `TypedRecord<T>[]`. */
    get records() {
        if (!this._typedRecords) {
            this._typedRecords = this._liveQuery.records.map((record) => new TypedRecord(record));
        }
        return this._typedRecords;
    }
    /**
     * Pagination cursor for fetching the next page of initial results.
     *
     * `undefined` when there are no more results.
     */
    get cursor() {
        return this._liveQuery.cursor;
    }
    /**
     * Whether the transport connection is currently active.
     * Delegates to the underlying `LiveQuery.isConnected`.
     */
    get isConnected() {
        return this._liveQuery.isConnected;
    }
    on(event, handler) {
        // Lifecycle events: delegate directly to the underlying LiveQuery.
        if (event === 'disconnected') {
            return this._liveQuery.on('disconnected', handler);
        }
        if (event === 'reconnected') {
            return this._liveQuery.on('reconnected', handler);
        }
        if (event === 'eose') {
            return this._liveQuery.on('eose', handler);
        }
        if (event === 'reconnecting') {
            return this._liveQuery.on('reconnecting', handler);
        }
        if (event === 'error') {
            return this._liveQuery.on('error', handler);
        }
        // Record change events: wrap records in TypedRecord.
        if (event === 'change') {
            return this._liveQuery.on('change', (change) => {
                handler({
                    type: change.type,
                    record: new TypedRecord(change.record),
                });
            });
        }
        // For create/update/delete, the underlying LiveQuery handler receives a Record.
        // Cast event to 'create' to satisfy the overload resolver — the actual value
        // is always one of 'create' | 'update' | 'delete' at this point.
        return this._liveQuery.on(event, (record) => {
            handler(new TypedRecord(record));
        });
    }
    // -------------------------------------------------------------------------
    // Lifecycle
    // -------------------------------------------------------------------------
    /**
     * Close the underlying subscription and stop dispatching events.
     */
    close() {
        return __awaiter(this, void 0, void 0, function* () {
            return this._liveQuery.close();
        });
    }
}
//# sourceMappingURL=typed-live-query.js.map