Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@thi.ng/paths

Package Overview
Dependencies
Maintainers
1
Versions
199
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@thi.ng/paths - npm Package Compare versions

Comparing version 3.0.5 to 4.0.0

12

api.d.ts

@@ -1,11 +0,3 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7 } from "@thi.ng/api";
export declare type Path1<T, A extends Keys<T>> = [A];
export declare type Path2<T, A extends Keys<T>, B extends Keys1<T, A>> = [A, B];
export declare type Path3<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>> = [A, B, C];
export declare type Path4<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>> = [A, B, C, D];
export declare type Path5<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>> = [A, B, C, D, E];
export declare type Path6<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>> = [A, B, C, D, E, F];
export declare type Path7<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>> = [A, B, C, D, E, F, G];
export declare type Path8<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>> = [A, B, C, D, E, F, G, H];
export declare type UpdateFn<T> = (curr: T, ...args: any[]) => T;
import type { FnO } from "@thi.ng/api";
export declare type UpdateFn<A, B> = FnO<A, B>;
//# sourceMappingURL=api.d.ts.map

27

CHANGELOG.md

@@ -6,34 +6,27 @@ # Change Log

## [3.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@3.0.4...@thi.ng/paths@3.0.5) (2020-03-06)
# [4.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@3.0.5...@thi.ng/paths@4.0.0) (2020-03-28)
**Note:** Version bump only for package @thi.ng/paths
### Code Refactoring
* **paths:** update path value inference ([ab4440e](https://github.com/thi-ng/umbrella/commit/ab4440e6a297559ceb824c5e4b3c7e023ae69710))
### Features
## [3.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@3.0.3...@thi.ng/paths@3.0.4) (2020-02-26)
* **paths:** add/update unsafe type infer, update doc strings ([5cc5b46](https://github.com/thi-ng/umbrella/commit/5cc5b461e9602011b62c49d8d4a6756e1ad4a404))
* **paths:** major API update ([b51efc6](https://github.com/thi-ng/umbrella/commit/b51efc69834e178344c4d1c1e47961460acedd8f))
* **paths:** update typed path sigs ([0b6c155](https://github.com/thi-ng/umbrella/commit/0b6c155d8d6cf9bd3f25bfce723cac2de48ad544))
**Note:** Version bump only for package @thi.ng/paths
### BREAKING CHANGES
* **paths:** update generics for `UpdateFn`
- UpdateFn now takes input & output type generics
## [3.0.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@3.0.2...@thi.ng/paths@3.0.3) (2020-02-26)
**Note:** Version bump only for package @thi.ng/paths
## [3.0.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@3.0.1...@thi.ng/paths@3.0.2) (2020-02-25)
**Note:** Version bump only for package @thi.ng/paths
# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@2.1.6...@thi.ng/paths@3.0.0) (2019-11-30)

@@ -40,0 +33,0 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Without, Without2, Without3, Without4, Without5, Without6, Without7, Without8 } from "@thi.ng/api";
/**
* Uses {@link updateIn} and returns updated state with key for given
* path removed. Does not modify original state.Returns `undefined` if
* `path` is an empty string or array.
* Unchecked version of {@link deleteIn}. Path can be given as string or
* tuple.
*
* ```
* @example
* ```ts
* // unchecked
* deleteIn({ a: { b: { c: 23 } } }, "a.b.c");

@@ -15,17 +16,34 @@ * // { a: { b: { } } }

*/
export declare const deleteIn: (state: any, path: Path) => Pick<any, never>;
export declare const deleteInUnsafe: (state: any, path: Path) => any;
/**
* Type checked version of {@link deleteIn}.
* Uses {@link updateIn} and returns updated state with key for given
* path removed. Does not modify original state. Returns `undefined` if
* `path` is an empty string or array.
*
* @remarks
* Only the first 8 path levels are type checked. The result type will
* have the path value removed too.
*
* See {@link deleteInUnsafe} for unchecked version.
*
* @example
* ```ts
* // type checked
* deleteIn({ a: { b: { c: 23 } } }, ["a","b","c"]);
*
* // error (invalid path)
* deleteIn({ a: { b: { c: 23 } } }, ["a","b","d"]);
* ```
*
* @param state -
* @param path -
*/
export declare function deleteInT<T, A extends Keys<T>>(state: T, path: [A]): Without<T, A>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: [A, B]): Without2<T, A, B>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: [A, B, C]): Without3<T, A, B, C>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: [A, B, C, D]): Without4<T, A, B, C, D>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: [A, B, C, D, E]): Without5<T, A, B, C, D, E>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: [A, B, C, D, E, F]): Without6<T, A, B, C, D, E, F>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(state: T, path: [A, B, C, D, E, F, G]): Without7<T, A, B, C, D, E, F, G>;
export declare function deleteInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H]): Without8<T, A, B, C, D, E, F, G, H>;
export declare function deleteIn<T, A extends Keys<T>>(state: T, path: readonly [A]): Without<T, A>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: readonly [A, B]): Without2<T, A, B>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: readonly [A, B, C]): Without3<T, A, B, C>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: readonly [A, B, C, D]): Without4<T, A, B, C, D>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: readonly [A, B, C, D, E]): Without5<T, A, B, C, D, E>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: readonly [A, B, C, D, E, F]): Without6<T, A, B, C, D, E, F>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(state: T, path: readonly [A, B, C, D, E, F, G]): Without7<T, A, B, C, D, E, F, G>;
export declare function deleteIn<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: readonly [A, B, C, D, E, F, G, H]): Without8<T, A, B, C, D, E, F, G, H>;
//# sourceMappingURL=delete-in.d.ts.map
import { toPath } from "./path";
import { updateInT } from "./update-in";
import { updateIn } from "./update-in";
/**
* Uses {@link updateIn} and returns updated state with key for given
* path removed. Does not modify original state.Returns `undefined` if
* `path` is an empty string or array.
* Unchecked version of {@link deleteIn}. Path can be given as string or
* tuple.
*
* ```
* @example
* ```ts
* // unchecked
* deleteIn({ a: { b: { c: 23 } } }, "a.b.c");

@@ -16,9 +17,9 @@ * // { a: { b: { } } }

*/
export const deleteIn = (state, path) => deleteInT(state, path);
export function deleteInT(state, path) {
const ks = [...toPath(path)];
if (ks.length > 0) {
export const deleteInUnsafe = (state, path) => deleteIn(state, path);
export function deleteIn(state, path) {
const ks = toPath(path).slice();
if (ks.length) {
const k = ks.pop();
return updateInT(state, ks, (x) => ((x = Object.assign({}, x)), delete x[k], x));
return updateIn(state, ks, (x) => ((x = Object.assign({}, x)), delete x[k], x));
}
}

@@ -1,18 +0,14 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Path, Path0, Path1, Path3, Path4, Path5, Path6, Path7, Path8, OptPathVal } from "@thi.ng/api";
/**
* Immediate use getter, i.e. same as: `getter(path)(state)`.
* Unchecked version of {@link getIn}. Returns `undefined` if path is
* invalid.
*
* @remarks
* Supports type checked paths and values for path lengths <= 8. String
* paths are always unchecked (i.e. `state` is `any`).
* The type parameter `T` can be used to indicate the type of the nested
* value to be retrieved (default: `any`).
*
* @example
* ```ts
* // checked path and inferred return type
* getIn({ a: { b: { c: 23 } } }, ["a","b","c"]);
* getInUnsafe({ a: { b: { c: 23 } } }, "a.b.c");
* // 23
*
* // unchecked path
* getIn({ a: { b: { c: 23 } } }, "a.b.c");
* // 23
* ```

@@ -23,19 +19,30 @@ *

*/
export declare const getIn: (state: any, path: Path) => any;
export declare const getInUnsafe: <T = any>(state: any, path: Path) => T | undefined;
/**
* Type checked version of {@link getIn}.
* Type checked, immediate use getter, i.e. same as:
* `defGetter(path)(state)`.
*
* @remarks
* Only the first 8 path levels are type checked.
*
* @example
* ```ts
* // type checked path and inferred return type
* getIn({ a: { b: { c: 23 } } }, ["a","b","c"]);
* // 23
* ```
*
* @param state -
* @param path -
*/
export declare function getInT<T>(state: T, path: []): T;
export declare function getInT<T, A extends Keys<T>>(state: T, path: [A]): Val1<T, A>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: [A, B]): Val2<T, A, B>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: [A, B, C]): Val3<T, A, B, C>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: [A, B, C, D]): Val4<T, A, B, C, D>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: [A, B, C, D, E]): Val5<T, A, B, C, D, E>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: [A, B, C, D, E, F]): Val6<T, A, B, C, D, E, F>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(state: T, path: [A, B, C, D, E, F, G]): Val7<T, A, B, C, D, E, F, G>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H]): Val8<T, A, B, C, D, E, F, G, H>;
export declare function getInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H, ...any[]]): any;
export declare function getIn<T>(state: T, path: Path0): T;
export declare function getIn<T, A>(state: T, path: Path1<T, A>): OptPathVal<T, [A]>;
export declare function getIn<T, A, B>(state: T, path: Path1<A, B>): OptPathVal<T, [A, B]>;
export declare function getIn<T, A, B, C>(state: T, path: Path3<T, A, B, C>): OptPathVal<T, [A, B, C]>;
export declare function getIn<T, A, B, C, D>(state: T, path: Path4<T, A, B, C, D>): OptPathVal<T, [A, B, C, D]>;
export declare function getIn<T, A, B, C, D, E>(state: T, path: Path5<T, A, B, C, D, E>): OptPathVal<T, [A, B, C, D, E]>;
export declare function getIn<T, A, B, C, D, E, F>(state: T, path: Path6<T, A, B, C, D, E, F>): OptPathVal<T, [A, B, C, D, E, F]>;
export declare function getIn<T, A, B, C, D, E, F, G>(state: T, path: Path7<T, A, B, C, D, E, F, G>): OptPathVal<T, [A, B, C, D, E, F, G]>;
export declare function getIn<T, A, B, C, D, E, F, G, H>(state: T, path: Path8<T, A, B, C, D, E, F, G, H>): OptPathVal<T, [A, B, C, D, E, F, G, H]>;
export declare function getIn<T, A, B, C, D, E, F, G, H>(state: T, path: DeepPath<T, A, B, C, D, E, F, G, H>): any;
//# sourceMappingURL=get-in.d.ts.map

@@ -1,18 +0,14 @@

import { getterT } from "./getter";
import { defGetter } from "./getter";
/**
* Immediate use getter, i.e. same as: `getter(path)(state)`.
* Unchecked version of {@link getIn}. Returns `undefined` if path is
* invalid.
*
* @remarks
* Supports type checked paths and values for path lengths <= 8. String
* paths are always unchecked (i.e. `state` is `any`).
* The type parameter `T` can be used to indicate the type of the nested
* value to be retrieved (default: `any`).
*
* @example
* ```ts
* // checked path and inferred return type
* getIn({ a: { b: { c: 23 } } }, ["a","b","c"]);
* getInUnsafe({ a: { b: { c: 23 } } }, "a.b.c");
* // 23
*
* // unchecked path
* getIn({ a: { b: { c: 23 } } }, "a.b.c");
* // 23
* ```

@@ -23,5 +19,5 @@ *

*/
export const getIn = (state, path) => getterT(path)(state);
export function getInT(state, path) {
return getterT(path)(state);
export const getInUnsafe = (state, path) => defGetter(path)(state);
export function getIn(state, path) {
return defGetter(path)(state);
}

@@ -1,22 +0,42 @@

import type { Fn, Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Fn, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, OptPathVal } from "@thi.ng/api";
/**
* Composes a getter function for given nested lookup path. Optimized
* fast execution paths are provided for path lengths <= 4.
* Unchecked version of {@link defGetter}.
*
* @remarks
* The type parameter `T` can be used to indicate the type of the nested
* value to be retrieved (default: `any`).
*
* Also see: {@link getIn}, {@link getInUnsafe}
*
* @example
* ```ts
* const g = defGetterUnsafe("a.b.c");
*
* g({ a: { b: { c: 23} } }) // 23
* g({ x: 23 }) // undefined
* g() // undefined
* ```
*
* @param path -
*/
export declare const defGetterUnsafe: <T = any>(path: Path) => Fn<any, T | undefined>;
/**
* Creates getter function for given nested lookup path. Returns
* function which accepts single object and returns value at given path.
*
* @remarks
* Optimized fast execution paths are provided for path lengths <= 4.
* Only the first 8 path levels are type checked.
*
* Supports any `[]`-indexable data structure (arrays, objects,
* strings).
*
* If `path` is given as string, it will be split using `.`. Returns
* function which accepts single object and when called, returns value
* at given path.
* If any intermediate key is not present in the given obj, further
* descent stops and the function returns `undefined`.
*
* If any intermediate key is not present in the given obj, descent
* stops and the function returns `undefined`.
* If `path` is an empty array, the returned getter will simply return
* the given state arg (aka identity function).
*
* If `path` is an empty string or array, the returned getter will
* simply return the given state arg (identity function).
* Also see: {@link defGetterUnsafe}, {@link getIn}, {@link getInUnsafe}
*
* Also see: `getIn()`
*
* @example

@@ -28,14 +48,11 @@ * ```ts

*
* // fully typed getter
* g = getter<Foo, "a", "b", "c">(["a","b","c"]);
* // fully type checked getter
* g = defGetter<Foo, "a", "b", "c">(["a","b","c"]);
*
* // error (wrong `d` key)
* g = getter<Foo, "a", "b", "d">(["a","b","d"]);
* g = defGetter<Foo, "a", "b", "d">(["a","b","d"]);
*
* // unchecked (accepts any, returns any)
* g = getter("a.b.c");
*
* g({ a: { b: { c: 23} } }) // 23
* g({ x: 23 }) // undefined
* g() // undefined
* g({ a: { b: { c: 23} } }); // 23
* g({ x: 23 }); // error
* g(); // error
* ```

@@ -45,18 +62,12 @@ *

*/
export declare const getter: (path: Path) => Fn<any, any>;
/**
* Type checked version of {@link getter}.
*
* @param path -
*/
export declare function getterT<T>(path: []): Fn<T, T>;
export declare function getterT<T, A extends Keys<T>>(path: [A]): Fn<T, Val1<T, A>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>>(path: [A, B]): Fn<T, Val2<T, A, B>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(path: [A, B, C]): Fn<T, Val3<T, A, B, C>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(path: [A, B, C, D]): Fn<T, Val4<T, A, B, C, D>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(path: [A, B, C, D, E]): Fn<T, Val5<T, A, B, C, D, E>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(path: [A, B, C, D, E, F]): Fn<T, Val6<T, A, B, C, D, E, F>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(path: [A, B, C, D, E, F, G]): Fn<T, Val7<T, A, B, C, D, E, F, G>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H]): Fn<T, Val8<T, A, B, C, D, E, F, G, H>>;
export declare function getterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H, ...any[]]): Fn<T, any>;
export declare function defGetter<T>(path: Path0): Fn<T, T>;
export declare function defGetter<T, A>(path: Path1<T, A>): Fn<T, OptPathVal<T, [A]>>;
export declare function defGetter<T, A, B>(path: Path2<T, A, B>): Fn<T, OptPathVal<T, [A, B]>>;
export declare function defGetter<T, A, B, C>(path: Path3<T, A, B, C>): Fn<T, OptPathVal<T, [A, B, C]>>;
export declare function defGetter<T, A, B, C, D>(path: Path4<T, A, B, C, D>): Fn<T, OptPathVal<T, [A, B, C, D]>>;
export declare function defGetter<T, A, B, C, D, E>(path: Path5<T, A, B, C, D, E>): Fn<T, OptPathVal<T, [A, B, C, D, E]>>;
export declare function defGetter<T, A, B, C, D, E, F>(path: Path6<T, A, B, C, D, E, F>): Fn<T, OptPathVal<T, [A, B, C, D, E, F]>>;
export declare function defGetter<T, A, B, C, D, E, F, G>(path: Path7<T, A, B, C, D, E, F, G>): Fn<T, OptPathVal<T, [A, B, C, D, E, F, G]>>;
export declare function defGetter<T, A, B, C, D, E, F, G, H>(path: Path8<T, A, B, C, D, E, F, G, H>): Fn<T, OptPathVal<T, [A, B, C, D, E, F, G, H]>>;
export declare function defGetter<T, A, B, C, D, E, F, G, H>(path: DeepPath<T, A, B, C, D, E, F, G, H>): Fn<T, any>;
//# sourceMappingURL=getter.d.ts.map
import { toPath } from "./path";
/**
* Composes a getter function for given nested lookup path. Optimized
* fast execution paths are provided for path lengths <= 4.
* Unchecked version of {@link defGetter}.
*
* @remarks
* Supports any `[]`-indexable data structure (arrays, objects,
* strings).
* The type parameter `T` can be used to indicate the type of the nested
* value to be retrieved (default: `any`).
*
* If `path` is given as string, it will be split using `.`. Returns
* function which accepts single object and when called, returns value
* at given path.
* Also see: {@link getIn}, {@link getInUnsafe}
*
* If any intermediate key is not present in the given obj, descent
* stops and the function returns `undefined`.
*
* If `path` is an empty string or array, the returned getter will
* simply return the given state arg (identity function).
*
* Also see: `getIn()`
*
* @example
* ```ts
* interface Foo {
* a: { b: { c: number; } }
* }
* const g = defGetterUnsafe("a.b.c");
*
* // fully typed getter
* g = getter<Foo, "a", "b", "c">(["a","b","c"]);
*
* // error (wrong `d` key)
* g = getter<Foo, "a", "b", "d">(["a","b","d"]);
*
* // unchecked (accepts any, returns any)
* g = getter("a.b.c");
*
* g({ a: { b: { c: 23} } }) // 23

@@ -44,6 +22,6 @@ * g({ x: 23 }) // undefined

*/
export const getter = (path) => getterT(path);
export function getterT(path) {
export const defGetterUnsafe = (path) => defGetter(path);
export function defGetter(path) {
const ks = toPath(path);
let [a, b, c, d] = ks;
const [a, b, c, d] = ks;
switch (ks.length) {

@@ -50,0 +28,0 @@ case 0:

@@ -35,6 +35,6 @@ 'use strict';

const getter = (path) => getterT(path);
function getterT(path) {
const defGetterUnsafe = (path) => defGetter(path);
function defGetter(path) {
const ks = toPath(path);
let [a, b, c, d] = ks;
const [a, b, c, d] = ks;
switch (ks.length) {

@@ -77,6 +77,6 @@ case 0:

const setter = (path) => setterT(path);
function setterT(path) {
const defSetterUnsafe = (path) => defSetter(path);
function defSetter(path) {
const ks = toPath(path);
let [a, b, c, d] = ks;
const [a, b, c, d] = ks;
switch (ks.length) {

@@ -86,8 +86,8 @@ case 0:

case 1:
return (s, v) => ((s = _copy(s)), (s[a] = v), s);
return (s, v) => ((s = copy(s)), (s[a] = v), s);
case 2:
return (s, v) => {
let x;
s = _copy(s);
s[a] = x = _copy(s[a]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = v;

@@ -99,5 +99,5 @@ return s;

let x, y;
s = _copy(s);
s[a] = x = _copy(s[a]);
x[b] = y = _copy(x[b]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = y = copy(x[b]);
y[c] = v;

@@ -109,6 +109,6 @@ return s;

let x, y, z;
s = _copy(s);
s[a] = x = _copy(s[a]);
x[b] = y = _copy(x[b]);
y[c] = z = _copy(y[c]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = y = copy(x[b]);
y[c] = z = copy(y[c]);
z[d] = v;

@@ -125,26 +125,28 @@ return s;

}
const _copy = (s) => (checks.isArray(s) ? s.slice() : Object.assign({}, s));
const compS = (k, f) => (s, v) => ((s = _copy(s)), (s[k] = f ? f(s[k], v) : v), s);
const copy = (x) => checks.isArray(x) || checks.isTypedArray(x) ? x.slice() : Object.assign({}, x);
const compS = (k, f) => (s, v) => ((s = copy(s)), (s[k] = f ? f(s[k], v) : v), s);
const updateIn = (state, path, fn, ...args) => updateInT(state, path, fn, ...args);
function updateInT(state, path, fn, ...args) {
return setterT(path)(state, fn.apply(null, (args.unshift(getterT(path)(state)), args)));
const updateInUnsafe = (state, path, fn, ...args) =>
updateIn(state, path, fn, ...args);
function updateIn(state, path, fn, ...args) {
return defSetter(path)(state,
fn.apply(null, (args.unshift(defGetter(path)(state)), args)));
}
const deleteIn = (state, path) => deleteInT(state, path);
function deleteInT(state, path) {
const ks = [...toPath(path)];
if (ks.length > 0) {
const deleteInUnsafe = (state, path) => deleteIn(state, path);
function deleteIn(state, path) {
const ks = toPath(path).slice();
if (ks.length) {
const k = ks.pop();
return updateInT(state, ks, (x) => ((x = Object.assign({}, x)), delete x[k], x));
return updateIn(state, ks, (x) => ((x = Object.assign({}, x)), delete x[k], x));
}
}
const getIn = (state, path) => getterT(path)(state);
function getInT(state, path) {
return getterT(path)(state);
const getInUnsafe = (state, path) => defGetter(path)(state);
function getIn(state, path) {
return defGetter(path)(state);
}
const mutator = (path) => mutatorT(path);
function mutatorT(path) {
const defMutatorUnsafe = (path) => defMutator(path);
function defMutator(path) {
const ks = toPath(path);

@@ -204,22 +206,22 @@ let [a, b, c, d] = ks;

const mutIn = (state, path, val) => mutInT(state, path, val);
function mutInT(state, path, val) {
return mutatorT(path)(state, val);
const mutInUnsafe = (state, path, val) => defMutator(path)(state, val);
function mutIn(state, path, val) {
return defMutator(path)(state, val);
}
const mutInMany = (state, ...pairs) => {
function mutInManyUnsafe(state, ...pairs) {
const n = pairs.length;
n & 1 && errors.illegalArgs(`require even number of args (got ${pairs.length})`);
for (let i = 0; i < n && state; i += 2) {
state = mutInT(state, pairs[i], pairs[i + 1]);
state = mutIn(state, pairs[i], pairs[i + 1]);
}
return state;
};
}
const setIn = (state, path, val) => setterT(path)(state, val);
function setInT(state, path, val) {
return setterT(path)(state, val);
const setInUnsafe = (state, path, val) => defSetter(path)(state, val);
function setIn(state, path, val) {
return defSetter(path)(state, val);
}
const setInMany = (state, ...pairs) => {
function setInManyUnsafe(state, ...pairs) {
const n = pairs.length;

@@ -229,35 +231,36 @@ n & 1 &&

for (let i = 0; i < n; i += 2) {
state = setInT(state, pairs[i], pairs[i + 1]);
state = setIn(state, pairs[i], pairs[i + 1]);
}
return state;
};
}
const updater = (path, fn) => updaterT(path, fn);
function updaterT(path, fn) {
const g = getterT(path);
const s = setterT(path);
const defUpdaterUnsafe = (path, fn) => defUpdater(path, fn);
function defUpdater(path, fn) {
const g = defGetter(path);
const s = defSetter(path);
return (state, ...args) => s(state, fn.apply(null, (args.unshift(g(state)), args)));
}
exports.copy = copy;
exports.defGetter = defGetter;
exports.defGetterUnsafe = defGetterUnsafe;
exports.defMutator = defMutator;
exports.defMutatorUnsafe = defMutatorUnsafe;
exports.defSetter = defSetter;
exports.defSetterUnsafe = defSetterUnsafe;
exports.defUpdater = defUpdater;
exports.defUpdaterUnsafe = defUpdaterUnsafe;
exports.deleteIn = deleteIn;
exports.deleteInT = deleteInT;
exports.deleteInUnsafe = deleteInUnsafe;
exports.exists = exists;
exports.getIn = getIn;
exports.getInT = getInT;
exports.getter = getter;
exports.getterT = getterT;
exports.getInUnsafe = getInUnsafe;
exports.mutIn = mutIn;
exports.mutInMany = mutInMany;
exports.mutInT = mutInT;
exports.mutator = mutator;
exports.mutatorT = mutatorT;
exports.mutInManyUnsafe = mutInManyUnsafe;
exports.mutInUnsafe = mutInUnsafe;
exports.setIn = setIn;
exports.setInMany = setInMany;
exports.setInT = setInT;
exports.setter = setter;
exports.setterT = setterT;
exports.setInManyUnsafe = setInManyUnsafe;
exports.setInUnsafe = setInUnsafe;
exports.toPath = toPath;
exports.updateIn = updateIn;
exports.updateInT = updateInT;
exports.updater = updater;
exports.updaterT = updaterT;
exports.updateInUnsafe = updateInUnsafe;

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/checks"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/checks","@thi.ng/errors"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.paths={}),e.thi.ng.checks,e.thi.ng.errors)}(this,(function(e,t,n){"use strict";const r=e=>t.isArray(e)?e:t.isString(e)?e.length>0?e.split("."):[]:null!=e?[e]:[];function u(e){const t=r(e);let[n,u,l,s]=t;switch(t.length){case 0:return e=>e;case 1:return e=>null!=e?e[n]:void 0;case 2:return e=>null!=e&&null!=(e=e[n])?e[u]:void 0;case 3:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])?e[l]:void 0;case 4:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])&&null!=(e=e[l])?e[s]:void 0;default:return e=>{const n=t.length-1;let r=e;for(let e=0;null!=r&&e<=n;e++)r=r[t[e]];return r}}}function l(e){const t=r(e);let[n,u,l,o]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>((e=s(e))[n]=t,e);case 2:return(e,t)=>{let r;return(e=s(e))[n]=r=s(e[n]),r[u]=t,e};case 3:return(e,t)=>{let r,i;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=t,e};case 4:return(e,t)=>{let r,i,c;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=c=s(i[l]),c[o]=t,e};default:let e;for(let n=t.length;--n>=0;)e=i(t[n],e);return e}}const s=e=>t.isArray(e)?e.slice():Object.assign({},e),i=(e,t)=>(n,r)=>((n=s(n))[e]=t?t(n[e],r):r,n);function o(e,t,n,...r){return l(t)(e,n.apply(null,(r.unshift(u(t)(e)),r)))}function c(e,t){const n=[...r(t)];if(n.length>0){const t=n.pop();return o(e,n,e=>(delete(e=Object.assign({},e))[t],e))}}function a(e){const t=r(e);let[n,u,l,s]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>e?(e[n]=t,e):void 0;case 2:return(e,t)=>{let r;return e&&(r=e[n])?(r[u]=t,e):void 0};case 3:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])?(r[l]=t,e):void 0};case 4:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])&&(r=r[l])?(r[s]=t,e):void 0};default:return(e,n)=>{let r=e;const u=t.length-1;for(let e=0;e<u;e++)if(!(r=r[t[e]]))return;return r[t[u]]=n,e}}}function f(e,t,n){return a(t)(e,n)}function g(e,t,n){return l(t)(e,n)}function h(e,t){const n=u(e),r=l(e);return(e,...u)=>r(e,t.apply(null,(u.unshift(n(e)),u)))}e.deleteIn=(e,t)=>c(e,t),e.deleteInT=c,e.exists=(e,t)=>{if(null==e)return!1;for(let n=(t=r(t)).length-1,u=0;u<=n;u++){const r=t[u];if(!e.hasOwnProperty(r))return!1;if(null==(e=e[r])&&u<n)return!1}return!0},e.getIn=(e,t)=>u(t)(e),e.getInT=function(e,t){return u(t)(e)},e.getter=e=>u(e),e.getterT=u,e.mutIn=(e,t,n)=>f(e,t,n),e.mutInMany=(e,...t)=>{const r=t.length;1&r&&n.illegalArgs(`require even number of args (got ${t.length})`);for(let n=0;n<r&&e;n+=2)e=f(e,t[n],t[n+1]);return e},e.mutInT=f,e.mutator=e=>a(e),e.mutatorT=a,e.setIn=(e,t,n)=>l(t)(e,n),e.setInMany=(e,...t)=>{const r=t.length;1&r&&n.illegalArgs(`require even number of KV args (got ${t.length})`);for(let n=0;n<r;n+=2)e=g(e,t[n],t[n+1]);return e},e.setInT=g,e.setter=e=>l(e),e.setterT=l,e.toPath=r,e.updateIn=(e,t,n,...r)=>o(e,t,n,...r),e.updateInT=o,e.updater=(e,t)=>h(e,t),e.updaterT=h,Object.defineProperty(e,"__esModule",{value:!0})}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/checks"),require("@thi.ng/errors")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/checks","@thi.ng/errors"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.paths={}),e.thi.ng.checks,e.thi.ng.errors)}(this,(function(e,t,n){"use strict";const r=e=>t.isArray(e)?e:t.isString(e)?e.length>0?e.split("."):[]:null!=e?[e]:[];function u(e){const t=r(e),[n,u,l,s]=t;switch(t.length){case 0:return e=>e;case 1:return e=>null!=e?e[n]:void 0;case 2:return e=>null!=e&&null!=(e=e[n])?e[u]:void 0;case 3:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])?e[l]:void 0;case 4:return e=>null!=e&&null!=(e=e[n])&&null!=(e=e[u])&&null!=(e=e[l])?e[s]:void 0;default:return e=>{const n=t.length-1;let r=e;for(let e=0;null!=r&&e<=n;e++)r=r[t[e]];return r}}}function l(e){const t=r(e),[n,u,l,o]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>((e=s(e))[n]=t,e);case 2:return(e,t)=>{let r;return(e=s(e))[n]=r=s(e[n]),r[u]=t,e};case 3:return(e,t)=>{let r,i;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=t,e};case 4:return(e,t)=>{let r,i,f;return(e=s(e))[n]=r=s(e[n]),r[u]=i=s(r[u]),i[l]=f=s(i[l]),f[o]=t,e};default:let e;for(let n=t.length;--n>=0;)e=i(t[n],e);return e}}const s=e=>t.isArray(e)||t.isTypedArray(e)?e.slice():Object.assign({},e),i=(e,t)=>(n,r)=>((n=s(n))[e]=t?t(n[e],r):r,n);function o(e,t,n,...r){return l(t)(e,n.apply(null,(r.unshift(u(t)(e)),r)))}function f(e,t){const n=r(t).slice();if(n.length){const t=n.pop();return o(e,n,e=>(delete(e=Object.assign({},e))[t],e))}}function c(e){const t=r(e);let[n,u,l,s]=t;switch(t.length){case 0:return(e,t)=>t;case 1:return(e,t)=>e?(e[n]=t,e):void 0;case 2:return(e,t)=>{let r;return e&&(r=e[n])?(r[u]=t,e):void 0};case 3:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])?(r[l]=t,e):void 0};case 4:return(e,t)=>{let r;return e&&(r=e[n])&&(r=r[u])&&(r=r[l])?(r[s]=t,e):void 0};default:return(e,n)=>{let r=e;const u=t.length-1;for(let e=0;e<u;e++)if(!(r=r[t[e]]))return;return r[t[u]]=n,e}}}function a(e,t,n){return c(t)(e,n)}function d(e,t,n){return l(t)(e,n)}function h(e,t){const n=u(e),r=l(e);return(e,...u)=>r(e,t.apply(null,(u.unshift(n(e)),u)))}e.copy=s,e.defGetter=u,e.defGetterUnsafe=e=>u(e),e.defMutator=c,e.defMutatorUnsafe=e=>c(e),e.defSetter=l,e.defSetterUnsafe=e=>l(e),e.defUpdater=h,e.defUpdaterUnsafe=(e,t)=>h(e,t),e.deleteIn=f,e.deleteInUnsafe=(e,t)=>f(e,t),e.exists=(e,t)=>{if(null==e)return!1;for(let n=(t=r(t)).length-1,u=0;u<=n;u++){const r=t[u];if(!e.hasOwnProperty(r))return!1;if(null==(e=e[r])&&u<n)return!1}return!0},e.getIn=function(e,t){return u(t)(e)},e.getInUnsafe=(e,t)=>u(t)(e),e.mutIn=a,e.mutInManyUnsafe=function(e,...t){const r=t.length;1&r&&n.illegalArgs(`require even number of args (got ${t.length})`);for(let n=0;n<r&&e;n+=2)e=a(e,t[n],t[n+1]);return e},e.mutInUnsafe=(e,t,n)=>c(t)(e,n),e.setIn=d,e.setInManyUnsafe=function(e,...t){const r=t.length;1&r&&n.illegalArgs(`require even number of KV args (got ${t.length})`);for(let n=0;n<r;n+=2)e=d(e,t[n],t[n+1]);return e},e.setInUnsafe=(e,t,n)=>l(t)(e,n),e.toPath=r,e.updateIn=o,e.updateInUnsafe=(e,t,n,...r)=>o(e,t,n,...r),Object.defineProperty(e,"__esModule",{value:!0})}));

