@talex-touch/utils 1.0.14 → 1.0.15

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.
Files changed (41) hide show
  1. package/base/index.ts +181 -181
  2. package/channel/index.ts +108 -99
  3. package/common/index.ts +2 -39
  4. package/common/storage/constants.ts +3 -0
  5. package/common/storage/entity/app-settings.ts +47 -0
  6. package/common/storage/entity/index.ts +1 -0
  7. package/common/storage/index.ts +3 -0
  8. package/common/utils.ts +160 -0
  9. package/core-box/README.md +218 -0
  10. package/core-box/index.ts +7 -0
  11. package/core-box/search.ts +536 -0
  12. package/core-box/types.ts +384 -0
  13. package/electron/download-manager.ts +118 -0
  14. package/{common → electron}/env-tool.ts +56 -56
  15. package/electron/touch-core.ts +167 -0
  16. package/electron/window.ts +71 -0
  17. package/eventbus/index.ts +86 -87
  18. package/index.ts +5 -0
  19. package/package.json +55 -30
  20. package/permission/index.ts +48 -48
  21. package/plugin/channel.ts +203 -193
  22. package/plugin/index.ts +216 -121
  23. package/plugin/log/logger-manager.ts +60 -0
  24. package/plugin/log/logger.ts +75 -0
  25. package/plugin/log/types.ts +27 -0
  26. package/plugin/preload.ts +39 -39
  27. package/plugin/sdk/common.ts +27 -27
  28. package/plugin/sdk/hooks/life-cycle.ts +95 -95
  29. package/plugin/sdk/index.ts +18 -13
  30. package/plugin/sdk/service/index.ts +29 -29
  31. package/plugin/sdk/types.ts +578 -0
  32. package/plugin/sdk/window/index.ts +40 -40
  33. package/renderer/index.ts +2 -0
  34. package/renderer/ref.ts +54 -54
  35. package/renderer/slots.ts +124 -0
  36. package/renderer/storage/app-settings.ts +34 -0
  37. package/renderer/storage/base-storage.ts +335 -0
  38. package/renderer/storage/index.ts +1 -0
  39. package/search/types.ts +726 -0
  40. package/service/index.ts +67 -67
  41. package/service/protocol/index.ts +77 -77
