clickgo 3.1.13 → 3.1.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/README.md CHANGED
@@ -28,7 +28,7 @@ Load the module loader first, and then load it using the module loader.
28
28
  **index.html**
29
29
 
30
30
  ```html
31
- <script src="https://cdn.jsdelivr.net/npm/@litert/loader@3.4.9/dist/loader.min.js?path=index&npm={'clickgo':'3.1.13'}"></script>
31
+ <script src="https://cdn.jsdelivr.net/npm/@litert/loader@3.4.9/dist/loader.min.js?path=index&npm={'clickgo':'3.1.14'}"></script>
32
32
  ```
33
33
 
34
34
  **index.js**
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/lib/core.js CHANGED
@@ -449,9 +449,19 @@ function trigger(name, taskId = 0, formId = 0, param1 = '', param2 = '') {
449
449
  exports.trigger = trigger;
450
450
  function readApp(blob) {
451
451
  return __awaiter(this, void 0, void 0, function* () {
452
- const iconLength = parseInt(yield blob.slice(0, 7).text());
453
- const icon = yield tool.blob2DataUrl(blob.slice(7, 7 + iconLength));
454
- const z = yield zip.get(blob.slice(7 + iconLength));
452
+ const head = yield tool.blob2Text(blob.slice(0, 5));
453
+ if (head !== '-CGA-') {
454
+ return false;
455
+ }
456
+ const iconLength = parseInt(yield blob.slice(21, 28).text());
457
+ if (Number.isNaN(iconLength)) {
458
+ return false;
459
+ }
460
+ const icon = iconLength ? yield tool.blob2DataUrl(blob.slice(28, 28 + iconLength)) : '';
461
+ const nb = new Blob([blob.slice(5, 21), blob.slice(28 + iconLength)], {
462
+ 'type': blob.type
463
+ });
464
+ const z = yield zip.get(nb);
455
465
  if (!z) {
456
466
  return false;
457
467
  }
@@ -502,6 +512,17 @@ function fetchApp(url, opt = {}, taskId) {
502
512
  return null;
503
513
  }
504
514
  }
515
+ if (!taskId &&
516
+ !url.startsWith('/clickgo/') &&
517
+ !url.startsWith('/storage/') &&
518
+ !url.startsWith('/mounted/') &&
519
+ !url.startsWith('/package/') &&
520
+ !url.startsWith('/current/') &&
521
+ !url.startsWith('http:') &&
522
+ !url.startsWith('https:') &&
523
+ !url.startsWith('file:')) {
524
+ url = tool.urlResolve(location.href, url);
525
+ }
505
526
  if (cga) {
506
527
  try {
507
528
  const blob = yield fs.getContent(url, {
package/dist/lib/core.ts CHANGED
@@ -533,9 +533,19 @@ export function trigger(name: types.TGlobalEvent, taskId: number | string | bool
533
533
  * @param blob blob 对象
534
534
  */
535
535
  export async function readApp(blob: Blob): Promise<false | types.IApp> {
536
- const iconLength = parseInt(await blob.slice(0, 7).text());
537
- const icon = await tool.blob2DataUrl(blob.slice(7, 7 + iconLength));
538
- const z = await zip.get(blob.slice(7 + iconLength));
536
+ const head = await tool.blob2Text(blob.slice(0, 5));
537
+ if (head !== '-CGA-') {
538
+ return false;
539
+ }
540
+ const iconLength = parseInt(await blob.slice(21, 28).text());
541
+ if (Number.isNaN(iconLength)) {
542
+ return false;
543
+ }
544
+ const icon = iconLength ? await tool.blob2DataUrl(blob.slice(28, 28 + iconLength)) : '';
545
+ const nb = new Blob([blob.slice(5, 21), blob.slice(28 + iconLength)], {
546
+ 'type': blob.type
547
+ });
548
+ const z = await zip.get(nb);
539
549
  if (!z) {
540
550
  return false;
541
551
  }
@@ -598,6 +608,19 @@ export async function fetchApp(
598
608
  return null;
599
609
  }
600
610
  }
611
+ // --- 非 taskId 模式下 current 以 location 为准 ---
612
+ if (!taskId &&
613
+ !url.startsWith('/clickgo/') &&
614
+ !url.startsWith('/storage/') &&
615
+ !url.startsWith('/mounted/') &&
616
+ !url.startsWith('/package/') &&
617
+ !url.startsWith('/current/') &&
618
+ !url.startsWith('http:') &&
619
+ !url.startsWith('https:') &&
620
+ !url.startsWith('file:')
621
+ ) {
622
+ url = tool.urlResolve(location.href, url);
623
+ }
601
624
  // --- 如果是 cga 文件,直接读取并交给 readApp 函数处理 ---
602
625
  if (cga) {
603
626
  try {
package/dist/lib/task.js CHANGED
@@ -193,41 +193,50 @@ function getList() {
193
193
  }
194
194
  exports.getList = getList;
195
195
  function run(url, opt = {}, ntid) {
196
- var _a, _b, _c, _d, _e;
196
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
197
197
  return __awaiter(this, void 0, void 0, function* () {
198
- if (!url.endsWith('/') && !url.endsWith('.cga')) {
199
- return 0;
200
- }
201
- let icon = __dirname + '/../icon.png';
202
- if (opt.icon) {
203
- icon = opt.icon;
204
- }
205
- if (opt.notify === undefined) {
206
- opt.notify = true;
198
+ let app = null;
199
+ if (typeof url === 'string') {
200
+ if (!url.endsWith('/') && !url.endsWith('.cga')) {
201
+ return 0;
202
+ }
203
+ let icon = __dirname + '/../icon.png';
204
+ if (opt.icon) {
205
+ icon = opt.icon;
206
+ }
207
+ if (opt.notify === undefined) {
208
+ opt.notify = true;
209
+ }
210
+ const notifyId = opt.notify ? form.notify({
211
+ 'title': (_b = (_a = localeData[core.config.locale]) === null || _a === void 0 ? void 0 : _a.loading) !== null && _b !== void 0 ? _b : localeData['en'].loading,
212
+ 'content': url,
213
+ 'icon': icon,
214
+ 'timeout': 0,
215
+ 'progress': true
216
+ }) : undefined;
217
+ if (!ntid &&
218
+ !url.startsWith('/clickgo/') &&
219
+ !url.startsWith('/storage/') &&
220
+ !url.startsWith('/mounted/') &&
221
+ !url.startsWith('/package/') &&
222
+ !url.startsWith('/current/')) {
223
+ url = tool.urlResolve(location.href, url);
224
+ }
225
+ app = yield core.fetchApp(url, {
226
+ 'notifyId': notifyId,
227
+ 'progress': opt.progress
228
+ }, ntid);
229
+ if (notifyId) {
230
+ setTimeout(function () {
231
+ form.hideNotify(notifyId);
232
+ }, 2000);
233
+ }
207
234
  }
208
- const notifyId = opt.notify ? form.notify({
209
- 'title': (_b = (_a = localeData[core.config.locale]) === null || _a === void 0 ? void 0 : _a.loading) !== null && _b !== void 0 ? _b : localeData['en'].loading,
210
- 'content': url,
211
- 'icon': icon,
212
- 'timeout': 0,
213
- 'progress': true
214
- }) : undefined;
215
- if (!ntid &&
216
- !url.startsWith('/clickgo/') &&
217
- !url.startsWith('/storage/') &&
218
- !url.startsWith('/mounted/') &&
219
- !url.startsWith('/package/') &&
220
- !url.startsWith('/current/')) {
221
- url = tool.urlResolve(location.href, url);
235
+ else if (url.type !== 'app') {
236
+ return -1;
222
237
  }
223
- const app = yield core.fetchApp(url, {
224
- 'notifyId': notifyId,
225
- 'progress': opt.progress
226
- }, ntid);
227
- if (notifyId) {
228
- setTimeout(function () {
229
- form.hideNotify(notifyId);
230
- }, 2000);
238
+ else {
239
+ app = url;
231
240
  }
232
241
  if (!app) {
233
242
  return -1;
@@ -966,7 +975,7 @@ function run(url, opt = {}, ntid) {
966
975
  return code;
967
976
  };
968
977
  app.files['/invoke/clickgo.js'] = `module.exports = invokeClickgo;`;
969
- const path = url;
978
+ const path = (_c = opt.path) !== null && _c !== void 0 ? _c : ((typeof url === 'string') ? url : '/runtime/' + tool.random(8, tool.RANDOM_LUN) + '.cga');
970
979
  const lio = path.endsWith('.cga') ? path.lastIndexOf('/') : path.slice(0, -1).lastIndexOf('/');
971
980
  const current = path.slice(0, lio);
972
981
  exports.list[taskId] = {
@@ -981,7 +990,7 @@ function run(url, opt = {}, ntid) {
981
990
  'current': current,
982
991
  'runtime': clickgo.vue.reactive({
983
992
  'dialogFormIds': [],
984
- 'permissions': (_c = opt.permissions) !== null && _c !== void 0 ? _c : []
993
+ 'permissions': (_d = opt.permissions) !== null && _d !== void 0 ? _d : []
985
994
  }),
986
995
  'forms': {},
987
996
  'controls': {},
@@ -994,6 +1003,7 @@ function run(url, opt = {}, ntid) {
994
1003
  if (!path.endsWith('.json')) {
995
1004
  path += '.json';
996
1005
  }
1006
+ yield ((_e = opt.initProgress) === null || _e === void 0 ? void 0 : _e.call(opt, 'Load local ' + path + ' ...'));
997
1007
  const lcontent = yield fs.getContent(path, {
998
1008
  'encoding': 'utf8'
999
1009
  }, taskId);
@@ -1004,7 +1014,7 @@ function run(url, opt = {}, ntid) {
1004
1014
  const data = JSON.parse(lcontent);
1005
1015
  loadLocaleData(locale, data, '', taskId);
1006
1016
  }
1007
- catch (_f) {
1017
+ catch (_p) {
1008
1018
  }
1009
1019
  }
1010
1020
  }
@@ -1033,16 +1043,18 @@ function run(url, opt = {}, ntid) {
1033
1043
  return -3;
1034
1044
  }
1035
1045
  dom.createToStyleList(taskId);
1046
+ yield ((_f = opt.initProgress) === null || _f === void 0 ? void 0 : _f.call(opt, 'Control initialization ...'));
1036
1047
  const r = yield control.init(taskId, invoke);
1037
1048
  if (r < 0) {
1038
1049
  dom.removeFromStyleList(taskId);
1039
1050
  delete exports.list[taskId];
1040
1051
  return -400 + r;
1041
1052
  }
1042
- if ((_d = app.config.themes) === null || _d === void 0 ? void 0 : _d.length) {
1053
+ if ((_g = app.config.themes) === null || _g === void 0 ? void 0 : _g.length) {
1043
1054
  for (let path of app.config.themes) {
1044
1055
  path += '.cgt';
1045
1056
  path = tool.urlResolve('/', path);
1057
+ yield ((_h = opt.initProgress) === null || _h === void 0 ? void 0 : _h.call(opt, 'Load theme ' + path + ' ...'));
1046
1058
  const file = yield fs.getContent(path, undefined, taskId);
1047
1059
  if (file && typeof file !== 'string') {
1048
1060
  const th = yield theme.read(file);
@@ -1054,6 +1066,7 @@ function run(url, opt = {}, ntid) {
1054
1066
  }
1055
1067
  else {
1056
1068
  if (theme.global) {
1069
+ yield ((_j = opt.initProgress) === null || _j === void 0 ? void 0 : _j.call(opt, 'Load global theme ...'));
1057
1070
  yield theme.load(undefined, taskId);
1058
1071
  }
1059
1072
  }
@@ -1063,16 +1076,19 @@ function run(url, opt = {}, ntid) {
1063
1076
  }, taskId);
1064
1077
  if (style) {
1065
1078
  const r = tool.stylePrepend(style, 'cg-task' + taskId.toString() + '_');
1079
+ yield ((_k = opt.initProgress) === null || _k === void 0 ? void 0 : _k.call(opt, 'Style initialization ...'));
1066
1080
  dom.pushStyle(taskId, yield tool.styleUrl2DataUrl(app.config.style, r.style, app.files));
1067
1081
  }
1068
1082
  }
1069
1083
  core.trigger('taskStarted', taskId);
1070
1084
  if (app.config.permissions) {
1085
+ yield ((_l = opt.initProgress) === null || _l === void 0 ? void 0 : _l.call(opt, 'Style initialization ...'));
1071
1086
  yield checkPermission(app.config.permissions, true, undefined, taskId);
1072
1087
  }
1073
1088
  const appCls = new expo.default();
1074
1089
  exports.list[taskId].class = appCls;
1075
- yield appCls.main((_e = opt.data) !== null && _e !== void 0 ? _e : {});
1090
+ yield ((_m = opt.initProgress) === null || _m === void 0 ? void 0 : _m.call(opt, 'Starting ...'));
1091
+ yield appCls.main((_o = opt.data) !== null && _o !== void 0 ? _o : {});
1076
1092
  return taskId;
1077
1093
  });
1078
1094
  }
package/dist/lib/task.ts CHANGED
@@ -227,50 +227,59 @@ export function getList(): Record<string, types.ITaskInfo> {
227
227
 
228
228
  /**
229
229
  * --- 运行一个应用,cga 直接文件全部正常加载,url 则静态文件需要去 config 里加载 ---
230
- * @param url app 路径(以 / 为结尾的路径或以 .cga 结尾的文件)
230
+ * @param url app 路径(以 / 为结尾的路径或以 .cga 结尾的文件),或 APP 包对象
231
231
  * @param opt 选项
232
232
  * @param ntid App 模式下无效
233
233
  */
234
- export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: number): Promise<number> {
235
- // --- 检测 url 是否合法 ---
236
- if (!url.endsWith('/') && !url.endsWith('.cga')) {
237
- return 0;
234
+ export async function run(url: string | types.IApp, opt: types.ITaskRunOptions = {}, ntid?: number): Promise<number> {
235
+ let app: types.IApp | null = null;
236
+ if (typeof url === 'string') {
237
+ // --- 检测 url 是否合法 ---
238
+ if (!url.endsWith('/') && !url.endsWith('.cga')) {
239
+ return 0;
240
+ }
241
+ /** --- 要显示的应用图标 --- */
242
+ let icon = __dirname + '/../icon.png';
243
+ if (opt.icon) {
244
+ icon = opt.icon;
245
+ }
246
+ if (opt.notify === undefined) {
247
+ opt.notify = true;
248
+ }
249
+ const notifyId: number | undefined = opt.notify ? form.notify({
250
+ 'title': localeData[core.config.locale]?.loading ?? localeData['en'].loading,
251
+ 'content': url,
252
+ 'icon': icon,
253
+ 'timeout': 0,
254
+ 'progress': true
255
+ }) : undefined;
256
+ // --- 非 ntid 模式下 current 以 location 为准 ---
257
+ if (!ntid &&
258
+ !url.startsWith('/clickgo/') &&
259
+ !url.startsWith('/storage/') &&
260
+ !url.startsWith('/mounted/') &&
261
+ !url.startsWith('/package/') &&
262
+ !url.startsWith('/current/')
263
+ ) {
264
+ url = tool.urlResolve(location.href, url);
265
+ }
266
+ // --- 获取并加载 app 对象 ---
267
+ app = await core.fetchApp(url, {
268
+ 'notifyId': notifyId,
269
+ 'progress': opt.progress
270
+ }, ntid);
271
+ // --- 无论是否成功,都可以先隐藏 notify 了 ---
272
+ if (notifyId) {
273
+ setTimeout(function(): void {
274
+ form.hideNotify(notifyId);
275
+ }, 2000);
276
+ }
238
277
  }
239
- /** --- 要显示的应用图标 --- */
240
- let icon = __dirname + '/../icon.png';
241
- if (opt.icon) {
242
- icon = opt.icon;
243
- }
244
- if (opt.notify === undefined) {
245
- opt.notify = true;
246
- }
247
- const notifyId: number | undefined = opt.notify ? form.notify({
248
- 'title': localeData[core.config.locale]?.loading ?? localeData['en'].loading,
249
- 'content': url,
250
- 'icon': icon,
251
- 'timeout': 0,
252
- 'progress': true
253
- }) : undefined;
254
- // --- 非 ntid 模式下 current 以 location 为准 ---
255
- if (!ntid &&
256
- !url.startsWith('/clickgo/') &&
257
- !url.startsWith('/storage/') &&
258
- !url.startsWith('/mounted/') &&
259
- !url.startsWith('/package/') &&
260
- !url.startsWith('/current/')
261
- ) {
262
- url = tool.urlResolve(location.href, url);
263
- }
264
- // --- 获取并加载 app 对象 ---
265
- const app = await core.fetchApp(url, {
266
- 'notifyId': notifyId,
267
- 'progress': opt.progress
268
- }, ntid);
269
- // --- 无论是否成功,都可以先隐藏 notify 了 ---
270
- if (notifyId) {
271
- setTimeout(function(): void {
272
- form.hideNotify(notifyId);
273
- }, 2000);
278
+ else if (url.type !== 'app') {
279
+ return -1;
280
+ }
281
+ else {
282
+ app = url;
274
283
  }
275
284
  if (!app) {
276
285
  return -1;
@@ -1076,7 +1085,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1076
1085
  };
1077
1086
  app.files['/invoke/clickgo.js'] = `module.exports = invokeClickgo;`;
1078
1087
  /** --- .cga 文件,或者不含 / 结尾的路径 --- */
1079
- const path = url;
1088
+ const path = opt.path ?? ((typeof url === 'string') ? url : '/runtime/' + tool.random(8, tool.RANDOM_LUN) + '.cga');
1080
1089
  const lio = path.endsWith('.cga') ? path.lastIndexOf('/') : path.slice(0, -1).lastIndexOf('/');
1081
1090
  const current = path.slice(0, lio);
1082
1091
  // --- 创建任务对象 ---
@@ -1108,6 +1117,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1108
1117
  if (!path.endsWith('.json')) {
1109
1118
  path += '.json';
1110
1119
  }
1120
+ await opt.initProgress?.('Load local ' + path + ' ...');
1111
1121
  const lcontent = await fs.getContent(path, {
1112
1122
  'encoding': 'utf8'
1113
1123
  }, taskId);
@@ -1150,6 +1160,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1150
1160
  // --- 创建 Task 总 style ---
1151
1161
  dom.createToStyleList(taskId);
1152
1162
  // --- 加载 control ---
1163
+ await opt.initProgress?.('Control initialization ...');
1153
1164
  const r = await control.init(taskId, invoke);
1154
1165
  if (r < 0) {
1155
1166
  dom.removeFromStyleList(taskId);
@@ -1161,6 +1172,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1161
1172
  for (let path of app.config.themes) {
1162
1173
  path += '.cgt';
1163
1174
  path = tool.urlResolve('/', path);
1175
+ await opt.initProgress?.('Load theme ' + path + ' ...');
1164
1176
  const file = await fs.getContent(path, undefined, taskId);
1165
1177
  if (file && typeof file !== 'string') {
1166
1178
  const th = await theme.read(file);
@@ -1173,6 +1185,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1173
1185
  else {
1174
1186
  // --- 加载全局主题 ---
1175
1187
  if (theme.global) {
1188
+ await opt.initProgress?.('Load global theme ...');
1176
1189
  await theme.load(undefined, taskId);
1177
1190
  }
1178
1191
  }
@@ -1183,6 +1196,7 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1183
1196
  }, taskId);
1184
1197
  if (style) {
1185
1198
  const r = tool.stylePrepend(style, 'cg-task' + taskId.toString() + '_');
1199
+ await opt.initProgress?.('Style initialization ...');
1186
1200
  dom.pushStyle(taskId, await tool.styleUrl2DataUrl(app.config.style, r.style, app.files));
1187
1201
  }
1188
1202
  }
@@ -1190,11 +1204,13 @@ export async function run(url: string, opt: types.ITaskRunOptions = {}, ntid?: n
1190
1204
  core.trigger('taskStarted', taskId);
1191
1205
  // --- 请求权限 ---
1192
1206
  if (app.config.permissions) {
1207
+ await opt.initProgress?.('Style initialization ...');
1193
1208
  await checkPermission(app.config.permissions, true, undefined, taskId);
1194
1209
  }
1195
1210
  // --- 执行 app ---
1196
1211
  const appCls: core.AbstractApp = new expo.default();
1197
1212
  list[taskId].class = appCls;
1213
+ await opt.initProgress?.('Starting ...');
1198
1214
  await appCls.main(opt.data ?? {});
1199
1215
  return taskId;
1200
1216
  }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clickgo",
3
- "version": "3.1.13",
3
+ "version": "3.1.14",
4
4
  "description": "Background interface, software interface, mobile phone APP interface operation library.",
5
5
  "keywords": [
6
6
  "deskrt",
@@ -24,5 +24,8 @@
24
24
  "electron": "^22.0.2",
25
25
  "jszip": "^3.10.1",
26
26
  "typescript": "^4.9.4"
27
+ },
28
+ "dependencies": {
29
+ "terser": "^5.16.1"
27
30
  }
28
31
  }
package/types/index.d.ts CHANGED
@@ -421,6 +421,8 @@ export interface ITaskRunOptions {
421
421
  'icon'?: string;
422
422
  /** --- 加载进度回调 --- */
423
423
  'progress'?: (loaded: number, total: number) => void | Promise<void>;
424
+ /** --- 初始化进度回调 --- */
425
+ 'initProgress'?: (state: string) => void | Promise<void>;
424
426
  /** --- 显示 notify 窗口 --- */
425
427
  'notify'?: boolean;
426
428
  /** --- 不禁止某些浏览器对象,App 模式下仅能设置基任务中已经 unblock 的值 --- */
@@ -429,6 +431,8 @@ export interface ITaskRunOptions {
429
431
  'permissions'?: string[];
430
432
  /** --- 给 task 传值 --- */
431
433
  'data'?: Record<string, any>;
434
+ /** --- 执行文件的基路径,一般在传入 APP 包时使用,以 .cga 结尾或不以 / 结尾的路径 --- */
435
+ 'path'?: string;
432
436
  }
433
437
 
434
438
  export interface ICreateTimerOptions {