@ngrx-traits/core 12.1.1 → 12.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,10 +23,84 @@ function camelCaseToSentence(text) {
23
23
  const result = text.replace(/([A-Z])/g, ' $1');
24
24
  return result.charAt(0).toUpperCase() + result.slice(1);
25
25
  }
26
-
27
- function createTraitFactory(f) {
28
- return f;
26
+ /**
27
+ * Set propertyReducer in sourceReducer in a property of the source state,
28
+ * @param sourceReducer
29
+ * @param property
30
+ * @param propertyReducer
31
+ *
32
+ * @example
33
+ *
34
+ * const newReducer = setPropertyReducer(productsReducer, 'selectedProduct', selectedProductReducer)
35
+ */
36
+ function setPropertyReducer(sourceReducer, property, propertyReducer) {
37
+ return function reducer(state, action) {
38
+ const sourceState = sourceReducer(state, action);
39
+ return Object.assign(Object.assign({}, sourceState), { [property]: propertyReducer(sourceState[property], action) });
40
+ };
41
+ }
42
+ /**
43
+ * Set propertyReducers in sourceReducer each in a property of the source state,
44
+ * @param sourceReducer
45
+ * @param property
46
+ * @param propertyReducer
47
+ *
48
+ * @example
49
+ *
50
+ * const newReducer = setPropertyReducer(productsReducer,
51
+ * {
52
+ * selectedProduct: selectedProductReducer
53
+ * favoriteProduct: favoriteProductReducer
54
+ * })
55
+ */
56
+ function setPropertiesReducer(sourceReducer, propertiesReducers) {
57
+ return function reducer(state, action) {
58
+ const newState = Object.assign({}, sourceReducer(state, action));
59
+ for (const property in propertiesReducers) {
60
+ newState[property] = propertiesReducers[property](newState[property], action);
61
+ }
62
+ return newState;
63
+ };
29
64
  }
65
+ /**
66
+ * joins two reducers so the work in the same state
67
+ * @param firstReducer
68
+ * @param secondReducer
69
+ */
70
+ function joinReducers(firstReducer, secondReducer) {
71
+ return function reducer(state, action) {
72
+ const sourceState = firstReducer(state, action);
73
+ return secondReducer(sourceState, action);
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Creates a function that when execute will combine all the traits, and return a EntityFeatureFactory
79
+ * which combines all the traits actions, selectors , reducers and effects,
80
+ * the names param will replace any action and selector with the word Entity or Entities,
81
+ * with the corresponding entityName and entitiesName param (entityName+'s' if entitiesName is omitted).
82
+ * @param namesConfig - Optional Names for entities
83
+ * @param namesConfig.entityName - singular name for entity
84
+ * @param [namesConfig.entitiesName] - plural name for entities, defaults to entityName + 's'
85
+ * @param traits set of traits to be combined
86
+ *
87
+ * @example
88
+ *
89
+ * const featureFactory = createEntityFeatureFactory(
90
+ * { entityName: 'product' },
91
+ * addLoadEntitiesTrait<Product>(),
92
+ * addSelectEntityTrait<Product>(),
93
+ * addAsyncActionTrait({
94
+ * name: 'checkout',
95
+ * actionSuccessProps: props<{ orderId: string }>(),
96
+ * })
97
+ * );
98
+ *
99
+ * export const productsFeature = featureFactory({
100
+ * actionsGroupKey: '[Products]',
101
+ * featureSelector: 'products',
102
+ * });
103
+ */
30
104
  function createEntityFeatureFactory(namesOrFactory, ...traits) {
31
105
  return ((config) => {
32
106
  const { entityName, entitiesName } = 'entityName' in namesOrFactory
@@ -190,27 +264,45 @@ function getSelectorsForFeature(featureSelect, selectors) {
190
264
  }
191
265
  return ss;
192
266
  }
193
- function setPropertyReducer(sourceReducer, property, propertyReducer) {
194
- return function reducer(state, action) {
195
- const sourceState = sourceReducer(state, action);
196
- return Object.assign(Object.assign({}, sourceState), { [property]: propertyReducer(sourceState[property], action) });
197
- };
198
- }
199
- function setPropertiesReducer(sourceReducer, propertiesReducers) {
200
- return function reducer(state, action) {
201
- const newState = Object.assign({}, sourceReducer(state, action));
202
- for (const property in propertiesReducers) {
203
- newState[property] = propertiesReducers[property](newState[property], action);
204
- }
205
- return newState;
206
- };
207
- }
208
- function joinReducers(firstReducer, secondReducer) {
209
- return function reducer(state, action) {
210
- const sourceState = firstReducer(state, action);
211
- return secondReducer(sourceState, action);
212
- };
213
- }
267
+ /**
268
+ * Combine a map entityFeatureFactories into one,
269
+ * grouping the actions and selectors by the key of the respective entityFeatureFactory
270
+ * @param traitFactoriesMap
271
+ *
272
+ * @example
273
+ *
274
+ * const clientsFeatureFactory = createEntityFeatureFactory(
275
+ * { entityName: 'client', entitiesName: 'clients' },
276
+ * addLoadEntitiesTrait<Client>(),
277
+ * addCrudEntitiesTrait<Client>()
278
+ * );
279
+ *
280
+ * const productOrderFeatureFactory = createEntityFeatureFactory(
281
+ * { entityName: 'productOrder' },
282
+ * addLoadEntitiesTrait<ProductOrder>(),
283
+ * addSelectEntitiesTrait<ProductOrder>()
284
+ * );
285
+ *
286
+ * const productFeatureFactory = createEntityFeatureFactory(
287
+ * { entityName: 'product' },
288
+ * addLoadEntitiesTrait<Product>(),
289
+ * addSelectEntitiesTrait<Product>()
290
+ * );
291
+ *
292
+ * const productCombinedFactory = combineEntityFeatures({
293
+ * products: productFeatureFactory,
294
+ * productOrders: productOrderFeatureFactory,
295
+ * clients: clientsFeatureFactory,
296
+ * });
297
+ *
298
+ * const combinedFeature = productCombinedFactory({
299
+ * actionsGroupKey: '[Combined]',
300
+ * featureSelector: 'combined',
301
+ * });
302
+ *
303
+ * combinedFeature.actions.client.loadClients();
304
+ * combinedFeature.actions.product.loadProducts();
305
+ */
214
306
  function combineEntityFeatures(traitFactoriesMap) {
215
307
  return ((config) => {
216
308
  const featureSelector = typeof config.featureSelector === 'string'
@@ -239,6 +331,45 @@ function combineEntityFeatures(traitFactoriesMap) {
239
331
  };
240
332
  });
241
333
  }
334
+ /**
335
+ * Mix a map entityFeatureFactories into one, different from combine the actions and selectors a mix, not group by key like in combine, the keys are still use
336
+ * internal in the reducers and selector to separate the state
337
+ * @param traitFactoriesMap
338
+ *
339
+ * @example
340
+ *
341
+ * const clientsFeatureFactory = createEntityFeatureFactory(
342
+ * { entityName: 'client', entitiesName: 'clients' },
343
+ * addLoadEntitiesTrait<Client>(),
344
+ * addCrudEntitiesTrait<Client>()
345
+ * );
346
+ *
347
+ * const productOrderFeatureFactory = createEntityFeatureFactory(
348
+ * { entityName: 'productOrder' },
349
+ * addLoadEntitiesTrait<ProductOrder>(),
350
+ * addSelectEntitiesTrait<ProductOrder>()
351
+ * );
352
+ *
353
+ * const productFeatureFactory = createEntityFeatureFactory(
354
+ * { entityName: 'product' },
355
+ * addLoadEntitiesTrait<Product>(),
356
+ * addSelectEntitiesTrait<Product>()
357
+ * );
358
+ *
359
+ * const productMixedFactory = mixEntityFeatures({
360
+ * products: productFeatureFactory,
361
+ * productOrders: productOrderFeatureFactory,
362
+ * clients: clientsFeatureFactory,
363
+ * });
364
+ *
365
+ * const mixedFeature = productMixedFactory({
366
+ * actionsGroupKey: '[Mixed]',
367
+ * featureSelector: 'mixed',
368
+ * });
369
+ * mixedFeature.actions.loadClients();
370
+ * mixedFeature.actions.loadProducts();
371
+ *
372
+ */
242
373
  function mixEntityFeatures(traitFactoriesMap) {
243
374
  return ((config) => {
244
375
  const featureSelector = typeof config.featureSelector === 'string'
@@ -267,6 +398,49 @@ function mixEntityFeatures(traitFactoriesMap) {
267
398
  };
268
399
  });
269
400
  }
401
+ /**
402
+ * Combines targetTraitFactory with the traitFactoriesMap using the keys as props for the targetTraitFactory state,
403
+ * and grouping the combined actions by key
404
+ * @param targetTraitFactory
405
+ * @param traitFactoriesMap
406
+ *
407
+ * @example
408
+ *
409
+ * const clientsFeatureFactory = createEntityFeatureFactory(
410
+ * { entityName: 'client', entitiesName: 'clients' },
411
+ * addLoadEntitiesTrait<Client>(),
412
+ * addCrudEntitiesTrait<Client>()
413
+ * );
414
+ *
415
+ * const productOrderFeatureFactory = createEntityFeatureFactory(
416
+ * { entityName: 'productOrder' },
417
+ * addLoadEntitiesTrait<ProductOrder>(),
418
+ * addSelectEntitiesTrait<ProductOrder>()
419
+ * );
420
+ *
421
+ * const productFeatureFactory = createEntityFeatureFactory(
422
+ * { entityName: 'product' },
423
+ * addLoadEntitiesTrait<Product>(),
424
+ * addSelectEntitiesTrait<Product>()
425
+ * );
426
+ *
427
+ * const productAddEntityPropertiesFactory = addEntityFeaturesProperties(
428
+ * productFeatureFactory,
429
+ * {
430
+ * productOrders: productOrderFeatureFactory,
431
+ * clients: clientsFeatureFactory,
432
+ * }
433
+ * );
434
+ *
435
+ * const combinedFeature = productAddEntityPropertiesFactory({
436
+ * actionsGroupKey: '[addEntityFeatures]',
437
+ * featureSelector: 'addEntityFeatures',
438
+ * });
439
+ *
440
+ * combinedFeature.actions.loadProducts();
441
+ * combinedFeature.actions.clients.loadClients();
442
+ * combinedFeature.actions.productOrders.loadProductOrders();
443
+ */
270
444
  function addEntityFeaturesProperties(targetTraitFactory, traitFactoriesMap) {
271
445
  return ((config) => {
272
446
  const featureSelector = typeof config.featureSelector === 'string'
@@ -299,38 +473,13 @@ function addEntityFeaturesProperties(targetTraitFactory, traitFactoriesMap) {
299
473
  };
300
474
  });
301
475
  }
302
- // export
303
- /// products:{actions, selectors, }, orders: {actions,slectors}
304
- /// { actions: {ProductActions, OrderActions}, selectors: {ProductSelectors, OrderSelectors}
305
- // TODO finish implementing combineTrais and addPropertiesTraits
306
- // TODO finish renaming traits
307
-
308
- // type G = ReplaceProps<
309
- // ReplaceProps<
310
- // {
311
- // loadEntities: 1;
312
- // loadEntitiesSuccess: 2;
313
- // selectEntities: 3;
314
- // selectEntity: 4;
315
- // },
316
- // 'Entities',
317
- // 'products'
318
- // >,
319
- // 'Entity',
320
- // 'product'
321
- // >;
322
- //
323
- // const g: G = {};
324
- // // g.
325
- // type F= ReplaceEntityNames<{
326
- // loadEntities: 1;
327
- // loadEntitiesSuccess: 2;
328
- // selectEntities: 3;
329
- // selectEntity: 4;
330
- // }, 'product','products'>;
331
- // const f: F = {};
332
- // f.
333
- // TODO clean up file
476
+ /**
477
+ * Helper function to create an implementation a TraitFactory
478
+ * @param f TraitFactory implementation
479
+ */
480
+ function createTraitFactory(f) {
481
+ return f;
482
+ }
334
483
 
335
484
  class TraitEffect {
336
485
  constructor(actions$, store) {
@@ -348,9 +497,9 @@ class TraitEffect {
348
497
  : resolvedEffects$;
349
498
  }
350
499
  }
351
- TraitEffect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitEffect, deps: [{ token: i1.Actions }, { token: i2.Store }], target: i0.ɵɵFactoryTarget.Injectable });
352
- TraitEffect.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitEffect });
353
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitEffect, decorators: [{
500
+ TraitEffect.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitEffect, deps: [{ token: i1.Actions }, { token: i2.Store }], target: i0.ɵɵFactoryTarget.Injectable });
501
+ TraitEffect.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitEffect });
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitEffect, decorators: [{
354
503
  type: Injectable
355
504
  }], ctorParameters: function () { return [{ type: i1.Actions }, { type: i2.Store }]; } });
356
505
  function getDestroyActionName(id) {
@@ -358,6 +507,7 @@ function getDestroyActionName(id) {
358
507
  }
359
508
 
360
509
  /**
510
+ * @ignore
361
511
  * @internal
362
512
  */
363
513
  const DISABLE_LOCAL_TRAIT_EFFECTS = new InjectionToken('disableLocalTraitEffects');
@@ -366,6 +516,18 @@ let id = 0;
366
516
  function uniqueComponentId() {
367
517
  return id++;
368
518
  }
519
+ /**
520
+ * Builds traitFactory and registers effects and reducers with
521
+ * a generated component id, returns build actions and selectors
522
+ * and a destroy method that will unergister the effects and reducers
523
+ * when called, and a addEffect which can be use to register extra effects
524
+ *
525
+ * Used inside TraitsLocalStore, can be used to create your
526
+ * own Component Service without extending TraitsLocalStore
527
+ * @param injector
528
+ * @param componentName
529
+ * @param traitFactory
530
+ */
369
531
  function buildLocalTraits(injector, componentName, traitFactory) {
370
532
  var _a;
371
533
  const reducers = injector.get(ReducerManager);
@@ -412,6 +574,67 @@ function buildLocalTraits(injector, componentName, traitFactory) {
412
574
  },
413
575
  };
414
576
  }
