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: add back dev4_restore_atoms to store v2 #2509

Merged
merged 10 commits into from
May 21, 2024
3 changes: 0 additions & 3 deletions src/vanilla/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,6 @@ type PrdStore = {
}
type Store = PrdStore & Partial<DevStoreRev2>

export type INTERNAL_DevStoreRev2 = DevStoreRev2
export type INTERNAL_PrdStore = PrdStore

/**
* Create a new store. Each store is an independent, isolated universe of atom
* states.
Expand Down
18 changes: 18 additions & 0 deletions src/vanilla/store2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ type DevStoreRev4 = {
key: K,
fn: PrdStore[K],
) => void
dev4_restore_atoms: (values: Iterable<readonly [AnyAtom, AnyValue]>) => void
}

type PrdStore = {
Expand Down Expand Up @@ -679,6 +680,23 @@ export const createStore = (): Store => {
dev4_override_method: (key, fn) => {
;(store as any)[key] = fn
},
dev4_restore_atoms: (values) => {
const pending = createPending()
for (const [atom, value] of values) {
if (hasInitialValue(atom)) {
const aState = getAtomState(atom)
const hasPrevValue = 'v' in aState
const prevValue = aState.v
setAtomStateValueOrPromise(atom, aState, value)
mountDependencies(pending, atom, aState)
if (!hasPrevValue || !Object.is(prevValue, aState.v)) {
addPendingAtom(pending, atom, aState)
recomputeDependents(pending, atom)
}
}
}
flushPending(pending)
},
}
return store
}
Expand Down
36 changes: 36 additions & 0 deletions tests/vanilla/storedev.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,40 @@ describe.skipIf(!IS_DEV_STORE2)('[DEV-ONLY] dev-only methods rev4', () => {
const weakMap = store.dev4_get_internal_weak_map()
expect(weakMap.get(countAtom)?.v).toEqual(1)
})

it('should restore atoms and its dependencies correctly', () => {
const store = createStore() as any
if (!('dev4_restore_atoms' in store)) {
throw new Error('dev methods are not available')
}
const countAtom = atom(0)
const derivedAtom = atom((get) => get(countAtom) * 2)
store.set(countAtom, 1)
store.dev4_restore_atoms([[countAtom, 2]])
expect(store.get(countAtom)).toBe(2)
expect(store.get?.(derivedAtom)).toBe(4)
})

it('should restore atoms and call store listeners correctly', () => {
const store = createStore() as any
if (!('dev4_restore_atoms' in store)) {
throw new Error('dev methods are not available')
}
const countAtom = atom(0)
const derivedAtom = atom((get) => get(countAtom) * 2)
const countCb = vi.fn()
const derivedCb = vi.fn()
store.set(countAtom, 2)
const unsubCount = store.sub(countAtom, countCb)
const unsubDerived = store.sub(derivedAtom, derivedCb)
store.dev4_restore_atoms([
[countAtom, 1],
[derivedAtom, 2],
])

expect(countCb).toHaveBeenCalled()
expect(derivedCb).toHaveBeenCalled()
unsubCount()
unsubDerived()
})
})
Loading