Skip to content

Commit 11d1f21

Browse files
committed
Fix memoryStore does not support nested-looking keys
1 parent eda127a commit 11d1f21

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

packages/ra-core/src/store/memoryStore.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,31 @@ describe('memoryStore', () => {
4040
expect(store.getItem('foo')).toEqual(undefined);
4141
});
4242
});
43+
44+
describe('nested-looking keys', () => {
45+
it('should store and retrieve values in keys that appear nested without overriding content', () => {
46+
const store = memoryStore();
47+
store.setItem('foo', 'parent value');
48+
store.setItem('foo.bar', 'nested value');
49+
50+
expect(store.getItem('foo')).toEqual('parent value');
51+
expect(store.getItem('foo.bar')).toEqual('nested value');
52+
});
53+
54+
it('should handle initial storage with nested objects', () => {
55+
const initialStorage = {
56+
user: {
57+
name: 'John',
58+
settings: {
59+
theme: 'dark',
60+
},
61+
},
62+
};
63+
64+
const store = memoryStore(initialStorage);
65+
66+
expect(store.getItem('user.name')).toEqual('John');
67+
expect(store.getItem('user.settings.theme')).toEqual('dark');
68+
});
69+
});
4370
});

packages/ra-core/src/store/memoryStore.tsx

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import set from 'lodash/set.js';
2-
import unset from 'lodash/unset.js';
3-
import get from 'lodash/get.js';
41
import { Store } from './types';
52

63
type Subscription = {
@@ -21,8 +18,15 @@ type Subscription = {
2118
* </Admin>
2219
* );
2320
*/
24-
export const memoryStore = (storage: any = {}): Store => {
21+
export const memoryStore = (
22+
initialStorage: Record<string, any> = {}
23+
): Store => {
24+
// Use a flat Map to store key-value pairs directly without treating dots as nested paths
25+
const storage = new Map<string, any>(
26+
Object.entries(flatten(initialStorage))
27+
);
2528
const subscriptions: { [key: string]: Subscription } = {};
29+
2630
const publish = (key: string, value: any) => {
2731
Object.keys(subscriptions).forEach(id => {
2832
if (!subscriptions[id]) return; // may happen if a component unmounts after a first subscriber was notified
@@ -31,36 +35,44 @@ export const memoryStore = (storage: any = {}): Store => {
3135
}
3236
});
3337
};
38+
3439
return {
3540
setup: () => {},
3641
teardown: () => {
37-
Object.keys(storage).forEach(key => delete storage[key]);
42+
storage.clear();
3843
},
3944
getItem<T = any>(key: string, defaultValue?: T): T {
40-
return get(storage, key, defaultValue);
45+
return storage.has(key)
46+
? (storage.get(key) as T)
47+
: (defaultValue as T);
4148
},
4249
setItem<T = any>(key: string, value: T): void {
43-
set(storage, key, value);
50+
storage.set(key, value);
4451
publish(key, value);
4552
},
4653
removeItem(key: string): void {
47-
unset(storage, key);
54+
storage.delete(key);
4855
publish(key, undefined);
4956
},
5057
removeItems(keyPrefix: string): void {
51-
const flatStorage = flatten(storage);
52-
Object.keys(flatStorage).forEach(key => {
53-
if (!key.startsWith(keyPrefix)) {
54-
return;
58+
const keysToDelete: string[] = [];
59+
storage.forEach((_, key) => {
60+
if (key.startsWith(keyPrefix)) {
61+
keysToDelete.push(key);
5562
}
56-
unset(storage, key);
63+
});
64+
keysToDelete.forEach(key => {
65+
storage.delete(key);
5766
publish(key, undefined);
5867
});
5968
},
6069
reset(): void {
61-
const flatStorage = flatten(storage);
62-
Object.keys(flatStorage).forEach(key => {
63-
unset(storage, key);
70+
const keysToDelete: string[] = [];
71+
storage.forEach((_, key) => {
72+
keysToDelete.push(key);
73+
});
74+
storage.clear();
75+
keysToDelete.forEach(key => {
6476
publish(key, undefined);
6577
});
6678
},

0 commit comments

Comments
 (0)