@@ -0,15 +1,21 @@

import type { Path } from "@thi.ng/api";
/**
* Similar to {@link mutIn}, but takes any number of path-value pairs as
* args and applies them in sequence using `mutIn()`. All key paths must
* already be present in the given data structure until their
* penultimate key.
* Similar to {@link mutInUnsafe}, but takes any number of path-value
* pairs as args and applies them in sequence using `mutInUnsafe()`.
*
* @remarks
* Unlike {@link mutIn}, this function does not use type checked paths.
* All intermediate path keys must already be present in the given data
* structure until their penultimate key. Missing leaf keys are
* supported.
*
* The type parameter `T` can be used to indicate the type of the state
* value and will also be used as return type.
*
* @example
* ```ts
* mutInMany(
* mutInManyUnsafe(
* { a: { b: 1 }, x: { y: { z: 2 } } },
* // pair #1
* "a.b", 10,
* // pair #2
* "x.y.z", 20

@@ -23,3 +29,7 @@ * )

*/
export declare const mutInMany: (state: any, ...pairs: any[]) => any;
export declare function mutInManyUnsafe<T>(state: T, p1: Path, v1: any): T;
export declare function mutInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any): T;
export declare function mutInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any): T;
export declare function mutInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any, p4: Path, v4: any): T;
export declare function mutInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any, p4: Path, v4: any, ...xs: any[]): T;
//# sourceMappingURL=mut-in-many.d.ts.map
import { illegalArgs } from "@thi.ng/errors";
import { mutInT } from "./mut-in";
/**
* Similar to {@link mutIn}, but takes any number of path-value pairs as
* args and applies them in sequence using `mutIn()`. All key paths must
* already be present in the given data structure until their
* penultimate key.
*
* @remarks
* Unlike {@link mutIn}, this function does not use type checked paths.
*
* @example
* ```ts
* mutInMany(
* { a: { b: 1 }, x: { y: { z: 2 } } },
* "a.b", 10,
* "x.y.z", 20
* )
* // { a: { b: 10 }, x: { y: { z: 20 } } }
* ```
*
* @param state -
* @param pairs -
*/
export const mutInMany = (state, ...pairs) => {
import { mutIn } from "./mut-in";
export function mutInManyUnsafe(state, ...pairs) {
const n = pairs.length;
n & 1 && illegalArgs(`require even number of args (got ${pairs.length})`);
for (let i = 0; i < n && state; i += 2) {
state = mutInT(state, pairs[i], pairs[i + 1]);
state = mutIn(state, pairs[i], pairs[i + 1]);
}
return state;
};
}

@@ -1,19 +0,11 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, PathVal } from "@thi.ng/api";
/**
* Immediate use mutator, i.e. same as: `mutator(path)(state, val)`.
* Unchecked version of {@link mutIn}.
*
* @remarks
* Also see {@link setIn}, {@link updateIn}, {@link deleteIn}.
* The type parameter `T` can be used to indicate the type of the nested
* value to be mutated (default: `any`).
*
* @example
* ```ts
* interface Foo {
* a: { b: number[]; }
* }
*
* // fully type checked
* mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23)
* // { a: { b: [ 10, 23 ] } }
*
* // unchecked
* mutIn({ a: { b: [10, 20] } }, "a.b.1", 23);

@@ -31,6 +23,18 @@ * // { a: { b: [ 10, 23 ] } }

*/
export declare const mutIn: (state: any, path: Path, val: any) => any;
export declare const mutInUnsafe: <T = any>(state: any, path: Path, val: T) => any;
/**
* Type checked version of {@link mutIn}.
* Type checked, immediate use mutator, i.e. same as:
* `defMutator(path)(state, val)`.
*
* @remarks
* Only the first 8 path levels are type checked.
*
* Also see {@link defMutator}, {@link mutInUnsafe}
*
* @example
* ```ts
* mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23)
* // { a: { b: [ 10, 23 ] } }
* ```
*
* @param state -

@@ -40,12 +44,12 @@ * @param path -

*/
export declare function mutInT<T>(state: T, path: [], val: T): T;
export declare function mutInT<T, A extends Keys<T>>(state: T, path: [A], val: Val1<T, A>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: [A, B], val: Val2<T, A, B>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: [A, B, C], val: Val3<T, A, B, C>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: [A, B, C, D], val: Val4<T, A, B, C, D>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: [A, B, C, D, E], val: Val5<T, A, B, C, D, E>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: [A, B, C, D, E, F], val: Val6<T, A, B, C, D, E, F>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, V>(state: T, path: [A, B, C, D, E, F, G], val: Val7<T, A, B, C, D, E, F, G>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H], val: Val8<T, A, B, C, D, E, F, G, H>): T;
export declare function mutInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H, ...PropertyKey[]], val: any): any;
export declare function mutIn<T>(state: T, path: Path0, val: T): T;
export declare function mutIn<T, A>(state: T, path: Path1<T, A>, val: PathVal<T, [A]>): T;
export declare function mutIn<T, A, B>(state: T, path: Path2<T, A, B>, val: PathVal<T, [A, B]>): T;
export declare function mutIn<T, A, B, C>(state: T, path: Path3<T, A, B, C>, val: PathVal<T, [A, B, C]>): T;
export declare function mutIn<T, A, B, C, D>(state: T, path: Path4<T, A, B, C, D>, val: PathVal<T, [A, B, C, D]>): T;
export declare function mutIn<T, A, B, C, D, E>(state: T, path: Path5<T, A, B, C, D, E>, val: PathVal<T, [A, B, C, D, E]>): T;
export declare function mutIn<T, A, B, C, D, E, F>(state: T, path: Path6<T, A, B, C, D, E, F>, val: PathVal<T, [A, B, C, D, E, F]>): T;
export declare function mutIn<T, A, B, C, D, E, F, G>(state: T, path: Path7<T, A, B, C, D, E, F, G>, val: PathVal<T, [A, B, C, D, E, F, G]>): T;
export declare function mutIn<T, A, B, C, D, E, F, G, H>(state: T, path: Path8<T, A, B, C, D, E, F, G, H>, val: PathVal<T, [A, B, C, D, E, F, G, H]>): T;
export declare function mutIn<T, A, B, C, D, E, F, G, H>(state: T, path: DeepPath<T, A, B, C, D, E, F, G, H>, val: any): any;
//# sourceMappingURL=mut-in.d.ts.map

