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

AtomicStore features #8

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft

AtomicStore features #8

wants to merge 13 commits into from

Conversation

beorn
Copy link

@beorn beorn commented Nov 25, 2024

See #7

Copy link

codesandbox-ci bot commented Nov 25, 2024

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.

Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preliminary review only on atomicStore.ts

* @template State - Type of the state definition object
*/
export function createAtomicStore<State extends object>(
initial: AtomicState<State>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another idea:

Suggested change
initial: AtomicState<State>,
definition: AtomicDefinition<State>,

baseValues[k] = desc.value;
}
}
const rootAtom = atom(baseValues);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better (perhaps more performant) to create baseAtoms first and derive rootAtom from them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's more performant, and we can try it. It'd be nice to be maximally performant.

I think the tradeoff is that updating several properties at once is a bit more tricky and less atomic, but perhaps not much of a problem — I didn't yet try to make the change.

In terms of performance, at least the direct subscriptions to the atoms will not be triggered unless the atom value changes, so it's just loop over properties, not a loop over all the consumers of the properties.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I removed rootAtom and it seems to work

): WritableAtom<void, any[], void> {
type Args = T[typeof key] extends (...args: infer P) => any ? P : never;

return atom(null, (get, set, ...args: Args) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use const ACTION = Symbol() instead of null.

get: any,
store: AtomicStore<T>,
baseAtoms: Map<keyof T, PrimitiveAtom<any>>,
initial: AtomicState<T>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to pass this. Just loop over baseAtoms and store?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just inlined the helper methods - they were quite tightly coupled to the code anyways (lots of parameters).

@dai-shi dai-shi marked this pull request as draft November 26, 2024 03:21
Copy link
Member

@dai-shi dai-shi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to move forward.

: Atom<T[K]>;
};

const ACTION = Symbol('ACTION'); // Unique symbol to denote action atoms
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to export this from this file, but...

Suggested change
const ACTION = Symbol('ACTION'); // Unique symbol to denote action atoms
export const ACTION = Symbol('ACTION'); // Unique symbol to denote action atoms

@@ -2,3 +2,4 @@ export { atomWithStore } from './atomWithStore.js';
export { atomWithActions } from './atomWithActions.js';
export { useSelector } from './useSelector.js';
export { create } from './create.js';
export * from './atomicStore.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...not from this file.

Suggested change
export * from './atomicStore.js';
export { createAtomicStore } from './atomicStore.js';

const baseAtoms = new Map<keyof State, PrimitiveAtom<any>>();

// Helper to check property types
const isPropType = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit:
Minification doesn't work for properties, so I'd define three functions:

const isActionPropType = (key) => ...;
const isDerivedPropType = (key) => ...;
const isBasePropType = (key) => ...;

const state = {} as T;

const get = () => state;
const set = (partial: Partial<T>) => Object.assign(state, partial);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too naive. state must be in atoms.

I don't think true "atomicStoreFromZustand" is possible. If we limit some usages, there might be a way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we added back the rootAtom to hold the basic state, and derived atoms from that? The rootAtom would just basically be the Zustand state.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atoms are configs and actual values are store in the Jotai store. So, there a contract mismatch. But, if we limit something, it might work. The rootAtom can be created from baseAtoms. The question is how to update the rootAtom from set().

@beorn
Copy link
Author

beorn commented Nov 27, 2024

Hm, I see a lot of errors - let me try to clean up and fix things first so that the tests run at least. Pls hold off reviewing for a while.

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