@vestra-player/sdk 1.6.0 → 1.6.2
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 +28 -8
- package/dist/docs-tree.json.gz +0 -0
- package/dist/i18n.js +0 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/testing.d.ts +14 -8
- package/dist/plugin/testing.js +23 -18
- package/dist/plugin/types.d.ts +59 -35
- package/dist/processing.d.ts +33 -0
- package/dist/wire.d.ts +1 -1
- package/dist/wire.js +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.2
|
|
4
|
+
|
|
5
|
+
**Who must change: nobody, but check `TestHost` tests of a full sidebar or of `keepsRunning` with a background tab.** No change to the TypeScript API or the wire, `apiVersion` stays `vestra/1`, no new capability, no player version needed. `TestHost` follows player 0.7.3: it no longer refuses a ninth sidebar tab, and `keepsRunning` lists a sidebar panel only while its tab is the current tab, as `"its sidebar tab is the current tab"`. A test that expected `conflict` for a ninth tab, or `"a mounted panel"` for a sidebar panel, now fails.
|
|
6
|
+
|
|
7
|
+
- **Sidebar tabs without a limit** (player 0.7.3; the player's [sidebar tabs design](https://github.com/vestrasys/vestra-player/blob/main/doc/architecture/sidebar-tabs.md)). The sidebar takes any number of tabs: the strip shows the tabs that fit and a `»` menu at its end lists all of them, the current one checked. Players 0.4.x to 0.7.2 refused a ninth tab with `conflict` (「侧栏最多 8 个页签」); player 0.7.3 never refuses a sidebar mount for that. `Panel.ready`, [Windows, panels, settings pages, dialogs and the OSD](docs/explanation/ui.md#shared-space) and `TestHost` say so. The SDK's copy of the player's Chinese texts (`HOST_ZH_HANS`) drops "The sidebar holds at most {} tabs", which the player no longer has.
|
|
8
|
+
- **A background tab does not keep its plugin running** (player 0.7.3). The current tab keeps its plugin running as busy work; a sidebar panel never makes a plugin resident. A plugin whose sidebar panel is in a background tab, and that holds nothing else that keeps it running, goes to standby after the idle time like any idle plugin (stop reason `idle`); the player keeps its tab, with its title, in the strip and the `»` menu. Showing the tab starts the plugin again: `activate` runs and mounts the same panel (same file and component), which takes the tab over, and `Panel.ready` resolves again. The new process mounts with the properties its `activate` passes, so keep what the panel shows in session storage, the only state that survives standby, and restore it in `activate`. `Panel.state`, [Windows, panels…](docs/explanation/ui.md#panel), [How a plugin runs › Idle plugins are stopped](docs/explanation/plugins.md#idle-plugins-are-stopped) and [How the player runs and talks to plugins](docs/explanation/host-and-node.md) (the recorded `ui.mount`, the `panel_shown` wake) describe it. `TestHost.keepsRunning` lists `"its sidebar tab is the current tab"` while it is, and nothing for a background tab; `"a mounted panel"` is now for the bottom bar and the backdrop only.
|
|
9
|
+
|
|
10
|
+
## 1.6.1
|
|
11
|
+
|
|
12
|
+
**Who must change: nobody.** Docs only: no change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability.
|
|
13
|
+
|
|
14
|
+
- **Player versions corrected to 0.7.1.** Players 0.6.6 to 0.6.8 and 0.7.0 were internal builds that were never published; 0.7.1 is the first published player with the plugin supervisor, on-demand start for everyone and selectable Markdown. Every "player 0.6.6", "0.6.7", "0.6.8" and "planned for player 0.6.x" label now reads player 0.7.1, and `"minPlayerVersion": "0.6.8"` for selectable Markdown is now `"0.7.1"`. A plugin that set `"0.6.8"` keeps loading on 0.7.1 and later. The tables of [How the player runs and talks to plugins](docs/explanation/host-and-node.md), [How a plugin runs](docs/explanation/plugins.md#idle-plugins-are-stopped) and [Reference: limits › Plugin processes](docs/reference/limits.md#plugin-processes) show the 0.7.1 values in one column (start timeout 60 s and no start retry after it, 5 s stop grace, idle time 30 s, process budget, memory pressure). The entries of 1.5.58 and 1.6.0 are aligned the same way. Behaviour that player 0.6.4 already shipped (stop reasons, `InstallOptions.enabled`) is no longer called planned.
|
|
15
|
+
- **Player release version** ([Reference: manifest › Player versions](docs/reference/manifest.md#player-versions), `AppInfo.version`, `minPlayerVersion`). From player 0.7.1, `plugin.app.version` and the version `minPlayerVersion` is compared with are the player release version, which can differ from the host binary version. Plugins compare against the release version.
|
|
16
|
+
- **Windows GPU rendering** ([Reference: platforms](docs/reference/platforms.md), [Offer a GPU rendering switch](docs/how-to/gpu-rendering.md)). Windows has a GPU renderer since player 0.5.14 (Direct3D 12), experimental and off by default: **Video ▸ GPU Rendering (Experimental)** or `VESTRA_RENDER=gpu` turns it on. Software (CPU) mode, the default there, cannot run render options or plugin shaders (`unsupported`); platforms lists plugin shaders in their own row.
|
|
17
|
+
- **The `lut3d` `.cube` format** (`VideoNode`, [Video and audio processing](docs/explanation/processing.md)). FFmpeg's `.cube` reader (`parse_cube` in `libavfilter/vf_lut3d.c`) reads the table: `LUT_3D_SIZE N`, optional `TITLE` and `DOMAIN_MIN`/`DOMAIN_MAX`, then N³ lines `r g b`, red changing fastest. Lines before `LUT_3D_SIZE` are skipped. Any other keyword after it, such as `MIN` or `MAX`, makes FFmpeg refuse the file, and the chain fails with "error running command (-12)". The player checks only the header.
|
|
18
|
+
|
|
3
19
|
## 1.6.0
|
|
4
20
|
|
|
5
|
-
**Who must change: nobody.** No change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability. New since 1.5.58 for plugin authors: Markdown the user can select and copy (`selectable` on `MarkdownView` and `MarkdownBlocks`, `plain` and `links` on `MarkdownBlock`, in the SDK's copy of the player's `@vestra/markdown.slint`; a plugin that uses them sets `"minPlayerVersion": "0.
|
|
21
|
+
**Who must change: nobody.** No change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability. New since 1.5.58 for plugin authors: Markdown the user can select and copy (`selectable` on `MarkdownView` and `MarkdownBlocks`, `plain` and `links` on `MarkdownBlock`, in the SDK's copy of the player's `@vestra/markdown.slint`; a plugin that uses them sets `"minPlayerVersion": "0.7.1"`), and, from player 0.7.1, plugins started on demand by default: a plugin starts on its first use and is stopped when idle, so `activate` can run many times and must never wait for its own commands or views (see 1.5.58). This is a minor release because it adds backward-compatible API and marks that milestone; nothing is removed or changed, and a plugin built with 1.5.x keeps working as it is.
|
|
6
22
|
|
|
7
|
-
|
|
8
|
-
|
|
23
|
+
_Player versions aligned in 1.6.1: players 0.6.6 to 0.6.8 and 0.7.0 were internal builds, never published; 0.7.1 is the first published player with these features._
|
|
24
|
+
|
|
25
|
+
- **Selectable Markdown** (player 0.7.1; the SDK's `slint/vestra/markdown.slint` is synced with the player's). `MarkdownView` and `MarkdownBlocks` take `in property <bool> selectable: false`. With `true`, a paragraph, heading, list item or quote without links is shown as its plain text in a read-only selectable text field (right-click Copy / Select All, where Copy with nothing selected copies the whole block; Ctrl+C / Ctrl+A; each field is a Tab stop); a block with links keeps its clickable links, and its right-click menu copies it as plain text with each address after its link text, `text (url)`, plus Copy Link when it has one link. Code blocks are always selectable, whatever `selectable` says (in player 0.7.1 this applies to every plugin's Markdown). A selection stays inside one block and is lost when its row scrolls out of a `MarkdownView`. `MarkdownBlock` gains `plain: string` (the block as plain text) and `links: [string]` (its link addresses). Older players do not have the property: set `"minPlayerVersion": "0.7.1"` before using it. See [Reference: theme › Markdown](docs/reference/theme.md#markdown).
|
|
26
|
+
- **Start retries corrected** ([How the player runs and talks to plugins](docs/explanation/host-and-node.md#the-start-deadline), [Reference: limits](docs/reference/limits.md#plugin-processes), [How a plugin runs](docs/explanation/plugins.md#restarts-activate-can-run-more-than-once)). 1.5.58 said a start that is not ready within the start timeout is tried up to three more times. That was the internal build 0.6.6; from player 0.7.1 a timed-out start gets one try (60 s) and is not retried, and only a process that cannot be created is tried again (about 250 ms, 500 ms and 1 s apart).
|
|
9
27
|
|
|
10
28
|
## 1.5.58
|
|
11
29
|
|
|
12
|
-
**Who must change: nobody.** Documentation only: no change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability, no player version needed. Plugin authors should read what the player's new plugin supervisor does with their plugin (
|
|
30
|
+
**Who must change: nobody.** Documentation only: no change to the TypeScript API, the wire or `TestHost`, `apiVersion` stays `vestra/1`, no new capability, no player version needed. Plugin authors should read what the player's new plugin supervisor does with their plugin (written for the internal build 0.6.6 and the defaults planned for 0.6.7; player 0.7.1 is the first published player with it, with the 0.6.7 defaults), and check that `activate` never waits for its own commands or views.
|
|
31
|
+
|
|
32
|
+
_Player versions aligned in 1.6.1: players 0.6.6 to 0.6.8 and 0.7.0 were internal builds, never published; 0.7.1 is the first published player with these features._
|
|
13
33
|
|
|
14
|
-
- **The plugin supervisor, as a plugin sees it** ([How the player runs and talks to plugins](docs/explanation/host-and-node.md), [How a plugin runs](docs/explanation/plugins.md)).
|
|
15
|
-
- **[Reference: limits › Plugin processes](docs/reference/limits.md#plugin-processes)**: heap cap, start timeout, retries, start limit, restart pauses, stop graces, quit, idle time, request timeout, start slots (`min(4, max(2, cores / 2))` plus a reserve for clicks), held triggers (64), waiting starts (256), the process budget (`clamp(physical MiB / 2 × 0.30 / 85, 3, 16)`) and the memory pressure thresholds (both
|
|
16
|
-
- **`StopReason`** lists when each reason comes with the supervisor: `quit` also after a lost GPU device, `disable` clears session storage, `idle` also for the process budget and memory pressure (
|
|
17
|
-
- **`appearance.changed` says what changed** (player 0.
|
|
34
|
+
- **The plugin supervisor, as a plugin sees it** ([How the player runs and talks to plugins](docs/explanation/host-and-node.md), [How a plugin runs](docs/explanation/plugins.md)). The internal build 0.6.6: a failed start is tried up to three more times; a built-in that crashes starts again by itself after 3 s, 6 s…; the fifth crash within 10 minutes stops a plugin until it is reloaded; an own process's JavaScript heap is capped at 512 MB (V8's heap only, not `Buffer` contents or addons), and passing it ends the process with "<name> ran out of memory"; a process that ended by itself gets no `runtime.stop`; without on-demand start a third-party plugin is listed as failed on its first crash, as before; at quit every plugin is stopped at once with 1 s in all; and two processes of one plugin never use its data directory at the same time. With on-demand start (lazy activation, `VESTRA_LAZY=1` in 0.6.6): a crashed plugin keeps its entries, shown disabled with the reason during a pause of 1 s, 2 s, 4 s…, and starts again on its next use (a resident plugin by itself); third-party plugins start a few at a time, clicks first; every start holds its clicks, resolutions, drops and view callbacks until `runtime.ready` (so an `activate` that awaits its own command or view callback waits until the start timeout); at most 64 are held per plugin, and one that cannot be taken is answered ("<name> is busy", "… could not start", "… is disabled") instead of dropped; busy work (a `busy` command, a dialog, a settings page shown, a resolution) keeps a plugin running with no time limit, and its idle time counts from when the work ends. Player 0.7.1 (planned as 0.6.7): on-demand start for everyone; a process budget for the machine's memory and the system's memory pressure put idle plugins in standby early, with the stop reason `idle`; idle time 30 s, start timeout 60 s, 5 s grace for a disable, uninstall, reload, upgrade or standby, a 5-minute cap on a player request awaiting the plugin's reply (a resolution; declared busy work stays uncapped), and a resident plugin never goes to standby. The source excerpts of host code that no longer exists (the lazy-activation trigger list, the 15-second activation record, the 250 ms idle poll, the stop's 5 ms poll) are replaced by descriptions of the current behaviour.
|
|
35
|
+
- **[Reference: limits › Plugin processes](docs/reference/limits.md#plugin-processes)**: heap cap, start timeout, retries, start limit, restart pauses, stop graces, quit, idle time, request timeout, start slots (`min(4, max(2, cores / 2))` plus a reserve for clicks), held triggers (64), waiting starts (256), the process budget (`clamp(physical MiB / 2 × 0.30 / 85, 3, 16)`) and the memory pressure thresholds (both from player 0.7.1), for the internal build 0.6.6 and for 0.7.1 (planned as 0.6.7).
|
|
36
|
+
- **`StopReason`** lists when each reason comes with the supervisor: `quit` also after a lost GPU device, `disable` clears session storage, `idle` also for the process budget and memory pressure (player 0.7.1; never for a busy plugin), `failed` also for a start timeout (possibly while `activate` runs) and, from player 0.7.1, an unanswered request; a crash or running out of memory is no stop at all. The stop reasons are no longer described as planned: they shipped in player 0.6.4. **`PluginInfo.process`** `"idle"` also covers the pause after a crash before a plugin starts again. `Plugin`, `DisposeInfo` and [Store a plugin's data](docs/how-to/store-data.md) give the new stop graces.
|
|
37
|
+
- **`appearance.changed` says what changed** (player 0.7.1): `"changed": ["theme"]` or `["language"]` beside `theme` and `language`. This SDK does not read it yet; a later release uses it so that a plugin woken by a language change no longer hears its unchanged theme once.
|
|
18
38
|
|
|
19
39
|
## 1.5.57
|
|
20
40
|
|
package/dist/docs-tree.json.gz
CHANGED
|
Binary file
|
package/dist/i18n.js
CHANGED
|
@@ -943,7 +943,6 @@ export const HOST_ZH_HANS = {
|
|
|
943
943
|
sidebar: "侧栏",
|
|
944
944
|
"video backdrop": "视频背景",
|
|
945
945
|
"The {} is used by {}": "{}已被 {} 使用",
|
|
946
|
-
"The sidebar holds at most {} tabs": "侧栏最多 {} 个页签",
|
|
947
946
|
"{} is resolved by {}": "{} 已由 {} 解析",
|
|
948
947
|
"File type .{}": "文件类型 .{}",
|
|
949
948
|
"Not available in fullscreen": "全屏时不可用",
|
package/dist/plugin/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface PluginInstance {
|
|
|
22
22
|
/**
|
|
23
23
|
* Stop the plugin: dispose the root scope, then stop the runtime.
|
|
24
24
|
* `info.reason` (SDK 1.5.54) is why: the runner passes `runtime.stop`'s
|
|
25
|
-
* `data.reason` (
|
|
25
|
+
* `data.reason` (player 0.6.4), or `"host-lost"` when its input closed
|
|
26
26
|
* without a `runtime.stop`. It reaches `plugin.stopReason` and every
|
|
27
27
|
* `onDispose` cleanup; a reason the SDK does not know reads as
|
|
28
28
|
* `undefined`. A second call runs no cleanup again and keeps the first reason.
|
package/dist/plugin/testing.d.ts
CHANGED
|
@@ -2451,7 +2451,7 @@ export declare class TestHost implements Transport {
|
|
|
2451
2451
|
* adds or upgrades the entry in {@link TestHost.packages} following the
|
|
2452
2452
|
* player's source rules: the same source upgrades, another source needs
|
|
2453
2453
|
* `replace` (`conflict` otherwise), a built-in id is `unsupported`. As
|
|
2454
|
-
* player 0.6.4
|
|
2454
|
+
* player 0.6.4 and later, the installed entry's `state` follows
|
|
2455
2455
|
* {@link "@vestra-player/sdk"!InstallOptions.enabled}: a first install
|
|
2456
2456
|
* runs, an update of a `disabled` entry stays `disabled` unless `enabled`
|
|
2457
2457
|
* is `true`, and `enabled: false` installs it `disabled`. Set
|
|
@@ -2475,7 +2475,7 @@ export declare class TestHost implements Transport {
|
|
|
2475
2475
|
readonly candidates: Map<string, PackageManifest>;
|
|
2476
2476
|
/**
|
|
2477
2477
|
* Which player's install rule `packages.install` plays. `true` (default,
|
|
2478
|
-
* SDK 1.5.55): player 0.6.4
|
|
2478
|
+
* SDK 1.5.55): player 0.6.4 and later, where an update or reinstall
|
|
2479
2479
|
* keeps a `disabled` plugin disabled unless the plugin passes
|
|
2480
2480
|
* {@link "@vestra-player/sdk"!InstallOptions.enabled}. `false`: players
|
|
2481
2481
|
* up to 0.6.3, where every install runs the plugin and `enabled` is
|
|
@@ -2782,12 +2782,18 @@ export declare class TestHost implements Transport {
|
|
|
2782
2782
|
close(): void;
|
|
2783
2783
|
/**
|
|
2784
2784
|
* Why the player would keep this plugin running while nothing uses it
|
|
2785
|
-
* (lazy activation, player 0.5.21), one line per reason
|
|
2786
|
-
*
|
|
2787
|
-
*
|
|
2788
|
-
* its open windows
|
|
2789
|
-
*
|
|
2790
|
-
*
|
|
2785
|
+
* (lazy activation, player 0.5.21), one line per reason: an event it
|
|
2786
|
+
* listens to that is not one the player wakes it for (with what listens
|
|
2787
|
+
* and where it was added), its panel in the bottom bar or the backdrop,
|
|
2788
|
+
* its open windows (these as the player's log says them), and, from
|
|
2789
|
+
* player 0.7.3, its sidebar tab while that is the current tab. The
|
|
2790
|
+
* player counts the current tab as busy work, not as something live: it
|
|
2791
|
+
* keeps the plugin running only while the tab is shown, and a sidebar
|
|
2792
|
+
* panel in a background tab is no reason at all (the plugin may go to
|
|
2793
|
+
* standby; showing the tab starts it again). Empty: the player may stop
|
|
2794
|
+
* it while idle and start it again on its next use. Filter chains,
|
|
2795
|
+
* streams, jobs and the like (which also keep a plugin running) are not
|
|
2796
|
+
* listed.
|
|
2791
2797
|
*
|
|
2792
2798
|
* @capability None.
|
|
2793
2799
|
* @since 1.5.40
|
package/dist/plugin/testing.js
CHANGED
|
@@ -314,8 +314,6 @@ const TEST_ZH_HANS = {
|
|
|
314
314
|
"External SRT": "外部 SRT",
|
|
315
315
|
"External ASS": "外部 ASS",
|
|
316
316
|
};
|
|
317
|
-
/** The player's limit of sidebar tabs. */
|
|
318
|
-
const MAX_SIDEBAR_TABS = 8;
|
|
319
317
|
/**
|
|
320
318
|
* The player's refusal of a declaration (commands.rs `CommandError`): code
|
|
321
319
|
* `invalid`, `conflict` or `limit`, its message prefixed as the player's.
|
|
@@ -3100,7 +3098,7 @@ export class TestHost {
|
|
|
3100
3098
|
* adds or upgrades the entry in {@link TestHost.packages} following the
|
|
3101
3099
|
* player's source rules: the same source upgrades, another source needs
|
|
3102
3100
|
* `replace` (`conflict` otherwise), a built-in id is `unsupported`. As
|
|
3103
|
-
* player 0.6.4
|
|
3101
|
+
* player 0.6.4 and later, the installed entry's `state` follows
|
|
3104
3102
|
* {@link "@vestra-player/sdk"!InstallOptions.enabled}: a first install
|
|
3105
3103
|
* runs, an update of a `disabled` entry stays `disabled` unless `enabled`
|
|
3106
3104
|
* is `true`, and `enabled: false` installs it `disabled`. Set
|
|
@@ -3124,7 +3122,7 @@ export class TestHost {
|
|
|
3124
3122
|
candidates = new Map();
|
|
3125
3123
|
/**
|
|
3126
3124
|
* Which player's install rule `packages.install` plays. `true` (default,
|
|
3127
|
-
* SDK 1.5.55): player 0.6.4
|
|
3125
|
+
* SDK 1.5.55): player 0.6.4 and later, where an update or reinstall
|
|
3128
3126
|
* keeps a `disabled` plugin disabled unless the plugin passes
|
|
3129
3127
|
* {@link "@vestra-player/sdk"!InstallOptions.enabled}. `false`: players
|
|
3130
3128
|
* up to 0.6.3, where every install runs the plugin and `enabled` is
|
|
@@ -3983,12 +3981,18 @@ export class TestHost {
|
|
|
3983
3981
|
}
|
|
3984
3982
|
/**
|
|
3985
3983
|
* Why the player would keep this plugin running while nothing uses it
|
|
3986
|
-
* (lazy activation, player 0.5.21), one line per reason
|
|
3987
|
-
*
|
|
3988
|
-
*
|
|
3989
|
-
* its open windows
|
|
3990
|
-
*
|
|
3991
|
-
*
|
|
3984
|
+
* (lazy activation, player 0.5.21), one line per reason: an event it
|
|
3985
|
+
* listens to that is not one the player wakes it for (with what listens
|
|
3986
|
+
* and where it was added), its panel in the bottom bar or the backdrop,
|
|
3987
|
+
* its open windows (these as the player's log says them), and, from
|
|
3988
|
+
* player 0.7.3, its sidebar tab while that is the current tab. The
|
|
3989
|
+
* player counts the current tab as busy work, not as something live: it
|
|
3990
|
+
* keeps the plugin running only while the tab is shown, and a sidebar
|
|
3991
|
+
* panel in a background tab is no reason at all (the plugin may go to
|
|
3992
|
+
* standby; showing the tab starts it again). Empty: the player may stop
|
|
3993
|
+
* it while idle and start it again on its next use. Filter chains,
|
|
3994
|
+
* streams, jobs and the like (which also keep a plugin running) are not
|
|
3995
|
+
* listed.
|
|
3992
3996
|
*
|
|
3993
3997
|
* @capability None.
|
|
3994
3998
|
* @since 1.5.40
|
|
@@ -4012,7 +4016,13 @@ export class TestHost {
|
|
|
4012
4016
|
if (!WAKE_EVENTS.includes(event))
|
|
4013
4017
|
for (const why of this.listeningWhy.get(event) ?? ["a listener"])
|
|
4014
4018
|
reasons.push(`listens to ${event}: ${why}`);
|
|
4015
|
-
|
|
4019
|
+
// A sidebar panel is never live (player 0.7.3): the current tab keeps
|
|
4020
|
+
// the plugin running as busy work, a background tab not at all.
|
|
4021
|
+
if (this.panel?.slot === "sidebar") {
|
|
4022
|
+
if (this.layout.sidebar?.owner === 1)
|
|
4023
|
+
reasons.push("its sidebar tab is the current tab");
|
|
4024
|
+
}
|
|
4025
|
+
else if (this.panel)
|
|
4016
4026
|
reasons.push("a mounted panel");
|
|
4017
4027
|
for (const [id, window] of this.windows)
|
|
4018
4028
|
if (window.visible)
|
|
@@ -4234,8 +4244,8 @@ export class TestHost {
|
|
|
4234
4244
|
"ui.mount": (p) => {
|
|
4235
4245
|
if (this.panel)
|
|
4236
4246
|
throw new HostError("conflict", "owner already mounted");
|
|
4237
|
-
// Like the player: one panel in the bottom bar and the backdrop,
|
|
4238
|
-
// in the sidebar (
|
|
4247
|
+
// Like the player: one panel in the bottom bar and the backdrop, any
|
|
4248
|
+
// number of tabs in the sidebar (player 0.7.3; 0.4.x to 0.7.2 took 8).
|
|
4239
4249
|
const holder = p.slot === "backdrop"
|
|
4240
4250
|
? this.backdrop?.owner
|
|
4241
4251
|
: p.slot === "bottom"
|
|
@@ -4246,11 +4256,6 @@ export class TestHost {
|
|
|
4246
4256
|
this.#hostText(SLOT_LABELS[String(p.slot)]),
|
|
4247
4257
|
String(holder),
|
|
4248
4258
|
]));
|
|
4249
|
-
if (p.slot === "sidebar" &&
|
|
4250
|
-
(this.layout.sidebar?.panels?.length ?? 0) >= MAX_SIDEBAR_TABS)
|
|
4251
|
-
throw taken(this.#hostText("The sidebar holds at most {} tabs", [
|
|
4252
|
-
MAX_SIDEBAR_TABS,
|
|
4253
|
-
]));
|
|
4254
4259
|
const properties = this.#initialValues(this.#shownValues(p.properties));
|
|
4255
4260
|
this.#seeImages(properties);
|
|
4256
4261
|
this.#resetWrites("$mount");
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -421,7 +421,7 @@ export interface Scope extends Disposable {
|
|
|
421
421
|
* The plugin writes its cache file at once when the player crashed or
|
|
422
422
|
* was killed, instead of waiting for the next periodic save. The cleanup
|
|
423
423
|
* may get a {@link DisposeInfo}: `stopping` says the plugin itself stops
|
|
424
|
-
* (not a child scope), `reason` why (
|
|
424
|
+
* (not a child scope), `reason` why (player 0.6.4). Players
|
|
425
425
|
* whose SDK is older than 1.5.54 call the cleanup without an argument,
|
|
426
426
|
* so read it with `?.`.
|
|
427
427
|
* ```ts
|
|
@@ -524,9 +524,9 @@ export interface Scope extends Disposable {
|
|
|
524
524
|
* (menus, windows, panels, filters, subtitle layers, snapshots, jobs,
|
|
525
525
|
* resolvers, streams); pending requests then fail with `disabled` and the
|
|
526
526
|
* root scope is disposed for local cleanup (timers, signals, sockets). A
|
|
527
|
-
* process that has not exited after its grace is killed:
|
|
528
|
-
* 0.
|
|
529
|
-
*
|
|
527
|
+
* process that has not exited after its grace is killed: 5 s from player
|
|
528
|
+
* 0.7.1 (before it 300 ms; 300 ms after a fault); at quit all plugins
|
|
529
|
+
* together get 1 s. Media the
|
|
530
530
|
* plugin opened with {@link Player.open} keeps playing.
|
|
531
531
|
*
|
|
532
532
|
* @example Write a minimal plugin with one menu item
|
|
@@ -591,7 +591,7 @@ export interface Plugin extends Scope {
|
|
|
591
591
|
*
|
|
592
592
|
* - `quit`: the player quits (or restarts after a lost GPU device). Every
|
|
593
593
|
* plugin is stopped at the same time, with 1 s in all (300 ms after a
|
|
594
|
-
* lost device; player 0.
|
|
594
|
+
* lost device; player 0.7.1).
|
|
595
595
|
* - `disable`: the user, or a plugin with `plugins.manage`, switched the
|
|
596
596
|
* plugin off. Its session storage is cleared.
|
|
597
597
|
* - `uninstall`: the user uninstalls it.
|
|
@@ -604,25 +604,23 @@ export interface Plugin extends Scope {
|
|
|
604
604
|
* its menu items, keys, settings pages, resolvers and drop targets stay,
|
|
605
605
|
* and so does its session storage
|
|
606
606
|
* ([Idle plugins](../../docs/explanation/plugins.md#idle-plugins-are-stopped)).
|
|
607
|
-
* Only with on-demand start (lazy activation)
|
|
608
|
-
* player 0.
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
* memory puts an idle plugin in standby early
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* never.
|
|
607
|
+
* Only with on-demand start (lazy activation): on for everyone from
|
|
608
|
+
* player 0.7.1, off by default before it (`VESTRA_LAZY=1` turns it on).
|
|
609
|
+
* It comes after the idle time without use (30 s; 60 s before 0.7.1),
|
|
610
|
+
* right after a first run that holds nothing live, and, from player
|
|
611
|
+
* 0.7.1, when the player's limit on third-party processes or low system
|
|
612
|
+
* memory puts an idle plugin in standby early. A busy plugin never gets
|
|
613
|
+
* it; a resident one (it held something live when it became ready) never
|
|
614
|
+
* from player 0.7.1 (before it, after the idle time).
|
|
616
615
|
* - `failed`: the player stops it for a fault it can still tell the plugin
|
|
617
616
|
* about: a malformed request, an unreadable or oversized line, a start
|
|
618
|
-
* that is not ready within the start timeout (
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
* within 10 minutes.
|
|
617
|
+
* that is not ready within the start timeout (60 s from player 0.7.1;
|
|
618
|
+
* the stop may come while `activate` still runs), an uncaught exception
|
|
619
|
+
* the shared process attributes to this plugin, and, from player 0.7.1,
|
|
620
|
+
* a request from the player (a resolution) it leaves unanswered for 5
|
|
621
|
+
* minutes. From player 0.7.1 the player may start it again afterwards (a
|
|
622
|
+
* built-in or resident plugin by itself, a plugin that has run before on
|
|
623
|
+
* its next use), until the fifth fault within 10 minutes.
|
|
626
624
|
* - `host-lost`: the plugin's runner saw its pipe to the player close
|
|
627
625
|
* without a stop: the player crashed or was killed. Requests are refused
|
|
628
626
|
* with `disabled`; clean up locally only. Player 0.6.4 sends `quit` on a
|
|
@@ -634,7 +632,7 @@ export interface Plugin extends Scope {
|
|
|
634
632
|
* own process is killed because its input queue is full or a write to it
|
|
635
633
|
* failed, when its own process fails to activate (the runner exits without
|
|
636
634
|
* cleaning up), when the process ended by itself (it crashed, or its
|
|
637
|
-
* JavaScript heap passed the 512 MB cap of player 0.
|
|
635
|
+
* JavaScript heap passed the 512 MB cap of player 0.7.1 and V8 ended it:
|
|
638
636
|
* "ran out of memory"), and when the shared runner is restarted as a whole
|
|
639
637
|
* (a hang, a fault it cannot attribute, an unreadable line of its own, a
|
|
640
638
|
* member's full input queue, the runner exiting): every member is killed
|
|
@@ -1773,7 +1771,7 @@ export interface Ui {
|
|
|
1773
1771
|
* the list on every streamed chunk keeps the scroll position and costs
|
|
1774
1772
|
* little.
|
|
1775
1773
|
*
|
|
1776
|
-
* From player 0.
|
|
1774
|
+
* From player 0.7.1 both views take `selectable: true` (default `false`):
|
|
1777
1775
|
* the user can select and copy the text, one block at a time; blocks with
|
|
1778
1776
|
* links keep their clickable links and copy as `text (url)`. Code blocks
|
|
1779
1777
|
* are always selectable. `MarkdownBlock.plain` (the block as plain text)
|
|
@@ -2734,15 +2732,22 @@ export interface Panel extends View, Disposable {
|
|
|
2734
2732
|
* A second sidebar panel is not refused: it resolves as another tab
|
|
2735
2733
|
* (see {@link Panel.state}). Built-in plugins mount first at start-up,
|
|
2736
2734
|
* so the playlist's tab is first and a built-in panel keeps its position.
|
|
2735
|
+
* Behaviour from player 0.7.3: the sidebar takes any number of tabs; the
|
|
2736
|
+
* strip shows the tabs that fit and a `»` menu lists all of them.
|
|
2737
|
+
* Players 0.4.x to 0.7.2 refused a ninth tab with `conflict`. A plugin
|
|
2738
|
+
* whose sidebar tab is in the background, and that holds nothing else
|
|
2739
|
+
* that keeps it running, goes to standby when idle; showing the tab
|
|
2740
|
+
* starts it again (see {@link Panel.state}).
|
|
2737
2741
|
*
|
|
2738
2742
|
* @throws `ui-prepare` (rejects) The Slint file does not compile, or a
|
|
2739
2743
|
* bound property is not declared on the bridge global; `message` has the
|
|
2740
2744
|
* diagnostics. (Players 0.4.0 and older also answer a taken bottom bar
|
|
2741
2745
|
* or sidebar with it.)
|
|
2742
2746
|
* @throws `conflict` (rejects) Another plugin's panel holds the bottom bar
|
|
2743
|
-
* or the backdrop (shown, or being mounted)
|
|
2744
|
-
*
|
|
2745
|
-
*
|
|
2747
|
+
* or the backdrop (shown, or being mounted); `message` names the
|
|
2748
|
+
* position and the holder (「底栏已被 vestra.playback 使用」). Not an
|
|
2749
|
+
* activation failure. Never for the sidebar (behaviour from player
|
|
2750
|
+
* 0.7.3); players 0.4.x to 0.7.2 also refused a ninth sidebar tab.
|
|
2746
2751
|
* @throws `busy` (rejects) The player is still preparing this plugin's
|
|
2747
2752
|
* previous mount, or its queue of mounts is full.
|
|
2748
2753
|
* @throws `invalid` (rejects) `title` is longer than 128 bytes or has
|
|
@@ -2763,6 +2768,19 @@ export interface Panel extends View, Disposable {
|
|
|
2763
2768
|
* only this plugin's own changes. A sidebar panel in a background tab
|
|
2764
2769
|
* has `active: false`, `effective: false` and `reason: "otherTab"`.
|
|
2765
2770
|
*
|
|
2771
|
+
* Behaviour from player 0.7.3: a background tab does not keep the plugin
|
|
2772
|
+
* running.
|
|
2773
|
+
* If the panel is all that keeps it running, the plugin goes to standby
|
|
2774
|
+
* after the idle time (stop reason `idle`): the player keeps its tab, with
|
|
2775
|
+
* its title, in the strip and the `»` menu. When the user shows the tab,
|
|
2776
|
+
* the player starts the plugin again; `activate` runs and mounts the same
|
|
2777
|
+
* panel (same file and component), which takes the tab over, and
|
|
2778
|
+
* {@link Panel.ready} resolves again. Anything the plugin kept only in
|
|
2779
|
+
* memory is gone: restore the view from storage (session storage
|
|
2780
|
+
* survives standby). While it is in the background, the player may also
|
|
2781
|
+
* drop the panel's component and build it again from the bridge
|
|
2782
|
+
* properties last written, as it does on any rebuild.
|
|
2783
|
+
*
|
|
2766
2784
|
* @throws Never; `null` stands for "not mounted".
|
|
2767
2785
|
*
|
|
2768
2786
|
* @since 1.5.2
|
|
@@ -4405,7 +4423,13 @@ export interface MainWindow {
|
|
|
4405
4423
|
* @category Plugin
|
|
4406
4424
|
*/
|
|
4407
4425
|
export interface AppInfo {
|
|
4408
|
-
/**
|
|
4426
|
+
/**
|
|
4427
|
+
* The player's version, e.g. `"0.7.1"`. From player 0.7.1 this is the
|
|
4428
|
+
* player's release version (the version of the published release), which
|
|
4429
|
+
* can differ from the version of the host binary inside it. The player
|
|
4430
|
+
* compares `minPlayerVersion` with this value, and plugins compare with
|
|
4431
|
+
* it too.
|
|
4432
|
+
*/
|
|
4409
4433
|
readonly version: string;
|
|
4410
4434
|
/** Short git hash of the build, `null` when unknown. */
|
|
4411
4435
|
readonly build: string | null;
|
|
@@ -8586,11 +8610,11 @@ export interface InstallOptions {
|
|
|
8586
8610
|
* Built-in plugins always run (and cannot be installed over). A value
|
|
8587
8611
|
* that is not a boolean is `invalid`.
|
|
8588
8612
|
*
|
|
8589
|
-
*
|
|
8613
|
+
* Player 0.6.4 and later: older players ignore it and an install there
|
|
8590
8614
|
* always runs the plugin, so after a committed install call
|
|
8591
8615
|
* {@link Packages.setEnabled} when the state matters.
|
|
8592
8616
|
*
|
|
8593
|
-
* @player 0.6.4
|
|
8617
|
+
* @player 0.6.4; older players ignore it (an install always
|
|
8594
8618
|
* enables the plugin).
|
|
8595
8619
|
*/
|
|
8596
8620
|
enabled?: boolean;
|
|
@@ -8639,8 +8663,8 @@ export interface PackageCandidate {
|
|
|
8639
8663
|
* player). A reserved id (`vestra` or `vestra.*`, which every built-in
|
|
8640
8664
|
* uses) fails with `reserved` (player 0.4.1; already when validated), as
|
|
8641
8665
|
* only the player installs built-in plugins. An update keeps a disabled
|
|
8642
|
-
* plugin disabled unless `enabled` says otherwise (
|
|
8643
|
-
*
|
|
8666
|
+
* plugin disabled unless `enabled` says otherwise (player 0.6.4; see
|
|
8667
|
+
* {@link InstallOptions.enabled}).
|
|
8644
8668
|
*
|
|
8645
8669
|
* @capability plugins.manage
|
|
8646
8670
|
* @throws `invalid` (rejects) An option is malformed: a `source` the
|
|
@@ -8845,11 +8869,11 @@ export interface PluginInfo {
|
|
|
8845
8869
|
* while the plugin is switched on but has no process. That is standby
|
|
8846
8870
|
* with on-demand start (lazy activation): nothing used it for the idle
|
|
8847
8871
|
* time, or the player's limit on third-party processes or low system
|
|
8848
|
-
* memory stopped it early (
|
|
8872
|
+
* memory stopped it early (player 0.7.1); it starts again on its next
|
|
8849
8873
|
* use, and its menu items, keys, settings pages, resolvers and drop
|
|
8850
|
-
* targets stay. From player 0.
|
|
8874
|
+
* targets stay. From player 0.7.1 it is also the pause after a crash: a
|
|
8851
8875
|
* built-in or resident plugin waiting to start again by itself, or a
|
|
8852
|
-
* plugin
|
|
8876
|
+
* plugin that has run before whose commands are shown disabled with the
|
|
8853
8877
|
* reason until the pause ends. Absent in other states and from players
|
|
8854
8878
|
* before 0.5.18. A change between the two alone does not fire
|
|
8855
8879
|
* {@link Packages.onChange}; a plugin stopped by the start limit (five
|
package/dist/processing.d.ts
CHANGED
|
@@ -194,6 +194,39 @@ export type VideoNode =
|
|
|
194
194
|
* 16 MiB) inside the plugin's package directory or data directory
|
|
195
195
|
* after following links; a path with `[` or `]` is refused. Outside
|
|
196
196
|
* those: `invalid`; a file that does not exist: `missing`.
|
|
197
|
+
*
|
|
198
|
+
* The player checks only that header; the table itself is read by
|
|
199
|
+
* FFmpeg's `.cube` reader (`parse_cube` in FFmpeg's
|
|
200
|
+
* [`libavfilter/vf_lut3d.c`](https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_lut3d.c)),
|
|
201
|
+
* which takes a subset of the
|
|
202
|
+
* Adobe/Resolve format:
|
|
203
|
+
*
|
|
204
|
+
* - Every line before `LUT_3D_SIZE N` is skipped (a `TITLE`, comments,
|
|
205
|
+
* and also a `DOMAIN_MIN` or `DOMAIN_MAX` there, which then has no
|
|
206
|
+
* effect).
|
|
207
|
+
* - After it, optional `TITLE`, `DOMAIN_MIN r g b` and
|
|
208
|
+
* `DOMAIN_MAX r g b` lines (default `0 0 0` and `1 1 1`), blank
|
|
209
|
+
* lines and `#` comments, then N³ data lines of three numbers
|
|
210
|
+
* `r g b`, red changing fastest, then green, then blue.
|
|
211
|
+
* - Any other keyword after `LUT_3D_SIZE`, such as `MIN` or `MAX`, is
|
|
212
|
+
* read as a data line, and FFmpeg refuses the file, as it does one
|
|
213
|
+
* with fewer than N³ data lines. The chain then fails and the
|
|
214
|
+
* player reports mpv's "error running command (-12)".
|
|
215
|
+
*
|
|
216
|
+
* ```text
|
|
217
|
+
* TITLE "Identity"
|
|
218
|
+
* LUT_3D_SIZE 2
|
|
219
|
+
* DOMAIN_MIN 0 0 0
|
|
220
|
+
* DOMAIN_MAX 1 1 1
|
|
221
|
+
* 0 0 0
|
|
222
|
+
* 1 0 0
|
|
223
|
+
* 0 1 0
|
|
224
|
+
* 1 1 0
|
|
225
|
+
* 0 0 1
|
|
226
|
+
* 1 0 1
|
|
227
|
+
* 0 1 1
|
|
228
|
+
* 1 1 1
|
|
229
|
+
* ```
|
|
197
230
|
*/
|
|
198
231
|
file: string;
|
|
199
232
|
/** How colours between the table's points are computed; `tetrahedral` is FFmpeg's default. */
|
package/dist/wire.d.ts
CHANGED
|
@@ -733,7 +733,7 @@ export declare function createWire(transport: Transport): {
|
|
|
733
733
|
installed: (id: string) => Promise<InstalledPackage>;
|
|
734
734
|
/**
|
|
735
735
|
* `source` and `replace` are sent only when given (player 0.2.0);
|
|
736
|
-
* `enabled` only when given (
|
|
736
|
+
* `enabled` only when given (player 0.6.4; older players
|
|
737
737
|
* ignore it).
|
|
738
738
|
*/
|
|
739
739
|
install: (token: string, expectedRevision: number, requestId: string, options?: {
|
package/dist/wire.js
CHANGED
|
@@ -343,7 +343,7 @@ export function createWire(transport) {
|
|
|
343
343
|
installed: (id) => transport.request("packages.installed", { id }),
|
|
344
344
|
/**
|
|
345
345
|
* `source` and `replace` are sent only when given (player 0.2.0);
|
|
346
|
-
* `enabled` only when given (
|
|
346
|
+
* `enabled` only when given (player 0.6.4; older players
|
|
347
347
|
* ignore it).
|
|
348
348
|
*/
|
|
349
349
|
install: (token, expectedRevision, requestId, options = {}) => transport.request("packages.install", {
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vestra Player SDK
|
|
2
2
|
|
|
3
|
-
> @vestra-player/sdk 1.6.
|
|
3
|
+
> @vestra-player/sdk 1.6.2: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
|
|
4
4
|
|
|
5
5
|
## Read the documentation
|
|
6
6
|
|