577
+ /**
578
+ * Class used to create local traits service, receives a trait factory, which will be
579
+ * built and its reducers and effect register using a dynamic id when the service is built
580
+ * and get destroyed when the onDestroy lifecycle method of the service is called, if the service
581
+ * has effects this.traits.addEffects(this) should be call in the constructor
582
+ *
583
+ * @example
584
+ * const productFeatureFactory = createEntityFeatureFactory(
585
+ * { entityName: 'product' },
586
+ * addLoadEntitiesTrait<Product>(),
587
+ * addSelectEntityTrait<Product>(),
588
+ * );
589
+ *
590
+ * Injectable()
591
+ * export class ProductsLocalTraits extends TraitsLocalStore<
592
+ * typeof productFeatureFactory
593
+ * > {
594
+ * loadProducts$ = createEffect(() =>
595
+ * this.actions$.pipe(
596
+ * ofType(this.localActions.loadProducts),
597
+ * switchMap(() =>
598
+ * //call your service to get the products data
599
+ * this.productService.getProducts().pipe(
600
+ * map((res) =>
601
+ * this.localActions.loadProductsSuccess({ entities: res.resultList })
602
+ * ),
603
+ * catchError(() => of(this.localActions.loadProductsFail()))
604
+ * )
605
+ * )
606
+ * )
607
+ * );
608
+ *
609
+ * constructor(injector: Injector, private productService: ProductService) {
610
+ * super(injector);
611
+ * this.traits.addEffects(this); // IMPORTANT! add this line if the service has effects
612
+ * }
613
+ *
614
+ * setup(): LocalTraitsConfig<typeof productFeatureFactory> {
615
+ * return {
616
+ * componentName: 'ProductsPickerComponent',
617
+ * traitsFactory: productFeatureFactory,
618
+ * };
619
+ * }
620
+ * }
621
+ *
622
+ * // use in component later
623
+ *
624
+ * Component({
625
+ * selector: 'some-component',
626
+ * template: `<div> some content</div> `,
627
+ * providers: [ProductsLocalTraits],
628
+ * changeDetection: ChangeDetectionStrategy.OnPush,
629
+ * })
630
+ * export class ProductSelectDialogComponent implements OnInit {
631
+ * constructor(private store: Store, private traits: ProductsLocalTraits) {}
632
+ *
633
+ * ngOnInit() {
634
+ * this.store.dispatch(this.traits.localActions.loadProducts());
635
+ * }
636
+ * }
637
+ */
415
638
  class TraitsLocalStore extends TraitEffect {
416
639
  constructor(injector) {
417
640
  super(injector.get(Actions), injector.get(Store));
@@ -425,9 +648,9 @@ class TraitsLocalStore extends TraitEffect {
425
648
  this.traits.destroy();
426
649
  }
427
650
  }
428
- TraitsLocalStore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitsLocalStore, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
429
- TraitsLocalStore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitsLocalStore });
430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: TraitsLocalStore, decorators: [{
651
+ TraitsLocalStore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitsLocalStore, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
652
+ TraitsLocalStore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitsLocalStore });
653
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: TraitsLocalStore, decorators: [{
431
654
  type: Injectable
432
655
  }], ctorParameters: function () { return [{ type: i0.Injector }]; } });
433
656
 
@@ -677,10 +900,10 @@ function invalidaSubKeys(state) {
677
900
 
678
901
  class CacheModule {
679
902
  }
680
- CacheModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: CacheModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
681
- CacheModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: CacheModule, imports: [i2.StoreFeatureModule] });
682
- CacheModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: CacheModule, providers: [], imports: [[StoreModule.forFeature('cache', cacheReducer)]] });
683
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: CacheModule, decorators: [{
903
+ CacheModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: CacheModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
904
+ CacheModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: CacheModule, imports: [i2.StoreFeatureModule] });
905
+ CacheModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: CacheModule, providers: [], imports: [[StoreModule.forFeature('cache', cacheReducer)]] });
906
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: CacheModule, decorators: [{
684
907
  type: NgModule,
685
908
  args: [{
686
909
  imports: [StoreModule.forFeature('cache', cacheReducer)],