Skip to content

Commit

Permalink
simplify map
Browse files Browse the repository at this point in the history
  • Loading branch information
postrockreverb committed Jun 7, 2024
1 parent 145e9fd commit 79e7f0d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 33 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yermak/derived",
"version": "1.0.0",
"version": "1.0.1",
"description": "State manager library",
"main": "./dist/index.js",
"module": "./dist/index.js",
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { derived, type DerivedType } from './derived';
export { async, type AsyncType } from './async';
export { map, type MapType } from './map';
export { useObservable, type ObservableType } from './observable';
export { observer, type Observer } from './observer';
62 changes: 30 additions & 32 deletions src/map.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,59 @@
import { ObservableType } from './observable';
import { observer } from './observer';
import { store, StoreType } from './store';

type MapValue<K extends keyof any, V> = Record<K, V>;

type MapItemStore<V> = StoreType<V | undefined>;

export interface MapType<K extends keyof any, V> extends ObservableType<Map<K, StoreType<V | undefined>>> {
export interface MapType<K extends keyof any, V> {
item: (key?: K | null | undefined) => MapItemStore<V>;
has: (key: K) => boolean;
set: (key: K, value: V) => void;
delete: (key: K) => void;
}

export function map<K extends keyof any, V>(initialValue?: MapValue<K, V>): MapType<K, V> {
type ItemStore = MapItemStore<V>;
type ItemValue = V | undefined;

const _observer = observer<Map<K, ItemStore>>();

const undefinedStore = store<ItemValue>(undefined);

const map = new Map<K, ItemStore>();
if (initialValue) {
for (let key in initialValue) {
const value = store<ItemValue>(initialValue[key]);
map.set(key, value);

const addStore = (key: K, value: ItemValue): ItemStore => {
const valueStore = store<ItemValue>(value);
map.set(key, valueStore);
return valueStore;
};

const getStore = (key: K): ItemStore => {
const valueStore = map.get(key);
if (valueStore === undefined) {
return addStore(key, undefined);
}
return valueStore;
};

for (let key in initialValue) {
addStore(key, initialValue[key]);
}

return {
get: () => map,
item: (key?: K | null | undefined) => {
if (key === null || key === undefined) {
return undefinedStore;
}
let valueStore = map.get(key);
if (valueStore === undefined) {
valueStore = store<ItemValue>(undefined);
map.set(key, valueStore);
}
return valueStore;
},
has: (key: K) => map.has(key),
set: (key: K, value: V) => {
const valueStore = map.get(key);
if (valueStore === undefined) {
map.set(key, store<ItemValue>(value));
_observer.notify(map);
return;
}
if (valueStore.get() !== value) {
valueStore.set(value);
_observer.notify(map);
return;
}
const valueStore = getStore(key);
return {
set: (newValue) => {
if (valueStore.get() === newValue) {
return;
}
valueStore.set(newValue);
_observer.notify(new Map(map));
},
get: valueStore.get,
subscribe: valueStore.subscribe,
};
},
delete: (key: K) => map.delete(key),
subscribe: _observer.subscribe,
};
}

0 comments on commit 79e7f0d

Please sign in to comment.