fix(shared): give createPersistentStore a destroy() to dispose its effect.root
The store created an $effect.root for the save-on-change sync but returned no disposer, so the effect leaked for the life of the process — contradicting the rule that $effect.root owners must expose destroy(). Capture and expose the disposer. - add destroy() to the returned store; covered by tests (flushSync proves the save effect runs before destroy and stops after) - trim the bloated header (two near-duplicate @example blocks) to one concise JSDoc — no fluff - update typographySettings test mocks to satisfy the now-required destroy() Consumers (LayoutManager, ThemeManager, typographySettings, comparisonStore) do not yet call it — threading + the createSingleton migration follow.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
import { flushSync } from 'svelte';
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
@@ -376,4 +377,39 @@ describe('createPersistentStore', () => {
|
||||
expect(store.value[0].name).toBe('First');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Lifecycle', () => {
|
||||
it('persists value changes via the sync effect', () => {
|
||||
const store = createPersistentStore(testKey, 'a');
|
||||
const spy = vi.spyOn(mockLocalStorage, 'setItem');
|
||||
|
||||
store.value = 'b';
|
||||
flushSync();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(testKey, JSON.stringify('b'));
|
||||
});
|
||||
|
||||
it('stops persisting after destroy()', () => {
|
||||
const store = createPersistentStore(testKey, 'a');
|
||||
flushSync();
|
||||
store.destroy();
|
||||
|
||||
const spy = vi.spyOn(mockLocalStorage, 'setItem');
|
||||
store.value = 'c';
|
||||
flushSync();
|
||||
|
||||
expect(spy).not.toHaveBeenCalled();
|
||||
// reading still works after disposal
|
||||
expect(store.value).toBe('c');
|
||||
});
|
||||
|
||||
it('destroy() is safe to call repeatedly', () => {
|
||||
const store = createPersistentStore(testKey, 'a');
|
||||
|
||||
expect(() => {
|
||||
store.destroy();
|
||||
store.destroy();
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user