    import CollectionProperty from 'f.lux/src/collection/CollectionProperty.js'

public class | source

# CollectionProperty

#### Extends:

Property → CollectionProperty

`CollectionProperty` provides a standard means for accessing remote data and was inspired by Backbone collections. The protocol for interacting with the data source is delegated to an endpoint so the same application logic can work with data from a RESTful api, graphql, local test data, or even an in-browser database like localforage. F.lux ships with support for two endpoints, RestEndpointProperty and PojoEndpointProperty.

F.lux ships with a example using collections in a todo application utilizing an in memory data source. The example uses a local data source to make setup dead simple while still demonstrating the basic features of creating and interacting with collections.

## Basic operations

- `add(state, mergeOp)`
- `all()`
- `clear()</li> <li>`create(model)`</li> <li>`destroy(id)`</li> <li>`fetch(filter, mergeOp)`</li> <li>`find(id)`</li> <li>`get(id)`</li> <li>`has(id)`</li> <li>`remove(id)`

## Utility functions

- `entries()`
- `every(iteratee, context)`
- `filter(iteratee, context)`
- `groupBy(callback, context)`
- `keys()`
- `map(iteratee, context)`
- `reduce(iteratee, acc, context)`
- `some(iteratee, context)`
- `sortBy(...iteratee)`
- `values()`

## Model access

Properties managed by a collection receive an f.lux accessor (`$()`) with additional capabilities related to the collection. The accessor class is $ShadowModelAccess.

- `collection()` - gets the Collection managing this model
- `destroy()` - permanently deletes the model from the collection using CollectionProperty#destroy
- `id()` - gets the ID used by the data source for tracking the model
- `isWaiting()` - is a network operation in progress associated with this model
- `isDirty()` - has the model been modified since it was last saved/retrieved
- `isNew()` - gets whether the model has yet to be written to the collection's endpoint
- `remove()` - removes the model from the collection using CollectionProperty#remove
- `save()` - save the model using CollectionProperty#save

## Paging

The collection provides redimentary paging support for potentially large collections. The current implementation simply grows the collection size wtih each call to `fetchNext()` and does not make any efforts to remove previous models. (A likely future enhancement)

- `fetchNext()` - gets the next group of models
- `isPaging()` - gets if a paging request is outstanding (only one paging request per collection allowed at one time)
- `hasMorePages()` - does the endpoint have additional models
- `nextOffset()` - gets the offset for the next paging request
- `resetPaging()` - resets the internal paging variables
- `setLimit()` - change the number of models requested with each `fetchNext()` request

## Endpoints

Collections represent a protocol independent means of managing persistent models that exist outside the application state. Endpoints implement the protocol connection to the data source. F.lux endpoints have been implemented for RESTful server apis, in-memory, GraphQL, Sqlite, and Couchbase. F.lux ships with support for RESTful servers and in-memory.

A simple, explicit example of creating a collection and assigning an endpoint:

    const rootProperty = store.root();
    const collection = new CollectionProperty(colType);
    const ep = new RestEndpointProperty.createFor("http://some-url.com/an-api");

    collection.setEndpoint(ep);

    root._keyed.addProperty("aCollection", collection);

The Todo Collection Example demonstrates a more typical example of setting up a collection.

#### See:

- RestEndpointProperty
- PojoEndpointProperty

## Query filters

Collection models are retrieved in full using CollectionProperty#fetch that has the following signature:

    fetch(filter=null, mergeOp=REPLACE_OPTION, replaceAll=true)

where:

- `filter` - a query filter object or `null` for no endpoint filtering
- `mergeOp` - one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.
- `replaceAll` - a boolean where `true` means replace the current colleciton models with the returned models.

The `filter` parameter is a specialized object generated by the endpoint method `queryBuilder()`. A query builder is specialized to the endpoint and expose the following methods:

- `equals(name, value)`
- `gt(name, value)`
- `gte(name, value)`
- `lt(name, value)`
- `lte(name, value)`

An example of using a query builder is:

    const qb = colleciton.endpoint.queryBuilder();

    qb.equals("name", "fred");

    collection.fetch(qb);

#### See:

- RestQueryBuilder
- PojoQueryBuilder

## Errors

Methods utilizing the collection endpoint are asynchronous and return a `Promise`. Errors generated during an endpoint operation reject using an `Error` with several specialized properties:

- `status` - an HTTP status code for the error type
- `endpointError` - the error object generated by the endpoint

## Auto-checkpointing

The `Property` class supports checkpointing state that can be reset at a later time using Property#resetToCheckpoint. Collections support setting an 'auto-checkpoint' flag that will result in managed models automatically setting a checkpoint on change. This handy for situations like a 'Cancel' button on a form where all changes need to be undone. The checkpoints are automatically cleared when a model is saved.

- `isAutocheckpoint()`
- `setAutocheckpoint(auto)`

## Middleware

A middleware operation is invoked before each asynchronous/network operation involving the endpoint. Middleware operations are functions with the following format

    function middleware(collectionShadow, collectionProperty, op): Promise

Middleware functions must return a `Promise` and are invoked in the order registered. A function generating an error will terminate the middleware chain and the collection operation will not be performed.

- `CreateOp` - invoked prior to create rquests
- `DestroyOp` - invoked prior to destroy rquests
- `FetchOp` - invoked prior to fetch rquests
- `FindOp` - invoked prior to find rquests
- `UpdateOp` - invoked prior to update rquests
- `` -

## Events

A colleciton is an Event Emitter and generates the following events:

- `ChangeEvent` - collection changes
- `DeletedEvent` - collection destroy() success
- `FetchedEvent` - collection fetch() success
- `FoundEvent` - collection find() success
- `ErrorEvent` - error during an operation
- `SavedEvent` - collection save() success

Events are can be utilized to handle authorization errors, offline support, logging, or debugging tools.

#### See:

- CollectionShadow
- ShadowModelAccess
- RestEndpointProperty
- PojoEndpointProperty
- RestQueryBuilder
- PojoQueryBuilder

## Static Method Summary

Static Public Methods
public static | createClass(shadowType: Object | CollectionShadow, typeCallback: function(type: StateType), initialState: Object): ObjectProperty Factory function for creating an `CollectionProperty` subclass. |
public static | defineType(PropClass: CollectionShadow, ShadowType: Object | CollectionShadow, typeCallback: function(type: StateType), initialState: Object): * Factory function for setting up the StateType `type` class variable with an appropriately configured intial state. |

## Constructor Summary

Public Constructor
public | constructor(stateType: *) |

## Member Summary

Public Members
public get | endpoint: Object: * Gets the endpoint for accessing the remote data source. |
public get | endpointId: string: * Gets the endpoint ID, which for RestEndpointProperty is its URL. |
public | pagingTime: * |
public get | size: * Gets the number of models contained in the collection. |

## Method Summary

Public Methods
public | addModel(state: object, mergeOp: string): * Synchronously adds a new model object to the collection. |
public | addModels(models: array, mergeOp: string, syncOp: boolean) Bulk adds multiple models. |
public | clean(json: *): * |
public | clearEndpoint() Removes the endpoint from the collection. |
public | create(model: Object): Promise Combines an CollectionProperty#add and CollectionProperty#save actions. |
public | destroy(id: *): Promise Permantently deletes the model with the endpoint and removes it from the collection. |
public | extractId(model: *): * Used by the private _shadow() method to get the id from the model JSON representation as returned by the subclass doXXX() apis. |
public | fetch(filter: *, mergeOp: string, replaceAll: boolean, callback: *): Promise Fetches all the models from the endpoint. |
public | fetchNext(mergeOp: string): Promise Fetches the next set of models from the endpoint. |
public | find(id: *): Promise Gets a model by ID. |
public | getModel(id: *): Object Gets a model by ID. |
public | getOfflineState(): Object this method is experimental. Gets an object capable of providing a persisted version of this collection. |
public | hasModel(id: *): boolean Gets if the collection contains a matching model. |
public | hasMorePages(state: *): * Gets if additional paging calls will return additional results. |
public | isAutocheckpoint(): boolean Sets whether auto-checkpointing is enabled. |
public | isConnected(): * Gets if the collection is active (has a shadow) and an endpoint. |
public | isFetching(): * Gets if a fetching operation that will replace ALL models is in progress. |
public | isNew(id: *): * Gets if a model has never been persisted to the endpoint. |
public | isNewModel(shadow: *): * Gets if a model shadow state model represents a model that has never been persisted to the endpoint. |
public | isPaging(state: *): * Gets if a paging operation (CollectionProperty#fetchNext) call is in progress. |
public | makeId(): string |
public | modelEntries(state: *): Array Gets an iterator with [ID, model] paris. |
public | modelKeys(state: *): Iterator Gets an iterator containing each model IDs. |
public | modelKeysArray(state: *): Array Gets an array containing each model iDs. |
public | modelValues(state: *): Iterator Gets an iterator containing each f.lux shadow state model. |
public | modelsArray(state: *): array Gets the shadow models currently managed by the collection. |
public | nextOffset(): * Gets the offset for the next paging request. |
public | remove(id: *) Synchronously removes the model from the collection without performing an endpoint operation. |
public | removeAllModels() Removes all models from the collection and marks the collection as having not synched with the endpoint. |
public | resetPaging() Resets all internal paging tracking variables but does not affect currently stored models. |
public | save(id: *, mergeOp: string): Promise Saves a model through the endpoint. |
public | setAutocheckpoint(auto: boolean) Sets whether auto-checkpointing should be enabled. |
public | setEndpoint(endPoint: *) Sets the CollectionProperty#endpoint. |
public | setIdName(idName: *) Sets the property name containing the model ID. |
public | setLimit(limit: number) Sets the number of models to request with each paging request. |
public | setModels(models: array, syncOp: boolean) Bulk replaces current models with an array of new models. |
public | setOfflineState(offline: Object) this method is experimental. Sets an object capable of providing a persisted version of this collection. |
public | use(op: *, mw: *) Registers collection middleware operation. |

## Inherited Summary

From class Property
public | [_ImplementationClass]: * |
public | [_ShadowClass]: * |
public | [_autoShadow]: * |
public | [_checkpoint]: {"data": *} |
public | [_impl]: * |
public | [_initialState]: * |
public | [_mixins]: *[] |
public | [_parent]: * |
public | [_pid]: * |
public | [_readonly]: * |
public | [_shader]: * |
public | [_stateType]: * |
public | [_store]: * |
public | $$(): Property Use this.$$() in shadow methods to get access to the property. |
public | autoShadow(): boolean Gets if autoshadowing is enabled for this property. |
public | checkpoint() Copies the current actual state for later reset using Property#resetToCheckpoint. |
public | clearCheckpoint() Clears an existing checkpoint created using Property#checkpoint. |
public | create$(impl: *): Access Creates the object to be assigned to the shadow.$ property. |
public | dotPath(): string Gets the path from root property using a dot (`.`) separator. |
public | getCheckpoint(): * Gets the checkpoint state previously recorded using Property#checkpoint. |
public | getInitialState(state: *): * Gets the initial state for a property at the beginning of the property mounting process. |
public | hasCheckpoint(): boolean Gets if an existing checkpoint has be created using Property#checkpoint. |
public | initialState(): * Gets the result from StateType#computeInitialState. |
public | isActive(): boolean Gets if the property is currently shadowing an actual state property. |
public | isIsolated(): boolean Gets if property is an actual isolated property managed by the store. |
public | isReadonly(): boolean Gets if the property allows for assignment through the shadow state, ie `todo.desc = "go skiing"`. |
public | isRoot(): boolean Gets if this is the shadow state root property. |
public | name(): string | number The property name by which this property is referenced by the Property.parent. |
public | nextState(): * Gets what the actual state for this property will be after the Store updates all pending actions. |
public | owner(): Property Gets the object containing or managing this property. |
public | parent(): Property Gets the parent property. |
public | parentShadow(): Shadow Gets the parent's shadow property. |
public | path(): [] Gets the Property#name components from the root property to this property. |
public | pid(): number Gets the unique f.lux ID for this property. |
public | propertyChildInvalidated(childProperty: Property, sourceProperty: Property) A child property or one of its descendents wil be changing state. |
public | propertyDidShadow() Invoked by the f.lux shadowing process after a property initially shadows a state property. |
public | propertyDidUpdate() Invoked by the f.lux shadowing process after a property is reshadowed. |
public | propertyWillShadow() Invoked by the f.lux shadowing process just before a property initially shadows a state property. |
public | propertyWillUnshadow() Invoked by the f.lux shadowing process just before a property will be removed from the shadow state. |
public | resetToCheckpoint() Replaces the current property state with a checkpoint state previously recorded using Property#checkpoint. |
public | root(): Property Gets the shadow state root property for the Store managing this property. |
public | rootShadow(): Shadow Gets the root shadow state for the Store managing this property. |
public | setAutoshadow(auto: boolean): * Sets the auto shadow property flag. |
public | setImplementationClass(ImplClass: *) |
public | setInitialState(state: *): Property Explicitly sets an initial state that will be used if the state tree does not have a value for this property. |
public | setReadonly(readonly: *) Sets the readonly flag which will prevent an assignment from changing the value. |
public | setShadowClass(ShadowClass: Shadow) Sets the class to be used for the shadow api |
public | shader(state: *): * Gets the Shader instance for this property. |
public | shadowClass(): * Returns the Shadow subclass used to virtualize the state property. |
public | slashPath(): string Gets the path from root property using a slash (`/`) separator. |
public | state(): * Gets the actual state being shadowed. |
public | stateType(): * Gets the StateType used for creating this property. |
public | store(): * Gets the {@Link Store} containing the application state. |
public | touch() Triggers a reshadow of the properties shadow state. |
public | typeName(): * Gets this property's StateType.typeName value. |
public | update(callback: function) Makes changes to the next proeprty state. |

## Static Public Methods

### public static createClass(shadowType: Object | CollectionShadow, typeCallback: function(type: StateType), initialState: Object): ObjectProperty source

Factory function for creating an `CollectionProperty` subclass. The generated class will have the `type` StateType descriptor set upon return.

Example usage:

    class SomeShadow extends CollectionShadow {
    // definition here
    }

    export default CollectionProperty.createClass(SomeShadow, type => {
    // configure type variable
    });

#### Params:

Name | Type | Attribute | Description

shadowType

Object | CollectionShadow

- optional
- default: {}

`Shadow` subclass or object literal api definition. If object literal specified, each property and function is mapped onto a Shadow subclass.

typeCallback

function(type: StateType)

- optional

a callback function that will be passed the StateType spec for additional customization, such as setting autoshadow, initial state, or readonly.

initialState

Object

- optional

={} - the initial state for the new property.

#### Return:

ObjectProperty | newly defined `ObjectProperty` subclass.

### public static defineType(PropClass: CollectionShadow, ShadowType: Object | CollectionShadow, typeCallback: function(type: StateType), initialState: Object): * source

Factory function for setting up the StateType `type` class variable with an appropriately configured intial state.

Example usage:

    export default class TodosCollection extends CollectionProperty {
    // implement property here
    }

    class TodosShadow extends CollectionShadow {
    // implement shadow api here
    }

    ObjectProperty.defineType(TodosCollection, TodosShadow, type => {
    // configure type variable
    });

#### Params:

Name | Type | Attribute | Description
PropClass | CollectionShadow |  | `CollectionShadow` subclass

ShadowType

Object | CollectionShadow

- optional

Shadow` subclass or object literal api definition. If object literal specified, each property and function is mapped onto a Shadow subclass.

