//#region src/core/CollectionNature.d.ts
declare const CollectionNature: {
  /**
   * The items in the collection should always be unique, and order does not matter
   * This option is always performant
   */
  readonly Set: "set";
  /**
   * The items in the collection should always preserve the order it is entered in the collection
   */
  readonly Array: "array";
};
type CollectionNature = (typeof CollectionNature)[keyof typeof CollectionNature];
//#endregion
//#region src/core/ICollectionOption.d.ts
interface ICollectionOption {
  nature: CollectionNature;
}
//#endregion
//#region src/core/CollectionViewFilterFn.d.ts
type CollectionViewFilterFn<T> = (item: T) => boolean;
//#endregion
//#region src/core/ICollectionViewOption.d.ts
interface ICollectionViewOption<T> {
  filter: CollectionViewFilterFn<T>;
  sort: (a: T, b: T) => number;
}
//#endregion
//#region src/core/IReadonlyCollection.d.ts
interface IReadonlyCollection<T> {
  exists(item: T): boolean;
  readonly items: readonly T[];
  readonly count: number;
}
//#endregion
//#region src/core/IMutableCollection.d.ts
interface IMutableCollection<T> extends IReadonlyCollection<T> {
  add(item: T): boolean;
  addRange(items: readonly T[] | IReadonlyCollection<T>): boolean[];
  remove(item: T): boolean;
}
//#endregion
//#region src/core/KeyExtract.d.ts
/**
 * Delegate for extracting key from the given item
 */
type KeyExtract<T = unknown, KeyT = unknown> = SingleKeyExtract<T, KeyT> | MultipleKeyExtract<T, KeyT>;
type SingleKeyExtract<T = unknown, KeyT = unknown> = {
  isMultiple?: boolean;
  (item: T): KeyT;
};
type MultipleKeyExtract<T = unknown, KeyT = unknown> = {
  isMultiple: true;
  (item: T): readonly KeyT[] | ReadonlySet<KeyT>;
};
//#endregion
//#region src/core/Optional.d.ts
type Optional<T> = T | undefined;
type Nullable<T> = T | null;
//#endregion
//#region src/core/defaultCollectionOption.d.ts
declare const defaultCollectionOption: Readonly<ICollectionOption>;
//#endregion
//#region src/core/defaultCollectionViewOption.d.ts
declare const defaultFilter: () => boolean;
declare const defaultSort: () => number;
declare const defaultCollectionViewOption: ICollectionViewOption<any>;
//#endregion
//#region src/builders/keyExtractBuilder.d.ts
declare function buildMultipleKeyExtract<T = unknown, KeyT = unknown>(getKeys: (item: T) => readonly KeyT[] | ReadonlySet<KeyT>): MultipleKeyExtract<T, KeyT>;
//#endregion
//#region src/signals/Signal.d.ts
/**
 * Signal is a base class for all signals.
 *
 */
declare abstract class Signal {
  readonly type: symbol;
  readonly target: unknown;
  protected constructor(type: symbol, target: unknown);
}
type SignalType = Signal['type'];
//#endregion
//#region src/signals/ISignalObserver.d.ts
type SignalHandler<T extends Signal> = (signal: T) => void;
interface ISignalObserver {
  registerObserver<T extends Signal>(signalType: symbol, handler: SignalHandler<T>): void;
  unregisterObserver<T extends Signal>(handler: SignalHandler<T>, signalType?: symbol): void;
  notifyObservers(signal: Signal): void;
}
//#endregion
//#region src/core/ICollectionAndView.d.ts
interface ICollectionAndView<T> extends ISignalObserver {
  readonly items: readonly T[];
  rebuild(deep?: boolean): void;
  exists(item: T): boolean;
}
//#endregion
//#region src/core/ICollectionChangeDetail.d.ts
interface ICollectionUpdateLineItem<T> {
  oldValue: T;
  newValue: T;
}
interface ICollectionChangeDetail<T> {
  readonly added: T[];
  readonly removed: T[];
  readonly updated: ICollectionUpdateLineItem<T>[];
}
//#endregion
//#region src/signals/CollectionChangeSignal.d.ts
declare class CollectionChangeSignal<T> extends Signal {
  readonly detail: Readonly<ICollectionChangeDetail<T>>;
  static readonly type: unique symbol;
  constructor(target: IReadonlyCollection<T>, detail: Readonly<ICollectionChangeDetail<T>>);
}
//#endregion
//#region src/signals/SignalObserver.d.ts
/**
 * Signal observer is a class that can be used to observe signals
 * It supports multiple observers for a single signal type and vice versa
 */