@@ -1,19 +0,11 @@

import { mutatorT } from "./mutator";
import { defMutator } from "./mutator";
/**
* Immediate use mutator, i.e. same as: `mutator(path)(state, val)`.
* Unchecked version of {@link mutIn}.
*
* @remarks
* Also see {@link setIn}, {@link updateIn}, {@link deleteIn}.
* The type parameter `T` can be used to indicate the type of the nested
* value to be mutated (default: `any`).
*
* @example
* ```ts
* interface Foo {
* a: { b: number[]; }
* }
*
* // fully type checked
* mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23)
* // { a: { b: [ 10, 23 ] } }
*
* // unchecked
* mutIn({ a: { b: [10, 20] } }, "a.b.1", 23);

@@ -31,5 +23,5 @@ * // { a: { b: [ 10, 23 ] } }

*/
export const mutIn = (state, path, val) => mutInT(state, path, val);
export function mutInT(state, path, val) {
return mutatorT(path)(state, val);
export const mutInUnsafe = (state, path, val) => defMutator(path)(state, val);
export function mutIn(state, path, val) {
return defMutator(path)(state, val);
}

@@ -1,7 +0,18 @@

import type { Fn2, Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Fn2, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, PathVal } from "@thi.ng/api";
/**
* Higher-order function, similar to {@link setter}. Returns function
* which when called mutates given object/array at given path location.
* Unchecked version of {@link defMutator}.
*
* @remarks
* The type parameter `T` can be used to indicate the type of the nested
* value to be mutated (default: `any`).
*
* @param path -
*/
export declare const defMutatorUnsafe: <T = any>(path: Path) => Fn2<any, T, any>;
/**
* Higher-order function, similar to {@link defSetter}. Returns a
* function, which when called, mutates given object/array at given path
* location.
*
* @remarks
* The returned function bails if any intermediate path values are

@@ -11,23 +22,20 @@ * non-indexable (only the very last path element can be missing in the

* object, else `undefined`. This function provides optimized versions
* for path lengths <= 4. Type checking is supported for path lengths <=
* 8.
* for path lengths <= 4.
*
* @param path -
*/
export declare const mutator: (path: Path) => Fn2<any, any, any>;
/**
* Type checked version of {@link mutator}.
* Only the first 8 path levels are type checked.
*
* Also see {@link defMutatorUnsafe}, {@link mutIn}
*
* @param path -
*/
export declare function mutatorT<T>(path: []): Fn2<T, T, T>;
export declare function mutatorT<T, A extends Keys<T>>(path: [A]): Fn2<T, Val1<T, A>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>>(path: [A, B]): Fn2<T, Val2<T, A, B>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(path: [A, B, C]): Fn2<T, Val3<T, A, B, C>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(path: [A, B, C, D]): Fn2<T, Val4<T, A, B, C, D>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(path: [A, B, C, D, E]): Fn2<T, Val5<T, A, B, C, D, E>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(path: [A, B, C, D, E, F]): Fn2<T, Val6<T, A, B, C, D, E, F>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(path: [A, B, C, D, E, F, G]): Fn2<T, Val7<T, A, B, C, D, E, F, G>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H]): Fn2<T, Val8<T, A, B, C, D, E, F, G, H>, T>;
export declare function mutatorT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H, ...PropertyKey[]]): Fn2<T, any, any>;
export declare function defMutator<T>(path: Path0): Fn2<T, T, T>;
export declare function defMutator<T, A>(path: Path1<T, A>): Fn2<T, PathVal<T, [A]>, T>;
export declare function defMutator<T, A, B>(path: Path2<T, A, B>): Fn2<T, PathVal<T, [A, B]>, T>;
export declare function defMutator<T, A, B, C>(path: Path3<T, A, B, C>): Fn2<T, PathVal<T, [A, B, C]>, T>;
export declare function defMutator<T, A, B, C, D>(path: Path4<T, A, B, C, D>): Fn2<T, PathVal<T, [A, B, C, D]>, T>;
export declare function defMutator<T, A, B, C, D, E>(path: Path5<T, A, B, C, D, E>): Fn2<T, PathVal<T, [A, B, C, D, E]>, T>;
export declare function defMutator<T, A, B, C, D, E, F>(path: Path6<T, A, B, C, D, E, F>): Fn2<T, PathVal<T, [A, B, C, D, E, F]>, T>;
export declare function defMutator<T, A, B, C, D, E, F, G>(path: Path7<T, A, B, C, D, E, F, G>): Fn2<T, PathVal<T, [A, B, C, D, E, F, G]>, T>;
export declare function defMutator<T, A, B, C, D, E, F, G, H>(path: Path8<T, A, B, C, D, E, F, G, H>): Fn2<T, PathVal<T, [A, B, C, D, E, F, G, H]>, T>;
export declare function defMutator<T, A, B, C, D, E, F, G, H>(path: DeepPath<T, A, B, C, D, E, F, G, H>): Fn2<T, any, any>;
//# sourceMappingURL=mutator.d.ts.map
import { toPath } from "./path";
/**
* Higher-order function, similar to {@link setter}. Returns function
* which when called mutates given object/array at given path location.
* Unchecked version of {@link defMutator}.
*
* @remarks
* The returned function bails if any intermediate path values are
* non-indexable (only the very last path element can be missing in the
* actual object structure). If successful, returns original (mutated)
* object, else `undefined`. This function provides optimized versions
* for path lengths <= 4. Type checking is supported for path lengths <=
* 8.
* The type parameter `T` can be used to indicate the type of the nested
* value to be mutated (default: `any`).
*
* @param path -
*/
export const mutator = (path) => mutatorT(path);
export function mutatorT(path) {
export const defMutatorUnsafe = (path) => defMutator(path);
export function defMutator(path) {
const ks = toPath(path);

@@ -19,0 +14,0 @@ let [a, b, c, d] = ks;

{
"name": "@thi.ng/paths",
"version": "3.0.5",
"version": "4.0.0",
"description": "Immutable, optimized and optionally typed path-based object property / array accessors with structural sharing",

@@ -24,3 +24,3 @@ "module": "./index.js",

"clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib",
"doc:readme": "../../scripts/generate-readme",
"doc:readme": "ts-node -P ../../tools/tsconfig.json ../../tools/src/readme.ts",
"doc": "node_modules/.bin/typedoc --mode modules --out doc src",

@@ -42,4 +42,5 @@ "doc:ae": "mkdir -p .ae/doc .ae/temp && node_modules/.bin/api-extractor run --local --verbose",

"dependencies": {
"@thi.ng/checks": "^2.5.4",
"@thi.ng/errors": "^1.2.7"
"@thi.ng/checks": "^2.6.0",
"@thi.ng/errors": "^1.2.8",
"tslib": "^1.11.1"
},

@@ -69,3 +70,3 @@ "keywords": [

"sideEffects": false,
"gitHead": "18014ee1e4978dac7eb2e5d51d0a6ff7d82e9ffc"
"gitHead": "202477e312cf26869f0421e42a9a5fd80ff6adc8"
}

@@ -18,3 +18,3 @@ import type { Path } from "@thi.ng/api";

*/
export declare const toPath: (path: Path) => (string | number | symbol)[];
export declare const toPath: (path: Path) => (string | number)[];
/**

@@ -21,0 +21,0 @@ * Takes an arbitrary object and lookup path. Descends into object along

<!-- This file is generated - DO NOT EDIT! -->
# ![@thi.ng/paths](https://media.thi.ng/umbrella/banners/thing-paths.svg?1583078711)
# ![@thi.ng/paths](https://media.thi.ng/umbrella/banners/thing-paths.svg?1585427333)

@@ -14,2 +14,6 @@ [![npm version](https://img.shields.io/npm/v/@thi.ng/paths.svg)](https://www.npmjs.com/package/@thi.ng/paths)

- [Status](#status)
- [Breaking changes](#breaking-changes)
- [4.0.0](#400)
- [Naming convention](#naming-convention)
- [Type checked accessors](#type-checked-accessors)
- [Installation](#installation)

@@ -19,4 +23,7 @@ - [Dependencies](#dependencies)

- [API](#api)
- [Accessors](#accessors)
- [Type checked versions](#type-checked-versions)
- [Type checked paths](#type-checked-paths)
- [Optional property handling](#optional-property-handling)
- [Higher-order accessors](#higher-order-accessors)
- [First order operators](#first-order-operators)
- [Deletions](#deletions)
- [Structural sharing](#structural-sharing)

@@ -36,2 +43,25 @@ - [Mutable setter](#mutable-setter)

## Breaking changes
### 4.0.0
#### Naming convention
As part of a larger effort to enforce more consistent naming conventions
across various umbrella packages, all higher-order operators in this
package are now using the `def` prefix: e.g. `getterT()` =>
`defGetter()`, `setterT()` => `defSetter()`.
#### Type checked accessors
**Type checked accessors are now the default and those functions expect
paths provided as tuples**. To continue using string based paths (e.g.
`"a.b.c"`), alternative `Unsafe` versions are provided. E.g. `getIn()`
(type checked) vs. `getInUnsafe()` (unchecked). Higher-order versions
also provide fallbacks (e.g. `getter()` => `defGetterUnsafe()`).
Type checking for paths is currently "only" supported for the first 8
levels of nesting. Deeper paths are supported but only partially checked
and their value type inferred as `any`.
## Installation

@@ -43,3 +73,3 @@

Package sizes (gzipped): ESM: 1.0KB / CJS: 1.1KB / UMD: 1.1KB
Package sizes (gzipped): ESM: 1.09 KB / CJS: 1.19 KB / UMD: 1.14 KB

@@ -50,2 +80,3 @@ ## Dependencies

- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
- [tslib](https://github.com/thi-ng/umbrella/tree/develop/packages/undefined)

@@ -60,67 +91,107 @@ ## Usage examples

### hdom-elm <!-- NOTOC -->
| Screenshot | Description | Live demo | Source |
| ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| | Using hdom in an Elm-like manner | [Demo](https://demo.thi.ng/umbrella/hdom-elm/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-elm) |
| | Event handling w/ interceptors and side effects | [Demo](https://demo.thi.ng/umbrella/interceptor-basics2/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/interceptor-basics2) |
| | Basic SPA example with atom-based UI router | [Demo](https://demo.thi.ng/umbrella/login-form/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/login-form) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rstream-event-loop.png" width="240"/> | Minimal demo of using rstream constructs to form an interceptor-style event loop | [Demo](https://demo.thi.ng/umbrella/rstream-event-loop/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rstream-event-loop) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/todo-list.png" width="240"/> | Obligatory to-do list example with undo/redo | [Demo](https://demo.thi.ng/umbrella/todo-list/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/todo-list) |
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/triple-query.png" width="240"/> | Triple store query results & sortable table | [Demo](https://demo.thi.ng/umbrella/triple-query/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/triple-query) |
Using hdom in an Elm-like manner
## API
[Live demo](https://demo.thi.ng/umbrella/hdom-elm/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/hdom-elm)
[Generated API docs](https://docs.thi.ng/umbrella/paths/)
### interceptor-basics2 <!-- NOTOC -->
### Type checked paths
Event handling w/ interceptors and side effects
As stated in the [breaking changes](#breaking-changes) section, since
v4.0.0 paths are now type checked by default. These new functions use
Typescript generics to validate a given path against the type structure
of the target state object. Since string paths cannot be checked, only
path tuples are supported. **Type checking & inference supports path
lengths up to 8** (i.e. levels of hierarchy) before reverting back to
`any` for longer/deeper paths (there's no depth limit per se).
[Live demo](https://demo.thi.ng/umbrella/interceptor-basics2/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/interceptor-basics2)
Due to missing type information of the not-yet-known state value, using
the typed checked higher-order versions (e.g. `defGetter`, `defSetter`
etc.) is slightly more verbose compared to their immediate use,
first-order versions (e.g. `getIn()`, `setIn()` etc.), where everything
can be inferred directly. However, (re)using the HOF-constructed
accessors *can* be somewhat faster and more convenient... YMMV! More details below.
### rstream-event-loop <!-- NOTOC -->
#### Optional property handling
![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rstream-event-loop.png)
When accessing data structures with optional properties, not only the
leaf value type targeted by a lookup path is important, but any
intermediate optional properties need to be considered too. Furthermore,
we need to distinguish between read (get) and write (update) use cases
for correct type inference.
Minimal demo of using rstream constructs to form an interceptor-style event loop
For example, given these types:
[Live demo](https://demo.thi.ng/umbrella/rstream-event-loop/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rstream-event-loop)
```ts
type Foo1 = { a: { b: { c?: number; } } };
### todo-list <!-- NOTOC -->
type Foo2 = { a?: { b: { c: number; } } };
```
![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/todo-list.png)
For get/read purposes the inferred type for `c` will both be `number |
undefined`. Even though `c` in `Foo2` is not marked as optional, the `a`
property is optional and so attempting to lookup `c` can yield
`undefined`...
Obligatory to-do list example with undo/redo
For set/update/write purposes, the type for `c` is inferred verbatim.
I.e. if a property is marked as optional, a setter will allow
`undefined` as new value as well.
[Live demo](https://demo.thi.ng/umbrella/todo-list/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/todo-list)
### Higher-order accessors
### triple-query <!-- NOTOC -->
The `defGetter()`, `defSetter()` and `defUpdater()` functions compile a
lookup path tuple into an optimized function, operating directly at the
value the path points to in a nested object given later. For getters,
this essentially compiles to:
![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/triple-query.png)
```ts
defGetter(["a","b","c"]) => (obj) => obj.a.b.c;
```
Triple store query results & sortable table
...with the important difference that the function returns `undefined`
if any intermediate values along the lookup path are undefined (and
doesn't throw an error).
[Live demo](https://demo.thi.ng/umbrella/triple-query/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/triple-query)
For setters / updaters, the resulting function too accepts a single
object (or array) to operate on and when called, **immutably** replaces
the value at the given path, i.e. it produces a selective deep copy of
obj up until given path. If any intermediate key is not present in the
given object, it creates a plain empty object for that missing key and
descends further along the path.
## API
```ts
// define state structure (see above example)
interface State {
a: {
b?: number;
c: string[];
}
}
[Generated API docs](https://docs.thi.ng/umbrella/paths/)
const state: State = { a: { b: 1, c: ["c1", "c2"] } };
### Accessors
// build type checked getter for `b` & `c`
const getB = defGetter<State, "a", "b">(["a", "b"]);
const getFirstC = defGetter<State, "a", "c", 0>(["a", "c", 0]);
The `getter()`, `setter()` and `updater()` functions compile a lookup
path like `a.b.c` into an optimized function operating directly at the
value the path points to in nested object. For getters, this essentially
compiles to `val = obj.a.b.c`, with the important difference that the
function returns `undefined` if any intermediate values along the lookup
path are undefined (and doesn't throw an error).
const b = getB(state); // b inferred as `number | undefined`
const c1 = getFirstC(state); // c1 inferred as `string`
```
The resulting setter function too accepts a single object (or array) to
operate on and when called, **immutably** replaces the value at the
given path, i.e. it produces a selective deep copy of obj up until given
path. If any intermediate key is not present in the given object, it
creates a plain empty object for that missing key and descends further
along the path.
Paths can also be defined as dot-separated strings, however cannot be type checked and MUST use the `Unsafe` version of each operation:
```ts
s = setter("a.b.c");
// or
s = setter(["a","b","c"]);
s = defSetterUnsafe("a.b.c");
s({a: {b: {c: 23}}}, 24)
// {a: {b: {c: 24}}}
s({ a: { b: { c: 23 } } }, 24)
// { a: { b: { c: 24 } } }
s({x: 23}, 24)
s({ x: 23 }, 24)
// { x: 23, a: { b: { c: 24 } } }

@@ -137,5 +208,11 @@

```ts
inc = updater("a.b", (x) => x != null ? x + 1 : 1);
type State = { a?: { b?: number; } };
inc({a: {b: 10}});
const inc = defUpdater<State, "a", "b">(
["a","b"],
// x inferred as number | undefined
(x) => x !== undefined ? x + 1 : 1
);
inc({ a: { b: 10 } });
// { a: { b: 11 } }

@@ -146,3 +223,3 @@ inc({});

// with additional arguments
add = updater("a.b", (x, n) => x + n);
add = defUpdater("a.b", (x, n) => x + n);

@@ -153,83 +230,42 @@ add({a: {b: 10}}, 13);

### First order operators
In addition to these higher-order functions, the module also provides
immediate-use wrappers: `getIn()`, `setIn()`, `updateIn()` and
`deleteIn()`. These functions are using `getter` / `setter` internally,
so have same behaviors.
`deleteIn()`. These functions are using `defGetter` / `defSetter` internally, so come with the same contracts/disclaimers...
```ts
state = {a: {b: {c: 23}}};
const state = { a: { b: { c: 23 } } };
getIn(state, "a.b.c")
const cPath = <const>["a", "b", "c"];
getIn(state, cPath)
// 23
setIn(state, "a.b.c", 24)
// {a: {b: {c: 24}}}
setIn(state, cPath, 24)
// { a: { b: { c: 24 } } }
// apply given function to path value
updateIn(state, "a.b.c", x => x + 1)
// {a: {b: {c: 24}}}
// Note: New `c` is 24, since above `setIn()` didn't mutate orig
updateIn(state, cPath, (x) => x + 1)
// { a: { b: { c: 24 } } }
// immutably remove path key
deleteIn(state, "a.b.c.")
// {a: {b: {}}}
deleteIn(state, cPath)
// { a: { b: {} } }
```
### Type checked versions
### Deletions
Since v2.2.0 type checked versions of the above accessors are available:
Since `deleteIn` immutably removes a key from the given state object, it
also returns a new type from which the key has been explicitly removed.
Those return types come in the form of `Without{1-8}<...>` interfaces.
- `getterT` / `getInT`
- `setterT` / `setInT`
- `updaterT` / `updateInT`
- `deleteInT`
- `mutatorT` / `mutInT`
These functions use generics (via mapped types) to validate the given
path against the type structure of the state object. Since string paths
cannot be type checked, only path tuples are supported. **Type checking &
inference supports path lengths up to 8** (i.e. levels of
hierarchy) before reverting back to `any`.
```ts
const state = { a: { b: 1, c: ["c1", "c2"] } };
const b = getInT(state, ["a", "b"]); // b inferred as number
const c = getInT(state, ["a", "c"]); // c inferred as string[]
const c1len = getInT(state, ["a", "c", 0, "length"]); // inferred as number
getIn(state, ["a", "d"]); // compile error
getIn(state, ["x"]); // compile error
```
Using the typed checked HOF versions (e.g. `getterT`, `setterT` etc.) is
slightly more verbose due to missing type information of the not yet
know state and the way generics are done in TypeScript:
```ts
// define state structure (see above example)
interface State {
a: {
b: number;
c: string[];
}
}
// build typed getter for `b` & `c` state
const getB = getterT<State, "a", "b">(["a", "b"]);
const getFirstC = getterT<State, "a", "c", 0>(["a", "c", 0]);
// using `state` from previous example
const b = getB(state); // inferred as number
const c1 = getFirstC(state); // inferred as string
```
Since `deleteInT` immutably removes a key from the given state object, it also returns a new type from which the key has been explicitly removed.
```ts
// again using `state` from above example
// remove nested key `a.c`
const state2 = deleteInT(state, ["a","c"]);
const state2 = deleteIn(state, ["a","b","c"]);
// compile error: "Property `c` does not exist`
state2.a.c;
state2.a.b.c;
```

@@ -248,8 +284,8 @@

```ts
s = setter("a.b.c");
const s = defSetterUnsafe("a.b.c");
// original
a = { x: { y: { z: 1 } }, u: { v: 2 } };
const a = { x: { y: { z: 1 } }, u: { v: 2 } };
// updated version
b = s(a, 3);
const b = s(a, 3);
// { x: { y: { z: 1 } }, u: { v: 2 }, a: { b: { c: 3 } } }

@@ -265,21 +301,21 @@

`mutator()` is the mutable alternative to `setter()`. It returns a
function, which when called, mutates given object / array at given path
location and bails if any intermediate path values are non-indexable
(only the very last path element can be missing in the actual object
structure). If successful, returns original (mutated) object, else
`undefined`. This function too provides optimized versions for path
lengths <= 4.
`defMutator()`/`defMutatorUnsafe()` are the mutable alternatives to
`defSetter()`/`defSetterUnsafe()`. Each returns a function, which when
called, mutates given object / array at given path location and bails if
any intermediate path values are non-indexable (only the very last path
element can be missing in the actual target object structure). If
successful, returns original (mutated) object, else `undefined`. This
function too provides optimized versions for path lengths <= 4.
As with `setIn`, `mutIn` is the immediate use mutator, i.e. the same as:
`mutator(path)(state, val)`.
`defMutator(path)(state, val)`.
```ts
mutIn({ a: { b: [10, 20] } }, "a.b.1", 23);
mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23);
// or
mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23);
mutInUnsafe({ a: { b: [10, 20] } }, "a.b.1", 23);
// { a: { b: [ 10, 23 ] } }
// fails (because of missing path structure in target object)
mutIn({}, "a.b.c", 23);
// no-op (because of missing path structure in target object)
mutInUnsafe({}, "a.b.c", 23);
// undefined

@@ -290,6 +326,6 @@ ```

The `exists()` function takes an arbitrary object and lookup path.
Descends into object along path and returns true if the full path exists
(even if final leaf value is `null` or `undefined`). Checks are
performed using `hasOwnProperty()`.
The `exists()` function takes an arbitrary object and lookup path
(string or tuple). Descends into object along path and returns true if
the full path exists (even if final leaf value is `null` or
`undefined`). Checks are performed using `hasOwnProperty()`.

@@ -296,0 +332,0 @@ ```ts

@@ -18,2 +18,25 @@ # ${pkg.banner}

## Breaking changes
### 4.0.0
#### Naming convention
As part of a larger effort to enforce more consistent naming conventions
across various umbrella packages, all higher-order operators in this
package are now using the `def` prefix: e.g. `getterT()` =>
`defGetter()`, `setterT()` => `defSetter()`.
#### Type checked accessors
**Type checked accessors are now the default and those functions expect
paths provided as tuples**. To continue using string based paths (e.g.
`"a.b.c"`), alternative `Unsafe` versions are provided. E.g. `getIn()`
(type checked) vs. `getInUnsafe()` (unchecked). Higher-order versions
also provide fallbacks (e.g. `getter()` => `defGetterUnsafe()`).
Type checking for paths is currently "only" supported for the first 8
levels of nesting. Deeper paths are supported but only partially checked
and their value type inferred as `any`.
${supportPackages}

@@ -43,27 +66,94 @@

### Accessors
### Type checked paths
The `getter()`, `setter()` and `updater()` functions compile a lookup
path like `a.b.c` into an optimized function operating directly at the
value the path points to in nested object. For getters, this essentially
compiles to `val = obj.a.b.c`, with the important difference that the
function returns `undefined` if any intermediate values along the lookup
path are undefined (and doesn't throw an error).
As stated in the [breaking changes](#breaking-changes) section, since
v4.0.0 paths are now type checked by default. These new functions use
Typescript generics to validate a given path against the type structure
of the target state object. Since string paths cannot be checked, only
path tuples are supported. **Type checking & inference supports path
lengths up to 8** (i.e. levels of hierarchy) before reverting back to
`any` for longer/deeper paths (there's no depth limit per se).
The resulting setter function too accepts a single object (or array) to
operate on and when called, **immutably** replaces the value at the
given path, i.e. it produces a selective deep copy of obj up until given
path. If any intermediate key is not present in the given object, it
creates a plain empty object for that missing key and descends further
along the path.
Due to missing type information of the not-yet-known state value, using
the typed checked higher-order versions (e.g. `defGetter`, `defSetter`
etc.) is slightly more verbose compared to their immediate use,
first-order versions (e.g. `getIn()`, `setIn()` etc.), where everything
can be inferred directly. However, (re)using the HOF-constructed
accessors *can* be somewhat faster and more convenient... YMMV! More details below.
#### Optional property handling
When accessing data structures with optional properties, not only the
leaf value type targeted by a lookup path is important, but any
intermediate optional properties need to be considered too. Furthermore,
we need to distinguish between read (get) and write (update) use cases
for correct type inference.
For example, given these types:
```ts
s = setter("a.b.c");
// or
s = setter(["a","b","c"]);
type Foo1 = { a: { b: { c?: number; } } };
s({a: {b: {c: 23}}}, 24)
// {a: {b: {c: 24}}}
type Foo2 = { a?: { b: { c: number; } } };
```
s({x: 23}, 24)
For get/read purposes the inferred type for `c` will both be `number |
undefined`. Even though `c` in `Foo2` is not marked as optional, the `a`
property is optional and so attempting to lookup `c` can yield
`undefined`...
For set/update/write purposes, the type for `c` is inferred verbatim.
I.e. if a property is marked as optional, a setter will allow
`undefined` as new value as well.
### Higher-order accessors
The `defGetter()`, `defSetter()` and `defUpdater()` functions compile a
lookup path tuple into an optimized function, operating directly at the
value the path points to in a nested object given later. For getters,
this essentially compiles to:
```ts
defGetter(["a","b","c"]) => (obj) => obj.a.b.c;
```
...with the important difference that the function returns `undefined`
if any intermediate values along the lookup path are undefined (and
doesn't throw an error).
For setters / updaters, the resulting function too accepts a single
object (or array) to operate on and when called, **immutably** replaces
the value at the given path, i.e. it produces a selective deep copy of
obj up until given path. If any intermediate key is not present in the
given object, it creates a plain empty object for that missing key and
descends further along the path.
```ts
// define state structure (see above example)
interface State {
a: {
b?: number;
c: string[];
}
}
const state: State = { a: { b: 1, c: ["c1", "c2"] } };
// build type checked getter for `b` & `c`
const getB = defGetter<State, "a", "b">(["a", "b"]);
const getFirstC = defGetter<State, "a", "c", 0>(["a", "c", 0]);
const b = getB(state); // b inferred as `number | undefined`
const c1 = getFirstC(state); // c1 inferred as `string`
```
Paths can also be defined as dot-separated strings, however cannot be type checked and MUST use the `Unsafe` version of each operation:
```ts
s = defSetterUnsafe("a.b.c");
s({ a: { b: { c: 23 } } }, 24)
// { a: { b: { c: 24 } } }
s({ x: 23 }, 24)
// { x: 23, a: { b: { c: 24 } } }

@@ -80,5 +170,11 @@

```ts
inc = updater("a.b", (x) => x != null ? x + 1 : 1);
type State = { a?: { b?: number; } };
inc({a: {b: 10}});
const inc = defUpdater<State, "a", "b">(
["a","b"],
// x inferred as number | undefined
(x) => x !== undefined ? x + 1 : 1
);
inc({ a: { b: 10 } });
// { a: { b: 11 } }

@@ -89,3 +185,3 @@ inc({});

// with additional arguments
add = updater("a.b", (x, n) => x + n);
add = defUpdater("a.b", (x, n) => x + n);

@@ -96,83 +192,42 @@ add({a: {b: 10}}, 13);

### First order operators
In addition to these higher-order functions, the module also provides
immediate-use wrappers: `getIn()`, `setIn()`, `updateIn()` and
`deleteIn()`. These functions are using `getter` / `setter` internally,
so have same behaviors.
`deleteIn()`. These functions are using `defGetter` / `defSetter` internally, so come with the same contracts/disclaimers...
```ts
state = {a: {b: {c: 23}}};
const state = { a: { b: { c: 23 } } };
getIn(state, "a.b.c")
const cPath = <const>["a", "b", "c"];
getIn(state, cPath)
// 23
setIn(state, "a.b.c", 24)
// {a: {b: {c: 24}}}
setIn(state, cPath, 24)
// { a: { b: { c: 24 } } }
// apply given function to path value
updateIn(state, "a.b.c", x => x + 1)
// {a: {b: {c: 24}}}
// Note: New `c` is 24, since above `setIn()` didn't mutate orig
updateIn(state, cPath, (x) => x + 1)
// { a: { b: { c: 24 } } }
// immutably remove path key
deleteIn(state, "a.b.c.")
// {a: {b: {}}}
deleteIn(state, cPath)
// { a: { b: {} } }
```
### Type checked versions
### Deletions
Since v2.2.0 type checked versions of the above accessors are available:
Since `deleteIn` immutably removes a key from the given state object, it
also returns a new type from which the key has been explicitly removed.
Those return types come in the form of `Without{1-8}<...>` interfaces.
- `getterT` / `getInT`
- `setterT` / `setInT`
- `updaterT` / `updateInT`
- `deleteInT`
- `mutatorT` / `mutInT`
These functions use generics (via mapped types) to validate the given
path against the type structure of the state object. Since string paths
cannot be type checked, only path tuples are supported. **Type checking &
inference supports path lengths up to 8** (i.e. levels of
hierarchy) before reverting back to `any`.
```ts
const state = { a: { b: 1, c: ["c1", "c2"] } };
const b = getInT(state, ["a", "b"]); // b inferred as number
const c = getInT(state, ["a", "c"]); // c inferred as string[]
const c1len = getInT(state, ["a", "c", 0, "length"]); // inferred as number
getIn(state, ["a", "d"]); // compile error
getIn(state, ["x"]); // compile error
```
Using the typed checked HOF versions (e.g. `getterT`, `setterT` etc.) is
slightly more verbose due to missing type information of the not yet
know state and the way generics are done in TypeScript:
```ts
// define state structure (see above example)
interface State {
a: {
b: number;
c: string[];
}
}
// build typed getter for `b` & `c` state
const getB = getterT<State, "a", "b">(["a", "b"]);
const getFirstC = getterT<State, "a", "c", 0>(["a", "c", 0]);
// using `state` from previous example
const b = getB(state); // inferred as number
const c1 = getFirstC(state); // inferred as string
```
Since `deleteInT` immutably removes a key from the given state object, it also returns a new type from which the key has been explicitly removed.
```ts
// again using `state` from above example
// remove nested key `a.c`
const state2 = deleteInT(state, ["a","c"]);
const state2 = deleteIn(state, ["a","b","c"]);
// compile error: "Property `c` does not exist`
state2.a.c;
state2.a.b.c;
```

@@ -191,8 +246,8 @@

```ts
s = setter("a.b.c");
const s = defSetterUnsafe("a.b.c");
// original
a = { x: { y: { z: 1 } }, u: { v: 2 } };
const a = { x: { y: { z: 1 } }, u: { v: 2 } };
// updated version
b = s(a, 3);
const b = s(a, 3);
// { x: { y: { z: 1 } }, u: { v: 2 }, a: { b: { c: 3 } } }

@@ -208,21 +263,21 @@

`mutator()` is the mutable alternative to `setter()`. It returns a
function, which when called, mutates given object / array at given path
location and bails if any intermediate path values are non-indexable
(only the very last path element can be missing in the actual object
structure). If successful, returns original (mutated) object, else
`undefined`. This function too provides optimized versions for path
lengths <= 4.
`defMutator()`/`defMutatorUnsafe()` are the mutable alternatives to
`defSetter()`/`defSetterUnsafe()`. Each returns a function, which when
called, mutates given object / array at given path location and bails if
any intermediate path values are non-indexable (only the very last path
element can be missing in the actual target object structure). If
successful, returns original (mutated) object, else `undefined`. This
function too provides optimized versions for path lengths <= 4.
As with `setIn`, `mutIn` is the immediate use mutator, i.e. the same as:
`mutator(path)(state, val)`.
`defMutator(path)(state, val)`.
```ts
mutIn({ a: { b: [10, 20] } }, "a.b.1", 23);
mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23);
// or
mutIn({ a: { b: [10, 20] } }, ["a", "b", 1], 23);
mutInUnsafe({ a: { b: [10, 20] } }, "a.b.1", 23);
// { a: { b: [ 10, 23 ] } }
// fails (because of missing path structure in target object)
mutIn({}, "a.b.c", 23);
// no-op (because of missing path structure in target object)
mutInUnsafe({}, "a.b.c", 23);
// undefined

@@ -233,6 +288,6 @@ ```

The `exists()` function takes an arbitrary object and lookup path.
Descends into object along path and returns true if the full path exists
(even if final leaf value is `null` or `undefined`). Checks are
performed using `hasOwnProperty()`.
The `exists()` function takes an arbitrary object and lookup path
(string or tuple). Descends into object along path and returns true if
the full path exists (even if final leaf value is `null` or
`undefined`). Checks are performed using `hasOwnProperty()`.

@@ -239,0 +294,0 @@ ```ts

@@ -0,14 +1,24 @@

import type { Path } from "@thi.ng/api";
/**
* Similar to {@link setIn}, but takes any number of path-value pairs as
* args and applies them in sequence by calling `setIn()` for each.
* Similar to {@link setInUnsafe}, but takes any number of path-value
* pairs as args and applies them in sequence by calling `setIn()` for
* each.
*
* @remarks
* Any key paths missing in the data structure will be created. Does
* *not* mutate original (instead use {@link mutInMany} for this
* purpose).
* Any intermediate key paths missing in the data structure will be
* created. Does NOT mutate original (instead use
* {@link mutInManyUnsafe} for this purpose).
*
* Unlike {@link setIn}, this function does not use type checked paths.
* The type parameter `T` can be used to indicate the type of the
* overall state value and will also be used as return type.
*
* ```
* setInMany({}, "a.b", 10, "x.y.z", 20)
* @example
* ```ts
* setInManyUnsafe(
* {},
* // pair #1
* "a.b", 10,
* // pair #2
* "x.y.z", 20
* );
* // { a: { b: 10 }, x: { y: { z: 20 } } }

@@ -20,3 +30,7 @@ * ```

*/
export declare const setInMany: (state: any, ...pairs: any[]) => any;
export declare function setInManyUnsafe<T>(state: T, p1: Path, v1: any): T;
export declare function setInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any): T;
export declare function setInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any): T;
export declare function setInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any, p4: Path, v4: any): T;
export declare function setInManyUnsafe<T>(state: T, p1: Path, v1: any, p2: Path, v2: any, p3: Path, v3: any, p4: Path, v4: any, ...xs: any[]): T;
//# sourceMappingURL=set-in-many.d.ts.map
import { illegalArgs } from "@thi.ng/errors";
import { setInT } from "./set-in";
/**
* Similar to {@link setIn}, but takes any number of path-value pairs as
* args and applies them in sequence by calling `setIn()` for each.
*
* @remarks
* Any key paths missing in the data structure will be created. Does
* *not* mutate original (instead use {@link mutInMany} for this
* purpose).
*
* Unlike {@link setIn}, this function does not use type checked paths.
*
* ```
* setInMany({}, "a.b", 10, "x.y.z", 20)
* // { a: { b: 10 }, x: { y: { z: 20 } } }
* ```
*
* @param state -
* @param pairs -
*/
export const setInMany = (state, ...pairs) => {
import { setIn } from "./set-in";
export function setInManyUnsafe(state, ...pairs) {
const n = pairs.length;

@@ -27,5 +8,5 @@ n & 1 &&

for (let i = 0; i < n; i += 2) {
state = setInT(state, pairs[i], pairs[i + 1]);
state = setIn(state, pairs[i], pairs[i + 1]);
}
return state;
};
}

