@talex-touch/utils 1.0.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/channel/index.ts +94 -0
- package/common/index.ts +39 -0
- package/eventbus/index.ts +87 -0
- package/help/tree-generator.ts +38 -0
- package/index.ts +0 -0
- package/package.json +29 -0
- package/plugin/channel.ts +182 -0
- package/plugin/index.ts +56 -0
- package/plugin/preload.ts +34 -0
- package/renderer/ref.ts +55 -0
package/channel/index.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export enum ChannelType {
|
|
2
|
+
MAIN = "main",
|
|
3
|
+
PLUGIN = "plugin"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export enum DataCode {
|
|
7
|
+
SUCCESS = 200,
|
|
8
|
+
NETWORK_ERROR = 500,
|
|
9
|
+
ERROR = 100
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ITouchChannel {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Register a channel
|
|
16
|
+
* @description Register a channel, and return a function to cancel the registration
|
|
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
|
|
19
|
+
* @param callback {Function} The callback function
|
|
20
|
+
*/
|
|
21
|
+
regChannel(type: ChannelType, eventName: string, callback: Function): () => void
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Send a message to a channel
|
|
25
|
+
* @param type {@link ChannelType} The type of channel
|
|
26
|
+
* @param eventName {string} The name of event, must be unique in the channel {@link ChannelType}
|
|
27
|
+
* @param arg {any} The arguments of the message
|
|
28
|
+
*/
|
|
29
|
+
send(type: ChannelType, eventName: string, arg?: any): Promise<any>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ITouchClientChannel {
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Register a channel
|
|
36
|
+
* @description Register a channel, and return a function to cancel the registration
|
|
37
|
+
* @param type {@link ChannelType} The type of channel
|
|
38
|
+
* @param eventName {string} The name of event, must be unique in the channel {@link ChannelType
|
|
39
|
+
* @param callback {Function} The callback function
|
|
40
|
+
*/
|
|
41
|
+
regChannel(eventName: string, callback: Function): () => void
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Send a message to a channel
|
|
45
|
+
* @param eventName {string} The name of event, must be unique in the channel {@link ChannelType}
|
|
46
|
+
* @param arg {any} The arguments of the message
|
|
47
|
+
*/
|
|
48
|
+
send(eventName: string, arg?: any): Promise<any>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Send a message to a channel and get the response
|
|
52
|
+
* @param eventName {string} The name of event, must be unique in the channel {@link ChannelType}
|
|
53
|
+
* @param arg {any} The arguments of the message
|
|
54
|
+
*/
|
|
55
|
+
sendSync(eventName: string, arg?: any): any
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface RawChannelSyncData {
|
|
59
|
+
timeStamp: number
|
|
60
|
+
/**
|
|
61
|
+
* The sync-data timeout
|
|
62
|
+
* @description The unit is milliseconds, and set it to 0 to cancel it.
|
|
63
|
+
* @default 10000
|
|
64
|
+
*/
|
|
65
|
+
timeout: 10000
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The sync-data unique id
|
|
69
|
+
* @description To identify each sync-request.
|
|
70
|
+
*/
|
|
71
|
+
id: string
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface RawChannelHeaderData {
|
|
75
|
+
status: 'reply' | 'request'
|
|
76
|
+
type: ChannelType
|
|
77
|
+
_originData?: any
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface RawChannelData {
|
|
81
|
+
name: string
|
|
82
|
+
header: RawChannelHeaderData
|
|
83
|
+
sync?: RawChannelSyncData
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface RawStandardChannelData extends RawChannelData {
|
|
87
|
+
code: DataCode
|
|
88
|
+
data?: any
|
|
89
|
+
plugin?: string
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface StandardChannelData extends RawStandardChannelData {
|
|
93
|
+
reply: (code: DataCode, data: any, options?: any) => void
|
|
94
|
+
}
|
package/common/index.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export async function sleep(time: number) {
|
|
2
|
+
return new Promise(resolve => setTimeout(() => resolve(time), time))
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function anyStr2Num(str: string): BigInt {
|
|
6
|
+
const numbers = new Array<String>
|
|
7
|
+
let minium = Infinity
|
|
8
|
+
|
|
9
|
+
for (let index = 0; index < str.length; index++) {
|
|
10
|
+
const e = +str.charCodeAt(index);
|
|
11
|
+
|
|
12
|
+
numbers.push(("" + e).padStart(5, "0"))
|
|
13
|
+
|
|
14
|
+
if ( minium > e ) minium = e
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// each number transform
|
|
19
|
+
numbers.forEach((e, i) => numbers[i] = (BigInt(+e) - BigInt(minium)).toString().padStart(2, "0"))
|
|
20
|
+
|
|
21
|
+
return BigInt(`${minium}000${BigInt(+numbers.join(""))}`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function num2anyStr(num: BigInt): string {
|
|
25
|
+
const strs = num.toString().split("000")
|
|
26
|
+
const baseNum = +strs[0]
|
|
27
|
+
const length = +strs[1].length / 2
|
|
28
|
+
|
|
29
|
+
let text = ''
|
|
30
|
+
|
|
31
|
+
for ( let i = 0; i < length; i++ ) {
|
|
32
|
+
const str = strs[1].slice(i * 2, i * 2 + 2)
|
|
33
|
+
|
|
34
|
+
// strs[1] = strs[1].replace(str, (BigInt(+str) + BigInt(baseNum)).toString().padStart(5, "0"))
|
|
35
|
+
text += String.fromCharCode(+str + baseNum)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return text
|
|
39
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export type EventHandler = (event: ITouchEvent) => void;
|
|
2
|
+
|
|
3
|
+
export interface EventHandlerWrapper {
|
|
4
|
+
/**
|
|
5
|
+
* Event handler
|
|
6
|
+
*/
|
|
7
|
+
handler: EventHandler;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Event type
|
|
11
|
+
* @see EventType
|
|
12
|
+
* @default EventType.PERSIST (must be, if implements)
|
|
13
|
+
*/
|
|
14
|
+
type?: EventType;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum EventType {
|
|
18
|
+
PERSIST,
|
|
19
|
+
CONSUME,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ITouchEvent<E = any> {
|
|
23
|
+
/**
|
|
24
|
+
* Event name
|
|
25
|
+
*/
|
|
26
|
+
name: E;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Event data
|
|
30
|
+
*/
|
|
31
|
+
data?: any;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ITouchEventBus<E> {
|
|
35
|
+
map: Map<E, Set<EventHandlerWrapper>>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Subscribe touch-app events (any kind of events extends from TouchEvent)
|
|
39
|
+
* @param event EventName (extends from TouchEvent)
|
|
40
|
+
* @param handler Event handler (extends from EventHandler)
|
|
41
|
+
* @returns true if the event was added, otherwise false
|
|
42
|
+
*/
|
|
43
|
+
on(event: E, handler: EventHandler): boolean;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe touch-app events (any kind of events extends from TouchEvent)
|
|
47
|
+
* @param event EventName (extends from TouchEvent)
|
|
48
|
+
* @param handler Event handler (extends from EventHandler)
|
|
49
|
+
* @returns true if the event was added, otherwise false
|
|
50
|
+
*/
|
|
51
|
+
once(event: E, handler: EventHandler): boolean;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* UnSubscribe touch-app events (any kind of events extends from TouchEvent)
|
|
55
|
+
* @param event EventName (extends from TouchEvent)
|
|
56
|
+
* @param handler Event handler (extends from EventHandler)
|
|
57
|
+
* @returns true if the event was removed, otherwise false
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const handler = (event: TouchEvent) => {
|
|
61
|
+
* console.log(event)
|
|
62
|
+
* }
|
|
63
|
+
*/
|
|
64
|
+
off<T extends ITouchEvent>(event: E, handler: EventHandler): boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* UnSubscribe touch-app events all matched (any kind of events extends from TouchEvent)
|
|
68
|
+
* @param event EventName (extends from TouchEvent)
|
|
69
|
+
* @returns true if the event was added, otherwise false
|
|
70
|
+
*/
|
|
71
|
+
offAll(event: E): boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* UnSubscribe touch-app events all matched (any kind of events extends from TouchEvent)
|
|
75
|
+
* @param event EventName (extends from TouchEvent)
|
|
76
|
+
* @param handler Event handler (extends from EventHandler)
|
|
77
|
+
* @returns true if the event was added, otherwise false
|
|
78
|
+
*/
|
|
79
|
+
off<T extends ITouchEvent>(event: E, handler: EventHandler): boolean;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Emit touch-app events (any kind of events extends from TouchEvent)
|
|
83
|
+
* @param event EventName (extends from TouchEvent)
|
|
84
|
+
* @param data Event data (extends from TouchEvent)
|
|
85
|
+
*/
|
|
86
|
+
emit<T extends ITouchEvent<E>>(event: E, data: T): void;
|
|
87
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
}
|
package/index.ts
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"main": "./index.ts",
|
|
3
|
+
"name": "@talex-touch/utils",
|
|
4
|
+
"author": "TalexDreamSoul",
|
|
5
|
+
"module": "./index.ts",
|
|
6
|
+
"license": "MPL-2.0",
|
|
7
|
+
"private": false,
|
|
8
|
+
"version": "1.0.0",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"publish": "npm publish --access public"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"vue",
|
|
14
|
+
"electron",
|
|
15
|
+
"talex-touch"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"url": "https://github.com/talex-touch/talex-touch.git",
|
|
19
|
+
"type": "git"
|
|
20
|
+
},
|
|
21
|
+
"description": "TalexTouch series utils",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"vue": "^3.2.47"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"vue": "^3.2.47",
|
|
27
|
+
"electron": "^24.4.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
const { ipcRenderer, IpcMainEvent } = require("electron");
|
|
2
|
+
import {
|
|
3
|
+
ChannelType,
|
|
4
|
+
DataCode,
|
|
5
|
+
ITouchClientChannel,
|
|
6
|
+
RawChannelSyncData,
|
|
7
|
+
RawStandardChannelData,
|
|
8
|
+
StandardChannelData,
|
|
9
|
+
} from "./../channel";
|
|
10
|
+
|
|
11
|
+
class TouchChannel implements ITouchClientChannel {
|
|
12
|
+
channelMap: Map<string, Function[]> = new Map();
|
|
13
|
+
|
|
14
|
+
pendingMap: Map<string, Function> = new Map();
|
|
15
|
+
|
|
16
|
+
plugin: string;
|
|
17
|
+
|
|
18
|
+
constructor(pluginName: string) {
|
|
19
|
+
this.plugin = pluginName;
|
|
20
|
+
|
|
21
|
+
ipcRenderer.on("@main-process-message", this.__handle_main.bind(this));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
__parse_raw_data(e, arg): RawStandardChannelData | null {
|
|
25
|
+
// console.log("Raw data: ", arg, e);
|
|
26
|
+
if (arg) {
|
|
27
|
+
const { name, header, code, plugin, data, sync } = arg;
|
|
28
|
+
|
|
29
|
+
if (header) {
|
|
30
|
+
return {
|
|
31
|
+
header: {
|
|
32
|
+
status: header.status || "request",
|
|
33
|
+
type: ChannelType.PLUGIN,
|
|
34
|
+
_originData: arg,
|
|
35
|
+
},
|
|
36
|
+
sync,
|
|
37
|
+
code,
|
|
38
|
+
data,
|
|
39
|
+
plugin,
|
|
40
|
+
name: name as string,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.error(e, arg);
|
|
46
|
+
return null;
|
|
47
|
+
// throw new Error("Invalid message!");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
__handle_main(e: typeof IpcMainEvent, arg: any): any {
|
|
51
|
+
const rawData = this.__parse_raw_data(e, arg);
|
|
52
|
+
if ( !rawData ) return
|
|
53
|
+
|
|
54
|
+
if ( rawData.header.status === 'reply' && rawData.sync ) {
|
|
55
|
+
const { id } = rawData.sync;
|
|
56
|
+
|
|
57
|
+
return this.pendingMap.get(id)?.(rawData);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if ( rawData.plugin !== this.plugin ) return
|
|
61
|
+
|
|
62
|
+
this.channelMap.get(rawData.name)?.forEach((func) => {
|
|
63
|
+
const handInData: StandardChannelData = {
|
|
64
|
+
reply: (code: DataCode, data: any, options: any) => {
|
|
65
|
+
e.sender.send(
|
|
66
|
+
"@main-process-message",
|
|
67
|
+
this.__parse_sender(code, rawData, data, rawData.sync)
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
...rawData,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const res = func(handInData);
|
|
74
|
+
|
|
75
|
+
if (res && res instanceof Promise) return;
|
|
76
|
+
|
|
77
|
+
handInData.reply(DataCode.SUCCESS, res);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
__parse_sender(
|
|
82
|
+
code: DataCode,
|
|
83
|
+
rawData: RawStandardChannelData,
|
|
84
|
+
data: any,
|
|
85
|
+
sync?: RawChannelSyncData
|
|
86
|
+
): RawStandardChannelData {
|
|
87
|
+
return {
|
|
88
|
+
code,
|
|
89
|
+
data,
|
|
90
|
+
sync: !sync
|
|
91
|
+
? undefined
|
|
92
|
+
: {
|
|
93
|
+
timeStamp: new Date().getTime(),
|
|
94
|
+
// reply sync timeout should follow the request timeout, unless user set it.
|
|
95
|
+
timeout: sync.timeout,
|
|
96
|
+
id: sync.id,
|
|
97
|
+
},
|
|
98
|
+
name: rawData.name,
|
|
99
|
+
header: {
|
|
100
|
+
status: "reply",
|
|
101
|
+
type: rawData.header.type,
|
|
102
|
+
_originData: rawData.header._originData,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
regChannel(
|
|
108
|
+
eventName: string,
|
|
109
|
+
callback: Function
|
|
110
|
+
): () => void {
|
|
111
|
+
const listeners = this.channelMap.get(eventName) || [];
|
|
112
|
+
|
|
113
|
+
if (!listeners.includes(callback)) {
|
|
114
|
+
listeners.push(callback);
|
|
115
|
+
} else return () => void 0;
|
|
116
|
+
|
|
117
|
+
this.channelMap.set(eventName, listeners);
|
|
118
|
+
|
|
119
|
+
return () => {
|
|
120
|
+
const index = listeners.indexOf(callback);
|
|
121
|
+
|
|
122
|
+
if (index !== -1) {
|
|
123
|
+
listeners.splice(index, 1);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
send(eventName: string, arg: any): Promise<any> {
|
|
129
|
+
const uniqueId = `${new Date().getTime()}#${eventName}@${Math.random().toString(
|
|
130
|
+
12
|
|
131
|
+
)}`;
|
|
132
|
+
|
|
133
|
+
const data = {
|
|
134
|
+
code: DataCode.SUCCESS,
|
|
135
|
+
data: arg,
|
|
136
|
+
sync: {
|
|
137
|
+
timeStamp: new Date().getTime(),
|
|
138
|
+
timeout: 10000,
|
|
139
|
+
id: uniqueId,
|
|
140
|
+
},
|
|
141
|
+
name: eventName,
|
|
142
|
+
plugin: this.plugin,
|
|
143
|
+
header: {
|
|
144
|
+
status: "request",
|
|
145
|
+
type: ChannelType.PLUGIN,
|
|
146
|
+
},
|
|
147
|
+
} as RawStandardChannelData;
|
|
148
|
+
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
|
|
151
|
+
ipcRenderer.send("@main-process-message", data);
|
|
152
|
+
|
|
153
|
+
this.pendingMap.set(uniqueId, (res) => {
|
|
154
|
+
this.pendingMap.delete(uniqueId);
|
|
155
|
+
|
|
156
|
+
resolve(res.data);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
sendSync(eventName: string, arg?: any): any {
|
|
162
|
+
const data = {
|
|
163
|
+
code: DataCode.SUCCESS,
|
|
164
|
+
data: arg,
|
|
165
|
+
name: eventName,
|
|
166
|
+
plugin: this.plugin,
|
|
167
|
+
header: {
|
|
168
|
+
status: "request",
|
|
169
|
+
type: ChannelType.PLUGIN,
|
|
170
|
+
},
|
|
171
|
+
} as RawStandardChannelData;
|
|
172
|
+
|
|
173
|
+
const res = this.__parse_raw_data(null, ipcRenderer.sendSync("@main-process-message", data))!
|
|
174
|
+
|
|
175
|
+
if ( res.header.status === 'reply' ) return res.data;
|
|
176
|
+
|
|
177
|
+
return res;
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const touchChannel: ITouchClientChannel = window['$channel'] = new TouchChannel(window.$plugin.name);
|
package/plugin/index.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export enum PluginStatus {
|
|
2
|
+
DISABLED,
|
|
3
|
+
DISABLING,
|
|
4
|
+
|
|
5
|
+
CRASHED,
|
|
6
|
+
|
|
7
|
+
ENABLED,
|
|
8
|
+
ACTIVE,
|
|
9
|
+
|
|
10
|
+
LOADING,
|
|
11
|
+
LOADED
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IPluginIcon {
|
|
15
|
+
type: string | 'remixicon'
|
|
16
|
+
value: any
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IPluginBaseInfo {
|
|
20
|
+
name: string
|
|
21
|
+
readme: string
|
|
22
|
+
version: string
|
|
23
|
+
desc: string
|
|
24
|
+
icon: IPluginIcon
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface IPluginDev {
|
|
28
|
+
enable: boolean
|
|
29
|
+
address: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface IPluginWebview {
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ITouchPlugin extends IPluginBaseInfo {
|
|
36
|
+
dev: IPluginDev
|
|
37
|
+
webViewInit: boolean
|
|
38
|
+
webview: IPluginWebview
|
|
39
|
+
|
|
40
|
+
get status(): PluginStatus
|
|
41
|
+
set status(v: PluginStatus)
|
|
42
|
+
|
|
43
|
+
enable(): Promise<boolean>
|
|
44
|
+
disable(): Promise<boolean>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface IPluginManager {
|
|
48
|
+
plugins: Map<string, ITouchPlugin>
|
|
49
|
+
active: string | null
|
|
50
|
+
pluginPath: string
|
|
51
|
+
|
|
52
|
+
setActivePlugin(pluginName: string): boolean
|
|
53
|
+
|
|
54
|
+
loadPlugin(pluginName: string): Promise<boolean>
|
|
55
|
+
unloadPlugin(pluginName: string): Promise<boolean>
|
|
56
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { touchChannel } from "./channel";
|
|
2
|
+
|
|
3
|
+
// window type
|
|
4
|
+
declare global {
|
|
5
|
+
export interface Window {
|
|
6
|
+
$plugin: {
|
|
7
|
+
name: string;
|
|
8
|
+
path: Object;
|
|
9
|
+
};
|
|
10
|
+
$send: (type: string, data: any) => void;
|
|
11
|
+
$sendSync: (type: string, data: any) => Promise<any>;
|
|
12
|
+
$regChannel: (type: string, callback: Function) => void;
|
|
13
|
+
$crash: (message: string, extraData: any) => void;
|
|
14
|
+
$config: {
|
|
15
|
+
themeStyle: any;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function init(window: Window) {
|
|
21
|
+
const plugin = window.$plugin;
|
|
22
|
+
if (!plugin)
|
|
23
|
+
throw new Error("Plugin has a fatal error! Please check your plugin!");
|
|
24
|
+
|
|
25
|
+
window.$crash = function(message, extraData) {
|
|
26
|
+
window.$send("crash", { message, ...extraData });
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function initBridge(window: Window) {
|
|
31
|
+
window.$send = touchChannel.send;
|
|
32
|
+
window.$sendSync = touchChannel.sendSync;
|
|
33
|
+
window.$regChannel = touchChannel.regChannel;
|
|
34
|
+
}
|
package/renderer/ref.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { computed, customRef } from 'vue'
|
|
2
|
+
|
|
3
|
+
export function useModelWrapper(props: any, emit: any, name = 'modelValue') {
|
|
4
|
+
return computed({
|
|
5
|
+
get: () => props[name],
|
|
6
|
+
set: (value) => emit(`update:${name}`, value)
|
|
7
|
+
})
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function throttleRef(value: any, time: number) {
|
|
11
|
+
|
|
12
|
+
let ts = 0
|
|
13
|
+
|
|
14
|
+
return customRef((track, trigger) => {
|
|
15
|
+
return {
|
|
16
|
+
get() {
|
|
17
|
+
track()
|
|
18
|
+
return value
|
|
19
|
+
},
|
|
20
|
+
set(newValue) {
|
|
21
|
+
|
|
22
|
+
if( new Date().getTime() - ts < time ) return
|
|
23
|
+
|
|
24
|
+
value = newValue
|
|
25
|
+
track()
|
|
26
|
+
trigger()
|
|
27
|
+
ts = new Date().getTime()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function debounceRef(value: any, delay: number) {
|
|
35
|
+
|
|
36
|
+
let timer: any
|
|
37
|
+
|
|
38
|
+
return customRef((track, trigger) => {
|
|
39
|
+
return {
|
|
40
|
+
get() {
|
|
41
|
+
track()
|
|
42
|
+
return value
|
|
43
|
+
},
|
|
44
|
+
set(newValue) {
|
|
45
|
+
clearTimeout(timer)
|
|
46
|
+
timer = setTimeout(() => {
|
|
47
|
+
value = newValue
|
|
48
|
+
track()
|
|
49
|
+
trigger()
|
|
50
|
+
}, delay)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
}
|