muya 1.1.0

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/src/types.ts ADDED
@@ -0,0 +1,94 @@
1
+ import type { Emitter } from './create-emitter'
2
+ import { isFunction, isPromise } from './is'
3
+
4
+ /**
5
+ * Equality check function.
6
+ */
7
+ export type IsEqual<T = unknown> = (a: T, b: T) => boolean
8
+
9
+ export type Setter<T> = (value: T) => T
10
+ /**
11
+ * Set new state value function.
12
+ */
13
+ export type SetValue<T> = T | Setter<T>
14
+ export type UpdateValue<T> = T extends object ? Partial<T> : T
15
+
16
+ /**
17
+ * Set new state function
18
+ */
19
+ export type StateValue<T, S> = undefined extends S ? T : S
20
+ export type Set<T> = (value: SetValue<T>) => void
21
+ export type Update<T> = (value: UpdateValue<T>) => void
22
+
23
+ /**
24
+ * Getting state value function.
25
+ */
26
+ export type GetState<T> = () => T
27
+ export interface StateDataInternal<T = unknown> {
28
+ value?: T
29
+ updateVersion: number
30
+ }
31
+
32
+ // eslint-disable-next-line no-shadow
33
+ export enum StateKeys {
34
+ IS_STATE = 'isState',
35
+ IS_SLICE = 'isSlice',
36
+ }
37
+
38
+ export interface BaseState<T> {
39
+ /**
40
+ * Reset state to default value if it's basic atom - if it's family - it will clear all family members
41
+ */
42
+ reset: () => void
43
+ /**
44
+ * Get current state value
45
+ */
46
+ getState: GetState<T>
47
+
48
+ select: <S>(selector: (value: T) => S, isEqual?: IsEqual<S>) => GetterState<S>
49
+ merge: <T2, S>(state2: GetterState<T2>, selector: (value1: T, value2: T2) => S, isEqual?: IsEqual<S>) => GetterState<S>
50
+
51
+ /**
52
+ * Internal state data
53
+ */
54
+ __internal: {
55
+ emitter: Emitter<T>
56
+ }
57
+
58
+ subscribe: (listener: (value: T) => void) => () => void
59
+ }
60
+
61
+ export interface GetterState<T> extends BaseState<T> {
62
+ // use use as the function call here
63
+ <S>(selector?: (state: T) => S, isEqual?: IsEqual<S>): StateValue<T, S>
64
+ }
65
+ export interface SetterState<T> extends GetterState<T> {
66
+ /**
67
+ * Set new state value
68
+ */
69
+ setState: Set<T>
70
+
71
+ /**
72
+ * Set new state value
73
+ */
74
+ updateState: Update<T>
75
+ }
76
+
77
+ export type State<T> = SetterState<T> | GetterState<T>
78
+
79
+ export type DefaultValue<T> = T | (() => T)
80
+
81
+ export function getDefaultValue<T>(initValue: DefaultValue<T>): T {
82
+ if (isPromise(initValue)) {
83
+ return initValue
84
+ }
85
+ if (isFunction(initValue)) {
86
+ return (initValue as () => T)()
87
+ }
88
+ return initValue
89
+ }
90
+
91
+ export interface Ref<T> {
92
+ current: T | undefined
93
+ readonly isRef: true
94
+ }
@@ -0,0 +1,29 @@
1
+ import type { IsEqual, State } from './types'
2
+ import { useSyncExternalStore, toType } from './common'
3
+ import { isPromise } from './is'
4
+
5
+ /**
6
+ * useCachedStateValue Hook.
7
+ * Hook for use state inside react scope. If the state is async - component need to be wrapped with Suspense.
8
+ * @param state - state value
9
+ * @param selector - selector function (useStateValue(state, (state) => state.value)) - it return only selected value, selector don't need to be memoized.
10
+ * @param isEqual - equality check function for selector
11
+ * @returns StateValue from selector if provided, otherwise whole state
12
+ */
13
+ export function useStateValue<T, S>(
14
+ state: State<T>,
15
+ selector: (stateValue: T) => S = (stateValue) => toType<S>(stateValue),
16
+ isEqual?: IsEqual<S>,
17
+ ): undefined extends S ? T : S {
18
+ const data = useSyncExternalStore(
19
+ state.__internal.emitter,
20
+ (stateValue) => {
21
+ return selector(stateValue)
22
+ },
23
+ isEqual,
24
+ )
25
+ if (isPromise(data)) {
26
+ throw data
27
+ }
28
+ return data
29
+ }
@@ -0,0 +1,7 @@
1
+ import type { Emitter } from './create-emitter';
2
+ import type { IsEqual } from './types';
3
+ /**
4
+ * Todo need to remove this
5
+ */
6
+ export declare function toType<T>(object?: unknown): T;
7
+ export declare function useSyncExternalStore<T, S>(emitter: Emitter<T>, selector: (stateValue: T) => S, isEqual?: IsEqual<S>): undefined extends S ? T : S;
@@ -0,0 +1,10 @@
1
+ import type { Emitter } from './create-emitter';
2
+ import type { BaseState, GetterState } from './types';
3
+ interface Options<T> {
4
+ readonly emitter: Emitter<T>;
5
+ readonly reset: () => void;
6
+ readonly getState: () => T;
7
+ readonly getGetterState: () => GetterState<T>;
8
+ }
9
+ export declare function createBaseState<T>(options: Options<T>): BaseState<T>;
10
+ export {};
@@ -0,0 +1,7 @@
1
+ export type EmitterSubscribe<P = undefined> = (listener: (...params: P[]) => void) => () => void;
2
+ export interface Emitter<T, R = T, P = undefined> {
3
+ subscribe: EmitterSubscribe<P>;
4
+ getSnapshot: () => R;
5
+ emit: (...params: P[]) => void;
6
+ }
7
+ export declare function createEmitter<T, R = T, P = undefined>(getSnapshot: () => R): Emitter<T, R, P>;
@@ -0,0 +1,6 @@
1
+ import type { BaseState, GetterState } from './types';
2
+ interface Options<T> {
3
+ readonly baseState: BaseState<T>;
4
+ }
5
+ export declare function createGetterState<T>(options: Options<T>): GetterState<T>;
6
+ export {};
@@ -0,0 +1,21 @@
1
+ import type { SetterState, DefaultValue, IsEqual } from './types';
2
+ /**
3
+ * Creates a basic atom state.
4
+ * @param defaultValue - The initial state value.
5
+ * @param options - Optional settings for the state (e.g., isEqual, onSet).
6
+ * @returns A state object that can be used as a hook and provides state management methods.
7
+ * @example
8
+ * ```typescript
9
+ * // Global scope
10
+ * const counterState = state(0);
11
+ * const userState = state({ name: 'John', age: 20 });
12
+ *
13
+ * // React component
14
+ * const counter = counterState(); // Use as a hook
15
+ * const user = userState();
16
+ *
17
+ * // Access partial data from the state using slice
18
+ * const userAge = userState.slice((state) => state.age)();
19
+ * ```
20
+ */
21
+ export declare function create<T>(defaultValue: DefaultValue<T>, isEqual?: IsEqual<T>): SetterState<Awaited<T>>;
@@ -0,0 +1,6 @@
1
+ export * from './types';
2
+ export { create } from './create';
3
+ export { select } from './select';
4
+ export { merge } from './merge';
5
+ export { useStateValue } from './use-state-value';
6
+ export { shallow } from './shallow';
package/types/is.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { Ref, Setter, SetValue } from './types';
2
+ export declare function isPromise(value: unknown): value is Promise<unknown>;
3
+ export declare function isFunction(value: unknown): value is (...args: unknown[]) => unknown;
4
+ export declare function isSetValueFunction<T>(value: SetValue<T>): value is Setter<T>;
5
+ export declare function isObject(value: unknown): value is Record<string, unknown>;
6
+ export declare function isRef<T>(value: unknown): value is Ref<T>;
7
+ export declare function isMap(value: unknown): value is Map<unknown, unknown>;
8
+ export declare function isSet(value: unknown): value is Set<unknown>;
9
+ export declare function isArray(value: unknown): value is Array<unknown>;
10
+ export declare function isEqualBase<T>(valueA: T, valueB: T): boolean;
@@ -0,0 +1,2 @@
1
+ import type { IsEqual, GetterState } from './types';
2
+ export declare function merge<T1, T2, S>(state1: GetterState<T1>, state2: GetterState<T2>, selector: (value1: T1, value2: T2) => S, isEqual?: IsEqual<S>): GetterState<S>;
@@ -0,0 +1,2 @@
1
+ import type { IsEqual, GetterState } from './types';
2
+ export declare function select<T, S>(state: GetterState<T>, selector: (value: T) => S, isEqual?: IsEqual<S>): GetterState<S>;
@@ -0,0 +1 @@
1
+ export declare function shallow<T>(valueA: T, valueB: T): boolean;
@@ -0,0 +1,68 @@
1
+ import type { Emitter } from './create-emitter';
2
+ /**
3
+ * Equality check function.
4
+ */
5
+ export type IsEqual<T = unknown> = (a: T, b: T) => boolean;
6
+ export type Setter<T> = (value: T) => T;
7
+ /**
8
+ * Set new state value function.
9
+ */
10
+ export type SetValue<T> = T | Setter<T>;
11
+ export type UpdateValue<T> = T extends object ? Partial<T> : T;
12
+ /**
13
+ * Set new state function
14
+ */
15
+ export type StateValue<T, S> = undefined extends S ? T : S;
16
+ export type Set<T> = (value: SetValue<T>) => void;
17
+ export type Update<T> = (value: UpdateValue<T>) => void;
18
+ /**
19
+ * Getting state value function.
20
+ */
21
+ export type GetState<T> = () => T;
22
+ export interface StateDataInternal<T = unknown> {
23
+ value?: T;
24
+ updateVersion: number;
25
+ }
26
+ export declare enum StateKeys {
27
+ IS_STATE = "isState",
28
+ IS_SLICE = "isSlice"
29
+ }
30
+ export interface BaseState<T> {
31
+ /**
32
+ * Reset state to default value if it's basic atom - if it's family - it will clear all family members
33
+ */
34
+ reset: () => void;
35
+ /**
36
+ * Get current state value
37
+ */
38
+ getState: GetState<T>;
39
+ select: <S>(selector: (value: T) => S, isEqual?: IsEqual<S>) => GetterState<S>;
40
+ merge: <T2, S>(state2: GetterState<T2>, selector: (value1: T, value2: T2) => S, isEqual?: IsEqual<S>) => GetterState<S>;
41
+ /**
42
+ * Internal state data
43
+ */
44
+ __internal: {
45
+ emitter: Emitter<T>;
46
+ };
47
+ subscribe: (listener: (value: T) => void) => () => void;
48
+ }
49
+ export interface GetterState<T> extends BaseState<T> {
50
+ <S>(selector?: (state: T) => S, isEqual?: IsEqual<S>): StateValue<T, S>;
51
+ }
52
+ export interface SetterState<T> extends GetterState<T> {
53
+ /**
54
+ * Set new state value
55
+ */
56
+ setState: Set<T>;
57
+ /**
58
+ * Set new state value
59
+ */
60
+ updateState: Update<T>;
61
+ }
62
+ export type State<T> = SetterState<T> | GetterState<T>;
63
+ export type DefaultValue<T> = T | (() => T);
64
+ export declare function getDefaultValue<T>(initValue: DefaultValue<T>): T;
65
+ export interface Ref<T> {
66
+ current: T | undefined;
67
+ readonly isRef: true;
68
+ }
@@ -0,0 +1,10 @@
1
+ import type { IsEqual, State } from './types';
2
+ /**
3
+ * useCachedStateValue Hook.
4
+ * Hook for use state inside react scope. If the state is async - component need to be wrapped with Suspense.
5
+ * @param state - state value
6
+ * @param selector - selector function (useStateValue(state, (state) => state.value)) - it return only selected value, selector don't need to be memoized.
7
+ * @param isEqual - equality check function for selector
8
+ * @returns StateValue from selector if provided, otherwise whole state
9
+ */
10
+ export declare function useStateValue<T, S>(state: State<T>, selector?: (stateValue: T) => S, isEqual?: IsEqual<S>): undefined extends S ? T : S;