-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create ngrx-accelerator (#399)
* feat: initialize new lib * feat: add ngrx utils to lib and deprecate ngrx utils in pia * fix: linter error * fix: add missing dependencies * fix: fix typing issues * feat: add navigationMergeReducer * fix: add missing dependency * fix: fix linting * feat: add lazyLoadingMergeReducer to ngrx-accelerator * fix: fix linting issue
- Loading branch information
1 parent
023dd8b
commit d3007a1
Showing
26 changed files
with
463 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"extends": ["../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts"], | ||
"extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], | ||
"rules": { | ||
"@angular-eslint/directive-selector": [ | ||
"error", | ||
{ | ||
"type": "attribute", | ||
"prefix": "ocx", | ||
"style": "camelCase" | ||
} | ||
], | ||
"@angular-eslint/component-selector": [ | ||
"error", | ||
{ | ||
"type": "element", | ||
"prefix": "ocx", | ||
"style": "kebab-case" | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
"files": ["*.html"], | ||
"extends": ["plugin:@nx/angular-template"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.json"], | ||
"parser": "jsonc-eslint-parser", | ||
"rules": { | ||
"@nx/dependency-checks": "error" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# ngrx-accelerator | ||
|
||
This library was generated with [Nx](https://nx.dev). | ||
|
||
## Running unit tests | ||
|
||
Run `nx test ngrx-accelerator` to execute the unit tests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: 'ngrx-accelerator', | ||
preset: '../../jest.preset.js', | ||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], | ||
coverageDirectory: '../../coverage/libs/ngrx-accelerator', | ||
transform: { | ||
'^.+\\.(ts|mjs|js|html)$': [ | ||
'jest-preset-angular', | ||
{ | ||
tsconfig: '<rootDir>/tsconfig.spec.json', | ||
stringifyContentPathRegex: '\\.(html|svg)$', | ||
}, | ||
], | ||
}, | ||
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], | ||
snapshotSerializers: [ | ||
'jest-preset-angular/build/serializers/no-ng-attributes', | ||
'jest-preset-angular/build/serializers/ng-snapshot', | ||
'jest-preset-angular/build/serializers/html-comment', | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json", | ||
"dest": "../../dist/libs/ngrx-accelerator", | ||
"lib": { | ||
"entryFile": "src/index.ts" | ||
}, | ||
"assets": [ | ||
"CHANGELOG.md" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"name": "@onecx/ngrx-accelerator", | ||
"version": "5.3.2", | ||
"peerDependencies": { | ||
"@angular/core": "^18.0.5", | ||
"@angular/router": "^18.0.5", | ||
"deepmerge": "^4.3.1", | ||
"fast-deep-equal": "^3.1.3", | ||
"@ngrx/effects": "^18.0.1", | ||
"@ngrx/operators": "^18.0.1", | ||
"@ngrx/router-store": "^18.0.1", | ||
"@ngrx/store": "^18.0.1", | ||
"rxjs": "7.8.1", | ||
"tslib": "^2.6.3", | ||
"zod": "^3.23.8" | ||
}, | ||
"main": "./src/index.js", | ||
"typings": "./src/index.d.ts", | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "ngrx-accelerator", | ||
"$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
"sourceRoot": "libs/ngrx-accelerator/src", | ||
"prefix": "lib", | ||
"projectType": "library", | ||
"tags": [], | ||
"targets": { | ||
"build": { | ||
"executor": "@nx/js:tsc", | ||
"outputs": ["{options.outputPath}"], | ||
"options": { | ||
"outputPath": "dist/libs/ngrx-accelerator", | ||
"main": "libs/ngrx-accelerator/src/index.ts", | ||
"tsConfig": "libs/ngrx-accelerator/tsconfig.lib.json", | ||
"assets": ["libs/ngrx-accelerator/*.md"] | ||
} | ||
}, | ||
"test": { | ||
"executor": "@nx/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], | ||
"options": { | ||
"jestConfig": "libs/ngrx-accelerator/jest.config.ts", | ||
"passWithNoTests": true | ||
}, | ||
"configurations": { | ||
"ci": { | ||
"ci": true, | ||
"codeCoverage": true | ||
} | ||
} | ||
}, | ||
"lint": { | ||
"executor": "@nx/linter:eslint", | ||
"outputs": ["{options.outputFile}"], | ||
"options": { | ||
"lintFilePatterns": ["libs/ngrx-accelerator/**/*.ts", "libs/ngrx-accelerator/package.json"] | ||
} | ||
}, | ||
"release": { | ||
"executor": "nx-release:build-update-publish", | ||
"options": { | ||
"libName": "ngrx-accelerator" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Effects | ||
export * from './lib/utils/effects/create-query-params-effect' | ||
export * from './lib/utils/effects/filter-for-navigated-to' | ||
export * from './lib/utils/effects/filter-for-only-query-params-changed' | ||
export * from './lib/utils/effects/filter-for-query-params-changed' | ||
|
||
// Selectors | ||
export * from './lib/utils/selectors/create-child-selectors' | ||
|
||
// Local Storage | ||
export * from './lib/utils/local-storage/lazy-loading-merge-reducer' |
32 changes: 32 additions & 0 deletions
32
libs/ngrx-accelerator/src/lib/utils/effects/create-query-params-effect.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ActivatedRoute, Router } from '@angular/router' | ||
import { Actions, createEffect, ofType } from '@ngrx/effects' | ||
import { concatLatestFrom } from '@ngrx/operators' | ||
import { ActionCreator, Creator } from '@ngrx/store' | ||
import { tap } from 'rxjs' | ||
|
||
export function createQueryParamsEffect<AC extends ActionCreator<string, Creator>>( | ||
actions$: Actions, | ||
actionType: AC, | ||
router: Router, | ||
activatedRoute: ActivatedRoute, | ||
reducer: (state: Record<string, any>, action: ReturnType<AC>) => Record<string, any> | ||
) { | ||
return createEffect( | ||
() => { | ||
return actions$.pipe( | ||
ofType(actionType), | ||
concatLatestFrom(() => activatedRoute.queryParams), | ||
tap(([action, queryParams]) => { | ||
const params = reducer(queryParams, action) | ||
router.navigate([], { | ||
relativeTo: activatedRoute, | ||
queryParams: params, | ||
replaceUrl: true, | ||
onSameUrlNavigation: 'reload', | ||
}) | ||
}) | ||
) | ||
}, | ||
{ dispatch: false } | ||
) | ||
} |
30 changes: 30 additions & 0 deletions
30
libs/ngrx-accelerator/src/lib/utils/effects/filter-for-navigated-to.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { filter, MonoTypeOperatorFunction } from 'rxjs' | ||
import { ActivatedRoute, Router } from '@angular/router' | ||
import { Type } from '@angular/core' | ||
import { RouterNavigatedAction } from '@ngrx/router-store' | ||
|
||
export function filterForNavigatedTo<A extends RouterNavigatedAction>( | ||
router: Router, | ||
component: Type<any> | ||
): MonoTypeOperatorFunction<A> { | ||
return (source) => { | ||
return source.pipe( | ||
filter(() => { | ||
return checkForComponent(component, router.routerState.root) | ||
}) | ||
) | ||
} | ||
} | ||
|
||
function checkForComponent(component: any, route: ActivatedRoute): boolean { | ||
if (route.component === component) { | ||
return true | ||
} | ||
for (const c of route.children) { | ||
const r = checkForComponent(component, c) | ||
if (r) { | ||
return true | ||
} | ||
} | ||
return false | ||
} |
34 changes: 34 additions & 0 deletions
34
libs/ngrx-accelerator/src/lib/utils/effects/filter-for-only-query-params-changed.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Router, RoutesRecognized } from '@angular/router' | ||
import { RouterNavigatedAction } from '@ngrx/router-store' | ||
import { filter, map, MonoTypeOperatorFunction, withLatestFrom } from 'rxjs' | ||
|
||
/** | ||
* @deprecated use filterOutOnlyQueryParamsChanged | ||
*/ | ||
export function filterForOnlyQueryParamsChanged<A extends RouterNavigatedAction>( | ||
router: Router | ||
): MonoTypeOperatorFunction<A> { | ||
return filterOutOnlyQueryParamsChanged(router) | ||
} | ||
|
||
export function filterOutOnlyQueryParamsChanged<A extends RouterNavigatedAction>( | ||
router: Router | ||
): MonoTypeOperatorFunction<A> { | ||
return (source) => { | ||
return source.pipe( | ||
withLatestFrom( | ||
router.events.pipe( | ||
filter((e) => e instanceof RoutesRecognized), | ||
map(() => router.routerState) | ||
) | ||
), | ||
filter(([action, previousRouterState]) => { | ||
const previousPath = previousRouterState.snapshot.url.split('?')[0] | ||
const currentPath = action.payload.event.urlAfterRedirects.split('?')[0] | ||
|
||
return previousPath !== currentPath | ||
}), | ||
map(([action]) => action) | ||
) | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
libs/ngrx-accelerator/src/lib/utils/effects/filter-for-query-params-changed.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { RouterNavigatedAction } from '@ngrx/router-store' | ||
import { ZodType } from 'zod' | ||
import { MonoTypeOperatorFunction, filter, withLatestFrom, map } from 'rxjs' | ||
import equal from 'fast-deep-equal' | ||
import { Router, RoutesRecognized } from '@angular/router' | ||
|
||
/** | ||
* @deprecated use filterOutQueryParamsHaveNotChanged | ||
*/ | ||
export function filterForQueryParamsChanged<A extends RouterNavigatedAction>( | ||
router: Router, | ||
queryParamsTypeDef: ZodType, | ||
allowEmptyQueryParamsList = false | ||
): MonoTypeOperatorFunction<A> { | ||
return filterOutQueryParamsHaveNotChanged(router, queryParamsTypeDef, allowEmptyQueryParamsList) | ||
} | ||
|
||
export function filterOutQueryParamsHaveNotChanged<A extends RouterNavigatedAction>( | ||
router: Router, | ||
queryParamsTypeDef: ZodType, | ||
allowEmptyQueryParamsList = false | ||
): MonoTypeOperatorFunction<A> { | ||
return (source) => { | ||
return source.pipe( | ||
withLatestFrom( | ||
router.events.pipe( | ||
filter((e) => e instanceof RoutesRecognized), | ||
map(() => router.routerState) | ||
) | ||
), | ||
filter(([action, previousRouterState]) => { | ||
if ( | ||
!allowEmptyQueryParamsList && | ||
Object.keys(action?.payload?.routerState?.root?.queryParams || {}).length === 0 | ||
) { | ||
return false | ||
} | ||
const currentQueryParams = previousRouterState.snapshot.root.queryParams | ||
const actionResult = queryParamsTypeDef.safeParse(action?.payload?.routerState?.root?.queryParams) | ||
const currentResult = queryParamsTypeDef.safeParse(currentQueryParams) | ||
|
||
if (actionResult.success && currentResult.success) { | ||
const actionParams = actionResult.data | ||
const currentParams = currentResult.data | ||
if ( | ||
allowEmptyQueryParamsList && | ||
Object.keys(actionParams).length === 0 && | ||
Object.keys(currentParams).length === 0 | ||
) { | ||
return true | ||
} | ||
return !equal(actionParams, currentParams) | ||
} | ||
return false | ||
}), | ||
map(([action]) => action) | ||
) | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
libs/ngrx-accelerator/src/lib/utils/local-storage/lazy-loading-merge-reducer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import deepmerge from 'deepmerge' | ||
|
||
export const lazyLoadingMergeReducer = (state: any, rehydratedState: any, _action: any) => { | ||
const overwriteMerge = (_destinationArray: any, sourceArray: any, _options: any) => sourceArray | ||
const options: deepmerge.Options = { | ||
arrayMerge: overwriteMerge, | ||
} | ||
const keysToRehydrate = Object.keys(rehydratedState).filter((key) => state[key]) | ||
if (keysToRehydrate.length) { | ||
const stateToRehydrate = Object.keys(rehydratedState).reduce((acc: Record<string, unknown>, key) => { | ||
if (keysToRehydrate.includes(key)) { | ||
acc[key] = rehydratedState[key] | ||
} | ||
return acc | ||
}, {}) | ||
state = deepmerge(state, stateToRehydrate, options) | ||
keysToRehydrate.forEach((key) => { | ||
delete rehydratedState[key] | ||
}) | ||
} | ||
return state | ||
} |
26 changes: 26 additions & 0 deletions
26
libs/ngrx-accelerator/src/lib/utils/selectors/create-child-selectors.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { MemoizedSelector, createSelector } from '@ngrx/store' | ||
|
||
type Primitive = string | number | bigint | boolean | null | undefined | ||
|
||
type ChildSelectors<State extends Record<string, any>, ChildState> = ChildState extends Primitive | unknown[] | Date | ||
? Record<string, never> | ||
: { | ||
[K in keyof ChildState & string as `select${Capitalize<K>}`]: MemoizedSelector<State, ChildState[K]> | ||
} | ||
|
||
function capitalize<T extends string>(text: T): Capitalize<T> { | ||
return (text.charAt(0).toUpperCase() + text.substring(1)) as Capitalize<T> | ||
} | ||
|
||
export function createChildSelectors<State extends Record<string, any>, ChildState extends Record<string, any>>( | ||
featureSelector: MemoizedSelector<State, ChildState>, | ||
initialChildState: ChildState | ||
): ChildSelectors<State, ChildState> { | ||
return Object.keys(initialChildState).reduce( | ||
(nestedSelectors, nestedKey) => ({ | ||
...nestedSelectors, | ||
[`select${capitalize(nestedKey)}`]: createSelector(featureSelector, (parentState) => parentState?.[nestedKey]), | ||
}), | ||
{} as ChildSelectors<State, ChildState> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment | ||
globalThis.ngJest = { | ||
testEnvironmentOptions: { | ||
errorOnUnknownElements: true, | ||
errorOnUnknownProperties: true, | ||
}, | ||
} | ||
import 'jest-preset-angular/setup-jest' |
Oops, something went wrong.