plusui-native-core 0.1.92 → 0.1.95

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.
@@ -1,216 +1,110 @@
1
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.
2
+ * PlusUI API - Simple & Direct
3
+ *
4
+ * window.show(), window.hide(), window.close()
5
+ * window.maximize(), window.minimize(), window.restore()
6
+ * window.setSize(w, h), window.setSize(x, y)
7
+ * window.setTitle(title), window.center()
19
8
  */
20
9
 
21
- // ============================================================
22
- // INTERNAL: Initialize Native Bridge Polyfill
23
- // ============================================================
24
10
  if (typeof window !== 'undefined') {
25
11
  const win = window as any;
26
12
  if (!win.__invoke__) {
27
- const pendingPromises = new Map<string, { resolve: (val: any) => void; reject: (err: any) => void }>();
28
13
  let callId = 0;
14
+ const pending = new Map<string, { resolve: (v: any) => void; reject: (e: any) => void }>();
29
15
 
30
16
  win.__response__ = function (id: string, result: any, error?: any) {
31
- if (pendingPromises.has(id)) {
32
- const { resolve, reject } = pendingPromises.get(id)!;
33
- pendingPromises.delete(id);
34
- if (error) {
35
- reject(new Error(error));
36
- } else {
37
- resolve(result);
38
- }
17
+ const p = pending.get(id);
18
+ if (p) {
19
+ pending.delete(id);
20
+ error ? p.reject(new Error(error)) : p.resolve(result);
39
21
  }
40
22
  };
41
23
 
42
24
  win.__invoke__ = function (method: string, params: any[] = []): Promise<any> {
43
25
  if (!win.__native_invoke__) {
44
- console.warn(`[PlusUI] API not initialized: __native_invoke__ missing. Running in mock mode for '${method}'.`);
45
26
  return Promise.resolve(null);
46
27
  }
47
28
  return new Promise((resolve, reject) => {
48
29
  const id = String(++callId);
49
- pendingPromises.set(id, { resolve, reject });
50
-
30
+ pending.set(id, { resolve, reject });
51
31
  try {
52
- const payload = JSON.stringify({
53
- jsonrpc: '2.0',
54
- id,
55
- method,
56
- params
57
- });
58
- win.__native_invoke__(payload);
59
- } catch (err) {
60
- pendingPromises.delete(id);
61
- reject(err);
32
+ win.__native_invoke__(JSON.stringify({ id, method, params }));
33
+ } catch (e) {
34
+ pending.delete(id);
35
+ reject(e);
62
36
  }
63
37
  });
64
38
  };
65
39
  }
66
40
  }
67
41
 
68
- // ============================================================
69
- // BUILT-IN FEATURES - Direct methods only (NO .on/.emit)
70
- // Each feature has its own dedicated API file in this directory.
71
- // ============================================================
72
-
73
42
  export { window } from './window-api';
74
43
  export { clipboard } from './clipboard-api';
44
+ export { app } from './app-api';
45
+ export { browser } from './browser-api';
46
+ export { router } from './router-api';
75
47
  export { keyboard, KeyCode, KeyMod } from './keyboard-api';
76
48
  export { tray } from './tray-api';
77
49
  export { display } from './display-api';
78
- export { fileDrop } from './filedrop-api';
50
+ export { fileDrop, formatFileSize } from './filedrop-api';
79
51
  export { menu } from './menu-api';
80
- export { app } from './app-api';
81
52
  export { gpu, GPUBufferUsage, GPUTextureUsage, GPUMapMode, GPUShaderStage, GPUColorWrite } from './webgpu-api';
82
- export { browser } from './browser-api';
83
- export { router } from './router-api';
84
-
85
- // ============================================================
86
- // CUSTOM CHANNELS - For user-defined events (uses .on/.emit)
87
- // ============================================================
88
53
 
89
- export {
90
- connect,
91
- createChannel,
92
- createFeatureConnect,
93
- type Channel
94
- } from './Connect_API';
95
-
96
- // Internal export for connection generator
54
+ export { connect, createChannel, type Channel } from './Connect_API';
97
55
  export { _client } from '../Connection/connect';
98
56
 
99
- // ============================================================
100
- // TYPES - Re-exported for convenience
101
- // ============================================================
102
-
103
- export type {
104
- WindowSize,
105
- WindowPosition,
106
- WindowRect,
107
- WindowState,
108
- WindowId
109
- } from './window-api';
110
-
57
+ export type { WindowSize, WindowPosition, WindowRect } from './window-api';
111
58
  export type { ClipboardAPI } from './clipboard-api';
112
-
113
- export type {
114
- KeyEvent,
115
- Shortcut,
116
- KeyEventCallback,
117
- ShortcutCallback,
118
- } from './keyboard-api';
119
-
59
+ export type { KeyEvent, Shortcut } from './keyboard-api';
120
60
  export type { TrayMenuItem, TrayIconData } from './tray-api';
121
-
122
- export type {
123
- Display,
124
- DisplayMode,
125
- DisplayBounds,
126
- DisplayResolution
127
- } from './display-api';
128
-
129
- export type { FileInfo, DragEvent, FileDropAPI } from './filedrop-api';
130
-
131
- export type {
132
- MenuItem,
133
- MenuItemType,
134
- MenuBarData,
135
- ContextMenuOptions,
136
- ContextInfo
137
- } from './menu-api';
138
-
61
+ export type { Display, DisplayMode, DisplayBounds, DisplayResolution } from './display-api';
62
+ export type { FileInfo, FileDropAPI } from './filedrop-api';
63
+ export type { MenuItem, MenuItemType, MenuBarData, ContextMenuOptions, ContextInfo } from './menu-api';
139
64
  export type { AppConfig } from './app-api';
140
-
141
- export type {
142
- GPUAdapter,
143
- GPUDevice,
144
- GPUBuffer,
145
- GPUTexture,
146
- GPUShaderModule,
147
- GPURenderPipeline,
148
- GPUComputePipeline,
149
- GPUQueue,
150
- GPUCommandEncoder
151
- } from './webgpu-api';
152
-
153
- export type {
154
- BrowserState,
155
- NavigateCallback,
156
- StateCallback,
157
- LoadCallback,
158
- ErrorCallback,
159
- } from './browser-api';
160
-
65
+ export type { GPUAdapter, GPUDevice, GPUBuffer, GPUTexture, GPUShaderModule, GPURenderPipeline, GPUComputePipeline, GPUQueue, GPUCommandEncoder } from './webgpu-api';
66
+ export type { BrowserState, NavigateCallback, StateCallback, LoadCallback, ErrorCallback } from './browser-api';
161
67
  export type { RouteMap, RouteChangeCallback, RouteConfig } from './router-api';
162
68
 
163
- // ============================================================
164
- // HELPER FUNCTIONS
165
- // ============================================================
166
-
167
- export {
168
- readFileAsText,
169
- readFileAsDataUrl,
170
- filterFilesByExtension,
171
- filterFilesByMimeType,
172
- isImageFile,
173
- isVideoFile,
174
- isAudioFile,
175
- isTextFile,
176
- formatFileSize
177
- } from './filedrop-api';
178
-
179
- // ============================================================
180
- // DEFAULT EXPORT - For `import plusui from 'plusui'` convenience
181
- // ============================================================
69
+ export { readFileAsText, readFileAsDataUrl, filterFilesByExtension, filterFilesByMimeType, isImageFile, isVideoFile, isAudioFile, isTextFile } from './filedrop-api';
182
70
 
183
71
  import { window } from './window-api';
184
72
  import { clipboard } from './clipboard-api';
185
- import { keyboard } from './keyboard-api';
73
+ import { app } from './app-api';
74
+ import { browser } from './browser-api';
75
+ import { router } from './router-api';
76
+ import { keyboard, KeyCode, KeyMod } from './keyboard-api';
186
77
  import { tray } from './tray-api';
187
78
  import { display } from './display-api';
188
79
  import { fileDrop, formatFileSize } from './filedrop-api';
189
80
  import { menu } from './menu-api';
190
- import { app } from './app-api';
191
- import { gpu } from './webgpu-api';
192
- import { browser } from './browser-api';
193
- import { router } from './router-api';
194
- import { connect, createChannel, createFeatureConnect } from './Connect_API';
81
+ import { gpu, GPUBufferUsage, GPUTextureUsage, GPUMapMode, GPUShaderStage, GPUColorWrite } from './webgpu-api';
82
+ import { connect, createChannel } from './Connect_API';
195
83
 
196
84
  const plusui = {
197
85
  window,
198
- win: window, // Alias for backward compatibility
86
+ win: window,
199
87
  clipboard,
88
+ app,
89
+ api: app,
90
+ browser,
91
+ router,
200
92
  keyboard,
201
93
  tray,
202
94
  display,
203
95
  fileDrop,
204
96
  menu,
205
- app,
206
- api: app,
207
97
  gpu,
208
- browser,
209
- router,
210
98
  connect,
211
99
  createChannel,
212
- createFeatureConnect,
213
- formatFileSize
100
+ formatFileSize,
101
+ KeyCode,
102
+ KeyMod,
103
+ GPUBufferUsage,
104
+ GPUTextureUsage,
105
+ GPUMapMode,
106
+ GPUShaderStage,
107
+ GPUColorWrite,
214
108
  };
215
109
 
216
110
  export default plusui;
@@ -1,52 +1,7 @@
1
- /**
2
- * Window API
3
- *
4
- * Controls native window behavior: visibility, size, position, decorations, and events.
5
- *
6
- * Actions:
7
- * window.show() - Make the window visible
8
- * window.hide() - Hide the window
9
- * window.minimize() - Minimize to taskbar
10
- * window.maximize() - Maximize to screen
11
- * window.restore() - Restore from minimized/maximized
12
- * window.close() - Close the window
13
- * window.center() - Center on screen
14
- * window.focus() - Bring to front and focus
15
- * window.setTitle(title) - Set the title bar text
16
- * window.setSize(w, h) - Resize the window
17
- * window.setPosition(x,y) - Move the window
18
- * window.setFullscreen(b) - Enter/exit fullscreen
19
- * window.setAlwaysOnTop(b)- Pin above other windows
20
- * window.setResizable(b) - Allow/disallow resizing
21
- * window.setDecorations(b)- Show/hide title bar and borders
22
- * window.setTransparency(a)- Set window opacity (0–1)
23
- * window.setIcon(path) - Set the window icon
24
- * window.getSize() - Get current size
25
- * window.getPosition() - Get current position
26
- * window.getRect() - Get position + size together
27
- * window.getState() - Get full window state
28
- * window.isMaximized() - Check if maximized
29
- * window.isMinimized() - Check if minimized
30
- * window.isVisible() - Check if visible
31
- *
32
- * Events:
33
- * window.onResize(cb) - Fires when window is resized
34
- * window.onMove(cb) - Fires when window is moved
35
- * window.onClose(cb) - Fires when window is closed
36
- * window.onFocus(cb) - Fires when focus changes
37
- * window.onStateChange(cb)- Fires on any state change
38
- * window.onMinimize(cb) - Fires when minimized
39
- * window.onMaximize(cb) - Fires when maximized
40
- * window.onRestore(cb) - Fires when restored
41
- * window.onFileDrop(cb) - Fires when files are dropped onto window
42
- */
43
-
44
- export type {
45
- WindowSize,
46
- WindowPosition,
47
- WindowRect,
48
- WindowState,
49
- WindowId,
50
- } from '../Window/window';
51
-
52
- export { window } from '../Window/window';
1
+ /**
2
+ * Window API
3
+ * Simple, direct window control - no events, just methods.
4
+ */
5
+
6
+ export type { WindowSize, WindowPosition, WindowRect } from '../Window/window';
7
+ export { window } from '../Window/window';
@@ -15,191 +15,65 @@ export interface WindowRect {
15
15
  height: number;
16
16
  }
17
17
 
18
- export interface WindowState {
19
- isMinimized: boolean;
20
- isMaximized: boolean;
21
- isVisible: boolean;
22
- isFullscreen: boolean;
23
- }
24
-
25
- export type WindowId = string;
26
-
27
- let _invoke: ((method: string, args?: unknown[]) => Promise<unknown>) | null = null;
28
- let _event: ((event: string, callback: (...args: unknown[]) => void) => () => void) | null = null;
29
-
30
- export function setInvokeFn(fn: (method: string, args?: unknown[]) => Promise<unknown>) {
31
- _invoke = fn;
32
- }
33
-
34
- export function setEventFn(fn: (event: string, callback: (...args: unknown[]) => void) => () => void) {
35
- _event = fn;
36
- }
37
-
38
- async function invoke<T = unknown>(method: string, args?: unknown[]): Promise<T> {
39
- if (!_invoke) {
40
- if (typeof window !== 'undefined' && (window as any).__invoke__) {
41
- _invoke = (window as any).__invoke__;
42
- } else {
43
- throw new Error('Window API not initialized');
44
- }
18
+ let callId = 0;
19
+ const pending = new Map<string, { resolve: (v: any) => void; reject: (e: any) => void }>();
20
+
21
+ async function invoke<T>(method: string, params: any[] = []): Promise<T> {
22
+ const win = window as any;
23
+
24
+ if (!win.__native_invoke__) {
25
+ console.warn(`[PlusUI] ${method} - native bridge not ready`);
26
+ return null as T;
45
27
  }
46
- return _invoke!(method, args) as Promise<T>;
47
- }
48
28
 
49
- function eventHandler(event: string, callback: (...args: unknown[]) => void): () => void {
50
- if (!_event) {
51
- if (typeof window !== 'undefined' && (window as any).__on__) {
52
- _event = (window as any).__on__;
53
- } else {
54
- return () => {};
29
+ return new Promise((resolve, reject) => {
30
+ const id = String(++callId);
31
+ pending.set(id, { resolve, reject });
32
+
33
+ win.__response__ = (respId: string, result: any, error?: any) => {
34
+ const p = pending.get(respId);
35
+ if (p) {
36
+ pending.delete(respId);
37
+ error ? p.reject(new Error(error)) : p.resolve(result);
38
+ }
39
+ };
40
+
41
+ try {
42
+ win.__native_invoke__(JSON.stringify({ id, method, params }));
43
+ } catch (e) {
44
+ pending.delete(id);
45
+ reject(e);
55
46
  }
56
- }
57
- return _event!(event, callback);
47
+ });
58
48
  }
59
49
 
60
50
  export const window = {
61
- // Direct methods
62
- async minimize(id?: WindowId): Promise<void> {
63
- await invoke('window.minimize', id ? [id] : []);
64
- },
65
-
66
- async maximize(id?: WindowId): Promise<void> {
67
- await invoke('window.maximize', id ? [id] : []);
68
- },
69
-
70
- async restore(id?: WindowId): Promise<void> {
71
- await invoke('window.restore', id ? [id] : []);
72
- },
73
-
74
- async close(id?: WindowId): Promise<void> {
75
- await invoke('window.close', id ? [id] : []);
76
- },
77
-
78
- async show(id?: WindowId): Promise<void> {
79
- await invoke('window.show', id ? [id] : []);
80
- },
81
-
82
- async hide(id?: WindowId): Promise<void> {
83
- await invoke('window.hide', id ? [id] : []);
84
- },
85
-
86
- async center(id?: WindowId): Promise<void> {
87
- await invoke('window.center', id ? [id] : []);
88
- },
89
-
90
- async setTitle(title: string, id?: WindowId): Promise<void> {
91
- const args = id ? [title, id] : [title];
92
- await invoke('window.setTitle', args);
93
- },
94
-
95
- async setSize(width: number, height: number, id?: WindowId): Promise<void> {
96
- const args = id ? [width, height, id] : [width, height];
97
- await invoke('window.setSize', args);
98
- },
99
-
100
- async setPosition(x: number, y: number, id?: WindowId): Promise<void> {
101
- const args = id ? [x, y, id] : [x, y];
102
- await invoke('window.setPosition', args);
103
- },
104
-
105
- async setFullscreen(enabled: boolean, id?: WindowId): Promise<void> {
106
- const args = id ? [enabled, id] : [enabled];
107
- await invoke('window.setFullscreen', args);
108
- },
109
-
110
- async setAlwaysOnTop(enabled: boolean, id?: WindowId): Promise<void> {
111
- const args = id ? [enabled, id] : [enabled];
112
- await invoke('window.setAlwaysOnTop', args);
113
- },
114
-
115
- async setResizable(enabled: boolean, id?: WindowId): Promise<void> {
116
- const args = id ? [enabled, id] : [enabled];
117
- await invoke('window.setResizable', args);
118
- },
119
-
120
- async setDecorations(enabled: boolean, id?: WindowId): Promise<void> {
121
- const args = id ? [enabled, id] : [enabled];
122
- await invoke('window.setDecorations', args);
123
- },
124
-
125
- async setTransparency(alpha: number, id?: WindowId): Promise<void> {
126
- const args = id ? [alpha, id] : [alpha];
127
- await invoke('window.setTransparency', args);
128
- },
129
-
130
- async getSize(id?: WindowId): Promise<WindowSize> {
131
- return invoke<WindowSize>('window.getSize', id ? [id] : []);
132
- },
133
-
134
- async getPosition(id?: WindowId): Promise<WindowPosition> {
135
- return invoke<WindowPosition>('window.getPosition', id ? [id] : []);
136
- },
137
-
138
- async getRect(id?: WindowId): Promise<WindowRect> {
139
- return invoke<WindowRect>('window.getRect', id ? [id] : []);
140
- },
141
-
142
- async getState(id?: WindowId): Promise<WindowState> {
143
- return invoke<WindowState>('window.getState', id ? [id] : []);
144
- },
145
-
146
- async isMaximized(id?: WindowId): Promise<boolean> {
147
- return invoke<boolean>('window.isMaximized', id ? [id] : []);
148
- },
149
-
150
- async isMinimized(id?: WindowId): Promise<boolean> {
151
- return invoke<boolean>('window.isMinimized', id ? [id] : []);
152
- },
153
-
154
- async isVisible(id?: WindowId): Promise<boolean> {
155
- return invoke<boolean>('window.isVisible', id ? [id] : []);
156
- },
157
-
158
- async focus(id?: WindowId): Promise<void> {
159
- await invoke('window.focus', id ? [id] : []);
160
- },
161
-
162
- async setIcon(iconPath: string, id?: WindowId): Promise<void> {
163
- const args = id ? [iconPath, id] : [iconPath];
164
- await invoke('window.setIcon', args);
165
- },
166
-
167
- // Direct event registration
168
- onResize(callback: (size: WindowSize) => void): () => void {
169
- return eventHandler('window:resize', callback as (...args: unknown[]) => void);
170
- },
171
-
172
- onMove(callback: (pos: WindowPosition) => void): () => void {
173
- return eventHandler('window:move', callback as (...args: unknown[]) => void);
174
- },
175
-
176
- onClose(callback: () => void): () => void {
177
- return eventHandler('window:close', callback as (...args: unknown[]) => void);
178
- },
179
-
180
- onFocus(callback: (focused: boolean) => void): () => void {
181
- return eventHandler('window:focus', callback as (...args: unknown[]) => void);
182
- },
183
-
184
- onStateChange(callback: (state: WindowState) => void): () => void {
185
- return eventHandler('window:stateChange', callback as (...args: unknown[]) => void);
186
- },
187
-
188
- onMinimize(callback: () => void): () => void {
189
- return eventHandler('window:minimize', callback as (...args: unknown[]) => void);
190
- },
191
-
192
- onMaximize(callback: () => void): () => void {
193
- return eventHandler('window:maximize', callback as (...args: unknown[]) => void);
194
- },
195
-
196
- onRestore(callback: () => void): () => void {
197
- return eventHandler('window:restore', callback as (...args: unknown[]) => void);
198
- },
199
-
200
- onFileDrop(callback: (files: { path: string; name: string; type: string; size: number }[]) => void): () => void {
201
- return eventHandler('window:fileDrop', callback as (...args: unknown[]) => void);
202
- },
51
+ show: () => invoke('window.show'),
52
+ hide: () => invoke('window.hide'),
53
+ close: () => invoke('window.close'),
54
+ minimize: () => invoke('window.minimize'),
55
+ maximize: () => invoke('window.maximize'),
56
+ restore: () => invoke('window.restore'),
57
+ focus: () => invoke('window.focus'),
58
+ center: () => invoke('window.center'),
59
+
60
+ setTitle: (title: string) => invoke('window.setTitle', [title]),
61
+ setSize: (width: number, height: number) => invoke('window.setSize', [width, height]),
62
+ setPosition: (x: number, y: number) => invoke('window.setPosition', [x, y]),
63
+ setFullscreen: (enabled: boolean) => invoke('window.setFullscreen', [enabled]),
64
+ setAlwaysOnTop: (enabled: boolean) => invoke('window.setAlwaysOnTop', [enabled]),
65
+ setResizable: (enabled: boolean) => invoke('window.setResizable', [enabled]),
66
+ setDecorations: (enabled: boolean) => invoke('window.setDecorations', [enabled]),
67
+ setTransparency: (alpha: number) => invoke('window.setTransparency', [alpha]),
68
+ setIcon: (path: string) => invoke('window.setIcon', [path]),
69
+
70
+ getSize: (): Promise<WindowSize> => invoke('window.getSize'),
71
+ getPosition: (): Promise<WindowPosition> => invoke('window.getPosition'),
72
+ getRect: (): Promise<WindowRect> => invoke('window.getRect'),
73
+
74
+ isMaximized: (): Promise<boolean> => invoke('window.isMaximized'),
75
+ isMinimized: (): Promise<boolean> => invoke('window.isMinimized'),
76
+ isVisible: (): Promise<boolean> => invoke('window.isVisible'),
203
77
  };
204
78
 
205
79
  export default window;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plusui-native-core",
3
- "version": "0.1.92",
3
+ "version": "0.1.95",
4
4
  "description": "PlusUI Core framework (frontend + backend implementations)",
5
5
  "type": "module",
6
6
  "main": "./Core/Features/API/index.ts",