@domicile-desktop/system-network 0.0.0-alpha-44d0983a58ce → 0.0.0-alpha-56dd6c187f4e

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/README.md CHANGED
@@ -4,15 +4,16 @@ The network for a Domicile shell, from NetworkManager, iwd or wpa_supplicant:
4
4
  connectivity and the primary connection, with the Wi-Fi network's name and
5
5
  signal. The Wi-Fi device, from NetworkManager or iwd: its networks and
6
6
  connection, and the requests that change them. Built on
7
- [`@domicile-desktop/sdk/system`](../chrome-sdk/README.md).
7
+ the `dbus`, `files` and `processes` namespaces of
8
+ [`desktop(domicile)`](../chrome-sdk/README.md).
8
9
 
9
10
  ## Usage
10
11
 
11
12
  ```ts
12
- import { system } from "@domicile-desktop/sdk/system";
13
+ import { desktop } from "@domicile-desktop/sdk/desktop/desktop";
13
14
  import { watchNetwork } from "@domicile-desktop/system-network/network";
14
15
 
15
- const stop = watchNetwork(system(domicile), (network) => {
16
+ const stop = watchNetwork(desktop(domicile), (network) => {
16
17
  network.match({
17
18
  Err: () => hide(),
18
19
  Ok: ({ connectivity, link }) => show(connectivity, link),
@@ -111,4 +112,4 @@ bun run turbo test --filter @domicile-desktop/system-network
111
112
  ```
112
113
 
113
114
  Tests replay D-Bus replies, in the compositor's JSON, through an injected
114
- `System`.
115
+ `dbus` namespace.
package/dist/follow.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
2
  import type { DbusMatch, DbusSignal, SystemError } from "@domicile-desktop/sdk/system";
3
- import type { NetworkSystem } from "./network-state";
3
+ import type { NetworkDesktop } from "./network-state";
4
4
  /** What one read found, and which signals can change it. */
