@owear/core 0.1.2 → 0.1.4

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 (58) hide show
  1. package/dist/app.d.ts +128 -0
  2. package/dist/app.js +285 -0
  3. package/dist/appicon.d.ts +4 -0
  4. package/dist/appicon.js +16 -0
  5. package/dist/bridge.d.ts +79 -0
  6. package/dist/bridge.js +55 -0
  7. package/dist/browserwindow.d.ts +115 -0
  8. package/dist/browserwindow.js +237 -0
  9. package/dist/channel.d.ts +22 -0
  10. package/dist/channel.js +114 -0
  11. package/dist/dialog.d.ts +47 -0
  12. package/dist/dialog.js +22 -0
  13. package/dist/index.d.ts +83 -96
  14. package/dist/index.js +26 -253
  15. package/dist/installer.d.ts +126 -0
  16. package/dist/installer.js +84 -0
  17. package/dist/ipc/node.d.ts +7 -0
  18. package/dist/ipc/node.js +25 -0
  19. package/dist/menu.d.ts +56 -0
  20. package/dist/menu.js +208 -0
  21. package/dist/modules.d.ts +16 -0
  22. package/dist/modules.js +13 -0
  23. package/dist/nativeimage.d.ts +41 -0
  24. package/dist/nativeimage.js +376 -0
  25. package/dist/node/worker-runner.d.ts +1 -0
  26. package/dist/node/worker-runner.js +35 -0
  27. package/dist/node/worker.d.ts +29 -0
  28. package/dist/node/worker.js +61 -0
  29. package/dist/port.d.ts +28 -0
  30. package/dist/port.js +42 -0
  31. package/dist/power.d.ts +33 -0
  32. package/dist/power.js +99 -0
  33. package/dist/protocol.d.ts +14 -0
  34. package/dist/protocol.js +46 -0
  35. package/dist/safestorage.d.ts +16 -0
  36. package/dist/safestorage.js +21 -0
  37. package/dist/screen.d.ts +92 -0
  38. package/dist/screen.js +121 -0
  39. package/dist/session.d.ts +24 -0
  40. package/dist/session.js +42 -0
  41. package/dist/theme.d.ts +30 -0
  42. package/dist/theme.js +34 -0
  43. package/dist/tray.d.ts +30 -0
  44. package/dist/tray.js +69 -0
  45. package/dist/updater/boot.d.ts +20 -0
  46. package/dist/updater/boot.js +49 -0
  47. package/dist/updater/delta.d.ts +30 -0
  48. package/dist/updater/delta.js +96 -0
  49. package/dist/updater/yaml.d.ts +6 -0
  50. package/dist/updater/yaml.js +160 -0
  51. package/dist/updater.d.ts +119 -0
  52. package/dist/updater.js +429 -0
  53. package/dist/webcontents.d.ts +44 -0
  54. package/dist/webcontents.js +109 -0
  55. package/dist/webrequest.d.ts +23 -0
  56. package/dist/webrequest.js +76 -0
  57. package/package.json +7 -6
  58. package/LICENSE +0 -201
