Skip to content

Commit

Permalink
Merge pull request #24 from jircdev/fix/entities-reestructure
Browse files Browse the repository at this point in the history
Solve #21 Refactoring of LocalProvider for Collections
  • Loading branch information
jircdev authored Jan 15, 2024
2 parents 08618e4 + fd004f3 commit 607bd58
Show file tree
Hide file tree
Showing 17 changed files with 523 additions and 461 deletions.
17 changes: 12 additions & 5 deletions library/modules/entities/collection/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ import { IProvider } from '../interfaces/provider';
import { ICollectionSpecs, ICollection } from './interfaces/ICollection';
import { ResponseAdapter } from '../adapter';
import { IResponseAdapter } from '../adapter/interface';
import { Item } from '../item';

export /*bundle */ class Collection extends ReactiveModel<Collection> {
declare triggerEvent: (event?: string) => void;
declare storeName: string;
declare trigger: (event?: string) => void;
declare reactiveProps: <T>(props: Array<keyof T>) => void;
db: string;
item: typeof Item;

#items: Array<any | undefined> = [];
protected localdb = true;
protected localdb: boolean = true;

#elements = new Map();
get elements() {
return this.#elements;
Expand All @@ -31,9 +40,6 @@ export /*bundle */ class Collection extends ReactiveModel<Collection> {
}

counters: any = {};
/**
* Represents the number of elements in the collection
*/
total: number = 0;
next: number | undefined;
#localProvider: CollectionLocalProvider;
Expand Down Expand Up @@ -82,7 +88,7 @@ export /*bundle */ class Collection extends ReactiveModel<Collection> {
const setProperty = (property, value) => (this[property] = value);
const bridge = { get: getProperty, set: setProperty };
this.#responseAdapter = ResponseAdapter.get(this, this.#initialSpecs?.adapter);
this.#localProvider = new CollectionLocalProvider(this, bridge);
this.#localProvider = new CollectionLocalProvider(this);
this.#saveManager = new CollectionSaveManager(this, bridge);
this.#loadManager = new CollectionLoadManager(this, bridge);
this.#localProvider.on('items.changed', this.#listenItems);
Expand Down Expand Up @@ -110,6 +116,7 @@ export /*bundle */ class Collection extends ReactiveModel<Collection> {
async set(data) {
const { items } = data;
delete data.item;

await super.set(data);

if (!items) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Item } from '../../item';
import { IProvider, IProviderConstructor } from '../../interfaces/provider';
import { IProviderConstructor } from '../../interfaces/provider';
import { TAdapters } from '../../adapter';

export type TItemConstructor<T extends object = any> = new (args?: { id?: any }) => Item<T>;
Expand Down
101 changes: 43 additions & 58 deletions library/modules/entities/collection/load.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
import type { Collection } from '.';
import type { CollectionLocalProvider } from './local-provider';
import { RegistryFactory } from '../registry/factory';
import type { ResponseAdapter } from '../adapter';
import { IResponseAdapter } from '../adapter/interface';
import { Item } from '../item';
import { IProvider } from '../interfaces/provider';
interface ILoadResponse {
localLoaded: true;
fetching: false;
total: number;
next?: boolean | number | string;
items?: any[];
items?: (typeof Item)[];
}
export class CollectionLoadManager {
filter: any;
#localProvider: CollectionLocalProvider;
#provider;
#parentBridge;
#provider: IProvider;
#parentBridge: {
get: (property: string) => any;
set: (property: string, value: any) => void;
};
#parent: Collection;
#registry: RegistryFactory;
#adapter: IResponseAdapter;
get parent() {
return this.#parent;
}
/**
* Original data obtained in provider.load
*
* This property lets the developer access to the original data obtained from the provider in the children object.
* Only contains the data from the last load.
*
*/

protected remoteData = [];
constructor(parent, parentBridge) {
constructor(
parent: Collection,
parentBridge: {
get: (property: string) => any;
set: (property: string, value: any) => void;
}
) {
this.#parent = parent;
this.#parentBridge = parentBridge;
this.#adapter = this.#parent.responseAdapter;
Expand All @@ -46,34 +49,8 @@ export class CollectionLoadManager {
if (this.#localProvider) this.#parent.customFilter = this.#localProvider?.customFilter;
}

/**
* metodo general para las consultas de tipo lista para las colecciones
* @param params Object filters and configuration
* parameters:
* - next
* - limit
* - update // siguiente pagina de misma consulta
*
*
* - status // 1, 0, -1
* {user: [10,30]}
*
* {and: [{user:10}, {user:30}]]}
*
* {user: 10}
* {user: [10,30,40,50]}
* {or: [{user:10}, {user:30}]]}
* {and: [{user:10}, {user:30}]]}
* el provider debe devolver:
* - next
* - entries
* - total
* load({status:1})
*/

#localLoad = async params => {
if (!this.#localProvider) return;
//if (this.parent.sOnline || this.#provider) return;
const localData = (await this.#localProvider.load(params)) ?? { data: [] };

const newItems = await this.processEntries(localData.data);
Expand All @@ -91,6 +68,7 @@ export class CollectionLoadManager {
this.#parent.loaded = true;

this.parent.set(properties);

return this.#adapter.toClient({ data: items });
};

Expand All @@ -105,7 +83,7 @@ export class CollectionLoadManager {
};
load = async (params: any = {}) => {
try {
this.parent.fetching = true;
this.#parent.fetching = true;
const { next } = this.parent;
let { start = 0, update } = params;
params.limit = params.limit ?? 30;
Expand All @@ -117,25 +95,12 @@ export class CollectionLoadManager {

const localResponse = await this.#localLoad(params);

if (!this.#provider) return localResponse;
const response = await this.#provider.list(params);
const data = this.#adapter.fromRemote(response);

const items: any[] = await this.processRemoteEntries(data);

this.remoteData = response;

this.#remoteElements = params.update === true ? this.#remoteElements.concat(items) : items;
if (!this.#parent.isOnline || !this.#provider) return localResponse;
const { properties, items } = await this.#remoteLoad(params);

const properties = {
items: this.#remoteElements,
next: data.next,
loaded: true,
fetching: false,
total: data.total ?? 0,
};
this.parent.set(properties);
this.parent.triggerEvent();

return this.#adapter.toClient({ data: items });
} catch (exc) {
this.parent.triggerEvent();
Expand All @@ -148,7 +113,27 @@ export class CollectionLoadManager {
}
};

async processRemoteEntries(data): Promise<any[]> {
#remoteLoad = async (params: Record<string, any>) => {
const response = await this.#provider.list(params);
const data = this.#adapter.fromRemote(response);

const items: (typeof Item)[] = await this.processRemoteEntries(data);

this.remoteData = response;

this.#remoteElements = params.update === true ? this.#remoteElements.concat(items) : items;

const properties = {
items: this.#remoteElements,
next: data.next,
loaded: true,
fetching: false,
total: data.total ?? 0,
};
return { properties, items };
};

async processRemoteEntries(data: { [key: string]: any }): Promise<any[]> {
if (!data.entries && !data.items) {
throw new Error('The list method must return an object with an entries property');
}
Expand All @@ -163,7 +148,7 @@ export class CollectionLoadManager {
return this.setItems(elements);
}

async setItems(entries) {
async setItems(entries: (typeof Item)[]) {
const promises = [];
const items = entries.map(record => {
const item = new this.parent.item({ id: record.id, properties: record });
Expand All @@ -185,7 +170,7 @@ export class CollectionLoadManager {
* @param updateLocalItems
* @returns
*/
processEntries = async (entries, updateLocalItems = false): Promise<Item<any>[]> => {
processEntries = async (entries: (typeof Item)[], updateLocalItems = false): Promise<Item<any>[]> => {
// this.#registry.registerList(this.#parentBridge.get('storeName'), entries);
const promises = [];
const items = entries.map(record => {
Expand Down
Loading

0 comments on commit 607bd58

Please sign in to comment.