Skip to content

Commit

Permalink
feat(search): create injection tokens with factory (#3259)
Browse files Browse the repository at this point in the history
  • Loading branch information
griest024 authored Oct 14, 2024
1 parent 91cf3e9 commit 2fbd482
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 215 deletions.
18 changes: 12 additions & 6 deletions libs/search/driver/federated/src/config/interface.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { InjectionToken } from '@angular/core';
import { createConfigInjectionToken } from '@daffodil/core';

import { SEARCH_FEDERATED_CONFIG_DEFAULT } from './default';

/**
* The token used to provide @daffodil/search/driver/federated config data.
* Mandatory for the Magento driver.
*/
export const SEARCH_FEDERATED_CONFIG_TOKEN = new InjectionToken<DaffSearchFederatedDriverConfig>('SEARCH_FEDERATED_CONFIG_TOKEN', { factory: () => SEARCH_FEDERATED_CONFIG_DEFAULT });
export const {
/**
* The token used to provide @daffodil/search/driver/federated config data.
* Mandatory for the Magento driver.
*/
token: SEARCH_FEDERATED_CONFIG_TOKEN,
provider: daffProvideAnalyticsConfig,
} = createConfigInjectionToken<DaffSearchFederatedDriverConfig>(
SEARCH_FEDERATED_CONFIG_DEFAULT,
'SEARCH_FEDERATED_CONFIG_TOKEN',
);

/**
* An interface for providing @daffodil/search/driver/federated with necessary config values.
Expand Down
54 changes: 21 additions & 33 deletions libs/search/driver/federated/src/injection-tokens/drivers.token.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,25 @@
import {
InjectionToken,
Provider,
Type,
} from '@angular/core';

import { createServicesInjectionToken } from '@daffodil/core';
import { DaffSearchResult } from '@daffodil/search';
import { DaffSearchDriverKindedInterface } from '@daffodil/search/driver';

/**
* A multi-provider injection token for providing feature-specific search platform drivers.
* This allows disparate modules to contribute to the business logic of performing searches while
* preventing tight coupling of said modules.
*/
export const DAFF_SEARCH_FEDERATED_DRIVERS = new InjectionToken<DaffSearchDriverKindedInterface[]>(
'DAFF_SEARCH_FEDERATED_DRIVERS',
{ factory: () => []},
);
export const {
/**
* A multi-provider injection token for providing feature-specific search platform drivers.
* This allows disparate modules to contribute to the business logic of performing searches while
* preventing tight coupling of said modules.
*/
token: DAFF_SEARCH_FEDERATED_DRIVERS,

/**
* Provides feature drivers for the federated search driver.
*
* See {@link DAFF_SEARCH_FEDERATED_DRIVERS}.
*
* ```ts
* providers: [
* ...daffProvideSearchFederatedDrivers(MySearchDriver)
* ]
* ```
*/
export function daffProvideSearchFederatedDrivers(...drivers: Type<DaffSearchDriverKindedInterface>[]): Provider[] {
return drivers.map(driver => ({
provide: DAFF_SEARCH_FEDERATED_DRIVERS,
useExisting: driver,
multi: true,
}));
}
/**
* Provides feature drivers for the federated search driver.
*
* See {@link DAFF_SEARCH_FEDERATED_DRIVERS}.
*
* ```ts
* providers: [
* ...daffProvideSearchFederatedDrivers(MySearchDriver)
* ]
* ```
*/
provider: daffProvideSearchFederatedDrivers,
} = createServicesInjectionToken<DaffSearchDriverKindedInterface>('DAFF_SEARCH_FEDERATED_DRIVERS');
2 changes: 1 addition & 1 deletion libs/search/driver/federated/src/search.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('@daffodil/search/driver/federated | DaffSearchFederatedDriver', () =>
TestBed.configureTestingModule({
providers: [
DaffSearchFederatedDriver,
...daffProvideSearchFederatedDrivers(TestDriver1, TestDriver2),
...daffProvideSearchFederatedDrivers<TestDriver1 | TestDriver2>(TestDriver1, TestDriver2),
],
});

Expand Down
53 changes: 21 additions & 32 deletions libs/search/driver/in-memory/src/injection-tokens/backends.token.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
import {
InjectionToken,
Provider,
Type,
} from '@angular/core';
import { createServicesInjectionToken } from '@daffodil/core';

import { DaffSearchInMemoryChildBackend } from '../interfaces/public_api';

/**
* A multi-provider injection token for providing feature-specific search in-memory backends.
* Feature/search "join" packages should provide a backend here to interface
* with their feature backend for realistic search behavior.
*/
export const DAFF_SEARCH_IN_MEMORY_BACKENDS = new InjectionToken<DaffSearchInMemoryChildBackend[]>(
'DAFF_SEARCH_IN_MEMORY_BACKENDS',
{ factory: () => []},
);
export const {
/**
* A multi-provider injection token for providing feature-specific search in-memory backends.
* Feature/search "join" packages should provide a backend here to interface
* with their feature backend for realistic search behavior.
*/
token: DAFF_SEARCH_IN_MEMORY_BACKENDS,

/**
* Provides child feature backends for the search in-memory backend.
*
* See {@link DAFF_SEARCH_IN_MEMORY_BACKENDS}.
*
* ```ts
* providers: [
* ...daffProvideSearchInMemoryBackends(MySearchFeatureBackend)
* ]
* ```
*/
export function daffProvideSearchInMemoryBackends(...drivers: Type<DaffSearchInMemoryChildBackend>[]): Provider[] {
return drivers.map(driver => ({
provide: DAFF_SEARCH_IN_MEMORY_BACKENDS,
useExisting: driver,
multi: true,
}));
}
/**
* Provides child feature backends for the search in-memory backend.
*
* See {@link DAFF_SEARCH_IN_MEMORY_BACKENDS}.
*
* ```ts
* providers: [
* ...daffProvideSearchInMemoryBackends(MySearchFeatureBackend)
* ]
* ```
*/
provider: daffProvideSearchInMemoryBackends,
} = createServicesInjectionToken<DaffSearchInMemoryChildBackend>('DAFF_SEARCH_IN_MEMORY_BACKENDS');
13 changes: 8 additions & 5 deletions libs/search/driver/src/interfaces/search-service.interface.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { InjectionToken } from '@angular/core';
import { Observable } from 'rxjs';

import { createSingleInjectionToken } from '@daffodil/core';
import {
DaffSearchResult,
DaffSearchResultCollection,
} from '@daffodil/search';

import type { DaffSearchDriverResponse } from './response.interface';

/**
* An injection token for the search driver.
*/
export const DaffSearchDriver = new InjectionToken<DaffSearchDriverInterface>('DaffSearchDriver');
export const {
/**
* An injection token for the search driver.
*/
token: DaffSearchDriver,
provider: daffProvideSearchDriver,
} = createSingleInjectionToken<DaffSearchDriverInterface>('DaffSearchDriver');

/**
* The options for making a search.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { InjectionToken } from '@angular/core';
import { createSingleInjectionToken } from '@daffodil/core';

import { DaffSearchRoutingOptionBuilder } from './builders.token';

/**
* An internal token to combine the {@link DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS} into a single builder.
*/
export const DAFF_SEARCH_ROUTING_OPTIONS_BUILDER = new InjectionToken<DaffSearchRoutingOptionBuilder>(
'DAFF_SEARCH_ROUTING_OPTIONS_BUILDER',
);
export const {
/**
* An internal token to combine the {@link DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS} into a single builder.
*/
token: DAFF_SEARCH_ROUTING_OPTIONS_BUILDER,
provider: daffProvideSearchRoutingOptionsBuilder,
} = createSingleInjectionToken<DaffSearchRoutingOptionBuilder>('DAFF_SEARCH_ROUTING_OPTIONS_BUILDER');
Original file line number Diff line number Diff line change
@@ -1,42 +1,32 @@
import {
InjectionToken,
ValueProvider,
} from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';

import { createMultiInjectionToken } from '@daffodil/core';
import { DaffSearchDriverOptions } from '@daffodil/search/driver';

export type DaffSearchRoutingOptionBuilder<T extends DaffSearchDriverOptions = DaffSearchDriverOptions> = (route: ActivatedRouteSnapshot) => T;

/**
* A multi-provider injection token for search option builders.
* These builders are called with the requested route during the resolve step
* and return options to pass to the search driver.
*/
export const DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS = new InjectionToken<DaffSearchRoutingOptionBuilder[]>(
'DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS',
{ factory: () => []},
);
export const {
/**
* A multi-provider injection token for search option builders.
* These builders are called with the requested route during the resolve step
* and return options to pass to the search driver.
*/
token: DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS,

/**
* Provides search option builders for the routing layer.
*
* See {@link DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS}.
*
* ```ts
* providers: [
* ...daffProvideSearchRoutingOptionBuilders(
* route => ({
* limit: route.queryParams.limit
* })
* )
* ]
* ```
*/
export function daffProvideSearchRoutingOptionBuilders(...builders: DaffSearchRoutingOptionBuilder[]): ValueProvider[] {
return builders.map(builder => ({
provide: DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS,
useValue: builder,
multi: true,
}));
}
/**
* Provides search option builders for the routing layer.
*
* See {@link DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS}.
*
* ```ts
* providers: [
* ...daffProvideSearchRoutingOptionBuilders(
* route => ({
* limit: route.queryParams.limit
* })
* )
* ]
* ```
*/
provider: daffProvideSearchRoutingOptionBuilders,
} = createMultiInjectionToken<DaffSearchRoutingOptionBuilder>('DAFF_SEARCH_ROUTING_OPTIONS_BUILDERS');
15 changes: 8 additions & 7 deletions libs/search/state/src/config/token.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { InjectionToken } from '@angular/core';
import { createConfigInjectionToken } from '@daffodil/core';

import { DAFF_SEARCH_STATE_CONFIG_DEFAULT } from './default';
import { DaffSearchStateConfig } from './interface';

/**
* The token used to provide @daffodil/search/state config data.
*/
export const DAFF_SEARCH_STATE_CONFIG = new InjectionToken<DaffSearchStateConfig>('DAFF_SEARCH_STATE_CONFIG', {
factory: () => DAFF_SEARCH_STATE_CONFIG_DEFAULT,
});
export const {
/**
* The token used to provide @daffodil/search/state config data.
*/
token: DAFF_SEARCH_STATE_CONFIG,
provider: provideDaffAuthRoutingConfig,
} = createConfigInjectionToken<DaffSearchStateConfig>(DAFF_SEARCH_STATE_CONFIG_DEFAULT, 'DAFF_SEARCH_STATE_CONFIG');
16 changes: 9 additions & 7 deletions libs/search/state/src/injection-tokens/error-matcher.token.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { InjectionToken } from '@angular/core';

import { createSingleInjectionToken } from '@daffodil/core';
import { daffTransformErrorToStateError } from '@daffodil/core/state';

/**
* Transforms `DaffError`s into `DaffStateError`s before they are serialized into state.
* Can be used to further refine Daffodil errors into more specific app errors.
*/
export const DAFF_SEARCH_ERROR_MATCHER = new InjectionToken<typeof daffTransformErrorToStateError>(
export const {
/**
* Transforms `DaffError`s into `DaffStateError`s before they are serialized into state.
* Can be used to further refine Daffodil errors into more specific app errors.
*/
token: DAFF_SEARCH_ERROR_MATCHER,
provider: daffProvideSearchErrorMatcher,
} = createSingleInjectionToken<typeof daffTransformErrorToStateError>(
'DAFF_SEARCH_ERROR_MATCHER',
{ factory: () => daffTransformErrorToStateError },
);
2 changes: 1 addition & 1 deletion libs/search/state/src/injection-tokens/public_api.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { DAFF_SEARCH_ERROR_MATCHER } from './error-matcher.token';
export * from './error-matcher.token';
60 changes: 24 additions & 36 deletions libs/search/state/src/reducers/token/extra.token.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,32 @@
import {
InjectionToken,
Provider,
} from '@angular/core';
import { ActionReducer } from '@ngrx/store';

import { createMultiInjectionToken } from '@daffodil/core';
import { DaffSearchResult } from '@daffodil/search';

import { DaffSearchReducersState } from '../reducers.interface';

/**
* A token to hold the injectable extra reducers.
*
* Prefer using {@link daffSearchProvideExtraReducers}.
*/
export const DAFF_SEARCH_EXTRA_REDUCERS = new InjectionToken<ActionReducer<DaffSearchReducersState>[]>(
export const {
/**
* A token to hold the injectable extra reducers.
*
* Prefer using {@link daffSearchProvideExtraReducers}.
*/
token: DAFF_SEARCH_EXTRA_REDUCERS,

/**
* Provides additional reducers that run after the standard Daffodil cart reducers.
*
* ```ts
* providers: [
* ...daffSearchProvideExtraReducers(
* myReducer1,
* myReducer2
* )
* ]
* ```
*/
provider: daffSearchProvideExtraReducers,
} = createMultiInjectionToken<ActionReducer<DaffSearchReducersState>>(
'DAFF_SEARCH_EXTRA_REDUCERS',
{
factory: () => [],
providedIn: 'any',
},
{ providedIn: 'any' },
);

/**
* Provides additional reducers that run after the standard Daffodil cart reducers.
*
* ```ts
* providers: [
* ...daffSearchProvideExtraReducers(
* myReducer1,
* myReducer2
* )
* ]
* ```
*/
export function daffSearchProvideExtraReducers<T extends DaffSearchResult = DaffSearchResult>(
...reducers: ActionReducer<DaffSearchReducersState<T>>[]
): Provider[] {
return reducers.map(reducer => ({
provide: DAFF_SEARCH_EXTRA_REDUCERS,
useValue: reducer,
multi: true,
}));
}
Loading

0 comments on commit 2fbd482

Please sign in to comment.