@e-mc/core 0.13.4 → 0.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +14 -11
  2. package/index.js +312 -189
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- * [View Source](https://www.unpkg.com/@e-mc/types@0.13.4/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.13.6/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { DataSource, LogStatus, WorkerAction } from "./squared";
@@ -74,7 +74,7 @@ interface HostConstructor extends ModuleConstructor {
74
74
  getThreadCount(full: true): ThreadCountStat;
75
75
  getThreadCount(username: string, iv?: BinaryLike): ThreadCountStat;
76
76
  getThreadCount(username?: string | boolean, iv?: BinaryLike): number;
77
- getPermissionFromSettings(): IPermission;
77
+ getPermissionFromSettings(freeze?: boolean): IPermission;
78
78
  readonly prototype: IHost;
79
79
  new(config?: HostInitConfig): IHost;
80
80
  }
@@ -132,10 +132,13 @@ interface ClientDbConstructor extends ClientConstructor<IHost, ClientModule> {
132
132
  convertTime(value: number | string): number;
133
133
  findResult(source: string, credential: unknown, queryString: string, timeout: number, sessionKey?: string | boolean, renewCache?: boolean): QueryResult | undefined;
134
134
  storeResult(source: string, credential: unknown, queryString: string, result: QueryResult, options: StoreResultOptions): QueryResult;
135
+ /** @deprecated */
135
136
  storeResult(source: string, credential: unknown, queryString: string, result: QueryResult, sessionKey: string, sessionExpires: number): QueryResult;
136
137
  storeResult(source: string, credential: unknown, queryString: string, result: QueryResult, cache: DbCacheValue): QueryResult;
137
- storeResult(source: string, credential: unknown, queryString: string, result: QueryResult, cache: DbCacheValue | undefined, options: StoreResultOptions): QueryResult;
138
- purgeResult(prefix?: string): Promise<number>;
138
+ storeResult(source: string, credential: unknown, queryString: string, result: QueryResult, cache: DbCacheValue | undefined, options: Omit<StoreResultOptions, "cache">): QueryResult;
139
+ findSession(source: string, user: string, key: string): unknown;
140
+ storeSession(source: string, user: string, key: string, result: unknown, expires?: number): void;
141
+ purgeResult(prefix?: string, lru?: boolean | number): Promise<number>;
139
142
  extractUUID(credential: unknown): string;
140
143
  setPoolConfig(value: unknown): void;
141
144
  getPoolConfig(source: string): unknown;
@@ -319,13 +322,13 @@ NOTE: **@e-mc/core** is mostly a collection of abstract base classes which canno
319
322
 
320
323
  ## References
321
324
 
322
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/squared.d.ts
323
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/core.d.ts
324
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/db.d.ts
325
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/dom.d.ts
326
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/logger.d.ts
327
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/node.d.ts
328
- - https://www.unpkg.com/@e-mc/types@0.13.4/lib/settings.d.ts
325
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/squared.d.ts
326
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/core.d.ts
327
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/db.d.ts
328
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/dom.d.ts
329
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/logger.d.ts
330
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/node.d.ts
331
+ - https://www.unpkg.com/@e-mc/types@0.13.6/lib/settings.d.ts
329
332
 
330
333
  * https://www.npmjs.com/package/@types/node
331
334
 
package/index.js CHANGED
@@ -3,7 +3,6 @@ var _a;
3
3
  exports.Module = exports.Permission = exports.AbortComponent = exports.WorkerChannel = exports.WorkerGroup = exports.ClientDb = exports.Client = exports.Host = void 0;
4
4
  const path = require("node:path");
5
5
  const fs = require("node:fs");
6
- const os = require("node:os");
7
6
  const pm = require("picomatch");
8
7
  const ipaddr = require("ipaddr.js");
9
8
  const EventEmitter = require("node:events");
@@ -15,7 +14,7 @@ exports.Module = module_1;
15
14
  const kHost = Symbol.for('host:constructor');
16
15
  const kClient = Symbol.for('client:constructor');
17
16
  const kClientDb = Symbol.for('clientdb:constructor');
18
- const CACHE_USER = {};
17
+ const CACHE_USER = Object.create(null);
19
18
  const CACHE_SOURCE = Object.create(null);
20
19
  const CACHE_SESSION = Object.create(null);
21
20
  const ABORT_LISTENER = new WeakMap();
@@ -43,7 +42,7 @@ const HOST = {
43
42
  LOG_PROGRESS_PAUSED: new Set()
44
43
  };
45
44
  const WORKER_GROUP = {
46
- MAX: (0, types_1.supported)(19, 4) || (0, types_1.supported)(18, 14, true) ? os.availableParallelism() : os.cpus().length,
45
+ MAX: module_1.availableParallelism(),
47
46
  TIMEOUT: Infinity,
48
47
  LOCKED: true
49
48
  };
@@ -159,65 +158,13 @@ function resumeHostQueue(item, aborted) {
159
158
  function encryptText(data, iv) {
160
159
  return HOST.CIPHER && (0, types_1.isString)(data) && (0, types_1.encryptUTF8)(HOST.CIPHER.algorithm, HOST.CIPHER.key, iv, data) || '';
161
160
  }
162
- function clearSourceResult(data) {
163
- const result = data[1];
164
- data[1] = null;
165
- if (typeof result === 'string') {
166
- fs.unlink(result, () => { });
167
- }
168
- }
169
- function addSourceResult(source, data) {
170
- const { items, config } = CACHE_SOURCE[source] ||= { items: [] };
171
- if (config && items.length >= config.limit) {
172
- const { percent, min } = config;
173
- if (percent === 1) {
174
- for (const item of items) {
175
- clearSourceResult(item);
176
- }
177
- items.length = 0;
178
- }
179
- else {
180
- items.sort((a, b) => a[2] - b[2]);
181
- for (let i = 0, length = Math.floor(items.length * percent); i < length; ++i) {
182
- const item = items[i];
183
- if (min === 0 || item[3] < min) {
184
- clearSourceResult(item);
185
- items.splice(i--, 1);
186
- --length;
187
- }
188
- }
189
- }
190
- }
191
- items.push(data);
192
- }
193
- function deleteSourceResult(source, data) {
194
- const stored = CACHE_SOURCE[source];
195
- if (stored) {
196
- const items = stored.items;
197
- const index = items.findIndex(item => item === data);
198
- if (index !== -1) {
199
- items.splice(index, 1);
200
- }
201
- }
202
- }
203
- function incrementSourceCount(source, data, cacheData, queryString) {
204
- const count = ++data[3];
205
- const stored = CACHE_SOURCE[source];
206
- if (stored?.config && count >= stored.config.max) {
207
- clearSourceResult(data);
208
- deleteSourceResult(source, data);
209
- if (cacheData && queryString) {
210
- delete cacheData[queryString];
211
- }
212
- }
213
- }
214
161
  function getSettingsValue(options, name, component) {
215
162
  const result = options[name];
216
163
  return component ? (0, types_1.isObject)(result) ? result[component] : undefined : result;
217
164
  }
218
165
  function isInvalidRange(result, range) {
219
166
  const [lower, upper = 0] = range;
220
- return result.length <= lower || upper > 0 && result.length > upper;
167
+ return Array.isArray(result) && (result.length <= lower || upper > 0 && result.length > upper);
221
168
  }
222
169
  function asPosix(value) {
223
170
  if (module_1.PLATFORM_WIN32) {
@@ -251,6 +198,192 @@ function parseIp(value, kind) {
251
198
  const readable = (value) => (0, types_1.isString)(value) || (0, types_1.isArray)(value);
252
199
  const expireTime = (value) => Date.now() + value * 1000;
253
200
  const convertSeconds = (value) => typeof value === 'string' && Math.ceil((0, types_1.parseTime)(value) / 1000) || 0;
201
+ class DbLRU {
202
+ static get(source) {
203
+ return CACHE_SOURCE[source] ||= new DbLRU();
204
+ }
205
+ static purge(source, value) {
206
+ const target = this.get(source);
207
+ const items = target.items;
208
+ for (let i = 0, length = items.length; i < length; ++i) {
209
+ const item = items[i];
210
+ if (item.value === value) {
211
+ item.delete(false);
212
+ items.splice(i, 1);
213
+ return true;
214
+ }
215
+ }
216
+ return false;
217
+ }
218
+ items = [];
219
+ config = null;
220
+ refresh(percent) {
221
+ const { items, config } = this;
222
+ let result = 0;
223
+ if (config && items.length >= config.limit || percent) {
224
+ percent = Math.min(1, percent ?? config.percent);
225
+ if (percent === 1) {
226
+ result = items.length;
227
+ for (let i = 0; i < result; ++i) {
228
+ items[i].delete(false);
229
+ }
230
+ items.length = 0;
231
+ }
232
+ else {
233
+ const min = config?.min || 0;
234
+ const data = items.slice(0).sort((a, b) => a.lastAccessed - b.lastAccessed);
235
+ for (let i = 0, length = Math.floor(data.length * Math.min(percent, 1)); i < length; ++i) {
236
+ const item = data[i];
237
+ if (min === 0 || item.accessCount < min) {
238
+ item.delete(true);
239
+ ++result;
240
+ }
241
+ }
242
+ }
243
+ }
244
+ return result;
245
+ }
246
+ }
247
+ class DbCache {
248
+ source;
249
+ user;
250
+ query;
251
+ value;
252
+ expires;
253
+ accessCount = 0;
254
+ lastAccessed = Date.now();
255
+ disposed = false;
256
+ userData;
257
+ queryData;
258
+ sourceList;
259
+ constructor(source, user, query, value, expires) {
260
+ this.source = source;
261
+ this.user = user;
262
+ this.query = query;
263
+ this.value = value;
264
+ this.expires = expires;
265
+ this.userData = CACHE_USER[source] ||= Object.create(null);
266
+ this.queryData = this.userData[user] ||= Object.create(null);
267
+ this.queryData[query] = this;
268
+ this.sourceList = DbLRU.get(source);
269
+ this.sourceList.refresh();
270
+ this.sourceList.items.push(this);
271
+ }
272
+ get(seconds) {
273
+ const current = Date.now();
274
+ if (seconds > 0) {
275
+ this.expires = expireTime(seconds);
276
+ }
277
+ else if (current >= this.expires) {
278
+ this.delete(true);
279
+ return;
280
+ }
281
+ let result = this.value;
282
+ if (typeof result === 'string') {
283
+ try {
284
+ result = JSON.parse(fs.readFileSync(result, 'utf8'));
285
+ }
286
+ catch {
287
+ result = null;
288
+ }
289
+ }
290
+ if (Array.isArray(result)) {
291
+ this.update(current);
292
+ return result;
293
+ }
294
+ this.delete(true);
295
+ }
296
+ update(current) {
297
+ const count = ++this.accessCount;
298
+ const config = this.sourceList.config;
299
+ if (config && count >= config.max) {
300
+ this.delete(true);
301
+ }
302
+ else {
303
+ this.lastAccessed = current;
304
+ }
305
+ }
306
+ delete(lru) {
307
+ if (!this.disposed) {
308
+ const value = this.value;
309
+ this.value = null;
310
+ this.queryData[this.query] = null;
311
+ this.disposed = true;
312
+ if (lru) {
313
+ const items = this.sourceList.items;
314
+ const index = items.findIndex(item => item === this);
315
+ if (index !== -1) {
316
+ items.splice(index, 1);
317
+ }
318
+ }
319
+ void this.cleanup(value);
320
+ }
321
+ }
322
+ async cleanup(value) {
323
+ const data = this.queryData;
324
+ let found = false;
325
+ for (const query in data) {
326
+ if (data[query]) {
327
+ found = true;
328
+ break;
329
+ }
330
+ }
331
+ if (!found) {
332
+ delete this.userData[this.user];
333
+ }
334
+ if (typeof value === 'string') {
335
+ try {
336
+ fs.unlinkSync(value);
337
+ }
338
+ catch {
339
+ }
340
+ }
341
+ }
342
+ expired(current) {
343
+ if (current >= this.expires) {
344
+ this.delete(true);
345
+ return true;
346
+ }
347
+ return false;
348
+ }
349
+ }
350
+ class DbSession {
351
+ source;
352
+ sourceData = Object.create(null);
353
+ constructor(source) {
354
+ this.source = source;
355
+ const timer = setInterval(() => {
356
+ this.clear();
357
+ if (this.users.length === 0) {
358
+ CACHE_SESSION[source] = undefined;
359
+ clearInterval(timer);
360
+ }
361
+ }, 60000);
362
+ }
363
+ set(user, key, result, seconds) {
364
+ let data = this.sourceData[user];
365
+ if (!data) {
366
+ data = [Object.create(null), Date.now() + Math.trunc(seconds * 1000)];
367
+ this.sourceData[user] = data;
368
+ }
369
+ data[0][key] = result;
370
+ }
371
+ get(user, key) {
372
+ return this.sourceData[user]?.[0][key];
373
+ }
374
+ clear() {
375
+ const current = Date.now();
376
+ for (const user of this.users) {
377
+ const expires = this.sourceData[user][1];
378
+ if (expires >= current) {
379
+ delete this.sourceData[user];
380
+ }
381
+ }
382
+ }
383
+ get users() {
384
+ return Object.keys(this.sourceData);
385
+ }
386
+ }
254
387
  class Host extends module_1 {
255
388
  static [kHost] = true;
256
389
  static async purgeMemory(percent = 1, limit = 0, parent) {
@@ -281,6 +414,7 @@ class Host extends module_1 {
281
414
  if (permission.unc_write) {
282
415
  PERMISSION.setUNCWrite(unc_write);
283
416
  }
417
+ Object.freeze(PERMISSION);
284
418
  }
285
419
  if (perm.settings) {
286
420
  const { picomatch: pico, minimatch: mini } = perm.settings;
@@ -486,8 +620,8 @@ class Host extends module_1 {
486
620
  static getLogDelayed() {
487
621
  return HOST.LOG_DELAYED;
488
622
  }
489
- static getPermissionFromSettings() {
490
- return PERMISSION;
623
+ static getPermissionFromSettings(freeze = true) {
624
+ return freeze ? PERMISSION : Permission.clone(PERMISSION);
491
625
  }
492
626
  restartable = true;
493
627
  modules = new Set();
@@ -896,7 +1030,6 @@ class ClientDb extends Client {
896
1030
  const item = client[source];
897
1031
  if ((0, types_1.isPlainObject)(item) && 'enabled' in item) {
898
1032
  const key = name + '_' + source;
899
- const stored = CACHE_SOURCE[key];
900
1033
  const { enabled, limit = 0, min = 0, max = 0 } = item;
901
1034
  if (enabled && +limit > 0) {
902
1035
  let percent = item.percent || 0;
@@ -907,11 +1040,16 @@ class ClientDb extends Client {
907
1040
  percent /= 100;
908
1041
  }
909
1042
  if (percent > 0) {
910
- (stored || (CACHE_SOURCE[key] = { items: [] })).config = { limit: +limit > 0 ? +limit : 0, percent: Math.min(percent, 1), min: min > 0 ? min : 0, max: max > 0 ? max : Infinity };
1043
+ DbLRU.get(key).config = {
1044
+ limit: +limit,
1045
+ percent: Math.min(percent, 1),
1046
+ min: min > 0 ? min : 0,
1047
+ max: max > 0 ? max : Infinity
1048
+ };
911
1049
  }
912
1050
  }
913
- else if (stored) {
914
- delete stored.config;
1051
+ else if (CACHE_SOURCE[key]) {
1052
+ CACHE_SOURCE[key].config = null;
915
1053
  }
916
1054
  }
917
1055
  }
@@ -958,96 +1096,63 @@ class ClientDb extends Client {
958
1096
  }
959
1097
  static findResult(source, credential, queryString, timeout, sessionKey, renewCache) {
960
1098
  const userKey = credential ? this.extractUUID(credential) || (0, types_1.hashKey)(this.asString(credential)) : undefined;
961
- if (!userKey) {
962
- return;
963
- }
964
- queryString = (0, types_1.hashKey)(queryString);
965
- if (timeout > 0) {
966
- const userCache = CACHE_USER[source]?.[userKey];
967
- let stored;
968
- if (!(userCache && (stored = userCache[queryString]))) {
969
- return;
970
- }
971
- const [expires, result] = stored;
972
- if (result) {
973
- const current = Date.now();
974
- let valid = false;
975
- if (renewCache) {
976
- stored[0] = expireTime(timeout);
977
- valid = true;
978
- }
979
- else if (current < expires) {
980
- valid = true;
981
- }
982
- if (valid) {
983
- stored[2] = current;
984
- incrementSourceCount(source, stored, userCache, queryString);
985
- if (Array.isArray(result)) {
986
- return result;
987
- }
988
- try {
989
- return JSON.parse(fs.readFileSync(result, 'utf8'));
990
- }
991
- catch {
992
- }
1099
+ if (userKey) {
1100
+ queryString = (0, types_1.hashKey)(queryString);
1101
+ if (timeout > 0) {
1102
+ const stored = CACHE_USER[source]?.[userKey]?.[queryString];
1103
+ if (stored) {
1104
+ return stored.get(renewCache ? timeout : 0);
993
1105
  }
994
- clearSourceResult(stored);
995
1106
  }
996
- deleteSourceResult(source, stored);
997
- delete userCache[queryString];
998
- }
999
- else if (sessionKey) {
1000
- return CACHE_SESSION[source]?.[userKey + sessionKey]?.[queryString];
1107
+ else if (sessionKey) {
1108
+ return this.findSession(source, userKey + sessionKey, queryString);
1109
+ }
1001
1110
  }
1002
1111
  }
1003
- static storeResult(source, credential, queryString, result, options, sessionKey, sessionExpires) {
1004
- if (!credential) {
1112
+ static storeResult(source, credential, queryString, result, cache, sessionKey, sessionExpires) {
1113
+ if (!credential || !Array.isArray(result)) {
1005
1114
  return result;
1006
1115
  }
1007
- let cache, cacheDir;
1116
+ let cacheDir;
1008
1117
  if ((0, types_1.isObject)(sessionKey)) {
1009
1118
  ({ cacheDir, sessionKey, sessionExpires } = sessionKey);
1010
1119
  }
1011
- else if ((0, types_1.isObject)(options) && 'cache' in options) {
1012
- ({ cache, cacheDir, sessionKey, sessionExpires } = options);
1120
+ else if ((0, types_1.isObject)(cache) && 'cache' in cache) {
1121
+ ({ cache, cacheDir, sessionKey, sessionExpires } = cache);
1013
1122
  }
1014
1123
  let timeout = 0, userKey, whenEmpty, partition = false;
1015
- if (cache) {
1016
- switch (typeof cache) {
1017
- case 'number':
1018
- timeout = cache;
1019
- break;
1020
- case 'string':
1021
- if (typeof sessionKey === 'number') {
1022
- sessionExpires = sessionKey;
1023
- sessionKey = cache;
1024
- break;
1025
- }
1026
- timeout = convertSeconds(cache);
1027
- break;
1028
- case 'object': {
1029
- let seconds, dir;
1030
- ({ timeout: seconds, when_empty: whenEmpty, dir } = cache);
1031
- if ((0, types_1.isString)(dir) && (!cacheDir || module_1.isDir(dir))) {
1032
- cacheDir = dir;
1033
- partition = true;
1034
- }
1035
- if (typeof seconds === 'number') {
1036
- timeout = seconds;
1037
- }
1038
- else {
1039
- cache.timeout = seconds ? convertSeconds(seconds) : 0;
1040
- }
1041
- break;
1124
+ switch (typeof cache) {
1125
+ case 'object': {
1126
+ let seconds, dir;
1127
+ ({ timeout: seconds, when_empty: whenEmpty, dir } = cache);
1128
+ if (dir && (!cacheDir || module_1.isDir(dir))) {
1129
+ cacheDir = dir;
1130
+ partition = true;
1131
+ }
1132
+ if (typeof seconds === 'number') {
1133
+ timeout = seconds;
1042
1134
  }
1135
+ else {
1136
+ cache.timeout = seconds ? timeout = convertSeconds(seconds) : 0;
1137
+ }
1138
+ break;
1043
1139
  }
1140
+ case 'number':
1141
+ timeout = cache;
1142
+ break;
1143
+ case 'string':
1144
+ if (typeof sessionKey === 'number') {
1145
+ sessionExpires = sessionKey;
1146
+ sessionKey = cache;
1147
+ break;
1148
+ }
1149
+ timeout = convertSeconds(cache);
1150
+ break;
1044
1151
  }
1045
1152
  if ((result.length > 0 || whenEmpty) && (userKey = this.extractUUID(credential) || (0, types_1.hashKey)(this.asString(credential)))) {
1046
1153
  queryString = (0, types_1.hashKey)(queryString);
1047
1154
  if (timeout > 0) {
1048
- const item = [expireTime(timeout), result, Date.now(), 0];
1049
- ((CACHE_USER[source] ||= {})[userKey] ||= {})[queryString] = item;
1050
- addSourceResult(source, item);
1155
+ const item = new DbCache(source, userKey, queryString, result, expireTime(timeout));
1051
1156
  if (cacheDir) {
1052
1157
  if (partition) {
1053
1158
  if (STORE_RESULT_COUNT === this.STORE_RESULT_PARTITION_SIZE) {
@@ -1061,61 +1166,62 @@ class ClientDb extends Client {
1061
1166
  const pathname = path.join(cacheDir, queryString);
1062
1167
  fs.writeFile(pathname, JSON.stringify(result), err => {
1063
1168
  if (!err) {
1064
- item[1] = pathname;
1169
+ item.value = pathname;
1065
1170
  }
1066
1171
  });
1067
1172
  }
1068
1173
  }
1069
- else if (typeof sessionKey === 'string' && sessionExpires && sessionExpires > 0) {
1070
- const dbKey = userKey + sessionKey;
1071
- ((CACHE_SESSION[source] ||= {})[dbKey] ||= {})[queryString] = result;
1072
- setTimeout(() => delete CACHE_SESSION[dbKey], sessionExpires * 1000);
1174
+ else if (typeof sessionKey === 'string' && typeof sessionExpires === 'number' && sessionExpires > 0) {
1175
+ this.storeSession(source, userKey + sessionKey, queryString, result, sessionExpires);
1073
1176
  }
1074
1177
  }
1075
1178
  return result;
1076
1179
  }
1077
- static async purgeResult(prefix) {
1078
- const current = Date.now();
1079
- const providers = new Map();
1180
+ static findSession(source, user, key) {
1181
+ return CACHE_SESSION[source]?.get(user, key);
1182
+ }
1183
+ static storeSession(source, user, key, result, expires = 600) {
1184
+ (CACHE_SESSION[source] ||= new DbSession(source)).set(user, key, result, expires);
1185
+ }
1186
+ static async purgeResult(prefix, lru) {
1187
+ const cache = lru ? CACHE_SOURCE : CACHE_USER;
1188
+ const items = [];
1080
1189
  if (prefix) {
1081
1190
  if (!prefix.includes('_')) {
1082
1191
  prefix += '_';
1083
- for (const key in CACHE_USER) {
1192
+ for (const key in cache) {
1084
1193
  if (key.startsWith(prefix)) {
1085
- providers.set(key, CACHE_USER[key]);
1194
+ items.push(cache[key]);
1086
1195
  }
1087
1196
  }
1088
1197
  }
1089
- else {
1090
- const source = CACHE_USER[prefix];
1091
- if (source) {
1092
- providers.set(prefix, source);
1093
- }
1198
+ else if (cache[prefix]) {
1199
+ items.push(cache[prefix]);
1094
1200
  }
1095
1201
  }
1096
1202
  else {
1097
- for (const key in CACHE_USER) {
1098
- providers.set(key, CACHE_USER[key]);
1203
+ for (const key in cache) {
1204
+ items.push(cache[key]);
1099
1205
  }
1100
1206
  }
1101
1207
  let result = 0;
1102
- for (const [source, data] of providers) {
1103
- for (const user in data) {
1104
- const queries = data[user];
1105
- for (const query in queries) {
1106
- const item = queries[query];
1107
- if (current >= item[0]) {
1108
- ++result;
1109
- delete queries[query];
1110
- deleteSourceResult(source, item);
1111
- if (typeof item[1] === 'string') {
1112
- fs.unlink(item[1], () => { });
1208
+ if (lru) {
1209
+ for (const source of items) {
1210
+ result += source.refresh(typeof lru === 'number' ? lru : undefined);
1211
+ }
1212
+ }
1213
+ else {
1214
+ const current = Date.now();
1215
+ for (const source of items) {
1216
+ for (const session in source) {
1217
+ const data = source[session];
1218
+ for (const query in data) {
1219
+ const item = data[query];
1220
+ if (item.expired(current)) {
1221
+ ++result;
1113
1222
  }
1114
1223
  }
1115
1224
  }
1116
- if (Object.keys(queries).length === 0) {
1117
- delete data[user];
1118
- }
1119
1225
  }
1120
1226
  }
1121
1227
  return result;
@@ -1201,14 +1307,14 @@ class ClientDb extends Client {
1201
1307
  break;
1202
1308
  case 'object':
1203
1309
  if (options !== null) {
1204
- ({ value, sessionKey, renewCache, exclusiveOf } = options);
1310
+ ({ value, sessionKey, exclusiveOf, renewCache } = options);
1205
1311
  if (Array.isArray(exclusiveOf)) {
1206
1312
  const ignoreCache = exclusiveOf[2];
1207
1313
  if (ignoreCache === 1) {
1208
1314
  return;
1209
1315
  }
1210
1316
  renewCache ||= ignoreCache === 0;
1211
- queryString += '_' + exclusiveOf.toString();
1317
+ queryString += '_' + exclusiveOf.slice(0, 2).toString();
1212
1318
  }
1213
1319
  }
1214
1320
  break;
@@ -1220,8 +1326,14 @@ class ClientDb extends Client {
1220
1326
  value = cache;
1221
1327
  }
1222
1328
  }
1223
- const result = ClientDb.findResult(this.moduleName + '_' + source, uuidKey || credential, queryString, value === 0 ? 0 : ClientDb.getTimeout(value || this.settingsOf(source, 'cache')), sessionKey, renewCache);
1224
- if (!exclusiveOf || !isInvalidRange(result, exclusiveOf)) {
1329
+ const result = ClientDb.findResult(this.getSourceName(source), uuidKey || credential, queryString, value === 0 ? 0 : ClientDb.getTimeout(value || this.settingsOf(source, 'cache')), sessionKey, renewCache);
1330
+ if (result) {
1331
+ if (exclusiveOf && isInvalidRange(result, exclusiveOf)) {
1332
+ if (exclusiveOf[2] === 2) {
1333
+ DbLRU.purge(this.getSourceName(source), result);
1334
+ }
1335
+ return;
1336
+ }
1225
1337
  return result;
1226
1338
  }
1227
1339
  }
@@ -1233,30 +1345,37 @@ class ClientDb extends Client {
1233
1345
  return result;
1234
1346
  }
1235
1347
  const uuidKey = ClientDb.extractUUID(credential);
1236
- let options;
1237
- if (this.hasPermission('memory')) {
1238
- let value, exclusiveOf;
1239
- if ((0, types_1.isObject)(sessionKey)) {
1240
- ({ value, sessionKey, exclusiveOf } = sessionKey);
1348
+ let value, exclusiveOf;
1349
+ if ((0, types_1.isObject)(sessionKey)) {
1350
+ ({ value, sessionKey, exclusiveOf } = sessionKey);
1351
+ }
1352
+ if (Array.isArray(exclusiveOf)) {
1353
+ if (isInvalidRange(result, exclusiveOf)) {
1354
+ return result;
1241
1355
  }
1242
- if (Array.isArray(exclusiveOf)) {
1243
- if (isInvalidRange(result, exclusiveOf)) {
1244
- return result;
1245
- }
1246
- queryString += '_' + exclusiveOf.toString();
1356
+ queryString += '_' + exclusiveOf.slice(0, 2).toString();
1357
+ }
1358
+ if (uuidKey) {
1359
+ const cache = this.settingsKey(uuidKey, 'cache');
1360
+ if (cache !== undefined) {
1361
+ value = cache;
1247
1362
  }
1248
- if (uuidKey) {
1249
- const cache = this.settingsKey(uuidKey, 'cache');
1250
- if (cache !== undefined) {
1251
- value = cache;
1252
- }
1363
+ }
1364
+ const cacheDir = this.cacheDir;
1365
+ value ??= this.settingsOf(source, 'cache');
1366
+ let options;
1367
+ if (this.hasPermission('memory')) {
1368
+ if (cacheDir || sessionKey) {
1369
+ options = { cacheDir, sessionKey, sessionExpires: this.cacheExpires / 1000 };
1253
1370
  }
1254
- options = { cache: value === 0 ? 0 : value || this.settingsOf(source, 'cache'), cacheDir: this.cacheDir, sessionKey, sessionExpires: this.cacheExpires / 1000 };
1255
1371
  }
1256
- else {
1257
- options = { cacheDir: this.cacheDir };
1372
+ else if (cacheDir) {
1373
+ options = { cacheDir };
1374
+ }
1375
+ else if (!(0, types_1.isObject)(value) || !(0, types_1.isString)(value.dir)) {
1376
+ return result;
1258
1377
  }
1259
- return ClientDb.storeResult(this.moduleName + '_' + source, uuidKey || credential, queryString, result, options);
1378
+ return value || options ? ClientDb.storeResult(this.getSourceName(source), uuidKey || credential, queryString, result, value, options) : result;
1260
1379
  }
1261
1380
  getCacheResult(source, credential, queryString, cacheValue, ignoreCache) {
1262
1381
  if (ignoreCache !== 1) {
@@ -1301,6 +1420,9 @@ class ClientDb extends Client {
1301
1420
  return getSettingsValue(data, name, component);
1302
1421
  }
1303
1422
  }
1423
+ getSourceName(value) {
1424
+ return this.moduleName + '_' + value;
1425
+ }
1304
1426
  get pending() {
1305
1427
  return this.database.filter(item => {
1306
1428
  const state = item.transactionState || 0;
@@ -2017,3 +2139,4 @@ class Permission {
2017
2139
  exports.Permission = Permission;
2018
2140
  _a = Permission;
2019
2141
  PERMISSION = Host.createPermission(true, true);
2142
+ Object.freeze(PERMISSION);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/core",
3
- "version": "0.13.4",
3
+ "version": "0.13.6",
4
4
  "description": "Core modules for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -19,9 +19,9 @@
19
19
  "license": "BSD-3-Clause",
20
20
  "homepage": "https://github.com/anpham6/e-mc#readme",
21
21
  "dependencies": {
22
- "@e-mc/module": "0.13.4",
23
- "@e-mc/types": "0.13.4",
24
- "ipaddr.js": "^2.2.0",
22
+ "@e-mc/module": "0.13.6",
23
+ "@e-mc/types": "0.13.6",
24
+ "ipaddr.js": "^2.3.0",
25
25
  "picomatch": "^4.0.3"
26
26
  }
27
27
  }