jsir 2.6.12 → 2.6.14

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/cmd/oaa.js CHANGED
@@ -4,7 +4,7 @@ const {
4
4
  getLibDataDir, trim, regEach, getConfig, mkdir, reget,
5
5
  getCbText, e, sleep, objDataFile, vl, md5, BigNumber,
6
6
  arrayDataFile, infoStr, warnStr,
7
- getInfo, pad, msgStr, getType,
7
+ getInfo, msgStr, getType,
8
8
  isMatch, draftQuery, setConfig,
9
9
  getTextComments, importG, requireG,
10
10
  clearConsole, trimText, getFnArgsStr,
@@ -13,7 +13,7 @@ const {
13
13
  getFullPath, parseUniqueName, toUniqueName, isJsirFileName, toJsirFileName,
14
14
  getAlias, wrapperJsirText, eia, getKeyTips, getValTips, getJsirTypeKey,
15
15
  createDetachedProcess, interceptStdStreams,
16
- draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key
16
+ draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key, terminalTitle
17
17
  } = $lib;
18
18
  const _args = process.argv.slice(2).map(trim);
19
19
  const evalCode = require('../deps/evalCode')
@@ -131,10 +131,24 @@ const $data = {
131
131
  `
132
132
  get or set by async function
133
133
  `
134
- if (!vl(_data[key])) {
135
- return _dataSet(key, await fn(), onLazyTempCode)
134
+ if (vl(_data[key])) {
135
+ return _dealOnLazyGet(key, onLazyTempCode);
136
136
  }
137
- return _dealOnLazyGet(key, onLazyTempCode)
137
+ let result = null;
138
+ await processLock('gafs:' + key, async () => {
139
+ if (!vl(_data[key])) {
140
+ result = _dataSet(key, await fn(), onLazyTempCode)
141
+ } else {
142
+ result = _dealOnLazyGet(key, onLazyTempCode)
143
+ }
144
+ }, async () => {
145
+ if (!vl(_data[key])) {
146
+ return true;
147
+ } else {
148
+ result = _dealOnLazyGet(key, onLazyTempCode)
149
+ }
150
+ })
151
+ return result;
138
152
  },
139
153
  set: _dataSet,
140
154
  del: (key) => {
@@ -184,6 +198,7 @@ function checkWorkspaces() {
184
198
  }
185
199
 
186
200
  async function start() {
201
+ terminalTitle()
187
202
  cleanFileLocks();
188
203
 
189
204
  setting.wrapperInput = wrapperInput;
@@ -337,8 +352,8 @@ function initRl(callback, promptStr, hidden) {
337
352
  })
338
353
  _rl.on("SIGINT", async () => {
339
354
  if (_noAppendNextLine) {
340
- delTips();
341
- process.exit(0);
355
+ setting.promptId = Date.now();
356
+ await delTips();
342
357
  } else {
343
358
  _rl._writeToOutput = origin_writeToOutput;
344
359
  _haveWrapperInput = true;
@@ -350,12 +365,12 @@ function initRl(callback, promptStr, hidden) {
350
365
  }
351
366
  origin_writeToOutput = _rl._writeToOutput
352
367
  if (promptStr !== '') {
353
- promptStr = promptStr || ((callback && callback !== wrapperInput) ? "-> ":"")
368
+ promptStr = promptStr || (callback !== wrapperInput ? "-> ":"")
354
369
  if (promptStr) {
355
370
  promptStr = infoStr(promptStr);
356
371
  } else {
357
- if (global.$newError) {
358
- global.$newError = false;
372
+ if (setting.newError) {
373
+ setting.newError = false;
359
374
  promptStr = errorStr(defaultPromptStr())
360
375
  } else {
361
376
  promptStr = infoStr(defaultPromptStr())
@@ -394,6 +409,7 @@ function closeRl() {
394
409
  }
395
410
 
396
411
  function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
412
+ callback = callback || wrapperInput;
397
413
  if (!setting.enableNextLine) {
398
414
  console.$log(warnStr("[warn]"), "NextLine Disabled");
399
415
  resolve(null);
@@ -405,15 +421,11 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
405
421
  return;
406
422
  }
407
423
  initRl(callback, promptStr, hidden);
408
- let isJsirNext = !callback || callback === wrapperInput
409
- if (!isJsirNext) {
424
+ if (callback !== wrapperInput) {
410
425
  _haveWrapperInput = false
411
426
  }
412
- if (isJsirNext) {
413
- global.$newInput = true;
414
- }
415
427
  end = trim(end)
416
- let inputStr = ''
428
+ let inputs = []
417
429
  let lineHandler = async line => {
418
430
  let textLine = line
419
431
  line = trim(line)
@@ -422,33 +434,32 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
422
434
  end = line
423
435
  line = ''
424
436
  } else if (line !== end) {
425
- inputStr += textLine + '\n'
437
+ inputs.push(textLine)
426
438
  }
427
439
  } else {
428
- inputStr = line
440
+ inputs.push(line)
429
441
  }
430
- if (trim(textLine) && (hidden || (callback && callback !== wrapperInput))) {
442
+ if (trim(textLine) && (hidden || callback !== wrapperInput)) {
431
443
  _rl.history = _rl.history.slice(1)
432
444
  }
433
445
  if (!isText || line === end) {
446
+ let promptId = setting.promptId;
434
447
  _haveWrapperInput = true;
435
448
  closeRl()
436
- inputStr = inputStr.replace(/\s+$/, '');
437
- if (!isText && /^\d+$/.test(inputStr) && /^\s+/.test(textLine) && (!callback || callback === wrapperInput)) {
449
+ let inputStr = inputs.join("\n");
450
+ if (callback === wrapperInput && !isText && /^\d+$/.test(inputStr) && /^\s+/.test(textLine)) {
438
451
  inputStr = '.e ' + inputStr;
439
452
  }
440
- let pro = (callback || wrapperInput)(inputStr);
441
- resolve(inputStr);
442
453
  try {
443
- await pro;
454
+ resolve(await callback(inputStr));
444
455
  } finally {
445
- if ((callback || wrapperInput) === wrapperInput) {
456
+ if (callback === wrapperInput) {
446
457
  if (!_noAppendNextLine) {
447
458
  if (/^\s+$/.test(textLine)) {
448
459
  clearConsole(textLine.length - 1)
449
460
  filterCmdAndList();
450
461
  nextLine(null, defaultPromptStr(true))
451
- } else {
462
+ } else if (promptId === setting.promptId) {
452
463
  nextLine()
453
464
  }
454
465
  }
@@ -460,6 +471,9 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
460
471
  _rl.removeAllListeners('line')
461
472
  _rl.on('line', lineHandler)
462
473
  _rl.prompt()
474
+ if (callback === wrapperInput) {
475
+ setting.promptId = Date.now();
476
+ }
463
477
  setting.lastOutput = null;
464
478
  }
465
479
 
@@ -470,7 +484,11 @@ async function nextText(callback, end, hidden) {
470
484
  }
471
485
 
472
486
  async function save(args) {
473
- let uniqueName = toUniqueName(toJsirFileName(args.join(' ')))
487
+ let pair = parseUniqueName(args.join(' '));
488
+ if (pair[0] && !setting.workspaceMap[pair[0]]) {
489
+ throw 'invalid name'
490
+ }
491
+ let uniqueName = toUniqueName(toJsirFileName(pair[1]), pair[0])
474
492
  let path = getFullPath(uniqueName)
475
493
  if (fs.existsSync(path)) {
476
494
  console.warn(`${path} already exist`)
@@ -612,10 +630,15 @@ async function wrapperInput(str, packOutput = false) {
612
630
  if (packOutput) {
613
631
  setting.enterOutputs = []
614
632
  }
633
+ const promptId = setting.promptId;
615
634
  try {
616
635
  await _wrapperInput(str);
617
636
  } catch (e) {
618
- console.error(e)
637
+ if (promptId === setting.promptId) {
638
+ console.error(e)
639
+ } else {
640
+ console.$error(e)
641
+ }
619
642
  }
620
643
  if (packOutput) {
621
644
  let outputs = setting.enterOutputs || [];
@@ -639,16 +662,16 @@ async function _wrapperInput(str) {
639
662
  if (!str) {
640
663
  return;
641
664
  }
642
- global.$newError = false;
665
+ setting.newError = false;
643
666
  str = wrapperAlias(str);
644
667
 
645
668
  if (/^[`'"]/.test(str)) {
646
- let fstr = str.substr(0, 1);
669
+ let fstr = str.substring(0, 1);
647
670
  if (fstr === '`') {
648
- let text = str.substr(1) + "\n" + await nextText(line => line, fstr)
671
+ let text = str.substring(1) + "\n" + await nextText(line => line, fstr)
649
672
  await wrapperInput(text)
650
673
  } else {
651
- let fLine = trim(str.substr(1))
674
+ let fLine = trim(str.substring(1))
652
675
  if (fLine) {
653
676
  if (/\s+[+-]$/.test(fLine)) {
654
677
  console.log((await draftModify(fLine)).join("\n"))
@@ -701,6 +724,7 @@ async function runInit(uniqueName, args) {
701
724
  if (arg === '-') {
702
725
  await offServer(uniqueName)
703
726
  } else {
727
+ console.$log(`Execute ${uniqueName}`);
704
728
  let exportLib = await _requireSource(setting.defaultSpace, uniqueName, true);
705
729
  if (typeof exportLib === "function") {
706
730
  await execLibFn(exportLib, args)
@@ -930,7 +954,7 @@ function dealStarCmd(rows, cmd, filterStr) {
930
954
  }
931
955
 
932
956
  // Capture single-line comments
933
- if (line.trim().startsWith('//')) {
957
+ if (line.trim().startsWith('//') || line.trim().startsWith("@")) {
934
958
  potentialComments.push(line);
935
959
  }
936
960
 
@@ -968,7 +992,8 @@ function dealStarCmd(rows, cmd, filterStr) {
968
992
  }
969
993
 
970
994
  // If not capturing function, reset potential comments
971
- if (!capturingFunction && !inMultiLineComment && line.trim() !== '' && !line.trim().startsWith('//')) {
995
+ if (!capturingFunction && !inMultiLineComment && line.trim() !== ''
996
+ && !line.trim().startsWith('//') && !line.trim().startsWith('@')) {
972
997
  potentialComments = [];
973
998
  }
974
999
  }
@@ -1039,7 +1064,7 @@ function delTipsByIndex(idxs) {
1039
1064
  console.warn("no items")
1040
1065
  return;
1041
1066
  }
1042
- delTips(...params)
1067
+ return delTips(...params)
1043
1068
  }
1044
1069
 
1045
1070
  function getPackageVersion(space, name) {
@@ -1185,8 +1210,8 @@ const keywordDef = {
1185
1210
  },
1186
1211
  clear: {
1187
1212
  comment: 'Clear task',
1188
- exeFn: (args) => {
1189
- delTipsByIndex(args.filter(i => i))
1213
+ exeFn: async (args) => {
1214
+ await delTipsByIndex(args.filter(i => i))
1190
1215
  },
1191
1216
  args: {
1192
1217
  tipIndex: 'left prompt index, can be separated by spaces for multiple'
@@ -1550,11 +1575,11 @@ const keywordDef = {
1550
1575
  },
1551
1576
  quit: {
1552
1577
  comment: 'Exit',
1553
- exeFn: (args) => {
1578
+ exeFn: async (args) => {
1554
1579
  Room.offRoom();
1555
- delTips();
1556
- console.log(infoStr("Bye!"));
1580
+ await delTips();
1557
1581
  _noAppendNextLine = true;
1582
+ console.log(infoStr("Bye!"));
1558
1583
  },
1559
1584
  short: 'q'
1560
1585
  },
@@ -1625,7 +1650,7 @@ const keywordDef = {
1625
1650
  },
1626
1651
  debug: {
1627
1652
  comment: 'debug mode',
1628
- exeFn: (args) => {
1653
+ exeFn: async (args) => {
1629
1654
  if ('+' === args[0]) {
1630
1655
  if (!global.$DEBUG) {
1631
1656
  global.$DEBUG = true;
@@ -1633,11 +1658,11 @@ const keywordDef = {
1633
1658
  }
1634
1659
  } else if ('-' === args[0]) {
1635
1660
  if (global.$DEBUG) {
1636
- delTips("DEBUG")
1661
+ await delTips("DEBUG")
1637
1662
  }
1638
1663
  } else {
1639
1664
  if (global.$DEBUG) {
1640
- delTips("DEBUG")
1665
+ await delTips("DEBUG")
1641
1666
  } else {
1642
1667
  global.$DEBUG = true;
1643
1668
  setTips("DEBUG", "DEBUG", () => delete global.$DEBUG);
@@ -1648,7 +1673,7 @@ const keywordDef = {
1648
1673
  },
1649
1674
  test: {
1650
1675
  comment: 'test mode',
1651
- exeFn: (args) => {
1676
+ exeFn: async (args) => {
1652
1677
  if ('+' === args[0]) {
1653
1678
  if (!global.$TEST) {
1654
1679
  global.$TEST = true;
@@ -1656,11 +1681,11 @@ const keywordDef = {
1656
1681
  }
1657
1682
  } else if ('-' === args[0]) {
1658
1683
  if (global.$TEST) {
1659
- delTips("TEST")
1684
+ await delTips("TEST")
1660
1685
  }
1661
1686
  } else {
1662
1687
  if (global.$TEST) {
1663
- delTips("TEST")
1688
+ await delTips("TEST")
1664
1689
  } else {
1665
1690
  global.$TEST = true;
1666
1691
  setTips("TEST", "TEST", () => delete global.$TEST);
@@ -1999,12 +2024,6 @@ function getArgComments(argDef, showShort = false) {
1999
2024
  let item = warnStr(k) + (shortMap[k] ? ` ${warnStr(shortMap[k])}`:'') + (argDef[k] ? ` ${argDef[k]}`:'')
2000
2025
  comments.push(item)
2001
2026
  }
2002
- comments[0] = comments[0]
2003
- if (comments.length > 1) {
2004
- for(let i = 1; i< comments.length; i++) {
2005
- comments[i] = comments[i]
2006
- }
2007
- }
2008
2027
  }
2009
2028
  return comments
2010
2029
  }
@@ -2079,6 +2098,9 @@ async function runCmd(str = '', uniqueName = '', text = '') {
2079
2098
  }
2080
2099
 
2081
2100
  let scriptArgs = await getScriptArgs(argDef, enrichArgs(str.replace(/^\d+\s*/, '')));
2101
+ if (uniqueName) {
2102
+ console.$log(`Execute ${uniqueName}`);
2103
+ }
2082
2104
  return await evalText(text, uniqueName, scriptArgs)
2083
2105
  }
2084
2106
 
@@ -2224,20 +2246,22 @@ function parseArgDef(inputString) {
2224
2246
  result[s1] = '';
2225
2247
  }
2226
2248
  }
2249
+ let tempResult = {}
2227
2250
  for (let key of Object.keys(result)) {
2228
2251
  let comment = result[key];
2229
2252
  let defaultValStr = ''
2230
2253
  if (key.indexOf("=") !== -1) {
2231
- delete result[key];
2232
2254
  let ss = key.split('=').map(trim);
2233
2255
  key = ss[0]
2234
2256
  defaultValStr = ss[1]
2235
2257
  }
2236
2258
  if (defaultValStr) {
2237
- result[key] = ['<' + warnStr(defaultValStr) + '>', comment].join(' ')
2259
+ tempResult[key] = ['<' + warnStr(defaultValStr) + '>', comment].join(' ')
2260
+ } else {
2261
+ tempResult[key] = comment
2238
2262
  }
2239
2263
  }
2240
- return result;
2264
+ return tempResult;
2241
2265
  }
2242
2266
 
2243
2267
  function getArgDef(text, uniqueName) {
@@ -2279,7 +2303,7 @@ function getArgDef(text, uniqueName) {
2279
2303
 
2280
2304
  function filterRequire(currSpace, cmdMatchStr) {
2281
2305
  if (typeof cmdMatchStr === 'number') {
2282
- cmdMatchStr = '0x' + pad(8, BigNumber(cmdMatchStr).toString(16), '0');
2306
+ cmdMatchStr = '0x' + BigNumber(cmdMatchStr).toString(16).padStart(8, '0');
2283
2307
  }
2284
2308
  cmdMatchStr = trim(cmdMatchStr);
2285
2309
 
@@ -2435,9 +2459,6 @@ function _addErrorTag(lines) {
2435
2459
  }
2436
2460
 
2437
2461
  async function evalText($text = '', $cmdName = '', $args = {}) {
2438
- if ($cmdName) {
2439
- console.$log(`Execute ${$cmdName}`);
2440
- }
2441
2462
  let currSpace;
2442
2463
  if ($cmdName) {
2443
2464
  let pair = parseUniqueName($cmdName)
@@ -2464,10 +2485,15 @@ async function evalText($text = '', $cmdName = '', $args = {}) {
2464
2485
  $homeDir, $lib, _cmdMap);
2465
2486
  }
2466
2487
 
2467
- function sigExit() {
2488
+ let sigExitCount = 0
2489
+ async function sigExit() {
2468
2490
  if (_noAppendNextLine) {
2469
- delTips();
2470
- process.exit(0);
2491
+ setting.promptId = Date.now();
2492
+ sigExitCount ++;
2493
+ if (sigExitCount > 1) {
2494
+ process.exit(0);
2495
+ }
2496
+ await delTips();
2471
2497
  } else {
2472
2498
  nextLine();
2473
2499
  }
@@ -2484,9 +2510,9 @@ process.on('rejectionHandled',function(err){
2484
2510
  })
2485
2511
  process.on('SIGINT', sigExit);
2486
2512
  process.on('SIGTERM', sigExit);
2487
- process.on('beforeExit', function () {
2513
+ process.on('beforeExit', async function () {
2488
2514
  if (_noAppendNextLine) {
2489
- delTips();
2515
+ terminalTitle(null)
2490
2516
  } else {
2491
2517
  nextLine();
2492
2518
  Room.onRoom()
package/deps/evalCode.js CHANGED
@@ -19,23 +19,17 @@ module.exports = async ($text = '', $cmdName = '', $args = [],
19
19
 
20
20
  const $setTips = $lib.setTips;
21
21
  const $delTips = $lib.delTips;
22
- const $tips = {
23
- set: $lib.setTips,
24
- del: $lib.delTips,
25
- has: $lib.hasTips,
26
- key: $lib.tipKeys
27
- }
22
+ const $tips = $lib.tipFns;
28
23
  const $errorTag = $lib.errorTag;
29
24
  const $aop = $lib.aop;
30
25
  const $aopAsync = $lib.aopAsync;
31
26
 
32
27
  const $context = {
33
28
  $defArgs,
34
- $data, $config,
29
+ $data, $config, $tips,
35
30
  $require, $requires, $import,
36
31
  $text, $cmdName, $args,
37
32
  $nextLine, $nextText,
38
- $setTips, $delTips, $tips,
39
33
  $enter, $filterCmd,
40
34
  $currentSpace, $defaultSpace, $workspaceMap,
41
35
  $homeDir, $lib, $cmdMap
package/deps/room.js CHANGED
@@ -57,7 +57,7 @@ function onRoom() {
57
57
  return;
58
58
  }
59
59
  res.output = await setting.wrapperInput(req.input, true)
60
- global.$newInput = true;
60
+ setting.promptId = Date.now()
61
61
  }
62
62
  })
63
63
  } catch (e) {
@@ -113,7 +113,12 @@ async function initNodes() {
113
113
  }
114
114
  }
115
115
  } else {
116
- let resp = await e(`${tailscalePath} status`);
116
+ let resp = '';
117
+ try {
118
+ resp = await e(`${tailscalePath} status`);
119
+ } catch (e) {
120
+ debug("initNodes", e)
121
+ }
117
122
  for (let line of resp.split("\n").map(trim)) {
118
123
  let offline = line.indexOf('offline') !== -1
119
124
  let ss = line.split(/\s+/);
@@ -248,8 +253,8 @@ async function _syncSetting(room) {
248
253
  setting.services = {}
249
254
  setting.serviceFns = {}
250
255
  for (const room of setting.rooms) {
251
- if (setting.nodeMap[room.selfNode]?.offline) {
252
- continue
256
+ if (!room.active) {
257
+ continue;
253
258
  }
254
259
  for (const pid of Object.keys(room.jsirs || {})) {
255
260
  let jsir = room.jsirs[pid];
@@ -297,7 +302,7 @@ async function processTasks() {
297
302
  if (unHandleKey) {
298
303
  console.$log(process.pid, `run task ${unHandleKey}[${defTasks[unHandleKey]}]`)
299
304
  await setting.wrapperInput(defTasks[unHandleKey]);
300
- if (!global.$newError) {
305
+ if (!setting.newError) {
301
306
  tasks[unHandleKey] = process.pid;
302
307
  console.$log(process.pid, `handle task ${unHandleKey}[${defTasks[unHandleKey]}]`)
303
308
  }
@@ -431,7 +436,7 @@ async function initRoomJsir(room) {
431
436
  lastUpdateTime: setting.roomTime,
432
437
  port: setting.server ? setting.server.address()?.port:null,
433
438
  services: services,
434
- newError: global.$newError,
439
+ newError: setting.newError,
435
440
  version: packageJson.version,
436
441
  upTime: formatUptime()
437
442
  }
package/deps/setting.js CHANGED
@@ -46,6 +46,8 @@ module.exports = {
46
46
  serviceReg: /[^a-zA-Z]service[^a-zA-Z]|[^a-zA-Z]service$/i,
47
47
  wrapperInput: null,
48
48
  lastOutput: null,
49
- locks: {},
50
- lastChangeFlag: null
49
+ lastChangeFlag: null,
50
+ terminalTitle: null,
51
+ promptId: Date.now(),
52
+ newError: false
51
53
  }
package/deps/util.js CHANGED
@@ -6,7 +6,6 @@ const readline = require('readline')
6
6
  const fs = require('fs')
7
7
  const fp = require('fs').promises
8
8
  const BigNumber = require('bignumber.js');
9
- const pad = require('pad');
10
9
  const crypto = require('crypto');
11
10
  const dayJs = require('dayjs')
12
11
  const table = require('console.table')
@@ -16,9 +15,6 @@ const _types = setting.fileType
16
15
  const _typeKeys = Object.keys(_types)
17
16
  const util = require('util')
18
17
 
19
- global.$newInput = false
20
- global.$newError = false
21
-
22
18
  let libDataDir;
23
19
  let lockDir;
24
20
  let logDir;
@@ -255,6 +251,7 @@ function createConsole(uniqueName) {
255
251
  result.$log = $log;
256
252
  result.$error = $error;
257
253
  result.$draft = draftLog;
254
+ result.$abort = () => false;
258
255
  if (uniqueName) {
259
256
  let pair = parseUniqueName(uniqueName)
260
257
  let fileName = pair[0] + '/' + pair[1].split(".")[0]
@@ -267,21 +264,24 @@ function createConsole(uniqueName) {
267
264
  error: true,
268
265
  syncLogs: [result.$log, roomError]
269
266
  });
267
+ const promptId = setting.promptId;
268
+ result.$abort = () => promptId !== setting.promptId;
270
269
  }
271
270
  let quite = false
271
+ let promptId = 0
272
272
  if (uniqueName) {
273
- global.$newInput = false;
273
+ promptId = setting.promptId;
274
274
  }
275
275
  for (let key of Object.keys(_consoleFns)) {
276
276
  result[key] = (...args) => {
277
- if (global.$newInput) {
277
+ if (promptId !== setting.promptId) {
278
278
  quite = true;
279
279
  }
280
280
  if ('debug' === key && !global.$DEBUG) {
281
281
  return;
282
282
  }
283
283
  if ('error' === key) {
284
- global.$newError = true;
284
+ setting.newError = true;
285
285
  }
286
286
  let hasFlag = false;
287
287
  let sameFlag = false;
@@ -309,6 +309,7 @@ function createConsole(uniqueName) {
309
309
  let _args = _consoleFns[key].args(args);
310
310
  let lastOutput = null;
311
311
  if (hasFlag) {
312
+ terminalTitle(setting.lastChangeFlag.replace(/^\*/, '').replace(/\*$/, '').trim())
312
313
  lastOutput = _args.join(" ")
313
314
  if (!isRunningInBackground() && setting.lastOutput && sameFlag) {
314
315
  let lines = setting.lastOutput.split('\n').length;
@@ -336,6 +337,20 @@ console = createConsole();
336
337
  // fix console done
337
338
 
338
339
 
340
+ function terminalTitle(title = 'jsir') {
341
+ if (isRunningInBackground()) {
342
+ return;
343
+ }
344
+ if (setting.terminalTitle !== title) {
345
+ setting.terminalTitle = title;
346
+ if (title) {
347
+ process.stdout.write(`\x1b]0;${setting.terminalTitle}\x07`);
348
+ } else {
349
+ process.stdout.write('\x1b]0;\x07');
350
+ }
351
+ }
352
+ }
353
+
339
354
  function getFullPath(name) {
340
355
  name = trim(name)
341
356
  if (!name) {
@@ -787,10 +802,10 @@ function createLimitLogger(fileName, {
787
802
 
788
803
  let text = consoleStrs(...args)
789
804
  if (error) {
790
- global.$newError = true;
805
+ setting.newError = true;
791
806
  }
792
807
  if (time) {
793
- text = `${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${pad(3, String(process.pid%1000), process.pid >= 1000 ? '0':' ')}> ${text}`
808
+ text = `${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${String(process.pid%1000).padStart(3, '0')}> ${text}`
794
809
  }
795
810
  syncQueue(() => fp.appendFile(logPath, text + '\n'), logPath)
796
811
  let _minNum = (Date.now()/(1000 * 60 * 10)).toFixed(0)
@@ -983,16 +998,17 @@ function aesCipher(str, key, useIv = false){
983
998
  if (!key || key.length > 16) {
984
999
  throw "aesCipher key length should be between 1 and 16"
985
1000
  }
1001
+ key = key.padEnd(16, '0');
986
1002
  if (useIv) {
987
1003
  // Generate random IV
988
1004
  const iv = crypto.randomBytes(16);
989
- const cipher = crypto.createCipheriv('aes-128-cbc', pad(key, 16, '0'), iv);
1005
+ const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
990
1006
 
991
1007
  // Return IV and ciphertext, as IV is needed for decryption
992
1008
  const ciphertext = cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
993
1009
  return iv.toString('hex') + ':' + ciphertext; // Combine IV and ciphertext
994
1010
  }
995
- const cipher = crypto.createCipheriv('aes-128-ecb', pad(key, 16, '0'), null);
1011
+ const cipher = crypto.createCipheriv('aes-128-ecb', key, null);
996
1012
  return cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
997
1013
  }
998
1014
 
@@ -1004,7 +1020,7 @@ function aesDecipher(str, key){
1004
1020
  if (!key || key.length > 16) {
1005
1021
  throw "aesCipher key length should be between 1 and 16";
1006
1022
  }
1007
-
1023
+ key = key.padEnd(16, '0');
1008
1024
  // Extract IV and ciphertext
1009
1025
  if(str.indexOf(":") !== -1) {
1010
1026
  const [ivHex, ciphertext] = str.split(':');
@@ -1012,10 +1028,10 @@ function aesDecipher(str, key){
1012
1028
  throw "Invalid encrypted string format";
1013
1029
  }
1014
1030
  const iv = Buffer.from(ivHex, 'hex');
1015
- const decipher = crypto.createDecipheriv('aes-128-cbc', pad(key, 16, '0'), iv);
1031
+ const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
1016
1032
  return decipher.update(ciphertext, 'hex', 'utf8') + decipher.final('utf8');
1017
1033
  }
1018
- const decipher = crypto.createDecipheriv('aes-128-ecb', pad(key, 16, '0'), null);
1034
+ const decipher = crypto.createDecipheriv('aes-128-ecb', key, null);
1019
1035
  return decipher.update(str, 'hex', 'utf8') + decipher.final('utf8');
1020
1036
  }
1021
1037
 
@@ -1286,19 +1302,21 @@ async function _fileLock(key, fn) {
1286
1302
 
1287
1303
  async function fileLock(key, fn, wait = true) {
1288
1304
  `
1289
- 文件锁, 默认一直等待expireMs,直到加锁成功执行fn
1305
+ 文件锁, 默认一直等待直到加锁成功执行fn
1290
1306
  wait = false, 加锁失败则不执行fn
1291
1307
  return void
1292
1308
  `
1293
- if (wait) {
1294
- while (true) {
1295
- if (await _fileLock(key, fn)) {
1296
- break;
1297
- }
1298
- await sleep(9);
1309
+ while (true) {
1310
+ if (await _fileLock(key, fn)) {
1311
+ break;
1299
1312
  }
1300
- } else {
1301
- await _fileLock(key, fn);
1313
+ if (typeof wait === 'function') {
1314
+ wait = await wait();
1315
+ }
1316
+ if (!wait) {
1317
+ break;
1318
+ }
1319
+ await sleep(9);
1302
1320
  }
1303
1321
  }
1304
1322
 
@@ -1308,32 +1326,35 @@ async function processLock(key, fn, wait = true) {
1308
1326
  wait = false, 加锁失败则不执行fn
1309
1327
  return void
1310
1328
  `
1311
- if (wait) {
1312
- while (true) {
1313
- if (await _processLock(key, fn)) {
1314
- break;
1315
- }
1316
- await sleep(9);
1329
+ while (true) {
1330
+ if (await _processLock(key, fn)) {
1331
+ break;
1317
1332
  }
1318
- } else {
1319
- await _processLock(key, fn);
1333
+ if (typeof wait === 'function') {
1334
+ wait = await wait();
1335
+ }
1336
+ if (!wait) {
1337
+ break;
1338
+ }
1339
+ await sleep(9);
1320
1340
  }
1321
1341
  }
1322
1342
 
1343
+ const $locks = {}
1323
1344
  async function _processLock(key, fn) {
1324
1345
  if (!key || typeof fn !== 'function') {
1325
1346
  throw new Error('invalid arguments');
1326
1347
  }
1327
1348
  key = key.trim();
1328
- if (setting.locks.hasOwnProperty(key)) {
1349
+ if ($locks.hasOwnProperty(key)) {
1329
1350
  return false;
1330
1351
  }
1331
- setting.locks[key] = true;
1352
+ $locks[key] = true;
1332
1353
  try {
1333
1354
  await fn();
1334
1355
  return true;
1335
1356
  } finally {
1336
- delete setting.locks[key];
1357
+ delete $locks[key];
1337
1358
  }
1338
1359
  }
1339
1360
 
@@ -1356,23 +1377,25 @@ function setTips(key, value, onRm) {
1356
1377
  if (!vl(key) || key.indexOf(",") !== -1) {
1357
1378
  throw "invalid tip key";
1358
1379
  }
1359
- getOr(setting.tips, key, []).push(value);
1380
+ key = trim(key)
1381
+ getOr(setting.tips, key, []).push(vl(value) ? value:'');
1360
1382
  if (onRm) {
1361
1383
  getOr(_tipsOnRm, key, []).push(onRm)
1362
1384
  }
1363
1385
  }
1364
1386
 
1365
1387
  function delTips(...keys) {
1388
+ let pros = []
1366
1389
  for (let key of Object.keys(setting.tips)) {
1367
1390
  if (keys.length === 0) {
1368
1391
  if (key === 'DEBUG') {
1369
1392
  continue
1370
1393
  }
1371
1394
  delete setting.tips[key]
1372
- tipsOnRmCallback(key)
1395
+ pros.push(tipsOnRmCallback(key))
1373
1396
  } else if (keys.indexOf(key) !== -1) {
1374
1397
  delete setting.tips[key]
1375
- tipsOnRmCallback(key)
1398
+ pros.push(tipsOnRmCallback(key))
1376
1399
  }
1377
1400
  }
1378
1401
  if (keys.length === 0) {
@@ -1380,13 +1403,22 @@ function delTips(...keys) {
1380
1403
  if (key === 'DEBUG') {
1381
1404
  continue
1382
1405
  }
1383
- tipsOnRmCallback(key)
1406
+ pros.push(tipsOnRmCallback(key))
1384
1407
  }
1385
1408
  }
1409
+ pros = pros.filter(i => i);
1410
+ if (pros.length > 0) {
1411
+ return Promise.all(pros)
1412
+ }
1386
1413
  }
1387
1414
 
1388
- function hasTips(key) {
1389
- return setting.tips.hasOwnProperty(key);
1415
+ function hasTips(key, value) {
1416
+ key = trim(key)
1417
+ if (vl(value)) {
1418
+ return setting.tips.hasOwnProperty(key) && setting.tips[key].includes(value);
1419
+ } else {
1420
+ return setting.tips.hasOwnProperty(key);
1421
+ }
1390
1422
  }
1391
1423
 
1392
1424
  function tipKeys() {
@@ -1396,15 +1428,22 @@ function tipKeys() {
1396
1428
  function tipsOnRmCallback(key) {
1397
1429
  let callbacks = _tipsOnRm[key]
1398
1430
  delete _tipsOnRm[key]
1431
+ const pros = [];
1399
1432
  if (callbacks && callbacks.length > 0) {
1400
1433
  for (let callback of callbacks) {
1401
1434
  try {
1402
- callback()
1435
+ let result = callback()
1436
+ if (getType(result) === 'Promise') {
1437
+ pros.push(result.catch(e => $error(`[${key}] OnRmCallback`, e)))
1438
+ }
1403
1439
  } catch (e) {
1404
1440
  $error(`[${key}] OnRmCallback`, e)
1405
1441
  }
1406
1442
  }
1407
1443
  }
1444
+ if (pros.length > 0) {
1445
+ return Promise.all(pros);
1446
+ }
1408
1447
  }
1409
1448
 
1410
1449
  async function timer(key, ms, fn, label, printInfo = true){
@@ -2147,6 +2186,9 @@ end tell
2147
2186
  function getKeyTips() {
2148
2187
  let items = [];
2149
2188
  for (let key of Object.keys(setting.tips)) {
2189
+ if (key.startsWith("_")) {
2190
+ continue;
2191
+ }
2150
2192
  items.push(trim(key))
2151
2193
  }
2152
2194
  return items
@@ -2155,6 +2197,9 @@ function getKeyTips() {
2155
2197
  function getValTips() {
2156
2198
  let items = [];
2157
2199
  for (let key of Object.keys(setting.tips)) {
2200
+ if (key.startsWith("_")) {
2201
+ continue;
2202
+ }
2158
2203
  let val = setting.tips[key].map(i => {
2159
2204
  if (typeof i === 'function') {
2160
2205
  try {
@@ -2260,13 +2305,20 @@ async function aopAsync(items, fn, args) {
2260
2305
  }
2261
2306
 
2262
2307
  function getMd5Key(str) {
2263
- return '0x' + md5(str).substr(0, 8);
2308
+ return '0x' + md5(str).substring(0, 8);
2264
2309
  }
2265
2310
 
2266
2311
  function isMd5Key(str) {
2267
2312
  return /^0x[a-z\d]{8}$/.test(str);
2268
2313
  }
2269
2314
 
2315
+ const tipFns = {
2316
+ set: setTips,
2317
+ del: delTips,
2318
+ has: hasTips,
2319
+ key: tipKeys
2320
+ }
2321
+
2270
2322
  module.exports = {
2271
2323
  formatUptime,
2272
2324
  wrapperJsirText,
@@ -2291,7 +2343,6 @@ module.exports = {
2291
2343
  bMul,
2292
2344
  getConfig,
2293
2345
  getCbText,
2294
- pad,
2295
2346
  aesCipher,
2296
2347
  aesDecipher,
2297
2348
  requireG,
@@ -2387,5 +2438,7 @@ module.exports = {
2387
2438
  isPidAlive,
2388
2439
  cleanFileLocks,
2389
2440
  getMd5Key,
2390
- isMd5Key
2441
+ isMd5Key,
2442
+ terminalTitle,
2443
+ tipFns
2391
2444
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsir",
3
- "version": "2.6.12",
3
+ "version": "2.6.14",
4
4
  "description": "JavaScript Script Management Tool",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,7 +21,6 @@
21
21
  "bignumber.js": "^9.0.0",
22
22
  "chokidar": "^3.5.2",
23
23
  "console.table": "^0.10.0",
24
- "dayjs": "^1.10.4",
25
- "pad": "^3.2.0"
24
+ "dayjs": "^1.10.4"
26
25
  }
27
26
  }