/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { _InlineTrick } from "../../../util";
import { TreeChunk } from "../chunk";
import { FluidSerializableReadOnly } from "../../contextuallyTyped";
import { TreeValue } from "../../../core";
/**
 * Utilities related to chunk encoding and decoding that do not depend on specific chunk types or formats.
 */
/**
 * Counts usages of some `T`, then generates tables for replacing those `T` values with small numbers.
 *
 * Can be used to deduplicate objects when encoding via {@link https://go-compression.github.io/algorithms/dictionary/ | Dictionary Coding}.
 */
export declare class Counter<T> {
    private readonly counts;
    add(t: T, count?: number): void;
    /**
     * Generate a table which can be used to deduplicate the items added via `add`.
     * Table is sorted from most used to least used so that more commonly added items will get smaller indexes.
     *
     * @param filter - determines which items should be included in the table.
     */
    buildTable(filter?: CounterFilter<T>): DeduplicationTable<T>;
}
/**
 * Returns true iff a given item `t` (of which there are `count` usages) is worth substituting with the number `value`.
 */
export declare type CounterFilter<T> = (t: T, value: number, count: number) => boolean;
/**
 * Table for dictionary compression.
 * See {@link Counter}.
 */
export interface DeduplicationTable<T> {
    /**
     * Lookup table derived from indexToValue,
     */
    readonly valueToIndex: ReadonlyMap<T, number>;
    /**
     * Deduplication table: lookup values by their index.
     *
     * This is the portion of the table that should be included in persisted data.
     */
    readonly indexToValue: readonly T[];
}
/**
 * Filter for use with Counter.buildTable that minimizes the size of the produced JSON.
 *
 * @remarks
 * This minimizes the number of UTF-16 code units in the produced JSON.
 * This is not ideal: minimizing UTF-8 bytes would be better.
 * For ascii text these are the same, and in worst cases they correlate pretty well (accurate to within a small constant factor).
 * This is thus good enough for a heuristic.
 *
 * Also the use of this filter doesn't take into account the length cost of keeping a value in the table possibly
 * making some of the entries at higher indexes in the table get a larger number.
 * For example, if keeping an entry at index 9 saves one character this will keep it,
 * even if that means the next entry (at index 10) loses more than one character due to 10 being two digits instead of the one digit it would have been at index 9.
 * This means that this filter is not guaranteed to be optimal, but it should always be quite close.
 */
export declare function jsonMinimizingFilter(s: string, value: number, count: number): boolean;
/**
 * Read from an array, but error if index is not valid.
 */
export declare function getChecked<T>(data: readonly T[], index: number): T;
/**
 * A readable stream.
 */
export interface StreamCursor {
    /**
     * The data to read.
     */
    readonly data: readonly FluidSerializableReadOnly[];
    /**
     * Location in the data.
     */
    offset: number;
}
/**
 * Read one item from the stream, advancing the stream offset.
 */
export declare function readStream(stream: StreamCursor): FluidSerializableReadOnly;
/**
 * Read one number from the stream, advancing the stream offset.
 */
export declare function readStreamNumber(stream: StreamCursor): number;
/**
 * Read one boolean from the stream, advancing the stream offset.
 */
export declare function readStreamBoolean(stream: StreamCursor): boolean;
/**
 * Read one TreeValue from the stream, advancing the stream offset.
 */
export declare function readStreamValue(stream: StreamCursor): TreeValue;
/**
 * Read one nested array from the stream, advancing the stream offset.
 *
 * @returns the nested array as a stream.
 */
export declare function readStreamStream(stream: StreamCursor): StreamCursor;
export interface ChunkDecoder {
    /**
     * Read from stream, updating the offset.
     *
     * @returns a TreeChunk made from the data from `stream`.
     * This chunk is allowed to reference/take ownership of content it reads from the stream.
     */
    decode(decoders: readonly ChunkDecoder[], stream: StreamCursor): TreeChunk;
}
/**
 * Applies a function to the content of a [discriminated union](https://en.wikipedia.org/wiki/Tagged_union)
 * where the function to apply depends on the which value from the union it holds.
 *
 * This uses a rather non-standard encoding of the union where it is an object with many differently named optional fields,
 * and which of the fields is populated determines the content type.
 * This union encoding has the advantage that schema validation (such as that implemented by TypeBox) can validate the data.
 * Other encodings, such as an untagged-union, then tagging the content types with a marker enum require the schema validator to disambiguate the union members,
 * inferring that the enum can be use to differentiate them.
 */
export declare class DiscriminatedUnionDispatcher<TUnion extends object, TArgs extends any[], TResult> {
    private readonly library;
    constructor(library: [
        {
            readonly [Property in keyof TUnion]-?: (value: Required<TUnion>[Property], ...args: TArgs) => TResult;
        }
    ][_InlineTrick]);
    dispatch(union: TUnion, ...args: TArgs): TResult;
}
//# sourceMappingURL=chunkCodecUtilities.d.ts.map