Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: atomTree #2

Merged
merged 2 commits into from
Jan 25, 2025
Merged

feat: atomTree #2

merged 2 commits into from
Jan 25, 2025

Conversation

dmaskasky
Copy link
Member

@dmaskasky dmaskasky commented Dec 27, 2024

Summary

This pull request adds a new utility, atomTree, which allows us to manage hierarchical Jotai atoms in a tree-like structure. It works similarly to Jotai’s atomFamily but provides subtree management, making it convenient to remove or inspect entire branches.

import { atom } from 'jotai'
import { atomTree } from 'jotai-family'

const tree = atomTree((path) => atom(path.join('-')))

const atomA = tree(['foo', 'bar'])
const atomB = tree(['foo', 'bar'])

// Remove the atom at the given path
tree.remove(['foo', 'bar'])

Details

Creating Path Atoms

tree(path: Path): AtomType

Creates (or retrieves) an atom at the specified path. Subsequent calls with the same path return the same atom instance.

Removing Path Atoms

tree.remove(path: Path, removeSubTree = false): void

Removes the atom at the specified path. If removeSubTree is true, all child paths under that path are also removed.

This method removes the atom at the specified path. If removeSubTree is true, it also removes all child paths under that path.

Retrieving A Subtree

tree.getSubTree(path: Path): Node<AtomType> | undefined

Retrieves the internal node representing the specified path. This is useful for inspecting the tree structure. The node structure is as follows:

type Node<AtomType> = {
  atom?: AtomType
  children?: Map<PathSegment, Node<AtomType>>
}

Retrieving A Node Path

tree.getNodePath(path: Path): Node<AtomType>[]

Returns an array of node objects from the root node to the node at the specified path, inclusive.

Why we need this

  • Managing data in a hierarchical structure is a common requirement in applications (e.g., file systems, nested comments, or deeply nested UI states).
  • atomTree provides a convenient way to handle nested states, removing entire subtrees when they are no longer needed.

How it works

  • Internally, atomTree maintains a root object of type Node, having a Map for children and an optional atom reference.
  • Each path segment navigates deeper into the map, creating sub-nodes as needed.
  • Removing subtrees cleans up child nodes and references to maintain a healthy and predictable state tree.

Please review and let me know if you have any suggestions or concerns. Thank you!

Credit: For the inspiration, thank you @paralin

@paralin
Copy link

paralin commented Dec 27, 2024

Copy link

codesandbox-ci bot commented Jan 24, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@dmaskasky dmaskasky changed the title rough draft idea for atom tree feat: atomTree Jan 24, 2025
@dmaskasky dmaskasky force-pushed the atom-tree branch 5 times, most recently from fb81f62 to 3583bc4 Compare January 24, 2025 23:56
- createAtom
- createAtom.remove
- createAtom.getSubTree
- createAtom.getNodePath
@dmaskasky dmaskasky merged commit 33fdf9b into main Jan 25, 2025
3 checks passed
@dmaskasky dmaskasky deleted the atom-tree branch January 25, 2025 00:07
@paralin
Copy link

paralin commented Jan 25, 2025

Cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants