@shijiu/jsview 2.1.25 → 2.1.200-next-vue.0

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.
@@ -1,2 +1,2 @@
1
- /* eslint-disable */ void 0===window.Forge?(window.Forge={},console.log("Define forge browser")):console.log("Define using JsView forge engine-js");var e=window.Forge;class t{constructor(e,t){if(!e)return;if(!0===e.startsWith("url")){let t=e.indexOf("(")+1,i=e.lastIndexOf(")");if("undefined"===(e=e.substring(t,i).trim())||"null"===e||0===e.length)return}if(!0===e.startsWith("data:"))return void(this.href=e);let i=e.indexOf("://");if(!(i<0||i>10)||e.startsWith("./")||e.startsWith("/")||(e="./"+e),!0===e.startsWith("/"))e=document.location.origin+e;else if(!0===e.startsWith("./")&&void 0!==window.JsView&&void 0!==window.JsView.Dom.JsSubPath){if(void 0===window.JsView.Dom.MainPath||"undefined"===window.JsView.Dom.MainPathRef||window.JsView.Dom.MainPathRef!==document.location.href){window.JsView.Dom.JsSubPath.startsWith("/")||(window.JsView.Dom.JsSubPath="/"+window.JsView.Dom.JsSubPath),window.JsView.Dom.JsSubPath.endsWith("/")||(window.JsView.Dom.JsSubPath=window.JsView.Dom.JsSubPath+"/"),window.JsView.Dom.MainPathRef=document.location.href;let e=document.location.pathname.lastIndexOf(window.JsView.Dom.JsSubPath);window.JsView.Dom.MainPath=document.location.origin+document.location.pathname.substring(0,e)}e=window.JsView.Dom.MainPath+e.substring(1)}if(this.href=e,!t)return;let o=this.href,n=o.indexOf("#");n>0&&(this.hash=o.substring(n),o=o.substring(0,n));let s=o.indexOf("?");s>1&&(this.search=o.substring(s),o=o.substring(0,s));let r=o,a=r.indexOf("://");this.protocol=a>0?r.substring(0,a+1):"";let d=a>1?r.substring(a+3):"";a=d.indexOf("/"),this.host=a>0?d.substring(0,a):"",this.pathname=a>=1?d.substring(a):"","file:"==this.protocol&&(this.host="",this.pathname=d),this.origin=this.protocol+"//"+this.host,a=this.host.indexOf(":"),this.hostname=a>0?this.host.substring(0,a):this.host,this.port=a>1?this.host.substring(a+1):""}replace(e){this.href=e}href="";origin="";protocol="";host="";hostname="";port="";pathname="";search="";hash=""}class i{static SetBackgroundColor(t,i,o){const n=window.JsvCode.ForgeHandles.TextureManager.GetColorTextureCached(i);let s;o&&(s=new e.ViewRoundCornerMask(o.topLeft,o.topRight,o.bottomLeft,o.bottomRight));const r=new e.ExternalTextureSetting(n,s);t.ResetTexture(r)}static SetBackgroundImage(i,o,n,s,r,a,d){let h,l={};if("string"==typeof o){const e=new t(o);if(e instanceof t==!1)throw Error("Bad Argument.",e);l.url=e.href}else"linear-gradient"==o?.type&&(l.gradient=o);if(l.gradient)if(l.gradient.colors?.length>2){const e=l.gradient.colors,t=[e[0],e[e.length-1]],i=e.slice(1,e.length-1);h=window.JsvCode.ForgeHandles.TextureManager.CreateLinearGradientTexture(t,i)}else 2==l.gradient.colors?.length?h=window.JsvCode.ForgeHandles.TextureManager.CreateMiniGradientTexture(!0,l.gradient.colors[0],l.gradient.colors[1],l.gradient.rawValue):console.warn("Failed to create backgroundImage gradient, bad colors.",l.gradient.colors);else l.url&&(h=l.url.includes(".gif")||l.url.includes(".webp")?window.JsvCode.ForgeHandles.TextureManager.GetGifImage(l.url,!1,null,d):window.JsvCode.ForgeHandles.TextureManager.GetImage2(l.url,!1,r,a||e.ColorSpace.RGBA_8888));if(h){let t;n&&(t=new e.ViewRoundCornerMask(n.topLeft,n.topRight,n.bottomLeft,n.bottomRight));const o=new e.ExternalTextureSetting(h,t);if(i.ResetTexture(o),s){let e=h.RegisterLoadImageCallback(null,(function(){s({width:h.Width,height:h.Height})}));i.RegisterDetachCallback((()=>{h.UnregisterLoadImageCallback(e)}))}}}static SetMaskedBackgroundImage(i,o,n,s){if("string"==typeof o&&(o=new t(o)),o instanceof t==!1)throw Error("Bad Argument.",o);if("string"==typeof n&&(n=new t(n)),n instanceof t==!1)throw Error("Bad Argument(MaskURL).",n);const r=window.JsvCode.ForgeHandles.TextureManager.GetImage2(o.href,!1,null,s||e.ColorSpace.RGBA_8888);if(r){const t=window.JsvCode.ForgeHandles.TextureManager.GetImage2(n.href,!1,null,e.ColorSpace.RGBA_8888),o=new e.ExternalTextureSetting(r,new e.ViewTextureMask(t));i.ResetTexture(o)}}}export{e as Forge,i as ForgeExtension};
1
+ /* eslint-disable */ void 0===window.Forge?(window.Forge={},console.log("Define forge browser")):console.log("Define using JsView forge engine-js");var e=window.Forge;class t{constructor(e,t){if(!e)return;if(!0===e.startsWith("url")){let t=e.indexOf("(")+1,i=e.lastIndexOf(")");if("undefined"===(e=e.substring(t,i).trim())||"null"===e||0===e.length)return}if(!0===e.startsWith("data:")||!0===e.startsWith("jsvtexturestore:"))return void(this.href=e);let i=e.indexOf("://");if(!(i<0||i>10)||e.startsWith("./")||e.startsWith("/")||(e="./"+e),!0===e.startsWith("/"))e=document.location.origin+e;else if(!0===e.startsWith("./")&&void 0!==window.JsView&&void 0!==window.JsView.Dom.JsSubPath){if(void 0===window.JsView.Dom.MainPath||"undefined"===window.JsView.Dom.MainPathRef||window.JsView.Dom.MainPathRef!==document.location.href){window.JsView.Dom.JsSubPath.startsWith("/")||(window.JsView.Dom.JsSubPath="/"+window.JsView.Dom.JsSubPath),window.JsView.Dom.JsSubPath.endsWith("/")||(window.JsView.Dom.JsSubPath=window.JsView.Dom.JsSubPath+"/"),window.JsView.Dom.MainPathRef=document.location.href;let e=document.location.pathname.lastIndexOf(window.JsView.Dom.JsSubPath);window.JsView.Dom.MainPath=document.location.origin+document.location.pathname.substring(0,e)}e=window.JsView.Dom.MainPath+e.substring(1)}if(this.href=e,!t)return;let o=this.href,n=o.indexOf("#");n>0&&(this.hash=o.substring(n),o=o.substring(0,n));let s=o.indexOf("?");s>1&&(this.search=o.substring(s),o=o.substring(0,s));let r=o,a=r.indexOf("://");this.protocol=a>0?r.substring(0,a+1):"";let d=a>1?r.substring(a+3):"";a=d.indexOf("/"),this.host=a>0?d.substring(0,a):"",this.pathname=a>=1?d.substring(a):"","file:"==this.protocol&&(this.host="",this.pathname=d),this.origin=this.protocol+"//"+this.host,a=this.host.indexOf(":"),this.hostname=a>0?this.host.substring(0,a):this.host,this.port=a>1?this.host.substring(a+1):""}replace(e){this.href=e}href="";origin="";protocol="";host="";hostname="";port="";pathname="";search="";hash=""}class i{static SetBackgroundColor(t,i,o){const n=window.JsvCode.ForgeHandles.TextureManager.GetColorTextureCached(i);let s;o&&(s=new e.ViewRoundCornerMask(o.topLeft,o.topRight,o.bottomLeft,o.bottomRight));const r=new e.ExternalTextureSetting(n,s);t.ResetTexture(r)}static SetBackgroundImage(i,o,n,s,r,a,d){let h,l={};if("string"==typeof o){const e=new t(o);if(e instanceof t==!1)throw Error("Bad Argument.",e);l.url=e.href}else"linear-gradient"==o?.type&&(l.gradient=o);if(l.gradient)if(l.gradient.colors?.length>2){const e=l.gradient.colors,t=[e[0],e[e.length-1]],i=e.slice(1,e.length-1);h=window.JsvCode.ForgeHandles.TextureManager.CreateLinearGradientTexture(t,i)}else 2==l.gradient.colors?.length?h=window.JsvCode.ForgeHandles.TextureManager.CreateMiniGradientTexture(!0,l.gradient.colors[0],l.gradient.colors[1],l.gradient.rawValue):console.warn("Failed to create backgroundImage gradient, bad colors.",l.gradient.colors);else l.url&&(h=l.url.includes(".gif")||l.url.includes(".webp")?window.JsvCode.ForgeHandles.TextureManager.GetGifImage(l.url,!1,null,d):window.JsvCode.ForgeHandles.TextureManager.GetImage2(l.url,!1,r,a||e.ColorSpace.RGBA_8888));if(h){let t;n&&(t=new e.ViewRoundCornerMask(n.topLeft,n.topRight,n.bottomLeft,n.bottomRight));const o=new e.ExternalTextureSetting(h,t);if(i.ResetTexture(o),s){let e=h.RegisterLoadImageCallback(null,(function(){s({width:h.Width,height:h.Height})}));i.RegisterDetachCallback((()=>{h.UnregisterLoadImageCallback(e)}))}}}static SetMaskedBackgroundImage(i,o,n,s){if("string"==typeof o&&(o=new t(o)),o instanceof t==!1)throw Error("Bad Argument.",o);if("string"==typeof n&&(n=new t(n)),n instanceof t==!1)throw Error("Bad Argument(MaskURL).",n);const r=window.JsvCode.ForgeHandles.TextureManager.GetImage2(o.href,!1,null,s||e.ColorSpace.RGBA_8888);if(r){const t=window.JsvCode.ForgeHandles.TextureManager.GetImage2(n.href,!1,null,e.ColorSpace.RGBA_8888),o=new e.ExternalTextureSetting(r,new e.ViewTextureMask(t));i.ResetTexture(o)}}}export{e as Forge,i as ForgeExtension};
2
2
 
