@shijiu/jsview 2.2.373 → 2.3.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.
Files changed (33) hide show
  1. package/dom/bin/DroidNaskh-Regular.ttf +0 -0
  2. package/dom/bin/DroidSans.ttf +0 -0
  3. package/dom/bin/DroidSansFallback.ttf +0 -0
  4. package/dom/bin/NotoColorEmoji.ttf +0 -0
  5. package/dom/bin/jsview-dom-browser-engine-core.min.js +2 -0
  6. package/dom/bin/jsview-dom-browser-engine-modules.min.js +2 -0
  7. package/dom/bin/jsview-dom-browser-forge.1436.54c9.wasm +0 -0
  8. package/dom/bin/jsview-dom-browser-forge.min.js +1 -0
  9. package/dom/bin/jsview-dom-browser-forge.worker.min.js +1 -0
  10. package/dom/bin/jsview-dom-browser.min.js +1 -1
  11. package/dom/bin/jsview-dom-native.min.js +1 -1
  12. package/dom/bin/jsview-engine-js-browser.min.js +1 -22
  13. package/dom/bin/jsview-engine-js-native.min.js +1 -1
  14. package/dom/bin/jsview-forge-define.min.js +1 -1
  15. package/dom/index.mjs +8 -10
  16. package/dom/target_core_revision.mjs +3 -3
  17. package/loader/jsv-core-api/jsview-core-api-glue.js +74 -0
  18. package/loader/jsv-core-api/wasm/backgroundtask.js +66 -0
  19. package/loader/jsv-core-api/wasm/core-api.js +208 -0
  20. package/loader/jsv-core-api/wasm/wasm-extension.js +37 -0
  21. package/loader/jsview-config.js +4 -1
  22. package/loader/jsview-loader.js +67 -77
  23. package/loader/jsview-main.mjs +1 -1
  24. package/package.json +1 -1
  25. package/patches/node_modules/vite/dist/node/jsview-vite-extension.js +67 -6
  26. package/tools/https-server-config/cert.pem +61 -0
  27. package/tools/https-server-config/key.pem +27 -0
  28. package/tools/https-server-config/serve.config.json +16 -0
  29. package/tools/jsview-common.mjs +86 -3
  30. package/tools/jsview-post-build.mjs +153 -3
  31. package/tools/jsview-post-install.mjs +7 -4
  32. package/tools/jsview-retrieve-sourcemap.mjs +64 -49
  33. package/tools/jsview-run-tool.mjs +88 -10
@@ -0,0 +1,37 @@
1
+
2
+ // wasm glue 特有api
3
+ export default class WasmCoreApisExtension {
4
+ constructor() {
5
+ this.ForgeCanvasRef = null;
6
+ this._EventBridge = null; // listenerToAckEvent 的分发处理
7
+ }
8
+
9
+ setForgeCanvasSingleton(forge_canvas_ref) {
10
+ this.ForgeCanvasRef = forge_canvas_ref;
11
+ }
12
+
13
+ setEventBridge(event_bridge) {
14
+ this._EventBridge = event_bridge;
15
+ }
16
+
17
+ listenerToAckEvent(category, type, track_id_from_js, callback_func) {
18
+ this._EventBridge?.listenerToAckEvent(category, type, track_id_from_js, callback_func);
19
+ }
20
+
21
+ recycleAckListener(callback_func) {
22
+ this._EventBridge?.recycleAckListener(callback_func);
23
+ }
24
+
25
+ onForgeAppReady() {
26
+ this.ForgeCanvasRef?.onForgeAppReady();
27
+ }
28
+
29
+ measurePosition(position, designMapWidth) {
30
+ return this.ForgeCanvasRef?.measurePosition(position, designMapWidth);
31
+ }
32
+
33
+ setLogSingleton(forge_log_ref, jse_log_ref) {
34
+ this.ForgeLogRef = forge_log_ref;
35
+ this.JseLogRef = jse_log_ref;
36
+ }
37
+ }
@@ -1,8 +1,11 @@
1
1
  import appConfig from "/src/appConfig/app.config.mjs";
2
2
  import jsviewVendorConfig from "/src/appConfig/jsview.config.mjs";
3
3
  import { PERMISSION } from "/src/appConfig/permission.js";
4
-
5
4
  import JsViewLoader from './jsview-loader.js';
5
+ import loadJsvCoreApi from "./jsv-core-api/jsview-core-api-glue.js"
6
+
7
+ // 加载JsvCoreApi
8
+ window.JsvCoreApi = loadJsvCoreApi();
6
9
 
7
10
  let loader = JsViewLoader;
8
11
  // 根据JsViewConfig, 判断厂商是否设置了使用远程loader启动
@@ -2,6 +2,10 @@ import JsViewDefConfig from "./jsview.config.default"
2
2
  import { loadJsViewDomAsync, loadEngineJs } from '../dom'
3
3
  import TargetRevision from "../dom/target_core_revision"
4
4
 
5
+ function isNoWasm() {
6
+ return (window.JsvCoreApi.Platform != "pc-wasm");
7
+ }
8
+
5
9
  const CYCLE_TIME = 10000;