package/plugin/index.ts CHANGED
@@ -1,121 +1,216 @@
1
- import { Arch, SupportOS } from './../base/index';
2
- export enum PluginStatus {
3
- DISABLED,
4
- DISABLING,
5
-
6
- CRASHED,
7
-
8
- ENABLED,
9
- ACTIVE,
10
-
11
- LOADING,
12
- LOADED,
13
- }
14
-
15
- export interface IPluginIcon {
16
- type: string | 'remixicon' | 'class'
17
- value: any
18
-
19
- init(): Promise<void>
20
- }
21
-
22
- export interface IPlatformInfo {
23
- enable: boolean
24
- arch: Arch[]
25
- os: SupportOS[]
26
- }
27
-
28
- export type PlatformKey = 'win' | 'darwin' | 'linux'
29
-
30
- export type IPlatform = {
31
- [key in PlatformKey]?: IPlatformInfo
32
- }
33
-
34
- export interface IPluginBaseInfo {
35
- name: string
36
- readme: string
37
- version: string
38
- desc: string
39
- icon: IPluginIcon
40
- platforms: IPlatform
41
- }
42
-
43
- export interface IPluginDev {
44
- enable: boolean
45
- address: string
46
- }
47
-
48
- export interface IPluginWebview {
49
- }
50
-
51
- export interface ITouchPlugin extends IPluginBaseInfo {
52
- dev: IPluginDev
53
- webViewInit: boolean
54
- webview: IPluginWebview
55
- features: IPluginFeature[]
56
-
57
- addFeature(feature: IPluginFeature): boolean
58
- delFeature(featureId: string): boolean
59
- getFeature(featureId: string): IPluginFeature | null
60
- getFeatures(): IPluginFeature[]
61
-
62
- get status(): PluginStatus
63
- set status(v: PluginStatus)
64
-
65
- enable(): Promise<boolean>
66
- disable(): Promise<boolean>
67
- }
68
-
69
- export interface IFeatureCommand {
70
- type: "match" | "contain" | "regex" | "function" | "over" | "image" | "files" | "directory" | "window"
71
- value: string | string[] | RegExp | Function
72
- onTrigger(): void
73
- }
74
-
75
- export interface IPluginFeature {
76
- id: string
77
- name: string
78
- desc: string
79
- icon: IPluginIcon
80
- push: boolean
81
- platform: IPlatform
82
- commands: IFeatureCommand[]
83
- }
84
-
85
- export interface IPluginManager {
86
- plugins: Map<string, ITouchPlugin>
87
- active: string | null
88
- pluginPath: string
89
-
90
- setActivePlugin(pluginName: string): boolean
91
-
92
- loadPlugin(pluginName: string): Promise<boolean>
93
- unloadPlugin(pluginName: string): Promise<boolean>
94
- }
95
-
96
- export interface IManifest {
97
- name: string
98
- version: string
99
- description: string
100
- plugin?: {
101
- dev: {
102
- enable: boolean
103
- address: string
104
- }
105
- }
106
- build?: {
107
- files: string[]
108
- secret: {
109
- pos: string
110
- addon: string[]
111
- }
112
- verify?: {
113
- enable: boolean
114
- online: 'custom' | 'always' | 'once'
115
- }
116
- version?: {
117
- update: 'auto' | 'ask' | 'readable'
118
- downgrade: boolean
119
- }
120
- }
121
- }
1
+ import { Arch, SupportOS } from './../base/index';
2
+ import { PluginLogger } from './log/logger';
3
+
4
+ export enum PluginStatus {
5
+ DISABLED,
6
+ DISABLING,
7
+
8
+ CRASHED,
9
+
10
+ ENABLED,
11
+ ACTIVE,
12
+
13
+ LOADING,
14
+ LOADED,
15
+ }
16
+
17
+ export interface IPluginIcon {
18
+ type: string | 'remixicon' | 'class'
19
+ value: any
20
+
21
+ init(): Promise<void>
22
+ }
23
+
24
+ export interface IPlatformInfo {
25
+ enable: boolean
26
+ arch: Arch[]
27
+ os: SupportOS[]
28
+ }
29
+
30
+ export type PlatformKey = 'win' | 'darwin' | 'linux'
31
+
32
+ export type IPlatform = {
33
+ [key in PlatformKey]?: IPlatformInfo
34
+ }
35
+
36
+ export interface IPluginBaseInfo {
37
+ name: string
38
+ readme: string
39
+ version: string
40
+ desc: string
41
+ icon: IPluginIcon
42
+ platforms: IPlatform
43
+ }
44
+
45
+ export interface IPluginDev {
46
+ enable: boolean
47
+ address: string
48
+ }
49
+
50
+ export interface IPluginWebview {
51
+ }
52
+
53
+
54
+
55
+ export interface ITouchPlugin extends IPluginBaseInfo {
56
+ dev: IPluginDev
57
+ webViewInit: boolean
58
+ logger: PluginLogger
59
+ webview: IPluginWebview
60
+ features: IPluginFeature[]
61
+
62
+ addFeature(feature: IPluginFeature): boolean
63
+ delFeature(featureId: string): boolean
64
+ getFeature(featureId: string): IPluginFeature | null
65
+ getFeatures(): IPluginFeature[]
66
+ triggerFeature(feature: IPluginFeature, query: any): void
67
+ triggerInputChanged(feature: IPluginFeature, query: any): void
68
+
69
+ get status(): PluginStatus
70
+ set status(v: PluginStatus)
71
+
72
+ enable(): Promise<boolean>
73
+ disable(): Promise<boolean>
74
+ }
75
+
76
+ export interface IFeatureCommand {
77
+ type: "match" | "contain" | "regex" | "function" | "over" | "image" | "files" | "directory" | "window"
78
+ value: string | string[] | RegExp | Function
79
+ onTrigger(): void
80
+ }
81
+
82
+ export interface IPluginFeature {
83
+ id: string
84
+ name: string
85
+ desc: string
86
+ icon: IPluginIcon
87
+ push: boolean
88
+ platform: IPlatform
89
+ commands: IFeatureCommand[]
90
+ }
91
+
92
+ /**
93
+ * Lifecycle hooks for a feature's behavior within the launcher environment.
94
+ * These hooks are triggered based on real user interaction and system events.
95
+ */
96
+ export interface IFeatureLifeCycle {
97
+ /**
98
+ * Called when a feature is actively launched from the launcher.
99
+ * Can be used to prepare data or UI specific to this session.
100
+ * @param feature - The feature instance being launched
101
+ */
102
+ onLaunch?(feature: IPluginFeature): void
103
+
104
+ /**
105
+ * Called when a feature is triggered via a matching command.
106
+ * @param id - Feature ID
107
+ * @param data - The triggering payload
108
+ * @param feature - The full feature definition
109
+ */
110
+ onFeatureTriggered(id: string, data: any, feature: IPluginFeature): void
111
+
112
+ /**
113
+ * Called when user input changes within this feature’s input box.
114
+ * For example, search text or commands typed.
115
+ * @param input - The new input value
116
+ */
117
+ onInputChanged?(input: string): void
118
+
119
+ /**
120
+ * Called when a user selects or clicks an actionable item inside the feature.
121
+ * For example, selecting a suggestion or executing an option.
122
+ * @param actionId - A string identifier for the clicked action
123
+ * @param data - Optional payload associated with that action
124
+ */
125
+ onActionClick?(actionId: string, data?: any): void
126
+
127
+ /**
128
+ * Called when the feature is manually closed by the user or by the system.
129
+ * Useful for cleanup or state saving.
130
+ * @param feature - The feature instance being closed
131
+ */
132
+ onClose?(feature: IPluginFeature): void
133
+ }
134
+
135
+ /**
136
+ * Lifecycle hooks for the feature's behavior within the launcher environment.
137
+ * These hooks are triggered based on real user interaction and system events.
138
+ */
139
+ export interface ITargetFeatureLifeCycle {
140
+ /**
141
+ * Called when the feature is actively launched from the launcher.
142
+ * Can be used to prepare data or UI specific to this session.
143
+ * @param feature - The feature instance being launched
144
+ */
145
+ onLaunch?(feature: IPluginFeature): void
146
+
147
+ /**
148
+ * Called when the feature is triggered via a matching command.
149
+ * @param data - The triggering payload
150
+ * @param feature - The full feature definition
151
+ */
152
+ onFeatureTriggered(data: any, feature: IPluginFeature): void
153
+
154
+ /**
155
+ * Called when user input changes within this feature’s input box.
156
+ * For example, search text or commands typed.
157
+ * @param input - The new input value
158
+ */
159
+ onInputChanged?(input: string): void
160
+
161
+ /**
162
+ * Called when a user selects or clicks an actionable item inside the feature.
163
+ * For example, selecting a suggestion or executing an option.
164
+ * @param actionId - A string identifier for the clicked action
165
+ * @param data - Optional payload associated with that action
166
+ */
167
+ onActionClick?(actionId: string, data?: any): void
168
+
169
+ /**
170
+ * Called when the feature is manually closed by the user or by the system.
171
+ * Useful for cleanup or state saving.
172
+ * @param feature - The feature instance being closed
173
+ */
174
+ onClose?(feature: IPluginFeature): void
175
+ }
176
+
177
+ export interface IPluginManager {
178
+ plugins: Map<string, ITouchPlugin>
179
+ active: string | null
180
+ pluginPath: string
181
+
182
+ setActivePlugin(pluginName: string): boolean
183
+
184
+ loadPlugin(pluginName: string): Promise<boolean>
185
+ unloadPlugin(pluginName: string): Promise<boolean>
186
+ }
187
+
188
+ export interface IManifest {
189
+ name: string
190
+ version: string
191
+ description: string
192
+ plugin?: {
193
+ dev: {
194
+ enable: boolean
195
+ address: string
196
+ }
197
+ }
198
+ build?: {
199
+ files: string[]
200
+ secret: {
201
+ pos: string
202
+ addon: string[]
203
+ }
204
+ verify?: {
205
+ enable: boolean
206
+ online: 'custom' | 'always' | 'once'
207
+ }
208
+ version?: {
209
+ update: 'auto' | 'ask' | 'readable'
210
+ downgrade: boolean
211
+ }
212
+ }
213
+ }
214
+
215
+ export * from './log/logger'
216
+ export * from './sdk/index'
@@ -0,0 +1,60 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { LogItem } from './types'
4
+
5
+ /**
6
+ * LoggerManager is responsible for managing and writing logs for all plugins.
7
+ */
8
+ export class LoggerManager {
9
+ private readonly logDir: string
10
+ private readonly sessionLogPath: string
11
+ private buffer: LogItem[] = []
12
+ private flushInterval: NodeJS.Timeout
13
+
14
+ /**
15
+ * Initializes a new LoggerManager instance.
16
+ * @param baseDir - Base directory to store logs.
17
+ */
18
+ constructor(baseDir: string) {
19
+ this.logDir = path.resolve(baseDir, 'logs')
20
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
21
+ this.sessionLogPath = path.resolve(this.logDir, `${timestamp}.log`)
22
+ this.ensureDirectory()
23
+ this.flushInterval = setInterval(() => this.flush(), 5000)
24
+ }
25
+
26
+ /**
27
+ * Appends a new log item to the buffer.
28
+ * @param log - The log entry to append.
29
+ */
30
+ append(log: LogItem): void {
31
+ this.buffer.push(log)
32
+ }
33
+
34
+ /**
35
+ * Flushes all buffered log items to the current session log file.
36
+ */
37
+ flush(): void {
38
+ if (this.buffer.length === 0) return
39
+ const lines = this.buffer.map((item) => JSON.stringify(item)).join('\n') + '\n'
40
+ fs.appendFileSync(this.sessionLogPath, lines)
41
+ this.buffer = []
42
+ }
43
+
44
+ /**
45
+ * Stops the flush interval and ensures remaining logs are written.
46
+ */
47
+ destroy(): void {
48
+ clearInterval(this.flushInterval)
49
+ this.flush()
50
+ }
51
+
52
+ /**
53
+ * Ensures the log directory exists.
54
+ */
55
+ private ensureDirectory(): void {
56
+ if (!fs.existsSync(this.logDir)) {
57
+ fs.mkdirSync(this.logDir, { recursive: true })
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,75 @@
1
+ import { LogLevel, LogItem, LogDataType } from './types'
2
+ import { LoggerManager } from './logger-manager'
3
+
4
+ /**
5
+ * PluginLogger provides structured logging capabilities for individual plugins.
6
+ */
7
+ export class PluginLogger {
8
+ private readonly pluginName: string
9
+ private readonly manager: LoggerManager
10
+
11
+ /**
12
+ * Get logger manager
13
+ */
14
+ getManager(): LoggerManager { return this.manager }
15
+
16
+ /**
17
+ * Creates an instance of PluginLogger.
18
+ * @param pluginName - The name of the plugin.
19
+ * @param manager - The logger manager instance controlling log file storage.
20
+ */
21
+ constructor(pluginName: string, manager: LoggerManager) {
22
+ this.pluginName = pluginName
23
+ this.manager = manager
24
+ }
25
+
26
+ /**
27
+ * Logs an info-level message.
28
+ * @param args - The log message and optional data payload.
29
+ */
30
+ info(...args: LogDataType[]): void {
31
+ this.log('INFO', ...args)
32
+ }
33
+
34
+ /**
35
+ * Logs a warning-level message.
36
+ * @param args - The log message and optional data payload.
37
+ */
38
+ warn(...args: LogDataType[]): void {
39
+ this.log('WARN', ...args)
40
+ }
41
+
42
+ /**
43
+ * Logs an error-level message.
44
+ * @param args - The log message and optional data payload.
45
+ */
46
+ error(...args: LogDataType[]): void {
47
+ this.log('ERROR', ...args)
48
+ }
49
+
50
+ /**
51
+ * Logs a debug-level message.
52
+ * @param args - The log message and optional data payload.
53
+ */
54
+ debug(...args: LogDataType[]): void {
55
+ this.log('DEBUG', ...args)
56
+ }
57
+
58
+ /**
59
+ * Constructs a log entry and forwards it to the manager.
60
+ * @param level - The severity level of the log.
61
+ * @param args - The log message and optional data payload.
62
+ */
63
+ private log(level: LogLevel, ...args: LogDataType[]): void {
64
+ const [message, ...data] = args
65
+ const log: LogItem = {
66
+ timestamp: new Date().toISOString(),
67
+ level,
68
+ plugin: this.pluginName,
69
+ message: String(message),
70
+ tags: [],
71
+ data,
72
+ }
73
+ this.manager.append(log)
74
+ }
75
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Defines supported logging levels.
3
+ */
4
+ export type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'DEBUG'
5
+
6
+ /**
7
+ * Supported data types for logging arguments.
8
+ */
9
+ export type LogDataType = string | number | boolean | object
10
+
11
+ /**
12
+ * Represents a single log entry for a plugin.
13
+ */
14
+ export interface LogItem {
15
+ /** ISO timestamp when the log was created */
16
+ timestamp: string
17
+ /** Logging severity level */
18
+ level: LogLevel
19
+ /** Plugin name */
20
+ plugin: string
21
+ /** Main log message */
22
+ message: string
23
+ /** Optional log tags for filtering and UI grouping */
24
+ tags: string[]
25
+ /** Additional log data (parameters, configs, responses) */
26
+ data: LogDataType[]
27
+ }
package/plugin/preload.ts CHANGED
@@ -1,39 +1,39 @@
1
- import { genChannel } from './channel'
2
- import './sdk/index'
3
-
4
- // window type
5
- declare global {
6
- export interface Window {
7
- $plugin: {
8
- name: string
9
- path: Object
10
- }
11
- $send: (type: string, data: any) => void
12
- $sendSync: (type: string, data: any) => Promise<any>
13
- $regChannel: (type: string, callback: Function) => void
14
- $crash: (message: string, extraData: any) => void
15
- $config: {
16
- themeStyle: any
17
- }
18
- }
19
- }
20
-
21
- export function init(window: Window) {
22
- const plugin = window.$plugin
23
- if (!plugin)
24
- throw new Error('Plugin has a fatal error! Please check your plugin!')
25
-
26
- window.$crash = function (message, extraData) {
27
- window.$send('crash', { message, ...extraData })
28
- }
29
-
30
- initBridge(window)
31
- }
32
-
33
- export function initBridge(window: 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)
39
- }
1
+ import { genChannel } from './channel'
2
+ import './sdk/index'
3
+
4
+ // window type
5
+ declare global {
6
+ export interface Window {
7
+ $plugin: {
8
+ name: string
9
+ path: Object
10
+ }
11
+ $send: (type: string, data: any) => void
12
+ $sendSync: (type: string, data: any) => Promise<any>
13
+ $regChannel: (type: string, callback: Function) => void
14
+ $crash: (message: string, extraData: any) => void
15
+ $config: {
16
+ themeStyle: any
17
+ }
18
+ }
19
+ }
20
+
21
+ export function init(window: Window) {
22
+ const plugin = window.$plugin
23
+ if (!plugin)
24
+ throw new Error('Plugin has a fatal error! Please check your plugin!')
25
+
26
+ window.$crash = function (message, extraData) {
27
+ window.$send('crash', { message, ...extraData })
28
+ }
29
+
30
+ initBridge(window)
31
+ }
32
+
33
+ export function initBridge(window: 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)
39
+ }
@@ -1,28 +1,28 @@
1
- import { genChannel } from '../channel';
2
- import { IPluginFeature } from '../index'
3
-
4
- export function regShortcut(key: string, func: Function) {
5
- const channel = genChannel()
6
-
7
- const res = channel.sendSync('shortcon:reg', { key })
8
- if ( res instanceof String ) throw new Error(String(res))
9
- if ( res === false ) return false;
10
-
11
- channel.regChannel('shortcon:trigger', ({ data }) => key === data.key && func())
12
-
13
- return true;
14
- }
15
-
16
- export function regFeature(feature: IPluginFeature): boolean {
17
- const channel = genChannel()
18
-
19
- return channel.sendSync('feature:reg', { feature })
20
- }
21
-
22
- export function unRegFeature(id: string): boolean {
23
- const channel = genChannel()
24
-
25
- return channel.sendSync('feature:unreg', { feature: id })
26
- }
27
-
1
+ import { genChannel } from '../channel';
2
+ import { IPluginFeature } from '../index'
3
+
4
+ export function regShortcut(key: string, func: Function) {
5
+ const channel = genChannel()
6
+
7
+ const res = channel.sendSync('shortcon:reg', { key })
8
+ if ( res instanceof String ) throw new Error(String(res))
9
+ if ( res === false ) return false;
10
+
11
+ channel.regChannel('shortcon:trigger', ({ data }) => key === data.key && func())
12
+
13
+ return true;
14
+ }
15
+
16
+ export function regFeature(feature: IPluginFeature): boolean {
17
+ const channel = genChannel()
18
+
19
+ return channel.sendSync('feature:reg', { feature })
20
+ }
21
+
22
+ export function unRegFeature(id: string): boolean {
23
+ const channel = genChannel()
24
+
25
+ return channel.sendSync('feature:unreg', { feature: id })
26
+ }
27
+
28
28
  export * from './window';