typeCallback

function(type: StateType)

- optional

a callback function that will be passed the StateType spec for additional customization, such as setting autoshadow, initial state, or readonly.

initialState

Object

- optional
- default: {}

the initial state for the new property.

#### Return:

*

## Public Constructors

### public constructor(stateType: *) source

If a StateType is not passed to this constructor then one is located using StateType.from thus ensuring the f.lux shadowing process is defined for this property.

#### Override:

Property#constructor

#### Params:

Name | Type | Attribute | Description
stateType | * |  |

## Public Members

### public get endpoint: Object: * source

Gets the endpoint for accessing the remote data source.

#### Return:

Object

### public get endpointId: string: * source

Gets the endpoint ID, which for RestEndpointProperty is its URL.

#### Return:

string

### public pagingTime: * source

### public get size: * source

Gets the number of models contained in the collection.

## Public Methods

### public addModel(state: object, mergeOp: string): * source

Synchronously adds a new model object to the collection. Call `model.$().save()` to persist the newly added object.

#### Params:

Name | Type | Attribute | Description
state | object |  | the json model to add to the collection

mergeOp

string

- optional
- default: REPLACE_OPTION

one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.

#### Return:

* | the object's ID. And ID is assigned if the 'id' parameter was not set and it could not be found in the `state` parameter.