6
10
  const BLOCK_CHECK_TIME = 5000; // + CYCLE_TIME, 总计15秒
7
11
  class JsThreadBlockTester {
@@ -12,7 +16,7 @@ class JsThreadBlockTester {
12
16
  const preTimestamp = JsThreadBlockTester.#timestamp;
13
17
  JsThreadBlockTester.#timestamp = Date.now();
14
18
  const gap = JsThreadBlockTester.#timestamp - preTimestamp;
15
- window.JsView?.logD?.(JsThreadBlockTester.#TAG, `check, pre: ${preTimestamp}, cur: ${JsThreadBlockTester.#timestamp}, cur-pre: ${gap}`);
19
+ window.JsvCoreApi.logD(JsThreadBlockTester.#TAG, `check, pre: ${preTimestamp}, cur: ${JsThreadBlockTester.#timestamp}, cur-pre: ${gap}`);
16
20
  if (gap > CYCLE_TIME + BLOCK_CHECK_TIME) {
17
21
  console.warn(JsThreadBlockTester.#TAG, `js thread blocked, preTime: ${preTimestamp}, curTime: ${JsThreadBlockTester.#timestamp}, curTime-preTime: ${gap}`);
18
22
  }
@@ -32,7 +36,7 @@ class JsThreadBlockTester {
32
36
 
33
37
  static init() {
34
38
  JsThreadBlockTester.#start();
35
- window.JsView?.onVisibilityChange?.(JsThreadBlockTester.#onVisibleChange);
39
+ window.JsvCoreApi.onVisibilityChange(JsThreadBlockTester.#onVisibleChange);
36
40
  }
37
41
 
38
42
  static #start() {
@@ -60,37 +64,42 @@ export default class JsViewLoader {
60
64
  }
61
65
 
62
66
  async initJsViewEnv(appName, onLoaded, permission) {
67
+ let onForgeAppReady = () => {
68
+ window.JsvCoreApi.WasmExt?.onForgeAppReady();
69
+ onLoaded?.();
70
+ }
71
+
63
72
  // 加载嵌入到 dom 模块中的 EngineJs
64
73
  await loadEngineJs(
65
- !!window.JsView,
66
- this.#runForgeApp.bind(this),
74
+ isNoWasm(),
75
+ (activityManager) => {
76
+ console.log("JsView Loader: On RenderBridge ready.");
77
+ this.#forgeActivityManager = activityManager;
78
+ this.#tryStartForgeApp(onForgeAppReady);
79
+ },
67
80
  this.#makeForgeDesignedMap.bind(this)
68
81
  );
69
82
 
70
83
  // 加载JsView Dom
71
- const jsviewDom = await loadJsViewDomAsync(window.JsView);
84
+ const jsviewDom = await loadJsViewDomAsync(isNoWasm());
72
85
 
73
86
  // 加载ForgeFront
74
87
  jsviewDom.InitEnv();
75
88
 
76
- if (window.JsView) {
77
- this.#forgeAppClass = jsviewDom.NativeForgeApp;
89
+ this.#forgeAppClass = jsviewDom.ForgeAppClass;
78
90
 
79
- // /static/js/: (可选配置)填写main.js或者bundle.js相对于index.html的相对位置,
80
- // 用于image / import.then的相对寻址
81
- if (typeof this.#config.jsviewConfig.jsRelativeDepth == "number") {
82
- window.location?.jsvSetRelativeDepth(this.#config.jsviewConfig.jsRelativeDepth)
83
- }
84
- } else {
85
- this.#forgeAppClass = jsviewDom.BrowserForgeApp;
91
+ // /static/js/: (可选配置)填写main.js或者bundle.js相对于index.html的相对位置,
92
+ // 用于image / import.then的相对寻址
93
+ if (typeof this.#config.jsviewConfig.jsRelativeDepth == "number") {
94
+ window.location?.jsvSetRelativeDepth?.(this.#config.jsviewConfig.jsRelativeDepth)
86
95
  }
87
96
 
88
- this.#loadJsViewEnvAsync(appName, onLoaded, permission);
97
+ this.#loadJsViewEnvAsync(appName, permission);
89
98
 
90
99
  // 环境启动后,动态加载React框架和main
91
100
  this.#checkEngineVersion();
92
101
  this.#jsviewInited = true;
93
- this.#tryStartForgeApp();
102
+ this.#tryStartForgeApp(onForgeAppReady);
94
103
 
95
104
  console.log("JsView Loader: Load done. AppName=" + appName);
96
105
  }
@@ -118,73 +127,57 @@ export default class JsViewLoader {
118
127
  return target;
119
128
  }
120
129
 
121
- #loadJsViewEnvAsync(appName, onLoaded, permission) {
130
+ #loadJsViewEnvAsync(appName, permission) {
122
131
  console.log("StartApp...");
123
132
 
124
- // 运行在Native中
125
- if (window.JsView) {
126
- if (appName) {
127
- window.JsView.setMiniAppPermissionInfo?.(JSON.stringify(permission));
128
- window.JsView.notifyAppName?.(appName);
129
- }
133
+ if (appName) {
134
+ window.JsvCoreApi.setMiniAppPermissionInfo(JSON.stringify(permission));
135
+ window.JsvCoreApi.notifyAppName(appName);
136
+ }
137
+
138
+ // (可选配置)按键接受的扩展,例如将静音按键(JAVA键值为164)映射为JS键值20001,PS:注意"164"的引号
139
+ window.JsvCoreApi.addKeysMap(this.#config.vendorConfig.bindKeys);
140
+
141
+ // (可选配置)localStorage支持
142
+ let storageDomain = this.#config.jsviewConfig.localStorage.domain;
143
+ if (!storageDomain || storageDomain === "default") {
144
+ // 兼容历史版本出现的default字符串设置
145
+ storageDomain = appName; // null/default场景,不和其他应用共享localStorage, 也规避了考虑同名item问题
146
+ } else if (storageDomain === "follow-url") {
147
+ if (window.location.protocol == "file:") {
148
+ // file方式加载,使用appName
149
+ storageDomain = appName;
150
+ console.warn("Storage domain follow-url not support file://");
151
+ } else {
152
+ storageDomain = window.location.hostname;
130
153
 
131
- // (可选配置)按键接受的扩展,例如将静音按键(JAVA键值为164)映射为JS键值20001,PS:注意"164"的引号
132
- window.JsView.addKeysMap(this.#config.vendorConfig.bindKeys);
133
-
134
- // (可选配置)localStorage支持
135
- let storageDomain = this.#config.jsviewConfig.localStorage.domain;
136
- if (!storageDomain || storageDomain === "default") {
137
- // 兼容历史版本出现的default字符串设置
138
- storageDomain = appName; // null/default场景,不和其他应用共享localStorage, 也规避了考虑同名item问题
139
- } else if (storageDomain === "follow-url") {
140
- if (window.location.protocol == "file:") {
141
- // file方式加载,使用appName
154
+ const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
155
+ const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
156
+ if (ipv4Regex.test(storageDomain) || ipv6Regex.test(storageDomain)) {
157
+ // ip形式, 不能作为合格domain, 使用appName作为domain
142
158
  storageDomain = appName;
143
- console.warn("Storage domain follow-url not support file://");
144
- } else {
145
- storageDomain = window.location.hostname;
146
-
147
- const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
148
- const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
149
- if (ipv4Regex.test(storageDomain) || ipv6Regex.test(storageDomain)) {
150
- // ip形式, 不能作为合格domain, 使用appName作为domain
151
- storageDomain = appName;
152
- console.warn("Storage domain follow-url not support host with ip");
153
- }
159
+ console.warn("Storage domain follow-url not support host with ip");
154
160
  }
155
161
  }
156
- console.log(`Storage domain [${storageDomain}]`);
157
- window.JsView.setStorageDomain(storageDomain); // Domain为app包名
158
-
159
- const localStorageKeys = this.#config.jsviewConfig.localStorage.presetKeys;
160
- window.JsView.enableStorageNames(...localStorageKeys);
162
+ }
163
+ console.log(`Storage domain [${storageDomain}]`);
164
+ window.JsvCoreApi.setStorageDomain(storageDomain); // Domain为app包名
161
165
 
162
- // (可选设置)cookies的支持
163
- const cookiesDomain = this.#config.jsviewConfig.cookies?.domain;
164
- if (cookiesDomain) {
165
- console.log("Enable cookie for domain " + cookiesDomain);
166
- window.JsView.setCookieDomain?.(cookiesDomain);
167
- }
166
+ const localStorageKeys = this.#config.jsviewConfig.localStorage.presetKeys;
167
+ window.JsvCoreApi.enableStorageNames(...localStorageKeys);
168
168
 
169
- // JsView Dom相关配置
170
- window.JsView.Dom.Render = function () {
171
- onLoaded()
172
- };
173
- } else {
174
- this.#forgeAppClass.SetRender(function () {
175
- onLoaded();
176
- })
169
+ // (可选设置)cookies的支持
170
+ const cookiesDomain = this.#config.jsviewConfig.cookies?.domain;
171
+ if (cookiesDomain) {
172
+ console.log("Enable cookie for domain " + cookiesDomain);
173
+ window.JsvCoreApi.setCookieDomain(cookiesDomain);
177
174
  }
178
175
  }
179
176
 
180
177
  #checkEngineVersion() {
181
- if (!window.JsView) {
182
- return;
183
- }
184
-
185
178
  // 检查配套引擎的版本
186
- if (window.JsView.CodeRevision !== TargetRevision.CoreRevision /* Native引擎版本(由APK启动参数 CORE 决定) */) {
187
- console.warn(`Warning: JsView Engine version miss matched, some effect will be lost or crash!! current using core=${window.JsView.CodeRevision} (but core should be ${TargetRevision.CoreRevision})`);
179
+ if (window.JsvCoreApi.CodeRevision !== TargetRevision.CoreRevision /* Native引擎版本(由APK启动参数 CORE 决定) */) {
180
+ console.warn(`Warning: JsView Engine version miss matched, some effect will be lost or crash!! current using core=${window.JsvCoreApi.CodeRevision} (but core should be ${TargetRevision.CoreRevision})`);
188
181
  }
189
182
  }
190
183
 
@@ -220,13 +213,7 @@ export default class JsViewLoader {
220
213
  return designMap;
221
214
  }
222
215
 
223
- #runForgeApp(activityManager) {
224
- console.log("JsView Loader: Run forge app.");
225
- this.#forgeActivityManager = activityManager;
226
- this.#tryStartForgeApp();
227
- }
228
-
229
- #tryStartForgeApp() {
216
+ #tryStartForgeApp(onForgeAppReady) {
230
217
  if (!this.#forgeActivityManager ||
231
218
  this.#jsviewInited == false) {
232
219
  return;
@@ -235,6 +222,9 @@ export default class JsViewLoader {
235
222
  console.log("JsView Loader: Start forge app.");
236
223
  // eslint-disable-next-line new-cap
237
224
  this.#forgeApp = new this.#forgeAppClass(this.#forgeActivityManager);
225
+
226
+ // Forge app创建完成
227
+ onForgeAppReady();
238
228
  }
239
229
 
240
230
  #config = JsViewDefConfig;
@@ -19,7 +19,7 @@ async function main() {
19
19
  try {
20
20
  await import('/src/main.tsx');
21
21
  } finally {
22
- window.JsView?.onMainTsDone(); // 通知Java, 此时app首次渲染执行完毕
22
+ window.JsvCoreApi.onMainTsDone(); // 通知Java, 此时app首次渲染执行完毕
23
23
  }
24
24
  };
25
25
  jsviewLoader.initJsViewEnv(appConfig.AppName, onInitJsViewEnv, PERMISSION);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shijiu/jsview",
3
- "version": "2.2.373",
3
+ "version": "2.3.0",
4
4
  "bin": {
5
5
  "jsview-post-build": "./tools/jsview-post-build.js",
6
6
  "jsview-post-install": "./tools/jsview-post-install.js"
@@ -2,6 +2,7 @@ import { defineConfig } from 'vite'
2
2
  import fs from 'fs'
3
3
  import path from 'path'
4
4
  // import fullReload from 'vite-plugin-full-reload';
5
+ // import wasm from "vite-plugin-wasm";
5
6
 
6
7
  // https://vitejs.dev/config/
7
8
  const jsviewConfig = defineConfig({
@@ -23,10 +24,10 @@ const jsviewConfig = defineConfig({
23
24
  polyfill: false
24
25
  },
25
26
  rollupOptions: {
27
+ onwarn: onRollupWarning,
26
28
  output: {
27
- assetFileNames: (chunkInfo) => chunkInfo.name.endsWith('.css') ? 'css/[name].[hash].css' : 'assets/[name].[hash].[ext]',
28
- chunkFileNames: process.env['JSVIEW_KEEP_CHUNKNAME'] ? 'js/[name].[hash].js' : 'js/chunk.jsv2.[hash].js',
29
- // chunkFileNames: 'js/[name].[hash].js',
29
+ assetFileNames: getFileName,
30
+ chunkFileNames: getFileName,
30
31
  entryFileNames: 'js/main.jsv.[hash].js',
31
32
  format: 'esm',
32
33
  manualChunks: {
@@ -42,7 +43,7 @@ const jsviewConfig = defineConfig({
42
43
  },
43
44
  plugins: [
44
45
  {
45
- name: 'remove-bangs',
46
+ name: 'vite-plugin-remove-bangs',
46
47
  renderChunk(code) { return {
47
48
  code: code.replace(/^\/\/!/g, '//').replace(/^\/\*!/g, '/*'),
48
49
  map: null,
@@ -72,9 +73,10 @@ const jsviewConfig = defineConfig({
72
73
  'jsview-vue-samples',
73
74
  ],
74
75
  },
75
- // plugins: [
76
+ plugins: [
76
77
  // fullReload('node_modules/@shijiu/**/*'),
77
- // ],
78
+ // wasm(),
79
+ ],
78
80
  resolve: {
79
81
  alias: {
80
82
  // 'jsview': path.resolve(process.cwd(), 'node_modules/@shijiu/jsview'),
@@ -87,7 +89,12 @@ const jsviewConfig = defineConfig({
87
89
  preserveSymlinks: true
88
90
  },
89
91
  server: {
92
+ headers: { // 启用浏览器SharedArrayBuffer,webassmbly的thread用
93
+ 'Cross-Origin-Opener-Policy': 'same-origin',
94
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
95
+ },
90
96
  host: true,
97
+ https: process.env['JSVIEW_ENABLE_HTTPS'] ? getHttpsConfig() : false,
91
98
  open: !process.env['JSVIEW_DISABLE_OPEN_BROWSER'] && process.platform === "darwin",
92
99
  watch: {
93
100
  ignored: [
@@ -95,6 +102,16 @@ const jsviewConfig = defineConfig({
95
102
  ],
96
103
  }
97
104
  },
105
+ worker: {
106
+ format: 'esm',
107
+ rollupOptions: {
108
+ output: {
109
+ assetFileNames: getFileName,
110
+ chunkFileNames: getFileName,
111
+ entryFileNames: getFileName,
112
+ },
113
+ },
114
+ },
98
115
  });
99
116
 
100
117
  function getModuleDir() {
@@ -135,6 +152,50 @@ function ensureFramework(originConfig) {
135
152
  return framework;
136
153
  }
137
154
 
155
+ function getFileName(chunkInfo) {
156
+ if(chunkInfo.name.endsWith('.css')) {
157
+ return 'css/[name].[hash].css';
158
+ } else if(chunkInfo.name.endsWith('.ttf')) {
159
+ return 'assets/[name].ttf';
160
+ } else if(chunkInfo.name.endsWith('.wasm')) {
161
+ return 'js/[name].wasm';
162
+ } else if(chunkInfo.type == 'chunk') {
163
+ return (process.env['JSVIEW_KEEP_CHUNKNAME'] ? 'js/[name].[hash].js' : 'js/chunk.jsv2.[hash].js');
164
+ }
165
+
166
+ return 'assets/[name].[hash].[ext]'
167
+ }
168
+
169
+ function onRollupWarning(warning, defaultHandler) {
170
+ if (warning.code === 'FILE_NAME_CONFLICT') {
171
+ if(warning.message.includes('jsview-dom-browser-forge')
172
+ && warning.message.includes('.wasm')) {
173
+ console.info('\nJsView Info: Ignore warning', warning.message)
174
+ return;
175
+ }
176
+ } else if (warning.code === 'EVAL') {
177
+ if(warning.message.includes('mock.js')) {
178
+ console.info('\nJsView Info: Ignore warning', warning.message)
179
+ return;
180
+ }
181
+ }
182
+
183
+ defaultHandler(warning);
184
+ }
185
+
186
+ function getHttpsConfig() {
187
+ const configDir = path.resolve(getModuleDir(), '@shijiu/jsview/tools/https-server-config');
188
+ const certFilePath = path.resolve(configDir, 'cert.pem');
189
+ const keyFilePath = path.resolve(configDir, 'key.pem');
190
+
191
+ return {
192
+ cert: fs.readFileSync(certFilePath),
193
+ key: fs.readFileSync(keyFilePath),
194
+ maxVersion: 'TLSv1.2',
195
+ minVersion: 'TLSv1',
196
+ }
197
+ }
198
+
138
199
  function jsvCreateJsViewViteConfig(originConfig) {
139
200
  let aliasJsView;
140
201
 
@@ -0,0 +1,61 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIF+TCCBOGgAwIBAgIQD86irWNoDq1u1raeYxf5STANBgkqhkiG9w0BAQsFADBu
3
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
4
+ d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
5
+ RFYgVExTIENBIC0gRzIwHhcNMjQxMDI0MDAwMDAwWhcNMjUwMTIxMjM1OTU5WjAU
6
+ MRIwEAYDVQQDEwlxaW5nbWEuY2MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
7
+ AoIBAQCnub2hwc+a36hc5XwRg9GADOck0+lFRAwWPxkoTKF2hucVDASM2W75iXAk
8
+ PaOOWSkoGsbCBSpTvdW1lmQDpMwSaQPpk6caeQi3XAQr8Cm6EwFoG3KjlXJgQDYm
9
+ MRrE+CMfr4SlJ4sG+mSMPHONgFcPBDB+9hoMC9Fxqz+A8IUe+tpIVIyxaC2JkI7F
10
+ PtWLGwUZqVmx3qwnbi8do86Szp5OZKQeiBVSJfvhqDqp9q+2Q+0ktjvXy2ru6a63
11
+ V8hKA5RLO3XcpQfPryM+fX4U/0rveF9pgo0Kd9Nqvx3nVgglHJKekI1sp51uMrv+
12
+ zW4QrsuDYuWyebmTN7RaFiE3kICpAgMBAAGjggLrMIIC5zAfBgNVHSMEGDAWgBR4
13
+ 35GQX+7erPbFdevVTFVT7yRKtjAdBgNVHQ4EFgQU5/BTc9JIOxyG/HeKbZ5UV3cq
14
+ +w8wIwYDVR0RBBwwGoIJcWluZ21hLmNjgg13d3cucWluZ21hLmNjMD4GA1UdIAQ3
15
+ MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQu
16
+ Y29tL0NQUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
17
+ AQUFBwMCMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw
18
+ LmRpZ2ljZXJ0LmNvbTBKBggrBgEFBQcwAoY+aHR0cDovL2NhY2VydHMuZGlnaWNl
19
+ cnQuY29tL0VuY3J5cHRpb25FdmVyeXdoZXJlRFZUTFNDQS1HMi5jcnQwDAYDVR0T
20
+ AQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYATnWjJ1yaEMM4W2zU
21
+ 3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGSvU+icAAABAMARzBFAiBJVL9R7lBz16jy
22
+ 8e0TJBdTzV3fMTWfzlRYZhG+I14puAIhANzli+hGrVk7AcsZCMMohZMcktsBKOfb
23
+ zsFZFllGlgXcAHYAfVkeEuF4KnscYWd8Xv340IdcFKBOlZ65Ay/ZDowuebgAAAGS
24
+ vU+iKwAABAMARzBFAiEA/AuFfaSAEthtIWr/xBManOf3Bz2LJPK8+YUtODolslAC
25
+ IFo7Y5E9FpWqQSNWB+Gq35rOsn/u9Chqfeu7h/LV33HPAHYA5tIxY0B3jMEQQQbX
26
+ cbnOwdJA9paEhvu6hzId/R43jlAAAAGSvU+iQAAABAMARzBFAiBhpXUJ0Ix8NI2Q
27
+ pKgzYUtz8WxSxuGTpf2bJw+xCybZeQIhAKz0p1DvF9hcp46QAfwVTlwyVPNDJCLD
28
+ OYSqdfy6xWCyMA0GCSqGSIb3DQEBCwUAA4IBAQCDQbUsMb7BOr4iCbcbZ25I7VDF
29
+ xUzk9b2n/z4CDlbbnmWn/8YtMORyspG2bBKp62sPpgt86SQC+f81aPMCAylJZjbt
30
+ gS4IGCQnnHyJsLez4ITQwA38xemjP/vbc++GVuQZFADfDYoSfjq73prEeGybtL9j
31
+ bkkkO3xC5Bba7enxu1IPlEwXOzlmfj5NxY6L69NRLYhgSeoEGl4NxMkAF5Cef6B8
32
+ wRMmeoyBtguAdLRU+y4I9Bsm5yOs+iSRb6nzTkbYj2QYvByXcHwC2bpW0wKJZYS+
33
+ KDUYTqSwJp9Jw9Jec6uSoZfsvaezKw1Gy40jtQbvsK+fr4LXFN8qi2aJWgl9
34
+ -----END CERTIFICATE-----
35
+ -----BEGIN CERTIFICATE-----
36
+ MIIEqjCCA5KgAwIBAgIQDeD/te5iy2EQn2CMnO1e0zANBgkqhkiG9w0BAQsFADBh
37
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
38
+ d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
39
+ MjAeFw0xNzExMjcxMjQ2NDBaFw0yNzExMjcxMjQ2NDBaMG4xCzAJBgNVBAYTAlVT
40
+ MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
41
+ b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
42
+ MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO8Uf46i/nr7pkgTDqnE
43
+ eSIfCFqvPnUq3aF1tMJ5hh9MnO6Lmt5UdHfBGwC9Si+XjK12cjZgxObsL6Rg1njv
44
+ NhAMJ4JunN0JGGRJGSevbJsA3sc68nbPQzuKp5Jc8vpryp2mts38pSCXorPR+sch
45
+ QisKA7OSQ1MjcFN0d7tbrceWFNbzgL2csJVQeogOBGSe/KZEIZw6gXLKeFe7mupn
46
+ NYJROi2iC11+HuF79iAttMc32Cv6UOxixY/3ZV+LzpLnklFq98XORgwkIJL1HuvP
47
+ ha8yvb+W6JislZJL+HLFtidoxmI7Qm3ZyIV66W533DsGFimFJkz3y0GeHWuSVMbI
48
+ lfsCAwEAAaOCAU8wggFLMB0GA1UdDgQWBBR435GQX+7erPbFdevVTFVT7yRKtjAf
49
+ BgNVHSMEGDAWgBROIlQgGJXm427mD/r6uRLtBhePOTAOBgNVHQ8BAf8EBAMCAYYw
50
+ HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
51
+ AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
52
+ Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
53
+ Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
54
+ /WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
55
+ MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAoBs1eCLKakLtVRPFRjBIJ9LJ
56
+ L0s8ZWum8U8/1TMVkQMBn+CPb5xnCD0GSA6L/V0ZFrMNqBirrr5B241OesECvxIi
57
+ 98bZ90h9+q/X5eMyOD35f8YTaEMpdnQCnawIwiHx06/0BfiTj+b/XQih+mqt3ZXe
58
+ xNCJqKexdiB2IWGSKcgahPacWkk/BAQFisKIFYEqHzV974S3FAz/8LIfD58xnsEN
59
+ GfzyIDkH3JrwYZ8caPTf6ZX9M1GrISN8HnWTtdNCH2xEajRa/h9ZBXjUyFKQrGk2
60
+ n2hcLrfZSbynEC/pSw/ET7H5nWwckjmAJ1l9fcnbqkU/pf6uMQmnfl0JQjJNSg==
61
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEAp7m9ocHPmt+oXOV8EYPRgAznJNPpRUQMFj8ZKEyhdobnFQwE
3
+ jNlu+YlwJD2jjlkpKBrGwgUqU73VtZZkA6TMEmkD6ZOnGnkIt1wEK/ApuhMBaBty
4
+ o5VyYEA2JjEaxPgjH6+EpSeLBvpkjDxzjYBXDwQwfvYaDAvRcas/gPCFHvraSFSM
5
+ sWgtiZCOxT7VixsFGalZsd6sJ24vHaPOks6eTmSkHogVUiX74ag6qfavtkPtJLY7
6
+ 18tq7umut1fISgOUSzt13KUHz68jPn1+FP9K73hfaYKNCnfTar8d51YIJRySnpCN
7
+ bKedbjK7/s1uEK7Lg2Llsnm5kze0WhYhN5CAqQIDAQABAoIBADntueQjVzurYa/s
8
+ BqTZ/UKXskGS+y9UKESKuHqltOKGB0vKocuv0VdYM6Ygr9ubSc6zKNCcDhlsKGKW
9
+ NabYhS8anCJRP9ax1OPXYQ133kGJDORTDo4XMLCznMAmF5POC/uGmG6eMLNRSebx
10
+ fgtyNx9VmBZRk39zmXwD5GP5LlEbTQ70MB56DdpQPOe8UZgT3aITZTRhGxwk9Z7N
11
+ YdhJLVRyS3lufnLxBgj+VFMmqViBgWPfi/T73V1tg+6i/n+MHVPY8XprqiioO3yE
12
+ FPDe4+5AciimTg9QrlqF7ZmyRx9c0zdxs2aDewPXovp4fmyO91I81f/XbxwR4Hg+
13
+ WbHUZ60CgYEA4sHLxidVhQD6wZrbmbjY3zgHsAtpKqst+xiRD73Uo4UM5B7A3+bo
14
+ v5HJx/PX+Ax4O8PZz8ghGS+J8xXXAAHdnBetYT5YniOfkFw/XDl7y1IazY+74k5e
15
+ Wew+mdELKRJtW/3ylFDcsHMxy9aA+jNVm0m8hjMnHdhufPZhs6wdpAsCgYEAvVsR
16
+ Rizx710Hlon5/byYPgo+vjPxTHNH/5b4nLmYTNsDWzVO8LqVkPpT8XewfEAYSOpp
17
+ uAYfK2GJc36XFX/0sZJFwuChKapnuL2r2x1OLKqJjKK/f+5XUirRFh//bMpS/FsM
18
+ +0/DWnfYsw9dwgnH2JIuods1+8SL7uFWYBV5SpsCgYBoT8YxzX5lxOGVlmtW99Ws
19
+ OdYvgdBLNJveWprApw7eeiJH/m2zkkGXfrVYKjA7h2D3/UyBbQrszxWioXVaJ4GO
20
+ gMXdahTSCokom4b6Ied0zLxPu8Mug+abbzYNBEEiD7wHCXdCC0C6WwOZRX/nmR3U
21
+ ZcM36OghrqKFEcI4KQEpqQKBgQCRzus5T2io+cjbCbofwba1pyvzSIoZZXfef0FH
22
+ Zb66B7fI5v63beW38prrCFA1DSHmG+N2WfhsbjnqXmM2ogYpKkpfqptPOzGNVzhb
23
+ jHBjAprSWYv+lehVlDTWxaLpAc7vFamkZyI1qq2KDF4VCXUC9mXEKsmh6hIayxe4
24
+ +zAf2wKBgA8qx/b8IpSc/9KJATtpNwnSWkDhwzazU8rwHTE8QDsbmSurf2eBtC3e
25
+ 5Gki7XcXpVIroERRfy5jdKfZ0xb5SmBsqCxu3NTDLtwuV3PMqh5oSGi6fjzL6/dn
26
+ XNaHyu1jMd2g3AxoWVk6+41iuHEIJZ2UnJhrFXsIsWejmrni6vGT
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,16 @@
1
+ {
2
+ "headers": [
3
+ {
4
+ "source": "**/*",
5
+ "headers": [
6
+ {
7
+ "key": "Cross-Origin-Opener-Policy",
8
+ "value": "same-origin"
9
+ }, {
10
+ "key": "Cross-Origin-Embedder-Policy",
11
+ "value": "require-corp"
12
+ }
13
+ ]
14
+ }
15
+ ]
16
+ }
@@ -179,6 +179,7 @@ function parseArguments(requiredUsages = {},
179
179
  /**************************************************
180
180
  * jsview-test-project
181
181
  * ├── dist
182
+ * │   ├── assets
182
183
  * │   ├── debug
183
184
  * │   │   └── map
184
185
  * │   └── js
@@ -209,6 +210,7 @@ function getOptions(framework)
209
210
  options.modulesDir = path.resolve(options.projectDir, 'node_modules');
210
211
  options.jsviewDir = path.resolve(options.modulesDir, '@shijiu', 'jsview');
211
212
  options.jsviewDomDir = path.resolve(options.jsviewDir, 'dom');
213
+ options.jsviewDomBinDir = path.resolve(options.jsviewDomDir, 'bin');
212
214
  options.jsviewPatchesDir = path.resolve(options.jsviewDir, 'patches');
213
215
  options.jsviewPatchModulesDir = path.resolve(options.jsviewPatchesDir, 'node_modules');
214
216
  options.jsviewToolsDir = path.resolve(options.jsviewDir, 'tools');
@@ -241,6 +243,7 @@ function getOptions(framework)
241
243
  options.distJsvListFile = path.resolve(options.distDir, 'jsv-list.json');
242
244
  options.distJsvInfoFile = path.resolve(options.distDir, 'jsv-info.json');
243
245
  options.distJsIndexFile = path.resolve(options.distDir, 'index.html');
246
+ options.distAssetsDir = path.resolve(options.distDir, 'assets');
244
247
  options.distJsDir = path.resolve(options.distDir, 'js');
245
248
  options.distDebugDir = path.resolve(options.distDir, 'debug');
246
249
  options.distDebugMapDir = path.resolve(options.distDebugDir, 'map');
@@ -326,6 +329,18 @@ function symlinkSync(workDir, targetPath, toPath)
326
329
  fs.symlinkSync(relativePath, toPath, 'junction');
327
330
  }
328
331
 
332
+ function isCommandAvailable(command) {
333
+ const isWindows = process.platform === 'win32';
334
+ const cmd = isWindows ? 'where' : 'which';
335
+
336
+ const result = childProcess.spawnSync(cmd, [command], {
337
+ stdio: 'ignore',
338
+ shell: true
339
+ });
340
+
341
+ return result.status === 0;
342
+ }
343
+
329
344
  function isSymlinkSync(filePath)
330
345
  {
331
346
  const stats = fs.lstatSync(filePath);
@@ -363,6 +378,54 @@ function execCommandAsync(cmdline)
363
378
  });
364
379
  }
365
380
 
381
+ function execCommandPromise(cmdline)
382
+ {
383
+ let log = '';
384
+
385
+ const promise = new Promise((resolve, reject) => {
386
+ const child = childProcess.spawn(cmdline, null, { shell: true });
387
+ child.stdout.on('data', (data) => {
388
+ log += data;
389
+ });
390
+ child.stderr.on('data', (data) => {
391
+ log += data;
392
+ });
393
+ child.on('close', (code) => {
394
+ if (code !== 0) {
395
+ reject(log);
396
+ } else {
397
+ resolve(log);
398
+ }
399
+ });
400
+ });
401
+
402
+ return promise;
403
+ }
404
+
405
+ function execCommandWithLiveLog(cmdline)
406
+ {
407
+ Logger.Info('Run [' + cmdline + ']... ');
408
+ const promise = new Promise((resolve, reject) => {
409
+ const child = childProcess.spawn(cmdline, null, { shell: true });
410
+ child.stdout.on('data', (data) => {
411
+ process.stdout.write(data);
412
+ });
413
+ child.stderr.on('data', (data) => {
414
+ process.stderr.write(data);
415
+ });
416
+ child.on('close', (code) => {
417
+ if (code !== 0) {
418
+ process.exit(code);
419
+ }
420
+
421
+ resolve();
422
+ });
423
+ });
424
+
425
+ return promise;
426
+ }
427
+
428
+
366
429
  function checkNodeVersion(minMajorVersion = 16)
367
430
  {
368
431
  const versions = process.version.replace('v', '').split('.');
@@ -464,7 +527,7 @@ function downloadFileAsync(url, localPath, workDir)
464
527
 
465
528
  function unzipFile(zipFilePath, toDir, workDir)
466
529
  {
467
- var relativePath = path.relative(workDir, toDir);
530
+ let relativePath = path.relative(workDir, toDir);
468
531
  if(!relativePath) {
469
532
  relativePath = './'
470
533
  }
@@ -474,6 +537,21 @@ function unzipFile(zipFilePath, toDir, workDir)
474
537
  execCommand(cmdline);
475
538
  }
476
539
 
540
+ function getExportPrefix()
541
+ {
542
+ let exportPrefix = 'export';
543
+ if(process.platform == 'win32') {
544
+ exportPrefix = 'set'
545
+ }
546
+
547
+ return exportPrefix;
548
+ }
549
+
550
+ function getJsViewBurdenDefaultBaseUrl()
551
+ {
552
+ return 'https://cdn.release.qcast.cn/JsViewTest/wasm/resources';
553
+ }
554
+
477
555
  function getNpmRegistry()
478
556
  {
479
557
  return 'https://nexus.cluster.qcast.cn/repository/npm-public';
@@ -485,8 +563,8 @@ function getNetworkIpv4Addresses() {
485
563
  for (const devName in interfaces) {
486
564
  const iface = interfaces[devName];
487
565
 
488
- for (var idx = 0; idx < iface.length; idx++) {
489
- var alias = iface[idx];
566
+ for (let idx = 0; idx < iface.length; idx++) {
567
+ let alias = iface[idx];
490
568
  if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
491
569
  addresses.push(alias.address);
492
570
  }
@@ -504,9 +582,14 @@ export {
504
582
  downloadFileAsync,
505
583
  execCommand,
506
584
  execCommandAsync,
585
+ execCommandPromise,
586
+ execCommandWithLiveLog,
587
+ getExportPrefix,
588
+ getJsViewBurdenDefaultBaseUrl,
507
589
  getNetworkIpv4Addresses,
508
590
  getNpmRegistry,
509
591
  getOptions,
592
+ isCommandAvailable,
510
593
  isSymlinkSync,
511
594
  loadPackageObject,
512
595
  makeZip,