2019-11-21 22:14:27 +00:00
|
|
|
import { any, copy, copyfields, items, iteritems } from "../common/Tools";
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
/**
|
|
|
|
* Interface for a remote storage, used for networking/multiplayer features
|
|
|
|
*/
|
|
|
|
export interface IRemoteStorage {
|
|
|
|
/**
|
|
|
|
* Search through a collection for equality of some fields
|
|
|
|
*/
|
|
|
|
search(collection: string, fields: any): Promise<any[]>
|
|
|
|
/**
|
|
|
|
* Find a single object with equality of some fields
|
|
|
|
*/
|
|
|
|
find(collection: string, fields: any): Promise<any>
|
|
|
|
/**
|
|
|
|
* Insert or update an object in a collection, based on some unicity fields
|
|
|
|
*/
|
|
|
|
upsert(collection: string, unicity: any, additional: any): Promise<void>
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
/**
|
|
|
|
* Remote storage using the Parse protocol
|
|
|
|
*/
|
|
|
|
export class ParseRemoteStorage implements IRemoteStorage {
|
|
|
|
constructor() {
|
|
|
|
Parse.initialize("thunderk.net");
|
|
|
|
Parse.serverURL = 'https://rs.thunderk.net/parse';
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
/**
|
|
|
|
* Unpack a Parse.Object to a javascript object
|
|
|
|
*/
|
|
|
|
static unpack(obj: Parse.Object): Object {
|
|
|
|
return obj.toJSON();
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
/**
|
|
|
|
* Get the Parse model for a given collection name.
|
|
|
|
*/
|
|
|
|
private getModel(collection: string): any {
|
|
|
|
return Parse.Object.extend("spacetac" + collection);
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
async search(collection: string, fields: any): Promise<any[]> {
|
|
|
|
let query = new Parse.Query(this.getModel(collection));
|
|
|
|
iteritems(fields, (key, value) => {
|
|
|
|
query.equalTo(key, value);
|
|
|
|
});
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
let results = await query.find();
|
|
|
|
return results.map(ParseRemoteStorage.unpack);
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
async find(collection: string, fields: any): Promise<any> {
|
|
|
|
let results = await this.search(collection, fields);
|
|
|
|
if (results.length == 1) {
|
|
|
|
return results[0];
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
async upsert(collection: string, unicity: any, additional: any): Promise<void> {
|
|
|
|
let query = new Parse.Query(this.getModel(collection));
|
|
|
|
iteritems(unicity, (key, value) => {
|
|
|
|
query.equalTo(key, value);
|
|
|
|
});
|
2017-05-04 23:19:28 +00:00
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
let results = await query.find();
|
|
|
|
let model = this.getModel(collection);
|
|
|
|
let base = new model();
|
|
|
|
if (results.length == 1) {
|
|
|
|
base = results[0];
|
|
|
|
} else {
|
|
|
|
iteritems(unicity, (key, value) => {
|
|
|
|
base.set(key, value);
|
|
|
|
});
|
2017-05-04 23:19:28 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 22:14:27 +00:00
|
|
|
iteritems(additional, (key, value) => {
|
|
|
|
base.set(key, value);
|
|
|
|
});
|
|
|
|
await base.save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fake remote storage in memory (for testing purposes)
|
|
|
|
*/
|
|
|
|
export class FakeRemoteStorage implements IRemoteStorage {
|
|
|
|
collections: { [collection: string]: any[] } = {}
|
|
|
|
getCollection(name: string): any {
|
|
|
|
let collection = this.collections[name];
|
|
|
|
if (collection) {
|
|
|
|
return collection;
|
|
|
|
} else {
|
|
|
|
this.collections[name] = [];
|
|
|
|
return this.collections[name];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
async search(collection: string, fields: any): Promise<any[]> {
|
|
|
|
let objects = this.getCollection(collection);
|
|
|
|
let result = objects.filter((obj: any) => !any(items(fields), ([key, value]) => obj[key] != value));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
async find(collection: string, fields: any): Promise<any> {
|
|
|
|
let results = await this.search(collection, fields);
|
|
|
|
if (results.length == 1) {
|
|
|
|
return results[0];
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
async upsert(collection: string, unicity: any, additional: any): Promise<void> {
|
|
|
|
let existing = await this.find(collection, unicity);
|
|
|
|
let base = existing || copy(unicity);
|
|
|
|
copyfields(additional, base);
|
|
|
|
if (!existing) {
|
|
|
|
let objects = this.getCollection(collection);
|
|
|
|
objects.push(base);
|
2017-05-04 23:19:28 +00:00
|
|
|
}
|
2019-11-21 22:14:27 +00:00
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
}
|