5
5
  export type Reading<T extends NonNullable<unknown>> = {
6
6
  value: Result<T, SystemError>;
@@ -10,4 +10,4 @@ export type Reading<T extends NonNullable<unknown>> = {
10
10
  * Calls `onValue` with what `read` finds now and after each signal that
11
11
  * matters, and returns a function that stops watching.
12
12
  */
13
- export declare const followBus: <T extends NonNullable<unknown>>(system: NetworkSystem, match: DbusMatch, read: () => Promise<Reading<T>>, onValue: (value: Result<T, SystemError>) => void) => (() => void);
13
+ export declare const followBus: <T extends NonNullable<unknown>>(domicile: NetworkDesktop, match: DbusMatch, read: () => Promise<Reading<T>>, onValue: (value: Result<T, SystemError>) => void) => (() => void);
package/dist/follow.js CHANGED
@@ -6,14 +6,14 @@ import { ListenedKind } from "@domicile-desktop/sdk/system";
6
6
  * Calls `onValue` with what `read` finds now and after each signal that
7
7
  * matters, and returns a function that stops watching.
8
8
  */
9
- export const followBus = (system, match, read, onValue) => {
9
+ export const followBus = (domicile, match, read, onValue) => {
10
10
  const watch = { listening: undefined, stopped: false };
11
11
  const report = (value) => {
12
12
  if (!watch.stopped) {
13
13
  onValue(value);
14
14
  }
15
15
  };
16
- follow(system, match, read, watch, report).catch((error) => {
16
+ follow(domicile, match, read, watch, report).catch((error) => {
17
17
  // biome-ignore lint/suspicious/noConsole: surfacing a background failure
18
18
  console.error("Failed to watch the network", error);
19
19
  });
@@ -22,8 +22,8 @@ export const followBus = (system, match, read, onValue) => {
22
22
  watch.listening?.stop();
23
23
  };
24
24
  };
25
- const follow = async (system, match, read, watch, report) => {
26
- const matched = await system.dbusMatch(match);
25
+ const follow = async (domicile, match, read, watch, report) => {
26
+ const matched = await domicile.dbus.match(match);
27
27
  await matched.match({
28
28
  Err: (error) => {
29
29
  report(Err(error));
@@ -1,8 +1,8 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { NetworkSystem } from "./network-state";
3
+ import type { NetworkDesktop } from "./network-state";
4
4
  /**
5
5
  * Whether `name` has an owner on the system bus. `NameHasOwner` does not start
6
6
  * a service that D-Bus can activate, as a call to the service would.
7
7
  */
8
- export declare const hasOwner: (system: NetworkSystem, name: string) => Promise<Result<boolean, SystemError>>;
8
+ export declare const hasOwner: (domicile: NetworkDesktop, name: string) => Promise<Result<boolean, SystemError>>;
package/dist/has-owner.js CHANGED
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  * Whether `name` has an owner on the system bus. `NameHasOwner` does not start
5
5
  * a service that D-Bus can activate, as a call to the service would.
6
6
  */
7
- export const hasOwner = async (system, name) => (await system.dbusCall({
7
+ export const hasOwner = async (domicile, name) => (await domicile.dbus.call({
8
8
  body: [name],
9
9
  bus: Bus.System,
10
10
  destination: "org.freedesktop.DBus",
@@ -1,5 +1,7 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
- import type { System, SystemError } from "@domicile-desktop/sdk/system";
2
+ import type { Files } from "@domicile-desktop/sdk/desktop/files";
3
+ import type { Processes } from "@domicile-desktop/sdk/desktop/processes";
4
+ import type { SystemError } from "@domicile-desktop/sdk/system";
3
5
  export declare enum InterfaceKind {
4
6
  Wired = 0,
5
7
  Wireless = 1
@@ -22,26 +24,32 @@ export type Addressing = {
22
24
  gateway: string | undefined;
23
25
  };
24
26
  /** The calls {@link readInterfaces} makes. Each works while the desktop is locked. */
25
- export type InterfaceSystem = Pick<System, "readDir" | "readTextFile" | "stat">;
27
+ export type InterfaceDesktop = {
28
+ readonly files: Pick<Files, "readDir" | "readText" | "stat">;
29
+ };
26
30
  /**
27
31
  * The interfaces with hardware behind them, by name. Virtual ones, such as
28
32
  * the loopback, a bridge or a VPN, have no `device` link and are left out.
29
33
  */
30
- export declare const readInterfaces: (system: InterfaceSystem) => Promise<Result<NetworkInterface[], SystemError>>;
34
+ export declare const readInterfaces: (domicile: InterfaceDesktop) => Promise<Result<NetworkInterface[], SystemError>>;
31
35
  /**
32
36
  * Calls `onInterfaces` with {@link readInterfaces} now and whenever it
33
37
  * changes, and returns a function that stops watching. Reads every 5 seconds.
34
38
  */
35
- export declare const watchInterfaces: (system: InterfaceSystem, onInterfaces: (interfaces: Result<NetworkInterface[], SystemError>) => void, every?: typeof everyInterval) => (() => void);
39
+ export declare const watchInterfaces: (domicile: InterfaceDesktop, onInterfaces: (interfaces: Result<NetworkInterface[], SystemError>) => void, every?: typeof everyInterval) => (() => void);
36
40
  /**
37
41
  * Calls `onAddresses` with {@link readAddresses} now and whenever it changes,
38
42
  * and returns a function that stops watching. Reads every 5 seconds.
39
43
  */
40
- export declare const watchAddresses: (system: Pick<System, "run">, onAddresses: (addresses: Result<Map<string, Addressing>, SystemError>) => void, every?: typeof everyInterval) => (() => void);
44
+ export declare const watchAddresses: (domicile: {
45
+ readonly processes: Pick<Processes, "run">;
46
+ }, onAddresses: (addresses: Result<Map<string, Addressing>, SystemError>) => void, every?: typeof everyInterval) => (() => void);
41
47
  /**
42
48
  * Each interface's global addresses in use and default gateway, by name, from
43
49
  * `ip -j`. `ip` must be on the compositor's `PATH`.
44
50
  */
45
- export declare const readAddresses: (system: Pick<System, "run">) => Promise<Result<Map<string, Addressing>, SystemError>>;
51
+ export declare const readAddresses: (domicile: {
52
+ readonly processes: Pick<Processes, "run">;
53
+ }) => Promise<Result<Map<string, Addressing>, SystemError>>;
46
54
  declare const everyInterval: (ms: number, tick: () => void) => (() => void);
47
55
  export {};
@@ -16,13 +16,13 @@ export var InterfaceKind;
16
16
  * The interfaces with hardware behind them, by name. Virtual ones, such as
17
17
  * the loopback, a bridge or a VPN, have no `device` link and are left out.
18
18
  */
19
- export const readInterfaces = async (system) => (await system.readDir(NET)).match({
19
+ export const readInterfaces = async (domicile) => (await domicile.files.readDir(NET)).match({
20
20
  Err: (error) => Promise.resolve(Err(error)),
21
21
  Ok: async (entries) => {
22
22
  const read = await Promise.all(entries
23
23
  .map(({ name }) => name)
24
24
  .toSorted()
25
- .map((name) => interfaceOf(system, name)));
25
+ .map((name) => interfaceOf(domicile, name)));
26
26
  return read.reduce((all, each) => all.andThen((found) => each.map((one) => one.match({ None: () => found, Some: (it) => [...found, it] }))), Ok([]));
27
27
  },
28
28
  });
@@ -30,19 +30,19 @@ export const readInterfaces = async (system) => (await system.readDir(NET)).matc
30
30
  * Calls `onInterfaces` with {@link readInterfaces} now and whenever it
31
31
  * changes, and returns a function that stops watching. Reads every 5 seconds.
32
32
  */
33
- export const watchInterfaces = (system, onInterfaces, every = everyInterval) => poll(() => readInterfaces(system), onInterfaces, every);
33
+ export const watchInterfaces = (domicile, onInterfaces, every = everyInterval) => poll(() => readInterfaces(domicile), onInterfaces, every);
34
34
  /**
35
35
  * Calls `onAddresses` with {@link readAddresses} now and whenever it changes,
36
36
  * and returns a function that stops watching. Reads every 5 seconds.
37
37
  */
38
- export const watchAddresses = (system, onAddresses, every = everyInterval) => poll(() => readAddresses(system), onAddresses, every);
38
+ export const watchAddresses = (domicile, onAddresses, every = everyInterval) => poll(() => readAddresses(domicile), onAddresses, every);
39
39
  /**
40
40
  * Each interface's global addresses in use and default gateway, by name, from
41
41
  * `ip -j`. `ip` must be on the compositor's `PATH`.
42
42
  */
43
- export const readAddresses = async (system) => {
44
- const addresses = await ip(system, ["address", "show"], addressesSchema);
45
- const routes = await ip(system, ["route", "show", "default"], routesSchema);
43
+ export const readAddresses = async (domicile) => {
44
+ const addresses = await ip(domicile, ["address", "show"], addressesSchema);
45
+ const routes = await ip(domicile, ["route", "show", "default"], routesSchema);
46
46
  return addresses.andThen((listed) => routes.map((defaults) => new Map(listed.map(({ addr_info: info, ifname }) => [
47
47
  ifname,
48
48
  {
@@ -93,24 +93,24 @@ const everyInterval = (ms, tick) => {
93
93
  };
94
94
  };
95
95
  /** The interface `name`, or `None` for a virtual one. */
96
- const interfaceOf = async (system, name) => {
96
+ const interfaceOf = async (domicile, name) => {
97
97
  const at = `${NET}/${name}`;
98
- return (await exists(system, `${at}/device`)).match({
98
+ return (await exists(domicile, `${at}/device`)).match({
99
99
  Err: (error) => Promise.resolve(Err(error)),
100
100
  Ok: async (physical) => physical
101
- ? (await hardwareOf(system, name)).map(Some)
101
+ ? (await hardwareOf(domicile, name)).map(Some)
102
102
  : Ok(None()),
103
103
  });
104
104
  };
105
105
  /** The interface `name`, which has a `device`. */
106
- const hardwareOf = async (system, name) => {
106
+ const hardwareOf = async (domicile, name) => {
107
107
  const at = `${NET}/${name}`;
108
- const wireless = await exists(system, `${at}/wireless`);
109
- const address = await line(system, `${at}/address`);
110
- const state = await line(system, `${at}/operstate`);
108
+ const wireless = await exists(domicile, `${at}/wireless`);
109
+ const address = await line(domicile, `${at}/address`);
110
+ const state = await line(domicile, `${at}/operstate`);
111
111
  const up = state.map((operstate) => operstate === "up");
112
112
  const speed = up.unwrapOr(false) && !wireless.unwrapOr(true)
113
- ? await speedOf(system, at)
113
+ ? await speedOf(domicile, at)
114
114
  : undefined;
115
115
  return wireless.andThen((isWireless) => address.andThen((hardwareAddress) => up.map((linked) => ({
116
116
  hardwareAddress,
@@ -121,17 +121,17 @@ const hardwareOf = async (system, name) => {
121
121
  }))));
122
122
  };
123
123
  /** Whether `path` exists. */
124
- const exists = async (system, path) => (await system.stat(path)).match({
124
+ const exists = async (domicile, path) => (await domicile.files.stat(path)).match({
125
125
  Err: (error) => error.kind === SystemErrorKind.NotFound ? Ok(false) : Err(error),
126
126
  Ok: () => Ok(true),
127
127
  });
128
128
  /** A one-line file under `/sys`, without its newline. */
129
- const line = async (system, path) => (await system.readTextFile(path)).map((text) => text.trim());
129
+ const line = async (domicile, path) => (await domicile.files.readText(path)).map((text) => text.trim());
130
130
  /**
131
131
  * A wired link's speed. The kernel fails the read, or answers `-1`, when the
132
132
  * driver does not know it, which is no speed to show.
133
133
  */
134
- const speedOf = async (system, at) => (await line(system, `${at}/speed`)).match({
134
+ const speedOf = async (domicile, at) => (await line(domicile, `${at}/speed`)).match({
135
135
  Err: () => undefined,
136
136
  Ok: (text) => {
137
137
  const mbits = Number.parseInt(text, 10);
@@ -139,7 +139,7 @@ const speedOf = async (system, at) => (await line(system, `${at}/speed`)).match(
139
139
  },
140
140
  });
141
141
  /** `ip -j` with `argv`, parsed with `schema`. */
142
- const ip = async (system, argv, schema) => (await system.run(["ip", "-j", ...argv])).andThen(({ code, stderr, stdout }) => code === 0
142
+ const ip = async (domicile, argv, schema) => (await domicile.processes.run(["ip", "-j", ...argv])).andThen(({ code, stderr, stdout }) => code === 0
143
143
  ? Ok(schema.parse(JSON.parse(stdout)))
144
144
  : Err({
145
145
  kind: SystemErrorKind.Other,
@@ -1,7 +1,7 @@
1
1
  import type { Option, Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { NetworkSystem } from "./network-state";
4
- import type { Wifi, WifiDevice, WifiNetwork, WifiSystem } from "./wifi-state";
3
+ import type { NetworkDesktop } from "./network-state";
4
+ import type { Wifi, WifiDesktop, WifiDevice, WifiNetwork } from "./wifi-state";
5
5
  /**
6
6
  * Calls `onWifi` with the first station device now and after each change, and
7
7
  * returns a function that stops watching. `None` is a machine without one.
@@ -9,16 +9,16 @@ import type { Wifi, WifiDevice, WifiNetwork, WifiSystem } from "./wifi-state";
9
9
  * An `Err` is a D-Bus failure, such as iwd not running. The watch keeps
10
10
  * listening after one, so a later change reads again.
11
11
  */
12
- export declare const watchIwdWifi: (system: NetworkSystem, onWifi: (wifi: Result<Option<Wifi>, SystemError>) => void) => (() => void);
12
+ export declare const watchIwdWifi: (domicile: NetworkDesktop, onWifi: (wifi: Result<Option<Wifi>, SystemError>) => void) => (() => void);
13
13
  /** Turn the device on or off. */
14
- export declare const setIwdWifiEnabled: (system: NetworkSystem, wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
14
+ export declare const setIwdWifiEnabled: (domicile: NetworkDesktop, wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
15
15
  /** Ask for a scan. Networks it finds arrive as changes. */
16
- export declare const scanIwdWifi: (system: NetworkSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
16
+ export declare const scanIwdWifi: (domicile: NetworkDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
17
17
  /**
18
18
  * Join `network`. A known or open network joins over D-Bus. A new secured one
19
19
  * joins through `iwctl`, which answers iwd's request for the passphrase: iwd
20
20
  * asks an agent for it, and a page cannot serve one.
21
21
  */
22
- export declare const connectIwdWifi: (system: WifiSystem, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
22
+ export declare const connectIwdWifi: (domicile: WifiDesktop, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
23
23
  /** Leave the current network, until asked to join one. */
24
- export declare const disconnectIwdWifi: (system: NetworkSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
24
+ export declare const disconnectIwdWifi: (domicile: NetworkDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
package/dist/iwd-wifi.js CHANGED
@@ -21,29 +21,29 @@ const WATCHED = [DEVICE, STATION, NETWORK];
21
21
  * An `Err` is a D-Bus failure, such as iwd not running. The watch keeps
22
22
  * listening after one, so a later change reads again.
23
23
  */
24
- export const watchIwdWifi = (system, onWifi) => followBus(system, { bus: Bus.System, sender: SERVICE }, async () => ({ matters, value: await read(system) }), onWifi);
24
+ export const watchIwdWifi = (domicile, onWifi) => followBus(domicile, { bus: Bus.System, sender: SERVICE }, async () => ({ matters, value: await read(domicile) }), onWifi);
25
25
  /** Turn the device on or off. */
26
- export const setIwdWifiEnabled = async (system, wifi, enabled) => done(await system.dbusCall({
26
+ export const setIwdWifiEnabled = async (domicile, wifi, enabled) => done(await domicile.dbus.call({
27
27
  ...request(wifi.device, "org.freedesktop.DBus.Properties", "Set"),
28
28
  body: [DEVICE, "Powered", { signature: "b", value: enabled }],
29
29
  signature: "ssv",
30
30
  }));
31
31
  /** Ask for a scan. Networks it finds arrive as changes. */
32
- export const scanIwdWifi = async (system, wifi) => done(await system.dbusCall(request(wifi.device, STATION, "Scan")));
32
+ export const scanIwdWifi = async (domicile, wifi) => done(await domicile.dbus.call(request(wifi.device, STATION, "Scan")));
33
33
  /**
34
34
  * Join `network`. A known or open network joins over D-Bus. A new secured one
35
35
  * joins through `iwctl`, which answers iwd's request for the passphrase: iwd
36
36
  * asks an agent for it, and a page cannot serve one.
37
37
  */
38
- export const connectIwdWifi = async (system, wifi, network, passphrase) => {
38
+ export const connectIwdWifi = async (domicile, wifi, network, passphrase) => {
39
39
  if (network.profile !== undefined || !network.secured) {
40
- return done(await system.dbusCall(request(network.path, NETWORK, "Connect")));
40
+ return done(await domicile.dbus.call(request(network.path, NETWORK, "Connect")));
41
41
  }
42
42
  else if (passphrase === undefined) {
43
43
  throw new Error(`joining ${network.ssid} needs a passphrase`);
44
44
  }
45
45
  else {
46
- const ran = await system.run([
46
+ const ran = await domicile.processes.run([
47
47
  "iwctl",
48
48
  "--passphrase",
49
49
  passphrase,
@@ -61,7 +61,7 @@ export const connectIwdWifi = async (system, wifi, network, passphrase) => {
61
61
  }
62
62
  };
63
63
  /** Leave the current network, until asked to join one. */
64
- export const disconnectIwdWifi = async (system, wifi) => done(await system.dbusCall(request(wifi.device, STATION, "Disconnect")));
64
+ export const disconnectIwdWifi = async (domicile, wifi) => done(await domicile.dbus.call(request(wifi.device, STATION, "Disconnect")));
65
65
  const request = (path, iface, member) => ({
66
66
  bus: Bus.System,
67
67
  destination: SERVICE,
@@ -86,7 +86,7 @@ const matters = (signal) => {
86
86
  }
87
87
  }
88
88
  };
89
- const read = async (system) => (await system.dbusCall({
89
+ const read = async (domicile) => (await domicile.dbus.call({
90
90
  bus: Bus.System,
91
91
  destination: SERVICE,
92
92
  interface: "org.freedesktop.DBus.ObjectManager",
@@ -100,9 +100,9 @@ const read = async (system) => (await system.dbusCall({
100
100
  })[0];
101
101
  return station === undefined
102
102
  ? Ok(None())
103
- : (await wifiOf(system, objects, station.path, station.device, station.held)).map((wifi) => Some(wifi));
103
+ : (await wifiOf(domicile, objects, station.path, station.device, station.held)).map((wifi) => Some(wifi));
104
104
  });
105
- const wifiOf = async (system, objects, path, device, held) => {
105
+ const wifiOf = async (domicile, objects, path, device, held) => {
106
106
  const off = {
107
107
  backend: WifiBackend.Iwd,
108
108
  connection: undefined,
@@ -116,16 +116,16 @@ const wifiOf = async (system, objects, path, device, held) => {
116
116
  const station = held[STATION];
117
117
  return station === undefined
118
118
  ? Ok(off)
119
- : (await stationOf(system, objects, path, station, held[DIAGNOSTIC])).map((found) => ({ ...off, ...found }));
119
+ : (await stationOf(domicile, objects, path, station, held[DIAGNOSTIC])).map((found) => ({ ...off, ...found }));
120
120
  };
121
- const stationOf = async (system, objects, path, station, diagnostic) => (await system.dbusCall(request(path, STATION, "GetOrderedNetworks"))).andThenAsync(async ({ body }) => {
121
+ const stationOf = async (domicile, objects, path, station, diagnostic) => (await domicile.dbus.call(request(path, STATION, "GetOrderedNetworks"))).andThenAsync(async ({ body }) => {
122
122
  const networks = orderedNetworksSchema
123
123
  .parse(body)[0]
124
124
  .map(([network, signal]) => networkOf(objects, network, signal));
125
125
  const connected = networks.find(({ connected: on }) => on);
126
126
  const connection = connected === undefined
127
127
  ? Ok(None())
128
- : (await diagnosticsOf(system, path, diagnostic)).map((found) => Some({
128
+ : (await diagnosticsOf(domicile, path, diagnostic)).map((found) => Some({
129
129
  ...found,
130
130
  ip: undefined,
131
131
  ssid: connected.ssid,
@@ -157,9 +157,9 @@ const networkOf = (objects, path, signal) => {
157
157
  }
158
158
  };
159
159
  /** The link's frequency and bitrate, when iwd offers diagnostics. */
160
- const diagnosticsOf = async (system, path, diagnostic) => diagnostic === undefined
160
+ const diagnosticsOf = async (domicile, path, diagnostic) => diagnostic === undefined
161
161
  ? Ok({ bitrate: undefined, frequency: undefined })
162
- : (await system.dbusCall(request(path, DIAGNOSTIC, "GetDiagnostics"))).map(({ body }) => {
162
+ : (await domicile.dbus.call(request(path, DIAGNOSTIC, "GetDiagnostics"))).map(({ body }) => {
163
163
  const [found] = diagnosticsSchema.parse(body);
164
164
  return { bitrate: found.RxBitrate / 10, frequency: found.Frequency };
165
165
  });
package/dist/iwd.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { Network, NetworkSystem } from "./network-state";
3
+ import type { Network, NetworkDesktop } from "./network-state";
4
4
  /**
5
5
  * Calls `onNetwork` with iwd's network now and after each change, and returns
6
6
  * a function that stops watching.
@@ -10,4 +10,4 @@ import type { Network, NetworkSystem } from "./network-state";
10
10
  * not running. The watch keeps listening after one, so a later change reads
11
11
  * again.
12
12
  */
13
- export declare const watchIwd: (system: NetworkSystem, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
13
+ export declare const watchIwd: (domicile: NetworkDesktop, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
package/dist/iwd.js CHANGED
@@ -24,7 +24,7 @@ const WATCHED = ["ConnectedNetwork", "Scanning", "State"];
24
24
  * not running. The watch keeps listening after one, so a later change reads
25
25
  * again.
26
26
  */
27
- export const watchIwd = (system, onNetwork) => followBus(system, { bus: Bus.System, sender: SERVICE }, async () => ({ matters, value: await read(system) }), onNetwork);
27
+ export const watchIwd = (domicile, onNetwork) => followBus(domicile, { bus: Bus.System, sender: SERVICE }, async () => ({ matters, value: await read(domicile) }), onNetwork);
28
28
  /**
29
29
  * Whether `signal` can change the network: an object coming or going, or a
30
30
  * watched station property.
@@ -44,8 +44,8 @@ const matters = (signal) => {
44
44
  }
45
45
  }
46
46
  };
47
- const read = async (system) => {
48
- const objects = await system.dbusCall({
47
+ const read = async (domicile) => {
48
+ const objects = await domicile.dbus.call({
49
49
  bus: Bus.System,
50
50
  destination: SERVICE,
51
51
  interface: "org.freedesktop.DBus.ObjectManager",
@@ -54,11 +54,11 @@ const read = async (system) => {
54
54
  });
55
55
  return objects.match({
56
56
  Err: (error) => Promise.resolve(Err(error)),
57
- Ok: async ({ body }) => (await linkOf(system, managedObjectsSchema.parse(body)[0])).map((link) => ({ connectivity: Connectivity.Unknown, link })),
57
+ Ok: async ({ body }) => (await linkOf(domicile, managedObjectsSchema.parse(body)[0])).map((link) => ({ connectivity: Connectivity.Unknown, link })),
58
58
  });
59
59
  };
60
60
  /** The first connected station's network, or `None`. */
61
- const linkOf = async (system, objects) => {
61
+ const linkOf = async (domicile, objects) => {
62
62
  const station = Object.entries(objects).flatMap(([path, held]) => held[STATION] !== undefined && isOnline(held[STATION].State)
63
63
  ? [{ network: connectedNetwork(path, held[STATION]), path }]
64
64
  : [])[0];
@@ -66,7 +66,7 @@ const linkOf = async (system, objects) => {
66
66
  return Ok(Link.None());
67
67
  }
68
68
  else {
69
- const ordered = await system.dbusCall({
69
+ const ordered = await domicile.dbus.call({
70
70
  bus: Bus.System,
71
71
  destination: SERVICE,
72
72
  interface: STATION,
@@ -1,4 +1,4 @@
1
- import type { System } from "@domicile-desktop/sdk/system";
1
+ import type { Dbus } from "@domicile-desktop/sdk/desktop/dbus";
2
2
  /** Whether the host reaches the internet. */
3
3
  export declare enum Connectivity {
4
4
  Unknown = 0,
@@ -42,4 +42,6 @@ export type Network = {
42
42
  link: Link;
43
43
  };
44
44
  /** The calls this library makes. */
45
- export type NetworkSystem = Pick<System, "dbusCall" | "dbusMatch">;
45
+ export type NetworkDesktop = {
46
+ readonly dbus: Pick<Dbus, "call" | "match">;
47
+ };
package/dist/network.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { Network, NetworkSystem } from "./network-state";
4
- export type { Network, NetworkSystem } from "./network-state";
3
+ import type { Network, NetworkDesktop } from "./network-state";
4
+ export type { Network, NetworkDesktop } from "./network-state";
5
5
  export { Connectivity, Link, LinkKind } from "./network-state";
6
6
  /**
7
7
  * Calls `onNetwork` with the network now and after each change, and returns a
@@ -12,4 +12,4 @@ export { Connectivity, Link, LinkKind } from "./network-state";
12
12
  * watch. An `Err` is a D-Bus failure, such as none of them running. When the
13
13
  * bus cannot say which runs, the watch reports that `Err` and ends.
14
14
  */
15
- export declare const watchNetwork: (system: NetworkSystem, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
15
+ export declare const watchNetwork: (domicile: NetworkDesktop, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
package/dist/network.js CHANGED
@@ -23,9 +23,9 @@ const BACKENDS = [
23
23
  * watch. An `Err` is a D-Bus failure, such as none of them running. When the
24
24
  * bus cannot say which runs, the watch reports that `Err` and ends.
25
25
  */
26
- export const watchNetwork = (system, onNetwork) => {
26
+ export const watchNetwork = (domicile, onNetwork) => {
27
27
  const watch = { stop: undefined, stopped: false };
28
- detect(system, BACKENDS)
28
+ detect(domicile, BACKENDS)
29
29
  .then((found) => {
30
30
  if (!watch.stopped) {
31
31
  found.match({
@@ -33,7 +33,7 @@ export const watchNetwork = (system, onNetwork) => {
33
33
  onNetwork(Err(error));
34
34
  },
35
35
  Ok: (backend) => {
36
- watch.stop = backend(system, onNetwork);
36
+ watch.stop = backend(domicile, onNetwork);
37
37
  },
38
38
  });
39
39
  }
@@ -48,17 +48,17 @@ export const watchNetwork = (system, onNetwork) => {
48
48
  };
49
49
  };
50
50
  /** The first backend whose service has an owner on the bus. */
51
- const detect = async (system, backends) => {
51
+ const detect = async (domicile, backends) => {
52
52
  const [first, ...rest] = backends;
53
53
  if (first === undefined) {
54
54
  return Ok(watchNetworkManager);
55
55
  }
56
56
  else {
57
57
  const [name, backend] = first;
58
- const owned = await hasOwner(system, name);
58
+ const owned = await hasOwner(domicile, name);
59
59
  return owned.match({
60
60
  Err: (error) => Promise.resolve(Err(error)),
61
- Ok: (has) => (has ? Promise.resolve(Ok(backend)) : detect(system, rest)),
61
+ Ok: (has) => has ? Promise.resolve(Ok(backend)) : detect(domicile, rest),
62
62
  });
63
63
  }
64
64
  };
@@ -1,7 +1,7 @@
1
1
  import type { Option } from "@cprussin/option-result";
2
2
  import { Result } from "@cprussin/option-result";
3
3
  import type { SystemError } from "@domicile-desktop/sdk/system";
4
- import type { NetworkSystem } from "./network-state";
4
+ import type { NetworkDesktop } from "./network-state";
5
5
  import type { Wifi, WifiDevice, WifiNetwork } from "./wifi-state";
6
6
  /** A read's outcome: Wi-Fi, if there is a device, or the first failure. */
7
7
  type Found = Result<Option<Wifi>, SystemError>;
@@ -12,16 +12,16 @@ type Found = Result<Option<Wifi>, SystemError>;
12
12
  * An `Err` is a D-Bus failure, such as NetworkManager not running. The watch
13
13
  * keeps listening after one, so a later change reads again.
14
14
  */
15
- export declare const watchNetworkManagerWifi: (system: NetworkSystem, onWifi: (wifi: Found) => void) => (() => void);
15
+ export declare const watchNetworkManagerWifi: (domicile: NetworkDesktop, onWifi: (wifi: Found) => void) => (() => void);
16
16
  /** Turn the Wi-Fi radio on or off. */
17
- export declare const setNetworkManagerWifiEnabled: (system: NetworkSystem, _wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
17
+ export declare const setNetworkManagerWifiEnabled: (domicile: NetworkDesktop, _wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
18
18
  /** Ask for a scan. Networks it finds arrive as changes. */
19
- export declare const scanNetworkManagerWifi: (system: NetworkSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
19
+ export declare const scanNetworkManagerWifi: (domicile: NetworkDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
20
20
  /**
21
21
  * Join `network`: through its saved profile if it has one, or with a new
22
22
  * profile, which needs `passphrase` when the network is secured.
23
23
  */
24
- export declare const connectNetworkManagerWifi: (system: NetworkSystem, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
24
+ export declare const connectNetworkManagerWifi: (domicile: NetworkDesktop, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
25
25
  /** Leave the current network, until asked to join one. */
26
- export declare const disconnectNetworkManagerWifi: (system: NetworkSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
26
+ export declare const disconnectNetworkManagerWifi: (domicile: NetworkDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
27
27
  export {};
@@ -22,20 +22,20 @@ const WIFI_DEVICE = 2;
22
22
  * An `Err` is a D-Bus failure, such as NetworkManager not running. The watch
23
23
  * keeps listening after one, so a later change reads again.
24
24
  */
25
- export const watchNetworkManagerWifi = (system, onWifi) => followBus(system, { bus: Bus.System, sender: SERVICE }, () => read(system), onWifi);
25
+ export const watchNetworkManagerWifi = (domicile, onWifi) => followBus(domicile, { bus: Bus.System, sender: SERVICE }, () => read(domicile), onWifi);
26
26
  /** Turn the Wi-Fi radio on or off. */
27
- export const setNetworkManagerWifiEnabled = async (system, _wifi, enabled) => done(await system.dbusCall(request(ROOT, "org.freedesktop.DBus.Properties", "Set", "ssv", [
27
+ export const setNetworkManagerWifiEnabled = async (domicile, _wifi, enabled) => done(await domicile.dbus.call(request(ROOT, "org.freedesktop.DBus.Properties", "Set", "ssv", [
28
28
  SERVICE,
29
29
  "WirelessEnabled",
30
30
  { signature: "b", value: enabled },
31
31
  ])));
32
32
  /** Ask for a scan. Networks it finds arrive as changes. */
33
- export const scanNetworkManagerWifi = async (system, wifi) => done(await system.dbusCall(request(wifi.device, WIRELESS, "RequestScan", "a{sv}", [{}])));
33
+ export const scanNetworkManagerWifi = async (domicile, wifi) => done(await domicile.dbus.call(request(wifi.device, WIRELESS, "RequestScan", "a{sv}", [{}])));
34
34
  /**
35
35
  * Join `network`: through its saved profile if it has one, or with a new
36
36
  * profile, which needs `passphrase` when the network is secured.
37
37
  */
38
- export const connectNetworkManagerWifi = async (system, wifi, network, passphrase) => done(await system.dbusCall(network.profile === undefined
38
+ export const connectNetworkManagerWifi = async (domicile, wifi, network, passphrase) => done(await domicile.dbus.call(network.profile === undefined
39
39
  ? request(ROOT, SERVICE, "AddAndActivateConnection", "a{sa{sv}}oo", [
40
40
  newProfile(network, passphrase),
41
41
  wifi.device,
@@ -47,7 +47,7 @@ export const connectNetworkManagerWifi = async (system, wifi, network, passphras
47
47
  network.path,
48
48
  ])));
49
49
  /** Leave the current network, until asked to join one. */
50
- export const disconnectNetworkManagerWifi = async (system, wifi) => done(await system.dbusCall({
50
+ export const disconnectNetworkManagerWifi = async (domicile, wifi) => done(await domicile.dbus.call({
51
51
  bus: Bus.System,
52
52
  destination: SERVICE,
53
53
  interface: DEVICE,
@@ -85,9 +85,9 @@ const newProfile = (network, passphrase) => {
85
85
  * Read Wi-Fi. A property change on an object read for it matters, as does an
86
86
  * access point or a device coming or going.
87
87
  */
88
- const read = async (system) => {
88
+ const read = async (domicile) => {
89
89
  const paths = new Set([ROOT]);
90
- const value = await readWifi(system, paths);
90
+ const value = await readWifi(domicile, paths);
91
91
  return { matters: (signal) => matters(paths, signal), value };
92
92
  };
93
93
  const matters = (paths, signal) => {
@@ -108,31 +108,31 @@ const matters = (paths, signal) => {
108
108
  }
109
109
  };
110
110
  /** Read Wi-Fi, adding each object read to `paths`. */
111
- const readWifi = async (system, paths) => (await properties(system, ROOT, SERVICE, rootSchema)).andThenAsync(async ({ WirelessEnabled: enabled }) => (await call(system, ROOT, SERVICE, "GetDevices")).andThenAsync(async ({ body }) => {
111
+ const readWifi = async (domicile, paths) => (await properties(domicile, ROOT, SERVICE, rootSchema)).andThenAsync(async ({ WirelessEnabled: enabled }) => (await call(domicile, ROOT, SERVICE, "GetDevices")).andThenAsync(async ({ body }) => {
112
112
  const listed = devicesSchema.parse(body)[0];
113
113
  for (const path of listed) {
114
114
  paths.add(path);
115
115
  }
116
- const devices = Result.collect(await Promise.all(listed.map(async (path) => (await properties(system, path, DEVICE, deviceSchema)).map((device) => ({ device, path })))));
116
+ const devices = Result.collect(await Promise.all(listed.map(async (path) => (await properties(domicile, path, DEVICE, deviceSchema)).map((device) => ({ device, path })))));
117
117
  return devices.andThenAsync(async (read) => {
118
118
  const found = read.find(({ device }) => device.DeviceType === WIFI_DEVICE);
119
119
  return found === undefined
120
120
  ? Ok(None())
121
- : (await wifiOf(system, paths, found.path, found.device, enabled)).map((wifi) => Some(wifi));
121
+ : (await wifiOf(domicile, paths, found.path, found.device, enabled)).map((wifi) => Some(wifi));
122
122
  });
123
123
  }));
124
124
  /** The Wi-Fi device at `path`. */
125
- const wifiOf = async (system, paths, path, device, enabled) => (await properties(system, path, WIRELESS, wirelessSchema)).andThenAsync(async (radio) => {
125
+ const wifiOf = async (domicile, paths, path, device, enabled) => (await properties(domicile, path, WIRELESS, wirelessSchema)).andThenAsync(async (radio) => {
126
126
  for (const point of radio.AccessPoints) {
127
127
  paths.add(point);
128
128
  }
129
129
  paths.add(device.Ip4Config);
130
130
  const [points, profiles, ip] = await Promise.all([
131
- accessPoints(system, radio.AccessPoints),
132
- savedProfiles(system, device.AvailableConnections),
131
+ accessPoints(domicile, radio.AccessPoints),
132
+ savedProfiles(domicile, device.AvailableConnections),
133
133
  radio.ActiveAccessPoint === NO_OBJECT || device.Ip4Config === NO_OBJECT
134
134
  ? Promise.resolve(Ok(None()))
135
- : ipOf(system, device.Ip4Config),
135
+ : ipOf(domicile, device.Ip4Config),
136
136
  ]);
137
137
  return points.andThen((read) => profiles.andThen((saved) => ip.map((address) => ({
138
138
  backend: WifiBackend.NetworkManager,
@@ -145,16 +145,16 @@ const wifiOf = async (system, paths, path, device, enabled) => (await properties
145
145
  scanning: false,
146
146
  }))));
147
147
  });
148
- const accessPoints = async (system, listed) => Result.collect(await Promise.all(listed.map(async (path) => (await properties(system, path, `${SERVICE}.AccessPoint`, accessPointSchema)).map((point) => ({ ...point, path })))));
148
+ const accessPoints = async (domicile, listed) => Result.collect(await Promise.all(listed.map(async (path) => (await properties(domicile, path, `${SERVICE}.AccessPoint`, accessPointSchema)).map((point) => ({ ...point, path })))));
149
149
  /** Each saved Wi-Fi profile's path, by its network's name. */
150
- const savedProfiles = async (system, listed) => Result.collect(await Promise.all(listed.map(async (path) => (await call(system, path, `${SERVICE}.Settings.Connection`, "GetSettings")).map(({ body }) => ({
150
+ const savedProfiles = async (domicile, listed) => Result.collect(await Promise.all(listed.map(async (path) => (await call(domicile, path, `${SERVICE}.Settings.Connection`, "GetSettings")).map(({ body }) => ({
151
151
  path,
152
152
  settings: settingsSchema.parse(body)[0],
153
153
  }))))).map((saved) => new Map(saved.flatMap(({ path, settings }) => {
154
154
  const ssid = settings["802-11-wireless"]?.ssid;
155
155
  return ssid === undefined ? [] : [[ssid, path]];
156
156
  })));
157
- const ipOf = async (system, path) => (await properties(system, path, `${SERVICE}.IP4Config`, ip4Schema)).map((config) => Some({
157
+ const ipOf = async (domicile, path) => (await properties(domicile, path, `${SERVICE}.IP4Config`, ip4Schema)).map((config) => Some({
158
158
  addresses: config.AddressData.map(({ address, prefix }) => `${address}/${prefix}`),
159
159
  dns: config.NameserverData.map(({ address }) => address),
160
160
  gateway: config.Gateway === "" ? undefined : config.Gateway,
@@ -198,7 +198,7 @@ const connectionOf = (points, radio, ip) => {
198
198
  };
199
199
  /** `NM_802_11_AP_FLAGS_PRIVACY`, or any WPA or RSN flag. */
200
200
  const isSecured = (point) => (point.Flags & 1) !== 0 || point.WpaFlags !== 0 || point.RsnFlags !== 0;
201
- const call = (system, path, iface, member) => system.dbusCall({
201
+ const call = (domicile, path, iface, member) => domicile.dbus.call({
202
202
  bus: Bus.System,
203
203
  destination: SERVICE,
204
204
  interface: iface,
@@ -206,7 +206,7 @@ const call = (system, path, iface, member) => system.dbusCall({
206
206
  path,
207
207
  });
208
208
  /** `Properties.GetAll` on one of NetworkManager's objects, parsed. */
209
- const properties = async (system, path, interfaceName, schema) => (await system.dbusCall({
209
+ const properties = async (domicile, path, interfaceName, schema) => (await domicile.dbus.call({
210
210
  body: [interfaceName],
211
211
  bus: Bus.System,
212
212
  destination: SERVICE,
@@ -1,6 +1,6 @@
1
1
  import type { Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { Network, NetworkSystem } from "./network-state";
3
+ import type { Network, NetworkDesktop } from "./network-state";
4
4
  /**
5
5
  * Calls `onNetwork` with NetworkManager's network now and after each change,
6
6
  * and returns a function that stops watching.
@@ -8,4 +8,4 @@ import type { Network, NetworkSystem } from "./network-state";
8
8
  * An `Err` is a D-Bus failure, such as NetworkManager not running. The watch
9
9
  * keeps listening after one, so a later change reads again.
10
10
  */
11
- export declare const watchNetworkManager: (system: NetworkSystem, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
11
+ export declare const watchNetworkManager: (domicile: NetworkDesktop, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
@@ -17,22 +17,22 @@ const NO_OBJECT = "/";
17
17
  * An `Err` is a D-Bus failure, such as NetworkManager not running. The watch
18
18
  * keeps listening after one, so a later change reads again.
19
19
  */
20
- export const watchNetworkManager = (system, onNetwork) => followBus(system, {
20
+ export const watchNetworkManager = (domicile, onNetwork) => followBus(domicile, {
21
21
  bus: Bus.System,
22
22
  interface: "org.freedesktop.DBus.Properties",
23
23
  member: "PropertiesChanged",
24
24
  sender: SERVICE,
25
- }, () => read(system), onNetwork);
25
+ }, () => read(domicile), onNetwork);
26
26
  /** Read the network; a change to any object read for it matters. */
27
- const read = async (system) => {
28
- const root = await properties(system, ROOT, SERVICE, rootSchema);
27
+ const read = async (domicile) => {
28
+ const root = await properties(domicile, ROOT, SERVICE, rootSchema);
29
29
  return root.match({
30
30
  Err: (error) => Promise.resolve({
31
31
  matters: ({ path }) => path === ROOT,
32
32
  value: Err(error),
33
33
  }),
34
34
  Ok: async ({ Connectivity: connectivity, PrimaryConnection: primary }) => {
35
- const link = await linkOf(system, primary);
35
+ const link = await linkOf(domicile, primary);
36
36
  const paths = new Set([ROOT, ...link.paths]);
37
37
  return {
38
38
  matters: ({ path }) => paths.has(path),
@@ -45,18 +45,18 @@ const read = async (system) => {
45
45
  });
46
46
  };
47
47
  /** The primary connection at `path`. */
48
- const linkOf = async (system, path) => {
48
+ const linkOf = async (domicile, path) => {
49
49
  if (path === NO_OBJECT) {
50
50
  return { paths: [], result: Ok(Link.None()) };
51
51
  }
52
52
  else {
53
- const active = await properties(system, path, `${SERVICE}.Connection.Active`, activeSchema);
53
+ const active = await properties(domicile, path, `${SERVICE}.Connection.Active`, activeSchema);
54
54
  return active.match({
55
55
  Err: (error) => Promise.resolve({ paths: [path], result: Err(error) }),
56
56
  Ok: async ({ Id: name, SpecificObject: specific, Type: type, }) => {
57
57
  switch (type) {
58
58
  case "802-11-wireless": {
59
- const point = await properties(system, specific, `${SERVICE}.AccessPoint`, accessPointSchema);
59
+ const point = await properties(domicile, specific, `${SERVICE}.AccessPoint`, accessPointSchema);
60
60
  return {
61
61
  paths: [path, specific],
62
62
  result: point.map(({ Ssid: ssid, Strength: strength }) => Link.Wifi(new TextDecoder().decode(new Uint8Array(ssid)), strength / 100)),
@@ -74,7 +74,7 @@ const linkOf = async (system, path) => {
74
74
  }
75
75
  };
76
76
  /** `Properties.GetAll` on one of NetworkManager's objects, parsed. */
77
- const properties = async (system, path, interfaceName, schema) => (await system.dbusCall({
77
+ const properties = async (domicile, path, interfaceName, schema) => (await domicile.dbus.call({
78
78
  body: [interfaceName],
79
79
  bus: Bus.System,
80
80
  destination: SERVICE,
package/dist/portal.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Option, Result } from "@cprussin/option-result";
2
- import type { System, SystemError } from "@domicile-desktop/sdk/system";
2
+ import type { Processes } from "@domicile-desktop/sdk/desktop/processes";
3
+ import type { SystemError } from "@domicile-desktop/sdk/system";
3
4
  /** Chrome's portal probe: `204 No Content` on the open internet. Plain http, so a portal can intercept it. */
4
5
  export declare const PORTAL_PROBE = "http://www.gstatic.com/generate_204";
5
6
  /**
@@ -9,4 +10,6 @@ export declare const PORTAL_PROBE = "http://www.gstatic.com/generate_204";
9
10
  * Retries a probe that gets no answer, since an address or a route can arrive
10
11
  * a moment after the network does. An `Err` is a probe that never got one.
11
12
  */
12
- export declare const checkPortal: (system: Pick<System, "run">) => Promise<Result<Option<string>, SystemError>>;
13
+ export declare const checkPortal: (domicile: {
14
+ readonly processes: Pick<Processes, "run">;
15
+ }) => Promise<Result<Option<string>, SystemError>>;
package/dist/portal.js CHANGED
@@ -16,7 +16,7 @@ const RETRIES = "3";
16
16
  * Retries a probe that gets no answer, since an address or a route can arrive
17
17
  * a moment after the network does. An `Err` is a probe that never got one.
18
18
  */
19
- export const checkPortal = async (system) => (await system.run([
19
+ export const checkPortal = async (domicile) => (await domicile.processes.run([
20
20
  "curl",
21
21
  "--silent",
22
22
  "--output",
@@ -1,4 +1,5 @@
1
- import type { System } from "@domicile-desktop/sdk/system";
1
+ import type { Dbus } from "@domicile-desktop/sdk/desktop/dbus";
2
+ import type { Processes } from "@domicile-desktop/sdk/desktop/processes";
2
3
  /** The service that manages the Wi-Fi device. */
3
4
  export declare enum WifiBackend {
4
5
  NetworkManager = 0,
@@ -51,4 +52,7 @@ export type Wifi = {
51
52
  /** What a request needs of the device. */
52
53
  export type WifiDevice = Pick<Wifi, "backend" | "device" | "interface">;
53
54
  /** The calls this library makes for Wi-Fi. */
54
- export type WifiSystem = Pick<System, "dbusCall" | "dbusMatch" | "run">;
55
+ export type WifiDesktop = {
56
+ readonly dbus: Pick<Dbus, "call" | "match">;
57
+ readonly processes: Pick<Processes, "run">;
58
+ };
package/dist/wifi.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Option, Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { Wifi, WifiDevice, WifiNetwork, WifiSystem } from "./wifi-state";
4
- export type { Ip, Wifi, WifiConnection, WifiDevice, WifiNetwork, WifiSystem, } from "./wifi-state";
3
+ import type { Wifi, WifiDesktop, WifiDevice, WifiNetwork } from "./wifi-state";
4
+ export type { Ip, Wifi, WifiConnection, WifiDesktop, WifiDevice, WifiNetwork, } from "./wifi-state";
5
5
  export { WifiBackend } from "./wifi-state";
6
6
  /**
7
7
  * Calls `onWifi` with the Wi-Fi device now and after each change, and returns
@@ -11,15 +11,15 @@ export { WifiBackend } from "./wifi-state";
11
11
  * `None` is no Wi-Fi device, or neither service: wpa_supplicant alone is not
12
12
  * controlled. An `Err` is a D-Bus failure.
13
13
  */
14
- export declare const watchWifi: (system: WifiSystem, onWifi: (wifi: Result<Option<Wifi>, SystemError>) => void) => (() => void);
14
+ export declare const watchWifi: (domicile: WifiDesktop, onWifi: (wifi: Result<Option<Wifi>, SystemError>) => void) => (() => void);
15
15
  /** Turn the radio on or off. */
16
- export declare const setWifiEnabled: (system: WifiSystem, wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
16
+ export declare const setWifiEnabled: (domicile: WifiDesktop, wifi: WifiDevice, enabled: boolean) => Promise<Result<"done", SystemError>>;
17
17
  /** Ask for a scan. Networks it finds arrive through the watch. */
18
- export declare const scanWifi: (system: WifiSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
18
+ export declare const scanWifi: (domicile: WifiDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
19
19
  /**
20
20
  * Join `network`. A secured network with no saved profile needs `passphrase`;
21
21
  * the call throws without one.
22
22
  */
23
- export declare const connectWifi: (system: WifiSystem, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
23
+ export declare const connectWifi: (domicile: WifiDesktop, wifi: WifiDevice, network: WifiNetwork, passphrase: string | undefined) => Promise<Result<"done", SystemError>>;
24
24
  /** Leave the current network. */
25
- export declare const disconnectWifi: (system: WifiSystem, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
25
+ export declare const disconnectWifi: (domicile: WifiDesktop, wifi: WifiDevice) => Promise<Result<"done", SystemError>>;
package/dist/wifi.js CHANGED
@@ -21,9 +21,9 @@ const BACKENDS = [
21
21
  * `None` is no Wi-Fi device, or neither service: wpa_supplicant alone is not
22
22
  * controlled. An `Err` is a D-Bus failure.
23
23
  */
24
- export const watchWifi = (system, onWifi) => {
24
+ export const watchWifi = (domicile, onWifi) => {
25
25
  const watch = { stop: undefined, stopped: false };
26
- detect(system, BACKENDS)
26
+ detect(domicile, BACKENDS)
27
27
  .then((found) => {
28
28
  if (!watch.stopped) {
29
29
  found.match({
@@ -36,7 +36,7 @@ export const watchWifi = (system, onWifi) => {
36
36
  onWifi(Ok(None()));
37
37
  },
38
38
  Some: (chosen) => {
39
- watch.stop = watchBackend(chosen)(system, onWifi);
39
+ watch.stop = watchBackend(chosen)(domicile, onWifi);
40
40
  },
41
41
  });
42
42
  },
@@ -53,42 +53,42 @@ export const watchWifi = (system, onWifi) => {
53
53
  };
54
54
  };
55
55
  /** Turn the radio on or off. */
56
- export const setWifiEnabled = (system, wifi, enabled) => {
56
+ export const setWifiEnabled = (domicile, wifi, enabled) => {
57
57
  switch (wifi.backend) {
58
58
  case WifiBackend.NetworkManager:
59
- return setNetworkManagerWifiEnabled(system, wifi, enabled);
59
+ return setNetworkManagerWifiEnabled(domicile, wifi, enabled);
60
60
  case WifiBackend.Iwd:
61
- return setIwdWifiEnabled(system, wifi, enabled);
61
+ return setIwdWifiEnabled(domicile, wifi, enabled);
62
62
  }
63
63
  };
64
64
  /** Ask for a scan. Networks it finds arrive through the watch. */
65
- export const scanWifi = (system, wifi) => {
65
+ export const scanWifi = (domicile, wifi) => {
66
66
  switch (wifi.backend) {
67
67
  case WifiBackend.NetworkManager:
68
- return scanNetworkManagerWifi(system, wifi);
68
+ return scanNetworkManagerWifi(domicile, wifi);
69
69
  case WifiBackend.Iwd:
70
- return scanIwdWifi(system, wifi);
70
+ return scanIwdWifi(domicile, wifi);
71
71
  }
72
72
  };
73
73
  /**
74
74
  * Join `network`. A secured network with no saved profile needs `passphrase`;
75
75
  * the call throws without one.
76
76
  */
77
- export const connectWifi = (system, wifi, network, passphrase) => {
77
+ export const connectWifi = (domicile, wifi, network, passphrase) => {
78
78
  switch (wifi.backend) {
79
79
  case WifiBackend.NetworkManager:
80
- return connectNetworkManagerWifi(system, wifi, network, passphrase);
80
+ return connectNetworkManagerWifi(domicile, wifi, network, passphrase);
81
81
  case WifiBackend.Iwd:
82
- return connectIwdWifi(system, wifi, network, passphrase);
82
+ return connectIwdWifi(domicile, wifi, network, passphrase);
83
83
  }
84
84
  };
85
85
  /** Leave the current network. */
86
- export const disconnectWifi = (system, wifi) => {
86
+ export const disconnectWifi = (domicile, wifi) => {
87
87
  switch (wifi.backend) {
88
88
  case WifiBackend.NetworkManager:
89
- return disconnectNetworkManagerWifi(system, wifi);
89
+ return disconnectNetworkManagerWifi(domicile, wifi);
90
90
  case WifiBackend.Iwd:
91
- return disconnectIwdWifi(system, wifi);
91
+ return disconnectIwdWifi(domicile, wifi);
92
92
  }
93
93
  };
94
94
  const watchBackend = (backend) => {
@@ -100,17 +100,17 @@ const watchBackend = (backend) => {
100
100
  }
101
101
  };
102
102
  /** The first backend whose service has an owner on the bus, if any. */
103
- const detect = async (system, backends) => {
103
+ const detect = async (domicile, backends) => {
104
104
  const [first, ...rest] = backends;
105
105
  if (first === undefined) {
106
106
  return Ok(None());
107
107
  }
108
108
  else {
109
109
  const [name, backend] = first;
110
- const owned = await hasOwner(system, name);
110
+ const owned = await hasOwner(domicile, name);
111
111
  return owned.match({
112
112
  Err: (error) => Promise.resolve(Err(error)),
113
- Ok: (has) => has ? Promise.resolve(Ok(Some(backend))) : detect(system, rest),
113
+ Ok: (has) => has ? Promise.resolve(Ok(Some(backend))) : detect(domicile, rest),
114
114
  });
115
115
  }
116
116
  };
@@ -1,6 +1,6 @@
1
1
  import { Result } from "@cprussin/option-result";
2
2
  import type { SystemError } from "@domicile-desktop/sdk/system";
3
- import type { Network, NetworkSystem } from "./network-state";
3
+ import type { Network, NetworkDesktop } from "./network-state";
4
4
  /**
5
5
  * Calls `onNetwork` with wpa_supplicant's network now and after each change,
6
6
  * and returns a function that stops watching. wpa_supplicant is on the bus
@@ -11,4 +11,4 @@ import type { Network, NetworkSystem } from "./network-state";
11
11
  * such as wpa_supplicant not on the bus. The watch keeps listening after one,
12
12
  * so a later change reads again.
13
13
  */
14
- export declare const watchWpaSupplicant: (system: NetworkSystem, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
14
+ export declare const watchWpaSupplicant: (domicile: NetworkDesktop, onNetwork: (network: Result<Network, SystemError>) => void) => (() => void);
@@ -19,13 +19,13 @@ const ROOT = "/fi/w1/wpa_supplicant1";
19
19
  * such as wpa_supplicant not on the bus. The watch keeps listening after one,
20
20
  * so a later change reads again.
21
21
  */
22
- export const watchWpaSupplicant = (system, onNetwork) => followBus(system, { bus: Bus.System, sender: SERVICE }, () => read(system), onNetwork);
22
+ export const watchWpaSupplicant = (domicile, onNetwork) => followBus(domicile, { bus: Bus.System, sender: SERVICE }, () => read(domicile), onNetwork);
23
23
  /**
24
24
  * Read the network. An interface coming or going matters, as does a property
25
25
  * change on an object read for it.
26
26
  */
27
- const read = async (system) => {
28
- const found = await readPaths(system);
27
+ const read = async (domicile) => {
28
+ const found = await readPaths(domicile);
29
29
  return {
30
30
  matters: (signal) => matters(found.paths, signal),
31
31
  value: found.network.map((link) => ({
@@ -53,12 +53,12 @@ const matters = (paths, signal) => {
53
53
  }
54
54
  }
55
55
  };
56
- const readPaths = async (system) => {
57
- const root = await properties(system, ROOT, SERVICE, rootSchema);
56
+ const readPaths = async (domicile) => {
57
+ const root = await properties(domicile, ROOT, SERVICE, rootSchema);
58
58
  return root.match({
59
59
  Err: (error) => Promise.resolve({ network: Err(error), paths: new Set() }),
60
60
  Ok: async ({ Interfaces: paths }) => {
61
- const interfaces = Result.collect(await Promise.all(paths.map(async (path) => (await properties(system, path, `${SERVICE}.Interface`, interfaceSchema)).map((held) => ({ ...held, path })))));
61
+ const interfaces = Result.collect(await Promise.all(paths.map(async (path) => (await properties(domicile, path, `${SERVICE}.Interface`, interfaceSchema)).map((held) => ({ ...held, path })))));
62
62
  return interfaces.match({
63
63
  Err: (error) => Promise.resolve({ network: Err(error), paths: new Set(paths) }),
64
64
  Ok: async (held) => {
@@ -66,7 +66,7 @@ const readPaths = async (system) => {
66
66
  return connected === undefined
67
67
  ? { network: Ok(Link.None()), paths: new Set(paths) }
68
68
  : {
69
- network: await linkOf(system, connected.CurrentBSS),
69
+ network: await linkOf(domicile, connected.CurrentBSS),
70
70
  paths: new Set([...paths, connected.CurrentBSS]),
71
71
  };
72
72
  },
@@ -99,9 +99,9 @@ const isOnline = (state) => {
99
99
  }
100
100
  };
101
101
  /** The network at the BSS `path`. */
102
- const linkOf = async (system, path) => (await properties(system, path, `${SERVICE}.BSS`, bssSchema)).map(({ SSID: ssid, Signal: signal }) => Link.Wifi(new TextDecoder().decode(new Uint8Array(ssid)), strengthOfDbm(signal)));
102
+ const linkOf = async (domicile, path) => (await properties(domicile, path, `${SERVICE}.BSS`, bssSchema)).map(({ SSID: ssid, Signal: signal }) => Link.Wifi(new TextDecoder().decode(new Uint8Array(ssid)), strengthOfDbm(signal)));
103
103
  /** `Properties.GetAll` on one of wpa_supplicant's objects, parsed. */
104
- const properties = async (system, path, interfaceName, schema) => (await system.dbusCall({
104
+ const properties = async (domicile, path, interfaceName, schema) => (await domicile.dbus.call({
105
105
  body: [interfaceName],
106
106
  bus: Bus.System,
107
107
  destination: SERVICE,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "@cprussin/option-result": "^2.0.1",
4
- "@domicile-desktop/sdk": "0.0.0-alpha-44d0983a58ce",
4
+ "@domicile-desktop/sdk": "0.0.0-alpha-56dd6c187f4e",
5
5
  "zod": "^4.5.4"
6
6
  },
7
7
  "description": "The network for a Domicile shell, from NetworkManager, iwd or wpa_supplicant: connectivity and the primary connection, with its Wi-Fi network and signal, kept current.",
@@ -64,5 +64,5 @@
64
64
  "test:unit": "bun test"
65
65
  },
66
66
  "type": "module",
67
- "version": "0.0.0-alpha-44d0983a58ce"
67
+ "version": "0.0.0-alpha-56dd6c187f4e"
68
68
  }