import * as Context from "effect/Context";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Scope from "effect/Scope"; import * as Electron from "electron"; export type ElectronThermalState = ReturnType<Electron.PowerMonitor["getCurrentThermalState"]>;export type ElectronIdleState = ReturnType<Electron.PowerMonitor["getSystemIdleState"]>; export class ElectronPowerMonitor extends Context.Service< ElectronPowerMonitor, { readonly isOnBatteryPower: Effect.Effect<boolean>; readonly getSystemIdleTime: Effect.Effect<number>; readonly getSystemIdleState: (idleThresholdSeconds: number) => Effect.Effect<ElectronIdleState>; readonly getCurrentThermalState: Effect.Effect<ElectronThermalState>; readonly onSimpleEvent: ( eventName: "lock-screen" | "unlock-screen" | "on-ac" | "on-battery" | "suspend" | "resume", listener: () => void, ) => Effect.Effect<void, never, Scope.Scope>; readonly onThermalStateChange: ( listener: (state: ElectronThermalState) => void, ) => Effect.Effect<void, never, Scope.Scope>; readonly onSpeedLimitChange: ( listener: (limit: number) => void, ) => Effect.Effect<void, never, Scope.Scope>; }>()("@t3tools/desktop/electron/ElectronPowerMonitor") {} const onSimpleEvent: ElectronPowerMonitor["Service"]["onSimpleEvent"] = (eventName, listener) => Effect.acquireRelease( Effect.sync(() => { Electron.powerMonitor.on(eventName as any, listener as any); }), () => Effect.sync(() => { Electron.powerMonitor.removeListener(eventName as any, listener as any); }), ).pipe(Effect.asVoid); const onThermalStateChange: ElectronPowerMonitor["Service"]["onThermalStateChange"] = ( listener,) => { const wrapped = ( event: Electron.Event<Electron.PowerMonitorThermalStateChangeEventParams>, ): void => { listener(event.state); }; return Effect.acquireRelease( Effect.sync(() => { Electron.powerMonitor.on("thermal-state-change", wrapped); }), () => Effect.sync(() => { Electron.powerMonitor.removeListener("thermal-state-change", wrapped); }), ).pipe(Effect.asVoid);}; const onSpeedLimitChange: ElectronPowerMonitor["Service"]["onSpeedLimitChange"] = (listener) => { const wrapped = ( event: Electron.Event<Electron.PowerMonitorSpeedLimitChangeEventParams>, ): void => { listener(event.limit); }; return Effect.acquireRelease( Effect.sync(() => { Electron.powerMonitor.on("speed-limit-change", wrapped); }), () => Effect.sync(() => { Electron.powerMonitor.removeListener("speed-limit-change", wrapped); }), ).pipe(Effect.asVoid);}; /** @public Service construction is part of the canonical Effect module API. */export const make = ElectronPowerMonitor.of({ isOnBatteryPower: Effect.sync(() => Electron.powerMonitor.isOnBatteryPower()), getSystemIdleTime: Effect.sync(() => Electron.powerMonitor.getSystemIdleTime()), getSystemIdleState: (idleThresholdSeconds) => Effect.sync(() => Electron.powerMonitor.getSystemIdleState(idleThresholdSeconds)), getCurrentThermalState: Effect.sync(() => Electron.powerMonitor.getCurrentThermalState()), onSimpleEvent, onThermalStateChange, onSpeedLimitChange,}); export const layer = Layer.succeed(ElectronPowerMonitor, make);
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Scope from "effect/Scope";
import * as Electron from "electron";
export type ElectronThermalState = ReturnType<Electron.PowerMonitor["getCurrentThermalState"]>;
export type ElectronIdleState = ReturnType<Electron.PowerMonitor["getSystemIdleState"]>;
export class ElectronPowerMonitor extends Context.Service<
ElectronPowerMonitor,
{
readonly isOnBatteryPower: Effect.Effect<boolean>;
readonly getSystemIdleTime: Effect.Effect<number>;
readonly getSystemIdleState: (idleThresholdSeconds: number) => Effect.Effect<ElectronIdleState>;
readonly getCurrentThermalState: Effect.Effect<ElectronThermalState>;
readonly onSimpleEvent: (
eventName: "lock-screen" | "unlock-screen" | "on-ac" | "on-battery" | "suspend" | "resume",
listener: () => void,
) => Effect.Effect<void, never, Scope.Scope>;
readonly onThermalStateChange: (
listener: (state: ElectronThermalState) => void,
) => Effect.Effect<void, never, Scope.Scope>;
readonly onSpeedLimitChange: (
listener: (limit: number) => void,
) => Effect.Effect<void, never, Scope.Scope>;
}
>()("@t3tools/desktop/electron/ElectronPowerMonitor") {}
const onSimpleEvent: ElectronPowerMonitor["Service"]["onSimpleEvent"] = (eventName, listener) =>
Effect.acquireRelease(
Effect.sync(() => {
Electron.powerMonitor.on(eventName as any, listener as any);
}),
() =>
Effect.sync(() => {
Electron.powerMonitor.removeListener(eventName as any, listener as any);
}),
).pipe(Effect.asVoid);
const onThermalStateChange: ElectronPowerMonitor["Service"]["onThermalStateChange"] = (
listener,
) => {
const wrapped = (
event: Electron.Event<Electron.PowerMonitorThermalStateChangeEventParams>,
): void => {
listener(event.state);
};
return Effect.acquireRelease(
Effect.sync(() => {
Electron.powerMonitor.on("thermal-state-change", wrapped);
}),
() =>
Effect.sync(() => {
Electron.powerMonitor.removeListener("thermal-state-change", wrapped);
}),
).pipe(Effect.asVoid);
};
const onSpeedLimitChange: ElectronPowerMonitor["Service"]["onSpeedLimitChange"] = (listener) => {
const wrapped = (
event: Electron.Event<Electron.PowerMonitorSpeedLimitChangeEventParams>,
): void => {
listener(event.limit);
};
return Effect.acquireRelease(
Effect.sync(() => {
Electron.powerMonitor.on("speed-limit-change", wrapped);
}),
() =>
Effect.sync(() => {
Electron.powerMonitor.removeListener("speed-limit-change", wrapped);
}),
).pipe(Effect.asVoid);
};
/** @public Service construction is part of the canonical Effect module API. */
export const make = ElectronPowerMonitor.of({
isOnBatteryPower: Effect.sync(() => Electron.powerMonitor.isOnBatteryPower()),
getSystemIdleTime: Effect.sync(() => Electron.powerMonitor.getSystemIdleTime()),
getSystemIdleState: (idleThresholdSeconds) =>
Effect.sync(() => Electron.powerMonitor.getSystemIdleState(idleThresholdSeconds)),
getCurrentThermalState: Effect.sync(() => Electron.powerMonitor.getCurrentThermalState()),
onSimpleEvent,
onThermalStateChange,
onSpeedLimitChange,
});
export const layer = Layer.succeed(ElectronPowerMonitor, make);