@lingxia/types 0.10.0 → 0.11.1

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 (130) hide show
  1. package/dist/automation/index.d.ts +942 -0
  2. package/dist/automation/index.d.ts.map +1 -0
  3. package/dist/automation/index.js +13 -0
  4. package/dist/automation/index.js.map +1 -0
  5. package/dist/generated/i18n.d.ts +1 -1
  6. package/dist/generated/i18n.d.ts.map +1 -1
  7. package/dist/generated/i18n.js +29 -0
  8. package/dist/generated/i18n.js.map +1 -1
  9. package/dist/generated/logic-web.d.ts +305 -0
  10. package/dist/generated/logic.d.ts +1909 -0
  11. package/dist/generated/logic.d.ts.map +1 -0
  12. package/dist/generated/logic.js +5 -0
  13. package/dist/generated/logic.js.map +1 -0
  14. package/dist/index.d.ts +16 -313
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +3 -16
  17. package/dist/index.js.map +1 -1
  18. package/dist/logic-globals.d.ts +1 -0
  19. package/dist/process.d.ts +117 -0
  20. package/dist/process.d.ts.map +1 -0
  21. package/dist/process.js +10 -0
  22. package/dist/process.js.map +1 -0
  23. package/package.json +73 -47
  24. package/src/automation/index.ts +1074 -0
  25. package/src/generated/i18n.ts +29 -0
  26. package/src/generated/logic-web.d.ts +305 -0
  27. package/src/generated/logic.ts +2123 -0
  28. package/src/index.ts +18 -459
  29. package/src/logic-globals.d.ts +1 -0
  30. package/src/process.ts +135 -0
  31. package/dist/app/index.d.ts +0 -328
  32. package/dist/app/index.d.ts.map +0 -1
  33. package/dist/app/index.js +0 -6
  34. package/dist/app/index.js.map +0 -1
  35. package/dist/device/actions.d.ts +0 -7
  36. package/dist/device/actions.d.ts.map +0 -1
  37. package/dist/device/actions.js +0 -6
  38. package/dist/device/actions.js.map +0 -1
  39. package/dist/device/index.d.ts +0 -5
  40. package/dist/device/index.d.ts.map +0 -1
  41. package/dist/device/index.js +0 -21
  42. package/dist/device/index.js.map +0 -1
  43. package/dist/device/info.d.ts +0 -16
  44. package/dist/device/info.d.ts.map +0 -1
  45. package/dist/device/info.js +0 -6
  46. package/dist/device/info.js.map +0 -1
  47. package/dist/device/network.d.ts +0 -12
  48. package/dist/device/network.d.ts.map +0 -1
  49. package/dist/device/network.js +0 -6
  50. package/dist/device/network.js.map +0 -1
  51. package/dist/device/wifi.d.ts +0 -20
  52. package/dist/device/wifi.d.ts.map +0 -1
  53. package/dist/device/wifi.js +0 -6
  54. package/dist/device/wifi.js.map +0 -1
  55. package/dist/display/index.d.ts +0 -8
  56. package/dist/display/index.d.ts.map +0 -1
  57. package/dist/display/index.js +0 -6
  58. package/dist/display/index.js.map +0 -1
  59. package/dist/env/index.d.ts +0 -8
  60. package/dist/env/index.d.ts.map +0 -1
  61. package/dist/env/index.js +0 -6
  62. package/dist/env/index.js.map +0 -1
  63. package/dist/file/index.d.ts +0 -146
  64. package/dist/file/index.d.ts.map +0 -1
  65. package/dist/file/index.js +0 -6
  66. package/dist/file/index.js.map +0 -1
  67. package/dist/input/index.d.ts +0 -18
  68. package/dist/input/index.d.ts.map +0 -1
  69. package/dist/input/index.js +0 -8
  70. package/dist/input/index.js.map +0 -1
  71. package/dist/location/index.d.ts +0 -19
  72. package/dist/location/index.d.ts.map +0 -1
  73. package/dist/location/index.js +0 -6
  74. package/dist/location/index.js.map +0 -1
  75. package/dist/lxapp/index.d.ts +0 -11
  76. package/dist/lxapp/index.d.ts.map +0 -1
  77. package/dist/lxapp/index.js +0 -6
  78. package/dist/lxapp/index.js.map +0 -1
  79. package/dist/media/index.d.ts +0 -372
  80. package/dist/media/index.d.ts.map +0 -1
  81. package/dist/media/index.js +0 -6
  82. package/dist/media/index.js.map +0 -1
  83. package/dist/navigator/index.d.ts +0 -14
  84. package/dist/navigator/index.d.ts.map +0 -1
  85. package/dist/navigator/index.js +0 -6
  86. package/dist/navigator/index.js.map +0 -1
  87. package/dist/share/index.d.ts +0 -90
  88. package/dist/share/index.d.ts.map +0 -1
  89. package/dist/share/index.js +0 -6
  90. package/dist/share/index.js.map +0 -1
  91. package/dist/storage/index.d.ts +0 -13
  92. package/dist/storage/index.d.ts.map +0 -1
  93. package/dist/storage/index.js +0 -6
  94. package/dist/storage/index.js.map +0 -1
  95. package/dist/system/index.d.ts +0 -9
  96. package/dist/system/index.d.ts.map +0 -1
  97. package/dist/system/index.js +0 -6
  98. package/dist/system/index.js.map +0 -1
  99. package/dist/transfer/index.d.ts +0 -166
  100. package/dist/transfer/index.d.ts.map +0 -1
  101. package/dist/transfer/index.js +0 -6
  102. package/dist/transfer/index.js.map +0 -1
  103. package/dist/ui/index.d.ts +0 -134
  104. package/dist/ui/index.d.ts.map +0 -1
  105. package/dist/ui/index.js +0 -6
  106. package/dist/ui/index.js.map +0 -1
  107. package/dist/update/index.d.ts +0 -17
  108. package/dist/update/index.d.ts.map +0 -1
  109. package/dist/update/index.js +0 -6
  110. package/dist/update/index.js.map +0 -1
  111. package/src/app/index.ts +0 -378
  112. package/src/device/actions.ts +0 -7
  113. package/src/device/index.ts +0 -4
  114. package/src/device/info.ts +0 -17
  115. package/src/device/network.ts +0 -23
  116. package/src/device/wifi.ts +0 -23
  117. package/src/display/index.ts +0 -9
  118. package/src/env/index.ts +0 -8
  119. package/src/file/index.ts +0 -171
  120. package/src/input/index.ts +0 -19
  121. package/src/location/index.ts +0 -20
  122. package/src/lxapp/index.ts +0 -12
  123. package/src/media/index.ts +0 -411
  124. package/src/navigator/index.ts +0 -16
  125. package/src/share/index.ts +0 -97
  126. package/src/storage/index.ts +0 -13
  127. package/src/system/index.ts +0 -9
  128. package/src/transfer/index.ts +0 -194
  129. package/src/ui/index.ts +0 -165
  130. package/src/update/index.ts +0 -19