@@ -3,11 +3,13 @@
3
3
  */
4
4
 
5
5
  const TargetRevision = {
6
- "CoreRevision": 1021540,
7
- "CoreRevisionAndBranch": "1021540",
8
- "JseRevision": "1.0.894",
6
+ "CoreRevision": 1021684,
7
+ "CoreRevisionAndBranch": "1021684",
8
+ "JseRevision": "1.0.931",
9
9
  "JseUrl":
10
- "http://cdn.release.qcast.cn/forge_js/master/JsViewES6_js2c_r894.jsv.efbd22ea.js"
10
+ "http://cdn.release.qcast.cn/forge_js/master/JsViewES6_js2c_r931.jsv.a0eb46f1.js",
11
+ "JseName": "JsViewES6_js2c_r931.jsv.a0eb46f1.js",
12
+ "JsidtName": "libjsidt.102.7.so",
11
13
  };
12
14
 
13
15
  // 版本是否存在测试方法
@@ -2,8 +2,55 @@ import JsViewDefConfig from "./jsview.config.default"
2
2
  import { loadJsViewDomAsync } from '../dom'
3
3
  import TargetRevision from "../dom/target_core_revision"
4
4
 
5
+ const CYCLE_TIME = 10000;
6
+ const BLOCK_CHECK_TIME = 5000; // + CYCLE_TIME, 总计15秒
7
+ class JsThreadBlockTester {
8
+ static #TAG = "JsThreadBlockTester";
9
+ static #timeoutHandler = -1;
10
+ static #timestamp = 0;
11
+ static #checkTask = () => {
12
+ const preTimestamp = JsThreadBlockTester.#timestamp;
13
+ JsThreadBlockTester.#timestamp = Date.now();
14
+ const gap = JsThreadBlockTester.#timestamp - preTimestamp;
15
+ window.JsView?.logD?.(JsThreadBlockTester.#TAG, `check, pre: ${preTimestamp}, cur: ${JsThreadBlockTester.#timestamp}, cur-pre: ${gap}`);
16
+ if (gap > CYCLE_TIME + BLOCK_CHECK_TIME) {
17
+ console.warn(JsThreadBlockTester.#TAG, `js thread blocked, preTime: ${preTimestamp}, curTime: ${JsThreadBlockTester.#timestamp}, curTime-preTime: ${gap}`);
18
+ }
19
+ JsThreadBlockTester.#timeoutHandler = setTimeout(JsThreadBlockTester.#checkTask, CYCLE_TIME);
20
+ };
21
+ static #onVisibleChange = (data) => {
22
+ if (data.status == "hide") {
23
+ //stop cycle
24
+ console.log(JsThreadBlockTester.#TAG, "jsview activity hide");
25
+ JsThreadBlockTester.#stop();
26
+ } else {
27
+ //start cycle
28
+ console.log(JsThreadBlockTester.#TAG, "jsview activity show");
29
+ JsThreadBlockTester.#start();
30
+ }
31
+ }
32
+
33
+ static init() {
34
+ JsThreadBlockTester.#start();
35
+ window.JsView?.onVisibilityChange?.(JsThreadBlockTester.#onVisibleChange);
36
+ }
37
+
38
+ static #start() {
39
+ console.log(JsThreadBlockTester.#TAG, "start");
40
+ JsThreadBlockTester.#timestamp = Date.now();
41
+ JsThreadBlockTester.#timeoutHandler = setTimeout(JsThreadBlockTester.#checkTask, CYCLE_TIME);
42
+ }
43
+
44
+ static #stop() {
45
+ console.log(JsThreadBlockTester.#TAG, "stop");
46
+ clearTimeout(JsThreadBlockTester.#timeoutHandler);
47
+ JsThreadBlockTester.#timeoutHandler = -1;
48
+ }
49
+ }
50
+
5
51
  export default class JsViewLoader {
6
52
  constructor() {
53
+ JsThreadBlockTester.init();
7
54
  }
8
55
 
9
56
  mergeConfig(newConfig) {
@@ -20,9 +20,13 @@ async function main() {
20
20
  jsviewLoader.initForgeEnv();
21
21
 
22
22
  // 初始化jsview运行环境。
23
- const onInitJsViewEnv = function () {
23
+ const onInitJsViewEnv = async function () {
24
24
  // JsView环境加载完毕后,加载vue/react的main.js文件。
25
- import('/src/main.tsx');
25
+ try {
26
+ await import('/src/main.tsx');
27
+ } finally {
28
+ window.JsView?.onMainTsDone(); // 通知Java, 此时app首次渲染执行完毕
29
+ }
26
30
  };
27
31
  jsviewLoader.initJsViewEnv(appConfig.AppName, onInitJsViewEnv, PERMISSION);
28
32
  }
@@ -41,7 +41,6 @@ export default {
41
41
  // PS:注意'164'的引号
42
42
  bindKeys: {
43
43
  keys: {
44
- '164': 20001
45
44
  },
46
45
  syncKeys: {
47
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shijiu/jsview",
3
- "version": "2.1.25",
3
+ "version": "2.1.200-next-vue.0",
4
4
  "bin": {
5
5
  "jsview-post-build": "./tools/jsview-post-build.js",
6
6
  "jsview-post-install": "./tools/jsview-post-install.js"
@@ -373,6 +373,9 @@ function compileKeyframesNode(node) {
373
373
 
374
374
  let content = '{';
375
375
  for (const ident of node.nodes) {
376
+ if (ident.type === 'comment') {
377
+ continue;
378
+ }
376
379
  content += ident.selector;
377
380
  content += '{';
378
381
  for (const declaration of ident.nodes) {
@@ -366,6 +366,9 @@ const comparator = (a, b) => {
366
366
  }
367
367
  return diff;
368
368
  };
369
+ // JsView Modified >>>
370
+ let JsvRenderCount = 0;
371
+ // JsView Modified <<<
369
372
  function flushJobs(seen) {
370
373
  isFlushPending = false;
371
374
  isFlushing = true;
@@ -430,6 +433,8 @@ function flushJobs(seen) {
430
433
  }
431
434
 
432
435
  // JsView Modified >>>
436
+ //重置允许描画的个数
437
+ JsvRenderCount = 0;
433
438
  // 重置pending drawing状态
434
439
  jsvPendingForFirstDelayRender = false;
435
440
 
@@ -5154,7 +5159,9 @@ function baseCreateRenderer(options, createHydrationFns) {
5154
5159
  // JsView Added >>>
5155
5160
  // 有按键打断, 取消patch
5156
5161
  if (n1 == null && n2) {
5157
- if (n2.key == "__QcodeJsviewMetroWidgetSlot" && (jsvPendingForFirstDelayRender || window.JsView?.hasPendingUserInput?.())) {
5162
+ if (n2.key == "__QcodeJsviewMetroWidgetSlot"
5163
+ && (jsvPendingForFirstDelayRender || window.JsView?.hasPendingUserInput?.())
5164
+ && JsvRenderCount >= (window.JsView?.getInstantRenderNum?.() ?? 0)) {
5158
5165
  // 创建Comment节点, 以解决el释放可能出错问题
5159
5166
  // 同时存储el以便给父节点进行属性链接
5160
5167
  hostInsert((n2.el = hostCreateComment('')), container, anchor)
@@ -5187,6 +5194,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5187
5194
  }
5188
5195
  return;
5189
5196
  }
5197
+ JsvRenderCount++;
5190
5198
  }
5191
5199
  // JsView Added <<<
5192
5200
 
@@ -26,15 +26,16 @@ const jsviewConfig = defineConfig({
26
26
  assetFileNames: (chunkInfo) => chunkInfo.name.endsWith('.css')
27
27
  ? 'css/[name].[hash].css' : 'assets/[name].[hash].[ext]',
28
28
  //chunkFileNames: 'js/[name].[hash].js',
29
- chunkFileNames: 'js/chunk.jsv.[hash].js',
29
+ chunkFileNames: process.env['JSVIEW_KEEP_CHUNKNAME'] ? 'js/[name].[hash].js' : 'js/chunk.jsv.[hash].js',
30
30
  entryFileNames: 'js/main.jsv.[hash].js',
31
31
  format: 'esm',
32
32
  manualChunks: {
33
33
  'export-sfc': ['\0plugin-vue:export-helper'], // 将_export_sfc独立出来,防止被集成在jsview-vue中导致import deadloop.
34
34
  'vue': ['vue'], // 将vue独立出来,防止被集成在main.js中导致import deadloop.
35
35
  // 将dom-entry和forge-define分割出来,防止被集成在main.js中导致import deadloop.
36
- 'forge-define': ['@shijiu/jsview/dom/jsv-forge-define.mjs'],
37
- 'jsivew-dom-entry': ['@shijiu/jsview/dom/index.mjs'],
36
+ 'jsview-forge-define': ['@shijiu/jsview/dom/jsv-forge-define.mjs'],
37
+ 'jsview-dom-entry': ['@shijiu/jsview/dom/index.mjs'],
38
+ 'jsview-vue-entry': ['@shijiu/jsview-vue/index.js'],
38
39
  },
39
40
  },
40
41
  },
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import {
7
+ checkNodeVersion,
8
+ execCommand,
9
+ getOptions,
10
+ parseArguments,
11
+ rmSync,
12
+ Logger,
13
+ } from './jsview-common.mjs';
14
+
15
+ async function main(argv)
16
+ {
17
+ checkNodeVersion();
18
+
19
+ const options = getOptions();
20
+
21
+ const filter = argv.filter ?? '^jsview-';
22
+ const regex = new RegExp(filter);
23
+
24
+ execCommand('JSVIEW_KEEP_CHUNKNAME=true npm run build');
25
+
26
+ const srcmapFileNames = fs.readdirSync(options.distDebugMapDir);
27
+ const needlessFileNames = srcmapFileNames.filter(it => !it.match(regex));
28
+ for(const fileName of needlessFileNames) {
29
+ rmSync(options.projectDir, path.resolve(options.distDebugMapDir, fileName));
30
+ }
31
+
32
+ Logger.Info('Done...');
33
+ }
34
+
35
+ const requiredUsages = {
36
+ };
37
+ const optionalUsages = {
38
+ '--filter': "Filter condition, it's a regex.",
39
+ };
40
+ const argv = parseArguments(requiredUsages, optionalUsages);
41
+ main(argv);
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import {
7
+ checkNodeVersion,
8
+ execCommand,
9
+ getOptions,
10
+ makeZip,
11
+ parseArguments,
12
+ Logger,
13
+ } from './jsview-common.mjs';
14
+
15
+ async function main(argv)
16
+ {
17
+ checkNodeVersion();
18
+
19
+ const options = getOptions();
20
+
21
+ const zipName = 'dist.dat';
22
+ const zipPath = path.resolve(options.distDir, zipName);
23
+
24
+ const password = argv.password ?? 'jsview.shijiu.com';
25
+
26
+ execCommand('npm run build');
27
+
28
+ let childFileNames = fs.readdirSync(options.distDir);
29
+ childFileNames = childFileNames.filter(it => it !== zipName);
30
+ childFileNames = childFileNames.map(it => path.resolve(options.distDir, it));
31
+
32
+ makeZip(zipPath, password, ...childFileNames)
33
+
34
+ Logger.Info('Done...');
35
+ }
36
+
37
+ const requiredUsages = {
38
+ };
39
+ const optionalUsages = {
40
+ '--password': 'Input passwork',
41
+ };
42
+ const argv = parseArguments(requiredUsages, optionalUsages);
43
+ main(argv);
@@ -211,7 +211,18 @@ function getOptions(framework)
211
211
  options.appPubKeyFile = path.resolve(options.appConfigDir, 'app_sign_public_key.pem');
212
212
 
213
213
  options.distDir = path.resolve(options.projectDir, 'dist');
214
+ if (framework == 'vue') {
215
+ const vueConfigFile = path.resolve(options.projectDir, 'vue.config.js');
216
+ if (fs.existsSync(vueConfigFile)) {
217
+ let vueCfgContent = fs.readFileSync(vueConfigFile, 'utf8');
218
+ const vueCfgObj = JSON.parse(vueCfgContent);
219
+ if (vueCfgObj.outputDir) {
220
+ options.distDir = path.resolve(options.projectDir, vueCfgObj.outputDir);
221
+ }
222
+ }
223
+ }
214
224
  options.distJsvListFile = path.resolve(options.distDir, 'jsv-list.json');
225
+ options.distJsvInfoFile = path.resolve(options.distDir, 'jsv-info.json');
215
226
  options.distJsDir = path.resolve(options.distDir, 'js');
216
227
  options.distDebugDir = path.resolve(options.distDir, 'debug');
217
228
  options.distDebugMapDir = path.resolve(options.distDebugDir, 'map');
@@ -258,7 +269,7 @@ function cpSync(workDir, srcPath, destPath, ignore=[])
258
269
  if (ignore && ignore.includes(filename)) {
259
270
  return;
260
271
  }
261
- const desc = ' ' + path.relative(workDir, srcPath) + ' -> ' + path.relative(workDir, destPath);
272
+ const desc = ' Copying ' + path.relative(workDir, srcPath) + ' => ' + path.relative(workDir, destPath);
262
273
  Logger.Info(desc);
263
274
  const dirPath = path.dirname(destPath);
264
275
  if (fs.existsSync(dirPath) == false) {
@@ -270,7 +281,7 @@ function cpSync(workDir, srcPath, destPath, ignore=[])
270
281
 
271
282
  function rmSync(workDir, filePath)
272
283
  {
273
- const desc = ' -* ' + path.relative(workDir, filePath);
284
+ const desc = ' Removing ' + path.relative(workDir, filePath);
274
285
  Logger.Info(desc);
275
286
  fs.rmSync(filePath, { recursive: true, force: true });
276
287
  }
@@ -281,7 +292,7 @@ function symlinkSync(workDir, targetPath, toPath)
281
292
 
282
293
  const relativePath = path.relative(path.dirname(toPath), targetPath);
283
294
 
284
- const desc = ' ' + path.relative(workDir, toPath) + ' -< ' + path.relative(workDir, relativePath);
295
+ const desc = ' ' + path.relative(workDir, toPath) + ' Linking ' + path.relative(workDir, relativePath);
285
296
  Logger.Info(desc);
286
297
  fs.symlinkSync(relativePath, toPath, 'junction');
287
298
  }
@@ -344,6 +355,34 @@ function readJsonFile(filePath) {
344
355
  return null;
345
356
  }
346
357
 
358
+ function makeZip(zipFilePath, password, ...args)
359
+ {
360
+ zipFilePath = path.resolve(zipFilePath);
361
+ const zipFileDir = path.dirname(zipFilePath);
362
+ const zipFileName = path.basename(zipFilePath);
363
+
364
+ // 创建一个空zip包
365
+ let cmdLine = 'cd ' + zipFileDir + ' && rm -f ' + zipFileName;
366
+ cmdLine += ' && echo "dump" |zip ' + zipFileName + ' -';
367
+ cmdLine += ' && zip -d ' + zipFileName + ' "*"';
368
+ try {
369
+ childProcess.execSync(cmdLine);
370
+ } catch (error) {
371
+ Logger.ErrorAndExit('Failed to create zip file ' + zipFilePath, error);
372
+ }
373
+
374
+ for(const source of args) {
375
+ let cmdLine = 'cd ' + path.dirname(source)
376
+ cmdLine += ' && zip -ru ' + (password ? `-P ${password} ` : '') + zipFilePath + ' ' + path.basename(source);
377
+ try {
378
+ childProcess.execSync(cmdLine);
379
+ Logger.Info('Success to append file ' + source);
380
+ } catch (error) {
381
+ Logger.ErrorAndExit('Failed to make zip file from ' + source, error);
382
+ }
383
+ }
384
+ }
385
+
347
386
  export {
348
387
  askAndAnswer,
349
388
  checkNodeVersion,
@@ -352,6 +391,7 @@ export {
352
391
  getOptions,
353
392
  getPackageObject,
354
393
  isSymlinkSync,
394
+ makeZip,
355
395
  parseArguments,
356
396
  readJsonFile,
357
397
  rmSync,
@@ -8,6 +8,7 @@ import url from 'node:url'
8
8
  import {
9
9
  checkNodeVersion,
10
10
  getOptions,
11
+ getPackageObject,
11
12
  parseArguments,
12
13
  Logger,
13
14
  } from './jsview-common.mjs';
@@ -238,6 +239,35 @@ function makeJsvList(options)
238
239
  fs.writeFileSync(options.distJsvListFile, content, 'utf8');
239
240
  }
240
241
 
242
+ async function makeJsvInfo(options)
243
+ {
244
+ const jsviewPkgJson = getPackageObject(options.jsviewDir);
245
+
246
+ const jsviewVersionURL = url.pathToFileURL(options.jsviewDomRevisionFile);
247
+ const { default: jsviewTargetVersion } = await import(jsviewVersionURL);
248
+
249
+ const appConfigFilePath = path.resolve(options.appConfigDir, 'app.config.mjs');
250
+ if (!fs.existsSync(appConfigFilePath)) {
251
+ Logger.ErrorAndExit('Failed to open app config file from ' + appConfigFilePath);
252
+ }
253
+ const appConfigFileUrl = url.pathToFileURL(appConfigFilePath);
254
+ const { default: appConfig } = await import(appConfigFileUrl);
255
+
256
+
257
+ const jsvInfo = {
258
+ version: {
259
+ "@shijiu/jsview": jsviewPkgJson.version,
260
+ "Core": jsviewTargetVersion.CoreRevisionAndBranch,
261
+ "EngineJsUrl": jsviewTargetVersion.JseUrl,
262
+ "AppName": appConfig.AppName,
263
+ "AppVersion": appConfig.AppVersion,
264
+ }
265
+ };
266
+
267
+ const content = JSON.stringify(jsvInfo, null, 2);
268
+ fs.writeFileSync(options.distJsvInfoFile, content, 'utf8');
269
+ }
270
+
241
271
  function makeFileListRecusive(dir)
242
272
  {
243
273
  let fileList = [];
@@ -269,15 +299,6 @@ async function main(argv)
269
299
 
270
300
  await checkDomDebugDisabled(options);
271
301
 
272
- const vueConfigFile = path.resolve(options.projectDir, 'vue.config.js');
273
- if (fs.existsSync(vueConfigFile)) {
274
- let vueCfgContent = fs.readFileSync(vueConfigFile, 'utf8');
275
- const vueCfgObj = JSON.parse(vueCfgContent);
276
- if(vueCfgObj.outputDir) {
277
- options.distDir = path.resolve(options.projectDir, vueCfgObj.outputDir);
278
- }
279
- }
280
-
281
302
  Logger.Info();
282
303
  Logger.Info('Redirecting JsView source map...');
283
304
  redirectSourceMappingURL(options)
@@ -299,9 +320,10 @@ async function main(argv)
299
320
  makeDebugMap(options, argv.framework);
300
321
  Logger.Info('Made JsView Debug map.');
301
322
 
302
- Logger.Info('Making JsView list...');
323
+ Logger.Info('Making JsView info...');
303
324
  makeJsvList(options);
304
- Logger.Info('Made JsView list...');
325
+ await makeJsvInfo(options);
326
+ Logger.Info('Made JsView info...');
305
327
 
306
328
  Logger.Info('Done...');
307
329
  }
@@ -135,6 +135,7 @@ async function printRevision(options)
135
135
  Logger.Info('* Update revision to:');
136
136
  Logger.Info('* CORE: ' + jsviewTargetVersion.CoreRevisionAndBranch);
137
137
  Logger.Info('* ENGINE JS URL: ' + jsviewTargetVersion.JseUrl);
138
+ Logger.Info('* DEVTOOLS-SO VER: ' + jsviewTargetVersion.JsidtName);
138
139
  Logger.Info('* PLUGIN LIST: ');
139
140
 
140
141
  // print plugin info
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ import {
5
+ askAndAnswer,
6
+ checkNodeVersion,
7
+ getOptions,
8
+ parseArguments,
9
+ Logger,
10
+ execCommand,
11
+ } from './jsview-common.mjs';
12
+
13
+ async function getExtraOptions(argv)
14
+ {
15
+ const options = getOptions(argv.framework);
16
+ options.jsviewCoreRevision = null;
17
+ options.jsviewEngineUrl = null;
18
+ options.entryUrl = argv.url;
19
+
20
+ let commandCount = 0;
21
+ commandCount += (argv.genKeypair ? 1 : 0);
22
+ commandCount += (argv.runonAndroid ? 1 : 0);
23
+ commandCount += (argv.buildMinmap ? 1 : 0);
24
+ commandCount += (argv.buildZip ? 1 : 0);
25
+ if(commandCount == 0) {
26
+ const commandPrompt = [
27
+ ' 1. runon-android',
28
+ ' 2. gen-keypair',
29
+ ' 3. build-minmap',
30
+ ' 4. build-offline',
31
+ ];
32
+
33
+ Logger.Info();
34
+ Logger.Info('Please choice a command:');
35
+ for(const key in commandPrompt) {
36
+ Logger.Info(key);
37
+ }
38
+ const answer = askAndAnswer('Command Index: ');
39
+ switch(answer) {
40
+ case '1':
41
+ options.runonAndroid = true;
42
+ break;
43
+ case '2':
44
+ options.genKeypair = true;
45
+ break;
46
+ case '3':
47
+ options.buildMinmap = true;
48
+ break;
49
+ case '4':
50
+ options.buildZip = true;
51
+ break;
52
+ default:
53
+ Logger.ErrorAndExitNoException("Unknown input: " + answer);
54
+ }
55
+ } else if(commandCount == 1) {
56
+ options.runonAndroid = argv.runonAndroid;
57
+ options.genKeypair = argv.genKeypair;
58
+ options.buildMinmap = argv.buildMinmap;
59
+ options.buildZip = argv.buildZip;
60
+ } else if(commandCount > 1) {
61
+ Logger.ErrorAndExitNoException("Only one command can be executed.");
62
+ }
63
+
64
+ return options;
65
+ }
66
+
67
+ function doCommand(options) {
68
+ let command;
69
+ if(options.runonAndroid) {
70
+ command = 'node node_modules/@shijiu/jsview/tools/jsview-run-android.mjs --framework=vue';
71
+ } else if(options.genKeypair) {
72
+ command = 'node node_modules/@shijiu/jsview/tools/jsview-generate-keypair.mjs';
73
+ } else if(options.buildMinmap) {
74
+ const defaultFilter = '^jsview-';
75
+ const filter = (typeof(options.buildMinmap) === 'string' ? options.buildMinmap : defaultFilter);
76
+ if(filter !== options.buildMinmap) {
77
+ Logger.Warn('Map filter is not set, use default value: ' + defaultFilter);
78
+ }
79
+
80
+ command = 'node node_modules/@shijiu/jsview/tools/jsview-build-minmap.mjs --filter=' + filter;
81
+ } else if(options.buildZip) {
82
+ const defaultPassword = 'jsview.shijiu.com';
83
+ const password = (typeof(options.buildZip) === 'string' ? options.buildZip : defaultPassword);
84
+ if(password !== options.buildZip) {
85
+ Logger.Warn('Zip password is not set, use default value: ' + defaultPassword);
86
+ }
87
+
88
+ command = 'node node_modules/@shijiu/jsview/tools/jsview-build-zip.mjs --password=' + password;
89
+ }
90
+
91
+ execCommand(command);
92
+ }
93
+
94
+ async function main(argv)
95
+ {
96
+ checkNodeVersion();
97
+
98
+ const options = await getExtraOptions(argv);
99
+
100
+ doCommand(options);
101
+ }
102
+
103
+ const requiredUsages = {
104
+ '--framework': 'Select from [vue|react]',
105
+ };
106
+ const optionalUsages = {
107
+ '-a | --runon-android': 'Run app on android devices.',
108
+ '-g | --gen-keypair': 'Generate sign keypair.',
109
+ '-m | --build-minmap': 'Build target with filter map, like: -m or --build-minmap=[filter].',
110
+ '-z | --build-zip': 'Build target to offline zip package, like: -z or --build-zip=[password].',
111
+ };
112
+ const argv = parseArguments(requiredUsages, optionalUsages, false);
113
+ main(argv)