@vestra-player/sdk 1.5.7 → 1.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +4 -1
- package/bin/vestra-plugin.mjs +194 -17
- package/dist/commands.d.ts +1 -2
- package/dist/commands.js +1 -2
- package/dist/i18n-tools.d.ts +67 -0
- package/dist/i18n-tools.js +731 -0
- package/dist/i18n.d.ts +130 -0
- package/dist/i18n.js +673 -0
- package/dist/player-runtime.d.ts +1 -0
- package/dist/player-runtime.js +1 -0
- package/dist/plugin/appearance.js +27 -1
- package/dist/plugin/language.d.ts +4 -0
- package/dist/plugin/language.js +5 -0
- package/dist/plugin/osd.d.ts +3 -0
- package/dist/plugin/osd.js +45 -9
- package/dist/plugin/packages.js +11 -65
- package/dist/plugin/resolvers.js +64 -0
- package/dist/plugin/runtime.d.ts +3 -1
- package/dist/plugin/runtime.js +6 -0
- package/dist/plugin/scope.d.ts +1 -0
- package/dist/plugin/scope.js +2 -0
- package/dist/plugin/testing.d.ts +155 -4
- package/dist/plugin/testing.js +332 -50
- package/dist/plugin/types.d.ts +247 -46
- package/dist/plugin/ui.js +4 -1
- package/dist/plugin/window.d.ts +4 -0
- package/dist/plugin/window.js +8 -0
- package/dist/wire.d.ts +29 -14
- package/dist/wire.js +12 -12
- package/llms-full.txt +399 -52
- package/llms.txt +44 -40
- package/package.json +1 -1
- package/slint/vestra/markdown.slint +5 -5
- package/slint/vestra/widgets.slint +4 -4
package/dist/plugin/types.d.ts
CHANGED
|
@@ -73,9 +73,8 @@ export interface Disposable {
|
|
|
73
73
|
* | `timeout` | A time limit ran out (`openStream` start-up, `tools.run`, `system.*` after 10 s). |
|
|
74
74
|
* | `stream`, `device` | `openStream`: the producer failed / the audio device is not ready. |
|
|
75
75
|
* | `backend-uncertain` | The player's backend blocked a filter stage; call `retry()`. |
|
|
76
|
-
* | `cleanup` | {@link PackageTrial.stop} could not confirm cleanup; call it again. |
|
|
77
76
|
* | `limit` | A player-wide limit was reached (for example the number of commands). |
|
|
78
|
-
* | `reserved` | {@link Packages.validate}, {@link PackageCandidate.
|
|
77
|
+
* | `reserved` | {@link Packages.validate}, {@link PackageCandidate.install}: the id is `vestra` or starts with `vestra.` (any case), which only the player's built-in plugins use (player 0.4.1). |
|
|
79
78
|
* | `versionMismatch` | The package needs a newer player (`minPlayerVersion`) or another `apiVersion`. |
|
|
80
79
|
* | `ui-prepare` | The player could not prepare a mounted panel or a settings page (its Slint file does not compile, a bound property is not declared, or another plugin's panel holds the slot); `message` has the diagnostics. |
|
|
81
80
|
* | `ui` | The player could not apply a property to a tool window or a settings page, or could not build the Options window (a property the Slint file does not declare, a value of the wrong type); `message` has Slint's reason. |
|
|
@@ -195,7 +194,7 @@ export interface Scope extends Disposable {
|
|
|
195
194
|
readonly media: MediaCapture;
|
|
196
195
|
/** Page-URL to stream-URL resolvers (`source.resolve`). */
|
|
197
196
|
readonly resolvers: Resolvers;
|
|
198
|
-
/** The installed plugins; validation,
|
|
197
|
+
/** The installed plugins; validation, installs (`plugins.manage` for changes). */
|
|
199
198
|
readonly packages: Packages;
|
|
200
199
|
/** On-screen messages over the video (`ui.osd`). */
|
|
201
200
|
readonly osd: Osd;
|
|
@@ -225,8 +224,10 @@ export interface Scope extends Disposable {
|
|
|
225
224
|
readonly timeline: Timeline;
|
|
226
225
|
/** Files dropped on the video area, by extension (`ui.drop`). */
|
|
227
226
|
readonly drops: Drops;
|
|
228
|
-
/** The player's palette. */
|
|
227
|
+
/** The player's palette and the saved interface language. */
|
|
229
228
|
readonly appearance: Appearance;
|
|
229
|
+
/** The interface language of this run (read-only). */
|
|
230
|
+
readonly i18n: I18n;
|
|
230
231
|
/** Pages in the player's options window (`ui.settings`). */
|
|
231
232
|
readonly settings: Settings;
|
|
232
233
|
/**
|
|
@@ -320,8 +321,7 @@ export interface Plugin extends Scope {
|
|
|
320
321
|
readonly id: string;
|
|
321
322
|
/**
|
|
322
323
|
* A writable directory for this plugin's own files (settings, remembered
|
|
323
|
-
* folders). Kept across restarts, disabling and upgrades
|
|
324
|
-
* temporary one. Write files atomically: to a temporary name, then rename.
|
|
324
|
+
* folders). Kept across restarts, disabling and upgrades. Write files atomically: to a temporary name, then rename.
|
|
325
325
|
* Throws `unavailable` when the player provided none.
|
|
326
326
|
*
|
|
327
327
|
* Location: `~/Library/Application Support/Vestra/plugin-data/<id>/` on
|
|
@@ -362,9 +362,9 @@ export interface CommandState {
|
|
|
362
362
|
export type Bindable<T> = T | (() => T);
|
|
363
363
|
/**
|
|
364
364
|
* A built-in top-level menu of the player, named in a command path as
|
|
365
|
-
* `@<id>` (see {@link CommandOptions.path}): Open
|
|
366
|
-
* Subtitles
|
|
367
|
-
*
|
|
365
|
+
* `@<id>` or by its English key (see {@link CommandOptions.path}): Open,
|
|
366
|
+
* Playback, Subtitles, Video, Audio, Screen, Settings. The list is
|
|
367
|
+
* `MENU_IDS` in `@vestra-player/sdk/testing`.
|
|
368
368
|
*/
|
|
369
369
|
export type MenuId = "open" | "playback" | "subtitles" | "video" | "audio" | "screen" | "settings";
|
|
370
370
|
/**
|
|
@@ -381,7 +381,7 @@ export type MenuId = "open" | "playback" | "subtitles" | "video" | "audio" | "sc
|
|
|
381
381
|
* ({@link MenuId}) sit at fixed orders, whatever is inside them: Open 110,
|
|
382
382
|
* Playback 200, Subtitles 300, Video 400, Audio 500, Screen 710, Settings
|
|
383
383
|
* 830 (player 0.3.0). This holds whether the path names the menu by id
|
|
384
|
-
* (`["@video", "Blur"]`) or by its
|
|
384
|
+
* (`["@video", "Blur"]`) or by its key (`["Video", "Blur"]`), so a plugin's
|
|
385
385
|
* item never moves the player's menu. Directly inside a built-in menu,
|
|
386
386
|
* `order` 0 (the default) sorts after every other order: an item without
|
|
387
387
|
* `order` goes at the end, after the player's own items (which all use 100
|
|
@@ -404,13 +404,20 @@ export interface CommandOptions {
|
|
|
404
404
|
* one segment is a top-level item. Omit it for a command that is not in the
|
|
405
405
|
* main menu (bindings and panel menus only); `title` is then required.
|
|
406
406
|
*
|
|
407
|
-
* Segments are
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
407
|
+
* Segments are English source text, and menus merge by them: commands
|
|
408
|
+
* of different plugins with the same leading segments share a submenu.
|
|
409
|
+
* The player shows each segment and the title in the interface language
|
|
410
|
+
* from the declaring plugin's catalog (`locales/<lang>.po`, see the
|
|
411
|
+
* [i18n guide](../../docs/how-to/i18n.md)); the player's own menus
|
|
412
|
+
* (Open, Playback, Subtitles, Video, Audio, Screen, Settings, and
|
|
413
|
+
* Playback ▸ Speed, Playback ▸ Seek) always show the player's words.
|
|
414
|
+
* A built-in menu can also be named by its id, `@` plus a {@link MenuId}:
|
|
415
|
+
* `@open`, `@playback`, `@subtitles`, `@video`, `@audio`, `@screen` or
|
|
416
|
+
* `@settings`. Only the first segment is read as an id; an unknown id, or
|
|
417
|
+
* an id with nothing after it, fails with `invalid`. Players up to 0.4.2
|
|
418
|
+
* titled their menus in Chinese (视频…): there `["Video", "Blur"]` is a
|
|
419
|
+
* menu of its own, so plugins for those players write `@video`; player
|
|
420
|
+
* 0.4.3 still accepts the old Chinese titles of its own menus.
|
|
414
421
|
*
|
|
415
422
|
* @example
|
|
416
423
|
* ```ts
|
|
@@ -418,7 +425,10 @@ export interface CommandOptions {
|
|
|
418
425
|
* ```
|
|
419
426
|
*/
|
|
420
427
|
path?: string[];
|
|
421
|
-
/**
|
|
428
|
+
/**
|
|
429
|
+
* Menu label (English source text, shown translated); defaults to the
|
|
430
|
+
* last path segment.
|
|
431
|
+
*/
|
|
422
432
|
title?: string;
|
|
423
433
|
/**
|
|
424
434
|
* Sibling order in the menu, ascending (integer, default 0). A submenu sits
|
|
@@ -1942,6 +1952,121 @@ export interface Appearance {
|
|
|
1942
1952
|
* @since 1.0.0
|
|
1943
1953
|
*/
|
|
1944
1954
|
set(theme: ThemeId): Promise<void>;
|
|
1955
|
+
/**
|
|
1956
|
+
* The saved interface language: `"system"` (follow the system's
|
|
1957
|
+
* languages, the default) or a {@link Locale}.
|
|
1958
|
+
*
|
|
1959
|
+
* @remarks
|
|
1960
|
+
* This is the choice for the next start. The language of this run is
|
|
1961
|
+
* {@link I18n.locale} and never changes while the player runs. Read before
|
|
1962
|
+
* activation; with `events` it follows other plugins' changes, without it
|
|
1963
|
+
* only this plugin's own. Players before 0.4.3 report `"system"`.
|
|
1964
|
+
*
|
|
1965
|
+
* @since 1.5.9
|
|
1966
|
+
*/
|
|
1967
|
+
readonly language: LanguagePreference;
|
|
1968
|
+
/**
|
|
1969
|
+
* Save the interface language for the next start.
|
|
1970
|
+
*
|
|
1971
|
+
* @remarks
|
|
1972
|
+
* The player keeps the choice in its interface state; the language
|
|
1973
|
+
* changes when the player starts again (tell the user, for example "Takes
|
|
1974
|
+
* effect after restart"). Every plugin with `events` hears the change in
|
|
1975
|
+
* {@link Appearance.language}.
|
|
1976
|
+
*
|
|
1977
|
+
* @capability ui.theme
|
|
1978
|
+
* @player 0.4.3
|
|
1979
|
+
*
|
|
1980
|
+
* @param language - `"system"` or a {@link Locale}.
|
|
1981
|
+
* @returns Resolves once the player saved it; {@link Appearance.language}
|
|
1982
|
+
* has the new value.
|
|
1983
|
+
*
|
|
1984
|
+
* @throws `invalid` (rejects) `language` is not `"system"` or a {@link Locale}.
|
|
1985
|
+
* @throws `capability` (rejects) The manifest does not declare `ui.theme`.
|
|
1986
|
+
* @throws `unsupported` (rejects) A player before 0.4.3.
|
|
1987
|
+
*
|
|
1988
|
+
* @example
|
|
1989
|
+
* ```ts
|
|
1990
|
+
* await plugin.appearance.setLanguage("de");
|
|
1991
|
+
* await plugin.osd.show("Takes effect after restart");
|
|
1992
|
+
* ```
|
|
1993
|
+
*
|
|
1994
|
+
* @since 1.5.9
|
|
1995
|
+
*/
|
|
1996
|
+
setLanguage(language: LanguagePreference): Promise<void>;
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* An interface language of the player: English (`en`, the source language
|
|
2000
|
+
* of every plugin text) or a translation. The list is `LOCALES` in
|
|
2001
|
+
* `@vestra-player/sdk/testing`.
|
|
2002
|
+
*
|
|
2003
|
+
* @remarks
|
|
2004
|
+
* Simplified Chinese is `zh-Hans`. There is no Traditional Chinese: a
|
|
2005
|
+
* system set to Traditional Chinese (Taiwan, Hong Kong, Macao) gets English.
|
|
2006
|
+
*
|
|
2007
|
+
* @since 1.5.9
|
|
2008
|
+
* @category UI
|
|
2009
|
+
*/
|
|
2010
|
+
export type Locale = "en" | "zh-Hans" | "ja" | "ko" | "de" | "fr" | "es";
|
|
2011
|
+
/**
|
|
2012
|
+
* The saved interface language ({@link Appearance.language}): follow the
|
|
2013
|
+
* system, or one {@link Locale}.
|
|
2014
|
+
*
|
|
2015
|
+
* @since 1.5.9
|
|
2016
|
+
* @category UI
|
|
2017
|
+
*/
|
|
2018
|
+
export type LanguagePreference = "system" | Locale;
|
|
2019
|
+
/**
|
|
2020
|
+
* Arguments of a template sentence ({@link Osd.show},
|
|
2021
|
+
* {@link OsdPanel.set}, {@link ConfirmOptions.args}): an array for `{}` and
|
|
2022
|
+
* `{0}`, `{1}` placeholders, or an object for `{name}` placeholders. At most
|
|
2023
|
+
* 16 strings and finite numbers; whole numbers print without a fraction.
|
|
2024
|
+
*
|
|
2025
|
+
* @since 1.5.9
|
|
2026
|
+
* @category UI
|
|
2027
|
+
*/
|
|
2028
|
+
export type TemplateArgs = readonly (string | number)[] | Readonly<Record<string, string | number>>;
|
|
2029
|
+
/**
|
|
2030
|
+
* The interface language of this run. `plugin.i18n`.
|
|
2031
|
+
*
|
|
2032
|
+
* @remarks
|
|
2033
|
+
* Plugins write no translation code. Every user-visible text is English
|
|
2034
|
+
* source text in one of three places, and the player translates it with
|
|
2035
|
+
* the plugin's own catalog (`locales/<lang>.po`, compiled into the package
|
|
2036
|
+
* by `vestra-plugin build`):
|
|
2037
|
+
*
|
|
2038
|
+
* 1. declarations: command titles and paths, settings page and panel
|
|
2039
|
+
* titles, the manifest's `name`, `punchline`, `description` and `tags`;
|
|
2040
|
+
* 2. Slint: `@tr("…")` in the plugin's `.slint` files;
|
|
2041
|
+
* 3. sentences the plugin hands the player: {@link Osd.show},
|
|
2042
|
+
* {@link OsdPanel.set} and {@link Dialogs.confirm} take a template and
|
|
2043
|
+
* its arguments (`osd.show("Speed {}×", [rate])`), never a sentence
|
|
2044
|
+
* composed in TypeScript.
|
|
2045
|
+
*
|
|
2046
|
+
* The language is fixed when the player starts: {@link I18n.locale} never
|
|
2047
|
+
* changes during a run. Read it for what is not text, such as the order of
|
|
2048
|
+
* names or a date format. `vestra-plugin i18n extract` collects the texts
|
|
2049
|
+
* into `locales/messages.pot`; see the
|
|
2050
|
+
* [i18n guide](../../docs/how-to/i18n.md).
|
|
2051
|
+
*
|
|
2052
|
+
* @capability None.
|
|
2053
|
+
*
|
|
2054
|
+
* @example Format a date the way the interface language writes it
|
|
2055
|
+
* ```ts
|
|
2056
|
+
* const day = new Date().toLocaleDateString(plugin.i18n.locale);
|
|
2057
|
+
* await plugin.osd.show("Today is {}", [day]);
|
|
2058
|
+
* ```
|
|
2059
|
+
*
|
|
2060
|
+
* @since 1.5.9
|
|
2061
|
+
* @category UI
|
|
2062
|
+
*/
|
|
2063
|
+
export interface I18n {
|
|
2064
|
+
/**
|
|
2065
|
+
* The interface language of this run, chosen at start-up from the saved
|
|
2066
|
+
* {@link Appearance.language} or the system's languages; English when
|
|
2067
|
+
* neither names a {@link Locale}. Players before 0.4.3 report `"en"`.
|
|
2068
|
+
*/
|
|
2069
|
+
readonly locale: Locale;
|
|
1945
2070
|
}
|
|
1946
2071
|
/**
|
|
1947
2072
|
* The categories of the Options window. The tree shows them in this order:
|
|
@@ -2582,6 +2707,16 @@ export interface ConfirmOptions {
|
|
|
2582
2707
|
destructive?: boolean;
|
|
2583
2708
|
/** A checkbox under the text, such as "Don't ask again"; 1–40 characters. */
|
|
2584
2709
|
checkbox?: string;
|
|
2710
|
+
/**
|
|
2711
|
+
* Values for the placeholders of `message` and `detail` (player 0.4.3).
|
|
2712
|
+
* Every text of the dialog is English source text that the player shows
|
|
2713
|
+
* translated from the plugin's catalog; `message` and `detail` are
|
|
2714
|
+
* templates like {@link Osd.show}'s. The length limits apply to the shown
|
|
2715
|
+
* text.
|
|
2716
|
+
*
|
|
2717
|
+
* @since 1.5.9
|
|
2718
|
+
*/
|
|
2719
|
+
args?: TemplateArgs;
|
|
2585
2720
|
}
|
|
2586
2721
|
/**
|
|
2587
2722
|
* The system's own dialogs: a confirmation alert and the open and save file
|
|
@@ -3351,18 +3486,20 @@ export interface OsdPanel extends Disposable {
|
|
|
3351
3486
|
* @capability ui.osd
|
|
3352
3487
|
*
|
|
3353
3488
|
* @param text - The text, with `\n` between lines: at most 32 lines and
|
|
3354
|
-
* 4096 bytes. `null` hides the block.
|
|
3489
|
+
* 4096 bytes once translated and formatted. `null` hides the block. A
|
|
3490
|
+
* template, like {@link Osd.show}'s.
|
|
3491
|
+
* @param args - Values for its placeholders (player 0.4.3).
|
|
3355
3492
|
*
|
|
3356
3493
|
* @example
|
|
3357
3494
|
* ```ts
|
|
3358
3495
|
* const info = plugin.osd.panel();
|
|
3359
|
-
* info.set("A:
|
|
3496
|
+
* info.set("A: {} s\nB: {} s", ["12.0", "18.5"]);
|
|
3360
3497
|
* info.set(null); // hide it
|
|
3361
3498
|
* ```
|
|
3362
3499
|
*
|
|
3363
3500
|
* @since 1.0.0
|
|
3364
3501
|
*/
|
|
3365
|
-
set(text: string | null): void;
|
|
3502
|
+
set(text: string | null, args?: TemplateArgs): void;
|
|
3366
3503
|
}
|
|
3367
3504
|
/**
|
|
3368
3505
|
* Text the player draws over the video: short messages and an information
|
|
@@ -3400,24 +3537,35 @@ export interface Osd {
|
|
|
3400
3537
|
* Replaces the message on screen, whichever plugin showed it. A message
|
|
3401
3538
|
* that is on screen when the plugin stops still disappears on time.
|
|
3402
3539
|
*
|
|
3540
|
+
* The text is a template in English: the player shows its translation
|
|
3541
|
+
* from the plugin's catalog, with the placeholders (`{}`, `{0}`, `{name}`;
|
|
3542
|
+
* `{{` and `}}` for braces) filled from `args`. Without `args` the text
|
|
3543
|
+
* shows as it is (braces included). Untranslated, the English template is
|
|
3544
|
+
* formatted. Never compose the sentence in TypeScript
|
|
3545
|
+
* (`` `Speed ${rate}×` ``): translators can only translate whole templates.
|
|
3546
|
+
*
|
|
3403
3547
|
* @capability ui.osd
|
|
3404
3548
|
*
|
|
3405
|
-
* @param text - 1–200 characters
|
|
3549
|
+
* @param text - The template, 1–200 characters once translated and
|
|
3550
|
+
* formatted; line breaks become spaces.
|
|
3551
|
+
* @param args - Values for its placeholders (player 0.4.3; older players
|
|
3552
|
+
* show the template as it is).
|
|
3406
3553
|
* @returns Resolves once the message is on screen.
|
|
3407
3554
|
*
|
|
3408
|
-
* @throws `invalid` (rejects)
|
|
3409
|
-
* than 200 characters.
|
|
3555
|
+
* @throws `invalid` (rejects) The shown text is empty, only white space,
|
|
3556
|
+
* or longer than 200 characters, or `args` is not a {@link TemplateArgs}.
|
|
3410
3557
|
* @throws `unavailable` (rejects) The player runs without a user interface.
|
|
3411
3558
|
* @throws `capability` (rejects) The manifest does not declare `ui.osd`.
|
|
3412
3559
|
*
|
|
3413
3560
|
* @example
|
|
3414
3561
|
* ```ts
|
|
3415
3562
|
* await plugin.osd.show("Bookmark added");
|
|
3563
|
+
* await plugin.osd.show("Speed {}×", [plugin.player.state.rate]);
|
|
3416
3564
|
* ```
|
|
3417
3565
|
*
|
|
3418
3566
|
* @since 1.0.0
|
|
3419
3567
|
*/
|
|
3420
|
-
show(text: string): Promise<void>;
|
|
3568
|
+
show(text: string, args?: TemplateArgs): Promise<void>;
|
|
3421
3569
|
/**
|
|
3422
3570
|
* Create this plugin's information block.
|
|
3423
3571
|
*
|
|
@@ -4008,6 +4156,47 @@ export interface Resolvers {
|
|
|
4008
4156
|
* error's message.
|
|
4009
4157
|
*/
|
|
4010
4158
|
add(options: ResolverOptions): Resolver;
|
|
4159
|
+
/**
|
|
4160
|
+
* The extensions some plugin's file resolver handles (SDK 1.5.8, player
|
|
4161
|
+
* 0.4.2): lower case, without the dot, sorted, each once; not who
|
|
4162
|
+
* registered them. Reading needs no capability; `[]` from older players.
|
|
4163
|
+
* Without `events` it is the list from when the plugin first read it.
|
|
4164
|
+
* Use it to accept such files beside the player's own media types, for
|
|
4165
|
+
* example in a playlist's drop or folder scan.
|
|
4166
|
+
*
|
|
4167
|
+
* @example
|
|
4168
|
+
* ```ts
|
|
4169
|
+
* const MEDIA = ["mp4", "mkv", "mp3"];
|
|
4170
|
+
* const accepted = (path: string) => {
|
|
4171
|
+
* const extension = path.split(".").pop()?.toLowerCase() ?? "";
|
|
4172
|
+
* return MEDIA.includes(extension) || plugin.resolvers.fileTypes.includes(extension);
|
|
4173
|
+
* };
|
|
4174
|
+
* ```
|
|
4175
|
+
*
|
|
4176
|
+
* @capability None.
|
|
4177
|
+
* @player 0.4.2
|
|
4178
|
+
* @since 1.5.8
|
|
4179
|
+
*/
|
|
4180
|
+
readonly fileTypes: readonly string[];
|
|
4181
|
+
/**
|
|
4182
|
+
* {@link Resolvers.fileTypes} changed: a file resolver was added, or its
|
|
4183
|
+
* plugin stopped. Needs `events`; without it the listener never fires.
|
|
4184
|
+
*
|
|
4185
|
+
* @param listener - Receives the new list.
|
|
4186
|
+
* @returns A handle that removes the listener.
|
|
4187
|
+
*
|
|
4188
|
+
* @example
|
|
4189
|
+
* ```ts
|
|
4190
|
+
* plugin.resolvers.onFileTypesChange((types) => {
|
|
4191
|
+
* void plugin.osd.show(`Also accepted: ${types.join(", ")}`);
|
|
4192
|
+
* });
|
|
4193
|
+
* ```
|
|
4194
|
+
*
|
|
4195
|
+
* @capability `events`
|
|
4196
|
+
* @player 0.4.2
|
|
4197
|
+
* @since 1.5.8
|
|
4198
|
+
*/
|
|
4199
|
+
onFileTypesChange(listener: (types: string[]) => void): Disposable;
|
|
4011
4200
|
}
|
|
4012
4201
|
/**
|
|
4013
4202
|
* The manifest of a package, as validated. The display fields and
|
|
@@ -4099,11 +4288,6 @@ export interface PackageCandidate {
|
|
|
4099
4288
|
readonly manifest: PackageManifest;
|
|
4100
4289
|
/** The checks the player ran. */
|
|
4101
4290
|
readonly checks: string[];
|
|
4102
|
-
/**
|
|
4103
|
-
* Load it temporarily alongside the installed plugins. A reserved id
|
|
4104
|
-
* (`vestra.*`) fails with `reserved`.
|
|
4105
|
-
*/
|
|
4106
|
-
trial(): Promise<PackageTrial>;
|
|
4107
4291
|
/**
|
|
4108
4292
|
* Install it. The same source upgrades the installed plugin (its data
|
|
4109
4293
|
* stays); another source fails with `conflict` unless `replace` is set;
|
|
@@ -4114,17 +4298,6 @@ export interface PackageCandidate {
|
|
|
4114
4298
|
*/
|
|
4115
4299
|
install(options?: InstallOptions): Promise<PackageChange>;
|
|
4116
4300
|
}
|
|
4117
|
-
/** A trial load of a package. Disposing it stops the trial and waits for cleanup. */
|
|
4118
|
-
export interface PackageTrial extends Disposable {
|
|
4119
|
-
/** The trial's status as the player reports it. */
|
|
4120
|
-
readonly status: string;
|
|
4121
|
-
/**
|
|
4122
|
-
* Stop and wait until the host confirmed cleanup. Rejects with code
|
|
4123
|
-
* `cleanup` when the host stopped the trial without confirming cleanup;
|
|
4124
|
-
* calling `stop()` again then asks the host again.
|
|
4125
|
-
*/
|
|
4126
|
-
stop(): Promise<void>;
|
|
4127
|
-
}
|
|
4128
4301
|
/** The progress of an install, rollback or uninstall. */
|
|
4129
4302
|
export type PackageChangeStatus = "preparing" | "activating" | "restoring" | "committed" | "cancelled" | "failed" | "failedDegraded" | "tooLate";
|
|
4130
4303
|
/**
|
|
@@ -4149,8 +4322,8 @@ export interface PluginInfo {
|
|
|
4149
4322
|
id: string;
|
|
4150
4323
|
/** Version, `null` when unknown. */
|
|
4151
4324
|
version: string | null;
|
|
4152
|
-
/** From the install library, a `--plugin` development load
|
|
4153
|
-
origin: "installed" | "development"
|
|
4325
|
+
/** From the install library, or a `--plugin` development load. */
|
|
4326
|
+
origin: "installed" | "development";
|
|
4154
4327
|
/** Run state. */
|
|
4155
4328
|
state: "starting" | "running" | "disabled" | "failed" | "stopped";
|
|
4156
4329
|
/** Why it failed (`state: "failed"`). */
|
|
@@ -4166,7 +4339,7 @@ export interface PluginInfo {
|
|
|
4166
4339
|
* replaced. `false` from players before 0.2.0.
|
|
4167
4340
|
*/
|
|
4168
4341
|
builtin: boolean;
|
|
4169
|
-
/** Where an installed plugin came from; `null` for development loads
|
|
4342
|
+
/** Where an installed plugin came from; `null` for development loads. */
|
|
4170
4343
|
source: PackageSource | null;
|
|
4171
4344
|
/**
|
|
4172
4345
|
* Its data directory (`plugin.dataDirectory` of that plugin); `null` when
|
|
@@ -4184,6 +4357,30 @@ export interface PluginInfo {
|
|
|
4184
4357
|
* @since 1.5.2
|
|
4185
4358
|
*/
|
|
4186
4359
|
warnings?: readonly PluginWarning[];
|
|
4360
|
+
/**
|
|
4361
|
+
* The manifest's display texts in the interface language, translated
|
|
4362
|
+
* with that package's catalog; absent from players before 0.4.3 (read
|
|
4363
|
+
* `manifest.json` there).
|
|
4364
|
+
*
|
|
4365
|
+
* @since 1.5.9
|
|
4366
|
+
*/
|
|
4367
|
+
display?: PluginDisplay;
|
|
4368
|
+
}
|
|
4369
|
+
/**
|
|
4370
|
+
* {@link PluginInfo.display}: a package's `name`, `punchline`,
|
|
4371
|
+
* `description` and `tags` as the player shows them.
|
|
4372
|
+
*
|
|
4373
|
+
* @since 1.5.9
|
|
4374
|
+
*/
|
|
4375
|
+
export interface PluginDisplay {
|
|
4376
|
+
/** `name`, translated; `null` when the manifest has none. */
|
|
4377
|
+
readonly name: string | null;
|
|
4378
|
+
/** `punchline`, translated; `null` when the manifest has none. */
|
|
4379
|
+
readonly punchline: string | null;
|
|
4380
|
+
/** `description`, translated; `null` when the manifest has none. */
|
|
4381
|
+
readonly description: string | null;
|
|
4382
|
+
/** `tags`, each translated. */
|
|
4383
|
+
readonly tags: readonly string[];
|
|
4187
4384
|
}
|
|
4188
4385
|
/**
|
|
4189
4386
|
* One refusal in {@link PluginInfo.warnings}.
|
|
@@ -4222,6 +4419,10 @@ export interface Packages {
|
|
|
4222
4419
|
* Validate a package directory (`plugins.manage`). A package whose id is
|
|
4223
4420
|
* reserved for the built-in plugins (`vestra` or `vestra.*`) fails with
|
|
4224
4421
|
* `reserved` (player 0.4.1).
|
|
4422
|
+
*
|
|
4423
|
+
* The player keeps the 32 most recent candidates of all plugins; an
|
|
4424
|
+
* older one's `install` fails with `stale` (validate again). Before
|
|
4425
|
+
* player 0.4.2 the 33rd validation of a run failed with `busy` instead.
|
|
4225
4426
|
*/
|
|
4226
4427
|
validate(directory: string): Promise<PackageCandidate>;
|
|
4227
4428
|
/**
|
|
@@ -4240,7 +4441,7 @@ export interface Packages {
|
|
|
4240
4441
|
/**
|
|
4241
4442
|
* Stop or start a plugin (`plugins.manage`). An installed plugin stays
|
|
4242
4443
|
* disabled across launches; a development load only for this run.
|
|
4243
|
-
* `invalid` to disable oneself, `
|
|
4444
|
+
* `invalid` to disable oneself, `missing` unknown.
|
|
4244
4445
|
* `busy` while it is being installed.
|
|
4245
4446
|
*/
|
|
4246
4447
|
setEnabled(id: string, enabled: boolean): Promise<void>;
|
|
@@ -4248,7 +4449,7 @@ export interface Packages {
|
|
|
4248
4449
|
* Remove an installed plugin (`plugins.manage`); `removeData` also deletes
|
|
4249
4450
|
* its data directory, otherwise reinstalling it from the same source
|
|
4250
4451
|
* reconnects to its data. Its user bindings stay (as orphans).
|
|
4251
|
-
* `unsupported` for built-ins
|
|
4452
|
+
* `unsupported` for built-ins and development loads, `missing`
|
|
4252
4453
|
* unknown, `invalid` for oneself.
|
|
4253
4454
|
*/
|
|
4254
4455
|
uninstall(id: string, options?: {
|
package/dist/plugin/ui.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Tool windows, docked panels and system dialogs. */
|
|
2
|
+
import { templateArgs } from "./osd.js";
|
|
2
3
|
import { readFileSync } from "node:fs";
|
|
3
4
|
import { basename, extname, resolve } from "node:path";
|
|
4
5
|
import { failure, Latest, quiet } from "./runtime.js";
|
|
@@ -651,7 +652,8 @@ export const dialogs = (scope) => {
|
|
|
651
652
|
};
|
|
652
653
|
return {
|
|
653
654
|
async confirm(options) {
|
|
654
|
-
const { message, detail, confirm, cancel, destructive, checkbox } = options ?? {};
|
|
655
|
+
const { message, detail, confirm, cancel, destructive, checkbox, args } = options ?? {};
|
|
656
|
+
const values = templateArgs(args);
|
|
655
657
|
const length = (text, min, max) => typeof text === "string" &&
|
|
656
658
|
[...text].length >= min &&
|
|
657
659
|
[...text].length <= max;
|
|
@@ -669,6 +671,7 @@ export const dialogs = (scope) => {
|
|
|
669
671
|
...(cancel === undefined ? {} : { cancel }),
|
|
670
672
|
...(destructive === undefined ? {} : { destructive }),
|
|
671
673
|
...(checkbox === undefined ? {} : { checkbox }),
|
|
674
|
+
...(values === undefined ? {} : { args: values }),
|
|
672
675
|
});
|
|
673
676
|
return {
|
|
674
677
|
confirmed: answer.confirmed === true,
|
package/dist/plugin/window.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export declare class WindowService {
|
|
|
19
19
|
start(): void;
|
|
20
20
|
/** The palette, as the `window.state` reply carried it (`plugin.appearance`). */
|
|
21
21
|
appearance: string | undefined;
|
|
22
|
+
/** The file resolvers' extensions, as the reply carried them (`plugin.resolvers.fileTypes`). */
|
|
23
|
+
fileTypes: string[] | undefined;
|
|
24
|
+
/** The saved interface language, as the reply carried it (`plugin.appearance.language`). */
|
|
25
|
+
language: string | undefined;
|
|
22
26
|
accept(facts: WindowFacts): void;
|
|
23
27
|
read(): Promise<void>;
|
|
24
28
|
watch(listener: (state: WindowState) => void): {
|
package/dist/plugin/window.js
CHANGED
|
@@ -52,9 +52,17 @@ export class WindowService {
|
|
|
52
52
|
}
|
|
53
53
|
/** The palette, as the `window.state` reply carried it (`plugin.appearance`). */
|
|
54
54
|
appearance;
|
|
55
|
+
/** The file resolvers' extensions, as the reply carried them (`plugin.resolvers.fileTypes`). */
|
|
56
|
+
fileTypes;
|
|
57
|
+
/** The saved interface language, as the reply carried it (`plugin.appearance.language`). */
|
|
58
|
+
language;
|
|
55
59
|
accept(facts) {
|
|
56
60
|
if (facts.appearance)
|
|
57
61
|
this.appearance = facts.appearance;
|
|
62
|
+
if (facts.language)
|
|
63
|
+
this.language = facts.language;
|
|
64
|
+
if (Array.isArray(facts.fileTypes))
|
|
65
|
+
this.fileTypes = [...facts.fileTypes];
|
|
58
66
|
const next = view(facts);
|
|
59
67
|
if (JSON.stringify(next) === JSON.stringify(this.state))
|
|
60
68
|
return;
|
package/dist/wire.d.ts
CHANGED
|
@@ -25,12 +25,6 @@ export interface PackageValidation {
|
|
|
25
25
|
checks: string[];
|
|
26
26
|
trustedExecution: true;
|
|
27
27
|
}
|
|
28
|
-
export interface PackageTrial {
|
|
29
|
-
trialId: number;
|
|
30
|
-
activationOwner?: number;
|
|
31
|
-
status: string;
|
|
32
|
-
cleanupConfirmed?: boolean;
|
|
33
|
-
}
|
|
34
28
|
export interface InstalledPackage {
|
|
35
29
|
revision: number;
|
|
36
30
|
current: null | {
|
|
@@ -102,7 +96,7 @@ export declare class HostError extends Error {
|
|
|
102
96
|
export interface PackageInfo {
|
|
103
97
|
id: string;
|
|
104
98
|
version: string | null;
|
|
105
|
-
origin: "installed" | "development"
|
|
99
|
+
origin: "installed" | "development";
|
|
106
100
|
state: "starting" | "running" | "disabled" | "failed" | "stopped";
|
|
107
101
|
error: string | null;
|
|
108
102
|
capabilities: string[];
|
|
@@ -118,6 +112,13 @@ export interface PackageInfo {
|
|
|
118
112
|
slot?: string;
|
|
119
113
|
owner?: string;
|
|
120
114
|
}[];
|
|
115
|
+
/** The manifest's display texts in the interface language (player 0.4.3). */
|
|
116
|
+
display?: {
|
|
117
|
+
name: string | null;
|
|
118
|
+
punchline: string | null;
|
|
119
|
+
description: string | null;
|
|
120
|
+
tags: string[];
|
|
121
|
+
};
|
|
121
122
|
}
|
|
122
123
|
/** Where an installed package came from (`packages.install` `source`). */
|
|
123
124
|
export type WireSource = {
|
|
@@ -175,6 +176,12 @@ export interface WindowFacts {
|
|
|
175
176
|
};
|
|
176
177
|
/** The palette (`plugin.appearance`), with the `window.state` reply; a newer player may name a palette this SDK does not list. */
|
|
177
178
|
appearance?: string;
|
|
179
|
+
/** The file resolvers' extensions (`plugin.resolvers.fileTypes`; player 0.4.2). */
|
|
180
|
+
fileTypes?: string[];
|
|
181
|
+
/** The saved interface language, `"system"` or a locale (player 0.4.3). */
|
|
182
|
+
language?: string;
|
|
183
|
+
/** The interface language of this run (player 0.4.3). */
|
|
184
|
+
locale?: string;
|
|
178
185
|
}
|
|
179
186
|
/** One timeline mark as the player merges them (`timeline.marks`). */
|
|
180
187
|
export interface WireMark {
|
|
@@ -280,11 +287,20 @@ export interface WireSystemInfo {
|
|
|
280
287
|
primary: boolean;
|
|
281
288
|
}[];
|
|
282
289
|
}
|
|
290
|
+
/** Template arguments on the wire (`osd.show`, `osd.panel`, `dialogs.confirm`). */
|
|
291
|
+
export type TemplateArgsJson = (string | number)[] | {
|
|
292
|
+
[name: string]: string | number;
|
|
293
|
+
};
|
|
283
294
|
export interface Transport {
|
|
284
295
|
request<T>(method: string, params?: Json): Promise<T>;
|
|
285
296
|
on(event: string, listener: (data: unknown) => void): () => void;
|
|
286
297
|
/** Replaces the real local services (test host). */
|
|
287
298
|
local?: LocalServices;
|
|
299
|
+
/**
|
|
300
|
+
* The interface language of this run (`plugin.i18n.locale`): the runner
|
|
301
|
+
* passes the player's `VESTRA_LOCALE`, the test host its `locale`.
|
|
302
|
+
*/
|
|
303
|
+
locale?: string;
|
|
288
304
|
}
|
|
289
305
|
export declare function createWire(transport: Transport): {
|
|
290
306
|
processing: {
|
|
@@ -310,6 +326,7 @@ export declare function createWire(transport: Transport): {
|
|
|
310
326
|
cancelled: boolean;
|
|
311
327
|
paths: string[];
|
|
312
328
|
}>;
|
|
329
|
+
/** Message and detail are templates formatted with `args` (player 0.4.3). */
|
|
313
330
|
confirm: (options: {
|
|
314
331
|
[key: string]: Json;
|
|
315
332
|
}) => Promise<{
|
|
@@ -355,6 +372,8 @@ export declare function createWire(transport: Transport): {
|
|
|
355
372
|
/** The palette (`ui.theme` to change it). */
|
|
356
373
|
appearance: {
|
|
357
374
|
set: (theme: string) => Promise<void>;
|
|
375
|
+
/** The interface language for the next start (player 0.4.3). */
|
|
376
|
+
setLanguage: (language: string) => Promise<void>;
|
|
358
377
|
};
|
|
359
378
|
/** Settings pages in the player's options window (`ui.settings`). */
|
|
360
379
|
settings: {
|
|
@@ -473,9 +492,10 @@ export declare function createWire(transport: Transport): {
|
|
|
473
492
|
} | null) => Promise<void>;
|
|
474
493
|
step: (direction: "next" | "previous") => Promise<void>;
|
|
475
494
|
};
|
|
495
|
+
/** `text` is a template in the plugin's catalog, formatted with `args` (player 0.4.3). */
|
|
476
496
|
osd: {
|
|
477
|
-
show: (text: string) => Promise<void>;
|
|
478
|
-
panel: (text: string | null) => Promise<void>;
|
|
497
|
+
show: (text: string, args?: TemplateArgsJson) => Promise<void>;
|
|
498
|
+
panel: (text: string | null, args?: TemplateArgsJson) => Promise<void>;
|
|
479
499
|
};
|
|
480
500
|
layout: {
|
|
481
501
|
state: () => Promise<{
|
|
@@ -530,11 +550,6 @@ export declare function createWire(transport: Transport): {
|
|
|
530
550
|
validate: (directory: string, apiVersion?: string) => Promise<PackageValidation>;
|
|
531
551
|
/** Player 0.2.0: a `.vxp` file. */
|
|
532
552
|
validateArchive: (file: string) => Promise<PackageValidation>;
|
|
533
|
-
/** `requestId` recovers a lost first reply in this owner session. */
|
|
534
|
-
trial: (token: string, requestId: string) => Promise<PackageTrial>;
|
|
535
|
-
trialStateByRequest: (requestId: string) => Promise<PackageTrial>;
|
|
536
|
-
trialState: (trialId: number) => Promise<PackageTrial>;
|
|
537
|
-
stopTrial: (trialId: number) => Promise<PackageTrial>;
|
|
538
553
|
installed: (id: string) => Promise<InstalledPackage>;
|
|
539
554
|
/** `source` and `replace` are sent only when given (player 0.2.0). */
|
|
540
555
|
install: (token: string, expectedRevision: number, requestId: string, options?: {
|