Migrate to a monorepo structure (#2909)
This commit is contained in:
@ -0,0 +1,33 @@
|
||||
import { useRef } from 'react';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { RecoilScopeContext as RecoilScopeContextType } from '@/types/RecoilScopeContext';
|
||||
|
||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated Use a custom scope context instead, see example with DropdownScope
|
||||
*/
|
||||
export const RecoilScope = ({
|
||||
children,
|
||||
scopeId,
|
||||
CustomRecoilScopeContext,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
scopeId?: string;
|
||||
CustomRecoilScopeContext?: RecoilScopeContextType;
|
||||
}) => {
|
||||
// eslint-disable-next-line twenty/no-state-useref
|
||||
const currentScopeId = useRef(scopeId ?? v4());
|
||||
|
||||
return CustomRecoilScopeContext ? (
|
||||
<CustomRecoilScopeContext.Provider value={currentScopeId.current}>
|
||||
{children}
|
||||
</CustomRecoilScopeContext.Provider>
|
||||
) : (
|
||||
<RecoilScopeContext.Provider value={currentScopeId.current}>
|
||||
{children}
|
||||
</RecoilScopeContext.Provider>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
import { Context, useContext } from 'react';
|
||||
|
||||
/**
|
||||
* @deprecated use a custom scope instead and desctructure the scope id from the scope context
|
||||
* Get the scope context with useScopeInternalContext
|
||||
*/
|
||||
export const useContextScopeId = (SpecificContext: Context<string | null>) => {
|
||||
const recoilScopeId = useContext(SpecificContext);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using useContextScopedId outside of the specified context : ${SpecificContext.displayName}, verify that you are using a RecoilScope with the specific context you want to use.`,
|
||||
);
|
||||
|
||||
return recoilScopeId;
|
||||
};
|
||||
@ -0,0 +1,17 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { RecoilScopeContext } from '@/types/RecoilScopeContext';
|
||||
|
||||
/**
|
||||
* @deprecated Use a custom scope instead and desctructure the scope id from the scope context
|
||||
*/
|
||||
export const useRecoilScopeId = (RecoilScopeContext: RecoilScopeContext) => {
|
||||
const recoilScopeId = useContext(RecoilScopeContext);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using useRecoilScopeId outside of the specified context : ${RecoilScopeContext.displayName}, verify that you are using a RecoilScope with the specific context you want to use.`,
|
||||
);
|
||||
|
||||
return recoilScopeId;
|
||||
};
|
||||
@ -0,0 +1,27 @@
|
||||
import { RecoilState, SerializableParam, useRecoilState } from 'recoil';
|
||||
|
||||
import { ScopedFamilyStateKey } from '../scopes-internal/types/ScopedFamilyStateKey';
|
||||
|
||||
export const useRecoilScopedFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
recoilState: (
|
||||
scopedFamilyKey: ScopedFamilyStateKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
familyKey?: FamilyKey,
|
||||
) => {
|
||||
const familyState = useRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
}),
|
||||
);
|
||||
|
||||
if (!familyKey) {
|
||||
return [undefined, undefined];
|
||||
}
|
||||
|
||||
return familyState;
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
import { Context, useContext } from 'react';
|
||||
import { RecoilState, useRecoilState } from 'recoil';
|
||||
|
||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||
|
||||
export const useRecoilScopedState = <StateType>(
|
||||
recoilState: (param: string) => RecoilState<StateType>,
|
||||
CustomRecoilScopeContext?: Context<string | null>,
|
||||
) => {
|
||||
const recoilScopeId = useContext(
|
||||
CustomRecoilScopeContext ?? RecoilScopeContext,
|
||||
);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using a scoped atom without a RecoilScope : ${
|
||||
recoilState('').key
|
||||
}, verify that you are using a RecoilScope with a specific context if you intended to do so.`,
|
||||
);
|
||||
|
||||
return useRecoilState<StateType>(recoilState(recoilScopeId));
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { RecoilState, useRecoilState } from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
export const useRecoilScopedStateV2 = <StateType>(
|
||||
recoilState: (scopedKey: ScopedStateKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,25 @@
|
||||
import { Context, useContext } from 'react';
|
||||
import { RecoilState, RecoilValueReadOnly, useRecoilValue } from 'recoil';
|
||||
|
||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||
|
||||
/**
|
||||
* @deprecated use useRecoilScopedStateV2 instead
|
||||
*/
|
||||
export const useRecoilScopedValue = <T>(
|
||||
recoilState: (param: string) => RecoilState<T> | RecoilValueReadOnly<T>,
|
||||
CustomRecoilScopeContext?: Context<string | null>,
|
||||
) => {
|
||||
const recoilScopeId = useContext(
|
||||
CustomRecoilScopeContext ?? RecoilScopeContext,
|
||||
);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using a scoped atom without a RecoilScope : ${
|
||||
recoilState('').key
|
||||
}, verify that you are using a RecoilScope with a specific context if you intended to do so.`,
|
||||
);
|
||||
|
||||
return useRecoilValue<T>(recoilState(recoilScopeId));
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { RecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
export const useRecoilScopedValueV2 = <StateType>(
|
||||
recoilState: (scopedKey: ScopedStateKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useRecoilValue<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,27 @@
|
||||
import { RecoilState, SerializableParam, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { ScopedFamilyStateKey } from '../scopes-internal/types/ScopedFamilyStateKey';
|
||||
|
||||
export const useSetRecoilScopedFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
recoilState: (
|
||||
scopedFamilyKey: ScopedFamilyStateKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
familyKey?: FamilyKey,
|
||||
) => {
|
||||
const familyState = useSetRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
}),
|
||||
);
|
||||
|
||||
if (!familyKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
return familyState;
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { RecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
export const useSetRecoilScopedStateV2 = <StateType>(
|
||||
recoilState: (scopedKey: ScopedStateKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useSetRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,20 @@
|
||||
import { ScopeInternalContext } from '../types/ScopeInternalContext';
|
||||
|
||||
import { useScopeInternalContext } from './useScopeInternalContext';
|
||||
|
||||
export const useAvailableScopeIdOrThrow = <T extends { scopeId: string }>(
|
||||
Context: ScopeInternalContext<T>,
|
||||
scopeIdFromProps?: string,
|
||||
): string => {
|
||||
const scopeInternalContext = useScopeInternalContext(Context);
|
||||
|
||||
const scopeIdFromContext = scopeInternalContext?.scopeId;
|
||||
|
||||
if (scopeIdFromProps) {
|
||||
return scopeIdFromProps;
|
||||
} else if (scopeIdFromContext) {
|
||||
return scopeIdFromContext;
|
||||
} else {
|
||||
throw new Error('Scope id is not provided and cannot be found in context.');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { ScopeInternalContext } from '../types/ScopeInternalContext';
|
||||
|
||||
export const useScopeInternalContext = <T extends { scopeId: string }>(
|
||||
Context: ScopeInternalContext<T>,
|
||||
) => {
|
||||
const context = useContext(Context);
|
||||
|
||||
return context;
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
import { ScopeInternalContext } from '../types/ScopeInternalContext';
|
||||
|
||||
export const useScopeInternalContextOrThrow = <T extends { scopeId: string }>(
|
||||
Context: ScopeInternalContext<T>,
|
||||
) => {
|
||||
const context = useContext(Context);
|
||||
|
||||
if (!isDefined(context)) {
|
||||
throw new Error(
|
||||
`Using a scope context without a ScopeInternalContext.Provider wrapper for context : ${Context.displayName}.`,
|
||||
);
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@ -0,0 +1,4 @@
|
||||
import { Context } from 'react';
|
||||
|
||||
export type ScopeInternalContext<T extends { scopeId: string }> =
|
||||
Context<T | null>;
|
||||
@ -0,0 +1,6 @@
|
||||
import { SerializableParam } from 'recoil';
|
||||
|
||||
export type ScopedFamilyStateKey<FamilyKey extends SerializableParam> = {
|
||||
scopeId: string;
|
||||
familyKey: FamilyKey;
|
||||
};
|
||||
@ -0,0 +1,3 @@
|
||||
export type ScopedStateKey = {
|
||||
scopeId: string;
|
||||
};
|
||||
@ -0,0 +1,13 @@
|
||||
import { Context, createContext } from 'react';
|
||||
|
||||
import { ScopedStateKey } from '../types/ScopedStateKey';
|
||||
|
||||
type ScopeInternalContext<T extends ScopedStateKey> = Context<T | null>;
|
||||
|
||||
export const createScopeInternalContext = <T extends ScopedStateKey>(
|
||||
initialValue?: T,
|
||||
) => {
|
||||
return createContext<T | null>(
|
||||
initialValue ?? null,
|
||||
) as ScopeInternalContext<T>;
|
||||
};
|
||||
@ -0,0 +1,3 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export const RecoilScopeContext = createContext<string | null>(null);
|
||||
@ -0,0 +1,7 @@
|
||||
import { RecoilValueReadOnly } from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
export type RecoilScopedSelector<StateType> = (
|
||||
scopedKey: ScopedStateKey,
|
||||
) => RecoilValueReadOnly<StateType>;
|
||||
@ -0,0 +1,7 @@
|
||||
import { RecoilState } from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
export type RecoilScopedState<StateType> = (
|
||||
scopedKey: ScopedStateKey,
|
||||
) => RecoilState<StateType>;
|
||||
@ -0,0 +1,19 @@
|
||||
import { atomFamily, SerializableParam } from 'recoil';
|
||||
|
||||
import { ScopedFamilyStateKey } from '../scopes-internal/types/ScopedFamilyStateKey';
|
||||
|
||||
export const createScopedFamilyState = <
|
||||
ValueType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>({
|
||||
key,
|
||||
defaultValue,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
}) => {
|
||||
return atomFamily<ValueType, ScopedFamilyStateKey<FamilyKey>>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,30 @@
|
||||
import {
|
||||
GetCallback,
|
||||
GetRecoilValue,
|
||||
Loadable,
|
||||
RecoilValue,
|
||||
selectorFamily,
|
||||
WrappedValue,
|
||||
} from 'recoil';
|
||||
|
||||
import { ScopedStateKey } from '../scopes-internal/types/ScopedStateKey';
|
||||
|
||||
type SelectorGetter<T, P> = (
|
||||
param: P,
|
||||
) => (opts: {
|
||||
get: GetRecoilValue;
|
||||
getCallback: GetCallback;
|
||||
}) => Promise<T> | RecoilValue<T> | Loadable<T> | WrappedValue<T> | T;
|
||||
|
||||
export const createScopedSelector = <ValueType>({
|
||||
key,
|
||||
get,
|
||||
}: {
|
||||
key: string;
|
||||
get: SelectorGetter<ValueType, ScopedStateKey>;
|
||||
}) => {
|
||||
return selectorFamily<ValueType, ScopedStateKey>({
|
||||
key,
|
||||
get,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
export const createScopedState = <ValueType>({
|
||||
key,
|
||||
defaultValue,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
}) => {
|
||||
return atomFamily<ValueType, { scopeId: string }>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { RecoilState, SerializableParam } from 'recoil';
|
||||
|
||||
import { ScopedFamilyStateKey } from '../scopes-internal/types/ScopedFamilyStateKey';
|
||||
|
||||
export const getScopedFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
recoilState: (
|
||||
scopedFamilyKey: ScopedFamilyStateKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
familyKey: FamilyKey,
|
||||
) => {
|
||||
return recoilState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,10 @@
|
||||
import { RecoilScopedSelector } from '../types/RecoilScopedSelector';
|
||||
|
||||
export const getScopedSelector = <StateType>(
|
||||
recoilScopedState: RecoilScopedSelector<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return recoilScopedState({
|
||||
scopeId,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,10 @@
|
||||
import { RecoilScopedState } from '../types/RecoilScopedState';
|
||||
|
||||
export const getScopedState = <StateType>(
|
||||
recoilScopedState: RecoilScopedState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return recoilScopedState({
|
||||
scopeId,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
import { Snapshot } from 'recoil';
|
||||
|
||||
import { RecoilScopedSelector } from '../types/RecoilScopedSelector';
|
||||
|
||||
import { getScopedSelector } from './getScopedSelector';
|
||||
|
||||
export const getSnapshotScopedSelector = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
scopedState: RecoilScopedSelector<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return snapshot
|
||||
.getLoadable(getScopedSelector(scopedState, scopeId))
|
||||
.getValue();
|
||||
};
|
||||
@ -0,0 +1,13 @@
|
||||
import { Snapshot } from 'recoil';
|
||||
|
||||
import { RecoilScopedState } from '../types/RecoilScopedState';
|
||||
|
||||
import { getScopedState } from './getScopedState';
|
||||
|
||||
export const getSnapshotScopedValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
scopedState: RecoilScopedState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return snapshot.getLoadable(getScopedState(scopedState, scopeId)).getValue();
|
||||
};
|
||||
@ -0,0 +1,8 @@
|
||||
import { RecoilState, RecoilValueReadOnly, Snapshot } from 'recoil';
|
||||
|
||||
export const getSnapshotValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
state: RecoilState<StateType> | RecoilValueReadOnly<StateType>,
|
||||
) => {
|
||||
return snapshot.getLoadable(state).getValue();
|
||||
};
|
||||
Reference in New Issue
Block a user