declare class SignalObserver implements ISignalObserver {
  private readonly typeToHandleMap;
  private handlerToTypeMap;
  constructor();
  /**
   * Notify all observers of a signal by the signal's type
   * @param signal
   */
  notifyObservers(signal: Signal): void;
  /**
   * Register an observer for a signal type
   * @param type The type of a signal
   * @param handler The handler to be called when the signal is emitted
   */
  registerObserver<T extends Signal>(type: symbol, handler: SignalHandler<T>): void;
  /**
   * Unregister an observer for a signal type
   * @param handler The handle to be unregistered
   * @param type (Optional) The type of a signal (if not provided, all types associated with the handle will be unregistered)
   */
  unregisterObserver<T extends Signal>(handler: SignalHandler<T>, type?: symbol): void;
}
//#endregion
//#region src/collections/CollectionViewBase.d.ts
/**
 * CollectionView is a view onto a collection of data.  Most common use case would be
 * having the collection reduced by filter and/or sorted according to various criteria
 * without modifying the underlying data.
 */
declare abstract class CollectionViewBase<T, SourceCollectionT extends ICollectionAndView<T>> extends SignalObserver implements IReadonlyCollection<T> {
  private readonly _source;
  private readonly _option;
  private _cachedItems;
  protected constructor(source: SourceCollectionT, option?: Partial<ICollectionViewOption<T>>);
  /**
   * Reindex the entire collection
   */
  rebuild(deep?: boolean): void;
  protected rebuildCache(): void;
  protected applyFilterAndSort(list: readonly T[]): T[];
  returnItemIfPassesFilter(item?: T): Optional<T>;
  protected source_onChange(signal: CollectionChangeSignal<T>): void;
  notifyChange(signal: CollectionChangeSignal<T>): void;
  get count(): number;
  get items(): readonly T[];
  exists(item: T): boolean;
  get source(): SourceCollectionT;
  get filter(): ICollectionViewOption<T>['filter'];
  get sort(): ICollectionViewOption<T>['sort'];
}
//#endregion
//#region src/core/IIndex.d.ts
interface IIndex<T> {
  /**
   * Add an item into the index
   * @param item
   * @return true if the item has been added to the index successfully.
   */
  index(item: T): boolean;
  /**
   * Remove an item from the index
   * @param item
   * @return true if the item has been removed to the index successfully.
   */
  removeFromIndex(item: T): boolean;
  reset(): void;
}
//#endregion
//#region src/collections/IndexedCollectionBase.d.ts
declare abstract class IndexedCollectionBase<T> extends SignalObserver implements IMutableCollection<T> {
  private _allItemList;
  protected indexes: Set<IIndex<T>>;
  private _pauseChangeSignal;
  private _hasPendingChangeSignal;
  private _pendingChange;
  readonly option: Readonly<ICollectionOption>;
  protected constructor(initialValues?: readonly T[], additionalIndexes?: ReadonlyArray<IIndex<T>>, option?: Partial<ICollectionOption>);
  rebuild(): void;
  protected reindex(): void;
  /**
   * Rebuild indexes
   * @param indexes
   * @param autoReindex if true, all items will be reindexed
   */
  protected buildIndexes(indexes: readonly IIndex<T>[], autoReindex?: boolean): void;
  add(item: T): boolean;
  addRange(items: readonly T[] | IReadonlyCollection<T> | ReadonlySet<T>): boolean[];
  exists(item: T): boolean;
  /**
   * Remove item from the collection
   * @param item
   * @returns
   */
  remove(item: T): boolean;
  update(newItem: T, oldItem: T): boolean;
  /**
   * Move item before the specified item
   * @param item The item to move
   * @param before
   */
  moveBefore(item: T, before: T): void;
  /**
   * Move item after the specified item
   * @param item The item to move
   * @param after
   */
  moveAfter(item: T, after: T): void;
  get items(): readonly T[];
  get count(): number;
  protected notifyChange(change: Partial<ICollectionChangeDetail<T>>): void;
  /**
   * Pause change signal when collection content has changed
   * This is useful when the collection is undergoing batch changes
   * that the collection would not cause too many down stream change reaction
   * during batch update.
   *
   * If there are any changes during pause period, resumeChangeEvent
   * will dispatch change event.
   */
  pauseChangeSignal(): void;
  /**
   * Resume change signal from its pause state
   * if there are any pending changes, change signal will be notified
   */
  resumeChangeSignal(): void;
}
//#endregion
//#region src/core/internals/IInternalList.d.ts
interface IInternalList<T> {
  /**
   * Add item to list regardless of existence of such item
   * @param item
   */
  add(item: T): void;
  /**
   * Remove the first instance item to list regardless of existence of such item
   * @param item
   */
  remove(item: T): void;
  /**
   * Whether the specified item exists in the list
   * @param item
   */
  exists(item: T): boolean;
  /**
   * Signal that the list has changed so cached output should be regenerated.
   */
  invalidate(): void;
  /**
   * Update the old item with the new item
   * @param newItem
   * @param oldItem
   */
  update(newItem: T, oldItem: T): void;
  /**
   * Move the item before another item
   * @param item
   * @param before
   */
  moveBefore(item: T, before: T): void;
  /**
   * Move the item after another item
   * @param item
   * @param after
   */
  moveAfter(item: T, after: T): void;
  readonly output: readonly T[];
  readonly count: number;
}
//#endregion
//#region src/indexes/IndexBase.d.ts
type SetOrArray<T> = Set<T> | T[];
type LeafMap<T, KeyT = unknown> = Map<KeyT, IInternalList<T>>;
/**
 * Base class for index implementations. An index maps one or more keys to the
 * items they reference. Keys are extracted using the provided key extraction
 * functions.
 */
