xshell 1.0.213 → 1.1.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.
package/Terminal.js CHANGED
@@ -10,7 +10,7 @@ import { WebLinksAddon } from '@xterm/addon-web-links';
10
10
  import { Model } from 'react-object-model';
11
11
  import { assert, defer, genid } from "./utils.browser.js";
12
12
  export function Terminal({ font }) {
13
- let rterminal = useRef();
13
+ let rterminal = useRef(undefined);
14
14
  useEffect(() => {
15
15
  (async () => {
16
16
  await document.fonts.ready;
package/builder.d.ts CHANGED
@@ -6,10 +6,14 @@ import { Lock } from './utils.ts';
6
6
  export interface Dependency {
7
7
  /** 项目隐含的子依赖 */
8
8
  dependencies?: string[];
9
- /** 开发环境依赖的 .js 文件 */
10
- devs?: string[];
11
- /** 生产环境依赖的 .js 文件 */
12
- productions?: string[];
9
+ /** 开发环境依赖的 .js 文件
10
+ string 类型时为 node_modules 下的相对路径,输出到 {fpd_out}vendors/ 同样的相对路径
11
+ AssetOption 类型时见 {@link AssetOption} */
12
+ devs?: (string | AssetOption)[];
13
+ /** 生产环境依赖的 .js 文件
14
+ string 类型时为 node_modules 下的相对路径,输出到 {fpd_out}vendors/ 同样的相对路径
15
+ AssetOption 类型时见 {@link AssetOption} */
16
+ productions?: (string | AssetOption)[];
13
17
  /** 需要直接复制到输出目录的资源 */
14
18
  assets?: {
15
19
  productions: string[];
@@ -17,11 +21,11 @@ export interface Dependency {
17
21
  };
18
22
  /** .map 代码映射 */
19
23
  maps?: {
20
- productions?: string[];
21
- devs?: string[];
24
+ productions?: (string | AssetOption)[];
25
+ devs?: (string | AssetOption)[];
22
26
  };
23
27
  }
24
- type DependencyId = 'react' | 'react-dom' | 'lodash' | 'jquery' | 'xterm' | 'swiper' | 'dayjs' | 'antd' | 'antd-icons' | 'vscode-oniguruma' | 'antd-plots' | 'gridstack' | 'quill' | 'monaco' | 'echarts';
28
+ type DependencyId = 'react' | 'lodash' | 'jquery' | 'xterm' | 'swiper' | 'dayjs' | 'antd' | 'antd-icons' | 'vscode-oniguruma' | 'antd-plots' | 'gridstack' | 'quill' | 'monaco' | 'echarts';
25
29
  export interface HtmlOptions {
26
30
  title: string;
27
31
  /** `index.js` 也可以设置 entries 中的其他项, 应填写相对于 fpd_out 的路径 */
@@ -45,9 +49,9 @@ export interface HtmlOptions {
45
49
  notice?: boolean;
46
50
  }
47
51
  interface AssetOption {
48
- /** 相对 fpd_root 的路径 */
52
+ /** 相对 fpd_root 的路径,或者绝对路径 */
49
53
  src: string;
50
- /** 默认为 {fpd_out}/ 加上 src 中的路径 */
54
+ /** 相对 fpd_out 的路径,或者绝对路径,默认等于 src 的值 */
51
55
  out?: string;
52
56
  }
53
57
  type Assets = {
@@ -137,18 +141,19 @@ export declare class Bundler {
137
141
  close(): Promise<void>;
138
142
  build_all(print?: boolean): Promise<void>;
139
143
  build_all_and_close(print?: boolean): Promise<void>;
144
+ build_and_close(print?: boolean): Promise<void>;
140
145
  build_htmls(print?: {
141
146
  info: boolean;
142
147
  files: boolean;
143
148
  }): Promise<void>;
144
- resolve_dependencies(dependency_ids?: DependencyId[], resolveds?: Set<DependencyId>): Set<DependencyId>;
149
+ resolve_dependencies(dependency_ids: DependencyId[], resolveds?: Set<DependencyId>): Set<DependencyId>;
145
150
  /** 解析依赖的文件
146
151
  - dependencies: 依赖 id
147
152
  - assets: false 时只包括在 script 标签加载的文件; true 时包括 assets, maps 等 */
148
- resolve_dependency_files(_dependencies: DependencyId[], assets: boolean, { production, source_map }?: {
153
+ resolve_dependency_assets(_dependencies: DependencyId[], assets: boolean, { production, source_map }?: {
149
154
  production?: boolean;
150
155
  source_map?: boolean;
151
- }): string[];
156
+ }): (string | AssetOption)[];
152
157
  copy_files({ dependencies, production, assets, fpd_root, fpd_out, print }?: {
153
158
  dependencies?: DependencyId[];
154
159
  production?: boolean;
package/builder.js CHANGED
@@ -15,15 +15,23 @@ const monaco_files = [
15
15
  // 'language/typescript/tsMode.js',
16
16
  // 'language/typescript/tsWorker.js',
17
17
  ];
18
+ function get_react_js(production, src, map) {
19
+ return `${src ? import.meta.dirname.fpd : 'vendors/react/'}react.${production ? 'production' : 'development'}.js${map ? '.map' : ''}`;
20
+ }
21
+ function get_react_asset(production, map) {
22
+ return {
23
+ src: get_react_js(production, true, map),
24
+ out: get_react_js(production, false, map),
25
+ };
26
+ }
18
27
  const dependencies = {
19
28
  react: {
20
- productions: ['react/umd/react.production.min.js'],
21
- devs: ['react/umd/react.development.js'],
22
- },
23
- 'react-dom': {
24
- dependencies: ['react'],
25
- productions: ['react-dom/umd/react-dom.production.min.js'],
26
- devs: ['react-dom/umd/react-dom.development.js'],
29
+ productions: [get_react_asset(true, false)],
30
+ devs: [get_react_asset(false, false)],
31
+ maps: {
32
+ productions: [get_react_asset(true, true)],
33
+ devs: [get_react_asset(false, true)],
34
+ }
27
35
  },
28
36
  lodash: {
29
37
  productions: ['lodash/lodash.min.js'],
@@ -45,7 +53,7 @@ const dependencies = {
45
53
  productions: ['dayjs/dayjs.min.js'],
46
54
  },
47
55
  antd: {
48
- dependencies: ['dayjs', 'react', 'react-dom'],
56
+ dependencies: ['dayjs', 'react'],
49
57
  productions: ['antd/dist/antd.min.js'],
50
58
  devs: ['antd/dist/antd.js'],
51
59
  maps: {
@@ -104,6 +112,16 @@ const dependencies = {
104
112
  }
105
113
  }
106
114
  };
115
+ function get_asset_out(asset) {
116
+ return typeof asset === 'string'
117
+ ? asset
118
+ : asset.out || asset.src;
119
+ }
120
+ function get_vendor_asset_out(asset) {
121
+ return typeof asset === 'string'
122
+ ? `vendors/${asset}`
123
+ : asset.out || asset.src;
124
+ }
107
125
  export class Bundler {
108
126
  name;
109
127
  fpd_root;
@@ -214,7 +232,9 @@ export class Bundler {
214
232
  // 取全局变量 window.React 的值作为 import { useState } from 'react' 中 { ... } 这部分的结果,再解构里面的 useState 属性
215
233
  externals: filter_values({
216
234
  react: 'React',
235
+ 'react/jsx-runtime': 'ReactJSX',
217
236
  'react-dom': 'ReactDOM',
237
+ 'react-dom/client': 'ReactDOMClient',
218
238
  jquery: '$',
219
239
  ...target === 'web' ? {
220
240
  lodash: '_',
@@ -470,17 +490,17 @@ export class Bundler {
470
490
  }
471
491
  async build_all_and_close(print = true) {
472
492
  await Promise.all([
473
- (async () => {
474
- await this.build(print);
475
- await this.close();
476
- })(),
493
+ this.build_and_close(print),
477
494
  this.copy_files({ print: { info: print, files: false } }),
478
495
  this.target === 'web' && this.htmls && this.build_htmls({ info: print, files: false })
479
496
  ]);
480
497
  }
498
+ async build_and_close(print = true) {
499
+ await this.build(print);
500
+ await this.close();
501
+ }
481
502
  async build_htmls(print = { info: true, files: false }) {
482
- await Promise.all(Object.entries(this.htmls).map(async ([fp_html, { entry = 'index.js', device_viewport: device_width = false, icon, manifest, dependencies: _dependencies = this.dependencies, title, scripts, mscripts, notice = false, heads, }]) => {
483
- const get = (asset) => typeof asset === 'string' ? asset : asset.out;
503
+ await Promise.all(Object.entries(this.htmls).map(async ([fp_html, { entry = 'index.js', device_viewport: device_width = false, icon, manifest, dependencies: _dependencies = [], title, scripts, mscripts, notice = false, heads, }]) => {
484
504
  const html_template = '<!doctype html>\n' +
485
505
  '<html>\n' +
486
506
  ' <head>\n' +
@@ -488,21 +508,28 @@ export class Bundler {
488
508
  " <meta charset='utf-8' />\n" +
489
509
  (heads ? heads.map(head => ` ${head}`).join_lines() : '') +
490
510
  (device_width ? " <meta name='viewport' content='width=device-width, initial-scale=1.0' />\n" : '') +
491
- (icon ? ` <link rel='icon' href='{root}${get(icon)}' />\n` : '') +
511
+ (icon ? ` <link rel='icon' href='{root}${get_asset_out(icon)}' />\n` : '') +
492
512
  (manifest ? ` <link rel='manifest' href='{root}${manifest}' />\n` : '') +
493
- this.resolve_dependency_files(_dependencies, false, { production: this.production }).map(fp => ` <script src='{root}vendors/${fp}' defer></script>`).join_lines() +
494
- (scripts?.before ? scripts.before.map(asset => ` <script src='{root}${get(asset)}' defer></script>`).join_lines() : '') +
495
- (mscripts ? mscripts.map(mscript => ` <script src='{root}${get(mscript)}' type='module'></script>`).join_lines() : '') +
513
+ this.resolve_dependency_assets(_dependencies, false, { production: this.production }).map(asset => ` <script src='{root}${get_vendor_asset_out(asset)}' defer></script>`).join_lines() +
514
+ (scripts?.before
515
+ ? scripts.before.map(asset => ` <script src='{root}${get_asset_out(asset)}' defer></script>`).join_lines()
516
+ : '') +
517
+ (mscripts
518
+ ? mscripts.map(mscript => ` <script src='{root}${get_asset_out(mscript)}' type='module'></script>`).join_lines()
519
+ : '') +
496
520
  ` <script src='{root}${entry}' type='module'></script>\n` +
497
- (scripts?.after ? scripts.after.map(asset => ` <script src='{root}${get(asset)}' defer></script>`).join_lines() : '') +
521
+ (scripts?.after
522
+ ? scripts.after.map(asset => ` <script src='{root}${get_asset_out(asset)}' defer></script>`).join_lines()
523
+ : '') +
498
524
  ' </head>\n' +
499
525
  ' <body>\n' +
500
- " <div class='root'>\n" +
501
- (notice ?
502
- ' <h2>正在加载 ··· (最多需要十秒钟)</h2>\n' +
503
- ' <h2>如果一直停留在此页面请按 f12 或右键 > 检查,打开开发者工具查看底部控制台报错,并尝试更换浏览器或将浏览器更新到最新版本,同时检查网络连接情况</h2>\n'
526
+ " <div class='root'>" +
527
+ (notice
528
+ ? '\n <h2>正在加载 ··· (最多需要十秒钟)</h2>\n' +
529
+ ' <h2>如果一直停留在此页面请按 f12 或右键 > 检查,打开开发者工具查看底部控制台报错,并尝试更换浏览器或将浏览器更新到最新版本,同时检查网络连接情况</h2>\n' +
530
+ ' '
504
531
  : '') +
505
- ' </div>\n' +
532
+ '</div>\n' +
506
533
  ' </body>\n' +
507
534
  '</html>\n';
508
535
  await Promise.all([
@@ -515,10 +542,10 @@ export class Bundler {
515
542
  if (print.files)
516
543
  console.log(`${this.name} 的所有 html 页面构建完成`);
517
544
  }
518
- resolve_dependencies(dependency_ids = this.dependencies, resolveds = new Set()) {
545
+ resolve_dependencies(dependency_ids, resolveds = new Set()) {
519
546
  dependency_ids.forEach(id => {
520
547
  if (!resolveds.has(id)) {
521
- const dependency_ids_ = dependencies[id].dependencies;
548
+ const { dependencies: dependency_ids_ } = dependencies[id];
522
549
  if (dependency_ids_)
523
550
  this.resolve_dependencies(dependency_ids_, resolveds);
524
551
  resolveds.add(id);
@@ -529,7 +556,7 @@ export class Bundler {
529
556
  /** 解析依赖的文件
530
557
  - dependencies: 依赖 id
531
558
  - assets: false 时只包括在 script 标签加载的文件; true 时包括 assets, maps 等 */
532
- resolve_dependency_files(_dependencies, assets, { production = this.production, source_map = this.source_map } = {}) {
559
+ resolve_dependency_assets(_dependencies, assets, { production = this.production, source_map = this.source_map } = {}) {
533
560
  return this.resolve_dependencies(_dependencies).map(id => {
534
561
  const dependency = dependencies[id];
535
562
  const { assets: _assets, maps } = dependency;
@@ -544,7 +571,7 @@ export class Bundler {
544
571
  if (print.files)
545
572
  console.log(`复制 ${this.name} 的依赖文件到 ${this.fpd_out}`);
546
573
  if (dependencies.length)
547
- await fmkdir(`${fpd_out}vendors/`, { print: false });
574
+ await fmkdir(`${fpd_out}vendors/`, noprint);
548
575
  // 输出路径 -> 原路径,用来保证只复制一次且是同样的映射
549
576
  let records = new Map();
550
577
  const { name } = this;
@@ -552,16 +579,17 @@ export class Bundler {
552
579
  let src, out;
553
580
  if (typeof asset === 'string')
554
581
  src = out = asset;
555
- else
582
+ else {
556
583
  ({ src, out } = asset);
584
+ out ??= src;
585
+ }
557
586
  await fcopy_record(path.resolve_with_slash(fpd_root, src), `${fpd_out}${out}`);
558
587
  }
588
+ /** 保证同样的输出资源只被写入一次 */
559
589
  async function fcopy_record(fp_src, fp_out) {
560
- // 保证同样的输出资源只被写入一次
561
590
  const fp_src_old = records.get(fp_out);
562
591
  if (fp_src_old) {
563
- if (fp_src_old === fp_src) { }
564
- else
592
+ if (fp_src_old !== fp_src)
565
593
  throw new Error(`${name} 复制项目资源冲突, ${fp_src_old} 和 ${fp_src} 均复制到 ${fp_out}`);
566
594
  }
567
595
  else {
@@ -570,25 +598,29 @@ export class Bundler {
570
598
  }
571
599
  }
572
600
  await Promise.all([
573
- ...this.resolve_dependency_files(dependencies, true, { production })
574
- .map(async (fp) => fcopy_record(`${fpd_root}node_modules/${fp}`, `${fpd_out}vendors/${fp}`)),
601
+ ...this.resolve_dependency_assets(dependencies, true, { production })
602
+ .map(async (asset) => typeof asset === 'string'
603
+ ? fcopy_record(`${fpd_root}node_modules/${asset}`, `${fpd_out}vendors/${asset}`)
604
+ : fcopy_record(path.resolve_with_slash(fpd_root, asset.src), path.resolve_with_slash(fpd_out, asset.out || asset.src))),
575
605
  ...this.resolve_config(assets, production)
576
606
  .map(fcopy_asset),
577
- ...this.htmls ? Object.entries(this.htmls).map(async ([fp_html, { icon, manifest, scripts, mscripts }]) => Promise.all([
578
- icon,
579
- manifest,
580
- ...(scripts?.before || []),
581
- ...(scripts?.after || []),
582
- ...(mscripts || [])
583
- ].filter(not_empty)
584
- .map(fcopy_asset))) : []
607
+ ...this.htmls
608
+ ? Object.values(this.htmls).map(async ({ icon, manifest, scripts, mscripts }) => Promise.all([
609
+ icon,
610
+ manifest,
611
+ ...(scripts?.before || []),
612
+ ...(scripts?.after || []),
613
+ ...(mscripts || [])
614
+ ].filter(not_empty)
615
+ .map(fcopy_asset))) : []
585
616
  ]);
586
617
  }
587
618
  /** 为空时返回空数组 */
588
619
  resolve_config(config, production) {
589
620
  return config
590
- ? (production ? config.productions : config.devs || config.productions) ||
591
- []
621
+ ? (production
622
+ ? config.productions
623
+ : config.devs || config.productions) || []
592
624
  : [];
593
625
  }
594
626
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xshell",
3
- "version": "1.0.213",
3
+ "version": "1.1.000",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -51,9 +51,9 @@
51
51
  "dependencies": {
52
52
  "@babel/core": "^7.26.0",
53
53
  "@babel/parser": "^7.26.3",
54
- "@babel/traverse": "^7.26.3",
54
+ "@babel/traverse": "^7.26.4",
55
55
  "@koa/cors": "^5.0.0",
56
- "@stylistic/eslint-plugin": "^2.11.0",
56
+ "@stylistic/eslint-plugin": "^2.12.0",
57
57
  "@svgr/webpack": "^8.1.0",
58
58
  "@types/sass-loader": "^8.0.9",
59
59
  "@types/ws": "^8.5.13",
@@ -66,7 +66,7 @@
66
66
  "@xterm/xterm": "^5.5.0",
67
67
  "ali-oss": "^6.22.0",
68
68
  "archiver": "^7.0.1",
69
- "byte-size": "^9.0.0",
69
+ "byte-size": "^9.0.1",
70
70
  "chalk": "^5.3.0",
71
71
  "chardet": "^2.0.0",
72
72
  "cli-table3": "^0.6.5",
@@ -80,7 +80,7 @@
80
80
  "eslint-plugin-react": "^7.37.2",
81
81
  "gulp-sort": "^2.0.0",
82
82
  "hash-string": "^1.0.0",
83
- "https-proxy-agent": "^7.0.5",
83
+ "https-proxy-agent": "^7.0.6",
84
84
  "i18next": "^24.0.5",
85
85
  "i18next-scanner": "^4.6.0",
86
86
  "koa": "^2.15.3",
@@ -90,9 +90,9 @@
90
90
  "map-stream": "^0.0.7",
91
91
  "mime-types": "^2.1.35",
92
92
  "ora": "^8.1.1",
93
- "react": "^18.3.1",
93
+ "react": "^19.0.0",
94
94
  "react-i18next": "^15.1.3",
95
- "react-object-model": "^1.2.18",
95
+ "react-object-model": "^1.2.20",
96
96
  "resolve-path": "^1.4.0",
97
97
  "sass": "^1.82.0",
98
98
  "sass-loader": "^16.0.4",
@@ -127,7 +127,7 @@
127
127
  "@types/lodash": "^4.17.13",
128
128
  "@types/mime-types": "^2.1.4",
129
129
  "@types/node": "^22.10.1",
130
- "@types/react": "^18.3.13",
130
+ "@types/react": "^19.0.1",
131
131
  "@types/through2": "^2.0.41",
132
132
  "@types/tough-cookie": "^4.0.5",
133
133
  "@types/ua-parser-js": "^0.7.39",