@scripty/react-store
Version:
This lightweight global react hook store is inspired by the extjs store architecture. Share your stores through your application with only a few lines of code!
190 lines (157 loc) • 4.89 kB
JavaScript
import { request } from './';
import { Model } from './Model';
export class Store {
constructor(store) {
const { name, model, proxy } = store;
const { api, rootProperty } = proxy;
this.name = name;
this.model = model;
this.proxy = this.getProxy(api, rootProperty);
this.data = [new Model(model)];
this.rawData = [];
this.filteredData = [];
this.pagination = {
total: 0,
page: 0,
results: 0
}
this.updated = [];
this.removed = [];
this.created = [];
}
createModel(data) {
const model = new Model(this.model);
model.set(data);
return model;
}
getProxy(api, rootProperty) {
if (api) {
let proxy = {};
Object.keys(api).forEach((key) => {
proxy[key] = async (data) => {
let response = await request(api[key].method, api[key].url, data);
this.present(response, rootProperty);
return response;
}
});
return proxy;
}
}
getDirtyRecords() {
return {
created: this.created,
updated: this.updated,
removed: this.removed
};
}
present(response, rootProperty) {
if (typeof response.pagination !== 'undefined') {
this.pagination = response.pagination;
}
if (typeof response.updated !== 'undefined') {
this.updatedData = this.getModelRecords(response.updated);
this.rawUpdatedData = response.updated;
}
if (typeof response.destroyed !== 'undefined') {
this.deletedData = this.getModelRecords(response.destroyed);
this.rawDeletedData = response.destroyed;
}
if (rootProperty) {
response = response[rootProperty]
}
if (typeof response !== 'undefined' && response.length > 0) {
this.rawData = response;
this.data = this.getModelRecords(response);
this.cachedData = this.getModelRecords(response);
} else {
this.data = [new Model(this.model, this.callback.bind(this))];
this.cachedData = [new Model(this.model, this.callback.bind(this))];
}
this.created = [];
this.updated = [];
this.removed = [];
this.saveGlobalStore();
}
callback() {
if (this.saveGlobalStore) {
this.saveGlobalStore();
}
}
getModelRecords(data) {
return data.map((record) => {
let model = new Model(this.model, this.callback.bind(this));
model.set(record);
return model;
})
}
getAt(index) {
return this.data[index];
}
filter(field, value) {
this.filteredData = this.data.filter((record) => {
if (record[field].toString() === value) {
return record;
}
});
if (this.filteredData.length > 0) {
this.data = this.filteredData;
this.saveGlobalStore();
return this.data[0];
}
this.data = this.cachedData;
return this.data;
}
clearFilter() {
this.data = this.cachedData;
this.saveGlobalStore();
}
add(model) {
if (typeof model === 'array') {
model.forEach((record) => {
this.data.push(record);
})
}
this.data.push(model);
if (!this.created.some(data => {
return JSON.stringify(data) === JSON.stringify(model)
})) {
this.created.push(model);
}
this.saveGlobalStore();
}
update(model) {
this.data = this.data.map((rec) => {
if (rec._id === model._id) {
return model;
}
return rec;
}).filter(rec => typeof rec !== 'undefined');
if (!this.updated.some(data => {
return JSON.stringify(data) === JSON.stringify(model)
})) {
this.updated.push(model);
}
this.saveGlobalStore();
}
removeAt(index) {
this.data.splice(index, 1);
this.rawData.splice(index, 1);
this.saveGlobalStore();
}
removeById(_id) {
const removed = this.data.find(rec => rec._id === _id);
this.data = this.data.filter(rec => rec._id !== _id);
if (removed) {
this.removed.push(removed);
}
this.saveGlobalStore();
}
removeAll() {
this.data.splice(0, this.data.length);
this.rawData.splice(0, this.rawData.length);
this.saveGlobalStore();
}
saveGlobalStore() {
window.globalStorage.setStore({ data: window.globalStorage.data });
}
}