@talex-touch/utils 1.0.3 → 1.0.6
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 +1 -1
- package/eventbus/index.ts +2 -2
- package/package.json +29 -29
- package/permission/index.ts +49 -0
- package/plugin/channel.ts +22 -13
- package/plugin/index.ts +27 -0
- package/plugin/preload.ts +7 -4
- package/plugin/sdk/common.ts +30 -0
- package/plugin/sdk/hooks/index.ts +1 -0
- package/plugin/sdk/hooks/life-cycle.ts +96 -0
- package/plugin/sdk/index.ts +13 -0
- package/plugin/sdk/service/index.ts +30 -0
- package/service/index.ts +68 -0
- package/service/protocol/index.ts +78 -0
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
|
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
|
@@ -1,29 +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.
|
|
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.
|
|
24
|
-
},
|
|
25
|
-
"peerDependencies": {
|
|
26
|
-
"vue": "^3.2.47",
|
|
27
|
-
"electron": "^24.4.0"
|
|
28
|
-
}
|
|
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.6",
|
|
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.3.4"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"vue": "^3.2.47",
|
|
27
|
+
"electron": "^24.4.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface Permission {
|
|
2
|
+
/**
|
|
3
|
+
* permission id
|
|
4
|
+
*/
|
|
5
|
+
id: symbol;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* permission name
|
|
9
|
+
*/
|
|
10
|
+
name: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* permission description
|
|
14
|
+
*/
|
|
15
|
+
description: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IPermissionCenter {
|
|
19
|
+
/**
|
|
20
|
+
* add a permission
|
|
21
|
+
* @param pluginScope plugin name
|
|
22
|
+
* @param permission permission
|
|
23
|
+
* @throws if permission already exists
|
|
24
|
+
*/
|
|
25
|
+
addPermission(pluginScope: string, permission: Permission): void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* remove a permission
|
|
29
|
+
* @param pluginScope plugin name
|
|
30
|
+
* @param permission permission
|
|
31
|
+
* @throws if permission not exists
|
|
32
|
+
*/
|
|
33
|
+
delPermission(pluginScope: string, permission: Permission): void;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* if pluginScope has permission
|
|
37
|
+
* @param pluginScope plugin name
|
|
38
|
+
* @param permission permission
|
|
39
|
+
*/
|
|
40
|
+
hasPermission(pluginScope: string, permission: Permission): boolean;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* get permission
|
|
44
|
+
* @param pluginScope plugin name
|
|
45
|
+
* @param permission permission id
|
|
46
|
+
* @returns permission
|
|
47
|
+
*/
|
|
48
|
+
getPermission(pluginScope: string, permission: symbol): Permission;
|
|
49
|
+
}
|
package/plugin/channel.ts
CHANGED
|
@@ -18,13 +18,13 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
18
18
|
constructor(pluginName: string) {
|
|
19
19
|
this.plugin = pluginName;
|
|
20
20
|
|
|
21
|
-
ipcRenderer.on("@
|
|
21
|
+
ipcRenderer.on("@plugin-process-message", this.__handle_main.bind(this));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
__parse_raw_data(e, arg): RawStandardChannelData | null {
|
|
25
|
-
|
|
24
|
+
__parse_raw_data(e: typeof IpcMainEvent, arg: any): RawStandardChannelData | null {
|
|
25
|
+
console.log("Raw data: ", arg, e);
|
|
26
26
|
if (arg) {
|
|
27
|
-
const { name, header, code,
|
|
27
|
+
const { name, header, code, data, sync } = arg;
|
|
28
28
|
|
|
29
29
|
if (header) {
|
|
30
30
|
return {
|
|
@@ -36,7 +36,6 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
36
36
|
sync,
|
|
37
37
|
code,
|
|
38
38
|
data,
|
|
39
|
-
plugin,
|
|
40
39
|
name: name as string,
|
|
41
40
|
};
|
|
42
41
|
}
|
|
@@ -47,7 +46,8 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
47
46
|
// throw new Error("Invalid message!");
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
__handle_main(e: typeof IpcMainEvent,
|
|
49
|
+
__handle_main(e: typeof IpcMainEvent, _arg: any): any {
|
|
50
|
+
const arg = JSON.parse(_arg)
|
|
51
51
|
const rawData = this.__parse_raw_data(e, arg);
|
|
52
52
|
if ( !rawData ) return
|
|
53
53
|
|
|
@@ -57,13 +57,13 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
57
57
|
return this.pendingMap.get(id)?.(rawData);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
if ( rawData.plugin !== this.plugin ) return
|
|
60
|
+
// if ( rawData.plugin !== this.plugin ) return
|
|
61
61
|
|
|
62
62
|
this.channelMap.get(rawData.name)?.forEach((func) => {
|
|
63
63
|
const handInData: StandardChannelData = {
|
|
64
|
-
reply: (code: DataCode, data: any
|
|
64
|
+
reply: (code: DataCode, data: any) => {
|
|
65
65
|
e.sender.send(
|
|
66
|
-
"@
|
|
66
|
+
"@plugin-process-message",
|
|
67
67
|
this.__parse_sender(code, rawData, data, rawData.sync)
|
|
68
68
|
);
|
|
69
69
|
},
|
|
@@ -148,9 +148,9 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
148
148
|
|
|
149
149
|
return new Promise((resolve) => {
|
|
150
150
|
|
|
151
|
-
ipcRenderer.send("@
|
|
151
|
+
ipcRenderer.send("@plugin-process-message", data);
|
|
152
152
|
|
|
153
|
-
this.pendingMap.set(uniqueId, (res) => {
|
|
153
|
+
this.pendingMap.set(uniqueId, (res: any) => {
|
|
154
154
|
this.pendingMap.delete(uniqueId);
|
|
155
155
|
|
|
156
156
|
resolve(res.data);
|
|
@@ -170,7 +170,7 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
170
170
|
},
|
|
171
171
|
} as RawStandardChannelData;
|
|
172
172
|
|
|
173
|
-
const res = this.__parse_raw_data(null, ipcRenderer.sendSync("@
|
|
173
|
+
const res = this.__parse_raw_data(null, ipcRenderer.sendSync("@plugin-process-message", data))!
|
|
174
174
|
|
|
175
175
|
if ( res.header.status === 'reply' ) return res.data;
|
|
176
176
|
|
|
@@ -179,4 +179,13 @@ class TouchChannel implements ITouchClientChannel {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
let touchChannel: ITouchClientChannel
|
|
183
|
+
|
|
184
|
+
export function genChannel() {
|
|
185
|
+
if (!touchChannel) {
|
|
186
|
+
// @ts-ignore
|
|
187
|
+
touchChannel = window.$channel = new TouchChannel(window.$plugin.name)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return touchChannel
|
|
191
|
+
}
|
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,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { genChannel } from './channel'
|
|
2
|
+
import './sdk/index'
|
|
2
3
|
|
|
3
4
|
// window type
|
|
4
5
|
declare global {
|
|
@@ -30,7 +31,9 @@ export function init(window: Window) {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export function initBridge(window: Window) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
window.$
|
|
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)
|
|
36
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * as LifeCycle from './life-cycle'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { genChannel } from './../../channel';
|
|
2
|
+
|
|
3
|
+
export enum LifecycleHooks {
|
|
4
|
+
ENABLE = 'en',
|
|
5
|
+
DISABLE = 'di',
|
|
6
|
+
ACTIVE = 'ac',
|
|
7
|
+
INACTIVE = 'in',
|
|
8
|
+
// FORE_PAUSED = 'fp',
|
|
9
|
+
CRASH = 'cr'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
export function injectHook(type: LifecycleHooks, hook: Function, processFunc = ({ data, reply }) => {
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
const hooks: Array<Function> = window.$touchSDK.__hooks[type]
|
|
16
|
+
if (hooks) {
|
|
17
|
+
hooks.forEach(hook => hook(data))
|
|
18
|
+
}
|
|
19
|
+
reply(true)
|
|
20
|
+
}) {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
const __hooks = window.$touchSDK.__hooks
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const hooks: Array<Function> = __hooks[type] || (__hooks[type] = [])
|
|
25
|
+
|
|
26
|
+
if (hooks.length === 0) {
|
|
27
|
+
|
|
28
|
+
genChannel().regChannel("@lifecycle:" + type, (obj: any) => {
|
|
29
|
+
|
|
30
|
+
processFunc(obj)
|
|
31
|
+
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
delete window.$touchSDK.__hooks[type]
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const wrappedHook = (data: any) => {
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
|
|
42
|
+
hook(data)
|
|
43
|
+
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error(`[TouchSDK] ${type} hook error: `, e)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
hooks.push(wrappedHook)
|
|
51
|
+
|
|
52
|
+
return wrappedHook
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const createHook = <T extends Function = (data: any) => any>(type: LifecycleHooks) => (hook: T) => injectHook(type, hook)
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The plugin is enabled
|
|
59
|
+
* When the plugin is enabled, the plugin can be used
|
|
60
|
+
* @returns void
|
|
61
|
+
*/
|
|
62
|
+
export const onPluginEnable = createHook(LifecycleHooks.ENABLE)
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The plugin is disabled
|
|
66
|
+
* When the plugin is disabled, the plugin can not be used
|
|
67
|
+
* @returns void
|
|
68
|
+
*/
|
|
69
|
+
export const onPluginDisable = createHook(LifecycleHooks.DISABLE)
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The plugin is activated
|
|
73
|
+
* @returns boolean If return false, the plugin will not be activated (User can force to activate the plugin)
|
|
74
|
+
*/
|
|
75
|
+
export const onPluginActive = createHook(LifecycleHooks.ACTIVE)
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The plugin is inactivated
|
|
79
|
+
* @returns boolean If return false, the plugin will not be inactivated (User can force to inactivate the plugin)
|
|
80
|
+
*/
|
|
81
|
+
export const onPluginInactive = createHook(LifecycleHooks.INACTIVE)
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* When plugin is in foreground (e.g. plugin is using media, camera, microphone, etc.) But paused by user
|
|
85
|
+
* For a detail example: User force to stop music playing
|
|
86
|
+
* @returns void
|
|
87
|
+
*/
|
|
88
|
+
// export const onForePaused = createHook(LifecycleHooks.FORE_PAUSED)
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* When plugin is crashed
|
|
92
|
+
* data.message Crash message
|
|
93
|
+
* data.extraData Crash data
|
|
94
|
+
* @returns void
|
|
95
|
+
*/
|
|
96
|
+
export const onCrash = createHook(LifecycleHooks.CRASH)
|
|
@@ -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
|
+
}
|
package/service/index.ts
ADDED
|
@@ -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
|
+
}
|