@talex-touch/utils 1.0.4 → 1.0.8

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/channel/index.ts CHANGED
@@ -15,7 +15,7 @@ export interface ITouchChannel {
15
15
  * Register a channel
16
16
  * @description Register a channel, and return a function to cancel the registration
17
17
  * @param type {@link ChannelType} The type of channel
18
- * @param eventName {string} The name of event, must be unique in the channel {@link ChannelType
18
+ * @param eventName {string} The name of event, must be unique in the channel {@link ChannelType}
19
19
  * @param callback {Function} The callback function
20
20
  */
21
21
  regChannel(type: ChannelType, eventName: string, callback: (data: StandardChannelData) => any): () => void
@@ -90,5 +90,5 @@ export interface RawStandardChannelData extends RawChannelData {
90
90
  }
91
91
 
92
92
  export interface StandardChannelData extends RawStandardChannelData {
93
- reply: (code: DataCode, data: any, options?: any) => void
93
+ reply: (code: DataCode, data: any) => void
94
94
  }
package/eventbus/index.ts CHANGED
@@ -40,7 +40,7 @@ export interface ITouchEventBus<E> {
40
40
  * @param handler Event handler (extends from EventHandler)
41
41
  * @returns true if the event was added, otherwise false
42
42
  */
43
- on(event: E, handler: EventHandler): boolean;
43
+ on(event: E, handler: EventHandler): boolean | void;
44
44
 
45
45
  /**
46
46
  * Subscribe touch-app events (any kind of events extends from TouchEvent)
@@ -48,7 +48,7 @@ export interface ITouchEventBus<E> {
48
48
  * @param handler Event handler (extends from EventHandler)
49
49
  * @returns true if the event was added, otherwise false
50
50
  */
51
- once(event: E, handler: EventHandler): boolean;
51
+ once(event: E, handler: EventHandler): boolean | void;
52
52
 
53
53
  /**
54
54
  * UnSubscribe touch-app events (any kind of events extends from TouchEvent)
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "module": "./index.ts",
6
6
  "license": "MPL-2.0",
7
7
  "private": false,
8
- "version": "1.0.4",
8
+ "version": "1.0.8",
9
9
  "scripts": {
10
10
  "publish": "npm publish --access public"
11
11
  },
@@ -20,10 +20,11 @@
20
20
  },
21
21
  "description": "TalexTouch series utils",
22
22
  "dependencies": {
23
+ "path-browserify": "^1.0.1",
23
24
  "vue": "^3.3.4"
24
25
  },
25
26
  "peerDependencies": {
26
- "vue": "^3.2.47",
27
- "electron": "^24.4.0"
27
+ "electron": "^24.4.0",
28
+ "vue": "^3.2.47"
28
29
  }
29
30
  }
@@ -15,7 +15,6 @@ export interface Permission {
15
15
  description: string;
16
16
  }
17
17
 
18
- // generate a permission manager interface
19
18
  export interface IPermissionCenter {
20
19
  /**
21
20
  * add a permission
package/plugin/channel.ts CHANGED
@@ -1,4 +1,5 @@
1
- const { ipcRenderer, IpcMainEvent } = require("electron");
1
+ // const { ipcRenderer, IpcMainEvent } = require("electron");
2
+ import { ipcRenderer, IpcRendererEvent } from "electron/main";
2
3
  import {
3
4
  ChannelType,
4
5
  DataCode,
@@ -6,7 +7,7 @@ import {
6
7
  RawChannelSyncData,
7
8
  RawStandardChannelData,
8
9
  StandardChannelData,
9
- } from "./../channel";
10
+ } from "../channel";
10
11
 
11
12
  class TouchChannel implements ITouchClientChannel {
12
13
  channelMap: Map<string, Function[]> = new Map();
@@ -18,13 +19,13 @@ class TouchChannel implements ITouchClientChannel {
18
19
  constructor(pluginName: string) {
19
20
  this.plugin = pluginName;
20
21
 
21
- ipcRenderer.on("@main-process-message", this.__handle_main.bind(this));
22
+ ipcRenderer.on("@plugin-process-message", this.__handle_main.bind(this));
22
23
  }
23
24
 
24
- __parse_raw_data(e, arg): RawStandardChannelData | null {
25
- // console.log("Raw data: ", arg, e);
25
+ __parse_raw_data(e: typeof IpcRendererEvent, arg: any): RawStandardChannelData | null {
26
+ console.log("Raw data: ", arg, e);
26
27
  if (arg) {
27
- const { name, header, code, plugin, data, sync } = arg;
28
+ const { name, header, code, data, sync } = arg;
28
29
 
29
30
  if (header) {
30
31
  return {
@@ -36,7 +37,6 @@ class TouchChannel implements ITouchClientChannel {
36
37
  sync,
37
38
  code,
38
39
  data,
39
- plugin,
40
40
  name: name as string,
41
41
  };
42
42
  }
@@ -47,7 +47,8 @@ class TouchChannel implements ITouchClientChannel {
47
47
  // throw new Error("Invalid message!");
48
48
  }
49
49
 
50
- __handle_main(e: typeof IpcMainEvent, arg: any): any {
50
+ __handle_main(e: typeof IpcRendererEvent, _arg: any): any {
51
+ const arg = JSON.parse(_arg)
51
52
  const rawData = this.__parse_raw_data(e, arg);
52
53
  if ( !rawData ) return
53
54
 
@@ -57,13 +58,13 @@ class TouchChannel implements ITouchClientChannel {
57
58
  return this.pendingMap.get(id)?.(rawData);
58
59
  }
59
60
 
60
- if ( rawData.plugin !== this.plugin ) return
61
+ // if ( rawData.plugin !== this.plugin ) return
61
62
 
62
63
  this.channelMap.get(rawData.name)?.forEach((func) => {
63
64
  const handInData: StandardChannelData = {
64
- reply: (code: DataCode, data: any, options: any) => {
65
+ reply: (code: DataCode, data: any) => {
65
66
  e.sender.send(
66
- "@main-process-message",
67
+ "@plugin-process-message",
67
68
  this.__parse_sender(code, rawData, data, rawData.sync)
68
69
  );
69
70
  },
@@ -148,9 +149,9 @@ class TouchChannel implements ITouchClientChannel {
148
149
 
149
150
  return new Promise((resolve) => {
150
151
 
151
- ipcRenderer.send("@main-process-message", data);
152
+ ipcRenderer.send("@plugin-process-message", data);
152
153
 
153
- this.pendingMap.set(uniqueId, (res) => {
154
+ this.pendingMap.set(uniqueId, (res: any) => {
154
155
  this.pendingMap.delete(uniqueId);
155
156
 
156
157
  resolve(res.data);
@@ -170,7 +171,7 @@ class TouchChannel implements ITouchClientChannel {
170
171
  },
171
172
  } as RawStandardChannelData;
172
173
 
173
- const res = this.__parse_raw_data(null, ipcRenderer.sendSync("@main-process-message", data))!
174
+ const res = this.__parse_raw_data(null, ipcRenderer.sendSync("@plugin-process-message", data))!
174
175
 
175
176
  if ( res.header.status === 'reply' ) return res.data;
176
177
 
@@ -179,4 +180,13 @@ class TouchChannel implements ITouchClientChannel {
179
180
  }
180
181
  }
181
182
 
182
- export const touchChannel: ITouchClientChannel = window['$channel'] = new TouchChannel(window.$plugin.name);
183
+ let touchChannel: ITouchClientChannel
184
+
185
+ export function genChannel() {
186
+ if (!touchChannel) {
187
+ // @ts-ignore
188
+ touchChannel = window.$channel = new TouchChannel(window.$plugin.name)
189
+ }
190
+
191
+ return touchChannel
192
+ }
package/plugin/index.ts CHANGED
@@ -68,3 +68,30 @@ export interface IPluginManager {
68
68
  loadPlugin(pluginName: string): Promise<boolean>
69
69
  unloadPlugin(pluginName: string): Promise<boolean>
70
70
  }
71
+
72
+ export interface IManifest {
73
+ name: string
74
+ version: string
75
+ description: string
76
+ plugin?: {
77
+ dev: {
78
+ enable: boolean
79
+ address: string
80
+ }
81
+ }
82
+ build?: {
83
+ files: string[]
84
+ secret: {
85
+ pos: string
86
+ addon: string[]
87
+ }
88
+ verify?: {
89
+ enable: boolean
90
+ online: 'custom' | 'always' | 'once'
91
+ }
92
+ version?: {
93
+ update: 'auto' | 'ask' | 'readable'
94
+ downgrade: boolean
95
+ }
96
+ }
97
+ }
package/plugin/preload.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { touchChannel } from './channel'
1
+ import { genChannel } from './channel'
2
2
  import './sdk/index'
3
3
 
4
4
  // window type
@@ -31,7 +31,9 @@ export function init(window: Window) {
31
31
  }
32
32
 
33
33
  export function initBridge(window: Window) {
34
- window.$send = touchChannel.send
35
- window.$sendSync = touchChannel.sendSync
36
- window.$regChannel = touchChannel.regChannel
34
+ const touchChannel = genChannel()
35
+
36
+ window.$send = touchChannel.send.bind(touchChannel)
37
+ window.$sendSync = touchChannel.sendSync.bind(touchChannel)
38
+ window.$regChannel = touchChannel.regChannel.bind(touchChannel)
37
39
  }
@@ -0,0 +1,30 @@
1
+ import { genChannel } from '../channel';
2
+ import {
3
+ BrowserWindowConstructorOptions
4
+ } from "electron";
5
+
6
+ export function regShortcut(key: string, func: Function) {
7
+ const channel = genChannel()
8
+
9
+ const res = channel.sendSync('shortcon:reg', { key })
10
+ if ( res instanceof String ) throw new Error(res)
11
+ if ( res === false ) return false;
12
+
13
+ channel.regChannel('shortcon:trigger', ({ data }) => key === data.key && func())
14
+
15
+ return true;
16
+ }
17
+
18
+ export function createWindow(options: BrowserWindowConstructorOptions & { file?: string } & { url?: string }): number {
19
+ const res = genChannel().sendSync('window:new', options)
20
+ if ( res.error ) throw new Error(res.error)
21
+
22
+ return res.id
23
+ }
24
+
25
+ export function toggleWinVisible(id: number, visible?: boolean): boolean {
26
+ const res = genChannel().sendSync('window:visible', visible !== undefined ? { id, visible } : { id })
27
+ if ( res.error ) throw new Error(res.error)
28
+
29
+ return res.visible
30
+ }
@@ -1,4 +1,4 @@
1
- import { touchChannel } from './../../channel';
1
+ import { genChannel } from './../../channel';
2
2
 
3
3
  export enum LifecycleHooks {
4
4
  ENABLE = 'en',
@@ -9,22 +9,27 @@ export enum LifecycleHooks {
9
9
  CRASH = 'cr'
10
10
  }
11
11
 
12
+ // @ts-ignore
12
13
  export function injectHook(type: LifecycleHooks, hook: Function, processFunc = ({ data, reply }) => {
14
+ // @ts-ignore
13
15
  const hooks: Array<Function> = window.$touchSDK.__hooks[type]
14
16
  if (hooks) {
15
17
  hooks.forEach(hook => hook(data))
16
18
  }
17
19
  reply(true)
18
20
  }) {
21
+ // @ts-ignore
19
22
  const __hooks = window.$touchSDK.__hooks
23
+ // @ts-ignore
20
24
  const hooks: Array<Function> = __hooks[type] || (__hooks[type] = [])
21
25
 
22
26
  if (hooks.length === 0) {
23
27
 
24
- touchChannel.regChannel("@lifecycle:" + type, obj => {
28
+ genChannel().regChannel("@lifecycle:" + type, (obj: any) => {
25
29
 
26
30
  processFunc(obj)
27
31
 
32
+ // @ts-ignore
28
33
  delete window.$touchSDK.__hooks[type]
29
34
  })
30
35
 
@@ -0,0 +1,30 @@
1
+ import { genChannel } from '../../channel';
2
+ import { IService } from "../../../service";
3
+
4
+ export function regService(service: IService, handler: Function): boolean {
5
+ const res = !!genChannel().sendSync('service:reg', { service: service.name })
6
+
7
+ if (res)
8
+ onHandleService(service, handler)
9
+
10
+ return res
11
+ }
12
+
13
+ export function unRegService(service: IService): boolean {
14
+ return !!genChannel().sendSync('service:unreg', { service: service.name })
15
+ }
16
+
17
+ export function onHandleService(service: IService, handler: Function) {
18
+ // @ts-ignore
19
+ genChannel().regChannel('service:handle', ({ data: _data }) => {
20
+ const { data } = _data
21
+
22
+ // console.log('service:handle', data, service)
23
+
24
+ if (data.service === service.name) {
25
+ return handler(data)
26
+ }
27
+
28
+ return false
29
+ })
30
+ }
@@ -0,0 +1,68 @@
1
+ export interface IService {
2
+ /**
3
+ * service id
4
+ */
5
+ id: Symbol;
6
+
7
+ /**
8
+ * service name
9
+ */
10
+ name: string;
11
+
12
+ /**
13
+ * service description
14
+ */
15
+ description: string;
16
+ }
17
+
18
+ export interface IServiceEvent {
19
+
20
+ service: IService;
21
+
22
+ setCancelled(cancelled: boolean): void;
23
+
24
+ isCancelled(): boolean;
25
+ }
26
+
27
+ export interface IServiceHandler {
28
+ /**
29
+ * The plugin scope of the service handler
30
+ * @description
31
+ * When service registered, the service center will use the plugin scope to find the service handler.
32
+ * If plugin is disabled, the app will automatically enable plugin and hand on the service to the plugin.
33
+ * When plugin enabled, you must immediately register service handler to the service center, app will waiting for the service handler, until the service handler handled.
34
+ */
35
+ pluginScope: string
36
+
37
+ /**
38
+ * Handle the service data
39
+ * @param data service data
40
+ */
41
+ handle(event: IServiceEvent, data: object): any;
42
+ }
43
+
44
+ export interface IServiceCenter {
45
+ /**
46
+ * The service center will register the service
47
+ * @param service will be registered service
48
+ * @param handler service handler
49
+ * @returns register result (true: success, false: fail)
50
+ */
51
+ regService(service: IService, handler: IServiceHandler): boolean;
52
+
53
+ /**
54
+ * The service center will unregister the service
55
+ * @param service will be unregistered service
56
+ * @returns unregister result (true: success, false: fail)
57
+ */
58
+ unRegService(service: IService): boolean;
59
+
60
+ /**
61
+ * Get the service by service id
62
+ * @param id service id
63
+ * @returns service
64
+ */
65
+ // getService(id: symbol): IService;
66
+
67
+ useService(service: IService, data: object): Promise<boolean> | boolean;
68
+ }
@@ -0,0 +1,78 @@
1
+ import { IService } from './../index';
2
+
3
+ export abstract class ProtocolService<T extends string> implements IService {
4
+ id: symbol;
5
+ name: string;
6
+ description: string;
7
+
8
+ protocol: string[]
9
+
10
+ type: T
11
+
12
+ constructor(id: symbol, protocol: string[]) {
13
+ this.id = id;
14
+ this.name = id.description!;
15
+ this.description = `${this.name} Protocol Service`;
16
+ this.protocol = protocol
17
+
18
+ this.type = id.description as T
19
+ }
20
+ }
21
+
22
+ export const IMAGE_SUFFIX = [
23
+ 'jpg', 'png', 'gif', 'bmp', 'webp', 'svg', 'ico', 'tiff', 'tif', 'jpeg', 'avif'
24
+ ]
25
+
26
+ export class ImageProtocolService extends ProtocolService<'image'> {
27
+ constructor() {
28
+ super(Symbol('Image'), IMAGE_SUFFIX)
29
+ }
30
+ }
31
+
32
+ export const AUDIO_SUFFIX = [
33
+ 'mp3', 'wav', 'ogg', 'aac', 'flac', 'wma', 'ape', 'm4a', 'm4r', 'm4b', 'm4p', 'm4v', 'mp4', '3gp', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'rmvb', 'rm', 'asf', 'dat', 'mpg', 'mpeg', 'vob', 'f4v', 'm3u8', 'webm', 'ts', 'mts', 'm2ts', 'mts', 'dv', 'divx', 'xvid', 'mpe', 'mod', 'sdp', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts'
34
+ ]
35
+
36
+ export class AudioProtocolService extends ProtocolService<'audio'> {
37
+ constructor() {
38
+ super(Symbol('Audio'), AUDIO_SUFFIX)
39
+ }
40
+ }
41
+
42
+ export const VIDEO_SUFFIX = [
43
+ 'mp4', '3gp', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'rmvb', 'rm', 'asf', 'dat', 'mpg', 'mpeg', 'vob', 'f4v', 'm3u8', 'webm', 'ts', 'mts', 'm2ts', 'mts', 'dv', 'divx', 'xvid', 'mpe', 'mod', 'sdp', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts', 'm2v', 'm2p', 'm2t', 'm2ts'
44
+ ]
45
+
46
+ export class VideoProtocolService extends ProtocolService<'video'> {
47
+ constructor() {
48
+ super(Symbol('Video'), VIDEO_SUFFIX)
49
+ }
50
+ }
51
+
52
+ export const TEXT_SUFFIX = [
53
+ 'txt', 'md', 'markdown', 'json', 'js', 'ts', 'html', 'css', 'scss', 'sass', 'less', 'xml', 'yaml', 'yml', 'ini', 'log', 'bat', 'sh', 'cmd', 'c', 'cpp', 'h', 'hpp', 'java', 'py', 'go', 'php', 'sql', 'swift', 'vb', 'vbs', 'lua', 'rb', 'r', 'cs', 'm', 'mm', 'pl', 'perl', 'asm', 'asmx', 'inc', 'coffee', 'ts', 'tsx', 'jsx', 'vue', 'php', 'php3', 'php4', 'php5', 'php7', 'phps', 'phtml', 'pht', 'phar', 'phpt', 'php-cgi', 'php-cs-fixer', 'phpunit', 'phpunit.xml', 'phpunit.xml.dist', 'phpunit.phar', 'phpunit.phar.dist', 'phpunit-4.8.36.phar', 'phpunit-4.8.36.phar.dist', 'phpunit-5.7.27.phar', 'phpunit-5.7.27.phar.dist', 'phpunit-6.5.14.phar', 'phpunit-6.5.14.phar.dist', 'phpunit-7.5.20.phar', 'phpunit-7.5.20.phar.dist', 'phpunit-8.5.8.phar', 'phpunit-8.5.8.phar.dist', 'phpunit-9.3.10.phar', 'phpunit-9.3.10.phar.dist', 'phpunit-9.4.3.phar', 'phpunit-9.4.3.phar.dist', 'phpunit-9.5.0.phar', 'phpunit-9.5.0.phar.dist', 'phpunit-9.5.1.phar', 'phpunit-9.5.1.phar.dist', 'phpunit-9.5.2.phar', 'phpunit-9.5.2.phar.dist', 'phpunit-9.5.4.phar', 'phpunit-9.5.4.phar.dist', 'php'
54
+ ]
55
+
56
+ export class TextProtocolService extends ProtocolService<'text'> {
57
+ constructor() {
58
+ super(Symbol('Text'), TEXT_SUFFIX)
59
+ }
60
+ }
61
+
62
+ export const serviceSuffixMap = new Map<ProtocolService<string>, string[]>
63
+
64
+ serviceSuffixMap.set(new ImageProtocolService(), IMAGE_SUFFIX)
65
+ serviceSuffixMap.set(new AudioProtocolService(), AUDIO_SUFFIX)
66
+ serviceSuffixMap.set(new VideoProtocolService(), VIDEO_SUFFIX)
67
+ serviceSuffixMap.set(new TextProtocolService(), TEXT_SUFFIX)
68
+
69
+ export function suffix2Service(suffix: string): ProtocolService<string> | null {
70
+
71
+ for (const [type, suffixes] of serviceSuffixMap.entries()) {
72
+ if (suffixes.includes(suffix)) {
73
+ return type
74
+ }
75
+ }
76
+
77
+ return null
78
+ }
@@ -1,38 +0,0 @@
1
- import fse from "fs-extra";
2
- import path from "path";
3
- import fs from "fs";
4
-
5
- export function genFileTree(basePath: string, depth: number = 0, options = {
6
- maxDepth: 1,
7
- ignores: [
8
- "node_modules",
9
- ".git",
10
- ".vscode",
11
- ".idea",
12
- ".github",
13
- ".gitignore"
14
- ]
15
- }) {
16
- if (depth > options.maxDepth) return;
17
- const name = path.basename(basePath);
18
-
19
- if (options.ignores.includes(name)) return;
20
-
21
- if (depth === 0) {
22
- console.log("Touch tree helper: ");
23
- console.log(` > ${name}:`);
24
- }
25
-
26
-
27
- fse.readdirSync(basePath).forEach((file) => {
28
- const fullPath = path.join(basePath, file);
29
- const stat = fs.statSync(fullPath);
30
-
31
- if (stat.isDirectory()) {
32
- console.log(` ├${"─".repeat(depth + 2)} ${file}:`);
33
- genFileTree(fullPath, depth + 1);
34
- } else {
35
- console.log(` ├${"─".repeat(depth * 2 )} ${file}`);
36
- }
37
- });
38
- }