This repository has been archived by the owner on Apr 27, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
MemberGateway.js
137 lines (117 loc) · 3.79 KB
/
MemberGateway.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const { GatewayStorage, Settings, util: { getIdentifier } } = require('klasa');
const { Collection } = require('discord.js');
/**
* The Gateway class that manages the data input, parsing, and output, of an entire database, while keeping a cache system sync with the changes.
* @extends GatewayStorage
*/
class MemberGateway extends GatewayStorage {
/**
* @since 0.0.1
* @param {GatewayDriver} store The GatewayDriver instance which initiated this instance
* @param {string} type The name of this Gateway
* @param {external:Schema} schema The schema for this gateway
* @param {string} provider The provider's name for this gateway
*/
constructor(store, type, schema, provider) {
super(store.client, type, schema, provider);
/**
* The GatewayDriver that manages this Gateway
* @since 0.0.1
* @type {external:GatewayDriver}
*/
this.store = store;
/**
* The synchronization queue for all Settings instances
* @since 0.0.1
* @type {external:Collection<string, Promise<external:Settings>>}
*/
this.syncQueue = new Collection();
/**
* @since 0.0.1
* @type {boolean}
* @private
*/
Object.defineProperty(this, '_synced', { value: false, writable: true });
}
/**
* The Settings that this class should make.
* @since 0.0.1
* @type {external:Settings}
* @readonly
* @private
*/
get Settings() {
return Settings;
}
/**
* The ID length for all entries.
* @since 0.0.1
* @type {number}
* @readonly
* @private
*/
get idLength() {
// 18 + 1 + 18: `{MEMBERID}.{GUILDID}`
return 37;
}
/**
* Get a Settings entry from this gateway
* @since 0.0.1
* @param {string|string[]} id The id for this instance
* @returns {?external:Settings}
*/
get(id) {
const [guildID, memberID] = typeof id === 'string' ? id.split('.') : id;
const guild = this.client.guilds.get(guildID);
if (guild) {
const member = guild.members.get(memberID);
return member && member.settings;
}
return undefined;
}
/**
* Create a new Settings for this gateway
* @since 0.0.1
* @param {string|string[]} id The id for this instance
* @param {Object<string, *>} [data={}] The data for this Settings instance
* @returns {external:Settings}
*/
create(id, data = {}) {
const [guildID, memberID] = typeof id === 'string' ? id.split('.') : id;
const entry = this.get([guildID, memberID]);
if (entry) return entry;
const settings = new this.Settings(this, { id: `${guildID}.${memberID}`, ...data });
if (this._synced) settings.sync();
return settings;
}
/**
* Sync either all entries from the cache with the persistent database, or a single one.
* @since 0.0.1
* @param {(Array<string>|string)} [input=Array<string>] An object containing a id property, like discord.js objects, or a string
* @returns {?(MemberGateway|external:Settings)}
*/
async sync(input = this.client.guilds.reduce((keys, guild) => keys.concat(guild.members.map(member => member.settings.id)), [])) {
if (Array.isArray(input)) {
if (!this._synced) this._synced = true;
const entries = await this.provider.getAll(this.type, input);
for (const entry of entries) {
if (!entry) continue;
// Get the entry from the cache
const cache = this.get(entry.id);
if (!cache) continue;
cache._existsInDB = true;
cache._patch(entry);
}
// Set all the remaining settings from unknown status in DB to not exists.
for (const guild of this.client.guilds.values()) {
for (const member of guild.members.values()) if (member.settings._existsInDB !== true) member.settings._existsInDB = false;
}
return this;
}
const target = getIdentifier(input);
if (!target) throw new TypeError('The selected target could not be resolved to a string.');
const cache = this.get(target);
return cache ? cache.sync() : null;
}
}
module.exports = MemberGateway;