plusui-native-core 0.1.66 → 0.1.68
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/Core/API/Connect_API.ts +160 -0
- package/Core/API/index.ts +127 -0
- package/Core/Features/App/app.ts +192 -131
- package/Core/Features/Clipboard/clipboard.ts +92 -127
- package/Core/Features/Connection/README.md +111 -214
- package/Core/Features/Connection/connect.ts +190 -272
- package/Core/Features/Display/display.ts +142 -116
- package/Core/Features/FileDrop/filedrop.ts +163 -283
- package/Core/Features/Keyboard/keyboard.ts +194 -186
- package/Core/Features/Menu/menu.ts +233 -420
- package/Core/Features/Router/router.ts +125 -0
- package/Core/Features/Tray/tray.ts +102 -80
- package/Core/Features/WebGPU/webgpu.ts +283 -1024
- package/Core/Features/Window/window.ts +207 -156
- package/package.json +5 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlusUI Connect API - Custom User Channels
|
|
3
|
+
*
|
|
4
|
+
* This is for user-defined channels generated by `plusui connect` tool.
|
|
5
|
+
* Built-in features (window, clipboard, etc.) use direct methods only.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { createChannel, connect } from '@plusui/api';
|
|
9
|
+
*
|
|
10
|
+
* // Create a custom channel
|
|
11
|
+
* const search = createChannel('search');
|
|
12
|
+
* search.emit({ query: 'test' });
|
|
13
|
+
* search.on((result) => { ... });
|
|
14
|
+
*
|
|
15
|
+
* // Or use connect directly
|
|
16
|
+
* connect.emit('myEvent', { data: 123 });
|
|
17
|
+
* connect.on('myEvent', (data) => { ... });
|
|
18
|
+
*
|
|
19
|
+
* The `plusui connect` CLI tool scans your codebase for:
|
|
20
|
+
* - TypeScript: name.on() and name.emit()
|
|
21
|
+
* - C++: name.on() and name.emit()
|
|
22
|
+
* And generates typed channel objects for both frontend and backend.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { _client } from '../Features/Connection/connect';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Channel object returned by createChannel()
|
|
29
|
+
* Mirrors the C++ Connect::Channel API
|
|
30
|
+
*/
|
|
31
|
+
export interface Channel<T = unknown> {
|
|
32
|
+
/**
|
|
33
|
+
* Listen for messages on this channel
|
|
34
|
+
* @param callback - Function called when message is received
|
|
35
|
+
* @returns Unsubscribe function
|
|
36
|
+
*/
|
|
37
|
+
on(callback: (data: T) => void): () => void;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Send a message on this channel
|
|
41
|
+
* @param data - Data to send
|
|
42
|
+
*/
|
|
43
|
+
emit(data: T): void;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Channel name
|
|
47
|
+
*/
|
|
48
|
+
readonly name: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create a named channel object
|
|
53
|
+
*
|
|
54
|
+
* @param name - Channel name (must match backend)
|
|
55
|
+
* @returns Channel object with .on() and .emit()
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const download = createChannel<DownloadProgress>('download');
|
|
59
|
+
* download.emit({ url: 'https://example.com/file.zip' });
|
|
60
|
+
* download.on((progress) => console.log(progress.percent));
|
|
61
|
+
*/
|
|
62
|
+
export function createChannel<T = unknown>(name: string): Channel<T> {
|
|
63
|
+
return {
|
|
64
|
+
name,
|
|
65
|
+
on: (callback: (data: T) => void): (() => void) => {
|
|
66
|
+
return _client.on<T>(name, callback);
|
|
67
|
+
},
|
|
68
|
+
emit: (data: T): void => {
|
|
69
|
+
_client.fire(name, data);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Direct connect API for custom channels
|
|
76
|
+
*
|
|
77
|
+
* Use this for quick one-off events, or use createChannel()
|
|
78
|
+
* for typed, reusable channel objects.
|
|
79
|
+
*/
|
|
80
|
+
export const connect = {
|
|
81
|
+
/**
|
|
82
|
+
* Send a message on a channel
|
|
83
|
+
* @param name - Channel name
|
|
84
|
+
* @param data - Data to send
|
|
85
|
+
*/
|
|
86
|
+
emit: <T = unknown>(name: string, data: T): void => {
|
|
87
|
+
_client.fire(name, data);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Listen for messages on a channel
|
|
92
|
+
* @param name - Channel name
|
|
93
|
+
* @param callback - Function called when message is received
|
|
94
|
+
* @returns Unsubscribe function
|
|
95
|
+
*/
|
|
96
|
+
on: <T = unknown>(name: string, callback: (data: T) => void): (() => void) => {
|
|
97
|
+
return _client.on<T>(name, callback);
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Make a call and wait for response
|
|
102
|
+
* @param name - Channel name
|
|
103
|
+
* @param data - Request data
|
|
104
|
+
* @returns Promise with response
|
|
105
|
+
*/
|
|
106
|
+
call: <TResponse = unknown, TRequest = unknown>(name: string, data: TRequest): Promise<TResponse> => {
|
|
107
|
+
return _client.call<TResponse, TRequest>(name, data);
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Create a typed channel object
|
|
112
|
+
* @param name - Channel name
|
|
113
|
+
* @returns Channel object with .on() and .emit()
|
|
114
|
+
*/
|
|
115
|
+
channel: <T = unknown>(name: string): Channel<T> => {
|
|
116
|
+
return createChannel<T>(name);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Feature-scoped connect
|
|
122
|
+
*
|
|
123
|
+
* Creates a connect API that automatically prefixes all channel names
|
|
124
|
+
* with a scope. Useful for organizing channels by feature.
|
|
125
|
+
*
|
|
126
|
+
* @param scope - Feature scope (e.g., 'auth', 'data', 'ui')
|
|
127
|
+
* @returns Scoped connect API
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* const authConnect = createFeatureConnect('auth');
|
|
131
|
+
* authConnect.emit('login', { user: 'john' }); // sends to 'auth.login'
|
|
132
|
+
* authConnect.on('logout', () => {}); // listens to 'auth.logout'
|
|
133
|
+
*/
|
|
134
|
+
export function createFeatureConnect(scope: string) {
|
|
135
|
+
const scopedName = (name: string): string => {
|
|
136
|
+
const prefix = `${scope}.`;
|
|
137
|
+
if (name.startsWith(prefix)) return name;
|
|
138
|
+
return prefix + name;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
emit: <T = unknown>(name: string, data: T): void => {
|
|
143
|
+
_client.fire(scopedName(name), data);
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
on: <T = unknown>(name: string, callback: (data: T) => void): (() => void) => {
|
|
147
|
+
return _client.on<T>(scopedName(name), callback);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
call: <TResponse = unknown, TRequest = unknown>(name: string, data: TRequest): Promise<TResponse> => {
|
|
151
|
+
return _client.call<TResponse, TRequest>(scopedName(name), data);
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
channel: <T = unknown>(name: string): Channel<T> => {
|
|
155
|
+
return createChannel<T>(scopedName(name));
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export default connect;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlusUI API - Unified Entry Point
|
|
3
|
+
*
|
|
4
|
+
* TWO DISTINCT PATTERNS:
|
|
5
|
+
*
|
|
6
|
+
* 1. BUILT-IN FEATURES - Direct methods only (NO .on/.emit)
|
|
7
|
+
* window.setTitle('My App');
|
|
8
|
+
* window.minimize();
|
|
9
|
+
* clipboard.setText('hello');
|
|
10
|
+
* window.onResize((size) => { ... });
|
|
11
|
+
*
|
|
12
|
+
* 2. CUSTOM CHANNELS - Use .on() and .emit()
|
|
13
|
+
* const search = createChannel('search');
|
|
14
|
+
* search.emit({ query: 'test' });
|
|
15
|
+
* search.on((result) => { ... });
|
|
16
|
+
*
|
|
17
|
+
* The `plusui connect` CLI scans your codebase for name.on() and name.emit()
|
|
18
|
+
* and generates typed channel objects for both frontend and backend.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// ============================================================
|
|
22
|
+
// BUILT-IN FEATURES - Direct methods only (NO .on/.emit)
|
|
23
|
+
// ============================================================
|
|
24
|
+
|
|
25
|
+
export { window } from '../Features/Window/window';
|
|
26
|
+
export { clipboard } from '../Features/Clipboard/clipboard';
|
|
27
|
+
export { keyboard } from '../Features/Keyboard/keyboard';
|
|
28
|
+
export { tray } from '../Features/Tray/tray';
|
|
29
|
+
export { display } from '../Features/Display/display';
|
|
30
|
+
export { fileDrop } from '../Features/FileDrop/filedrop';
|
|
31
|
+
export { menu } from '../Features/Menu/menu';
|
|
32
|
+
export { app } from '../Features/App/app';
|
|
33
|
+
export { gpu } from '../Features/WebGPU/webgpu';
|
|
34
|
+
|
|
35
|
+
// ============================================================
|
|
36
|
+
// CUSTOM CHANNELS - For user-defined events (uses .on/.emit)
|
|
37
|
+
// ============================================================
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
connect,
|
|
41
|
+
createChannel,
|
|
42
|
+
createFeatureConnect,
|
|
43
|
+
type Channel
|
|
44
|
+
} from './Connect_API';
|
|
45
|
+
|
|
46
|
+
// ============================================================
|
|
47
|
+
// TYPES - Re-exported for convenience
|
|
48
|
+
// ============================================================
|
|
49
|
+
|
|
50
|
+
export type {
|
|
51
|
+
WindowSize,
|
|
52
|
+
WindowPosition,
|
|
53
|
+
WindowRect,
|
|
54
|
+
WindowState,
|
|
55
|
+
WindowId
|
|
56
|
+
} from '../Features/Window/window';
|
|
57
|
+
|
|
58
|
+
export type {
|
|
59
|
+
ClipboardAPI
|
|
60
|
+
} from '../Features/Clipboard/clipboard';
|
|
61
|
+
|
|
62
|
+
export type {
|
|
63
|
+
KeyEvent,
|
|
64
|
+
Shortcut,
|
|
65
|
+
KeyEventCallback,
|
|
66
|
+
ShortcutCallback,
|
|
67
|
+
KeyCode,
|
|
68
|
+
KeyMod
|
|
69
|
+
} from '../Features/Keyboard/keyboard';
|
|
70
|
+
|
|
71
|
+
export type {
|
|
72
|
+
TrayMenuItem,
|
|
73
|
+
TrayIconData
|
|
74
|
+
} from '../Features/Tray/tray';
|
|
75
|
+
|
|
76
|
+
export type {
|
|
77
|
+
Display,
|
|
78
|
+
DisplayMode,
|
|
79
|
+
DisplayBounds,
|
|
80
|
+
DisplayResolution
|
|
81
|
+
} from '../Features/Display/display';
|
|
82
|
+
|
|
83
|
+
export type {
|
|
84
|
+
FileInfo,
|
|
85
|
+
DragEvent,
|
|
86
|
+
FileDropAPI
|
|
87
|
+
} from '../Features/FileDrop/filedrop';
|
|
88
|
+
|
|
89
|
+
export type {
|
|
90
|
+
MenuItem,
|
|
91
|
+
MenuItemType,
|
|
92
|
+
MenuBarData,
|
|
93
|
+
ContextMenuOptions,
|
|
94
|
+
ContextInfo
|
|
95
|
+
} from '../Features/Menu/menu';
|
|
96
|
+
|
|
97
|
+
export type {
|
|
98
|
+
AppConfig
|
|
99
|
+
} from '../Features/App/app';
|
|
100
|
+
|
|
101
|
+
export type {
|
|
102
|
+
GPUAdapter,
|
|
103
|
+
GPUDevice,
|
|
104
|
+
GPUBuffer,
|
|
105
|
+
GPUTexture,
|
|
106
|
+
GPUShaderModule,
|
|
107
|
+
GPURenderPipeline,
|
|
108
|
+
GPUComputePipeline,
|
|
109
|
+
GPUQueue,
|
|
110
|
+
GPUCommandEncoder
|
|
111
|
+
} from '../Features/WebGPU/webgpu';
|
|
112
|
+
|
|
113
|
+
// ============================================================
|
|
114
|
+
// HELPER FUNCTIONS
|
|
115
|
+
// ============================================================
|
|
116
|
+
|
|
117
|
+
export {
|
|
118
|
+
readFileAsText,
|
|
119
|
+
readFileAsDataUrl,
|
|
120
|
+
filterFilesByExtension,
|
|
121
|
+
filterFilesByMimeType,
|
|
122
|
+
isImageFile,
|
|
123
|
+
isVideoFile,
|
|
124
|
+
isAudioFile,
|
|
125
|
+
isTextFile,
|
|
126
|
+
formatFileSize
|
|
127
|
+
} from '../Features/FileDrop/filedrop';
|
package/Core/Features/App/app.ts
CHANGED
|
@@ -1,131 +1,192 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
1
|
+
/**
|
|
2
|
+
* App API - Application lifecycle
|
|
3
|
+
*
|
|
4
|
+
* Direct method calls - no .on/.emit
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { app } from '@plusui/api';
|
|
8
|
+
*
|
|
9
|
+
* app.quit();
|
|
10
|
+
* app.onReady(() => { ... });
|
|
11
|
+
* app.onQuit(() => { ... });
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface AppConfig {
|
|
15
|
+
title?: string;
|
|
16
|
+
width?: number;
|
|
17
|
+
height?: number;
|
|
18
|
+
resizable?: boolean;
|
|
19
|
+
devtools?: boolean;
|
|
20
|
+
trayIcon?: string;
|
|
21
|
+
trayTooltip?: string;
|
|
22
|
+
alwaysOnTop?: boolean;
|
|
23
|
+
centered?: boolean;
|
|
24
|
+
transparent?: boolean;
|
|
25
|
+
decorations?: boolean;
|
|
26
|
+
skipTaskbar?: boolean;
|
|
27
|
+
scrollbars?: boolean;
|
|
28
|
+
enableFileDrop?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface InvokeOptions {
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let _invoke: ((name: string, args?: unknown[]) => Promise<unknown>) | null = null;
|
|
36
|
+
let _event: ((event: string, callback: (...args: unknown[]) => void) => () => void) | null = null;
|
|
37
|
+
let _initialized = false;
|
|
38
|
+
|
|
39
|
+
export function setInvokeFn(fn: (name: string, args?: unknown[]) => Promise<unknown>) {
|
|
40
|
+
_invoke = fn;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function setEventFn(fn: (event: string, callback: (...args: unknown[]) => void) => () => void) {
|
|
44
|
+
_event = fn;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function init(): void {
|
|
48
|
+
if (_initialized) return;
|
|
49
|
+
_initialized = true;
|
|
50
|
+
|
|
51
|
+
if (typeof window !== 'undefined') {
|
|
52
|
+
const win = window as Window & {
|
|
53
|
+
__plusui_listeners__?: Map<string, Set<(...args: unknown[]) => void>>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
win.__plusui_listeners__ = new Map();
|
|
57
|
+
|
|
58
|
+
window.addEventListener('message', (event: MessageEvent) => {
|
|
59
|
+
if (event.data?.type === '__plusui_event__') {
|
|
60
|
+
const { event: eventName, payload } = event.data;
|
|
61
|
+
const listeners = win.__plusui_listeners__?.get(eventName);
|
|
62
|
+
if (listeners) {
|
|
63
|
+
listeners.forEach(cb => cb(payload));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function invoke<T = unknown>(name: string, args?: unknown[], options: InvokeOptions = {}): Promise<T> {
|
|
71
|
+
const { timeout = 30000 } = options;
|
|
72
|
+
|
|
73
|
+
if (_invoke) {
|
|
74
|
+
return _invoke(name, args) as Promise<T>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (typeof window !== 'undefined') {
|
|
78
|
+
const win = window as Window & {
|
|
79
|
+
__invoke__?: (name: string, args?: unknown[]) => Promise<unknown>;
|
|
80
|
+
__native_invoke__?: (request: string) => void;
|
|
81
|
+
};
|
|
82
|
+
if (win.__invoke__) {
|
|
83
|
+
return win.__invoke__(name, args) as Promise<T>;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return new Promise((_, reject) => {
|
|
88
|
+
setTimeout(() => reject(new Error(`Invocation ${name} timed out`)), timeout);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function eventHandler(event: string, callback: (...args: unknown[]) => void): () => void {
|
|
93
|
+
init();
|
|
94
|
+
|
|
95
|
+
if (!_event) {
|
|
96
|
+
if (typeof window !== 'undefined' && (window as any).__on__) {
|
|
97
|
+
_event = (window as any).__on__;
|
|
98
|
+
} else {
|
|
99
|
+
const win = window as Window & {
|
|
100
|
+
__plusui_listeners__?: Map<string, Set<(...args: unknown[]) => void>>;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (!win.__plusui_listeners__) {
|
|
104
|
+
win.__plusui_listeners__ = new Map();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const listeners = win.__plusui_listeners__!;
|
|
108
|
+
|
|
109
|
+
if (!listeners.has(event)) {
|
|
110
|
+
listeners.set(event, new Set());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
listeners.get(event)!.add(callback);
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
listeners.get(event)?.delete(callback);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return _event!(event, callback);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const app = {
|
|
124
|
+
async invoke<T = unknown>(name: string, args?: unknown[], options: InvokeOptions = {}): Promise<T> {
|
|
125
|
+
return invoke<T>(name, args, options);
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
async quit(): Promise<void> {
|
|
129
|
+
await invoke('app.quit');
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
async getVersion(): Promise<string> {
|
|
133
|
+
return invoke<string>('app.getVersion');
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
async getName(): Promise<string> {
|
|
137
|
+
return invoke<string>('app.getName');
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
async getPath(name: 'home' | 'appData' | 'userData' | 'temp' | 'desktop' | 'documents' | 'downloads'): Promise<string> {
|
|
141
|
+
return invoke<string>('app.getPath', [name]);
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
async setBadge(count: number): Promise<void> {
|
|
145
|
+
await invoke('app.setBadge', [count]);
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
async getBadge(): Promise<number> {
|
|
149
|
+
return invoke<number>('app.getBadge');
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
onReady(callback: () => void): () => void {
|
|
153
|
+
return eventHandler('app:ready', callback);
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
onQuit(callback: (reason?: string) => void): () => void {
|
|
157
|
+
return eventHandler('app:quit', callback as (...args: unknown[]) => void);
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
onActivate(callback: () => void): () => void {
|
|
161
|
+
return eventHandler('app:activate', callback);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
onWindowAllClosed(callback: () => void): () => void {
|
|
165
|
+
return eventHandler('app:windowAllClosed', callback);
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
onSecondInstance(callback: (args: string[], cwd: string) => void): () => void {
|
|
169
|
+
return eventHandler('app:secondInstance', callback as (...args: unknown[]) => void);
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
on(event: string, callback: (...args: unknown[]) => void): () => void {
|
|
173
|
+
return eventHandler(event, callback);
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
once(event: string, callback: (...args: unknown[]) => void): () => void {
|
|
177
|
+
const unsubscribe = this.on(event, (...args) => {
|
|
178
|
+
unsubscribe();
|
|
179
|
+
callback(...args);
|
|
180
|
+
});
|
|
181
|
+
return unsubscribe;
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
emit(event: string, payload?: unknown): void {
|
|
185
|
+
if (typeof window !== 'undefined') {
|
|
186
|
+
const customEvent = new CustomEvent(event, { detail: payload });
|
|
187
|
+
window.dispatchEvent(customEvent);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export default app;
|