onin-sdk 1.3.0

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.
@@ -0,0 +1,75 @@
1
+ /**
2
+ * 窗口适配器基础接口
3
+ *
4
+ * 定义了处理窗口事件的统一接口,具体实现由 InlineAdapter 和 WindowAdapter 提供。
5
+ *
6
+ * @module core/adapters/base
7
+ */
8
+ export type EventCallback = () => void | Promise<void>;
9
+ /**
10
+ * 窗口适配器接口
11
+ *
12
+ * 定义了窗口事件监听的统一 API,不同运行模式有不同的实现:
13
+ * - InlineAdapter: 使用 postMessage 和 visibilitychange
14
+ * - WindowAdapter: 使用 Tauri 事件系统
15
+ */
16
+ export interface WindowAdapter {
17
+ /**
18
+ * 监听窗口显示事件
19
+ */
20
+ onShow(callback: EventCallback): void;
21
+ /**
22
+ * 监听窗口隐藏事件
23
+ */
24
+ onHide(callback: EventCallback): void;
25
+ /**
26
+ * 监听窗口获得焦点事件
27
+ */
28
+ onFocus(callback: EventCallback): void;
29
+ /**
30
+ * 监听窗口失去焦点事件
31
+ */
32
+ onBlur(callback: EventCallback): void;
33
+ /**
34
+ * 销毁适配器(清理事件监听器)
35
+ */
36
+ destroy(): void;
37
+ }
38
+ /**
39
+ * 适配器基类 - 提供回调管理的通用逻辑
40
+ */
41
+ export declare abstract class BaseAdapter implements WindowAdapter {
42
+ protected showCallbacks: EventCallback[];
43
+ protected hideCallbacks: EventCallback[];
44
+ protected focusCallbacks: EventCallback[];
45
+ protected blurCallbacks: EventCallback[];
46
+ protected initialized: boolean;
47
+ protected isVisible: boolean;
48
+ protected isFocused: boolean;
49
+ protected static readonly DEBOUNCE_MS = 100;
50
+ protected lastShowTime: number;
51
+ protected lastHideTime: number;
52
+ protected lastFocusTime: number;
53
+ protected lastBlurTime: number;
54
+ /**
55
+ * 获取带时间戳的日志前缀
56
+ */
57
+ protected log(msg: string): void;
58
+ onShow(callback: EventCallback): void;
59
+ onHide(callback: EventCallback): void;
60
+ onFocus(callback: EventCallback): void;
61
+ onBlur(callback: EventCallback): void;
62
+ protected ensureInitialized(): void;
63
+ protected abstract initialize(): void;
64
+ destroy(): void;
65
+ /**
66
+ * 执行显示回调(带防抖和状态检查)
67
+ */
68
+ protected executeShowCallbacks(): Promise<void>;
69
+ /**
70
+ * 执行隐藏回调(带防抖和状态检查)
71
+ */
72
+ protected executeHideCallbacks(): Promise<void>;
73
+ protected executeFocusCallbacks(): Promise<void>;
74
+ protected executeBlurCallbacks(): Promise<void>;
75
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 适配器模块导出
3
+ *
4
+ * @module core/adapters
5
+ */
6
+ export type { WindowAdapter, EventCallback } from './base';
7
+ export { BaseAdapter } from './base';
8
+ export { InlineAdapter } from './inline';
9
+ export { WindowModeAdapter } from './window';
10
+ export { PostMessageAdapter } from './postmessage';
@@ -0,0 +1,17 @@
1
+ import { BaseAdapter } from './base';
2
+ /**
3
+ * 内联模式(iframe)窗口适配器
4
+ */
5
+ export declare class InlineAdapter extends BaseAdapter {
6
+ private messageHandler;
7
+ private visibilityHandler;
8
+ private focusHandler;
9
+ private blurHandler;
10
+ initialize(): void;
11
+ /**
12
+ * 设置 fallback 事件监听
13
+ * 当 postMessage 不可用时,使用浏览器原生事件
14
+ */
15
+ private setupFallbackEvents;
16
+ destroy(): void;
17
+ }
@@ -0,0 +1,47 @@
1
+ import { BaseAdapter } from './base';
2
+ /**
3
+ * 运行时信息
4
+ */
5
+ interface RuntimeInfo {
6
+ mode: 'inline' | 'window';
7
+ pluginId: string;
8
+ version: string;
9
+ mainWindowLabel: string;
10
+ }
11
+ /**
12
+ * 统一 PostMessage 适配器
13
+ */
14
+ export declare class PostMessageAdapter extends BaseAdapter {
15
+ private messageHandler;
16
+ private runtimeResolve;
17
+ private runtimePromise;
18
+ private _runtime;
19
+ constructor();
20
+ /**
21
+ * 立即初始化
22
+ */
23
+ private initializeNow;
24
+ /**
25
+ * 尝试从 URL 参数设置运行时信息(作为 fallback)
26
+ */
27
+ private trySetRuntimeFromUrl;
28
+ /**
29
+ * 获取运行时信息(异步)
30
+ */
31
+ getRuntime(): Promise<RuntimeInfo>;
32
+ /**
33
+ * 获取运行时信息(同步,可能返回 null)
34
+ */
35
+ getRuntimeSync(): RuntimeInfo | null;
36
+ protected initialize(): void;
37
+ /**
38
+ * 处理运行时初始化
39
+ */
40
+ private handleRuntimeInit;
41
+ /**
42
+ * 处理生命周期事件
43
+ */
44
+ private handleLifecycleEvent;
45
+ destroy(): void;
46
+ }
47
+ export {};
@@ -0,0 +1,37 @@
1
+ import { BaseAdapter } from './base';
2
+ /**
3
+ * 窗口模式适配器
4
+ * 使用 Tauri 事件系统监听窗口事件
5
+ */
6
+ export declare class WindowModeAdapter extends BaseAdapter {
7
+ private unlistenVisibility;
8
+ private unlistenFocus;
9
+ private unlistenBlur;
10
+ private tauriEventsActive;
11
+ initialize(): void;
12
+ /**
13
+ * 重置状态为未知,这样第一个事件会被正确处理
14
+ */
15
+ private resetStateToUnknown;
16
+ /**
17
+ * 尝试监听 Tauri 事件(带重试机制)
18
+ */
19
+ private tryListenTauriEvents;
20
+ /**
21
+ * 处理 focus 事件
22
+ */
23
+ private handleFocusEvent;
24
+ /**
25
+ * 处理 blur 事件
26
+ */
27
+ private handleBlurEvent;
28
+ /**
29
+ * 处理 show 事件
30
+ */
31
+ private handleShowEvent;
32
+ /**
33
+ * 处理 hide 事件
34
+ */
35
+ private handleHideEvent;
36
+ destroy(): void;
37
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Defines handler function signatures for different environments
3
+ * @interface Handlers
4
+ * @typeParam T - The return type of the handlers
5
+ * @since 0.1.0
6
+ * @group Core
7
+ */
8
+ export interface Handlers<T> {
9
+ webview: () => T;
10
+ headless: () => T;
11
+ }
12
+ /**
13
+ * Automatically selects and executes the appropriate handler function based on the current runtime environment.
14
+ *
15
+ * This function provides environment-aware execution, allowing the same code to work seamlessly
16
+ * in both webview (UI) and headless (background) environments. It automatically detects the
17
+ * current runtime and calls the appropriate handler.
18
+ *
19
+ * @typeParam T - The return type of the handler functions
20
+ * @param handlers - An object containing implementations for both webview and headless environments
21
+ * @returns The execution result of the selected handler function
22
+ * @throws {Error} If the environment is neither webview nor headless
23
+ * @example
24
+ * ```typescript
25
+ * // Different behavior for different environments
26
+ * const result = dispatch({
27
+ * webview: () => {
28
+ * // Code that runs in UI environment
29
+ * return window.someWebAPICall();
30
+ * },
31
+ * headless: () => {
32
+ * // Code that runs in background environment
33
+ * return Deno.env.get('SOME_VALUE');
34
+ * }
35
+ * });
36
+ *
37
+ * // API calls that work in both environments
38
+ * await dispatch({
39
+ * webview: () => invoke('some_command', args),
40
+ * headless: () => invoke('some_command', args)
41
+ * });
42
+ * ```
43
+ * @since 0.1.0
44
+ * @group Core
45
+ */
46
+ export declare function dispatch<T>(handlers: Handlers<T>): T;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Runtime environment detection module
3
+ * @fileoverview Used to identify whether the current SDK is running in a Headless (Deno) environment or Webview (HTML) environment
4
+ */
5
+ /**
6
+ * Supported runtime environment enumeration
7
+ * @enum {string}
8
+ */
9
+ export declare enum RuntimeEnvironment {
10
+ Headless = "headless",/** Headless Deno environment */
11
+ Webview = "webview",/** Webview environment with UI */
12
+ Iframe = "iframe",/** Iframe environment (plugin in iframe) */
13
+ Unknown = "unknown"
14
+ }
15
+ /**
16
+ * Gets the current runtime environment.
17
+ *
18
+ * Determines the current code's runtime environment by checking global objects and runtime characteristics.
19
+ * - If `window.__TAURI_INTERNALS__` object exists, it's considered a Webview environment
20
+ * - If running in an iframe (window.self !== window.top), it's considered an Iframe environment
21
+ * - If `Deno.core` exists, it's considered a Headless environment (including plugin runtime)
22
+ * - Otherwise, it's considered an unknown environment.
23
+ *
24
+ * @returns The current runtime environment
25
+ */
26
+ export declare function getEnvironment(): RuntimeEnvironment;
@@ -0,0 +1,66 @@
1
+ import { EventName, EventCallback, UnlistenFn } from '@tauri-apps/api/event';
2
+ /**
3
+ * Cross-environment invoke function for calling Tauri commands
4
+ *
5
+ * Provides a unified interface for invoking Tauri commands that works seamlessly
6
+ * in both webview and headless environments. Automatically handles environment
7
+ * detection and uses the appropriate underlying implementation.
8
+ *
9
+ * @typeParam T - The expected return type
10
+ * @param method - The method name to invoke
11
+ * @param arg - Arguments to pass to the method
12
+ * @returns Promise resolving to the method result
13
+ * @throws {Error} When the method call fails or returns an error
14
+ * @example
15
+ * ```typescript
16
+ * // Simple method call
17
+ * const result = await invoke('get_app_version');
18
+ *
19
+ * // Method call with arguments
20
+ * const response = await invoke<UserData>('get_user_data', { userId: 123 });
21
+ *
22
+ * // Error handling
23
+ * try {
24
+ * const data = await invoke('risky_operation', { param: 'value' });
25
+ * console.log('Success:', data);
26
+ * } catch (error) {
27
+ * console.error('Operation failed:', error.message);
28
+ * }
29
+ * ```
30
+ * @since 0.1.0
31
+ * @group Core
32
+ */
33
+ export declare function invoke<T>(method: string, arg: any): Promise<T>;
34
+ /**
35
+ * Cross-environment event listener for Tauri events
36
+ *
37
+ * Provides a unified interface for listening to Tauri events that works in both
38
+ * webview and headless environments. In webview mode, it uses the standard Tauri
39
+ * event system. In headless mode, it provides limited event support for specific
40
+ * plugin-related events.
41
+ *
42
+ * @typeParam T - The event payload type
43
+ * @param event - The event name to listen for
44
+ * @param handler - The event handler function
45
+ * @returns Promise resolving to an unlisten function
46
+ * @throws {Error} When event listening setup fails
47
+ * @example
48
+ * ```typescript
49
+ * // Listen for custom events
50
+ * const unlisten = await listen<string>('my-event', (event) => {
51
+ * console.log('Received event:', event.payload);
52
+ * });
53
+ *
54
+ * // Listen for plugin command execution (special case)
55
+ * await listen('plugin_command_execute', async (event) => {
56
+ * const { command, args } = event.payload;
57
+ * console.log(`Executing command: ${command}`, args);
58
+ * });
59
+ *
60
+ * // Clean up listener when done
61
+ * unlisten();
62
+ * ```
63
+ * @since 0.1.0
64
+ * @group Core
65
+ */
66
+ export declare function listen<T>(event: EventName, handler: EventCallback<T>): Promise<UnlistenFn>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 插件运行时环境模块
3
+ *
4
+ * 提供统一的运行时环境检测,通过主应用注入的 __ONIN_RUNTIME__ 对象
5
+ * 来判断插件的运行模式,而不是使用不可靠的 iframe 检测方法。
6
+ *
7
+ * @module core/runtime
8
+ */
9
+ /**
10
+ * 插件运行模式
11
+ */
12
+ export type PluginMode = 'inline' | 'window';
13
+ /**
14
+ * 运行时环境信息接口
15
+ */
16
+ export interface OninRuntime {
17
+ /** 插件运行模式:inline(iframe 内联)或 window(独立窗口) */
18
+ mode: PluginMode;
19
+ /** 插件 ID */
20
+ pluginId: string;
21
+ /** 插件版本 */
22
+ version: string;
23
+ /** 主窗口标签 */
24
+ mainWindowLabel: string;
25
+ }
26
+ declare global {
27
+ interface Window {
28
+ __ONIN_RUNTIME__?: OninRuntime;
29
+ }
30
+ }
31
+ /**
32
+ * 获取运行时环境信息
33
+ *
34
+ * 优先从 window.__ONIN_RUNTIME__ 读取主应用注入的信息,
35
+ * 如果不存在则根据环境自动检测。
36
+ */
37
+ export declare function getRuntime(): OninRuntime;
38
+ /**
39
+ * 重置运行时缓存(用于测试)
40
+ * @internal
41
+ */
42
+ export declare function _resetRuntimeCache(): void;
43
+ /**
44
+ * 当前运行时环境信息
45
+ * 注意:这是延迟计算的 getter,不是立即执行的
46
+ */
47
+ export declare const runtime: {
48
+ readonly mode: PluginMode;
49
+ readonly pluginId: string;
50
+ readonly version: string;
51
+ readonly mainWindowLabel: string;
52
+ };
53
+ /**
54
+ * 是否为内联模式(iframe)
55
+ */
56
+ export declare function isInlineMode(): boolean;
57
+ /**
58
+ * 是否为窗口模式(独立窗口)
59
+ */
60
+ export declare function isWindowMode(): boolean;
61
+ /**
62
+ * 获取当前插件 ID
63
+ */
64
+ export declare function getPluginId(): string;
@@ -0,0 +1,29 @@
1
+ function d(r, n = !1) {
2
+ return window.__TAURI_INTERNALS__.transformCallback(r, n);
3
+ }
4
+ async function t(r, n = {}, e) {
5
+ return window.__TAURI_INTERNALS__.invoke(r, n, e);
6
+ }
7
+ var _;
8
+ (function(r) {
9
+ r.WINDOW_RESIZED = "tauri://resize", r.WINDOW_MOVED = "tauri://move", r.WINDOW_CLOSE_REQUESTED = "tauri://close-requested", r.WINDOW_DESTROYED = "tauri://destroyed", r.WINDOW_FOCUS = "tauri://focus", r.WINDOW_BLUR = "tauri://blur", r.WINDOW_SCALE_FACTOR_CHANGED = "tauri://scale-change", r.WINDOW_THEME_CHANGED = "tauri://theme-changed", r.WINDOW_CREATED = "tauri://window-created", r.WEBVIEW_CREATED = "tauri://webview-created", r.DRAG_ENTER = "tauri://drag-enter", r.DRAG_OVER = "tauri://drag-over", r.DRAG_DROP = "tauri://drag-drop", r.DRAG_LEAVE = "tauri://drag-leave";
10
+ })(_ || (_ = {}));
11
+ async function l(r, n) {
12
+ window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(r, n), await t("plugin:event|unlisten", {
13
+ event: r,
14
+ eventId: n
15
+ });
16
+ }
17
+ async function s(r, n, e) {
18
+ var a;
19
+ const u = typeof (e == null ? void 0 : e.target) == "string" ? { kind: "AnyLabel", label: e.target } : (a = e == null ? void 0 : e.target) !== null && a !== void 0 ? a : { kind: "Any" };
20
+ return t("plugin:event|listen", {
21
+ event: r,
22
+ target: u,
23
+ handler: d(n)
24
+ }).then((i) => async () => l(r, i));
25
+ }
26
+ export {
27
+ _ as TauriEvent,
28
+ s as listen
29
+ };
@@ -0,0 +1,67 @@
1
+ import { http } from './api/request';
2
+ import { storage } from './api/storage';
3
+ import { notification } from './api/notification';
4
+ import { command } from './api/command';
5
+ import { fs } from './api/fs';
6
+ import { dialog } from './api/dialog';
7
+ import { clipboard } from './api/clipboard';
8
+ import { settings } from './api/settings';
9
+ import { lifecycle } from './api/lifecycle';
10
+ import { scheduler } from './api/scheduler';
11
+ import { pluginWindow } from './api/window';
12
+ import { ai } from './api/ai';
13
+ import { invoke, listen } from './core/ipc';
14
+ import { debug } from './utils/debug';
15
+ import * as error from './types/errors';
16
+ import * as retry from './utils/retry';
17
+ import type * as Permissions from './types/permissions';
18
+ import type * as Errors from './types/errors';
19
+ import type * as Retry from './utils/retry';
20
+ import type * as Fs from './api/fs';
21
+ import type * as Dialog from './api/dialog';
22
+ import type * as Settings from './api/settings';
23
+ /**
24
+ * Contains all available type definitions for the SDK
25
+ *
26
+ * Provides access to TypeScript type definitions for all SDK components.
27
+ * Use these types for better type safety and IDE support when working with
28
+ * the SDK APIs.
29
+ *
30
+ * @namespace types
31
+ * @version 0.1.0
32
+ * @since 0.1.0
33
+ * @group Types
34
+ * @example
35
+ * ```typescript
36
+ * import { types } from 'onin-plugin-sdk';
37
+ *
38
+ * // Use error types
39
+ * function handleError(error: types.Errors.PluginError) {
40
+ * console.log('Error code:', error.code);
41
+ * }
42
+ *
43
+ * // Use file system types
44
+ * function processFile(info: types.Fs.FileInfo) {
45
+ * console.log('File size:', info.size);
46
+ * }
47
+ *
48
+ * // Use dialog types
49
+ * const filters: types.Dialog.DialogFilter[] = [
50
+ * { name: 'Text Files', extensions: ['txt', 'md'] }
51
+ * ];
52
+ * ```
53
+ */
54
+ declare const types: {
55
+ Permissions: typeof Permissions;
56
+ Errors: typeof Errors;
57
+ Retry: typeof Retry;
58
+ Fs: typeof Fs;
59
+ Dialog: typeof Dialog;
60
+ Settings: typeof Settings;
61
+ };
62
+ export { http, storage, notification, command, fs, dialog, clipboard, settings, lifecycle, scheduler, pluginWindow, ai, invoke, listen, debug, error, retry, types, };
63
+ export type { SettingField, TextSettingField, PasswordSettingField, TextareaSettingField, NumberSettingField, ColorSettingField, DateSettingField, TimeSettingField, DatetimeSettingField, SliderSettingField, SwitchSettingField, RadioSettingField, SelectSettingField, MultiSelectSettingField, ButtonSettingField, SettingOption, JsonValue, SettingsValues, SettingSchemaDesc, } from './api/settings';
64
+ export type { PluginError, ErrorCode } from './types/errors';
65
+ export type { FileInfo } from './api/fs';
66
+ export type { DialogFilter, OpenDialogOptions, SaveDialogOptions, } from './api/dialog';
67
+ export type { ClipboardMetadata, ClipboardContentType, ClipboardFile, } from './api/clipboard';