Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Store): Implement Store #72

Merged
merged 43 commits into from
Mar 15, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4b1bef4
feat(Store): New Store structure
Khaaz Mar 14, 2020
e82f784
refactor(Collection): Collection now uses Store
Khaaz Mar 14, 2020
c9f1d83
fix(Store): Store.has
Khaaz Mar 14, 2020
48f5dd2
fix(Store): values()
Khaaz Mar 14, 2020
c39dd9e
refactor(registries): ARegistry use Store
Khaaz Mar 14, 2020
7db1ba9
fix: drop getAll on ARegistry
Khaaz Mar 14, 2020
bbb99d5
docs(Collection): correctly template?
Khaaz Mar 14, 2020
a4299a5
docs(Store): Map generics
Khaaz Mar 14, 2020
bafd1af
docs(Store): Iterator
Khaaz Mar 14, 2020
1d5dad9
docs(Store): formatting cache.keys
Khaaz Mar 14, 2020
ece4971
docs(Store): Iterator
Khaaz Mar 14, 2020
67e0262
docs(Store): formatting cache.values
Khaaz Mar 14, 2020
e7f8e3f
docs(Store): Whether (again)
Khaaz Mar 14, 2020
669420a
docs(Store): formatting toArray
Khaaz Mar 14, 2020
b848ce6
docs(Store): formatting cache.entries
Khaaz Mar 14, 2020
c381cac
docs(Store): Iterator
Khaaz Mar 14, 2020
49d7662
docs(Store): toObject
Khaaz Mar 14, 2020
749ebfe
docs(Store): Sotre.cache formatting (toObject)
Khaaz Mar 14, 2020
2ea2ed8
docs(Store): wording
Khaaz Mar 14, 2020
bb5e29f
docs(Store): Store jsdoc (review)
Khaaz Mar 14, 2020
6d05e99
refactor: GuildConfigCache and LRUCache impl Store
Khaaz Mar 14, 2020
d8a1ca8
feat: export Store
Khaaz Mar 14, 2020
f15e7e6
docs(Store): wording
Khaaz Mar 14, 2020
de3048e
docs(Store): wording
Khaaz Mar 14, 2020
aab2586
docs(Store): spacing
Khaaz Mar 14, 2020
07a15ea
docs(Store): spacing
Khaaz Mar 14, 2020
ea52ff8
docs: missing comments
Khaaz Mar 14, 2020
3e00c95
Merge branch 'stores' of https://github.com/Khaazz/AxonCore into stores
Khaaz Mar 14, 2020
f2c3653
docs(Store): boolean => Boolean
Khaaz Mar 14, 2020
1b0297d
fix(Store): comment
Khaaz Mar 14, 2020
3af4c4a
fix(Store): comment every
Khaaz Mar 14, 2020
20ddc69
fix(Store): usable over (apply)
Khaaz Mar 15, 2020
c1bd455
fix(Store): safeguard on apply (map, filter, toArray)
Khaaz Mar 15, 2020
7327b04
feat(Store): implement sweep function
Khaaz Mar 15, 2020
6bea3e8
feat(Store): implement first function
Khaaz Mar 15, 2020
e0ab0f8
doc(Store): general documentation
Khaaz Mar 15, 2020
6d1ed3f
fix(Collection): grammar
Khaaz Mar 15, 2020
3ba2bd7
fix(LRUCache): jsdoc
Khaaz Mar 15, 2020
d64b12a
fix(LRUCache): grammar
Khaaz Mar 15, 2020
6d82dfa
fix(LRUCache): consistent return
Khaaz Mar 15, 2020
babb741
fix(Store): Iterator
Khaaz Mar 15, 2020
7947f0f
docs(ARegistry): syntax
Khaaz Mar 15, 2020
3260a1b
fix(LRUCache): inconsistence in return type
Khaaz Mar 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Core/Command/Command.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ class Command extends Base {
embed.fields = [];
/* SubCommands */
if (this.hasSubcmd) {
const subcmds = this.subCommands.getAll().filter(e => !e.options.hidden).map(e => `${prefix}${e.info.usage}`);
const subcmds = this.subCommands.filter(e => !e.options.hidden).map(e => `${prefix}${e.info.usage}`);
if (subcmds.length > 0) {
embed.fields.push( {
name: 'SubCommands:',
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Module.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class Module extends Base {
* @memberof Module
*/
get commands() {
return this.axon.commandRegistry.getAll().apply('label', 'filter', (c) => c.module === this);
return this.axon.commandRegistry.apply('label', 'filter', (c) => c.module === this);
}

/**
Expand All @@ -123,7 +123,7 @@ class Module extends Base {
* @memberof Module
*/
get listeners() {
return this.axon.listenerRegistry.getAll().apply('label', 'filter', (l) => l.module === this);
return this.axon.listenerRegistry.apply('label', 'filter', (l) => l.module === this);
}

/**
Expand Down
50 changes: 20 additions & 30 deletions src/Core/Stores/ARegistry.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable no-unused-vars */
import NoAbstractInstanceException from '../../Errors/NoAbstractInstanceException';
import NotImplementedException from '../../Errors/NotImplementedException';
import AxonError from '../../Errors/AxonError';

import Collection from '../../Utility/Collection';
import Store from '../../Utility/Store';

/**
* @typedef {import('../../AxonClient').default} AxonClient
Expand All @@ -14,14 +15,13 @@ import Collection from '../../Utility/Collection';
* @author KhaaZ
*
* @template T
*
* @prop {AxonClient} _axon - The AxonClient
* @prop {Collection<T>} registry - The collection of items hold by the registry
*
* @abstract
* @class ARegistry
* @extends Store<T>
* @prop {AxonClient} _axon - The AxonClient
* @prop {T} _base - The base definition to use for the registry
*/
class ARegistry {
class ARegistry extends Store {
/**
* Creates an instance of ARegistry.
*
Expand All @@ -30,11 +30,12 @@ class ARegistry {
* @memberof ARegistry
*/
constructor(axon, base) {
super(new Map() );
if (this.constructor === 'ARegistry') {
throw new NoAbstractInstanceException();
}
this._axon = axon;
this.registry = new Collection( { base } );
this._base = base;
}

/**
Expand All @@ -49,14 +50,14 @@ class ARegistry {
}

/**
* Get the size of the registry
* Returns the current registry
*
* @readonly
* @type {Number}
* @type {Map}
* @memberof ARegistry
*/
get size() {
return this.registry.size;
get registry() {
return this.cache;
}

/**
Expand All @@ -67,7 +68,7 @@ class ARegistry {
* @memberof ARegistry
*/
has(key) {
return this.registry.has(key);
return this.registry.has(key.toLowerCase() );
}

/**
Expand All @@ -81,26 +82,20 @@ class ARegistry {
return this.registry.get(key.toLowerCase() );
}

/**
* Get the registry
*
* @returns {Collection<T>} - The current registry
* @memberof ARegistry
*/
getAll() {
return this.registry;
}

/**
* Add an item to the registry
*
* @param {String} key
* @param {T} value
* @returns {Collection<T>} - The registry
* @returns {ARegistry} - The registry
* @memberof ARegistry
*/
add(key, value) {
return this.registry.set(key.toLowerCase(), value);
if (!(value instanceof this._base) ) {
throw new AxonError('Incorrect Object type', 'REGISTRY');
}
this.registry.set(key.toLowerCase(), value);
return this;
}

/**
Expand All @@ -111,12 +106,7 @@ class ARegistry {
* @memberof ARegistry
*/
remove(key) {
return this.registry.delete(key);
}

// for - of directly on the registry
[Symbol.iterator]() {
return this.registry[Symbol.iterator]();
return this.registry.delete(key.toLowerCase() );
}

/**
Expand Down
185 changes: 10 additions & 175 deletions src/Utility/Collection.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import Store from './Store';

/**
* Extended Map with built in methods for ease of data manipulation.
* Based on Eris.Collection
* Custom Store that uses Map as cache.
* Enforce that a single object type exists in a Collection.
*
* @author KhaaZ
*
* @class Collection
* @extends Map<string|number,T>
*
* @template T
* @class Collection
* @extends Store<T>
* @prop {T} baseObject - The base class for all items
*/
class Collection extends Map {
class Collection extends Store {
/**
* Creates an instance of Collection.
*
Expand All @@ -23,11 +24,11 @@ class Collection extends Map {
constructor(options = {} ) {
const { base: baseObject = null, iterable } = options;
if (iterable && Array.isArray(iterable) ) {
super(iterable);
super(new Map(iterable) );
} else if (iterable && iterable instanceof Object) {
super(Object.entries(iterable) );
super(new Map(Object.entries(iterable) ) );
} else {
super();
super(new Map() );
}
/**
* @type {new (...args) => T}
Expand All @@ -49,46 +50,6 @@ class Collection extends Map {
return new Collection( { base: array[0].constructor, iterable: array.map(e => [e[key], e] ) } );
}

/**
* Map to array
* [ value, value, value ]
*
* @returns {Array<T>}
* @memberof Collection
*/
toArray() {
return [...this.values()];
}

/**
* Map to object
* { key: value, key: value }
*
* @returns {{[key:string]: T}}
*
* @memberof Collection
*/
toObject() {
const obj = {};
for (const [key, value] of this.entries() ) {
obj[key] = value;
}
return obj;
}

/**
* Apply a function to the Collection and returns a new Collection
*
* @param {String} key - The property to use as key for the new Collection
* @param {String} func - The function name to apply to the Collection
* @param {...any} args - All the argument that need to be applied to the Collection
* @returns {Collection<T>} A new Collection modified by the apply call
* @memberof Collection
*/
apply(key, func, ...args) {
return new Collection( { base: this.baseObject, iterable: this[func](...args).map(e => [e[key], e] ) } );
}

/**
* Add an object
* If baseObject, add only if instance of baseObject
Expand All @@ -113,124 +74,11 @@ class Collection extends Map {
return value;
}

/**
* Return the first object to make the function evaluate true
*
* @param {(i: T) => boolean} func - A function that takes an object and returns true if it matches
* @returns {T} The first matching object, or null if no match
* @memberof Collection
*/
find(func) {
for (const item of this.values() ) {
if (func(item) ) {
return item;
}
}
return null;
}

/**
* Return an array with the results of applying the given function to each element
*
* @template R
* @param {(i: T) => R} func - A function that takes an object and returns something
* @returns {Array<R>} An array containing the results
* @memberof Collection
*/
map(func) {
const arr = [];
for (const item of this.values() ) {
arr.push(func(item) );
}
return arr;
}

/**
* Return all the objects that make the function evaluate true
*
* @param {(i: T) => boolean} func - A function that takes an object and returns true if it matches
* @returns {Array<T>} An array containing all the objects that matched
* @memberof Collection
*/
filter(func) {
const arr = [];
for (const item of this.values() ) {
if (func(item) ) {
arr.push(item);
}
}
return arr;
}

/**
* Reduce values by function
*
* @template U
* @param {(accumulator: U, val: T) => U} func - Function to execute on each element in the array
* @param {Number} [initialValue=0] - Value to use as the first argument to the first call of the callback
* @returns {U} Accumulator
* @memberof Collection
*/
reduce(func, initialValue = 0) {
const iter = this.values();
let val;
let result = initialValue === undefined ? iter.next().value : initialValue;
while ( (val = iter.next().value) !== undefined) {
result = func(result, val);
}
return result;
}

/**
* Test if at least one element passes the test implemented by the provided function. Returns true if yes, or false if not.
*
* @param {(i: T) => boolean} func - A function that takes an object and returns true if it matches
* @returns {Boolean} An array containing all the objects that matched
* @memberof Collection
*/
some(func) {
for (const item of this.values() ) {
if (func(item) ) {
return true;
}
}
return false;
}

/**
* Test if all elements pass the test implemented by the provided function. Returns true if yes, or false if not.
*
* @param {(i: T) => boolean} func - A function that takes an object and returns true if it matches
* @returns {Boolean} An array containing all the objects that matched
* @memberof Collection
*/
every(func) {
for (const item of this.values() ) {
if (!func(item) ) {
return false;
}
}
return true;
}

/**
* Update an object
*
* @param {String} key - The ID of the object
* @param {T} value - The updated object data
* @returns {T} The updated object
* @memberof Collection
*/
update(key, value) {
return this.add(key, value, true);
}

/**
* Remove an object
*
* @param {String} key - The ID of the object
* @returns {T} The removed object, or null if nothing was removed
*
* @memberof Collection
*/
remove(key) {
Expand All @@ -242,19 +90,6 @@ class Collection extends Map {
return item;
}

/**
* Get a random object from the Collection
*
* @returns {T?} The random object, or null if there is no match
* @memberof Collection
*/
random() {
if (!this.size) {
return null;
}
return Array.from(this.values() )[Math.floor(Math.random() * this.size)];
}

toString() {
return `[Collection<${this.baseObject.name}>]`;
}
Expand Down
Loading