@e-mc/core 0.11.14 → 0.11.15

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 (4) hide show
  1. package/LICENSE +3 -7
  2. package/README.md +8 -8
  3. package/index.js +122 -97
  4. package/package.json +4 -4
package/LICENSE CHANGED
@@ -1,11 +1,7 @@
1
1
  Copyright 2024 An Pham
2
2
 
3
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
-
9
- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
-
11
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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.11.14/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.11.15/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { DataSource, LogStatus } from "./squared";
@@ -232,13 +232,13 @@ NOTE: **@e-mc/core** is mostly a collection of abstract base classes which canno
232
232
 
233
233
  ## References
234
234
 
235
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/squared.d.ts
236
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/core.d.ts
237
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/db.d.ts
238
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/dom.d.ts
239
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/logger.d.ts
240
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/node.d.ts
241
- - https://www.unpkg.com/@e-mc/types@0.11.14/lib/settings.d.ts
235
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/squared.d.ts
236
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/core.d.ts
237
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/db.d.ts
238
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/dom.d.ts
239
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/logger.d.ts
240
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/node.d.ts
241
+ - https://www.unpkg.com/@e-mc/types@0.11.15/lib/settings.d.ts
242
242
 
243
243
  ## LICENSE
244
244
 
package/index.js CHANGED
@@ -68,10 +68,17 @@ function closeHostThread(host) {
68
68
  resumeHostQueue(item, true);
69
69
  }
70
70
  }
71
- if (HOST.QUEUE.length > 0 && HOST.DONE.size < HOST.THREAD_LIMIT) {
72
- const queue = HOST.QUEUE.shift();
73
- addHostThread(queue.instance);
74
- resumeHostQueue(queue);
71
+ const length = HOST.QUEUE.length;
72
+ if (length > 0 && HOST.DONE.size < HOST.THREAD_LIMIT) {
73
+ for (let i = 0; i < length; ++i) {
74
+ const queue = HOST.QUEUE[i];
75
+ if (queue.joined) {
76
+ addHostThread(queue.instance);
77
+ resumeHostQueue(queue);
78
+ HOST.QUEUE.splice(i, 1);
79
+ break;
80
+ }
81
+ }
75
82
  HOST.QUEUE.forEach((item, index) => {
76
83
  notifyHostQueue(item.instance, index, item.priority, true);
77
84
  });
@@ -145,16 +152,32 @@ function resumeHostQueue(item, aborted) {
145
152
  }
146
153
  }
147
154
  }
148
- HOST.LOG_PROGRESS_QUEUE.delete(instance);
149
155
  instance.writeTimeElapsed('JOIN', ['Thread restarting...', HOST.THREAD_LIMIT > 1 ? 'Availability: ' + HOST.DONE.size + ' / ' + HOST.THREAD_LIMIT : ''], startTime, { type: 2, ...module_1.LOG_STYLE_WARN });
150
156
  }