### public addModels(models: array, mergeOp: string, syncOp: boolean) source

Bulk adds multiple models. Models must have an ID as it is assumed they have been previously saved.

#### Params:

Name | Type | Attribute | Description
models | array |  | array of model values

mergeOp

string

- optional
- default: REPLACE_OPTION

one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.

syncOp

boolean

- optional
- default: true

sets the `synced` flag to true if this parameter is true

### public clean(json: *): * source

#### Params:

Name | Type | Attribute | Description
json | * |  |

#### Return:

*

### public clearEndpoint() source

Removes the endpoint from the collection. This has the side-effect of clearing the mdoels.

### public create(model: Object): Promise source

Combines an CollectionProperty#add and CollectionProperty#save actions.

#### Params:

Name | Type | Attribute | Description
model | Object |  | the json data

#### Return:

Promise | resolves with the f.lux shadow state for the new model

### public destroy(id: *): Promise source

Permantently deletes the model with the endpoint and removes it from the collection.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model ID to delete

#### Return:

Promise | resolves with the ID for the removed mdoel

### public extractId(model: *): * source

Used by the private _shadow() method to get the id from the model JSON representation as returned by the subclass doXXX() apis. The default implementation simply returns the 'id' model property.

#### Params:

Name | Type | Attribute | Description
model | * |  |

