@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.
- package/README.md +14 -11
- package/index.js +312 -189
- 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.
|
|
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
|
-
|
|
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.
|
|
323
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
324
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
325
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
326
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
327
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
328
|
-
- https://www.unpkg.com/@e-mc/types@0.13.
|
|
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:
|
|
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
|
-
(
|
|
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 (
|
|
914
|
-
|
|
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 (
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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
|
-
|
|
997
|
-
|
|
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,
|
|
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
|
|
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)(
|
|
1012
|
-
({ cache, cacheDir, sessionKey, sessionExpires } =
|
|
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
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
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 =
|
|
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
|
|
1169
|
+
item.value = pathname;
|
|
1065
1170
|
}
|
|
1066
1171
|
});
|
|
1067
1172
|
}
|
|
1068
1173
|
}
|
|
1069
|
-
else if (typeof sessionKey === 'string' && sessionExpires && sessionExpires > 0) {
|
|
1070
|
-
|
|
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
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
|
1192
|
+
for (const key in cache) {
|
|
1084
1193
|
if (key.startsWith(prefix)) {
|
|
1085
|
-
|
|
1194
|
+
items.push(cache[key]);
|
|
1086
1195
|
}
|
|
1087
1196
|
}
|
|
1088
1197
|
}
|
|
1089
|
-
else {
|
|
1090
|
-
|
|
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
|
|
1098
|
-
|
|
1203
|
+
for (const key in cache) {
|
|
1204
|
+
items.push(cache[key]);
|
|
1099
1205
|
}
|
|
1100
1206
|
}
|
|
1101
1207
|
let result = 0;
|
|
1102
|
-
|
|
1103
|
-
for (const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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,
|
|
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.
|
|
1224
|
-
if (
|
|
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
|
|
1237
|
-
if (
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
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
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
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
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
23
|
-
"@e-mc/types": "0.13.
|
|
24
|
-
"ipaddr.js": "^2.
|
|
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
|
}
|