Skip to content

Commit

Permalink
Merge pull request #23 from XbyOrange/release-v.1.2.0
Browse files Browse the repository at this point in the history
Release v.1.2.0
  • Loading branch information
javierbrea authored Oct 14, 2019
2 parents 239a3e8 + b575d93 commit f4aee87
Show file tree
Hide file tree
Showing 48 changed files with 2,934 additions and 432 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"parser": "flow"
}
],
"no-undef": "error",
"no-unused-vars": ["error", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }]
},
"extends": ["prettier"],
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Removed
### BREAKING CHANGES

## [TO BE DEPRECATED]
- Last argument of Selectors will stop being assigned as "defaultValue". To define default value, it will be mandatory to pass an options object as last argument, containing a "defaultValue" property.

## [1.2.0] - 2019-10-14
### Added
- Accept options object in Origin constructor as last argument.
- Assign to the `_id` private property the value received in new option "uuid", when received.
- Last argument in Selectors now can be an object containing "defaultValue" and/or "uuid" options.
- Add "sources" handler for managing all instantiated mercury sources as a group.
- Add "config" method to Origin and sources handlers. From now, all Origin implementations can define its own `_config` method, which will be called with the resultant config each time the "config" method is called.

### Changed
- `_id` private property now is a hash of default id and default value (if no "uuid" option is received)
- Objects without query now will emit "undefined" as "_queryId" property in "cleanAny" events, instead of "null".

### Fixed
- Emit `_root` property on cleanAny events of Selectors.

## [1.1.0] - 2019-06-25
### Added
- Expose `_root` property in queried instances to allow identify the root instance.
Expand Down
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Provides:
* [Api][mercury-api-url]
* [Memory Storage][mercury-memory-url]
* [Browser Local Storage][mercury-browser-storage-url]
* [Broswer Session Storage][mercury-browser-storage-url]
* [Browser Session Storage][mercury-browser-storage-url]
* [Prismic CMS][mercury-prismic-url]
* __"Selector"__ constructor for combining or transforming the result of one or many origins.
* __Declarative__. Declare which Origins your Selector needs to consume. Mercury will do the rest for you.
Expand All @@ -38,6 +38,8 @@ Provides:
* __Switchable__. Consumed "source" can be changed programatically.
* __Parallellizable__. Can fetch data from declared sources in series or in parallel.
* __Queryable__. Queries can be applied as in Origins. You can pass the `query` data to sources, or use it in the `parser` function, after all related sources data have been fetched.
* __"sources"__ singleton containing methods for managing all created mercury sources at a time.
* __Tags__ Mercury instances can be tagged to create "management" groups. "Cleaning" cache of all mercury sources tagged with "api" tag calling to a single method is easy, for example.

## Install

Expand All @@ -48,7 +50,7 @@ npm i @xbyorange/mercury --save
## A simple example

```js
import { Selector } from "@xbyorange/mercury";
import { Selector, sources } from "@xbyorange/mercury";
import { Api } from "@xbyorange/mercury-api";

const booksCollection = new Api("http://api.library.com/books");
Expand All @@ -67,6 +69,8 @@ const booksWithAuthors = new Selector(
// Each book now includes an "authorName" property.
const results = await booksWithAuthors.read();

// Clean cache of books, authors, and booksWithAuthors at a time.
sources.clean();
```

> This example uses the Api origin, which is not distributed in this package, but can clearly illustrate the usage of an Origin, and the intention of the library.
Expand Down Expand Up @@ -114,6 +118,28 @@ Read the full [Selector API documentation](docs/selector/api.md).

Some utilities are provided to make easier the task of testing Selectors. Please red the [testing selectors docs](docs/selector/testing.md).

## Sources

All created Mercury origins or selectors are registered in the "sources" object, which provides methods for managing them all together, or by groups based in tags.

### A simple example

```js
import { sources } from "@xbyorange/mercury";

sources.clean();

sources.getByTag("need-auth").config({
headers: {
"authentication": "foo"
}
})
```

### Api

Read the full [sources API documentation](docs/sources/api.md).

## Usage with frameworks

### React
Expand Down
33 changes: 18 additions & 15 deletions docs/origin/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,29 @@ To create a new `Origin`, you should extend from the Mercury `Origin` Class, def

If you don't define one of this methods, the correspondant CRUD method will not be available in the resultant Origin.

The Constructor requires two arguments. Call `super` from your own constructor, passing:
* `super([id, defaultValue])`
* Arguments:
* `id` Used for debugging purposes.
* `defaultValue` Resultant origin will have this value in the `value` property until data is fetched.
Call `super` from your own constructor, passing:
* `super([id, defaultValue, options])`
* Arguments:
* `defaultId` Used for debugging purposes. The `_id` of the resultant source will be a hash calculated using this default id and default value.
* `defaultValue` Resultant origin will have this value in the `value` property until data is fetched.
* `options` Object containing another options, such as:
* `uuid` If provided, the resultant instance will have this property as `_id`. It will not be "hashed".
* `tags` Tags to be assigned to the instance when created. Tags are used by "sources" handler. For further info [read the `sources` documentation](../sources/api.md).

