/*
* Copyright (C) 2022 StApps
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*/
import {Injectable} from '@angular/core';
import {Client} from '@openstapps/api/lib/client';
import {
SCFacet,
SCIndexableThings,
SCMultiSearchRequest,
SCMultiSearchResponse,
SCSearchRequest,
SCSearchResponse,
SCSearchValueFilter,
SCThing,
SCThingOriginType,
SCThings,
SCThingsField,
SCThingType,
SCSaveableThing,
SCFeedbackRequest,
SCFeedbackResponse,
SCUuid,
} from '@openstapps/core';
import {environment} from '../../../environments/environment';
import {StorageProvider} from '../storage/storage.provider';
import {StAppsWebHttpClient} from './stapps-web-http-client.provider';
import {chunk} from '../../_helpers/collections/chunk';
export enum DataScope {
Local = 'local',
Remote = 'remote',
}
interface CacheItem {
data: Promise;
timestamp: number;
}
/**
* Generated class for the DataProvider provider.
*
* See https://angular.io/guide/dependency-injection for more info on providers
* and Angular DI.
*/
@Injectable({
providedIn: 'root',
})
export class DataProvider {
/**
* TODO
*/
get storagePrefix(): string {
return this._storagePrefix;
}
/**
* TODO
*/
set storagePrefix(storagePrefix) {
this._storagePrefix = storagePrefix;
}
/**
* TODO
*/
private _storagePrefix = 'stapps.data';
readonly cache: Record | undefined> = {};
private maxCacheAge = 3600;
/**
* Version of the app (used for the header in communication with the backend)
*/
appVersion = environment.backend_version;
/**
* Maximum number of sub-queries in a multi-query allowed by the backend
*/
backendQueriesLimit = 5;
/**
* TODO
*/
backendUrl = environment.backend_url;
/**
* TODO
*/
client: Client;
/**
* TODO
*/
storageProvider: StorageProvider;
/**
* Simplify creation of a value filter
*
* @param field Database field for apply the filter to
* @param value Value to match with
*/
static createValueFilter(field: SCThingsField, value: string): SCSearchValueFilter {
return {
type: 'value',
arguments: {
field: field,
value: value,
},
};
}
/**
* Create a facet from data
*
* @param items Data to generate facet for
* @param field Field for which to generate facet
*/
static facetForField(items: SCThing[], field: SCThingsField): SCFacet {
const bucketMap = new Map();
const facet: SCFacet = {buckets: [], field: field};
for (const item of items) {
const value =
typeof bucketMap.get(item.type) === 'undefined' ? 1 : (bucketMap.get(item.type) as number) + 1;
bucketMap.set(item.type, value);
}
for (const [key, value] of bucketMap.entries()) {
facet.buckets.push({key: key, count: value});
}
return facet;
}
/**
* TODO
*
* @param stAppsWebHttpClient TODO
* @param storageProvider TODO
*/
constructor(stAppsWebHttpClient: StAppsWebHttpClient, storageProvider: StorageProvider) {
this.client = new Client(stAppsWebHttpClient, this.backendUrl, this.appVersion);
this.storageProvider = storageProvider;
}
/**
* Create savable thing from an indexable thing
*
* @param item An indexable to create savable thing from
* @param type The type (falls back to the type of the indexable thing)
*/
static createSaveable(item: SCIndexableThings, type?: SCThingType): SCSaveableThing {
return {
data: item,
name: item.name,
origin: {
created: new Date().toISOString(),
type: SCThingOriginType.User,
},
type: typeof type === 'undefined' ? item.type : type,
uid: item.uid,
};
}
/**
* Delete a data item
*
* @param uid Unique identifier of the saved data item
*/
async delete(uid: string): Promise {
return this.storageProvider.delete(this.getDataKey(uid));
}
/**
* Delete all the previously saved data items
*/
async deleteAll(): Promise {
const keys = [...(await this.getAll()).keys()];
return this.storageProvider.delete(...keys);
}
/**
* Provides a savable thing from the local database using the provided UID
*/
async get(uid: string, scope: DataScope.Local): Promise;
/**
* Provides a thing from the backend
*/
async get(uid: string, scope: DataScope.Remote): Promise;
/**
* Provides a thing from both local database and backend
*/
async get(uid: string): Promise