@@ -3,92 +3,62 @@ import LoadingStoreCollection from './LoadingStoreCollection'
33import Resource from './interfaces/Resource'
44import Collection from './interfaces/Collection'
55import { Link } from './interfaces/StoreData'
6- import ApiActions from './interfaces/ApiActions'
7- import { InternalConfig } from './interfaces/Config'
6+ import StoreValue from './StoreValue'
87
9- // Check Typescript Handbook fore more explanation of mixin pattern
10- // https://www.typescriptlang.org/docs/handbook/mixins.html
11-
12- // Now we use a generic version which can apply a constraint on
13- // the class which this mixin is applied to
14- // eslint-disable-next-line @typescript-eslint/no-explicit-any
15- type GConstructor < T > = new ( ...args : any [ ] ) => T ;
16-
17- // Ensure property _storeData.items exist
18- type HasStoreData = GConstructor < { _storeData : { items : Array < Link > } } > ;
19-
20- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
21- function HasItems < TBase extends HasStoreData > ( Base : TBase , apiActions : ApiActions , config : InternalConfig ) {
22- /**
23- * Filter out items that are marked as deleting (eager removal)
24- */
25- function filterDeleting ( array : Array < Resource > ) : Array < Resource > {
26- return array . filter ( entry => ! entry . _meta . deleting )
27- }
28-
29- /**
30- * Replace each item in array with a proper StoreValue (or LoadingStoreValue)
31- */
32- function replaceEntityReferences ( array : Array < Link > ) : Array < Resource > {
33- return array
34- . filter ( entry => isEntityReference ( entry ) )
35- . map ( entry => apiActions . get ( entry . href ) )
36- }
8+ /**
9+ * Filter out items that are marked as deleting (eager removal)
10+ */
11+ function filterDeleting ( array : Array < Resource > ) : Array < Resource > {
12+ return array . filter ( entry => ! entry . _meta . deleting )
13+ }
3714
15+ class HasItems extends StoreValue {
3816 /**
39- * Returns true if any of the items within 'array' is not yet known to the API (meaning it has never been loaded)
40- */
41- function containsUnknownEntityReference ( array : Array < Link > ) : boolean {
42- return array . some ( entry => isEntityReference ( entry ) && apiActions . isUnknown ( entry . href ) )
43- }
44-
45- const HasItems = class extends Base {
46- /**
4717 * Get items excluding ones marked as 'deleting' (eager remove)
4818 * The items property should always be a getter, in order to make the call to mapArrayOfEntityReferences
4919 * lazy, since that potentially fetches a large number of entities from the API.
5020 */
51- public get items ( ) : Array < Resource > {
52- return filterDeleting ( this . _mapArrayOfEntityReferences ( this . _storeData . items ) )
53- }
21+ public get items ( ) : Array < Resource > {
22+ return filterDeleting ( this . _mapArrayOfEntityReferences ( this . _storeData . items ) )
23+ }
5424
55- /**
25+ /**
5626 * Get all items including ones marked as 'deleting' (lazy remove)
5727 */
58- public get allItems ( ) : Array < Resource > {
59- return this . _mapArrayOfEntityReferences ( this . _storeData . items )
60- }
28+ public get allItems ( ) : Array < Resource > {
29+ return this . _mapArrayOfEntityReferences ( this . _storeData . items )
30+ }
6131
62- /**
32+ /**
6333 * Returns a promise that resolves to the collection object, once all items have been loaded
6434 */
65- public $loadItems ( ) :Promise < Collection > {
66- return this . _itemLoader ( this . _storeData . items )
67- }
35+ public $loadItems ( ) :Promise < Collection > {
36+ return this . _itemLoader ( this . _storeData . items )
37+ }
6838
69- /**
39+ /**
7040 * Returns a promise that resolves to the collection object, once all items have been loaded
7141 */
72- _itemLoader ( array : Array < Link > ) : Promise < Collection > {
73- if ( ! containsUnknownEntityReference ( array ) ) {
74- return Promise . resolve ( this as unknown as Collection ) // we know that this object must be of type Collection
75- }
42+ private _itemLoader ( array : Array < Link > ) : Promise < Collection > {
43+ if ( ! this . _containsUnknownEntityReference ( array ) ) {
44+ return Promise . resolve ( this as unknown as Collection ) // we know that this object must be of type Collection
45+ }
7646
77- // eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
78- if ( config . avoidNPlusOneRequests ) {
79- return apiActions . reload ( this as unknown as Collection ) as Promise < Collection > // we know that reload resolves to a type Collection
47+ // eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
48+ if ( this . config . avoidNPlusOneRequests ) {
49+ return this . apiActions . reload ( this as unknown as Collection ) as Promise < Collection > // we know that reload resolves to a type Collection
8050
8151 // no eager loading: replace each reference (Link) with a StoreValue (Resource)
82- } else {
83- const arrayWithReplacedReferences = replaceEntityReferences ( array )
52+ } else {
53+ const arrayWithReplacedReferences = this . _replaceEntityReferences ( array )
8454
85- return Promise . all (
86- arrayWithReplacedReferences . map ( entry => entry . _meta . load )
87- ) . then ( ( ) => this as unknown as Collection ) // we know that this object must be of type Collection
88- }
55+ return Promise . all (
56+ arrayWithReplacedReferences . map ( entry => entry . _meta . load )
57+ ) . then ( ( ) => this as unknown as Collection ) // we know that this object must be of type Collection
8958 }
59+ }
9060
91- /**
61+ /**
9262 * Given an array, replaces any entity references in the array with the entity loaded from the Vuex store
9363 * (or from the API if necessary), and returns that as a new array. In case some of the entity references in
9464 * the array have not finished loading yet, returns a LoadingStoreCollection instead.
@@ -98,25 +68,38 @@ function HasItems<TBase extends HasStoreData> (Base: TBase, apiActions: ApiActio
9868 * @returns array the new array with replaced items, or a LoadingStoreCollection if any of the array
9969 * elements is still loading.
10070 */
101- _mapArrayOfEntityReferences ( array : Array < Link > ) : Array < Resource > {
102- if ( ! containsUnknownEntityReference ( array ) ) {
103- return replaceEntityReferences ( array )
104- }
71+ private _mapArrayOfEntityReferences ( array : Array < Link > ) : Array < Resource > {
72+ if ( ! this . _containsUnknownEntityReference ( array ) ) {
73+ return this . _replaceEntityReferences ( array )
74+ }
10575
106- const itemsLoaded = this . _itemLoader ( array ) . then ( ( ) => replaceEntityReferences ( array ) )
76+ const itemsLoaded = this . _itemLoader ( array ) . then ( ( ) => this . _replaceEntityReferences ( array ) )
10777
108- // eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
109- if ( config . avoidNPlusOneRequests ) {
110- return LoadingStoreCollection . create ( itemsLoaded )
78+ // eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
79+ if ( this . config . avoidNPlusOneRequests ) {
80+ return LoadingStoreCollection . create ( itemsLoaded )
11181
11282 // no eager loading: replace each reference (Link) with a StoreValue (Resource)
113- } else {
114- return LoadingStoreCollection . create ( itemsLoaded , replaceEntityReferences ( array ) )
115- }
83+ } else {
84+ return LoadingStoreCollection . create ( itemsLoaded , this . _replaceEntityReferences ( array ) )
11685 }
11786 }
11887
119- return HasItems
88+ /**
89+ * Replace each item in array with a proper StoreValue (or LoadingStoreValue)
90+ */
91+ private _replaceEntityReferences ( array : Array < Link > ) : Array < Resource > {
92+ return array
93+ . filter ( entry => isEntityReference ( entry ) )
94+ . map ( entry => this . apiActions . get ( entry . href ) )
95+ }
96+
97+ /**
98+ * Returns true if any of the items within 'array' is not yet known to the API (meaning it has never been loaded)
99+ */
100+ private _containsUnknownEntityReference ( array : Array < Link > ) : boolean {
101+ return array . some ( entry => isEntityReference ( entry ) && this . apiActions . isUnknown ( entry . href ) )
102+ }
120103}
121104
122105export default HasItems
0 commit comments