#### Return:

*

### public fetch(filter: *, mergeOp: string, replaceAll: boolean, callback: *): Promise source

Fetches all the models from the endpoint.

#### Params:

Name | Type | Attribute | Description

filter

*

- optional
- default: null

filter object created using the endpoint.

mergeOp

string

- optional
- default: REPLACE_OPTION

one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.

replaceAll

boolean

- optional
- default: true

set to `true` replace any current models by the ones returned by the endpoint.

callback | * |  | invoked before retrieved models are process or in case of an error

#### Return:

Promise | resolves with the json models from the endpoint

### public fetchNext(mergeOp: string): Promise source

Fetches the next set of models from the endpoint. This method differs from CollectionProperty#fetch by passing `offset` and `limit` filter criteria to the endpoint.

#### Params:

Name | Type | Attribute | Description

mergeOp

string

- optional
- default: REPLACE_OPTION

one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.

#### Return:

Promise | resolves with a single argument of an array of model json objects as returned from the endpoint.

### public find(id: *): Promise source

Gets a model by ID. The method looks for a matching model in the collection. If one is not found then one is requested from the endpoint.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model ID

#### Return:

Promise | reolves with the model or undefined if one is not found

### public getModel(id: *): Object source

Gets a model by ID. The method looks for a matching model in the collection and never looks for one remotely through the endpoint.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model ID