Crud methods will receive two arguments:

* `_read([query, extraParams])`
* Arguments:
* `query` If origin is queried, you will receive here the current query.
* `extraParams` Extra data passed as argument when the method is invoked.
* Returns: `<Promise>`
* Arguments:
* `query` If origin is queried, you will receive here the current query.
* `extraParams` Extra data passed as argument when the method is invoked.
* Returns: `<Promise>`

Available methods for internal usage:

* `this._cache` Use built-in cache to provide cache to your Origin.
* `this._cache.set(query, value)`. Set cache for an specific query. Cached objects should be Promises, in order to provide cache too for parallel invokations.
* `this._cache.get(query)`. Returns cache for an specific query.
* `this._cache.clean([query])`. Clean cache of an specific query. Cleans all caches if no query is provided.
* `this._cache.set(query, value)`. Set cache for an specific query. Cached objects should be Promises, in order to provide cache too for parallel invokations.
* `this._cache.get(query)`. Returns cache for an specific query.
* `this._cache.clean([query])`. Clean cache of an specific query. Cleans all caches if no query is provided.

#### Example

Expand All @@ -34,8 +37,8 @@ import { Origin } from "@xbyorange/mercury";
import requestPromise from "request-promise";

export class Request extends Origin {
constructor(url, options) {
super(url, options.defaultValue);
constructor(url, options = {}) {
super(url, options.defaultValue, options.uuid);
this._url = url;
}

Expand All @@ -54,4 +57,4 @@ export class Request extends Origin {
return request;
}
}
```
```
2 changes: 1 addition & 1 deletion docs/origin/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ booksCollection.onCleanAny(cleanDetails => {

```

> Use the `removeCleanAnyListener` to remove an specific callback.
> Use the `removeCleanAnyListener` to remove an specific callback.
128 changes: 65 additions & 63 deletions docs/selector/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,76 @@

#### Constructor

* `const selector = new Selector(sources, parserCallback(sourcesResults[, currentQuery]), [defaultValue])`
* Arguments
* sources - `<source object or Array of sources objects>`
* source object - `<source instance, or customSourceReader object>`
* source instance - `<instance of an Origin or Selector>` Origin or Selector to read.
* customSourceReader - `<Object>` with next properties:
* `source`: `<instance of an Origin or Selector>` Origin or Selector to read.
* `query`: `<Function>` `query: (currentQuery[, previousSourcesResults])`. Query callback.
* Arguments:
* currentQuery - `<Any>` Selector current query.
* previousSourcesResults - `<Array of Any>` Array containing results of all previously fetched sources in series.
* Returns:
* `<Any>` Result of this callback will be passed as `query` to the source.
* `catch`: `<Function>` `catch: (error[, currentQuery])`.
* Arguments:
* error - `<Error>` Error thrown by the read method of the source.
* currentQuery - `<Any>` Selector current query.
* Returns:
* `<Error>` - Source will throw this error.
* `<Any>` - Source will return this value instead of error.
* `<source instance>` - The `read` method of the returned source instance will be called, and returned result will be assigned as value of the current source (Allows to switch to another source if first returns an error)
* Array of source objects - `<Array of <source object>>` Provided sources will be fetched in parallel.
* parserCallback - `<Function>`
* Arguments:
* sourcesResults - `<Any>` - Results returned by the `read` method of the sources.
* currentQuery - `<Any>` Selector current query.
* Returns:
* Result data - `<Any>`
* `<Promise>` - The result of the returned Promise will be returned as result data.
* `<source instance>` - If another source instance is returned, it will be called with same method and data than Selector was.
* defaultValue - `<Any>` Default value to return until real data is returned.
* `const selector = new Selector(source, source, parserCallback(sourcesResults[, currentQuery]), [options])`
* Arguments
* sources - `<source object or Array of sources objects>`
* source object - `<source instance, or customSourceReader object>`
* source instance - `<instance of an Origin or Selector>` Origin or Selector to read.
* customSourceReader - `<Object>` with next properties:
* `source`: `<instance of an Origin or Selector>` Origin or Selector to read.
* `query`: `<Function>` `query: (currentQuery[, previousSourcesResults])`. Query callback.
* Arguments:
* currentQuery - `<Any>` Selector current query.
* previousSourcesResults - `<Array of Any>` Array containing results of all previously fetched sources in series.
* Returns:
* `<Any>` Result of this callback will be passed as `query` to the source.
* `catch`: `<Function>` `catch: (error[, currentQuery])`.
* Arguments:
* error - `<Error>` Error thrown by the read method of the source.
* currentQuery - `<Any>` Selector current query.
* Returns:
* `<Error>` - Source will throw this error.
* `<Any>` - Source will return this value instead of error.
* `<source instance>` - The `read` method of the returned source instance will be called, and returned result will be assigned as value of the current source (Allows to switch to another source if first returns an error)
* Array of source objects - `<Array of <source object>>` Provided sources will be fetched in parallel.
* parserCallback - `<Function>`
* Arguments:
* sourcesResults - `<Any>` - Results returned by the `read` method of the sources.
* currentQuery - `<Any>` Selector current query.
* Returns:
* Result data - `<Any>`
* `<Promise>` - The result of the returned Promise will be returned as result data.
* `<source instance>` - If another source instance is returned, it will be called with same method and data than Selector was.
* options - `<Object>`
* defaultValue - `<Any>` Default value to return until real data is returned.
* uuid - `<String>` Custom uuid to be defined as selector "_id"

#### Instance

* read `selector.read()`
* Statics:
* error - `<Error>` If read method returns an error, it will be accessible at this property.
* loading - `<Boolean>` Will be true while Selector read is in progress.
* value - `<Any>` Value returned by `read` method.
* Returns
* `<Any>` - Result of the parser function.
* Statics:
* error - `<Error>` If read method returns an error, it will be accessible at this property.
* loading - `<Boolean>` Will be true while Selector read is in progress.
* value - `<Any>` Value returned by `read` method.
* Returns
* `<Any>` - Result of the parser function.
* create, update, delete `selector.create(data)` These methods can be used only when Selector returns another source.
* Statics:
* error - `<Error>` If read method returns an error, it will be accessible at this property.
* loading - `<Boolean>` Will be true while Selector read is in progress.
* value - `<Any>` Value returned by `read` method.
* Arguments
* data - `<Any>` Data that will be passed to the correspondant create, update or delete method of the returned source.
* Returns
* `<Any>` - Result of the correspondant method of returned source.
* Statics:
* error - `<Error>` If read method returns an error, it will be accessible at this property.
* loading - `<Boolean>` Will be true while Selector read is in progress.
* value - `<Any>` Value returned by `read` method.
* Arguments
* data - `<Any>` Data that will be passed to the correspondant create, update or delete method of the returned source.
* Returns
* `<Any>` - Result of the correspondant method of returned source.
* clean `selector.clean([query])`
* Arguments
* query - `<Any>` Any object, string, array etc. for quering the source.
* Returns
* `<undefined>` - Selector instance cache corresponding to the provided query will be cleaned.
* Arguments
* query - `<Any>` Any object, string, array etc. for quering the source.
* Returns
* `<undefined>` - Selector instance cache corresponding to the provided query will be cleaned.
* query `selector.query([query])`
* Arguments
* query - `<Any>` Any object, string, array etc. for quering the source.
* Returns
* `<selector instance>` - Will return a selector instance unique for the query provided. Returned instances will be the same if query is the same.
* Arguments
* query - `<Any>` Any object, string, array etc. for quering the source.
* Returns
* `<selector instance>` - Will return a selector instance unique for the query provided. Returned instances will be the same if query is the same.
* addCustomQueries `selector.addCustomQueries(customQueryObject)`
* Aliases
* addCustomQuery `selector.addCustomQuery({ queryName: queryCallback(query)})`
* Arguments
* customQueryObject - `<Object>` containing properties:
* [key] - `<String>` Key will be used as name of the new selector method that will execute the custom query.
* queryCallback - `<Function>`
* Arguments
* query - `<Any>` Query provided by the user when using custom query method.
* Returns
* currentQuery - `<Any>` Query that will be used as current query, and passed to the CRUD methods when executed.
* Aliases
* addCustomQuery `selector.addCustomQuery({ queryName: queryCallback(query)})`
* Arguments
* customQueryObject - `<Object>` containing properties:
* [key] - `<String>` Key will be used as name of the new selector method that will execute the custom query.
* queryCallback - `<Function>`
* Arguments
* query - `<Any>` Query provided by the user when using custom query method.
* Returns
* currentQuery - `<Any>` Query that will be used as current query, and passed to the CRUD methods when executed.
2 changes: 1 addition & 1 deletion docs/selector/asynchronous-mutable-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ console.log(await booksWithAuthors.read()) // value returned by parser function.
console.log(books.read.loading) // false
console.log(books.read.value) // value returned by parser function.

```
```
2 changes: 1 addition & 1 deletion docs/selector/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ booksWithAuthors.clean();

await booksWithAuthors.read(); // Selector will be executed again

```
```
8 changes: 5 additions & 3 deletions docs/selector/default-value.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Default values

Define a default value for the Selector as last argument. Selector `value` property will have that value until real value is ready
Define a default value for the Selector using options in last argument. Selector `value` property will have that value until real value is ready

```js
const booksAndAuthors = new Selector(
Expand All @@ -9,7 +9,9 @@ const booksAndAuthors = new Selector(
books: booksAndAuthors[0],
authors: booksAndAuthors[1]
}),
[]
{
defaultValue: []
}
);
console.log(booksAndAuthors.read.value); // []
```
```
2 changes: 1 addition & 1 deletion docs/selector/parallel-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ const booksWithAuthors = new Selector(
// Now books and authors fetchs are executed in parallel
const results = await booksWithAuthors.read();

```
```
2 changes: 1 addition & 1 deletion docs/selector/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ const mySelector = new Selector({

```js
expect(mySelector.test.selector(["foo"])).toEqual("foo");
```
```
Loading

0 comments on commit f4aee87

Please sign in to comment.