feat(sync): add flatten() function (#43)

This commit is contained in:
richard 2025-01-25 16:11:34 -08:00 • committed by GitHub
parent 63388761f8
commit 8063ea3142
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 0 deletions

View file

@ -5,6 +5,8 @@ export as namespace CharmSync;
type Cleanup = () => void;
type Key = string | number | symbol;
declare namespace CharmSync {
type AtomMap = Record<string, Atom<any>>;
@ -60,6 +62,39 @@ declare namespace CharmSync {
*/
function isNone(value: unknown): value is None;
interface NestedAtomMap {
readonly [key: string]: NestedAtomMap | Atom<any>;
}
type AppendPath<Path extends Key | undefined, Name extends Key> = undefined extends Path
? Name
: Name extends string
? Path extends string
? `${Path}/${Name}`
: never
: never;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type IntersectValues<T> = UnionToIntersection<{ readonly [K in keyof T]: T[K] }[keyof T]>;
type FlattenNestedAtoms<Atoms extends NestedAtomMap, Path extends Key | undefined = undefined> = IntersectValues<{
readonly [Name in keyof Atoms as AppendPath<Path, Name>]: Atoms[Name] extends Atom<any>
? { readonly [K in AppendPath<Path, Name>]: Atoms[Name] }
: Atoms[Name] extends NestedAtomMap
? FlattenNestedAtoms<Atoms[Name], AppendPath<Path, Name>>
: never;
}>;
/**
* Flattens a nested atom map into a single object with slash-separated
* keys. Useful for recursively collecting atoms returned by modules.
*
* @param atoms The nested atom map to flatten.
* @return A flattened atom map.
*/
function flatten<Atoms extends NestedAtomMap>(atoms: Atoms): FlattenNestedAtoms<Atoms>;
type DataTypes = {
[P in keyof CheckableTypes as P extends keyof CheckablePrimitives ? never : P]: CheckableTypes[P];
};