@@ -1,13 +0,12 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, PathVal } from "@thi.ng/api";
/**
* Immediate use setter, i.e. same as: `setter(path)(state, val)`.
* Unchecked version of {@link setIn}.
*
* @remarks
* Supports type checked paths and values for path lengths <= 8. String
* paths are always unchecked (i.e. `state` is `any`).
* The type parameter `T` can be used to indicate the type of the nested
* value to be set (default: `any`).
*
* @example
* ```ts
*
* setIn({}, "a.b.c", 23);
* setInUnsafe({}, "a.b.c", 23);
* // { a: { b: { c: 23} } }

@@ -19,6 +18,20 @@ * ```

*/
export declare const setIn: (state: any, path: Path, val: any) => any;
export declare const setInUnsafe: <T>(state: any, path: Path, val: T) => any;
/**
* Type checked version of {@link setIn}.
* Type checked, immediate use setter, i.e. same as:
* `defSetterUnsafe(path)(state, val)`.
*
* @remarks
* Only the first 8 path levels are type checked.
*
* @example
* ```ts
* // type checked path & value
* setIn({ a: { b: { c: 23 } } }, ["a", "b", "c"], 24);
* // { a: { b: { c: 24 } } }
*
* // error (wrong value type)
* setIn({ a: { b: { c: 23 } } }, ["a", "b", "c"], "24");
* ```
*
* @param state -

@@ -28,12 +41,12 @@ * @param path -

*/
export declare function setInT<T>(state: T, path: [], val: T): T;
export declare function setInT<T, A extends Keys<T>>(state: T, path: [A], val: Val1<T, A>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: [A, B], val: Val2<T, A, B>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: [A, B, C], val: Val3<T, A, B, C>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: [A, B, C, D], val: Val4<T, A, B, C, D>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: [A, B, C, D, E], val: Val5<T, A, B, C, D, E>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: [A, B, C, D, E, F], val: Val6<T, A, B, C, D, E, F>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(state: T, path: [A, B, C, D, E, F, G], val: Val7<T, A, B, C, D, E, F, G>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H], val: Val8<T, A, B, C, D, E, F, G, H>): T;
export declare function setInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H, ...PropertyKey[]], val: any): any;
export declare function setIn<T>(state: T, path: Path0, val: T): T;
export declare function setIn<T, A>(state: T, path: Path1<T, A>, val: PathVal<T, [A]>): T;
export declare function setIn<T, A, B>(state: T, path: Path2<T, A, B>, val: PathVal<T, [A, B]>): T;
export declare function setIn<T, A, B, C>(state: T, path: Path3<T, A, B, C>, val: PathVal<T, [A, B, C]>): T;
export declare function setIn<T, A, B, C, D>(state: T, path: Path4<T, A, B, C, D>, val: PathVal<T, [A, B, C, D]>): T;
export declare function setIn<T, A, B, C, D, E>(state: T, path: Path5<T, A, B, C, D, E>, val: PathVal<T, [A, B, C, D, E]>): T;
export declare function setIn<T, A, B, C, D, E, F>(state: T, path: Path6<T, A, B, C, D, E, F>, val: PathVal<T, [A, B, C, D, E, F]>): T;
export declare function setIn<T, A, B, C, D, E, F, G>(state: T, path: Path7<T, A, B, C, D, E, F, G>, val: PathVal<T, [A, B, C, D, E, F, G]>): T;
export declare function setIn<T, A, B, C, D, E, F, G, H>(state: T, path: Path8<T, A, B, C, D, E, F, G, H>, val: PathVal<T, [A, B, C, D, E, F, G, H]>): T;
export declare function setIn<T, A, B, C, D, E, F, G, H>(state: T, path: DeepPath<T, A, B, C, D, E, F, G, H>, val: any): any;
//# sourceMappingURL=set-in.d.ts.map