@@ -0,0 +1,237 @@
1
+ // Copyright 2026 Owear Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // @owear/core/src/browserwindow.ts — BrowserWindow (C9).
5
+ import { EventEmitter } from 'node:events';
6
+ import { channel, invokeNative } from './channel.js';
7
+ import { windowIcon } from './appicon.js';
8
+ import { readyPromise } from './app.js';
9
+ import { WebContents, WIN_EVENT_NAMES, WC_EVENT_NAMES } from './webcontents.js';
10
+ // ── BrowserWindow ───────────────────────────────────────────────────────────
11
+ /** Registro de ventanas por id (para resolver clicks de menú). */
12
+ export const windowsById = new Map();
13
+ /** Ventana con foco (para `BrowserWindow.getFocusedWindow`). */
14
+ let focusedWindowId = 0;
15
+ export class BrowserWindow extends EventEmitter {
16
+ _id = null;
17
+ _options;
18
+ _wc = new WebContents(null);
19
+ _onWindowEvent;
20
+ _onDisconnected;
21
+ constructor(options = {}) {
22
+ super();
23
+ this._options = options;
24
+ if (!readyPromise) {
25
+ throw new Error('BrowserWindow creado antes de app.whenReady()');
26
+ }
27
+ this._onWindowEvent = (params) => {
28
+ if (params.windowId !== this._id)
29
+ return;
30
+ this.emit(params.name, params.payload);
31
+ const dashWin = WIN_EVENT_NAMES[params.name];
32
+ if (dashWin)
33
+ this.emit(dashWin, params.payload);
34
+ this._wc.emit(WC_EVENT_NAMES[params.name] ?? params.name, params.payload);
35
+ if (params.name === 'focus' && this._id != null)
36
+ focusedWindowId = this._id;
37
+ if (params.name === 'blur' && this._id != null && focusedWindowId === this._id)
38
+ focusedWindowId = 0;
39
+ if (params.name === 'closed') {
40
+ if (this._id != null)
41
+ windowsById.delete(this._id);
42
+ this._unwireEvents();
43
+ }
44
+ };
45
+ this._onDisconnected = () => this.emit('disconnected');
46
+ readyPromise.then(() => this._create()).catch((e) => this.emit('error', e));
47
+ }
48
+ async _create() {
49
+ const { icon, ...rest } = this._options;
50
+ const res = await channel.call('window.create', { ...rest });
51
+ this._id = res.windowId;
52
+ this._wc._setWindowId(res.windowId);
53
+ windowsById.set(res.windowId, this);
54
+ this._wireEvents();
55
+ // Icono: el de la opción o el global (app.setIcon). PNG/JPEG.
56
+ const ic = icon ?? windowIcon();
57
+ if (ic)
58
+ await this.setIcon(ic).catch(() => undefined);
59
+ this.emit('ready-to-show', this._id);
60
+ }
61
+ /** Fija el icono de ESTA ventana (ruta a PNG/JPEG). */
62
+ async setIcon(path) {
63
+ const { readFileSync } = await import('node:fs');
64
+ const pngB64 = readFileSync(path).toString('base64');
65
+ await invokeNative('window', 'setIcon', this.requireId(), pngB64);
66
+ }
67
+ _wireEvents() {
68
+ channel.on('window.event', this._onWindowEvent);
69
+ channel.on('disconnected', this._onDisconnected);
70
+ }
71
+ _unwireEvents() {
72
+ channel.off('window.event', this._onWindowEvent);
73
+ channel.off('disconnected', this._onDisconnected);
74
+ }
75
+ get id() {
76
+ return this._id;
77
+ }
78
+ requireId() {
79
+ if (this._id == null)
80
+ throw new Error('ventana aún no creada');
81
+ return this._id;
82
+ }
83
+ // ── carga ──────────────────────────────────────────────────────────────
84
+ loadURL(url) {
85
+ return channel.call('window.loadURL', { windowId: this.requireId(), url });
86
+ }
87
+ /** Evalúa JS; devuelve el resultado JSON-serializado. */
88
+ eval(js) {
89
+ return channel.call('window.eval', { windowId: this.requireId(), js });
90
+ }
91
+ // ── ciclo de vida ──────────────────────────────────────────────────────
92
+ show() {
93
+ return channel.call('window.show', { windowId: this.requireId() });
94
+ }
95
+ hide() {
96
+ return channel.call('window.hide', { windowId: this.requireId() });
97
+ }
98
+ focus() {
99
+ return channel.call('window.focus', { windowId: this.requireId() });
100
+ }
101
+ close() {
102
+ return channel.call('window.close', { windowId: this.requireId() });
103
+ }
104
+ destroy() {
105
+ return channel.call('window.destroy', { windowId: this.requireId() });
106
+ }
107
+ minimize() {
108
+ return channel.call('window.minimize', { windowId: this.requireId() });
109
+ }
110
+ maximize() {
111
+ return channel.call('window.maximize', { windowId: this.requireId(), enabled: true });
112
+ }
113
+ unmaximize() {
114
+ return channel.call('window.maximize', { windowId: this.requireId(), enabled: false });
115
+ }
116
+ setFullScreen(enabled) {
117
+ return channel.call('window.setFullScreen', { windowId: this.requireId(), enabled });
118
+ }
119
+ /**
120
+ * Responde a un `closeRequested` (F3.4).
121
+ * `allow=false` cancela el cierre; `true` destruye la ventana.
122
+ * Si nadie responde en `OW_CLOSE_TIMEOUT_MS` (default 1000 ms), el kernel
123
+ * cierra igualmente.
124
+ */
125
+ closeRespond(requestId, allow) {
126
+ return channel.call('window.respondCloseRequest', {
127
+ windowId: this.requireId(),
128
+ requestId,
129
+ allow,
130
+ });
131
+ }
132
+ // ── estado ─────────────────────────────────────────────────────────────
133
+ isMaximized() {
134
+ return channel.call('window.isMaximized', { windowId: this.requireId() });
135
+ }
136
+ isMinimized() {
137
+ return channel.call('window.isMinimized', { windowId: this.requireId() });
138
+ }
139
+ getBounds() {
140
+ return channel.call('window.getBounds', { windowId: this.requireId() });
141
+ }
142
+ setBounds(b) {
143
+ return channel.call('window.setBounds', { windowId: this.requireId(), ...b });
144
+ }
145
+ setTitle(title) {
146
+ return channel.call('window.setTitle', { windowId: this.requireId(), title });
147
+ }
148
+ /**
149
+ * Activa/desactiva o reconfigura los botones nativos de ventana
150
+ * (min/max/close) dentro de la titlebar custom (Linux: GTK `titlebutton`).
151
+ * `true` los activa con los valores por defecto.
152
+ */
153
+ setTitleBarOverlay(overlay) {
154
+ return channel.call('window.setTitleBarOverlay', {
155
+ windowId: this.requireId(),
156
+ titleBarOverlay: overlay,
157
+ });
158
+ }
159
+ // ── estado extendido (C9) ──────────────────────────────────────────────
160
+ isVisible() { return channel.call('window.isVisible', { windowId: this.requireId() }); }
161
+ isFocused() { return channel.call('window.isFocused', { windowId: this.requireId() }); }
162
+ isResizable() { return channel.call('window.isResizable', { windowId: this.requireId() }); }
163
+ isMovable() { return channel.call('window.isMovable', { windowId: this.requireId() }); }
164
+ isMinimizable() { return channel.call('window.isMinimizable', { windowId: this.requireId() }); }
165
+ isMaximizable() { return channel.call('window.isMaximizable', { windowId: this.requireId() }); }
166
+ isClosable() { return channel.call('window.isClosable', { windowId: this.requireId() }); }
167
+ isAlwaysOnTop() { return channel.call('window.isAlwaysOnTop', { windowId: this.requireId() }); }
168
+ isKiosk() { return channel.call('window.isKiosk', { windowId: this.requireId() }); }
169
+ isDestroyed() { return channel.call('window.isDestroyed', { windowId: this.requireId() }); }
170
+ isFullScreen() { return channel.call('window.isFullScreen', { windowId: this.requireId() }); }
171
+ setResizable(on = true) { return channel.call('window.setResizable', { windowId: this.requireId(), on }); }
172
+ setMovable(on = true) { return channel.call('window.setMovable', { windowId: this.requireId(), on }); }
173
+ setMinimizable(on = true) { return channel.call('window.setMinimizable', { windowId: this.requireId(), on }); }
174
+ setMaximizable(on = true) { return channel.call('window.setMaximizable', { windowId: this.requireId(), on }); }
175
+ setClosable(on = true) { return channel.call('window.setClosable', { windowId: this.requireId(), on }); }
176
+ setAlwaysOnTop(on = true, level = 0) { return channel.call('window.setAlwaysOnTop', { windowId: this.requireId(), on, level }); }
177
+ setSkipTaskbar(on = true) { return channel.call('window.setSkipTaskbar', { windowId: this.requireId(), on }); }
178
+ setHasShadow(on = true) { return channel.call('window.setHasShadow', { windowId: this.requireId(), on }); }
179
+ setKiosk(on = true) { return channel.call('window.setKiosk', { windowId: this.requireId(), on }); }
180
+ setIgnoreMouseEvents(ignore = true, options = {}) {
181
+ return channel.call('window.setIgnoreMouseEvents', { windowId: this.requireId(), ignore, forward: !!options.forward });
182
+ }
183
+ setProgressBar(value, options = {}) {
184
+ return channel.call('window.setProgressBar', { windowId: this.requireId(), value, mode: options.mode ?? 'normal' });
185
+ }
186
+ setBackgroundColor(color) {
187
+ return channel.call('window.setBackgroundColor', { windowId: this.requireId(), color });
188
+ }
189
+ moveTop() { return channel.call('window.moveTop', { windowId: this.requireId() }); }
190
+ setAspectRatio(ratio, extraSize) {
191
+ return channel.call('window.setAspectRatio', {
192
+ windowId: this.requireId(),
193
+ ratio,
194
+ extraW: extraSize?.width ?? 0,
195
+ extraH: extraSize?.height ?? 0,
196
+ });
197
+ }
198
+ getContentBounds() { return channel.call('window.getContentBounds', { windowId: this.requireId() }); }
199
+ setContentSize(width, height) {
200
+ return channel.call('window.setContentSize', { windowId: this.requireId(), width, height });
201
+ }
202
+ getContentSize() {
203
+ return channel.call('window.getContentSize', { windowId: this.requireId() });
204
+ }
205
+ getMinimumSize() {
206
+ return channel.call('window.getMinimumSize', { windowId: this.requireId() });
207
+ }
208
+ getMaximumSize() {
209
+ return channel.call('window.getMaximumSize', { windowId: this.requireId() });
210
+ }
211
+ setMinimumSize(width, height) {
212
+ return channel.call('window.setMinimumSize', { windowId: this.requireId(), width, height });
213
+ }
214
+ setMaximumSize(width, height) {
215
+ return channel.call('window.setMaximumSize', { windowId: this.requireId(), width, height });
216
+ }
217
+ // ── estáticos (C9) ─────────────────────────────────────────────────────
218
+ /** Ventanas creadas por esta app (orden de creación). Síncrono, como Electron. */
219
+ static getAllWindows() {
220
+ return [...windowsById.values()];
221
+ }
222
+ /** Ventana con foco, o `null`. Síncrono, como Electron. */
223
+ static getFocusedWindow() {
224
+ return focusedWindowId ? windowsById.get(focusedWindowId) ?? null : null;
225
+ }
226
+ static fromId(id) {
227
+ return windowsById.get(id) ?? null;
228
+ }
229
+ /**
230
+ * `webContents` de esta ventana (estilo Electron): `send`, `capturePage`,
231
+ * eventos (`did-finish-load`, `before-input-event`, …) y
232
+ * `setWindowOpenHandler`.
233
+ */
234
+ get webContents() {
235
+ return this._wc;
236
+ }
237
+ }
@@ -0,0 +1,22 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export declare class ControlChannel extends EventEmitter {
3
+ private socket;
4
+ private buffer;
5
+ private nextId;
6
+ private pending;
7
+ connect(socketPath: string): Promise<void>;
8
+ private rejectAllPending;
9
+ private handleLine;
10
+ call<T = any>(cmd: string, params?: Record<string, unknown>): Promise<T>;
11
+ }
12
+ /** Canal singleton con el kernel. */
13
+ export declare const channel: ControlChannel;
14
+ /** Ruta del control socket (env o último de XDG_RUNTIME_DIR). */
15
+ export declare function socketPathFromEnv(): string;
16
+ /**
17
+ * Invoca un módulo nativo (.owm) desde el proceso principal. Equivalente a
18
+ * `ow.invoke()` del renderer, pero sin depender de una ventana.
19
+ *
20
+ * const txt = await invokeNative<string>('fs', 'readText', '/etc/hostname')
21
+ */
22
+ export declare function invokeNative<T = unknown>(module: string, method: string, ...args: unknown[]): Promise<T>;
@@ -0,0 +1,114 @@
1
+ // Copyright 2026 Owear Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // @owear/core/src/channel.ts — canal de control (NDJSON) con el kernel.
5
+ //
6
+ // Piedra angular del SDK: sin dependencias de otras partes del paquete (evita
7
+ // ciclos). El resto de features importan `channel` / `invokeNative` de aquí.
8
+ import * as net from 'node:net';
9
+ import { EventEmitter } from 'node:events';
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+ export class ControlChannel extends EventEmitter {
13
+ socket = null;
14
+ buffer = '';
15
+ nextId = 1;
16
+ pending = new Map();
17
+ connect(socketPath) {
18
+ return new Promise((resolve, reject) => {
19
+ const sock = net.connect(socketPath);
20
+ sock.once('connect', () => {
21
+ this.socket = sock;
22
+ resolve();
23
+ });
24
+ sock.once('error', (err) => {
25
+ this.socket = null;
26
+ this.rejectAllPending(err);
27
+ reject(err);
28
+ });
29
+ sock.on('data', (chunk) => {
30
+ this.buffer += chunk.toString('utf8');
31
+ let idx;
32
+ while ((idx = this.buffer.indexOf('\n')) >= 0) {
33
+ const line = this.buffer.slice(0, idx);
34
+ this.buffer = this.buffer.slice(idx + 1);
35
+ if (line.trim())
36
+ this.handleLine(line);
37
+ }
38
+ });
39
+ sock.on('close', () => {
40
+ this.socket = null;
41
+ this.rejectAllPending(new Error('conexión cerrada'));
42
+ this.emit('disconnected');
43
+ });
44
+ });
45
+ }
46
+ rejectAllPending(err) {
47
+ for (const { reject } of this.pending.values()) {
48
+ reject(err);
49
+ }
50
+ this.pending.clear();
51
+ }
52
+ handleLine(line) {
53
+ let msg;
54
+ try {
55
+ msg = JSON.parse(line);
56
+ }
57
+ catch {
58
+ return;
59
+ }
60
+ if (msg.event) {
61
+ this.emit(msg.event, msg.params);
62
+ return;
63
+ }
64
+ const p = this.pending.get(msg.id);
65
+ if (!p)
66
+ return;
67
+ this.pending.delete(msg.id);
68
+ if (msg.ok)
69
+ p.resolve(msg.result);
70
+ else
71
+ p.reject(new Error(msg.error ?? 'error de control'));
72
+ }
73
+ call(cmd, params = {}) {
74
+ if (!this.socket)
75
+ return Promise.reject(new Error('control socket desconectado'));
76
+ const id = this.nextId++;
77
+ return new Promise((resolve, reject) => {
78
+ this.pending.set(id, { resolve, reject });
79
+ this.socket.write(JSON.stringify({ id, cmd, params }) + '\n');
80
+ });
81
+ }
82
+ }
83
+ /** Canal singleton con el kernel. */
84
+ export const channel = new ControlChannel();
85
+ /** Ruta del control socket (env o último de XDG_RUNTIME_DIR). */
86
+ export function socketPathFromEnv() {
87
+ if (process.env.OW_CONTROL_SOCKET)
88
+ return process.env.OW_CONTROL_SOCKET;
89
+ // fallback: último socket vivo en XDG_RUNTIME_DIR (útil para depurar)
90
+ const dir = process.env.XDG_RUNTIME_DIR;
91
+ if (dir) {
92
+ try {
93
+ const socks = fs
94
+ .readdirSync(dir)
95
+ .filter((f) => f.startsWith('owear-') && f.endsWith('.sock'))
96
+ .sort();
97
+ if (socks.length)
98
+ return path.join(dir, socks[socks.length - 1]);
99
+ }
100
+ catch {
101
+ /* noop */
102
+ }
103
+ }
104
+ throw new Error('Owear: OW_CONTROL_SOCKET no definida. Lanza la app con `ow dev` o `ow build && owear`.');
105
+ }
106
+ /**
107
+ * Invoca un módulo nativo (.owm) desde el proceso principal. Equivalente a
108
+ * `ow.invoke()` del renderer, pero sin depender de una ventana.
109
+ *
110
+ * const txt = await invokeNative<string>('fs', 'readText', '/etc/hostname')
111
+ */
112
+ export function invokeNative(module, method, ...args) {
113
+ return channel.call('module.invoke', { module, method, args });
114
+ }
@@ -0,0 +1,47 @@
1
+ export interface FileFilter {
2
+ name: string;
3
+ extensions: string[];
4
+ }
5
+ export interface OpenDialogOptions {
6
+ title?: string;
7
+ defaultPath?: string;
8
+ buttonLabel?: string;
9
+ filters?: FileFilter[];
10
+ properties?: Array<'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory'>;
11
+ }
12
+ export interface SaveDialogOptions {
13
+ title?: string;
14
+ defaultPath?: string;
15
+ buttonLabel?: string;
16
+ filters?: FileFilter[];
17
+ }
18
+ export interface MessageBoxOptions {
19
+ type?: 'none' | 'info' | 'error' | 'question' | 'warning';
20
+ title?: string;
21
+ message: string;
22
+ detail?: string;
23
+ buttons?: string[];
24
+ defaultId?: number;
25
+ cancelId?: number;
26
+ checkboxLabel?: string;
27
+ }
28
+ /**
29
+ * Diálogos nativos (módulo `dialog`).
30
+ * const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile','multiSelections'] })
31
+ * const { filePath } = await dialog.showSaveDialog({ defaultPath: '/tmp/x.txt' })
32
+ * const { response } = await dialog.showMessageBox({ message: '¿Seguir?', buttons: ['Sí','No'] })
33
+ */
34
+ export declare const dialog: {
35
+ showOpenDialog(options?: OpenDialogOptions): Promise<{
36
+ canceled: boolean;
37
+ filePaths: string[];
38
+ }>;
39
+ showSaveDialog(options?: SaveDialogOptions): Promise<{
40
+ canceled: boolean;
41
+ filePath: string;
42
+ }>;
43
+ showMessageBox(options: MessageBoxOptions): Promise<{
44
+ response: number;
45
+ checkboxChecked: boolean;
46
+ }>;
47
+ };
package/dist/dialog.js ADDED
@@ -0,0 +1,22 @@
1
+ // Copyright 2026 Owear Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // @owear/core/src/dialog.ts — diálogos nativos (módulo `dialog`).
5
+ import { invokeNative } from './channel.js';
6
+ /**
7
+ * Diálogos nativos (módulo `dialog`).
8
+ * const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile','multiSelections'] })
9
+ * const { filePath } = await dialog.showSaveDialog({ defaultPath: '/tmp/x.txt' })
10
+ * const { response } = await dialog.showMessageBox({ message: '¿Seguir?', buttons: ['Sí','No'] })
11
+ */
12
+ export const dialog = {
13
+ showOpenDialog(options = {}) {
14
+ return invokeNative('dialog', 'showOpenDialog', options);
15
+ },
16
+ showSaveDialog(options = {}) {
17
+ return invokeNative('dialog', 'showSaveDialog', options);
18
+ },
19
+ showMessageBox(options) {
20
+ return invokeNative('dialog', 'showMessageBox', options);
21
+ },
22
+ };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,52 @@
1
- import { EventEmitter } from 'node:events';
1
+ export { NativeImage, nativeImage } from './nativeimage.js';
2
+ export type { Size as NativeImageSize, Rectangle, ResizeOptions } from './nativeimage.js';
2
3
  export interface WindowOptions {
3
4
  title?: string;
4
5
  width?: number;
5
6
  height?: number;
6
7
  x?: number;
7
8
  y?: number;
9
+ minWidth?: number;
10
+ minHeight?: number;
11
+ maxWidth?: number;
12
+ maxHeight?: number;
8
13
  resizable?: boolean;
14
+ movable?: boolean;
15
+ minimizable?: boolean;
16
+ maximizable?: boolean;
17
+ closable?: boolean;
18
+ fullscreenable?: boolean;
9
19
  frameless?: boolean;
20
+ transparent?: boolean;
21
+ backgroundColor?: string;
22
+ show?: boolean;
23
+ skipTaskbar?: boolean;
24
+ alwaysOnTop?: boolean;
25
+ hasShadow?: boolean;
26
+ aspectRatio?: number;
27
+ /** Ventana padre (id de otra ventana) y si es modal respecto a ella. */
28
+ parent?: number;
29
+ modal?: boolean;
10
30
  titleBarStyle?: 'default' | 'hidden' | 'custom';
11
- titleBarOverlay?: {
31
+ titleBarOverlay?: boolean | {
32
+ enabled?: boolean;
12
33
  color?: string;
13
34
  symbolColor?: string;
35
+ buttonColor?: string;
14
36
  height?: number;
15
37
  };
16
38
  url?: string;
39
+ /**
40
+ * Partición de sesión: aísla cookies/localStorage/IndexedDB/cache por perfil.
41
+ * Vacío = perfil por defecto de la app. Ej: "persist:cuenta-2".
42
+ * Crea la partición con `session.fromPartition(name)`.
43
+ */
44
+ session?: string;
45
+ /**
46
+ * Icono de la ventana (ruta a un PNG/JPEG). Para un icono por defecto de toda
47
+ * la app usa `app.setIcon(path)`.
48
+ */
49
+ icon?: string;
17
50
  }
18
51
  export interface Bounds {
19
52
  x: number;
@@ -21,6 +54,16 @@ export interface Bounds {
21
54
  width: number;
22
55
  height: number;
23
56
  }
57
+ /**
58
+ * Vista mínima de `webContents` (paridad con Electron) para el envío dirigido
59
+ * main → renderer. `send` llega al renderer como `ow.on(name, cb)`.
60
+ */
61
+ export interface WebContentsHandle {
62
+ /** Id de la ventana/webContents (-1 si aún no se creó). */
63
+ readonly id: number;
64
+ /** Envía un evento SOLO a esta ventana. */
65
+ send(name: string, payload?: unknown): Promise<void>;
66
+ }
24
67
  export type WindowEventMap = {
25
68
  resize: Bounds;
26
69
  move: Bounds;
@@ -35,99 +78,44 @@ export type WindowEventMap = {
35
78
  };
36
79
  closed: void;
37
80
  };
38
- declare class ControlChannel extends EventEmitter {
39
- private socket;
40
- private buffer;
41
- private nextId;
42
- private pending;
43
- connect(socketPath: string): Promise<void>;
44
- private rejectAllPending;
45
- private handleLine;
46
- call<T = any>(cmd: string, params?: Record<string, unknown>): Promise<T>;
47
- }
48
- export declare const app: {
49
- /** Conecta con el kernel. Resuelve cuando el canal de control está listo. */
50
- whenReady(): Promise<void>;
51
- quit(exitCode?: number): Promise<void>;
52
- info(): Promise<{
53
- pid: number;
54
- version: string;
55
- socket: string;
56
- }>;
57
- /**
58
- * Localiza (o descarga) un runtime Node. Prioridad: OW_NODE_BIN → Node del
59
- * sistema → caché de Owear → descarga oficial. `source` indica de dónde
60
- * salió ("env" | "system" | "cache" | "downloaded").
61
- */
62
- ensureNodeRuntime(range?: string): Promise<{
63
- path: string;
64
- version: string;
65
- source: string;
66
- }>;
67
- /** Acceso crudo al canal (para módulos custom del SDK). */
68
- __channel: ControlChannel;
69
- };
70
- /**
71
- * Invoca una función de un módulo nativo del kernel desde el proceso
72
- * principal (fs, process, net, clipboard…). Es el equivalente de `ow.invoke()`
73
- * del renderer, pero sin depender de una ventana: es la pieza que permite
74
- * portar APIs de Electron al main process.
75
- *
76
- * const txt = await invokeNative<string>('fs', 'readText', '/etc/hostname')
77
- */
78
- export declare function invokeNative<T = unknown>(module: string, method: string, ...args: unknown[]): Promise<T>;
79
- /** Metadatos de un módulo nativo cargado en el kernel. */
80
- export interface NativeModuleInfo {
81
- name: string;
82
- version: string;
83
- /** Ruta del .owm o "builtin:<nombre>" para los enlazados al kernel. */
84
- origin: string;
85
- builtin: boolean;
86
- /** Número de funciones (compat). */
87
- functions: number;
88
- /** Nombres de las funciones. */
89
- functionNames: string[];
90
- }
91
- /** Módulos nativos cargados, con versión, origen y funciones. */
92
- export declare function listNativeModules(): Promise<NativeModuleInfo[]>;
93
- /** Metadatos de un módulo nativo concreto. Rechaza si no existe. */
94
- export declare function nativeModuleInfo(name: string): Promise<NativeModuleInfo>;
95
- export declare class BrowserWindow extends EventEmitter {
96
- private _id;
97
- private _options;
98
- private _onWindowEvent;
99
- private _onDisconnected;
100
- constructor(options?: WindowOptions);
101
- private _create;
102
- private _wireEvents;
103
- private _unwireEvents;
104
- get id(): number | null;
105
- private requireId;
106
- loadURL(url: string): Promise<void>;
107
- /** Evalúa JS; devuelve el resultado JSON-serializado. */
108
- eval<T = unknown>(js: string): Promise<T>;
109
- show(): Promise<void>;
110
- hide(): Promise<void>;
111
- focus(): Promise<void>;
112
- close(): Promise<void>;
113
- destroy(): Promise<void>;
114
- minimize(): Promise<void>;
115
- maximize(): Promise<void>;
116
- unmaximize(): Promise<void>;
117
- setFullScreen(enabled: boolean): Promise<void>;
118
- /**
119
- * Responde a un `closeRequested` (F3.4).
120
- * `allow=false` cancela el cierre; `true` destruye la ventana.
121
- * Si nadie responde en `OW_CLOSE_TIMEOUT_MS` (default 1000 ms), el kernel
122
- * cierra igualmente.
123
- */
124
- closeRespond(requestId: number, allow: boolean): Promise<void>;
125
- isMaximized(): Promise<boolean>;
126
- isMinimized(): Promise<boolean>;
127
- getBounds(): Promise<Bounds>;
128
- setBounds(b: Partial<Bounds>): Promise<void>;
129
- setTitle(title: string): Promise<void>;
130
- }
81
+ export { invokeNative } from './channel.js';
82
+ export { listNativeModules, nativeModuleInfo } from './modules.js';
83
+ export type { NativeModuleInfo } from './modules.js';
84
+ export { theme, nativeTheme } from './theme.js';
85
+ export type { ThemeInfo } from './theme.js';
86
+ export { screen } from './screen.js';
87
+ export type { DisplayBounds, DisplaySize, Display, DisplayMetric } from './screen.js';
88
+ export { powerMonitor, powerSaveBlocker } from './power.js';
89
+ export type { IdleState, PowerSaveBlockerType } from './power.js';
90
+ export { safeStorage } from './safestorage.js';
91
+ export type { SafeStorageResult } from './safestorage.js';
92
+ export { session } from './session.js';
93
+ export type { PermissionRequest, PermissionHandler } from './session.js';
94
+ export { webRequest } from './webrequest.js';
95
+ export type { WebRequestDetails, WebRequestResult, WebRequestHandler } from './webrequest.js';
96
+ export { dialog } from './dialog.js';
97
+ export type { FileFilter, OpenDialogOptions, SaveDialogOptions, MessageBoxOptions } from './dialog.js';
98
+ export { WebContents } from './webcontents.js';
99
+ export { BrowserWindow } from './browserwindow.js';
100
+ export { MenuItem, Menu } from './menu.js';
101
+ export { Tray } from './tray.js';
102
+ export type { TrayEvent } from './tray.js';
103
+ export { nodeHandlers, nodeContextHandlers } from './ipc/node.js';
104
+ export type { NodeHandler, ContextNodeHandler } from './ipc/node.js';
105
+ export { protocolHandlers } from './protocol.js';
106
+ export type { ProtocolRequest, ProtocolHandlerResult, ProtocolHandler } from './protocol.js';
107
+ export { portRecords, makeMainPort, allocPortId } from './port.js';
108
+ export type { MessagePortMain } from './port.js';
109
+ export { app } from './app.js';
110
+ export { readyPromise } from './app.js';
111
+ export { installer } from './installer.js';
112
+ export type { InstallerMode, PayloadEntry, InstallerInfo, PlanOptions, InstallOptions, InstallResult, UninstallResult, VerifyResult, StateResult, ShortcutOptions, LaunchOptions, } from './installer.js';
113
+ export { autoUpdater } from './updater.js';
114
+ export type { FeedOptions, UpdateInfo, UpdateFile, ProgressInfo, UpdateCheckResult, } from './updater.js';
115
+ export { defineBridge } from './bridge.js';
116
+ export type { OwearBridge, BridgeApp, BridgeTarget, BridgePlatform, BridgeFormat, BridgeLayout, BridgePreset, BridgeGroup, BridgeProtect, BridgeNode, BridgeHooks, } from './bridge.js';
117
+ export { forkWorker, resolveWorkerEntry } from './node/worker.js';
118
+ export type { ForkWorkerOptions, WorkerHandle } from './node/worker.js';
131
119
  /** Tipos de `window.ow` disponible dentro del WebView (inyectado por el kernel). */
132
120
  export interface OwBridge {
133
121
  invoke<T = unknown>(module: string, fn: string, ...args: unknown[]): Promise<T>;
@@ -141,4 +129,3 @@ declare global {
141
129
  const ow: OwBridge;
142
130
  }
143
131
  export declare const platform: NodeJS.Platform;
144
- export {};