import { IDisposable, IDisposableOwnerT } from './dispose'; import { Listener } from './emit'; import { BaseObservable, Observable } from './observable'; /** * Either an observable or a plain array of T. This is useful for functions like dom.forEach() * which are convenient to have available for both. */ export type MaybeObsArray = BaseObservable | T[]; /** * Info about a modification to ObsArray contents. It is included as a third argument to change * listeners when available. When not available, listeners should assume that the array changed * completely. */ export interface IObsArraySplice { start: number; /** asdf */ numAdded: number; deleted: T[]; } export type ISpliceListener = (this: C, val: T[], prev: T[], change?: IObsArraySplice) => void; /** * `ObsArray` is essentially an array-valued observable. It extends a plain Observable to allow * for more efficient observation of array changes. It also may be * used as an owner for disposable array elements. * * As for any array-valued `Observable`, when the contents of the observed array changes, the * listeners get called with new and previous values which are the same array. For simple changes, * such as those made with `.push()` and `.splice()` methods, `ObsArray` allows for more efficient * handling of the change by calling listeners with splice info in the third argument. * * `ObsArray` may be used with disposable elements as their owner. E.g. * ```ts * const arr = obsArray(); * arr.push(D.create(arr, "x"), D.create(arr, "y")); * arr.pop(); // Element "y" gets disposed. * arr.dispose(); // Element "x" gets disposed. * ``` * * Note that only the pattern above works: `obsArray` may only be used to take * ownership of those disposables that are added to it as array elements. */ export declare class ObsArray extends BaseObservable { private _ownedItems?; /** * Adds a callback to listen to changes in the observable. In case of `ObsArray`, the listener * gets additional information. */ addListener(callback: ISpliceListener): Listener; addListener(callback: ISpliceListener, context: C): Listener; /** * Take ownership of an item added to this array. This should _only_ be used for array elements, * not any unrelated items. */ autoDispose(value: T & IDisposable): T & IDisposable; /** @override */ dispose(): void; /** @internal */ protected _setWithSplice(value: T[], splice: IObsArraySplice): void; /** @internal */ protected _disposeOwned(splice?: IObsArraySplice): void; } /** * `MutableObsArray` adds array-like mutation methods which emit events with splice info, to * allow more efficient processing of such changes. It is created with `obsArray()`. */ export declare class MutableObsArray extends ObsArray { /** Appends elements to the end and returns the new length (like `Array#push`). */ push(...args: T[]): number; /** Removes and returns the last element (like `Array#pop`). */ pop(): T | undefined; /** Prepends elements to the start and returns the new length (like `Array#unshift`). */ unshift(...args: T[]): number; /** Removes and returns the first element (like `Array#shift`). */ shift(): T | undefined; /** * Removes and/or inserts elements at a given index and returns the removed elements (like * `Array#splice`). */ splice(start: number, deleteCount?: number, ...newValues: T[]): T[]; } /** * Creates a new MutableObsArray with an optional initial value, defaulting to the empty array. * It is essentially the same as `observable`, but with array-like mutation methods. */ export declare function obsArray(value?: T[]): MutableObsArray; /** * See [`computedArray()`](#computedArray) for documentation. */ export declare class ComputedArray extends ObsArray { private _mapper; private _sub; private _source?; private _listener?; private _lastSplice?; constructor(obsArr: BaseObservable | Observable>, _mapper: (item: T, index: number, arr: ComputedArray) => U); /** @internal */ dispose(): void; private _syncMap; private _unsync; private _rebuild; private _applySplice; private _recordChange; } /** * Returns an `ObsArray` that maps all elements of the passed-in `ObsArray` through a mapper * function. Also accepts an observable (e.g. a computed) whose value is an `ObsArray`. * ```ts * computedArray(obsArray, mapper) * ``` * * The result is analogous to: * ```ts * computed((use) => use(obsArray).map(mapper)) // for ObsArray * computed((use) => use(use(obsArray)).map(mapper)) // for Observable * ``` * * The benefit of `computedArray()` is that a small change to the source array (e.g. one item * added or removed), causes a small change to the mapped array, rather than a full rebuild. * * This is useful with an `ObsArray` or with an observable whose value is an `ObsArray`, and also * when the computed array's items are disposable and it owns them. * * There is no need or benefit to using `computedArray()` if you have a `computed()` that returns * a plain array. It is specifically for the case when you want to preserve the efficiency of * `ObsArray` when you map its values. * * Note that the mapper function is called with `(item, index, array)` as for a standard * `array.map()`, but that the index is only accurate at the time of the call, and will stop * reflecting the true index if more items are inserted into the array later. * * As with `ObsArray`, a `ComputedArray` may be used with disposable elements as their owners. E.g. * ```ts * const values = obsArray(); * const compArr = computedArray(values, (val, i, compArr) => D.create(compArr, val)); * values.push("foo", "bar"); // D("foo") and D("bar") get created * values.pop(); // D("bar") gets disposed. * compArr.dispose(); // D("foo") gets disposed. * ``` * * Note that only the pattern above works: obsArray (or compArray) may only be used to take * ownership of those disposables that are added to it as array elements. */ export declare function computedArray(obsArr: BaseObservable | Observable>, mapper: (item: T, index: number, arr: ComputedArray) => U): ObsArray; /** * Returns a new observable representing an index into this array. It can be read and written, and * its value is clamped to be a valid index. The index is only null if the array is empty. * * As the array changes, the index is adjusted to continue pointing to the same element. If the * pointed element is deleted, the index is adjusted to after the deletion point. * * The returned observable has an additional .setLive(bool) method. While set to false, the * observable will not be adjusted as the array changes, except to keep it valid. */ export declare function makeLiveIndex(owner: IDisposableOwnerT | null, obsArr: ObsArray, initialIndex?: number): LiveIndex; /** * An Observable that represents an index into an `ObsArray`, clamped to be in the valid range. */ export declare class LiveIndex extends Observable { private _obsArray; private _listener; private _isLive; constructor(_obsArray: ObsArray, initialIndex?: number); /** * Set the index, clamping it to a valid value. */ set(index: number | null): void; /** * Turn "liveness" on or off. While set to false, the observable will not be adjusted as the * array changes, except to keep it valid. * * @privateRemarks * Note that this feature comes from a rather obscure need, and it would be better if something * similar were possible without making it an explicit feature. */ setLive(value: boolean): void; /** @override */ dispose(): void; private _onArrayChange; }