floppy-disk 1.2.0 → 1.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,12 @@ export type UseStore<T extends StoreData> = {
15
15
  set: (value: SetStoreData<T>, silent?: boolean) => void;
16
16
  subscribe: (fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
17
17
  getSubscribers: () => Subscribers<T>;
18
+ /**
19
+ * Set default values inside a component.
20
+ *
21
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
22
+ */
23
+ setDefaultValues: (values: SetStoreData<T>) => void;
18
24
  Watch: (props: WatchProps<T>) => any;
19
25
  };
20
26
  export declare const createStore: <T extends StoreData>(initializer: StoreInitializer<T>, options?: InitStoreOptions<T> & {
@@ -16,6 +16,16 @@ export const createStore = (initializer, options = {}) => {
16
16
  useStore.set = set;
17
17
  useStore.subscribe = subscribe;
18
18
  useStore.getSubscribers = getSubscribers;
19
+ useStore.setDefaultValues = (value) => {
20
+ // eslint-disable-next-line react-hooks/rules-of-hooks
21
+ useState(() => {
22
+ const subscribers = getSubscribers();
23
+ if (subscribers.size > 0) {
24
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
25
+ }
26
+ set(value);
27
+ });
28
+ };
19
29
  const Watch = ({ selectDeps, render }) => {
20
30
  const store = useStore(selectDeps);
21
31
  return render(store);
@@ -1,5 +1,6 @@
1
1
  import { InitStoreOptions, SelectDeps, SetStoreData, StoreData, Subscribers } from '../vanilla';
2
2
  import { WatchProps } from './create-store';
3
+ type Maybe<T> = T | null | undefined;
3
4
  export type StoreKey = Record<string, any> | undefined;
4
5
  export type StoresInitializer<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = (api: {
5
6
  key: TKey;
@@ -15,20 +16,28 @@ export type UseStores<TKey extends StoreKey = StoreKey, T extends StoreData = St
15
16
  *
16
17
  * IMPORTANT NOTE: `selectDeps` must not be changed after initialization.
17
18
  */
18
- (...args: [TKey?, SelectDeps<T>?] | [SelectDeps<T>?]): T;
19
- get: (key?: TKey) => T;
19
+ (...args: [Maybe<TKey>, SelectDeps<T>?] | [SelectDeps<T>?]): T;
20
+ get: (key?: Maybe<TKey>) => T;
20
21
  getAll: () => T[];
21
22
  getAllWithSubscriber: () => T[];
22
- set: (key: TKey, value: SetStoreData<T>, silent?: boolean) => void;
23
+ set: (key: Maybe<TKey>, value: SetStoreData<T>, silent?: boolean) => void;
23
24
  setAll: (value: SetStoreData<T>, silent?: boolean) => void;
24
- subscribe: (key: TKey, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
25
- getSubscribers: (key: TKey) => Subscribers<T>;
25
+ subscribe: (key: Maybe<TKey>, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
26
+ getSubscribers: (key: Maybe<TKey>) => Subscribers<T>;
27
+ /**
28
+ * Set default values inside a component.
29
+ *
30
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
31
+ */
32
+ setDefaultValues: (key: Maybe<TKey>, values: SetStoreData<T>) => void;
26
33
  Watch: (props: WatchProps<T> & {
27
- storeKey?: TKey;
34
+ storeKey?: Maybe<TKey>;
28
35
  }) => any;
29
36
  };
30
37
  export type CreateStoresOptions<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = InitStoreOptions<T> & {
31
38
  onBeforeChangeKey?: (nextKey: TKey, prevKey: TKey) => void;
32
39
  defaultDeps?: SelectDeps<T>;
40
+ hashKeyFn?: (obj: TKey) => string;
33
41
  };
34
42
  export declare const createStores: <TKey extends StoreKey = StoreKey, T extends StoreData = StoreData>(initializer: StoresInitializer<TKey, T>, options?: CreateStoresOptions<TKey, T>) => UseStores<TKey, T>;
43
+ export {};
@@ -3,10 +3,11 @@ import { noop } from '../utils';
3
3
  import { initStore, } from '../vanilla';
4
4
  const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
5
5
  export const createStores = (initializer, options = {}) => {
6
- const { onBeforeChangeKey = noop, defaultDeps } = options;
6
+ const { onBeforeChangeKey = noop, defaultDeps, hashKeyFn = hashStoreKey } = options;
7
7
  const stores = new Map();
8
- const getStore = (key) => {
9
- const normalizedKey = hashStoreKey(key);
8
+ const getStore = (_key) => {
9
+ const key = _key || {};
10
+ const normalizedKey = hashKeyFn(key);
10
11
  if (!stores.has(normalizedKey)) {
11
12
  stores.set(normalizedKey, initStore((api) => initializer({ key, ...api }), options));
12
13
  }
@@ -16,9 +17,9 @@ export const createStores = (initializer, options = {}) => {
16
17
  * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
17
18
  */
18
19
  const useStores = (...args) => {
19
- const [_key = {}, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
20
- const key = _key;
21
- const normalizedKey = hashStoreKey(key);
20
+ const [_key, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
21
+ const key = _key || {};
22
+ const normalizedKey = hashKeyFn(key);
22
23
  // eslint-disable-next-line react-hooks/exhaustive-deps
23
24
  const { get, subscribe } = useMemo(() => getStore(key), [normalizedKey]);
24
25
  const [state, setState] = useState(get);
@@ -37,7 +38,7 @@ export const createStores = (initializer, options = {}) => {
37
38
  }, [normalizedKey]);
38
39
  return state;
39
40
  };
40
- useStores.get = (key = {}) => {
41
+ useStores.get = (key) => {
41
42
  const store = getStore(key);
42
43
  return store.get();
43
44
  };
@@ -57,7 +58,7 @@ export const createStores = (initializer, options = {}) => {
57
58
  });
58
59
  return allStores;
59
60
  };
60
- useStores.set = (key = {}, value, silent) => {
61
+ useStores.set = (key, value, silent) => {
61
62
  const store = getStore(key);
62
63
  store.set(value, silent);
63
64
  };
@@ -66,15 +67,26 @@ export const createStores = (initializer, options = {}) => {
66
67
  store.set(value, silent);
67
68
  });
68
69
  };
69
- useStores.subscribe = (key = {}, fn, selectDeps) => {
70
+ useStores.subscribe = (key, fn, selectDeps) => {
70
71
  const store = getStore(key);
71
72
  return store.subscribe(fn, selectDeps);
72
73
  };
73
- useStores.getSubscribers = (key = {}) => {
74
+ useStores.getSubscribers = (key) => {
74
75
  const store = getStore(key);
75
76
  return store.getSubscribers();
76
77
  };
77
- const Watch = ({ storeKey = {}, selectDeps, render }) => {
78
+ useStores.setDefaultValues = (key, value) => {
79
+ // eslint-disable-next-line react-hooks/rules-of-hooks
80
+ useState(() => {
81
+ const store = getStore(key);
82
+ const subscribers = store.getSubscribers();
83
+ if (subscribers.size > 0) {
84
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
85
+ }
86
+ store.set(value);
87
+ });
88
+ };
89
+ const Watch = ({ storeKey, selectDeps, render }) => {
78
90
  const store = useStores(storeKey, selectDeps);
79
91
  return render(store);
80
92
  };
@@ -15,6 +15,12 @@ export type UseStore<T extends StoreData> = {
15
15
  set: (value: SetStoreData<T>, silent?: boolean) => void;
16
16
  subscribe: (fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
17
17
  getSubscribers: () => Subscribers<T>;
18
+ /**
19
+ * Set default values inside a component.
20
+ *
21
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
22
+ */
23
+ setDefaultValues: (values: SetStoreData<T>) => void;
18
24
  Watch: (props: WatchProps<T>) => any;
19
25
  };
20
26
  export declare const createStore: <T extends StoreData>(initializer: StoreInitializer<T>, options?: InitStoreOptions<T> & {
@@ -19,6 +19,16 @@ const createStore = (initializer, options = {}) => {
19
19
  useStore.set = set;
20
20
  useStore.subscribe = subscribe;
21
21
  useStore.getSubscribers = getSubscribers;
22
+ useStore.setDefaultValues = (value) => {
23
+ // eslint-disable-next-line react-hooks/rules-of-hooks
24
+ (0, react_1.useState)(() => {
25
+ const subscribers = getSubscribers();
26
+ if (subscribers.size > 0) {
27
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
28
+ }
29
+ set(value);
30
+ });
31
+ };
22
32
  const Watch = ({ selectDeps, render }) => {
23
33
  const store = useStore(selectDeps);
24
34
  return render(store);
@@ -1,5 +1,6 @@
1
1
  import { InitStoreOptions, SelectDeps, SetStoreData, StoreData, Subscribers } from '../vanilla';
2
2
  import { WatchProps } from './create-store';
3
+ type Maybe<T> = T | null | undefined;
3
4
  export type StoreKey = Record<string, any> | undefined;
4
5
  export type StoresInitializer<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = (api: {
5
6
  key: TKey;
@@ -15,20 +16,28 @@ export type UseStores<TKey extends StoreKey = StoreKey, T extends StoreData = St
15
16
  *
16
17
  * IMPORTANT NOTE: `selectDeps` must not be changed after initialization.
17
18
  */
18
- (...args: [TKey?, SelectDeps<T>?] | [SelectDeps<T>?]): T;
19
- get: (key?: TKey) => T;
19
+ (...args: [Maybe<TKey>, SelectDeps<T>?] | [SelectDeps<T>?]): T;
20
+ get: (key?: Maybe<TKey>) => T;
20
21
  getAll: () => T[];
21
22
  getAllWithSubscriber: () => T[];
22
- set: (key: TKey, value: SetStoreData<T>, silent?: boolean) => void;
23
+ set: (key: Maybe<TKey>, value: SetStoreData<T>, silent?: boolean) => void;
23
24
  setAll: (value: SetStoreData<T>, silent?: boolean) => void;
24
- subscribe: (key: TKey, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
25
- getSubscribers: (key: TKey) => Subscribers<T>;
25
+ subscribe: (key: Maybe<TKey>, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
26
+ getSubscribers: (key: Maybe<TKey>) => Subscribers<T>;
27
+ /**
28
+ * Set default values inside a component.
29
+ *
30
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
31
+ */
32
+ setDefaultValues: (key: Maybe<TKey>, values: SetStoreData<T>) => void;
26
33
  Watch: (props: WatchProps<T> & {
27
- storeKey?: TKey;
34
+ storeKey?: Maybe<TKey>;
28
35
  }) => any;
29
36
  };
30
37
  export type CreateStoresOptions<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = InitStoreOptions<T> & {
31
38
  onBeforeChangeKey?: (nextKey: TKey, prevKey: TKey) => void;
32
39
  defaultDeps?: SelectDeps<T>;
40
+ hashKeyFn?: (obj: TKey) => string;
33
41
  };
34
42
  export declare const createStores: <TKey extends StoreKey = StoreKey, T extends StoreData = StoreData>(initializer: StoresInitializer<TKey, T>, options?: CreateStoresOptions<TKey, T>) => UseStores<TKey, T>;
43
+ export {};
@@ -6,10 +6,11 @@ const utils_1 = require("../utils");
6
6
  const vanilla_1 = require("../vanilla");
7
7
  const hashStoreKey = (obj) => JSON.stringify(obj, Object.keys(obj).sort());
8
8
  const createStores = (initializer, options = {}) => {
9
- const { onBeforeChangeKey = utils_1.noop, defaultDeps } = options;
9
+ const { onBeforeChangeKey = utils_1.noop, defaultDeps, hashKeyFn = hashStoreKey } = options;
10
10
  const stores = new Map();
11
- const getStore = (key) => {
12
- const normalizedKey = hashStoreKey(key);
11
+ const getStore = (_key) => {
12
+ const key = _key || {};
13
+ const normalizedKey = hashKeyFn(key);
13
14
  if (!stores.has(normalizedKey)) {
14
15
  stores.set(normalizedKey, (0, vanilla_1.initStore)((api) => initializer({ key, ...api }), options));
15
16
  }
@@ -19,9 +20,9 @@ const createStores = (initializer, options = {}) => {
19
20
  * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
20
21
  */
21
22
  const useStores = (...args) => {
22
- const [_key = {}, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
23
- const key = _key;
24
- const normalizedKey = hashStoreKey(key);
23
+ const [_key, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
24
+ const key = _key || {};
25
+ const normalizedKey = hashKeyFn(key);
25
26
  // eslint-disable-next-line react-hooks/exhaustive-deps
26
27
  const { get, subscribe } = (0, react_1.useMemo)(() => getStore(key), [normalizedKey]);
27
28
  const [state, setState] = (0, react_1.useState)(get);
@@ -40,7 +41,7 @@ const createStores = (initializer, options = {}) => {
40
41
  }, [normalizedKey]);
41
42
  return state;
42
43
  };
43
- useStores.get = (key = {}) => {
44
+ useStores.get = (key) => {
44
45
  const store = getStore(key);
45
46
  return store.get();
46
47
  };
@@ -60,7 +61,7 @@ const createStores = (initializer, options = {}) => {
60
61
  });
61
62
  return allStores;
62
63
  };
63
- useStores.set = (key = {}, value, silent) => {
64
+ useStores.set = (key, value, silent) => {
64
65
  const store = getStore(key);
65
66
  store.set(value, silent);
66
67
  };
@@ -69,15 +70,26 @@ const createStores = (initializer, options = {}) => {
69
70
  store.set(value, silent);
70
71
  });
71
72
  };
72
- useStores.subscribe = (key = {}, fn, selectDeps) => {
73
+ useStores.subscribe = (key, fn, selectDeps) => {
73
74
  const store = getStore(key);
74
75
  return store.subscribe(fn, selectDeps);
75
76
  };
76
- useStores.getSubscribers = (key = {}) => {
77
+ useStores.getSubscribers = (key) => {
77
78
  const store = getStore(key);
78
79
  return store.getSubscribers();
79
80
  };
80
- const Watch = ({ storeKey = {}, selectDeps, render }) => {
81
+ useStores.setDefaultValues = (key, value) => {
82
+ // eslint-disable-next-line react-hooks/rules-of-hooks
83
+ (0, react_1.useState)(() => {
84
+ const store = getStore(key);
85
+ const subscribers = store.getSubscribers();
86
+ if (subscribers.size > 0) {
87
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
88
+ }
89
+ store.set(value);
90
+ });
91
+ };
92
+ const Watch = ({ storeKey, selectDeps, render }) => {
81
93
  const store = useStores(storeKey, selectDeps);
82
94
  return render(store);
83
95
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "floppy-disk",
3
- "version": "1.2.0",
3
+ "version": "1.3.0-beta.1",
4
4
  "description": "FloppyDisk - lightweight, simple, and powerful state management library",
5
5
  "keywords": [
6
6
  "state",