@@ -0,0 +1,1909 @@
1
+ declare const appDownloadPathBrand: unique symbol;
2
+ declare const systemDownloadsPathBrand: unique symbol;
3
+ export interface PageConfig<TData extends Record<string, unknown> = Record<string, unknown>> {
4
+ data?: TData;
5
+ onLoad?: (options?: PageLoadOptions) => void | Promise<void>;
6
+ onShow?: () => void | Promise<void>;
7
+ onReady?: () => void | Promise<void>;
8
+ onHide?: () => void | Promise<void>;
9
+ onUnload?: () => void | Promise<void>;
10
+ onPullDownRefresh?: () => void | Promise<void>;
11
+ [key: string]: unknown;
12
+ }
13
+ export interface PageInstance<TData extends Record<string, unknown> = Record<string, unknown>> {
14
+ data: TData;
15
+ route: string;
16
+ /**
17
+ * Available when this page was opened as a surface via `lx.openSurface(...)`.
18
+ */
19
+ surface?: Surface;
20
+ /**
21
+ * Available when this page was opened by `lx.navigateTo(...)`.
22
+ */
23
+ opener?: PageMessagePort;
24
+ setData(data: Partial<TData> | Record<string, unknown>, callback?: () => void): void;
25
+ }
26
+ /**
27
+ * Injected by the runtime into methods listed in `stream_handlers` page metadata.
28
+ *
29
+ * Use this when your async source uses callbacks rather than an async iterator.
30
+ * For the generator form (`async *method()`), no handle is needed — the runtime
31
+ * pumps the generator automatically.
32
+ */
33
+ export interface StreamHandle<T = unknown> {
34
+ /** Send a chunk to View. */
35
+ send(payload: T): void;
36
+ /** End the stream with an optional final value. */
37
+ end(result?: unknown): void;
38
+ /** End the stream with an error. */
39
+ error(code: string, message?: string): void;
40
+ }
41
+ /**
42
+ * Injected by the runtime as the second parameter when View opens a channel.
43
+ *
44
+ * Use `ch.send()` to push data to View, `ch.on()` to receive data/close
45
+ * events from View, and `ch.close()` to shut down the channel.
46
+ */
47
+ export interface ChannelHandle<TSend = unknown, TReceive = unknown> {
48
+ /** Push a message to View. */
49
+ send(payload: TSend): void;
50
+ /** Close the channel from Logic side. */
51
+ close(code?: string, reason?: string): void;
52
+ /** Register a listener for incoming events. */
53
+ on(event: 'data', handler: (payload: TReceive) => void): void;
54
+ on(event: 'close', handler: (info: {
55
+ code: string;
56
+ reason: string;
57
+ }) => void): void;
58
+ }
59
+ /**
60
+ * Download options.
61
+ *
62
+ * - `app`: app-owned temporary output, or durable `lx://userdata` output when
63
+ * `filePath` is set
64
+ * - `downloads`: user-visible system Downloads output, requiring
65
+ * `security.privileges: ["downloads"]` in `lxapp.json`
66
+ *
67
+ * Default: `app`.
68
+ */
69
+ export type DownloadOptions<TDestination extends DownloadDestination = DownloadDestination> = TDestination extends 'downloads' ? DownloadsDownloadOptions : AppDownloadOptions;
70
+ export type DownloadResultForDestination<TDestination extends DownloadDestination> = TDestination extends 'downloads' ? DownloadsDownloadResult : AppDownloadResult;
71
+ export interface DownloadProgressEvent<TResult extends DownloadResult = DownloadResult> {
72
+ kind: 'progress' | 'paused' | 'resumed' | 'canceled' | 'completed';
73
+ downloadedBytes?: number;
74
+ totalBytes?: number;
75
+ /** Present only when the total size is known. */
76
+ progress?: number;
77
+ result?: TResult;
78
+ }
79
+ export interface DownloadIteratorResult<TResult extends DownloadResult = DownloadResult> {
80
+ done: boolean;
81
+ value?: DownloadProgressEvent<TResult>;
82
+ }
83
+ export interface DownloadTask<TDownloadResult extends DownloadResult = DownloadResult> extends PromiseLike<TDownloadResult>, AsyncIterable<DownloadProgressEvent<TDownloadResult>> {
84
+ next(): Promise<DownloadIteratorResult<TDownloadResult>>;
85
+ /** Stops iteration only. Does not cancel the underlying download task. */
86
+ return(): Promise<DownloadIteratorResult<TDownloadResult>>;
87
+ catch<TRejected = never>(onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null): Promise<TDownloadResult | TRejected>;
88
+ finally(onfinally?: (() => void) | null): Promise<TDownloadResult>;
89
+ pause(): Promise<void>;
90
+ resume(): Promise<void>;
91
+ cancel(): Promise<void>;
92
+ /** Alias for cancel(), matching browser/mini-program abort naming. */
93
+ abort(): Promise<void>;
94
+ wait(): Promise<TDownloadResult>;
95
+ }
96
+ export interface FileManager {
97
+ readFile(options: ReadTextFileOptions): Promise<ReadTextFileResult>;
98
+ readFile(options: ReadBinaryFileOptions): Promise<ReadBinaryFileResult>;
99
+ readFile(options: ReadFileOptions): Promise<ReadFileResult>;
100
+ }
101
+ declare global {
102
+ interface HostAppApi {
103
+ /**
104
+ * The build environment from `app.json::envVersion`. It is fixed at boot
105
+ * and defaults to `release` for older artifacts.
106
+ */
107
+ readonly envVersion: HostAppEnvVersion;
108
+ /**
109
+ * Launch-at-startup control. Present only on macOS / Windows with the
110
+ * capability declared; gate access with `lx.app.autostart?.…`.
111
+ */
112
+ autostart?: AutostartApi;
113
+ }
114
+ /** Runtime environment constants backed by abstract `lx://` paths. */
115
+ interface LxEnv {
116
+ }
117
+ interface Lx {
118
+ /**
119
+ * Open a surface. Browser tabs resolve to `null`, declared surfaces to a
120
+ * host-managed handle, and page surfaces to a full `Surface`. URL asides
121
+ * return a `Surface` when docked and `null` in compact browser chrome.
122
+ * `as: "window"` is desktop-only.
123
+ */
124
+ openSurface(spec: OpenUrlTabSpec): Promise<null>;
125
+ openSurface(spec: OpenDeclaredSurfaceSpec | OpenLxappSurfaceSpec | OpenNativeSurfaceSpec): Promise<SurfaceHandle>;
126
+ openSurface(spec: OpenPageSurfaceSpec): Promise<Surface>;
127
+ openSurface(spec: OpenUrlAsideSpec): Promise<Surface | null>;
128
+ openSurface(spec: OpenSurfaceSpec): Promise<Surface | SurfaceHandle | null>;
129
+ /** Download to the downloads directory. */
130
+ downloadFile(options: DownloadsDownloadOptions): DownloadTask<DownloadsDownloadResult>;
131
+ /** Download to the lxapp-managed app directory. */
132
+ downloadFile(options: AppDownloadOptions): DownloadTask<AppDownloadResult>;
133
+ /** Download with a destination-correlated result type. */
134
+ downloadFile<TDestination extends DownloadDestination = "app">(options: DownloadOptions<TDestination>): DownloadTask<DownloadResultForDestination<TDestination>>;
135
+ }
136
+ }
137
+ export type ActionSheetResult = {
138
+ tapIndex: number;
139
+ };
140
+ export type AppConfig = {
141
+ globalData?: Record<string, unknown>;
142
+ onLaunch?: (options?: AppLaunchOptions) => void | Promise<void>;
143
+ onShow?: (args?: AppLifecycleEventArgs) => void | Promise<void>;
144
+ onHide?: (args?: AppLifecycleEventArgs) => void | Promise<void>;
145
+ onUserCaptureScreen?: () => void | Promise<void>;
146
+ [key: string]: unknown;
147
+ };
148
+ /** Runtime-managed app download path, usually under `lx://userdata`. */
149
+ export type AppDownloadFilePath = string & {
150
+ readonly [appDownloadPathBrand]: 'app-download-file-path';
151
+ };
152
+ export type AppDownloadOptions = DownloadOptionsBase & {
153
+ /**
154
+ * Optional app-owned durable output path.
155
+ *
156
+ * Omit `filePath` to receive a temporary result in `tempFilePath`. Relative
157
+ * paths resolve under user data. `lx://` paths must target `lx://userdata`;
158
+ * `lx://usercache` is not accepted here.
159
+ */
160
+ filePath?: string;
161
+ /**
162
+ * App-owned output. Omit to use a temporary output unless `filePath` is set.
163
+ */
164
+ destination?: 'app';
165
+ };
166
+ export type AppDownloadResult = {
167
+ /**
168
+ * Temporary result.
169
+ *
170
+ * Not durable; move or copy it to `lx://userdata` if you need to keep it.
171
+ *
172
+ * When `filePath` is omitted, the runtime must be able to infer a file
173
+ * type from the URL or the server's `Content-Type` header.
174
+ */
175
+ tempFilePath: string;
176
+ filePath?: never;
177
+ mimeType?: string;
178
+ size: number;
179
+ } | {
180
+ /** Durable destination under `lx://userdata`. */
181
+ filePath: AppDownloadFilePath;
182
+ tempFilePath?: never;
183
+ mimeType?: string;
184
+ size: number;
185
+ };
186
+ export type AppInstance = AppConfig & {
187
+ globalData: Record<string, unknown>;
188
+ };
189
+ export type AppLaunchOptions = {
190
+ path?: string;
191
+ query?: Record<string, string>;
192
+ scene?: number;
193
+ referrerInfo?: {
194
+ appId?: string;
195
+ extraData?: Record<string, unknown>;
196
+ };
197
+ };
198
+ export type AppLifecycleEventArgs = {
199
+ source: 'host' | 'lxapp';
200
+ reason: 'foreground' | 'background' | 'screenshot' | 'open' | 'close' | 'switch_back' | 'switch_away';
201
+ };
202
+ export type AppScreenshotOptions = {
203
+ /**
204
+ * Platform-specific window id to capture (desktop only). Omit to let the
205
+ * platform pick: the key/main window on desktop, the sole window on mobile.
206
+ */
207
+ windowId?: string;
208
+ };
209
+ export type AppScreenshotResult = {
210
+ /** `lx://` URI of the captured PNG in the lxapp temp directory. */
211
+ tempFilePath: string;
212
+ /** Image width in pixels, when the runtime could read it from the PNG. */
213
+ width?: number;
214
+ /** Image height in pixels, when the runtime could read it from the PNG. */
215
+ height?: number;
216
+ };
217
+ /**
218
+ * Launch-at-startup control for the host app.
219
+ * **macOS 13+ / Windows only.** Everywhere else — other platforms, or a
220
+ * macOS shell older than 13 — `lx.app.autostart` is absent (`undefined`);
221
+ * presence is the support check, so portable code gates on the member itself:
222
+ * ```ts
223
+ * if (lx.app.autostart) {
224
+ * // render the "Launch at startup" toggle
225
+ * }
226
+ * ```
227
+ * Requires `capabilities.autostart: true` in `lingxia.yaml`; without it the
228
+ * member is absent on all platforms. Declaring the capability never enables
229
+ * autostart by itself — the SDK registers the app only when `setEnabled(true)`
230
+ * is called, so the decision stays with the user (typically a settings-page
231
+ * toggle, default off).
232
+ * Host-app-level capability: like `checkUpdate` and `screenshot`, the methods
233
+ * are available only to the home lxapp; other lxapps receive a permission
234
+ * error.
235
+ */
236
+ export type AutostartApi = {
237
+ /**
238
+ * Whether the app is currently registered to launch at startup, read from
239
+ * the OS (macOS login items / Windows `Run` registry key) — never a cached
240
+ * preference. The user can flip this outside the app (System Settings on
241
+ * macOS, Task Manager's Startup page on Windows), so re-read it whenever the
242
+ * settings UI is shown.
243
+ */
244
+ isEnabled(): Promise<boolean>;
245
+ /**
246
+ * Register or unregister the app as a startup item for the current user.
247
+ * Idempotent. On macOS the system may notify the user that a login item was
248
+ * added — only call this from an explicit user action.
249
+ */
250
+ setEnabled(on: boolean): Promise<void>;
251
+ };
252
+ export type BinaryFileData = ArrayBuffer | ArrayBufferView;
253
+ export type CapsuleRect = {
254
+ width?: number;
255
+ height?: number;
256
+ top?: number;
257
+ right?: number;
258
+ bottom?: number;
259
+ left?: number;
260
+ };
261
+ export type ChooseDirectoryOptions = {
262
+ /** Initial directory the dialog opens in. Platform default if omitted. */
263
+ defaultPath?: string;
264
+ };
265
+ export type ChooseDirectoryResult = {
266
+ /** True if the user dismissed the dialog without selecting. */
267
+ canceled: boolean;
268
+ /** Native-consumable directory reference (path or URI). Undefined when canceled. */
269
+ path?: string;
270
+ };
271
+ export type ChooseFileOptions = {
272
+ /** Allow selecting multiple files. Default: false */
273
+ multiple?: boolean;
274
+ /** Optional file filters. Empty or omitted means all file types. */
275
+ filters?: FileDialogFilter[];
276
+ /**
277
+ * Initial directory the dialog opens in.
278
+ *
279
+ * When this resolves to an app-local directory, LingXia may use its internal
280
+ * file picker. When omitted, the platform system file picker is used.
281
+ */
282
+ defaultPath?: string;
283
+ };
284
+ export type ChooseFileResult = {
285
+ /** True if the user dismissed the dialog without selecting. */
286
+ canceled: boolean;
287
+ /**
288
+ * File paths returned by LingXia. Values may be app-local paths, `lx://...`
289
+ * paths, or platform system-picker references. Treat them as opaque strings
290
+ * and pass them back to LingXia APIs such as `lx.share`.
291
+ */
292
+ paths: string[];
293
+ };
294
+ export type ChooseMediaOptions = {
295
+ count?: number;
296
+ mediaType?: ('image' | 'video')[];
297
+ sourceType?: ('album' | 'camera')[];
298
+ camera?: 'back' | 'front';
299
+ maxDuration?: number;
300
+ };
301
+ export type ChosenMediaEntry = {
302
+ tempFilePath: string;
303
+ fileType: 'image' | 'video';
304
+ isOriginal: boolean;
305
+ };
306
+ export type CompressImageOptions = {
307
+ path: string;
308
+ quality?: number;
309
+ compressedWidth?: number;
310
+ compressedHeight?: number;
311
+ };
312
+ export type CompressImageResult = {
313
+ tempFilePath: string;
314
+ };
315
+ export type CompressVideoIteratorResult = {
316
+ done: boolean;
317
+ value?: CompressVideoProgressEvent;
318
+ };
319
+ export type CompressVideoOptions = {
320
+ /**
321
+ * Source video path or `lx://` URI.
322
+ */
323
+ path: string;
324
+ /**
325
+ * Cross-platform note: video compression parameters are best-effort and may map to
326
+ * native presets instead of exact encoder settings.
327
+ *
328
+ * Compression quality preset.
329
+ * When provided, `bitrate`, `fps`, and `resolution` are ignored.
330
+ */
331
+ quality?: VideoCompressQuality;
332
+ /**
333
+ * Preferred target video bitrate in kbps.
334
+ * May be adjusted or ignored by platform codec/runtime limitations.
335
+ */
336
+ bitrate?: number;
337
+ /**
338
+ * Preferred target frame rate in fps.
339
+ * Some platforms may ignore this option.
340
+ */
341
+ fps?: number;
342
+ /**
343
+ * Target resolution scale ratio relative to source size, in range `(0, 1]`.
344
+ * May be approximated or ignored by platform transcoder capabilities.
345
+ */
346
+ resolution?: number;
347
+ /**
348
+ * Optional output path for compressed file.
349
+ */
350
+ outputPath?: string;
351
+ };
352
+ export type CompressVideoProgressEvent = {
353
+ /** Transcode progress in percent, `0`-`100`. */
354
+ progress: number;
355
+ };
356
+ export type CompressVideoResult = {
357
+ tempFilePath: string;
358
+ width: number;
359
+ height: number;
360
+ durationMs: number;
361
+ /**
362
+ * Output file size in bytes.
363
+ * Could be close to source size when platform falls back to source content.
364
+ */
365
+ size: number;
366
+ type: string;
367
+ };
368
+ /**
369
+ * Handle returned by `lx.compressVideo`.
370
+ * Awaiting the task resolves with the final {@link CompressVideoResult}.
371
+ * Iterating it with `for await` yields {@link CompressVideoProgressEvent}s
372
+ * while the transcode runs.
373
+ */
374
+ export type CompressVideoTask = PromiseLike<CompressVideoResult> & AsyncIterable<CompressVideoProgressEvent> & {
375
+ next(): Promise<CompressVideoIteratorResult>;
376
+ /** Stops iteration only. Does not cancel the compression. */
377
+ return(): Promise<CompressVideoIteratorResult>;
378
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<CompressVideoResult | TResult>;
379
+ finally(onfinally?: (() => void) | null): Promise<CompressVideoResult>;
380
+ /**
381
+ * Cancels the transcode and deletes any partial output.
382
+ * The task promise rejects with an `AbortError` (`code: 'E_ABORT'`).
383
+ */
384
+ cancel(): void;
385
+ wait(): Promise<CompressVideoResult>;
386
+ };
387
+ export type ConnectWifiOptions = {
388
+ SSID: string;
389
+ password?: string;
390
+ };
391
+ export type CopyFileOptions = {
392
+ srcPath: string;
393
+ destPath: string;
394
+ /** Defaults to false. */
395
+ overwrite?: boolean;
396
+ };
397
+ /** Display and orientation APIs. */
398
+ export type DeviceOrientation = "portrait" | "landscape";
399
+ export type DeviceOrientationChangeEvent = {
400
+ value: DeviceOrientation;
401
+ };
402
+ export type DownloadDestination = 'app' | 'downloads';
403
+ export type DownloadOptionsBase = {
404
+ /** HTTP(S) source URL. */
405
+ url: string;
406
+ /**
407
+ * Optional request headers.
408
+ * Restricted headers such as `Referer` are ignored by the runtime.
409
+ */
410
+ headers?: Record<string, string>;
411
+ /** Request timeout in milliseconds. */
412
+ timeout?: number;
413
+ /** Optional abort signal. */
414
+ signal?: AbortSignal;
415
+ };
416
+ export type DownloadResult = AppDownloadResult | DownloadsDownloadResult;
417
+ export type DownloadsDownloadOptions = DownloadOptionsBase & {
418
+ /**
419
+ * Optional filename hint for the system Downloads destination.
420
+ * This is not an app-owned FileManager path.
421
+ */
422
+ filePath?: string;
423
+ /** Save into the user's system Downloads directory. */
424
+ destination: 'downloads';
425
+ };
426
+ export type DownloadsDownloadResult = {
427
+ /** Native system Downloads path. Do not pass this to `FileManager`. */
428
+ filePath: SystemDownloadsPath;
429
+ tempFilePath?: never;
430
+ mimeType?: string;
431
+ size: number;
432
+ };
433
+ export type ExistsOptions = {
434
+ path: string;
435
+ };
436
+ export type ExtractVideoThumbnailOptions = {
437
+ /**
438
+ * Source video path or `lx://` URI.
439
+ */
440
+ path: string;
441
+ /**
442
+ * Optional output image path. If omitted, runtime chooses a temporary path.
443
+ */
444
+ outputPath?: string;
445
+ /**
446
+ * Max output width in pixels.
447
+ * Optional; when set with/without `maxHeight`, output keeps aspect ratio (no cropping).
448
+ */
449
+ maxWidth?: number;
450
+ /**
451
+ * Max output height in pixels.
452
+ * Optional; when set with/without `maxWidth`, output keeps aspect ratio (no cropping).
453
+ */
454
+ maxHeight?: number;
455
+ /**
456
+ * Target frame time in milliseconds from video start.
457
+ * `0` means first frame.
458
+ */
459
+ timeMs?: number;
460
+ /**
461
+ * JPEG quality in range `0-100`.
462
+ */
463
+ quality?: number;
464
+ };
465
+ export type ExtractVideoThumbnailResult = {
466
+ /**
467
+ * Generated thumbnail file path.
468
+ */
469
+ tempFilePath: string;
470
+ /**
471
+ * Output image width in pixels.
472
+ */
473
+ width: number;
474
+ /**
475
+ * Output image height in pixels.
476
+ */
477
+ height: number;
478
+ /**
479
+ * Output MIME type, usually `image/jpeg`.
480
+ */
481
+ type: string;
482
+ };
483
+ export type FileDialogFilter = {
484
+ /** Optional label shown in the native dialog. */
485
+ name?: string;
486
+ /** Allowed extensions without dots, e.g. ['pdf', 'txt']. */
487
+ extensions: string[];
488
+ };
489
+ /** Media picker, preview, scan, and file processing APIs. */
490
+ export type GetImageInfoOptions = {
491
+ path: string;
492
+ };
493
+ /** Location APIs. */
494
+ export type GetLocationOptions = {
495
+ type?: 'wgs84' | 'gcj02';
496
+ altitude?: boolean;
497
+ isHighAccuracy?: boolean;
498
+ highAccuracyExpireTime?: number;
499
+ };
500
+ export type GetVideoInfoOptions = {
501
+ /**
502
+ * Video file path or `lx://` URI.
503
+ */
504
+ path: string;
505
+ };
506
+ export type HostAppApi = globalThis.HostAppApi;
507
+ /**
508
+ * Build-time environment version of the host app.
509
+ * Surfaced via {@link HostAppApi.envVersion}. Mirrors the
510
+ * `crates/lingxia-update::ReleaseType` enum and the `envVersion` field in the
511
+ * generated `app.json`. Pre-envVersion app artifacts are treated as `'release'`.
512
+ * Note: this is *separate* from `LxAppEnvVersion` in the navigator module,
513
+ * which encodes lxapp release channels (`'develop' | 'preview' | 'release'`)
514
+ * for cross-app navigation URLs and uses the truncated `develop` form.
515
+ */
516
+ export type HostAppEnvVersion = 'developer' | 'preview' | 'release';
517
+ export type HostAppUpdateApplyStage = 'download' | 'install';
518
+ export type HostAppUpdateCheckResult = {
519
+ hasUpdate: false;
520
+ update?: never;
521
+ } | {
522
+ hasUpdate: true;
523
+ update: HostAppUpdateInfo;
524
+ };
525
+ export type HostAppUpdateEvent = {
526
+ state: 'downloading';
527
+ downloadedBytes?: number;
528
+ progress?: number;
529
+ } | {
530
+ state: 'downloaded' | 'installRequested';
531
+ } | {
532
+ state: 'failed';
533
+ stage: HostAppUpdateApplyStage;
534
+ error: string;
535
+ };
536
+ export type HostAppUpdateInfo = {
537
+ version: string;
538
+ size?: number;
539
+ releaseNotes?: string[];
540
+ isForceUpdate: boolean;
541
+ /**
542
+ * Download and apply this checked update.
543
+ *
544
+ * `apply()` is single-use for this update object.
545
+ *
546
+ * The returned task can be awaited directly when progress is not needed, or
547
+ * consumed with `for await...of` to render progress.
548
+ *
549
+ * Direct package handoff is currently supported on Android and macOS. Other
550
+ * platforms reject with an unsupported-operation error; use `version` and
551
+ * `releaseNotes` to guide users to the appropriate app marketplace.
552
+ */
553
+ apply(): HostAppUpdateTask;
554
+ };
555
+ export type HostAppUpdateIteratorResult = {
556
+ done: boolean;
557
+ value?: HostAppUpdateEvent;
558
+ };
559
+ export type HostAppUpdateResult = {
560
+ state: 'installRequested';
561
+ };
562
+ export type HostAppUpdateTask = PromiseLike<HostAppUpdateResult> & AsyncIterable<HostAppUpdateEvent> & {
563
+ next(): Promise<HostAppUpdateIteratorResult>;
564
+ /** Stops iteration only. It does not cancel an app update already handed to the platform. */
565
+ return(): Promise<HostAppUpdateIteratorResult>;
566
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<HostAppUpdateResult | TResult>;
567
+ finally(onfinally?: (() => void) | null): Promise<HostAppUpdateResult>;
568
+ wait(): Promise<HostAppUpdateResult>;
569
+ };
570
+ /**
571
+ * Input event APIs.
572
+ * Platform support: Android only
573
+ */
574
+ export type KeyEvent = {
575
+ /** Key value following W3C naming (e.g. "Enter", "ArrowLeft", "a") */
576
+ key: string;
577
+ /** Physical key code (e.g. "ENTER", "DPAD_LEFT") */
578
+ code: string;
579
+ altKey?: boolean;
580
+ ctrlKey?: boolean;
581
+ shiftKey?: boolean;
582
+ metaKey?: boolean;
583
+ repeat?: boolean;
584
+ };
585
+ export type KeyEventCallback = (event: KeyEvent) => void;
586
+ export type LxAppEnvVersion = 'release' | 'preview' | 'develop';
587
+ /** LxApp metadata APIs. */
588
+ export type LxAppReleaseType = 'release' | 'preview' | 'developer';
589
+ export type LxEnv = globalThis.LxEnv;
590
+ /** Device action APIs. */
591
+ export type MakePhoneCallOptions = {
592
+ phoneNumber: string;
593
+ };
594
+ export type MediaObjectFit = 'cover' | 'contain' | 'fill' | 'fit';
595
+ export type MediaRotation = 0 | 90 | 180 | 270;
596
+ export type MkdirOptions = {
597
+ path: string;
598
+ recursive?: boolean;
599
+ };
600
+ export type ModalResult = {
601
+ confirm: boolean;
602
+ cancel: boolean;
603
+ };
604
+ export type NavigateBackOptions = {
605
+ delta: number;
606
+ };
607
+ export type NavigateToLxAppOptions = {
608
+ appId: string;
609
+ page?: string;
610
+ path?: string;
611
+ query?: PageQuery;
612
+ envVersion?: LxAppEnvVersion;
613
+ targetVersion?: string;
614
+ };
615
+ export type NavigateToOptions = PageTargetOptions;
616
+ export type NetworkChangeCallback = (info: NetworkInfo) => void;
617
+ export type NetworkInfo = {
618
+ isConnected: boolean;
619
+ networkType: NetworkType;
620
+ ipv4: string[];
621
+ ipv6: string[];
622
+ };
623
+ /** Network status APIs. */
624
+ export type NetworkType = 'none' | 'unknown' | 'wifi' | '2g' | '3g' | '4g' | '5g' | 'ethernet';
625
+ /**
626
+ * Show a surface declared by id in the host's `lingxia.yaml`.
627
+ * Available to any lxapp granted access to that declaration.
628
+ */
629
+ export type OpenDeclaredSurfaceSpec = {
630
+ surface: string;
631
+ /** Docking edge override for this open. */
632
+ edge?: SurfaceEdge;
633
+ page?: never;
634
+ url?: never;
635
+ lxapp?: never;
636
+ native?: never;
637
+ as?: never;
638
+ position?: never;
639
+ size?: never;
640
+ query?: never;
641
+ };
642
+ /** File system APIs. */
643
+ export type OpenFileOptions = {
644
+ /** Local file path or runtime-managed temp path. */
645
+ filePath: string;
646
+ /** Optional coarse file type hint such as `pdf`, `docx`, or `xlsx`. */
647
+ fileType?: string;
648
+ /**
649
+ * `auto`: prefer native review, then fall back to external open.
650
+ * `review`: require native review UI and reject when unsupported.
651
+ * `external`: hand off directly to the system / external app.
652
+ */
653
+ mode?: 'auto' | 'review' | 'external';
654
+ /** Hint for whether the native review UI should expose its action menu when supported. */
655
+ showMenu?: boolean;
656
+ };
657
+ /**
658
+ * Open another lxapp by appId (home lxapp only). A declared surface
659
+ * toggles its shell presentation; an undeclared lxapp opens as a main
660
+ * tab, or docks as an aside panel with `as: 'aside'`.
661
+ */
662
+ export type OpenLxappSurfaceSpec = {
663
+ lxapp: string;
664
+ /** Defaults to the lingxia.yaml role, else 'main'. */
665
+ as?: 'main' | 'aside' | 'float';
666
+ /**
667
+ * Docking edge override for this open. Without it the surface keeps its
668
+ * current placement (initially the `lingxia.yaml` edge); with it the panel
669
+ * opens there — or moves there if already visible.
670
+ */
671
+ edge?: SurfaceEdge;
672
+ page?: never;
673
+ url?: never;
674
+ native?: never;
675
+ position?: never;
676
+ size?: never;
677
+ query?: never;
678
+ };
679
+ /**
680
+ * Open a host-registered native capability (home lxapp only), e.g.
681
+ * the built-in terminal declared in `lingxia.yaml` surfaces.
682
+ */
683
+ export type OpenNativeSurfaceSpec = {
684
+ native: string;
685
+ /** Docking edge override for this open. */
686
+ edge?: SurfaceEdge;
687
+ page?: never;
688
+ url?: never;
689
+ lxapp?: never;
690
+ as?: never;
691
+ position?: never;
692
+ size?: never;
693
+ query?: never;
694
+ };
695
+ /**
696
+ * Spec for {@link OpenSurfaceSpec}. A discriminated union keyed by source so a
697
+ * page name and a declared surface id never collide (each is its own string
698
+ * space, separately type-checkable).
699
+ * - `{ page }` — one of this lxapp's own pages, by name, arranged as `as`
700
+ * (`float` is a popup; `window` is a bare desktop window, which rejects on
701
+ * mobile). `position` applies to `float`, and `size` is a Host-clamped hint.
702
+ * They are fixed at open (re-open to change). Your own pages **cannot** be
703
+ * docked as an `aside` — an aside is external content only (see `{ url }`).
704
+ * For a side panel of your own, use a declared `surface`, an in-page split
705
+ * layout, or `role: main` for a switchable destination.
706
+ * `float` is a popup layered above the main at `position` (like a dialog); it
707
+ * takes no layout space. `interaction` controls the native close button,
708
+ * outside-click dismissal, and modality. Defaults are no button,
709
+ * `tapOutside`, and non-modal.
710
+ * - `{ surface }` — a surface declared in `lingxia.yaml` `surfaces:`, by id
711
+ * (e.g. `'terminal'`, `'ai-assistant'`). Form, position, and startup data come
712
+ * from the declaration.
713
+ * - `{ url }` — external content in the in-app browser. Without `as` it opens as
714
+ * a main browser tab (the **self** browser: full chrome **with an editable
715
+ * address bar**, no handle). With `as: 'aside'` it opens in the **browser
716
+ * aside** — a docked (large screen) / full-screen (phone) **multi-tab** browser
717
+ * for external content only (`https://` or `file://`).
718
+ * The aside is **API-only** and never permits address editing or a manual
719
+ * "new tab" action. Desktop may show the current address read-only; compact
720
+ * phone/Runner chrome omits the address row entirely.
721
+ * Tabs are **deduped by URL** — reopening a URL focuses the existing tab and
722
+ * preserves its current navigation. On `medium` / `expanded`, the returned
723
+ * handle is **tab-scoped**: `close()` closes that tab. Compact browser chrome
724
+ * owns the group and returns `null`. Closing the last tab closes the aside;
725
+ * dismissing it only hides the group. The tab UI shows page **titles** (never
726
+ * the URL), plus per-tab close, back/forward, refresh, and dismissal.
727
+ * Presentation is the only large/small difference: on `medium` / `expanded`
728
+ * the aside **docks** and splits beside the main at `edge` (default `'right'`)
729
+ * with a horizontal title tab strip; on `compact` (phone / runner) it presents
730
+ * **full-screen** with a single-row **bottom** browser toolbar (tabs reached
731
+ * via an aside-only switcher). System/edge Back and the toolbar dismiss action
732
+ * exit the whole aside even when page history exists; the explicit browser
733
+ * Back button navigates history. `size` is a host-clamped preferred size
734
+ * (large screen only).
735
+ */
736
+ export type OpenPageSurfaceSpec = {
737
+ page: string;
738
+ /** A popup above the main. */
739
+ as: 'float';
740
+ position?: SurfaceFloatPosition;
741
+ size?: OverlaySurfaceSize;
742
+ interaction?: SurfaceInteraction;
743
+ query?: Record<string, unknown>;
744
+ edge?: never;
745
+ surface?: never;
746
+ url?: never;
747
+ } | {
748
+ page: string;
749
+ as: 'window';
750
+ size?: WindowSurfaceSize;
751
+ /** Windows use manual dismissal; `tapOutside` is invalid. */
752
+ interaction?: SurfaceInteraction;
753
+ query?: Record<string, unknown>;
754
+ edge?: never;
755
+ position?: never;
756
+ surface?: never;
757
+ url?: never;
758
+ };
759
+ export type OpenSurfaceSpec = OpenPageSurfaceSpec | OpenDeclaredSurfaceSpec | OpenLxappSurfaceSpec | OpenNativeSurfaceSpec | OpenUrlTabSpec | OpenUrlAsideSpec;
760
+ /**
761
+ * Open `url` in the multi-tab browser aside. `url` must be `https://` or
762
+ * `file://` (external content only). Repeated calls add/focus tabs (deduped by
763
+ * URL) in the single aside per window. Medium/expanded returns a tab-scoped
764
+ * handle; compact returns `null` because browser chrome owns the group. See
765
+ * {@link OpenSurfaceSpec} for the full aside contract.
766
+ */
767
+ export type OpenUrlAsideSpec = {
768
+ url: string;
769
+ as: 'aside';
770
+ edge?: SurfaceEdge;
771
+ size?: OverlaySurfaceSize;
772
+ page?: never;
773
+ surface?: never;
774
+ position?: never;
775
+ query?: never;
776
+ };
777
+ export type OpenUrlTabSpec = {
778
+ url: string;
779
+ as?: never;
780
+ page?: never;
781
+ surface?: never;
782
+ edge?: never;
783
+ position?: never;
784
+ size?: never;
785
+ query?: never;
786
+ };
787
+ export type OverlaySurfaceSize = {
788
+ /** Width hint. */
789
+ width?: OverlaySurfaceSizeValue;
790
+ /** Height hint. */
791
+ height?: OverlaySurfaceSizeValue;
792
+ };
793
+ /**
794
+ * Size hint for an overlay surface (aside / float).
795
+ * - number: absolute px, must be > 0
796
+ * - `${number}%`: percentage of the container, 0 < N ≤ 100
797
+ */
798
+ export type OverlaySurfaceSizeValue = number | `${number}%`;
799
+ export type PageLoadOptions = {
800
+ [key: string]: string | undefined;
801
+ };
802
+ export type PageMessagePort = {
803
+ postMessage(message: unknown): void;
804
+ onMessage(handler: (message: unknown) => void): () => void;
805
+ };
806
+ export type PageQuery = Record<string, PageQueryValue>;
807
+ export type PageQueryValue = string | number | boolean | null | undefined;
808
+ /**
809
+ * Target page for `navigateTo`, `redirectTo`, `switchTab`, and `reLaunch`.
810
+ * Pass exactly one of `page` or `path`; there is no `url` field. Page
811
+ * names and routes are discoverable with `lxdev lxapp pages`.
812
+ */
813
+ export type PageTargetOptions = {
814
+ /** Configured page name from `lingxia.yaml` / `lxapp.json`. */
815
+ page: string;
816
+ path?: never;
817
+ query?: PageQuery;
818
+ } | {
819
+ /** Full page route, for example `/pages/home/index`. */
820
+ path: string;
821
+ page?: never;
822
+ query?: PageQuery;
823
+ };
824
+ export type PreviewMediaAdvance = 'manual' | 'next' | 'loop';
825
+ /** One change-stream event / the `current` snapshot. */
826
+ export type PreviewMediaChange = {
827
+ index: number;
828
+ source: PreviewMediaShownSource;
829
+ };
830
+ export type PreviewMediaCloseReason = 'manual' | 'completed' | 'interrupted' | 'error';
831
+ /**
832
+ * Handle returned synchronously from `lx.previewMedia(...)` — synchronous so
833
+ * listeners can be attached before the first event fires:
834
+ * - `presented` resolves once the first pixel of the underlying media has
835
+ * been composited to screen. Use this to time the hide of an overlay
836
+ * surface above the preview so the swap is seamless. Never rejects;
837
+ * resolves with no value when the first frame is up. Safe to ignore.
838
+ * - `current` is a live `{ index, source }` snapshot of the item on screen,
839
+ * updated as the user swipes and as the session auto-advances.
840
+ * - `onChange(listener)` fires for every item change. Returns an
841
+ * unsubscribe function.
842
+ * - `completed` resolves `{ reason, index, source }` when the preview
843
+ * session ends (manual / auto / interrupted / error), or rejects on abort.
844
+ * If the call was aborted before any frame was presented, `presented` still
845
+ * resolves (with no value) once the abort takes effect — it never rejects,
846
+ * to keep fire-and-forget usage safe.
847
+ * @example
848
+ * const preview = lx.previewMedia({ sources, startIndex: 2 });
849
+ * preview.onChange(({ source }) => markAsViewed(source.path));
850
+ * const { reason, source } = await preview.completed;
851
+ */
852
+ export type PreviewMediaHandle = {
853
+ readonly presented: Promise<void>;
854
+ readonly current: PreviewMediaChange;
855
+ onChange(listener: (change: PreviewMediaChange) => void): () => void;
856
+ readonly completed: Promise<PreviewMediaResult>;
857
+ };
858
+ export type PreviewMediaOptions = string | PreviewMediaSingleOptions | PreviewMediaSequenceOptions;
859
+ export type PreviewMediaResult = {
860
+ /**
861
+ * Why the preview session finished.
862
+ */
863
+ reason: PreviewMediaCloseReason;
864
+ /**
865
+ * Index of the item on screen when the session closed.
866
+ */
867
+ index: number;
868
+ /**
869
+ * The item on screen when the session closed — "what the user just
870
+ * viewed/played", without mapping `index` back yourself.
871
+ */
872
+ source: PreviewMediaShownSource;
873
+ };
874
+ export type PreviewMediaSequenceOptions = {
875
+ /**
876
+ * Preview list. Supports images, videos, or a mixed queue.
877
+ */
878
+ sources: PreviewMediaSource[];
879
+ /**
880
+ * Initial item index in `sources`.
881
+ * Must be an integer.
882
+ * Out-of-range values are clamped by runtime.
883
+ * Default: `0`.
884
+ */
885
+ startIndex?: number;
886
+ /**
887
+ * Auto behavior for the preview session.
888
+ *
889
+ * - `manual`: never auto-advance
890
+ * - `next`: advance to the next item; if already on the last item, close the session
891
+ * - `loop`: advance to the next item; if already on the last item, wrap to the first item
892
+ *
893
+ * Default: `manual`
894
+ */
895
+ advance?: PreviewMediaAdvance;
896
+ /**
897
+ * Optional cancellation signal for the preview request.
898
+ *
899
+ * Aborting rejects the returned promise with a cancellation error and requests the active
900
+ * native preview session to close immediately.
901
+ */
902
+ signal?: AbortSignal;
903
+ /**
904
+ * Whether to show the top `current/total` indicator.
905
+ *
906
+ * Default: `true` when previewing multiple items, otherwise `false`.
907
+ */
908
+ showIndexIndicator?: boolean;
909
+ };
910
+ /**
911
+ * The item the user is (or was) looking at, handed back as the caller
912
+ * described it — `path` is returned verbatim, so it can be matched against
913
+ * the caller's own data without re-indexing an array.
914
+ */
915
+ export type PreviewMediaShownSource = {
916
+ /** The path exactly as passed in the request. */
917
+ path: string;
918
+ /** Resolved media kind (after extension inference when `type` was omitted). */
919
+ type: 'image' | 'video';
920
+ };
921
+ export type PreviewMediaSingleOptions = PreviewMediaSource & {
922
+ /**
923
+ * Auto behavior for the preview session.
924
+ *
925
+ * - `manual`: never auto-advance
926
+ * - `next`: advance to the next item; if already on the last item, close the session
927
+ * - `loop`: advance to the next item; if already on the last item, wrap to the first item
928
+ *
929
+ * Default: `manual`
930
+ */
931
+ advance?: PreviewMediaAdvance;
932
+ /**
933
+ * Optional cancellation signal for the preview request.
934
+ *
935
+ * Aborting rejects the returned promise with a cancellation error and requests the active
936
+ * native preview session to close immediately.
937
+ */
938
+ signal?: AbortSignal;
939
+ /**
940
+ * Whether to show the top `current/total` indicator.
941
+ *
942
+ * Default: `true` when previewing multiple items, otherwise `false`.
943
+ */
944
+ showIndexIndicator?: boolean;
945
+ };
946
+ export type PreviewMediaSource = {
947
+ /**
948
+ * Media source path.
949
+ * Recommended: `lx://` path (for example `lx://usercache/...`) or a sandbox-local path
950
+ * that can be resolved by runtime access rules.
951
+ */
952
+ path: string;
953
+ type?: 'image' | 'video';
954
+ /**
955
+ * Optional clockwise rotation in degrees (`0 | 90 | 180 | 270`).
956
+ * Default: when omitted, runtime resolves orientation from media metadata.
957
+ */
958
+ rotate?: MediaRotation;
959
+ /**
960
+ * Optional display fit mode for video preview.
961
+ * Default: `contain`.
962
+ */
963
+ objectFit?: MediaObjectFit;
964
+ /**
965
+ * Display duration in milliseconds.
966
+ * Effective when preview `advance` is not `manual`.
967
+ */
968
+ durationMs?: number;
969
+ };
970
+ export type ReLaunchOptions = PageTargetOptions;
971
+ export type ReadBinaryFileOptions = {
972
+ filePath: string;
973
+ encoding?: undefined;
974
+ };
975
+ export type ReadBinaryFileResult = {
976
+ data: ArrayBuffer;
977
+ };
978
+ export type ReadDirOptions = {
979
+ path: string;
980
+ };
981
+ export type ReadFileOptions = ReadTextFileOptions | ReadBinaryFileOptions;
982
+ export type ReadFileResult = ReadTextFileResult | ReadBinaryFileResult;
983
+ export type ReadTextFileOptions = {
984
+ filePath: string;
985
+ encoding: 'utf8' | 'base64';
986
+ };
987
+ export type ReadTextFileResult = {
988
+ data: string;
989
+ };
990
+ export type RedirectToOptions = PageTargetOptions;
991
+ export type RemoveOptions = {
992
+ path: string;
993
+ recursive?: boolean;
994
+ };
995
+ export type RenameOptions = {
996
+ oldPath: string;
997
+ newPath: string;
998
+ /** Defaults to false. */
999
+ overwrite?: boolean;
1000
+ };
1001
+ export type SaveMediaOptions = {
1002
+ filePath: string;
1003
+ };
1004
+ export type ScanCodeOptions = {
1005
+ onlyFromCamera?: boolean;
1006
+ scanType?: ('barCode' | 'qrCode' | 'datamatrix' | 'pdf417')[];
1007
+ };
1008
+ export type ScanCodeResult = {
1009
+ scanResult: string;
1010
+ scanType: string;
1011
+ };
1012
+ /** Share images, PDFs, or other files. */
1013
+ export type ShareFilesOptions = ShareTitleOptions & {
1014
+ /**
1015
+ * File paths returned by LingXia APIs to share. Images, PDFs, and other
1016
+ * documents are all represented as file paths.
1017
+ *
1018
+ * Use `lx.chooseFile` for system files and `lx.chooseMedia` for picked media;
1019
+ * pass the returned path here without parsing it.
1020
+ * Some platforms or receivers may limit multi-file shares. Share files one
1021
+ * at a time when targeting those receivers.
1022
+ *
1023
+ * `files` and `page` are mutually exclusive.
1024
+ * `text` is intentionally not supported for file shares because system
1025
+ * receivers handle text+attachment inconsistently.
1026
+ */
1027
+ files: string[];
1028
+ page?: never;
1029
+ text?: never;
1030
+ };
1031
+ export type ShareOptions = ShareTextOptions | SharePageOptions | ShareFilesOptions;
1032
+ export type SharePage = /**
1033
+ * Share the current page.
1034
+ */ true
1035
+ /**
1036
+ * Share the current page with query.
1037
+ */
1038
+ | {
1039
+ /**
1040
+ * Query appended to the current page. Query belongs to the page target and is
1041
+ * encoded into the AppLink URL.
1042
+ */
1043
+ query?: ShareQuery;
1044
+ };
1045
+ /** Share the current page as an AppLink. */
1046
+ export type SharePageOptions = ShareTextBaseOptions & {
1047
+ /**
1048
+ * Share the current page. The runtime uses the current appId and page path
1049
+ * implicitly and shares it through the host AppLink configuration.
1050
+ *
1051
+ * Rejects when the host app has no `appLinks.hosts` configuration because
1052
+ * receivers would not be able to open the shared page.
1053
+ *
1054
+ * `title` and `text` are presentation hints. Platforms and receivers may
1055
+ * ignore them; on iOS the URL is shared by itself so receivers can render it
1056
+ * as a webpage card when they support that.
1057
+ *
1058
+ * `page` and `files` are mutually exclusive.
1059
+ */
1060
+ page: SharePage;
1061
+ files?: never;
1062
+ };
1063
+ /** Share APIs. */
1064
+ export type ShareQuery = Record<string, string | number | boolean>;
1065
+ export type ShareResult = {
1066
+ /**
1067
+ * Best-effort completion flag. Some platforms can only confirm that the
1068
+ * system share UI was opened or closed.
1069
+ */
1070
+ completed?: boolean;
1071
+ };
1072
+ export type ShareTextBaseOptions = ShareTitleOptions & {
1073
+ /**
1074
+ * Share text body.
1075
+ */
1076
+ text?: string;
1077
+ };
1078
+ /**
1079
+ * Share title/text only. Receiver support is platform/app dependent; some
1080
+ * share extensions may reject text-only shares.
1081
+ */
1082
+ export type ShareTextOptions = ShareTextBaseOptions & {
1083
+ page?: never;
1084
+ files?: never;
1085
+ };
1086
+ export type ShareTitleOptions = {
1087
+ /**
1088
+ * Share title.
1089
+ */
1090
+ title?: string;
1091
+ };
1092
+ /**
1093
+ * One app-declared shell activator. Its `id` remains stable across
1094
+ * updates and activation. The shell only routes activation to the
1095
+ * callback; the app owns every resulting action.
1096
+ */
1097
+ export type ShellActivator = {
1098
+ id: string;
1099
+ icon: string;
1100
+ label: string;
1101
+ disabled?: boolean;
1102
+ onActivate: () => void;
1103
+ };
1104
+ /** Mutable presentation fields for an existing activator. */
1105
+ export type ShellActivatorUpdate = {
1106
+ icon?: string;
1107
+ label?: string;
1108
+ disabled?: boolean;
1109
+ };
1110
+ /** Shell chrome writer API (home lxapp only). */
1111
+ export type ShellApi = {
1112
+ activators: ShellActivatorsApi;
1113
+ };
1114
+ export type ShowActionSheetOptions = {
1115
+ itemList: string[];
1116
+ itemColor?: string;
1117
+ };
1118
+ export type ShowModalOptions = {
1119
+ title?: string;
1120
+ content?: string;
1121
+ showCancel?: boolean;
1122
+ cancelText?: string;
1123
+ cancelColor?: string;
1124
+ confirmText?: string;
1125
+ confirmColor?: string;
1126
+ };
1127
+ /** UI feedback, navigation, and surface control APIs. */
1128
+ export type ShowToastOptions = {
1129
+ title: string;
1130
+ icon?: 'success' | 'error' | 'loading' | 'none';
1131
+ image?: string;
1132
+ duration?: number;
1133
+ mask?: boolean;
1134
+ position?: 'top' | 'center' | 'bottom';
1135
+ };
1136
+ export type StatOptions = {
1137
+ path: string;
1138
+ };
1139
+ /** Persistent key-value storage backed by the lxapp database. */
1140
+ export type Storage = {
1141
+ get(key: string): Promise<unknown>;
1142
+ set(key: string, value: unknown): Promise<void>;
1143
+ delete(key: string): Promise<void>;
1144
+ clear(): Promise<void>;
1145
+ list(prefix?: string): Promise<IterableIterator<string>>;
1146
+ info(): Promise<StorageInfo>;
1147
+ };
1148
+ /** Current persistent-storage usage and configured limits. */
1149
+ export type StorageInfo = {
1150
+ currentSize: number;
1151
+ limitSize: number;
1152
+ keyCount: number;
1153
+ };
1154
+ export type StreamSourceOptions = {
1155
+ provider: string;
1156
+ isLive: boolean;
1157
+ duration?: number;
1158
+ params?: Record<string, unknown>;
1159
+ };
1160
+ export type Surface = SurfaceHandle & {
1161
+ readonly kind: 'overlay' | 'window';
1162
+ /**
1163
+ * Last-known visibility, kept in sync with the native side via show/hide
1164
+ * events. False once the surface has been closed. Safe to bind into
1165
+ * declarative UI; for event-driven updates subscribe via `onShow`/`onHide`.
1166
+ */
1167
+ readonly visible: boolean;
1168
+ /**
1169
+ * True until `close()` fires. After close the surface is detached and the
1170
+ * page instance is being torn down; further `show()` / `hide()` calls will
1171
+ * reject.
1172
+ */
1173
+ readonly alive: boolean;
1174
+ /**
1175
+ * Sends a message to the other side of a page surface.
1176
+ *
1177
+ * For the opener this targets the opened page. For the opened page this
1178
+ * targets the opener. URL surfaces have no page-side receiver.
1179
+ */
1180
+ postMessage(message: unknown): void;
1181
+ onMessage(handler: (message: unknown) => void): () => void;
1182
+ onClose(handler: (event: SurfaceClosedEvent) => void): () => void;
1183
+ /**
1184
+ * Fires when the surface transitions to visible, regardless of whether
1185
+ * `show()` was called on this side or on the peer. Returns an unsubscribe
1186
+ * function. Only fires on real state changes — calling `show()` on an
1187
+ * already-visible surface is a no-op for listeners.
1188
+ */
1189
+ onShow(handler: (event: SurfaceVisibilityEvent) => void): () => void;
1190
+ /**
1191
+ * Fires when the surface transitions to hidden, regardless of which side
1192
+ * triggered it. Returns an unsubscribe function. Only fires on real state
1193
+ * changes.
1194
+ */
1195
+ onHide(handler: (event: SurfaceVisibilityEvent) => void): () => void;
1196
+ close(): Promise<void>;
1197
+ /**
1198
+ * Toggle the surface to visible without tearing it down. The page instance
1199
+ * and its state survive a hide / show round-trip — only close() actually
1200
+ * destroys the surface and fires the onClose listener. Idempotent: calling
1201
+ * on an already-visible surface resolves without firing `onShow`.
1202
+ */
1203
+ show(): Promise<void>;
1204
+ /**
1205
+ * Hide the surface without destroying it. The page instance stays mounted,
1206
+ * so a subsequent show() restores the same scroll position, form input,
1207
+ * and JS state. Hidden surfaces still receive postMessage but are not
1208
+ * visible to the user. Idempotent.
1209
+ */
1210
+ hide(): Promise<void>;
1211
+ };
1212
+ /**
1213
+ * Surfaces (docked asides, floats, windows, browser tabs, declared surfaces)
1214
+ * and the desktop tray — the types behind `lx.openSurface`, `lx.onSurfaceContext`,
1215
+ * and `lx.tray`.
1216
+ */
1217
+ export type SurfaceCloseReason = 'user' | 'programmatic' | 'owner_closed' | 'app_closed' | 'failed'
1218
+ /**
1219
+ * The SDK reclaimed a long-hidden overlay surface for resource reasons.
1220
+ * Treat as a normal close: the page instance is gone; further postMessage /
1221
+ * show / hide calls will fail. The opener may immediately reopen if needed.
1222
+ */
1223
+ | 'reclaimed' | 'unknown';
1224
+ export type SurfaceClosedEvent = {
1225
+ id: string;
1226
+ kind: 'overlay' | 'window';
1227
+ reason: SurfaceCloseReason;
1228
+ };
1229
+ /**
1230
+ * The current surface viewport context, delivered to `lx.onSurfaceContext()`
1231
+ * so an lxapp can self-adapt (e.g. switch column count by `sizeClass`).
1232
+ */
1233
+ export type SurfaceContext = {
1234
+ /** compact (<600) / medium (600–840) / expanded (>840), with hysteresis. */
1235
+ sizeClass: 'compact' | 'medium' | 'expanded';
1236
+ /** Actual surface viewport width in logical pixels. */
1237
+ width: number;
1238
+ /** Actual surface viewport height in logical pixels. */
1239
+ height: number;
1240
+ };
1241
+ /** Edge an aside docks to; the Host decides the realized form by screen size. */
1242
+ export type SurfaceEdge = 'left' | 'right' | 'top' | 'bottom';
1243
+ /** Where a float popup anchors (default `center`). */
1244
+ export type SurfaceFloatPosition = 'center' | 'top' | 'bottom' | 'left' | 'right';
1245
+ export type SurfaceHandle = {
1246
+ readonly id: string;
1247
+ /** Standalone windows have no role in the primary shell graph. */
1248
+ readonly role?: SurfaceRole;
1249
+ readonly presentation: SurfacePresentation;
1250
+ readonly visible: boolean;
1251
+ readonly alive: boolean;
1252
+ /**
1253
+ * Show a host-managed surface. Dynamic page/url surfaces return a Promise;
1254
+ * host-declared surfaces may complete synchronously.
1255
+ */
1256
+ show(): void | Promise<void>;
1257
+ /**
1258
+ * Hide without destroying user-visible state when the platform supports it.
1259
+ */
1260
+ hide(): void | Promise<void>;
1261
+ /**
1262
+ * Destroy the live surface. Repeated close calls are idempotent.
1263
+ */
1264
+ close(): void | Promise<void>;
1265
+ onShow(handler: (event: SurfaceVisibilityEvent) => void): () => void;
1266
+ onHide(handler: (event: SurfaceVisibilityEvent) => void): () => void;
1267
+ onClose(handler: (event: SurfaceClosedEvent) => void): () => void;
1268
+ };
1269
+ /** Native interaction supplied by the host around page content. */
1270
+ export type SurfaceInteraction = {
1271
+ /** Show the standard circular close button. Default `false`. */
1272
+ closeButton?: boolean;
1273
+ /** Default `tapOutside` for floats and `manual` for windows. */
1274
+ dismiss?: 'tapOutside' | 'manual';
1275
+ /** Block interaction with content below. Default `false`. */
1276
+ modal?: boolean;
1277
+ };
1278
+ export type SurfacePresentation = 'main' | 'dock' | 'overlay' | 'popover' | 'sheet' | 'window';
1279
+ export type SurfaceRole = 'main' | 'aside' | 'float';
1280
+ /**
1281
+ * Detail payload for `onShow` / `onHide` events. `source` identifies which
1282
+ * Surface object initiated the visibility change so observers can
1283
+ * distinguish self-driven transitions from peer-driven ones (e.g. an opener
1284
+ * UI that wants to update its own button state only when the page side
1285
+ * toggled visibility).
1286
+ */
1287
+ export type SurfaceVisibilityEvent = {
1288
+ id: string;
1289
+ kind: 'overlay' | 'window';
1290
+ source: 'opener' | 'page';
1291
+ };
1292
+ export type SwitchTabOptions = PageTargetOptions;
1293
+ /** Native system Downloads path. Do not pass this to `FileManager`. */
1294
+ export type SystemDownloadsPath = string & {
1295
+ readonly [systemDownloadsPathBrand]: 'system-downloads-path';
1296
+ };
1297
+ export type TabBarRedDotOptions = {
1298
+ index: number;
1299
+ };
1300
+ export type TrayApi = globalThis.TrayApi;
1301
+ /**
1302
+ * Runtime control of the menu-bar (macOS) / system-tray (Windows) status item.
1303
+ * The tray is declared in `lingxia.yaml` (`tray:`); these update its dynamic
1304
+ * content at runtime.
1305
+ * **Desktop only.** Mobile platforms have no tray, so every method here is a
1306
+ * no-op there (it never throws) — safe to call from portable code. For an
1307
+ * app-icon badge that *is* cross-platform (including mobile), use
1308
+ * `lx.app.setBadge`.
1309
+ */
1310
+ export type TrayMenuItem = {
1311
+ label: string;
1312
+ /** Invoked when this item is clicked. */
1313
+ onClick?: () => void;
1314
+ enabled?: boolean;
1315
+ checked?: boolean;
1316
+ };
1317
+ export type TrayMenuSeparator = {
1318
+ separator: true;
1319
+ };
1320
+ export type UpdateFailedInfo = UpdateReadyInfo & {
1321
+ error?: string;
1322
+ };
1323
+ /** Runtime update APIs. */
1324
+ export type UpdateManager = {
1325
+ applyUpdate(): void;
1326
+ onUpdateReady(callback: (info: UpdateReadyInfo) => void): void;
1327
+ onUpdateFailed(callback: (info: UpdateFailedInfo) => void): void;
1328
+ };
1329
+ export type UpdateReadyInfo = {
1330
+ version?: string;
1331
+ isForceUpdate?: boolean;
1332
+ channel?: "release" | "preview" | "developer" | string;
1333
+ };
1334
+ export type UploadIteratorResult = {
1335
+ done: boolean;
1336
+ value?: UploadProgressEvent;
1337
+ };
1338
+ export type UploadOptions = {
1339
+ /** HTTP(S) destination URL. */
1340
+ url: string;
1341
+ /** Local file path or runtime-managed URI to upload. */
1342
+ filePath: string;
1343
+ /** Multipart field name. Default: `file`. */
1344
+ name?: string;
1345
+ /**
1346
+ * Optional request headers.
1347
+ * Restricted headers such as `Referer` are ignored by the runtime.
1348
+ */
1349
+ headers?: Record<string, string>;
1350
+ /** Optional extra `multipart/form-data` text fields. */
1351
+ formData?: Record<string, string>;
1352
+ /** Request timeout in milliseconds. */
1353
+ timeout?: number;
1354
+ /** Override multipart filename. */
1355
+ fileName?: string;
1356
+ /** Override file MIME type. */
1357
+ mimeType?: string;
1358
+ /** Optional abort signal. */
1359
+ signal?: AbortSignal;
1360
+ };
1361
+ export type UploadProgressEvent = {
1362
+ kind: 'progress' | 'canceled' | 'completed';
1363
+ uploadedBytes?: number;
1364
+ totalBytes?: number;
1365
+ progress?: number;
1366
+ result?: UploadResult;
1367
+ };
1368
+ export type UploadResult = {
1369
+ /** HTTP status code returned by the server. */
1370
+ statusCode: number;
1371
+ /** Response body decoded as UTF-8 text. */
1372
+ data: string;
1373
+ };
1374
+ export type UploadTask = PromiseLike<UploadResult> & AsyncIterable<UploadProgressEvent> & {
1375
+ next(): Promise<UploadIteratorResult>;
1376
+ /** Stops iteration only. Does not cancel the underlying upload task. */
1377
+ return(): Promise<UploadIteratorResult>;
1378
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<UploadResult | TResult>;
1379
+ finally(onfinally?: (() => void) | null): Promise<UploadResult>;
1380
+ cancel(): Promise<void>;
1381
+ wait(): Promise<UploadResult>;
1382
+ };
1383
+ export type VideoCompressQuality = 'low' | 'medium' | 'high';
1384
+ export type VideoContext = {
1385
+ play(): void;
1386
+ pause(): void;
1387
+ stop(): void;
1388
+ seek(position: number): void;
1389
+ requestFullScreen(): void;
1390
+ exitFullScreen(): void;
1391
+ setStreamSource(options: StreamSourceOptions): void;
1392
+ };
1393
+ /**
1394
+ * Local video metadata for client-side upload preflight and presentation.
1395
+ * Track-level codec and audio fields are best-effort. The receiving service
1396
+ * must still validate the uploaded bytes; this result does not indicate
1397
+ * whether the file already exists in cloud storage.
1398
+ */
1399
+ export type VideoInfo = {
1400
+ /**
1401
+ * Encoded display width in pixels.
1402
+ */
1403
+ width: number;
1404
+ /**
1405
+ * Encoded display height in pixels.
1406
+ */
1407
+ height: number;
1408
+ /**
1409
+ * Video duration in milliseconds.
1410
+ */
1411
+ durationMs: number;
1412
+ /**
1413
+ * Exact local file size in bytes.
1414
+ */
1415
+ size: number;
1416
+ /**
1417
+ * Clockwise rotation in degrees (usually `0 | 90 | 180 | 270`).
1418
+ */
1419
+ rotation?: number;
1420
+ /**
1421
+ * Average bitrate in bits per second (bps).
1422
+ */
1423
+ bitrate?: number;
1424
+ /**
1425
+ * Frame rate in frames per second (fps).
1426
+ */
1427
+ fps?: number;
1428
+ /**
1429
+ * Best-effort container MIME type, e.g. `video/mp4`.
1430
+ * It may be inferred from the file extension when the platform does not expose it.
1431
+ */
1432
+ type?: string;
1433
+ /**
1434
+ * Normalized video-track codec MIME type. Known values include `video/avc`,
1435
+ * `video/hevc`, `video/x-vnd.on2.vp8`, `video/x-vnd.on2.vp9`, `video/av01`,
1436
+ * `video/mp4v-es`, `video/mpeg2`, and `video/mjpeg`. Other valid `video/*`
1437
+ * values may be returned for codecs added by the platform. Omitted when the
1438
+ * platform cannot determine it.
1439
+ */
1440
+ videoCodec?: string;
1441
+ /**
1442
+ * Whether an audio track was detected. Omitted when the platform cannot determine it.
1443
+ */
1444
+ hasAudio?: boolean;
1445
+ /**
1446
+ * Best-effort audio-track codec MIME type, e.g. `audio/mp4a-latm` or `audio/opus`.
1447
+ * Omitted when there is no audio track or the platform cannot determine it.
1448
+ */
1449
+ audioCodec?: string;
1450
+ /**
1451
+ * Resolved path used by runtime (typically `lx://...`).
1452
+ */
1453
+ path: string;
1454
+ };
1455
+ export type WifiConnectedCallback = (info: WifiConnectedInfo) => void;
1456
+ export type WifiConnectedInfo = WifiInfo & {
1457
+ connected: boolean;
1458
+ state: string;
1459
+ };
1460
+ export type WindowSurfaceSize = {
1461
+ /** Initial window width in logical pixels. */
1462
+ width?: number;
1463
+ /** Initial window height in logical pixels. */
1464
+ height?: number;
1465
+ };
1466
+ export type WriteBinaryFileOptions = {
1467
+ filePath: string;
1468
+ data: BinaryFileData;
1469
+ encoding?: never;
1470
+ /** Defaults to false. */
1471
+ overwrite?: boolean;
1472
+ };
1473
+ export type WriteFileOptions = WriteTextFileOptions | WriteBinaryFileOptions;
1474
+ export type WriteTextFileOptions = {
1475
+ filePath: string;
1476
+ data: string;
1477
+ encoding?: 'utf8' | 'base64';
1478
+ /** Defaults to false. */
1479
+ overwrite?: boolean;
1480
+ };
1481
+ /** Host app base information. */
1482
+ export interface AppBaseInfo {
1483
+ /**
1484
+ * Raw system locale, unaffected by a saved in-app language override.
1485
+ * For the language the UI should actually render in, use
1486
+ * `display_language` instead.
1487
+ */
1488
+ locale: string;
1489
+ /**
1490
+ * Effective display language: a saved user override when set, else
1491
+ * `locale`. This is what native chrome and `lx.*` i18n strings follow.
1492
+ */
1493
+ displayLanguage: string;
1494
+ /**
1495
+ * Platform family: `"iOS"` / `"macOS"` / `"Android"` / `"Windows"` /
1496
+ * `"Harmony"`. Matches the View-side `usePlatform().os` value.
1497
+ */
1498
+ os: string;
1499
+ productName: string;
1500
+ version: string;
1501
+ SDKVersion: string;
1502
+ }
1503
+ /** Device info APIs. */
1504
+ export interface DeviceInfo {
1505
+ brand: string;
1506
+ model: string;
1507
+ marketName: string;
1508
+ osName: string;
1509
+ osVersion: string;
1510
+ }
1511
+ export interface FileStats {
1512
+ isFile: boolean;
1513
+ isDirectory: boolean;
1514
+ isSymlink: boolean;
1515
+ size: number;
1516
+ lastModifiedTime?: number;
1517
+ lastAccessedTime?: number;
1518
+ createTime?: number;
1519
+ }
1520
+ export interface ImageInfo {
1521
+ width: number;
1522
+ height: number;
1523
+ type: string;
1524
+ path: string;
1525
+ }
1526
+ /** Location information */
1527
+ export interface LocationInfo {
1528
+ /** Latitude, range -90~90, negative for south */
1529
+ latitude: number;
1530
+ /** Longitude, range -180~180, negative for west */
1531
+ longitude: number;
1532
+ /** Speed in m/s */
1533
+ speed?: number;
1534
+ /** Position accuracy in meters (smaller = more accurate) */
1535
+ accuracy?: number;
1536
+ /** Altitude in meters */
1537
+ altitude?: number;
1538
+ /** Vertical accuracy in meters */
1539
+ verticalAccuracy?: number;
1540
+ /** Horizontal accuracy in meters */
1541
+ horizontalAccuracy?: number;
1542
+ }
1543
+ export interface LxAppInfo {
1544
+ appId: string;
1545
+ appName: string;
1546
+ version: string;
1547
+ releaseType: LxAppReleaseType;
1548
+ }
1549
+ /** Options for removing TabBar badge */
1550
+ export interface RemoveTabBarBadgeOptions {
1551
+ index: number;
1552
+ }
1553
+ export interface ScreenInfo {
1554
+ width: number;
1555
+ height: number;
1556
+ scale: number;
1557
+ }
1558
+ /** Options for setNavigationBarColor */
1559
+ export interface SetNavigationBarColorOptions {
1560
+ frontColor: string;
1561
+ backgroundColor: string;
1562
+ }
1563
+ /** Options for setNavigationBarTitle */
1564
+ export interface SetNavigationBarTitleOptions {
1565
+ title: string;
1566
+ }
1567
+ /** Options for setting TabBar badge */
1568
+ export interface SetTabBarBadgeOptions {
1569
+ index: number;
1570
+ text: string;
1571
+ }
1572
+ /** Options for setting TabBar item */
1573
+ export interface SetTabBarItemOptions {
1574
+ index: number;
1575
+ text?: string;
1576
+ iconPath?: string;
1577
+ selectedIconPath?: string;
1578
+ }
1579
+ /** Options for setting TabBar style */
1580
+ export interface SetTabBarStyleOptions {
1581
+ color?: string;
1582
+ selectedColor?: string;
1583
+ backgroundColor?: string;
1584
+ borderStyle?: string;
1585
+ }
1586
+ /** System setting status */
1587
+ export interface SystemSettingInfo {
1588
+ bluetoothEnabled: boolean;
1589
+ locationEnabled: boolean;
1590
+ wifiEnabled: boolean;
1591
+ }
1592
+ /** Wi-Fi APIs. */
1593
+ export interface WifiInfo {
1594
+ /** Service Set Identifier (network name) */
1595
+ SSID: string;
1596
+ /** Basic Service Set Identifier (MAC address) */
1597
+ BSSID?: string;
1598
+ /** Whether the network is secure (requires password) */
1599
+ secure: boolean;
1600
+ /** Signal strength (0-100, higher is better) */
1601
+ signalStrength: number;
1602
+ /** Center frequency in MHz (if available) */
1603
+ frequency?: number;
1604
+ }
1605
+ export declare class DirEntry {
1606
+ private constructor();
1607
+ readonly name: string;
1608
+ readonly isFile: boolean;
1609
+ readonly isDirectory: boolean;
1610
+ readonly isSymlink: boolean;
1611
+ }
1612
+ export declare class FileManager {
1613
+ private constructor();
1614
+ exists(options: ExistsOptions): Promise<boolean>;
1615
+ stat(options: StatOptions): Promise<FileStats>;
1616
+ readDir(options: ReadDirOptions): Promise<AsyncIterableIterator<DirEntry>>;
1617
+ mkdir(options: MkdirOptions): Promise<void>;
1618
+ readFile(options: never): Promise<never>;
1619
+ writeFile(options: WriteFileOptions): Promise<void>;
1620
+ copyFile(options: CopyFileOptions): Promise<void>;
1621
+ rename(options: RenameOptions): Promise<void>;
1622
+ remove(options: RemoveOptions): Promise<void>;
1623
+ }
1624
+ export declare class JSMessagePort {
1625
+ constructor();
1626
+ static postMessage(payload: any): void;
1627
+ static onMessage(handler: (...args: any[]) => any): (...args: any[]) => any;
1628
+ }
1629
+ export declare class JSSurface {
1630
+ constructor();
1631
+ close(): Promise<void>;
1632
+ postMessage(payload: any): void;
1633
+ onMessage(handler: (...args: any[]) => any): (...args: any[]) => any;
1634
+ static onClose(handler: (...args: any[]) => any): (...args: any[]) => any;
1635
+ }
1636
+ export declare class JSUpdateManager {
1637
+ constructor();
1638
+ /** Apply update by restarting the app */
1639
+ applyUpdate(): void;
1640
+ onUpdateReady(cb: (...args: any[]) => any): void;
1641
+ onUpdateFailed(cb: (...args: any[]) => any): void;
1642
+ }
1643
+ export declare class JSVideoContext {
1644
+ constructor();
1645
+ play(): void;
1646
+ pause(): void;
1647
+ stop(): void;
1648
+ seek(position: number): void;
1649
+ requestFullScreen(): void;
1650
+ exitFullScreen(): void;
1651
+ setStreamSource(options: StreamSourceOptions): void;
1652
+ }
1653
+ declare global {
1654
+ interface HostAppApi {
1655
+ /**
1656
+ * `lx.app.screenshot(options?)` — capture the host app's window as a PNG.
1657
+ * App-level semantics, one level above any page/WebView capture: the image
1658
+ * is what the user sees of the whole app — host-drawn navigation chrome,
1659
+ * native overlays, and every composited WebView, not just this lxapp's web
1660
+ * content. Because that view can include other lxapps' UI, the API is
1661
+ * restricted to the home lxapp, like the other host-level APIs on `lx.app`.
1662
+ */
1663
+ screenshot(options?: AppScreenshotOptions): Promise<AppScreenshotResult>;
1664
+ /**
1665
+ * Check whether the host app has an update.
1666
+ * This host-level capability is restricted to the home lxapp. Calling it opts
1667
+ * the process into custom update handling. Incompatible updates are hidden as
1668
+ * `hasUpdate: false`; platforms that cannot apply a package may still return
1669
+ * metadata and reject when `update.apply()` is invoked.
1670
+ */
1671
+ checkUpdate(): Promise<HostAppUpdateCheckResult>;
1672
+ readonly envVersion: HostAppEnvVersion;
1673
+ getBaseInfo(): AppBaseInfo;
1674
+ /**
1675
+ * Exit the host app immediately without a confirmation dialog.
1676
+ * If the user should confirm first, call `lx.showModal(...)` and invoke this
1677
+ * only after confirmation.
1678
+ */
1679
+ exit(): void;
1680
+ /**
1681
+ * Set the app-icon badge, for example an unread count.
1682
+ * This targets the dock on macOS, taskbar on Windows, and home/launcher icon
1683
+ * on mobile. Null or an empty string clears it. Unsupported platforms treat
1684
+ * the call as a no-op.
1685
+ */
1686
+ setBadge(value: string | number | null): void;
1687
+ }
1688
+ }
1689
+ declare global {
1690
+ interface Lx {
1691
+ readonly app: HostAppApi;
1692
+ vibrateShort(): boolean;
1693
+ vibrateLong(): boolean;
1694
+ makePhoneCall(options: MakePhoneCallOptions): boolean;
1695
+ getDeviceInfo(): DeviceInfo;
1696
+ getScreenInfo(): ScreenInfo;
1697
+ getNetworkInfo(): Promise<NetworkInfo>;
1698
+ onNetworkChange(callback: NetworkChangeCallback): void;
1699
+ offNetworkChange(callback?: NetworkChangeCallback): void;
1700
+ /** Initialize WiFi module */
1701
+ startWifi(): Promise<void>;
1702
+ /** Stop WiFi module */
1703
+ stopWifi(): Promise<void>;
1704
+ /**
1705
+ * Connect to WiFi (async - waits for request submission, not actual connection)
1706
+ * This function returns when the connection request is successfully submitted to the system.
1707
+ * The actual connection status will be reported via onWifiConnected event.
1708
+ */
1709
+ connectWifi(options: ConnectWifiOptions): Promise<void>;
1710
+ /** Get WiFi list (scan results) */
1711
+ getWifiList(): Promise<WifiInfo[]>;
1712
+ /** Get connected WiFi info */
1713
+ getConnectedWifi(): Promise<WifiInfo>;
1714
+ onWifiConnected(callback: WifiConnectedCallback): void;
1715
+ offWifiConnected(callback?: WifiConnectedCallback): void;
1716
+ setDeviceOrientation(orientation: DeviceOrientation): boolean;
1717
+ onDeviceOrientationChange(callback: (event: DeviceOrientationChangeEvent) => void): void;
1718
+ offDeviceOrientationChange(callback?: (event: DeviceOrientationChangeEvent) => void): void;
1719
+ readonly env: LxEnv;
1720
+ downloadFile(options: never): never;
1721
+ uploadFile(options: UploadOptions): UploadTask;
1722
+ /**
1723
+ * Open a local file with the requested strategy.
1724
+ * Use `mode: "review"` when the UX requires in-app preview; otherwise prefer
1725
+ * `mode: "auto"`.
1726
+ */
1727
+ openFile(options: OpenFileOptions): Promise<void>;
1728
+ chooseFile(options?: ChooseFileOptions): Promise<ChooseFileResult>;
1729
+ chooseDirectory(options?: ChooseDirectoryOptions): Promise<ChooseDirectoryResult>;
1730
+ getFileManager(): FileManager;
1731
+ onKeyDown(callback: KeyEventCallback): void;
1732
+ offKeyDown(callback?: KeyEventCallback): void;
1733
+ onKeyUp(callback: KeyEventCallback): void;
1734
+ offKeyUp(callback?: KeyEventCallback): void;
1735
+ /** Get location function */
1736
+ getLocation(options?: GetLocationOptions): Promise<LocationInfo>;
1737
+ getLxAppInfo(): LxAppInfo;
1738
+ getImageInfo(options: GetImageInfoOptions): Promise<ImageInfo>;
1739
+ compressImage(options: CompressImageOptions): Promise<CompressImageResult>;
1740
+ chooseMedia(options?: ChooseMediaOptions): Promise<ChosenMediaEntry[]>;
1741
+ /**
1742
+ * Synchronously returns a JS handle so listeners can be attached before the
1743
+ * first event fires:
1744
+ * - `presented`: Promise, resolves with no value when the first pixel of the
1745
+ * underlying media is composited to screen. Also resolves unconditionally
1746
+ * once `completed` settles, so consumers can safely ignore it (it never
1747
+ * rejects).
1748
+ * - `current`: `{ index, source }` snapshot of the item on screen, updated
1749
+ * live as the user swipes / the session auto-advances.
1750
+ * - `onChange(listener)`: fires `{ index, source }` for every item change
1751
+ * (the initial item is seeded into `current`, and re-fired by native so
1752
+ * late platforms still converge); returns an unsubscribe function.
1753
+ * - `completed`: Promise resolving `{ reason, index, source }` when the
1754
+ * session ends, or rejecting on abort / error. `source` is the item that
1755
+ * was on screen when the preview closed — handed back verbatim so the
1756
+ * caller never re-indexes their own array.
1757
+ */
1758
+ previewMedia(options: PreviewMediaOptions): PreviewMediaHandle;
1759
+ saveImageToPhotosAlbum(options: SaveMediaOptions): Promise<void>;
1760
+ saveVideoToPhotosAlbum(options: SaveMediaOptions): Promise<void>;
1761
+ scanCode(options?: ScanCodeOptions): Promise<ScanCodeResult>;
1762
+ createVideoContext(componentId: string): VideoContext;
1763
+ /**
1764
+ * Reads local video metadata for upload preflight and presentation.
1765
+ * Size, dimensions, duration, and path form the portable core. Container type,
1766
+ * rotation, and track-level codec/audio fields are best-effort and may be
1767
+ * omitted when the platform cannot determine them. The receiving service must
1768
+ * still validate the uploaded bytes.
1769
+ */
1770
+ getVideoInfo(options: GetVideoInfoOptions): Promise<VideoInfo>;
1771
+ extractVideoThumbnail(options: ExtractVideoThumbnailOptions): Promise<ExtractVideoThumbnailResult>;
1772
+ compressVideo(options: CompressVideoOptions): CompressVideoTask;
1773
+ navigateToLxApp(options: NavigateToLxAppOptions): Promise<void>;
1774
+ navigateBackLxApp(): Promise<void>;
1775
+ share(options: ShareOptions): Promise<ShareResult>;
1776
+ getStorage(): Storage;
1777
+ /**
1778
+ * `lx.openSurface(spec)` — unified surface entry point. The spec is a
1779
+ * discriminated union keyed by exactly one of `page`, `surface`, or `url`:
1780
+ * - `{ page, as, position?, size?, query? }` opens one of this lxapp's own
1781
+ * pages as a `float` (overlay popup) or a `window` (bare standalone desktop
1782
+ * window). Pages cannot be docked as an `aside` — an aside shows external
1783
+ * content only.
1784
+ * - `{ surface, edge?, query? }` shows a host-declared surface by its `ui` id.
1785
+ * - `{ url }` opens an authorized HTTPS/file URL in the in-app chromed browser.
1786
+ */
1787
+ openSurface(spec: never): Promise<never>;
1788
+ /** `lx.openExternal(url)` — hand the url off to the OS default browser. */
1789
+ openExternal(url: string): void;
1790
+ /**
1791
+ * `lx.onSurfaceContext(handler)` — register a JS callback (scoped to this
1792
+ * lxapp's JS context), invoke it immediately, then again whenever that
1793
+ * presentation's actual viewport changes. Returns an unsubscribe fn.
1794
+ */
1795
+ onSurfaceContext(handler: (context: SurfaceContext) => void): () => void;
1796
+ getSystemSetting(): SystemSettingInfo;
1797
+ /** Show action sheet function for JavaScript */
1798
+ showActionSheet(options: ShowActionSheetOptions): Promise<ActionSheetResult>;
1799
+ /**
1800
+ * Get capsule button bounding client rect (async)
1801
+ * Returns Promise<{width, height, top, right, bottom, left}>
1802
+ */
1803
+ getCapsuleRect(): Promise<CapsuleRect>;
1804
+ /** Show modal function (async) */
1805
+ showModal(options: ShowModalOptions): Promise<ModalResult>;
1806
+ /** Set navigation bar title */
1807
+ setNavigationBarTitle(options: SetNavigationBarTitleOptions): boolean;
1808
+ /** Set navigation bar color */
1809
+ setNavigationBarColor(options: SetNavigationBarColorOptions): boolean;
1810
+ /** Hide home button */
1811
+ hideHomeButton(): boolean;
1812
+ /**
1813
+ * lx.startPullDownRefresh()
1814
+ * Programmatically start the pull-to-refresh animation.
1815
+ * This will show the refresh indicator and trigger the onPullDownRefresh lifecycle method.
1816
+ */
1817
+ startPullDownRefresh(): void;
1818
+ /**
1819
+ * lx.stopPullDownRefresh()
1820
+ * Stop the pull-to-refresh animation.
1821
+ * This should be called after the refresh operation is complete.
1822
+ */
1823
+ stopPullDownRefresh(): void;
1824
+ /** Navigate to a new page (forward navigation) */
1825
+ navigateTo(options: NavigateToOptions): Promise<PageMessagePort>;
1826
+ /** Navigate back to previous page */
1827
+ navigateBack(options: NavigateBackOptions): void;
1828
+ /** Redirect to a new page (replace current page) */
1829
+ redirectTo(options: RedirectToOptions): Promise<void>;
1830
+ /** Switch to a tab page */
1831
+ switchTab(options: SwitchTabOptions): Promise<void>;
1832
+ /** Relaunch to a new page (clear page stack) */
1833
+ reLaunch(options: ReLaunchOptions): Promise<void>;
1834
+ readonly shell: ShellApi;
1835
+ /** Show TabBar red dot */
1836
+ showTabBarRedDot(options: TabBarRedDotOptions): boolean;
1837
+ /** Hide TabBar red dot */
1838
+ hideTabBarRedDot(options: TabBarRedDotOptions): boolean;
1839
+ /** Set TabBar badge */
1840
+ setTabBarBadge(options: SetTabBarBadgeOptions): boolean;
1841
+ /** Remove TabBar badge */
1842
+ removeTabBarBadge(options: RemoveTabBarBadgeOptions): boolean;
1843
+ /** Show TabBar */
1844
+ showTabBar(): Promise<boolean>;
1845
+ /** Hide TabBar */
1846
+ hideTabBar(): Promise<boolean>;
1847
+ /** Set TabBar style */
1848
+ setTabBarStyle(options: SetTabBarStyleOptions): boolean;
1849
+ /** Set TabBar item */
1850
+ setTabBarItem(options: SetTabBarItemOptions): boolean;
1851
+ /** Show toast function */
1852
+ showToast(options: ShowToastOptions): Promise<void>;
1853
+ /** Hide toast function */
1854
+ hideToast(): Promise<void>;
1855
+ readonly tray: TrayApi;
1856
+ getUpdateManager(): UpdateManager;
1857
+ }
1858
+ }
1859
+ declare global {
1860
+ interface LxEnv {
1861
+ readonly USER_DATA_PATH: 'lx://userdata';
1862
+ readonly USER_CACHE_PATH: 'lx://usercache';
1863
+ }
1864
+ }
1865
+ declare global {
1866
+ interface ShellActivatorsApi {
1867
+ /**
1868
+ * Atomically replaces the complete desktop activator declaration. Home lxapp
1869
+ * only. Relative icons resolve from the home app bundle. Every entry is bound
1870
+ * to its generation-scoped callback; `replace([])` explicitly clears chrome.
1871
+ */
1872
+ replace(items: ShellActivator[]): void;
1873
+ /** Updates presentation fields for one stable id. Home lxapp only. */
1874
+ update(id: string, patch: ShellActivatorUpdate): void;
1875
+ /** Removes one stable id from the declaration. Home lxapp only. */
1876
+ remove(id: string): void;
1877
+ /** Clears the current runtime declaration. Home lxapp only. */
1878
+ clear(): void;
1879
+ }
1880
+ }
1881
+ declare global {
1882
+ interface TrayApi {
1883
+ /** lx.tray.setBadge(value) — the menu-bar / system-tray badge. Null/empty clears it. */
1884
+ setBadge(value: string | number | null): void;
1885
+ /** lx.tray.setIcon(icon) — replace the tray icon (a resource path). */
1886
+ setIcon(icon: string): void;
1887
+ /** lx.tray.setTitle(text) — text shown beside the icon (macOS). Empty clears it. */
1888
+ setTitle(text: string | null): void;
1889
+ /**
1890
+ * lx.tray.setMenu(items) — replace the tray dropdown menu. Each item is
1891
+ * `{ label, onClick?, enabled?, checked? }` or `{ separator: true }`. The native
1892
+ * menu is built from labels; clicks are routed back to each item's `onClick` by
1893
+ * index over the app event bus.
1894
+ */
1895
+ setMenu(items: Array<TrayMenuItem | TrayMenuSeparator>): void;
1896
+ /**
1897
+ * lx.tray.onClick(handler) — left-click on the tray icon. While at least one
1898
+ * handler is registered, the left-click runs only the handler(s); the tray's
1899
+ * configured surface action is suppressed. Returns an unsubscribe function.
1900
+ */
1901
+ onClick(handler: () => void): () => void;
1902
+ /** lx.tray.show() — show the tray status item. */
1903
+ show(): void;
1904
+ /** lx.tray.hide() — hide the tray status item. */
1905
+ hide(): void;
1906
+ }
1907
+ }
1908
+ export {};
1909
+ //# sourceMappingURL=logic.d.ts.map