151
- queueMicrotask(() => {
152
- try {
157
+ HOST.LOG_PROGRESS_QUEUE.delete(instance);
158
+ if (typeof instance.resumeThread === 'function') {
159
+ queueMicrotask(() => {
153
160
  instance.resumeThread({ args, startTime, aborted });
161
+ });
162
+ }
163
+ }
164
+ function killHostThread() {
165
+ const items = [];
166
+ const current = Date.now();
167
+ for (const [host, pid] of HOST.DONE) {
168
+ if (host.done) {
169
+ closeHostThread(host);
154
170
  }
155
- catch {
171
+ else if (host.startTime + HOST.THREAD_EXPIRES >= current) {
172
+ host.writeFail(["Transaction was cancelled", host.username], (0, types_1.errorValue)("Timeout was exceeded", (0, types_1.formatTime)(HOST.THREAD_EXPIRES)), { fatal: true });
173
+ host.abort();
174
+ closeHostThread(host);
156
175
  }
157
- });
176
+ else {
177
+ items.push([host, pid]);
178
+ }
179
+ }
180
+ return items;
158
181
  }
159
182
  function encryptUsername(data, iv) {
160
183
  return HOST.CIPHER_ALGORITHM && HOST.CIPHER_KEY && (0, types_1.isString)(data) && (0, types_1.encryptUTF8)(HOST.CIPHER_ALGORITHM, HOST.CIPHER_KEY, iv, data) || '';
@@ -269,7 +292,7 @@ function parseIp(value, kind) {
269
292
  return '';
270
293
  }
271
294
  const readable = (value) => (0, types_1.isString)(value) || (0, types_1.isArray)(value);
272
- const expireTime = (value) => Date.now() + value * 1000;
295
+ const expireTime = (value) => Date.now() + Math.trunc(value * 1000);
273
296
  const convertSeconds = (value) => typeof value === 'string' && Math.ceil((0, types_1.parseTime)(value) / 1000) || 0;
274
297
  class Host extends module_1 {
275
298
  static async purgeMemory(percent = 1, limit = 0, parent) {
@@ -426,21 +449,7 @@ class Host extends module_1 {
426
449
  if (HOST.ADMIN_PRIVATE && !username) {
427
450
  return full ? { count: -1 } : -1;
428
451
  }
429
- const current = Date.now();
430
- const items = [];
431
- for (const [host, pid] of HOST.DONE) {
432
- if (host.done) {
433
- closeHostThread(host);
434
- }
435
- else if (host.startTime + HOST.THREAD_EXPIRES >= current) {
436
- host.writeFail(["Transaction was cancelled", host.username], (0, types_1.errorValue)("Timeout was exceeded", (0, types_1.formatTime)(HOST.THREAD_EXPIRES)), { fatal: true });
437
- host.abort();
438
- closeHostThread(host);
439
- }
440
- else {
441
- items.push([host, pid]);
442
- }
443
- }
452
+ const items = killHostThread();
444
453
  const count = items.length;
445
454
  if (full) {
446
455
  const result = { count, pending: HOST.QUEUE.length, opened: HOST.DONE.size, closed: HOST.CLOSED, queued: HOST.QUEUED, rejected: HOST.REJECTED, killed: HOST.KILLED };
@@ -525,10 +534,16 @@ class Host extends module_1 {
525
534
  this.ignoreLog(typeof log === 'boolean' ? !log : log);
526
535
  }
527
536
  this[kConfig] = Object.freeze({ ...config });
537
+ if (HOST.DONE.size >= HOST.THREAD_LIMIT) {
538
+ killHostThread();
539
+ }
528
540
  if (HOST.DONE.size < HOST.THREAD_LIMIT || this.username && typeof priority === 'number' && priority === HOST.PRIORITY_BYPASS) {
529
541
  HOST.DONE.set(this, HOST.PID++);
530
542
  if (HOST.LOG_PROGRESS) {
531
543
  this.pauseLog('progress');
544
+ if (showProgress) {
545
+ HOST.LOG_PROGRESS_QUEUE.add(this);
546
+ }
532
547
  }
533
548
  else if (showProgress) {
534
549
  HOST.LOG_PROGRESS = this;
@@ -727,10 +742,10 @@ class Host extends module_1 {
727
742
  addHostThread(this);
728
743
  return false;
729
744
  }
730
- if (Array.isArray(args)) {
731
- queue.args = args;
732
- }
733
745
  if (!queue.joined) {
746
+ if (Array.isArray(args)) {
747
+ queue.args = args;
748
+ }
734
749
  queue.joined = true;
735
750
  ++HOST.QUEUED;
736
751
  }
@@ -874,27 +889,29 @@ class ClientDb extends Client {
874
889
  const memory = settings.memory;
875
890
  if ((0, types_1.isPlainObject)(memory)) {
876
891
  for (const name in memory) {
877
- const client = memory[name];
878
- if ((0, types_1.isPlainObject)(client)) {
879
- for (const source in client) {
880
- const item = client[source];
881
- if ((0, types_1.isPlainObject)(item) && 'enabled' in item) {
882
- const key = name + '_' + source;
883
- const stored = CACHE_SOURCE[key];
884
- let { enabled, percent = 0, limit = 0, min = 0, max = 0 } = item;
885
- if (enabled && limit > 0) {
886
- if ((0, types_1.isString)(percent)) {
887
- percent = percent.includes('%') ? parseFloat(percent) / 100 : parseFloat(percent);
892
+ if (name !== 'settings') {
893
+ const client = memory[name];
894
+ if ((0, types_1.isPlainObject)(client)) {
895
+ for (const source in client) {
896
+ const item = client[source];
897
+ if ((0, types_1.isPlainObject)(item) && 'enabled' in item) {
898
+ const key = name + '_' + source;
899
+ const stored = CACHE_SOURCE[key];
900
+ let { enabled, percent = 0, limit = 0, min = 0, max = 0 } = item;
901
+ if (enabled && limit > 0) {
902
+ if ((0, types_1.isString)(percent)) {
903
+ percent = percent.includes('%') ? parseFloat(percent) / 100 : parseFloat(percent);
904
+ }
905
+ else if ((percent = Math.max(percent, 0)) > 1) {
906
+ percent /= 100;
907
+ }
908
+ if (percent > 0) {
909
+ (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 };
910
+ }
888
911
  }
889
- else if ((percent = Math.max(percent, 0)) > 1) {
890
- percent /= 100;
912
+ else if (stored) {
913
+ delete stored.config;
891
914
  }
892
- if (percent > 0) {
893
- (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 };
894
- }
895
- }
896
- else if (stored) {
897
- delete stored.config;
898
915
  }
899
916
  }
900
917
  }
@@ -907,7 +924,7 @@ class ClientDb extends Client {
907
924
  return parent ? super.purgeMemory(percent, limit, parent) : 0;
908
925
  }
909
926
  static getTimeout(value) {
910
- if (value === undefined) {
927
+ if (value == null) {
911
928
  return 0;
912
929
  }
913
930
  let result = 0;
@@ -944,11 +961,13 @@ class ClientDb extends Client {
944
961
  if (!userKey) {
945
962
  return;
946
963
  }
947
- queryString = (0, types_1.hashKey)(queryString);
948
- if (timeout > 0) {
964
+ if (timeout > 0 && timeout < Infinity) {
949
965
  const userCache = CACHE_USER[source]?.[userKey];
950
- let stored;
951
- if (!(userCache && (stored = userCache[queryString]))) {
966
+ if (!userCache) {
967
+ return;
968
+ }
969
+ const stored = userCache[queryString = (0, types_1.hashKey)(queryString)];
970
+ if (!stored) {
952
971
  return;
953
972
  }
954
973
  const [expires, result] = stored;
@@ -980,38 +999,27 @@ class ClientDb extends Client {
980
999
  delete userCache[queryString];
981
1000
  }
982
1001
  else if (sessionKey) {
983
- return CACHE_SESSION[source]?.[userKey + sessionKey]?.[queryString];
1002
+ return CACHE_SESSION[source]?.[userKey + sessionKey]?.[(0, types_1.hashKey)(queryString)];
984
1003
  }
985
1004
  }
986
- static storeResult(source, credential, queryString, result, options, sessionKey, sessionExpires) {
1005
+ static storeResult(source, credential, queryString, result, cache, sessionKey, sessionExpires) {
987
1006
  if (!credential || !Array.isArray(result)) {
988
1007
  return result;
989
1008
  }
990
- let cache, cacheDir;
1009
+ let cacheDir;
991
1010
  if ((0, types_1.isObject)(sessionKey)) {
992
1011
  ({ cacheDir, sessionKey, sessionExpires } = sessionKey);
993
1012
  }
994
- else if ((0, types_1.isObject)(options) && 'cache' in options) {
995
- ({ cache, cacheDir, sessionKey, sessionExpires } = options);
1013
+ else if ((0, types_1.isObject)(cache) && 'cache' in cache) {
1014
+ ({ cache, cacheDir, sessionKey, sessionExpires } = cache);
996
1015
  }
997
1016
  let timeout = 0, userKey, whenEmpty, partition = false;
998
- if (cache) {
999
- switch (typeof cache) {
1000
- case 'number':
1001
- timeout = cache;
1002
- break;
1003
- case 'string':
1004
- if (typeof sessionKey === 'number') {
1005
- sessionExpires = sessionKey;
1006
- sessionKey = cache;
1007
- break;
1008
- }
1009
- timeout = convertSeconds(cache);
1010
- break;
1011
- case 'object': {
1017
+ switch (typeof cache) {
1018
+ case 'object':
1019
+ if (cache) {
1012
1020
  let seconds, dir;
1013
1021
  ({ timeout: seconds, when_empty: whenEmpty, dir } = cache);
1014
- if ((0, types_1.isString)(dir) && (!cacheDir || module_1.isDir(dir))) {
1022
+ if (dir && (!cacheDir || module_1.isDir(dir))) {
1015
1023
  cacheDir = dir;
1016
1024
  partition = true;
1017
1025
  }
@@ -1019,15 +1027,25 @@ class ClientDb extends Client {
1019
1027
  timeout = seconds;
1020
1028
  }
1021
1029
  else {
1022
- cache.timeout = seconds ? convertSeconds(seconds) : 0;
1030
+ cache.timeout = seconds ? timeout = convertSeconds(seconds) : 0;
1023
1031
  }
1032
+ }
1033
+ break;
1034
+ case 'number':
1035
+ timeout = cache;
1036
+ break;
1037
+ case 'string':
1038
+ if (typeof sessionKey === 'number') {
1039
+ sessionExpires = sessionKey;
1040
+ sessionKey = cache;
1024
1041
  break;
1025
1042
  }
1026
- }
1043
+ timeout = convertSeconds(cache);
1044
+ break;
1027
1045
  }
1028
1046
  if ((result.length > 0 || whenEmpty) && (userKey = this.extractUUID(credential) || (0, types_1.hashKey)(this.asString(credential)))) {
1029
- queryString = (0, types_1.hashKey)(queryString);
1030
- if (timeout > 0) {
1047
+ if (timeout > 0 && timeout < Infinity) {
1048
+ queryString = (0, types_1.hashKey)(queryString);
1031
1049
  const item = [expireTime(timeout), result, Date.now(), 0];
1032
1050
  ((CACHE_USER[source] ||= {})[userKey] ||= {})[queryString] = item;
1033
1051
  addSourceResult(source, item);
@@ -1058,7 +1076,7 @@ class ClientDb extends Client {
1058
1076
  sourceData[dbKey] = data;
1059
1077
  setTimeout(() => delete sourceData[dbKey], sessionExpires * 1000);
1060
1078
  }
1061
- data[queryString] = result;
1079
+ data[(0, types_1.hashKey)(queryString)] = result;
1062
1080
  }
1063
1081
  }
1064
1082
  return result;
@@ -1186,7 +1204,7 @@ class ClientDb extends Client {
1186
1204
  sessionKey = options;
1187
1205
  break;
1188
1206
  case 'object':
1189
- if (options !== null) {
1207
+ if (options) {
1190
1208
  ({ value, sessionKey, exclusiveOf, renewCache } = options);
1191
1209
  if (Array.isArray(exclusiveOf)) {
1192
1210
  const ignoreCache = exclusiveOf[2];
@@ -1220,30 +1238,37 @@ class ClientDb extends Client {
1220
1238
  return result;
1221
1239
  }
1222
1240
  const uuidKey = ClientDb.extractUUID(credential);
1223
- let options;
1224
- if (ClientDb.enabled("memory.settings.users", this.host?.username)) {
1225
- let value, exclusiveOf;
1226
- if ((0, types_1.isObject)(sessionKey)) {
1227
- ({ value, sessionKey, exclusiveOf } = sessionKey);
1241
+ let value, exclusiveOf;
1242
+ if ((0, types_1.isObject)(sessionKey)) {
1243
+ ({ value, sessionKey, exclusiveOf } = sessionKey);
1244
+ }
1245
+ if (Array.isArray(exclusiveOf)) {
1246
+ if (isInvalidRange(result, exclusiveOf)) {
1247
+ return result;
1228
1248
  }
1229
- if (Array.isArray(exclusiveOf)) {
1230
- if (isInvalidRange(result, exclusiveOf)) {
1231
- return result;
1232
- }
1233
- queryString += '_' + exclusiveOf.slice(0, 2).toString();
1249
+ queryString += '_' + exclusiveOf.slice(0, 2).toString();
1250
+ }
1251
+ if (uuidKey) {
1252
+ const cache = this.settingsKey(uuidKey, 'cache');
1253
+ if (cache !== undefined) {
1254
+ value = cache;
1234
1255
  }
1235
- if (uuidKey) {
1236
- const cache = this.settingsKey(uuidKey, 'cache');
1237
- if (cache !== undefined) {
1238
- value = cache;
1239
- }
1256
+ }
1257
+ const cacheDir = this.cacheDir;
1258
+ value ??= this.settingsOf(source, 'cache');
1259
+ let options;
1260
+ if (ClientDb.enabled("memory.settings.users", this.host?.username)) {
1261
+ if (cacheDir || sessionKey) {
1262
+ options = { cacheDir, sessionKey, sessionExpires: this.cacheExpires / 1000 };
1240
1263
  }
1241
- options = { cache: value === 0 ? 0 : value || this.settingsOf(source, 'cache'), cacheDir: this.cacheDir, sessionKey, sessionExpires: this.cacheExpires / 1000 };
1242
1264
  }
1243
- else {
1244
- options = { cacheDir: this.cacheDir };
1265
+ else if (cacheDir) {
1266
+ options = { cacheDir };
1267
+ }
1268
+ else if (!(0, types_1.isObject)(value) || !(0, types_1.isString)(value.dir)) {
1269
+ return result;
1245
1270
  }
1246
- return ClientDb.storeResult(this.moduleName + '_' + source, uuidKey || credential, queryString, result, options);
1271
+ return value || options ? ClientDb.storeResult(this.moduleName + '_' + source, uuidKey || credential, queryString, result, options) : result;
1247
1272
  }
1248
1273
  getCacheResult(source, credential, queryString, cacheValue, ignoreCache) {
1249
1274
  if (ignoreCache !== 1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/core",
3
- "version": "0.11.14",
3
+ "version": "0.11.15",
4
4
  "description": "Core modules for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,11 +17,11 @@
17
17
  "squared-functions"
18
18
  ],
19
19
  "author": "An Pham <anpham6@gmail.com>",
20
- "license": "BSD-3-Clause",
20
+ "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/e-mc#readme",
22
22
  "dependencies": {
23
- "@e-mc/module": "0.11.14",
24
- "@e-mc/types": "0.11.14",
23
+ "@e-mc/module": "0.11.15",
24
+ "@e-mc/types": "0.11.15",
25
25
  "ipaddr.js": "^2.2.0",
26
26
  "picomatch": "^4.0.3"
27
27
  }