pocket-state 0.1.17 → 0.1.18
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.
- package/package.json +1 -1
- package/src/globalState/{create.ts → create-hook.ts} +6 -6
- package/src/globalState/hooks.ts +9 -11
- package/src/globalState/store.ts +8 -13
- package/src/globalState/type.d.ts +8 -0
- package/src/index.tsx +2 -2
- package/src/utils/cloneObject.ts +25 -0
- package/src/{globalState → utils}/event.ts +1 -1
- package/src/utils/isArray.ts +2 -0
- package/src/utils/isDateObject.ts +1 -0
- package/src/utils/isFunction.ts +2 -0
- package/src/utils/isNullOrUndefined.ts +1 -0
- package/src/utils/isObject.ts +11 -0
- package/src/utils/isPlainObject.ts +10 -0
- package/src/utils/isPromise.ts +2 -0
- /package/src/{globalState → utils}/shallowEqual.ts +0 -0
- /package/src/{globalState → utils}/type-helper.d.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {useMemo} from 'react';
|
|
2
|
+
import {useStore} from './hooks';
|
|
3
|
+
import {Store} from './type';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Creates a custom React hook for a store, giving you access to the store API
|
|
@@ -27,14 +27,14 @@ import { Store } from "./type";
|
|
|
27
27
|
* 2. `useHook(selector)` – Returns `{ value, ...api }` where `value` is the selected state. Re-renders on selected value changes.
|
|
28
28
|
*/
|
|
29
29
|
export function createHook<T>(store: Store<T>) {
|
|
30
|
-
const api = {
|
|
30
|
+
const api = {...store};
|
|
31
31
|
|
|
32
32
|
function useBoundStore(): typeof api;
|
|
33
|
-
function useBoundStore<S>(selector: (state: T) => S): {
|
|
33
|
+
function useBoundStore<S>(selector: (state: T) => S): {value: S} & typeof api;
|
|
34
34
|
function useBoundStore<S = T>(selector?: (state: T) => S) {
|
|
35
35
|
if (!selector) return api;
|
|
36
36
|
const value = useStore(store, selector);
|
|
37
|
-
return useMemo(() => ({
|
|
37
|
+
return useMemo(() => ({value, ...api}), [value]);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return useBoundStore;
|
package/src/globalState/hooks.ts
CHANGED
|
@@ -7,19 +7,17 @@ export function useStore<T, S = T>(
|
|
|
7
7
|
): S {
|
|
8
8
|
const sel = selector ?? ((s: T) => s as unknown as S);
|
|
9
9
|
|
|
10
|
+
|
|
10
11
|
const lastStateRef = useRef<T>(store.getValue());
|
|
11
12
|
const lastSliceRef = useRef<S>(sel(lastStateRef.current));
|
|
12
13
|
|
|
13
|
-
const subscribe = useCallback(
|
|
14
|
-
(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
[store, sel],
|
|
22
|
-
);
|
|
14
|
+
const subscribe = useCallback((onChange: () => void) => {
|
|
15
|
+
return store.subscribe(sel, (nextSlice: S) => {
|
|
16
|
+
lastStateRef.current = store.getValue();
|
|
17
|
+
lastSliceRef.current = nextSlice;
|
|
18
|
+
onChange();
|
|
19
|
+
});
|
|
20
|
+
}, []);
|
|
23
21
|
|
|
24
22
|
const getSnapshot = useCallback(() => {
|
|
25
23
|
const s = store.getValue();
|
|
@@ -28,7 +26,7 @@ export function useStore<T, S = T>(
|
|
|
28
26
|
lastSliceRef.current = sel(s);
|
|
29
27
|
}
|
|
30
28
|
return lastSliceRef.current;
|
|
31
|
-
}, [
|
|
29
|
+
}, []);
|
|
32
30
|
|
|
33
31
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
34
32
|
}
|
package/src/globalState/store.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// store.ts
|
|
2
2
|
import {IEventEmitter, Listener, Middleware, Store, UseStoreGet} from './type';
|
|
3
|
-
import {EventEmitter} from '
|
|
3
|
+
import {EventEmitter} from '../utils/event';
|
|
4
4
|
import {Draft, produce} from 'immer';
|
|
5
|
-
import {shallow} from '
|
|
5
|
+
import {shallow} from '../utils/shallowEqual';
|
|
6
|
+
import cloneObject from '../utils/cloneObject';
|
|
7
|
+
import isPromise from '../utils/isPromise';
|
|
8
|
+
import isArray from '../utils/isArray';
|
|
6
9
|
|
|
7
10
|
export function createStore<T>(
|
|
8
11
|
initialState: T,
|
|
@@ -10,7 +13,7 @@ export function createStore<T>(
|
|
|
10
13
|
equalityFn?: (a: any, b: any) => boolean,
|
|
11
14
|
): Store<T> {
|
|
12
15
|
const emitter: IEventEmitter = new EventEmitter();
|
|
13
|
-
const _initialState =
|
|
16
|
+
const _initialState = isArray(initialState)
|
|
14
17
|
? (initialState as any).slice()
|
|
15
18
|
: initialState && typeof initialState === 'object'
|
|
16
19
|
? {...initialState}
|
|
@@ -76,7 +79,7 @@ export function createStore<T>(
|
|
|
76
79
|
patch: Partial<T> | ((state: T) => Partial<T> | Promise<Partial<T>>),
|
|
77
80
|
): void {
|
|
78
81
|
let resolved = typeof patch === 'function' ? patch(state) : patch;
|
|
79
|
-
if (resolved
|
|
82
|
+
if (isPromise(resolved)) {
|
|
80
83
|
resolved
|
|
81
84
|
.then(res => {
|
|
82
85
|
if (res && typeof res === 'object') {
|
|
@@ -122,21 +125,13 @@ export function createStore<T>(
|
|
|
122
125
|
}
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
function reset(): void;
|
|
126
|
-
function reset(initialValue?: T | Partial<T>): void;
|
|
127
128
|
function reset(initialValue?: T | Partial<T>) {
|
|
128
129
|
const isObj = (
|
|
129
130
|
v: unknown,
|
|
130
131
|
): v is Record<string | symbol | number, unknown> =>
|
|
131
132
|
typeof v === 'object' && v !== null;
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
if (Array.isArray(src)) return (src as any).slice();
|
|
135
|
-
if (isObj(src)) return {...(src as any)} as U;
|
|
136
|
-
return src;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
let next = cloneShallow(initialState) as T;
|
|
134
|
+
let next = cloneObject(initialState) as T;
|
|
140
135
|
if (initialValue !== undefined) {
|
|
141
136
|
if (Array.isArray(initialValue)) {
|
|
142
137
|
next = (initialValue as any).slice();
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import {Draft} from 'immer';
|
|
2
2
|
|
|
3
|
+
interface FileList {
|
|
4
|
+
readonly length: number;
|
|
5
|
+
item(index: number): File | null;
|
|
6
|
+
[index: number]: File;
|
|
7
|
+
}
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* A callback invoked when an event is emitted with a payload of type `T`.
|
|
5
11
|
* Keep listeners pure and fast. Long-running side effects should live in
|
|
@@ -200,6 +206,8 @@ export interface Store<T> {
|
|
|
200
206
|
|
|
201
207
|
/** Get number of subscriber for current store */
|
|
202
208
|
getNumberOfSubscriber(): number;
|
|
209
|
+
|
|
210
|
+
/** */
|
|
203
211
|
}
|
|
204
212
|
|
|
205
213
|
/**
|
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from './globalState/store';
|
|
2
2
|
export * from './globalState/hooks';
|
|
3
|
-
export * from './globalState/create';
|
|
3
|
+
export * from './globalState/create-hook';
|
|
4
4
|
export type * from './globalState/type';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './utils/event';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import isArray from './isArray';
|
|
2
|
+
import isObject from './isObject';
|
|
3
|
+
import isPlainObject from './isPlainObject';
|
|
4
|
+
|
|
5
|
+
export default function cloneObject<T>(data: T): T {
|
|
6
|
+
let copy: any;
|
|
7
|
+
|
|
8
|
+
if (data instanceof Date) {
|
|
9
|
+
copy = new Date(data);
|
|
10
|
+
} else if (isArray(data) || isObject(data)) {
|
|
11
|
+
copy = isArray(data) ? [] : Object.create(Object.getPrototypeOf(data));
|
|
12
|
+
if (!isArray(data) && !isPlainObject(data)) {
|
|
13
|
+
copy = data;
|
|
14
|
+
} else {
|
|
15
|
+
for (const key in data) {
|
|
16
|
+
if (data.hasOwnProperty(key)) {
|
|
17
|
+
copy[key] = cloneObject(data[key]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
return copy;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default (value: unknown): value is Date => value instanceof Date;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default (value: unknown): value is null | undefined => value == null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import isDateObject from './isDateObject';
|
|
2
|
+
import isNullOrUndefined from './isNullOrUndefined';
|
|
3
|
+
|
|
4
|
+
export const isObjectType = (value: unknown): value is object =>
|
|
5
|
+
typeof value === 'object';
|
|
6
|
+
|
|
7
|
+
export default <T extends object>(value: unknown): value is T =>
|
|
8
|
+
!isNullOrUndefined(value) &&
|
|
9
|
+
!Array.isArray(value) &&
|
|
10
|
+
isObjectType(value) &&
|
|
11
|
+
!isDateObject(value);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import isObject from './isObject';
|
|
2
|
+
|
|
3
|
+
export default (tempObject: object) => {
|
|
4
|
+
const prototypeCopy =
|
|
5
|
+
tempObject.constructor && tempObject.constructor.prototype;
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
isObject(prototypeCopy) && prototypeCopy.hasOwnProperty('isPrototypeOf')
|
|
9
|
+
);
|
|
10
|
+
};
|
|
File without changes
|
|
File without changes
|