Skip to content

Commit

Permalink
feat: entity decorator
Browse files Browse the repository at this point in the history
 + Add @entity decorator for models
 + Implement required modelName option
 + Implement optional pluralName option
 + Implement optional uriName option
 + Implement optional comparer function option
 + Implement effect exclusion feature
 + Add sorted$ facade stream and selectAllSorted selector
 * Fix prod build issue with modelName in @entity decorator
 * Improve robustness of all selectors when state is falsy

 + Added test-app for simpler app than demo to test library features with

Issue #70 #58 #81
  • Loading branch information
Jon Rista authored and jrista committed Jan 13, 2020
1 parent cd19510 commit 3ae5011
Show file tree
Hide file tree
Showing 75 changed files with 1,263 additions and 241 deletions.
29 changes: 26 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
<a name="0.4.0"></a>

# [0.4.0](https://github.com/briebug/ngrx-auto-entity/compare/0.3.1...0.4.0) Beta (2020-01-13)

Introducing the `@Entity` decorator for model classes. This decorator provides custom naming capabilities,
the ability to filter which auto-entity pre-fab effects handle each model, as well as define a default
comparer for sorting entities retrieved with a new .sorted$ stream on pre-fab facades.

### Features
- **decorators:** Add `@Entity` decorator for models with modelName, pluralName, uriName properties (#70)
- **decorators:** Add `excludeEffects` functionality to `@Entity` decorator for filtering which effects handle entity
- **decorators:** Add `comparer` property to `@Entity` decorator to support selecting sorted entities (#58)
- **selectors:** Add `selectAllSorted` selector that uses entity comparer to sort on selection (#58)
- **facades:** Add `sorted$` stream to return all entities in sorted order from `selectAllSorted` selector (#58)

### Internal

- **decorators:** Moved all decorators into internal /lib/decorators directory (will break direct imports, use public api!)

### Bug Fix
- **selectors:** Added additional falsy checks to all selectors to limit frequency of hard failures (#81)
- **decorators:** Added `modelName` to `@Entity` decorator to allow explicit definition of model name immune to mangling by code minifiers (#81)

<a name="0.3.1"></a>

# [0.3.1](https://github.com/briebug/ngrx-auto-entity/compare/0.3.0...0.3.1) Beta (2020-01-07)
Expand All @@ -23,7 +46,7 @@ Correlated actions are usually sets of request/success/failure actions, such as

### Features

- **correlated actions:** Add `correlationId` property to `EntityAction` for tracking correlated actions.
- **correlated actions:** Add `correlationId` property to `EntityAction` for tracking correlated actions. (#75)

### Package

Expand Down Expand Up @@ -58,11 +81,11 @@ custom effects creation.

### Features

- **actions:** Add fromEntityTypes factory function for multi-entity multi-action effects filtering
- **actions:** Add fromEntityTypes factory function for multi-entity multi-action effects filtering (#66)

### Bug Fixes

- **selectors:** Add createdAt facade getter and corresponding selectors
- **selectors:** Add createdAt facade getter and corresponding selectors (#65)



Expand Down
100 changes: 100 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,106 @@
}
}
}
},
"test-app": {
"projectType": "application",
"schematics": {},
"root": "projects/test-app",
"sourceRoot": "projects/test-app/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-app",
"index": "projects/test-app/src/index.html",
"main": "projects/test-app/src/main.ts",
"polyfills": "projects/test-app/src/polyfills.ts",
"tsConfig": "projects/test-app/tsconfig.app.json",
"aot": false,
"assets": [
"projects/test-app/src/favicon.ico",
"projects/test-app/src/assets"
],
"styles": [
"projects/test-app/src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "projects/test-app/src/environments/environment.ts",
"with": "projects/test-app/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "test-app:build"
},
"configurations": {
"production": {
"browserTarget": "test-app:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "test-app:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/test-app/src/test.ts",
"polyfills": "projects/test-app/src/polyfills.ts",
"tsConfig": "projects/test-app/tsconfig.spec.json",
"karmaConfig": "projects/test-app/karma.conf.js",
"assets": [
"projects/test-app/src/favicon.ico",
"projects/test-app/src/assets"
],
"styles": [
"projects/test-app/src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/test-app/tsconfig.app.json",
"projects/test-app/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "ngrx-auto-entity-app"
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
"ng": "ng",
"start": "concurrently --prefix-colors white.bgBlue,white.bgRed --names angular,json-server --kill-others \"npm run serve-proxy\" \"npm run json-server\"",
"serve": "ng serve --source-map --vendorSourceMap",
"serve-proxy": "ng serve --source-map --vendorSourceMap --proxy-config proxy.conf.json",
"serve:prod": "ng serve --prod --source-map --vendorSourceMap",
"serve:test": "ng serve test-app --prod --source-map --vendorSourceMap",
"serve:test:prod": "ng serve test-app --source-map --vendorSourceMap",
"serve-proxy": "ng serve --prod --source-map --vendorSourceMap --proxy-config proxy.conf.json",
"serve-proxy:test": "ng serve test-app --source-map --vendorSourceMap --proxy-config proxy.conf.json",
"serve-proxy:test:prod": "ng serve test-app --prod --source-map --vendorSourceMap --proxy-config proxy.conf.json",
"build": "ng build --prod",
"build:watch": "ng build --prod --watch",
"build:app": "ng build ngrx-auto-entity-app --prod",
Expand Down
2 changes: 1 addition & 1 deletion projects/ngrx-auto-entity/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.3.1",
"version": "0.4.0",
"name": "@briebug/ngrx-auto-entity",
"description": "Automatic Entity State and Facades for NgRx. Simplifying reactive state!",
"keywords": [
Expand Down
15 changes: 14 additions & 1 deletion projects/ngrx-auto-entity/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,20 @@ export {
Clear
} from './lib/actions';

export { Key, getKey, getKeyFromModel, getKeyNames, getKeyNamesFromModel, checkKeyName } from './lib/decorators';
export {
IEffectExclusions,
IEffectExcept,
IEntityOptions,
Entity,
all,
extra,
loads,
curd,
except,
matching
} from './lib/decorators/entity';

export { Key, getKey, getKeyFromModel, getKeyNames, getKeyNamesFromModel, checkKeyName } from './lib/decorators/key';

export { EntityOperators } from './lib/operators';

Expand Down
2 changes: 1 addition & 1 deletion projects/ngrx-auto-entity/src/lib/actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
UpdateManySuccess,
UpdateSuccess
} from './actions';
import { Key } from './decorators';
import { Key } from './decorators/key';

class TestEntity {
@Key id: number;
Expand Down
22 changes: 18 additions & 4 deletions projects/ngrx-auto-entity/src/lib/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { Actions } from '@ngrx/effects';
import { Action } from '@ngrx/store';
import { merge, Observable, OperatorFunction } from 'rxjs';
import { filter } from 'rxjs/operators';

import { pascalCase } from '../util/case';
import { checkKeyName } from './decorators';
import { IEntityOptions } from './decorators/entity';
import { ENTITY_OPTS_PROP } from './decorators/entity-tokens';
import { checkKeyName } from './decorators/key';
import { IPageInfo, IRangeInfo, Page, Range } from './models';
import { EntityIdentity } from './util';

Expand Down Expand Up @@ -94,6 +97,8 @@ export enum EntityActionTypes {
*/
export interface IEntityInfo {
modelName: string;
pluralName?: string;
uriName?: string;
modelType: new () => any;
}

Expand All @@ -110,9 +115,14 @@ export interface IEntityAction extends Action, ICorrelatedAction {

// tslint:disable
const uuid = (a?, b?) => {
for (b = a = ''; a++ < 36; b += a * 51 & 52 ? (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString(16) : '-') ;
for (
b = a = '';
a++ < 36;
b += (a * 51) & 52 ? (a ^ 15 ? 8 ^ (Math.random() * (a ^ 20 ? 16 : 4)) : 4).toString(16) : '-'
);
return b;
};

// tslint:enable

/**
Expand All @@ -130,10 +140,14 @@ export abstract class EntityAction<TModel> implements IEntityAction {

const setInfo = (type: any): IEntityInfo => {
const instance = new type();
checkKeyName(type, instance.constructor.name);
const opts = (type[ENTITY_OPTS_PROP] || { modelName: instance.constructor.name }) as IEntityOptions;
const modelName = opts.modelName;
checkKeyName(type, modelName);
return {
modelType: type,
modelName: instance.constructor.name
modelName,
pluralName: opts.pluralName,
uriName: opts.uriName
};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ENTITY_OPTS_PROP = '__nae_entity_opts';
Loading

0 comments on commit 3ae5011

Please sign in to comment.