@@ -1,13 +0,12 @@

import { setterT } from "./setter";
import { defSetter } from "./setter";
/**
* Immediate use setter, i.e. same as: `setter(path)(state, val)`.
* Unchecked version of {@link setIn}.
*
* @remarks
* Supports type checked paths and values for path lengths <= 8. String
* paths are always unchecked (i.e. `state` is `any`).
* The type parameter `T` can be used to indicate the type of the nested
* value to be set (default: `any`).
*
* @example
* ```ts
*
* setIn({}, "a.b.c", 23);
* setInUnsafe({}, "a.b.c", 23);
* // { a: { b: { c: 23} } }

@@ -19,5 +18,5 @@ * ```

*/
export const setIn = (state, path, val) => setterT(path)(state, val);
export function setInT(state, path, val) {
return setterT(path)(state, val);
export const setInUnsafe = (state, path, val) => defSetter(path)(state, val);
export function setIn(state, path, val) {
return defSetter(path)(state, val);
}

@@ -1,2 +0,2 @@

import type { Fn2, Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Fn2, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, PathVal } from "@thi.ng/api";
/**

@@ -12,2 +12,5 @@ * Composes a setter function for given nested update path. Optimized

*
* The type parameter `T` can be used to indicate the type of the nested
* value to be updated (default: `any`).
*
* If `path` is given as string, it will be split using `.`. Returns

@@ -28,9 +31,7 @@ * function which accepts single object and when called, **immutably**

*
* Also see: {@link setIn}, {@link updateIn}, {@link deleteIn}
*
* @example
* ```
* s = setter("a.b.c");
* ```ts
* s = defSetterUnsafe("a.b.c");
* // or
* s = setter(["a","b","c"]);
* s = defSetterUnsafe(["a", "b", "c"]);
*

@@ -49,5 +50,5 @@ * s({ a: { b: { c: 23} } }, 24)

* ```ts
* s = setter("a.b.c");
* s = defSetterUnsafe("a.b.c");
*
* a = {x: {y: {z: 1}}};
* a = { x: { y: { z: 1 } } };
* b = s(a, 2);

@@ -62,18 +63,49 @@ * // { x: { y: { z: 1 } }, a: { b: { c: 2 } } }

*/
export declare const setter: (path: Path) => Fn2<any, any, any>;
export declare const defSetterUnsafe: <T = any>(path: Path) => Fn2<any, T, any>;
/**
* Type checked version of {@link setter}.
* Type checked version of {@link defSetterUnsafe}. Only the first 8
* path levels are type checked.
*
* @remarks
* Due to the higher-order nature of this function, generics for path
* validation must be given and so this function is more verbose than
* {@link setIn} (where the generics can usually be fully inferred).
*
* @example
* ```ts
* type State = { a: { b: number } };
*
* const setB = defSetter<State, "a", "b">(["a", "b"]);
*
* setB({ a: { b: 1 } }, 2); // ok!
* setB({ a: { b: 1 } }, "2"); // error!
* ```
*
* @example
* ```ts
* type State = { a: { b: number } };
*
* const path = <const>["a","b"];
*
* const setB = defSetter<State, typeof path[0], typeof path[1]>(path);
* ```
*
* @param path -
*/
export declare function setterT<T>(path: []): Fn2<T, T, T>;
export declare function setterT<T, A extends Keys<T>>(path: [A]): Fn2<T, Val1<T, A>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>>(path: [A, B]): Fn2<T, Val2<T, A, B>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(path: [A, B, C]): Fn2<T, Val3<T, A, B, C>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(path: [A, B, C, D]): Fn2<T, Val4<T, A, B, C, D>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(path: [A, B, C, D, E]): Fn2<T, Val5<T, A, B, C, D, E>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(path: [A, B, C, D, E, F]): Fn2<T, Val6<T, A, B, C, D, E, F>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(path: [A, B, C, D, E, F, G]): Fn2<T, Val7<T, A, B, C, D, E, F, G>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H]): Fn2<T, Val8<T, A, B, C, D, E, F, G, H>, T>;
export declare function setterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H, ...PropertyKey[]]): Fn2<T, any, any>;
export declare function defSetter<T>(path: Path0): Fn2<T, T, T>;
export declare function defSetter<T, A>(path: Path1<T, A>): Fn2<T, PathVal<T, [A]>, T>;
export declare function defSetter<T, A, B>(path: Path2<T, A, B>): Fn2<T, PathVal<T, [A, B]>, T>;
export declare function defSetter<T, A, B, C>(path: Path3<T, A, B, C>): Fn2<T, PathVal<T, [A, B, C]>, T>;
export declare function defSetter<T, A, B, C, D>(path: Path4<T, A, B, C, D>): Fn2<T, PathVal<T, [A, B, C, D]>, T>;
export declare function defSetter<T, A, B, C, D, E>(path: Path5<T, A, B, C, D, E>): Fn2<T, PathVal<T, [A, B, C, D, E]>, T>;
export declare function defSetter<T, A, B, C, D, E, F>(path: Path6<T, A, B, C, D, E, F>): Fn2<T, PathVal<T, [A, B, C, D, E, F]>, T>;
export declare function defSetter<T, A, B, C, D, E, F, G>(path: Path7<T, A, B, C, D, E, F, G>): Fn2<T, PathVal<T, [A, B, C, D, E, F, G]>, T>;
export declare function defSetter<T, A, B, C, D, E, F, G, H>(path: Path8<T, A, B, C, D, E, F, G, H>): Fn2<T, PathVal<T, [A, B, C, D, E, F, G, H]>, T>;
export declare function defSetter<T, A, B, C, D, E, F, G, H>(path: DeepPath<T, A, B, C, D, E, F, G, H>): Fn2<T, any, any>;
/**
* Creates a shallow copy of given array, typed array or plain object.
*
* @param x
*/
export declare const copy: (x: any) => any;
//# sourceMappingURL=setter.d.ts.map

