Migrate to a monorepo structure (#2909)

This commit is contained in:
Charles Bochet
2023-12-10 18:10:54 +01:00
committed by GitHub
parent a70a9281eb
commit 5bdca9de6c
2304 changed files with 37152 additions and 25869 deletions

View File

@ -0,0 +1,156 @@
import {
ApolloCache,
DocumentNode,
OperationVariables,
useApolloClient,
} from '@apollo/client';
import { isNonEmptyArray } from '@sniptt/guards';
import { useRecoilCallback } from 'recoil';
import {
EMPTY_QUERY,
useObjectMetadataItem,
} from '@/object-metadata/hooks/useObjectMetadataItem';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier';
import { optimisticEffectState } from '../states/optimisticEffectState';
import { OptimisticEffect } from '../types/internal/OptimisticEffect';
import { OptimisticEffectDefinition } from '../types/OptimisticEffectDefinition';
export const useOptimisticEffect = ({
objectNameSingular,
}: ObjectMetadataItemIdentifier) => {
const apolloClient = useApolloClient();
const { findManyRecordsQuery } = useObjectMetadataItem({
objectNameSingular,
});
const registerOptimisticEffect = useRecoilCallback(
({ snapshot, set }) =>
<T>({
variables,
definition,
}: {
variables: OperationVariables;
definition: OptimisticEffectDefinition;
}) => {
if (findManyRecordsQuery === EMPTY_QUERY) {
throw new Error(
`Trying to register an optimistic effect for unknown object ${objectNameSingular}`,
);
}
const optimisticEffects = snapshot
.getLoadable(optimisticEffectState)
.getValue();
const optimisticEffectWriter = ({
cache,
newData,
deletedRecordIds,
query,
variables,
objectMetadataItem,
}: {
cache: ApolloCache<unknown>;
newData: unknown;
deletedRecordIds?: string[];
variables: OperationVariables;
query: DocumentNode;
isUsingFlexibleBackend?: boolean;
objectMetadataItem?: ObjectMetadataItem;
}) => {
if (objectMetadataItem) {
const existingData = cache.readQuery({
query: findManyRecordsQuery,
variables,
});
if (!existingData) {
return;
}
cache.writeQuery({
query: findManyRecordsQuery,
variables,
data: {
[objectMetadataItem.namePlural]: definition.resolver({
currentData: (existingData as any)?.[
objectMetadataItem.namePlural
],
newData,
deletedRecordIds,
variables,
}),
},
});
return;
}
const existingData = cache.readQuery({
query,
variables,
});
if (!existingData) {
return;
}
};
const optimisticEffect = {
key: definition.key,
variables,
typename: definition.typename,
query: definition.query,
writer: optimisticEffectWriter,
objectMetadataItem: definition.objectMetadataItem,
isUsingFlexibleBackend: definition.isUsingFlexibleBackend,
} satisfies OptimisticEffect<T>;
set(optimisticEffectState, {
...optimisticEffects,
[definition.key]: optimisticEffect,
});
},
);
const triggerOptimisticEffects = useRecoilCallback(
({ snapshot }) =>
(typename: string, newData: unknown, deletedRecordIds?: string[]) => {
const optimisticEffects = snapshot
.getLoadable(optimisticEffectState)
.getValue();
for (const optimisticEffect of Object.values(optimisticEffects)) {
// We need to update the typename when createObject type differs from listObject types
// It is the case for apiKey, where the creation route returns an ApiKeyToken type
const formattedNewData = isNonEmptyArray(newData)
? newData.map((data: any) => {
return { ...data, __typename: typename };
})
: newData;
if (optimisticEffect.typename === typename) {
optimisticEffect.writer({
cache: apolloClient.cache,
query: optimisticEffect.query ?? ({} as DocumentNode),
newData: formattedNewData,
deletedRecordIds,
variables: optimisticEffect.variables,
isUsingFlexibleBackend: optimisticEffect.isUsingFlexibleBackend,
objectMetadataItem: optimisticEffect.objectMetadataItem,
});
}
}
},
[apolloClient.cache],
);
return {
registerOptimisticEffect,
triggerOptimisticEffects,
};
};

View File

@ -0,0 +1,24 @@
import { useApolloClient } from '@apollo/client';
export const useOptimisticEvict = () => {
const cache = useApolloClient().cache;
const performOptimisticEvict = (
typename: string,
fieldName: string,
fieldValue: string,
) => {
const serializedCache = cache.extract();
Object.values(serializedCache)
.filter((item) => item.__typename === typename)
.forEach((item) => {
if (item[fieldName] === fieldValue) {
cache.evict({ id: cache.identify(item) });
}
});
};
return {
performOptimisticEvict,
};
};

View File

@ -0,0 +1,10 @@
import { atom } from 'recoil';
import { OptimisticEffect } from '../types/internal/OptimisticEffect';
export const optimisticEffectState = atom<
Record<string, OptimisticEffect<unknown>>
>({
key: 'optimisticEffectState',
default: {},
});

View File

@ -0,0 +1,14 @@
import { DocumentNode } from 'graphql';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { OptimisticEffectResolver } from './OptimisticEffectResolver';
export type OptimisticEffectDefinition = {
key: string;
query?: DocumentNode;
typename: string;
resolver: OptimisticEffectResolver;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
};

View File

@ -0,0 +1,13 @@
import { OperationVariables } from '@apollo/client';
export type OptimisticEffectResolver = ({
currentData,
newData,
deletedRecordIds,
variables,
}: {
currentData: any; //TODO: Change when decommissioning v1
newData: any; //TODO: Change when decommissioning v1
deletedRecordIds?: string[];
variables: OperationVariables;
}) => void;

View File

@ -0,0 +1,28 @@
import { ApolloCache, DocumentNode, OperationVariables } from '@apollo/client';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
type OptimisticEffectWriter<T> = ({
cache,
newData,
variables,
query,
}: {
cache: ApolloCache<T>;
query: DocumentNode;
newData: T;
deletedRecordIds?: string[];
variables: OperationVariables;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
}) => void;
export type OptimisticEffect<T> = {
key: string;
query?: DocumentNode;
typename: string;
variables: OperationVariables;
writer: OptimisticEffectWriter<T>;
objectMetadataItem?: ObjectMetadataItem;
isUsingFlexibleBackend?: boolean;
};