UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

59 lines (58 loc) 2.09 kB
import { type ImmutableArray } from "./array.js"; import type { BranchData, BranchKey, Data, LeafData, LeafKey } from "./data.js"; /** * Set of named updates for a data object. * * Note: string templates infer best when you have fixed character(s) at the start, * so our `Update` syntax always */ export type Updates<T extends Data = Data> = { /** * Set update (all branches) * - Can set `a` and `a.a1` in `{ a: { a1: 123 } }` * - Sometimes inference gets confused, if that happens use `=` syntax instead. */ readonly [K in BranchKey<T> as `${K}`]?: BranchData<T>[K] | undefined; } & { /** * Set update (leaves only) * - Can set `a.a1` in `{ a: { a1: 123 } }`, but cannot set `a` * - Deeply-nested properties don't always infer when leaves and branches are combined. * - This syntax is more exact and will infer better. */ readonly [K in LeafKey<T> as `=${K}`]?: LeafData<T>[K] | undefined; } & { /** * Sum update. * - Increment/decrement numbers. */ readonly [K in LeafKey<T> as `+=${K}` | `-=${K}`]?: LeafData<T>[K] extends number ? LeafData<T>[K] | undefined : never; } & { /** * With/omit update. * - Add or remove items from arrays. */ readonly [K in LeafKey<T> as `+[]${K}` | `-[]${K}`]?: LeafData<T>[K] extends ImmutableArray<unknown> ? LeafData<T>[K] | LeafData<T>[K][number] | undefined : never; }; /** A single update to a keyed property in an object. */ export type Update = { action: "set"; key: string; value: unknown; } | { action: "with"; key: string; value: ImmutableArray<unknown>; } | { action: "omit"; key: string; value: ImmutableArray<unknown>; } | { action: "sum"; key: string; value: number; }; /** Yield the prop updates in an `Updates` object as a set of `Update` objects. */ export declare function getUpdates<T extends Data>(data: Updates<T>): ImmutableArray<Update>; /** Update a data object with a set of updates. */ export declare function updateData<T extends Data>(data: T, updates: Updates<T>): T;