@flighthq/power 0.5.0-next.1944.cd6b6e7 → 0.5.1-edge.638.d4dbd4e
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/power.d.ts +19 -18
- package/dist/power.d.ts.map +1 -1
- package/dist/power.js +203 -246
- package/dist/power.js.map +1 -1
- package/package.json +4 -3
- package/src/power.test.ts +328 -568
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.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/power@0.5.1-edge.638.d4dbd4e](https://github.com/flighthq/flight/tree/d4dbd4e347dc8be10b180c85a766ab50333dcb51/packages/power)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/d4dbd4e347dc8be10b180c85a766ab50333dcb51/LICENSE.md)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { attachPower, createPower, detachPower, disposePower, enablePowerSignals,
|
|
1
|
+
export { acquirePowerKeepAwake, attachPower, createPower, destroyPowerKeepAwake, detachPower, disposePower, enablePowerSignals, getPowerBatteryHealth, getPowerIdlePollingIntervalMs, getPowerStatus, getPowerSystemIdleState, getPowerSystemIdleTime, getPowerThermalState, isPowerKeepAwakeActive, makePowerBatteryHealth, makePowerStatus, releasePowerKeepAwake, setPowerIdlePollingIntervalMs, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { attachPower, createPower, detachPower, disposePower, enablePowerSignals,
|
|
1
|
+
export { acquirePowerKeepAwake, attachPower, createPower, destroyPowerKeepAwake, detachPower, disposePower, enablePowerSignals, getPowerBatteryHealth, getPowerIdlePollingIntervalMs, getPowerStatus, getPowerSystemIdleState, getPowerSystemIdleTime, getPowerThermalState, isPowerKeepAwakeActive, makePowerBatteryHealth, makePowerStatus, releasePowerKeepAwake, setPowerIdlePollingIntervalMs, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,YAAY,CAAC"}
|
package/dist/power.d.ts
CHANGED
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare function attachPower(power: Power, idleThresholdSeconds?: number): void;
|
|
1
|
+
import type { HasPowerIdle, HasPowerKeepAwake, HasPowerStatus, HasPowerThermal, PowerAttachHost, Power, PowerBatteryHealth, PowerIdleState, PowerKeepAwakeAcquireResult, PowerKeepAwakeMode, PowerKeepAwakeReleaseResult, PowerStatus, PowerThermalState } from '@flighthq/types/contract';
|
|
2
|
+
export declare function acquirePowerKeepAwake(host: HasPowerKeepAwake, mode?: PowerKeepAwakeMode): Promise<PowerKeepAwakeAcquireResult>;
|
|
3
|
+
export declare function attachPower(host: PowerAttachHost, power: Power, idleThresholdSeconds?: number): void;
|
|
4
4
|
export declare function createPower(): Power;
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function createPowerStatus(): PowerStatus;
|
|
5
|
+
export declare function destroyPowerKeepAwake(...hosts: readonly HasPowerKeepAwake[]): void;
|
|
7
6
|
export declare function detachPower(power: Power): void;
|
|
8
7
|
export declare function disposePower(power: Power): void;
|
|
9
8
|
export declare function enablePowerSignals(power: Power): void;
|
|
10
|
-
export declare function
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
export declare function getPowerBatteryHealth(host: {
|
|
10
|
+
readonly power: {
|
|
11
|
+
readonly batteryHealth: {
|
|
12
|
+
getBatteryHealth(out: PowerBatteryHealth): PowerBatteryHealth;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
}, out: PowerBatteryHealth): PowerBatteryHealth;
|
|
13
16
|
export declare function getPowerIdlePollingIntervalMs(): number;
|
|
14
|
-
export declare function getPowerStatus(out: PowerStatus): PowerStatus;
|
|
15
|
-
export declare function getPowerSystemIdleState(thresholdSeconds: number): PowerIdleState;
|
|
16
|
-
export declare function getPowerSystemIdleTime(): number;
|
|
17
|
-
export declare function getPowerThermalState(): PowerThermalState;
|
|
18
|
-
export declare function
|
|
19
|
-
export declare function
|
|
20
|
-
export declare function
|
|
21
|
-
export declare function
|
|
22
|
-
export declare function setPowerBackend(backend: PowerBackend | null): void;
|
|
17
|
+
export declare function getPowerStatus(host: HasPowerStatus, out: PowerStatus): PowerStatus;
|
|
18
|
+
export declare function getPowerSystemIdleState(host: HasPowerIdle, thresholdSeconds: number): PowerIdleState;
|
|
19
|
+
export declare function getPowerSystemIdleTime(host: HasPowerIdle): number;
|
|
20
|
+
export declare function getPowerThermalState(host: HasPowerThermal): PowerThermalState;
|
|
21
|
+
export declare function isPowerKeepAwakeActive(host: HasPowerKeepAwake): boolean;
|
|
22
|
+
export declare function makePowerBatteryHealth(): PowerBatteryHealth;
|
|
23
|
+
export declare function makePowerStatus(): PowerStatus;
|
|
24
|
+
export declare function releasePowerKeepAwake(host: HasPowerKeepAwake): Promise<PowerKeepAwakeReleaseResult>;
|
|
23
25
|
export declare function setPowerIdlePollingIntervalMs(intervalMs: number): void;
|
|
24
|
-
export declare function setPowerKeepAwake(enabled: boolean, mode?: PowerKeepAwakeMode): boolean;
|
|
25
26
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"power.d.ts","sourceRoot":"","sources":["../src/power.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,KAAK,EACL,kBAAkB,EAClB,cAAc,EACd,2BAA2B,EAC3B,kBAAkB,EAClB,2BAA2B,EAC3B,WAAW,EACX,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AASlC,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,iBAAiB,EACvB,IAAI,GAAE,kBAA0C,GAC/C,OAAO,CAAC,2BAA2B,CAAC,CAEtC;AAQD,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,SAAK,GAAG,IAAI,CA+DhG;AAID,wBAAgB,WAAW,IAAI,KAAK,CAYnC;AAYD,wBAAgB,qBAAqB,CAAC,GAAG,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,CAiBlF;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,IAAI,EAAE;IACJ,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE;YAAE,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,GAAG,kBAAkB,CAAA;SAAE,CAAA;KAAE,CAAC;CAC/G,EACD,GAAG,EAAE,kBAAkB,GACtB,kBAAkB,CAEpB;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,WAAW,GAAG,WAAW,CAElF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,GAAG,cAAc,CAEpG;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEjE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAE7E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAEvE;AAKD,wBAAgB,sBAAsB,IAAI,kBAAkB,CAQ3D;AAID,wBAAgB,eAAe,IAAI,WAAW,CAW7C;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAEnG;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAEtE"}
|
package/dist/power.js
CHANGED
|
@@ -1,286 +1,243 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
export function
|
|
1
|
+
import { createEntity } from '@flighthq/entity/contract';
|
|
2
|
+
import { clearSignal, createSignal, emitSignal, hasSignalSlots } from '@flighthq/signals/contract';
|
|
3
|
+
// AN ATTEMPT IS NEVER AN OUTCOME. The previous seam recorded that an operation had been STARTED and
|
|
4
|
+
// reported that as availability: a denied Wake Lock request was observed as 'available' because the
|
|
5
|
+
// observation ran on the synchronous path before the promise settled. Every result here is produced
|
|
6
|
+
// after the underlying operation has actually completed.
|
|
7
|
+
// Acquires a keep-awake lock, resolving only once the provider has really taken it. `ok` means the
|
|
8
|
+
// provider acquired its mechanism — not that the hardware can never sleep for other policy reasons.
|
|
9
|
+
export function acquirePowerKeepAwake(host, mode = 'PreventDisplaySleep') {
|
|
10
|
+
return host.power.keepAwake.acquire(mode);
|
|
11
|
+
}
|
|
12
|
+
// Starts delivering the host's power events into `power`'s signals. Re-attaching detaches first, so one
|
|
13
|
+
// entity never holds two live subscriptions.
|
|
14
|
+
//
|
|
15
|
+
// Each unsubscribe is ORIGIN-PINNED: it is kept beside the entity that opened it, so detaching one
|
|
16
|
+
// entity ends exactly its own subscriptions. Teardown ATTEMPTS ALL of them even if one throws, because
|
|
17
|
+
// abandoning the rest would leak every subscription after the first failure.
|
|
18
|
+
export function attachPower(host, power, idleThresholdSeconds = 60) {
|
|
10
19
|
detachPower(power);
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
21
|
-
emitSignal(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
unsubscribeLowPowerModeChange();
|
|
67
|
-
unsubscribeResume();
|
|
68
|
-
unsubscribeSuspend();
|
|
69
|
-
unsubscribeThermalStateChange();
|
|
70
|
-
unsubscribeUnlockScreen();
|
|
71
|
-
clearInterval(idleIntervalId);
|
|
72
|
-
});
|
|
20
|
+
const teardowns = [];
|
|
21
|
+
const status = host.power.status;
|
|
22
|
+
const change = host.power.change;
|
|
23
|
+
if (change !== undefined) {
|
|
24
|
+
let wasCharging = status !== undefined ? status.getStatus(makePowerStatus()).isCharging : false;
|
|
25
|
+
teardowns.push(change.subscribe(() => {
|
|
26
|
+
// A FRESH value per event, never a shared reusable buffer: a listener may retain this payload
|
|
27
|
+
// and it must not mutate underneath on the next power event.
|
|
28
|
+
const current = status !== undefined ? status.getStatus(makePowerStatus()) : null;
|
|
29
|
+
if (current !== null && power.onChange !== null)
|
|
30
|
+
emitSignal(power.onChange, current);
|
|
31
|
+
if (current !== null && current.isCharging !== wasCharging) {
|
|
32
|
+
wasCharging = current.isCharging;
|
|
33
|
+
const transition = current.isCharging ? power.onCharging : power.onDischarging;
|
|
34
|
+
if (transition !== null)
|
|
35
|
+
emitSignal(transition);
|
|
36
|
+
}
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
const sessionLock = host.power.sessionLock;
|
|
40
|
+
if (sessionLock !== undefined) {
|
|
41
|
+
teardowns.push(sessionLock.subscribeLock(() => emitSignalWhenPresent(power.onLockScreen)));
|
|
42
|
+
teardowns.push(sessionLock.subscribeUnlock(() => emitSignalWhenPresent(power.onUnlockScreen)));
|
|
43
|
+
}
|
|
44
|
+
const suspension = host.power.suspension;
|
|
45
|
+
if (suspension !== undefined) {
|
|
46
|
+
teardowns.push(suspension.subscribeSuspend(() => emitSignalWhenPresent(power.onSuspend)));
|
|
47
|
+
teardowns.push(suspension.subscribeResume(() => emitSignalWhenPresent(power.onResume)));
|
|
48
|
+
}
|
|
49
|
+
const thermal = host.power.thermal;
|
|
50
|
+
if (thermal !== undefined) {
|
|
51
|
+
teardowns.push(thermal.subscribeThermalStateChange((state) => {
|
|
52
|
+
if (power.onThermalStateChange !== null)
|
|
53
|
+
emitSignal(power.onThermalStateChange, state);
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
// Idle is polled because no host pushes idle transitions. The interval exists only when the host
|
|
57
|
+
// actually offers the idle slot: a host that would answer a constant 'Unknown' omits the slot, so
|
|
58
|
+
// nothing polls a value that provably cannot change.
|
|
59
|
+
const idle = host.power.idle;
|
|
60
|
+
if (idle !== undefined) {
|
|
61
|
+
let lastIdleState = idle.getIdleState(idleThresholdSeconds);
|
|
62
|
+
const idleIntervalId = setInterval(() => {
|
|
63
|
+
const idleSignal = power.onIdleStateChange;
|
|
64
|
+
if (idleSignal === null || !hasSignalSlots(idleSignal))
|
|
65
|
+
return;
|
|
66
|
+
const current = idle.getIdleState(idleThresholdSeconds);
|
|
67
|
+
if (current !== lastIdleState) {
|
|
68
|
+
lastIdleState = current;
|
|
69
|
+
emitSignal(idleSignal);
|
|
70
|
+
}
|
|
71
|
+
}, _idlePollingIntervalMs);
|
|
72
|
+
teardowns.push(() => clearInterval(idleIntervalId));
|
|
73
|
+
}
|
|
74
|
+
_subscriptions.set(power, teardowns);
|
|
73
75
|
}
|
|
74
76
|
// Allocates a Power event entity with its signals left null. Call enablePowerSignals to allocate the
|
|
75
|
-
// signals to connect to, and attachPower to start delivering
|
|
77
|
+
// signals to connect to, and attachPower to start delivering host events into them.
|
|
76
78
|
export function createPower() {
|
|
77
|
-
return {
|
|
79
|
+
return createEntity({
|
|
78
80
|
onChange: null,
|
|
79
81
|
onCharging: null,
|
|
80
82
|
onDischarging: null,
|
|
81
83
|
onIdleStateChange: null,
|
|
82
84
|
onLockScreen: null,
|
|
83
|
-
onLowPowerModeChange: null,
|
|
84
85
|
onResume: null,
|
|
85
86
|
onSuspend: null,
|
|
86
87
|
onThermalStateChange: null,
|
|
87
88
|
onUnlockScreen: null,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
// Allocates a zeroed PowerBatteryHealth, suitable as the `out` for getPowerBatteryHealth.
|
|
91
|
-
export function createPowerBatteryHealth() {
|
|
92
|
-
return {
|
|
93
|
-
capacityWearLevel: -1,
|
|
94
|
-
cycleCount: -1,
|
|
95
|
-
healthState: 'Unknown',
|
|
96
|
-
temperatureCelsius: -1,
|
|
97
|
-
voltage: -1,
|
|
98
|
-
};
|
|
89
|
+
});
|
|
99
90
|
}
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
91
|
+
// Stops delivery without discarding the entity. Runs every teardown this entity opened, ATTEMPTING ALL
|
|
92
|
+
// of them: one throwing unsubscribe must not strand the rest. Does not touch the provider — that is
|
|
93
|
+
// `destroy` on the host's slot, a separate lifecycle.
|
|
94
|
+
// FINAL RELEASE for the one power slot that owns a whole-provider resource. Destroys every DISTINCT
|
|
95
|
+
// keep-awake provider exactly once — alias-safe, because two hosts may share one provider object and
|
|
96
|
+
// destroying it twice would double-release an OS lock.
|
|
97
|
+
//
|
|
98
|
+
// Attempt-all: every obligation is tried even after one throws, and the first error is rethrown once the
|
|
99
|
+
// siblings have run. A provider whose destroy threw is RETAINED, so a later call retries only the
|
|
100
|
+
// failures; the ones that succeeded are forgotten and never destroyed twice.
|
|
101
|
+
export function destroyPowerKeepAwake(...hosts) {
|
|
102
|
+
const pending = new Set();
|
|
103
|
+
for (const host of hosts) {
|
|
104
|
+
const provider = host.power.keepAwake;
|
|
105
|
+
if (!_destroyedKeepAwake.has(provider))
|
|
106
|
+
pending.add(provider);
|
|
107
|
+
}
|
|
108
|
+
let failure = null;
|
|
109
|
+
for (const provider of pending) {
|
|
110
|
+
try {
|
|
111
|
+
if (provider.destroy !== undefined)
|
|
112
|
+
assertSyncVoid(provider.destroy());
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
failure ??= error;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
_destroyedKeepAwake.add(provider);
|
|
119
|
+
}
|
|
120
|
+
if (failure !== null)
|
|
121
|
+
throw failure;
|
|
112
122
|
}
|
|
113
|
-
// Stops delivery to `power` and forgets its subscription. Safe to call when not attached.
|
|
114
123
|
export function detachPower(power) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
const teardowns = _subscriptions.get(power);
|
|
125
|
+
if (teardowns === undefined)
|
|
126
|
+
return;
|
|
127
|
+
_subscriptions.delete(power);
|
|
128
|
+
let failure = null;
|
|
129
|
+
for (const teardown of teardowns) {
|
|
130
|
+
try {
|
|
131
|
+
teardown();
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
failure ??= error;
|
|
135
|
+
}
|
|
119
136
|
}
|
|
137
|
+
if (failure !== null)
|
|
138
|
+
throw failure;
|
|
120
139
|
}
|
|
121
|
-
//
|
|
122
|
-
// plain GC-managed memory afterward.
|
|
140
|
+
// Terminal disposal: detaches and then clears the entity's signals, so it becomes GC-eligible.
|
|
123
141
|
export function disposePower(power) {
|
|
124
142
|
detachPower(power);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
143
|
+
if (power.onChange !== null)
|
|
144
|
+
clearSignal(power.onChange);
|
|
145
|
+
if (power.onCharging !== null)
|
|
146
|
+
clearSignal(power.onCharging);
|
|
147
|
+
if (power.onDischarging !== null)
|
|
148
|
+
clearSignal(power.onDischarging);
|
|
149
|
+
if (power.onIdleStateChange !== null)
|
|
150
|
+
clearSignal(power.onIdleStateChange);
|
|
151
|
+
if (power.onLockScreen !== null)
|
|
152
|
+
clearSignal(power.onLockScreen);
|
|
153
|
+
if (power.onResume !== null)
|
|
154
|
+
clearSignal(power.onResume);
|
|
155
|
+
if (power.onSuspend !== null)
|
|
156
|
+
clearSignal(power.onSuspend);
|
|
157
|
+
if (power.onThermalStateChange !== null)
|
|
158
|
+
clearSignal(power.onThermalStateChange);
|
|
159
|
+
if (power.onUnlockScreen !== null)
|
|
160
|
+
clearSignal(power.onUnlockScreen);
|
|
161
|
+
}
|
|
162
|
+
// Allocates any not-yet-allocated Power signals so callers can connect to them. Idempotent.
|
|
128
163
|
export function enablePowerSignals(power) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (power.onResume === null)
|
|
142
|
-
power.onResume = createSignal();
|
|
143
|
-
if (power.onSuspend === null)
|
|
144
|
-
power.onSuspend = createSignal();
|
|
145
|
-
if (power.onThermalStateChange === null)
|
|
146
|
-
power.onThermalStateChange = createSignal();
|
|
147
|
-
if (power.onUnlockScreen === null)
|
|
148
|
-
power.onUnlockScreen = createSignal();
|
|
164
|
+
power.onChange ??= createSignal();
|
|
165
|
+
power.onCharging ??= createSignal();
|
|
166
|
+
power.onDischarging ??= createSignal();
|
|
167
|
+
power.onIdleStateChange ??= createSignal();
|
|
168
|
+
power.onLockScreen ??= createSignal();
|
|
169
|
+
power.onResume ??= createSignal();
|
|
170
|
+
power.onSuspend ??= createSignal();
|
|
171
|
+
power.onThermalStateChange ??= createSignal();
|
|
172
|
+
power.onUnlockScreen ??= createSignal();
|
|
173
|
+
}
|
|
174
|
+
export function getPowerBatteryHealth(host, out) {
|
|
175
|
+
return host.power.batteryHealth.getBatteryHealth(out);
|
|
149
176
|
}
|
|
150
|
-
export function explainPowerBackend() {
|
|
151
|
-
if (_custom !== null) {
|
|
152
|
-
return { conflict: _hostConflict, layer: 'custom', operation: null, viability: 'unobserved' };
|
|
153
|
-
}
|
|
154
|
-
if (_host !== null) {
|
|
155
|
-
return {
|
|
156
|
-
conflict: _hostConflict,
|
|
157
|
-
layer: 'host',
|
|
158
|
-
operation: _hostObservation !== null ? _hostObservation.operation : null,
|
|
159
|
-
viability: _hostObservation !== null ? _hostObservation.viability : 'unobserved',
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return { conflict: false, layer: 'host-not-enabled', operation: null, viability: 'unobserved' };
|
|
163
|
-
}
|
|
164
|
-
export function getPowerBackend() {
|
|
165
|
-
return _custom ?? _host ?? _sentinel;
|
|
166
|
-
}
|
|
167
|
-
// Returns the battery health detail from the active backend, writing into `out` and returning it,
|
|
168
|
-
// or returns null when the active backend does not support battery health reporting.
|
|
169
|
-
export function getPowerBatteryHealth(out) {
|
|
170
|
-
return getPowerBackend().getBatteryHealth(out);
|
|
171
|
-
}
|
|
172
|
-
// Returns the current idle-state polling interval in milliseconds (default 5000).
|
|
173
177
|
export function getPowerIdlePollingIntervalMs() {
|
|
174
178
|
return _idlePollingIntervalMs;
|
|
175
179
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return getPowerBackend().getStatus(out);
|
|
179
|
-
}
|
|
180
|
-
// Returns the current system idle state at the given threshold in seconds.
|
|
181
|
-
export function getPowerSystemIdleState(thresholdSeconds) {
|
|
182
|
-
return getPowerBackend().getSystemIdleState(thresholdSeconds);
|
|
180
|
+
export function getPowerStatus(host, out) {
|
|
181
|
+
return host.power.status.getStatus(out);
|
|
183
182
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return getPowerBackend().getSystemIdleTime();
|
|
183
|
+
export function getPowerSystemIdleState(host, thresholdSeconds) {
|
|
184
|
+
return host.power.idle.getIdleState(thresholdSeconds);
|
|
187
185
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return getPowerBackend().getStatus(_scratch).thermalState;
|
|
186
|
+
export function getPowerSystemIdleTime(host) {
|
|
187
|
+
return host.power.idle.getIdleTimeSeconds();
|
|
191
188
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return getPowerBackend().isKeepAwakeActive();
|
|
189
|
+
export function getPowerThermalState(host) {
|
|
190
|
+
return host.power.thermal.getThermalState();
|
|
195
191
|
}
|
|
196
|
-
export function
|
|
197
|
-
|
|
198
|
-
if (_host !== backend)
|
|
199
|
-
_hostConflict = true;
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
_host = backend;
|
|
192
|
+
export function isPowerKeepAwakeActive(host) {
|
|
193
|
+
return host.power.keepAwake.isActive();
|
|
203
194
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
195
|
+
// Allocates a PowerBatteryHealth value with the domain's complete unknown encoding. Not a create*: this
|
|
196
|
+
// is a plain value the queries fill, with no identity — but it earns a function because the -1/'Unknown'
|
|
197
|
+
// defaults are load-bearing and a literal `{}` would read as undefined where the domain expects -1.
|
|
198
|
+
export function makePowerBatteryHealth() {
|
|
199
|
+
return {
|
|
200
|
+
capacityWearLevel: -1,
|
|
201
|
+
cycleCount: -1,
|
|
202
|
+
healthState: 'Unknown',
|
|
203
|
+
temperatureCelsius: -1,
|
|
204
|
+
voltage: -1,
|
|
208
205
|
};
|
|
209
206
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
207
|
+
// Allocates a PowerStatus value with the domain's complete unknown encoding. Same reasoning as
|
|
208
|
+
// makePowerBatteryHealth: a value, not an entity, but the defaults are load-bearing.
|
|
209
|
+
export function makePowerStatus() {
|
|
210
|
+
return {
|
|
211
|
+
batteryLevel: -1,
|
|
212
|
+
chargingTime: -1,
|
|
213
|
+
dischargingTime: -1,
|
|
214
|
+
isBatteryLow: false,
|
|
215
|
+
isCharging: false,
|
|
216
|
+
isLowPower: false,
|
|
217
|
+
isOnBattery: false,
|
|
218
|
+
thermalState: 'Unknown',
|
|
219
|
+
};
|
|
215
220
|
}
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
// Releases a keep-awake lock, resolving only once the provider has really let it go. State is never
|
|
222
|
+
// published before the awaited release succeeds.
|
|
223
|
+
export function releasePowerKeepAwake(host) {
|
|
224
|
+
return host.power.keepAwake.release();
|
|
218
225
|
}
|
|
219
|
-
// Sets the interval at which attachPower polls the backend for idle state changes. The default is
|
|
220
|
-
// 5000ms (5 seconds); set lower for more responsive idle detection at the cost of more frequent
|
|
221
|
-
// backend calls. Only affects Power entities attached after this call.
|
|
222
226
|
export function setPowerIdlePollingIntervalMs(intervalMs) {
|
|
223
|
-
_idlePollingIntervalMs = intervalMs;
|
|
227
|
+
_idlePollingIntervalMs = intervalMs > 0 ? intervalMs : 1;
|
|
224
228
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return getPowerBackend().setKeepAwake(enabled, mode);
|
|
229
|
+
function emitSignalWhenPresent(signal) {
|
|
230
|
+
if (signal !== null)
|
|
231
|
+
emitSignal(signal);
|
|
229
232
|
}
|
|
230
|
-
let _custom = null;
|
|
231
|
-
let _host = null;
|
|
232
|
-
let _hostConflict = false;
|
|
233
|
-
let _hostObservation = null;
|
|
234
233
|
let _idlePollingIntervalMs = 5000;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
getBatteryHealth() {
|
|
238
|
-
return null;
|
|
239
|
-
},
|
|
240
|
-
getStatus(out) {
|
|
241
|
-
out.batteryLevel = -1;
|
|
242
|
-
out.chargingTime = -1;
|
|
243
|
-
out.dischargingTime = -1;
|
|
244
|
-
out.isBatteryLow = false;
|
|
245
|
-
out.isCharging = false;
|
|
246
|
-
out.isLowPower = false;
|
|
247
|
-
out.isOnBattery = false;
|
|
248
|
-
out.thermalState = 'Unknown';
|
|
249
|
-
return out;
|
|
250
|
-
},
|
|
251
|
-
getSystemIdleState() {
|
|
252
|
-
return 'Unknown';
|
|
253
|
-
},
|
|
254
|
-
getSystemIdleTime() {
|
|
255
|
-
return -1;
|
|
256
|
-
},
|
|
257
|
-
isKeepAwakeActive() {
|
|
258
|
-
return false;
|
|
259
|
-
},
|
|
260
|
-
setKeepAwake() {
|
|
261
|
-
return false;
|
|
262
|
-
},
|
|
263
|
-
subscribe() {
|
|
264
|
-
return () => { };
|
|
265
|
-
},
|
|
266
|
-
subscribeLockScreen() {
|
|
267
|
-
return () => { };
|
|
268
|
-
},
|
|
269
|
-
subscribeLowPowerModeChange() {
|
|
270
|
-
return () => { };
|
|
271
|
-
},
|
|
272
|
-
subscribeResume() {
|
|
273
|
-
return () => { };
|
|
274
|
-
},
|
|
275
|
-
subscribeSuspend() {
|
|
276
|
-
return () => { };
|
|
277
|
-
},
|
|
278
|
-
subscribeThermalStateChange() {
|
|
279
|
-
return () => { };
|
|
280
|
-
},
|
|
281
|
-
subscribeUnlockScreen() {
|
|
282
|
-
return () => { };
|
|
283
|
-
},
|
|
284
|
-
};
|
|
234
|
+
// Origin-pinned teardown bookkeeping: each entity's own unsubscribes, held beside the entity rather
|
|
235
|
+
// than in a shared slot, so detaching one never ends another's subscriptions.
|
|
285
236
|
const _subscriptions = new WeakMap();
|
|
237
|
+
// Providers already finally-released. A destroy that THREW is deliberately absent, so the next call
|
|
238
|
+
// retries exactly the failed obligations and never re-destroys a successful one.
|
|
239
|
+
const _destroyedKeepAwake = new WeakSet();
|
|
240
|
+
function assertSyncVoid(value) {
|
|
241
|
+
void value;
|
|
242
|
+
}
|
|
286
243
|
//# sourceMappingURL=power.js.map
|