tracked-instance
Version:
Build large forms and track all changes
44 lines (43 loc) • 2.48 kB
TypeScript
import { ComputedRef, Raw, Ref } from 'vue';
import { TrackedInstance, TrackedInstanceOptions } from './tracked-instance';
export type CollectionItem<Item, Meta = undefined> = Raw<{
instance: TrackedInstance<Item>;
/** Arbitrary metadata attached to this item, produced by CollectionOptions.createItemMeta. */
meta: Meta;
/** True when the item has been soft-deleted via remove(). */
isRemoved: Ref<boolean>;
/** True for items added via add() after the last loadData() call. */
isNew: Ref<boolean>;
/** Removes this item from the collection. Shortcut for calling collection.remove(index). */
remove: (isHardRemoved?: boolean) => void;
}>;
export interface Collection<Item, Meta = undefined> {
items: Ref<CollectionItem<Item, Meta>[]>;
/** True when any item is modified, newly added, or soft-deleted. */
isDirty: ComputedRef<boolean>;
/** Adds an item to the collection. Inserts at the end by default; pass `index` to insert elsewhere. */
add: (item: Item, index?: number) => CollectionItem<Item, Meta>;
/** Soft-deletes an item by index (sets isRemoved). Pass isHardRemove=true to splice immediately. */
remove: (index: number, isHardRemove?: boolean) => void;
/** Replaces all items and clears the dirty state. The loaded items become the new baseline. */
loadData: (items: Item[]) => void;
/** Reverts all changes: drops new items, restores removed items, resets modified fields. */
reset: () => void;
}
export interface CollectionOptions<Item, Meta = undefined> extends TrackedInstanceOptions {
/**
* Factory called when a collection item is created (via loadData or add).
* Use it to attach arbitrary metadata to each item — UI flags, sub-forms, derived state —
* that lives alongside the tracked instance but is not part of the tracked data.
* Receives the newly created TrackedInstance so the meta can reference reactive instance fields.
*/
createItemMeta?: (instance: TrackedInstance<Item>) => Meta;
}
/**
* Creates a reactive collection of TrackedInstance items.
*
* Tracks additions, removals, and field-level modifications across all items.
* Each item is wrapped with markRaw to prevent Vue from making the collection item
* itself deeply reactive — only instance.data, isRemoved, and isNew carry reactivity.
*/
export declare const useCollection: <Item = any, Meta = undefined>(options?: CollectionOptions<Item, Meta>) => Collection<Item, Meta>;