@flighthq/power 0.5.1-next.1069.554a2ac → 0.5.1-next.1197.6a425ce
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 +2 -2
- package/dist/power.d.ts +11 -17
- package/dist/power.d.ts.map +1 -1
- package/dist/power.js +25 -26
- package/dist/power.js.map +1 -1
- package/package.json +4 -4
- package/src/power.test.ts +77 -49
package/README.md
CHANGED
|
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/power`. The `@flight
|
|
|
13
13
|
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
14
14
|
|
|
15
15
|
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
-
- [Source for @flighthq/power@0.5.1-next.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/power@0.5.1-next.1197.6a425ce](https://github.com/flighthq/flight/tree/6a425ce64e6d501dac8218fe625e73d58da88639/packages/power)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/6a425ce64e6d501dac8218fe625e73d58da88639/LICENSE.md)
|
package/dist/power.d.ts
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import type { EntityConstruction,
|
|
2
|
-
export declare function acquirePowerKeepAwake(
|
|
3
|
-
export declare function attachPower(
|
|
1
|
+
import type { EntityConstruction, HostPowerBatteryHealthProvider, HostPowerChangeProvider, HostPowerIdleProvider, HostPowerKeepAwakeProvider, HostPowerSessionLockProvider, HostPowerStatusProvider, HostPowerSuspensionProvider, HostPowerThermalProvider, Power, PowerBatteryHealth, PowerIdleState, PowerKeepAwakeAcquireResult, PowerKeepAwakeMode, PowerKeepAwakeReleaseResult, PowerStatus, PowerThermalState } from '@flighthq/types/contract';
|
|
2
|
+
export declare function acquirePowerKeepAwake(hostPowerKeepAwake: Readonly<HostPowerKeepAwakeProvider>, mode?: PowerKeepAwakeMode): Promise<PowerKeepAwakeAcquireResult>;
|
|
3
|
+
export declare function attachPower(hostPowerStatus: Readonly<HostPowerStatusProvider> | undefined, hostPowerChange: Readonly<HostPowerChangeProvider> | undefined, hostPowerSessionLock: Readonly<HostPowerSessionLockProvider> | undefined, hostPowerSuspension: Readonly<HostPowerSuspensionProvider> | undefined, hostPowerThermal: Readonly<HostPowerThermalProvider> | undefined, hostPowerIdle: Readonly<HostPowerIdleProvider> | undefined, power: Power, idleThresholdSeconds?: number): void;
|
|
4
4
|
export declare function createPower(): Power;
|
|
5
|
-
export declare function destroyPowerKeepAwake(...
|
|
5
|
+
export declare function destroyPowerKeepAwake(...hostPowerKeepAwake: readonly Readonly<HostPowerKeepAwakeProvider>[]): void;
|
|
6
6
|
export declare function detachPower(power: Power): void;
|
|
7
7
|
export declare function disposePower(power: Power): void;
|
|
8
8
|
export declare function enablePowerSignals(power: Power): void;
|
|
9
|
-
export declare function getPowerBatteryHealth(
|
|
10
|
-
readonly power: {
|
|
11
|
-
readonly batteryHealth: {
|
|
12
|
-
getBatteryHealth(out: PowerBatteryHealth): PowerBatteryHealth;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
}, out: PowerBatteryHealth): PowerBatteryHealth;
|
|
9
|
+
export declare function getPowerBatteryHealth(hostPowerBatteryHealth: Readonly<HostPowerBatteryHealthProvider>, out: PowerBatteryHealth): PowerBatteryHealth;
|
|
16
10
|
export declare function getPowerIdlePollingIntervalMs(): number;
|
|
17
|
-
export declare function getPowerStatus(
|
|
18
|
-
export declare function getPowerSystemIdleState(
|
|
19
|
-
export declare function getPowerSystemIdleTime(
|
|
20
|
-
export declare function getPowerThermalState(
|
|
11
|
+
export declare function getPowerStatus(hostPowerStatus: Readonly<HostPowerStatusProvider>, out: PowerStatus): PowerStatus;
|
|
12
|
+
export declare function getPowerSystemIdleState(hostPowerIdle: Readonly<HostPowerIdleProvider>, thresholdSeconds: number): PowerIdleState;
|
|
13
|
+
export declare function getPowerSystemIdleTime(hostPowerIdle: Readonly<HostPowerIdleProvider>): number;
|
|
14
|
+
export declare function getPowerThermalState(hostPowerThermal: Readonly<HostPowerThermalProvider>): PowerThermalState;
|
|
21
15
|
export declare function initializePower(out: EntityConstruction<Power>): void;
|
|
22
|
-
export declare function isPowerKeepAwakeActive(
|
|
16
|
+
export declare function isPowerKeepAwakeActive(hostPowerKeepAwake: Readonly<HostPowerKeepAwakeProvider>): boolean;
|
|
23
17
|
export declare function makePowerBatteryHealth(): PowerBatteryHealth;
|
|
24
18
|
export declare function makePowerStatus(): PowerStatus;
|
|
25
|
-
export declare function releasePowerKeepAwake(
|
|
19
|
+
export declare function releasePowerKeepAwake(hostPowerKeepAwake: Readonly<HostPowerKeepAwakeProvider>): Promise<PowerKeepAwakeReleaseResult>;
|
|
26
20
|
export declare function setPowerIdlePollingIntervalMs(intervalMs: number): void;
|
|
27
21
|
//# sourceMappingURL=power.d.ts.map
|
package/dist/power.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"power.d.ts","sourceRoot":"","sources":["../src/power.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"power.d.ts","sourceRoot":"","sources":["../src/power.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,8BAA8B,EAC9B,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,wBAAwB,EACxB,KAAK,EACL,kBAAkB,EAClB,cAAc,EACd,2BAA2B,EAC3B,kBAAkB,EAClB,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AASlC,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,QAAQ,CAAC,0BAA0B,CAAC,EACxD,IAAI,GAAE,kBAA0C,GAC/C,OAAO,CAAC,2BAA2B,CAAC,CAEtC;AAQD,wBAAgB,WAAW,CACzB,eAAe,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAAG,SAAS,EAC9D,eAAe,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAAG,SAAS,EAC9D,oBAAoB,EAAE,QAAQ,CAAC,4BAA4B,CAAC,GAAG,SAAS,EACxE,mBAAmB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,GAAG,SAAS,EACtE,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAAG,SAAS,EAChE,aAAa,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,SAAS,EAC1D,KAAK,EAAE,KAAK,EACZ,oBAAoB,SAAK,GACxB,IAAI,CA+DN;AAED,wBAAgB,WAAW,IAAI,KAAK,CAInC;AAYD,wBAAgB,qBAAqB,CAAC,GAAG,kBAAkB,EAAE,SAAS,QAAQ,CAAC,0BAA0B,CAAC,EAAE,GAAG,IAAI,CAgBlH;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAa9C;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAW/C;AAGD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAUrD;AAED,wBAAgB,qBAAqB,CACnC,sBAAsB,EAAE,QAAQ,CAAC,8BAA8B,CAAC,EAChE,GAAG,EAAE,kBAAkB,GACtB,kBAAkB,CAEpB;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,WAAW,CAEhH;AAED,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EAC9C,gBAAgB,EAAE,MAAM,GACvB,cAAc,CAEhB;AAED,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,MAAM,CAE7F;AAED,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAAG,iBAAiB,CAE5G;AAID,wBAAgB,eAAe,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAAG,IAAI,CAUpE;AAED,wBAAgB,sBAAsB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GAAG,OAAO,CAExG;AAKD,wBAAgB,sBAAsB,IAAI,kBAAkB,CAQ3D;AAID,wBAAgB,eAAe,IAAI,WAAW,CAW7C;AAID,wBAAgB,qBAAqB,CACnC,kBAAkB,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GACvD,OAAO,CAAC,2BAA2B,CAAC,CAEtC;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEtE"}
|
package/dist/power.js
CHANGED
|
@@ -6,8 +6,8 @@ import { clearSignal, createSignal, emitSignal, hasSignalSlots } from '@flighthq
|
|
|
6
6
|
// after the underlying operation has actually completed.
|
|
7
7
|
// Acquires a keep-awake lock, resolving only once the provider has really taken it. `ok` means the
|
|
8
8
|
// provider acquired its mechanism — not that the hardware can never sleep for other policy reasons.
|
|
9
|
-
export function acquirePowerKeepAwake(
|
|
10
|
-
return
|
|
9
|
+
export function acquirePowerKeepAwake(hostPowerKeepAwake, mode = 'PreventDisplaySleep') {
|
|
10
|
+
return hostPowerKeepAwake.acquire(mode);
|
|
11
11
|
}
|
|
12
12
|
// Starts delivering the host's power events into `power`'s signals. Re-attaching detaches first, so one
|
|
13
13
|
// entity never holds two live subscriptions.
|
|
@@ -15,11 +15,11 @@ export function acquirePowerKeepAwake(host, mode = 'PreventDisplaySleep') {
|
|
|
15
15
|
// Each unsubscribe is ORIGIN-PINNED: it is kept beside the entity that opened it, so detaching one
|
|
16
16
|
// entity ends exactly its own subscriptions. Teardown ATTEMPTS ALL of them even if one throws, because
|
|
17
17
|
// abandoning the rest would leak every subscription after the first failure.
|
|
18
|
-
export function attachPower(
|
|
18
|
+
export function attachPower(hostPowerStatus, hostPowerChange, hostPowerSessionLock, hostPowerSuspension, hostPowerThermal, hostPowerIdle, power, idleThresholdSeconds = 60) {
|
|
19
19
|
detachPower(power);
|
|
20
20
|
const teardowns = [];
|
|
21
|
-
const status =
|
|
22
|
-
const change =
|
|
21
|
+
const status = hostPowerStatus;
|
|
22
|
+
const change = hostPowerChange;
|
|
23
23
|
if (change !== undefined) {
|
|
24
24
|
let wasCharging = status !== undefined ? status.getStatus(makePowerStatus()).isCharging : false;
|
|
25
25
|
teardowns.push(change.subscribe(() => {
|
|
@@ -36,17 +36,17 @@ export function attachPower(host, power, idleThresholdSeconds = 60) {
|
|
|
36
36
|
}
|
|
37
37
|
}));
|
|
38
38
|
}
|
|
39
|
-
const sessionLock =
|
|
39
|
+
const sessionLock = hostPowerSessionLock;
|
|
40
40
|
if (sessionLock !== undefined) {
|
|
41
41
|
teardowns.push(sessionLock.subscribeLock(() => emitSignalWhenPresent(power.onLockScreen)));
|
|
42
42
|
teardowns.push(sessionLock.subscribeUnlock(() => emitSignalWhenPresent(power.onUnlockScreen)));
|
|
43
43
|
}
|
|
44
|
-
const suspension =
|
|
44
|
+
const suspension = hostPowerSuspension;
|
|
45
45
|
if (suspension !== undefined) {
|
|
46
46
|
teardowns.push(suspension.subscribeSuspend(() => emitSignalWhenPresent(power.onSuspend)));
|
|
47
47
|
teardowns.push(suspension.subscribeResume(() => emitSignalWhenPresent(power.onResume)));
|
|
48
48
|
}
|
|
49
|
-
const thermal =
|
|
49
|
+
const thermal = hostPowerThermal;
|
|
50
50
|
if (thermal !== undefined) {
|
|
51
51
|
teardowns.push(thermal.subscribeThermalStateChange((state) => {
|
|
52
52
|
if (power.onThermalStateChange !== null)
|
|
@@ -56,7 +56,7 @@ export function attachPower(host, power, idleThresholdSeconds = 60) {
|
|
|
56
56
|
// Idle is polled because no host pushes idle transitions. The interval exists only when the host
|
|
57
57
|
// actually offers the idle slot: a host that would answer a constant 'Unknown' omits the slot, so
|
|
58
58
|
// nothing polls a value that provably cannot change.
|
|
59
|
-
const idle =
|
|
59
|
+
const idle = hostPowerIdle;
|
|
60
60
|
if (idle !== undefined) {
|
|
61
61
|
let lastIdleState = idle.getIdleState(idleThresholdSeconds);
|
|
62
62
|
const idleIntervalId = setInterval(() => {
|
|
@@ -88,10 +88,9 @@ export function createPower() {
|
|
|
88
88
|
// Attempt-all: every obligation is tried even after one throws, and the first error is rethrown once the
|
|
89
89
|
// siblings have run. A provider whose destroy threw is RETAINED, so a later call retries only the
|
|
90
90
|
// failures; the ones that succeeded are forgotten and never destroyed twice.
|
|
91
|
-
export function destroyPowerKeepAwake(...
|
|
91
|
+
export function destroyPowerKeepAwake(...hostPowerKeepAwake) {
|
|
92
92
|
const pending = new Set();
|
|
93
|
-
for (const
|
|
94
|
-
const provider = host.power.keepAwake;
|
|
93
|
+
for (const provider of hostPowerKeepAwake) {
|
|
95
94
|
if (!_destroyedKeepAwake.has(provider))
|
|
96
95
|
pending.add(provider);
|
|
97
96
|
}
|
|
@@ -161,23 +160,23 @@ export function enablePowerSignals(power) {
|
|
|
161
160
|
power.onThermalStateChange ??= createSignal();
|
|
162
161
|
power.onUnlockScreen ??= createSignal();
|
|
163
162
|
}
|
|
164
|
-
export function getPowerBatteryHealth(
|
|
165
|
-
return
|
|
163
|
+
export function getPowerBatteryHealth(hostPowerBatteryHealth, out) {
|
|
164
|
+
return hostPowerBatteryHealth.getBatteryHealth(out);
|
|
166
165
|
}
|
|
167
166
|
export function getPowerIdlePollingIntervalMs() {
|
|
168
167
|
return _idlePollingIntervalMs;
|
|
169
168
|
}
|
|
170
|
-
export function getPowerStatus(
|
|
171
|
-
return
|
|
169
|
+
export function getPowerStatus(hostPowerStatus, out) {
|
|
170
|
+
return hostPowerStatus.getStatus(out);
|
|
172
171
|
}
|
|
173
|
-
export function getPowerSystemIdleState(
|
|
174
|
-
return
|
|
172
|
+
export function getPowerSystemIdleState(hostPowerIdle, thresholdSeconds) {
|
|
173
|
+
return hostPowerIdle.getIdleState(thresholdSeconds);
|
|
175
174
|
}
|
|
176
|
-
export function getPowerSystemIdleTime(
|
|
177
|
-
return
|
|
175
|
+
export function getPowerSystemIdleTime(hostPowerIdle) {
|
|
176
|
+
return hostPowerIdle.getIdleTimeSeconds();
|
|
178
177
|
}
|
|
179
|
-
export function getPowerThermalState(
|
|
180
|
-
return
|
|
178
|
+
export function getPowerThermalState(hostPowerThermal) {
|
|
179
|
+
return hostPowerThermal.getThermalState();
|
|
181
180
|
}
|
|
182
181
|
// Allocates a Power event entity with its signals left null. Call enablePowerSignals to allocate the
|
|
183
182
|
// signals to connect to, and attachPower to start delivering host events into them.
|
|
@@ -192,8 +191,8 @@ export function initializePower(out) {
|
|
|
192
191
|
out.onThermalStateChange = null;
|
|
193
192
|
out.onUnlockScreen = null;
|
|
194
193
|
}
|
|
195
|
-
export function isPowerKeepAwakeActive(
|
|
196
|
-
return
|
|
194
|
+
export function isPowerKeepAwakeActive(hostPowerKeepAwake) {
|
|
195
|
+
return hostPowerKeepAwake.isActive();
|
|
197
196
|
}
|
|
198
197
|
// Allocates a PowerBatteryHealth value with the domain's complete unknown encoding. Not a create*: this
|
|
199
198
|
// is a plain value the queries fill, with no identity — but it earns a function because the -1/'Unknown'
|
|
@@ -223,8 +222,8 @@ export function makePowerStatus() {
|
|
|
223
222
|
}
|
|
224
223
|
// Releases a keep-awake lock, resolving only once the provider has really let it go. State is never
|
|
225
224
|
// published before the awaited release succeeds.
|
|
226
|
-
export function releasePowerKeepAwake(
|
|
227
|
-
return
|
|
225
|
+
export function releasePowerKeepAwake(hostPowerKeepAwake) {
|
|
226
|
+
return hostPowerKeepAwake.release();
|
|
228
227
|
}
|
|
229
228
|
export function setPowerIdlePollingIntervalMs(intervalMs) {
|
|
230
229
|
_idlePollingIntervalMs = intervalMs > 0 ? intervalMs : 1;
|
package/dist/power.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"power.js","sourceRoot":"","sources":["../src/power.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"power.js","sourceRoot":"","sources":["../src/power.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/power",
|
|
3
|
-
"version": "0.5.1-next.
|
|
3
|
+
"version": "0.5.1-next.1197.6a425ce",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.5.1-next.
|
|
42
|
-
"@flighthq/signals": "0.5.1-next.
|
|
43
|
-
"@flighthq/types": "0.5.1-next.
|
|
41
|
+
"@flighthq/entity": "0.5.1-next.1197.6a425ce",
|
|
42
|
+
"@flighthq/signals": "0.5.1-next.1197.6a425ce",
|
|
43
|
+
"@flighthq/types": "0.5.1-next.1197.6a425ce"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "^5.3.0"
|
package/src/power.test.ts
CHANGED
|
@@ -3,16 +3,17 @@ import { connectSignal } from '@flighthq/signals/contract';
|
|
|
3
3
|
import { EntityRuntimeKey } from '@flighthq/types/contract';
|
|
4
4
|
import type {
|
|
5
5
|
EntityWithoutRuntime,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
HostPowerCapabilities,
|
|
7
|
+
HostPowerBatteryHealthProvider,
|
|
8
|
+
HostPowerKeepAwakeProvider,
|
|
9
|
+
HostPowerChangeProvider,
|
|
9
10
|
PowerIdleState,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
PowerSessionLockBackend,
|
|
11
|
+
HostPowerIdleProvider,
|
|
12
|
+
HostPowerSessionLockProvider,
|
|
13
13
|
PowerStatus,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
HostPowerStatusProvider,
|
|
15
|
+
HostPowerThermalProvider,
|
|
16
|
+
PowerBatteryHealth,
|
|
16
17
|
PowerThermalState,
|
|
17
18
|
} from '@flighthq/types/contract';
|
|
18
19
|
|
|
@@ -40,7 +41,22 @@ import {
|
|
|
40
41
|
|
|
41
42
|
// A host built from exactly the slots a test needs. Nothing installs anywhere, so two hosts can be live
|
|
42
43
|
// at once — the property the ambient seam could not express.
|
|
43
|
-
|
|
44
|
+
interface TestPowerHost {
|
|
45
|
+
readonly power: Partial<HostPowerCapabilities>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function powerAttachProviders(host: TestPowerHost) {
|
|
49
|
+
return [
|
|
50
|
+
host.power.status,
|
|
51
|
+
host.power.change,
|
|
52
|
+
host.power.sessionLock,
|
|
53
|
+
host.power.suspension,
|
|
54
|
+
host.power.thermal,
|
|
55
|
+
host.power.idle,
|
|
56
|
+
] as const;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function statusHost(status: Partial<PowerStatus>): TestPowerHost & { emitChange(): void } {
|
|
44
60
|
const listeners = new Set<() => void>();
|
|
45
61
|
return {
|
|
46
62
|
emitChange(): void {
|
|
@@ -66,7 +82,9 @@ function statusHost(status: Partial<PowerStatus>): PowerAttachHost & { emitChang
|
|
|
66
82
|
};
|
|
67
83
|
}
|
|
68
84
|
|
|
69
|
-
function keepAwakeHost(
|
|
85
|
+
function keepAwakeHost(
|
|
86
|
+
overrides: Partial<{ readonly power: { readonly keepAwake: HostPowerKeepAwakeProvider } }['power']['keepAwake']> = {},
|
|
87
|
+
): { readonly power: { readonly keepAwake: HostPowerKeepAwakeProvider } } {
|
|
70
88
|
return {
|
|
71
89
|
power: {
|
|
72
90
|
keepAwake: (() => {
|
|
@@ -90,7 +108,9 @@ describe('acquirePowerKeepAwake', () => {
|
|
|
90
108
|
return { reason: 'denied' } as const;
|
|
91
109
|
},
|
|
92
110
|
});
|
|
93
|
-
await expect(acquirePowerKeepAwake(host, 'PreventAppSuspension')).resolves.toEqual({
|
|
111
|
+
await expect(acquirePowerKeepAwake(host.power.keepAwake, 'PreventAppSuspension')).resolves.toEqual({
|
|
112
|
+
reason: 'denied',
|
|
113
|
+
});
|
|
94
114
|
expect(seen).toBe('PreventAppSuspension');
|
|
95
115
|
});
|
|
96
116
|
|
|
@@ -102,7 +122,7 @@ describe('acquirePowerKeepAwake', () => {
|
|
|
102
122
|
return { reason: 'ok' } as const;
|
|
103
123
|
},
|
|
104
124
|
});
|
|
105
|
-
await acquirePowerKeepAwake(host);
|
|
125
|
+
await acquirePowerKeepAwake(host.power.keepAwake);
|
|
106
126
|
expect(seen).toBe('PreventDisplaySleep');
|
|
107
127
|
});
|
|
108
128
|
});
|
|
@@ -114,7 +134,7 @@ describe('attachPower', () => {
|
|
|
114
134
|
enablePowerSignals(power);
|
|
115
135
|
const seen: Readonly<PowerStatus>[] = [];
|
|
116
136
|
connectSignal(power.onChange!, (status) => seen.push(status));
|
|
117
|
-
attachPower(host, power);
|
|
137
|
+
attachPower(...powerAttachProviders(host), power);
|
|
118
138
|
host.emitChange();
|
|
119
139
|
host.emitChange();
|
|
120
140
|
expect(seen).toHaveLength(2);
|
|
@@ -126,7 +146,7 @@ describe('attachPower', () => {
|
|
|
126
146
|
it('derives charging transitions from status changes', () => {
|
|
127
147
|
let charging = false;
|
|
128
148
|
const listeners = new Set<() => void>();
|
|
129
|
-
const host:
|
|
149
|
+
const host: TestPowerHost = {
|
|
130
150
|
power: {
|
|
131
151
|
change: (() => {
|
|
132
152
|
const out = allocateEntity<any>();
|
|
@@ -152,7 +172,7 @@ describe('attachPower', () => {
|
|
|
152
172
|
let discharged = 0;
|
|
153
173
|
connectSignal(power.onCharging!, () => charged++);
|
|
154
174
|
connectSignal(power.onDischarging!, () => discharged++);
|
|
155
|
-
attachPower(host, power);
|
|
175
|
+
attachPower(...powerAttachProviders(host), power);
|
|
156
176
|
charging = true;
|
|
157
177
|
for (const l of listeners) l();
|
|
158
178
|
charging = false;
|
|
@@ -163,7 +183,7 @@ describe('attachPower', () => {
|
|
|
163
183
|
|
|
164
184
|
it('delivers the thermal state as the event payload', () => {
|
|
165
185
|
const listeners = new Set<(state: PowerThermalState) => void>();
|
|
166
|
-
const host:
|
|
186
|
+
const host: TestPowerHost = {
|
|
167
187
|
power: {
|
|
168
188
|
thermal: (() => {
|
|
169
189
|
const out = allocateEntity<any>();
|
|
@@ -180,7 +200,7 @@ describe('attachPower', () => {
|
|
|
180
200
|
enablePowerSignals(power);
|
|
181
201
|
const seen: PowerThermalState[] = [];
|
|
182
202
|
connectSignal(power.onThermalStateChange!, (state) => seen.push(state));
|
|
183
|
-
attachPower(host, power);
|
|
203
|
+
attachPower(...powerAttachProviders(host), power);
|
|
184
204
|
for (const l of listeners) l('Critical');
|
|
185
205
|
// ★ An event that only said "something changed" left the state unreadable; the payload is the point.
|
|
186
206
|
expect(seen).toEqual(['Critical']);
|
|
@@ -189,7 +209,7 @@ describe('attachPower', () => {
|
|
|
189
209
|
it('never polls when the host offers no idle slot', () => {
|
|
190
210
|
const spy = vi.spyOn(globalThis, 'setInterval');
|
|
191
211
|
const power = createPower();
|
|
192
|
-
attachPower(statusHost({}), power);
|
|
212
|
+
attachPower(...powerAttachProviders(statusHost({})), power);
|
|
193
213
|
expect(spy).not.toHaveBeenCalled();
|
|
194
214
|
spy.mockRestore();
|
|
195
215
|
});
|
|
@@ -200,8 +220,8 @@ describe('attachPower', () => {
|
|
|
200
220
|
enablePowerSignals(power);
|
|
201
221
|
let count = 0;
|
|
202
222
|
connectSignal(power.onChange!, () => count++);
|
|
203
|
-
attachPower(host, power);
|
|
204
|
-
attachPower(host, power);
|
|
223
|
+
attachPower(...powerAttachProviders(host), power);
|
|
224
|
+
attachPower(...powerAttachProviders(host), power);
|
|
205
225
|
host.emitChange();
|
|
206
226
|
expect(count).toBe(1);
|
|
207
227
|
});
|
|
@@ -218,7 +238,9 @@ describe('createPower', () => {
|
|
|
218
238
|
describe('destroyPowerKeepAwake', () => {
|
|
219
239
|
// Builds the provider ONCE so two hosts can genuinely alias the same object; spreading it per host
|
|
220
240
|
// would silently make them distinct and the alias assertion would prove nothing.
|
|
221
|
-
function keepAwakeProvider(
|
|
241
|
+
function keepAwakeProvider(
|
|
242
|
+
destroy?: () => void,
|
|
243
|
+
): { readonly power: { readonly keepAwake: HostPowerKeepAwakeProvider } }['power']['keepAwake'] {
|
|
222
244
|
const out = allocateEntity<any>();
|
|
223
245
|
out.acquire = async () => ({ reason: 'ok' }) as const;
|
|
224
246
|
out.destroy = destroy;
|
|
@@ -227,7 +249,9 @@ describe('destroyPowerKeepAwake', () => {
|
|
|
227
249
|
return finishEntity(out);
|
|
228
250
|
}
|
|
229
251
|
|
|
230
|
-
function keepAwakeHostWith(
|
|
252
|
+
function keepAwakeHostWith(
|
|
253
|
+
provider: { readonly power: { readonly keepAwake: HostPowerKeepAwakeProvider } }['power']['keepAwake'],
|
|
254
|
+
): { readonly power: { readonly keepAwake: HostPowerKeepAwakeProvider } } {
|
|
231
255
|
return { power: { keepAwake: provider } };
|
|
232
256
|
}
|
|
233
257
|
|
|
@@ -235,7 +259,7 @@ describe('destroyPowerKeepAwake', () => {
|
|
|
235
259
|
it('destroys each distinct provider exactly once, even when hosts alias one', () => {
|
|
236
260
|
let destroyed = 0;
|
|
237
261
|
const shared = keepAwakeProvider(() => destroyed++);
|
|
238
|
-
destroyPowerKeepAwake(keepAwakeHostWith(shared), keepAwakeHostWith(shared));
|
|
262
|
+
destroyPowerKeepAwake(keepAwakeHostWith(shared).power.keepAwake, keepAwakeHostWith(shared).power.keepAwake);
|
|
239
263
|
expect(destroyed).toBe(1);
|
|
240
264
|
});
|
|
241
265
|
|
|
@@ -245,7 +269,9 @@ describe('destroyPowerKeepAwake', () => {
|
|
|
245
269
|
throw new Error('first failed');
|
|
246
270
|
});
|
|
247
271
|
const healthy = keepAwakeProvider(() => (secondDestroyed = true));
|
|
248
|
-
expect(() =>
|
|
272
|
+
expect(() =>
|
|
273
|
+
destroyPowerKeepAwake(keepAwakeHostWith(failing).power.keepAwake, keepAwakeHostWith(healthy).power.keepAwake),
|
|
274
|
+
).toThrow('first failed');
|
|
249
275
|
expect(secondDestroyed).toBe(true);
|
|
250
276
|
});
|
|
251
277
|
|
|
@@ -257,8 +283,12 @@ describe('destroyPowerKeepAwake', () => {
|
|
|
257
283
|
if (attempts === 1) throw new Error('transient');
|
|
258
284
|
});
|
|
259
285
|
const healthy = keepAwakeProvider(() => healthyDestroyed++);
|
|
260
|
-
expect(() =>
|
|
261
|
-
|
|
286
|
+
expect(() =>
|
|
287
|
+
destroyPowerKeepAwake(keepAwakeHostWith(flaky).power.keepAwake, keepAwakeHostWith(healthy).power.keepAwake),
|
|
288
|
+
).toThrow();
|
|
289
|
+
expect(() =>
|
|
290
|
+
destroyPowerKeepAwake(keepAwakeHostWith(flaky).power.keepAwake, keepAwakeHostWith(healthy).power.keepAwake),
|
|
291
|
+
).not.toThrow();
|
|
262
292
|
expect(attempts).toBe(2);
|
|
263
293
|
expect(healthyDestroyed).toBe(1);
|
|
264
294
|
});
|
|
@@ -271,7 +301,7 @@ describe('detachPower', () => {
|
|
|
271
301
|
enablePowerSignals(power);
|
|
272
302
|
let count = 0;
|
|
273
303
|
connectSignal(power.onChange!, () => count++);
|
|
274
|
-
attachPower(host, power);
|
|
304
|
+
attachPower(...powerAttachProviders(host), power);
|
|
275
305
|
detachPower(power);
|
|
276
306
|
host.emitChange();
|
|
277
307
|
expect(count).toBe(0);
|
|
@@ -282,7 +312,7 @@ describe('detachPower', () => {
|
|
|
282
312
|
// after the first failure leaks.
|
|
283
313
|
it('runs every teardown even when one throws', () => {
|
|
284
314
|
let unlockTornDown = false;
|
|
285
|
-
const host:
|
|
315
|
+
const host: TestPowerHost = {
|
|
286
316
|
power: {
|
|
287
317
|
sessionLock: (() => {
|
|
288
318
|
const out = allocateEntity<any>();
|
|
@@ -297,7 +327,7 @@ describe('detachPower', () => {
|
|
|
297
327
|
},
|
|
298
328
|
};
|
|
299
329
|
const power = createPower();
|
|
300
|
-
attachPower(host, power);
|
|
330
|
+
attachPower(...powerAttachProviders(host), power);
|
|
301
331
|
expect(() => detachPower(power)).toThrow('lock teardown failed');
|
|
302
332
|
expect(unlockTornDown).toBe(true);
|
|
303
333
|
});
|
|
@@ -309,8 +339,8 @@ describe('detachPower', () => {
|
|
|
309
339
|
enablePowerSignals(kept);
|
|
310
340
|
let count = 0;
|
|
311
341
|
connectSignal(kept.onChange!, () => count++);
|
|
312
|
-
attachPower(host, kept);
|
|
313
|
-
attachPower(host, dropped);
|
|
342
|
+
attachPower(...powerAttachProviders(host), kept);
|
|
343
|
+
attachPower(...powerAttachProviders(host), dropped);
|
|
314
344
|
detachPower(dropped);
|
|
315
345
|
host.emitChange();
|
|
316
346
|
expect(count).toBe(1);
|
|
@@ -324,7 +354,7 @@ describe('disposePower', () => {
|
|
|
324
354
|
enablePowerSignals(power);
|
|
325
355
|
let count = 0;
|
|
326
356
|
connectSignal(power.onChange!, () => count++);
|
|
327
|
-
attachPower(host, power);
|
|
357
|
+
attachPower(...powerAttachProviders(host), power);
|
|
328
358
|
disposePower(power);
|
|
329
359
|
host.emitChange();
|
|
330
360
|
expect(count).toBe(0);
|
|
@@ -346,17 +376,15 @@ describe('enablePowerSignals', () => {
|
|
|
346
376
|
describe('getPowerBatteryHealth', () => {
|
|
347
377
|
it('fills and returns the caller-owned out parameter', () => {
|
|
348
378
|
const out = makePowerBatteryHealth();
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
};
|
|
359
|
-
expect(getPowerBatteryHealth(host, out)).toBe(out);
|
|
379
|
+
const provider = (() => {
|
|
380
|
+
const target = allocateEntity<HostPowerBatteryHealthProvider>();
|
|
381
|
+
target.getBatteryHealth = (health: PowerBatteryHealth): PowerBatteryHealth => {
|
|
382
|
+
health.cycleCount = 12;
|
|
383
|
+
return health;
|
|
384
|
+
};
|
|
385
|
+
return finishEntity(target);
|
|
386
|
+
})();
|
|
387
|
+
expect(getPowerBatteryHealth(provider, out)).toBe(out);
|
|
360
388
|
expect(out.cycleCount).toBe(12);
|
|
361
389
|
});
|
|
362
390
|
});
|
|
@@ -372,7 +400,7 @@ describe('getPowerIdlePollingIntervalMs', () => {
|
|
|
372
400
|
describe('getPowerStatus', () => {
|
|
373
401
|
it('fills the caller-owned out parameter', () => {
|
|
374
402
|
const out = makePowerStatus();
|
|
375
|
-
expect(getPowerStatus(statusHost({ isCharging: true })
|
|
403
|
+
expect(getPowerStatus(statusHost({ isCharging: true }).power.status!, out)).toBe(out);
|
|
376
404
|
expect(out.isCharging).toBe(true);
|
|
377
405
|
});
|
|
378
406
|
});
|
|
@@ -393,7 +421,7 @@ describe('getPowerSystemIdleState', () => {
|
|
|
393
421
|
})(),
|
|
394
422
|
},
|
|
395
423
|
};
|
|
396
|
-
expect(getPowerSystemIdleState(host, 90)).toBe('Idle');
|
|
424
|
+
expect(getPowerSystemIdleState(host.power.idle, 90)).toBe('Idle');
|
|
397
425
|
expect(seen).toBe(90);
|
|
398
426
|
});
|
|
399
427
|
});
|
|
@@ -410,7 +438,7 @@ describe('getPowerSystemIdleTime', () => {
|
|
|
410
438
|
})(),
|
|
411
439
|
},
|
|
412
440
|
};
|
|
413
|
-
expect(getPowerSystemIdleTime(host)).toBe(42);
|
|
441
|
+
expect(getPowerSystemIdleTime(host.power.idle)).toBe(42);
|
|
414
442
|
});
|
|
415
443
|
});
|
|
416
444
|
|
|
@@ -426,7 +454,7 @@ describe('getPowerThermalState', () => {
|
|
|
426
454
|
})(),
|
|
427
455
|
},
|
|
428
456
|
};
|
|
429
|
-
expect(getPowerThermalState(host)).toBe('Fair');
|
|
457
|
+
expect(getPowerThermalState(host.power.thermal)).toBe('Fair');
|
|
430
458
|
});
|
|
431
459
|
});
|
|
432
460
|
|
|
@@ -438,7 +466,7 @@ describe('initializePower', () => {
|
|
|
438
466
|
|
|
439
467
|
describe('isPowerKeepAwakeActive', () => {
|
|
440
468
|
it('reports the provider state', () => {
|
|
441
|
-
expect(isPowerKeepAwakeActive(keepAwakeHost({ isActive: () => true }))).toBe(true);
|
|
469
|
+
expect(isPowerKeepAwakeActive(keepAwakeHost({ isActive: () => true }).power.keepAwake)).toBe(true);
|
|
442
470
|
});
|
|
443
471
|
});
|
|
444
472
|
|
|
@@ -481,7 +509,7 @@ describe('makePowerStatus', () => {
|
|
|
481
509
|
describe('releasePowerKeepAwake', () => {
|
|
482
510
|
it('resolves the provider outcome', async () => {
|
|
483
511
|
const host = keepAwakeHost({ release: async () => ({ reason: 'inactive' }) as const });
|
|
484
|
-
await expect(releasePowerKeepAwake(host)).resolves.toEqual({ reason: 'inactive' });
|
|
512
|
+
await expect(releasePowerKeepAwake(host.power.keepAwake)).resolves.toEqual({ reason: 'inactive' });
|
|
485
513
|
});
|
|
486
514
|
});
|
|
487
515
|
describe('setPowerIdlePollingIntervalMs', () => {
|