@domicile-desktop/sdk 0.0.0-alpha-ecd3fba3a199 → 0.0.0-alpha-9fe15f8f4e4a

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.
@@ -5,6 +5,7 @@ import type { Capture } from "./capture";
5
5
  import type { Clipboard } from "./clipboard";
6
6
  import type { Dbus } from "./dbus";
7
7
  import type { Displays } from "./displays";
8
+ import type { Downloads } from "./downloads";
8
9
  import type { Extensions } from "./extensions";
9
10
  import type { Files } from "./files";
10
11
  import type { GoogleCast } from "./google-cast";
@@ -37,6 +38,7 @@ export type Domicile = {
37
38
  readonly clipboard: Clipboard;
38
39
  readonly dbus: Dbus;
39
40
  readonly displays: Displays;
41
+ readonly downloads: Downloads;
40
42
  readonly extensions: Extensions;
41
43
  readonly files: Files;
42
44
  readonly googleCast: GoogleCast;
@@ -6,6 +6,7 @@ import { capture } from "./capture";
6
6
  import { clipboard } from "./clipboard";
7
7
  import { dbus } from "./dbus";
8
8
  import { displays } from "./displays";
9
+ import { downloads } from "./downloads";
9
10
  import { extensions } from "./extensions";
10
11
  import { files } from "./files";
11
12
  import { googleCast } from "./google-cast";
@@ -45,6 +46,7 @@ const build = (host) => {
45
46
  clipboard: clipboard(host),
46
47
  dbus: bus,
47
48
  displays: displays(host, calls),
49
+ downloads: downloads(host),
48
50
  extensions: extensions(host),
49
51
  files: files(host, calls),
50
52
  googleCast: googleCast(host),
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import type { DomicileHost } from "../domicile-host";
3
+ import type { On } from "./subscribe";
4
+ export declare enum DownloadState {
5
+ InProgress = 0,
6
+ Complete = 1,
7
+ /** Interrupted by the network or the disk. */
8
+ Failed = 2
9
+ }
10
+ /**
11
+ * Parses a row of `DomicileHost.downloads`. The engine and the SDK ship apart,
12
+ * so a row is checked rather than trusted.
13
+ */
14
+ declare const downloadSchema: z.ZodObject<{
15
+ id: z.ZodString;
16
+ page: z.ZodString;
17
+ path: z.ZodString;
18
+ receivedBytes: z.ZodNumber;
19
+ state: z.ZodPipe<z.ZodEnum<{
20
+ complete: "complete";
21
+ failed: "failed";
22
+ "in-progress": "in-progress";
23
+ }>, z.ZodTransform<DownloadState, "complete" | "failed" | "in-progress">>;
24
+ totalBytes: z.ZodNumber;
25
+ window: z.ZodPipe<z.ZodString, z.ZodTransform<string | undefined, string>>;
26
+ }, z.core.$strip>;
27
+ export type Download = z.infer<typeof downloadSchema>;
28
+ export type DownloadsListeners = {
29
+ /** A download started, progressed, finished, failed or left the list. */
30
+ change: () => void;
31
+ };
32
+ export type Downloads = {
33
+ /** Oldest first; `undefined` until the engine says. */
34
+ readonly list: readonly Download[] | undefined;
35
+ /** Cancel download `id`. It leaves the list. */
36
+ cancel: (id: string) => void;
37
+ /** Take finished or failed download `id` off the list. The file stays. */
38
+ remove: (id: string) => void;
39
+ /** Take every download not in progress off the list. The files stay. */
40
+ clear: () => void;
41
+ on: On<DownloadsListeners>;
42
+ };
43
+ export type DownloadsHost = Pick<DomicileHost, "addEventListener" | "cancelDownload" | "clearDownloads" | "downloads" | "removeDownload" | "removeEventListener">;
44
+ export declare const downloads: (host: DownloadsHost) => Downloads;
45
+ export {};
@@ -0,0 +1,67 @@
1
+ // The desk's downloads: every download a browser window's page started while
2
+ // the browser runs, kept after its window closes until the shell removes it.
3
+ // See "Downloads" in docs/SHELL-BROWSER-WINDOWS.md.
4
+ import { z } from "zod";
5
+ import { memoizeLast } from "./memoize-last";
6
+ import { hostEvent, on } from "./subscribe";
7
+ export var DownloadState;
8
+ (function (DownloadState) {
9
+ DownloadState[DownloadState["InProgress"] = 0] = "InProgress";
10
+ DownloadState[DownloadState["Complete"] = 1] = "Complete";
11
+ /** Interrupted by the network or the disk. */
12
+ DownloadState[DownloadState["Failed"] = 2] = "Failed";
13
+ })(DownloadState || (DownloadState = {}));
14
+ /**
15
+ * Parses a row of `DomicileHost.downloads`. The engine and the SDK ship apart,
16
+ * so a row is checked rather than trusted.
17
+ */
18
+ const downloadSchema = z.object({
19
+ id: z.string(),
20
+ /** The page that started it. */
21
+ page: z.string(),
22
+ /** Where it is saved, absolute. */
23
+ path: z.string(),
24
+ receivedBytes: z.number(),
25
+ state: z.enum(["in-progress", "complete", "failed"]).transform((state) => {
26
+ switch (state) {
27
+ case "in-progress": {
28
+ return DownloadState.InProgress;
29
+ }
30
+ case "complete": {
31
+ return DownloadState.Complete;
32
+ }
33
+ case "failed": {
34
+ return DownloadState.Failed;
35
+ }
36
+ }
37
+ }),
38
+ /** `0` when the server sent no size. */
39
+ totalBytes: z.number(),
40
+ /**
41
+ * The browser window whose page started it, which may have closed since;
42
+ * `undefined` for a page that is not a browser window.
43
+ */
44
+ window: z
45
+ .string()
46
+ .transform((window) => (window === "" ? undefined : window)),
47
+ });
48
+ export const downloads = (host) => {
49
+ const listOf = memoizeLast((list) => list === null ? undefined : z.array(downloadSchema).parse(list));
50
+ return {
51
+ cancel: (id) => {
52
+ host.cancelDownload(id);
53
+ },
54
+ clear: () => {
55
+ host.clearDownloads();
56
+ },
57
+ get list() {
58
+ return listOf(host.downloads);
59
+ },
60
+ on: on({
61
+ change: (listener) => hostEvent(host, "downloadschanged", () => listener()),
62
+ }),
63
+ remove: (id) => {
64
+ host.removeDownload(id);
65
+ },
66
+ };
67
+ };
@@ -14,6 +14,13 @@
14
14
  * `scripts/test-cursor-shapes-agree.sh` compares all four as sequences.
15
15
  */
16
16
  export type DomicileCursorShape = "none" | "default" | "context-menu" | "help" | "pointer" | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text" | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "grab" | "grabbing" | "e-resize" | "n-resize" | "ne-resize" | "nw-resize" | "s-resize" | "se-resize" | "sw-resize" | "w-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "col-resize" | "row-resize" | "all-scroll" | "zoom-in" | "zoom-out";
17
+ /**
18
+ * One of the desk's downloads. See components/domicile/mojom/downloads.mojom.
19
+ *
20
+ * An interface for DomicileBrowserWindow's reason: these are read from the
21
+ * desktop's `downloads` attribute.
22
+ */
23
+ export type DomicileDownloadState = "in-progress" | "complete" | "failed";
17
24
  /**
18
25
  * The desktop's light or dark theme.
19
26
  *
@@ -291,6 +298,23 @@ export type DomicileDisplay = {
291
298
  */
292
299
  readonly transform: string;
293
300
  };
301
+ export type DomicileDownload = {
302
+ /** The id cancelDownload() and removeDownload() take. */
303
+ readonly id: string;
304
+ readonly state: DomicileDownloadState;
305
+ /** Where it is saved. */
306
+ readonly path: string;
307
+ readonly receivedBytes: number;
308
+ /** 0 when the server sent no size. */
309
+ readonly totalBytes: number;
310
+ /**
311
+ * The browser window whose page started it, as a DomicileBrowserWindow's
312
+ * `id`; empty for a <webview> that is not one. It may have closed since.
313
+ */
314
+ readonly window: string;
315
+ /** The address of the page that started it. */
316
+ readonly page: string;
317
+ };
294
318
  /**
295
319
  * One extension with an action, as a shell's tray draws it.
296
320
  *
@@ -399,6 +423,11 @@ export type DomicileHostEventMap = {
399
423
  * `castSinks` for the current list.
400
424
  */
401
425
  castsinkschanged: Event;
426
+ /**
427
+ * Fires when a download starts, progresses, finishes, fails, or leaves the
428
+ * list. Read `downloads` for the current list.
429
+ */
430
+ downloadschanged: Event;
402
431
  /**
403
432
  * An answer to callSystem(), as a MessageEvent whose `data` is the
404
433
  * compositor's `system_reply`, `system_event` or `system_end` line.
@@ -677,6 +706,18 @@ export type DomicileHost = {
677
706
  * `castsinkschanged`. An unknown route does nothing.
678
707
  */
679
708
  stopCasting(route: string): void;
709
+ /**
710
+ * Cancels download `id`; it leaves the next `downloadschanged`. An unknown
711
+ * id, or one no longer in progress, does nothing.
712
+ */
713
+ cancelDownload(id: string): void;
714
+ /**
715
+ * Removes download `id` from `downloads`. The file stays. A download in
716
+ * progress, or an unknown id, does nothing.
717
+ */
718
+ removeDownload(id: string): void;
719
+ /** Removes every download not in progress from `downloads`. The files stay. */
720
+ clearDownloads(): void;
680
721
  /**
681
722
  * Sends `method`, "GET" or "POST", to `url` from the browser process with
682
723
  * the cookies of the profile the ordinary browser windows use, so a bar
@@ -783,6 +824,14 @@ export type DomicileHost = {
783
824
  * components/domicile/mojom/cast_sinks.mojom.
784
825
  */
785
826
  readonly castSinks: readonly DomicileCastSink[] | null;
827
+ /**
828
+ * The desk's downloads, oldest first: each one a browser window's page
829
+ * started while the browser runs, until removeDownload() or
830
+ * clearDownloads(). Null until the browser lists them, which it does as soon
831
+ * as this page listens. No [SameObject], for `displays`' reason. See
832
+ * components/domicile/mojom/downloads.mojom.
833
+ */
834
+ readonly downloads: readonly DomicileDownload[] | null;
786
835
  /**
787
836
  * Typed by the event map rather than by inheriting `EventTarget`, whose
788
837
  * overloads take any name and type every listener's event as `Event`.
package/dist/fake-host.js CHANGED
@@ -19,6 +19,7 @@ const CHANGED = {
19
19
  clipboard: "clipboardchanged",
20
20
  ctrlKey: "modifierschanged",
21
21
  displays: "displayschanged",
22
+ downloads: "downloadschanged",
22
23
  extensions: "extensionschanged",
23
24
  focusedWindow: "focusedwindowchanged",
24
25
  highContrast: "appearancechanged",
@@ -43,6 +44,7 @@ const UNDESCRIBED = {
43
44
  clipboard: null,
44
45
  ctrlKey: null,
45
46
  displays: null,
47
+ downloads: null,
46
48
  extensions: null,
47
49
  focusedWindow: null,
48
50
  highContrast: null,
@@ -26,15 +26,6 @@ export declare const WEBVIEW_LOADING_CHANGE_EVENT = "domicile-loading-change";
26
26
  * payload. Bubbles.
27
27
  */
28
28
  export declare const WEBVIEW_LOAD_PROGRESS_CHANGE_EVENT = "domicile-load-progress-change";
29
- /**
30
- * Fired when {@link HTMLWebViewElement.downloadCount},
31
- * {@link HTMLWebViewElement.downloadReceivedBytes},
32
- * {@link HTMLWebViewElement.downloadTotalBytes} or
33
- * {@link HTMLWebViewElement.downloadCompletedCount} or
34
- * {@link HTMLWebViewElement.downloadCompletedPaths} changes. Carries no payload.
35
- * Bubbles.
36
- */
37
- export declare const WEBVIEW_DOWNLOADS_CHANGE_EVENT = "domicile-downloads-change";
38
29
  /**
39
30
  * Fired when {@link HTMLWebViewElement.url} or
40
31
  * {@link HTMLWebViewElement.security} changes. Carries no payload. Bubbles.
@@ -378,37 +369,6 @@ declare global {
378
369
  * {@link WEBVIEW_LOAD_PROGRESS_CHANGE_EVENT}.
379
370
  */
380
371
  readonly loadProgress: number;
381
- /**
382
- * How many of the page's downloads are in progress. A download counts once
383
- * the shell has said where it goes. Changes fire
384
- * {@link WEBVIEW_DOWNLOADS_CHANGE_EVENT}.
385
- */
386
- readonly downloadCount: number;
387
- /** Bytes received across the downloads in progress. */
388
- readonly downloadReceivedBytes: number;
389
- /**
390
- * Bytes expected across the downloads in progress. `0` when any one's size
391
- * is unknown.
392
- */
393
- readonly downloadTotalBytes: number;
394
- /**
395
- * How many of the page's downloads finished, until
396
- * {@link HTMLWebViewElement.clearCompletedDownloads}. A canceled or
397
- * interrupted download is not counted.
398
- */
399
- readonly downloadCompletedCount: number;
400
- /**
401
- * Where the finished downloads were saved, absolute, in the order they
402
- * started. `undefined` from an engine without it.
403
- */
404
- readonly downloadCompletedPaths: readonly string[] | undefined;
405
- /** Stops counting finished downloads in `downloadCompletedCount`. */
406
- clearCompletedDownloads(): void;
407
- /**
408
- * Stops counting the finished downloads saved at `path`, an entry of
409
- * `downloadCompletedPaths`. `undefined` from an engine without it.
410
- */
411
- readonly removeCompletedDownload: ((path: string) => void) | undefined;
412
372
  /**
413
373
  * The current address, as a browser's address bar shows it. Differs from
414
374
  * {@link HTMLWebViewElement.src} after links and redirects.
@@ -32,15 +32,6 @@ export const WEBVIEW_LOADING_CHANGE_EVENT = "domicile-loading-change";
32
32
  * payload. Bubbles.
33
33
  */
34
34
  export const WEBVIEW_LOAD_PROGRESS_CHANGE_EVENT = "domicile-load-progress-change";
35
- /**
36
- * Fired when {@link HTMLWebViewElement.downloadCount},
37
- * {@link HTMLWebViewElement.downloadReceivedBytes},
38
- * {@link HTMLWebViewElement.downloadTotalBytes} or
39
- * {@link HTMLWebViewElement.downloadCompletedCount} or
40
- * {@link HTMLWebViewElement.downloadCompletedPaths} changes. Carries no payload.
41
- * Bubbles.
42
- */
43
- export const WEBVIEW_DOWNLOADS_CHANGE_EVENT = "domicile-downloads-change";
44
35
  /**
45
36
  * Fired when {@link HTMLWebViewElement.url} or
46
37
  * {@link HTMLWebViewElement.security} changes. Carries no payload. Bubbles.
package/package.json CHANGED
@@ -79,6 +79,10 @@
79
79
  "types": "./dist/desktop/displays.d.ts",
80
80
  "default": "./dist/desktop/displays.js"
81
81
  },
82
+ "./desktop/downloads": {
83
+ "types": "./dist/desktop/downloads.d.ts",
84
+ "default": "./dist/desktop/downloads.js"
85
+ },
82
86
  "./desktop/extensions": {
83
87
  "types": "./dist/desktop/extensions.d.ts",
84
88
  "default": "./dist/desktop/extensions.js"
@@ -238,7 +242,7 @@
238
242
  "test:unit": "bun test"
239
243
  },
240
244
  "type": "module",
241
- "version": "0.0.0-alpha-ecd3fba3a199",
245
+ "version": "0.0.0-alpha-9fe15f8f4e4a",
242
246
  "repository": {
243
247
  "type": "git",
244
248
  "url": "git+https://github.com/cprussin/domicile.git",