#### Return:

Object | the model or undefined if one is not found

### public getOfflineState(): Object source

this method is experimental.

Gets an object capable of providing a persisted version of this collection.

#### Return:

Object

### public hasModel(id: *): boolean source

Gets if the collection contains a matching model.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model ID

#### Return:

boolean

### public hasMorePages(state: *): * source

Gets if additional paging calls will return additional results.

#### Params:

Name | Type | Attribute | Description

state

*

- optional

#### Return:

*

### public isAutocheckpoint(): boolean source

Sets whether auto-checkpointing is enabled.

#### Return:

boolean

### public isConnected(): * source

Gets if the collection is active (has a shadow) and an endpoint.

#### Return:

*

### public isFetching(): * source

Gets if a fetching operation that will replace ALL models is in progress.

#### Return:

*

### public isNew(id: *): * source

Gets if a model has never been persisted to the endpoint.

#### Params:

Name | Type | Attribute | Description
id | * |  |

#### Return:

*

### public isNewModel(shadow: *): * source

Gets if a model shadow state model represents a model that has never been persisted to the endpoint.

#### Params:

Name | Type | Attribute | Description
shadow | * |  |

#### Return:

*

### public isPaging(state: *): * source

Gets if a paging operation (CollectionProperty#fetchNext) call is in progress.

#### Params:

Name | Type | Attribute | Description

state

*

- optional

#### Return:

*

### public makeId(): string source

#### Return:

string

### public modelEntries(state: *): Array source

Gets an iterator with [ID, model] paris.

#### Params:

Name | Type | Attribute | Description
state | * |  |

#### Return:

Array

### public modelKeys(state: *): Iterator source

Gets an iterator containing each model IDs.

#### Params:

Name | Type | Attribute | Description

state

*

- optional

#### Return:

Iterator

### public modelKeysArray(state: *): Array source

Gets an array containing each model iDs.

#### Params:

Name | Type | Attribute | Description
state | * |  |

#### Return:

Array

### public modelValues(state: *): Iterator source

Gets an iterator containing each f.lux shadow state model.

#### Params:

Name | Type | Attribute | Description

state

*

- optional

#### Return:

Iterator

### public modelsArray(state: *): array source

Gets the shadow models currently managed by the collection.

#### Params:

Name | Type | Attribute | Description
state | * |  |

#### Return:

array | all models being managed by the collection

### public nextOffset(): * source

Gets the offset for the next paging request.

#### Return:

*

### public remove(id: *) source

Synchronously removes the model from the collection without performing an endpoint operation.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model id or cid

### public removeAllModels() source

Removes all models from the collection and marks the collection as having not synched with the endpoint.

### public resetPaging() source

Resets all internal paging tracking variables but does not affect currently stored models.

### public save(id: *, mergeOp: string): Promise source

Saves a model through the endpoint.

#### Params:

Name | Type | Attribute | Description
id | * |  | the model id or cid

mergeOp

string

- optional
- default: REPLACE_OPTION

one of `DEFAULTS_OPTION`, `MERGE_OPTION`, or `REPLACE_OPTION` and specifies how to combine an existing model with a matching ID with a newly retrieved model.

#### Return:

Promise | resolves to the f.lux shadow state for the saved model

### public setAutocheckpoint(auto: boolean) source

Sets whether auto-checkpointing should be enabled.

#### Params:

Name | Type | Attribute | Description
auto | boolean |  | `true` to enable.

### public setEndpoint(endPoint: *) source

Sets the CollectionProperty#endpoint.

#### Params:

Name | Type | Attribute | Description
endPoint | * |  |

### public setIdName(idName: *) source

Sets the property name containing the model ID. Default is `id`.

#### Params:

Name | Type | Attribute | Description
idName | * |  |

### public setLimit(limit: number) source

Sets the number of models to request with each paging request. The default paging size is 50.

#### Params:

Name | Type | Attribute | Description
limit | number |  |

### public setModels(models: array, syncOp: boolean) source

Bulk replaces current models with an array of new models.

#### Params:

Name | Type | Attribute | Description
models | array |  | array of model values

syncOp

boolean

- optional
- default: true

sets the `synced` flag to true if this parameter is true

### public setOfflineState(offline: Object) source

this method is experimental.

Sets an object capable of providing a persisted version of this collection. The object must minimally expose a single method with the form:

    function restore()

Method sets the collection state for offline access. Typically invoked by application logic after a failed `fetch()` to the endpoint.

An object is used as the offline state management entity because it will normally perform other duties such as registering for ChangeEvent to persistently store collection state on changes and support deleting previous backups

#### Params:

Name | Type | Attribute | Description
offline | Object |  | the object containing the `restore()` function.

### public use(op: *, mw: *) source

Registers collection middleware operation. A middleware operation is invoked before each asynchronous/ network operation. Middleware operations are functions with the following format:

    function mwCallback(collectionShadow, collectionProperty)

Middleware functions must return a promise and are invoked in the order registered. A function generating an error will terminate the middleware chain and the collection operation will not be performed.

#### Params:

Name | Type | Attribute | Description
op | * |  |
mw | * |  |