/**
 * Per-frame ring of action records.
 *
 * Each frame's `BinaryBuffer` holds a sequence of action records. One record per
 * `SimActionExecutor.execute` call:
 *
 * ```
 *   varint:    prior_state_count
 *   loop:
 *     varint:  entity_id
 *     uint8:   component_type_id   (assigned by the ReplicatedComponentRegistry)
 *     uint32:  prior_payload_len
 *     bytes:   prior_payload       (adapter.serialize of the component's prior state)
 *   uint8:     action_type_id
 *   uint8:     sender_id           (peer that originated the action; local-only,
 *                                   STRIPPED by Replicator before send)
 *   uint32:    action_payload_len
 *   bytes:     action_payload      (the action's own serialize output)
 * ```
 *
 * Self-describing: records can be skipped without consulting the action registry,
 * which means rewind code can walk records forward to find boundaries, then
 * iterate backward to apply prior states — no need to instantiate any actions.
 *
 * Note that `sender_id` is recorded in-buffer for local rollback orchestrators
 * (stable-sort tie-breaking by sender on replay) but never crosses the wire —
 * {@link Replicator#pack_for_peer} strips it and the receiver derives sender
 * from the inbound packet's peer_id, so a hostile peer cannot impersonate.
 *
 * Ring depth is set at construction. When the ring fills, the oldest frame's
 * buffer is recycled for the new frame.
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2025
 */
export class ActionLog {
    /**
     * @param {{ frame_capacity: number, initial_buffer_size?: number }} options
     */
    constructor({ frame_capacity, initial_buffer_size }: {
        frame_capacity: number;
        initial_buffer_size?: number;
    });
    /**
     * @readonly
     * @type {number}
     */
    readonly frame_capacity: number;
    /**
     * Open a new frame for writing. Recycles the oldest slot if the ring is full.
     *
     * @param {number} frame absolute frame number
     */
    begin_frame(frame: number): void;
    /**
     * Close the currently-open frame.
     */
    end_frame(): void;
    /**
     * Get the buffer for the currently-open frame for direct writing.
     *
     * @returns {BinaryBuffer}
     */
    current_buffer(): BinaryBuffer;
    /**
     * Has the given frame number ever been written, and is it still in the ring?
     *
     * @param {number} frame
     * @returns {boolean}
     */
    has_frame(frame: number): boolean;
    /**
     * Read-only access to a closed frame's buffer. Throws if the frame is not in the ring.
     * The buffer's `position` will be set to 0 and its valid byte length is `write_end_for(frame)`.
     *
     * **Only valid for frames that have been closed via {@link end_frame}.** While a
     * frame is open, `__write_ends[slot]` still holds the previous occupant's
     * length — `buffer_for`/`write_end_for` would return mismatched
     * buffer-contents-vs-length and any reader would walk garbage.
     *
     * @param {number} frame
     * @returns {BinaryBuffer}
     */
    buffer_for(frame: number): BinaryBuffer;
    /**
     * Number of valid bytes written to the given frame's buffer.
     * @param {number} frame
     * @returns {number}
     */
    write_end_for(frame: number): number;
    #private;
}
import { BinaryBuffer } from "../../../core/binary/BinaryBuffer.js";
//# sourceMappingURL=ActionLog.d.ts.map