animus
v0.1.8
Published
Http framework with full offline capabilities
Downloads
4
Maintainers
Readme
Animus
Features
- Brings to the application ability to build full offline experience.
- Shows stored results before getting response from the server.
- Stores results of the http requests on the browser side by using flexible localForage for future usage even after application was reloaded.
- Provides TypeScript friendly interface based on decorators
- Independent from any frameworks. Can be used with Angular, React, Vue etc.
- Sending date with POST, PUT or DELETE methods in case if service is unreachable to queue for future invocation event if application is reloaded.
Creation of this package was inspired by AngularJS $resource and $cachedResource libraries.
Few Samples
Define resource using decorators.
import { Action, Resource, ResourceArray, ResourceInstance } from 'animus';
/**
* Single instance of the resource
*/
export interface Comment extends ResourceInstance {
id?: number;
comment: string;
}
/**
* Array of the resources
*/
export interface Comments extends Array<Comment>, ResourceArray { }
@Resource({
name: 'Comments.db', // The name of the localForage collection
url: '/api/articles/:articleId/comments(/:id)', // The url pattern '/:id' is an optional segment
params: { articleId: '@articleId', id: '@id' } // Parameters pattern for passing fields from the resource to the url.
})
export class CommentsResource {
// Threat response as an array. Pick from cache array by given params.
@Action({ method: 'get', isArray: true })
public readonly findAllByArticle: (params: { articleId: number }) => Comments;
@Action({ method: 'get' })
public readonly findOne: (params: { articleId: number, id: number }) => Comment;
@Action({ method: 'get', localOnly: true })
public readonly findOneCached: (params: { articleId: number, id: number }) => Comments;
@Action({ method: 'post' })
public readonly create: (params: { articleId: number }, comment: Comment) => Comment;
@Action({ method: 'put' })
public readonly update: (params: { }, comment: Comment) => Comment;
@Action({ method: 'delete' })
public readonly remove: (params: { }, comment: Comment) => Comment;
}
const commentsResource = new CommentsResource();
Since this package does not depend onto any certain framework there are no difficulties to use it as, for example, Angular provider
import { Injectable, Component, ... } from '@angular/core';
import { Resource, ... } from 'animus';
@Injectable()
@Resource({
/// ...
})
class CommentsResource {
/// ...
}
@Component(...)
class CommentsComponent {
public comments: Comments;
constructor(
private commentsResource: CommentsResource
) {
this.comments = this.commentsResource.findAllByArticle({ articleId: 1 });
}
}
Decorators
@Resource(metadata: ResourceMetadata)
Class decorator. Declares new resource over the decorated class based on the given ResourceMetadata.
@Resource({
name: 'Comments.db', // The name of the localForage collection
url: '/api/articles/:articleId/comments(/:id)', // The url pattern '/:id' is an optional segment
params: { articleId: '@articleId', id: '@id' } // Parameters pattern for passing fields from the resource to the url.
})
class CommentsResource { ... }
Common configurations
Resource.common
- default resource configuration
Resource.common.networkStateAdapter = new CustomNetworkStateAdapter();
Resource.common.driver = CustomLocalForage._driver;
@Action(metadata: ActionMetadata)
Property decorator. Declares resource action over the decorated method based on a given ActionMetadata.
class CommentsResource {
@Action({ method: 'get' })
public readonly findOne: (params: { articleId: number, id: number }) => Comment;
}
Metadata
ResourceMetadata
This metadata contains configuration information for the resource.
ResourceMetadata#url: String
Url patters for the http. Action params will be passed to the url according to this pattern. Segments prefixed with:
(colon) will be replaced with action params, other will be passed to the query string params.Example
url: `/api/library/:libraryId/books(/:bookId)`
Param
bookId
in this example is optional.See url-pattern for extra information.
ResourceMetadata#params: Object
Bounding params pattern. This params used to map resource instance to url params and also as a key in the local data storage. Params prefixed with@
(at) will be picked from resource instance according to names.// Book resource with following structure: { id:1, libraryId: 1 } // Using params pattern: { bookId: '@id', libraryId: '@libraryId' } // Will be mapped to the action params: { bookId: 1, libraryId: 1 }
ResourceMetadata#http: AxiosInstance
Axios instance used as http framework. Can be easily replaced with custom instance of the axios. For example to mock http in testing purposes.@Resource({ ... http: new MockAdapter(axios.create()) ... }) class CommentsResource {...}
ResourceMetadata#httpOnly: Boolean
Do not perform any actions over storage. Note: if truehttpOnly
andlocalOnly
field on action decorators will be ignored. Default is falseResourceMetadata#name: String
Name of the LocalForage database. If name is not specified class name will be used.ResourceMetadata#driver: String | LocalForageDriver | LocalForageDriver[]
LocalForage driver.Default is
localforage.LOCALSTORAGE
ResourceMetadata#bootstrap: Promise
Defer initialization of resource.Resource.common.bootstrap = new Promise(resolve => $(document).ready(() => resolve()));
ResourceMetadata#autoCompact: Boolean
Whether to perform auto compaction after each array response is handled. Process is similar to garbage collection.
It is not recommended to use auto compaction if it is expected to have large amount of array responses cached, e.g pagination. Use Resource defined
$compact
function on the instance of the decorated class to perform compaction manually e.g. on application start.class ArticlesResource { public readonly $compact() => Promise<void>; } await new ArticlesResource().$compact()
Default is
true
.ResourceMetadata#networkState: NetworkStateAdapter
Network state adapter. Used to determine network availability state of the application. Also notify resource about application is getting online/offline
Default is
BrowserNetworkStateAdapter
. Usesnavigator.online
property and 'online'/'offline' events on the window.ResourceMetadata#reattemptInterval: number
How often to attempt to perform actions over http if server is unavailable (receives 5** codes)Default
60000
- every minute
ActionMetadata
This metadata contains configuration information for the resource action.
ActionMetadata#method: 'get' | 'post' | 'put' | 'delete'
Action method.Post
andput
methods also create temporary instances so those instances will be added to the array.Delete
method also removes instance from the local array.ActionMetadata#isArray: Boolean
Threat response as array.ActionMetadata#url: String
Override resource url.ActionMetadata#params: Object
Overrides resource bounding params.ActionMetadata#localOnly: Boolean
Do not perform any actions over http.Default is
false
ActionMetadata#httpOnly: Boolean
Do not perform any actions over the local data storage.Default is
false
ActionMetadata#config
Additional http action config@Action({ method: 'get', config: { headers: { 'X-My-Custom-Header': 'MyCustomValue' } } })
Interfaces
ResourceInstance
Resource instance and indicators to determine whether it was resolved either by http or from cache. Extend your instance model interfaces from this abstraction.
Example
interface Comment extends ResourceInstance {
id: number;
content: string;
}
ResourceInstance#$new: Boolean
Whether the resource is newly created and not submitted to the server yet. Once resource is submitted this field will be deleted from the object.
ResourceInstance#$removed: Boolean
Whether the resource is removed or waiting for its removal due to server is unavailable.
ResourceInstance#$storagePromise: Promise<this>
Resolution of performing operations over the local data storage. Once resolved this field will be deleted from the object.
ResourceInstance#$httpPromise: Promise<this>
Resolution of performing operations over the http. Once resolved this field will be deleted from the object.
ResourceInstance#$formCache: Boolean
Whether the resource is from the local data storage. Once resolved over the http this field will be set to
true
.ResourceInstance#toJSON() => Object
Produces regular JavaScript object from the resource.
ResourceArray
Represents an array of the resources and indicators to determine whether elements were resolved either by http or from cache. Extend your arrays model interfaces from this abstraction.
Example
interface Comments extends Array<Comment> ResourceArray {
id: number;
}
ResourceInstance#$storagePromise: Promise<this>
Resolution of performing operations over the local data storage.
ResourceInstance#$httpPromise: Promise<this>
Resolution of performing operations over the http.
ResourceInstance#$formCache: Boolean
Whether the resource is from the local data storage.
ResourceInstance#toJSON() => Object
Produces regular JavaScript array from the resource.
NetworkStateAdapter
Used to determine network availability state.
isOnline: boolean
Indicates whether internet connection is available.
setOnlineHandler(handler: () => void) => void
Set handler to be called once application get online.
setOfflineHandler(handler: () => void) => void
Set handler to be called once application get offline.
Resource object resolution
Note that resource instances combines with results of the http requests by Object.assign(...)
like mechanism.
All the fields from response will be assigned to the resource instance due to server authority principle,
but fields which was already in the resource will not be removed from it.
Local fields
Resource has "local only" fields. All the fields prefixed with $
(dollar) or __
(double underscore) will not be sent over http.
Such fields will be saved on the client side until they removed manually.
Thees fields are useful to store some kind of meta information such as references to another resource or timestamps of performed actions.
Clearing the cache
Use Resource defined $clear
function on the instance of the decorated class to perform clearing the resource data.
class ArticlesResource {
public readonly $clear() => Promise<void>;
}
await new ArticlesResource().$clear()
Reserved fields
Resource instances and resource arrays use some fields for internal purposes.
Please do not override or delete or set them to avoid unexpected behavior.
$fromCache
- Indicates whether array or instance is currently fetched from local data storage.$new
- Indicates whether the resource instance is newly created.$removed
- Indicates whether the resource instance is removed.$query
- Reference to itself in local data storage. Used to keep tracking of new object.$storagePromise
- Resolution of performing operations over the http.$httpPromise
- Resolution of performing operations over the http.
License
The MIT License (MIT)
Copyright (c)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.