declare abstract class IndexBase<T> implements IIndex<T> {
  protected readonly _keyFns: readonly KeyExtract<T>[];
  protected readonly option: Readonly<ICollectionOption>;
  internalMap: Map<any, any>;
  protected constructor(keyFns: readonly KeyExtract<T>[], option?: Readonly<ICollectionOption>);
  /**
   * Add an item to the index under all of the keys produced by the key
   * extractors.
   *
   * @param item The item to index
   * @returns True if the item was inserted for at least one key
   */
  index(item: T): boolean;
  /**
   * Remove an item from the index for all of its associated keys.
   *
   * @param item The item to unindex
   * @returns True if the item existed for at least one key
   */
  removeFromIndex(item: T): boolean;
  /**
   * Retrieve items stored under the specified sequence of keys.
   *
   * @param keys Keys identifying the value within the index
   * @returns A readonly array of matched items
   */
  protected getValueInternal(keys: readonly unknown[]): readonly T[];
  /**
   * Extract the key values for the given item using all key extractor
   * functions.
   *
   * Single-value extractors are wrapped in an array so all returned values are
   * iterable.
   *
   * @param item The item whose keys are being generated
   */
  protected getKeys(item: T): SetOrArray<unknown>[];
  /**
   * Walk or create the nested map structure for the provided keys and return
   * the leaf maps corresponding to the last key segment.
   *
   * @param keys Array of key values for each level of the index
   */
  protected getLeafMaps(keys: SetOrArray<unknown>[], createIfMissing: boolean): LeafMap<T>[];
  /**
   * Clear all stored keys and values from the index.
   */
  reset(): void;
}
//#endregion
//#region src/indexes/CollectionIndex.d.ts
type KeyTypeArray = ReadonlyArray<unknown>;
type KeyExtractArray<T, KeysT extends KeyTypeArray> = { [index in keyof KeysT]: KeyExtract<T, KeysT[index]> };
declare class CollectionIndex<T, KeysT extends KeyTypeArray> extends IndexBase<T> {
  constructor(keyFn: KeyExtractArray<T, KeysT>, option?: Readonly<ICollectionOption>);
  getValue(...keys: KeysT): readonly T[];
}
//#endregion
//#region src/collections/PrimaryKeyCollection.d.ts
/**
 * A collection where every item contains a unique identifier key (aka primary key)
 */
declare class PrimaryKeyCollection<T, IdT = string> extends IndexedCollectionBase<T> {
  readonly primaryKeyExtract: SingleKeyExtract<T, IdT>;
  protected readonly idIndex: CollectionIndex<T, [IdT]>;
  constructor(primaryKeyExtract: SingleKeyExtract<T, IdT>, initialValues?: readonly T[], additionalIndexes?: ReadonlyArray<IIndex<T>>, option?: Readonly<ICollectionOption>);
  protected buildIndexes(indexes: readonly IIndex<T>[], autoReindex?: boolean): void;
  exists(item: T): boolean;
  /**
   * Get the item by its primary key
   * @param keyValue
   * @returns
   */
  byPrimaryKey(keyValue: IdT): Optional<T>;
  update(newItem: T): boolean;
}
//#endregion
//#region src/signals/CollectionAddSignal.d.ts
declare class CollectionAddSignal<T> extends Signal {
  readonly added: readonly T[];
  static readonly type: unique symbol;
  constructor(target: IReadonlyCollection<T>, added: readonly T[]);
}
//#endregion
//#region src/signals/CollectionRemoveSignal.d.ts
declare class CollectionRemoveSignal<T> extends Signal {
  readonly removed: readonly T[];
  static readonly type: unique symbol;
  constructor(target: IReadonlyCollection<T>, removed: readonly T[]);
}
//#endregion
//#region src/signals/CollectionUpdateSignal.d.ts
declare class CollectionUpdateSignal<T> extends Signal {
  readonly updated: readonly Readonly<ICollectionUpdateLineItem<T>>[];
  static readonly type: unique symbol;
  constructor(target: IReadonlyCollection<T>, updated: readonly Readonly<ICollectionUpdateLineItem<T>>[]);
}
//#endregion
export { CollectionAddSignal, CollectionChangeSignal, CollectionIndex, CollectionNature, CollectionRemoveSignal, CollectionUpdateSignal, CollectionViewBase, ICollectionOption, ICollectionViewOption, IMutableCollection, IReadonlyCollection, IndexBase, IndexedCollectionBase, KeyExtract, MultipleKeyExtract, Nullable, Optional, PrimaryKeyCollection, Signal, SignalHandler, SignalObserver, SignalType, SingleKeyExtract, buildMultipleKeyExtract, defaultCollectionOption, defaultFilter as defaultCollectionViewFilter, defaultCollectionViewOption, defaultSort as defaultCollectionViewSort };