@@ -1,2 +0,2 @@

import { isArray } from "@thi.ng/checks";
import { isArray, isTypedArray } from "@thi.ng/checks";
import { toPath } from "./path";

@@ -13,2 +13,5 @@ /**

*
* The type parameter `T` can be used to indicate the type of the nested
* value to be updated (default: `any`).
*
* If `path` is given as string, it will be split using `.`. Returns

@@ -29,9 +32,7 @@ * function which accepts single object and when called, **immutably**

*
* Also see: {@link setIn}, {@link updateIn}, {@link deleteIn}
*
* @example
* ```
* s = setter("a.b.c");
* ```ts
* s = defSetterUnsafe("a.b.c");
* // or
* s = setter(["a","b","c"]);
* s = defSetterUnsafe(["a", "b", "c"]);
*

@@ -50,5 +51,5 @@ * s({ a: { b: { c: 23} } }, 24)

* ```ts
* s = setter("a.b.c");
* s = defSetterUnsafe("a.b.c");
*
* a = {x: {y: {z: 1}}};
* a = { x: { y: { z: 1 } } };
* b = s(a, 2);

@@ -63,6 +64,6 @@ * // { x: { y: { z: 1 } }, a: { b: { c: 2 } } }

*/
export const setter = (path) => setterT(path);
export function setterT(path) {
export const defSetterUnsafe = (path) => defSetter(path);
export function defSetter(path) {
const ks = toPath(path);
let [a, b, c, d] = ks;
const [a, b, c, d] = ks;
switch (ks.length) {

@@ -72,8 +73,8 @@ case 0:

case 1:
return (s, v) => ((s = _copy(s)), (s[a] = v), s);
return (s, v) => ((s = copy(s)), (s[a] = v), s);
case 2:
return (s, v) => {
let x;
s = _copy(s);
s[a] = x = _copy(s[a]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = v;

@@ -85,5 +86,5 @@ return s;

let x, y;
s = _copy(s);
s[a] = x = _copy(s[a]);
x[b] = y = _copy(x[b]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = y = copy(x[b]);
y[c] = v;

@@ -95,6 +96,6 @@ return s;

let x, y, z;
s = _copy(s);
s[a] = x = _copy(s[a]);
x[b] = y = _copy(x[b]);
y[c] = z = _copy(y[c]);
s = copy(s);
s[a] = x = copy(s[a]);
x[b] = y = copy(x[b]);
y[c] = z = copy(y[c]);
z[d] = v;

@@ -111,3 +112,16 @@ return s;

}
const _copy = (s) => (isArray(s) ? s.slice() : Object.assign({}, s));
const compS = (k, f) => (s, v) => ((s = _copy(s)), (s[k] = f ? f(s[k], v) : v), s);
/**
* Creates a shallow copy of given array, typed array or plain object.
*
* @param x
*/
export const copy = (x) => isArray(x) || isTypedArray(x) ? x.slice() : Object.assign({}, x);
/**
* Helper for {@link defSetter}. Returns setter for a single step.
*
* @param k -
* @param f -
*
* @internal
*/
const compS = (k, f) => (s, v) => ((s = copy(s)), (s[k] = f ? f(s[k], v) : v), s);

@@ -1,13 +0,26 @@

import type { Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, OptPathVal, PathVal } from "@thi.ng/api";
import type { UpdateFn } from "./api";
/**
* Similar to {@link setIn}, but applies given function to current path
* value (incl. any additional/optional arguments passed to `updateIn`)
* and uses result as new value. Does not modify original state (unless
* given function does so itself).
* Similar to {@link setInUnsafe}, but applies given function to current
* path value (incl. any additional/optional arguments passed to
* `updateIn`) and uses result as new value. Does not modify original
* state.
*
* ```
* add = (x, y) => x + y;
* updateIn({ a: { b: { c: 23 } } }, "a.b.c", add, 10);
* @remarks
* Unchecked version of {@link updateIn}. The type parameter `T` can be
* used to indicate the type of the nested value to be updated (default:
* `any`).
*
* @example
* ```ts
* add = (x: number, y: number) => x + y;
* updateInUnsafe({ a: { b: { c: 23 } } }, "a.b.c", add, 10);
* // { a: { b: { c: 33 } } }
*
* // type checked
* updateIn({ a: { b: { c: 23 } } }, ["a","b","c"], add, 10);
* // { a: { b: { c: 33 } } }
*
* // type error (value at "a.b" is not a number)
* updateIn({ a: { b: { c: 23 } } }, ["a","b"], add, 10);
* ```

@@ -20,5 +33,6 @@ *

*/
export declare const updateIn: (state: any, path: Path, fn: UpdateFn<any>, ...args: any[]) => any;
export declare const updateInUnsafe: <T = any>(state: any, path: Path, fn: import("@thi.ng/api").FnO<T, T>, ...args: any[]) => any;
/**
* Type checked version of {@link updateIn}.
* Type checked version of {@link updateIn}. Only the first 8 path
* levels are type checked.
*

@@ -29,12 +43,12 @@ * @param state -

*/
export declare function updateInT<T>(state: T, path: [], fn: UpdateFn<T>): T;
export declare function updateInT<T, A extends Keys<T>>(state: T, path: [A], fn: UpdateFn<Val1<T, A>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>>(state: T, path: [A, B], fn: UpdateFn<Val2<T, A, B>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(state: T, path: [A, B, C], fn: UpdateFn<Val3<T, A, B, C>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(state: T, path: [A, B, C, D], fn: UpdateFn<Val4<T, A, B, C, D>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(state: T, path: [A, B, C, D, E], fn: UpdateFn<Val5<T, A, B, C, D, E>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(state: T, path: [A, B, C, D, E, F], fn: UpdateFn<Val6<T, A, B, C, D, E, F>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(state: T, path: [A, B, C, D, E, F, G], fn: UpdateFn<Val7<T, A, B, C, D, E, F, G>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H], fn: UpdateFn<Val8<T, A, B, C, D, E, F, G, H>>, ...args: any[]): T;
export declare function updateInT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(state: T, path: [A, B, C, D, E, F, G, H, ...PropertyKey[]], fn: UpdateFn<any>, ...args: any[]): T;
export declare function updateIn<T>(state: T, path: Path0, fn: UpdateFn<T, T>): T;
export declare function updateIn<T, A>(state: T, path: Path1<T, A>, fn: UpdateFn<OptPathVal<T, [A]>, PathVal<T, [A]>>, ...args: any[]): T;
export declare function updateIn<T, A, B>(state: T, path: Path2<T, A, B>, fn: UpdateFn<OptPathVal<T, [A, B]>, PathVal<T, [A, B]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C>(state: T, path: Path3<T, A, B, C>, fn: UpdateFn<OptPathVal<T, [A, B, C]>, PathVal<T, [A, B, C]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D>(state: T, path: Path4<T, A, B, C, D>, fn: UpdateFn<OptPathVal<T, [A, B, C, D]>, PathVal<T, [A, B, C, D]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D, E>(state: T, path: Path5<T, A, B, C, D, E>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E]>, PathVal<T, [A, B, C, D, E]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D, E, F>(state: T, path: Path6<T, A, B, C, D, E, F>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F]>, PathVal<T, [A, B, C, D, E, F]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D, E, F, G>(state: T, path: Path7<T, A, B, C, D, E, F, G>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F, G]>, PathVal<T, [A, B, C, D, E, F, G]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D, E, F, G, H>(state: T, path: Path8<T, A, B, C, D, E, F, G, H>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F, G, H]>, PathVal<T, [A, B, C, D, E, F, G, H]>>, ...args: any[]): T;
export declare function updateIn<T, A, B, C, D, E, F, G, H>(state: T, path: DeepPath<T, A, B, C, D, E, F, G, H>, fn: UpdateFn<any, any>, ...args: any[]): T;
//# sourceMappingURL=update-in.d.ts.map

@@ -1,13 +0,26 @@

import { getterT } from "./getter";
import { setterT } from "./setter";
import { defGetter } from "./getter";
import { defSetter } from "./setter";
/**
* Similar to {@link setIn}, but applies given function to current path
* value (incl. any additional/optional arguments passed to `updateIn`)
* and uses result as new value. Does not modify original state (unless
* given function does so itself).
* Similar to {@link setInUnsafe}, but applies given function to current
* path value (incl. any additional/optional arguments passed to
* `updateIn`) and uses result as new value. Does not modify original
* state.
*
* ```
* add = (x, y) => x + y;
* updateIn({ a: { b: { c: 23 } } }, "a.b.c", add, 10);
* @remarks
* Unchecked version of {@link updateIn}. The type parameter `T` can be
* used to indicate the type of the nested value to be updated (default:
* `any`).
*
* @example
* ```ts
* add = (x: number, y: number) => x + y;
* updateInUnsafe({ a: { b: { c: 23 } } }, "a.b.c", add, 10);
* // { a: { b: { c: 33 } } }
*
* // type checked
* updateIn({ a: { b: { c: 23 } } }, ["a","b","c"], add, 10);
* // { a: { b: { c: 33 } } }
*
* // type error (value at "a.b" is not a number)
* updateIn({ a: { b: { c: 23 } } }, ["a","b"], add, 10);
* ```

@@ -20,5 +33,9 @@ *

*/
export const updateIn = (state, path, fn, ...args) => updateInT(state, path, fn, ...args);
export function updateInT(state, path, fn, ...args) {
return setterT(path)(state, fn.apply(null, (args.unshift(getterT(path)(state)), args)));
export const updateInUnsafe = (state, path, fn, ...args) =>
// @ts-ignore
updateIn(state, path, fn, ...args);
export function updateIn(state, path, fn, ...args) {
return defSetter(path)(state,
// @ts-ignore
fn.apply(null, (args.unshift(defGetter(path)(state)), args)));
}

@@ -1,17 +0,23 @@

import type { FnO, Keys, Keys1, Keys2, Keys3, Keys4, Keys5, Keys6, Keys7, Path, Val1, Val2, Val3, Val4, Val5, Val6, Val7, Val8 } from "@thi.ng/api";
import type { DeepPath, FnO, Path, Path0, Path1, Path2, Path3, Path4, Path5, Path6, Path7, Path8, OptPathVal, PathVal } from "@thi.ng/api";
import type { UpdateFn } from "./api";
/**
* Similar to {@link setter}, returns a function to update values at
* given `path` using provided update `fn`.
* Similar to {@link defSetterUnsafe}, returns a function to update
* values at given `path` using provided update `fn`. Paths and the
* arguments given to the returned function are NOT type checked.
*
* @remarks
* The returned function accepts a single object / array and applies
* `fn` to current path value (incl. any additional/optional arguments
* passed) and uses result as new value. Does not modify original state
* (unless given function does so itself).
* `fn` to given path value (incl. any additional / optional arguments
* passed) and uses result as new value. Does not modify original state.
*
* ```
* add = updater("a.b", (x, n) => x + n);
* The type parameter `T` can be used to indicate the type of the nested
* value to be updated (default: `any`).
*
* add({a: {b: 10}}, 13);
* @example
* ```ts
* const incB = defUpdaterUnsafe("a.b", (x, n) => x + n);
* // or
* const incB = defUpdaterUnsafe(["a", "b"], (x, n) => x + n);
*
* incB({ a: { b: 10 } }, 13);
* // { a: { b: 23 } }

@@ -23,5 +29,6 @@ * ```

*/
export declare const updater: (path: Path, fn: UpdateFn<any>) => FnO<any, any>;
export declare const defUpdaterUnsafe: <T = any>(path: Path, fn: FnO<T, T>) => FnO<T, any>;
/**
* Type checked version of {@link updater}.
* Type checked version of {@link defUpdaterUnsafe}. Only the first 8
* path levels are type checked.
*

@@ -31,12 +38,12 @@ * @param path -

*/
export declare function updaterT<T>(path: [], fn: UpdateFn<T>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>>(path: [A], fn: UpdateFn<Val1<T, A>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>>(path: [A, B], fn: UpdateFn<Val2<T, A, B>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>>(path: [A, B, C], fn: UpdateFn<Val3<T, A, B, C>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>>(path: [A, B, C, D], fn: UpdateFn<Val4<T, A, B, C, D>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>>(path: [A, B, C, D, E], fn: UpdateFn<Val5<T, A, B, C, D, E>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>>(path: [A, B, C, D, E, F], fn: UpdateFn<Val6<T, A, B, C, D, E, F>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>>(path: [A, B, C, D, E, F, G], fn: UpdateFn<Val7<T, A, B, C, D, E, F, G>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H], fn: UpdateFn<Val8<T, A, B, C, D, E, F, G, H>>): FnO<T, T>;
export declare function updaterT<T, A extends Keys<T>, B extends Keys1<T, A>, C extends Keys2<T, A, B>, D extends Keys3<T, A, B, C>, E extends Keys4<T, A, B, C, D>, F extends Keys5<T, A, B, C, D, E>, G extends Keys6<T, A, B, C, D, E, F>, H extends Keys7<T, A, B, C, D, E, F, G>>(path: [A, B, C, D, E, F, G, H, ...PropertyKey[]], fn: UpdateFn<any>): FnO<T, T>;
export declare function defUpdater<T>(path: Path0, fn: UpdateFn<T, T>): FnO<T, T>;
export declare function defUpdater<T, A>(path: Path1<T, A>, fn: UpdateFn<OptPathVal<T, [A]>, PathVal<T, [A]>>): FnO<T, T>;
export declare function defUpdater<T, A, B>(path: Path2<T, A, B>, fn: UpdateFn<OptPathVal<T, [A, B]>, PathVal<T, [A, B]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C>(path: Path3<T, A, B, C>, fn: UpdateFn<OptPathVal<T, [A, B, C]>, PathVal<T, [A, B, C]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D>(path: Path4<T, A, B, C, D>, fn: UpdateFn<OptPathVal<T, [A, B, C, D]>, PathVal<T, [A, B, C, D]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D, E>(path: Path5<T, A, B, C, D, E>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E]>, PathVal<T, [A, B, C, D, E]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D, E, F>(path: Path6<T, A, B, C, D, E, F>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F]>, PathVal<T, [A, B, C, D, E, F]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D, E, F, G>(path: Path7<T, A, B, C, D, E, F, G>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F, G]>, PathVal<T, [A, B, C, D, E, F, G]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D, E, F, G, H>(path: Path8<T, A, B, C, D, E, F, G, H>, fn: UpdateFn<OptPathVal<T, [A, B, C, D, E, F, G, H]>, PathVal<T, [A, B, C, D, E, F, G, H]>>): FnO<T, T>;
export declare function defUpdater<T, A, B, C, D, E, F, G, H>(path: DeepPath<T, A, B, C, D, E, F, G, H>, fn: UpdateFn<any, any>): FnO<T, T>;
//# sourceMappingURL=updater.d.ts.map

@@ -1,17 +0,23 @@

import { getterT } from "./getter";
import { setterT } from "./setter";
import { defGetter } from "./getter";
import { defSetter } from "./setter";
/**
* Similar to {@link setter}, returns a function to update values at
* given `path` using provided update `fn`.
* Similar to {@link defSetterUnsafe}, returns a function to update
* values at given `path` using provided update `fn`. Paths and the
* arguments given to the returned function are NOT type checked.
*
* @remarks
* The returned function accepts a single object / array and applies
* `fn` to current path value (incl. any additional/optional arguments
* passed) and uses result as new value. Does not modify original state
* (unless given function does so itself).
* `fn` to given path value (incl. any additional / optional arguments
* passed) and uses result as new value. Does not modify original state.
*
* ```
* add = updater("a.b", (x, n) => x + n);
* The type parameter `T` can be used to indicate the type of the nested
* value to be updated (default: `any`).
*
* add({a: {b: 10}}, 13);
* @example
* ```ts
* const incB = defUpdaterUnsafe("a.b", (x, n) => x + n);
* // or
* const incB = defUpdaterUnsafe(["a", "b"], (x, n) => x + n);
*
* incB({ a: { b: 10 } }, 13);
* // { a: { b: 23 } }

@@ -23,7 +29,7 @@ * ```

*/
export const updater = (path, fn) => updaterT(path, fn);
export function updaterT(path, fn) {
const g = getterT(path);
const s = setterT(path);
export const defUpdaterUnsafe = (path, fn) => defUpdater(path, fn);
export function defUpdater(path, fn) {
const g = defGetter(path);
const s = defSetter(path);
return (state, ...args) => s(state, fn.apply(null, (args.unshift(g(state)), args)));
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc