Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support number type for id in entity store #1600

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions packages/@o3r/core/src/store/async/async-entity.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,31 @@ export interface EntityAsyncRequestAdapter<T extends AsyncStoreItem> extends Ent
* @param ids Ids of the entity to be updated with AsyncStoreItem properties
* @param requestId Id of request which has failed
*/
failRequestMany<V extends EntityState<T> & AsyncStoreItem>(state: V, ids?: string[], requestId?: string): V;
failRequestMany<V extends EntityState<T> & AsyncStoreItem>(state: V, ids?: string[] | number[], requestId?: string): V;

/**
* Adds AsyncStoreItem property to the global store, or the entity if it already exists, when a request is triggered.
* @param state Actual state
* @param id Id of the entity to update
* @param requestId Id of the request which is triggered
*/
addRequestOne<V extends EntityState<T> & AsyncStoreItem>(state: V, id: string | null | undefined, requestId: string): V;
addRequestOne<V extends EntityState<T> & AsyncStoreItem>(state: V, id: string | number | null | undefined, requestId: string): V;

/**
* Adds AsyncStoreItem properties for each entity matching the given ids, when a request is triggered
* @param state Actual state
* @param ids Ids of the entity to be updated with AsyncStoreItem properties
* @param requestId Id of request which is triggered
*/
addRequestMany<V extends EntityState<T>>(state: V, ids: string[], requestId: string): V;
addRequestMany<V extends EntityState<T>>(state: V, ids: string[] | number[], requestId: string): V;

/**
* Updates the state with the given entity. Update the global or the current entity's status if it exists.
* @param state Actual state
* @param entity Payload item;
* @param requestId Id of request which has resolved if any
*/
resolveRequestOne<V extends EntityState<T> & AsyncStoreItem>(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<'id', string>, requestId?: string): V;
resolveRequestOne<V extends EntityState<T> & AsyncStoreItem>(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<'id', string | number>, requestId?: string): V;

/**
* Updates the state with the given entity. Update the global or the current entity's status if it exists.
Expand All @@ -44,15 +44,15 @@ export interface EntityAsyncRequestAdapter<T extends AsyncStoreItem> extends Ent
* @param requestId Id of request which has resolved if any
* @param idProperty Property of the entity containing its unique identifier
*/
resolveRequestOne<V extends EntityState<T> & AsyncStoreItem, W extends keyof T>(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string>, requestId?: string, idProperty?: W): V;
resolveRequestOne<V extends EntityState<T> & AsyncStoreItem, W extends keyof T>(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string | number>, requestId?: string, idProperty?: W): V;

/**
* Updates the state with the given entities. Updates also AsyncStoreItem properties of each entity, when a request is resolved.
* @param state Actual state
* @param entities Payload items;
* @param requestId Id of request which has resolved if any
*/
resolveRequestMany<V extends EntityState<T>>(state: V, entities: (Partial<T> & Record<'id', string>)[], requestId?: string): V;
resolveRequestMany<V extends EntityState<T>>(state: V, entities: (Partial<T> & Record<'id', string | number>)[], requestId?: string): V;

/**
* Updates the state with the given entities. Updates also AsyncStoreItem properties of each entity, when a request is resolved.
Expand All @@ -61,7 +61,7 @@ export interface EntityAsyncRequestAdapter<T extends AsyncStoreItem> extends Ent
* @param requestId Id of request which has resolved if any
* @param idProperty Property of the entity containing its unique identifier
*/
resolveRequestMany<V extends EntityState<T>, W extends keyof T>(state: V, entities: (Partial<T> & Record<W, string>)[], requestId?: string, idProperty?: W): V;
resolveRequestMany<V extends EntityState<T>, W extends keyof T>(state: V, entities: (Partial<T> & Record<W, string | number>)[], requestId?: string, idProperty?: W): V;
}

/**
Expand All @@ -70,7 +70,7 @@ export interface EntityAsyncRequestAdapter<T extends AsyncStoreItem> extends Ent
*/
export function createEntityAsyncRequestAdapter<T extends AsyncStoreItem>(adapter: EntityAdapter<T>): EntityAsyncRequestAdapter<T> {

const addRequestOne: <V extends EntityState<T> & AsyncStoreItem>(state: V, id: string | null | undefined, requestId: string) => V = (state, id, requestId) => {
const addRequestOne: <V extends EntityState<T> & AsyncStoreItem>(state: V, id: string | number | null | undefined, requestId: string) => V = (state, id, requestId) => {
const currentEntity = typeof id !== 'undefined' && id !== null && state.entities[id];
if (currentEntity) {
const changes = asyncStoreItemAdapter.addRequest(asyncStoreItemAdapter.extractAsyncStoreItem(currentEntity), requestId);
Expand All @@ -88,8 +88,9 @@ export function createEntityAsyncRequestAdapter<T extends AsyncStoreItem>(adapte
), state);

const resolveRequestOne: <V extends EntityState<T> & AsyncStoreItem, W extends keyof T | 'id' = 'id'>
(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string>, requestId?: string, idProperty?: W) => V =
<V extends EntityState<T> & AsyncStoreItem, W extends keyof T | 'id'>(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string>, requestId?: string, idProperty: W = 'id' as W): V => {
(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string | number>, requestId?: string, idProperty?: W) => V =
<V extends EntityState<T> & AsyncStoreItem, W extends keyof T | 'id'>
(state: V, entity: EntityWithoutAsyncStoreItem<T> & Record<W, string | number>, requestId?: string, idProperty: W = 'id' as W): V => {
let newEntity;
const currentEntity = state.entities[entity[idProperty]];
if (currentEntity) {
Expand All @@ -101,16 +102,19 @@ export function createEntityAsyncRequestAdapter<T extends AsyncStoreItem>(adapte
return adapter.upsertOne(newEntity as T, state);
};

const resolveRequestMany: <V extends EntityState<T>, W extends keyof T | 'id' = 'id'>(state: V, entities: (Partial<T> & Record<W, string>)[], requestId?: string, idProperty?: W) => V =
<V extends EntityState<T>, W extends keyof T | 'id'>(state: V, entities: (Partial<T> & Record<W, string>)[], requestId?: string, idProperty: W = 'id' as W): V =>
adapter.updateMany(entities.filter((entity) => !!state.entities[entity[idProperty]]).map((entity) => {
const model = {...entity, ...asyncStoreItemAdapter.extractAsyncStoreItem(state.entities[entity[idProperty]]!)};
return {id: entity[idProperty], changes: asyncStoreItemAdapter.resolveRequest(model, requestId)};
}
), state);
const resolveRequestMany: <V extends EntityState<T>, W extends keyof T | 'id' = 'id'>
(state: V, entities: (Partial<T> & Record<W, string | number>)[], requestId?: string, idProperty?: W) => V =
<V extends EntityState<T>, W extends keyof T | 'id'>
(state: V, entities: (Partial<T> & Record<W, string | number>)[], requestId?: string, idProperty: W = 'id' as W): V =>
adapter.updateMany(
entities.filter((entity) => !!state.entities[entity[idProperty]]).map((entity) => {
const model = {...entity, ...asyncStoreItemAdapter.extractAsyncStoreItem(state.entities[entity[idProperty]]!)};
return {id: entity[idProperty], changes: asyncStoreItemAdapter.resolveRequest(model, requestId)} as Update<T>;
}
), state);

const failRequestMany: <V extends EntityState<T> & AsyncStoreItem>(state: V, ids?: string[], requestId?: string) => V =
<V extends EntityState<T> & AsyncStoreItem>(state: V, ids: string[] = [], requestId?: string): V => {
const failRequestMany: <V extends EntityState<T> & AsyncStoreItem>(state: V, ids?: string[] | number[], requestId?: string) => V =
<V extends EntityState<T> & AsyncStoreItem>(state: V, ids: string[] | number[] = [], requestId?: string): V => {
if (ids.length && !ids.some((id) => state.entities[id] === undefined)) {
return adapter.updateMany(ids.map((id) => ({
id,
Expand Down
4 changes: 2 additions & 2 deletions packages/@o3r/core/src/store/async/async.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ export interface SetAsyncStoreItemActionPayload<T> extends SetActionPayload<T>,
export interface UpdateAsyncStoreItemEntitiesActionPayload<T extends object, K extends keyof T> extends UpdateEntitiesActionPayload<T, K>, Partial<AsyncRequest> {}

/** Payload to update entities actions from async with a field ID */
export interface UpdateAsyncStoreItemEntitiesActionPayloadWithId<T extends {id: string}> extends UpdateEntitiesActionPayloadWithId<T>, Partial<AsyncRequest> {}
export interface UpdateAsyncStoreItemEntitiesActionPayloadWithId<T extends {id: string | number}> extends UpdateEntitiesActionPayloadWithId<T>, Partial<AsyncRequest> {}

/** Payload to update entity actions from async */
// eslint-disable-next-line @typescript-eslint/ban-types
export interface UpdateAsyncStoreItemEntityActionPayload<T extends object, K extends keyof T> extends UpdateEntityActionPayload<T, K>, Partial<AsyncRequest> {}

/** Payload to update entity actions from async with a field ID */
export interface UpdateAsyncStoreItemEntityActionPayloadWithId<T extends {id: string}> extends UpdateEntityActionPayloadWithId<T>, Partial<AsyncRequest> {}
export interface UpdateAsyncStoreItemEntityActionPayloadWithId<T extends {id: string | number}> extends UpdateEntityActionPayloadWithId<T>, Partial<AsyncRequest> {}

/** Payload to set/upsert entities actions from async */
// eslint-disable-next-line @typescript-eslint/ban-types
Expand Down
10 changes: 5 additions & 5 deletions packages/@o3r/core/src/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export interface LocalStateModel {
}

/**
* Adds a string `id` to the given type
* Adds an `id` to the given type
*/
export type Idfy<T> = T & {id: string};
export type Idfy<T> = T & {id: string | number};

/**
* Payload to update actions
Expand Down Expand Up @@ -75,7 +75,7 @@ export interface UpdateEntitiesActionPayload<T, K extends keyof T> {
}

/** Payload to update entities actions with a field ID */
export interface UpdateEntitiesActionPayloadWithId<T extends {id: string}> {
export interface UpdateEntitiesActionPayloadWithId<T extends {id: string | number}> {
entities: keep<T, 'id'>[];
}

Expand All @@ -85,7 +85,7 @@ export interface UpdateEntityActionPayload<T, K extends keyof T> {
}

/** Payload to update entities actions with a field ID */
export interface UpdateEntityActionPayloadWithId<T extends {id: string}> {
export interface UpdateEntityActionPayloadWithId<T extends {id: string | number}> {
entity: keep<T, 'id'>;
}

Expand All @@ -101,7 +101,7 @@ export interface SetEntityActionPayload<T> {

/** Payload to fail entities actions */
export interface FailEntitiesActionPayload<T> extends FailActionPayload<T> {
ids?: string[];
ids?: string[] | number[];
}

/**
Expand Down
Loading