Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/romagny13/spa-lib
TypeScript SpaLib
https://github.com/romagny13/spa-lib
http indexeddb oauth promise spa storage typescript
Last synced: about 1 month ago
JSON representation
TypeScript SpaLib
- Host: GitHub
- URL: https://github.com/romagny13/spa-lib
- Owner: romagny13
- License: mit
- Created: 2017-02-20T00:24:01.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2017-03-14T17:06:46.000Z (almost 8 years ago)
- Last Synced: 2024-11-11T20:32:56.594Z (about 2 months ago)
- Topics: http, indexeddb, oauth, promise, spa, storage, typescript
- Language: JavaScript
- Homepage:
- Size: 454 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SpaLib
[![Build Status](https://travis-ci.org/romagny13/spa-lib.svg?branch=master)](https://travis-ci.org/romagny13/spa-lib)
```
npm i spa-lib -S
```- Storage (local, session, cookies and indexedDB services)
- Cache
- Messenger
- Observable and ObservableArray
- Form binding and validation
- Http (with interceptors)
- OAuth (Google, Facebook, ...easy to extend)
- TypeScript Promise polyfill## es6 / TypeScript
Example
```js
import { Observable, TSPromise } from 'spa-lib';
// or
import * as SpaLib from 'spa-lib';
```## es5
```html
```Example
```js
var messenger = new SpaLib.Messenger();
```## Observables
- Observe value changes
```js
const vm = {
title: 'My title'
};// observe an object's property
let observable = new Observable(vm, 'title');
observable.subscribe((value) => {});
vm.title = 'My new title'; // => valuechanged
```- Observe array changes
```js
let items = ['a', 'b'];
let observableArray = new ObservableArray(items);
observableArray.subscribe((event, value, index) => {
switch (event) {
case 'added':break;
case 'removed':break;
case 'filtered':break;
case 'sorted':break;
}
});
// example with push
items.push('c', 'd', 'e');
```Support :
- push
- unshift
- splice
- shift
- pop
- sort
- filter
- resetFilter### Shorthands
```js
const vm = {
title: 'My title'
};observe(vm, 'title', (value) => {
});
``````js
let items = ['a', 'b'];observeArray(items, (event, value, index) => {
});
```## Form binding and validation
```js
// model
let user = {
firstname: 'marie',
lastname: 'bellin',
email: '',
age: 20,
list: '2',
preference: 'b',
likes: ['Milk', 'Cakes'] // binding on array
};// form config (validation on 'submit' by default or 'valuechanged')
const formConfig = new FormConfig()
// form element name, validators array, updateType? ('valuechanged' by default or 'lostfocus')
.addFormElementConfig('firstname', [Validator.required(), Validator.minLength(3)])
.addFormElementConfig('lastname', [Validator.maxLength(10)])
.addFormElementConfig('email', [Validator.pattern(/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/, 'Please enter a valid email.')])
.addFormElementConfig('age', [Validator.custom((value) => {
return value > 0 && value < 120;
}, 'Oops ??')])
.addFormElementConfig('agree', [Validator.required()]) // validation with an element not in the model (checkbox for example)
.addFormElementConfig('likes', [Validator.custom(() => {
return user.likes.length > 0;
}, 'Please select one or more items.')]);// form binding
const formBinding = new FormBinding('#myform', user, formConfig);
```
Note: validation messages are appended to html element on error with css class 'has-error' or 'has-success' (could be desabled with form config).on validation state changed
```js
formBinding.onStateChanged((element, errors) => {
console.log('State changed', element, errors);
});
```on submit (create a sumary for example)
```js
const sumary: any = document.querySelector('.sumary');
formBinding.onSubmit((response: FormSubmittedResponse) => {
sumary.innerHTML = '';
sumary.style.display = 'block';
if (response.hasError) {
response.errors.forEach((error: FormElementError) => {
let p = document.createElement('p');
p.innerHTML = error.message;
sumary.appendChild(p);
});
}
else {
let json = JSON.stringify(response.source);
sumary.innerHTML = `
Ok (refresh on validation state changed)
${json}
`;
}
});
```Allow to bind and validate with a simple form (cons: actually interact with the DOM)
```html
Firstname:
Lastname:
Email:
Age:
List (no validation):
1
2
3
Preference
A
B
C
Like (multiple choice)
Cakes
Milk
Nutella
Agree to conditions
```
## Messenger
```js
let messenger = new Messenger();
// subscribe (one or more arguments)
messenger.subscribe('MyEvent', (result1, result2, result3) => {});
// publish
messenger.publish('MyEvent', 'my string', 10, { name: 'my object result' });
```## Http
### Send a request (GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH)
```js
const baseUrl = 'http://jsonplaceholder.typicode.com';
const http = new Http();
const request = new HttpRequest({ url: `${baseUrl}/posts` });
http.send(request).then((response: HttpResponse) => {
let posts = JSON.parse(response.body);
});
```
- Post JSON
```js
const data = {
title: 'My post',
body: 'My content'
};
http.post(`${baseUrl}/posts`, JSON.stringify(data)).then((response: HttpResponse) => {
let post = JSON.parse(response.body);
});
```- Post form
```js
let body = 'title=' + encodeURIComponent('My post') + '&content=' + encodeURIComponent('My content');
const request = new HttpRequest({
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
url: `${baseUrl}/posts`,
body
});
http.send(request).then((response: HttpResponse) => {
let post = JSON.parse(response.body);
});
```- FormData
```js
let data = new FormData();
data.append('id', '101');
data.append('title', 'My post');
data.append('content', 'My content');const request = new HttpRequest({
method: 'POST',
url: `${baseUrl}/posts`,
body: data
});
http.send(request).then((response: HttpResponse) => {
let post = JSON.parse(response.body);
});
```- Set a timeout (milliseconds)
```js
const request = new HttpRequest({
url: `${baseUrl}/posts`,
timeout: 1000
});
http.send(request).then(() => {}, (response: HttpResponse) => {
// handle :
// - response with error status code
// - xhr error | timeout | abort
});
```- Abort a request
```js
const request = new HttpRequest({ url: `${baseUrl}/posts`});
http.send(request).then(() => { }, (response) => {});
request.abort();
```
- Handle progress
```jsconst request = new HttpRequest({
url: `${baseUrl}/posts`,
progress: (event) => {
// ...
}
});
http.send(request).then(() => {});
```
- Response type => blob
```js
const request = new HttpRequest({ url: 'http://res.cloudinary.com/romagny13/image/upload/v1464052663/dotnet_oh0ryu.png', responseType: 'blob' });
http.send(request).then((response: HttpResponse) => {});
```### REST Shorthands (get,post,put,delete)
```js
const data = {
title: 'My post',
body: 'lorem ipsum ...'
};
http.post(`${baseUrl}/posts`, JSON.stringify(data)).then((response: HttpResponse) => {});
```
- put
```js
const data = {
id: 1,
title: 'My updated post',
content: 'My updated content'
};
http.put(`${baseUrl}/posts/1`, JSON.stringify(data)).then((response: HttpResponse) => {
let post = JSON.parse(response.body);
});
```
- delete
```js
http.delete(`${baseUrl}/posts/1`).then((response: HttpResponse) => {});
```- With an access_token
```js
let access_token = 'ya29.CjCmA3KKBZH7ElidD3j_peoQaPdy2G099Ek6DYuYRfwFqSMXpR3i2_2xSjjHBo6FNNo';
http.get(`${baseUrl}/posts`, access_token).then((response: HttpResponse) => {});
```### Interceptors
Create an interceptor
```js
http.interceptors.push({
before(request: HttpRequest, next: Function) {next(true); // cancel if false
},
after(response: HttpResponse, next: Function) {
next(true);
}
});
```### Load
```js
http.load('http://localhost/blog/mytemplate.html', (template) => {});
```## OAuth
## TSPromise
## Cache
```js
// create a cache
const cache = new Cache();
let k = 'mykey';
let item = { name: 'my value' };
// store
cache.store(k, item);
// check
let hasItem = cache.has(k);
// get
let result = cache.retrieve(k);
// save to local storage
let storageKey = '__cache';
cache.save(storageKey);
// restore cache from local storage
cache.restore(storageKey);
// remove an item by key
cache.remove(k);
// clear
cache.clear();
```## Storage
### Cookies
```js
const cookieService = new CookieService();
let name = 'mycookie';
// create a cookie (arguments: name, value, expirationDays, path, domain, secure)
cookieService.set(name, value, 10);
// check
let hasCookie = cookieService.has(name)
// get
let result = cookieService.get(name);
// delete
let result = cookieService.delete(name);
// clear all cookies
cookieService.clear();
```### Local and session storage
```js
let localService = new StorageService();let key = 'mykey';
// set
localService.set(key, 'my value'); // value could be an object
// check
let hasItem = localService.has(key)
// get
let item = localService.get(key);
// remove
localService.remove(key);
// clear
localService.clear();
``````js
let sessionService = new StorageService('session');let key = 'mykey';
// set
sessionService.set(key, 'my value'); // value could be an object
// check
let hasItem = sessionService.has(key)
// get
let item = sessionService.get(key);
// remove
sessionService.remove(key);
// clear
sessionService.clear();
```### indexedDB
```js
const dbConfigs = [{
name: 'testdb', // db name
created: true, // add created and modified fields
// object stores
objectStores: [{
name: 'users',
key: { keyPath: 'id', autoIncrement: true }, // key
indexes: [{ name: 'username', definition: { unique: false } }] // indexes
}]
}];
const indexeddbService = new IndexedDBService(dbConfigs);
// open /create / update the db (if db version is updated)
indexeddbService.openCreateDb('testdb', 1).then((result) => {
// then could get, insert, update,... data}, (error) => {
});
```
- Insert
```js
indexeddbService.insert('users', { userName: 'marie' }).then((result) => {});
```- get all
```js
indexeddbService.getAll('users').then((result: any[]) => {});
```
- get one```js
// object store and key
indexeddbService.getOne('users', 1).then((result) => {};
```- update
```js
let user = {
userName: 'updated'
};
indexeddbService.update('users', 1, user).then((result) => {});
```- delete
```js
indexeddbService.delete('users', 1).then((result) => {});
```